Class: RAGE::Mesh
- Inherits:
-
Object
- Object
- RAGE::Mesh
- Defined in:
- lib/rage/mesh.rb
Overview
3D mesh to be displayed on the screen. Contains geometry and visual properties. Currently implements certain parts of the X3D graphics schema. en.wikipedia.org/wiki/X3D
Instance Attribute Summary collapse
-
#op_rotation ⇒ Object
Optional transformation params, set these to transformations to be factored in if needed.
-
#op_scale ⇒ Object
Optional transformation params, set these to transformations to be factored in if needed.
-
#op_translation ⇒ Object
Optional transformation params, set these to transformations to be factored in if needed.
Instance Method Summary collapse
-
#boundaries ⇒ Object
Return mesh boundaries.
-
#center ⇒ Object
Return center point of mesh from mesh translation provided in mesh and op_translation.
-
#coordinates ⇒ Object
Return current location coordinates associated w/ the mesh.
-
#draw ⇒ Object
Invoked during draw cycle to draw mesh.
-
#initialize(data) ⇒ Mesh
constructor
Create new mesh from raw X3D mesh.
-
#scale ⇒ Object
Return factor which mesh should scale to.
-
#show_at(args = {}) ⇒ Object
Create location w/ specified args, associated mesh w/ it and add it to the LocationsManager.
Constructor Details
#initialize(data) ⇒ Mesh
Create new mesh from raw X3D mesh
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/rage/mesh.rb', line 30 def initialize(data) # set default attributes @op_translation = [0,0,0] @op_scale = [1,1,1] # load the x3d xsd schema and classes if not already done so unless defined? @@x3d_schema @@x3d_schema = RXSD::Parser.parse_xsd :uri => 'http://www.web3d.org/specifications/x3d-3.0.xsd' # TODO allow location which this is pulled from to be configured @@x3d_schema_classes = @@x3d_schema.to :ruby_classes end # load the scene from the x3d schema instance objs = RXSD::Parser.parse_xml(:raw => data).to(:ruby_objects, :schema => @@x3d_schema) @scene = objs[0].scene # FIXME get all transformations (and groups of) under scene @tf = @scene.collision.transform @translation = @tf.translation.to_xa :type => XSDFloat @scale = @tf.scale.to_xa :type => XSDFloat #diffuse = tf.shape.appearance.material.diffuse_color.split.collect { |c| c.to_f } #specular = tf.shape.appearance.material.specular_color.split.collect { |c| c.to_f } #emissive = tf.shape.appearance.material.emissive_color.split.collect { |c| c.to_f } @coord_index = @tf.shape.indexed_face_set.coord_index. to_xa(:type => String, :delim => ","). collect { |coords| a = coords.to_xa(:type => XSDInteger); a[0...a.size-1]}.flatten # cut off the last -1 @coord_point = @tf.shape.indexed_face_set.coordinate.point. to_xa(:type => String, :delim => ","). collect { |coords| coords.to_xa :type => XSDFloat }.flatten end |
Instance Attribute Details
#op_rotation ⇒ Object
Optional transformation params, set these to transformations to be factored in if needed
20 21 22 |
# File 'lib/rage/mesh.rb', line 20 def op_rotation @op_rotation end |
#op_scale ⇒ Object
Optional transformation params, set these to transformations to be factored in if needed
20 21 22 |
# File 'lib/rage/mesh.rb', line 20 def op_scale @op_scale end |
#op_translation ⇒ Object
Optional transformation params, set these to transformations to be factored in if needed
20 21 22 |
# File 'lib/rage/mesh.rb', line 20 def op_translation @op_translation end |
Instance Method Details
#boundaries ⇒ Object
Return mesh boundaries. This is generated by determining the maxima/minima coordinate points. Return value is an array of six values as follows
max_x, max_y, max_z, min_x, min_y, min_z
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/rage/mesh.rb', line 98 def boundaries centerx, centery, centerz = *center max_x = max_y = max_z = min_x = min_y = min_z = 0 @coord_point.each_index { |cpi| if cpi % 3 == 0 adjx = centerx + @coord_point[cpi] if adjx > max_x max_x = adjx elsif adjx < min_x min_x = adjx end elsif cpi % 3 == 1 adjy = centery + @coord_point[cpi] if adjy > max_y max_y = adjy elsif adjy < min_y min_y = adjy end else adjz = centerz + @coord_point[cpi] if adjz > max_z max_z = adjz elsif adjz < min_z min_z = adjz end end } return max_x, max_y, max_z, min_x, min_y, min_z end |
#center ⇒ Object
Return center point of mesh from mesh translation provided in mesh and op_translation
82 83 84 85 86 |
# File 'lib/rage/mesh.rb', line 82 def center return @op_translation[0] + @translation[0], @op_translation[1] + @translation[1], @op_translation[2] + @translation[2] end |
#coordinates ⇒ Object
Return current location coordinates associated w/ the mesh
75 76 77 |
# File 'lib/rage/mesh.rb', line 75 def coordinates [@location.x, @location.y, @location.z] end |
#draw ⇒ Object
Invoked during draw cycle to draw mesh
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/rage/mesh.rb', line 130 def draw # FIXME mesh material #Gl.glMaterial(Gl::GL_FRONT, Gl::GL_DIFFUSE, diffuse) #Gl.glMaterial(Gl::GL_FRONT, Gl::GL_SPECULAR, specular) #Gl.glMaterial(Gl::GL_FRONT, Gl::GL_EMISSIVE, emissive) # translate coordinate system to center position of mesh Gl.glTranslatef(*center) # scale as specified Gl.glScalef(*scale) # FIXME rotate according to mesh and optional params # draw mesh Gl.glEnableClientState(Gl::GL_VERTEX_ARRAY); Gl.glVertexPointer(3, Gl::GL_FLOAT, 0, @coord_point); Gl.glDrawElements(Gl::GL_QUADS, @coord_index.size, Gl::GL_UNSIGNED_INT, @coord_index); Gl.glDisableClientState(Gl::GL_VERTEX_ARRAY); end |
#scale ⇒ Object
Return factor which mesh should scale to
89 90 91 92 93 |
# File 'lib/rage/mesh.rb', line 89 def scale return @scale[0] * @op_scale[0], @scale[1] * @op_scale[1], @scale[2] * @op_scale[2] end |
#show_at(args = {}) ⇒ Object
Create location w/ specified args, associated mesh w/ it and add it to the LocationsManager
61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/rage/mesh.rb', line 61 def show_at(args = {}) # XXX not a huge fan of storing location interally, # but this is best way to do this for now if ! defined? @location args[:mesh] = self @location = Location.new(args) LocationsManager.instance.add @location else @location.update args end return @location end |