def is_point_in_tri(self, P, A, B, C): #Compute vectors v0 = [C[0] - A[0], C[1] - A[1]] v1 = [B[0] - A[0], B[1] - A[1]] v2 = [P[0] - A[0], P[1] - A[1]] #Compute dot products dot00 = MyMaths.vector2ScalarProduct(v0, v0) dot01 = MyMaths.vector2ScalarProduct(v0, v1) dot02 = MyMaths.vector2ScalarProduct(v0, v2) dot11 = MyMaths.vector2ScalarProduct(v1, v1) dot12 = MyMaths.vector2ScalarProduct(v1, v2) #check if denom == 0, discard if neccessary denom = (dot00 * dot11 - dot01 * dot01) if(denom == 0) : return [False,0,0,0] #Compute barycentric coordinates invDenom = 1 / denom u = (dot11 * dot02 - dot01 * dot12) * invDenom v = (dot00 * dot12 - dot01 * dot02) * invDenom #Check if point is in triangle and return the barycentric coords return [(u >= 0) and (v >= 0) and (u + v < 1), u, v, 1 - u - v]
def InitializeCamera (self, angleY) : self.cameraToWorld = [[ 1, 0, 0, 0], [ 0, 1, 0, 0], [ 0, 0, 1, 0], [ 0, 0, 0, 0]] """rotate the camera to have an isometric point of view""" """careful: right handed euler rotation""" self.cameraToWorld = MyMaths.rotateMatrix(self.cameraToWorld, -angleY, -45, 0) self.worldToCamera = MyMaths.transposeMatrix(self.cameraToWorld)
def calculateProjectedBoundaries (self) : maxX = 0 minX = 0 maxY = 0 minY = 0 maxZ = 0 minZ = 0 boundaries = [] for k in range(len(self.meshes)): m = self.meshes[k] count = range(len(m.controlPoints)) for i in count: #control points must be in camera coordinates m.controlPoints[i] = MyMaths.vectorDotMatrix(m.controlPoints[i], self.worldToCamera) m.controlPoints[i] = [m.controlPoints[i][0], -m.controlPoints[i][1], m.controlPoints[i][2]] """check boundaries""" #if (m.controlPoints[i][0] > maxX) : # maxX = m.controlPoints[i][0] #if (m.controlPoints[i][0] < minX) : # minX = m.controlPoints[i][0] #if (m.controlPoints[i][1] > maxY) : # maxY = m.controlPoints[i][1] #if (m.controlPoints[i][1] < minY) : # minY = m.controlPoints[i][1] #if (m.controlPoints[i][2] > maxZ) : # maxZ = m.controlPoints[i][2] #if (m.controlPoints[i][2] < minZ) : # minZ = m.controlPoints[i][2] if (m.controlPoints[i][0] > maxX) : maxX = m.controlPoints[i][0] if (-m.controlPoints[i][0] > maxX) : maxX = -m.controlPoints[i][0] if (m.controlPoints[i][1] > maxY) : maxY = m.controlPoints[i][1] if (-m.controlPoints[i][1] > maxY) : maxY = -m.controlPoints[i][1] if (m.controlPoints[i][2] > maxZ) : maxZ = m.controlPoints[i][2] if (m.controlPoints[i][2] < minZ) : minZ = m.controlPoints[i][2] boundaries.append([maxX, maxY, maxZ, 1]) boundaries.append([maxX, minY, maxZ, 1]) boundaries.append([minX, maxY, maxZ, 1]) boundaries.append([minX, minY, maxZ, 1]) boundaries.append([maxX, maxY, minZ, 1]) boundaries.append([maxX, minY, minZ, 1]) boundaries.append([minX, maxY, minZ, 1]) boundaries.append([minX, minY, minZ, 1]) return boundaries
def __init__(self, rnd, par, rad, pos=Vex(0, 0, 0), dir=False, minSize=2, maxSize=4): self.rnd = rnd self.parent = par self.pos = pos self.scale = Vex(.5, .5) self.rot = math.radians(self.rnd.randint(0, 360)) self.ang = math.radians(self.rnd.randint(0, 360)) self.rotsp = self.rnd.uniform(-.1, .1) self.speed = self.rnd.uniform(.1, 3) if dir: self.speed = -self.speed self.edges = [] rc = self.rnd.randint(25, 255) self.color = (rc, rc, rc) self.corHealth = 150 mi = 0 self.points = [] self.projectedPoints = [] size = self.rnd.randint(8, 16) step = 360.0 / size for i in range(0, size): sx = math.sin(math.radians(step * i)) sy = math.cos(math.radians(step * i)) d = MyMaths.rand2Dinst(sx, sy, self.rnd) / 2 + 2 tv = Vex(sx * d, sy * d) self.points += [tv] self.projectedPoints += [0, 0] for i in range(mi, len(self.points)): if i + 1 < len(self.points): self.edges.append((i, i + 1)) else: self.edges.append((i, mi)) mi = i + 1
def SetWorldBoundaries (self, bound) : maxX = 0 maxY = 0 maxZ = 0 minX = 0 minY = 0 minZ = 0 self.worldBoundaries = bound count = range(len(self.worldBoundaries)) for i in count: """project bounding box points""" self.worldBoundaries[i] = MyMaths.vectorDotMatrix(self.worldBoundaries[i], self.worldToCamera) self.worldBoundaries[i] = [self.worldBoundaries[i][0], -self.worldBoundaries[i][1], self.worldBoundaries[i][2]] """check boundaries""" if (self.worldBoundaries[i][0] > maxX) : maxX = self.worldBoundaries[i][0] if (self.worldBoundaries[i][0] < minX) : minX = self.worldBoundaries[i][0] if (self.worldBoundaries[i][1] > maxY) : maxY = self.worldBoundaries[i][1] if (self.worldBoundaries[i][1] < minY) : minY = self.worldBoundaries[i][1] if (self.worldBoundaries[i][2] > maxZ) : maxZ = self.worldBoundaries[i][2] if (self.worldBoundaries[i][2] < minZ) : minZ = self.worldBoundaries[i][2] self.renderXRange = maxX - minX self.renderYRange = maxY - minY self.ZRange = maxZ - minZ self.minProjX = minX self.minProjY = minY self.minZ = minZ self.aspectRatio = self.renderYRange/self.renderYRange
def projectControlPoints (self) : """transform to camera coordinates and project each control point of each mesh""" count = range(len(self.mesh.controlPoints)) for i in count: #control points must be in world coordinates """controlPoints world->camera space""" self.mesh.controlPoints[i] = MyMaths.vectorDotMatrix(self.mesh.controlPoints[i], self.worldToCamera) self.mesh.controlPoints[i] = [self.mesh.controlPoints[i][0], -self.mesh.controlPoints[i][1], self.mesh.controlPoints[i][2]] """normalize respect the image size and adapt to screen coordinates (Y axis inverted)""" self.mesh.controlPoints[i] = [self.mesh.controlPoints[i][0] - self.minProjX, self.mesh.controlPoints[i][1] - self.minProjY, self.mesh.controlPoints[i][2] - self.minZ] #self.mesh.controlPoints[i] = [self.mesh.controlPoints[i][0]/self.renderXRange*self.imageWidth, self.mesh.controlPoints[i][1]/self.renderYRange*self.imageHeight, (self.mesh.controlPoints[i][2])/self.ZRange] if(self.aspectRatio < 1) : self.mesh.controlPoints[i] = [self.mesh.controlPoints[i][0]/self.renderXRange*self.imageWidth + self.imageWidth*0.25, self.mesh.controlPoints[i][1]/self.renderXRange*self.imageWidth + self.imageWidth*0.3, (self.mesh.controlPoints[i][2])/self.ZRange] if(self.aspectRatio >= 1) : self.mesh.controlPoints[i] = [self.mesh.controlPoints[i][0]/self.renderYRange*self.imageHeight + self.imageHeight*0.25, self.mesh.controlPoints[i][1]/self.renderYRange*self.imageHeight + self.imageHeight*0.3, (self.mesh.controlPoints[i][2])/self.ZRange] return
def exploreMesh (self, node) : mesh = node.GetMesh() m = MyMesh() m.node = node; (m.bones, m.vertexBoneBindings) = self.extractSkinWeights(mesh) mesh_uvs = mesh.GetLayer( 0 ).GetUVs() if( not mesh_uvs ): print "Scene: Error, No UV coordinates found for the mesh" return if( mesh_uvs.GetMappingMode() != 2 ): print "Scene: Error, UV mapping mode not supported, please use EMappingMode.eByPolygonVertex" return uvs_array = mesh_uvs.GetDirectArray() uvs_count = uvs_array.GetCount() uv_values = [] uv_indices = [] for k in range( uvs_count ): uv = uvs_array.GetAt( k ) uv = [ uv[ 0 ], uv[ 1 ] ] uv_values.append( uv ) m.textureCoordinates = uv_values self.extractTextures(node, m.textures) fbxMatrix = fbx.FbxAMatrix() fbxMatrix = node.EvaluateGlobalTransform(self.time) for i in range (0, 4) : for j in range (0, 4) : m.transform[i][j] = fbxMatrix.Get(i, j) #print 'Scene: skinning mesh '+str(len(self.meshes)) cPoints = mesh.GetControlPoints(); count = list(range(len(cPoints))) for i in count: #local-space p = [cPoints[i][0], cPoints[i][1], cPoints[i][2], 1] #to world-space coordinates p = MyMaths.vectorDotMatrix(p, m.transform) vertexToInterpolate = [] #one per bone skinned if(len(m.bones) != 0) : boneCount = len(m.vertexBoneBindings[i]) for j in range(0,boneCount) : boneIndex = m.vertexBoneBindings[i][j] #if weight is 0, discard weight = m.bones[boneIndex].vertexWeightsArray[i] if weight == 0 : continue #for Vertex -> get world coords in t=0, set vertex in bone-space, get vertex back to world-space with the bone's transform in t=x boneNode = self.GetNode(self.root, m.bones[boneIndex].name) vertex = p t0 = fbx.FbxTime() t0.SetFrame(0) #boneTransform0 = self.animationEvaluator.GetNodeGlobalTransform(boneNode, t0) boneInvTransform0 = m.bones[boneIndex].inverseBindPose myboneInvTransform0 = [[ 1, 0, 0, 0],[ 0, 1, 0, 0],[ 0, 0, 1, 0],[ 0, 0, 0, 0]] for y in range (0, 4) : for z in range (0, 4) : myboneInvTransform0[y][z] = boneInvTransform0.Get(y, z) #myboneInvTransform0 = MyMaths.transposeMatrix(myboneTransform0) pInBoneCoords0 = MyMaths.vectorDotMatrix(vertex, myboneInvTransform0) """boneTransformT = self.animationEvaluator.GetNodeGlobalTransform(boneNode, self.time) #frame x myboneTransformT = [[ 1, 0, 0, 0],[ 0, 1, 0, 0],[ 0, 0, 1, 0],[ 0, 0, 0, 0]] for y in range (0, 4) : for z in range (0, 4) : myboneTransformT[y][z] = boneTransformT.Get(y, z) vertex = MyMaths.vectorDotMatrix(pInBoneCoords0, myboneTransformT)""" boneTransform0 = m.bones[boneIndex].boneMatrixT myboneTransform0 = [[ 1, 0, 0, 0],[ 0, 1, 0, 0],[ 0, 0, 1, 0],[ 0, 0, 0, 0]] for y in range (0, 4) : for z in range (0, 4) : myboneTransform0[y][z] = boneTransform0.Get(y, z) #myboneInvTransform0 = MyMaths.transposeMatrix(myboneTransform0) vertex = MyMaths.vectorDotMatrix(pInBoneCoords0, myboneTransform0) #apply bone weight vertex = [vertex[0]*weight, vertex[1]*weight, vertex[2]*weight, 1] vertexToInterpolate.append(vertex) if len(vertexToInterpolate) > 0 : p = [0, 0, 0] for n in range(0, len(vertexToInterpolate)) : p = [p[0] + vertexToInterpolate[n][0], p[1] + vertexToInterpolate[n][1], p[2] + vertexToInterpolate[n][2], 1] m.controlPoints.append(p) # skinning finished polygonCount = mesh.GetPolygonCount() count = list(range(polygonCount)) vertex_id = 0 for i in count: # Get indices for the current triangle _indices = [] poly_uvs = [] # Check if the polygon is facing the camera, discard it if not for j in range(0, 3): _indices.append(mesh.GetPolygonVertex(i, j)) uv_texture_index = mesh_uvs.GetIndexArray().GetAt(vertex_id) poly_uvs.append( uv_texture_index ) vertex_id += 1 v1 = m.controlPoints[_indices[0]] v2 = m.controlPoints[_indices[1]] v3 = m.controlPoints[_indices[2]] v1v2 = [v2[0]-v1[0], v2[1]-v1[1], v2[2]-v1[2], 0] v1v3 = [v3[0]-v1[0], v3[1]-v1[1], v3[2]-v1[2], 1] normal = MyMaths.vector4CrossProduct(v1v2, v1v3) if (MyMaths.vector4ScalarProduct(normal, self.cameraToWorld[2]) > 0) : m.vertexIndicesArray.append(_indices) m.uvCoordsIndexArray.append(poly_uvs) self.meshes.append(m) return