(Will be putting a bounty on this - Also, I'm not 100% sure what tags are relevant for this)
I'm incredibly confused here. I am attempting to use this (simplified) model for my archers to collide with:
However, as you can see, my archers appear to be colliding in mid-air! I would understand if they fell through (e.g. I had not put enough "points" in my collision model), but to actually appear to be colliding with NOTHING is absolutely baffling me.
I'm loading the model on the server with the same code that I'm displaying it there in the client, so that can't be the issue. I've pastebinned it here anyway.
Then, I'm adding it to three int[]
arrays, like this:
coordsx = new int[80 * 10];
coordsy = new int[80 * 10];
coordsz = new int[80 * 10];
for (javax.vecmath.Vector3f vec : m.getVertices()){ //Quick note: M is a model. As you can see, I'm just going through all the vertex positions.
coordsx[DELTA+(int) vec.x] = 1;
coordsy[DELTA+(int) vec.y] = 1;
coordsz[DELTA+(int) vec.z] = 1;
}
Quick note: DELTA is the value of ((80 * 10) / 2)
or to save you the math, 400
. Also, I used three int[]
's and not an int[][][]
because an int[][][]
caused an OutOfMemory
which I couldn't fix.
Now that I have got these arrays of coordinates, I'm using this code to check it:
for (int x = (int) (location.x + 1); x > location.x - 1; x--){
for (int y = (int) (location.y + 1); y > location.y - 1; y--){
for (int z = (int) (location.z + 1); z > location.z - 1; z--){
distancex = x;
distancez = z;
distancey = y;
try{
int i = 0;
if (owner.type == 0){
if (GameServer.DELTA + distancex > 0 && GameServer.DELTA + distancex < 800 && GameServer.coordsx[(int) (GameServer.DELTA + distancex)] == 1){
if (GameServer.DELTA + distancey > 0 && GameServer.DELTA + distancey < 800 && GameServer.coordsy[(int) (GameServer.DELTA + distancey)] == 1){
if (GameServer.DELTA + distancez > 0 && GameServer.DELTA + distancez < 800 && GameServer.coordsz[(int) (GameServer.DELTA + distancez)] == 1){
i = 1;
}
}
}
}
if (i == 1){
collision = true;
YDown = 0;
}
}catch (ArrayIndexOutOfBoundsException e1){
e1.printStackTrace();
}
}
}
}
if (collision){
System.out.println("Collision!");
}else{
System.out.println("No Collision!");
location.y = location.y-=YDown;
}
location
is a Vector3f
of the archers' X, Y, and Z relative to the ship's location - I've checked this using de-bug messages, and the location is indeed returning correctly.
As you can see, the variable i
is only being set to 1 if there is a coordinate at both the X, Y, and Z location of the point that is being checked. Obviously, I am iterating through all the nearby coordinates as well, since my player is not just a single point.
Since the player appears to be colliding with air, then there is obviously something wrong. But I cannot find what.
Am I on the right track here, or am I doing everything entirely wrong? And if I am on the right track, then what is going wrong here and how can I fix it?
There is a problem with your model. Using three arrays may save memory, but it also changes the model, creating "shadows" that your archers can collide with.
Let's say that you have vertices in (1,1,1) and (2,2,2). Using your model, there will also a vertex at (1,2,2) and any other combination where all coordinates is either 1 or 2.
So, back to the drawing board.
Maybe you can save memory by using a single bit instead of a 32 bit int
for each coordinate?
Or you could change the way you store the model. What if you use a 2-dimensional array of int
and store the z-coordinate(s) of the floor. This would limit your world to one (or just a few) floors at each x,y-coordinate but would save a huge amount of memory.