From d342ae740c9b1a58a7bbfb2b1c1ebe67bd1d54cf Mon Sep 17 00:00:00 2001 From: Jozufozu Date: Sun, 15 Sep 2024 15:29:09 -0700 Subject: [PATCH] Get shulked - Convert ShulkerBoxVisual to use InstanceTree - Add "pruning" helper visitors - Remove ModelPartConverter - Remove TextureMapper and related code from VertexWriter --- .../lib/model/part/LoweringVisitor.java | 39 +++++++- .../lib/model/part/ModelPartConverter.java | 70 --------------- .../flywheel/lib/model/part/VertexWriter.java | 19 ---- .../flywheel/vanilla/BellVisual.java | 2 +- .../flywheel/vanilla/ChestVisual.java | 4 +- .../flywheel/vanilla/MinecartVisual.java | 2 +- .../flywheel/vanilla/ShulkerBoxVisual.java | 90 ++++++++----------- 7 files changed, 75 insertions(+), 151 deletions(-) delete mode 100644 common/src/lib/java/dev/engine_room/flywheel/lib/model/part/ModelPartConverter.java diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/LoweringVisitor.java b/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/LoweringVisitor.java index 8b5d30af1..29800551b 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/LoweringVisitor.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/LoweringVisitor.java @@ -1,6 +1,7 @@ package dev.engine_room.flywheel.lib.model.part; import java.util.ArrayList; +import java.util.Set; import org.jetbrains.annotations.Nullable; @@ -24,14 +25,48 @@ static ModelTree leaf(Model model, PartPose initialPose) { return ModelTree.create(model, initialPose, new ModelTree[0], new String[0]); } - static LoweringVisitor materialApplyingVisitor(Material material) { + static LoweringVisitor create(Material material) { return (path, mesh) -> new SingleMeshModel(mesh, material); } - static LoweringVisitor retexturingVisitor(Material material, TextureAtlasSprite sprite) { + static LoweringVisitor create(Material material, TextureAtlasSprite sprite) { return (path, mesh) -> new SingleMeshModel(new RetexturedMesh(mesh, sprite), material); } + static LoweringVisitor pruning(Set prune, Material material) { + return new LoweringVisitor() { + @Override + public @Nullable ModelTree visit(String path, MeshTree meshTree) { + if (prune.contains(path)) { + return null; + } + return LoweringVisitor.super.visit(path, meshTree); + } + + @Override + public Model visit(String path, Mesh mesh) { + return new SingleMeshModel(mesh, material); + } + }; + } + + static LoweringVisitor pruning(Set prune, Material material, TextureAtlasSprite sprite) { + return new LoweringVisitor() { + @Override + public @Nullable ModelTree visit(String path, MeshTree meshTree) { + if (prune.contains(path)) { + return null; + } + return LoweringVisitor.super.visit(path, meshTree); + } + + @Override + public Model visit(String path, Mesh mesh) { + return new SingleMeshModel(new RetexturedMesh(mesh, sprite), material); + } + }; + } + static String append(String path, String child) { if (path.isEmpty()) { return child; diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/ModelPartConverter.java b/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/ModelPartConverter.java deleted file mode 100644 index b5999cdac..000000000 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/ModelPartConverter.java +++ /dev/null @@ -1,70 +0,0 @@ -package dev.engine_room.flywheel.lib.model.part; - -import org.jetbrains.annotations.Nullable; -import org.joml.Vector2f; - -import com.mojang.blaze3d.vertex.PoseStack; - -import dev.engine_room.flywheel.api.model.Mesh; -import dev.engine_room.flywheel.lib.memory.MemoryBlock; -import dev.engine_room.flywheel.lib.model.SimpleQuadMesh; -import dev.engine_room.flywheel.lib.vertex.PosTexNormalVertexView; -import dev.engine_room.flywheel.lib.vertex.VertexView; -import net.minecraft.client.Minecraft; -import net.minecraft.client.model.geom.EntityModelSet; -import net.minecraft.client.model.geom.ModelLayerLocation; -import net.minecraft.client.model.geom.ModelPart; -import net.minecraft.client.renderer.LightTexture; -import net.minecraft.client.renderer.texture.OverlayTexture; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; - -@Deprecated(forRemoval = true) -public final class ModelPartConverter { - private static final ThreadLocal THREAD_LOCAL_OBJECTS = ThreadLocal.withInitial(ThreadLocalObjects::new); - - private ModelPartConverter() { - } - - public static Mesh convert(ModelPart modelPart, @Nullable PoseStack poseStack, @Nullable TextureMapper textureMapper) { - ThreadLocalObjects objects = THREAD_LOCAL_OBJECTS.get(); - if (poseStack == null) { - poseStack = objects.identityPoseStack; - } - VertexWriter vertexWriter = objects.vertexWriter; - - vertexWriter.setTextureMapper(textureMapper); - modelPart.render(poseStack, vertexWriter, LightTexture.FULL_BRIGHT, OverlayTexture.NO_OVERLAY); - MemoryBlock data = vertexWriter.copyDataAndReset(); - - VertexView vertexView = new PosTexNormalVertexView(); - vertexView.load(data); - return new SimpleQuadMesh(vertexView, "source=ModelPartConverter"); - } - - public static Mesh convert(ModelLayerLocation layer, @Nullable TextureAtlasSprite sprite, String... childPath) { - EntityModelSet entityModels = Minecraft.getInstance().getEntityModels(); - ModelPart modelPart = entityModels.bakeLayer(layer); - for (String pathPart : childPath) { - modelPart = modelPart.getChild(pathPart); - } - TextureMapper textureMapper = sprite == null ? null : TextureMapper.toSprite(sprite); - return convert(modelPart, null, textureMapper); - } - - public static Mesh convert(ModelLayerLocation layer, String... childPath) { - return convert(layer, null, childPath); - } - - public interface TextureMapper { - void map(Vector2f uv); - - static TextureMapper toSprite(TextureAtlasSprite sprite) { - return uv -> uv.set(sprite.getU(uv.x * 16), sprite.getV(uv.y * 16)); - } - } - - private static class ThreadLocalObjects { - public final PoseStack identityPoseStack = new PoseStack(); - public final VertexWriter vertexWriter = new VertexWriter(); - } -} diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/VertexWriter.java b/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/VertexWriter.java index 30855a85e..9f247cfa9 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/VertexWriter.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/VertexWriter.java @@ -1,14 +1,11 @@ package dev.engine_room.flywheel.lib.model.part; -import org.jetbrains.annotations.Nullable; -import org.joml.Vector2f; import org.lwjgl.system.MemoryUtil; import com.mojang.blaze3d.vertex.VertexConsumer; import dev.engine_room.flywheel.lib.math.DataPacker; import dev.engine_room.flywheel.lib.memory.MemoryBlock; -import dev.engine_room.flywheel.lib.model.part.ModelPartConverter.TextureMapper; import dev.engine_room.flywheel.lib.vertex.PosTexNormalVertexView; class VertexWriter implements VertexConsumer { @@ -16,10 +13,6 @@ class VertexWriter implements VertexConsumer { private MemoryBlock data; - @Nullable - private TextureMapper textureMapper; - private final Vector2f uvVec = new Vector2f(); - private int vertexCount; private boolean filledPosition; private boolean filledTexture; @@ -29,10 +22,6 @@ public VertexWriter() { data = MemoryBlock.malloc(128 * STRIDE); } - public void setTextureMapper(@Nullable TextureMapper mapper) { - textureMapper = mapper; - } - @Override public VertexConsumer vertex(double x, double y, double z) { if (!filledPosition) { @@ -54,13 +43,6 @@ public VertexConsumer color(int red, int green, int blue, int alpha) { @Override public VertexConsumer uv(float u, float v) { if (!filledTexture) { - if (textureMapper != null) { - uvVec.set(u, v); - textureMapper.map(uvVec); - u = uvVec.x; - v = uvVec.y; - } - long ptr = vertexPtr(); MemoryUtil.memPutFloat(ptr + 12, u); MemoryUtil.memPutFloat(ptr + 16, v); @@ -131,7 +113,6 @@ public MemoryBlock copyDataAndReset() { filledPosition = false; filledTexture = false; filledNormal = false; - textureMapper = null; return dataCopy; } diff --git a/common/src/main/java/dev/engine_room/flywheel/vanilla/BellVisual.java b/common/src/main/java/dev/engine_room/flywheel/vanilla/BellVisual.java index 1d69910ed..080bc2005 100644 --- a/common/src/main/java/dev/engine_room/flywheel/vanilla/BellVisual.java +++ b/common/src/main/java/dev/engine_room/flywheel/vanilla/BellVisual.java @@ -27,7 +27,7 @@ public class BellVisual extends AbstractBlockEntityVisual imple .build(); // Need to hold the visitor in a ResourceReloadHolder to ensure we have a valid sprite. - private static final ResourceReloadHolder VISITOR = new ResourceReloadHolder<>(() -> LoweringVisitor.retexturingVisitor(MATERIAL, BellRenderer.BELL_RESOURCE_LOCATION.sprite())); + private static final ResourceReloadHolder VISITOR = new ResourceReloadHolder<>(() -> LoweringVisitor.create(MATERIAL, BellRenderer.BELL_RESOURCE_LOCATION.sprite())); private final InstanceTree instances; private final InstanceTree bellBody; diff --git a/common/src/main/java/dev/engine_room/flywheel/vanilla/ChestVisual.java b/common/src/main/java/dev/engine_room/flywheel/vanilla/ChestVisual.java index d6e0e6a88..39af485fc 100644 --- a/common/src/main/java/dev/engine_room/flywheel/vanilla/ChestVisual.java +++ b/common/src/main/java/dev/engine_room/flywheel/vanilla/ChestVisual.java @@ -12,7 +12,6 @@ import dev.engine_room.flywheel.api.instance.Instance; import dev.engine_room.flywheel.api.material.Material; -import dev.engine_room.flywheel.api.model.Model; import dev.engine_room.flywheel.api.visualization.VisualizationContext; import dev.engine_room.flywheel.lib.material.CutoutShaders; import dev.engine_room.flywheel.lib.material.SimpleMaterial; @@ -20,7 +19,6 @@ import dev.engine_room.flywheel.lib.model.part.InstanceTree; import dev.engine_room.flywheel.lib.model.part.LoweringVisitor; import dev.engine_room.flywheel.lib.model.part.ModelTree; -import dev.engine_room.flywheel.lib.transform.TransformStack; import dev.engine_room.flywheel.lib.visual.AbstractBlockEntityVisual; import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual; import it.unimi.dsi.fastutil.floats.Float2FloatFunction; @@ -57,7 +55,7 @@ public class ChestVisual extends Abstrac LAYER_LOCATIONS.put(ChestType.RIGHT, ModelLayers.DOUBLE_CHEST_RIGHT); } - private static final Function VISITOR = new ResourceReloadCache<>(s -> LoweringVisitor.retexturingVisitor(MATERIAL, s)); + private static final Function VISITOR = new ResourceReloadCache<>(s -> LoweringVisitor.create(MATERIAL, s)); @Nullable private final InstanceTree instances; diff --git a/common/src/main/java/dev/engine_room/flywheel/vanilla/MinecartVisual.java b/common/src/main/java/dev/engine_room/flywheel/vanilla/MinecartVisual.java index 4b0ad1891..d8348fbf1 100644 --- a/common/src/main/java/dev/engine_room/flywheel/vanilla/MinecartVisual.java +++ b/common/src/main/java/dev/engine_room/flywheel/vanilla/MinecartVisual.java @@ -36,7 +36,7 @@ public class MinecartVisual extends ComponentEntityV .texture(TEXTURE) .mipmap(false) .build(); - private static final LoweringVisitor VISITOR = LoweringVisitor.materialApplyingVisitor(MATERIAL); + private static final LoweringVisitor VISITOR = LoweringVisitor.create(MATERIAL); private final InstanceTree instances; @Nullable diff --git a/common/src/main/java/dev/engine_room/flywheel/vanilla/ShulkerBoxVisual.java b/common/src/main/java/dev/engine_room/flywheel/vanilla/ShulkerBoxVisual.java index be5d85ba7..f3554e39e 100644 --- a/common/src/main/java/dev/engine_room/flywheel/vanilla/ShulkerBoxVisual.java +++ b/common/src/main/java/dev/engine_room/flywheel/vanilla/ShulkerBoxVisual.java @@ -1,28 +1,26 @@ package dev.engine_room.flywheel.vanilla; +import java.util.Set; import java.util.function.Consumer; +import java.util.function.Function; -import org.joml.Quaternionf; - -import com.mojang.math.Axis; +import org.joml.Matrix4f; import dev.engine_room.flywheel.api.instance.Instance; import dev.engine_room.flywheel.api.visualization.VisualizationContext; -import dev.engine_room.flywheel.lib.instance.InstanceTypes; -import dev.engine_room.flywheel.lib.instance.TransformedInstance; import dev.engine_room.flywheel.lib.material.CutoutShaders; import dev.engine_room.flywheel.lib.material.SimpleMaterial; -import dev.engine_room.flywheel.lib.model.ModelCache; -import dev.engine_room.flywheel.lib.model.SingleMeshModel; -import dev.engine_room.flywheel.lib.model.part.ModelPartConverter; -import dev.engine_room.flywheel.lib.transform.TransformStack; -import dev.engine_room.flywheel.lib.util.RecyclingPoseStack; +import dev.engine_room.flywheel.lib.model.ResourceReloadCache; +import dev.engine_room.flywheel.lib.model.part.InstanceTree; +import dev.engine_room.flywheel.lib.model.part.LoweringVisitor; +import dev.engine_room.flywheel.lib.model.part.ModelTree; import dev.engine_room.flywheel.lib.visual.AbstractBlockEntityVisual; import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual; import net.minecraft.client.model.geom.ModelLayers; import net.minecraft.client.renderer.Sheets; import net.minecraft.client.resources.model.Material; import net.minecraft.core.Direction; +import net.minecraft.util.Mth; import net.minecraft.world.item.DyeColor; import net.minecraft.world.level.block.ShulkerBoxBlock; import net.minecraft.world.level.block.entity.ShulkerBoxBlockEntity; @@ -35,17 +33,13 @@ public class ShulkerBoxVisual extends AbstractBlockEntityVisual BASE_MODELS = new ModelCache<>(texture -> { - return new SingleMeshModel(ModelPartConverter.convert(ModelLayers.SHULKER, texture.sprite(), "base"), MATERIAL); - }); - private static final ModelCache LID_MODELS = new ModelCache<>(texture -> { - return new SingleMeshModel(ModelPartConverter.convert(ModelLayers.SHULKER, texture.sprite(), "lid"), MATERIAL); - }); - private final TransformedInstance base; - private final TransformedInstance lid; + private static final Function VISITORS = new ResourceReloadCache<>(m -> LoweringVisitor.pruning(Set.of("head"), MATERIAL, m.sprite())); + + private final InstanceTree instances; + private final InstanceTree lid; - private final RecyclingPoseStack stack = new RecyclingPoseStack(); + private final Matrix4f initialPose; private float lastProgress = Float.NaN; @@ -60,31 +54,22 @@ public ShulkerBoxVisual(VisualizationContext ctx, ShulkerBoxBlockEntity blockEnt texture = Sheets.SHULKER_TEXTURE_LOCATION.get(color.getId()); } - var rotation = getDirection().getRotation(); - - stack.setIdentity(); - TransformStack.of(stack) - .translate(getVisualPosition()) - .translate(0.5f) - .scale(0.9995f) - .rotate(rotation) - .scale(1, -1, -1) - .translateY(-1); + instances = InstanceTree.create(instancerProvider(), ModelTree.of(ModelLayers.SHULKER, VISITORS.apply(texture))); - base = createBaseInstance(texture).setTransform(stack); - base.setChanged(); - lid = createLidInstance(texture).setTransform(stack); - lid.setChanged(); - } + initialPose = createInitialPose(); - private TransformedInstance createBaseInstance(Material texture) { - return instancerProvider().instancer(InstanceTypes.TRANSFORMED, BASE_MODELS.get(texture)) - .createInstance(); + lid = instances.childOrThrow("lid"); } - private TransformedInstance createLidInstance(Material texture) { - return instancerProvider().instancer(InstanceTypes.TRANSFORMED, LID_MODELS.get(texture)) - .createInstance(); + private Matrix4f createInitialPose() { + var rotation = getDirection().getRotation(); + var visualPosition = getVisualPosition(); + return new Matrix4f().translate(visualPosition.getX(), visualPosition.getY(), visualPosition.getZ()) + .translate(0.5f, 0.5f, 0.5f) + .scale(0.9995f) + .rotate(rotation) + .scale(1, -1, -1) + .translate(0, -1, 0); } private Direction getDirection() { @@ -107,33 +92,28 @@ public void beginFrame(Context context) { } lastProgress = progress; - Quaternionf spin = Axis.YP.rotationDegrees(270.0f * progress); - - TransformStack.of(stack) - .pushPose() - .translateY(-progress * 0.5f) - .rotate(spin); - - lid.setTransform(stack) - .setChanged(); + lid.yRot(1.5f * Mth.PI * progress); + lid.yPos(24f - progress * 8f); - stack.popPose(); + instances.updateInstancesStatic(initialPose); } @Override public void updateLight(float partialTick) { - relight(base, lid); + int packedLight = computePackedLight(); + instances.traverse(instance -> { + instance.light(packedLight) + .setChanged(); + }); } @Override public void collectCrumblingInstances(Consumer consumer) { - consumer.accept(base); - consumer.accept(lid); + instances.traverse(consumer); } @Override protected void _delete() { - base.delete(); - lid.delete(); + instances.delete(); } }