def __init__(self, modelStanding, modelAnimationDict, turnRate, speed, agentList, massKg, collisionMask, name="", collisionHandler = None, collisionTraverser = None): NodePath.__init__(self, ActorNode(name + " actor node")) self.name = name self.actor = Actor() self.actor.loadModel(modelStanding) self.actor.loadAnims(modelAnimationDict) self.loop = self.actor.loop self.stop = self.actor.stop self.pose = self.actor.pose self.turnRate = turnRate self.speed = speed self.agentList = agentList self.massKg = massKg self.collisionMask = collisionMask if self.actor not in agentList: self.agentList.append(self.actor) self.actor.reparentTo(self) self.__setupCollisionHandling(collisionHandler, collisionTraverser)
def __init__(self, base, render, node1, node2, nodeMass=1, springConstant = 1, drag=5, actor1=None, actor2=None, lengthFactor =1): self._render = render self._base = base self._base.enableParticles() self._node1 = node1 self._node2 = node2 if not actor1: self._actor1 = ActorNode() node1 = NodePath("PhysicsNode1") node1.reparentTo(render) anp1 = node1.attachNewNode(self._actor1) base.physicsMgr.attachPhysicalNode(self._actor1) self._actor1.getPhysicsObject().setMass(nodeMass) self._node1.reparentTo(anp1) else: self._actor1 = actor1 if not actor2: node2 = NodePath("PhysicsNode2") node2.reparentTo(render) self._actor2 = ActorNode() anp2 = node2.attachNewNode(self._actor2) base.physicsMgr.attachPhysicalNode(self._actor2) self._actor2.getPhysicsObject().setMass(nodeMass) self._node2.reparentTo(anp2) else: self._actor2 = actor2 self._springConstant = float(springConstant) self._drag = float(drag) self.lastTime = globalClock.getDt() if lengthFactor == 1: self._zeroDistance = self._node1.getPos() - self._node2.getPos() else: vec = self._node1.getPos() - self._node2.getPos() vec = Vec3( (vec.x/lengthFactor), (vec.y/lengthFactor), (vec.z/lengthFactor) ) self._zeroDistance = vec self._force1 = None self._force2 = None self._lastPosNode1 = self._node1.getPos() self._lastPosNode2 = self._node2.getPos() self._impulse1 = None self._impulse2 = None self._timeOut = None
def __init__(self, name, world, pos): ActorNode.__init__(self, name) self.nodePath = NodePath(self) self.world = world # init the model or the Actor self.model = self.getModel() self.model.reparentTo(self.nodePath) self.nodePath.setPos(*pos) self.prevPos = self.nodePath.getPos() # collision detection fromObject = self.nodePath.attachNewNode(CollisionNode(name)) self.addSolids(fromObject) fromObject.show() # setup the ground ray, needed for detecting the ground groundRay = CollisionRay() groundRay.setOrigin(0, 0, 1000) groundRay.setDirection(0, 0, -1) groundCol = CollisionNode('groundRay') groundCol.addSolid(groundRay) groundCol.setFromCollideMask(BitMask32.bit(0)) groundCol.setIntoCollideMask(BitMask32.allOff()) groundColNp = base.camera.attachNewNode(groundCol) self.groundHandler = CollisionHandlerQueue() self.world.cTrav.addCollider(groundColNp, self.groundHandler) # self.world.cTrav.addCollider(fromObject, self.world.pusher) # self.world.pusher.addCollider(fromObject, self.nodePath) self.postInit()
avatarFloorHandler.setGravity(9.81 + 25) avatarFloorHandler.setMaxVelocity(100) #** the walls collider wallHandler = CollisionHandlerPusher() #** we'll use this to 'sense' the fallout impact velocity and also to 'read' various triggers we've put around the map for several purposes. collisionEvent = CollisionHandlerEvent() #** Collision masks - this time there is a new one: the TRIGGER_MASK is used to detect certain collision geometry to act as a trigger, therefore we need to distinguish'em from floor and walls. FLOOR_MASK = BitMask32.bit(1) WALL_MASK = BitMask32.bit(2) TRIGGER_MASK = BitMask32.bit(3) #** Our steering avatar avatarNP = base.render.attachNewNode(ActorNode('yolkyNP')) avatarNP.reparentTo(base.render) # by the way: this time we wont use the same old smiley but a 2d guy for this snippet purposes only - it is just a plane with a texture glued on, a so 2d object then. avatar = loader.loadModel('yolky') avatar.reparentTo(avatarNP) # why this? this is to have our flat puppet rendered always on top of all objects in the scene, either 2d and 3d. avatar.setDepthWrite(True, 100) # the rest of the stuff is as usual... avatar.setPos(0, 0, 1) avatar.setCollideMask(BitMask32.allOff()) avatarNP.setPos(0, 0, 15) # The yolky collision sphere used to detect when yolky hits walls avatarCollider = avatar.attachNewNode(CollisionNode('yolkycnode')) avatarCollider.node().addSolid(CollisionSphere(0, 0, 0, 1)) avatarCollider.node().setFromCollideMask(WALL_MASK) avatarCollider.node().setIntoCollideMask(BitMask32.allOff())
#========================================================================= #** Collision system ignition base.cTrav = CollisionTraverser() #** The floor collision handler - all stuff explained in step3 avatarFloorHandler = CollisionHandlerGravity() avatarFloorHandler.setGravity(9.81 + 25) avatarFloorHandler.setMaxVelocity(100) #** Collision masks FLOOR_MASK = BitMask32.bit(1) MASK_OFF = BitMask32.allOff() #** Our steering avatar avatarNP = base.render.attachNewNode(ActorNode('smileyNP')) avatarNP.reparentTo(base.render) avatar = loader.loadModel('smiley') avatar.reparentTo(avatarNP) avatar.setPos(0, 0, 1) avatar.setCollideMask(MASK_OFF) avatarNP.setPos(0, 0, 15) #** Stick and set the ray collider to the avatar raygeometry = CollisionRay(0, 0, 2, 0, 0, -1) avatarRay = avatarNP.attachNewNode(CollisionNode('avatarRay')) avatarRay.node().addSolid(raygeometry) # let's mask our floor FROM collider avatarRay.node().setFromCollideMask(FLOOR_MASK) avatarRay.node().setIntoCollideMask(MASK_OFF)
def __init__(self): ShowBase.__init__(self) # Load shaders. If this fails, quit. if(not self.loadShaders()): return #Make some floors for us :) floorTex=loader.loadTexture('maps/envir-ground.jpg') cm=CardMaker('') cm.setFrame(-2,2,-2,2) floor = render.attachNewNode(PandaNode("floor")) for y in range(12): for x in range(12): nn = floor.attachNewNode(cm.generate()) nn.setP(-90) nn.setPos((x-6)*4, (y-6)*4, 0) floor.setTexture(floorTex) floor.flattenStrong() # set up shaders and anti alias self.render.setShaderAuto() self.render.setAntialias(AntialiasAttrib.MAuto) # set up lights dlight = DirectionalLight('dlight') alight = AmbientLight('alight') dlnp = render.attachNewNode(dlight) alnp = render.attachNewNode(alight) dlight.setColor(Vec4(1.0, 0.7, 0.2, 1)) alight.setColor(Vec4(0.2, 0.2, 0.2, 1)) dlnp.setHpr(0, -60, 0) render.setLight(dlnp) render.setLight(alnp) # Models #Tron self.pandaActor = Actor("models/tron") self.pandaActor.setScale(0.3, 0.3, 0.3) self.pandaActor.reparentTo(self.render) self.pandaActor.setPos(10, 0, 4.2) #Panda # Load the "panda" model. Loading a model returns a # NodePath object. ##self.panda = loader.loadModel("panda") # Remember, loaded objects start out hidden! If we want to # see the panda, it must be reparented to the "render" node. ##self.panda.reparentTo(render) # By default, position is specified relative to a node's # parent.Position is specified as "x,y,z" or "right, forward, up" # Since panda's parent is the root node (render), # this command moves panda to the global position (0, 30, -5). ##self.panda.setPos(0, 0, 0) # Alternately, the position can be given relative to any other # NodePath. Here, we set the position to be 30 feet in front # of the camera, and slightly to the right. Note the use of # 'camera', another pre-defined NodePath object. ##self.panda.setX(camera, 10) # Text self.text = TextNode('node name') self.textNodePath = aspect2d.attachNewNode(self.text) self.textNodePath.setScale(0.05) self.text.setTextColor(1, 1, 1, 1) # enable physics base.enableParticles() self.physicsNode=NodePath(PandaNode("PhysicsNode")) self.physicsNode.reparentTo(render) # set up camera with physics self.cameraActorNode=ActorNode("camera-physics") self.cameraActorNodeParent=self.physicsNode.attachNewNode(self.cameraActorNode) base.physicsMgr.attachPhysicalNode(self.cameraActorNode) self.camera.reparentTo(self.cameraActorNodeParent) # set up camera and mouse settings self.camera.setPos(6.27662, -48.9656, 26.0119) self.camera.setHpr(7.30458, -27.7855, 3.34447) self.cameraInterval = self.camera.posInterval(10, Point3(10,10,20), startPos=Point3(camera.getPos())) self.cameraPace = Sequence(self.cameraInterval) self.cameraForwardThrottleEnabled = False #self.cameraPace.start() # disable debug mode for starters self.setDebugMode(False) # event handling self.accept("space", self.toggleGlow) self.accept("escape", sys.exit, [0]) self.accept('o', self.toggleDebugMode) self.accept('p', self.pauseSequence) self.accept('w', self.moveForward) self.accept('a', self.moveLeft) self.accept('d', self.moveRight) self.accept('s', self.moveBack) self.accept('arrow_up', self.enableCameraForwardThrottle) self.accept('arrow_up-up', self.disableCameraForwardThrottle) # add tasks self.taskMgr.add(self.doLogic, "DoLogic")
class MainApp(ShowBase): def __init__(self): ShowBase.__init__(self) # Load shaders. If this fails, quit. if(not self.loadShaders()): return #Make some floors for us :) floorTex=loader.loadTexture('maps/envir-ground.jpg') cm=CardMaker('') cm.setFrame(-2,2,-2,2) floor = render.attachNewNode(PandaNode("floor")) for y in range(12): for x in range(12): nn = floor.attachNewNode(cm.generate()) nn.setP(-90) nn.setPos((x-6)*4, (y-6)*4, 0) floor.setTexture(floorTex) floor.flattenStrong() # set up shaders and anti alias self.render.setShaderAuto() self.render.setAntialias(AntialiasAttrib.MAuto) # set up lights dlight = DirectionalLight('dlight') alight = AmbientLight('alight') dlnp = render.attachNewNode(dlight) alnp = render.attachNewNode(alight) dlight.setColor(Vec4(1.0, 0.7, 0.2, 1)) alight.setColor(Vec4(0.2, 0.2, 0.2, 1)) dlnp.setHpr(0, -60, 0) render.setLight(dlnp) render.setLight(alnp) # Models #Tron self.pandaActor = Actor("models/tron") self.pandaActor.setScale(0.3, 0.3, 0.3) self.pandaActor.reparentTo(self.render) self.pandaActor.setPos(10, 0, 4.2) #Panda # Load the "panda" model. Loading a model returns a # NodePath object. ##self.panda = loader.loadModel("panda") # Remember, loaded objects start out hidden! If we want to # see the panda, it must be reparented to the "render" node. ##self.panda.reparentTo(render) # By default, position is specified relative to a node's # parent.Position is specified as "x,y,z" or "right, forward, up" # Since panda's parent is the root node (render), # this command moves panda to the global position (0, 30, -5). ##self.panda.setPos(0, 0, 0) # Alternately, the position can be given relative to any other # NodePath. Here, we set the position to be 30 feet in front # of the camera, and slightly to the right. Note the use of # 'camera', another pre-defined NodePath object. ##self.panda.setX(camera, 10) # Text self.text = TextNode('node name') self.textNodePath = aspect2d.attachNewNode(self.text) self.textNodePath.setScale(0.05) self.text.setTextColor(1, 1, 1, 1) # enable physics base.enableParticles() self.physicsNode=NodePath(PandaNode("PhysicsNode")) self.physicsNode.reparentTo(render) # set up camera with physics self.cameraActorNode=ActorNode("camera-physics") self.cameraActorNodeParent=self.physicsNode.attachNewNode(self.cameraActorNode) base.physicsMgr.attachPhysicalNode(self.cameraActorNode) self.camera.reparentTo(self.cameraActorNodeParent) # set up camera and mouse settings self.camera.setPos(6.27662, -48.9656, 26.0119) self.camera.setHpr(7.30458, -27.7855, 3.34447) self.cameraInterval = self.camera.posInterval(10, Point3(10,10,20), startPos=Point3(camera.getPos())) self.cameraPace = Sequence(self.cameraInterval) self.cameraForwardThrottleEnabled = False #self.cameraPace.start() # disable debug mode for starters self.setDebugMode(False) # event handling self.accept("space", self.toggleGlow) self.accept("escape", sys.exit, [0]) self.accept('o', self.toggleDebugMode) self.accept('p', self.pauseSequence) self.accept('w', self.moveForward) self.accept('a', self.moveLeft) self.accept('d', self.moveRight) self.accept('s', self.moveBack) self.accept('arrow_up', self.enableCameraForwardThrottle) self.accept('arrow_up-up', self.disableCameraForwardThrottle) # add tasks self.taskMgr.add(self.doLogic, "DoLogic") # self.taskMgr.add(self.refreshGUI, "RefreshGUI") def enableCameraForwardThrottle(self): self.cameraForwardThrottleEnabled = True def disableCameraForwardThrottle(self): self.cameraForwardThrottleEnabled = False def refreshGUI(self, task): string = str(self.pandaActor.getPos()) self.text.setText(string) self.text.setCardColor(0, 0, 0, 0.5) self.text.setCardAsMargin(0, 0, 0, 0) return task.cont def moveForward(self): currentPosition = self.pandaActor.getPos() newPosition = Point3(0,2,0) + currentPosition pandaMoveForwardInterval = self.pandaActor.posInterval(0.1, Point3(newPosition), startPos=Point3(currentPosition)) self.pandaPace = Sequence(pandaMoveForwardInterval) self.pandaPace.start() return currentPosition def moveBack(self): currentPosition = self.pandaActor.getPos() newPosition = Point3(0,-2,0) + currentPosition pandaMoveForwardInterval = self.pandaActor.posInterval(0.1, Point3(newPosition), startPos=Point3(currentPosition)) self.pandaPace = Sequence(pandaMoveForwardInterval) self.pandaPace.start() return currentPosition def moveLeft(self): currentPosition = self.pandaActor.getPos() newPosition = Point3(-2,0,0) + currentPosition pandaMoveForwardInterval = self.pandaActor.posInterval(0.1, Point3(newPosition), startPos=Point3(currentPosition)) self.pandaPace = Sequence(pandaMoveForwardInterval) self.pandaPace.start() return currentPosition def moveRight(self): currentPosition = self.pandaActor.getPos() newPosition = Point3(2,0,0) + currentPosition pandaMoveForwardInterval = self.pandaActor.posInterval(0.1, Point3(newPosition), startPos=Point3(currentPosition)) self.pandaPace = Sequence(pandaMoveForwardInterval) self.pandaPace.start() return currentPosition def pauseSequence(self): self.pandaPace.pause() def doLogic(self, task): dt = globalClock.getDt() # this method is a placeholder to test if differnt stuff has occured # like checking wether the robot is ready for a new command, etc. if self.cameraForwardThrottleEnabled: currentVelocity = self.cameraActorNode.getPhysicsObject().getVelocity() newVelocity = currentVelocity + Vec3(dt*250,0,0) self.cameraActorNode.getPhysicsObject().setVelocity(newVelocity) # slow down camera ("friction") self.cameraActorNode.getPhysicsObject().setVelocity(self.cameraActorNode.getPhysicsObject().getVelocity() * 0.92) return Task.cont def toggleGlow(self): self.glowSize = self.glowSize + 1 if (self.glowSize == 4): self.glowSize = 0 self.filters.setBloom(blend=(0,0,0,1), desat=-0.5, intensity=3.0, size=self.glowSize) print "Glow size set to", self.glowSize def printCameraPosition(self): print self.camera.getPos() print self.camera.getHpr() def toggleDebugMode(self): if(self.debugMode): self.setDebugMode(False) else: self.setDebugMode(True) def setDebugMode(self, enabled): self.debugMode = enabled if(enabled): self.enableMouse() self.accept('c', self.printCameraPosition) else: self.disableMouse() self.ignore('c') def loadShaders(self): # Check video card capabilities for shaders. if (base.win.getGsg().getSupportsBasicShaders() == 0): addTitle("Glow Filter: Video driver reports that shaders are not supported.") return False # Load filters self.filters = CommonFilters(base.win, base.cam) filterok = self.filters.setBloom(blend=(0,0,0,1), desat=-0.5, intensity=3.0, size="small") if (filterok == False): addTitle("Toon Shader: Video card not powerful enough to do image postprocessing") return False self.glowSize=1 # Shadow shaders # TODO: Implement shadows return True
class Spring(object): def __init__(self, base, render, node1, node2, nodeMass=1, springConstant = 1, drag=5, actor1=None, actor2=None, lengthFactor =1): self._render = render self._base = base self._base.enableParticles() self._node1 = node1 self._node2 = node2 if not actor1: self._actor1 = ActorNode() node1 = NodePath("PhysicsNode1") node1.reparentTo(render) anp1 = node1.attachNewNode(self._actor1) base.physicsMgr.attachPhysicalNode(self._actor1) self._actor1.getPhysicsObject().setMass(nodeMass) self._node1.reparentTo(anp1) else: self._actor1 = actor1 if not actor2: node2 = NodePath("PhysicsNode2") node2.reparentTo(render) self._actor2 = ActorNode() anp2 = node2.attachNewNode(self._actor2) base.physicsMgr.attachPhysicalNode(self._actor2) self._actor2.getPhysicsObject().setMass(nodeMass) self._node2.reparentTo(anp2) else: self._actor2 = actor2 self._springConstant = float(springConstant) self._drag = float(drag) self.lastTime = globalClock.getDt() if lengthFactor == 1: self._zeroDistance = self._node1.getPos() - self._node2.getPos() else: vec = self._node1.getPos() - self._node2.getPos() vec = Vec3( (vec.x/lengthFactor), (vec.y/lengthFactor), (vec.z/lengthFactor) ) self._zeroDistance = vec self._force1 = None self._force2 = None self._lastPosNode1 = self._node1.getPos() self._lastPosNode2 = self._node2.getPos() self._impulse1 = None self._impulse2 = None self._timeOut = None #self._base.taskMgr.add(self.timer, "update") def timer(self): actor1 = self._actor1.getPhysical(0) actor2 = self._actor2.getPhysical(0) if self._force1: actor1.removeLinearForce(self._force1) actor2.removeLinearForce(self._force2) if self._impulse1: if globalClock.getLongTime() > self._timeOut: print "removing perturbation" try: actor1.removeLinearForce(self._impulse1) actor2.removeLinearForce(self._impulse2) except Exception, e: print e print "failed" self._impulse1 = None self._impulse2 = None self._timeOut = None force = self.getForce() #print force if force: try: forceVector = self._node1.getPos() - self._node2.getPos() self._force1 = ForceNode('force1') self._node1.attachNewNode(self._force1) force2 = self._node2.getRelativeVector( self._node1, force) lvf1 = LinearVectorForce(force.x , force.y, force.z) #print force self._force1.addForce( lvf1 ) lvf1.setMassDependent(1) self._force2 = ForceNode('force2') self._node2.attachNewNode(self._force2) lvf2 = LinearVectorForce( LinearVectorForce( Vec3( -1* force2.x, -1 * force2.y, -1* force2.z))) lvf2.setMassDependent(1) self._force2.addForce(lvf2) #self._base.physicsMgr.addLinearForce(lvf1) #self._base.physicsMgr.addLinearForce(lvf2) self._actor1.getPhysical(0).addLinearForce(lvf1) self._actor2.getPhysical(0).addLinearForce(lvf2) self._force1 = lvf1 self._force2 = lvf2 except: traceback.print_exc() pass