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

commonMain.ru.casperix.demo_platform.camera.OrthographicCameraController.kt Maven / Gradle / Ivy

package ru.casperix.demo_platform.camera

import ru.casperix.input.*
import ru.casperix.math.axis_aligned.float32.Box2f
import ru.casperix.math.axis_aligned.int32.Dimension2i
import ru.casperix.math.camera.OrthographicCamera2f
import ru.casperix.math.vector.float32.Vector2f
import ru.casperix.math.vector.int32.Vector2i
import ru.casperix.misc.clamp

class OrthographicCameraController(val camera: OrthographicCamera2f, val config: CameraConfig) {
    private var zoomFactor = 1.1f
    private var startPoint: Vector2i? = null
    private val translateButton = PointerButton.RIGHT

    init {
        //  apply camera limits:
        setZoom(camera.zoom)
        setPosition(camera.position)
    }

    fun update(viewport: Dimension2i) {
        camera.viewport = viewport
    }

    fun input(event: InputEvent) {
        when (event) {
            is PointerDown -> if (translateButton == event.button) {
                startPoint = event.position.roundToVector2i()
                event.captured = true
            }

            is PointerUp -> if (translateButton == event.button) {
                startPoint = null
                event.captured = true
            }

            is PointerMove -> {
                val lastPoint = startPoint ?: return
                val currentPoint = event.position.roundToVector2i()

                val delta = (currentPoint - lastPoint) * Vector2i(1, -1)
                startPoint = currentPoint
                setPosition(camera.position - delta.toVector2f() * camera.zoom)
                event.captured = true
            }

            is MouseWheel -> {
                val wheelOffset = event.wheel.y
                if (wheelOffset != 0f) {
                    val factor = if (wheelOffset < 0) zoomFactor
                    else 1f / zoomFactor
                    setZoom(camera.zoom * factor)
                }
            }
        }
    }

    private fun setPosition(value: Vector2f) {
        camera.position = if (config.bound != null) {
            bound(value, config.bound)
        } else {
            value
        }
    }

    private fun bound(value: Vector2f, bound: Box2f): Vector2f {
        val min = bound.min
        val max = bound.max
        var result = value
        if (result.x < min.x) result = result.copy(x = min.x)
        if (result.y < min.y) result = result.copy(y = min.y)
        if (result.x > max.x) result = result.copy(x = max.x)
        if (result.y > max.y) result = result.copy(y = max.y)
        return result
    }

    private fun setZoom(value: Float) {
        camera.zoom = value.coerceIn(config.zoomRanges)
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy