Class: Doom::Render::RayTracing::Bvh

Inherits:
Object
  • Object
show all
Defined in:
lib/doom/render/ray_tracing/bvh.rb

Overview

Stackless, pre-order bounding volume hierarchy for GPU traversal. Internal nodes point at their children and every node stores an escape index, allowing GLSL 1.20 to traverse without a dynamic stack.

Defined Under Namespace

Classes: Node

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(source_triangles, leaf_size: 8) ⇒ Bvh

Returns a new instance of Bvh.



19
20
21
22
23
24
25
# File 'lib/doom/render/ray_tracing/bvh.rb', line 19

def initialize(source_triangles, leaf_size: 8)
  @leaf_size = leaf_size
  @nodes = []
  @triangles = []
  @triangle_order = []
  build(source_triangles.each_with_index.to_a)
end

Instance Attribute Details

#leaf_sizeObject (readonly)

Returns the value of attribute leaf_size.



17
18
19
# File 'lib/doom/render/ray_tracing/bvh.rb', line 17

def leaf_size
  @leaf_size
end

#nodesObject (readonly)

Returns the value of attribute nodes.



17
18
19
# File 'lib/doom/render/ray_tracing/bvh.rb', line 17

def nodes
  @nodes
end

#triangle_orderObject (readonly)

Returns the value of attribute triangle_order.



17
18
19
# File 'lib/doom/render/ray_tracing/bvh.rb', line 17

def triangle_order
  @triangle_order
end

#trianglesObject (readonly)

Returns the value of attribute triangles.



17
18
19
# File 'lib/doom/render/ray_tracing/bvh.rb', line 17

def triangles
  @triangles
end

Instance Method Details

#compatible?(source_triangles) ⇒ Boolean

Returns:

  • (Boolean)


27
28
29
# File 'lib/doom/render/ray_tracing/bvh.rb', line 27

def compatible?(source_triangles)
  @triangle_order.size == source_triangles.size
end

#packed_floatsObject

Three RGBA texels per node: min/escape, max/start, count/padding.



52
53
54
55
56
57
58
# File 'lib/doom/render/ray_tracing/bvh.rb', line 52

def packed_floats
  @nodes.flat_map do |node|
    [*node.minimum, node.escape.to_f,
     *node.maximum, node.start.to_f,
     node.count.to_f, 0.0, 0.0, 0.0]
  end
end

#refit(source_triangles) ⇒ Object

Door/lift motion changes vertices but not triangle identity. Refit bounds bottom-up while preserving the GPU-friendly leaf ordering.

Raises:

  • (ArgumentError)


33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/doom/render/ray_tracing/bvh.rb', line 33

def refit(source_triangles)
  raise ArgumentError, 'triangle topology changed' unless compatible?(source_triangles)

  @triangles = @triangle_order.map { |index| source_triangles[index] }
  (@nodes.size - 1).downto(0) do |index|
    node = @nodes[index]
    if node.leaf?
      node.minimum, node.maximum = bounds(@triangles[node.start, node.count])
    else
      left = @nodes[node.left]
      right = @nodes[node.right]
      node.minimum = axes { |axis| [left.minimum[axis], right.minimum[axis]].min }
      node.maximum = axes { |axis| [left.maximum[axis], right.maximum[axis]].max }
    end
  end
  self
end