继续魔改OBB判定

This commit is contained in:
17146 2025-06-21 20:03:52 +08:00 committed by Light_Quanta
parent 7736a780a8
commit 40dad236dd
No known key found for this signature in database
GPG key ID: 11A39A1B8C890959
3 changed files with 20 additions and 19 deletions

View file

@ -4,6 +4,7 @@ import com.atsuishio.superbwarfare.entity.OBBEntity;
import com.atsuishio.superbwarfare.entity.mixin.OBBHitter;
import com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntity;
import com.atsuishio.superbwarfare.tools.OBB;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
@ -34,12 +35,6 @@ public abstract class EntityMixin implements OBBHitter {
@Shadow
public abstract AABB getBoundingBox();
@Shadow
public abstract Vec3 position();
@Shadow
public abstract Vec3 getEyePosition();
@Inject(method = "collide", at = @At("HEAD"))
private void sbw$spoofGroundStart(Vec3 movement, CallbackInfoReturnable<Vec3> cir) {
if (MobileVehicleEntity.IGNORE_ENTITY_GROUND_CHECK_STEPPING) {
@ -74,19 +69,23 @@ public abstract class EntityMixin implements OBBHitter {
private void onHitOBB(Vec3 movement, CallbackInfoReturnable<Vec3> cir) {
AABB boundingBox = this.getBoundingBox();
Entity self = (Entity) (Object) this;
if (self instanceof Player player) {
boundingBox = player.getLocalBoundsForPose(player.getPose());
}
var list = this.level().getEntities(self, boundingBox.expandTowards(movement));
var entity = list.stream().filter(e -> e instanceof OBBEntity).findFirst().orElse(null);
var list = this.level().getEntities(self, boundingBox.expandTowards(movement).inflate(1), e -> true);
var entity = list.stream().filter(e -> e instanceof OBBEntity).min((e1, e2) -> (int) (e1.position().distanceTo(self.position()) - e2.position().distanceTo(self.position()))).orElse(null);
if (entity == null || entity == self) return;
OBBEntity obbEntity = (OBBEntity) entity;
Vec3 feetPos = this.position().subtract(this.getEyePosition());
Vec3 position = self.position();
// 第一版实现
var faceInfo = OBB.findClosestFace(obbEntity.getOBBs(), feetPos);
var faceInfo = OBB.findClosestFace(obbEntity.getOBBs(), position);
if (faceInfo == null) return;
double dot = movement.dot(new Vec3(faceInfo.faceNormal()));
var vec = new Vec3(faceInfo.faceNormal()).multiply(dot, dot, dot);
if (self instanceof Player player) {
player.displayClientMessage(Component.literal("Vec: [" + vec.x + ", " + vec.y + ", " + vec.z + "]," +
" Face: [" + faceInfo.faceNormal().x + ", " + faceInfo.faceNormal().y + ", " + faceInfo.faceNormal().z + "]"), true);
}
cir.setReturnValue(movement.subtract(vec));
}

View file

@ -29,14 +29,16 @@ public abstract class LevelMixin {
// TODO 研究OBB碰撞的时候把这个删了
if (!(pEntity instanceof Projectile)) return;
StreamSupport.stream(this.getEntities().getAll().spliterator(), false).filter(e -> e instanceof OBBEntity && pPredicate.test(e))
StreamSupport.stream(this.getEntities().getAll().spliterator(), false).filter(e -> pPredicate.test(e) && e != pEntity)
.forEach(entity -> {
for (OBB obb : ((OBBEntity) entity).getOBBs()) {
if (entity instanceof OBBEntity obbEntity) {
for (OBB obb : obbEntity.getOBBs()) {
if (OBB.isColliding(obb, pBoundingBox) && !cir.getReturnValue().contains(entity)) {
cir.getReturnValue().add(entity);
}
}
}
}
);
}
}

View file

@ -397,7 +397,7 @@ public record OBB(Vector3f center, Vector3f extents, Quaternionf rotation, Part
return null;
}
Vector3f pos = new Vector3f((float) playerPos.x, (float) playerPos.y, (float) playerPos.z);
Vector3f pos = playerPos.toVector3f();
OBB closestOBB = null;
int closestFaceIndex = -1;
float minDistance = Float.MAX_VALUE;
@ -410,7 +410,7 @@ public record OBB(Vector3f center, Vector3f extents, Quaternionf rotation, Part
float distToCenter = pos.distance(obb.center());
// 如果距离大于包围球半径不可能比当前最小值更近
if (distToCenter - obb.getBoundingSphereRadius() > minDistance) {
if (distToCenter > obb.getBoundingSphereRadius()) {
continue;
}