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 __init__(self): array_format = GeomVertexArrayFormat() array_format.addColumn( InternalName.make(ArrayFormatColunm.Vertex.value), 3, Geom.NT_float32, Geom.C_point) array_format.addColumn( InternalName.make(ArrayFormatColunm.Color.value), 4, Geom.NT_uint8, Geom.C_color) array_format.addColumn( InternalName.make(ArrayFormatColunm.Normal.value), 3, Geom.NT_float32, Geom.C_normal) array_format.addColumn( InternalName.make(ArrayFormatColunm.Tangent.value), 3, Geom.NT_float32, Geom.C_vector) array_format.addColumn( InternalName.make(ArrayFormatColunm.Binormal.value), 3, Geom.NT_float32, Geom.C_vector) array_format.addColumn( InternalName.make(ArrayFormatColunm.UVMap.value), 2, Geom.NT_float32, Geom.C_texcoord) self.vertex_format = GeomVertexFormat() self.vertex_format.addArray(array_format) self.vertex_format = GeomVertexFormat.registerFormat( self.vertex_format)
def makeVertexFormat(color=True, normal=False, texcoord=False, tan_binorm=False): myArray = GeomVertexArrayFormat() myArray.addColumn(InternalName.make('vertex'), 3, Geom.NTFloat32, Geom.CPoint) if color: myArray.addColumn(InternalName.make('color'), 4, Geom.NTFloat32, Geom.CColor) if normal: myArray.addColumn(InternalName.make('normal'), 3, Geom.NTFloat32, Geom.CVector) if texcoord: myArray.addColumn(InternalName.make('texcoord'), 2, Geom.NTFloat32, Geom.CTexcoord) if tan_binorm: myArray.addColumn(InternalName.make('tangent'), 3, Geom.NTFloat32, Geom.CVector) myArray.addColumn(InternalName.make('binormal'), 3, Geom.NTFloat32, Geom.CVector) myFormat = GeomVertexFormat() myFormat.addArray(myArray) myFormat = GeomVertexFormat.registerFormat(myFormat) return myFormat
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 geom_node(): array = GeomVertexArrayFormat() array.add_column("vertex", 3, Geom.NT_float32, Geom.C_point) array.add_column("normal", 3, Geom.NT_float32, Geom.C_normal) array.add_column("color", 3, Geom.NT_float32, Geom.C_color) array.add_column("texcoord", 3, Geom.NT_float32, Geom.C_texcoord) format = GeomVertexFormat() format.add_array(array) format = GeomVertexFormat.register_format(format) vdata = GeomVertexData("test", format, Geom.UH_static) vdata.set_num_rows(4) vertex = GeomVertexWriter(vdata, 'vertex') normal = GeomVertexWriter(vdata, 'normal') color = GeomVertexWriter(vdata, 'color') texcoord = GeomVertexWriter(vdata, 'texcoord') vertex.add_data3f(1, 0, 0) normal.add_data3f(0, 0, 1) color.add_data4f(0, 0, 1, 1) texcoord.add_data2f(1, 0) vertex.add_data3f(1, 1, 0) normal.add_data3f(0, 1, 1) color.add_data4f(1, 0, 1, 1) texcoord.add_data2f(1, 1) geom = Geom(vdata) node = GeomNode('gnode') node.add_geom(geom) return node
def makeGeom(self, points, colors, sizes): #format = GeomVertexFormat.getV3c4() array = GeomVertexArrayFormat() array.addColumn(InternalName.get_vertex(), 3, Geom.NTFloat32, Geom.CPoint) array.addColumn(InternalName.get_color(), 4, Geom.NTFloat32, Geom.CColor) array.addColumn(InternalName.get_size(), 1, Geom.NTFloat32, Geom.COther) format = GeomVertexFormat() format.addArray(array) format = GeomVertexFormat.registerFormat(format) vdata = GeomVertexData('vdata', format, Geom.UH_static) vdata.unclean_set_num_rows(len(points)) self.vwriter = GeomVertexWriter(vdata, InternalName.get_vertex()) self.colorwriter = GeomVertexWriter(vdata, InternalName.get_color()) self.sizewriter = GeomVertexWriter(vdata, InternalName.get_size()) geompoints = GeomPoints(Geom.UH_static) geompoints.reserve_num_vertices(len(points)) index = 0 for (point, color, size) in zip(points, colors, sizes): self.vwriter.addData3f(*point) self.colorwriter.addData4f(*color) self.sizewriter.addData1f(size) geompoints.addVertex(index) #geompoints.closePrimitive() index += 1 geom = Geom(vdata) geom.addPrimitive(geompoints) return geom
def __init__(self, base, obj, **kwargs): super(GalaxyView, self).__init__(base, obj, **kwargs) array = GeomVertexArrayFormat() array.addColumn(InternalName.make('vertex'), 3, Geom.NTFloat32, Geom.CPoint) array.addColumn(InternalName.make('color'), 4, Geom.NTFloat32, Geom.CColor) array.addColumn(InternalName.make('size'), 1, Geom.NTFloat32, Geom.COther) gmformat = GeomVertexFormat() gmformat.addArray(array) gmformat = GeomVertexFormat.registerFormat(gmformat) vdata = GeomVertexData('points', gmformat, Geom.UHDynamic) vertex = GeomVertexWriter(vdata, 'vertex') color = GeomVertexWriter(vdata, 'color') size = GeomVertexWriter(vdata, 'size') self.node = NodePath('galaxy') self.node.reparentTo(self.base.render) self.node.setTransparency(TransparencyAttrib.MAlpha) lumsort = sorted([star.luminosity for star in self.obj.stars]) #highest_luminosity = lumsort[-1] median_luminosity = lumsort[len(lumsort) / 2] for star in self.obj.stars: vertex.addData3f(star.galpos.x, star.galpos.y, star.galpos.z) color.addData4f(star.red, star.green, star.blue, 1.0) #size.addData1f(min(100, max(5, 10-star.magnitude/2))) sizeval = 10 + log(star.luminosity) size.addData1f(min(30, max(10, sizeval))) prim = GeomPoints(Geom.UHStatic) prim.addConsecutiveVertices(0, len(self.obj.stars)) prim.closePrimitive() geom = Geom(vdata) geom.addPrimitive(prim) node = GeomNode('gnode') node.addGeom(geom) galaxy_node = self.node.attachNewNode(node) galaxy_node.setRenderModeThickness(1) ts = TextureStage.getDefault() #TextureStage('ts') #ts.setMode(TextureStage.MGlow) galaxy_node.setTexGen(ts, TexGenAttrib.MPointSprite) galaxy_node.setTexture( ts, self.base.loader.loadTexture('texture/flare.png')) #galaxy_node.setRenderModePerspective(True) galaxy_node.setBin("unsorted", 1) galaxy_node.setDepthWrite(0) galaxy_node.setTransparency(1) self.setup_glow_shader() """
def empty_geom(prefix, nb_data, nb_vertices, points=False, normal=True, texture=True, color=False, tanbin=False): array = GeomVertexArrayFormat() array.addColumn(InternalName.make('vertex'), 3, Geom.NTFloat32, Geom.CPoint) if color: array.addColumn(InternalName.make('color'), 4, Geom.NTFloat32, Geom.CColor) if texture: array.addColumn(InternalName.make('texcoord'), 2, Geom.NTFloat32, Geom.CTexcoord) if normal: array.addColumn(InternalName.make('normal'), 3, Geom.NTFloat32, Geom.CVector) if tanbin: array.addColumn(InternalName.make('binormal'), 3, Geom.NTFloat32, Geom.CVector) array.addColumn(InternalName.make('tangent'), 3, Geom.NTFloat32, Geom.CVector) format = GeomVertexFormat() format.addArray(array) format = GeomVertexFormat.registerFormat(format) gvd = GeomVertexData('gvd', format, Geom.UHStatic) if nb_data != 0: gvd.unclean_set_num_rows(nb_data) geom = Geom(gvd) gvw = GeomVertexWriter(gvd, 'vertex') if color: gcw = GeomVertexWriter(gvd, 'color') else: gcw = None if texture: gtw = GeomVertexWriter(gvd, 'texcoord') else: gtw = None if normal: gnw = GeomVertexWriter(gvd, 'normal') else: gnw = None if tanbin: gtanw = GeomVertexWriter(gvd, 'tangent') gbiw = GeomVertexWriter(gvd, 'binormal') else: gtanw = None gbiw = None if points: prim = GeomPoints(Geom.UHStatic) else: prim = GeomTriangles(Geom.UHStatic) if nb_vertices != 0: prim.reserve_num_vertices(nb_vertices) return (gvw, gcw, gtw, gnw, gtanw, gbiw, prim, geom)
def create_model(self): # Set up the vertex arrays vformatArray = GeomVertexArrayFormat() # Panda3D implicitly generates a bounding volume from a # column named "vertex", so you either # * have a column of that name, or # * add a bounding volume yourself. vformatArray.addColumn(InternalName.make("vertex"), 3, Geom.NTFloat32, Geom.CPoint) vformatArray.addColumn(InternalName.make("color"), 4, Geom.NTFloat32, Geom.CColor) vformat = GeomVertexFormat() vformat.addArray(vformatArray) vformat = GeomVertexFormat.registerFormat(vformat) vdata = GeomVertexData("Data", vformat, Geom.UHStatic) vertex = GeomVertexWriter(vdata, 'vertex') color = GeomVertexWriter(vdata, 'color') geom = Geom(vdata) # Vertex data vertex.addData3f(1.5, 0, -1) color.addData4f(1, 0, 0, 1) vertex.addData3f(-1.5, 0, -1) color.addData4f(0, 1, 0, 1) vertex.addData3f(0, 0, 1) color.addData4f(0, 0, 1, 1) # Primitive tri = GeomPatches(3, Geom.UHStatic) tri.add_vertex(2) tri.add_vertex(1) tri.add_vertex(0) tri.close_primitive() geom.addPrimitive(tri) # Create the actual node node = GeomNode('geom_node') node.addGeom(geom) np = NodePath(node) # Shader, initial shader vars, number of instances np.set_shader( Shader.load(Shader.SL_GLSL, vertex="shader.vert", tess_control="shader.tesc", tess_evaluation="shader.tese", geometry="shader.geom", fragment="shader.frag")) np.set_shader_input("time", 0.0) np.set_shader_input("tess_level", 32.0) np.set_instance_count(num_instances) np.set_shader_input("numInstances", num_instances) return np
def __init__(self, __occupying_unit = None, __occupiable = True, x = 0, z = 0, r = 5, tag = 0): self.__occupying_unit = __occupying_unit self.__occupiable = __occupiable self.__r = r self.__x = x self.__z = z self.__tag = tag #Procedurally creating a hex! geometry_array = GeomVertexArrayFormat() geometry_array.addColumn(InternalName.make('vertex'), 3, Geom.NTFloat32, Geom.CPoint) geometry_array.addColumn(InternalName.make('normal'), 3, Geom.NTFloat32, Geom.CPoint) format = GeomVertexFormat() format.addArray(geometry_array) format = GeomVertexFormat.registerFormat(format) self.__vdata = GeomVertexData('Hex', format, Geom.UHStatic) self.__vertex = GeomVertexWriter(self.__vdata, 'vertex') self.__normal = GeomVertexWriter(self.__vdata, 'normal') #Vertex 1 self.__vertex.addData3f(self.__x, self.__z+self.__r, 0) self.__normal.addData3f(1, 0, 0) #Vertex 2 self.__vertex.addData3f(self.__x+self.__r*sin(pi/3), self.__z+self.__r*cos(pi/3), 0) self.__normal.addData3f(1, 0, 0) #Vertex 3 self.__vertex.addData3f(self.__x+self.__r*sin(pi/3), self.__z-self.__r*cos(pi/3), 0) self.__normal.addData3f(1, 0, 0) #Vertex 4 self.__vertex.addData3f(self.__x, self.__z-self.__r, 0) self.__normal.addData3f(1, 0, 0) #Vertex 5 self.__vertex.addData3f(self.__x-self.__r*sin(pi/3), self.__z-self.__r*cos(pi/3), 0) self.__normal.addData3f(1, 0, 0) #Vertex 6 self.__vertex.addData3f(self.__x-self.__r*sin(pi/3), self.__z+self.__r*cos(pi/3), 0) self.__normal.addData3f(1, 0, 0) self.__hex_primitive = GeomTrifans(Geom.UHStatic) self.__hex_primitive.addVertices(5, 4) self.__hex_primitive.addVertices(3, 2) self.__hex_primitive.addVertices(1, 0) self.__hex_primitive.closePrimitive() self.__hex_geometry = Geom(self.__vdata) self.__hex_geometry.addPrimitive(self.__hex_primitive) self.__hex_node = GeomNode('HexNode') self.__hex_node.addGeom(self.__hex_geometry) nodePath = render.attachNewNode(self.__hex_node) nodePath.setTag( "hex", str(tag) ) nodePath.node().setIntoCollideMask(BitMask32.bit(1)) nodePath.hide()
def create_model(self): # Set up the vertex arrays vformatArray = GeomVertexArrayFormat() # Panda3D implicitly generates a bounding volume from a # column named "vertex", so you either # * have a column of that name, or # * add a bounding volume yourself. vformatArray.addColumn(InternalName.make("vertex"), 3, Geom.NTFloat32, Geom.CPoint) vformatArray.addColumn(InternalName.make("color"), 4, Geom.NTFloat32, Geom.CColor) vformat = GeomVertexFormat() vformat.addArray(vformatArray) vformat = GeomVertexFormat.registerFormat(vformat) vdata = GeomVertexData("Data", vformat, Geom.UHStatic) vertex = GeomVertexWriter(vdata, 'vertex') color = GeomVertexWriter(vdata, 'color') geom = Geom(vdata) # Vertex data vertex.addData3f(1.5, 0, -1) color.addData4f(1, 0, 0, 1) vertex.addData3f(-1.5, 0, -1) color.addData4f(0, 1, 0, 1) vertex.addData3f(0, 0, 1) color.addData4f(0, 0, 1, 1) # Primitive tri = GeomPatches(3, Geom.UHStatic) tri.add_vertex(2) tri.add_vertex(1) tri.add_vertex(0) tri.close_primitive() geom.addPrimitive(tri) # Create the actual node node = GeomNode('geom_node') node.addGeom(geom) np = NodePath(node) # Shader, initial shader vars, number of instances np.set_shader(Shader.load(Shader.SL_GLSL, vertex = "shader.vert", tess_control = "shader.tesc", tess_evaluation = "shader.tese", geometry = "shader.geom", fragment = "shader.frag")) np.set_shader_input("time", 0.0) np.set_shader_input("tess_level", 32.0) np.set_instance_count(num_instances) np.set_shader_input("numInstances", num_instances) return np
class MyGeomVertexArrayFormat: """ Class which is supposed to extend the existing vertex array format of Panda3d Panda supports : vertex, color, normal and uv-coordinates natively. However, for normal (bump)-mapping, tangent and binormal vector for each vertex are required. Thus: vertex: Vertex in 3D space color: Color in 4D color space (rgb with alpha channel) normal: normal vector of vertex, e.g. required for smooth lightning tangent: tangent vector to the normal vector of the vertex. Required for normal(bump) mapping bi-normal: sometimes referred to as bi-tangent. Cross product of normal and tangent vector n_v x t_v texcoord: UV coordinates -> mapping of each vertex to a 2D [0,1]x[0,1] space """ # noinspection PyArgumentList,PyCallByClass def __init__(self): array_format = GeomVertexArrayFormat() array_format.addColumn( InternalName.make(ArrayFormatColunm.Vertex.value), 3, Geom.NT_float32, Geom.C_point) array_format.addColumn( InternalName.make(ArrayFormatColunm.Color.value), 4, Geom.NT_uint8, Geom.C_color) array_format.addColumn( InternalName.make(ArrayFormatColunm.Normal.value), 3, Geom.NT_float32, Geom.C_normal) array_format.addColumn( InternalName.make(ArrayFormatColunm.Tangent.value), 3, Geom.NT_float32, Geom.C_vector) array_format.addColumn( InternalName.make(ArrayFormatColunm.Binormal.value), 3, Geom.NT_float32, Geom.C_vector) array_format.addColumn( InternalName.make(ArrayFormatColunm.UVMap.value), 2, Geom.NT_float32, Geom.C_texcoord) self.vertex_format = GeomVertexFormat() self.vertex_format.addArray(array_format) self.vertex_format = GeomVertexFormat.registerFormat( self.vertex_format) @staticmethod def get_column_name(column_name: ArrayFormatColunm) -> str: return column_name.value @staticmethod def get_writer(geom: Geom, column_name: ArrayFormatColunm) -> GeomVertexReader: vertex_data = geom.modifyVertexData() return GeomVertexReader(vertex_data, column_name.value)
def _create_geom(self): color = ConfigVariableColor('grid-color', DEFAULT_GRID_COLOR) radius = floor(self.size / (2 * self.spacing)) diameter = (2 * radius + 1) start = -radius * self.spacing vertex_format = GeomVertexFormat.get_v3c4() vertex_data = GeomVertexData('grid', vertex_format, Geom.UH_static) vertex_data.set_num_rows(diameter * 4) vertex_writer = GeomVertexWriter(vertex_data, 'vertex') color_writer = GeomVertexWriter(vertex_data, 'color') for i, j in product(range(diameter), repeat=2): vertex_writer.add_data3f(start + i * self.spacing, start + j * self.spacing, 0.0) alpha = GRID_ALPHA - GRID_ALPHA * ( Vector(i - radius, j - radius).norm() / radius) color_writer.add_data4f(color[0], color[1], color[2], alpha) primitive = GeomLinestrips(Geom.UH_static) for vertex in vertex_indexes(diameter): primitive.add_vertex(vertex) primitive.close_primitive() self.geom = Geom(vertex_data) self.geom.add_primitive(primitive)
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, diameter, density): self.fmt = GeomVertexFormat.getV3c4() self.diameter = diameter r = diameter / 2 # Sample random points in a 2d plane points_2d = [] for i in range(int(density * pi * r**2)): x, y = random_in_circle() points_2d.append((x * r, y * r)) # Compute triangulations triangulation = DelaunayTri(points_2d) # Save points in 3d space self.points = [] for x, y in triangulation.points: p = Vec3(x, y, elevation(x, y)) self.points.append(p) # Save triangles self.vertices = triangulation.vertices # Save a graph with the triangulation self.nodes = [set() for i in range(len(self.points))] self.edges = [] for a, b, c in triangulation.vertices: self.nodes[a] |= {b, c} self.nodes[b] |= {a, c} self.nodes[c] |= {a, b} self.edges.append((a, b)) self.edges.append((b, c)) self.edges.append((c, a))
def __build_Writers(self): # Build Vdata. array = GeomVertexArrayFormat() for field_name, field_spec_name in list(self.field_types.items()): field_specs = self._data_types[field_spec_name][:-1] array.addColumn(InternalName.make(field_name), *field_specs) vformat = GeomVertexFormat() vformat.addArray(array) vformat = GeomVertexFormat.registerFormat(vformat) vdata = GeomVertexData("data", vformat, Geom.UHStatic) # Build GeomVertexWriters. writers = {} for field_name in list(self.field_types.keys()): writers[field_name] = GeomVertexWriter(vdata, field_name) return vdata, writers
def makePoints(n=1000): """ make a cloud of points that are a single node VS branching and making subnodes to control display """ #points = np.random.uniform(-10,10,(n,4)) points = np.random.randn(n,3) colors = np.random.rand(n,4) fmt = GeomVertexFormat.getV3c4() #3 component vertex, w/ 4 comp color vertexData = GeomVertexData('points', fmt, Geom.UHStatic) verts = GeomVertexWriter(vertexData, 'vertex') color = GeomVertexWriter(vertexData, 'color') for point,clr4 in zip(points,colors): #for point in points: verts.addData3f(*point) #color.addData4f(*point) color.addData4f(*clr4) #color.addData4f(.1,.1,.1,1) #pointCloud = GeomLinestrips(Geom.UHStatic) #this is f*****g cool! pointCloud = GeomTristrips(Geom.UHStatic) #this is f*****g cool! #pointCloud = GeomPoints(Geom.UHStatic) #pointCloud.addVerticies(*range(n)) pointCloud.addConsecutiveVertices(0,n) #warning may error since n-1? pointCloud.closePrimitive() cloud = Geom(vertexData) cloud.addPrimitive(pointCloud) return cloud
def __build_Star_Sphere(self, bg_stars): from panda3d.core import GeomVertexWriter, GeomVertexFormat, GeomVertexData from panda3d.core import Geom, GeomNode, GeomPoints, AmbientLight self.star_sphere_np.removeNode() # Fill GeomVertexData. vformat = GeomVertexFormat.getV3c4() vdata = GeomVertexData("Data", vformat, Geom.UHStatic) vertices = GeomVertexWriter(vdata, "vertex") colours = GeomVertexWriter(vdata, "color") for coords in bg_stars: x, y, z = coords vertices.addData3f(x, y, z) colours.addData4f(1, 1, 1, 1) # Render bg stars. bg_stars = GeomPoints(Geom.UHStatic) bg_stars.addNextVertices(_env.STAR_COUNT) bg_stars_geom = Geom(vdata) bg_stars_geom.addPrimitive(bg_stars) star_sphere = GeomNode("star_sphere") star_sphere.addGeom(bg_stars_geom) star_sphere_np = NodePath(star_sphere) star_sphere_np.reparentTo(self.NP) return star_sphere_np
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 addMeshConvexRB(self,vertices, faces,ghost=False,**kw): #step 1) create GeomVertexData and add vertex information format=GeomVertexFormat.getV3() vdata=GeomVertexData("vertices", format, Geom.UHStatic) vertexWriter=GeomVertexWriter(vdata, "vertex") [vertexWriter.addData3f(v[0],v[1],v[2]) for v in vertices] #step 2) make primitives and assign vertices to them tris=GeomTriangles(Geom.UHStatic) [self.setGeomFaces(tris,face) for face in faces] #step 3) make a Geom object to hold the primitives geom=Geom(vdata) geom.addPrimitive(tris) #step 4) create the bullet mesh and node mesh = BulletTriangleMesh() mesh.addGeom(geom) shape = BulletConvexHullShape(mesh, dynamic=not ghost)# if ghost : inodenp = self.worldNP.attachNewNode(BulletGhostNode('Mesh')) else : inodenp = self.worldNP.attachNewNode(BulletRigidBodyNode('Mesh')) inodenp.node().addShape(shape) # inodenp.setPos(0, 0, 0.1) self.setRB(inodenp,**kw) inodenp.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(inodenp.node()) return inodenp
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 makeSimpleGeom(array, ctup, geomType = GeomPoints, fix = False): fmt = GeomVertexFormat.getV3c4() vertexData = GeomVertexData('points', fmt, Geom.UHDynamic) #FIXME use the index for these too? with setPythonTag, will have to 'reserve' some cloudGeom = Geom(vertexData) cloudNode = GeomNode('just some points') verts = GeomVertexWriter(vertexData, 'vertex') color = GeomVertexWriter(vertexData, 'color') if fix: if len(ctup) == len(array): for point,c in zip(array, ctup): verts.addData3f(*point) color.addData4f(*c) else: for point in array: verts.addData3f(*point) color.addData4f(*ctup) else: for point in array: verts.addData3f(*point) color.addData4f(*ctup) points = geomType(Geom.UHDynamic) points.addConsecutiveVertices(0,len(array)) points.closePrimitive() cloudGeom.addPrimitive(points) cloudNode.addGeom(cloudGeom) #TODO figure out if it is faster to add and subtract Geoms from geom nodes... if fix: return cloudNode.__reduce__() else: return cloudNode # decoding fails becuase ForkingPickler is called for reasons beyond comprehension
def makeSimpleGeomBuffer(array, color, geomType=GeomPoints): """ massively faster than the nonbuffer version """ full = [tuple(d) for d in np.hstack((array,color))] fmt = GeomVertexFormat.getV3c4() vertexData = GeomVertexData('points', fmt, Geom.UHDynamic) #FIXME use the index for these too? with setPythonTag, will have to 'reserve' some cloudGeom = Geom(vertexData) cloudNode = GeomNode('just some points') vertexData.setNumRows(len(array)) mem_array = vertexData.modifyArray(0) view = memoryview(mem_array) arr = np.asarray(view) arr[:] = full points = geomType(Geom.UHDynamic) points.addConsecutiveVertices(0,len(array)) points.closePrimitive() cloudGeom.addPrimitive(points) cloudNode.addGeom(cloudGeom) return cloudNode
def makeSimpleGeomBuffer(array, color, geomType=GeomPoints): """ massively faster than the nonbuffer version """ full = [tuple(d) for d in np.hstack((array, color))] fmt = GeomVertexFormat.getV3c4() vertexData = GeomVertexData( 'points', fmt, Geom.UHDynamic ) #FIXME use the index for these too? with setPythonTag, will have to 'reserve' some cloudGeom = Geom(vertexData) cloudNode = GeomNode('just some points') vertexData.setNumRows(len(array)) mem_array = vertexData.modifyArray(0) view = memoryview(mem_array) arr = np.asarray(view) arr[:] = full points = geomType(Geom.UHDynamic) points.addConsecutiveVertices(0, len(array)) points.closePrimitive() cloudGeom.addPrimitive(points) cloudNode.addGeom(cloudGeom) return cloudNode
def _makeGeom(array,ctup,i,pipe, geomType=GeomPoints): #XXX testing multiple Geom version ... for perf seems like it will be super slow #SUUUPER slow TONS of draw calls #wwwayyy better to make a bunch of geoms ahead of time... """ multiprocessing capable geometery maker """ fmt = GeomVertexFormat.getV3c4() cloudNode = GeomNode('bin %s selectable'%(i)) for point in array: vertexData = GeomVertexData('poitn', fmt, Geom.UHStatic) GeomVertexWriter(vertexData, 'vertex').addData3f(*point) GeomVertexWriter(vertexData, 'color').addData4f(*ctup) #verts.addData3f(*point) #color.addData4f(*ctup) points = geomType(Geom.UHStatic) points.addVertex(0) points.closePrimitive() cloudGeom = Geom(vertexData) cloudGeom.addPrimitive(points) cloudNode.addGeom(cloudGeom) #TODO figure out if it is faster to add and subtract Geoms from geom nodes... #output[i] = cloudNode #print('ping',{i:cloudNode}) #pipe.send((i,)) #out = q.get() #print('pong',out) #q.put(out) if pipe == None: return (cloudNode) pipe.send(cloudNode.encodeToBamStream()) #FIXME make this return a pointer NOPE
def makeRotationGeomNode(): vdata = GeomVertexData('rotHandleData', GeomVertexFormat.getV3(), Geom.UHStatic) v = GeomVertexWriter(vdata, 'vertex') radius = 0.7 width = 0.08 res = 30 innerRad = radius - width for i in xrange(res): theta = i*(2*pi/res) v.addData3f(innerRad*sin(theta), innerRad*cos(theta), width/2.0) v.addData3f(innerRad*sin(theta), innerRad*cos(theta), -width/2.0) v.addData3f(radius*sin(theta), radius*cos(theta), width/2.0) v.addData3f(radius*sin(theta), radius*cos(theta), -width/2.0) circle = Geom(vdata) # Make prims for the faces of the torus faces = [GeomTristrips(Geom.UHStatic) for i in xrange(4)] for i in xrange(res): i = i*4 faces[0].addVertices(i + 1, i) faces[1].addVertices(i + 2, i + 1) faces[2].addVertices(i + 3, i + 2) faces[3].addVertices(i, i + 3) for i in xrange(4): faces[i].addVertices((i + 1) % 4, i) faces[i].closePrimitive() circle.addPrimitive(faces[i]) node = GeomNode('geomnode') node.addGeom(circle) return node
def create_model(self): # Set up the vertex arrays vformat = GeomVertexFormat.get_v3c4() vdata = GeomVertexData("Data", vformat, Geom.UHStatic) vertex = GeomVertexWriter(vdata, 'vertex') color = GeomVertexWriter(vdata, 'color') geom = Geom(vdata) # Vertex data vertex.addData3f(1.5, 0, -1) color.addData4f(1, 0, 0, 1) vertex.addData3f(-1.5, 0, -1) color.addData4f(0, 1, 0, 1) vertex.addData3f(0, 0, 1) color.addData4f(0, 0, 1, 1) # Primitive tri = GeomTriangles(Geom.UHStatic) tri.add_vertex(2) tri.add_vertex(1) tri.add_vertex(0) tri.close_primitive() geom.addPrimitive(tri) # Create the actual node node = GeomNode('geom_node') node.addGeom(geom) np = NodePath(node) # Shader and initial shader vars np.set_shader( Shader.load(Shader.SL_GLSL, "shader/shader.vert", "shader/shader.frag")) np.set_shader_input("time", 0.0) # No instancing necessary #np.set_instance_count(27) # return np np.reparent_to(base.render) self.model = np
def makeSelectRect(): ctup = (1,1,1,1) fmt = GeomVertexFormat.getV3c4() vertexData = GeomVertexData('points', fmt, Geom.UHDynamic) points = ( #makes nice for Tristrips (0,0,0), (0,0,1), (1,0,0), (1,0,1), ) verts = GeomVertexWriter(vertexData, 'vertex') color = GeomVertexWriter(vertexData, 'color') for point in points: verts.addData3f(*point) color.addData4f(*ctup) boxLines = GeomLinestrips(Geom.UHDynamic) boxLines.addVertices(0,1,3,2) boxLines.addVertex(0) boxLines.closePrimitive() boxTris = GeomTristrips(Geom.UHDynamic) boxTris.addConsecutiveVertices(0,3) boxTris.closePrimitive() box = Geom(vertexData) box.addPrimitive(boxLines) #box.addPrimitive(boxTris) return box
def draw_rain_mesh(self): _format = GeomVertexFormat.get_v3cp() self.rain_vdata = GeomVertexData('rain', _format, Geom.UHDynamic) self.rain_vdata.setNumRows(self.n_points**2) vertex = GeomVertexWriter(self.rain_vdata, 'vertex') color = GeomVertexWriter(self.rain_vdata, 'color') for j in range(self.n_points): for i in range(self.n_points): # Rain Vertices vertex.addData3f(self.x[j][i], self.y[j][i], self.n_points) # Rain Colors color.addData4f(0.3, 0.3, 1, 0) # Rain Primitive prim = GeomPoints(Geom.UHDynamic) for j in range(self.n_points): for i in range(self.n_points): prim.add_vertices(j * (self.n_points) + i, j * (self.n_points) + i, j * (self.n_points) + i) geom = Geom(self.rain_vdata) prim.closePrimitive() geom.addPrimitive(prim) node = GeomNode('gnode') node.addGeom(geom) rain_nodePath = render.attachNewNode(node) rain_nodePath.setTransparency(TransparencyAttrib.MAlpha) rain_nodePath.setAntialias(AntialiasAttrib.MAuto) rain_nodePath.setRenderModeThickness(2) rain_nodePath.setPos(-50, -50, 0)
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 draw_face(self,f,f_color): #add normal format = GeomVertexFormat.getV3n3cp() vdata=GeomVertexData('vert', format, Geom.UHDynamic) vertex=GeomVertexWriter(vdata, 'vertex') color=GeomVertexWriter(vdata, 'color') normal=GeomVertexWriter(vdata, 'normal') vertex.addData3f(f.v1.pos) normal.addData3f(f.v1.norm.x, f.v1.norm.y, f.v1.norm.z) color.addData4f(f_color) vertex.addData3f(f.v2.pos) normal.addData3f(f.v2.norm.x, f.v2.norm.y, f.v2.norm.z) color.addData4f(f_color) vertex.addData3f(f.v3.pos) normal.addData3f(f.v3.norm.x, f.v3.norm.y, f.v3.norm.z) color.addData4f(f_color) mesh = Geom(vdata) tri = GeomTriangles(Geom.UHDynamic) tri.addVertex(0) tri.addVertex(1) tri.addVertex(2) tri.closePrimitive() mesh.addPrimitive(tri) face_node = GeomNode(self.mesh.name+'_face_'+str(f.ID)) face_node.addGeom(mesh) face_node.setTag('ID',str(f.ID)) rendered_face = self.render_root.attachNewNode(face_node) rendered_face.setTwoSided(True) self.render_nodes['face_'+str(f.ID)] = rendered_face
def __init__(self, length=1., tickness=3.): GeomNode.__init__(self, "Basis") self.vertexData = GeomVertexData("Basis", GeomVertexFormat.getV3c4(), Geom.UHStatic) self.vertex = GeomVertexWriter(self.vertexData, 'vertex') self.color = GeomVertexWriter(self.vertexData, 'color') self.mesh = Geom(self.vertexData) self.lines = GeomLines(Geom.UHStatic) self.vertex.addData3f(0.0, 0.0, 0.0) self.color.addData4f(1.0, 0.0, 0.0, 1.0) self.vertex.addData3f(length, 0.0, 0.0) self.color.addData4f(1.0, 0.0, 0.0, 1.0) self.lines.add_vertices(0, 1) self.vertex.addData3f(0.0, 0.0, 0.0) self.color.addData4f(0.0, 1.0, 0.0, 1.0) self.vertex.addData3f(0.0, length, 0.0) self.color.addData4f(0.0, 1.0, 0.0, 1.0) self.lines.add_vertices(2, 3) self.vertex.addData3f(0.0, 0.0, 0.0) self.color.addData4f(0.0, 0.0, 1.0, 1.0) self.vertex.addData3f(0.0, 0.0, length) self.color.addData4f(0.0, 0.0, 1.0, 1.0) self.lines.add_vertices(4, 5) self.lines.closePrimitive() self.mesh.addPrimitive(self.lines) self.addGeom(self.mesh) NodePath(self).setRenderModeThickness(tickness) NodePath(self).setLightOff() NodePath(self).setColorOff() NodePath(self).set_bin('fixed', 9)
def newVertexData(self): fmt = GeomVertexFormat.getV3c4() # fmt = GeomVertexFormat.getV3n3c4() self.vertexData = GeomVertexData("path", fmt, Geom.UHStatic) self.vertexWriter = GeomVertexWriter(self.vertexData, "vertex") # self.normalWriter = GeomVertexWriter(self.vertexData, 'normal') self.colorWriter = GeomVertexWriter(self.vertexData, "color")
def create_instance(self): self.vertexData = GeomVertexData('vertexData', GeomVertexFormat.getV3c4(), Geom.UHStatic) self.vertexWriter = GeomVertexWriter(self.vertexData, 'vertex') self.colorwriter = GeomVertexWriter(self.vertexData, 'color') for point in self.points: position = point.project(0, self.context.observer.camera_global_pos, self.context.observer.infinity) self.vertexWriter.addData3f(*position) self.colorwriter.addData4f(*self.color) self.lines = GeomLines(Geom.UHStatic) index = 0 for i in range(len(self.points) - 1): self.lines.addVertex(index) self.lines.addVertex(index + 1) self.lines.closePrimitive() index += 1 self.geom = Geom(self.vertexData) self.geom.addPrimitive(self.lines) self.node = GeomNode("boundary") self.node.addGeom(self.geom) self.instance = NodePath(self.node) self.instance.setRenderModeThickness(settings.boundary_thickness) self.instance.reparentTo(self.context.annotation) self.instance.setBin('background', settings.boundaries_depth) self.instance.set_depth_write(False)
def create_model(self): # Set up the vertex arrays vformat = GeomVertexFormat.get_v3c4() vdata = GeomVertexData("Data", vformat, Geom.UHStatic) vertex = GeomVertexWriter(vdata, 'vertex') color = GeomVertexWriter(vdata, 'color') geom = Geom(vdata) # Vertex data vertex.addData3f(1.5, 0, -1) color.addData4f(1, 0, 0, 1) vertex.addData3f(-1.5, 0, -1) color.addData4f(0, 1, 0, 1) vertex.addData3f(0, 0, 1) color.addData4f(0, 0, 1, 1) # Primitive tri = GeomTriangles(Geom.UHStatic) tri.add_vertex(2) tri.add_vertex(1) tri.add_vertex(0) tri.close_primitive() geom.addPrimitive(tri) # Create the actual node node = GeomNode('geom_node') node.addGeom(geom) np = NodePath(node) # Shader and initial shader vars np.set_shader(Shader.load(Shader.SL_GLSL, "shader/shader.vert", "shader/shader.frag")) np.set_shader_input("time", 0.0) # No instancing necessary #np.set_instance_count(27) # return np np.reparent_to(base.render) self.model = np
def add_plane(map_width, map_height): # Prepare the vertex format writers v_fmt = GeomVertexFormat.getV3n3c4() v_data = GeomVertexData('TerrainData', v_fmt, Geom.UHStatic) vertex = GeomVertexWriter(v_data, 'vertex') normal = GeomVertexWriter(v_data, 'normal') color = GeomVertexWriter(v_data, 'color') #texcoord = GeomVertexWriter(v_data, 'texcoord') # Create a primitive prim = GeomTrifans(Geom.UHStatic) poly_color = (uniform(0, 0.05), uniform(0, 0.5), uniform(0.5, 1), 0.5, ) for i, point in enumerate([ (-map_width/2, -map_height/2), (map_width/2, -map_height/2), (map_width/2, map_height/2), (-map_width/2, map_height/2), ]): x, y = point vertex.addData3f(x, y, 0) normal.addData3f(0, 0, 1) color.addData4f(*poly_color) #texcoord.addData2f(1, 0) prim.addVertex(i) prim.addVertex(0) prim.closePrimitive() # Add to the scene graph geom = Geom(v_data) geom.addPrimitive(prim) node = GeomNode('gnode') node.addGeom(geom) nodePath = render.attachNewNode(node) nodePath.setTwoSided(True) nodePath.setAlphaScale(0.5)
def createColoredUnitDisk(color_vec4=Vec4(0., 0., 1., 1.), num_of_verts=10, origin_point=Vec3(0., 0., 0.), radius=1.): # Own Geometry # format = GeomVertexFormat.getV3c4t2() format = GeomVertexFormat.getV3c4() vdata = GeomVertexData("colored_circle", format, Geom.UHStatic) vdata.setNumRows(4) vertexPosWriter = GeomVertexWriter(vdata, "vertex") # num_of_verts = 10 # phi = 0. r = radius # origin_point_x = 0. # origin_point_z = 0. vertexPosWriter.addData3f(origin_point[0], origin_point[1], origin_point[2]) circle_points = math_utils.get_circle_vertices(num_of_verts=num_of_verts, radius=r) circle_points[:,0] += origin_point[0] circle_points[:,1] += origin_point[1] circle_points[:,2] += origin_point[2] _normal_vector_info = Vec3(0., 1., 0.) # this is returned just as info about the normal vector of the generated geometry for p in circle_points: vertexPosWriter.addData3f(p[0], 0, p[1]) # for i in range(num_of_verts): # phi += 2. * np.pi / num_of_verts # x = r * np.cos(phi) # z = r * np.sin(phi) # vertexPosWriter.addData3f(x, 0, z) # let's also add color to each vertex colorWriter = GeomVertexWriter(vdata, "color") colorWriter.addData4f(color_vec4) # origin point for i in range(num_of_verts): colorWriter.addData4f(color_vec4) # make primitives and assign vertices to them (primitives and primitive # groups can be made independently from vdata, and are later assigned # to vdata) tris = GeomTrifans(Geom.UHStatic) # the first vertex is a vertex that all triangles share tris.add_consecutive_vertices(0, num_of_verts+1) tris.addVertex(1) tris.closePrimitive() # the 1st primitive is finished # make a Geom object to hold the primitives geom = Geom(vdata) geom.addPrimitive(tris) geom_node = GeomNode("colored_circle_node") geom_node.addGeom(geom) return geom_node, _normal_vector_info
def create_GeomNode_Single_Point(color_vec4=Vec4(1., 1., 1., 1.)): # ---- step 1: create point at (0,0,0) and close the primitive format = GeomVertexFormat.getV3c4() vdata = GeomVertexData("colored_point", format, Geom.UHStatic) vdata.setNumRows(4) # add color to each vertex colorWriter = GeomVertexWriter(vdata, "color") # add a vertex position to each vertex vertexPosWriter = GeomVertexWriter(vdata, "vertex") # just one origin point vertex, it gets transformed later # to it's intended position vertexPosWriter.addData3f(0., 0., 0.) colorWriter.addData4f(color_vec4) # build the primitive pointsprimitive = GeomPoints(Geom.UHStatic) pointsprimitive.addVertex(0) pointsprimitive.closePrimitive() # this resets all the data contained in the vertexPosWriter and colorWriter # ----- step 3: make a GeomNode out of the Geom (to which the Primitives have been added) # make a Geom object to hold the primitives geom = Geom(vdata) geom.addPrimitive(pointsprimitive) geom_node = GeomNode("colored_point_node") geom_node.addGeom(geom) return geom_node
def __init__(self, name): self.name = name self.poly_groups = [] # GeomVertexFormats # # GeomVertexFormat.getV3cpt2() - vertex, color, uv # GeomVertexFormat.getV3t2() - vertex, uv # GeomVertexFormat.getV3cp() - vertex, color # GeomVertexFormat.getV3n3t2() - vertex, normal, uv # GeomVertexFormat.getV3n3cpt2()- vertex, normal, rgba, uv # textured self.vdata = GeomVertexData(name, GeomVertexFormat.getV3n3cpt2(), Geom.UHStatic) # plain color filled polys # self.vdata = GeomVertexData(name, GeomVertexFormat.getV3cp(), Geom.UHStatic) self.vertex = GeomVertexWriter(self.vdata, 'vertex') self.vnormal = GeomVertexWriter(self.vdata, 'normal') self.color = GeomVertexWriter(self.vdata, 'color') self.texcoord = GeomVertexWriter(self.vdata, 'texcoord') self.root = NodePath(PandaNode(name + '_mesh'))
def pandageom_from_vfnf(vertices, face_normals, triangles, name='auto'): """ :param vertices: nx3 nparray, each row is vertex :param face_normals: nx3 nparray, each row is the normal of a face :param triangles: nx3 nparray, each row is three idx to the vertices :param name: :return: a geom model that is ready to be used to define a nodepath author: weiwei date: 20160613, 20210109 """ # expand vertices to let each triangle refer to a different vert+normal # vertices and normals vertformat = GeomVertexFormat.getV3n3() vertexdata = GeomVertexData(name, vertformat, Geom.UHStatic) vertids = triangles.flatten() multiplied_verticies = np.empty((len(vertids), 3), dtype=np.float32) multiplied_verticies[:] = vertices[vertids] vertex_normals = np.repeat(face_normals.astype(np.float32), repeats=3, axis=0) npstr = np.hstack((multiplied_verticies, vertex_normals)).tobytes() vertexdata.modifyArrayHandle(0).setData(npstr) # triangles primitive = GeomTriangles(Geom.UHStatic) primitive.setIndexType(GeomEnums.NTUint32) multiplied_triangles = np.arange(len(vertids), dtype=np.uint32).reshape(-1, 3) primitive.modifyVertices(-1).modifyHandle().setData( multiplied_triangles.tobytes()) # make geom geom = Geom(vertexdata) geom.addPrimitive(primitive) return geom
def pg_draw_tris(pg, render): format = GeomVertexFormat.getV3c4() vdata = GeomVertexData('pgtris', format, Geom.UHStatic) vdata.setNumRows(len(pg.nodes)) vertex = GeomVertexWriter(vdata, 'vertex') color = GeomVertexWriter(vdata, 'color') prim = GeomTriangles(Geom.UHStatic) for pt in pg.nodes: vertex.addData3f(pt.x, pt.y, pt.z) color.addData4f(random.random(), random.random(), random.random(), 1.0) for pt in pg.nodes: if len(pt.conn) > 0: for i, cpt in enumerate(pt.conn): next_cpt = pt.conn[(i + 1) % len(pt.conn)] prim.addVertices(pt.idx, cpt.idx, next_cpt.idx) print("%d - %d - %d" % (pt.idx, cpt.idx, next_cpt.idx)) geom = Geom(vdata) geom.addPrimitive(prim) node = GeomNode('TheTris') node.addGeom(geom) nodePath = render.attachNewNode(node) nodePath.setPos(0, 10, 0)
def __init__(self, wheel_pos, radius, heading): self.radius = radius v_f = GeomVertexFormat.getV3() self.vdata = GeomVertexData('skid', v_f, Geom.UHDynamic) self.vdata.setNumRows(1) self.vertex = GeomVertexWriter(self.vdata, 'vertex') self.prim = GeomTriangles(Geom.UHStatic) self.cnt = 1 self.last_pos = wheel_pos geom = Geom(self.vdata) geom.addPrimitive(self.prim) node = GeomNode('gnode') node.addGeom(geom) nodePath = render.attachNewNode(node) nodePath.setTransparency(True) nodePath.setDepthOffset(1) self.__set_material(nodePath) nodePath.node().setBounds(OmniBoundingVolume()) self.add_vertices(radius, heading) self.add_vertices(radius, heading) self.remove_seq = Sequence( Wait(8), LerpFunc(nodePath.setAlphaScale, 8, 1, 0, 'easeInOut'), Func(nodePath.remove_node)) self.remove_seq.start()
def create_instance(self): self.vertexData = GeomVertexData('vertexData', GeomVertexFormat.getV3(), Geom.UHStatic) self.vertexWriter = GeomVertexWriter(self.vertexData, 'vertex') radius = 1.0 top = LPoint3d(0, 0, radius * 1.25) north_pole = LPoint3d(0, 0, radius) south_pole = LPoint3d(0, 0, -radius) bottom = LPoint3d(0, 0, -radius * 1.25) self.vertexWriter.addData3f(*top) self.vertexWriter.addData3f(*north_pole) self.vertexWriter.addData3f(*south_pole) self.vertexWriter.addData3f(*bottom) self.lines = GeomLines(Geom.UHStatic) self.lines.addVertex(0) self.lines.addVertex(1) self.lines.addVertex(2) self.lines.addVertex(3) self.lines.closePrimitive() self.geom = Geom(self.vertexData) self.geom.addPrimitive(self.lines) self.node = GeomNode(self.body.get_ascii_name() + '-axis') self.node.addGeom(self.geom) self.instance = NodePath(self.node) self.instance.setRenderModeThickness(settings.axis_thickness) self.instance.setColor(self.parent.get_orbit_color()) self.instance.setAntialias(AntialiasAttrib.MMultisample) self.instance.reparentTo(self.context.annotation)
def _make_fullscreen_tri(self): """ Creates the oversized triangle used for rendering """ vformat = GeomVertexFormat.get_v3() vdata = GeomVertexData("vertices", vformat, Geom.UH_static) vdata.set_num_rows(3) vwriter = GeomVertexWriter(vdata, "vertex") vwriter.add_data3f(-1, 0, -1) vwriter.add_data3f(3, 0, -1) vwriter.add_data3f(-1, 0, 3) gtris = GeomTriangles(Geom.UH_static) gtris.add_next_vertices(3) geom = Geom(vdata) geom.add_primitive(gtris) geom_node = GeomNode("gn") geom_node.add_geom(geom) geom_node.set_final(True) geom_node.set_bounds(OmniBoundingVolume()) tri = NodePath(geom_node) tri.set_depth_test(False) tri.set_depth_write(False) tri.set_attrib(TransparencyAttrib.make(TransparencyAttrib.M_none), 10000) tri.set_color(Vec4(1)) tri.set_bin("unsorted", 10) tri.reparent_to(self._node) self._tri = tri
def draw(self): if self.rendered_mesh != None: self.reset_draw() format=GeomVertexFormat.getV3n3cp() vdata=GeomVertexData('tri', format, Geom.UHDynamic) vertex=GeomVertexWriter(vdata, 'vertex') normal=GeomVertexWriter(vdata, 'normal') color=GeomVertexWriter(vdata, 'color') v_mapping = {} i=0 for v in self.verts.values(): vertex.addData3f(v.pos.x,v.pos.y,v.pos.z) normal.addData3f(v.norm.x, v.norm.y, v.norm.z) color.addData4f(v.color[0],v.color[1],v.color[2],v.color[3]) v_mapping[v.ID] = i i += 1 mesh = Geom(vdata) for f in self.faces.values(): tri = GeomTriangles(Geom.UHDynamic) tri.addVertex(v_mapping[f.v1.ID]) tri.addVertex(v_mapping[f.v2.ID]) tri.addVertex(v_mapping[f.v3.ID]) tri.closePrimitive() mesh.addPrimitive(tri) snode = GeomNode(self.name) snode.addGeom(mesh) self.rendered_mesh = render.attachNewNode(snode) self.rendered_mesh.setTwoSided(True)
def __init__(self, whl_pos, whl_radius, car_h): GameObject.__init__(self) self.radius = whl_radius v_f = GeomVertexFormat.getV3() vdata = GeomVertexData('skid', v_f, Geom.UHDynamic) prim = GeomTriangles(Geom.UHStatic) self.vtx_cnt = 1 self.last_pos = whl_pos geom = Geom(vdata) geom.add_primitive(prim) self.node = GeomNode('gnode') self.node.add_geom(geom) nodepath = self.eng.gfx.root.attach_node(self.node) nodepath.set_transparency(True) nodepath.set_depth_offset(1) nodepath.node.set_two_sided(True) # for self-shadowing issues self.__set_material(nodepath) nodepath.p3dnode.set_bounds(OmniBoundingVolume()) self.add_vertices(whl_radius, car_h) self.add_vertices(whl_radius, car_h) def alpha(time, n_p): if not n_p.is_empty: n_p.node.set_shader_input('alpha', time) # this if seems necessary since, if there are skidmarks and you # exit from the race (e.g. back to the menu), then alpha is being # called from the interval manager even if the interval manager # correctly says that there are 0 intervals. self.remove_seq = Sequence( Wait(8), LerpFunc(alpha, 8, .5, 0, 'easeInOut', [nodepath]), Func(nodepath.remove_node)) self.remove_seq.start()
def draw(self): if self.rendered_mesh != None: self.reset_draw() format = GeomVertexFormat.getV3n3cp() vdata = GeomVertexData('tri', format, Geom.UHDynamic) vertex = GeomVertexWriter(vdata, 'vertex') normal = GeomVertexWriter(vdata, 'normal') color = GeomVertexWriter(vdata, 'color') v_mapping = {} i = 0 for v in self.verts.values(): vertex.addData3f(v.pos.x, v.pos.y, v.pos.z) normal.addData3f(v.norm.x, v.norm.y, v.norm.z) color.addData4f(v.color[0], v.color[1], v.color[2], v.color[3]) v_mapping[v.ID] = i i += 1 mesh = Geom(vdata) for f in self.faces.values(): tri = GeomTriangles(Geom.UHDynamic) tri.addVertex(v_mapping[f.v1.ID]) tri.addVertex(v_mapping[f.v2.ID]) tri.addVertex(v_mapping[f.v3.ID]) tri.closePrimitive() mesh.addPrimitive(tri) snode = GeomNode(self.name) snode.addGeom(mesh) self.rendered_mesh = render.attachNewNode(snode) self.rendered_mesh.setTwoSided(True)
def makePoints(n=1000): """ make a cloud of points that are a single node VS branching and making subnodes to control display """ #points = np.random.uniform(-10,10,(n,4)) points = np.random.randn(n, 3) colors = np.random.rand(n, 4) fmt = GeomVertexFormat.getV3c4() #3 component vertex, w/ 4 comp color vertexData = GeomVertexData('points', fmt, Geom.UHStatic) verts = GeomVertexWriter(vertexData, 'vertex') color = GeomVertexWriter(vertexData, 'color') for point, clr4 in zip(points, colors): #for point in points: verts.addData3f(*point) #color.addData4f(*point) color.addData4f(*clr4) #color.addData4f(.1,.1,.1,1) #pointCloud = GeomLinestrips(Geom.UHStatic) #this is f*****g cool! pointCloud = GeomTristrips(Geom.UHStatic) #this is f*****g cool! #pointCloud = GeomPoints(Geom.UHStatic) #pointCloud.addVerticies(*range(n)) pointCloud.addConsecutiveVertices(0, n) #warning may error since n-1? pointCloud.closePrimitive() cloud = Geom(vertexData) cloud.addPrimitive(pointCloud) return cloud
def create_geom(self, sidelength): # Set up the vertex arrays vformat = GeomVertexFormat.getV3n3c4() vdata = GeomVertexData("Data", vformat, Geom.UHDynamic) vertex = GeomVertexWriter(vdata, 'vertex') normal = GeomVertexWriter(vdata, 'normal') color = GeomVertexWriter(vdata, 'color') geom = Geom(vdata) # Write vertex data for x in range(0, sidelength): for y in range(0, sidelength): # vertex_number = x * sidelength + y v_x, v_y, v_z = self.map_b[(x, y)] n_x, n_y, n_z = 0.0, 0.0, 1.0 c_r, c_g, c_b, c_a = 0.5, 0.5, 0.5, 0.5 vertex.addData3f(v_x, v_y, v_z) normal.addData3f(n_x, n_y, n_z) color.addData4f(c_r, c_g, c_b, c_a) # Add triangles for x in range(0, sidelength - 1): for y in range(0, sidelength - 1): # The vertex arrangement (y up, x right) # 2 3 # 0 1 v_0 = x * sidelength + y v_1 = x * sidelength + (y + 1) v_2 = (x + 1) * sidelength + y v_3 = (x + 1) * sidelength + (y + 1) if (x+y)%1 == 0: # An even square tris = GeomTriangles(Geom.UHStatic) tris.addVertices(v_0, v_2, v_3) tris.closePrimitive() geom.addPrimitive(tris) tris = GeomTriangles(Geom.UHStatic) tris.addVertices(v_3, v_1, v_0) tris.closePrimitive() geom.addPrimitive(tris) else: # An odd square tris = GeomTriangles(Geom.UHStatic) tris.addVertices(v_1, v_0, v_2) tris.closePrimitive() geom.addPrimitive(tris) tris = GeomTriangles(Geom.UHStatic) tris.addVertices(v_2, v_3, v_1) tris.closePrimitive() geom.addPrimitive(tris) # Create the actual node node = GeomNode('geom_node') node.addGeom(geom) # Remember GeomVertexWriters to adjust vertex data later #self.vertex_writer = vertex #self.color_writer = color self.vdata = vdata return node
def makeVertexFormat(color = True, normal = False, texcoord = False, tan_binorm = False): myArray = GeomVertexArrayFormat() myArray.addColumn(InternalName.make('vertex'), 3, Geom.NTFloat32, Geom.CPoint) if color: myArray.addColumn(InternalName.make('color'), 4, Geom.NTFloat32, Geom.CColor) if normal: myArray.addColumn(InternalName.make('normal'), 3, Geom.NTFloat32, Geom.CVector) if texcoord: myArray.addColumn(InternalName.make('texcoord'), 2, Geom.NTFloat32, Geom.CTexcoord) if tan_binorm: myArray.addColumn(InternalName.make('tangent'), 3, Geom.NTFloat32, Geom.CVector) myArray.addColumn(InternalName.make('binormal'), 3, Geom.NTFloat32, Geom.CVector) myFormat = GeomVertexFormat() myFormat.addArray(myArray) myFormat = GeomVertexFormat.registerFormat(myFormat) return myFormat
def __init__(self): ShowBase.__init__(self) PanditorDisableMouseFunc() camera.setPos(0.0, 0.0, 50.0) camera.lookAt(0.0) PanditorEnableMouseFunc() # 1) create GeomVertexData frmt = GeomVertexFormat.getV3n3cp() vdata = GeomVertexData('triangle', frmt, Geom.UHDynamic) # 2) create Writers/Rewriters (must all be created before any readers and readers are one-pass-temporary) vertex = GeomVertexRewriter(vdata, 'vertex') normal = GeomVertexRewriter(vdata, 'normal') color = GeomVertexRewriter(vdata, 'color') zUp = Vec3(0, 0, 1) wt = Vec4(1.0, 1.0, 1.0, 1.0) gr = Vec4(0.5, 0.5, 0.5, 1.0) # 3) write each column on the vertex data object (for speed, have a different writer for each column) def addPoint(x, y, z): vertex.addData3f(x, y, z) normal.addData3f(zUp) color.addData4f(wt) addPoint(0.0, 0.0, 0.0) addPoint(5.0, 0.0, 0.0) addPoint(0.0, 5.0, 0.0) addPoint(5.0, 5.0, 0.0) # 4) create a primitive and add the vertices via index (not truely associated with the actual vertex table, yet) tris = GeomTriangles(Geom.UHDynamic) tris.addVertices(0, 1, 2) tris.closePrimitive() # exception thrown if verts added != 3, other types inform Panda how many verts/primitive tris.addVertices(2, 1, 3) print "vdataPoints", vdata.getArrays()[0] # 5.1) (adding to scene) create a Geom and add primitives of like base-type i.e. triangles and triangle strips geom = Geom(vdata) geom.addPrimitive(tris) # 5.2) create a GeomNode to hold the Geom(s) and add the Geom(s) gn = GeomNode('gnode') gn.addGeom(geom) # 5.3) attache the node to the scene gnNodePath = render.attachNewNode(gn) geomPts = Geom(vdata) pts = GeomPoints(Geom.UHStatic) pts.addVertices(0, 1, 2) pts.closePrimitive() geomPts.addPrimitive(pts) pointsNode = GeomNode('points_node') pointsNode.addGeom(geomPts) pointsNP = render.attachNewNode(pointsNode) pointsNP.setZ(0.5) render.ls()
def registerObject(self, obj): """ Registers a new dynamic object, this will store an index for every vertex, which can be used to read and store last position data in order to compute the velocity. This method also assigns the standard animated shader to the node """ self.debug("Registering dynamic object") # Find all GeomNodes for node in obj.findAllMatches("**/+GeomNode"): geomNode = node.node() geomCount = geomNode.getNumGeoms() # Find all Geoms for i in xrange(geomCount): # Modify vertex data geom = geomNode.modifyGeom(i) geomVertexData = geom.modifyVertexData() # Add a new column named "dovindex" to the vertex data formatArray = GeomVertexArrayFormat() formatArray.addColumn(InternalName.make("dovindex"), 1, GeomEnums.NTUint32, GeomEnums.CIndex) newArrayFormat = GeomVertexFormat(geomVertexData.getFormat()) newArrayFormat.addArray(formatArray) newArrayFormat = GeomVertexFormat.registerFormat(newArrayFormat) # Convert the old vertex data and assign the new vertex data convertedVertexData = geomVertexData.convertTo(newArrayFormat) geom.setVertexData(convertedVertexData) # Write the per-vertex indices the dovindex column newVertexData = geom.modifyVertexData() vtxReader = GeomVertexReader(newVertexData, "vertex") indexWriter = GeomVertexWriter(newVertexData, "dovindex") while not vtxReader.isAtEnd(): data = vtxReader.getData3f() indexWriter.setData1i(self.currentIndex) self.currentIndex += 1 if self.currentIndex > self.maxVertexCount: self.error("Max dynamic vertex count of", self.maxVertexCount, "reached!")
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 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 __init__(self): formatArray = GeomVertexArrayFormat() formatArray.addColumn( InternalName.make("drawFlag"), 1, Geom.NTUint8, Geom.COther) format = GeomVertexFormat(GeomVertexFormat.getV3n3cpt2()) format.addArray(formatArray) self.format = GeomVertexFormat.registerFormat(format) bodydata = GeomVertexData("body vertices", format, Geom.UHStatic) self.barkTexture = loader.loadTexture("barkTexture.jpg") treeNodePath = NodePath("Tree Holder") makeFractalTree(bodydata, treeNodePath, LVector3(4, 4, 7)) treeNodePath.setTexture(self.barkTexture, 1) treeNodePath.reparentTo(render) self.accept("q", self.regenTree) self.accept("w", self.addTree) self.accept("arrow_up", self.upIterations) self.accept("arrow_down", self.downIterations) self.accept("arrow_right", self.upCopies) self.accept("arrow_left", self.downCopies) self.numIterations = 11 self.numCopies = 4 self.upDownEvent = OnscreenText( text="Up/Down: Increase/Decrease the number of iterations (" + str( self.numIterations) + ")", parent=base.a2dTopLeft, align=TextNode.ALeft, style=1, fg=(1, 1, 1, 1), pos=(0.06, -0.22), scale=.05, mayChange=True) self.leftRightEvent = OnscreenText( text="Left/Right: Increase/Decrease branching (" + str( self.numCopies) + ")", parent=base.a2dTopLeft, align=TextNode.ALeft, style=1, fg=(1, 1, 1, 1), pos=(0.06, -0.28), scale=.05, mayChange=True)
def createTriangle(v1, v2, v3, is_flat=False): x1 = v1.x y1 = v1.y z1 = v1.z x2 = v2.x y2 = v2.y z2 = v2.z x3 = v3.x y3 = v3.y z3 = v3.z format=GeomVertexFormat.getV3n3cp() vdata=GeomVertexData('tri', format, Geom.UHDynamic) vertex=GeomVertexWriter(vdata, 'vertex') normal=GeomVertexWriter(vdata, 'normal') color=GeomVertexWriter(vdata, 'color') vertex.addData3f(x1, y1, z1) vertex.addData3f(x2, y2, z2) vertex.addData3f(x3, y3, z3) if is_flat: normVector = norm(Vec3( (x1 + x2 + x3)/3.0, (y1 + y2 + y3)/3.0, (z1+ z2+ z3)/3.0)) normal.addData3f(normVector) normal.addData3f(normVector) normal.addData3f(normVector) else: normal.addData3f(norm(Vec3(x1,y1,z1))) normal.addData3f(norm(Vec3(x2,y2,z2))) normal.addData3f(norm(Vec3(x3,y3,z3))) #adding different colors to the vertex for visibility color.addData4f(0.5,0.5,0.5,1.0) color.addData4f(0.5,0.5,0.5,1.0) color.addData4f(0.5,0.5,0.5,1.0) tri = GeomTriangles(Geom.UHDynamic) tri.addVertex(0) tri.addVertex(1) tri.addVertex(2) tri.closePrimitive() output_tri = Geom(vdata) output_tri.addPrimitive(tri) return output_tri
def makeSquare(x1, y1, z1, x2, y2, z2): format = GeomVertexFormat.getV3n3cpt2() vdata = GeomVertexData('square', format, Geom.UHDynamic) vertex = GeomVertexWriter(vdata, 'vertex') normal = GeomVertexWriter(vdata, 'normal') # color = GeomVertexWriter(vdata, 'color') texcoord = GeomVertexWriter(vdata, 'texcoord') # make sure we draw the sqaure in the right plane if x1 != x2: vertex.addData3(x1, y1, z1) vertex.addData3(x2, y1, z1) vertex.addData3(x2, y2, z2) vertex.addData3(x1, y2, z2) normal.addData3(normalized(2 * x1 - 1, 2 * y1 - 1, 2 * z1 - 1)) normal.addData3(normalized(2 * x2 - 1, 2 * y1 - 1, 2 * z1 - 1)) normal.addData3(normalized(2 * x2 - 1, 2 * y2 - 1, 2 * z2 - 1)) normal.addData3(normalized(2 * x1 - 1, 2 * y2 - 1, 2 * z2 - 1)) else: vertex.addData3(x1, y1, z1) vertex.addData3(x2, y2, z1) vertex.addData3(x2, y2, z2) vertex.addData3(x1, y1, z2) normal.addData3(normalized(2 * x1 - 1, 2 * y1 - 1, 2 * z1 - 1)) normal.addData3(normalized(2 * x2 - 1, 2 * y2 - 1, 2 * z1 - 1)) normal.addData3(normalized(2 * x2 - 1, 2 * y2 - 1, 2 * z2 - 1)) normal.addData3(normalized(2 * x1 - 1, 2 * y1 - 1, 2 * z2 - 1)) # adding different colors to the vertex for visibility # color.addData4f(1.0, 0.0, 0.0, 1.0) # color.addData4f(0.0, 1.0, 0.0, 1.0) # color.addData4f(0.0, 0.0, 1.0, 1.0) # color.addData4f(1.0, 0.0, 1.0, 1.0) texcoord.addData2f(0.0, 1.0) texcoord.addData2f(0.0, 0.0) texcoord.addData2f(1.0, 0.0) texcoord.addData2f(1.0, 1.0) # Quads aren't directly supported by the Geom interface # you might be interested in the CardMaker class if you are # interested in rectangle though tris = GeomTriangles(Geom.UHDynamic) tris.addVertices(0, 1, 3) tris.addVertices(1, 2, 3) square = Geom(vdata) square.addPrimitive(tris) return square