glimr 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/glimr.rb +2 -0
- data/lib/glimr/configurable.rb +37 -0
- data/lib/glimr/default_theme/button_bg.png +0 -0
- data/lib/glimr/default_theme/button_bg_down.png +0 -0
- data/lib/glimr/default_theme/button_cover.png +0 -0
- data/lib/glimr/default_theme/button_cover_down.png +0 -0
- data/lib/glimr/default_theme/button_focus.png +0 -0
- data/lib/glimr/default_theme/checkbox_bg.png +0 -0
- data/lib/glimr/default_theme/checkbox_checked_bg.png +0 -0
- data/lib/glimr/default_theme/font.ttf +0 -0
- data/lib/glimr/default_theme/hscroller_bg.png +0 -0
- data/lib/glimr/default_theme/radiobutton_bg.png +0 -0
- data/lib/glimr/default_theme/radiobutton_checked_bg.png +0 -0
- data/lib/glimr/default_theme/resizer_down.png +0 -0
- data/lib/glimr/default_theme/resizer_up.png +0 -0
- data/lib/glimr/default_theme/scroll_down_down.png +0 -0
- data/lib/glimr/default_theme/scroll_down_up.png +0 -0
- data/lib/glimr/default_theme/scroll_hknob_down.png +0 -0
- data/lib/glimr/default_theme/scroll_hknob_up.png +0 -0
- data/lib/glimr/default_theme/scroll_left_down.png +0 -0
- data/lib/glimr/default_theme/scroll_left_up.png +0 -0
- data/lib/glimr/default_theme/scroll_right_down.png +0 -0
- data/lib/glimr/default_theme/scroll_right_up.png +0 -0
- data/lib/glimr/default_theme/scroll_up_down.png +0 -0
- data/lib/glimr/default_theme/scroll_up_up.png +0 -0
- data/lib/glimr/default_theme/scroll_vknob_down.png +0 -0
- data/lib/glimr/default_theme/scroll_vknob_up.png +0 -0
- data/lib/glimr/default_theme/text_cursor.png +0 -0
- data/lib/glimr/default_theme/text_cursor_insert.png +0 -0
- data/lib/glimr/default_theme/text_input_bg.png +0 -0
- data/lib/glimr/default_theme/vscroller_bg.png +0 -0
- data/lib/glimr/event.rb +41 -0
- data/lib/glimr/eventlistener.rb +209 -0
- data/lib/glimr/layoutable.rb +520 -0
- data/lib/glimr/renderer.rb +2 -0
- data/lib/glimr/renderer/camera.rb +63 -0
- data/lib/glimr/renderer/geometry.rb +194 -0
- data/lib/glimr/renderer/glutwindow.rb +387 -0
- data/lib/glimr/renderer/light.rb +43 -0
- data/lib/glimr/renderer/material.rb +66 -0
- data/lib/glimr/renderer/model.rb +103 -0
- data/lib/glimr/renderer/orthoprojection.rb +21 -0
- data/lib/glimr/renderer/raw.rb +34 -0
- data/lib/glimr/renderer/sceneobject.rb +279 -0
- data/lib/glimr/renderer/shader.rb +14 -0
- data/lib/glimr/renderer/texture.rb +280 -0
- data/lib/glimr/renderer/transform.rb +322 -0
- data/lib/glimr/renderer/viewport.rb +349 -0
- data/lib/glimr/renderer_core.rb +10 -0
- data/lib/glimr/util.rb +247 -0
- data/lib/glimr/widget.rb +87 -0
- data/lib/glimr/widgets.rb +37 -0
- data/lib/glimr/widgets/button.rb +277 -0
- data/lib/glimr/widgets/checkbox.rb +82 -0
- data/lib/glimr/widgets/container.rb +84 -0
- data/lib/glimr/widgets/image.rb +82 -0
- data/lib/glimr/widgets/label.rb +91 -0
- data/lib/glimr/widgets/layout.rb +227 -0
- data/lib/glimr/widgets/list.rb +28 -0
- data/lib/glimr/widgets/radiogroup.rb +118 -0
- data/lib/glimr/widgets/resizer.rb +31 -0
- data/lib/glimr/widgets/scrollable_container.rb +67 -0
- data/lib/glimr/widgets/scrollbar.rb +496 -0
- data/lib/glimr/widgets/stretchable_image.rb +135 -0
- data/lib/glimr/widgets/text_editor.rb +349 -0
- data/tests/assets/datatowers_crop.jpg +0 -0
- data/tests/assets/download_progress_meter.png +0 -0
- data/tests/assets/metalwing2.png +0 -0
- data/tests/assets/redhairgreeneyes3.jpg +0 -0
- data/tests/demo_apps/spinning_ruby.rb +37 -0
- data/tests/integration_tests/run_all.rb +8 -0
- data/tests/integration_tests/test_button.rb +22 -0
- data/tests/integration_tests/test_checkbox.rb +21 -0
- data/tests/integration_tests/test_container.rb +22 -0
- data/tests/integration_tests/test_label.rb +12 -0
- data/tests/integration_tests/test_layout.rb +43 -0
- data/tests/integration_tests/test_radiogroup.rb +16 -0
- data/tests/integration_tests/test_renderer.rb +44 -0
- data/tests/integration_tests/test_renderer2.rb +36 -0
- data/tests/integration_tests/test_scrollable_container.rb +34 -0
- data/tests/integration_tests/test_scrollbar.rb +20 -0
- data/tests/integration_tests/test_stretchable_image.rb +34 -0
- data/tests/integration_tests/test_text_input.rb +20 -0
- data/tests/integration_tests/test_zsort.rb +18 -0
- data/tests/unit_tests/test_button.rb +93 -0
- data/tests/unit_tests/test_checkbox.rb +35 -0
- data/tests/unit_tests/test_label.rb +36 -0
- data/tests/unit_tests/test_layout.rb +229 -0
- data/tests/unit_tests/test_widget.rb +3 -0
- metadata +139 -0
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'glimr/renderer/sceneobject'
|
2
|
+
|
3
|
+
|
4
|
+
module GlimR
|
5
|
+
|
6
|
+
|
7
|
+
class Light < SceneObject
|
8
|
+
|
9
|
+
LIGHTS = GL::constants.grep(/^LIGHT[0-9]+/).map{|l| GL.const_get l }
|
10
|
+
|
11
|
+
def self.reserve_light_id
|
12
|
+
@index ||= 0
|
13
|
+
return false if LIGHTS.size <= @index
|
14
|
+
l = LIGHTS[@index]
|
15
|
+
@index += 1
|
16
|
+
l
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.reset_lights
|
20
|
+
@index = 0
|
21
|
+
LIGHTS.each{|l| Disable(l) }
|
22
|
+
end
|
23
|
+
|
24
|
+
attr_accessor :position, :diffuse, :specular, :ambient
|
25
|
+
attr_accessor :constant_attenuation, :linear_attenuation, :quadratic_attenuation
|
26
|
+
|
27
|
+
def setup
|
28
|
+
light_id = self.class.reserve_light_id
|
29
|
+
return unless light_id
|
30
|
+
Enable(light_id)
|
31
|
+
Lightfv(light_id, POSITION, position ) if position
|
32
|
+
Lightfv(light_id, DIFFUSE, diffuse ) if diffuse
|
33
|
+
Lightfv( light_id, SPECULAR, specular ) if specular
|
34
|
+
Lightfv( light_id, AMBIENT, ambient ) if ambient
|
35
|
+
Lightf( light_id, CONSTANT_ATTENUATION, constant_attenuation) if constant_attenuation
|
36
|
+
Lightf( light_id, LINEAR_ATTENUATION, linear_attenuation) if linear_attenuation
|
37
|
+
Lightf( light_id, QUADRATIC_ATTENUATION, quadratic_attenuation) if quadratic_attenuation
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'glimr/renderer/sceneobject'
|
2
|
+
|
3
|
+
|
4
|
+
module GlimR
|
5
|
+
|
6
|
+
|
7
|
+
# A Material node controls OpenGL surface material parameters.
|
8
|
+
# It has accessors for ambient, diffuse, specular, shininess and emission.
|
9
|
+
#
|
10
|
+
# Look up glMaterial and Blinn-Phong shading to find out more.
|
11
|
+
#
|
12
|
+
class Material < SceneObject
|
13
|
+
|
14
|
+
touching_accessor :ambient, :diffuse, :specular, :shininess, :emission
|
15
|
+
|
16
|
+
# The absolute material of a Material is the parent's absolute material
|
17
|
+
# merged with the Material.
|
18
|
+
def absolute_material
|
19
|
+
@__pama ||= (
|
20
|
+
pam = parent.absolute_material
|
21
|
+
pam.ambient = ambient if ambient
|
22
|
+
pam.diffuse = diffuse if diffuse
|
23
|
+
pam.specular = specular if specular
|
24
|
+
pam.shininess = shininess if shininess
|
25
|
+
pam.emission = emission if emission
|
26
|
+
pam
|
27
|
+
)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Applies the material by calling GL::Material to set the material properties.
|
31
|
+
def apply
|
32
|
+
Material(FRONT_AND_BACK, AMBIENT, ambient) if ambient
|
33
|
+
Material(FRONT_AND_BACK, DIFFUSE, diffuse) if diffuse
|
34
|
+
Material(FRONT_AND_BACK, SPECULAR, specular) if specular
|
35
|
+
Material(FRONT_AND_BACK, SHININESS, shininess) if shininess
|
36
|
+
Material(FRONT_AND_BACK, EMISSION, emission) if emission
|
37
|
+
end
|
38
|
+
|
39
|
+
# Pushes the LIGHTING_BIT to attrib stack.
|
40
|
+
def push_state
|
41
|
+
PushAttrib(LIGHTING_BIT)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Pops the attrib stack.
|
45
|
+
def pop_state
|
46
|
+
PopAttrib()
|
47
|
+
end
|
48
|
+
|
49
|
+
# Replaces the instance variables of the Material with
|
50
|
+
# the other's.
|
51
|
+
def replace!(other)
|
52
|
+
@ambient = other.ambient
|
53
|
+
@diffuse = other.diffuse
|
54
|
+
@specular = other.specular
|
55
|
+
@shininess = other.shininess
|
56
|
+
@emission = other.emission
|
57
|
+
self
|
58
|
+
end
|
59
|
+
|
60
|
+
touching :touch!, :replace!
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
end
|
66
|
+
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'glimr/renderer/sceneobject'
|
2
|
+
require 'glimr/renderer/transform'
|
3
|
+
require 'glimr/renderer/texture'
|
4
|
+
require 'glimr/renderer/geometry'
|
5
|
+
require 'glimr/renderer/material'
|
6
|
+
require 'glimr/renderer/shader'
|
7
|
+
|
8
|
+
|
9
|
+
module GlimR
|
10
|
+
|
11
|
+
# A Model is a convenience SceneObject that
|
12
|
+
# has its own transform, material, texture, shader, and geometry.
|
13
|
+
#
|
14
|
+
# The state nodes are attached to the Model after super initialization
|
15
|
+
# and form a five-node subtree ordered like this (from top to bottom):
|
16
|
+
# transform - material - texture - shader - geometry.
|
17
|
+
#
|
18
|
+
# Model delegates many accessors to the corresponding state nodes
|
19
|
+
#
|
20
|
+
# Example:
|
21
|
+
# m = Model.new
|
22
|
+
# m.texture.load('foo.jpg')
|
23
|
+
# m.position = [10, 20, 30]
|
24
|
+
# m.texcoords = make texcoords
|
25
|
+
# m.vertices = make vertices
|
26
|
+
#
|
27
|
+
class Model < SceneObject
|
28
|
+
|
29
|
+
attr_reader :texture, :geometry, :transform, :material, :shader
|
30
|
+
|
31
|
+
delegate_accessor :geometry, :type, :vertices, :texcoords, :colors, :normals
|
32
|
+
delegate_accessor :transform, :position, :rotation, :scale, :matrix, :x, :y, :z, :angle
|
33
|
+
delegate_accessor :material, :ambient, :diffuse, :specular, :shininess, :emission
|
34
|
+
|
35
|
+
def initialize(*a,&b)
|
36
|
+
@transform = Transform.new
|
37
|
+
@material = Material.new
|
38
|
+
@texture = Texture.new
|
39
|
+
@shader = Shader.new
|
40
|
+
@geometry = Geometry.new
|
41
|
+
super
|
42
|
+
attach @material
|
43
|
+
@material.attach @texture
|
44
|
+
@texture.attach @shader
|
45
|
+
@shader.attach @geometry
|
46
|
+
end
|
47
|
+
|
48
|
+
def push_state
|
49
|
+
@transform.push_state
|
50
|
+
super
|
51
|
+
end
|
52
|
+
|
53
|
+
def pop_state
|
54
|
+
@transform.pop_state
|
55
|
+
super
|
56
|
+
end
|
57
|
+
|
58
|
+
def apply
|
59
|
+
@transform.apply
|
60
|
+
super
|
61
|
+
end
|
62
|
+
|
63
|
+
def absolute_transform
|
64
|
+
@transform.instance_variable_set :@parent , @parent
|
65
|
+
@transform.absolute_transform
|
66
|
+
end
|
67
|
+
|
68
|
+
# Replaces transform with t using Transform#replace!
|
69
|
+
# If t is a matrix, creates a Transform with t as the collapsed matrix.
|
70
|
+
def transform= t
|
71
|
+
unless t.is_a? Transform
|
72
|
+
t = Transform.new(:collapsed_matrix => t, :position => nil, :rotation => nil, :scale => nil, :matrix => nil)
|
73
|
+
end
|
74
|
+
@transform.replace! t
|
75
|
+
end
|
76
|
+
|
77
|
+
# Replaces texture with t. Uses Texture#replace!
|
78
|
+
def texture= t
|
79
|
+
@texture.replace! t
|
80
|
+
end
|
81
|
+
|
82
|
+
# Replaces geometry with g using Geometry#replace!
|
83
|
+
def geometry= g
|
84
|
+
@geometry.replace! g
|
85
|
+
end
|
86
|
+
|
87
|
+
# Replaces material with m using Material#replace!
|
88
|
+
def material= m
|
89
|
+
@material.replace! m
|
90
|
+
end
|
91
|
+
|
92
|
+
# Replaces shader with s using Shader#replace!
|
93
|
+
def shader= s
|
94
|
+
@shader.replace! s
|
95
|
+
end
|
96
|
+
|
97
|
+
def inspect
|
98
|
+
super[0..-2] + "::#{ [@transform, @material, @texture, @shader, @geometry].map{|i|i.inspect[9..-2]}.join("::") }>"
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'glimr/renderer/sceneobject'
|
2
|
+
|
3
|
+
|
4
|
+
module GlimR
|
5
|
+
|
6
|
+
class OrthoProjection < SceneObject
|
7
|
+
|
8
|
+
attr_accessor :width, :height, :x, :y, :near, :far
|
9
|
+
|
10
|
+
def apply(x=x, y=y, width=width, height=height)
|
11
|
+
MatrixMode(PROJECTION)
|
12
|
+
LoadIdentity()
|
13
|
+
Ortho(x,width, y,height, near,far)
|
14
|
+
MatrixMode(MODELVIEW)
|
15
|
+
LoadIdentity()
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'glimr/renderer/sceneobject'
|
2
|
+
|
3
|
+
|
4
|
+
module GlimR
|
5
|
+
|
6
|
+
|
7
|
+
# Raw is a SceneObject that calls its #renderer
|
8
|
+
# when applied.
|
9
|
+
#
|
10
|
+
# Use for doing custom OpenGL calls and such.
|
11
|
+
#
|
12
|
+
# Raw doesn't work with the Viewport's collapsing #render,
|
13
|
+
# so is pretty much useless at the moment.
|
14
|
+
#
|
15
|
+
# Example:
|
16
|
+
#
|
17
|
+
# r = Raw.new
|
18
|
+
# r.renderer = lambda do
|
19
|
+
# puts 'Hi, I was just applied!'
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
class Raw < SceneObject
|
23
|
+
|
24
|
+
attr_accessor :renderer
|
25
|
+
|
26
|
+
# Calls #renderer if renderer is set.
|
27
|
+
def apply
|
28
|
+
renderer.call if renderer
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,279 @@
|
|
1
|
+
require 'glimr/eventlistener'
|
2
|
+
require 'glimr/util'
|
3
|
+
require 'opengl'
|
4
|
+
require 'set'
|
5
|
+
|
6
|
+
|
7
|
+
module GlimR
|
8
|
+
|
9
|
+
|
10
|
+
# The SceneObject is the root class of the GlimR scene graph class hierarchy.
|
11
|
+
#
|
12
|
+
# A SceneObject may have a parent and children, and usually will.
|
13
|
+
# All actual OpenGL state manipulation should be done with its
|
14
|
+
# specific subclasses like Transform, Geometry and Texture.
|
15
|
+
#
|
16
|
+
# The SceneObject is an EventListener, and as such you can tell
|
17
|
+
# it to listen and respond to events.
|
18
|
+
#
|
19
|
+
# SceneObjects also maintain a list of drawable objects underneath them.
|
20
|
+
# This is mainly used to speed up rendering by removing the need to traverse
|
21
|
+
# the whole scene graph to draw the scene.
|
22
|
+
#
|
23
|
+
# Example:
|
24
|
+
# s = SceneObject.new
|
25
|
+
# t = Texture.new
|
26
|
+
# s.attach t
|
27
|
+
# s.detach t
|
28
|
+
#
|
29
|
+
class SceneObject
|
30
|
+
include GL
|
31
|
+
include EventListener
|
32
|
+
include Configurable
|
33
|
+
|
34
|
+
attr_accessor :parent, :children, :viewport, :drawables
|
35
|
+
attr_reader :mtime
|
36
|
+
touching_accessor :visible
|
37
|
+
|
38
|
+
def default_config
|
39
|
+
super.merge(
|
40
|
+
:visible => true,
|
41
|
+
:mtime => Time.now.to_f
|
42
|
+
)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Configurable initialize.
|
46
|
+
def initialize(*arg_hash, &config_block)
|
47
|
+
@children = []
|
48
|
+
@drawables = Set.new
|
49
|
+
super
|
50
|
+
end
|
51
|
+
|
52
|
+
# Returns the viewport or possible parent's viewport.
|
53
|
+
def viewport
|
54
|
+
@viewport ||= (parent and parent.viewport)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Returns the scene root.
|
58
|
+
# This is either the viewport,
|
59
|
+
# the parent's scene root if there is no viewport,
|
60
|
+
# or self if there is no parent.
|
61
|
+
#
|
62
|
+
def root
|
63
|
+
(viewport || (parent ? parent.root : self))
|
64
|
+
end
|
65
|
+
|
66
|
+
# Sets viewport to vp.
|
67
|
+
# Passes viewport change to children.
|
68
|
+
#
|
69
|
+
def viewport= vp
|
70
|
+
if vp != @viewport
|
71
|
+
@viewport = vp
|
72
|
+
children.each{|c| c.viewport = vp}
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# Attaches new_children to the scene graph below self.
|
77
|
+
def attach(*new_children)
|
78
|
+
new_children.each{|c|
|
79
|
+
adopt(c)
|
80
|
+
}
|
81
|
+
end
|
82
|
+
|
83
|
+
# Attach single child.
|
84
|
+
def <<(new_child)
|
85
|
+
attach new_child
|
86
|
+
self
|
87
|
+
end
|
88
|
+
|
89
|
+
# Detaches children_to_detach from self.
|
90
|
+
def detach(*children_to_detach)
|
91
|
+
children_to_detach.each{|c|
|
92
|
+
orphan(c)
|
93
|
+
}
|
94
|
+
end
|
95
|
+
|
96
|
+
# Detaches self from parent if there is a parent.
|
97
|
+
def detach_self
|
98
|
+
parent.detach(self) if parent
|
99
|
+
end
|
100
|
+
|
101
|
+
# Sets parent to p.
|
102
|
+
#
|
103
|
+
# Causes viewport to be set to nil and drawables to
|
104
|
+
# be added to parent's drawables.
|
105
|
+
def parent= new_parent
|
106
|
+
#~ if @parent
|
107
|
+
#~ puts object_id, "reparenting #{self} from #{@parent} to #{new_parent.inspect}"
|
108
|
+
#~ d = @parent
|
109
|
+
#~ end
|
110
|
+
@parent.remove_drawables drawables if @parent
|
111
|
+
@parent = new_parent
|
112
|
+
self.viewport = nil
|
113
|
+
@parent.add_drawables drawables if @parent
|
114
|
+
#~ p [:after, d.drawables] if d
|
115
|
+
#~ puts '','' if d
|
116
|
+
end
|
117
|
+
|
118
|
+
# A node is visible if its @visible is true and its parent is visible (if it has a parent.)
|
119
|
+
def visible
|
120
|
+
@visible and (parent ? parent.visible : true)
|
121
|
+
end
|
122
|
+
|
123
|
+
# Adds d to drawables and parent's drawables.
|
124
|
+
def add_drawables(d)
|
125
|
+
parent.add_drawables d if parent
|
126
|
+
@drawables += d
|
127
|
+
end
|
128
|
+
|
129
|
+
# Removes d from drawables and parent's drawables.
|
130
|
+
def remove_drawables(d)
|
131
|
+
parent.remove_drawables d if parent
|
132
|
+
@drawables -= d
|
133
|
+
end
|
134
|
+
|
135
|
+
# Sets drawables to d and updates parent's drawables.
|
136
|
+
def drawables= d
|
137
|
+
if (d != @drawables) and parent
|
138
|
+
parent.drawables = ((parent.drawables - @drawables) + d)
|
139
|
+
end
|
140
|
+
@drawables = d
|
141
|
+
end
|
142
|
+
|
143
|
+
# Replaces orig node in scene graph with replacement by
|
144
|
+
# Attaching the replacement to orig's parent, and attaching
|
145
|
+
# orig's children to replacement.
|
146
|
+
#
|
147
|
+
# If no replacement is given, removes orig from scenegraph
|
148
|
+
# and attaches its children to its parent. If there is no parent or
|
149
|
+
# replacement, does nothing.
|
150
|
+
#
|
151
|
+
def replace_node(orig, replacement=nil)
|
152
|
+
return unless orig
|
153
|
+
replacement ||= orig.parent
|
154
|
+
return unless replacement
|
155
|
+
replacement.detach(*orig.children)
|
156
|
+
replacement.attach(*orig.children)
|
157
|
+
orig.detach(*orig.children)
|
158
|
+
orig.parent.attach(replacement) if orig.parent
|
159
|
+
orig.detach_self
|
160
|
+
end
|
161
|
+
|
162
|
+
# Renders the SceneObject by pushing state, applying, calling render
|
163
|
+
# for each child, and popping state.
|
164
|
+
#
|
165
|
+
# Not used with collapsing Viewport #render.
|
166
|
+
def render(*a)
|
167
|
+
push_state
|
168
|
+
apply
|
169
|
+
children.each{|c| c.render if c.visible }
|
170
|
+
pop_state
|
171
|
+
end
|
172
|
+
|
173
|
+
# The collapsed state of a SceneObject is its parent's collapsed state,
|
174
|
+
# which fits in with SceneObjects not editing OpenGL state.
|
175
|
+
def absolute_transform
|
176
|
+
parent.absolute_transform
|
177
|
+
end
|
178
|
+
|
179
|
+
def absolute_transform_for_drawing
|
180
|
+
absolute_transform
|
181
|
+
end
|
182
|
+
|
183
|
+
def absolute_material
|
184
|
+
#~ unless parent
|
185
|
+
#~ puts object_id, geometry.object_id, self, geometry
|
186
|
+
#~ ObjectSpace.each_object(Button){|b|
|
187
|
+
#~ if b.drawables.include? geometry
|
188
|
+
#~ puts b
|
189
|
+
#~ p b.drawables.to_a, b.children
|
190
|
+
#~ puts
|
191
|
+
#~ puts
|
192
|
+
#~ cc = b.children.find{|c|
|
193
|
+
#~ c.geometry == geometry if c.is_a? Model
|
194
|
+
#~ }
|
195
|
+
#~ p cc
|
196
|
+
#~ end
|
197
|
+
#~ }
|
198
|
+
#~ end
|
199
|
+
parent.absolute_material
|
200
|
+
end
|
201
|
+
|
202
|
+
def absolute_texture
|
203
|
+
parent.absolute_texture
|
204
|
+
end
|
205
|
+
|
206
|
+
def absolute_geometry
|
207
|
+
parent.absolute_geometry
|
208
|
+
end
|
209
|
+
|
210
|
+
def absolute_shader
|
211
|
+
parent.absolute_shader
|
212
|
+
end
|
213
|
+
|
214
|
+
# Applies the SceneObject to OpenGL state.
|
215
|
+
# For SceneObject, this is empty.
|
216
|
+
def apply
|
217
|
+
end
|
218
|
+
|
219
|
+
# Pushes the relevant OpenGL state stack.
|
220
|
+
# Empty for SceneObject.
|
221
|
+
def push_state
|
222
|
+
end
|
223
|
+
|
224
|
+
# Pops the relevant OpenGL state stack.
|
225
|
+
# Empty for SceneObject.
|
226
|
+
def pop_state
|
227
|
+
end
|
228
|
+
|
229
|
+
# Creates a clone of the SceneObject.
|
230
|
+
# If deep is set to true, also clones the children.
|
231
|
+
# If deep is false, clears children.
|
232
|
+
#
|
233
|
+
def clone(deep=false)
|
234
|
+
c = super()
|
235
|
+
if deep
|
236
|
+
c.children = []
|
237
|
+
c.drawables.clear
|
238
|
+
cchildren = c.children.map{|ch| ch.clone(deep) }
|
239
|
+
c.attach *cchildren
|
240
|
+
else
|
241
|
+
c.children = []
|
242
|
+
c.drawables.clear
|
243
|
+
end
|
244
|
+
c.parent = nil
|
245
|
+
c
|
246
|
+
end
|
247
|
+
|
248
|
+
def inspect
|
249
|
+
"#<#{self.class.name}:#{object_id}>"
|
250
|
+
end
|
251
|
+
|
252
|
+
def touch!(mtime=Time.now.to_f)
|
253
|
+
@mtime = mtime
|
254
|
+
parent.touch!(@mtime) if parent
|
255
|
+
nil
|
256
|
+
end
|
257
|
+
|
258
|
+
private
|
259
|
+
|
260
|
+
def adopt(c)
|
261
|
+
children.push c
|
262
|
+
c.parent = self
|
263
|
+
c.listener_count.each{|k,v| increment_listener_count k, v }
|
264
|
+
touch!
|
265
|
+
end
|
266
|
+
|
267
|
+
def orphan(c)
|
268
|
+
if children.include? c
|
269
|
+
children.delete c
|
270
|
+
c.parent = nil
|
271
|
+
c.listener_count.each{|k,v| decrement_listener_count k, v }
|
272
|
+
touch!
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
end
|
277
|
+
|
278
|
+
|
279
|
+
end
|