コード例 #1
0
ファイル: jcmb_bullet.py プロジェクト: PlumpMath/jcmb
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')
コード例 #2
0
ファイル: simulator.py プロジェクト: ajaybha/OpenBiped
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)
コード例 #3
0
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()


    """
コード例 #4
0
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)
コード例 #5
0
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)
コード例 #6
0
ファイル: RonnieRacer.py プロジェクト: MarcusKhoo/RonnieRacer
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)
コード例 #7
0
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))
コード例 #8
0
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