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
|
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.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.systems.RenderSystem
|
||||||
import com.mojang.blaze3d.vertex.PoseStack
|
import com.mojang.blaze3d.vertex.PoseStack
|
||||||
import com.mojang.blaze3d.vertex.VertexConsumer
|
import com.mojang.blaze3d.vertex.VertexConsumer
|
||||||
@ -19,7 +8,7 @@ import net.minecraft.network.FriendlyByteBuf
|
|||||||
import net.minecraft.resources.ResourceLocation
|
import net.minecraft.resources.ResourceLocation
|
||||||
import ru.dbotthepony.mc.otm.core.RGBAColor
|
import ru.dbotthepony.mc.otm.core.RGBAColor
|
||||||
import ru.dbotthepony.mc.otm.core.linearInterpolation
|
import ru.dbotthepony.mc.otm.core.linearInterpolation
|
||||||
import java.lang.reflect.Type
|
import java.lang.ref.WeakReference
|
||||||
|
|
||||||
sealed class AbstractSkinElement {
|
sealed class AbstractSkinElement {
|
||||||
/**
|
/**
|
||||||
@ -39,6 +28,14 @@ sealed class AbstractSkinElement {
|
|||||||
abstract val u1: Float
|
abstract val u1: Float
|
||||||
abstract val v1: 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 {
|
fun partialU(offset: Float): Float {
|
||||||
return u0 + (offset / width) * (u1 - u0)
|
return u0 + (offset / width) * (u1 - u0)
|
||||||
}
|
}
|
||||||
@ -316,4 +313,40 @@ sealed class AbstractSkinElement {
|
|||||||
fun toNetwork(buff: FriendlyByteBuf) {
|
fun toNetwork(buff: FriendlyByteBuf) {
|
||||||
type.toActualNetwork(this, buff)
|
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 spriteWidth: Float = Mth.smallestEncompassingPowerOfTwo(width.toInt()).toFloat(),
|
||||||
val spriteHeight: Float = Mth.smallestEncompassingPowerOfTwo(height.toInt()).toFloat(),
|
val spriteHeight: Float = Mth.smallestEncompassingPowerOfTwo(height.toInt()).toFloat(),
|
||||||
override val winding: UVWindingOrder = UVWindingOrder.NORMAL,
|
override val winding: UVWindingOrder = UVWindingOrder.NORMAL,
|
||||||
) : AbstractSkinElement() {
|
) : AbstractSkinElement.Mutable() {
|
||||||
init {
|
init {
|
||||||
synchronized(keys) {
|
synchronized(keys) {
|
||||||
if (keys.add(location)) {
|
if (keys.add(location)) {
|
||||||
@ -33,9 +33,9 @@ class AtlasSkinElement(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// optimistic: we should not create a lot of instances of this class
|
// optimistic: we should not create a lot of instances of this class
|
||||||
synchronized(listeners) {
|
synchronized(atlasListeners) {
|
||||||
listeners.add(WeakReference(this))
|
atlasListeners.add(WeakReference(this))
|
||||||
val iterator = listeners.listIterator()
|
val iterator = atlasListeners.listIterator()
|
||||||
|
|
||||||
for (ref in iterator) {
|
for (ref in iterator) {
|
||||||
val value = ref.get()
|
val value = ref.get()
|
||||||
@ -78,6 +78,8 @@ class AtlasSkinElement(
|
|||||||
u1 = get.u1 - (get.u1 - get.u0) * (1f - width / spriteWidth)
|
u1 = get.u1 - (get.u1 - get.u0) * (1f - width / spriteWidth)
|
||||||
v1 = get.v1 - (get.v1 - get.v0) * (1f - height / spriteHeight)
|
v1 = get.v1 - (get.v1 - get.v0) * (1f - height / spriteHeight)
|
||||||
|
|
||||||
|
notifyListeners()
|
||||||
|
|
||||||
return get
|
return get
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,12 +122,12 @@ class AtlasSkinElement(
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val keys = HashSet<ResourceLocation>()
|
private val keys = HashSet<ResourceLocation>()
|
||||||
private val listeners = ArrayList<WeakReference<AtlasSkinElement>>()
|
private val atlasListeners = ArrayList<WeakReference<AtlasSkinElement>>()
|
||||||
val keysStream: Stream<ResourceLocation> get() = keys.stream()
|
val keysStream: Stream<ResourceLocation> get() = keys.stream()
|
||||||
|
|
||||||
fun notifyListeners() {
|
fun notifyListeners() {
|
||||||
synchronized(listeners) {
|
synchronized(atlasListeners) {
|
||||||
val iterator = listeners.listIterator()
|
val iterator = atlasListeners.listIterator()
|
||||||
|
|
||||||
for (ref in iterator) {
|
for (ref in iterator) {
|
||||||
val value = ref.get()
|
val value = ref.get()
|
||||||
|
@ -106,8 +106,8 @@ enum class SkinElementType {
|
|||||||
it["parent"] = value.parent.toJson()
|
it["parent"] = value.parent.toJson()
|
||||||
it["xOffset"] = JsonPrimitive(value.xOffset)
|
it["xOffset"] = JsonPrimitive(value.xOffset)
|
||||||
it["yOffset"] = JsonPrimitive(value.yOffset)
|
it["yOffset"] = JsonPrimitive(value.yOffset)
|
||||||
it["subWidth"] = JsonPrimitive(value.subWidth)
|
it["subWidth"] = JsonPrimitive(value.width)
|
||||||
it["subHeight"] = JsonPrimitive(value.subHeight)
|
it["subHeight"] = JsonPrimitive(value.height)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,8 +117,8 @@ enum class SkinElementType {
|
|||||||
value.parent.toNetwork(buff)
|
value.parent.toNetwork(buff)
|
||||||
buff.writeFloat(value.xOffset)
|
buff.writeFloat(value.xOffset)
|
||||||
buff.writeFloat(value.yOffset)
|
buff.writeFloat(value.yOffset)
|
||||||
buff.writeFloat(value.subWidth)
|
buff.writeFloat(value.width)
|
||||||
buff.writeFloat(value.subHeight)
|
buff.writeFloat(value.height)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun fromNetwork(buff: FriendlyByteBuf): AbstractSkinElement {
|
override fun fromNetwork(buff: FriendlyByteBuf): AbstractSkinElement {
|
||||||
|
@ -6,24 +6,37 @@ class SubSkinElement(
|
|||||||
val parent: AbstractSkinElement,
|
val parent: AbstractSkinElement,
|
||||||
val xOffset: Float = 0f,
|
val xOffset: Float = 0f,
|
||||||
val yOffset: Float = 0f,
|
val yOffset: Float = 0f,
|
||||||
val subWidth: Float = parent.width,
|
override val width: Float = parent.width,
|
||||||
val subHeight: Float = parent.height,
|
override val height: Float = parent.height,
|
||||||
private val overrideWinding: UVWindingOrder? = null
|
private val overrideWinding: UVWindingOrder? = null
|
||||||
) : AbstractSkinElement() {
|
) : AbstractSkinElement.Mutable() {
|
||||||
override val width: Float
|
override var u0: Float = 0f
|
||||||
get() = subWidth
|
private set
|
||||||
override val height: Float
|
override var v0: Float = 0f
|
||||||
get() = subHeight
|
private set
|
||||||
|
override var u1: Float = 0f
|
||||||
|
private set
|
||||||
|
override var v1: Float = 0f
|
||||||
|
private set
|
||||||
|
|
||||||
override val u0: Float
|
private fun calculateUVs() {
|
||||||
get() = parent.u0 + (xOffset / parent.width) * (parent.u1 - parent.u0)
|
u0 = parent.u0 + (xOffset / parent.width) * (parent.u1 - parent.u0)
|
||||||
override val v0: Float
|
v0 = parent.v0 + (yOffset / parent.height) * (parent.v1 - parent.v0)
|
||||||
get() = 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
|
notifyListeners()
|
||||||
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)
|
override fun parentChanges(parent: AbstractSkinElement) = calculateUVs()
|
||||||
|
|
||||||
|
init {
|
||||||
|
parent.addListener(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
calculateUVs()
|
||||||
|
}
|
||||||
|
|
||||||
override val texture: ResourceLocation
|
override val texture: ResourceLocation
|
||||||
get() = parent.texture
|
get() = parent.texture
|
||||||
@ -37,10 +50,10 @@ class SubSkinElement(
|
|||||||
fun copy(
|
fun copy(
|
||||||
xOffset: Float = this.xOffset,
|
xOffset: Float = this.xOffset,
|
||||||
yOffset: Float = this.yOffset,
|
yOffset: Float = this.yOffset,
|
||||||
subWidth: Float = this.subWidth,
|
width: Float = this.width,
|
||||||
subHeight: Float = this.subHeight,
|
height: Float = this.height,
|
||||||
overrideWinding: UVWindingOrder? = this.overrideWinding
|
overrideWinding: UVWindingOrder? = this.overrideWinding
|
||||||
) = SubSkinElement(parent, xOffset, yOffset, subWidth, subHeight, overrideWinding)
|
) = SubSkinElement(parent, xOffset, yOffset, width, height, overrideWinding)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun AbstractSkinElement.subElement(
|
fun AbstractSkinElement.subElement(
|
||||||
|
Loading…
Reference in New Issue
Block a user