예제 #1
0
    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)
예제 #2
0
    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)
예제 #3
0
    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
예제 #4
0
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])
예제 #7
0
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
예제 #8
0
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)
예제 #9
0
    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
예제 #10
0
    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)
예제 #11
0
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
예제 #13
0
    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)
예제 #14
0
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