entity renderer: damage

This commit is contained in:
Moritz Zwerger 2023-11-02 10:10:51 +01:00
parent d33eb3bb6c
commit b33696058f
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
15 changed files with 80 additions and 18 deletions

View File

@ -229,7 +229,7 @@ testing {
val options = this as TestNGOptions val options = this as TestNGOptions
options.preserveOrder = true options.preserveOrder = true
// options.excludeGroups("models", "mesher", "chunk", "input", "font", "command", "registry", "biome", "version", "fluid", "world", "raycasting", "pixlyzer", "item", "block", "physics", "light", "packet", "container", "item_stack", "signature", "private_key", "interaction", "item_digging", "chunk_renderer", "rendering", "texture", "atlas", "gui") // options.excludeGroups("models", "mesher", "chunk", "input", "font", "command", "registry", "biome", "version", "fluid", "world", "raycasting", "pixlyzer", "item", "block", "physics", "light", "packet", "container", "item_stack", "signature", "private_key", "interaction", "item_digging", "chunk_renderer", "rendering", "texture", "atlas", "gui")
options.excludeGroups("models", "mesher", "chunk", "input", "font", "command", "registry", "biome", "version", "fluid", "world", "raycasting", "pixlyzer", "item", "block", "physics", "light", "packet", "container", "item_stack", "signature", "private_key", "interaction", "item_digging", "chunk_renderer", "texture", "atlas", "gui") options.excludeGroups("models", "chunk", "input", "font", "command", "registry", "biome", "version", "fluid", "world", "raycasting", "pixlyzer", "item", "physics", "light", "packet", "container", "item_stack", "signature", "private_key", "interaction", "item_digging", "chunk_renderer", "texture", "atlas", "gui")
} }
} }
} }

View File

@ -14,6 +14,7 @@ package de.bixilon.minosoft.data.entities.entities
import de.bixilon.kotlinglm.vec3.Vec3d import de.bixilon.kotlinglm.vec3.Vec3d
import de.bixilon.kotlinglm.vec3.Vec3i import de.bixilon.kotlinglm.vec3.Vec3i
import de.bixilon.kutil.cast.CastUtil.nullCast
import de.bixilon.kutil.cast.CastUtil.unsafeCast import de.bixilon.kutil.cast.CastUtil.unsafeCast
import de.bixilon.minosoft.data.container.equipment.EntityEquipment import de.bixilon.minosoft.data.container.equipment.EntityEquipment
import de.bixilon.minosoft.data.entities.EntityRotation import de.bixilon.minosoft.data.entities.EntityRotation
@ -22,6 +23,8 @@ import de.bixilon.minosoft.data.entities.data.EntityData
import de.bixilon.minosoft.data.entities.data.EntityDataField import de.bixilon.minosoft.data.entities.data.EntityDataField
import de.bixilon.minosoft.data.entities.entities.player.Hands import de.bixilon.minosoft.data.entities.entities.player.Hands
import de.bixilon.minosoft.data.entities.entities.properties.StatusEffectProperty import de.bixilon.minosoft.data.entities.entities.properties.StatusEffectProperty
import de.bixilon.minosoft.data.entities.event.events.damage.DamageEvent
import de.bixilon.minosoft.data.entities.event.events.damage.DamageListener
import de.bixilon.minosoft.data.registries.effects.attributes.EntityAttributes import de.bixilon.minosoft.data.registries.effects.attributes.EntityAttributes
import de.bixilon.minosoft.data.registries.effects.attributes.MinecraftAttributes import de.bixilon.minosoft.data.registries.effects.attributes.MinecraftAttributes
import de.bixilon.minosoft.data.registries.entities.EntityType import de.bixilon.minosoft.data.registries.entities.EntityType
@ -33,7 +36,7 @@ import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.sp
import de.bixilon.minosoft.physics.entities.living.LivingEntityPhysics import de.bixilon.minosoft.physics.entities.living.LivingEntityPhysics
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
abstract class LivingEntity(connection: PlayConnection, entityType: EntityType, data: EntityData, position: Vec3d, rotation: EntityRotation) : Entity(connection, entityType, data, position, rotation) { abstract class LivingEntity(connection: PlayConnection, entityType: EntityType, data: EntityData, position: Vec3d, rotation: EntityRotation) : Entity(connection, entityType, data, position, rotation), DamageListener {
private val entityEffectParticle = connection.registries.particleType[EntityEffectParticle] private val entityEffectParticle = connection.registries.particleType[EntityEffectParticle]
private val ambientEntityEffectParticle = connection.registries.particleType[AmbientEntityEffectParticle] private val ambientEntityEffectParticle = connection.registries.particleType[AmbientEntityEffectParticle]
@ -109,6 +112,10 @@ abstract class LivingEntity(connection: PlayConnection, entityType: EntityType,
override fun physics(): LivingEntityPhysics<*> = super.physics().unsafeCast() override fun physics(): LivingEntityPhysics<*> = super.physics().unsafeCast()
override fun onDamage(type: DamageEvent) {
this.renderer?.nullCast<DamageListener>()?.onDamage(type)
}
companion object { companion object {
private val FLAGS_DATA = EntityDataField("LIVING_ENTITY_FLAGS") private val FLAGS_DATA = EntityDataField("LIVING_ENTITY_FLAGS")
private val HEALTH_DATA = EntityDataField("LIVING_ENTITY_HEALTH") private val HEALTH_DATA = EntityDataField("LIVING_ENTITY_HEALTH")

View File

@ -19,6 +19,6 @@ import de.bixilon.minosoft.data.entities.event.EntityEvent
interface DamageEvent : EntityEvent<LivingEntity> { interface DamageEvent : EntityEvent<LivingEntity> {
override fun handle(entity: LivingEntity) { override fun handle(entity: LivingEntity) {
// TODO entity.onDamage(this)
} }
} }

View File

@ -0,0 +1,19 @@
/*
* Minosoft
* Copyright (C) 2020-2023 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.entities.event.events.damage
fun interface DamageListener {
fun onDamage(type: DamageEvent) // TODO: DamageType
}

View File

@ -13,6 +13,8 @@
package de.bixilon.minosoft.data.text.formatting.color package de.bixilon.minosoft.data.text.formatting.color
import de.bixilon.kutil.math.interpolation.FloatInterpolation
object ColorUtil { object ColorUtil {
fun mixColors(vararg colors: Int): Int { fun mixColors(vararg colors: Int): Int {
@ -38,7 +40,7 @@ object ColorUtil {
return (start.toFloat() + delta * (end.toFloat() - start.toFloat())).toInt() return (start.toFloat() + delta * (end.toFloat() - start.toFloat())).toInt()
} }
fun interpolateRGB(delta: Float, start: RGBColor, end: RGBColor): RGBColor { fun interpolateRGB(delta: Float, start: RGBColor, end: RGBColor, component: (Float, Float, Float) -> Float = FloatInterpolation::interpolateLinear): RGBColor {
if (delta <= 0.0f) return start if (delta <= 0.0f) return start
if (delta >= 1.0f) return end if (delta >= 1.0f) return end

View File

@ -64,7 +64,8 @@ open class SkeletalFeature(
} }
override fun draw() { override fun draw() {
instance.draw(renderer.light.value) val tint = renderer.light.value.mix(renderer.damage.value)
instance.draw(tint)
} }
override fun reset() { override fun reset() {

View File

@ -48,7 +48,6 @@ class HitboxFeature(renderer: EntityRenderer<*>) : EntityRenderFeature(renderer)
override fun update(millis: Long, delta: Float) { override fun update(millis: Long, delta: Float) {
if (!manager.enabled) return unload() if (!manager.enabled) return unload()
if (!enabled) return unload() if (!enabled) return unload()
if (!manager.profile.showInvisible && renderer.entity.isInvisible) return unload()
if (!visible) return if (!visible) return
val offset = renderer.renderer.context.camera.offset.offset val offset = renderer.renderer.context.camera.offset.offset

View File

@ -37,7 +37,7 @@ open class PlayerModel(
shader.use() shader.use()
shader.texture = renderer.skin?.shaderId ?: renderer.renderer.context.textures.debugTexture.shaderId shader.texture = renderer.skin?.shaderId ?: renderer.renderer.context.textures.debugTexture.shaderId
shader.light = renderer.light.value shader.tint = renderer.light.value.mix(renderer.damage.value)
shader.skinParts = this.skinParts shader.skinParts = this.skinParts

View File

@ -16,6 +16,8 @@ package de.bixilon.minosoft.gui.rendering.entities.renderer
import de.bixilon.kotlinglm.mat4x4.Mat4 import de.bixilon.kotlinglm.mat4x4.Mat4
import de.bixilon.kotlinglm.vec3.Vec3 import de.bixilon.kotlinglm.vec3.Vec3
import de.bixilon.minosoft.data.entities.entities.Entity import de.bixilon.minosoft.data.entities.entities.Entity
import de.bixilon.minosoft.data.entities.event.events.damage.DamageEvent
import de.bixilon.minosoft.data.entities.event.events.damage.DamageListener
import de.bixilon.minosoft.data.text.formatting.color.ChatColors import de.bixilon.minosoft.data.text.formatting.color.ChatColors
import de.bixilon.minosoft.data.text.formatting.color.ColorUtil import de.bixilon.minosoft.data.text.formatting.color.ColorUtil
import de.bixilon.minosoft.gui.rendering.entities.EntitiesRenderer import de.bixilon.minosoft.gui.rendering.entities.EntitiesRenderer
@ -31,13 +33,14 @@ import de.bixilon.minosoft.util.interpolate.Interpolator
abstract class EntityRenderer<E : Entity>( abstract class EntityRenderer<E : Entity>(
val renderer: EntitiesRenderer, val renderer: EntitiesRenderer,
val entity: E, val entity: E,
) { ) : DamageListener {
private var update = 0L private var update = 0L
val features = FeatureManager(this) val features = FeatureManager(this)
val info = entity.renderInfo val info = entity.renderInfo
val hitbox = HitboxFeature(this).register() val hitbox = HitboxFeature(this).register()
val light = Interpolator(ChatColors.WHITE, ColorUtil::interpolateRGB) val light = Interpolator(ChatColors.WHITE, ColorUtil::interpolateRGB)
val damage = Interpolator(ChatColors.WHITE, ColorUtil::interpolateRGB) // TODO delta^2
val matrix = Mat4() val matrix = Mat4()
var visible = true var visible = true
protected set protected set
@ -62,6 +65,10 @@ abstract class EntityRenderer<E : Entity>(
open fun update(millis: Long) { open fun update(millis: Long) {
val delta = if (this.update <= 0L) 0.0f else ((millis - update) / 1000.0f) val delta = if (this.update <= 0L) 0.0f else ((millis - update) / 1000.0f)
updateLight(delta) updateLight(delta)
if (damage.delta > 1.0f) {
damage.push(ChatColors.WHITE)
}
damage.add(delta, 0.05f)
entity.draw(millis) entity.draw(millis)
updateMatrix(delta) updateMatrix(delta)
features.update(millis, delta) features.update(millis, delta)
@ -96,4 +103,8 @@ abstract class EntityRenderer<E : Entity>(
this.visible = visible && !entity.isInvisible this.visible = visible && !entity.isInvisible
features.updateVisibility(occluded) features.updateVisibility(occluded)
} }
override fun onDamage(type: DamageEvent) {
damage.push(ChatColors.RED)
}
} }

View File

@ -14,12 +14,13 @@
package de.bixilon.minosoft.gui.rendering.entities.renderer.living.player package de.bixilon.minosoft.gui.rendering.entities.renderer.living.player
import de.bixilon.minosoft.data.text.formatting.color.ChatColors import de.bixilon.minosoft.data.text.formatting.color.ChatColors
import de.bixilon.minosoft.gui.rendering.shader.types.TintedShader
import de.bixilon.minosoft.gui.rendering.skeletal.shader.BaseSkeletalShader import de.bixilon.minosoft.gui.rendering.skeletal.shader.BaseSkeletalShader
import de.bixilon.minosoft.gui.rendering.system.base.buffer.uniform.FloatUniformBuffer import de.bixilon.minosoft.gui.rendering.system.base.buffer.uniform.FloatUniformBuffer
import de.bixilon.minosoft.gui.rendering.system.base.shader.NativeShader import de.bixilon.minosoft.gui.rendering.system.base.shader.NativeShader
class PlayerShader(native: NativeShader, buffer: FloatUniformBuffer) : BaseSkeletalShader(native, buffer) { class PlayerShader(native: NativeShader, buffer: FloatUniformBuffer) : BaseSkeletalShader(native, buffer), TintedShader {
var texture by uniform("uIndexLayer", 0x00, NativeShader::setUInt) var texture by uniform("uIndexLayer", 0x00, NativeShader::setUInt)
var light by uniform("uLight", ChatColors.WHITE) { shader, name, value -> shader.setUInt(name, value.rgb) } override var tint by uniform("uTintColor", ChatColors.WHITE) { shader, name, value -> shader.setUInt(name, value.rgb) }
var skinParts by uniform("uSkinParts", 0xFF, NativeShader::setUInt) var skinParts by uniform("uSkinParts", 0xFF, NativeShader::setUInt)
} }

View File

@ -0,0 +1,21 @@
/*
* Minosoft
* Copyright (C) 2020-2023 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.gui.rendering.shader.types
import de.bixilon.minosoft.data.text.formatting.color.RGBColor
import de.bixilon.minosoft.gui.rendering.shader.AbstractShader
interface TintedShader : AbstractShader {
var tint: RGBColor
}

View File

@ -41,11 +41,11 @@ class SkeletalInstance(
draw(shader) draw(shader)
} }
fun draw(light: RGBColor) { fun draw(tint: RGBColor) {
context.system.reset(faceCulling = false) context.system.reset(faceCulling = false)
val shader = context.skeletal.shader val shader = context.skeletal.shader
shader.use() shader.use()
shader.light = light shader.tint = tint
draw(shader) draw(shader)
} }

View File

@ -15,9 +15,10 @@ package de.bixilon.minosoft.gui.rendering.skeletal.shader
import de.bixilon.minosoft.data.text.formatting.color.ChatColors import de.bixilon.minosoft.data.text.formatting.color.ChatColors
import de.bixilon.minosoft.gui.rendering.shader.types.AnimatedShader import de.bixilon.minosoft.gui.rendering.shader.types.AnimatedShader
import de.bixilon.minosoft.gui.rendering.shader.types.TintedShader
import de.bixilon.minosoft.gui.rendering.system.base.buffer.uniform.FloatUniformBuffer import de.bixilon.minosoft.gui.rendering.system.base.buffer.uniform.FloatUniformBuffer
import de.bixilon.minosoft.gui.rendering.system.base.shader.NativeShader import de.bixilon.minosoft.gui.rendering.system.base.shader.NativeShader
class SkeletalShader(native: NativeShader, buffer: FloatUniformBuffer) : BaseSkeletalShader(native, buffer), AnimatedShader { class SkeletalShader(native: NativeShader, buffer: FloatUniformBuffer) : BaseSkeletalShader(native, buffer), AnimatedShader, TintedShader {
var light by uniform("uLight", ChatColors.WHITE) { shader, name, value -> shader.setUInt(name, value.rgb) } override var tint by uniform("uTintColor", ChatColors.WHITE) { shader, name, value -> shader.setUInt(name, value.rgb) }
} }

View File

@ -21,7 +21,7 @@ out vec3 finFragmentPosition;
uniform uint uIndexLayer; uniform uint uIndexLayer;
uniform uint uLight; uniform uint uTintColor;
uniform uint uSkinParts; uniform uint uSkinParts;
flat out uint finAllowTransparency; flat out uint finAllowTransparency;
@ -45,7 +45,7 @@ void main() {
} }
finAllowTransparency = skinPart; finAllowTransparency = skinPart;
run_skeletal(partTransformNormal, vinPosition); run_skeletal(partTransformNormal, vinPosition);
vec4 light = getRGBColor(uLight & 0xFFFFFFu); vec4 light = getRGBColor(uTintColor & 0xFFFFFFu);
finTintColor *= light; finTintColor *= light;
finTextureIndex = uIndexLayer >> 28u; finTextureIndex = uIndexLayer >> 28u;

View File

@ -28,12 +28,12 @@ layout (location = 3) in float vinIndexLayerAnimation;// texture index (0xF00000
#include "minosoft:color" #include "minosoft:color"
uniform uint uLight; uniform uint uTintColor;
void main() { void main() {
run_skeletal(floatBitsToUint(vinTransformNormal), vinPosition); run_skeletal(floatBitsToUint(vinTransformNormal), vinPosition);
run_animation(); run_animation();
finTintColor *= getRGBColor(uLight & 0xFFFFFFu); finTintColor *= getRGBColor(uTintColor & 0xFFFFFFu);
} }