![JAR search and dependency download from the Maven repository](/logo.png)
commonMain.ru.casperix.math.camera.CameraTransform3f.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.Matrix4f
import ru.casperix.math.vector.float32.Vector2f
import ru.casperix.math.vector.float32.Vector3f
data class CameraTransform3f(
val projection: Matrix4f,
val view: Matrix4f,
val viewport: Dimension2i,
val near: Float,
val far: Float,
) {
private val projectionView = view * projection
private val projectionViewInversed = projectionView.inverse()
fun unproject(screenPosition: Vector2f): Vector3f {
return unproject(screenPosition.expand(0f))
}
fun unproject(screenPosition: Vector3f): Vector3f {
val screenPositionNormalized = Vector3f(
2.0f * screenPosition.x / viewport.width - 1.0f,
2.0f * (viewport.height - screenPosition.y) / viewport.height - 1.0f,
2.0f * screenPosition.z - 1.0f,
)
val worldPosition = projection(screenPositionNormalized, projectionViewInversed)
if (worldPosition.isFinite()) return worldPosition
return Vector3f.ZERO
}
fun project(worldPosition: Vector2f): Vector3f {
return project(worldPosition.expand(0f))
}
fun project(worldPosition: Vector3f): Vector3f {
val screenPositionNormalized = projection(worldPosition, projectionView)
val screenPosition = Vector3f(
viewport.width * (screenPositionNormalized.x + 1.0f) / 2.0f,
viewport.height * (screenPositionNormalized.y + 1.0f) / 2.0f,
(screenPositionNormalized.z + 1.0f) / 2.0f,
)
if (screenPosition.isFinite()) return screenPosition
return Vector3f.ZERO
}
fun getViewportInObjectSpace(): Box2f {
val start = unproject(Vector3f.ZERO)
val finish = unproject(viewport.toVector2f().expand(0f))
return Box2f.byCorners(start.getXY(), finish.getXY())
}
fun getViewport(): Box2f {
val start = Vector2f.ZERO
val finish = viewport.toVector2f()
return Box2f.byCorners(start, finish)
}
fun getTranslate(): Vector3f {
return view.getTranslate()
}
private fun projection(self: Vector3f, matrix: Matrix4f): Vector3f {
val table = matrix.data
val factor = 1.0f / (self.x * table[3] + self.y * table[7] + self.z * table[11] + table[15])
return Vector3f(
(self.x * table[0] + self.y * table[4] + self.z * table[8] + table[12]) * factor,
(self.x * table[1] + self.y * table[5] + self.z * table[9] + table[13]) * factor,
(self.x * table[2] + self.y * table[6] + self.z * table[10] + table[14]) * factor
)
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy