-
Notifications
You must be signed in to change notification settings - Fork 68
/
Copy pathObjLoader.py
106 lines (82 loc) · 3.88 KB
/
ObjLoader.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import numpy as np
class ObjLoader:
buffer = []
@staticmethod
def search_data(data_values, coordinates, skip, data_type):
for d in data_values:
if d == skip:
continue
if data_type == 'float':
coordinates.append(float(d))
elif data_type == 'int':
coordinates.append(int(d)-1)
@staticmethod # sorted vertex buffer for use with glDrawArrays function
def create_sorted_vertex_buffer(indices_data, vertices, textures, normals):
for i, ind in enumerate(indices_data):
if i % 3 == 0: # sort the vertex coordinates
start = ind * 3
end = start + 3
ObjLoader.buffer.extend(vertices[start:end])
elif i % 3 == 1: # sort the texture coordinates
start = ind * 2
end = start + 2
ObjLoader.buffer.extend(textures[start:end])
elif i % 3 == 2: # sort the normal vectors
start = ind * 3
end = start + 3
ObjLoader.buffer.extend(normals[start:end])
@staticmethod # TODO unsorted vertex buffer for use with glDrawElements function
def create_unsorted_vertex_buffer(indices_data, vertices, textures, normals):
num_verts = len(vertices) // 3
for i1 in range(num_verts):
start = i1 * 3
end = start + 3
ObjLoader.buffer.extend(vertices[start:end])
for i2, data in enumerate(indices_data):
if i2 % 3 == 0 and data == i1:
start = indices_data[i2 + 1] * 2
end = start + 2
ObjLoader.buffer.extend(textures[start:end])
start = indices_data[i2 + 2] * 3
end = start + 3
ObjLoader.buffer.extend(normals[start:end])
break
@staticmethod
def show_buffer_data(buffer):
for i in range(len(buffer)//8):
start = i * 8
end = start + 8
print(buffer[start:end])
@staticmethod
def load_model(file, sorted=True):
vert_coords = [] # will contain all the vertex coordinates
tex_coords = [] # will contain all the texture coordinates
norm_coords = [] # will contain all the vertex normals
all_indices = [] # will contain all the vertex, texture and normal indices
indices = [] # will contain the indices for indexed drawing
with open(file, 'r') as f:
line = f.readline()
while line:
values = line.split()
if values[0] == 'v':
ObjLoader.search_data(values, vert_coords, 'v', 'float')
elif values[0] == 'vt':
ObjLoader.search_data(values, tex_coords, 'vt', 'float')
elif values[0] == 'vn':
ObjLoader.search_data(values, norm_coords, 'vn', 'float')
elif values[0] == 'f':
for value in values[1:]:
val = value.split('/')
ObjLoader.search_data(val, all_indices, 'f', 'int')
indices.append(int(val[0])-1)
line = f.readline()
if sorted:
# use with glDrawArrays
ObjLoader.create_sorted_vertex_buffer(all_indices, vert_coords, tex_coords, norm_coords)
else:
# use with glDrawElements
ObjLoader.create_unsorted_vertex_buffer(all_indices, vert_coords, tex_coords, norm_coords)
# ObjLoader.show_buffer_data(ObjLoader.buffer)
buffer = ObjLoader.buffer.copy() # create a local copy of the buffer list, otherwise it will overwrite the static field buffer
ObjLoader.buffer = [] # after copy, make sure to set it back to an empty list
return np.array(indices, dtype='uint32'), np.array(buffer, dtype='float32')