def gen_polygons_cdnp(pdnp, name='cdnp_polygons', radius=.01): """ :param trimeshmodel: :param name: :param radius: TODO :return: author: weiwei date: 20210204 """ collision_node = CollisionNode(name) # counter = 0 for geom in pdnp.findAllMatches('**/+GeomNode'): geom_node = geom.node() for g in range(geom_node.getNumGeoms()): geom = geom_node.getGeom(g).decompose() vdata = geom.getVertexData() vreader = GeomVertexReader(vdata, 'vertex') for p in range(geom.getNumPrimitives()): prim = geom.getPrimitive(p) for p2 in range(prim.getNumPrimitives()): s = prim.getPrimitiveStart(p2) e = prim.getPrimitiveEnd(p2) v = [] for vi in range(s, e): vreader.setRow(prim.getVertex(vi)) # TODO expand radius by moving along normal directions v.append(vreader.getData3f()) col_poly = CollisionPolygon(*v) collision_node.addSolid(col_poly) # print("polygon ", counter) # counter += 1 return collision_node
def make_nav_graph(self, mesh, edge_neighbors_only=True, draw_graph=False): '''Creates a navigation graph from a 3D mesh, A node is created for each triangle in the mesh, nodes are connected either by shared edges (edge_neighbors_only=True), or by shared vertex (edge_neighbors_only=False). ''' _get_center=self._get_center _get_neighbors=self._get_neighbors _distance=self._distance _round_vec3_to_tuple=self._round_vec3_to_tuple #make a list of the triangles #get the id of each vert in each triangle and #get the position of each vert triangles=[] vert_dict=defaultdict(set) #only works ok with one geom so flatten the mesh befor comming here geom=self.find_first_geom(mesh) vdata = geom.getVertexData() vertex = GeomVertexReader(vdata, 'vertex') for prim in geom.getPrimitives(): num_primitives=prim.getNumPrimitives() for p in range(num_primitives): #print ('primitive {} of {}'.format(p, num_primitives)) s = prim.getPrimitiveStart(p) e = prim.getPrimitiveEnd(p) triangle={'vertex_id':[], 'vertex_pos':[]} for i in range(s, e): vi = prim.getVertex(i) vertex.setRow(vi) v =[round(i, 4) for i in vertex.getData3f() ] vertex_id=tuple([round(i*4.0)/4.0 for i in v]) triangle['vertex_pos'].append(v) triangle['vertex_id'].append(vertex_id) vert_dict[vertex_id].add(len(triangles))#len(self.triangles) is the triangle id triangles.append(triangle) #get centers and neighbors for i, triangle in enumerate(triangles): #print ('triangle ', i ,' of ', len(self.triangles) ) triangle['center']=_get_center(triangle['vertex_pos']) triangle['neighbors']=_get_neighbors(triangle['vertex_id'], vert_dict, i, edge_neighbors_only) #construct the dict edges={} cost={} positions={} for i, triangle in enumerate(triangles): #print ('neighbor ', i) edges[i]=triangle['neighbors'] cost[i]={} start=triangle['center'] positions[i]=start for neighbor in triangle['neighbors']: cost[i][neighbor]=_distance(start, triangles[neighbor]['center']) lookup={_round_vec3_to_tuple(value):key for (key, value) in positions.items()} self.graph= {'neighbors':edges, 'cost':cost, 'pos':positions, 'lookup':lookup} if draw_graph: self.draw_connections()
def getTriangleAsPoints(self, ind, vreader=None): if vreader is None: vreader = GeomVertexReader(self.vdata, 'vertex') pts = [] for vi in self.getTriangleVertexIndices(ind): vreader.setRow(vi) pt = vreader.getData3f() pts.append(Point3(*pt)) return Triangle.TriangleTuple(pts[0], pts[1], pts[2])
def processPrimitive(prim, vdata, mesh): vertex = GeomVertexReader(vdata, 'vertex') prim = prim.decompose() for p in range(prim.getNumPrimitives()): s = prim.getPrimitiveStart(p) e = prim.getPrimitiveEnd(p) vertices = [] for i in range(s, e): vi = prim.getVertex(i) vertices.append(vi) vertex.setRow(vi) v = vertex.getData3f() print("prim %s has vertex %s: %s" % (p, vi, repr(v))) mesh.add_face(f=vertices)
def get3DTrianglesFromModel(model): # Calculate the net transformation transform = model.getNetTransform() transformMat = transform.getMat() # Get geometry data from GeomNode instances inside the model geomNodes = model.findAllMatches('**/+GeomNode') triangles = [] for nodePath in geomNodes: geomNode = nodePath.node() for n in range(geomNode.getNumGeoms()): geom = geomNode.getGeom(n) vdata = geom.getVertexData() for k in range(geom.getNumPrimitives()): prim = geom.getPrimitive(k) vertex = GeomVertexReader(vdata, 'vertex') assert isinstance(prim, (GeomTristrips, GeomTriangles)) # Decompose into triangles prim = prim.decompose() for p in range(prim.getNumPrimitives()): s = prim.getPrimitiveStart(p) e = prim.getPrimitiveEnd(p) triPts = [] for i in range(s, e): vi = prim.getVertex(i) vertex.setRow(vi) v = vertex.getData3f() # Apply transformation v = transformMat.xformPoint(v) triPts.append([v.x, v.y, v.z]) triangles.append(triPts) triangles = np.array(triangles) return triangles
def processPrimitive(prim, vdata): vertex = GeomVertexReader(vdata, 'vertex') prim = prim.decompose() for p in range(prim.getNumPrimitives()): s = prim.getPrimitiveStart(p) e = prim.getPrimitiveEnd(p) last = None roadBuilder.addPrim() for i in range(s, e): vi = prim.getVertex(i) vertex.setRow(vi) v = vertex.getData3() if last is not None: self.road_segments.append([last, v]) roadBuilder.addSegment(last, v) last = v
def completeTunnelPath(self): self.geomNode.addGeom(self.geom) if self.triStrips.getNumPrimitives() == 0: return floorMesh = CollisionFloorMesh() vertexReader = GeomVertexReader(self.vertexData, 'vertex') print "Original prims:", self.triStrips.getNumPrimitives() p = 0 for i in range(self.triStrips.getNumPrimitives()): v0 = self.triStrips.getPrimitiveStart(i) ve = self.triStrips.getPrimitiveEnd(i) j = v0 + 4 # add the bottom triangles vertexReader.setRow(self.triStrips.getVertex(j)) floorMesh.addVertex(Point3(vertexReader.getData3f())) vertexReader.setRow(self.triStrips.getVertex(j + 1)) floorMesh.addVertex(Point3(vertexReader.getData3f())) vertexReader.setRow(self.triStrips.getVertex(j + 2)) floorMesh.addVertex(Point3(vertexReader.getData3f())) floorMesh.addTriangle(p, p + 1, p + 2) vertexReader.setRow(self.triStrips.getVertex(j + 3)) floorMesh.addVertex(Point3(vertexReader.getData3f())) floorMesh.addTriangle(p + 1, p + 3, p + 2) p += 4 # this adds every triangle, but is not appropriate for a closed path # tris = self.triStrips.decompose() # print "Decomposed prims:",tris.getNumPrimitives() # p = 0 # for i in range(tris.getNumPrimitives()): # v0 = tris.getPrimitiveStart(i) # ve = tris.getPrimitiveEnd(i) # if v0 < ve: # vertexReader.setRow(tris.getVertex(v0)) # floorMesh.addVertex(Point3(vertexReader.getData3f())) # vertexReader.setRow(tris.getVertex(v0+1)) # floorMesh.addVertex(Point3(vertexReader.getData3f())) # vertexReader.setRow(tris.getVertex(v0+2)) # floorMesh.addVertex(Point3(vertexReader.getData3f())) # floorMesh.addTriangle(p, p+1, p+2) # p += 3 self.floorCollNode.addSolid(floorMesh)
def completeQuadPath(self): self.geomNode.addGeom(self.geom) if self.triStrips.getNumPrimitives() == 0: return floorMesh = CollisionFloorMesh() vertexReader = GeomVertexReader(self.vertexData, 'vertex') tris = self.triStrips.decompose() print "Decomposed prims:", tris.getNumPrimitives() p = 0 for i in range(tris.getNumPrimitives()): v0 = tris.getPrimitiveStart(i) ve = tris.getPrimitiveEnd(i) if v0 < ve: vertexReader.setRow(tris.getVertex(v0)) floorMesh.addVertex(Point3(vertexReader.getData3f())) vertexReader.setRow(tris.getVertex(v0 + 1)) floorMesh.addVertex(Point3(vertexReader.getData3f())) vertexReader.setRow(tris.getVertex(v0 + 2)) floorMesh.addVertex(Point3(vertexReader.getData3f())) floorMesh.addTriangle(p, p + 1, p + 2) p += 3 self.floorCollNode.addSolid(floorMesh)
def completeTunnelPath(self): self.geomNode.addGeom(self.geom) if self.triStrips.getNumPrimitives() == 0: return floorMesh = CollisionFloorMesh() vertexReader = GeomVertexReader(self.vertexData, 'vertex') print "Original prims:",self.triStrips.getNumPrimitives() p = 0 for i in range(self.triStrips.getNumPrimitives()): v0 = self.triStrips.getPrimitiveStart(i) ve = self.triStrips.getPrimitiveEnd(i) j = v0 + 4 # add the bottom triangles vertexReader.setRow(self.triStrips.getVertex(j)) floorMesh.addVertex(Point3(vertexReader.getData3f())) vertexReader.setRow(self.triStrips.getVertex(j+1)) floorMesh.addVertex(Point3(vertexReader.getData3f())) vertexReader.setRow(self.triStrips.getVertex(j+2)) floorMesh.addVertex(Point3(vertexReader.getData3f())) floorMesh.addTriangle(p, p+1, p+2) vertexReader.setRow(self.triStrips.getVertex(j+3)) floorMesh.addVertex(Point3(vertexReader.getData3f())) floorMesh.addTriangle(p+1, p+3, p+2) p += 4 # this adds every triangle, but is not appropriate for a closed path # tris = self.triStrips.decompose() # print "Decomposed prims:",tris.getNumPrimitives() # p = 0 # for i in range(tris.getNumPrimitives()): # v0 = tris.getPrimitiveStart(i) # ve = tris.getPrimitiveEnd(i) # if v0 < ve: # vertexReader.setRow(tris.getVertex(v0)) # floorMesh.addVertex(Point3(vertexReader.getData3f())) # vertexReader.setRow(tris.getVertex(v0+1)) # floorMesh.addVertex(Point3(vertexReader.getData3f())) # vertexReader.setRow(tris.getVertex(v0+2)) # floorMesh.addVertex(Point3(vertexReader.getData3f())) # floorMesh.addTriangle(p, p+1, p+2) # p += 3 self.floorCollNode.addSolid(floorMesh)
def rebuildGeomNodesToColPolys(incomingNode, relativeTo=None, filter=lambda n: True): ''' Converts GeomNodes into CollisionPolys in a straight 1-to-1 conversion Returns a new NodePath containing the CollisionNodes If the geometry is at all complex, running the result of this through colTree should improve performance. ''' parent = NodePath('cGeomConversionParent') for c in incomingNode.findAllMatches('**/+GeomNode'): if not filter(c): continue if relativeTo: xform = c.getMat(relativeTo).xformPoint else: xform = (c.getMat(incomingNode) * (incomingNode.getMat())).xformPoint geomNode = c.node() for g in range(geomNode.getNumGeoms()): geom = geomNode.getGeom(g).decompose() vdata = geom.getVertexData() vreader = GeomVertexReader(vdata, 'vertex') cChild = CollisionNode("") for p in range(geom.getNumPrimitives()): prim = geom.getPrimitive(p) for p2 in range(prim.getNumPrimitives()): s = prim.getPrimitiveStart(p2) e = prim.getPrimitiveEnd(p2) if e - s > 2: v = [] for vi in range(s, e): vreader.setRow(prim.getVertex(vi)) v.append(Point3(xform(vreader.getData3f()))) colPoly = CollisionPolygon(*v) cChild.addSolid(colPoly) n = parent.attachNewNode(cChild) return parent
def completePath(self): self.geomNode.addGeom(self.geom) if self.triStrips.getNumPrimitives() == 0: return floorMesh = CollisionFloorMesh() tris = self.triStrips.decompose() p = 0 vertexReader = GeomVertexReader(self.vertexData, "vertex") for i in range(tris.getNumPrimitives()): v0 = tris.getPrimitiveStart(i) ve = tris.getPrimitiveEnd(i) if v0 < ve: vertexReader.setRow(tris.getVertex(v0)) floorMesh.addVertex(Point3(vertexReader.getData3f())) vertexReader.setRow(tris.getVertex(v0 + 1)) floorMesh.addVertex(Point3(vertexReader.getData3f())) vertexReader.setRow(tris.getVertex(v0 + 2)) floorMesh.addVertex(Point3(vertexReader.getData3f())) floorMesh.addTriangle(p, p + 1, p + 2) p += 3 self.floorCollNode.addSolid(floorMesh)
def rebuildGeomNodesToColPolys (incomingNode,relativeTo=None): ''' Converts GeomNodes into CollisionPolys in a straight 1-to-1 conversion Returns a new NodePath containing the CollisionNodes ''' parent = NodePath('cGeomConversionParent') for c in incomingNode.findAllMatches('**/+GeomNode'): if relativeTo: xform=c.getMat(relativeTo).xformPoint else: xform=(c.getMat(incomingNode)*(incomingNode.getMat())).xformPoint gni = 0 geomNode = c.node() for g in range(geomNode.getNumGeoms()): geom = geomNode.getGeom(g).decompose() vdata = geom.getVertexData() vreader = GeomVertexReader(vdata, 'vertex') cChild = CollisionNode('cGeom-%s-gni%i' % (c.getName(), gni)) gni += 1 for p in range(geom.getNumPrimitives()): prim = geom.getPrimitive(p) for p2 in range(prim.getNumPrimitives()): s = prim.getPrimitiveStart(p2) e = prim.getPrimitiveEnd(p2) v = [] for vi in range (s, e): vreader.setRow(prim.getVertex(vi)) v.append (xform(vreader.getData3f())) colPoly = CollisionPolygon(*v) cChild.addSolid(colPoly) n=parent.attachNewNode (cChild) #n.show() return parent
def getSurfaceAreaFromGeom(geom, transform=None): totalArea = 0.0 for k in range(geom.getNumPrimitives()): prim = geom.getPrimitive(k) vdata = geom.getVertexData() vertex = GeomVertexReader(vdata, 'vertex') assert isinstance(prim, (GeomTristrips, GeomTriangles)) # Decompose into triangles prim = prim.decompose() for p in range(prim.getNumPrimitives()): s = prim.getPrimitiveStart(p) e = prim.getPrimitiveEnd(p) triPts = [] for i in range(s, e): vi = prim.getVertex(i) vertex.setRow(vi) v = vertex.getData3f() # Apply transformation if transform is not None: v = transform.xformPoint(v) triPts.append([v.x, v.y, v.z]) triPts = np.array(triPts) # calculate the semi-perimeter and area a = np.linalg.norm(triPts[0] - triPts[1], 2) b = np.linalg.norm(triPts[1] - triPts[2], 2) c = np.linalg.norm(triPts[2] - triPts[0], 2) s = (a + b + c) / 2 area = (s*(s-a)*(s-b)*(s-c)) ** 0.5 totalArea += area return totalArea
def rebuildGeomNodesToColPolys (incomingNode,relativeTo=None,filter=lambda n:True): ''' Converts GeomNodes into CollisionPolys in a straight 1-to-1 conversion Returns a new NodePath containing the CollisionNodes If the geometry is at all complex, running the result of this through colTree should improve performance. ''' parent = NodePath('cGeomConversionParent') for c in incomingNode.findAllMatches('**/+GeomNode'): if not filter(c): continue if relativeTo: xform=c.getMat(relativeTo).xformPoint else: xform=(c.getMat(incomingNode)*(incomingNode.getMat())).xformPoint geomNode = c.node() for g in range(geomNode.getNumGeoms()): geom = geomNode.getGeom(g).decompose() vdata = geom.getVertexData() vreader = GeomVertexReader(vdata, 'vertex') cChild = CollisionNode("") for p in range(geom.getNumPrimitives()): prim = geom.getPrimitive(p) for p2 in range(prim.getNumPrimitives()): s = prim.getPrimitiveStart(p2) e = prim.getPrimitiveEnd(p2) if e-s>2: v = [] for vi in range (s, e): vreader.setRow(prim.getVertex(vi)) v.append(Point3(xform(vreader.getData3f())) ) colPoly = CollisionPolygon(*v) cChild.addSolid(colPoly) n=parent.attachNewNode(cChild) return parent
def drawBody(nodePath, vdata, pos, vecList, radius=1, keepDrawing=True, numVertices=8): circleGeom = Geom(vdata) vertWriter = GeomVertexWriter(vdata, "vertex") colorWriter = GeomVertexWriter(vdata, "color") normalWriter = GeomVertexWriter(vdata, "normal") drawReWriter = GeomVertexRewriter(vdata, "drawFlag") texReWriter = GeomVertexRewriter(vdata, "texcoord") startRow = vdata.getNumRows() vertWriter.setRow(startRow) colorWriter.setRow(startRow) normalWriter.setRow(startRow) sCoord = 0 if (startRow != 0): texReWriter.setRow(startRow - numVertices) sCoord = texReWriter.getData2f().getX() + 1 drawReWriter.setRow(startRow - numVertices) if (drawReWriter.getData1f() == False): sCoord -= 1 drawReWriter.setRow(startRow) texReWriter.setRow(startRow) angleSlice = 2 * math.pi / numVertices currAngle = 0 #axisAdj=LMatrix4.rotateMat(45, axis)*LMatrix4.scaleMat(radius)*LMatrix4.translateMat(pos) perp1 = vecList[1] perp2 = vecList[2] # vertex information is written here for i in range(numVertices): adjCircle = pos + \ (perp1 * math.cos(currAngle) + perp2 * math.sin(currAngle)) * \ radius normal = perp1 * math.cos(currAngle) + perp2 * math.sin(currAngle) normalWriter.addData3f(normal) vertWriter.addData3f(adjCircle) texReWriter.addData2f(sCoord, (i + 0.001) / (numVertices - 1)) colorWriter.addData4f(0.5, 0.5, 0.5, 1) drawReWriter.addData1f(keepDrawing) currAngle += angleSlice if startRow == 0: return drawReader = GeomVertexReader(vdata, "drawFlag") drawReader.setRow(startRow - numVertices) # we cant draw quads directly so we use Tristrips if drawReader.getData1i() != 0: lines = GeomTristrips(Geom.UHStatic) half = int(numVertices * 0.5) for i in range(numVertices): lines.addVertex(i + startRow) if i < half: lines.addVertex(i + startRow - half) else: lines.addVertex(i + startRow - half - numVertices) lines.addVertex(startRow) lines.addVertex(startRow - half) lines.closePrimitive() lines.decompose() circleGeom.addPrimitive(lines) circleGeomNode = GeomNode("Debug") circleGeomNode.addGeom(circleGeom) # I accidentally made the front-face face inwards. Make reverse makes the tree render properly and # should cause any surprises to any poor programmer that tries to use # this code circleGeomNode.setAttrib(CullFaceAttrib.makeReverse(), 1) global numPrimitives numPrimitives += numVertices * 2 nodePath.attachNewNode(circleGeomNode)
def getColorAttributesFromVertexData(geom, transform=None): colorsTotalAreas = dict() for k in range(geom.getNumPrimitives()): prim = geom.getPrimitive(k) vdata = geom.getVertexData() assert isinstance(prim, (GeomTristrips, GeomTriangles)) # Check if color is defined for vertex isColorDefined = False for i, geomVertexCol in enumerate(vdata.getFormat().getColumns()): if geomVertexCol.getContents() == GeomEnums.CColor: isColorDefined = True break assert isColorDefined vertex = GeomVertexReader(vdata, 'vertex') vertexColor = GeomVertexReader(vdata, 'color') # Decompose into triangles prim = prim.decompose() for p in range(prim.getNumPrimitives()): s = prim.getPrimitiveStart(p) e = prim.getPrimitiveEnd(p) color = None triPts = [] for i in range(s, e): vi = prim.getVertex(i) vertex.setRow(vi) vertexColor.setRow(vi) v = vertex.getData3f() # NOTE: all vertex of the same polygon (triangles) should have the same color, # so only grab it once. if color is None: color = vertexColor.getData4f() color = (color[0], color[1], color[2], color[3]) triPts.append([v.x, v.y, v.z]) triPts = np.array(triPts) # Apply transformation if transform is not None: v = transform.xformPoint(v) # calculate the semi-perimeter and area a = np.linalg.norm(triPts[0] - triPts[1], 2) b = np.linalg.norm(triPts[1] - triPts[2], 2) c = np.linalg.norm(triPts[2] - triPts[0], 2) s = (a + b + c) / 2 area = (s*(s-a)*(s-b)*(s-c)) ** 0.5 if color in colorsTotalAreas: colorsTotalAreas[color] += area else: colorsTotalAreas[color] = area areas = [] rgbColors = [] transparencies = [] for color, area in colorsTotalAreas.iteritems(): areas.append(area) rgbColors.append(list(color[:3])) # Check transparency isTransparent = color[3] < 1.0 transparencies.append(isTransparent) return areas, rgbColors, transparencies
def processModel(path): scene = loadModel(path) if scene.isEmpty(): print("Error converting `{0}`!".format(path)) return fPath = Filename.fromOsSpecific(path) outputPath = Filename.toOsSpecific( Filename("bam2smd/" + fPath.getDirname() + "/" + fPath.getBasenameWoExtension() + "/")) if not os.path.exists(outputPath): os.makedirs(outputPath) isCharacter = not scene.find("**/+Character").isEmpty() isAnimation = not scene.find("**/+AnimBundleNode").isEmpty() if not isAnimation: if isCharacter: nodes = Skeleton(scene.findAllMatches("**/+Character")) else: nodes = Skeleton(None) names = {} for geomNp in scene.findAllMatches("**/+GeomNode"): smd = "version 1\n" smd += str(nodes) smd += "skeleton\n" smd += "time 0\n" if isCharacter: boneIds = sorted(nodes.bones.keys()) for iBone in range(len(boneIds)): boneId = boneIds[iBone] bone = nodes.bones[boneId] if isinstance(bone, CharacterJoint): boneTform = bone.getTransformState() pos = boneTform.getPos() boneMat = boneTform.getMat().getUpper3() #boneMat.transposeInPlace() rot = mat3NormalizedToEulO(boneMat) else: pos = Vec3() rot = Vec3() smd += boneFrameString(boneId, pos, rot) else: smd += "0 0 0 0 0 0 0\n" smd += "end\n" smd += "triangles\n" for geom in geomNp.node().getGeoms(): geom = geom.decompose() vdata = geom.getVertexData() blendTable = vdata.getTransformBlendTable() for prim in geom.getPrimitives(): numTris = prim.getNumPrimitives() for nTri in range(numTris): start = prim.getPrimitiveStart(nTri) end = prim.getPrimitiveEnd(nTri) smd += "no_material\n" for primVert in range(start, end): vertIdx = prim.getVertex(primVert) reader = GeomVertexReader(vdata) reader.setColumn(InternalName.getVertex()) reader.setRow(vertIdx) pos = reader.getData3f() uv = Vec2(0, 0) if vdata.hasColumn(InternalName.getTexcoord()): reader.setColumn(InternalName.getTexcoord()) reader.setRow(vertIdx) uv = reader.getData2f() norm = Vec3.forward() if vdata.hasColumn(InternalName.getNormal()): reader.setColumn(InternalName.getNormal()) reader.setRow(vertIdx) norm = reader.getData3f() smd += "0 {0:.6f} {1:.6f} {2:.6f} {3:.6f} {4:.6f} {5:.6f} {6:.6f} {7:.6f} ".format( pos[0], pos[1], pos[2], norm[0], norm[1], norm[2], uv[0], uv[1]) if (isCharacter and blendTable and vdata.getNumArrays() > 1 and vdata.getArray(1).hasColumn( InternalName.getTransformBlend())): reader.setColumn( 1, vdata.getArray( 1).getArrayFormat().getColumn( InternalName.getTransformBlend())) reader.setRow(vertIdx) nBlend = reader.getData1i() blend = blendTable.getBlend(nBlend) numTransforms = blend.getNumTransforms() smd += "{0} ".format(numTransforms) for nTransform in range(numTransforms): transform = blend.getTransform(nTransform) if isinstance(transform, JointVertexTransform): boneId = nodes.getBoneId( transform.getJoint()) smd += "{0} {1:.6f} ".format( boneId, blend.getWeight(nTransform)) else: smd += "1 0 1.0" smd += "\n" smd += "end\n" smdFile = geomNp.getName() if len(smdFile) == 0: smdFile = getUnknownName() elif names.get(smdFile, 0) > 0: smdFile = smdFile + "_{0}".format(names[smdFile]) names[smdFile] += 1 else: names[smdFile] = 1 smdFile += ".smd" outFile = open(outputPath + "\\" + smdFile, "w") outFile.write(smd) outFile.flush() outFile.close() else: bundles = scene.findAllMatches("**/+AnimBundleNode") bundle = bundles[0].node().getBundle() nodes = Skeleton(bundles) smd = "version 1\n" smd += str(nodes) smd += "skeleton\n" numFrames = bundle.getNumFrames() boneIds = sorted(nodes.bones.keys()) for iFrame in range(numFrames): smd += "time {0}\n".format(iFrame) for iBone in range(len(boneIds)): bone = nodes.getBone(boneIds[iBone]) if isinstance(bone, AnimChannelACMatrixSwitchType): boneFrameMat = Mat4() bone.getValueNoScaleShear(iFrame, boneFrameMat) boneFrameTransform = TransformState.makeMat(boneFrameMat) pos = boneFrameTransform.getPos() rotMat = boneFrameMat.getUpper3() #rotMat.transposeInPlace() rot = mat3NormalizedToEulO(rotMat) smd += boneFrameString(boneIds[iBone], pos, rot) smd += "end\n" smdFile = fPath.getBasenameWoExtension() + ".smd" outFile = open(outputPath + "\\" + smdFile, "w") outFile.write(smd) outFile.flush() outFile.close()
def createModelClone(self,modelFilename): newVisualCar = loader.loadModel(modelFilename) geomNodeCollection = newVisualCar.findAllMatches('**/+GeomNode') simpleTris=[] self.unmodifiedVertexData=[] for nodePath in geomNodeCollection: geomNode = nodePath.node() for i in range(geomNode.getNumGeoms()): geom = geomNode.getGeom(i) vdata = geom.getVertexData() vertex = GeomVertexReader(vdata, 'vertex') while not vertex.isAtEnd(): v=vertex.getData3f() vertexModelX,vertexModelY,vertexModelZ=v self.unmodifiedVertexData.append([vertexModelX,vertexModelY,vertexModelZ]) for primitiveIndex in range(geom.getNumPrimitives()): prim=geom.getPrimitive(primitiveIndex) prim=prim.decompose() for p in range(prim.getNumPrimitives()): s = prim.getPrimitiveStart(p) e = prim.getPrimitiveEnd(p) singleTriData=[] for i in range(s, e): vertex.setRow(prim.getVertex(s)) vi = prim.getVertex(i) singleTriData.append(vi) simpleTris.append(singleTriData) simpleVertices=self.unmodifiedVertexData format=GeomVertexFormat.getV3() vdata=GeomVertexData('shadow', format, Geom.UHDynamic) self.pandaVertexData=vdata vertex=GeomVertexWriter(vdata, 'vertex') for vertexIndex in range(len(simpleVertices)): simpleVertex=simpleVertices[vertexIndex] vertex.addData3f(0,0,0) tris=GeomTriangles(Geom.UHStatic) for index in range(len(simpleTris)): simpleTri=simpleTris[index] tris.addVertex(simpleTri[0]) tris.addVertex(simpleTri[1]) tris.addVertex(simpleTri[2]) tris.closePrimitive() shadow=Geom(vdata) shadow.addPrimitive(tris) snode=GeomNode('shadow') snode.addGeom(shadow) self.snode=snode
def __init__(self, entity, mesh=None, center=(0,0,0)): super().__init__() center = Vec3(center) if mesh == None and entity.model: mesh = entity.model # print('''auto generating mesh collider from entity's mesh''') self.node_path = entity.attachNewNode(CollisionNode('CollisionNode')) self.collision_polygons = [] if isinstance(mesh, Mesh): if mesh.triangles: triangles = mesh.triangles if not isinstance(mesh.triangles[0], tuple): triangles = [triangles[i:i + 3] for i in range(0, len(triangles), 3)] # group into groups of three for tri in triangles: if len(tri) == 3: poly = CollisionPolygon( Vec3(mesh.vertices[tri[2]]), Vec3(mesh.vertices[tri[1]]), Vec3(mesh.vertices[tri[0]]), ) self.collision_polygons.append(poly) elif len(tri) == 4: poly = CollisionPolygon( Vec3(mesh.vertices[tri[3]]), Vec3(mesh.vertices[tri[2]]), Vec3(mesh.vertices[tri[1]]), Vec3(mesh.vertices[tri[0]])) self.collision_polygons.append(poly) elif mesh.mode == 'triangle': # no triangle list, so take 3 and 3 vertices for i in range(0, len(mesh.vertices), 3): poly = CollisionPolygon( Vec3(mesh.vertices[i+2]), Vec3(mesh.vertices[i+1]), Vec3(mesh.vertices[i]), ) self.collision_polygons.append(poly) else: print('error: mesh collider does not support', mesh.mode, 'mode') return None elif isinstance(mesh, NodePath): from panda3d.core import GeomVertexReader verts = [] geomNodeCollection = mesh.findAllMatches('**/+GeomNode') for nodePath in geomNodeCollection: geomNode = nodePath.node() for i in range(geomNode.getNumGeoms()): geom = geomNode.getGeom(i) vdata = geom.getVertexData() for i in range(geom.getNumPrimitives()): prim = geom.getPrimitive(i) vertex_reader = GeomVertexReader(vdata, 'vertex') prim = prim.decompose() for p in range(prim.getNumPrimitives()): s = prim.getPrimitiveStart(p) e = prim.getPrimitiveEnd(p) for i in range(s, e): vi = prim.getVertex(i) vertex_reader.setRow(vi) verts.append(vertex_reader.getData3()) for i in range(0, len(verts)-3, 3): p = CollisionPolygon(Vec3(verts[i+2]), Vec3(verts[i+1]), Vec3(verts[i])) self.collision_polygons.append(p) node = self.node_path.node() for poly in self.collision_polygons: node.addSolid(poly) self.visible = False
def movePmTo(self, dest_index): geom = self.geomPath.node().modifyGeom(0) vertdata = geom.modifyVertexData() prim = geom.modifyPrimitive(0) indexdata = prim.modifyVertices() indexrewriter = GeomVertexRewriter(indexdata) indexrewriter.setColumn(0) nextTriangleIndex = indexdata.getNumRows() vertwriter = GeomVertexWriter(vertdata, 'vertex') numverts = vertdata.getNumRows() vertwriter.setRow(numverts) normalwriter = GeomVertexWriter(vertdata, 'normal') normalwriter.setRow(numverts) uvwriter = GeomVertexWriter(vertdata, 'texcoord') uvwriter.setRow(numverts) while self.pm_index < dest_index: for op_index in range(len(self.pm_refinements[self.pm_index])): vals = self.pm_refinements[self.pm_index][op_index] op = vals[0] if op == PM_OP.TRIANGLE_ADDITION: indexrewriter.setRow(nextTriangleIndex) nextTriangleIndex += 3 indexrewriter.addData1i(vals[1]) indexrewriter.addData1i(vals[2]) indexrewriter.addData1i(vals[3]) elif op == PM_OP.INDEX_UPDATE: #TODO: ugly workaround for p3d 1.7 bug, change to below for 1.8 indexreader = GeomVertexReader(indexdata) indexreader.setColumn(0) indexreader.setRow(vals[1]) oldval = indexreader.getData1i() del indexreader #indexrewriter.setRow(vals[1]) #oldval = indexrewriter.getData1i() indexrewriter.setRow(vals[1]) indexrewriter.setData1i(vals[2]) self.pm_refinements[self.pm_index][op_index] = (op, vals[1], oldval) elif op == PM_OP.VERTEX_ADDITION: numverts += 1 vertwriter.addData3f(vals[1], vals[2], vals[3]) normalwriter.addData3f(vals[4], vals[5], vals[6]) uvwriter.addData2f(vals[7], vals[8]) self.pm_index += 1 while self.pm_index > dest_index: self.pm_index -= 1 for op_index in range(len(self.pm_refinements[self.pm_index])): vals = self.pm_refinements[self.pm_index][op_index] op = vals[0] if op == PM_OP.TRIANGLE_ADDITION: nextTriangleIndex -= 3 elif op == PM_OP.INDEX_UPDATE: #TODO: ugly workaround for p3d 1.7 bug, change to below for 1.8 indexreader = GeomVertexReader(indexdata) indexreader.setColumn(0) indexreader.setRow(vals[1]) oldval = indexreader.getData1i() del indexreader #indexrewriter.setRow(vals[1]) #oldval = indexrewriter.getData1i() indexrewriter.setRow(vals[1]) indexrewriter.setData1i(vals[2]) self.pm_refinements[self.pm_index][op_index] = (op, vals[1], oldval) elif op == PM_OP.VERTEX_ADDITION: numverts -= 1 if nextTriangleIndex < indexdata.getNumRows(): indexdata.setNumRows(nextTriangleIndex) if numverts < vertdata.getNumRows(): vertdata.setNumRows(numverts)
def drawBody(nodePath, vdata, pos, vecList, radius=1, keepDrawing=True, numVertices=8): circleGeom = Geom(vdata) vertWriter = GeomVertexWriter(vdata, "vertex") colorWriter = GeomVertexWriter(vdata, "color") normalWriter = GeomVertexWriter(vdata, "normal") drawReWriter = GeomVertexRewriter(vdata, "drawFlag") texReWriter = GeomVertexRewriter(vdata, "texcoord") startRow = vdata.getNumRows() vertWriter.setRow(startRow) colorWriter.setRow(startRow) normalWriter.setRow(startRow) sCoord = 0 if (startRow != 0): texReWriter.setRow(startRow - numVertices) sCoord = texReWriter.getData2f().getX() + 1 drawReWriter.setRow(startRow - numVertices) if(drawReWriter.getData1f() == False): sCoord -= 1 drawReWriter.setRow(startRow) texReWriter.setRow(startRow) angleSlice = 2 * math.pi / numVertices currAngle = 0 #axisAdj=LMatrix4.rotateMat(45, axis)*LMatrix4.scaleMat(radius)*LMatrix4.translateMat(pos) perp1 = vecList[1] perp2 = vecList[2] # vertex information is written here for i in range(numVertices): adjCircle = pos + \ (perp1 * math.cos(currAngle) + perp2 * math.sin(currAngle)) * \ radius normal = perp1 * math.cos(currAngle) + perp2 * math.sin(currAngle) normalWriter.addData3f(normal) vertWriter.addData3f(adjCircle) texReWriter.addData2f(sCoord, (i + 0.001) / (numVertices - 1)) colorWriter.addData4f(0.5, 0.5, 0.5, 1) drawReWriter.addData1f(keepDrawing) currAngle += angleSlice drawReader = GeomVertexReader(vdata, "drawFlag") drawReader.setRow(startRow - numVertices) # we cant draw quads directly so we use Tristrips if (startRow != 0) & (drawReader.getData1f() != False): lines = GeomTristrips(Geom.UHStatic) half = int(numVertices * 0.5) for i in range(numVertices): lines.addVertex(i + startRow) if i < half: lines.addVertex(i + startRow - half) else: lines.addVertex(i + startRow - half - numVertices) lines.addVertex(startRow) lines.addVertex(startRow - half) lines.closePrimitive() lines.decompose() circleGeom.addPrimitive(lines) circleGeomNode = GeomNode("Debug") circleGeomNode.addGeom(circleGeom) # I accidentally made the front-face face inwards. Make reverse makes the tree render properly and # should cause any surprises to any poor programmer that tries to use # this code circleGeomNode.setAttrib(CullFaceAttrib.makeReverse(), 1) global numPrimitives numPrimitives += numVertices * 2 nodePath.attachNewNode(circleGeomNode)
def __init__(self, entity, mesh=None, center=(0,0,0)): super().__init__() center = Vec3(center) if mesh == None and entity.model: mesh = entity.model # print('''auto generating mesh collider from entity's mesh''') # from ursina import Mesh # this part is obsolete if I use the old obj loading # if not isinstance(mesh, Mesh): # from ursina import mesh_importer # mesh = eval(mesh_importer.obj_to_ursinamesh(name=mesh.name, save_to_file=False)) # flipped_verts = [v*Vec3(-1,1,1) for v in mesh.vertices] # have to flip it on x axis for some reason # mesh.vertices = flipped_verts self.node_path = entity.attachNewNode(CollisionNode('CollisionNode')) self.node = self.node_path.node() self.collision_polygons = list() if isinstance(mesh, Mesh): if mesh.triangles: for tri in mesh.triangles: if len(tri) == 3: poly = CollisionPolygon( Vec3(mesh.vertices[tri[2]]), Vec3(mesh.vertices[tri[1]]), Vec3(mesh.vertices[tri[0]]), ) self.collision_polygons.append(poly) elif len(tri) == 4: poly = CollisionPolygon( Vec3(mesh.vertices[tri[2]]), Vec3(mesh.vertices[tri[1]]), Vec3(mesh.vertices[tri[0]])) self.collision_polygons.append(poly) poly = CollisionPolygon( Vec3(mesh.vertices[tri[0]]), Vec3(mesh.vertices[tri[3]]), Vec3(mesh.vertices[tri[2]])) self.collision_polygons.append(poly) elif mesh.mode == 'triangle': for i in range(0, len(mesh.vertices), 3): poly = CollisionPolygon( Vec3(mesh.vertices[i+2]), Vec3(mesh.vertices[i+1]), Vec3(mesh.vertices[i]), ) self.collision_polygons.append(poly) else: print('error: mesh collider does not support', mesh.mode, 'mode') return None elif isinstance(mesh, NodePath): from panda3d.core import GeomVertexReader verts = [] geomNodeCollection = mesh.findAllMatches('**/+GeomNode') for nodePath in geomNodeCollection: geomNode = nodePath.node() for i in range(geomNode.getNumGeoms()): geom = geomNode.getGeom(i) vdata = geom.getVertexData() for i in range(geom.getNumPrimitives()): prim = geom.getPrimitive(i) vertex_reader = GeomVertexReader(vdata, 'vertex') prim = prim.decompose() for p in range(prim.getNumPrimitives()): s = prim.getPrimitiveStart(p) e = prim.getPrimitiveEnd(p) for i in range(s, e): vi = prim.getVertex(i) vertex_reader.setRow(vi) verts.append(vertex_reader.getData3()) for i in range(0, len(verts)-3, 3): p = CollisionPolygon(Vec3(verts[i+2]), Vec3(verts[i+1]), Vec3(verts[i])) self.collision_polygons.append(p) for poly in self.collision_polygons: self.node.addSolid(poly) self.visible = False
def createModelClone(self, modelFilename): newVisualCar = loader.loadModel(modelFilename) geomNodeCollection = newVisualCar.findAllMatches('**/+GeomNode') simpleTris = [] self.unmodifiedVertexData = [] for nodePath in geomNodeCollection: geomNode = nodePath.node() for i in range(geomNode.getNumGeoms()): geom = geomNode.getGeom(i) vdata = geom.getVertexData() vertex = GeomVertexReader(vdata, 'vertex') while not vertex.isAtEnd(): v = vertex.getData3f() vertexModelX, vertexModelY, vertexModelZ = v self.unmodifiedVertexData.append( [vertexModelX, vertexModelY, vertexModelZ]) for primitiveIndex in range(geom.getNumPrimitives()): prim = geom.getPrimitive(primitiveIndex) prim = prim.decompose() for p in range(prim.getNumPrimitives()): s = prim.getPrimitiveStart(p) e = prim.getPrimitiveEnd(p) singleTriData = [] for i in range(s, e): vertex.setRow(prim.getVertex(s)) vi = prim.getVertex(i) singleTriData.append(vi) simpleTris.append(singleTriData) simpleVertices = self.unmodifiedVertexData format = GeomVertexFormat.getV3() vdata = GeomVertexData('shadow', format, Geom.UHDynamic) self.pandaVertexData = vdata vertex = GeomVertexWriter(vdata, 'vertex') for vertexIndex in range(len(simpleVertices)): simpleVertex = simpleVertices[vertexIndex] vertex.addData3f(0, 0, 0) tris = GeomTriangles(Geom.UHStatic) for index in range(len(simpleTris)): simpleTri = simpleTris[index] tris.addVertex(simpleTri[0]) tris.addVertex(simpleTri[1]) tris.addVertex(simpleTri[2]) tris.closePrimitive() shadow = Geom(vdata) shadow.addPrimitive(tris) snode = GeomNode('shadow') snode.addGeom(shadow) self.snode = snode