Skip to content
Draft
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions src/main/java/me/owdding/catharsis/mixins/ModelManagerMixin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package me.owdding.catharsis.mixins;

import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import me.owdding.catharsis.features.models.BedrockModels;
import net.minecraft.client.resources.model.ModelManager;
import net.minecraft.server.packs.resources.PreparableReloadListener;
import org.spongepowered.asm.mixin.Mixin;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;

@Mixin(ModelManager.class)
public class ModelManagerMixin {

@WrapMethod(method = "reload")
public CompletableFuture<Void> reload(
PreparableReloadListener.SharedState sharedState,
Executor executor,
PreparableReloadListener.PreparationBarrier preparationBarrier,
Executor executor2,
Operation<CompletableFuture<Void>> original
) {
return BedrockModels.INSTANCE.reload(sharedState, executor, preparationBarrier, executor2).thenCompose(i ->
original.call(sharedState, executor, preparationBarrier, executor2)
);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import com.mojang.blaze3d.vertex.PoseStack;
import me.owdding.catharsis.features.armor.models.ArmorModelState;
import me.owdding.catharsis.hooks.armor.LivingEntityRenderStateHook;
import me.owdding.catharsis.utils.geometry.BedrockGeometryRenderer;
import me.owdding.catharsis.utils.geometry.armor.BedrockArmorGeometryRenderer;
import net.minecraft.client.model.HumanoidModel;
import net.minecraft.client.model.Model;
import net.minecraft.client.renderer.RenderType;
Expand Down Expand Up @@ -48,7 +48,7 @@ public class HumanoidArmorModelMixin<S extends HumanoidRenderState, A extends Hu

nodes.order(1).submitCustomGeometry(stack, RenderType.entityCutoutNoCull(renderer.getTexture()), (pose, consumer) -> {
model.setupAnim(state);
BedrockGeometryRenderer.render(renderer.getGeometry(), slot, model, pose, consumer, light, overlay);
BedrockArmorGeometryRenderer.render(renderer.getGeometry(), slot, model, pose, consumer, light, overlay);
});
return false;
}
Expand Down
4 changes: 4 additions & 0 deletions src/main/kotlin/me/owdding/catharsis/Catharsis.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ package me.owdding.catharsis
import me.owdding.catharsis.events.BootstrapConditionalPropertiesEvent
import me.owdding.catharsis.events.BootstrapNumericPropertiesEvent
import me.owdding.catharsis.events.BootstrapSelectPropertiesEvent
import me.owdding.catharsis.generated.CatharsisCodecs
import me.owdding.catharsis.generated.CatharsisModules
import me.owdding.catharsis.utils.CatharsisLogger
import me.owdding.catharsis.utils.geometry.model.UnbakedBedrockBlockStateModel
import me.owdding.ktmodules.Module
import net.fabricmc.api.ClientModInitializer
import net.fabricmc.fabric.api.client.model.loading.v1.CustomUnbakedBlockStateModel
import net.minecraft.client.renderer.item.properties.conditional.ConditionalItemModelProperties
import net.minecraft.client.renderer.item.properties.numeric.RangeSelectItemModelProperties
import net.minecraft.client.renderer.item.properties.select.SelectItemModelProperties
Expand All @@ -24,6 +27,7 @@ object Catharsis : ClientModInitializer, CatharsisLogger by CatharsisLogger.auto
BootstrapConditionalPropertiesEvent(ConditionalItemModelProperties.ID_MAPPER::put).post(SkyBlockAPI.eventBus)
BootstrapNumericPropertiesEvent(RangeSelectItemModelProperties.ID_MAPPER::put).post(SkyBlockAPI.eventBus)
BootstrapSelectPropertiesEvent(SelectItemModelProperties.ID_MAPPER::put).post(SkyBlockAPI.eventBus)
CustomUnbakedBlockStateModel.register(id("geo_model"), CatharsisCodecs.getMapCodec<UnbakedBedrockBlockStateModel>())
}

fun id(@Pattern("[a-z_0-9\\/.-]+") path: String): ResourceLocation = ResourceLocation.fromNamespaceAndPath("catharsis", path)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class SimpleArmorModel(private val state: ArmorModelState) : ArmorModel {

override fun bake(swapper: RegistryContextSwapper?, resources: TypedResourceManager): ArmorModel {
val geometry = resources.getOrLoad(this.model, BedrockGeometry.RESOURCE_PARSER)?.getOrThrow() ?: error("Could not find referenced bedrock geometry $model")
return SimpleArmorModel(ArmorModelState.Bedrock(geometry.bake(), texture))
return SimpleArmorModel(ArmorModelState.Bedrock(geometry.bakeToArmor(), texture))
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ data class BlockStateModelReplacement(
val replacementSelector: BlockReplacementSelector,
): FabricBlockStateModel by original as FabricBlockStateModel, BlockStateModel {
override fun emitQuads(emitter: QuadEmitter, blockView: BlockAndTintGetter, pos: BlockPos, state: BlockState, random: RandomSource, cullTest: Predicate<Direction?>) {
val random = RandomSource.create(pos.asLong())
val random = RandomSource.create(Mth.getSeed(pos))
val replacement = replacementSelector.select(state, pos, random)
val model = replacement?.models[state]
if (model != null) {
Expand All @@ -63,7 +63,7 @@ data class BlockStateModelReplacement(
return super<FabricBlockStateModel>.particleSprite(blockView, pos, state)
}

override fun particleIcon(): TextureAtlasSprite? {
override fun particleIcon(): TextureAtlasSprite {
return original.particleIcon()
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package me.owdding.catharsis.features.models

import com.google.gson.GsonBuilder
import com.google.gson.JsonElement
import me.owdding.catharsis.Catharsis
import me.owdding.catharsis.utils.extensions.mapBothNotNull
import me.owdding.catharsis.utils.geometry.BedrockGeometry
import me.owdding.ktmodules.Module
import net.minecraft.resources.FileToIdConverter
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.packs.resources.ResourceManager
import net.minecraft.server.packs.resources.SimplePreparableReloadListener
import net.minecraft.util.profiling.ProfilerFiller
import tech.thatgravyboat.skyblockapi.utils.json.Json.toDataOrThrow

@Module
object BedrockModels : SimplePreparableReloadListener<Map<ResourceLocation, BedrockGeometry>>() {
private val geoModelConverter = FileToIdConverter("catharsis/geo_models", ".geo.json")
private val logger = Catharsis.featureLogger("BlockReplacements")
private val gson = GsonBuilder().create()

private val models: MutableMap<ResourceLocation, BedrockGeometry> = mutableMapOf()

override fun prepare(
resourceManager: ResourceManager,
profiler: ProfilerFiller,
): Map<ResourceLocation, BedrockGeometry> {
return geoModelConverter.listMatchingResources(resourceManager).mapBothNotNull { (id, resource) ->
geoModelConverter.fileToId(id) to logger.runCatching("Error loading block replacement definition $id") {
resource.openAsReader().use { reader ->
gson.fromJson(reader, JsonElement::class.java).toDataOrThrow(BedrockGeometry.CODEC).first()
}
}
}
}

override fun apply(
loadedModels: Map<ResourceLocation, BedrockGeometry>,
resourceManager: ResourceManager,
profiler: ProfilerFiller,
) {
models.clear()
models.putAll(loadedModels)
}

fun getModel(location: ResourceLocation) = models[location]

init {
// Utils.registerClientReloadListener(Catharsis.id("bedrock_models"), this, ResourceReloaderKeys.BEFORE_VANILLA)
}
}
57 changes: 57 additions & 0 deletions src/main/kotlin/me/owdding/catharsis/utils/DevUtils.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package me.owdding.catharsis.utils

import me.owdding.catharsis.Catharsis
import me.owdding.catharsis.utils.extensions.sendWithPrefix
import me.owdding.ktmodules.Module
import net.minecraft.network.chat.MutableComponent
import net.minecraft.resources.ResourceLocation
import tech.thatgravyboat.skyblockapi.api.events.base.Subscription
import tech.thatgravyboat.skyblockapi.api.events.misc.RegisterCommandsEvent
import tech.thatgravyboat.skyblockapi.helpers.McClient
import tech.thatgravyboat.skyblockapi.utils.DebugToggle
import tech.thatgravyboat.skyblockapi.utils.DevUtils
import tech.thatgravyboat.skyblockapi.utils.extentions.parseFormattedInt
import java.util.*
import kotlin.io.path.Path
import kotlin.io.path.notExists
import kotlin.io.path.reader

internal fun debugToggle(path: String, description: String = path): DebugToggle {
return DebugToggle(Catharsis.id(path), description, CatharsisDevUtils)
}
@Module
internal object CatharsisDevUtils : DevUtils() {
override val commandName: String = "sbapi toggle"
Comment thread
meowora marked this conversation as resolved.
Outdated
override fun send(component: MutableComponent) = component.sendWithPrefix()
val properties: Map<String, String> = loadFromProperties()

fun getInt(key: String, default: Int = 0): Int {
return properties[key].parseFormattedInt(default)
}

fun getBoolean(key: String): Boolean {
return properties[key] == "true"
}

private fun loadFromProperties(): Map<String, String> {
val properties = Properties()
val path = System.getProperty("sbapi.property_path")?.let { Path(it) } ?: McClient.config.resolve("catharsis.properties")
if (path.notExists()) return emptyMap()
path.reader(Charsets.UTF_8).use {
properties.load(it)
}
val map = mutableMapOf<String, String>()
properties.forEach { (key, value) ->
ResourceLocation.tryBySeparator(key.toString(), '@')?.let {
if (value.toString() == "true") {
states[it] = true
}
}
map[key.toString()] = value.toString()
}
return map
}

@Subscription
fun commandRegister(event: RegisterCommandsEvent) = super.onCommandRegister(event)
}
17 changes: 7 additions & 10 deletions src/main/kotlin/me/owdding/catharsis/utils/Utils.kt
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
package me.owdding.catharsis.utils

import net.fabricmc.fabric.api.resource.IdentifiableResourceReloadListener
import net.fabricmc.fabric.api.resource.ResourceManagerHelper
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.packs.PackType
import net.minecraft.server.packs.resources.PreparableReloadListener
import net.minecraft.server.packs.resources.ResourceManager
import java.util.concurrent.CompletableFuture
import java.util.concurrent.Executor


//? >= 1.21.9
import net.fabricmc.fabric.api.resource.v1.ResourceLoader
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.packs.PackType
import net.minecraft.server.packs.resources.PreparableReloadListener

object Utils {

Expand Down Expand Up @@ -46,9 +40,12 @@ object Utils {
}
*///?}

fun registerClientReloadListener(id: ResourceLocation, listener: PreparableReloadListener) {
fun registerClientReloadListener(id: ResourceLocation, listener: PreparableReloadListener, second: ResourceLocation? = null) {
//? >= 1.21.9 {
ResourceLoader.get(PackType.CLIENT_RESOURCES).registerReloader(id, listener)
if (second != null) {
ResourceLoader.get(PackType.CLIENT_RESOURCES).addReloaderOrdering(id, second)
}
//?} else {
/*ResourceManagerHelper.get(PackType.CLIENT_RESOURCES).registerReloadListener(ReloadListenerWrapper(id, listener))
*///?}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,4 @@ fun Vector3ic.toVec3() = Vec3(toBlockPos())
fun Vec3.toVector3dc(): Vector3dc = toVector3d()
fun Vec3.toVector3d(): Vector3d = Vector3d(x, y, z)
fun Vector3dc.toVec3() = Vec3(x(), y(), z())
fun Vector3fc.toVec3() = Vec3(x().toDouble(), y().toDouble(), z().toDouble())
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,31 @@ package me.owdding.catharsis.utils.geometry

import com.google.gson.JsonElement
import com.mojang.datafixers.util.Either
import com.mojang.serialization.Codec
import me.owdding.catharsis.generated.CatharsisCodecs
import me.owdding.catharsis.utils.TypedResourceParser
import me.owdding.catharsis.utils.geometry.armor.BedrockGeometryBaker
import me.owdding.ktcodecs.FieldName
import me.owdding.ktcodecs.GenerateCodec
import net.minecraft.core.Direction
import org.joml.Vector3f
import tech.thatgravyboat.skyblockapi.utils.json.Json.toDataOrThrow
import me.owdding.catharsis.utils.geometry.BakedBedrockGeometry as BakedBedrockArmorGeometry

@GenerateCodec
data class BedrockGeometry(
val description: BedrockGeometryDescription,
val bones: List<BedrockBone>,
) {

fun bake(): BakedBedrockGeometry {
fun bakeToArmor(): BakedBedrockArmorGeometry {
return BedrockGeometryBaker.bake(this)
}

companion object {

val RESOURCE_PARSER = TypedResourceParser.of<BedrockGeometry>(BedrockGeometry::parseSingle)
private val CODEC = CatharsisCodecs.getCodec<BedrockGeometry>()
val CODEC: Codec<List<BedrockGeometry>> = CatharsisCodecs.getCodec<BedrockGeometry>()
.listOf()
.fieldOf("minecraft:geometry")
.codec()
Expand All @@ -48,8 +52,8 @@ data class BedrockGeometryDescription(
data class BedrockBone(
val name: String,
val parent: String?,
val pivot: List<Float> = listOf(0f, 0f, 0f),
val rotation: List<Float> = listOf(0f, 0f, 0f),
val pivot: Vector3f = Vector3f(),
val rotation: Vector3f = Vector3f(),
val mirror: Boolean = false,
val inflate: Float = 0f,
// debug, the spec has no mention of what its purpose is
Expand All @@ -64,8 +68,8 @@ data class BedrockBone(
data class BedrockCube(
val origin: List<Float>,
val size: List<Float>,
val rotation: List<Float> = listOf(0f, 0f, 0f),
val pivot: List<Float> = listOf(0f, 0f, 0f),
val pivot: Vector3f = Vector3f(),
val rotation: Vector3f = Vector3f(),
val inflate: Float?,
val mirror: Boolean?,
val uv: Either<List<Float>, Map<Direction, UvFace>>?
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
package me.owdding.catharsis.utils.geometry
package me.owdding.catharsis.utils.geometry.armor

import com.mojang.blaze3d.vertex.PoseStack
import com.mojang.blaze3d.vertex.VertexConsumer
import me.owdding.catharsis.utils.debugToggle
import me.owdding.catharsis.utils.geometry.BakedBedrockBone
import me.owdding.catharsis.utils.geometry.BakedBedrockCube
import me.owdding.catharsis.utils.geometry.BakedBedrockGeometry
import net.minecraft.client.model.HumanoidModel
import net.minecraft.core.Direction
import net.minecraft.util.Mth
import net.minecraft.world.entity.EquipmentSlot
import org.joml.*

private const val DEBUG = false

private const val HEAD_BONE = "head"
private const val BODY_BONE = "body"
private const val RIGHT_ARM_BONE = "right_arm"
Expand All @@ -18,7 +22,8 @@ private const val LEFT_LEG_BONE = "left_leg"
private const val RIGHT_FOOT_BONE = "right_foot"
private const val LEFT_FOOT_BONE = "left_foot"

object BedrockGeometryRenderer {
object BedrockArmorGeometryRenderer {
private val debug by debugToggle("armor_debug", "Enables debug colors :3")

@JvmStatic
fun render(geometry: BakedBedrockGeometry, slot: EquipmentSlot, model: HumanoidModel<*>, pose: PoseStack.Pose, consumer: VertexConsumer, light: Int, overlay: Int) {
Expand Down Expand Up @@ -102,7 +107,7 @@ object BedrockGeometryRenderer {

for (vertex in quad.vertices) {

if (DEBUG) {
if (debug) {
consumer
.addVertex(pose, vertex.position.x / 16f, vertex.position.y / 16f, vertex.position.z / 16f)
.setColor(quad.direction.color())
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package me.owdding.catharsis.utils.geometry
package me.owdding.catharsis.utils.geometry.armor

import me.owdding.catharsis.utils.geometry.*
import net.minecraft.core.Direction
import org.joml.Vector2f
import org.joml.Vector3f
Expand All @@ -21,8 +22,8 @@ object BedrockGeometryBaker {
return BakedBedrockBone(
bone.name,
bone.parent,
Vector3f(bone.pivot[0], bone.pivot[1], bone.pivot[2]),
Vector3f(bone.rotation[0], bone.rotation[1], bone.rotation[2]),
bone.pivot,
bone.rotation,
bone.mirror,
bone.inflate,
bone.cubes.map { bakeCube(bone, it, description) }
Expand Down
Loading