Class: Stagecraft::Node

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

Direct Known Subclasses

Cameras::Camera, Lights::Light, MatrixNode, Mesh, Scene

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name: nil) ⇒ Node

Returns a new instance of Node.



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/stagecraft/core/node.rb', line 8

def initialize(name: nil)
  @name = name
  @visible = true
  @cast_shadow = false
  @receive_shadow = true
  @render_order = 0
  @children = []
  @parent = nil
  @local_revision = 0
  @cached_local_revision = -1
  @cached_parent_version = nil
  @cached_parent_identity = nil
  @world_version = 0
  @position = ObservedVec3.new(self)
  @rotation = ObservedQuat.new(self)
  @scale = ObservedVec3.new(self, Larb::Vec3.one)
  @local_matrix = Larb::Mat4.identity
  @world_matrix = Larb::Mat4.identity
end

Instance Attribute Details

#cast_shadowObject

Returns the value of attribute cast_shadow.



6
7
8
# File 'lib/stagecraft/core/node.rb', line 6

def cast_shadow
  @cast_shadow
end

#childrenObject (readonly)

Returns the value of attribute children.



5
6
7
# File 'lib/stagecraft/core/node.rb', line 5

def children
  @children
end

#nameObject

Returns the value of attribute name.



6
7
8
# File 'lib/stagecraft/core/node.rb', line 6

def name
  @name
end

#parentObject

Returns the value of attribute parent.



5
6
7
# File 'lib/stagecraft/core/node.rb', line 5

def parent
  @parent
end

#positionObject (readonly)

Returns the value of attribute position.



5
6
7
# File 'lib/stagecraft/core/node.rb', line 5

def position
  @position
end

#receive_shadowObject

Returns the value of attribute receive_shadow.



6
7
8
# File 'lib/stagecraft/core/node.rb', line 6

def receive_shadow
  @receive_shadow
end

#render_orderObject

Returns the value of attribute render_order.



6
7
8
# File 'lib/stagecraft/core/node.rb', line 6

def render_order
  @render_order
end

#rotationObject (readonly)

Returns the value of attribute rotation.



5
6
7
# File 'lib/stagecraft/core/node.rb', line 5

def rotation
  @rotation
end

#scaleObject (readonly)

Returns the value of attribute scale.



5
6
7
# File 'lib/stagecraft/core/node.rb', line 5

def scale
  @scale
end

#visibleObject

Returns the value of attribute visible.



6
7
8
# File 'lib/stagecraft/core/node.rb', line 6

def visible
  @visible
end

#world_versionObject (readonly)

Returns the value of attribute world_version.



5
6
7
# File 'lib/stagecraft/core/node.rb', line 5

def world_version
  @world_version
end

Instance Method Details

#add(*nodes) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
# File 'lib/stagecraft/core/node.rb', line 28

def add(*nodes)
  nodes.flatten.each do |node|
    validate_child!(node)
    next if node.parent.equal?(self)

    node.parent&.remove(node)
    node.send(:parent=, self)
    children << node
  end
  self
end

#find(target_name) ⇒ Object



55
56
57
# File 'lib/stagecraft/core/node.rb', line 55

def find(target_name)
  traverse.find { |node| node.name == target_name }
end

#local_matrixObject



59
60
61
62
63
64
65
# File 'lib/stagecraft/core/node.rb', line 59

def local_matrix
  return @local_matrix if @cached_local_revision == @local_revision

  @local_matrix = compose_local_matrix
  @cached_local_revision = @local_revision
  @local_matrix
end

#look_at(target, up: Larb::Vec3.up) ⇒ Object

Raises:

  • (ArgumentError)


91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/stagecraft/core/node.rb', line 91

def look_at(target, up: Larb::Vec3.up)
  target_value = target.respond_to?(:to_larb) ? target.to_larb : target
  eye = world_position
  raise ArgumentError, "look_at target must differ from position" if eye == target_value

  world_rotation = Larb::Mat4.look_at(eye, target_value, up).inverse.extract_rotation
  local_rotation = if parent
                     parent.world_matrix.extract_rotation.inverse * world_rotation
                   else
                     world_rotation
                   end
  rotation.set(local_rotation)
  self
end

#remove(node) ⇒ Object



40
41
42
43
44
45
# File 'lib/stagecraft/core/node.rb', line 40

def remove(node)
  return nil unless children.delete(node)

  node.send(:parent=, nil)
  node
end

#transform_dirty!Object



106
107
108
109
# File 'lib/stagecraft/core/node.rb', line 106

def transform_dirty!
  @local_revision += 1
  self
end

#traverse(&block) ⇒ Object



47
48
49
50
51
52
53
# File 'lib/stagecraft/core/node.rb', line 47

def traverse(&block)
  return enum_for(:traverse) unless block

  block.call(self)
  children.each { |child| child.traverse(&block) }
  self
end

#world_matrixObject



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

def world_matrix
  world_matrix_with_version.first
end

#world_matrix_with_versionObject



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

def world_matrix_with_version
  parent_matrix, parent_version = parent&.world_matrix_with_version
  parent_identity = parent&.object_id
  stale = @cached_local_revision != @local_revision ||
          @cached_parent_version != parent_version ||
          @cached_parent_identity != parent_identity
  if stale
    local = local_matrix
    @world_matrix = parent_matrix ? parent_matrix * local : local
    @cached_parent_version = parent_version
    @cached_parent_identity = parent_identity
    @world_version += 1
  end
  [@world_matrix, @world_version]
end

#world_positionObject



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

def world_position
  world_matrix.extract_translation
end