Class: Stagecraft::Geometry

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

Constant Summary collapse

ATTRIBUTE_NAMES =
%i[position normal uv uv1 tangent color joints weights].freeze
TOPOLOGIES =
%i[point_list line_list line_strip triangle_list triangle_strip].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(topology: :triangle_list) ⇒ Geometry

Returns a new instance of Geometry.



11
12
13
14
15
16
17
18
19
# File 'lib/stagecraft/core/geometry.rb', line 11

def initialize(topology: :triangle_list)
  @attributes = {}
  @index = nil
  @version = 0
  @disposed = false
  @dispose_callbacks = []
  @bounding_version = -1
  self.topology = topology
end

Instance Attribute Details

#indexObject (readonly)

Returns the value of attribute index.



9
10
11
# File 'lib/stagecraft/core/geometry.rb', line 9

def index
  @index
end

#topologyObject

Returns the value of attribute topology.



9
10
11
# File 'lib/stagecraft/core/geometry.rb', line 9

def topology
  @topology
end

#versionObject (readonly)

Returns the value of attribute version.



9
10
11
# File 'lib/stagecraft/core/geometry.rb', line 9

def version
  @version
end

Instance Method Details

#attribute(name) ⇒ Object



37
38
39
# File 'lib/stagecraft/core/geometry.rb', line 37

def attribute(name)
  @attributes[name.to_sym]
end

#attributesObject



41
42
43
# File 'lib/stagecraft/core/geometry.rb', line 41

def attributes
  @attributes.dup.freeze
end

#bounding_boxObject



62
63
64
65
# File 'lib/stagecraft/core/geometry.rb', line 62

def bounding_box
  refresh_bounds! if @bounding_version != version
  @bounding_box
end

#bounding_sphereObject



67
68
69
70
# File 'lib/stagecraft/core/geometry.rb', line 67

def bounding_sphere
  refresh_bounds! if @bounding_version != version
  @bounding_sphere
end

#compute_normals!Object



72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/stagecraft/core/geometry.rb', line 72

def compute_normals!
  positions = position_values
  normals = Array.new(positions.length) { Larb::Vec3.new }
  triangle_indices.each_slice(3) do |a, b, c|
    break unless c

    face = (positions[b] - positions[a]).cross(positions[c] - positions[a])
    normals[a] = normals[a] + face
    normals[b] = normals[b] + face
    normals[c] = normals[c] + face
  end
  packed = normals.flat_map { |normal| normal.length.zero? ? [0.0, 1.0, 0.0] : normal.normalize.to_a }.pack("e*")
  set_attribute(:normal, data: packed, format: :float32x3, count: positions.length)
end

#delete_attribute(name) ⇒ Object



31
32
33
34
35
# File 'lib/stagecraft/core/geometry.rb', line 31

def delete_attribute(name)
  return nil unless @attributes.delete(name.to_sym)

  changed!
end

#disposeObject



92
93
94
95
96
97
98
99
100
# File 'lib/stagecraft/core/geometry.rb', line 92

def dispose
  return self if @disposed

  @disposed = true
  @version += 1
  @dispose_callbacks.each { |callback| callback.call(self) }
  @dispose_callbacks.clear
  self
end

#disposed?Boolean

Returns:

  • (Boolean)


102
103
104
# File 'lib/stagecraft/core/geometry.rb', line 102

def disposed?
  @disposed
end

#on_dispose(&block) ⇒ Object



87
88
89
90
# File 'lib/stagecraft/core/geometry.rb', line 87

def on_dispose(&block)
  @dispose_callbacks << block
  self
end

#set_attribute(name, data:, format:, count:) ⇒ Object

Raises:

  • (ArgumentError)


21
22
23
24
25
26
27
28
29
# File 'lib/stagecraft/core/geometry.rb', line 21

def set_attribute(name, data:, format:, count:)
  ensure_alive!
  key = name.to_sym
  raise ArgumentError, "unsupported attribute #{name.inspect}" unless ATTRIBUTE_NAMES.include?(key)

  @attributes[key] = Attribute.new(data:, format:, count:) { changed! }
  changed!
  self
end

#set_index(data:, format:) ⇒ Object



45
46
47
48
49
50
# File 'lib/stagecraft/core/geometry.rb', line 45

def set_index(data:, format:)
  ensure_alive!
  @index = IndexAttribute.new(data:, format:) { changed! }
  changed!
  self
end