mirror of
https://github.com/jorio/Pomme.git
synced 2024-11-23 06:32:14 +00:00
QD3D: New math features
This commit is contained in:
parent
b2873430d1
commit
4b6df39318
@ -209,6 +209,7 @@ typedef struct TQ3ColorRGB
|
||||
float b;
|
||||
} TQ3ColorRGB;
|
||||
|
||||
// WARNING: this structure differs from QD3D
|
||||
typedef struct TQ3Vertex3D
|
||||
{
|
||||
TQ3Point3D point;
|
||||
@ -221,6 +222,14 @@ typedef struct TQ3BoundingBox
|
||||
TQ3Boolean isEmpty;
|
||||
} TQ3BoundingBox;
|
||||
|
||||
typedef struct TQ3BoundingSphere
|
||||
{
|
||||
TQ3Point3D origin;
|
||||
float radius;
|
||||
TQ3Boolean isEmpty;
|
||||
} TQ3BoundingSphere;
|
||||
|
||||
|
||||
typedef struct TQ3Matrix3x3
|
||||
{
|
||||
float value[3][3];
|
||||
|
@ -382,3 +382,79 @@ TQ3Matrix4x4* Q3Matrix4x4_Invert(
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#pragma mark Q3BoundingBox
|
||||
|
||||
TQ3BoundingBox* Q3BoundingBox_SetFromPoints3D(
|
||||
TQ3BoundingBox *bBox,
|
||||
const TQ3Point3D *points3D,
|
||||
TQ3Uns32 numPoints,
|
||||
TQ3Uns32 structSize)
|
||||
{
|
||||
if (structSize != sizeof(TQ3Point3D))
|
||||
throw std::runtime_error("Q3BoundingBox_SetFromPoints3D: unsupported struct size");
|
||||
|
||||
if (numPoints == 0)
|
||||
{
|
||||
bBox->isEmpty = kQ3True;
|
||||
}
|
||||
else
|
||||
{
|
||||
TQ3Uns32 i = 0;
|
||||
|
||||
bBox->isEmpty = kQ3False;
|
||||
bBox->min = points3D[0];
|
||||
bBox->max = points3D[0];
|
||||
|
||||
// We have already accounted for the first point, so if the number of
|
||||
// points is odd, we can handle the other points in pairs, and need not
|
||||
// look at the first point again. But if the number of points is even,
|
||||
// we will start at the first point just so we can work in pairs.
|
||||
if ( (numPoints % 2) == 1 )
|
||||
{
|
||||
i = 1;
|
||||
}
|
||||
|
||||
for (; i < numPoints; i += 2)
|
||||
{
|
||||
TQ3Point3D pt0 = points3D[i];
|
||||
TQ3Point3D pt1 = points3D[i+1];
|
||||
|
||||
if (pt0.x < pt1.x)
|
||||
{
|
||||
if (pt0.x < bBox->min.x) bBox->min.x = pt0.x;
|
||||
if (pt1.x > bBox->max.x) bBox->max.x = pt1.x;
|
||||
}
|
||||
else // pt1.x <= pt0.x
|
||||
{
|
||||
if (pt1.x < bBox->min.x) bBox->min.x = pt1.x;
|
||||
if (pt0.x > bBox->max.x) bBox->max.x = pt0.x;
|
||||
}
|
||||
|
||||
if (pt0.y < pt1.y)
|
||||
{
|
||||
if (pt0.y < bBox->min.y) bBox->min.y = pt0.y;
|
||||
if (pt1.y > bBox->max.y) bBox->max.y = pt1.y;
|
||||
}
|
||||
else // pt1.y <= pt0.y
|
||||
{
|
||||
if (pt1.y < bBox->min.y) bBox->min.y = pt1.y;
|
||||
if (pt0.y > bBox->max.y) bBox->max.y = pt0.y;
|
||||
}
|
||||
|
||||
if (pt0.z < pt1.z)
|
||||
{
|
||||
if (pt0.z < bBox->min.z) bBox->min.z = pt0.z;
|
||||
if (pt1.z > bBox->max.z) bBox->max.z = pt1.z;
|
||||
}
|
||||
else // pt1.z <= pt0.z
|
||||
{
|
||||
if (pt1.z < bBox->min.z) bBox->min.z = pt1.z;
|
||||
if (pt0.z > bBox->max.z) bBox->max.z = pt0.z;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(bBox);
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ extern "C" {
|
||||
|
||||
#include "QD3D.h"
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef FLT_EPSILON
|
||||
@ -137,25 +138,6 @@ static inline void Q3Point3D_CrossProductTri(
|
||||
result->z = (v1_x * v2_y) - (v1_y * v2_x);
|
||||
}
|
||||
|
||||
static inline TQ3Vector3D* Q3Vector3D_Transform(
|
||||
const TQ3Vector3D *vector3D,
|
||||
const TQ3Matrix4x4 *matrix4x4,
|
||||
TQ3Vector3D *result)
|
||||
{
|
||||
// Save input to avoid problems when result is same as input
|
||||
float x = vector3D->x;
|
||||
float y = vector3D->y;
|
||||
float z = vector3D->z;
|
||||
|
||||
#define M(x,y) matrix4x4->value[x][y]
|
||||
result->x = x*M(0,0) + y*M(1,0) + z*M(2,0);
|
||||
result->y = x*M(0,1) + y*M(1,1) + z*M(2,1);
|
||||
result->z = x*M(0,2) + y*M(1,2) + z*M(2,2);
|
||||
#undef M
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline TQ3Point3D* Q3Point3D_Transform(
|
||||
const TQ3Point3D *point3D,
|
||||
const TQ3Matrix4x4 *matrix4x4,
|
||||
@ -210,6 +192,7 @@ static inline TQ3Point3D* Q3Point3D_TransformAffine(
|
||||
return(result);
|
||||
}
|
||||
|
||||
// This function's signature differs from vanilla QD3D's.
|
||||
void Q3Point3D_To3DTransformArray(
|
||||
const TQ3Point3D *inPoints3D,
|
||||
const TQ3Matrix4x4 *matrix4x4,
|
||||
@ -272,6 +255,41 @@ static inline void Q3Vector2D_Normalize(
|
||||
Q3Vector2D_Scale(v1, 1.0f / theLength, result);
|
||||
}
|
||||
|
||||
static inline float Q3Vector2D_Cross(
|
||||
const TQ3Vector2D* v1,
|
||||
const TQ3Vector2D* v2)
|
||||
{
|
||||
return (v1->x * v2->y) - (v1->y * v2->x);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// E3Vector2D_Transform : Transform 2D vector by 3x3 matrix.
|
||||
//-----------------------------------------------------------------------------
|
||||
// Note : 'result' may be the same as 'vector2D'.
|
||||
//
|
||||
// Note that the translation and perspective components of the
|
||||
// matrix is ignored (as if it were really a 2x2 matrix).
|
||||
//
|
||||
// Contrast with E3Point2D_Transform, which does the full 3x3
|
||||
// transformation.
|
||||
//-----------------------------------------------------------------------------
|
||||
static inline TQ3Vector2D* Q3Vector2D_Transform(
|
||||
const TQ3Vector2D *vector2D,
|
||||
const TQ3Matrix3x3 *matrix3x3,
|
||||
TQ3Vector2D *result)
|
||||
{
|
||||
// Save input to avoid problems when result is same as input
|
||||
float x = vector2D->x;
|
||||
float y = vector2D->y;
|
||||
|
||||
#define M(x,y) matrix3x3->value[x][y]
|
||||
result->x = x*M(0,0) + y*M(1,0);
|
||||
result->y = x*M(0,1) + y*M(1,1);
|
||||
#undef M
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#pragma mark Q3Vector3D
|
||||
|
||||
@ -335,6 +353,25 @@ static inline void Q3Vector3D_Normalize(
|
||||
Q3Vector3D_Scale(v1, 1.0f / theLength, result);
|
||||
}
|
||||
|
||||
static inline TQ3Vector3D* Q3Vector3D_Transform(
|
||||
const TQ3Vector3D *vector3D,
|
||||
const TQ3Matrix4x4 *matrix4x4,
|
||||
TQ3Vector3D *result)
|
||||
{
|
||||
// Save input to avoid problems when result is same as input
|
||||
float x = vector3D->x;
|
||||
float y = vector3D->y;
|
||||
float z = vector3D->z;
|
||||
|
||||
#define M(x,y) matrix4x4->value[x][y]
|
||||
result->x = x*M(0,0) + y*M(1,0) + z*M(2,0);
|
||||
result->y = x*M(0,1) + y*M(1,1) + z*M(2,1);
|
||||
result->z = x*M(0,2) + y*M(1,2) + z*M(2,2);
|
||||
#undef M
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#pragma mark Q3Matrix3x3
|
||||
|
||||
@ -372,6 +409,37 @@ static inline TQ3Matrix3x3* Q3Matrix3x3_SetTranslate(
|
||||
return matrix3x3;
|
||||
}
|
||||
|
||||
static inline TQ3Matrix3x3* Q3Matrix3x3_SetRotateAboutPoint(
|
||||
TQ3Matrix3x3 *matrix3x3,
|
||||
const TQ3Point2D *origin,
|
||||
float angle)
|
||||
{
|
||||
float cosAngle = cosf(angle);
|
||||
float sinAngle = sinf(angle);
|
||||
|
||||
#define M(x,y) matrix3x3->value[x][y]
|
||||
#define Dx origin->x
|
||||
#define Dy origin->y
|
||||
|
||||
M(0,0) = cosAngle;
|
||||
M(0,1) = sinAngle;
|
||||
M(0,2) = 0.0f;
|
||||
|
||||
M(1,0) = -sinAngle;
|
||||
M(1,1) = cosAngle;
|
||||
M(1,2) = 0.0f;
|
||||
|
||||
M(2,0) = Dx - Dx*cosAngle + Dy*sinAngle; // = Dx - Dx*M(0,0) - Dy*M(1,0)
|
||||
M(2,1) = Dy - Dx*sinAngle - Dy*cosAngle; // = Dx - Dx*M(0,1) - Dy*M(1,1)
|
||||
M(2,2) = 1.0f;
|
||||
|
||||
#undef M
|
||||
#undef Dx
|
||||
#undef Dy
|
||||
|
||||
return(matrix3x3);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#pragma mark Q3Matrix4x4
|
||||
|
||||
@ -602,6 +670,62 @@ static inline TQ3Matrix4x4* Q3Matrix4x4_SetRotate_XYZ(
|
||||
return(matrix4x4);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// E3Matrix4x4_SetRotateAboutPoint : Set 4x4 matrix to rotate about axes through
|
||||
// point and parallel to X, Y, Z axes
|
||||
// (in that order -- which is rarely useful).
|
||||
//-----------------------------------------------------------------------------
|
||||
static inline TQ3Matrix4x4* Q3Matrix4x4_SetRotateAboutPoint(
|
||||
TQ3Matrix4x4 *matrix4x4,
|
||||
const TQ3Point3D *origin,
|
||||
float xAngle,
|
||||
float yAngle,
|
||||
float zAngle)
|
||||
{
|
||||
float cosX = cosf(xAngle);
|
||||
float sinX = sinf(xAngle);
|
||||
float cosY = cosf(yAngle);
|
||||
float sinY = sinf(yAngle);
|
||||
float cosZ = cosf(zAngle);
|
||||
float sinZ = sinf(zAngle);
|
||||
|
||||
float sinXsinY = sinX*sinY;
|
||||
float cosXsinY = cosX*sinY;
|
||||
|
||||
#define M(x,y) matrix4x4->value[x][y]
|
||||
#define Dx origin->x
|
||||
#define Dy origin->y
|
||||
#define Dz origin->z
|
||||
|
||||
M(0,0) = cosY*cosZ;
|
||||
M(0,1) = cosY*sinZ;
|
||||
M(0,2) = -sinY;
|
||||
M(0,3) = 0.0f;
|
||||
|
||||
M(1,0) = sinXsinY*cosZ - cosX*sinZ;
|
||||
M(1,1) = sinXsinY*sinZ + cosX*cosZ;
|
||||
M(1,2) = sinX*cosY;
|
||||
M(1,3) = 0.0f;
|
||||
|
||||
M(2,0) = cosXsinY*cosZ + sinX*sinZ;
|
||||
M(2,1) = cosXsinY*sinZ - sinX*cosZ;
|
||||
M(2,2) = cosX*cosY;
|
||||
M(2,3) = 0.0f;
|
||||
|
||||
M(3,0) = Dx - Dx*M(0,0) - Dy*M(1,0) - Dz*M(2,0);
|
||||
M(3,1) = Dy - Dx*M(0,1) - Dy*M(1,1) - Dz*M(2,1);
|
||||
M(3,2) = Dz - Dx*M(0,2) - Dy*M(1,2) - Dz*M(2,2);
|
||||
M(3,3) = 1.0f;
|
||||
|
||||
#undef M
|
||||
#undef Dx
|
||||
#undef Dy
|
||||
#undef Dz
|
||||
|
||||
return(matrix4x4);
|
||||
}
|
||||
|
||||
|
||||
TQ3Matrix4x4* Q3Matrix4x4_Transpose(
|
||||
const TQ3Matrix4x4 *matrix4x4,
|
||||
TQ3Matrix4x4 *result);
|
||||
@ -610,6 +734,15 @@ TQ3Matrix4x4* Q3Matrix4x4_Invert(
|
||||
const TQ3Matrix4x4 *inMatrix,
|
||||
TQ3Matrix4x4 *result);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#pragma mark Q3BoundingBox
|
||||
|
||||
TQ3BoundingBox* Q3BoundingBox_SetFromPoints3D(
|
||||
TQ3BoundingBox *bBox,
|
||||
const TQ3Point3D *points3D,
|
||||
TQ3Uns32 numPoints,
|
||||
TQ3Uns32 structSize);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user