diff --git a/src/main/java/de/bixilon/minosoft/config/profile/profiles/rendering/camera/shaking/ShakingC.kt b/src/main/java/de/bixilon/minosoft/config/profile/profiles/rendering/camera/shaking/ShakingC.kt index 9240c52df8..8774a41229 100644 --- a/src/main/java/de/bixilon/minosoft/config/profile/profiles/rendering/camera/shaking/ShakingC.kt +++ b/src/main/java/de/bixilon/minosoft/config/profile/profiles/rendering/camera/shaking/ShakingC.kt @@ -23,7 +23,8 @@ class ShakingC(profile: RenderingProfile) { */ var enabled by BooleanDelegate(profile, true) - var amplifier by FloatDelegate(profile, 1.0f, "", ranges = arrayOf(0.1f..2.0f)) + var speed by FloatDelegate(profile, 1.0f, "", ranges = arrayOf(0.1f..2.0f)) + var intensity by FloatDelegate(profile, 1.0f, "", ranges = arrayOf(0.1f..2.0f)) /** * Shake the camera while walking diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/camera/MatrixHandler.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/camera/MatrixHandler.kt index 04f23479b2..9e88784b02 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/camera/MatrixHandler.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/camera/MatrixHandler.kt @@ -109,14 +109,14 @@ class MatrixHandler( fun draw() { dynamicFOV += camera.view.view.fovMultiplier - shaking.draw() + val shaking = shaking.update() val fov = calculateFOV() val view = camera.view.view val eyePosition = view.eyePosition context.camera.offset.draw() val matrixPosition = Vec3(eyePosition - context.camera.offset.offset) val front = view.front - if (upToDate && matrixPosition == this.matrixPosition && front == this.front && fov == previousFOV && shaking.isEmpty) { + if (!shaking && upToDate && matrixPosition == this.matrixPosition && front == this.front && fov == previousFOV) { return } this.matrixPosition = matrixPosition diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/camera/shaking/CameraShaking.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/camera/shaking/CameraShaking.kt index b3133412dd..a00a1b4d0f 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/camera/shaking/CameraShaking.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/camera/shaking/CameraShaking.kt @@ -20,44 +20,81 @@ import de.bixilon.kutil.avg.FloatAverage import de.bixilon.kutil.time.TimeUtil.millis import de.bixilon.minosoft.config.profile.profiles.rendering.camera.shaking.ShakingC import de.bixilon.minosoft.gui.rendering.camera.Camera -import de.bixilon.minosoft.gui.rendering.renderer.drawable.Drawable import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition import kotlin.math.sin class CameraShaking( private val camera: Camera, private val profile: ShakingC, -) : Drawable { - private var rotation = 0.0f - private var strength = FloatAverage(5 * ProtocolDefinition.TICK_TIME * 1_000_000L, 1.0f) +) { + private var cameraTransform: Mat4? = Mat4() + private var damaged: Boolean = false private val speed = FloatAverage(5 * ProtocolDefinition.TICK_TIME * 1_000_000L, 0.0f) + private val physics = camera.context.connection.camera.entity.physics - val isEmpty: Boolean get() = rotation == 0.0f - override fun draw() { - this.strength += 1.0f - val strength = this.strength.avg * profile.amplifier // strength affects how far it goes + fun update(): Boolean { + if (this.damaged) { + if (profile.damage) { + this.cameraTransform = updateDamage() + this.damaged = false + return true + } + } + if (profile.walking) { + this.cameraTransform = updateBobbing() + return true - val physics = camera.context.connection.camera.entity.physics - val velocity = physics.velocity.xz.length2().toFloat() // velocity affects how quick it goes - if (velocity > 0.003 && physics.onGround) { - this.speed += velocity - } else { - this.speed += 0.0f // TODO: remove this, kutil 1.21 } - val time = (millis() % 100L).toFloat() / 100.0f + return false + } + + private fun updateBobbing(): Mat4? { + if (!this.physics.onGround) { + this.speed += 0.0f + return null + } + val transform = Mat4() + val time = millis() + this.speed += this.physics.velocity.xz.length2().toFloat() // velocity affects how quick it goes + val speed = minOf(this.speed.avg, 0.25f) + val translation = bobbing(time, speed, TRANSLATION_FREQUENCY * profile.speed, TRANSLATION_STRENGTH * profile.intensity) + val rotation = bobbing(time, speed, ROTATION_FREQUENCY * profile.speed, ROTATION_STRENGTH * profile.intensity) + transform.translateAssign(Vec3(0, translation, 0)) + transform.rotateAssign(rotation, Vec3(0, 0, 1)) + return transform + } - this.rotation = sin(time * minOf(this.speed.avg, 0.5f) / 3.0f) * strength * 0.03f + private fun bobbing(time: Long, speed: Float, frequency: Float, intensity: Float): Float { + val seconds = time / 1000.0 + + val sin = sin(seconds * frequency).toFloat() + return (sin * speed * intensity) / MINIMUM_SPEED + } + + private fun updateDamage(): Mat4 { + val transform = Mat4() + val time = millis() + val rotation = bobbing(time, 0.5f, DAMAGE_FREQUENCY * profile.speed, DAMAGE_STRENGTH * profile.intensity) + transform.rotateAssign(rotation, Vec3(0, 0, 1)) + return transform } fun onDamage() { - strength += 1000.0f - speed += 0.05f + this.damaged = true } fun transform(): Mat4? { - if (rotation == 0.0f) return null - return Mat4() - .rotateAssign(rotation, Vec3(0, 0, 1)) + return cameraTransform + } + + companion object { + private const val DAMAGE_FREQUENCY = 40.0f + private const val DAMAGE_STRENGTH = 0.004f + private const val ROTATION_STRENGTH = 0.002f + private const val ROTATION_FREQUENCY = 10.0f + private const val TRANSLATION_STRENGTH = 0.1f + private const val TRANSLATION_FREQUENCY = 15.0f + private const val MINIMUM_SPEED = 0.1f } }