Class: GlimR::Transform

Inherits:
SceneObject show all
Defined in:
lib/glimr/renderer/transform.rb

Overview

Transform is a SceneObject that handles OpenGL transformations.

It has a rotation, scale, position and matrix, These are applied in the following order: first translate, then scale, then rotate, then multiply by matrix.

Direct Known Subclasses

Camera

Instance Attribute Summary collapse

Attributes inherited from SceneObject

#children, #drawables, #mtime, #parent, #viewport

Attributes included from EventListener

#event_listeners, #listener_count

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from SceneObject

#<<, #absolute_geometry, #absolute_material, #absolute_shader, #absolute_texture, #absolute_transform_for_drawing, #add_drawables, #attach, #detach, #detach_self, #initialize, #remove_drawables, #render, #replace_node, #root, #visible

Methods included from Configurable

#initialize

Methods included from EventListener

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

Constructor Details

This class inherits a constructor from GlimR::SceneObject

Dynamic Method Handling

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

Instance Attribute Details

#collapsed_matrixObject

Returns the value of attribute collapsed_matrix.



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

def collapsed_matrix
  @collapsed_matrix
end

#matrixObject

Returns the value of attribute matrix.



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

def matrix
  @matrix
end

#positionObject

Returns the value of attribute position.



37
38
39
# File 'lib/glimr/renderer/transform.rb', line 37

def position
  @position
end

#rotationObject

Returns the value of attribute rotation.



37
38
39
# File 'lib/glimr/renderer/transform.rb', line 37

def rotation
  @rotation
end

#scaleObject

Returns the value of attribute scale.



37
38
39
# File 'lib/glimr/renderer/transform.rb', line 37

def scale
  @scale
end

Class Method Details

.rotate(r) ⇒ Object

Creates a new Transform with rotation set to r.



54
55
56
57
58
# File 'lib/glimr/renderer/transform.rb', line 54

def self.rotate(r)
  t = new
  t.rotation = r
  t
end

.rotate_aa(angle_deg, x = 0, y = 0, z = 1) ⇒ Object

Creates a new rotation Transform based on the given angle-axis rotation.



61
62
63
# File 'lib/glimr/renderer/transform.rb', line 61

def self.rotate_aa(angle_deg, x=0,y=0,z=1)
  rotate AngleAxis[angle_deg,x,y,z]
end

.rotate_quat(w, x, y, z) ⇒ Object

Creates a new rotation Transform based on the given quaternion rotation.



66
67
68
# File 'lib/glimr/renderer/transform.rb', line 66

def self.rotate_quat(w,x,y,z)
  rotate Quaternion[w,x,y,z]
end

.scale(x, y = x, z = x) ⇒ Object

Creates a new Transform with scale set to [x,y,z].



47
48
49
50
51
# File 'lib/glimr/renderer/transform.rb', line 47

def self.scale(x,y=x,z=x)
  t = new
  t.scale = [x,y,z]
  t
end

.translate(x, y = x, z = 0) ⇒ Object

Creates a new Transform with position set to [x,y,z].



40
41
42
43
44
# File 'lib/glimr/renderer/transform.rb', line 40

def self.translate(x,y=x,z=0)
  t = new
  t.position = [x,y,z]
  t
end

Instance Method Details

#===(t) ⇒ Object

Compares two transformations by their transformations.



195
196
197
198
# File 'lib/glimr/renderer/transform.rb', line 195

def ===(t)
  return super unless t.is_a?(Transform)
  matrix == t.matrix and position == t.position and scale == t.scale and rotation == t.rotation
end

#absolute_transformObject

The absolute transform for a Transform is the parent’s absolute transform multiplied with the current transform’s collapsed matrix.



201
202
203
204
205
206
207
208
209
210
211
212
213
# File 'lib/glimr/renderer/transform.rb', line 201

def absolute_transform
  return parent.absolute_transform unless (@position or @scale or @rotation or @matrix or @collapsed_matrix)
  collapse! unless @collapsed_matrix
  if not (@absolute_transform and @parent_absolute_transform == (parent and (parent.absolute_transform)))
    @parent_absolute_transform = (parent and (parent.absolute_transform))
    PushMatrix()
      LoadMatrix(@parent_absolute_transform) if @parent_absolute_transform
      MultMatrix(@collapsed_matrix)
      @absolute_transform = GetDoublev(MODELVIEW_MATRIX)
    PopMatrix()
  end
  @absolute_transform
end

#angleObject



132
133
134
# File 'lib/glimr/renderer/transform.rb', line 132

def angle
  @rotation.to_aa[0]
end

#angle=(a) ⇒ Object



136
137
138
# File 'lib/glimr/renderer/transform.rb', line 136

def angle= a
  self.rotation = a
end

#applyObject

Applies the Transform to the current OpenGL transform matrix.



167
168
169
170
171
172
173
# File 'lib/glimr/renderer/transform.rb', line 167

def apply
  if @collapsed_matrix
    MultMatrix(@collapsed_matrix)
  else
    gl_transform
  end
end

#clone(*a) ⇒ Object

Clones instance variables as well.



222
223
224
225
226
227
228
229
230
# File 'lib/glimr/renderer/transform.rb', line 222

def clone(*a)
  c = super
  c.instance_variable_set(:@position, @position.clone) if @position
  c.instance_variable_set(:@scale, @scale.clone) if @scale
  c.instance_variable_set(:@rotation, @rotation.clone) if @rotation
  c.instance_variable_set(:@matrix, @matrix.clone) if @matrix
  c.instance_variable_set(:@collapsed_matrix, @collapsed_matrix.clone) if @collapsed_matrix
  c
end

#collapse!Object

Collapses the transform into a single transform matrix and returns it.



176
177
178
179
180
181
182
183
184
# File 'lib/glimr/renderer/transform.rb', line 176

def collapse!
  PushMatrix()
    LoadIdentity()
    gl_transform
    @collapsed_matrix = GetDoublev(MODELVIEW_MATRIX).flatten
  PopMatrix()
  @absolute_transform = false
  @collapsed_matrix
end

#default_configObject



70
71
72
73
74
75
76
77
# File 'lib/glimr/renderer/transform.rb', line 70

def default_config
  super.merge(
    :position => [0,0,0],
    :rotation => AngleAxis[0,0,0,1],
    :scale => [1,1,1],
    :changed => true
  )
end

#gl_transformObject

Apply position, scale, rotation and matrix to OpenGL state.



187
188
189
190
191
192
# File 'lib/glimr/renderer/transform.rb', line 187

def gl_transform
  Translate(*position) if @position
  Scale(*scale) if @scale
  Rotate(*rotation) if @rotation
  MultMatrix(*matrix) if @matrix
end

#inspectObject



246
247
248
# File 'lib/glimr/renderer/transform.rb', line 246

def inspect
  "#<#{self.class.name}:#{hash}:POS#@position:ROT#@rotation:SCA#@scale:MAT#@matrix>"
end

#pop_stateObject

Pops OpenGL matrix stack.



162
163
164
# File 'lib/glimr/renderer/transform.rb', line 162

def pop_state
  PopMatrix()
end

#push_stateObject

Pushes the OpenGL matrix stack.



157
158
159
# File 'lib/glimr/renderer/transform.rb', line 157

def push_state
  PushMatrix()
end

#replace!(other) ⇒ Object

Replaces ivars with the other’s.



233
234
235
236
237
238
239
240
241
242
# File 'lib/glimr/renderer/transform.rb', line 233

def replace!(other)
  @position = other.position
  @scale = other.scale
  @rotation = other.rotation
  @matrix = other.matrix
  @collapsed_matrix = other.collapsed_matrix
  @absolute_transform = other.instance_variable_get(:@absolute_transform)
  @parent_absolute_transform = other.instance_variable_get(:@parent_absolute_transform)
  self
end

#touch!(*a) ⇒ Object

Clears collapsed matrix.



216
217
218
219
# File 'lib/glimr/renderer/transform.rb', line 216

def touch!(*a)
  super
  @collapsed_matrix = false
end

#translate(x, y = 0, z = 0) ⇒ Object

Adds the given coordinates to position.



141
142
143
144
145
# File 'lib/glimr/renderer/transform.rb', line 141

def translate(x,y=0,z=0)
  tl = [x,y,z]
  tl = x if x.is_a? Array
  self.position = @position.zip(tl).map{|a,b| a+b}
end

#xObject



108
109
110
# File 'lib/glimr/renderer/transform.rb', line 108

def x
  @position[0]
end

#x=(nx) ⇒ Object



120
121
122
# File 'lib/glimr/renderer/transform.rb', line 120

def x= nx
  @position[0] = nx
end

#yObject



112
113
114
# File 'lib/glimr/renderer/transform.rb', line 112

def y
  @position[1]
end

#y=(ny) ⇒ Object



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

def y= ny
  @position[1] = ny
end

#zObject



116
117
118
# File 'lib/glimr/renderer/transform.rb', line 116

def z
  @position[2]
end

#z=(nz) ⇒ Object



128
129
130
# File 'lib/glimr/renderer/transform.rb', line 128

def z= nz
  @position[2] = nz
end