[WIP] Cactus, netherrack, round logs work
+ lots more cleanup + Optifine x-ray fix
This commit is contained in:
@@ -2,7 +2,8 @@ package mods.betterfoliage.render.lighting
|
||||
|
||||
import mods.betterfoliage.model.HalfBakedQuad
|
||||
import mods.betterfoliage.util.Double3
|
||||
import mods.betterfoliage.util.EPSILON
|
||||
import mods.betterfoliage.util.EPSILON_ONE
|
||||
import mods.betterfoliage.util.EPSILON_ZERO
|
||||
import mods.betterfoliage.util.minBy
|
||||
import net.minecraft.client.renderer.color.BlockColors
|
||||
import net.minecraft.util.Direction
|
||||
@@ -41,6 +42,12 @@ class VanillaQuadLighting {
|
||||
abstract class VanillaVertexLighter {
|
||||
abstract fun updateLightmapAndColor(quad: HalfBakedQuad, lighting: VanillaQuadLighting)
|
||||
|
||||
/**
|
||||
* Update lighting for each vertex with AO values from one of the corners.
|
||||
* Does not calculate missing AO values!
|
||||
* @param quad the quad to shade
|
||||
* @param func selector function from vertex position to directed corner index of desired AO values
|
||||
*/
|
||||
inline fun VanillaQuadLighting.updateWithCornerAo(quad: HalfBakedQuad, func: (Double3)->Int?) {
|
||||
quad.raw.verts.forEachIndexed { idx, vertex ->
|
||||
func(vertex.xyz)?.let {
|
||||
@@ -51,9 +58,13 @@ abstract class VanillaVertexLighter {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Replicates vanilla shading for full blocks. Interpolation for non-full blocks
|
||||
* is not implemented.
|
||||
*/
|
||||
object VanillaFullBlockLighting : VanillaVertexLighter() {
|
||||
override fun updateLightmapAndColor(quad: HalfBakedQuad, lighting: VanillaQuadLighting) {
|
||||
// TODO bounds checking
|
||||
// TODO bounds checking & interpolation
|
||||
val face = quad.raw.face()
|
||||
lighting.calc.fillLightData(face, true)
|
||||
lighting.updateWithCornerAo(quad) { nearestCornerOnFace(it, face) }
|
||||
@@ -62,7 +73,7 @@ object VanillaFullBlockLighting : VanillaVertexLighter() {
|
||||
}
|
||||
}
|
||||
|
||||
object RoundLeafLighting : VanillaVertexLighter() {
|
||||
object RoundLeafLightingPreferUp : VanillaVertexLighter() {
|
||||
override fun updateLightmapAndColor(quad: HalfBakedQuad, lighting: VanillaQuadLighting) {
|
||||
val angles = getAngles45(quad)?.let { normalFaces ->
|
||||
lighting.calc.fillLightData(normalFaces.first)
|
||||
@@ -79,6 +90,28 @@ object RoundLeafLighting : VanillaVertexLighter() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lights vertices with the AO values from the nearest corner on either of
|
||||
* the 2 faces the quad normal points towards.
|
||||
*/
|
||||
object RoundLeafLighting : VanillaVertexLighter() {
|
||||
override fun updateLightmapAndColor(quad: HalfBakedQuad, lighting: VanillaQuadLighting) {
|
||||
val angles = getAngles45(quad)?.let { normalFaces ->
|
||||
lighting.calc.fillLightData(normalFaces.first)
|
||||
lighting.calc.fillLightData(normalFaces.second)
|
||||
lighting.updateWithCornerAo(quad) { vertex ->
|
||||
val cornerUndir = AoSideHelper.getCornerUndir(vertex.x, vertex.y, vertex.z)
|
||||
val preferredFace = normalFaces.minBy { faceDistance(it, vertex) }
|
||||
AoSideHelper.boxCornersDirFromUndir[preferredFace.ordinal][cornerUndir]
|
||||
}
|
||||
lighting.updateBlockTint(quad.baked.tintIndex)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lights vertices with the AO values from the nearest corner on the preferred face.
|
||||
*/
|
||||
class LightingPreferredFace(val face: Direction) : VanillaVertexLighter() {
|
||||
override fun updateLightmapAndColor(quad: HalfBakedQuad, lighting: VanillaQuadLighting) {
|
||||
lighting.calc.fillLightData(face)
|
||||
@@ -87,6 +120,38 @@ class LightingPreferredFace(val face: Direction) : VanillaVertexLighter() {
|
||||
}
|
||||
}
|
||||
|
||||
object ColumnLighting : VanillaVertexLighter() {
|
||||
override fun updateLightmapAndColor(quad: HalfBakedQuad, lighting: VanillaQuadLighting) {
|
||||
// faces pointing in cardinal directions
|
||||
getNormalFace(quad)?.let { face ->
|
||||
lighting.calc.fillLightData(face)
|
||||
lighting.updateWithCornerAo(quad) { nearestCornerOnFace(it, face) }
|
||||
lighting.updateBlockTint(quad.baked.tintIndex)
|
||||
return
|
||||
}
|
||||
// faces pointing at 45deg angles
|
||||
getAngles45(quad)?.let { (face1, face2) ->
|
||||
lighting.calc.fillLightData(face1)
|
||||
lighting.calc.fillLightData(face2)
|
||||
quad.raw.verts.forEachIndexed { idx, vertex ->
|
||||
val cornerUndir = AoSideHelper.getCornerUndir(vertex.xyz.x, vertex.xyz.y, vertex.xyz.z)
|
||||
val cornerDir1 = AoSideHelper.boxCornersDirFromUndir[face1.ordinal][cornerUndir]
|
||||
val cornerDir2 = AoSideHelper.boxCornersDirFromUndir[face2.ordinal][cornerUndir]
|
||||
if (cornerDir1 == null || cornerDir2 == null) return@let
|
||||
val ao1 = lighting.calc.aoData[cornerDir1]
|
||||
val ao2 = lighting.calc.aoData[cornerDir2]
|
||||
lighting.packedLight[idx] = ((ao1.packedLight + ao2.packedLight) shr 1) and 0xFF00FF
|
||||
lighting.colorMultiplier[idx] = (ao1.colorMultiplier + ao2.colorMultiplier) * 0.5f
|
||||
}
|
||||
lighting.updateBlockTint(quad.baked.tintIndex)
|
||||
return
|
||||
}
|
||||
// something is wrong...
|
||||
lighting.updateWithCornerAo(quad) { nearestCornerOnFace(it, quad.raw.face()) }
|
||||
lighting.updateBlockTint(quad.baked.tintIndex)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the directed box corner index for the corner nearest the given vertex,
|
||||
* which is on the given face. May return null if the vertex is closest to
|
||||
@@ -107,9 +172,9 @@ fun getAngles45(quad: HalfBakedQuad): Pair<Direction, Direction>? {
|
||||
val normal = quad.raw.normal
|
||||
// one of the components must be close to zero
|
||||
val zeroAxis = when {
|
||||
abs(normal.x) < EPSILON -> Axis.X
|
||||
abs(normal.y) < EPSILON -> Axis.Y
|
||||
abs(normal.z) < EPSILON -> Axis.Z
|
||||
abs(normal.x) < EPSILON_ZERO -> Axis.X
|
||||
abs(normal.y) < EPSILON_ZERO -> Axis.Y
|
||||
abs(normal.z) < EPSILON_ZERO -> Axis.Z
|
||||
else -> return null
|
||||
}
|
||||
// the other two must be of similar magnitude
|
||||
@@ -118,7 +183,7 @@ fun getAngles45(quad: HalfBakedQuad): Pair<Direction, Direction>? {
|
||||
Axis.Y -> abs(abs(normal.x) - abs(normal.z))
|
||||
Axis.Z -> abs(abs(normal.x) - abs(normal.y))
|
||||
}
|
||||
if (diff > EPSILON) return null
|
||||
if (diff > EPSILON_ZERO) return null
|
||||
return when(zeroAxis) {
|
||||
Axis.X -> Pair(if (normal.y > 0.0f) UP else DOWN, if (normal.z > 0.0f) SOUTH else NORTH)
|
||||
Axis.Y -> Pair(if (normal.x > 0.0f) EAST else WEST, if (normal.z > 0.0f) SOUTH else NORTH)
|
||||
@@ -126,6 +191,18 @@ fun getAngles45(quad: HalfBakedQuad): Pair<Direction, Direction>? {
|
||||
}
|
||||
}
|
||||
|
||||
fun getNormalFace(quad: HalfBakedQuad) = quad.raw.normal.let { normal ->
|
||||
when {
|
||||
normal.x > EPSILON_ONE -> EAST
|
||||
normal.x < -EPSILON_ONE -> WEST
|
||||
normal.y > EPSILON_ONE -> UP
|
||||
normal.y < -EPSILON_ONE -> DOWN
|
||||
normal.z > EPSILON_ONE -> SOUTH
|
||||
normal.z < -EPSILON_ONE -> NORTH
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
fun faceDistance(face: Direction, pos: Double3) = when(face) {
|
||||
WEST -> pos.x; EAST -> 1.0 - pos.x
|
||||
DOWN -> pos.y; UP -> 1.0 - pos.y
|
||||
|
||||
Reference in New Issue
Block a user