mirror of
https://github.com/MineLittlePony/MineLittlePony.git
synced 2024-11-28 23:17:59 +01:00
Clean up the EquineRendermanager (should fix some crashing issues with null seapony models)
This commit is contained in:
parent
f54cd5682d
commit
76a2e043b7
14 changed files with 189 additions and 202 deletions
|
@ -18,14 +18,14 @@ import java.util.function.Consumer;
|
|||
/**
|
||||
* Container class for the various models and their associated piece of armour.
|
||||
*/
|
||||
public class ModelWrapper<T extends LivingEntity, M extends PonyModel<?>> {
|
||||
public class Models<T extends LivingEntity, M extends PonyModel<?>> {
|
||||
@Nullable
|
||||
private final MsonModel.Factory<PonyArmourModel<T>> armorFactory;
|
||||
private final Map<ModelKey<PonyArmourModel<?>>, PonyArmourModel<T>> armor = new HashMap<>();
|
||||
|
||||
private final M body;
|
||||
|
||||
public ModelWrapper(PlayerModelKey<T, ? super M> playerModelKey, boolean slimArms, @Nullable Consumer<M> initializer) {
|
||||
public Models(PlayerModelKey<T, ? super M> playerModelKey, boolean slimArms, @Nullable Consumer<M> initializer) {
|
||||
this.armorFactory = playerModelKey.armorFactory();
|
||||
this.body = playerModelKey.getKey(slimArms).createModel();
|
||||
if (initializer != null) {
|
||||
|
@ -33,7 +33,7 @@ public class ModelWrapper<T extends LivingEntity, M extends PonyModel<?>> {
|
|||
}
|
||||
}
|
||||
|
||||
public ModelWrapper(ModelKey<M> key) {
|
||||
public Models(ModelKey<M> key) {
|
||||
this.armorFactory = null;
|
||||
this.body = key.createModel();
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ public class ModelWrapper<T extends LivingEntity, M extends PonyModel<?>> {
|
|||
}));
|
||||
}
|
||||
|
||||
public ModelWrapper<T, M> applyMetadata(PonyData meta) {
|
||||
public Models<T, M> applyMetadata(PonyData meta) {
|
||||
body.setMetadata(meta);
|
||||
armor.values().forEach(a -> a.setMetadata(meta));
|
||||
return this;
|
|
@ -7,7 +7,7 @@ import net.minecraft.util.Identifier;
|
|||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.minelittlepony.api.model.ModelWrapper;
|
||||
import com.minelittlepony.api.model.Models;
|
||||
import com.minelittlepony.api.model.PonyModel;
|
||||
import com.minelittlepony.client.model.armour.PonyArmourModel;
|
||||
import com.minelittlepony.mson.api.*;
|
||||
|
@ -31,12 +31,12 @@ public record PlayerModelKey<T extends LivingEntity, M extends Model & PonyModel
|
|||
return slimArms ? alexKey : steveKey;
|
||||
}
|
||||
|
||||
public <E extends T, N extends M> ModelWrapper<E, N> create(boolean slimArms) {
|
||||
public <E extends T, N extends M> Models<E, N> create(boolean slimArms) {
|
||||
return create(slimArms, null);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public <E extends T, N extends M> ModelWrapper<E, N> create(boolean slimArms, @Nullable Consumer<N> initializer) {
|
||||
return new ModelWrapper(this, slimArms, initializer);
|
||||
public <E extends T, N extends M> Models<E, N> create(boolean slimArms, @Nullable Consumer<N> initializer) {
|
||||
return new Models(this, slimArms, initializer);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import com.minelittlepony.util.MathUtil;
|
|||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.function.Function;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
|
@ -26,40 +27,38 @@ import org.jetbrains.annotations.Nullable;
|
|||
|
||||
public class EquineRenderManager<T extends LivingEntity, M extends EntityModel<T> & PonyModel<T>> {
|
||||
|
||||
private ModelWrapper<T, M> playerModel;
|
||||
private Models<T, M> models;
|
||||
@Nullable
|
||||
private Function<T, Models<T, M>> modelsLookup;
|
||||
|
||||
private final PonyRenderContext<T, M> renderer;
|
||||
private final PonyRenderContext<T, M> context;
|
||||
private final Transformer<T> transformer;
|
||||
|
||||
private final FrustrumCheck<T> frustrum = new FrustrumCheck<>(this);
|
||||
private final FrustrumCheck<T> frustrum;
|
||||
|
||||
public static void disableModelRenderProfile() {
|
||||
RenderSystem.disableBlend();
|
||||
}
|
||||
|
||||
public EquineRenderManager(PonyRenderContext<T, M> renderer) {
|
||||
this.renderer = renderer;
|
||||
}
|
||||
|
||||
public PonyRenderContext<T, M> getContext() {
|
||||
return renderer;
|
||||
}
|
||||
|
||||
public ModelWrapper<T, M> getModelWrapper() {
|
||||
return playerModel;
|
||||
}
|
||||
|
||||
public M getModel() {
|
||||
return playerModel.body();
|
||||
public EquineRenderManager(PonyRenderContext<T, M> context, Transformer<T> transformer, Models<T, M> models) {
|
||||
this.context = context;
|
||||
this.transformer = transformer;
|
||||
this.models = models;
|
||||
frustrum = new FrustrumCheck<>(context);
|
||||
context.setModel(models.body());
|
||||
}
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public ModelWrapper<T, M> setModel(ModelKey<? super M> key) {
|
||||
return setModel(new ModelWrapper(key));
|
||||
public EquineRenderManager(PonyRenderContext<T, M> context, Transformer<T> transformer, ModelKey<? super M> key) {
|
||||
this(context, transformer, new Models(key));
|
||||
}
|
||||
|
||||
public ModelWrapper<T, M> setModel(ModelWrapper<T, M> wrapper) {
|
||||
playerModel = wrapper;
|
||||
return wrapper;
|
||||
public void setModelsLookup(@Nullable Function<T, Models<T, M>> modelsLookup) {
|
||||
this.modelsLookup = modelsLookup;
|
||||
}
|
||||
|
||||
public Models<T, M> getModels() {
|
||||
return models;
|
||||
}
|
||||
|
||||
public Frustum getFrustrum(T entity, Frustum vanilla) {
|
||||
|
@ -73,7 +72,61 @@ public class EquineRenderManager<T extends LivingEntity, M extends EntityModel<T
|
|||
return frustrum.withCamera(entity, vanilla);
|
||||
}
|
||||
|
||||
public float getRenderYaw(T entity, float rotationYaw, float partialTicks) {
|
||||
public void preRender(T entity, ModelAttributes.Mode mode) {
|
||||
Pony pony = context.getEntityPony(entity);
|
||||
if (modelsLookup != null) {
|
||||
models = modelsLookup.apply(entity);
|
||||
context.setModel(models.body());
|
||||
}
|
||||
models.applyMetadata(pony.metadata());
|
||||
models.body().updateLivingState(entity, pony, mode);
|
||||
|
||||
if (entity instanceof PlayerEntity player && entity instanceof RegistrationHandler handler) {
|
||||
handler.getSyncedPony().synchronize(player, pony);
|
||||
}
|
||||
}
|
||||
|
||||
public void setupTransforms(T entity, MatrixStack stack, float ageInTicks, float rotationYaw, float tickDelta) {
|
||||
float s = getScaleFactor();
|
||||
stack.scale(s, s, s);
|
||||
|
||||
if (entity.hasVehicle() && entity.getVehicle() instanceof LivingEntity livingVehicles) {
|
||||
PonyRenderContext<LivingEntity, ?> renderer = MineLittlePony.getInstance().getRenderDispatcher().getPonyRenderer(livingVehicles);
|
||||
|
||||
if (renderer != null) {
|
||||
// negate vanilla translations so the rider begins at the ridees feet.
|
||||
stack.translate(0, -livingVehicles.getHeight(), 0);
|
||||
Pony pony = context.getEntityPony(entity);
|
||||
if (!pony.race().isHuman()) {
|
||||
renderer.getInternalRenderer().translateRider(livingVehicles, renderer.getEntityPony(livingVehicles), entity, pony, stack, tickDelta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (entity instanceof PlayerEntity) {
|
||||
if (getModels().body().getAttributes().isSitting) {
|
||||
stack.translate(0, 0.125D, 0);
|
||||
}
|
||||
}
|
||||
|
||||
rotationYaw = getMountedYaw(entity, rotationYaw, tickDelta);
|
||||
transformer.setupTransforms(entity, stack, ageInTicks, rotationYaw, tickDelta);
|
||||
|
||||
PonyPosture.of(getModels().body().getAttributes()).apply(entity, getModels().body(), stack, rotationYaw, tickDelta, 1);
|
||||
}
|
||||
|
||||
private void translateRider(T entity, Pony pony, LivingEntity passenger, Pony passengerPony, MatrixStack stack, float tickDelta) {
|
||||
if (!passengerPony.race().isHuman()) {
|
||||
float yaw = MathUtil.interpolateDegress((float)entity.prevY, (float)entity.getY(), tickDelta);
|
||||
|
||||
models.applyMetadata(pony.metadata());
|
||||
models.body().transform(BodyPart.BACK, stack);
|
||||
|
||||
PonyPosture.of(models.body().getAttributes()).apply(entity, getModels().body(), stack, yaw, tickDelta, -1);
|
||||
}
|
||||
}
|
||||
|
||||
private float getMountedYaw(T entity, float rotationYaw, float partialTicks) {
|
||||
if (entity.hasVehicle()) {
|
||||
Entity mount = entity.getVehicle();
|
||||
if (mount instanceof LivingEntity) {
|
||||
|
@ -84,91 +137,20 @@ public class EquineRenderManager<T extends LivingEntity, M extends EntityModel<T
|
|||
return rotationYaw;
|
||||
}
|
||||
|
||||
public void preRenderCallback(T entity, MatrixStack stack, float ticks) {
|
||||
updateModel(entity, ModelAttributes.Mode.THIRD_PERSON);
|
||||
|
||||
float s = getScaleFactor();
|
||||
stack.scale(s, s, s);
|
||||
|
||||
translateRider(entity, stack, ticks);
|
||||
}
|
||||
|
||||
private void translateRider(T entity, MatrixStack stack, float ticks) {
|
||||
if (entity.hasVehicle() && entity.getVehicle() instanceof LivingEntity) {
|
||||
|
||||
LivingEntity ridingEntity = (LivingEntity) entity.getVehicle();
|
||||
PonyRenderContext<LivingEntity, ?> renderer = MineLittlePony.getInstance().getRenderDispatcher().getPonyRenderer(ridingEntity);
|
||||
|
||||
if (renderer != null) {
|
||||
// negate vanilla translations so the rider begins at the ridees feet.
|
||||
stack.translate(0, -ridingEntity.getHeight(), 0);
|
||||
|
||||
Pony riderPony = renderer.getEntityPony(ridingEntity);
|
||||
|
||||
renderer.translateRider(ridingEntity, riderPony, entity, renderer.getEntityPony(entity), stack, ticks);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setupTransforms(T entity, MatrixStack stack, float yaw, float tickDelta) {
|
||||
PonyPosture.of(getModel().getAttributes()).apply(entity, getModel(), stack, yaw, tickDelta, 1);
|
||||
}
|
||||
|
||||
public void applyPostureRiding(T entity, MatrixStack stack, float yaw, float tickDelta) {
|
||||
PonyPosture.of(getModel().getAttributes()).apply(entity, getModel(), stack, yaw, tickDelta, -1);
|
||||
}
|
||||
|
||||
public Pony updateModel(T entity, ModelAttributes.Mode mode) {
|
||||
Pony pony = renderer.getEntityPony(entity);
|
||||
playerModel.applyMetadata(pony.metadata());
|
||||
|
||||
if (entity instanceof PlayerEntity player && entity instanceof RegistrationHandler handler) {
|
||||
SyncedPony synced = handler.getSyncedPony();
|
||||
boolean changed = pony.compareTo(synced.lastRenderedPony) != 0;
|
||||
|
||||
if (changed) {
|
||||
synced.lastRenderedPony = pony;
|
||||
player.calculateDimensions();
|
||||
}
|
||||
|
||||
if (!(player instanceof PreviewModel)) {
|
||||
@Nullable
|
||||
PlayerEntity clientPlayer = MinecraftClient.getInstance().player;
|
||||
|
||||
if (pony.compareTo(synced.lastTransmittedPony) != 0) {
|
||||
if (clientPlayer != null && (Objects.equals(player, clientPlayer) || Objects.equals(player.getGameProfile(), clientPlayer.getGameProfile()))) {
|
||||
if (Channel.broadcastPonyData(pony.metadata())) {
|
||||
synced.lastTransmittedPony = pony;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
PonyDataCallback.EVENT.invoker().onPonyDataAvailable(player, pony.metadata(), EnvType.CLIENT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getModel().updateLivingState(entity, pony, mode);
|
||||
|
||||
return pony;
|
||||
}
|
||||
|
||||
public float getScaleFactor() {
|
||||
return getModel().getSize().scaleFactor();
|
||||
return getModels().body().getSize().scaleFactor();
|
||||
}
|
||||
|
||||
public float getShadowSize() {
|
||||
return getModel().getSize().shadowSize();
|
||||
return getModels().body().getSize().shadowSize();
|
||||
}
|
||||
|
||||
public double getNamePlateYOffset(T entity) {
|
||||
|
||||
// We start by negating the height calculation done by mahjong.
|
||||
float y = -(entity.getHeight() + 0.5F);
|
||||
|
||||
// Then we add our own offsets.
|
||||
y += getModel().getAttributes().visualHeight * getScaleFactor() + 0.25F;
|
||||
y += getModels().body().getAttributes().visualHeight * getScaleFactor() + 0.25F;
|
||||
|
||||
if (entity.isSneaking()) {
|
||||
y -= 0.25F;
|
||||
|
@ -185,14 +167,48 @@ public class EquineRenderManager<T extends LivingEntity, M extends EntityModel<T
|
|||
return y;
|
||||
}
|
||||
|
||||
public interface Transformer<T extends LivingEntity> {
|
||||
void setupTransforms(T entity, MatrixStack stack, float ageInTicks, float rotationYaw, float partialTicks);
|
||||
}
|
||||
|
||||
public interface RegistrationHandler {
|
||||
SyncedPony getSyncedPony();
|
||||
}
|
||||
|
||||
public interface ModelHolder<T extends LivingEntity, M extends EntityModel<T> & PonyModel<T>> {
|
||||
void setModel(M model);
|
||||
}
|
||||
|
||||
public static class SyncedPony {
|
||||
@Nullable
|
||||
private Pony lastRenderedPony;
|
||||
@Nullable
|
||||
private Pony lastTransmittedPony;
|
||||
|
||||
public void synchronize(PlayerEntity player, Pony pony) {
|
||||
boolean changed = pony.compareTo(lastRenderedPony) != 0;
|
||||
|
||||
if (changed) {
|
||||
lastRenderedPony = pony;
|
||||
player.calculateDimensions();
|
||||
}
|
||||
|
||||
if (!(player instanceof PreviewModel)) {
|
||||
@Nullable
|
||||
PlayerEntity clientPlayer = MinecraftClient.getInstance().player;
|
||||
|
||||
if (pony.compareTo(lastTransmittedPony) != 0) {
|
||||
if (clientPlayer != null && (Objects.equals(player, clientPlayer) || Objects.equals(player.getGameProfile(), clientPlayer.getGameProfile()))) {
|
||||
if (Channel.broadcastPonyData(pony.metadata())) {
|
||||
lastTransmittedPony = pony;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
PonyDataCallback.EVENT.invoker().onPonyDataAvailable(player, pony.metadata(), EnvType.CLIENT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,11 +19,11 @@ public class FrustrumCheck<T extends LivingEntity> extends Frustum {
|
|||
|
||||
private Frustum vanilla;
|
||||
|
||||
private final EquineRenderManager<T, ?> renderer;
|
||||
private final PonyRenderContext<T, ?> context;
|
||||
|
||||
public FrustrumCheck(EquineRenderManager<T, ?> render) {
|
||||
public FrustrumCheck(PonyRenderContext<T, ?> context) {
|
||||
super(new Matrix4f(), new Matrix4f());
|
||||
renderer = render;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public Frustum withCamera(T entity, Frustum vanillaFrustrum) {
|
||||
|
@ -34,7 +34,7 @@ public class FrustrumCheck<T extends LivingEntity> extends Frustum {
|
|||
|
||||
@Override
|
||||
public boolean isVisible(Box bounds) {
|
||||
return vanilla.isVisible(PonyBounds.getBoundingBox(renderer.getContext().getEntityPony(entity), entity));
|
||||
return vanilla.isVisible(PonyBounds.getBoundingBox(context.getEntityPony(entity), entity));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
package com.minelittlepony.client.render;
|
||||
|
||||
import com.minelittlepony.api.model.BodyPart;
|
||||
import com.minelittlepony.api.model.PonyModel;
|
||||
import com.minelittlepony.api.model.gear.Gear;
|
||||
import com.minelittlepony.api.pony.Pony;
|
||||
import com.minelittlepony.util.MathUtil;
|
||||
|
||||
import net.minecraft.client.render.entity.model.EntityModel;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
|
||||
public interface PonyRenderContext<T extends LivingEntity, M extends EntityModel<T> & PonyModel<T>> extends Gear.Context<T, M> {
|
||||
|
@ -16,19 +13,5 @@ public interface PonyRenderContext<T extends LivingEntity, M extends EntityModel
|
|||
|
||||
EquineRenderManager<T, M> getInternalRenderer();
|
||||
|
||||
/**
|
||||
* Called by riders to have their transportation adjust their position.
|
||||
*/
|
||||
default void translateRider(T entity, Pony entityPony, LivingEntity passenger, Pony passengerPony, MatrixStack stack, float ticks) {
|
||||
if (!passengerPony.race().isHuman()) {
|
||||
float yaw = MathUtil.interpolateDegress((float)entity.prevY, (float)entity.getY(), ticks);
|
||||
|
||||
getInternalRenderer().getModelWrapper().applyMetadata(entityPony.metadata());
|
||||
M model = getInternalRenderer().getModelWrapper().body();
|
||||
|
||||
model.transform(BodyPart.BACK, stack);
|
||||
|
||||
getInternalRenderer().applyPostureRiding(entity, stack, yaw, ticks);
|
||||
}
|
||||
}
|
||||
void setModel(M model);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.minelittlepony.client.render.entity;
|
||||
|
||||
import com.minelittlepony.api.model.ModelAttributes;
|
||||
import com.minelittlepony.api.model.PonyModel;
|
||||
import com.minelittlepony.api.pony.Pony;
|
||||
import com.minelittlepony.api.pony.meta.Wearable;
|
||||
|
@ -29,7 +30,7 @@ import net.minecraft.util.Identifier;
|
|||
|
||||
public abstract class AbstractPonyRenderer<T extends MobEntity, M extends EntityModel<T> & PonyModel<T> & ModelWithArms> extends MobEntityRenderer<T, M> implements PonyRenderContext<T, M> {
|
||||
|
||||
protected final EquineRenderManager<T, M> manager = new EquineRenderManager<>(this);
|
||||
protected final EquineRenderManager<T, M> manager;
|
||||
|
||||
private final Map<Wearable, Identifier> wearableTextures = new EnumMap<>(Wearable.class);
|
||||
|
||||
|
@ -39,7 +40,7 @@ public abstract class AbstractPonyRenderer<T extends MobEntity, M extends Entity
|
|||
|
||||
public AbstractPonyRenderer(EntityRendererFactory.Context context, ModelKey<? super M> key, TextureSupplier<T> texture, float scale) {
|
||||
super(context, null, 0.5F);
|
||||
this.model = manager.setModel(key).body();
|
||||
this.manager = new EquineRenderManager<>(this, super::setupTransforms, key);
|
||||
this.texture = texture;
|
||||
this.scale = scale;
|
||||
addFeatures(context);
|
||||
|
@ -64,24 +65,14 @@ public abstract class AbstractPonyRenderer<T extends MobEntity, M extends Entity
|
|||
|
||||
@Override
|
||||
public void render(T entity, float entityYaw, float tickDelta, MatrixStack stack, VertexConsumerProvider renderContext, int lightUv) {
|
||||
manager.preRender(entity, ModelAttributes.Mode.THIRD_PERSON);
|
||||
super.render(entity, entityYaw, tickDelta, stack, renderContext, lightUv);
|
||||
DebugBoundingBoxRenderer.render(getEntityPony(entity), this, entity, stack, renderContext, tickDelta);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setupTransforms(T entity, MatrixStack stack, float ageInTicks, float rotationYaw, float partialTicks) {
|
||||
manager.preRenderCallback(entity, stack, partialTicks);
|
||||
if (getModel() instanceof PlayerEntityModel) {
|
||||
((PlayerEntityModel<?>)getModel()).setVisible(true);
|
||||
}
|
||||
|
||||
if (getModel().getAttributes().isSitting) {
|
||||
stack.translate(0, 0.125D, 0);
|
||||
}
|
||||
|
||||
rotationYaw = manager.getRenderYaw(entity, rotationYaw, partialTicks);
|
||||
super.setupTransforms(entity, stack, ageInTicks, rotationYaw, partialTicks);
|
||||
manager.setupTransforms(entity, stack, rotationYaw, partialTicks);
|
||||
manager.setupTransforms(entity, stack, ageInTicks, rotationYaw, partialTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -117,8 +108,7 @@ public abstract class AbstractPonyRenderer<T extends MobEntity, M extends Entity
|
|||
@Override
|
||||
public Identifier getDefaultTexture(T entity, Wearable wearable) {
|
||||
return wearableTextures.computeIfAbsent(wearable, w -> {
|
||||
Identifier texture = getTexture(entity);
|
||||
texture = new Identifier(texture.getNamespace(), texture.getPath().split("\\.")[0] + "_" + wearable.name().toLowerCase(Locale.ROOT) + ".png");
|
||||
Identifier texture = getTexture(entity).withPath(path -> path.split("\\.")[0] + "_" + wearable.name().toLowerCase(Locale.ROOT) + ".png");
|
||||
|
||||
if (MinecraftClient.getInstance().getResourceManager().getResource(texture).isPresent()) {
|
||||
return texture;
|
||||
|
@ -127,6 +117,11 @@ public abstract class AbstractPonyRenderer<T extends MobEntity, M extends Entity
|
|||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setModel(M model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EquineRenderManager<T, M> getInternalRenderer() {
|
||||
return manager;
|
||||
|
|
|
@ -30,8 +30,8 @@ public class AquaticPlayerPonyRenderer extends PlayerPonyRenderer {
|
|||
|
||||
@Override
|
||||
public void render(AbstractClientPlayerEntity player, float entityYaw, float tickDelta, MatrixStack stack, VertexConsumerProvider renderContext, int light) {
|
||||
updateSeaponyState(player);
|
||||
super.render(player, entityYaw, tickDelta, stack, renderContext, light);
|
||||
updateSeaponyState(player);
|
||||
|
||||
if (!(player instanceof PreviewModel) && wet && player.getVelocity().length() > 0.1F) {
|
||||
double x = player.getEntityWorld().getRandom().nextTriangular(player.getX(), 1);
|
||||
|
@ -44,32 +44,30 @@ public class AquaticPlayerPonyRenderer extends PlayerPonyRenderer {
|
|||
|
||||
protected Race getPlayerRace(AbstractClientPlayerEntity entity, Pony pony) {
|
||||
Race race = super.getPlayerRace(entity, pony);
|
||||
return wet ? Race.SEAPONY : race == Race.SEAPONY ? Race.UNICORN : race;
|
||||
return PonyPosture.isSeaponyModifier(entity) ? Race.SEAPONY : race == Race.SEAPONY ? Race.UNICORN : race;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setupTransforms(AbstractClientPlayerEntity entity, MatrixStack stack, float ageInTicks, float rotationYaw, float partialTicks) {
|
||||
if (wet) {
|
||||
protected void setupTransforms(AbstractClientPlayerEntity player, MatrixStack stack, float ageInTicks, float rotationYaw, float partialTicks) {
|
||||
if (PonyPosture.isSeaponyModifier(player)) {
|
||||
stack.translate(0, 0.6, 0);
|
||||
if (entity.isInSneakingPose()) {
|
||||
if (player.isInSneakingPose()) {
|
||||
stack.translate(0, 0.125, 0);
|
||||
}
|
||||
}
|
||||
super.setupTransforms(entity, stack, ageInTicks, rotationYaw, partialTicks);
|
||||
super.setupTransforms(player, stack, ageInTicks, rotationYaw, partialTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderArm(MatrixStack stack, VertexConsumerProvider renderContext, int lightUv, AbstractClientPlayerEntity player, Arm side) {
|
||||
updateSeaponyState(player);
|
||||
super.renderArm(stack, renderContext, lightUv, player, side);
|
||||
updateSeaponyState(player);
|
||||
}
|
||||
|
||||
private void updateSeaponyState(AbstractClientPlayerEntity player) {
|
||||
wet = PonyPosture.isSeaponyModifier(player);
|
||||
|
||||
if (!(player instanceof PreviewModel)) {
|
||||
float state = wet ? 100 : 0;
|
||||
float interpolated = getInternalRenderer().getModel().getAttributes().getMainInterpolator().interpolate("seapony_state", state, 5);
|
||||
float state = PonyPosture.isSeaponyModifier(player) ? 100 : 0;
|
||||
float interpolated = getInternalRenderer().getModels().body().getAttributes().getMainInterpolator().interpolate("seapony_state", state, 5);
|
||||
|
||||
if (!MathUtil.compareFloats(interpolated, state)) {
|
||||
double x = player.getEntityWorld().getRandom().nextTriangular(player.getX(), 1);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package com.minelittlepony.client.render.entity;
|
||||
|
||||
import com.minelittlepony.api.model.ModelAttributes;
|
||||
import com.minelittlepony.api.model.ModelWrapper;
|
||||
import com.minelittlepony.api.model.Models;
|
||||
import com.minelittlepony.api.pony.Pony;
|
||||
import com.minelittlepony.api.pony.SkinsProxy;
|
||||
import com.minelittlepony.api.pony.meta.Race;
|
||||
|
@ -30,21 +30,20 @@ import net.minecraft.util.*;
|
|||
import net.minecraft.util.math.*;
|
||||
|
||||
public class PlayerPonyRenderer extends PlayerEntityRenderer implements PonyRenderContext<AbstractClientPlayerEntity, ClientPonyModel<AbstractClientPlayerEntity>> {
|
||||
|
||||
protected final EquineRenderManager<AbstractClientPlayerEntity, ClientPonyModel<AbstractClientPlayerEntity>> manager = new EquineRenderManager<>(this);
|
||||
|
||||
private final Function<Race, ModelWrapper<AbstractClientPlayerEntity, ClientPonyModel<AbstractClientPlayerEntity>>> modelsCache;
|
||||
private final Function<Race, Models<AbstractClientPlayerEntity, ClientPonyModel<AbstractClientPlayerEntity>>> modelsCache;
|
||||
protected final EquineRenderManager<AbstractClientPlayerEntity, ClientPonyModel<AbstractClientPlayerEntity>> manager;
|
||||
|
||||
public PlayerPonyRenderer(EntityRendererFactory.Context context, boolean slim) {
|
||||
super(context, slim);
|
||||
modelsCache = Util.memoize(race -> ModelType.getPlayerModel(race).create(slim));
|
||||
manager = new EquineRenderManager<>(this, super::setupTransforms, modelsCache.apply(Race.EARTH));
|
||||
manager.setModelsLookup(entity -> modelsCache.apply(getPlayerRace(entity, getEntityPony(entity))));
|
||||
addLayers(context);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
protected void addLayers(EntityRendererFactory.Context context) {
|
||||
// remove vanilla features (keep modded ones)
|
||||
// TODO: test with https://github.com/Globox1997/BackSlot
|
||||
features.removeIf(feature -> {
|
||||
return feature instanceof ArmorFeatureRenderer
|
||||
|| feature instanceof PlayerHeldItemFeatureRenderer
|
||||
|
@ -71,19 +70,18 @@ public class PlayerPonyRenderer extends PlayerEntityRenderer implements PonyRend
|
|||
|
||||
@Override
|
||||
protected void scale(AbstractClientPlayerEntity entity, MatrixStack stack, float tickDelta) {
|
||||
if (manager.getModel().getAttributes().isSitting && entity.hasVehicle()) {
|
||||
if (manager.getModels().body().getAttributes().isSitting && entity.hasVehicle()) {
|
||||
stack.translate(0, entity.getRidingOffset(entity.getVehicle()), 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(AbstractClientPlayerEntity entity, float entityYaw, float tickDelta, MatrixStack stack, VertexConsumerProvider renderContext, int lightUv) {
|
||||
Pony pony = getEntityPony(entity);
|
||||
model = manager.setModel(modelsCache.apply(getPlayerRace(entity, pony))).body();
|
||||
// EntityModelFeatures: We have to force it to use our models otherwise EMF overrides it and breaks pony rendering
|
||||
manager.preRender(entity, ModelAttributes.Mode.THIRD_PERSON);
|
||||
shadowRadius = manager.getShadowSize();
|
||||
super.render(entity, entityYaw, tickDelta, stack, renderContext, lightUv);
|
||||
DebugBoundingBoxRenderer.render(pony, this, entity, stack, renderContext, tickDelta);
|
||||
DebugBoundingBoxRenderer.render(getEntityPony(entity), this, entity, stack, renderContext, tickDelta);
|
||||
|
||||
// Translate the shadow position after everything is done
|
||||
// (shadows are drawn after us)
|
||||
|
@ -103,10 +101,7 @@ public class PlayerPonyRenderer extends PlayerEntityRenderer implements PonyRend
|
|||
|
||||
@Override
|
||||
protected void setupTransforms(AbstractClientPlayerEntity entity, MatrixStack stack, float ageInTicks, float rotationYaw, float partialTicks) {
|
||||
manager.preRenderCallback(entity, stack, partialTicks);
|
||||
rotationYaw = manager.getRenderYaw(entity, rotationYaw, partialTicks);
|
||||
super.setupTransforms(entity, stack, ageInTicks, rotationYaw, partialTicks);
|
||||
manager.setupTransforms(entity, stack, rotationYaw, partialTicks);
|
||||
manager.setupTransforms(entity, stack, ageInTicks, rotationYaw, partialTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -145,9 +140,7 @@ public class PlayerPonyRenderer extends PlayerEntityRenderer implements PonyRend
|
|||
}
|
||||
|
||||
protected void renderArm(MatrixStack stack, VertexConsumerProvider renderContext, int lightUv, AbstractClientPlayerEntity player, Arm side) {
|
||||
Pony pony = getEntityPony(player);
|
||||
model = manager.setModel(modelsCache.apply(getPlayerRace(player, pony))).body();
|
||||
manager.updateModel(player, ModelAttributes.Mode.FIRST_PERSON);
|
||||
manager.preRender(player, ModelAttributes.Mode.FIRST_PERSON);
|
||||
|
||||
stack.push();
|
||||
float reflect = side == Arm.LEFT ? 1 : -1;
|
||||
|
@ -179,6 +172,11 @@ public class PlayerPonyRenderer extends PlayerEntityRenderer implements PonyRend
|
|||
return getEntityPony(player).texture();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setModel(ClientPonyModel<AbstractClientPlayerEntity> model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EquineRenderManager<AbstractClientPlayerEntity, ClientPonyModel<AbstractClientPlayerEntity>> getInternalRenderer() {
|
||||
return manager;
|
||||
|
@ -192,7 +190,7 @@ public class PlayerPonyRenderer extends PlayerEntityRenderer implements PonyRend
|
|||
@Override
|
||||
public Identifier getDefaultTexture(AbstractClientPlayerEntity entity, Wearable wearable) {
|
||||
return SkinsProxy.instance.getSkin(wearable.getId(), entity).orElseGet(() -> {
|
||||
if (wearable.isSaddlebags() && getInternalRenderer().getModel().getRace().supportsLegacySaddlebags()) {
|
||||
if (wearable.isSaddlebags() && getInternalRenderer().getModels().body().getRace().supportsLegacySaddlebags()) {
|
||||
return getTexture(entity);
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ import net.minecraft.entity.EquipmentSlot;
|
|||
import net.minecraft.entity.decoration.ArmorStandEntity;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
import com.minelittlepony.api.model.ModelWrapper;
|
||||
import com.minelittlepony.api.model.Models;
|
||||
import com.minelittlepony.api.pony.PonyData;
|
||||
import com.minelittlepony.api.pony.meta.Race;
|
||||
import com.minelittlepony.client.model.ModelType;
|
||||
|
@ -60,7 +60,7 @@ public class PonyStandRenderer extends ArmorStandEntityRenderer {
|
|||
}
|
||||
|
||||
class Armour extends ArmorFeatureRenderer<ArmorStandEntity, ArmorStandArmorEntityModel, ArmorStandArmorEntityModel> {
|
||||
private final ModelWrapper<ArmorStandEntity, EarthPonyModel<ArmorStandEntity>> pony = ModelType.EARTH_PONY.<ArmorStandEntity, EarthPonyModel<ArmorStandEntity>>create(false);
|
||||
private final Models<ArmorStandEntity, EarthPonyModel<ArmorStandEntity>> pony = ModelType.EARTH_PONY.<ArmorStandEntity, EarthPonyModel<ArmorStandEntity>>create(false);
|
||||
|
||||
public Armour(FeatureRendererContext<ArmorStandEntity, ArmorStandArmorEntityModel> renderer, EntityRendererFactory.Context context) {
|
||||
super(renderer,
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.minelittlepony.client.render.entity;
|
|||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import com.minelittlepony.api.model.ModelAttributes;
|
||||
import com.minelittlepony.client.mixin.IResizeable;
|
||||
import com.minelittlepony.client.model.ModelType;
|
||||
import com.minelittlepony.client.model.entity.GuardianPonyModel;
|
||||
|
@ -52,7 +53,7 @@ public class SeaponyRenderer extends GuardianEntityRenderer {
|
|||
|
||||
@Override
|
||||
public void render(GuardianEntity entity, float entityYaw, float tickDelta, MatrixStack stack, VertexConsumerProvider renderContext, int lightUv) {
|
||||
ponyRenderer.manager.preRenderCallback(entity, stack, tickDelta);
|
||||
ponyRenderer.manager.preRender(entity, ModelAttributes.Mode.THIRD_PERSON);
|
||||
|
||||
float height = entity.getStandingEyeHeight();
|
||||
|
||||
|
@ -61,4 +62,9 @@ public class SeaponyRenderer extends GuardianEntityRenderer {
|
|||
super.render(entity, entityYaw, tickDelta, stack, renderContext, lightUv);
|
||||
((IResizeable)entity).setStandingEyeHeight(height);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setupTransforms(GuardianEntity entity, MatrixStack stack, float ageInTicks, float rotationYaw, float partialTicks) {
|
||||
ponyRenderer.manager.setupTransforms(entity, stack, ageInTicks, rotationYaw, partialTicks);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package com.minelittlepony.client.render.entity.feature;
|
||||
|
||||
import com.minelittlepony.api.model.ModelWrapper;
|
||||
import com.minelittlepony.api.model.Models;
|
||||
import com.minelittlepony.api.model.PonyModel;
|
||||
import com.minelittlepony.client.render.PonyRenderContext;
|
||||
|
||||
|
@ -45,10 +45,10 @@ public abstract class AbstractPonyFeature<T extends LivingEntity, M extends Enti
|
|||
|
||||
@Override
|
||||
public final M getContextModel() {
|
||||
return context.getInternalRenderer().getModel();
|
||||
return context.getInternalRenderer().getModels().body();
|
||||
}
|
||||
|
||||
protected ModelWrapper<T, M> getModelWrapper() {
|
||||
return context.getInternalRenderer().getModelWrapper();
|
||||
protected Models<T, M> getModelWrapper() {
|
||||
return context.getInternalRenderer().getModels();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package com.minelittlepony.client.render.entity.feature;
|
||||
|
||||
import com.minelittlepony.api.model.ModelWrapper;
|
||||
import com.minelittlepony.api.model.Models;
|
||||
import com.minelittlepony.api.model.PonyModel;
|
||||
import com.minelittlepony.client.model.armour.*;
|
||||
import com.minelittlepony.client.render.ArmorRenderLayers;
|
||||
|
@ -29,7 +29,7 @@ public class ArmourFeature<T extends LivingEntity, M extends EntityModel<T> & Po
|
|||
|
||||
@Override
|
||||
public void render(MatrixStack stack, VertexConsumerProvider renderContext, int lightUv, T entity, float limbDistance, float limbAngle, float tickDelta, float age, float headYaw, float headPitch) {
|
||||
ModelWrapper<T, M> pony = getModelWrapper();
|
||||
Models<T, M> pony = getModelWrapper();
|
||||
|
||||
for (EquipmentSlot i : EquipmentSlot.values()) {
|
||||
if (i.getType() == EquipmentSlot.Type.ARMOR) {
|
||||
|
@ -40,7 +40,7 @@ public class ArmourFeature<T extends LivingEntity, M extends EntityModel<T> & Po
|
|||
}
|
||||
|
||||
public static <T extends LivingEntity, V extends PonyArmourModel<T>> void renderArmor(
|
||||
ModelWrapper<T, ? extends PonyModel<T>> pony, MatrixStack matrices,
|
||||
Models<T, ? extends PonyModel<T>> pony, MatrixStack matrices,
|
||||
VertexConsumerProvider renderContext, int light, T entity,
|
||||
float limbDistance, float limbAngle,
|
||||
float age, float headYaw, float headPitch,
|
||||
|
|
|
@ -44,7 +44,7 @@ public class HeldItemFeature<T extends LivingEntity, M extends EntityModel<T> &
|
|||
ItemStack right = getRightItem(entity);
|
||||
|
||||
if (!left.isEmpty() || !right.isEmpty()) {
|
||||
M model = context.getInternalRenderer().getModel();
|
||||
M model = context.getInternalRenderer().getModels().body();
|
||||
|
||||
stack.push();
|
||||
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
package com.minelittlepony.client.render.entity.npc;
|
||||
|
||||
import net.minecraft.client.render.VertexConsumerProvider;
|
||||
import net.minecraft.client.render.entity.EntityRendererFactory;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.entity.mob.MobEntity;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.Util;
|
||||
import net.minecraft.village.VillagerDataContainer;
|
||||
import net.minecraft.village.VillagerProfession;
|
||||
|
||||
import com.minelittlepony.api.model.ModelWrapper;
|
||||
import com.minelittlepony.api.model.Models;
|
||||
import com.minelittlepony.api.model.gear.Gear;
|
||||
import com.minelittlepony.api.pony.meta.Race;
|
||||
import com.minelittlepony.api.pony.meta.Wearable;
|
||||
|
@ -17,15 +16,21 @@ import com.minelittlepony.client.render.entity.PonyRenderer;
|
|||
import com.minelittlepony.client.render.entity.feature.*;
|
||||
import com.minelittlepony.client.render.entity.npc.textures.*;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
|
||||
abstract class AbstractNpcRenderer<T extends MobEntity & VillagerDataContainer> extends PonyRenderer<T, ClientPonyModel<T>> {
|
||||
private final Map<Race, ModelWrapper<T, ClientPonyModel<T>>> models = new EnumMap<>(Race.class);
|
||||
private final NpcClothingFeature<T, ClientPonyModel<T>, AbstractNpcRenderer<T>> clothing;
|
||||
private final Function<Race, Models<T, ClientPonyModel<T>>> models = Util.memoize(race -> {
|
||||
if (race.isHuman()) {
|
||||
race = Race.EARTH;
|
||||
}
|
||||
return ModelType.getPlayerModel(race).create(false, this::initializeModel);
|
||||
});
|
||||
|
||||
public AbstractNpcRenderer(EntityRendererFactory.Context context, String type, TextureSupplier<T> textureSupplier, TextureSupplier<String> formatter) {
|
||||
super(context, ModelType.getPlayerModel(Race.EARTH).getKey(false), SillyPonyTextureSupplier.create(textureSupplier, formatter));
|
||||
clothing = new NpcClothingFeature<>(this, type);
|
||||
this.manager.setModelsLookup(entity -> models.apply(getEntityPony(entity).race()));
|
||||
addFeature(clothing);
|
||||
}
|
||||
|
||||
|
@ -54,20 +59,6 @@ abstract class AbstractNpcRenderer<T extends MobEntity & VillagerDataContainer>
|
|||
return super.shouldRender(model, entity, wearable, gear);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(T entity, float entityYaw, float tickDelta, MatrixStack stack, VertexConsumerProvider renderContext, int lightUv) {
|
||||
model = manager.setModel(models.computeIfAbsent(getEntityPony(entity).race(), this::createModel)).body();
|
||||
|
||||
super.render(entity, entityYaw, tickDelta, stack, renderContext, lightUv);
|
||||
}
|
||||
|
||||
private ModelWrapper<T, ClientPonyModel<T>> createModel(Race race) {
|
||||
if (race.isHuman()) {
|
||||
race = Race.EARTH;
|
||||
}
|
||||
return ModelType.getPlayerModel(race).create(false, this::initializeModel);
|
||||
}
|
||||
|
||||
protected void initializeModel(ClientPonyModel<T> model) {
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue