[go: nahoru, domu]

blob: d3ccf46cc49f38c9940e6df127e8d00c939402ea [file] [log] [blame]
/*
* Copyright 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.ui.vectormath64
import kotlin.math.cos
import kotlin.math.sin
import kotlin.math.tan
fun transpose(m: Matrix2) = Matrix2(
Vector2(m.x.x, m.y.x),
Vector2(m.x.y, m.y.y)
)
fun transpose(m: Matrix3) = Matrix3(
Vector3(m.x.x, m.y.x, m.z.x),
Vector3(m.x.y, m.y.y, m.z.y),
Vector3(m.x.z, m.y.z, m.z.z)
)
fun inverse(m: Matrix3): Matrix3 {
val a = m.x.x
val b = m.x.y
val c = m.x.z
val d = m.y.x
val e = m.y.y
val f = m.y.z
val g = m.z.x
val h = m.z.y
val i = m.z.z
val A = e * i - f * h
val B = f * g - d * i
val C = d * h - e * g
val det = a * A + b * B + c * C
return Matrix3.of(
A / det, B / det, C / det,
(c * h - b * i) / det, (a * i - c * g) / det, (b * g - a * h) / det,
(b * f - c * e) / det, (c * d - a * f) / det, (a * e - b * d) / det
)
}
fun transpose(m: Matrix4) = Matrix4(
Vector4(m.x.x, m.y.x, m.z.x, m.w.x),
Vector4(m.x.y, m.y.y, m.z.y, m.w.y),
Vector4(m.x.z, m.y.z, m.z.z, m.w.z),
Vector4(m.x.w, m.y.w, m.z.w, m.w.w)
)
fun inverse(m: Matrix4): Matrix4 {
val result = Matrix4()
var pair0 = m.z.z * m.w.w
var pair1 = m.w.z * m.z.w
var pair2 = m.y.z * m.w.w
var pair3 = m.w.z * m.y.w
var pair4 = m.y.z * m.z.w
var pair5 = m.z.z * m.y.w
var pair6 = m.x.z * m.w.w
var pair7 = m.w.z * m.x.w
var pair8 = m.x.z * m.z.w
var pair9 = m.z.z * m.x.w
var pair10 = m.x.z * m.y.w
var pair11 = m.y.z * m.x.w
result.x.x = pair0 * m.y.y + pair3 * m.z.y + pair4 * m.w.y
result.x.x -= pair1 * m.y.y + pair2 * m.z.y + pair5 * m.w.y
result.x.y = pair1 * m.x.y + pair6 * m.z.y + pair9 * m.w.y
result.x.y -= pair0 * m.x.y + pair7 * m.z.y + pair8 * m.w.y
result.x.z = pair2 * m.x.y + pair7 * m.y.y + pair10 * m.w.y
result.x.z -= pair3 * m.x.y + pair6 * m.y.y + pair11 * m.w.y
result.x.w = pair5 * m.x.y + pair8 * m.y.y + pair11 * m.z.y
result.x.w -= pair4 * m.x.y + pair9 * m.y.y + pair10 * m.z.y
result.y.x = pair1 * m.y.x + pair2 * m.z.x + pair5 * m.w.x
result.y.x -= pair0 * m.y.x + pair3 * m.z.x + pair4 * m.w.x
result.y.y = pair0 * m.x.x + pair7 * m.z.x + pair8 * m.w.x
result.y.y -= pair1 * m.x.x + pair6 * m.z.x + pair9 * m.w.x
result.y.z = pair3 * m.x.x + pair6 * m.y.x + pair11 * m.w.x
result.y.z -= pair2 * m.x.x + pair7 * m.y.x + pair10 * m.w.x
result.y.w = pair4 * m.x.x + pair9 * m.y.x + pair10 * m.z.x
result.y.w -= pair5 * m.x.x + pair8 * m.y.x + pair11 * m.z.x
pair0 = m.z.x * m.w.y
pair1 = m.w.x * m.z.y
pair2 = m.y.x * m.w.y
pair3 = m.w.x * m.y.y
pair4 = m.y.x * m.z.y
pair5 = m.z.x * m.y.y
pair6 = m.x.x * m.w.y
pair7 = m.w.x * m.x.y
pair8 = m.x.x * m.z.y
pair9 = m.z.x * m.x.y
pair10 = m.x.x * m.y.y
pair11 = m.y.x * m.x.y
result.z.x = pair0 * m.y.w + pair3 * m.z.w + pair4 * m.w.w
result.z.x -= pair1 * m.y.w + pair2 * m.z.w + pair5 * m.w.w
result.z.y = pair1 * m.x.w + pair6 * m.z.w + pair9 * m.w.w
result.z.y -= pair0 * m.x.w + pair7 * m.z.w + pair8 * m.w.w
result.z.z = pair2 * m.x.w + pair7 * m.y.w + pair10 * m.w.w
result.z.z -= pair3 * m.x.w + pair6 * m.y.w + pair11 * m.w.w
result.z.w = pair5 * m.x.w + pair8 * m.y.w + pair11 * m.z.w
result.z.w -= pair4 * m.x.w + pair9 * m.y.w + pair10 * m.z.w
result.w.x = pair2 * m.z.z + pair5 * m.w.z + pair1 * m.y.z
result.w.x -= pair4 * m.w.z + pair0 * m.y.z + pair3 * m.z.z
result.w.y = pair8 * m.w.z + pair0 * m.x.z + pair7 * m.z.z
result.w.y -= pair6 * m.z.z + pair9 * m.w.z + pair1 * m.x.z
result.w.z = pair6 * m.y.z + pair11 * m.w.z + pair3 * m.x.z
result.w.z -= pair10 * m.w.z + pair2 * m.x.z + pair7 * m.y.z
result.w.w = pair10 * m.z.z + pair4 * m.x.z + pair9 * m.y.z
result.w.w -= pair8 * m.y.z + pair11 * m.z.z + pair5 * m.x.z
val determinant = m.x.x * result.x.x + m.y.x * result.x.y +
m.z.x * result.x.z + m.w.x * result.x.w
return result / determinant
}
fun scale(s: Vector3) = Matrix4(Vector4(x = s.x), Vector4(y = s.y), Vector4(z = s.z))
fun scale(m: Matrix4) = scale(m.scale)
fun translation(t: Vector3) = Matrix4(w = Vector4(t, 1.0f))
fun translation(m: Matrix4) = translation(m.translation)
fun rotation(m: Matrix4) = Matrix4(normalize(m.right), normalize(m.up), normalize(m.forward))
fun rotation(d: Vector3): Matrix4 {
val r = transform(d, ::radians)
val c = transform(r, { x -> cos(x) })
val s = transform(r, { x -> sin(x) })
return Matrix4.of(
c.y * c.z, -c.x * s.z + s.x * s.y * c.z, s.x * s.z + c.x * s.y * c.z, 0.0f,
c.y * s.z, c.x * c.z + s.x * s.y * s.z, -s.x * c.z + c.x * s.y * s.z, 0.0f,
-s.y, s.x * c.y, c.x * c.y, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f
)
}
fun rotation(axis: Vector3, angle: Float): Matrix4 {
val x = axis.x
val y = axis.y
val z = axis.z
val r = radians(angle)
val c = cos(r)
val s = sin(r)
val d = 1.0f - c
return Matrix4.of(
x * x * d + c, x * y * d - z * s, x * y * d + y * s, 0.0f,
y * x * d + z * s, y * y * d + c, y * z * d - x * s, 0.0f,
z * x * d - y * s, z * y * d + x * s, z * z * d + c, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f
)
}
fun normal(m: Matrix4) = scale(1.0f / Vector3(length2(m.right),
length2(m.up), length2(m.forward))) * m
fun lookAt(eye: Vector3, target: Vector3, up: Vector3 = Vector3(z = 1.0f)): Matrix4 {
return lookTowards(eye, target - eye, up)
}
fun lookTowards(eye: Vector3, forward: Vector3, up: Vector3 = Vector3(z = 1.0f)): Matrix4 {
val f = normalize(forward)
val r = normalize(f x up)
val u = normalize(r x f)
return Matrix4(Vector4(r), Vector4(u), Vector4(f), Vector4(eye, 1.0f))
}
fun perspective(fov: Float, ratio: Float, near: Float, far: Float): Matrix4 {
val t = 1.0f / tan(radians(fov) * 0.5f)
val a = (far + near) / (far - near)
val b = (2.0f * far * near) / (far - near)
val c = t / ratio
return Matrix4(Vector4(x = c), Vector4(y = t), Vector4(z = a, w = 1.0f), Vector4(z = -b))
}
fun ortho(l: Float, r: Float, b: Float, t: Float, n: Float, f: Float) = Matrix4(
Vector4(x = 2.0f / (r - 1.0f)),
Vector4(y = 2.0f / (t - b)),
Vector4(z = -2.0f / (f - n)),
Vector4(-(r + l) / (r - l), -(t + b) / (t - b), -(f + n) / (f - n), 1.0f)
)