[BloodyMess 1.5.4] Heightfield problems

zzDuskzz

03-07-2009 22:47:50

ok, i have two problems with terrain generated from image
my image is 16bit, and my terrarian don't smooth, it's look's like created from 8bit image
here's screens
http://picasaweb.google.com/lh/photo/Mu ... directlink
http://picasaweb.google.com/lh/photo/1R ... directlink
///-----------------------
and second problem my terrain has flipped axes
so look, zero coordinate is in left up, camera on same position
http://picasaweb.google.com/lh/photo/-m ... directlink
http://picasaweb.google.com/lh/photo/-4 ... directlink



sorry for bad English

betajaen

03-07-2009 22:53:59

Upgrade to 1.5.5

spacegaier

03-07-2009 22:55:51

Can't say anything to the first issue so far. However, the second one is caused by a bug in 1.5.4 and was solved with the version 1.5.5 (patch is in one of the recent HeightField threads).

zzDuskzz

04-07-2009 02:26:19

i install the 1.5.5unstable. and still no luck - heightfield flipped and looks wrost

Pans

16-07-2009 23:42:17

I can't see your pictures, zzDuskzz, but I've got a good illustration of a heightfield problem (could be yours, no idea). I also applied the patch suggested in that other recent heightfield thread, though maybe it didn't stick. Here's the issue:

Here's my heightmap, converted to RAW and entered into terrain.cfg as a .png.


I ran the .raw through flour with
flour convert in:terrain.raw, into:heightfield, out:terrain.xhf, width:513, height:513
Here's the result:


Something's switched. I run the physics heightmap back through GIMP by flipping it vertically and rotating clockwise (essentially, reflecting across y=-x), but I keep the original .png from above for Ogre's heightmap:


Here's the result (the way it's supposed to be)


It works perfectly, too, here's a shot of me on the "ground" (I'm the sphere):


I'm not sure if this is what was fixed by the patch in that other thread, but I applied it and recompiled, and moved the new DLLs in and all that. Once I get a chance, I'll throw together a patch (unless someone beats me to it, probably can't get to it til Saturday). I should be a very easy fix.

Edit: Here's the relevant code chunk, thought someone might find it useful:

mSceneMgr->setWorldGeometry( "terrain.cfg" );
ResourceSystem::getSingleton()->openArchive("media", "file:C:/OgreSDK/media/materials/textures/");
HeightField* hf = HeightFieldManager::getSingleton()->load("media:terrain.xhf");

HeightFieldGeometry* hfg = new HeightFieldGeometry(hf, Real3(1500,50,1500));
hfg->setLocalPose(Matrix44(Real3(0,50,0)));
mScene->createSceneGeometry(hfg);

betajaen

17-07-2009 00:16:36

Looking good.

A slight fragment of my memory has surfaced; regarding the flipping of the image. I remember doing something similar when I was experimenting with heightfields/flour for the first time.

Pans

17-07-2009 04:22:54

Looking good.

A slight fragment of my memory has surfaced; regarding the flipping of the image. I remember doing something similar when I was experimenting with heightfields/flour for the first time.


Is it an issue with flour flipping the heightmap around, or is it in NxOgreHeightfieldGeometry.cpp? Though I guess the difference isn't very meaningful, since heightmaps of type xhf are only coming from flour, I guess.

betajaen

17-07-2009 11:40:10

No. Flour reads the file forwards as it should be. The "xhf" file format is really simple, it's just the red channel of the image, prefixed with some header stuff and future bits about materials. PhysX doesn't have serialisation of heightfields, so I had to write my own. Using XHF, means I only have to worry about one type and one version of a file, when quickly cooking the heightfield on the spot.

But Photoshop and gimp write raw images written upside down; the blame is on the visualisation. If someone wants to try it using ETM, or another terrain system, I would expect the extra process of flipping the image isn't necessary.

Pans

18-07-2009 21:49:11

No. Flour reads the file forwards as it should be. The "xhf" file format is really simple, it's just the red channel of the image, prefixed with some header stuff and future bits about materials. PhysX doesn't have serialisation of heightfields, so I had to write my own. Using XHF, means I only have to worry about one type and one version of a file, when quickly cooking the heightfield on the spot.

But Photoshop and gimp write raw images written upside down; the blame is on the visualisation. If someone wants to try it using ETM, or another terrain system, I would expect the extra process of flipping the image isn't necessary.


In that case, I'll try implementing the Editable Terrain Manager next to see if it's an issue there as well. If so, wouldn't the fix be as simple as swapping 'x' and 'z' in the constructor in the aforementioned .cpp file?

betajaen

18-07-2009 22:03:04

You could just rotate the StaticGeometry.

Pans

18-07-2009 22:46:50

You could just rotate the StaticGeometry.

It seems to me to be a mirroring problem, not a rotational issue... e.g. the heightmap is mirrored about y=x, if you consider the top left as the origin, going right is +x and going down is +y. In which case, x and y are simply swapped.

Edit: Nevermind, it's the right one. Going to try to switch x and y.

Pans

19-07-2009 00:47:47

OK, I created a minor patch for NxOgreHeightField.cpp, in the code for HeighField::load(). Here's what it usually says:

for (unsigned int i=0; i < wh; i++)
{
HeightFieldSample sample;
resource->readCharArray( (char*) &sample, sizeof(NxHeightFieldSample));
heightfield.sample(sample);
}


I changed it to

HeightFieldSample *mSample = new HeightFieldSample[wh];
for (unsigned int i=0; i < nbRows; i++)
for (unsigned int j=0; j < nbColumns; j++)
resource->readCharArray( (char*) &mSample[j*nbRows + i], sizeof(NxHeightFieldSample));

for (unsigned int i=0; i < wh; i++)
{
heightfield.sample(mSample[i]);
}


Which basically just goes through and turns rows into columns. But, I guess this is only to get things working within the typical Ogre terrain scene manager's heightfield creation, and could also just be changed around in flour if it was at all valuable. It was more that I just wanted to see if I could create this, since I had gotten so far into illustrating an issue I was having :D

betajaen

19-07-2009 00:53:06

Interesting patch.

However; I can't put it in. Your assuming every user of NxOgre that uses the heightfield will use the Ogre heightfield system. Considering there are many other heightfields systems, and Bloody Mess doesn't even need to work with Ogre anymore (the whole anonymous rendersystem thing), the patch is incredibly specific.

If you can rewrite the patch - so it allows multiple types of angles (+90, +180, -90, -180) and flipping horizontally and vertically of the xhf file, then I'll put it in.

Pans

19-07-2009 00:58:31

Interesting patch.

However; I can't put it in. Your assuming every user of NxOgre that uses the heightfield will use the Ogre heightfield system. Considering there are many other heightfields systems, and Bloody Mess doesn't even need to work with Ogre anymore (the whole anonymous rendersystem thing), the patch is incredibly specific.

If you can rewrite the patch - so it allows multiple types of angles (+90, +180, -90, -180) and flipping horizontally and vertically of the xhf file, then I'll put it in.


No, I understand, it's primarily for my own use untli I get rid of the default Ogre heightfield system. I'll see what I can do with those other functions, though--I think that would certainly help with matching up any heightfield system with NxOgre.

Pans

19-07-2009 02:40:38

After a little bit of research, adding those extra functions in might be duplicating functionality. HeightFieldGeometry::setLocalPose(), since it's a 4x4 matrix, should be able to perform any sort of rotation or reflection. I'll test to see if the proper 4x4 transformation indeed does what I think it does, but do you think it would be valuable to add an extra function to simplify this process without an individual needing to create their own 4x4? I'm thinking something like rotateHeightfield(int) and reflectHeightfield(bool).

Edit: Once again, after a little bit more digging, it turns out I didn't really understand what 4x4 pose matrices did... but it looks like can't be used for reflection. Can you shine a little bit of light on what they do exactly? I guess the better question is, why does NxOgre use 4x4 matrices if PhysX is using 3x4's for its poses (which uses 3x3 for rotation and 3x1 for translation... as far as I can tell, anyway).

betajaen

19-07-2009 12:41:17

Edit: Once again, after a little bit more digging, it turns out I didn't really understand what 4x4 pose matrices did... but it looks like can't be used for reflection. Can you shine a little bit of light on what they do exactly? I guess the better question is, why does NxOgre use 4x4 matrices if PhysX is using 3x4's for its poses (which uses 3x3 for rotation and 3x1 for translation... as far as I can tell, anyway).

When designing the pose matrix instead of using the 3x4 (which is a wrapped NxVec3 and NxMat33). Although it could have a scalar component there is no way of transforming that into a NxMat34 (or infact into other parts of PhysX), so it was pointless to implement.

If I remember correctly; I went with a 4x4 matrix due to many reasons including Ogre which also uses 4x4 matrixes. The matrix is mostly used going "out" of NxOgre, than going in, so I thought it would be faster to use a memcpy or a static_cast into a Matrix4 rather than dealing with a horrid mess of a 3x4 matrix (which Ogre doesn't support).


I would implement flipping it through a different route; upgrade flour to flip horiziontaly/vertically the heightfield mesh via a command-line param.