objects graphics intersecting

nickak2003

06-06-2013 03:09:33

I'm new to physics engines so have been using as much example code as possible in my project. Right now I have 1 static cube with 1 falling cube, and then they intersect before the falling cube comes to rest. I cant quite figure out what is wrong.
I've attached my code to the post.
I think it may have to do with how I create the cube shape, like this:

self.setShape(physics.MeshInfo.createBoxShape(self.ent ) )

...meshinfo.createboxshape:

def createBoxShape(entity, unitScale=True):
"""Bullet Box Shape"""
## mesh extents
e = MeshInfo.getBoundingBox(entity)
size = bullet.btVector3(e.getHalfSize().x,
e.getHalfSize().y,
e.getHalfSize().z)
print size.x(), size.y(), size.z()
return bullet.btBoxShape(size)

nickak2003

06-06-2013 08:55:25

Ok, if I add 150 to the cubes y in the motionstate, it works. 150 is 1.5 * height.
Ogres nodes are positioned in the top corner of the object; are bullets nodes centered in the middle of the object?
Why does it work when I add 150 to y in the motionstate?

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()+150
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)

nickak2003

06-06-2013 09:57:30

OK I figured it out, the graphics weren't being transformed if mass=0

dermont

06-06-2013 11:15:31

OK I figured it out, the graphics weren't being transformed if mass=0

Yes due to the fact taht using a mass of 0 a btDefaultMotionState is implemented and the node is not set to the initial position.

If you move the node prior to creating the bullet body you can add ent->_getParentNodeFullTransform() to the call to MeshInfo::GetVertices to return the actual bounding box.

First you need to implement the DebugDrawer it will help.


import sys
sys.path.insert(0,'..')
import PythonOgreConfig

import ogre.renderer.OGRE as ogre

#import ogre.physics.OgreBulletC as bulletC
import ogre.physics.bullet as bullet
import ogre.io.OIS as OIS

import SampleFramework as sf


#================================================================
class DebugDrawer(bullet.btIDebugDraw):
#================================================================

#-------------------------------------------------------------
# DebugDrawer using ManualObject, this kills
# the frame rate but shows actual body positions
# for bullet objects and is therefore useful for
# debugging
#--------------------------------------------------------------
def __init__(self, sceneManager):
bullet.btIDebugDraw.__init__(self)

self.mDebugMode = bullet.btIDebugDraw.DBG_DrawWireframe
self.beginLineUpdates = False
self.beginTriUpdates = False
self.mContactPoints = []

mLines = ogre.ManualObject("physics lines")
mTriangles = ogre.ManualObject("physics triangles")
mLines.setDynamic(True)
mTriangles.setDynamic(True)
self.mSceneManager = sceneManager
self.mSceneManager.getRootSceneNode().attachObject( mLines )
self.mSceneManager.getRootSceneNode().attachObject( mTriangles )

matName = "OgreBulletCollisionsDebugDefault"
mtl = ogre.MaterialManager.getSingleton().getDefaultSettings().clone(matName)
mtl.setReceiveShadows(False)
mtl.setSceneBlending( ogre.SBT_TRANSPARENT_ALPHA )
mtl.setDepthBias( 0.1, 0 )
tu = mtl.getTechnique(0).getPass(0).createTextureUnitState()
tu.setColourOperationEx( ogre.LBX_SOURCE1, ogre.LBS_DIFFUSE )
mtl.getTechnique(0).setLightingEnabled(False)
##mtl.getTechnique(0).setSelfIllumination( ogre.ColourValue().White )

mLines.begin( matName, ogre.RenderOperation.OT_LINE_LIST )
mLines.position( ogre.Vector3().ZERO )
mLines.colour( ogre.ColourValue().Blue )
mLines.position( ogre.Vector3().ZERO )
mLines.colour( ogre.ColourValue().Blue )

mTriangles.begin( matName, ogre.RenderOperation.OT_TRIANGLE_LIST )
mTriangles.position( ogre.Vector3().ZERO )
mTriangles.colour( ogre.ColourValue().Blue )
mTriangles.position( ogre.Vector3().ZERO )
mTriangles.colour( ogre.ColourValue().Blue )
mTriangles.position( ogre.Vector3().ZERO )
mTriangles.colour( ogre.ColourValue().Blue )

self.mLines = mLines
self.mTriangles = mTriangles


def __del__(self):
self.mSceneManager.getRootSceneNode().detachObject( self.mLines )
self.mSceneManager.getRootSceneNode().detachObject( self.mTriangles )
del self.mLines
del self.mTriangles

def frameRenderingQueued( self, evt ):
self.mLines.end()
self.mLines.beginUpdate(0)

now = ogre.Root.getSingleton().getTimer().getMilliseconds()

newCP = []
for p in self.mContactPoints:
self.mLines.position( p._from )
self.mLines.colour( p.colour )
self.mLines.position( p._to )
self.mLines.colour( p.colour )
if now <= p.dieTime:
newCP.append(p )
self.mContactPoints = newCP

def frameEnded(self, evt ):
self.beginLineUpdates = False
self.beginTriUpdates = False


def showdebugContactInfo(self, p):
pass
#print ("Start (%f,%f,%f) End (%f,%f,%f)" %(p._from.x,p._from.y,p._from.z,
#p._to.x,p._to.y,p._to.z) )

def drawContactPoint(self, PointOnB, normalOnB, distance, lifeTime, color ):
p = ContactPoint()
p._from = ogre.Vector3( PointOnB.x(), PointOnB.y(), PointOnB.z() )
p._to = p._from + ogre.Vector3( normalOnB.x(), normalOnB.y(), normalOnB.z() ) * distance
p.dieTime = ogre.Root.getSingleton().getTimer().getMilliseconds() + lifeTime
p.colour.r = color.x()
p.colour.g = color.y()
p.colour.b = color.z()
self.mContactPoints.append(p)


def drawLine(self,btVectorFrom , btVectorTo, colour):
mLines = self.mLines
c = ogre.ColourValue( colour.getX(), colour.getY(), colour.getZ() )
c.saturate()
mLines.position( btVectorFrom.x(),btVectorFrom.y(),btVectorFrom.z())
mLines.colour( c )
mLines.position( btVectorTo.x(),btVectorTo.y(),btVectorTo.z() )
mLines.colour( c )


def drawTriangle(self, v0, v1, v2, colour, alpha ):
return
if not self.beginTriUpdates:
self.beginTriUpdates = True
self.mTriangles.beginUpdate(0)
mTriangles = self.mTriangles
c = ogre.ColourValue( colour.getX(), colour.getY(), colour.getZ(), alpha )
c.saturate()
mTriangles.position( v0.x(),v0.y(),v0.z() )
mTriangles.colour( c )
mTriangles.position( v1.x(),v1.y(),v1.z() )
mTriangles.colour( c )
mTriangles.position( v2.x(),v2.y(),v2.z() )
mTriangles.colour( c )


def drawAabb(self, btVecFrom, btVecTo,btVecColor):
bullet.btIDebugDraw.drawAabb(self,btVecFrom, btVecTo,btVecColor)


def reportErrorWarning(self,warningString):
ogre.LogManager.getSingleton().getDefaultLog().logMessage(warningString)

def draw3dText(self,btVecLocation,textString):
pass

def setDebugMode(self, idebugMode):
self.mDebugMode = idebugMode

def getDebugMode(self):
return self.mDebugMode


#================================================================
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.dynamicsWorld = world

def __del__(self):
pass

def frameStarted(self, frameEvent):
self.dynamicsWorld.stepSimulation(frameEvent.timeSinceLastFrame,50)
## begin debugger update
debugger = self.dynamicsWorld.getDebugDrawer()
debugger.frameRenderingQueued(frameEvent)

## debugger draw
self.dynamicsWorld.debugDrawWorld()

ret = sf.FrameListener.frameStarted( self,frameEvent)

## some debugger options
if self.Keyboard.isKeyDown(OIS.KC_1) and self.timeUntilNextToggle <= 0:
debugger.setDebugMode(bullet.btIDebugDraw.DBG_DrawWireframe)
self.timeUntilNextToggle = 0.5
if self.Keyboard.isKeyDown(OIS.KC_2) and self.timeUntilNextToggle <= 0:
debugger.setDebugMode(bullet.btIDebugDraw.DBG_DrawAabb)
self.timeUntilNextToggle = 0.5
if self.Keyboard.isKeyDown(OIS.KC_3) and self.timeUntilNextToggle <= 0:
debugger.setDebugMode(bullet.btIDebugDraw.DBG_NoDebug)
self.timeUntilNextToggle = 0.5
return ret

def frameEnded(self, frameEvent):

## end debugger update
self.dynamicsWorld.getDebugDrawer().frameEnded(frameEvent)
return sf.FrameListener.frameEnded(self, frameEvent)


#================================================================
class BulletApplication( sf.Application ):
#================================================================

def __init__(self):
sf.Application.__init__(self)
self.shapes = []
self.rigidbodies = []
self.motionstates = []
self.collisionConfiguration = None
self.dispatcher = None
self.broadphase = None
self.solver = None
self.dynamicsWorld = None
self.mDebugDrawer = None

def _createScene( self ):
self.setupBullet()
self.createPlane()
self.createBoxes()

self.camera.setPosition(ogre.Vector3(0,10,-30))
self.camera.lookAt((0,0,0))
self.camera.nearClipDistance = 5


# def __del__(self):
# if self.dynamicsWorld:
# del self.dynamicsWorld

def setupBullet(self):
self.collisionConfiguration = bullet.get_btDefaultCollisionConfiguration()
self.dispatcher = bullet.get_btCollisionDispatcher1 (self.collisionConfiguration)
self.broadphase = bullet.btDbvtBroadphase()
self.solver = bullet.btSequentialImpulseConstraintSolver()

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


## debugger
self.mDebugDrawer = DebugDrawer(self.sceneManager)
self.dynamicsWorld.setDebugDrawer(self.mDebugDrawer)
self.dynamicsWorld.getDebugDrawer().setDebugMode(bullet.btIDebugDraw.DBG_DrawWireframe)


def createPlane(self):
#------------------------------------------
# Static Plane
#------------------------------------------
s = self.sceneManager.createStaticGeometry('StaticFloor')
s.setRegionDimensions((160,100,160))
s.setOrigin((0,-1,0))
i = 0
for z in range(-80,80,20):
for x in range(-80,80,20):
name = 'Plane_'+str(i)
i+=1
ent = self.sceneManager.createEntity(name,'plane.mesh')
ent.setQueryFlags(1<<4)
s.addEntity(ent,ogre.Vector3(x,0.0,z))
s.build()
## This will create a generic plane, other dynamic physics objects will still
## interact with outside the static region geometry limits
## TODO limit physics world to plane size
shape = bullet.btStaticPlaneShape(bullet.btVector3(0,4,0),0)
#shape = bullet.btBoxShape(bullet.btVector3(150.,1.,150.))

mass = 0.0
fallInertia = bullet.btVector3(0, 0, 0)
#shape.calculateLocalInertia(mass, fallInertia)
motionState = bullet.btDefaultMotionState(bullet.btTransform(bullet.btQuaternion(0, 0,0, 1), bullet.btVector3(0, 0, 0)))

rbInfo=bullet.btRigidBody.btRigidBodyConstructionInfo(mass,motionState,shape,fallInertia)
mRigidBody = bullet.btRigidBody(rbInfo)

self.dynamicsWorld.addRigidBody(mRigidBody)

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

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

####self.dynamicsWorld.setGravity(bullet.btVector3(0, -10, 0))
mass = 0.05
fallInertia = bullet.btVector3(0, 0, 0)
#shape = bullet.btStaticPlaneShape(bullet.btVector3(0,4,0),0)
shape=bullet.btSphereShape(10)
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.dynamicsWorld.addRigidBody(self.Object)

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



def cleanUp (self):
while(len(self.rigidbodies)>0):
c = self.rigidbodies.pop()
self.dynamicsWorld.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
del self.dynamicsWorld
del self.solver
del self.broadphase
del self.dispatcher
del self.collisionConfiguration

def _createFrameListener( self ):

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


Your code/demo is a bit disjointed but this is probably due to the demos you are following. Since I did the demos I'll rewrite them even I'm having difficulty following what's going on.

What version of python-ogre are you using? What version of bullet? Did you build from source?

nickak2003

09-06-2013 08:41:31

OK, I implemented the debug drawer, very cool.