First things you should know :
- physics simulation is performed on ode.body, while ode.geom is for collision detection
- ODE does the physics simulation
- then we synchronize the visible geometry to it’s body. This is done in simulate method :
x, y, z = body.getPosition()
R = body.getRotation()
mat = Mat4(R[0], R[3], R[6], 0.,
R[1], R[4], R[7], 0.,
R[2], R[5], R[8], 0.,
x, y, z, 1.0)
o.realObj.setMat(mat)
o.realObj.setScale(o.scale)
That’s the part to update the visible geometry’s transformation, directly on it’s transform state level, using transform matrix. But by setting the transform matrix directly, only for setting the position and rotation, unfortunately it also overrides the scale too, since rotation and scale is melted in the matrix. Shear is ignored here.
That update part is the one used in the 3rd ODE tutorial (using pygame), and the 1st poster in CodeSnippet forum here used it 1:1. And I just followed that path and been BLIND for so long time, without even realized that there is “body.getQuaternion”. Just realized it lately, arrrgh … damn stupid me !
So it can be done this way too, which is a lot simpler :
o.realObj.setPos(*body.getPosition())
o.realObj.setQuat(Quat(*body.getQuaternion()))
mpos.getX() & mpos.getY() result is in window space :
= mpos.getX() result is -1 (left) ~ 1 (right)
= mpos.getY() result is -1 (bottom) ~ 1 (top)
which is exactly similar to bowl’s and the camera’s default XY orientation (facing to Y+), assuming it’s not moved around.
addRelForceAtRelPos adds force RELATIVE to the body’s rotation and position (it’s own coordinate space & origin).
So addRelForceAtRelPos((0,0,-5),(mpos.getX() * 10,mpos.getY() * 10,0)) adds (0,0,-5) linear force (down) at (x10, y10). Then, 10 multiplier is used to get a farther distance from the bowl’s origin, which allow the force to give a greater effect :
M = F * d (remember it in highschool physics ?)
TriMesh is collision geom type which is built of triangles. Here we use it for the bowl only. It’s constructed by using the actual triangles of the bowl, by packing it’s vertices list and indices list :
meshdata=ode.TriMeshData()
# create TriMesh data
meshdata.build(collVertices,collFaces)
# and pass it to ODE
self.geom = ode.GeomTriMesh(meshdata,space)
in ODEtrimesh method.