gmath3D 0.2.4 → 0.2.5
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/.document +5 -5
- data/Gemfile +5 -11
- data/LICENSE.txt +20 -20
- data/README.rdoc +19 -19
- data/Rakefile +45 -45
- data/VERSION +1 -1
- data/gmath3D.gemspec +79 -80
- data/lib/box.rb +145 -145
- data/lib/ellipse.rb +11 -11
- data/lib/ext.rb +82 -82
- data/lib/finite_line.rb +244 -244
- data/lib/geom.rb +20 -20
- data/lib/gmath3D.rb +22 -22
- data/lib/line.rb +122 -122
- data/lib/plane.rb +131 -131
- data/lib/polyline.rb +73 -73
- data/lib/quat.rb +170 -170
- data/lib/rectangle.rb +155 -155
- data/lib/tri_mesh.rb +258 -258
- data/lib/triangle.rb +281 -281
- data/lib/util.rb +36 -23
- data/lib/vector3.rb +227 -227
- data/test/helper.rb +15 -15
- data/test/test_box.rb +167 -167
- data/test/test_ellipse.rb +55 -55
- data/test/test_finite_line.rb +306 -306
- data/test/test_geom.rb +17 -17
- data/test/test_line.rb +146 -146
- data/test/test_matrix_util.rb +84 -84
- data/test/test_plane.rb +200 -200
- data/test/test_polyline.rb +93 -93
- data/test/test_quat.rb +144 -144
- data/test/test_rectangle.rb +184 -184
- data/test/test_tri_mesh.rb +186 -186
- data/test/test_triangle.rb +318 -318
- data/test/test_util.rb +88 -57
- data/test/test_vector3.rb +439 -439
- metadata +8 -11
- data/Gemfile.lock +0 -16
data/lib/tri_mesh.rb
CHANGED
@@ -1,258 +1,258 @@
|
|
1
|
-
require 'gmath3D'
|
2
|
-
|
3
|
-
module GMath3D
|
4
|
-
#
|
5
|
-
# TriMesh represents an structured trianglular mesh.
|
6
|
-
#
|
7
|
-
class TriMesh < Geom
|
8
|
-
attr_reader :vertices
|
9
|
-
attr_reader :tri_indices
|
10
|
-
|
11
|
-
include BoxAvailable
|
12
|
-
|
13
|
-
# [Input]
|
14
|
-
# vertices is Array of Vector3.
|
15
|
-
# tri_indices is Array of triangle whick is consist of 3 vertices index.
|
16
|
-
# [Output]
|
17
|
-
# return new instance of TriMesh.
|
18
|
-
def initialize(vertices, tri_indices)
|
19
|
-
# check arg
|
20
|
-
Util3D.check_arg_type(Array, vertices)
|
21
|
-
Util3D.check_arg_type(Array, tri_indices)
|
22
|
-
vertices.each do |item|
|
23
|
-
Util3D.check_arg_type(Vector3, item)
|
24
|
-
end
|
25
|
-
tri_indices.each do |tri_index|
|
26
|
-
Util3D.check_arg_type(Array, tri_index)
|
27
|
-
tri_index.each do |item|
|
28
|
-
Util3D.check_arg_type(Integer, item)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
super()
|
32
|
-
@vertices = vertices
|
33
|
-
@tri_indices = tri_indices
|
34
|
-
end
|
35
|
-
|
36
|
-
def initialize_copy( original_obj )
|
37
|
-
@vertices = Array.new(original_obj.vertices.size)
|
38
|
-
for i in 0..@vertices.size-1
|
39
|
-
@vertices[i] = original_obj.vertices[i].dup
|
40
|
-
end
|
41
|
-
@tri_indices = Array.new(original_obj.tri_indices.size)
|
42
|
-
for i in 0..@tri_indices.size-1
|
43
|
-
@tri_indices[i] = original_obj.tri_indices[i].dup
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
# [Input]
|
48
|
-
# _box_ is a Box object.
|
49
|
-
# [Output]
|
50
|
-
# return new instance of TriMesh.
|
51
|
-
def self.from_box(box)
|
52
|
-
Util3D.check_arg_type(Box, box)
|
53
|
-
width, height, depth = box.length()
|
54
|
-
vertices = Array.new(8)
|
55
|
-
vertices[0] = box.min_point
|
56
|
-
vertices[1] = box.min_point + Vector3.new(width, 0, 0)
|
57
|
-
vertices[2] = box.min_point + Vector3.new(width, 0, depth)
|
58
|
-
vertices[3] = box.min_point + Vector3.new(0 , 0, depth)
|
59
|
-
vertices[4] = box.min_point + Vector3.new(0 , height, 0)
|
60
|
-
vertices[5] = box.min_point + Vector3.new(width, height, 0)
|
61
|
-
vertices[6] = box.min_point + Vector3.new(width, height, depth)
|
62
|
-
vertices[7] = box.min_point + Vector3.new(0 , height, depth)
|
63
|
-
|
64
|
-
tri_indices =[
|
65
|
-
[0, 1, 2],
|
66
|
-
[0, 2, 3],
|
67
|
-
[1, 5, 6],
|
68
|
-
[1, 6, 2],
|
69
|
-
[5, 4, 7],
|
70
|
-
[5, 7, 6],
|
71
|
-
[4, 0, 3],
|
72
|
-
[4, 3, 7],
|
73
|
-
[2, 6, 7],
|
74
|
-
[2, 7, 3],
|
75
|
-
[0, 4, 5],
|
76
|
-
[0, 5, 1]]
|
77
|
-
return TriMesh.new( vertices, tri_indices )
|
78
|
-
end
|
79
|
-
|
80
|
-
# [Input]
|
81
|
-
# _rect_ is a Rectangle object.
|
82
|
-
# [Output]
|
83
|
-
# return new instance of TriMesh.
|
84
|
-
def self.from_rectangle(rect)
|
85
|
-
Util3D.check_arg_type(Rectangle, rect)
|
86
|
-
return TriMesh.new(rect.vertices, [[0,1,3], [1,2,3]])
|
87
|
-
end
|
88
|
-
|
89
|
-
# [Input]
|
90
|
-
# _tris_ is Array of Triangle object.
|
91
|
-
# [Output]
|
92
|
-
# return new instance of TriMesh
|
93
|
-
def self.from_triangles(tris)
|
94
|
-
Util3D.check_arg_type(Array, tris)
|
95
|
-
tris.each do | item |
|
96
|
-
Util3D.check_arg_type(Triangle, item)
|
97
|
-
end
|
98
|
-
|
99
|
-
tri_idx = 0
|
100
|
-
vert_tris_map = Hash.new(nil)
|
101
|
-
tris.each_with_index do | triangle, tri_idx |
|
102
|
-
triangle.vertices.each do | vertex |
|
103
|
-
vert_tris_map[vertex] = Array.new() if( !vert_tris_map.key?(vertex) )
|
104
|
-
vert_tris_map[vertex] = vert_tris_map[vertex].push(tri_idx)
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
tri_indices = Array.new( tris.size )
|
109
|
-
vertices = vert_tris_map.keys
|
110
|
-
|
111
|
-
vert_idx = 0
|
112
|
-
vert_tris_map.each do | vertex, tri_index_ary |
|
113
|
-
tri_index_ary.each do | tri_index |
|
114
|
-
tri_indices[tri_index] = Array.new() if( !tri_indices[tri_index] )
|
115
|
-
tri_indices[tri_index].push(vert_idx)
|
116
|
-
end
|
117
|
-
vert_idx += 1
|
118
|
-
end
|
119
|
-
|
120
|
-
# modify noamal direction
|
121
|
-
tri_idx = 0
|
122
|
-
tri_indices.each do | tri_index_ary |
|
123
|
-
if ( tri_index_ary.size > 2 )
|
124
|
-
tmp_tri = Triangle.new(vertices[tri_index_ary[0]], vertices[tri_index_ary[1]], vertices[tri_index_ary[2]])
|
125
|
-
if( tmp_tri.normal.dot(tris[tri_idx].normal) < 0 )
|
126
|
-
tri_index_ary.reverse!
|
127
|
-
end
|
128
|
-
end
|
129
|
-
tri_idx += 1
|
130
|
-
end
|
131
|
-
|
132
|
-
return TriMesh.new( vertices, tri_indices )
|
133
|
-
end
|
134
|
-
|
135
|
-
# [Input]
|
136
|
-
# _polyline_ is Poyline object that should be convex.
|
137
|
-
# [Output]
|
138
|
-
# return new instance of TriMesh
|
139
|
-
def self.from_convex_polyline(polyline)
|
140
|
-
trimesh_vertices = Array.new(polyline.vertices.size + 1)
|
141
|
-
trimesh_vertices[0] = polyline.center
|
142
|
-
i = 1
|
143
|
-
polyline.vertices.each do | poly_vert |
|
144
|
-
trimesh_vertices[i] = poly_vert.clone
|
145
|
-
i += 1
|
146
|
-
end
|
147
|
-
trimesh_tri_indices = Array.new(polyline.vertices.size)
|
148
|
-
for i in 0..polyline.vertices.size-1
|
149
|
-
trimesh_tri_indices[i] = [0,i+1,i+2]
|
150
|
-
end
|
151
|
-
trimesh_tri_indices[trimesh_tri_indices.size - 1] = [0,polyline.vertices.size,1]
|
152
|
-
return TriMesh.new( trimesh_vertices, trimesh_tri_indices )
|
153
|
-
end
|
154
|
-
|
155
|
-
# [Input]
|
156
|
-
# _polyline_ is Poyline object.
|
157
|
-
# _extrude_direction_ is Vector3.
|
158
|
-
# [Output]
|
159
|
-
# return new instance of TriMesh that is extruded polyline
|
160
|
-
def self.from_extrude_polyline(polyline, extrude_direction)
|
161
|
-
trimesh_vertices = Array.new(polyline.vertices.size*2)
|
162
|
-
poly_vert_cnt = polyline.vertices.size
|
163
|
-
i = 0
|
164
|
-
polyline.vertices.each do | poly_vert |
|
165
|
-
trimesh_vertices[i] = poly_vert.clone
|
166
|
-
trimesh_vertices[i + poly_vert_cnt] = poly_vert + extrude_direction
|
167
|
-
i+=1
|
168
|
-
end
|
169
|
-
|
170
|
-
tri_indices_cnt = (poly_vert_cnt-1)*2
|
171
|
-
trimesh_tri_indices = Array.new(tri_indices_cnt)
|
172
|
-
|
173
|
-
for i in 0..poly_vert_cnt-2
|
174
|
-
trimesh_tri_indices[2*i ] = [i, i + 1, i + poly_vert_cnt]
|
175
|
-
trimesh_tri_indices[2*i + 1] = [i + 1, i + 1 + poly_vert_cnt, i + poly_vert_cnt]
|
176
|
-
end
|
177
|
-
if(!polyline.is_open)
|
178
|
-
trimesh_tri_indices[2*(poly_vert_cnt - 1) ] = [poly_vert_cnt - 1, 0, 2*(poly_vert_cnt - 1) + 1]
|
179
|
-
trimesh_tri_indices[2*(poly_vert_cnt - 1) + 1] = [0, poly_vert_cnt, 2*(poly_vert_cnt - 1) + 1]
|
180
|
-
end
|
181
|
-
return TriMesh.new(trimesh_vertices, trimesh_tri_indices)
|
182
|
-
end
|
183
|
-
|
184
|
-
# [Input]
|
185
|
-
# _rhs_ is TriMesh.
|
186
|
-
# [Output]
|
187
|
-
# return true if rhs equals myself.
|
188
|
-
def ==(rhs)
|
189
|
-
return false if rhs == nil
|
190
|
-
return false if( !rhs.kind_of?(TriMesh) )
|
191
|
-
return false if(@vertices.size != rhs.vertices.size)
|
192
|
-
return false if(@tri_indices.size != rhs.tri_indices.size)
|
193
|
-
|
194
|
-
for i in 0..(@vertices.size-1)
|
195
|
-
return false if( @vertices[i] != rhs.vertices[i])
|
196
|
-
end
|
197
|
-
|
198
|
-
for i in 0..(@tri_indices.size-1)
|
199
|
-
return false if( @tri_indices[i] != rhs.tri_indices[i])
|
200
|
-
end
|
201
|
-
return true
|
202
|
-
end
|
203
|
-
|
204
|
-
def to_s
|
205
|
-
"TriMesh[triangle_count:#{tri_indices.size}, vertex_count:#{vertices.size}]"
|
206
|
-
end
|
207
|
-
|
208
|
-
# [Input]
|
209
|
-
# _index_ is index of triangle.
|
210
|
-
# [Output]
|
211
|
-
# return new instance of Triangle.
|
212
|
-
def triangle(index)
|
213
|
-
return nil if( index < 0 || @tri_indices.size <= index )
|
214
|
-
tri_index = @tri_indices[index]
|
215
|
-
return Triangle.new(vertices[tri_index[0]], vertices[tri_index[1]], vertices[tri_index[2]])
|
216
|
-
end
|
217
|
-
|
218
|
-
# [Output]
|
219
|
-
# return Array of Triangle.
|
220
|
-
def triangles
|
221
|
-
tris = Array.new(tri_indices.size)
|
222
|
-
i = 0
|
223
|
-
tri_indices.each do |tri_index|
|
224
|
-
tris[i] = self.triangle(i)
|
225
|
-
i += 1
|
226
|
-
end
|
227
|
-
return tris
|
228
|
-
end
|
229
|
-
|
230
|
-
# [Output]
|
231
|
-
# return surface area of TriMesh.
|
232
|
-
def area
|
233
|
-
area_sum = 0
|
234
|
-
triangles.each do | tri |
|
235
|
-
area_sum += tri.area
|
236
|
-
end
|
237
|
-
return area_sum
|
238
|
-
end
|
239
|
-
|
240
|
-
# [Output]
|
241
|
-
# return normal vector for each vertex as Hash{ Vector3 vertex => Vector3 normal_vector}.
|
242
|
-
def normals_for_each_vertices
|
243
|
-
normals_map = Hash.new(nil)
|
244
|
-
triangles.each_with_index do | tri, tri_idx |
|
245
|
-
tri.vertices.each_with_index do | vertex, ver_idx |
|
246
|
-
normals_map[vertex] = Vector3.new() if( !normals_map.key?(vertex) )
|
247
|
-
normals_map[vertex] += tri.normal*tri.angle(ver_idx)
|
248
|
-
end
|
249
|
-
end
|
250
|
-
normals_map.each do |vertex, normal|
|
251
|
-
normals_map[vertex] = normal.normalize
|
252
|
-
end
|
253
|
-
return normals_map
|
254
|
-
end
|
255
|
-
|
256
|
-
end
|
257
|
-
end
|
258
|
-
|
1
|
+
require 'gmath3D'
|
2
|
+
|
3
|
+
module GMath3D
|
4
|
+
#
|
5
|
+
# TriMesh represents an structured trianglular mesh.
|
6
|
+
#
|
7
|
+
class TriMesh < Geom
|
8
|
+
attr_reader :vertices
|
9
|
+
attr_reader :tri_indices
|
10
|
+
|
11
|
+
include BoxAvailable
|
12
|
+
|
13
|
+
# [Input]
|
14
|
+
# vertices is Array of Vector3.
|
15
|
+
# tri_indices is Array of triangle whick is consist of 3 vertices index.
|
16
|
+
# [Output]
|
17
|
+
# return new instance of TriMesh.
|
18
|
+
def initialize(vertices, tri_indices)
|
19
|
+
# check arg
|
20
|
+
Util3D.check_arg_type(Array, vertices)
|
21
|
+
Util3D.check_arg_type(Array, tri_indices)
|
22
|
+
vertices.each do |item|
|
23
|
+
Util3D.check_arg_type(Vector3, item)
|
24
|
+
end
|
25
|
+
tri_indices.each do |tri_index|
|
26
|
+
Util3D.check_arg_type(Array, tri_index)
|
27
|
+
tri_index.each do |item|
|
28
|
+
Util3D.check_arg_type(Integer, item)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
super()
|
32
|
+
@vertices = vertices
|
33
|
+
@tri_indices = tri_indices
|
34
|
+
end
|
35
|
+
|
36
|
+
def initialize_copy( original_obj )
|
37
|
+
@vertices = Array.new(original_obj.vertices.size)
|
38
|
+
for i in 0..@vertices.size-1
|
39
|
+
@vertices[i] = original_obj.vertices[i].dup
|
40
|
+
end
|
41
|
+
@tri_indices = Array.new(original_obj.tri_indices.size)
|
42
|
+
for i in 0..@tri_indices.size-1
|
43
|
+
@tri_indices[i] = original_obj.tri_indices[i].dup
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# [Input]
|
48
|
+
# _box_ is a Box object.
|
49
|
+
# [Output]
|
50
|
+
# return new instance of TriMesh.
|
51
|
+
def self.from_box(box)
|
52
|
+
Util3D.check_arg_type(Box, box)
|
53
|
+
width, height, depth = box.length()
|
54
|
+
vertices = Array.new(8)
|
55
|
+
vertices[0] = box.min_point
|
56
|
+
vertices[1] = box.min_point + Vector3.new(width, 0, 0)
|
57
|
+
vertices[2] = box.min_point + Vector3.new(width, 0, depth)
|
58
|
+
vertices[3] = box.min_point + Vector3.new(0 , 0, depth)
|
59
|
+
vertices[4] = box.min_point + Vector3.new(0 , height, 0)
|
60
|
+
vertices[5] = box.min_point + Vector3.new(width, height, 0)
|
61
|
+
vertices[6] = box.min_point + Vector3.new(width, height, depth)
|
62
|
+
vertices[7] = box.min_point + Vector3.new(0 , height, depth)
|
63
|
+
|
64
|
+
tri_indices =[
|
65
|
+
[0, 1, 2],
|
66
|
+
[0, 2, 3],
|
67
|
+
[1, 5, 6],
|
68
|
+
[1, 6, 2],
|
69
|
+
[5, 4, 7],
|
70
|
+
[5, 7, 6],
|
71
|
+
[4, 0, 3],
|
72
|
+
[4, 3, 7],
|
73
|
+
[2, 6, 7],
|
74
|
+
[2, 7, 3],
|
75
|
+
[0, 4, 5],
|
76
|
+
[0, 5, 1]]
|
77
|
+
return TriMesh.new( vertices, tri_indices )
|
78
|
+
end
|
79
|
+
|
80
|
+
# [Input]
|
81
|
+
# _rect_ is a Rectangle object.
|
82
|
+
# [Output]
|
83
|
+
# return new instance of TriMesh.
|
84
|
+
def self.from_rectangle(rect)
|
85
|
+
Util3D.check_arg_type(Rectangle, rect)
|
86
|
+
return TriMesh.new(rect.vertices, [[0,1,3], [1,2,3]])
|
87
|
+
end
|
88
|
+
|
89
|
+
# [Input]
|
90
|
+
# _tris_ is Array of Triangle object.
|
91
|
+
# [Output]
|
92
|
+
# return new instance of TriMesh
|
93
|
+
def self.from_triangles(tris)
|
94
|
+
Util3D.check_arg_type(Array, tris)
|
95
|
+
tris.each do | item |
|
96
|
+
Util3D.check_arg_type(Triangle, item)
|
97
|
+
end
|
98
|
+
|
99
|
+
tri_idx = 0
|
100
|
+
vert_tris_map = Hash.new(nil)
|
101
|
+
tris.each_with_index do | triangle, tri_idx |
|
102
|
+
triangle.vertices.each do | vertex |
|
103
|
+
vert_tris_map[vertex] = Array.new() if( !vert_tris_map.key?(vertex) )
|
104
|
+
vert_tris_map[vertex] = vert_tris_map[vertex].push(tri_idx)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
tri_indices = Array.new( tris.size )
|
109
|
+
vertices = vert_tris_map.keys
|
110
|
+
|
111
|
+
vert_idx = 0
|
112
|
+
vert_tris_map.each do | vertex, tri_index_ary |
|
113
|
+
tri_index_ary.each do | tri_index |
|
114
|
+
tri_indices[tri_index] = Array.new() if( !tri_indices[tri_index] )
|
115
|
+
tri_indices[tri_index].push(vert_idx)
|
116
|
+
end
|
117
|
+
vert_idx += 1
|
118
|
+
end
|
119
|
+
|
120
|
+
# modify noamal direction
|
121
|
+
tri_idx = 0
|
122
|
+
tri_indices.each do | tri_index_ary |
|
123
|
+
if ( tri_index_ary.size > 2 )
|
124
|
+
tmp_tri = Triangle.new(vertices[tri_index_ary[0]], vertices[tri_index_ary[1]], vertices[tri_index_ary[2]])
|
125
|
+
if( tmp_tri.normal.dot(tris[tri_idx].normal) < 0 )
|
126
|
+
tri_index_ary.reverse!
|
127
|
+
end
|
128
|
+
end
|
129
|
+
tri_idx += 1
|
130
|
+
end
|
131
|
+
|
132
|
+
return TriMesh.new( vertices, tri_indices )
|
133
|
+
end
|
134
|
+
|
135
|
+
# [Input]
|
136
|
+
# _polyline_ is Poyline object that should be convex.
|
137
|
+
# [Output]
|
138
|
+
# return new instance of TriMesh
|
139
|
+
def self.from_convex_polyline(polyline)
|
140
|
+
trimesh_vertices = Array.new(polyline.vertices.size + 1)
|
141
|
+
trimesh_vertices[0] = polyline.center
|
142
|
+
i = 1
|
143
|
+
polyline.vertices.each do | poly_vert |
|
144
|
+
trimesh_vertices[i] = poly_vert.clone
|
145
|
+
i += 1
|
146
|
+
end
|
147
|
+
trimesh_tri_indices = Array.new(polyline.vertices.size)
|
148
|
+
for i in 0..polyline.vertices.size-1
|
149
|
+
trimesh_tri_indices[i] = [0,i+1,i+2]
|
150
|
+
end
|
151
|
+
trimesh_tri_indices[trimesh_tri_indices.size - 1] = [0,polyline.vertices.size,1]
|
152
|
+
return TriMesh.new( trimesh_vertices, trimesh_tri_indices )
|
153
|
+
end
|
154
|
+
|
155
|
+
# [Input]
|
156
|
+
# _polyline_ is Poyline object.
|
157
|
+
# _extrude_direction_ is Vector3.
|
158
|
+
# [Output]
|
159
|
+
# return new instance of TriMesh that is extruded polyline
|
160
|
+
def self.from_extrude_polyline(polyline, extrude_direction)
|
161
|
+
trimesh_vertices = Array.new(polyline.vertices.size*2)
|
162
|
+
poly_vert_cnt = polyline.vertices.size
|
163
|
+
i = 0
|
164
|
+
polyline.vertices.each do | poly_vert |
|
165
|
+
trimesh_vertices[i] = poly_vert.clone
|
166
|
+
trimesh_vertices[i + poly_vert_cnt] = poly_vert + extrude_direction
|
167
|
+
i+=1
|
168
|
+
end
|
169
|
+
|
170
|
+
tri_indices_cnt = (poly_vert_cnt-1)*2
|
171
|
+
trimesh_tri_indices = Array.new(tri_indices_cnt)
|
172
|
+
|
173
|
+
for i in 0..poly_vert_cnt-2
|
174
|
+
trimesh_tri_indices[2*i ] = [i, i + 1, i + poly_vert_cnt]
|
175
|
+
trimesh_tri_indices[2*i + 1] = [i + 1, i + 1 + poly_vert_cnt, i + poly_vert_cnt]
|
176
|
+
end
|
177
|
+
if(!polyline.is_open)
|
178
|
+
trimesh_tri_indices[2*(poly_vert_cnt - 1) ] = [poly_vert_cnt - 1, 0, 2*(poly_vert_cnt - 1) + 1]
|
179
|
+
trimesh_tri_indices[2*(poly_vert_cnt - 1) + 1] = [0, poly_vert_cnt, 2*(poly_vert_cnt - 1) + 1]
|
180
|
+
end
|
181
|
+
return TriMesh.new(trimesh_vertices, trimesh_tri_indices)
|
182
|
+
end
|
183
|
+
|
184
|
+
# [Input]
|
185
|
+
# _rhs_ is TriMesh.
|
186
|
+
# [Output]
|
187
|
+
# return true if rhs equals myself.
|
188
|
+
def ==(rhs)
|
189
|
+
return false if rhs == nil
|
190
|
+
return false if( !rhs.kind_of?(TriMesh) )
|
191
|
+
return false if(@vertices.size != rhs.vertices.size)
|
192
|
+
return false if(@tri_indices.size != rhs.tri_indices.size)
|
193
|
+
|
194
|
+
for i in 0..(@vertices.size-1)
|
195
|
+
return false if( @vertices[i] != rhs.vertices[i])
|
196
|
+
end
|
197
|
+
|
198
|
+
for i in 0..(@tri_indices.size-1)
|
199
|
+
return false if( @tri_indices[i] != rhs.tri_indices[i])
|
200
|
+
end
|
201
|
+
return true
|
202
|
+
end
|
203
|
+
|
204
|
+
def to_s
|
205
|
+
"TriMesh[triangle_count:#{tri_indices.size}, vertex_count:#{vertices.size}]"
|
206
|
+
end
|
207
|
+
|
208
|
+
# [Input]
|
209
|
+
# _index_ is index of triangle.
|
210
|
+
# [Output]
|
211
|
+
# return new instance of Triangle.
|
212
|
+
def triangle(index)
|
213
|
+
return nil if( index < 0 || @tri_indices.size <= index )
|
214
|
+
tri_index = @tri_indices[index]
|
215
|
+
return Triangle.new(vertices[tri_index[0]], vertices[tri_index[1]], vertices[tri_index[2]])
|
216
|
+
end
|
217
|
+
|
218
|
+
# [Output]
|
219
|
+
# return Array of Triangle.
|
220
|
+
def triangles
|
221
|
+
tris = Array.new(tri_indices.size)
|
222
|
+
i = 0
|
223
|
+
tri_indices.each do |tri_index|
|
224
|
+
tris[i] = self.triangle(i)
|
225
|
+
i += 1
|
226
|
+
end
|
227
|
+
return tris
|
228
|
+
end
|
229
|
+
|
230
|
+
# [Output]
|
231
|
+
# return surface area of TriMesh.
|
232
|
+
def area
|
233
|
+
area_sum = 0
|
234
|
+
triangles.each do | tri |
|
235
|
+
area_sum += tri.area
|
236
|
+
end
|
237
|
+
return area_sum
|
238
|
+
end
|
239
|
+
|
240
|
+
# [Output]
|
241
|
+
# return normal vector for each vertex as Hash{ Vector3 vertex => Vector3 normal_vector}.
|
242
|
+
def normals_for_each_vertices
|
243
|
+
normals_map = Hash.new(nil)
|
244
|
+
triangles.each_with_index do | tri, tri_idx |
|
245
|
+
tri.vertices.each_with_index do | vertex, ver_idx |
|
246
|
+
normals_map[vertex] = Vector3.new() if( !normals_map.key?(vertex) )
|
247
|
+
normals_map[vertex] += tri.normal*tri.angle(ver_idx)
|
248
|
+
end
|
249
|
+
end
|
250
|
+
normals_map.each do |vertex, normal|
|
251
|
+
normals_map[vertex] = normal.normalize
|
252
|
+
end
|
253
|
+
return normals_map
|
254
|
+
end
|
255
|
+
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|