From: Andrew D. <ad...@gm...> - 2005-10-03 02:58:34
|
Hi everyone, I'm experimenting with PyODE and PyOgre at the moment, and have been working through PyODE's Tutorial 2 (two bodies connected with ball joints to form a compound pendulum). I've tried to rewrite Tutorial 2 using PyOgre instead of PyGame. I'd managed to get an ogre head to fall under gravity without trouble, but attempting to attach the head to a joint (with the other end fixed), the joint seems to be completely ignored, with the head merely falling and not swinging as it ought. I can't see at all what I'm doing wrong here -- can anyone help me? Here's the code: import pyogre.ogre as ogre import SampleFramework as sf import ode class TutorialApplication(sf.Application): def __init__(self): sf.Application.__init__(self) # Set up the physics world self.world =3D ode.World() self.world.setGravity((0, -9.81, 0)) self.bodyList =3D [] def _createScene(self): sm =3D self.sceneManager # Set up the lighting conditions sm.ambientLight =3D (0.7, 0.7, 0.7) # Create a disembodied ogre head e =3D sm.createEntity("OgreHead", "ogrehead.mesh") n =3D sm.rootSceneNode.createChildSceneNode() n.attachObject(e) pos =3D (100, 200, 0) n.position =3D ogre.Vector3(*pos) body1 =3D ode.Body(self.world) M =3D ode.Mass() M.setSphere(2500, 0.05) body1.setMass(M) body1.setPosition((100, 200, 0)) # Add it to the body list self.bodyList.append((body1, n)) # Connect body1 with the static environment j1 =3D ode.BallJoint(self.world) j1.attach(body1, None) j1.setAnchor((0, 200, 0)) def _createFrameListener(self): """Creates the FrameListener.""" self.frameListener =3D PhysicsFrameListener(self.renderWindow, self.camera, self.world, self.bodyList) self.frameListener.showDebugOverlay(True) self.root.addFrameListener(self.frameListener) class PhysicsFrameListener(sf.FrameListener): def __init__(self, renderWindow, camera, world, bodyList): sf.FrameListener.__init__(self, renderWindow, camera) self.world =3D world self.bodyList =3D bodyList self.time =3D 0.0 self.dt =3D 0.08 def frameStarted(self, frameEvent): # Step the physics self.world.step(self.dt) self.time +=3D self.dt if False: body =3D self.bodyList[0][0] x,y,z =3D body.getPosition() u,v,w =3D body.getLinearVel() print "%1.2fsec: pos=3D(%6.3f, %6.3f, %6.3f) vel=3D(%6.3f, %6.3f, %6.3f)" % \ (self.time, x, y, z, u,v,w) # Update the positions of objects for body, node in self.bodyList: pos =3D body.getPosition() node.position =3D ogre.Vector3(*pos) return sf.FrameListener.frameStarted(self, frameEvent) if __name__ =3D=3D "__main__": app =3D TutorialApplication() app.go() |
From: Matthias B. <ba...@ir...> - 2005-10-03 20:33:04
|
Andrew Durdin wrote: > # Connect body1 with the static environment > j1 = ode.BallJoint(self.world) > j1.attach(body1, None) > j1.setAnchor((0, 200, 0)) I couldn't run your code as I don't have PyOgre but it seems the problem is you store the BallJoint in a local variable which gets deleted at the end of the method. And as j1 is the only reference to the BallJoint object the BallJoint is garbage collected when j1 is deleted which will also delete the underlying ODE BallJoint. To fix this you simply have to keep a Python reference to the joint (self.j1 = ode.BallJoint(...)). - Matthias - |
From: Andrew D. <ad...@gm...> - 2005-10-05 05:48:01
|
On 10/4/05, Matthias Baas <ba...@ir...> wrote: > > I couldn't run your code as I don't have PyOgre but it seems the problem > is you store the BallJoint in a local variable which gets deleted at the > end of the method. And as j1 is the only reference to the BallJoint > object the BallJoint is garbage collected when j1 is deleted which will > also delete the underlying ODE BallJoint. To fix this you simply have to > keep a Python reference to the joint (self.j1 =3D ode.BallJoint(...)). Yes, that fixes it -- although it seems a little unnatural. I would have expected that the world would maintain the object, and that PyODE would not delete the joint merely because the Python reference gets collected... Anyway, thanks! I've got a solution now. |