Skip to content

Commit

Permalink
Refactor staff model rendering (again)
Browse files Browse the repository at this point in the history
  • Loading branch information
opekope2 committed Feb 15, 2024
1 parent be6177c commit 853550e
Show file tree
Hide file tree
Showing 14 changed files with 284 additions and 183 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,14 @@ import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper
import net.fabricmc.fabric.api.client.model.loading.v1.ModelLoadingPlugin
import net.fabricmc.fabric.api.client.model.loading.v1.ModelModifier
import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents
import net.minecraft.client.render.model.BakedModel
import net.minecraft.client.item.ModelPredicateProviderRegistry
import net.minecraft.client.render.model.UnbakedModel
import net.minecraft.client.render.model.json.JsonUnbakedModel
import net.minecraft.item.ItemGroups
import net.minecraft.item.Items
import opekope2.avm_staff.internal.event_handler.ADD_REMOVE_KEYBINDING
import opekope2.avm_staff.internal.fabric.item.model.StaffItemModel
import opekope2.avm_staff.internal.event_handler.handleKeyBindings
import opekope2.avm_staff.internal.fabric.item.model.UnbakedFabricStaffItemModel
import opekope2.avm_staff.internal.registerModelPredicateProviders
import opekope2.avm_staff.util.MOD_ID

Expand All @@ -57,13 +58,16 @@ object StaffModClient : ClientModInitializer {
}

private fun modelLoadingPlugin(pluginContext: ModelLoadingPlugin.Context) {
pluginContext.modifyModelAfterBake().register(::modifyModelAfterBake)
pluginContext.modifyModelBeforeBake().register(::modifyModelBeforeBake)
}

private fun modifyModelAfterBake(model: BakedModel?, context: ModelModifier.AfterBake.Context): BakedModel? {
val id = context.id()
private fun modifyModelBeforeBake(model: UnbakedModel, context: ModelModifier.BeforeBake.Context): UnbakedModel {
if (context.id().namespace != MOD_ID) return model

return if (model == null || id.namespace != MOD_ID || id.path != "staff") model
else StaffItemModel(model)
return when (context.id().path) {
// TODO hardcoded paths
"staff", "item/staff_in_use" -> UnbakedFabricStaffItemModel(model as JsonUnbakedModel) // FIXME
else -> model
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,24 +24,29 @@ import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext
import net.minecraft.client.render.model.BakedModel
import net.minecraft.item.ItemStack
import net.minecraft.registry.Registries
import net.minecraft.util.Identifier
import net.minecraft.util.math.random.Random
import opekope2.avm_staff.util.handlerOfItemOrFallback
import opekope2.avm_staff.api.item.model.IStaffItemBakedModel
import opekope2.avm_staff.util.isItemInStaff
import opekope2.avm_staff.util.itemInStaff
import java.util.function.Supplier

@Environment(EnvType.CLIENT)
class StaffItemModel(original: BakedModel) : BakedModel by original {
class BakedFabricStaffItemModel(
original: BakedModel,
private val itemModels: Map<Identifier, IStaffItemBakedModel>,
private val missingModel: BakedModel
) : BakedModel by original {
override fun emitItemQuads(stack: ItemStack, randomSupplier: Supplier<Random>, context: RenderContext) {
super.emitItemQuads(stack, randomSupplier, context)

if (!stack.isItemInStaff) return

val itemStack = stack.itemInStaff
val handler = itemStack.handlerOfItemOrFallback
val itemStack = stack.itemInStaff ?: return

val model = handler.itemModelProvider.getModel(stack) as FabricBakedModel
model.emitItemQuads(stack, randomSupplier, context)
val model = itemModels[Registries.ITEM.getId(itemStack.item)]?.getModel(stack) ?: missingModel
(model as FabricBakedModel).emitItemQuads(stack, randomSupplier, context)
}

override fun isVanillaAdapter() = false
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* AvM Staff Mod
* Copyright (c) 2024 opekope2
*
* This mod is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This mod is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this mod. If not, see <https://www.gnu.org/licenses/>.
*/

package opekope2.avm_staff.internal.fabric.item.model

import net.fabricmc.api.EnvType
import net.fabricmc.api.Environment
import net.minecraft.client.render.model.BakedModel
import net.minecraft.client.render.model.Baker
import net.minecraft.client.render.model.ModelBakeSettings
import net.minecraft.client.render.model.json.JsonUnbakedModel
import net.minecraft.client.texture.MissingSprite
import net.minecraft.client.texture.Sprite
import net.minecraft.client.util.SpriteIdentifier
import net.minecraft.util.Identifier
import opekope2.avm_staff.api.item.model.IStaffItemBakedModel
import opekope2.avm_staff.internal.item.model.UnbakedStaffItemModel
import java.util.function.Function

@Environment(EnvType.CLIENT)
class UnbakedFabricStaffItemModel(private val original: JsonUnbakedModel) : UnbakedStaffItemModel(original) {
override fun bake(
baker: Baker,
textureGetter: Function<SpriteIdentifier, Sprite>,
rotationContainer: ModelBakeSettings,
modelId: Identifier,
itemModels: Map<Identifier, IStaffItemBakedModel>
): BakedModel? {
return BakedFabricStaffItemModel(
original.bake(baker, textureGetter, rotationContainer, modelId) ?: return null,
itemModels,
baker.bake(MissingSprite.getMissingSpriteId(), rotationContainer)!!
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* AvM Staff Mod
* Copyright (c) 2016-2024 opekope2
*
* This mod is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This mod is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this mod. If not, see <https://www.gnu.org/licenses/>.
*/

package opekope2.avm_staff.mixin.forge;

import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import net.minecraft.client.render.model.Baker;
import net.minecraft.client.render.model.UnbakedModel;
import net.minecraft.client.render.model.json.JsonUnbakedModel;
import net.minecraft.util.Identifier;
import opekope2.avm_staff.internal.forge.item.model.UnbakedForgeStaffItemModel;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Coerce;

import static opekope2.avm_staff.util.Constants.MOD_ID;

// Forge geometry loaders are way more difficult, than porting a Fabric mixin
@Mixin(targets = "net/minecraft/client/render/model/ModelLoader$BakerImpl")
public class ModelLoaderBakerImplMixin {
// Change method to directly call Staff Mod instead of an exposed event
// Ignore this error, IntelliJ/mcdev is not looking at the correct jar
@WrapOperation(
method = "bake(Lnet/minecraft/util/Identifier;Lnet/minecraft/client/render/model/ModelBakeSettings;Ljava/util/function/Function;)Lnet/minecraft/client/render/model/BakedModel;",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/render/model/ModelLoader$BakerImpl;getOrLoadModel(Lnet/minecraft/util/Identifier;)Lnet/minecraft/client/render/model/UnbakedModel;"
)
)
private UnbakedModel modifyUnbakedModel(@Coerce Baker thiz, Identifier id, Operation<UnbakedModel> original) {
UnbakedModel model = original.call(thiz, id);
if (!MOD_ID.equals(id.getNamespace())) return model;

return switch (id.getPath()) {
// TODO hardcoded paths
case "staff", "item/staff_in_use" -> new UnbakedForgeStaffItemModel((JsonUnbakedModel) model); // FIXME
default -> model;
};
}

// Remove unused mixins: invokeModifyAfterBake
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,26 +20,22 @@ package opekope2.avm_staff.internal.forge

import net.minecraft.client.MinecraftClient
import net.minecraft.client.item.ModelPredicateProviderRegistry
import net.minecraft.client.util.ModelIdentifier
import net.minecraft.item.ItemGroup.StackVisibility.PARENT_AND_SEARCH_TABS
import net.minecraft.item.ItemGroups
import net.minecraft.item.ItemStack
import net.minecraft.item.Items
import net.minecraftforge.api.distmarker.Dist
import net.minecraftforge.api.distmarker.OnlyIn
import net.minecraftforge.client.event.ModelEvent
import net.minecraftforge.client.event.RegisterKeyMappingsEvent
import net.minecraftforge.common.MinecraftForge.EVENT_BUS
import net.minecraftforge.event.BuildCreativeModeTabContentsEvent
import net.minecraftforge.event.TickEvent
import net.minecraftforge.eventbus.api.SubscribeEvent
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent
import opekope2.avm_staff.internal.event_handler.ADD_REMOVE_KEYBINDING
import opekope2.avm_staff.internal.forge.item.model.StaffItemModel
import opekope2.avm_staff.internal.event_handler.handleKeyBindings
import opekope2.avm_staff.internal.platform.forge.getStaffMod
import opekope2.avm_staff.internal.registerModelPredicateProviders
import opekope2.avm_staff.util.MOD_ID
import thedarkcolour.kotlinforforge.forge.MOD_BUS

@OnlyIn(Dist.CLIENT)
Expand Down Expand Up @@ -85,11 +81,4 @@ object StaffModClient {

handleKeyBindings(MinecraftClient.getInstance())
}

@SubscribeEvent
fun modifyModelAfterBake(event: ModelEvent.ModifyBakingResult) {
val id = ModelIdentifier(MOD_ID, "staff", "inventory")

event.models[id] = StaffItemModel(event.models[id]!!)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,21 @@ import net.minecraft.client.render.model.BakedModel
import net.minecraft.client.render.model.json.ModelTransformationMode
import net.minecraft.client.util.math.MatrixStack
import net.minecraft.item.ItemStack
import net.minecraft.util.Identifier
import net.minecraftforge.api.distmarker.Dist
import net.minecraftforge.api.distmarker.OnlyIn
import net.minecraftforge.client.model.BakedModelWrapper
import opekope2.avm_staff.util.handlerOfItemOrFallback
import net.minecraftforge.registries.ForgeRegistries
import opekope2.avm_staff.api.item.model.IStaffItemBakedModel
import opekope2.avm_staff.util.isItemInStaff
import opekope2.avm_staff.util.itemInStaff

class StaffItemModel(original: BakedModel) : BakedModelWrapper<BakedModel>(original) {
@OnlyIn(Dist.CLIENT)
class BakedForgeStaffItemModel(
original: BakedModel,
private val itemModels: Map<Identifier, IStaffItemBakedModel>,
private val missingModel: BakedModel
) : BakedModelWrapper<BakedModel>(original) {
override fun applyTransform(
cameraTransformType: ModelTransformationMode,
poseStack: MatrixStack,
Expand All @@ -38,13 +47,12 @@ class StaffItemModel(original: BakedModel) : BakedModelWrapper<BakedModel>(origi
return this
}

override fun getRenderPasses(itemStack: ItemStack, fabulous: Boolean): MutableList<BakedModel> {
if (!itemStack.isItemInStaff) return mutableListOf(this)
override fun getRenderPasses(stack: ItemStack, fabulous: Boolean): MutableList<BakedModel> {
if (!stack.isItemInStaff) return mutableListOf(this)

val staffItemStack = itemStack.itemInStaff
val handler = staffItemStack.handlerOfItemOrFallback
val itemStack = stack.itemInStaff ?: return mutableListOf(this)

val model = handler.itemModelProvider.getModel(itemStack)
val model = itemModels[ForgeRegistries.ITEMS.getKey(itemStack.item)]?.getModel(stack) ?: missingModel
return mutableListOf(this, model)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* AvM Staff Mod
* Copyright (c) 2024 opekope2
*
* This mod is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This mod is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this mod. If not, see <https://www.gnu.org/licenses/>.
*/

package opekope2.avm_staff.internal.forge.item.model

import net.minecraft.client.render.model.BakedModel
import net.minecraft.client.render.model.Baker
import net.minecraft.client.render.model.ModelBakeSettings
import net.minecraft.client.render.model.json.JsonUnbakedModel
import net.minecraft.client.texture.MissingSprite
import net.minecraft.client.texture.Sprite
import net.minecraft.client.util.SpriteIdentifier
import net.minecraft.util.Identifier
import net.minecraftforge.api.distmarker.Dist
import net.minecraftforge.api.distmarker.OnlyIn
import opekope2.avm_staff.api.item.model.IStaffItemBakedModel
import opekope2.avm_staff.internal.item.model.UnbakedStaffItemModel
import java.util.function.Function

@OnlyIn(Dist.CLIENT)
class UnbakedForgeStaffItemModel(private val original: JsonUnbakedModel) : UnbakedStaffItemModel(original) {
override fun bake(
baker: Baker,
textureGetter: Function<SpriteIdentifier, Sprite>,
rotationContainer: ModelBakeSettings,
modelId: Identifier,
itemModels: Map<Identifier, IStaffItemBakedModel>
): BakedModel? {
return BakedForgeStaffItemModel(
original.bake(baker, original, textureGetter, rotationContainer, modelId, true) ?: return null,
itemModels,
baker.bake(MissingSprite.getMissingSpriteId(), rotationContainer, textureGetter)!!
)
}
}
3 changes: 2 additions & 1 deletion ForgeMod/src/main/resources/avm_staff_forge.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"defaultRequire": 1
},
"client": [
"ClientPlayerInteractionManagerMixin"
"ClientPlayerInteractionManagerMixin",
"ModelLoaderBakerImplMixin"
],
"mixins": [
"ServerPlayerEntityMixin",
Expand Down

This file was deleted.

Loading

0 comments on commit 853550e

Please sign in to comment.