Blocks looked at are now highlighted

This commit is contained in:
OLEGSHA 2020-11-16 18:02:41 +03:00
parent b987412670
commit b51b3a4d80
11 changed files with 475 additions and 21 deletions

View File

@ -3,6 +3,7 @@ package ru.windcorp.progressia.client;
import ru.windcorp.progressia.client.comms.DefaultClientCommsListener;
import ru.windcorp.progressia.client.comms.ServerCommsChannel;
import ru.windcorp.progressia.client.graphics.world.Camera;
import ru.windcorp.progressia.client.graphics.world.LocalPlayer;
import ru.windcorp.progressia.client.world.WorldRender;
import ru.windcorp.progressia.common.world.WorldData;
import ru.windcorp.progressia.common.world.entity.EntityData;
@ -10,7 +11,7 @@ import ru.windcorp.progressia.common.world.entity.EntityData;
public class Client {
private final WorldRender world;
private EntityData localPlayer;
private LocalPlayer localPlayer;
private final Camera camera = new Camera((float) Math.toRadians(70));
@ -27,12 +28,12 @@ public class Client {
return world;
}
public EntityData getLocalPlayer() {
public LocalPlayer getLocalPlayer() {
return localPlayer;
}
public void setLocalPlayer(EntityData localPlayer) {
this.localPlayer = localPlayer;
this.localPlayer = new LocalPlayer(localPlayer);
}
public Camera getCamera() {

View File

@ -20,6 +20,7 @@ package ru.windcorp.progressia.client.graphics.world;
import java.util.ArrayList;
import java.util.List;
import glm.vec._3.i.Vec3i;
import ru.windcorp.progressia.client.Client;
import ru.windcorp.progressia.client.ClientState;
import ru.windcorp.progressia.client.comms.controls.InputBasedControls;
@ -65,6 +66,10 @@ public class LayerWorld extends Layer {
if (camera.hasAnchor()) {
renderWorld();
}
if (client.getLocalPlayer() != null) {
client.getLocalPlayer().update(client.getWorld());
}
}
private void renderWorld() {
@ -89,6 +94,7 @@ public class LayerWorld extends Layer {
try {
tmp_performCollisions(tickLength);
tmp_drawSelectionBox();
tmp_testControls.applyPlayerControls();
@ -122,13 +128,25 @@ public class LayerWorld extends Layer {
);
}
private void tmp_drawSelectionBox() {
LocalPlayer player = client.getLocalPlayer();
if (player == null) return;
Vec3i lookingAt = player.getLookingAt();
if (lookingAt == null) return;
helper.pushTransform().translate(lookingAt.x, lookingAt.y, lookingAt.z).scale(1.1f);
CollisionModelRenderer.renderCollisionModel(client.getWorld().getData().getCollisionModelOfBlock(lookingAt), helper);
helper.popTransform();
}
private void tmp_applyFriction(EntityData entity) {
final float frictionCoeff = 1 - 1e-5f;
entity.getVelocity().mul(frictionCoeff);
}
private void tmp_applyGravity(EntityData entity, float tickLength) {
if (ClientState.getInstance().getLocalPlayer() == entity && tmp_testControls.isFlying()) {
if (ClientState.getInstance().getLocalPlayer().getEntity() == entity && tmp_testControls.isFlying()) {
return;
}

View File

@ -0,0 +1,64 @@
package ru.windcorp.progressia.client.graphics.world;
import glm.vec._3.Vec3;
import glm.vec._3.i.Vec3i;
import ru.windcorp.progressia.client.world.WorldRender;
import ru.windcorp.progressia.client.world.entity.EntityRenderable;
import ru.windcorp.progressia.common.util.Vectors;
import ru.windcorp.progressia.common.world.BlockRay;
import ru.windcorp.progressia.common.world.Player;
import ru.windcorp.progressia.common.world.entity.EntityData;
public class LocalPlayer extends Player {
private Vec3i lookingAt = new Vec3i();
private boolean isLookingAtBlock = false;
private BlockRay lookingAtRay = new BlockRay();
public LocalPlayer(EntityData entity) {
super(entity);
}
public Vec3i getLookingAt() {
return isLookingAtBlock ? lookingAt : null;
}
public void update(WorldRender world) {
updateLookingAt(world);
}
private void updateLookingAt(WorldRender world) {
Vec3 direction = Vectors.grab3();
Vec3 start = Vectors.grab3();
BlockRay ray = lookingAtRay;
EntityData player = getEntity();
player.getLookingAtVector(direction);
world.getEntityRenderable(player).getViewPoint(start);
start.add(player.getPosition());
isLookingAtBlock = false;
for (ray.start(start, direction); ray.getDistance() < 6; ray.next()) {
Vec3i blockInWorld = ray.current();
if (world.getData().getCollisionModelOfBlock(blockInWorld) != null) {
isLookingAtBlock = true;
lookingAt.set(blockInWorld.x, blockInWorld.y, blockInWorld.z);
break;
}
}
ray.end();
Vectors.release(direction);
Vectors.release(start);
}
public EntityRenderable getRenderable(WorldRender world) {
return world.getEntityRenderable(getEntity());
}
}

View File

@ -3,12 +3,22 @@ package ru.windcorp.progressia.common.util;
import java.util.function.Consumer;
import glm.mat._4.Mat4;
import glm.vec._2.Vec2;
import glm.vec._2.d.Vec2d;
import glm.vec._2.i.Vec2i;
import glm.vec._3.Vec3;
import glm.vec._3.d.Vec3d;
import glm.vec._3.i.Vec3i;
import glm.vec._4.Vec4;
import glm.vec._4.d.Vec4d;
import glm.vec._4.i.Vec4i;
public class VectorUtil {
public static enum Axis {
X, Y, Z, W;
}
public static void forEachVectorInCuboid(
int x0, int y0, int z0,
int x1, int y1, int z1,
@ -47,6 +57,204 @@ public class VectorUtil {
inOut.set(vec4.x, vec4.y, vec4.z);
}
public static Vec3 linearCombination(
Vec3 va, float ka,
Vec3 vb, float kb,
Vec3 output
) {
output.set(
va.x * ka + vb.x * kb,
va.y * ka + vb.y * kb,
va.z * ka + vb.z * kb
);
return output;
}
public static Vec3 linearCombination(
Vec3 va, float ka,
Vec3 vb, float kb,
Vec3 vc, float kc,
Vec3 output
) {
output.set(
va.x * ka + vb.x * kb + vc.x * kc,
va.y * ka + vb.y * kb + vc.y * kc,
va.z * ka + vb.z * kb + vc.z * kc
);
return output;
}
public static float get(Vec2 v, Axis a) {
switch (a) {
case X: return v.x;
case Y: return v.y;
default: throw new IllegalArgumentException("Vec2 does not have axis " + a);
}
}
public static Vec2 set(Vec2 v, Axis a, float value) {
switch (a) {
case X: v.x = value; break;
case Y: v.y = value; break;
default: throw new IllegalArgumentException("Vec2 does not have axis " + a);
}
return v;
}
public static int get(Vec2i v, Axis a) {
switch (a) {
case X: return v.x;
case Y: return v.y;
default: throw new IllegalArgumentException("Vec2i does not have axis " + a);
}
}
public static Vec2i set(Vec2i v, Axis a, int value) {
switch (a) {
case X: v.x = value; break;
case Y: v.y = value; break;
default: throw new IllegalArgumentException("Vec2i does not have axis " + a);
}
return v;
}
public static double get(Vec2d v, Axis a) {
switch (a) {
case X: return v.x;
case Y: return v.y;
default: throw new IllegalArgumentException("Vec2d does not have axis " + a);
}
}
public static Vec2d set(Vec2d v, Axis a, double value) {
switch (a) {
case X: v.x = value; break;
case Y: v.y = value; break;
default: throw new IllegalArgumentException("Vec2d does not have axis " + a);
}
return v;
}
public static float get(Vec3 v, Axis a) {
switch (a) {
case X: return v.x;
case Y: return v.y;
case Z: return v.z;
default: throw new IllegalArgumentException("Vec3 does not have axis " + a);
}
}
public static Vec3 set(Vec3 v, Axis a, float value) {
switch (a) {
case X: v.x = value; break;
case Y: v.y = value; break;
case Z: v.z = value; break;
default: throw new IllegalArgumentException("Vec3 does not have axis " + a);
}
return v;
}
public static int get(Vec3i v, Axis a) {
switch (a) {
case X: return v.x;
case Y: return v.y;
case Z: return v.z;
default: throw new IllegalArgumentException("Vec3i does not have axis " + a);
}
}
public static Vec3i set(Vec3i v, Axis a, int value) {
switch (a) {
case X: v.x = value; break;
case Y: v.y = value; break;
case Z: v.z = value; break;
default: throw new IllegalArgumentException("Vec3i does not have axis " + a);
}
return v;
}
public static double get(Vec3d v, Axis a) {
switch (a) {
case X: return v.x;
case Y: return v.y;
case Z: return v.z;
default: throw new IllegalArgumentException("Vec3d does not have axis " + a);
}
}
public static Vec3d set(Vec3d v, Axis a, double value) {
switch (a) {
case X: v.x = value; break;
case Y: v.y = value; break;
case Z: v.z = value; break;
default: throw new IllegalArgumentException("Vec3d does not have axis " + a);
}
return v;
}
public static float get(Vec4 v, Axis a) {
switch (a) {
case X: return v.x;
case Y: return v.y;
case Z: return v.z;
case W: return v.w;
default: throw new IllegalArgumentException("Vec4 does not have axis " + a);
}
}
public static Vec4 set(Vec4 v, Axis a, float value) {
switch (a) {
case X: v.x = value; break;
case Y: v.y = value; break;
case Z: v.z = value; break;
case W: v.w = value; break;
default: throw new IllegalArgumentException("Vec4 does not have axis " + a);
}
return v;
}
public static int get(Vec4i v, Axis a) {
switch (a) {
case X: return v.x;
case Y: return v.y;
case Z: return v.z;
case W: return v.w;
default: throw new IllegalArgumentException("Vec4i does not have axis " + a);
}
}
public static Vec4i set(Vec4i v, Axis a, int value) {
switch (a) {
case X: v.x = value; break;
case Y: v.y = value; break;
case Z: v.z = value; break;
case W: v.w = value; break;
default: throw new IllegalArgumentException("Vec4i does not have axis " + a);
}
return v;
}
public static double get(Vec4d v, Axis a) {
switch (a) {
case X: return v.x;
case Y: return v.y;
case Z: return v.z;
case W: return v.w;
default: throw new IllegalArgumentException("Vec4d does not have axis " + a);
}
}
public static Vec4d set(Vec4d v, Axis a, double value) {
switch (a) {
case X: v.x = value; break;
case Y: v.y = value; break;
case Z: v.z = value; break;
case W: v.w = value; break;
default: throw new IllegalArgumentException("Vec4d does not have axis " + a);
}
return v;
}
private VectorUtil() {}
}

View File

@ -0,0 +1,123 @@
package ru.windcorp.progressia.common.world;
import glm.vec._3.Vec3;
import glm.vec._3.i.Vec3i;
import ru.windcorp.progressia.common.util.VectorUtil;
import ru.windcorp.progressia.common.util.VectorUtil.Axis;
import static java.lang.Math.*;
public class BlockRay {
private final Vec3 position = new Vec3();
private final Vec3 direction = new Vec3();
private float distance;
private final Vec3i block = new Vec3i();
private boolean isValid = false;
public void start(Vec3 position, Vec3 direction) {
if (!direction.any()) {
throw new IllegalArgumentException("Direction is a zero vector");
}
isValid = true;
this.position.set(position).sub(0.5f); // Make sure lattice points are block vertices, not centers
this.direction.set(direction).normalize();
this.block.set(toBlock(position.x), toBlock(position.y), toBlock(position.z));
this.distance = 0;
}
public void end() {
isValid = false;
}
public Vec3i next() {
checkState();
float tx = distanceToEdge(position.x, direction.x);
float ty = distanceToEdge(position.y, direction.y);
float tz = distanceToEdge(position.z, direction.z);
float tMin;
Axis axis;
if (tx < ty && tx < tz) {
tMin = tx;
axis = Axis.X;
} else if (ty < tx && ty < tz) {
tMin = ty;
axis = Axis.Y;
} else {
tMin = tz;
axis = Axis.Z;
}
// block.(axis) += signum(direction.(axis))
VectorUtil.set(block, axis, VectorUtil.get(block, axis) + (int) signum(VectorUtil.get(direction, axis)));
// position += direction * tMin
VectorUtil.linearCombination(position, 1, direction, tMin, position); // position += direction * tMin
distance += tMin;
// position.(axis) = round(position.(axis))
VectorUtil.set(position, axis, round(VectorUtil.get(position, axis)));
return block;
}
public Vec3i current() {
checkState();
return block;
}
private static float distanceToEdge(float c, float dir) {
if (dir == 0) return Float.POSITIVE_INFINITY;
float edge;
if (dir > 0) {
edge = strictCeil(c);
} else {
edge = strictFloor(c);
}
return (edge - c) / dir;
}
public float getDistance() {
checkState();
return distance;
}
private void checkState() {
if (!isValid) {
throw new IllegalStateException("BlockRay not started");
}
}
private static int toBlock(float c) {
return (int) round(c);
}
/**
* Returns a smallest integer <i>a</i> such that <i>a</i> > <i>c</i>.
* @param c the number to compute strict ceiling of
* @return the strict ceiling of <i>c</i>
*/
private static float strictCeil(float c) {
return (float) (floor(c) + 1);
}
/**
* Returns a largest integer <i>a</i> such that <i>a</i> < <i>c</i>.
* @param c the number to compute strict ceiling of
* @return the strict ceiling of <i>c</i>
*/
private static float strictFloor(float c) {
return (float) (ceil(c) - 1);
}
}

View File

@ -133,14 +133,6 @@ public class ChunkData {
}
if (!getPosition().any()) {
// EntityData javapony = EntityDataRegistry.getInstance().create("Test:Javapony");
// javapony.setEntityId(0x42);
// javapony.setPosition(new Vec3(-6, -6, 20));
// javapony.setDirection(new Vec2(
// (float) Math.toRadians(40), (float) Math.toRadians(45)
// ));
// getEntities().add(javapony);
EntityData player = EntityDataRegistry.getInstance().create("Test:Player");
player.setEntityId(0x42);
player.setPosition(new Vec3(-6, -6, 20));

View File

@ -0,0 +1,17 @@
package ru.windcorp.progressia.common.world;
import ru.windcorp.progressia.common.world.entity.EntityData;
public class Player {
private EntityData entity;
public Player(EntityData entity) {
this.entity = entity;
}
public EntityData getEntity() {
return entity;
}
}

View File

@ -119,5 +119,15 @@ public class EntityData extends StatefulObject implements Collideable {
public void changeVelocityOnCollision(Vec3 velocityChange) {
getVelocity().add(velocityChange);
}
public Vec3 getLookingAtVector(Vec3 output) {
output.set(
Math.cos(getPitch()) * Math.cos(getYaw()),
Math.cos(getPitch()) * Math.sin(getYaw()),
-Math.sin(getPitch())
);
return output;
}
}

View File

@ -53,7 +53,7 @@ public class CollisionModelRenderer {
}
public static void renderBlock(Vec3i coords, ShapeRenderHelper helper) {
helper.pushTransform().translate(coords.x, coords.y, coords.z);
helper.pushTransform().translate(coords.x, coords.y, coords.z).scale(0.25f);
CUBE_GRAY.render(helper);
helper.popTransform();
}

View File

@ -87,10 +87,6 @@ public class TestContent {
}
private static void registerEntities() {
// registerEntityData("Test", "Javapony", e -> e.setCollisionModel(new AABB(0, 0, -0.05f, 0.75f, 0.75f, 1.2f)));
// register(new TestEntityRenderJavapony());
// register(new EntityLogic("Test", "Javapony"));
float scale = 1.8f / 8;
registerEntityData("Test", "Player", e -> e.setCollisionModel(new AABB(0, 0, 4*scale, 0.75f, 0.75f, 1.8f)));
register(new TestEntityRenderHuman());
@ -121,6 +117,26 @@ public class TestContent {
server.getAdHocChanger().setBlock(z000, block);
}
});
// ControlDataRegistry.getInstance().register(new ControlData("Test", "BreakBlock"));
// ControlTriggerRegistry.getInstance().register(new ControlTriggerOnKeyPress("Test", "BreakBlock", new KeyMatcher(GLFW.GLFW_KEY_ENTER, new int[0], 0)::matches));
// ControlLogicRegistry.getInstance().register(new ControlLogic("Test", "BreakBlock") {
// @Override
// public void apply(Server server, PacketControl packet, Client client) {
// Vec3i z000 = new Vec3i(0, 0, 0);
//
// ChunkData data = server.getWorld().getChunk(z000).getData();
//
// BlockData block;
// if (data.getBlock(z000).getId().equals("Test:Stone")) {
// block = BlockDataRegistry.getInstance().get("Test:Glass");
// } else {
// block = BlockDataRegistry.getInstance().get("Test:Stone");
// }
//
// server.getAdHocChanger().setBlock(z000, block);
// }
// });
}
private static void register(BlockData x) {

View File

@ -13,6 +13,7 @@ import ru.windcorp.progressia.client.graphics.input.CursorMoveEvent;
import ru.windcorp.progressia.client.graphics.input.InputEvent;
import ru.windcorp.progressia.client.graphics.input.KeyEvent;
import ru.windcorp.progressia.client.graphics.input.bus.Input;
import ru.windcorp.progressia.client.graphics.world.LocalPlayer;
import ru.windcorp.progressia.common.Units;
import ru.windcorp.progressia.common.util.FloatMathUtils;
import ru.windcorp.progressia.common.util.Matrices;
@ -65,7 +66,7 @@ public class TestPlayerControls {
return;
}
EntityData player = getPlayer();
EntityData player = getEntity();
Mat3 angMat = Matrices.grab3();
angMat.identity().rotateZ(player.getYaw());
@ -185,7 +186,7 @@ public class TestPlayerControls {
}
private void jump() {
getPlayer().getVelocity().add(0, 0, JUMP_VELOCITY * (useMinecraftGravity ? 2 : 1));
getEntity().getVelocity().add(0, 0, JUMP_VELOCITY * (useMinecraftGravity ? 2 : 1));
}
private void handleShift(int multiplier) {
@ -223,7 +224,7 @@ public class TestPlayerControls {
final float yawScale = -0.002f;
final float pitchScale = yawScale;
EntityData player = getPlayer();
EntityData player = getEntity();
normalizeAngles(player.getDirection().add(
(float) (event.getChangeX() * yawScale),
@ -241,7 +242,11 @@ public class TestPlayerControls {
);
}
private EntityData getPlayer() {
private EntityData getEntity() {
return getPlayer().getEntity();
}
private LocalPlayer getPlayer() {
return ClientState.getInstance().getLocalPlayer();
}