You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
156 lines
3.8 KiB
156 lines
3.8 KiB
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
|
|
"""
|
|
**Project Name:** MakeHuman
|
|
|
|
**Product Home Page:** http://www.makehumancommunity.org/
|
|
|
|
**Github Code Home Page:** https://github.com/makehumancommunity/
|
|
|
|
**Authors:** Glynn Clements
|
|
|
|
**Copyright(c):** MakeHuman Team 2001-2020
|
|
|
|
**Licensing:** AGPL3
|
|
|
|
This file is part of MakeHuman Community (www.makehumancommunity.org).
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU Affero General Public License as
|
|
published by the Free Software Foundation, either version 3 of the
|
|
License, or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU Affero General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Affero General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
Abstract
|
|
--------
|
|
|
|
Numpy powered matrix transformations.
|
|
"""
|
|
|
|
import math
|
|
|
|
import numpy as np
|
|
|
|
|
|
def transform(m, v):
|
|
return np.asarray(m * np.asmatrix(v).T)[:, 0]
|
|
|
|
|
|
def transform3(m, v):
|
|
x, y, z = v
|
|
v = np.asmatrix((x, y, z, 1)).T
|
|
v = np.asarray(m * v)[:, 0]
|
|
return v[:3] / v[3]
|
|
|
|
|
|
def magnitude(v):
|
|
return math.sqrt(np.sum(v**2))
|
|
|
|
|
|
def normalize(v):
|
|
m = magnitude(v)
|
|
if m == 0:
|
|
return v
|
|
return v / m
|
|
|
|
|
|
def ortho(l1, r1, b1, t1, n1, f1):
|
|
dx = r1 - l1
|
|
dy = t1 - b1
|
|
dz = f1 - n1
|
|
rx = -(r1 + l1) / (r1 - l1)
|
|
ry = -(t1 + b1) / (t1 - b1)
|
|
rz = -(f1 + n1) / (f1 - n1)
|
|
return np.matrix(
|
|
[[2.0 / dx, 0, 0, rx], [0, 2.0 / dy, 0, ry], [0, 0, -2.0 / dz, rz], [0, 0, 0, 1]]
|
|
)
|
|
|
|
|
|
def perspective(fovy, aspect, n, f):
|
|
s = 1.0 / math.tan(math.radians(fovy) / 2.0)
|
|
sx, sy = s / aspect, s
|
|
zz = (f + n) / (n - f)
|
|
zw = 2 * f * n / (n - f)
|
|
return np.matrix([[sx, 0, 0, 0], [0, sy, 0, 0], [0, 0, zz, zw], [0, 0, -1, 0]])
|
|
|
|
|
|
def frustum(x0, x1, y0, y1, z0, z1):
|
|
a = (x1 + x0) / (x1 - x0)
|
|
b = (y1 + y0) / (y1 - y0)
|
|
c = -(z1 + z0) / (z1 - z0)
|
|
d = -2 * z1 * z0 / (z1 - z0)
|
|
sx = 2 * z0 / (x1 - x0)
|
|
sy = 2 * z0 / (y1 - y0)
|
|
return np.matrix([[sx, 0, a, 0], [0, sy, b, 0], [0, 0, c, d], [0, 0, -1, 0]])
|
|
|
|
|
|
def translate(xyz):
|
|
x, y, z = xyz
|
|
return np.matrix([[1, 0, 0, x], [0, 1, 0, y], [0, 0, 1, z], [0, 0, 0, 1]])
|
|
|
|
|
|
def scale(xyz):
|
|
x, y, z = xyz
|
|
return np.matrix([[x, 0, 0, 0], [0, y, 0, 0], [0, 0, z, 0], [0, 0, 0, 1]])
|
|
|
|
|
|
def _sincos(a):
|
|
a = math.radians(a)
|
|
return math.sin(a), math.cos(a)
|
|
|
|
|
|
def rotate(a, xyz):
|
|
x, y, z = normalize(xyz)
|
|
s, c = _sincos(a)
|
|
nc = 1 - c
|
|
return np.matrix(
|
|
[
|
|
[x * x * nc + c, x * y * nc - z * s, x * z * nc + y * s, 0],
|
|
[y * x * nc + z * s, y * y * nc + c, y * z * nc - x * s, 0],
|
|
[x * z * nc - y * s, y * z * nc + x * s, z * z * nc + c, 0],
|
|
[0, 0, 0, 1],
|
|
]
|
|
)
|
|
|
|
|
|
def rotx(a):
|
|
s, c = _sincos(a)
|
|
return np.matrix([[1, 0, 0, 0], [0, c, -s, 0], [0, s, c, 0], [0, 0, 0, 1]])
|
|
|
|
|
|
def roty(a):
|
|
s, c = _sincos(a)
|
|
return np.matrix([[c, 0, s, 0], [0, 1, 0, 0], [-s, 0, c, 0], [0, 0, 0, 1]])
|
|
|
|
|
|
def rotz(a):
|
|
s, c = _sincos(a)
|
|
return np.matrix([[c, -s, 0, 0], [s, c, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]])
|
|
|
|
|
|
def lookat(eye, target, up):
|
|
F = target[:3] - eye[:3]
|
|
f = normalize(F)
|
|
U = normalize(up[:3])
|
|
s = np.cross(f, U)
|
|
u = np.cross(s, f)
|
|
M = np.matrix(np.identity(4))
|
|
M[:3, :3] = np.vstack([s, u, -f])
|
|
T = translate(-eye)
|
|
return M * T
|
|
|
|
|
|
def viewport(x, y, w, h):
|
|
x, y, w, h = list(map(float, (x, y, w, h)))
|
|
return np.matrix(
|
|
[[w / 2, 0, 0, x + w / 2], [0, h / 2, 0, y + h / 2], [0, 0, 0.5, 0.5], [0, 0, 0, 1]]
|
|
)
|