problem with pyogre-bullet

nickak2003

04-06-2013 05:54:21

So I'm trying to get bullet to work using pyogre. WHAT A NIGHTMARE. I'm using a tutorial from pyogre demos, it does not work and crashes in a number of ways.
Check out this code I'm trying to get working... the line,
self.world.addRigidBody(self.Object) causes the program to crash on exit and causes the program to crash when it encounters this code in the frame listener: self.world.stepSimulation( evt.timeSinceLastFrame)

Here is the full code:


import sys

import ogre.renderer.OGRE as ogre

import ogre.physics.OgreBulletC as bulletC
import ogre.physics.bullet as bullet

import SampleFramework as sf


class OgreMotionState(bullet.btMotionState):

def __init__(self, initalPosition, node):
bullet.btMotionState.__init__(self)
self.mWorldTrans = initalPosition
self.mParentNode = node

def getWorldTransform(self, WorldTrans):
WorldTrans.setOrigin(self.mWorldTrans.getOrigin())
WorldTrans.setBasis(self.mWorldTrans.getBasis())

def setWorldTransform(self, WorldTrans):
x = WorldTrans.getOrigin().x()
y = WorldTrans.getOrigin().y()
z = WorldTrans.getOrigin().z()
p = ogre.Vector3(x, y, z)
q = ogre.Quaternion(WorldTrans.getRotation().w(),
WorldTrans.getRotation().x(),
WorldTrans.getRotation().y(),
WorldTrans.getRotation().z())

self.mParentNode.setOrientation(q)
self.mParentNode.setPosition(x, y , z)

class BulletListener( sf.FrameListener ):
def __init__(self, rw, cam, world ):
sf.FrameListener.__init__(self, rw, cam)
self.world = world

def __del__(self):
pass
def frameStarted(self, evt):
#self.world.stepSimulation( evt.timeSinceLastFrame)
return sf.FrameListener.frameStarted( self, evt )

class BulletApplication( sf.Application ):
def _createScene( self ):
self.setupBullet()
self.createBoxes()
def __del__(self):
if self.world:
del self.world
def setupBullet(self):
self.collisionConfiguration = bullet.get_btDefaultCollisionConfiguration()
self.dispatcher = bullet.get_btCollisionDispatcher1 (self.collisionConfiguration)
self.broadphase = bullet.btDbvtBroadphase()
self.solver = bullet.btSequentialImpulseConstraintSolver()

self.world = bullet.btDiscreteDynamicsWorld(self.dispatcher, self.broadphase , self.solver, self.collisionConfiguration)
self.world.setGravity(bullet.btVector3(0,-10,0))
self.world.getDispatchInfo().m_enableSPU = True

def createBoxes(self):
ent = self.sceneManager.createEntity( "box", "cube.mesh" )
node = self.sceneManager.getRootSceneNode().createChildSceneNode()
node.attachObject( ent )
ent.setMaterialName( "Examples/RustySteel")

####self.world.setGravity(bullet.btVector3(0, -10, 0))
mass = 10
fallInertia = bullet.btVector3(0, 0, 0)
shape=bullet.btSphereShape(1)
shape.calculateLocalInertia(mass, fallInertia)
motionState=OgreMotionState(bullet.btTransform(bullet.btQuaternion(0, 0,0, 1), bullet.btVector3(0, 50, 0)),node)
construct = bullet.btRigidBody.btRigidBodyConstructionInfo(mass, motionState, shape, fallInertia)
self.Object=bullet.btRigidBody(construct)
self.world.addRigidBody(self.Object)
def _createFrameListener( self ):

self.fl = BulletListener( self.renderWindow, self.camera, self.world )
self.root.addFrameListener( self.fl )
if __name__=="__main__":
app = BulletApplication()
app.go()


except for the motion state, this code is straight from the demo

dermont

04-06-2013 15:02:06

I'm not familiar with the demo but it looks as if you need to hold a reference to the bullet shape and motion state.


...
self.shape = shape
self.motionState = motionState



In general you can do something like:

class BulletApplication( sf.Application ):

def __init__(self):
sf.Application.__init__(self)
self.shapes = []
self.rigidbodies = []
self.motionstates = []

mass = 1.0
fallInertia = bullet.btVector3(0, 0, 0)
shape=bullet.btSphereShape(1)
shape.calculateLocalInertia(mass, fallInertia)
motionState=OgreMotionState(bullet.btTransform(bullet.btQuaternion(0, 0,0, 1), bullet.btVector3(0, 50, 0)),node)
rbInfo = bullet.btRigidBody.btRigidBodyConstructionInfo(mass, motionState, shape, fallInertia)
rigidBody=bullet.btRigidBody(rbInfo)
self.world.addRigidBody(rigidBody)

self.shapes.append(shape)
self.rigidbodies.append(rigidBody)
self.motionstates.append(motionState)

def cleanUp (self):
while(len(self.rigidbodies)>0):
c = self.rigidbodies.pop()
self.world.removeRigidBody(c)
del c
while(len(self.shapes)>0):
c = self.shapes.pop()
del c

while(len(self.motionstates)>0):
c = self.motionstates.pop()
del c


or a better way would be to encapsulate the above into a simple class, e.g:

class PhysicsObject( ):
def __init__(self, world):
self.world = world
self.shape = None
self.motionstate = None
self.rigiidbody = None

.... whatever

def __del__(self):
self.world.removeRigidBody(self.rigiidbody)
del self.shape
del self.motionstate

class BulletApplication( sf.Application ):
def __init__(self):
sf.Application.__init__(self)
self.physicsobjects = []

...
self.world.addRigidBody(rigidBody)
c = PhysicsObject(self.world)
c.whatever.....
c.shape = shape
c.rigidbody = rigidBody
c.motionState = motionState
self.physicsobjects.append(c)

nickak2003

05-06-2013 00:18:28

Ok It's working now, thanks