Michaël Lemaire
ee86e2d251
git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@348 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
402 lines
11 KiB
C
402 lines
11 KiB
C
#include "euclid.h"
|
|
|
|
#include <math.h>
|
|
|
|
#include "tools.h"
|
|
|
|
Vector3 VECTOR_ZERO = {0.0, 0.0, 0.0};
|
|
|
|
void v3Save(PackStream* stream, Vector3* v)
|
|
{
|
|
packWriteFloat(stream, &v->x);
|
|
packWriteFloat(stream, &v->y);
|
|
packWriteFloat(stream, &v->z);
|
|
}
|
|
|
|
void v3Load(PackStream* stream, Vector3* v)
|
|
{
|
|
packReadFloat(stream, &v->x);
|
|
packReadFloat(stream, &v->y);
|
|
packReadFloat(stream, &v->z);
|
|
}
|
|
|
|
Vector3 v3Translate(Vector3 v1, float x, float y, float z)
|
|
{
|
|
Vector3 result;
|
|
result.x = v1.x + x;
|
|
result.y = v1.y + y;
|
|
result.z = v1.z + z;
|
|
return result;
|
|
}
|
|
|
|
Vector3 v3Add(Vector3 v1, Vector3 v2)
|
|
{
|
|
Vector3 result;
|
|
result.x = v1.x + v2.x;
|
|
result.y = v1.y + v2.y;
|
|
result.z = v1.z + v2.z;
|
|
return result;
|
|
}
|
|
|
|
Vector3 v3Sub(Vector3 v1, Vector3 v2)
|
|
{
|
|
Vector3 result;
|
|
result.x = v1.x - v2.x;
|
|
result.y = v1.y - v2.y;
|
|
result.z = v1.z - v2.z;
|
|
return result;
|
|
}
|
|
|
|
Vector3 v3Neg(Vector3 v)
|
|
{
|
|
Vector3 result;
|
|
result.x = -v.x;
|
|
result.y = -v.y;
|
|
result.z = -v.z;
|
|
return result;
|
|
}
|
|
|
|
Vector3 v3Scale(Vector3 v, float scale)
|
|
{
|
|
Vector3 result;
|
|
result.x = v.x * scale;
|
|
result.y = v.y * scale;
|
|
result.z = v.z * scale;
|
|
return result;
|
|
}
|
|
|
|
float v3Norm(Vector3 v)
|
|
{
|
|
return sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
|
|
}
|
|
|
|
Vector3 v3Normalize(Vector3 v)
|
|
{
|
|
float norm = v3Norm(v);
|
|
if (norm == 0.0)
|
|
{
|
|
return VECTOR_ZERO;
|
|
}
|
|
else
|
|
{
|
|
return v3Scale(v, 1.0 / norm);
|
|
}
|
|
}
|
|
|
|
float v3Dot(Vector3 v1, Vector3 v2)
|
|
{
|
|
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
|
|
}
|
|
|
|
Vector3 v3Cross(Vector3 v1, Vector3 v2)
|
|
{
|
|
Vector3 result;
|
|
result.x = v1.y * v2.z - v1.z * v2.y;
|
|
result.y = v1.z * v2.x - v1.x * v2.z;
|
|
result.z = v1.x * v2.y - v1.y * v2.x;
|
|
return result;
|
|
}
|
|
|
|
void m4Save(PackStream* stream, Matrix4* m)
|
|
{
|
|
packWriteFloat(stream, &m->a);
|
|
packWriteFloat(stream, &m->b);
|
|
packWriteFloat(stream, &m->c);
|
|
packWriteFloat(stream, &m->d);
|
|
packWriteFloat(stream, &m->e);
|
|
packWriteFloat(stream, &m->f);
|
|
packWriteFloat(stream, &m->g);
|
|
packWriteFloat(stream, &m->h);
|
|
packWriteFloat(stream, &m->i);
|
|
packWriteFloat(stream, &m->j);
|
|
packWriteFloat(stream, &m->k);
|
|
packWriteFloat(stream, &m->l);
|
|
packWriteFloat(stream, &m->m);
|
|
packWriteFloat(stream, &m->n);
|
|
packWriteFloat(stream, &m->o);
|
|
packWriteFloat(stream, &m->p);
|
|
}
|
|
|
|
void m4Load(PackStream* stream, Matrix4* m)
|
|
{
|
|
packReadFloat(stream, &m->a);
|
|
packReadFloat(stream, &m->b);
|
|
packReadFloat(stream, &m->c);
|
|
packReadFloat(stream, &m->d);
|
|
packReadFloat(stream, &m->e);
|
|
packReadFloat(stream, &m->f);
|
|
packReadFloat(stream, &m->g);
|
|
packReadFloat(stream, &m->h);
|
|
packReadFloat(stream, &m->i);
|
|
packReadFloat(stream, &m->j);
|
|
packReadFloat(stream, &m->k);
|
|
packReadFloat(stream, &m->l);
|
|
packReadFloat(stream, &m->m);
|
|
packReadFloat(stream, &m->n);
|
|
packReadFloat(stream, &m->o);
|
|
packReadFloat(stream, &m->p);
|
|
}
|
|
|
|
Matrix4 m4NewIdentity()
|
|
{
|
|
Matrix4 result;
|
|
result.a = result.f = result.k = result.p = 1.0;
|
|
result.b = result.c = result.d = result.e = result.g = result.h = 0.0;
|
|
result.i = result.j = result.l = result.m = result.n = result.o = 0.0;
|
|
return result;
|
|
}
|
|
|
|
Matrix4 m4Mult(Matrix4 m1, Matrix4 m2)
|
|
{
|
|
Matrix4 result;
|
|
result.a = m1.a * m2.a + m1.b * m2.e + m1.c * m2.i + m1.d * m2.m;
|
|
result.b = m1.a * m2.b + m1.b * m2.f + m1.c * m2.j + m1.d * m2.n;
|
|
result.c = m1.a * m2.c + m1.b * m2.g + m1.c * m2.k + m1.d * m2.o;
|
|
result.d = m1.a * m2.d + m1.b * m2.h + m1.c * m2.l + m1.d * m2.p;
|
|
result.e = m1.e * m2.a + m1.f * m2.e + m1.g * m2.i + m1.h * m2.m;
|
|
result.f = m1.e * m2.b + m1.f * m2.f + m1.g * m2.j + m1.h * m2.n;
|
|
result.g = m1.e * m2.c + m1.f * m2.g + m1.g * m2.k + m1.h * m2.o;
|
|
result.h = m1.e * m2.d + m1.f * m2.h + m1.g * m2.l + m1.h * m2.p;
|
|
result.i = m1.i * m2.a + m1.j * m2.e + m1.k * m2.i + m1.l * m2.m;
|
|
result.j = m1.i * m2.b + m1.j * m2.f + m1.k * m2.j + m1.l * m2.n;
|
|
result.k = m1.i * m2.c + m1.j * m2.g + m1.k * m2.k + m1.l * m2.o;
|
|
result.l = m1.i * m2.d + m1.j * m2.h + m1.k * m2.l + m1.l * m2.p;
|
|
result.m = m1.m * m2.a + m1.n * m2.e + m1.o * m2.i + m1.p * m2.m;
|
|
result.n = m1.m * m2.b + m1.n * m2.f + m1.o * m2.j + m1.p * m2.n;
|
|
result.o = m1.m * m2.c + m1.n * m2.g + m1.o * m2.k + m1.p * m2.o;
|
|
result.p = m1.m * m2.d + m1.n * m2.h + m1.o * m2.l + m1.p * m2.p;
|
|
return result;
|
|
}
|
|
|
|
Vector3 m4MultPoint(Matrix4 m, Vector3 v)
|
|
{
|
|
Vector3 result;
|
|
result.x = m.a * v.x + m.b * v.y + m.c * v.z + m.d;
|
|
result.y = m.e * v.x + m.f * v.y + m.g * v.z + m.h;
|
|
result.z = m.i * v.x + m.j * v.y + m.k * v.z + m.l;
|
|
return result;
|
|
}
|
|
|
|
Vector3 m4Transform(Matrix4 m, Vector3 v)
|
|
{
|
|
Vector3 result;
|
|
float w;
|
|
result.x = m.a * v.x + m.b * v.y + m.c * v.z + m.d;
|
|
result.y = m.e * v.x + m.f * v.y + m.g * v.z + m.h;
|
|
result.z = m.i * v.x + m.j * v.y + m.k * v.z + m.l;
|
|
w = m.m * v.x + m.n * v.y + m.o * v.z + m.p;
|
|
if (w != 0.0)
|
|
{
|
|
result.x /= w;
|
|
result.y /= w;
|
|
result.z /= w;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
Matrix4 m4Transpose(Matrix4 m)
|
|
{
|
|
Matrix4 result;
|
|
result.a = m.a;
|
|
result.e = m.b;
|
|
result.i = m.c;
|
|
result.m = m.d;
|
|
result.b = m.e;
|
|
result.f = m.f;
|
|
result.j = m.g;
|
|
result.n = m.h;
|
|
result.c = m.i;
|
|
result.g = m.j;
|
|
result.k = m.k;
|
|
result.o = m.l;
|
|
result.d = m.m;
|
|
result.h = m.n;
|
|
result.l = m.o;
|
|
result.p = m.p;
|
|
return result;
|
|
}
|
|
|
|
Matrix4 m4NewScale(float x, float y, float z)
|
|
{
|
|
Matrix4 result = m4NewIdentity();
|
|
result.a = x;
|
|
result.f = y;
|
|
result.k = z;
|
|
return result;
|
|
}
|
|
|
|
Matrix4 m4NewTranslate(float x, float y, float z)
|
|
{
|
|
Matrix4 result = m4NewIdentity();
|
|
result.d = x;
|
|
result.h = y;
|
|
result.l = z;
|
|
return result;
|
|
}
|
|
|
|
Matrix4 m4NewRotateX(float angle)
|
|
{
|
|
Matrix4 result = m4NewIdentity();
|
|
float s = sin(angle);
|
|
float c = cos(angle);
|
|
result.f = result.k = c;
|
|
result.g = -s;
|
|
result.j = s;
|
|
return result;
|
|
}
|
|
|
|
Matrix4 m4NewRotateY(float angle)
|
|
{
|
|
Matrix4 result = m4NewIdentity();
|
|
float s = sin(angle);
|
|
float c = cos(angle);
|
|
result.a = result.k = c;
|
|
result.c = s;
|
|
result.i = -s;
|
|
return result;
|
|
}
|
|
|
|
Matrix4 m4NewRotateZ(float angle)
|
|
{
|
|
Matrix4 result = m4NewIdentity();
|
|
float s = sin(angle);
|
|
float c = cos(angle);
|
|
result.a = result.f = c;
|
|
result.b = -s;
|
|
result.e = s;
|
|
return result;
|
|
}
|
|
|
|
Matrix4 m4NewRotateAxis(float angle, Vector3 axis)
|
|
{
|
|
Matrix4 result = m4NewIdentity();
|
|
float s = sin(angle);
|
|
float c = cos(angle);
|
|
float c1 = 1.0 - c;
|
|
axis = v3Normalize(axis);
|
|
result.a = axis.x * axis.x * c1 + c;
|
|
result.b = axis.x * axis.y * c1 - axis.z * s;
|
|
result.c = axis.x * axis.z * c1 + axis.y * s;
|
|
result.e = axis.y * axis.x * c1 + axis.z * s;
|
|
result.f = axis.y * axis.y * c1 + c;
|
|
result.g = axis.y * axis.z * c1 - axis.x * s;
|
|
result.i = axis.x * axis.z * c1 - axis.y * s;
|
|
result.j = axis.y * axis.z * c1 + axis.x * s;
|
|
result.k = axis.z * axis.z * c1 + c;
|
|
return result;
|
|
}
|
|
|
|
Matrix4 m4NewRotateEuler(float heading, float attitude, float bank)
|
|
{
|
|
Matrix4 result = m4NewIdentity();
|
|
float ch = cos(heading);
|
|
float sh = sin(heading);
|
|
float ca = cos(attitude);
|
|
float sa = sin(attitude);
|
|
float cb = cos(bank);
|
|
float sb = sin(bank);
|
|
result.a = ch * ca;
|
|
result.b = sh * sb - ch * sa * cb;
|
|
result.c = ch * sa * sb + sh * cb;
|
|
result.e = sa;
|
|
result.f = ca * cb;
|
|
result.g = -ca * sb;
|
|
result.i = -sh * ca;
|
|
result.j = sh * sa * cb + ch * sb;
|
|
result.k = -sh * sa * sb + ch * cb;
|
|
return result;
|
|
}
|
|
|
|
Matrix4 m4NewRotateTripleAxis(Vector3 x, Vector3 y, Vector3 z)
|
|
{
|
|
Matrix4 result = m4NewIdentity();
|
|
result.a = x.x;
|
|
result.b = y.x;
|
|
result.c = z.x;
|
|
result.e = x.y;
|
|
result.f = y.y;
|
|
result.g = z.y;
|
|
result.i = x.z;
|
|
result.j = y.z;
|
|
result.k = z.z;
|
|
return result;
|
|
}
|
|
|
|
Matrix4 m4NewLookAt(Vector3 eye, Vector3 at, Vector3 up)
|
|
{
|
|
Vector3 z = v3Normalize(v3Sub(at, eye));
|
|
Vector3 x = v3Normalize(v3Cross(up, z));
|
|
Vector3 y = v3Cross(z, x);
|
|
Matrix4 result = m4NewRotateTripleAxis(x, y, z);
|
|
result.d = eye.x;
|
|
result.h = eye.y;
|
|
result.l = eye.z;
|
|
return m4Inverse(result);
|
|
}
|
|
|
|
Matrix4 m4NewPerspective(float fov_y, float aspect, float near, float far)
|
|
{
|
|
Matrix4 result = m4NewIdentity();
|
|
float f = 1 / tan(fov_y / 2.0);
|
|
result.a = f / aspect;
|
|
result.f = f;
|
|
result.k = (far + near) / (near - far);
|
|
result.l = 2.0 * far * near / (near - far);
|
|
result.o = -1.0;
|
|
result.p = 0.0;
|
|
return result;
|
|
}
|
|
|
|
float m4Determinant(Matrix4 m)
|
|
{
|
|
return ((m.a * m.f - m.e * m.b)
|
|
* (m.k * m.p - m.o * m.l)
|
|
- (m.a * m.j - m.i * m.b)
|
|
* (m.g * m.p - m.o * m.h)
|
|
+ (m.a * m.n - m.m * m.b)
|
|
* (m.g * m.l - m.k * m.h)
|
|
+ (m.e * m.j - m.i * m.f)
|
|
* (m.c * m.p - m.o * m.d)
|
|
- (m.e * m.n - m.m * m.f)
|
|
* (m.c * m.l - m.k * m.d)
|
|
+ (m.i * m.n - m.m * m.j)
|
|
* (m.c * m.h - m.g * m.d));
|
|
}
|
|
|
|
Matrix4 m4Inverse(Matrix4 m)
|
|
{
|
|
Matrix4 result;
|
|
float d = m4Determinant(m);
|
|
|
|
if (fabs(d) < 0.00001)
|
|
{
|
|
return m4NewIdentity();
|
|
}
|
|
else
|
|
{
|
|
d = 1.0 / d;
|
|
|
|
result.a = d * (m.f * (m.k * m.p - m.o * m.l) + m.j * (m.o * m.h - m.g * m.p) + m.n * (m.g * m.l - m.k * m.h));
|
|
result.e = d * (m.g * (m.i * m.p - m.m * m.l) + m.k * (m.m * m.h - m.e * m.p) + m.o * (m.e * m.l - m.i * m.h));
|
|
result.i = d * (m.h * (m.i * m.n - m.m * m.j) + m.l * (m.m * m.f - m.e * m.n) + m.p * (m.e * m.j - m.i * m.f));
|
|
result.m = d * (m.e * (m.n * m.k - m.j * m.o) + m.i * (m.f * m.o - m.n * m.g) + m.m * (m.j * m.g - m.f * m.k));
|
|
|
|
result.b = d * (m.j * (m.c * m.p - m.o * m.d) + m.n * (m.k * m.d - m.c * m.l) + m.b * (m.o * m.l - m.k * m.p));
|
|
result.f = d * (m.k * (m.a * m.p - m.m * m.d) + m.o * (m.i * m.d - m.a * m.l) + m.c * (m.m * m.l - m.i * m.p));
|
|
result.j = d * (m.l * (m.a * m.n - m.m * m.b) + m.p * (m.i * m.b - m.a * m.j) + m.d * (m.m * m.j - m.i * m.n));
|
|
result.n = d * (m.i * (m.n * m.c - m.b * m.o) + m.m * (m.b * m.k - m.j * m.c) + m.a * (m.j * m.o - m.n * m.k));
|
|
|
|
result.c = d * (m.n * (m.c * m.h - m.g * m.d) + m.b * (m.g * m.p - m.o * m.h) + m.f * (m.o * m.d - m.c * m.p));
|
|
result.g = d * (m.o * (m.a * m.h - m.e * m.d) + m.c * (m.e * m.p - m.m * m.h) + m.g * (m.m * m.d - m.a * m.p));
|
|
result.k = d * (m.p * (m.a * m.f - m.e * m.b) + m.d * (m.e * m.n - m.m * m.f) + m.h * (m.m * m.b - m.a * m.n));
|
|
result.o = d * (m.m * (m.f * m.c - m.b * m.g) + m.a * (m.n * m.g - m.f * m.o) + m.e * (m.b * m.o - m.n * m.c));
|
|
|
|
result.d = d * (m.b * (m.k * m.h - m.g * m.l) + m.f * (m.c * m.l - m.k * m.d) + m.j * (m.g * m.d - m.c * m.h));
|
|
result.h = d * (m.c * (m.i * m.h - m.e * m.l) + m.g * (m.a * m.l - m.i * m.d) + m.k * (m.e * m.d - m.a * m.h));
|
|
result.l = d * (m.d * (m.i * m.f - m.e * m.j) + m.h * (m.a * m.j - m.i * m.b) + m.l * (m.e * m.b - m.a * m.f));
|
|
result.p = d * (m.a * (m.f * m.k - m.j * m.g) + m.e * (m.j * m.c - m.b * m.k) + m.i * (m.b * m.g - m.f * m.c));
|
|
|
|
return result;
|
|
}
|
|
}
|
|
|