diff --git a/src/main/java/com/atsuishio/superbwarfare/client/renderer/CustomGunRenderer.java b/src/main/java/com/atsuishio/superbwarfare/client/renderer/CustomGunRenderer.java index de02fbd6a..01566adef 100644 --- a/src/main/java/com/atsuishio/superbwarfare/client/renderer/CustomGunRenderer.java +++ b/src/main/java/com/atsuishio/superbwarfare/client/renderer/CustomGunRenderer.java @@ -5,12 +5,15 @@ import com.atsuishio.superbwarfare.config.client.DisplayConfig; import com.atsuishio.superbwarfare.item.gun.GunItem; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; +import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.entity.ItemRenderer; import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.ItemDisplayContext; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.phys.Vec3; import org.jetbrains.annotations.Nullable; import org.joml.Matrix4f; import software.bernie.geckolib.animatable.GeoAnimatable; @@ -25,6 +28,8 @@ public class CustomGunRenderer extends GeoIte public static final float SCALE_RECIPROCAL = 1.0f / 16.0f; + public static final int LOD_DISTANCE = 100; + protected T animatable; protected boolean renderArms = false; protected MultiBufferSource currentBuffer; @@ -35,12 +40,6 @@ public class CustomGunRenderer extends GeoIte super(model); } - @Override - public void renderByItem(ItemStack stack, ItemDisplayContext transformType, PoseStack matrixStack, MultiBufferSource bufferIn, int combinedLightIn, int p_239207_6_) { - this.transformType = transformType; - super.renderByItem(stack, transformType, matrixStack, bufferIn, combinedLightIn, p_239207_6_); - } - @Override public void actuallyRender(PoseStack matrixStackIn, T animatable, BakedGeoModel model, RenderType type, MultiBufferSource renderTypeBuffer, VertexConsumer vertexBuilder, boolean isRenderer, float partialTicks, int packedLightIn, int packedOverlayIn, int color) { @@ -55,7 +54,7 @@ public class CustomGunRenderer extends GeoIte @Override public RenderType getRenderType(T animatable, ResourceLocation texture, MultiBufferSource bufferSource, float partialTick) { - return RenderType.entityTranslucent(getTextureLocation(animatable)); + return RenderType.entityTranslucent(texture); } @Override @@ -69,7 +68,45 @@ public class CustomGunRenderer extends GeoIte return gunModel.getLODTextureResource(animatable); } - return geoModel.getTextureResource(animatable); + return geoModel.getTextureResource(animatable, null); + } + + public ResourceLocation getTextureLocation(T animatable, PoseStack poseStack) { + var geoModel = getGeoModel(); + + if (renderPerspective != ItemDisplayContext.FIRST_PERSON_RIGHT_HAND + && DisplayConfig.ENABLE_GUN_LOD.get() + && geoModel instanceof CustomGunModel gunModel + ) { + var player = Minecraft.getInstance().player; + if (player != null) { + Vec3 pos = new Vec3(poseStack.last().pose().m30(), poseStack.last().pose().m31(), poseStack.last().pose().m32()); + if (pos.lengthSqr() >= LOD_DISTANCE) { + return gunModel.getLODTextureResource(animatable); + } else { + return geoModel.getTextureResource(animatable, null); + } + } + return gunModel.getLODTextureResource(animatable); + } + return geoModel.getTextureResource(animatable, null); + } + + @Override + public void renderByItem(ItemStack stack, ItemDisplayContext transformType, PoseStack poseStack, MultiBufferSource bufferSource, int packedLight, int packedOverlay) { + this.animatable = (T) stack.getItem(); + this.currentItemStack = stack; + this.renderPerspective = transformType; + + if (transformType == ItemDisplayContext.GUI) { + renderInGui(transformType, poseStack, bufferSource, packedLight, packedOverlay, Minecraft.getInstance().getTimer().getRealtimeDeltaTicks()); + } else { + RenderType renderType = getRenderType(this.animatable, getTextureLocation(this.animatable, poseStack), bufferSource, Minecraft.getInstance().getTimer().getRealtimeDeltaTicks()); + VertexConsumer buffer = ItemRenderer.getFoilBufferDirect(bufferSource, renderType, false, this.currentItemStack != null && this.currentItemStack.hasFoil()); + + defaultRender(poseStack, this.animatable, bufferSource, renderType, buffer, + 0, Minecraft.getInstance().getTimer().getRealtimeDeltaTicks(), packedLight); + } } @Override @@ -79,21 +116,33 @@ public class CustomGunRenderer extends GeoIte Color renderColor = getRenderColor(animatable, partialTick, packedLight); int packedOverlay = getPackedOverlay(animatable, 0, partialTick); + var player = Minecraft.getInstance().player; + ResourceLocation modelLocation; var geoModel = getGeoModel(); if (renderPerspective != ItemDisplayContext.FIRST_PERSON_RIGHT_HAND && DisplayConfig.ENABLE_GUN_LOD.get() && geoModel instanceof CustomGunModel gunModel ) { - modelLocation = gunModel.getLODModelResource(animatable); + if (player != null) { + Vec3 pos = new Vec3(poseStack.last().pose().m30(), poseStack.last().pose().m31(), poseStack.last().pose().m32()); + if (pos.lengthSqr() >= LOD_DISTANCE) { + modelLocation = gunModel.getLODModelResource(animatable); + } else { + // TODO 这个地方有问题,如果是在这里使用了高模,会导致custom animation无法分离 + modelLocation = geoModel.getModelResource(animatable, null); + } + } else { + modelLocation = gunModel.getLODModelResource(animatable); + } } else { - modelLocation = geoModel.getModelResource(animatable); + modelLocation = geoModel.getModelResource(animatable, null); } BakedGeoModel model = geoModel.getBakedModel(modelLocation); if (renderType == null) - renderType = getRenderType(animatable, getTextureLocation(animatable), bufferSource, partialTick); + renderType = getRenderType(animatable, getTextureLocation(animatable, poseStack), bufferSource, partialTick); if (buffer == null) buffer = bufferSource.getBuffer(renderType); @@ -146,7 +195,7 @@ public class CustomGunRenderer extends GeoIte RenderUtil.prepMatrixForBone(poseStack, bone); if (bone.getName().endsWith("_illuminated")) { - renderCubesOfBone(poseStack, bone, bufferSource.getBuffer(ModRenderTypes.ILLUMINATED.apply(this.getTextureLocation(animatable))), + renderCubesOfBone(poseStack, bone, bufferSource.getBuffer(ModRenderTypes.ILLUMINATED.apply(this.getTextureLocation(animatable, poseStack))), packedLight, OverlayTexture.NO_OVERLAY, color); } this.illuminatedRenderChildBones(poseStack, animatable, bone, renderType, bufferSource, buffer, partialTick, packedLight, packedOverlay, color);