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()
|
||||
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
|
||||
|
||||
@ -266,13 +271,6 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat
|
||||
thisTick = Decimal.ZERO
|
||||
}
|
||||
|
||||
fun clientTick() {
|
||||
// TODO
|
||||
// historyTick = (historyTick + 1) % history.size
|
||||
// history[historyTick] = lastTick
|
||||
// passed += lastTick
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val MACHINE_NAME = TranslatableComponent("block.overdrive_that_matters.energy_counter")
|
||||
const val PASSED_ENERGY_KEY = "passedEnergy"
|
||||
|
@ -46,12 +46,9 @@ class EnergyCounterBlock(val color: DyeColor?) : MatteryBlock(DEFAULT_MACHINE_PR
|
||||
blockState: BlockState,
|
||||
blockEntityType: BlockEntityType<T>
|
||||
): BlockEntityTicker<T>? {
|
||||
if (blockEntityType !== MBlockEntities.ENERGY_COUNTER)
|
||||
if (blockEntityType !== MBlockEntities.ENERGY_COUNTER || level.isClientSide)
|
||||
return null
|
||||
|
||||
if (level.isClientSide)
|
||||
return BlockEntityTicker { _, _, _, tile -> if (tile is EnergyCounterBlockEntity) tile.clientTick() }
|
||||
|
||||
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.DefaultVertexFormat
|
||||
import com.mojang.blaze3d.vertex.PoseStack
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer
|
||||
import com.mojang.blaze3d.vertex.VertexFormat
|
||||
import com.mojang.blaze3d.vertex.VertexSorting
|
||||
import net.minecraft.client.gui.Font
|
||||
@ -106,9 +107,35 @@ val CHART_RENDER_TYPE = run {
|
||||
) 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 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(
|
||||
poseStack: PoseStack,
|
||||
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" }
|
||||
val builder = buffer.getBuffer(CHART_RENDER_TYPE)
|
||||
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
|
||||
|
||||
@ -134,20 +163,24 @@ fun renderChart(
|
||||
var drawPointX = 0f
|
||||
var drawPointY = 0f
|
||||
|
||||
val halfWidth = lineWidth / 2f
|
||||
|
||||
if (levelLabels != null) {
|
||||
for ((level, label) in levelLabels.labels) {
|
||||
val y0 = y + (1f - level) * height
|
||||
|
||||
builder.vertex(poseStack, x + width, lineWidth / 2f + y0, 0f).color(levelLabels.lineColor)
|
||||
builder.vertex(poseStack, x + width, -lineWidth / 2f + y0, 0f).color(levelLabels.lineColor)
|
||||
builder.vertex(poseStack, x, -lineWidth / 2f + y0, 0f).color(levelLabels.lineColor)
|
||||
builder.vertex(poseStack, x, lineWidth / 2f + y0, 0f).color(levelLabels.lineColor)
|
||||
builder.vertex(poseStack, x + width, halfWidth + y0, 0f).color(levelLabels.lineColor)
|
||||
builder.vertex(poseStack, x + width, -halfWidth + y0, 0f).color(levelLabels.lineColor)
|
||||
builder.vertex(poseStack, x, -halfWidth + y0, 0f).color(levelLabels.lineColor)
|
||||
builder.vertex(poseStack, x, halfWidth + y0, 0f).color(levelLabels.lineColor)
|
||||
}
|
||||
}
|
||||
|
||||
poseStack.translate(0f, 0f, 0.2f)
|
||||
|
||||
for ((normalized, color) in charts) {
|
||||
var previousAngle = 0f
|
||||
|
||||
for (i in 0 until normalized.size - 1) {
|
||||
val y0 = y + (1f - normalized[i]) * height
|
||||
val y1 = y + (1f - normalized[i + 1]) * height
|
||||
@ -158,17 +191,22 @@ fun renderChart(
|
||||
val xDiff = x1 - x0
|
||||
val yDiff = y1 - y0
|
||||
|
||||
val currentAngle: Float
|
||||
|
||||
if (yDiff.sign == 0f) {
|
||||
builder.vertex(poseStack, x0, y0 + lineWidth / 2f, 0f).color(color)
|
||||
builder.vertex(poseStack, x0, y0 - lineWidth / 2f, 0f).color(color)
|
||||
builder.vertex(poseStack, x1, y1 - lineWidth / 2f, 0f).color(color)
|
||||
builder.vertex(poseStack, x1, y1 + lineWidth / 2f, 0f).color(color)
|
||||
builder.vertex(poseStack, x0, y0 + halfWidth, 0f).color(color)
|
||||
builder.vertex(poseStack, x0, y0 - halfWidth, 0f).color(color)
|
||||
builder.vertex(poseStack, x1, y1 - halfWidth, 0f).color(color)
|
||||
builder.vertex(poseStack, x1, y1 + halfWidth, 0f).color(color)
|
||||
|
||||
currentAngle = PI.toFloat() / 2f
|
||||
} else {
|
||||
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 yDisp = sin(angle).toFloat() * lineWidth / 2f
|
||||
val xDisp = cos(angle) * halfWidth
|
||||
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)
|
||||
@ -176,7 +214,60 @@ fun renderChart(
|
||||
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) {
|
||||
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()) {
|
||||
poseStack.translate(0f, 0f, 0.2f)
|
||||
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(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, false), ImmutableList.of(next.type), immutableAfter = true, chained = true)
|
||||
@ -250,13 +251,7 @@ class DynamicBufferSource(
|
||||
}
|
||||
|
||||
override fun getBuffer(renderType: RenderType): VertexConsumer {
|
||||
var getState = buffers[renderType]
|
||||
|
||||
if (getState == null) {
|
||||
getState = State(renderType)
|
||||
}
|
||||
|
||||
return getState.begin()
|
||||
return (buffers[renderType] ?: State(renderType)).begin()
|
||||
}
|
||||
|
||||
fun getBuffer(renderType: RenderType, after: RenderType): VertexConsumer {
|
||||
|
Loading…
Reference in New Issue
Block a user