aboutsummaryrefslogtreecommitdiff
path: root/src/raymath.c
diff options
context:
space:
mode:
authorraysan5 <raysan5@gmail.com>2015-05-11 00:15:46 +0200
committerraysan5 <raysan5@gmail.com>2015-05-11 00:15:46 +0200
commita7714c842f72b8d41829caa7564f91abb3ffbd6b (patch)
treefea199fdb2d67d184529d8442b6cbea7b78b92df /src/raymath.c
parenteae98e1c34512579d69966c99713bd0c45bfcb50 (diff)
downloadraylib-a7714c842f72b8d41829caa7564f91abb3ffbd6b.tar.gz
raylib-a7714c842f72b8d41829caa7564f91abb3ffbd6b.zip
raymath module review and other changes
Complete review of matrix rotation math Check compressed textures support WIP: LoadImageFromData()
Diffstat (limited to 'src/raymath.c')
-rw-r--r--src/raymath.c262
1 files changed, 67 insertions, 195 deletions
diff --git a/src/raymath.c b/src/raymath.c
index 9763b075..f5e30833 100644
--- a/src/raymath.c
+++ b/src/raymath.c
@@ -431,109 +431,16 @@ Matrix MatrixSubstract(Matrix left, Matrix right)
}
// Returns translation matrix
-// TODO: Review this function
Matrix MatrixTranslate(float x, float y, float z)
{
-/*
- For OpenGL
- 1, 0, 0, 0
- 0, 1, 0, 0
- 0, 0, 1, 0
- x, y, z, 1
- Is the correct Translation Matrix. Why? Opengl Uses column-major matrix ordering.
- Which is the Transpose of the Matrix you initially presented, which is in row-major ordering.
- Row major is used in most math text-books and also DirectX, so it is a common
- point of confusion for those new to OpenGL.
-
- * matrix notation used in opengl documentation does not describe in-memory layout for OpenGL matrices
-
- Translation matrix should be laid out in memory like this:
- { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, trabsX, transY, transZ, 1 }
-
-
- 9.005 Are OpenGL matrices column-major or row-major?
-
- For programming purposes, OpenGL matrices are 16-value arrays with base vectors laid out
- contiguously in memory. The translation components occupy the 13th, 14th, and 15th elements
- of the 16-element matrix, where indices are numbered from 1 to 16 as described in section
- 2.11.2 of the OpenGL 2.1 Specification.
-
- Column-major versus row-major is purely a notational convention. Note that post-multiplying
- with column-major matrices produces the same result as pre-multiplying with row-major matrices.
- The OpenGL Specification and the OpenGL Reference Manual both use column-major notation.
- You can use any notation, as long as it's clearly stated.
-
- Sadly, the use of column-major format in the spec and blue book has resulted in endless confusion
- in the OpenGL programming community. Column-major notation suggests that matrices
- are not laid out in memory as a programmer would expect.
-*/
-
Matrix result = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, x, y, z, 1 };
return result;
}
-// Returns rotation matrix
-// TODO: Review this function
-Matrix MatrixRotate(float angleX, float angleY, float angleZ)
-{
- Matrix result;
-
- Matrix rotX = MatrixRotateX(angleX);
- Matrix rotY = MatrixRotateY(angleY);
- Matrix rotZ = MatrixRotateZ(angleZ);
-
- result = MatrixMultiply(MatrixMultiply(rotX, rotY), rotZ);
-
- return result;
-}
-
-/*
-Matrix MatrixRotate(float angle, float x, float y, float z)
-{
- Matrix result = MatrixIdentity();
-
- float c = cosf(angle*DEG2RAD); // cosine
- float s = sinf(angle*DEG2RAD); // sine
- float c1 = 1.0f - c; // 1 - c
-
- float m0 = result.m0, m4 = result.m4, m8 = result.m8, m12 = result.m12,
- m1 = result.m1, m5 = result.m5, m9 = result.m9, m13 = result.m13,
- m2 = result.m2, m6 = result.m6, m10 = result.m10, m14 = result.m14;
-
- // build rotation matrix
- float r0 = x * x * c1 + c;
- float r1 = x * y * c1 + z * s;
- float r2 = x * z * c1 - y * s;
- float r4 = x * y * c1 - z * s;
- float r5 = y * y * c1 + c;
- float r6 = y * z * c1 + x * s;
- float r8 = x * z * c1 + y * s;
- float r9 = y * z * c1 - x * s;
- float r10= z * z * c1 + c;
-
- // multiply rotation matrix
- result.m0 = r0*m0 + r4*m1 + r8*m2;
- result.m1 = r1*m0 + r5*m1 + r9*m2;
- result.m2 = r2*m0 + r6*m1 + r10*m2;
- result.m4 = r0*m4 + r4*m5 + r8*m6;
- result.m5 = r1*m4 + r5*m5 + r9*m6;
- result.m6 = r2*m4 + r6*m5 + r10*m6;
- result.m8 = r0*m8 + r4*m9 + r8*m10;
- result.m9 = r1*m8 + r5*m9 + r9*m10;
- result.m10 = r2*m8 + r6*m9 + r10*m10;
- result.m12 = r0*m12+ r4*m13 + r8*m14;
- result.m13 = r1*m12+ r5*m13 + r9*m14;
- result.m14 = r2*m12+ r6*m13 + r10*m14;
-
- return result;
-}
-*/
-
// Create rotation matrix from axis and angle
-// TODO: Test this function
-// NOTE: NO prototype defined!
-Matrix MatrixFromAxisAngle(Vector3 axis, float angle)
+// NOTE: Angle should be provided in radians
+Matrix MatrixRotate(float angle, Vector3 axis)
{
Matrix result;
@@ -545,15 +452,15 @@ Matrix MatrixFromAxisAngle(Vector3 axis, float angle)
if ((length != 1) && (length != 0))
{
- length = 1 / length;
+ length = 1/length;
x *= length;
y *= length;
z *= length;
}
- float s = sin(angle);
- float c = cos(angle);
- float t = 1-c;
+ float s = sinf(angle);
+ float c = cosf(angle);
+ float t = 1.0f - c;
// Cache some matrix values (speed optimization)
float a00 = mat.m0, a01 = mat.m1, a02 = mat.m2, a03 = mat.m3;
@@ -584,69 +491,50 @@ Matrix MatrixFromAxisAngle(Vector3 axis, float angle)
result.m15 = mat.m15;
return result;
-};
-
-// Create rotation matrix from axis and angle (version 2)
-// TODO: Test this function
-// NOTE: NO prototype defined!
-Matrix MatrixFromAxisAngle2(Vector3 axis, float angle)
-{
- Matrix result;
-
- VectorNormalize(&axis);
- float axisX = axis.x, axisY = axis.y, axisZ = axis.y;
-
- // Calculate angles
- float cosres = (float)cos(angle);
- float sinres = (float)sin(angle);
- float t = 1.0f - cosres;
-
- // Do the conversion math once
- float tXX = t * axisX * axisX;
- float tXY = t * axisX * axisY;
- float tXZ = t * axisX * axisZ;
- float tYY = t * axisY * axisY;
- float tYZ = t * axisY * axisZ;
- float tZZ = t * axisZ * axisZ;
-
- float sinX = sinres * axisX;
- float sinY = sinres * axisY;
- float sinZ = sinres * axisZ;
-
- result.m0 = tXX + cosres;
- result.m1 = tXY + sinZ;
- result.m2 = tXZ - sinY;
- result.m3 = 0;
- result.m4 = tXY - sinZ;
- result.m5 = tYY + cosres;
- result.m6 = tYZ + sinX;
- result.m7 = 0;
- result.m8 = tXZ + sinY;
- result.m9 = tYZ - sinX;
- result.m10 = tZZ + cosres;
- result.m11 = 0;
- result.m12 = 0;
- result.m13 = 0;
- result.m14 = 0;
- result.m15 = 1;
-
- return result;
}
-// Returns rotation matrix for a given quaternion
-Matrix MatrixFromQuaternion(Quaternion q)
+/*
+// Another implementation for MatrixRotate...
+Matrix MatrixRotate(float angle, float x, float y, float z)
{
Matrix result = MatrixIdentity();
- Vector3 axis;
- float angle;
+ float c = cosf(angle); // cosine
+ float s = sinf(angle); // sine
+ float c1 = 1.0f - c; // 1 - c
- QuaternionToAxisAngle(q, &axis, &angle);
+ float m0 = result.m0, m4 = result.m4, m8 = result.m8, m12 = result.m12,
+ m1 = result.m1, m5 = result.m5, m9 = result.m9, m13 = result.m13,
+ m2 = result.m2, m6 = result.m6, m10 = result.m10, m14 = result.m14;
- result = MatrixFromAxisAngle2(axis, angle);
+ // build rotation matrix
+ float r0 = x * x * c1 + c;
+ float r1 = x * y * c1 + z * s;
+ float r2 = x * z * c1 - y * s;
+ float r4 = x * y * c1 - z * s;
+ float r5 = y * y * c1 + c;
+ float r6 = y * z * c1 + x * s;
+ float r8 = x * z * c1 + y * s;
+ float r9 = y * z * c1 - x * s;
+ float r10= z * z * c1 + c;
+
+ // multiply rotation matrix
+ result.m0 = r0*m0 + r4*m1 + r8*m2;
+ result.m1 = r1*m0 + r5*m1 + r9*m2;
+ result.m2 = r2*m0 + r6*m1 + r10*m2;
+ result.m4 = r0*m4 + r4*m5 + r8*m6;
+ result.m5 = r1*m4 + r5*m5 + r9*m6;
+ result.m6 = r2*m4 + r6*m5 + r10*m6;
+ result.m8 = r0*m8 + r4*m9 + r8*m10;
+ result.m9 = r1*m8 + r5*m9 + r9*m10;
+ result.m10 = r2*m8 + r6*m9 + r10*m10;
+ result.m12 = r0*m12+ r4*m13 + r8*m14;
+ result.m13 = r1*m12+ r5*m13 + r9*m14;
+ result.m14 = r2*m12+ r6*m13 + r10*m14;
return result;
}
+*/
// Returns x-rotation matrix (angle in radians)
Matrix MatrixRotateX(float angle)
@@ -704,22 +592,6 @@ Matrix MatrixScale(float x, float y, float z)
return result;
}
-// Returns transformation matrix for a given translation, rotation and scale
-// NOTE: Transformation order is rotation -> scale -> translation
-// NOTE: Rotation angles should come in radians
-Matrix MatrixTransform(Vector3 translation, Vector3 rotation, Vector3 scale)
-{
- Matrix result = MatrixIdentity();
-
- Matrix mRotation = MatrixRotate(rotation.x, rotation.y, rotation.z);
- Matrix mScale = MatrixScale(scale.x, scale.y, scale.z);
- Matrix mTranslate = MatrixTranslate(translation.x, translation.y, translation.z);
-
- result = MatrixMultiply(MatrixMultiply(mRotation, mScale), mTranslate);
-
- return result;
-}
-
// Returns two matrix multiplication
// NOTE: When multiplying matrices... the order matters!
Matrix MatrixMultiply(Matrix left, Matrix right)
@@ -874,7 +746,7 @@ void PrintMatrix(Matrix m)
// Module Functions Definition - Quaternion math
//----------------------------------------------------------------------------------
-// Calculates the length of a quaternion
+// Computes the length of a quaternion
float QuaternionLength(Quaternion quat)
{
return sqrt(quat.x*quat.x + quat.y*quat.y + quat.z*quat.z + quat.w*quat.w);
@@ -948,7 +820,7 @@ Quaternion QuaternionSlerp(Quaternion q1, Quaternion q2, float amount)
return result;
}
-// Returns a quaternion from a given rotation matrix
+// Returns a quaternion for a given rotation matrix
Quaternion QuaternionFromMatrix(Matrix matrix)
{
Quaternion result;
@@ -1004,29 +876,7 @@ Quaternion QuaternionFromMatrix(Matrix matrix)
return result;
}
-// Returns rotation quaternion for an angle around an axis
-// NOTE: angle must be provided in radians
-Quaternion QuaternionFromAxisAngle(Vector3 axis, float angle)
-{
- Quaternion result = { 0, 0, 0, 1 };
-
- if (VectorLength(axis) != 0.0)
-
- angle *= 0.5;
-
- VectorNormalize(&axis);
-
- result.x = axis.x * (float)sin(angle);
- result.y = axis.y * (float)sin(angle);
- result.z = axis.z * (float)sin(angle);
- result.w = (float)cos(angle);
-
- QuaternionNormalize(&result);
-
- return result;
-}
-
-// Calculates the matrix from the given quaternion
+// Returns a matrix for a given quaternion
Matrix QuaternionToMatrix(Quaternion q)
{
Matrix result;
@@ -1065,12 +915,34 @@ Matrix QuaternionToMatrix(Quaternion q)
result.m13 = 0;
result.m14 = 0;
result.m15 = 1;
+
+ return result;
+}
+
+// Returns rotation quaternion for an angle and axis
+// NOTE: angle must be provided in radians
+Quaternion QuaternionFromAxisAngle(float angle, Vector3 axis)
+{
+ Quaternion result = { 0, 0, 0, 1 };
+
+ if (VectorLength(axis) != 0.0)
+
+ angle *= 0.5;
+
+ VectorNormalize(&axis);
+
+ result.x = axis.x * (float)sin(angle);
+ result.y = axis.y * (float)sin(angle);
+ result.z = axis.z * (float)sin(angle);
+ result.w = (float)cos(angle);
+
+ QuaternionNormalize(&result);
return result;
}
-// Returns the axis and the angle for a given quaternion
-void QuaternionToAxisAngle(Quaternion q, Vector3 *outAxis, float *outAngle)
+// Returns the rotation angle and axis for a given quaternion
+void QuaternionToAxisAngle(Quaternion q, float *outAngle, Vector3 *outAxis)
{
if (fabs(q.w) > 1.0f) QuaternionNormalize(&q);