hud: improve unit system

This commit is contained in:
Lukas 2021-06-10 20:30:26 +02:00
parent 03f6683697
commit 0c75b50093
10 changed files with 133 additions and 101 deletions

View File

@ -32,15 +32,6 @@ data class HUDAtlasElement(
override val size: Vec2i override val size: Vec2i
get() = binding.size get() = binding.size
val uvs: Array<Vec2> 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() { fun postInit() {
uvStart = (Vec2(binding.start) + RenderConstants.PIXEL_UV_PIXEL_ADD) * texture.arraySinglePixelFactor uvStart = (Vec2(binding.start) + RenderConstants.PIXEL_UV_PIXEL_ADD) * texture.arraySinglePixelFactor
uvEnd = Vec2(binding.end) * texture.arraySinglePixelFactor uvEnd = Vec2(binding.end) * texture.arraySinglePixelFactor

View File

@ -22,4 +22,13 @@ interface TextureLike {
val uvStart: Vec2 val uvStart: Vec2
val uvEnd: Vec2 val uvEnd: Vec2
val size: Vec2i val size: Vec2i
val uvs: Array<Vec2> get() {
return arrayOf(
Vec2(uvStart.x, uvStart.y),
Vec2(uvStart.x, uvEnd.y),
Vec2(uvEnd.x, uvStart.y),
Vec2(uvEnd.x, uvEnd.y),
)
}
} }

View File

@ -3,15 +3,21 @@ package de.bixilon.minosoft.gui.rendering.hud.elements.position
import de.bixilon.minosoft.data.mappings.ResourceLocation import de.bixilon.minosoft.data.mappings.ResourceLocation
import glm_.vec2.Vec2i import glm_.vec2.Vec2i
enum class HUDElementPositionAnchors(val resourceLocation: ResourceLocation, val quadTransform: (Vec2i, Vec2i) -> Array<Vec2i>) { enum class HUDElementPositionAnchors(
CENTER(ResourceLocation("minosoft:center"), { position, size -> val resourceLocation: ResourceLocation,
arrayOf( val quadTransform: (Vec2i, Vec2i) -> Array<Vec2i>,
Vec2i(position.x + size.x * 0.5f, position.y + size.y * 0.5f), val positionTransform: (Vec2i) -> Vec2i
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), CENTER(ResourceLocation("minosoft:center"),
Vec2i(position.x - size.x * 0.5f, position.y - size.y * 0.5f), { 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 { companion object {
val HUD_ELEMENT_POSITION_ATTACHMENT_OPTIONS = values() val HUD_ELEMENT_POSITION_ATTACHMENT_OPTIONS = values()

View File

@ -13,26 +13,21 @@
package de.bixilon.minosoft.gui.rendering.hud.elements.primitive 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.HUDRenderer
import de.bixilon.minosoft.gui.rendering.hud.elements.position.HUDElementPositionAnchors import de.bixilon.minosoft.gui.rendering.hud.elements.position.HUDElementPositionAnchors
import de.bixilon.minosoft.gui.rendering.hud.elements.position.HUDElementVec2 import de.bixilon.minosoft.gui.rendering.hud.elements.position.HUDElementVec2
import glm_.mat4x4.Mat4 import glm_.mat4x4.Mat4
import glm_.vec2.Vec2i
abstract class HUDElement( abstract class HUDElement(
json: Map<String, Any>, val position: HUDElementPosition,
val position: HUDElementVec2,
val positionAnchor: HUDElementPositionAnchors,
val content: ResourceLocation,
val size: HUDElementVec2, val size: HUDElementVec2,
val realZ: Float,
val tint: RGBColor,
) { ) {
lateinit var hudRenderer: HUDRenderer lateinit var hudRenderer: HUDRenderer
open fun init(hudRenderer: HUDRenderer) { open fun init(hudRenderer: HUDRenderer) {
this.hudRenderer = hudRenderer this.hudRenderer = hudRenderer
position.init()
} }
open fun postInit() {} open fun postInit() {}
@ -40,4 +35,9 @@ abstract class HUDElement(
open fun draw() {} open fun draw() {}
open fun prepare(matrix: Mat4) {} 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))
}
} }

View File

@ -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<Vec2i> {
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<String, Any>): 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)
}
}
}

View File

@ -4,24 +4,17 @@ import com.squareup.moshi.FromJson
import com.squareup.moshi.JsonWriter import com.squareup.moshi.JsonWriter
import com.squareup.moshi.ToJson import com.squareup.moshi.ToJson
import de.bixilon.minosoft.data.mappings.ResourceLocation 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.gui.rendering.hud.elements.position.HUDElementVec2
import de.bixilon.minosoft.util.json.RGBColorSerializer
object HUDElementSerializer { object HUDElementSerializer {
@FromJson @FromJson
fun fromJson(json: Map<String, Any>): HUDElement? { fun fromJson(json: Map<String, Any>): HUDElement? {
val position = HUDElementVec2.deserialize(json["position"]) val position = HUDElementPosition.deserialize(json["position"] as Map<String, Any>)
val positionAnchor = HUDElementPositionAnchors.HUD_ELEMENT_POSITION_ATTACHMENTS_MAPPING[ResourceLocation((json["position"] as Map<*,*>)["location"].toString())]!!
val size = HUDElementVec2.deserialize(json["size"]) val size = HUDElementVec2.deserialize(json["size"])
return HUD_ELEMENT_TYPES[ResourceLocation(json["type"].toString())]?.constructors?.first()?.call( return HUD_ELEMENT_TYPES[ResourceLocation(json["type"].toString())]?.constructors?.first()?.call(
json,
position, position,
positionAnchor,
ResourceLocation(json["content"].toString()),
size, size,
(json["real_z"] as Double).toFloat(), json,
json["tint"]?.let{ RGBColorSerializer.fromJsonValue(it) },
) )
} }

View File

@ -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.mappings.ResourceLocation
import de.bixilon.minosoft.data.text.ChatColors import de.bixilon.minosoft.data.text.ChatColors
import de.bixilon.minosoft.data.text.RGBColor 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.HUDRenderer
import de.bixilon.minosoft.gui.rendering.hud.atlas.HUDAtlasElement import de.bixilon.minosoft.gui.rendering.hud.atlas.TextureLike
import de.bixilon.minosoft.gui.rendering.hud.elements.position.HUDElementPositionAnchors
import de.bixilon.minosoft.gui.rendering.hud.elements.position.HUDElementVec2 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.Mesh
import de.bixilon.minosoft.gui.rendering.util.mesh.SimpleTextureMesh import de.bixilon.minosoft.gui.rendering.util.mesh.SimpleTextureMesh
import de.bixilon.minosoft.util.json.RGBColorSerializer
import glm_.mat4x4.Mat4 import glm_.mat4x4.Mat4
import glm_.vec2.Vec2 import glm_.vec2.Vec2
import glm_.vec3.Vec3 import glm_.vec3.Vec3
import glm_.vec4.Vec4 import glm_.vec4.Vec4
import glm_.vec4.swizzle.xy import glm_.vec4.swizzle.xy
class HUDImageElement( class HUDImageElement: HUDElement {
json: Map<String, Any>,
position: HUDElementVec2,
positionAnchor: HUDElementPositionAnchors,
content: ResourceLocation,
size: HUDElementVec2,
realZ: Float,
tint: RGBColor = ChatColors.WHITE,
) : HUDElement(json, position, positionAnchor, content, size, realZ, tint) {
private var mesh = SimpleTextureMesh() 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<String, Any>? = 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) { override fun init(hudRenderer: HUDRenderer) {
super.init(hudRenderer) super.init(hudRenderer)
hudAtlasElement = hudRenderer.hudAtlasElements[content]!! texture = textureName?.let { hudRenderer.hudAtlasElements[it]!! } ?: hudRenderer.renderWindow.WHITE_TEXTURE
} }
override fun draw() { override fun draw() {
@ -44,17 +51,16 @@ class HUDImageElement(
mesh.unload() mesh.unload()
mesh = SimpleTextureMesh() mesh = SimpleTextureMesh()
} }
val realPosition = position.getRealVector(hudRenderer) val realZ = RenderConstants.HUD_Z_COORDINATE + RenderConstants.HUD_Z_COORDINATE_Z_FACTOR * z
val realSize = size.getRealVector(hudRenderer) val positions = position.getPositions(hudRenderer, size.getRealVector(hudRenderer))
val uvs = texture.uvs
fun addVertex(position: Vec2, textureUV: Vec2) { fun addVertex(position: Vec2, textureUV: Vec2) {
mesh.addVertex(Vec3( mesh.addVertex(Vec3(
position.x, position.x,
position.y, position.y,
realZ, 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)) { for (position in arrayOf(0, 1, 2, 1, 3, 2)) {
addVertex((matrix * Vec4(positions[position], 1f, 1f)).xy, uvs[position]) addVertex((matrix * Vec4(positions[position], 1f, 1f)).xy, uvs[position])
} }

View File

@ -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<String, Any>,
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<HUDImageElement>()
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)
}
}
}

View File

@ -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<String, Any>? = null,
val z: Int = (json?.get("z") as Int?) ?: 0,
val tint: RGBColor = ChatColors.WHITE,
): HUDElement(position, size) {
val elements = mutableListOf<HUDImageElement>()
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
}
}
}

View File

@ -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 import de.bixilon.minosoft.data.mappings.ResourceLocation