Things are changing

- Track if the transforms for an InstanceTree have changed
- Pass a boolean down the tree and || it with our changed flag to force
  updates
- Expose the force flag to visuals so they can hint to us if their root
  transforms never change
- Add 2 wrapper methods to make the distinction more clear
This commit is contained in:
Jozufozu 2024-09-15 00:28:10 -07:00
parent 5299571540
commit ed727e7a1b
2 changed files with 195 additions and 23 deletions

View file

@ -34,29 +34,29 @@ public final class InstanceTree {
private final MeshTree source; private final MeshTree source;
@Nullable @Nullable
private final TransformedInstance instance; private final TransformedInstance instance;
private final PartPose initialPose;
private final InstanceTree[] children; private final InstanceTree[] children;
private final Matrix4f poseMatrix; private final Matrix4f poseMatrix;
public float x; private float x;
public float y; private float y;
public float z; private float z;
public float xRot; private float xRot;
public float yRot; private float yRot;
public float zRot; private float zRot;
public float xScale; private float xScale;
public float yScale; private float yScale;
public float zScale; private float zScale;
@ApiStatus.Experimental @ApiStatus.Experimental
public boolean visible = true; public boolean visible = true;
@ApiStatus.Experimental @ApiStatus.Experimental
public boolean skipDraw; public boolean skipDraw;
private InstanceTree(MeshTree source, @Nullable TransformedInstance instance, PartPose initialPose, InstanceTree[] children) { private boolean changed;
private InstanceTree(MeshTree source, @Nullable TransformedInstance instance, InstanceTree[] children) {
this.source = source; this.source = source;
this.instance = instance; this.instance = instance;
this.initialPose = initialPose;
this.children = children; this.children = children;
if (instance != null) { if (instance != null) {
@ -88,7 +88,7 @@ public final class InstanceTree {
instance = null; instance = null;
} }
return new InstanceTree(meshTree, instance, meshTree.initialPose(), children); return new InstanceTree(meshTree, instance, children);
} }
public static InstanceTree create(InstancerProvider provider, MeshTree meshTree, BiFunction<String, Mesh, Model.ConfiguredMesh> meshFinalizerFunc) { public static InstanceTree create(InstancerProvider provider, MeshTree meshTree, BiFunction<String, Mesh, Model.ConfiguredMesh> meshFinalizerFunc) {
@ -113,7 +113,7 @@ public final class InstanceTree {
} }
public PartPose initialPose() { public PartPose initialPose() {
return initialPose; return source.initialPose();
} }
public int childCount() { public int childCount() {
@ -214,57 +214,222 @@ public final class InstanceTree {
} }
} }
/**
* Update the instances in this tree, assuming initialPose changes.
*
* <p>This is the preferred method for entity visuals, or if you're not sure which you need.
*
* @param initialPose The root transformation matrix.
*/
public void updateInstances(Matrix4fc initialPose) { public void updateInstances(Matrix4fc initialPose) {
propagateAnimation(initialPose, true);
}
/**
* Update the instances in this tree, assuming initialPose doesn't change between invocations.
*
* <p>This is the preferred method for block entity visuals.
*
* @param initialPose The root transformation matrix.
*/
public void updateInstancesStatic(Matrix4fc initialPose) {
propagateAnimation(initialPose, false);
}
/**
* Propagate pose transformations to this tree and all its children.
*
* @param initialPose The root transformation matrix.
* @param force Whether to force the update even if this node's transformations haven't changed.
*/
public void propagateAnimation(Matrix4fc initialPose, boolean force) {
if (!visible) { if (!visible) {
return; return;
} }
poseMatrix.set(initialPose); if (changed || force) {
translateAndRotate(poseMatrix); poseMatrix.set(initialPose);
translateAndRotate(poseMatrix);
force = true;
if (instance != null && !skipDraw) { if (instance != null && !skipDraw) {
instance.setChanged(); instance.setChanged();
}
} }
for (InstanceTree child : children) { for (InstanceTree child : children) {
child.updateInstances(poseMatrix); child.propagateAnimation(poseMatrix, force);
} }
changed = false;
}
public float xPos() {
return x;
}
public float yPos() {
return y;
}
public float zPos() {
return z;
}
public float xRot() {
return xRot;
}
public float yRot() {
return yRot;
}
public float zRot() {
return zRot;
}
public float xScale() {
return xScale;
}
public float yScale() {
return yScale;
}
public float zScale() {
return zScale;
} }
public void pos(float x, float y, float z) { public void pos(float x, float y, float z) {
this.x = x; this.x = x;
this.y = y; this.y = y;
this.z = z; this.z = z;
setChanged();
}
public void xPos(float x) {
this.x = x;
setChanged();
}
public void yPos(float y) {
this.y = y;
setChanged();
}
public void zPos(float z) {
this.z = z;
setChanged();
} }
public void rotation(float xRot, float yRot, float zRot) { public void rotation(float xRot, float yRot, float zRot) {
this.xRot = xRot; this.xRot = xRot;
this.yRot = yRot; this.yRot = yRot;
this.zRot = zRot; this.zRot = zRot;
setChanged();
}
public void xRot(float xRot) {
this.xRot = xRot;
setChanged();
}
public void yRot(float yRot) {
this.yRot = yRot;
setChanged();
}
public void zRot(float zRot) {
this.zRot = zRot;
setChanged();
} }
public void scale(float xScale, float yScale, float zScale) { public void scale(float xScale, float yScale, float zScale) {
this.xScale = xScale; this.xScale = xScale;
this.yScale = yScale; this.yScale = yScale;
this.zScale = zScale; this.zScale = zScale;
setChanged();
}
public void xScale(float xScale) {
this.xScale = xScale;
setChanged();
}
public void yScale(float yScale) {
this.yScale = yScale;
setChanged();
}
public void zScale(float zScale) {
this.zScale = zScale;
setChanged();
} }
public void offsetPos(float xOffset, float yOffset, float zOffset) { public void offsetPos(float xOffset, float yOffset, float zOffset) {
x += xOffset; x += xOffset;
y += yOffset; y += yOffset;
z += zOffset; z += zOffset;
setChanged();
}
public void offsetXPos(float xOffset) {
x += xOffset;
setChanged();
}
public void offsetYPos(float yOffset) {
y += yOffset;
setChanged();
}
public void offsetZPos(float zOffset) {
z += zOffset;
setChanged();
} }
public void offsetRotation(float xOffset, float yOffset, float zOffset) { public void offsetRotation(float xOffset, float yOffset, float zOffset) {
xRot += xOffset; xRot += xOffset;
yRot += yOffset; yRot += yOffset;
zRot += zOffset; zRot += zOffset;
setChanged();
}
public void offsetXRot(float xOffset) {
xRot += xOffset;
setChanged();
}
public void offsetYRot(float yOffset) {
yRot += yOffset;
setChanged();
}
public void offsetZRot(float zOffset) {
zRot += zOffset;
setChanged();
} }
public void offsetScale(float xOffset, float yOffset, float zOffset) { public void offsetScale(float xOffset, float yOffset, float zOffset) {
xScale += xOffset; xScale += xOffset;
yScale += yOffset; yScale += yOffset;
zScale += zOffset; zScale += zOffset;
setChanged();
}
public void offsetXScale(float xOffset) {
xScale += xOffset;
setChanged();
}
public void offsetYScale(float yOffset) {
yScale += yOffset;
setChanged();
}
public void offsetZScale(float zOffset) {
zScale += zOffset;
setChanged();
} }
public void offsetPos(Vector3fc offset) { public void offsetPos(Vector3fc offset) {
@ -293,10 +458,11 @@ public final class InstanceTree {
xScale = ModelPart.DEFAULT_SCALE; xScale = ModelPart.DEFAULT_SCALE;
yScale = ModelPart.DEFAULT_SCALE; yScale = ModelPart.DEFAULT_SCALE;
zScale = ModelPart.DEFAULT_SCALE; zScale = ModelPart.DEFAULT_SCALE;
setChanged();
} }
public void resetPose() { public void resetPose() {
loadPose(initialPose); loadPose(source.initialPose());
} }
public void copyTransform(InstanceTree tree) { public void copyTransform(InstanceTree tree) {
@ -309,6 +475,7 @@ public final class InstanceTree {
xScale = tree.xScale; xScale = tree.xScale;
yScale = tree.yScale; yScale = tree.yScale;
zScale = tree.zScale; zScale = tree.zScale;
setChanged();
} }
public void copyTransform(ModelPart modelPart) { public void copyTransform(ModelPart modelPart) {
@ -321,6 +488,7 @@ public final class InstanceTree {
xScale = modelPart.xScale; xScale = modelPart.xScale;
yScale = modelPart.yScale; yScale = modelPart.yScale;
zScale = modelPart.zScale; zScale = modelPart.zScale;
setChanged();
} }
public void delete() { public void delete() {
@ -332,6 +500,10 @@ public final class InstanceTree {
} }
} }
private void setChanged() {
changed = true;
}
@ApiStatus.Experimental @ApiStatus.Experimental
@FunctionalInterface @FunctionalInterface
public interface ObjIntIntConsumer<T> { public interface ObjIntIntConsumer<T> {

View file

@ -146,9 +146,9 @@ public class ChestVisual<T extends BlockEntity & LidBlockEntity> extends Abstrac
progress = 1.0F - progress; progress = 1.0F - progress;
progress = 1.0F - progress * progress * progress; progress = 1.0F - progress * progress * progress;
lid.xRot = -(progress * ((float) Math.PI / 2F)); lid.xRot(-(progress * ((float) Math.PI / 2F)));
lock.xRot = lid.xRot; lock.xRot(lid.xRot());
instances.updateInstances(initialPose); instances.updateInstancesStatic(initialPose);
} }
@Override @Override