From a9900d7f1eea77900eb9543c905a27a7dcb9302a Mon Sep 17 00:00:00 2001 From: Maik Marschner Date: Wed, 30 Aug 2023 00:31:37 +0200 Subject: [PATCH] Update hanging sign models, add wall hanging sign. --- .../chunky/block/MinecraftBlockProvider.java | 6 +- .../llbit/chunky/block/WallHangingSign.java | 71 +++++ .../java/se/llbit/chunky/entity/Entity.java | 2 + .../chunky/entity/HangingSignEntity.java | 211 +++++++++++++- .../chunky/entity/WallHangingSignEntity.java | 273 ++++++++++++++++++ .../src/java/se/llbit/chunky/model/Model.java | 12 + chunky/src/java/se/llbit/math/Quad.java | 3 +- 7 files changed, 568 insertions(+), 10 deletions(-) create mode 100644 chunky/src/java/se/llbit/chunky/block/WallHangingSign.java create mode 100644 chunky/src/java/se/llbit/chunky/entity/WallHangingSignEntity.java diff --git a/chunky/src/java/se/llbit/chunky/block/MinecraftBlockProvider.java b/chunky/src/java/se/llbit/chunky/block/MinecraftBlockProvider.java index 12761d2d81..85431ad141 100644 --- a/chunky/src/java/se/llbit/chunky/block/MinecraftBlockProvider.java +++ b/chunky/src/java/se/llbit/chunky/block/MinecraftBlockProvider.java @@ -1014,7 +1014,7 @@ private static void addBlocks(Texture texture, String... names) { addBlock("cherry_sign", (name, tag) -> sign(tag, "cherry")); addBlock("cherry_hanging_sign", (name, tag) -> hangingSign(tag, "cherry")); addBlock("cherry_wall_sign", (name, tag) -> wallSign(tag, "cherry")); - addBlock("cherry_wall_hanging_sign", (name, tag) -> hangingSign(tag, "cherry")); + addBlock("cherry_wall_hanging_sign", (name, tag) -> wallHangingSign(tag, "cherry")); addBlock("cherry_slab", (name, tag) -> slab(tag, Texture.cherryPlanks)); addBlock("cherry_stairs", (name, tag) -> stairs(tag, Texture.cherryPlanks)); addBlock("cherry_trapdoor", (name, tag) -> trapdoor(tag, Texture.cherryTrapdoor)); @@ -3268,6 +3268,10 @@ private static Block hangingSign(Tag tag, String material) { return new HangingSign(name, material, rotation, attached); } + private static Block wallHangingSign(Tag tag, String material) { + return new WallHangingSign(BlockProvider.blockName(tag), material, BlockProvider.facing(tag)); + } + private static Block banner(Tag tag, Texture texture, int color) { String name = BlockProvider.blockName(tag); int rotation = BlockProvider.stringToInt(tag.get("Properties").get("rotation"), 0); diff --git a/chunky/src/java/se/llbit/chunky/block/WallHangingSign.java b/chunky/src/java/se/llbit/chunky/block/WallHangingSign.java new file mode 100644 index 0000000000..11f5ab745f --- /dev/null +++ b/chunky/src/java/se/llbit/chunky/block/WallHangingSign.java @@ -0,0 +1,71 @@ +package se.llbit.chunky.block; + +import se.llbit.chunky.entity.Entity; +import se.llbit.chunky.entity.SignEntity; +import se.llbit.chunky.entity.WallHangingSignEntity; +import se.llbit.chunky.renderer.scene.Scene; +import se.llbit.math.Ray; +import se.llbit.math.Vector3; +import se.llbit.nbt.CompoundTag; + +public class WallHangingSign extends MinecraftBlockTranslucent { + private final String material; + private final Facing facing; + + public WallHangingSign(String name, String material, String facing) { + super(name, SignEntity.textureFromMaterial(material)); + this.material = material; + this.facing = Facing.fromString(facing); + invisible = true; + solid = false; + localIntersect = true; + } + + @Override + public boolean intersect(Ray ray, Scene scene) { + return false; + } + + @Override + public boolean isBlockEntity() { + return true; + } + + @Override + public Entity toBlockEntity(Vector3 position, CompoundTag entityTag) { + return new WallHangingSignEntity(position, entityTag, facing, material); + } + + public enum Facing { + NORTH, EAST, SOUTH, WEST; + + public static Facing fromString(String facing) { + switch (facing) { + case "east": + return EAST; + case "south": + return SOUTH; + case "west": + return WEST; + case "north": + default: + return NORTH; + } + } + + @Override + public String toString() { + switch (this) { + case EAST: + return "east"; + case SOUTH: + return "south"; + case WEST: + return "west"; + case NORTH: + default: + return "north"; + } + } + } +} diff --git a/chunky/src/java/se/llbit/chunky/entity/Entity.java b/chunky/src/java/se/llbit/chunky/entity/Entity.java index d64e7f3ef1..eef4c594c4 100644 --- a/chunky/src/java/se/llbit/chunky/entity/Entity.java +++ b/chunky/src/java/se/llbit/chunky/entity/Entity.java @@ -116,6 +116,8 @@ public static Entity fromJson(JsonObject json) { return CalibratedSculkSensorAmethyst.fromJson(json); case "hangingSign": return HangingSignEntity.fromJson(json); + case "wallHangingSign": + return WallHangingSignEntity.fromJson(json); } return null; } diff --git a/chunky/src/java/se/llbit/chunky/entity/HangingSignEntity.java b/chunky/src/java/se/llbit/chunky/entity/HangingSignEntity.java index b7ba8aed57..786cfe167c 100644 --- a/chunky/src/java/se/llbit/chunky/entity/HangingSignEntity.java +++ b/chunky/src/java/se/llbit/chunky/entity/HangingSignEntity.java @@ -1,20 +1,212 @@ package se.llbit.chunky.entity; +import se.llbit.chunky.model.Model; import se.llbit.chunky.resources.SignTexture; import se.llbit.chunky.resources.Texture; +import se.llbit.chunky.world.material.TextureMaterial; import se.llbit.json.JsonArray; import se.llbit.json.JsonObject; import se.llbit.json.JsonValue; +import se.llbit.math.Quad; +import se.llbit.math.Transform; import se.llbit.math.Vector3; +import se.llbit.math.Vector4; import se.llbit.math.primitive.Primitive; import se.llbit.nbt.CompoundTag; import java.util.Collection; import java.util.LinkedHashSet; -import static se.llbit.chunky.entity.SignEntity.*; - public class HangingSignEntity extends Entity { + private static final Quad[] quadsAttached = new Quad[]{ + new Quad( + new Vector3(-7 / 16.0, 10 / 16.0, 1 / 16.0), + new Vector3(7 / 16.0, 10 / 16.0, 1 / 16.0), + new Vector3(-7 / 16.0, 10 / 16.0, -1 / 16.0), + new Vector4(0 / 16.0, 16 / 16.0, 0 / 16.0, 16 / 16.0) + ), + new Quad( + new Vector3(-7 / 16.0, 0 / 16.0, -1 / 16.0), + new Vector3(7 / 16.0, 0 / 16.0, -1 / 16.0), + new Vector3(-7 / 16.0, 0 / 16.0, 1 / 16.0), + new Vector4(0 / 16.0, 16 / 16.0, 0 / 16.0, 16 / 16.0) + ), + new Quad( + new Vector3(-7 / 16.0, 10 / 16.0, 1 / 16.0), + new Vector3(-7 / 16.0, 10 / 16.0, -1 / 16.0), + new Vector3(-7 / 16.0, 0 / 16.0, 1 / 16.0), + new Vector4(16 / 16.0, 0 / 16.0, 16 / 16.0, 0 / 16.0) + ), + new Quad( + new Vector3(7 / 16.0, 10 / 16.0, -1 / 16.0), + new Vector3(7 / 16.0, 10 / 16.0, 1 / 16.0), + new Vector3(7 / 16.0, 0 / 16.0, -1 / 16.0), + new Vector4(16 / 16.0, 0 / 16.0, 16 / 16.0, 0 / 16.0) + ), + new Quad( + new Vector3(-7 / 16.0, 10 / 16.0, -1 / 16.0), + new Vector3(7 / 16.0, 10 / 16.0, -1 / 16.0), + new Vector3(-7 / 16.0, 0 / 16.0, -1 / 16.0), + new Vector4(16 / 16.0, 0 / 16.0, 16 / 16.0, 0 / 16.0) + ), + new Quad( + new Vector3(7 / 16.0, 10 / 16.0, 1 / 16.0), + new Vector3(-7 / 16.0, 10 / 16.0, 1 / 16.0), + new Vector3(7 / 16.0, 0 / 16.0, 1 / 16.0), + new Vector4(16 / 16.0, 0 / 16.0, 16 / 16.0, 0 / 16.0) + ), + new Quad( + new Vector3(-6 / 16.0, 16 / 16.0, 0 / 16.0), + new Vector3(6 / 16.0, 16 / 16.0, 0 / 16.0), + new Vector3(-6 / 16.0, 10 / 16.0, 0 / 16.0), + new Vector4(16 / 16.0, 0 / 16.0, 16 / 16.0, 0 / 16.0) + ), + new Quad( + new Vector3(6 / 16.0, 16 / 16.0, 0 / 16.0), + new Vector3(-6 / 16.0, 16 / 16.0, 0 / 16.0), + new Vector3(6 / 16.0, 10 / 16.0, 0 / 16.0), + new Vector4(16 / 16.0, 0 / 16.0, 16 / 16.0, 0 / 16.0) + ) + }; + + private static final Quad[] quadsNotAttached = Model.join( + new Quad[]{ + new Quad( + new Vector3(-7 / 16.0, 10 / 16.0, 1 / 16.0), + new Vector3(7 / 16.0, 10 / 16.0, 1 / 16.0), + new Vector3(-7 / 16.0, 10 / 16.0, -1 / 16.0), + new Vector4(0 / 16.0, 16 / 16.0, 0 / 16.0, 16 / 16.0) + ), + new Quad( + new Vector3(-7 / 16.0, 0 / 16.0, -1 / 16.0), + new Vector3(7 / 16.0, 0 / 16.0, -1 / 16.0), + new Vector3(-7 / 16.0, 0 / 16.0, 1 / 16.0), + new Vector4(0 / 16.0, 16 / 16.0, 0 / 16.0, 16 / 16.0) + ), + new Quad( + new Vector3(-7 / 16.0, 10 / 16.0, 1 / 16.0), + new Vector3(-7 / 16.0, 10 / 16.0, -1 / 16.0), + new Vector3(-7 / 16.0, 0 / 16.0, 1 / 16.0), + new Vector4(16 / 16.0, 0 / 16.0, 16 / 16.0, 0 / 16.0) + ), + new Quad( + new Vector3(7 / 16.0, 10 / 16.0, -1 / 16.0), + new Vector3(7 / 16.0, 10 / 16.0, 1 / 16.0), + new Vector3(7 / 16.0, 0 / 16.0, -1 / 16.0), + new Vector4(16 / 16.0, 0 / 16.0, 16 / 16.0, 0 / 16.0) + ), + new Quad( + new Vector3(-7 / 16.0, 10 / 16.0, -1 / 16.0), + new Vector3(7 / 16.0, 10 / 16.0, -1 / 16.0), + new Vector3(-7 / 16.0, 0 / 16.0, -1 / 16.0), + new Vector4(16 / 16.0, 0 / 16.0, 16 / 16.0, 0 / 16.0) + ), + new Quad( + new Vector3(7 / 16.0, 10 / 16.0, 1 / 16.0), + new Vector3(-7 / 16.0, 10 / 16.0, 1 / 16.0), + new Vector3(7 / 16.0, 0 / 16.0, 1 / 16.0), + new Vector4(16 / 16.0, 0 / 16.0, 16 / 16.0, 0 / 16.0) + ) + }, + Model.transform( + new Quad[]{ + new Quad( + new Vector3(-1.5 / 16.0, 16 / 16.0, 0 / 16.0), + new Vector3(1.5 / 16.0, 16 / 16.0, 0 / 16.0), + new Vector3(-1.5 / 16.0, 10 / 16.0, 0 / 16.0), + new Vector4(16 / 16.0, 0 / 16.0, 16 / 16.0, 0 / 16.0) + ), + new Quad( + new Vector3(1.5 / 16.0, 16 / 16.0, 0 / 16.0), + new Vector3(-1.5 / 16.0, 16 / 16.0, 0 / 16.0), + new Vector3(1.5 / 16.0, 10 / 16.0, 0 / 16.0), + new Vector4(16 / 16.0, 0 / 16.0, 16 / 16.0, 0 / 16.0) + ) + }, + Transform.NONE + .translate(0.5, 0.5, 0.5) + .rotateY(Math.toRadians(-45)) + .translate(-0.5, -0.5, -0.5) + .translate(-5 / 16.0, 0 / 16.0, 0 / 16.0) + ), + Model.transform( + new Quad[]{ + new Quad( + new Vector3(-1.5 / 16.0, 16 / 16.0, 0 / 16.0), + new Vector3(1.5 / 16.0, 16 / 16.0, 0 / 16.0), + new Vector3(-1.5 / 16.0, 10 / 16.0, 0 / 16.0), + new Vector4(16 / 16.0, 0 / 16.0, 16 / 16.0, 0 / 16.0) + ), + new Quad( + new Vector3(1.5 / 16.0, 16 / 16.0, 0 / 16.0), + new Vector3(-1.5 / 16.0, 16 / 16.0, 0 / 16.0), + new Vector3(1.5 / 16.0, 10 / 16.0, 0 / 16.0), + new Vector4(16 / 16.0, 0 / 16.0, 16 / 16.0, 0 / 16.0) + ) + }, + Transform.NONE + .translate(0.5, 0.5, 0.5) + .rotateY(Math.toRadians(45)) + .translate(-0.5, -0.5, -0.5) + .translate(-5 / 16.0, 0 / 16.0, 0 / 16.0) + ), + Model.transform( + new Quad[]{ + new Quad( + new Vector3(-1.5 / 16.0, 16 / 16.0, 0 / 16.0), + new Vector3(1.5 / 16.0, 16 / 16.0, 0 / 16.0), + new Vector3(-1.5 / 16.0, 10 / 16.0, 0 / 16.0), + new Vector4(16 / 16.0, 0 / 16.0, 16 / 16.0, 0 / 16.0) + ), + new Quad( + new Vector3(1.5 / 16.0, 16 / 16.0, 0 / 16.0), + new Vector3(-1.5 / 16.0, 16 / 16.0, 0 / 16.0), + new Vector3(1.5 / 16.0, 10 / 16.0, 0 / 16.0), + new Vector4(16 / 16.0, 0 / 16.0, 16 / 16.0, 0 / 16.0) + ) + }, + Transform.NONE + .translate(0.5, 0.5, 0.5) + .rotateY(Math.toRadians(-45)) + .translate(-0.5, -0.5, -0.5) + .translate(5 / 16.0, 0 / 16.0, 0 / 16.0) + ), + Model.transform( + new Quad[]{ + new Quad( + new Vector3(-1.5 / 16.0, 16 / 16.0, 0 / 16.0), + new Vector3(1.5 / 16.0, 16 / 16.0, 0 / 16.0), + new Vector3(-1.5 / 16.0, 10 / 16.0, 0 / 16.0), + new Vector4(16 / 16.0, 0 / 16.0, 16 / 16.0, 0 / 16.0) + ), + new Quad( + new Vector3(1.5 / 16.0, 16 / 16.0, 0 / 16.0), + new Vector3(-1.5 / 16.0, 16 / 16.0, 0 / 16.0), + new Vector3(1.5 / 16.0, 10 / 16.0, 0 / 16.0), + new Vector4(16 / 16.0, 0 / 16.0, 16 / 16.0, 0 / 16.0) + ) + }, + Transform.NONE + .translate(0.5, 0.5, 0.5) + .rotateY(Math.toRadians(45)) + .translate(-0.5, -0.5, -0.5) + .translate(5 / 16.0, 0 / 16.0, 0 / 16.0) + ) + ); + + private static Quad[][] rotatedQuadsAttached = new Quad[16][]; + private static Quad[][] rotatedQuadsNotAttached = new Quad[16][]; + + static { + rotatedQuadsAttached[0] = Model.translate(quadsAttached, 0.5, 0, 0.5); + rotatedQuadsNotAttached[0] = Model.translate(quadsNotAttached, 0.5, 0, 0.5); + + for (int i = 1; i < 16; ++i) { + rotatedQuadsAttached[i] = Model.rotateY(rotatedQuadsAttached[0], -i * Math.PI / 8); + rotatedQuadsNotAttached[i] = Model.rotateY(rotatedQuadsNotAttached[0], -i * Math.PI / 8); + } + } + private final JsonArray[] frontText; private final JsonArray[] backText; private final int angle; @@ -25,7 +217,7 @@ public class HangingSignEntity extends Entity { private final String material; public HangingSignEntity(Vector3 position, CompoundTag entityTag, int rotation, boolean attached, String material) { - this(position, getFrontTextLines(entityTag), getBackTextLines(entityTag), rotation, attached, material); + this(position, SignEntity.getFrontTextLines(entityTag), SignEntity.getBackTextLines(entityTag), rotation, attached, material); } public HangingSignEntity(Vector3 position, JsonArray[] frontText, JsonArray[] backText, int rotation, boolean attached, String material) { @@ -43,8 +235,13 @@ public HangingSignEntity(Vector3 position, JsonArray[] frontText, JsonArray[] ba @Override public Collection primitives(Vector3 offset) { - // TODO - return new LinkedHashSet<>(); + LinkedHashSet set = new LinkedHashSet<>(); + Quad[] quads = attached ? rotatedQuadsAttached[angle] : rotatedQuadsNotAttached[angle]; + for (Quad quad : quads) { + quad.addTriangles(set, new TextureMaterial(Texture.redWool), + Transform.NONE.translate(position.x + offset.x, position.y + offset.y, position.z + offset.z)); + } + return set; } @Override @@ -72,11 +269,11 @@ public static Entity fromJson(JsonObject json) { position.fromJson(json.get("position").object()); JsonArray[] frontText = null; if (json.get("text").isArray()) { - frontText = textFromJson(json.get("text")); + frontText = SignEntity.textFromJson(json.get("text")); } JsonArray[] backText = null; if (json.get("backText").isArray()) { - backText = textFromJson(json.get("backText")); + backText = SignEntity.textFromJson(json.get("backText")); } int direction = json.get("direction").intValue(0); boolean attached = json.get("attached").boolValue(false); diff --git a/chunky/src/java/se/llbit/chunky/entity/WallHangingSignEntity.java b/chunky/src/java/se/llbit/chunky/entity/WallHangingSignEntity.java new file mode 100644 index 0000000000..f36631ec72 --- /dev/null +++ b/chunky/src/java/se/llbit/chunky/entity/WallHangingSignEntity.java @@ -0,0 +1,273 @@ +package se.llbit.chunky.entity; + +import se.llbit.chunky.block.WallHangingSign; +import se.llbit.chunky.model.Model; +import se.llbit.chunky.resources.SignTexture; +import se.llbit.chunky.resources.Texture; +import se.llbit.chunky.world.material.TextureMaterial; +import se.llbit.json.JsonArray; +import se.llbit.json.JsonObject; +import se.llbit.json.JsonValue; +import se.llbit.math.Quad; +import se.llbit.math.Transform; +import se.llbit.math.Vector3; +import se.llbit.math.Vector4; +import se.llbit.math.primitive.Primitive; +import se.llbit.nbt.CompoundTag; + +import java.util.Collection; +import java.util.LinkedHashSet; + +public class WallHangingSignEntity extends Entity { + private static final Quad[] quads = Model.join( + new Quad[]{ + new Quad( + new Vector3(-7 / 16.0, 10 / 16.0, 1 / 16.0), + new Vector3(7 / 16.0, 10 / 16.0, 1 / 16.0), + new Vector3(-7 / 16.0, 10 / 16.0, -1 / 16.0), + new Vector4(0 / 16.0, 16 / 16.0, 0 / 16.0, 16 / 16.0) + ), + new Quad( + new Vector3(-7 / 16.0, 0 / 16.0, -1 / 16.0), + new Vector3(7 / 16.0, 0 / 16.0, -1 / 16.0), + new Vector3(-7 / 16.0, 0 / 16.0, 1 / 16.0), + new Vector4(0 / 16.0, 16 / 16.0, 0 / 16.0, 16 / 16.0) + ), + new Quad( + new Vector3(-7 / 16.0, 10 / 16.0, 1 / 16.0), + new Vector3(-7 / 16.0, 10 / 16.0, -1 / 16.0), + new Vector3(-7 / 16.0, 0 / 16.0, 1 / 16.0), + new Vector4(16 / 16.0, 0 / 16.0, 16 / 16.0, 0 / 16.0) + ), + new Quad( + new Vector3(7 / 16.0, 10 / 16.0, -1 / 16.0), + new Vector3(7 / 16.0, 10 / 16.0, 1 / 16.0), + new Vector3(7 / 16.0, 0 / 16.0, -1 / 16.0), + new Vector4(16 / 16.0, 0 / 16.0, 16 / 16.0, 0 / 16.0) + ), + new Quad( + new Vector3(-7 / 16.0, 10 / 16.0, -1 / 16.0), + new Vector3(7 / 16.0, 10 / 16.0, -1 / 16.0), + new Vector3(-7 / 16.0, 0 / 16.0, -1 / 16.0), + new Vector4(16 / 16.0, 0 / 16.0, 16 / 16.0, 0 / 16.0) + ), + new Quad( + new Vector3(7 / 16.0, 10 / 16.0, 1 / 16.0), + new Vector3(-7 / 16.0, 10 / 16.0, 1 / 16.0), + new Vector3(7 / 16.0, 0 / 16.0, 1 / 16.0), + new Vector4(16 / 16.0, 0 / 16.0, 16 / 16.0, 0 / 16.0) + ) + }, + new Quad[]{ + new Quad( + new Vector3(-8 / 16.0, 16 / 16.0, 2 / 16.0), + new Vector3(8 / 16.0, 16 / 16.0, 2 / 16.0), + new Vector3(-8 / 16.0, 16 / 16.0, -2 / 16.0), + new Vector4(0 / 16.0, 16 / 16.0, 0 / 16.0, 16 / 16.0) + ), + new Quad( + new Vector3(-8 / 16.0, 14 / 16.0, -2 / 16.0), + new Vector3(8 / 16.0, 14 / 16.0, -2 / 16.0), + new Vector3(-8 / 16.0, 14 / 16.0, 2 / 16.0), + new Vector4(0 / 16.0, 16 / 16.0, 0 / 16.0, 16 / 16.0) + ), + new Quad( + new Vector3(-8 / 16.0, 16 / 16.0, 2 / 16.0), + new Vector3(-8 / 16.0, 16 / 16.0, -2 / 16.0), + new Vector3(-8 / 16.0, 14 / 16.0, 2 / 16.0), + new Vector4(16 / 16.0, 0 / 16.0, 16 / 16.0, 0 / 16.0) + ), + new Quad( + new Vector3(8 / 16.0, 16 / 16.0, -2 / 16.0), + new Vector3(8 / 16.0, 16 / 16.0, 2 / 16.0), + new Vector3(8 / 16.0, 14 / 16.0, -2 / 16.0), + new Vector4(16 / 16.0, 0 / 16.0, 16 / 16.0, 0 / 16.0) + ), + new Quad( + new Vector3(-8 / 16.0, 16 / 16.0, -2 / 16.0), + new Vector3(8 / 16.0, 16 / 16.0, -2 / 16.0), + new Vector3(-8 / 16.0, 14 / 16.0, -2 / 16.0), + new Vector4(16 / 16.0, 0 / 16.0, 16 / 16.0, 0 / 16.0) + ), + new Quad( + new Vector3(8 / 16.0, 16 / 16.0, 2 / 16.0), + new Vector3(-8 / 16.0, 16 / 16.0, 2 / 16.0), + new Vector3(8 / 16.0, 14 / 16.0, 2 / 16.0), + new Vector4(16 / 16.0, 0 / 16.0, 16 / 16.0, 0 / 16.0) + ) + }, + Model.transform( + new Quad[]{ + new Quad( + new Vector3(-1.5 / 16.0, 10 / 16.0, 0 / 16.0), + new Vector3(1.5 / 16.0, 10 / 16.0, 0 / 16.0), + new Vector3(-1.5 / 16.0, 4 / 16.0, 0 / 16.0), + new Vector4(16 / 16.0, 0 / 16.0, 16 / 16.0, 0 / 16.0) + ), + new Quad( + new Vector3(1.5 / 16.0, 10 / 16.0, 0 / 16.0), + new Vector3(-1.5 / 16.0, 10 / 16.0, 0 / 16.0), + new Vector3(1.5 / 16.0, 4 / 16.0, 0 / 16.0), + new Vector4(16 / 16.0, 0 / 16.0, 16 / 16.0, 0 / 16.0) + ) + }, + Transform.NONE + .translate(0.5, 0.5, 0.5) + .rotateY(Math.toRadians(-45)) + .translate(-0.5, -0.5, -0.5) + .translate(-5 / 16.0, 6 / 16.0, 0 / 16.0) + ), + Model.transform( + new Quad[]{ + new Quad( + new Vector3(-1.5 / 16.0, 10 / 16.0, 0 / 16.0), + new Vector3(1.5 / 16.0, 10 / 16.0, 0 / 16.0), + new Vector3(-1.5 / 16.0, 4 / 16.0, 0 / 16.0), + new Vector4(16 / 16.0, 0 / 16.0, 16 / 16.0, 0 / 16.0) + ), + new Quad( + new Vector3(1.5 / 16.0, 10 / 16.0, 0 / 16.0), + new Vector3(-1.5 / 16.0, 10 / 16.0, 0 / 16.0), + new Vector3(1.5 / 16.0, 4 / 16.0, 0 / 16.0), + new Vector4(16 / 16.0, 0 / 16.0, 16 / 16.0, 0 / 16.0) + ) + }, + Transform.NONE + .translate(0.5, 0.5, 0.5) + .rotateY(Math.toRadians(45)) + .translate(-0.5, -0.5, -0.5) + .translate(-5 / 16.0, 6 / 16.0, 0 / 16.0) + ), + Model.transform( + new Quad[]{ + new Quad( + new Vector3(-1.5 / 16.0, 10 / 16.0, 0 / 16.0), + new Vector3(1.5 / 16.0, 10 / 16.0, 0 / 16.0), + new Vector3(-1.5 / 16.0, 4 / 16.0, 0 / 16.0), + new Vector4(16 / 16.0, 0 / 16.0, 16 / 16.0, 0 / 16.0) + ), + new Quad( + new Vector3(1.5 / 16.0, 10 / 16.0, 0 / 16.0), + new Vector3(-1.5 / 16.0, 10 / 16.0, 0 / 16.0), + new Vector3(1.5 / 16.0, 4 / 16.0, 0 / 16.0), + new Vector4(16 / 16.0, 0 / 16.0, 16 / 16.0, 0 / 16.0) + ) + }, + Transform.NONE + .translate(0.5, 0.5, 0.5) + .rotateY(Math.toRadians(-45)) + .translate(-0.5, -0.5, -0.5) + .translate(5 / 16.0, 6 / 16.0, 0 / 16.0) + ), + Model.transform( + new Quad[]{ + new Quad( + new Vector3(-1.5 / 16.0, 10 / 16.0, 0 / 16.0), + new Vector3(1.5 / 16.0, 10 / 16.0, 0 / 16.0), + new Vector3(-1.5 / 16.0, 4 / 16.0, 0 / 16.0), + new Vector4(16 / 16.0, 0 / 16.0, 16 / 16.0, 0 / 16.0) + ), + new Quad( + new Vector3(1.5 / 16.0, 10 / 16.0, 0 / 16.0), + new Vector3(-1.5 / 16.0, 10 / 16.0, 0 / 16.0), + new Vector3(1.5 / 16.0, 4 / 16.0, 0 / 16.0), + new Vector4(16 / 16.0, 0 / 16.0, 16 / 16.0, 0 / 16.0) + ) + }, + Transform.NONE + .translate(0.5, 0.5, 0.5) + .rotateY(Math.toRadians(45)) + .translate(-0.5, -0.5, -0.5) + .translate(5 / 16.0, 6 / 16.0, 0 / 16.0) + ) + ); + private static Quad[][] rotatedQuads = new Quad[4][]; + + static { + rotatedQuads[0] = Model.translate(quads, 0.5, 0, 0.5); + rotatedQuads[1] = Model.rotateY(rotatedQuads[0]); + rotatedQuads[2] = Model.rotateY(rotatedQuads[1]); + rotatedQuads[3] = Model.rotateY(rotatedQuads[2]); + } + + private final JsonArray[] frontText; + private final JsonArray[] backText; + private final WallHangingSign.Facing orientation; + private final SignTexture frontTexture; + private final SignTexture backTexture; + private final Texture texture; + private final String material; + + public WallHangingSignEntity(Vector3 position, CompoundTag entityTag, WallHangingSign.Facing direction, String material) { + this(position, SignEntity.getFrontTextLines(entityTag), SignEntity.getBackTextLines(entityTag), direction, material); + } + + public WallHangingSignEntity(Vector3 position, JsonArray[] frontText, JsonArray[] backText, WallHangingSign.Facing direction, String material) { + super(position); + Texture signTexture = SignEntity.textureFromMaterial(material); + this.frontText = frontText; + this.backText = backText; + this.orientation = direction; + this.frontTexture = frontText != null ? new SignTexture(frontText, signTexture, false) : null; + this.backTexture = backText != null ? new SignTexture(backText, signTexture, true) : null; + this.texture = signTexture; + this.material = material; + } + + @Override + public Collection primitives(Vector3 offset) { + LinkedHashSet set = new LinkedHashSet<>(); + Quad[] quads = rotatedQuads[0]; + switch (orientation) { + case EAST: + quads = rotatedQuads[1]; + break; + case SOUTH: + quads = rotatedQuads[2]; + break; + case WEST: + quads = rotatedQuads[3]; + break; + } + for (Quad quad : quads) { + quad.addTriangles(set, new TextureMaterial(Texture.lightBlueWool), + Transform.NONE.translate(position.x + offset.x, position.y + offset.y, position.z + offset.z)); + } + return set; + } + + @Override + public JsonValue toJson() { + JsonObject json = new JsonObject(); + json.add("kind", "wallHangingSign"); + json.add("position", position.toJson()); + if (frontText != null) { + json.add("text", SignEntity.textToJson(frontText)); + } + if (backText != null) { + json.add("backText", SignEntity.textToJson(backText)); + } + json.add("direction", orientation.toString()); + json.add("material", material); + return json; + } + + /** + * Unmarshalls a sign entity from JSON data. + */ + public static Entity fromJson(JsonObject json) { + Vector3 position = new Vector3(); + position.fromJson(json.get("position").object()); + JsonArray[] frontText = null; + if (json.get("text").isArray()) { + frontText = SignEntity.textFromJson(json.get("text")); + } + JsonArray[] backText = null; + if (json.get("backText").isArray()) { + backText = SignEntity.textFromJson(json.get("backText")); + } + WallHangingSign.Facing direction = WallHangingSign.Facing.fromString(json.get("direction").stringValue("north")); + String material = json.get("material").stringValue("oak"); + return new WallHangingSignEntity(position, frontText, backText, direction, material); + } +} diff --git a/chunky/src/java/se/llbit/chunky/model/Model.java b/chunky/src/java/se/llbit/chunky/model/Model.java index 29d4b2653e..32b22c0e7d 100644 --- a/chunky/src/java/se/llbit/chunky/model/Model.java +++ b/chunky/src/java/se/llbit/chunky/model/Model.java @@ -226,6 +226,18 @@ public static Quad[] scale(Quad[] src, double scale) { return out; } + /** + * @param src source quads + * @return Quads rotated about the Z axis by some angle + */ + public static Quad[] transform(Quad[] src, Transform transform) { + Quad[] rot = new Quad[src.length]; + for (int i = 0; i < src.length; ++i) { + rot[i] = src[i].transform(transform); + } + return rot; + } + /** * @param models source quads * @return All quads merged into a single array diff --git a/chunky/src/java/se/llbit/math/Quad.java b/chunky/src/java/se/llbit/math/Quad.java index 97f41a4b3c..336ed7a489 100644 --- a/chunky/src/java/se/llbit/math/Quad.java +++ b/chunky/src/java/se/llbit/math/Quad.java @@ -200,8 +200,7 @@ public Quad getScaled(double scale) { return new Quad(this, transform); } - public void addTriangles(Collection primitives, Material material, - Transform transform) { + public void addTriangles(Collection primitives, Material material, Transform transform) { Vector3 c0 = new Vector3(o); Vector3 c1 = new Vector3(); Vector3 c2 = new Vector3();