diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/backend/OpenGLObjectTracker.java b/src/main/java/ru/windcorp/progressia/client/graphics/backend/OpenGLObjectTracker.java index decf3ca..1910625 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/backend/OpenGLObjectTracker.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/backend/OpenGLObjectTracker.java @@ -85,10 +85,6 @@ public class OpenGLObjectTracker { this.GLDeleter = GLDeleter; } - public int getHandle() { - return referentGLhandle; - } - public void delete() { GLDeleter.accept(referentGLhandle); } diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/font/Font.java b/src/main/java/ru/windcorp/progressia/client/graphics/font/Font.java index a121f55..8374730 100755 --- a/src/main/java/ru/windcorp/progressia/client/graphics/font/Font.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/font/Font.java @@ -1,5 +1,7 @@ package ru.windcorp.progressia.client.graphics.font; +import java.util.function.Supplier; + import glm.vec._2.i.Vec2i; import ru.windcorp.progressia.client.graphics.Colors; import ru.windcorp.progressia.client.graphics.model.Renderable; @@ -48,6 +50,12 @@ public class Font { ) { return typeface.assemble(chars, style, align, maxWidth, color); } + + public Renderable assembleDynamic( + Supplier supplier + ) { + return typeface.assembleDynamic(supplier, color); + } public int getWidth(CharSequence chars, int maxWidth) { return typeface.getWidth(chars, style, align, maxWidth); diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/font/SpriteTypeface.java b/src/main/java/ru/windcorp/progressia/client/graphics/font/SpriteTypeface.java index fbdd84f..8559b05 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/font/SpriteTypeface.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/font/SpriteTypeface.java @@ -4,22 +4,29 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.function.Consumer; +import java.util.function.Supplier; import glm.vec._3.Vec3; +import gnu.trove.map.TCharObjectMap; +import gnu.trove.map.hash.TCharObjectHashMap; import ru.windcorp.progressia.client.graphics.backend.Usage; import ru.windcorp.progressia.client.graphics.model.Face; import ru.windcorp.progressia.client.graphics.model.Faces; import ru.windcorp.progressia.client.graphics.model.Shape; +import ru.windcorp.progressia.client.graphics.model.ShapeRenderHelper; import ru.windcorp.progressia.client.graphics.model.ShapeRenderProgram; import ru.windcorp.progressia.client.graphics.model.Renderable; import ru.windcorp.progressia.client.graphics.texture.Texture; +import ru.windcorp.progressia.common.util.Vectors; public abstract class SpriteTypeface extends Typeface { - + private final int height; private final int thickness; private final Vec3 shadowOffset; + private final TCharObjectMap charShapes = new TCharObjectHashMap<>(); + public SpriteTypeface(String name, int height, int thinkness) { super(name); this.height = height; @@ -37,6 +44,11 @@ public abstract class SpriteTypeface extends Typeface { return height; } + @Override + public int getLineHeight() { + return getHeight(); + } + public int getThickness() { return thickness; } @@ -275,6 +287,11 @@ public abstract class SpriteTypeface extends Typeface { faces.add(copy); } } + + @Override + public Renderable assembleDynamic(Supplier supplier, int color) { + return new DynamicText(supplier, createVectorFromRGBInt(color)); + } @Override protected long getSize( @@ -303,6 +320,21 @@ public abstract class SpriteTypeface extends Typeface { return pack(resultWidth, height); } + + private Shape createCharShape(char c, Vec3 color) { + return new Shape( + Usage.STATIC, getProgram(), + Faces.createRectangle( + getProgram(), + getTexture(c), + color, + Vectors.ZERO_3, + new Vec3(getWidth(c), 0, 0), + new Vec3(0, height, 0), + false + ) + ); + } // TODO remove private static Vec3 createVectorFromRGBInt(int rgb) { @@ -312,5 +344,43 @@ public abstract class SpriteTypeface extends Typeface { return new Vec3(r / 256f, g / 256f, b / 256f); } + + private class DynamicText implements Renderable { + + private final Supplier supplier; + private final Vec3 color; + + public DynamicText(Supplier supplier, Vec3 color) { + this.supplier = supplier; + this.color = color; + } + + @Override + public void render(ShapeRenderHelper renderer) { + CharSequence text = supplier.get(); + + int x = 0; + for (int i = 0; i < text.length(); ++i) { + char c = text.charAt(i); + + renderer.pushTransform().translate(x, -getInterlineBuffer(), 0); + Shape charShape = getShape(c); + charShape.render(renderer); + renderer.popTransform(); + + x += getWidth(c); + } + } + + private Shape getShape(char c) { + Shape shape = charShapes.get(c); + if (shape == null) { + shape = createCharShape(c, this.color); + charShapes.put(c, shape); + } + return shape; + } + + } } diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/font/Typeface.java b/src/main/java/ru/windcorp/progressia/client/graphics/font/Typeface.java index 50451be..8ba6597 100755 --- a/src/main/java/ru/windcorp/progressia/client/graphics/font/Typeface.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/font/Typeface.java @@ -1,5 +1,7 @@ package ru.windcorp.progressia.client.graphics.font; +import java.util.function.Supplier; + import glm.vec._2.i.Vec2i; import ru.windcorp.progressia.client.graphics.model.Renderable; import ru.windcorp.progressia.common.util.CoordinatePacker; @@ -51,6 +53,9 @@ public abstract class Typeface extends Named { float align, int maxWidth, int color ); + + // TODO implement styling + public abstract Renderable assembleDynamic(Supplier supplier, int color); public int getWidth( CharSequence chars, int style, @@ -66,6 +71,8 @@ public abstract class Typeface extends Named { return getHeight(getSize(chars, style, align, maxWidth)); } + public abstract int getLineHeight(); + public Vec2i getSize( CharSequence chars, int style, float align, int maxWidth, diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/gui/DynamicLabel.java b/src/main/java/ru/windcorp/progressia/client/graphics/gui/DynamicLabel.java new file mode 100644 index 0000000..10d69c9 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/client/graphics/gui/DynamicLabel.java @@ -0,0 +1,36 @@ +package ru.windcorp.progressia.client.graphics.gui; + +import glm.mat._4.Mat4; +import ru.windcorp.progressia.client.graphics.flat.RenderTarget; +import ru.windcorp.progressia.client.graphics.font.Font; + +import java.util.function.Supplier; + +public class DynamicLabel extends Component { + + private Font font; + private Supplier contents; + + public DynamicLabel(String name, Font font, Supplier contents, int width) { + super(name); + this.font = font; + this.contents = contents; + setPreferredSize(width, font.getHeight("", Integer.MAX_VALUE) * 2); + } + + public Font getFont() { + return font; + } + + public Supplier getContentSupplier() { + return contents; + } + + @Override + protected void assembleSelf(RenderTarget target) { + target.pushTransform(new Mat4().identity().translate(getX(), getY(), -1000).scale(2)); + target.addCustomRenderer(font.assembleDynamic(getContentSupplier())); + target.popTransform(); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/gui/Label.java b/src/main/java/ru/windcorp/progressia/client/graphics/gui/Label.java index 7fb5247..e56774f 100755 --- a/src/main/java/ru/windcorp/progressia/client/graphics/gui/Label.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/gui/Label.java @@ -51,7 +51,7 @@ public class Label extends Component { @Override protected void assembleSelf(RenderTarget target) { target.pushTransform( - new Mat4().identity().translate(getX(), getY(), -1000) + new Mat4().identity().translate(getX(), getY(), -1000) // TODO wtf is this magic <--- .scale(2) ); diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/world/LayerWorld.java b/src/main/java/ru/windcorp/progressia/client/graphics/world/LayerWorld.java index b0d35f6..0bbe753 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/world/LayerWorld.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/world/LayerWorld.java @@ -176,10 +176,11 @@ public class LayerWorld extends Layer { return new StaticModel(b); } + + private static final float FRICTION_COEFF = Units.get("1e-5f kg/s"); private void tmp_applyFriction(EntityData entity, float tickLength) { - final float frictionCoeff = Units.get(1e-5f, "kg/s"); - entity.getVelocity().mul((float) Math.exp(-frictionCoeff / entity.getCollisionMass() * tickLength)); + entity.getVelocity().mul((float) Math.exp(-FRICTION_COEFF / entity.getCollisionMass() * tickLength)); } private static final float MC_g = Units.get("32 m/s^2"); diff --git a/src/main/java/ru/windcorp/progressia/common/world/WorldData.java b/src/main/java/ru/windcorp/progressia/common/world/WorldData.java index d67515f..77e0a3c 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/WorldData.java +++ b/src/main/java/ru/windcorp/progressia/common/world/WorldData.java @@ -55,7 +55,7 @@ public class WorldData { } public void tmp_generate() { - final int size = 3; + final int size = 2; Vec3i cursor = new Vec3i(0, 0, 0); for (cursor.x = -(size / 2); cursor.x <= (size / 2); ++cursor.x) { diff --git a/src/main/java/ru/windcorp/progressia/server/Server.java b/src/main/java/ru/windcorp/progressia/server/Server.java index ca99589..437f854 100644 --- a/src/main/java/ru/windcorp/progressia/server/Server.java +++ b/src/main/java/ru/windcorp/progressia/server/Server.java @@ -126,6 +126,10 @@ public class Server { return this.serverThread.getTicker().getTickLength(); } + public double getTPS() { + return this.serverThread.getTicker().getTPS(); + } + /** * Returns the {@link WorldAccessor} object for this server. Use the provided accessor to * request common {@link Evaluation}s and {@link Change}s. diff --git a/src/main/java/ru/windcorp/progressia/server/world/ticking/TickerCoordinator.java b/src/main/java/ru/windcorp/progressia/server/world/ticking/TickerCoordinator.java index 074f69b..e47e878 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/ticking/TickerCoordinator.java +++ b/src/main/java/ru/windcorp/progressia/server/world/ticking/TickerCoordinator.java @@ -49,6 +49,10 @@ public class TickerCoordinator { private final AtomicInteger workingTickers = new AtomicInteger(); + private boolean isTickStartSet = false; + private long tickStart = -1; + private double tickLength = 1.0 / 20; // Do something about it + private final Logger logger = LogManager.getLogger("Ticker Coordinator"); public TickerCoordinator(Server server, int tickers) { @@ -97,8 +101,23 @@ public class TickerCoordinator { } public double getTickLength() { - // TODO implement - return Units.SECONDS / 20; + return tickLength; + } + + public double getTPS() { + return 1 / tickLength; + } + + private void onTickStart() { + long now = System.currentTimeMillis(); + + if (isTickStartSet) { + tickLength = (now - tickStart) * Units.MILLISECONDS; + } else { + isTickStartSet = true; + } + + tickStart = System.currentTimeMillis(); } /* @@ -107,6 +126,7 @@ public class TickerCoordinator { public void runOneTick() { try { + onTickStart(); int passes = 0; diff --git a/src/main/java/ru/windcorp/progressia/test/LayerTestGUI.java b/src/main/java/ru/windcorp/progressia/test/LayerTestGUI.java index 2ae9828..94d80a1 100755 --- a/src/main/java/ru/windcorp/progressia/test/LayerTestGUI.java +++ b/src/main/java/ru/windcorp/progressia/test/LayerTestGUI.java @@ -19,14 +19,18 @@ package ru.windcorp.progressia.test; import java.util.ArrayList; import java.util.Collection; +import java.util.Locale; import ru.windcorp.progressia.client.ClientState; +import ru.windcorp.progressia.client.graphics.backend.GraphicsInterface; import ru.windcorp.progressia.client.graphics.font.Font; +import ru.windcorp.progressia.client.graphics.gui.DynamicLabel; import ru.windcorp.progressia.client.graphics.gui.GUILayer; import ru.windcorp.progressia.client.graphics.gui.Label; import ru.windcorp.progressia.client.graphics.gui.Panel; import ru.windcorp.progressia.client.graphics.gui.layout.LayoutAlign; import ru.windcorp.progressia.client.graphics.gui.layout.LayoutVertical; +import ru.windcorp.progressia.server.ServerState; public class LayerTestGUI extends GUILayer { @@ -57,7 +61,23 @@ public class LayerTestGUI extends GUILayer { () -> String.format("Gravity: %9s (G)", TestPlayerControls.getInstance().useMinecraftGravity() ? "Minecraft" : "Realistic") )); - panel.getChildren().forEach(c -> labels.add((Label) c)); + panel.addChild(new DynamicLabel( + "FPSDisplay", new Font().withColor(0x37A3E6).deriveShadow(), + () -> String.format(Locale.US, "FPS: %5.1f", GraphicsInterface.getFPS()), + 128 + )); + + panel.addChild(new DynamicLabel( + "TPSDisplay", new Font().withColor(0x37A3E6).deriveShadow(), + () -> ServerState.getInstance() == null ? "TPS: n/a" : String.format(Locale.US, "TPS: %5.1f", ServerState.getInstance().getTPS()), + 128 + )); + + panel.getChildren().forEach(c -> { + if (c instanceof Label) { + labels.add((Label) c); + } + }); TestPlayerControls.getInstance().setUpdateCallback(() -> labels.forEach(Label::update)); getRoot().addChild(panel); diff --git a/src/main/java/ru/windcorp/progressia/test/TestPlayerControls.java b/src/main/java/ru/windcorp/progressia/test/TestPlayerControls.java index afd2e37..74fc33c 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestPlayerControls.java +++ b/src/main/java/ru/windcorp/progressia/test/TestPlayerControls.java @@ -35,13 +35,13 @@ public class TestPlayerControls { private static final float FLYING_SPEED = 6.0f * Units.METERS_PER_SECOND; // (0; 1], 1 is instant change, 0 is no control authority - private static final float FLYING_CONTROL_AUTHORITY = 0.05f; + private static final float FLYING_CONTROL_AUTHORITY = Units.get("2 1/s"); // Horizontal and vertical max control speed when walking private static final float WALKING_SPEED = 4.0f * Units.METERS_PER_SECOND; // (0; 1], 1 is instant change, 0 is no control authority - private static final float WALKING_CONTROL_AUTHORITY = 0.1f; + private static final float WALKING_CONTROL_AUTHORITY = Units.get("15 1/s"); // Vertical velocity instantly add to player when they jump private static final float JUMP_VELOCITY = 5f * Units.METERS_PER_SECOND; @@ -66,28 +66,36 @@ public class TestPlayerControls { EntityData player = getEntity(); - Mat3 angMat = new Mat3().identity().rotateZ(player.getYaw()); - Vec3 movement = new Vec3(movementForward, -movementRight, 0); - - if (movementForward != 0 && movementRight != 0) { - movement.normalize(); - } - - angMat.mul_(movement); // bug in jglm, .mul() and mul_() are swapped + final float speed, authority; if (isFlying) { - movement.z = movementUp; - movement.mul(FLYING_SPEED); - movement.sub(player.getVelocity()); - movement.mul(FLYING_CONTROL_AUTHORITY); + speed = FLYING_SPEED; + authority = FLYING_CONTROL_AUTHORITY; } else { - movement.mul(WALKING_SPEED); - movement.sub(player.getVelocity()); - movement.mul(WALKING_CONTROL_AUTHORITY); - movement.z = 0; + speed = WALKING_SPEED; + authority = WALKING_CONTROL_AUTHORITY; } - player.getVelocity().add(movement); + Mat3 angMat = new Mat3().identity().rotateZ(player.getYaw()); + Vec3 desiredVelocity = new Vec3(movementForward, -movementRight, 0); + + if (movementForward != 0 && movementRight != 0) desiredVelocity.normalize(); + angMat.mul_(desiredVelocity); // bug in jglm, .mul() and mul_() are swapped + desiredVelocity.z = movementUp; + desiredVelocity.mul(speed); + + Vec3 change = new Vec3() + .set(desiredVelocity) + .sub(player.getVelocity()) + .mul((float) Math.exp(-authority * GraphicsInterface.getFrameLength())) + .negate() + .add(desiredVelocity); + + if (!isFlying) { + change.z = player.getVelocity().z; + } + + player.getVelocity().set(change); } public void handleInput(Input input) { @@ -233,11 +241,11 @@ public class TestPlayerControls { ); } - private EntityData getEntity() { + public EntityData getEntity() { return getPlayer().getEntity(); } - private LocalPlayer getPlayer() { + public LocalPlayer getPlayer() { return ClientState.getInstance().getLocalPlayer(); }