mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-12-28 16:06:28 +01:00
Overridden overrides
- Only instance items if their *base* baked model has no overrides - ItemRenderer#getModel applies overrides internally, so we have to go directly to the ItemModelShaper - Don't filter the results of ClientLevel#entitiesForRendering, instead do an early exit in LevelRenderer#renderEntity - Avoids allocating a potentially massive list - Only need to loop over the entity list once - Visible entity counter is fixed - Would be nice to continue out of an iteration to avoid other unnecessary checks in the render loop, but I don't think there's a way to do that with mixin - Use a persistent rotation quat in InstanceTree to avoid allocations - Only call setChanged when updating instances in CowVisual, saves a ton of atomic overhead
This commit is contained in:
parent
08b09f8a3c
commit
5df7b09ecb
7 changed files with 35 additions and 58 deletions
|
@ -1,32 +0,0 @@
|
||||||
package com.jozufozu.flywheel.impl.mixin;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
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 com.google.common.collect.Lists;
|
|
||||||
import com.jozufozu.flywheel.api.visualization.VisualizationManager;
|
|
||||||
import com.jozufozu.flywheel.impl.visualization.VisualizationHelper;
|
|
||||||
|
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
|
||||||
import net.minecraft.world.entity.Entity;
|
|
||||||
|
|
||||||
@Mixin(ClientLevel.class)
|
|
||||||
abstract class ClientLevelMixin {
|
|
||||||
@Inject(method = "entitiesForRendering()Ljava/lang/Iterable;", at = @At("RETURN"), cancellable = true)
|
|
||||||
private void flywheel$filterEntities(CallbackInfoReturnable<Iterable<Entity>> cir) {
|
|
||||||
if (!VisualizationManager.supportsVisualization((ClientLevel) (Object) this)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Iterable<Entity> entities = cir.getReturnValue();
|
|
||||||
ArrayList<Entity> filtered = Lists.newArrayList(entities);
|
|
||||||
|
|
||||||
filtered.removeIf(VisualizationHelper::shouldSkipRender);
|
|
||||||
|
|
||||||
cir.setReturnValue(filtered);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -18,7 +18,9 @@ import com.jozufozu.flywheel.api.event.BeginFrameEvent;
|
||||||
import com.jozufozu.flywheel.api.event.ReloadLevelRendererEvent;
|
import com.jozufozu.flywheel.api.event.ReloadLevelRendererEvent;
|
||||||
import com.jozufozu.flywheel.api.event.RenderStage;
|
import com.jozufozu.flywheel.api.event.RenderStage;
|
||||||
import com.jozufozu.flywheel.api.event.RenderStageEvent;
|
import com.jozufozu.flywheel.api.event.RenderStageEvent;
|
||||||
|
import com.jozufozu.flywheel.api.visualization.VisualizationManager;
|
||||||
import com.jozufozu.flywheel.impl.event.RenderContextImpl;
|
import com.jozufozu.flywheel.impl.event.RenderContextImpl;
|
||||||
|
import com.jozufozu.flywheel.impl.visualization.VisualizationHelper;
|
||||||
import com.jozufozu.flywheel.impl.visualization.VisualizationManagerImpl;
|
import com.jozufozu.flywheel.impl.visualization.VisualizationManagerImpl;
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
|
|
||||||
|
@ -28,8 +30,10 @@ import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
import net.minecraft.client.renderer.GameRenderer;
|
import net.minecraft.client.renderer.GameRenderer;
|
||||||
import net.minecraft.client.renderer.LevelRenderer;
|
import net.minecraft.client.renderer.LevelRenderer;
|
||||||
import net.minecraft.client.renderer.LightTexture;
|
import net.minecraft.client.renderer.LightTexture;
|
||||||
|
import net.minecraft.client.renderer.MultiBufferSource;
|
||||||
import net.minecraft.client.renderer.RenderBuffers;
|
import net.minecraft.client.renderer.RenderBuffers;
|
||||||
import net.minecraft.server.level.BlockDestructionProgress;
|
import net.minecraft.server.level.BlockDestructionProgress;
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraftforge.common.MinecraftForge;
|
import net.minecraftforge.common.MinecraftForge;
|
||||||
|
|
||||||
@Mixin(value = LevelRenderer.class, priority = 1001) // Higher priority to go after Sodium
|
@Mixin(value = LevelRenderer.class, priority = 1001) // Higher priority to go after Sodium
|
||||||
|
@ -79,6 +83,14 @@ abstract class LevelRendererMixin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ENTITY CANCELLING
|
||||||
|
@Inject(method = "renderEntity", at = @At("HEAD"), cancellable = true)
|
||||||
|
private void flywheel$decideNotToRenderEntity(Entity pEntity, double pCamX, double pCamY, double pCamZ, float pPartialTick, PoseStack pPoseStack, MultiBufferSource pBufferSource, CallbackInfo ci) {
|
||||||
|
if (VisualizationManager.supportsVisualization(pEntity.level()) && VisualizationHelper.shouldSkipRender(pEntity)) {
|
||||||
|
ci.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// STAGE DISPATCHING
|
// STAGE DISPATCHING
|
||||||
|
|
||||||
@Unique
|
@Unique
|
||||||
|
|
|
@ -39,6 +39,7 @@ public class InstanceTree {
|
||||||
@Nullable
|
@Nullable
|
||||||
public TransformedInstance instance;
|
public TransformedInstance instance;
|
||||||
|
|
||||||
|
private final Quaternionf rotation = new Quaternionf();
|
||||||
private final Entry entry;
|
private final Entry entry;
|
||||||
private final PartPose initialPose;
|
private final PartPose initialPose;
|
||||||
|
|
||||||
|
@ -136,7 +137,7 @@ public class InstanceTree {
|
||||||
void accept(T t, int i, int j);
|
void accept(T t, int i, int j);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void render(PoseStack pPoseStack) {
|
public void updateInstances(PoseStack pPoseStack) {
|
||||||
if (this.visible) {
|
if (this.visible) {
|
||||||
pPoseStack.pushPose();
|
pPoseStack.pushPose();
|
||||||
this.translateAndRotate(pPoseStack);
|
this.translateAndRotate(pPoseStack);
|
||||||
|
@ -146,7 +147,7 @@ public class InstanceTree {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (InstanceTree modelpart : this.children.values()) {
|
for (InstanceTree modelpart : this.children.values()) {
|
||||||
modelpart.render(pPoseStack);
|
modelpart.updateInstances(pPoseStack);
|
||||||
}
|
}
|
||||||
|
|
||||||
pPoseStack.popPose();
|
pPoseStack.popPose();
|
||||||
|
@ -156,7 +157,7 @@ public class InstanceTree {
|
||||||
public void translateAndRotate(PoseStack pPoseStack) {
|
public void translateAndRotate(PoseStack pPoseStack) {
|
||||||
pPoseStack.translate(this.x / 16.0F, this.y / 16.0F, this.z / 16.0F);
|
pPoseStack.translate(this.x / 16.0F, this.y / 16.0F, this.z / 16.0F);
|
||||||
if (this.xRot != 0.0F || this.yRot != 0.0F || this.zRot != 0.0F) {
|
if (this.xRot != 0.0F || this.yRot != 0.0F || this.zRot != 0.0F) {
|
||||||
pPoseStack.mulPose((new Quaternionf()).rotationZYX(this.zRot, this.yRot, this.xRot));
|
pPoseStack.mulPose(rotation.rotationZYX(this.zRot, this.yRot, this.xRot));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.xScale != 1.0F || this.yScale != 1.0F || this.zScale != 1.0F) {
|
if (this.xScale != 1.0F || this.yScale != 1.0F || this.zScale != 1.0F) {
|
||||||
|
|
|
@ -22,24 +22,24 @@ public abstract class AgeableListComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
pPoseStack.translate(0.0F, this.config.babyYHeadOffset / 16.0F, this.config.babyZHeadOffset / 16.0F);
|
pPoseStack.translate(0.0F, this.config.babyYHeadOffset / 16.0F, this.config.babyZHeadOffset / 16.0F);
|
||||||
for (InstanceTree p_102081_ : this.headParts()) {
|
for (InstanceTree headPart : this.headParts()) {
|
||||||
p_102081_.render(pPoseStack);
|
headPart.updateInstances(pPoseStack);
|
||||||
}
|
}
|
||||||
pPoseStack.popPose();
|
pPoseStack.popPose();
|
||||||
pPoseStack.pushPose();
|
pPoseStack.pushPose();
|
||||||
float f1 = 1.0F / this.config.babyBodyScale;
|
float f1 = 1.0F / this.config.babyBodyScale;
|
||||||
pPoseStack.scale(f1, f1, f1);
|
pPoseStack.scale(f1, f1, f1);
|
||||||
pPoseStack.translate(0.0F, this.config.bodyYOffset / 16.0F, 0.0F);
|
pPoseStack.translate(0.0F, this.config.bodyYOffset / 16.0F, 0.0F);
|
||||||
for (InstanceTree p_102071_ : this.bodyParts()) {
|
for (InstanceTree bodyPart : this.bodyParts()) {
|
||||||
p_102071_.render(pPoseStack);
|
bodyPart.updateInstances(pPoseStack);
|
||||||
}
|
}
|
||||||
pPoseStack.popPose();
|
pPoseStack.popPose();
|
||||||
} else {
|
} else {
|
||||||
for (InstanceTree p_102061_ : this.headParts()) {
|
for (InstanceTree headPart : this.headParts()) {
|
||||||
p_102061_.render(pPoseStack);
|
headPart.updateInstances(pPoseStack);
|
||||||
}
|
}
|
||||||
for (InstanceTree p_102051_ : this.bodyParts()) {
|
for (InstanceTree bodyPart : this.bodyParts()) {
|
||||||
p_102051_.render(pPoseStack);
|
bodyPart.updateInstances(pPoseStack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,7 @@ public class CowVisual extends SimpleEntityVisual<Cow> {
|
||||||
cowQuadrupedComponent.root.walkInstances(overlay, light, (i, o, l) -> {
|
cowQuadrupedComponent.root.walkInstances(overlay, light, (i, o, l) -> {
|
||||||
i.setOverlay(o);
|
i.setOverlay(o);
|
||||||
i.light(l);
|
i.light(l);
|
||||||
i.setChanged();
|
// We'll #setChanged in the
|
||||||
});
|
});
|
||||||
|
|
||||||
stack.setIdentity();
|
stack.setIdentity();
|
||||||
|
|
|
@ -18,6 +18,7 @@ import com.mojang.math.Axis;
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.renderer.LightTexture;
|
import net.minecraft.client.renderer.LightTexture;
|
||||||
|
import net.minecraft.client.renderer.block.model.ItemOverrides;
|
||||||
import net.minecraft.client.resources.model.BakedModel;
|
import net.minecraft.client.resources.model.BakedModel;
|
||||||
import net.minecraft.client.resources.model.MultiPartBakedModel;
|
import net.minecraft.client.resources.model.MultiPartBakedModel;
|
||||||
import net.minecraft.client.resources.model.SimpleBakedModel;
|
import net.minecraft.client.resources.model.SimpleBakedModel;
|
||||||
|
@ -48,9 +49,7 @@ public class ItemVisual extends SimpleEntityVisual<ItemEntity> {
|
||||||
super(ctx, entity);
|
super(ctx, entity);
|
||||||
|
|
||||||
var item = entity.getItem();
|
var item = entity.getItem();
|
||||||
model = Minecraft.getInstance()
|
model = getModel(item);
|
||||||
.getItemRenderer()
|
|
||||||
.getModel(item, entity.level(), null, entity.getId());
|
|
||||||
|
|
||||||
isSupported = isSupported(model);
|
isSupported = isSupported(model);
|
||||||
|
|
||||||
|
@ -61,11 +60,14 @@ public class ItemVisual extends SimpleEntityVisual<ItemEntity> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isSupported(ItemEntity entity) {
|
public static boolean isSupported(ItemEntity entity) {
|
||||||
var model = Minecraft.getInstance()
|
return isSupported(getModel(entity.getItem()));
|
||||||
.getItemRenderer()
|
}
|
||||||
.getModel(entity.getItem(), entity.level(), null, entity.getId());
|
|
||||||
|
|
||||||
return isSupported(model);
|
public static BakedModel getModel(ItemStack stack) {
|
||||||
|
return Minecraft.getInstance()
|
||||||
|
.getItemRenderer()
|
||||||
|
.getItemModelShaper()
|
||||||
|
.getItemModel(stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isSupported(BakedModel model) {
|
public static boolean isSupported(BakedModel model) {
|
||||||
|
@ -73,9 +75,7 @@ public class ItemVisual extends SimpleEntityVisual<ItemEntity> {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!model.getOverrides()
|
if (model.getOverrides() != ItemOverrides.EMPTY) {
|
||||||
.getOverrides()
|
|
||||||
.isEmpty()) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,7 +110,6 @@ public class ItemVisual extends SimpleEntityVisual<ItemEntity> {
|
||||||
.translate(getVisualPosition(ctx.partialTick()));
|
.translate(getVisualPosition(ctx.partialTick()));
|
||||||
|
|
||||||
instances.resetCount();
|
instances.resetCount();
|
||||||
pPoseStack.pushPose();
|
|
||||||
ItemStack itemstack = entity.getItem();
|
ItemStack itemstack = entity.getItem();
|
||||||
int i = itemstack.isEmpty() ? 187 : Item.getId(itemstack.getItem()) + itemstack.getDamageValue();
|
int i = itemstack.isEmpty() ? 187 : Item.getId(itemstack.getItem()) + itemstack.getDamageValue();
|
||||||
var random = RANDOM.get();
|
var random = RANDOM.get();
|
||||||
|
@ -158,7 +157,6 @@ public class ItemVisual extends SimpleEntityVisual<ItemEntity> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pPoseStack.popPose();
|
|
||||||
instances.discardExtra();
|
instances.discardExtra();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,7 +197,6 @@ public class ItemVisual extends SimpleEntityVisual<ItemEntity> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public record ItemKey(ItemStack stack, BakedModel model) {
|
public record ItemKey(ItemStack stack, BakedModel model) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) {
|
if (this == o) {
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
"client": [
|
"client": [
|
||||||
"BlockEntityTypeMixin",
|
"BlockEntityTypeMixin",
|
||||||
"ClientChunkCacheMixin",
|
"ClientChunkCacheMixin",
|
||||||
"ClientLevelMixin",
|
|
||||||
"EntityTypeMixin",
|
"EntityTypeMixin",
|
||||||
"LevelMixin",
|
"LevelMixin",
|
||||||
"LevelRendererMixin",
|
"LevelRendererMixin",
|
||||||
|
|
Loading…
Reference in a new issue