diff --git a/README.md b/README.md index f285e3b..b81f149 100644 --- a/README.md +++ b/README.md @@ -3,16 +3,17 @@ ## Zero gravity space -[x] no gravity -[x] swim movement --[ ] no swim up/down based on pitch + -[ ] no swim up/down based on pitch +-[ ] correct on ground to use all surface orientations -[x] no fall damage -[ ] bump into wall damage regardless of direction -[ ] make mob AI less helpless in zero gravity ## 6DOF -[x] camera --[ ] model pose +-[x] model pose -[ ] look around -[ ] controls for roll --[ ] camera relative movement +-[ ] camera relative movement (hook Entity.movementInputToVelocity) -[ ] sync orientation -[ ] animate transition back to upright (roll) diff --git a/src/main/java/gdavid/sixdoftest/ClientMod.java b/src/main/java/gdavid/sixdoftest/ClientMod.java index 6209048..9c6f683 100644 --- a/src/main/java/gdavid/sixdoftest/ClientMod.java +++ b/src/main/java/gdavid/sixdoftest/ClientMod.java @@ -3,9 +3,6 @@ import net.fabricmc.api.ClientModInitializer; import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents; import net.minecraft.entity.Entity; -import net.minecraft.util.math.RotationAxis; -import net.minecraft.util.math.Vec3d; -import org.joml.Quaternionf; public class ClientMod implements ClientModInitializer { @@ -14,11 +11,7 @@ public void onInitializeClient() { WorldRenderEvents.AFTER_SETUP.register((ctx) -> { Entity focus = ctx.camera().getFocusedEntity(); if (focus == null) return; - float roll = (float) focus.getVelocity().dotProduct(focus.getRotationVecClient().crossProduct(new Vec3d(0, 1, 0))); - Quaternionf q = RotationAxis.POSITIVE_Z.rotation(roll); - var mats = ctx.matrixStack().peek(); - mats.getPositionMatrix().rotateLocal(q); - mats.getNormalMatrix().rotateLocal(q); + RollManager.rollTransform(ctx.matrixStack(), focus); }); } diff --git a/src/main/java/gdavid/sixdoftest/RollManager.java b/src/main/java/gdavid/sixdoftest/RollManager.java new file mode 100644 index 0000000..612561e --- /dev/null +++ b/src/main/java/gdavid/sixdoftest/RollManager.java @@ -0,0 +1,30 @@ +package gdavid.sixdoftest; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.entity.Entity; +import net.minecraft.util.math.RotationAxis; +import net.minecraft.util.math.Vec3d; +import org.joml.Quaternionf; + +public class RollManager { + + public static float getRoll(Entity entity) { + return (float) entity.getVelocity().dotProduct(entity.getRotationVecClient().crossProduct(new Vec3d(0, 1, 0))); + } + + @Environment(EnvType.CLIENT) + public static void rollTransform(MatrixStack ms, Entity entity) { + rollTransform(ms, getRoll(entity)); + } + + @Environment(EnvType.CLIENT) + public static void rollTransform(MatrixStack ms, float roll) { + Quaternionf q = RotationAxis.POSITIVE_Z.rotation(roll); + var mats = ms.peek(); + mats.getPositionMatrix().rotateLocal(q); + mats.getNormalMatrix().rotateLocal(q); + } + +} diff --git a/src/main/java/gdavid/sixdoftest/mixin/EntityMixin.java b/src/main/java/gdavid/sixdoftest/mixin/EntityMixin.java index 921aec2..ae1e905 100644 --- a/src/main/java/gdavid/sixdoftest/mixin/EntityMixin.java +++ b/src/main/java/gdavid/sixdoftest/mixin/EntityMixin.java @@ -2,7 +2,6 @@ import gdavid.sixdoftest.SpaceManager; import net.minecraft.entity.Entity; -import net.minecraft.entity.damage.DamageSource; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; @@ -36,11 +35,5 @@ private void noCrawlIn6DOFSpace(CallbackInfoReturnable callback) { if (!SpaceManager.isIn6dof(self())) return; callback.setReturnValue(false); } - - @Inject(method = "handleFallDamage", at = @At("HEAD"), cancellable = true) - private void noFallDamageIn6DOFSpace(float fallDistance, float damageMultiplier, DamageSource damageSource, CallbackInfoReturnable callback) { - if (!SpaceManager.isIn6dof(self())) return; - callback.setReturnValue(false); - } - + } diff --git a/src/main/java/gdavid/sixdoftest/mixin/LivingEntityMixin.java b/src/main/java/gdavid/sixdoftest/mixin/LivingEntityMixin.java new file mode 100644 index 0000000..6fbac73 --- /dev/null +++ b/src/main/java/gdavid/sixdoftest/mixin/LivingEntityMixin.java @@ -0,0 +1,25 @@ +package gdavid.sixdoftest.mixin; + +import gdavid.sixdoftest.SpaceManager; +import net.minecraft.entity.LivingEntity; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(LivingEntity.class) +public class LivingEntityMixin { + + @Unique + private LivingEntity self() { + return (LivingEntity) (Object) this; + } + + @Inject(method = "computeFallDamage", at = @At("HEAD"), cancellable = true) + private void noFallDamageIn6DOFSpace(float fallDistance, float damageMultiplier, CallbackInfoReturnable callback) { + if (!SpaceManager.isIn6dof(self())) return; + callback.setReturnValue(0); + } + +} diff --git a/src/main/java/gdavid/sixdoftest/mixin/PlayerEntityRendererMixin.java b/src/main/java/gdavid/sixdoftest/mixin/PlayerEntityRendererMixin.java index 45e9281..3caaed7 100644 --- a/src/main/java/gdavid/sixdoftest/mixin/PlayerEntityRendererMixin.java +++ b/src/main/java/gdavid/sixdoftest/mixin/PlayerEntityRendererMixin.java @@ -1,11 +1,15 @@ package gdavid.sixdoftest.mixin; +import gdavid.sixdoftest.RollManager; import gdavid.sixdoftest.SpaceManager; import net.minecraft.client.network.AbstractClientPlayerEntity; import net.minecraft.client.render.entity.PlayerEntityRenderer; +import net.minecraft.client.util.math.MatrixStack; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(PlayerEntityRenderer.class) public class PlayerEntityRendererMixin { @@ -15,5 +19,11 @@ public class PlayerEntityRendererMixin { private boolean fix6DOFSwimPose(AbstractClientPlayerEntity instance) { return SpaceManager.isIn6dof(instance) || instance.isTouchingWater(); } - + + @Inject(method = "setupTransforms(Lnet/minecraft/client/network/AbstractClientPlayerEntity;Lnet/minecraft/client/util/math/MatrixStack;FFF)V", at = @At("TAIL")) + private void setup6DOFTranform(AbstractClientPlayerEntity player, MatrixStack matrixStack, float f, float g, float h, CallbackInfo callback) { + if (!SpaceManager.isIn6dof(player)) return; + RollManager.rollTransform(matrixStack, player); + } + } diff --git a/src/main/resources/sixdoftest.mixins.json b/src/main/resources/sixdoftest.mixins.json index 57153b2..b80389c 100644 --- a/src/main/resources/sixdoftest.mixins.json +++ b/src/main/resources/sixdoftest.mixins.json @@ -1,13 +1,15 @@ { - "required": true, - "minVersion": "0.8", - "package": "gdavid.sixdoftest.mixin", - "compatibilityLevel": "JAVA_17", - "mixins": [ - "EntityMixin" - ], - "client": [ - "PlayerEntityRendererMixin" - ], - "injectors": { "defaultRequire": 1 } + "required": true, + "minVersion": "0.8", + "package": "gdavid.sixdoftest.mixin", + "compatibilityLevel": "JAVA_17", + "mixins": [ + "EntityMixin", + "LivingEntityMixin" + ], + "client": [ + "PlayerEntityRendererMixin" + ], + "injectors": { + "defaultRequire": 1 } }