mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-29 08:27:03 +01:00
More collision polish
This commit is contained in:
parent
f6053da7de
commit
ddf28cfcea
7 changed files with 158 additions and 57 deletions
|
@ -1,10 +1,13 @@
|
||||||
package com.simibubi.create.content.contraptions.components.structureMovement;
|
package com.simibubi.create.content.contraptions.components.structureMovement;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.IdentityHashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.mutable.MutableInt;
|
||||||
import org.apache.commons.lang3.tuple.MutablePair;
|
import org.apache.commons.lang3.tuple.MutablePair;
|
||||||
|
|
||||||
import com.simibubi.create.AllMovementBehaviours;
|
import com.simibubi.create.AllMovementBehaviours;
|
||||||
|
@ -49,7 +52,7 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
|
||||||
private static final DataParameter<Boolean> STALLED =
|
private static final DataParameter<Boolean> STALLED =
|
||||||
EntityDataManager.createKey(AbstractContraptionEntity.class, DataSerializers.BOOLEAN);
|
EntityDataManager.createKey(AbstractContraptionEntity.class, DataSerializers.BOOLEAN);
|
||||||
|
|
||||||
public final List<Entity> collidingEntities = new ArrayList<>();
|
public final Map<Entity, MutableInt> collidingEntities;
|
||||||
|
|
||||||
protected Contraption contraption;
|
protected Contraption contraption;
|
||||||
protected boolean initialized;
|
protected boolean initialized;
|
||||||
|
@ -58,6 +61,7 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
|
||||||
public AbstractContraptionEntity(EntityType<?> entityTypeIn, World worldIn) {
|
public AbstractContraptionEntity(EntityType<?> entityTypeIn, World worldIn) {
|
||||||
super(entityTypeIn, worldIn);
|
super(entityTypeIn, worldIn);
|
||||||
prevPosInvalid = true;
|
prevPosInvalid = true;
|
||||||
|
collidingEntities = new IdentityHashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setContraption(Contraption contraption) {
|
protected void setContraption(Contraption contraption) {
|
||||||
|
@ -205,6 +209,13 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (Iterator<Entry<Entity, MutableInt>> iterator = collidingEntities.entrySet()
|
||||||
|
.iterator(); iterator.hasNext();)
|
||||||
|
if (iterator.next()
|
||||||
|
.getValue()
|
||||||
|
.incrementAndGet() > 3)
|
||||||
|
iterator.remove();
|
||||||
|
|
||||||
prevPosX = getX();
|
prevPosX = getX();
|
||||||
prevPosY = getY();
|
prevPosY = getY();
|
||||||
prevPosZ = getZ();
|
prevPosZ = getZ();
|
||||||
|
@ -378,8 +389,13 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
|
||||||
return;
|
return;
|
||||||
if (contraption == null)
|
if (contraption == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
remove();
|
remove();
|
||||||
|
|
||||||
StructureTransform transform = makeStructureTransform();
|
StructureTransform transform = makeStructureTransform();
|
||||||
|
AllPackets.channel.send(PacketDistributor.TRACKING_ENTITY.with(() -> this),
|
||||||
|
new ContraptionDisassemblyPacket(this.getEntityId(), transform));
|
||||||
|
|
||||||
contraption.addBlocksToWorld(world, transform);
|
contraption.addBlocksToWorld(world, transform);
|
||||||
contraption.addPassengersToWorld(world, transform, getPassengers());
|
contraption.addPassengersToWorld(world, transform, getPassengers());
|
||||||
|
|
||||||
|
@ -396,14 +412,17 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
|
||||||
}
|
}
|
||||||
|
|
||||||
removePassengers();
|
removePassengers();
|
||||||
|
moveCollidedEntitiesOnDisassembly(transform);
|
||||||
|
}
|
||||||
|
|
||||||
for (Entity entity : collidingEntities) {
|
private void moveCollidedEntitiesOnDisassembly(StructureTransform transform) {
|
||||||
Vec3d positionVec = getPositionVec();
|
for (Entity entity : collidingEntities.keySet()) {
|
||||||
Vec3d localVec = entity.getPositionVec()
|
Vec3d localVec = toLocalVector(entity.getPositionVec(), 0);
|
||||||
.subtract(positionVec);
|
|
||||||
localVec = reverseRotation(localVec, 1);
|
|
||||||
Vec3d transformed = transform.apply(localVec);
|
Vec3d transformed = transform.apply(localVec);
|
||||||
entity.setPositionAndUpdate(transformed.x, transformed.y, transformed.z);
|
if (world.isRemote)
|
||||||
|
entity.setPosition(transformed.x, transformed.y + 1 / 16f, transformed.z);
|
||||||
|
else
|
||||||
|
entity.setPositionAndUpdate(transformed.x, transformed.y + 1 / 16f, transformed.z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -449,6 +468,15 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
|
||||||
ce.handleStallInformation(packet.x, packet.y, packet.z, packet.angle);
|
ce.handleStallInformation(packet.x, packet.y, packet.z, packet.angle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
static void handleDisassemblyPacket(ContraptionDisassemblyPacket packet) {
|
||||||
|
Entity entity = Minecraft.getInstance().world.getEntityByID(packet.entityID);
|
||||||
|
if (!(entity instanceof AbstractContraptionEntity))
|
||||||
|
return;
|
||||||
|
AbstractContraptionEntity ce = (AbstractContraptionEntity) entity;
|
||||||
|
ce.moveCollidedEntitiesOnDisassembly(packet.transform);
|
||||||
|
}
|
||||||
|
|
||||||
protected abstract float getStalledAngle();
|
protected abstract float getStalledAngle();
|
||||||
|
|
||||||
protected abstract void handleStallInformation(float x, float y, float z, float angle);
|
protected abstract void handleStallInformation(float x, float y, float z, float angle);
|
||||||
|
|
|
@ -8,6 +8,8 @@ import java.util.List;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import org.apache.commons.lang3.mutable.MutableBoolean;
|
import org.apache.commons.lang3.mutable.MutableBoolean;
|
||||||
|
import org.apache.commons.lang3.mutable.MutableFloat;
|
||||||
|
import org.apache.commons.lang3.mutable.MutableInt;
|
||||||
import org.apache.commons.lang3.mutable.MutableObject;
|
import org.apache.commons.lang3.mutable.MutableObject;
|
||||||
|
|
||||||
import com.google.common.base.Predicates;
|
import com.google.common.base.Predicates;
|
||||||
|
@ -65,8 +67,6 @@ public class ContraptionCollider {
|
||||||
if (bounds == null)
|
if (bounds == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
contraptionEntity.collidingEntities.clear();
|
|
||||||
|
|
||||||
Vec3d contraptionPosition = contraptionEntity.getPositionVec();
|
Vec3d contraptionPosition = contraptionEntity.getPositionVec();
|
||||||
Vec3d contraptionMotion = contraptionPosition.subtract(contraptionEntity.getPrevPositionVec());
|
Vec3d contraptionMotion = contraptionPosition.subtract(contraptionEntity.getPrevPositionVec());
|
||||||
Vec3d anchorVec = contraptionEntity.getAnchorVec();
|
Vec3d anchorVec = contraptionEntity.getAnchorVec();
|
||||||
|
@ -123,13 +123,12 @@ public class ContraptionCollider {
|
||||||
// Prepare entity bounds
|
// Prepare entity bounds
|
||||||
OrientedBB obb = new OrientedBB(localBB);
|
OrientedBB obb = new OrientedBB(localBB);
|
||||||
obb.setRotation(rotationMatrix);
|
obb.setRotation(rotationMatrix);
|
||||||
motion = rotationMatrix.transform(motion);
|
|
||||||
motion = motion.subtract(contraptionMotion);
|
motion = motion.subtract(contraptionMotion);
|
||||||
|
motion = rotationMatrix.transform(motion);
|
||||||
|
|
||||||
MutableObject<Vec3d> collisionResponse = new MutableObject<>(Vec3d.ZERO);
|
MutableObject<Vec3d> collisionResponse = new MutableObject<>(Vec3d.ZERO);
|
||||||
MutableObject<Vec3d> allowedMotion = new MutableObject<>(motion);
|
|
||||||
MutableBoolean futureCollision = new MutableBoolean(false);
|
|
||||||
MutableBoolean surfaceCollision = new MutableBoolean(false);
|
MutableBoolean surfaceCollision = new MutableBoolean(false);
|
||||||
|
MutableFloat temporalResponse = new MutableFloat(1);
|
||||||
Vec3d obbCenter = obb.getCenter();
|
Vec3d obbCenter = obb.getCenter();
|
||||||
|
|
||||||
// Apply separation maths
|
// Apply separation maths
|
||||||
|
@ -140,21 +139,22 @@ public class ContraptionCollider {
|
||||||
|
|
||||||
boolean doHorizontalPass = !rotation.hasVerticalRotation();
|
boolean doHorizontalPass = !rotation.hasVerticalRotation();
|
||||||
for (boolean horizontalPass : Iterate.trueAndFalse) {
|
for (boolean horizontalPass : Iterate.trueAndFalse) {
|
||||||
|
boolean verticalPass = !horizontalPass || !doHorizontalPass;
|
||||||
|
|
||||||
for (AxisAlignedBB bb : bbs) {
|
for (AxisAlignedBB bb : bbs) {
|
||||||
Vec3d currentResponse = collisionResponse.getValue();
|
Vec3d currentResponse = collisionResponse.getValue();
|
||||||
obb.setCenter(obbCenter.add(currentResponse));
|
obb.setCenter(obbCenter.add(currentResponse));
|
||||||
ContinuousSeparationManifold intersect = obb.intersect(bb, allowedMotion.getValue());
|
ContinuousSeparationManifold intersect = obb.intersect(bb, motion);
|
||||||
|
|
||||||
if (intersect == null)
|
if (intersect == null)
|
||||||
continue;
|
continue;
|
||||||
if ((!horizontalPass || !doHorizontalPass) && surfaceCollision.isFalse())
|
if (verticalPass && surfaceCollision.isFalse())
|
||||||
surfaceCollision.setValue(intersect.isSurfaceCollision());
|
surfaceCollision.setValue(intersect.isSurfaceCollision());
|
||||||
|
|
||||||
double timeOfImpact = intersect.getTimeOfImpact();
|
double timeOfImpact = intersect.getTimeOfImpact();
|
||||||
if (timeOfImpact > 0 && timeOfImpact < 1) {
|
if (timeOfImpact > 0 && timeOfImpact < 1) {
|
||||||
futureCollision.setTrue();
|
if (temporalResponse.getValue() > timeOfImpact)
|
||||||
allowedMotion.setValue(intersect.getAllowedMotion(allowedMotion.getValue()));
|
temporalResponse.setValue(timeOfImpact);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,28 +163,28 @@ public class ContraptionCollider {
|
||||||
collisionResponse.setValue(currentResponse.add(separation));
|
collisionResponse.setValue(currentResponse.add(separation));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!horizontalPass || !doHorizontalPass)
|
if (verticalPass)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
boolean noVerticalMotionResponse = allowedMotion.getValue().y == motion.y;
|
boolean noVerticalMotionResponse = temporalResponse.getValue() == 1;
|
||||||
boolean noVerticalCollision = collisionResponse.getValue().y == 0;
|
boolean noVerticalCollision = collisionResponse.getValue().y == 0;
|
||||||
if (noVerticalCollision && noVerticalMotionResponse)
|
if (noVerticalCollision && noVerticalMotionResponse)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Re-run collisions with horizontal offset
|
// Re-run collisions with horizontal offset
|
||||||
collisionResponse.setValue(collisionResponse.getValue()
|
collisionResponse.setValue(collisionResponse.getValue()
|
||||||
.mul(1, 0, 1));
|
.mul(129 / 128f, 0, 129 / 128f));
|
||||||
allowedMotion.setValue(allowedMotion.getValue()
|
|
||||||
.mul(1, 0, 1)
|
|
||||||
.add(0, motion.y, 0));
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resolve collision
|
// Resolve collision
|
||||||
Vec3d entityMotion = entity.getMotion();
|
Vec3d entityMotion = entity.getMotion();
|
||||||
Vec3d totalResponse = collisionResponse.getValue();
|
Vec3d totalResponse = collisionResponse.getValue();
|
||||||
Vec3d motionResponse = allowedMotion.getValue();
|
|
||||||
boolean hardCollision = !totalResponse.equals(Vec3d.ZERO);
|
boolean hardCollision = !totalResponse.equals(Vec3d.ZERO);
|
||||||
|
boolean temporalCollision = temporalResponse.getValue() != 1;
|
||||||
|
Vec3d motionResponse = !temporalCollision ? motion
|
||||||
|
: motion.normalize()
|
||||||
|
.scale(motion.length() * temporalResponse.getValue());
|
||||||
|
|
||||||
rotationMatrix.transpose();
|
rotationMatrix.transpose();
|
||||||
motionResponse = rotationMatrix.transform(motionResponse)
|
motionResponse = rotationMatrix.transform(motionResponse)
|
||||||
|
@ -193,10 +193,11 @@ public class ContraptionCollider {
|
||||||
totalResponse = VecHelper.rotate(totalResponse, yawOffset, Axis.Y);
|
totalResponse = VecHelper.rotate(totalResponse, yawOffset, Axis.Y);
|
||||||
rotationMatrix.transpose();
|
rotationMatrix.transpose();
|
||||||
|
|
||||||
if (futureCollision.isTrue() && playerType != PlayerType.SERVER) {
|
if (temporalCollision && playerType != PlayerType.SERVER) {
|
||||||
if (motionResponse.y != entityMotion.y) {
|
double idealVerticalMotion = motionResponse.y;
|
||||||
|
if (idealVerticalMotion != entityMotion.y) {
|
||||||
entity.setMotion(entityMotion.mul(1, 0, 1)
|
entity.setMotion(entityMotion.mul(1, 0, 1)
|
||||||
.add(0, motionResponse.y, 0));
|
.add(0, idealVerticalMotion, 0));
|
||||||
entityMotion = entity.getMotion();
|
entityMotion = entity.getMotion();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -213,7 +214,8 @@ public class ContraptionCollider {
|
||||||
if (motionX != 0 && Math.abs(intersectX) > horizonalEpsilon && motionX > 0 == intersectX < 0)
|
if (motionX != 0 && Math.abs(intersectX) > horizonalEpsilon && motionX > 0 == intersectX < 0)
|
||||||
entityMotion = entityMotion.mul(0, 1, 1);
|
entityMotion = entityMotion.mul(0, 1, 1);
|
||||||
if (motionY != 0 && intersectY != 0 && motionY > 0 == intersectY < 0)
|
if (motionY != 0 && intersectY != 0 && motionY > 0 == intersectY < 0)
|
||||||
entityMotion = entityMotion.mul(1, 0, 1);
|
entityMotion = entityMotion.mul(1, 0, 1)
|
||||||
|
.add(0, contraptionMotion.y, 0);
|
||||||
if (motionZ != 0 && Math.abs(intersectZ) > horizonalEpsilon && motionZ > 0 == intersectZ < 0)
|
if (motionZ != 0 && Math.abs(intersectZ) > horizonalEpsilon && motionZ > 0 == intersectZ < 0)
|
||||||
entityMotion = entityMotion.mul(1, 1, 0);
|
entityMotion = entityMotion.mul(1, 1, 0);
|
||||||
}
|
}
|
||||||
|
@ -226,27 +228,25 @@ public class ContraptionCollider {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// totalResponse = totalResponse.add(contactPointMotion);
|
|
||||||
Vec3d allowedMovement = getAllowedMovement(totalResponse, entity);
|
Vec3d allowedMovement = getAllowedMovement(totalResponse, entity);
|
||||||
contraptionEntity.collidingEntities.add(entity);
|
|
||||||
entity.velocityChanged = true;
|
|
||||||
entity.setPosition(entityPosition.x + allowedMovement.x, entityPosition.y + allowedMovement.y,
|
entity.setPosition(entityPosition.x + allowedMovement.x, entityPosition.y + allowedMovement.y,
|
||||||
entityPosition.z + allowedMovement.z);
|
entityPosition.z + allowedMovement.z);
|
||||||
entityPosition = entity.getPositionVec();
|
entityPosition = entity.getPositionVec();
|
||||||
|
|
||||||
|
entity.velocityChanged = true;
|
||||||
Vec3d contactPointMotion = Vec3d.ZERO;
|
Vec3d contactPointMotion = Vec3d.ZERO;
|
||||||
|
|
||||||
if (surfaceCollision.isTrue()) {
|
if (surfaceCollision.isTrue()) {
|
||||||
entity.fallDistance = 0;
|
entity.fallDistance = 0;
|
||||||
entity.onGround = true;
|
entity.onGround = true;
|
||||||
contraptionEntity.collidingEntities.add(entity);
|
contraptionEntity.collidingEntities.put(entity, new MutableInt(0));
|
||||||
if (entity instanceof ItemEntity)
|
if (entity instanceof ItemEntity)
|
||||||
entityMotion = entityMotion.mul(.5f, 1, .5f);
|
entityMotion = entityMotion.mul(.5f, 1, .5f);
|
||||||
|
|
||||||
if (playerType != PlayerType.SERVER) {
|
if (playerType != PlayerType.SERVER) {
|
||||||
contactPointMotion = contraptionEntity.getContactPointMotion(entityPosition);
|
contactPointMotion = contraptionEntity.getContactPointMotion(entityPosition);
|
||||||
allowedMovement = getAllowedMovement(contactPointMotion, entity);
|
allowedMovement = getAllowedMovement(contactPointMotion, entity);
|
||||||
entity.setPosition(entityPosition.x + allowedMovement.x, entityPosition.y + allowedMovement.y,
|
entity.setPosition(entityPosition.x + allowedMovement.x,
|
||||||
entityPosition.z + allowedMovement.z);
|
entityPosition.y, entityPosition.z + allowedMovement.z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,7 +260,8 @@ public class ContraptionCollider {
|
||||||
float limbSwing = MathHelper.sqrt(d0 * d0 + d1 * d1) * 4.0F;
|
float limbSwing = MathHelper.sqrt(d0 * d0 + d1 * d1) * 4.0F;
|
||||||
if (limbSwing > 1.0F)
|
if (limbSwing > 1.0F)
|
||||||
limbSwing = 1.0F;
|
limbSwing = 1.0F;
|
||||||
AllPackets.channel.sendToServer(new ClientMotionPacket(entityMotion, true, limbSwing));
|
AllPackets.channel
|
||||||
|
.sendToServer(new ClientMotionPacket(entityMotion, true, limbSwing));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
package com.simibubi.create.content.contraptions.components.structureMovement;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.networking.SimplePacketBase;
|
||||||
|
|
||||||
|
import net.minecraft.network.PacketBuffer;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.fml.DistExecutor;
|
||||||
|
import net.minecraftforge.fml.network.NetworkEvent.Context;
|
||||||
|
|
||||||
|
public class ContraptionDisassemblyPacket extends SimplePacketBase {
|
||||||
|
|
||||||
|
int entityID;
|
||||||
|
StructureTransform transform;
|
||||||
|
|
||||||
|
public ContraptionDisassemblyPacket(int entityID, StructureTransform transform) {
|
||||||
|
this.entityID = entityID;
|
||||||
|
this.transform = transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ContraptionDisassemblyPacket(PacketBuffer buffer) {
|
||||||
|
entityID = buffer.readInt();
|
||||||
|
transform = StructureTransform.fromBuffer(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(PacketBuffer buffer) {
|
||||||
|
buffer.writeInt(entityID);
|
||||||
|
transform.writeToBuffer(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(Supplier<Context> context) {
|
||||||
|
context.get()
|
||||||
|
.enqueueWork(() -> DistExecutor.runWhenOn(Dist.CLIENT,
|
||||||
|
() -> () -> AbstractContraptionEntity.handleDisassemblyPacket(this)));
|
||||||
|
context.get()
|
||||||
|
.setPacketHandled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -50,6 +50,13 @@ public class ControlledContraptionEntity extends AbstractContraptionEntity {
|
||||||
return contraption instanceof TranslatingContraption;
|
return contraption instanceof TranslatingContraption;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Vec3d getContactPointMotion(Vec3d globalContactPoint) {
|
||||||
|
if (contraption instanceof TranslatingContraption)
|
||||||
|
return getMotion();
|
||||||
|
return super.getContactPointMotion(globalContactPoint);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void setContraption(Contraption contraption) {
|
protected void setContraption(Contraption contraption) {
|
||||||
super.setContraption(contraption);
|
super.setContraption(contraption);
|
||||||
|
|
|
@ -19,6 +19,7 @@ import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.HorizontalFaceBlock;
|
import net.minecraft.block.HorizontalFaceBlock;
|
||||||
import net.minecraft.block.SlabBlock;
|
import net.minecraft.block.SlabBlock;
|
||||||
import net.minecraft.block.StairsBlock;
|
import net.minecraft.block.StairsBlock;
|
||||||
|
import net.minecraft.network.PacketBuffer;
|
||||||
import net.minecraft.state.BooleanProperty;
|
import net.minecraft.state.BooleanProperty;
|
||||||
import net.minecraft.state.properties.AttachFace;
|
import net.minecraft.state.properties.AttachFace;
|
||||||
import net.minecraft.state.properties.BellAttachment;
|
import net.minecraft.state.properties.BellAttachment;
|
||||||
|
@ -40,6 +41,13 @@ public class StructureTransform {
|
||||||
Axis rotationAxis;
|
Axis rotationAxis;
|
||||||
BlockPos offset;
|
BlockPos offset;
|
||||||
|
|
||||||
|
private StructureTransform(BlockPos offset, int angle, Axis axis, Rotation rotation) {
|
||||||
|
this.offset = offset;
|
||||||
|
this.angle = angle;
|
||||||
|
rotationAxis = axis;
|
||||||
|
this.rotation = rotation;
|
||||||
|
}
|
||||||
|
|
||||||
public StructureTransform(BlockPos offset, float xRotation, float yRotation, float zRotation) {
|
public StructureTransform(BlockPos offset, float xRotation, float yRotation, float zRotation) {
|
||||||
this.offset = offset;
|
this.offset = offset;
|
||||||
if (xRotation != 0) {
|
if (xRotation != 0) {
|
||||||
|
@ -71,6 +79,7 @@ public class StructureTransform {
|
||||||
|
|
||||||
public Vec3d apply(Vec3d localVec) {
|
public Vec3d apply(Vec3d localVec) {
|
||||||
Vec3d vec = localVec;
|
Vec3d vec = localVec;
|
||||||
|
if (rotationAxis != null)
|
||||||
vec = VecHelper.rotateCentered(vec, angle, rotationAxis);
|
vec = VecHelper.rotateCentered(vec, angle, rotationAxis);
|
||||||
vec = vec.add(new Vec3d(offset));
|
vec = vec.add(new Vec3d(offset));
|
||||||
return vec;
|
return vec;
|
||||||
|
@ -78,6 +87,7 @@ public class StructureTransform {
|
||||||
|
|
||||||
public BlockPos apply(BlockPos localPos) {
|
public BlockPos apply(BlockPos localPos) {
|
||||||
Vec3d vec = VecHelper.getCenterOf(localPos);
|
Vec3d vec = VecHelper.getCenterOf(localPos);
|
||||||
|
if (rotationAxis != null)
|
||||||
vec = VecHelper.rotateCentered(vec, angle, rotationAxis);
|
vec = VecHelper.rotateCentered(vec, angle, rotationAxis);
|
||||||
localPos = new BlockPos(vec);
|
localPos = new BlockPos(vec);
|
||||||
return localPos.add(offset);
|
return localPos.add(offset);
|
||||||
|
@ -202,7 +212,8 @@ public class StructureTransform {
|
||||||
|
|
||||||
protected BlockState transformBelt(BlockState state, boolean halfTurn) {
|
protected BlockState transformBelt(BlockState state, boolean halfTurn) {
|
||||||
Direction initialDirection = state.get(BeltBlock.HORIZONTAL_FACING);
|
Direction initialDirection = state.get(BeltBlock.HORIZONTAL_FACING);
|
||||||
boolean diagonal = state.get(BeltBlock.SLOPE) == BeltSlope.DOWNWARD || state.get(BeltBlock.SLOPE) == BeltSlope.UPWARD;
|
boolean diagonal =
|
||||||
|
state.get(BeltBlock.SLOPE) == BeltSlope.DOWNWARD || state.get(BeltBlock.SLOPE) == BeltSlope.UPWARD;
|
||||||
|
|
||||||
if (!diagonal) {
|
if (!diagonal) {
|
||||||
for (int i = 0; i < rotation.ordinal(); i++) {
|
for (int i = 0; i < rotation.ordinal(); i++) {
|
||||||
|
@ -254,8 +265,7 @@ public class StructureTransform {
|
||||||
boolean downward = slope == BeltSlope.DOWNWARD;
|
boolean downward = slope == BeltSlope.DOWNWARD;
|
||||||
|
|
||||||
// Rotate diagonal
|
// Rotate diagonal
|
||||||
if (direction.getAxisDirection() == AxisDirection.POSITIVE ^ downward
|
if (direction.getAxisDirection() == AxisDirection.POSITIVE ^ downward ^ direction.getAxis() == Axis.Z) {
|
||||||
^ direction.getAxis() == Axis.Z) {
|
|
||||||
state = state.with(BeltBlock.SLOPE, upward ? BeltSlope.DOWNWARD : BeltSlope.UPWARD);
|
state = state.with(BeltBlock.SLOPE, upward ? BeltSlope.DOWNWARD : BeltSlope.UPWARD);
|
||||||
} else {
|
} else {
|
||||||
state = state.with(BeltBlock.HORIZONTAL_FACING, newDirection);
|
state = state.with(BeltBlock.HORIZONTAL_FACING, newDirection);
|
||||||
|
@ -269,8 +279,8 @@ public class StructureTransform {
|
||||||
boolean vertical = slope == BeltSlope.VERTICAL;
|
boolean vertical = slope == BeltSlope.VERTICAL;
|
||||||
|
|
||||||
if (diagonal) {
|
if (diagonal) {
|
||||||
state = state.with(BeltBlock.SLOPE,
|
state = state.with(BeltBlock.SLOPE, slope == BeltSlope.UPWARD ? BeltSlope.DOWNWARD
|
||||||
slope == BeltSlope.UPWARD ? BeltSlope.DOWNWARD : slope == BeltSlope.DOWNWARD ? BeltSlope.UPWARD : slope);
|
: slope == BeltSlope.DOWNWARD ? BeltSlope.UPWARD : slope);
|
||||||
} else if (vertical) {
|
} else if (vertical) {
|
||||||
state = state.with(BeltBlock.HORIZONTAL_FACING, newDirection);
|
state = state.with(BeltBlock.HORIZONTAL_FACING, newDirection);
|
||||||
}
|
}
|
||||||
|
@ -317,4 +327,21 @@ public class StructureTransform {
|
||||||
return rotated;
|
return rotated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static StructureTransform fromBuffer(PacketBuffer buffer) {
|
||||||
|
BlockPos readBlockPos = buffer.readBlockPos();
|
||||||
|
int readAngle = buffer.readInt();
|
||||||
|
int axisIndex = buffer.readVarInt();
|
||||||
|
int rotationIndex = buffer.readVarInt();
|
||||||
|
return new StructureTransform(readBlockPos, readAngle,
|
||||||
|
axisIndex == -1 ? null : Axis.values()[axisIndex],
|
||||||
|
rotationIndex == -1 ? null : Rotation.values()[rotationIndex]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeToBuffer(PacketBuffer buffer) {
|
||||||
|
buffer.writeBlockPos(offset);
|
||||||
|
buffer.writeInt(angle);
|
||||||
|
buffer.writeVarInt(rotationAxis == null ? -1 : rotationAxis.ordinal());
|
||||||
|
buffer.writeVarInt(rotation == null ? -1 : rotation.ordinal());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,12 +163,6 @@ public class ContinuousOBBCollider extends OBBCollider {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vec3d getAllowedMotion(Vec3d motion) {
|
|
||||||
double length = motion.length();
|
|
||||||
return motion.normalize()
|
|
||||||
.scale(getTimeOfImpact() * length);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Vec3d asSeparationVec(double obbStepHeight) {
|
public Vec3d asSeparationVec(double obbStepHeight) {
|
||||||
if (isDiscreteCollision) {
|
if (isDiscreteCollision) {
|
||||||
if (stepSeparation <= obbStepHeight)
|
if (stepSeparation <= obbStepHeight)
|
||||||
|
|
|
@ -5,6 +5,7 @@ import java.util.function.Function;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import com.simibubi.create.Create;
|
import com.simibubi.create.Create;
|
||||||
|
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionDisassemblyPacket;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionStallPacket;
|
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionStallPacket;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.glue.GlueEffectPacket;
|
import com.simibubi.create.content.contraptions.components.structureMovement.glue.GlueEffectPacket;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.sync.ClientMotionPacket;
|
import com.simibubi.create.content.contraptions.components.structureMovement.sync.ClientMotionPacket;
|
||||||
|
@ -25,8 +26,8 @@ import com.simibubi.create.content.logistics.packet.ConfigureStockswitchPacket;
|
||||||
import com.simibubi.create.content.schematics.packet.ConfigureSchematicannonPacket;
|
import com.simibubi.create.content.schematics.packet.ConfigureSchematicannonPacket;
|
||||||
import com.simibubi.create.content.schematics.packet.InstantSchematicPacket;
|
import com.simibubi.create.content.schematics.packet.InstantSchematicPacket;
|
||||||
import com.simibubi.create.content.schematics.packet.SchematicPlacePacket;
|
import com.simibubi.create.content.schematics.packet.SchematicPlacePacket;
|
||||||
import com.simibubi.create.content.schematics.packet.SchematicUploadPacket;
|
|
||||||
import com.simibubi.create.content.schematics.packet.SchematicSyncPacket;
|
import com.simibubi.create.content.schematics.packet.SchematicSyncPacket;
|
||||||
|
import com.simibubi.create.content.schematics.packet.SchematicUploadPacket;
|
||||||
import com.simibubi.create.foundation.command.ConfigureConfigPacket;
|
import com.simibubi.create.foundation.command.ConfigureConfigPacket;
|
||||||
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringCountUpdatePacket;
|
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringCountUpdatePacket;
|
||||||
import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.ScrollValueUpdatePacket;
|
import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.ScrollValueUpdatePacket;
|
||||||
|
@ -69,6 +70,7 @@ public enum AllPackets {
|
||||||
BEAM_EFFECT(ZapperBeamPacket.class, ZapperBeamPacket::new),
|
BEAM_EFFECT(ZapperBeamPacket.class, ZapperBeamPacket::new),
|
||||||
CONFIGURE_CONFIG(ConfigureConfigPacket.class, ConfigureConfigPacket::new),
|
CONFIGURE_CONFIG(ConfigureConfigPacket.class, ConfigureConfigPacket::new),
|
||||||
CONTRAPTION_STALL(ContraptionStallPacket.class, ContraptionStallPacket::new),
|
CONTRAPTION_STALL(ContraptionStallPacket.class, ContraptionStallPacket::new),
|
||||||
|
CONTRAPTION_DISASSEMBLE(ContraptionDisassemblyPacket.class, ContraptionDisassemblyPacket::new),
|
||||||
GLUE_EFFECT(GlueEffectPacket.class, GlueEffectPacket::new),
|
GLUE_EFFECT(GlueEffectPacket.class, GlueEffectPacket::new),
|
||||||
CONTRAPTION_SEAT_MAPPING(ContraptionSeatMappingPacket.class, ContraptionSeatMappingPacket::new),
|
CONTRAPTION_SEAT_MAPPING(ContraptionSeatMappingPacket.class, ContraptionSeatMappingPacket::new),
|
||||||
LIMBSWING_UPDATE(LimbSwingUpdatePacket.class, LimbSwingUpdatePacket::new),
|
LIMBSWING_UPDATE(LimbSwingUpdatePacket.class, LimbSwingUpdatePacket::new),
|
||||||
|
|
Loading…
Reference in a new issue