def make_grid(num_ticks=10, step=1.0): """Make a grid geometry. Keyword Arguments: step {float} -- step in meters (default: {1.0}) num_ticks {int} -- ticks number per axis (default: {5}) Returns: Geom -- p3d geometry """ ticks = np.arange(-num_ticks // 2, num_ticks // 2 + 1) * step vformat = GeomVertexFormat.get_v3() vdata = GeomVertexData('vdata', vformat, Geom.UHStatic) vdata.uncleanSetNumRows(len(ticks) * 4) vertex = GeomVertexWriter(vdata, 'vertex') for t in ticks: vertex.addData3(t, ticks[0], 0) vertex.addData3(t, ticks[-1], 0) vertex.addData3(ticks[0], t, 0) vertex.addData3(ticks[-1], t, 0) prim = GeomLines(Geom.UHStatic) prim.addNextVertices(len(ticks) * 4) geom = Geom(vdata) geom.addPrimitive(prim) return geom
def make_plane(size=(1.0, 1.0)): """Make a plane geometry. Arguments: size {tuple} -- plane size x,y Returns: Geom -- p3d geometry """ vformat = GeomVertexFormat.get_v3n3t2() vdata = GeomVertexData('vdata', vformat, Geom.UHStatic) vdata.uncleanSetNumRows(4) vertex = GeomVertexWriter(vdata, 'vertex') normal = GeomVertexWriter(vdata, 'normal') tcoord = GeomVertexWriter(vdata, 'texcoord') quad = ((0, 0), (1, 0), (0, 1), (1, 1)) for u, v in quad: vertex.addData3((u - 0.5) * size[0], (v - 0.5) * size[1], 0) normal.addData3(0, 0, 1) tcoord.addData2(u, v) prim = GeomTriangles(Geom.UHStatic) prim.addVertices(0, 1, 2) prim.addVertices(2, 1, 3) geom = Geom(vdata) geom.addPrimitive(prim) return geom
def make_box(): """Make a uniform box geometry. Returns: Geom -- p3d geometry """ vformat = GeomVertexFormat.get_v3n3t2() vdata = GeomVertexData('vdata', vformat, Geom.UHStatic) vdata.uncleanSetNumRows(24) vertex = GeomVertexWriter(vdata, 'vertex') normal = GeomVertexWriter(vdata, 'normal') tcoord = GeomVertexWriter(vdata, 'texcoord') axes = itertools.permutations(np.eye(3), r=2) quad = ((0, 0), (1, 0), (0, 1), (1, 1)) for x, y in axes: z = np.cross(x, y) for u, v in quad: vertex.addData3(*(x * (u - 0.5) + y * (v - 0.5) + z * 0.5)) normal.addData3(*z) tcoord.addData2(u, v) prim = GeomTriangles(Geom.UHStatic) for i in range(0, 24, 4): prim.addVertices(i + 0, i + 1, i + 2) prim.addVertices(i + 2, i + 1, i + 3) geom = Geom(vdata) geom.addPrimitive(prim) return geom
def make_axes(): """Make an axes geometry. Returns: Geom -- p3d geometry """ vformat = GeomVertexFormat.get_v3c4() vdata = GeomVertexData('vdata', vformat, Geom.UHStatic) vdata.uncleanSetNumRows(6) vertex = GeomVertexWriter(vdata, 'vertex') color = GeomVertexWriter(vdata, 'color') for x, y, z in np.eye(3): vertex.addData3(0, 0, 0) color.addData4(x, y, z, 1) vertex.addData3(x, y, z) color.addData4(x, y, z, 1) prim = GeomLines(Geom.UHStatic) prim.addNextVertices(6) geom = Geom(vdata) geom.addPrimitive(prim) return geom
def make_cylinder(num_segments=16, closed=True): """Make a uniform cylinder geometry. Keyword Arguments: num_segments {int} -- segments number (default: {16}) closed {bool} -- add caps (default: {True}) Returns: Geom -- p3d geometry """ vformat = GeomVertexFormat.get_v3n3t2() vdata = GeomVertexData('vdata', vformat, Geom.UHStatic) vertex = GeomVertexWriter(vdata, 'vertex') normal = GeomVertexWriter(vdata, 'normal') tcoord = GeomVertexWriter(vdata, 'texcoord') cyl_rows = num_segments * 2 cap_rows = num_segments + 1 if closed: vdata.uncleanSetNumRows(cyl_rows + 2 * cap_rows) else: vdata.uncleanSetNumRows(cyl_rows) for phi in np.linspace(0, 2 * np.pi, num_segments): x, y = np.cos(phi), np.sin(phi) for z in (-1, 1): vertex.addData3(x, y, z * 0.5) normal.addData3(x, y, 0) tcoord.addData2(phi / (2 * np.pi), (z + 1) / 2) prim = GeomTriangles(Geom.UHStatic) for i in range(num_segments - 1): prim.addVertices(i * 2, i * 2 + 3, i * 2 + 1) prim.addVertices(i * 2, i * 2 + 2, i * 2 + 3) if closed: for z in (-1, 1): vertex.addData3(0, 0, z * 0.5) normal.addData3(0, 0, z) tcoord.addData2(0, 0) for phi in np.linspace(0, 2 * np.pi, num_segments): x, y = np.cos(phi), np.sin(phi) vertex.addData3(x, y, z * 0.5) normal.addData3(0, 0, z) tcoord.addData2(x, y) for i in range(num_segments): r0 = cyl_rows r1 = r0 + cap_rows prim.addVertices(r0, r0 + i + 1, r0 + i) prim.addVertices(r1, r1 + i, r1 + i + 1) geom = Geom(vdata) geom.addPrimitive(prim) return geom
def make_capsule(radius, length, num_segments=16, num_rings=16): """Make capsule geometry. Arguments: radius {float} -- capsule radius length {float} -- capsule length Keyword Arguments: num_segments {int} -- segments number (default: {16}) num_rings {int} -- rings number (default: {16}) Returns: Geom -- p3d geometry """ vformat = GeomVertexFormat.get_v3n3t2() vdata = GeomVertexData('vdata', vformat, Geom.UHStatic) vdata.uncleanSetNumRows(num_segments * num_rings) vertex = GeomVertexWriter(vdata, 'vertex') normal = GeomVertexWriter(vdata, 'normal') tcoord = GeomVertexWriter(vdata, 'texcoord') for u in np.linspace(0, np.pi, num_rings): for v in np.linspace(0, 2 * np.pi, num_segments): x, y, z = np.cos(v) * np.sin(u), np.sin(v) * np.sin(u), np.cos(u) offset = np.sign(z) * 0.5 * length vertex.addData3(x * radius, y * radius, z * radius + offset) normal.addData3(x, y, z) tcoord.addData2(u / np.pi, v / (2 * np.pi)) prim = GeomTriangles(Geom.UHStatic) for i in range(num_rings - 1): for j in range(num_segments - 1): r0 = i * num_segments + j r1 = r0 + num_segments if i < num_rings - 2: prim.addVertices(r0, r1, r1 + 1) if i > 0: prim.addVertices(r0, r1 + 1, r0 + 1) geom = Geom(vdata) geom.addPrimitive(prim) return geom
class Mesh: 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 addView(self, primitiveType, drawMask, state=None): self.views.append( PolygonView(self, primitiveType, drawMask, renderState=state)) def begin(self, numVerts): self.vertexBuffer.uncleanSetNumRows(numVerts) for view in self.views: view.clear() self.vwriter = GeomVertexWriter(self.vertexBuffer, InternalName.getVertex()) self.twriter = GeomVertexWriter(self.vertexBuffer, InternalName.getTexcoord()) self.nwriter = GeomVertexWriter(self.vertexBuffer, InternalName.getNormal()) def end(self): self.vwriter = None self.nwriter = None self.twriter = None def addFace(self, meshVertices, state=RenderState.makeEmpty()): row = self.vwriter.getWriteRow() for vert in meshVertices: self.vwriter.setData3f(vert.pos) self.nwriter.setData3f(vert.normal) self.twriter.setData2f(vert.texcoord) for view in self.views: view.generateIndices()
def regenerateGeometry(self): # # Generate vertex data # numVerts = len(self.vertices) vdata = GeomVertexData("SolidFace", getFaceFormat(), GeomEnums.UHStatic) vdata.uncleanSetNumRows(len(self.vertices)) vwriter = GeomVertexWriter(vdata, InternalName.getVertex()) twriter = GeomVertexWriter(vdata, InternalName.getTexcoord()) nwriter = GeomVertexWriter(vdata, InternalName.getNormal()) tanwriter = GeomVertexWriter(vdata, InternalName.getTangent()) bwriter = GeomVertexWriter(vdata, InternalName.getBinormal()) for i in range(len(self.vertices)): vert = self.vertices[i] vwriter.setData3f(vert.pos) twriter.setData2f(vert.uv) nwriter.setData3f(self.plane.getNormal()) tanwriter.setData3f(self.material.tangent) bwriter.setData3f(self.material.binormal) # # Generate indices # # Triangles in 3D view prim3D = GeomTriangles(GeomEnums.UHStatic) prim3D.reserveNumVertices((numVerts - 2) * 3) for i in range(1, numVerts - 1): prim3D.addVertices(i + 1, i, 0) prim3D.closePrimitive() # Line loop in 2D view.. using line strips prim2D = GeomLinestrips(GeomEnums.UHStatic) prim2D.reserveNumVertices(numVerts + 1) for i in range(numVerts): prim2D.addVertex(i) # Close off the line strip with the first vertex.. creating a line loop prim2D.addVertex(0) prim2D.closePrimitive() # # Generate mesh objects # geom3D = SolidFaceGeom(vdata) geom3D.setDrawMask(VIEWPORT_3D_MASK) geom3D.setPlaneCulled(True) geom3D.setPlane(self.plane) geom3D.addPrimitive(prim3D) self.index3D = self.solid.addFaceGeom(geom3D, self.state3D) geom3DLines = SolidFaceGeom(vdata) geom3DLines.addPrimitive(prim2D) geom3DLines.setDrawMask(VIEWPORT_3D_MASK) geom3DLines.setDraw(False) self.index3DLines = self.solid.addFaceGeom(geom3DLines, self.state3DLines) geom2D = SolidFaceGeom(vdata) geom2D.addPrimitive(prim2D) geom2D.setDrawMask(VIEWPORT_2D_MASK) self.index2D = self.solid.addFaceGeom(geom2D, self.state2D) self.geom3D = geom3D self.geom3DLines = geom3DLines self.geom2D = geom2D self.vdata = vdata self.hasGeometry = True