Skip to content

Commit

Permalink
Stackless
Browse files Browse the repository at this point in the history
- Store a pose matrix in each InstanceTree, equivalent to its instance's pose matrix if the instance exists
- Directly transform the current InstanceTree's pose matrix instead of transforming a PoseStack and copying its matrix to the instance, eliminating the need to push and pop stack entries
- Remove InstanceTree.rotation
- Add more InstanceTree methods to allow full inspection of children
  • Loading branch information
PepperCode1 committed Sep 15, 2024
1 parent 41e0aa6 commit b24e872
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 66 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public final class InstanceTypes {
MemoryUtil.memPutByte(ptr + 3, instance.alpha);
ExtraMemoryOps.put2x16(ptr + 4, instance.overlay);
ExtraMemoryOps.put2x16(ptr + 8, instance.light);
ExtraMemoryOps.putMatrix4f(ptr + 12, instance.model);
ExtraMemoryOps.putMatrix4f(ptr + 12, instance.pose);
})
.vertexShader(Flywheel.rl("instance/transformed.vert"))
.cullShader(Flywheel.rl("instance/cull/transformed.glsl"))
Expand All @@ -46,7 +46,7 @@ public final class InstanceTypes {
MemoryUtil.memPutByte(ptr + 3, instance.alpha);
ExtraMemoryOps.put2x16(ptr + 4, instance.overlay);
ExtraMemoryOps.put2x16(ptr + 8, instance.light);
ExtraMemoryOps.putMatrix4f(ptr + 12, instance.model);
ExtraMemoryOps.putMatrix4f(ptr + 12, instance.pose);
ExtraMemoryOps.putMatrix3f(ptr + 76, instance.normal);
})
.vertexShader(Flywheel.rl("instance/posed.vert"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import net.minecraft.util.Mth;

public class PosedInstance extends ColoredLitInstance implements Transform<PosedInstance> {
public final Matrix4f model = new Matrix4f();
public final Matrix4f pose = new Matrix4f();
public final Matrix3f normal = new Matrix3f();

public PosedInstance(InstanceType<? extends PosedInstance> type, InstanceHandle handle) {
Expand All @@ -23,7 +23,7 @@ public PosedInstance(InstanceType<? extends PosedInstance> type, InstanceHandle

@Override
public PosedInstance mulPose(Matrix4fc pose) {
this.model.mul(pose);
this.pose.mul(pose);
return this;
}

Expand All @@ -35,27 +35,27 @@ public PosedInstance mulNormal(Matrix3fc normal) {

@Override
public PosedInstance rotateAround(Quaternionfc quaternion, float x, float y, float z) {
model.rotateAround(quaternion, x, y, z);
pose.rotateAround(quaternion, x, y, z);
normal.rotate(quaternion);
return this;
}

@Override
public PosedInstance translate(float x, float y, float z) {
model.translate(x, y, z);
pose.translate(x, y, z);
return this;
}

@Override
public PosedInstance rotate(Quaternionfc quaternion) {
model.rotate(quaternion);
pose.rotate(quaternion);
normal.rotate(quaternion);
return this;
}

@Override
public PosedInstance scale(float x, float y, float z) {
model.scale(x, y, z);
pose.scale(x, y, z);

if (x == y && y == z) {
if (x < 0.0f) {
Expand All @@ -74,7 +74,7 @@ public PosedInstance scale(float x, float y, float z) {
}

public PosedInstance setTransform(PoseStack.Pose pose) {
model.set(pose.pose());
this.pose.set(pose.pose());
normal.set(pose.normal());
return this;
}
Expand All @@ -84,7 +84,7 @@ public PosedInstance setTransform(PoseStack stack) {
}

public PosedInstance setIdentityTransform() {
model.identity();
pose.identity();
normal.identity();
return this;
}
Expand All @@ -97,7 +97,7 @@ public PosedInstance setIdentityTransform() {
* </p>
*/
public PosedInstance setZeroTransform() {
model.zero();
pose.zero();
normal.zero();
return this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,40 +9,39 @@
import dev.engine_room.flywheel.api.instance.InstanceType;
import dev.engine_room.flywheel.lib.transform.Affine;


public class TransformedInstance extends ColoredLitInstance implements Affine<TransformedInstance> {
public final Matrix4f model = new Matrix4f();
public final Matrix4f pose = new Matrix4f();

public TransformedInstance(InstanceType<? extends TransformedInstance> type, InstanceHandle handle) {
super(type, handle);
}

@Override
public TransformedInstance rotateAround(Quaternionfc quaternion, float x, float y, float z) {
model.rotateAround(quaternion, x, y, z);
pose.rotateAround(quaternion, x, y, z);
return this;
}

@Override
public TransformedInstance translate(float x, float y, float z) {
model.translate(x, y, z);
pose.translate(x, y, z);
return this;
}

@Override
public TransformedInstance rotate(Quaternionfc quaternion) {
model.rotate(quaternion);
pose.rotate(quaternion);
return this;
}

@Override
public TransformedInstance scale(float x, float y, float z) {
model.scale(x, y, z);
pose.scale(x, y, z);
return this;
}

public TransformedInstance setTransform(PoseStack.Pose pose) {
model.set(pose.pose());
this.pose.set(pose.pose());
return this;
}

Expand All @@ -51,7 +50,7 @@ public TransformedInstance setTransform(PoseStack stack) {
}

public TransformedInstance setIdentityTransform() {
model.identity();
pose.identity();
return this;
}

Expand All @@ -63,7 +62,7 @@ public TransformedInstance setIdentityTransform() {
* </p>
*/
public TransformedInstance setZeroTransform() {
model.zero();
pose.zero();
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@

import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.Unmodifiable;
import org.joml.Matrix4f;
import org.joml.Matrix4fc;
import org.joml.Quaternionf;
import org.joml.Vector3fc;

Expand All @@ -21,6 +22,8 @@
import dev.engine_room.flywheel.lib.instance.TransformedInstance;
import dev.engine_room.flywheel.lib.model.ModelCache;
import dev.engine_room.flywheel.lib.model.SingleMeshModel;
import dev.engine_room.flywheel.lib.transform.Affine;
import dev.engine_room.flywheel.lib.transform.TransformStack;
import net.minecraft.client.model.geom.ModelLayerLocation;
import net.minecraft.client.model.geom.ModelPart;
import net.minecraft.client.model.geom.PartPose;
Expand All @@ -32,10 +35,9 @@ public final class InstanceTree {
@Nullable
private final TransformedInstance instance;
private final PartPose initialPose;
@Unmodifiable
private final InstanceTree[] children;

private final Quaternionf rotation = new Quaternionf();
private final Matrix4f poseMatrix;

public float x;
public float y;
Expand All @@ -46,14 +48,23 @@ public final class InstanceTree {
public float xScale;
public float yScale;
public float zScale;
@ApiStatus.Experimental
public boolean visible = true;
@ApiStatus.Experimental
public boolean skipDraw;

private InstanceTree(MeshTree source, @Nullable TransformedInstance instance, PartPose initialPose, InstanceTree[] children) {
this.source = source;
this.instance = instance;
this.initialPose = initialPose;
this.children = children;

if (instance != null) {
poseMatrix = instance.pose;
} else {
poseMatrix = new Matrix4f();
}

resetPose();
}

Expand All @@ -64,8 +75,7 @@ private static InstanceTree create(InstancerProvider provider, MeshTree meshTree
for (int i = 0; i < meshTree.childCount(); i++) {
var meshTreeChild = meshTree.child(i);
String name = meshTree.childName(i);
children[i] = InstanceTree.create(provider, meshTreeChild, meshFinalizerFunc, pathSlash + name);

children[i] = create(provider, meshTreeChild, meshFinalizerFunc, pathSlash + name);
}

Mesh mesh = meshTree.mesh();
Expand Down Expand Up @@ -106,17 +116,35 @@ public PartPose initialPose() {
return initialPose;
}

@Nullable
public int childCount() {
return children.length;
}

public InstanceTree child(int index) {
if (index < 0 || index >= children.length) {
return null;
}
return children[index];
}

public String childName(int index) {
return source.childName(index);
}

public int childIndex(String name) {
return source.childIndex(name);
}

public boolean hasChild(String name) {
return childIndex(name) >= 0;
}

@Nullable
public InstanceTree child(String name) {
return child(source.childIndex(name));
int index = childIndex(name);

if (index < 0) {
return null;
}

return child(index);
}

public InstanceTree childOrThrow(String name) {
Expand Down Expand Up @@ -158,35 +186,48 @@ public void traverse(int i, int j, ObjIntIntConsumer<? super TransformedInstance
}
}

public void translateAndRotate(PoseStack poseStack) {
poseStack.translate(x / 16.0F, y / 16.0F, z / 16.0F);
public void translateAndRotate(Affine<?> affine, Quaternionf tempQuaternion) {
affine.translate(x / 16.0F, y / 16.0F, z / 16.0F);

if (xRot != 0.0F || yRot != 0.0F || zRot != 0.0F) {
poseStack.mulPose(rotation.rotationZYX(zRot, yRot, xRot));
affine.rotate(tempQuaternion.rotationZYX(zRot, yRot, xRot));
}

if (xScale != 1.0F || yScale != 1.0F || zScale != 1.0F) {
poseStack.scale(xScale, yScale, zScale);
affine.scale(xScale, yScale, zScale);
}
}

public void updateInstances(PoseStack poseStack) {
if (visible) {
poseStack.pushPose();
translateAndRotate(poseStack);
public void translateAndRotate(PoseStack poseStack, Quaternionf tempQuaternion) {
translateAndRotate(TransformStack.of(poseStack), tempQuaternion);
}

if (instance != null && !skipDraw) {
instance.setTransform(poseStack.last())
.setChanged();
}
public void translateAndRotate(Matrix4f pose) {
pose.translate(x / 16.0F, y / 16.0F, z / 16.0F);

// Use the bare HashMap.forEach because .values() always allocates a new collection.
// We also don't want to store an array of children because that would statically use a lot more memory.
for (InstanceTree child : children) {
child.updateInstances(poseStack);
}
if (xRot != 0.0F || yRot != 0.0F || zRot != 0.0F) {
pose.rotateZYX(zRot, yRot, xRot);
}

poseStack.popPose();
if (xScale != ModelPart.DEFAULT_SCALE || yScale != ModelPart.DEFAULT_SCALE || zScale != ModelPart.DEFAULT_SCALE) {
pose.scale(xScale, yScale, zScale);
}
}

public void updateInstances(Matrix4fc initialPose) {
if (!visible) {
return;
}

poseMatrix.set(initialPose);
translateAndRotate(poseMatrix);

if (instance != null && !skipDraw) {
instance.setChanged();
}

for (InstanceTree child : children) {
child.updateInstances(poseMatrix);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,13 @@ public final class MeshTree {
private final Mesh mesh;
private final PartPose initialPose;
private final MeshTree[] children;
private final String[] childKeys;
private final String[] childNames;

private MeshTree(@Nullable Mesh mesh, PartPose initialPose, MeshTree[] children, String[] childKeys) {
private MeshTree(@Nullable Mesh mesh, PartPose initialPose, MeshTree[] children, String[] childNames) {
this.mesh = mesh;
this.initialPose = initialPose;
this.childKeys = childKeys;
this.children = children;
this.childNames = childNames;
}

public static MeshTree of(ModelLayerLocation layer) {
Expand All @@ -59,15 +59,15 @@ private static MeshTree convert(ModelPart modelPart, ThreadLocalObjects objects)
var modelPartChildren = FlwLibLink.INSTANCE.getModelPartChildren(modelPart);

// Freeze the ordering here. Maybe we want to sort this?
String[] childKeys = modelPartChildren.keySet()
.toArray(new String[0]);
String[] childNames = modelPartChildren.keySet()
.toArray(String[]::new);

MeshTree[] children = new MeshTree[modelPartChildren.size()];
for (int i = 0; i < childKeys.length; i++) {
children[i] = convert(modelPartChildren.get(childKeys[i]), objects);
MeshTree[] children = new MeshTree[childNames.length];
for (int i = 0; i < childNames.length; i++) {
children[i] = convert(modelPartChildren.get(childNames[i]), objects);
}

return new MeshTree(compile(modelPart, objects), modelPart.getInitialPose(), children, childKeys);
return new MeshTree(compile(modelPart, objects), modelPart.getInitialPose(), children, childNames);
}

@Nullable
Expand Down Expand Up @@ -103,11 +103,11 @@ public MeshTree child(int index) {
}

public String childName(int index) {
return childKeys[index];
return childNames[index];
}

public int childIndex(String name) {
return Arrays.binarySearch(childKeys, name);
return Arrays.binarySearch(childNames, name);
}

public boolean hasChild(String name) {
Expand Down
Loading

0 comments on commit b24e872

Please sign in to comment.