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); 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 @Nullable
public ActorInstance createActor(Pair<Template.BlockInfo, MovementContext> actor) { public ActorInstance createActor(Pair<Template.BlockInfo, MovementContext> actor) {
Template.BlockInfo blockInfo = actor.getLeft(); Template.BlockInfo blockInfo = actor.getLeft();

View file

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

View file

@ -12,6 +12,11 @@ public class InterpolatedValue {
this.value = value; this.value = value;
return this; return this;
} }
public InterpolatedValue init(float value) {
this.lastValue = this.value = value;
return this;
}
public float get(float partialTicks) { public float get(float partialTicks) {
return MathHelper.lerp(partialTicks, lastValue, value); 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 dY = pos.getY() - cY;
int dZ = pos.getZ() - cZ; int dZ = pos.getZ() - cZ;
int dSq = dX * dX + dY * dY + dZ * dZ; if ((frame % getUpdateDivisor(dX, dY, dZ)) == 0)
int divisor = (dSq / 1024) + 1;
if (frame % divisor == 0)
instance.tick(); instance.tick();
} }
} }
@ -88,21 +84,7 @@ public abstract class InstancedTileRenderer<P extends BasicProgram> {
continue; continue;
} }
BlockPos pos = dyn.getWorldPosition(); if (shouldTick(dyn.getWorldPosition(), lookX, lookY, lookZ, cX, cY, cZ))
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)
dyn.beginFrame(); 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) { private void addInternal(TileEntity tile) {
getInstance(tile, true); getInstance(tile, true);
} }