def generate_renderable_array_object(self) -> RenderableArray: """Generates RenderableArray object for a portal""" # Hard coded triangle indices as file format only specifies 4 indices triangleIndices: List[IntIterable] = [[0, 1, 2], [0, 2, 3]] currentRenderable = RenderableArray() currentRenderable.materialIndex = R6Constants.UINT_MAX for vertex in self.vertices: currentRenderable.vertices.append(vertex.copy()) #calculate the normal of the first triangle line1 = Vector.subtract_vector(self.vertices[0], self.vertices[1]) line2 = Vector.subtract_vector(self.vertices[1], self.vertices[2]) crossProductNormal = Vector.cross(line1, line2) #use the same normal for all vertices currentRenderable.normals = [] for _ in range(len(currentRenderable.vertices)): currentRenderable.normals.append(crossProductNormal.copy()) #Explicitly state that there are no values for these attributes currentRenderable.UVs = None currentRenderable.vertexColors = None currentRenderable.triangleIndices = triangleIndices return currentRenderable
def generate_renderable_array_for_facegroup(self, facegroup: RSMAPFaceGroup): """ Generates a RenderableArray object from the internal data structure """ renderable = RenderableArray() renderable.materialIndex = facegroup.materialIndex attribList: List[Tuple[int, int]] = [] triangleIndices: List[IntIterable] = [] for i in range(facegroup.faceCount): # Pack triangle indices into sub arrays per face for consistency with RenderableArray format currentTriangleIndices: List[int] = [] currentVertIndices = facegroup.faceVertexIndices[i] currentVertParamIndices = facegroup.faceVertexParamIndices[i] numVerts = len(currentVertIndices) for j in range(numVerts): currentAttribIndices = (currentVertIndices[j], currentVertParamIndices[j]) if currentAttribIndices not in attribList: attribList.append(currentAttribIndices) currentTriangleIndices.append( attribList.index(currentAttribIndices)) triangleIndices.append(currentTriangleIndices) #Create fresh lists for vertexColors and UVs renderable.vertexColors = [] renderable.UVs = [] for currentAttribSet in attribList: # Make sure to copy any arrays so any transforms don't get interferred with in other renderables currentVertex: List[float] = self.vertices[currentAttribSet[0]] currentVertParamIdx = currentAttribSet[1] renderable.vertices.append(currentVertex.copy()) renderable.normals.append( facegroup.vertexParams.normals[currentVertParamIdx].copy()) renderable.UVs.append( facegroup.vertexParams.UVs[currentVertParamIdx].copy()) # Convert color to RenderableArray standard format, RGBA 0.0-1.0 range importedColorCopy: List[float] = facegroup.vertexParams.colors[ currentVertParamIdx].copy() # convert the color to 0.0-1.0 range, rather than 0-255 #TODO: Verify this is no longer needed #importedColor = normalize_color(importedColorCopy) # pad with an alpha value so it's RGBA importedColor = pad_color(importedColorCopy) renderable.vertexColors.append(importedColor) # set the triangle indices renderable.triangleIndices = triangleIndices return renderable
def generate_renderable_arrays_for_mesh(self, mesh): """ Generates a list of RenderableArray objects from the internal data structure """ renderables = [] uniqueMaterials = set() for faceIdx in mesh.faceIndices: currentFace = self.faces[faceIdx] uniqueMaterials.add(currentFace.materialIndex) for materialIdx in uniqueMaterials: attribList = [] triangleIndices = [] #build list of sets of vertices and associated params, and list of new triangle indices for faceIdx in mesh.faceIndices: currentFace = self.faces[faceIdx] if currentFace.materialIndex == materialIdx: # Add this face to the current renderable currentTriangleIndices = [] for vertIndex in range(len(currentFace.vertexIndices)): #Build a list of attributes paired with a vertex, which we can use to reduce total array length in the RenderableArray currentAttribs = (currentFace.vertexIndices[vertIndex], currentFace.paramIndices[vertIndex]) if currentAttribs in attribList: currentTriangleIndices.append(attribList.index(currentAttribs)) else: attribList.append(currentAttribs) currentTriangleIndices.append(attribList.index(currentAttribs)) triangleIndices.append(currentTriangleIndices) currentRenderable = RenderableArray() # fill out new renderable by unravelling and expanding the vertex and param pairs for currentAttribSet in attribList: # Make sure to copy any arrays so any transforms don't get interferred with in other renderables currentVertex = self.vertices[currentAttribSet[0]] currentVertexParams = self.vertexParams[currentAttribSet[1]] currentRenderable.vertices.append(currentVertex.copy()) currentRenderable.normals.append(currentVertexParams.normal.copy()) currentRenderable.UVs.append(currentVertexParams.UV.copy()) # Convert color to RenderableArray standard format, RGBA 0.0-1.0 range importedColor = currentVertexParams.color.copy() # convert the color to 0.0-1.0 range, rather than 0-255 importedColor = normalize_color(importedColor) # pad with an alpha value so it's RGBA importedColor = pad_color(importedColor) currentRenderable.vertexColors.append(importedColor) # Assign the specified material currentRenderable.materialIndex = materialIdx # set the triangle indices currentRenderable.triangleIndices = triangleIndices renderables.append(currentRenderable) return renderables
def generate_renderable_array_for_collisionmesh(self, collisionMesh, geometryData): """Generates RenderableArray objects for each collision mesh defined""" attribList = [] triangleIndices = [] for faceIdx in collisionMesh.faceIndices: currentFace = self.faces[faceIdx] currentVertIndices = currentFace.vertexIndices currentVertNormIndices = currentFace.normalIndices currentTriangleIndices = [] numVerts = len(currentVertIndices) for j in range(numVerts): currentAttribs = (currentVertIndices[j], currentVertNormIndices[j]) if currentAttribs in attribList: currentTriangleIndices.append( attribList.index(currentAttribs)) else: attribList.append(currentAttribs) currentTriangleIndices.append( attribList.index(currentAttribs)) triangleIndices.append(currentTriangleIndices) currentRenderable = RenderableArray() currentRenderable.materialIndex = R6Constants.UINT_MAX for currentAttribSet in attribList: currentVertex = None try: currentVertex = geometryData.vertices[currentAttribSet[0]] #currentNormal = geometryData.normals[currentAttribSet[1]] except IndexError: log.error("Error in mesh. Vertex index out of range") log.error(str(currentAttribSet[0])) log_pprint(collisionMesh.geometryFlags, logging.ERROR) raise IndexError( "A vertex index was out of range, something has gone wrong reading this file." ) currentRenderable.vertices.append(currentVertex.copy()) #currentRenderable.normals.append(currentNormal.copy()) #Explicitly state that there are no values for these attributes currentRenderable.UVs = None currentRenderable.vertexColors = None currentRenderable.triangleIndices = triangleIndices return currentRenderable