mirror of
https://github.com/MineLittlePony/MineLittlePony.git
synced 2025-03-28 14:27:44 +01:00
163 lines
5.7 KiB
Java
163 lines
5.7 KiB
Java
package com.minelittlepony.client.render;
|
|
|
|
import com.minelittlepony.api.config.PonyConfig;
|
|
import com.minelittlepony.api.events.ClientChannel;
|
|
import com.minelittlepony.api.events.PonyDataCallback;
|
|
import com.minelittlepony.api.model.*;
|
|
import com.minelittlepony.api.pony.Pony;
|
|
import com.minelittlepony.api.pony.PonyData;
|
|
import com.minelittlepony.client.PonyDataLoader;
|
|
import com.minelittlepony.client.render.entity.state.PonyRenderState;
|
|
import com.minelittlepony.client.transform.PonyPosture;
|
|
import com.minelittlepony.mson.api.ModelKey;
|
|
import com.minelittlepony.util.MathUtil;
|
|
import com.mojang.blaze3d.systems.RenderSystem;
|
|
|
|
import java.util.*;
|
|
import java.util.function.Function;
|
|
import java.util.function.Supplier;
|
|
|
|
import net.fabricmc.api.EnvType;
|
|
import net.minecraft.client.MinecraftClient;
|
|
import net.minecraft.client.render.Frustum;
|
|
import net.minecraft.client.render.entity.model.EntityModel;
|
|
import net.minecraft.client.render.entity.state.BipedEntityRenderState;
|
|
import net.minecraft.client.render.entity.state.PlayerEntityRenderState;
|
|
import net.minecraft.client.util.math.MatrixStack;
|
|
import net.minecraft.entity.EntityPose;
|
|
import net.minecraft.entity.LivingEntity;
|
|
import net.minecraft.entity.player.PlayerEntity;
|
|
|
|
import org.jetbrains.annotations.Nullable;
|
|
|
|
public class EquineRenderManager<
|
|
T extends LivingEntity,
|
|
S extends PonyRenderState,
|
|
M extends EntityModel<? super S> & PonyModel<S>> {
|
|
|
|
private Models<T, M> models;
|
|
@Nullable
|
|
private Function<S, Models<T, M>> modelsLookup;
|
|
|
|
private final PonyRenderContext<T, S, M> context;
|
|
private final Transformer<? super S> transformer;
|
|
|
|
private final FrustrumCheck<T> frustrum;
|
|
|
|
public static void disableModelRenderProfile() {
|
|
RenderSystem.disableBlend();
|
|
}
|
|
|
|
public EquineRenderManager(PonyRenderContext<T, S, M> context, Transformer<? super S> 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 EquineRenderManager(PonyRenderContext<T, S, M> context, Transformer<? super S> transformer, ModelKey<? super M> key) {
|
|
this(context, transformer, new Models(key));
|
|
}
|
|
|
|
public void setModelsLookup(@Nullable Function<S, Models<T, M>> modelsLookup) {
|
|
this.modelsLookup = modelsLookup;
|
|
}
|
|
|
|
public Models<T, M> getModels() {
|
|
return models;
|
|
}
|
|
|
|
public Frustum getFrustrum(T entity, Frustum vanilla) {
|
|
if (RenderPass.getCurrent() == RenderPass.HUD) {
|
|
return FrustrumCheck.ALWAYS_VISIBLE;
|
|
}
|
|
|
|
if (entity.isSleeping() || !PonyConfig.getInstance().frustrum.get()) {
|
|
return vanilla;
|
|
}
|
|
return frustrum.withCamera(entity, vanilla);
|
|
}
|
|
|
|
public void preRender(T entity, S state, ModelAttributes.Mode mode) {
|
|
Pony pony = context.getEntityPony(entity);
|
|
if (modelsLookup != null) {
|
|
models = modelsLookup.apply(state);
|
|
context.setModel(models.body());
|
|
}
|
|
models.applyMetadata(pony.metadata());
|
|
state.updateState(entity, models.body(), pony, mode);
|
|
}
|
|
|
|
public void setupTransforms(S state, MatrixStack stack, float animationProgress, float bodyYaw) {
|
|
float s = state.getScaleFactor();
|
|
stack.scale(s, s, s);
|
|
|
|
if (state instanceof PlayerEntityRenderState) {
|
|
if (state.attributes.isSitting) {
|
|
stack.translate(0, 0.125D, 0);
|
|
}
|
|
}
|
|
|
|
transformer.setupTransforms(state, stack, animationProgress, bodyYaw);
|
|
|
|
PonyPosture.of(state.attributes).apply(state, getModels().body(), stack, bodyYaw, state.age, 1);
|
|
}
|
|
|
|
public interface Transformer<S extends BipedEntityRenderState> {
|
|
void setupTransforms(S state, MatrixStack stack, float animationProgress, float bodyYaw);
|
|
}
|
|
|
|
public interface RegistrationHandler {
|
|
SyncedPony getSyncedPony();
|
|
}
|
|
|
|
public interface ModelHolder<S extends BipedEntityRenderState, M extends EntityModel<S> & PonyModel<S>> {
|
|
void setModel(M model);
|
|
}
|
|
|
|
public static class SyncedPony {
|
|
@Nullable
|
|
private Pony lastRenderedPony;
|
|
private Supplier<Optional<PonyData>> lastPonyData = PonyDataLoader.NULL;
|
|
@Nullable
|
|
private Pony lastTransmittedPony;
|
|
|
|
public Pony getCachedPony() {
|
|
return lastRenderedPony;
|
|
}
|
|
|
|
public PonyData getCachedPonyData() {
|
|
return lastPonyData.get().orElse(PonyData.NULL);
|
|
}
|
|
|
|
public void synchronize(PlayerEntity player) {
|
|
Pony pony = Pony.getManager().getPony(player);
|
|
boolean changed = pony.compareTo(lastRenderedPony) != 0;
|
|
|
|
if (changed) {
|
|
lastRenderedPony = pony;
|
|
lastPonyData = pony.metadataGetter();
|
|
player.calculateDimensions();
|
|
}
|
|
|
|
if (!(player instanceof PreviewModel)) {
|
|
@Nullable
|
|
PlayerEntity clientPlayer = MinecraftClient.getInstance().player;
|
|
|
|
if (ClientChannel.isRegistered() && pony.compareTo(lastTransmittedPony) != 0) {
|
|
if (clientPlayer != null && (Objects.equals(player, clientPlayer) || Objects.equals(player.getGameProfile(), clientPlayer.getGameProfile()))) {
|
|
if (ClientChannel.broadcastPonyData(pony.metadata())) {
|
|
lastTransmittedPony = pony;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (changed) {
|
|
PonyDataCallback.EVENT.invoker().onPonyDataAvailable(player, pony.metadata(), EnvType.CLIENT);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|