mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-12-27 23:47:09 +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.RenderStage;
|
||||
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.visualization.VisualizationHelper;
|
||||
import com.jozufozu.flywheel.impl.visualization.VisualizationManagerImpl;
|
||||
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.LevelRenderer;
|
||||
import net.minecraft.client.renderer.LightTexture;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.RenderBuffers;
|
||||
import net.minecraft.server.level.BlockDestructionProgress;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
|
||||
@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
|
||||
|
||||
@Unique
|
||||
|
|
|
@ -39,6 +39,7 @@ public class InstanceTree {
|
|||
@Nullable
|
||||
public TransformedInstance instance;
|
||||
|
||||
private final Quaternionf rotation = new Quaternionf();
|
||||
private final Entry entry;
|
||||
private final PartPose initialPose;
|
||||
|
||||
|
@ -136,7 +137,7 @@ public class InstanceTree {
|
|||
void accept(T t, int i, int j);
|
||||
}
|
||||
|
||||
public void render(PoseStack pPoseStack) {
|
||||
public void updateInstances(PoseStack pPoseStack) {
|
||||
if (this.visible) {
|
||||
pPoseStack.pushPose();
|
||||
this.translateAndRotate(pPoseStack);
|
||||
|
@ -146,7 +147,7 @@ public class InstanceTree {
|
|||
}
|
||||
|
||||
for (InstanceTree modelpart : this.children.values()) {
|
||||
modelpart.render(pPoseStack);
|
||||
modelpart.updateInstances(pPoseStack);
|
||||
}
|
||||
|
||||
pPoseStack.popPose();
|
||||
|
@ -156,7 +157,7 @@ public class InstanceTree {
|
|||
public void translateAndRotate(PoseStack pPoseStack) {
|
||||
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) {
|
||||
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) {
|
||||
|
|
|
@ -22,24 +22,24 @@ public abstract class AgeableListComponent {
|
|||
}
|
||||
|
||||
pPoseStack.translate(0.0F, this.config.babyYHeadOffset / 16.0F, this.config.babyZHeadOffset / 16.0F);
|
||||
for (InstanceTree p_102081_ : this.headParts()) {
|
||||
p_102081_.render(pPoseStack);
|
||||
for (InstanceTree headPart : this.headParts()) {
|
||||
headPart.updateInstances(pPoseStack);
|
||||
}
|
||||
pPoseStack.popPose();
|
||||
pPoseStack.pushPose();
|
||||
float f1 = 1.0F / this.config.babyBodyScale;
|
||||
pPoseStack.scale(f1, f1, f1);
|
||||
pPoseStack.translate(0.0F, this.config.bodyYOffset / 16.0F, 0.0F);
|
||||
for (InstanceTree p_102071_ : this.bodyParts()) {
|
||||
p_102071_.render(pPoseStack);
|
||||
for (InstanceTree bodyPart : this.bodyParts()) {
|
||||
bodyPart.updateInstances(pPoseStack);
|
||||
}
|
||||
pPoseStack.popPose();
|
||||
} else {
|
||||
for (InstanceTree p_102061_ : this.headParts()) {
|
||||
p_102061_.render(pPoseStack);
|
||||
for (InstanceTree headPart : this.headParts()) {
|
||||
headPart.updateInstances(pPoseStack);
|
||||
}
|
||||
for (InstanceTree p_102051_ : this.bodyParts()) {
|
||||
p_102051_.render(pPoseStack);
|
||||
for (InstanceTree bodyPart : this.bodyParts()) {
|
||||
bodyPart.updateInstances(pPoseStack);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ public class CowVisual extends SimpleEntityVisual<Cow> {
|
|||
cowQuadrupedComponent.root.walkInstances(overlay, light, (i, o, l) -> {
|
||||
i.setOverlay(o);
|
||||
i.light(l);
|
||||
i.setChanged();
|
||||
// We'll #setChanged in the
|
||||
});
|
||||
|
||||
stack.setIdentity();
|
||||
|
|
|
@ -18,6 +18,7 @@ import com.mojang.math.Axis;
|
|||
|
||||
import net.minecraft.client.Minecraft;
|
||||
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.MultiPartBakedModel;
|
||||
import net.minecraft.client.resources.model.SimpleBakedModel;
|
||||
|
@ -48,9 +49,7 @@ public class ItemVisual extends SimpleEntityVisual<ItemEntity> {
|
|||
super(ctx, entity);
|
||||
|
||||
var item = entity.getItem();
|
||||
model = Minecraft.getInstance()
|
||||
.getItemRenderer()
|
||||
.getModel(item, entity.level(), null, entity.getId());
|
||||
model = getModel(item);
|
||||
|
||||
isSupported = isSupported(model);
|
||||
|
||||
|
@ -61,11 +60,14 @@ public class ItemVisual extends SimpleEntityVisual<ItemEntity> {
|
|||
}
|
||||
|
||||
public static boolean isSupported(ItemEntity entity) {
|
||||
var model = Minecraft.getInstance()
|
||||
.getItemRenderer()
|
||||
.getModel(entity.getItem(), entity.level(), null, entity.getId());
|
||||
return isSupported(getModel(entity.getItem()));
|
||||
}
|
||||
|
||||
return isSupported(model);
|
||||
public static BakedModel getModel(ItemStack stack) {
|
||||
return Minecraft.getInstance()
|
||||
.getItemRenderer()
|
||||
.getItemModelShaper()
|
||||
.getItemModel(stack);
|
||||
}
|
||||
|
||||
public static boolean isSupported(BakedModel model) {
|
||||
|
@ -73,9 +75,7 @@ public class ItemVisual extends SimpleEntityVisual<ItemEntity> {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!model.getOverrides()
|
||||
.getOverrides()
|
||||
.isEmpty()) {
|
||||
if (model.getOverrides() != ItemOverrides.EMPTY) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -110,7 +110,6 @@ public class ItemVisual extends SimpleEntityVisual<ItemEntity> {
|
|||
.translate(getVisualPosition(ctx.partialTick()));
|
||||
|
||||
instances.resetCount();
|
||||
pPoseStack.pushPose();
|
||||
ItemStack itemstack = entity.getItem();
|
||||
int i = itemstack.isEmpty() ? 187 : Item.getId(itemstack.getItem()) + itemstack.getDamageValue();
|
||||
var random = RANDOM.get();
|
||||
|
@ -158,7 +157,6 @@ public class ItemVisual extends SimpleEntityVisual<ItemEntity> {
|
|||
}
|
||||
}
|
||||
|
||||
pPoseStack.popPose();
|
||||
instances.discardExtra();
|
||||
}
|
||||
|
||||
|
@ -199,7 +197,6 @@ public class ItemVisual extends SimpleEntityVisual<ItemEntity> {
|
|||
}
|
||||
|
||||
public record ItemKey(ItemStack stack, BakedModel model) {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
"client": [
|
||||
"BlockEntityTypeMixin",
|
||||
"ClientChunkCacheMixin",
|
||||
"ClientLevelMixin",
|
||||
"EntityTypeMixin",
|
||||
"LevelMixin",
|
||||
"LevelRendererMixin",
|
||||
|
|
Loading…
Reference in a new issue