Chart smooth bends
This commit is contained in:
parent
d0e6ab2829
commit
1c3fc4e6e6
@ -55,7 +55,12 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat
|
|||||||
var lastTick by syncher.decimal()
|
var lastTick by syncher.decimal()
|
||||||
internal set
|
internal set
|
||||||
|
|
||||||
var displayChartOnBlock by syncher.int(0, setter = DelegateSetter { field, value -> if (value in 0 .. charts.size + 1) field.accept(value) })
|
var displayChartOnBlock by syncher.int(0, setter = DelegateSetter { field, value ->
|
||||||
|
if (value in 0 .. charts.size + 1) {
|
||||||
|
field.accept(value)
|
||||||
|
markDirtyFast()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
var ioLimit: Decimal? = null
|
var ioLimit: Decimal? = null
|
||||||
|
|
||||||
@ -266,13 +271,6 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat
|
|||||||
thisTick = Decimal.ZERO
|
thisTick = Decimal.ZERO
|
||||||
}
|
}
|
||||||
|
|
||||||
fun clientTick() {
|
|
||||||
// TODO
|
|
||||||
// historyTick = (historyTick + 1) % history.size
|
|
||||||
// history[historyTick] = lastTick
|
|
||||||
// passed += lastTick
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val MACHINE_NAME = TranslatableComponent("block.overdrive_that_matters.energy_counter")
|
private val MACHINE_NAME = TranslatableComponent("block.overdrive_that_matters.energy_counter")
|
||||||
const val PASSED_ENERGY_KEY = "passedEnergy"
|
const val PASSED_ENERGY_KEY = "passedEnergy"
|
||||||
|
@ -46,12 +46,9 @@ class EnergyCounterBlock(val color: DyeColor?) : MatteryBlock(DEFAULT_MACHINE_PR
|
|||||||
blockState: BlockState,
|
blockState: BlockState,
|
||||||
blockEntityType: BlockEntityType<T>
|
blockEntityType: BlockEntityType<T>
|
||||||
): BlockEntityTicker<T>? {
|
): BlockEntityTicker<T>? {
|
||||||
if (blockEntityType !== MBlockEntities.ENERGY_COUNTER)
|
if (blockEntityType !== MBlockEntities.ENERGY_COUNTER || level.isClientSide)
|
||||||
return null
|
return null
|
||||||
|
|
||||||
if (level.isClientSide)
|
|
||||||
return BlockEntityTicker { _, _, _, tile -> if (tile is EnergyCounterBlockEntity) tile.clientTick() }
|
|
||||||
|
|
||||||
return BlockEntityTicker { _, _, _, tile -> if (tile is EnergyCounterBlockEntity) tile.tick() }
|
return BlockEntityTicker { _, _, _, tile -> if (tile is EnergyCounterBlockEntity) tile.tick() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import com.mojang.blaze3d.systems.RenderSystem
|
|||||||
import com.mojang.blaze3d.vertex.ByteBufferBuilder
|
import com.mojang.blaze3d.vertex.ByteBufferBuilder
|
||||||
import com.mojang.blaze3d.vertex.DefaultVertexFormat
|
import com.mojang.blaze3d.vertex.DefaultVertexFormat
|
||||||
import com.mojang.blaze3d.vertex.PoseStack
|
import com.mojang.blaze3d.vertex.PoseStack
|
||||||
|
import com.mojang.blaze3d.vertex.VertexConsumer
|
||||||
import com.mojang.blaze3d.vertex.VertexFormat
|
import com.mojang.blaze3d.vertex.VertexFormat
|
||||||
import com.mojang.blaze3d.vertex.VertexSorting
|
import com.mojang.blaze3d.vertex.VertexSorting
|
||||||
import net.minecraft.client.gui.Font
|
import net.minecraft.client.gui.Font
|
||||||
@ -106,9 +107,35 @@ val CHART_RENDER_TYPE = run {
|
|||||||
) as RenderType
|
) as RenderType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val CHART_RENDER_TYPE2 = run {
|
||||||
|
val builder = RenderType.CompositeState.builder()
|
||||||
|
|
||||||
|
builder.setShaderState(RenderStateShard.ShaderStateShard(GameRenderer::getPositionColorShader))
|
||||||
|
builder.setDepthTestState(RenderStateShard.DepthTestStateShard("always", GL_LESS))
|
||||||
|
|
||||||
|
builder.setTransparencyState(RenderStateShard.TransparencyStateShard("normal_blend", {
|
||||||
|
RenderSystem.enableBlend()
|
||||||
|
RenderSystem.defaultBlendFunc()
|
||||||
|
}, { RenderSystem.disableBlend() }))
|
||||||
|
|
||||||
|
@Suppress("INACCESSIBLE_TYPE")
|
||||||
|
RenderType.create(
|
||||||
|
"otm_chart2",
|
||||||
|
DefaultVertexFormat.POSITION_COLOR,
|
||||||
|
VertexFormat.Mode.TRIANGLES,
|
||||||
|
16_000,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
builder.createCompositeState(false)
|
||||||
|
) as RenderType
|
||||||
|
}
|
||||||
|
|
||||||
private val buffer = DynamicBufferSource(vertexSorting = VertexSorting.ORTHOGRAPHIC_Z)
|
private val buffer = DynamicBufferSource(vertexSorting = VertexSorting.ORTHOGRAPHIC_Z)
|
||||||
private fun buffer() = buffer
|
private fun buffer() = buffer
|
||||||
|
|
||||||
|
private val sinValues = FloatArray(16) { sin(it / 16f * PI.toFloat() * 2f) }
|
||||||
|
private val cosValues = FloatArray(16) { cos(it / 16f * PI.toFloat() * 2f) }
|
||||||
|
|
||||||
fun renderChart(
|
fun renderChart(
|
||||||
poseStack: PoseStack,
|
poseStack: PoseStack,
|
||||||
charts: List<Pair<FloatArray, RGBAColor>>,
|
charts: List<Pair<FloatArray, RGBAColor>>,
|
||||||
@ -125,6 +152,8 @@ fun renderChart(
|
|||||||
require(charts.all { it.first.size == charts[0].first.size }) { "Provided chart data is not of same width" }
|
require(charts.all { it.first.size == charts[0].first.size }) { "Provided chart data is not of same width" }
|
||||||
val builder = buffer.getBuffer(CHART_RENDER_TYPE)
|
val builder = buffer.getBuffer(CHART_RENDER_TYPE)
|
||||||
val step = width / charts[0].first.size
|
val step = width / charts[0].first.size
|
||||||
|
// so we can work with crumbling buffer sources
|
||||||
|
val bendFuncs = ArrayList<VertexConsumer.() -> Unit>()
|
||||||
|
|
||||||
val checkLabels = labels != null && labels.mouseY in 0f .. height && labels.mouseX in 0f .. width
|
val checkLabels = labels != null && labels.mouseY in 0f .. height && labels.mouseX in 0f .. width
|
||||||
|
|
||||||
@ -134,20 +163,24 @@ fun renderChart(
|
|||||||
var drawPointX = 0f
|
var drawPointX = 0f
|
||||||
var drawPointY = 0f
|
var drawPointY = 0f
|
||||||
|
|
||||||
|
val halfWidth = lineWidth / 2f
|
||||||
|
|
||||||
if (levelLabels != null) {
|
if (levelLabels != null) {
|
||||||
for ((level, label) in levelLabels.labels) {
|
for ((level, label) in levelLabels.labels) {
|
||||||
val y0 = y + (1f - level) * height
|
val y0 = y + (1f - level) * height
|
||||||
|
|
||||||
builder.vertex(poseStack, x + width, lineWidth / 2f + y0, 0f).color(levelLabels.lineColor)
|
builder.vertex(poseStack, x + width, halfWidth + y0, 0f).color(levelLabels.lineColor)
|
||||||
builder.vertex(poseStack, x + width, -lineWidth / 2f + y0, 0f).color(levelLabels.lineColor)
|
builder.vertex(poseStack, x + width, -halfWidth + y0, 0f).color(levelLabels.lineColor)
|
||||||
builder.vertex(poseStack, x, -lineWidth / 2f + y0, 0f).color(levelLabels.lineColor)
|
builder.vertex(poseStack, x, -halfWidth + y0, 0f).color(levelLabels.lineColor)
|
||||||
builder.vertex(poseStack, x, lineWidth / 2f + y0, 0f).color(levelLabels.lineColor)
|
builder.vertex(poseStack, x, halfWidth + y0, 0f).color(levelLabels.lineColor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
poseStack.translate(0f, 0f, 0.2f)
|
poseStack.translate(0f, 0f, 0.2f)
|
||||||
|
|
||||||
for ((normalized, color) in charts) {
|
for ((normalized, color) in charts) {
|
||||||
|
var previousAngle = 0f
|
||||||
|
|
||||||
for (i in 0 until normalized.size - 1) {
|
for (i in 0 until normalized.size - 1) {
|
||||||
val y0 = y + (1f - normalized[i]) * height
|
val y0 = y + (1f - normalized[i]) * height
|
||||||
val y1 = y + (1f - normalized[i + 1]) * height
|
val y1 = y + (1f - normalized[i + 1]) * height
|
||||||
@ -158,17 +191,22 @@ fun renderChart(
|
|||||||
val xDiff = x1 - x0
|
val xDiff = x1 - x0
|
||||||
val yDiff = y1 - y0
|
val yDiff = y1 - y0
|
||||||
|
|
||||||
|
val currentAngle: Float
|
||||||
|
|
||||||
if (yDiff.sign == 0f) {
|
if (yDiff.sign == 0f) {
|
||||||
builder.vertex(poseStack, x0, y0 + lineWidth / 2f, 0f).color(color)
|
builder.vertex(poseStack, x0, y0 + halfWidth, 0f).color(color)
|
||||||
builder.vertex(poseStack, x0, y0 - lineWidth / 2f, 0f).color(color)
|
builder.vertex(poseStack, x0, y0 - halfWidth, 0f).color(color)
|
||||||
builder.vertex(poseStack, x1, y1 - lineWidth / 2f, 0f).color(color)
|
builder.vertex(poseStack, x1, y1 - halfWidth, 0f).color(color)
|
||||||
builder.vertex(poseStack, x1, y1 + lineWidth / 2f, 0f).color(color)
|
builder.vertex(poseStack, x1, y1 + halfWidth, 0f).color(color)
|
||||||
|
|
||||||
|
currentAngle = PI.toFloat() / 2f
|
||||||
} else {
|
} else {
|
||||||
val length = (xDiff.pow(2f) + yDiff.pow(2f)).pow(0.5f)
|
val length = (xDiff.pow(2f) + yDiff.pow(2f)).pow(0.5f)
|
||||||
val angle = acos(xDiff / length) * yDiff.sign - PI / 2f // rotate 90 deg
|
val angle = acos(xDiff / length) * yDiff.sign - PI.toFloat() / 2f // rotate 90 deg
|
||||||
|
currentAngle = angle
|
||||||
|
|
||||||
val xDisp = cos(angle).toFloat() * lineWidth / 2f
|
val xDisp = cos(angle) * halfWidth
|
||||||
val yDisp = sin(angle).toFloat() * lineWidth / 2f
|
val yDisp = sin(angle) * halfWidth
|
||||||
|
|
||||||
builder.vertex(poseStack, x0 + xDisp, y0 + yDisp, 0f).color(color)
|
builder.vertex(poseStack, x0 + xDisp, y0 + yDisp, 0f).color(color)
|
||||||
builder.vertex(poseStack, x0 - xDisp, y0 - yDisp, 0f).color(color)
|
builder.vertex(poseStack, x0 - xDisp, y0 - yDisp, 0f).color(color)
|
||||||
@ -176,7 +214,60 @@ fun renderChart(
|
|||||||
builder.vertex(poseStack, x1 + xDisp, y1 + yDisp, 0f).color(color)
|
builder.vertex(poseStack, x1 + xDisp, y1 + yDisp, 0f).color(color)
|
||||||
}
|
}
|
||||||
|
|
||||||
//graphics.renderRect(x0, y0, LINE_WIDTH, LINE_WIDTH)
|
if (currentAngle != previousAngle) {
|
||||||
|
for (i2 in sinValues.indices) {
|
||||||
|
val i3 = (i2 + 1) % cosValues.size
|
||||||
|
val cos0 = cosValues[i2] * halfWidth
|
||||||
|
val cos1 = cosValues[i3] * halfWidth
|
||||||
|
val sin0 = sinValues[i2] * halfWidth
|
||||||
|
val sin1 = sinValues[i3] * halfWidth
|
||||||
|
|
||||||
|
bendFuncs.add {
|
||||||
|
vertex(poseStack, x0 + cos0, y0 + sin0, 0f).color(color)
|
||||||
|
vertex(poseStack, x0, y0, 0f).color(color)
|
||||||
|
vertex(poseStack, x0 + cos1, y0 + sin1, 0f).color(color)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: actually make this work, because this should be more efficient than drawing full circle
|
||||||
|
/*
|
||||||
|
if (previousAngle < currentAngle) {
|
||||||
|
// peak bend
|
||||||
|
var bendAngle = previousAngle - 0.05f
|
||||||
|
|
||||||
|
while (bendAngle < currentAngle + 0.05f) {
|
||||||
|
val sin0 = sin(bendAngle)
|
||||||
|
val cos0 = cos(bendAngle)
|
||||||
|
val sin1 = sin(bendAngle + 0.05f)
|
||||||
|
val cos1 = cos(bendAngle + 0.05f)
|
||||||
|
|
||||||
|
builder2.vertex(poseStack, x0 + cos0, y0 + sin0, 0f).color(color)
|
||||||
|
builder2.vertex(poseStack, x0, y0, 0f).color(color)
|
||||||
|
builder2.vertex(poseStack, x0 + cos1, y0 + sin1, 0f).color(color)
|
||||||
|
|
||||||
|
bendAngle += 0.05f
|
||||||
|
}
|
||||||
|
} else if (previousAngle > currentAngle) {
|
||||||
|
// chasm bend
|
||||||
|
var bendAngle = currentAngle - 0.05f
|
||||||
|
|
||||||
|
while (bendAngle < previousAngle + 0.05f) {
|
||||||
|
val sin0 = sin(bendAngle)
|
||||||
|
val cos0 = cos(bendAngle)
|
||||||
|
val sin1 = sin(bendAngle + 0.05f)
|
||||||
|
val cos1 = cos(bendAngle + 0.05f)
|
||||||
|
|
||||||
|
builder2.vertex(poseStack, x0 + cos0, y0 + sin0, 0f).color(color)
|
||||||
|
builder2.vertex(poseStack, x0, y0, 0f).color(color)
|
||||||
|
builder2.vertex(poseStack, x0 + cos1, y0 + sin1, 0f).color(color)
|
||||||
|
|
||||||
|
bendAngle += 0.05f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
previousAngle = currentAngle
|
||||||
|
|
||||||
if (checkLabels && drawLabel == -1 && labels!!.mouseX in x1 .. x0) {
|
if (checkLabels && drawLabel == -1 && labels!!.mouseX in x1 .. x0) {
|
||||||
drawLabel = i
|
drawLabel = i
|
||||||
@ -186,6 +277,11 @@ fun renderChart(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bendFuncs.isNotEmpty()) {
|
||||||
|
val builder2 = buffer.getBuffer(CHART_RENDER_TYPE2)
|
||||||
|
bendFuncs.forEach { it.invoke(builder2) }
|
||||||
|
}
|
||||||
|
|
||||||
if (levelLabels != null && levelLabels.labels.isNotEmpty()) {
|
if (levelLabels != null && levelLabels.labels.isNotEmpty()) {
|
||||||
poseStack.translate(0f, 0f, 0.2f)
|
poseStack.translate(0f, 0f, 0.2f)
|
||||||
val font = levelLabels.font ?: minecraft.font
|
val font = levelLabels.font ?: minecraft.font
|
||||||
|
@ -165,6 +165,7 @@ class DynamicBufferSource(
|
|||||||
|
|
||||||
next = State(Sheets.chestSheet(), ImmutableList.of(next.type), immutableAfter = true, chained = false)
|
next = State(Sheets.chestSheet(), ImmutableList.of(next.type), immutableAfter = true, chained = false)
|
||||||
next = State(CHART_RENDER_TYPE, ImmutableList.of(next.type), immutableAfter = true, chained = true)
|
next = State(CHART_RENDER_TYPE, ImmutableList.of(next.type), immutableAfter = true, chained = true)
|
||||||
|
next = State(CHART_RENDER_TYPE2, ImmutableList.of(next.type), immutableAfter = true, chained = true)
|
||||||
|
|
||||||
next = State(rectRenderType(true, false, true), ImmutableList.of(next.type), immutableAfter = true, chained = true)
|
next = State(rectRenderType(true, false, true), ImmutableList.of(next.type), immutableAfter = true, chained = true)
|
||||||
next = State(rectRenderType(true, false, false), ImmutableList.of(next.type), immutableAfter = true, chained = true)
|
next = State(rectRenderType(true, false, false), ImmutableList.of(next.type), immutableAfter = true, chained = true)
|
||||||
@ -250,13 +251,7 @@ class DynamicBufferSource(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getBuffer(renderType: RenderType): VertexConsumer {
|
override fun getBuffer(renderType: RenderType): VertexConsumer {
|
||||||
var getState = buffers[renderType]
|
return (buffers[renderType] ?: State(renderType)).begin()
|
||||||
|
|
||||||
if (getState == null) {
|
|
||||||
getState = State(renderType)
|
|
||||||
}
|
|
||||||
|
|
||||||
return getState.begin()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getBuffer(renderType: RenderType, after: RenderType): VertexConsumer {
|
fun getBuffer(renderType: RenderType, after: RenderType): VertexConsumer {
|
||||||
|
Loading…
Reference in New Issue
Block a user