diff --git a/src/main/java/com/atsuishio/superbwarfare/client/renderer/special/OBBRenderer.java b/src/main/java/com/atsuishio/superbwarfare/client/renderer/special/OBBRenderer.java index f442949f1..eb9e9de81 100644 --- a/src/main/java/com/atsuishio/superbwarfare/client/renderer/special/OBBRenderer.java +++ b/src/main/java/com/atsuishio/superbwarfare/client/renderer/special/OBBRenderer.java @@ -1,10 +1,11 @@ package com.atsuishio.superbwarfare.client.renderer.special; +import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity; import com.atsuishio.superbwarfare.tools.OBB; +import com.atsuishio.superbwarfare.tools.VectorTool; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; import net.minecraft.client.renderer.LevelRenderer; -import net.minecraft.world.entity.Entity; import net.minecraft.world.phys.Vec3; import org.joml.Quaternionf; import org.joml.Vector3f; @@ -16,11 +17,11 @@ public class OBBRenderer { public static final OBBRenderer INSTANCE = new OBBRenderer(); - public void render(Entity entity, OBB obb, PoseStack poseStack, VertexConsumer buffer, float red, float green, float blue, float alpha) { + public void render(VehicleEntity entity, OBB obb, PoseStack poseStack, VertexConsumer buffer, float red, float green, float blue, float alpha, float pPartialTicks) { Vec3 position = entity.position(); Vector3f center = obb.center(); Vector3f halfExtents = obb.extents(); - Quaternionf rotation = obb.rotation(); + Quaternionf rotation = VectorTool.combineRotations(pPartialTicks, entity); renderOBB( poseStack, buffer, (float) (center.x() - position.x()), (float) (center.y() - position.y()), (float) (center.z() - position.z()), diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Yx100Entity.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Yx100Entity.java index efb588627..3c02aa739 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Yx100Entity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Yx100Entity.java @@ -92,7 +92,7 @@ public class Yx100Entity extends ContainerMobileVehicleEntity implements GeoEnti public Yx100Entity(EntityType type, Level world) { super(type, world); - this.obb = new OBB(this.position().toVector3f(), new Vector3f(3.5f, 3.0f, 5.0f), new Quaternionf()); + this.obb = new OBB(this.position().toVector3f(), new Vector3f(2.53125f, 1.0625f, 4.75f), new Quaternionf()); } @Override @@ -1297,11 +1297,12 @@ public class Yx100Entity extends ContainerMobileVehicleEntity implements GeoEnti return this.obb; } - // TODO 实现正确的旋转设置 @Override public void updateOBB() { - Quaternionf rotation = eulerToQuaternion(-getRoll(), -getYRot(), getXRot()); - this.obb.setRotation(rotation); - this.obb.center().set(this.position().toVector3f()); + Matrix4f transform = getVehicleTransform(1); + Vector4f worldPosition = transformPosition(transform, 0, 1.125f, 0.25f); + this.obb.center().set(new Vector3f(worldPosition.x, worldPosition.y, worldPosition.z)); + + this.obb.setRotation(VectorTool.combineRotations(1, this)); } } diff --git a/src/main/java/com/atsuishio/superbwarfare/mixins/EntityRenderDispatcherMixin.java b/src/main/java/com/atsuishio/superbwarfare/mixins/EntityRenderDispatcherMixin.java index 416b081c9..603d6e1d3 100644 --- a/src/main/java/com/atsuishio/superbwarfare/mixins/EntityRenderDispatcherMixin.java +++ b/src/main/java/com/atsuishio/superbwarfare/mixins/EntityRenderDispatcherMixin.java @@ -2,8 +2,10 @@ package com.atsuishio.superbwarfare.mixins; import com.atsuishio.superbwarfare.client.renderer.special.OBBRenderer; import com.atsuishio.superbwarfare.entity.OBBEntity; +import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; +import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.entity.EntityRenderDispatcher; import net.minecraft.world.entity.Entity; import org.spongepowered.asm.mixin.Mixin; @@ -16,9 +18,9 @@ public class EntityRenderDispatcherMixin { @Inject(method = "renderHitbox", at = @At("RETURN")) - private static void renderHitbox(PoseStack poseStack, VertexConsumer buffer, Entity entity, float red, float green, float blue, float alpha, CallbackInfo ci) { - if (entity instanceof OBBEntity obbEntity) { - OBBRenderer.INSTANCE.render(entity, obbEntity.getOBB(), poseStack, buffer, 1, 1, 1, 1); + private static void renderHitbox(PoseStack poseStack, VertexConsumer buffer, Entity p_entity, float red, float green, float blue, float alpha, CallbackInfo ci) { + if (p_entity instanceof OBBEntity obbEntity && p_entity instanceof VehicleEntity vehicle) { + OBBRenderer.INSTANCE.render(vehicle, obbEntity.getOBB(), poseStack, buffer, 1, 1, 1, 1, Minecraft.getInstance().getTimer().getRealtimeDeltaTicks()); } } } diff --git a/src/main/java/com/atsuishio/superbwarfare/tools/VectorTool.java b/src/main/java/com/atsuishio/superbwarfare/tools/VectorTool.java index 1f7008222..f112cb010 100644 --- a/src/main/java/com/atsuishio/superbwarfare/tools/VectorTool.java +++ b/src/main/java/com/atsuishio/superbwarfare/tools/VectorTool.java @@ -1,7 +1,10 @@ package com.atsuishio.superbwarfare.tools; +import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity; +import com.mojang.math.Axis; import net.minecraft.util.Mth; import net.minecraft.world.phys.Vec3; +import org.joml.Quaternionf; public class VectorTool { public static double calculateAngle(Vec3 start, Vec3 end) { @@ -23,4 +26,19 @@ public class VectorTool { return ((180.0f - x) / 90.0f); // x ∈ (90, 180] } } + + // 合并三个旋转(Yaw -> Pitch -> Roll) + public static Quaternionf combineRotations(float partialTicks, VehicleEntity entity) { + // 1. 获取三个独立的旋转四元数 + Quaternionf yawRot = Axis.YP.rotationDegrees(-Mth.lerp(partialTicks, entity.yRotO, entity.getYRot())); + Quaternionf pitchRot = Axis.XP.rotationDegrees(Mth.lerp(partialTicks, entity.xRotO, entity.getXRot())); + Quaternionf rollRot = Axis.ZP.rotationDegrees(Mth.lerp(partialTicks, entity.prevRoll, entity.getRoll())); + + // 2. 按照正确顺序合并:先Yaw,再Pitch,最后Roll + Quaternionf combined = new Quaternionf(yawRot); // 初始化为Yaw旋转 + combined.mul(pitchRot); // 应用Pitch旋转 + combined.mul(rollRot); // 应用Roll旋转 + + return combined; + } }