[1198] | 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 |
---|