Multi-layer rendering support
This commit is contained in:
@@ -1,7 +1,10 @@
|
||||
package mods.betterfoliage.model
|
||||
|
||||
import mods.betterfoliage.chunk.BlockCtx
|
||||
import mods.betterfoliage.render.pipeline.RenderCtxBase
|
||||
import net.minecraft.client.renderer.RenderType
|
||||
import net.minecraft.client.renderer.model.IBakedModel
|
||||
import net.minecraft.client.renderer.model.WeightedBakedModel
|
||||
import net.minecraft.util.WeightedRandom
|
||||
import java.util.Random
|
||||
|
||||
@@ -9,18 +12,46 @@ import java.util.Random
|
||||
* Model that makes use of advanced rendering features.
|
||||
*/
|
||||
interface SpecialRenderModel : IBakedModel {
|
||||
fun render(ctx: RenderCtxBase, noDecorations: Boolean = false)
|
||||
/**
|
||||
* Create custom renderdata object. Called once per block. Result is passed to renderLayer().
|
||||
*/
|
||||
fun prepare(ctx: BlockCtx, random: Random): Any
|
||||
fun renderLayer(ctx: RenderCtxBase, data: Any, layer: RenderType)
|
||||
|
||||
/**
|
||||
* Get the actual model that will be rendered. Useful for container models (like [WeightedBakedModel]).
|
||||
*/
|
||||
fun resolve(random: Random) = this
|
||||
}
|
||||
|
||||
interface SpecialRenderData {
|
||||
fun canRenderInLayer(layer: RenderType) = false
|
||||
}
|
||||
|
||||
class WeightedModelWrapper(
|
||||
val models: List<WeightedModel>, baseModel: SpecialRenderModel
|
||||
): IBakedModel by baseModel, SpecialRenderModel {
|
||||
) : IBakedModel by baseModel, SpecialRenderModel {
|
||||
class WeightedModel(val model: SpecialRenderModel, weight: Int) : WeightedRandom.Item(weight)
|
||||
|
||||
val totalWeight = models.sumBy { it.weight }
|
||||
|
||||
fun getModel(random: Random) = WeightedRandom.getWeightedItem(models, random.nextInt(totalWeight))
|
||||
|
||||
override fun render(ctx: RenderCtxBase, noDecorations: Boolean) {
|
||||
getModel(ctx.random).model.render(ctx, noDecorations)
|
||||
override fun resolve(random: Random) = getModel(random).model.resolve(random)
|
||||
|
||||
override fun prepare(ctx: BlockCtx, random: Random) = getModel(random).model.let { actual ->
|
||||
WeightedRenderData(actual, actual.prepare(ctx, random))
|
||||
}
|
||||
|
||||
override fun renderLayer(ctx: RenderCtxBase, data: Any, layer: RenderType) = when (data) {
|
||||
is WeightedRenderData -> data.model.renderLayer(ctx, data.modelRenderData, layer)
|
||||
else -> getModel(ctx.random).model.renderLayer(ctx, data, layer)
|
||||
}
|
||||
}
|
||||
|
||||
data class WeightedRenderData(
|
||||
val model: SpecialRenderModel,
|
||||
val modelRenderData: Any
|
||||
) : SpecialRenderData {
|
||||
override fun canRenderInLayer(layer: RenderType) = (modelRenderData as? SpecialRenderData)?.canRenderInLayer(layer) ?: false
|
||||
}
|
||||
Reference in New Issue
Block a user