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 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 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 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 load(self): if panda3d is None: raise ImportError("Cannot locate Panda3D") #KLUDGE if self.material is not None and self.colors is None: col = self.material.getAmbient() col = (col[0] / col[3], col[1] / col[3], col[2] / col[3], 1.0) self.colors = (col,) * len(self.vertices) #/KLUDGE geom = make_geom(self.vertices, self.normals, self.colors, self.texcoords) prim = GeomTriangles(Geom.UHStatic) for face in self.faces: #TODO: proper tesselation! the current one only works for convex faces first = face[0] curr = face[1] for v in face[2:]: prim.addVertex(curr) prim.addVertex(v) prim.addVertex(first) curr = v prim.closePrimitive() geom.addPrimitive(prim) node = GeomNode(self.name) node.addGeom(geom) self.node = NodePath(node) self.node.setTwoSided(True) if self.material is not None: self.node.setMaterial(self.material, priority=1) self.loaded = True
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 __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
class Sky(object): def __init__(self, mp): vdata = GeomVertexData("name_me", GeomVertexFormat.getV3c4(), Geom.UHStatic) vertex = GeomVertexWriter(vdata, "vertex") color = GeomVertexWriter(vdata, "color") primitive = GeomTristrips(Geom.UHStatic) film_size = base.cam.node().getLens().getFilmSize() x = film_size.getX() / 2.0 z = x * 256.0 / 240.0 vertex.addData3f(x, 90, z) vertex.addData3f(-x, 90, z) vertex.addData3f(x, 90, -z) vertex.addData3f(-x, 90, -z) color.addData4f(VBase4(*mp["backgroundcolor1"])) color.addData4f(VBase4(*mp["backgroundcolor1"])) color.addData4f(VBase4(*mp["backgroundcolor2"])) color.addData4f(VBase4(*mp["backgroundcolor2"])) primitive.addNextVertices(4) primitive.closePrimitive() geom = Geom(vdata) geom.addPrimitive(primitive) self.node = GeomNode("sky") self.node.addGeom(geom) base.camera.attachNewNode(self.node) def remove(self): NodePath(self.node).removeNode()
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 __build_Geom(self, data_dict, tris, prim_type=GeomTriangles): data_list = list(data_dict.items()) _num_rows = 0 for field, data in data_list: if not _num_rows: _num_rows = len(data) writer = self.__writers[field] writer.reserveNumRows(_num_rows) set_data = self._data_types[self.field_types[field]][-1] for datum in data: set_data(writer, *datum) # Tris prim = prim_type(Geom.UHStatic) prim.reserveNumVertices(len(tris)) for tri in tris: prim.addVertices(*tri) prim.closePrimitive() # Geom. geom = Geom(self.__vdata) geom.addPrimitive(prim) geom_node = GeomNode("geom") geom_node.addGeom(geom) geom_np = NodePath(geom_node) return geom_np
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 make_cube(x, y, z, size): squares = [] squares.append( make_square(x - (size / 2), y - (size / 2), z - (size / 2), x + (size / 2), y - (size / 2), z + (size / 2)) ) squares.append( make_square(x - (size / 2), y + (size / 2), z - (size / 2), x + (size / 2), y + (size / 2), z + (size / 2)) ) squares.append( make_square(x - (size / 2), y + (size / 2), z + (size / 2), x + (size / 2), y - (size / 2), z + (size / 2)) ) squares.append( make_square(x - (size / 2), y + (size / 2), z - (size / 2), x + (size / 2), y - (size / 2), z - (size / 2)) ) squares.append( make_square(x - (size / 2), y - (size / 2), z - (size / 2), x - (size / 2), y + (size / 2), z + (size / 2)) ) squares.append( make_square(x + (size / 2), y - (size / 2), z - (size / 2), x + (size / 2), y + (size / 2), z + (size / 2)) ) snode = GeomNode("square") for s in squares: snode.addGeom(s) cube = render.attachNewNode(snode) cube.setTwoSided(True)
def __init__(self, scale=10): axisNode = GeomNode('axis') axisGeom = makeAxis() axisNode.addGeom(axisGeom) axis = render.attachNewNode(axisNode) axis.setScale(scale,scale,scale) axis.setRenderModeThickness(2)
def makeSB(pos, hpr): import torus geom = torus.makeGeom() #geom = loader.loadModel('models/torus.egg') \ # .findAllMatches('**/+GeomNode').getPath(0).node() \ # .modifyGeom(0) geomNode = GeomNode('') geomNode.addGeom(geom) node = BulletSoftBodyNode.makeTriMesh(info, geom) node.linkGeom(geomNode.modifyGeom(0)) node.generateBendingConstraints(2) node.getCfg().setPositionsSolverIterations(2) node.getCfg().setCollisionFlag(BulletSoftBodyConfig.CFVertexFaceSoftSoft, True) node.randomizeConstraints() node.setTotalMass(50, True) softNP = self.worldNP.attachNewNode(node) softNP.setPos(pos) softNP.setHpr(hpr) self.world.attachSoftBody(node) geomNP = softNP.attachNewNode(geomNode)
def __build_Tris(self, sphere, mode): vdata = GeomVertexData("Data", self.__vformat[mode], Geom.UHStatic) _num_rows = len(sphere.pts) # Vertices. vertices = GeomVertexWriter(vdata, "vertex") vertices.reserveNumRows(_num_rows) for pt in sphere.pts: vertices.addData3f(*pt) # Map coords. if mode == "mid": mapcoords = GeomVertexWriter(vdata, "mapcoord") mapcoords.reserveNumRows(_num_rows) for mc in sphere.coords: u, v = mc[:2] mapcoords.addData2f(u,v) # Tris. prim = GeomTriangles(Geom.UHStatic) prim.reserveNumVertices(len(sphere.tris)) for tri in sphere.tris: prim.addVertices(*tri) prim.closePrimitive() # Geom. geom = Geom(vdata) geom.addPrimitive(prim) geom_node = GeomNode("geom") geom_node.addGeom(geom) geom_np = NodePath(geom_node) return geom_np
def __build_Patches(self, sphere): vdata = GeomVertexData("Data", self.__vformat['high'], Geom.UHStatic) vertices = GeomVertexWriter(vdata, "vertex") mapcoords = GeomVertexWriter(vdata, "mapcoord") texcoords = GeomVertexWriter(vdata, "texcoord") _num_rows = len(sphere.pts) vertices.reserveNumRows(_num_rows) mapcoords.reserveNumRows(_num_rows) texcoords.reserveNumRows(_num_rows) # Pts. for pt, uv, coords, in zip(sphere.pts, sphere.uvs, sphere.coords): vertices.addData3f(*pt) mapcoords.addData2f(*coords) texcoords.addData2f(*uv) ## *.99+.01) # Patches. prim = GeomPatches(3, Geom.UHStatic) prim.reserveNumVertices(len(sphere.tris)) for tri in sphere.tris: prim.addVertices(*tri) prim.closePrimitive() # Geom. geom = Geom(vdata) geom.addPrimitive(prim) geom_node = GeomNode("geom") geom_node.addGeom(geom) geom_np = NodePath(geom_node) return geom_np
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 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 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 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 getGeomNode(self): if self.finished == False: self.triangles.closePrimitive() self.mesh.addPrimitive(self.triangles) self.finished = True geomNode = GeomNode(self.name) geomNode.addGeom(self.mesh) return geomNode
def makeGeom(self, geom_data): """ this is for Geoms or GeomNodes """ node = GeomNode('') # use attach new node... if self.runlocal: out = geom_data else: out = node.decodeFromBamStream(geom_data) return out
def create_mesh(parentnp, debug=False, invert=False): """This creates a simple 17x17 grid mesh for the sides of our cube. The ultimate goal is to use a LOD system, probably based on quadtrees. If debug is true then we get a color gradiant on our vertexes.""" x = -1.0 y = -1.0 vertex_count = 0 u = 0.0 v = 0.0 WIDTH_STEP = 2 / 16.0 while y <= 1.0: while x <= 1.0: vertex.addData3f(x, y, 0) if invert: normal.addData3f(myNormalize((Vec3(2 * x + 1, 2 * y + 1, 2 * 0 - 1)))) else: normal.addData3f(myNormalize((Vec3(2 * x - 1, 2 * y - 1, 2 * 0 - 1)))) if debug: color.addData4f(1.0, u, v, 1.0) texcoord.addData2f(u, v) vertex_count += 1 x += WIDTH_STEP u += WIDTH_STEP / 2.0 x = -1.0 u = 0 y += WIDTH_STEP v += WIDTH_STEP / 2.0 print vertex_count triangles = [] for y in range(0, 16): for x in range(0, 16): v = 17 * y + x tri = GeomTriangles(Geom.UHDynamic) tri.addVertex(v) tri.addVertex(v + 1) tri.addVertex(v + 17) tri.closePrimitive() triangles.append(tri) tri = GeomTriangles(Geom.UHDynamic) tri.addVertex(v + 1) tri.addVertex(v + 18) tri.addVertex(v + 17) tri.closePrimitive() triangles.append(tri) mesh = Geom(vdata) for t in triangles: mesh.addPrimitive(t) mnode = GeomNode("quadface") mnode.addGeom(mesh) nodePath = parentnp.attachNewNode(mnode) return nodePath
def __init__(self, mesh, pm_filebuf): scene_members = getSceneMembers(mesh) base = ShowBase() if len(scene_members) > 1: print('There is more than one geometry in the scene, so I think this is not a progressive base mesh.') sys.exit(1) rotateNode = GeomNode("rotater") rotatePath = render.attachNewNode(rotateNode) matrix = numpy.identity(4) if mesh.assetInfo.upaxis == collada.asset.UP_AXIS.X_UP: r = collada.scene.RotateTransform(0,1,0,90) matrix = r.matrix elif mesh.assetInfo.upaxis == collada.asset.UP_AXIS.Y_UP: r = collada.scene.RotateTransform(1,0,0,90) matrix = r.matrix rotatePath.setMat(Mat4(*matrix.T.flatten().tolist())) geom, renderstate, mat4 = scene_members[0] node = GeomNode("primitive") node.addGeom(geom) if renderstate is not None: node.setGeomState(0, renderstate) self.geomPath = rotatePath.attachNewNode(node) self.geomPath.setMat(mat4) wrappedNode = ensureCameraAt(self.geomPath, base.camera) base.disableMouse() attachLights(render) render.setShaderAuto() render.setTransparency(TransparencyAttrib.MDual, 1) base.render.analyze() KeyboardMovement() MouseDrag(wrappedNode) MouseScaleZoom(wrappedNode) ButtonUtils(wrappedNode) MouseCamera() print('Loading pm into memory... ', end=' ') sys.stdout.flush() self.pm_refinements = readPDAE(pm_filebuf) self.pm_index = 0 print('Done') self.slider = DirectSlider(range=(0,len(self.pm_refinements)), value=0, pageSize=len(self.pm_refinements)/20, command=self.sliderMoved, pos=(0, 0, -.9), scale=1) for key, val in uiArgs.items(): self.slider.thumb[key] = val self.triText = OnscreenText(text="", pos=(-1,0.85), scale = 0.15, fg=(1, 0.5, 0.5, 1), align=TextNode.ALeft, mayChange=1) base.run()
def main(): import pickle from .util.util import ui_text, console, exit_cleanup, frame_rate, startup_data from .keys import AcceptKeys from .render_manager import renderManager from .ui import CameraControl, Axis3d, Grid3d base = ShowBase() base.setBackgroundColor(0,0,0) base.disableMouse() startup_data() console() exit_cleanup() frame_rate() CameraControl() Axis3d() Grid3d() r = renderManager() from .test_objects import makeSimpleGeom import numpy as np from .trees import treeMe from uuid import uuid4 from panda3d.core import GeomLinestrips n = 1000 #positions = np.array([i for i in zip(np.linspace(-1000,1000,n),np.linspace(-1000,1000,n),np.linspace(-1000,1000,n))]) # wat 1 #positions = np.array([i for i in zip(np.linspace(-1000,1000,n),np.linspace(-1000,1000,n),np.zeros(n))]) # wat 2 positions = np.array([i for i in zip(np.linspace(-1000,1000,n),np.zeros(n),np.zeros(n))]) #positions = np.random.randint(-1000,1000,(n,3)) # so it turns out that the collision nodes don't render properly on this, the tree constructed with math is correct, the rendering is not r.geomRoot.attachNewNode(makeSimpleGeom(positions,(1,1,1,1))) uuids = np.array(['%s'%uuid4() for _ in range(n)]) bounds = np.ones(n) * .5 treeMe(r.collRoot, positions, uuids, bounds) base.camLens.setFov(90) n = 1E4 # apparently 1e8 is a bit too big and 1e7 is slowwww... definitely need downsampling positions = np.array([i for i in zip(10*np.sin(np.arange(0,n)),np.arange(0,n),10*np.cos(np.arange(0,n)))]) # fukken saved r.geomRoot.attachNewNode(makeSimpleGeom(positions,(1,1,1,1), geomType=GeomLinestrips)) #with open('edge_case_data_tuple.pickle','rb') as f: #data_tuple = pickle.load(f) #r.cache['edgecase'] = False #r.set_nodes('edgecase',data_tuple) sgn = GeomNode('srct') sgn.addGeom(makeSelectRect()) sn = render.attachNewNode(sgn) sn.setSx(10) sn.setSy(10) sn.setColor(.5,.5,.5,.5) ut = ui_text() dt = BoxSel(visualize = BoxSel.VIS_ALL) ac = AcceptKeys() base.run()
def __init__(self,n): self.accept('escape',sys.exit) poses = np.random.randint(-100,100,(n,3)) geomParent = render.attachNewNode('geomParent') geoms = GeomNode('container') for _ in range(n): ax = makeAxis() #ax.setPos(np.random.randint(-100,100)) #FIXME geoms.addGeom(ax) geomParent.attachNewNode(geoms)
def Chunk2Geom(self,sChunk,origin): """ Decodes chunk into Panda3D geometry format @param sChunk: encoded chunk origin: chunk location in world as 3-tuple @return A panda3D Node object translated appropriately to place the decoded chunk correctly within the world. """ # determine where chunk should be placed in world space orgX=origin[0] orgY=origin[1] orgZ=origin[2] # determine chunk's coordinate chunkX=orgX/16 chunkY=orgY/16 # generate name tags for the various parts chunkId="%s_%s" % (chunkX,chunkY) vtxName="vtx_%s" % chunkId nodeName="chunk_%s" % chunkId # create empty node for entire chunk chunkNode=render.attachNewNode(nodeName) # convert string chunk to numeric chunk=[ord(c) for c in sChunk] # TODO: read chunk data and generate cube nodes flags=chunk[0]+(chunk[1]<<8)+(chunk[2]<<16)+(chunk[3]<<24) chunk=chunk[4:] # remove biome/flagbits for cY in range(16): for cX in range(16): for cZ in range(256): cell=cZ+(cX<<8)+(cY<<12) # lookup neighbours me=chunk[cell] if me>0: n_up=chunk[cell-1] if cZ>0 else 0 n_dn=chunk[cell+1] if cZ<255 else 0 n_lt=chunk[cell-256] if cX>0 else 0 n_rt=chunk[cell+256] if cX<15 else 0 n_bk=chunk[cell-4096] if cY>0 else 0 n_fd=chunk[cell+4096] if cY<15 else 0 if n_up==0 or n_dn==0 or \ n_lt==0 or n_rt==0 or \ n_bk==0 or n_fd==0: # for any non-obscured block # generate a cube block=GeomNode("%s_block_%s_%s_%s"%(nodeName,cX,cY,cZ)) block.addGeom(self.cubeGeom) blockNode=chunkNode.attachNewNode(block) blockNode.setTexture(self.textures[me]) blockNode.setPos(cX,cY,cZ) chunkNode.setPos(chunkX*16,chunkY*16,-64) return chunkNode
def __init__(self): self.base = ShowBase() self.base.disableMouse() self.base.camera.setPos(0, -10, 0) color_vertices = [(0.2, 0.2, 0.1, 1), (0.2, 0.7, 0.1, 1), (0.7, 0.7, 0.1, 1), (0.7, 0.2, 0.1, 1)] square = make_square(color_vertices) sq_node = GeomNode('square') sq_node.addGeom(square) self.base.render.attachNewNode(sq_node)
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): self.escapeText = genLabelText("ESC: Quit", 0) self.accept("escape", sys.exit) cloudNode = GeomNode('points') #self.cloudGeom=makePoints(999999) self.cloudGeom=makePoints(9999) cloudNode.addGeom(self.cloudGeom) #ooops dont forget this! cloud = render.attachNewNode(cloudNode) cloud.hprInterval(20,Point3(360,0,0)).loop() #scale this with zoom taskMgr.add(self.spawnTask,'newInput')
def __init__(self, size, pos, depth, spec=WaterSpec()): NodePath.__init__(self, 'waterNode') self.setPos(pos) self.spec = spec self.pos = pos self.depth = depth self.size = size self.height = pos[2] normal = (0, 0, 1) tangent = (normal[0], normal[2], -normal[1]) binormal = (normal[2], normal[1], -normal[0]) # Build array for new format. array = GeomVertexArrayFormat() array.addColumn(InternalName.make('vertex'), 3, Geom.NTFloat32, Geom.CPoint) array.addColumn(InternalName.make('texcoord'), 2, Geom.NTFloat32, Geom.CTexcoord) array.addColumn(InternalName.make('normal'), 3, Geom.NTFloat32, Geom.CVector) array.addColumn(InternalName.make('binormal'), 3, Geom.NTFloat32, Geom.CVector) array.addColumn(InternalName.make('tangent'), 3, Geom.NTFloat32, Geom.CVector) # Create and register format. format = GeomVertexFormat() format.addArray(array) format = GeomVertexFormat.registerFormat(format) vdata = GeomVertexData('waterPlanes', format, Geom.UHStatic) vdata.setNumRows(4) vtxWriter = GeomVertexWriter(vdata, 'vertex') tcWriter = GeomVertexWriter(vdata, 'texcoord') tnWriter = GeomVertexWriter(vdata, 'tangent') bnWriter = GeomVertexWriter(vdata, 'binormal') normWriter = GeomVertexWriter(vdata, 'normal') # top left corner vtxWriter.addData3f(size[0], size[3], 0) tcWriter.addData2f(0, 1) normWriter.addData3f(*normal) tnWriter.addData3f(*tangent) bnWriter.addData3f(*binormal) # bottom left corner vtxWriter.addData3f(size[0], size[2], 0) tcWriter.addData2f(0, 0) normWriter.addData3f(*normal) tnWriter.addData3f(*tangent) bnWriter.addData3f(*binormal) # top right corner vtxWriter.addData3f(size[1], size[3], 0) tcWriter.addData2f(1, 1) normWriter.addData3f(*normal) tnWriter.addData3f(*tangent) bnWriter.addData3f(*binormal) # bottom right corner vtxWriter.addData3f(size[1], size[2], 0) tcWriter.addData2f(1, 0) normWriter.addData3f(*normal) tnWriter.addData3f(*tangent) bnWriter.addData3f(*binormal) topTris = GeomTriangles(Geom.UHStatic) topTris.addVertices(0, 1, 2) topTris.addVertices(3, 2, 1) topGeom = Geom(vdata) topGeom.addPrimitive(topTris) self.topNP = self.attachNewNode(GeomNode('waterTop')) self.topNP.node().addGeom(topGeom) # Reverse the winding for the bottom water plane botTris = GeomTriangles(Geom.UHStatic) botTris.addVertices(2, 1, 0) botTris.addVertices(1, 2, 3) botGeom = Geom(vdata) botGeom.addPrimitive(botTris) self.botNP = self.attachNewNode(GeomNode('waterBot')) self.botNP.node().addGeom(botGeom) # Create an AABB which defines the volume of this water. self.aabb = BoundingBox(Point3(size[0], size[2], -depth), Point3(size[1], size[3], 0)) self.aabb.xform(self.getMat(render)) self.cubemap = base.bspLoader.getClosestCubemapTexture( self.getPos(render)) self.dudvFrame = 0
class PointsTest(DirectObject): def __init__(self, num=99999, its=99): self.num = num self.its = its self.accept("escape", sys.exit) #pointcloud #self.clouds=[] for i in range(its): cloudGeom = makePoints( self.num ) #save us the pain in this version make it the same one probably a more efficient way to do this self.cloudNode = GeomNode('points') self.cloudNode.addGeom(cloudGeom) #ooops dont forget this! self.cloud = render.attachNewNode(self.cloudNode) #self.cloud.setPos(10,10,10) #for i in range(its): #self.clouds.append(cloudNode) #self.poses = np.random.randint(-1000,1000,(its,3)) #self.cloud = None #self.cloud = render.attachNewNode(self.cloudNode) #cloud.hprInterval(1.5,Point3(360,360,360)).loop() #self.counter = 0 #self.count = genLabelText('%s'%self.counter,3) #self.count.reparentTo(base.a2dTopLeft) """ inst=render.attachNewNode('clound-%s'%self.counter) for i in range(its): inst=render.attachNewNode('clound-%s'%self.counter) inst.setPos(*self.poses[self.counter]) self.cloud.instanceTo(inst) self.counter += 1 """ #self.update() #self.timer = globalClock.getRealTime() #taskMgr.add(self.spawnTask,'MOAR') def spawnTask(self, task): #every frame move a point and change its color #self.cloudGeom #dt = .05 #now = globalClock.getRealTime() #if now - self.timer > dt: #self.timer = now #for i in range(np.random.randint(1,10)): #self.update() #return Task.cont self.update() return task.cont def update(self): #if self.cloud: #self.cloud.detachNode() #self.cloud = render.attachNewNode(self.clouds[np.random.randint(0,self.its)]) if self.counter < self.its - 100: for i in range(1000): inst = render.attachNewNode('clound-%s' % self.counter) inst.setPos(*self.poses[self.counter]) self.cloud.instanceTo(inst) self.counter += 1 self.count.setText('%s' % self.counter) else: taskMgr.remove('MOAR')
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 = [Vec3(v) for v in self.vertices] self.generate() def generate( self ): # call this after setting some of the variables to update it if hasattr(self, 'geomNode'): self.geomNode.removeAllGeoms() static_mode = Geom.UHStatic if self.static else Geom.UHDynamic vertex_format = Mesh._formats[(bool(self.colors), bool(self.uvs), bool(self.normals))] vdata = GeomVertexData('name', vertex_format, static_mode) vdata.setNumRows(len(self.vertices)) # for speed self.geomNode = GeomNode('mesh') self.attachNewNode(self.geomNode) vertexwriter = GeomVertexWriter(vdata, 'vertex') for v in self.vertices: vertexwriter.addData3f((v[0], v[2], v[1])) # swap y and z if self.colors: colorwriter = GeomVertexWriter(vdata, 'color') for c in self.colors: colorwriter.addData4f(c) if self.uvs: uvwriter = GeomVertexWriter(vdata, 'texcoord') for uv in self.uvs: uvwriter.addData2f(uv[0], uv[1]) if self.normals != None: normalwriter = GeomVertexWriter(vdata, 'normal') for norm in self.normals: normalwriter.addData3f((norm[0], norm[2], norm[1])) if self.mode != 'line' or not self._triangles: prim = Mesh._modes[self.mode](static_mode) if self._triangles: if isinstance(self._triangles[0], int): for t in self._triangles: prim.addVertex(t) elif len( self._triangles[0] ) >= 3: # if tris are tuples like this: ((0,1,2), (1,2,3)) for t in self._triangles: if len(t) == 3: for e in t: prim.addVertex(e) elif len(t) == 4: # turn quad into tris prim.addVertex(t[0]) prim.addVertex(t[1]) prim.addVertex(t[2]) prim.addVertex(t[2]) prim.addVertex(t[3]) prim.addVertex(t[0]) else: prim.addConsecutiveVertices(0, len(self.vertices)) prim.close_primitive() geom = Geom(vdata) geom.addPrimitive(prim) self.geomNode.addGeom(geom) else: # line with segments defined in triangles for line in self._triangles: prim = Mesh._modes[self.mode](static_mode) for e in line: prim.addVertex(e) prim.close_primitive() geom = Geom(vdata) geom.addPrimitive(prim) self.geomNode.addGeom(geom) if self.mode == 'point': self.setTexGen(TextureStage.getDefault(), TexGenAttrib.MPointSprite) # self.set_render_mode_perspective(True) self.recipe = dedent(f''' Mesh( vertices={[tuple(e) for e in self.vertices]}, triangles={self._triangles}, colors={[tuple(e) for e in self.colors]}, uvs={self.uvs}, normals={[tuple(e) for e in self.normals]}, static={self.static}, mode="{self.mode}", thickness={self.thickness} ) ''') # print('finished') def __add__(self, other): self.vertices += other.vertices self.triangles += other.triangles if other.colors: self.colors += other.colors else: self.colors += (color.white, ) * len(other.vertices) self.normals += other.normals self.uvs += other.uvs def __copy__(self): 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(recipe) print('saved .ursinamesh to:', path / name) elif name.endswith('.obj'): from ursina.mesh_importer import ursina_mesh_to_obj ursina_mesh_to_obj(self, name, path) elif name.endswith('.bam'): success = self.writeBamFile(path / name) print('saved .bam to:', path / name)
class PointsSet(VisibleObject): tex = None def __init__(self, use_sprites=True, use_sizes=True, points_size=2, sprite=None, background=None, shader=None): self.gnode = GeomNode('starfield') self.use_sprites = use_sprites self.use_sizes = use_sizes self.background = background if shader is None: shader = BasicShader(lighting_model=FlatLightingModel(), point_shader=False) self.shader = shader self.reset() self.geom = self.makeGeom([], [], []) self.gnode.addGeom(self.geom) self.instance = NodePath(self.gnode) if self.use_sprites: if sprite is None: sprite = RoundDiskPointSprite() self.sprite = sprite else: self.sprite = SimplePoint(points_size) self.min_size = self.sprite.get_min_size() self.sprite.apply(self.instance) self.instance.setCollideMask(GeomNode.getDefaultCollideMask()) self.instance.node().setPythonTag('owner', self) #TODO: Should not use ModelAppearance ! self.appearance = ModelAppearance(vertex_color=True) if self.appearance is not None: self.appearance.bake() self.appearance.apply(self, self) if self.shader is not None: self.shader.apply(self, self.appearance) if self.use_sprites: self.instance.node().setBounds(OmniBoundingVolume()) self.instance.node().setFinal(True) if self.background is not None: self.instance.setBin('background', self.background) self.instance.set_depth_write(False) def jobs_done_cb(self, patch): pass def reset(self): self.points = [] self.colors = [] self.sizes = [] def add_point_scale(self, position, color, size): #Observer is at position (0, 0, 0) distance_to_obs = position.length() vector_to_obs = -position / distance_to_obs point, _, _ = self.get_real_pos_rel(position, distance_to_obs, vector_to_obs) self.points.append(point) self.colors.append(color) self.sizes.append(size) def add_point(self, position, color, size): self.points.append(position) self.colors.append(color) self.sizes.append(size) def update(self): self.update_arrays(self.points, self.colors, self.sizes) def makeGeom(self, points, colors, sizes): #format = GeomVertexFormat.getV3c4() array = GeomVertexArrayFormat() array.addColumn(InternalName.make('vertex'), 3, Geom.NTFloat32, Geom.CPoint) array.addColumn(InternalName.make('color'), 4, Geom.NTFloat32, Geom.CColor) if self.use_sizes: array.addColumn(InternalName.make('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, 'vertex') self.colorwriter = GeomVertexWriter(vdata, 'color') if self.use_sizes: self.sizewriter = GeomVertexWriter(vdata, '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.addData3f(color[0], color[1], color[2]) self.colorwriter.addData4f(*color) if self.use_sizes: self.sizewriter.addData1f(size) geompoints.addVertex(index) geompoints.closePrimitive() index += 1 geom = Geom(vdata) geom.addPrimitive(geompoints) return geom def update_arrays(self, points, colors, sizes): self.gnode.removeAllGeoms() self.geom = self.makeGeom(points, colors, sizes) self.gnode.addGeom(self.geom)
def get_geom_node(self): node = GeomNode(self.name) node.add_geom(self.get_geom()) return node
def createModelClone(self, modelFilename): newVisualCar = loader.loadModel(modelFilename) geomNodeCollection = newVisualCar.findAllMatches('**/+GeomNode') simpleTris = [] self.unmodifiedVertexData = [] for nodePath in geomNodeCollection: geomNode = nodePath.node() for i in range(geomNode.getNumGeoms()): geom = geomNode.getGeom(i) vdata = geom.getVertexData() vertex = GeomVertexReader(vdata, 'vertex') while not vertex.isAtEnd(): v = vertex.getData3f() vertexModelX, vertexModelY, vertexModelZ = v self.unmodifiedVertexData.append( [vertexModelX, vertexModelY, vertexModelZ]) for primitiveIndex in range(geom.getNumPrimitives()): prim = geom.getPrimitive(primitiveIndex) prim = prim.decompose() for p in range(prim.getNumPrimitives()): s = prim.getPrimitiveStart(p) e = prim.getPrimitiveEnd(p) singleTriData = [] for i in range(s, e): vertex.setRow(prim.getVertex(s)) vi = prim.getVertex(i) singleTriData.append(vi) simpleTris.append(singleTriData) simpleVertices = self.unmodifiedVertexData format = GeomVertexFormat.getV3() vdata = GeomVertexData('shadow', format, Geom.UHDynamic) self.pandaVertexData = vdata vertex = GeomVertexWriter(vdata, 'vertex') for vertexIndex in range(len(simpleVertices)): simpleVertex = simpleVertices[vertexIndex] vertex.addData3f(0, 0, 0) tris = GeomTriangles(Geom.UHStatic) for index in range(len(simpleTris)): simpleTri = simpleTris[index] tris.addVertex(simpleTri[0]) tris.addVertex(simpleTri[1]) tris.addVertex(simpleTri[2]) tris.closePrimitive() shadow = Geom(vdata) shadow.addPrimitive(tris) snode = GeomNode('shadow') snode.addGeom(shadow) self.snode = snode
class Asterism(VisibleObject): def __init__(self, name): VisibleObject.__init__(self, name) self.visible = True self.color = bodyClasses.get_orbit_color('constellation') self.position = LPoint3d(0, 0, 0) self.segments = [] self.position = None def check_settings(self): self.set_shown(settings.show_asterisms) def set_segments_list(self, segments): self.segments = segments ra_sin = 0 ra_cos = 0 decl = 0 if len(self.segments) > 0 and len(self.segments[0]) > 0: for star in self.segments[0]: asc = star.orbit.get_right_asc() ra_sin += sin(asc) ra_cos += cos(asc) decl += star.orbit.get_declination() ra = atan2(ra_sin, ra_cos) decl /= len(self.segments[0]) self.position = InfinitePosition(right_asc=ra, right_asc_unit=units.Rad, declination=decl, declination_unit=units.Rad) def create_instance(self): self.vertexData = GeomVertexData('vertexData', GeomVertexFormat.getV3c4(), Geom.UHStatic) self.vertexWriter = GeomVertexWriter(self.vertexData, 'vertex') self.colorwriter = GeomVertexWriter(self.vertexData, 'color') #TODO: Ugly hack to calculate star position from the sun... old_cam_pos = self.context.observer.camera_global_pos self.context.observer.camera_global_pos = LPoint3d() center = LPoint3d() for segment in self.segments: if len(segment) < 2: continue for star in segment: #TODO: Temporary workaround to have star pos star.update(0, 0) star.update_obs(self.context.observer) position, distance, scale_factor = self.calc_scene_params(star.rel_position, star._position, star.distance_to_obs, star.vector_to_obs) self.vertexWriter.addData3f(*position) self.colorwriter.addData4(srgb_to_linear(self.color)) self.context.observer.camera_global_pos = old_cam_pos self.lines = GeomLines(Geom.UHStatic) index = 0 for segment in self.segments: if len(segment) < 2: continue for i in range(len(segment)-1): self.lines.addVertex(index) self.lines.addVertex(index+1) self.lines.closePrimitive() index += 1 index += 1 self.geom = Geom(self.vertexData) self.geom.addPrimitive(self.lines) self.node = GeomNode("asterism") self.node.addGeom(self.geom) self.instance = NodePath(self.node) self.instance.setRenderModeThickness(settings.asterism_thickness) self.instance.reparentTo(self.context.annotation) self.instance.setBin('background', settings.asterisms_depth) self.instance.set_depth_write(False)
def setup_square(config): sq_colors = make_color_vertices(config) square = make_square(sq_colors) sq_node = GeomNode('square') sq_node.addGeom(square) return sq_node
def __init__(self, mesh, pm_filebuf): scene_members = getSceneMembers(mesh) base = ShowBase() if len(scene_members) > 1: print 'There is more than one geometry in the scene, so I think this is not a progressive base mesh.' sys.exit(1) rotateNode = GeomNode("rotater") rotatePath = render.attachNewNode(rotateNode) matrix = numpy.identity(4) if mesh.assetInfo.upaxis == collada.asset.UP_AXIS.X_UP: r = collada.scene.RotateTransform(0, 1, 0, 90) matrix = r.matrix elif mesh.assetInfo.upaxis == collada.asset.UP_AXIS.Y_UP: r = collada.scene.RotateTransform(1, 0, 0, 90) matrix = r.matrix rotatePath.setMat(Mat4(*matrix.T.flatten().tolist())) geom, renderstate, mat4 = scene_members[0] node = GeomNode("primitive") node.addGeom(geom) if renderstate is not None: node.setGeomState(0, renderstate) self.geomPath = rotatePath.attachNewNode(node) self.geomPath.setMat(mat4) wrappedNode = ensureCameraAt(self.geomPath, base.camera) base.disableMouse() attachLights(render) render.setShaderAuto() render.setTransparency(TransparencyAttrib.MDual, 1) base.render.analyze() KeyboardMovement() MouseDrag(wrappedNode) MouseScaleZoom(wrappedNode) ButtonUtils(wrappedNode) MouseCamera() print 'Loading pm into memory... ', sys.stdout.flush() self.pm_refinements = readPDAE(pm_filebuf) self.pm_index = 0 print 'Done' self.slider = DirectSlider(range=(0, len(self.pm_refinements)), value=0, pageSize=len(self.pm_refinements) / 20, command=self.sliderMoved, pos=(0, 0, -.9), scale=1) for key, val in uiArgs.iteritems(): self.slider.thumb[key] = val self.triText = OnscreenText(text="", pos=(-1, 0.85), scale=0.15, fg=(1, 0.5, 0.5, 1), align=TextNode.ALeft, mayChange=1) base.run()
class Ramp: def __init__(self, pos, l, w, h, c, t, name): #Creating the ramp self.pos = pos self.len = l self.wid = w self.dep = h self.color = c self.texture = t self.name = name self.prim = 0 self.model = 0 self.Ramp() self.node = render.attachNewNode(self.model) #A ramp's like a cube, but it's missing a face def Ramp(self): format = GeomVertexFormat.getV3n3cpt2() vdata = GeomVertexData('square', format, Geom.UHDynamic) vertex = GeomVertexWriter(vdata, 'vertex') #The corner at Quadrant 2 on face 1 is the starting point of our rectangle ################################ # # FACE 1 # ################################ vert1 = LVector3(self.pos.getX(), self.pos.getY(), self.pos.getZ()) vert2 = LVector3(vert1.getX() + self.len, vert1.getY(), vert1.getZ()) vert3 = LVector3(vert2.getX(), vert2.getY() + self.wid, vert2.getZ()) vert4 = LVector3(vert1.getX(), vert1.getY() + self.wid, vert1.getZ()) vertex.addData3(vert1) vertex.addData3(vert2) vertex.addData3(vert3) vertex.addData3(vert4) normal = GeomVertexWriter(vdata, 'normal') norm = (vert4 - vert1).cross(vert2 - vert1) norm.normalize() normal.addData3(norm) normal.addData3(norm) normal.addData3(norm) normal.addData3(norm) color = GeomVertexWriter(vdata, 'color') color.addData4f(self.color) color.addData4f(self.color) color.addData4f(self.color) color.addData4f(self.color) texcoord = GeomVertexWriter(vdata, 'texcoord') texcoord.addData2f(1, 0) texcoord.addData2f(1, 1) texcoord.addData2f(0, 1) texcoord.addData2f(0, 0) tris = GeomTriangles(Geom.UHDynamic) tris.addVertices(0, 3, 1) tris.addVertices(1, 3, 2) ##################################### # # FACE 2 # ##################################### vert5 = vert1 vert6 = vert2 vert7 = LVector3(vert3.getX(), vert3.getY(), vert3.getZ() + self.dep) vert8 = LVector3(vert4.getX(), vert4.getY(), vert4.getZ() + self.dep) vertex.addData3(vert5) vertex.addData3(vert6) vertex.addData3(vert7) vertex.addData3(vert8) norm = (vert8 - vert5).cross(vert6 - vert5) norm.normalize() normal.addData3(norm) normal.addData3(norm) normal.addData3(norm) normal.addData3(norm) color.addData4f(self.color) color.addData4f(self.color) color.addData4f(self.color) color.addData4f(self.color) texcoord.addData2f(1, 0) texcoord.addData2f(1, 1) texcoord.addData2f(0, 1) texcoord.addData2f(0, 0) tris.addVertices(4, 7, 5) tris.addVertices(5, 7, 6) ######################################## # # FACE 3 # ######################################## vert9 = vert1 vert10 = vert2 vert11 = vert6 vert12 = vert5 vertex.addData3(vert9) vertex.addData3(vert10) vertex.addData3(vert11) vertex.addData3(vert12) norm = (vert12 - vert9).cross(vert10 - vert9) norm.normalize() normal.addData3(norm) normal.addData3(norm) normal.addData3(norm) normal.addData3(norm) color.addData4f(self.color) color.addData4f(self.color) color.addData4f(self.color) color.addData4f(self.color) texcoord.addData2f(1, 0) texcoord.addData2f(1, 1) texcoord.addData2f(0, 1) texcoord.addData2f(0, 0) tris.addVertices(8, 11, 9) tris.addVertices(9, 11, 10) ############################################### # # FACE 4 # ############################################### vert13 = vert1 vert14 = vert4 vert15 = vert8 vert16 = vert5 vertex.addData3(vert13) vertex.addData3(vert14) vertex.addData3(vert15) vertex.addData3(vert16) norm = (vert16 - vert13).cross(vert14 - vert13) norm.normalize() normal.addData3(norm) normal.addData3(norm) normal.addData3(norm) normal.addData3(norm) color.addData4f(self.color) color.addData4f(self.color) color.addData4f(self.color) color.addData4f(self.color) texcoord.addData2f(1, 0) texcoord.addData2f(1, 1) texcoord.addData2f(0, 1) texcoord.addData2f(0, 0) tris.addVertices(12, 15, 13) tris.addVertices(13, 15, 14) ############################################ # # FACE 5 # ############################################ vert17 = vert2 vert18 = vert3 vert19 = vert7 vert20 = vert6 vertex.addData3(vert17) vertex.addData3(vert18) vertex.addData3(vert19) vertex.addData3(vert20) norm = (vert20 - vert17).cross(vert18 - vert17) normal.addData3(norm) normal.addData3(norm) normal.addData3(norm) normal.addData3(norm) color.addData4f(self.color) color.addData4f(self.color) color.addData4f(self.color) color.addData4f(self.color) texcoord.addData2f(1, 0) texcoord.addData2f(1, 1) texcoord.addData2f(0, 1) texcoord.addData2f(0, 0) tris.addVertices(16, 19, 17) tris.addVertices(17, 19, 18) ramp = Geom(vdata) ramp.addPrimitive(tris) self.prim = ramp self.model = GeomNode(self.name) self.model.addGeom(self.prim) def attachToSpace(self, model, space): self.node = space.attachNewNode(model) def generate(self, space): self.node.setTexture(self.texture) self.node.setTwoSided(True)
def makeBulletCollFromGeoms(rootNode, exclusions=[], enableNow=True, world=None): """ Creates and attaches bullet triangle mesh nodes underneath each GeomNode of `rootNode`, which contains the same mesh as the Geoms. This can be expensive if the geometry contains lots of triangles or GeomNodes. """ if not world: world = base.physicsWorld # BulletRigidBodyNode -> triangle index -> surfaceprop # (it's so we know which surface we are walking on) result = {} for faceNp in rootNode.findAllMatches("**"): if faceNp.getName() in exclusions: continue if faceNp.node().getType() != GeomNode.getClassType(): continue # Create a separate list of geoms for each possible face type # ( a wall or floor ) type2geoms = {} for i in xrange(faceNp.node().getNumGeoms()): geom = faceNp.node().getGeom(i) state = faceNp.node().getGeomState(i) if not geom.getPrimitive(0).isIndexed(): continue if state.hasAttrib(BSPFaceAttrib.getClassSlot()): bca = state.getAttrib(BSPFaceAttrib.getClassSlot()) facetype = bca.getFaceType() else: facetype = BSPFaceAttrib.FACETYPE_WALL if not type2geoms.has_key(facetype): type2geoms[facetype] = [(geom, state)] else: type2geoms[facetype].append((geom, state)) # Now create a separate body node to group each face type, # and assign the correct bit for facetype, geoms in type2geoms.items(): data = {} numGeoms = 0 mesh = BulletTriangleMesh() for i in xrange(len(geoms)): geom, state = geoms[i] mesh.addGeom(geom, True) surfaceprop = "default" if state.hasAttrib(BSPMaterialAttrib.getClassSlot()): mat = state.getAttrib( BSPMaterialAttrib.getClassSlot()).getMaterial() if mat: surfaceprop = mat.getSurfaceProp() for j in xrange(geom.getNumPrimitives()): prim = geom.getPrimitive(j) prim = prim.decompose() tris = prim.getNumVertices() / 3 for tidx in xrange(tris): data[numGeoms] = surfaceprop numGeoms += 1 shape = BulletTriangleMeshShape(mesh, False) rbnode = BulletRigidBodyNode(faceNp.getName() + "_bullet_type" + str(facetype)) rbnode.setKinematic(True) rbnode.addShape(shape) rbnodeNp = NodePath(rbnode) rbnodeNp.reparentTo(faceNp) if facetype == BSPFaceAttrib.FACETYPE_WALL: rbnodeNp.setCollideMask(CIGlobals.WallGroup) elif facetype == BSPFaceAttrib.FACETYPE_FLOOR: rbnodeNp.setCollideMask(CIGlobals.FloorGroup) if enableNow: world.attachRigidBody(rbnode) result[rbnode] = data return result
class Orbit(VisibleObject): ignore_light = True default_shown = False selected_color = LColor(1.0, 0.0, 0.0, 1.0) appearance = None shader = None def __init__(self, body): VisibleObject.__init__(self, body.get_ascii_name() + '-orbit') self.body = body self.owner = body self.nbOfPoints = 360 self.orbit = self.find_orbit(self.body) self.color = None self.fade = 0.0 if not self.orbit: print("No orbit for", self.get_name()) self.visible = False def get_oid_color(self): if self.body is not None: return self.body.oid_color else: return LColor() @classmethod def create_shader(cls): cls.appearance = ModelAppearance(attribute_color=True) if settings.use_inv_scaling: vertex_control = LargeObjectVertexControl() else: vertex_control = None cls.shader = BasicShader(lighting_model=FlatLightingModel(), vertex_control=vertex_control) def check_settings(self): if self.body.body_class is None: print("No class for", self.body.get_name()) return self.set_shown(settings.show_orbits and bodyClasses.get_show_orbit(self.body.body_class)) def find_orbit(self, body): if body != None: if not isinstance(body.orbit, FixedOrbit): return body.orbit else: return None, None else: return None, None def set_selected(self, selected): if selected: self.color = self.selected_color else: self.color = self.parent.get_orbit_color() if self.instance: self.instance.setColor(srgb_to_linear(self.color * self.fade)) def create_instance(self): self.vertexData = GeomVertexData('vertexData', GeomVertexFormat.getV3(), Geom.UHStatic) self.vertexWriter = GeomVertexWriter(self.vertexData, 'vertex') delta = self.body.parent.get_local_position() if self.orbit.is_periodic(): epoch = self.context.time.time_full - self.orbit.period / 2 step = self.orbit.period / (self.nbOfPoints - 1) else: #TODO: Properly calculate orbit start and end time epoch = self.orbit.get_time_of_perihelion() - self.orbit.period * 5.0 step = self.orbit.period * 10.0 / (self.nbOfPoints - 1) for i in range(self.nbOfPoints): time = epoch + step * i pos = self.orbit.get_position_at(time) - delta self.vertexWriter.addData3f(*pos) self.lines = GeomLines(Geom.UHStatic) for i in range(self.nbOfPoints-1): self.lines.addVertex(i) self.lines.addVertex(i+1) if self.orbit.is_periodic() and self.orbit.is_closed(): self.lines.addVertex(self.nbOfPoints-1) self.lines.addVertex(0) self.geom = Geom(self.vertexData) self.geom.addPrimitive(self.lines) self.node = GeomNode(self.body.get_ascii_name() + '-orbit') self.node.addGeom(self.geom) self.instance = NodePath(self.node) self.instance.setRenderModeThickness(settings.orbit_thickness) self.instance.setCollideMask(GeomNode.getDefaultCollideMask()) self.instance.node().setPythonTag('owner', self) self.instance.reparentTo(self.context.annotation) if self.color is None: self.color = self.parent.get_orbit_color() self.instance.setColor(srgb_to_linear(self.color * self.fade)) self.instance_ready = True if self.shader is None: self.create_shader() self.shader.apply(self, self.appearance) self.shader.update(self, self.appearance) def update_geom(self): geom = self.node.modify_geom(0) vdata = geom.modify_vertex_data() vwriter = GeomVertexRewriter(vdata, InternalName.get_vertex()) #TODO: refactor with above code !!! delta = self.body.parent.get_local_position() if self.orbit.is_periodic(): epoch = self.context.time.time_full - self.orbit.period step = self.orbit.period / (self.nbOfPoints - 1) else: #TODO: Properly calculate orbit start and end time epoch = self.orbit.get_time_of_perihelion() - self.orbit.period * 5.0 step = self.orbit.period * 10.0 / (self.nbOfPoints - 1) for i in range(self.nbOfPoints): time = epoch + step * i pos = self.orbit.get_position_at(time) - delta vwriter.setData3f(*pos) def check_visibility(self, pixel_size): if self.parent.parent.visible and self.parent.shown and self.orbit: distance_to_obs = self.parent.distance_to_obs if distance_to_obs > 0.0: size = self.orbit.get_apparent_radius() / (distance_to_obs * pixel_size) else: size = 0.0 self.visible = size > settings.orbit_fade self.fade = min(1.0, max(0.0, (size - settings.orbit_fade) / settings.orbit_fade)) if self.color is not None and self.instance is not None: self.instance.setColor(srgb_to_linear(self.color * self.fade)) else: self.visible = False def update_instance(self, camera_pos, camera_rot): if self.instance: self.place_instance_params(self.instance, self.body.parent.scene_position, self.body.parent.scene_scale_factor, LQuaternion()) self.shader.update(self, self.appearance) def update_user_parameters(self): if self.instance is not None: self.update_geom()
class MyApp(ShowBase): def __init__(self): ShowBase.__init__(self) self.seeNode = self.render.attachNewNode('see') self.cam.reparentTo(self.seeNode) self.cam.setPos(0, 0, 5) self.fpscamera = fpscontroller.FpsController(self, self.seeNode) self.fpscamera.setFlyMode(True) self.prevPos = self.fpscamera.getPos() self.prevInto = None self.info = self.genLabelText("Position: <unknown>", 4) self.makeInstructions() self.initCollisions() self.leftColor = LVecBase4i(224, 224, 64, 255) self.rightColor = LVecBase4i(64, 224, 224, 255) self.isDrawing = False self.toggleDrawing() self.accept("escape", sys.exit) #Escape quits self.accept("enter", self.toggleDrawing) def initCollisions(self): # Initialize the collision traverser. self.cTrav = CollisionTraverser() self.cTrav.showCollisions(self.render) # self.cQueue = CollisionHandlerQueue() # Initialize the Pusher collision handler. #self.pusher = CollisionHandlerPusher() self.pusher = CollisionHandlerFloor() ### player print DirectNotifyGlobal.directNotify.getCategories() # Create a collsion node for this object. playerNode = CollisionNode('player') playerNode.addSolid(CollisionSphere(0, 0, 0, 1)) # playerNode.setFromCollideMask(BitMask32.bit(0)) # playerNode.setIntoCollideMask(BitMask32.allOn()) # Attach the collision node to the object's model. self.playerC = self.fpscamera.player.attachNewNode(playerNode) # Set the object's collision node to render as visible. self.playerC.show() # Add the 'player' collision node to the Pusher collision handler. #self.pusher.addCollider(self.playerC, self.fpscamera.player) #self.pusher.addCollider(playerC, self.fpscamera.player) # self.cTrav.addCollider(self.playerC, self.cQueue) def toggleDrawing(self): self.isDrawing = not self.isDrawing if self.isDrawing: self.drawText.setText("Enter: Turn off drawing") self.fpscamera.setFlyMode(True) self.prevPos = None self.cTrav.removeCollider(self.playerC) self.pusher.removeCollider(self.playerC) self.removeTask('updatePhysics') self.addTask(self.drawHere, 'drawHere') self.geomNode = GeomNode('geomNode') self.geomNodePath = self.render.attachNewNode(self.geomNode) self.geomNodePath.setTwoSided(True) # apparently p3tinydisplay needs this self.geomNodePath.setColorOff() # Create a collision node for this object. self.floorCollNode = CollisionNode('geom') # self.floorCollNode.setFromCollideMask(BitMask32.bit(0)) # self.floorCollNode.setIntoCollideMask(BitMask32.allOn()) # Attach the collision node to the object's model. floorC = self.geomNodePath.attachNewNode(self.floorCollNode) # Set the object's collision node to render as visible. floorC.show() #self.pusher.addCollider(floorC, self.geomNodePath) self.newVertexData() self.newGeom() else: self.drawText.setText("Enter: Turn on drawing") self.removeTask('drawHere') if self.prevPos: self.completePath() self.fpscamera.setFlyMode(True) self.drive.setPos(self.fpscamera.getPos()) self.cTrav.addCollider(self.playerC, self.pusher) self.pusher.addCollider(self.playerC, self.fpscamera.player) self.taskMgr.add(self.updatePhysics, 'updatePhysics') 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 newGeom(self): self.triStrips = GeomTristrips(Geom.UHDynamic) self.geom = Geom(self.vertexData) self.geom.addPrimitive(self.triStrips) def makeInstructions(self): OnscreenText(text="Draw Path by Walking", style=1, fg=(1, 1, 0, 1), pos=(0.5, -0.95), scale=.07) self.drawText = self.genLabelText("", 0) self.genLabelText("Walk (W/S/A/D), Jump=Space, Look=PgUp/PgDn", 1) self.genLabelText( " (hint, go backwards with S to see your path immediately)", 2) self.genLabelText("ESC: Quit", 3) def genLabelText(self, text, i): return OnscreenText(text=text, pos=(-1.3, .95 - .05 * i), fg=(1, 1, 0, 1), align=TextNode.ALeft, scale=.05) def drawHere(self, task): pos = self.fpscamera.getPos() self.info.setText("Position: {0}, {1}, {2} at {3} by {4}".format( int(pos.x * 100) / 100., int(pos.y * 100) / 100., int(pos.z) / 100., self.fpscamera.getHeading(), self.fpscamera.getLookAngle())) prevPos = self.prevPos if not prevPos: self.prevPos = pos elif (pos - prevPos).length() > 1: self.drawQuadTo(prevPos, pos, 2) row = self.vertexWriter.getWriteRow() numPrims = self.triStrips.getNumPrimitives() if numPrims == 0: primVerts = row else: primVerts = row - self.triStrips.getPrimitiveEnd(numPrims - 1) if primVerts >= 4: self.triStrips.closePrimitive() if row >= 256: print "Packing and starting anew" newGeom = True self.geom.unifyInPlace(row, False) else: newGeom = False self.completePath() if newGeom: self.newVertexData() self.newGeom() if not newGeom: self.triStrips.addConsecutiveVertices(row - 2, 2) else: self.drawQuadTo(prevPos, pos, 2) self.leftColor[1] += 63 self.rightColor[2] += 37 self.prevPos = pos return task.cont def drawLineTo(self, pos, color): self.vertexWriter.addData3f(pos.x, pos.y, pos.z) # self.normalWriter.addData3f(0, 0, 1) self.colorWriter.addData4i(color) self.triStrips.addNextVertices(1) def drawQuadTo(self, a, b, width): """ a (to) b are vectors defining a line bisecting a new quad. """ into = (b - a) if abs(into.x) + abs(into.y) < 1: if not self.prevInto: return into = self.prevInto print into else: into.normalize() # the perpendicular of (a,b) is (-b,a); we want the path to be "flat" in Z=space if self.vertexWriter.getWriteRow() == 0: self.drawQuadRow(a, into, width) self.drawQuadRow(b, into, width) self.prevInto = into def drawQuadRow(self, a, into, width): """ a defines a point, with 'into' being the normalized direction. """ # the perpendicular of (a,b) is (-b,a); we want the path to be "flat" in Z=space aLeft = Vec3(a.x - into.y * width, a.y + into.x * width, a.z) aRight = Vec3(a.x + into.y * width, a.y - into.x * width, a.z) row = self.vertexWriter.getWriteRow() self.vertexWriter.addData3f(aLeft) self.vertexWriter.addData3f(aRight) # self.normalWriter.addData3f(Vec3(0, 0, 1)) # self.normalWriter.addData3f(Vec3(0, 0, 1)) self.colorWriter.addData4i(self.leftColor) self.colorWriter.addData4i(self.rightColor) self.triStrips.addConsecutiveVertices(row, 2) def completePath(self): self.geomNode.addGeom(self.geom) if self.triStrips.getNumPrimitives() == 0: return floorMesh = CollisionFloorMesh() tris = self.triStrips.decompose() p = 0 vertexReader = GeomVertexReader(self.vertexData, 'vertex') for i in range(tris.getNumPrimitives()): v0 = tris.getPrimitiveStart(i) ve = tris.getPrimitiveEnd(i) if v0 < ve: vertexReader.setRow(tris.getVertex(v0)) floorMesh.addVertex(Point3(vertexReader.getData3f())) vertexReader.setRow(tris.getVertex(v0 + 1)) floorMesh.addVertex(Point3(vertexReader.getData3f())) vertexReader.setRow(tris.getVertex(v0 + 2)) floorMesh.addVertex(Point3(vertexReader.getData3f())) floorMesh.addTriangle(p, p + 1, p + 2) p += 3 self.floorCollNode.addSolid(floorMesh) def updatePhysics(self, task): pos = self.fpscamera.getPos() self.info.setText("Position: {0}, {1}, {2}".format( int(pos.x * 100) / 100., int(pos.y * 100) / 100., int(pos.z) / 100.)) return task.cont
class ChunkModel(NodePath): """Chunk for quick render and create voxel-objects config - config of voxplanet heights - {(centerX, centerY): height, (X2, Y2: height, ... (XN, YN): height} centerX, centerY - center coordinates size - size of chunk (in scene coords) chunk_len - count of voxels tex_uv_height - function return of uv coordinates for height voxel tex - texture map """ dirty = False 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 create(self): self.chunk_geom = GeomNode('self.chunk_geom') vertex = GeomVertexWriter(self.v_data, 'vertex') normal = GeomVertexWriter(self.v_data, 'normal') texcoord = GeomVertexWriter(self.v_data, 'texcoord') # make buffer of vertices vertices = [] n_vert = 0 t = time.time() tri = GeomTriangles(Geom.UHStatic) def add_data(n_vert, v0, v1, v2, v3, voxel): vertex.addData3f(v0) vertex.addData3f(v1) vertex.addData3f(v2) vertex.addData3f(v3) side1 = v0 - v1 side2 = v0 - v3 norm1 = side1.cross(side2) side1 = v1 - v2 side2 = v1 - v3 norm2 = side1.cross(side2) normal.addData3f(norm1) normal.addData3f(norm1) normal.addData3f(norm1) normal.addData3f(norm2) u1, v1, u2, v2 = voxel.get_uv() texcoord.addData2f(v1, u1) texcoord.addData2f(v2, u1) texcoord.addData2f(v2, u2) texcoord.addData2f(v1, u2) tri.addConsecutiveVertices(0 + n_vert, 3) tri.addVertex(2 + n_vert) tri.addVertex(3 + n_vert) tri.addVertex(0 + n_vert) end = self.chunk_len - 1 for x in xrange(0, self.chunk_len): for y in xrange(0, self.chunk_len): X = self.centerX - self.size2 + (x * self.size_voxel) Y = self.centerY - self.size2 + (y * self.size_voxel) dX = X + self.size_voxel dY = Y + self.size_voxel dx = x + 1 dy = y + 1 v0 = Vec3(x, dy, self.heights[X, dY]) v1 = Vec3(x, y, self.heights[X, Y]) v2 = Vec3(dx, y, self.heights[dX, Y]) v3 = Vec3(dx, dy, self.heights[dX, dY]) add_data(n_vert, v0, v1, v2, v3, self.voxels[X, Y, self.heights[X, Y]]) n_vert += 4 if x == 0: v0 = Vec3(x, y, self.heights[X, Y] - self.size_voxel) v1 = Vec3(x, y, self.heights[X, Y]) v2 = Vec3(x, dy, self.heights[X, dY]) v3 = Vec3(x, dy, self.heights[X, dY] - self.size_voxel) add_data(n_vert, v0, v1, v2, v3, self.voxels[X, Y, self.heights[X, Y]]) n_vert += 4 if y == 0: v0 = Vec3(dx, y, self.heights[dX, Y] - self.size_voxel) v1 = Vec3(dx, y, self.heights[dX, Y]) v2 = Vec3(x, y, self.heights[X, Y]) v3 = Vec3(x, y, self.heights[X, Y] - self.size_voxel) add_data(n_vert, v0, v1, v2, v3, self.voxels[X, Y, self.heights[X, Y]]) n_vert += 4 if x == end: v0 = Vec3(dx, dy, self.heights[dX, dY] - self.size_voxel) v1 = Vec3(dx, dy, self.heights[dX, dY]) v2 = Vec3(dx, y, self.heights[dX, Y]) v3 = Vec3(dx, y, self.heights[dX, Y] - self.size_voxel) add_data(n_vert, v0, v1, v2, v3, self.voxels[X, Y, self.heights[X, Y]]) n_vert += 4 if y == end: v0 = Vec3(x, dy, self.heights[X, dY] - self.size_voxel) v1 = Vec3(x, dy, self.heights[X, dY]) v2 = Vec3(dx, dy, self.heights[dX, dY]) v3 = Vec3(dx, dy, self.heights[dX, dY] - self.size_voxel) add_data(n_vert, v0, v1, v2, v3, self.voxels[X, Y, self.heights[X, Y]]) n_vert += 4 self.geom = Geom(self.v_data) self.geom.addPrimitive(tri) self.chunk_geom.addGeom(self.geom) self.chunk_np = self.attachNewNode('chunk_np') self.chunk_np.attachNewNode(self.chunk_geom) self.chunk_geom.setIntoCollideMask(BitMask32.bit(1)) self.chunk_np.setTag( 'Chunk', 'Chunk: {0} {1} {2}'.format(self.centerX, self.centerY, self.size)) #self.setTwoSided(True) self.water = WaterNode(0, 0, self.size, self.water_tex) self.water.setTwoSided(True) self.water.reparentTo(self) ts = TextureStage('ts') self.chunk_np.setTexture(ts, self.tex) self.chunk_np.setScale(self.size_voxel, self.size_voxel, 1) #t = time.time() # i love this function ^--^ self.flattenStrong() #print 'flatten chunk: ', time.time() - t def setX(self, DX): """Set to new X center X - self.size/2 - DX """ x = self.start_x - DX NodePath.setX(self, x) def setY(self, DY): """Set to new Y center Y - self.size/2 - DY """ y = self.start_y - DY NodePath.setY(self, y)
def main(): import pickle from .util.util import ui_text, console, exit_cleanup, frame_rate, startup_data from .keys import AcceptKeys from .render_manager import renderManager from .ui import CameraControl, Axis3d, Grid3d base = ShowBase() base.setBackgroundColor(0, 0, 0) base.disableMouse() startup_data() console() exit_cleanup() frame_rate() CameraControl() Axis3d() Grid3d() r = renderManager() from .test_objects import makeSimpleGeom import numpy as np from .trees import treeMe from uuid import uuid4 from panda3d.core import GeomLinestrips n = 1000 #positions = np.array([i for i in zip(np.linspace(-1000,1000,n),np.linspace(-1000,1000,n),np.linspace(-1000,1000,n))]) # wat 1 #positions = np.array([i for i in zip(np.linspace(-1000,1000,n),np.linspace(-1000,1000,n),np.zeros(n))]) # wat 2 positions = np.array([ i for i in zip(np.linspace(-1000, 1000, n), np.zeros(n), np.zeros(n)) ]) #positions = np.random.randint(-1000,1000,(n,3)) # so it turns out that the collision nodes don't render properly on this, the tree constructed with math is correct, the rendering is not r.geomRoot.attachNewNode(makeSimpleGeom(positions, (1, 1, 1, 1))) uuids = np.array(['%s' % uuid4() for _ in range(n)]) bounds = np.ones(n) * .5 treeMe(r.collRoot, positions, uuids, bounds) base.camLens.setFov(90) n = 1E4 # apparently 1e8 is a bit too big and 1e7 is slowwww... definitely need downsampling positions = np.array([ i for i in zip(10 * np.sin(np.arange(0, n)), np.arange(0, n), 10 * np.cos(np.arange(0, n))) ]) # fukken saved r.geomRoot.attachNewNode( makeSimpleGeom(positions, (1, 1, 1, 1), geomType=GeomLinestrips)) #with open('edge_case_data_tuple.pickle','rb') as f: #data_tuple = pickle.load(f) #r.cache['edgecase'] = False #r.set_nodes('edgecase',data_tuple) sgn = GeomNode('srct') sgn.addGeom(makeSelectRect()) sn = render.attachNewNode(sgn) sn.setSx(10) sn.setSy(10) sn.setColor(.5, .5, .5, .5) ut = ui_text() dt = BoxSel(visualize=BoxSel.VIS_ALL) ac = AcceptKeys() base.run()
def drawBody(nodePath, vdata, pos, vecList, radius=1, keepDrawing=True, numVertices=8): circleGeom = Geom(vdata) vertWriter = GeomVertexWriter(vdata, "vertex") colorWriter = GeomVertexWriter(vdata, "color") normalWriter = GeomVertexWriter(vdata, "normal") drawReWriter = GeomVertexRewriter(vdata, "drawFlag") texReWriter = GeomVertexRewriter(vdata, "texcoord") startRow = vdata.getNumRows() vertWriter.setRow(startRow) colorWriter.setRow(startRow) normalWriter.setRow(startRow) sCoord = 0 if (startRow != 0): texReWriter.setRow(startRow - numVertices) sCoord = texReWriter.getData2f().getX() + 1 drawReWriter.setRow(startRow - numVertices) if (drawReWriter.getData1f() == False): sCoord -= 1 drawReWriter.setRow(startRow) texReWriter.setRow(startRow) angleSlice = 2 * math.pi / numVertices currAngle = 0 #axisAdj=LMatrix4.rotateMat(45, axis)*LMatrix4.scaleMat(radius)*LMatrix4.translateMat(pos) perp1 = vecList[1] perp2 = vecList[2] # vertex information is written here for i in range(numVertices): adjCircle = pos + \ (perp1 * math.cos(currAngle) + perp2 * math.sin(currAngle)) * \ radius normal = perp1 * math.cos(currAngle) + perp2 * math.sin(currAngle) normalWriter.addData3f(normal) vertWriter.addData3f(adjCircle) texReWriter.addData2f(sCoord, (i + 0.001) / (numVertices - 1)) colorWriter.addData4f(0.5, 0.5, 0.5, 1) drawReWriter.addData1f(keepDrawing) currAngle += angleSlice drawReader = GeomVertexReader(vdata, "drawFlag") drawReader.setRow(startRow - numVertices) # we cant draw quads directly so we use Tristrips if (startRow != 0) & (drawReader.getData1f() != False): lines = GeomTristrips(Geom.UHStatic) half = int(numVertices * 0.5) for i in range(numVertices): lines.addVertex(i + startRow) if i < half: lines.addVertex(i + startRow - half) else: lines.addVertex(i + startRow - half - numVertices) lines.addVertex(startRow) lines.addVertex(startRow - half) lines.closePrimitive() lines.decompose() circleGeom.addPrimitive(lines) circleGeomNode = GeomNode("Debug") circleGeomNode.addGeom(circleGeom) # I accidentally made the front-face face inwards. Make reverse makes the tree render properly and # should cause any surprises to any poor programmer that tries to use # this code circleGeomNode.setAttrib(CullFaceAttrib.makeReverse(), 1) global numPrimitives numPrimitives += numVertices * 2 nodePath.attachNewNode(circleGeomNode)
def __init__(self): ShowBase.__init__(self) self.scene = self.loader.loadModel("models/test.egg") self.scene.reparentTo(self.render) self.scene.setScale(1, 3, 1) # self.scene.setPos(0, 1000, 0) sphere = CollisionSphere(0, 0, 0, 50) cnode = self.scene.attachNewNode(CollisionNode('cnode_scene')) cnode.node().addSolid(sphere) # cnode.show() base.setBackgroundColor(0, 0.0, 0) base.disableMouse() props = WindowProperties() props.setCursorHidden(True) base.win.requestProperties(props) OnscreenText(text='.', pos=(0, 0, 0)) plight = PointLight('plight') plight.setColor(VBase4(2, 2, 2, 1)) plnp = self.render.attachNewNode(plight) plnp.setPos(0, 0, 100) self.render.setLight(plnp) # dummy node for camera, attach player to it self.camparent = self.render.attachNewNode('camparent') self.camparent.reparentTo(self.render) # inherit transforms self.camparent.setEffect(CompassEffect.make( self.render)) # NOT inherit rotation self.camparent.setY(-1000) self.camparent.setZ(200) # the camera base.camera.reparentTo(self.camparent) base.camera.lookAt(self.camparent) base.camera.setY(0) # camera distance from model self.heading = 0 self.pitch = 0 self.taskMgr.add(self.cameraTask, 'cameraTask') self.keyMap = {"left": 0, "right": 0, "forward": 0, "reverse": 0} self.accept("escape", sys.exit) self.accept("arrow_left", self.setKey, ["left", True]) self.accept("arrow_right", self.setKey, ["right", True]) self.accept("arrow_up", self.setKey, ["forward", True]) self.accept("arrow_down", self.setKey, ["reverse", True]) self.accept("w", self.setKey, ["forward", True]) self.accept("a", self.setKey, ["left", True]) self.accept("s", self.setKey, ["reverse", True]) self.accept("d", self.setKey, ["right", True]) self.accept("arrow_left-up", self.setKey, ["left", False]) self.accept("arrow_right-up", self.setKey, ["right", False]) self.accept("arrow_up-up", self.setKey, ["forward", False]) self.accept("arrow_down-up", self.setKey, ["reverse", False]) self.accept("w-up", self.setKey, ["forward", False]) self.accept("a-up", self.setKey, ["left", False]) self.accept("s-up", self.setKey, ["reverse", False]) self.accept("d-up", self.setKey, ["right", False]) self.accept('mouse1', self.myFunction) self.textObject = None db = TinyDB('paintings/db.json') self.descriptions = dict() base.cTrav = CollisionTraverser() pickerNode = CollisionNode('mouseRay') pickerNP = self.camera.attachNewNode(pickerNode) pickerNode.setFromCollideMask(GeomNode.getDefaultCollideMask()) self.pickerRay = CollisionRay() pickerNode.addSolid(self.pickerRay) self.queue = CollisionHandlerQueue() base.cTrav.addCollider(pickerNP, self.queue) id = 0 for item in db.all(): self.addImage('paintings/' + item['img'], id=id) self.descriptions[id] = item['name'] id += 1
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 create(self): self.chunk_geom = GeomNode('self.chunk_geom') vertex = GeomVertexWriter(self.v_data, 'vertex') normal = GeomVertexWriter(self.v_data, 'normal') texcoord = GeomVertexWriter(self.v_data, 'texcoord') # make buffer of vertices vertices = [] n_vert = 0 t = time.time() tri = GeomTriangles(Geom.UHStatic) def add_data(n_vert, v0, v1, v2, v3, voxel): vertex.addData3f(v0) vertex.addData3f(v1) vertex.addData3f(v2) vertex.addData3f(v3) side1 = v0 - v1 side2 = v0 - v3 norm1 = side1.cross(side2) side1 = v1 - v2 side2 = v1 - v3 norm2 = side1.cross(side2) normal.addData3f(norm1) normal.addData3f(norm1) normal.addData3f(norm1) normal.addData3f(norm2) u1, v1, u2, v2 = voxel.get_uv() texcoord.addData2f(v1, u1) texcoord.addData2f(v2, u1) texcoord.addData2f(v2, u2) texcoord.addData2f(v1, u2) tri.addConsecutiveVertices(0 + n_vert, 3) tri.addVertex(2 + n_vert) tri.addVertex(3 + n_vert) tri.addVertex(0 + n_vert) end = self.chunk_len - 1 for x in xrange(0, self.chunk_len): for y in xrange(0, self.chunk_len): X = self.centerX - self.size2 + (x * self.size_voxel) Y = self.centerY - self.size2 + (y * self.size_voxel) dX = X + self.size_voxel dY = Y + self.size_voxel dx = x + 1 dy = y + 1 v0 = Vec3(x, dy, self.heights[X, dY]) v1 = Vec3(x, y, self.heights[X, Y]) v2 = Vec3(dx, y, self.heights[dX, Y]) v3 = Vec3(dx, dy, self.heights[dX, dY]) add_data(n_vert, v0, v1, v2, v3, self.voxels[X, Y, self.heights[X, Y]]) n_vert += 4 if x == 0: v0 = Vec3(x, y, self.heights[X, Y] - self.size_voxel) v1 = Vec3(x, y, self.heights[X, Y]) v2 = Vec3(x, dy, self.heights[X, dY]) v3 = Vec3(x, dy, self.heights[X, dY] - self.size_voxel) add_data(n_vert, v0, v1, v2, v3, self.voxels[X, Y, self.heights[X, Y]]) n_vert += 4 if y == 0: v0 = Vec3(dx, y, self.heights[dX, Y] - self.size_voxel) v1 = Vec3(dx, y, self.heights[dX, Y]) v2 = Vec3(x, y, self.heights[X, Y]) v3 = Vec3(x, y, self.heights[X, Y] - self.size_voxel) add_data(n_vert, v0, v1, v2, v3, self.voxels[X, Y, self.heights[X, Y]]) n_vert += 4 if x == end: v0 = Vec3(dx, dy, self.heights[dX, dY] - self.size_voxel) v1 = Vec3(dx, dy, self.heights[dX, dY]) v2 = Vec3(dx, y, self.heights[dX, Y]) v3 = Vec3(dx, y, self.heights[dX, Y] - self.size_voxel) add_data(n_vert, v0, v1, v2, v3, self.voxels[X, Y, self.heights[X, Y]]) n_vert += 4 if y == end: v0 = Vec3(x, dy, self.heights[X, dY] - self.size_voxel) v1 = Vec3(x, dy, self.heights[X, dY]) v2 = Vec3(dx, dy, self.heights[dX, dY]) v3 = Vec3(dx, dy, self.heights[dX, dY] - self.size_voxel) add_data(n_vert, v0, v1, v2, v3, self.voxels[X, Y, self.heights[X, Y]]) n_vert += 4 self.geom = Geom(self.v_data) self.geom.addPrimitive(tri) self.chunk_geom.addGeom(self.geom) self.chunk_np = self.attachNewNode('chunk_np') self.chunk_np.attachNewNode(self.chunk_geom) self.chunk_geom.setIntoCollideMask(BitMask32.bit(1)) self.chunk_np.setTag( 'Chunk', 'Chunk: {0} {1} {2}'.format(self.centerX, self.centerY, self.size)) #self.setTwoSided(True) self.water = WaterNode(0, 0, self.size, self.water_tex) self.water.setTwoSided(True) self.water.reparentTo(self) ts = TextureStage('ts') self.chunk_np.setTexture(ts, self.tex) self.chunk_np.setScale(self.size_voxel, self.size_voxel, 1) #t = time.time() # i love this function ^--^ self.flattenStrong()
def CreateDistalSynapses(self, HTMObject, layer, data, inputObjects): for child in self.__node.getChildren(): if child.getName() == "DistalSynapseLine": child.removeNode() printLog("Creating distal synapses", verbosityMedium) printLog("EXTERNAL DISTAL:" + str(inputObjects)) printLog("HTM inputs:" + str(HTMObject.inputs)) printLog("HTM layers:" + str(HTMObject.layers)) for segment in data: for presynCellID in segment: cellID = presynCellID % layer.nOfCellsPerColumn colID = (int)(presynCellID / layer.nOfCellsPerColumn) if colID < len(layer.minicolumns): presynCell = layer.minicolumns[colID].cells[ cellID] # it is within current layer else: # it is for external distal input cellID = presynCellID - len( layer.minicolumns) * layer.nOfCellsPerColumn for inputObj in inputObjects: if inputObj in HTMObject.inputs: if cellID < HTMObject.inputs[inputObj].count: presynCell = HTMObject.inputs[ inputObj].inputBits[cellID] break else: # not this one cellID -= HTMObject.inputs[inputObj].count elif inputObj in HTMObject.layers: if cellID < HTMObject.layers[ inputObj].nOfCellsPerColumn * len( HTMObject.layers[inputObj].minicolumns ): presynCell = HTMObject.layers[ inputObj].minicolumns[(int)( cellID / HTMObject.layers[inputObj]. nOfCellsPerColumn)].cells[ cellID % HTMObject. layers[inputObj].nOfCellsPerColumn] break else: # not this one cellID -= HTMObject.layers[ inputObj].nOfCellsPerColumn * len( HTMObject.layers[inputObj].minicolumns) presynCell.setPresynapticFocus( ) # highlight presynapctic cells form = GeomVertexFormat.getV3() vdata = GeomVertexData("DistalSynapseLine", form, Geom.UHStatic) vdata.setNumRows(1) vertex = GeomVertexWriter(vdata, "vertex") vertex.addData3f(presynCell.getNode().getPos(self.__node)) vertex.addData3f(0, 0, 0) prim = GeomLines(Geom.UHStatic) prim.addVertices(0, 1) geom = Geom(vdata) geom.addPrimitive(prim) node = GeomNode("DistalSynapse") node.addGeom(geom) nodePath = self.__node.attachNewNode(node) nodePath.setRenderModeThickness(2) # color of the line if presynCell.active: nodePath.setColor(COL_DISTAL_SYNAPSES_ACTIVE) else: nodePath.setColor(COL_DISTAL_SYNAPSES_INACTIVE)
def Ramp(self): format = GeomVertexFormat.getV3n3cpt2() vdata = GeomVertexData('square', format, Geom.UHDynamic) vertex = GeomVertexWriter(vdata, 'vertex') #The corner at Quadrant 2 on face 1 is the starting point of our rectangle ################################ # # FACE 1 # ################################ vert1 = LVector3(self.pos.getX(), self.pos.getY(), self.pos.getZ()) vert2 = LVector3(vert1.getX() + self.len, vert1.getY(), vert1.getZ()) vert3 = LVector3(vert2.getX(), vert2.getY() + self.wid, vert2.getZ()) vert4 = LVector3(vert1.getX(), vert1.getY() + self.wid, vert1.getZ()) vertex.addData3(vert1) vertex.addData3(vert2) vertex.addData3(vert3) vertex.addData3(vert4) normal = GeomVertexWriter(vdata, 'normal') norm = (vert4 - vert1).cross(vert2 - vert1) norm.normalize() normal.addData3(norm) normal.addData3(norm) normal.addData3(norm) normal.addData3(norm) color = GeomVertexWriter(vdata, 'color') color.addData4f(self.color) color.addData4f(self.color) color.addData4f(self.color) color.addData4f(self.color) texcoord = GeomVertexWriter(vdata, 'texcoord') texcoord.addData2f(1, 0) texcoord.addData2f(1, 1) texcoord.addData2f(0, 1) texcoord.addData2f(0, 0) tris = GeomTriangles(Geom.UHDynamic) tris.addVertices(0, 3, 1) tris.addVertices(1, 3, 2) ##################################### # # FACE 2 # ##################################### vert5 = vert1 vert6 = vert2 vert7 = LVector3(vert3.getX(), vert3.getY(), vert3.getZ() + self.dep) vert8 = LVector3(vert4.getX(), vert4.getY(), vert4.getZ() + self.dep) vertex.addData3(vert5) vertex.addData3(vert6) vertex.addData3(vert7) vertex.addData3(vert8) norm = (vert8 - vert5).cross(vert6 - vert5) norm.normalize() normal.addData3(norm) normal.addData3(norm) normal.addData3(norm) normal.addData3(norm) color.addData4f(self.color) color.addData4f(self.color) color.addData4f(self.color) color.addData4f(self.color) texcoord.addData2f(1, 0) texcoord.addData2f(1, 1) texcoord.addData2f(0, 1) texcoord.addData2f(0, 0) tris.addVertices(4, 7, 5) tris.addVertices(5, 7, 6) ######################################## # # FACE 3 # ######################################## vert9 = vert1 vert10 = vert2 vert11 = vert6 vert12 = vert5 vertex.addData3(vert9) vertex.addData3(vert10) vertex.addData3(vert11) vertex.addData3(vert12) norm = (vert12 - vert9).cross(vert10 - vert9) norm.normalize() normal.addData3(norm) normal.addData3(norm) normal.addData3(norm) normal.addData3(norm) color.addData4f(self.color) color.addData4f(self.color) color.addData4f(self.color) color.addData4f(self.color) texcoord.addData2f(1, 0) texcoord.addData2f(1, 1) texcoord.addData2f(0, 1) texcoord.addData2f(0, 0) tris.addVertices(8, 11, 9) tris.addVertices(9, 11, 10) ############################################### # # FACE 4 # ############################################### vert13 = vert1 vert14 = vert4 vert15 = vert8 vert16 = vert5 vertex.addData3(vert13) vertex.addData3(vert14) vertex.addData3(vert15) vertex.addData3(vert16) norm = (vert16 - vert13).cross(vert14 - vert13) norm.normalize() normal.addData3(norm) normal.addData3(norm) normal.addData3(norm) normal.addData3(norm) color.addData4f(self.color) color.addData4f(self.color) color.addData4f(self.color) color.addData4f(self.color) texcoord.addData2f(1, 0) texcoord.addData2f(1, 1) texcoord.addData2f(0, 1) texcoord.addData2f(0, 0) tris.addVertices(12, 15, 13) tris.addVertices(13, 15, 14) ############################################ # # FACE 5 # ############################################ vert17 = vert2 vert18 = vert3 vert19 = vert7 vert20 = vert6 vertex.addData3(vert17) vertex.addData3(vert18) vertex.addData3(vert19) vertex.addData3(vert20) norm = (vert20 - vert17).cross(vert18 - vert17) normal.addData3(norm) normal.addData3(norm) normal.addData3(norm) normal.addData3(norm) color.addData4f(self.color) color.addData4f(self.color) color.addData4f(self.color) color.addData4f(self.color) texcoord.addData2f(1, 0) texcoord.addData2f(1, 1) texcoord.addData2f(0, 1) texcoord.addData2f(0, 0) tris.addVertices(16, 19, 17) tris.addVertices(17, 19, 18) ramp = Geom(vdata) ramp.addPrimitive(tris) self.prim = ramp self.model = GeomNode(self.name) self.model.addGeom(self.prim)
def shape_draw_tris(s, render): format = GeomVertexFormat.getV3c4() for face in s.faces: r, g, b = (random.random(), random.random(), random.random()) p = face.original_vertex.pt n = len(face.edges) + 1 vdata = GeomVertexData('facetris', format, Geom.UHStatic) vdata.setNumRows(n + 1) vertex = GeomVertexWriter(vdata, 'vertex') color = GeomVertexWriter(vdata, 'color') prim = GeomTriangles(Geom.UHStatic) vertex.addData3f(p.x, p.y, p.z) color.addData4f((1 + r) / 2, (1 + g) / 2, (1 + b) / 2, 1) pobj = face.get_points() points = pobj['points'] for i, pt in enumerate(points): vertex.addData3f(pt.x, pt.y, pt.z) color.addData4f(r, g, b, 1.0) for i in range(0, len(points)): idx = i + 1 idx2 = idx % len(points) + 1 prim.addVertices(0, idx, idx2) geom = Geom(vdata) geom.addPrimitive(prim) node = GeomNode('TheTris') node.addGeom(geom) nodePath = render.attachNewNode(node) nodePath.setPos(0, 10, 0) # Edges not associated with faces. A completed shape should # not have any of these. But it's useful to see them in wireframe # mode during transitions. for edge in [e for e in s.edges if len(e.faces) == 0]: vdata = GeomVertexData('edgetris', format, Geom.UHStatic) vdata.setNumRows(3) vertex = GeomVertexWriter(vdata, 'vertex') color = GeomVertexWriter(vdata, 'color') prim = GeomTriangles(Geom.UHStatic) vertex.addData3f(edge.v1.pt.x, edge.v1.pt.y, edge.v1.pt.z) color.addData4f(0, 0, 0, 1) vertex.addData3f(edge.v1.pt.x, edge.v1.pt.y, edge.v1.pt.z) color.addData4f(0, 0, 0, 1) vertex.addData3f(edge.v2.pt.x, edge.v2.pt.y, edge.v2.pt.z) color.addData4f(0, 0, 0, 1) prim.addVertices(0, 1, 2) geom = Geom(vdata) geom.addPrimitive(prim) node = GeomNode('TheEdge') node.addGeom(geom) nodePath = render.attachNewNode(node) nodePath.setPos(0, 10, 0) # show rectangle for scale show_rect = False if show_rect: vdata = GeomVertexData('facetris', format, Geom.UHStatic) vdata.setNumRows(4) vertex = GeomVertexWriter(vdata, 'vertex') color = GeomVertexWriter(vdata, 'color') prim = GeomTriangles(Geom.UHStatic) vertex.addData3f(-1, 0, 1) vertex.addData3f(-1, 0, -1) vertex.addData3f(1, 0, -1) vertex.addData3f(1, 0, 1) color.addData4f(1, 1, 1, 1) color.addData4f(1, 1, 1, 1) color.addData4f(1, 1, 1, 1) color.addData4f(1, 1, 1, 1) prim.addVertices(0, 1, 3) prim.addVertices(3, 1, 2) geom = Geom(vdata) geom.addPrimitive(prim) node = GeomNode('TheRect') node.addGeom(geom) nodePath = render.attachNewNode(node) nodePath.setPos(0, 10, 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)
class Grid(VisibleObject): ignore_light = True default_shown = False def __init__(self, name, orientation, color): VisibleObject.__init__(self, name) self.visible = True self.nbOfPoints = 360 self.nbOfRings = 17 self.nbOfSectors = 24 self.points_to_remove = (self.nbOfPoints // (self.nbOfRings + 1)) // 2 self.orientation = orientation self.color = color self.settings_attr = 'show_' + name.lower() + '_grid' def check_settings(self): show = getattr(settings, self.settings_attr) if show is not None: self.set_shown(show) 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 r in range(1, self.nbOfRings + 1): for i in range(self.nbOfPoints): angle = 2 * pi / self.nbOfPoints * i x = cos(angle) * sin( pi * r / (self.nbOfRings + 1) ) y = sin(angle) * sin( pi * r / (self.nbOfRings + 1) ) z = sin( -pi / 2 + pi * r / (self.nbOfRings + 1) ) self.vertexWriter.addData3f((self.context.observer.infinity * x, self.context.observer.infinity * y, self.context.observer.infinity * z)) if r == self.nbOfRings / 2 + 1: self.colorwriter.addData4(srgb_to_linear((self.color.x * 1.5, 0, 0, 1))) else: self.colorwriter.addData4(srgb_to_linear(self.color)) for s in range(self.nbOfSectors): for i in range(self.points_to_remove, self.nbOfPoints // 2 - self.points_to_remove + 1): angle = 2 * pi / self.nbOfPoints * i x = cos(2*pi * s / self.nbOfSectors) * sin(angle) y = sin(2*pi * s / self.nbOfSectors) * sin(angle) z = cos(angle) self.vertexWriter.addData3f((self.context.observer.infinity * x , self.context.observer.infinity * y, self.context.observer.infinity * z)) if s == 0: self.colorwriter.addData4(srgb_to_linear((self.color.x * 1.5, 0, 0, 1))) else: self.colorwriter.addData4(srgb_to_linear(self.color)) self.lines = GeomLines(Geom.UHStatic) index = 0 for r in range(self.nbOfRings): for i in range(self.nbOfPoints-1): self.lines.addVertex(index) self.lines.addVertex(index+1) self.lines.closePrimitive() index += 1 self.lines.addVertex(index) self.lines.addVertex(index - self.nbOfPoints + 1) self.lines.closePrimitive() index += 1 for r in range(self.nbOfSectors): for i in range(self.nbOfPoints // 2 - self.points_to_remove * 2): self.lines.addVertex(index) self.lines.addVertex(index+1) self.lines.closePrimitive() index += 1 index += 1 self.geom = Geom(self.vertexData) self.geom.addPrimitive(self.lines) self.node = GeomNode("grid") self.node.addGeom(self.geom) self.instance = NodePath(self.node) self.instance.setRenderModeThickness(settings.grid_thickness) self.instance.reparentTo(self.context.annotation) self.instance.setQuat(LQuaternion(*self.orientation)) def set_orientation(self, orientation): self.orientation = orientation if self.instance: self.instance.setQuat(LQuaternion(*self.orientation))
class RobotSim(ShowBase): def __init__(self, textboxes=({}), graph_objs={}, default_text_scale=.07): ShowBase.__init__(self) self.scene = self.loader.loadModel("field_1.obj", noCache=True) # Reparent the model to render. self.scene.reparentTo(self.render) self.scene.setPos(0, 0, 0) self.insertLight("MainLight", 0, 0, 75) self.insertLight("ExtraLight1", -50, 0, 75) self.resetSim() self.robot = SwerveBot() self.robot.loadModel() self.setupCones() #Joystick setup self.joys = self.devices.getDevices(InputDevice.DeviceClass.gamepad) #Attaches input devices to base for ind, joy in enumerate(self.joys): self.attachInputDevice(joy, prefix=str(ind)) #Joystick reading variable self.joystick_readings = [] #Text boxes which will be rendered every frame #Key is a node name, value is a dict with #arguments such as text, location, and scale #Hack to keep default argument immutable and prevent bugs if type(textboxes) == tuple: self.textboxes = textboxes[0] else: self.textboxes = textboxes self.textNodes = {} self.textNodePaths = {} self.default_text_scale = default_text_scale self.text_is_active = False #If the text toggle button has been up for more than one frame self.text_button_lifted = True #If changes that need to be made on text have taken place self.text_toggled = True #Graph drawing data #Lines to be rendered on the next frame self.lines = [] self.lineNodes = [] self.lineNodePaths = [] self.graphs = graph_objs for graph in self.graphs: self.graphs[graph].dummyUpdate() #Init physics engine self.physics = physics.Swerve() #Geometry drawing node self.geom_node = GeomNode("drawer") self.aspect2d.attach_new_node(self.geom_node) #Tasks self.taskMgr.add(self.updateJoysticks, "updateJoysticks") self.taskMgr.add(self.driveRobot, "driveRobot") self.taskMgr.add(self.updateHud, "updateHud") self.taskMgr.add(self.toggleHud, "toggleHud") self.accept('r', self.reportStatus) self.accept('i', self.resetSim) self.accept('a', self.robot.toggleAutoDrive) def driveRobot(self, task): """ Task to drive the robot """ x = self.joystick_readings[0]["axes"]["left_x"] y = self.joystick_readings[0]["axes"]["left_y"] z = self.joystick_readings[0]["axes"]["right_x"] self.physics.sendControls(x, y, z) self.physics.update() self.setRobotToLocation() return Task.cont def setRobotToLocation(self): x = self.physics.position[0] y = self.physics.position[1] angle = self.physics.position[2] * (2 * pi) self.robot.setPos(x, y, angle) caster_angle_1 = self.physics.positions["brswerve"] * (180 / pi) + 90 caster_angle_2 = self.physics.positions["blswerve"] * (180 / pi) + 90 caster_angle_3 = self.physics.positions["flswerve"] * (180 / pi) + 90 caster_angle_4 = self.physics.positions["frswerve"] * (180 / pi) + 90 self.robot.setCasterAngles(caster_angle_1, caster_angle_2, caster_angle_3, caster_angle_4) wheel_angle_1 = self.physics.positions["brwheel"] / (2 * pi) wheel_angle_2 = self.physics.positions["blwheel"] / (2 * pi) wheel_angle_3 = self.physics.positions["flwheel"] / (2 * pi) wheel_angle_4 = self.physics.positions["frwheel"] / (2 * pi) self.robot.setWheelTurns(wheel_angle_1, wheel_angle_2, wheel_angle_3, wheel_angle_4) def updateJoysticks(self, task): joystick_readings = [] for joystick in self.joys: joystick_readings.append(joy.readJoystickValues(joystick)) self.joystick_readings = joystick_readings return Task.cont def updateHud(self, task): #Removes all lines from the geometry node self.geom_node.removeAllGeoms() if self.text_is_active: frvector = "Mag: {}\nDir: {}\nTheta_acc: {}\nVel_x: {}\nVel_y: {}\nVel_t: {}\nPos: {}, {}\nRot: {}".format( round(self.physics.vectors["frame"].magnitude, 4), round(self.physics.vectors["frame"].direction, 4), round(self.physics.z_acceleration, 4), round(self.physics.velocities["frame"][0], 4), round(self.physics.velocities["frame"][1], 4), round(self.physics.z_velocity, 4), round(self.physics.position[0], 4), round(self.physics.position[1], 4), round(self.physics.position[2], 4)) self.textboxes["frvector_value"]["text"] = frvector self.lines = [] for graph_name in self.graphs: lines, strings = self.graphs[graph_name].render() #Splits the lines into pairs of points and assigns them to self.lines for line in lines: self.lines += pairPoints(line) #Clears all graph generated strings from textboxes deleted = [] for key in self.textboxes: if graph_name in key: deleted.append(key) for key in deleted: self.textboxes.pop(key) #Processes strings into textboxes for ind, val in enumerate(strings): location, string = val self.textboxes["{}_{}".format(graph_name, str(ind))] = { "location": location, "text": string } self.manageTextNodes() self.renderText() self.manageGeometry() return Task.cont def toggleHud(self, task): if self.joystick_readings[0]["axes"][ "right_trigger"] >= .05 and self.text_button_lifted: self.text_is_active = not self.text_is_active self.text_toggled = False self.text_button_lifted = False elif not self.joystick_readings[0]["axes"]["right_trigger"] >= .05: self.text_button_lifted = True if not self.text_toggled: if not self.text_is_active: for path in self.textNodePaths: self.textNodePaths[path].detachNode() for path in self.lineNodePaths: path.detachNode() else: for node in self.textNodes: self.textNodePaths[node] = self.aspect2d.attachNewNode( self.textNodes[node]) for node in self.lineNodes: self.aspect2d.attachNewNode(node) return Task.cont def resetSim(self): base.disableMouse() self.resetCamPosition() self.allowMovement() def allowMovement(self): mat = Mat4(camera.getMat()) mat.invertInPlace() base.mouseInterfaceNode.setMat(mat) base.enableMouse() #self.resetCamPosition() def insertLight(self, name, x, y, z): lightball = self.loader.loadModel("lightball_1.obj", noCache=True) lightball.reparentTo(self.render) lightball.setPos(x, y, z) plight = PointLight(name) plight.setColor(VBase4(1.0, 1.0, 1.0, 1)) plnp = self.render.attachNewNode(plight) plnp.setPos(x, y, z) self.render.setLight(plnp) def setupCones(self): self.cones = [] conepos = [(20, 20), (18, 0)] for cp in conepos: c = Cones() c.loadModel() x, y = cp c.setPos(x, y) self.cones.append(c) def reportStatus(self): x = base.camera.getX() y = base.camera.getY() z = base.camera.getZ() print("Camera Position", x, y, z) h = base.camera.getH() p = base.camera.getP() r = base.camera.getR() print("Camera Angle", h, p, r) def resetCamPosition(self): self.camPos = (-28, -23, 17) self.camAngle = (-51, -17, -12) x, y, z = self.camPos h, p, r = self.camAngle base.camera.setPos(x, y, z) base.camera.setHpr(h, p, r)
def renderCharts(facegraph, verts, vert_indices, lineset=None): from meshtool.filters.panda_filters.pandacore import getVertexData, attachLights, ensureCameraAt from meshtool.filters.panda_filters.pandacontrols import KeyboardMovement, MouseDrag, MouseScaleZoom, ButtonUtils from panda3d.core import GeomTriangles, Geom, GeomNode, GeomVertexFormat, GeomVertexData, GeomVertexWriter, LineSegs from direct.showbase.ShowBase import ShowBase vformat = GeomVertexFormat.getV3c4() vdata = GeomVertexData('tris', vformat, Geom.UHDynamic) vertex = GeomVertexWriter(vdata, 'vertex') color = GeomVertexWriter(vdata, 'color') colors = gen_color3(len(facegraph)) numtris = 0 for chart, data in facegraph.nodes_iter(data=True): curcolor = next(colors) for tri in data['tris']: triv = verts[vert_indices[tri]] vertex.addData3f(triv[0][0], triv[0][1], triv[0][2]) vertex.addData3f(triv[1][0], triv[1][1], triv[1][2]) vertex.addData3f(triv[2][0], triv[2][1], triv[2][2]) color.addData4f(curcolor[0], curcolor[1], curcolor[2], 1) color.addData4f(curcolor[0], curcolor[1], curcolor[2], 1) color.addData4f(curcolor[0], curcolor[1], curcolor[2], 1) numtris += 1 tris = GeomTriangles(Geom.UHDynamic) tris.addConsecutiveVertices(0, 3 * numtris) tris.closePrimitive() linenodes = [] if lineset: for lines in lineset: ls = LineSegs() ls.setThickness(4) curcolor = next(colors) ls.setColor(curcolor[0] / 256.0, curcolor[1] / 256.0, curcolor[2] / 256.0, 1) tuples = False for blah in lines: if isinstance(blah, tuple): tuples = True break if tuples: for i, j in lines: frompt = verts[i] topt = verts[j] ls.moveTo(frompt[0], frompt[1], frompt[2]) ls.drawTo(topt[0], topt[1], topt[2]) else: for i in range(len(lines) - 1): frompt = verts[lines[i]] topt = verts[lines[i + 1]] ls.moveTo(frompt[0], frompt[1], frompt[2]) ls.drawTo(topt[0], topt[1], topt[2]) linenodes.append(ls.create()) pgeom = Geom(vdata) pgeom.addPrimitive(tris) node = GeomNode("primitive") node.addGeom(pgeom) p3dApp = ShowBase() #attachLights(render) geomPath = render.attachNewNode(node) for linenode in linenodes: geomPath.attachNewNode(linenode) #geomPath.setRenderModeWireframe() ensureCameraAt(geomPath, base.cam) boundingSphere = geomPath.getBounds() base.cam.setPos(boundingSphere.getCenter() + boundingSphere.getRadius()) base.cam.lookAt(boundingSphere.getCenter()) KeyboardMovement() ButtonUtils(geomPath) MouseDrag(geomPath) MouseScaleZoom(geomPath) #render.setShaderAuto() p3dApp.run()
def __init__(self): # Basics ShowBase.__init__(self) # self.disableMouse() self.setFrameRateMeter(True) self.backfaceCullingOff() self.accept("escape", sys.exit) self.camera.set_pos(-10, -10, 10) self.camera.look_at(-10, 0, 0) # A light plight = PointLight("plight") plight.setColor(VBase4(1, 1, 1, 1)) plnp = self.render.attachNewNode(plight) plnp.setPos(10, 10, 50) self.render.setLight(plnp) # Create the geometry vformat = GeomVertexFormat.getV3n3c4() vdata = GeomVertexData("Data", vformat, Geom.UHStatic) vdata.setNumRows(3) vertex = GeomVertexWriter(vdata, 'vertex') normal = GeomVertexWriter(vdata, 'normal') color = GeomVertexWriter(vdata, 'color') ''' vertex.addData3f(0, 0, 0) normal.addData3f(0, 0, 1) color.addData4f(0, 0, 1, 1) vertex.addData3f(0, 150, 0) normal.addData3f(0, 0, 1) color.addData4f(0, 1, 0, 1) vertex.addData3f(10, 150, 0) normal.addData3f(0, 0, 1) color.addData4f(1, 0, 0, 1) vertex.addData3f(10, 0, 0) normal.addData3f(0, 0, 1) color.addData4f(0, 0, 0, 1) ''' prim = GeomTriangles(Geom.UHStatic) ''' prim.addVertices(0, 1, 2) prim.addVertices(2, 1, 0) prim.addVertices(2, 3, 0) prim.addVertices(0, 3, 2) ''' org = np.array([0, 0, 0]) add_rect(0, org, np.array([1, 0, 0]), np.array([0, 1, 0]), (1, 1, 1, 1), vertex, normal, color, prim) add_rect(1, org, np.array([-0.05, 0, 0]), np.array([0, 2, 0]), (0, 0, 1, 1), vertex, normal, color, prim) add_rect(2, org, np.array([2, 0, 0]), np.array([0, -0.05, 0]), (0, 1, 0, 1), vertex, normal, color, prim) prim.closePrimitive() geom = Geom(vdata) geom.addPrimitive(prim) node = GeomNode("GNode") node.addGeom(geom) nodePath = self.render.attachNewNode(node)
tris.addVertices(1, 2, 3) square = Geom(vdata) square.addPrimitive(tris) return square # Note: it isn't particularly efficient to make every face as a separate Geom. # instead, it would be better to create one Geom holding all of the faces. square0 = makeSquare(-1, -1, -1, 1, -1, 1) square1 = makeSquare(-1, 1, -1, 1, 1, 1) square2 = makeSquare(-1, 1, 1, 1, -1, 1) square3 = makeSquare(-1, 1, -1, 1, -1, -1) square4 = makeSquare(-1, -1, -1, -1, 1, 1) square5 = makeSquare(1, -1, -1, 1, 1, 1) snode = GeomNode('square') snode.addGeom(square0) snode.addGeom(square1) snode.addGeom(square2) snode.addGeom(square3) snode.addGeom(square4) snode.addGeom(square5) cube = render.attachNewNode(snode) cube.hprInterval(1.5, (360, 360, 360)).loop() # OpenGl by default only draws "front faces" (polygons whose vertices are # specified CCW). cube.setTwoSided(True)
def generate( self ): # call this after setting some of the variables to update it if hasattr(self, 'geomNode'): self.geomNode.removeAllGeoms() static_mode = Geom.UHStatic if self.static else Geom.UHDynamic vertex_format = Mesh._formats[(bool(self.colors), bool(self.uvs), bool(self.normals))] vdata = GeomVertexData('name', vertex_format, static_mode) vdata.setNumRows(len(self.vertices)) # for speed self.geomNode = GeomNode('mesh') self.attachNewNode(self.geomNode) vertexwriter = GeomVertexWriter(vdata, 'vertex') for v in self.vertices: vertexwriter.addData3f((v[0], v[2], v[1])) # swap y and z if self.colors: colorwriter = GeomVertexWriter(vdata, 'color') for c in self.colors: colorwriter.addData4f(c) if self.uvs: uvwriter = GeomVertexWriter(vdata, 'texcoord') for uv in self.uvs: uvwriter.addData2f(uv[0], uv[1]) if self.normals != None: normalwriter = GeomVertexWriter(vdata, 'normal') for norm in self.normals: normalwriter.addData3f((norm[0], norm[2], norm[1])) if self.mode != 'line' or not self._triangles: prim = Mesh._modes[self.mode](static_mode) if self._triangles: if isinstance(self._triangles[0], int): for t in self._triangles: prim.addVertex(t) elif len( self._triangles[0] ) >= 3: # if tris are tuples like this: ((0,1,2), (1,2,3)) for t in self._triangles: if len(t) == 3: for e in t: prim.addVertex(e) elif len(t) == 4: # turn quad into tris prim.addVertex(t[0]) prim.addVertex(t[1]) prim.addVertex(t[2]) prim.addVertex(t[2]) prim.addVertex(t[3]) prim.addVertex(t[0]) else: prim.addConsecutiveVertices(0, len(self.vertices)) prim.close_primitive() geom = Geom(vdata) geom.addPrimitive(prim) self.geomNode.addGeom(geom) else: # line with segments defined in triangles for line in self._triangles: prim = Mesh._modes[self.mode](static_mode) for e in line: prim.addVertex(e) prim.close_primitive() geom = Geom(vdata) geom.addPrimitive(prim) self.geomNode.addGeom(geom) if self.mode == 'point': self.setTexGen(TextureStage.getDefault(), TexGenAttrib.MPointSprite) # self.set_render_mode_perspective(True) 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 Prism(self): format = GeomVertexFormat.getV3n3cpt2() vdata = GeomVertexData('square', format, Geom.UHDynamic) vertex = GeomVertexWriter(vdata, 'vertex') #################################### #First, we need to create the first face, and then base #the other faces on it. #################################### # # DIAGRAM OF A RECTANGULAR PRISM # |--------| # | Face 6 |<-Depth # |--------|--------|--------|--------| # | Face 4 | Face 2 | Face 3 | Face 1 | <-Width # | | | | | # |--------|--------|--------|--------| # | Face 5 | ^Length # |--------| #################################### #The corner at Quadrant 2 on face 1 is the starting point of our rectangle ################################ # # FACE 1 # ################################ vert1 = LVector3(self.pos.getX(), self.pos.getY(), self.pos.getZ()) vert2 = LVector3(vert1.getX() + self.len, vert1.getY(), vert1.getZ()) vert3 = LVector3(vert2.getX(), vert2.getY() + self.wid, vert2.getZ()) vert4 = LVector3(vert1.getX(), vert1.getY() + self.wid, vert1.getZ()) vertex.addData3(vert1) vertex.addData3(vert2) vertex.addData3(vert3) vertex.addData3(vert4) normal = GeomVertexWriter(vdata, 'normal') norm = (vert4 - vert1).cross(vert2 - vert1) norm.normalize() normal.addData3(norm) normal.addData3(norm) normal.addData3(norm) normal.addData3(norm) color = GeomVertexWriter(vdata, 'color') color.addData4f(self.color) color.addData4f(self.color) color.addData4f(self.color) color.addData4f(self.color) texcoord = GeomVertexWriter(vdata, 'texcoord') texcoord.addData2f(1, 0) texcoord.addData2f(1, 1) texcoord.addData2f(0, 1) texcoord.addData2f(0, 0) tris = GeomTriangles(Geom.UHDynamic) tris.addVertices(0, 3, 1) tris.addVertices(1, 3, 2) ##################################### # # FACE 2 # ##################################### vert5 = LVector3(vert1.getX(), vert1.getY(), vert1.getZ() - self.dep) vert6 = LVector3(vert5.getX() + self.len, vert5.getY(), vert5.getZ()) vert7 = LVector3(vert6.getX(), vert6.getY() + self.wid, vert6.getZ()) vert8 = LVector3(vert5.getX(), vert5.getY() + self.wid, vert5.getZ()) vertex.addData3(vert5) vertex.addData3(vert6) vertex.addData3(vert7) vertex.addData3(vert8) norm = (vert8 - vert5).cross(vert6 - vert5) norm.normalize() normal.addData3(norm) normal.addData3(norm) normal.addData3(norm) normal.addData3(norm) color.addData4f(self.color) color.addData4f(self.color) color.addData4f(self.color) color.addData4f(self.color) texcoord.addData2f(1, 0) texcoord.addData2f(1, 1) texcoord.addData2f(0, 1) texcoord.addData2f(0, 0) tris.addVertices(4, 7, 5) tris.addVertices(5, 7, 6) ######################################## # # FACE 3 # ######################################## vert9 = vert1 vert10 = vert2 vert11 = vert6 vert12 = vert5 vertex.addData3(vert9) vertex.addData3(vert10) vertex.addData3(vert11) vertex.addData3(vert12) norm = (vert12 - vert9).cross(vert10 - vert9) norm.normalize() normal.addData3(norm) normal.addData3(norm) normal.addData3(norm) normal.addData3(norm) color.addData4f(self.color) color.addData4f(self.color) color.addData4f(self.color) color.addData4f(self.color) texcoord.addData2f(1, 0) texcoord.addData2f(1, 1) texcoord.addData2f(0, 1) texcoord.addData2f(0, 0) tris.addVertices(8, 11, 9) tris.addVertices(9, 11, 10) ########################################## # # FACE 4 # ########################################### vert13 = vert4 vert14 = vert3 vert15 = vert7 vert16 = vert8 vertex.addData3(vert13) vertex.addData3(vert14) vertex.addData3(vert15) vertex.addData3(vert16) norm = (vert16 - vert13).cross(vert14 - vert13) norm.normalize() normal.addData3(norm) normal.addData3(norm) normal.addData3(norm) normal.addData3(norm) color.addData4f(self.color) color.addData4f(self.color) color.addData4f(self.color) color.addData4f(self.color) texcoord.addData2f(1, 0) texcoord.addData2f(1, 1) texcoord.addData2f(0, 1) texcoord.addData2f(0, 0) tris.addVertices(12, 15, 13) tris.addVertices(13, 15, 14) square = Geom(vdata) square.addPrimitive(tris) ############################################### # # FACE 5 # ############################################### vert17 = vert1 vert18 = vert4 vert19 = vert8 vert20 = vert5 vertex.addData3(vert17) vertex.addData3(vert18) vertex.addData3(vert19) vertex.addData3(vert20) norm = (vert20 - vert17).cross(vert18 - vert17) norm.normalize() normal.addData3(norm) normal.addData3(norm) normal.addData3(norm) normal.addData3(norm) color.addData4f(self.color) color.addData4f(self.color) color.addData4f(self.color) color.addData4f(self.color) texcoord.addData2f(1, 0) texcoord.addData2f(1, 1) texcoord.addData2f(0, 1) texcoord.addData2f(0, 0) tris.addVertices(16, 19, 17) tris.addVertices(17, 19, 18) ############################################ # # FACE 6 # ############################################ vert21 = vert2 vert22 = vert3 vert23 = vert7 vert24 = vert6 vertex.addData3(vert21) vertex.addData3(vert22) vertex.addData3(vert23) vertex.addData3(vert24) norm = (vert21 - vert24).cross(vert21 - vert22) norm.normalize() normal.addData3(norm) normal.addData3(norm) normal.addData3(norm) normal.addData3(norm) color.addData4f(self.color) color.addData4f(self.color) color.addData4f(self.color) color.addData4f(self.color) texcoord.addData2f(1, 0) texcoord.addData2f(1, 1) texcoord.addData2f(0, 1) texcoord.addData2f(0, 0) tris.addVertices(20, 23, 21) tris.addVertices(21, 23, 22) square = Geom(vdata) square.addPrimitive(tris) self.prim = square self.model = GeomNode(self.name) self.model.addGeom(self.prim)