@@ -39,7 +39,7 @@ export function rotate(q: ReadonlyQuat, out: Mat4 = mat4.create()): Mat4 {
3939
4040/**
4141 * Returns a {@link Mat4} for a 3D rotation about the x-axis in couterclockwise direction.
42- * see: https://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations
42+ * @ see https://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations
4343 */
4444export function rotateX ( theta : Float , out : Mat4 = mat4 . create ( ) ) : Mat4 {
4545 mat4 . id ( out ) ;
@@ -51,7 +51,7 @@ export function rotateX(theta: Float, out: Mat4 = mat4.create()): Mat4 {
5151
5252/**
5353 * Returns a {@link Mat4} for a 3D rotation about the y-axis in couterclockwise direction.
54- * see: https://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations
54+ * @ see https://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations
5555 */
5656export function rotateY ( theta : Float , out : Mat4 = mat4 . create ( ) ) : Mat4 {
5757 mat4 . id ( out ) ;
@@ -63,7 +63,7 @@ export function rotateY(theta: Float, out: Mat4 = mat4.create()): Mat4 {
6363
6464/**
6565 * Returns a {@link Mat4} for a 3D rotation about the z-axis in couterclockwise direction.
66- * see: https://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations
66+ * @ see https://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations
6767 */
6868export function rotateZ ( theta : Float , out : Mat4 = mat4 . create ( ) ) : Mat4 {
6969 mat4 . id ( out ) ;
@@ -75,7 +75,7 @@ export function rotateZ(theta: Float, out: Mat4 = mat4.create()): Mat4 {
7575
7676/**
7777 * Returns a {@link Mat4} for a 3D rotation about a given unit axis in couterclockwise direction.
78- * see: https://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations
78+ * @ see https://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations
7979 */
8080export function rotateAxis ( axis : ReadonlyVec3 , theta : Float , out : Mat4 = mat4 . create ( ) ) : Mat4 {
8181 const
@@ -121,6 +121,42 @@ export function transform(translation: ReadonlyVec3, rotation: ReadonlyQuat, sca
121121 return out ;
122122}
123123
124+ /**
125+ * Returns the inverse of a {@link ReadonlyMat4} that represents a valid transformation in TRS order (= translation * rotation * scale).
126+ * This function is more efficient than {@link mat4.invert} by using the properties of a TRS matrix.
127+ * @returns out = M^-1
128+ */
129+ export function inverseTransform ( m : ReadonlyMat4 , out : Mat4 = mat4 . create ( ) ) : Mat4 {
130+ // Assume M is a TRS matrix:
131+ // M = T * R * S = [RS t]
132+ // [0 1]
133+ // Then the inverse of M is:
134+ // M^-1 = [(RS)^-1 (RS)^-1 * -t]
135+ // [ 0 1 ]
136+ // Where: (RS)^-1 = S^-1 * R^-1 = S^-1 * RT = S^-1 * ((RS)(S^-1))T = S^-1 * (S^-1)T * (RS)T = S^-1 * S^-1 * (RS)T
137+
138+ // Calculate output = (RS)T
139+ mat4 . transpose ( m , out ) ;
140+ unchecked ( out [ 3 ] = out [ 7 ] = out [ 11 ] = 0 ) ;
141+
142+ // Extract S and premultiply S^-2 = 1/(S*S) to output
143+ scaleOf ( m , v1 ) ;
144+ for ( let i = 0 ; i < 3 ; ++ i ) {
145+ for ( let j = 0 ; j < 3 ; ++ j ) {
146+ unchecked ( out [ 4 * i + j ] *= 1 / ( v1 [ j ] * v1 [ j ] ) ) ;
147+ }
148+ }
149+
150+ // With output = (RS)^-1, apply translation = (output * -t) to output
151+ array . copy (
152+ vec3 . mmul4 ( out , vec3 . scale ( array . copy ( m , v0 , 12 , 0 , 3 ) as Vec3 , - 1 ) ) ,
153+ out ,
154+ 0 , 12 , 3
155+ ) ;
156+
157+ return out ;
158+ }
159+
124160// -- Transformation matrix decomposition --
125161
126162/**
@@ -131,7 +167,7 @@ export function translationOf(m: ReadonlyMat4, out: Vec3 = vec3.create()): Vec3
131167}
132168
133169/**
134- * Extract the {@link Vec3} scaling components from an affine transformation matrix.
170+ * Extract the {@link Vec3} scaling components from a transformation matrix in TRS order (= translation * rotation * scale) .
135171 */
136172export function scaleOf ( m : ReadonlyMat4 , out : Vec3 = vec3 . create ( ) ) : Vec3 {
137173 for ( let i = 0 ; i < 3 ; ++ i ) {
@@ -144,7 +180,7 @@ export function scaleOf(m: ReadonlyMat4, out: Vec3 = vec3.create()): Vec3 {
144180}
145181
146182/**
147- * Extract the {@link Quat} rotation components from an affine transformation matrix.
183+ * Extract the {@link Quat} rotation components from a transformation matrix in TRS order (= translation * rotation * scale) .
148184 * @see https://en.wikipedia.org/wiki/Rotation_matrix#Quaternion
149185 */
150186export function rotationOf ( m : ReadonlyMat4 , out : Quat = quat . create ( ) ) : Quat {
0 commit comments