All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.casperix.scene.camera.orbital.OrbitalCameraSmoother.kt Maven / Gradle / Ivy

The newest version!
package casperix.scene.camera.orbital

import casperix.math.vector.asSpherical
import casperix.math.vector.float64.Vector2d
import casperix.math.vector.float64.Vector3d
import casperix.misc.DisposableHolder
import casperix.misc.clamp
import casperix.signals.concrete.Future
import casperix.signals.then
import kotlin.math.PI

class OrbitalCameraSmoother(val nextFrameFuture: Future, var frictionFactor: Double = 0.6, var elasticityFactor: Double = 0.6, val outputTransform: (state: OrbitalCameraState) -> Unit) : DisposableHolder() {
	private var current: OrbitalCameraState? = null
	private var finish: OrbitalCameraState? = null

	private var offsetSpeed = Vector3d.ZERO
	private var pivotSpeed = Vector2d.ZERO

	init {
		nextFrameFuture.then(components) {
			update()
		}
	}

	private fun update() {
		val current = current ?: return
		val finish = finish ?: return

		val RVH = finish.offset.asVector3d() - current.offset.asVector3d()
		val range = RVH.x
		val vAngle = RVH.y
		val hAngle = RVH.z

		val deltaOffset = Vector3d(range, prepareAngleForInterpolate(vAngle), prepareAngleForInterpolate(hAngle))
		val deltaPivot = finish.pivot - current.pivot

		val elasticityFactor = elasticityFactor.clamp(0.0, 1.0)
		val frictionFactor = frictionFactor.clamp(0.0, 1.0)

		offsetSpeed += deltaOffset * elasticityFactor * (1.0 - frictionFactor) - offsetSpeed * elasticityFactor
		pivotSpeed += deltaPivot * elasticityFactor * (1.0 - frictionFactor) - pivotSpeed * elasticityFactor

		val next = OrbitalCameraState(current.pivot + pivotSpeed, (current.offset.asVector3d() + offsetSpeed).asSpherical())
		this.current = next
		outputTransform(next)
	}

	private fun prepareAngleForInterpolate(factor: Double): Double {
		return (factor + 9.0 * PI) % (2.0 * PI) - PI
	}

	fun inputState(state: OrbitalCameraState) {
		if (current == null) {
			current = state
		}
		finish = state
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy