def __build_ocean_mesh(self): vdata = GeomVertexData('data', GeomVertexFormat.getV3n3c4t2(), Geom.UHStatic) vertex = GeomVertexWriter(vdata, 'vertex') normal = GeomVertexWriter(vdata, 'normal') texcoord = GeomVertexWriter(vdata, 'texcoord') color = GeomVertexWriter(vdata, 'color') axes = [Vec3.unitX(), Vec3.unitY(), Vec3.unitZ()] face = 0 for x in range(3): for s in [-1, 1]: for i in range(self.__n + 1): for j in range(self.__n + 1): a = (i * 1.0 / self.__n) * (pi / 2) - (pi / 4) b = (j * 1.0 / self.__n) * (pi / 2) - (pi / 4) xAxis = axes[(x + 3) % 3] yAxis = axes[(x + 4) % 3] zAxis = axes[(x + 5) % 3] v = (xAxis * (-cos(a) * sin(b)) + yAxis * (sin(a) * cos(b)) + zAxis * (cos(a) * cos(b))) * s v.normalize() normal.addData3f(v) vertex.addData3f(v * self.__radius) texcoord.addData2f(i * 1.0, j * 1.0) color.addData4f(self.__ocean_color) face = face + 1 prim = self.__heightmap_primitive() geom = Geom(vdata) geom.addPrimitive(prim) return geom
def __build_land_mesh(self): vdata = GeomVertexData('data', GeomVertexFormat.getV3n3c4t2(), Geom.UHStatic) vertex = GeomVertexWriter(vdata, 'vertex') normal = GeomVertexWriter(vdata, 'normal') texcoord = GeomVertexWriter(vdata, 'texcoord') color = GeomVertexWriter(vdata, 'color') axes = [Vec3.unitX(), Vec3.unitY(), Vec3.unitZ()] face = 0 for x in range(3): for s in [-1, 1]: for i in range(self.__n + 1): for j in range(self.__n + 1): a = (i * 1.0 / self.__n) * (pi / 2) - (pi / 4) b = (j * 1.0 / self.__n) * (pi / 2) - (pi / 4) xAxis = axes[(x + 3) % 3] yAxis = axes[(x + 4) % 3] zAxis = axes[(x + 5) % 3] v = (xAxis * (-cos(a) * sin(b)) + yAxis * (sin(a) * cos(b)) + zAxis * (cos(a) * cos(b))) * s v.normalize() normal.addData3f(v) index = self.__height_i(face, i, j) v = v * ( 1.0 + (self.__height_factor * self.__height_unit * (self.__heightmap[index] - 0.5))) * self.__radius vertex.addData3f(v) texcoord.addData2f(i * 1.0, j * 1.0) c = self.__gradient(self.__color_gradient, self.__heightmap[index]) color.addData4f(c[0] / 255.0, c[1] / 255.0, c[2] / 255.0, 1.0) face = face + 1 prim = self.__heightmap_primitive() geom = Geom(vdata) geom.addPrimitive(prim) return geom
from panda3d.core import Geom, GeomNode, GeomTriangles, GeomVertexData from panda3d.core import GeomVertexFormat, GeomVertexWriter from panda3d.core import Material, NodePath, Shader, Texture, TextureStage from panda3d.core import VBase4, Vec3 def myNormalize(myVec): myVec.normalize() return myVec format = GeomVertexFormat.getV3n3c4t2() vdata = GeomVertexData("quadFace", format, Geom.UHDynamic) vertex = GeomVertexWriter(vdata, "vertex") normal = GeomVertexWriter(vdata, "normal") color = GeomVertexWriter(vdata, "color") texcoord = GeomVertexWriter(vdata, "texcoord") def create_mesh(parentnp, debug=False, invert=False): """This creates a simple 17x17 grid mesh for the sides of our cube. The ultimate goal is to use a LOD system, probably based on quadtrees. If debug is true then we get a color gradiant on our vertexes.""" x = -1.0 y = -1.0 vertex_count = 0 u = 0.0 v = 0.0 WIDTH_STEP = 2 / 16.0
def generate( self ): # call this after setting some of the variables to update it if not self.vertices: return 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': GeomLines(static_mode), 'lines': GeomLinestrips(static_mode), 'point': GeomPoints(static_mode), } if self.mode == 'line' and len(self.vertices) % 2 > 0: if len(self.vertices) == 1: self.mode = point print( 'warning: number of vertices must be even for line mode, ignoring last vert' ) self.vertices = self.vertices[:len(self.vertices) - 1] 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) self.geomNode = GeomNode('mesh') self.geomNode.addGeom(geom) self.attachNewNode(self.geomNode) # print('finished') self.recipe = f'''Mesh(
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)
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 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) 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 = 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} ) ''') # 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 @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)
from panda3d.core import Geom, GeomNode, GeomTriangles, GeomVertexData from panda3d.core import GeomVertexFormat, GeomVertexWriter from panda3d.core import Material, NodePath, Shader, Texture, TextureStage from panda3d.core import VBase4, Vec3 def myNormalize(myVec): myVec.normalize() return myVec format = GeomVertexFormat.getV3n3c4t2() vdata = GeomVertexData('quadFace', format, Geom.UHDynamic) vertex = GeomVertexWriter(vdata, 'vertex') normal = GeomVertexWriter(vdata, 'normal') color = GeomVertexWriter(vdata, 'color') texcoord = GeomVertexWriter(vdata, 'texcoord') def create_mesh(parentnp, debug=False, invert=False): '''This creates a simple 17x17 grid mesh for the sides of our cube. The ultimate goal is to use a LOD system, probably based on quadtrees. If debug is true then we get a color gradiant on our vertexes.''' x = -1.0 y = -1.0 vertex_count = 0 u = 0.0 v = 0.0 WIDTH_STEP = 2 / 16.0
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} ) ''')