From c6b1f53b44767224960b5258d0f8a3ec16b519d1 Mon Sep 17 00:00:00 2001 From: gnembon <41132274+gnembon@users.noreply.github.com> Date: Sat, 15 Oct 2022 12:48:39 +0200 Subject: [PATCH] shapes 'facing' now defaults to player and player is correctly rendered facing player face, not camera plane. --- docs/scarpet/api/Auxiliary.md | 10 +-- .../carpet/script/utils/ShapeDispatcher.java | 29 ++------ .../carpet/script/utils/ShapesRenderer.java | 73 ++++--------------- .../script/utils/shapes/ShapeDirection.java | 60 +++++++++++++++ 4 files changed, 84 insertions(+), 88 deletions(-) create mode 100644 src/main/java/carpet/script/utils/shapes/ShapeDirection.java diff --git a/docs/scarpet/api/Auxiliary.md b/docs/scarpet/api/Auxiliary.md index f69f510b..cc2a03fa 100644 --- a/docs/scarpet/api/Auxiliary.md +++ b/docs/scarpet/api/Auxiliary.md @@ -92,6 +92,10 @@ Optional shared shape attributes: instance makes so that the shape follows the entity, but stays at the same, absolute Y coordinate. Preceeding an axis with `d`, like `dxdydz` would make so that entity position is treated discretely (rounded down). * `debug` - if True, it will only be visible when F3+B entity bounding boxes is enabled. + * `facing` - applicable only to `'text'`, `'block'` or '`item'` shapes, where its facing. Possible options are: + * `player`: Default. Element always rotates to face the player eye position, + * `camera`: Element is placed on the plane orthogonal to player look vector, + * `north`, `south`, `east`, `west`, `up`, `down`: obvious Available shapes: * `'line'` - draws a straight line between two points. @@ -141,8 +145,6 @@ Available shapes: display smoothly dynamic elements where value of an element is constantly changing and updates to it are being sent from the server. * `size` - float. Default font size is 10. - * `facing` - text direction, where its facing. Possible options are: `player` (default, text - always rotates to face the player), `north`, `south`, `east`, `west`, `up`, `down` * `doublesided` - if `true` it will make the text visible from the back as well. Default is `false` (1.16+) * `align` - text alignment with regards to `pos`. Default is `center` (displayed text is centered with respect to `pos`), `left` (`pos` indicates beginning of text), and `right` (`pos` @@ -157,8 +159,6 @@ Available shapes: * `pos` - position of the object. * `block` - the object to show. It is a block value or a name of a block with optional NBT data. * Optional attributes: - * `facing` - object's direction, where its facing. Possible options are: `player` (it - rotates to face the player), `north`(default), `south`, `east`, `west`, `up`, `down` * `tilt`, `lean`, `turn` - additional rotations along all three axis. It uses the block center as the origin. * `scale` - scale of it in 3 axis-direction. should be a number or a list of 3 numbers (x,y,z). * `skylight`, `blocklight` - light level. omit it to use local light level. should between 0~15. @@ -168,8 +168,6 @@ Available shapes: * `pos` - position of the object. * `item` - the object to show. It is an item tuple or a string identified item that may have NBT data. * Optional attributes: - * `facing` - object's direction, where its facing. Possible options are: `player` (it - always rotates to face the player), `north`(default), `south`, `east`, `west`, `up`, `down` * `tilt`, `lean`, `turn` - additional rotations along all three axis. for `block`, it use its block center as the origin. * `scale` - scale of it in 3 axis-direction. should be a number or a list of 3 numbers (x,y,z). * `skylight`, `blocklight` - light level. omit it to use local light level. should between 0~15. diff --git a/src/main/java/carpet/script/utils/ShapeDispatcher.java b/src/main/java/carpet/script/utils/ShapeDispatcher.java index ef6cc767..33770b45 100644 --- a/src/main/java/carpet/script/utils/ShapeDispatcher.java +++ b/src/main/java/carpet/script/utils/ShapeDispatcher.java @@ -6,6 +6,7 @@ import carpet.script.exception.InternalExpressionException; import carpet.script.exception.ThrowStatement; import carpet.script.exception.Throwables; import carpet.script.language.Sys; +import carpet.script.utils.shapes.ShapeDirection; import carpet.script.value.AbstractListValue; import carpet.script.value.BlockValue; import carpet.script.value.BooleanValue; @@ -68,6 +69,7 @@ import java.util.Set; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; +import java.util.stream.Collectors; import static java.util.Map.entry; @@ -472,7 +474,7 @@ public class ShapeDispatcher int textcolor; int textbck; - Direction facing; + ShapeDirection facing; float raise; float tilt; float lean; @@ -498,16 +500,7 @@ public class ShapeDispatcher textcolor = rgba2argb(color); textbck = rgba2argb(fillColor); String dir = options.getOrDefault("facing", optional.get("facing")).getString(); - facing = null; - switch (dir) - { - case "north": facing = Direction.NORTH; break; - case "south": facing = Direction.SOUTH; break; - case "east": facing = Direction.EAST; break; - case "west": facing = Direction.WEST; break; - case "up": facing = Direction.UP; break; - case "down": facing = Direction.DOWN; break; - } + facing = ShapeDirection.fromString(dir); align = 0; if (options.containsKey("align")) { @@ -596,7 +589,7 @@ public class ShapeDispatcher Vec3 pos; - Direction facing; + ShapeDirection facing; float tilt; float lean; @@ -640,15 +633,7 @@ public class ShapeDispatcher } String dir = options.getOrDefault("facing", optional.get("facing")).getString(); - facing = switch (dir) { - case "north" -> Direction.NORTH; - case "south" -> Direction.SOUTH; - case "east" -> Direction.EAST; - case "west" -> Direction.WEST; - case "up" -> Direction.UP; - case "down" -> Direction.DOWN; - default -> null; - }; + facing = ShapeDirection.fromString(dir); tilt = NumericValue.asNumber(options.getOrDefault("tilt", optional.get("tilt"))).getFloat(); lean = NumericValue.asNumber(options.getOrDefault("lean", optional.get("lean"))).getFloat(); @@ -1259,7 +1244,7 @@ public class ShapeDispatcher put("tilt", new FloatParam("tilt")); put("lean", new FloatParam("lean")); put("turn", new FloatParam("turn")); - put("facing", new StringChoiceParam("axis", "player", "north", "south", "east", "west", "up", "down")); + put("facing", new StringChoiceParam("facing", "player", "camera", "north", "south", "east", "west", "up", "down")); put("doublesided", new BoolParam("doublesided")); put("debug", new BoolParam("debug")); diff --git a/src/main/java/carpet/script/utils/ShapesRenderer.java b/src/main/java/carpet/script/utils/ShapesRenderer.java index 45812c12..463cdbfc 100644 --- a/src/main/java/carpet/script/utils/ShapesRenderer.java +++ b/src/main/java/carpet/script/utils/ShapesRenderer.java @@ -2,6 +2,7 @@ package carpet.script.utils; import carpet.CarpetSettings; import carpet.mixins.ShulkerBoxAccessMixin; +import carpet.script.utils.shapes.ShapeDirection; import carpet.utils.CarpetProfiler; import com.mojang.blaze3d.systems.RenderSystem; @@ -31,10 +32,8 @@ import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.Sheets; -import net.minecraft.client.renderer.block.model.ItemTransform; import net.minecraft.client.renderer.block.model.ItemTransforms; import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; -import net.minecraft.client.renderer.blockentity.ShulkerBoxRenderer; import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.client.resources.model.Material; import net.minecraft.core.BlockPos; @@ -281,45 +280,23 @@ public class ShapesRenderer { matrices.translate(0.5, 0.5, 0.5); } - matrices.translate(v1.x - cx, v1.y - cy, v1.z - cz); - if (shape.facing == null) - { - matrices.mulPose(camera1.rotation()); - matrices.mulPose(Vector3f.YP.rotationDegrees(180)); - } - else - { - switch (shape.facing) - { - case NORTH: - break; - case SOUTH: - matrices.mulPose(Vector3f.YP.rotationDegrees(180)); - break; - case EAST: - matrices.mulPose(Vector3f.YP.rotationDegrees(270)); - break; - case WEST: - matrices.mulPose(Vector3f.YP.rotationDegrees(90)); - break; - case UP: - matrices.mulPose(Vector3f.XP.rotationDegrees(90)); - break; - case DOWN: - matrices.mulPose(Vector3f.XP.rotationDegrees(-90)); - break; - } - } + matrices.translate(v1.x - cx, v1.y - cy, v1.z - cz); + ShapeDirection.rotatePoseStackByShapeDirection(matrices, shape.facing, camera1, isitem ? v1 : v1.add(0.5, 0.5, 0.5)); if (shape.tilt != 0.0f) matrices.mulPose(Vector3f.ZP.rotationDegrees(-shape.tilt)); if (shape.lean != 0.0f) matrices.mulPose(Vector3f.XP.rotationDegrees(-shape.lean)); if (shape.turn != 0.0f) matrices.mulPose(Vector3f.YP.rotationDegrees( shape.turn)); matrices.scale(shape.scaleX, shape.scaleY, shape.scaleZ); - if (!isitem)// blocks should use its center as the origin + if (!isitem) { + // blocks should use its center as the origin matrices.translate(-0.5, -0.5, -0.5); } + else { + // items seems to be flipped by default + matrices.mulPose(Vector3f.YP.rotationDegrees(180)); + } RenderSystem.depthMask(true); RenderSystem.enableCull(); @@ -386,6 +363,7 @@ public class ShapesRenderer { if (shape.item != null) { + // draw the item client.getItemRenderer().renderStatic(shape.item, transformType, light, OverlayTexture.NO_OVERLAY, matrices, immediate, (int) shape.key()); } @@ -464,34 +442,9 @@ public class ShapesRenderer RenderSystem.enableCull(); matrices.pushPose(); matrices.translate(v1.x - cx,v1.y - cy,v1.z - cz); - if (shape.facing == null) - { - //matrices.method_34425(new Matrix4f(camera1.getRotation())); - matrices.mulPose(camera1.rotation()); - } - else - { - switch (shape.facing) - { - case NORTH: - break; - case SOUTH: - matrices.mulPose(Vector3f.YP.rotationDegrees(180)); - break; - case EAST: - matrices.mulPose(Vector3f.YP.rotationDegrees(270)); - break; - case WEST: - matrices.mulPose(Vector3f.YP.rotationDegrees(90)); - break; - case UP: - matrices.mulPose(Vector3f.XP.rotationDegrees(90)); - break; - case DOWN: - matrices.mulPose(Vector3f.XP.rotationDegrees(-90)); - break; - } - } + + ShapeDirection.rotatePoseStackByShapeDirection(matrices, shape.facing, camera1, v1); + matrices.scale(shape.size* 0.0025f, -shape.size*0.0025f, shape.size*0.0025f); //RenderSystem.scalef(shape.size* 0.0025f, -shape.size*0.0025f, shape.size*0.0025f); if (shape.tilt!=0.0f) matrices.mulPose(Vector3f.ZP.rotationDegrees(shape.tilt)); diff --git a/src/main/java/carpet/script/utils/shapes/ShapeDirection.java b/src/main/java/carpet/script/utils/shapes/ShapeDirection.java new file mode 100644 index 00000000..b1a7fcaa --- /dev/null +++ b/src/main/java/carpet/script/utils/shapes/ShapeDirection.java @@ -0,0 +1,60 @@ +package carpet.script.utils.shapes; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.math.Vector3f; +import net.minecraft.client.Camera; +import net.minecraft.world.phys.Vec3; + +import java.util.Locale; + +public enum ShapeDirection { + NORTH, + SOUTH, + EAST, + WEST, + UP, + DOWN, + CAMERA, + PLAYER; + + public static ShapeDirection fromString(String direction) { + return switch (direction.toLowerCase(Locale.ROOT)) { + case "north" -> NORTH; + case "south" -> SOUTH; + case "east" -> EAST; + case "west" -> WEST; + case "up" -> UP; + case "down" -> DOWN; + case "camera" -> CAMERA; + case "player" -> PLAYER; + default -> null; + }; + } + + public static void rotatePoseStackByShapeDirection(PoseStack poseStack, ShapeDirection shapeDirection, Camera camera, Vec3 objectPos) { + switch (shapeDirection) { + case NORTH -> {} + case SOUTH -> poseStack.mulPose(Vector3f.YP.rotationDegrees(180)); + case EAST -> poseStack.mulPose(Vector3f.YP.rotationDegrees(270)); + case WEST -> poseStack.mulPose(Vector3f.YP.rotationDegrees(90)); + case UP -> poseStack.mulPose(Vector3f.XP.rotationDegrees(90)); + case DOWN -> poseStack.mulPose(Vector3f.XP.rotationDegrees(-90)); + case CAMERA -> poseStack.mulPose(camera.rotation()); + case PLAYER -> { + final Vec3 vector = objectPos.subtract(camera.getPosition()); + final double x = vector.x; + final double y = vector.y; + final double z = vector.z; + final double d = Math.sqrt(x * x + z * z); + final float rotX = (float) (Math.atan2(x, z)); + final float rotY = (float) (Math.atan2(y, d)); + + // that should work somehow but it doesn't for some reason + //matrices.mulPose(new Quaternion( -rotY, rotX, 0, false)); + + poseStack.mulPose(Vector3f.YP.rotation(rotX)); + poseStack.mulPose(Vector3f.XP.rotation(-rotY)); + } + } + } +}