Split up the WorldRenderDelegate class a little

This commit is contained in:
Sollace 2023-10-10 19:06:29 +01:00
parent 2b2d792768
commit 8e19ab6a96
No known key found for this signature in database
GPG key ID: E52FACE7B5C773DB
5 changed files with 168 additions and 137 deletions

View file

@ -0,0 +1,129 @@
package com.minelittlepony.unicopia.client.render;
import org.jetbrains.annotations.Nullable;
import com.minelittlepony.unicopia.compat.pehkui.PehkUtil;
import com.minelittlepony.unicopia.entity.Living;
import com.minelittlepony.unicopia.entity.behaviour.Disguise;
import com.minelittlepony.unicopia.entity.behaviour.EntityAppearance;
import com.minelittlepony.unicopia.entity.behaviour.FallingBlockBehaviour;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.OverlayTexture;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.block.entity.BlockEntityRenderer;
import net.minecraft.client.render.entity.LivingEntityRenderer;
import net.minecraft.client.render.entity.model.BipedEntityModel;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.Entity;
import net.minecraft.state.property.Properties;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.RotationAxis;
import net.minecraft.util.math.Vec3d;
class EntityDisguiseRenderer {
private final WorldRenderDelegate delegate;
public EntityDisguiseRenderer(WorldRenderDelegate delegate) {
this.delegate = delegate;
}
public boolean render(Living<?> pony, Disguise disguise,
double x, double y, double z,
float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light) {
int fireTicks = pony.asEntity().doesRenderOnFire() ? 1 : 0;
disguise.update(pony, false);
EntityAppearance ve = disguise.getDisguise();
Entity e = ve.getAppearance();
if (e == null) {
return false;
}
PehkUtil.copyScale(pony.asEntity(), e);
if (delegate.client.getEntityRenderDispatcher().shouldRenderHitboxes()) {
e.setBoundingBox(pony.asEntity().getBoundingBox());
}
render(ve, e, x, y, z, fireTicks, tickDelta, matrices, vertexConsumers, light);
ve.getAttachments().forEach(ee -> {
PehkUtil.copyScale(pony.asEntity(), ee);
Vec3d difference = ee.getPos().subtract(e.getPos());
render(ve, ee, x + difference.x, y + difference.y, z + difference.z, fireTicks, tickDelta, matrices, vertexConsumers, light);
PehkUtil.clearScale(ee);
});
delegate.afterEntityRender(pony, matrices, light);
PehkUtil.clearScale(e);
return true;
}
private void render(EntityAppearance ve, Entity e,
double x, double y, double z,
int fireTicks, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light) {
if (ve.isAxisAligned() && (x != 0 || y != 0 || z != 0)) {
Vec3d cam = MinecraftClient.getInstance().gameRenderer.getCamera().getPos();
x = MathHelper.lerp(tickDelta, e.lastRenderX, e.getX()) - cam.x;
y = MathHelper.lerp(tickDelta, e.lastRenderY, e.getY()) - cam.y;
z = MathHelper.lerp(tickDelta, e.lastRenderZ, e.getZ()) - cam.z;
}
BlockEntity blockEntity = ve.getBlockEntity();
if (blockEntity != null) {
BlockEntityRenderer<BlockEntity> r = MinecraftClient.getInstance().getBlockEntityRenderDispatcher().get(blockEntity);
if (r != null) {
((FallingBlockBehaviour.Positioned)blockEntity).setPos(e.getBlockPos());
blockEntity.setWorld(e.getWorld());
matrices.push();
BlockState state = blockEntity.getCachedState();
Direction direction = state.contains(Properties.HORIZONTAL_FACING) ? state.get(Properties.HORIZONTAL_FACING) : Direction.UP;
matrices.translate(x, y, z);
matrices.multiply(direction.getRotationQuaternion());
matrices.multiply(RotationAxis.NEGATIVE_X.rotationDegrees(90));
matrices.translate(-0.5, 0, -0.5);
r.render(blockEntity, 1, matrices, vertexConsumers, light, OverlayTexture.DEFAULT_UV);
matrices.pop();
blockEntity.setWorld(null);
return;
}
}
BipedEntityModel<?> model = getBipedModel(e);
if (model != null) {
model.sneaking = e.isSneaking();
}
e.setFireTicks(fireTicks);
delegate.client.getEntityRenderDispatcher().render(e, x, y, z, e.getYaw(), tickDelta, matrices, vertexConsumers, light);
e.setFireTicks(0);
if (model != null) {
model.sneaking = false;
}
}
@Nullable
private BipedEntityModel<?> getBipedModel(Entity entity) {
if (delegate.client.getEntityRenderDispatcher().getRenderer(entity) instanceof LivingEntityRenderer livingRenderer
&& livingRenderer.getModel() instanceof BipedEntityModel<?> biped) {
return biped;
}
return null;
}
}

View file

@ -18,9 +18,7 @@ import net.minecraft.entity.EntityType;
import net.minecraft.entity.passive.PassiveEntity;
import net.minecraft.entity.player.PlayerEntity;
class EntityReplacementRenderManager implements Disguise {
public static final EntityReplacementRenderManager INSTANCE = new EntityReplacementRenderManager();
class EntityReplacementManager implements Disguise {
@Nullable
private EntityType<?> currentType;
private final EntityAppearance disguise = new EntityAppearance();

View file

@ -23,8 +23,6 @@ import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.RotationAxis;
public class SmittenEyesRenderer {
public static final SmittenEyesRenderer INSTANCE = new SmittenEyesRenderer();
private static final Identifier TEXTURE = Unicopia.id("textures/entity/smitten_eyes.png");
private final MinecraftClient client = MinecraftClient.getInstance();

View file

@ -1,44 +1,41 @@
package com.minelittlepony.unicopia.client.render;
import org.jetbrains.annotations.Nullable;
import java.util.Optional;
import com.minelittlepony.client.util.render.RenderLayerUtil;
import com.minelittlepony.unicopia.EquinePredicates;
import com.minelittlepony.unicopia.Unicopia;
import com.minelittlepony.unicopia.compat.pehkui.PehkUtil;
import com.minelittlepony.unicopia.entity.Creature;
import com.minelittlepony.unicopia.entity.Equine;
import com.minelittlepony.unicopia.entity.ItemImpl;
import com.minelittlepony.unicopia.entity.Living;
import com.minelittlepony.unicopia.entity.behaviour.EntityAppearance;
import com.minelittlepony.unicopia.entity.behaviour.FallingBlockBehaviour;
import com.minelittlepony.unicopia.entity.duck.LavaAffine;
import com.minelittlepony.unicopia.entity.player.Pony;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.*;
import net.minecraft.client.render.VertexConsumerProvider.Immediate;
import net.minecraft.client.render.block.entity.BlockEntityRenderer;
import net.minecraft.client.render.entity.EntityRenderDispatcher;
import net.minecraft.client.render.entity.LivingEntityRenderer;
import net.minecraft.client.render.entity.model.BipedEntityModel;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.*;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.vehicle.BoatEntity;
import net.minecraft.screen.PlayerScreenHandler;
import net.minecraft.state.property.Properties;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.*;
public class WorldRenderDelegate {
public static final WorldRenderDelegate INSTANCE = new WorldRenderDelegate();
private final EntityReplacementManager disguiseLookup = new EntityReplacementManager();
private final EntityDisguiseRenderer disguiseRenderer = new EntityDisguiseRenderer(this);
private final SmittenEyesRenderer smittenEyesRenderer = new SmittenEyesRenderer();
private boolean recurseMinion;
private boolean recurseFrosting;
public boolean beforeEntityRender(EntityRenderDispatcher dispatcher, Entity entity,
final MinecraftClient client = MinecraftClient.getInstance();
public boolean beforeEntityRender(Entity entity,
double x, double y, double z, float yaw,
float tickDelta, MatrixStack matrices, VertexConsumerProvider vertices, int light) {
@ -47,7 +44,7 @@ public class WorldRenderDelegate {
if (MinecraftClient.getInstance().getResourceManager().getResource(frostingTexture).isPresent()) {
recurseFrosting = true;
dispatcher.render(entity, x, y, z, yaw, tickDelta, matrices, layer -> {
client.getEntityRenderDispatcher().render(entity, x, y, z, yaw, tickDelta, matrices, layer -> {
if (RenderLayerUtil.getTexture(layer).orElse(null) == null) {
return vertices.getBuffer(layer);
}
@ -62,17 +59,36 @@ public class WorldRenderDelegate {
return false;
}
return Equine.of(entity).filter(eq -> onEntityRender(dispatcher, eq, x, y, z, yaw, tickDelta, matrices, vertices, light)).isPresent();
return Equine.of(entity).filter(eq -> onEntityRender(eq, x, y, z, yaw, tickDelta, matrices, vertices, light)).isPresent();
}
public boolean onEntityRender(EntityRenderDispatcher dispatcher, Equine<?> pony,
public void afterEntityRender(Equine<?> pony, MatrixStack matrices, int light) {
if (recurseFrosting) {
return;
}
if (pony instanceof Creature creature && smittenEyesRenderer.isSmitten(creature)) {
Immediate immediate = MinecraftClient.getInstance().getBufferBuilders().getEntityVertexConsumers();
smittenEyesRenderer.render(creature, matrices, immediate, light, 0);
}
if (pony instanceof ItemImpl || pony instanceof Living) {
matrices.pop();
if (pony instanceof Living && pony.getPhysics().isGravityNegative()) {
flipAngles(pony.asEntity());
}
}
}
private boolean onEntityRender(Equine<?> pony,
double x, double y, double z, float yaw,
float tickDelta, MatrixStack matrices, VertexConsumerProvider vertices, int light) {
if (!recurseMinion && pony instanceof Creature creature && creature.isMinion()) {
try {
recurseMinion = true;
dispatcher.render(creature.asEntity(), x, y, z, yaw, tickDelta, matrices, layer -> {
client.getEntityRenderDispatcher().render(creature.asEntity(), x, y, z, yaw, tickDelta, matrices, layer -> {
return RenderLayerUtil.getTexture(layer)
.filter(texture -> texture != PlayerScreenHandler.BLOCK_ATLAS_TEXTURE)
.map(texture -> {
@ -100,14 +116,14 @@ public class WorldRenderDelegate {
return false;
}
if (pony instanceof Living) {
return onLivingRender(dispatcher, (Living<?>)pony, x, y, z, yaw, tickDelta, matrices, vertices, light);
if (pony instanceof Living living) {
return onLivingRender(living, x, y, z, yaw, tickDelta, matrices, vertices, light);
}
return false;
}
private boolean onLivingRender(EntityRenderDispatcher dispatcher, Living<?> pony,
private boolean onLivingRender(Living<?> pony,
double x, double y, double z, float yaw,
float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light) {
@ -145,7 +161,7 @@ public class WorldRenderDelegate {
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(diveAngle));
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(yaw));
} else if (pony instanceof Creature creature && SmittenEyesRenderer.INSTANCE.isSmitten(creature)) {
} else if (pony instanceof Creature creature && smittenEyesRenderer.isSmitten(creature)) {
ModelPartHooks.startCollecting();
}
@ -155,117 +171,7 @@ public class WorldRenderDelegate {
flipAngles(owner);
}
int fireTicks = owner.doesRenderOnFire() ? 1 : 0;
return EntityReplacementRenderManager.INSTANCE.getAppearanceFor(pony).map(effect -> {
effect.update(pony, false);
EntityAppearance ve = effect.getDisguise();
Entity e = ve.getAppearance();
if (e != null) {
PehkUtil.copyScale(pony.asEntity(), e);
if (dispatcher.shouldRenderHitboxes()) {
e.setBoundingBox(pony.asEntity().getBoundingBox());
}
renderDisguise(dispatcher, ve, e, x, y, z, fireTicks, tickDelta, matrices, vertexConsumers, light);
ve.getAttachments().forEach(ee -> {
PehkUtil.copyScale(pony.asEntity(), ee);
Vec3d difference = ee.getPos().subtract(e.getPos());
renderDisguise(dispatcher, ve, ee, x + difference.x, y + difference.y, z + difference.z, fireTicks, tickDelta, matrices, vertexConsumers, light);
PehkUtil.clearScale(ee);
});
afterEntityRender(pony, matrices, light);
PehkUtil.clearScale(e);
return true;
}
return false;
}).orElse(false);
}
public void afterEntityRender(Equine<?> pony, MatrixStack matrices, int light) {
if (recurseFrosting) {
return;
}
if (pony instanceof Creature creature && SmittenEyesRenderer.INSTANCE.isSmitten(creature)) {
Immediate immediate = MinecraftClient.getInstance().getBufferBuilders().getEntityVertexConsumers();
SmittenEyesRenderer.INSTANCE.render(creature, matrices, immediate, light, 0);
}
if (pony instanceof ItemImpl || pony instanceof Living) {
matrices.pop();
if (pony instanceof Living && pony.getPhysics().isGravityNegative()) {
flipAngles(pony.asEntity());
}
}
}
public void renderDisguise(EntityRenderDispatcher dispatcher, EntityAppearance ve, Entity e,
double x, double y, double z,
int fireTicks, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light) {
if (ve.isAxisAligned() && (x != 0 || y != 0 || z != 0)) {
Vec3d cam = MinecraftClient.getInstance().gameRenderer.getCamera().getPos();
x = MathHelper.lerp(tickDelta, e.lastRenderX, e.getX()) - cam.x;
y = MathHelper.lerp(tickDelta, e.lastRenderY, e.getY()) - cam.y;
z = MathHelper.lerp(tickDelta, e.lastRenderZ, e.getZ()) - cam.z;
}
BlockEntity blockEntity = ve.getBlockEntity();
if (blockEntity != null) {
BlockEntityRenderer<BlockEntity> r = MinecraftClient.getInstance().getBlockEntityRenderDispatcher().get(blockEntity);
if (r != null) {
((FallingBlockBehaviour.Positioned)blockEntity).setPos(e.getBlockPos());
blockEntity.setWorld(e.getWorld());
matrices.push();
BlockState state = blockEntity.getCachedState();
Direction direction = state.contains(Properties.HORIZONTAL_FACING) ? state.get(Properties.HORIZONTAL_FACING) : Direction.UP;
matrices.translate(x, y, z);
matrices.multiply(direction.getRotationQuaternion());
matrices.multiply(RotationAxis.NEGATIVE_X.rotationDegrees(90));
matrices.translate(-0.5, 0, -0.5);
r.render(blockEntity, 1, matrices, vertexConsumers, light, OverlayTexture.DEFAULT_UV);
matrices.pop();
blockEntity.setWorld(null);
return;
}
}
BipedEntityModel<?> model = getBipedModel(dispatcher, e);
if (model != null) {
model.sneaking = e.isSneaking();
}
e.setFireTicks(fireTicks);
dispatcher.render(e, x, y, z, e.getYaw(), tickDelta, matrices, vertexConsumers, light);
e.setFireTicks(0);
if (model != null) {
model.sneaking = false;
}
}
@Nullable
private BipedEntityModel<?> getBipedModel(EntityRenderDispatcher dispatcher, Entity entity) {
if (dispatcher.getRenderer(entity) instanceof LivingEntityRenderer livingRenderer
&& livingRenderer.getModel() instanceof BipedEntityModel<?> biped) {
return biped;
}
return null;
return disguiseLookup.getAppearanceFor(pony).map(effect -> disguiseRenderer.render(pony, effect, x, y, z, tickDelta, matrices, vertexConsumers, light)).orElse(false);
}
private void flipAngles(Entity entity) {

View file

@ -20,7 +20,7 @@ abstract class MixinEntityRenderDispatcher {
@Inject(method = RENDER, at = @At("HEAD"), cancellable = true)
private <E extends Entity> void beforeRender(E entity, double x, double y, double z, float yaw, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, CallbackInfo info) {
if (WorldRenderDelegate.INSTANCE.beforeEntityRender((EntityRenderDispatcher)(Object)this, entity, x, y, z, yaw, tickDelta, matrices, vertexConsumers, light)) {
if (WorldRenderDelegate.INSTANCE.beforeEntityRender(entity, x, y, z, yaw, tickDelta, matrices, vertexConsumers, light)) {
info.cancel();
}
}