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

commonMain.ru.casperix.math.camera.CameraTransform2f.kt Maven / Gradle / Ivy

package ru.casperix.math.camera

import ru.casperix.math.axis_aligned.float32.Box2f
import ru.casperix.math.axis_aligned.int32.Dimension2i
import ru.casperix.math.quad_matrix.float32.Matrix3f
import ru.casperix.math.quad_matrix.float32.Matrix4f
import ru.casperix.math.vector.float32.Vector2f
import ru.casperix.math.vector.float32.Vector3f

data class CameraTransform2f(
    val projection: Matrix3f,
    val view: Matrix3f,
    val viewport: Dimension2i,
) {
    private val projectionView = view * projection
    private val projectionViewInversed = projectionView.inverse()


    fun unproject(screenPosition: Vector2f): Vector2f {
        val screenPositionNormalized = Vector2f(
            2.0f * screenPosition.x / viewport.width - 1.0f,
            2.0f * (viewport.height - screenPosition.y) / viewport.height - 1.0f,
        )
        val worldPosition = projection(screenPositionNormalized, projectionViewInversed)
        if (worldPosition.isFinite()) return worldPosition
        return Vector2f.ZERO
    }


    fun project(worldPosition: Vector2f): Vector2f {
        val screenPositionNormalized = projection(worldPosition, projectionView)
        val screenPosition = Vector2f(
            viewport.width * (screenPositionNormalized.x + 1.0f) / 2.0f,
            viewport.height * (screenPositionNormalized.y + 1.0f) / 2.0f,
        )

        if (screenPosition.isFinite()) return screenPosition
        return Vector2f.ZERO
    }

    fun getViewportInObjectSpace(): Box2f {
        val start = unproject(Vector2f.ZERO)
        val finish = unproject(viewport.toVector2f())
        return Box2f.byCorners(start, finish)
    }

    fun getViewport(): Box2f {
        val start = Vector2f.ZERO
        val finish = viewport.toVector2f()
        return Box2f.byCorners(start, finish)
    }

    fun getTranslate(): Vector2f {
        return view.getTranslate()
    }

    private fun projection(self: Vector2f, matrix: Matrix3f): Vector2f {
        val table = matrix.data
        val factor = 1.0f / (self.x * table[2] + self.y * table[5]  + table[8])
        return Vector2f(
            (self.x * table[0] + self.y * table[3] + table[6]) * factor,
            (self.x * table[1] + self.y * table[4] + table[7]) * factor,
        )
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy