From 0c75b500939b64a66929e3541ad79383c1998587 Mon Sep 17 00:00:00 2001 From: Lukas Date: Thu, 10 Jun 2021 20:30:26 +0200 Subject: [PATCH] hud: improve unit system --- .../rendering/hud/atlas/HUDAtlasElement.kt | 9 ---- .../gui/rendering/hud/atlas/TextureLike.kt | 9 ++++ .../position/HUDElementPositionAnchors.kt | 24 ++++++---- .../hud/elements/primitive/HUDElement.kt | 16 +++---- .../elements/primitive/HUDElementPosition.kt | 42 +++++++++++++++++ .../primitive/HUDElementSerializer.kt | 11 +---- .../hud/elements/primitive/HUDImageElement.kt | 44 ++++++++++-------- .../hud/elements/primitive/HUDTextElement.kt | 46 ------------------- .../hud/elements/text/HUDTextElement.kt | 31 +++++++++++++ .../HUDTextElementAlignments.kt | 2 +- 10 files changed, 133 insertions(+), 101 deletions(-) create mode 100644 src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/primitive/HUDElementPosition.kt delete mode 100644 src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/primitive/HUDTextElement.kt create mode 100644 src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/text/HUDTextElement.kt rename src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/{primitive => text}/HUDTextElementAlignments.kt (94%) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/atlas/HUDAtlasElement.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/atlas/HUDAtlasElement.kt index fffb9969f..9366a1751 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/atlas/HUDAtlasElement.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/atlas/HUDAtlasElement.kt @@ -32,15 +32,6 @@ data class HUDAtlasElement( override val size: Vec2i get() = binding.size - val uvs: Array get() { - return arrayOf( - Vec2(uvStart.x, uvStart.y), - Vec2(uvStart.x, uvEnd.y), - Vec2(uvEnd.x, uvStart.y), - Vec2(uvEnd.x, uvEnd.y), - ) - } - fun postInit() { uvStart = (Vec2(binding.start) + RenderConstants.PIXEL_UV_PIXEL_ADD) * texture.arraySinglePixelFactor uvEnd = Vec2(binding.end) * texture.arraySinglePixelFactor diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/atlas/TextureLike.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/atlas/TextureLike.kt index 88f447808..ec8d6d7c6 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/atlas/TextureLike.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/atlas/TextureLike.kt @@ -22,4 +22,13 @@ interface TextureLike { val uvStart: Vec2 val uvEnd: Vec2 val size: Vec2i + + val uvs: Array get() { + return arrayOf( + Vec2(uvStart.x, uvStart.y), + Vec2(uvStart.x, uvEnd.y), + Vec2(uvEnd.x, uvStart.y), + Vec2(uvEnd.x, uvEnd.y), + ) + } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/position/HUDElementPositionAnchors.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/position/HUDElementPositionAnchors.kt index dc2de3c56..2f2a35fb8 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/position/HUDElementPositionAnchors.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/position/HUDElementPositionAnchors.kt @@ -3,15 +3,21 @@ package de.bixilon.minosoft.gui.rendering.hud.elements.position import de.bixilon.minosoft.data.mappings.ResourceLocation import glm_.vec2.Vec2i -enum class HUDElementPositionAnchors(val resourceLocation: ResourceLocation, val quadTransform: (Vec2i, Vec2i) -> Array) { - CENTER(ResourceLocation("minosoft:center"), { position, size -> - arrayOf( - Vec2i(position.x + size.x * 0.5f, position.y + size.y * 0.5f), - Vec2i(position.x + size.x * 0.5f, position.y - size.y * 0.5f), - Vec2i(position.x - size.x * 0.5f, position.y + size.y * 0.5f), - Vec2i(position.x - size.x * 0.5f, position.y - size.y * 0.5f), - ) - }) +enum class HUDElementPositionAnchors( + val resourceLocation: ResourceLocation, + val quadTransform: (Vec2i, Vec2i) -> Array, + val positionTransform: (Vec2i) -> Vec2i +) { + CENTER(ResourceLocation("minosoft:center"), + { position, size -> + arrayOf( + Vec2i(position.x + size.x * 0.5f, position.y + size.y * 0.5f), + Vec2i(position.x + size.x * 0.5f, position.y - size.y * 0.5f), + Vec2i(position.x - size.x * 0.5f, position.y + size.y * 0.5f), + Vec2i(position.x - size.x * 0.5f, position.y - size.y * 0.5f), + ) }, + { size -> size * 0.5f } + ) ; companion object { val HUD_ELEMENT_POSITION_ATTACHMENT_OPTIONS = values() diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/primitive/HUDElement.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/primitive/HUDElement.kt index 23cd7be39..4eccb3104 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/primitive/HUDElement.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/primitive/HUDElement.kt @@ -13,26 +13,21 @@ package de.bixilon.minosoft.gui.rendering.hud.elements.primitive -import de.bixilon.minosoft.data.mappings.ResourceLocation -import de.bixilon.minosoft.data.text.RGBColor import de.bixilon.minosoft.gui.rendering.hud.HUDRenderer import de.bixilon.minosoft.gui.rendering.hud.elements.position.HUDElementPositionAnchors import de.bixilon.minosoft.gui.rendering.hud.elements.position.HUDElementVec2 import glm_.mat4x4.Mat4 +import glm_.vec2.Vec2i abstract class HUDElement( - json: Map, - val position: HUDElementVec2, - val positionAnchor: HUDElementPositionAnchors, - val content: ResourceLocation, + val position: HUDElementPosition, val size: HUDElementVec2, - val realZ: Float, - val tint: RGBColor, ) { lateinit var hudRenderer: HUDRenderer open fun init(hudRenderer: HUDRenderer) { this.hudRenderer = hudRenderer + position.init() } open fun postInit() {} @@ -40,4 +35,9 @@ abstract class HUDElement( open fun draw() {} open fun prepare(matrix: Mat4) {} + fun getPositionAtAnchor(anchor: HUDElementPositionAnchors, hudRenderer: HUDRenderer): Vec2i { + return position.getRealPosition(hudRenderer) - + position.anchor.positionTransform.invoke(size.getRealVector(hudRenderer)) + + anchor.positionTransform.invoke(size.getRealVector(hudRenderer)) + } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/primitive/HUDElementPosition.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/primitive/HUDElementPosition.kt new file mode 100644 index 000000000..087b108ad --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/primitive/HUDElementPosition.kt @@ -0,0 +1,42 @@ +package de.bixilon.minosoft.gui.rendering.hud.elements.primitive + +import de.bixilon.minosoft.Minosoft +import de.bixilon.minosoft.data.mappings.ResourceLocation +import de.bixilon.minosoft.gui.rendering.hud.HUDRenderer +import de.bixilon.minosoft.gui.rendering.hud.elements.position.HUDElementPositionAnchors +import de.bixilon.minosoft.gui.rendering.hud.elements.position.HUDElementVec2 +import glm_.vec2.Vec2i + +class HUDElementPosition( + val position: HUDElementVec2, + val anchor: HUDElementPositionAnchors, + val parent: String?, +) { + var parentElement: HUDElement? = null + + fun init() { + parentElement = parent?.let { Minosoft.getConfig().config.game.elements.entries[ResourceLocation(it)] } + } + + fun getPositions(hudRenderer: HUDRenderer, size: Vec2i): Array { + val position = getRealPosition(hudRenderer) + return anchor.quadTransform.invoke(position, size) + } + + fun getRealPosition(hudRenderer: HUDRenderer): Vec2i { + if (parentElement == null) { + return position.getRealVector(hudRenderer) + } + return parentElement!!.getPositionAtAnchor(anchor, hudRenderer) + position.getRealVector(hudRenderer) + } + + companion object { + fun deserialize(json: Map): HUDElementPosition { + val position = HUDElementVec2.deserialize(json)!! + val positionAnchor = HUDElementPositionAnchors.HUD_ELEMENT_POSITION_ATTACHMENTS_MAPPING[ResourceLocation(json["anchor"].toString())]!! + val parent = json["parent"] as String? + + return HUDElementPosition(position, positionAnchor, parent) + } + } +} diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/primitive/HUDElementSerializer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/primitive/HUDElementSerializer.kt index e6d10b1ce..17601bfc1 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/primitive/HUDElementSerializer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/primitive/HUDElementSerializer.kt @@ -4,24 +4,17 @@ import com.squareup.moshi.FromJson import com.squareup.moshi.JsonWriter import com.squareup.moshi.ToJson import de.bixilon.minosoft.data.mappings.ResourceLocation -import de.bixilon.minosoft.gui.rendering.hud.elements.position.HUDElementPositionAnchors import de.bixilon.minosoft.gui.rendering.hud.elements.position.HUDElementVec2 -import de.bixilon.minosoft.util.json.RGBColorSerializer object HUDElementSerializer { @FromJson fun fromJson(json: Map): HUDElement? { - val position = HUDElementVec2.deserialize(json["position"]) - val positionAnchor = HUDElementPositionAnchors.HUD_ELEMENT_POSITION_ATTACHMENTS_MAPPING[ResourceLocation((json["position"] as Map<*,*>)["location"].toString())]!! + val position = HUDElementPosition.deserialize(json["position"] as Map) val size = HUDElementVec2.deserialize(json["size"]) return HUD_ELEMENT_TYPES[ResourceLocation(json["type"].toString())]?.constructors?.first()?.call( - json, position, - positionAnchor, - ResourceLocation(json["content"].toString()), size, - (json["real_z"] as Double).toFloat(), - json["tint"]?.let{ RGBColorSerializer.fromJsonValue(it) }, + json, ) } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/primitive/HUDImageElement.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/primitive/HUDImageElement.kt index 0cd7b0906..19285d455 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/primitive/HUDImageElement.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/primitive/HUDImageElement.kt @@ -3,35 +3,42 @@ package de.bixilon.minosoft.gui.rendering.hud.elements.primitive import de.bixilon.minosoft.data.mappings.ResourceLocation import de.bixilon.minosoft.data.text.ChatColors import de.bixilon.minosoft.data.text.RGBColor +import de.bixilon.minosoft.gui.rendering.RenderConstants import de.bixilon.minosoft.gui.rendering.hud.HUDRenderer -import de.bixilon.minosoft.gui.rendering.hud.atlas.HUDAtlasElement -import de.bixilon.minosoft.gui.rendering.hud.elements.position.HUDElementPositionAnchors +import de.bixilon.minosoft.gui.rendering.hud.atlas.TextureLike import de.bixilon.minosoft.gui.rendering.hud.elements.position.HUDElementVec2 import de.bixilon.minosoft.gui.rendering.util.mesh.Mesh import de.bixilon.minosoft.gui.rendering.util.mesh.SimpleTextureMesh +import de.bixilon.minosoft.util.json.RGBColorSerializer import glm_.mat4x4.Mat4 import glm_.vec2.Vec2 import glm_.vec3.Vec3 import glm_.vec4.Vec4 import glm_.vec4.swizzle.xy -class HUDImageElement( - json: Map, - position: HUDElementVec2, - positionAnchor: HUDElementPositionAnchors, - content: ResourceLocation, - size: HUDElementVec2, - realZ: Float, - tint: RGBColor = ChatColors.WHITE, -) : HUDElement(json, position, positionAnchor, content, size, realZ, tint) { - +class HUDImageElement: HUDElement { private var mesh = SimpleTextureMesh() + private lateinit var texture: TextureLike - private lateinit var hudAtlasElement: HUDAtlasElement + val z: Int + private val textureName: ResourceLocation? + val tint: RGBColor + + constructor(position: HUDElementPosition, size: HUDElementVec2, json: Map? = null): super(position, size) { + z = (json?.get("z") as Int?) ?: 0 + textureName = (json?.get("texture") as String?)?.let { ResourceLocation(it) } + tint = json?.get("tint")?.let{ RGBColorSerializer.fromJsonValue(it) } ?: ChatColors.WHITE + } + + constructor(position: HUDElementPosition, size: HUDElementVec2, z: Int): super(position, size) { + this.z = z + textureName = null + tint = ChatColors.WHITE + } override fun init(hudRenderer: HUDRenderer) { super.init(hudRenderer) - hudAtlasElement = hudRenderer.hudAtlasElements[content]!! + texture = textureName?.let { hudRenderer.hudAtlasElements[it]!! } ?: hudRenderer.renderWindow.WHITE_TEXTURE } override fun draw() { @@ -44,17 +51,16 @@ class HUDImageElement( mesh.unload() mesh = SimpleTextureMesh() } - val realPosition = position.getRealVector(hudRenderer) - val realSize = size.getRealVector(hudRenderer) + val realZ = RenderConstants.HUD_Z_COORDINATE + RenderConstants.HUD_Z_COORDINATE_Z_FACTOR * z + val positions = position.getPositions(hudRenderer, size.getRealVector(hudRenderer)) + val uvs = texture.uvs fun addVertex(position: Vec2, textureUV: Vec2) { mesh.addVertex(Vec3( position.x, position.y, realZ, - ), hudAtlasElement.texture, textureUV, tint) + ), texture.texture, textureUV, tint) } - val positions = positionAnchor.quadTransform.invoke(realPosition, realSize) - val uvs = hudAtlasElement.uvs for (position in arrayOf(0, 1, 2, 1, 3, 2)) { addVertex((matrix * Vec4(positions[position], 1f, 1f)).xy, uvs[position]) } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/primitive/HUDTextElement.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/primitive/HUDTextElement.kt deleted file mode 100644 index 9d4b870c3..000000000 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/primitive/HUDTextElement.kt +++ /dev/null @@ -1,46 +0,0 @@ -package de.bixilon.minosoft.gui.rendering.hud.elements.primitive - -import de.bixilon.minosoft.data.mappings.ResourceLocation -import de.bixilon.minosoft.data.text.ChatColors -import de.bixilon.minosoft.data.text.ChatComponent -import de.bixilon.minosoft.data.text.RGBColor -import de.bixilon.minosoft.gui.rendering.hud.elements.position.HUDElementPositionAnchors -import de.bixilon.minosoft.gui.rendering.hud.elements.position.HUDElementVec2 -import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition -import glm_.glm - -class HUDTextElement( - json: Map, - position: HUDElementVec2, - positionAnchor: HUDElementPositionAnchors, - content: ResourceLocation, - size: HUDElementVec2, - realZ: Float, - tint: RGBColor = ChatColors.WHITE, -): HUDElement(json, position, positionAnchor, content, size, realZ, tint) { - val charImages = mutableListOf() - - val HUDTextElementAlignment = HUDTextElementAlignments.deserialize(json["alignment"] as String)!! - - fun renderChatComponent(chatComponent: ChatComponent) { - var width = 0 - var lines = 1 - var maxHeight = 0 - fun newLine() { - lines++ - } - - val chars = chatComponent.message.toCharArray() - - for (char in chars) { - if (ProtocolDefinition.LINE_BREAK_CHARS.contains(char)) { - newLine() - } - val fontChar = hudRenderer.renderWindow.font.getChar(char) - width += fontChar.size.x - maxHeight = glm.max(maxHeight, fontChar.size.y) - - - } - } -} diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/text/HUDTextElement.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/text/HUDTextElement.kt new file mode 100644 index 000000000..e992eabb1 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/text/HUDTextElement.kt @@ -0,0 +1,31 @@ +package de.bixilon.minosoft.gui.rendering.hud.elements.text + +import de.bixilon.minosoft.data.text.ChatColors +import de.bixilon.minosoft.data.text.ChatComponent +import de.bixilon.minosoft.data.text.RGBColor +import de.bixilon.minosoft.gui.rendering.hud.elements.position.HUDElementVec2 +import de.bixilon.minosoft.gui.rendering.hud.elements.primitive.HUDElement +import de.bixilon.minosoft.gui.rendering.hud.elements.primitive.HUDElementPosition +import de.bixilon.minosoft.gui.rendering.hud.elements.primitive.HUDImageElement + +class HUDTextElement( + position: HUDElementPosition, + size: HUDElementVec2, + json: Map? = null, + val z: Int = (json?.get("z") as Int?) ?: 0, + val tint: RGBColor = ChatColors.WHITE, +): HUDElement(position, size) { + val elements = mutableListOf() + + val HUDTextElementAlignment = HUDTextElementAlignments.deserialize(json?.get("alignment") as String) ?: HUDTextElementAlignments.LEFT + + fun renderChatComponent(chatComponent: ChatComponent) { + val chars = chatComponent.message.toCharArray() + var size = 0f + for (char in chars) { + // TODO: line break + val fontChar = hudRenderer.renderWindow.font.getChar(char) + size += fontChar.size.x + } + } +} diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/primitive/HUDTextElementAlignments.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/text/HUDTextElementAlignments.kt similarity index 94% rename from src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/primitive/HUDTextElementAlignments.kt rename to src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/text/HUDTextElementAlignments.kt index 6e636f150..7a293927e 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/primitive/HUDTextElementAlignments.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/text/HUDTextElementAlignments.kt @@ -1,4 +1,4 @@ -package de.bixilon.minosoft.gui.rendering.hud.elements.primitive +package de.bixilon.minosoft.gui.rendering.hud.elements.text import de.bixilon.minosoft.data.mappings.ResourceLocation