def generateNormals(self): """If :attr:`normals` is `None` or you wish for normals to be recomputed, call this method to recompute them.""" norms = numpy.zeros(self._vertex.shape, dtype=self._vertex.dtype) tris = self._vertex[self._vertex_index] n = numpy.cross(tris[::, 1] - tris[::, 0], tris[::, 2] - tris[::, 0]) normalize_v3(n) norms[self._vertex_index[:, 0]] += n norms[self._vertex_index[:, 1]] += n norms[self._vertex_index[:, 2]] += n normalize_v3(norms) self._normal = norms self._normal_index = self._vertex_index
def __init__(self, inFileName): # inputFilename = sys.argv[1] col = collada.Collada( inFileName, ignore=[collada.DaeUnsupportedError, collada.DaeBrokenRefError]) if col.scene is not None: for geom in col.scene.objects('geometry'): for prim in geom.primitives(): # use primitive-specific ways to get triangles prim_type = type(prim).__name__ if prim_type == 'BoundTriangleSet': triangles = prim elif prim_type == 'BoundPolylist': triangles = prim.triangleset() else: print 'Unsupported mesh used:', prim_type triangles = None if triangles is not None: # # triangles.generateNormals() vertices = triangles.vertex #.flatten().tolist() vertex_indices = triangles.vertex_index #.flatten().tolist() VERTICES = vertices[vertex_indices] normals = triangles.normal normal_indices = triangles.normal_index # .flatten().tolist() NORMALS = normals[normal_indices] uv = triangles.texcoordset[0] uv_indices = triangles.texcoord_indexset[0] UV = uv[uv_indices] x1 = VERTICES[:, 1, 0] - VERTICES[:, 0, 0] x2 = VERTICES[:, 2, 0] - VERTICES[:, 0, 0] y1 = VERTICES[:, 1, 1] - VERTICES[:, 0, 1] y2 = VERTICES[:, 2, 1] - VERTICES[:, 0, 1] z1 = VERTICES[:, 1, 2] - VERTICES[:, 0, 2] z2 = VERTICES[:, 2, 2] - VERTICES[:, 0, 2] s1 = UV[:, 1, 0] - UV[:, 0, 0] s2 = UV[:, 2, 0] - UV[:, 0, 0] t1 = UV[:, 1, 1] - UV[:, 0, 1] t2 = UV[:, 2, 1] - UV[:, 0, 1] f = 1.0 / (s1 * t2 - s2 * t1) tanX = (x1 * t2 - x2 * t1) * f tanY = (y1 * t2 - y2 * t1) * f tanZ = (z1 * t2 - z2 * t1) * f tangent = numpy.vstack((tanX, tanY, tanZ)).T TANGENTS = normalize_v3( tangent) # one tangent for triangle face BINORMALS = numpy.cross( NORMALS, tangent) # one BINORMALS for triangle face self.VERTICES = VERTICES self.NORMALS = NORMALS self.UV = UV self.TANGENTS = TANGENTS self.BINORMALS = BINORMALS
def __init__(self, inFileName): # inputFilename = sys.argv[1] col = collada.Collada(inFileName, ignore=[collada.DaeUnsupportedError, collada.DaeBrokenRefError]) if col.scene is not None: for geom in col.scene.objects('geometry'): for prim in geom.primitives(): # use primitive-specific ways to get triangles prim_type = type(prim).__name__ if prim_type == 'BoundTriangleSet': triangles = prim elif prim_type == 'BoundPolylist': triangles = prim.triangleset() else: print 'Unsupported mesh used:', prim_type triangles = None if triangles is not None: # # triangles.generateNormals() vertices = triangles.vertex #.flatten().tolist() vertex_indices = triangles.vertex_index #.flatten().tolist() VERTICES = vertices[vertex_indices] normals = triangles.normal normal_indices = triangles.normal_index # .flatten().tolist() NORMALS = normals[normal_indices] uv = triangles.texcoordset[0] uv_indices = triangles.texcoord_indexset[0] UV = uv[uv_indices] x1 = VERTICES[:,1,0] - VERTICES[:,0,0] x2 = VERTICES[:,2,0] - VERTICES[:,0,0] y1 = VERTICES[:,1,1] - VERTICES[:,0,1] y2 = VERTICES[:,2,1] - VERTICES[:,0,1] z1 = VERTICES[:,1,2] - VERTICES[:,0,2] z2 = VERTICES[:,2,2] - VERTICES[:,0,2] s1 = UV[:,1,0] - UV[:,0,0] s2 = UV[:,2,0] - UV[:,0,0] t1 = UV[:,1,1] - UV[:,0,1] t2 = UV[:,2,1] - UV[:,0,1] f = 1.0 / (s1 * t2 - s2 * t1) tanX = (x1 * t2 - x2 * t1) * f tanY = (y1 * t2 - y2 * t1) * f tanZ = (z1 * t2 - z2 * t1) * f tangent = numpy.vstack((tanX, tanY, tanZ)).T TANGENTS = normalize_v3(tangent) # one tangent for triangle face BINORMALS = numpy.cross(NORMALS, tangent) # one BINORMALS for triangle face self.VERTICES = VERTICES self.NORMALS = NORMALS self.UV = UV self.TANGENTS = TANGENTS self.BINORMALS = BINORMALS
def generateTexTangentsAndBinormals(self): """If there are no texture tangents, this method will compute them. Texture coordinates must exist and it uses the first texture coordinate set.""" #The following is taken from: # http://www.terathon.com/code/tangent.html # It's pretty much a direct translation, using numpy arrays tris = self._vertex[self._vertex_index] uvs = self._texcoordset[0][self._texcoord_indexset[0]] x1 = tris[:, 1, 0] - tris[:, 0, 0] x2 = tris[:, 2, 0] - tris[:, 1, 0] y1 = tris[:, 1, 1] - tris[:, 0, 1] y2 = tris[:, 2, 1] - tris[:, 1, 1] z1 = tris[:, 1, 2] - tris[:, 0, 2] z2 = tris[:, 2, 2] - tris[:, 1, 2] s1 = uvs[:, 1, 0] - uvs[:, 0, 0] s2 = uvs[:, 2, 0] - uvs[:, 1, 0] t1 = uvs[:, 1, 1] - uvs[:, 0, 1] t2 = uvs[:, 2, 1] - uvs[:, 1, 1] r = 1.0 / (s1 * t2 - s2 * t1) sdirx = (t2 * x1 - t1 * x2) * r sdiry = (t2 * y1 - t1 * y2) * r sdirz = (t2 * z1 - t1 * z2) * r sdir = numpy.vstack((sdirx, sdiry, sdirz)).T tans1 = numpy.zeros(self._vertex.shape, dtype=self._vertex.dtype) tans1[self._vertex_index[:, 0]] += sdir tans1[self._vertex_index[:, 1]] += sdir tans1[self._vertex_index[:, 2]] += sdir norm = self._normal[self._normal_index] norm.shape = (-1, 3) tan1 = tans1[self._vertex_index] tan1.shape = (-1, 3) tangent = normalize_v3(tan1 - norm * dot_v3(norm, tan1)[:, numpy.newaxis]) self._textangentset = (tangent, ) self._textangent_indexset = (numpy.arange( len(self._vertex_index) * 3, dtype=self._vertex_index.dtype), ) self._textangent_indexset[0].shape = (len(self._vertex_index), 3) tdirx = (s1 * x2 - s2 * x1) * r tdiry = (s1 * y2 - s2 * y1) * r tdirz = (s1 * z2 - s2 * z1) * r tdir = numpy.vstack((tdirx, tdiry, tdirz)).T tans2 = numpy.zeros(self._vertex.shape, dtype=self._vertex.dtype) tans2[self._vertex_index[:, 0]] += tdir tans2[self._vertex_index[:, 1]] += tdir tans2[self._vertex_index[:, 2]] += tdir tan2 = tans2[self._vertex_index] tan2.shape = (-1, 3) tanw = dot_v3(numpy.cross(norm, tan1), tan2) tanw = numpy.sign(tanw) binorm = numpy.cross(norm, tangent).flatten() binorm.shape = (-1, 3) binorm = binorm * tanw[:, numpy.newaxis] self._texbinormalset = (binorm, ) self._texbinormal_indexset = (numpy.arange( len(self._vertex_index) * 3, dtype=self._vertex_index.dtype), ) self._texbinormal_indexset[0].shape = (len(self._vertex_index), 3)
def generateTexTangentsAndBinormals(self): """If there are no texture tangents, this method will compute them. Texture coordinates must exist and it uses the first texture coordinate set.""" # The following is taken from: # http://www.terathon.com/code/tangent.html # It's pretty much a direct translation, using numpy arrays tris = self._vertex[self._vertex_index] uvs = self._texcoordset[0][self._texcoord_indexset[0]] x1 = tris[:, 1, 0] - tris[:, 0, 0] x2 = tris[:, 2, 0] - tris[:, 1, 0] y1 = tris[:, 1, 1] - tris[:, 0, 1] y2 = tris[:, 2, 1] - tris[:, 1, 1] z1 = tris[:, 1, 2] - tris[:, 0, 2] z2 = tris[:, 2, 2] - tris[:, 1, 2] s1 = uvs[:, 1, 0] - uvs[:, 0, 0] s2 = uvs[:, 2, 0] - uvs[:, 1, 0] t1 = uvs[:, 1, 1] - uvs[:, 0, 1] t2 = uvs[:, 2, 1] - uvs[:, 1, 1] r = 1.0 / (s1 * t2 - s2 * t1) sdirx = (t2 * x1 - t1 * x2) * r sdiry = (t2 * y1 - t1 * y2) * r sdirz = (t2 * z1 - t1 * z2) * r sdir = numpy.vstack((sdirx, sdiry, sdirz)).T tans1 = numpy.zeros(self._vertex.shape, dtype=self._vertex.dtype) tans1[self._vertex_index[:, 0]] += sdir tans1[self._vertex_index[:, 1]] += sdir tans1[self._vertex_index[:, 2]] += sdir norm = self._normal[self._normal_index] norm.shape = (-1, 3) tan1 = tans1[self._vertex_index] tan1.shape = (-1, 3) tangent = normalize_v3(tan1 - norm * dot_v3(norm, tan1)[:, numpy.newaxis]) self._textangentset = (tangent,) self._textangent_indexset = (numpy.arange(len(self._vertex_index) * 3, dtype=self._vertex_index.dtype),) self._textangent_indexset[0].shape = (len(self._vertex_index), 3) tdirx = (s1 * x2 - s2 * x1) * r tdiry = (s1 * y2 - s2 * y1) * r tdirz = (s1 * z2 - s2 * z1) * r tdir = numpy.vstack((tdirx, tdiry, tdirz)).T tans2 = numpy.zeros(self._vertex.shape, dtype=self._vertex.dtype) tans2[self._vertex_index[:, 0]] += tdir tans2[self._vertex_index[:, 1]] += tdir tans2[self._vertex_index[:, 2]] += tdir tan2 = tans2[self._vertex_index] tan2.shape = (-1, 3) tanw = dot_v3(numpy.cross(norm, tan1), tan2) tanw = numpy.sign(tanw) binorm = numpy.cross(norm, tangent).flatten() binorm.shape = (-1, 3) binorm = binorm * tanw[:, numpy.newaxis] self._texbinormalset = (binorm,) self._texbinormal_indexset = (numpy.arange(len(self._vertex_index) * 3, dtype=self._vertex_index.dtype),) self._texbinormal_indexset[0].shape = (len(self._vertex_index), 3)
def normal_vector(a, b, c): direction = numpy.cross(b - a, c - a) normalize_v3(direction[None, :]) return direction