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, #destroy!, #destroyed?, destroyed_components, erase_destroyed_components, method_added, #renderer?, #set_game_object, #start, #ui_renderer?

Constructor Details

#initialize(velocity: Vector[0, 0, 0], angular_velocity: Vector[0, 0, 0], mass: 1, inertia_tensor: nil, gravity: Vector[0, -9.81, 0], coefficient_of_restitution: 1, coefficient_of_friction: 0) ⇒ Rigidbody

Returns a new instance of Rigidbody.



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/engine/physics/components/rigidbody.rb', line 13

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

Instance Attribute Details

#angular_velocityObject

Returns the value of attribute angular_velocity.



5
6
7
# File 'lib/engine/physics/components/rigidbody.rb', line 5

def angular_velocity
  @angular_velocity
end

#coefficient_of_frictionObject

Returns the value of attribute coefficient_of_friction.



5
6
7
# File 'lib/engine/physics/components/rigidbody.rb', line 5

def coefficient_of_friction
  @coefficient_of_friction
end

#coefficient_of_restitutionObject

Returns the value of attribute coefficient_of_restitution.



5
6
7
# File 'lib/engine/physics/components/rigidbody.rb', line 5

def coefficient_of_restitution
  @coefficient_of_restitution
end

#forceObject

Returns the value of attribute force.



5
6
7
# File 'lib/engine/physics/components/rigidbody.rb', line 5

def force
  @force
end

#impulsesObject

Returns the value of attribute impulses.



5
6
7
# File 'lib/engine/physics/components/rigidbody.rb', line 5

def impulses
  @impulses
end

#massObject

Returns the value of attribute mass.



5
6
7
# File 'lib/engine/physics/components/rigidbody.rb', line 5

def mass
  @mass
end

#velocityObject

Returns the value of attribute velocity.



5
6
7
# File 'lib/engine/physics/components/rigidbody.rb', line 5

def velocity
  @velocity
end

Instance Method Details

#angular_momentum(origin = ) ⇒ Object



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

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



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

def apply_angular_impulse(impulse)
  @angular_impulses << impulse
end

#apply_impulse(impulse, point) ⇒ Object



59
60
61
62
# File 'lib/engine/physics/components/rigidbody.rb', line 59

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

#collidersObject



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

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

#kinetic_energyObject



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

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

#momentumObject



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

def momentum
  @mass * @velocity
end

#update(delta_time) ⇒ Object



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

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



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

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