class DynamicBox(DynamicObject): def __init__(self, name, game, pos): self.name = name self.game = game self.shape = BulletBoxShape(Vec3(0.5, 0.5, 0.5)) self.node = BulletRigidBodyNode(name) self.node.setMass(10.0) self.node.addShape(self.shape) self.setFriction(20) self.np = self.game.render.attachNewNode(self.node) self.np.setPos(pos) self.game.world.attachRigidBody(self.node) self.model = self.game.loader.loadModel("models/crate.egg") self.model.reparentTo(self.np) self.node.setCcdMotionThreshold(1e-7) self.node.setCcdSweptSphereRadius(0.5) self.debugOff() self.slice_able = True def update(self, dt): #self.activate() #if self.node.isActive(): # return contact = self.checkFeet() contacts = self.getContacts() if contact in self.game.objects and contact in contacts: obj = self.game.objects[contact] if type(obj) is KinematicPlatform: self.activate() self.setAngularVelocity(self.getAngularVelocity()*0.9) self.setFriction(0.1) #print "%s is a box sliding on %s" % (self.name, obj.name) #self.addSpeedVec(self.game.objects[contact].getSpeedVec()) #self.setForce(obj.getSpeedVec()*self.node.getMass() * 100) platform_speed = obj.getSpeedVec() force = platform_speed * self.node.getMass() * 50 #self.setSpeedXY(platform_speed[0], platform_speed[1]) self.setSpeedVec(platform_speed) #self.setAngularVelocity(0) #self.node.addLin(obj.getSpeedVec()*self.node.getMass() * 100) #self.node.applyCentralForce(force) #self.setForce(force) #self.setFriction(20) #self.setPos(self.getPos() + obj.getSpeedVec()) #self.node.setActive(False) else: self.setFriction(20)
class DynamicBox(DynamicObject): def __init__(self, name, game, pos): self.name = name self.game = game self.shape = BulletBoxShape(Vec3(0.5, 0.5, 0.5)) self.node = BulletRigidBodyNode(name) self.node.setMass(10.0) self.node.addShape(self.shape) self.setFriction(20) self.np = self.game.render.attachNewNode(self.node) self.np.setPos(pos) self.game.world.attachRigidBody(self.node) self.model = self.game.loader.loadModel("models/crate.egg") self.model.reparentTo(self.np) self.node.setCcdMotionThreshold(1e-7) self.node.setCcdSweptSphereRadius(0.5) self.debugOff() self.slice_able = True def update(self, dt): #self.activate() #if self.node.isActive(): # return contact = self.checkFeet() contacts = self.getContacts() if contact in self.game.objects and contact in contacts: obj = self.game.objects[contact] if type(obj) is KinematicPlatform: self.activate() self.setAngularVelocity(self.getAngularVelocity() * 0.9) self.setFriction(0.1) #print "%s is a box sliding on %s" % (self.name, obj.name) #self.addSpeedVec(self.game.objects[contact].getSpeedVec()) #self.setForce(obj.getSpeedVec()*self.node.getMass() * 100) platform_speed = obj.getSpeedVec() force = platform_speed * self.node.getMass() * 50 #self.setSpeedXY(platform_speed[0], platform_speed[1]) self.setSpeedVec(platform_speed) #self.setAngularVelocity(0) #self.node.addLin(obj.getSpeedVec()*self.node.getMass() * 100) #self.node.applyCentralForce(force) #self.setForce(force) #self.setFriction(20) #self.setPos(self.getPos() + obj.getSpeedVec()) #self.node.setActive(False) else: self.setFriction(20)
def _initObjects(self): # Load objects for model in self.scene.scene.findAllMatches('**/objects/object*/model*'): modelId = model.getParent().getTag('model-id') # XXX: we could create BulletGhostNode instance for non-collidable objects, # but we would need to filter out the collisions later on if modelId not in self.openedDoorModelIds: # NOTE: ignore models that have no geometry defined if model.getTightBounds() is None: logger.warning('Object %s has no geometry defined and will be ignored for physics!' % (str(model))) continue shape, transform = getCollisionShapeFromModel( model, self.objectMode, defaultCentered=True) node = BulletRigidBodyNode('physics') node.addShape(shape) node.setFriction(self.defaultMaterialFriction) node.setRestitution(self.defaultMaterialRestitution) node.setIntoCollideMask(BitMask32.allOn()) node.setDeactivationEnabled(True) if self.suncgDatasetRoot is not None: # Check if it is a movable object category = self.modelCatMapping.getCoarseGrainedCategoryForModelId( modelId) if category in self.movableObjectCategories: # Estimate mass of object based on volumetric data and # default material density objVoxFilename = os.path.join( self.suncgDatasetRoot, 'object_vox', 'object_vox_data', modelId, modelId + '.binvox') voxelData = ObjectVoxelData.fromFile(objVoxFilename) mass = Panda3dBulletPhysics.defaultDensity * voxelData.getFilledVolume() node.setMass(mass) else: node.setMass(0.0) node.setStatic(True) else: node.setMass(0.0) node.setStatic(True) if node.isStatic(): model.getParent().setTag('physics-mode', 'static') else: model.getParent().setTag('physics-mode', 'dynamic') model.getParent().setTag('mass', str(node.getMass())) # Attach the physic-related node to the scene graph physicsNp = model.getParent().attachNewNode(node) physicsNp.setTransform(transform) # Reparent render and acoustics nodes (if any) below the new physic node # XXX: should be less error prone to just reparent all children # (except the hidden model) renderNp = model.getParent().find('**/render') if not renderNp.isEmpty(): renderNp.reparentTo(physicsNp) acousticsNp = model.getParent().find('**/acoustics') if not acousticsNp.isEmpty(): acousticsNp.reparentTo(physicsNp) semanticsNp = model.getParent().find('**/semantics') if not semanticsNp.isEmpty(): semanticsNp.reparentTo(physicsNp) # NOTE: we need this to update the transform state of the # internal bullet node node.setTransformDirty() # NOTE: we need to add the node to the bullet engine only after # setting all attributes self.bulletWorld.attach(node) # Validation assert np.allclose(mat4ToNumpyArray(physicsNp.getNetTransform().getMat()), mat4ToNumpyArray(model.getParent().getNetTransform().getMat()), atol=1e-6) else: logger.debug('Object %s ignored from physics' % (modelId))