예제 #1
0
    def tick(self, time):
        if abs(self.angular_velocity) > 0.001:
            q = Quaternion.new_rotate_axis(abs(self.angular_velocity) * time,
                                       self.angular_velocity.normalized())
        else:
            q = Quaternion()
        self.rotation *= q
        self.rotation = Quaternion.new_rotate_axis(*self.rotation.get_angle_axis())
        self.position += self.velocity * time + (self.game.gravity * time ** 2) / 2
        self.velocity += self.game.gravity * time

        self.check_ground(time)
예제 #2
0
    def adjust_rotation(self, center, height):
        probe_len = 1#self.probe_len
        # y, z, x
        heading, attitude, bank = self.rotation.get_euler()

        height_x = self.game.terrain.get_height_at(center + Vector2(probe_len, 0))
        heading = -safe_asin((height_x - height) / probe_len)

        height_y = self.game.terrain.get_height_at(center + Vector2(0, probe_len))
        bank = safe_asin((height_y - height) / probe_len)

        # TODO: use angular_velocity instead
        d_rotation = Quaternion.new_rotate_euler(heading, 0, bank)
        d_rotation *= Quaternion.new_rotate_euler(0, attitude, 0)

        self.rotation = d_rotation
예제 #3
0
 def create_static_object(self, player_name, name, pos=None):
     # for debugging
     player = self.get_player(player_name)
     model = g3d.model.read(loader=self.loader, name=name).clone()
     obj = Object(self, model)
     obj.owner = player
     obj.position = pos or Vector3(120, 135 + self._static_num * 30, 210)
     obj.rotation = Quaternion.new_rotate_axis(0, Vector3(0, 0, 1))
     model.root.scale = 10
     self._static_num += 1
     self.add_object(obj)
예제 #4
0
    def __init__(self, game, model):
        self.game = game
        self.ident = random_string()
        self.model = model
        self.model.root.scale = self.model_scale
        self.owner = None

        self.is_on_ground = False

        self.position = Vector3()
        self.velocity = Vector3()

        self.rotation = Quaternion()
        self.angular_velocity = Vector3()

        self.motor = (0, 0)
예제 #5
0
class Object(object):
    model_scale = 0.2
    probe_len = 0.1

    def __init__(self, game, model):
        self.game = game
        self.ident = random_string()
        self.model = model
        self.model.root.scale = self.model_scale
        self.owner = None

        self.is_on_ground = False

        self.position = Vector3()
        self.velocity = Vector3()

        self.rotation = Quaternion()
        self.angular_velocity = Vector3()

        self.motor = (0, 0)

    def tick(self, time):
        if abs(self.angular_velocity) > 0.001:
            q = Quaternion.new_rotate_axis(abs(self.angular_velocity) * time,
                                       self.angular_velocity.normalized())
        else:
            q = Quaternion()
        self.rotation *= q
        self.rotation = Quaternion.new_rotate_axis(*self.rotation.get_angle_axis())
        self.position += self.velocity * time + (self.game.gravity * time ** 2) / 2
        self.velocity += self.game.gravity * time

        self.check_ground(time)

    def calc_motor(self, time):
        f0, f1 = self.motor
        f = (f0 + f1) * self.motor_force # net force
        m = (f1 - f0) * self.motor_force * self.motor_radius # torque
        self.velocity += self.rotation * Vector3(f / self.mass * time, 0, 0)
        j = self.mass # moment of intertia
        self.angular_velocity += (m / j * time) *  Vector3(0, 0, 1)

    def check_ground(self, time):
        center = Vector2(self.position.x, self.position.y)
        height = self.game.terrain.get_height_at(center)
        if self.position.z <= height:
            self.is_on_ground = True
            self.position.z = height

            self.calc_motor(time)
            #self.adjust_rotation(center, height)
            #self.rotate_velocity(center, height)
            self.apply_friction(time)
        else:
            self.is_on_ground = False

    def adjust_rotation(self, center, height):
        probe_len = 1#self.probe_len
        # y, z, x
        heading, attitude, bank = self.rotation.get_euler()

        height_x = self.game.terrain.get_height_at(center + Vector2(probe_len, 0))
        heading = -safe_asin((height_x - height) / probe_len)

        height_y = self.game.terrain.get_height_at(center + Vector2(0, probe_len))
        bank = safe_asin((height_y - height) / probe_len)

        # TODO: use angular_velocity instead
        d_rotation = Quaternion.new_rotate_euler(heading, 0, bank)
        d_rotation *= Quaternion.new_rotate_euler(0, attitude, 0)

        self.rotation = d_rotation

    def rotate_velocity(self, center, height):
        ''' Make sure that velocity is not pointed underground. '''
        velocity_projection = Vector2(self.velocity.x, self.velocity.y)
        if abs(velocity_projection) < 0.001:
            return
        velocity_projection = velocity_projection.normalized()
        height_v = self.game.terrain.get_height_at(center + velocity_projection)
        ground_vector = Vector3(velocity_projection.x,
                                velocity_projection.y,
                                height_v - height).normalized()
        velocity_angle = Vector3.angle_between(ground_vector, self.velocity)
        if velocity_angle < 0:
            self.velocity = abs(self.velocity) * self.ground_vector

    def apply_friction(self, time):
        kinetic_friction = \
            self.game.terrain.get_kinetic_friction(self.position, self.velocity) * time
        if kinetic_friction > abs(self.velocity):
            self.velocity = Vector3(0, 0, 0)
        else:
            self.velocity -= (self.velocity.normalized() * kinetic_friction)

        angular_friction = \
            self.game.terrain.get_angular_friction(self.position,
                                                   self.angular_velocity) * time

        if abs(self.angular_velocity) < angular_friction:
            self.angular_velocity = Vector3()
        else:
            self.angular_velocity -= self.angular_velocity.normalized() * angular_friction
예제 #6
0
def get_rotation_quaternion(dir):
    angle = (dir - 0.5) / 2 * pi
    return Quaternion.new_rotate_axis(angle, Vector3(0, 0, 1))