Skip to content

Commit

Permalink
修改缓存机制,加快缓存速度
Browse files Browse the repository at this point in the history
  • Loading branch information
TartaricAcid committed Sep 6, 2024
1 parent d2bad4b commit 774b5b3
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
import com.github.tartaricacid.touhoulittlemaid.entity.passive.EntityMaid;
import com.github.tartaricacid.touhoulittlemaid.init.InitEntities;
import com.github.tartaricacid.touhoulittlemaid.tileentity.TileEntityModelSwitcher;
import com.github.tartaricacid.touhoulittlemaid.util.RenderHelper;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.inventory.InventoryScreen;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;

Expand Down Expand Up @@ -71,29 +71,31 @@ public static void openModelSwitcherModelGui(EntityMaid maid, TileEntityModelSwi
}

private static CacheScreen<EntityMaid, MaidModelInfo> getMaidCacheScreen(AbstractModelGui<EntityMaid, MaidModelInfo> maidModelGui) {
return new CacheScreen<>(maidModelGui, InitEntities.MAID.get(), MAID_CACHE_QUEUE, (graphics, posX, posY, modelInfo, scaleModified, maid) -> {
return new CacheScreen<>(maidModelGui, InitEntities.MAID.get(), MAID_CACHE_QUEUE, (graphics, posX, posY, posZ, modelInfo, scaleModified, maid) -> {
clearMaidDataResidue(maid, false);
if (modelInfo.getEasterEgg() != null) {
maid.setModelId(EASTER_EGG_MODEL);
} else {
maid.setModelId(modelInfo.getModelId().toString());
}
int scale = scaleModified / 2;
InventoryScreen.renderEntityInInventory(
RenderHelper.renderEntityInInventory(
posX + scale,
posY + scaleModified - 5,
posZ,
(int) (scale * modelInfo.getRenderItemScale() * 0.9),
-25, -20, maid);
});
}

private static CacheScreen<EntityChair, ChairModelInfo> getChairCacheScreen(ChairModelGui chairModelGui) {
return new CacheScreen<>(chairModelGui, InitEntities.CHAIR.get(), CHAIR_CACHE_QUEUE, (graphics, posX, posY, modelInfo, scaleModified, chair) -> {
return new CacheScreen<>(chairModelGui, InitEntities.CHAIR.get(), CHAIR_CACHE_QUEUE, (graphics, posX, posY, posZ, modelInfo, scaleModified, chair) -> {
chair.setModelId(modelInfo.getModelId().toString());
int scale = scaleModified / 2;
InventoryScreen.renderEntityInInventory(
RenderHelper.renderEntityInInventory(
posX + scale,
posY + scaleModified - 5,
posZ,
(int) (scale * modelInfo.getRenderItemScale() * 0.9),
-25, -20, chair);
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.github.tartaricacid.touhoulittlemaid.client.gui.entity.cache;

import com.github.tartaricacid.touhoulittlemaid.TouhouLittleMaid;
import com.github.tartaricacid.touhoulittlemaid.client.renderer.texture.CacheIconTexture;
import com.github.tartaricacid.touhoulittlemaid.client.resource.pojo.IModelInfo;
import com.github.tartaricacid.touhoulittlemaid.util.EntityCacheUtil;
Expand All @@ -15,9 +16,11 @@
import net.minecraft.world.level.Level;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import org.apache.commons.lang3.time.StopWatch;

import java.util.Queue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;


@OnlyIn(Dist.CLIENT)
Expand All @@ -27,18 +30,20 @@ public class CacheScreen<T extends LivingEntity, E extends IModelInfo> extends S
private final Queue<E> modelInfos;
private final EntityRender<T, E> entityRender;
private final int totalCount;
private final StopWatch stopWatch;

public CacheScreen(Screen parent, EntityType<T> entityType, Queue<E> modelInfos, EntityRender<T, E> entityRender) {
super(Component.literal(" Cache Screen"));
super(Component.literal("Cache Screen"));
this.parent = parent;
this.entityType = entityType;
this.modelInfos = modelInfos;
this.entityRender = entityRender;
this.totalCount = modelInfos.size();
this.stopWatch = StopWatch.createStarted();
}

@SuppressWarnings("unchecked")
private void drawEntity(PoseStack pPoseStack, int posX, int posY, E modelInfo, int scaleModified) {
private void drawEntity(PoseStack pPoseStack, int posX, int posY, int posZ, E modelInfo, int scaleModified) {
Level world = getMinecraft().level;
if (world == null) {
return;
Expand All @@ -50,39 +55,57 @@ private void drawEntity(PoseStack pPoseStack, int posX, int posY, E modelInfo, i
e.fillInStackTrace();
return;
}
entityRender.render(pPoseStack, posX, posY, modelInfo, scaleModified, entity);
entityRender.render(pPoseStack, posX, posY, posZ, modelInfo, scaleModified, entity);
}

@Override
public void render(PoseStack pPoseStack, int mouseX, int mouseY, float partialTick) {
super.renderBackground(pPoseStack);
super.render(pPoseStack, mouseX, mouseY, partialTick);
public void render(PoseStack poseStack, int mouseX, int mouseY, float partialTick) {
super.renderBackground(poseStack);
super.render(poseStack, mouseX, mouseY, partialTick);

if (modelInfos.isEmpty()) {
stopWatch.stop();
double timeCost = stopWatch.getTime(TimeUnit.MILLISECONDS) / 1000.0;
TouhouLittleMaid.LOGGER.info("Cache icon time: {} seconds", timeCost);
Minecraft.getInstance().setScreen(parent);
return;
}

// 每帧尝试缓存 5 个
poseStack.pushPose();
int posZ = 0;
for (int i = 0; i < 5; i++) {
if (modelInfos.isEmpty()) {
return;
}
posZ += 100;
poseStack.translate(0, 0, 100);
doCacheIcon(poseStack, posZ);
}
poseStack.popPose();

int finishSize = totalCount - modelInfos.size();
drawCenteredString(poseStack, font, Component.translatable("gui.touhou_little_maid.cache_screen.progress", finishSize, totalCount), this.width / 2, this.height - 42, 0xFFFFFF);
drawCenteredString(poseStack, font, Component.translatable("gui.touhou_little_maid.cache_screen.desc"), this.width / 2, this.height - 30, 0xFFFFFF);
}

private void doCacheIcon(PoseStack poseStack, int posZ) {
E modelInfo = modelInfos.poll();
if (modelInfo != null) {
double guiScale = Minecraft.getInstance().getWindow().getGuiScale();
int scaleModified = (int) Math.ceil((256 / guiScale));

fill(pPoseStack, 0, 0, scaleModified, scaleModified + 2, IconCache.BACKGROUND_COLOR);
this.drawEntity(pPoseStack, 0, 0, modelInfo, scaleModified);
fill(poseStack, 0, 0, scaleModified, scaleModified + 2, IconCache.BACKGROUND_COLOR);
this.drawEntity(poseStack, 0, 0, posZ, modelInfo, scaleModified);
NativeImage nativeImage = IconCache.exportImageFromScreenshot(256, IconCache.BACKGROUND_COLOR_SHIFTED);

ResourceLocation modelId = modelInfo.getModelId();
CacheIconTexture cacheIconTexture = new CacheIconTexture(modelId, nativeImage);
Minecraft.getInstance().textureManager.register(modelInfo.getCacheIconId(), cacheIconTexture);
}

int finishSize = totalCount - modelInfos.size();
drawCenteredString(pPoseStack, font, Component.translatable("gui.touhou_little_maid.cache_screen.progress", finishSize, totalCount), this.width / 2, this.height - 42, 0xFFFFFF);
drawCenteredString(pPoseStack, font, Component.translatable("gui.touhou_little_maid.cache_screen.desc"), this.width / 2, this.height - 30, 0xFFFFFF);
}

public interface EntityRender<T extends LivingEntity, E extends IModelInfo> {
void render(PoseStack pPoseStack, int posX, int posY, E modelInfo, int scaleModified, T entity);
void render(PoseStack pPoseStack, int posX, int posY, int posZ, E modelInfo, int scaleModified, T entity);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.mojang.math.Matrix3f;
import com.mojang.math.Matrix4f;
import com.mojang.math.Quaternion;
import com.mojang.math.Vector3f;
import net.minecraft.client.Camera;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Font;
Expand Down Expand Up @@ -154,4 +155,60 @@ public static void renderEntityInInventory(PoseStack poseStack, int pX, int pY,
poseStack.popPose();
Lighting.setupFor3DItems();
}

/**
* 修改自原版的 net.minecraft.client.gui.screens.inventory.InventoryScreen#renderEntityInInventoryRaw(int, int, int, float, float, net.minecraft.world.entity.LivingEntity)
* 主要添加了 posZ 的偏移
*/
public static void renderEntityInInventory(int posX, int posY, int posZ, int scale, float mouseX, float mouseY, LivingEntity entity) {
float angleX = (float) Math.atan(mouseX / 40.0F);
float angleY = (float) Math.atan(mouseY / 40.0F);

PoseStack viewStack = RenderSystem.getModelViewStack();
viewStack.pushPose();
viewStack.translate(posX, posY, posZ + 1050);
viewStack.scale(1.0F, 1.0F, -1.0F);
RenderSystem.applyModelViewMatrix();

PoseStack poseStack = new PoseStack();
poseStack.translate(0, 0, 1000);
poseStack.scale((float) scale, (float) scale, (float) scale);
Quaternion zDeg = Vector3f.ZP.rotationDegrees(180.0F);
Quaternion xDeg = Vector3f.XP.rotationDegrees(angleY * 20.0F);
zDeg.mul(xDeg);
poseStack.mulPose(zDeg);

float yBodyRot = entity.yBodyRot;
float yRot = entity.getYRot();
float xRot = entity.getXRot();
float yHeadRotO = entity.yHeadRotO;
float yHeadRot = entity.yHeadRot;

entity.yBodyRot = 180.0F + angleX * 20.0F;
entity.setYRot(180.0F + angleX * 40.0F);
entity.setXRot(-angleY * 20.0F);
entity.yHeadRot = entity.getYRot();
entity.yHeadRotO = entity.getYRot();

Lighting.setupForEntityInInventory();
EntityRenderDispatcher renderDispatcher = Minecraft.getInstance().getEntityRenderDispatcher();
xDeg.conj();
renderDispatcher.overrideCameraOrientation(xDeg);
renderDispatcher.setRenderShadow(false);
MultiBufferSource.BufferSource bufferSource = Minecraft.getInstance().renderBuffers().bufferSource();
RenderSystem.runAsFancy(() -> renderDispatcher.render(entity, 0, 0, 0, 0.0F, 1.0F, poseStack, bufferSource, 0xF000F0));
bufferSource.endBatch();
renderDispatcher.setRenderShadow(true);

entity.yBodyRot = yBodyRot;
entity.setYRot(yRot);
entity.setXRot(xRot);
entity.yHeadRotO = yHeadRotO;
entity.yHeadRot = yHeadRot;

viewStack.popPose();

RenderSystem.applyModelViewMatrix();
Lighting.setupFor3DItems();
}
}

0 comments on commit 774b5b3

Please sign in to comment.