Getting objects within a range (In order, fast)

Started by
27 comments, last by WozNZ 7 years, 11 months ago

It's called TreeSet in java, which leads to I didn't check its contents carefully, but it may be another way in

Advertisement

What you want is called a range search, and there are efficient data structures for it. A good one is the kd-tree, which has an efficient range search algorithm associated with it, so take a look at that if you have the time.

“If I understand the standard right it is legal and safe to do this but the resulting value could be anything.”

What you want is called a range search, and there are efficient data structures for it. A good one is the kd-tree, which has an efficient range search algorithm associated with it, so take a look at that if you have the time.

This is absolutely exactly what I was looking for. I couldn't thank you enough!

I'm making an open source voxel space game called V0xel_Sp4ce! Help me out with the repository here: https://github.com/SpikeViper/V0xel_Sp4ce

Okay, I have a kd-tree set up, but I have a minor problem. I now need to add all the positions (Vector3s) of chunks in the planet into this. Problem: Thats quite a few.

I'm using:


    public Vector3[] GetPoints()
    {



        List<Vector3> Vectors = new List<Vector3>();

        int x;
        int y;
        int z;

            for (x = 1; x < length - 1; x++)
            {
                for (y = 1; y < length - 1; y++)
                {
                    for (z = 1; x < length - 1; z++)
                    {

                    Vectors.Add(new Vector3(x, y, z));

                    }

                }

            }

        
        return Vectors.ToArray();
    }

But, since the length is 32... that's 32,768 chunks. And because of that, I'm throwing an "out of memory" error.

Any way to fix this? In order for the tree to work, it needs to know all the chunk positions.

I'm making an open source voxel space game called V0xel_Sp4ce! Help me out with the repository here: https://github.com/SpikeViper/V0xel_Sp4ce

How big are your chunks and why do you need them all in ram? I they are beyond a certain distance then dump them and load in the new ones hat are now in range. This can all happen in a background thread if done right and not effect the core game flow too much.

You have avoided the question ask by myself and many others here...

What do you mean by chunks, how big are they etc

Without knowing what it is you are manipulating it is harder to help

btw your array of vectors is

Vector = 3 * float = 12 bytes * 32768 = 384MB just for a vector list

You are adding these to a list so that keeps growing which is big churn then copy to an array after that.

If you then try and create 32768 chunks in ram (I assume meshes and data etc your memory demands will be big)

Very little ram required and lazy generation of vectors that are in range on demand

IEnumerable<Vector3> GetVisibleChunks(Vector3 playerLocation, int range)

{
Func<int, bool> isValid => n >=1 && n < length;

return

from x in Enumerable.Range(playerLocation.X - range, range * 2))

from y in Enumerable.Range(playerLocation.Y - range, range * 2))

from z in Enumerable.Range(playerLocation.Z - range, range * 2))

where isValid(x) && isvalid(y) && isValid(z)

select new Vector3(x, y, x);

}

For all

IEnumerable<Vector3> GetAllVectors()

{

return

from x in Enumerable.Range(1, length))

from y in Enumerable.Range(1, length))

from z in Enumerable.Range(1, length))

select new Vector3(x, y, x);

}

IEnumerable is your friend, saves the storage space and with lazy generation means only steps when you pull from it

Very little ram required and lazy generation of vectors that are in range on demand

IEnumerable<Vector3> GetVisibleChunks(Vector3 playerLocation, int range)

{
Func<int, bool> isValid => n >=1 && n < length;

return

from x in Enumerable.Range(playerLocation.X - range, range * 2))

from y in Enumerable.Range(playerLocation.Y - range, range * 2))

from z in Enumerable.Range(playerLocation.Z - range, range * 2))

where isValid(x) && isvalid(y) && isValid(z)

select new Vector3(x, y, x);

}

For all

IEnumerable<Vector3> GetAllVectors()

{

return

from x in Enumerable.Range(1, length))

from y in Enumerable.Range(1, length))

from z in Enumerable.Range(1, length))

select new Vector3(x, y, x);

}

IEnumerable is your friend, saves the storage space and with lazy generation means only steps when you pull from it

What's the language used here? I get errors on the => n >= 1 && n < length; and Enumerable is not found (when I try IEnumerable, it says Range is now found). Or is this just psuedocode?

I'm making an open source voxel space game called V0xel_Sp4ce! Help me out with the repository here: https://github.com/SpikeViper/V0xel_Sp4ce

New idea:

Instead of having the planet check for the player's position and loading its chunks near the player, how about have the player figure out which chunk it's within using the planet's position and then load chunk around it one at a time, layer by layer around the player. I'll see how this works. If you see a problem with this idea, tell me.

I'm making an open source voxel space game called V0xel_Sp4ce! Help me out with the repository here: https://github.com/SpikeViper/V0xel_Sp4ce

Hi,

My bad for the typo, was typed direct here and not in the ide lol

Func<int, bool> isValid = n >=1 && n < length;

As for length, I was re-using your "length" variable. If not in scope pass in as an extra param into the functions. I assumed these were some class members for which length was in scope

It is c# using Linq and Lamba which have been part of the language since VS2008 if memory serves me right :)

For Enumerable I think in System.Collections or the Generic version. Not sure the default command to pull in as I use resharper overlay on VS which does all that for me.

Word of warning, it will not debug in the flow you expect as it is all lazy on demand calculation. A great feature as you only do the work when it needs to be done. Depends on your use case though as to if you cache to a List/Array to save recalculation each time you walk the array

As for your comment about what is around the player, that is what the first linq example will do, it will give you all the vectors within Range distance of the plaer :)

This topic is closed to new replies.

Advertisement