Page 4 of 28
Re: New Terrain Early Shots
Posted: Wed Jun 24, 2009 11:04 am
by stealth977
sinbad wrote:
The reason I went for raw floats for the heights is that I didn't want to limit the core to a set precision (like 8- or 16-bit). This way, the min/max of the terrain is unbounded (well, within reason), meaning it's a lot more flexible - it can accurately represent terrains that would be impossible to store in even a 16-bit PNG without data loss. I allowed for importing from lower-precision sources but when saving, the full float data is the only lossless way - even exporting to 16-bit PNG will lose some precision. If people want to process the data in external tools then you can provide export functions in your editor, but you'd have to accept that precision loss unless you use a float format. I didn't include an export to PNG or similar because I didn't really want to encourage this, preferring to advocate a 1-way conversion from these 'lesser' formats.
Thats exactly what i meant with my post, i wrote that post just to share the implementation experience with other members of the community so that they can have a much clearer image of implementation on their mind.
- In my implementation i use float arrays so height data doesnt loose precision (which is very important especially when you start placing objects on the terrain, you wouldnt want the terrain to erode due to lossy conversion ) and most of the professional apps can read from a float array.
- Since the blend maps have an internal format of UINT8, L8 PNG files are perfect candidates for saving them, although saving them individually creates an assets mess, its much more compatible for editing in other editing programs...
- And of course when it comes to exporting, options can be supplied to export in:
* Native StreamSerializer based packed format
* 16 bit PNG files for heightmap
* 3 or 4 channel packed PNG files for layers...
ismail,
Re: New Terrain Early Shots
Posted: Wed Jun 24, 2009 10:45 pm
by avalanche_raptor
Looking Great!!

Added the inherant paging support, this would open up a wide range of possibilities!
Jus wanted to know.... When will we be able to get our hands on this..... I mean is the svn head stable enough to use right now? or would you reccomend waiting for a stable version??
Thanks

Re: New Terrain Early Shots
Posted: Thu Jun 25, 2009 12:39 am
by KungFooMasta
I was looking more at the Terrain interface, how its used, and I saw this:
Code: Select all
/// Save terrain data in native form
void save(StreamSerialiser& stream);
I'm trying to figure out what the data looks like in "native" form, but I haven't made use of Ogre's Stream classes before. The Constructor for a StreamSerialiser takes a DataStreamPtr... how can I simply write this data to a text file?
Also, what exactly is a Layer? Its like a material pass, that can support up to X number of Textures? What does the "WorldSize" of the Layer mean?
Re: New Terrain Early Shots
Posted: Thu Jun 25, 2009 5:29 am
by stealth977
KungFooMasta wrote:I was looking more at the Terrain interface, how its used, and I saw this:
Code: Select all
/// Save terrain data in native form
void save(StreamSerialiser& stream);
I'm trying to figure out what the data looks like in "native" form, but I haven't made use of Ogre's Stream classes before. The Constructor for a StreamSerialiser takes a DataStreamPtr... how can I simply write this data to a text file?
Also, what exactly is a Layer? Its like a material pass, that can support up to X number of Textures? What does the "WorldSize" of the Layer mean?
1 - Terrain saving is a binary format
2 - A Layer is same as Photoshop layers, the difference is, it may have more than 1 textures defining different aspects of it, in current implementation (DefaultMaterialGenerator) a layer has a DIFFUSE and a NORMAL texture, and there can be 6 Layers total in a MATERIAL PASS.
3 - The WorldSize of a Layer defines how many times this Layer is repeated on the terrain:
Lets say your Terrain has a WorldSize of 4000 units
And you define a Layer, with WorldSize 100 units
it means the Layer will be repeated every 100 units = will have a Texture repeat count of 40 (TerrainWorldSize / LayerWorldSize)
You remember problems during using ETM? Each layer had a fixed repeat count which you couldnt change, in Ogre::Terrain you can define the repeat count (by using WorldSize) so each layer can repeat at different scales...
ismail,
Re: New Terrain Early Shots
Posted: Thu Jun 25, 2009 10:58 am
by CABAListic
You remember problems during using ETM? Each layer had a fixed repeat count which you couldnt change, in Ogre::Terrain you can define the repeat count (by using WorldSize) so each layer can repeat at different scales...
Technically you could, since this is just a shader property. My example shaders used single repeat parameters for all layers, but you could just as easily have defined multiple

But if the new Terrain components makes it easier, all the better - only reassures me that it was a good idea to retire ETL in favour of the new Terrain component.
Re: New Terrain Early Shots
Posted: Thu Jun 25, 2009 11:24 am
by stealth977
CABAListic wrote:
Technically you could, since this is just a shader property. My example shaders used single repeat parameters for all layers, but you could just as easily have defined multiple

But if the new Terrain components makes it easier, all the better - only reassures me that it was a good idea to retire ETL in favour of the new Terrain component.
Well, it was just an example meaning ETM/ETL didnt have functions to set texture repeat counts

No offense intended
ismail,
Re: New Terrain Early Shots
Posted: Thu Jun 25, 2009 12:33 pm
by sinbad
avalanche_raptor wrote:Jus wanted to know.... When will we be able to get our hands on this..... I mean is the svn head stable enough to use right now? or would you reccomend waiting for a stable version??
SVN trunk works in a limited way right now, there are still bugs and unfinished aspects, so it's a 'use at your own risk' kind of situation for the moment. I'm going to stop giving estimates about when it's ready since I keep missing them, but I will be working on it as much as I can around my other commitments.
KungFooMasta wrote:I'm trying to figure out what the data looks like in "native" form, but I haven't made use of Ogre's Stream classes before. The Constructor for a StreamSerialiser takes a DataStreamPtr... how can I simply write this data to a text file?
StreamSerialiser is a chunk-based, binary formatter. Basically it does the same kind of thing as the MeshSerializer et al, which write binary chunks too, but it's considerably easier to use and can also operate on shared streams - so you could have a stream of data that includes data for multiple objects, or embed the terrain data in your own binary file format. This is essential for the paging system where a page data file may interleave many types of content that only subclasses can understand.
stealth977 wrote:in current implementation (DefaultMaterialGenerator) a layer has a DIFFUSE and a NORMAL texture, and there can be 6 Layers total in a MATERIAL PASS.
Slight clarification - each layer actually uses 2 sampler units per layer, but in fact together they pack diffuse, specular, normal and height information, with specular in the alpha channel of the diffuse texture, and height in the alpha channel of the normal texture. You can use Image::loadTwoImagesAsRGBA to do this combination (I saved mine out as PNG after that and then compressed them with DXT5).
Re: New Terrain Early Shots
Posted: Thu Jun 25, 2009 6:52 pm
by KungFooMasta
Code: Select all
/// List of texture names to import; must match with TerrainLayerDeclaration
StringVector textureNames;
This kind of suggests a layer can have more than 1 texture assigned to it. By 2 sampler units, does this mean we can have 2 textures per layer? Or am I totally confused?
Also, it seems like the binary file will be the most used format? As stealth mentioned, png's have limits in their values, 8bit or 16bit, but the inputScale field allows you to stretch png data out vertically to make the terrain match any 3d world height. In an editor application users would be able to deform terrain to exceed the limits of 8/16 bit png, in which case the data can only be stored/reloaded properly if its in binary format. Is this right?
Is anybody familiar with data streams and can throw out some reference code? I'm familiar with the Mesh/MaterialSerializer, but those have APIs that make everything super simple, ie:
Code: Select all
void exportMesh (const Mesh *pMesh, const String &filename, Endian endianMode=ENDIAN_NATIVE)
In my case I would want to have my binary files not embedded within other files, ie MyTerrain.terrain
Last question, is there a process for creating mutliple terrain pages? I've looked at the Terrain class and haven't seen anything that would allow me to create paged terrain. It actually looks like the Terrain class can be created several times. I doubt creating multiple Terrain instances would be the way to go, right? (There is no enforcement of size)
[edit] I think I partially understand the question I have about layers. Users can define their own layer declarations which might use a number of textures, and the layer needs to match the declaration. [/edit]
Re: New Terrain Early Shots
Posted: Thu Jun 25, 2009 9:01 pm
by stealth977
KungFooMasta wrote:
Last question, is there a process for creating mutliple terrain pages? I've looked at the Terrain class and haven't seen anything that would allow me to create paged terrain. It actually looks like the Terrain class can be created several times. I doubt creating multiple Terrain instances would be the way to go, right? (There is no enforcement of size)
In theory you can create a very big terrain with one terrain instance, like for example 16kX16k and it would probably handle it very nice. But to take advantage of paging, you will create multiple instances of the terrain with smaller page sizes, then connect them with the Paging component using paging strategies, so that only required instances (those are in the frustum) will be loaded and rendered at a time (but thats not ready yet).
ismail,
Re: New Terrain Early Shots
Posted: Thu Jun 25, 2009 11:56 pm
by stormfornever
Why parralax map when you can you use ConeStepMap ?
ConeStepMap did not work better and more MORE MOOOORE FASTER ?
Re: New Terrain Early Shots
Posted: Fri Jun 26, 2009 11:23 am
by sinbad
KungFooMasta wrote:Code: Select all
/// List of texture names to import; must match with TerrainLayerDeclaration
StringVector textureNames;
This kind of suggests a layer can have more than 1 texture assigned to it. By 2 sampler units, does this mean we can have 2 textures per layer? Or am I totally confused?
Yes, this is so that you can have diffuse, normal, specular, height etc elements from multiple textures for one layer. As I said above, the default material generator uses 2 textures per layer, a packed diffuse/specular texture and a packed normal/height texture.
Also, it seems like the binary file will be the most used format? As stealth mentioned, png's have limits in their values, 8bit or 16bit, but the inputScale field allows you to stretch png data out vertically to make the terrain match any 3d world height. In an editor application users would be able to deform terrain to exceed the limits of 8/16 bit png, in which case the data can only be stored/reloaded properly if its in binary format. Is this right?
Correct. Or, you can export the data into your own format if you like, the full precision float data is there for you to access and you can feed floats directly into the terrain prepare() call.
Is anybody familiar with data streams and can throw out some reference code? I'm familiar with the Mesh/MaterialSerializer, but those have APIs that make everything super simple, ie:
Code: Select all
DataStreamPtr stream;
// set up stream
StreamSerialiser ss(stream);
mTerrain->save(ss);
'set up stream' can be anything that results in a writeable stream. E.g.
Code: Select all
stream = myArchive->create(filename);
Code: Select all
stream = ResourceGroupManager::getSingleton().createResource(filename);
// (check out the optional parameters to be more specific about where the file is created)
Code: Select all
std::fstream fstr(filename, std::ios::out|std::ios::binary);
stream = DataStreamPtr(OGRE_NEW FileStreamDataStream(&fstr, false));
Code: Select all
FILE* fp = fopen(filename, "wb");
stream = DataStreamPtr(OGRE_NEW FileHandleDataStream(fp));
Next time don't PM me the same question please, I don't like repeating myself

But, I've added more detail here.
Re: New Terrain Early Shots
Posted: Fri Jun 26, 2009 11:32 am
by sinbad
stormfornever wrote:Why parralax map when you can you use ConeStepMap ?
ConeStepMap did not work better and more MORE MOOOORE FASTER ?
Simple - because it's more expensive, by a factor of a minimum of 4 (worst quality). You can choose to add it if you want, I think it's overkill for terrain.
Re: New Terrain Early Shots
Posted: Fri Jun 26, 2009 3:35 pm
by lickstab
this is really awesome, and i found out about it right after i'd been thinking to myself "hmm, i need an editable terrain thingy.."
i added it in a test project and i can get it to show up and all, but now i'd like to access the vertex data so i can build a collision mesh from the terrain.
however, i can't figure out how to do it.. is it even possible in the current version?
all i can find that might be it is getQuadTree()->getVertexDataRecord(), but it's not public.
anyway, like i said, this is awesome and i'm definitely going to be using this for my random experiments in the future..
Re: New Terrain Early Shots
Posted: Fri Jun 26, 2009 3:41 pm
by sinbad
Just call Terrain::getPoint for all points on the grid (or just access the height buffer directly since you know how things are spaced).
Re: New Terrain Early Shots
Posted: Fri Jun 26, 2009 7:54 pm
by KungFooMasta
Sorry for the double question.

Thanks for the information, much appreciated.

Re: New Terrain Early Shots
Posted: Fri Jun 26, 2009 10:58 pm
by lickstab
awesome, thanks. i used getHeightAtPoint().
i managed to build an OgreNewt::TreeCollision based on the terrain, and it matches the shape perfectly, however the polys are shaped oddly.
instead of forming a grid like i'd expected, they make little "stripes", and mostly don't block things from falling through.
looks like this:

- terrain to collision mesh oddity
- odd.jpg (41.88 KiB) Viewed 11023 times
admittedly i'm no expert and just experimenting.
is there any "obvious"/common mistake that would result in the polys looking this way?
Re: New Terrain Early Shots
Posted: Sat Jun 27, 2009 2:54 am
by lonewolff
Awesome screenshots, Sinbad!
Great frame rate too.

Re: New Terrain Early Shots
Posted: Sat Jun 27, 2009 5:24 am
by stealth977
lickstab wrote:awesome, thanks. i used getHeightAtPoint().
i managed to build an OgreNewt::TreeCollision based on the terrain, and it matches the shape perfectly, however the polys are shaped oddly.
instead of forming a grid like i'd expected, they make little "stripes", and mostly don't block things from falling through.
admittedly i'm no expert and just experimenting.
is there any "obvious"/common mistake that would result in the polys looking this way?
I dont know what you are doing wrong but:
float *mapptr = OGRETERRAIN->getHeightData(); //< This is the array of height values (SIZE: MapSize * MapSize)
One Grid Point (X,Z):
Code: Select all
float DeltaPos = (WorldSize / 2.0f);
float Scale = WorldSize / (float)(MapSize - 1);
Ogre::Vector3((Scale * X) - DeltaPos, mapptr[(MapSize * Z) + X], (Scale * -Z) + DeltaPos);
i hope that helps
ismail,
Re: New Terrain Early Shots
Posted: Sat Jun 27, 2009 3:55 pm
by lickstab
sweeeet, now it works.
first of all i was doing WorldSize/MapSize for the scale, instead of using mapsize-1.
also, the code that generated the indices that i passed on to ogrenewt was completely messed up, that was probably the biggest issue.
i rewrote it from scratch, and now it works perfectly!

- notodd.jpg (81.89 KiB) Viewed 10881 times
thanks!
Re: New Terrain Early Shots
Posted: Sun Jun 28, 2009 10:16 am
by kinjalkishor
It looks close to natural terrain found in hilly regions. This is going really very good. I am such a fan of outdoor environments. The look is very refined owing to normal mapping an good textures and materials. Also performance is also good.
Re: New Terrain Early Shots
Posted: Mon Jun 29, 2009 4:41 pm
by Xplodwild
@lickstab : Can you share your code ? I think it will be very appreciated by all OgreNewt users (like me)
Also, I'm waiting so much the final release, it looks really great. I hope it will be pluggable with ETM so you can use for instance ETM in your editor, and then use this Terrain manager in your game to render big terrains. If it needs some code, I'll write it and share it with you

Re: New Terrain Early Shots
Posted: Mon Jun 29, 2009 4:45 pm
by CABAListic
The new terrain system is itself editable; there is no need to use ETM for your editor

Re: New Terrain Early Shots
Posted: Mon Jun 29, 2009 4:53 pm
by Xplodwild
Is it possible to load maps created with ETM in Terrain Manager ? Because there's a lot of work already done and my artists won't mind recreating everything ^^ . I read the whole topic and didn't saw that Terrain is editable, maybe I missed something ? Thanks anyway for the news.
Re: New Terrain Early Shots
Posted: Mon Jun 29, 2009 5:48 pm
by stealth977
Xplodwild wrote:Is it possible to load maps created with ETM in Terrain Manager ? Because there's a lot of work already done and my artists won't mind recreating everything ^^ . I read the whole topic and didn't saw that Terrain is editable, maybe I missed something ? Thanks anyway for the news.
Yes, it is very much possible to use the heightmaps and splat maps from ETM in Ogre::Terrain, though splat maps may need some tweaking.
ismail,
Re: New Terrain Early Shots
Posted: Mon Jun 29, 2009 6:27 pm
by lickstab
Xplodwild wrote:@lickstab : Can you share your code ? I think it will be very appreciated by all OgreNewt users (like me) :)
i suppose i could, but i'm definitely just an amateur programmer so i don't make any claims about the quality/correctness of the code.
i just know it appears to work for me, so keep that in mind.. maybe someone can comment on it, feel free.
anyway, here's my function:
Code: Select all
// build an OgreNewt collision mesh based on a "new ogre terrain" terrain
void joey::UpdateTerrainBody()
{
if(TerrainBody != NULL)
delete TerrainBody;
// credits to stealth977 @ http://www.ogre3d.org/forums/ for pointing me in the right direction
// get height data, world size, map size
float *mapptr = myTerrain->getHeightData();
float WorldSize = myTerrain->getWorldSize();
int MapSize = myTerrain->getSize();
// calculate where we need to move/place our vertices
float DeltaPos = (WorldSize / 2.0f);
float Scale = WorldSize / (float)(MapSize - 1);
// build vertices
float* vertices = new float[(MapSize*MapSize) * 3];
int i = 0;
int max = MapSize; // i think i needed this for something before but now it's obviously redundant
int z = 0;
for(int x = 0;; ++x)
{
// if we've reached the right edge, start over on the next line
if(x == max)
{
x = 0;
++z;
}
// if we reached the bottom/end, we're done
if(z == max)
break;
// insert vertex
vertices[i] = (Scale*x) - DeltaPos;
vertices[i+1] = mapptr[(MapSize*z)+x] - 0.5f; // i put the collision shape slightly lower, because before objects would appear to be floating just above the terrain instead
vertices[i+2] = (Scale * -z) + DeltaPos;
i += 3;
}
// i think this is right, seems to be
int size = ((MapSize*MapSize)-(MapSize*2)) * 6;
int* indices = new int[size];
// i will point to the 'indices' index to insert at, x points to the vertex # to use
i = 0;
for(int x = 0;;++x)
{
// skip rightmost vertices
if((x+1)%MapSize == 0)
{
++x;
}
// make a square of 2 triangles
indices[i] = x;
indices[i+1] = x + 1;
indices[i+2] = x + MapSize;
indices[i+3] = x + 1;
indices[i+4] = x + 1 + MapSize;
indices[i+5] = x + MapSize;
// if we just did the final square, we're done
if(x+1+MapSize == (MapSize*MapSize)-1)
break;
i += 6;
}
// build our collision shape
OgreNewt::Collision* TerrainShape = new OgreNewt::CollisionPrimitives::TreeCollision(nWorld, MapSize*MapSize, size, vertices, indices, false);
// .. and our body
TerrainBody = new OgreNewt::Body(nWorld, TerrainShape);
// cleanup
delete TerrainShape;
delete [] vertices;
//delete [] indices; // my program crashes on this line and i'm not sure why, i thought i wouldn't need 'indices' anymore
}
also, it's probably possible to make it use a lower resolution shape instead of going point-by-point like mine does, but i haven't really given it much thought yet..