diff --git a/src/main/java/com/github/tartaricacid/touhoulittlemaid/client/gui/entity/cache/CacheIconManager.java b/src/main/java/com/github/tartaricacid/touhoulittlemaid/client/gui/entity/cache/CacheIconManager.java index 603aea568..0c0e886c8 100644 --- a/src/main/java/com/github/tartaricacid/touhoulittlemaid/client/gui/entity/cache/CacheIconManager.java +++ b/src/main/java/com/github/tartaricacid/touhoulittlemaid/client/gui/entity/cache/CacheIconManager.java @@ -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; @@ -71,7 +71,7 @@ public static void openModelSwitcherModelGui(EntityMaid maid, TileEntityModelSwi } private static CacheScreen getMaidCacheScreen(AbstractModelGui 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); @@ -79,21 +79,23 @@ private static CacheScreen getMaidCacheScreen(Abstrac 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 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); }); diff --git a/src/main/java/com/github/tartaricacid/touhoulittlemaid/client/gui/entity/cache/CacheScreen.java b/src/main/java/com/github/tartaricacid/touhoulittlemaid/client/gui/entity/cache/CacheScreen.java index 4c47884ae..287ea29df 100644 --- a/src/main/java/com/github/tartaricacid/touhoulittlemaid/client/gui/entity/cache/CacheScreen.java +++ b/src/main/java/com/github/tartaricacid/touhoulittlemaid/client/gui/entity/cache/CacheScreen.java @@ -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; @@ -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) @@ -27,18 +30,20 @@ public class CacheScreen extends S private final Queue modelInfos; private final EntityRender entityRender; private final int totalCount; + private final StopWatch stopWatch; public CacheScreen(Screen parent, EntityType entityType, Queue modelInfos, EntityRender 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; @@ -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 { - 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); } } diff --git a/src/main/java/com/github/tartaricacid/touhoulittlemaid/util/RenderHelper.java b/src/main/java/com/github/tartaricacid/touhoulittlemaid/util/RenderHelper.java index b3289b3e7..2e3172ea2 100644 --- a/src/main/java/com/github/tartaricacid/touhoulittlemaid/util/RenderHelper.java +++ b/src/main/java/com/github/tartaricacid/touhoulittlemaid/util/RenderHelper.java @@ -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; @@ -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(); + } }