Here is a video of the issue with the debug enabled: https://youtu.be/lVxEzhyEzzM
Here is the source code.
Code: Select all
from direct.gui.OnscreenText import OnscreenText
from direct.showbase.ShowBase import ShowBase
from panda3d.bullet import BulletWorld, BulletDebugNode, BulletBoxShape, \
BulletRigidBodyNode, BulletTriangleMesh, BulletTriangleMeshShape, \
BulletVehicle
from panda3d.core import TransformState
class VehicleTest(ShowBase, object):
def __init__(self, configuration=None, domain=''):
ShowBase.__init__(self)
self.setup_physics()
self.setup_track()
self.setup_car()
self.set_debug()
self.taskMgr.add(self.update, 'Engine::update')
def setup_physics(self):
self.world_phys = BulletWorld()
self.world_phys.setGravity((0, 0, -9.81))
def setup_track(self):
self.track_model = loader.loadModel('assets/track/track')
self.track_model.reparentTo(render)
self.track_model.flattenLight()
collision_models = self.track_model.findAllMatches('**/Road*')
map(lambda mod: mod.hide(), collision_models)
for geom in self.find_geoms(self.track_model, 'Road'):
mesh = BulletTriangleMesh()
mesh.addGeom(geom.node().getGeom(0))
np = render.attachNewNode(BulletRigidBodyNode())
np.node().addShape(BulletTriangleMeshShape(mesh, dynamic=False))
self.world_phys.attachRigidBody(np.node())
def setup_car(self):
self.car_np = render.attachNewNode(BulletRigidBodyNode())
self.car_np.set_pos(-100, -20, 2)
self.chassis_np = self.loader.loadModel('assets/car/car')
self.chassis_np.reparentTo(self.car_np)
self.wheels_np = []
for _ in range(4):
self.wheels_np += [self.loader.loadModel('assets/car/wheel')]
self.wheels_np[-1].reparentTo(render)
chassis_shape = BulletBoxShape((.8, 1.4, .4))
transform_state = TransformState.makePos((0, .05, .5))
self.car_np.node().addShape(chassis_shape, transform_state)
self.car_np.node().setMass(1400)
self.world_phys.attachRigidBody(self.car_np.node())
self.vehicle = BulletVehicle(self.world_phys, self.car_np.node())
self.world_phys.attachVehicle(self.vehicle)
wheels_info = [
((.75, .9, .3), True, 0),
((-0.75, .9, .3), True, 1),
((.75, -0.9, .3), False, 2),
((-0.75, -0.9, .3), False, 3)]
def add_wheel(pos, front, idx):
wheel = self.vehicle.createWheel()
wheel.setNode(self.wheels_np[idx].node())
wheel.setChassisConnectionPointCs(pos)
wheel.setFrontWheel(front)
wheel.setWheelDirectionCs((0, 0, -1))
wheel.setWheelRadius(.3)
wheel.setSuspensionStiffness(10)
map(lambda (pos, front, idx): add_wheel(pos, front, idx), wheels_info)
def update(self, task):
car_pos = self.car_np.get_pos()
self.cam.set_pos(car_pos.x - 15, car_pos.y - 15, car_pos.z + 5)
self.cam.look_at(car_pos.x, car_pos.y, car_pos.z)
map(lambda idx: self.vehicle.applyEngineForce(2000, idx), [2, 3])
self.world_phys.doPhysics(globalClock.getDt(), 10, 1 / 60.0)
return task.cont
def set_debug(self):
def toggle_debug():
is_hidden = self.debug_np.isHidden()
(self.debug_np.show if is_hidden else self.debug_np.hide)()
OnscreenText('press F9 for physics debug', pos=(0, -.9))
self.accept('f9', toggle_debug)
self.debug_np = self.render.attachNewNode(BulletDebugNode('Debug'))
self.world_phys.setDebugNode(self.debug_np.node())
def find_geoms(self, model, name):
def sibling_names(node):
siblings = node.getParent().getChildren()
return [child.getName() for child in siblings]
named_geoms = [
geom for geom in model.findAllMatches('**/+GeomNode')
if any([s.startswith(name) for s in sibling_names(geom)])]
in_vec = [name in named_geom.getName() for named_geom in named_geoms]
indexes = [i for i, el in enumerate(in_vec) if el]
return [named_geoms[i] for i in indexes]
VehicleTest().run()