Help with 3d array

Recommended Posts

mekrob    122
Hi all, thanks for taking the time to help me with my problem. I an currently in the process of programming my first directx game (a fps). The way I have chosen to do collision detection is to create a 3d array of integer values int[, ,] worldArray = new int[1000, 100, 1000]; and set the integer to 0 if an object is in that space (cannot walk there) or 1 if it is air (you can walk there). I have 3d cubes / rectangles loaded in from a map file which also sets the worldArray points within the cubes to 0 as they are loaded. So far I have no problem setting the worldArray values to 0's or 1's when loading my cubes / rectangles into the game. My problem is arising when I attemp to check the values within the 3d array. Any simple reference to a value within the array such as... writer.WriteLine(worldArray[10, 10, 10]); returns an unhandled exception "Object reference not set to an instance of an object." Is there a special way I need to retrieve the values in this 3d array so as to not cause this error to occur? Does anyone have any thoughts on this? I will check back frequently to answer any questions you may have. Thanks again, your help is much appreciated!

Share on other sites
Gage64    1235
The array access is correct, but are you sure 'writer' is not null? Are you sure that the exception states this line as the cause for the error? (double-check just in case...)

Share on other sites
mekrob    122

Its not just for writer, whenever I try to access it with anything. For instance, I am getting the same error this this...
if (_engine.worldArray[System.Convert.ToInt16(Decimal.Truncate(System.Convert.ToDecimal(_position.X))),                System.Convert.ToInt16(Decimal.Truncate(System.Convert.ToDecimal(_position.Y))),                 System.Convert.ToInt16(Decimal.Truncate(System.Convert.ToDecimal(_position.Z)))] == 0)            {                _position = _oldposition;            }

I also tried simplifying that if statement to this, but I get the same error...

 if ((_engine.worldArray [0,0,0]) == 0)             {                _position = _oldposition;            }

I know the 3d array is created and values are inputted to it before I am doing any checking. I'm very confused here >.<

Share on other sites
Gage64    1235
Any chance '_engine' is null?

Your best bet is to use the debugger. Before you step into the line that causes the exception, look at the variables that are being used in that line, and make sure none of them are null.

Share on other sites
Sneftel    1788
Quote:
 Original post by mekrobint[, ,] worldArray = new int[1000, 100, 1000];

You realize that that line allocates 400 megabytes of memory, right?
A 3D grid representation is not generally an appropriate solution for collision detection.

Share on other sites
mekrob    122
Sorry I just kinda sat down and came up with an idea to do collision detection. I should probably try to implement a more efficient method. What would you suggest? My map is only going to contain simple rectangular shapes. Should I check the position for being inside the coordinates of all cubes on the screen? I'm going to be using many different shaped cubes to create a 3d map, so I did not think this would be the most efficient method.

Share on other sites
Sneftel    1788
The most efficient and popular method would be a hierarchical spatial culling structure such as an octree or BSP tree. These are a little difficult to implement, but will produce the best results. Failing that, yes, I would suggest brute-force testing against each volume. This will be inefficient for very large scenes, but it's easy to get working (easier than the grid representation) and you can swap it out later on.

Share on other sites
To see if the problem is one of concept or memory, what about reducing it down to 10,10,10?

That way, you can test your code to see if it is working properly.

Share on other sites
mekrob    122
Thanks for everyones help. I have decided to rethink how I am doing collision detection. I have all the code written but now I have come across an unusual problem.

I have created an array that will hold the center point of every cube in the map as well as the distance from the center to each side. I have created this new struct / array in my Camera class, however it is necessary for me to atler it in my terrain class. I have set a break point at my code in my terrain class where it is setting the values in this array, and it seems to set everything correctly. Then after setting the values in the array, it returns to the camera class and starts checking the values in this array, however they are all set to 0 for some reason!

Is there any reason these values in the array would not transfer between classes?

Here is where I set the values in the terrain class

 _camera.collisionarray[on_cube] = new Camera.collision ((p1.X + ((p4.X - p1.X) / 2)), (pb1.Y + (((p1.Y - pb1.Y) / 2))),                        (p1.Z + (((p2.Z - p1.Z) / 2))), ((p4.X - p1.X) / 2), ((p1.Y - pb1.Y) / 2), ((p2.Z - p1.Z) / 2));

Here is my collision check in my camera class

public bool checkCollision()        {            _collision = false;            for (int i = 0; i < collisionarray.Length; i++)            {                                if ((_position.X < (collisionarray[i].X + collisionarray[i].DX))                    &&                    (_position.X > (collisionarray[i].X - collisionarray[i].DX))                    &&                    (_position.Y < (collisionarray[i].Y + collisionarray[i].DY))                    &&                    (_position.Y > (collisionarray[i].Y - collisionarray[i].DY))                    &&                    (_position.Z < (collisionarray[i].Z + collisionarray[i].DZ))                    &&                    (_position.Z > (collisionarray[i].Z - collisionarray[i].DZ)))                {                    _collision = true;                }                             }return _collision;}

And here is my struct in my camera class

    public struct collision        {            public float X, Y, Z;            public float DX, DY, DZ;            public collision(float _X, float _Y, float _Z, float _DX, float _DY, float _DZ)            {                X = _X; Y = _Y; Z = _Z;                DX = _DX; DY = _DY; DZ = _DZ;            }        }

Thanks again for the help! It is very much appreciated.

[Edited by - mekrob on July 7, 2007 5:33:47 PM]