def createTrifans(self, basepoint, pointrange): prim = GeomTrifans(Geom.UHStatic) prim.addVertex(basepoint) for i in pointrange: prim.addVertex(i) prim.addVertex(pointrange[0]) prim.closePrimitive() return prim
def createColoredUnitDisk(color_vec4=Vec4(0., 0., 1., 1.), num_of_verts=10, origin_point=Vec3(0., 0., 0.), radius=1.): # Own Geometry # format = GeomVertexFormat.getV3c4t2() format = GeomVertexFormat.getV3c4() vdata = GeomVertexData("colored_circle", format, Geom.UHStatic) vdata.setNumRows(4) vertexPosWriter = GeomVertexWriter(vdata, "vertex") # num_of_verts = 10 # phi = 0. r = radius # origin_point_x = 0. # origin_point_z = 0. vertexPosWriter.addData3f(origin_point[0], origin_point[1], origin_point[2]) circle_points = math_utils.get_circle_vertices(num_of_verts=num_of_verts, radius=r) circle_points[:,0] += origin_point[0] circle_points[:,1] += origin_point[1] circle_points[:,2] += origin_point[2] _normal_vector_info = Vec3(0., 1., 0.) # this is returned just as info about the normal vector of the generated geometry for p in circle_points: vertexPosWriter.addData3f(p[0], 0, p[1]) # for i in range(num_of_verts): # phi += 2. * np.pi / num_of_verts # x = r * np.cos(phi) # z = r * np.sin(phi) # vertexPosWriter.addData3f(x, 0, z) # let's also add color to each vertex colorWriter = GeomVertexWriter(vdata, "color") colorWriter.addData4f(color_vec4) # origin point for i in range(num_of_verts): colorWriter.addData4f(color_vec4) # make primitives and assign vertices to them (primitives and primitive # groups can be made independently from vdata, and are later assigned # to vdata) tris = GeomTrifans(Geom.UHStatic) # the first vertex is a vertex that all triangles share tris.add_consecutive_vertices(0, num_of_verts+1) tris.addVertex(1) tris.closePrimitive() # the 1st primitive is finished # make a Geom object to hold the primitives geom = Geom(vdata) geom.addPrimitive(tris) geom_node = GeomNode("colored_circle_node") geom_node.addGeom(geom) return geom_node, _normal_vector_info
def 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 makeCircle(vdata, numVertices=40,offset=Vec3(0,0,0), direction=1): circleGeom=Geom(vdata) vertWriter=GeomVertexWriter(vdata, "vertex") normalWriter=GeomVertexWriter(vdata, "normal") colorWriter=GeomVertexWriter(vdata, "color") uvWriter=GeomVertexWriter(vdata, "texcoord") drawWriter=GeomVertexWriter(vdata, "drawFlag") #make sure we start at the end of the GeomVertexData so we dont overwrite anything #that might be there already startRow=vdata.getNumRows() vertWriter.setRow(startRow) colorWriter.setRow(startRow) uvWriter.setRow(startRow) normalWriter.setRow(startRow) drawWriter.setRow(startRow) angle=2*math.pi/numVertices currAngle=angle for i in range(numVertices): position=Vec3(math.cos(currAngle)+offset.getX(), math.sin(currAngle)+offset.getY(),offset.getZ()) vertWriter.addData3f(position) uvWriter.addData2f(position.getX()/2.0+0.5,position.getY()/2.0+0.5) colorWriter.addData4f(1.0, 1.0, 1.0, 1.0) position.setZ(position.getZ()*direction) position.normalize() normalWriter.addData3f(position) #at default Opengl only draws "front faces" (all shapes whose vertices are arranged CCW). We #need direction so we can specify which side we want to be the front face currAngle+=angle*direction circle=GeomTrifans(Geom.UHStatic) circle.addConsecutiveVertices(startRow, numVertices) circle.closePrimitive() circleGeom.addPrimitive(circle) return circleGeom
def __init__(self, __occupying_unit = None, __occupiable = True, x = 0, z = 0, r = 5, tag = 0): self.__occupying_unit = __occupying_unit self.__occupiable = __occupiable self.__r = r self.__x = x self.__z = z self.__tag = tag #Procedurally creating a hex! geometry_array = GeomVertexArrayFormat() geometry_array.addColumn(InternalName.make('vertex'), 3, Geom.NTFloat32, Geom.CPoint) geometry_array.addColumn(InternalName.make('normal'), 3, Geom.NTFloat32, Geom.CPoint) format = GeomVertexFormat() format.addArray(geometry_array) format = GeomVertexFormat.registerFormat(format) self.__vdata = GeomVertexData('Hex', format, Geom.UHStatic) self.__vertex = GeomVertexWriter(self.__vdata, 'vertex') self.__normal = GeomVertexWriter(self.__vdata, 'normal') #Vertex 1 self.__vertex.addData3f(self.__x, self.__z+self.__r, 0) self.__normal.addData3f(1, 0, 0) #Vertex 2 self.__vertex.addData3f(self.__x+self.__r*sin(pi/3), self.__z+self.__r*cos(pi/3), 0) self.__normal.addData3f(1, 0, 0) #Vertex 3 self.__vertex.addData3f(self.__x+self.__r*sin(pi/3), self.__z-self.__r*cos(pi/3), 0) self.__normal.addData3f(1, 0, 0) #Vertex 4 self.__vertex.addData3f(self.__x, self.__z-self.__r, 0) self.__normal.addData3f(1, 0, 0) #Vertex 5 self.__vertex.addData3f(self.__x-self.__r*sin(pi/3), self.__z-self.__r*cos(pi/3), 0) self.__normal.addData3f(1, 0, 0) #Vertex 6 self.__vertex.addData3f(self.__x-self.__r*sin(pi/3), self.__z+self.__r*cos(pi/3), 0) self.__normal.addData3f(1, 0, 0) self.__hex_primitive = GeomTrifans(Geom.UHStatic) self.__hex_primitive.addVertices(5, 4) self.__hex_primitive.addVertices(3, 2) self.__hex_primitive.addVertices(1, 0) self.__hex_primitive.closePrimitive() self.__hex_geometry = Geom(self.__vdata) self.__hex_geometry.addPrimitive(self.__hex_primitive) self.__hex_node = GeomNode('HexNode') self.__hex_node.addGeom(self.__hex_geometry) nodePath = render.attachNewNode(self.__hex_node) nodePath.setTag( "hex", str(tag) ) nodePath.node().setIntoCollideMask(BitMask32.bit(1)) nodePath.hide()
def makeCircle(vdata, numVertices=40, offset=Vec3(0, 0, 0), direction=1): circleGeom = Geom(vdata) vertWriter = GeomVertexWriter(vdata, "vertex") normalWriter = GeomVertexWriter(vdata, "normal") colorWriter = GeomVertexWriter(vdata, "color") uvWriter = GeomVertexWriter(vdata, "texcoord") drawWriter = GeomVertexWriter(vdata, "drawFlag") #make sure we start at the end of the GeomVertexData so we dont overwrite anything #that might be there already startRow = vdata.getNumRows() vertWriter.setRow(startRow) colorWriter.setRow(startRow) uvWriter.setRow(startRow) normalWriter.setRow(startRow) drawWriter.setRow(startRow) angle = 2 * math.pi / numVertices currAngle = angle for i in range(numVertices): position = Vec3( math.cos(currAngle) + offset.getX(), math.sin(currAngle) + offset.getY(), offset.getZ()) vertWriter.addData3f(position) uvWriter.addData2f(position.getX() / 2.0 + 0.5, position.getY() / 2.0 + 0.5) colorWriter.addData4f(1.0, 1.0, 1.0, 1.0) position.setZ(position.getZ() * direction) position.normalize() normalWriter.addData3f(position) #at default Opengl only draws "front faces" (all shapes whose vertices are arranged CCW). We #need direction so we can specify which side we want to be the front face currAngle += angle * direction circle = GeomTrifans(Geom.UHStatic) circle.addConsecutiveVertices(startRow, numVertices) circle.closePrimitive() circleGeom.addPrimitive(circle) return circleGeom
class Gridspace: """ This class contains information about an individual gridspace """ __occupying_unit = None __occupiable = None __x = 0 __z = 0 __r = 0 __tag = 0 __vdata = None __vertex = None __normal = None __hex_primitive = None __hex_geometry = None __hex_node = None def __init__(self, __occupying_unit=None, __occupiable=True, x=0, z=0, r=5, tag=0): self.__occupying_unit = __occupying_unit self.__occupiable = __occupiable self.__r = r self.__x = x self.__z = z self.__tag = tag #Procedurally creating a hex! geometry_array = GeomVertexArrayFormat() geometry_array.addColumn(InternalName.make('vertex'), 3, Geom.NTFloat32, Geom.CPoint) geometry_array.addColumn(InternalName.make('normal'), 3, Geom.NTFloat32, Geom.CPoint) format = GeomVertexFormat() format.addArray(geometry_array) format = GeomVertexFormat.registerFormat(format) self.__vdata = GeomVertexData('Hex', format, Geom.UHStatic) self.__vertex = GeomVertexWriter(self.__vdata, 'vertex') self.__normal = GeomVertexWriter(self.__vdata, 'normal') #Vertex 1 self.__vertex.addData3f(self.__x, self.__z + self.__r, 0) self.__normal.addData3f(1, 0, 0) #Vertex 2 self.__vertex.addData3f(self.__x + self.__r * sin(pi / 3), self.__z + self.__r * cos(pi / 3), 0) self.__normal.addData3f(1, 0, 0) #Vertex 3 self.__vertex.addData3f(self.__x + self.__r * sin(pi / 3), self.__z - self.__r * cos(pi / 3), 0) self.__normal.addData3f(1, 0, 0) #Vertex 4 self.__vertex.addData3f(self.__x, self.__z - self.__r, 0) self.__normal.addData3f(1, 0, 0) #Vertex 5 self.__vertex.addData3f(self.__x - self.__r * sin(pi / 3), self.__z - self.__r * cos(pi / 3), 0) self.__normal.addData3f(1, 0, 0) #Vertex 6 self.__vertex.addData3f(self.__x - self.__r * sin(pi / 3), self.__z + self.__r * cos(pi / 3), 0) self.__normal.addData3f(1, 0, 0) self.__hex_primitive = GeomTrifans(Geom.UHStatic) self.__hex_primitive.addVertices(5, 4) self.__hex_primitive.addVertices(3, 2) self.__hex_primitive.addVertices(1, 0) self.__hex_primitive.closePrimitive() self.__hex_geometry = Geom(self.__vdata) self.__hex_geometry.addPrimitive(self.__hex_primitive) self.__hex_node = GeomNode('HexNode') self.__hex_node.addGeom(self.__hex_geometry) nodePath = render.attachNewNode(self.__hex_node) nodePath.setTag("hex", str(tag)) nodePath.node().setIntoCollideMask(BitMask32.bit(1)) nodePath.hide() def get_x_position(self): return self.__x def get_y_position(self): return self.__z def get_occupying_unit(self): return self.__occupying_unit def set_occupying_unit(self, __occupying_unit): self.__occupying_unit = __occupying_unit def get_occupiable(self): return self.__occupiable def set_occupiable(self, __occupiable): self.__occupiable = __occupiable def getTag(self): return self.__tag
def __init__(self, point, vertices, map_width=1024, map_height=1024, base=0.0): self.point = point # TODO: Sort these clockwise (they still are 2D points) # http://stackoverflow.com/questions/6989100/sort-points-in-clockwise-order # Might just need to reverse if the wrong way. I think they're already # ordered. Should be able to tell by checking the normal calculation. self.vertices = vertices # Ensure that stuff is working correctly if [-10.101, -10.101] in vertices: raise ValueError("Can't create this region.") # TODO: Constrain the bounds like this... though it's somewhat busted. # for i, v in enumerate(vertices): # x, y = v # x = max(min(x, map_width/2), -map_width/2) # y = max(min(y, map_height/2), -map_height/2) # vertices[i] = (x, y) for v in vertices: if not (-map_width/2 <= v[0] <= map_width/2 and -map_height/2 <= v[1] <= map_height/2): raise ValueError("Can't create this region.") # 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 # TODO: Migrate to Tristrips. # TODO: Make walls, floors (and ceilings?) prim = GeomTrifans(Geom.UHStatic) DETAIL = 128 HEIGHT_SCALE = 20 vertices = [ (v[0], v[1], snoise2( v[0]/DETAIL, v[1]/DETAIL, base=base, persistence=0.5, lacunarity=2.0, repeatx=map_width/4, repeaty=map_height/4, octaves=5) * HEIGHT_SCALE) for v in vertices] num_high = len(list(filter(lambda x: x[2] > HEIGHT_SCALE * 0.4, vertices))) num_above = len(list(filter(lambda x: HEIGHT_SCALE * 0.4 > x[2] > 0, vertices))) num_below = len(list(filter(lambda x: x[2] <= 0, vertices))) num_deep = len(list(filter(lambda x: x[2] < -HEIGHT_SCALE * 0.2, vertices))) # Calculate the color: # * White if high altitude # * Green if land # * Tan if coast # * Blue if water # * Dark Blue if deep water # poly_color = (uniform(0, 1), uniform(0, 1), uniform(0, 1), 1, ) if num_high: white = uniform(0.7, 1.0) poly_color = (white, white, white, 1.0) elif num_below and num_above: yellow = uniform(0.5, 1.0) poly_color = (yellow, yellow, 0.0, 1.0) elif num_deep: poly_color = (0.0, 0.0, uniform(0.5, 1.0), 1.0) elif num_below: poly_color = (0.3, 0.3, uniform(0.5, 1.0), 1.0) else: poly_color = (0.0, uniform(0.5, 1.0), 0.0, 1.0) for i, point in enumerate(vertices): vertex.addData3f(point[0], point[1], max(point[2], 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)
def create_GeomNode_Cone(color_vec4=Vec4(1., 1., 1., 1.)): # a cone that points into the y direction # and the center of it's base is at the origin # ---- step 1: create circle with trifans in the x-y plane and close the primitive format = GeomVertexFormat.getV3c4() vdata = GeomVertexData("colored_quad", format, Geom.UHStatic) vdata.setNumRows(4) # add color to each vertex colorWriter = GeomVertexWriter(vdata, "color") # add a vertex position to each vertex vertexPosWriter = GeomVertexWriter(vdata, "vertex") # first the circle vertices num_of_circle_vertices = 10 circle_verts = math_utils.get_circle_vertices(num_of_verts=num_of_circle_vertices) # then the origin point vertex vertexPosWriter.addData3f(0., 0., 0.) colorWriter.addData4f(color_vec4) for v in circle_verts: vertexPosWriter.addData3f(v[0], v[1], v[2]) colorWriter.addData4f(color_vec4) # build the primitive (base of cone) tris = GeomTrifans(Geom.UHStatic) # the first vertex is a vertex that all triangles share tris.add_consecutive_vertices(0, num_of_circle_vertices+1) # add all vertices # close up the circle (the last triangle involves the first # point of the circle base, i.e. point with index 1) tris.addVertex(1) tris.closePrimitive() # this resets all the data contained in the vertexPosWriter and colorWriter # ---- step 2: create tip vertex and make a trifans primitive # with the vertices of the cone base outer circle # first the tip point vertex vertexPosWriter.addData3f(0., 0., cos(pi / 6.)) colorWriter.addData4f(color_vec4) tris.addVertex(num_of_circle_vertices+1) tris.add_consecutive_vertices(0, num_of_circle_vertices+1) # add all circle vertices # close up the circle (the last triangle involves the first # point of the circle base, i.e. point with index 1) tris.addVertex(0) tris.closePrimitive() # this resets all the data contained in the vertexPosWriter and colorWriter # ----- step 3: make a GeomNode out of the Geom (to which the Primitives have been added) # make a Geom object to hold the primitives geom = Geom(vdata) geom.addPrimitive(tris) geom_node = GeomNode("colored_polygon_node") geom_node.addGeom(geom) return geom_node
def generate( self ): # call this after setting some of the variables to update it if not self.vertices: return if hasattr(self, 'geomNode'): self.geomNode.removeAllGeoms() static_mode = Geom.UHStatic if self.static else Geom.UHDynamic formats = { (0, 0, 0): GeomVertexFormat.getV3(), (1, 0, 0): GeomVertexFormat.getV3c4(), (0, 1, 0): GeomVertexFormat.getV3t2(), (0, 0, 1): GeomVertexFormat.getV3n3(), (1, 0, 1): GeomVertexFormat.getV3n3c4(), (1, 1, 0): GeomVertexFormat.getV3c4t2(), (0, 1, 1): GeomVertexFormat.getV3n3t2(), (1, 1, 1): GeomVertexFormat.getV3n3c4t2(), } vertex_format = formats[(bool(self.colors), bool(self.uvs), bool(self.normals))] vdata = GeomVertexData('name', vertex_format, static_mode) vdata.setNumRows(len(self.vertices)) # for speed vertexwriter = GeomVertexWriter(vdata, 'vertex') for v in self.vertices: vertexwriter.addData3f((v[0], v[2], v[1])) # swap y and z if self.colors: colorwriter = GeomVertexWriter(vdata, 'color') for c in self.colors: colorwriter.addData4f(c) if self.uvs: uvwriter = GeomVertexWriter(vdata, 'texcoord') for uv in self.uvs: uvwriter.addData2f(uv[0], uv[1]) if self.normals != None: normalwriter = GeomVertexWriter(vdata, 'normal') for norm in self.normals: normalwriter.addData3f((norm[0], norm[2], norm[1])) modes = { 'triangle': GeomTriangles(static_mode), 'tristrip': GeomTristrips(static_mode), 'ngon': GeomTrifans(static_mode), 'line': GeomLines(static_mode), 'lines': GeomLinestrips(static_mode), 'point': GeomPoints(static_mode), } if self.mode == 'line' and len(self.vertices) % 2 > 0: if len(self.vertices) == 1: self.mode = point print( 'warning: number of vertices must be even for line mode, ignoring last vert' ) self.vertices = self.vertices[:len(self.vertices) - 1] prim = modes[self.mode] if self._triangles: if isinstance(self._triangles[0], int): for t in self._triangles: prim.addVertex(t) elif len( self._triangles[0] ) >= 3: # if tris are tuples like this: ((0,1,2), (1,2,3)) for t in self._triangles: if len(t) == 3: for e in t: prim.addVertex(e) elif len(t) == 4: # turn quad into tris prim.addVertex(t[0]) prim.addVertex(t[1]) prim.addVertex(t[2]) prim.addVertex(t[2]) prim.addVertex(t[3]) prim.addVertex(t[0]) else: prim.addConsecutiveVertices(0, len(self.vertices)) prim.close_primitive() geom = Geom(vdata) geom.addPrimitive(prim) self.geomNode = GeomNode('mesh') self.geomNode.addGeom(geom) self.attachNewNode(self.geomNode) # print('finished') self.recipe = f'''Mesh(
def generate( self ): # call this after setting some of the variables to update it if hasattr(self, 'geomNode'): self.geomNode.removeAllGeoms() static_mode = Geom.UHStatic if self.static else Geom.UHDynamic formats = { (0, 0, 0): GeomVertexFormat.getV3(), (1, 0, 0): GeomVertexFormat.getV3c4(), (0, 1, 0): GeomVertexFormat.getV3t2(), (0, 0, 1): GeomVertexFormat.getV3n3(), (1, 0, 1): GeomVertexFormat.getV3n3c4(), (1, 1, 0): GeomVertexFormat.getV3c4t2(), (0, 1, 1): GeomVertexFormat.getV3n3t2(), (1, 1, 1): GeomVertexFormat.getV3n3c4t2(), } vertex_format = formats[(bool(self.colors), bool(self.uvs), bool(self.normals))] vdata = GeomVertexData('name', vertex_format, static_mode) vdata.setNumRows(len(self.vertices)) # for speed vertexwriter = GeomVertexWriter(vdata, 'vertex') for v in self.vertices: vertexwriter.addData3f((v[0], v[2], v[1])) # swap y and z if self.colors: colorwriter = GeomVertexWriter(vdata, 'color') for c in self.colors: colorwriter.addData4f(c) if self.uvs: uvwriter = GeomVertexWriter(vdata, 'texcoord') for uv in self.uvs: uvwriter.addData2f(uv[0], uv[1]) if self.normals != None: normalwriter = GeomVertexWriter(vdata, 'normal') for norm in self.normals: normalwriter.addData3f((norm[0], norm[2], norm[1])) modes = { 'triangle': GeomTriangles(static_mode), 'tristrip': GeomTristrips(static_mode), 'ngon': GeomTrifans(static_mode), 'line': GeomLinestrips(static_mode), 'point': GeomPoints(static_mode), } if self.mode != 'line' or not self._triangles: prim = modes[self.mode] if self._triangles: if isinstance(self._triangles[0], int): for t in self._triangles: prim.addVertex(t) elif len( self._triangles[0] ) >= 3: # if tris are tuples like this: ((0,1,2), (1,2,3)) for t in self._triangles: if len(t) == 3: for e in t: prim.addVertex(e) elif len(t) == 4: # turn quad into tris prim.addVertex(t[0]) prim.addVertex(t[1]) prim.addVertex(t[2]) prim.addVertex(t[2]) prim.addVertex(t[3]) prim.addVertex(t[0]) else: prim.addConsecutiveVertices(0, len(self.vertices)) prim.close_primitive() geom = Geom(vdata) geom.addPrimitive(prim) else: # line with segments defnined in triangles for line in self._triangles: prim = modes[self.mode] for e in line: prim.addVertex(e) prim.close_primitive() geom = Geom(vdata) geom.addPrimitive(prim) self.geomNode = GeomNode('mesh') self.geomNode.addGeom(geom) self.attachNewNode(self.geomNode) # if self.normals: # self.normals = [tuple(e) for e in self.normals] self.recipe = dedent(f''' Mesh( vertices={[tuple(e) for e in self.vertices]}, triangles={self._triangles}, colors={[tuple(e) for e in self.colors]}, uvs={self.uvs}, normals={[tuple(e) for e in self.normals]}, static={self.static}, mode="{self.mode}", thickness={self.thickness} ) ''')