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)
class PolyGroup(): # vdata is the Panda3D vertex data object created by the main Mesh def __init__(self, vdata, tex_idx): self.vdata = vdata # vertex data, passed in from parent mesh self.name = 'PolyGroup_' + str(tex_idx) self.geom = Geom(self.vdata) self.primitives = GeomTriangles(Geom.UHStatic) self.geom.addPrimitive(self.primitives) self.sprite_list_index = 0 self.nodePath = None # Parameters: # wld_container - WldContainer parent object # f - the f36 fragment we are based on # start_index - index of our first poly in the fragment's polyList polygon list # n_polys - numer of polys to build # tex_idx - index of the texture that all our polys share def build(self, wld_container, f, start_index, n_polys, tex_idx, debug=False): # f.dump() self.sprite_list_index = f.fragment1 - 1 # the fragment1 ref is used as sprite list index sprite = wld_container.getSprite(tex_idx, self.sprite_list_index) polyList = f.polyList poly_idx = start_index for poly in range(0, n_polys): p = polyList[poly_idx] poly_idx += 1 self.primitives.addVertices(p[0], p[1], p[2]) self.node = GeomNode(self.name) self.node.addGeom(self.geom) # make a node path for our GEOM, these will be attached under our parent mesh's root self.nodePath = NodePath(self.node) # self.nodePath.setRenderModeWireframe() # self.nodePath.setRenderModeFilled() # self.nodePath.showBounds() self.nodePath.setPos(f.centerX, f.centerY, f.centerZ) # translate to correct position self.nodePath.setAttrib( CullFaceAttrib.make(CullFaceAttrib.MCullCounterClockwise)) # self.nodePath.setAttrib(CullFaceAttrib.make(CullFaceAttrib.MCullClockwise)) # Texture setup if sprite != None: # sprite.dump() if sprite.numtex > 0: t = sprite.textures[0] self.nodePath.setTexture(t) if debug: print(" polygroup build had texture count: " + str(sprite.numtex) + " AnimDelay: " + str(sprite.anim_delay)) patchInvertDDSV(self.nodePath, t, debug) if sprite.anim_delay > 0: geom_num = self.node.getNumGeoms() - 1 if debug: print("Adding geom render state for " + self.name) from panda3d.core import ColorBlendAttrib # seems animated "masked" textrue need this in order to function # dont want to have it on the main zone geoms though cause it breaks # semi trasparent surfaces (water etc). Probably should move away from making those # transparent through color blending and simply patch up their alpha channels as needed? if sprite.masked == 1: self.node.setAttrib( ColorBlendAttrib.make(ColorBlendAttrib.MAdd, ColorBlendAttrib.OAlphaScale, ColorBlendAttrib.OOne)) sprite.addAnimGeomRenderState( (self.node, geom_num, self.node.getGeomState(geom_num), self.name)) else: print 'Error: texture (idx=%i) not found. PolyGroup will be rendered untextured' % ( tex_idx) return 1
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 PolyGroup(): # vdata is the Panda3D vertex data object created by the main Mesh def __init__(self, vdata, tex_idx): self.vdata = vdata # vertex data, passed in from parent mesh self.name = 'PolyGroup_'+str(tex_idx) self.geom = Geom(self.vdata) self.primitives = GeomTriangles(Geom.UHStatic) self.geom.addPrimitive(self.primitives) self.sprite_list_index = 0 self.nodePath = None # Parameters: # wld_container - WldContainer parent object # f - the f36 fragment we are based on # start_index - index of our first poly in the fragment's polyList polygon list # n_polys - numer of polys to build # tex_idx - index of the texture that all our polys share def build(self, wld_container, f, start_index, n_polys, tex_idx,debug=False): # f.dump() self.sprite_list_index = f.fragment1-1 # the fragment1 ref is used as sprite list index sprite = wld_container.getSprite(tex_idx, self.sprite_list_index) polyList = f.polyList poly_idx = start_index for poly in range(0, n_polys): p = polyList[poly_idx] poly_idx += 1 self.primitives.addVertices(p[0], p[1], p[2]) self.node = GeomNode(self.name) self.node.addGeom(self.geom) # make a node path for our GEOM, these will be attached under our parent mesh's root self.nodePath = NodePath(self.node) # self.nodePath.setRenderModeWireframe() # self.nodePath.setRenderModeFilled() # self.nodePath.showBounds() self.nodePath.setPos(f.centerX, f.centerY,f.centerZ) # translate to correct position self.nodePath.setAttrib(CullFaceAttrib.make(CullFaceAttrib.MCullCounterClockwise)) # self.nodePath.setAttrib(CullFaceAttrib.make(CullFaceAttrib.MCullClockwise)) # Texture setup if sprite != None: # sprite.dump() if sprite.numtex > 0: t = sprite.textures[0] self.nodePath.setTexture(t) if debug: print(" polygroup build had texture count: " + str(sprite.numtex) + " AnimDelay: " + str(sprite.anim_delay)) patchInvertDDSV(self.nodePath,t,debug) if sprite.anim_delay > 0: geom_num = self.node.getNumGeoms()-1 if debug: print("Adding geom render state for " + self.name) from panda3d.core import ColorBlendAttrib # seems animated "masked" textrue need this in order to function # dont want to have it on the main zone geoms though cause it breaks # semi trasparent surfaces (water etc). Probably should move away from making those # transparent through color blending and simply patch up their alpha channels as needed? if sprite.masked == 1: self.node.setAttrib(ColorBlendAttrib.make(ColorBlendAttrib.MAdd,ColorBlendAttrib.OAlphaScale,ColorBlendAttrib.OOne)) sprite.addAnimGeomRenderState( (self.node,geom_num,self.node.getGeomState(geom_num),self.name) ) else: print 'Error: texture (idx=%i) not found. PolyGroup will be rendered untextured' % (tex_idx) return 1