[bleeding]terrain from heightmap

Dutchie

06-04-2008 20:46:46

i want to create a terrain with bleeding, but what i've found is that you cannot do it from a heightmap image anymore but have to convert it with flour. I can do that ofcourse, but how do i have to create the terrain than exactly?

betajaen

06-04-2008 20:59:32

Well assuming you've created a saved heightfield (xhf) using flour; you can use the wave.raw to get you started; otherwise create your image in Photoshop or GIMP and save it as a RAW. Make sure the width/height is a power of two (otherwise flour will complain; whilst it is trying to work out the width/height for you).

Load in the heightfield into the resource system:

Resources::ResourceSystem::getSingleton()->addHeightfieldAs("file://wave.raw.xhf", "wave");

Get a copy of the heightfield:

Resources::Heightfield* hf = Resources::ResourceSystem::getSingleton()->getHeightfield("wave");

Then use it in a Terrain (shape):

mScene->createActor("Trotters", new Terrain(hf, float3(128,4,128), "", "centering: xz-above, hole-material: 65535"), Ogre::Vector3(64, 0, 64), "static: yes");

Done.

Dutchie

07-04-2008 10:25:18

thanks, i will look into that...
is it btw even possible to create convex or triangle shapes without using flour? using the old way.
because if i have to convert all the meshes it will take me much much time because i (will) have many models

betajaen

07-04-2008 10:26:48

Sadly not. Unless you want to write the code to do it in your application.

It's better to have the meshes cook "offline", your application start up is quicker, and you don't have slow downs in frames when you want to load and cook something into the Scene.

Dutchie

07-04-2008 10:34:50

hmmm... now im thinking of going back to 0.9 (please keep it online) because converting hundreds of meshes will really take too long. And i only load them in a loading screen, so the loading of the level will just be a little bit longer, which is not really an issue.

betajaen

07-04-2008 11:05:32

You know that's the most silliest thing I've heard. All computer games that use Physics, or require some sort of conversion to one format to an other do it offline. They don't do it in the game - it just takes far to long even with loading screens.

It would take you ten minutes to write or find a DOS batch script that will execute flour each time with a different filename in that directory.

Dutchie

07-04-2008 12:13:20

that is true... i will do it with a batch file. didn't think about that.

thanks for your help.

DanielH

07-04-2008 16:05:25

Even if that may be true for a release version, in debug it's really nice to let NxOgre do it at runtime. The meshes might be updating quite a lot and doing the cooking is a bit annoying when you are just trying things out :P I don't fully understand the design dession to make NxOgre indepdendant of Ogre. I liked how it worked in 0.9.

betajaen

07-04-2008 17:05:24

Because I want NxOgre to be independent of NxOgre; allowing it to be used in other Rendering systems. For it to work; things have to be cut out.

DanielH

07-04-2008 18:04:56

I've been trying to create the heightfield manually with ManualHeightfield with no success. My code is here below.


esources::Heightfield* GameApplication::createHeightfield(const std::string& heightmap)
{
Ogre::Image img;
img.load(heightmap, "General");

int w = img.getWidth();
int h = img.getHeight();

Resources::ManualHeightfield mh;
// Nothing of the below helps
//mh.setDefaultMaterial0((NxMaterialIndex)0);
//mh.setDefaultMaterial1((NxMaterialIndex)0);
// Setting both vertical extent and thickness makes the app crash (NxHeightmap creation fails)
//mh.setVerticalExtent(1.0f);
//mh.setThickness(1.0f);
mh.begin(w, h);

// Tesselation direction
bool tessltr = false;
for (int y = 0; y < h; ++y) {
for (int x = 0; x < w; ++x) {
short height = static_cast<short>(img.getColourAt(x, y, 0).r * 65536 - 32768);
mh.sample(height, tessltr);
}
tessltr = !tessltr;
}

return mh.end(true);
}



Actual creation:

ShapeParams sp;
sp.setToDefault();
sp.mFlags = 0;//NX_SF_VISUALIZATION;

TerrainParams tp;
tp.setToDefault();
tp.mFlags.mVisualiseTerrain = true;

Resources::Heightfield* hf = createHeightfield("terrain_heightmap.png");
m_scene->createActor("TerrainActor", new NxOgre::Terrain(hf, float3(100.0f, 10.0f, 100.0f), sp, tp),
NxVec3(0, -10, 0), "static: yes");


I can see the bounding box in Remote Debugger, but not the actual terrain and nothing collides against it.

If i set both thickness and vertical extent the NxHeightField object creation fails.

betajaen

07-04-2008 18:27:52

Roughly:

NxOgre::Resources::ManualHeightfield* mhf = new NxOgre::Resources::ManualHeightfield();
mhf->begin(image_width, image_height);

for each_pixel {
int c = getPixelRedColour();
int t = (c * 256) - (32768);
height = short(t);
mhf->sample(height);
}

NxOgre::Resources::Heightfield* hf = mhf->end();


Thickness have to be negative and vertical extent is deprecated in PhysX.

betajaen

07-04-2008 18:53:03

For those who want to use 16-bit images, or want to use negative value terrain. I've written this page for the formula I use in Flour to convert the RAW images to.

DanielH

07-04-2008 19:09:13

Sorry still the same result. Even if i set height = 0 and try it it becomes the same. I've uncommented the vertical extent and tried different values for thickness but it doesn't seem to matter at all.

betajaen

07-04-2008 19:36:48

Try my code:

// Create a ManualHeightfield, it's like the Ogre's ManualObject.
Resources::ManualHeightfield* manual_hf = new Resources::ManualHeightfield();

// Make the terrain 16 x 16 rows and columns - length isn't defined here,
// a unit may be a centimetre to a kilometre.
unsigned int mx = 16, my = 16;

manual_hf->begin(mx,my);
// I want the terrain quads to switch direction every other row, so I need
// a bool.
bool tesselate_tl2br = false;

for (unsigned int x = 0; x < mx;x++) {
for (unsigned int y = 0;y < my;y++) {

// Calculate the height. Which varies from -32768 to 32768 units.
short height = -32768 + (y * (65536 / my));

// Add my height sample with some tesselation.
manual_hf->sample(height, tesselate_tl2br);
}
// Switch rows.
tesselate_tl2br = !tesselate_tl2br;
}

// Set the height thickness to 1.0 metre
manual_hf->setThickness(-1.0);

// And turn this into an actual Heightfield we can use.
Resources::Heightfield* hf = manual_hf->end();
hf->save("file://test.xhf");

// Finished with the Manual Heightfield
delete manual_hf;


Also remember about the hole material. PhysX makes it zero by default for some reason.

mScene->createActor("Trotters", new Terrain(hf, float3(128,4,128), "", "centering: xz-above, hole-material: 65535"), Ogre::Vector3(64, 0, 64), "static: yes");

DanielH

07-04-2008 20:36:42

The problem was that I hadn't set a hole material. Thats a pretty odd behavior ;)

Not sure if this is intended, but when I use a standard terrain in Ogre with maxheight = 100, I need to use the following scales and translation to make the heightfield fit with the graphics:


m_scene->createActor("TerrainActor", new NxOgre::Terrain(hf, float3(1500, 50, 1500), sp, tp),
NxVec3(0, 50, 0), "static: yes");


It would be more logical if it was float3(1500, 50, 1500).

Dutchie

11-04-2008 10:06:54

Betajaen, i have problems... again...

i get an unresolved external symbol:
2>BladeEngine.lib(BladeTerrain.obj) : error LNK2001: unresolved external symbol "public: __thiscall NxOgre::Terrain::Terrain(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class Ogre::Vector3,class NxOgre::ShapeParams const &,class NxOgre::TerrainParams const &)" (??0Terrain@NxOgre@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@VVector3@Ogre@@ABVShapeParams@1@ABVTerrainParams@1@@Z)

when adding this code:
NxOgre::Resources::ResourceSystem::getSingleton()->addHeightfield("file://media/terrain/terrain.xhf");
act = DarkEngine->getNxScene()->createActor("Actor"+name, new NxOgre::Terrain("media/terrain/terrain.xhf", NxOgre::float3(500,60,500), "", "centering: xz-above, hole-material: 65535"), Ogre::Vector3::ZERO, "static: yes");



using the same way/code it worked from my other topic, but now with terrain...

betajaen

11-04-2008 10:15:03

Yep. Missing function. For now you'll have to get the heightfield pointer directly and use that. It's demonstrated by me in the previous page.

Dutchie

11-04-2008 12:03:49

Ok, done that now... but... still having problems.

If i load the terrain:
NxOgre::Resources::ResourceSystem::getSingleton()->addHeightfieldAs("file://media/terrain/terrain.xhf");
NxOgre::Resources::Heightfield* hf = NxOgre::Resources::ResourceSystem::getSingleton()->getHeightfield("media/terrain/terrain.xhf");
act = DarkEngine->getNxScene()->createActor("ATerrain", new NxOgre::Terrain(hf, NxOgre::float3(500,60,500), "", "centering: xz-above, hole-material: 65535"), Ogre::Vector3::ZERO, "static: yes");


The RemoteDebugger from the PhysX SDK crashes... but the app continues to run


and in Ogre itself when i insert a body:
NxOgre::Resources::ResourceSystem::getSingleton()->addMesh("file://triangle/cube.1m.mesh.nxs");
NxOgre::Body *MyBody = NxScene->createBody("Cube;cube.1m.mesh", new NxOgre::Cube(1), Ogre::Vector3(175, 200, 260), "mass: 10");


i see it falling(also in RemoteDebugger) but it goes trough everything...

betajaen

11-04-2008 12:08:42

Make the terrain static.

Dutchie

11-04-2008 12:14:25

the terrain is static, the lowest code is to create a body that falls trough everyhing. which isn't supposed to be....

Dutchie

11-04-2008 18:34:30

still got problems with the terrains...

RemoteDebugger doesn't crash anymore... the hole-material: 65535 was the problem...
In remote debugger i don't see the terrain, but in the Ogre scene i see the axis(by using: world->createDebugRenderer()).

The cube falls trough everything...

Dutchie

13-04-2008 12:27:02

betajaen, do you know anything to fix thse problems?

DanielH

13-04-2008 12:40:33

Did you try to show everything in the remote debugger? Bounding boxes etc... If you don't see anything in the remote debugger it is not there.

Are you sure your pre-baked heightmap is loaded correctly? Have you tried to load the heightmap manually with the code on the previous page?

Dutchie

13-04-2008 12:48:30

I am not sure the terrain is loaded, because in the RemoteDebugger i can't see him. But in the Ogre world is see his axis(when CreateDebugRenderer is called)...

I create the terrain with this code:
NxOgre::Resources::ResourceSystem::getSingleton()->addHeightfield("file://media/terrain/terrain.xhf");
NxOgre::Resources::Heightfield* hf = NxOgre::Resources::ResourceSystem::getSingleton()->getHeightfield("media/terrain/terrain.xhf");
act = DarkEngine->getNxScene()->createActor("TerrainName", new NxOgre::Terrain(hf, NxOgre::float3(500,60,500), "", "centering: xz-above"), Ogre::Vector3::ZERO, "static: yes");

the xhf file is an terrain file created using flour.



I am creating city walls with max, converted them to ogre and with flour converted to a triangle mesh. When adding these to the game i DO see them in the remoteDebugger like they should.

than i am creating a body for a cube with mass 10:
NxOgre::Body *MyBody = NxScene->createBody("Cube;cube.1m.mesh", new NxOgre::Cube(1), Ogre::Vector3(175, 200, 260), "mass: 10");

I DO see this one in DebugRenderer but i goes trough the city walls i made.


When letting the scene create a floor the cube does NOT fall trough the floor.

another thing: if I add hole-material to the Terrain parameters the debugrenderer crashes.

betajaen

13-04-2008 13:05:16

By it crashing when you add the hole-material means it's working or at least about to work.

Turn on debug rendering and see if cube enters the bounding box of the terrain shape.

Dutchie

13-04-2008 13:09:39

oh, you have bounding boxes in debugrenderer too... i don't see bounding boxes for both the terrain and the triangle meshes(the walls), but i do see bounding boxes for the cube.

betajaen

13-04-2008 13:15:16

No bounding box; with a hole-material?

Dutchie

13-04-2008 13:19:41

with AND without the hole-material i don't see any bounding box for the terrain...
and as told before i also don't see bounding boxes for the city wall.

Dutchie

13-04-2008 16:08:10

i am a bit further...

Changed the height values of the terrain in NxOgre... i had the height = 60, but in the terrain file it is 255. so the nxOgre height is also 255 now.

The blocks seem to fall on something, that had a bit of the form of my terrain. But it doesn't fall how my terrain is.

another thing i noticed:
with flour when i put in a 1024x1024 16bit RAW image it says the image is 1024x1024 and when i put in the same image but than 8 bit, the outcomming xhf is 2x smaller(2mb instead of 4mb). But flour says the image is 724x724 and it thinks it is 16bit and in Ogre itself the NxOgre terrains seem to stop earlier(in XZ, in height it is totally wrong on both) than the 16bit terrain...


without the hole-material the terrain doesn't seem to exist, which is supposed to be so i think, but the RemoteDebugger crashes.

and again, with DebugRenderer in ogre i don't see the bounding boxes of the terrain and the city walls(where the blocks also fall through)

Dutchie

13-04-2008 19:18:33

converted for a test to 0.9 NxOgre... there the terrains works perfectly. But the cubes fall trough the city walls when using trianglemesh. so the problem is either the triangleMesh in NxOgre or just the triangleMesh in PhysX itself.

FriedChicken

17-04-2008 13:09:27

with flour when i put in a 1024x1024 16bit RAW image it says the image is 1024x1024 and when i put in the same image but than 8 bit, the outcomming xhf is 2x smaller(2mb instead of 4mb). But flour says the image is 724x724 and it thinks it is 16bit and in Ogre itself the NxOgre terrains seem to stop earlier(in XZ, in height it is totally wrong on both) than the 16bit terrain...

I got the same problem! And the result is that the collision model does fit with graphical model at all !

FriedChicken

17-04-2008 13:21:20

I complie Bleeding whith PhysX SDK 2.7.3. Could it generate this problem?

betajaen

17-04-2008 13:39:37

No. It should be. I'll release a new copy of flour that allows you specify width/height of the image.

FriedChicken

18-04-2008 05:51:22

Is there any one who successfully add terrain collision model with Bleeding ?

FriedChicken

18-04-2008 07:42:55

I notice that although I create body with position property set,

Body* body = mScene->createBody("cube", new Cube(5), Vector3(0, 0, 0), "model: cube.1m.mesh, scale: 5 5 5, position:200 100 280", "mass: 10");

I have to reset the global position manually for each body.

body->setGlobalPosition(...)

But the cube still collide with the terrain incollectly, although it seem to fall on something.

Netskate

16-09-2008 21:53:11

I have the same problem, can't see the terrain in visual remote debugger.

and my cube shape fall through the terrain. In some place it was block by my terrain actor (that not fit the real terrain, seems to be lower), in other place it didn't be stopped by terrain.

a thingh that I note, if I load you hftest.raw and convert it with flour, I can see it in visual remote debugger, and I can see also cube roll because your image is a gradient, a sort of inverted pyramid.

I've tried to convert a lot of raw images with any results, I'm completely stuck...