正确实现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;
|
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.OBB;
|
||||||
|
import com.atsuishio.superbwarfare.tools.VectorTool;
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||||
import net.minecraft.client.renderer.LevelRenderer;
|
import net.minecraft.client.renderer.LevelRenderer;
|
||||||
import net.minecraft.world.entity.Entity;
|
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
import org.joml.Quaternionf;
|
import org.joml.Quaternionf;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
|
@ -16,11 +17,11 @@ public class OBBRenderer {
|
||||||
|
|
||||||
public static final OBBRenderer INSTANCE = new 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();
|
Vec3 position = entity.position();
|
||||||
Vector3f center = obb.center();
|
Vector3f center = obb.center();
|
||||||
Vector3f halfExtents = obb.extents();
|
Vector3f halfExtents = obb.extents();
|
||||||
Quaternionf rotation = obb.rotation();
|
Quaternionf rotation = VectorTool.combineRotations(pPartialTicks, entity);
|
||||||
renderOBB(
|
renderOBB(
|
||||||
poseStack, buffer,
|
poseStack, buffer,
|
||||||
(float) (center.x() - position.x()), (float) (center.y() - position.y()), (float) (center.z() - position.z()),
|
(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) {
|
public Yx100Entity(EntityType<Yx100Entity> type, Level world) {
|
||||||
super(type, 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
|
@Override
|
||||||
|
@ -1297,11 +1297,12 @@ public class Yx100Entity extends ContainerMobileVehicleEntity implements GeoEnti
|
||||||
return this.obb;
|
return this.obb;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO 实现正确的旋转设置
|
|
||||||
@Override
|
@Override
|
||||||
public void updateOBB() {
|
public void updateOBB() {
|
||||||
Quaternionf rotation = eulerToQuaternion(-getRoll(), -getYRot(), getXRot());
|
Matrix4f transform = getVehicleTransform(1);
|
||||||
this.obb.setRotation(rotation);
|
Vector4f worldPosition = transformPosition(transform, 0, 1.125f, 0.25f);
|
||||||
this.obb.center().set(this.position().toVector3f());
|
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.client.renderer.special.OBBRenderer;
|
||||||
import com.atsuishio.superbwarfare.entity.OBBEntity;
|
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.PoseStack;
|
||||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.renderer.entity.EntityRenderDispatcher;
|
import net.minecraft.client.renderer.entity.EntityRenderDispatcher;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
@ -16,9 +18,9 @@ public class EntityRenderDispatcherMixin {
|
||||||
|
|
||||||
@Inject(method = "renderHitbox",
|
@Inject(method = "renderHitbox",
|
||||||
at = @At("RETURN"))
|
at = @At("RETURN"))
|
||||||
private static void renderHitbox(PoseStack poseStack, VertexConsumer buffer, Entity entity, float red, float green, float blue, float alpha, CallbackInfo ci) {
|
private static void renderHitbox(PoseStack poseStack, VertexConsumer buffer, Entity p_entity, float red, float green, float blue, float alpha, CallbackInfo ci) {
|
||||||
if (entity instanceof OBBEntity obbEntity) {
|
if (p_entity instanceof OBBEntity obbEntity && p_entity instanceof VehicleEntity vehicle) {
|
||||||
OBBRenderer.INSTANCE.render(entity, obbEntity.getOBB(), poseStack, buffer, 1, 1, 1, 1);
|
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;
|
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.util.Mth;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
import org.joml.Quaternionf;
|
||||||
|
|
||||||
public class VectorTool {
|
public class VectorTool {
|
||||||
public static double calculateAngle(Vec3 start, Vec3 end) {
|
public static double calculateAngle(Vec3 start, Vec3 end) {
|
||||||
|
@ -23,4 +26,19 @@ public class VectorTool {
|
||||||
return ((180.0f - x) / 90.0f); // x ∈ (90, 180]
|
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