ODE Collisions [resolved]

Hi all,

Well, I’m studying the ODE on Panda, and I got a bit lost when dealing with collisions.

In the Manual, samples are ok, but I think I didn’t get it right… :frowning: I also got some samples in the web…

I did this, but I can not figure out what is wrong, why the box is not colliding with the floor mesh?

http://www.paulobarbeiro.com.br/arquivos/PhysicsCollision.zip

I some one could give me a little tip… thanks a lot.

ah… the main code is here below :

import direct.directbase.DirectStart

from pandac.PandaModules import *
from direct.showbase.DirectObject import DirectObject
from direct.actor.Actor import Actor
from direct.task.Task import Task
from direct.directtools.DirectSelection import DirectBoundingBox

from pandac.PandaModules import OdeWorld, OdeSimpleSpace, OdeJointGroup
from pandac.PandaModules import OdeBody, OdeMass, OdeBoxGeom, OdePlaneGeom
from pandac.PandaModules import BitMask32, Vec4, Quat, CardMaker


class Floor():
    def __init__(self):
        self.loadModel()

    def loadModel(self):
        self.floorNP = render.attachNewNode('floor')

        self.floorModel = loader.loadModel('models/Map')
        self.floorModel.setPos(0,0,-15)
        self.floorModel.setScale(1)
        self.floorModel.reparentTo( self.floorNP )

        self.MapTrimesh = OdeTriMeshData(self.floorModel, True)
        self.MapGeom = OdeTriMeshGeom(space, self.MapTrimesh)
        self.MapGeom.setCollideBits(BitMask32(0x00000001))
        self.MapGeom.setCategoryBits(BitMask32(0x00000001))



class Box():
    def __init__(self):
        self.loadModel()
        self.createRigidbody()

        self.startTasks()

    def loadModel(self):
        self.boxNP = render.attachNewNode('boxNP')

        self.boxModel = loader.loadModel('box')
        self.boxModel.setScale(1)
        self.boxModel.setPos(0,0,0)
        self.boxModel.reparentTo( self.boxNP )

        self.boxModel.setPos(0,0,0)

    def createRigidbody(self):
        #RidigBody -----------
        self.boxBody = OdeBody(physicWorld)
        self.boxMass = OdeMass()
        self.boxMass.setBoxTotal(5, 1,1,1)
        self.boxBody.setMass(self.boxMass)
        self.boxBody.setPosition(self.boxNP.getPos(render))
        self.boxBody.setQuaternion(self.boxNP.getQuat(render))
            #coliders
        self.boxGeom = OdeBoxGeom(space, 1,1,1)
        self.boxGeom.setCollideBits(BitMask32(0x00000001))
        self.boxGeom.setCategoryBits(BitMask32(0x00000001))
        self.boxGeom.setBody(self.boxBody)

    def startTasks(self):
        taskMgr.doMethodLater(5, self.simulation, 'Physics Simulation')

    def simulation(self, task):
        space.autoCollide()
        physicWorld.quickStep( globalClock.getDt() )
        self.boxNP.setPosQuat(render,
                              self.boxBody.getPosition(),
                              Quat( self.boxBody.getQuaternion()) )
        contactgroup.empty()
        return Task.cont


class World():
    def __init__(self):
        #self.defineODEWorld()
        self.loadElements()

    def defineODEWorld(self):
        self.physicWorld = OdeWorld()
        self.physicWorld.setGravity(0, 0, -9.81)

    def loadElements(self):
        self.arena = Floor()
        self.obj = Box()


#World of Physic
physicWorld = OdeWorld()
physicWorld.setGravity(0, 0, -9.81)

#World Colisions
space = OdeSimpleSpace()
space.setAutoCollideWorld(physicWorld)
contactgroup = OdeJointGroup()
space.setAutoCollideJointGroup(contactgroup)

# I don't know...
# The surface table is needed for autoCollide
physicWorld.initSurfaceTable(1)
physicWorld.setSurfaceEntry(0, 0, 0.8, 0.0, 10    , 0.9, 0.00001, 100, 0.002)

completeWorld = World()

run()

I know… there are some imports which are totally useless in this sample… :slight_smile:

[/code]
[/url]

It seems a little odd that you’re calling world.quickStep for every box. You should only call it once per frame.

you mean that line:

in the simulation Task? it should be called as global?

I did this changes, but no results… the box still pass through the floor mesh… :frowning:

def simulation(self, task):
        global deltaTimeAccumulator
        deltaTimeAccumulator += globalClock.getDt()
        while deltaTimeAccumulator > stepSize :
            deltaTimeAccumulator -= stepSize
            physicWorld.quickStep(stepSize)

        space.autoCollide()
#        physicWorld.quickStep( )
        self.boxNP.setPosQuat(render,
                              self.boxBody.getPosition(),
                              Quat( self.boxBody.getQuaternion()) )
        contactgroup.empty()

        return Task.cont

After you create the trimesh floor, you forget to synchronize the position and quat.

        self.MapTrimesh = OdeTriMeshData(self.floorModel, True)
        self.MapGeom = OdeTriMeshGeom(space, self.MapTrimesh)

        self.MapGeom.setPosition(self.floorModel.getPos(render))
        self.MapGeom.setQuaternion(self.floorModel.getQuat(render))

        self.MapGeom.setCollideBits(BitMask32(0x00000001))
        self.MapGeom.setCategoryBits(BitMask32(0x00000001))

You may want to change your box model also. You shall use a centered box instead.

Wow… \o/ yeah!

It is working! :slight_smile:
thanks a lot!