Skip to content

Commit

Permalink
Place block
Browse files Browse the repository at this point in the history
  • Loading branch information
squid233 committed Apr 12, 2024
1 parent faebf66 commit a0571d9
Show file tree
Hide file tree
Showing 4 changed files with 201 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@
import io.github.xenfork.freeworld.client.render.gl.GLStateMgr;
import io.github.xenfork.freeworld.client.render.world.HitResult;
import io.github.xenfork.freeworld.core.registry.BuiltinRegistries;
import io.github.xenfork.freeworld.util.Direction;
import io.github.xenfork.freeworld.util.Logging;
import io.github.xenfork.freeworld.util.Timer;
import io.github.xenfork.freeworld.world.World;
import io.github.xenfork.freeworld.world.block.BlockType;
import io.github.xenfork.freeworld.world.block.BlockTypes;
import io.github.xenfork.freeworld.world.entity.Entity;
import io.github.xenfork.freeworld.world.entity.EntityTypes;
Expand Down Expand Up @@ -64,6 +66,8 @@ public final class Freeworld implements AutoCloseable {
private World world;
private Entity player;
private int blockDestroyTimer = 0;
private int blockPlaceTimer = 0;
private int selectBlock = 0;

private Freeworld() {
this.glfw = GLFW.INSTANCE;
Expand Down Expand Up @@ -132,6 +136,13 @@ private void onKey(int key, int scancode, int action, int mods) {
}
}
}
case GLFW.PRESS -> {
switch (key) {
case GLFW.KEY_1 -> selectBlock = 0;
case GLFW.KEY_2 -> selectBlock = 1;
case GLFW.KEY_3 -> selectBlock = 2;
}
}
}
}

Expand Down Expand Up @@ -187,7 +198,30 @@ private void tick() {
blockDestroyTimer = 0;
}
}
if (blockPlaceTimer >= 3) {
final HitResult hitResult = gameRenderer.hitResult();
if (!hitResult.missed() &&
glfw.getMouseButton(window, GLFW.MOUSE_BUTTON_RIGHT) == GLFW.PRESS) {
final Direction face = hitResult.face();
final BlockType type = switch (selectBlock) {
case 0 -> BlockTypes.STONE;
case 1 -> BlockTypes.DIRT;
case 2 -> BlockTypes.GRASS_BLOCK;
default -> BlockTypes.AIR;
};
if (!type.air()) {
world.setBlockType(
hitResult.x() + face.axisX(),
hitResult.y() + face.axisY(),
hitResult.z() + face.axisZ(),
type
);
}
blockPlaceTimer = 0;
}
}
blockDestroyTimer++;
blockPlaceTimer++;
}

private void initGL() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import io.github.xenfork.freeworld.client.render.world.WorldRenderer;
import io.github.xenfork.freeworld.core.Identifier;
import io.github.xenfork.freeworld.core.math.AABBox;
import io.github.xenfork.freeworld.util.Direction;
import io.github.xenfork.freeworld.util.Logging;
import org.joml.Matrix4f;
import org.slf4j.Logger;
Expand Down Expand Up @@ -52,7 +53,7 @@ public final class GameRenderer implements GLResource {
private BlockRenderer blockRenderer;
private WorldRenderer worldRenderer;
private Tessellator tessellator;
private HitResult hitResult = new HitResult(null, 0, 0, 0, true);
private HitResult hitResult = new HitResult(true, null, 0, 0, 0, Direction.SOUTH);

public GameRenderer(Freeworld client) {
this.client = client;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,19 @@

package io.github.xenfork.freeworld.client.render.world;

import io.github.xenfork.freeworld.util.Direction;
import io.github.xenfork.freeworld.world.block.BlockType;

/**
* @author squid233
* @since 0.1.0
*/
public record HitResult(
boolean missed,
BlockType blockType,
int x,
int y,
int z,
boolean missed
Direction face
) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ public HitResult selectBlock() {
int nearestX = 0;
int nearestY = 0;
int nearestZ = 0;
Direction face = Direction.SOUTH;

final float radius = 5.0f;
final float radiusSquared = radius * radius;
Expand Down Expand Up @@ -187,13 +188,173 @@ public HitResult selectBlock() {
nearestX = x;
nearestY = y;
nearestZ = z;
face = detectFace(
ox,
oy,
oz,
frustumRayDir.x(),
frustumRayDir.y(),
frustumRayDir.z(),
box
);
}
}
}
}
}

return new HitResult(nearestBlock, nearestX, nearestY, nearestZ, nearestBlock == null);
// TODO: 2024/4/12 squid233: detect face
return new HitResult(nearestBlock == null, nearestBlock, nearestX, nearestY, nearestZ, face);
}

private Direction detectFace(
double originX,
double originY,
double originZ,
double dirX,
double dirY,
double dirZ,
AABBox box
) {
double t = -1.0;
Direction direction = Direction.SOUTH;
for (Direction dir : Direction.LIST) {
final double v = rayFace(dir, originX, originY, originZ, dirX, dirY, dirZ, box);
if (v > t) {
t = v;
direction = dir;
}
}
return direction;
}

private double rayFace(
Direction direction,
double originX,
double originY,
double originZ,
double dirX,
double dirY,
double dirZ,
AABBox box
) {
final double epsilon = 0.001;
final double minX = box.minX();
final double minY = box.minY();
final double minZ = box.minZ();
final double maxX = box.maxX();
final double maxY = box.maxY();
final double maxZ = box.maxZ();
return switch (direction) {
case WEST -> Math.max(
Intersectiond.intersectRayTriangleFront(
originX, originY, originZ,
dirX, dirY, dirZ,
minX, maxY, minZ,
minX, minY, minZ,
minX, minY, maxZ,
epsilon
),
Intersectiond.intersectRayTriangleFront(
originX, originY, originZ,
dirX, dirY, dirZ,
minX, minY, maxZ,
minX, maxY, maxZ,
minX, maxY, minZ,
epsilon
)
);
case EAST -> Math.max(
Intersectiond.intersectRayTriangleFront(
originX, originY, originZ,
dirX, dirY, dirZ,
maxX, maxY, maxZ,
maxX, minY, maxZ,
maxX, minY, minZ,
epsilon
),
Intersectiond.intersectRayTriangleFront(
originX, originY, originZ,
dirX, dirY, dirZ,
maxX, minY, minZ,
maxX, maxY, minZ,
maxX, maxY, maxZ,
epsilon
)
);
case DOWN -> Math.max(
Intersectiond.intersectRayTriangleFront(
originX, originY, originZ,
dirX, dirY, dirZ,
minX, minY, maxZ,
minX, minY, minZ,
maxX, minY, minZ,
epsilon
),
Intersectiond.intersectRayTriangleFront(
originX, originY, originZ,
dirX, dirY, dirZ,
maxX, minY, minZ,
maxX, minY, maxZ,
minX, minY, maxZ,
epsilon
)
);
case UP -> Math.max(
Intersectiond.intersectRayTriangleFront(
originX, originY, originZ,
dirX, dirY, dirZ,
minX, maxY, minZ,
minX, maxY, maxZ,
maxX, maxY, maxZ,
epsilon
),
Intersectiond.intersectRayTriangleFront(
originX, originY, originZ,
dirX, dirY, dirZ,
maxX, maxY, maxZ,
maxX, maxY, minZ,
minX, maxY, minZ,
epsilon
)
);
case NORTH -> Math.max(
Intersectiond.intersectRayTriangleFront(
originX, originY, originZ,
dirX, dirY, dirZ,
maxX, maxY, minZ,
maxX, minY, minZ,
minX, minY, minZ,
epsilon
),
Intersectiond.intersectRayTriangleFront(
originX, originY, originZ,
dirX, dirY, dirZ,
minX, minY, minZ,
minX, maxY, minZ,
maxX, maxY, minZ,
epsilon
)
);
case SOUTH -> Math.max(
Intersectiond.intersectRayTriangleFront(
originX, originY, originZ,
dirX, dirY, dirZ,
minX, maxY, maxZ,
minX, minY, maxZ,
maxX, minY, maxZ,
epsilon
),
Intersectiond.intersectRayTriangleFront(
originX, originY, originZ,
dirX, dirY, dirZ,
maxX, minY, maxZ,
maxX, maxY, maxZ,
minX, maxY, maxZ,
epsilon
)
);
};
}

@Override
Expand Down

0 comments on commit a0571d9

Please sign in to comment.