mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-12-27 23:47:09 +01:00
Keeping it shrimple
- Bake a model layer and then compile each part into a separate mesh - Move vanilla mixins to lib - Move caching logic into MeshTree
This commit is contained in:
parent
d2aa2e0013
commit
209da68c52
22 changed files with 166 additions and 470 deletions
|
@ -98,7 +98,7 @@ mixin {
|
|||
config 'flywheel.backend.mixins.json'
|
||||
config 'flywheel.impl.mixins.json'
|
||||
config 'flywheel.impl.sodium.mixins.json'
|
||||
config 'flywheel.vanilla.mixins.json'
|
||||
config 'flywheel.lib.mixins.json'
|
||||
|
||||
debug.verbose = true
|
||||
debug.export = true
|
||||
|
|
|
@ -27,11 +27,11 @@ import com.jozufozu.flywheel.lib.memory.FlwMemoryTracker;
|
|||
import com.jozufozu.flywheel.lib.model.ModelCache;
|
||||
import com.jozufozu.flywheel.lib.model.ModelHolder;
|
||||
import com.jozufozu.flywheel.lib.model.baked.PartialModel;
|
||||
import com.jozufozu.flywheel.lib.model.part.MeshTree;
|
||||
import com.jozufozu.flywheel.lib.util.LevelAttached;
|
||||
import com.jozufozu.flywheel.lib.util.ShadersModHandler;
|
||||
import com.jozufozu.flywheel.lib.util.StringUtil;
|
||||
import com.jozufozu.flywheel.vanilla.VanillaVisuals;
|
||||
import com.jozufozu.flywheel.vanilla.model.MeshTreeCache;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.commands.synchronization.ArgumentTypeInfos;
|
||||
|
@ -107,7 +107,7 @@ public class Flywheel {
|
|||
modEventBus.addListener(BackendManagerImpl::onEndClientResourceReload);
|
||||
|
||||
modEventBus.addListener((EndClientResourceReloadEvent e) -> ModelCache.onEndClientResourceReload(e));
|
||||
modEventBus.addListener(MeshTreeCache::onEndClientResourceReload);
|
||||
modEventBus.addListener(MeshTree::onEndClientResourceReload);
|
||||
modEventBus.addListener(ModelHolder::onEndClientResourceReload);
|
||||
|
||||
modEventBus.addListener(PartialModel::onModelRegistry);
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
package com.jozufozu.flywheel.lib.mixin;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
|
||||
import net.minecraft.client.model.geom.ModelPart;
|
||||
|
||||
@Mixin(ModelPart.class)
|
||||
public interface ModelPartAccessor {
|
||||
@Accessor("children")
|
||||
Map<String, ModelPart> flywheel$children();
|
||||
|
||||
@Invoker("compile")
|
||||
void flywheel$compile(PoseStack.Pose pPose, VertexConsumer pVertexConsumer, int pPackedLight, int pPackedOverlay, float pRed, float pGreen, float pBlue, float pAlpha);
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package com.jozufozu.flywheel.vanilla.mixin;
|
||||
package com.jozufozu.flywheel.lib.mixin;
|
||||
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
|
@ -1,4 +1,4 @@
|
|||
package com.jozufozu.flywheel.vanilla.model;
|
||||
package com.jozufozu.flywheel.lib.model;
|
||||
|
||||
import org.joml.Vector4fc;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.jozufozu.flywheel.vanilla.model;
|
||||
package com.jozufozu.flywheel.lib.model;
|
||||
|
||||
import com.jozufozu.flywheel.api.vertex.MutableVertexList;
|
||||
import com.jozufozu.flywheel.lib.vertex.WrappedVertexList;
|
|
@ -1,4 +1,4 @@
|
|||
package com.jozufozu.flywheel.vanilla.model;
|
||||
package com.jozufozu.flywheel.lib.model.part;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
114
src/main/java/com/jozufozu/flywheel/lib/model/part/MeshTree.java
Normal file
114
src/main/java/com/jozufozu/flywheel/lib/model/part/MeshTree.java
Normal file
|
@ -0,0 +1,114 @@
|
|||
package com.jozufozu.flywheel.lib.model.part;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.jozufozu.flywheel.api.event.EndClientResourceReloadEvent;
|
||||
import com.jozufozu.flywheel.api.model.Mesh;
|
||||
import com.jozufozu.flywheel.lib.mixin.ModelPartAccessor;
|
||||
import com.jozufozu.flywheel.lib.model.SimpleMesh;
|
||||
import com.jozufozu.flywheel.lib.vertex.PosTexNormalVertexView;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
|
||||
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.model.geom.PartPose;
|
||||
|
||||
public class MeshTree {
|
||||
private static final ThreadLocal<ThreadLocalObjects> THREAD_LOCAL_OBJECTS = ThreadLocal.withInitial(ThreadLocalObjects::new);
|
||||
private static final PoseStack.Pose IDENTITY = new PoseStack().last();
|
||||
private static final Map<ModelLayerLocation, MeshTree> MESH_TREES = new ConcurrentHashMap<>();
|
||||
|
||||
private final PartPose initialPose;
|
||||
@Nullable
|
||||
private final Mesh mesh;
|
||||
private final Map<String, MeshTree> children;
|
||||
|
||||
private MeshTree(PartPose initialPose, @Nullable Mesh mesh, Map<String, MeshTree> children) {
|
||||
this.initialPose = initialPose;
|
||||
this.mesh = mesh;
|
||||
this.children = children;
|
||||
}
|
||||
|
||||
public static MeshTree get(ModelLayerLocation key) {
|
||||
return MESH_TREES.computeIfAbsent(key, MeshTree::convert);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static void onEndClientResourceReload(EndClientResourceReloadEvent event) {
|
||||
MESH_TREES.values()
|
||||
.forEach(MeshTree::delete);
|
||||
MESH_TREES.clear();
|
||||
}
|
||||
|
||||
public PartPose initialPose() {
|
||||
return initialPose;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Mesh mesh() {
|
||||
return mesh;
|
||||
}
|
||||
|
||||
public Map<String, MeshTree> children() {
|
||||
return children;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public MeshTree child(String name) {
|
||||
return children.get(name);
|
||||
}
|
||||
|
||||
public void delete() {
|
||||
if (mesh != null) {
|
||||
mesh.delete();
|
||||
}
|
||||
children.values()
|
||||
.forEach(MeshTree::delete);
|
||||
}
|
||||
|
||||
public static MeshTree convert(ModelLayerLocation location) {
|
||||
EntityModelSet entityModels = Minecraft.getInstance()
|
||||
.getEntityModels();
|
||||
ModelPart modelPart = entityModels.bakeLayer(location);
|
||||
|
||||
return convert(modelPart, THREAD_LOCAL_OBJECTS.get());
|
||||
}
|
||||
|
||||
private static MeshTree convert(ModelPart modelPart, ThreadLocalObjects objects) {
|
||||
var accessor = cast(modelPart);
|
||||
var childModelParts = accessor.flywheel$children();
|
||||
|
||||
Map<String, MeshTree> children = new HashMap<>();
|
||||
|
||||
for (Map.Entry<String, ModelPart> entry : childModelParts.entrySet()) {
|
||||
children.put(entry.getKey(), convert(entry.getValue(), objects));
|
||||
}
|
||||
|
||||
return new MeshTree(modelPart.getInitialPose(), compile(accessor, objects), children);
|
||||
}
|
||||
|
||||
private static Mesh compile(ModelPartAccessor accessor, ThreadLocalObjects objects) {
|
||||
var vertexWriter = objects.vertexWriter;
|
||||
|
||||
accessor.flywheel$compile(IDENTITY, vertexWriter, 0, 0, 1.0F, 1.0F, 1.0F, 1.0F);
|
||||
|
||||
var data = vertexWriter.copyDataAndReset();
|
||||
|
||||
return new SimpleMesh(new PosTexNormalVertexView(), data, "source=ModelPartConverter");
|
||||
}
|
||||
|
||||
private static ModelPartAccessor cast(ModelPart cube) {
|
||||
return (ModelPartAccessor) (Object) cube;
|
||||
}
|
||||
|
||||
private static class ThreadLocalObjects {
|
||||
public final VertexWriter vertexWriter = new VertexWriter();
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
package com.jozufozu.flywheel.vanilla;
|
||||
|
||||
import com.jozufozu.flywheel.vanilla.model.InstanceTree;
|
||||
import com.jozufozu.flywheel.lib.model.part.InstanceTree;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
|
||||
public abstract class AgeableListComponent {
|
||||
|
|
|
@ -15,12 +15,12 @@ import com.jozufozu.flywheel.lib.instance.OrientedInstance;
|
|||
import com.jozufozu.flywheel.lib.instance.TransformedInstance;
|
||||
import com.jozufozu.flywheel.lib.material.Materials;
|
||||
import com.jozufozu.flywheel.lib.model.ModelCache;
|
||||
import com.jozufozu.flywheel.lib.model.RetexturedMesh;
|
||||
import com.jozufozu.flywheel.lib.model.SingleMeshModel;
|
||||
import com.jozufozu.flywheel.lib.model.part.MeshTree;
|
||||
import com.jozufozu.flywheel.lib.util.Pair;
|
||||
import com.jozufozu.flywheel.lib.visual.AbstractBlockEntityVisual;
|
||||
import com.jozufozu.flywheel.lib.visual.SimpleDynamicVisual;
|
||||
import com.jozufozu.flywheel.vanilla.model.MeshTreeCache;
|
||||
import com.jozufozu.flywheel.vanilla.model.RetexturedMesh;
|
||||
|
||||
import it.unimi.dsi.fastutil.floats.Float2FloatFunction;
|
||||
import net.minecraft.client.model.geom.ModelLayerLocation;
|
||||
|
@ -173,7 +173,7 @@ public class ChestVisual<T extends BlockEntity & LidBlockEntity> extends Abstrac
|
|||
}
|
||||
|
||||
public static Model chestModel(Pair<ChestType, Material> key, String child) {
|
||||
var mesh = MeshTreeCache.get(LAYER_LOCATIONS.get(key.first()))
|
||||
var mesh = MeshTree.get(LAYER_LOCATIONS.get(key.first()))
|
||||
.child(child)
|
||||
.mesh();
|
||||
var sprite = key.second()
|
||||
|
|
|
@ -4,8 +4,8 @@ import java.util.List;
|
|||
|
||||
import com.jozufozu.flywheel.api.instance.InstancerProvider;
|
||||
import com.jozufozu.flywheel.api.material.Material;
|
||||
import com.jozufozu.flywheel.vanilla.model.InstanceTree;
|
||||
import com.jozufozu.flywheel.vanilla.model.MeshTreeCache;
|
||||
import com.jozufozu.flywheel.lib.model.part.InstanceTree;
|
||||
import com.jozufozu.flywheel.lib.model.part.MeshTree;
|
||||
|
||||
import net.minecraft.client.model.geom.ModelLayerLocation;
|
||||
import net.minecraft.util.Mth;
|
||||
|
@ -23,7 +23,7 @@ public class QuadrupedComponent extends AgeableListComponent {
|
|||
public QuadrupedComponent(InstancerProvider instancerProvider, ModelLayerLocation layer, Material material, Config config) {
|
||||
super(config);
|
||||
|
||||
var meshTree = MeshTreeCache.get(layer);
|
||||
var meshTree = MeshTree.get(layer);
|
||||
|
||||
this.root = InstanceTree.create(instancerProvider, meshTree, material);
|
||||
|
||||
|
|
|
@ -11,12 +11,12 @@ import com.jozufozu.flywheel.lib.instance.InstanceTypes;
|
|||
import com.jozufozu.flywheel.lib.instance.TransformedInstance;
|
||||
import com.jozufozu.flywheel.lib.material.Materials;
|
||||
import com.jozufozu.flywheel.lib.model.ModelCache;
|
||||
import com.jozufozu.flywheel.lib.model.RetexturedMesh;
|
||||
import com.jozufozu.flywheel.lib.model.SingleMeshModel;
|
||||
import com.jozufozu.flywheel.lib.model.part.MeshTree;
|
||||
import com.jozufozu.flywheel.lib.transform.TransformStack;
|
||||
import com.jozufozu.flywheel.lib.visual.AbstractBlockEntityVisual;
|
||||
import com.jozufozu.flywheel.lib.visual.SimpleDynamicVisual;
|
||||
import com.jozufozu.flywheel.vanilla.model.MeshTreeCache;
|
||||
import com.jozufozu.flywheel.vanilla.model.RetexturedMesh;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.math.Axis;
|
||||
|
||||
|
@ -138,7 +138,7 @@ public class ShulkerBoxVisual extends AbstractBlockEntityVisual<ShulkerBoxBlockE
|
|||
}
|
||||
|
||||
private static Model shulkerModel(Material texture, String child) {
|
||||
var mesh = MeshTreeCache.get(ModelLayers.SHULKER)
|
||||
var mesh = MeshTree.get(ModelLayers.SHULKER)
|
||||
.child(child)
|
||||
.mesh();
|
||||
return new SingleMeshModel(new RetexturedMesh(mesh, texture.sprite()), Materials.SHULKER);
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
package com.jozufozu.flywheel.vanilla.mixin;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.joml.Vector3f;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import net.minecraft.client.model.geom.builders.CubeDefinition;
|
||||
import net.minecraft.client.model.geom.builders.CubeDeformation;
|
||||
import net.minecraft.client.model.geom.builders.UVPair;
|
||||
import net.minecraft.core.Direction;
|
||||
|
||||
@Mixin(CubeDefinition.class)
|
||||
public interface CubeDefinitionAccessor {
|
||||
@Accessor("origin")
|
||||
Vector3f vanillin$origin();
|
||||
|
||||
@Accessor("dimensions")
|
||||
Vector3f vanillin$dimensions();
|
||||
|
||||
@Accessor("grow")
|
||||
CubeDeformation vanillin$grow();
|
||||
|
||||
@Accessor("mirror")
|
||||
boolean vanillin$mirror();
|
||||
|
||||
@Accessor("texCoord")
|
||||
UVPair vanillin$texCoord();
|
||||
|
||||
@Accessor("texScale")
|
||||
UVPair vanillin$texScale();
|
||||
|
||||
@Accessor("visibleFaces")
|
||||
Set<Direction> vanillin$visibleFaces();
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
package com.jozufozu.flywheel.vanilla.mixin;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import net.minecraft.client.model.geom.builders.CubeDeformation;
|
||||
|
||||
@Mixin(CubeDeformation.class)
|
||||
public interface CubeDeformationAccessor {
|
||||
@Accessor("growX")
|
||||
float vanillin$growX();
|
||||
|
||||
@Accessor("growY")
|
||||
float vanillin$growY();
|
||||
|
||||
@Accessor("growZ")
|
||||
float vanillin$growZ();
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
package com.jozufozu.flywheel.vanilla.mixin;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import net.minecraft.client.model.geom.EntityModelSet;
|
||||
import net.minecraft.client.model.geom.ModelLayerLocation;
|
||||
import net.minecraft.client.model.geom.builders.LayerDefinition;
|
||||
|
||||
@Mixin(EntityModelSet.class)
|
||||
public interface EntityModelSetAccessor {
|
||||
@Accessor("roots")
|
||||
Map<ModelLayerLocation, LayerDefinition> vanillin$roots();
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
package com.jozufozu.flywheel.vanilla.mixin;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import net.minecraft.client.model.geom.builders.LayerDefinition;
|
||||
import net.minecraft.client.model.geom.builders.MaterialDefinition;
|
||||
import net.minecraft.client.model.geom.builders.MeshDefinition;
|
||||
|
||||
@Mixin(LayerDefinition.class)
|
||||
public interface LayerDefinitionAccessor {
|
||||
@Accessor("mesh")
|
||||
MeshDefinition vanillin$mesh();
|
||||
|
||||
@Accessor("material")
|
||||
MaterialDefinition vanillin$material();
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
package com.jozufozu.flywheel.vanilla.mixin;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import net.minecraft.client.model.geom.builders.MaterialDefinition;
|
||||
|
||||
@Mixin(MaterialDefinition.class)
|
||||
public interface MaterialDefinitionAccessor {
|
||||
@Accessor("xTexSize")
|
||||
int vanillin$xTexSize();
|
||||
|
||||
@Accessor("yTexSize")
|
||||
int vanillin$yTexSize();
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
package com.jozufozu.flywheel.vanilla.mixin;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import net.minecraft.client.model.geom.PartPose;
|
||||
import net.minecraft.client.model.geom.builders.CubeDefinition;
|
||||
import net.minecraft.client.model.geom.builders.PartDefinition;
|
||||
|
||||
@Mixin(PartDefinition.class)
|
||||
public interface PartDefinitionAccessor {
|
||||
@Accessor("cubes")
|
||||
List<CubeDefinition> vanillin$cubes();
|
||||
|
||||
@Accessor("partPose")
|
||||
PartPose vanillin$partPose();
|
||||
|
||||
@Accessor("children")
|
||||
Map<String, PartDefinition> vanillin$children();
|
||||
}
|
|
@ -1,281 +0,0 @@
|
|||
package com.jozufozu.flywheel.vanilla.model;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.jozufozu.flywheel.api.model.Mesh;
|
||||
import com.jozufozu.flywheel.lib.memory.MemoryBlock;
|
||||
import com.jozufozu.flywheel.lib.model.SimpleMesh;
|
||||
import com.jozufozu.flywheel.lib.vertex.PosTexNormalVertexView;
|
||||
import com.jozufozu.flywheel.vanilla.mixin.CubeDefinitionAccessor;
|
||||
import com.jozufozu.flywheel.vanilla.mixin.CubeDeformationAccessor;
|
||||
import com.jozufozu.flywheel.vanilla.mixin.EntityModelSetAccessor;
|
||||
import com.jozufozu.flywheel.vanilla.mixin.LayerDefinitionAccessor;
|
||||
import com.jozufozu.flywheel.vanilla.mixin.MaterialDefinitionAccessor;
|
||||
import com.jozufozu.flywheel.vanilla.mixin.PartDefinitionAccessor;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.model.geom.ModelLayerLocation;
|
||||
import net.minecraft.client.model.geom.PartPose;
|
||||
import net.minecraft.client.model.geom.builders.CubeDefinition;
|
||||
import net.minecraft.client.model.geom.builders.LayerDefinition;
|
||||
import net.minecraft.client.model.geom.builders.PartDefinition;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
public class MeshTree {
|
||||
private final PartPose initialPose;
|
||||
@Nullable
|
||||
private final Mesh mesh;
|
||||
private final Map<String, MeshTree> children;
|
||||
|
||||
private MeshTree(PartPose initialPose, @Nullable Mesh mesh, Map<String, MeshTree> children) {
|
||||
this.initialPose = initialPose;
|
||||
this.mesh = mesh;
|
||||
this.children = children;
|
||||
}
|
||||
|
||||
public PartPose initialPose() {
|
||||
return initialPose;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Mesh mesh() {
|
||||
return mesh;
|
||||
}
|
||||
|
||||
public Map<String, MeshTree> children() {
|
||||
return children;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public MeshTree child(String name) {
|
||||
return children.get(name);
|
||||
}
|
||||
|
||||
public void delete() {
|
||||
if (mesh != null) {
|
||||
mesh.delete();
|
||||
}
|
||||
children.values()
|
||||
.forEach(MeshTree::delete);
|
||||
}
|
||||
|
||||
public static MeshTree convert(ModelLayerLocation location) {
|
||||
var entityModels = (EntityModelSetAccessor) Minecraft.getInstance()
|
||||
.getEntityModels();
|
||||
|
||||
return convert(entityModels.vanillin$roots()
|
||||
.get(location));
|
||||
}
|
||||
|
||||
public static MeshTree convert(LayerDefinition layerDefinition) {
|
||||
var accessor = (LayerDefinitionAccessor) layerDefinition;
|
||||
var root = accessor.vanillin$mesh()
|
||||
.getRoot();
|
||||
|
||||
var material = (MaterialDefinitionAccessor) accessor.vanillin$material();
|
||||
|
||||
int xTexSize = material.vanillin$xTexSize();
|
||||
int yTexSize = material.vanillin$yTexSize();
|
||||
|
||||
return convert(root, xTexSize, yTexSize);
|
||||
}
|
||||
|
||||
private static MeshTree convert(PartDefinition part, int xTexSize, int yTexSize) {
|
||||
var accessor = (PartDefinitionAccessor) part;
|
||||
|
||||
var cubes = accessor.vanillin$cubes();
|
||||
var initialPose = accessor.vanillin$partPose();
|
||||
var childDefinitions = accessor.vanillin$children();
|
||||
|
||||
Map<String, MeshTree> children = new HashMap<>();
|
||||
|
||||
for (Map.Entry<String, PartDefinition> entry : childDefinitions.entrySet()) {
|
||||
children.put(entry.getKey(), convert(entry.getValue(), xTexSize, yTexSize));
|
||||
}
|
||||
|
||||
return new MeshTree(initialPose, convertCubes(cubes, xTexSize, yTexSize), children);
|
||||
}
|
||||
|
||||
private static Mesh convertCubes(List<CubeDefinition> cubes, int xTexSize, int yTexSize) {
|
||||
if (cubes.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
var totalVisibleFaces = countVisibleFaces(cubes);
|
||||
|
||||
if (totalVisibleFaces == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var totalVertices = totalVisibleFaces * 4;
|
||||
|
||||
var block = MemoryBlock.malloc(totalVertices * PosTexNormalVertexView.STRIDE);
|
||||
var view = new PosTexNormalVertexView();
|
||||
|
||||
view.ptr(block.ptr());
|
||||
view.vertexCount(totalVertices);
|
||||
|
||||
int vertexIndex = 0;
|
||||
for (CubeDefinition cube : cubes) {
|
||||
CubeDefinitionAccessor accessor = cast(cube);
|
||||
|
||||
var origin = accessor.vanillin$origin();
|
||||
var dimensions = accessor.vanillin$dimensions();
|
||||
var grow = (CubeDeformationAccessor) accessor.vanillin$grow();
|
||||
var pMirror = accessor.vanillin$mirror();
|
||||
var texCoord = accessor.vanillin$texCoord();
|
||||
var texScale = accessor.vanillin$texScale();
|
||||
|
||||
var visibleFaces = accessor.vanillin$visibleFaces();
|
||||
|
||||
float pOriginX = origin.x();
|
||||
float pOriginY = origin.y();
|
||||
float pOriginZ = origin.z();
|
||||
|
||||
float pDimensionX = dimensions.x();
|
||||
float pDimensionY = dimensions.y();
|
||||
float pDimensionZ = dimensions.z();
|
||||
|
||||
float pGrowX = grow.vanillin$growX();
|
||||
float pGrowY = grow.vanillin$growY();
|
||||
float pGrowZ = grow.vanillin$growZ();
|
||||
|
||||
float pTexCoordU = texCoord.u();
|
||||
float pTexCoordV = texCoord.v();
|
||||
|
||||
float pTexScaleU = xTexSize * texScale.u();
|
||||
float pTexScaleV = yTexSize * texScale.v();
|
||||
|
||||
float f = pOriginX + pDimensionX;
|
||||
float f1 = pOriginY + pDimensionY;
|
||||
float f2 = pOriginZ + pDimensionZ;
|
||||
pOriginX -= pGrowX;
|
||||
pOriginY -= pGrowY;
|
||||
pOriginZ -= pGrowZ;
|
||||
f += pGrowX;
|
||||
f1 += pGrowY;
|
||||
f2 += pGrowZ;
|
||||
if (pMirror) {
|
||||
float f3 = f;
|
||||
f = pOriginX;
|
||||
pOriginX = f3;
|
||||
}
|
||||
|
||||
Vertex modelpart$vertex7 = new Vertex(pOriginX, pOriginY, pOriginZ, 0.0F, 0.0F);
|
||||
Vertex modelpart$vertex = new Vertex(f, pOriginY, pOriginZ, 0.0F, 8.0F);
|
||||
Vertex modelpart$vertex1 = new Vertex(f, f1, pOriginZ, 8.0F, 8.0F);
|
||||
Vertex modelpart$vertex2 = new Vertex(pOriginX, f1, pOriginZ, 8.0F, 0.0F);
|
||||
Vertex modelpart$vertex3 = new Vertex(pOriginX, pOriginY, f2, 0.0F, 0.0F);
|
||||
Vertex modelpart$vertex4 = new Vertex(f, pOriginY, f2, 0.0F, 8.0F);
|
||||
Vertex modelpart$vertex5 = new Vertex(f, f1, f2, 8.0F, 8.0F);
|
||||
Vertex modelpart$vertex6 = new Vertex(pOriginX, f1, f2, 8.0F, 0.0F);
|
||||
float f4 = pTexCoordU;
|
||||
float f5 = pTexCoordU + pDimensionZ;
|
||||
float f6 = pTexCoordU + pDimensionZ + pDimensionX;
|
||||
float f7 = pTexCoordU + pDimensionZ + pDimensionX + pDimensionX;
|
||||
float f8 = pTexCoordU + pDimensionZ + pDimensionX + pDimensionZ;
|
||||
float f9 = pTexCoordU + pDimensionZ + pDimensionX + pDimensionZ + pDimensionX;
|
||||
float f10 = pTexCoordV;
|
||||
float f11 = pTexCoordV + pDimensionZ;
|
||||
float f12 = pTexCoordV + pDimensionZ + pDimensionY;
|
||||
if (visibleFaces.contains(Direction.DOWN)) {
|
||||
addFace(view, vertexIndex, new Vertex[]{modelpart$vertex4, modelpart$vertex3, modelpart$vertex7, modelpart$vertex}, f5, f10, f6, f11, pTexScaleU, pTexScaleV, pMirror, Direction.DOWN);
|
||||
vertexIndex += 4;
|
||||
}
|
||||
|
||||
if (visibleFaces.contains(Direction.UP)) {
|
||||
addFace(view, vertexIndex, new Vertex[]{modelpart$vertex1, modelpart$vertex2, modelpart$vertex6, modelpart$vertex5}, f6, f11, f7, f10, pTexScaleU, pTexScaleV, pMirror, Direction.UP);
|
||||
vertexIndex += 4;
|
||||
}
|
||||
|
||||
if (visibleFaces.contains(Direction.WEST)) {
|
||||
addFace(view, vertexIndex, new Vertex[]{modelpart$vertex7, modelpart$vertex3, modelpart$vertex6, modelpart$vertex2}, f4, f11, f5, f12, pTexScaleU, pTexScaleV, pMirror, Direction.WEST);
|
||||
vertexIndex += 4;
|
||||
}
|
||||
|
||||
if (visibleFaces.contains(Direction.NORTH)) {
|
||||
addFace(view, vertexIndex, new Vertex[]{modelpart$vertex, modelpart$vertex7, modelpart$vertex2, modelpart$vertex1}, f5, f11, f6, f12, pTexScaleU, pTexScaleV, pMirror, Direction.NORTH);
|
||||
vertexIndex += 4;
|
||||
}
|
||||
|
||||
if (visibleFaces.contains(Direction.EAST)) {
|
||||
addFace(view, vertexIndex, new Vertex[]{modelpart$vertex4, modelpart$vertex, modelpart$vertex1, modelpart$vertex5}, f6, f11, f8, f12, pTexScaleU, pTexScaleV, pMirror, Direction.EAST);
|
||||
vertexIndex += 4;
|
||||
}
|
||||
|
||||
if (visibleFaces.contains(Direction.SOUTH)) {
|
||||
addFace(view, vertexIndex, new Vertex[]{modelpart$vertex3, modelpart$vertex4, modelpart$vertex5, modelpart$vertex6}, f8, f11, f9, f12, pTexScaleU, pTexScaleV, pMirror, Direction.SOUTH);
|
||||
vertexIndex += 4;
|
||||
}
|
||||
}
|
||||
|
||||
return new SimpleMesh(view, block);
|
||||
}
|
||||
|
||||
private static void addFace(PosTexNormalVertexView view, int index, Vertex[] pVertices, float pU1, float pV1, float pU2, float pV2, float pTextureWidth, float pTextureHeight, boolean pMirror, Direction pDirection) {
|
||||
float f = 0.0F / pTextureWidth;
|
||||
float f1 = 0.0F / pTextureHeight;
|
||||
pVertices[0] = pVertices[0].remap(pU2 / pTextureWidth - f, pV1 / pTextureHeight + f1);
|
||||
pVertices[1] = pVertices[1].remap(pU1 / pTextureWidth + f, pV1 / pTextureHeight + f1);
|
||||
pVertices[2] = pVertices[2].remap(pU1 / pTextureWidth + f, pV2 / pTextureHeight - f1);
|
||||
pVertices[3] = pVertices[3].remap(pU2 / pTextureWidth - f, pV2 / pTextureHeight - f1);
|
||||
if (pMirror) {
|
||||
int i = pVertices.length;
|
||||
|
||||
for (int j = 0; j < i / 2; ++j) {
|
||||
Vertex modelpart$vertex = pVertices[j];
|
||||
pVertices[j] = pVertices[i - 1 - j];
|
||||
pVertices[i - 1 - j] = modelpart$vertex;
|
||||
}
|
||||
}
|
||||
|
||||
var normal = pDirection.step();
|
||||
if (pMirror) {
|
||||
normal.mul(-1.0F, 1.0F, 1.0F);
|
||||
}
|
||||
|
||||
int i = index;
|
||||
for (Vertex modelpart$vertex : pVertices) {
|
||||
float f3 = modelpart$vertex.x() / 16.0F;
|
||||
float f4 = modelpart$vertex.y() / 16.0F;
|
||||
float f5 = modelpart$vertex.z() / 16.0F;
|
||||
view.x(i, f3);
|
||||
view.y(i, f4);
|
||||
view.z(i, f5);
|
||||
view.u(i, modelpart$vertex.u());
|
||||
view.v(i, modelpart$vertex.v());
|
||||
view.normalX(i, normal.x());
|
||||
view.normalY(i, normal.y());
|
||||
view.normalZ(i, normal.z());
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
private static int countVisibleFaces(List<CubeDefinition> cubes) {
|
||||
int totalVisibleFaces = 0;
|
||||
for (CubeDefinition cube : cubes) {
|
||||
totalVisibleFaces += cast(cube).vanillin$visibleFaces()
|
||||
.size();
|
||||
}
|
||||
return totalVisibleFaces;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static CubeDefinitionAccessor cast(CubeDefinition cube) {
|
||||
return (CubeDefinitionAccessor) (Object) cube;
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
record Vertex(float x, float y, float z, float u, float v) {
|
||||
public Vertex remap(float pU, float pV) {
|
||||
return new Vertex(x, y, z, pU, pV);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
package com.jozufozu.flywheel.vanilla.model;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import com.jozufozu.flywheel.api.event.EndClientResourceReloadEvent;
|
||||
|
||||
import net.minecraft.client.model.geom.ModelLayerLocation;
|
||||
|
||||
public class MeshTreeCache {
|
||||
private static final Map<ModelLayerLocation, MeshTree> MESH_TREES = new ConcurrentHashMap<>();
|
||||
|
||||
public static MeshTree get(ModelLayerLocation key) {
|
||||
return MESH_TREES.computeIfAbsent(key, MeshTree::convert);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static void onEndClientResourceReload(EndClientResourceReloadEvent event) {
|
||||
MESH_TREES.values()
|
||||
.forEach(MeshTree::delete);
|
||||
MESH_TREES.clear();
|
||||
}
|
||||
|
||||
private MeshTreeCache() {
|
||||
}
|
||||
}
|
14
src/main/resources/flywheel.lib.mixins.json
Normal file
14
src/main/resources/flywheel.lib.mixins.json
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"required" : true,
|
||||
"minVersion" : "0.8",
|
||||
"package" : "com.jozufozu.flywheel.lib.mixin",
|
||||
"compatibilityLevel" : "JAVA_17",
|
||||
"refmap" : "flywheel.refmap.json",
|
||||
"client" : [
|
||||
"ModelPartAccessor",
|
||||
"VertexMultiConsumerDoubleMixin"
|
||||
],
|
||||
"injectors" : {
|
||||
"defaultRequire" : 1
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
{
|
||||
"required" : true,
|
||||
"minVersion" : "0.8",
|
||||
"package" : "com.jozufozu.flywheel.vanilla.mixin",
|
||||
"compatibilityLevel" : "JAVA_17",
|
||||
"refmap" : "flywheel.refmap.json",
|
||||
"client" : [
|
||||
"CubeDefinitionAccessor",
|
||||
"CubeDeformationAccessor",
|
||||
"EntityModelSetAccessor",
|
||||
"LayerDefinitionAccessor",
|
||||
"MaterialDefinitionAccessor",
|
||||
"PartDefinitionAccessor",
|
||||
"VertexMultiConsumerDoubleMixin"
|
||||
],
|
||||
"injectors" : {
|
||||
"defaultRequire" : 1
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue