use of com.simibubi.create.foundation.utility.VecHelper in project Create by Creators-of-Create.
the class CouplingPhysics method softCollisionStep.
public static void softCollisionStep(Level world, Couple<AbstractMinecart> carts, double couplingLength) {
Couple<Float> maxSpeed = carts.map(AbstractMinecart::getMaxCartSpeedOnRail);
Couple<Boolean> canAddmotion = carts.map(MinecartSim2020::canAddMotion);
// Assuming Minecarts will never move faster than 1 block/tick
Couple<Vec3> motions = carts.map(Entity::getDeltaMovement);
motions.replaceWithParams(VecHelper::clamp, Couple.create(1f, 1f));
Couple<Vec3> nextPositions = carts.map(MinecartSim2020::predictNextPositionOf);
Couple<RailShape> shapes = carts.mapWithContext((minecart, current) -> {
Vec3 vec = nextPositions.get(current);
int x = Mth.floor(vec.x());
int y = Mth.floor(vec.y());
int z = Mth.floor(vec.z());
BlockPos pos = new BlockPos(x, y - 1, z);
if (minecart.level.getBlockState(pos).is(BlockTags.RAILS))
pos = pos.below();
BlockPos railPosition = pos;
BlockState railState = world.getBlockState(railPosition.above());
if (!(railState.getBlock() instanceof BaseRailBlock))
return null;
BaseRailBlock block = (BaseRailBlock) railState.getBlock();
return block.getRailDirection(railState, world, railPosition, minecart);
});
float futureStress = (float) (couplingLength - nextPositions.getFirst().distanceTo(nextPositions.getSecond()));
if (Mth.equal(futureStress, 0D))
return;
for (boolean current : Iterate.trueAndFalse) {
Vec3 correction = Vec3.ZERO;
Vec3 pos = nextPositions.get(current);
Vec3 link = nextPositions.get(!current).subtract(pos);
float correctionMagnitude = -futureStress / 2f;
if (canAddmotion.get(current) != canAddmotion.get(!current))
correctionMagnitude = !canAddmotion.get(current) ? 0 : correctionMagnitude * 2;
if (!canAddmotion.get(current))
continue;
RailShape shape = shapes.get(current);
if (shape != null) {
Vec3 railVec = MinecartSim2020.getRailVec(shape);
correction = followLinkOnRail(link, pos, correctionMagnitude, railVec).subtract(pos);
} else
correction = link.normalize().scale(correctionMagnitude);
correction = VecHelper.clamp(correction, maxSpeed.get(current));
motions.set(current, motions.get(current).add(correction));
}
motions.replaceWithParams(VecHelper::clamp, maxSpeed);
carts.forEachWithParams(Entity::setDeltaMovement, motions);
}
Aggregations