1 | from gui.visual.loader import Loader
|
---|
2 | from gui.visual.modelData import ModelData
|
---|
3 | from gui.visual.modelTexture import ModelTexture
|
---|
4 | import glm
|
---|
5 |
|
---|
6 | class OBJLoader:
|
---|
7 | class PackedVertex:
|
---|
8 | def __init__(self, position, uv, normal) -> None:
|
---|
9 | self.position = position
|
---|
10 | self.uv = uv
|
---|
11 | self.normal = normal
|
---|
12 |
|
---|
13 | @staticmethod
|
---|
14 | def loadOBJ(objFileName: str, textureFileName: str, loader: Loader):
|
---|
15 | vertices, uvs, normals = OBJLoader._loadOBJ(objFileName)
|
---|
16 | indices, indexed_vertices, indexed_uvs, indexed_normals = OBJLoader._indexVBO(vertices, uvs, normals)
|
---|
17 | verticesf = OBJLoader._vec3ToFloat(indexed_vertices)
|
---|
18 | uvsf = OBJLoader._vec2ToFloat(indexed_uvs)
|
---|
19 | normalsf = OBJLoader._vec3ToFloat(indexed_normals)
|
---|
20 | rawModel = loader.loadToVao5(verticesf, uvsf, normalsf, indices, len(vertices))
|
---|
21 | model = ModelData(rawModel, ModelTexture(loader.loadTexture(textureFileName) if textureFileName else 0))
|
---|
22 | return model
|
---|
23 |
|
---|
24 | @staticmethod
|
---|
25 | def _loadOBJ(path):
|
---|
26 | vertexIndices = []
|
---|
27 | uvIndices = []
|
---|
28 | normalIndices = []
|
---|
29 | temp_vertices = []
|
---|
30 | temp_uvs = []
|
---|
31 | temp_normals = []
|
---|
32 | out_vertices = []
|
---|
33 | out_uvs = []
|
---|
34 | out_normals = []
|
---|
35 |
|
---|
36 | with open(path, "r") as file:
|
---|
37 | while (line := file.readline()):
|
---|
38 | if line[0:2] == 'v ':
|
---|
39 | currentLine = line.split()
|
---|
40 | vertex = glm.vec3(float(currentLine[1]), float(currentLine[2]), float(currentLine[3]))
|
---|
41 | temp_vertices.append(vertex)
|
---|
42 | elif line[0:2] == 'vt':
|
---|
43 | currentLine = line.split()
|
---|
44 | uv = glm.vec2(float(currentLine[1]), float(currentLine[2]))
|
---|
45 | temp_uvs.append(uv)
|
---|
46 | elif line[0:2] == 'vn':
|
---|
47 | currentLine = line.split()
|
---|
48 | normal = glm.vec3(float(currentLine[1]), float(currentLine[2]), float(currentLine[3]))
|
---|
49 | temp_normals.append(normal)
|
---|
50 | elif line[0] == 'f':
|
---|
51 | currentLine = line.split()
|
---|
52 | vertexIndex = [0,0,0]
|
---|
53 | uvIndex = [0,0,0]
|
---|
54 | normalIndex = [0,0,0]
|
---|
55 | for i in range(1, 4):
|
---|
56 | trip = currentLine[i].split('/')
|
---|
57 | vertexIndex[i-1] = int(trip[0])
|
---|
58 | if len(trip) > 1:
|
---|
59 | if trip[1]:
|
---|
60 | uvIndex[i-1] = int(trip[1])
|
---|
61 | else:
|
---|
62 | uvIndex[i-1] = 0
|
---|
63 | if len(trip) > 2:
|
---|
64 | normalIndex[i-1] = int(trip[2])
|
---|
65 | vertexIndices.extend(vertexIndex)
|
---|
66 | uvIndices.extend(uvIndex)
|
---|
67 | normalIndices.extend(normalIndex)
|
---|
68 |
|
---|
69 | for i in range(len(vertexIndices)):
|
---|
70 | vertex = temp_vertices[vertexIndices[i] - 1]
|
---|
71 | out_vertices.append(vertex)
|
---|
72 | if temp_uvs:
|
---|
73 | uv = temp_uvs[uvIndices[i] - 1]
|
---|
74 | else:
|
---|
75 | uv = glm.vec2(0)
|
---|
76 | out_uvs.append(uv)
|
---|
77 | if temp_normals:
|
---|
78 | normal = temp_normals[normalIndices[i] - 1]
|
---|
79 | else:
|
---|
80 | normal = glm.vec3(0)
|
---|
81 | out_normals.append(normal)
|
---|
82 |
|
---|
83 | return out_vertices, out_uvs, out_normals
|
---|
84 |
|
---|
85 | @staticmethod
|
---|
86 | def _indexVBO(vertices, uvs, normals):
|
---|
87 | out_indices = []
|
---|
88 | out_vertices = []
|
---|
89 | out_uvs = []
|
---|
90 | out_normals = []
|
---|
91 | vertexToOutIndex = {}
|
---|
92 |
|
---|
93 | for vertex, uv, normal in zip(vertices, uvs, normals):
|
---|
94 | packed = OBJLoader.PackedVertex(vertex, uv, normal)
|
---|
95 | found, index = OBJLoader._getSimilarVertexIndex(packed, vertexToOutIndex)
|
---|
96 |
|
---|
97 | if not found:
|
---|
98 | out_vertices.append(vertex)
|
---|
99 | out_uvs.append(uv)
|
---|
100 | out_normals.append(normal)
|
---|
101 | index = len(out_vertices) - 1
|
---|
102 | vertexToOutIndex[packed] = index
|
---|
103 |
|
---|
104 | out_indices.append(index)
|
---|
105 |
|
---|
106 | return out_indices, out_vertices, out_uvs, out_normals
|
---|
107 |
|
---|
108 | @staticmethod
|
---|
109 | def _getSimilarVertexIndex(vertex, VertexToOutIndex: dict):
|
---|
110 | result = VertexToOutIndex.get(vertex)
|
---|
111 | return True if result else False, result
|
---|
112 |
|
---|
113 | @staticmethod
|
---|
114 | def _vec3ToFloat(vector):
|
---|
115 | out = []
|
---|
116 | for v in vector:
|
---|
117 | out.append(v.x)
|
---|
118 | out.append(v.y)
|
---|
119 | out.append(v.z)
|
---|
120 | return out
|
---|
121 |
|
---|
122 | @staticmethod
|
---|
123 | def _vec2ToFloat(vector):
|
---|
124 | out = []
|
---|
125 | for v in vector:
|
---|
126 | out.append(v.x)
|
---|
127 | out.append(v.y)
|
---|
128 | return out |
---|