def regesterGeomRequirements(self, LOD, collection): n = NodePath('tmp') if self.barkTexture is not None: n.setTexture(self.barkTexture) n.setShaderInput('diffTex', self.barkTexture) format = GeomVertexFormat.getV3n3t2() else: format = GeomVertexFormat.getV3n3() n.setColor(.4, .3, .3, 1) #n.setShader(customLoader.makeShader(n)) trunkRequirements = meshManager.GeomRequirements( geomVertexFormat=format, renderState=n.getState()) n = NodePath('tmp') if self.leafTexture is not None: #n.setTag("alpha","") n.setShaderInput("alpha", 0, 0, 0) # marker we need cutout alpha n.setTexture(self.leafTexture) n.setShaderInput('diffTex', self.leafTexture) format = GeomVertexFormat.getV3n3t2() else: format = GeomVertexFormat.getV3n3c4() #n.setShader(customLoader.makeShader(n,debugCodePrefix="tree",debugGraphPrefix="tree")) leafRequirements = meshManager.GeomRequirements( geomVertexFormat=format, renderState=n.getState()) self.trunkDataIndex[LOD] = collection.add(trunkRequirements) self.leafDataIndex[LOD] = collection.add(leafRequirements)
def regesterGeomRequirements(self, LOD, collection): n = NodePath("tmp") if self.barkTexture is not None: n.setTexture(self.barkTexture) n.setShaderInput("diffTex", self.barkTexture) format = GeomVertexFormat.getV3n3t2() else: format = GeomVertexFormat.getV3n3() n.setColor(0.4, 0.3, 0.3, 1) # n.setShader(customLoader.makeShader(n)) trunkRequirements = meshManager.GeomRequirements(geomVertexFormat=format, renderState=n.getState()) n = NodePath("tmp") if self.leafTexture is not None: # n.setTag("alpha","") n.setShaderInput("alpha", 0, 0, 0) # marker we need cutout alpha n.setTexture(self.leafTexture) n.setShaderInput("diffTex", self.leafTexture) format = GeomVertexFormat.getV3n3t2() else: format = GeomVertexFormat.getV3n3c4() # n.setShader(customLoader.makeShader(n,debugCodePrefix="tree",debugGraphPrefix="tree")) leafRequirements = meshManager.GeomRequirements(geomVertexFormat=format, renderState=n.getState()) self.trunkDataIndex[LOD] = collection.add(trunkRequirements) self.leafDataIndex[LOD] = collection.add(leafRequirements)
def __init__(self, barkTexture, leafModel, lengthList, numCopiesList, radiusList): """ make tree from params """ NodePath.__init__(self, "Tree Holder") self.numPrimitives = 0 self.leafModel = leafModel self.barkTexture = barkTexture self.bodies = NodePath("Bodies") self.leaves = NodePath("Leaves") self.coll = self.attachNewNode(CollisionNode("Collision")) self.bodydata = GeomVertexData("body vertices", GeomVertexFormat.getV3n3t2(), Geom.UHStatic) self.drawFlags = set() self.numCopiesList = list(numCopiesList) self.radiusList = list(radiusList) self.lengthList = list(lengthList) self.iterations = 1 self.makeEnds() self.makeFromStack(True) #self.coll.show() self.bodies.setTexture(barkTexture) self.coll.reparentTo(self) self.bodies.reparentTo(self) self.leaves.reparentTo(self)
def makeGeom(): # Vertex data fmt = GeomVertexFormat.getV3n3t2() vdata = GeomVertexData('', fmt, Geom.UHStatic) vertex = GeomVertexWriter(vdata, InternalName.getVertex()) normal = GeomVertexWriter(vdata, InternalName.getNormal()) texcoord = GeomVertexWriter(vdata, InternalName.getTexcoord()) for (x, y, z) in vertices: vertex.addData3f(x, y, z) normal.addData3f(0, 0, 0) # Privitive prim = GeomTriangles(Geom.UHStatic) for (i1, i2, i3) in indices: prim.addVertices(i1, i2, i3) prim.closePrimitive() # Geom geom = Geom(vdata) geom.addPrimitive(prim) return geom
def setup(self): self.worldNP = render.attachNewNode('World') # World self.debugNP = self.worldNP.attachNewNode(BulletDebugNode('Debug')) self.debugNP.show() self.world = BulletWorld() self.world.setGravity(Vec3(0, 0, -9.81)) self.world.setDebugNode(self.debugNP.node()) # Ground p0 = Point3(-20, -20, 0) p1 = Point3(-20, 20, 0) p2 = Point3(20, -20, 0) p3 = Point3(20, 20, 0) mesh = BulletTriangleMesh() mesh.addTriangle(p0, p1, p2) mesh.addTriangle(p1, p2, p3) shape = BulletTriangleMeshShape(mesh, dynamic=False) np = self.worldNP.attachNewNode(BulletRigidBodyNode('Mesh')) np.node().addShape(shape) np.setPos(0, 0, -2) np.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(np.node()) # Soft body world information info = self.world.getWorldInfo() info.setAirDensity(1.2) info.setWaterDensity(0) info.setWaterOffset(0) info.setWaterNormal(Vec3(0, 0, 0)) # Softbody for i in range(50): p00 = Point3(-2, -2, 0) p10 = Point3( 2, -2, 0) p01 = Point3(-2, 2, 0) p11 = Point3( 2, 2, 0) node = BulletSoftBodyNode.makePatch(info, p00, p10, p01, p11, 6, 6, 0, True) node.generateBendingConstraints(2) node.getCfg().setLiftCoefficient(0.004) node.getCfg().setDynamicFrictionCoefficient(0.0003) node.getCfg().setAeroModel(BulletSoftBodyConfig.AMVertexTwoSided) node.setTotalMass(0.1) node.addForce(Vec3(0, 2, 0), 0) np = self.worldNP.attachNewNode(node) np.setPos(self.Vec3Rand() * 10 + Vec3(0, 0, 20)) np.setHpr(self.Vec3Rand() * 16) self.world.attachSoftBody(node) fmt = GeomVertexFormat.getV3n3t2() geom = BulletHelper.makeGeomFromFaces(node, fmt, True) node.linkGeom(geom) nodeV = GeomNode('') nodeV.addGeom(geom) npV = np.attachNewNode(nodeV)
def buildGeom(self, meshData): prims = meshData["prims"] vertices = meshData["vertices"] normals = meshData["normals"] texcoords = meshData["texcoords"] vdata = GeomVertexData('mesh', GeomVertexFormat.getV3n3t2(), Geom.UHStatic) vwriter = GeomVertexWriter(vdata, 'vertex') nvwriter = GeomVertexWriter(vdata, 'normal') tvwriter = GeomVertexWriter(vdata, 'texcoord') for i in range(len(vertices)): v = vertices[i] n = normals[i] t = texcoords[i] vwriter.addData3f(v) nvwriter.addData3f(n) tvwriter.addData2f(t) prim = GeomTriangles(Geom.UHStatic) for i in range(len(prims)): A, B, C = prims[i] prim.addVertices(A, B, C) prim.closePrimitive() geom = Geom(vdata) geom.addPrimitive(prim) geomNode = GeomNode('trig') geomNode.addGeom(geom) geomNode.unify(1, True) return geomNode
def __init__(self, config, heights, voxels, X, Y, size, chunk_len, tex, water_tex): NodePath.__init__(self, 'ChunkModel') self.centerX = X self.centerY = Y self.config = config self.heights = heights self.tex = tex self.water_tex = water_tex self.size = size self.chunk_len = chunk_len self.size_voxel = self.size / self.chunk_len if self.size_voxel < 1: self.size_voxel = 1 self.size2 = self.size / 2 self.start_x = self.centerX - self.size2 self.start_y = self.centerY - self.size2 self.voxels = voxels self.v_format = GeomVertexFormat.getV3n3t2() self.v_data = GeomVertexData('chunk', self.v_format, Geom.UHStatic) self.create()
def regesterGeomRequirements(self,LOD,collection): # for now, going to use our own node, so we don't have any special requirements assert LOD==self.LOD requirements=meshManager.GeomRequirements( geomVertexFormat=GeomVertexFormat.getV3n3t2() ) self.dataIndex[LOD]=collection.add(requirements)
def __init__(self): self.views = [] self.vertexBuffer = GeomVertexData('mesh-vdata', GeomVertexFormat.getV3n3t2(), GeomEnums.UHDynamic) self.np = NodePath("mesh") self.vwriter = None self.twriter = None self.nwriter = None
def make_square(x1, y1, z1, x2, y2, z2, tex_coord): format = GeomVertexFormat.getV3n3t2() vdata = GeomVertexData("square", format, Geom.UHStatic) vertex = GeomVertexWriter(vdata, "vertex") normal = GeomVertexWriter(vdata, "normal") texcoord = GeomVertexWriter(vdata, "texcoord") # make sure we draw the sqaure in the right plane if x1 != x2: vertex.addData3f(x1, y1, z1) vertex.addData3f(x2, y1, z1) vertex.addData3f(x2, y2, z2) vertex.addData3f(x1, y2, z2) else: vertex.addData3f(x1, y1, z1) vertex.addData3f(x2, y2, z1) vertex.addData3f(x2, y2, z2) vertex.addData3f(x1, y1, z2) normal.addData3f(my_normalize(Vec3(2 * x1 - 1, 2 * y1 - 1, 2 * z1 - 1))) normal.addData3f(my_normalize(Vec3(2 * x2 - 1, 2 * y2 - 1, 2 * z1 - 1))) normal.addData3f(my_normalize(Vec3(2 * x2 - 1, 2 * y2 - 1, 2 * z2 - 1))) normal.addData3f(my_normalize(Vec3(2 * x1 - 1, 2 * y1 - 1, 2 * z2 - 1))) # adding different colors to the vertex for visibility u1, v1, u2, v2 = tex_coord texcoord.addData2f(u1, v2) texcoord.addData2f(u1, v1) texcoord.addData2f(u2, v1) texcoord.addData2f(u2, v2) # quads arent directly supported by the Geom interface # you might be interested in the CardMaker class if you are # interested in rectangle though tri1 = GeomTriangles(Geom.UHStatic) tri2 = GeomTriangles(Geom.UHStatic) tri1.addVertex(0) tri1.addVertex(1) tri1.addVertex(3) tri2.addConsecutiveVertices(1, 3) tri1.closePrimitive() tri2.closePrimitive() square = Geom(vdata) square.addPrimitive(tri1) square.addPrimitive(tri2) return square
def make_square(x1, y1, z1, x2, y2, z2, tex_coord): format = GeomVertexFormat.getV3n3t2() vdata = GeomVertexData('square', format, Geom.UHStatic) vertex = GeomVertexWriter(vdata, 'vertex') normal = GeomVertexWriter(vdata, 'normal') texcoord = GeomVertexWriter(vdata, 'texcoord') #make sure we draw the sqaure in the right plane if x1 != x2: vertex.addData3f(x1, y1, z1) vertex.addData3f(x2, y1, z1) vertex.addData3f(x2, y2, z2) vertex.addData3f(x1, y2, z2) else: vertex.addData3f(x1, y1, z1) vertex.addData3f(x2, y2, z1) vertex.addData3f(x2, y2, z2) vertex.addData3f(x1, y1, z2) normal.addData3f(my_normalize(Vec3(2 * x1 - 1, 2 * y1 - 1, 2 * z1 - 1))) normal.addData3f(my_normalize(Vec3(2 * x2 - 1, 2 * y2 - 1, 2 * z1 - 1))) normal.addData3f(my_normalize(Vec3(2 * x2 - 1, 2 * y2 - 1, 2 * z2 - 1))) normal.addData3f(my_normalize(Vec3(2 * x1 - 1, 2 * y1 - 1, 2 * z2 - 1))) #adding different colors to the vertex for visibility u1, v1, u2, v2 = tex_coord texcoord.addData2f(u1, v2) texcoord.addData2f(u1, v1) texcoord.addData2f(u2, v1) texcoord.addData2f(u2, v2) #quads arent directly supported by the Geom interface #you might be interested in the CardMaker class if you are #interested in rectangle though tri1 = GeomTriangles(Geom.UHStatic) tri2 = GeomTriangles(Geom.UHStatic) tri1.addVertex(0) tri1.addVertex(1) tri1.addVertex(3) tri2.addConsecutiveVertices(1, 3) tri1.closePrimitive() tri2.closePrimitive() square = Geom(vdata) square.addPrimitive(tri1) square.addPrimitive(tri2) return square
def make_square4v(coord1, coord2, coord3, coord4, tex_coord): format = GeomVertexFormat.getV3n3t2() vdata = GeomVertexData("square", format, Geom.UHStatic) vertex = GeomVertexWriter(vdata, "vertex") normal = GeomVertexWriter(vdata, "normal") texcoord = GeomVertexWriter(vdata, "texcoord") # make sure we draw the sqaure in the right plane vertex.addData3f(coord1) vertex.addData3f(coord2) vertex.addData3f(coord3) vertex.addData3f(coord4) side1 = coord1 - coord2 side2 = coord1 - coord4 norm1 = side1.cross(side2) side1 = coord2 - coord3 side2 = coord2 - coord4 norm2 = side1.cross(side2) normal.addData3f(norm1) normal.addData3f(norm1) normal.addData3f(norm1) normal.addData3f(norm2) # adding different colors to the vertex for visibility u1, v1, u2, v2 = tex_coord texcoord.addData2f(u1, v2) texcoord.addData2f(u1, v1) texcoord.addData2f(u2, v1) texcoord.addData2f(u2, v2) # quads arent directly supported by the Geom interface # you might be interested in the CardMaker class if you are # interested in rectangle though tri1.addVertex(0) tri1.addVertex(1) tri1.addVertex(3) tri1.addConsecutiveVertices(1, 3) tri1.closePrimitive() square = Geom(vdata) square.addPrimitive(tri1) return square
def make_square4v(coord1, coord2, coord3, coord4, tex_coord): format = GeomVertexFormat.getV3n3t2() vdata = GeomVertexData('square', format, Geom.UHStatic) vertex = GeomVertexWriter(vdata, 'vertex') normal = GeomVertexWriter(vdata, 'normal') texcoord = GeomVertexWriter(vdata, 'texcoord') #make sure we draw the sqaure in the right plane vertex.addData3f(coord1) vertex.addData3f(coord2) vertex.addData3f(coord3) vertex.addData3f(coord4) side1 = coord1 - coord2 side2 = coord1 - coord4 norm1 = side1.cross(side2) side1 = coord2 - coord3 side2 = coord2 - coord4 norm2 = side1.cross(side2) normal.addData3f(norm1) normal.addData3f(norm1) normal.addData3f(norm1) normal.addData3f(norm2) #adding different colors to the vertex for visibility u1, v1, u2, v2 = tex_coord texcoord.addData2f(u1, v2) texcoord.addData2f(u1, v1) texcoord.addData2f(u2, v1) texcoord.addData2f(u2, v2) #quads arent directly supported by the Geom interface #you might be interested in the CardMaker class if you are #interested in rectangle though tri1.addVertex(0) tri1.addVertex(1) tri1.addVertex(3) tri1.addConsecutiveVertices(1, 3) tri1.closePrimitive() square = Geom(vdata) square.addPrimitive(tri1) return square
def __init__(self, nodeName, L, initRadius, nSeg): NodePath.__init__(self, nodeName) self.numPrimitives = 0 self.nodeList = [] # for the branch geometry itself self.buds = [] # a list of children. "buds" for next gen of branchs self.length = L # total length of this branch; note Node scaling will mess this up! self.R0 = initRadius self.nSeg = nSeg self.gen = 0 # ID's generation of this branch (trunk = 0, 1 = primary branches, ...) # contains 2 Vec3:[ position, and Hpr]. Nominally these are set by the parent Tree class # with it's add children function(s) self.bodydata = GeomVertexData("body vertices", GeomVertexFormat.getV3n3t2(), Geom.UHStatic) self.bodies = NodePath("Bodies") self.bodies.reparentTo(self)
def empty(prefix, points=False): path = NodePath(prefix + '_path') node = GeomNode(prefix + '_node') path.attachNewNode(node) gvd = GeomVertexData('gvd', GeomVertexFormat.getV3n3t2(), Geom.UHStatic) geom = Geom(gvd) gvw = GeomVertexWriter(gvd, b'vertex') gnw = GeomVertexWriter(gvd, b'normal') gtw = GeomVertexWriter(gvd, b'texcoord') node.addGeom(geom) if points: prim = GeomPoints(Geom.UHStatic) else: prim = GeomTriangles(Geom.UHStatic) return (gvw, gnw, gtw, prim, geom, path)
def regesterGeomRequirements(self,LOD,collection): n=NodePath('tmp') if self.leafTexture is not None: n.setTexture(self.leafTexture) n.setShaderInput('diffTex',self.leafTexture) format=GeomVertexFormat.getV3n3t2() else: n.setColor(.1,.3,.1,1) format=GeomVertexFormat.getV3n3() #n.setShader(customLoader.makeShader(n,debugCodePrefix="fern",debugGraphPrefix="fern")) leafRequirements=meshManager.GeomRequirements( geomVertexFormat=format, renderState=n.getState(), ) self.leafDataIndex[LOD]=collection.add(leafRequirements)
def regesterGeomRequirements(self, LOD, collection): n = NodePath('tmp') if self.leafTexture is not None: n.setTexture(self.leafTexture) n.setShaderInput('diffTex', self.leafTexture) format = GeomVertexFormat.getV3n3t2() else: n.setColor(.1, .3, .1, 1) format = GeomVertexFormat.getV3n3() #n.setShader(customLoader.makeShader(n,debugCodePrefix="fern",debugGraphPrefix="fern")) leafRequirements = meshManager.GeomRequirements( geomVertexFormat=format, renderState=n.getState(), ) self.leafDataIndex[LOD] = collection.add(leafRequirements)
def makeSquare(face, rhs=True): format=GeomVertexFormat.getV3n3cpt2() format=GeomVertexFormat.getV3n3t2() vdata=GeomVertexData('square', format, Geom.UHStatic) vertex=GeomVertexWriter(vdata, 'vertex') normal=GeomVertexWriter(vdata, 'normal') #color=GeomVertexWriter(vdata, 'color') texcoord=GeomVertexWriter(vdata, 'texcoord') if not rhs: face = list(reversed(face)) normalvec = (face[1]-face[0]).cross(face[2]-face[0]) normalvec.normalize() f = 0.9 if rhs else 0.8 f = 1.0 for ver in face: vertex.addData3f(ver*f) normal.addData3f(normalvec) #color.addData3f((ver+1.0+2.0)*0.25) #color.addData3f(ver*0.0+1.0) if not normalvec.z: texcoord.addData2f(0.0, 0.0) texcoord.addData2f(1.0, 0.0) texcoord.addData2f(1.0, 1.0) texcoord.addData2f(0.0, 1.0) tri=GeomTriangles(Geom.UHStatic) tri.addVertices(0, 1, 2) tri.addVertices(2, 3, 0) tri.closePrimitive() square=Geom(vdata) square.addPrimitive(tri) return square
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)
def createBox(self): """ Create the skybox GeomNode :return: """ obj = '' obj += "# Skybox\n" obj += 'mtllib skybox.mtl\n' mtl = '# material for skybox\n' fmt = GeomVertexFormat.getV3n3t2() vdata = GeomVertexData('skybox', fmt, Geom.UHStatic) vdata.setNumRows(24) vertex = GeomVertexWriter(vdata, 'vertex') normals = GeomVertexWriter(vdata, 'normal') texcoord = GeomVertexWriter(vdata, 'texcoord') node = GeomNode('skybox') for normal in self.normals: geom = Geom(vdata) prim = GeomTriangles(Geom.UHStatic) idx = vertex.getWriteRow() verts = self.vertMappings[normal] tcs = self.getFaceMapping(normal) for v, t in zip(verts, tcs): vertex.addData3f(v[0]*2, v[1]*2, v[2]*2) normals.addData3f(normal) texcoord.addData2f(t) obj += 'v {0} {1} {2}\n'.format(v[0]*2, v[1]*2, v[2]*2) obj += 'vn {0} {1} {2}\n'.format(*normal) obj += 'vt {0} {1}\n'.format(*t) tex = self.getFaceTexture(normal) prim.addVertices(idx, idx + 1, idx + 3) prim.closePrimitive() obj += "usemtl {0}\n".format(tex.getName()) obj += 'f {0}/{0} {1}/{1} {2}/{2}\n'.format(1+idx, 1+idx+1, 1+idx+3) prim.addVertices(idx + 1, idx + 2, idx + 3) prim.closePrimitive() obj += "usemtl {0}\n".format(tex.getName()) obj += 'f {0}/{0} {1}/{1} {2}/{2}\n'.format(1+idx+1, 1+idx+2, 1+idx+3) geom.addPrimitive(prim) tex.setWrapU(Texture.WMMirror) tex.setWrapV(Texture.WMMirror) node.addGeom(geom, RenderState.make(TextureAttrib.make(tex))) mtl += "newmtl {0}\n".format(tex.getName()) mtl += "Ka 1 1 1\n" mtl += "Kd 1 1 1\n" mtl += "map_Kd {0}\n".format(tex.getFilename().toOsSpecific()) return node
def regesterGeomRequirements(self, LOD, collection): # for now, going to use our own node, so we don't have any special requirements assert LOD == self.LOD requirements = meshManager.GeomRequirements(geomVertexFormat=GeomVertexFormat.getV3n3t2()) self.dataIndex[LOD] = collection.add(requirements)
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)
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} ) ''')
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(
def setup(self): self.worldNP = render.attachNewNode('World') # World self.debugNP = self.worldNP.attachNewNode(BulletDebugNode('Debug')) self.debugNP.show() self.world = BulletWorld() self.world.setGravity(Vec3(0, 0, -9.81)) self.world.setDebugNode(self.debugNP.node()) # Box shape = BulletBoxShape(Vec3(0.5, 0.5, 0.5) * 2.0) boxNP = self.worldNP.attachNewNode(BulletRigidBodyNode('Box')) boxNP.node().setMass(150.0) boxNP.node().addShape(shape) boxNP.setPos(0, 0, 2) boxNP.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(boxNP.node()) visualNP = loader.loadModel('models/box.egg') visualNP.clearModelNodes() visualNP.setScale(2.0) visualNP.reparentTo(boxNP) # Soft body world information info = self.world.getWorldInfo() info.setAirDensity(1.2) info.setWaterDensity(0) info.setWaterOffset(0) info.setWaterNormal(Vec3(0, 0, 0)) # Softbody nx = 31 ny = 31 p00 = Point3(-8, -8, 0) p10 = Point3( 8, -8, 0) p01 = Point3(-8, 8, 0) p11 = Point3( 8, 8, 0) bodyNode = BulletSoftBodyNode.makePatch(info, p00, p10, p01, p11, nx, ny, 1+2+4+8, True) material = bodyNode.appendMaterial() material.setLinearStiffness(0.4) bodyNode.generateBendingConstraints(2, material); bodyNode.setTotalMass(50.0) bodyNode.getShape(0).setMargin(0.5) bodyNP = self.worldNP.attachNewNode(bodyNode) self.world.attachSoftBody(bodyNode) # Rendering with Geom: fmt = GeomVertexFormat.getV3n3t2() geom = BulletHelper.makeGeomFromFaces(bodyNode, fmt, True) bodyNode.linkGeom(geom) visNode = GeomNode('') visNode.addGeom(geom) visNP = bodyNP.attachNewNode(visNode) # Now we want to have a texture and texture coordinates. # The geom's format has already a column for texcoords, so we just need # to write texcoords using a GeomVertexRewriter. tex = loader.loadTexture('models/panda.jpg') visNP.setTexture(tex) BulletHelper.makeTexcoordsForPatch(geom, nx, ny)
def setup(self): self.worldNP = render.attachNewNode('World') # World self.debugNP = self.worldNP.attachNewNode(BulletDebugNode('Debug')) self.debugNP.show() self.world = BulletWorld() self.world.setGravity(Vec3(0, 0, -9.81)) self.world.setDebugNode(self.debugNP.node()) # Ground p0 = Point3(-20, -20, 0) p1 = Point3(-20, 20, 0) p2 = Point3(20, -20, 0) p3 = Point3(20, 20, 0) mesh = BulletTriangleMesh() mesh.addTriangle(p0, p1, p2) mesh.addTriangle(p1, p2, p3) shape = BulletTriangleMeshShape(mesh, dynamic=False) np = self.worldNP.attachNewNode(BulletRigidBodyNode('Mesh')) np.node().addShape(shape) np.setPos(0, 0, -2) np.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(np.node()) # Soft body world information info = self.world.getWorldInfo() info.setAirDensity(1.2) info.setWaterDensity(0) info.setWaterOffset(0) info.setWaterNormal(Vec3(0, 0, 0)) # Softbody for i in range(50): p00 = Point3(-2, -2, 0) p10 = Point3(2, -2, 0) p01 = Point3(-2, 2, 0) p11 = Point3(2, 2, 0) node = BulletSoftBodyNode.makePatch(info, p00, p10, p01, p11, 6, 6, 0, True) node.generateBendingConstraints(2) node.getCfg().setLiftCoefficient(0.004) node.getCfg().setDynamicFrictionCoefficient(0.0003) node.getCfg().setAeroModel(BulletSoftBodyConfig.AMVertexTwoSided) node.setTotalMass(0.1) node.addForce(Vec3(0, 2, 0), 0) np = self.worldNP.attachNewNode(node) np.setPos(self.Vec3Rand() * 10 + Vec3(0, 0, 20)) np.setHpr(self.Vec3Rand() * 16) self.world.attachSoftBody(node) fmt = GeomVertexFormat.getV3n3t2() geom = BulletHelper.makeGeomFromFaces(node, fmt, True) node.linkGeom(geom) nodeV = GeomNode('') nodeV.addGeom(geom) npV = np.attachNewNode(nodeV)
def setup(self): self.worldNP = render.attachNewNode('World') # World self.debugNP = self.worldNP.attachNewNode(BulletDebugNode('Debug')) self.debugNP.show() self.world = BulletWorld() self.world.setGravity(Vec3(0, 0, -9.81)) self.world.setDebugNode(self.debugNP.node()) # Box shape = BulletBoxShape(Vec3(0.5, 0.5, 0.5) * 2.0) boxNP = self.worldNP.attachNewNode(BulletRigidBodyNode('Box')) boxNP.node().setMass(150.0) boxNP.node().addShape(shape) boxNP.setPos(0, 0, 2) boxNP.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(boxNP.node()) visualNP = loader.loadModel('models/box.egg') visualNP.clearModelNodes() visualNP.setScale(2.0) visualNP.reparentTo(boxNP) # Soft body world information info = self.world.getWorldInfo() info.setAirDensity(1.2) info.setWaterDensity(0) info.setWaterOffset(0) info.setWaterNormal(Vec3(0, 0, 0)) # Softbody nx = 31 ny = 31 p00 = Point3(-8, -8, 0) p10 = Point3(8, -8, 0) p01 = Point3(-8, 8, 0) p11 = Point3(8, 8, 0) bodyNode = BulletSoftBodyNode.makePatch(info, p00, p10, p01, p11, nx, ny, 1 + 2 + 4 + 8, True) material = bodyNode.appendMaterial() material.setLinearStiffness(0.4) bodyNode.generateBendingConstraints(2, material) bodyNode.setTotalMass(50.0) bodyNode.getShape(0).setMargin(0.5) bodyNP = self.worldNP.attachNewNode(bodyNode) self.world.attachSoftBody(bodyNode) # Rendering with Geom: fmt = GeomVertexFormat.getV3n3t2() geom = BulletHelper.makeGeomFromFaces(bodyNode, fmt, True) bodyNode.linkGeom(geom) visNode = GeomNode('') visNode.addGeom(geom) visNP = bodyNP.attachNewNode(visNode) # Now we want to have a texture and texture coordinates. # The geom's format has already a column for texcoords, so we just need # to write texcoords using a GeomVertexRewriter. tex = loader.loadTexture('models/panda.jpg') visNP.setTexture(tex) BulletHelper.makeTexcoordsForPatch(geom, nx, ny)
def getNodeFromGeom(prim): format = GeomVertexFormat.getV3n3t2() vdata = GeomVertexData("dataname", format, Geom.UHStatic) vertex = GeomVertexWriter(vdata, 'vertex') normal = GeomVertexWriter(vdata, 'normal') texcoord = GeomVertexWriter(vdata, 'texcoord') if type(prim) is collada.triangleset.BoundTriangleSet: numtris = 0 for tri in prim.triangles(): for tri_pt in range(3): vertex.addData3f(tri.vertices[tri_pt][0], tri.vertices[tri_pt][1], tri.vertices[tri_pt][2]) normal.addData3f(tri.normals[tri_pt][0], tri.normals[tri_pt][1], tri.normals[tri_pt][2]) if len(prim._texcoordset) > 0: texcoord.addData2f(tri.texcoords[0][tri_pt][0], tri.texcoords[0][tri_pt][1]) numtris+=1 gprim = GeomTriangles(Geom.UHStatic) for i in range(numtris): gprim.addVertices(i*3, i*3+1, i*3+2) gprim.closePrimitive() elif type(prim) is collada.polylist.BoundPolygonList: numtris = 0 for poly in prim.polygons(): for tri in poly.triangles(): for tri_pt in range(3): vertex.addData3f(tri.vertices[tri_pt][0], tri.vertices[tri_pt][1], tri.vertices[tri_pt][2]) normal.addData3f(tri.normals[tri_pt][0], tri.normals[tri_pt][1], tri.normals[tri_pt][2]) if len(prim._texcoordset) > 0: texcoord.addData2f(tri.texcoords[0][tri_pt][0], tri.texcoords[0][tri_pt][1]) numtris+=1 gprim = GeomTriangles(Geom.UHStatic) for i in range(numtris): gprim.addVertices(i*3, i*3+1, i*3+2) gprim.closePrimitive() elif type(prim) is collada.lineset.BoundLineSet: numlines = 0 for line in prim.lines(): for line_pt in range(2): vertex.addData3f(line.vertices[line_pt][0], line.vertices[line_pt][1], line.vertices[line_pt][2]) numlines+=1 gprim = GeomLines(Geom.UHStatic) for i in range(numlines): gprim.addVertices(i*2, i*2+1) gprim.closePrimitive() else: raise Exception("Error: Unsupported primitive type. Exiting.") pgeom = Geom(vdata) pgeom.addPrimitive(gprim) render_state = getStateFromMaterial(prim.material) node = GeomNode("primitive") node.addGeom(pgeom, render_state) return node