Feature requests for ETM v3

CABAListic

21-01-2008 18:39:53

If anyone can think of a feature they would like to see for the next major version, this is the place to post. ETM v3 is currently in the planning phase, so I will consider each suggestion and look if it fits my concept of ETM.

The basic idea for ETM is to have a core set of functionality which is as small and as flexible as possible. It is not supposed to do everything one might need, but it should allow for outside code to do just about anything sensible. Routines which do not fit the core but will be useful to a majority of the library's users will be added as utility functions (like loading and saving heightmaps etc.).

kungfoomasta

21-01-2008 21:24:45

Congratulations on the forum! :D

It seems that functionally, the core part of the library works well. Most of my suggestions are regarding convenience and usability of the library.

- Integrate Ogre's Movable Object concept, meaning that the Terrain can be created at any time, but won't be a part of the scene unless it is attached to a Scene Node.

- Essential terrain functions like ray casts should be handled through the terrain object, and not the data used to create the terrain, its not very intuitive with that design. On a general level, the Terrain should allow access to accurate terrain data, the TerrainInfo class should be thrown away after used to create the Terrain.

- Brush class with functions to set the brush image, size, etc.

- Transparent material management allowing for users to easily define what textures to splat, and be able to remove/change these at run time.

- Easy access to Tile vertex/index data, for collision/physics libraries not using a heightfield shape.

CABAListic

21-01-2008 21:50:09


- Integrate Ogre's Movable Object concept, meaning that the Terrain can be created at any time, but won't be a part of the scene unless it is attached to a Scene Node.

Definitely planned. The TerrainPatch (as the new terrain primitive) will become a MovableObject, and so will the TerrainPage which builds upon the patches. I'm not certain about all the details, yet, but this is set :)

- Essential terrain functions like ray casts should be handled through the terrain object, and not the data used to create the terrain, its not very intuitive with that design. On a general level, the Terrain should allow access to accurate terrain data, the TerrainInfo class should be thrown away after used to create the Terrain.
Hm, actually, I'm planning on doing the opposite, that is, not only keep querying on the new Heightmap object, but also move all the editing functionality to Heightmap.
The reason is that with the new foundation on TerrainPatches (Tiles at the moment), if you are discarding the Heightmap after creation, those would need to offer the editing abilities. But that means they probably have to keep their own copies of them. Since Patches will generally not be what you are using directly, any higher level component would have to replicate the functionality and do some weird stuff to map any call to the correct Patch and unite their info when necessary (saving etc.).
My take is to have a Heightmap as an abstract base class providing querying info and editing abilities for heightmap data. The standard implementation would be based on a 2D array. Patches would be created by passing a Heightmap* pointer to their constructor. You could define only a subarea of your Heightmap* by using the SubHeightmap class. Whenever a heightmap is edited, the changes are propagated via a listener architecture to any relevant terrain object which needs updating.
So in fact the Heightmap* would become your main object of interaction with the terrain.

Of course, what *could* be done is to make TerrainPage inherit from Heightmap so that your actual higher level terrain structure becomes an integrated object. But I'm not yet certain if that is really a good idea, as it introduces unnecessary coupling and might make the Page less flexible for a paging solution.


- Brush class with functions to set the brush image, size, etc.
This will very likely become utility functionality. It wouldn't hurt to state in more detail what you'd like to see here :)

- Transparent material management allowing for users to easily define what textures to splat, and be able to remove/change these at run time.
You mean something like a TerrainMaterial class providing a standard implementation for the "average" user? Yeah, that could go in utility.

- Easy access to Tile vertex/index data, for collision/physics libraries not using a heightfield shape.
I've still had no experience with physics libraries. What data would be needed, exactly?

kungfoomasta

21-01-2008 22:46:13

Yah, a lot of my requests are utility methods, or things that would make current use easier. :wink:

In PhysX, all scenes have Actors. These Actors are constructed through a "Shape description" and "Actor description". You fill in the data of these two objects, and use them to create an Actor. Once you have the actor, you can throw away the descriptions and interact with the Actor class directly. This would be like creating a blueprint for the terrain, and then constructing the terrain. After the terrain is created, you work with the terrain directly. If this doesn't really fit into the design you planned then so be it, but it really seems more intuitive that the terrain class is used to modify the terrain. Using Class A to use and interact with Class B seems odd, since Class B should be self contained, right?

With the Brush, I had the smoothing functionality in mind, but I'm not sure what class would contain it.

I was wondering about transparent splatting, for the scenario where you'd want to add a mesh cave. You'd need to make the terrain transparent so the cave entrance can be seen.

For Physics Objects, you need 2 lists: vertices, indices. Imagine you had a patch, and you wanted to create an Ogre Manual Object from it. If you can provide the data needed to make a Manual Object, then you can also use that data for a physics shape. (Its just vertices and indices, nothing else needed, AFAIK)

I just wanted to restate that IMO, ETM seems to be functionally complete, or close to it. Main things left are optimizations, utility, and useability. :)

CABAListic

21-01-2008 23:18:24

If this doesn't really fit into the design you planned then so be it, but it really seems more intuitive that the terrain class is used to modify the terrain. Using Class A to use and interact with Class B seems odd, since Class B should be self contained, right?

Actually, it's a matter of view. The way I see it is that the terrain object is just a visual representation of a heightmap. Now, do you edit the visual representation, or do you edit the heightmap? Technically, you will need a copy of the heightmap data somewhere, so you're editing this heightmap data, then the vertex buffers are updated.
I agree that the current way is suboptimal, where editing functionality resides in the TerrainManager, but queries are down on the TerrainInfo. But separating the data from the visual representation does make sense in a way, I think. It's like a model-view approach.
Or maybe think of the following scenario, thought towards paging: Suppose you have a heightmap of size 2048x2048 which is divided into 64 256x256 pages. Not all pages are loaded all the time, and if they were responsible for editing terrain, that would mean you can't edit terrain whose page isn't currently loaded. However, if the editing capability resided at the Heightmap class, you could edit your big heightmap, and changes would reflect to actively loaded pages while it wouldn't matter if parts were not loaded. They would just be loaded with the updated data next time.

For Physics Objects, you need 2 lists: vertices, indices. Imagine you had a patch, and you wanted to create an Ogre Manual Object from it. If you can provide the data needed to make a Manual Object, then you can also use that data for a physics shape. (Its just vertices and indices, nothing else needed, AFAIK)
Yeah, but actually the data I use to create the "ManualObject" (I'm one step lower level actually filling my own vertex buffers) is just the Heightmap. I then have a list of index buffers for different LODs and a HardwareVertexBuffer for each patch. But the HardwareVertexBuffer is not supposed to be read from, and I think exposing it would not be a good idea.

If I understand you right, what would be needed would be the heightmap data converted to scaled Vector3 positions which could be used to state vertex positions. And for the index buffer you would need the triangle list for full LOD - obviously LODded index buffers don't make much sense for physics models, or do they? Maybe the Heightmap again could provide some convenience functions for this...

kungfoomasta

21-01-2008 23:47:54

Now that you explained your view and how it relates to the design, it makes more sense. Not a view I prefer, but thats a matter of opinion, I believe. :wink:

I would imagine that you don't want to apply any LOD to the physics shape. Your camera might be far away from a particular patch, but the actors in the scene may not be. Like you said, you would just grab the section of heightmap and convert it to actual world positions (Vector3), and supply the indexes for the vectors. (depending on if you do counter clockwise or clockwise winding, you should be able to calculate this)

CABAListic

22-01-2008 00:25:57

Now that you explained your view and how it relates to the design, it makes more sense. Not a view I prefer, but thats a matter of opinion, I believe. :wink:

Most certainly. Maybe you'll like it more once it's finished. :) Just don't let the current TerrainInfo fool you, the new Heightmap won't have too much in common with it (except, obviously, the query interface). I'm not actually fixed on my approach, especially if others are feeling like you I might have to rethink this. My biggest problem with that, though, is that I haven't yet found a convincing alternative for me.

Still, here is what it might look like with this new interface:

Heightmap* bigHeightmap = loadHeightmapFromImage("heightmap.png");
TerrainPage* page = new TerrainPage(sceneMgr, new SubAreaMap(bigHeightmap, 0, 0, 256, 256));
page->setMaterial(material);
sceneNode->attachObject(page);

// ...
deform(bigHeightmap, posX, posZ, brush, intensity);
float terrainHeight = getHeightAt(bigHeightmap, posX, posZ);


But this is just a draft. With deform, getHeightAt etc. being nonmember functions, they could actually be overloaded to also take TerrainPage* and TerrainPatch* pointers and do a mapping to the correct Heightmap* pointer internally. Maybe that would be a good compromise.

Anyway, the point is that after setup, you most likely would no longer touch the visual objects, you'd just operate on the Heightmap entirely.

kungfoomasta

22-01-2008 00:44:52

What do the arguements of

new SubAreaMap(bigHeightmap, 0, 0, 256, 256)

represent?

You need to somewhere specify the ogre world bounds of the object, right?

Minor request:
- Terrain constructor to ask for only the total width, height, and depth of the terrain. Since we attach to scene node, we shouldn't need to specify the bounding box dimensions, like we do now.

SongOfTheWeave

22-01-2008 00:45:44

I'm not actually fixed on my approach, especially if others are feeling like you I might have to rethink this. My biggest problem with that, though, is that I haven't yet found a convincing alternative for me.

Your approach makes sense to me, as I understand it right now.

From where I'm sitting, it makes even more sense to use this sort of an architecture when potentially many patches exist (and are exposed.)

I'm thinking of it like this:

Coordinator --(has)--> Patches
(TerrainMgr) (Patches/tiles/what have you)

Thats probably how any implementation would do it, the difference here I believe is that rather than asking Coordinator (terrainMgr equivalent) to ask a Patch something and then relay it back to you, the patch observer methods are exposed. I'm not sure that last bit was really very clear, so I'll do an example. I like examples.


Rather than providing a wrapper method like so:

float Coordinator::getHeightAt(int x, int y)
{
return getPatchContaining(x, y)->getHeightAt(x, y);
}

A utillity function getPatchContaining(int, int) or something is provided and you call getHeightAt on it yourself. Or maybe the BigHeightmap class handles getting the proper patch. I dunno.

Anyway, my point was that this way of thinking about it seems just as natural as any other way that I've thought of or heard mentioned *shrugs*

SongOfTheWeave

22-01-2008 00:47:22

What do the arguements of

new SubAreaMap(bigHeightmap, 0, 0, 256, 256)

represent?

You need to somewhere specify the ogre world bounds of the object, right?

Minor request:
- Terrain constructor to ask for only the total width, height, and depth of the terrain. Since we attach to scene node, we shouldn't need to specify the bounding box dimensions, like we do now.


The arguments represent the bounds of the area within the bigHeightmap that we are assigning to the SubAreaMap.

i.e. the new SubAreaMap we just created encompases verticies of bigHeightmap from points (0,0) to (256, 256)

CABAListic

22-01-2008 00:50:55

What do the arguements of

new SubAreaMap(bigHeightmap, 0, 0, 256, 256)

represent?

They select a sub-box of the bigger heightmap. If the bigger heightmap were a 2049x2049 vertices heightmap, then this would define the subarea from top left (0, 0) to (256,256). So basically this is a 257x257 heightmap wrapper, if you so will.

You need to somewhere specify the ogre world bounds of the object, right?

Minor request:
- Terrain constructor to ask for only the total width, height, and depth of the terrain. Since we attach to scene node, we shouldn't need to specify the bounding box dimensions, like we do now.


Yeah, I omitted that, it would probably still be on the Heightmap. Of course you are right with the bounding box, the patch would be centered on the origin of the attached scene node, so you only need to provide the dimensions, not the extents.

MisterMayhem

22-01-2008 02:59:56

The ability to paint the terrain with colors.

This doesn't seem like it would be that hard. The way I see it, there could be a shadow map and a color map. For efficiency they would be pre-blended together by the CPU as one texture for the rendering pipeline, but managed as two separate textures. They would be required to be the same size and texture format.

So the functionality is mostly there already in the form of the existing shadow map. I plan to add the ability to paint a color map similar to the splatting. I'll probably have the shadow map disabled and not shown for the painting process, to make it easier and faster in real time.

I'll be planning it in the coming weeks. Suggestions are welcome, and hopefully it will be useful for this project, at least as something that can be switched on or off.

kungfoomasta

22-01-2008 04:48:29

SongOfTheWeave, I disagree, and I don't really follow your examples.

Take the SceneManager, for example. You create the SceneManager, and then manage the scene through this class. There is no class "XYZ" which manipulates the Scene. The SceneManager manipulates the Scene. And following this common idea, the TerrainManager manipulates the terrain. The SceneManager doesn't require some external class to use its ray queries, or create/destroy parts of the scene, and neither should the TerrainManager.

As the name suggests, anything with "manager" in the name should manage. It defies its own definition with the fact that the ETM does not in fact manage the terrain, but the heightmap object does.

I would outline a general use case of a more intuitive way to structure the library, but I think it might require a lot of work to put in place. The current method works, it just requires more background knowledge to get familiar with all that can be done with the library. (higher learning curve IMO)

Sorry if I sounded harsh, I don't mean to be. :)

CABAListic

22-01-2008 12:02:01

@MisterMayhem: Sure, would be pretty similar to the splatting editing. But you cannot unite the textures to one until you are finished with them. So long as you are editing, they need to remain apart and mixed by the GPU - way faster than doing it with the CPU. Only when it's final, then you can safely multiply them together as a pre-render step.

@kungfoomasta:
TerrainManager is indeed a misleading name and will no longer occur in ETM v3 (and maybe the library name should change to "Editable Terrain Library"?). The new Page and Patch classes will essentially be just MovableObjects/Renderables which you attach to your scene graph.
Which brings me back to the fact that Terrain in ETM *is* essentially a heightmap. There are other ways of doing terrain, but for us it's a heightmap. The heightmap is what defines the shape of your terrain, and it's the heightmap you edit.
Do you know tools like L3DT or others which let you edit terrain via 2D images? You can apply brushes to them like in a graphics manipulation program. ETM (ETL) v3 would in theory allow you to expose such a 2D representation instead and use it to edit without ever having to create a 3D terrain representation. The heightmap is just a more general concept, and I like to keep things general if I can :)

CABAListic

22-01-2008 19:07:27

I currently have one big general problem to solve which results from making the terrain objects MovableObjects: And that's querying the terrain. For any query (height or ray) you must know the terrain's position in 3D space, obviously. This in itself is a problem with my approach because the heightmap doesn't know unless it's informed by the patches which use this heightmap. Even then, the patches would need to be synchronised so as not to give differing indications. Obviously, this is a problem that the other approach would handle better (except for the code repetition that any higher level object would need to do which I don't find very elegant).

But even so, as a MovableObject the terrain objects could suddenly turn up rotated in 3D space, so they are no longer aligned with the x-z plane. Now what? How do you retrieve the terrain height at some arbitrary point? You would need to provide a full Vector3, and internal routines would have to transform that into the local coordinate space xz plane to do the height query. Ray queries would similarly need to be transformed. Hm, this definitely complicates things a lot :)

CABAListic

26-01-2008 09:11:44

A simple question: When adding a Terrain to a SceneNode, which point of the terrain would you like to be at the SceneNode's origin? In (x,y,z), the most sensible choices would be (0,0,0), (mid, 0, mid) and (mid, mid, mid). I'd favor (mid, 0, mid) which would mean that if your SceneNode is at Ogre's origin, then the origin would be in the center of the terrain's xz plane (x and z going from -width/2 to + width/2), but the y coordinates would range from 0 to the terrain's height.

SongOfTheWeave

26-01-2008 10:04:05

A simple question: When adding a Terrain to a SceneNode, which point of the terrain would you like to be at the SceneNode's origin? In (x,y,z), the most sensible choices would be (0,0,0), (mid, 0, mid) and (mid, mid, mid). I'd favor (mid, 0, mid) which would mean that if your SceneNode is at Ogre's origin, then the origin would be in the center of the terrain's xz plane (x and z going from -width/2 to + width/2), but the y coordinates would range from 0 to the terrain's height.

I'm for either (0, 0, 0) or (mid, 0 mid). The height mid seems a poor choice since it may change during editing.

Though, I must note that Y = up drives me absolutely batty *laughs* Z is up! Z is up!

I can't seem to remember at what point in my life I was indoctrinated...

Nauk

26-01-2008 10:06:50

not sure but i think things are prolly easiest to calculate with (0,0,0) but that's rather a gut feeling than well thought out :)

Nauk

29-01-2008 21:54:51

Oh and a Feature request:

- Support for some sort of Bump / Offset / Normal or Displacement mapping.
- Support for 1 big colormap on top of everything

Bascially things to make the terrain look more real and tune down tile- and texturerepeating effects :)

CABAListic

29-01-2008 22:34:58

What do you need for normal/whatever mapping that isn't there already?

kungfoomasta

29-01-2008 23:36:59

Are there any possible ways to get more than 4 splatting textures managed by a cover map?

I'm dreaming, but...

Create functionality that allows the user to specify the number of splatting textures mapped to a channel. Right now it's 1 channel = 1 texture, so a RBGA image will manage 4 textures. What if we could make 1 channel map to 2 textures? 3? x? I realize you won't have the full range of opacity when you do this, but then users can find whats acceptable to them and use that. In this way most people will only have 1 or 2 passes for texture splatting.

I know this would be an insane amount of work, if it was possible, but thought I'd throw on this idea anyway. :P

Nauk

30-01-2008 00:23:29

What do you need for normal/whatever mapping that isn't there already?

I tried to "marry" several of the existing normal mapping examples to the ETTerrain.material, adding it as extra pass on top, at the start, no result at all, the only time anything ever happened on the screen when i derived the Bumpmapping material from ETTerrain.material and assigned it in the code as main material for the terrain. like:
material Examples/BumpMapping/MultiLightSpecular : ETTerrainMaterial



MaterialPtr material MaterialManager::getSingleton().getByName("Examples/BumpMapping/MultiLightSpecular"));
mTerrainMgr->setMaterial(material);


Honestly I am a total noob when it comes to material scripts and shaders etc. So I don't know if this is something the current splatting shader or manager just does not allow or just my lacking knowledge in doing it right :). Still I think it would be a nice feature to put up a working bumpmapping example into the sample code that comes along. In the line of being easy to understand and right away usable with a low learning curve, imho totally in line with ETMs current philosophy.

CABAListic

30-01-2008 00:43:33

Well, you definitely cannot use the example splatting shaders, as normal mapping would have to be done in these shaders. I think in principle this should be a pure material issue, nothing on code site (except, maybe, normal map generation).

@kungfoomasta: Well, a single 8 bit channel gives you 256 different opacity states for a texture from fully transparent to fully opaque. If you compress two channels into these 8 bits, then there remain 4 bits per channel, meaning 16 different states. I'm not sure this is enough to create smooth transitions between textures. But it would certainly be the limit, you can't effectively store more than those 2.
In a pure integer world, you could also use the full 32 bits of the texture and use 5 or 6 bits per channel to get 5 to 6 channels with 32 or 64 transparency states. Problem is, I don't see how you could extract those channels out of the texture in your shader. Even with the simpler approach above it would still complicate your shader quite a bit, I'm not certain if that's really worth the trouble.

Newer graphics cards have more than 8 texture units, I think, and SM2 allows for up to 16 texture units in a single pass (even though that would probably be split up by the graphics card internally, if it does not have that many units). So in theory you could splat 12 textures in a single pass already.

Nauk

30-01-2008 07:09:25

Well, you definitely cannot use the example splatting shaders, as normal mapping would have to be done in these shaders. I think in principle this should be a pure material issue, nothing on code site (except, maybe, normal map generation).

As long as I know it can be done from the material side only I have np buttering down the hours necessary to work it out. And of course I am willing to share any fertile results :). I just wanted to be sure that this is the case and doable from that side (maybe the wrong thread *cough*).

Time to go jump into The CG tutorial.

Nauk

03-02-2008 05:04:18

Giving it another thought, a SplattingManager for bumpmaps and the ability to paint and merge an extra layer of different bumpmaps, just like you do with textures now, would be great. Easy to use and WYSIWYG ftw :)

SongOfTheWeave

04-02-2008 12:08:44

Giving it another thought, a SplattingManager for bumpmaps and the ability to paint and merge an extra layer of different bumpmaps, just like you do with textures now, would be great. Easy to use and WYSIWYG ftw :)

Generally, I think one would want to match specific normal maps to specific textures.

For example, if I have a rocky texture, I want the rocky normal map that lines up with it, and I dont' want to have to paint the normal map over the same region that I just painted with the colour texture.

So, implementing normal mapping probably still belongs solidly in the material side of things unless there's an application that I'm not thinking of where you would want to freely paint normal maps, independant of your colour textures, rather than essentially painting a pre assigned colour texture/normal map pair (which afaik just requires some material manipulation.)

I admit, I haven't written normal mapping yet for my app, so I might be off base.

Nauk

04-02-2008 12:44:54

I think Vanguard does it with their terrain to counter the tiling effect, my impression is they run a generic structured normal map over everything, but i might be wrong of course. Also with a paint ability there you could do both, either go generic "noise" or match your texture.

luis

04-02-2008 14:01:34

I dont know if it is already possible but i'd like to have a way to rotate, or even better set the brush's orientation in the splattingmanager/terrainmanager.


For example, i use brushes to make jumps in the terrain, so i need to set the brush orientation exactly the same as the camera.
Perhaps i could rotate the brush image right before using it but i think it will work ok only with 90 degrees angles, otherwise i'll get artifacts.....

CABAListic

04-02-2008 14:33:56

I can try and do some interpolation, but in effect this would also just be a rotation of the "image" (or rather, the 2D array). There is no other way as I can only modify the heights of the vertices which form the heightmap's grid, and similarly the brush is a 2D array of height values.

luis

04-02-2008 15:18:12

I see.... i didn't realize you are in fact modifying another image (the heightmap) with the brush.
Since Ogre::Image doesn't have a 'rotate' method would be useful if you implement it. i think that something like:

currentBrush.setScale( scale );
currentBrush.setRotation( angle );
mTerrainMgr->deform(x, z, currentBrush, brushIntensity );


and if you just apply the transform in the brush, it will be faster than loading the image, apply the tranformation and build a new brush for each case.
But if none here is going to use that feature i'm feeling bad for asking something i could do in my own code...

CABAListic

04-02-2008 15:59:06

Well, on second thought, it shouldn't be so much more work to do. Brush scaling was already planned, so I need an interpolation of the brush values, anyway. Doing rotations is then as simple as mapping the terrain vertices' 2D positions to the local coordinate space of the brush. That's some sine and cosine calculations, so not really that bad.
I can't, however, promise that the results will be any good ;)

luis

04-02-2008 19:29:52

I can't, however, promise that the results will be any good
Dont worry, i'll happy anyway ;)

BTW: is it possible to do an 'undo' in the terrain ? I mean something to revert to last previous state like: TerrainManager::undo ?

thanks!

CABAListic

04-02-2008 21:44:10

Well, you can just do the inverse transformation to cancel the effect ;)
On a more practical note, you could, at the beginning of each update step, request the heights of the region you are editing and store it in some sort of undo list. If an undo is requested, you can just set the heights of the region to the heights you stored in your undo list. I think it is reasonable to do this at the app site, not in the library itself.
Admittedly, though, undoing splatting changes might be more difficult since the SplattingManager doesn't currently expose any way of retrieving a region of the splat maps. I'll have to think of a better interface for that part of ETM...

SongOfTheWeave

04-02-2008 22:32:56

I think it is reasonable to do this at the app site, not in the library itself.

Agreed.

(BTW, CABAListic, I'm joining you on the anti-feature-creep squad ;P)

luis

04-02-2008 23:00:50

On a more practical note, you could, at the beginning of each update step, request the heights of the region you are editing and store it in some sort of undo list. If an undo is requested, you can just set the heights of the region to the heights you stored in your undo list. I think it is reasonable to do this at the app site, not in the library itself.
ohh i didnt see who useful is TerrainManager::setHeights, so doing an undo is very easy.... sorry i'm beginning to use ETM :)

Admittedly, though, undoing splatting changes might be more difficult since the SplattingManager doesn't currently expose any way of retrieving a region of the splat maps. I'll have to think of a better interface for that part of ETM...
great!

kungfoomasta

04-02-2008 23:32:57

(BTW, CABAListic, I'm joining you on the anti-feature-creep squad ;P)

While its true that some requests are not within the scope of the library itself, the fact remains that ETM is already functionally complete, all the base functionality is there. So all thats left is to add cool new features. :wink:

SongOfTheWeave

05-02-2008 09:33:01

(BTW, CABAListic, I'm joining you on the anti-feature-creep squad ;P)

While its true that some requests are not within the scope of the library itself, the fact remains that ETM is already functionally complete, all the base functionality is there. So all thats left is to add cool new features. :wink:


Heh, I suppose that is true, but I consider many of the features/api enhancements that CABAListic has planned for v3 to be significant (in other words, not "superfluous features.")

For example, the planned "patch" implementation. The ability to use an independant list of splat textures for each patch (rather than one set for the entire terrain) will enable greater variance of terrain appearance without bloating your material with textures that may only be used in a small section of the overall map.

CABAListic

17-02-2008 13:24:10

Another question for consideration:
In the current version of ETM, updates to terrain and splatting map are done directly by vertex positions, i. e. the Brush class is essentially a 2D array which modifies another 2D array, and you have to give the update position as the array indices. In ETM v3 the Brush can be scaled and rotated, so updates will now take the real position, not array indices, and the updates are interpolated internally.
This is no problem for the Terrain operations, however for this kind of update to work on the SplattingManager or the upcoming ColourMap, those must also have a scale and a position/orientation in 3D space. How would you like to provide these? There are basically 2 possibilities:

1) The SplattingManager is itself a MovableObject, just like the Terrain. You have to provide a "vertex" scale factor just like for the Terrain and then attach it to a SceneNode in order to work correctly.
2) The SplattingManager requires passing of a Terrain object to which it belongs and uses the scale and positioning of that Terrain object wherever necessary.

Quite obviously, the latter simplifies usage and is most likely what you'd want to have in pretty much any case I can think of. But it does require a Terrain object in order to use the SplattingManager which is not currently the case. Which way do you prefer?

kungfoomasta

17-02-2008 19:03:26

How about 2, except with more built in convenience, so that a raycast is done, and the terrain that is hit is supplied, so the user doens't need to pass the Terrain Object? With large bounding boxes, the raycast shouldn't be very heavy on performance.

CABAListic

17-02-2008 19:09:08

How do you mean that? Option 2) meant that the Terrain is passed at construction, not at each update to the textures. I have no idea how a ray query would be any help here :)

kungfoomasta

17-02-2008 20:00:29

doh!

Well if a pointer to the Terrain is only required in the constructor, option 2 doesn't seem bad at all. How does option 1 work, with the SplattingManager as a MovableObject? Can you give a sample use case? (few lines of pseudo code)

CABAListic

17-02-2008 20:19:01

Well, in most cases you would probably attach the SplattingManager to the same node as the Terrain itself, plus additionally you'd have to give the scale (terrain extents) at construction.

SongOfTheWeave

18-02-2008 10:34:35

I vote for #2

It is more intuitive and I can't think of any advantage you'd gain in terms of flexibility by using #1.

kungfoomasta

19-02-2008 17:34:59

Now that I'm able to successfully create heightfield Shapes using heightmap data, I wanted to emphasize a request for:

- Public access to Tiles
- Public access to Tile heightmap data

With these 2 features I would be able to have a more efficient PhysX solution with Terrain, and have easier updating when deformations occur.

CABAListic

19-02-2008 17:39:55

/**
* This is an abstract interface which represents a vertex description of a
* heightmapped piece of terrain.
*/
class TerrainDescription
{
public:
/** Get the number of vertices of this terrain */
virtual unsigned int getNumVertices() const = 0;
/** Get the number of vertices in X direction */
virtual unsigned int getNumVerticesX() const = 0;
/** Get the number of vertices in Z direction */
virtual unsigned int getNumVerticesZ() const = 0;
/** Get the vertex index from 2D coordinates */
virtual unsigned int getVertexIndex(unsigned int x, unsigned int z) = 0;
/** Get the position of the i'th vertex */
virtual Ogre::Vector3 getVertexPosition(unsigned int i) const = 0;
/** Get the normal of the i'th vertex */
virtual Ogre::Vector3 getVertexNormal(unsigned int i) const = 0;
/** Get the tangent of the i'th vertex */
virtual Ogre::Vector3 getVertexTangent(unsigned int i) const = 0;
/** Get the binormal of the i'th vertex */
virtual Ogre::Vector3 getVertexBinormal(unsigned int i) const = 0;
/** Get the first texture coordinate of the i'th vertex */
virtual Ogre::Vector2 getVertexTexcoord0(unsigned int i) const = 0;
/** Get the second texture coordinate of the i'th vertex */
virtual Ogre::Vector2 getVertexTexcoord1(unsigned int i) const = 0;

/** Get the size of the triangle list of the index buffer (at full detail, no stitching) */
virtual unsigned int getTriListSize() const = 0;
/** Get the vertex index for the i'th position in the trilist */
virtual unsigned int getTriListIndex(unsigned int i) const = 0;

/** Retrieve a list of vertices whose details have changed and need updating */
const VertexList& getDirtyVertexList() const
};


This will be at the heart of the new Terrain class. I suppose that should satisfy all your needs. You will be able to retrieve subareas of the vertices via a wrapper class as I already proposed in some earlier drafts :)

kungfoomasta

19-02-2008 17:54:50

Wow, that is open! :D

Right now I'm using the heightmap values, which are a list of floats. [0.0 - 1.0] You're supplying the actual vertex position in ogre world space, but I'm pretty sure I can use that to create a heightfield shape. I just need to know the offset of the vertice in the y dimension, or be able to derive this from the highest/lowest y position, or from the AABB dimensions. The reason for this is that I have to convert each 3d world position's y value into a 16 bit integer between -(2^15 - 1) and 2^15 - 1.

CABAListic

19-02-2008 18:16:31

The vertex positions are in local space, they are scaled, but not paying attention to world position or orientation. So their y positions will range from 0 to scale.y, you can transform that scaling to anything you like.

kungfoomasta

19-02-2008 18:22:08

So their y positions will range from 0 to scale.y

What is scale.y?

Say I have a terrain made from a 16 bit .raw, so there are 2^16 values that can be used to describe a height. I want the terrain to take up 1000 Ogre units in the y direction.

Is the scale.y equal to (1000 / 2^16)?

CABAListic

19-02-2008 18:31:56

Well, with scale I meant the vertex scaling in Ogre units, i. e. the space between two vertices is equal to scale.x (or scale.z, respectively), and the y values range in [0, scale.y]. So, if your terrain takes 1000 Ogre units in height, then scale.y would be 1000.0f.
To transform this to your desired range, you could use

int height = static_cast<int>(-32768 + 65535 * (vertex.y / scale.y));

kungfoomasta

19-02-2008 18:39:56

Awesome, that works out nicely. :D

Looking forward to the wrappers to give me Tile vertex data. :twisted:

[edit] Do tiles overlap? I will probably need to make sure my Tile shapes exclude each other from collisions.
[/edit]

CABAListic

19-02-2008 18:50:50

The visual representations will overlap, they must. But that doesn't need to concern you, you can use the description of the whole terrain and choose subparts of it (via the wrapper class) which don't overlap.
However, actually I think that also your collision shapes must have overlapping vertices at the borders, otherwise you would have a gap in the collision. Since only vertices overlap, no triangles, that should not be any problem at all.

Nauk

20-02-2008 16:39:39


...
This will be at the heart of the new Terrain class. I suppose that should satisfy all your needs. You will be able to retrieve subareas of the vertices via a wrapper class as I already proposed in some earlier drafts :)


Looks great! :)

mkiv

03-04-2008 04:49:04

- I second bump mapping
- integration of a fog shader with ETM (or just including a shader file in the package)