Class: Stagecraft::Raycaster

Inherits:
Object
  • Object
show all
Defined in:
lib/stagecraft/core/raycaster.rb

Defined Under Namespace

Classes: Hit

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(origin: Larb::Vec3.new, direction: Larb::Vec3.forward, near: 0.0, far: Float::INFINITY) ⇒ Raycaster

Returns a new instance of Raycaster.

Raises:

  • (ArgumentError)


9
10
11
12
13
14
15
16
# File 'lib/stagecraft/core/raycaster.rb', line 9

def initialize(origin: Larb::Vec3.new, direction: Larb::Vec3.forward, near: 0.0, far: Float::INFINITY)
  @near = Float(near)
  @far = Float(far)
  raise ArgumentError, "ray near distance cannot be negative" if @near.negative?
  raise ArgumentError, "ray far distance must not be less than near" if @far < @near

  set(origin, direction)
end

Instance Attribute Details

#directionObject (readonly)

Returns the value of attribute direction.



7
8
9
# File 'lib/stagecraft/core/raycaster.rb', line 7

def direction
  @direction
end

#farObject (readonly)

Returns the value of attribute far.



7
8
9
# File 'lib/stagecraft/core/raycaster.rb', line 7

def far
  @far
end

#nearObject (readonly)

Returns the value of attribute near.



7
8
9
# File 'lib/stagecraft/core/raycaster.rb', line 7

def near
  @near
end

#originObject (readonly)

Returns the value of attribute origin.



7
8
9
# File 'lib/stagecraft/core/raycaster.rb', line 7

def origin
  @origin
end

Instance Method Details

#intersect(root, recursive: true) ⇒ Object



35
36
37
38
# File 'lib/stagecraft/core/raycaster.rb', line 35

def intersect(root, recursive: true)
  nodes = recursive ? root.traverse : [root]
  nodes.filter_map { |node| intersect_mesh(node) }.sort_by(&:distance)
end

#set(origin, direction) ⇒ Object

Raises:

  • (ArgumentError)


18
19
20
21
22
23
24
25
# File 'lib/stagecraft/core/raycaster.rb', line 18

def set(origin, direction)
  @origin = vector(origin)
  value = vector(direction)
  raise ArgumentError, "ray direction cannot be zero" if value.length.zero?

  @direction = value.normalize
  self
end

#set_from_camera(ndc_x, ndc_y, camera) ⇒ Object



27
28
29
30
31
32
33
# File 'lib/stagecraft/core/raycaster.rb', line 27

def set_from_camera(ndc_x, ndc_y, camera)
  inverse = camera.view_projection_matrix.inverse
  near_point = unproject(inverse, ndc_x, ndc_y, 0.0)
  far_point = unproject(inverse, ndc_x, ndc_y, 1.0)
  ray_origin = camera.is_a?(Cameras::Perspective) ? camera.world_position : near_point
  set(ray_origin, far_point - ray_origin)
end