def __init__(self, geom, offset=p3d.LVector3f(0, 0, 0)): super().__init__() mesh = bullet.BulletTriangleMesh() for i in range(geom.node().get_num_geoms()): mesh.add_geom(geom.node().get_geom(i)) shape = bullet.BulletTriangleMeshShape(mesh, dynamic=False) self.physics_node = bullet.BulletRigidBodyNode('StaticMesh') xform_state = p3d.TransformState.make_pos(offset) self.physics_node.add_shape(shape, xform_state) self.physics_node.set_python_tag('component', self)
def Create(cls, *args, **kwargs): if 'inputNp' in kwargs: inputNp = kwargs['inputNp'] elif 'path' in kwargs: inputNp = cls(cls.FindChild(kwargs['path'], kwargs['parent'])) return inputNp else: return cls(pm.NodePath(blt.BulletRigidBodyNode(''))) # Get all geom nodes at this level and below. #geomNps = inputNp.findAllMatches( '**/+GeomNode' ) #if inputNp.node().isOfType( pm.GeomNode ): # geomNps.addPath( inputNp ) geomNps = [inputNp] # Get a flat list of all geoms. geoms = [] for geomNp in geomNps: geoms.extend(geomNp.node().getGeoms()) mesh = blt.BulletTriangleMesh() for geom in geoms: mesh.addGeom(geom) shape = blt.BulletTriangleMeshShape(mesh, dynamic=False) rBody = blt.BulletRigidBodyNode(inputNp.getName()) rBody.addShape(shape) # Swap the original NodePath for the one we just created. np = pm.NodePath(rBody) np.reparentTo(inputNp.getParent()) np.setTag(game.nodes.TAG_NODE_TYPE, TAG_EMBEDDED_BULLET_TRIANGLE_MESH_SHAPE) inputNp.detachNode() wrpr = cls(np) wrpr.CreateNewId() return wrpr
def __init__(self): super().__init__() self.height = 1.75 self.air_control = 0.8 self.airborne = False radius = 0.4 step_height = 0.8 shape = bullet.BulletCapsuleShape(radius, self.height - 2 * radius, bullet.ZUp) self.physics_node = bullet.BulletRigidBodyNode('Character') self.physics_node.add_shape(shape) self.physics_node.set_angular_factor(0) self.physics_node.set_mass(80.0) self.physics_node.set_deactivation_enabled(False)
def load_physics_bullet(self, node_name, geomnode, shape_type, bounding_box, radius, height, gltf_rigidbody): shape = None static = 'static' in gltf_rigidbody and gltf_rigidbody['static'] if shape_type == 'BOX': shape = bullet.BulletBoxShape(LVector3(*bounding_box) / 2.0) elif shape_type == 'SPHERE': shape = bullet.BulletSphereShape(max(bounding_box) / 2.0) elif shape_type == 'CAPSULE': shape = bullet.BulletCapsuleShape(radius, height - 2.0 * radius, bullet.ZUp) elif shape_type == 'CYLINDER': shape = bullet.BulletCylinderShape(radius, height, bullet.ZUp) elif shape_type == 'CONE': shape = bullet.BulletConeShape(radius, height, bullet.ZUp) elif shape_type == 'CONVEX_HULL': if geomnode: shape = bullet.BulletConvexHullShape() for geom in geomnode.get_geoms(): shape.add_geom(geom) elif shape_type == 'MESH': if geomnode: mesh = bullet.BulletTriangleMesh() for geom in geomnode.get_geoms(): mesh.add_geom(geom) shape = bullet.BulletTriangleMeshShape(mesh, dynamic=not static) else: print("Unknown collision shape ({}) for object ({})".format( shape_type, nodeid)) if shape is not None: phynode = bullet.BulletRigidBodyNode(node_name) phynode.add_shape(shape) if not static: phynode.set_mass(gltf_rigidbody['mass']) return phynode else: print("Could not create collision shape for object ({})".format( nodeid))
def OnDuplicate(self, origNp, dupeNp): # Duplicate doesn't work for rigid body nodes... foo = blt.BulletRigidBodyNode(origNp.getName()) bar = pm.NodePath(foo) bar.reparentTo(self.data.getParent()) self.data.detachNode() self.data = bar self.data.setTag(game.nodes.TAG_NODE_TYPE, TAG_EMBEDDED_BULLET_TRIANGLE_MESH_SHAPE) #self.SetupNodePath() #print 'DUPE: ', self.data #print 'new: ', dupeNp, ' : ', self.data #print 'from: ', dupeNp for shape in origNp.node().getShapes(): copShape = copy.copy(shape) self.data.node().addShape(copShape) BulletRigidBodyNode.OnDuplicate(self, origNp, dupeNp) return self.data
def add_node(root, gltf_scene, nodeid): if nodeid not in gltf_data['nodes']: print("Could not find node with id: {}".format(nodeid)) return gltf_node = gltf_data['nodes'][nodeid] if 'jointName' in gltf_node: # don't handle joints here return panda_node = self.nodes[nodeid] if 'extras' in gltf_scene and 'hidden_nodes' in gltf_scene[ 'extras']: if nodeid in gltf_scene['extras']['hidden_nodes']: panda_node = panda_node.make_copy() np = self.node_paths.get(nodeid, root.attach_new_node(panda_node)) self.node_paths[nodeid] = np if 'meshes' in gltf_node: np_tmp = np if 'skeletons' in gltf_node: char = self.characters[gltf_node['name']] np_tmp = np.attach_new_node(char) for meshid in gltf_node['meshes']: mesh = self.meshes[meshid] np_tmp.attach_new_node(mesh) if 'camera' in gltf_node: camid = gltf_node['camera'] cam = self.cameras[camid] np.attach_new_node(cam) if 'extensions' in gltf_node: if 'KHR_materials_common' in gltf_node['extensions']: lightid = gltf_node['extensions']['KHR_materials_common'][ 'light'] light = self.lights[lightid] if copy_lights: light = light.make_copy() lnp = np.attach_new_node(light) if isinstance(light, Light): root.set_light(lnp) if HAVE_BULLET and 'BLENDER_physics' in gltf_node['extensions']: phy = gltf_node['extensions']['BLENDER_physics'] shape = None collision_shape = phy['collisionShapes'][0] bounding_box = collision_shape['boundingBox'] radius = max(bounding_box[0], bounding_box[1]) / 2.0 height = bounding_box[2] geomnode = None static = 'static' in phy and phy['static'] if 'mesh' in collision_shape: try: geomnode = self.meshes[collision_shape['mesh']] except KeyError: print( "Could not find physics mesh ({}) for object ({})" .format(collision_shape['mesh'], nodeid)) shape_type = collision_shape['shapeType'] if shape_type == 'BOX': shape = bullet.BulletBoxShape( LVector3(*bounding_box) / 2.0) elif shape_type == 'SPHERE': shape = bullet.BulletSphereShape( max(bounding_box) / 2.0) elif shape_type == 'CAPSULE': shape = bullet.BulletCapsuleShape( radius, height - 2.0 * radius, bullet.ZUp) elif shape_type == 'CYLINDER': shape = bullet.BulletCylinderShape( radius, height, bullet.ZUp) elif shape_type == 'CONE': shape = bullet.BulletConeShape(radius, height, bullet.ZUp) elif shape_type == 'CONVEX_HULL': if geomnode: shape = bullet.BulletConvexHullShape() for geom in geomnode.get_geoms(): shape.add_geom(geom) elif shape_type == 'MESH': if geomnode: mesh = bullet.BulletTriangleMesh() for geom in geomnode.get_geoms(): mesh.add_geom(geom) shape = bullet.BulletTriangleMeshShape( mesh, dynamic=not static) else: print("Unknown collision shape ({}) for object ({})". format(shape_type, nodeid)) if shape is not None: phynode = bullet.BulletRigidBodyNode(gltf_node['name']) phynode.add_shape(shape) np.attach_new_node(phynode) if not static: phynode.set_mass(phy['mass']) else: print( "Could not create collision shape for object ({})". format(nodeid)) elif not HAVE_BULLET: print( "Bullet is unavailable, not converting collision shape for object ({})" .format(nodeid)) if 'extras' in gltf_node: for key, value in gltf_node['extras'].items(): np.set_tag(key, str(value)) for child_nodeid in gltf_node.get('children', []): add_node(np, gltf_scene, child_nodeid) # Handle visibility after children are loaded def visible_recursive(node, visible): if visible: node.show() else: node.hide() for child in node.get_children(): visible_recursive(child, visible) if 'extras' in gltf_scene and 'hidden_nodes' in gltf_scene[ 'extras']: if nodeid in gltf_scene['extras']['hidden_nodes']: #print('Hiding', np) visible_recursive(np, False) else: #print('Showing', np) visible_recursive(np, True) # Check if we need to deal with negative scale values scale = panda_node.get_transform().get_scale() negscale = scale.x * scale.y * scale.z < 0 if negscale: for geomnode in np.find_all_matches('**/+GeomNode'): tmp = geomnode.get_parent().attach_new_node( PandaNode('ReverseCulling')) tmp.set_attrib(CullFaceAttrib.make_reverse()) geomnode.reparent_to(tmp)