Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

Dark GDK / How to write a QuadTree...?

Author
Message
Zeal
22
Years of Service
User Offline
Joined: 10th Oct 2002
Location: Colorado Springs, CO
Posted: 17th May 2006 18:09
Im trying to divide my 1km x 1km terrain sectors into 16x16 smaller sub sectors so I can better place grass and trees. I understand the concept of a quad tree, dividing sectors into quarters untill you can safely rule out all the children. However, I dont understand how you 'write' it.

Dont laugh, but I wrote it out long hand to try and better understand it. The following code cuts up one of my 1km square sectors into 16x16 sub sectors (storing the results in sector[][]).



After staring at the code for some time I just dont see how you can close those loops. I might want to subdivide into smaller sectors, and I sure as hell dont want to have to keep writing my code like that.

I know there is a better way to write it, I just cant see it.

Help!

All you need is zeal
Barnski
18
Years of Service
User Offline
Joined: 26th Jan 2006
Location: Switzerland, Zurich
Posted: 17th May 2006 20:23
Assuming you have a global 2d array sector[][], you can write a linked quad tree that refers to entries of that array. However, you could also make it binary, if you you change the orientation of splitting each time (horizontal -> vertical -> h -> v...).

Search in the binary tree will only take log(n) time.

Each node of the binary tree will have "pointers" to its boundaries within the array, and of course two children.

When creating the Tree, you recursively create the nodes until you reach the desired elementary size (e.g. 16x16 units).
For your children you simply halve the size of the parent (array boundaries), using the apropriate line (horiz/vert, e.g. you pass a value, when it is odd you do horizontal, else vert..).

Would this solve your problem? If so, we can go on discuss it.

Zeal
22
Years of Service
User Offline
Joined: 10th Oct 2002
Location: Colorado Springs, CO
Posted: 18th May 2006 05:04
Hmm dont quite understand what you mean by binary tree. Can you whip up some pseudo code? All I want to do is cut a area into quarters untill its safe to say its 'out of view'. Then flag all children from that point on as out of view. Can you show me how that would look in your system?

All you need is zeal
Barnski
18
Years of Service
User Offline
Joined: 26th Jan 2006
Location: Switzerland, Zurich
Posted: 19th May 2006 00:32
Lets stick to the quad tree, as it is easier to define the children.

The main thing are the QuadNode and QuadLeaf classes (or structs if you prefer).



So well, thats the datastructure.. Now for creating it, you would start at the top level, the root: create a new QuadNode, and link it with a variable "root" ... which has the border of the entire map.

Then create 4 sub-nodes, which respective quarters of the map, and set the array entries of the parent-node (e.g. root-node) to the object-pointers.

Repeat the last until your nodes cover an apropriately sized region of the map. Now create 4 QuadLeaves instead of Nodes, and add to the object list the grass_obj_ids, or any other things you like.

Add any flags to the classes you like.
Thats all about the QuadTree.

Actually I wonder if you can't simply use a 2d-array, which maps the bigger 2d-map sector-wise, such that each entry represents a sector on the map. To get the coordinates you simply make integer division of the map-coordinate with the sector-width.
I am not sure what you actually want at this point

Zeal
22
Years of Service
User Offline
Joined: 10th Oct 2002
Location: Colorado Springs, CO
Posted: 19th May 2006 01:48
Quote: "Actually I wonder if you can't simply use a 2d-array, which maps the bigger 2d-map sector-wise, such that each entry represents a sector on the map."


Yeah I imagine there should be a simple solution as well. As for "What I actually want", just imagine you had a 1km x 1km area. Now I want to frustum cull that area into 16x16 sub sectors.

Would it be possible to code that with a basic 2d array and some division/for loops? Or do you need a complex class with children, linking, ect...

All you need is zeal
Lost in Thought
20
Years of Service
User Offline
Joined: 4th Feb 2004
Location: U.S.A. : Douglas, Georgia
Posted: 19th May 2006 02:22 Edited at: 19th May 2006 02:35
The quadtree on terrains is not that hard as the divisions of polys are evenly spaced (you can make sure each poly is in only 1 zone). Levels are what mess up my quadtree where the polys are not evenly spaced on the x-z axi. You can setup your terrain for octrees easily for for next loops since you know the layout of your terrain.

Say your terrain is 64 limbs wide by 64 limbs deep. You would need 5(or 4) layers of quadtrees, though you could go all the way down to 7 levels to be perfect 1 box per limb. 1 huge box(not cube) to cover the entire terrain. You can skip this level if you want as DBP already does object culling. Then break this box up into 4 even boxes on the x-z axi and size the y to the max-min vert of polys inside it. Break each one of these up into 4 the same way (giving you 16 total on this level). And break each of thos 16 up the same way (giving you 64) and so on until you want to stop or there is 1 box per limb.

Now all while doing this you will want to keep track of each level's root-node relation ships. The first level will simple be assigned a value to test by "root". The second will be assigned a 2 dim array in case you have more than on object to test. Assign the first dim to root and the second to node names 1-4 or 0-3 like the bottom left sector will be (root,0), the bottom right (root,1) and so on. the next level will need a 3dim array to keep things organised (root, 2nd_level_node_its_in, 3rd_level_node). Keep up this pattern until you get to the botom level. I use UDT's to keep the arrays simple (one array can store the bounds and level node info like this).

You will now need to modify the culling code you have to check and see if the bounding box is either totally outside the frustum, partially in/outside, or totally inside. If it is totally inside or outside there is no need checking any of the nodes inside them. If it is partially in/outside the take it to the next level.

I am totally open to any other suggestions though as I said this only works for terrains. I would really like to see a great culling system for DBP and DSDK.

[edit] Make sure when you make your terrains to make them powers of 2 wide and deep. Instead of like the advanced terrain which is (powers of 2)-1. So with a power of 2 system you can make this awesome culling with even trees (1,4,16, etc), yet with the advanced terrain you have to make a ghetto system (1,9,15,etc) to line up with the limbs

Zeal
22
Years of Service
User Offline
Joined: 10th Oct 2002
Location: Colorado Springs, CO
Posted: 19th May 2006 03:54
Hmm im still not sure how to write it. Take a look at the code I posted (it works btw). Tell me how its possible to 'compress' all those loops. How can I make it neater.

I understand the theory, but short of a complex class, I dont see how it can be written any differently than what I did above.

All you need is zeal
Lost in Thought
20
Years of Service
User Offline
Joined: 4th Feb 2004
Location: U.S.A. : Douglas, Georgia
Posted: 19th May 2006 04:02
Well with my rusty almost non-existant c++ skills, that looks almost greek. I can post a DBP version of what I said when I get time. I'll have to re-write it myself as I scrapped it, because of it not working with unever objects. I am looking for a one code does it all (for every type of object) system to post. Which I haven't found yet. I am leaning towards a node sharing system though with each limb being able to occupy more than one node. If you need a version for terrains in a hurry, I'll re-write it as it worked great for that. If you can wait I am going to post the other system when I get it working. It'll be a couple of days min either way though.

I don't have any info or background for binary trees though. I'll have another look at the code you posted.

Zeal
22
Years of Service
User Offline
Joined: 10th Oct 2002
Location: Colorado Springs, CO
Posted: 19th May 2006 04:19
Yeah I can still read basic, that would be great!

All you need is zeal
Lost in Thought
20
Years of Service
User Offline
Joined: 4th Feb 2004
Location: U.S.A. : Douglas, Georgia
Posted: 19th May 2006 04:26
Does DGSDK have the vertex manip commands? If not I'll convert it over to memblock code instead.

Zeal
22
Years of Service
User Offline
Joined: 10th Oct 2002
Location: Colorado Springs, CO
Posted: 19th May 2006 04:41
Yeah it has those. It doesnt even have to be workign code, even pseudo code would be fine

All you need is zeal
Zeal
22
Years of Service
User Offline
Joined: 10th Oct 2002
Location: Colorado Springs, CO
Posted: 21st May 2006 07:39
Quote: "Actually I wonder if you can't simply use a 2d-array, which maps the bigger 2d-map sector-wise, such that each entry represents a sector on the map. To get the coordinates you simply make integer division of the map-coordinate with the sector-width."


Ive been giving this some more thought, and I think a single 2d array (made up of the smallest elements in the tree, 16x16 in this case) would work fine for my project. I know there is a pattern in the above code I wrote, if I could just figure out how to close all those loops, I wouldnt need anything fancy beyond that.

Will give it another go tomorrow

All you need is zeal

Login to post a reply

Server time is: 2024-11-19 06:45:10
Your offset time is: 2024-11-19 06:45:10