A big thanks for this very detailed and informative answer .

I already thought that the GeomNode is a specific type of Panda node but how exactly do I use the functions of it.

Is it just: somenode.function or

somenode.PandaNode.function

if somenode is created as GeomNode?

Back to my main problem. I solved the framerate drop with flattenstrong and it really made a good job in boosting the performance. But the disadvantage you already mentioned comes along with it. It takes over 500 seconds to complete the flatten command.

I´m now trying to create the Landscape with larger batches from the beginning

I did a little performance test on flatten and got the following results:

Tris-----Time[s]-----Time/Tri[s]

1710-----0.37-------0.00022

7594-----7.34-------0.00096

30054----274.00------0.00911

110654----654.00------0.00591

Before flattening each geonode consisted of 2 tris.

That are´t really my expected results and I´m curios why the 30k Tri test is slower than the 110k Tri.

The conclusion I came up with after looking at the first 3 results was that the flattenstrong command tests every geomnode for adjacent geomnodes resulting in an exponential increase of calculation-time with increasing polygons.

The last few hours i tried to solve the Problem to create the Geom in one Bach, this is with what i came up:

```
#you cant normalize in-place so this is a helper function
def myNormalize(myVec):
myVec.normalize()
return myVec
#helper function to make a geom mesh given a Vertexlist (2 vertices in line resume in one rectangle, for example: Vertexlist = [[0,0,0],[0,1,1]]), adapted from panda3d example "Procedural-Cube"
def create_chunk(vertexlist):
format=GeomVertexFormat.getV3n3cpt2()
vdata=GeomVertexData('square', format, Geom.UHDynamic)
vertex=GeomVertexWriter(vdata, 'vertex')
normal=GeomVertexWriter(vdata, 'normal')
color=GeomVertexWriter(vdata, 'color')
texcoord=GeomVertexWriter(vdata, 'texcoord')
#loop through the vertex list and create 1 rectangle for every 2 vertices
TriBuffer = []
maxindex = len(vertexlist)
for index in range(0,maxindex,2):
pointa = vertexlist[index]
pointb = vertexlist[index+1]
#split the vertices to their coordinates for later usage
x1 = pointa[0]
y1 = pointa[1]
z1 = pointa[2]
x2 = pointb[0]
y2 = pointb[1]
z2 = pointb[2]
#make sure we draw the sqaure in the right plane
if x1!=x2:
vertex.addData3f(x1, y1, z1)
vertex.addData3f(x2, y1, z1)
vertex.addData3f(x2, y2, z2)
vertex.addData3f(x1, y2, z2)
normal.addData3f(myNormalize(Vec3(2*x1-1, 2*y1-1, 2*z1-1)))
normal.addData3f(myNormalize(Vec3(2*x2-1, 2*y1-1, 2*z1-1)))
normal.addData3f(myNormalize(Vec3(2*x2-1, 2*y2-1, 2*z2-1)))
normal.addData3f(myNormalize(Vec3(2*x1-1, 2*y2-1, 2*z2-1)))
else:
vertex.addData3f(x1, y1, z1)
vertex.addData3f(x2, y2, z1)
vertex.addData3f(x2, y2, z2)
vertex.addData3f(x1, y1, z2)
normal.addData3f(myNormalize(Vec3(2*x1-1, 2*y1-1, 2*z1-1)))
normal.addData3f(myNormalize(Vec3(2*x2-1, 2*y2-1, 2*z1-1)))
normal.addData3f(myNormalize(Vec3(2*x2-1, 2*y2-1, 2*z2-1)))
normal.addData3f(myNormalize(Vec3(2*x1-1, 2*y1-1, 2*z2-1)))
#adding different colors to the vertex for visibility
color.addData4f(1.0,0.0,0.0,1.0)
color.addData4f(0.0,1.0,0.0,1.0)
color.addData4f(0.0,0.0,1.0,1.0)
color.addData4f(1.0,0.0,1.0,1.0)
texcoord.addData2f(0.0, 1.0)
texcoord.addData2f(0.0, 0.0)
texcoord.addData2f(1.0, 0.0)
texcoord.addData2f(1.0, 1.0)
#quads arent directly supported by the Geom interface
#you might be interested in the CardMaker class if you are
#interested in rectangle though
tri1=GeomTriangles(Geom.UHDynamic)
tri2=GeomTriangles(Geom.UHDynamic)
tri1.addVertex(0+index*2)
tri1.addVertex(1+index*2)
tri1.addVertex(3+index*2)
tri2.addVertex(1+index*2)
tri2.addVertex(3+index*2)
tri2.addVertex(4+index*2)
#tri2.addConsecutiveVertices(1+index*2,3+index*2)
tri1.closePrimitive()
tri2.closePrimitive()
TriBuffer.append(tri1)
TriBuffer.append(tri2)
square=Geom(vdata)
print(type(TriBuffer[10]))
maxindex = len(TriBuffer)
for index in range(maxindex):
primitive = TriBuffer[index]
square.addPrimitive(primitive)
#print(x1, y1, z1)
#print(x2, y2, z1)
#print(x2, y2, z2)
#print(x1, y1, z2)
return square
```

Unfortunately all the time i try to run the program i get the following error message:

square.addPrimitive(primitive)

AssertionError: primitive->check_valid(cdata->_data.get_read_pointer()) at line

370 of c:\buildslave\release_sdk_win32\build\panda3d\panda\src\gobj\geom.cxx

I think that this has something to do with how python adds the GeomTriangles to my TriBuffer array. Probably python just stores a pointer to the GeomTriangle instead of a real copy.

I would really appreciate it if someone knows a solution.