Getting the vertex data from the terrain.

Xpoint

27-05-2006 17:22:17

Ok, I need to get all the vertex data from the terrain, but I still don't understand how to get it... I know that I need to call the "LoadNow" option or something, but what do I need to do next?

I'm breaking my head on this for 2hours now, so I just ask it here.. Sorry if the answer is already somewere on this forum. :roll:

Thanks in advance,
Xpoint.

pfo

28-05-2006 00:10:44

You can only get terrain geometry after its loaded, its best to create a paging landscape delegate when a tile loads (see setOption("addLoadTileListener", ...). To get the geometry, the function is sceneManager.getOption("PageGetTileVertexData_2", ...) or something like that. If you look in the Wiki and search for PLSM2 and Newton, you'll see how they do it to create terrain collision bodies.

Xpoint

28-05-2006 15:46:07

So you mean, I've to call LoadNow, and then receive all the vertex data via the listeners and PageGetTileVertexData_2? Ok I'll try that. :)

Xpoint

29-05-2006 16:12:09

Ok I've a problem loading the terrain. I only need the geometry, and not the textures, scripts and programs. How can I tell PLSM2 to don't load the textures, scripts and programs?

Falagard

29-05-2006 16:26:17

Try setting texture mode to "None" in your terrain config file.

Xpoint

29-05-2006 16:31:13

Doesn't work for me, I still get this error:
-----------------------------------
Details:
-----------------------------------
Error #: 8
Function: ResourceGroupManager::openResource
Description: Cannot locate resource splatting_sand.png in resource group Shared or any other group..
File: d:\sdk\ogrenew\ogremain\src\ogreresourcegroupmanager.cpp
Line: 583
Stack unwinding: <<beginning of stack>>

Is it also possible to set this option in C++? Because I need to send the terrains to the clients (patching system), and they need to use textures ofcourse.

Falagard

29-05-2006 16:48:40

All I know is there's a texture mode called "None" as shown by the file OgrePagingLandScapeTexture_None.h so it *should* work. Perhaps if you have splatting textures set up in the cfg file it still attempts to load them even if your mode is None. Where is that exception occuring?

Regarding doing it in C++ - I'm sure there's a sceneMgr->setOption("TextureMode") setting but it probably only works after you've already loaded your terrain (if you do it before the options in the terrain cfg will probably replace your texturemode anyhow) so I'm guessing you'll need to keep two terrain cfg files, one for server and one for client, or look into the plm2 code and modify it to fit your needs. Again, I'm guessing - perhaps it can already work.

Xpoint

29-05-2006 17:56:39

OgrePagingLandScapeTexture_None.h doesn't exists in the PLSM2 project, so what version do I need? I'm now also using two different configurations for the clients and the server, which works fine. But the None texture mode is not supported so.. I'll try to get the latest version and see if it works then.

Falagard

29-05-2006 18:00:33

I'll try to get the latest version and see if it works then.

Always a good idea ;-)

Xpoint

29-05-2006 21:59:30

Ok now I've problems with the HardwareBufferManager... how to get rid of this?

Falagard

29-05-2006 22:08:52

Provide more info.

Xpoint

29-05-2006 22:18:24

Ok. My server is created in wxWidgets, and uses Ogre for the heightmap loading. This means I create the root, but I don't initialise it (since I don't need a window). Then I create the PLSM2 scene manager, and load the map using the None TextureMode. But there is no instance of HardwareBufferManager, so it crashes when it tries to create the renderables.

How to create the HardwareBufferManager?

Hope this helps. :)

Falagard

29-05-2006 22:29:10

Just create it the same way Ogre's Root.cpp does, and then if there are any other managers you need to create, create them as well. It'll likely take some trial and error.

Xpoint

29-05-2006 22:38:05

Ok, I'll continue with that tommorrow, and then I'll post what I did. :)
Thanks for the quick responses.

Xpoint

29-05-2006 22:44:11

Ok quick thing before I go to sleep: the HardwareBufferManager needs the DirectX or OpenGL plugin to be created. Does this mean I just need to create a dummy HardwareBufferManager class?

Like:
class DummyHardwareBufferManager : public HardwareBufferManager
{
// Blabla...
}

Or is there another way to get past this without initialising the root?

Falagard

29-05-2006 22:49:56

Tuan might be able to answer better than me. I'd think that the paging landscape manager should have (and might have) a way to not create the vertex buffers and only load the height data for collision purposes, etc. which use the raw height data anyhow and not the vertex buffers.

tuan kuranes

30-05-2006 09:22:05

so it crashes when it tries to create the renderables.
It should not try to create renderables.

Did you created a camera ?
If not, perhaps a Pool pre-allocation problem, try to set Renderable Pool to 0, in terrain option config file.

Xpoint

30-05-2006 11:27:48

Ok, I tried to create a camera, didn't work because there was no HardwareBufferManager (assert error). Then I tried to set 'RenderablePool' to 0, but that also didn't work, same error. Is 'RenderablePool' the correct one or do I need to set it else?

tuan kuranes

30-05-2006 11:48:26

sorry, I was meaning that you shouldn't create a camera.
About renderables correct syntax is
MaxNumRenderables=0

Xpoint

30-05-2006 11:54:40

Ok that worked fine, the terrain now gets loaded. :D

But the next thing is, I'm using events to load the collision data from the terrain (using the newton example from the wiki), but the onTileLoaded event never gets called..

This is the code:
// Get the scene manager.
Ogre::SceneManager* pSceneManager = CKernel::getSingleton().getSceneManager();

// Create the listener.
Ogre::PagingLandscapeDelegate* pLoadTileDelegate;
pLoadTileDelegate = new Ogre::PagingLandscapeDelegate();

pLoadTileDelegate->bind(this, &CTerrain::onTileLoaded);
pSceneManager->setOption("addLoadTileListener", pLoadTileDelegate);

// Load the terrain.
pSceneManager->setOption("LoadNow", NULL);

// Remove the listener.
pSceneManager->setOption("removeLoadTileListener", pLoadTileDelegate);
delete pLoadTileDelegate;

Do I need something else?

tuan kuranes

30-05-2006 12:05:31

Tiles are never loaded.

You should use directly heightfield given in page loaded event to build a mesh and feed newton. Check how it is done per tile in renderable::getRawVertexData()

And considering that contributed code, it could really easily go in PagingLandScapePage instead of renderable. It doesn't really use information in Renderable and tiles and does just what I'm telling you to do.

Xpoint

30-05-2006 17:34:51

Ok, the callbacks are working when I change then to pages, but now how do I get the vertex and index data? I see there is a mHeightData variable in the event, but how do I use that?

Hope this is the last question, thanks for all the fast help, this scene manager is absolutly great! :)

pfo

31-05-2006 00:38:45

Basically you want to do something like this:


std::vector<void*> params;
int renderLevel=0;
int pageX = sa.GetInt(3); params.push_back(&pageX);
int pageZ = sa.GetInt(4); params.push_back(&pageZ);
int tileX = sa.GetInt(5); params.push_back(&tileX);
int tileZ = sa.GetInt(6); params.push_back(&tileZ);
params.push_back(&renderLevel);
if (sm->getOption("PageGetTileVertexData_2", &params))
{
int* numVtx=((int*)params[5]);
Vector3* vertices=((Vector3*)params[6]);
IndexData* indexData=((IndexData*)params[7]);
int numPolys = indexData->indexCount / 3;
Ogre::HardwareIndexBufferSharedPtr hwIndexBuffer=indexData->indexBuffer;
size_t indexSize=hwIndexBuffer->getIndexSize();
void* indices=hwIndexBuffer->lock(HardwareBuffer::HBL_READ_ONLY);

assert((indexSize==2) || (indexSize==4));

if (indexSize==2)
{
unsigned short* curIndex=(unsigned short*)indices;
for ( int poly = 0; poly < numPolys; poly++ )
{
// face
vertices[*curIndex]; curIndex++;
vertices[*curIndex]; curIndex++;
vertices[*curIndex]; curIndex++;
}
}
else
{
unsigned int* curIndex=(unsigned int*)indices;
for ( int poly = 0; poly < numPolys; poly++ )
{
// face
vertices[*curIndex]; curIndex++;
vertices[*curIndex]; curIndex++;
vertices[*curIndex]; curIndex++;
}
}

hwIndexBuffer->unlock();
delete[] vertices;
}


Where I marked 'face' in the comment is where you would call NewtonTreeCollisionAddFace

Xpoint

31-05-2006 11:28:38

Problem with that is, is that you also need the tiles for loading the data. I'm already using this system on the client, but on the server this won't work since it requires HardwareIndexBuffer which isn't loaded because HardwareBufferManager isn't created (is this correct?). And I also only load the pages, not the tiles since these are never loaded when you use setOption("LoadNow", NULL).

tuan kuranes

31-05-2006 12:07:40

You have to build indexdata & vertexdata from mHeightData, using the code in paginglandscaperenderable getRawVertexData and getRawIndexData as inspirationnal sample code.

Xpoint

01-06-2006 16:52:06

Ok, I think I got it now, since I got 4 collision files of 34mb each. :P

But now, in the client when I run it in debug mode, everything goes fine when a terrain is loaded. But when I run it in release mode I get an assertion failed error. The error is in OgrePagingLandScapePageManager.cpp at line 617. The code on that line is:
assert (p && !p->isLoaded ());
So I think p is NULL, but why? Why is it NULL in release mode, and not in debug mode?

There is absolutly no difference in debug and release mode, only the dll's are different (release versions ofcourse :wink: ).

tuan kuranes

01-06-2006 17:18:54

Why is it NULL in release mode, and not in debug mode
Could be a speed difference that make a bug apperas or a memory corruption is much more dangerous in release mode and lead easily to segfault.
Can you make sure p is null (split that assert in two assert one for nullity one for not loaded check)

Xpoint

01-06-2006 17:59:53

Ok, I've split the assert and it says that p is null. Anything else I can do to debug it? Since I've no idea what could be wrong here...

tuan kuranes

02-06-2006 09:11:49

if p is null, it leads to the memory corruption other than else (debug vs release difference.). Can you try to debug release mode and see why a not empty queue returns a null p ?

Xpoint

02-06-2006 11:42:13

Will do that asap. But if I won't do it today, I will to it next week, because I'm not home this weekend.