Skip to content

Commit

Permalink
Changed to bind based on UV coordinates and Improved ModelViewScreen
Browse files Browse the repository at this point in the history
  • Loading branch information
xTracr committed Feb 17, 2024
1 parent fb75f99 commit 0357e1c
Show file tree
Hide file tree
Showing 13 changed files with 295 additions and 212 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
plugins {
id "architectury-plugin" version "3.4-SNAPSHOT"
id "dev.architectury.loom" version "1.4-SNAPSHOT" apply false
id "dev.architectury.loom" version "1.5-SNAPSHOT" apply false
}

architectury {
Expand Down
19 changes: 10 additions & 9 deletions common/src/main/java/com/xtracr/realcamera/RealCameraCore.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.AbstractClientPlayerEntity;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.entity.EntityRenderDispatcher;
import net.minecraft.client.render.entity.PlayerEntityRenderer;
Expand All @@ -27,6 +28,7 @@
import org.joml.Vector4f;

import java.util.Collection;
import java.util.function.BiPredicate;

public class RealCameraCore {
private static final ModConfig config = ConfigFile.modConfig;
Expand Down Expand Up @@ -90,16 +92,15 @@ public static void renderPlayer(Vec3d offset, MatrixStack matrices, VertexConsum
Matrix4f positionMatrix = matrices.peek().getPositionMatrix().transpose().invertAffine()
.translate((float) -offset.getX(), (float) -offset.getY(), (float) -offset.getZ());
Matrix3f normalMatrix = matrices.peek().getNormalMatrix().transpose().invert();
VertexRecorder.VertexPredicate predicate = (renderLayer, vertices, index) -> {
Vec3d center = Vec3d.ZERO;
double depth = config.disable.depth;
BiPredicate<RenderLayer, VertexRecorder.Vertex[]> biPredicate = (renderLayer, vertices) -> {
double depth = config.disable.depth, centerZ = 0;
for (VertexRecorder.Vertex vertex : vertices) {
center = center.add(vertex.pos());
if (vertex.z() < -depth) return true;
centerZ += vertex.z();
}
return center.getZ() < -depth * vertices.length;
return centerZ < -depth * vertices.length;
};
recorder.drawByAnother(vertex -> vertex.transform(positionMatrix, normalMatrix), vertexConsumers, renderLayer -> true, predicate);
recorder.drawByAnother(vertex -> vertex.transform(positionMatrix, normalMatrix), vertexConsumers, renderLayer -> true, biPredicate);
matrices.pop();
}

Expand Down Expand Up @@ -133,9 +134,9 @@ public static void computeCamera(MinecraftClient client, float tickDelta) {
}
recorder.setCurrent(renderLayer -> renderLayer.toString().contains(target.textureId()), 0);
if (recorder.quadCount() <= 0) throw new NullPointerException("Vertices not found");
Vec3d front = recorder.getNormal(target.frontIndex());
Vec3d up = recorder.getNormal(target.upIndex());
Vec3d center = recorder.getCenter(target.posIndex());
Vec3d front = recorder.getNormal(target.forwardU(), target.forwardV());
Vec3d up = recorder.getNormal(target.upwardU(), target.upwardV());
Vec3d center = recorder.getPos(target.posU(), target.posV());
if (!MathUtil.isFinite(front) || !MathUtil.isFinite(up) || !MathUtil.isFinite(center)) throw new ArithmeticException();
normal.set(up.crossProduct(front).toVector3f(), up.toVector3f(), front.toVector3f());
Vector3f vec3f = normal.transform(new Vector3f((float) (config.getBindingZ() * config.getScale()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,7 @@ private int deleteList(CommandContext<S> context) {

private int listAll(CommandContext<S> context) {
StringBuffer buffer = new StringBuffer();
config.binding.targetMap.forEach((name, target) -> buffer.append("\n'").append(name).append("' -> [ ")
.append(target.textureId()).append(" ").append(target.frontIndex()).append(" ")
.append(target.upIndex()).append(" ").append(target.posIndex()).append(" ]"));
config.binding.targetMap.forEach((name, target) -> buffer.append("\n'").append(name).append("' -> ").append(target));
printGameMessage(Text.translatable(KEY_COMMAND + "listAll", config.binding.targetMap.size(), buffer.toString()));
return 1;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,8 @@ private void clamp() {

public static class Binding {
protected static final Map<String, Target> defaultTargetMap = Map.of("minecraft_head",
new Target("minecraft:textures/entity/player/", 3, 0, 3));
new Target("minecraft:textures/entity/player/",
0.1875f, 0.2f, 0.1875f, 0.075f, 0.1875f, 0.2f));
public VanillaModelPart vanillaModelPart = VanillaModelPart.head;
public boolean experimental = false;
public boolean adjustOffset = true;
Expand Down Expand Up @@ -324,7 +325,7 @@ private void clamp() {
roll = MathHelper.wrapDegrees(roll);
}

public record Target(String textureId, int frontIndex, int upIndex, int posIndex) {}
public record Target(String textureId, float forwardU, float forwardV, float upwardU, float upwardV, float posU, float posV) {}
}

public static class Classic {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@
public class DoubleValueSlider extends SliderWidget {
private final double min, max;
private final Function<Double, Text> textFunction;
private final DoubleConsumer consumer;
private final DoubleConsumer setter;

public DoubleValueSlider(int width, int height, double value, double min, double max, Function<Double, Text> textFunction, DoubleConsumer consumer) {
public DoubleValueSlider(int width, int height, double value, double min, double max, Function<Double, Text> textFunction, DoubleConsumer setter) {
super(0, 0, width, height, textFunction.apply(min + (max - min) * value), value);
this.min = min;
this.max = max;
this.textFunction = textFunction;
this.consumer = consumer;
this.consumer.accept(min + (max - min) * value);
this.setter = setter;
this.setter.accept(min + (max - min) * value);
}

protected void setValue(double value) {
Expand All @@ -34,6 +34,6 @@ protected void updateMessage() {

@Override
protected void applyValue() {
consumer.accept(min + (max - min) * value);
setter.accept(min + (max - min) * value);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.xtracr.realcamera.gui;

import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.text.Text;
import org.jetbrains.annotations.Nullable;


public class FloatFieldWidget extends TextFieldWidget {

public FloatFieldWidget(TextRenderer textRenderer, int x, int y, int width, int height, @Nullable FloatFieldWidget copyFrom, Text text) {
super(textRenderer, x, y, width, height, text);
setMaxLength(8);
setValue(0);
if (copyFrom != null) setValue(copyFrom.getValue());
}

protected float getValue() {
try {
String text = getText();
if (text.startsWith(".")) setText("0" + text);
return Float.parseFloat(getText());
} catch (Exception exception) {
return 0f;
}
}

protected void setValue(float value) {
setText(String.valueOf(value));
}

@Override
public boolean charTyped(char chr, int modifiers) {
if (chr != '.' && (chr < '0' || chr > '9')) return false;
if (chr == '.' && getText().contains(".")) return false;
return super.charTyped(chr, modifiers);
}
}
39 changes: 0 additions & 39 deletions common/src/main/java/com/xtracr/realcamera/gui/IntFieldWidget.java

This file was deleted.

78 changes: 48 additions & 30 deletions common/src/main/java/com/xtracr/realcamera/gui/ModelAnalyser.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.render.VertexConsumer;
import org.joml.Vector3f;
import net.minecraft.util.Pair;
import net.minecraft.util.math.Vec3d;

import java.awt.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

Expand All @@ -21,29 +21,46 @@ public String focusedTextureId() {
return getTextureId(focusedRecord);
}

public int getFocusedIndex(int mouseX, int mouseY, int layers) {
List<Triple<Float, BuiltRecord, Integer>> sortByDepth = new ArrayList<>();
for (BuiltRecord record : records) for (int i = 0; i < record.quadCount(); i++) {
Vertex[] quad = record.vertices()[i];
Polygon polygon = new Polygon();
for (Vertex vertex : quad) polygon.addPoint((int) vertex.x(), (int) vertex.y());
Vertex point = quad[0];
Vector3f normal = new Vector3f(point.normalX(), point.normalY(), point.normalZ());
Vector3f mousePos = new Vector3f((float) point.x(), (float) point.y(), (float) point.z());
float deltaZ = 0;
if (normal.z() != 0) deltaZ = (normal.x() * (mouseX - mousePos.x()) + normal.y() * (mouseY - mousePos.y())) / normal.z();
if (polygon.contains(mouseX, mouseY)) sortByDepth.add(new Triple<>(mousePos.z() + deltaZ, record, i));
public Pair<Float, Float> getCenterUV(int quadIndex) {
if (quadIndex == -1 || focusedRecord == null || quadIndex >= focusedRecord.quadCount()) return null;
float u = 0, v = 0;
Vertex[] quad = focusedRecord.vertices()[quadIndex];
for (Vertex vertex : quad) {
u += vertex.u();
v += vertex.v();
}
return new Pair<>(u / quad.length, v / quad.length);
}

public int getFocusedIndex(int mouseX, int mouseY, int layers) {
List<Triple<Double, BuiltRecord, Integer>> sortByDepth = new ArrayList<>();
records.forEach(record -> {
Vertex[][] vertices = record.vertices();
for (int i = 0, size = vertices.length; i < size; i++) {
Polygon polygon = new Polygon();
Vertex[] quad = vertices[i];
for (Vertex vertex : quad) polygon.addPoint((int) vertex.x(), (int) vertex.y());
Vertex point = quad[0];
double deltaZ = 0;
if (point.normalZ() != 0) deltaZ = (point.normalX() * (mouseX - point.x()) + point.normalY() * (mouseY - point.y())) / point.normalZ();
if (polygon.contains(mouseX, mouseY)) sortByDepth.add(new Triple<>(point.z() + deltaZ, record, i));
}
});
if (sortByDepth.isEmpty()) return -1;
sortByDepth.sort(Comparator.comparingDouble(triple -> -triple.getLeft()));
Triple<Float, BuiltRecord, Integer> result = sortByDepth.get(Math.min(sortByDepth.size() - 1, layers));
Triple<Double, BuiltRecord, Integer> result = sortByDepth.get(Math.min(sortByDepth.size() - 1, layers));
focusedRecord = result.getMiddle();
return result.getRight();
}

public void drawQuad(DrawContext context, float u, float v, int argb) {
if (currentRecord == null) return;
drawQuad(context, getQuadIndex(currentRecord, u, v), argb, false);
}

public void drawQuad(DrawContext context, int quadIndex, int argb, boolean drawFocused) {
BuiltRecord record = drawFocused ? focusedRecord : currentRecord;
if (record == null || quadIndex >= record.quadCount()) return;
if (quadIndex == -1 || record == null || quadIndex >= record.quadCount()) return;
drawQuad(context, record.vertices()[quadIndex], argb, 1000);
if (drawFocused) {
Vertex[] highlight = record.vertices()[quadIndex];
Expand Down Expand Up @@ -90,30 +107,31 @@ public void drawPolyhedron(DrawContext context, int quadIndex, int argb) {
drawQuad(context, reversed, argb, 1100);
}

public void drawNormal(DrawContext context, int quadIndex, int length, int argb) {
if (quadIndex >= quadCount()) return;
public void drawNormal(DrawContext context, float u, float v, int length, int argb) {
if (currentRecord == null) return;
int quadIndex = getQuadIndex(currentRecord, u, v);
if (quadIndex == -1) return;
Vertex vertex = currentRecord.vertices()[quadIndex][0];
Vec3d start = getPos(u, v);
Vec3d end = vertex.normal().multiply(length).add(start);
VertexConsumer vertexConsumer = context.getVertexConsumers().getBuffer(RenderLayer.getLineStrip());
Vector3f normal = getNormal(quadIndex).toVector3f();
Vector3f start = getCenter(quadIndex).toVector3f();
Vector3f end = new Vector3f(normal).mul(length).add(start);
vertexConsumer.vertex(start.x(), start.y(), start.z() + 1200f).color(argb).normal(normal.x(), normal.y(), normal.z()).next();
vertexConsumer.vertex(end.x(), end.y(), end.z() + 1200f).color(argb).normal(normal.x(), normal.y(), normal.z()).next();
vertexConsumer.vertex(start.getX(), start.getY(), start.getZ() + 1200f).color(argb)
.normal(vertex.normalX(), vertex.normalY(), vertex.normalZ()).next();
vertexConsumer.vertex(end.getX(), end.getY(), end.getZ() + 1200f).color(argb)
.normal(vertex.normalX(), vertex.normalY(), vertex.normalZ()).next();
context.draw();
}

private static boolean intersects(Vertex[] quad, List<Vertex[]> quads) {
final float precision = 0.00001f;
boolean ret = false;
for (Vertex[] p : quads) for (Vertex v1 : quad)
if (Arrays.stream(p).anyMatch(v2 -> v1.pos().squaredDistanceTo(v2.pos()) < precision)) ret = true;
return ret;
for (Vertex[] q : quads) for (Vertex v1 : quad)
for (Vertex v2 : q) if (v1.pos().squaredDistanceTo(v2.pos()) < precision) return true;
return false;
}

private static void drawQuad(DrawContext context, Vertex[] quad, int argb, int offset) {
VertexConsumer vertexConsumer = context.getVertexConsumers().getBuffer(RenderLayer.getGui());
for (Vertex vertex : quad) {
vertexConsumer.vertex(vertex.x(), vertex.y(), vertex.z() + offset).color(argb).next();
}
for (Vertex vertex : quad) vertexConsumer.vertex(vertex.x(), vertex.y(), vertex.z() + offset).color(argb).next();
if (quad.length == 3) vertexConsumer.vertex(quad[2].x(), quad[2].y(), quad[2].z() + offset).color(argb).next();
context.draw();
}
Expand Down
Loading

0 comments on commit 0357e1c

Please sign in to comment.