def addPoint(self, x, y, wheel_dir, force): """ Adds a point to the skid mark trail. The coordinates are in the world frame. The force is a number between zero and one, where one is the max force and makes the biggest and darkest skid mark. The argument 'wheel_dir' is given in degrees, where zero points toward the positive X axis. """ h = self.wheel_width * 0.5 rads = (wheel_dir - 90) * math.pi / 180.0 x0b, y0b = x + h * math.cos(rads), y + h * math.sin(rads) rads = (wheel_dir + 90) * math.pi / 180.0 x1b, y1b = x + h * math.cos(rads), y + h * math.sin(rads) x0a, y0a, x1a, y1a = self.lastpoints self.lastpoints = (x0b, y0b, x1b, y1b) if not self.havelast: self.havelast = True return indx = self.nextrect * 4 self.nextrect += 1 if self.nextrect >= self.nrects: self.nextrect = 0 vtx = GeomVertexWriter(self.vdata, "vertex") cx = GeomVertexWriter(self.vdata, "color") vtx.setRow(indx) cx.setRow(indx) c = self.forceToColor(force) vtx.addData3f(x0a, y0a, self.zpos) vtx.addData3f(x1a, y1a, self.zpos) vtx.addData3f(x0b, y0b, self.zpos) vtx.addData3f(x1b, y1b, self.zpos) cx.addData4f(*c) cx.addData4f(*c) cx.addData4f(*c) cx.addData4f(*c)
def drawBody(self, pos, quat, radius=1, keepDrawing=True, numVertices=16): """ this draws the body of the tree. This draws a ring of vertices and connects the rings with triangles to from the body. the keepDrawing parameter tells the function whether or not we're at an end if the vertices before were an end, don't draw branches to it """ vdata = self.bodydata circleGeom = Geom(vdata) vertWriter = GeomVertexWriter(vdata, "vertex") normalWriter = GeomVertexWriter(vdata, "normal") texReWriter = GeomVertexRewriter(vdata, "texcoord") startRow = vdata.getNumRows() vertWriter.setRow(startRow) normalWriter.setRow(startRow) sCoord = 0 if (startRow != 0): texReWriter.setRow(startRow - numVertices) sCoord = texReWriter.getData2f().getX() + 1 draw = (startRow - numVertices) in self.drawFlags if not draw: sCoord -= 1 drawIndex = startRow texReWriter.setRow(startRow) angleSlice = 2 * math.pi / numVertices currAngle = 0 perp1 = quat.getRight() perp2 = quat.getForward() #vertex information is written here for i in xrange(numVertices + 1): #doubles the last vertex to fix UV seam 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(1.0 * i / numVertices, sCoord) if keepDrawing: self.drawFlags.add(drawIndex) drawIndex += 1 currAngle += angleSlice draw = (startRow - numVertices) in self.drawFlags #we cant draw quads directly so we use Tristrips if (startRow != 0) and draw: lines = GeomTristrips(Geom.UHStatic) for i in xrange(numVertices + 1): lines.addVertex(i + startRow) lines.addVertex(i + startRow - numVertices - 1) lines.addVertex(startRow) lines.addVertex(startRow - numVertices) lines.closePrimitive() #lines.decompose() circleGeom.addPrimitive(lines) circleGeomNode = GeomNode("Debug") circleGeomNode.addGeom(circleGeom) self.numPrimitives += numVertices * 2 self.bodies.attachNewNode(circleGeomNode)
def drawBody(self, pos, quat, radius=1,UVcoord=(1,1), numVertices=_polySize): # if isRoot: # self.bodydata = GeomVertexData("body vertices", GeomVertexFormat.getV3n3t2(), Geom.UHStatic) vdata = self.bodydata circleGeom = Geom(vdata) # this was originally a copy of all previous geom in 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) texReWriter.setRow(startRow) #axisAdj=Mat4.rotateMat(45, axis)*Mat4.scaleMat(radius)*Mat4.translateMat(pos) perp1 = quat.getRight() perp2 = quat.getForward() #TODO: PROPERLY IMPLEMENT RADIAL NOISE #vertex information is written here angleSlice = 2 * pi / numVertices currAngle = 0 for i in xrange(numVertices+1): adjCircle = pos + (perp1 * cos(currAngle) + perp2 * sin(currAngle)) * radius * (.5+bNodeRadNoise*random.random()) normal = perp1 * cos(currAngle) + perp2 * sin(currAngle) normalWriter.addData3f(normal) vertWriter.addData3f(adjCircle) texReWriter.addData2f(float(UVcoord[0]*i) / numVertices,UVcoord[1]) # UV SCALE HERE! #colorWriter.addData4f(0.5, 0.5, 0.5, 1) currAngle += angleSlice #we cant draw quads directly so we use Tristrips if (startRow != 0): lines = GeomTristrips(Geom.UHStatic) for i in xrange(numVertices+1): lines.addVertex(i + startRow) lines.addVertex(i + startRow - numVertices-1) lines.addVertex(startRow) lines.addVertex(startRow - numVertices) lines.closePrimitive() #lines.decompose() circleGeom.addPrimitive(lines) circleGeomNode = GeomNode("Debug") circleGeomNode.addGeom(circleGeom) self.numPrimitives += numVertices * 2 self.bodies.attachNewNode(circleGeomNode) return circleGeomNode
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 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 update_nodepath(pandaNode, refinements): geom = pandaNode.modifyGeom(0) vertdata = geom.modifyVertexData() prim = geom.modifyPrimitive(0) indexdata = prim.modifyVertices() indexwriter = GeomVertexWriter(indexdata) indexwriter.setColumn(0) nextTriangleIndex = indexdata.getNumRows() vertwriter = GeomVertexWriter(vertdata, 'vertex') numverts = vertdata.getNumRows() vertwriter.setRow(numverts) normalwriter = GeomVertexWriter(vertdata, 'normal') normalwriter.setRow(numverts) uvwriter = GeomVertexWriter(vertdata, 'texcoord') uvwriter.setRow(numverts) for refinement in refinements: for op_index in range(len(refinement)): vals = refinement[op_index] op = vals[0] if op == PM_OP.TRIANGLE_ADDITION: indexwriter.setRow(nextTriangleIndex) nextTriangleIndex += 3 indexwriter.addData1i(vals[1]) indexwriter.addData1i(vals[2]) indexwriter.addData1i(vals[3]) elif op == PM_OP.INDEX_UPDATE: indexwriter.setRow(vals[1]) indexwriter.setData1i(vals[2]) elif op == PM_OP.VERTEX_ADDITION: numverts += 1 vertwriter.addData3f(vals[1], vals[2], vals[3]) normalwriter.addData3f(vals[4], vals[5], vals[6]) uvwriter.addData2f(vals[7], vals[8])
class MapPointMngr: def __init__(self): # self.point_cloud: List[Tuple[Tuple[float, float, float], int]] = [] self.v_data = None self.vert_writer = None self.color_writer = None self.uv_writer = None self.normal_writer = None self.draw_writer = None self.map_dim = (0, 0) self.crit_points_per_hex: List[List[Tuple[Tuple[float, float, float], int]]] = [] def set_v_data(self, v_data): self.v_data = v_data self.vert_writer = GeomVertexWriter(self.v_data, "vertex") self.color_writer = GeomVertexWriter(self.v_data, "color") self.uv_writer = GeomVertexWriter(self.v_data, "texcoord") self.normal_writer = GeomVertexWriter(self.v_data, "normal") self.draw_writer = GeomVertexWriter(self.v_data, "drawFlag") def set_map_dim(self, map_dim: Tuple[int, int]): self.map_dim = map_dim def add_non_critical_point(self, p: Tuple[float, float, float], hex_x_grid: int, hex_y_grid: int, uv_map: Vec2, n=Vec3(.0, .0, 1.0)) -> int: if not self.v_data: return -1 lin_idx = self.linearize(hex_x_grid, hex_y_grid) if len(self.crit_points_per_hex) <= lin_idx: print("ERROR - can add non critical points only to a existing hexagon ..") return -1 points_hex = self.crit_points_per_hex[lin_idx] idx = self.__add_point_to_vdata(p, n, uv_map) points_hex.append((p, idx)) return idx def add_critical_point(self, p: Tuple[float, float, float], hex_x_grid: int, hex_y_grid: int, uv_map: Vec2, n=Vec3(.0, .0, 1.0)) -> int: if not self.v_data: return -1 lin_idx = self.linearize(hex_x_grid, hex_y_grid) if len(self.crit_points_per_hex) == lin_idx: # print(f"add center point: {p}") # new hexagon and point is a center-point (cannot exist already) self.crit_points_per_hex.append([]) idx = self.__add_point_to_vdata(p, n, uv_map) self.crit_points_per_hex[lin_idx].append((p, idx)) return idx else: # print(f"add non-center point {p}") # existing hexagon - 3 neighbouring hexagons possible # if hex_x_grid > 0: # points_west = self.crit_points_per_hex[self.linearize(hex_x_grid-1, hex_y_grid)] # for nei, idx in points_west: # if self.close_enough(p, nei): # return idx # if hex_y_grid > 0: # points_south_west = self.crit_points_per_hex[self.linearize(hex_x_grid, hex_y_grid - 1)] # for nei, idx in points_south_west: # if self.close_enough(p, nei): # return idx # points_south_east = self.crit_points_per_hex[self.linearize(hex_x_grid+1, hex_y_grid - 1)] # for nei, idx in points_south_east: # if self.close_enough(p, nei): # return idx idx = self.__add_point_to_vdata(p, n, uv_map) self.crit_points_per_hex[lin_idx].append((p, idx)) return idx # for vec, idx in self.point_cloud: # if abs(vec[0] - p[0]) < TOL and abs(vec[1] - p[1]) < TOL and abs(vec[2] - p[2]) < TOL: # # print(f"point reused at {vec} -> ({p})") # return idx # print(f"new point at {p}") def __add_point_to_vdata(self, p, n, uv_map) -> int: new_idx = self.v_data.getNumRows() self.vert_writer.setRow(new_idx) self.color_writer.setRow(new_idx) self.uv_writer.setRow(new_idx) self.draw_writer.setRow(new_idx) self.normal_writer.setRow(new_idx) position = Vec3(p[0], p[1], p[2]) self.vert_writer.addData3f(position) self.color_writer.addData4f(.3, .3, .3, 1.0) self.normal_writer.addData3f(n) self.uv_writer.addData2f(uv_map[0], uv_map[1]) # not sure here return new_idx def linearize(self, x, y): return y * self.map_dim[0] + x def close_enough(self, p, other): return abs(other[0] - p[0]) < TOL and abs(other[1] - p[1]) < TOL and abs(other[2] - p[2]) < TOL
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 if startRow == 0: return drawReader = GeomVertexReader(vdata, "drawFlag") drawReader.setRow(startRow - numVertices) # we cant draw quads directly so we use Tristrips if drawReader.getData1i() != 0: 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 drawBody(self, pos, quat, radius=1, UVcoord=(1, 1), numVertices=_polySize): # if isRoot: # self.bodydata = GeomVertexData("body vertices", GeomVertexFormat.getV3n3t2(), Geom.UHStatic) vdata = self.bodydata circleGeom = Geom( vdata ) # this was originally a copy of all previous geom in 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) texReWriter.setRow(startRow) #axisAdj=Mat4.rotateMat(45, axis)*Mat4.scaleMat(radius)*Mat4.translateMat(pos) perp1 = quat.getRight() perp2 = quat.getForward() #TODO: PROPERLY IMPLEMENT RADIAL NOISE #vertex information is written here angleSlice = 2 * pi / numVertices currAngle = 0 for i in xrange(numVertices + 1): adjCircle = pos + (perp1 * cos(currAngle) + perp2 * sin(currAngle)) * radius * ( .5 + bNodeRadNoise * random.random()) normal = perp1 * cos(currAngle) + perp2 * sin(currAngle) normalWriter.addData3f(normal) vertWriter.addData3f(adjCircle) texReWriter.addData2f( float(UVcoord[0] * i) / numVertices, UVcoord[1]) # UV SCALE HERE! #colorWriter.addData4f(0.5, 0.5, 0.5, 1) currAngle += angleSlice #we cant draw quads directly so we use Tristrips if (startRow != 0): lines = GeomTristrips(Geom.UHStatic) for i in xrange(numVertices + 1): lines.addVertex(i + startRow) lines.addVertex(i + startRow - numVertices - 1) lines.addVertex(startRow) lines.addVertex(startRow - numVertices) lines.closePrimitive() #lines.decompose() circleGeom.addPrimitive(lines) circleGeomNode = GeomNode("Debug") circleGeomNode.addGeom(circleGeom) self.numPrimitives += numVertices * 2 self.bodies.attachNewNode(circleGeomNode) return circleGeomNode
def movePmTo(self, dest_index): geom = self.geomPath.node().modifyGeom(0) vertdata = geom.modifyVertexData() prim = geom.modifyPrimitive(0) indexdata = prim.modifyVertices() indexrewriter = GeomVertexRewriter(indexdata) indexrewriter.setColumn(0) nextTriangleIndex = indexdata.getNumRows() vertwriter = GeomVertexWriter(vertdata, 'vertex') numverts = vertdata.getNumRows() vertwriter.setRow(numverts) normalwriter = GeomVertexWriter(vertdata, 'normal') normalwriter.setRow(numverts) uvwriter = GeomVertexWriter(vertdata, 'texcoord') uvwriter.setRow(numverts) while self.pm_index < dest_index: for op_index in range(len(self.pm_refinements[self.pm_index])): vals = self.pm_refinements[self.pm_index][op_index] op = vals[0] if op == PM_OP.TRIANGLE_ADDITION: indexrewriter.setRow(nextTriangleIndex) nextTriangleIndex += 3 indexrewriter.addData1i(vals[1]) indexrewriter.addData1i(vals[2]) indexrewriter.addData1i(vals[3]) elif op == PM_OP.INDEX_UPDATE: #TODO: ugly workaround for p3d 1.7 bug, change to below for 1.8 indexreader = GeomVertexReader(indexdata) indexreader.setColumn(0) indexreader.setRow(vals[1]) oldval = indexreader.getData1i() del indexreader #indexrewriter.setRow(vals[1]) #oldval = indexrewriter.getData1i() indexrewriter.setRow(vals[1]) indexrewriter.setData1i(vals[2]) self.pm_refinements[self.pm_index][op_index] = (op, vals[1], oldval) elif op == PM_OP.VERTEX_ADDITION: numverts += 1 vertwriter.addData3f(vals[1], vals[2], vals[3]) normalwriter.addData3f(vals[4], vals[5], vals[6]) uvwriter.addData2f(vals[7], vals[8]) self.pm_index += 1 while self.pm_index > dest_index: self.pm_index -= 1 for op_index in range(len(self.pm_refinements[self.pm_index])): vals = self.pm_refinements[self.pm_index][op_index] op = vals[0] if op == PM_OP.TRIANGLE_ADDITION: nextTriangleIndex -= 3 elif op == PM_OP.INDEX_UPDATE: #TODO: ugly workaround for p3d 1.7 bug, change to below for 1.8 indexreader = GeomVertexReader(indexdata) indexreader.setColumn(0) indexreader.setRow(vals[1]) oldval = indexreader.getData1i() del indexreader #indexrewriter.setRow(vals[1]) #oldval = indexrewriter.getData1i() indexrewriter.setRow(vals[1]) indexrewriter.setData1i(vals[2]) self.pm_refinements[self.pm_index][op_index] = (op, vals[1], oldval) elif op == PM_OP.VERTEX_ADDITION: numverts -= 1 if nextTriangleIndex < indexdata.getNumRows(): indexdata.setNumRows(nextTriangleIndex) if numverts < vertdata.getNumRows(): vertdata.setNumRows(numverts)
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)
class Planetimpl(): def __init__(self, world, size, distance, ratio, description, rotation, translation): self.worldOrigin = world self.size = size self.distance = distance self.renderRatio = ratio self.description = description self.rotation = rotation self.translation = translation def impl(self): # Load the Moon model self.planet = loader.loadModel("models/planet_sphere") self.chooseTexture("models/"+self.description+"_1k_tex.jpg") self.planet.reparentTo(self.worldOrigin) self.planet.setScale(self.size * self.renderRatio) self.planet.setPos(self.distance * self.renderRatio, 0.0, 0.0) self.planet.setTag('targetSize', str(self.size)) self.planet.setTag('isPickable', '2') self.startstop = True return self.planet def chooseTexture(self, name): """ Methode zum Setzen der Ursprungstextur """ self.planet.setTexture(loader.loadTexture(name), 1) def line(self): # Create and populate the Moon orbit model using Vertices and Lines self.planetOrbitVertexData = GeomVertexData(self.description+'OrbitVertexData', GeomVertexFormat.getV3(), Geom.UHDynamic) self.planetOrbitVertexWriter = GeomVertexWriter(self.planetOrbitVertexData, 'vertex') self.planetOrbitNumberPoints = 360 for i in range(self.planetOrbitNumberPoints): angleDegrees = i * 360 / self.planetOrbitNumberPoints angleRadians = angleDegrees * (pi / 180.0) x = -self.distance * sin(angleRadians) y = self.distance * cos(angleRadians) self.planetOrbitVertexWriter.addData3f(x, y, 0.0) self.planetOrbitLines = GeomLines(Geom.UHStatic) for i in range(self.planetOrbitNumberPoints-1): self.planetOrbitLines.addVertex(i) self.planetOrbitLines.addVertex(i+1) self.planetOrbitLines.closePrimitive() self.planetOrbitLines.addVertex(self.planetOrbitNumberPoints-1) self.planetOrbitLines.addVertex(0) self.planetOrbitLines.closePrimitive() self.planetOrbitGeom = Geom(self.planetOrbitVertexData) self.planetOrbitGeom.addPrimitive(self.planetOrbitLines) self.planetOrbitNode = GeomNode(self.description+'OrbitNode') self.planetOrbitNode.addGeom(self.planetOrbitGeom) self.planetOrbitNnodePath = render.attachNewNode(self.planetOrbitNode) self.planetOrbitNnodePath.reparentTo(self.worldOrigin) return self.planetOrbitVertexWriter def setstartstop(self): self.startstop = not self.startstop return self.startstop def rotatePlanet(self, task): # Compute earth rotation frameTime = globalClock.getFrameTime() angleDegrees = frameTime * self.rotation self.planet.setHpr(angleDegrees, 0, 0) # End task if self.startstop: return Task.cont else: return Task.done def translatePlanet(self, task): # Compute Moon position relative to Earth with circular orbit frameTime = globalClock.getFrameTime() angleDegrees = frameTime * self.translation angleRadians = angleDegrees * (pi / 180.0) # Compute the Moon's position with respect to the Earth x = -self.distance * self.renderRatio * sin(angleRadians) y = self.distance * self.renderRatio * cos(angleRadians) # Set the position on the model self.planet.setPos(x, y, 0.0) # Also rotate the orbit to follow the Moon and eliminate jitter effect self.planetOrbitVertexWriter.setRow(0) for i in range(self.planetOrbitNumberPoints): angleDegrees = angleDegrees + 360.0 / self.planetOrbitNumberPoints angleRadians = angleDegrees * (pi / 180.0) x = -self.distance * self.renderRatio * sin(angleRadians) y = self.distance * self.renderRatio * cos(angleRadians) self.planetOrbitVertexWriter.setData3f(x, y, 0.0) # End task if self.startstop: return Task.cont else: return Task.done
class RenderApp(ShowBase): def __init__(self, data, timescale, scale, record, dark_matter, no_ordinary_matter): self.data = data self.scale = scale self.timescale = timescale self.dark_matter = dark_matter self.no_ordinary_matter = no_ordinary_matter self.n_particles = self.data.shape[1] ShowBase.__init__(self) vdata = GeomVertexData('galaxies', GeomVertexFormat.get_v3c4(), Geom.UHStatic) vdata.setNumRows(self.n_particles) self.vertex = GeomVertexWriter(vdata, 'vertex') color = GeomVertexWriter(vdata, 'color') for i in range(self.n_particles): if (self.data[0][i].dark_matter and not self.dark_matter) or (not self.data[0][i].dark_matter and self.no_ordinary_matter): continue pos = self.data[0][i].pos / self.scale self.vertex.addData3(*pos) color.addData4(1, 1, 1, 1) prim = GeomPoints(Geom.UHStatic) prim.add_consecutive_vertices(0, self.n_particles - 1) geom = Geom(vdata) geom.addPrimitive(prim) node = GeomNode('gnode') node.addGeom(geom) nodePath = self.render.attach_new_node(node) nodePath.setRenderModeThickness(2) self.disableMouse() self.useTrackball() self.trackball.node().set_pos(0, 100, 0) self.trackball.node().set_hpr(90, 0, 90) self.setBackgroundColor(0, 0, 0) self.taskMgr.add(self.update_task, "VertexUpdateTask") self.record(record) def load_data(self): self.data = cs.Result.load(self.file).numpy() def record(self, time): if time > 0: self.movie("screenshot", time, fps=60) def update_vertex(self, i): for j in range(self.n_particles): if (self.data[0][j].dark_matter and not self.dark_matter) or (not self.data[0][j].dark_matter and self.no_ordinary_matter): continue pos = self.data[i][j].pos / self.scale self.vertex.setRow(j) self.vertex.setData3(*pos) def update_task(self, task): index = int((task.time * self.timescale)) % self.data.shape[0] self.update_vertex(index) return Task.cont