hi, im trying to use the eggoctree from the ‘Code Snipplets’ section to optimize my terrain model.
i met this problem when i try to run the .py file:
AttributeError: ‘libpandaegg.EggTexture’ object has no attribute ‘triangulatePolygons’
this is my code:
EggOctree.py:
from pandac.PandaModules import *
import direct.directbase.DirectStart
from direct.actor.Actor import Actor
from direct.task.Task import Task
from direct.showbase.DirectObject import DirectObject
import random, sys, os, math
import thread
import math
class EggOctree(object):
def build(self, sourceNode, destNode, cellSize, collide=False):
snode = sourceNode
snode.triangulatePolygons(0xff)
# First, extract the <VertexPool>
vpool = snode.getFirstChild()
assert type(vpool) == EggVertexPool, 'First child must be a <VertexPool>'
# Loop on the vertices determine the bounding box
minBB = Point3D()
maxBB = Point3D()
nverts = vpool.getHighestIndex()
for iv in range(nverts + 1) :
vtx = vpool[iv]
vtxPos = vtx.getPos3()
# Sets the X, Y or Z components
i = 0
for set in [Point3D.setX, Point3D.setY, Point3D.setZ] :
if vtxPos[i] < minBB[i] :
set(minBB, vtxPos[i])
if vtxPos[i] > maxBB[i] :
set(maxBB, vtxPos[i])
i += 1
minBB -= Vec3D(0.001, 0.001, 0.001)
maxBB += Vec3D(0.001, 0.001, 0.001)
# Number of leaves x,y,z
bboxSize = maxBB - minBB
self.ncx = math.ceil(bboxSize.getX() / cellSize.getX())
self.ncy = math.ceil(bboxSize.getY() / cellSize.getY())
self.ncz = math.ceil(bboxSize.getZ() / cellSize.getZ())
# Depth of the tree x,y,z
self.depthX = math.ceil(math.log(self.ncx) / math.log(2))
self.depthY = math.ceil(math.log(self.ncy) / math.log(2))
self.depthZ = math.ceil(math.log(self.ncz) / math.log(2))
self.depth = max(self.depthX, self.depthY, self.depthZ)
self.cells = [[[
{'min':
Point3D(minBB.getX() + x * cellSize.getX(),
minBB.getY() + y * cellSize.getY(),
minBB.getZ() + z * cellSize.getZ()),
'max':
Point3D(minBB.getX() + (x+1) * cellSize.getX(),
minBB.getY() + (y+1) * cellSize.getY(),
minBB.getZ() + (z+1) * cellSize.getZ()),
'group':EggGroup('leaf_%d_%d_%d' % (x,y,z)) }
for z in range(self.ncz)]
for y in range(self.ncy)]
for x in range(self.ncx)]
print 'Cell grid is %dx%dx%d' % (len(self.cells), len(self.cells[0]), len(self.cells[0][0]))
if collide :
for x in range(self.ncx) :
for y in range(self.ncy) :
for z in range(self.ncz) :
self.cells[x][y][z]['group'].addObjectType('barrier')
# Iterate on the <Polygon>s (should be triangles)
poly = snode.getNextChild()
while poly != None :
if isinstance(poly, EggPolygon) :
# Get the triangle center
polyCenter = Point3D(0,0,0)
for i in range(3) :
polyCenter += poly.getVertex(i).getPos3()
polyCenter /= 3.0
# Add the triangle to the corresponding cell group
cx = int(math.floor((polyCenter.getX()-minBB.getX()) / cellSize.getX()))
cy = int(math.floor((polyCenter.getY()-minBB.getY()) / cellSize.getY()))
cz = int(math.floor((polyCenter.getZ()-minBB.getZ()) / cellSize.getZ()))
self.cells[cx][cy][cz]['group'].addChild(poly)
poly = snode.getNextChild()
# Add the vertex data
destNode.addChild(vpool)
self.nleaves = self.recur(destNode, 0, 0,0,0)
print self.nleaves, 'leaves added'
def recur(self, node, depth, x, y, z) :
if depth < self.depth :
nnode = EggGroup('')
delt = int(math.pow(2, self.depth - depth - 1))
nchilds = 0
nchilds += self.recur(nnode, depth+1, x, y, z)
nchilds += self.recur(nnode, depth+1, x + delt, y, z)
nchilds += self.recur(nnode, depth+1, x, y + delt, z)
nchilds += self.recur(nnode, depth+1, x + delt, y + delt, z)
nchilds += self.recur(nnode, depth+1, x, y, z + delt)
nchilds += self.recur(nnode, depth+1, x + delt, y, z + delt)
nchilds += self.recur(nnode, depth+1, x, y + delt, z + delt)
nchilds += self.recur(nnode, depth+1, x + delt, y + delt, z + delt)
if nchilds > 0 :
node.addChild(nnode)
return nchilds
else :
# We are in a leaf
if x < self.ncx and y < self.ncy and z < self.ncz :
node.addChild(self.cells[x][y][z]['group'])
return 1
else :
return 0
MyEggTree.py:
from pandac.PandaModules import *
from pandac.PandaModules import EggData,EggVertexPool,EggPolygon,EggVertex,EggGroupNode
import direct.directbase.DirectStart
from direct.actor.Actor import Actor
from direct.task.Task import Task
from direct.showbase.DirectObject import DirectObject
import random, sys, os, math
import thread
from EggOctree import EggOctree
class World(DirectObject, EggData, EggGroupNode):
def __init__(self):
self.config()
taskMgr.add(self.main, 'mainLoop')
pass
def config(self):
self.np = render.attachNewNode('np')
self.octree = EggOctree()
def main(self, task):
egg = EggData()
egg.read(Filename('Map_Tutorial_Level.egg'))
egg.getFirstChild()
sourceNode = egg.getNextChild() # the sourcenode must contain a VertexPool and a list of Polygons
if self.np != None :
self.np.removeNode()
self.np = None
ed = EggData()
ed.setCoordinateSystem(egg.getCoordinateSystem())
# Here, it's a quadtree since there will be only 1 leaf along the Y axis
self.octree.build(sourceNode, ed, Vec3D(3, 100, 3))
ed.writeEgg(Filename('Map_Tutorial_Level_Octree.egg'))
ed = None
self.np = loader.loadModel('Map_Tutorial_Level_Octree.egg')
self.np.reparentTo(render)
self.np.setScale(15);
print 'Been Here'
w = World()
run()
i found that the EggData inherits from the EggGroupNode, but im not too sure of how to use it in the function. im not too sure if i did my code in python correctly cos im still new to python, so i need some help here.
im stuck at this point and cant render anything to the screen or write any .egg files. please correct my code because im really lost