Class: ObjParser::Obj
- Inherits:
-
Object
- Object
- ObjParser::Obj
- Defined in:
- lib/obj_parser/obj.rb
Constant Summary collapse
- VERTEX_BY_FACE =
3
Instance Attribute Summary collapse
-
#faces ⇒ Object
Returns the value of attribute faces.
-
#normals ⇒ Object
Returns the value of attribute normals.
-
#normals_indexes ⇒ Object
Returns the value of attribute normals_indexes.
-
#tangents ⇒ Object
Returns the value of attribute tangents.
-
#tangents_indexes ⇒ Object
Returns the value of attribute tangents_indexes.
-
#textures ⇒ Object
Returns the value of attribute textures.
-
#textures_indexes ⇒ Object
Returns the value of attribute textures_indexes.
-
#vertice ⇒ Object
Returns the value of attribute vertice.
-
#vertice_indexes ⇒ Object
Returns the value of attribute vertice_indexes.
Instance Method Summary collapse
- #compute_tangents ⇒ Object
-
#initialize ⇒ Obj
constructor
A new instance of Obj.
- #resolve_faces ⇒ Object
- #tangents_self_check ⇒ Object
Constructor Details
#initialize ⇒ Obj
Returns a new instance of Obj.
13 14 15 16 17 18 19 20 21 22 |
# File 'lib/obj_parser/obj.rb', line 13 def initialize self.vertice = [] self.normals = [] self.textures = [] self.tangents = [] self.vertice_indexes = [] self.normals_indexes = [] self.textures_indexes = [] self.tangents_indexes = [] end |
Instance Attribute Details
#faces ⇒ Object
Returns the value of attribute faces.
11 12 13 |
# File 'lib/obj_parser/obj.rb', line 11 def faces @faces end |
#normals ⇒ Object
Returns the value of attribute normals.
7 8 9 |
# File 'lib/obj_parser/obj.rb', line 7 def normals @normals end |
#normals_indexes ⇒ Object
Returns the value of attribute normals_indexes.
7 8 9 |
# File 'lib/obj_parser/obj.rb', line 7 def normals_indexes @normals_indexes end |
#tangents ⇒ Object
Returns the value of attribute tangents.
10 11 12 |
# File 'lib/obj_parser/obj.rb', line 10 def tangents @tangents end |
#tangents_indexes ⇒ Object
Returns the value of attribute tangents_indexes.
10 11 12 |
# File 'lib/obj_parser/obj.rb', line 10 def tangents_indexes @tangents_indexes end |
#textures ⇒ Object
Returns the value of attribute textures.
9 10 11 |
# File 'lib/obj_parser/obj.rb', line 9 def textures @textures end |
#textures_indexes ⇒ Object
Returns the value of attribute textures_indexes.
9 10 11 |
# File 'lib/obj_parser/obj.rb', line 9 def textures_indexes @textures_indexes end |
#vertice ⇒ Object
Returns the value of attribute vertice.
8 9 10 |
# File 'lib/obj_parser/obj.rb', line 8 def vertice @vertice end |
#vertice_indexes ⇒ Object
Returns the value of attribute vertice_indexes.
8 9 10 |
# File 'lib/obj_parser/obj.rb', line 8 def vertice_indexes @vertice_indexes end |
Instance Method Details
#compute_tangents ⇒ Object
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/obj_parser/obj.rb', line 37 def compute_tangents self.tangents = [] self.tangents_indexes = [] return if textures.count == 0 || normals.count == 0 self.resolve_faces pindex = 0 self.faces.each do |face| pindex += 1 tangent_for_face = MathUtils::tangent_for_vertices_and_texures(face.vertice.map(&:data), face.textures.map(&:data)) tangent_for_face = MathUtils::normalized_vector(tangent_for_face) #set the same tangent for the 3 vertex of current face #re-compute tangents for duplicates vertices to get tangent per face face.vertice.each_with_index do |vertex, index| vertex.tangent.data = MathUtils::sum_vectors(vertex.tangent.data, tangent_for_face) end end #orthonormalize self.faces.each_with_index do |face,pindex| face.vertice.each_with_index do |vertex, index| vertex.tangent.data = MathUtils::orthogonalized_vector_with_vector(vertex.tangent.data, self.normals[self.normals_indexes[pindex * 3 + index]].data) vertex.tangent.data = MathUtils::normalized_vector(vertex.tangent.data) end end #binormal should be computed with per vertex tangent and summed for each vertex self.faces.each_with_index do |face,pindex| face.vertice.each_with_index do |vertex, index| binormal = MathUtils::cross_product(self.normals[self.normals_indexes[pindex * 3 + index]].data, vertex.tangent.data) vertex.binormal.data = MathUtils::sum_vectors(vertex.binormal.data, binormal) end end self.faces.each_with_index do |face,pindex| face.vertice.each_with_index do |vertex, index| vertex.binormal.data = MathUtils::normalized_vector(vertex.binormal.data) if(MathUtils::dot(MathUtils::cross_product(self.normals[self.normals_indexes[pindex * 3 + index]].data, vertex.tangent.data), vertex.binormal.data) < 0.0) vertex.tangent.data[3] = -1.0 else vertex.tangent.data[3] = 1.0 end end end self.faces.each_with_index do |face, index| self.tangents += face.vertice.map(&:tangent) point_index = index * 3 self.tangents_indexes += [point_index, point_index + 1, point_index + 2] end end |
#resolve_faces ⇒ Object
24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/obj_parser/obj.rb', line 24 def resolve_faces self.faces = (self.vertice_indexes.count / VERTEX_BY_FACE).times.map { Face.new } self.faces.each_with_index do |face, face_index| [:vertice, :normals, :textures, :tangents].each do |element| point_indexes = (self.send("#{element}_indexes")[face_index * VERTEX_BY_FACE..-1] || []).take(VERTEX_BY_FACE) points = point_indexes.map do |point_index| self.send(element)[point_index] end face.send("#{element}=", points) end end end |
#tangents_self_check ⇒ Object
88 89 90 91 92 93 94 95 96 97 |
# File 'lib/obj_parser/obj.rb', line 88 def tangents_self_check self.resolve_faces result = self.faces.each_with_index.map do |face, index| face.vertice.map do |vertex| ("%.2f" % MathUtils::dot(vertex.tangent.data[0..2], vertex.normal.data)).to_f end.reduce(&:+) end.reduce(&:+) puts "RESULT: tangents and normals are orthogonal -> [#{result == 0 ? "VALID" : "NOT VALID"}]" result == 0 end |