From 92db60d73e3a006ccd81c64f597a6fe356fb9425 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Tue, 4 Oct 2022 23:06:42 +0700 Subject: [PATCH] Basic matter replicator graphics --- .../matter/MatterReplicatorBlockEntity.kt | 15 +++ .../mc/otm/client/render/RenderHelper.kt | 7 ++ .../blockentity/MatterReplicatorRenderer.kt | 97 +++++++++++++++++++ .../ru/dbotthepony/mc/otm/core/EuclidMath.kt | 28 ++++++ .../mc/otm/registry/MBlockEntities.kt | 3 + src/main/resources/coremods/code_injector.js | 86 ++++++++++++++++ 6 files changed, 236 insertions(+) create mode 100644 src/main/kotlin/ru/dbotthepony/mc/otm/client/render/blockentity/MatterReplicatorRenderer.kt diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterReplicatorBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterReplicatorBlockEntity.kt index 3d0173acd..818090380 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterReplicatorBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterReplicatorBlockEntity.kt @@ -173,6 +173,20 @@ class MatterReplicatorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : MatterNetworkGraph.discoverFull(this, matterNode) } + override fun jobUpdated(oldJob: ReplicatorJob?, newJob: ReplicatorJob?) { + visualItemStack = newJob?.itemStack ?: ItemStack.EMPTY + visualProgress = 0f + } + + var visualItemStack by synchronizer.item(observe = false) + private set + + var visualProgress by synchronizer.float() + private set + + var renderRotation = 0f + var lastRender = 0L + override fun computeNextJob(): Pair { if (energy.batteryLevel < BASE_CONSUMPTION) { return null to IdleReason.POWER @@ -246,6 +260,7 @@ class MatterReplicatorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : // в машине достаточно материи matter.extractMatterInner(drainPerTick, false) + visualProgress = workProgress return Status.SUCCESS } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/RenderHelper.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/RenderHelper.kt index a558572dd..180a95c3d 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/RenderHelper.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/RenderHelper.kt @@ -24,6 +24,13 @@ var zLevel = 0f var drawColor = RGBAColor(255, 255, 255, 255) var is3DContext = false +/** + * Prohibits from changing blend function through RenderSystem.enable/disable + * + * ALWAYS use try/finally block with this + */ +var lockBlendFunc = false + @JvmName("setDrawColor\$JVM") fun setDrawColor(color: RGBAColor) { drawColor = color diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/blockentity/MatterReplicatorRenderer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/blockentity/MatterReplicatorRenderer.kt new file mode 100644 index 000000000..ec5703a84 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/blockentity/MatterReplicatorRenderer.kt @@ -0,0 +1,97 @@ +package ru.dbotthepony.mc.otm.client.render.blockentity + +import com.mojang.blaze3d.platform.GlStateManager +import com.mojang.blaze3d.platform.GlStateManager.DestFactor +import com.mojang.blaze3d.platform.GlStateManager.SourceFactor +import com.mojang.blaze3d.systems.RenderSystem +import com.mojang.blaze3d.vertex.PoseStack +import com.mojang.math.Vector3f +import net.minecraft.client.renderer.MultiBufferSource +import net.minecraft.client.renderer.block.model.ItemTransforms +import net.minecraft.client.renderer.blockentity.BlockEntityRenderer +import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider +import org.lwjgl.opengl.GL14 +import org.lwjgl.opengl.GL14.GL_ADD +import org.lwjgl.opengl.GL14.GL_FUNC_ADD +import org.lwjgl.opengl.GL14.GL_MIN +import org.lwjgl.opengl.GL14.glBlendColor +import ru.dbotthepony.mc.otm.block.entity.matter.MatterReplicatorBlockEntity +import ru.dbotthepony.mc.otm.client.minecraft +import ru.dbotthepony.mc.otm.client.render.lockBlendFunc +import ru.dbotthepony.mc.otm.client.render.popScissorRect +import ru.dbotthepony.mc.otm.client.render.pushScissorRect +import ru.dbotthepony.mc.otm.client.screen.widget.PowerGaugePanel +import ru.dbotthepony.mc.otm.core.normalizeAngleDeg + +class MatterReplicatorRenderer(private val context: BlockEntityRendererProvider.Context) : BlockEntityRenderer { + override fun render( + tile: MatterReplicatorBlockEntity, + partialTick: Float, + pose: PoseStack, + bufferSource: MultiBufferSource, + packedLight: Int, + packedOverlay: Int + ) { + val item = tile.visualItemStack + + if (item.isEmpty) { + return + } + + pose.pushPose() + + pose.translate(0.5, 0.3, 0.5) + pose.scale(0.3f, 0.3f, 0.3f) + + val diff = System.nanoTime() - tile.lastRender + tile.lastRender = System.nanoTime() + + tile.renderRotation = normalizeAngleDeg(tile.renderRotation + diff / 10_000_000f) + pose.mulPose(Vector3f.YP.rotationDegrees(tile.renderRotation)) + + val model = context.itemRenderer.getModel( + item, + tile.level, + null, + 0 + ) + + val source = minecraft.renderBuffers().bufferSource() + + source.endBatch() + + context.itemRenderer.render( + item, + ItemTransforms.TransformType.NONE, + false, + pose, + source, + packedLight, + packedOverlay, + model + ) + + glBlendColor(1f, 1f, 1f, 1f - tile.visualProgress) + + RenderSystem.enableBlend() + RenderSystem.blendFuncSeparate( + SourceFactor.ONE_MINUS_CONSTANT_ALPHA, + DestFactor.CONSTANT_ALPHA, + SourceFactor.ZERO, + DestFactor.ONE + ) + + lockBlendFunc = true + + try { + source.endBatch() + } finally { + lockBlendFunc = false + } + + RenderSystem.defaultBlendFunc() + glBlendColor(0f, 0f, 0f, 0f) + + pose.popPose() + } +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/EuclidMath.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/EuclidMath.kt index f17d5bb1d..c6ead3df0 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/EuclidMath.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/EuclidMath.kt @@ -495,3 +495,31 @@ fun normalizeAngle(angle: Float): Float { fun angleDifference(angle1: Float, angle2: Float): Float { return angleDifference(angle1.toDouble(), angle2.toDouble()).toFloat() } + +fun normalizeAngleDeg(angle: Double): Double { + return (angle + 180.0) % 360.0 - 180.0 +} + +fun normalizeAngleDeg(angle: Float): Float { + return (angle + 180f) % 360f - 180f +} + +fun angleDifferenceDeg(angle1: Double, angle2: Double): Double { + val diff = normalizeAngle(angle1 - angle2) + + if (diff < 180.0) { + return diff + } + + return 360.0 - diff +} + +fun angleDifferenceDeg(angle1: Float, angle2: Float): Float { + val diff = normalizeAngle(angle1 - angle2) + + if (diff < 180f) { + return diff + } + + return 360f - diff +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlockEntities.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlockEntities.kt index 06ff7984e..047198565 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlockEntities.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlockEntities.kt @@ -18,7 +18,9 @@ import ru.dbotthepony.mc.otm.client.render.blockentity.BlackHoleRenderer import ru.dbotthepony.mc.otm.client.render.blockentity.EnergyCounterRenderer import ru.dbotthepony.mc.otm.client.render.blockentity.GravitationStabilizerRenderer import ru.dbotthepony.mc.otm.client.render.blockentity.MatterBatteryBankRenderer +import ru.dbotthepony.mc.otm.client.render.blockentity.MatterReplicatorRenderer +@Suppress("NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS") // Type<*> is unused in BlockEntityType.Builder object MBlockEntities { private val registry = DeferredRegister.create(ForgeRegistries.BLOCK_ENTITY_TYPES, OverdriveThatMatters.MOD_ID) @@ -69,6 +71,7 @@ object MBlockEntities { BlockEntityRenderers.register(ENERGY_COUNTER as BlockEntityType, ::EnergyCounterRenderer) BlockEntityRenderers.register(BATTERY_BANK as BlockEntityType, ::BatteryBankRenderer) BlockEntityRenderers.register(MATTER_CAPACITOR_BANK as BlockEntityType, ::MatterBatteryBankRenderer) + BlockEntityRenderers.register(MATTER_REPLICATOR as BlockEntityType, ::MatterReplicatorRenderer) } } } diff --git a/src/main/resources/coremods/code_injector.js b/src/main/resources/coremods/code_injector.js index a091fa940..1f93f6a08 100644 --- a/src/main/resources/coremods/code_injector.js +++ b/src/main/resources/coremods/code_injector.js @@ -502,8 +502,94 @@ function injectInventoryInsertHook( instructions.insert(last, next) } +function patchBlendFunc(node) { + var last = new MethodInsnNode( + opcodesRemapped.invokestatic, + 'ru/dbotthepony/mc/otm/client/render/RenderHelperKt', + 'getLockBlendFunc', + '()Z', + false + ) + + var label = new Label() + var labelNode = new LabelNode(label) + + node.instructions.insert(last) + node.instructions.insert(last, labelNode) + + var next = new JumpInsnNode(opcodesRemapped.ifeq, labelNode) + node.instructions.insert(last, next) + last = next + + next = new InsnNode(opcodesRemapped['return']) + node.instructions.insert(last, next) + last = next + + return node +} + function initializeCoreMod() { return { + 'blend func lock 1': { + 'target': { + 'type': 'METHOD', + 'class': 'com.mojang.blaze3d.systems.RenderSystem', + 'methodName': ASMAPI.mapMethod('m_69478_'), // enableBlend + 'methodDesc': '()V' + }, + 'transformer': patchBlendFunc + }, + + 'blend func lock 2': { + 'target': { + 'type': 'METHOD', + 'class': 'com.mojang.blaze3d.systems.RenderSystem', + 'methodName': ASMAPI.mapMethod('m_69461_'), // disableBlend + 'methodDesc': '()V' + }, + 'transformer': patchBlendFunc + }, + + 'blend func lock 3': { + 'target': { + 'type': 'METHOD', + 'class': 'com.mojang.blaze3d.systems.RenderSystem', + 'methodName': ASMAPI.mapMethod('m_69405_'), // blendFunc + 'methodDesc': '(II)V' + }, + 'transformer': patchBlendFunc + }, + + 'blend func lock 5': { + 'target': { + 'type': 'METHOD', + 'class': 'com.mojang.blaze3d.systems.RenderSystem', + 'methodName': ASMAPI.mapMethod('m_69411_'), // blendFuncSeparate + 'methodDesc': '(IIII)V' + }, + 'transformer': patchBlendFunc + }, + + 'blend func lock 6': { + 'target': { + 'type': 'METHOD', + 'class': 'com.mojang.blaze3d.systems.RenderSystem', + 'methodName': ASMAPI.mapMethod('m_69416_'), // blendFuncSeparate + 'methodDesc': '(Lcom/mojang/blaze3d/platform/GlStateManager$SourceFactor;Lcom/mojang/blaze3d/platform/GlStateManager$DestFactor;Lcom/mojang/blaze3d/platform/GlStateManager$SourceFactor;Lcom/mojang/blaze3d/platform/GlStateManager$DestFactor;)V' + }, + 'transformer': patchBlendFunc + }, + + 'blend func lock 4': { + 'target': { + 'type': 'METHOD', + 'class': 'com.mojang.blaze3d.systems.RenderSystem', + 'methodName': ASMAPI.mapMethod('m_69408_'), // blendFunc + 'methodDesc': '(Lcom/mojang/blaze3d/platform/GlStateManager$SourceFactor;Lcom/mojang/blaze3d/platform/GlStateManager$DestFactor;)V' + }, + 'transformer': patchBlendFunc + }, + 'Inventory#add patch': { 'target': { 'type': 'METHOD',