正确实现OBB旋转
This commit is contained in:
parent
b6ddd1557f
commit
219fe939a3
4 changed files with 33 additions and 11 deletions
|
@ -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()),
|
||||
|
|
|
@ -92,7 +92,7 @@ public class Yx100Entity extends ContainerMobileVehicleEntity implements GeoEnti
|
|||
|
||||
public Yx100Entity(EntityType<Yx100Entity> 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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue