Voxel - a start

Hi

When moving forward, the block in front needs to be checked.

When falling block below you is checked.

Just to note, when jumping forward, you can’t jump forward if there is a block there, but as soon as you are higher than the block you would then be able to move forward, then the block below you is the new ground height. So the block doesn’t stop you jumping, only jumping forward. The vertical component of your jump is unaffected by forward motion. As herosgrave mentioned its quadratic - but moving forward has no effect on you upward or downward movement.

Because they are cubes, ordered in a grid, I think just taking the int of your position tells you if you are in a block or not.

The only consideration for collision if you want your character to have a physical size and not be a point is that it has a bounding box, and you could test each corner.
This does created additional problems when moving towards the corner of a block.
AABB may be a good way to go. I may do that later, but there are others ways around that.

You also have to test more than one block if you character is higher than one block, in case you want to go under blocks!

Hi,

Not had time to look at my code yesterday.

I basically just check blocks that are all around you. The X below is a block and O is
the cameras position, so, as can be seen block on right is air and is the only place
we should be able to move to, unless we jump:

XXXXX
XO XX
XXXXX

Code below gets block to the left of the player:


int blockX = (int) Math.abs((pos.x/2) - 1);  // block to left of player 
int blockZ = (int) Math.abs((pos.z/2));
int blockY = (int) Math.abs(pos.y);

Remember pos.x, pos.z and pos.y is my camera’s vector position.
But, still not working…

Need to investigate.

Thanks,
Steve

Will have a think about this.
But I noticed that you have pos.x/2 is this because your blocks are 2 big?

if so, i found it easier to make my cubes like this… -0.5 to 0.5 rather than -1 to 1

also, if thats true , why dont you do pos.y/2 ?

I think you are checking the blocks to north,south,east , west etc of player… but you may need to instead check the
position of where the player would be if they moved forward, this may be at an angle, so you would check the x and z vector components.
Ill try and make a diagram tommorow.

Does your player move at an angle? or will they only move in 4 directions?

Sorry Ive not been much help!

I think the problem of the OP is, that he hasn’t his scales and directions set right.
You should always know exactly how big a voxel is, render-wise and logic-wise.
Also, you should know exactly where south/west/east/up/down/left/right/top/north/whatever is.
If you don’t know that, you will run into very big problems.

  • Longor1996

Edit:
Oh, and here’s a tipp: Do not use simple “Is Box in Box” checks for collision.
Use AABB/AABB velocity intersection. It work’s much better.
And it’s nerly fail-safe.

  • Longor1996

Thanks guys,

Think scales could be wrong. I’ve zipped project up and it just draws a couple of blocks, you can use space bar to get onto the block (note space just moves player up until you let go at the moment), wsad keys to move.

Yes, drawing blocks from -1.0 to 1.0 hence the divide by 2, just changed now to -0.5 to 0.5 :slight_smile:

Added project here if you care to look at the code?! I’d like the camera position set up better, think if you run the project you may see what I mean?

Many thanks, really, really appreciate your help guys.

PS - camera moves in all directions, so, yes player moves on diagonals.

Steve

I think it is my camera position that is incorrect when i turn around 180 degrees, how do you store your player position?

Thanks

How i store my player position?

I use an Player Entity Object.
In Puzzlez Project, every voxel occupies exactly 1 cubic meter.
Because of that, getting the voxel im standing on is very easy.


world.getVoxel((int)Math.floor(player.position.x),(int)Math.floor(player.position.y-1),(int)Math.floor(player.position.z));

The getVoxel method simply get’s the voxel at the given position.
Since all blocks are 1³, i just have to floor the coordinates component’s and put them into the getVoxel method.
It’s a really good idea to make your voxels 1³ big.
It also makes rendering a bit easier.

  • Longor1996

Wait, why do you need to know what block you are standing on?

Thanks @Longor1996

Didn’t think of using floor to get largest integer :wink:

Why need to know about what blocking standing on - to stop player falling through a cube?!

Why not use normal collision detection?

Thinking of giving up with this :-, just cannot see what I’m doing wrong, all I can think of is the scaling. This is how I set up the view matrix at the start:


gluPerspective(
				  45.0f,
				  (float) Display.getWidth() / (float) Display.getHeight(),
				  0.1f,
				  100.0f);

		GL11.glTranslatef(0, -2f, -1f);
		gluLookAt(0, 0, -2, 
				  0, 0, 0, 
				  0, 1, 0);

Does this look wrong? I’ve tried all manner of different values.

Thanks

It doesn’t matter how the view matrix and opengl are setup at all!
The problem is you collision detection. It doesn’t work!

You have to use AABB collision detection or something else.
It doesn’t work with simple “If Block under Plyer, Stop Falling” stuff.
That works only in 2D games.

  • Longor1996

It seems to be working for @Vermeer?!

This is what I read:


Take the players position vector and transform it into ‘voxel space’ coordinates.
Check if the voxel that corresponds to the player’s voxel position is currently active or not.
If the voxel IS active, it means the player is colliding with the world. since an active voxel is part of the world and should be collided with.

AABB something like:


bool CheckCollision(Block pBox1, Block pBox2)
{
    if(pBox1.xyz1.x > pBox2.xyz2.x) return false;
    if(pBox1.xyz1.y > pBox2.xyz2.y) return false;
    if(pBox1.xyz1.z > pBox2.xyz2.z) return false;
    if(pBox1.xyz2.x < pBox2.xyz1.x) return false;
    if(pBox1.xyz2.y < pBox2.xyz1.y) return false;
    if(pBox1.xyz2.z < pBox2.xyz1.z) return false;

    return true;
}


Thanks for your help.

I wrote a quicker AABB implementation a while ago.

http://www.java-gaming.org/index.php/topic,28059.0.html

It was made for 2D, but can be easily changed for 3D.

Hey thanks for that.

I guess, I need to find what block we are at and then do the AABB check?

Thanks,
Steve

Small video of how my voxel little project is looking now. Thanks to everybody for helping.


https://www.youtube.com/watch?v=aspN3ah0z7w

To do: Full collision detection, only draw chunks that are in view, block replacement and addition, plus lots more…

Trying to get a wire frame cube to be drawn just in front of camera (like camera is in center of it). I want this cube to move with the camera, got part of it working, but when turn past 45 degs, it doesn’t appear to be working.

I use this code to position the cube:


Vector3f pos = camera.getCameraPosition(); // get camera x,y,z position vector
float yrot = camera.getCameraYaw();  // get rotation on y-axis
float xpos = pos.x  + (float)Math.sin( Math.toRadians(yrot));
float zpos = pos.z + (float)Math.cos(Math.toRadians(yrot));
zpos -= 2;
cube.render(0.5f, -xpos, pos.y, -zpos,yrot);

Cube is then just translated with glTranslatef(x,y,z) in the cube.render function.

Anyway of keeping this cube in line with the camera position and rotation?

Link here to what is happening:


https://www.youtube.com/watch?v=t8dePWEkD74

Also, when placing a removing a block, I guess you need to take the camera’s position vector and its rotation to work out where block is to be placed?

Thanks

Try see if this works…

float xpos = pos.x +(float)Math.sin( Math.toRadians(yrot)) * amountToMove;
float zpos = pos.z +(float)Math.cos(Math.toRadians(yrot)) * amountToMove;

amountToMove is the block displacement from the player

But not this:
zpos -= 2;

You may also want to rotate that wireframe block with the yrot value as well so it maintains the same relative rotation to the player. It may even be -yrot!

You have this working for the block the player is holding… It should be no different?

Thanks @Vermeer,

I did this in the end:


                            Vector3f pos = camera.getCameraPosition();
			    double cameraPitchInRadians = Math.toRadians(camera.getCameraPitch());
			    double cameraYawInRadians = Math.toRadians(camera.getCameraYaw());
			    // coefficient - possibly not needed
			    float f = (float)Math.cos(cameraPitchInRadians);
			             
			    float newX = 6 * f * (float)Math.sin(cameraYawInRadians);
			    float newZ = 6 * f * (float)Math.cos(cameraYawInRadians);
			    float newY = 6 * (float)Math.sin(cameraPitchInRadians);
			  
			    newY += 1;
			    cube.render(0.5f, -newX + -(pos.x), newY + -(pos.y), newZ + -(pos.z),
						0);


As for the block player is holding, didn’t need any transformation, basically I did:


	player.updatePlayer(0, 0, camera.getCameraPosition(), camera.getWalkBias());

and in the updatePlayer, just used identity matrix and did a translation on Y with the walk bias.

My wireframe block I’ve put 3 blocks in front of the player, it moves as the player moves, but need it to move my blocks width at a time on x,y,z ( 16 units ).

Thanks,
Steve