Different terrain scales

Jan 3, 2008 at 10:55 AM
Hi, I'm currently using the Quickstart engine to create a rowing machine game (later for use with a rowing machine, but thats not important now). The problem I'm having is thinking of a way to create a longer terrain as apposed to a square terrain such as 1024x1024. This is because the user can row for different distances and a square shaped terrain is not ideal, as the terrain meets the skybox and doesn't look right. I've tried just inputting different size terrain and height maps but this doesn't work with anything other than same size height and width.

Any help would be appreciated. (I couldn't find any other helpful resources so I apologise if this is the wrong place).

Thanks

Nick.


Coordinator
Jan 3, 2008 at 3:13 PM
Creating a terrain that isn't a power-of-two is width and length would require a complete re-write of the terrain system. In fact, I've never seen a non power-of-two terrain before. What most games do is have their square terrain area, and use barriers, or geographical features to block off the parts they do not want the player to go to.

It is possible to have entire worlds there aren't 'square' by having multiple terrains together in an arrangement that isn't square, like having 8 terrain sections in a 4x2 arrangement. In the new engine we're working on allowing multiple scenes, and each scene can have a terrain section, so this would be possible at that time.
Jan 3, 2008 at 5:25 PM
I think this is something that needs to be addressed in greater detail. I perfectly understand the power-of-two limitation and agree that it'll stay. What I don't really agree with is the requirement that it be square. A terrain size of 256 x 4096 should be handled by the engine without having to resort to multiple scenes. Of course this would require a modified culling technique, but I think it's something we need to seriously consider. For the 256 x 4096 example, it's feasible to have the users create 4096 x 4096 maps with barriers, but you're looking at a lot of wasted memory to store geometry and texture data that will never be used.
Coordinator
Jan 3, 2008 at 5:36 PM
Either way it will require a re-write. You'll notice that there is no height and width variables in the terrain system, only width. I guess I've never run into a situation that required a non-square terrain, so I didn't really design for it. I'm not sure how this would affect all of the algorithms associated with creating the indices and vertices. It would definitely add some time to work on the terrain component further.

I agree we need to decide if this issue is big enough to go back and take the time to work on it.
Jan 3, 2008 at 5:53 PM
We already have one person who wants it, and I agree with Shaws view on memory wastage. I dont think its pressing enough for the 0.19 release, I would prefer to see basic AI or physics before it. Just my two-pence.
Jan 3, 2008 at 6:59 PM
OK, looks like I can just make the scale smaller and move the boat at a smaller scale. If I create one edge of the scene to match the beginning I can simply transform the boat back to the start. Problem is with a river, its hard to just simply put models and scenery to block the user looking down the river and into the skybox as it should always be river which is pretty much straight. A think a simple way would be to modify the camera angles to avoid looking straight down the river and lock it at an angle?

Cheers

Nick
Jan 3, 2008 at 8:05 PM
I agree with Mike, we should get the new engine in a working state before we tackle rectangular terrains. Just off the top of my head, I'd say the easiest way to handle it would be to split it up into length / width cubes of edge length width, assuming length > width. This partitioning could be used instead of a true quad tree for rectangular terrains.
Jan 4, 2008 at 6:07 AM
I created this Arbitrary Terrain size issue for it and assigned it for the 0.20 release (It's assigned to LordIkon).
Coordinator
Jan 4, 2008 at 3:50 PM
One thing to consider is that if we do this then we cannot require that a scene manager use a quad-tree (at least not from terrain). I have no idea how to setup a quad-tree on a terrain that is not square.

Unless I find a way to do quad-tree on rectangular terrain sizes.

If I could not use a quad-tree in all situations then it would require a re-write of about 80% of the terrain. As you may have noticed, the terrain class itself doesn't generate its own vertices or indices, it leaves that up to the quad-tree and terrainpatch classes.
Jan 4, 2008 at 5:27 PM
In my oppinion the editor shouldn't care about the type of terrain, just as it doesn't care about the type of entity placed in the scene.
Feb 28, 2008 at 6:49 PM
Edited Feb 28, 2008 at 6:50 PM
Hi, Im back again - I fixed the problem as suggested by LordIkon, I've created an array of terrains in a 2x4 grid of 256x256 terrains. The only problem I now have is not being able to work out the culling techniques used and for some reason parts of the terrains are being culled.

e.g.

http://img238.imageshack.us/my.php?image=fitnessgame1hp9.jpg

The terrain is set up as an array:

Terrain[] terrains = new Terrain[7];

All the loading is then done on each terrain as before

terrains[0].Initialize("./Images/Heightmaps/test1", "./Images/Terrainmaps/test2", 1, 25, 0, 0);
terrains[1].Initialize("./Images/Heightmaps/test2", "./Images/Terrainmaps/test1", 1, 25, 0, gridSize);

Any ideas or help again appreciated :)

Nick.
Coordinator
Feb 28, 2008 at 9:16 PM
It is tough to say, as your project has new stuff we haven't used before. I'd check the bounding box of the root quadtree node of the terrain sections that aren't appearing, and make sure they're in the appropriate spots. If that box is invalid it will get culled out.

It has been awhile since I used 0.182b, but there should be a way to show all bounding boxes by commenting something back in. Somewhere in terrain or quadtree classes you should see something about boundingBoxDebug or something similar, it was my way of testing the quadtree stuff when I was creating it, and I believe I left it in.

Additionally, it could be the way you're cycling through your terrains to check them for culling.

It may not even be a culling issue either. You may be able to hardcode a value in the culling so that when it checks if something is in view you simply always return true. This way all terrain gets drawn all the time. This is a performance hit, but may work good for testing.
Mar 4, 2008 at 11:18 AM
Fixed it now, just edited the bounding boxes to fit the individule terrains. Thanks and great work on the engine :)

Nick.
Mar 4, 2008 at 1:15 PM
Hey Nick. I don't mean to leech off your hard work, but could you perhaps share the secret to how you got multiple terrains going. It's not my top priority but I'll be able to get rid of about 90% of unused polygons... which I'll then make up to make the map 16 times as detailed.

Thanks,
Gary

Addendum :

If you're wondering how I could possibly use 10 times more polygons than I need to, here is the heightmap: http://img257.imageshack.us/my.php?image=earth4il5.png

Because of the square constraint, the lower two thirds remain unused. As of the third percent that is used, 70% of that is always underwater. (I keep my reflection much higher than the refraction so the abyss isn't visible anyway).
Mar 5, 2008 at 11:56 AM
Edited Mar 5, 2008 at 12:01 PM
Sorry double post, see below
Mar 5, 2008 at 12:00 PM
Edited Mar 6, 2008 at 11:18 AM
I managed to do it quite easily, I'm not saying this is the greatest way to do it just one way I found.

Well if you are using 0.182b then it went rather like this

Initialize the terrains into an array (placed mine at the top of the GameMain class)

        // Terrain variables -----------------------------------------------------------------
 
        const int gridAmount = 7; // Number of terrains in the grid
 
        // Create an array of terrains for the grid
        Terrain[] terrains = new Terrain [gridAmount];
 
        int gridSize = 255; // The width and height of each grid needed for the shifting
 
        // -----------------------------------------------------------------------------------
 


Then within the LoadTerrain() method in GameMain this was how I loaded mine

 
for (int i = 0; i < gridAmount; i++)
            {
                terrains[i] = new Terrain(Device, Content, LOD.Med);
 
                terrains[i].SetElevationStrength(20);                       // Changes elevation strength
                terrains[i].InitTerrainTextures("./Textures/grass", "./Textures/rock", "./Textures/sand");
 
                if (CommonVars.QSDetail == GraphicsLevel.High)
                    terrains[i].InitTerrainNormalsTextures("./Textures/grassNormal", "./Textures/rockNormal", "./Textures/sandNormal");
            }
            
            // ====================================== Load height and terrain maps ==================================
            
            // Load a grid of terrains (height and terrain path, scaler value, smoothing value, shiftX, shiftY)
            // Shift the terrain along the x and y axis to generate a grid
            //         [0][1] 
            //         [2][3] 
            //         [4][5] 
            //         [6][7] 
            terrains[0].Initialize("./Images/Heightmaps/test1", "./Images/Terrainmaps/test2", 1, 25, 0, 0);
            terrains[1].Initialize("./Images/Heightmaps/test2", "./Images/Terrainmaps/test1", 1, 25, 0, gridSize);
            terrains[2].Initialize("./Images/Heightmaps/test1", "./Images/Terrainmaps/test2", 1, 25, gridSize, 0);
            terrains[3].Initialize("./Images/Heightmaps/test2", "./Images/Terrainmaps/test1", 1, 25, gridSize, gridSize);
            terrains[4].Initialize("./Images/Heightmaps/test1", "./Images/Terrainmaps/test2", 1, 25, gridSize * 2, 0 );
            terrains[5].Initialize("./Images/Heightmaps/test2", "./Images/Terrainmaps/test1", 1, 25, gridSize * 2, gridSize);
            terrains[6].Initialize("./Images/Heightmaps/test1", "./Images/Terrainmaps/test2", 1, 25, gridSize * 3, 0);
 
            // ======================================================================================================
 
            // Loop through all the terrains and add them to the component manager
            for (int i = 0; i < gridAmount; i++)
            {
                // Setup a very low LOD terrain. This will allow the water
                // component to use a very low detail terrain for faster
                // rendering. This terrain is not the default unless specific
                // seperately, so the terrain will continue to render at
                // its default setting, this merely sets up a second LOD terrain
                // for use by other components.
                terrains[i].AddNew(LOD.Low);
 
                // Sets up the LOD arrays to allow for new LODs later on.
                terrains[i].SetupLODS();
 
 
                AddComponent(terrains[i]);
            }
 

So once the terrains are initialized you loop through them all giving them specific values.

I added 2 parameters on the end of the terrains.Initialize call, this shifts the X and Y position of the terrain which is called by the vertex buffer method via the Initialize method in Terrains class.

Change the Terrains Initialize class to

public void Initialize(string HeightImagePath, string TerrainTexturePath, int scale, int shiftX, int shiftY)

and this code within it to

SetupTerrainVertexBuffer(shiftX, shiftY); // Quad-tree sections have setup the vertex list, now this creates a buffer.

This is the updated SetupTerrainVertexBuffer method within the terrain class containing the parameters x and y called from the terrain class (above)

 
 private void SetupTerrainVertexBuffer(int x, int y)
        {
            VertexTerrain[] verticesArray = new VertexTerrain{"[TerrainVertices.Count]"};
 
            for (int i = 0; i < TerrainVertices.Count; i++)
            {
                // Load in the terrain data loaded by XNA to create customizable terrain
                verticesArray[i] = TerrainVertices[i];
 
                // Shift the terrain along the x and y to form a grid
                verticesArray[i].Position.X += x;
                verticesArray[i].Position.Y += y;
            }
 
            TerrainVertexBuffer = new VertexBuffer(Device, VertexTerrain.SizeInBytes * (MapWidth + (MapWidth / CommonVars.QUAD_TREE_WIDTH)) * (MapHeight + (MapHeight /                                CommonVars.QUAD_TREE_WIDTH)), ResourceUsage.WriteOnly, ResourceManagementMode.Automatic);
            TerrainVertexBuffer.SetData(verticesArray);
 
            //TerrainVertices.Clear();
        }
 

Its not 100% clear because of the limits of the formatting but I hope you get a rough idea
Mar 5, 2008 at 7:51 PM
Just FYI: you can use double curly brackets to produce code sections, like

{ {
This is a code section
} }

produces (removing the space between the brackets).

    This is a code section
Mar 6, 2008 at 7:26 AM
Nick, you're my hero.
Mar 6, 2008 at 2:19 PM
I implemented your code and ammended most references to it so it is now quasi-functional.

I do have one nagging little question though. The engine seems to not be drawing parts of the second map: http://img509.imageshack.us/my.php?image=cullerrorcu9.jpg

I recall you had a similar problem and I'm wondering how you fixed it. I really did try but I don't know the first thing about quad trees and the like.

Sorry to be bothering you (again).

Gary

Addendum:
For what it's worth, the physics seem to work on those parts of the map not drawn.
Coordinator
Mar 6, 2008 at 2:50 PM
I believe the issue was related to the bounding boxes for those sections of terrain not being in the right place for whatever reason. It sounded like in his post he repositioned them somehow. If the bounding box doesn't line up properly then that box may not be considered to be in the frustum and that terrain will get culled.

The big question is why aren't the bounding boxes in the right place? If one of you would like to upload your project I will take a look.
Mar 6, 2008 at 3:38 PM


LordIkon wrote:
I believe the issue was related to the bounding boxes for those sections of terrain not being in the right place for whatever reason. It sounded like in his post he repositioned them somehow. If the bounding box doesn't line up properly then that box may not be considered to be in the frustum and that terrain will get culled.

The big question is why aren't the bounding boxes in the right place? If one of you would like to upload your project I will take a look.


I caught that it had something to do with bounding boxes, but like I said, that stuff is far beyond my (very narrow) area of expertise.

I don't mean to sound like a small child or like I'm co-dependant (or both), but I'd only be able to get it right with some code examples.

As for an upload, do you know of a site where one can upload files. Just let me know and I'll stick it up. I should warn you though, my code is very messy and my comments incoherent, but most of the stuff I edited are minor so you probably won't run into them.

Thanks,
Gary
Coordinator
Mar 7, 2008 at 4:39 AM
You could zip up your source, and resources, and email them (if it is under 10mb). Source most certainly is, but your heightmap and terrain map images might not be depending on what type and quality you're using.
Mar 7, 2008 at 6:46 AM
I'll see what I can do. At the moment my entire project is about over 200 mb. Thankfully I can exclude the bin folder which in itself is 170 mb. That leaves me with 30-something mb with which I'll have to sift through the resources I'm no longer using and remove them. No problem but it might take some time.
Mar 7, 2008 at 7:40 AM
All done, compressed to a nice 6mb.

So where should I send it to?
Coordinator
Mar 8, 2008 at 4:17 AM
lordikon82@hotmail.com. I'd have you send it to my gmail, but it is picky about specific file extensions, hotmail is just easier.
Mar 8, 2008 at 6:31 AM
It's sent. If it's not a problem for you, I'd prefer if you replied on this discussion board rather than my e-mail address. I rarely check that one, and besided someone else may benefit from the info being public.

Oh yeah, and thanks a lot for all the attention. I realise that you don't get paid for this so I just want to say I really appreciate it.

Gary
Coordinator
Mar 11, 2008 at 3:54 PM
No problem, I replied already before I saw this, basically just letting you know that I'm pretty busy with work related stuff, but I hope to look at this within a few days.
Mar 11, 2008 at 4:09 PM
Greatly appreciated.
Mar 12, 2008 at 11:10 AM
I tried what you suggested on the other thread with the bounding boxes. It was quite a mission but in the end I got it running.

I'm happy to report that now each terrain is surrounded by its own bounding box... but the second one still gets culled.

I've attached graphic evidence: http://img521.imageshack.us/my.php?image=cullboundboxna3.jpg

Gary
Coordinator
Mar 12, 2008 at 1:25 PM
I'm confused as to the problem? In the pictures are there missing boxes? If so then they're not being culled at the right time. The culling should work such that you never notice the boxes disappear, as they only do so right when they're off screen.

As to the strange reflection, that should be due to the bounding boxes being enabled and the sky being disabled, return those to normal after the terrain is acting normal and you should get your water reflection working right again.
Mar 12, 2008 at 2:32 PM
I figured out the reflection story, don't worry.

But I have no idea what's cooking with the culling or the bounding boxes.

That's all I can add from my side.