Terrain Algorithm: PGMM / geoMipTerrain

Oh! Right, the DLL is still compiled for 1.4.0.
I’ll soon compile one for 1.4.1, as soon as I have access to a windows-running PC.

Got it… thanks.

I had already compiled for 1.4.1 so here you go :

heartseed.sf.net/libpgmm.dll

cheers
nl

And it works! Fantastic! Now to play around with it and maybe get some terrain up and running.

I’m having trouble with the getElevation function on PGMM.

It returns a value between 0 and 1. What’s the multiplication factor? Just on gross testing it looks like it’s around 100 but I can’t tell.

Also, Treeform was using an alpha blending function. Is this incorporated into PGMM? If so, what’s the syntax?

Look at your code. You scale the terrain somewhere in the Z, right? If you have set terrain.setSz(100), the multiplication factor is 100.

It’s not yet implemented. I hope to have it in the next version of PGMM, though I need to make a lot of modifications for it.

Thanks. hmm. I may have an issue then.
I’m working on a pathfinding algorithm and combining it with PGMM. I have a example here.

mavasher.p3dp.com/Pathfinding.zip

I use a “gridmap” an image where white space is traversable terrain and black is obstacles/boudaries.
In the example I ask the map for a clear path between two points. For the example’s sake I’ve used the gridmap image as the texture of the terrain so you can see what’s happening. It finds the path and then for testing purposes I draw a series of line segments from the beginning to the end of the path. I have X & Y from my path algorithm, and I query Z from the PGMM object. But as you can see there are times when the linesegment dips into the terrain even though I’ve added 10 units to the linesegment Z height. Also, looking at in meshmode certain places it dips paradoxally- the lineseg object dips down at the exact places where the terrain rises up. Other than these few places it seems to follow the terrain elevation well.

Hmm. The linesegment never is below the terrain here at my pc… Could be that I have the latest unstable version.
Try rendering the terrain bruteforce. To do that, set the LOD factor as high as possible (around 9999 is enough) and the blocksize to 512. See what happens then.

Thanks for writing back. I made the changes you suggested and things improved- but it’s still patchy in some places where the line dips below into the terrain.

Here’s a shot of the paradoxical dipping. Here the line dips into the hill just as the hill goes up.

I’m using the PGMM lib that nl posted for panda ver 1.4.1

Maybe it’s just the build I’m using.

Hmm. This seems to be a build issue indeed.
Perhaps its due to the fact that you’re running on windows, that the MSVC compiler compiles the calculations different than g++? Or it’s just the version?
You can try getting the vc8 project zipfile from the PGMM download site, and replace the .cxx, .h and .I files with the ones from the svn trunk.

I think I got it now. The build was ok. The problem was that I wasn’t converting to heightfield space appropriately. The Y dimension is with respect to the image file not the model.

Ok, I’ve got a new issue I need help with.

I am using the PGMM along with a mouse based picker collision ray. For testing purposes I now just have the picker function place a simple cube model at the point of collision between the mouse picker ray and the terrain. I’m getting an interesting behavior:

The issue is that it seems like there are certain areas of the mesh that aren’t picking up the collisions. In the image I have the cube models show up in those roughly square areas that I’ve marked with the light blue line. The red X shows that I can’t click in that region and have the collision system pick it up.

I think it has something to do with the way the PGMM is broken up into segments- is there a simple way to fix this issue? I haven’t done anything to the mesh, I just call this function

self.terrain.setCollideMask(collisionMASK2)

to make the mesh collidable.

Thanks.

Ah yes, I should’ve put a notice somewhere. I experienced the same error. I think its a bug in Panda3D.
PGMM breaks the terrain up into multiple chunks. When you call terrain.update(), it checks which chunks need to be updated (lower/higher quality), then it updates it. All parameters (texture, shaders, etc) gets copied to the new chunk by Panda3D, except the collision bitmask.
So, every time you call terrain.update(), you have to re-set the bitmask.

Yup, that was it. Thanks for the reply. Works fine now.

Can you clarify the precise nature of the bug? Is there some low-level call being made to copy nodes, which should be copying collision bitmasks but isn’t? Or is there some other problem?

David

Hmm. I just checked the source again and it appears to be just removing the node and then assigning it again:

  368       _blocks[mx][my].remove_node();
  369       _blocks[mx][my]=generate_block(mx,my,level);

Whenever this is done, the bitmask which is set on the parent of all these blocks, is cleared. The texture isn’t. I don’t excactly know whether this is a bug, or me doing something wrong.
Is there perhaps a better way to reassign a node?

Ah. When you assign a bitmask to a parent node, it immediately propagates the assignment down into the leaves. So then when you delete a leaf and add a new one, it doesn’t have the bitmask that you had assigned to the previous leaf.

This is different from changes in state, for instance, assigning a texture to a parent node. These state assignments are made directly to the parent node, and get propagated to the leaves implicitly as the scene is rendered.

The reason this is different is just because of the logistics of the way the collision system works. It is necessary for the collision bitmask to be immediately propagated to the child node.

It is just a bit unfortunate that these two very different operations have somewhat similar interfaces, so it is tricking you into thinking that they should behave very similarly too.

You’ll have to write the code to reapply the appropriate collision bitmask to the new node you create.

David

Does this apply for just the bitmask or also for other parameters?
Is there perhaps a different way to reassign a node than the one I use, or perhaps a way to copy a node’s parameters?

This applies just to the collision mask. The method nodePath.setCollideMask() is different from most of the other NodePath methods, in that it immediately walks the scene graph at the indicated node and below and modifies it in-place. On the other hand, most of the NodePath methods modify only the specified node directly, and allow its children to inherit those properties.

This means that the effects of setCollideMask() do not persist when the children below the root node are changed out. But most other NodePath properties do.

Does your block include any nested nodes, or is it just a leaf node? There is a Panda method called copyAllProperties(), which is supposed to copy all the existing scene graph properties from node A to node B, and would work if your block did not include any children. Except that, looking at the code, it doesn’t appear that this method actually copies the collideMask. It just copies everything else. Oops. I’ll check in a fix for that, but it won’t help you in the short term.

You’ll have to do something like this:

CollideMask mask = _blocks[mx][my].get_collide_mask();
_blocks[mx][my].remove_node();
_blocks[mx][my]=generate_block(mx,my,level);
_blocks[mx][my].set_collide_mask(mask);

David

Thanks for your reply David, I will try your suggestion.