def __init__(self): self.textures={} for k in texMap: v=texMap[k] tex=loader.loadTexture("gfx/%s"%v) tex.setWrapU(Texture.WM_clamp) tex.setWrapV(Texture.WM_clamp) self.textures[k]=tex self.viewPoint=(0,0,0) self.cubeVtxSrc=[ # 14 vertices per cube mapped # so that UV coords utilize # the typical cube unwrap: # # #### <-- square texture # ##U# # BLFR # ##D# #=unused # # This form uses 14 vertices per cube since # the extra (worldspace overlapped) vertices # map different U,V coordinates at the same # worldspace coordinates, depending on face # # x y z u v (1.00,1.00,1.00,0.00,0.50), # A (1.00,1.00,0.00,0.00,0.25), # B (0.00,1.00,1.00,0.25,0.50), # C (0.00,1.00,0.00,0.25,0.25), # D (0.00,0.00,1.00,0.50,0.50), # E (0.00,0.00,0.00,0.50,0.25), # F (1.00,0.00,1.00,0.75,0.50), # G (1.00,0.00,0.00,0.75,0.25), # H (1.00,1.00,1.00,1.00,0.50), # I (1.00,1.00,0.00,1.00,0.25), # J (0.00,1.00,1.00,0.50,0.75), # K (1.00,1.00,1.00,0.75,0.75), # L (0.00,1.00,0.00,0.50,0.00), # M (1.00,1.00,0.00,0.75,0.00) # N ] self.triSrc=[ # # Faces (QUAD/TRIPAIR) # using RHR vertex ordering for # correct face surface normals # # front: EFHG/EFH+HGE # rear: CABD/CAB+BDC # left: CDFE/CDF+FEC # right: GHJI/GHJ+JIG # upper: KEGL/KEG+GLK # lower: FMNH/FMN+NHF # "EFH","HGE", "CAB","BDC", "CDF","FEC", "GHJ","JIG", "KEG","GLK", "FMN","NHF" ] # # setup cube # # one cube node will be generated per non-air block # since different block id's potentially refer to # different textures and thus must be separate nodes # of the scene graph. # # 1. vertices self.cubeVtx=GeomVertexData('blockCube',GeomVertexFormat.getV3t2(),Geom.UHStatic) self.cubeVtx.setNumRows(len(self.cubeVtxSrc)) vtxW=GeomVertexWriter(self.cubeVtx,'vertex') txcW=GeomVertexWriter(self.cubeVtx,'texcoord') for vertex in self.cubeVtxSrc: vtxW.addData3f(*vertex[0:3]) txcW.addData2f(*vertex[3:5]) # 2. mesh self.cubeMesh=GeomTriangles(Geom.UHStatic) for tri in self.triSrc: for triV in tri: triVtxId=ord(triV)-65 # changea 'A'-'N' to 0-13 self.cubeMesh.addVertex(triVtxId) self.cubeMesh.close_primitive() # 3. geometry (primitive+vertex pair) self.cubeGeom=Geom(self.cubeVtx) self.cubeGeom.addPrimitive(self.cubeMesh)
def makeTrack(segments): format=GeomVertexFormat.getV3t2() vdata=GeomVertexData('track', format, Geom.UHStatic) vertex=GeomVertexWriter(vdata, 'vertex') texcoord=GeomVertexWriter(vdata, 'texcoord') vdata2=GeomVertexData('startline', format, Geom.UHStatic) vertex2=GeomVertexWriter(vdata2, 'vertex') texcoord2=GeomVertexWriter(vdata2, 'texcoord') numVertices=0 twat=0 for segmentIndex in range(len(segments)): currentSegment=segments[segmentIndex] if segmentIndex==0: nextSegment=segments[segmentIndex+1] currentStartLineLeftPoint=Geometry.Point.CreateByInterpolation(currentSegment.getMidPoint(),currentSegment.getLeftPoint(),100,77.5); currentStartLineRightPoint=Geometry.Point.CreateByInterpolation(currentSegment.getMidPoint(),currentSegment.getRightPoint(),100,77.5); nextStartLineLeftPoint=Geometry.Point.CreateByInterpolation(nextSegment.getMidPoint(),nextSegment.getLeftPoint(),100,77.5); nextStartLineRightPoint=Geometry.Point.CreateByInterpolation(nextSegment.getMidPoint(),nextSegment.getRightPoint(),100,77.5); vertex2.addData3f(nextStartLineLeftPoint.getX(),nextStartLineLeftPoint.getY(),0) vertex2.addData3f(nextStartLineRightPoint.getX(),nextStartLineRightPoint.getY(),0) vertex2.addData3f(currentStartLineLeftPoint.getX(),currentStartLineLeftPoint.getY(),0) vertex2.addData3f(currentStartLineRightPoint.getX(),currentStartLineRightPoint.getY(),0) texcoord2.addData2f(0.0, 0.0) texcoord2.addData2f(12.0, 0.0) texcoord2.addData2f(0.0, 2.0) texcoord2.addData2f(12.0, 2.0) vertex.addData3f(currentSegment.leftPoint.getX(),currentSegment.leftPoint.getY(),0) vertex.addData3f(currentSegment.rightPoint.getX(),currentSegment.rightPoint.getY(),0) texcoord.addData2f(0.0, 1.0/8*float(twat)) texcoord.addData2f(1.0, 1.0/8*float(twat)) #print('vertex at '+str(segmentIndex)+' with v='+str(1.0/8*float(twat))) numVertices+=2 twat=twat+1 if twat==9: #print('surplus at '+str(segmentIndex)+' with v=0.0') vertex.addData3f(currentSegment.leftPoint.getX(),currentSegment.leftPoint.getY(),0) vertex.addData3f(currentSegment.rightPoint.getX(),currentSegment.rightPoint.getY(),0) texcoord.addData2f(0.0, 0.0) texcoord.addData2f(1.0, 0.0) numVertices+=2 twat=1 #print('vertices created: '+str(numVertices)) tris=GeomTriangles(Geom.UHDynamic) bob=0 vertexOffset=0 for index in range(len(segments)): vertexOffsets=[] for innerIndex in range(4): offset=vertexOffset+innerIndex if offset>numVertices-1: offset=offset-numVertices vertexOffsets.append(offset) tris.addVertex(vertexOffsets[0]) tris.addVertex(vertexOffsets[1]) tris.addVertex(vertexOffsets[3]) tris.closePrimitive() tris.addVertex(vertexOffsets[0]) tris.addVertex(vertexOffsets[3]) tris.addVertex(vertexOffsets[2]) tris.closePrimitive() vertexOffset+=2 bob+=1 if bob==8: vertexOffset+=2 bob=0 tris2=GeomTriangles(Geom.UHDynamic) tris2.addVertex(0) tris2.addVertex(3) tris2.addVertex(1) tris2.closePrimitive() tris2.addVertex(0) tris2.addVertex(2) tris2.addVertex(3) tris2.closePrimitive() track=Geom(vdata) track.addPrimitive(tris) startLine=Geom(vdata2) startLine.addPrimitive(tris2) snode=GeomNode('tarmac') snode.addGeom(track) snode2=GeomNode('startline') snode2.addGeom(startLine) returnValues={"tarmac":snode,"startline":snode2} return returnValues return snode
def makeMountains(): format=GeomVertexFormat.getV3t2() vdata=GeomVertexData('mountains', format, Geom.UHStatic) vertex=GeomVertexWriter(vdata, 'vertex') texcoord=GeomVertexWriter(vdata, 'texcoord') format2=GeomVertexFormat.getV3c4() vdata2=GeomVertexData('sky', format2, Geom.UHStatic) vertex2=GeomVertexWriter(vdata2, 'vertex') color2=GeomVertexWriter(vdata2, 'color') numQuads=32 angle=0 textureX=0 angleAdd=math.pi*2/numQuads textureXAdd=1.0/numQuads currentQuad=0 numVertices=0 while currentQuad<numQuads: if currentQuad==0: vertexX=math.sin(angle)*3000 vertexY=math.cos(angle)*3000 vertex.addData3f(vertexX,vertexY,0.0) vertex.addData3f(vertexX,vertexY,360.0) texcoord.addData2f(1.0, 0.0) texcoord.addData2f(1.0, 1.0) numVertices=numVertices+2 vertexX=math.sin(angle)*3000 vertexY=math.cos(angle)*3000 vertex.addData3f(vertexX,vertexY,0.0) vertex.addData3f(vertexX,vertexY,360.0) vertex2.addData3f(vertexX,vertexY,360.0) color2.addData4f(45.0/255.0,112.0/255.0,255.0/255.0,1.0) #color2.addData4f(1.0,1.0,1.0,1.0) #print('created vertex at '+str(vertexX)+','+str(vertexY)+',2') #print('created vertex at '+str(vertexX)+','+str(vertexY)+',0') texcoord.addData2f(textureX, 0.0) texcoord.addData2f(textureX, 1.0) #print('texturex is '+str(textureX)) #print('creating vertices v'+str(numVertices)+' and v'+str(numVertices+1)) numVertices=numVertices+2 currentQuad=currentQuad+1 textureX=textureX+textureXAdd angle=angle+angleAdd vertex2.addData3f(0.0,0.0,360.0) #color2.addData4f(1.0,1.0,1.0,1.0) color2.addData4f(45.0/255.0,112.0/255.0,255.0/255.0,1.0) currentQuad=0 currentOffset=2 tris=GeomTriangles(Geom.UHDynamic) #print('creating tris - numVertices is '+str(numVertices)) while currentQuad<numQuads: vertexOffsets=[] for innerIndex in range(4): offset=currentOffset+innerIndex #print('comparing '+str(offset)+' with '+str(numVertices-1)) if offset>numVertices-1: offset=offset-numVertices vertexOffsets.append(offset) #print('adding tri connecting v'+str(vertexOffsets[0])+', v'+str(vertexOffsets[1])+', v'+str(vertexOffsets[3])) #print('adding tri connecting v'+str(vertexOffsets[1])+', v'+str(vertexOffsets[3])+', v'+str(vertexOffsets[2])) tris.addVertex(vertexOffsets[0]) tris.addVertex(vertexOffsets[2]) tris.addVertex(vertexOffsets[1]) tris.closePrimitive() tris.addVertex(vertexOffsets[1]) tris.addVertex(vertexOffsets[2]) tris.addVertex(vertexOffsets[3]) tris.closePrimitive() currentOffset=currentOffset+2 currentQuad=currentQuad+1 tris2=GeomTriangles(Geom.UHDynamic) currentOffset=1 numTris=numQuads currentTri=0 while currentTri<numTris: tris2.addVertex(numTris) tris2.addVertex(currentTri) if currentTri==numTris-1: tris2.addVertex(0) else: tris2.addVertex(currentTri+1) tris2.closePrimitive() currentTri=currentTri+1 mountains=Geom(vdata) mountains.addPrimitive(tris) sky=Geom(vdata2) sky.addPrimitive(tris2) snode=GeomNode('mountains') snode.addGeom(mountains) snode2=GeomNode('sky') snode2.addGeom(sky) returnValues={"mountains":snode,"sky":snode2} return returnValues
class Mesh(NodePath): _formats = { (0, 0, 0): GeomVertexFormat.getV3(), (1, 0, 0): GeomVertexFormat.getV3c4(), (0, 1, 0): GeomVertexFormat.getV3t2(), (0, 0, 1): GeomVertexFormat.getV3n3(), (1, 0, 1): GeomVertexFormat.getV3n3c4(), (1, 1, 0): GeomVertexFormat.getV3c4t2(), (0, 1, 1): GeomVertexFormat.getV3n3t2(), (1, 1, 1): GeomVertexFormat.getV3n3c4t2(), } _modes = { 'triangle': GeomTriangles, 'tristrip': GeomTristrips, 'ngon': GeomTrifans, 'line': GeomLinestrips, 'point': GeomPoints, } def __init__(self, vertices=None, triangles=None, colors=None, uvs=None, normals=None, static=True, mode='triangle', thickness=1): super().__init__('mesh') self.vertices = vertices self.triangles = triangles self.colors = colors self.uvs = uvs self.normals = normals self.static = static self.mode = mode self.thickness = thickness for var in ( ('vertices', vertices), ('triangles', triangles), ('colors', colors), ('uvs', uvs), ('normals', normals)): name, value = var if value is None: setattr(self, name, list()) if self.vertices: self.vertices = [tuple(v) for v in self.vertices] self.generate() def generate(self): # call this after setting some of the variables to update it if hasattr(self, 'geomNode'): self.geomNode.removeAllGeoms() static_mode = Geom.UHStatic if self.static else Geom.UHDynamic vertex_format = Mesh._formats[(bool(self.colors), bool(self.uvs), bool(self.normals))] vdata = GeomVertexData('name', vertex_format, static_mode) vdata.setNumRows(len(self.vertices)) # for speed self.geomNode = GeomNode('mesh') self.attachNewNode(self.geomNode) vertexwriter = GeomVertexWriter(vdata, 'vertex') for v in self.vertices: vertexwriter.addData3f((v[0], v[2], v[1])) # swap y and z if self.colors: colorwriter = GeomVertexWriter(vdata, 'color') for c in self.colors: colorwriter.addData4f(c) if self.uvs: uvwriter = GeomVertexWriter(vdata, 'texcoord') for uv in self.uvs: uvwriter.addData2f(uv[0], uv[1]) if self.normals != None: normalwriter = GeomVertexWriter(vdata, 'normal') for norm in self.normals: normalwriter.addData3f((norm[0], norm[2], norm[1])) if self.mode != 'line' or not self._triangles: prim = Mesh._modes[self.mode](static_mode) if self._triangles: if isinstance(self._triangles[0], int): for t in self._triangles: prim.addVertex(t) elif len(self._triangles[0]) >= 3: # if tris are tuples like this: ((0,1,2), (1,2,3)) for t in self._triangles: if len(t) == 3: for e in t: prim.addVertex(e) elif len(t) == 4: # turn quad into tris prim.addVertex(t[0]) prim.addVertex(t[1]) prim.addVertex(t[2]) prim.addVertex(t[2]) prim.addVertex(t[3]) prim.addVertex(t[0]) else: prim.addConsecutiveVertices(0, len(self.vertices)) prim.close_primitive() geom = Geom(vdata) geom.addPrimitive(prim) self.geomNode.addGeom(geom) else: # line with segments defined in triangles for line in self._triangles: prim = Mesh._modes[self.mode](static_mode) for e in line: prim.addVertex(e) prim.close_primitive() geom = Geom(vdata) geom.addPrimitive(prim) self.geomNode.addGeom(geom) self.recipe = dedent(f''' Mesh( vertices={[tuple(e) for e in self.vertices]}, triangles={self._triangles}, colors={[tuple(e) for e in self.colors]}, uvs={self.uvs}, normals={[tuple(e) for e in self.normals]}, static={self.static}, mode="{self.mode}", thickness={self.thickness} ) ''') # print('finished') def __add__(self, other): self.vertices += other.vertices self.triangles += other.triangles if other.colors: self.colors += other.colors else: self.colors += (color.white,) * len(other.vertices) self.normals += other.normals self.uvs += other.uvs def __copy__(self): return Mesh(self.vertices, self.triangles, self.colors, self.uvs, self.normals, self.static, self.mode, self.thickness) @property def thickness(self): return self.getRenderModeThickness() @thickness.setter def thickness(self, value): self.setRenderModeThickness(value) @property def triangles(self): if self._triangles == None: self._triangles = [(i, i + 1, i + 2) for i in range(0, len(self.vertices), 3)] return self._triangles @triangles.setter def triangles(self, value): self._triangles = value def generate_normals(self, smooth=True): self.normals = list(generate_normals(self.vertices, self.triangles, smooth)) self.generate() return self.normals def colorize(self, left=color.white, right=color.blue, down=color.red, up=color.green, back=color.white, forward=color.white, smooth=True, world_space=True): colorize(self, left, right, down, up, back, forward, smooth, world_space) def project_uvs(self, aspect_ratio=1, direction='forward'): project_uvs(self, aspect_ratio) def clear(self, regenerate=True): self.vertices, self.triangles, self.colors, self.uvs, self.normals = list(), list(), list(), list(), list() if regenerate: self.generate() def save(self, name, path=application.asset_folder, filetype='ursinamesh'): if filetype == 'ursinamesh': if not '.' in name: name += '.ursinamesh' with open(path / name, 'w') as f: recipe = self.recipe.replace('LVector3f', '') f.write(recipe) elif filetype == 'obj': from ursina.mesh_importer import ursina_mesh_to_obj ursina_mesh_to_obj(self, name, path)
def generate( self ): # call this after setting some of the variables to update it if hasattr(self, 'geomNode'): self.geomNode.removeAllGeoms() static_mode = Geom.UHStatic if self.static else Geom.UHDynamic formats = { (0, 0, 0): GeomVertexFormat.getV3(), (1, 0, 0): GeomVertexFormat.getV3c4(), (0, 1, 0): GeomVertexFormat.getV3t2(), (0, 0, 1): GeomVertexFormat.getV3n3(), (1, 0, 1): GeomVertexFormat.getV3n3c4(), (1, 1, 0): GeomVertexFormat.getV3c4t2(), (0, 1, 1): GeomVertexFormat.getV3n3t2(), (1, 1, 1): GeomVertexFormat.getV3n3c4t2(), } vertex_format = formats[(bool(self.colors), bool(self.uvs), bool(self.normals))] vdata = GeomVertexData('name', vertex_format, static_mode) vdata.setNumRows(len(self.vertices)) # for speed vertexwriter = GeomVertexWriter(vdata, 'vertex') for v in self.vertices: vertexwriter.addData3f((v[0], v[2], v[1])) # swap y and z if self.colors: colorwriter = GeomVertexWriter(vdata, 'color') for c in self.colors: colorwriter.addData4f(c) if self.uvs: uvwriter = GeomVertexWriter(vdata, 'texcoord') for uv in self.uvs: uvwriter.addData2f(uv[0], uv[1]) if self.normals != None: normalwriter = GeomVertexWriter(vdata, 'normal') for norm in self.normals: normalwriter.addData3f((norm[0], norm[2], norm[1])) modes = { 'triangle': GeomTriangles(static_mode), 'tristrip': GeomTristrips(static_mode), 'ngon': GeomTrifans(static_mode), 'line': GeomLinestrips(static_mode), 'point': GeomPoints(static_mode), } if self.mode != 'line' or not self._triangles: prim = modes[self.mode] if self._triangles: if isinstance(self._triangles[0], int): for t in self._triangles: prim.addVertex(t) elif len( self._triangles[0] ) >= 3: # if tris are tuples like this: ((0,1,2), (1,2,3)) for t in self._triangles: if len(t) == 3: for e in t: prim.addVertex(e) elif len(t) == 4: # turn quad into tris prim.addVertex(t[0]) prim.addVertex(t[1]) prim.addVertex(t[2]) prim.addVertex(t[2]) prim.addVertex(t[3]) prim.addVertex(t[0]) else: prim.addConsecutiveVertices(0, len(self.vertices)) prim.close_primitive() geom = Geom(vdata) geom.addPrimitive(prim) else: # line with segments defnined in triangles for line in self._triangles: prim = modes[self.mode] for e in line: prim.addVertex(e) prim.close_primitive() geom = Geom(vdata) geom.addPrimitive(prim) self.geomNode = GeomNode('mesh') self.geomNode.addGeom(geom) self.attachNewNode(self.geomNode) # if self.normals: # self.normals = [tuple(e) for e in self.normals] self.recipe = dedent(f''' Mesh( vertices={[tuple(e) for e in self.vertices]}, triangles={self._triangles}, colors={[tuple(e) for e in self.colors]}, uvs={self.uvs}, normals={[tuple(e) for e in self.normals]}, static={self.static}, mode="{self.mode}", thickness={self.thickness} ) ''')
class Mesh(NodePath): _formats = { (0, 0, 0): GeomVertexFormat.getV3(), (1, 0, 0): GeomVertexFormat.getV3c4(), (0, 1, 0): GeomVertexFormat.getV3t2(), (0, 0, 1): GeomVertexFormat.getV3n3(), (1, 0, 1): GeomVertexFormat.getV3n3c4(), (1, 1, 0): GeomVertexFormat.getV3c4t2(), (0, 1, 1): GeomVertexFormat.getV3n3t2(), (1, 1, 1): GeomVertexFormat.getV3n3c4t2(), } _modes = { 'triangle': GeomTriangles, 'tristrip': GeomTristrips, 'ngon': GeomTrifans, 'line': GeomLinestrips, 'point': GeomPoints, } def __init__(self, vertices=None, triangles=None, colors=None, uvs=None, normals=None, static=True, mode='triangle', thickness=1): super().__init__('mesh') self.vertices = vertices self.triangles = triangles self.colors = colors self.uvs = uvs self.normals = normals self.static = static self.mode = mode self.thickness = thickness for var in (('vertices', vertices), ('triangles', triangles), ('colors', colors), ('uvs', uvs), ('normals', normals)): name, value = var if value is None: setattr(self, name, list()) if self.vertices: self.generate() def generate( self ): # call this after setting some of the variables to update it if hasattr(self, 'geomNode'): self.geomNode.removeAllGeoms() static_mode = Geom.UHStatic if self.static else Geom.UHDynamic vertex_format = Mesh._formats[(bool(self.colors), bool(self.uvs), bool(self.normals))] vdata = GeomVertexData('name', vertex_format, static_mode) vdata.setNumRows(len(self.vertices)) # for speed if not hasattr(self, 'geomNode'): self.geomNode = GeomNode('mesh') self.attachNewNode(self.geomNode) vertexwriter = GeomVertexWriter(vdata, 'vertex') for v in self.vertices: vertexwriter.addData3f(*v) if self.colors: colorwriter = GeomVertexWriter(vdata, 'color') for c in self.colors: colorwriter.addData4f(c) if self.uvs: uvwriter = GeomVertexWriter(vdata, 'texcoord') for uv in self.uvs: uvwriter.addData2f(uv[0], uv[1]) if self.normals != None: normalwriter = GeomVertexWriter(vdata, 'normal') for norm in self.normals: normalwriter.addData3f(*norm) if self.mode != 'line' or not self._triangles: self.indices = list() if self._triangles: if isinstance(self._triangles[0], int): for t in self._triangles: self.indices.append(t) elif len( self._triangles[0] ) >= 3: # if tris are tuples like this: ((0,1,2), (1,2,3)) for t in self._triangles: if len(t) == 3: self.indices.extend(t) elif len(t) == 4: # turn quad into tris self.indices.extend( [t[i] for i in (0, 1, 2, 2, 3, 0)]) else: self.indices = [i for i in range(len(self.vertices))] prim = Mesh._modes[self.mode](static_mode) self.generated_vertices = [self.vertices[i] for i in self.indices] for v in self.indices: prim.addVertex(v) prim.close_primitive() geom = Geom(vdata) geom.addPrimitive(prim) self.geomNode.addGeom(geom) else: # line with segments defined in triangles for line in self._triangles: prim = Mesh._modes[self.mode](static_mode) for e in line: prim.addVertex(e) prim.close_primitive() geom = Geom(vdata) geom.addPrimitive(prim) self.geomNode.addGeom(geom) if self.mode == 'point': self.setTexGen(TextureStage.getDefault(), TexGenAttrib.MPointSprite) # self.set_render_mode_perspective(True) # print('finished') @property def recipe(self): if hasattr(self, '_recipe'): return self._recipe return dedent(f''' Mesh( vertices={[tuple(e) for e in self.vertices]}, triangles={self._triangles}, colors={[tuple(e) for e in self.colors]}, uvs={self.uvs}, normals={[tuple(e) for e in self.normals]}, static={self.static}, mode="{self.mode}", thickness={self.thickness} ) ''') @recipe.setter def recipe(self, value): self._recipe = value def __add__(self, other): self.vertices += other.vertices self.triangles += other.triangles if other.colors: self.colors += other.colors else: self.colors += (color.white, ) * len(other.vertices) self.normals += other.normals self.uvs += other.uvs def __deepcopy__(self, memo): m = Mesh(self.vertices, self.triangles, self.colors, self.uvs, self.normals, self.static, self.mode, self.thickness) m.name = self.name return m @property def thickness(self): return self.getRenderModeThickness() @thickness.setter def thickness(self, value): self.setRenderModeThickness(value) @property def triangles(self): if self._triangles == None: self._triangles = [(i, i + 1, i + 2) for i in range(0, len(self.vertices), 3)] return self._triangles @triangles.setter def triangles(self, value): self._triangles = value def generate_normals(self, smooth=True): self.normals = list( generate_normals(self.vertices, self.triangles, smooth)) self.generate() return self.normals def colorize(self, left=color.white, right=color.blue, down=color.red, up=color.green, back=color.white, forward=color.white, smooth=True, world_space=True): colorize(self, left, right, down, up, back, forward, smooth, world_space) def project_uvs(self, aspect_ratio=1, direction='forward'): project_uvs(self, aspect_ratio) def clear(self, regenerate=True): self.vertices, self.triangles, self.colors, self.uvs, self.normals = list( ), list(), list(), list(), list() if regenerate: self.generate() def save(self, name='', path=application.compressed_models_folder): if not application.compressed_models_folder.exists(): application.compressed_models_folder.mkdir() if not name and hasattr(self, 'path'): name = self.path.stem if not '.' in name: name += '.ursinamesh' if name.endswith('ursinamesh'): with open(path / name, 'w') as f: # recipe = self.recipe.replace('LVector3f', '') f.write(self.recipe) print('saved .ursinamesh to:', path / name) elif name.endswith('.obj'): from ursina.mesh_importer import ursina_mesh_to_obj ursina_mesh_to_obj(self, name, path) elif name.endswith('.bam'): success = self.writeBamFile(path / name) print('saved .bam to:', path / name)