obj_parser 0.0.1 → 0.0.2
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/README.md +3 -2
- data/lib/obj_parser/face.rb +1 -1
- data/lib/obj_parser/math_utils.rb +1 -1
- data/lib/obj_parser/obj.rb +11 -11
- data/lib/obj_parser/obj_parser.rb +1 -1
- data/lib/obj_parser/point.rb +1 -1
- data/lib/obj_parser/single_indexed_obj.rb +1 -1
- data/lib/obj_parser/version.rb +2 -2
- data/lib/obj_parser.rb +1 -1
- data/obj_parser.gemspec +1 -1
- data/test/math_utils_test.rb +14 -14
- data/test/obj_parser_spec.rb +3 -2
- data/test/obj_spec.rb +3 -3
- data/test/single_indexed_obj_spec.rb +3 -3
- data/test/test_helper.rb +1 -2
- metadata +1 -1
data/README.md
CHANGED
@@ -6,6 +6,7 @@ Can merge vertice, normals, and textures indexes into a single index for OpenGL
|
|
6
6
|
|
7
7
|
- Support triangle primitives
|
8
8
|
- Support only one model per obj file
|
9
|
+
- Did not support materials
|
9
10
|
|
10
11
|
## Installation
|
11
12
|
|
@@ -25,10 +26,10 @@ Or install it yourself as:
|
|
25
26
|
|
26
27
|
Sample to parse an obj file, generate tangents and transform to a single indexed 3D model.
|
27
28
|
|
28
|
-
@parser =
|
29
|
+
@parser = ObjParser::ObjParser.new
|
29
30
|
obj = @parser.load(File.open("/Users/lcobos/development/ios/OpenGL-4/models/cube.obj"))
|
30
31
|
obj.compute_tangents
|
31
|
-
obj =
|
32
|
+
obj = ObjParser::SingleIndexedObj.build_with_obj(obj)
|
32
33
|
|
33
34
|
puts obj.vertice.map(&:data).join(",")
|
34
35
|
puts obj.normals.map(&:data).join(",")
|
data/lib/obj_parser/face.rb
CHANGED
data/lib/obj_parser/obj.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require_relative 'face'
|
2
2
|
require_relative 'math_utils'
|
3
3
|
|
4
|
-
module
|
4
|
+
module ObjParser
|
5
5
|
class Obj
|
6
6
|
VERTEX_BY_FACE = 3
|
7
7
|
attr_accessor :normals, :normals_indexes
|
@@ -41,35 +41,35 @@ module ObjLoader
|
|
41
41
|
pindex = 0
|
42
42
|
self.faces.each do |face|
|
43
43
|
pindex += 1
|
44
|
-
tangent_for_face =
|
45
|
-
tangent_for_face =
|
44
|
+
tangent_for_face = ObjParser::MathUtils::tangent_for_vertices_and_texures(face.vertice.map(&:data), face.textures.map(&:data))
|
45
|
+
tangent_for_face = ObjParser::MathUtils::normalized_vector(tangent_for_face)
|
46
46
|
#set the same tangent for the 3 vertex of current face
|
47
47
|
#re-compute tangents for duplicates vertices to get tangent per face
|
48
48
|
face.vertice.each_with_index do |vertex, index|
|
49
|
-
vertex.tangent.data =
|
49
|
+
vertex.tangent.data = ObjParser::MathUtils::sum_vectors(vertex.tangent.data, tangent_for_face)
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
53
|
#orthonormalize
|
54
54
|
self.faces.each_with_index do |face,pindex|
|
55
55
|
face.vertice.each_with_index do |vertex, index|
|
56
|
-
vertex.tangent.data =
|
57
|
-
vertex.tangent.data =
|
56
|
+
vertex.tangent.data = ObjParser::MathUtils::orthogonalized_vector_with_vector(vertex.tangent.data, self.normals[self.normals_indexes[pindex * 3 + index]].data)
|
57
|
+
vertex.tangent.data = ObjParser::MathUtils::normalized_vector(vertex.tangent.data)
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
61
|
#binormal should be computed with per vertex tangent and summed for each vertex
|
62
62
|
self.faces.each_with_index do |face,pindex|
|
63
63
|
face.vertice.each_with_index do |vertex, index|
|
64
|
-
binormal =
|
65
|
-
vertex.binormal.data =
|
64
|
+
binormal = ObjParser::MathUtils::cross_product(self.normals[self.normals_indexes[pindex * 3 + index]].data, vertex.tangent.data)
|
65
|
+
vertex.binormal.data = ObjParser::MathUtils::sum_vectors(vertex.binormal.data, binormal)
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
69
69
|
self.faces.each_with_index do |face,pindex|
|
70
70
|
face.vertice.each_with_index do |vertex, index|
|
71
|
-
vertex.binormal.data =
|
72
|
-
if(
|
71
|
+
vertex.binormal.data = ObjParser::MathUtils::normalized_vector(vertex.binormal.data)
|
72
|
+
if(ObjParser::MathUtils::dot(ObjParser::MathUtils::cross_product(self.normals[self.normals_indexes[pindex * 3 + index]].data, vertex.tangent.data), vertex.binormal.data) < 0.0)
|
73
73
|
vertex.tangent.data[3] = -1.0
|
74
74
|
else
|
75
75
|
vertex.tangent.data[3] = 1.0
|
@@ -88,7 +88,7 @@ module ObjLoader
|
|
88
88
|
self.resolve_faces
|
89
89
|
result = self.faces.each_with_index.map do |face, index|
|
90
90
|
face.vertice.map do |vertex|
|
91
|
-
("%.2f" %
|
91
|
+
("%.2f" % ObjParser::MathUtils::dot(vertex.tangent.data[0..2], vertex.normal.data)).to_f
|
92
92
|
end.reduce(&:+)
|
93
93
|
end.reduce(&:+)
|
94
94
|
puts "RESULT: tangents and normals are orthogonal -> [#{result == 0 ? "VALID" : "NOT VALID"}]"
|
data/lib/obj_parser/point.rb
CHANGED
data/lib/obj_parser/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
module
|
2
|
-
VERSION = "0.0.
|
1
|
+
module ObjParser
|
2
|
+
VERSION = "0.0.2"
|
3
3
|
end
|
data/lib/obj_parser.rb
CHANGED
data/obj_parser.gemspec
CHANGED
@@ -5,7 +5,7 @@ require 'obj_parser/version'
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = "obj_parser"
|
8
|
-
spec.version =
|
8
|
+
spec.version = ObjParser::VERSION
|
9
9
|
spec.authors = ["Laurent Cobos"]
|
10
10
|
spec.email = ["laurent@11factory.fr"]
|
11
11
|
spec.summary = %q{3D obj file parser.}
|
data/test/math_utils_test.rb
CHANGED
@@ -1,52 +1,52 @@
|
|
1
1
|
require 'test/unit'
|
2
2
|
require 'obj_parser'
|
3
3
|
|
4
|
-
class
|
4
|
+
class ObjParser::MathUtilsTest < Test::Unit::TestCase
|
5
5
|
|
6
6
|
def test_tangent_computing_given_vertices_and_normal
|
7
7
|
vertices = [[0,0,0], [1,0,0], [1,1,0]]
|
8
8
|
textures = [[0,1], [1,1], [1,0]]
|
9
|
-
assert_equal [1,0,0],
|
9
|
+
assert_equal [1,0,0], ObjParser::MathUtils.tangent_for_vertices_and_texures(vertices, textures)
|
10
10
|
end
|
11
11
|
|
12
12
|
def test_tangent2_and_binormal_computing_given_vertices_and_normal
|
13
13
|
vertices = [[0,0,0], [1,0,0], [1,1,0]]
|
14
14
|
textures = [[0,1], [1,1], [1,0]]
|
15
15
|
normal = [0,0,-1]
|
16
|
-
assert_array_in_delta [1.29289321881345, -0.707106781186547, 0.0],
|
16
|
+
assert_array_in_delta [1.29289321881345, -0.707106781186547, 0.0], ObjParser::MathUtils.tangent2_for_vertices_and_texures(vertices, textures), 0.00001
|
17
17
|
end
|
18
18
|
|
19
19
|
def test_vector_length
|
20
|
-
assert_equal 0,
|
21
|
-
assert_equal 1,
|
22
|
-
assert_equal Math.sqrt(29),
|
20
|
+
assert_equal 0, ObjParser::MathUtils::vector_length([0,0,0])
|
21
|
+
assert_equal 1, ObjParser::MathUtils::vector_length([1,0,0])
|
22
|
+
assert_equal Math.sqrt(29), ObjParser::MathUtils.vector_length([2,3,4])
|
23
23
|
end
|
24
24
|
|
25
25
|
def test_vector_normalization
|
26
|
-
assert_equal [0,0,0],
|
27
|
-
assert_equal [1,0,0],
|
28
|
-
assert_array_in_delta [0.371390676354104, 0.557086014531156, 0.742781352708207],
|
26
|
+
assert_equal [0,0,0], ObjParser::MathUtils.normalized_vector([0,0,0])
|
27
|
+
assert_equal [1,0,0], ObjParser::MathUtils.normalized_vector([1,0,0])
|
28
|
+
assert_array_in_delta [0.371390676354104, 0.557086014531156, 0.742781352708207], ObjParser::MathUtils.normalized_vector([2,3,4]), 0.00001
|
29
29
|
end
|
30
30
|
|
31
31
|
def test_dot_product
|
32
32
|
v1 = [1,0,0]
|
33
33
|
v2 = [0,1,0]
|
34
|
-
assert_equal 0,
|
34
|
+
assert_equal 0, ObjParser::MathUtils.dot(v1, v2)
|
35
35
|
v2 = [1,1,0]
|
36
|
-
assert_equal 1,
|
36
|
+
assert_equal 1, ObjParser::MathUtils.dot(v1, v2)
|
37
37
|
end
|
38
38
|
|
39
39
|
def test_orthogonalize
|
40
40
|
v1 = [0.2,1,0]
|
41
41
|
v2 = [1,0,0]
|
42
|
-
assert_equal [0,1,0],
|
42
|
+
assert_equal [0,1,0], ObjParser::MathUtils.orthogonalized_vector_with_vector(v1, v2)
|
43
43
|
end
|
44
44
|
|
45
45
|
def test_normal_computing_given_face_vertices
|
46
46
|
vertices = [[0,0,0], [1,0,0], [1,1,0]]
|
47
|
-
assert_equal [0,0,1].map(&:to_s),
|
47
|
+
assert_equal [0,0,1].map(&:to_s), ObjParser::MathUtils.normal_for_face_with_vertices(vertices).map(&:to_s)
|
48
48
|
vertices = [[0,0,0], [0,0,1], [0,1,0]]
|
49
|
-
assert_equal [-1,0,0].map(&:to_s),
|
49
|
+
assert_equal [-1,0,0].map(&:to_s), ObjParser::MathUtils.normal_for_face_with_vertices(vertices).map(&:to_s)
|
50
50
|
end
|
51
51
|
|
52
52
|
private
|
data/test/obj_parser_spec.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
require 'test_helper'
|
2
|
+
require 'stringio'
|
2
3
|
|
3
|
-
describe
|
4
|
+
describe ObjParser::ObjParser do
|
4
5
|
|
5
6
|
it "should get obj vertice, normals, textures and indexes" do
|
6
|
-
@parser =
|
7
|
+
@parser = ObjParser::ObjParser.new
|
7
8
|
obj = @parser.load(StringIO.new(sample_cube_obj))
|
8
9
|
obj.vertice.take(3).map(&:data).must_equal([p([0.0,0.0,0.0]), p([0.0,0.0,1.0]), p([0.0,1.0,0.0])].map(&:data))
|
9
10
|
obj.normals.count.must_equal(6)
|
data/test/obj_spec.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
-
describe
|
3
|
+
describe ObjParser::Obj do
|
4
4
|
|
5
5
|
before do
|
6
|
-
@obj =
|
6
|
+
@obj = ObjParser::Obj.new
|
7
7
|
@obj.vertice = [p([0.0,0.0,0.0]), p([0.0,0.0,1.0]), p([0.0,1.0,0.0]), p([0.0,1.0,1.0])]
|
8
8
|
@obj.vertice_indexes = [0, 1, 2, 1, 2, 3]
|
9
9
|
@obj.normals = [p([1.0,0.0,0.0]), p([0.0,1.0,0.0])]
|
@@ -24,7 +24,7 @@ describe ObjLoader::Obj do
|
|
24
24
|
@obj.compute_tangents
|
25
25
|
result = @obj.faces.each_with_index.map do |face, index|
|
26
26
|
face.vertice.map do |vertex|
|
27
|
-
("%.2f" %
|
27
|
+
("%.2f" % ObjParser::MathUtils::dot(vertex.tangent.data[0..2], vertex.normal.data)).to_f
|
28
28
|
end.reduce(&:+)
|
29
29
|
end.reduce(&:+)
|
30
30
|
result.must_equal(0)
|
@@ -1,14 +1,14 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
-
describe
|
3
|
+
describe ObjParser::SingleIndexedObj do
|
4
4
|
|
5
5
|
before do
|
6
|
-
@obj =
|
6
|
+
@obj = ObjParser::Obj.new
|
7
7
|
@obj.vertice = [p([0.0,0.0,0.0]), p([0.0,0.0,1.0]), p([0.0,1.0,0.0]), p([0.0,1.0,1.0])]
|
8
8
|
@obj.vertice_indexes = [0, 1, 2, 0, 2, 3]
|
9
9
|
@obj.normals = [p([1.0,0.0,0.0]), p([0.0,1.0,0.0])]
|
10
10
|
@obj.normals_indexes = [1, 0, 1, 1, 0, 0]
|
11
|
-
@single_indexed_obj =
|
11
|
+
@single_indexed_obj = ObjParser::SingleIndexedObj.build_with_obj(@obj)
|
12
12
|
end
|
13
13
|
|
14
14
|
describe 'compute detailed vertice' do
|
data/test/test_helper.rb
CHANGED