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

commonMain.ru.casperix.math.transform.float64.Transform3d.kt Maven / Gradle / Ivy

package ru.casperix.math.transform.float64

import ru.casperix.math.quaternion.float64.QuaternionDouble
import ru.casperix.math.interpolation.float64.InterpolateDoubleFunction
import ru.casperix.math.interpolation.float64.InterpolationDouble
import ru.casperix.math.interpolation.float64.linearInterpolate
import ru.casperix.math.quad_matrix.float64.Matrix4d
import ru.casperix.math.vector.float64.Vector3d
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient

@Serializable
data class Transform3d(val position: Vector3d = Vector3d.ZERO, val scale: Vector3d = Vector3d.ONE, val rotation: QuaternionDouble = QuaternionDouble.IDENTITY) {
	@Transient
	private var cacheMatrix: Matrix4d? = null

	fun getMatrix(): Matrix4d {
		cacheMatrix?.let {
			return it
		}
		val result = Matrix4d.compose(position, scale, rotation)
		cacheMatrix = result
		return result
	}

	fun getLocalX(): Vector3d {
		return getLocalX(rotation)
	}

	fun getLocalY(): Vector3d {
		return getLocalY(rotation)
	}

	fun getLocalZ(): Vector3d {
		return getLocalZ(rotation)
	}

	fun isFinite(): Boolean {
		return rotation.isFinite() && position.isFinite() && scale.isFinite()
	}

	companion object {
		val IDENTITY = Transform3d(Vector3d.ZERO, Vector3d.ONE, QuaternionDouble.IDENTITY)

		fun interpolate(A: Transform3d, B: Transform3d, factor: Double, interpolator: InterpolateDoubleFunction = linearInterpolate): Transform3d {
			val pos = InterpolationDouble.vector3(A.position, B.position, factor, interpolator)
			val scale = InterpolationDouble.vector3(A.scale, B.scale, factor, interpolator)
			val Q = InterpolationDouble.quaternion(A.rotation, B.rotation, factor)
			return Transform3d(pos, scale, Q)
		}

		fun getLocalX(orientation: QuaternionDouble): Vector3d {
			return orientation.transform(Vector3d.X).normalize()
		}

		fun getLocalY(orientation: QuaternionDouble): Vector3d {
			return orientation.transform(Vector3d.Y).normalize()
		}

		fun getLocalZ(orientation: QuaternionDouble): Vector3d {
			return orientation.transform(Vector3d.Z).normalize()
		}

		fun fromYAxis(position: Vector3d, yAxis: Vector3d, zAxis: Vector3d): Transform3d {
			val yAxisN = yAxis.normalize()
			val xAxisN = yAxis.cross(zAxis).normalize()
			val zAxisN = xAxisN.cross(yAxisN)
			return Transform3d(position, Vector3d.ONE, QuaternionDouble.fromAxis(xAxisN, yAxisN, zAxisN))
		}

		fun fromXAxis(position: Vector3d, xAxis: Vector3d, zAxis: Vector3d): Transform3d {
			val xAxisN = xAxis.normalize()
			val yAxisN = zAxis.cross(xAxis).normalize()
			val zAxisN = xAxisN.cross(yAxisN)
			return Transform3d(position, Vector3d.ONE, QuaternionDouble.fromAxis(xAxisN, yAxisN, zAxisN))
		}

		fun fromZAxis(position: Vector3d, zAxis: Vector3d, yAxis: Vector3d): Transform3d {
			val zAxisN = zAxis.normalize()
			val xAxisN = yAxis.cross(zAxis).normalize()
			val yAxisN = zAxisN.cross(xAxisN)
			return Transform3d(position, Vector3d.ONE, QuaternionDouble.fromAxis(xAxisN, yAxisN, zAxisN))
		}
	}

}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy