Added hit stuff, but it doesn't work yet.

This commit is contained in:
Andrew Lalis 2022-07-15 20:40:56 +02:00
parent 2ebf5ad1bf
commit 236a421296
5 changed files with 71 additions and 15 deletions

View File

@ -0,0 +1,13 @@
package nl.andrewl.aos_core;
import org.joml.Vector3i;
import org.joml.Vector3ic;
public class Directions {
public static final Vector3ic UP = new Vector3i(0, 1, 0);
public static final Vector3ic DOWN = new Vector3i(0, -1, 0);
public static final Vector3ic NEGATIVE_X = new Vector3i(-1, 0, 0);
public static final Vector3ic POSITIVE_X = new Vector3i(1, 0, 0);
public static final Vector3ic NEGATIVE_Z = new Vector3i(0, 0, -1);
public static final Vector3ic POSITIVE_Z = new Vector3i(0, 0, 1);
}

View File

@ -0,0 +1,13 @@
package nl.andrewl.aos_core.model;
import org.joml.Vector3i;
import org.joml.Vector3ic;
/**
* Represents the point at which a ray hits a block, often used when casting a
* ray from a player's location to see if they break or place a block.
*/
public record Hit (
Vector3i pos,
Vector3ic norm
) {}

View File

@ -1,5 +1,6 @@
package nl.andrewl.aos_core.model; package nl.andrewl.aos_core.model;
import nl.andrewl.aos_core.Directions;
import org.joml.Math; import org.joml.Math;
import org.joml.Vector3f; import org.joml.Vector3f;
import org.joml.Vector3i; import org.joml.Vector3i;
@ -95,7 +96,7 @@ public class World {
* @return The location of the block that is looked at, or null if none * @return The location of the block that is looked at, or null if none
* could be found. * could be found.
*/ */
public Vector3i getLookingAtPos(Vector3f eyePos, Vector3f eyeDir, float limit) { public Hit getLookingAtPos(Vector3f eyePos, Vector3f eyeDir, float limit) {
if (eyeDir.lengthSquared() == 0 || limit <= 0) return null; if (eyeDir.lengthSquared() == 0 || limit <= 0) return null;
Vector3f pos = new Vector3f(eyePos); Vector3f pos = new Vector3f(eyePos);
Vector3f movement = new Vector3f(); // Pre-allocate this vector. Vector3f movement = new Vector3f(); // Pre-allocate this vector.
@ -120,11 +121,22 @@ public class World {
movement.set(eyeDir).mul(minFactor); movement.set(eyeDir).mul(minFactor);
pos.add(movement); pos.add(movement);
if (getBlockAt(pos) > 0) { if (getBlockAt(pos) > 0) {
return new Vector3i( Vector3f prevPos = new Vector3f(pos).sub(movement);
Vector3i hitPos = new Vector3i(
(int) Math.floor(pos.x), (int) Math.floor(pos.x),
(int) Math.floor(pos.y), (int) Math.floor(pos.y),
(int) Math.floor(pos.z) (int) Math.floor(pos.z)
); );
Vector3ic hitNorm = null;
if (prevPos.y > hitPos.y + 1) hitNorm = Directions.UP;
else if (prevPos.y < hitPos.y) hitNorm = Directions.DOWN;
else if (prevPos.x > hitPos.x + 1) hitNorm = Directions.POSITIVE_X;
else if (prevPos.x < hitPos.x) hitNorm = Directions.NEGATIVE_X;
else if (prevPos.z > hitPos.z + 1) hitNorm = Directions.POSITIVE_Z;
else if (prevPos.z < hitPos.z) hitNorm = Directions.NEGATIVE_Z;
return new Hit(hitPos, hitNorm);
} }
} }
return null; return null;

View File

@ -1,6 +1,8 @@
package nl.andrewl.aos_core.net.udp; package nl.andrewl.aos_core.net.udp;
import nl.andrewl.aos_core.model.World;
import nl.andrewl.record_net.Message; import nl.andrewl.record_net.Message;
import org.joml.Vector3i;
/** /**
* A message that's sent to clients when a block in a chunk is updated. * A message that's sent to clients when a block in a chunk is updated.
@ -16,4 +18,14 @@ public record ChunkUpdateMessage(
int cx, int cy, int cz, int cx, int cy, int cz,
int lx, int ly, int lz, int lx, int ly, int lz,
byte newBlock byte newBlock
) implements Message {} ) implements Message {
public static ChunkUpdateMessage fromWorld(Vector3i worldPos, World world) {
Vector3i chunkPos = World.getChunkPosAt(worldPos);
Vector3i localPos = World.getLocalPosAt(worldPos);
return new ChunkUpdateMessage(
chunkPos.x, chunkPos.y, chunkPos.z,
localPos.x, localPos.y, localPos.z,
world.getBlockAt(worldPos.x, worldPos.y, worldPos.z)
);
}
}

View File

@ -1,6 +1,5 @@
package nl.andrewl.aos2_server; package nl.andrewl.aos2_server;
import nl.andrewl.aos_core.model.Chunk;
import nl.andrewl.aos_core.model.Player; import nl.andrewl.aos_core.model.Player;
import nl.andrewl.aos_core.model.World; import nl.andrewl.aos_core.model.World;
import nl.andrewl.aos_core.net.udp.ChunkUpdateMessage; import nl.andrewl.aos_core.net.udp.ChunkUpdateMessage;
@ -63,18 +62,25 @@ public class ServerPlayer extends Player {
if (lastInputState.hitting() && now - lastBlockRemovedAt > BLOCK_REMOVE_COOLDOWN) { if (lastInputState.hitting() && now - lastBlockRemovedAt > BLOCK_REMOVE_COOLDOWN) {
Vector3f eyePos = new Vector3f(position); Vector3f eyePos = new Vector3f(position);
eyePos.y += getEyeHeight(); eyePos.y += getEyeHeight();
Vector3i targetPos = world.getLookingAtPos(eyePos, viewVector, 10); var hit = world.getLookingAtPos(eyePos, viewVector, 10);
System.out.println(targetPos); System.out.println(hit);
if (targetPos != null) { if (hit != null) {
Vector3i chunkPos = World.getChunkPosAt(targetPos); world.setBlockAt(hit.pos().x, hit.pos().y, hit.pos().z, (byte) 0);
Vector3i localPos = World.getLocalPosAt(targetPos);
world.setBlockAt(targetPos.x, targetPos.y, targetPos.z, (byte) 0);
lastBlockRemovedAt = now; lastBlockRemovedAt = now;
server.getPlayerManager().broadcastUdpMessage(new ChunkUpdateMessage( server.getPlayerManager().broadcastUdpMessage(ChunkUpdateMessage.fromWorld(hit.pos(), world));
chunkPos.x, chunkPos.y, chunkPos.z, }
localPos.x, localPos.y, localPos.z, }
(byte) 0 if (lastInputState.interacting() && now - lastBlockRemovedAt > BLOCK_REMOVE_COOLDOWN) {
)); Vector3f eyePos = new Vector3f(position);
eyePos.y += getEyeHeight();
var hit = world.getLookingAtPos(eyePos, viewVector, 10);
System.out.println(hit);
if (hit != null) {
Vector3i placePos = new Vector3i(hit.pos());
placePos.add(hit.norm());
world.setBlockAt(placePos.x, placePos.y, placePos.z, (byte) 1);
lastBlockRemovedAt = now;
server.getPlayerManager().broadcastUdpMessage(ChunkUpdateMessage.fromWorld(placePos, world));
} }
} }
tickMovement(dt, world); tickMovement(dt, world);