Exemplo n.º 1
0
class Room(ccm.Model):
    def __init__(self, x, y, z=1, gravity=10, color=[
            Color(0xFFFFFF), Color(0xFFFFFF), Color(0xEEEEEE), Color(0xDDDDDD),
            Color(0xCCCCCC), Color(0xBBBBBB)], camera=(0, 0, 10), dt=0.0001):
        ccm.Model.__init__(self)
        self.size = (x, y, z)
        self.world = World()
        self.dt = dt
        brightness = 180
        self.world.setAmbientLight(brightness, brightness, brightness)
        self.world.addLight(SimpleVector(2, 2, 5), 10, 10, 10)
        self.world.camera.setPosition(*camera)
        self.world.camera.setOrientation(
            SimpleVector(0, 0, -1), SimpleVector(0, -1, 0))

        self.objects = []

        collisionConfiguration = DefaultCollisionConfiguration()
        dispatcher = CollisionDispatcher(collisionConfiguration)

        overlappingPairCache = AxisSweep3(
            Vector3f(-x / 2.0, -y / 2.0, -z / 2.0),
            Vector3f(x / 2.0, y / 2.0, z / 2.0),
            1024)
        solver = SequentialImpulseConstraintSolver()
        self.physics = DiscreteDynamicsWorld(
            dispatcher, overlappingPairCache, solver, collisionConfiguration)
        self.physics.setGravity(Vector3f(0, 0, -gravity))

        t = Transform()
        t.setIdentity()
        rbi = RigidBodyConstructionInfo(
            0, DefaultMotionState(t), StaticPlaneShape(
                Vector3f(0, 0, 1), 0), Vector3f(0, 0, 0))
        self.physics.addRigidBody(RigidBody(rbi))
        rbi = RigidBodyConstructionInfo(
            0, DefaultMotionState(t), StaticPlaneShape(
                Vector3f(0, 1, 0), -y / 2.0), Vector3f(0, 0, 0))
        self.physics.addRigidBody(RigidBody(rbi))
        rbi = RigidBodyConstructionInfo(
            0, DefaultMotionState(t), StaticPlaneShape(
                Vector3f(0, -1, 0), -y / 2.0), Vector3f(0, 0, 0))
        self.physics.addRigidBody(RigidBody(rbi))
        rbi = RigidBodyConstructionInfo(
            0, DefaultMotionState(t), StaticPlaneShape(
                Vector3f(1, 0, 0), -x / 2.0), Vector3f(0, 0, 0))
        self.physics.addRigidBody(RigidBody(rbi))
        rbi = RigidBodyConstructionInfo(
            0, DefaultMotionState(t), StaticPlaneShape(
                Vector3f(-1, 0, 0), -x / 2.0), Vector3f(0, 0, 0))
        self.physics.addRigidBody(RigidBody(rbi))

        self.vehicle_raycaster = DefaultVehicleRaycaster(self.physics)

        if not isinstance(color, (list, tuple)):
            room = createBox(x / 2.0, y / 2.0, z / 2.0)
            room.translate(0, 0, z / 2.0)
            room.invert()
            colorname = 'room%d' % id(self)
            TextureManager.getInstance().addTexture(
                colorname, Texture(1, 1, color))
            room.setTexture(colorname)
            room.shadingMode = Object3D.SHADING_FAKED_FLAT
            room.build()
            self.world.addObject(room)
        else:
            room = createBoxPieces(x / 2.0, y / 2.0, z / 2.0)
            for i, r in enumerate(room):
                r.translate(0, 0, z / 2.0)
                r.invert()
                colorname = 'room%d_%d' % (id(self), i)
                TextureManager.getInstance().addTexture(
                    colorname, Texture(1, 1, color[i % len(color)]))
                r.setTexture(colorname)
                r.shadingMode = Object3D.SHADING_FAKED_FLAT
                r.build()
                self.world.addObject(r)

        self.ratelimit = RateLimit()

    def add(self, obj, x, y, z=None):
        if z is None:
            t = Transform()
            min = Vector3f()
            max = Vector3f()
            obj.physics.getAabb(min, max)
            z = -min.z
        self.temp = obj
        if hasattr(obj, 'physics'):
            t = Transform()
            ms = obj.physics.motionState
            ms.getWorldTransform(t)
            m = Matrix4f()
            t.getMatrix(m)
            m.m03 = x
            m.m13 = y
            m.m23 = z
            t.set(m)
            ms.worldTransform = t
            obj.physics.motionState = ms

            self.physics.addRigidBody(obj.physics)

            if hasattr(obj, 'wheels'):
                tuning = VehicleTuning()
                obj.vehicle = RaycastVehicle(
                    tuning, obj.physics, self.vehicle_raycaster)
                obj.physics.setActivationState(
                    CollisionObject.DISABLE_DEACTIVATION)
                self.physics.addVehicle(obj.vehicle)
                obj.vehicle.setCoordinateSystem(1, 2, 0)

                for w in obj.wheels:
                    wheel = obj.vehicle.addWheel(Vector3f(w.x, w.y, w.z),
                                                 Vector3f(w.dir),
                                                 Vector3f(w.axle),
                                                 w.suspension_rest_len,
                                                 w.radius,
                                                 tuning,
                                                 False)
                    wheel.suspensionStiffness = w.suspension_stiffness
                    wheel.maxSuspensionTravelCm = w.suspension_max_travel * 100
                    wheel.frictionSlip = w.friction
                    wheel.wheelsDampingRelaxation = w.damping_relaxation
                    wheel.wheelsDampingCompression = w.damping_compression
                    wheel.rollInfluence = w.roll_influence

        self.objects.append(obj)
        self.world.addObject(obj.shape)

    def start(self):
        dt = self.dt
        while True:
            self.physics_dump()
            # p = self.physics_dump()
            # self.update_shapes(p)
            for obj in self.objects:
                if hasattr(obj, 'vehicle'):
                    for i, w in enumerate(obj.wheels):
                        obj.vehicle.updateWheelTransform(i, True)
                        obj.vehicle.applyEngineForce(w.force, i)
                        # obj.vehicle.setBrake(w.brake, i)

            self.physics.stepSimulation(dt, 10, dt * 0.1)
            yield dt

    def physics_dump(self):
        d = {}
        for obj in self.objects:
            if hasattr(obj, 'physics'):
                t = Transform()
                obj.physics.getMotionState().getWorldTransform(t)
                m = Matrix4f()
                t.getMatrix(m)

                trans = Matrix()
                trans.set(3, 0, m.m03)
                trans.set(3, 1, m.m13)
                trans.set(3, 2, m.m23)
                rot = Matrix()
                for i in range(3):
                    for j in range(3):
                        rot.set(i, j, m.getElement(j, i))
                d[obj] = (trans, rot)
        return d

    def update_shapes(self, physics):
        for obj in self.objects:
            if hasattr(obj, 'physics') and obj in physics:
                trans, rot = physics[obj]
                obj.shape.translationMatrix = trans
                obj.shape.rotationMatrix = rot
                if hasattr(obj, 'extra_shapes'):
                    for s, x, y, z in obj.extra_shapes:
                        p = SimpleVector(x, y, z)
                        p.matMul(rot)
                        m4 = Matrix(trans)
                        m4.translate(p)
                        s.translationMatrix = m4
                        s.rotationMatrix = rot