123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- -- everything in this file is licensed under CC0
- -- see also minetest PR #8515
- matrix3 = {}
- function matrix3.new(a, ...)
- if not a then
- return {0, 0, 0, 0, 0, 0, 0, 0, 0}
- elseif type(a) ~= "table" then
- return {a, ...}
- else
- return {a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9]}
- end
- end
- matrix3.identity = {1, 0, 0, 0, 1, 0, 0, 0, 1}
- function matrix3.apply(m, func)
- local mr = {}
- for i = 1, 9 do
- mr[i] = func(m[i])
- end
- return mr
- end
- function matrix3.equals(m1, m2)
- for i = 1, 9 do
- if m1[i] ~= m2[i] then
- return false
- end
- end
- return true
- end
- function matrix3.index(m, l, c)
- return m[(l - 1) * 3 + c]
- end
- function matrix3.add(m1, m2)
- local m3 = {}
- for i = 1, 9 do
- m3[i] = m1[i] + m2[i]
- end
- return m3
- end
- local function multiply_matrix3_scalar(m, a)
- local mr = {}
- for i = 1, 9 do
- mr[i] = m[i] * a
- end
- return mr
- end
- local function multiply_matrix3_vector(m1, v)
- return {
- x = m1[1] * v.x + m1[2] * v.y + m1[3] * v.z,
- y = m1[4] * v.x + m1[5] * v.y + m1[6] * v.z,
- z = m1[7] * v.x + m1[8] * v.y + m1[9] * v.z,
- }
- end
- function matrix3.multiply(m1, m2)
- if type(m2) ~= "table" then
- return multiply_matrix3_scalar(m1, m2)
- elseif m2.x then
- return multiply_matrix3_vector(m1, m2)
- end
- local m3 = {}
- for l = 1, 3 do
- for c = 1, 3 do
- local i = (l - 1) * 3 + c
- m3[i] = 0
- for k = 1, 3 do
- m3[i] = m3[i] + m1[(l - 1) * 3 + k] * m2[(k - 1) * 3 + c]
- end
- end
- end
- return m3
- end
- function matrix3.tensor_multiply(a, b)
- local m1 = matrix3.new()
- m1[1] = a.x
- m1[4] = a.y
- m1[7] = a.z
- local m2 = matrix3.new()
- m2[1] = a.x
- m2[2] = a.y
- m2[3] = a.z
- return matrix3.multiply(m1, m2)
- end
- function matrix3.transpose(m)
- return {m[1], m[4], m[7],
- m[2], m[5], m[8],
- m[3], m[6], m[9]}
- end
- function matrix3.determinant(m)
- return m[1] * (m[5] * m[9] - m[6] * m[8])
- + m[2] * (m[6] * m[7] - m[4] * m[9])
- + m[3] * (m[4] * m[8] - m[5] * m[7])
- end
- function matrix3.invert(a)
- local t11 = a[5] * a[9] - a[6] * a[8]
- local t12 = a[6] * a[7] - a[4] * a[9]
- local t13 = a[4] * a[8] - a[5] * a[7]
- local det = a[1] * t11 + a[2] * t12 + a[3] * t13
- if det == 0 then
- return false -- there is no inverted
- end
- local b = {
- t11 / det, (a[3]*a[8] - a[2]*a[9]) / det, (a[2]*a[6] - a[3]*a[5]) / det,
- t12 / det, (a[1]*a[9] - a[3]*a[7]) / det, (a[3]*a[4] - a[1]*a[6]) / det,
- t13 / det, (a[2]*a[7] - a[1]*a[8]) / det, (a[1]*a[5] - a[2]*a[4]) / det
- }
- return b
- end
- local function sin(x)
- if x % math.pi == 0 then
- return 0
- else
- return math.sin(x)
- end
- end
- local function cos(x)
- if x % math.pi == math.pi / 2 then
- return 0
- else
- return math.cos(x)
- end
- end
- function matrix3.rotation_around_x(angle)
- local s = sin(angle)
- local c = cos(angle)
- return {1, 0, 0,
- 0, c, -s,
- 0, s, c}
- end
- function matrix3.rotation_around_y(angle)
- local s = sin(angle)
- local c = cos(angle)
- return { c, 0, s,
- 0, 1, 0,
- -s, 0, c}
- end
- function matrix3.rotation_around_z(angle)
- local s = sin(angle)
- local c = cos(angle)
- return {c, -s, 0,
- s, c, 0,
- 0, 0, 1}
- end
- function matrix3.rotation_around_vector(v, angle)
- local length_v = vector.length(v)
- v = vector.divide(v, length_v)
- angle = angle or length_v
- local s = sin(angle)
- local c = cos(angle)
- local omc = 1 - c
- return {
- v.x * v.x * omc + c, v.x * v.y * omc - v.z * s, v.x * v.z * omc + v.y * s,
- v.y * v.x * omc + v.z * s, v.y * v.y * omc + c, v.y * v.z * omc - v.x * s,
- v.z * v.x * omc - v.y * s, v.z * v.y * omc + v.x * s, v.z * v.z * omc + c
- }
- end
- function matrix3.to_pitch_yaw_roll(m)
- local r = vector.new()
- r.y = math.atan2(-m[3], m[9])
- local c2 = math.sqrt(m[4]^2 + m[5]^2)
- r.x = math.atan2(m[6], c2)
- local s1 = sin(r.y)
- local c1 = cos(r.y)
- r.z = math.atan2(s1 * m[8] + c1 * m[2], s1 * m[7] + c1 * m[1])
- return r
- end
- function matrix3.from_pitch_yaw_roll(v)
- local sx, cx = sin(v.x), cos(v.x)
- local sy, cy = sin(v.y), cos(v.y)
- local sz, cz = sin(v.z), cos(v.z)
- return {
- -sy * sx * sz + cy * cz, cz * sy * sx + cy * sz, -cx * sy,
- -cx * sz, cx * cz, sx,
- cy * sx * sz + cz * sy, -cy * cz * sx + sy * sz, cy * cx
- }
- end
|