Refactored Camera to use anchors
- Camera now uses anchor objects to obtain position and direction - Replaceable at runtime - Anchor supplies info about camera modes (switch with F5) - Only Entity anchor implemented ATM - Added PacketSetLocalPlayer - EntityRenders now produce EntityRenderable - Holds reference to EntityData - Has getViewPoint() to use with camera anchors - Added Matrices (like Vectors) - Added FloatMathUtils for all those pesky math functions that are only implemented for double. Curse you double!
This commit is contained in:
parent
c613bef8c5
commit
ccc9d8f3a7
@ -1,6 +1,5 @@
|
|||||||
package ru.windcorp.progressia.client;
|
package ru.windcorp.progressia.client;
|
||||||
|
|
||||||
import glm.vec._3.Vec3;
|
|
||||||
import ru.windcorp.progressia.client.comms.DefaultClientCommsListener;
|
import ru.windcorp.progressia.client.comms.DefaultClientCommsListener;
|
||||||
import ru.windcorp.progressia.client.comms.ServerCommsChannel;
|
import ru.windcorp.progressia.client.comms.ServerCommsChannel;
|
||||||
import ru.windcorp.progressia.client.graphics.world.Camera;
|
import ru.windcorp.progressia.client.graphics.world.Camera;
|
||||||
@ -13,11 +12,7 @@ public class Client {
|
|||||||
private final WorldRender world;
|
private final WorldRender world;
|
||||||
private EntityData localPlayer;
|
private EntityData localPlayer;
|
||||||
|
|
||||||
private final Camera camera = new Camera(
|
private final Camera camera = new Camera((float) Math.toRadians(70));
|
||||||
new Vec3(-6, -6, 20),
|
|
||||||
(float) Math.toRadians(-40), (float) Math.toRadians(-45),
|
|
||||||
(float) Math.toRadians(70)
|
|
||||||
);
|
|
||||||
|
|
||||||
private final ServerCommsChannel comms;
|
private final ServerCommsChannel comms;
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package ru.windcorp.progressia.client;
|
package ru.windcorp.progressia.client;
|
||||||
|
|
||||||
import glm.vec._3.i.Vec3i;
|
|
||||||
import ru.windcorp.progressia.client.comms.localhost.LocalServerCommsChannel;
|
import ru.windcorp.progressia.client.comms.localhost.LocalServerCommsChannel;
|
||||||
import ru.windcorp.progressia.client.graphics.GUI;
|
import ru.windcorp.progressia.client.graphics.GUI;
|
||||||
import ru.windcorp.progressia.client.graphics.flat.LayerTestUI;
|
import ru.windcorp.progressia.client.graphics.flat.LayerTestUI;
|
||||||
@ -24,14 +23,15 @@ public class ClientState {
|
|||||||
public static void connectToLocalServer() {
|
public static void connectToLocalServer() {
|
||||||
|
|
||||||
WorldData world = new WorldData();
|
WorldData world = new WorldData();
|
||||||
Client client = new Client(world, new LocalServerCommsChannel(
|
|
||||||
ServerState.getInstance()
|
|
||||||
));
|
|
||||||
|
|
||||||
client.setLocalPlayer(
|
LocalServerCommsChannel channel = new LocalServerCommsChannel(
|
||||||
world.getChunk(new Vec3i(0, 0, 0)).getEntities().get(0)
|
ServerState.getInstance()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Client client = new Client(world, channel);
|
||||||
|
|
||||||
|
channel.connect();
|
||||||
|
|
||||||
setInstance(client);
|
setInstance(client);
|
||||||
|
|
||||||
GUI.addBottomLayer(new LayerWorld(client));
|
GUI.addBottomLayer(new LayerWorld(client));
|
||||||
|
@ -18,6 +18,7 @@ import ru.windcorp.progressia.client.graphics.texture.Texture;
|
|||||||
import ru.windcorp.progressia.client.graphics.world.WorldRenderProgram;
|
import ru.windcorp.progressia.client.graphics.world.WorldRenderProgram;
|
||||||
import ru.windcorp.progressia.client.world.entity.EntityRender;
|
import ru.windcorp.progressia.client.world.entity.EntityRender;
|
||||||
import ru.windcorp.progressia.client.world.entity.EntityRenderRegistry;
|
import ru.windcorp.progressia.client.world.entity.EntityRenderRegistry;
|
||||||
|
import ru.windcorp.progressia.client.world.entity.EntityRenderable;
|
||||||
import ru.windcorp.progressia.client.world.entity.QuadripedModel;
|
import ru.windcorp.progressia.client.world.entity.QuadripedModel;
|
||||||
import ru.windcorp.progressia.common.world.block.BlockFace;
|
import ru.windcorp.progressia.common.world.block.BlockFace;
|
||||||
import ru.windcorp.progressia.common.world.entity.EntityData;
|
import ru.windcorp.progressia.common.world.entity.EntityData;
|
||||||
@ -313,13 +314,13 @@ public class TestEntityRenderJavapony extends EntityRender {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Renderable createRenderable(EntityData entity) {
|
public EntityRenderable createRenderable(EntityData entity) {
|
||||||
return new QuadripedModel(
|
return new QuadripedModel(
|
||||||
entity,
|
entity,
|
||||||
|
|
||||||
new QuadripedModel.Body(body),
|
new QuadripedModel.Body(body),
|
||||||
new QuadripedModel.Head(
|
new QuadripedModel.Head(
|
||||||
head, new Vec3(12, 0, 20), 60, 45
|
head, new Vec3(12, 0, 20), 60, 45, new Vec3(16, 0, 20)
|
||||||
),
|
),
|
||||||
new QuadripedModel.Leg(
|
new QuadripedModel.Leg(
|
||||||
leftForeLeg, new Vec3( 6, +8.1f, -16), 0.0f
|
leftForeLeg, new Vec3( 6, +8.1f, -16), 0.0f
|
||||||
|
@ -1,12 +1,18 @@
|
|||||||
package ru.windcorp.progressia.client.comms;
|
package ru.windcorp.progressia.client.comms;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import ru.windcorp.progressia.client.Client;
|
import ru.windcorp.progressia.client.Client;
|
||||||
|
import ru.windcorp.progressia.client.graphics.world.EntityAnchor;
|
||||||
import ru.windcorp.progressia.client.world.ChunkRender;
|
import ru.windcorp.progressia.client.world.ChunkRender;
|
||||||
import ru.windcorp.progressia.common.comms.CommsListener;
|
import ru.windcorp.progressia.common.comms.CommsListener;
|
||||||
import ru.windcorp.progressia.common.comms.packets.Packet;
|
import ru.windcorp.progressia.common.comms.packets.Packet;
|
||||||
|
import ru.windcorp.progressia.common.comms.packets.PacketSetLocalPlayer;
|
||||||
import ru.windcorp.progressia.common.comms.packets.PacketWorldChange;
|
import ru.windcorp.progressia.common.comms.packets.PacketWorldChange;
|
||||||
|
import ru.windcorp.progressia.common.world.ChunkData;
|
||||||
|
import ru.windcorp.progressia.common.world.entity.EntityData;
|
||||||
|
|
||||||
public class DefaultClientCommsListener implements CommsListener {
|
public class DefaultClientCommsListener implements CommsListener {
|
||||||
|
|
||||||
@ -24,9 +30,41 @@ public class DefaultClientCommsListener implements CommsListener {
|
|||||||
);
|
);
|
||||||
|
|
||||||
tmp_reassembleWorld();
|
tmp_reassembleWorld();
|
||||||
|
} else if (packet instanceof PacketSetLocalPlayer) {
|
||||||
|
setLocalPlayer((PacketSetLocalPlayer) packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setLocalPlayer(PacketSetLocalPlayer packet) {
|
||||||
|
UUID uuid = packet.getLocalPlayerEntityUUID();
|
||||||
|
|
||||||
|
Collection<ChunkData> chunks =
|
||||||
|
getClient().getWorld().getData().getChunks();
|
||||||
|
|
||||||
|
EntityData entity = null;
|
||||||
|
|
||||||
|
synchronized (chunks) {
|
||||||
|
chunkLoop:
|
||||||
|
for (ChunkData chunk : chunks) {
|
||||||
|
for (EntityData anEntity : chunk.getEntities()) {
|
||||||
|
if (anEntity.getUUID().equals(uuid)) {
|
||||||
|
entity = anEntity;
|
||||||
|
break chunkLoop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entity == null) {
|
||||||
|
throw new RuntimeException("");
|
||||||
|
}
|
||||||
|
|
||||||
|
getClient().setLocalPlayer(entity);
|
||||||
|
getClient().getCamera().setAnchor(new EntityAnchor(
|
||||||
|
getClient().getWorld().getEntityRenderable(entity)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
private void tmp_reassembleWorld() {
|
private void tmp_reassembleWorld() {
|
||||||
getClient().getWorld().getChunks().forEach(ChunkRender::markForUpdate);
|
getClient().getWorld().getChunks().forEach(ChunkRender::markForUpdate);
|
||||||
}
|
}
|
||||||
|
@ -6,10 +6,15 @@ import ru.windcorp.progressia.server.Server;
|
|||||||
|
|
||||||
public class LocalServerCommsChannel extends ServerCommsChannel {
|
public class LocalServerCommsChannel extends ServerCommsChannel {
|
||||||
|
|
||||||
private final LocalClient localClient;
|
private LocalClient localClient;
|
||||||
|
private final Server server;
|
||||||
|
|
||||||
public LocalServerCommsChannel(Server server) {
|
public LocalServerCommsChannel(Server server) {
|
||||||
super(Role.GAME, Role.CHAT);
|
super(Role.GAME, Role.CHAT);
|
||||||
|
this.server = server;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void connect() {
|
||||||
setState(State.CONNECTED);
|
setState(State.CONNECTED);
|
||||||
|
|
||||||
this.localClient = new LocalClient(
|
this.localClient = new LocalClient(
|
||||||
|
@ -30,6 +30,7 @@ import ru.windcorp.progressia.client.graphics.input.bus.Input;
|
|||||||
import ru.windcorp.progressia.client.graphics.model.LambdaModel;
|
import ru.windcorp.progressia.client.graphics.model.LambdaModel;
|
||||||
import ru.windcorp.progressia.client.graphics.texture.SimpleTextures;
|
import ru.windcorp.progressia.client.graphics.texture.SimpleTextures;
|
||||||
import ru.windcorp.progressia.client.graphics.texture.Texture;
|
import ru.windcorp.progressia.client.graphics.texture.Texture;
|
||||||
|
import ru.windcorp.progressia.client.graphics.world.Camera;
|
||||||
|
|
||||||
public class LayerTestUI extends AssembledFlatLayer {
|
public class LayerTestUI extends AssembledFlatLayer {
|
||||||
|
|
||||||
@ -73,7 +74,10 @@ public class LayerTestUI extends AssembledFlatLayer {
|
|||||||
target.addCustomRenderer(new LambdaModel(LambdaModel.lambdaBuilder()
|
target.addCustomRenderer(new LambdaModel(LambdaModel.lambdaBuilder()
|
||||||
.addDynamicPart(
|
.addDynamicPart(
|
||||||
target.createRectagle(0, 0, texSize, texSize, 0xFFFFFF, compassFg),
|
target.createRectagle(0, 0, texSize, texSize, 0xFFFFFF, compassFg),
|
||||||
mat -> mat.translate(texSize/2, texSize/2, 0).rotateZ(ClientState.getInstance().getCamera().getYaw()).translate(-texSize/2, -texSize/2, 0)
|
mat ->
|
||||||
|
mat.translate(texSize/2, texSize/2, 0)
|
||||||
|
.rotateZ(getCompassRotation())
|
||||||
|
.translate(-texSize/2, -texSize/2, 0)
|
||||||
)
|
)
|
||||||
));
|
));
|
||||||
target.popTransform();
|
target.popTransform();
|
||||||
@ -81,6 +85,15 @@ public class LayerTestUI extends AssembledFlatLayer {
|
|||||||
drawCross(target);
|
drawCross(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private double getCompassRotation() {
|
||||||
|
Camera.Anchor anchor =
|
||||||
|
ClientState.getInstance().getCamera().getAnchor();
|
||||||
|
|
||||||
|
if (anchor == null) return 0;
|
||||||
|
|
||||||
|
return -anchor.getCameraYaw();
|
||||||
|
}
|
||||||
|
|
||||||
private void drawCross(RenderTarget target) {
|
private void drawCross(RenderTarget target) {
|
||||||
int cx = getWidth() / 2;
|
int cx = getWidth() / 2;
|
||||||
int cy = getHeight() / 2;
|
int cy = getHeight() / 2;
|
||||||
|
@ -19,26 +19,62 @@ package ru.windcorp.progressia.client.graphics.world;
|
|||||||
|
|
||||||
import static java.lang.Math.*;
|
import static java.lang.Math.*;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import glm.Glm;
|
import glm.Glm;
|
||||||
import glm.mat._4.Mat4;
|
import glm.mat._4.Mat4;
|
||||||
import glm.vec._3.Vec3;
|
import glm.vec._3.Vec3;
|
||||||
import ru.windcorp.progressia.client.graphics.backend.GraphicsInterface;
|
import ru.windcorp.progressia.client.graphics.backend.GraphicsInterface;
|
||||||
|
import ru.windcorp.progressia.client.graphics.world.Camera.Anchor.Mode;
|
||||||
|
import ru.windcorp.progressia.common.util.Vectors;
|
||||||
|
|
||||||
public class Camera {
|
public class Camera {
|
||||||
|
|
||||||
private final Vec3 position = new Vec3();
|
public static interface Anchor {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Offset is applied after the rotation.
|
||||||
|
*/
|
||||||
|
public static interface Mode {
|
||||||
|
void getCameraOffset(Vec3 output);
|
||||||
|
void applyCameraRotation(Mat4 output);
|
||||||
|
|
||||||
|
public static Mode of(
|
||||||
|
Consumer<Vec3> offsetGetter,
|
||||||
|
Consumer<Mat4> rotator
|
||||||
|
) {
|
||||||
|
return new Mode() {
|
||||||
|
@Override
|
||||||
|
public void getCameraOffset(Vec3 output) {
|
||||||
|
offsetGetter.accept(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void applyCameraRotation(Mat4 output) {
|
||||||
|
rotator.accept(output);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void getCameraPosition(Vec3 output);
|
||||||
|
void getCameraVelocity(Vec3 output);
|
||||||
|
float getCameraYaw();
|
||||||
|
float getCameraPitch();
|
||||||
|
|
||||||
|
Collection<Mode> getCameraModes();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private float pitch;
|
private Anchor anchor;
|
||||||
private float yaw;
|
|
||||||
|
private Anchor.Mode[] modes;
|
||||||
|
private int currentModeIndex;
|
||||||
|
|
||||||
private float fieldOfView;
|
private float fieldOfView;
|
||||||
|
|
||||||
public boolean tmp_mode = false;
|
public Camera(float fieldOfView) {
|
||||||
|
|
||||||
public Camera(Vec3 position, float pitch, float yaw, float fieldOfView) {
|
|
||||||
teleport(position);
|
|
||||||
setPitch(pitch);
|
|
||||||
setYaw(yaw);
|
|
||||||
setFieldOfView(fieldOfView);
|
setFieldOfView(fieldOfView);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,10 +84,7 @@ public class Camera {
|
|||||||
applyPerspective(helper);
|
applyPerspective(helper);
|
||||||
rotateCoordinateSystem(helper);
|
rotateCoordinateSystem(helper);
|
||||||
|
|
||||||
// TODO debug
|
applyMode(helper);
|
||||||
helper.pushViewTransform().translate(3.5f, 0, -0.5f);
|
|
||||||
if (tmp_mode) helper.pushViewTransform().rotateZ(PI);
|
|
||||||
|
|
||||||
applyDirection(helper);
|
applyDirection(helper);
|
||||||
applyPosition(helper);
|
applyPosition(helper);
|
||||||
}
|
}
|
||||||
@ -70,14 +103,38 @@ public class Camera {
|
|||||||
private void rotateCoordinateSystem(WorldRenderHelper helper) {
|
private void rotateCoordinateSystem(WorldRenderHelper helper) {
|
||||||
helper.pushViewTransform().rotateX(-PI / 2).rotateZ(PI / 2);
|
helper.pushViewTransform().rotateX(-PI / 2).rotateZ(PI / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void applyMode(WorldRenderHelper helper) {
|
||||||
|
Mode mode = getMode();
|
||||||
|
|
||||||
|
Mat4 matrix = helper.pushViewTransform();
|
||||||
|
|
||||||
|
Vec3 offset = Vectors.grab3();
|
||||||
|
mode.getCameraOffset(offset);
|
||||||
|
|
||||||
|
offset.negate();
|
||||||
|
matrix.translate(offset);
|
||||||
|
|
||||||
|
Vectors.release(offset);
|
||||||
|
|
||||||
|
mode.applyCameraRotation(matrix);
|
||||||
|
}
|
||||||
|
|
||||||
private void applyDirection(WorldRenderHelper helper) {
|
private void applyDirection(WorldRenderHelper helper) {
|
||||||
helper.pushViewTransform().rotateY(pitch).rotateZ(yaw);
|
helper.pushViewTransform()
|
||||||
|
.rotateY(-anchor.getCameraPitch())
|
||||||
|
.rotateZ(-anchor.getCameraYaw());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyPosition(WorldRenderHelper helper) {
|
private void applyPosition(WorldRenderHelper helper) {
|
||||||
helper.pushViewTransform().translate(position.negate());
|
Vec3 v = Vectors.grab3();
|
||||||
position.negate();
|
|
||||||
|
anchor.getCameraPosition(v);
|
||||||
|
v.negate();
|
||||||
|
|
||||||
|
helper.pushViewTransform().translate(v);
|
||||||
|
|
||||||
|
Vectors.release(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
private float computeFovY() {
|
private float computeFovY() {
|
||||||
@ -93,45 +150,6 @@ public class Camera {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vec3 getPosition() {
|
|
||||||
return position;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void teleport(Vec3 pos) {
|
|
||||||
position.set(pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void move(Vec3 pos) {
|
|
||||||
position.add(pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getPitch() {
|
|
||||||
return pitch;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPitch(float pitch) {
|
|
||||||
final float maxPitch = (float) (Math.PI / 2);
|
|
||||||
this.pitch = Glm.clamp(pitch, -maxPitch, +maxPitch);
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getYaw() {
|
|
||||||
return yaw;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setYaw(float yaw) {
|
|
||||||
this.yaw = Glm.mod(yaw, 2 * (float) PI);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDirection(float pitch, float yaw) {
|
|
||||||
setPitch(pitch);
|
|
||||||
setYaw(yaw);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void turn(float pitchChange, float yawChange) {
|
|
||||||
setPitch(getPitch() + pitchChange);
|
|
||||||
setYaw(getYaw() + yawChange);
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getFieldOfView() {
|
public float getFieldOfView() {
|
||||||
return fieldOfView;
|
return fieldOfView;
|
||||||
@ -140,5 +158,47 @@ public class Camera {
|
|||||||
public void setFieldOfView(float fieldOfView) {
|
public void setFieldOfView(float fieldOfView) {
|
||||||
this.fieldOfView = fieldOfView;
|
this.fieldOfView = fieldOfView;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Anchor getAnchor() {
|
||||||
|
return anchor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasAnchor() {
|
||||||
|
return anchor != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAnchor(Anchor anchor) {
|
||||||
|
if (anchor == null) {
|
||||||
|
this.anchor = null;
|
||||||
|
this.modes = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Collection<Mode> modesCollection = anchor.getCameraModes();
|
||||||
|
|
||||||
|
if (modesCollection.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Anchor " + anchor + " returned no camera modes,"
|
||||||
|
+ " at least one required"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.anchor = anchor;
|
||||||
|
|
||||||
|
this.modes = modesCollection.toArray(new Mode[modesCollection.size()]);
|
||||||
|
this.currentModeIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Anchor.Mode getMode() {
|
||||||
|
return modes[currentModeIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
public void selectNextMode() {
|
||||||
|
if (currentModeIndex == modes.length - 1) {
|
||||||
|
currentModeIndex = 0;
|
||||||
|
} else {
|
||||||
|
currentModeIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,67 @@
|
|||||||
|
package ru.windcorp.progressia.client.graphics.world;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
|
||||||
|
import glm.vec._3.Vec3;
|
||||||
|
import ru.windcorp.progressia.client.graphics.world.Camera.Anchor;
|
||||||
|
import ru.windcorp.progressia.client.world.entity.EntityRenderable;
|
||||||
|
import ru.windcorp.progressia.common.world.entity.EntityData;
|
||||||
|
|
||||||
|
public class EntityAnchor implements Anchor {
|
||||||
|
|
||||||
|
private final EntityData entity;
|
||||||
|
private final EntityRenderable model;
|
||||||
|
|
||||||
|
private final Collection<Mode> modes;
|
||||||
|
|
||||||
|
public EntityAnchor(EntityRenderable model) {
|
||||||
|
this.entity = model.getData();
|
||||||
|
this.model = model;
|
||||||
|
|
||||||
|
this.modes = ImmutableList.of(
|
||||||
|
// From viewpoint / first person
|
||||||
|
Mode.of(v -> v.set(0), m -> {}),
|
||||||
|
|
||||||
|
// Third person, looking forward
|
||||||
|
Mode.of(
|
||||||
|
v -> v.set(-3.5f, +0.5f, 0),
|
||||||
|
m -> {}
|
||||||
|
),
|
||||||
|
|
||||||
|
// Third person, looking back
|
||||||
|
Mode.of(
|
||||||
|
v -> v.set(-3.5f, 0, 0),
|
||||||
|
m -> m.rotateZ((float) Math.PI)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getCameraPosition(Vec3 output) {
|
||||||
|
model.getViewPoint(output);
|
||||||
|
output.add(entity.getPosition());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getCameraVelocity(Vec3 output) {
|
||||||
|
output.set(entity.getVelocity());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getCameraYaw() {
|
||||||
|
return entity.getYaw();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getCameraPitch() {
|
||||||
|
return entity.getPitch();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<Mode> getCameraModes() {
|
||||||
|
return modes;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -19,7 +19,9 @@ package ru.windcorp.progressia.client.graphics.world;
|
|||||||
|
|
||||||
import org.lwjgl.glfw.GLFW;
|
import org.lwjgl.glfw.GLFW;
|
||||||
|
|
||||||
|
import glm.Glm;
|
||||||
import glm.mat._3.Mat3;
|
import glm.mat._3.Mat3;
|
||||||
|
import glm.vec._2.Vec2;
|
||||||
import glm.vec._3.Vec3;
|
import glm.vec._3.Vec3;
|
||||||
import ru.windcorp.progressia.client.Client;
|
import ru.windcorp.progressia.client.Client;
|
||||||
import ru.windcorp.progressia.client.comms.controls.InputBasedControls;
|
import ru.windcorp.progressia.client.comms.controls.InputBasedControls;
|
||||||
@ -31,7 +33,9 @@ import ru.windcorp.progressia.client.graphics.input.CursorMoveEvent;
|
|||||||
import ru.windcorp.progressia.client.graphics.input.InputEvent;
|
import ru.windcorp.progressia.client.graphics.input.InputEvent;
|
||||||
import ru.windcorp.progressia.client.graphics.input.KeyEvent;
|
import ru.windcorp.progressia.client.graphics.input.KeyEvent;
|
||||||
import ru.windcorp.progressia.client.graphics.input.bus.Input;
|
import ru.windcorp.progressia.client.graphics.input.bus.Input;
|
||||||
|
import ru.windcorp.progressia.common.util.FloatMathUtils;
|
||||||
import ru.windcorp.progressia.common.util.Vectors;
|
import ru.windcorp.progressia.common.util.Vectors;
|
||||||
|
import ru.windcorp.progressia.common.world.entity.EntityData;
|
||||||
|
|
||||||
public class LayerWorld extends Layer {
|
public class LayerWorld extends Layer {
|
||||||
|
|
||||||
@ -67,19 +71,20 @@ public class LayerWorld extends Layer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doRender() {
|
protected void doRender() {
|
||||||
client.getLocalPlayer().setPosition(client.getCamera().getPosition());
|
if (client.getLocalPlayer() != null) {
|
||||||
client.getLocalPlayer().setVelocity(velocity);
|
tmp_handleControls();
|
||||||
client.getLocalPlayer().getDirection().set(
|
}
|
||||||
-client.getCamera().getYaw(),
|
|
||||||
-client.getCamera().getPitch()
|
|
||||||
);
|
|
||||||
|
|
||||||
client.getCamera().apply(helper);
|
Camera camera = client.getCamera();
|
||||||
|
if (camera.hasAnchor()) {
|
||||||
|
renderWorld();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void tmp_handleControls() {
|
||||||
|
EntityData player = client.getLocalPlayer();
|
||||||
|
|
||||||
renderWorld();
|
angMat.set().rotateZ(player.getYaw());
|
||||||
helper.reset();
|
|
||||||
|
|
||||||
angMat.set().rotateZ(-client.getCamera().getYaw());
|
|
||||||
|
|
||||||
Vec3 movement = Vectors.grab3();
|
Vec3 movement = Vectors.grab3();
|
||||||
|
|
||||||
@ -97,15 +102,21 @@ public class LayerWorld extends Layer {
|
|||||||
Vec3 velCopy = Vectors.grab3().set(velocity);
|
Vec3 velCopy = Vectors.grab3().set(velocity);
|
||||||
|
|
||||||
velCopy.mul((float) (GraphicsInterface.getFrameLength() * 60));
|
velCopy.mul((float) (GraphicsInterface.getFrameLength() * 60));
|
||||||
client.getCamera().move(velCopy);
|
|
||||||
|
player.getPosition().add(velCopy);
|
||||||
|
player.getVelocity().set(velocity);
|
||||||
|
|
||||||
Vectors.release(velCopy);
|
Vectors.release(velCopy);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void renderWorld() {
|
private void renderWorld() {
|
||||||
|
client.getCamera().apply(helper);
|
||||||
FaceCulling.push(true);
|
FaceCulling.push(true);
|
||||||
|
|
||||||
this.client.getWorld().render(helper);
|
this.client.getWorld().render(helper);
|
||||||
|
|
||||||
FaceCulling.pop();
|
FaceCulling.pop();
|
||||||
|
helper.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -170,7 +181,9 @@ public class LayerWorld extends Layer {
|
|||||||
case GLFW.GLFW_KEY_F5:
|
case GLFW.GLFW_KEY_F5:
|
||||||
if (!event.isPress()) return false;
|
if (!event.isPress()) return false;
|
||||||
|
|
||||||
client.getCamera().tmp_mode = !client.getCamera().tmp_mode;
|
if (client.getCamera().hasAnchor()) {
|
||||||
|
client.getCamera().selectNextMode();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -183,12 +196,26 @@ public class LayerWorld extends Layer {
|
|||||||
private void onMouseMoved(CursorMoveEvent event) {
|
private void onMouseMoved(CursorMoveEvent event) {
|
||||||
if (!flag) return;
|
if (!flag) return;
|
||||||
|
|
||||||
final float yawScale = 0.002f;
|
final float yawScale = -0.002f;
|
||||||
final float pitchScale = yawScale;
|
final float pitchScale = yawScale;
|
||||||
|
|
||||||
|
EntityData player = client.getLocalPlayer();
|
||||||
|
|
||||||
client.getCamera().turn(
|
if (player != null) {
|
||||||
(float) (event.getChangeY() * pitchScale),
|
normalizeAngles(player.getDirection().add(
|
||||||
(float) (event.getChangeX() * yawScale)
|
(float) (event.getChangeX() * yawScale),
|
||||||
|
(float) (event.getChangeY() * pitchScale)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void normalizeAngles(Vec2 dir) {
|
||||||
|
// Normalize yaw
|
||||||
|
dir.x = FloatMathUtils.normalizeAngle(dir.x);
|
||||||
|
|
||||||
|
// Clamp pitch
|
||||||
|
dir.y = Glm.clamp(
|
||||||
|
dir.y, -FloatMathUtils.PI_F/2, +FloatMathUtils.PI_F/2
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,9 +25,9 @@ import java.util.WeakHashMap;
|
|||||||
|
|
||||||
import glm.vec._3.i.Vec3i;
|
import glm.vec._3.i.Vec3i;
|
||||||
import ru.windcorp.progressia.client.graphics.backend.FaceCulling;
|
import ru.windcorp.progressia.client.graphics.backend.FaceCulling;
|
||||||
import ru.windcorp.progressia.client.graphics.model.Renderable;
|
|
||||||
import ru.windcorp.progressia.client.graphics.model.ShapeRenderHelper;
|
import ru.windcorp.progressia.client.graphics.model.ShapeRenderHelper;
|
||||||
import ru.windcorp.progressia.client.world.entity.EntityRenderRegistry;
|
import ru.windcorp.progressia.client.world.entity.EntityRenderRegistry;
|
||||||
|
import ru.windcorp.progressia.client.world.entity.EntityRenderable;
|
||||||
import ru.windcorp.progressia.common.world.ChunkData;
|
import ru.windcorp.progressia.common.world.ChunkData;
|
||||||
import ru.windcorp.progressia.common.world.WorldData;
|
import ru.windcorp.progressia.common.world.WorldData;
|
||||||
import ru.windcorp.progressia.common.world.entity.EntityData;
|
import ru.windcorp.progressia.common.world.entity.EntityData;
|
||||||
@ -37,7 +37,7 @@ public class WorldRender {
|
|||||||
private final WorldData data;
|
private final WorldData data;
|
||||||
|
|
||||||
private final Map<ChunkData, ChunkRender> chunks = new HashMap<>();
|
private final Map<ChunkData, ChunkRender> chunks = new HashMap<>();
|
||||||
private final Map<EntityData, Renderable> entityModels =
|
private final Map<EntityData, EntityRenderable> entityModels =
|
||||||
Collections.synchronizedMap(new WeakHashMap<>());
|
Collections.synchronizedMap(new WeakHashMap<>());
|
||||||
|
|
||||||
public WorldRender(WorldData data) {
|
public WorldRender(WorldData data) {
|
||||||
@ -86,14 +86,14 @@ public class WorldRender {
|
|||||||
FaceCulling.pop();
|
FaceCulling.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Renderable getEntityRenderable(EntityData entity) {
|
public EntityRenderable getEntityRenderable(EntityData entity) {
|
||||||
return entityModels.computeIfAbsent(
|
return entityModels.computeIfAbsent(
|
||||||
entity,
|
entity,
|
||||||
WorldRender::createEntityRenderable
|
WorldRender::createEntityRenderable
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Renderable createEntityRenderable(EntityData entity) {
|
private static EntityRenderable createEntityRenderable(EntityData entity) {
|
||||||
return EntityRenderRegistry.getInstance().get(entity.getId())
|
return EntityRenderRegistry.getInstance().get(entity.getId())
|
||||||
.createRenderable(entity);
|
.createRenderable(entity);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package ru.windcorp.progressia.client.world.entity;
|
package ru.windcorp.progressia.client.world.entity;
|
||||||
|
|
||||||
import ru.windcorp.progressia.client.graphics.model.Renderable;
|
|
||||||
import ru.windcorp.progressia.common.util.Namespaced;
|
import ru.windcorp.progressia.common.util.Namespaced;
|
||||||
import ru.windcorp.progressia.common.world.entity.EntityData;
|
import ru.windcorp.progressia.common.world.entity.EntityData;
|
||||||
|
|
||||||
@ -10,6 +9,6 @@ public abstract class EntityRender extends Namespaced {
|
|||||||
super(namespace, name);
|
super(namespace, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract Renderable createRenderable(EntityData entity);
|
public abstract EntityRenderable createRenderable(EntityData entity);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
package ru.windcorp.progressia.client.world.entity;
|
||||||
|
|
||||||
|
import glm.vec._3.Vec3;
|
||||||
|
import ru.windcorp.progressia.client.graphics.model.Renderable;
|
||||||
|
import ru.windcorp.progressia.common.world.entity.EntityData;
|
||||||
|
|
||||||
|
public abstract class EntityRenderable implements Renderable {
|
||||||
|
|
||||||
|
private final EntityData data;
|
||||||
|
|
||||||
|
public EntityRenderable(EntityData data) {
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityData getData() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void getViewPoint(Vec3 output) {
|
||||||
|
output.set(0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,17 +1,20 @@
|
|||||||
package ru.windcorp.progressia.client.world.entity;
|
package ru.windcorp.progressia.client.world.entity;
|
||||||
|
|
||||||
import static java.lang.Math.*;
|
import static java.lang.Math.*;
|
||||||
|
import static ru.windcorp.progressia.common.util.FloatMathUtils.*;
|
||||||
|
|
||||||
import glm.Glm;
|
import glm.Glm;
|
||||||
import glm.mat._4.Mat4;
|
import glm.mat._4.Mat4;
|
||||||
import glm.vec._3.Vec3;
|
import glm.vec._3.Vec3;
|
||||||
|
import glm.vec._4.Vec4;
|
||||||
import ru.windcorp.progressia.client.graphics.backend.GraphicsInterface;
|
import ru.windcorp.progressia.client.graphics.backend.GraphicsInterface;
|
||||||
import ru.windcorp.progressia.client.graphics.model.Renderable;
|
import ru.windcorp.progressia.client.graphics.model.Renderable;
|
||||||
import ru.windcorp.progressia.client.graphics.model.ShapeRenderHelper;
|
import ru.windcorp.progressia.client.graphics.model.ShapeRenderHelper;
|
||||||
|
import ru.windcorp.progressia.common.util.Matrices;
|
||||||
import ru.windcorp.progressia.common.util.Vectors;
|
import ru.windcorp.progressia.common.util.Vectors;
|
||||||
import ru.windcorp.progressia.common.world.entity.EntityData;
|
import ru.windcorp.progressia.common.world.entity.EntityData;
|
||||||
|
|
||||||
public class QuadripedModel implements Renderable {
|
public class QuadripedModel extends EntityRenderable {
|
||||||
|
|
||||||
private static abstract class BodyPart {
|
private static abstract class BodyPart {
|
||||||
private final Renderable renderable;
|
private final Renderable renderable;
|
||||||
@ -20,7 +23,6 @@ public class QuadripedModel implements Renderable {
|
|||||||
public BodyPart(Renderable renderable, Vec3 joint) {
|
public BodyPart(Renderable renderable, Vec3 joint) {
|
||||||
this.renderable = renderable;
|
this.renderable = renderable;
|
||||||
if (joint != null) {
|
if (joint != null) {
|
||||||
// joint.negate(this.translation);
|
|
||||||
this.translation.set(joint);
|
this.translation.set(joint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -37,6 +39,10 @@ public class QuadripedModel implements Renderable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void applyTransform(Mat4 mat, QuadripedModel model);
|
protected abstract void applyTransform(Mat4 mat, QuadripedModel model);
|
||||||
|
|
||||||
|
public Vec3 getTranslation() {
|
||||||
|
return translation;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Body extends BodyPart {
|
public static class Body extends BodyPart {
|
||||||
@ -54,19 +60,27 @@ public class QuadripedModel implements Renderable {
|
|||||||
private final float maxYaw;
|
private final float maxYaw;
|
||||||
private final float maxPitch;
|
private final float maxPitch;
|
||||||
|
|
||||||
|
private final Vec3 viewPoint;
|
||||||
|
|
||||||
public Head(
|
public Head(
|
||||||
Renderable renderable, Vec3 joint,
|
Renderable renderable, Vec3 joint,
|
||||||
double maxYawDegrees, double maxPitchDegrees
|
double maxYawDegrees, double maxPitchDegrees,
|
||||||
|
Vec3 viewPoint
|
||||||
) {
|
) {
|
||||||
super(renderable, joint);
|
super(renderable, joint);
|
||||||
this.maxYaw = (float) toRadians(maxYawDegrees);
|
this.maxYaw = (float) toRadians(maxYawDegrees);
|
||||||
this.maxPitch = (float) toRadians(maxPitchDegrees);
|
this.maxPitch = (float) toRadians(maxPitchDegrees);
|
||||||
|
this.viewPoint = viewPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void applyTransform(Mat4 mat, QuadripedModel model) {
|
protected void applyTransform(Mat4 mat, QuadripedModel model) {
|
||||||
mat.rotateZ(model.headYaw).rotateY(model.headPitch);
|
mat.rotateZ(model.headYaw).rotateY(model.headPitch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Vec3 getViewPoint() {
|
||||||
|
return viewPoint;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Leg extends BodyPart {
|
public static class Leg extends BodyPart {
|
||||||
@ -86,8 +100,6 @@ public class QuadripedModel implements Renderable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final EntityData entity;
|
|
||||||
|
|
||||||
private final Body body;
|
private final Body body;
|
||||||
private final Head head;
|
private final Head head;
|
||||||
private final Leg leftForeLeg, rightForeLeg;
|
private final Leg leftForeLeg, rightForeLeg;
|
||||||
@ -120,7 +132,7 @@ public class QuadripedModel implements Renderable {
|
|||||||
|
|
||||||
float scale
|
float scale
|
||||||
) {
|
) {
|
||||||
this.entity = entity;
|
super(entity);
|
||||||
|
|
||||||
this.body = body;
|
this.body = body;
|
||||||
this.head = head;
|
this.head = head;
|
||||||
@ -134,23 +146,21 @@ public class QuadripedModel implements Renderable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(ShapeRenderHelper renderer) {
|
public void render(ShapeRenderHelper renderer) {
|
||||||
accountForVelocity();
|
|
||||||
evaluateAngles();
|
|
||||||
|
|
||||||
renderer.pushTransform().scale(scale).rotateZ(bodyYaw);
|
renderer.pushTransform().scale(scale).rotateZ(bodyYaw);
|
||||||
body.render(renderer, this);
|
body.render(renderer, this);
|
||||||
|
|
||||||
head.render(renderer, this);
|
head.render(renderer, this);
|
||||||
|
|
||||||
leftForeLeg.render(renderer, this);
|
leftForeLeg.render(renderer, this);
|
||||||
rightForeLeg.render(renderer, this);
|
rightForeLeg.render(renderer, this);
|
||||||
leftHindLeg.render(renderer, this);
|
leftHindLeg.render(renderer, this);
|
||||||
rightHindLeg.render(renderer, this);
|
rightHindLeg.render(renderer, this);
|
||||||
renderer.popTransform();
|
renderer.popTransform();
|
||||||
|
|
||||||
|
accountForVelocity();
|
||||||
|
evaluateAngles();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void evaluateAngles() {
|
private void evaluateAngles() {
|
||||||
float globalYaw = normalizeAngle(entity.getYaw());
|
float globalYaw = normalizeAngle(getData().getYaw());
|
||||||
|
|
||||||
if (Float.isNaN(bodyYaw)) {
|
if (Float.isNaN(bodyYaw)) {
|
||||||
bodyYaw = globalYaw;
|
bodyYaw = globalYaw;
|
||||||
@ -170,14 +180,14 @@ public class QuadripedModel implements Renderable {
|
|||||||
bodyYaw = normalizeAngle(bodyYaw);
|
bodyYaw = normalizeAngle(bodyYaw);
|
||||||
|
|
||||||
headPitch = Glm.clamp(
|
headPitch = Glm.clamp(
|
||||||
entity.getPitch(),
|
getData().getPitch(),
|
||||||
-head.maxPitch, head.maxPitch
|
-head.maxPitch, head.maxPitch
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void accountForVelocity() {
|
private void accountForVelocity() {
|
||||||
Vec3 horizontal = Vectors.grab3();
|
Vec3 horizontal = Vectors.grab3();
|
||||||
horizontal.set(entity.getVelocity());
|
horizontal.set(getData().getVelocity());
|
||||||
horizontal.z = 0;
|
horizontal.z = 0;
|
||||||
|
|
||||||
velocity = horizontal.length();
|
velocity = horizontal.length();
|
||||||
@ -201,11 +211,26 @@ public class QuadripedModel implements Renderable {
|
|||||||
velocityCoeff *= velocityCoeff;
|
velocityCoeff *= velocityCoeff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static float normalizeAngle(float x) {
|
@Override
|
||||||
final float half = (float) (PI);
|
public void getViewPoint(Vec3 output) {
|
||||||
final float full = (float) (2 * PI);
|
Mat4 m = Matrices.grab4();
|
||||||
return ((x + half) % full + full) % full - half;
|
Vec4 v = Vectors.grab4();
|
||||||
|
|
||||||
|
m.identity()
|
||||||
|
.scale(scale)
|
||||||
|
.rotateZ(bodyYaw)
|
||||||
|
.translate(head.getTranslation())
|
||||||
|
.rotateZ(headYaw)
|
||||||
|
.rotateY(headPitch);
|
||||||
|
|
||||||
|
v.set(head.getViewPoint(), 1);
|
||||||
|
m.mul(v);
|
||||||
|
|
||||||
|
output.set(v.x, v.y, v.z);
|
||||||
|
|
||||||
|
Vectors.release(v);
|
||||||
|
Matrices.release(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
package ru.windcorp.progressia.common.comms.packets;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class PacketSetLocalPlayer extends Packet {
|
||||||
|
|
||||||
|
private final UUID localPlayerEntityUUID;
|
||||||
|
|
||||||
|
public PacketSetLocalPlayer(UUID uuid) {
|
||||||
|
super("Core", "SetLocalPlayer");
|
||||||
|
this.localPlayerEntityUUID = uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID getLocalPlayerEntityUUID() {
|
||||||
|
return localPlayerEntityUUID;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package ru.windcorp.progressia.common.util;
|
||||||
|
|
||||||
|
import org.apache.commons.math3.util.FastMath;
|
||||||
|
|
||||||
|
public class FloatMathUtils {
|
||||||
|
|
||||||
|
public static final float PI_F = (float) Math.PI;
|
||||||
|
|
||||||
|
public static float floor(float x) {
|
||||||
|
return (float) FastMath.floor(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float normalizeAngle(float a) {
|
||||||
|
return a - 2*PI_F * floor((a + PI_F) / (2*PI_F));
|
||||||
|
}
|
||||||
|
|
||||||
|
private FloatMathUtils() {}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,65 @@
|
|||||||
|
package ru.windcorp.progressia.common.util;
|
||||||
|
|
||||||
|
import glm.mat._3.Mat3;
|
||||||
|
import glm.mat._4.Mat4;
|
||||||
|
import glm.mat._4.d.Mat4d;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A set of caches for GLM matrix objects. Use this instead of allocating new
|
||||||
|
* matrices when the objects are effectively local.
|
||||||
|
* <p>
|
||||||
|
* All {@code grab}bed objects must be {@code release}d as soon as possible.
|
||||||
|
* Ideally, user code should be:
|
||||||
|
* <pre>
|
||||||
|
* Mat4 myMatrix = Vectors.grab4();
|
||||||
|
* try {
|
||||||
|
* // use myMatrix
|
||||||
|
* } finally {
|
||||||
|
* Matrices.release(myMatrix);
|
||||||
|
* }
|
||||||
|
* </pre>
|
||||||
|
* Provided objects may be reused after {@code release} has been invoked;
|
||||||
|
* do not store them.
|
||||||
|
* <p>
|
||||||
|
* This class is thread- and recursion-safe.
|
||||||
|
*
|
||||||
|
* @see Vectors
|
||||||
|
*/
|
||||||
|
public class Matrices {
|
||||||
|
|
||||||
|
private static final LowOverheadCache<Mat3> MAT3S =
|
||||||
|
new LowOverheadCache<>(Mat3::new);
|
||||||
|
|
||||||
|
public static Mat3 grab3() {
|
||||||
|
return MAT3S.grab();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void release(Mat3 m) {
|
||||||
|
MAT3S.release(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final LowOverheadCache<Mat4> MAT4S =
|
||||||
|
new LowOverheadCache<>(Mat4::new);
|
||||||
|
|
||||||
|
public static Mat4 grab4() {
|
||||||
|
return MAT4S.grab();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void release(Mat4 m) {
|
||||||
|
MAT4S.release(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final LowOverheadCache<Mat4d> MAT4DS =
|
||||||
|
new LowOverheadCache<>(Mat4d::new);
|
||||||
|
|
||||||
|
public static Mat4d grab4d() {
|
||||||
|
return MAT4DS.grab();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void release(Mat4d m) {
|
||||||
|
MAT4DS.release(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Matrices() {}
|
||||||
|
|
||||||
|
}
|
@ -25,6 +25,8 @@ import glm.vec._4.i.Vec4i;
|
|||||||
* do not store them.
|
* do not store them.
|
||||||
* <p>
|
* <p>
|
||||||
* This class is thread- and recursion-safe.
|
* This class is thread- and recursion-safe.
|
||||||
|
*
|
||||||
|
* @see Matrices
|
||||||
*/
|
*/
|
||||||
public class Vectors {
|
public class Vectors {
|
||||||
|
|
||||||
|
@ -22,11 +22,13 @@ import static ru.windcorp.progressia.common.world.block.BlockFace.*;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
|
import glm.vec._2.Vec2;
|
||||||
import glm.vec._3.Vec3;
|
import glm.vec._3.Vec3;
|
||||||
import glm.vec._3.i.Vec3i;
|
import glm.vec._3.i.Vec3i;
|
||||||
import ru.windcorp.progressia.client.world.tile.TileLocation;
|
import ru.windcorp.progressia.client.world.tile.TileLocation;
|
||||||
@ -131,7 +133,11 @@ public class ChunkData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
EntityData javapony = new EntityData("Test", "Javapony");
|
EntityData javapony = new EntityData("Test", "Javapony");
|
||||||
javapony.setPosition(new Vec3(8, 12, 16.2f));
|
javapony.setUUID(UUID.nameUUIDFromBytes(new byte[] {42}));
|
||||||
|
javapony.setPosition(new Vec3(-6, -6, 20));
|
||||||
|
javapony.setDirection(new Vec2(
|
||||||
|
(float) Math.toRadians(40), (float) Math.toRadians(45)
|
||||||
|
));
|
||||||
getEntities().add(javapony);
|
getEntities().add(javapony);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,12 +4,14 @@ import java.util.Collection;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
import glm.vec._3.i.Vec3i;
|
||||||
import gnu.trove.TCollections;
|
import gnu.trove.TCollections;
|
||||||
import gnu.trove.map.TIntObjectMap;
|
import gnu.trove.map.TIntObjectMap;
|
||||||
import gnu.trove.map.hash.TIntObjectHashMap;
|
import gnu.trove.map.hash.TIntObjectHashMap;
|
||||||
import ru.windcorp.progressia.common.comms.CommsChannel.Role;
|
import ru.windcorp.progressia.common.comms.CommsChannel.Role;
|
||||||
import ru.windcorp.progressia.common.comms.CommsChannel.State;
|
import ru.windcorp.progressia.common.comms.CommsChannel.State;
|
||||||
import ru.windcorp.progressia.common.comms.packets.Packet;
|
import ru.windcorp.progressia.common.comms.packets.Packet;
|
||||||
|
import ru.windcorp.progressia.common.comms.packets.PacketSetLocalPlayer;
|
||||||
import ru.windcorp.progressia.server.Server;
|
import ru.windcorp.progressia.server.Server;
|
||||||
|
|
||||||
public class ClientManager {
|
public class ClientManager {
|
||||||
@ -36,6 +38,11 @@ public class ClientManager {
|
|||||||
clientsById.put(client.getId(), client);
|
clientsById.put(client.getId(), client);
|
||||||
|
|
||||||
client.addListener(new DefaultServerCommsListener(this, client));
|
client.addListener(new DefaultServerCommsListener(this, client));
|
||||||
|
|
||||||
|
client.sendPacket(new PacketSetLocalPlayer(
|
||||||
|
server.getWorld().getData().getChunk(new Vec3i(0, 0, 0))
|
||||||
|
.getEntities().get(0).getUUID()
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void disconnectClient(Client client) {
|
public void disconnectClient(Client client) {
|
||||||
|
Reference in New Issue
Block a user