Block Raycasting

I am having a problem with ray casting. I basically do the collision the same way the tutorial did it. I instantiate a Ray like this:



[java]Ray ray = new Ray(cam.getLocation(), cam.getDirection());[/java]



Then I do the CollisionResults, blah, blah, blah. The code is basically copied and pasted from the tutorial.

After I get the first collision point, I have my problem. I try to detect which block in the array it is from the point and I can’t. The reason why is that two blocks share each face, even though some blocks are air blocks. If I just cast the values to int’s and try to set it in the array, it only works for some sides.



After I discovered that this was my problem, I tried to detect the block using this code:

[java]int chunkX = (int) contactPoint.x / Chunk.SIZE_X;

int chunkY = (int) contactPoint.y / Chunk.SIZE_Y;

int chunkZ = (int) contactPoint.z / Chunk.SIZE_Z;





Vector3i chunk = new Vector3i(chunkX * Chunk.SIZE_X, chunkY * Chunk.SIZE_Y, chunkZ * Chunk.SIZE_Z);



Vector3i block = new Vector3i((int)Math.abs(contactPoint.x - chunkXChunk.SIZE_X),

(int)Math.abs(contactPoint.y - chunkY
Chunk.SIZE_Y),

(int)Math.abs(contactPoint.z - chunkZChunk.SIZE_Z));



if (chunks.get(chunk).getBlock(block) != Blocks.AIR)

chunks.get(chunk).removeBlock(block);

else {

Vector3f direction = r.getDirection().normalize();

direction.multLocal(0.001f,0.001f,-0.001f);

Vector3f newContactPoint = contactPoint.add(direction);



chunkX = (int) newContactPoint.x / Chunk.SIZE_X;

chunkY = (int) newContactPoint.y / Chunk.SIZE_Y;

chunkZ = (int) newContactPoint.z / Chunk.SIZE_Z;



chunk = new Vector3i (chunkX * Chunk.SIZE_X, chunkY
Chunk.SIZE_Y,chunkZChunk.SIZE_Z);



block = new Vector3i((int)Math.abs(newContactPoint.x - chunkX
Chunk.SIZE_X),

(int)Math.abs(newContactPoint.y - chunkYChunk.SIZE_Y),

(int)Math.abs(newContactPoint.z - chunkZ
Chunk.SIZE_Z));

chunks.get(chunk).removeBlock(block); // chunks is a hashmap of all the chunks.

}[/java]



My idea here was to extrapolate along the ray by a very small amount. This still yields almost the same results.



Does anyone have any ideas on the best approach to this or some other advice?

Also, my first collision test takes forever (literally about 4 or 5 seconds). I can avoid this by doing some random collision test in the init method, but does anyone know why this happens and how to stop it?

Thanks.

The first collision test takes a long time because JME has to build the collision data. Which for a block world is going to be pretty redundant and inefficient.



Since I don’t know how you are structuring your world, I can’t comment on better ways using the JME approach. I suspect most block worlds would just do their own collision detection since doing hit detection on the sides of grid aligned blocks is pretty straight forward.



Note: this is exactly one of the reasons I tell people that block worlds are not the “easier” way to build a game as a lot of new-comers think. Block worlds are actually much harder than regular 3D games. None of the regular approaches work well and the flexibility of the model makes them impractical anyway.

1 Like

Block worlds (particularly minecraft style with low res textures) are very light on graphics artist/modelling time. Not so much for the programmers though :slight_smile:

@zarch said:
Block worlds (particularly minecraft style with low res textures) are very light on graphics artist/modelling time. Not so much for the programmers though :)


Yeah seriously. This is much harder than just normal terrain. Only 16x16 pixel textures when it comes to minecraft lol.
@joey-watts-96 said:
Yeah seriously. This is much harder than just normal terrain. Only 16x16 pixel textures when it comes to minecraft lol.


Yeah, a block world will challenge every 3D programming skill in some way. And larger textures do require a little more artistic skill I guess... certainly more time than a few blips on a 16x16 grid does.

And in case it wasn't already known, I speak from experience: http://mythruna.com
@pspeed said:
The first collision test takes a long time because JME has to build the collision data. Which for a block world is going to be pretty redundant and inefficient.

Since I don't know how you are structuring your world, I can't comment on better ways using the JME approach. I suspect most block worlds would just do their own collision detection since doing hit detection on the sides of grid aligned blocks is pretty straight forward.

Note: this is exactly one of the reasons I tell people that block worlds are not the "easier" way to build a game as a lot of new-comers think. Block worlds are actually much harder than regular 3D games. None of the regular approaches work well and the flexibility of the model makes them impractical anyway.


Thanks for the input. I guess I'll start restructuring this. Should I still use JBullet without directly calling collideWith on the node or just forget it altogether? I was thinking to still use it to check for collisions against some BoundingBox's.