Skip to content

Commit

Permalink
Fixed #88, #89 and #90
Browse files Browse the repository at this point in the history
  • Loading branch information
xTracr committed Jul 11, 2024
1 parent 5e2c204 commit 739d523
Show file tree
Hide file tree
Showing 12 changed files with 94 additions and 44 deletions.
26 changes: 15 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
## [中文](README_ZH.md) ##

Make the camera more realistic in the first-person view.
Supported versions: 1.18-1.20 Forge & Fabric.
Supported versions: 1.20-1.21 Fabric & NeoForge.
Download the mod from [Releases](https://github.com/xTracr/RealCamera/releases), [Modrinth](https://modrinth.com/mod/real-camera) or [CurseForge](https://curseforge.com/minecraft/mc-mods/real-camera)
Snapshots are [here](https://github.com/xTracr/RealCamera/actions/workflows/build.yml)

Expand All @@ -14,26 +14,30 @@ Snapshots are [here](https://github.com/xTracr/RealCamera/actions/workflows/buil
* Render player model in first-person perspective.
* Use F6 to toggle the feature on or off and other hotkeys to adjust the camera.
* Configure these features in the config screen (Cloth Config required).

### Configuration (0.6+) ###

* Theoretically, most mod models are supported, but need to be configured manually:
* First, set the key binding for `Open Model View Screen`.
* Open the model view gui and left click with left Alt held to select the corresponding face of the model, scroll with left Alt held to switch between the different layers of the model.
* By clicking the `Selecting` button on the left, switch between the three to select the `Forward Vector`, `Upward Vector`, and `Target Plane`.
* Enter the `Preview` section, where you can see the relative relationship between the camera and the model and make certain adjustments (you can also adjust through key bindings).
* Enter a name and save (if needed, other settings such as priority can be changed).
* First, set the key binding for `Open Model View Screen`.
* ![model view screen](https://cdn.modrinth.com/data/fYYSAh4R/images/cc484d54238992077ab3632c274a2631efeca35f.png)
* Open the model view screen and left click with left Alt held to select the corresponding face of the model, scroll with left Alt held to switch between the different layers of the model.
* By clicking the `Selecting` button on the left, switch between the three to select the `Forward Vector`, `Upward Vector`, and `Target Plane`.
* Enter the `Preview` section, where you can see the relative relationship between the camera and the model and make certain adjustments (you can also adjust through key bindings).
* ![preview](https://cdn.modrinth.com/data/fYYSAh4R/images/22cfcf444bbf2d3c0d0280e470a29f01b9308617.png)
* Enter a name and save (if needed, other settings such as priority can be changed).

### Dependencies ###
## Dependencies ##

* Fabric:
* [Fabric Loader](https://fabricmc.net/use/installer/)
* [Fabric API](https://modrinth.com/mod/fabric-api)
* Forge:
* [Forge Mod Loader](https://files.minecraftforge.net/)
* Both:
* (Optional but recommended) [Cloth Config API](https://modrinth.com/mod/cloth-config)

## FAQ ##

* WIP
* A part of the model (e.g. hair) is always in the way, how to make it invisible?
* Increasing this value may help
![screenshot_2024_6_2_22_42](https://github.com/xTracr/RealCamera/assets/57320980/78c246e8-34aa-4979-89de-780ee907870b)

### Compatibility ###

Expand Down
28 changes: 16 additions & 12 deletions README_ZH.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
## [English](README.md) ##

使第一人称视角下的摄像头更加真实。
支持的版本: 1.18-1.20 Forge & Fabric
支持的版本: 1.20-1.21 Fabric & NeoForge
[Releases](https://github.com/xTracr/RealCamera/releases)[Modrinth](https://modrinth.com/mod/real-camera)[CurseForge](https://curseforge.com/minecraft/mc-mods/real-camera)下载
快照版在[这里](https://github.com/xTracr/RealCamera/actions/workflows/build.yml)

Expand All @@ -14,26 +14,30 @@
* 在第一人称视角下渲染玩家模型
* 按下F6来开关,另外一些键来调整摄像头
* 在配置界面配置以上特性(需Cloth Config)

### 配置 ###

* 理论上支持大多数模组模型,但需要手动进行配置:
* 首先设置`打开模型视图界面`的按键绑定
* 打开模型视图界面,左Alt+左键选择模型的对应的面,左Alt+滚轮可以在模型的不同层间切换
* 通过点击左侧的`选择`按钮,在三者间切换,选好`向前矢量``向上矢量``目标平面`
* 进入`预览`部分,在这里可以看到摄像头与模型的相对关系并进行一定的调整(也可以通过按键绑定调整)
* 输入名称并保存(如果需要,还有其他设置如优先级可以更改)
* 首先设置`打开模型视图界面`的按键绑定
* ![model view screen](https://cdn.modrinth.com/data/fYYSAh4R/images/cc484d54238992077ab3632c274a2631efeca35f.png)
* 打开模型视图界面,左Alt+左键选择模型的对应的面,左Alt+滚轮可以在模型的不同层间切换
* 通过点击左侧的`选择`按钮,在三者间切换,选好`向前矢量``向上矢量``目标平面`
* 进入`预览`部分,在这里可以看到摄像头与模型的相对关系并进行一定的调整(也可以通过按键绑定调整)
* ![preview](https://cdn.modrinth.com/data/fYYSAh4R/images/22cfcf444bbf2d3c0d0280e470a29f01b9308617.png)
* 输入名称并保存(如果需要,还有其他设置如优先级可以更改)

### 依赖项目 ###
## 依赖项目 ##

* Fabric:
* [Fabric Loader](https://fabricmc.net/use/installer/)
* [Fabric API](https://modrinth.com/mod/fabric-api)
* Forge:
* [Forge Mod Loader](https://files.minecraftforge.net/)
* Both:
* 所有平台:
* (可选但建议)[Cloth Config API](https://modrinth.com/mod/cloth-config)

## 常见问题 ##

* 施工中
* 模型的一部分(如头发)始终挡在面前,怎样隐藏它?
* 增加这个值或许有所帮助
![screenshot_2024_6_2_22_42](https://github.com/xTracr/RealCamera/assets/57320980/78c246e8-34aa-4979-89de-780ee907870b)

### 兼容性 ###

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.xtracr.realcamera.compat;

import com.xtracr.realcamera.RealCameraCore;
import net.minecraft.world.item.ItemStack;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
Expand All @@ -9,6 +10,7 @@
public class CompatibilityHelper {
private static Class<?> NEA_NEAnimationsLoader = null;
private static Method NEA_playerTransformer_setDeltaTick = null;
protected static Method Exposure_CameraItem_isActive = null;

@SuppressWarnings("unchecked")
public static void initialize() {
Expand All @@ -26,6 +28,11 @@ public static void initialize() {
NEA_playerTransformer_setDeltaTick = NEA_PlayerTransformer.getDeclaredMethod("setDeltaTick", float.class);
} catch (Exception ignored) {
}
if (isClassLoaded("io.github.mortuusars.exposure.Exposure")) try {
Class<?> Exposure_CameraItem = Class.forName("io.github.mortuusars.exposure.item.CameraItem");
Exposure_CameraItem_isActive = Exposure_CameraItem.getDeclaredMethod("isActive", ItemStack.class);
} catch (Exception ignored) {
}
}

public static void NEA_setDeltaTick(float tickDelta) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,33 @@
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;

import java.util.HashMap;
import java.util.Map;
import java.util.function.Predicate;

public class DisableHelper {
private static final Map<String, Predicate<LivingEntity>> predicates = new HashMap<>();
private static final String EXPOSURE_CAMERA = "exposure:camera";

public static void initialize() {
registerOr("mainFeature", LivingEntity::isSleeping);
registerOr("renderModel", entity -> entity instanceof Player player && player.isScoping());
registerOr("renderModel", entity -> ConfigFile.config().getDisableRenderItems().contains(BuiltInRegistries.ITEM.getKey(entity.getMainHandItem().getItem()).toString()));
registerOr("renderModel", entity -> ConfigFile.config().getDisableRenderItems().contains(BuiltInRegistries.ITEM.getKey(entity.getOffhandItem().getItem()).toString()));
registerOr("renderModel", entity -> {
if (CompatibilityHelper.Exposure_CameraItem_isActive == null) return false;
final ItemStack itemStack;
if (EXPOSURE_CAMERA.equals(BuiltInRegistries.ITEM.getKey(entity.getMainHandItem().getItem()).toString())) itemStack = entity.getMainHandItem();
else if (EXPOSURE_CAMERA.equals(BuiltInRegistries.ITEM.getKey(entity.getOffhandItem().getItem()).toString())) itemStack = entity.getOffhandItem();
else return false;
try {
return (boolean) CompatibilityHelper.Exposure_CameraItem_isActive.invoke(itemStack.getItem(), itemStack);
} catch (Exception ignored) {
return false;
}
});
}

public static void registerOr(String type, Predicate<LivingEntity> predicate) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
import java.util.List;

public class BindingTarget {
protected static final List<BindingTarget> defaultTargets = List.of(createDefaultTarget("minecraft_head", "minecraft:textures/entity/player/", 5, false),
createDefaultTarget("skin_head", "minecraft:skins/", 5, false),
createDefaultTarget("minecraft_head_2", "minecraft:textures/entity/player/", 0, true),
createDefaultTarget("skin_head_2", "minecraft:skins/", 0, true));
protected static final List<BindingTarget> defaultTargets = List.of(vanillaTarget("minecraft_head", 5, false).offsetX(-0.1),
vanillaTarget("skin_head", 5, false).offsetX(-0.1),
vanillaTarget("minecraft_head_2", 1, true).offsetX(-0.1),
vanillaTarget("skin_head_2", 1, true).offsetX(-0.1),
vanillaTarget("minecraft_head_3", 0, true).offsetX(-0.06).offsetY(-0.08).disablingDepth(0.08f),
vanillaTarget("skin_head_3", 0, true).offsetX(-0.06).offsetY(-0.08).disablingDepth(0.08f));
public final String name, textureId;
public int priority = 0;
public float forwardU = 0, forwardV = 0, upwardU = 0, upwardV = 0, posU = 0, posV = 0, disablingDepth = 0.2f;
Expand All @@ -26,13 +28,12 @@ public BindingTarget(String name, String textureId) {
this.textureId = textureId;
}

private static BindingTarget createDefaultTarget(String name, String textureId, int priority, boolean shouldBind) {
return new BindingTarget(name, textureId).priority(priority)
private static BindingTarget vanillaTarget(String name, int priority, boolean shouldBind) {
return new BindingTarget(name, name.contains("skin") ? "minecraft:skins/" : "minecraft:textures/entity/player/").priority(priority)
.forwardU(0.1875f).forwardV(0.2f)
.upwardU(0.1875f).upwardV(0.075f)
.posU(0.1875f).posV(0.2f)
.bindX(shouldBind).bindZ(shouldBind).bindRotation(shouldBind)
.offsetX(-0.1)
.disabledTextureIds(List.of("minecraft:textures/entity/enderdragon/dragon.png"));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ private void initRightWidgets(final int category, final int page) {
@Override
public void render(GuiGraphics graphics, int mouseX, int mouseY, float delta) {
renderBackground(graphics);// 1.20.1 only
drawEntity(graphics, x + (xSize - ySize) / 2, y, x + (xSize + ySize) / 2, y + ySize, mouseX, mouseY, minecraft.player);
renderEntityInViewArea(graphics, x + (xSize - ySize) / 2, y, x + (xSize + ySize) / 2, y + ySize, mouseX, mouseY, minecraft.player);
super.render(graphics, mouseX, mouseY, delta);
}

Expand All @@ -239,7 +239,7 @@ public void renderBackground(GuiGraphics graphics) {
graphics.fill(x + (xSize + ySize) / 2 + 4, y, x + xSize, y + ySize, 0xFF444444);
}

protected void drawEntity(GuiGraphics graphics, int x1, int y1, int x2, int y2, int mouseX, int mouseY, LivingEntity entity) {
protected void renderEntityInViewArea(GuiGraphics graphics, 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;
graphics.enableScissor(x1, y1, x2, y2);
Expand All @@ -255,7 +255,7 @@ protected void drawEntity(GuiGraphics graphics, int x1, int y1, int x2, int y2,
entity.yHeadRot = entity.getYRot();
entity.yHeadRotO = entity.getYRot();
Vector3f vector3f = new Vector3f((float) entityX, (float) entityY, -2.0f);
drawEntity(graphics, centerX, centerY, mouseX, mouseY, vector3f, quaternionf, entity);
renderEntityWithAnalyser(graphics, centerX, centerY, mouseX, mouseY, vector3f, quaternionf, entity);
entity.yBodyRot = entityBodyYaw;
entity.setYRot(entityYaw);
entity.setXRot(entityPitch);
Expand All @@ -264,7 +264,7 @@ protected void drawEntity(GuiGraphics graphics, int x1, int y1, int x2, int y2,
graphics.disableScissor();
}

protected void drawEntity(GuiGraphics graphics, float x, float y, int mouseX, int mouseY, Vector3f offset, Quaternionf quaternionf, LivingEntity entity) {
protected void renderEntityWithAnalyser(GuiGraphics graphics, float x, float y, int mouseX, int mouseY, Vector3f offset, Quaternionf quaternionf, LivingEntity entity) {
graphics.pose().pushPose();
graphics.pose().translate(x, y, 0);
graphics.pose().mulPoseMatrix(new Matrix4f().scaling(entitySize, entitySize, -entitySize));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.xtracr.realcamera.mixin;

import net.minecraft.client.renderer.GameRenderer;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;

@Mixin(GameRenderer.class)
public interface GameRendererAccessor {
@Accessor
float getFov();

@Accessor
float getOldFov();
}
14 changes: 11 additions & 3 deletions common/src/main/java/com/xtracr/realcamera/mixin/MixinCamera.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.xtracr.realcamera.config.ConfigFile;
import com.xtracr.realcamera.config.ModConfig;
import net.minecraft.client.Camera;
import net.minecraft.client.Minecraft;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
Expand Down Expand Up @@ -55,14 +56,14 @@ public abstract class MixinCamera {
setPosition(prevPos);
setRotation(RealCameraCore.getYaw(yRot), RealCameraCore.getPitch(xRot));
}
realcamera$clipToSpace(startVec);
realcamera$clipToSpace(startVec, realcamera$getFov(tickDelta));
RealCameraCore.setCameraPos(position);
}

@Unique
private void realcamera$clipToSpace(Vec3 startVec) {
private void realcamera$clipToSpace(Vec3 startVec, double fov) {
Vec3 offset = position.subtract(startVec);
final float depth = 0.085f;
final float depth = 0.05f + (float) (fov * (0.0001 + 0.000005 * fov));
for (int i = 0; i < 8; ++i) {
float f = depth * ((i & 1) * 2 - 1);
float g = depth * ((i >> 1 & 1) * 2 - 1);
Expand All @@ -77,6 +78,13 @@ public abstract class MixinCamera {
setPosition(startVec.add(offset));
}

@Unique
private static float realcamera$getFov(float tickDelta) {
Minecraft client = Minecraft.getInstance();
float multiplier = Mth.lerp(tickDelta, ((GameRendererAccessor) client.gameRenderer).getOldFov(), ((GameRendererAccessor) client.gameRenderer).getFov());
return client.options.fov().get() * multiplier;
}

@Shadow
protected abstract void move(double x, double y, double z);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import com.xtracr.realcamera.RealCameraCore;
import com.xtracr.realcamera.config.ConfigFile;
import net.minecraft.client.Camera;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.*;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.phys.Vec3;
Expand All @@ -18,8 +17,6 @@

@Mixin(LevelRenderer.class)
public abstract class MixinLevelRenderer {
@Shadow
@Final private Minecraft minecraft;
@Shadow
@Final private RenderBuffers renderBuffers;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ public void buildRecords() {
public BuiltRecord getTargetPosAndRot(BindingTarget target, Matrix3f normal, Vector3f position) {
return records.stream().map(record -> {
if (!record.textureId().contains(target.textureId)) return null;
Vec3 forward = getPrimitive(record, target.forwardU, target.forwardV)[0].normal().normalize();
Vec3 left = getPrimitive(record, target.upwardU, target.upwardV)[0].normal().cross(forward).normalize();
Vec3 forward = getPrimitive(record, target.forwardU, target.forwardV)[0].normal();
Vec3 left = getPrimitive(record, target.upwardU, target.upwardV)[0].normal().cross(forward);
Vertex[] face = getPrimitive(record, target.posU, target.posV);
if (face[0].normal().equals(Vec3.ZERO) && forward.equals(Vec3.ZERO) && left.equals(Vec3.ZERO)) return null;
normal.set(left.toVector3f(), forward.cross(left).toVector3f(), forward.toVector3f());
Expand Down Expand Up @@ -194,7 +194,7 @@ public Vec3 pos() {
}

public Vec3 normal() {
return new Vec3(normalX, normalY, normalZ);
return new Vec3(normalX, normalY, normalZ).normalize();
}

public Vertex transform(Matrix4f positionMatrix, Matrix3f normalMatrix) {
Expand Down
1 change: 1 addition & 0 deletions common/src/main/resources/realcamera-common.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
],
"client": [
"CameraAccessor",
"GameRendererAccessor",
"MixinCamera",
"MixinGameRenderer",
"MixinGui",
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ forge_version=1.20.1-47.3.1
fabric_loader_version=0.15.10
#yarn_mappings=1.20.1+build.10
# Mod Properties
mod_version=0.6.1-beta
mod_version=0.6.2-beta.1
maven_group=com.xtracr.realcamera
archives_base_name=realcamera
# Dependencies
Expand Down

0 comments on commit 739d523

Please sign in to comment.