Download:
http://www.homepages.inf.ed.ac.uk/s0094060/terrain.tar.gz
Screenshot:
Download:
http://www.homepages.inf.ed.ac.uk/s0094060/terrain.tar.gz
Screenshot:
Yay for height maps!
All right, so the reason why you can’t go passed 250x250 is a bit of a doozy (I may be way off on this too, but it seems right):
So if you use pdb.pm() at the crash, you’ll see it dying around vertex index 65535, which is in line with the assertion error (in this case, its asking if the newest index is indexArray[65536],
and since uint16(65536)=0x0000, its triggering the assertion error)
Okay, so the heart of this lies in the GeometryPrimitive’s cycleDataWriter. Its based off of CycleData, which is a generic object used by many panda classes to store data. Each class usually implements their own version, and the GeomPrimitive unfortunately uses uint16s to store the vertex indices (check
panda/src/gobj/geomPrimitive.i line 367. CDWriter and Reader are built off of CDATA).
I’m curious if this is a hardware limitation?
(by the way, geomPrimitive.cxx line 247 is the add_vertex function)
Anywho, there’s a funny solution that may be nigh impossible (other than
splitting into multiple geomPrimitives to avoid the 65k vertex limit):
So the GeomPrimitive only builds an index off of the vertex list if it perceives the need to. If your vertex indices in the primitive are strictly ordered (1,2,3,4,5, etc). then it keeps the primitive unindexed. As a result, it avoids using the cycle data at all, preventing the assertion. You can test this with the following:
myGeom=GeomTriangles(Geom.UHStatic)
for i in range(100000):
myGeom.addVertex(3*i)
myGeom.addVertex(3*i+1)
myGeom.addVertex(3*i+2)
myGeom.closePrimitive()
will make 1000000 polygons. You can kill the whole thing by following up with:
myGeom.addVertex(1) #BEWAAAAAAARE
This will force indexing, and subsequently cause roughly 3000000 assertion errors to trigger. whee. So yeah, if you find a way to order the triangles to the same order as the verticess, you can do larger than 250x250 height maps.
Err, yeah, so the fact that GeomPrimitive doesn’t actually create the index until it’s needed allows you to “work around” this hardware limitation–in OpenGL, for certain drivers, in certain rendering modes. But for the most part, you’re not supposed to do that. You can’t really go beyond 16-bit indexes on current-generation hardware (although some OpenGL drivers will automatically remap this for you). DirectX simply doesn’t allow it.
Really, you’re just not supposed to stuff more than 65536 vertices into a single GeomPrimitive. Even though it works in some limited cases, it’s not optimal. One day this will be supported transparently, especially when there is hardware that can handle it.
The CycleData bit, by the way, is just the standard way that Panda stores data in its classes to implement pipelining–different versions of an object for the different stages of the graphics pipeline visible in different threads (not yet fully implemented). For the most part, you can treat things within a CycleData object as if they are things within the class itself.
David
Actually, you know what? I’m mistaken. DirectX does support more than 16-bit indexes.
So it might be safe to use this feature of Panda. But to do this, you have to explicitly tell your GeomPrimitive that you intend to use 32-bit indexes, like this:
primitive.setIndexType(GeomPrimitive.NTUint32)
Still, strictly speaking, you should not create a GeomPrimitive with more than base.win.getGsg().getMaxVerticesPerPrimitive() different vertices in it; and you should not create a GeomVertexArray with more than base.win.getGsg().getMaxVerticesPerArray() vertices in it. These limits are imposed by your hardware, and they may be different for different cards (or different drivers).
David
Great, thanks guys.
I actually started working on some improvements to the code, mainly for efficiency (in terms of framerate) which happen to include building the mesh out of multiple GeomPrimitive’s anyway. The mesh is so big (I’m now scaling it to 10 or 100 times the size it was in the currently released code, that’s scaling, not increasing the no. of triangles) that it can’t all fit on screen at once, so it is not the most efficient thing to have the whole mesh as one GeomPrimitive, even regardless of this index error.
So, it may be that the current development version I have can handle much larger height maps, I’ll try it sometime.