113 lines
5.2 KiB
Kotlin
113 lines
5.2 KiB
Kotlin
package mods.betterfoliage.render.column
|
|
|
|
import mods.betterfoliage.chunk.ChunkOverlayManager
|
|
import mods.betterfoliage.model.HalfBakedSpecialWrapper
|
|
import mods.betterfoliage.model.SpecialRenderModel
|
|
import mods.betterfoliage.render.column.ColumnLayerData.NormalRender
|
|
import mods.betterfoliage.render.column.ColumnLayerData.SpecialRender.BlockType.NONSOLID
|
|
import mods.betterfoliage.render.column.ColumnLayerData.SpecialRender.BlockType.PARALLEL
|
|
import mods.betterfoliage.render.column.ColumnLayerData.SpecialRender.BlockType.PERPENDICULAR
|
|
import mods.betterfoliage.render.column.ColumnLayerData.SpecialRender.QuadrantType.INVISIBLE
|
|
import mods.betterfoliage.render.column.ColumnLayerData.SpecialRender.QuadrantType.LARGE_RADIUS
|
|
import mods.betterfoliage.render.column.ColumnLayerData.SpecialRender.QuadrantType.SMALL_RADIUS
|
|
import mods.betterfoliage.render.column.ColumnLayerData.SpecialRender.QuadrantType.SQUARE
|
|
import mods.betterfoliage.render.lighting.ColumnLighting
|
|
import mods.betterfoliage.render.pipeline.RenderCtxBase
|
|
import net.minecraft.util.Direction.Axis
|
|
|
|
abstract class ColumnModelBase(
|
|
wrapped: SpecialRenderModel
|
|
) : HalfBakedSpecialWrapper(wrapped) {
|
|
|
|
abstract val enabled: Boolean
|
|
abstract val overlayLayer: ColumnRenderLayer
|
|
abstract val connectPerpendicular: Boolean
|
|
abstract fun getMeshSet(axis: Axis, quadrant: Int): ColumnMeshSet
|
|
|
|
override fun render(ctx: RenderCtxBase, noDecorations: Boolean) {
|
|
if (!enabled) return super.render(ctx, noDecorations)
|
|
|
|
val roundLog = ChunkOverlayManager.get(overlayLayer, ctx)
|
|
when(roundLog) {
|
|
ColumnLayerData.SkipRender -> return
|
|
NormalRender -> return super.render(ctx, noDecorations)
|
|
ColumnLayerData.ResolveError, null -> {
|
|
return super.render(ctx, noDecorations)
|
|
}
|
|
}
|
|
|
|
// if log axis is not defined and "Default to vertical" config option is not set, render normally
|
|
if ((roundLog as ColumnLayerData.SpecialRender).column.axis == null && !overlayLayer.defaultToY) {
|
|
return super.render(ctx, noDecorations)
|
|
}
|
|
|
|
ctx.vertexLighter = ColumnLighting
|
|
|
|
val axis = roundLog.column.axis ?: Axis.Y
|
|
val baseRotation = ColumnMeshSet.baseRotation(axis)
|
|
ColumnMeshSet.quadrantRotations.forEachIndexed { idx, quadrantRotation ->
|
|
// set rotation for the current quadrant
|
|
val rotation = baseRotation + quadrantRotation
|
|
val meshSet = getMeshSet(axis, idx)
|
|
|
|
// disallow sharp discontinuities in the chamfer radius, or tapering-in where inappropriate
|
|
if (roundLog.quadrants[idx] == LARGE_RADIUS &&
|
|
roundLog.upType == PARALLEL && roundLog.quadrantsTop[idx] != LARGE_RADIUS &&
|
|
roundLog.downType == PARALLEL && roundLog.quadrantsBottom[idx] != LARGE_RADIUS) {
|
|
roundLog.quadrants[idx] = SMALL_RADIUS
|
|
}
|
|
|
|
// select meshes for current quadrant based on connectivity rules
|
|
val sideMesh = when (roundLog.quadrants[idx]) {
|
|
SMALL_RADIUS -> meshSet.sideRoundSmall[idx]
|
|
LARGE_RADIUS -> if (roundLog.upType == PARALLEL && roundLog.quadrantsTop[idx] == SMALL_RADIUS) meshSet.transitionTop[idx]
|
|
else if (roundLog.downType == PARALLEL && roundLog.quadrantsBottom[idx] == SMALL_RADIUS) meshSet.transitionBottom[idx]
|
|
else meshSet.sideRoundLarge[idx]
|
|
SQUARE -> meshSet.sideSquare[idx]
|
|
else -> null
|
|
}
|
|
|
|
val upMesh = when(roundLog.upType) {
|
|
NONSOLID -> meshSet.flatTop(roundLog.quadrants, idx)
|
|
PERPENDICULAR -> {
|
|
if (!connectPerpendicular) {
|
|
meshSet.flatTop(roundLog.quadrants, idx)
|
|
} else {
|
|
meshSet.extendTop(roundLog.quadrants, idx)
|
|
}
|
|
}
|
|
PARALLEL -> {
|
|
if (roundLog.quadrants[idx] discontinuousWith roundLog.quadrantsTop[idx] &&
|
|
roundLog.quadrants[idx].let { it == SQUARE || it == INVISIBLE } )
|
|
meshSet.flatTop(roundLog.quadrants, idx)
|
|
else null
|
|
}
|
|
else -> null
|
|
}
|
|
|
|
val downMesh = when(roundLog.downType) {
|
|
NONSOLID -> meshSet.flatBottom(roundLog.quadrants, idx)
|
|
PERPENDICULAR -> {
|
|
if (!connectPerpendicular) {
|
|
meshSet.flatBottom(roundLog.quadrants, idx)
|
|
} else {
|
|
meshSet.extendBottom(roundLog.quadrants, idx)
|
|
}
|
|
}
|
|
PARALLEL -> {
|
|
if (roundLog.quadrants[idx] discontinuousWith roundLog.quadrantsBottom[idx] &&
|
|
roundLog.quadrants[idx].let { it == SQUARE || it == INVISIBLE } )
|
|
meshSet.flatBottom(roundLog.quadrants, idx)
|
|
else null
|
|
}
|
|
else -> null
|
|
}
|
|
|
|
// render
|
|
sideMesh?.let { ctx.renderQuads(it) }
|
|
upMesh?.let { ctx.renderQuads(it) }
|
|
downMesh?.let { ctx.renderQuads(it) }
|
|
}
|
|
|
|
}
|
|
} |