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 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 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)
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)
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
def get_rotation_quaternion(dir): angle = (dir - 0.5) / 2 * pi return Quaternion.new_rotate_axis(angle, Vector3(0, 0, 1))