Beispiel #1
0
    def __init__(self, app, model_name):
        model_file_name = 'assets/cars/{}/{}.bam'.format(
            model_name, model_name)
        self.app = app

        def animation_path(model, animation):
            base_path = 'assets/cars/animations/{}/{}-{}.bam'
            return base_path.format(model, model, animation)

        self.model = Actor(
            model_file_name,
            {
                #    AIRBRAKE: 'assets/cars/animations/{}-{}.bam'.format(model_name, AIRBRAKE),
                #    AIRBRAKE: animation_path(model_name, AIRBRAKE),
                #    STABILIZER_FINS: animation_path(model_name, STABILIZER_FINS),
            })
        self.model.enableBlend()
        self.model.setControlEffect(AIRBRAKE, 1)
        self.model.setControlEffect(STABILIZER_FINS, 1)
        # FIXME: This code fails due to a bug in Actor
        # airbrake_joints = [joint.name
        #                    for joint in self.model.getJoints()
        #                    if joint.name.startswith(AIRBRAKE)
        # ]
        # self.model.makeSubpart(AIRBRAKE, airbrake_joints)
        # stabilizer_joints = [joint.name
        #                      for joint in self.model.getJoints()
        #                      if joint.name.startswith(STABILIZER_FINS)
        # ]
        # self.model.makeSubpart(STABILIZER_FINS, stabilizer_joints)

        puppet = self.app.loader.load_model(model_file_name)
        puppet.find("**/armature").hide()
        puppet.reparentTo(self.model)

        # Get the vehicle data
        self.vehicle_data = VehicleData(puppet, model_name, 'cars')

        # Configure the physics node
        self.physics_node = BulletRigidBodyNode('vehicle')
        self.physics_node.set_friction(self.vehicle_data.friction)
        self.physics_node.set_linear_sleep_threshold(0)
        self.physics_node.set_angular_sleep_threshold(0)
        self.physics_node.setCcdMotionThreshold(1e-7)
        self.physics_node.setCcdSweptSphereRadius(0.5)
        self.physics_node.setMass(self.vehicle_data.mass)
        shape = BulletConvexHullShape()
        for geom_node in self.model.find_all_matches("**/+GeomNode"):
            for geom in geom_node.node().get_geoms():
                vertices = GeomVertexReader(geom.get_vertex_data(), 'vertex')
                while not vertices.is_at_end():
                    v_geom = vertices.getData3f()
                    v_model = self.model.get_relative_point(geom_node, v_geom)
                    shape.add_point(v_model)
        self.physics_node.add_shape(shape)
        self.vehicle = NodePath(self.physics_node)
        self.vehicle.set_collide_mask(CM_VEHICLE | CM_COLLIDE)
        self.model.reparent_to(self.vehicle)

        # Navigational aids
        self.target_node = self.app.loader.load_model('models/zup-axis')
        self.target_node.reparent_to(self.model)
        self.target_node.set_scale(1)
        self.target_node.set_render_mode_wireframe()
        self.target_node.hide()

        self.delta_node = self.app.loader.load_model('models/smiley')
        self.delta_node.set_pos(1, 10, 1)
        self.delta_node.reparent_to(base.cam)
        self.delta_node.hide()

        self.airbrake_state = 0.0
        self.airbrake_factor = 0.5
        self.airbrake_speed = 1 / self.vehicle_data.airbrake_duration
        self.stabilizer_fins_state = 0.0
        self.stabilizer_fins_speed = 1 / self.vehicle_data.stabilizer_fins_duration

        self.centroid = base.loader.load_model('models/smiley')
        self.centroid.reparent_to(self.vehicle)
        self.centroid.hide()

        # Gyro sound
        sound_file = 'assets/cars/{}/{}.wav'.format(
            model_name,
            GYROSCOPE_SOUND,
        )
        sound = base.audio3d.load_sfx(sound_file)
        self.model.set_python_tag(GYROSCOPE_SOUND, sound)
        base.audio3d.attach_sound_to_object(sound, self.model)
        sound.set_volume(0)
        sound.set_play_rate(0)
        sound.set_loop(True)
        sound.play()

        # Thruster limiting
        self.thruster_state = 0.0
        self.thruster_heat = 0.0

        for repulsor in self.vehicle_data.repulsor_nodes:
            self.add_repulsor(repulsor, model_name)
        for thruster in self.vehicle_data.thruster_nodes:
            self.add_thruster(thruster, model_name)

        # ECU data storage from frame to frame
        self.last_flight_height = None

        # FIXME: Move into a default controller
        self.inputs = {
            # Repulsors
            REPULSOR_ACTIVATION: 0.0,
            ACCELERATE: 0.0,
            TURN: 0.0,
            STRAFE: 0.0,
            HOVER: 0.0,
            FULL_REPULSORS: False,
            # Gyro
            ACTIVE_STABILIZATION_ON_GROUND: PASSIVE,
            ACTIVE_STABILIZATION_CUTOFF_ANGLE: PASSIVE,
            ACTIVE_STABILIZATION_IN_AIR: PASSIVE,
            TARGET_ORIENTATION: Vec3(0, 0, 0),
            # Thrust
            THRUST: 0.0,
            # Air foils
            AIRBRAKE: 0.0,
            STABILIZER_FINS: 0.0,
        }
        self.sensors = {}
        self.commands = {}