尝试添加obb与aabb的碰撞检测
This commit is contained in:
parent
773b0b0d35
commit
c8c141e4bb
3 changed files with 118 additions and 25 deletions
|
@ -4,6 +4,7 @@ import com.atsuishio.superbwarfare.block.BarbedWireBlock;
|
||||||
import com.atsuishio.superbwarfare.component.ModDataComponents;
|
import com.atsuishio.superbwarfare.component.ModDataComponents;
|
||||||
import com.atsuishio.superbwarfare.config.server.ProjectileConfig;
|
import com.atsuishio.superbwarfare.config.server.ProjectileConfig;
|
||||||
import com.atsuishio.superbwarfare.entity.DPSGeneratorEntity;
|
import com.atsuishio.superbwarfare.entity.DPSGeneratorEntity;
|
||||||
|
import com.atsuishio.superbwarfare.entity.OBBEntity;
|
||||||
import com.atsuishio.superbwarfare.entity.TargetEntity;
|
import com.atsuishio.superbwarfare.entity.TargetEntity;
|
||||||
import com.atsuishio.superbwarfare.entity.mixin.ICustomKnockback;
|
import com.atsuishio.superbwarfare.entity.mixin.ICustomKnockback;
|
||||||
import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity;
|
import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity;
|
||||||
|
@ -155,6 +156,7 @@ public class ProjectileEntity extends Projectile implements IEntityWithComplexSp
|
||||||
@Nullable
|
@Nullable
|
||||||
protected List<EntityResult> findEntitiesOnPath(Vec3 startVec, Vec3 endVec) {
|
protected List<EntityResult> findEntitiesOnPath(Vec3 startVec, Vec3 endVec) {
|
||||||
List<EntityResult> hitEntities = new ArrayList<>();
|
List<EntityResult> hitEntities = new ArrayList<>();
|
||||||
|
// TODO 换一个允许检测obb的方法
|
||||||
List<Entity> entities = this.level().getEntities(
|
List<Entity> entities = this.level().getEntities(
|
||||||
this,
|
this,
|
||||||
this.getBoundingBox()
|
this.getBoundingBox()
|
||||||
|
@ -179,6 +181,14 @@ public class ProjectileEntity extends Projectile implements IEntityWithComplexSp
|
||||||
@Nullable
|
@Nullable
|
||||||
private EntityResult getHitResult(Entity entity, Vec3 startVec, Vec3 endVec) {
|
private EntityResult getHitResult(Entity entity, Vec3 startVec, Vec3 endVec) {
|
||||||
double expandHeight = entity instanceof Player && !entity.isCrouching() ? 0.0625 : 0.0;
|
double expandHeight = entity instanceof Player && !entity.isCrouching() ? 0.0625 : 0.0;
|
||||||
|
|
||||||
|
Vec3 hitPos;
|
||||||
|
if (entity instanceof OBBEntity obbEntity) {
|
||||||
|
OBB obb = obbEntity.getOBB();
|
||||||
|
var obbVec = obb.clip(startVec.toVector3f(), endVec.toVector3f()).orElse(null);
|
||||||
|
if (obbVec == null) return null;
|
||||||
|
hitPos = new Vec3(obbVec);
|
||||||
|
} else {
|
||||||
AABB boundingBox = entity.getBoundingBox();
|
AABB boundingBox = entity.getBoundingBox();
|
||||||
Vec3 velocity = new Vec3(entity.getX() - entity.xOld, entity.getY() - entity.yOld, entity.getZ() - entity.zOld);
|
Vec3 velocity = new Vec3(entity.getX() - entity.xOld, entity.getY() - entity.yOld, entity.getZ() - entity.zOld);
|
||||||
|
|
||||||
|
@ -188,7 +198,6 @@ public class ProjectileEntity extends Projectile implements IEntityWithComplexSp
|
||||||
velocity = HitboxHelper.getVelocity(player, ping);
|
velocity = HitboxHelper.getVelocity(player, ping);
|
||||||
}
|
}
|
||||||
boundingBox = boundingBox.expandTowards(0, expandHeight, 0);
|
boundingBox = boundingBox.expandTowards(0, expandHeight, 0);
|
||||||
|
|
||||||
boundingBox = boundingBox.expandTowards(velocity.x, velocity.y, velocity.z);
|
boundingBox = boundingBox.expandTowards(velocity.x, velocity.y, velocity.z);
|
||||||
|
|
||||||
double playerHitboxOffset = 3;
|
double playerHitboxOffset = 3;
|
||||||
|
@ -208,7 +217,8 @@ public class ProjectileEntity extends Projectile implements IEntityWithComplexSp
|
||||||
boundingBox = boundingBox.inflate(3);
|
boundingBox = boundingBox.inflate(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec3 hitPos = boundingBox.clip(startVec, endVec).orElse(null);
|
hitPos = boundingBox.clip(startVec, endVec).orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
if (hitPos == null) {
|
if (hitPos == null) {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -20,7 +20,7 @@ public class EntityRenderDispatcherMixin {
|
||||||
at = @At("RETURN"))
|
at = @At("RETURN"))
|
||||||
private static void renderHitbox(PoseStack poseStack, VertexConsumer buffer, Entity p_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 (p_entity instanceof OBBEntity obbEntity && p_entity instanceof VehicleEntity vehicle) {
|
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());
|
OBBRenderer.INSTANCE.render(vehicle, obbEntity.getOBB(), poseStack, buffer, 0, 1, 0, 1, Minecraft.getInstance().getTimer().getRealtimeDeltaTicks());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,8 @@ import org.joml.Math;
|
||||||
import org.joml.Quaternionf;
|
import org.joml.Quaternionf;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Codes based on @AnECanSaiTin's <a href="https://github.com/AnECanSaiTin/HitboxAPI">HitboxAPI</a>
|
* Codes based on @AnECanSaiTin's <a href="https://github.com/AnECanSaiTin/HitboxAPI">HitboxAPI</a>
|
||||||
*
|
*
|
||||||
|
@ -130,4 +132,85 @@ public record OBB(Vector3f center, Vector3f extents, Quaternionf rotation) {
|
||||||
|
|
||||||
return nearP;
|
return nearP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Optional<Vector3f> clip(Vector3f pFrom, Vector3f pTo) {
|
||||||
|
// 计算OBB的局部坐标系基向量(世界坐标系中的方向)
|
||||||
|
Vector3f[] axes = new Vector3f[3];
|
||||||
|
axes[0] = rotation.transform(new Vector3f(1, 0, 0));
|
||||||
|
axes[1] = rotation.transform(new Vector3f(0, 1, 0));
|
||||||
|
axes[2] = rotation.transform(new Vector3f(0, 0, 1));
|
||||||
|
|
||||||
|
// 将点转换到OBB局部坐标系
|
||||||
|
Vector3f localFrom = worldToLocal(pFrom, axes);
|
||||||
|
Vector3f localTo = worldToLocal(pTo, axes);
|
||||||
|
|
||||||
|
// 射线方向(局部坐标系)
|
||||||
|
Vector3f dir = new Vector3f(localTo).sub(localFrom);
|
||||||
|
|
||||||
|
// Slab算法参数
|
||||||
|
double tEnter = 0.0; // 进入时间
|
||||||
|
double tExit = 1.0; // 离开时间
|
||||||
|
|
||||||
|
// 在三个轴上执行Slab算法
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
double min = -extents.get(i);
|
||||||
|
double max = extents.get(i);
|
||||||
|
double origin = localFrom.get(i);
|
||||||
|
double direction = dir.get(i);
|
||||||
|
|
||||||
|
// 处理射线平行于轴的情况
|
||||||
|
if (Math.abs(direction) < 1e-7f) {
|
||||||
|
if (origin < min || origin > max) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算与两个平面的交点参数
|
||||||
|
double t1 = (min - origin) / direction;
|
||||||
|
double t2 = (max - origin) / direction;
|
||||||
|
|
||||||
|
// 确保tNear是近平面,tFar是远平面
|
||||||
|
double tNear = Math.min(t1, t2);
|
||||||
|
double tFar = Math.max(t1, t2);
|
||||||
|
|
||||||
|
// 更新进入/离开时间
|
||||||
|
if (tNear > tEnter) tEnter = tNear;
|
||||||
|
if (tFar < tExit) tExit = tFar;
|
||||||
|
|
||||||
|
// 检查是否提前退出(无交点)
|
||||||
|
if (tEnter > tExit) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否有有效交点
|
||||||
|
if (tEnter >= 0 && tEnter <= 1) {
|
||||||
|
// 计算局部坐标系中的交点
|
||||||
|
Vector3f localHit = new Vector3f(dir).mul((float) tEnter).add(localFrom);
|
||||||
|
// 转换回世界坐标系
|
||||||
|
return Optional.of(localToWorld(localHit, axes));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 世界坐标转局部坐标
|
||||||
|
private Vector3f worldToLocal(Vector3f worldPoint, Vector3f[] axes) {
|
||||||
|
Vector3f rel = new Vector3f(worldPoint).sub(center);
|
||||||
|
return new Vector3f(
|
||||||
|
rel.dot(axes[0]),
|
||||||
|
rel.dot(axes[1]),
|
||||||
|
rel.dot(axes[2])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 局部坐标转世界坐标
|
||||||
|
private Vector3f localToWorld(Vector3f localPoint, Vector3f[] axes) {
|
||||||
|
Vector3f result = new Vector3f(center);
|
||||||
|
result.add(axes[0].mul(localPoint.x, new Vector3f()));
|
||||||
|
result.add(axes[1].mul(localPoint.y, new Vector3f()));
|
||||||
|
result.add(axes[2].mul(localPoint.z, new Vector3f()));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue