From f1b599275a68ca0d4ec8f6b366edcef9668efd3f Mon Sep 17 00:00:00 2001 From: i509VCB <git@i509.me> Date: Sun, 14 Feb 2021 12:58:41 -0600 Subject: [PATCH] Add registry for creating entity model layers and texture data (#1197) * Add registry for creating entity model layers and texture data * Add ApiStatus annotations and document factory method * Helper -> Registry --- .../v1/EntityModelLayerRegistry.java | 71 +++++++++++++++++++ .../v1/EntityRendererRegistry.java | 2 + .../registry/EntityModelLayerImpl.java | 34 +++++++++ .../registry/EntityModelLayersAccessor.java | 33 +++++++++ .../renderer/registry/EntityModelsMixin.java | 43 +++++++++++ .../fabric-renderer-registries-v1.mixins.json | 2 + 6 files changed, 185 insertions(+) create mode 100644 fabric-renderer-registries-v1/src/main/java/net/fabricmc/fabric/api/client/rendereregistry/v1/EntityModelLayerRegistry.java create mode 100644 fabric-renderer-registries-v1/src/main/java/net/fabricmc/fabric/impl/client/renderer/registry/EntityModelLayerImpl.java create mode 100644 fabric-renderer-registries-v1/src/main/java/net/fabricmc/fabric/mixin/client/renderer/registry/EntityModelLayersAccessor.java create mode 100644 fabric-renderer-registries-v1/src/main/java/net/fabricmc/fabric/mixin/client/renderer/registry/EntityModelsMixin.java diff --git a/fabric-renderer-registries-v1/src/main/java/net/fabricmc/fabric/api/client/rendereregistry/v1/EntityModelLayerRegistry.java b/fabric-renderer-registries-v1/src/main/java/net/fabricmc/fabric/api/client/rendereregistry/v1/EntityModelLayerRegistry.java new file mode 100644 index 000000000..c4553f54c --- /dev/null +++ b/fabric-renderer-registries-v1/src/main/java/net/fabricmc/fabric/api/client/rendereregistry/v1/EntityModelLayerRegistry.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.fabricmc.fabric.api.client.rendereregistry.v1; + +import java.util.Objects; + +import org.jetbrains.annotations.ApiStatus; + +import net.minecraft.client.model.TexturedModelData; +import net.minecraft.client.render.entity.model.EntityModelLayer; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.impl.client.renderer.registry.EntityModelLayerImpl; +import net.fabricmc.fabric.mixin.client.renderer.registry.EntityModelLayersAccessor; + +/** + * A helpers for registering entity model layers and providers for the layer's textured model data. + * + * @deprecated Experimental feature, may be removed or changed without further notice: Snapshot feature. + */ +@Deprecated +@ApiStatus.Experimental +@Environment(EnvType.CLIENT) +public final class EntityModelLayerRegistry { + /** + * Registers an entity model layer and registers a provider for a {@linkplain TexturedModelData}. + * + * @param modelLayer the entity model layer + * @param provider the provider for the textured model data + */ + public static void registerModelLayer(EntityModelLayer modelLayer, TexturedModelDataProvider provider) { + Objects.requireNonNull(modelLayer, "EntityModelLayer cannot be null"); + Objects.requireNonNull(provider, "TexturedModelDataProvider cannot be null"); + + if (EntityModelLayerImpl.PROVIDERS.putIfAbsent(modelLayer, provider) != null) { + throw new IllegalArgumentException(String.format("Cannot replace registration for entity model layer \"%s\"", modelLayer)); + } + + EntityModelLayersAccessor.getLayers().add(modelLayer); + } + + private EntityModelLayerRegistry() { + } + + @FunctionalInterface + @ApiStatus.Experimental + @Environment(EnvType.CLIENT) + public interface TexturedModelDataProvider { + /** + * Creates the textured model data for use in a {@link EntityModelLayer}. + * + * @return the textured model data for the entity model layer. + */ + TexturedModelData createModelData(); + } +} diff --git a/fabric-renderer-registries-v1/src/main/java/net/fabricmc/fabric/api/client/rendereregistry/v1/EntityRendererRegistry.java b/fabric-renderer-registries-v1/src/main/java/net/fabricmc/fabric/api/client/rendereregistry/v1/EntityRendererRegistry.java index 867bea85d..bedff324a 100644 --- a/fabric-renderer-registries-v1/src/main/java/net/fabricmc/fabric/api/client/rendereregistry/v1/EntityRendererRegistry.java +++ b/fabric-renderer-registries-v1/src/main/java/net/fabricmc/fabric/api/client/rendereregistry/v1/EntityRendererRegistry.java @@ -16,6 +16,8 @@ package net.fabricmc.fabric.api.client.rendereregistry.v1; +import net.minecraft.client.render.entity.EntityRenderDispatcher; +import net.minecraft.client.render.entity.EntityRenderer; import net.minecraft.client.render.entity.EntityRendererFactory; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; diff --git a/fabric-renderer-registries-v1/src/main/java/net/fabricmc/fabric/impl/client/renderer/registry/EntityModelLayerImpl.java b/fabric-renderer-registries-v1/src/main/java/net/fabricmc/fabric/impl/client/renderer/registry/EntityModelLayerImpl.java new file mode 100644 index 000000000..c2bc300b1 --- /dev/null +++ b/fabric-renderer-registries-v1/src/main/java/net/fabricmc/fabric/impl/client/renderer/registry/EntityModelLayerImpl.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.fabricmc.fabric.impl.client.renderer.registry; + +import java.util.HashMap; +import java.util.Map; + +import net.minecraft.client.render.entity.model.EntityModelLayer; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.client.rendereregistry.v1.EntityModelLayerRegistry; + +@Environment(EnvType.CLIENT) +public final class EntityModelLayerImpl { + public static final Map<EntityModelLayer, EntityModelLayerRegistry.TexturedModelDataProvider> PROVIDERS = new HashMap<>(); + + private EntityModelLayerImpl() { + } +} diff --git a/fabric-renderer-registries-v1/src/main/java/net/fabricmc/fabric/mixin/client/renderer/registry/EntityModelLayersAccessor.java b/fabric-renderer-registries-v1/src/main/java/net/fabricmc/fabric/mixin/client/renderer/registry/EntityModelLayersAccessor.java new file mode 100644 index 000000000..a0bea64d2 --- /dev/null +++ b/fabric-renderer-registries-v1/src/main/java/net/fabricmc/fabric/mixin/client/renderer/registry/EntityModelLayersAccessor.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.fabricmc.fabric.mixin.client.renderer.registry; + +import java.util.Set; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import net.minecraft.client.render.entity.model.EntityModelLayer; +import net.minecraft.client.render.entity.model.EntityModelLayers; + +@Mixin(EntityModelLayers.class) +public interface EntityModelLayersAccessor { + @Accessor("LAYERS") + static Set<EntityModelLayer> getLayers() { + throw new AssertionError("This should not occur!"); + } +} diff --git a/fabric-renderer-registries-v1/src/main/java/net/fabricmc/fabric/mixin/client/renderer/registry/EntityModelsMixin.java b/fabric-renderer-registries-v1/src/main/java/net/fabricmc/fabric/mixin/client/renderer/registry/EntityModelsMixin.java new file mode 100644 index 000000000..9d1627f12 --- /dev/null +++ b/fabric-renderer-registries-v1/src/main/java/net/fabricmc/fabric/mixin/client/renderer/registry/EntityModelsMixin.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.fabricmc.fabric.mixin.client.renderer.registry; + +import java.util.Map; + +import com.google.common.collect.ImmutableMap; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; + +import net.minecraft.client.model.TexturedModelData; +import net.minecraft.client.render.entity.model.EntityModelLayer; +import net.minecraft.client.render.entity.model.EntityModels; + +import net.fabricmc.fabric.api.client.rendereregistry.v1.EntityModelLayerRegistry; +import net.fabricmc.fabric.impl.client.renderer.registry.EntityModelLayerImpl; + +@Mixin(EntityModels.class) +abstract class EntityModelsMixin { + @Inject(method = "getModels", at = @At(value = "INVOKE", target = "Lcom/google/common/collect/ImmutableMap$Builder;build()Lcom/google/common/collect/ImmutableMap;"), locals = LocalCapture.CAPTURE_FAILEXCEPTION) + private static void registerExtraModelData(CallbackInfoReturnable<Map<EntityModelLayer, TexturedModelData>> info, ImmutableMap.Builder<EntityModelLayer, TexturedModelData> builder) { + for (Map.Entry<EntityModelLayer, EntityModelLayerRegistry.TexturedModelDataProvider> entry : EntityModelLayerImpl.PROVIDERS.entrySet()) { + builder.put(entry.getKey(), entry.getValue().createModelData()); + } + } +} diff --git a/fabric-renderer-registries-v1/src/main/resources/fabric-renderer-registries-v1.mixins.json b/fabric-renderer-registries-v1/src/main/resources/fabric-renderer-registries-v1.mixins.json index c6ca53822..b60c3ac34 100644 --- a/fabric-renderer-registries-v1/src/main/resources/fabric-renderer-registries-v1.mixins.json +++ b/fabric-renderer-registries-v1/src/main/resources/fabric-renderer-registries-v1.mixins.json @@ -3,6 +3,8 @@ "package": "net.fabricmc.fabric.mixin.client.renderer.registry", "compatibilityLevel": "JAVA_8", "client": [ + "EntityModelLayersAccessor", + "EntityModelsMixin", "LivingEntityRendererAccessor", "MixinBlockEntityRenderers", "MixinEntityRenderers"