class EscapeFromJCMB(object, DirectObject): def __init__(self): print "Loading..." self.init_window() self.init_music() self.init_bullet() self.init_key() self.load_world() self.init_player() self.init_objects() render.prepareScene(base.win.getGsg()) print "Done" self.start_physics() def init_window(self): # Hide the mouse cursor props = WindowProperties() props.setCursorHidden(True) base.win.requestProperties(props) def init_music(self): music = base.loader.loadSfx("../data/snd/Bent_and_Broken.mp3") music.play() self.playferscream = base.loader.loadSfx("../data/snd/deadscrm.wav") def init_bullet(self): self.world = BulletWorld() self.world.setGravity(Vec3(0, 0, -9.81)) # debugNode = BulletDebugNode('Debug') # debugNode.showWireframe(True) # debugNode.showConstraints(True) # debugNode.showBoundingBoxes(False) # debugNode.showNormals(False) # debugNP = render.attachNewNode(debugNode) # debugNP.show() # self.world.setDebugNode(debugNP.node()) alight = AmbientLight('alight') alight.setColor(VBase4(0.05, 0.05, 0.05, 1)) alnp = render.attachNewNode(alight) render.setLight(alnp) def init_key(self): # Stores the state of the keys, 1 for pressed and 0 for unpressed self.key_state = { 'up': False, 'right': False, 'down': False, 'left': False } # Assign the key event handler self.accept('w', self.set_key_state, ['up', True]) self.accept('w-up', self.set_key_state, ['up', False]) self.accept('d', self.set_key_state, ['right', True]) self.accept('d-up', self.set_key_state, ['right', False]) self.accept('s', self.set_key_state, ['down', True]) self.accept('s-up', self.set_key_state, ['down', False]) self.accept('a', self.set_key_state, ['left', True]) self.accept('a-up', self.set_key_state, ['left', False]) # Stores the state of the mouse buttons, 1 for pressed and 0 for unpressed self.mouse_state = {'left_click': False, 'right_click': False} # Assign the mouse click event handler self.accept('mouse1', self.set_mouse_state, ['left_click', True]) self.accept('mouse1-up', self.set_mouse_state, ['left_click', False]) self.accept('mouse2', self.set_mouse_state, ['right_click', True]) self.accept('mouse2-up', self.set_mouse_state, ['right_click', False]) self.accept('z', self.print_pos) # Esc self.accept('escape', sys.exit) def set_key_state(self, key, state): self.key_state[key] = state def set_mouse_state(self, button, state): self.mouse_state[button] = state def print_pos(self): print self.playernp.getPos() def egg_to_BulletTriangleMeshShape(self, modelnp): mesh = BulletTriangleMesh() for collisionNP in modelnp.findAllMatches('**/+CollisionNode'): collisionNode = collisionNP.node() for collisionPolygon in collisionNode.getSolids(): tri_points = collisionPolygon.getPoints() mesh.addTriangle(tri_points[0], tri_points[1], tri_points[2]) shape = BulletTriangleMeshShape(mesh, dynamic=False) return shape def load_world(self): stairwell = loader.loadModel('../data/mod/jcmbstairs.egg') stairwell.reparentTo(render) stairwell_shape = self.egg_to_BulletTriangleMeshShape(stairwell) stairwellnode = BulletRigidBodyNode('stairwell') stairwellnode.addShape(stairwell_shape) self.world.attachRigidBody(stairwellnode) def init_player(self): # Stop the default mouse behaviour base.disableMouse() # Character has a capsule shape shape = BulletCapsuleShape(0.2, 1, ZUp) self.player = BulletRigidBodyNode('Player') self.player.setMass(80.0) self.player.addShape(shape) self.playernp = render.attachNewNode(self.player) self.playernp.setPos(0, 0, 1) self.world.attachRigidBody(self.player) self.player.setLinearSleepThreshold(0.0) self.player.setAngularFactor(0.0) self.player_speed = 3 self.player_is_grabbing = False # self.head = BulletRigidBodyNode('Player Head') # self.head.addShape(BulletSphereShape(0.2)) # self.head.setMass(10) # self.head.setInertia(Vec3(1,1,1)) # self.head.setAngularFactor(1.0) # self.head.setLinearFactor(0.0) # self.headnp = self.playernp.attachNewNode(self.head) # self.headnp.setPos(0,0,0) # self.headnp.setCollideMask(BitMask32.allOff()) # self.world.attachRigidBody(self.head) # Attach the camera to the player's head base.camera.reparentTo(self.playernp) # base.camera.setPos(0,0,.5) base.camLens.setFov(80) base.camLens.setNear(0.01) # Make the torch and attach it to our character torch = Spotlight('torch') torch.setColor(VBase4(1, 1, 1, 1)) lens = PerspectiveLens() lens.setFov(80) lens.setNearFar(20, 100) torch.setLens(lens) self.torchnp = base.camera.attachNewNode(torch) self.torchnp.setPos(0, 0, 0) # Allow the world to be illuminated by our torch render.setLight(self.torchnp) self.cs = None # Player's "hand" in the world hand_model = loader.loadModel('../data/mod/hand.egg') hand_model.setScale(1) hand_model.setBillboardPointEye() self.hand = BulletRigidBodyNode('Hand') self.hand.addShape(BulletSphereShape(0.1)) self.hand.setLinearSleepThreshold(0.0) self.hand.setLinearDamping(0.9999999) self.hand.setAngularFactor(0.0) self.hand.setMass(1.0) self.world.attachRigidBody(self.hand) self.handnp = render.attachNewNode(self.hand) self.handnp.setCollideMask(BitMask32.allOff()) # hand_model.reparentTo(self.handnp) # Create a text node to display object identification information and attach it to the player's "hand" self.hand_text = TextNode('Hand Text') self.hand_text.setText("Ch-ch-chek yoself befo yo rek yoself, bro.") self.hand_text.setAlign(TextNode.ACenter) self.hand_text.setTextColor(1, 1, 1, 1) self.hand_text.setShadow(0.05, 0.05) self.hand_text.setShadowColor(0, 0, 0, 1) self.hand_text_np = render.attachNewNode(self.hand_text) self.hand_text_np.setScale(0.03) self.hand_text_np.setBillboardPointEye() self.hand_text_np.hide() # Disable the depth testing for the hand and the text - we always want these things on top, with no clipping self.handnp.setDepthTest(False) self.hand_text_np.setDepthTest(False) # Add the player update task taskMgr.add(self.update, 'update_player_task') def init_objects(self): # Make Playfer Box shape = BulletBoxShape(Vec3(0.25, 0.25, 0.25)) node = BulletRigidBodyNode('Playfer Box') node.setMass(110.0) node.setFriction(1.0) node.addShape(shape) node.setAngularDamping(0.0) np = render.attachNewNode(node) np.setPos(-1.4, 1.7, -1.7) self.world.attachRigidBody(node) playferboxmodel = loader.loadModel('../data/mod/playferbox.egg') playferboxmodel.reparentTo(np) # Make Pendlepot shape = BulletBoxShape(Vec3(0.2, 0.15, 0.1)) node = BulletRigidBodyNode('Pendlepot') node.setMass(5.0) node.setFriction(1.0) node.addShape(shape) node.setAngularDamping(0.0) np = render.attachNewNode(node) np.setPos(-1.4, 1.7, -1.5) self.world.attachRigidBody(node) pendlepotmodel = loader.loadModel('../data/mod/pendlepot.egg') pendlepotmodel.reparentTo(np) def update(self, task): # Update camera orientation md = base.win.getPointer(0) mouse_x = md.getX() mouse_y = md.getY() centre_x = base.win.getXSize() / 2 centre_y = base.win.getYSize() / 2 if base.win.movePointer(0, centre_x, centre_y): new_H = base.camera.getH() + (centre_x - mouse_x) new_P = base.camera.getP() + (centre_y - mouse_y) if new_P < -90: new_P = -90 elif new_P > 90: new_P = 90 base.camera.setH(new_H) base.camera.setP(new_P) # Update player position speed = 3 self.player_is_moving = False if (self.key_state["up"] == True): self.player_is_moving = True dir = 0 if (self.key_state["down"] == True): self.player_is_moving = True dir = 180 if (self.key_state["left"] == True): self.player_is_moving = True dir = 90 if (self.key_state["right"] == True): self.player_is_moving = True dir = 270 self.player.clearForces() old_vel = self.player.getLinearVelocity() new_vel = Vec3(0, 0, 0) if self.player_is_moving == True: new_vel.setX(-speed * math.sin( (base.camera.getH() + dir) * 3.1415 / 180.0)) new_vel.setY(speed * math.cos( (base.camera.getH() + dir) * 3.1415 / 180.0)) timescale = 0.001 linear_force = (new_vel - old_vel) / (timescale) linear_force.setZ(0.0) self.player.applyCentralForce(linear_force) if self.player_is_grabbing == False: new_hand_pos = LPoint3f( render.getRelativePoint(base.camera, Vec3(0, 0.2, 0))) self.handnp.setPos(new_hand_pos) else: new_hand_pos = LPoint3f( render.getRelativePoint(base.camera, Vec3(0, 0.5, 0))) diff = new_hand_pos - self.handnp.getPos() self.hand.applyCentralForce(diff * 1000 - self.hand.getLinearVelocity() * 100) if diff.length() > .5: self.player.setLinearVelocity(Vec3(0, 0, 0)) # Identify what lies beneath the player's hand (unless player is holding something) if self.player_is_grabbing == False: ray_from = self.playernp.getPos() ray_to = LPoint3f( render.getRelativePoint(base.camera, Vec3(0, 1, 0))) result = self.world.rayTestClosest(ray_from, ray_to) if result.hasHit() == True: self.hand_text.setText(result.getNode().getName()) self.hand_text_np.setPos(result.getHitPos()) self.hand_text_np.show() # If player clicks, grab the object by the nearest point (as chosen by ray) if self.mouse_state["left_click"] == True: if result.getNode().getNumChildren() == 1: obj = NodePath(result.getNode().getChild(0)) if self.player_is_grabbing == False: self.player_is_grabbing = True # Find the position of contact in terms of the object's local coordinates. # Parent the player's hand to the grabbed object at that position. pos = obj.getRelativePoint(render, result.getHitPos()) self.grabbed_node = result.getNode() self.grabbed_node.setActive(True) print self.grabbed_node frameA = TransformState.makePosHpr( Vec3(0, 0, 0), Vec3(0, 0, 0)) frameB = TransformState.makePosHpr( Vec3(0, 0, 0), Vec3(0, 0, 0)) swing1 = 20 # degrees swing2 = 20 # degrees twist = 20 # degrees self.cs = BulletConeTwistConstraint( self.hand, result.getNode(), frameA, frameB) self.cs.setLimit(swing1, swing2, twist) self.world.attachConstraint(self.cs) # Stop the held object swinging all over the place result.getNode().setAngularDamping(0.7) else: self.hand_text_np.hide() self.player_is_grabbing = False if self.mouse_state["left_click"] == False: self.player_is_grabbing = False if self.cs != None: self.world.remove_constraint(self.cs) self.cs = None self.grabbed_node.setAngularDamping(0.0) if self.player_is_grabbing == True and self.mouse_state[ "right_click"] == True: self.world.remove_constraint(self.cs) self.cs = None self.grabbed_node.setAngularDamping(0.0) self.grabbed_node.setActive(True) self.grabbed_node.applyCentralImpulse(1000, 0, 0) if self.player_is_grabbing == True: self.hand_text_np.hide() return task.cont def update_physics(self, task): dt = globalClock.getDt() self.world.doPhysics(dt) return task.cont def start_physics(self): taskMgr.add(self.update_physics, 'update_physics')
class Game(DirectObject): def __init__(self): base.setBackgroundColor(0.1, 0.1, 0.5, 1) base.setFrameRateMeter(True) base.cam.setPos(0, -20, 5) base.cam.lookAt(0, 0, 0) base.disableMouse() self.zoom = 50; self.viewPoint = "FRONT" # Light alight = AmbientLight('ambientLight') alight.setColor(Vec4(0.5, 0.5, 0.5, 1)) alightNP = render.attachNewNode(alight) dlight = DirectionalLight('directionalLight') dlight.setDirection(Vec3(1, 1, -1)) dlight.setColor(Vec4(0.7, 0.7, 0.7, 1)) dlightNP = render.attachNewNode(dlight) render.clearLight() render.setLight(alightNP) render.setLight(dlightNP) #bot self.ankleJont = 0 self.foot = 0 self.kneeJoint = 0 self.hipKneeJoint = 0 # Input self.accept('escape', self.doExit) self.accept('r', self.doReset) self.accept('f1', self.toggleWireframe) self.accept('f2', self.toggleTexture) self.accept('f3', self.toggleDebug) self.accept('f5', self.doScreenshot) self.accept('enter', self.doShoot) self.accept('a',self.setAngleMax) self.accept('o',self.setAngleMin) self.accept('1', self.setViewPointTOP) self.accept('2', self.setViewPointFRONT) self.accept('3', self.setViewPointLEFT) self.accept('4', self.setViewPointDIAG) self.accept('b', self.setZoomInc) self.accept('m', self.setZoomDec) # Task taskMgr.add(self.update, 'updateWorld') # Physics self.setup() # _____HANDLER_____ def setViewPoint(self,view): self.viewPoint = view if(view == "TOP"): base.cam.setPos(0,0,self.zoom) elif(view == "FRONT"): base.cam.setPos(0,-self.zoom,0) elif(view == "LEFT"): base.cam.setPos(-self.zoom,0,0) elif(view == "DIAG"): base.cam.setPos(self.zoom,self.zoom,self.zoom) base.cam.lookAt(0, 0, 0) def setViewPointTOP(self): self.setViewPoint("TOP") def setViewPointFRONT(self): self.setViewPoint("FRONT") def setViewPointLEFT(self): self.setViewPoint("LEFT") def setViewPointDIAG(self): self.setViewPoint("DIAG") def setZoomLevel(self,zoom): self.zoom = zoom self.setViewPoint(self.viewPoint) def setZoomInc(self): self.setZoomLevel(self.zoom+10) def setZoomDec(self): self.setZoomLevel(self.zoom-10) def doExit(self): self.cleanup() sys.exit(1) def doReset(self): self.cleanup() self.setup() def toggleWireframe(self): base.toggleWireframe() def toggleTexture(self): base.toggleTexture() def toggleDebug(self): if self.debugNP.isHidden(): self.debugNP.show() else: self.debugNP.hide() def doScreenshot(self): base.screenshot('Bullet') def setAngleMax(self): # self.kneeJoint.setMotorTarget(180,2) self.foot.applyTorqueImpulse(Vec3(1,1,1)) self.foot.applyForce(Vec3(1,1,1),Vec3(1,1,1)) def setAngleMin(self): self.foot.applyTorqueImpulse(Vec3(-1,-1,-1)) # self.kneeJoint.setMotorTarget(0,2) def doShoot(self): # Get from/to points from mouse click pMouse = base.mouseWatcherNode.getMouse() pFrom = Point3() pTo = Point3() base.camLens.extrude(pMouse, pFrom, pTo) pFrom = render.getRelativePoint(base.cam, pFrom) pTo = render.getRelativePoint(base.cam, pTo) # Calculate initial velocity v = pTo - pFrom v.normalize() v *= 100.0 # Create bullet shape = BulletSphereShape(0.3) body = BulletRigidBodyNode('Bullet') bodyNP = self.worldNP.attachNewNode(body) bodyNP.node().addShape(shape) bodyNP.node().setMass(1.0) bodyNP.node().setLinearVelocity(v) bodyNP.node().setCcdMotionThreshold(1e-7); bodyNP.node().setCcdSweptSphereRadius(0.50); bodyNP.setCollideMask(BitMask32.allOn()) bodyNP.setPos(pFrom) visNP = loader.loadModel('models/ball.egg') visNP.setScale(0.8) visNP.reparentTo(bodyNP) self.world.attachRigidBody(bodyNP.node()) # Remove the bullet again after 2 seconds taskMgr.doMethodLater(2, self.doRemove, 'doRemove', extraArgs=[bodyNP], appendTask=True) def doRemove(self, bodyNP, task): self.world.removeRigidBody(bodyNP.node()) bodyNP.removeNode() return task.done # ____TASK___ def update(self, task): angle = self.kneeJoint.getHingeAngle() impulse = self.kneeJoint.getAppliedImpulse() self.kneeJointText.setText("kneeJoint:\n Angle: %0.2f\n Impulse: %0.2f" % (angle, impulse)) angle = self.ankleJoint.getHingeAngle() impulse = self.ankleJoint.getAppliedImpulse() self.ankleJointText.setText("ankleJoint:\n Angle: %0.2f\n Impulse: %0.2f" % (angle, impulse)) force = self.hLeg.getTotalForce() t = self.hLeg.getTotalTorque() self.hLegText.setText("High Leg:\nForce: %0.2f,%0.2f,%0.2f\nTorque: %0.2f,%0.2f,%0.2f" % (force.x, force.y, force.z, t.x,t.y,t.z)) force = self.lLeg.getTotalForce() t = self.lLeg.getTotalTorque() self.lLegText.setText("Low Leg:\nForce: %0.2f,%0.2f,%0.2f\nTorque: %0.2f,%0.2f,%0.2f" % (force.x, force.y, force.z, t.x,t.y,t.z)) f = self.foot.getTotalForce() t = self.foot.getTotalTorque() self.footText.setText("Foot:\nForce: %0.2f,%0.2f,%0.2f\nTorque: %0.2f,%0.2f,%0.2f" % (f.x,f.y,f.z, t.x,t.y,t.z)) dt = globalClock.getDt() self.world.doPhysics(dt, 20, 1.0/180.0) return task.cont def cleanup(self): self.worldNP.removeNode() self.worldNP = None self.world = None def setup(self): self.worldNP = render.attachNewNode('World') # World self.debugNP = self.worldNP.attachNewNode(BulletDebugNode('Debug')) self.debugNP.show() self.debugNP.node().showWireframe(True) self.debugNP.node().showConstraints(True) self.debugNP.node().showBoundingBoxes(False) self.debugNP.node().showNormals(True) self.world = BulletWorld() self.world.setGravity(Vec3(0, 0, -9.81)) self.world.setDebugNode(self.debugNP.node()) # Box 0 shape = BulletBoxShape(Vec3(1, 1, 1)) body0 = BulletRigidBodyNode('Box 0') bodyNP = self.worldNP.attachNewNode(body0) bodyNP.node().addShape(shape) bodyNP.setCollideMask(BitMask32.allOn()) bodyNP.setPos(0, 0, 12.2) visNP = loader.loadModel('models/box.egg') visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.world.attachRigidBody(body0) # Box A shape = BulletBoxShape(Vec3(0.1, 0.1, 5)) self.hLeg = BulletRigidBodyNode('Box A') bodyNP = self.worldNP.attachNewNode(self.hLeg) bodyNP.node().addShape(shape) bodyNP.node().setMass(1.0) bodyNP.node().setDeactivationEnabled(False) bodyNP.setCollideMask(BitMask32.allOn()) bodyNP.setPos(0, 0, 5.1) visNP = loader.loadModel('models/box.egg') visNP.clearModelNodes() visNP.setScale(Vec3(0.2, 0.2, 10)) visNP.reparentTo(bodyNP) self.world.attachRigidBody(self.hLeg) # Box B shape = BulletBoxShape(Vec3(0.1, 0.1, 5)) self.lLeg = BulletRigidBodyNode('Box B') bodyNP = self.worldNP.attachNewNode(self.lLeg) bodyNP.node().addShape(shape) bodyNP.node().setMass(1.0) bodyNP.node().setDeactivationEnabled(False) force = bodyNP.node().getTotalForce() bodyNP.setCollideMask(BitMask32.allOn()) bodyNP.setPos(0, 0, -5.1) visNP = loader.loadModel('models/box.egg') visNP.clearModelNodes() visNP.setScale(Vec3(0.2, 0.2, 10)) visNP.reparentTo(bodyNP) self.world.attachRigidBody(self.lLeg) # Box C shape = BulletBoxShape(Vec3(0.5, 1, 0.1)) self.foot = BulletRigidBodyNode('Box C') bodyNP = self.worldNP.attachNewNode(self.foot) bodyNP.node().addShape(shape) bodyNP.node().setMass(1.0) bodyNP.node().setDeactivationEnabled(False) bodyNP.setCollideMask(BitMask32.allOn()) bodyNP.setPos(0, 0.5, -5.2) visNP = loader.loadModel('models/box.egg') visNP.clearModelNodes() visNP.setScale(Vec3(1, 2, 0.2)) visNP.reparentTo(bodyNP) self.world.attachRigidBody(self.foot) # Text data self.kneeJointText = OnscreenText(text = 'kneeJoint', pos = (-0.4, 0.6), scale = 0.05, fg = (1.0,1.0,1.0,1.0)) self.ankleJointText = OnscreenText(text = 'ankleJoint', pos = (-0.4, 0.4), scale = 0.05, fg = (1.0,1.0,1.0,1.0)) self.hLegText = OnscreenText(text = 'highLeg', pos = (-1, 0.8), scale = 0.05, fg = (1.0,1.0,1.0,1.0)) self.lLegText = OnscreenText(text = 'lowLeg', pos = (-1, 0.6), scale = 0.05, fg = (1.0,1.0,1.0,1.0)) self.footText = OnscreenText(text = 'foot', pos = (-1, 0.4), scale = 0.05, fg = (1.0,1.0,1.0,1.0)) # attachment to hip # Hinge01 pivotA = Point3(0, 0, -2.0) pivotB = Point3(0, 0, 5.1) axisA = Vec3(1, 0, 0) axisB = Vec3(1, 0, 0) hinge = BulletHingeConstraint(body0, self.hLeg, pivotA, pivotB, axisA, axisB, True) hinge.setDebugDrawSize(2.0) hinge.setLimit(-90, 180, softness=0.1, bias=0.3, relaxation=0.1) self.world.attachConstraint(hinge) # Hinge1 pivotA = Point3(0, 0, -5.3) pivotB = Point3(0, 0, 5.3) axisA = Vec3(1, 0, 0) axisB = Vec3(1, 0, 0) self.kneeJoint = BulletHingeConstraint(self.hLeg, self.lLeg, pivotA, pivotB, axisA, axisB, True) #self.kneeJoint.enableAngularMotor(True,1,1) self.kneeJoint.setDebugDrawSize(2.0) self.kneeJoint.setLimit(-10, 180, softness=0.1, bias=0.3, relaxation=0.1) self.world.attachConstraint(self.kneeJoint) # Hinge2 pivotA = Point3(0, 0.2, -5.2) pivotB = Point3(0, 0.2, 0.1) axisA = Vec3(1, 0, 0) axisB = Vec3(1, 0, 0) self.ankleJoint = BulletHingeConstraint(self.lLeg, self.foot, pivotA, pivotB, axisA, axisB, True) self.ankleJoint.setDebugDrawSize(2.0) self.ankleJoint.setLimit(-60, 80, softness=0.1, bias=0.3, relaxation=0.1) self.world.attachConstraint(self.ankleJoint)
class Simulation(ShowBase): scale = 1 height = 500 lateralError = 200 dt = 0.1 steps = 0 #Test Controllers fuelPID = PID(10, 0.5, 10, 0, 100) heightPID = PID(0.08, 0, 0.3, 0.1, 1) pitchPID = PID(10, 0, 1000, -10, 10) rollPID = PID(10, 0, 1000, -10, 10) XPID = PID(0.2, 0, 0.8, -10, 10) YPID = PID(0.2, 0, 0.8, -10, 10) vulcain = NeuralNetwork() tau = 0.5 Valves=[] CONTROL = False EMPTY = False LANDED = False DONE = False gimbalX = 0 gimbalY = 0 targetAlt = 150 R = RE(200 * 9.806, 250 * 9.806, 7607000 / 9 * scale, 0.4) throttle = 0.0 fuelMass_full = 417000 * scale fuelMass_init = 0.10 radius = 1.8542 * scale length = 47 * scale Cd = 1.5 def __init__(self, VISUALIZE=False): self.VISUALIZE = VISUALIZE if VISUALIZE is True: ShowBase.__init__(self) self.setBackgroundColor(0.2, 0.2, 0.2, 1) self.setFrameRateMeter(True) self.render.setShaderAuto() self.cam.setPos(-120 * self.scale, -120 * self.scale, 120 * self.scale) self.cam.lookAt(0, 0, 10 * self.scale) alight = AmbientLight('ambientLight') alight.setColor(Vec4(0.5, 0.5, 0.5, 1)) alightNP = self.render.attachNewNode(alight) dlight = DirectionalLight('directionalLight') dlight.setDirection(Vec3(1, -1, -1)) dlight.setColor(Vec4(0.7, 0.7, 0.7, 1)) dlightNP = self.render.attachNewNode(dlight) self.render.clearLight() self.render.setLight(alightNP) self.render.setLight(dlightNP) self.accept('escape', self.doExit) self.accept('r', self.doReset) self.accept('f1', self.toggleWireframe) self.accept('f2', self.toggleTexture) self.accept('f3', self.toggleDebug) self.accept('f5', self.doScreenshot) inputState.watchWithModifiers('forward', 'w') inputState.watchWithModifiers('left', 'a') inputState.watchWithModifiers('reverse', 's') inputState.watchWithModifiers('right', 'd') inputState.watchWithModifiers('turnLeft', 'q') inputState.watchWithModifiers('turnRight', 'e') self.ostData = OnscreenText(text='ready', pos=(-1.3, 0.9), scale=0.07, fg=Vec4(1, 1, 1, 1), align=TextNode.ALeft) self.fuelMass = self.fuelMass_full * self.fuelMass_init self.vulcain.load_existing_model(path="LandingRockets/",model_name="140k_samples_1024neurons_3layers_l2-0.000001") # Physics self.setup() # _____HANDLER_____ def doExit(self): self.cleanup() sys.exit(1) def doReset(self): self.cleanup() self.setup() def toggleWireframe(self): ...#self.toggleWireframe() def toggleTexture(self): ...#self.toggleTexture() def toggleDebug(self): if self.debugNP.isHidden(): self.debugNP.show() else: self.debugNP.hide() def doScreenshot(self): self.screenshot('Bullet') # ____TASK___ def processInput(self): throttleChange = 0.0 if inputState.isSet('forward'): self.gimbalY = 10 if inputState.isSet('reverse'): self.gimbalY = -10 if inputState.isSet('left'): self.gimbalX = 10 if inputState.isSet('right'): self.gimbalX = -10 if inputState.isSet('turnLeft'): throttleChange = -1.0 if inputState.isSet('turnRight'): throttleChange = 1.0 self.throttle += throttleChange / 100.0 self.throttle = min(max(self.throttle, 0), 1) def processContacts(self): result = self.world.contactTestPair(self.rocketNP.node(), self.groundNP.node()) #print(result.getNumContacts()) if result.getNumContacts() != 0: self.LANDED = True #self.DONE = True def update(self,task): #self.control(0.1,0.1,0.1) #self.processInput() #self.processContacts() # self.terrain.update() return task.cont def cleanup(self): self.world.removeRigidBody(self.groundNP.node()) self.world.removeRigidBody(self.rocketNP.node()) self.world = None self.debugNP = None self.groundNP = None self.rocketNP = None self.worldNP.removeNode() self.LANDED = False self.EMPTY = False self.DONE = False self.steps = 0 self.fuelMass = self.fuelMass_full*self.fuelMass_init def setup(self): self.targetAlt = r.randrange(100,300) self.Valves = np.array([0.15,0.2,0.15]) self.EngObs = self.vulcain.predict_data_point(np.array(self.Valves).reshape(1,-1)) if self.VISUALIZE is True: self.worldNP = self.render.attachNewNode('World') else: self.root = NodePath(PandaNode("world root")) self.worldNP = self.root.attachNewNode('World') self.world = BulletWorld() self.world.setGravity(Vec3(0, 0, -9.80665)) # World self.debugNP = self.worldNP.attachNewNode(BulletDebugNode('Debug')) self.debugNP.node().showWireframe(True) self.debugNP.node().showConstraints(True) self.debugNP.node().showBoundingBoxes(False) self.debugNP.node().showNormals(True) self.debugNP.show() self.world.setDebugNode(self.debugNP.node()) # self.debugNP.showTightBounds() # self.debugNP.showBounds() # Ground (static) shape = BulletPlaneShape(Vec3(0, 0, 1), 1) self.groundNP = self.worldNP.attachNewNode(BulletRigidBodyNode('Ground')) self.groundNP.node().addShape(shape) self.groundNP.setPos(0, 0, 0) self.groundNP.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(self.groundNP.node()) # Rocket shape = BulletCylinderShape(self.radius, self.length, ZUp) self.rocketNP = self.worldNP.attachNewNode(BulletRigidBodyNode('Cylinder')) self.rocketNP.node().setMass(27200 * self.scale) self.rocketNP.node().addShape(shape) #self.rocketNP.setPos(20,20,250) self.rocketNP.setPos(20, 20, r.randrange(100, 300)+200) #self.rocketNP.setPos(r.randrange(-self.lateralError, self.lateralError, 1), r.randrange(-self.lateralError, self.lateralError, 1), self.height) # self.rocketNP.setPos(0, 0, self.length*10) self.rocketNP.setCollideMask(BitMask32.allOn()) # self.rocketNP.node().setCollisionResponse(0) self.rocketNP.node().notifyCollisions(True) self.world.attachRigidBody(self.rocketNP.node()) for i in range(4): leg = BulletCylinderShape(0.1 * self.radius, 0.5 * self.length, XUp) self.rocketNP.node().addShape(leg, TransformState.makePosHpr( Vec3(6 * self.radius * math.cos(i * math.pi / 2), 6 * self.radius * math.sin(i * math.pi / 2), -0.6 * self.length), Vec3(i * 90, 0, 30))) shape = BulletConeShape(0.75 * self.radius, 0.5 * self.radius, ZUp) self.rocketNP.node().addShape(shape, TransformState.makePosHpr(Vec3(0, 0, -1 / 2 * self.length), Vec3(0, 0, 0))) # Fuel self.fuelRadius = 0.9 * self.radius shape = BulletCylinderShape(self.fuelRadius, 0.01 * self.length, ZUp) self.fuelNP = self.worldNP.attachNewNode(BulletRigidBodyNode('Cone')) self.fuelNP.node().setMass(self.fuelMass_full * self.fuelMass_init) self.fuelNP.node().addShape(shape) self.fuelNP.setPos(0, 0, self.rocketNP.getPos().getZ() - self.length * 0.5 * (1 - self.fuelMass_init)) self.fuelNP.setCollideMask(BitMask32.allOn()) self.fuelNP.node().setCollisionResponse(0) self.world.attachRigidBody(self.fuelNP.node()) frameA = TransformState.makePosHpr(Point3(0, 0, 0), Vec3(0, 0, 90)) frameB = TransformState.makePosHpr(Point3(0, 0, 0), Vec3(0, 0, 90)) self.fuelSlider = BulletSliderConstraint(self.rocketNP.node(), self.fuelNP.node(), frameA, frameB, 1) self.fuelSlider.setTargetLinearMotorVelocity(0) self.fuelSlider.setDebugDrawSize(2.0) self.fuelSlider.set_lower_linear_limit(0) self.fuelSlider.set_upper_linear_limit(0) self.world.attachConstraint(self.fuelSlider) self.npThrustForce = LineNodePath(self.rocketNP, 'Thrust', thickness=4, colorVec=Vec4(1, 0.5, 0, 1)) self.npDragForce = LineNodePath(self.rocketNP, 'Drag', thickness=4, colorVec=Vec4(1, 0, 0, 1)) self.npLiftForce = LineNodePath(self.rocketNP, 'Lift', thickness=4, colorVec=Vec4(0, 0, 1, 1)) self.npFuelState = LineNodePath(self.fuelNP, 'Fuel', thickness=20, colorVec=Vec4(0, 1, 0, 1)) self.rocketCSLon = self.radius ** 2 * math.pi self.rocketCSLat = self.length * 2 * self.radius if self.VISUALIZE is True: self.terrain = loader.loadModel("LZGrid2.egg") self.terrain.setScale(10) self.terrain.reparentTo(self.render) self.terrain.setColor(Vec4(0.1, 0.2, 0.1, 1)) self.toggleTexture() #self.fuelNP.setPos(0, 0, self.rocketNP.getPos().getZ() - self.length * 0.4 * (1 - self.fuelMass_init)) for i in range(5): self.world.doPhysics(self.dt, 5, 1.0 / 180.0) self.fuelSlider.set_lower_linear_limit(-self.length * 0.5 * (1 - self.fuelMass_init)) self.fuelSlider.set_upper_linear_limit(self.length * 0.5 * (1 - self.fuelMass_init)) for i in range(100): self.world.doPhysics(self.dt, 5, 1.0 / 180.0) self.rocketNP.node().applyForce(Vec3(0,0,300000), Vec3(0, 0, 0)) def updateRocket(self, mdot, dt): # Fuel Update self.fuelMass = self.fuelNP.node().getMass() - dt * mdot if self.fuelMass <= 0: self.EMPTY is True fuel_percent = self.fuelMass / self.fuelMass_full self.fuelNP.node().setMass(self.fuelMass) fuelHeight = self.length * fuel_percent I1 = 1 / 2 * self.fuelMass * self.fuelRadius ** 2 I2 = 1 / 4 * self.fuelMass * self.fuelRadius ** 2 + 1 / 12 * self.fuelMass * fuelHeight * fuelHeight self.fuelNP.node().setInertia(Vec3(I2, I2, I1)) # Shift fuel along slider constraint fuelTargetPos = 0.5 * (self.length - fuelHeight) fuelPos = self.fuelSlider.getLinearPos() self.fuelSlider.set_upper_linear_limit(fuelTargetPos) self.fuelSlider.set_lower_linear_limit(-fuelTargetPos) self.npFuelState.reset() self.npFuelState.drawArrow2d(Vec3(0, 0, -0.5 * fuelHeight), Vec3(0, 0, 0.5 * fuelHeight), 45, 2) self.npFuelState.create() def observe(self): pos = self.rocketNP.getPos() vel = self.rocketNP.node().getLinearVelocity() quat = self.rocketNP.getTransform().getQuat() Roll, Pitch, Yaw = quat.getHpr() rotVel = self.rocketNP.node().getAngularVelocity() offset = self.targetAlt-pos.getZ() return pos, vel, Roll, Pitch, Yaw, rotVel, self.fuelMass / self.fuelMass_full, self.EMPTY, self.DONE, self.LANDED, offset, self.EngObs[0], self.Valves def control(self,ValveCommands): self.gimbalX = 0 self.gimbalY = 0 self.Valves = ValveCommands-(ValveCommands-self.Valves)*np.exp(-self.dt/self.tau) self.EngObs = self.vulcain.predict_data_point(np.array(self.Valves).reshape(1,-1 )) #Brennkammerdruck, Gaskammertemp, H2Massenstrom, LOX MAssentrom, Schub #Bar,K,Kg/s,Kg/s,kN #self.dt = globalClock.getDt() pos = self.rocketNP.getPos() vel = self.rocketNP.node().getLinearVelocity() quat = self.rocketNP.getTransform().getQuat() Roll, Pitch, Yaw = quat.getHpr() rotVel = self.rocketNP.node().getAngularVelocity() # CHECK STATE if self.fuelMass <= 0: self.EMPTY = True #if pos.getZ() <= 36: # self.LANDED = True self.LANDED = False self.processContacts() P, T, rho = air_dens(pos[2]) rocketZWorld = quat.xform(Vec3(0, 0, 1)) AoA = math.acos(min(max(dot(norm(vel), norm(-rocketZWorld)), -1), 1)) dynPress = 0.5 * dot(vel, vel) * rho dragArea = self.rocketCSLon + (self.rocketCSLat - self.rocketCSLon) * math.sin(AoA) drag = norm(-vel) * dynPress * self.Cd * dragArea time = globalClock.getFrameTime() liftVec = norm(vel.project(rocketZWorld) - vel) if AoA > 0.5 * math.pi: liftVec = -liftVec lift = liftVec * (math.sin(AoA * 2) * self.rocketCSLat * dynPress) if self.CONTROL: self.throttle = self.heightPID.control(pos.getZ(), vel.getZ(), 33) pitchTgt = self.XPID.control(pos.getX(), vel.getX(), 0) self.gimbalX = -self.pitchPID.control(Yaw, rotVel.getY(), pitchTgt) rollTgt = self.YPID.control(pos.getY(), vel.getY(), 0) self.gimbalY = -self.rollPID.control(Pitch, rotVel.getX(), -rollTgt) self.thrust = self.EngObs[0][4]*1000 #print(self.EngObs) quat = self.rocketNP.getTransform().getQuat() quatGimbal = TransformState.makeHpr(Vec3(0, self.gimbalY, self.gimbalX)).getQuat() thrust = quatGimbal.xform(Vec3(0, 0, self.thrust)) thrustWorld = quat.xform(thrust) #print(thrustWorld) self.npDragForce.reset() self.npDragForce.drawArrow2d(Vec3(0, 0, 0), quat.conjugate().xform(drag) / 1000, 45, 2) self.npDragForce.create() self.npLiftForce.reset() self.npLiftForce.drawArrow2d(Vec3(0, 0, 0), quat.conjugate().xform(lift) / 1000, 45, 2) self.npLiftForce.create() self.npThrustForce.reset() if self.EMPTY is False & self.LANDED is False: self.npThrustForce.drawArrow2d(Vec3(0, 0, -0.5 * self.length), Vec3(0, 0, -0.5 * self.length) - thrust / 30000, 45, 2) self.npThrustForce.create() self.rocketNP.node().applyForce(drag, Vec3(0, 0, 0)) self.rocketNP.node().applyForce(lift, Vec3(0, 0, 0)) #print(self.EMPTY,self.LANDED) if self.EMPTY is False & self.LANDED is False: self.rocketNP.node().applyForce(thrustWorld, quat.xform(Vec3(0, 0, -1 / 2 * self.length))) self.updateRocket(self.EngObs[0][2]+self.EngObs[0][3], self.dt) self.rocketNP.node().setActive(True) self.fuelNP.node().setActive(True) self.processInput() self.world.doPhysics(self.dt) self.steps+=1 if self.steps > 1000: self.DONE = True telemetry = [] telemetry.append('Thrust: {}'.format(int(self.EngObs[0][4]))) telemetry.append('Fuel: {}%'.format(int(self.fuelMass / self.fuelMass_full * 100.0))) telemetry.append('Gimbal: {}'.format(int(self.gimbalX)) + ',{}'.format(int(self.gimbalY))) telemetry.append('AoA: {}'.format(int(AoA / math.pi * 180.0))) telemetry.append('\nPos: {},{}'.format(int(pos.getX()), int(pos.getY()))) telemetry.append('Height: {}'.format(int(pos.getZ()))) telemetry.append('RPY: {},{},{}'.format(int(Roll), int(Pitch), int(Yaw))) telemetry.append('Speed: {}'.format(int(np.linalg.norm(vel)))) telemetry.append('Vel: {},{},{}'.format(int(vel.getX()), int(vel.getY()), int(vel.getZ()))) telemetry.append('Rot: {},{},{}'.format(int(rotVel.getX()), int(rotVel.getY()), int(rotVel.getZ()))) telemetry.append('LANDED: {}'.format(self.LANDED)) telemetry.append('Time: {}'.format(self.steps*self.dt)) telemetry.append('TARGET: {}'.format(self.targetAlt)) #print(pos) if self.VISUALIZE is True: self.ostData.setText('\n'.join(telemetry)) self.cam.setPos(pos[0] - 120 * self.scale, pos[1] - 120 * self.scale, pos[2] + 80 * self.scale) self.cam.lookAt(pos[0], pos[1], pos[2]) self.taskMgr.step() """
class Game(DirectObject): def __init__(self): base.setBackgroundColor(0.1, 0.1, 0.8, 1) base.setFrameRateMeter(True) base.cam.setPos(0, -20, 5) base.cam.lookAt(0, 0, 0) # Light alight = AmbientLight('ambientLight') alight.setColor(Vec4(0.5, 0.5, 0.5, 1)) alightNP = render.attachNewNode(alight) dlight = DirectionalLight('directionalLight') dlight.setDirection(Vec3(1, 1, -1)) dlight.setColor(Vec4(0.7, 0.7, 0.7, 1)) dlightNP = render.attachNewNode(dlight) render.clearLight() render.setLight(alightNP) render.setLight(dlightNP) # Input self.accept('escape', self.doExit) self.accept('r', self.doReset) self.accept('f1', self.toggleWireframe) self.accept('f2', self.toggleTexture) self.accept('f3', self.toggleDebug) self.accept('f5', self.doScreenshot) self.accept('enter', self.doShoot) # Task taskMgr.add(self.update, 'updateWorld') # Physics self.setup() # _____HANDLER_____ def doExit(self): self.cleanup() sys.exit(1) def doReset(self): self.cleanup() self.setup() def toggleWireframe(self): base.toggleWireframe() def toggleTexture(self): base.toggleTexture() def toggleDebug(self): if self.debugNP.isHidden(): self.debugNP.show() else: self.debugNP.hide() def doScreenshot(self): base.screenshot('Bullet') def doShoot(self): # Get from/to points from mouse click pMouse = base.mouseWatcherNode.getMouse() pFrom = Point3() pTo = Point3() base.camLens.extrude(pMouse, pFrom, pTo) pFrom = render.getRelativePoint(base.cam, pFrom) pTo = render.getRelativePoint(base.cam, pTo) # Calculate initial velocity v = pTo - pFrom v.normalize() v *= 100.0 # Create bullet shape = BulletSphereShape(0.3) body = BulletRigidBodyNode('Bullet') bodyNP = self.worldNP.attachNewNode(body) bodyNP.node().addShape(shape) bodyNP.node().setMass(1.0) bodyNP.node().setLinearVelocity(v) bodyNP.node().setCcdMotionThreshold(1e-7); bodyNP.node().setCcdSweptSphereRadius(0.50); bodyNP.setCollideMask(BitMask32.allOn()) bodyNP.setPos(pFrom) visNP = loader.loadModel('models/ball.egg') visNP.setScale(0.8) visNP.reparentTo(bodyNP) self.world.attachRigidBody(bodyNP.node()) # Remove the bullet again after 2 seconds taskMgr.doMethodLater(2, self.doRemove, 'doRemove', extraArgs=[bodyNP], appendTask=True) def doRemove(self, bodyNP, task): self.world.removeRigidBody(bodyNP.node()) bodyNP.removeNode() return task.done # ____TASK___ def update(self, task): dt = globalClock.getDt() self.world.doPhysics(dt, 20, 1.0/180.0) return task.cont def cleanup(self): self.worldNP.removeNode() self.worldNP = None self.world = None def setup(self): self.worldNP = render.attachNewNode('World') # World self.debugNP = self.worldNP.attachNewNode(BulletDebugNode('Debug')) self.debugNP.show() self.debugNP.node().showWireframe(True) self.debugNP.node().showConstraints(True) self.debugNP.node().showBoundingBoxes(False) self.debugNP.node().showNormals(False) self.world = BulletWorld() self.world.setGravity(Vec3(0, 0, -9.81)) self.world.setDebugNode(self.debugNP.node()) # Box A shape = BulletBoxShape(Vec3(0.5, 0.5, 0.5)) bodyA = BulletRigidBodyNode('Box A') bodyNP = self.worldNP.attachNewNode(bodyA) bodyNP.node().addShape(shape) bodyNP.setCollideMask(BitMask32.allOn()) bodyNP.setPos(-2, 0, 1) visNP = loader.loadModel('models/box.egg') visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.world.attachRigidBody(bodyA) # Box B shape = BulletBoxShape(Vec3(0.5, 0.5, 0.5)) bodyB = BulletRigidBodyNode('Box B') bodyNP = self.worldNP.attachNewNode(bodyB) bodyNP.node().addShape(shape) bodyNP.node().setMass(1.0) bodyNP.node().setDeactivationEnabled(False) bodyNP.setCollideMask(BitMask32.allOn()) bodyNP.setPos(2, 0, 1) visNP = loader.loadModel('models/box.egg') visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.world.attachRigidBody(bodyB) # Hinge pivotA = Point3(2, 0, 0) pivotB = Point3(-4, 0, 0) axisA = Vec3(0, 0, 1) axisB = Vec3(0, 0, 1) hinge = BulletHingeConstraint(bodyA, bodyB, pivotA, pivotB, axisA, axisB, True) hinge.setDebugDrawSize(2.0) hinge.setLimit(-90, 120, softness=0.9, bias=0.3, relaxation=1.0) self.world.attachConstraint(hinge)
class Game(DirectObject): def __init__(self): base.setBackgroundColor(0.1, 0.1, 0.8, 1) base.setFrameRateMeter(True) base.cam.setPos(0, -20, 5) base.cam.lookAt(0, 0, 0) # Light alight = AmbientLight('ambientLight') alight.setColor(Vec4(0.5, 0.5, 0.5, 1)) alightNP = render.attachNewNode(alight) dlight = DirectionalLight('directionalLight') dlight.setDirection(Vec3(1, 1, -1)) dlight.setColor(Vec4(0.7, 0.7, 0.7, 1)) dlightNP = render.attachNewNode(dlight) render.clearLight() render.setLight(alightNP) render.setLight(dlightNP) # Input self.accept('escape', self.doExit) self.accept('r', self.doReset) self.accept('f1', self.toggleWireframe) self.accept('f2', self.toggleTexture) self.accept('f3', self.toggleDebug) self.accept('f5', self.doScreenshot) self.accept('enter', self.doShoot) # Task taskMgr.add(self.update, 'updateWorld') # Physics self.setup() # _____HANDLER_____ def doExit(self): self.cleanup() sys.exit(1) def doReset(self): self.cleanup() self.setup() def toggleWireframe(self): base.toggleWireframe() def toggleTexture(self): base.toggleTexture() def toggleDebug(self): if self.debugNP.isHidden(): self.debugNP.show() else: self.debugNP.hide() def doScreenshot(self): base.screenshot('Bullet') def doShoot(self): # Get from/to points from mouse click pMouse = base.mouseWatcherNode.getMouse() pFrom = Point3() pTo = Point3() base.camLens.extrude(pMouse, pFrom, pTo) pFrom = render.getRelativePoint(base.cam, pFrom) pTo = render.getRelativePoint(base.cam, pTo) # Calculate initial velocity v = pTo - pFrom v.normalize() v *= 100.0 # Create bullet shape = BulletSphereShape(0.3) body = BulletRigidBodyNode('Bullet') bodyNP = self.worldNP.attachNewNode(body) bodyNP.node().addShape(shape) bodyNP.node().setMass(1.0) bodyNP.node().setLinearVelocity(v) bodyNP.node().setCcdMotionThreshold(1e-7) bodyNP.node().setCcdSweptSphereRadius(0.50) bodyNP.setCollideMask(BitMask32.allOn()) bodyNP.setPos(pFrom) visNP = loader.loadModel('models/ball.egg') visNP.setScale(0.8) visNP.reparentTo(bodyNP) self.world.attachRigidBody(bodyNP.node()) # Remove the bullet again after 2 seconds taskMgr.doMethodLater(2, self.doRemove, 'doRemove', extraArgs=[bodyNP], appendTask=True) def doRemove(self, bodyNP, task): self.world.removeRigidBody(bodyNP.node()) bodyNP.removeNode() return task.done # ____TASK___ def update(self, task): dt = globalClock.getDt() self.world.doPhysics(dt, 20, 1.0 / 180.0) return task.cont def cleanup(self): self.worldNP.removeNode() self.worldNP = None self.world = None def setup(self): self.worldNP = render.attachNewNode('World') # World self.debugNP = self.worldNP.attachNewNode(BulletDebugNode('Debug')) self.debugNP.show() self.debugNP.node().showWireframe(True) self.debugNP.node().showConstraints(True) self.debugNP.node().showBoundingBoxes(False) self.debugNP.node().showNormals(False) self.world = BulletWorld() self.world.setGravity(Vec3(0, 0, -9.81)) self.world.setDebugNode(self.debugNP.node()) # Box A shape = BulletBoxShape(Vec3(0.5, 0.5, 0.5)) bodyA = BulletRigidBodyNode('Box A') bodyNP = self.worldNP.attachNewNode(bodyA) bodyNP.node().addShape(shape) bodyNP.setCollideMask(BitMask32.allOn()) bodyNP.setPos(-2, 0, 4) visNP = loader.loadModel('models/box.egg') visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.world.attachRigidBody(bodyA) # Box B shape = BulletBoxShape(Vec3(0.5, 0.5, 0.5)) bodyB = BulletRigidBodyNode('Box B') bodyNP = self.worldNP.attachNewNode(bodyB) bodyNP.node().addShape(shape) bodyNP.node().setMass(1.0) bodyNP.node().setDeactivationEnabled(False) bodyNP.setCollideMask(BitMask32.allOn()) bodyNP.setPos(0, 0, 0) visNP = loader.loadModel('models/box.egg') visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.world.attachRigidBody(bodyB) # Cone frameA = TransformState.makePosHpr(Point3(0, 0, -2), Vec3(0, 0, 90)) frameB = TransformState.makePosHpr(Point3(-5, 0, 0), Vec3(0, 0, 0)) cone = BulletConeTwistConstraint(bodyA, bodyB, frameA, frameB) cone.setDebugDrawSize(2.0) cone.setLimit(30, 45, 170, softness=1.0, bias=0.3, relaxation=8.0) self.world.attachConstraint(cone)
class RonnieRacer(DirectObject): gameState = 'INIT' gameLevel = 1 distanceTravelled = 0 speed = 0 score = 0 triesLeft = 3 count = 0 rot = 0 time = 0 pause = False def __init__(self): self.imageObject = OnscreenImage(image = 'media/images/splashscreen.png', pos=(0,0,0), scale=(1.4,1,1)) self.loseScreen = OnscreenImage(image = 'media/images/gameover.png', pos=(0,0,0), scale=(1,1,0.8)) self.loseScreen.hide() self.retryScreen = OnscreenImage(image = 'media/images/retry.png', pos=(0,0,0), scale=(1,1,0.8)) self.retryScreen.hide() self.congratScreen = OnscreenImage(image = 'media/images/congratulations.png', pos=(0,0,0), scale = (1,1,0.8)) self.congratScreen.hide() self.winScreen = OnscreenImage(image = 'media/images/victory.png', pos=(0,0,0), scale = (1,1,0.8)) self.winScreen.hide() self.pauseScreen = OnscreenImage(image = 'media/images/pause.png', pos=(0,0,0), scale = (1,1,0.8)) self.pauseScreen.hide() self.instructionScreen = OnscreenImage(image = 'media/images/instructions.png', pos=(0,0,0), scale = (1,1,0.8)) self.instructionScreen.hide() preloader = Preloader() base.setBackgroundColor(0, 0, 0, 1) base.setFrameRateMeter(True) # Audio self.loseSound = base.loader.loadSfx("media/audio/sfxboo.wav") self.winSound = base.loader.loadSfx("media/audio/cheer2.aif") self.menuMusic = base.loader.loadSfx("media/audio/Scattershot.mp3") self.gameMusic = base.loader.loadSfx("media/audio/Ghostpocalypse - 7 Master.mp3") self.menuMusic.setLoop(True) self.menuMusic.setLoopCount(0) self.gameMusic.setLoop(True) self.gameMusic.setLoopCount(0) #setup buttons self.retryBtn = DirectButton(text="Retry", scale = 0.1, pos = (0,0,0), command = self.doRetry) self.retryBtn.hide() self.menuBtn = DirectButton(text="Main Menu", scale = 0.1, pos = (0,0,0), command = self.doMenu) self.menuBtn.hide() self.nextBtn = DirectButton(text='Next', scale = 0.1, pos = (0,0,0), command = self.doNext) self.nextBtn.hide() self.backBtn = DirectButton(text='back', scale = 0.1, pos = (-0.7,0,-0.7), command = self.doBack) self.backBtn.hide() #setup font self.font = loader.loadFont('media/SHOWG.TTF') self.font.setPixelsPerUnit(60) #setup text self.text = OnscreenText(text = '', pos = (0, 0), scale = 0.07, font = self.font) self.rpmText = OnscreenText(text = '', pos = (-0.9, -0.9), scale = 0.07, font = self.font) self.speedText = OnscreenText(text = '', pos = (0, -0.9), scale = 0.07, font = self.font) self.distanceText = OnscreenText(text = '', pos = (0.9, -0.9), scale = 0.07, font = self.font) self.triesLeftText = OnscreenText(text = '', pos = (1.0, 0.9), scale = 0.07, font = self.font) self.gameLevelText = OnscreenText(text = '', pos = (-1.0, 0.9), scale = 0.07, font = self.font) self.timeText = OnscreenText(text = '', pos = (0, 0.9), scale = 0.07, font = self.font) self.scoreText = OnscreenText(text = '', pos = (1.0, 0.8), scale = 0.07, font = self.font) self.finalScoreText = OnscreenText(text = '', pos = (0, 0.2), scale = 0.07, font = self.font) # Light alight = AmbientLight('ambientLight') alight.setColor(Vec4(0.5, 0.5, 0.5, 1)) alightNP = render.attachNewNode(alight) dlight = DirectionalLight('directionalLight') dlight.setDirection(Vec3(1, 1, -1)) dlight.setColor(Vec4(0.7, 0.7, 0.7, 1)) dlightNP = render.attachNewNode(dlight) render.clearLight() render.setLight(alightNP) render.setLight(dlightNP) # Input self.accept('escape', self.doExit) self.accept('r', self.doReset) self.accept('f1', self.toggleWireframe) self.accept('f2', self.toggleTexture) self.accept('f3', self.toggleDebug) self.accept('f5', self.doScreenshot) inputState.watchWithModifiers('forward', 'w') inputState.watchWithModifiers('left', 'a') inputState.watchWithModifiers('reverse', 's') inputState.watchWithModifiers('right', 'd') inputState.watchWithModifiers('turnLeft', 'a') inputState.watchWithModifiers('turnRight', 'd') # Task taskMgr.add(self.update, 'updateWorld') # _____HANDLER_____ def doExit(self): sys.exit(1) def doReset(self): self.cleanup() self.terrain.getRoot().removeNode() self.setup() def doBack(self): self.backBtn.hide() self.instructionScreen.hide() self.imageObject.show() self.helpBtn.show() self.startBtn.show() self.exitBtn.show() def toggleWireframe(self): base.toggleWireframe() def toggleTexture(self): base.toggleTexture() def toggleDebug(self): if self.debugNP.isHidden(): self.debugNP.show() else: self.debugNP.hide() def doScreenshot(self): base.screenshot('Bullet') # ____TASK___ def processInput(self, dt): # Process input engineForce = 0.0 brakeForce = 0.0 self.accept('p', self.doPause) if inputState.isSet('forward'): engineForce = 15.0 brakeForce = 0.0 if inputState.isSet('reverse'): engineForce = -25.0 brakeForce = 25.0 if inputState.isSet('turnLeft'): self.steering += dt * self.steeringIncrement self.steering = min(self.steering, self.steeringClamp) if inputState.isSet('turnRight'): self.steering -= dt * self.steeringIncrement self.steering = max(self.steering, -self.steeringClamp) # Apply steering to front wheels self.vehicle.setSteeringValue(self.steering, 0) self.vehicle.setSteeringValue(self.steering, 1) # Apply engine and brake to rear wheels self.vehicle.applyEngineForce(engineForce, 2) self.vehicle.applyEngineForce(engineForce, 3) self.vehicle.setBrake(brakeForce, 2) self.vehicle.setBrake(brakeForce, 3) def processContacts(self, dt): result = self.world.contactTestPair(self.vehicleNP.node(), self.flagNP.node()) if(result.getNumContacts() > 0): self.gameState = 'WIN' self.doContinue() def doContinue(self): if(self.gameState == 'INIT'): self.gameState = 'MENU' self.menuMusic.play() self.text.hide() self.startBtn = DirectButton(text=("Play"), scale = 0.1, pos = (0.5,0,0),command=self.playGame) self.helpBtn = DirectButton(text=("Help"), scale = 0.1, pos = (0.5,0,-0.2),command=self.help) self.exitBtn = DirectButton(text=("Exit"), scale = 0.1, pos = (0.5,0,-0.4), command = self.doExit) return if(self.gameState == 'RETRY'): self.retryScreen.show() self.retryBtn.show() self.loseSound.play() return if(self.gameState == 'LOSE'): self.loseScreen.show() self.menuBtn.show() return if(self.gameState == 'WIN'): if(self.gameLevel < 3): self.congratScreen.show() self.nextBtn.show() elif(self.gameLevel >= 3): self.winScreen.show() self.menuBtn.show() self.finalScoreText.setText('Your Score: '+str(int(self.score))) self.finalScoreText.show() self.winSound.play() def help(self): self.gameState = 'HELP' self.startBtn.hide() self.exitBtn.hide() self.helpBtn.hide() self.imageObject.hide() self.instructionScreen.show() self.backBtn.show() def doNext(self): self.nextBtn.hide() self.finalScoreText.hide() self.congratScreen.hide() self.gameLevel += 1 if(self.gameLevel == 2): self.score += 2000 elif(self.gameLevel == 3): self.score += 3000 self.doReset() self.triesLeft = 3 self.gameState = 'PLAY' def doRetry(self): self.doReset() self.gameState = 'PLAY' self.retryScreen.hide() self.retryBtn.hide() self.triesLeft -= 1 def doMenu(self): self.cleanup() self.terrain.getRoot().removeNode() self.gameState = 'MENU' self.score = 0 self.imageObject.show() self.startBtn.show() self.exitBtn.show() self.helpBtn.show() self.loseScreen.hide() self.menuBtn.hide() self.winScreen.hide() self.finalScoreText.hide() self.speedText.hide() self.distanceText.hide() self.rpmText.hide() self.scoreText.hide() self.gameLevelText.hide() self.timeText.hide() self.triesLeftText.hide() self.gameMusic.stop() self.menuMusic.play() def doPause(self): self.pause = not self.pause if(self.pause): self.pauseScreen.show() else: self.pauseScreen.hide() def playGame(self): self.gameState = 'PLAY' self.triesLeft = 3 self.gameLevel = 1 self.imageObject.hide() self.startBtn.hide() self.exitBtn.hide() self.helpBtn.hide() self.menuMusic.stop() self.gameMusic.play() self.speedText.show() self.distanceText.show() self.rpmText.show() self.scoreText.show() self.gameLevelText.show() self.triesLeftText.show() self.timeText.show() # Physics self.setup() def update(self, task): dt = globalClock.getDt() if(not self.pause): if(self.gameState == 'RETRY'): return task.cont if (self.gameState == 'INIT'): self.accept('space', self.doContinue) self.text.setText('Press Space to Continue') if(self.gameState == 'PLAY'): if (self.steering > 0): self.steering -= dt * 50 if (self.steering < 0): self.steering += dt * 50 playerOldSpeed = self.vehicle.getCurrentSpeedKmHour() self.processInput(dt) self.processContacts(dt) self.world.doPhysics(dt, 10, 0.008) #calculate speed,rpm,distance and display text self.speed = self.vehicle.getCurrentSpeedKmHour() if(self.speed<0): self.speed = -self.speed self.speedText.setText('Speed: ' + str(int(self.speed)) + 'Km/h') self.distanceTravelled += self.speed*(dt/3600) self.distanceText.setText('Distance: '+str(float(int(self.distanceTravelled * 1000))/1000) + 'Km') playerNewSpeed = self.vehicle.getCurrentSpeedKmHour() playerAcceleration = (playerNewSpeed - playerOldSpeed) / (dt/60) #playerPosText = self.vehicleNP.getPos() #self.text.setText('Player position: %s'%playerPosText) self.rpmText.setText('Engine RPM: ' + str(int(((self.vehicle.getCurrentSpeedKmHour() / 60) * 1000) / (2 * 0.4 * 3.14159265))) + ' Rpm') self.triesLeftText.setText('Tries Left: ' + str(self.triesLeft)) self.gameLevelText.setText('Level: '+ str(self.gameLevel)) #update camera #position d = self.vehicleNP.getPos() - base.cam.getPos() if(d.length() > 8): base.cam.setX(base.cam.getX() + d.getX()*dt) base.cam.setY(base.cam.getY() + d.getY()*dt) base.cam.setZ(self.vehicleNP.getZ() + 4) #lookat base.cam.lookAt(self.vehicleNP.getPos()+Vec3(0,0,1)) if(self.gameLevel == 1): if(self.vehicleNP.getZ() < -17): if(self.triesLeft > 0): self.gameState = 'RETRY' else: self.gameState = 'LOSE' self.doContinue() elif(self.gameLevel == 2): if(self.vehicleNP.getZ() < -20): if(self.triesLeft > 0): self.gameState = 'RETRY' else: self.gameState = 'LOSE' self.doContinue() elif(self.gameLevel == 3): if(self.vehicleNP.getZ() < -17): if(self.triesLeft > 0): self.gameState = 'RETRY' else: self.gameState = 'LOSE' self.doContinue() if(self.speed < 5): self.steeringIncrement = 120 elif(self.speed >= 5 and self.speed < 10): self.steeringIncrement = 100 elif(self.speed >= 10 and self.speed < 15): self.steeringIncrement = 80 elif(self.speed >=15 and self.speed < 30): self.steeringIncrement = 60 #spin the flag self.rot += 1 self.flagNP.setHpr(self.rot,0,0) #time self.time += dt self.timeText.setText('Time: ' + str(int(self.time))) if(self.score > 0): self.score -= dt self.scoreText.setText('Score: '+str(int(self.score))) return task.cont def cleanup(self): self.world = None self.worldNP.removeNode() def setup(self): # Steering info self.steering = 0.0 # degree self.steeringClamp = 30.0 # degree self.steeringIncrement = 80.0 # degree per second self.worldNP = render.attachNewNode('World') # World self.debugNP = self.worldNP.attachNewNode(BulletDebugNode('Debug')) #self.debugNP.show() self.world = BulletWorld() self.world.setGravity(Vec3(0, 0, -9.81)) self.world.setDebugNode(self.debugNP.node()) if(self.gameLevel == 1): #set score print('GameLevel') self.score = 1000 self.distanceTravelled = 0 self.time = 0 # Plane img = PNMImage(Filename('media/terrain/SIMP_Assignment_2_Terrain_1.png')) shape = BulletHeightfieldShape(img, 50.0, ZUp) np = self.worldNP.attachNewNode(BulletRigidBodyNode('Ground')) np.node().addShape(shape) np.setPos(0, 0, 0) np.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(np.node()) #skybox skybox = loader.loadModel('media/models/skybox/skybox_01.X') skybox.reparentTo(render) # Chassis shape = BulletBoxShape(Vec3(0.6, 1.4, 0.5)) ts = TransformState.makePos(Point3(0, 0, 1.0)) self.vehicleNP = self.worldNP.attachNewNode(BulletRigidBodyNode('Vehicle')) self.vehicleNP.node().addShape(shape, ts) self.vehicleNP.setPos(-93, -88, -7)#-93, -88, -7) #(-82,65.8,-8) #(55,8.38,-6)#(45, -19, -8)#(-93, -88, -7) self.vehicleNP.setHpr(-90,0,0) self.vehicleNP.node().setMass(5.0) self.vehicleNP.node().setDeactivationEnabled(False) base.cam.setPos(self.vehicleNP.getPos().getX()+2,self.vehicleNP.getPos().getY()+2,self.vehicleNP.getPos().getZ()+2) self.world.attachRigidBody(self.vehicleNP.node()) # Vehicle self.vehicle = BulletVehicle(self.world, self.vehicleNP.node()) self.vehicle.setCoordinateSystem(ZUp) self.world.attachVehicle(self.vehicle) self.hummerNP = loader.loadModel('media/models/vehicle/body.X') self.hummerNP.reparentTo(self.vehicleNP) # Right front wheel np = loader.loadModel('media/models/vehicle/front_right.X') np.reparentTo(self.worldNP) self.addWheel(Point3( 0.8, 0.9, 0.8), True, np) # Left front wheel np = loader.loadModel('media/models/vehicle/front_left.X') np.reparentTo(self.worldNP) self.addWheel(Point3(-0.8, 0.9, 0.8), True, np) # Right rear wheel np = loader.loadModel('media/models/vehicle/back_right.X') np.reparentTo(self.worldNP) self.addWheel(Point3( 0.8, -0.7, 0.8), False, np) # Left rear wheel np = loader.loadModel('media/models/vehicle/back_left.X') np.reparentTo(self.worldNP) self.addWheel(Point3(-0.8, -0.7, 0.8), False, np) #Obstacles self.setupObstacleOne(Vec3(50, -5, -4), 1.8, Vec3(60, 0, 0)) self.setupObstacleFour(Vec3(63.3, 59.2, -10), 1.5, Vec3(0,0,0)) self.setupObstacleFour(Vec3(41, 57, -10), 1.5, Vec3(0,0,0)) self.setupObstacleFour(Vec3(7.5, 53.8, -10), 1.5, Vec3(0,0,0)) self.setupObstacleFour(Vec3(-28, 81.4, -10), 1.5, Vec3(0,0,0)) self.setupObstacleSix(Vec3(-91, 81 , -6), 1, Vec3(60,0,0)) #Goal self.setupGoal(Vec3(-101,90.6,-6.5)) #self.vehicleNP.setPos(Vec3(6,52,-6)) self.setupTerrain() elif(self.gameLevel == 2): self.distanceTravelled = 0 self.time = 0 # Plane img = PNMImage(Filename('media/terrain/SIMP_Assignment_2_Terrain_2.png')) shape = BulletHeightfieldShape(img, 50.0, ZUp) np = self.worldNP.attachNewNode(BulletRigidBodyNode('Ground')) np.node().addShape(shape) np.setPos(0, 0, 0) np.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(np.node()) #skybox skybox = loader.loadModel('media/models/skybox/skybox_01.X') skybox.reparentTo(render) # Chassis shape = BulletBoxShape(Vec3(0.6, 1.4, 0.5)) ts = TransformState.makePos(Point3(0, 0, 1.0)) self.vehicleNP = self.worldNP.attachNewNode(BulletRigidBodyNode('Vehicle')) self.vehicleNP.node().addShape(shape, ts) self.vehicleNP.setPos(-99.6,105,-11.8)#(88, 21, -11)#(34.3,8.4,-11.8)#(-99.6,105,-11.8)#(86.4,41.2,-12) self.vehicleNP.setHpr(-130,0,0) self.vehicleNP.node().setMass(5.0) self.vehicleNP.node().setDeactivationEnabled(False) base.cam.setPos(self.vehicleNP.getPos().getX()+2,self.vehicleNP.getPos().getY()+2,self.vehicleNP.getPos().getZ()+2) self.world.attachRigidBody(self.vehicleNP.node()) # Vehicle self.vehicle = BulletVehicle(self.world, self.vehicleNP.node()) self.vehicle.setCoordinateSystem(ZUp) self.world.attachVehicle(self.vehicle) self.hummerNP = loader.loadModel('media/models/vehicle/body.X') self.hummerNP.reparentTo(self.vehicleNP) # Right front wheel np = loader.loadModel('media/models/vehicle/front_right.X') np.reparentTo(self.worldNP) self.addWheel(Point3( 0.8, 0.9, 0.8), True, np) # Left front wheel np = loader.loadModel('media/models/vehicle/front_left.X') np.reparentTo(self.worldNP) self.addWheel(Point3(-0.8, 0.9, 0.8), True, np) # Right rear wheel np = loader.loadModel('media/models/vehicle/back_right.X') np.reparentTo(self.worldNP) self.addWheel(Point3( 0.8, -0.7, 0.8), False, np) # Left rear wheel np = loader.loadModel('media/models/vehicle/back_left.X') np.reparentTo(self.worldNP) self.addWheel(Point3(-0.8, -0.7, 0.8), False, np) self.setupObstacleFive(Vec3(91, 3, -9),1,Vec3(90,0,0)) self.setupObstacleFive(Vec3(94,-19, -10),0.9,Vec3(90,0,0)) self.setupObstacleFive(Vec3(85,-40, -10),1,Vec3(90,0,0)) self.setupObstacleFour(Vec3(-33.5, 23.4,-14.5),1,Vec3(0,0,0)) self.setupObstacleFour(Vec3(-43.3, 24.2,-14.5),1,Vec3(0,0,0)) self.setupObstacleTwo(Vec3(34.7,20.9,-8.5),1,Vec3(90,0,0)) self.setupObstacleTwo(Vec3(26.8,20.3,-8.5),1,Vec3(90,0,0)) self.setupObstacleTwo(Vec3(42.1,22.5,-8.5),1,Vec3(90,0,0)) #self.setupObstacleFive(Vec3(91,0.2, -8),2.1,Vec3(90,0,0)) #Goal self.setupGoal(Vec3(94,-89.7,-10)) self.setupTerrain() elif(self.gameLevel == 3): self.distanceTravelled = 0 self.time = 0 # Plane img = PNMImage(Filename('media/terrain/SIMP_Assignment_2_Terrain_3.png')) shape = BulletHeightfieldShape(img, 50.0, ZUp) np = self.worldNP.attachNewNode(BulletRigidBodyNode('Ground')) np.node().addShape(shape) np.setPos(0, 0, 0) np.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(np.node()) #skybox skybox = loader.loadModel('media/models/skybox/skybox_01.X') skybox.reparentTo(render) # Chassis shape = BulletBoxShape(Vec3(0.6, 1.4, 0.5)) ts = TransformState.makePos(Point3(0, 0, 1.0)) self.vehicleNP = self.worldNP.attachNewNode(BulletRigidBodyNode('Vehicle')) self.vehicleNP.node().addShape(shape, ts) self.vehicleNP.setPos(-110, -110, 0) self.vehicleNP.setHpr(-40,0,0) self.vehicleNP.node().setMass(5.0) self.vehicleNP.node().setDeactivationEnabled(False) base.cam.setPos(self.vehicleNP.getPos().getX()+2,self.vehicleNP.getPos().getY()+2,self.vehicleNP.getPos().getZ()+2) self.world.attachRigidBody(self.vehicleNP.node()) # Vehicle self.vehicle = BulletVehicle(self.world, self.vehicleNP.node()) self.vehicle.setCoordinateSystem(ZUp) self.world.attachVehicle(self.vehicle) self.hummerNP = loader.loadModel('media/models/vehicle/body.X') self.hummerNP.reparentTo(self.vehicleNP) # Right front wheel np = loader.loadModel('media/models/vehicle/front_right.X') np.reparentTo(self.worldNP) self.addWheel(Point3( 0.8, 0.9, 0.8), True, np) # Left front wheel np = loader.loadModel('media/models/vehicle/front_left.X') np.reparentTo(self.worldNP) self.addWheel(Point3(-0.8, 0.9, 0.8), True, np) # Right rear wheel np = loader.loadModel('media/models/vehicle/back_right.X') np.reparentTo(self.worldNP) self.addWheel(Point3( 0.8, -0.7, 0.8), False, np) # Left rear wheel np = loader.loadModel('media/models/vehicle/back_left.X') np.reparentTo(self.worldNP) self.addWheel(Point3(-0.8, -0.7, 0.8), False, np) self.setupTerrain() #Goal self.setupGoal(Vec3(114,100,-13)) #Obstacles self.setupObstacleFour(Vec3(-60, -73, -9), 1, Vec3(0, 0, 0)) self.setupObstacleFour(Vec3(-63, -77, -9), 1, Vec3(0, 0, 0)) self.setupObstacleTwo(Vec3(-15, -40, -3), 1, Vec3(0, 0, 0)) self.setupObstacleFour(Vec3(-60, 12, -11), 1, Vec3(0, 0, 0)) self.setupObstacleSix(Vec3(-15, 90, -6), 1.5, Vec3(-30, 0, 0)) self.setupObstacleFour(Vec3(28, 87, -11), 1, Vec3(0, 0, 0)) self.setupObstacleFour(Vec3(32, 90, -11), 1, Vec3(0, 0, 0)) def addWheel(self, pos, front, np): wheel = self.vehicle.createWheel() wheel.setNode(np.node()) wheel.setChassisConnectionPointCs(pos) wheel.setFrontWheel(front) wheel.setWheelDirectionCs(Vec3(0, 0, -1)) wheel.setWheelAxleCs(Vec3(1, 0, 0)) wheel.setWheelRadius(0.4) wheel.setMaxSuspensionTravelCm(40.0) wheel.setSuspensionStiffness(40.0) wheel.setWheelsDampingRelaxation(2.3) wheel.setWheelsDampingCompression(4.4) wheel.setFrictionSlip(100.0); wheel.setRollInfluence(0.1) def setupTerrain(self): if(self.gameLevel == 1): #terrain setting img = PNMImage(Filename('media/terrain/SIMP_Assignment_2_Terrain_1.png')) self.terrain = GeoMipTerrain("myTerrain") self.terrain.setHeightfield(img) self.terrain.getRoot().setSz(50) self.terrain.setBlockSize(4) #self.terrain.setFactor(10) #self.terrain.setMinLevel(0) self.terrain.setNear(50) self.terrain.setFar(1000) self.terrain.setFocalPoint(base.camera) self.terrain.getRoot().reparentTo(render) offset = img.getXSize() / 2.0 - 0.5 self.terrain.getRoot().setPos(-offset, -offset, -50 / 2.0) self.terrain.generate() #load textures tex0 = loader.loadTexture("media/terrain/SIMP_Assignment_2_Terrain_1_d.png") tex0.setMinfilter(Texture.FTLinearMipmapLinear) tex1 = loader.loadTexture("media/terrain/longGrass.png") tex1.setMinfilter(Texture.FTLinearMipmapLinear) tex2 = loader.loadTexture("media/terrain/bigRockFace.png") tex2.setMinfilter(Texture.FTLinearMipmapLinear) tex3 = loader.loadTexture("media/terrain/greenrough.png") tex3.setMinfilter(Texture.FTLinearMipmapLinear) tex4 = loader.loadTexture("media/terrain/grayRock.png") tex4.setMinfilter(Texture.FTLinearMipmapLinear) tex5 = loader.loadTexture("media/terrain/SIMP_Assignment_2_Terrain_1_c.png") tex5.setMinfilter(Texture.FTLinearMipmapLinear) tex6 = loader.loadTexture("media/terrain/SIMP_Assignment_2_Terrain_1_l.png") tex6.setMinfilter(Texture.FTLinearMipmapLinear) #set mutiltextures self.terrain.getRoot().setTexture( TextureStage('tex0'),tex0 ) self.terrain.getRoot().setTexture( TextureStage('tex1'),tex1 ) self.terrain.getRoot().setTexture( TextureStage('tex2'),tex2 ) self.terrain.getRoot().setTexture( TextureStage('tex3'),tex3 ) self.terrain.getRoot().setTexture( TextureStage('tex4'),tex4 ) self.terrain.getRoot().setTexture( TextureStage('tex5'),tex5 ) self.terrain.getRoot().setTexture( TextureStage('tex6'),tex6 ) #load shader self.terrain.getRoot().setShader(loader.loadShader('terraintexture.sha')) elif(self.gameLevel == 2): #terrain setting img = PNMImage(Filename('media/terrain/SIMP_Assignment_2_Terrain_2.png')) self.terrain = GeoMipTerrain("myTerrain") self.terrain.setHeightfield(img) self.terrain.getRoot().setSz(50) self.terrain.setBlockSize(4) #self.terrain.setFactor(10) #self.terrain.setMinLevel(0) self.terrain.setNear(50) self.terrain.setFar(100) self.terrain.setFocalPoint(base.camera) self.terrain.getRoot().reparentTo(render) offset = img.getXSize() / 2.0 - 0.5 self.terrain.getRoot().setPos(-offset, -offset, -50 / 2.0) self.terrain.generate() #load textures tex0 = loader.loadTexture("media/terrain/SIMP_Assignment_2_Terrain_2_d.png") tex0.setMinfilter(Texture.FTLinearMipmapLinear) tex1 = loader.loadTexture("media/terrain/sandripple.png") tex1.setMinfilter(Texture.FTLinearMipmapLinear) tex2 = loader.loadTexture("media/terrain/orangesand.png") tex2.setMinfilter(Texture.FTLinearMipmapLinear) tex3 = loader.loadTexture("media/terrain/grayRock.png") tex3.setMinfilter(Texture.FTLinearMipmapLinear) tex4 = loader.loadTexture("media/terrain/bigRockFace.png") tex4.setMinfilter(Texture.FTLinearMipmapLinear) tex5 = loader.loadTexture("media/terrain/SIMP_Assignment_2_Terrain_2_c.png") tex5.setMinfilter(Texture.FTLinearMipmapLinear) tex6 = loader.loadTexture("media/terrain/SIMP_Assignment_2_Terrain_2_l.png") tex6.setMinfilter(Texture.FTLinearMipmapLinear) #set mutiltextures self.terrain.getRoot().setTexture( TextureStage('tex0'),tex0 ) self.terrain.getRoot().setTexture( TextureStage('tex1'),tex1 ) self.terrain.getRoot().setTexture( TextureStage('tex2'),tex2 ) self.terrain.getRoot().setTexture( TextureStage('tex3'),tex3 ) self.terrain.getRoot().setTexture( TextureStage('tex4'),tex4 ) self.terrain.getRoot().setTexture( TextureStage('tex5'),tex5 ) self.terrain.getRoot().setTexture( TextureStage('tex6'),tex6 ) #load shader self.terrain.getRoot().setShader(loader.loadShader('terraintexture.sha')) elif(self.gameLevel == 3): #terrain setting img = PNMImage(Filename('media/terrain/SIMP_Assignment_2_Terrain_3.png')) self.terrain = GeoMipTerrain("myTerrain") self.terrain.setHeightfield(img) self.terrain.getRoot().setSz(50) self.terrain.setBlockSize(4) #self.terrain.setFactor(10) #self.terrain.setMinLevel(0) self.terrain.setNear(50) self.terrain.setFar(100) self.terrain.setFocalPoint(base.camera) self.terrain.getRoot().reparentTo(render) offset = img.getXSize() / 2.0 - 0.5 self.terrain.getRoot().setPos(-offset, -offset, -50 / 2.0) self.terrain.generate() #load textures tex0 = loader.loadTexture("media/terrain/SIMP_Assignment_2_Terrain_3_d.png") tex0.setMinfilter(Texture.FTLinearMipmapLinear) tex1 = loader.loadTexture("media/terrain/hardDirt.png") tex1.setMinfilter(Texture.FTLinearMipmapLinear) tex2 = loader.loadTexture("media/terrain/littlerocks.png") tex2.setMinfilter(Texture.FTLinearMipmapLinear) tex3 = loader.loadTexture("media/terrain/greenrough.png") tex3.setMinfilter(Texture.FTLinearMipmapLinear) tex4 = loader.loadTexture("media/terrain/bigRockFace.png") tex4.setMinfilter(Texture.FTLinearMipmapLinear) tex5 = loader.loadTexture("media/terrain/SIMP_Assignment_2_Terrain_3_c.png") tex5.setMinfilter(Texture.FTLinearMipmapLinear) tex6 = loader.loadTexture("media/terrain/SIMP_Assignment_2_Terrain_3_l.png") tex6.setMinfilter(Texture.FTLinearMipmapLinear) #set mutiltextures self.terrain.getRoot().setTexture( TextureStage('tex0'),tex0 ) self.terrain.getRoot().setTexture( TextureStage('tex1'),tex1 ) self.terrain.getRoot().setTexture( TextureStage('tex2'),tex2 ) self.terrain.getRoot().setTexture( TextureStage('tex3'),tex3 ) self.terrain.getRoot().setTexture( TextureStage('tex4'),tex4 ) self.terrain.getRoot().setTexture( TextureStage('tex5'),tex5 ) self.terrain.getRoot().setTexture( TextureStage('tex6'),tex6 ) #load shader self.terrain.getRoot().setShader(loader.loadShader('terraintexture.sha')) def setupObstacleOne(self, pos, scale, turn): #box A shape = BulletBoxShape(Vec3(3, 0.1, 0.1) * scale) bodyA = BulletRigidBodyNode('Box A') bodyNP= self.worldNP.attachNewNode(bodyA) bodyNP.node().addShape(shape) bodyNP.setCollideMask(BitMask32.allOn()) bodyNP.setPos(pos) bodyNP.setHpr(turn) visNP = loader.loadModel('media/models/box.egg') visNP.setScale(Vec3(3, 0.1, 0.1)*2 * scale) visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.world.attachRigidBody(bodyA) # Box C shape = BulletBoxShape(Vec3(0.1, 0.1, 0.9)*scale) bodyC = BulletRigidBodyNode('Box C') bodyNP = self.worldNP.attachNewNode(bodyC) bodyNP.node().addShape(shape) bodyNP.node().setMass(1.0) bodyNP.node().setLinearDamping(0.5) bodyNP.node().setDeactivationEnabled(False) bodyNP.setCollideMask(BitMask32.allOn()) bodyNP.setPos(pos) bodyNP.setHpr(turn) visNP = loader.loadModel('media/models/box.egg') visNP.setScale(Vec3(0.1, 0.1, 0.9)*2*scale) visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.world.attachRigidBody(bodyC) pivotA = Point3(0, 0, -0.1 * scale) pivotB = Point3(0, 0, 1 * scale) axisA = Vec3(1, 0, 0) axisB = Vec3(1, 0, 0) hinge = BulletHingeConstraint(bodyA, bodyC, pivotA, pivotB, axisA, axisB, True) hinge.setDebugDrawSize(2.0) hinge.setLimit(-90,90, softness=1.0, bias=0.3, relaxation=1.0) self.world.attachConstraint(hinge) # Box B shape = BulletBoxShape(Vec3(3, 2, 0.1)*scale) bodyB = BulletRigidBodyNode('Box B') bodyNP = self.worldNP.attachNewNode(bodyB) bodyNP.node().addShape(shape) bodyNP.node().setMass(1.0) bodyNP.node().setLinearDamping(0.5) bodyNP.node().setDeactivationEnabled(False) bodyNP.setCollideMask(BitMask32.allOn()) bodyNP.setPos(pos) bodyNP.setHpr(turn); visNP = loader.loadModel('media/models/box.egg') visNP.setScale(Vec3(3, 2, 0.1)*2*scale) visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.world.attachRigidBody(bodyB) # Hinge pivotA = Point3(0, 0, 0) pivotB = Point3(0, 0, -1 * scale) hinge = BulletHingeConstraint(bodyB, bodyC, pivotA, pivotB, axisA, axisB, True) hinge.setLimit(0,360, softness=1.0, bias=0.3, relaxation=1.0) self.world.attachConstraint(hinge) def setupObstacleTwo(self,pos,scale,turn): #box A shape = BulletBoxShape(Vec3(3, 0.1, 0.1)*scale) bodyA = BulletRigidBodyNode('Box A') bodyNP= self.worldNP.attachNewNode(bodyA) bodyNP.node().addShape(shape) bodyNP.setCollideMask(BitMask32.allOn()) bodyNP.setPos(pos) bodyNP.setHpr(turn) visNP = loader.loadModel('media/models/box.egg') visNP.setScale(Vec3(3, 0.1, 0.1)*2*scale) visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.world.attachRigidBody(bodyA) # Box B shape = BulletBoxShape(Vec3(0.1, 1, 1)*scale) bodyB = BulletRigidBodyNode('Box B') bodyNP = self.worldNP.attachNewNode(bodyB) bodyNP.node().addShape(shape) bodyNP.node().setMass(100.0) bodyNP.node().setDeactivationEnabled(False) bodyNP.setCollideMask(BitMask32.allOn()) bodyNP.setPos(pos) bodyNP.setHpr(turn) visNP = loader.loadModel('media/models/box.egg') visNP.setScale(Vec3(0.1, 1, 1)*2*scale) visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.world.attachRigidBody(bodyB) # Hinge pivotA = Point3(2, 0, 0) pivotB = Point3(0, 0, 2) axisA = Vec3(1, 0, 0) axisB = Vec3(1, 0, 0) hinge = BulletHingeConstraint(bodyA, bodyB, pivotA, pivotB, axisA, axisB, True) hinge.setDebugDrawSize(2.0) hinge.setLimit(-90,90, softness=1.0, bias=0.3, relaxation=1.0) self.world.attachConstraint(hinge) # Box C shape = BulletBoxShape(Vec3(0.1, 1, 1)*scale) bodyC = BulletRigidBodyNode('Box C') bodyNP = self.worldNP.attachNewNode(bodyC) bodyNP.node().addShape(shape) bodyNP.node().setMass(100.0) bodyNP.node().setDeactivationEnabled(False) bodyNP.setCollideMask(BitMask32.allOn()) bodyNP.setPos(pos) bodyNP.setHpr(turn) visNP = loader.loadModel('media/models/box.egg') visNP.setScale(Vec3(0.1, 1, 1)*2*scale) visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.world.attachRigidBody(bodyC) pivotA = Point3(-2, 0, 0) pivotB = Point3(0, 0, 2) hinge = BulletHingeConstraint(bodyA, bodyC, pivotA, pivotB, axisA, axisB, True) self.world.attachConstraint(hinge) def setupObstacleThree(self, pos, scale, turn): # Box A shape = BulletBoxShape(Vec3(0.1, 0.1, 0.1)) bodyA = BulletRigidBodyNode('Box A') bodyA.setRestitution(1.0) bodyNP = self.worldNP.attachNewNode(bodyA) bodyNP.node().addShape(shape) bodyNP.setCollideMask(BitMask32.allOn()) bodyNP.setPos(pos) bodyNP.setHpr(turn) visNP = loader.loadModel('media/models/box.egg') visNP.setScale(Vec3(0.1, 0.1, 0.1)*2*scale) visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.world.attachRigidBody(bodyA) #Box B shape = BulletBoxShape(Vec3(0.1,0.1,0.1)) bodyB = BulletRigidBodyNode('Box B') bodyB.setRestitution(1.0) bodyNP = self.worldNP.attachNewNode(bodyB) bodyNP.node().addShape(shape) bodyNP.setCollideMask(BitMask32.allOn()) bodyNP.setPos(pos) bodyNP.setHpr(turn) visNP = loader.loadModel('media/models/box.egg') visNP.setScale(Vec3(0.1,0.1,0.1)*2*scale) visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.world.attachRigidBody(bodyB) # Slider frameA = TransformState.makePosHpr(Point3(0, 0, 0), Vec3(0, 0, 0)) frameB = TransformState.makePosHpr(Point3(0, 0, 0), Vec3(0, 0, 0)) slider = BulletSliderConstraint(bodyA, bodyB, frameA, frameB, True) slider.setDebugDrawSize(2.0) slider.setLowerLinearLimit(0) slider.setUpperLinearLimit(12) slider.setLowerAngularLimit(-90) slider.setUpperAngularLimit(-85) self.world.attachConstraint(slider) # Box C shape = BulletBoxShape(Vec3(1, 3, 0.1)) bodyC = BulletRigidBodyNode('Box C') bodyC.setRestitution(1.0) bodyNP = self.worldNP.attachNewNode(bodyC) bodyNP.node().addShape(shape) bodyNP.node().setMass(0.1) bodyNP.node().setDeactivationEnabled(False) bodyNP.setCollideMask(BitMask32.allOn()) bodyNP.setPos(Vec3(pos.getX() + 3, pos.getY() - 4, pos.getZ())) bodyNP.setHpr(turn) visNP = loader.loadModel('media/models/box.egg') visNP.setScale(Vec3(1, 3, 0.1)*2*scale) visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.world.attachRigidBody(bodyC) bodyNP.node().setLinearVelocity(-100) # Slider frameA = TransformState.makePosHpr(Point3(0, 0, 0), Vec3(0, 0, 0)) frameB = TransformState.makePosHpr(Point3(0, 0, 0), Vec3(0, 0, 0)) slider = BulletSliderConstraint(bodyA, bodyC, frameA, frameB, True) slider.setDebugDrawSize(2.0) slider.setLowerLinearLimit(2) slider.setUpperLinearLimit(6) slider.setLowerAngularLimit(-90) slider.setUpperAngularLimit(-85) self.world.attachConstraint(slider) def setupObstacleFour(self, pos, scale, turn): #Start Here # Box A shape = BulletBoxShape(Vec3(0.01, 0.01, 0.01) * scale) bodyA = BulletRigidBodyNode('Box A') bodyNP = self.worldNP.attachNewNode(bodyA) bodyNP.node().addShape(shape) bodyNP.setCollideMask(BitMask32.allOn()) bodyNP.setPos(pos.getX(), pos.getY(), pos.getZ() + 4) #(0, 0, 4) visNP = loader.loadModel('media/models/box.egg') visNP.setScale(Vec3(0.01, 0.01, 0.01)*2*scale) visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.world.attachRigidBody(bodyA) # Box B shape = BulletSphereShape(0.5*scale) bodyB = BulletRigidBodyNode('Sphere B') bodyNP = self.worldNP.attachNewNode(bodyB) bodyNP.node().addShape(shape) bodyNP.node().setMass(10.0) bodyNP.node().setDeactivationEnabled(False) bodyNP.setCollideMask(BitMask32.allOn()) bodyNP.setPos(pos.getX(), pos.getY(), pos.getZ() + 5) #(0, 0, 0.001) visNP = loader.loadModel('media/models/ball.egg') visNP.clearModelNodes() visNP.setScale(1.25*scale) visNP.reparentTo(bodyNP) bodyNP.node().setLinearVelocity(100) self.world.attachRigidBody(bodyB) # Cone frameA = TransformState.makePosHpr(Point3(0, 0, 0), Vec3(0, 0, 90)) frameB = TransformState.makePosHpr(Point3(2, 0, 0)*scale, Vec3(0, 0, 0)) cone = BulletConeTwistConstraint(bodyA, bodyB, frameA, frameB) cone.setDebugDrawSize(2.0) cone.setLimit(30, 90, 270, softness=1.0, bias=0.3, relaxation=10.0) self.world.attachConstraint(cone) # Box C shape = BulletBoxShape(Vec3(0.1, 0.1, 1)*scale) bodyC = BulletRigidBodyNode('Box C') bodyNP = self.worldNP.attachNewNode(bodyC) bodyNP.node().addShape(shape) bodyNP.node().setDeactivationEnabled(False) bodyNP.setCollideMask(BitMask32.allOn()) bodyNP.setPos(pos.getX(), pos.getY(), pos.getZ() + 3) self.world.attachRigidBody(bodyC) visNP = loader.loadModel('media/models/box.egg') visNP.setScale(Vec3(0.1, 0.1, 1)*2*scale) visNP.clearModelNodes() visNP.reparentTo(bodyNP) def setupObstacleSix(self, pos, scale, turn): #box A shape = BulletBoxShape(Vec3(0.1, 0.1, 0.1)*scale) bodyA = BulletRigidBodyNode('Box A') bodyNP= self.worldNP.attachNewNode(bodyA) bodyNP.node().addShape(shape) bodyNP.setCollideMask(BitMask32.allOff()) bodyNP.setPos(pos.getX()-2,pos.getY(),pos.getZ()+2.5)#-2,0,2.5) bodyNP.setHpr(turn) # Box B shape = BulletBoxShape(Vec3(2, 0.1, 3)*scale) bodyB = BulletRigidBodyNode('Box B') bodyNP = self.worldNP.attachNewNode(bodyB) bodyNP.node().addShape(shape) bodyNP.node().setMass(1.0) bodyNP.node().setLinearDamping(0.5) bodyNP.node().setDeactivationEnabled(False) bodyNP.setCollideMask(BitMask32.allOn()) bodyNP.setPos(pos.getX()-3,pos.getY(), pos.getZ())#, 0, 0) bodyNP.setHpr(turn) visNP = loader.loadModel('media/models/box.egg') visNP.setScale(Vec3(2, 0.1, 3)*2*scale) visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.world.attachRigidBody(bodyB) # Hinge pivotA = Point3(-2, 0, -3) pivotB = Point3(-2, 0, -3) axisA = Vec3(0, 0, 1) axisB = Vec3(0, 0, 1) hinge = BulletHingeConstraint(bodyA, bodyB, pivotA, pivotB, axisA, axisB, True) hinge.setDebugDrawSize(2.0) hinge.setLimit(0,90, softness=1.0, bias=0.3, relaxation=1.0) self.world.attachConstraint(hinge) #box A shape = BulletBoxShape(Vec3(0.1, 0.1, 0.1)*scale) bodyA = BulletRigidBodyNode('Box A') bodyNP= self.worldNP.attachNewNode(bodyA) bodyNP.node().addShape(shape) bodyNP.setCollideMask(BitMask32.allOff()) bodyNP.setPos(pos.getX()+2,pos.getY(),pos.getZ()+2.5)#2,0,2.5) bodyNP.setHpr(turn) # Box B shape = BulletBoxShape(Vec3(2, 0.1, 3)*scale) bodyB = BulletRigidBodyNode('Box B') bodyNP = self.worldNP.attachNewNode(bodyB) bodyNP.node().addShape(shape) bodyNP.node().setMass(1.0) bodyNP.node().setLinearDamping(0.5) bodyNP.node().setDeactivationEnabled(False) bodyNP.setCollideMask(BitMask32.allOn()) bodyNP.setPos(pos.getX()+4, pos.getY(), pos.getZ())# 0, 0) bodyNP.setHpr(turn) visNP = loader.loadModel('media/models/box.egg') visNP.setScale(Vec3(2, 0.1, 3)*2*scale) visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.world.attachRigidBody(bodyB) pivotA = Point3(2, 0, -3) pivotB = Point3(2, 0, -3) hinge = BulletHingeConstraint(bodyA, bodyB, pivotA, pivotB, axisA, axisB, True) hinge.setLimit(-90,0, softness=1.0, bias=0.3, relaxation=1.0) self.world.attachConstraint(hinge) def setupObstacleFive(self, pos, scale, turn): #box A shape = BulletBoxShape(Vec3(3, 0.1, 0.1)*scale) bodyA = BulletRigidBodyNode('Box A') bodyNP= self.worldNP.attachNewNode(bodyA) bodyNP.node().addShape(shape) bodyNP.setCollideMask(BitMask32.allOn()) bodyNP.setPos(pos) bodyNP.setHpr(turn) visNP = loader.loadModel('media/models/box.egg') visNP.setScale(Vec3(3, 0.1, 0.1)*2*scale) visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.world.attachRigidBody(bodyA) # Box B shape = BulletBoxShape(Vec3(3, 2, 0.1)*scale) bodyB = BulletRigidBodyNode('Box B') bodyNP = self.worldNP.attachNewNode(bodyB) bodyNP.node().addShape(shape) bodyNP.node().setMass(1.0) bodyNP.node().setDeactivationEnabled(False) bodyNP.setCollideMask(BitMask32.allOn()) bodyNP.setPos(pos) bodyNP.setHpr(turn) visNP = loader.loadModel('media/models/box.egg') visNP.setScale(Vec3(3, 2, 0.1)*2*scale) visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.world.attachRigidBody(bodyB) # Hinge pivotA = Point3(0, 0, 0) pivotB = Point3(0, 0, 5) axisA = Vec3(1, 0, 0) axisB = Vec3(1, 0, 0) hinge = BulletHingeConstraint(bodyA, bodyB, pivotA, pivotB, axisA, axisB, True) hinge.setDebugDrawSize(2.0) hinge.setLimit(-50,50, softness=0.5, bias=0.3, relaxation=0.6) self.world.attachConstraint(hinge) # Box C shape = BulletBoxShape(Vec3(0.1, 0.1, 0.9)*scale) bodyC = BulletRigidBodyNode('Box C') bodyNP = self.worldNP.attachNewNode(bodyC) bodyNP.node().addShape(shape) bodyNP.node().setMass(1.0) bodyNP.node().setDeactivationEnabled(False) bodyNP.setCollideMask(BitMask32.allOn()) bodyNP.setPos(pos) bodyNP.setHpr(turn) visNP = loader.loadModel('media/models/box.egg') visNP.setScale(Vec3(0.1, 0.1, 0.9)*2*scale) visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.world.attachRigidBody(bodyC) pivotA = Point3(0, 0, -1.1) pivotB = Point3(0, 0, 1) hinge = BulletHingeConstraint(bodyA, bodyC, pivotA, pivotB, axisA, axisB, True) hinge.setLimit(-90,90, softness=1.0, bias=0.3, relaxation=1.0) self.world.attachConstraint(hinge) def setupGoal(self, pos): # Goal shape = BulletBoxShape(Vec3(1, 1, 1)) body = BulletRigidBodyNode('Flag') self.flagNP = self.worldNP.attachNewNode(body) self.flagNP.node().addShape(shape) self.flagNP.setCollideMask(BitMask32.allOn()) self.flagNP.setPos(pos) visNP = loader.loadModel('media/models/Flag.X') visNP.clearModelNodes() visNP.reparentTo(self.flagNP) self.world.attachRigidBody(body)
class Simulation(DirectObject): scale = 10 R = RE throttle = 0.0 def __init__(self): base.setBackgroundColor(0.1, 0.1, 0.8, 1) base.setFrameRateMeter(True) base.cam.setPos(-8 * self.scale, -8 * self.scale, 4 * self.scale) base.cam.lookAt(0, 0, 1 * self.scale) # Light alight = AmbientLight('ambientLight') alight.setColor(Vec4(0.5, 0.5, 0.5, 1)) alightNP = render.attachNewNode(alight) dlight = DirectionalLight('directionalLight') dlight.setDirection(Vec3(1, 1, -1)) dlight.setColor(Vec4(0.7, 0.7, 0.7, 1)) dlightNP = render.attachNewNode(dlight) render.clearLight() render.setLight(alightNP) render.setLight(dlightNP) # Input self.accept('escape', self.doExit) self.accept('r', self.doReset) self.accept('f1', self.toggleWireframe) self.accept('f2', self.toggleTexture) self.accept('f3', self.toggleDebug) self.accept('f5', self.doScreenshot) inputState.watchWithModifiers('forward', 'w') inputState.watchWithModifiers('left', 'a') inputState.watchWithModifiers('reverse', 's') inputState.watchWithModifiers('right', 'd') inputState.watchWithModifiers('turnLeft', 'q') inputState.watchWithModifiers('turnRight', 'e') # Task taskMgr.add(self.update, 'updateWorld') self.ostData = OnscreenText(text='ready', pos=(-1.3, 0.9), scale=0.07, fg=Vec4(1, 1, 1, 1), align=TextNode.ALeft) # Physics self.setup() # _____HANDLER_____ def doExit(self): self.cleanup() sys.exit(1) def doReset(self): self.cleanup() self.setup() def toggleWireframe(self): base.toggleWireframe() def toggleTexture(self): base.toggleTexture() def toggleDebug(self): if self.debugNP.isHidden(): self.debugNP.show() else: self.debugNP.hide() def doScreenshot(self): base.screenshot('Bullet') # ____TASK___ def processInput(self, dt): force = Vec3(0, 0, 0) throttleChange = 0.0 #torque = Vec3(0, 0, 0) if inputState.isSet('forward'): force.setX(1) if inputState.isSet('reverse'): force.setX(-1) if inputState.isSet('left'): force.setY(-1) if inputState.isSet('right'): force.setY(1) if inputState.isSet('turnLeft'): throttleChange = -1.0 if inputState.isSet('turnRight'): throttleChange = 1.0 force *= -20.0 / 180.0 * math.pi self.throttle += throttleChange / 100.0 self.throttle = min(max(self.throttle, 0), 1) thrust = Vec3(0, 0, self.throttle * 50) quatGimbal = self.rocketNozzle.getTransform(self.worldNP).getQuat() self.rocketNozzle.node().applyForce(quatGimbal.xform(thrust), LPoint3f(0, 0, 0)) #torque *= 10.0 #force = render.getRelativeVector(self.rocketNP, force) #torque = render.getRelativeVector(self.rocketNP, torque) self.rocketNozzle.node().setActive(True) self.rocketNP.node().setActive(True) #self.rocketNozzle.node().applyCentralForce(force) #self.rocketNozzle.node().applyTorque(torque) force = rot.from_euler('zyx', force).as_quat() self.cone.setMotorTarget( LQuaternionf(force[0], force[1], force[2], force[3])) def update(self, task): dt = globalClock.getDt() self.processInput(dt) #self.world.doPhysics(dt) self.world.doPhysics(dt, 5, 1.0 / 180.0) yawpitchroll = rot.from_quat( self.rocketNozzle.getTransform(self.rocketNP).getQuat()) yawpitchroll = yawpitchroll.as_euler('zyx', degrees=True) #self.ostData.destroy() telemetry = [] telemetry.append( 'Nozzle Position:\n Yaw: {}\n Pitch: {}\n Roll: {}'.format( int(yawpitchroll[0]), int(yawpitchroll[1]), int(yawpitchroll[2]))) telemetry.append('\nThrottle: {}'.format(self.throttle)) self.ostData.setText('\n'.join(telemetry)) return task.cont def cleanup(self): self.world.removeRigidBody(self.groundNP.node()) self.world.removeRigidBody(self.rocketNP.node()) self.world = None self.debugNP = None self.groundNP = None self.rocketNP = None self.worldNP.removeNode() def setup(self): self.worldNP = render.attachNewNode('World') # World self.debugNP = self.worldNP.attachNewNode(BulletDebugNode('Debug')) self.debugNP.show() self.debugNP.node().showWireframe(True) self.debugNP.node().showConstraints(True) self.debugNP.node().showBoundingBoxes(False) self.debugNP.node().showNormals(True) #self.debugNP.showTightBounds() #self.debugNP.showBounds() self.world = BulletWorld() self.world.setGravity(Vec3(0, 0, -9.81)) self.world.setDebugNode(self.debugNP.node()) # Ground (static) shape = BulletPlaneShape(Vec3(0, 0, 1), 1) self.groundNP = self.worldNP.attachNewNode( BulletRigidBodyNode('Ground')) self.groundNP.node().addShape(shape) self.groundNP.setPos(0, 0, -2) self.groundNP.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(self.groundNP.node()) #Rocket shape = BulletCylinderShape(0.2 * self.scale, 2 * self.scale, ZUp) self.rocketNP = self.worldNP.attachNewNode( BulletRigidBodyNode('Cylinder')) self.rocketNP.node().setMass(3.0) self.rocketNP.node().addShape(shape) self.rocketNP.setPos(0, 0, 2 * self.scale) self.rocketNP.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(self.rocketNP.node()) for i in range(4): leg = BulletCylinderShape(0.02 * self.scale, 1 * self.scale, XUp) self.rocketNP.node().addShape( leg, TransformState.makePosHpr( Vec3(0.6 * self.scale * math.cos(i * math.pi / 2), 0.6 * self.scale * math.sin(i * math.pi / 2), -1.2 * self.scale), Vec3(i * 90, 0, 30))) shape = BulletConeShape(0.15 * self.scale, 0.3 * self.scale, ZUp) self.rocketNozzle = self.worldNP.attachNewNode( BulletRigidBodyNode('Cone')) self.rocketNozzle.node().setMass(1) self.rocketNozzle.node().addShape(shape) self.rocketNozzle.setPos(0, 0, 0.8 * self.scale) self.rocketNozzle.setCollideMask(BitMask32.allOn()) self.rocketNozzle.node().setCollisionResponse(0) self.world.attachRigidBody(self.rocketNozzle.node()) frameA = TransformState.makePosHpr(Point3(0, 0, -1 * self.scale), Vec3(0, 0, 90)) frameB = TransformState.makePosHpr(Point3(0, 0, 0.2 * self.scale), Vec3(0, 0, 90)) self.cone = BulletConeTwistConstraint(self.rocketNP.node(), self.rocketNozzle.node(), frameA, frameB) self.cone.enableMotor(1) #self.cone.setMaxMotorImpulse(2) #self.cone.setDamping(1000) self.cone.setDebugDrawSize(2.0) self.cone.setLimit(20, 20, 0, softness=1.0, bias=1.0, relaxation=10.0) self.world.attachConstraint(self.cone) self.npThrustForce = LineNodePath(self.render, 'Thrust', thickness=4, colorVec=VBase4(1, 0.5, 0, 1))
class App(ShowBase): def __init__(self, args): ShowBase.__init__(self) width = args['--width'] height = args['--height'] globalClock.setMode(ClockObject.MNonRealTime) globalClock.setDt(0.02) # 20ms per frame self.setBackgroundColor(0.9, 0.9, 0.9) self.createLighting() self.setupCamera(width, height, Vec3(0, -10, 10), Vec3(0, 0, 0)) self.render.setShaderAuto() self.world = BulletWorld() self.world.setGravity(Vec3(0, 0, -9.81)) # self.setupDebug() self.createPlane(Vec3(0, 0, -1), Vec3(10, 10, 1)) box_a = self.createBox(1.5, Vec3(2, 0, 1), Vec3(2, 1, 1), VBase4(0.5, 1, 0.5, 1.0)) box_b = self.createBox(1.0, Vec3(-2, 0, 1), Vec3(2, 1, 1), VBase4(0.5, 0.5, 1, 1.0)) constraint = BulletHingeConstraint(box_a.node(), box_b.node(), \ Vec3(-2, 0, 0), Vec3(2, 0, 0), \ Vec3(0, 1, 0), Vec3(0, 1, 0)) self.world.attachConstraint(constraint, linked_collision=True) self.muscle = Muscle(30) self.muscle.setA(box_a, Vec3(-1, 0, 1)) self.muscle.setB(box_b, Vec3(1, 0, 1)) self.muscle.setJointCenter(Vec3(-2, 0, 0)) # self.muscle.setupDebug(self.loader) self.disableCollisions() self.accept('escape', sys.exit) self.taskMgr.add(self.update, 'update') def disableCollisions(self): for i in range(32): self.world.setGroupCollisionFlag(i, i, False) self.world.setGroupCollisionFlag(0, 1, True) def setupDebug(self): node = BulletDebugNode('Debug') node.showWireframe(True) self.world.setDebugNode(node) np = self.render.attachNewNode(node) np.show() def createLens(self, aspect_ratio, fov=60.0, near=1.0, far=1000.0): lens = PerspectiveLens() lens.setFov(fov) lens.setAspectRatio(aspect_ratio) lens.setNearFar(near, far) return lens def setupCamera(self, width, height, pos, look): self.cam.setPos(pos) self.cam.lookAt(look) self.cam.node().setLens(self.createLens(width / height)) def createLighting(self): light = DirectionalLight('light') light.setColor(VBase4(0.6, 0.6, 0.6, 1)) light.setShadowCaster(True, 1024, 1024) light.getLens().setNearFar(1.0, 40.0) light.getLens().setFilmSize(40, 40) # light.showFrustum() np = self.render.attachNewNode(light) np.setPos(10, -10, 20) np.lookAt(0, 0, 0) self.render.setLight(np) light = AmbientLight('ambient') light.setColor(VBase4(0.4, 0.4, 0.4, 1)) np = self.render.attachNewNode(light) self.render.setLight(np) def createBox(self, mass, pos, scale, color): rb = BulletRigidBodyNode('box') rb.addShape(BulletBoxShape(scale)) rb.setMass(mass) rb.setLinearDamping(0.2) rb.setAngularDamping(0.9) rb.setFriction(1.0) rb.setAnisotropicFriction(1.0) rb.setRestitution(0.0) self.world.attachRigidBody(rb) np = self.render.attachNewNode(rb) np.setPos(pos) np.setCollideMask(BitMask32.bit(1)) cube = self.loader.loadModel('cube') cube.setScale(scale) cube.setColor(color) cube.reparentTo(np) return np def createPlane(self, pos, scale): rb = BulletRigidBodyNode('plane') rb.addShape(BulletPlaneShape(Vec3(0, 0, 1), 1)) rb.setFriction(1.0) rb.setAnisotropicFriction(1.0) rb.setRestitution(1.0) self.world.attachRigidBody(rb) np = self.render.attachNewNode(rb) np.setPos(pos) np.setCollideMask(BitMask32.bit(0)) plane = self.loader.loadModel('cube') plane.setScale(scale) plane.setPos(Vec3(0, 0, 0)) plane.setColor(VBase4(0.8, 0.8, 0.8, 1.0)) plane.reparentTo(np) return np def update(self, task): self.muscle.apply(1.0) self.world.doPhysics(globalClock.getDt(), 10, 1.0 / 180.0) return task.cont