Don't calculate uvs of subelements on each access
This commit is contained in:
parent
4de6be0289
commit
bdd0fb28f0
@ -1,17 +1,6 @@
|
||||
package ru.dbotthepony.mc.otm.client.render
|
||||
|
||||
import com.google.gson.JsonDeserializationContext
|
||||
import com.google.gson.JsonDeserializer
|
||||
import com.google.gson.JsonElement
|
||||
import com.google.gson.JsonObject
|
||||
import com.google.gson.JsonPrimitive
|
||||
import com.google.gson.JsonSerializationContext
|
||||
import com.google.gson.JsonSerializer
|
||||
import com.google.gson.JsonSyntaxException
|
||||
import com.google.gson.TypeAdapter
|
||||
import com.google.gson.internal.bind.TypeAdapters
|
||||
import com.google.gson.stream.JsonReader
|
||||
import com.google.gson.stream.JsonWriter
|
||||
import com.mojang.blaze3d.systems.RenderSystem
|
||||
import com.mojang.blaze3d.vertex.PoseStack
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer
|
||||
@ -19,7 +8,7 @@ import net.minecraft.network.FriendlyByteBuf
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import ru.dbotthepony.mc.otm.core.RGBAColor
|
||||
import ru.dbotthepony.mc.otm.core.linearInterpolation
|
||||
import java.lang.reflect.Type
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
sealed class AbstractSkinElement {
|
||||
/**
|
||||
@ -39,6 +28,14 @@ sealed class AbstractSkinElement {
|
||||
abstract val u1: Float
|
||||
abstract val v1: Float
|
||||
|
||||
internal open fun addListener(listener: AbstractSkinElement) {
|
||||
// no-op by default
|
||||
}
|
||||
|
||||
internal open fun parentChanges(parent: AbstractSkinElement) {
|
||||
|
||||
}
|
||||
|
||||
fun partialU(offset: Float): Float {
|
||||
return u0 + (offset / width) * (u1 - u0)
|
||||
}
|
||||
@ -316,4 +313,40 @@ sealed class AbstractSkinElement {
|
||||
fun toNetwork(buff: FriendlyByteBuf) {
|
||||
type.toActualNetwork(this, buff)
|
||||
}
|
||||
|
||||
abstract class Mutable : AbstractSkinElement() {
|
||||
private val listeners = ArrayList<WeakReference<AbstractSkinElement>>(0)
|
||||
|
||||
override fun addListener(listener: AbstractSkinElement) {
|
||||
synchronized(listeners) {
|
||||
val iterator = listeners.listIterator()
|
||||
|
||||
for (ref in iterator) {
|
||||
if (ref.get() == null) {
|
||||
iterator.remove()
|
||||
} else if (ref.get() === listener) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
listeners.add(WeakReference(listener))
|
||||
}
|
||||
}
|
||||
|
||||
protected fun notifyListeners() {
|
||||
synchronized(listeners) {
|
||||
val iterator = listeners.listIterator()
|
||||
|
||||
for (ref in iterator) {
|
||||
val value = ref.get()
|
||||
|
||||
if (value == null) {
|
||||
iterator.remove()
|
||||
} else {
|
||||
value.parentChanges(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ class AtlasSkinElement(
|
||||
val spriteWidth: Float = Mth.smallestEncompassingPowerOfTwo(width.toInt()).toFloat(),
|
||||
val spriteHeight: Float = Mth.smallestEncompassingPowerOfTwo(height.toInt()).toFloat(),
|
||||
override val winding: UVWindingOrder = UVWindingOrder.NORMAL,
|
||||
) : AbstractSkinElement() {
|
||||
) : AbstractSkinElement.Mutable() {
|
||||
init {
|
||||
synchronized(keys) {
|
||||
if (keys.add(location)) {
|
||||
@ -33,9 +33,9 @@ class AtlasSkinElement(
|
||||
}
|
||||
|
||||
// optimistic: we should not create a lot of instances of this class
|
||||
synchronized(listeners) {
|
||||
listeners.add(WeakReference(this))
|
||||
val iterator = listeners.listIterator()
|
||||
synchronized(atlasListeners) {
|
||||
atlasListeners.add(WeakReference(this))
|
||||
val iterator = atlasListeners.listIterator()
|
||||
|
||||
for (ref in iterator) {
|
||||
val value = ref.get()
|
||||
@ -78,6 +78,8 @@ class AtlasSkinElement(
|
||||
u1 = get.u1 - (get.u1 - get.u0) * (1f - width / spriteWidth)
|
||||
v1 = get.v1 - (get.v1 - get.v0) * (1f - height / spriteHeight)
|
||||
|
||||
notifyListeners()
|
||||
|
||||
return get
|
||||
}
|
||||
|
||||
@ -120,12 +122,12 @@ class AtlasSkinElement(
|
||||
|
||||
companion object {
|
||||
private val keys = HashSet<ResourceLocation>()
|
||||
private val listeners = ArrayList<WeakReference<AtlasSkinElement>>()
|
||||
private val atlasListeners = ArrayList<WeakReference<AtlasSkinElement>>()
|
||||
val keysStream: Stream<ResourceLocation> get() = keys.stream()
|
||||
|
||||
fun notifyListeners() {
|
||||
synchronized(listeners) {
|
||||
val iterator = listeners.listIterator()
|
||||
synchronized(atlasListeners) {
|
||||
val iterator = atlasListeners.listIterator()
|
||||
|
||||
for (ref in iterator) {
|
||||
val value = ref.get()
|
||||
|
@ -106,8 +106,8 @@ enum class SkinElementType {
|
||||
it["parent"] = value.parent.toJson()
|
||||
it["xOffset"] = JsonPrimitive(value.xOffset)
|
||||
it["yOffset"] = JsonPrimitive(value.yOffset)
|
||||
it["subWidth"] = JsonPrimitive(value.subWidth)
|
||||
it["subHeight"] = JsonPrimitive(value.subHeight)
|
||||
it["subWidth"] = JsonPrimitive(value.width)
|
||||
it["subHeight"] = JsonPrimitive(value.height)
|
||||
}
|
||||
}
|
||||
|
||||
@ -117,8 +117,8 @@ enum class SkinElementType {
|
||||
value.parent.toNetwork(buff)
|
||||
buff.writeFloat(value.xOffset)
|
||||
buff.writeFloat(value.yOffset)
|
||||
buff.writeFloat(value.subWidth)
|
||||
buff.writeFloat(value.subHeight)
|
||||
buff.writeFloat(value.width)
|
||||
buff.writeFloat(value.height)
|
||||
}
|
||||
|
||||
override fun fromNetwork(buff: FriendlyByteBuf): AbstractSkinElement {
|
||||
|
@ -6,24 +6,37 @@ class SubSkinElement(
|
||||
val parent: AbstractSkinElement,
|
||||
val xOffset: Float = 0f,
|
||||
val yOffset: Float = 0f,
|
||||
val subWidth: Float = parent.width,
|
||||
val subHeight: Float = parent.height,
|
||||
override val width: Float = parent.width,
|
||||
override val height: Float = parent.height,
|
||||
private val overrideWinding: UVWindingOrder? = null
|
||||
) : AbstractSkinElement() {
|
||||
override val width: Float
|
||||
get() = subWidth
|
||||
override val height: Float
|
||||
get() = subHeight
|
||||
) : AbstractSkinElement.Mutable() {
|
||||
override var u0: Float = 0f
|
||||
private set
|
||||
override var v0: Float = 0f
|
||||
private set
|
||||
override var u1: Float = 0f
|
||||
private set
|
||||
override var v1: Float = 0f
|
||||
private set
|
||||
|
||||
override val u0: Float
|
||||
get() = parent.u0 + (xOffset / parent.width) * (parent.u1 - parent.u0)
|
||||
override val v0: Float
|
||||
get() = parent.v0 + (yOffset / parent.height) * (parent.v1 - parent.v0)
|
||||
private fun calculateUVs() {
|
||||
u0 = parent.u0 + (xOffset / parent.width) * (parent.u1 - parent.u0)
|
||||
v0 = parent.v0 + (yOffset / parent.height) * (parent.v1 - parent.v0)
|
||||
u1 = parent.u0 + ((xOffset + width) / parent.width) * (parent.u1 - parent.u0)
|
||||
v1 = parent.v0 + ((yOffset + height) / parent.height) * (parent.v1 - parent.v0)
|
||||
|
||||
override val u1: Float
|
||||
get() = parent.u0 + ((xOffset + subWidth) / parent.width) * (parent.u1 - parent.u0)
|
||||
override val v1: Float
|
||||
get() = parent.v0 + ((yOffset + subHeight) / parent.height) * (parent.v1 - parent.v0)
|
||||
notifyListeners()
|
||||
}
|
||||
|
||||
override fun parentChanges(parent: AbstractSkinElement) = calculateUVs()
|
||||
|
||||
init {
|
||||
parent.addListener(this)
|
||||
}
|
||||
|
||||
init {
|
||||
calculateUVs()
|
||||
}
|
||||
|
||||
override val texture: ResourceLocation
|
||||
get() = parent.texture
|
||||
@ -37,10 +50,10 @@ class SubSkinElement(
|
||||
fun copy(
|
||||
xOffset: Float = this.xOffset,
|
||||
yOffset: Float = this.yOffset,
|
||||
subWidth: Float = this.subWidth,
|
||||
subHeight: Float = this.subHeight,
|
||||
width: Float = this.width,
|
||||
height: Float = this.height,
|
||||
overrideWinding: UVWindingOrder? = this.overrideWinding
|
||||
) = SubSkinElement(parent, xOffset, yOffset, subWidth, subHeight, overrideWinding)
|
||||
) = SubSkinElement(parent, xOffset, yOffset, width, height, overrideWinding)
|
||||
}
|
||||
|
||||
fun AbstractSkinElement.subElement(
|
||||
|
Loading…
Reference in New Issue
Block a user