Fix arms glitching out on contraptions.

- Also provide a hook for subclasses of InstancedTileRenderer to control when specific instances tick.
This commit is contained in:
JozsefA 2021-03-29 15:06:09 -07:00
parent 0b6098817e
commit ff4a9e5c78
4 changed files with 34 additions and 24 deletions

View file

@ -57,6 +57,11 @@ public class ContraptionKineticRenderer extends InstancedTileRenderer<Contraptio
actors.forEach(ActorInstance::beginFrame);
}
@Override
protected boolean shouldTick(BlockPos worldPos, float lookX, float lookY, float lookZ, int cX, int cY, int cZ) {
return true;
}
@Nullable
public ActorInstance createActor(Pair<Template.BlockInfo, MovementContext> actor) {
Template.BlockInfo blockInfo = actor.getLeft();

View file

@ -79,13 +79,13 @@ public class ArmTileEntity extends KineticTileEntity {
phase = Phase.SEARCH_INPUTS;
previousTarget = ArmAngleTarget.NO_TARGET;
baseAngle = new InterpolatedAngle();
baseAngle.set(previousTarget.baseAngle);
baseAngle.init(previousTarget.baseAngle);
lowerArmAngle = new InterpolatedAngle();
lowerArmAngle.set(previousTarget.lowerArmAngle);
lowerArmAngle.init(previousTarget.lowerArmAngle);
upperArmAngle = new InterpolatedAngle();
upperArmAngle.set(previousTarget.upperArmAngle);
upperArmAngle.init(previousTarget.upperArmAngle);
headAngle = new InterpolatedAngle();
headAngle.set(previousTarget.headAngle);
headAngle.init(previousTarget.headAngle);
clawAngle = new InterpolatedAngle();
previousBaseAngle = previousTarget.baseAngle;
updateInteractionPoints = true;

View file

@ -12,6 +12,11 @@ public class InterpolatedValue {
this.value = value;
return this;
}
public InterpolatedValue init(float value) {
this.lastValue = this.value = value;
return this;
}
public float get(float partialTicks) {
return MathHelper.lerp(partialTicks, lastValue, value);

View file

@ -57,11 +57,7 @@ public abstract class InstancedTileRenderer<P extends BasicProgram> {
int dY = pos.getY() - cY;
int dZ = pos.getZ() - cZ;
int dSq = dX * dX + dY * dY + dZ * dZ;
int divisor = (dSq / 1024) + 1;
if (frame % divisor == 0)
if ((frame % getUpdateDivisor(dX, dY, dZ)) == 0)
instance.tick();
}
}
@ -88,21 +84,7 @@ public abstract class InstancedTileRenderer<P extends BasicProgram> {
continue;
}
BlockPos pos = dyn.getWorldPosition();
int dX = pos.getX() - cX;
int dY = pos.getY() - cY;
int dZ = pos.getZ() - cZ;
float dot = dX * lookX + dY * lookY + dZ * lookZ;
if (dot < 0) continue; // is it behind the camera?
int dSq = dX * dX + dY * dY + dZ * dZ;
int divisor = (dSq / 1024) + 1; // https://www.desmos.com/calculator/aaycpludsy
if (frame % divisor == 0)
if (shouldTick(dyn.getWorldPosition(), lookX, lookY, lookZ, cX, cY, cZ))
dyn.beginFrame();
}
}
@ -207,6 +189,24 @@ public abstract class InstancedTileRenderer<P extends BasicProgram> {
}
}
protected boolean shouldTick(BlockPos worldPos, float lookX, float lookY, float lookZ, int cX, int cY, int cZ) {
int dX = worldPos.getX() - cX;
int dY = worldPos.getY() - cY;
int dZ = worldPos.getZ() - cZ;
float dot = dX * lookX + dY * lookY + dZ * lookZ;
if (dot < 0) return false; // is it behind the camera?
return (frame % getUpdateDivisor(dX, dY, dZ)) == 0;
}
protected int getUpdateDivisor(int dX, int dY, int dZ) {
int dSq = dX * dX + dY * dY + dZ * dZ;
return (dSq / 1024) + 1;
}
private void addInternal(TileEntity tile) {
getInstance(tile, true);
}