OdeTriMesh problem in newer builds

I’ve got a problem with Panda3D after 1.9.3 and OdeTriMesh collision objects. Objects simply pass through each other with almost no interaction.

I’ve wanted to update for sometime to use the git repository version but I new there was a problem somewhere with collision detection in my simulation. The ODE example in the Panda3D manual works in my compiled (cloned yesterday from git) version of Panda3d but as soon as I replace the plane collider with my simple arena model it no longer collides. Actually, it collides a little bit; most of the cubes fall straight through but one or two will interact momentarily. The modified example works very nicely on 1.9.3 and earlier.

If anybody has any ideas on this it would be great.

Here is a link to the egg file for my trimesh model https://www.dropbox.com/s/ekn218b7e9g2u39/tray2b.egg?dl=0

Here is the code:

from direct.directbase import DirectStart
from panda3d.ode import OdeWorld, OdeSimpleSpace, OdeJointGroup
from panda3d.ode import OdeBody, OdeMass, OdeBoxGeom, OdePlaneGeom
from panda3d.core import BitMask32, CardMaker, Vec4, Quat
from random import randint, random
import math
from pandac.PandaModules import OdeTriMeshData, OdeTriMeshGeom, Point3, Mat4

# Setup our physics world
world = OdeWorld()
world.setGravity(0, 0, -9.81)
 
# The surface table is needed for autoCollide
world.initSurfaceTable(1)
world.setSurfaceEntry(0, 0, 150, 0.0, 9.1, 0.9, 0.00001, 0.0, 0.002)
 
# Create a space and add a contactgroup to it to add the contact joints
space = OdeSimpleSpace()
space.setAutoCollideWorld(world)
contactgroup = OdeJointGroup()
space.setAutoCollideJointGroup(contactgroup)
 
# Load the box
box = loader.loadModel("box")
# Make sure its center is at 0, 0, 0 like OdeBoxGeom
box.setPos(-.5, -.5, -.5)
box.flattenLight() # Apply transform
box.setTextureOff()
 
# Add a random amount of boxes
boxes = []
for i in range(randint(15, 30)):
  # Setup the geometry
  boxNP = box.copyTo(render)
  boxNP.setPos(randint(-10, 10), randint(-10, 10), 10 + random())
  boxNP.setColor(random(), random(), random(), 1)
  boxNP.setHpr(randint(-45, 45), randint(-45, 45), randint(-45, 45))
  # Create the body and set the mass
  boxBody = OdeBody(world)
  M = OdeMass()
  M.setBox(5, 1, 1, 1)
  boxBody.setMass(M)
  boxBody.setPosition(boxNP.getPos(render))
  boxBody.setQuaternion(boxNP.getQuat(render))
  # Create a BoxGeom
  boxGeom = OdeBoxGeom(space, 1, 1, 1)
  boxGeom.setCollideBits(BitMask32(0x00000002))
  boxGeom.setCategoryBits(BitMask32(0x00000001))
  boxGeom.setBody(boxBody)
  boxes.append((boxNP, boxBody))
 
# Add a plane to collide with
# cm = CardMaker("ground")
# cm.setFrame(-20, 20, -20, 20)
# ground = render.attachNewNode(cm.generate())
# ground.setPos(0, 0, 0); ground.lookAt(0, 0, -1)
# groundGeom = OdePlaneGeom(space, Vec4(0, 0, 1, 0))
# groundGeom.setCollideBits(BitMask32(0x00000001))
# groundGeom.setCategoryBits(BitMask32(0x00000002))

tray_mod = loader.loadModel('models/tray2b.egg')
tray_mod = tray_mod.find('**/tray')
tray_mod.reparentTo(render)
cat=BitMask32(0x00000001)
col=BitMask32(0x00000002)
objdata = OdeTriMeshData(tray_mod, True)
tray_geom = OdeTriMeshGeom(space, objdata)
tray_body = OdeBody(world)
tray_body.setGravityMode(0)
tray_mass = OdeMass()
minDim, maxDim = tray_mod.getTightBounds()
tray_dimms = Point3(maxDim - minDim)
tray_mass.setBox(1, tray_dimms.getX(), tray_dimms.getY(), tray_dimms.getZ())
tray_body.setMass(tray_mass)
tray_body.setPosition(tray_mod.getPos(render))
tray_body.setQuaternion(tray_mod.getQuat(render))
tray_geom.setBody(tray_body)
boxes.append((tray_mod, tray_body))

# Set the camera position
base.disableMouse()
base.camera.setPos(10, -10, 40)
base.camera.lookAt(0, 0, 0)

# The task for our simulation
def simulationTask(task):
  space.autoCollide() # Setup the contact joints
  # Step the simulation and set the new positions
  world.quickStep(globalClock.getDt())
  for np, body in boxes:
    np.setPosQuat(render, body.getPosition(), Quat(body.getQuaternion()))
  contactgroup.empty() # Clear the contact joints
  return task.cont

# Wait a split second, then start the simulation
taskMgr.doMethodLater(0.5, simulationTask, "Physics Simulation")

run()