/****************************************************************************** Copyright (C) 2013 by Hugh Bailey This program is free software: you can redistribute it and/or modify it under the terms of the GNU 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ******************************************************************************/ #include #include "matrix3.h" #include "matrix4.h" #include "plane.h" #include "quat.h" void matrix3_from_quat(struct matrix3 *dst, const struct quat *q) { float norm = quat_dot(q, q); float s = (norm > 0.0f) ? (2.0f/norm) : 0.0f; float xx = q->x * q->x * s; float yy = q->y * q->y * s; float zz = q->z * q->z * s; float xy = q->x * q->y * s; float xz = q->x * q->z * s; float yz = q->y * q->z * s; float wx = q->w * q->x * s; float wy = q->w * q->y * s; float wz = q->w * q->z * s; dst->x.x = 1.0f - (yy + zz); dst->x.y = xy + wz; dst->x.z = xz - wy; dst->x.w = 0.0f; dst->y.x = xy - wz; dst->y.y = 1.0f - (xx + zz); dst->y.z = yz + wx; dst->y.w = 0.0f; dst->z.x = xz + wy; dst->z.y = yz - wx; dst->z.z = 1.0f - (xx + yy); dst->z.w = 0.0f; vec3_zero(&dst->t); } void matrix3_from_axisang(struct matrix3 *dst, const struct axisang *aa) { struct quat q; quat_from_axisang(&q, aa); matrix3_from_quat(dst, &q); } void matrix3_from_matrix4(struct matrix3 *dst, const struct matrix4 *m) { dst->x.m = m->x.m; dst->y.m = m->y.m; dst->z.m = m->z.m; dst->t.m = m->t.m; dst->x.w = 0.0f; dst->y.w = 0.0f; dst->z.w = 0.0f; dst->t.w = 0.0f; } void matrix3_mul(struct matrix3 *dst, const struct matrix3 *m1, const struct matrix3 *m2) { vec3_rotate(&dst->x, &m1->x, m2); vec3_rotate(&dst->y, &m1->y, m2); vec3_rotate(&dst->z, &m1->z, m2); vec3_transform(&dst->t, &m1->t, m2); } void matrix3_rotate(struct matrix3 *dst, const struct matrix3 *m, const struct quat *q) { struct matrix3 temp; matrix3_from_quat(&temp, q); matrix3_mul(dst, m, &temp); } void matrix3_rotate_aa(struct matrix3 *dst, const struct matrix3 *m, const struct axisang *aa) { struct matrix3 temp; matrix3_from_axisang(&temp, aa); matrix3_mul(dst, m, &temp); } void matrix3_scale(struct matrix3 *dst, const struct matrix3 *m, const struct vec3 *v) { vec3_mul(&dst->x, &m->x, v); vec3_mul(&dst->y, &m->y, v); vec3_mul(&dst->z, &m->z, v); vec3_mul(&dst->t, &m->t, v); } void matrix3_transpose(struct matrix3 *dst, const struct matrix3 *m) { __m128 tmp1, tmp2; vec3_transform(&dst->t, &m->t, m); vec3_neg(&dst->t, &dst->t); tmp1 = _mm_movelh_ps(m->x.m, m->y.m); tmp2 = _mm_movehl_ps(m->y.m, m->x.m); dst->x.m = _mm_shuffle_ps(tmp1, m->z.m, _MM_SHUFFLE(3, 0, 2, 0)); dst->y.m = _mm_shuffle_ps(tmp1, m->z.m, _MM_SHUFFLE(3, 1, 3, 1)); dst->z.m = _mm_shuffle_ps(tmp2, m->z.m, _MM_SHUFFLE(3, 2, 2, 0)); } void matrix3_inv(struct matrix3 *dst, const struct matrix3 *m) { matrix4_inv((struct matrix4*)dst, (struct matrix4*)m); } void matrix3_mirror(struct matrix3 *dst, const struct matrix3 *m, const struct plane *p) { vec3_mirrorv(&dst->x, &m->x, &p->dir); vec3_mirrorv(&dst->y, &m->y, &p->dir); vec3_mirrorv(&dst->z, &m->z, &p->dir); vec3_mirror(&dst->t, &m->t, p); } void matrix3_mirrorv(struct matrix3 *dst, const struct matrix3 *m, const struct vec3 *v) { vec3_mirrorv(&dst->x, &m->x, v); vec3_mirrorv(&dst->y, &m->y, v); vec3_mirrorv(&dst->z, &m->z, v); vec3_mirrorv(&dst->t, &m->t, v); }