Editable Terrain Manager [v2.2 released]

A place to show off your latest screenshots and for people to comment on them. Only start a new thread here if you have some nice images to show off!
CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
x 57
Contact:

Post by CABAListic »

Actually, that whole listener stuff got me thinking a bit about the overall ETM design. And I got some ideas for ETM 3.0 (i. e. future work, nothing I'll immediately get to):

At the moment, we have a TerrainManager which essentially manages a complete terrain. Internally, it divides the terrain into tiles which are the actual renderables. This is nice enough, but actually prevents people from using the "lower" level parts to assemble their terrains differently or even implement paging.
So, my proposed change is to make the Tile class publically acessible (actually, I think I'd rather call it a Patch in the future, since Tile tends to be highly confusing) with an interface similar to the current TerrainManager and with the added option to connect Patches to each other. A patch would be a MovableObject you'd need to attach to a SceneNode as requested by KungFooMasta. The TerrainInfo class would need an overhaul to allow to pass subareas to create the Patches. All in all, the Patches would form the "lower level" core of the library. (Only thing I need to figure out is where to put the ray and height queries.)
On top of that, I would offer a Page class which essentially mirrors the Patches' functionality, but for a larger, rectangular terrain layout. And this could then be used as the fundament for a paging solution complete with listener architecture and floating origin (but I will not implement this myself unless I should need it for future projects).

In a similar manner, the splatting manager could use a redesign. Basically, the current one would more or less become the "lower level" functionality, with more advanced managers on top of it to allow for optimised splatting. (With optimised splatting I mean that often, you may have a large number of different textures for the whole terrain, but single patches actually only use a limited number of those. With a modified, higher level splatting manager you could take advantage of that so that each patch only splats the textures it actually needs thus making it more GPU-friendly.)

What do you think? As I said, just some ideas for the moment. I'll probably not get to them anytime soon.

User avatar
KungFooMasta
OGRE Contributor
OGRE Contributor
Posts: 2087
Joined: Thu Mar 03, 2005 7:11 am
Location: WA, USA
x 16
Contact:

Post by KungFooMasta »

Definately a fan of your ideas! I agree with the Patch over Tile naming. Either works, but Tile is used more frequently I believe, at least from my own experience.

I probably won't make use of Paging, but overall everything you listed seems like a good feature. (And possibly a lot of work!)

Also requested is a method to get heightmap data from a particular tile, (I guess an array of floats) and be able to update tile data in real time (from array of floats). The reasoning for this is for the RTS project I'm working on. Our game has real time terrain deformation as part of the game play, so I will need a way to sync up client terrain with the server terrain. (not sync the entire terrain for every change, I'm trying to provide only relevant data to clients, to minimize any possible forms of cheating) If there is a better way to achieve this let me know.

[edit]
Another benefit of being able to access tile heightmap data is that one can create collision shape objects for each tile, which makes it more performance friendly when a part of the terrain has changed. In fact, you could allow Listeners, so that when the Tile is changed, the Collision Shape is updated to match it. 8)

I see I used "Tile" instead of "Patch". Will take some getting used to, if that change is supported. :P
[/edit]
Creator of QuickGUI!

CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
x 57
Contact:

Post by CABAListic »

As for the heightmap data: The overall idea is to change the TerrainInfo object into a hierarchy of classes. At the bottom you'd get the abstract base class HeightmapBase (don't take the names for granted, I'll decide on them later *g*) which provides an interface to get relevant values like width and length (both in terms of scaled values and number of vertices) as well as the height values of each vertex and interpolated terrain height functions.
From this base class there exists one concrete class Heightmap which is pretty much what TerrainInfo is now (why I didn't name it Heightmap in the first place, I'll never know), except that the interface will be slightly different. You will usually create one such Heightmap for your terrain via new. In addition, there's another class inheriting from HeightmapBase which might be called SubMap or similar. This is essentially a wrapper of a full Heightmap to define subparts of the whole heightmap. It stores no actual data itself, i. e. it translates coordinate requests to the whole heightmap and queries the Heightmap it was created for. Since a Patch will require a HeightmapBase* pointer at creation, you can pass it a sub area of your whole heightmap. And you can always get the HeightmapBase* pointer of a Patch via a corresponding getHeightmap() function.

I'm not yet certain where ray scene queries will go. If they do stay on the Heightmap (which I still think is not so bad), then the Heightmap will probably also have to be a MovableObject so that it can be attached to the same scene node as a Page and stay updated on position changes.

User avatar
KungFooMasta
OGRE Contributor
OGRE Contributor
Posts: 2087
Joined: Thu Mar 03, 2005 7:11 am
Location: WA, USA
x 16
Contact:

Post by KungFooMasta »

I'm sure I'll have plenty of questions once I start using the new approach. :wink:

Regarding the Ray Scene Queries, its not really relevant to me how you do it, since I will be using PhysX Ray casts. Everything I want to select will have an associated Shape/Actor. In General, I would say performing raycasts through the Heightmap class are a bit awkward, because you have to know if the user is trying to pick a point on the terrain. Its much better to be able to fire a ray and have it return any hit objects, instead of implementing a "I'm placing something on terrain X" mode, vs. a "I'm selecting a movable object" mode.
Creator of QuickGUI!

CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
x 57
Contact:

Post by CABAListic »

Problem though is that Ogre would normally return the terrain renderables via bounding box query which is quite inappropriate. I don't know if there's a way to override ray query matching, but I'll investigate.

Kerion
Goblin
Posts: 235
Joined: Wed Feb 05, 2003 5:49 am
Contact:

Post by Kerion »

Speaking of Rays and queries, I am having an issue that maybe you guys can help me with. When I use getCameraViewportRay and rayIntersects to get a terrain position, it doesn't seem to take in to account terrain that is actually in front of my mouse.

For instance, lets say I click at a point and build up a hill. if I then click in the middle of that hill, I should cast a ray through it, and it should become my position point, right? But that's not what happens, the ray travels THROUGH the hill and hits behind it, where the mouse would have hit if the hill weren't there (and the terrain were flat).

Shouldn't rayIntersects actually intersect the terrain that is there? It's almost as if when I call deform, it's not updating the TerrainInfo on the backend.

CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
x 57
Contact:

Post by CABAListic »

Maybe you are using the wrong TerrainInfo? The moment you create a terrain, the TerrainManager stores an internal copy of a TerrainInfo object for its use. Only this one is updated by deformations, the TerrainInfo instance you used to create the terrain is not updated.

You can always access the TerrainManager's TerrainInfo object via getTerrainInfo for queries.

Kerion
Goblin
Posts: 235
Joined: Wed Feb 05, 2003 5:49 am
Contact:

Post by Kerion »

Yah, that's what I am doing. I'll play with it to see if I am doing something wrong.

CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
x 57
Contact:

Post by CABAListic »

That's strange, because any deformation definitely updates the internal TerrainInfo. In fact, the TerrainInfo is updated first, and then the changes of the TerrainInfo are reflected onto the vertex buffers. So I don't really know what's going on. If you find anything, let me know.

Edit: What's the scale of your terrain? The ray query is similar to what the TSM does and is only an approximation. If your terrain's scale is very small, it might be that the approximation is too inaccurate.

Kerion
Goblin
Posts: 235
Joined: Wed Feb 05, 2003 5:49 am
Contact:

Post by Kerion »

Hmm, I don't think it's too small. I create a flat TerrainInfo (all heights 0.5) of 129x129. My extents is { 0, 0, 0, 1500, 300, 1500 }.

Those seems like pretty reasonable values?

CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
x 57
Contact:

Post by CABAListic »

Yeah, that should not be the reason then. Hm, very strange. I'm out of ideas for the moment, sorry :-/

Kerion
Goblin
Posts: 235
Joined: Wed Feb 05, 2003 5:49 am
Contact:

Post by Kerion »

Alright, well, at this point I am going to go with "it's the wrapper layer" and I am going to look in that direction.

CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
x 57
Contact:

Post by CABAListic »

Well, if it's not, then the ray query code itself must be buggy, but I can't spot anything suspicious, at least not immediately.

Kerion
Goblin
Posts: 235
Joined: Wed Feb 05, 2003 5:49 am
Contact:

Post by Kerion »

Bingo, it was the wrapper layer. I am submitting a patch back to the author now.

Basically, I am using a .NET wrapper for ETM called MET. In his implementation, he was assuming the TerrainInfo you pass in is the TerrainInfo reference you keep, that's not the case it seems. You copy the TerrainInfo, so if you don't directly call getTerrainInfo() again, you won't have the right one. He was just keeping his own reference and returning at as his TerrainInfo property. That won't work, you need to create the .NET wrapper with your getTerrainInfo() reference in aggregate.

It sort of sucks, because I am relying on an implementation detail, but it works :P

CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
x 57
Contact:

Post by CABAListic »

Yep, that's what I meant in my first post, heh. This will definitely change in the redesign for ETM v3, though.
I didn't even know there is a .NET wrapper, cool :)

Kerion
Goblin
Posts: 235
Joined: Wed Feb 05, 2003 5:49 am
Contact:

Post by Kerion »

http://www.ogre3d.org/phpBB2addons/viewtopic.php?t=6165 :)

It's sort of funny, because he released that wrapper as I was about 50% done with my own.

It's nice to be able to write my world editor in WinForms and use ETM for the terrain package :)

Kerion
Goblin
Posts: 235
Joined: Wed Feb 05, 2003 5:49 am
Contact:

Post by Kerion »

Now I have a far more interesting question. I am not sure if you have ever played with the NWN2 toolset, but one of the features the editor has in it's terrain package is "smoothing". It's somewhat like painting the terrain, but it sort of goes over the rough edges so to speak. It acts just like a regular brush, but smooths out edges, fills in any wierd gaps, etc. I am not really sure how better to explain it if you haven't actually used the tool and seen it.

Anyways, the point of all that, is I am curious if you had any advice on how to start a feature like that? I am guessing you would want to use some kind of procedural deform, that take in to account perhaps the ratios of angles between vertices? Maybe as the smooth tool passes over a patch, it checks the angle ratio between all the vertexes under it's area of effect, and lowers those ratios inside a certain threshold? That's a total shot in the dark, but it's all I could really think of.

User avatar
KungFooMasta
OGRE Contributor
OGRE Contributor
Posts: 2087
Joined: Thu Mar 03, 2005 7:11 am
Location: WA, USA
x 16
Contact:

Post by KungFooMasta »

CABAListic, I also have something I'd welcome your input on , regarding networking. If I remember right you haven't gotten to this stage yet, but you're still working on your RTS project right?

What I'm wondering is, using a client/server design, how can you update clients such that they only receive relevant updates? That is, they don't simulate the entire map even if its under the fog of war. The reason I'd want to do this is because packet sniffers could probably be used to maphack. (I say probably because I'm not familiar with what can be done with packet sniffing..) Is this feasible?

We're going to aim for having physics simulated on each client, but corrected every so often by the server. If you take a scenario where a rock or projectile is launched from an area outside your influence (under fog) and comes into your area of influence, this means the client would pretty much need to know about areas outside your influence, right?

I play WC3 occasionally, and it sucks knowing that a lot of people use maphack in pvp games. I'd like to eliminate cheating as much as possible.

What are your initial thoughts on this?
Creator of QuickGUI!

CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
x 57
Contact:

Post by CABAListic »

I'm by no means an expert on the subject of network, seeing as I've never done network for games before. But I'm afraid that map hacks (just like wall hacks for shooters) are problems which you might just have to accept you'll never fully extinguish. The situation for me is a lot easier because our game is a game of complete knowledge, i. e. there is no fog of war at all, therefore no one can use a map hack to gain an advantage. And I'm eliminating any other cheating possibility by using a deterministic gameplay where every client (there is actually no real server) computes the whole gameplay, and only player commands are transfered. If anyone were trying to cheat, the cheat would not be transmitted to the other clients and the game would just go out of sync.

For your situation, though, first of all you must realise that the server is the one place where cheats could be placed because it holds the ultimate command. Then, to actually follow your idea you would need to determine which objects might be relevant for a client between two consecutive updates. You'd probably need to take each entity (units, buildings, ...) owned by the player and determine all other entities whose distance to the player's entities is less than 1.5x the sight range (or something like that). And then you'd need to update these entities if necessary.

By the way, I don't actually think packet sniffers are the common route to do map hacks. The usual attack point is to just remove the fog of war display locally by hacking memory contents or the executable.

CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
x 57
Contact:

Post by CABAListic »

Kerion wrote:Now I have a far more interesting question. I am not sure if you have ever played with the NWN2 toolset, but one of the features the editor has in it's terrain package is "smoothing". It's somewhat like painting the terrain, but it sort of goes over the rough edges so to speak. It acts just like a regular brush, but smooths out edges, fills in any wierd gaps, etc. I am not really sure how better to explain it if you haven't actually used the tool and seen it.

Anyways, the point of all that, is I am curious if you had any advice on how to start a feature like that? I am guessing you would want to use some kind of procedural deform, that take in to account perhaps the ratios of angles between vertices? Maybe as the smooth tool passes over a patch, it checks the angle ratio between all the vertexes under it's area of effect, and lowers those ratios inside a certain threshold? That's a total shot in the dark, but it's all I could really think of.
Haven't actually tried that, but I would simply use a smoothing filter for the area you want to smooth. Probably a simple box filter would do.

Basically you'd retrieve the relevant area (+1 vertex at each side), copy it to a 2D array and apply the box filter (i. e. for each vertex height you sum the vertex's own height as well as the heights of the 8 surrounding heights and divide by 9), then set those values back to the terrain. You can also apply the filter multiple times if you want.

Kerion
Goblin
Posts: 235
Joined: Wed Feb 05, 2003 5:49 am
Contact:

Post by Kerion »

Now the trick is figuring out how to get the vertex data. I guess I can use PosToVertexX zn PosToVertexZ to get the vertex I am clicking on, then get all of it's adjacent vertexes. I just need to figure out what "get" entails at this point.

Kerion
Goblin
Posts: 235
Joined: Wed Feb 05, 2003 5:49 am
Contact:

Post by Kerion »

So I implemented a smooth function in TerrainManager. It basically does the same thing as deform, except rather than applying an intensity, it box filters all the vertexes under the brush. It's a big too much right now I think, I need a slightly smarter filter, but the idea is sound. It smooths, it just smooths a bit too much.

CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
x 57
Contact:

Post by CABAListic »

Well, I would have made the smoothing an external function, but anyway. If you want to less filtering, there's basically two things you can do:

1) Use less samples. Instead of summing all 8 surrounding heights, you can use just 4 (left, right, top, bottom).

2) Give more weight to the height of the vertex itself in contrast to the neighbours. For example, you could multiply its value by 4 or so. Of course, you'll have to divide by 13 now instead of 9.

User avatar
KungFooMasta
OGRE Contributor
OGRE Contributor
Posts: 2087
Joined: Thu Mar 03, 2005 7:11 am
Location: WA, USA
x 16
Contact:

Post by KungFooMasta »

Kerion: Can you share your implementation so others can benefit? Maybe it can be added to the terrain manager functionality?
Creator of QuickGUI!

Kerion
Goblin
Posts: 235
Joined: Wed Feb 05, 2003 5:49 am
Contact:

Post by Kerion »

How would you implement it externally? There is a call in deform to updateTiles that I can't call externally, if I change the heightmap data using at(), how do I tell the terrain manager it's been updated? Seems like it wouldn't update until the next time I called deform().

Post Reply