Allow getting BakedModels using Identifiers ()

This commit is contained in:
PepperCode1 2021-04-18 06:06:02 -07:00 committed by Player
parent 12865e786c
commit 2263f53eac
11 changed files with 363 additions and 0 deletions
fabric-models-v0
build.gradle
src
main
java/net/fabricmc/fabric
resources
testmod

View file

@ -4,3 +4,8 @@ version = getSubprojectVersion(project, "0.2.2")
moduleDependencies(project, [
'fabric-api-base'
])
dependencies {
testmodCompile project(path: ':fabric-renderer-registries-v1', configuration: 'dev')
testmodCompile project(path: ':fabric-resource-loader-v0', configuration: 'dev')
}

View file

@ -0,0 +1,49 @@
/*
* 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.model;
import org.jetbrains.annotations.Nullable;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.render.model.BakedModelManager;
import net.minecraft.client.util.ModelIdentifier;
import net.minecraft.util.Identifier;
import net.fabricmc.fabric.impl.client.model.BakedModelManagerHooks;
public final class BakedModelManagerHelper {
/**
* An alternative to {@link BakedModelManager#getModel(ModelIdentifier)} that accepts an
* {@link Identifier} instead. Models loaded using {@link ExtraModelProvider} do not have a
* corresponding {@link ModelIdentifier}, so the vanilla method cannot be used to retrieve them.
* The Identifier that was used to load them can be used in this method to retrieve them.
*
* <p><b>This method, as well as its vanilla counterpart, should only be used after the
* {@link BakedModelManager} has completed reloading.</b> Otherwise, the result will be
* null or an old model.
*
* @param manager the manager that holds models
* @param id the id of the model
* @return the model
*/
@Nullable
public static BakedModel getModel(BakedModelManager manager, Identifier id) {
return ((BakedModelManagerHooks) manager).fabric_getModel(id);
}
private BakedModelManagerHelper() { }
}

View file

@ -0,0 +1,24 @@
/*
* 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.model;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.util.Identifier;
public interface BakedModelManagerHooks {
BakedModel fabric_getModel(Identifier id);
}

View file

@ -0,0 +1,39 @@
/*
* 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.model;
import java.util.Map;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.render.model.BakedModelManager;
import net.minecraft.util.Identifier;
import net.fabricmc.fabric.impl.client.model.BakedModelManagerHooks;
@Mixin(BakedModelManager.class)
public class MixinBakedModelManager implements BakedModelManagerHooks {
@Shadow
private Map<Identifier, BakedModel> models;
@Override
public BakedModel fabric_getModel(Identifier id) {
return models.get(id);
}
}

View file

@ -3,6 +3,7 @@
"package": "net.fabricmc.fabric.mixin.client.model",
"compatibilityLevel": "JAVA_8",
"client": [
"MixinBakedModelManager",
"MixinModelLoader"
],
"injectors": {

View file

@ -0,0 +1,54 @@
/*
* 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.test.model;
import java.util.function.Supplier;
import net.minecraft.client.render.TexturedRenderLayers;
import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.entity.feature.FeatureRenderer;
import net.minecraft.client.render.entity.feature.FeatureRendererContext;
import net.minecraft.client.render.entity.model.EntityModel;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.LivingEntity;
import net.minecraft.util.math.Vec3f;
public class BakedModelFeatureRenderer<T extends LivingEntity, M extends EntityModel<T>> extends FeatureRenderer<T, M> {
private Supplier<BakedModel> modelSupplier;
public BakedModelFeatureRenderer(FeatureRendererContext<T, M> context, Supplier<BakedModel> modelSupplier) {
super(context);
this.modelSupplier = modelSupplier;
}
@Override
public void render(MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, T entity, float limbAngle, float limbDistance, float tickDelta, float animationProgress, float headYaw, float headPitch) {
BakedModel model = modelSupplier.get();
VertexConsumer vertices = vertexConsumers.getBuffer(TexturedRenderLayers.getEntityCutout());
matrices.push();
//matrices.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(headYaw));
//matrices.multiply(Vector3f.POSITIVE_X.getDegreesQuaternion(headPitch));
matrices.multiply(Vec3f.POSITIVE_Y.getRadialQuaternion(animationProgress * 0.07F));
matrices.scale(-0.75F, -0.75F, 0.75F);
float aboveHead = (float) (Math.sin(animationProgress * 0.08F)) * 0.5F + 0.5F;
matrices.translate(-0.5F, 0.75F + aboveHead, -0.5F);
BakedModelRenderer.renderBakedModel(model, vertices, matrices.peek(), light);
matrices.pop();
}
}

View file

@ -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.test.model;
import java.util.Random;
import org.apache.commons.lang3.ArrayUtils;
import net.minecraft.client.render.OverlayTexture;
import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.render.model.BakedQuad;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.math.Direction;
public class BakedModelRenderer {
private static final Direction[] CULL_FACES = ArrayUtils.add(Direction.values(), null);
private static final Random RANDOM = new Random();
public static void renderBakedModel(BakedModel model, VertexConsumer vertices, MatrixStack.Entry entry, int light) {
for (Direction cullFace : CULL_FACES) {
RANDOM.setSeed(42L);
for (BakedQuad quad : model.getQuads(null, cullFace, RANDOM)) {
vertices.quad(entry, quad, 1.0F, 1.0F, 1.0F, light, OverlayTexture.DEFAULT_UV);
}
}
}
}

View file

@ -0,0 +1,47 @@
/*
* 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.test.model;
import net.minecraft.client.render.entity.PlayerEntityRenderer;
import net.minecraft.resource.ResourceType;
import net.minecraft.util.Identifier;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.model.ModelLoadingRegistry;
import net.fabricmc.fabric.api.client.rendereregistry.v1.LivingEntityFeatureRendererRegistrationCallback;
import net.fabricmc.fabric.api.resource.ResourceManagerHelper;
public class ModelTestModClient implements ClientModInitializer {
public static final String ID = "fabric-models-v0-testmod";
public static final Identifier MODEL_ID = new Identifier(ID, "half_red_sand");
@Override
public void onInitializeClient() {
ModelLoadingRegistry.INSTANCE.registerModelProvider((manager, out) -> {
out.accept(MODEL_ID);
});
ResourceManagerHelper.get(ResourceType.CLIENT_RESOURCES).registerReloadListener(SpecificModelReloadListener.INSTANCE);
LivingEntityFeatureRendererRegistrationCallback.EVENT.register((entityType, entityRenderer, registrationHelper, context) -> {
if (entityRenderer instanceof PlayerEntityRenderer) {
registrationHelper.register(new BakedModelFeatureRenderer<>((PlayerEntityRenderer) entityRenderer, SpecificModelReloadListener.INSTANCE::getSpecificModel));
}
});
}
}

View file

@ -0,0 +1,63 @@
/*
* 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.test.model;
import java.util.Arrays;
import java.util.Collection;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.resource.ResourceManager;
import net.minecraft.resource.SinglePreparationResourceReloader;
import net.minecraft.util.Identifier;
import net.minecraft.util.Unit;
import net.minecraft.util.profiler.Profiler;
import net.fabricmc.fabric.api.client.model.BakedModelManagerHelper;
import net.fabricmc.fabric.api.resource.IdentifiableResourceReloadListener;
import net.fabricmc.fabric.api.resource.ResourceReloadListenerKeys;
public class SpecificModelReloadListener extends SinglePreparationResourceReloader<Unit> implements IdentifiableResourceReloadListener {
public static final SpecificModelReloadListener INSTANCE = new SpecificModelReloadListener();
public static final Identifier ID = new Identifier(ModelTestModClient.ID, "specific_model");
private BakedModel specificModel;
public BakedModel getSpecificModel() {
return specificModel;
}
@Override
protected Unit prepare(ResourceManager manager, Profiler profiler) {
return Unit.INSTANCE;
}
@Override
protected void apply(Unit loader, ResourceManager manager, Profiler profiler) {
specificModel = BakedModelManagerHelper.getModel(MinecraftClient.getInstance().getBakedModelManager(), ModelTestModClient.MODEL_ID);
}
@Override
public Identifier getFabricId() {
return ID;
}
@Override
public Collection<Identifier> getFabricDependencies() {
return Arrays.asList(ResourceReloadListenerKeys.MODELS);
}
}

View file

@ -0,0 +1,20 @@
{
"textures": {
"sand": "minecraft:block/sand",
"red_sand": "minecraft:block/red_sand"
},
"elements": [
{
"from": [ 0, 0, 0 ],
"to": [ 16, 16, 16 ],
"faces": {
"down": { "texture": "#sand" },
"up": { "texture": "#red_sand" },
"north": { "texture": "#sand" },
"south": { "texture": "#red_sand" },
"west": { "texture": "#sand" },
"east": { "texture": "#red_sand" }
}
}
]
}

View file

@ -0,0 +1,18 @@
{
"schemaVersion": 1,
"id": "fabric-models-v0-testmod",
"name": "Fabric Models (v0) Test Mod",
"version": "1.0.0",
"environment": "client",
"license": "Apache-2.0",
"depends": {
"fabric-models-v0": "*",
"fabric-renderer-registries-v1": "*",
"fabric-resource-loader-v0": "*"
},
"entrypoints": {
"client": [
"net.fabricmc.fabric.test.model.ModelTestModClient"
]
}
}