From 427489ffe457ced8a97182e3e2583aa1843d39bf Mon Sep 17 00:00:00 2001 From: xTracr Date: Thu, 21 Dec 2023 23:06:07 +0800 Subject: [PATCH] Allowed to select surfaces of model & deleted the old analyser --- .../com/xtracr/realcamera/RealCameraCore.java | 49 ++-- .../realcamera/command/ClientCommand.java | 33 --- .../realcamera/config/ConfigScreen.java | 6 +- .../xtracr/realcamera/config/ModConfig.java | 4 +- .../xtracr/realcamera/gui/IntFieldWidget.java | 5 +- .../realcamera/gui/ModelViewScreen.java | 132 ++++++---- .../xtracr/realcamera/mixin/MixinCamera.java | 16 +- .../xtracr/realcamera/util/ModelAnalyser.java | 84 +++++++ .../realcamera/util/VertexDataAnalyser.java | 230 ------------------ .../realcamera/util/VertexDataCatcher.java | 19 +- .../assets/realcamera/lang/en_us.json | 19 +- .../assets/realcamera/lang/zh_cn.json | 18 +- .../xtracr/realcamera/RealCameraFabric.java | 2 - .../com/xtracr/realcamera/EventHandler.java | 7 - .../xtracr/realcamera/RealCameraForge.java | 1 - gradle.properties | 12 +- 16 files changed, 245 insertions(+), 392 deletions(-) create mode 100644 common/src/main/java/com/xtracr/realcamera/util/ModelAnalyser.java delete mode 100644 common/src/main/java/com/xtracr/realcamera/util/VertexDataAnalyser.java diff --git a/common/src/main/java/com/xtracr/realcamera/RealCameraCore.java b/common/src/main/java/com/xtracr/realcamera/RealCameraCore.java index e61b958..a81bf70 100644 --- a/common/src/main/java/com/xtracr/realcamera/RealCameraCore.java +++ b/common/src/main/java/com/xtracr/realcamera/RealCameraCore.java @@ -7,7 +7,6 @@ import com.xtracr.realcamera.config.ModConfig; import com.xtracr.realcamera.mixin.PlayerEntityRendererAccessor; import com.xtracr.realcamera.util.MathUtil; -import com.xtracr.realcamera.util.VertexDataAnalyser; import com.xtracr.realcamera.util.VertexDataCatcher; import net.minecraft.client.MinecraftClient; import net.minecraft.client.network.AbstractClientPlayerEntity; @@ -22,15 +21,13 @@ import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; import org.joml.Matrix3f; +import org.joml.Vector3f; import org.joml.Vector4f; -import java.util.ArrayList; import java.util.List; public class RealCameraCore { private static final ModConfig config = ConfigFile.modConfig; - private static final List normalList = new ArrayList<>(); - private static final List posList = new ArrayList<>(); private static String status = "Successful"; private static boolean vRendering = false; private static float pitch ,yaw, roll; @@ -85,15 +82,17 @@ public static void computeCamera(MinecraftClient client, float tickDelta) { // GameRenderer.renderWorld MatrixStack matrixStack = new MatrixStack(); vRendering = true; - VertexDataCatcher catcher = setupCatcher(); + VertexDataCatcher catcher = new VertexDataCatcher(); virtualRender(client, tickDelta, matrixStack, catcher); vRendering = false; // ModelPart$Cuboid.renderCuboid - Vector4f offset = matrixStack.peek().getPositionMatrix().transform(new Vector4f(0, 0, 0, 1.0F)); + Vector4f offset = matrixStack.peek().getPositionMatrix().transform(new Vector4f((float) (config.getBindingZ() * config.getScale()), + -(float) (config.getBindingY() * config.getScale()) - 0.125f, + -(float) (config.getBindingX() * config.getScale()) - 0.225f, 1.0F)); pos = new Vec3d(offset.x(), offset.y(), offset.z()); Matrix3f normal = matrixStack.peek().getNormalMatrix().scale(1.0F, -1.0F, -1.0F); - if (!VertexDataAnalyser.isAnalysing() && config.binding.experimental) try { + if (config.binding.experimental) try { applyAnalysisResult(normal, catcher); } catch (Exception ignored) { } @@ -107,31 +106,20 @@ public static void computeCamera(MinecraftClient client, float tickDelta) { roll = config.isRollingBound() ? (float) eulerAngle.getZ() : config.getBindingRoll(); } - private static VertexDataCatcher setupCatcher() { - normalList.clear(); - posList.clear(); - if (VertexDataAnalyser.isAnalysing()) return VertexDataAnalyser.catcher; - if (config.binding.experimental) try { - List list = config.binding.indexListMap.get(config.binding.nameOfList); - normalList.add(list.get(0)); - normalList.add(list.get(1)); - posList.addAll(list.subList(2, list.size())); - } catch (Exception ignored) { - } - return new VertexDataCatcher(normalList::contains, posList::contains); - } - private static void applyAnalysisResult(Matrix3f normal, VertexDataCatcher catcher) { if (catcher.posRecorder.isEmpty()) throw new NullPointerException("Target vertices not found"); - Vec3d average = Vec3d.ZERO; - for (Vec3d vec : catcher.posRecorder) { - average = average.add(vec); - } - pos = average.multiply(1 / (double) catcher.posRecorder.size()); - int order = normalList.get(0) < normalList.get(1) ? 0 : 1; - Vec3d front = catcher.normalRecorder.get(normalList.get(order)); - Vec3d up = catcher.normalRecorder.get(normalList.get(1 - order)); + List indexList = config.binding.indexListMap.get(config.binding.nameOfList); + Vec3d front = catcher.normalRecorder.get(indexList.get(0)); + Vec3d up = catcher.normalRecorder.get(indexList.get(1)); normal.set(front.crossProduct(up).multiply(-1).toVector3f(), up.toVector3f(), front.toVector3f()); + Vector3f offset = normal.transform(new Vector3f((float) (config.getBindingZ() * config.getScale()), + (float) (config.getBindingY() * config.getScale()), + (float) (config.getBindingX() * config.getScale()))); + Vec3d center = Vec3d.ZERO; + for (int i : indexList.subList(2, indexList.size())) { + center = center.add(catcher.posRecorder.get(i)); + } + pos = center.multiply(1 / (double) (indexList.size() - 2)).add(offset.x(), offset.y(), offset.z()); } private static void virtualRender(MinecraftClient client, float tickDelta, MatrixStack matrixStack, VertexDataCatcher catcher) { @@ -149,9 +137,8 @@ private static void virtualRender(MinecraftClient client, float tickDelta, Matri matrixStack.push(); EntityRenderDispatcher dispatcher = client.getEntityRenderDispatcher(); dispatcher.configure(client.world, client.gameRenderer.getCamera(), player); - if (VertexDataAnalyser.preAnalysing() || config.binding.experimental) dispatcher.render(player, renderOffset.getX(), + if (config.binding.experimental) dispatcher.render(player, renderOffset.getX(), renderOffset.getY(), renderOffset.getZ(), 0, tickDelta, matrixStack, layer -> catcher, 0xF000F0); - VertexDataAnalyser.analyse(player, tickDelta); matrixStack.pop(); // EntityRenderDispatcher.render if (config.compatPhysicsMod()) diff --git a/common/src/main/java/com/xtracr/realcamera/command/ClientCommand.java b/common/src/main/java/com/xtracr/realcamera/command/ClientCommand.java index 45c20ca..ae5fa03 100644 --- a/common/src/main/java/com/xtracr/realcamera/command/ClientCommand.java +++ b/common/src/main/java/com/xtracr/realcamera/command/ClientCommand.java @@ -2,7 +2,6 @@ import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.arguments.ArgumentType; -import com.mojang.brigadier.arguments.IntegerArgumentType; import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.builder.RequiredArgumentBuilder; @@ -10,51 +9,25 @@ import com.xtracr.realcamera.RealCamera; import com.xtracr.realcamera.config.ConfigFile; import com.xtracr.realcamera.config.ModConfig; -import com.xtracr.realcamera.util.VertexDataAnalyser; import net.minecraft.client.MinecraftClient; import net.minecraft.command.CommandRegistryAccess; import net.minecraft.command.CommandSource; import net.minecraft.text.Text; -import java.util.List; - public class ClientCommand{ private static final String KEY_COMMAND = "message.xtracr_" + RealCamera.MODID + "_command_"; private static final ModConfig config = ConfigFile.modConfig; public void register(CommandDispatcher dispatcher, CommandRegistryAccess access) { final LiteralArgumentBuilder builder = literal(RealCamera.MODID); - builder.then(literal("analyse").executes(context -> this.startAnalysis(context, 0)) - .then(argument("targetIndex", IntegerArgumentType.integer(0)) - .then(argument("accuracy", IntegerArgumentType.integer(10, 10000000)).executes(context -> this.startAnalysis(context, 1))))); - builder.then(literal("autoBind") - .then(argument("name", StringArgumentType.string()).executes(this::autoBind))); builder.then(literal("config") .then(literal("delete") .then(argument("name", StringArgumentType.string()).executes(this::deleteList))) .then(literal("listAll").executes(this::listAll))); - builder.then(literal("showResult") - .then(argument("number", IntegerArgumentType.integer(1)).executes(this::showResult))); dispatcher.register(builder); } - private int startAnalysis(CommandContext context, int mode) { - if (mode == 1) mode += IntegerArgumentType.getInteger(context, "targetIndex"); - final float accuracy = mode == 0 ? 100 : IntegerArgumentType.getInteger(context, "accuracy"); - VertexDataAnalyser.start(mode, mode == 0 ? 80 : 120, 1 / accuracy); - return 1; - } - - private int autoBind(CommandContext context) { - List list = VertexDataAnalyser.getFinalResults(-1); - if (list == null) return 0; - config.binding.indexListMap.put(StringArgumentType.getString(context, "name"), list); - ConfigFile.save(); - printGameMessage(Text.translatable(KEY_COMMAND + "autoBind", list.get(0), list.get(0), list.get(1), list.get(2))); - return 1; - } - private int deleteList(CommandContext context) { final String name = StringArgumentType.getString(context, "name"); if (!config.binding.indexListMap.containsKey(name)) { @@ -78,12 +51,6 @@ private int listAll(CommandContext context) { return 1; } - private int showResult(CommandContext context) { - final int number = IntegerArgumentType.getInteger(context, "number"); - VertexDataAnalyser.showResult(number, true); - return 1; - } - private static void printGameMessage(Text text) { MinecraftClient.getInstance().getMessageHandler().onGameMessage(text, false); } diff --git a/common/src/main/java/com/xtracr/realcamera/config/ConfigScreen.java b/common/src/main/java/com/xtracr/realcamera/config/ConfigScreen.java index e91098d..3214123 100644 --- a/common/src/main/java/com/xtracr/realcamera/config/ConfigScreen.java +++ b/common/src/main/java/com/xtracr/realcamera/config/ConfigScreen.java @@ -96,13 +96,13 @@ public static Screen create(Screen parent) { SubCategoryBuilder bindingCameraOffset = entryBuilder.startSubCategory(Text.translatable(CATEGORY + "cameraOffset")) .setTooltip(Text.translatable(TOOLTIP + "bindingOffset"), Text.translatable(TOOLTIP + "bindingOffset_n")); bindingCameraOffset.add(entryBuilder.startDoubleField(Text.translatable(OPTION + "cameraOffset", "X"), config.binding.cameraX) - .setDefaultValue(3.25D) + .setDefaultValue(0.0D) .setMin(ModConfig.MIN_DOUBLE) .setMax(ModConfig.MAX_DOUBLE) .setSaveConsumer(d -> config.binding.cameraX = d) .build()); bindingCameraOffset.add(entryBuilder.startDoubleField(Text.translatable(OPTION + "cameraOffset", "Y"), config.binding.cameraY) - .setDefaultValue(2.0D) + .setDefaultValue(0.0D) .setMin(ModConfig.MIN_DOUBLE) .setMax(ModConfig.MAX_DOUBLE) .setSaveConsumer(d -> config.binding.cameraY = d) @@ -316,7 +316,7 @@ public static Screen create(Screen parent) { .build()); disable.addEntry(disableModWhen.build()); - experimental.addEntry(entryBuilder.startBooleanToggle(Text.literal("Enabled"), config.binding.experimental) + experimental.addEntry(entryBuilder.startBooleanToggle(Text.translatable(OPTION + "enabled"), config.binding.experimental) .setDefaultValue(false) .setSaveConsumer(b -> config.binding.experimental = b) .build()); diff --git a/common/src/main/java/com/xtracr/realcamera/config/ModConfig.java b/common/src/main/java/com/xtracr/realcamera/config/ModConfig.java index cd8e294..73e0c9b 100644 --- a/common/src/main/java/com/xtracr/realcamera/config/ModConfig.java +++ b/common/src/main/java/com/xtracr/realcamera/config/ModConfig.java @@ -302,8 +302,8 @@ public static class Binding { public boolean offsetModel = false; public String nameOfList = "minecraft_head"; public Map> indexListMap = defaultIndexListMap; - public double cameraX = 3.25D; - public double cameraY = 2.0D; + public double cameraX = 0.0D; + public double cameraY = 0.0D; public double cameraZ = 0.0D; public boolean bindPitching = true; public boolean bindYawing = true; diff --git a/common/src/main/java/com/xtracr/realcamera/gui/IntFieldWidget.java b/common/src/main/java/com/xtracr/realcamera/gui/IntFieldWidget.java index c41ea70..3e5dd90 100644 --- a/common/src/main/java/com/xtracr/realcamera/gui/IntFieldWidget.java +++ b/common/src/main/java/com/xtracr/realcamera/gui/IntFieldWidget.java @@ -9,8 +9,8 @@ public class IntFieldWidget extends TextFieldWidget { IntConsumer consumer; - public IntFieldWidget(TextRenderer textRenderer, int width, int height, Text text, int value, IntConsumer consumer) { - super(textRenderer, width, height, text); + public IntFieldWidget(TextRenderer textRenderer, int x, int y, int width, int height, Text text, int value, IntConsumer consumer) { + super(textRenderer, x, y, width, height, text); this.consumer = consumer; setMaxLength(9); setValue(value); @@ -22,6 +22,7 @@ protected int getValue() { protected void setValue(int value) { setText(String.valueOf(value)); + consumer.accept(value); } @Override diff --git a/common/src/main/java/com/xtracr/realcamera/gui/ModelViewScreen.java b/common/src/main/java/com/xtracr/realcamera/gui/ModelViewScreen.java index b3dc138..5e7f454 100644 --- a/common/src/main/java/com/xtracr/realcamera/gui/ModelViewScreen.java +++ b/common/src/main/java/com/xtracr/realcamera/gui/ModelViewScreen.java @@ -1,11 +1,15 @@ package com.xtracr.realcamera.gui; import com.xtracr.realcamera.RealCamera; +import com.xtracr.realcamera.config.ConfigFile; import com.xtracr.realcamera.util.MathUtil; +import com.xtracr.realcamera.util.ModelAnalyser; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.tooltip.Tooltip; import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.client.gui.widget.TextFieldWidget; import net.minecraft.client.render.DiffuseLighting; import net.minecraft.client.render.entity.EntityRenderDispatcher; import net.minecraft.client.util.InputUtil; @@ -18,21 +22,28 @@ import org.joml.Vector3f; import org.lwjgl.glfw.GLFW; +import java.util.ArrayList; +import java.util.List; + public class ModelViewScreen extends Screen { - private static final String KEY_SCREEN = "screen.xtracr_" + RealCamera.MODID + "_vertexSelection_"; - private static final String KEY_WIDGET = "screen.widget.xtracr_" + RealCamera.MODID + "_vertexSelection_"; + private static final String KEY_SCREEN = "screen.xtracr_" + RealCamera.MODID + "_modelView_"; + private static final String KEY_WIDGET = "screen.widget.xtracr_" + RealCamera.MODID + "_modelView_"; + private static final String KEY_TOOLTIP = "screen.tooltip.xtracr_" + RealCamera.MODID + "_modelView_"; protected int xSize = 400, ySize = 220; protected int x, y; - public double mouseX, mouseY; private int entitySize = 80; private double entityX, entityY; private float yaw, pitch, xRot, yRot; private boolean selectingFront, selectingUp, selectingPos; - private int layers, frontIndex, upIndex; - private IntFieldWidget frontIndexWidget, upIndexWidget; + private List focusedPolygon, posPolygon; + private int layers, frontIndex, upIndex, posIndex; + private IntFieldWidget frontIndexWidget, upIndexWidget, posIndexWidget; + private TextFieldWidget nameWidget; private final ButtonWidget selectFrontButton = ButtonWidget.builder(Text.literal("OFF"), button -> changeSelectionTarget(0)).size(25, 18).build(); private final ButtonWidget selectUpButton = ButtonWidget.builder(Text.literal("OFF"), button -> changeSelectionTarget(1)).size(25, 18).build(); private final ButtonWidget selectPosButton = ButtonWidget.builder(Text.literal("OFF"), button -> changeSelectionTarget(2)).size(25, 18).build(); + private final ButtonWidget saveButton = ButtonWidget.builder(Text.translatable(KEY_WIDGET + "save"), button -> saveCurrent()).size((xSize - ySize)/4 - 10, 18).build(); + private final ButtonWidget loadButton = ButtonWidget.builder(Text.translatable(KEY_WIDGET + "load"), button -> loadToCurrent()).size((xSize - ySize)/4 - 10, 18).build(); private final DoubleValueSlider yawWidget = new DoubleValueSlider((xSize - ySize)/2 - 15, 18, 0.5D, -60.0D, 60.0D, d -> Text.translatable(KEY_WIDGET + "yaw", MathUtil.round(d, 2)), d -> yaw = (float) d); private final DoubleValueSlider pitchWidget = new DoubleValueSlider((xSize - ySize)/2 - 15, 18, 0.5D, @@ -48,43 +59,38 @@ protected void init() { super.init(); x = (width - xSize) / 2; y = (height - ySize) / 2; - frontIndexWidget = new IntFieldWidget(textRenderer, (xSize - ySize)/2 - 45, 18, Text.translatable(KEY_WIDGET + "frontIndex"), frontIndex, i -> frontIndex = i); - upIndexWidget = new IntFieldWidget(textRenderer, (xSize - ySize)/2 - 45, 18, Text.translatable(KEY_WIDGET + "upIndex"), upIndex, i -> upIndex = i); - frontIndexWidget.setPosition(x + 5, y + 70); - selectFrontButton.setPosition(x + (xSize - ySize)/2 - 35, y + 70); - upIndexWidget.setPosition(x + 5, y + 92); - selectUpButton.setPosition(x + (xSize - ySize)/2 - 35, y + 92); - selectPosButton.setPosition(x + (xSize - ySize)/2 - 35, y + 114); - yawWidget.setPosition(x + 5, y + 26); - pitchWidget.setPosition(x + 5, y + 48); - resetWidget.setPosition(x + 5, y + 4); - addDrawableChild(frontIndexWidget); - addDrawableChild(selectFrontButton); - addDrawableChild(upIndexWidget); - addDrawableChild(selectUpButton); - addDrawableChild(selectPosButton); - addDrawableChild(yawWidget); - addDrawableChild(pitchWidget); - addDrawableChild(resetWidget); + frontIndexWidget = new IntFieldWidget(textRenderer, x + 5, y + 70, (xSize - ySize)/2 - 45, 18, Text.translatable(KEY_WIDGET + "frontIndex"), frontIndex, i -> frontIndex = i); + upIndexWidget = new IntFieldWidget(textRenderer, x + 5, y + 92, (xSize - ySize)/2 - 45, 18, Text.translatable(KEY_WIDGET + "upIndex"), upIndex, i -> upIndex = i); + posIndexWidget = new IntFieldWidget(textRenderer, x + 5, y + 114, (xSize - ySize)/2 - 45, 18, Text.translatable(KEY_WIDGET + "posIndex"), posIndex, i -> posIndex = i); + nameWidget = new TextFieldWidget(textRenderer, x + 5, y + 158, (xSize - ySize)/2 - 15, 18, Text.translatable(KEY_WIDGET + "listName")); + nameWidget.setMaxLength(20); + selectFrontButton.setTooltip(Tooltip.of(Text.translatable(KEY_TOOLTIP + "selectFront"))); + selectUpButton.setTooltip(Tooltip.of(Text.translatable(KEY_TOOLTIP + "selectUp"))); + selectPosButton.setTooltip(Tooltip.of(Text.translatable(KEY_TOOLTIP + "selectPos"))); + addDrawableChild(resetWidget).setPosition(x + 5, y + 4); + addDrawableChild(yawWidget).setPosition(x + 5, y + 26); + addDrawableChild(pitchWidget).setPosition(x + 5, y + 48); + addDrawableChild(frontIndexWidget).setTooltip(Tooltip.of(Text.translatable(KEY_WIDGET + "frontIndex"))); + addDrawableChild(selectFrontButton).setPosition(x + (xSize - ySize)/2 - 35, y + 70); + addDrawableChild(upIndexWidget).setTooltip(Tooltip.of(Text.translatable(KEY_WIDGET + "upIndex"))); + addDrawableChild(selectUpButton).setPosition(x + (xSize - ySize)/2 - 35, y + 92); + addDrawableChild(posIndexWidget).setTooltip(Tooltip.of(Text.translatable(KEY_WIDGET + "posIndex"))); + addDrawableChild(selectPosButton).setPosition(x + (xSize - ySize)/2 - 35, y + 114); + addDrawableChild(saveButton).setPosition(x + 5, y + 136); + addDrawableChild(loadButton).setPosition(x + (xSize - ySize)/4, y + 136); + addDrawableChild(nameWidget).setTooltip(Tooltip.of(Text.translatable(KEY_WIDGET + "listName"))); } @Override public void render(DrawContext context, int mouseX, int mouseY, float delta) { - super.render(context, mouseX, mouseY, delta); - this.mouseX = mouseX; - this.mouseY = mouseY; - drawEntity(context, x + (xSize - ySize) / 2, y, x + (xSize + ySize) / 2, y + ySize, this.client.player); - } - - @Override - public void renderBackground(DrawContext context, int mouseX, int mouseY, float delta) { - super.renderBackground(context, mouseX, mouseY, delta); - context.fill(x, y, x + (xSize - ySize) / 2 - 5, y + ySize, 0xFF555555); + context.fill(x, y, x + (xSize - ySize) / 2 - 5, y + ySize, 0xEE505050); context.fill(x + (xSize - ySize) / 2, y, x + (xSize + ySize) / 2, y + ySize, 0xFF222222); - context.fill(x + (xSize + ySize) / 2 + 5, y, x + xSize, y + ySize, 0xFF555555); + context.fill(x + (xSize + ySize) / 2 + 5, y, x + xSize, y + ySize, 0xEE505050); + super.render(context, mouseX, mouseY, delta); + drawEntity(context, x + (xSize - ySize) / 2, y, x + (xSize + ySize) / 2, y + ySize, mouseX, mouseY, this.client.player); } - protected void drawEntity(DrawContext context, int x1, int y1, int x2, int y2, LivingEntity entity) { + protected void drawEntity(DrawContext context, int x1, int y1, int x2, int y2, int mouseX, int mouseY, LivingEntity entity) { float centerX = (float)(x1 + x2) / 2.0f; float centerY = (float)(y1 + y2) / 2.0f; context.enableScissor(x1, y1, x2, y2); @@ -100,7 +106,7 @@ protected void drawEntity(DrawContext context, int x1, int y1, int x2, int y2, L entity.headYaw = entity.getYaw(); entity.prevHeadYaw = entity.getYaw(); Vector3f vector3f = new Vector3f((float) entityX, (float) entityY, -2.0f); - drawEntity(context, centerX, centerY, entitySize, vector3f, quaternionf, entity); + drawEntity(context, centerX, centerY, entitySize, mouseX, mouseY, vector3f, quaternionf, entity); entity.bodyYaw = entityBodyYaw; entity.setYaw(entityYaw); entity.setPitch(entityPitch); @@ -109,7 +115,7 @@ protected void drawEntity(DrawContext context, int x1, int y1, int x2, int y2, L context.disableScissor(); } - protected static void drawEntity(DrawContext context, float x, float y, int size, Vector3f offset, Quaternionf quaternionf, LivingEntity entity) { + protected void drawEntity(DrawContext context, float x, float y, int size, int mouseX, int mouseY, Vector3f offset, Quaternionf quaternionf, LivingEntity entity) { context.getMatrices().push(); context.getMatrices().translate(x, y, 0); context.getMatrices().multiplyPositionMatrix(new Matrix4f().scaling(size, size, -size)); @@ -119,8 +125,15 @@ protected static void drawEntity(DrawContext context, float x, float y, int size EntityRenderDispatcher entityRenderDispatcher = MinecraftClient.getInstance().getEntityRenderDispatcher(); entityRenderDispatcher.setRenderShadows(false); entityRenderDispatcher.render(entity, 0, -entity.getHeight() / 2.0f, 0, 0.0f, 1.0f, context.getMatrices(), context.getVertexConsumers(), 0xF000F0); - //entityRenderDispatcher.render(entity, 0, -entity.getHeight() / 2.0f, 0, 0.0f, 1.0f, context.getMatrices(), layer -> null, 0xF000F0); + ModelAnalyser analyser = new ModelAnalyser(); + entityRenderDispatcher.render(entity, 0, -entity.getHeight() / 2.0f, 0, 0.0f, 1.0f, context.getMatrices(), analyser, 0xF000F0); context.draw(); + focusedPolygon = analyser.getFocusedPolygon(mouseX, mouseY, layers); + if (focusedPolygon != null) analyser.drawPolygon(context, focusedPolygon.get(0), 0x6FFFFFFF); + analyser.drawNormal(context, frontIndex, entitySize / 2, 0xFF00CC00); + analyser.drawNormal(context, upIndex, entitySize / 2, 0xFFCC0000); + analyser.drawPolygon(context, posIndex, 0x6F3333CC); + posPolygon = analyser.getPolygon(posIndex); entityRenderDispatcher.setRenderShadows(true); context.getMatrices().pop(); DiffuseLighting.enableGuiDepthLighting(); @@ -135,6 +148,26 @@ private void reset() { layers = 0; } + private void saveCurrent() { + String name = nameWidget.getText(); + if (name == null) return; + List list = new ArrayList<>(List.of(frontIndex, upIndex)); + list.addAll(posPolygon); + ConfigFile.modConfig.binding.indexListMap.put(name, list); + ConfigFile.save(); + } + + private void loadToCurrent() { + String name = nameWidget.getText(); + List list = ConfigFile.modConfig.binding.indexListMap.get(name); + try { + frontIndexWidget.setValue(list.get(0)); + upIndexWidget.setValue(list.get(1)); + posIndexWidget.setValue(list.get(2)); + } catch (Exception ignored) { + } + } + private void changeSelectionTarget(int target) { Text ON = Text.literal("ON").styled(style -> style.withColor(Formatting.GREEN)); Text OFF = Text.literal("OFF"); @@ -168,10 +201,21 @@ protected boolean mouseInViewArea(double mouseX, double mouseY) { return mouseX >= x + (double) (xSize - ySize) / 2 && mouseX <= x + (double) (xSize + ySize) / 2 && mouseY >= y && mouseY <= y + (double) ySize; } + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + if (mouseInViewArea(mouseX, mouseY) && focusedPolygon != null && button == GLFW.GLFW_MOUSE_BUTTON_LEFT&& + InputUtil.isKeyPressed(this.client.getWindow().getHandle(), GLFW.GLFW_KEY_LEFT_ALT)) { + if (selectingFront) frontIndexWidget.setValue(focusedPolygon.get(0)); + if (selectingUp) upIndexWidget.setValue(focusedPolygon.get(0)); + if (selectingPos) posIndexWidget.setValue(focusedPolygon.get(0)); + } + return super.mouseClicked(mouseX, mouseY, button); + } + @Override public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) { if (mouseInViewArea(mouseX, mouseY)) { - if (button == GLFW.GLFW_MOUSE_BUTTON_LEFT) { + if (button == GLFW.GLFW_MOUSE_BUTTON_LEFT && !InputUtil.isKeyPressed(this.client.getWindow().getHandle(), GLFW.GLFW_KEY_LEFT_ALT)) { xRot = MathHelper.wrapDegrees(xRot + (float) deltaY / 90f); yRot = MathHelper.wrapDegrees(yRot - (float) deltaX / 90f); } else if (button == GLFW.GLFW_MOUSE_BUTTON_RIGHT) { @@ -183,17 +227,19 @@ public boolean mouseDragged(double mouseX, double mouseY, int button, double del } @Override - public boolean mouseScrolled(double mouseX, double mouseY, double horizontalAmount, double verticalAmount) { + public boolean mouseScrolled(double mouseX, double mouseY, double amount) { // 1.20.1 if (mouseInViewArea(mouseX, mouseY)) { if (InputUtil.isKeyPressed(this.client.getWindow().getHandle(), GLFW.GLFW_KEY_LEFT_ALT)) { - layers = Math.max(0, layers + (int) verticalAmount); + layers = Math.max(0, layers + (int) amount); } else { - entitySize = MathHelper.clamp(entitySize + (int) verticalAmount * entitySize / 16, 16, 1024); + entitySize = MathHelper.clamp(entitySize + (int) amount * entitySize / 16, 16, 1024); } + return true; } - return super.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount); + return super.mouseScrolled(mouseX, mouseY, amount); } + @Override public boolean shouldPause() { return false; diff --git a/common/src/main/java/com/xtracr/realcamera/mixin/MixinCamera.java b/common/src/main/java/com/xtracr/realcamera/mixin/MixinCamera.java index 954328d..d50bf53 100644 --- a/common/src/main/java/com/xtracr/realcamera/mixin/MixinCamera.java +++ b/common/src/main/java/com/xtracr/realcamera/mixin/MixinCamera.java @@ -61,22 +61,16 @@ public abstract class MixinCamera { moveBy(offset.getX(), offset.getY(), offset.getZ()); realCamera$clipToSpace(startVec); } else { - Vec3d prevPos = pos; - Vec3d offset = new Vec3d(config.getBindingX(), config.getBindingY(), config.getBindingZ()).multiply(config.getScale()); - if (config.compatPehkui()) offset = PehkuiCompat.scaleVec3d(offset, focusedEntity, tickDelta); - setPos(RealCameraCore.getPos()); - setRotation(RealCameraCore.getYaw(yaw), RealCameraCore.getPitch(pitch)); - moveBy(offset.getX(), offset.getY(), offset.getZ()); - Vec3d modifiedPos = pos; - setPos(prevPos); + Vec3d prevPos = RealCameraCore.getPos(); Box box = focusedEntity.getBoundingBox(); - double restrictedY = MathHelper.clamp(modifiedPos.getY(), box.minY + 0.1D, box.maxY - 0.1D); + double restrictedY = MathHelper.clamp(prevPos.getY(), box.minY + 0.1D, box.maxY - 0.1D); startVec = new Vec3d(pos.getX(), restrictedY, pos.getZ()); if (!config.doOffsetModel()) { - setPos(modifiedPos); + setPos(prevPos); realCamera$clipToSpace(startVec); } - RealCameraCore.setModelOffset(pos.subtract(modifiedPos)); + RealCameraCore.setModelOffset(pos.subtract(prevPos)); + setRotation(RealCameraCore.getYaw(yaw), RealCameraCore.getPitch(pitch)); } } diff --git a/common/src/main/java/com/xtracr/realcamera/util/ModelAnalyser.java b/common/src/main/java/com/xtracr/realcamera/util/ModelAnalyser.java new file mode 100644 index 0000000..0349e32 --- /dev/null +++ b/common/src/main/java/com/xtracr/realcamera/util/ModelAnalyser.java @@ -0,0 +1,84 @@ +package com.xtracr.realcamera.util; + +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.render.RenderLayer; +import net.minecraft.client.render.VertexConsumer; +import net.minecraft.client.render.VertexConsumerProvider; +import net.minecraft.util.Pair; +import net.minecraft.util.math.Vec3d; +import org.joml.Vector3f; + +import java.awt.*; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; + +public class ModelAnalyser implements VertexConsumerProvider { + private final VertexDataCatcher catcher = new VertexDataCatcher(); + private final List> polygons = new ArrayList<>(); + + public List getPolygon(int index) { + List ret = new ArrayList<>(); + for (List polygon : polygons) { + if (polygon.contains(index)) ret = polygon; + } + return ret; + } + + public List getFocusedPolygon(int mouseX, int mouseY, int layers) { + final float precision = 0.00001f; + List recorder = catcher.normalRecorder; + polygons.add(new ArrayList<>(List.of(0))); + for (int i = 1; i < recorder.size(); i++) { + double dotProduct = recorder.get(i - 1).dotProduct(recorder.get(i)); + if (dotProduct >= 1 - precision) polygons.get(polygons.size() - 1).add(i); + else polygons.add(new ArrayList<>(List.of(i))); + } + List, Float>> sortByDepth = new ArrayList<>(); + for (List vertices : polygons) { + Vector3f intersection = new Vector3f(); + Polygon polygon = new Polygon(); + for (int index : vertices) { + Vector3f pos = catcher.posRecorder.get(index).toVector3f(); + polygon.addPoint((int) pos.x(), (int) pos.y()); + intersection.add(pos); + } + intersection.mul((float) 1 / vertices.size()); + Vector3f normal = catcher.normalRecorder.get(vertices.get(0)).toVector3f(); + float deltaZ = 0; + if (normal.z() != 0) deltaZ = (normal.x() * (mouseX - intersection.x()) + normal.y() * (mouseY - intersection.y())) / normal.z(); + if (polygon.contains(mouseX, mouseY)) sortByDepth.add(new Pair<>(vertices, intersection.z() + deltaZ)); + } + if (sortByDepth.isEmpty()) return null; + sortByDepth.sort(Comparator.comparingDouble(pair -> -pair.getRight())); + return sortByDepth.get(Math.min(sortByDepth.size() - 1, layers)).getLeft(); + } + + public void drawPolygon(DrawContext context, int index, int argb) { + VertexConsumer vertexConsumer = context.getVertexConsumers().getBuffer(RenderLayer.getGui()); + getPolygon(index).forEach(i -> { + Vector3f pos = catcher.posRecorder.get(i).toVector3f().add(0, 0, 0.1f); + vertexConsumer.vertex(pos.x(), pos.y(), pos.z()).color(argb).next(); + }); + context.draw(); + } + + public void drawNormal(DrawContext context, int index, int size, int argb) { + if (index >= catcher.posRecorder.size()) return; + VertexConsumer vertexConsumer = context.getVertexConsumers().getBuffer(RenderLayer.getDebugLineStrip(5)); + Vector3f normal = catcher.normalRecorder.get(index).toVector3f(); + Vector3f start = new Vector3f(); + List polygon = getPolygon(index); + polygon.forEach(i -> start.add(catcher.posRecorder.get(i).toVector3f())); + start.mul(1 / (float) polygon.size()); + Vector3f end = new Vector3f(normal).mul(size).add(start); + vertexConsumer.vertex(start.x(), start.y(), start.z()).color(argb).normal(normal.x(), normal.y(), normal.z()).next(); + vertexConsumer.vertex(end.x(), end.y(), end.z()).color(argb).normal(normal.x(), normal.y(), normal.z()).next(); + context.draw(); + } + + @Override + public VertexConsumer getBuffer(RenderLayer layer) { + return catcher; + } +} diff --git a/common/src/main/java/com/xtracr/realcamera/util/VertexDataAnalyser.java b/common/src/main/java/com/xtracr/realcamera/util/VertexDataAnalyser.java deleted file mode 100644 index c604ed9..0000000 --- a/common/src/main/java/com/xtracr/realcamera/util/VertexDataAnalyser.java +++ /dev/null @@ -1,230 +0,0 @@ -package com.xtracr.realcamera.util; - -import com.xtracr.realcamera.RealCamera; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; -import net.minecraft.util.Pair; -import net.minecraft.util.math.RotationAxis; -import net.minecraft.util.math.Vec3d; -import org.joml.Matrix3f; - -import java.util.*; - -public abstract class VertexDataAnalyser { - private static final String KEY_ANALYSER = "message.xtracr_" + RealCamera.MODID + "_analyser_"; - private static final float defaultAccuracy = 0.00001f; - private static final Map> indexResult = new HashMap<>(); - private static final Map> orthogonalResult = new HashMap<>(); - private static final List processedResults = new ArrayList<>(); - private static List equivalenceClass = new ArrayList<>(); - private static boolean analysing; - private static float accuracy = defaultAccuracy; - private static int count, mode, ticks; - public static final VertexDataCatcher catcher = new VertexDataCatcher(i -> analysing, i -> analysing); - - public static boolean isAnalysing() { - return analysing; - } - - public static boolean preAnalysing() { - catcher.clear(); - return analysing; - } - - public static List getFinalResults(int index) { - if (processedResults.isEmpty()) { - printGameMessage(Text.translatable(KEY_ANALYSER + "notReady")); - return null; - } - List ret = new ArrayList<>(processedResults).subList(0, 2); - final int target = index == -1 ? processedResults.get(0) : index; - ret.add(target); - if (equivalenceClass.contains(target)) { - for (int i = 1; i <= Math.max(target, equivalenceClass.get(equivalenceClass.size() - 1) - target); i++) { - boolean add = equivalenceClass.contains(target + i); - if (add) ret.add(target + i); - if (equivalenceClass.contains(target - i)) ret.add(target + i); - else if (!add) break; - } - } - return ret; - } - - public static void tick() { - if (!analysing) return; - ticks--; - if (ticks > 0) return; - if (mode == 0) { - int target = getResult(1, false).get(0); - start(target + 1, 80, accuracy); - return; - } - analysing = false; - showResult(12, false); - } - - public static void start(int mode, int ticks, float accuracy) { - indexResult.clear(); - orthogonalResult.clear(); - processedResults.clear(); - equivalenceClass.clear(); - analysing = true; - count = 0; - VertexDataAnalyser.accuracy = accuracy; - VertexDataAnalyser.mode = mode; - VertexDataAnalyser.ticks = ticks; - equivalenceClass.add(Math.max(0, mode - 1)); - if (mode >= 0) printGameMessage(Text.translatable(KEY_ANALYSER + "start")); - } - - public static void showResult(int number, boolean detail) { - if (indexResult.isEmpty()) { - printGameMessage(Text.translatable(KEY_ANALYSER + "notReady")); - return; - } - printGameMessage(Text.translatable(KEY_ANALYSER + "showResult")); - List sorted = getResult(number, true); - StringBuilder buffer = new StringBuilder(); - for (int i : sorted) { - buffer.append(" [").append(i).append("]"); - if (!detail) continue; - float f = Math.round(1000 * indexResult.get(i).getLeft() / (float) count) / 1000f; - buffer.append(": ").append(f); - } - sorted = getResult(number, false); - printGameMessage(Text.translatable(KEY_ANALYSER + "byFrequency", buffer.toString())); - buffer = new StringBuilder(); - for (int i : sorted) { - buffer.append(" [").append(i).append("]"); - if (!detail) continue; - float c = Math.round(1000 * indexResult.get(i).getRight() / (float) count) / 1000f; - buffer.append(": ").append(c); - } - printGameMessage(Text.translatable(KEY_ANALYSER + "byCorrelation", buffer.toString())); - printGameMessage(Text.translatable(KEY_ANALYSER + "numberOfResults", - Math.min(number, indexResult.keySet().size()), indexResult.keySet().size())); - if (orthogonalResult.isEmpty()) return; - if (processedResults.isEmpty()) { - sorted = new ArrayList<>(orthogonalResult.keySet()); - sorted.sort(Comparator.comparingInt(i -> -Math.abs(orthogonalResult.get(i).getRight()))); - int leftIndex = sorted.get(0); - sorted.sort(Comparator.comparingInt(i -> -Math.abs(orthogonalResult.get(i).getLeft()))); - int upIndex = sorted.get(0); - processedResults.add(equivalenceClass.get(0)); - processedResults.add(orthogonalResult.get(upIndex).getLeft() > 0 ? upIndex : -upIndex - 1); - processedResults.add(orthogonalResult.get(leftIndex).getLeft()> 0 ? leftIndex : -leftIndex - 1); - } - if (!equivalenceClass.contains(-1)) { - equivalenceClass = simplifyList(equivalenceClass, Comparator.comparingInt(i -> i), (int) (count * 0.9)); - equivalenceClass = equivalenceClass.subList(0, Math.min(number, equivalenceClass.size())); - equivalenceClass.add(-1); - } - if (detail) { - buffer = new StringBuilder().append("[ "); - for (int i : equivalenceClass) { - if (i < 0) continue; - buffer.append(i).append(" "); - } - printGameMessage(Text.translatable(KEY_ANALYSER + "equivalenceClass", buffer.append("]").toString())); - } - printGameMessage(Text.translatable(KEY_ANALYSER + "bindSuggestion", Text.literal("'autoBind'") - .styled(s -> s.withColor(Formatting.GREEN)), processedResults.get(0), processedResults.get(1), processedResults.get(2))); - } - - public static void analyse(ClientPlayerEntity player, float tickDelta) { - if (!analysing) return; - count++; - Vec3d viewVector = player.getRotationVec(tickDelta); - List> indexCash = new ArrayList<>(); - Matrix3f viewRotation = new Matrix3f().rotate(RotationAxis.POSITIVE_X.rotationDegrees(-player.getPitch(tickDelta))) - .rotate(RotationAxis.POSITIVE_Y.rotationDegrees(player.getYaw(tickDelta))); - analyseVertices(viewVector, viewRotation, indexCash); - for (Pair pair : indexCash) { - int index = pair.getLeft(); - float dot = pair.getRight(); - if (indexResult.containsKey(index)) { - Pair value = indexResult.get(index); - value.setLeft(value.getLeft() + 1); - value.setRight(value.getRight() + dot); - } else { - indexResult.put(index, new Pair<>(1, dot)); - } - } - } - - private static List getResult(int number , boolean byFrequency) { - List indexList = new ArrayList<>(indexResult.keySet()); - if (byFrequency) indexList.sort((i, j) -> indexResult.get(j).getLeft() - indexResult.get(i).getLeft()); - else indexList.sort(Comparator.comparingDouble(i -> -indexResult.get(i).getRight())); - return indexList.subList(0, Math.min(number, indexList.size())); - } - - private static List simplifyList(List list, Comparator comparator, int times) { - Map listCash = new HashMap<>(); - List ret = new ArrayList<>(); - list.forEach(t -> listCash.put(t, listCash.getOrDefault(t, 0) + 1)); - listCash.forEach((t, i) -> { if (i >= times) ret.add(t); }); - ret.sort(comparator); - return ret; - } - - private static void analyseVertices(Vec3d viewVector, Matrix3f viewRotation, List> indexCash) { - final float accuracy = mode == 0 ? defaultAccuracy : VertexDataAnalyser.accuracy; - List recorder = catcher.normalRecorder; - List cash = new ArrayList<>(); - List orthogonalCash = new ArrayList<>(); - final int index0 = Math.min(equivalenceClass.get(0), recorder.size()); - if (equivalenceClass.size() == 1) { - equivalenceClass.clear(); - equivalenceClass.add(index0); - } - Vec3d element0 = recorder.get(index0); - cash.add(element0); - double dotWithView0 = element0.dotProduct(viewVector); - indexCash.add(new Pair<>(index0, (float) dotWithView0)); - for (int i = 0; i < recorder.size(); i++) { - Vec3d element = recorder.get(i); - double dotWith0 = element.dotProduct(element0); - if (i == index0 || dotWith0 >= 1- defaultAccuracy) equivalenceClass.add(i); - else if (dotWith0 < defaultAccuracy && -dotWith0 < defaultAccuracy) { - boolean shouldAdd = true; - if (!orthogonalCash.isEmpty()) for (int index : orthogonalCash) { - if (Math.abs(element.dotProduct(recorder.get(index))) > defaultAccuracy) shouldAdd = false; - } - if (shouldAdd) orthogonalCash.add(i); - } - - double dotWithView = element.dotProduct(viewVector); - if (i == index0 || -dotWithView > accuracy) continue; - boolean skip = false; - for (Vec3d vec : cash) { - double dotAbs = Math.abs(vec.dotProduct(element)); - if (dotAbs >= 1-accuracy) skip = true; - } - if (skip) continue; - cash.add(element); - indexCash.add(new Pair<>(i, (float) dotWithView)); - } - if (orthogonalCash.size() >= 2) { - int index2 = orthogonalCash.get(1); - int index1 = orthogonalCash.get(0); - Matrix3f rotation = new Matrix3f(recorder.get(index2).toVector3f(), recorder.get(index1).toVector3f(), - recorder.get(equivalenceClass.get(0)).toVector3f()); - Pair pair2 = orthogonalResult.getOrDefault(index2, new Pair<>(0, 0)); - Pair pair1 = orthogonalResult.getOrDefault(index1, new Pair<>(0, 0)); - Matrix3f dotProduct = viewRotation.mul(rotation, new Matrix3f()); - pair2.setRight(pair2.getRight() + Math.round(dotProduct.m00())); - pair2.setLeft(pair2.getLeft() + Math.round(dotProduct.m01())); - pair1.setRight(pair1.getRight() + Math.round(dotProduct.m10())); - pair1.setLeft(pair1.getLeft() + Math.round(dotProduct.m11())); - orthogonalResult.putIfAbsent(index2, pair2); - orthogonalResult.putIfAbsent(index1, pair1); - } - } - - private static void printGameMessage(Text text) { - MinecraftClient.getInstance().getMessageHandler().onGameMessage(text, false); - } -} diff --git a/common/src/main/java/com/xtracr/realcamera/util/VertexDataCatcher.java b/common/src/main/java/com/xtracr/realcamera/util/VertexDataCatcher.java index 7cbc16a..cbad1dc 100644 --- a/common/src/main/java/com/xtracr/realcamera/util/VertexDataCatcher.java +++ b/common/src/main/java/com/xtracr/realcamera/util/VertexDataCatcher.java @@ -5,29 +5,17 @@ import java.util.ArrayList; import java.util.List; -import java.util.function.IntPredicate; public class VertexDataCatcher implements VertexConsumer { - private final IntPredicate normalPredicate; - private final IntPredicate posPredicate; public final List normalRecorder = new ArrayList<>(); public final List posRecorder = new ArrayList<>(); - private int index; - public VertexDataCatcher(IntPredicate normalPredicate, IntPredicate posPredicate) { - this.normalPredicate = normalPredicate; - this.posPredicate = posPredicate; - } - - protected void clear() { - index = 0; - normalRecorder.clear(); - posRecorder.clear(); + public VertexDataCatcher() { } @Override public VertexConsumer vertex(double x, double y, double z) { - if (posPredicate.test(index)) posRecorder.add(new Vec3d(x, y, z)); + posRecorder.add(new Vec3d(x, y, z)); return this; } @@ -53,13 +41,12 @@ public VertexConsumer light(int u, int v) { @Override public VertexConsumer normal(float x, float y, float z) { - if (normalPredicate.test(index)) normalRecorder.add(new Vec3d(x, y, z)); + normalRecorder.add(new Vec3d(x, y, z)); return this; } @Override public void next() { - index++; } @Override diff --git a/common/src/main/resources/assets/realcamera/lang/en_us.json b/common/src/main/resources/assets/realcamera/lang/en_us.json index af8f0cd..50d416f 100644 --- a/common/src/main/resources/assets/realcamera/lang/en_us.json +++ b/common/src/main/resources/assets/realcamera/lang/en_us.json @@ -1,5 +1,6 @@ { "key.category.xtracr_realcamera": "Real Camera", + "key.xtracr_realcamera_modelViewGui": "Open Model View GUI", "key.xtracr_realcamera_togglePerspective": "Enable/Disable", "key.xtracr_realcamera_toggleAdjustMode": "Toggle Adjust Mode", "key.xtracr_realcamera_toggleCameraMode": "Toggle Camera Mode", @@ -108,8 +109,18 @@ "message.xtracr_realcamera_command_delete_success": "Successfully deleted '%s'", "message.xtracr_realcamera_command_listAll": "Found %d results: %s", - "screen.xtracr_realcamera_vertexSelection_title": "Vertex Selection", - "screen.widget.xtracr_realcamera_vertexSelection_yaw": "Yaw = %s", - "screen.widget.xtracr_realcamera_vertexSelection_pitch": "Pitch = %s", - "screen.widget.xtracr_realcamera_vertexSelection_reset": "Reset" + "screen.xtracr_realcamera_modelView_title": "Model View", + "screen.widget.xtracr_realcamera_modelView_yaw": "Yaw = %s", + "screen.widget.xtracr_realcamera_modelView_pitch": "Pitch = %s", + "screen.widget.xtracr_realcamera_modelView_reset": "Reset Model State", + "screen.widget.xtracr_realcamera_modelView_frontIndex": "index of the forward vector", + "screen.widget.xtracr_realcamera_modelView_upIndex": "index of the upward vector", + "screen.widget.xtracr_realcamera_modelView_posIndex": "index of the first vertex of the plane", + "screen.widget.xtracr_realcamera_modelView_listName": "name of the list of the indexes, can be selected and bound in the 'Experimental' screen of config screen if saved", + "screen.widget.xtracr_realcamera_modelView_save": "Save", + "screen.widget.xtracr_realcamera_modelView_load": "Load", + + "screen.tooltip.xtracr_realcamera_modelView_selectFront": "When turned on, hold Alt and left click to select forward vector", + "screen.tooltip.xtracr_realcamera_modelView_selectUp": "When turned on, hold Alt and left click to select upward vector", + "screen.tooltip.xtracr_realcamera_modelView_selectPos": "When turned on, hold Alt and left click to select plane, to which camera can be bound to its center" } \ No newline at end of file diff --git a/common/src/main/resources/assets/realcamera/lang/zh_cn.json b/common/src/main/resources/assets/realcamera/lang/zh_cn.json index b2e2f27..c0a3af8 100644 --- a/common/src/main/resources/assets/realcamera/lang/zh_cn.json +++ b/common/src/main/resources/assets/realcamera/lang/zh_cn.json @@ -1,5 +1,6 @@ { "key.category.xtracr_realcamera": "Real Camera", + "key.xtracr_realcamera_modelViewGui": "打开模型视图界面", "key.xtracr_realcamera_togglePerspective": "开启/关闭", "key.xtracr_realcamera_toggleAdjustMode": "切换调整模式", "key.xtracr_realcamera_toggleCameraMode": "切换摄像头模式", @@ -106,5 +107,20 @@ "message.xtracr_realcamera_command_autoBind": "绑定成功: (位置) [%d], (前方) [%d], (上方) [%d] and (左方) [%d]", "message.xtracr_realcamera_command_delete_failure": "未能找到'%s'", "message.xtracr_realcamera_command_delete_success": "成功删除'%s'", - "message.xtracr_realcamera_command_listAll": "找到了%d个结果: %s" + "message.xtracr_realcamera_command_listAll": "找到了%d个结果: %s", + + "screen.xtracr_realcamera_modelView_title": "模型试图", + "screen.widget.xtracr_realcamera_modelView_yaw": "俯仰 = %s", + "screen.widget.xtracr_realcamera_modelView_pitch": "偏航 = %s", + "screen.widget.xtracr_realcamera_modelView_reset": "重置模型状态", + "screen.widget.xtracr_realcamera_modelView_frontIndex": "向前矢量的索引", + "screen.widget.xtracr_realcamera_modelView_upIndex": "向上矢量的索引", + "screen.widget.xtracr_realcamera_modelView_posIndex": "平面的第一个顶点的索引", + "screen.widget.xtracr_realcamera_modelView_listName": "索引组的名称,保存后可在配置屏幕的'Experimental'界面选择并绑定", + "screen.widget.xtracr_realcamera_modelView_save": "保存", + "screen.widget.xtracr_realcamera_modelView_load": "加载", + + "screen.tooltip.xtracr_realcamera_modelView_selectFront": "打开后,按住Alt并左键可选择向前矢量", + "screen.tooltip.xtracr_realcamera_modelView_selectUp": "打开后,按住Alt并左键可选择向上矢量", + "screen.tooltip.xtracr_realcamera_modelView_selectPos": "打开后,按住Alt并左键可选择平面,摄像头可以绑定到该平面的中心点上" } \ No newline at end of file diff --git a/fabric/src/main/java/com/xtracr/realcamera/RealCameraFabric.java b/fabric/src/main/java/com/xtracr/realcamera/RealCameraFabric.java index d51125a..6921149 100644 --- a/fabric/src/main/java/com/xtracr/realcamera/RealCameraFabric.java +++ b/fabric/src/main/java/com/xtracr/realcamera/RealCameraFabric.java @@ -1,7 +1,6 @@ package com.xtracr.realcamera; import com.xtracr.realcamera.command.ClientCommand; -import com.xtracr.realcamera.util.VertexDataAnalyser; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; @@ -18,7 +17,6 @@ public void onInitializeClient() { RealCamera.setup(); ClientTickEvents.END_CLIENT_TICK.register(KeyBindings::handle); - ClientTickEvents.END_CLIENT_TICK.register(client -> VertexDataAnalyser.tick()); WorldRenderEvents.START.register(EventHandler::onWorldRenderStart); ClientCommandRegistrationCallback.EVENT.register(new ClientCommand()::register); diff --git a/forge/src/main/java/com/xtracr/realcamera/EventHandler.java b/forge/src/main/java/com/xtracr/realcamera/EventHandler.java index 27dc783..cb492e6 100644 --- a/forge/src/main/java/com/xtracr/realcamera/EventHandler.java +++ b/forge/src/main/java/com/xtracr/realcamera/EventHandler.java @@ -3,14 +3,12 @@ import com.xtracr.realcamera.command.ClientCommand; import com.xtracr.realcamera.config.ConfigFile; import com.xtracr.realcamera.util.CrosshairUtil; -import com.xtracr.realcamera.util.VertexDataAnalyser; import net.minecraft.client.MinecraftClient; import net.minecraft.server.command.ServerCommandSource; import net.minecraftforge.client.event.InputEvent.Key; import net.minecraftforge.client.event.RegisterClientCommandsEvent; import net.minecraftforge.client.event.RenderLevelStageEvent; import net.minecraftforge.client.event.ViewportEvent; -import net.minecraftforge.event.TickEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; public class EventHandler { @@ -28,11 +26,6 @@ public static void onCameraUpdate(ViewportEvent.ComputeCameraAngles event) { } } - @SubscribeEvent - public static void onClientTick(TickEvent.ClientTickEvent event) { - VertexDataAnalyser.tick(); - } - @SubscribeEvent public static void onClientCommandRegister(RegisterClientCommandsEvent event) { new ClientCommand().register(event.getDispatcher(), event.getBuildContext()); diff --git a/forge/src/main/java/com/xtracr/realcamera/RealCameraForge.java b/forge/src/main/java/com/xtracr/realcamera/RealCameraForge.java index 7c5fce1..2c5e289 100644 --- a/forge/src/main/java/com/xtracr/realcamera/RealCameraForge.java +++ b/forge/src/main/java/com/xtracr/realcamera/RealCameraForge.java @@ -28,7 +28,6 @@ public void clientSetup(FMLClientSetupEvent event) { MinecraftForge.EVENT_BUS.addListener(EventHandler::onKeyInput); MinecraftForge.EVENT_BUS.addListener(EventHandler::onCameraUpdate); - MinecraftForge.EVENT_BUS.addListener(EventHandler::onClientTick); MinecraftForge.EVENT_BUS.addListener(EventHandler::onClientCommandRegister); MinecraftForge.EVENT_BUS.addListener(EventHandler::onRenderWorldStage); diff --git a/gradle.properties b/gradle.properties index 532cbba..db64d95 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,16 +2,16 @@ org.gradle.jvmargs=-Xmx4G org.gradle.parallel=true # Loader Properties -minecraft_version=1.20.2 +minecraft_version=1.20.1 enabled_platforms=fabric,forge -forge_version=1.20.2-48.1.0 +forge_version=1.20.1-47.2.18 fabric_loader_version=0.15.3 -yarn_mappings=1.20.2+build.4 +yarn_mappings=1.20.1+build.10 # Mod Properties mod_version=0.6.0-alpha.1 maven_group=com.xtracr.realcamera archives_base_name=realcamera # Dependencies -fabric_api_version=0.91.2+1.20.2 -cloth_config_version=12.0.113 -modmenu_version=8.0.0 +fabric_api_version=0.91.0+1.20.1 +cloth_config_version=11.1.106 +modmenu_version=7.1.0