🦈 GET ROTATED Idiot 🦈
This commit is contained in:
parent
e1408c5a7a
commit
338e45d016
@ -16,14 +16,13 @@ Template blocks can be placed in the world, then right-clicked with a full-size
|
|||||||
|
|
||||||
## Todo
|
## Todo
|
||||||
|
|
||||||
|
* Fix the item model lol, broke it with the new system (might need a ModelLoadingRegistry registerVariantProvider as a last resort)
|
||||||
* Re-generalize the model system (I removed a layer of indirection while rewriting it, so it's just slopes now)
|
* Re-generalize the model system (I removed a layer of indirection while rewriting it, so it's just slopes now)
|
||||||
* See what I can do about using the vanilla rotation system (`ModelBakeSettings.getRotation`) instead of manually rotating the `Mesh`
|
* Upside-down slopes would be nice...
|
||||||
* A simplification of the mesh system would *definitely* reduce the friction of adding new meshes (see all the `paintXxx` stuff in `SlopeMeshTransformer`, it's fairly ugly)
|
* Pass UVs as part of the mesh and retexture them at runtime too
|
||||||
* Upside-down slopes would be nice...
|
|
||||||
* (if i may): Packages-ish "retexturing" of json blockmodels
|
|
||||||
|
|
||||||
## Notes for addon developers
|
## Notes for addon developers
|
||||||
|
|
||||||
To create your block, instantiate or extend `TemplateBlock`. Pass your `Block.Settings` through `TemplateBlock.configureSettings` to wire up the "click for glowstone" feature. Create an `ItemBlock` as normal, and create a `BlockEntityType` by instantiating or extending `TemplateEntity`.
|
To create your block, instantiate or extend `TemplateBlock`. Pass your `Block.Settings` through `TemplateBlock.configureSettings` to wire up the "click for glowstone" feature. Create an `ItemBlock` as normal, and create a `BlockEntityType` by instantiating or extending `TemplateEntity`.
|
||||||
|
|
||||||
Next, wire up the custom model. im going to refactor this in like 5 seconds so im not documenting it >:).
|
Next, wire up the custom model todo document this, it's easy
|
@ -1,6 +1,5 @@
|
|||||||
package io.github.cottonmc.templates;
|
package io.github.cottonmc.templates;
|
||||||
|
|
||||||
import io.github.cottonmc.templates.block.SlopeBlock;
|
|
||||||
import io.github.cottonmc.templates.model.SlopeUnbakedModel;
|
import io.github.cottonmc.templates.model.SlopeUnbakedModel;
|
||||||
import io.github.cottonmc.templates.model.TemplateModelVariantProvider;
|
import io.github.cottonmc.templates.model.TemplateModelVariantProvider;
|
||||||
import net.fabricmc.api.ClientModInitializer;
|
import net.fabricmc.api.ClientModInitializer;
|
||||||
@ -14,7 +13,6 @@ import net.minecraft.resource.ResourceManager;
|
|||||||
import net.minecraft.resource.ResourceType;
|
import net.minecraft.resource.ResourceType;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.math.ChunkSectionPos;
|
import net.minecraft.util.math.ChunkSectionPos;
|
||||||
import net.minecraft.util.math.Direction;
|
|
||||||
|
|
||||||
public class TemplatesClient implements ClientModInitializer {
|
public class TemplatesClient implements ClientModInitializer {
|
||||||
public static TemplateModelVariantProvider provider = new TemplateModelVariantProvider();
|
public static TemplateModelVariantProvider provider = new TemplateModelVariantProvider();
|
||||||
@ -43,17 +41,10 @@ public class TemplatesClient implements ClientModInitializer {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ModelLoadingRegistry.INSTANCE.registerVariantProvider(rm -> provider);
|
ModelLoadingRegistry.INSTANCE.registerResourceProvider(rm -> provider);
|
||||||
|
|
||||||
BlockRenderLayerMap.INSTANCE.putBlock(Templates.SLOPE, RenderLayer.getCutout());
|
BlockRenderLayerMap.INSTANCE.putBlock(Templates.SLOPE, RenderLayer.getCutout());
|
||||||
|
|
||||||
//ADDON DEVELOEPRS: do this!
|
provider.addTemplateModel(Templates.id("slope_special"), SlopeUnbakedModel::new);
|
||||||
provider.registerTemplateModels(
|
|
||||||
//block
|
|
||||||
Templates.SLOPE,
|
|
||||||
//the blockstate you'd like the item model to show
|
|
||||||
Templates.SLOPE.getDefaultState().with(SlopeBlock.FACING, Direction.EAST),
|
|
||||||
//Function<BlockState, UnbakedModel> that creates your model
|
|
||||||
SlopeUnbakedModel::new
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,6 @@ package io.github.cottonmc.templates.model;
|
|||||||
import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView;
|
import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView;
|
||||||
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
|
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
|
||||||
import net.minecraft.util.math.AffineTransformation;
|
import net.minecraft.util.math.AffineTransformation;
|
||||||
import net.minecraft.util.math.AffineTransformations;
|
|
||||||
import net.minecraft.util.math.Direction;
|
|
||||||
import org.joml.Matrix4f;
|
import org.joml.Matrix4f;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
import org.joml.Vector4f;
|
import org.joml.Vector4f;
|
||||||
@ -16,40 +14,36 @@ public record AffineQuadTransformer(Matrix4f affineMatrix) implements RenderCont
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean transform(MutableQuadView quad) {
|
public boolean transform(MutableQuadView quad) {
|
||||||
Matrix4f mat = affineMatrix;
|
|
||||||
//TODO: Hard Coded for DEBUGGING
|
|
||||||
mat = (
|
|
||||||
AffineTransformations.DIRECTION_ROTATIONS.get(Direction.NORTH)
|
|
||||||
).getMatrix();
|
|
||||||
|
|
||||||
Vector3f pos3 = new Vector3f();
|
Vector3f pos3 = new Vector3f();
|
||||||
//Vector3f norm3 = new Vector3f();
|
Vector3f norm3 = new Vector3f();
|
||||||
|
|
||||||
//ugh
|
//ugh
|
||||||
Vector4f pos4 = new Vector4f();
|
Vector4f pos4 = new Vector4f();
|
||||||
//Vector4f norm4 = new Vector4f();
|
Vector4f norm4 = new Vector4f();
|
||||||
|
|
||||||
for(int i = 0; i < 4; i++) {
|
for(int i = 0; i < 4; i++) {
|
||||||
//Copy quad data into vec3's
|
//Copy quad data into vec3's
|
||||||
quad.copyPos(i, pos3);
|
quad.copyPos(i, pos3);
|
||||||
//quad.copyNormal(i, norm3);
|
quad.copyNormal(i, norm3);
|
||||||
|
|
||||||
pos3.add(-0.5f, -0.5f, -0.5f); //TODO HACK
|
pos3.add(-0.5f, -0.5f, -0.5f); //TODO, kinda a hack to center the affine transformation not at 0,0,0
|
||||||
|
|
||||||
//Initialize the x/y/z components of vec4s using that data
|
//Initialize the x/y/z components of vec4s using that data
|
||||||
//W component of normal vector is set to 1, normal vectors transform differently from points :)
|
//W component of normal vector is set to 1, normal vectors transform differently from points :)
|
||||||
pos4.set(pos3, 0);
|
pos4.set(pos3, 0);
|
||||||
//norm4.set(norm3, 1);
|
norm4.set(norm3, 1);
|
||||||
|
|
||||||
//Compute the matrix-vector product. This function mutates the vec4 in-place.
|
//Compute the matrix-vector product. This function mutates the vec4 in-place.
|
||||||
//Note that `transformAffine` has the same purpose as `transform`; the difference is it
|
//Note that `transformAffine` has the same purpose as `transform`; the difference is it
|
||||||
//assumes (without checking) that the last row of the matrix is 0,0,0,1, as an optimization
|
//assumes (without checking) that the last row of the matrix is 0,0,0,1, as an optimization
|
||||||
mat.transformAffine(pos4);
|
affineMatrix.transformAffine(pos4);
|
||||||
//mat.transformAffine(norm4);
|
affineMatrix.transformAffine(norm4);
|
||||||
|
|
||||||
//Manually copy the data back onto the vertex
|
//Manually copy the data back onto the vertex
|
||||||
quad.pos(i, pos4.x + 0.5f, pos4.y + 0.5f, pos4.z + 0.5f);
|
quad.pos(i, pos4.x + 0.5f, pos4.y + 0.5f, pos4.z + 0.5f);
|
||||||
//quad.normal(i, norm4.x, norm4.y + 1, norm4.z);
|
|
||||||
|
//TODO: makes everything turn black for some reason (norm vec is (0, 0, 0))
|
||||||
|
//quad.normal(i, norm4.x, norm4.y, norm4.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -17,12 +17,12 @@ import java.util.function.Function;
|
|||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public final class SlopeBakedModel extends ForwardingBakedModel {
|
public final class SlopeBakedModel extends ForwardingBakedModel {
|
||||||
public SlopeBakedModel(BakedModel baseModel, BlockState slopeState, AffineTransformation aff, Function<SpriteIdentifier, Sprite> spriteLookup) {
|
public SlopeBakedModel(BakedModel baseModel, Function<SpriteIdentifier, Sprite> spriteLookup, AffineTransformation aff) {
|
||||||
this.wrapped = baseModel;
|
this.wrapped = baseModel;
|
||||||
|
|
||||||
this.preparer = new SlopeMeshTransformPreparer(spriteLookup);
|
this.preparer = new SlopeMeshTransformPreparer(spriteLookup);
|
||||||
this.affineTransformer = new AffineQuadTransformer(aff);
|
this.affineTransformer = new AffineQuadTransformer(aff);
|
||||||
this.baseMesh = SlopeBaseMesh.make(slopeState.getBlock().getDefaultState()); //TODO
|
this.baseMesh = SlopeBaseMesh.make();
|
||||||
}
|
}
|
||||||
|
|
||||||
private final TemplateQuadTransformPreparer preparer;
|
private final TemplateQuadTransformPreparer preparer;
|
||||||
|
@ -5,106 +5,25 @@ import net.fabricmc.fabric.api.renderer.v1.RendererAccess;
|
|||||||
import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh;
|
import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh;
|
||||||
import net.fabricmc.fabric.api.renderer.v1.mesh.MeshBuilder;
|
import net.fabricmc.fabric.api.renderer.v1.mesh.MeshBuilder;
|
||||||
import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter;
|
import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter;
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.state.property.Properties;
|
|
||||||
import net.minecraft.util.math.Direction;
|
|
||||||
|
|
||||||
public class SlopeBaseMesh {
|
public class SlopeBaseMesh {
|
||||||
public static Mesh make(BlockState state) {
|
|
||||||
Renderer renderer = RendererAccess.INSTANCE.getRenderer();
|
|
||||||
if(renderer == null) throw new IllegalStateException("RenderAccess.INSTANCE not populated - no Fabric Renderer API?");
|
|
||||||
|
|
||||||
final MeshBuilder builder = renderer.meshBuilder();
|
|
||||||
final QuadEmitter quad = builder.getEmitter();
|
|
||||||
final Direction dir = state.get(Properties.HORIZONTAL_FACING);
|
|
||||||
drawSlope(quad.color(-1, -1, -1, -1), dir);
|
|
||||||
drawLeftSide(quad.color(-1, -1, -1, -1), dir);
|
|
||||||
drawRightSide(quad.color(-1, -1, -1, -1), dir);
|
|
||||||
drawBack(quad.color(-1, -1, -1, -1), dir);
|
|
||||||
drawBottom(quad.color(-1, -1, -1, -1));
|
|
||||||
return builder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final int TAG_SLOPE = 0;
|
public static final int TAG_SLOPE = 0;
|
||||||
public static final int TAG_LEFT = 1;
|
public static final int TAG_LEFT = 1;
|
||||||
public static final int TAG_RIGHT = 2;
|
public static final int TAG_RIGHT = 2;
|
||||||
public static final int TAG_BACK = 3;
|
public static final int TAG_BACK = 3;
|
||||||
public static final int TAG_BOTTOM = 4;
|
public static final int TAG_BOTTOM = 4;
|
||||||
|
|
||||||
private static void drawSlope(QuadEmitter quad, Direction dir) {
|
public static Mesh make() {
|
||||||
quad.tag(TAG_SLOPE);
|
Renderer renderer = RendererAccess.INSTANCE.getRenderer();
|
||||||
switch(dir) {
|
if(renderer == null) throw new IllegalStateException("RenderAccess.INSTANCE not populated - no Fabric Renderer API?");
|
||||||
case NORTH:
|
|
||||||
quad.pos(0, 0f, 1f, 0f).pos(1, 0f, 0f, 1f).pos(2, 1f, 0f, 1f).pos(3, 1f, 1f, 0f).emit();
|
|
||||||
break;
|
|
||||||
case SOUTH:
|
|
||||||
quad.pos(0, 0f, 0f, 0f).pos(1, 0f, 1f, 1f).pos(2, 1f, 1f, 1f).pos(3, 1f, 0f, 0f).emit();
|
|
||||||
break;
|
|
||||||
case EAST:
|
|
||||||
quad.pos(0, 0f, 0f, 0f).pos(1, 0f, 0f, 1f).pos(2, 1f, 1f, 1f).pos(3, 1f, 1f, 0f).emit();
|
|
||||||
break;
|
|
||||||
case WEST:
|
|
||||||
quad.pos(0, 0f, 1f, 0f).pos(1, 0f, 1f, 1f).pos(2, 1f, 0f, 1f).pos(3, 1f, 0f, 0f).emit();
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void drawLeftSide(QuadEmitter quad, Direction dir) {
|
MeshBuilder builder = renderer.meshBuilder();
|
||||||
switch(dir) {
|
QuadEmitter qu = builder.getEmitter();
|
||||||
case NORTH:
|
qu.color(-1, -1, -1, -1).tag(TAG_SLOPE) .pos(0, 0f, 0f, 0f).pos(1, 0f, 1f, 1f).pos(2, 1f, 1f, 1f).pos(3, 1f, 0f, 0f).emit()
|
||||||
quad.tag(TAG_LEFT).pos(0, 0f, 0f, 0f).pos(1, 0f, 0f, 1f).pos(2, 0f, 0f, 1f).pos(3, 0f, 1f, 0f).emit();
|
.color(-1, -1, -1, -1).tag(TAG_LEFT) .pos(0, 1f, 0f, 0f).pos(1, 1f, 1f, 1f).pos(2, 1f, 0f, 1f).pos(3, 1f, 0f, 1f).emit()
|
||||||
break;
|
.color(-1, -1, -1, -1).tag(TAG_RIGHT) .pos(0, 0f, 0f, 0f).pos(1, 0f, 0f, 0f).pos(2, 0f, 0f, 1f).pos(3, 0f, 1f, 1f).emit()
|
||||||
case SOUTH:
|
.color(-1, -1, -1, -1).tag(TAG_BACK) .pos(0, 0f, 0f, 1f).pos(1, 1f, 0f, 1f).pos(2, 1f, 1f, 1f).pos(3, 0f, 1f, 1f).emit()
|
||||||
quad.tag(TAG_LEFT).pos(0, 1f, 0f, 0f).pos(1, 1f, 1f, 1f).pos(2, 1f, 0f, 1f).pos(3, 1f, 0f, 1f).emit();
|
.color(-1, -1, -1, -1).tag(TAG_BOTTOM).pos(0, 0f, 0f, 0f).pos(1, 1f, 0f, 0f).pos(2, 1f, 0f, 1f).pos(3, 0f, 0f, 1f).emit();
|
||||||
break;
|
return builder.build();
|
||||||
case EAST:
|
|
||||||
quad.tag(TAG_LEFT).pos(0, 1f, 0f, 0f).pos(1, 0f, 0f, 0f).pos(2, 0f, 0f, 0f).pos(3, 1f, 1f, 0f).emit();
|
|
||||||
break;
|
|
||||||
case WEST:
|
|
||||||
quad.tag(TAG_LEFT).pos(0, 0f, 0f, 1f).pos(1, 1f, 0f, 1f).pos(2, 1f, 0f, 1f).pos(3, 0f, 1f, 1f).emit();
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void drawRightSide(QuadEmitter quad, Direction dir) {
|
|
||||||
switch(dir) {
|
|
||||||
case NORTH:
|
|
||||||
quad.tag(TAG_RIGHT).pos(0, 1f, 0f, 0f).pos(1, 1f, 1f, 0f).pos(2, 1f, 0f, 1f).pos(3, 1f, 0f, 1f).emit();
|
|
||||||
break;
|
|
||||||
case SOUTH:
|
|
||||||
quad.tag(TAG_RIGHT).pos(0, 0f, 0f, 0f).pos(1, 0f, 0f, 0f).pos(2, 0f, 0f, 1f).pos(3, 0f, 1f, 1f).emit();
|
|
||||||
break;
|
|
||||||
case EAST:
|
|
||||||
quad.tag(TAG_RIGHT).pos(0, 0f, 0f, 1f).pos(1, 0f, 0f, 1f).pos(2, 1f, 0f, 1f).pos(3, 1f, 1f, 1f).emit();
|
|
||||||
break;
|
|
||||||
case WEST:
|
|
||||||
quad.tag(TAG_RIGHT).pos(0, 0f, 0f, 0f).pos(1, 0f, 1f, 0f).pos(2, 1f, 0f, 0f).pos(3, 1f, 0f, 0f).emit();
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void drawBack(QuadEmitter quad, Direction dir) {
|
|
||||||
switch(dir) {
|
|
||||||
case NORTH:
|
|
||||||
quad.tag(TAG_BACK).pos(0, 0f, 0f, 0f).pos(1, 0f, 1f, 0f).pos(2, 1f, 1f, 0f).pos(3, 1f, 0f, 0f).emit();
|
|
||||||
break;
|
|
||||||
case SOUTH:
|
|
||||||
quad.tag(TAG_BACK).pos(0, 0f, 0f, 1f).pos(1, 1f, 0f, 1f).pos(2, 1f, 1f, 1f).pos(3, 0f, 1f, 1f).emit();
|
|
||||||
break;
|
|
||||||
case EAST:
|
|
||||||
quad.tag(TAG_BACK).pos(0, 1f, 0f, 0f).pos(1, 1f, 1f, 0f).pos(2, 1f, 1f, 1f).pos(3, 1f, 0f, 1f).emit();
|
|
||||||
break;
|
|
||||||
case WEST:
|
|
||||||
quad.tag(TAG_BACK).pos(0, 0f, 0f, 0f).pos(1, 0f, 0f, 1f).pos(2, 0f, 1f, 1f).pos(3, 0f, 1f, 0f).emit();
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void drawBottom(QuadEmitter quad) {
|
|
||||||
quad.tag(TAG_BOTTOM).pos(0, 0f, 0f, 0f).pos(1, 1f, 0f, 0f).pos(2, 1f, 0f, 1f).pos(3, 0f, 0f, 1f).emit();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package io.github.cottonmc.templates.model;
|
package io.github.cottonmc.templates.model;
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.block.Blocks;
|
import net.minecraft.block.Blocks;
|
||||||
import net.minecraft.client.render.block.BlockModels;
|
import net.minecraft.client.render.block.BlockModels;
|
||||||
import net.minecraft.client.render.model.BakedModel;
|
import net.minecraft.client.render.model.BakedModel;
|
||||||
@ -15,7 +14,7 @@ import java.util.Collection;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
public record SlopeUnbakedModel(BlockState slopeState) implements UnbakedModel {
|
public class SlopeUnbakedModel implements UnbakedModel {
|
||||||
@Override
|
@Override
|
||||||
public Collection<Identifier> getModelDependencies() {
|
public Collection<Identifier> getModelDependencies() {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
@ -28,10 +27,9 @@ public record SlopeUnbakedModel(BlockState slopeState) implements UnbakedModel {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BakedModel bake(Baker baker, Function<SpriteIdentifier, Sprite> function, ModelBakeSettings modelBakeSettings, Identifier identifier) {
|
public BakedModel bake(Baker baker, Function<SpriteIdentifier, Sprite> function, ModelBakeSettings modelBakeSettings, Identifier identifier) {
|
||||||
//TODO: weird, should use my own model instead
|
//TODO: this is weird, should use my own model instead
|
||||||
BakedModel baseModel = baker.bake(BlockModels.getModelId(Blocks.SANDSTONE_STAIRS.getDefaultState()), modelBakeSettings);
|
BakedModel baseModel = baker.bake(BlockModels.getModelId(Blocks.SANDSTONE_STAIRS.getDefaultState()), modelBakeSettings);
|
||||||
|
|
||||||
//TODO: ModelBakeSettings.getRotation is always the identity transform atm
|
return new SlopeBakedModel(baseModel, function, modelBakeSettings.getRotation());
|
||||||
return new SlopeBakedModel(baseModel, slopeState, modelBakeSettings.getRotation(), function);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,34 +2,29 @@ package io.github.cottonmc.templates.model;
|
|||||||
|
|
||||||
import net.fabricmc.fabric.api.client.model.ModelProviderContext;
|
import net.fabricmc.fabric.api.client.model.ModelProviderContext;
|
||||||
import net.fabricmc.fabric.api.client.model.ModelProviderException;
|
import net.fabricmc.fabric.api.client.model.ModelProviderException;
|
||||||
import net.fabricmc.fabric.api.client.model.ModelVariantProvider;
|
import net.fabricmc.fabric.api.client.model.ModelResourceProvider;
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.client.render.block.BlockModels;
|
|
||||||
import net.minecraft.client.render.model.UnbakedModel;
|
import net.minecraft.client.render.model.UnbakedModel;
|
||||||
import net.minecraft.client.util.ModelIdentifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.registry.Registries;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public class TemplateModelVariantProvider implements ModelVariantProvider {
|
public class TemplateModelVariantProvider implements ModelResourceProvider {
|
||||||
private final Map<ModelIdentifier, Supplier<UnbakedModel>> factories = new HashMap<>();
|
private final Map<Identifier, Supplier<UnbakedModel>> factories = new HashMap<>();
|
||||||
private final Map<ModelIdentifier, UnbakedModel> cache = new HashMap<>();
|
private final Map<Identifier, UnbakedModel> cache = new HashMap<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable UnbakedModel loadModelVariant(ModelIdentifier modelId, ModelProviderContext context) throws ModelProviderException {
|
public @Nullable UnbakedModel loadModelResource(Identifier resourceId, ModelProviderContext context) throws ModelProviderException {
|
||||||
UnbakedModel cacheResult = cache.get(modelId);
|
UnbakedModel cacheResult = cache.get(resourceId);
|
||||||
if(cacheResult != null) return cacheResult;
|
if(cacheResult != null) return cacheResult;
|
||||||
|
|
||||||
//Either we have a factory for this model (just haven't cached its output yet),
|
//Either we have a factory for this model (just haven't cached its output yet),
|
||||||
Supplier<UnbakedModel> factory = factories.get(modelId);
|
Supplier<UnbakedModel> factory = factories.get(resourceId);
|
||||||
if(factory != null) {
|
if(factory != null) {
|
||||||
UnbakedModel freshModel = factory.get();
|
UnbakedModel freshModel = factory.get();
|
||||||
cache.put(modelId, freshModel);
|
cache.put(resourceId, freshModel);
|
||||||
return freshModel;
|
return freshModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,9 +32,8 @@ public class TemplateModelVariantProvider implements ModelVariantProvider {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerTemplateModels(Block block, BlockState itemState, Function<BlockState, UnbakedModel> model) {
|
public void addTemplateModel(Identifier id, Supplier<UnbakedModel> modelFactory) {
|
||||||
for(BlockState state : block.getStateManager().getStates()) factories.put(BlockModels.getModelId(state), () -> model.apply(state));
|
factories.put(id, modelFactory);
|
||||||
factories.put(new ModelIdentifier(Registries.ITEM.getId(block.asItem()), "inventory"), () -> model.apply(itemState));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void dumpCache() {
|
public void dumpCache() {
|
||||||
|
19
src/main/resources/assets/templates/blockstates/slope.json
Normal file
19
src/main/resources/assets/templates/blockstates/slope.json
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"variants": {
|
||||||
|
"facing=east": {
|
||||||
|
"model": "templates:slope_special",
|
||||||
|
"y": 270
|
||||||
|
},
|
||||||
|
"facing=north": {
|
||||||
|
"model": "templates:slope_special",
|
||||||
|
"y": 180
|
||||||
|
},
|
||||||
|
"facing=south": {
|
||||||
|
"model": "templates:slope_special"
|
||||||
|
},
|
||||||
|
"facing=west": {
|
||||||
|
"model": "templates:slope_special",
|
||||||
|
"y": 90
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user