Physics
how things move
In the traditional "Scene Graph" model, a 3D scene is created from a tree of translation nodes. These nodes serve as an inexpensive joint system with their actual positions calculated through a series of nested matrix transformations by the GPU.
The Scene Graph model is crude and obsolete given the speed of modern CPUs.
ODE, the Open Dynamics Engine, makes it possible to base 3D scenes on a physics model instead. That is, each "body" in the 3D scene has it's own physical properties and can interact with all other bodies in that scene.
We originally used PyODE for this which served to prove the model as feasible. PyODE is slow, however, so we've since integrated ODE with our Coreloop.
PySoy's Coreloop Thread
When PySoy is first imported by Python a background thread, called Coreloop, is launched to handle rendering and physics. This thread is 100% C, Python code is not permitted for speed, calling the C functions of almost every PySoy class in it's processing.
The _coreLoop() function itself is a standard ODE collision, physics, io, and render cycle. The main change is the use of mutex locks to prevent Python from changing or deleting data as it's being processed.
Bodies
Virtually everything visible in a soy.Scene is an instance of soy.bodies.Body. The Body class implements the standard ODE body properties such as velocity, rotation, and mass. Even lights and cameras are considered physics bodies and behave accordingly.
Bodies can connected using soy.bodies.joints to constrain their movement in respect to each other. These are ODE joints with their standard properties exposed to Python.
By default a Body has no shape, that is, it cannot collide with anything else. A .shape property can be added to provide collision. These shapes are ODE geoms.
For field effects we have soy.bodies.fields which apply ODE forces to all bodies within range according to the rules of that field. Currently we only have "gravity"-like fields (ie, for space flight games). Fields acting according to surface area or volume displacement are in development.
To aid in development each of these can be made visible in the 3D scene. In this way PySoy can also be a great learning tool.
Mesh Animation
One of the greatest challenges in this model is merging mesh animation, such as a bipedal character walking or a tree bending to wind.
Traditional character animation libraries, such as Cal3D, work only with pre-scripted animation cycles. While different cycles can be blended, such as walking and swinging a sword at the same time, the position of bones cannot be constrained by the environment. One negative effect of this is the "walking uphill" scenario where one foot is inside the hill and the other stands on air.
We are implementing our own internal rigid transformation system where instances of soy.bodies.Bone, connected with joints and each with their own shape, are implemented on the physics layer as separate bodies. Each bone has a parent soy.bodies.Mesh which stores the vertex group data.
Left alone any such model would be only somewhat more realistic than a ragdoll; it's limbs would move according to their mass, it's joints constrained, but under gravity this model would crumple to the ground.
From here a programmer will implement "behavior", which applies torque and forces to joints to achieve certain dynamic effects. Part of this is "training" through scripted walk cycles and other animations.
This sort of animation would not have been possible ten years ago, but we believe modern CPUs have the power to handle it. We hope to have it included by the Beta-2 release.
Credits
The PySoy physics model was developed by Arc Riley, Zach Miller, Mike Beckson, and Eric Stein.
Thanks to the PyODE developers as their Pyrex bindings were invaluable to us during this process. While no code is shared between PyODE and PySoy we frequently referenced it to find solutions to Pyrex specific issues. Cheers, guys.
