Class: GlimR::SceneObject

Inherits:
Object show all
Includes:
GL, Configurable, EventListener
Defined in:
lib/glimr/renderer/sceneobject.rb

Overview

The SceneObject is the root class of the GlimR scene graph class hierarchy.

A SceneObject may have a parent and children, and usually will. All actual OpenGL state manipulation should be done with its specific subclasses like Transform, Geometry and Texture.

The SceneObject is an EventListener, and as such you can tell it to listen and respond to events.

SceneObjects also maintain a list of drawable objects underneath them. This is mainly used to speed up rendering by removing the need to traverse the whole scene graph to draw the scene.

Example:

s = SceneObject.new
t = Texture.new
s.attach t
s.detach t

Instance Attribute Summary collapse

Attributes included from EventListener

#event_listeners, #listener_count

Instance Method Summary collapse

Methods included from EventListener

#add_event_listener, #decrement_listener_count, #dispatch_event, #event_root, #increment_listener_count, #method_missing, #multicast_event, #process_event, #remove_event_listener

Constructor Details

#initialize(*arg_hash, &config_block) ⇒ SceneObject

Configurable initialize.



46
47
48
49
50
# File 'lib/glimr/renderer/sceneobject.rb', line 46

def initialize(*arg_hash, &config_block)
  @children = []
  @drawables = Set.new
  super
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class GlimR::EventListener

Instance Attribute Details

#childrenObject

Returns the value of attribute children.



34
35
36
# File 'lib/glimr/renderer/sceneobject.rb', line 34

def children
  @children
end

#drawablesObject

Returns the value of attribute drawables.



34
35
36
# File 'lib/glimr/renderer/sceneobject.rb', line 34

def drawables
  @drawables
end

#mtimeObject (readonly)

Returns the value of attribute mtime.



35
36
37
# File 'lib/glimr/renderer/sceneobject.rb', line 35

def mtime
  @mtime
end

#parentObject

Returns the value of attribute parent.



34
35
36
# File 'lib/glimr/renderer/sceneobject.rb', line 34

def parent
  @parent
end

#viewportObject

Returns the viewport or possible parent’s viewport.



53
54
55
# File 'lib/glimr/renderer/sceneobject.rb', line 53

def viewport
  @viewport
end

Instance Method Details

#<<(new_child) ⇒ Object

Attach single child.



84
85
86
87
# File 'lib/glimr/renderer/sceneobject.rb', line 84

def <<(new_child)
  attach new_child
  self
end

#absolute_geometryObject



206
207
208
# File 'lib/glimr/renderer/sceneobject.rb', line 206

def absolute_geometry
  parent.absolute_geometry
end

#absolute_materialObject



183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'lib/glimr/renderer/sceneobject.rb', line 183

def absolute_material
  #~ unless parent
    #~ puts object_id, geometry.object_id, self, geometry
    #~ ObjectSpace.each_object(Button){|b|
      #~ if b.drawables.include? geometry
        #~ puts b
        #~ p b.drawables.to_a, b.children
        #~ puts
        #~ puts
        #~ cc = b.children.find{|c|
          #~ c.geometry == geometry if c.is_a? Model
        #~ }
        #~ p cc
      #~ end
    #~ }
  #~ end
  parent.absolute_material
end

#absolute_shaderObject



210
211
212
# File 'lib/glimr/renderer/sceneobject.rb', line 210

def absolute_shader
  parent.absolute_shader
end

#absolute_textureObject



202
203
204
# File 'lib/glimr/renderer/sceneobject.rb', line 202

def absolute_texture
  parent.absolute_texture
end

#absolute_transformObject

The collapsed state of a SceneObject is its parent’s collapsed state, which fits in with SceneObjects not editing OpenGL state.



175
176
177
# File 'lib/glimr/renderer/sceneobject.rb', line 175

def absolute_transform
  parent.absolute_transform
end

#absolute_transform_for_drawingObject



179
180
181
# File 'lib/glimr/renderer/sceneobject.rb', line 179

def absolute_transform_for_drawing
  absolute_transform
end

#add_drawables(d) ⇒ Object

Adds d to drawables and parent’s drawables.



124
125
126
127
# File 'lib/glimr/renderer/sceneobject.rb', line 124

def add_drawables(d)
  parent.add_drawables d if parent
  @drawables += d
end

#applyObject

Applies the SceneObject to OpenGL state. For SceneObject, this is empty.



216
217
# File 'lib/glimr/renderer/sceneobject.rb', line 216

def apply
end

#attach(*new_children) ⇒ Object

Attaches new_children to the scene graph below self.



77
78
79
80
81
# File 'lib/glimr/renderer/sceneobject.rb', line 77

def attach(*new_children)
  new_children.each{|c|
    adopt(c)
  }
end

#clone(deep = false) ⇒ Object

Creates a clone of the SceneObject. If deep is set to true, also clones the children. If deep is false, clears children.



233
234
235
236
237
238
239
240
241
242
243
244
245
246
# File 'lib/glimr/renderer/sceneobject.rb', line 233

def clone(deep=false)
  c = super()
  if deep
    c.children = []
    c.drawables.clear
    cchildren = c.children.map{|ch| ch.clone(deep) }
    c.attach *cchildren
  else
    c.children = []
    c.drawables.clear
  end
  c.parent = nil
  c
end

#default_configObject



38
39
40
41
42
43
# File 'lib/glimr/renderer/sceneobject.rb', line 38

def default_config
  super.merge(
    :visible => true,
    :mtime => Time.now.to_f
  )
end

#detach(*children_to_detach) ⇒ Object

Detaches children_to_detach from self.



90
91
92
93
94
# File 'lib/glimr/renderer/sceneobject.rb', line 90

def detach(*children_to_detach)
  children_to_detach.each{|c|
    orphan(c)
  }
end

#detach_selfObject

Detaches self from parent if there is a parent.



97
98
99
# File 'lib/glimr/renderer/sceneobject.rb', line 97

def detach_self
  parent.detach(self) if parent
end

#inspectObject



248
249
250
# File 'lib/glimr/renderer/sceneobject.rb', line 248

def inspect
  "#<#{self.class.name}:#{object_id}>"
end

#pop_stateObject

Pops the relevant OpenGL state stack. Empty for SceneObject.



226
227
# File 'lib/glimr/renderer/sceneobject.rb', line 226

def pop_state
end

#push_stateObject

Pushes the relevant OpenGL state stack. Empty for SceneObject.



221
222
# File 'lib/glimr/renderer/sceneobject.rb', line 221

def push_state
end

#remove_drawables(d) ⇒ Object

Removes d from drawables and parent’s drawables.



130
131
132
133
# File 'lib/glimr/renderer/sceneobject.rb', line 130

def remove_drawables(d)
  parent.remove_drawables d if parent
  @drawables -= d
end

#render(*a) ⇒ Object

Renders the SceneObject by pushing state, applying, calling render for each child, and popping state.

Not used with collapsing Viewport #render.



166
167
168
169
170
171
# File 'lib/glimr/renderer/sceneobject.rb', line 166

def render(*a)
  push_state
  apply
  children.each{|c| c.render if c.visible }
  pop_state
end

#replace_node(orig, replacement = nil) ⇒ Object

Replaces orig node in scene graph with replacement by Attaching the replacement to orig’s parent, and attaching orig’s children to replacement.

If no replacement is given, removes orig from scenegraph and attaches its children to its parent. If there is no parent or replacement, does nothing.



151
152
153
154
155
156
157
158
159
160
# File 'lib/glimr/renderer/sceneobject.rb', line 151

def replace_node(orig, replacement=nil)
  return unless orig
  replacement ||= orig.parent
  return unless replacement
  replacement.detach(*orig.children)
  replacement.attach(*orig.children)
  orig.detach(*orig.children)
  orig.parent.attach(replacement) if orig.parent
  orig.detach_self
end

#rootObject

Returns the scene root. This is either the viewport, the parent’s scene root if there is no viewport, or self if there is no parent.



62
63
64
# File 'lib/glimr/renderer/sceneobject.rb', line 62

def root
  (viewport || (parent ? parent.root : self))
end

#touch!(mtime = Time.now.to_f) ⇒ Object



252
253
254
255
256
# File 'lib/glimr/renderer/sceneobject.rb', line 252

def touch!(mtime=Time.now.to_f)
  @mtime = mtime
  parent.touch!(@mtime) if parent
  nil
end

#visibleObject

A node is visible if its @visible is true and its parent is visible (if it has a parent.)



119
120
121
# File 'lib/glimr/renderer/sceneobject.rb', line 119

def visible
  @visible and (parent ? parent.visible : true)
end