Parent object without loosing physics?

Hello! In my game, I have a spaceship, which can move around a giant map. The spaceships need to have interiors, but because its a multiplayer game I cant just have it as another scene(Cause each ship needs a different interior(Due to breakable objects), and also the limited number of collision groups). I decided the way I’m handling the spaceships and their interiors is to merge the two. What I end up with is a bunch of interior objects that need to be parented to the outer spaceship. This is fine, until I start having rigid body objects. For some reason parenting them to something makes them loose their physics. I can understand why this is normally done, but I’ve set the game up so that the object wont collide with the ship causing it to move, but because the object is parented it moves with it and so it spazzes out of control.

In short, is there a way to parent objects to another object without them loosing their physics? I would prefer not to use a script as I would like this to be fairly perfect(and apparently there’s a frame of lag between logic bricks and physics updates). A fork of blender is fine though(In fact, I might go looking through the source code and see if I can change it so that it doesn’t do that lol :D)

Thanks in advance! :slight_smile:
Edit:
BTW, the ship needs to be able to move around, and also rotate in the z-axis. No other axis need to matter :slight_smile:

By “loose their physics” one assumes that you mean collision response and not gravitational acceleration. Enable Compound on the parent object.

Sorry, I probably should have made myself clearer lol :). The Compound option is useful for my static objects, but in my question I really mean gravity and the ability to be pushed around and such :).

Like this?

Attachments

Collidite.blend (393 KB)

What is the purpose of parenting the two together then?

I’m guessing he wants to something like moving platforms.
So object1 can stand on top of a rotating/moving object2, object2 affects the orientation and position of object1 but object1 can still move on it’s own (taking into account the transformations given by object2).

ahh,

collision with platform--------------python - [own.setLinearVelocity(own.getLinearVelocity() + target.getLinearVelocity()]

Not quite.

You still need to account for rotation, which makes it a bit harder.

You’ll need to have a way to access the platform’s rotation and displacement per frame (dLoc or linear velocity), then apply that rotation value and the displacement value to all the objects on board your ship.

The most efficient way to parent while preserving physics is creating a rigid body joint between the child and parent, Setting it to 6DoF and limiting all of transforms and rotations.

2 Likes

EDIT: ACtually there still seems to be some problems with the script, I’ll update this post once I fix them :slight_smile:

Thanks everyone for there help! I was able to create a script that simulates movement and zrotation of a parent object on a child object, here it is(Sorry, its a bit messy and wasteful of variables here and there :frowning: )


#Parent an object to another without disrupting rigid body stuff. It does not handle scaling or x and y rotation.

import math
import bge.logic as logic
#Get/Set important variables
objects = logic.getCurrentScene().objects
obj = logic.getCurrentController().owner
OriginObject = "Cube"

#Set C to the origin objects world position so I dont have to type so much lol :D
c=objects[OriginObject].worldPosition
#Get the array which contains the distance from the current object to the origin object
stuff = obj.getVectTo((c[0],c[1],obj.worldPosition[2]))
#Set dist to the distance
dist = stuff[0]

#####Now to work out the angle between the two objects! :) (BTW, in case your wondering why I do this instead of using the angles provided in VectTo, its because I have no idea what to do with those lol :D)

#Create two variables which contain the world positions(just realised this part is wastefull but oh well :P)
p2 = [obj.worldPosition[0],obj.worldPosition[1]]
p1 = [objects[OriginObject].worldPosition[0],objects[OriginObject].worldPosition[1]]
#Work out the X and Y difference between them
xDiff = p2[0]-p1[0]
yDiff= p2[1]-p1[1]
#Set dir to the angle between the two points
dir = math.atan2(yDiff,xDiff)#math.radians(math.degrees#+1)
#Add to dir the amount that the origin object is turning
dir += objects[OriginObject].worldAngularVelocity[2]/60

#####Figure out where to put the object! :)

#Set xmod and ymod to the position of the origin object
xmod = c[0]
ymod = c[1]

#Conver the angle and distance to x and y values, then add them onto xmod and ymod
xmod += math.cos(dir)*dist
ymod += math.sin(dir)*dist

#Add the amount that the origin object is moving to prevent the 1 frame lag
xmod+=objects[OriginObject].getLinearVelocity(0)[0]/60
ymod+=objects[OriginObject].getLinearVelocity(0)[1]/60

#Apply xmod and ymod to the objects world position!
obj.worldPosition[0]=xmod
obj.worldPosition[1]=ymod

#Finally add the amount the origin object is rotating to the object
obj.applyRotation([0,0,objects[OriginObject].worldAngularVelocity[2]/60],0)

#Done! :)

If anyone wants to optimize it please post, I’m sick of looking at this script though lol :D, I’m just gonna chuck it on every dynamic object and be done with it :P.

Thanks! :slight_smile:

Ok figured out what the problem is, although its a tough one :(. What wrong is that the physics engine still sticks the child object to the ground loosely without the script, so that once the script is applied they accumulate causing the child object to spaz out and make its position really far after a few frames :(. Not sure if theres any way to fix this though, so I might be in trouble lol :smiley:

Forgive me if I am wrong, but surely if you set your ship’s collision bounds to compound, enabled anisotropic friction and added a friction amount in the material panel it would keep the objects from moving? You wouldn’t need to parent the object and rather add empties which spawn in objects in the correct space.

Just add the LINV and RotV to the player if he is in the collision bound of a static ghost?

this way you can walk, move, jump etc, while still on the ship?

@@MrPutuLips
I can’t get that to work sadly, but even if it did while touching the ship, the player can still pick up and throw the object, and because its now not colliding with the ship it would not move with it. Thanks though :slight_smile:

@@BluePrintRandom
That is pretty much what I’m doing with the script :). Its just really complex because for the rotation they have different origin points so I need to calculate where the child would be relative to the ships and not its own.

Too be honest I’m beggining to think this might be impossible, so I think I’ll have to think of another way to store the interior for the game. Other than that I wonder if its possible to edit the source code so it doesn’t remove physics while parenting? I’ve looked around but the best I can find that relates to parents is in the SceneGraph folder of the gamengine folder. Its called SG_ParentRelation.h, although it doesn’t have much in it :frowning:

On a side note, does anyone know where I can get an error free copy of the source code, everywhere I get it, be it from blender.org or the Trunk svn, it always has errors with a few scripts, and most of the time I can fix them but its still rather annoying :slight_smile:

Sorry to double post, just figured this should go in a separate one. I found several files in the source code which use that file, so I’ve been looking through them. I’m not sure what I was thinking assuming that there would be some sort of disable physics function which is called when parented, but instead i think it just sets the world position every frame so it has no chance to move. I found most information in “\source\gameengine\Ketsji\KX_SG_NodeRelationships.ccp”. Of this is right then I would have to recode a decent amount of the parented stuff, and I’m not particularly good at C++ so I think that’s above me :(. Unless there are any other ways I think I’ll have to think a bit differently :frowning:
Thanks though, and hopefully the script is helpful if you can get it to work lol :D. In its current state it sort of works, it just depends on if the object is already sort of sticking to the parent.

From what I’m reading, you’re trying to get objects inside the ship to move with the ship?

When I had to find a way to get an object to move with a moving object, I didn’t use anything near as complex as you’re doing, and you might be making this out to be way more complex than it needs to be.

Basically, what you need to do is something like this…


collision = own.sensors['Collide']
colObject = collision.hitObject

colX, colY, colZ = colObject.getLinearVelocity

if collision.positive == True:
    own.applyForce([colX,colY,colZ],False)

So if it’s just a simple case of moving on another object (providing the object has physics enabled), then you might be able to just forget about the complex parenting and positioning stuff and instead just apply simple forces. It worked for me with moving platforms.

Thanks, but I also had to deal with rotation as well, hence the complex script :). Even with just position it still has trouble as the object half sticks to the ship without the script every so often, causing the script to move the object when its already moving, ill look at the physics settings and see if I can get it to stop sticking who the script can do all the work. I just whish there was an option for this, hence me looking at the source :slight_smile:

Sent from my phone, sorry for spelling mystakea :).

There’s a function out there known as applyTorque as well, have you tried using that as a possible solution before going the more complex route?

It’s a pitfall that I’ve fallen into as well, I see something as a complex problem and it actually turns out to be one that’s a bit simpler, and as far as I know you would still be able to use applyRotation (the function in your script) with applyForce.

the reason is very simple, the more easy way to get dependence between 2 obj is using parent.

do something as ragdool become extremely more easy, (than the mess actual), since each obj dynamic has usually one obj as reference.
so, you can use the parent of the obj as reference.
plus you can use the correct position / orientation, as yuou have setup in edit mode without other additive code

ie:
add a box obj(with 4 obj dynamic parented)
put 2 line of code on the dynamic obj:

referenceObj = own.parent
own.removeParent()
cs = bge.constraints.createConstraints(own.getPhysicsId(), referenceObj.getPhysicsId()),0,0,0,0,0,0,128)
cs.setParam(14,2000)

done

or another example more simple to understand:
you have a car with piece dynamic(parented) ,
when you have some crash , you just do :
pieceOfCar.removeParent()

this bug, clearly start in edit mode when you press CTRL+P , that trigger some buggy line , that make the obj permanently STATIC.

just to know , this bug exist at least from TWO YEARS (as minimum)
and is not little.

There’s a patch in the tracker (from Agoose77) which fixes an issue with parenting and physics in the game engine, but I’m not sure if it’s one that covers this exact issue though.

Perhaps it’s time for Moguri to give this a look over and give it the changes that are needed to make it applicable to trunk (would be nice to have for 2.69).