添加63式火箭炮的OBB

This commit is contained in:
Atsuishio 2025-07-13 02:25:48 +08:00 committed by Light_Quanta
parent aa0e839c7c
commit 29f810eb04
No known key found for this signature in database
GPG key ID: 11A39A1B8C890959
5 changed files with 276 additions and 11 deletions

View file

@ -54,6 +54,23 @@ public class Type63Renderer extends GeoEntityRenderer<Type63Entity> {
if (name.equals("wheel2")) {
bone.setRotX(Mth.lerp(partialTick, animatable.rightWheelRotO, animatable.getRightWheelRot()));
}
if (name.equals("main")) {
bone.setRotY(Mth.lerp(partialTick, animatable.turretYRotO, animatable.getTurretYRot()) * Mth.DEG_TO_RAD);
}
if (name.equals("paotou")) {
bone.setRotX(-Mth.lerp(partialTick, animatable.turretXRotO, animatable.getTurretXRot()) * Mth.DEG_TO_RAD);
}
if (name.equals("shoulunx")) {
bone.setRotX(-Mth.lerp(partialTick, animatable.turretXRotO, animatable.getTurretXRot()) * 3);
}
if (name.equals("shouluny")) {
bone.setRotZ(-Mth.lerp(partialTick, animatable.turretYRotO, animatable.getTurretYRot()) * 6);
}
super.renderRecursively(poseStack, animatable, bone, renderType, bufferSource, buffer, isReRender, partialTick, packedLight, packedOverlay, color);
}
}

View file

@ -9,20 +9,29 @@ import com.atsuishio.superbwarfare.item.SmallShellItem;
import com.atsuishio.superbwarfare.tools.CustomExplosion;
import com.atsuishio.superbwarfare.tools.OBB;
import com.atsuishio.superbwarfare.tools.ParticleTool;
import com.atsuishio.superbwarfare.tools.VectorTool;
import com.mojang.math.Axis;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.Mth;
import net.minecraft.world.Container;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Explosion;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3;
import net.neoforged.neoforge.event.EventHooks;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.joml.*;
import org.joml.Math;
import org.joml.Matrix4f;
import software.bernie.geckolib.animatable.GeoEntity;
import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache;
import software.bernie.geckolib.animation.AnimatableManager;
@ -32,6 +41,8 @@ import java.util.List;
public class Type63Entity extends MobileVehicleEntity implements GeoEntity, OBBEntity, Container {
public static final EntityDataAccessor<Float> PITCH = SynchedEntityData.defineId(Type63Entity.class, EntityDataSerializers.FLOAT);
public static final EntityDataAccessor<Float> YAW = SynchedEntityData.defineId(Type63Entity.class, EntityDataSerializers.FLOAT);
private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this);
public OBB barrel0;
public OBB barrel1;
@ -50,17 +61,94 @@ public class Type63Entity extends MobileVehicleEntity implements GeoEntity, OBBE
public OBB hoe1;
public OBB hoe2;
public double interactionTick;
public ItemStack stack = ItemStack.EMPTY;
public Type63Entity(EntityType<Type63Entity> type, Level world) {
super(type, world);
this.barrel0 = new OBB(this.position().toVector3f(), new Vector3f(0.09375f, 0.09375f, 0.0625f), new Quaternionf(), OBB.Part.BODY);
this.barrel1 = new OBB(this.position().toVector3f(), new Vector3f(0.09375f, 0.09375f, 0.0625f), new Quaternionf(), OBB.Part.BODY);
this.barrel2 = new OBB(this.position().toVector3f(), new Vector3f(0.09375f, 0.09375f, 0.0625f), new Quaternionf(), OBB.Part.BODY);
this.barrel3 = new OBB(this.position().toVector3f(), new Vector3f(0.09375f, 0.09375f, 0.0625f), new Quaternionf(), OBB.Part.BODY);
this.barrel4 = new OBB(this.position().toVector3f(), new Vector3f(0.09375f, 0.09375f, 0.0625f), new Quaternionf(), OBB.Part.BODY);
this.barrel5 = new OBB(this.position().toVector3f(), new Vector3f(0.09375f, 0.09375f, 0.0625f), new Quaternionf(), OBB.Part.BODY);
this.barrel6 = new OBB(this.position().toVector3f(), new Vector3f(0.09375f, 0.09375f, 0.0625f), new Quaternionf(), OBB.Part.BODY);
this.barrel7 = new OBB(this.position().toVector3f(), new Vector3f(0.09375f, 0.09375f, 0.0625f), new Quaternionf(), OBB.Part.BODY);
this.barrel8 = new OBB(this.position().toVector3f(), new Vector3f(0.09375f, 0.09375f, 0.0625f), new Quaternionf(), OBB.Part.BODY);
this.barrel9 = new OBB(this.position().toVector3f(), new Vector3f(0.09375f, 0.09375f, 0.0625f), new Quaternionf(), OBB.Part.BODY);
this.barrel10 = new OBB(this.position().toVector3f(), new Vector3f(0.09375f, 0.09375f, 0.0625f), new Quaternionf(), OBB.Part.BODY);
this.barrel11 = new OBB(this.position().toVector3f(), new Vector3f(0.09375f, 0.09375f, 0.0625f), new Quaternionf(), OBB.Part.BODY);
this.pitchController = new OBB(this.position().toVector3f(), new Vector3f(0.15625f, 0.21875f, 0.21875f), new Quaternionf(), OBB.Part.BODY);
this.yawController = new OBB(this.position().toVector3f(), new Vector3f(0.125f, 0.125f, 0.125f), new Quaternionf(), OBB.Part.BODY);
this.hoe1 = new OBB(this.position().toVector3f(), new Vector3f(0.125f, 0.125f, 0.875f), new Quaternionf(), OBB.Part.BODY);
this.hoe2 = new OBB(this.position().toVector3f(), new Vector3f(0.125f, 0.125f, 0.875f), new Quaternionf(), OBB.Part.BODY);
}
@Override
protected void defineSynchedData(SynchedEntityData.Builder builder) {
super.defineSynchedData(builder);
builder.define(PITCH, 0F)
.define(YAW, 0F);
}
@Override
public void addAdditionalSaveData(CompoundTag compound) {
super.addAdditionalSaveData(compound);
compound.putFloat("Pitch", this.entityData.get(PITCH));
compound.putFloat("Yaw", this.entityData.get(YAW));
}
@Override
protected void readAdditionalSaveData(CompoundTag compound) {
super.readAdditionalSaveData(compound);
this.entityData.set(PITCH, compound.getFloat("Pitch"));
this.entityData.set(YAW, compound.getFloat("Yaw"));
}
@Override
public @NotNull InteractionResult interact(Player player, @NotNull InteractionHand hand) {
ItemStack stack = player.getMainHandItem();
if (stack.isEmpty()) {
if (OBB.getLookingObb(player, player.entityInteractionRange()) == hoe1) {
if (player.level() instanceof ServerLevel) {
setYRot(getYRot() + (float) interactionTick);
interactionTick++;
}
player.swing(InteractionHand.MAIN_HAND);
}
if (OBB.getLookingObb(player, player.entityInteractionRange()) == hoe2) {
if (player.level() instanceof ServerLevel) {
setYRot(getYRot() - (float) interactionTick);
interactionTick++;
}
player.swing(InteractionHand.MAIN_HAND);
}
if (OBB.getLookingObb(player, player.entityInteractionRange()) == yawController) {
if (player.level() instanceof ServerLevel) {
interactionTick++;
}
entityData.set(YAW, Mth.clamp(entityData.get(YAW) + (player.isShiftKeyDown() ? -0.07f : 0.07f) * (float) interactionTick, -15, 15));
player.swing(InteractionHand.MAIN_HAND);
}
if (OBB.getLookingObb(player, player.entityInteractionRange()) == pitchController) {
if (player.level() instanceof ServerLevel) {
interactionTick++;
}
entityData.set(PITCH, Mth.clamp(entityData.get(PITCH) + (player.isShiftKeyDown() ? 0.15f : -0.15f) * (float) interactionTick, -60, 5));
player.swing(InteractionHand.MAIN_HAND);
}
}
return InteractionResult.FAIL;
}
@Override
public void baseTick() {
turretYRotO = this.getTurretYRot();
turretXRotO = this.getTurretXRot();
rudderRotO = this.getRudderRot();
leftWheelRotO = this.getLeftWheelRot();
rightWheelRotO = this.getRightWheelRot();
@ -83,6 +171,12 @@ public class Type63Entity extends MobileVehicleEntity implements GeoEntity, OBBE
this.setDeltaMovement(this.getDeltaMovement().add(this.getViewVector(1).normalize().scale(0.04 * getDeltaMovement().dot(getViewVector(1)))));
this.setDeltaMovement(this.getDeltaMovement().multiply(f1, 0.85, f1));
}
// setTurretYRot(getTurretYRot() + 1);
// setTurretXRot(getTurretXRot() + 1);
interactionTick *= 0.9;
this.refreshDimensions();
}
@ -104,12 +198,48 @@ public class Type63Entity extends MobileVehicleEntity implements GeoEntity, OBBE
@Override
public void travel() {
float diffY = 0;
float diffY = entityData.get(YAW) - getTurretYRot();
this.setTurretYRot(Mth.clamp(this.getTurretYRot() + 0.25f * diffY, -15, 15));
float diffX = entityData.get(PITCH) - getTurretXRot();
this.setTurretXRot(Mth.clamp(this.getTurretXRot() + 0.25f * diffX, -60, 5));
double s0 = getDeltaMovement().dot(this.getViewVector(1));
this.setLeftWheelRot((float) (this.getLeftWheelRot() - 1.75 * s0) - 0.015f * Mth.clamp(0.4f * diffY, -5f, 5f));
this.setRightWheelRot((float) (this.getRightWheelRot() - 1.75 * s0) + 0.015f * Mth.clamp(0.4f * diffY, -5f, 5f));
this.setLeftWheelRot((float) (this.getLeftWheelRot() - 1.75 * s0));
this.setRightWheelRot((float) (this.getRightWheelRot() - 1.75 * s0));
}
public Vec3 getTurretVector(float pPartialTicks) {
Matrix4f transform = getTurretTransform(pPartialTicks);
Vector4f rootPosition = transformPosition(transform, 0, 0, 0);
Vector4f targetPosition = transformPosition(transform, 0, 0, 1);
return new Vec3(rootPosition.x, rootPosition.y, rootPosition.z).vectorTo(new Vec3(targetPosition.x, targetPosition.y, targetPosition.z));
}
@Override
public Matrix4f getTurretTransform(float ticks) {
Matrix4f transformV = getVehicleTransform(ticks);
Matrix4f transform = new Matrix4f();
Vector4f worldPosition = transformPosition(transform, 0, 0.45703125f, -0.1625f);
transformV.translate(worldPosition.x, worldPosition.y, worldPosition.z);
transformV.rotate(Axis.YP.rotationDegrees(Mth.lerp(ticks, turretYRotO, getTurretYRot())));
return transformV;
}
public Matrix4f getBarrelTransform(float ticks) {
Matrix4f transformT = getTurretTransform(ticks);
Matrix4f transform = new Matrix4f();
Vector4f worldPosition = transformPosition(transform, 0, 0.65f, -0.203125f);
transformT.translate(worldPosition.x, worldPosition.y, worldPosition.z);
float x = Mth.lerp(ticks, turretXRotO, getTurretXRot());
transformT.rotate(Axis.XP.rotationDegrees(x));
return transformT;
}
@Override
@ -197,12 +327,86 @@ public class Type63Entity extends MobileVehicleEntity implements GeoEntity, OBBE
@Override
public List<OBB> getOBBs() {
return List.of();
return List.of(this.barrel0, this.barrel1, this.barrel2, this.barrel3, this.barrel4, this.barrel5, this.barrel6, this.barrel7, this.barrel8, this.barrel9, this.barrel10, this.barrel11,
this.hoe1, this.hoe2, this.yawController, this.pitchController);
}
@Override
public void updateOBB() {
Matrix4f transform = getVehicleTransform(1);
// 驻锄位置
Vector4f worldPosition = transformPosition(transform, 0.875f, 0.1875f, -1.625f);
this.hoe1.center().set(new Vector3f(worldPosition.x, worldPosition.y, worldPosition.z));
this.hoe1.setRotation(VectorTool.combineRotations(1, this));
Vector4f worldPosition2 = transformPosition(transform, -0.875f, 0.1875f, -1.625f);
this.hoe2.center().set(new Vector3f(worldPosition2.x, worldPosition2.y, worldPosition2.z));
this.hoe2.setRotation(VectorTool.combineRotations(1, this));
Matrix4f transformT = getTurretTransform(1);
Vector4f worldPositionYaw = transformPosition(transformT, 0.62625f, 0.0396875f, -0.5f);
this.yawController.center().set(new Vector3f(worldPositionYaw.x, worldPositionYaw.y, worldPositionYaw.z));
this.yawController.setRotation(VectorTool.combineRotationsTurret(1, this));
Vector4f worldPositionPitch = transformPosition(transformT, 0.7825f, 0.5771875f, -0.024375f);
this.pitchController.center().set(new Vector3f(worldPositionPitch.x, worldPositionPitch.y, worldPositionPitch.z));
this.pitchController.setRotation(VectorTool.combineRotationsTurret(1, this));
Matrix4f transformB = getBarrelTransform(1);
float i = 0.24375f;
Vector4f worldPositionBarrel0 = transformPosition(transformB, -0.3659375f, 0.244375f, -0.44625f);
this.barrel0.center().set(new Vector3f(worldPositionBarrel0.x, worldPositionBarrel0.y, worldPositionBarrel0.z));
this.barrel0.setRotation(VectorTool.combineRotationsBarrel(1, this));
Vector4f worldPositionBarrel1 = transformPosition(transformB, -0.3659375f + i, 0.244375f, -0.44625f);
this.barrel1.center().set(new Vector3f(worldPositionBarrel1.x, worldPositionBarrel1.y, worldPositionBarrel1.z));
this.barrel1.setRotation(VectorTool.combineRotationsBarrel(1, this));
Vector4f worldPositionBarrel2 = transformPosition(transformB, -0.3659375f + 2 * i, 0.244375f, -0.44625f);
this.barrel2.center().set(new Vector3f(worldPositionBarrel2.x, worldPositionBarrel2.y, worldPositionBarrel2.z));
this.barrel2.setRotation(VectorTool.combineRotationsBarrel(1, this));
Vector4f worldPositionBarrel3 = transformPosition(transformB, -0.3659375f + 3 * i, 0.244375f, -0.44625f);
this.barrel3.center().set(new Vector3f(worldPositionBarrel3.x, worldPositionBarrel3.y, worldPositionBarrel3.z));
this.barrel3.setRotation(VectorTool.combineRotationsBarrel(1, this));
Vector4f worldPositionBarrel4 = transformPosition(transformB, -0.3659375f, 0.244375f - i, -0.44625f);
this.barrel4.center().set(new Vector3f(worldPositionBarrel4.x, worldPositionBarrel4.y, worldPositionBarrel4.z));
this.barrel4.setRotation(VectorTool.combineRotationsBarrel(1, this));
Vector4f worldPositionBarrel5 = transformPosition(transformB, -0.3659375f + i, 0.244375f - i, -0.44625f);
this.barrel5.center().set(new Vector3f(worldPositionBarrel5.x, worldPositionBarrel5.y, worldPositionBarrel5.z));
this.barrel5.setRotation(VectorTool.combineRotationsBarrel(1, this));
Vector4f worldPositionBarrel6 = transformPosition(transformB, -0.3659375f + 2 * i, 0.244375f - i, -0.44625f);
this.barrel6.center().set(new Vector3f(worldPositionBarrel6.x, worldPositionBarrel6.y, worldPositionBarrel6.z));
this.barrel6.setRotation(VectorTool.combineRotationsBarrel(1, this));
Vector4f worldPositionBarrel7 = transformPosition(transformB, -0.3659375f + 3 * i, 0.244375f - i, -0.44625f);
this.barrel7.center().set(new Vector3f(worldPositionBarrel7.x, worldPositionBarrel7.y, worldPositionBarrel7.z));
this.barrel7.setRotation(VectorTool.combineRotationsBarrel(1, this));
Vector4f worldPositionBarrel8 = transformPosition(transformB, -0.3659375f, 0.244375f - 2 * i, -0.44625f);
this.barrel8.center().set(new Vector3f(worldPositionBarrel8.x, worldPositionBarrel8.y, worldPositionBarrel8.z));
this.barrel8.setRotation(VectorTool.combineRotationsBarrel(1, this));
Vector4f worldPositionBarrel9 = transformPosition(transformB, -0.3659375f + i, 0.244375f - 2 * i, -0.44625f);
this.barrel9.center().set(new Vector3f(worldPositionBarrel9.x, worldPositionBarrel9.y, worldPositionBarrel9.z));
this.barrel9.setRotation(VectorTool.combineRotationsBarrel(1, this));
Vector4f worldPositionBarrel10 = transformPosition(transformB, -0.3659375f + 2 * i, 0.244375f - 2 * i, -0.44625f);
this.barrel10.center().set(new Vector3f(worldPositionBarrel10.x, worldPositionBarrel10.y, worldPositionBarrel10.z));
this.barrel10.setRotation(VectorTool.combineRotationsBarrel(1, this));
Vector4f worldPositionBarrel11 = transformPosition(transformB, -0.3659375f + 3 * i, 0.244375f - 2 * i, -0.44625f);
this.barrel11.center().set(new Vector3f(worldPositionBarrel11.x, worldPositionBarrel11.y, worldPositionBarrel11.z));
this.barrel11.setRotation(VectorTool.combineRotationsBarrel(1, this));
}
@Override

View file

@ -179,12 +179,24 @@ public class ClientEventHandler {
return;
}
float xRotOffset = Mth.lerp(event.getPartialTick(), player.xBobO, player.xBob);
float yRotOffset = Mth.lerp(event.getPartialTick(), player.yBobO, player.yBob);
float xRot = player.getViewXRot(event.getPartialTick()) - xRotOffset;
float yRot = player.getViewYRot(event.getPartialTick()) - yRotOffset;
turnRot[0] = Mth.clamp(0.05 * xRot, -5, 5) * (1 - 0.75 * zoomTime);
turnRot[1] = Mth.clamp(0.05 * yRot, -10, 10) * (1 - 0.75 * zoomTime);
turnRot[2] = Mth.clamp(0.1 * yRot, -10, 10) * (1 - zoomTime);
var fromY = player.yRotO;
var toY = player.getYRot();
if (fromY > 135 && toY < -135) {
toY += 360;
}
if (fromY < -135 && toY > 135) {
fromY += 360;
}
float yRotOffset = Mth.lerp(event.getPartialTick(), 0, toY - fromY);
// float yRot = Mth.wrapDegrees(player.getYRot() + yRotOffset);
turnRot[0] = Mth.clamp(0.05 * yRotOffset, -5, 5) * (1 - 0.75 * zoomTime);
turnRot[1] = Mth.clamp(0.05 * yRotOffset, -10, 10) * (1 - 0.75 * zoomTime);
turnRot[2] = Mth.clamp(0.1 * yRotOffset, -10, 10) * (1 - zoomTime);
}
private static boolean notInGame() {

View file

@ -1,5 +1,8 @@
package com.atsuishio.superbwarfare.tools;
import com.atsuishio.superbwarfare.entity.OBBEntity;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.Nullable;
@ -438,6 +441,27 @@ public record OBB(Vector3f center, Vector3f extents, Quaternionf rotation, Part
public record ClosestFaceResult(OBB obb, int faceIndex, float distance, Vector3f faceCenter, Vector3f faceNormal) {
}
//获取玩家看向的某个OBB
// TODO 修复看向的第一个OBB后方如果还有另外的OBB时无法正确返回看向的第一个OBB的BUG
public static OBB getLookingObb(Player player, double range) {
OBB lookingOBB = null;
Entity lookingEntity = TraceTool.findLookingEntity(player, range);
if (lookingEntity instanceof OBBEntity obbEntity) {
var obbList = obbEntity.getOBBs();
for (OBB obb : obbList) {
Vec3 hitPos = TraceTool.playerFindLookingPos(player, lookingEntity, range);
if (hitPos != null && obb.contains(hitPos.add(player.getViewVector(1).scale(0.02)))) {
// player.displayClientMessage(Component.literal(String.valueOf(obb)), true);
lookingOBB = obb;
break;
}
}
}
return lookingOBB;
}
public enum Part {
EMPTY,
WHEEL_LEFT,

View file

@ -56,6 +56,14 @@ public class VectorTool {
return combined;
}
public static Quaternionf combineRotationsBarrel(float partialTicks, VehicleEntity entity) {
Quaternionf turretPitchRot = Axis.XP.rotationDegrees(Mth.lerp(partialTicks, entity.turretXRotO, entity.getTurretXRot()));
Quaternionf combined = combineRotationsTurret(partialTicks, entity);
combined.mul(turretPitchRot);
return combined;
}
public static Vec3 randomPos(Vec3 originPos, int radius) {
return originPos.add(new Vec3(Math.random() * radius, 0, 0).yRot((float) (360 * Math.random()) * Mth.DEG_TO_RAD));
}