Class: Engine::Physics::Components::Rigidbody

Inherits:
Component
  • Object
show all
Defined in:
lib/engine/physics/components/rigidbody.rb

Instance Attribute Summary collapse

Attributes inherited from Component

#game_object

Instance Method Summary collapse

Methods inherited from Component

#_erase!, #destroy!, #destroyed?, destroyed_components, erase_destroyed_components, method_added, #renderer?, #set_game_object, #ui_renderer?

Methods included from Serializable

allowed_class?, get_class, included, register_class, #uuid

Instance Attribute Details

#angular_velocityObject

Returns the value of attribute angular_velocity.



8
9
10
# File 'lib/engine/physics/components/rigidbody.rb', line 8

def angular_velocity
  @angular_velocity
end

#coefficient_of_frictionObject

Returns the value of attribute coefficient_of_friction.



8
9
10
# File 'lib/engine/physics/components/rigidbody.rb', line 8

def coefficient_of_friction
  @coefficient_of_friction
end

#coefficient_of_restitutionObject

Returns the value of attribute coefficient_of_restitution.



8
9
10
# File 'lib/engine/physics/components/rigidbody.rb', line 8

def coefficient_of_restitution
  @coefficient_of_restitution
end

#forceObject

Returns the value of attribute force.



8
9
10
# File 'lib/engine/physics/components/rigidbody.rb', line 8

def force
  @force
end

#impulsesObject

Returns the value of attribute impulses.



8
9
10
# File 'lib/engine/physics/components/rigidbody.rb', line 8

def impulses
  @impulses
end

#massObject

Returns the value of attribute mass.



8
9
10
# File 'lib/engine/physics/components/rigidbody.rb', line 8

def mass
  @mass
end

#velocityObject

Returns the value of attribute velocity.



8
9
10
# File 'lib/engine/physics/components/rigidbody.rb', line 8

def velocity
  @velocity
end

Instance Method Details

#angular_momentum(origin = ) ⇒ Object



84
85
86
87
# File 'lib/engine/physics/components/rigidbody.rb', line 84

def angular_momentum(origin = Vector[0, 0, 0])
  moment_of_inertia * @angular_velocity +
    (game_object.pos - origin).cross(momentum)
end

#apply_angular_impulse(impulse) ⇒ Object



67
68
69
# File 'lib/engine/physics/components/rigidbody.rb', line 67

def apply_angular_impulse(impulse)
  @angular_impulses << impulse
end

#apply_impulse(impulse, point) ⇒ Object



62
63
64
65
# File 'lib/engine/physics/components/rigidbody.rb', line 62

def apply_impulse(impulse, point)
  @impulses << impulse
  @angular_impulses << (game_object.pos - point).cross(impulse)
end

#awakeObject



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/engine/physics/components/rigidbody.rb', line 16

def awake
  @velocity ||= Vector[0, 0, 0]
  @angular_velocity ||= Vector[0, 0, 0]
  @mass ||= 1
  @gravity ||= Vector[0, -9.81, 0]
  @coefficient_of_restitution ||= 1
  @coefficient_of_friction ||= 0
  @inertia_tensor ||= Matrix[
    [1, 0, 0],
    [0, 1, 0],
    [0, 0, 1]
  ] * @mass
  @force = @gravity * @mass
  @impulses = []
  @angular_impulses = []
end

#collidersObject



71
72
73
# File 'lib/engine/physics/components/rigidbody.rb', line 71

def colliders
  @game_object.components.select { |c| c.is_a?(SphereCollider) }
end

#destroyObject



37
38
39
# File 'lib/engine/physics/components/rigidbody.rb', line 37

def destroy
  Engine::Physics::PhysicsResolver.unregister_rigidbody(self)
end

#kinetic_energyObject



75
76
77
78
# File 'lib/engine/physics/components/rigidbody.rb', line 75

def kinetic_energy
  0.5 * @mass * @velocity.magnitude ** 2 +
    0.5 * moment_of_inertia * @angular_velocity.magnitude ** 2
end

#momentumObject



80
81
82
# File 'lib/engine/physics/components/rigidbody.rb', line 80

def momentum
  @mass * @velocity
end

#startObject



33
34
35
# File 'lib/engine/physics/components/rigidbody.rb', line 33

def start
  Engine::Physics::PhysicsResolver.register_rigidbody(self)
end

#update(delta_time) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/engine/physics/components/rigidbody.rb', line 41

def update(delta_time)
  @velocity += acceleration * delta_time
  @velocity += @impulses.reduce(Vector[0, 0, 0]) { |acc, impulse| acc + impulse } / @mass
  @impulses = []
  @game_object.pos += @velocity * delta_time

  total_angular_impulse = @angular_impulses.reduce(Vector[0, 0, 0]) { |acc, impulse| acc + impulse }
  if total_angular_impulse.magnitude > 0
    angular_inertia =
      if moment_of_inertia == 0
        impulse_direction = total_angular_impulse.normalize
        impulse_direction.dot(@inertia_tensor * impulse_direction)
      else
        moment_of_inertia
      end
    @angular_velocity += total_angular_impulse / angular_inertia
  end
  @angular_impulses = []
  @game_object.rotate_around(angular_velocity, delta_time * angular_velocity.magnitude) if angular_velocity.magnitude > 0
end

#velocity_at_point(point) ⇒ Object



89
90
91
# File 'lib/engine/physics/components/rigidbody.rb', line 89

def velocity_at_point(point)
  velocity + (angular_velocity.cross(game_object.pos - point) * Math::PI / 180)
end