Animated Meshes and Physics Interaction

charlierby

31-03-2008 13:43:13

Hi,

I'm currently trying to figure out what's the best way of getting animated meshes to physically interact with other physics objects in a scene?

We are doing all our scene creation in Blender and use the Ogre Meshes Exporter script to export all the meshes. Now think of an object (e.g. some kinda machine or something) where some parts are animated - what is the best way of letting the physics engine know the movement of this object?

Any help is highly appreciated!

Greetings,
charlie

NoodlesOnMyBack

02-04-2008 21:45:28

What you have to do its to create the meshes with bone animation when you desing your model, then you export a .skeleton wich contain the animations and bone positions.
The next step its to create the primitive actors for each part of the movable machine or character, ie: i create capsule shapes for arms and legs of my characters.
You atach each actor to bone positions and use joints to atach them (in the case you need them of course), you can do this both the 'hardcoded' way or the easy way:
Using the Scythe editor (wich is open source and free)

http://www.youtube.com/watch?v=1SGtMHqJRjI&feature=related

Download the Scythe demos and take a look

charlierby

03-04-2008 09:50:29

Thanks for your reply!

As we only have very simple animations (like a part of a machine going up and down all the time), I found a rather easy and automated way to achieve what I want.

Given that the entity's skeleton has only a root bone and you are able to set all the animated bodies to kinematic, you can do that:

(Please note that I've done all this with python-ogre...)

0. When loading the body, just set a new node for the body, so that the entity that is attached to the original node isn't translated/rotated when you move/rotate the body:


node = body.getNode()
body.setNode(node.createChildSceneNode())


1. Save the initial root bone to body position vector:


entity = body.getEntity()
skeleton = entity.getSkeleton()
rootBone = skeleton.getRootBone()

initialBonePosition = rootBone.getWorldPosition()
initialBonePosition = exchangeYZ(initialBonePosition)
initialBodyPosition = body.getGlobalPosition()
boneToBody = initialBodyPosition - initialBonePosition


2. Save the inverse initial root bone orientation:


inverseInitialBoneOrientation = rootBone.getWorldOrientation().Inverse()


3. Each frame, get the current root bone position, add the boneToBody vector and set the body's position:


# get current root bone position
rootBone = entity.getSkeleton().getRootBone()
currentRootBonePosition = rootBone.getWorldPosition()
currentRootBonePosition = exchangeYZ(currentRootBonePosition)

# add bone to body vector
bodyPosition = boneToBody + currentRootBonePosition

# set the body's new position
body.moveGlobalPosition(bodyPosition)


4. Multiply the root bone's current orientation with the initial orientation and set the final orientation:


bodyOrientation = quaternionMulti(boneWorldOrientation, inverseInitialBoneOrientation)

# rotate 90 degrees to get final orientation
bodyOrientation = quaternionMulti(ogre.Quaternion(ogre.Degree(-90), ogre.Vector3.UNIT_X), bodyOrientation)

# set final body orientation
body.moveGlobalOrientation(bodyOrientation)



Note that I've done some rotations here to translate stuff from the ogre coordinate system to nx coordinate system.

Maybe this is a lil hack, but it's a fast way to get simple animations done by an artist to interact with the physics world without doing any additional work...

Greetings,
charlie