Refactor custom rendered items

- CustomRenderedItemModel no longer holds partials
- Store partials as PartialModels in static fields in renderers
- Remove all CustomRenderedItemModel subclasses
- Remove CustomRenderedItemModelRenderer#createModel
- CustomRenderedItemModelRenderer is no longer generic
- Store items with custom renderers in CustomRenderedItems instead of
CustomRenderedItemModelRenderer
This commit is contained in:
PepperCode1 2023-02-22 20:34:37 -08:00
parent e54ccb853a
commit 6265b6d295
23 changed files with 150 additions and 351 deletions

View file

@ -1,21 +1,25 @@
package com.simibubi.create.content.contraptions.wrench;
import com.jozufozu.flywheel.core.PartialModel;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Vector3f;
import com.simibubi.create.Create;
import com.simibubi.create.foundation.blockEntity.behaviour.scrollvalue.ScrollValueHandler;
import com.simibubi.create.foundation.item.render.CustomRenderedItemModel;
import com.simibubi.create.foundation.item.render.CustomRenderedItemModelRenderer;
import com.simibubi.create.foundation.item.render.PartialItemModelRenderer;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.block.model.ItemTransforms;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.world.item.ItemStack;
public class WrenchItemRenderer extends CustomRenderedItemModelRenderer<WrenchModel> {
public class WrenchItemRenderer extends CustomRenderedItemModelRenderer {
protected static final PartialModel GEAR = new PartialModel(Create.asResource("item/wrench/gear"));
@Override
protected void render(ItemStack stack, WrenchModel model, PartialItemModelRenderer renderer, ItemTransforms.TransformType transformType,
protected void render(ItemStack stack, CustomRenderedItemModel model, PartialItemModelRenderer renderer, ItemTransforms.TransformType transformType,
PoseStack ms, MultiBufferSource buffer, int light, int overlay) {
renderer.render(model.getOriginalModel(), light);
@ -24,12 +28,7 @@ public class WrenchItemRenderer extends CustomRenderedItemModelRenderer<WrenchMo
ms.mulPose(Vector3f.YP.rotationDegrees(ScrollValueHandler.getScroll(AnimationTickHolder.getPartialTicks())));
ms.translate(xOffset, 0, 0);
renderer.render(model.getPartial("gear"), light);
}
@Override
public WrenchModel createModel(BakedModel originalModel) {
return new WrenchModel(originalModel);
renderer.render(GEAR.get(), light);
}
}

View file

@ -1,14 +0,0 @@
package com.simibubi.create.content.contraptions.wrench;
import com.simibubi.create.foundation.item.render.CreateCustomRenderedItemModel;
import net.minecraft.client.resources.model.BakedModel;
public class WrenchModel extends CreateCustomRenderedItemModel {
public WrenchModel(BakedModel template) {
super(template, "wrench");
addPartials("gear");
}
}

View file

@ -1,7 +1,10 @@
package com.simibubi.create.content.curiosities.symmetry.client;
import com.jozufozu.flywheel.core.PartialModel;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Vector3f;
import com.simibubi.create.Create;
import com.simibubi.create.foundation.item.render.CustomRenderedItemModel;
import com.simibubi.create.foundation.item.render.CustomRenderedItemModelRenderer;
import com.simibubi.create.foundation.item.render.PartialItemModelRenderer;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
@ -9,21 +12,24 @@ import com.simibubi.create.foundation.utility.AnimationTickHolder;
import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.block.model.ItemTransforms;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.util.Mth;
import net.minecraft.world.item.ItemStack;
public class SymmetryWandItemRenderer extends CustomRenderedItemModelRenderer<SymmetryWandModel> {
public class SymmetryWandItemRenderer extends CustomRenderedItemModelRenderer {
protected static final PartialModel BITS = new PartialModel(Create.asResource("item/wand_of_symmetry/bits"));
protected static final PartialModel CORE = new PartialModel(Create.asResource("item/wand_of_symmetry/core"));
protected static final PartialModel CORE_GLOW = new PartialModel(Create.asResource("item/wand_of_symmetry/core_glow"));
@Override
protected void render(ItemStack stack, SymmetryWandModel model, PartialItemModelRenderer renderer, ItemTransforms.TransformType transformType,
protected void render(ItemStack stack, CustomRenderedItemModel model, PartialItemModelRenderer renderer, ItemTransforms.TransformType transformType,
PoseStack ms, MultiBufferSource buffer, int light, int overlay) {
float worldTime = AnimationTickHolder.getRenderTime() / 20;
int maxLight = LightTexture.FULL_BRIGHT;
renderer.render(model.getOriginalModel(), light);
renderer.renderSolidGlowing(model.getPartial("core"), maxLight);
renderer.renderGlowing(model.getPartial("core_glow"), maxLight);
renderer.renderSolidGlowing(CORE.get(), maxLight);
renderer.renderGlowing(CORE_GLOW.get(), maxLight);
float floating = Mth.sin(worldTime) * .05f;
float angle = worldTime * -10 % 360;
@ -31,12 +37,7 @@ public class SymmetryWandItemRenderer extends CustomRenderedItemModelRenderer<Sy
ms.translate(0, floating, 0);
ms.mulPose(Vector3f.YP.rotationDegrees(angle));
renderer.renderGlowing(model.getPartial("bits"), maxLight);
}
@Override
public SymmetryWandModel createModel(BakedModel originalModel) {
return new SymmetryWandModel(originalModel);
renderer.renderGlowing(BITS.get(), maxLight);
}
}

View file

@ -1,14 +0,0 @@
package com.simibubi.create.content.curiosities.symmetry.client;
import com.simibubi.create.foundation.item.render.CreateCustomRenderedItemModel;
import net.minecraft.client.resources.model.BakedModel;
public class SymmetryWandModel extends CreateCustomRenderedItemModel {
public SymmetryWandModel(BakedModel template) {
super(template, "wand_of_symmetry");
addPartials("bits", "core", "core_glow");
}
}

View file

@ -1,26 +1,34 @@
package com.simibubi.create.content.curiosities.tools;
import com.jozufozu.flywheel.core.PartialModel;
import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.Create;
import com.simibubi.create.foundation.item.render.CustomRenderedItemModel;
import com.simibubi.create.foundation.item.render.CustomRenderedItemModelRenderer;
import com.simibubi.create.foundation.item.render.PartialItemModelRenderer;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.block.model.ItemTransforms.TransformType;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.util.Mth;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.phys.Vec3;
public class ExtendoGripItemRenderer extends CustomRenderedItemModelRenderer<ExtendoGripModel> {
public class ExtendoGripItemRenderer extends CustomRenderedItemModelRenderer {
private static final Vec3 rotationOffset = new Vec3(0, 1 / 2f, 1 / 2f);
private static final Vec3 cogRotationOffset = new Vec3(0, 1 / 16f, 0);
protected static final PartialModel COG = new PartialModel(Create.asResource("item/extendo_grip/cog"));
protected static final PartialModel THIN_SHORT = new PartialModel(Create.asResource("item/extendo_grip/thin_short"));
protected static final PartialModel WIDE_SHORT = new PartialModel(Create.asResource("item/extendo_grip/wide_short"));
protected static final PartialModel THIN_LONG = new PartialModel(Create.asResource("item/extendo_grip/thin_long"));
protected static final PartialModel WIDE_LONG = new PartialModel(Create.asResource("item/extendo_grip/wide_long"));
private static final Vec3 ROTATION_OFFSET = new Vec3(0, 1 / 2f, 1 / 2f);
private static final Vec3 COG_ROTATION_OFFSET = new Vec3(0, 1 / 16f, 0);
@Override
protected void render(ItemStack stack, ExtendoGripModel model, PartialItemModelRenderer renderer, TransformType transformType,
protected void render(ItemStack stack, CustomRenderedItemModel model, PartialItemModelRenderer renderer, TransformType transformType,
PoseStack ms, MultiBufferSource buffer, int light, int overlay) {
TransformStack stacker = TransformStack.cast(ms);
float animation = 0.25f;
@ -45,43 +53,43 @@ public class ExtendoGripItemRenderer extends CustomRenderedItemModelRenderer<Ext
ms.scale(1, 1, 1 + animation);
ms.pushPose();
stacker.rotateX(-halfAngle)
.translate(rotationOffset);
renderer.renderSolid(model.getPartial("thin_short"), light);
stacker.translateBack(rotationOffset);
.translate(ROTATION_OFFSET);
renderer.renderSolid(THIN_SHORT.get(), light);
stacker.translateBack(ROTATION_OFFSET);
ms.translate(0, 5.5f / 16f, 0);
stacker.rotateX(-oppositeAngle)
.translate(rotationOffset);
renderer.renderSolid(model.getPartial("wide_long"), light);
stacker.translateBack(rotationOffset);
.translate(ROTATION_OFFSET);
renderer.renderSolid(WIDE_LONG.get(), light);
stacker.translateBack(ROTATION_OFFSET);
ms.translate(0, 11 / 16f, 0);
stacker.rotateX(oppositeAngle)
.translate(rotationOffset);
.translate(ROTATION_OFFSET);
ms.translate(0, 0.5f / 16f, 0);
renderer.renderSolid(model.getPartial("thin_short"), light);
stacker.translateBack(rotationOffset);
renderer.renderSolid(THIN_SHORT.get(), light);
stacker.translateBack(ROTATION_OFFSET);
ms.popPose();
ms.pushPose();
stacker.rotateX(-180 + halfAngle)
.translate(rotationOffset);
renderer.renderSolid(model.getPartial("wide_short"), light);
stacker.translateBack(rotationOffset);
.translate(ROTATION_OFFSET);
renderer.renderSolid(WIDE_SHORT.get(), light);
stacker.translateBack(ROTATION_OFFSET);
ms.translate(0, 5.5f / 16f, 0);
stacker.rotateX(oppositeAngle)
.translate(rotationOffset);
renderer.renderSolid(model.getPartial("thin_long"), light);
stacker.translateBack(rotationOffset);
.translate(ROTATION_OFFSET);
renderer.renderSolid(THIN_LONG.get(), light);
stacker.translateBack(ROTATION_OFFSET);
ms.translate(0, 11 / 16f, 0);
stacker.rotateX(-oppositeAngle)
.translate(rotationOffset);
.translate(ROTATION_OFFSET);
ms.translate(0, 0.5f / 16f, 0);
renderer.renderSolid(model.getPartial("wide_short"), light);
stacker.translateBack(rotationOffset);
renderer.renderSolid(WIDE_SHORT.get(), light);
stacker.translateBack(ROTATION_OFFSET);
// hand
ms.translate(0, 5.5f / 16f, 0);
@ -101,16 +109,11 @@ public class ExtendoGripItemRenderer extends CustomRenderedItemModelRenderer<Ext
if (leftHand || rightHand)
angle += 360 * animation;
angle %= 360;
stacker.translate(cogRotationOffset)
stacker.translate(COG_ROTATION_OFFSET)
.rotateZ(angle)
.translateBack(cogRotationOffset);
renderer.renderSolid(model.getPartial("cog"), light);
.translateBack(COG_ROTATION_OFFSET);
renderer.renderSolid(COG.get(), light);
ms.popPose();
}
@Override
public ExtendoGripModel createModel(BakedModel originalModel) {
return new ExtendoGripModel(originalModel);
}
}

View file

@ -1,14 +0,0 @@
package com.simibubi.create.content.curiosities.tools;
import com.simibubi.create.foundation.item.render.CreateCustomRenderedItemModel;
import net.minecraft.client.resources.model.BakedModel;
public class ExtendoGripModel extends CreateCustomRenderedItemModel {
public ExtendoGripModel(BakedModel template) {
super(template, "extendo_grip");
addPartials("cog", "thin_short", "wide_short", "thin_long", "wide_long");
}
}

View file

@ -2,7 +2,7 @@ package com.simibubi.create.content.curiosities.tools;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Vector3f;
import com.simibubi.create.foundation.item.render.CreateCustomRenderedItemModel;
import com.simibubi.create.foundation.item.render.CustomRenderedItemModel;
import com.simibubi.create.foundation.item.render.CustomRenderedItemModelRenderer;
import com.simibubi.create.foundation.item.render.PartialItemModelRenderer;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
@ -12,15 +12,14 @@ import net.minecraft.client.player.LocalPlayer;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.block.model.ItemTransforms.TransformType;
import net.minecraft.client.renderer.entity.ItemRenderer;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.util.Mth;
import net.minecraft.world.item.ItemStack;
public class SandPaperItemRenderer extends CustomRenderedItemModelRenderer<SandPaperItemRenderer.SandPaperModel> {
public class SandPaperItemRenderer extends CustomRenderedItemModelRenderer {
@Override
protected void render(ItemStack stack, SandPaperModel model, PartialItemModelRenderer renderer,
protected void render(ItemStack stack, CustomRenderedItemModel model, PartialItemModelRenderer renderer,
TransformType transformType, PoseStack ms, MultiBufferSource buffer, int light, int overlay) {
ItemRenderer itemRenderer = Minecraft.getInstance().getItemRenderer();
LocalPlayer player = Minecraft.getInstance().player;
@ -79,17 +78,4 @@ public class SandPaperItemRenderer extends CustomRenderedItemModelRenderer<SandP
ms.popPose();
}
@Override
public SandPaperModel createModel(BakedModel originalModel) {
return new SandPaperModel(originalModel);
}
public static class SandPaperModel extends CreateCustomRenderedItemModel {
public SandPaperModel(BakedModel template) {
super(template, "");
}
}
}

View file

@ -1,9 +1,12 @@
package com.simibubi.create.content.curiosities.weapons;
import com.jozufozu.flywheel.core.PartialModel;
import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Vector3f;
import com.simibubi.create.Create;
import com.simibubi.create.CreateClient;
import com.simibubi.create.foundation.item.render.CustomRenderedItemModel;
import com.simibubi.create.foundation.item.render.CustomRenderedItemModelRenderer;
import com.simibubi.create.foundation.item.render.PartialItemModelRenderer;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
@ -14,15 +17,16 @@ import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.block.model.ItemTransforms.TransformType;
import net.minecraft.client.renderer.entity.ItemRenderer;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.HumanoidArm;
import net.minecraft.world.item.ItemStack;
public class PotatoCannonItemRenderer extends CustomRenderedItemModelRenderer<PotatoCannonModel> {
public class PotatoCannonItemRenderer extends CustomRenderedItemModelRenderer {
protected static final PartialModel COG = new PartialModel(Create.asResource("item/potato_cannon/cog"));
@Override
protected void render(ItemStack stack, PotatoCannonModel model, PartialItemModelRenderer renderer,
protected void render(ItemStack stack, CustomRenderedItemModel model, PartialItemModelRenderer renderer,
TransformType transformType, PoseStack ms, MultiBufferSource buffer, int light, int overlay) {
ItemRenderer itemRenderer = Minecraft.getInstance()
.getItemRenderer();
@ -46,7 +50,7 @@ public class PotatoCannonItemRenderer extends CustomRenderedItemModelRenderer<Po
ms.translate(0, offset, 0);
ms.mulPose(Vector3f.ZP.rotationDegrees(angle));
ms.translate(0, -offset, 0);
renderer.render(model.getPartial("cog"), light);
renderer.render(COG.get(), light);
ms.popPose();
if (transformType == TransformType.GUI) {
@ -63,9 +67,4 @@ public class PotatoCannonItemRenderer extends CustomRenderedItemModelRenderer<Po
}
@Override
public PotatoCannonModel createModel(BakedModel originalModel) {
return new PotatoCannonModel(originalModel);
}
}

View file

@ -1,14 +0,0 @@
package com.simibubi.create.content.curiosities.weapons;
import com.simibubi.create.foundation.item.render.CreateCustomRenderedItemModel;
import net.minecraft.client.resources.model.BakedModel;
public class PotatoCannonModel extends CreateCustomRenderedItemModel {
public PotatoCannonModel(BakedModel template) {
super(template, "potato_cannon");
addPartials("cog");
}
}

View file

@ -16,10 +16,10 @@ import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.CrossCollisionBlock;
import net.minecraft.world.level.block.state.BlockState;
public abstract class ZapperItemRenderer<M extends CustomRenderedItemModel> extends CustomRenderedItemModelRenderer<M> {
public abstract class ZapperItemRenderer extends CustomRenderedItemModelRenderer {
@Override
protected void render(ItemStack stack, M model, PartialItemModelRenderer renderer, TransformType transformType,
protected void render(ItemStack stack, CustomRenderedItemModel model, PartialItemModelRenderer renderer, TransformType transformType,
PoseStack ms, MultiBufferSource buffer, int light, int overlay) {
// Block indicator
if (transformType == TransformType.GUI && stack.hasTag() && stack.getTag()

View file

@ -2,9 +2,12 @@ package com.simibubi.create.content.curiosities.zapper.terrainzapper;
import static java.lang.Math.max;
import com.jozufozu.flywheel.core.PartialModel;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Vector3f;
import com.simibubi.create.Create;
import com.simibubi.create.content.curiosities.zapper.ZapperItemRenderer;
import com.simibubi.create.foundation.item.render.CustomRenderedItemModel;
import com.simibubi.create.foundation.item.render.PartialItemModelRenderer;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
@ -13,15 +16,18 @@ import net.minecraft.client.player.LocalPlayer;
import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.block.model.ItemTransforms;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.HumanoidArm;
import net.minecraft.world.item.ItemStack;
public class WorldshaperItemRenderer extends ZapperItemRenderer<WorldshaperModel> {
public class WorldshaperItemRenderer extends ZapperItemRenderer {
protected static final PartialModel CORE = new PartialModel(Create.asResource("item/handheld_worldshaper/core"));
protected static final PartialModel CORE_GLOW = new PartialModel(Create.asResource("item/handheld_worldshaper/core_glow"));
protected static final PartialModel ACCELERATOR = new PartialModel(Create.asResource("item/handheld_worldshaper/accelerator"));
@Override
protected void render(ItemStack stack, WorldshaperModel model, PartialItemModelRenderer renderer, ItemTransforms.TransformType transformType,
protected void render(ItemStack stack, CustomRenderedItemModel model, PartialItemModelRenderer renderer, ItemTransforms.TransformType transformType,
PoseStack ms, MultiBufferSource buffer, int light, int overlay) {
super.render(stack, model, renderer, transformType, ms, buffer, light, overlay);
@ -45,8 +51,8 @@ public class WorldshaperItemRenderer extends ZapperItemRenderer<WorldshaperModel
int lightItensity = (int) (15 * Mth.clamp(multiplier, 0, 1));
int glowLight = LightTexture.pack(lightItensity, max(lightItensity, 4));
renderer.renderSolidGlowing(model.getPartial("core"), glowLight);
renderer.renderGlowing(model.getPartial("core_glow"), glowLight);
renderer.renderSolidGlowing(CORE.get(), glowLight);
renderer.renderGlowing(CORE_GLOW.get(), glowLight);
// Accelerator spins
float angle = worldTime * -25;
@ -58,12 +64,7 @@ public class WorldshaperItemRenderer extends ZapperItemRenderer<WorldshaperModel
ms.translate(0, offset, 0);
ms.mulPose(Vector3f.ZP.rotationDegrees(angle));
ms.translate(0, -offset, 0);
renderer.render(model.getPartial("accelerator"), light);
}
@Override
public WorldshaperModel createModel(BakedModel originalModel) {
return new WorldshaperModel(originalModel);
renderer.render(ACCELERATOR.get(), light);
}
}

View file

@ -1,14 +0,0 @@
package com.simibubi.create.content.curiosities.zapper.terrainzapper;
import com.simibubi.create.foundation.item.render.CreateCustomRenderedItemModel;
import net.minecraft.client.resources.model.BakedModel;
public class WorldshaperModel extends CreateCustomRenderedItemModel {
public WorldshaperModel(BakedModel template) {
super(template, "handheld_worldshaper");
addPartials("core", "core_glow", "accelerator");
}
}

View file

@ -4,6 +4,7 @@ import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllItems;
import com.simibubi.create.foundation.blockEntity.renderer.SafeBlockEntityRenderer;
import com.simibubi.create.foundation.item.render.CustomRenderedItemModel;
import com.simibubi.create.foundation.item.render.PartialItemModelRenderer;
import com.simibubi.create.foundation.utility.AngleHelper;
@ -25,7 +26,7 @@ public class LecternControllerRenderer extends SafeBlockEntityRenderer<LecternCo
ItemStack stack = AllItems.LINKED_CONTROLLER.asStack();
TransformType transformType = TransformType.NONE;
LinkedControllerModel mainModel = (LinkedControllerModel) Minecraft.getInstance()
CustomRenderedItemModel mainModel = (CustomRenderedItemModel) Minecraft.getInstance()
.getItemRenderer()
.getModel(stack, be.getLevel(), null, 0);
PartialItemModelRenderer renderer = PartialItemModelRenderer.of(stack, transformType, ms, buffer, overlay);

View file

@ -2,10 +2,13 @@ package com.simibubi.create.content.logistics.item;
import java.util.Vector;
import com.jozufozu.flywheel.core.PartialModel;
import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllItems;
import com.simibubi.create.Create;
import com.simibubi.create.content.logistics.item.LinkedControllerClientHandler.Mode;
import com.simibubi.create.foundation.item.render.CustomRenderedItemModel;
import com.simibubi.create.foundation.item.render.CustomRenderedItemModelRenderer;
import com.simibubi.create.foundation.item.render.PartialItemModelRenderer;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
@ -21,7 +24,10 @@ import net.minecraft.util.Mth;
import net.minecraft.world.entity.HumanoidArm;
import net.minecraft.world.item.ItemStack;
public class LinkedControllerItemRenderer extends CustomRenderedItemModelRenderer<LinkedControllerModel> {
public class LinkedControllerItemRenderer extends CustomRenderedItemModelRenderer {
protected static final PartialModel POWERED = new PartialModel(Create.asResource("item/linked_controller/powered"));
protected static final PartialModel BUTTON = new PartialModel(Create.asResource("item/linked_controller/button"));
static LerpedFloat equipProgress;
static Vector<LerpedFloat> buttons;
@ -61,25 +67,25 @@ public class LinkedControllerItemRenderer extends CustomRenderedItemModelRendere
}
@Override
protected void render(ItemStack stack, LinkedControllerModel model, PartialItemModelRenderer renderer,
protected void render(ItemStack stack, CustomRenderedItemModel model, PartialItemModelRenderer renderer,
ItemTransforms.TransformType transformType, PoseStack ms, MultiBufferSource buffer, int light,
int overlay) {
renderNormal(stack, model, renderer, transformType, ms, light);
}
protected static void renderNormal(ItemStack stack, LinkedControllerModel model,
protected static void renderNormal(ItemStack stack, CustomRenderedItemModel model,
PartialItemModelRenderer renderer, ItemTransforms.TransformType transformType, PoseStack ms,
int light) {
render(stack, model, renderer, transformType, ms, light, RenderType.NORMAL, false, false);
}
public static void renderInLectern(ItemStack stack, LinkedControllerModel model,
public static void renderInLectern(ItemStack stack, CustomRenderedItemModel model,
PartialItemModelRenderer renderer, ItemTransforms.TransformType transformType, PoseStack ms,
int light, boolean active, boolean renderDepression) {
render(stack, model, renderer, transformType, ms, light, RenderType.LECTERN, active, renderDepression);
}
protected static void render(ItemStack stack, LinkedControllerModel model,
protected static void render(ItemStack stack, CustomRenderedItemModel model,
PartialItemModelRenderer renderer, ItemTransforms.TransformType transformType, PoseStack ms,
int light, RenderType renderType, boolean active, boolean renderDepression) {
float pt = AnimationTickHolder.getPartialTicks();
@ -119,14 +125,14 @@ public class LinkedControllerItemRenderer extends CustomRenderedItemModelRendere
renderDepression = true;
}
renderer.render(active ? model.getPartial("powered") : model.getOriginalModel(), light);
renderer.render(active ? POWERED.get() : model.getOriginalModel(), light);
if (!active) {
ms.popPose();
return;
}
BakedModel button = model.getPartial("button");
BakedModel button = BUTTON.get();
float s = 1 / 16f;
float b = s * -.75f;
int index = 0;
@ -168,11 +174,6 @@ public class LinkedControllerItemRenderer extends CustomRenderedItemModelRendere
ms.popPose();
}
@Override
public LinkedControllerModel createModel(BakedModel originalModel) {
return new LinkedControllerModel(originalModel);
}
protected enum RenderType {
NORMAL, LECTERN;
}

View file

@ -1,14 +0,0 @@
package com.simibubi.create.content.logistics.item;
import com.simibubi.create.foundation.item.render.CreateCustomRenderedItemModel;
import net.minecraft.client.resources.model.BakedModel;
public class LinkedControllerModel extends CreateCustomRenderedItemModel {
public LinkedControllerModel(BakedModel template) {
super(template, "linked_controller");
addPartials("powered", "button");
}
}

View file

@ -16,7 +16,8 @@ import net.minecraftforge.registries.ForgeRegistries;
public class CustomBlockModels {
private final Multimap<ResourceLocation, NonNullFunction<BakedModel, ? extends BakedModel>> modelFuncs = MultimapBuilder.hashKeys().arrayListValues().build();
private final Map<Block, NonNullFunction<BakedModel, ? extends BakedModel>> finalModelFunc = new IdentityHashMap<>();
private final Map<Block, NonNullFunction<BakedModel, ? extends BakedModel>> finalModelFuncs = new IdentityHashMap<>();
private boolean funcsLoaded = false;
public void register(ResourceLocation block, NonNullFunction<BakedModel, ? extends BakedModel> func) {
modelFuncs.put(block, func);
@ -24,16 +25,18 @@ public class CustomBlockModels {
public void forEach(NonNullBiConsumer<Block, NonNullFunction<BakedModel, ? extends BakedModel>> consumer) {
loadEntriesIfMissing();
finalModelFunc.forEach(consumer);
finalModelFuncs.forEach(consumer);
}
private void loadEntriesIfMissing() {
if (finalModelFunc.isEmpty())
if (!funcsLoaded) {
loadEntries();
funcsLoaded = true;
}
}
private void loadEntries() {
finalModelFunc.clear();
finalModelFuncs.clear();
modelFuncs.asMap().forEach((location, funcList) -> {
Block block = ForgeRegistries.BLOCKS.getValue(location);
if (block == null) {
@ -49,7 +52,7 @@ public class CustomBlockModels {
}
}
finalModelFunc.put(block, finalFunc);
finalModelFuncs.put(block, finalFunc);
});
}

View file

@ -1,13 +0,0 @@
package com.simibubi.create.foundation.item.render;
import com.simibubi.create.Create;
import net.minecraft.client.resources.model.BakedModel;
public abstract class CreateCustomRenderedItemModel extends CustomRenderedItemModel {
public CreateCustomRenderedItemModel(BakedModel template, String basePath) {
super(template, Create.ID, basePath);
}
}

View file

@ -17,6 +17,7 @@ public class CustomItemModels {
private final Multimap<ResourceLocation, NonNullFunction<BakedModel, ? extends BakedModel>> modelFuncs = MultimapBuilder.hashKeys().arrayListValues().build();
private final Map<Item, NonNullFunction<BakedModel, ? extends BakedModel>> finalModelFuncs = new IdentityHashMap<>();
private boolean funcsLoaded = false;
public void register(ResourceLocation item, NonNullFunction<BakedModel, ? extends BakedModel> func) {
modelFuncs.put(item, func);
@ -28,8 +29,10 @@ public class CustomItemModels {
}
private void loadEntriesIfMissing() {
if (finalModelFuncs.isEmpty())
if (!funcsLoaded) {
loadEntries();
funcsLoaded = true;
}
}
private void loadEntries() {

View file

@ -1,30 +1,15 @@
package com.simibubi.create.foundation.item.render;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.renderer.block.model.ItemTransforms;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.client.resources.model.BlockModelRotation;
import net.minecraft.resources.ResourceLocation;
import net.minecraftforge.client.event.ModelBakeEvent;
import net.minecraftforge.client.model.BakedModelWrapper;
import net.minecraftforge.client.model.ForgeModelBakery;
public abstract class CustomRenderedItemModel extends BakedModelWrapper<BakedModel> {
public class CustomRenderedItemModel extends BakedModelWrapper<BakedModel> {
protected String namespace;
protected String basePath;
protected Map<String, BakedModel> partials = new HashMap<>();
public CustomRenderedItemModel(BakedModel template, String namespace, String basePath) {
super(template);
this.namespace = namespace;
this.basePath = basePath;
public CustomRenderedItemModel(BakedModel originalModel) {
super(originalModel);
}
@Override
@ -34,42 +19,14 @@ public abstract class CustomRenderedItemModel extends BakedModelWrapper<BakedMod
@Override
public BakedModel handlePerspective(ItemTransforms.TransformType cameraTransformType, PoseStack mat) {
// Super call returns originalModel, but we want to return this, else ISTER
// Super call returns originalModel, but we want to return this, else BEWLR
// won't be used.
super.handlePerspective(cameraTransformType, mat);
return this;
}
public final BakedModel getOriginalModel() {
public BakedModel getOriginalModel() {
return originalModel;
}
public BakedModel getPartial(String name) {
return partials.get(name);
}
public final List<ResourceLocation> getModelLocations() {
return partials.keySet().stream().map(this::getPartialModelLocation).collect(Collectors.toList());
}
protected void addPartials(String... partials) {
for (String name : partials)
this.partials.put(name, null);
}
public void loadPartials(ModelBakeEvent event) {
ForgeModelBakery modelLoader = event.getModelLoader();
for (String name : partials.keySet())
partials.put(name, loadPartial(modelLoader, name));
}
@SuppressWarnings("deprecation")
protected BakedModel loadPartial(ForgeModelBakery modelLoader, String name) {
return modelLoader.bake(getPartialModelLocation(name), BlockModelRotation.X0_Y0);
}
protected ResourceLocation getPartialModelLocation(String name) {
return new ResourceLocation(namespace, "item/" + basePath + "/" + name);
}
}

View file

@ -1,34 +1,22 @@
package com.simibubi.create.foundation.item.render;
import java.util.HashSet;
import java.util.Set;
import com.mojang.blaze3d.vertex.PoseStack;
import com.tterrag.registrate.util.nullness.NonNullBiConsumer;
import com.tterrag.registrate.util.nullness.NonNullFunction;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BlockEntityWithoutLevelRenderer;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.block.model.ItemTransforms;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.client.RenderProperties;
import net.minecraftforge.registries.ForgeRegistries;
public abstract class CustomRenderedItemModelRenderer<M extends CustomRenderedItemModel> extends BlockEntityWithoutLevelRenderer {
private static final Set<Item> ITEMS = new HashSet<>();
public abstract class CustomRenderedItemModelRenderer extends BlockEntityWithoutLevelRenderer {
public CustomRenderedItemModelRenderer() {
super(null, null);
}
@Override
@SuppressWarnings("unchecked")
public void renderByItem(ItemStack stack, ItemTransforms.TransformType transformType, PoseStack ms, MultiBufferSource buffer, int light, int overlay) {
M mainModel = (M) Minecraft.getInstance()
CustomRenderedItemModel mainModel = (CustomRenderedItemModel) Minecraft.getInstance()
.getItemRenderer()
.getModel(stack, null, null, 0);
PartialItemModelRenderer renderer = PartialItemModelRenderer.of(stack, transformType, ms, buffer, overlay);
@ -39,30 +27,7 @@ public abstract class CustomRenderedItemModelRenderer<M extends CustomRenderedIt
ms.popPose();
}
protected abstract void render(ItemStack stack, M model, PartialItemModelRenderer renderer, ItemTransforms.TransformType transformType,
protected abstract void render(ItemStack stack, CustomRenderedItemModel model, PartialItemModelRenderer renderer, ItemTransforms.TransformType transformType,
PoseStack ms, MultiBufferSource buffer, int light, int overlay);
public abstract M createModel(BakedModel originalModel);
/**
* Track an item that uses a subclass of {@link CustomRenderedItemModelRenderer} as its custom renderer
* to automatically register {@link #createModel} to {@link CustomRenderedItems} on client setup so that
* its model can be swapped.
* @param item The item that should have its model swapped.
*/
public static void registerForSwapping(Item item) {
ITEMS.add(item);
}
public static void acceptModelFuncs(NonNullBiConsumer<Item, NonNullFunction<BakedModel, ? extends CustomRenderedItemModel>> consumer) {
for (Item item : ITEMS) {
if (ForgeRegistries.ITEMS.containsValue(item)) {
BlockEntityWithoutLevelRenderer renderer = RenderProperties.get(item).getItemStackRenderer();
if (renderer instanceof CustomRenderedItemModelRenderer<?> customRenderer) {
consumer.accept(item, customRenderer::createModel);
}
}
}
}
}

View file

@ -1,48 +1,45 @@
package com.simibubi.create.foundation.item.render;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.Iterator;
import java.util.Set;
import java.util.function.Consumer;
import com.tterrag.registrate.util.nullness.NonNullBiConsumer;
import com.tterrag.registrate.util.nullness.NonNullFunction;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.resources.ResourceLocation;
import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet;
import net.minecraft.world.item.Item;
import net.minecraftforge.client.RenderProperties;
import net.minecraftforge.registries.ForgeRegistries;
public class CustomRenderedItems {
private final Map<ResourceLocation, NonNullFunction<BakedModel, ? extends CustomRenderedItemModel>> modelFuncs = new HashMap<>();
private final Map<Item, NonNullFunction<BakedModel, ? extends CustomRenderedItemModel>> finalModelFuncs = new IdentityHashMap<>();
private static final Set<Item> ITEMS = new ReferenceOpenHashSet<>();
private static boolean itemsFiltered = false;
public void register(ResourceLocation item,
NonNullFunction<BakedModel, ? extends CustomRenderedItemModel> func) {
modelFuncs.put(item, func);
/**
* Track an item that uses a subclass of {@link CustomRenderedItemModelRenderer} as its custom renderer
* to automatically register {@link #createModel} to {@link CustomRenderedItems} on client setup so that
* its model can be swapped.
* @param item The item that should have its model swapped.
*/
public static void register(Item item) {
ITEMS.add(item);
}
public void forEach(
NonNullBiConsumer<Item, NonNullFunction<BakedModel, ? extends CustomRenderedItemModel>> consumer) {
loadEntriesIfMissing();
finalModelFuncs.forEach(consumer);
}
private void loadEntriesIfMissing() {
if (finalModelFuncs.isEmpty())
loadEntries();
}
private void loadEntries() {
finalModelFuncs.clear();
CustomRenderedItemModelRenderer.acceptModelFuncs(finalModelFuncs::put);
modelFuncs.forEach((location, func) -> {
Item item = ForgeRegistries.ITEMS.getValue(location);
if (item == null) {
return;
/**
* This method must not be called before item registration is finished!
*/
public static void forEach(Consumer<Item> consumer) {
if (!itemsFiltered) {
Iterator<Item> iterator = ITEMS.iterator();
while (iterator.hasNext()) {
Item item = iterator.next();
if (!ForgeRegistries.ITEMS.containsValue(item) ||
!(RenderProperties.get(item).getItemStackRenderer() instanceof CustomRenderedItemModelRenderer)) {
iterator.remove();
}
}
finalModelFuncs.put(item, func);
});
itemsFiltered = true;
}
ITEMS.forEach(consumer);
}
}

View file

@ -5,19 +5,19 @@ import net.minecraftforge.client.IItemRenderProperties;
public class SimpleCustomRenderer implements IItemRenderProperties {
protected CustomRenderedItemModelRenderer<?> renderer;
protected CustomRenderedItemModelRenderer renderer;
protected SimpleCustomRenderer(CustomRenderedItemModelRenderer<?> renderer) {
protected SimpleCustomRenderer(CustomRenderedItemModelRenderer renderer) {
this.renderer = renderer;
}
public static SimpleCustomRenderer create(Item item, CustomRenderedItemModelRenderer<?> renderer) {
CustomRenderedItemModelRenderer.registerForSwapping(item);
public static SimpleCustomRenderer create(Item item, CustomRenderedItemModelRenderer renderer) {
CustomRenderedItems.register(item);
return new SimpleCustomRenderer(renderer);
}
@Override
public CustomRenderedItemModelRenderer<?> getItemStackRenderer() {
public CustomRenderedItemModelRenderer getItemStackRenderer() {
return renderer;
}

View file

@ -17,15 +17,12 @@ import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.block.Block;
import net.minecraftforge.client.event.ModelBakeEvent;
import net.minecraftforge.client.event.ModelRegistryEvent;
import net.minecraftforge.client.model.ForgeModelBakery;
import net.minecraftforge.eventbus.api.IEventBus;
public class ModelSwapper {
protected CustomBlockModels customBlockModels = new CustomBlockModels();
protected CustomItemModels customItemModels = new CustomItemModels();
protected CustomRenderedItems customRenderedItems = new CustomRenderedItems();
public CustomBlockModels getCustomBlockModels() {
return customBlockModels;
@ -35,32 +32,15 @@ public class ModelSwapper {
return customItemModels;
}
public CustomRenderedItems getCustomRenderedItems() {
return customRenderedItems;
}
public void onModelRegistry(ModelRegistryEvent event) {
customRenderedItems.forEach((item, modelFunc) -> modelFunc.apply(null)
.getModelLocations()
.forEach(ForgeModelBakery::addSpecialModel));
}
public void onModelBake(ModelBakeEvent event) {
Map<ResourceLocation, BakedModel> modelRegistry = event.getModelRegistry();
customBlockModels.forEach((block, modelFunc) -> swapModels(modelRegistry, getAllBlockStateModelLocations(block), modelFunc));
customItemModels.forEach((item, modelFunc) -> swapModels(modelRegistry, getItemModelLocation(item), modelFunc));
customRenderedItems.forEach((item, modelFunc) -> {
swapModels(modelRegistry, getItemModelLocation(item), m -> {
CustomRenderedItemModel swapped = modelFunc.apply(m);
swapped.loadPartials(event);
return swapped;
});
});
CustomRenderedItems.forEach(item -> swapModels(modelRegistry, getItemModelLocation(item), CustomRenderedItemModel::new));
}
public void registerListeners(IEventBus modEventBus) {
modEventBus.addListener(this::onModelRegistry);
modEventBus.addListener(this::onModelBake);
}