adding more math/common helper stuff
This commit is contained in:
parent
09471fb57d
commit
0d28d5950b
|
@ -90,6 +90,10 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="src\assets\material.h" />
|
<ClInclude Include="src\assets\material.h" />
|
||||||
|
<ClInclude Include="src\common.h" />
|
||||||
|
<ClInclude Include="src\geometry\common.h" />
|
||||||
|
<ClInclude Include="src\geometry\matrix4x4.h" />
|
||||||
|
<ClInclude Include="src\geometry\quaternion.h" />
|
||||||
<ClInclude Include="src\geometry\vector2.h" />
|
<ClInclude Include="src\geometry\vector2.h" />
|
||||||
<ClInclude Include="src\geometry\vector3.h" />
|
<ClInclude Include="src\geometry\vector3.h" />
|
||||||
<ClInclude Include="src\md2\md2.h" />
|
<ClInclude Include="src\md2\md2.h" />
|
||||||
|
|
27
MeshConverter/src/common.h
Normal file
27
MeshConverter/src/common.h
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
#ifndef __COMMON_H_INCLUDED__
|
||||||
|
#define __COMMON_H_INCLUDED__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#if !defined(TRUE) && !defined(FALSE)
|
||||||
|
typedef int32_t BOOL;
|
||||||
|
const BOOL TRUE = 1;
|
||||||
|
const BOOL FALSE = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SAFE_RELEASE
|
||||||
|
#define SAFE_RELEASE(x) if (x) { (x)->Release(); (x) = NULL; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SAFE_DELETE
|
||||||
|
#define SAFE_DELETE(x) if (x) { delete (x); (x) = NULL; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SAFE_DELETE_ARRAY
|
||||||
|
#define SAFE_DELETE_ARRAY(x) if (x) { delete [] (x); (x) = NULL; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MAX(a, b) ( (a) > (b) ? (a) : (b) )
|
||||||
|
#define MIN(a, b) ( (a) < (b) ? (a) : (b) )
|
||||||
|
|
||||||
|
#endif
|
19
MeshConverter/src/geometry/common.h
Normal file
19
MeshConverter/src/geometry/common.h
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#ifndef __GEOMETRY_COMMON_H_INCLUDED__
|
||||||
|
#define __GEOMETRY_COMMON_H_INCLUDED__
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#define PI 3.141593f
|
||||||
|
#define PI_OVER_180 (PI / 180.0f)
|
||||||
|
|
||||||
|
#define DEG_TO_RAD(x) ((x) * PI_OVER_180)
|
||||||
|
#define RAD_TO_DEG(x) ((x) * (1.0f / (PI_OVER_180)))
|
||||||
|
|
||||||
|
#define TOLERANCE 0.00001f
|
||||||
|
#define IS_CLOSE_ENOUGH(a, b) (fabs((a - b) / ((b == 0.0f) ? 1.0f : b)) < EPSILON)
|
||||||
|
|
||||||
|
#define EPSILON 0.0005f
|
||||||
|
|
||||||
|
#define ISPOWEROF2(x) (((x) != 0) && !((x) & ((x) - 1)))
|
||||||
|
|
||||||
|
#endif
|
1030
MeshConverter/src/geometry/matrix4x4.h
Normal file
1030
MeshConverter/src/geometry/matrix4x4.h
Normal file
File diff suppressed because it is too large
Load diff
491
MeshConverter/src/geometry/quaternion.h
Normal file
491
MeshConverter/src/geometry/quaternion.h
Normal file
|
@ -0,0 +1,491 @@
|
||||||
|
#ifndef __GEOMETRY_QUATERNION_H_INCLUDED__
|
||||||
|
#define __GEOMETRY_QUATERNION_H_INCLUDED__
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include "common.h"
|
||||||
|
#include "vector3.h"
|
||||||
|
#include "matrix4x4.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a quaternion to store an orientation or angular
|
||||||
|
* displacement and provides methods for conversion/manipulation
|
||||||
|
* <p>Referenced/based on code from:</p>
|
||||||
|
* <ul>
|
||||||
|
* <li>3D Math Primer for Graphics and Game Development (Dunn & Parberry, 2002)</li>
|
||||||
|
* <li>More OpenGL Game Programming (Dave Astle, 2006)</li>
|
||||||
|
* <li>http://www.dhpoware.com/source/mathlib.html</li>
|
||||||
|
* </ul>
|
||||||
|
* @author Gered
|
||||||
|
*/
|
||||||
|
class Quaternion
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Quaternion() {}
|
||||||
|
|
||||||
|
Quaternion(float w, float x, float y, float z)
|
||||||
|
{
|
||||||
|
this->w = w;
|
||||||
|
this->x = x;
|
||||||
|
this->y = y;
|
||||||
|
this->z = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
Quaternion(float w, const Vector3 &v)
|
||||||
|
{
|
||||||
|
this->w = w;
|
||||||
|
this->x = v.x;
|
||||||
|
this->y = v.y;
|
||||||
|
this->z = v.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
Quaternion(const float *q)
|
||||||
|
{
|
||||||
|
w = q[0];
|
||||||
|
x = q[1];
|
||||||
|
y = q[2];
|
||||||
|
z = q[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
~Quaternion() {}
|
||||||
|
|
||||||
|
void Set(float w, float x, float y, float z);
|
||||||
|
Matrix4x4 ToMatrix() const;
|
||||||
|
Vector3 GetVector() const;
|
||||||
|
|
||||||
|
static Quaternion Cross(const Quaternion &a, const Quaternion &b);
|
||||||
|
static float Dot(const Quaternion &a, const Quaternion &b);
|
||||||
|
static float Length(const Quaternion &q);
|
||||||
|
static float LengthSquared(const Quaternion &q);
|
||||||
|
static Quaternion Normalize(const Quaternion &q);
|
||||||
|
static Quaternion Conjugate(const Quaternion &q);
|
||||||
|
static Quaternion Inverse(const Quaternion &q);
|
||||||
|
static Quaternion CreateFromEulerAngles(float x, float y, float z);
|
||||||
|
static Quaternion CreateFromAxisAngle(float angle, const Vector3 &axis);
|
||||||
|
static Quaternion CreateFromRotationMatrix(const Matrix4x4 &matrix);
|
||||||
|
static void ExtractAxisAngle(const Quaternion &q, float *angle, Vector3 *axis);
|
||||||
|
static Quaternion Lerp(const Quaternion &a, const Quaternion &b, float interpolation);
|
||||||
|
static Quaternion Slerp(const Quaternion &a, const Quaternion &b, float interpolation);
|
||||||
|
|
||||||
|
float w;
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
float z;
|
||||||
|
};
|
||||||
|
|
||||||
|
Quaternion operator+(const Quaternion &left, const Quaternion &right);
|
||||||
|
Quaternion &operator+=(Quaternion &left, const Quaternion &right);
|
||||||
|
Quaternion operator-(const Quaternion &left, const Quaternion &right);
|
||||||
|
Quaternion &operator-=(Quaternion &left, const Quaternion &right);
|
||||||
|
Quaternion operator*(const Quaternion &left, float right);
|
||||||
|
Quaternion &operator*=(Quaternion &left, float right);
|
||||||
|
Quaternion operator*(const Quaternion &left, const Quaternion &right);
|
||||||
|
Quaternion &operator*=(Quaternion &left, const Quaternion &right);
|
||||||
|
Quaternion operator/(const Quaternion &left, float right);
|
||||||
|
Quaternion &operator/=(Quaternion &left, float right);
|
||||||
|
Vector3 operator*(const Vector3 &left, const Quaternion &right);
|
||||||
|
|
||||||
|
#define IDENTITY_QUATERNION Quaternion(1.0f, 0.0f, 0.0f, 0.0f)
|
||||||
|
|
||||||
|
inline void Quaternion::Set(float w, float x, float y, float z)
|
||||||
|
{
|
||||||
|
this->w = w;
|
||||||
|
this->x = x;
|
||||||
|
this->y = y;
|
||||||
|
this->z = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a quaternion to a rotation matrix
|
||||||
|
* @return Matrix4x4
|
||||||
|
*/
|
||||||
|
inline Matrix4x4 Quaternion::ToMatrix() const
|
||||||
|
{
|
||||||
|
Matrix4x4 output;
|
||||||
|
|
||||||
|
output.m[_11] = 1.0f - (2.0f * ((y * y) + (z * z)));
|
||||||
|
output.m[_21] = 2.0f * ((x * y) + (z * w));
|
||||||
|
output.m[_31] = 2.0f * ((z * x) - (y * w));
|
||||||
|
output.m[_41] = 0.0f;
|
||||||
|
|
||||||
|
output.m[_12] = 2.0f * ((x * y) - (z * w));
|
||||||
|
output.m[_22] = 1.0f - (2.0f * ((z * z) + (x * x)));
|
||||||
|
output.m[_32] = 2.0f * ((y * z) + (x * w));
|
||||||
|
output.m[_42] = 0.0f;
|
||||||
|
|
||||||
|
output.m[_13] = 2.0f * ((z * x) + (y * w));
|
||||||
|
output.m[_23] = 2.0f * ((y * z) - (x * w));
|
||||||
|
output.m[_33] = 1.0f - (2.0f * ((y * y) + (x * x)));
|
||||||
|
output.m[_43] = 0.0f;
|
||||||
|
|
||||||
|
output.m[_14] = 0.0f;
|
||||||
|
output.m[_24] = 0.0f;
|
||||||
|
output.m[_34] = 0.0f;
|
||||||
|
output.m[_44] = 1.0f;
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Vector3 the vector component of the quaternion.
|
||||||
|
*/
|
||||||
|
inline Vector3 Quaternion::GetVector() const
|
||||||
|
{
|
||||||
|
return Vector3(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the cross product of two quaternions
|
||||||
|
* @param a first quaternion
|
||||||
|
* @param b second quaternion
|
||||||
|
* @return Quaternion the cross product
|
||||||
|
*/
|
||||||
|
inline Quaternion Quaternion::Cross(const Quaternion &a, const Quaternion &b)
|
||||||
|
{
|
||||||
|
return a * b;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the dot product of 2 quaternions.
|
||||||
|
* @param a first quaternion
|
||||||
|
* @param b second quaternion
|
||||||
|
* @return float the dot product
|
||||||
|
*/
|
||||||
|
inline float Quaternion::Dot(const Quaternion &a, const Quaternion &b)
|
||||||
|
{
|
||||||
|
return (a.w * b.w) + (a.x * b.x) + (a.y * b.y) + (a.z * b.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the length (magnitude) of a quaternion.
|
||||||
|
* @param q quaternion to retrieve the length of
|
||||||
|
* @return float the length
|
||||||
|
*/
|
||||||
|
inline float Quaternion::Length(const Quaternion &q)
|
||||||
|
{
|
||||||
|
return sqrtf((q.w * q.w) + (q.x * q.x) + (q.y * q.y) + (q.z * q.z));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the squared length of a quaternion (the length minus the
|
||||||
|
* sqrt call).
|
||||||
|
* @param q quaternion to retrieve the squared length of
|
||||||
|
* @return float the squared length
|
||||||
|
*/
|
||||||
|
inline float Quaternion::LengthSquared(const Quaternion &q)
|
||||||
|
{
|
||||||
|
return (q.w * q.w) + (q.x * q.x) + (q.y * q.y) + (q.z * q.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalizes a quaternion (only if necessary)
|
||||||
|
* @param q quaternion to be normalized
|
||||||
|
* @return Quaternion normalized quaternion
|
||||||
|
*/
|
||||||
|
inline Quaternion Quaternion::Normalize(const Quaternion &q)
|
||||||
|
{
|
||||||
|
float inverseLength = 1.0f / Length(q);
|
||||||
|
return Quaternion(
|
||||||
|
q.w * inverseLength,
|
||||||
|
q.x * inverseLength,
|
||||||
|
q.y * inverseLength,
|
||||||
|
q.z * inverseLength
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the conjugate of a quaternion. If the quaternion
|
||||||
|
* is unit length, this also returns the inverse.
|
||||||
|
* @param q quaternion to retrieve the conjugate of
|
||||||
|
* @return Quaternion conjugate
|
||||||
|
*/
|
||||||
|
inline Quaternion Quaternion::Conjugate(const Quaternion &q)
|
||||||
|
{
|
||||||
|
return Quaternion(q.w, -q.x, -q.y, -q.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the inverse of a given quaternion
|
||||||
|
* @param q quaternion to retrieve the inverse of
|
||||||
|
* @return Quaternion inverse of the quaternion
|
||||||
|
*/
|
||||||
|
inline Quaternion Quaternion::Inverse(const Quaternion &q)
|
||||||
|
{
|
||||||
|
float inverseSquaredLength = 1.0f / LengthSquared(q);
|
||||||
|
return Quaternion(
|
||||||
|
q.w * inverseSquaredLength,
|
||||||
|
-q.x * inverseSquaredLength,
|
||||||
|
-q.y * inverseSquaredLength,
|
||||||
|
-q.z * inverseSquaredLength
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts euler angles to a quaternion
|
||||||
|
* @param x x angle of rotation (specified in radians)
|
||||||
|
* @param y y angle of rotation (specified in radians)
|
||||||
|
* @param z z angle of rotation (specified in radians)
|
||||||
|
* @return Quaternion quaternion equivalent to the euler angle
|
||||||
|
* orientation
|
||||||
|
*/
|
||||||
|
inline Quaternion Quaternion::CreateFromEulerAngles(float x, float y, float z)
|
||||||
|
{
|
||||||
|
Quaternion qx(cosf(x / 2.0f), sinf(x / 2.0f), 0.0f, 0.0f);
|
||||||
|
Quaternion qy(cosf(y / 2.0f), 0.0f, sinf(y / 2.0f), 0.0f);
|
||||||
|
Quaternion qz(cosf(z / 2.0f), 0.0f, 0.0f, sinf(z / 2.0f));
|
||||||
|
|
||||||
|
return Normalize(qz * qy * qx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts an axis angle to a quaternion
|
||||||
|
* @param angle the angle to rotate be (specified in radians)
|
||||||
|
* @param axis the axis being rotated about
|
||||||
|
* @return Quaternion quaternion equivalent to the axis angle
|
||||||
|
* orientation
|
||||||
|
*/
|
||||||
|
inline Quaternion Quaternion::CreateFromAxisAngle(float angle, const Vector3 &axis)
|
||||||
|
{
|
||||||
|
Quaternion result;
|
||||||
|
|
||||||
|
float c = cosf(angle / 2.0f);
|
||||||
|
float s = sinf(angle / 2.0f);
|
||||||
|
|
||||||
|
result.w = c;
|
||||||
|
result.x = axis.x * s;
|
||||||
|
result.y = axis.y * s;
|
||||||
|
result.z = axis.z * s;
|
||||||
|
|
||||||
|
return Normalize(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a rotation matrix to a quaternion
|
||||||
|
* @param matrix matrix to be converted
|
||||||
|
* @return Quaternion quaternion equivalent of the rotation
|
||||||
|
* matrix
|
||||||
|
*/
|
||||||
|
inline Quaternion Quaternion::CreateFromRotationMatrix(const Matrix4x4 &matrix)
|
||||||
|
{
|
||||||
|
Quaternion result;
|
||||||
|
|
||||||
|
float n = matrix.m[_11] + matrix.m[_22] + matrix.m[_33];
|
||||||
|
if (n > 0.0f)
|
||||||
|
{
|
||||||
|
float a = sqrtf(n + 1.0f);
|
||||||
|
result.w = a / 2.0f;
|
||||||
|
a = 0.5f / a;
|
||||||
|
result.x = (matrix.m[_32] - matrix.m[_23]) * a;
|
||||||
|
result.y = (matrix.m[_13] - matrix.m[_31]) * a;
|
||||||
|
result.z = (matrix.m[_21] - matrix.m[_12]) * a;
|
||||||
|
}
|
||||||
|
else if ((matrix.m[_11] >= matrix.m[_22]) && (matrix.m[_11] >= matrix.m[_33]))
|
||||||
|
{
|
||||||
|
float a = sqrtf(1.0f + matrix.m[_11] - matrix.m[_22] - matrix.m[_33]);
|
||||||
|
float b = 0.5f / a;
|
||||||
|
|
||||||
|
result.x = 0.5f * a;
|
||||||
|
result.y = (matrix.m[_21] + matrix.m[_12]) * b;
|
||||||
|
result.z = (matrix.m[_31] + matrix.m[_13]) * b;
|
||||||
|
result.w = (matrix.m[_32] - matrix.m[_23]) * b;
|
||||||
|
}
|
||||||
|
else if (matrix.m[_22] > matrix.m[_33])
|
||||||
|
{
|
||||||
|
float a = sqrtf(1.0f + matrix.m[_22] - matrix.m[_11] - matrix.m[_33]);
|
||||||
|
float b = 0.5f / a;
|
||||||
|
|
||||||
|
result.x = (matrix.m[_12] + matrix.m[_21]) * b;
|
||||||
|
result.y = 0.5f * a;
|
||||||
|
result.z = (matrix.m[_23] + matrix.m[_32]) * b;
|
||||||
|
result.w = (matrix.m[_13] - matrix.m[_31]) * b;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float a = sqrtf(1.0f + matrix.m[_33] - matrix.m[_11] - matrix.m[_22]);
|
||||||
|
float b = 0.5f / a;
|
||||||
|
|
||||||
|
result.x = (matrix.m[_13] + matrix.m[_31]) * b;
|
||||||
|
result.y = (matrix.m[_23] + matrix.m[_32]) * b;
|
||||||
|
result.z = 0.5f * a;
|
||||||
|
result.w = (matrix.m[_21] - matrix.m[_12]) * b;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Normalize(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a quaternion to an axis-angle representation.
|
||||||
|
* @param q the normalized quaternion to convert
|
||||||
|
* @param angle the angle (in radians)
|
||||||
|
* @param axis a vector that will contain the axis
|
||||||
|
*/
|
||||||
|
inline void Quaternion::ExtractAxisAngle(const Quaternion &q, float *angle, Vector3 *axis)
|
||||||
|
{
|
||||||
|
*angle = 2.0f * acosf(q.w);
|
||||||
|
float n = sqrtf(1.0f - (q.w * q.w));
|
||||||
|
if (n > 0.0001f)
|
||||||
|
*axis = q.GetVector() / n;
|
||||||
|
else
|
||||||
|
*axis = X_AXIS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Linearly interpolates between two quaternions.
|
||||||
|
* @param a the first quaternion
|
||||||
|
* @param b the second quaternion
|
||||||
|
* @param interpolation the amount to interpolate
|
||||||
|
* @return Quaternion the interpolated quaternion
|
||||||
|
*/
|
||||||
|
inline Quaternion Quaternion::Lerp(const Quaternion &a, const Quaternion &b, float interpolation)
|
||||||
|
{
|
||||||
|
return (a * (1.0f - interpolation)) + (b * interpolation);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interpolates between two quaternions using spherical
|
||||||
|
* interpolation.
|
||||||
|
* @param a the first quaternion
|
||||||
|
* @param b the second quaternion
|
||||||
|
* @param interpolation the amount to interpolate
|
||||||
|
* @return Quaternion the interpolated quaternion
|
||||||
|
*/
|
||||||
|
inline Quaternion Quaternion::Slerp(const Quaternion &a, const Quaternion &b, float interpolation)
|
||||||
|
{
|
||||||
|
if (LengthSquared(a) == 0.0f)
|
||||||
|
{
|
||||||
|
if (LengthSquared(b) == 0.0f)
|
||||||
|
return IDENTITY_QUATERNION;
|
||||||
|
else
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
else if (LengthSquared(b) == 0.0f)
|
||||||
|
return a;
|
||||||
|
|
||||||
|
Quaternion q1 = a;
|
||||||
|
Quaternion q2 = b;
|
||||||
|
|
||||||
|
float cosHalfAngle = q1.w * q2.w + Vector3::Dot(q1.GetVector(), q2.GetVector());
|
||||||
|
|
||||||
|
if (cosHalfAngle >= 1.0f || cosHalfAngle <= -1.0f)
|
||||||
|
return q1;
|
||||||
|
else if (cosHalfAngle < 0.0f)
|
||||||
|
{
|
||||||
|
q2.x = -q2.x;
|
||||||
|
q2.y = -q2.y;
|
||||||
|
q2.z = -q2.z;
|
||||||
|
q2.w = -q2.w;
|
||||||
|
cosHalfAngle = -cosHalfAngle;
|
||||||
|
}
|
||||||
|
|
||||||
|
float blendA;
|
||||||
|
float blendB;
|
||||||
|
if (cosHalfAngle < 0.99f)
|
||||||
|
{
|
||||||
|
float halfAngle = acosf(cosHalfAngle);
|
||||||
|
float sinHalfAngle = sinf(halfAngle);
|
||||||
|
float oneOverSinHalfAngle = 1.0f / sinHalfAngle;
|
||||||
|
blendA = sinf(halfAngle * (1.0f - interpolation)) * oneOverSinHalfAngle;
|
||||||
|
blendB = sinf(halfAngle * interpolation) * oneOverSinHalfAngle;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
blendA = 1.0f - interpolation;
|
||||||
|
blendB = interpolation;
|
||||||
|
}
|
||||||
|
|
||||||
|
Quaternion result(q1.w * blendA + q2.w * blendB, q1.GetVector() * blendA + q2.GetVector() * blendB);
|
||||||
|
if (LengthSquared(result) > 0.0f)
|
||||||
|
return Normalize(result);
|
||||||
|
else
|
||||||
|
return IDENTITY_QUATERNION;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Quaternion operator+(const Quaternion &left, const Quaternion &right)
|
||||||
|
{
|
||||||
|
return Quaternion(
|
||||||
|
left.w + right.w,
|
||||||
|
left.x + right.x,
|
||||||
|
left.y + right.y,
|
||||||
|
left.z + right.z
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Quaternion &operator+=(Quaternion &left, const Quaternion &right)
|
||||||
|
{
|
||||||
|
left = left + right;
|
||||||
|
return left;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Quaternion operator-(const Quaternion &left, const Quaternion &right)
|
||||||
|
{
|
||||||
|
return Quaternion(
|
||||||
|
left.w - right.w,
|
||||||
|
left.x - right.x,
|
||||||
|
left.y - right.y,
|
||||||
|
left.z - right.z
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Quaternion &operator-=(Quaternion &left, const Quaternion &right)
|
||||||
|
{
|
||||||
|
left = left - right;
|
||||||
|
return left;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Quaternion operator*(const Quaternion &left, float right)
|
||||||
|
{
|
||||||
|
return Quaternion(
|
||||||
|
left.w * right,
|
||||||
|
left.x * right,
|
||||||
|
left.y * right,
|
||||||
|
left.z * right
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Quaternion &operator*=(Quaternion &left, float right)
|
||||||
|
{
|
||||||
|
left = left * right;
|
||||||
|
return left;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Quaternion operator*(const Quaternion &left, const Quaternion &right)
|
||||||
|
{
|
||||||
|
return Quaternion(
|
||||||
|
(left.w * right.w) - (left.x * right.x) - (left.y * right.y) - (left.z * right.z),
|
||||||
|
(left.w * right.x) + (left.x * right.w) + (left.y * right.z) - (left.z * right.y),
|
||||||
|
(left.w * right.y) + (left.y * right.w) + (left.z * right.x) - (left.x * right.z),
|
||||||
|
(left.w * right.z) + (left.z * right.w) + (left.x * right.y) - (left.y * right.x)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Quaternion &operator*=(Quaternion &left, const Quaternion &right)
|
||||||
|
{
|
||||||
|
left = left * right;
|
||||||
|
return left;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Quaternion operator/(const Quaternion &left, float right)
|
||||||
|
{
|
||||||
|
return Quaternion(
|
||||||
|
left.w / right,
|
||||||
|
left.x / right,
|
||||||
|
left.y / right,
|
||||||
|
left.z / right
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Quaternion &operator/=(Quaternion &left, float right)
|
||||||
|
{
|
||||||
|
left = left / right;
|
||||||
|
return left;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector3 operator*(const Vector3 &left, const Quaternion &right)
|
||||||
|
{
|
||||||
|
return Vector3(
|
||||||
|
((left.x * ((1.0f - (right.y * (right.y + right.y))) - (right.z * (right.z + right.z)))) + (left.y * ((right.x * (right.y + right.y)) - (right.w * (right.z + right.z))))) + (left.z * ((right.x * (right.z + right.z)) + (right.w * (right.y + right.y)))),
|
||||||
|
((left.x * ((right.x * (right.y + right.y)) + (right.w * (right.z + right.z)))) + (left.y * ((1.0f - (right.x * (right.x + right.x))) - (right.z * (right.z + right.z))))) + (left.z * ((right.y * (right.z + right.z)) - (right.w * (right.x + right.x)))),
|
||||||
|
((left.x * ((right.x * (right.z + right.z)) - (right.w * (right.y + right.y)))) + (left.y * ((right.y * (right.z + right.z)) + (right.w * (right.x + right.x))))) + (left.z * ((1.0f - (right.x * (right.x + right.x))) - (right.y * (right.y + right.y))))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,11 +1,236 @@
|
||||||
#ifndef __VECTOR2_H_INCLUDED__
|
#ifndef __GEOMETRY_VECTOR2_H_INCLUDED__
|
||||||
#define __VECTOR2_H_INCLUDED__
|
#define __GEOMETRY_VECTOR2_H_INCLUDED__
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a 2D vector and provides common methods for vector math.
|
||||||
|
* <p>Referenced/based on code from:</p>
|
||||||
|
* <ul>
|
||||||
|
* <li>3D Math Primer for Graphics and Game Development (Dunn & Parberry, 2002)</li>
|
||||||
|
* <li>http://www.dhpoware.com/source/mathlib.html</li>
|
||||||
|
* </ul>
|
||||||
|
* @author Gered
|
||||||
|
*/
|
||||||
class Vector2
|
class Vector2
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
Vector2() {}
|
||||||
|
|
||||||
|
Vector2(float x, float y)
|
||||||
|
{
|
||||||
|
this->x = x;
|
||||||
|
this->y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2(const float *v)
|
||||||
|
{
|
||||||
|
x = v[0];
|
||||||
|
y = v[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
~Vector2() {}
|
||||||
|
|
||||||
|
void Set(float x, float y);
|
||||||
|
|
||||||
|
static float Distance(const Vector2 &a, const Vector2 &b);
|
||||||
|
static float Dot(const Vector2 &a, const Vector2 &b);
|
||||||
|
static float Length(const Vector2 &v);
|
||||||
|
static float LengthSquared(const Vector2 &v);
|
||||||
|
static Vector2 Normalize(const Vector2 &v);
|
||||||
|
static Vector2 SetLength(const Vector2 &v, float length);
|
||||||
|
|
||||||
float x;
|
float x;
|
||||||
float y;
|
float y;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
bool operator==(const Vector2 &left, const Vector2 &right);
|
||||||
|
Vector2 operator-(const Vector2 &left);
|
||||||
|
Vector2 operator+(const Vector2 &left, const Vector2 &right);
|
||||||
|
Vector2 &operator+=(Vector2 &left, const Vector2 &right);
|
||||||
|
Vector2 operator-(const Vector2 &left, const Vector2 &right);
|
||||||
|
Vector2 &operator-=(Vector2 &left, const Vector2 &right);
|
||||||
|
Vector2 operator*(const Vector2 &left, float right);
|
||||||
|
Vector2 &operator*=(Vector2 &left, float right);
|
||||||
|
Vector2 operator/(const Vector2 &left, float right);
|
||||||
|
Vector2 &operator/=(Vector2 &left, float right);
|
||||||
|
Vector2 operator*(const Vector2 &left, const Vector2 &right);
|
||||||
|
Vector2 &operator*=(Vector2 &left, const Vector2 &right);
|
||||||
|
Vector2 operator/(const Vector2 &left, const Vector2 &right);
|
||||||
|
Vector2 &operator/=(Vector2 &left, const Vector2 &right);
|
||||||
|
|
||||||
|
inline void Vector2::Set(float x, float y)
|
||||||
|
{
|
||||||
|
this->x = x;
|
||||||
|
this->y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the distance between two points.
|
||||||
|
* @param a the first point
|
||||||
|
* @param b the second point
|
||||||
|
* @return the distance between both points
|
||||||
|
*/
|
||||||
|
inline float Vector2::Distance(const Vector2 &a, const Vector2 &b)
|
||||||
|
{
|
||||||
|
return sqrtf(
|
||||||
|
((b.x - a.x) * (b.x - a.x)) +
|
||||||
|
((b.y - a.y) * (b.y - a.y))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the dot product of 2 vectors.
|
||||||
|
* @param a first vector
|
||||||
|
* @param b second vector
|
||||||
|
* @return the dot product
|
||||||
|
*/
|
||||||
|
inline float Vector2::Dot(const Vector2 &a, const Vector2 &b)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
(a.x * b.y) +
|
||||||
|
(a.y * b.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the length (magnitude) of a vector.
|
||||||
|
* @param v vector to calculate the length of
|
||||||
|
* @return the vector length
|
||||||
|
*/
|
||||||
|
inline float Vector2::Length(const Vector2 &v)
|
||||||
|
{
|
||||||
|
return sqrtf(
|
||||||
|
(v.x * v.x) +
|
||||||
|
(v.y * v.y)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the squared length of a vector (the magnitude minus the sqrt
|
||||||
|
* call).
|
||||||
|
* @param v vector to calculate the squared length of
|
||||||
|
* @return squared length of the vector
|
||||||
|
*/
|
||||||
|
inline float Vector2::LengthSquared(const Vector2 &v)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
(v.x * v.x) +
|
||||||
|
(v.y * v.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalizes a vector.
|
||||||
|
* @param v vector to normalize
|
||||||
|
* @return the normalized vector
|
||||||
|
*/
|
||||||
|
inline Vector2 Vector2::Normalize(const Vector2 &v)
|
||||||
|
{
|
||||||
|
float inverseLength = 1.0f / Length(v);
|
||||||
|
return Vector2(
|
||||||
|
v.x * inverseLength,
|
||||||
|
v.y * inverseLength
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjusts a vector so that it's length is equal to the given length.
|
||||||
|
* @param v the original vector to be adjusted
|
||||||
|
* @param length desired vector length (magnitude)
|
||||||
|
* @return the resulting vector after it's length has been converted to the
|
||||||
|
* desired amount
|
||||||
|
*/
|
||||||
|
inline Vector2 Vector2::SetLength(const Vector2 &v, float length)
|
||||||
|
{
|
||||||
|
return v * (length / Length(v));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator==(const Vector2 &left, const Vector2 &right)
|
||||||
|
{
|
||||||
|
return (left.x == right.x && left.y == right.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector2 operator-(const Vector2 &left)
|
||||||
|
{
|
||||||
|
return Vector2(-left.x, -left.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector2 operator+(const Vector2 &left, const Vector2 &right)
|
||||||
|
{
|
||||||
|
return Vector2(left.x + right.x, left.y + right.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector2 &operator+=(Vector2 &left, const Vector2 &right)
|
||||||
|
{
|
||||||
|
left.x += right.x;
|
||||||
|
left.y += right.y;
|
||||||
|
|
||||||
|
return left;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector2 operator-(const Vector2 &left, const Vector2 &right)
|
||||||
|
{
|
||||||
|
return Vector2(left.x - right.x, left.y - right.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector2 &operator-=(Vector2 &left, const Vector2 &right)
|
||||||
|
{
|
||||||
|
left.x -= right.x;
|
||||||
|
left.y -= right.y;
|
||||||
|
|
||||||
|
return left;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector2 operator*(const Vector2 &left, float right)
|
||||||
|
{
|
||||||
|
return Vector2(left.x * right, left.y * right);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector2 &operator*=(Vector2 &left, float right)
|
||||||
|
{
|
||||||
|
left.x *= right;
|
||||||
|
left.y *= right;
|
||||||
|
|
||||||
|
return left;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector2 operator/(const Vector2 &left, float right)
|
||||||
|
{
|
||||||
|
return Vector2(left.x / right, left.y / right);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector2 &operator/=(Vector2 &left, float right)
|
||||||
|
{
|
||||||
|
left.x /= right;
|
||||||
|
left.y /= right;
|
||||||
|
|
||||||
|
return left;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector2 operator*(const Vector2 &left, const Vector2 &right)
|
||||||
|
{
|
||||||
|
return Vector2(left.x * right.x, left.y * right.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector2 &operator*=(Vector2 &left, const Vector2 &right)
|
||||||
|
{
|
||||||
|
left.x *= right.x;
|
||||||
|
left.y *= right.y;
|
||||||
|
|
||||||
|
return left;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector2 operator/(const Vector2 &left, const Vector2 &right)
|
||||||
|
{
|
||||||
|
return Vector2(left.x / right.x, left.y / right.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector2 &operator/=(Vector2 &left, const Vector2 &right)
|
||||||
|
{
|
||||||
|
left.x /= right.x;
|
||||||
|
left.y /= right.y;
|
||||||
|
|
||||||
|
return left;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -1,29 +1,52 @@
|
||||||
#ifndef __VECTOR3_H_INCLUDED__
|
#ifndef __GEOMETRY_VECTOR3_H_INCLUDED__
|
||||||
#define __VECTOR3_H_INCLUDED__
|
#define __GEOMETRY_VECTOR3_H_INCLUDED__
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include "../common.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a 3D vector and provides common methods/operators
|
* <p>Represents a 3D vector and provides common methods for vector math.</p>
|
||||||
* for vector math
|
* <p>Referenced/based on code from:</p>
|
||||||
|
* <ul>
|
||||||
|
* <li>3D Math Primer for Graphics and Game Development (Dunn & Parberry, 2002)</li>
|
||||||
|
* <li>http://www.dhpoware.com/source/mathlib.html</li>
|
||||||
|
* <li>http://www.peroxide.dk/papers/collision/collision.pdf</li>
|
||||||
|
* </ul>
|
||||||
|
* @author Gered
|
||||||
*/
|
*/
|
||||||
class Vector3
|
class Vector3
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Vector3() {}
|
Vector3() {}
|
||||||
Vector3(float vx, float vy, float vz) { x = vx; y = vy; z = vz; }
|
|
||||||
Vector3(const float *v) { x = v[0]; y = v[1]; z = v[2]; }
|
Vector3(float x, float y, float z)
|
||||||
|
{
|
||||||
|
this->x = x;
|
||||||
|
this->y = y;
|
||||||
|
this->z = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3(const float *v)
|
||||||
|
{
|
||||||
|
x = v[0];
|
||||||
|
y = v[1];
|
||||||
|
z = v[2];
|
||||||
|
}
|
||||||
|
|
||||||
~Vector3() {}
|
~Vector3() {}
|
||||||
|
|
||||||
|
void Set(float x, float y, float z);
|
||||||
|
|
||||||
static Vector3 Cross(const Vector3 &a, const Vector3 &b);
|
static Vector3 Cross(const Vector3 &a, const Vector3 &b);
|
||||||
static float Dot(const Vector3 &a, const Vector3 &b);
|
|
||||||
static Vector3 Normalize(const Vector3 &a);
|
|
||||||
static Vector3 SurfaceNormal(const Vector3 &v1, const Vector3 &v2, const Vector3 &v3);
|
|
||||||
static float Magnitude(const Vector3 &a);
|
|
||||||
static float SquaredLength(const Vector3 &a);
|
|
||||||
static Vector3 SetLength(const Vector3 &v, float length);
|
|
||||||
static float Distance(const Vector3 &a, const Vector3 &b);
|
static float Distance(const Vector3 &a, const Vector3 &b);
|
||||||
static bool IsPointInTriangle(const Vector3 &point, const Vector3 &pa, const Vector3 &pb, const Vector3 &pc);
|
static float Dot(const Vector3 &a, const Vector3 &b);
|
||||||
|
static BOOL IsPointInTriangle(const Vector3 &point, const Vector3 &a, const Vector3 &b, const Vector3 &c);
|
||||||
|
static float Length(const Vector3 &v);
|
||||||
|
static float LengthSquared(const Vector3 &v);
|
||||||
|
static Vector3 Normalize(const Vector3 &v);
|
||||||
|
static Vector3 SetLength(const Vector3 &v, float length);
|
||||||
|
static Vector3 SurfaceNormal(const Vector3 &a, const Vector3 &b, const Vector3 &c);
|
||||||
|
static Vector3 Lerp(const Vector3 &a, const Vector3 &b, float interpolation);
|
||||||
|
|
||||||
float x;
|
float x;
|
||||||
float y;
|
float y;
|
||||||
|
@ -46,138 +69,43 @@ Vector3 operator/(const Vector3 &left, const Vector3 &right);
|
||||||
Vector3 &operator/=(Vector3 &left, const Vector3 &right);
|
Vector3 &operator/=(Vector3 &left, const Vector3 &right);
|
||||||
|
|
||||||
#define ZERO_VECTOR Vector3(0.0f, 0.0f, 0.0f)
|
#define ZERO_VECTOR Vector3(0.0f, 0.0f, 0.0f)
|
||||||
|
|
||||||
#define X_AXIS Vector3(1.0f, 0.0f, 0.0f)
|
#define X_AXIS Vector3(1.0f, 0.0f, 0.0f)
|
||||||
#define Y_AXIS Vector3(0.0f, 1.0f, 0.0f)
|
#define Y_AXIS Vector3(0.0f, 1.0f, 0.0f)
|
||||||
#define Z_AXIS Vector3(0.0f, 0.0f, 1.0f)
|
#define Z_AXIS Vector3(0.0f, 0.0f, 1.0f)
|
||||||
|
#define UP Vector3(0.0f, 1.0f, 0.0f)
|
||||||
|
#define DOWN Vector3(0.0f, -1.0f, 0.0f)
|
||||||
|
#define FORWARD Vector3(0.0f, 0.0f, -1.0f)
|
||||||
|
#define BACKWARD Vector3(0.0f, 0.0f, 1.0f)
|
||||||
|
#define LEFT Vector3(-1.0f, 0.0f, 0.0f)
|
||||||
|
#define RIGHT Vector3(1.0f, 0.0f, 0.0f)
|
||||||
|
|
||||||
#define UP_VECTOR Vector3(0.0f, 1.0f, 0.0f)
|
inline void Vector3::Set(float x, float y, float z)
|
||||||
|
{
|
||||||
|
this->x = x;
|
||||||
|
this->y = y;
|
||||||
|
this->z = z;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes the cross product of 2 vectors.
|
* Computes the cross product of 2 vectors.
|
||||||
* x = a.y * b.z - b.y * a.z
|
* @param a first vector
|
||||||
* y = a.z * b.x - b.z * a.x
|
|
||||||
* z = a.x * b.y - b.x * a.y
|
|
||||||
* @param a first vector
|
|
||||||
* @param b second vector
|
* @param b second vector
|
||||||
*
|
* @return the cross product
|
||||||
* @return Vector3 the cross product
|
|
||||||
*/
|
*/
|
||||||
inline Vector3 Vector3::Cross(const Vector3 &a, const Vector3 &b)
|
inline Vector3 Vector3::Cross(const Vector3 &a, const Vector3 &b)
|
||||||
{
|
{
|
||||||
return Vector3(
|
return Vector3(
|
||||||
(a.y * b.z) - (b.y * a.z),
|
(a.y * b.z) - (a.z * b.y),
|
||||||
(a.z * b.x) - (b.z * a.x),
|
(a.z * b.x) - (a.x * b.z),
|
||||||
(a.x * b.y) - (b.x * a.y)
|
(a.x * b.y) - (a.y * b.x)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes the dot product of 2 vectors.
|
* Calculates the distance between two points.
|
||||||
* dot = (a.x * b.x) + (a.y * b.y) + (a.z * b.z)
|
|
||||||
* @param a first vector
|
|
||||||
* @param b second vector
|
|
||||||
*
|
|
||||||
* @return float the dot product
|
|
||||||
*/
|
|
||||||
inline float Vector3::Dot(const Vector3 &a, const Vector3 &b)
|
|
||||||
{
|
|
||||||
return (a.x * b.x) +
|
|
||||||
(a.y * b.y) +
|
|
||||||
(a.z * b.z);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Normalizes a vector
|
|
||||||
* x = a.x / ||a||
|
|
||||||
* y = a.y / ||a||
|
|
||||||
* z = a.z / ||a||
|
|
||||||
* @param a vector to normalize
|
|
||||||
*
|
|
||||||
* @return Vector3 the normalized vector
|
|
||||||
*/
|
|
||||||
inline Vector3 Vector3::Normalize(const Vector3 &a)
|
|
||||||
{
|
|
||||||
float magnitudeSquared = (a.x * a.x) + (a.y * a.y) + (a.z * a.z);
|
|
||||||
if (magnitudeSquared > 0.0f)
|
|
||||||
{
|
|
||||||
float inverseMagnitude = 1.0f / sqrtf(magnitudeSquared);
|
|
||||||
return Vector3(
|
|
||||||
a.x * inverseMagnitude,
|
|
||||||
a.y * inverseMagnitude,
|
|
||||||
a.z * inverseMagnitude
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates a normal vector for the given 3 vectors making up
|
|
||||||
* a triangle (counter-clockwise order)
|
|
||||||
* @param v1 first vertex
|
|
||||||
* @param v2 second vertex
|
|
||||||
* @param v3 third vertex
|
|
||||||
*
|
|
||||||
* @return Vector3 normal vector for the triangle
|
|
||||||
*/
|
|
||||||
inline Vector3 Vector3::SurfaceNormal(const Vector3 &v1, const Vector3 &v2, const Vector3 &v3)
|
|
||||||
{
|
|
||||||
return Vector3::Normalize(Vector3::Cross(v2 - v1, v3 - v1));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns magnitude of a vector.
|
|
||||||
* ||a|| = sqrt((a.x * a.x) + (a.y * a.y) + (a.z * a.z))
|
|
||||||
* @param a vector to calculate the magnitude of
|
|
||||||
*
|
|
||||||
* @return float vector magnitude
|
|
||||||
*/
|
|
||||||
inline float Vector3::Magnitude(const Vector3 &a)
|
|
||||||
{
|
|
||||||
return sqrtf(
|
|
||||||
(a.x * a.x) +
|
|
||||||
(a.y * a.y) +
|
|
||||||
(a.z * a.z)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the squared length of a vector (the magnitude minus
|
|
||||||
* the sqrt call)
|
|
||||||
* @param a vector to calculate the squared length of
|
|
||||||
*
|
|
||||||
* @return float squared length of the vector
|
|
||||||
*/
|
|
||||||
inline float Vector3::SquaredLength(const Vector3 &a)
|
|
||||||
{
|
|
||||||
return
|
|
||||||
(a.x * a.x) +
|
|
||||||
(a.y * a.y) +
|
|
||||||
(a.z * a.z);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adjusts a vector so that it's magnitude is equal to the given
|
|
||||||
* length
|
|
||||||
* @param v the original vector to be adjusted
|
|
||||||
* @param length desired vector magnitude
|
|
||||||
*
|
|
||||||
* @return Vector3 the resulting vector after it's length has
|
|
||||||
* been converted to the desired amount
|
|
||||||
*/
|
|
||||||
inline Vector3 Vector3::SetLength(const Vector3 &v, float length)
|
|
||||||
{
|
|
||||||
float magnitude = Vector3::Magnitude(v);
|
|
||||||
return v * (length / magnitude);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the distance between two points
|
|
||||||
* @param a the first point
|
* @param a the first point
|
||||||
* @param b the second point
|
* @param b the second point
|
||||||
*
|
* @return the distance between both points
|
||||||
* @return float the distance between both points
|
|
||||||
*/
|
*/
|
||||||
inline float Vector3::Distance(const Vector3 &a, const Vector3 &b)
|
inline float Vector3::Distance(const Vector3 &a, const Vector3 &b)
|
||||||
{
|
{
|
||||||
|
@ -189,37 +117,131 @@ inline float Vector3::Distance(const Vector3 &a, const Vector3 &b)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if a given point lies inside a triangle or not
|
* Computes the dot product of 2 vectors.
|
||||||
|
* @param a first vector
|
||||||
|
* @param b second vector
|
||||||
|
* @return the dot product
|
||||||
|
*/
|
||||||
|
inline float Vector3::Dot(const Vector3 &a, const Vector3 &b)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
(a.x * b.x) +
|
||||||
|
(a.y * b.y) +
|
||||||
|
(a.z * b.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a given point lies inside a triangle or not.
|
||||||
* @param point point to test
|
* @param point point to test
|
||||||
* @param a first vector of the triangle
|
* @param a first vector of the triangle
|
||||||
* @param b second vector of the triangle
|
* @param b second vector of the triangle
|
||||||
* @param c third vector of the triangle
|
* @param c third vector of the triangle
|
||||||
*
|
* @return TRUE if the point lies inside the triangle
|
||||||
* @return BOOL TRUE if the point lies inside the triangle,
|
|
||||||
* FALSE if it doesn't
|
|
||||||
*/
|
*/
|
||||||
inline bool Vector3::IsPointInTriangle(const Vector3 &point, const Vector3 &pa, const Vector3 &pb, const Vector3 &pc)
|
inline BOOL Vector3::IsPointInTriangle(const Vector3 &point, const Vector3 &a, const Vector3 &b, const Vector3 &c)
|
||||||
{
|
{
|
||||||
Vector3 edge1 = pb - pa;
|
Vector3 v0 = c - a;
|
||||||
Vector3 edge2 = pc - pa;
|
Vector3 v1 = b - a;
|
||||||
|
Vector3 v2 = point - a;
|
||||||
float a = Vector3::Dot(edge1, edge1);
|
|
||||||
float b = Vector3::Dot(edge1, edge2);
|
float dot00 = (v0.x * v0.x) + (v0.y * v0.y) + (v0.z * v0.z);
|
||||||
float c = Vector3::Dot(edge2, edge2);
|
float dot01 = (v0.x * v1.x) + (v0.y * v1.y) + (v0.z * v1.z);
|
||||||
float ac_bb = (a * c) - (b * b);
|
float dot02 = (v0.x * v2.x) + (v0.y * v2.y) + (v0.z * v2.z);
|
||||||
Vector3 vp(point.x - pa.x, point.y - pa.y, point.z - pa.z);
|
float dot11 = (v1.x * v1.x) + (v1.y * v1.y) + (v1.z * v1.z);
|
||||||
|
float dot12 = (v1.x * v2.x) + (v1.y * v2.y) + (v1.z * v2.z);
|
||||||
float d = Vector3::Dot(vp, edge1);
|
|
||||||
float e = Vector3::Dot(vp, edge2);
|
float denom = dot00 * dot11 - dot01 * dot01;
|
||||||
float x = (d * c) - (e * b);
|
if (denom == 0)
|
||||||
float y = (e * a) - (d * b);
|
return FALSE;
|
||||||
float z = x + y - ac_bb;
|
|
||||||
|
float u = (dot11 * dot02 - dot01 * dot12) / denom;
|
||||||
int result = (( ((unsigned int&) z)& ~(((unsigned int&) x)|((unsigned int&) y)) ) & 0x80000000);
|
float v = (dot00 * dot12 - dot01 * dot02) / denom;
|
||||||
if (result == 0)
|
|
||||||
return false;
|
if (u >= 0 && v >= 0 && u + v <= 1)
|
||||||
|
return TRUE;
|
||||||
else
|
else
|
||||||
return true;
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the length (magnitude) of a vector.
|
||||||
|
* @param v vector to calculate the length of
|
||||||
|
* @return the vector length
|
||||||
|
*/
|
||||||
|
inline float Vector3::Length(const Vector3 &v)
|
||||||
|
{
|
||||||
|
return sqrtf(
|
||||||
|
(v.x * v.x) +
|
||||||
|
(v.y * v.y) +
|
||||||
|
(v.z * v.z)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the squared length of a vector (the magnitude minus the sqrt
|
||||||
|
* call).
|
||||||
|
* @param v vector to calculate the squared length of
|
||||||
|
* @return squared length of the vector
|
||||||
|
*/
|
||||||
|
inline float Vector3::LengthSquared(const Vector3 &v)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
(v.x * v.x) +
|
||||||
|
(v.y * v.y) +
|
||||||
|
(v.z * v.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalizes a vector.
|
||||||
|
* @param v vector to normalize
|
||||||
|
* @return the normalized vector
|
||||||
|
*/
|
||||||
|
inline Vector3 Vector3::Normalize(const Vector3 &v)
|
||||||
|
{
|
||||||
|
float inverseLength = 1.0f / Length(v);
|
||||||
|
return Vector3(
|
||||||
|
v.x * inverseLength,
|
||||||
|
v.y * inverseLength,
|
||||||
|
v.z * inverseLength
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjusts a vector so that it's length is equal to the given
|
||||||
|
* length.
|
||||||
|
* @param v the original vector to be adjusted
|
||||||
|
* @param length desired vector length (magnitude)
|
||||||
|
* @return the resulting vector after it's length has been converted to the
|
||||||
|
* desired amount
|
||||||
|
*/
|
||||||
|
inline Vector3 Vector3::SetLength(const Vector3 &v, float length)
|
||||||
|
{
|
||||||
|
return v * (length / Length(v));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates a normal vector for the given 3 vectors making up a
|
||||||
|
* triangle (counter clockwise order).
|
||||||
|
* @param a first vertex
|
||||||
|
* @param b second vertex
|
||||||
|
* @param c third vertex
|
||||||
|
* @return normal vector for the triangle
|
||||||
|
*/
|
||||||
|
inline Vector3 Vector3::SurfaceNormal(const Vector3 &a, const Vector3 &b, const Vector3 &c)
|
||||||
|
{
|
||||||
|
return Normalize(Cross((b - a), (c - a)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Linearly interpolates between two vectors.
|
||||||
|
* @param a the first vector
|
||||||
|
* @param b the second vector
|
||||||
|
* @param interpolation the amount to interpolate
|
||||||
|
* @return Vector3 the interpolated vector
|
||||||
|
*/
|
||||||
|
inline Vector3 Vector3::Lerp(const Vector3 &a, const Vector3 &b, float interpolation)
|
||||||
|
{
|
||||||
|
return a + (b - a) * interpolation;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool operator==(const Vector3 &left, const Vector3 &right)
|
inline bool operator==(const Vector3 &left, const Vector3 &right)
|
||||||
|
@ -316,4 +338,4 @@ inline Vector3 &operator/=(Vector3 &left, const Vector3 &right)
|
||||||
return left;
|
return left;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Reference in a new issue