mirror of https://github.com/axmolengine/axmol.git
Updates to latest version of kazmath
This commit is contained in:
parent
bf1413e71f
commit
4fe3b16287
|
@ -1 +1 @@
|
|||
8fad051dc33d390c01df304fee2a78e22785136f
|
||||
e8eaf27db3b5c75d371db6c73f434cea5c0f970d
|
|
@ -1 +1 @@
|
|||
9da17496043155938cbd8973b01514f220e7192b
|
||||
d70aa2f168a737e7a152028e2156e3099e01c3aa
|
|
@ -191,7 +191,7 @@ void Frustum::setupProjectionOrthogonal(const cocos2d::ViewTransform &view, floa
|
|||
normal = cDir;
|
||||
kmVec3Scale(&point, &cDir, nearPlane);
|
||||
kmVec3Add(&point, &point, &cc);
|
||||
kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_NEAR], &point, &normal);
|
||||
kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_NEAR], &point, &normal);
|
||||
}
|
||||
|
||||
//far
|
||||
|
@ -201,7 +201,7 @@ void Frustum::setupProjectionOrthogonal(const cocos2d::ViewTransform &view, floa
|
|||
kmVec3Scale(&normal, &cDir, -1);
|
||||
kmVec3Scale(&point, &cDir, farPlane);
|
||||
kmVec3Add(&point, &point, &cc);
|
||||
kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_FAR], &point, &normal);
|
||||
kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_FAR], &point, &normal);
|
||||
}
|
||||
|
||||
//left
|
||||
|
@ -211,7 +211,7 @@ void Frustum::setupProjectionOrthogonal(const cocos2d::ViewTransform &view, floa
|
|||
normal = cRight;
|
||||
kmVec3Scale(&point, &cRight, -width * 0.5);
|
||||
kmVec3Add(&point, &point, &cc);
|
||||
kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_LEFT], &point, &normal);
|
||||
kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_LEFT], &point, &normal);
|
||||
}
|
||||
|
||||
//right
|
||||
|
@ -221,7 +221,7 @@ void Frustum::setupProjectionOrthogonal(const cocos2d::ViewTransform &view, floa
|
|||
kmVec3Scale(&normal, &cRight, -1);
|
||||
kmVec3Scale(&point, &cRight, width * 0.5);
|
||||
kmVec3Add(&point, &point, &cc);
|
||||
kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_RIGHT], &point, &normal);
|
||||
kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_RIGHT], &point, &normal);
|
||||
}
|
||||
|
||||
//bottom
|
||||
|
@ -231,7 +231,7 @@ void Frustum::setupProjectionOrthogonal(const cocos2d::ViewTransform &view, floa
|
|||
normal = cUp;
|
||||
kmVec3Scale(&point, &cUp, -height * 0.5);
|
||||
kmVec3Add(&point, &point, &cc);
|
||||
kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_BOTTOM], &point, &normal);
|
||||
kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_BOTTOM], &point, &normal);
|
||||
}
|
||||
|
||||
//top
|
||||
|
@ -241,7 +241,7 @@ void Frustum::setupProjectionOrthogonal(const cocos2d::ViewTransform &view, floa
|
|||
kmVec3Scale(&normal, &cUp, -1);
|
||||
kmVec3Scale(&point, &cUp, height * 0.5);
|
||||
kmVec3Add(&point, &point, &cc);
|
||||
kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_TOP], &point, &normal);
|
||||
kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_TOP], &point, &normal);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -267,14 +267,14 @@ void Frustum::setupProjectionPerspective(const ViewTransform& view, float left,
|
|||
|
||||
//near
|
||||
{
|
||||
kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_NEAR], &nearCenter, &cDir);
|
||||
kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_NEAR], &nearCenter, &cDir);
|
||||
}
|
||||
|
||||
//far
|
||||
{
|
||||
kmVec3 normal;
|
||||
kmVec3Scale(&normal, &cDir, -1);
|
||||
kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_FAR], &farCenter, &normal);
|
||||
kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_FAR], &farCenter, &normal);
|
||||
}
|
||||
|
||||
//left
|
||||
|
@ -288,7 +288,7 @@ void Frustum::setupProjectionPerspective(const ViewTransform& view, float left,
|
|||
kmVec3Cross(&normal, &normal, &cUp);
|
||||
kmVec3Normalize(&normal, &normal);
|
||||
|
||||
kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_LEFT], &point, &normal);
|
||||
kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_LEFT], &point, &normal);
|
||||
}
|
||||
|
||||
//right
|
||||
|
@ -302,7 +302,7 @@ void Frustum::setupProjectionPerspective(const ViewTransform& view, float left,
|
|||
kmVec3Cross(&normal, &cUp, &normal);
|
||||
kmVec3Normalize(&normal, &normal);
|
||||
|
||||
kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_RIGHT], &point, &normal);
|
||||
kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_RIGHT], &point, &normal);
|
||||
}
|
||||
|
||||
//bottom
|
||||
|
@ -316,7 +316,7 @@ void Frustum::setupProjectionPerspective(const ViewTransform& view, float left,
|
|||
kmVec3Cross(&normal, &cRight, &normal);
|
||||
kmVec3Normalize(&normal, &normal);
|
||||
|
||||
kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_BOTTOM], &point, &normal);
|
||||
kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_BOTTOM], &point, &normal);
|
||||
}
|
||||
|
||||
//top
|
||||
|
@ -330,7 +330,7 @@ void Frustum::setupProjectionPerspective(const ViewTransform& view, float left,
|
|||
kmVec3Cross(&normal, &normal, &cRight);
|
||||
kmVec3Normalize(&normal, &normal);
|
||||
|
||||
kmPlaneFromPointNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_TOP], &point, &normal);
|
||||
kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_TOP], &point, &normal);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,76 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2008, Luke Benstead.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef MAT3_H_INCLUDED
|
||||
#define MAT3_H_INCLUDED
|
||||
|
||||
#include "CCPlatformMacros.h"
|
||||
#include "utility.h"
|
||||
|
||||
struct kmVec3;
|
||||
struct kmQuaternion;
|
||||
|
||||
typedef struct kmMat3{
|
||||
kmScalar mat[9];
|
||||
} kmMat3;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
CC_DLL kmMat3* const kmMat3Fill(kmMat3* pOut, const kmScalar* pMat);
|
||||
CC_DLL kmMat3* const kmMat3Adjugate(kmMat3* pOut, const kmMat3* pIn);
|
||||
CC_DLL kmMat3* const kmMat3Identity(kmMat3* pOut);
|
||||
CC_DLL kmMat3* const kmMat3Inverse(kmMat3* pOut, const kmScalar pDeterminate, const kmMat3* pM);
|
||||
CC_DLL const int kmMat3IsIdentity(const kmMat3* pIn);
|
||||
CC_DLL kmMat3* const kmMat3Transpose(kmMat3* pOut, const kmMat3* pIn);
|
||||
CC_DLL const kmScalar kmMat3Determinant(const kmMat3* pIn);
|
||||
CC_DLL kmMat3* const kmMat3Multiply(kmMat3* pOut, const kmMat3* pM1, const kmMat3* pM2);
|
||||
CC_DLL kmMat3* const kmMat3ScalarMultiply(kmMat3* pOut, const kmMat3* pM, const kmScalar pFactor);
|
||||
|
||||
CC_DLL kmMat3* const kmMat3RotationAxisAngle(kmMat3* pOut, const struct kmVec3* axis, kmScalar radians);
|
||||
CC_DLL struct kmVec3* const kmMat3RotationToAxisAngle(struct kmVec3* pAxis, kmScalar* radians, const kmMat3* pIn);
|
||||
|
||||
CC_DLL kmMat3* const kmMat3Assign(kmMat3* pOut, const kmMat3* pIn);
|
||||
CC_DLL const int kmMat3AreEqual(const kmMat3* pM1, const kmMat3* pM2);
|
||||
|
||||
CC_DLL kmMat3* const kmMat3RotationX(kmMat3* pOut, const kmScalar radians);
|
||||
CC_DLL kmMat3* const kmMat3RotationY(kmMat3* pOut, const kmScalar radians);
|
||||
CC_DLL kmMat3* const kmMat3RotationZ(kmMat3* pOut, const kmScalar radians);
|
||||
|
||||
CC_DLL kmMat3* const kmMat3Rotation(kmMat3* pOut, const kmScalar radians);
|
||||
CC_DLL kmMat3* const kmMat3Scaling(kmMat3* pOut, const kmScalar x, const kmScalar y);
|
||||
CC_DLL kmMat3* const kmMat3Translation(kmMat3* pOut, const kmScalar x, const kmScalar y);
|
||||
|
||||
CC_DLL kmMat3* const kmMat3RotationQuaternion(kmMat3* pOut, const struct kmQuaternion* pIn);
|
||||
CC_DLL kmMat3* const kmMat3RotationAxisAngle(kmMat3* pOut, const struct kmVec3* axis, kmScalar radians);
|
||||
CC_DLL struct kmVec3* const kmMat3RotationToAxisAngle(struct kmVec3* pAxis, kmScalar* radians, const kmMat3* pIn);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // MAT3_H_INCLUDED
|
||||
|
|
@ -1,94 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2008, Luke Benstead.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef MAT4_H_INCLUDED
|
||||
#define MAT4_H_INCLUDED
|
||||
|
||||
#include "CCPlatformMacros.h"
|
||||
#include "utility.h"
|
||||
|
||||
struct kmVec3;
|
||||
struct kmMat3;
|
||||
struct kmQuaternion;
|
||||
struct kmPlane;
|
||||
|
||||
/*
|
||||
A 4x4 matrix
|
||||
|
||||
| 0 4 8 12 |
|
||||
mat = | 1 5 9 13 |
|
||||
| 2 6 10 14 |
|
||||
| 3 7 11 15 |
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct kmMat4 {
|
||||
kmScalar mat[16];
|
||||
} kmMat4;
|
||||
|
||||
CC_DLL kmMat4* const kmMat4Fill(kmMat4* pOut, const kmScalar* pMat);
|
||||
|
||||
|
||||
CC_DLL kmMat4* const kmMat4Identity(kmMat4* pOut);
|
||||
|
||||
CC_DLL kmMat4* const kmMat4Inverse(kmMat4* pOut, const kmMat4* pM);
|
||||
|
||||
|
||||
CC_DLL const int kmMat4IsIdentity(const kmMat4* pIn);
|
||||
|
||||
CC_DLL kmMat4* const kmMat4Transpose(kmMat4* pOut, const kmMat4* pIn);
|
||||
CC_DLL kmMat4* const kmMat4Multiply(kmMat4* pOut, const kmMat4* pM1, const kmMat4* pM2);
|
||||
|
||||
CC_DLL kmMat4* const kmMat4Assign(kmMat4* pOut, const kmMat4* pIn);
|
||||
CC_DLL const int kmMat4AreEqual(const kmMat4* pM1, const kmMat4* pM2);
|
||||
|
||||
CC_DLL kmMat4* const kmMat4RotationX(kmMat4* pOut, const kmScalar radians);
|
||||
CC_DLL kmMat4* const kmMat4RotationY(kmMat4* pOut, const kmScalar radians);
|
||||
CC_DLL kmMat4* const kmMat4RotationZ(kmMat4* pOut, const kmScalar radians);
|
||||
CC_DLL kmMat4* const kmMat4RotationPitchYawRoll(kmMat4* pOut, const kmScalar pitch, const kmScalar yaw, const kmScalar roll);
|
||||
CC_DLL kmMat4* const kmMat4RotationQuaternion(kmMat4* pOut, const struct kmQuaternion* pQ);
|
||||
CC_DLL kmMat4* const kmMat4RotationTranslation(kmMat4* pOut, const struct kmMat3* rotation, const struct kmVec3* translation);
|
||||
CC_DLL kmMat4* const kmMat4Scaling(kmMat4* pOut, const kmScalar x, const kmScalar y, const kmScalar z);
|
||||
CC_DLL kmMat4* const kmMat4Translation(kmMat4* pOut, const kmScalar x, const kmScalar y, const kmScalar z);
|
||||
|
||||
CC_DLL struct kmVec3* const kmMat4GetUpVec3(struct kmVec3* pOut, const kmMat4* pIn);
|
||||
CC_DLL struct kmVec3* const kmMat4GetRightVec3(struct kmVec3* pOut, const kmMat4* pIn);
|
||||
CC_DLL struct kmVec3* const kmMat4GetForwardVec3(struct kmVec3* pOut, const kmMat4* pIn);
|
||||
|
||||
CC_DLL kmMat4* const kmMat4PerspectiveProjection(kmMat4* pOut, kmScalar fovY, kmScalar aspect, kmScalar zNear, kmScalar zFar);
|
||||
CC_DLL kmMat4* const kmMat4OrthographicProjection(kmMat4* pOut, kmScalar left, kmScalar right, kmScalar bottom, kmScalar top, kmScalar nearVal, kmScalar farVal);
|
||||
CC_DLL kmMat4* const kmMat4LookAt(kmMat4* pOut, const struct kmVec3* pEye, const struct kmVec3* pCenter, const struct kmVec3* pUp);
|
||||
|
||||
CC_DLL kmMat4* const kmMat4RotationAxisAngle(kmMat4* pOut, const struct kmVec3* axis, kmScalar radians);
|
||||
CC_DLL struct kmMat3* const kmMat4ExtractRotation(struct kmMat3* pOut, const kmMat4* pIn);
|
||||
CC_DLL struct kmPlane* const kmMat4ExtractPlane(struct kmPlane* pOut, const kmMat4* pIn, const kmEnum plane);
|
||||
CC_DLL struct kmVec3* const kmMat4RotationToAxisAngle(struct kmVec3* pAxis, kmScalar* radians, const kmMat4* pIn);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* MAT4_H_INCLUDED */
|
|
@ -1,114 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2008, Luke Benstead.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef QUATERNION_H_INCLUDED
|
||||
#define QUATERNION_H_INCLUDED
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "CCPlatformMacros.h"
|
||||
#include "utility.h"
|
||||
|
||||
struct kmMat4;
|
||||
struct kmMat3;
|
||||
struct kmVec3;
|
||||
|
||||
typedef struct kmQuaternion {
|
||||
kmScalar x;
|
||||
kmScalar y;
|
||||
kmScalar z;
|
||||
kmScalar w;
|
||||
} kmQuaternion;
|
||||
|
||||
CC_DLL kmQuaternion* const kmQuaternionConjugate(kmQuaternion* pOut, const kmQuaternion* pIn); ///< Returns pOut, sets pOut to the conjugate of pIn
|
||||
|
||||
CC_DLL const kmScalar kmQuaternionDot(const kmQuaternion* q1, const kmQuaternion* q2); ///< Returns the dot product of the 2 quaternions
|
||||
|
||||
CC_DLL kmQuaternion* kmQuaternionExp(kmQuaternion* pOut, const kmQuaternion* pIn); ///< Returns the exponential of the quaternion
|
||||
|
||||
///< Makes the passed quaternion an identity quaternion
|
||||
|
||||
CC_DLL kmQuaternion* kmQuaternionIdentity(kmQuaternion* pOut);
|
||||
|
||||
///< Returns the inverse of the passed Quaternion
|
||||
|
||||
CC_DLL kmQuaternion* kmQuaternionInverse(kmQuaternion* pOut,
|
||||
const kmQuaternion* pIn);
|
||||
|
||||
///< Returns true if the quaternion is an identity quaternion
|
||||
|
||||
CC_DLL int kmQuaternionIsIdentity(const kmQuaternion* pIn);
|
||||
|
||||
///< Returns the length of the quaternion
|
||||
|
||||
CC_DLL kmScalar kmQuaternionLength(const kmQuaternion* pIn);
|
||||
|
||||
///< Returns the length of the quaternion squared (prevents a sqrt)
|
||||
|
||||
CC_DLL kmScalar kmQuaternionLengthSq(const kmQuaternion* pIn);
|
||||
|
||||
///< Returns the natural logarithm
|
||||
|
||||
CC_DLL kmQuaternion* kmQuaternionLn(kmQuaternion* pOut, const kmQuaternion* pIn);
|
||||
|
||||
///< Multiplies 2 quaternions together
|
||||
|
||||
CC_DLL kmQuaternion* kmQuaternionMultiply(kmQuaternion* pOut, const kmQuaternion* q1, const kmQuaternion* q2);
|
||||
|
||||
///< Normalizes a quaternion
|
||||
|
||||
CC_DLL kmQuaternion* kmQuaternionNormalize(kmQuaternion* pOut, const kmQuaternion* pIn);
|
||||
|
||||
///< Rotates a quaternion around an axis
|
||||
|
||||
CC_DLL kmQuaternion* kmQuaternionRotationAxis(kmQuaternion* pOut, const struct kmVec3* pV, kmScalar angle);
|
||||
|
||||
///< Creates a quaternion from a rotation matrix
|
||||
|
||||
CC_DLL kmQuaternion* kmQuaternionRotationMatrix(kmQuaternion* pOut, const struct kmMat3* pIn);
|
||||
|
||||
///< Create a quaternion from yaw, pitch and roll
|
||||
|
||||
CC_DLL kmQuaternion* kmQuaternionRotationYawPitchRoll(kmQuaternion* pOut, kmScalar yaw, kmScalar pitch, kmScalar roll);
|
||||
///< Interpolate between 2 quaternions
|
||||
CC_DLL kmQuaternion* kmQuaternionSlerp(kmQuaternion* pOut, const kmQuaternion* q1, const kmQuaternion* q2, kmScalar t);
|
||||
|
||||
///< Get the axis and angle of rotation from a quaternion
|
||||
CC_DLL void kmQuaternionToAxisAngle(const kmQuaternion* pIn, struct kmVec3* pVector, kmScalar* pAngle);
|
||||
|
||||
///< Scale a quaternion
|
||||
CC_DLL kmQuaternion* kmQuaternionScale(kmQuaternion* pOut, const kmQuaternion* pIn, kmScalar s);
|
||||
CC_DLL kmQuaternion* kmQuaternionAssign(kmQuaternion* pOut, const kmQuaternion* pIn);
|
||||
CC_DLL kmQuaternion* kmQuaternionAdd(kmQuaternion* pOut, const kmQuaternion* pQ1, const kmQuaternion* pQ2);
|
||||
CC_DLL kmQuaternion* kmQuaternionRotationBetweenVec3(kmQuaternion* pOut, const struct kmVec3* vec1, const struct kmVec3* vec2, const struct kmVec3* fallback);
|
||||
CC_DLL struct kmVec3* kmQuaternionMultiplyVec3(struct kmVec3* pOut, const kmQuaternion* q, const struct kmVec3* v);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,66 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2008, Luke Benstead.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef VEC2_H_INCLUDED
|
||||
#define VEC2_H_INCLUDED
|
||||
|
||||
#include "CCPlatformMacros.h"
|
||||
|
||||
struct kmMat3;
|
||||
|
||||
#ifndef kmScalar
|
||||
#define kmScalar float
|
||||
#endif
|
||||
|
||||
#pragma pack(push) /* push current alignment to stack */
|
||||
#pragma pack(1) /* set alignment to 1 byte boundary */
|
||||
typedef struct kmVec2 {
|
||||
kmScalar x;
|
||||
kmScalar y;
|
||||
} kmVec2;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
CC_DLL kmVec2* kmVec2Fill(kmVec2* pOut, kmScalar x, kmScalar y);
|
||||
CC_DLL kmScalar kmVec2Length(const kmVec2* pIn); ///< Returns the length of the vector
|
||||
CC_DLL kmScalar kmVec2LengthSq(const kmVec2* pIn); ///< Returns the square of the length of the vector
|
||||
CC_DLL kmVec2* kmVec2Normalize(kmVec2* pOut, const kmVec2* pIn); ///< Returns the vector passed in set to unit length
|
||||
CC_DLL kmVec2* kmVec2Add(kmVec2* pOut, const kmVec2* pV1, const kmVec2* pV2); ///< Adds 2 vectors and returns the result
|
||||
CC_DLL kmScalar kmVec2Dot(const kmVec2* pV1, const kmVec2* pV2); /** Returns the Dot product which is the cosine of the angle between the two vectors multiplied by their lengths */
|
||||
CC_DLL kmVec2* kmVec2Subtract(kmVec2* pOut, const kmVec2* pV1, const kmVec2* pV2); ///< Subtracts 2 vectors and returns the result
|
||||
CC_DLL kmVec2* kmVec2Transform(kmVec2* pOut, const kmVec2* pV1, const struct kmMat3* pM); /** Transform the Vector */
|
||||
CC_DLL kmVec2* kmVec2TransformCoord(kmVec2* pOut, const kmVec2* pV, const struct kmMat3* pM); ///<Transforms a 2D vector by a given matrix, projecting the result back into w = 1.
|
||||
CC_DLL kmVec2* kmVec2Scale(kmVec2* pOut, const kmVec2* pIn, const kmScalar s); ///< Scales a vector to length s
|
||||
CC_DLL int kmVec2AreEqual(const kmVec2* p1, const kmVec2* p2); ///< Returns 1 if both vectors are equal
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif // VEC2_H_INCLUDED
|
|
@ -1,69 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2008, Luke Benstead.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef VEC3_H_INCLUDED
|
||||
#define VEC3_H_INCLUDED
|
||||
|
||||
#include "CCPlatformMacros.h"
|
||||
#include <assert.h>
|
||||
|
||||
#ifndef kmScalar
|
||||
#define kmScalar float
|
||||
#endif
|
||||
|
||||
struct kmMat4;
|
||||
|
||||
typedef struct kmVec3 {
|
||||
kmScalar x;
|
||||
kmScalar y;
|
||||
kmScalar z;
|
||||
} kmVec3;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
CC_DLL kmVec3* kmVec3Fill(kmVec3* pOut, kmScalar x, kmScalar y, kmScalar z);
|
||||
CC_DLL kmScalar kmVec3Length(const kmVec3* pIn); /** Returns the length of the vector */
|
||||
CC_DLL kmScalar kmVec3LengthSq(const kmVec3* pIn); /** Returns the square of the length of the vector */
|
||||
CC_DLL kmVec3* kmVec3Normalize(kmVec3* pOut, const kmVec3* pIn); /** Returns the vector passed in set to unit length */
|
||||
CC_DLL kmVec3* kmVec3Cross(kmVec3* pOut, const kmVec3* pV1, const kmVec3* pV2); /** Returns a vector perpendicular to 2 other vectors */
|
||||
CC_DLL kmScalar kmVec3Dot(const kmVec3* pV1, const kmVec3* pV2); /** Returns the cosine of the angle between 2 vectors */
|
||||
CC_DLL kmVec3* kmVec3Add(kmVec3* pOut, const kmVec3* pV1, const kmVec3* pV2); /** Adds 2 vectors and returns the result */
|
||||
CC_DLL kmVec3* kmVec3Subtract(kmVec3* pOut, const kmVec3* pV1, const kmVec3* pV2); /** Subtracts 2 vectors and returns the result */
|
||||
CC_DLL kmVec3* kmVec3Transform(kmVec3* pOut, const kmVec3* pV1, const struct kmMat4* pM); /** Transforms a vector (assuming w=1) by a given matrix */
|
||||
CC_DLL kmVec3* kmVec3TransformNormal(kmVec3* pOut, const kmVec3* pV, const struct kmMat4* pM);/**Transforms a 3D normal by a given matrix */
|
||||
CC_DLL kmVec3* kmVec3TransformCoord(kmVec3* pOut, const kmVec3* pV, const struct kmMat4* pM); /**Transforms a 3D vector by a given matrix, projecting the result back into w = 1. */
|
||||
CC_DLL kmVec3* kmVec3Scale(kmVec3* pOut, const kmVec3* pIn, const kmScalar s); /** Scales a vector to length s */
|
||||
CC_DLL int kmVec3AreEqual(const kmVec3* p1, const kmVec3* p2);
|
||||
CC_DLL kmVec3* kmVec3InverseTransform(kmVec3* pOut, const kmVec3* pV, const struct kmMat4* pM);
|
||||
CC_DLL kmVec3* kmVec3InverseTransformNormal(kmVec3* pOut, const kmVec3* pVect, const struct kmMat4* pM);
|
||||
CC_DLL kmVec3* kmVec3Assign(kmVec3* pOut, const kmVec3* pIn);
|
||||
CC_DLL kmVec3* kmVec3Zero(kmVec3* pOut);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* VEC3_H_INCLUDED */
|
|
@ -0,0 +1,18 @@
|
|||
|
||||
#ADD_LIBRARY(Kazmath STATIC ${KAZMATH_SRCS})
|
||||
#INSTALL(TARGETS Kazmath ARCHIVE DESTINATION lib)
|
||||
FIND_PACKAGE(Threads REQUIRED)
|
||||
ADD_LIBRARY(kazmath SHARED ${KAZMATH_SOURCES})
|
||||
TARGET_LINK_LIBRARIES(kazmath ${CMAKE_THREAD_LIBS_INIT})
|
||||
SET_TARGET_PROPERTIES(kazmath
|
||||
PROPERTIES
|
||||
VERSION 0.0.1
|
||||
SOVERSION 1)
|
||||
INSTALL(TARGETS kazmath DESTINATION lib)
|
||||
|
||||
#ADD_LIBRARY(KazmathGL STATIC ${GL_UTILS_SRCS})
|
||||
#INSTALL(TARGETS KazmathGL ARCHIVE DESTINATION lib)
|
||||
|
||||
INSTALL(FILES ${KAZMATH_HEADERS} DESTINATION include/kazmath)
|
||||
INSTALL(FILES ${GL_UTILS_HEADERS} DESTINATION include/kazmath/GL)
|
||||
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../cmake_modules/KAZMATHConfig.cmake DESTINATION ${CMAKE_INSTALL_PREFIX}/share/kazmath)
|
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
Copyright (c) 2008, Luke Benstead.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "aabb.h"
|
||||
|
||||
|
||||
/**
|
||||
Initializes the AABB around a central point. If centre is NULL then the origin
|
||||
is used. Returns pBox.
|
||||
*/
|
||||
kmAABB* kmAABBInitialize(kmAABB* pBox, const kmVec3* centre, const kmScalar width, const kmScalar height, const kmScalar depth) {
|
||||
if(!pBox) return 0;
|
||||
|
||||
kmVec3 origin;
|
||||
kmVec3* point = centre ? (kmVec3*) centre : &origin;
|
||||
kmVec3Zero(&origin);
|
||||
|
||||
pBox->min.x = point->x - (width / 2);
|
||||
pBox->min.y = point->y - (height / 2);
|
||||
pBox->min.z = point->z - (depth / 2);
|
||||
|
||||
pBox->max.x = point->x + (width / 2);
|
||||
pBox->max.y = point->y + (height / 2);
|
||||
pBox->max.z = point->z + (depth / 2);
|
||||
|
||||
return pBox;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns KM_TRUE if point is in the specified AABB, returns
|
||||
* KM_FALSE otherwise.
|
||||
*/
|
||||
int kmAABBContainsPoint(const kmAABB* pBox, const kmVec3* pPoint)
|
||||
{
|
||||
if(pPoint->x >= pBox->min.x && pPoint->x <= pBox->max.x &&
|
||||
pPoint->y >= pBox->min.y && pPoint->y <= pBox->max.y &&
|
||||
pPoint->z >= pBox->min.z && pPoint->z <= pBox->max.z) {
|
||||
return KM_TRUE;
|
||||
}
|
||||
|
||||
return KM_FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns pIn to pOut, returns pOut.
|
||||
*/
|
||||
kmAABB* kmAABBAssign(kmAABB* pOut, const kmAABB* pIn)
|
||||
{
|
||||
kmVec3Assign(&pOut->min, &pIn->min);
|
||||
kmVec3Assign(&pOut->max, &pIn->max);
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scales pIn by s, stores the resulting AABB in pOut. Returns pOut
|
||||
*/
|
||||
kmAABB* kmAABBScale(kmAABB* pOut, const kmAABB* pIn, kmScalar s)
|
||||
{
|
||||
assert(0 && "Not implemented");
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmBool kmAABBIntersectsTriangle(kmAABB* box, const kmVec3* p1, const kmVec3* p2, const kmVec3* p3) {
|
||||
assert(0 && "Not implemented");
|
||||
return KM_TRUE;
|
||||
}
|
||||
|
||||
kmEnum kmAABBContainsAABB(const kmAABB* container, const kmAABB* to_check) {
|
||||
kmVec3 corners[8];
|
||||
kmEnum result = KM_CONTAINS_ALL;
|
||||
kmBool found = KM_FALSE;
|
||||
|
||||
kmVec3Fill(&corners[0], to_check->min.x, to_check->min.y, to_check->min.z);
|
||||
kmVec3Fill(&corners[1], to_check->max.x, to_check->min.y, to_check->min.z);
|
||||
kmVec3Fill(&corners[2], to_check->max.x, to_check->max.y, to_check->min.z);
|
||||
kmVec3Fill(&corners[3], to_check->min.x, to_check->max.y, to_check->min.z);
|
||||
kmVec3Fill(&corners[4], to_check->min.x, to_check->min.y, to_check->max.z);
|
||||
kmVec3Fill(&corners[5], to_check->max.x, to_check->min.y, to_check->max.z);
|
||||
kmVec3Fill(&corners[6], to_check->max.x, to_check->max.y, to_check->max.z);
|
||||
kmVec3Fill(&corners[7], to_check->min.x, to_check->max.y, to_check->max.z);
|
||||
|
||||
for(kmUchar i = 0; i < 8; ++i) {
|
||||
if(!kmAABBContainsPoint(container, &corners[i])) {
|
||||
result = KM_CONTAINS_PARTIAL;
|
||||
if(found) {
|
||||
//If we previously found a corner that was within the container
|
||||
//We know that partial is the final result
|
||||
return result;
|
||||
}
|
||||
} else {
|
||||
found = KM_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if(!found) {
|
||||
result = KM_CONTAINS_NONE;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
kmScalar kmAABBDiameterX(const kmAABB* aabb) {
|
||||
return fabs(aabb->max.x - aabb->min.x);
|
||||
}
|
||||
|
||||
kmScalar kmAABBDiameterY(const kmAABB* aabb) {
|
||||
return fabs(aabb->max.y - aabb->min.y);
|
||||
}
|
||||
|
||||
kmScalar kmAABBDiameterZ(const kmAABB* aabb) {
|
||||
return fabs(aabb->max.z - aabb->min.z);
|
||||
}
|
||||
|
||||
kmVec3* kmAABBCentre(const kmAABB* aabb, kmVec3* pOut) {
|
||||
kmVec3Add(pOut, &aabb->min, &aabb->max);
|
||||
kmVec3Scale(pOut, pOut, 0.5);
|
||||
return pOut;
|
||||
}
|
||||
|
|
@ -26,7 +26,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#ifndef KAZMATH_AABB_H_INCLUDED
|
||||
#define KAZMATH_AABB_H_INCLUDED
|
||||
|
||||
#include "CCPlatformMacros.h"
|
||||
#include "vec3.h"
|
||||
#include "utility.h"
|
||||
|
||||
|
@ -35,7 +34,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
/**
|
||||
* A structure that represents an axis-aligned
|
||||
* A struture that represents an axis-aligned
|
||||
* bounding box.
|
||||
*/
|
||||
typedef struct kmAABB {
|
||||
|
@ -43,9 +42,17 @@ typedef struct kmAABB {
|
|||
kmVec3 max; /** The min corner of the box */
|
||||
} kmAABB;
|
||||
|
||||
CC_DLL const int kmAABBContainsPoint(const kmVec3* pPoint, const kmAABB* pBox);
|
||||
CC_DLL kmAABB* const kmAABBAssign(kmAABB* pOut, const kmAABB* pIn);
|
||||
CC_DLL kmAABB* const kmAABBScale(kmAABB* pOut, const kmAABB* pIn, kmScalar s);
|
||||
|
||||
kmAABB* kmAABBInitialize(kmAABB* pBox, const kmVec3* centre, const kmScalar width, const kmScalar height, const kmScalar depth);
|
||||
int kmAABBContainsPoint(const kmAABB* pBox, const kmVec3* pPoint);
|
||||
kmAABB* kmAABBAssign(kmAABB* pOut, const kmAABB* pIn);
|
||||
kmAABB* kmAABBScale(kmAABB* pOut, const kmAABB* pIn, kmScalar s);
|
||||
kmBool kmAABBIntersectsTriangle(kmAABB* box, const kmVec3* p1, const kmVec3* p2, const kmVec3* p3);
|
||||
kmEnum kmAABBContainsAABB(const kmAABB* container, const kmAABB* to_check);
|
||||
kmScalar kmAABBDiameterX(const kmAABB* aabb);
|
||||
kmScalar kmAABBDiameterY(const kmAABB* aabb);
|
||||
kmScalar kmAABBDiameterZ(const kmAABB* aabb);
|
||||
kmVec3* kmAABBCentre(const kmAABB* aabb, kmVec3* pOut);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
|
@ -28,7 +28,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include "vec2.h"
|
||||
#include "vec3.h"
|
||||
#include "vec4.h"
|
||||
#include "mat3.h"
|
||||
#include "mat4.h"
|
||||
#include "utility.h"
|
||||
|
@ -36,5 +35,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "plane.h"
|
||||
#include "aabb.h"
|
||||
#include "ray2.h"
|
||||
#include "ray3.h"
|
||||
|
||||
#endif // KAZMATH_H_INCLUDED
|
|
@ -0,0 +1,458 @@
|
|||
/*
|
||||
Copyright (c) 2008, Luke Benstead.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "utility.h"
|
||||
#include "vec3.h"
|
||||
#include "mat3.h"
|
||||
#include "mat4.h"
|
||||
#include "quaternion.h"
|
||||
|
||||
kmMat3* kmMat3Fill(kmMat3* pOut, const kmScalar* pMat)
|
||||
{
|
||||
memcpy(pOut->mat, pMat, sizeof(kmScalar) * 9);
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/** Sets pOut to an identity matrix returns pOut*/
|
||||
kmMat3* kmMat3Identity(kmMat3* pOut)
|
||||
{
|
||||
memset(pOut->mat, 0, sizeof(kmScalar) * 9);
|
||||
pOut->mat[0] = pOut->mat[4] = pOut->mat[8] = 1.0f;
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmScalar kmMat3Determinant(const kmMat3* pIn)
|
||||
{
|
||||
kmScalar output;
|
||||
/*
|
||||
calculating the determinant following the rule of sarus,
|
||||
| 0 3 6 | 0 3 |
|
||||
m = | 1 4 7 | 1 4 |
|
||||
| 2 5 8 | 2 5 |
|
||||
now sum up the products of the diagonals going to the right (i.e. 0,4,8)
|
||||
and substract the products of the other diagonals (i.e. 2,4,6)
|
||||
*/
|
||||
|
||||
output = pIn->mat[0] * pIn->mat[4] * pIn->mat[8] + pIn->mat[1] * pIn->mat[5] * pIn->mat[6] + pIn->mat[2] * pIn->mat[3] * pIn->mat[7];
|
||||
output -= pIn->mat[2] * pIn->mat[4] * pIn->mat[6] + pIn->mat[0] * pIn->mat[5] * pIn->mat[7] + pIn->mat[1] * pIn->mat[3] * pIn->mat[8];
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
kmMat3* kmMat3Adjugate(kmMat3* pOut, const kmMat3* pIn)
|
||||
{
|
||||
pOut->mat[0] = pIn->mat[4] * pIn->mat[8] - pIn->mat[5] * pIn->mat[7];
|
||||
pOut->mat[1] = pIn->mat[2] * pIn->mat[7] - pIn->mat[1] * pIn->mat[8];
|
||||
pOut->mat[2] = pIn->mat[1] * pIn->mat[5] - pIn->mat[2] * pIn->mat[4];
|
||||
pOut->mat[3] = pIn->mat[5] * pIn->mat[6] - pIn->mat[3] * pIn->mat[8];
|
||||
pOut->mat[4] = pIn->mat[0] * pIn->mat[8] - pIn->mat[2] * pIn->mat[6];
|
||||
pOut->mat[5] = pIn->mat[2] * pIn->mat[3] - pIn->mat[0] * pIn->mat[5];
|
||||
pOut->mat[6] = pIn->mat[3] * pIn->mat[7] - pIn->mat[4] * pIn->mat[6];
|
||||
pOut->mat[7] = pIn->mat[1] * pIn->mat[6] - pIn->mat[0] * pIn->mat[7];
|
||||
pOut->mat[8] = pIn->mat[0] * pIn->mat[4] - pIn->mat[1] * pIn->mat[3];
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmMat3* kmMat3Inverse(kmMat3* pOut, const kmMat3* pM)
|
||||
{
|
||||
kmScalar determinate = kmMat3Determinant(pM);
|
||||
kmScalar detInv;
|
||||
kmMat3 adjugate;
|
||||
|
||||
if(determinate == 0.0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
detInv = 1.0 / determinate;
|
||||
|
||||
kmMat3Adjugate(&adjugate, pM);
|
||||
kmMat3ScalarMultiply(pOut, &adjugate, detInv);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/** Returns true if pIn is an identity matrix */
|
||||
int kmMat3IsIdentity(const kmMat3* pIn)
|
||||
{
|
||||
static kmScalar identity [] = { 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f};
|
||||
|
||||
return (memcmp(identity, pIn->mat, sizeof(kmScalar) * 9) == 0);
|
||||
}
|
||||
|
||||
/** Sets pOut to the transpose of pIn, returns pOut */
|
||||
kmMat3* kmMat3Transpose(kmMat3* pOut, const kmMat3* pIn)
|
||||
{
|
||||
kmScalar temp[9];
|
||||
|
||||
temp[0] = pIn->mat[0];
|
||||
temp[1] = pIn->mat[3];
|
||||
temp[2] = pIn->mat[6];
|
||||
|
||||
temp[3] = pIn->mat[1];
|
||||
temp[4] = pIn->mat[4];
|
||||
temp[5] = pIn->mat[7];
|
||||
|
||||
temp[6] = pIn->mat[2];
|
||||
temp[7] = pIn->mat[5];
|
||||
temp[8] = pIn->mat[8];
|
||||
|
||||
memcpy(&pOut->mat, temp, sizeof(kmScalar)*9);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/* Multiplies pM1 with pM2, stores the result in pOut, returns pOut */
|
||||
kmMat3* kmMat3Multiply(kmMat3* pOut, const kmMat3* pM1, const kmMat3* pM2)
|
||||
{
|
||||
kmScalar mat[9];
|
||||
|
||||
const kmScalar *m1 = pM1->mat, *m2 = pM2->mat;
|
||||
|
||||
mat[0] = m1[0] * m2[0] + m1[3] * m2[1] + m1[6] * m2[2];
|
||||
mat[1] = m1[1] * m2[0] + m1[4] * m2[1] + m1[7] * m2[2];
|
||||
mat[2] = m1[2] * m2[0] + m1[5] * m2[1] + m1[8] * m2[2];
|
||||
|
||||
mat[3] = m1[0] * m2[3] + m1[3] * m2[4] + m1[6] * m2[5];
|
||||
mat[4] = m1[1] * m2[3] + m1[4] * m2[4] + m1[7] * m2[5];
|
||||
mat[5] = m1[2] * m2[3] + m1[5] * m2[4] + m1[8] * m2[5];
|
||||
|
||||
mat[6] = m1[0] * m2[6] + m1[3] * m2[7] + m1[6] * m2[8];
|
||||
mat[7] = m1[1] * m2[6] + m1[4] * m2[7] + m1[7] * m2[8];
|
||||
mat[8] = m1[2] * m2[6] + m1[5] * m2[7] + m1[8] * m2[8];
|
||||
|
||||
memcpy(pOut->mat, mat, sizeof(kmScalar)*9);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmMat3* kmMat3ScalarMultiply(kmMat3* pOut, const kmMat3* pM, const kmScalar pFactor)
|
||||
{
|
||||
kmScalar mat[9];
|
||||
int i;
|
||||
|
||||
for(i = 0; i < 9; i++)
|
||||
{
|
||||
mat[i] = pM->mat[i] * pFactor;
|
||||
}
|
||||
|
||||
memcpy(pOut->mat, mat, sizeof(kmScalar)*9);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/** Assigns the value of pIn to pOut */
|
||||
kmMat3* kmMat3Assign(kmMat3* pOut, const kmMat3* pIn)
|
||||
{
|
||||
assert(pOut != pIn); //You have tried to self-assign!!
|
||||
|
||||
memcpy(pOut->mat, pIn->mat, sizeof(kmScalar)*9);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmMat3* kmMat3AssignMat4(kmMat3* pOut, const kmMat4* pIn) {
|
||||
pOut->mat[0] = pIn->mat[0];
|
||||
pOut->mat[1] = pIn->mat[1];
|
||||
pOut->mat[2] = pIn->mat[2];
|
||||
|
||||
pOut->mat[3] = pIn->mat[4];
|
||||
pOut->mat[4] = pIn->mat[5];
|
||||
pOut->mat[5] = pIn->mat[6];
|
||||
|
||||
pOut->mat[6] = pIn->mat[8];
|
||||
pOut->mat[7] = pIn->mat[9];
|
||||
pOut->mat[8] = pIn->mat[10];
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/** Returns true if the 2 matrices are equal (approximately) */
|
||||
int kmMat3AreEqual(const kmMat3* pMat1, const kmMat3* pMat2)
|
||||
{
|
||||
int i;
|
||||
if (pMat1 == pMat2) {
|
||||
return KM_TRUE;
|
||||
}
|
||||
|
||||
for (i = 0; i < 9; ++i) {
|
||||
if (!(pMat1->mat[i] + kmEpsilon > pMat2->mat[i] &&
|
||||
pMat1->mat[i] - kmEpsilon < pMat2->mat[i])) {
|
||||
return KM_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return KM_TRUE;
|
||||
}
|
||||
|
||||
/* Rotation around the z axis so everything stays planar in XY */
|
||||
kmMat3* kmMat3Rotation(kmMat3* pOut, const kmScalar radians)
|
||||
{
|
||||
/*
|
||||
| cos(A) -sin(A) 0 |
|
||||
M = | sin(A) cos(A) 0 |
|
||||
| 0 0 1 |
|
||||
*/
|
||||
|
||||
pOut->mat[0] = cosf(radians);
|
||||
pOut->mat[1] = sinf(radians);
|
||||
pOut->mat[2] = 0.0f;
|
||||
|
||||
pOut->mat[3] = -sinf(radians);
|
||||
pOut->mat[4] = cosf(radians);
|
||||
pOut->mat[5] = 0.0f;
|
||||
|
||||
pOut->mat[6] = 0.0f;
|
||||
pOut->mat[7] = 0.0f;
|
||||
pOut->mat[8] = 1.0f;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/** Builds a scaling matrix */
|
||||
kmMat3* kmMat3Scaling(kmMat3* pOut, const kmScalar x, const kmScalar y)
|
||||
{
|
||||
// memset(pOut->mat, 0, sizeof(kmScalar) * 9);
|
||||
kmMat3Identity(pOut);
|
||||
pOut->mat[0] = x;
|
||||
pOut->mat[4] = y;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmMat3* kmMat3Translation(kmMat3* pOut, const kmScalar x, const kmScalar y)
|
||||
{
|
||||
// memset(pOut->mat, 0, sizeof(kmScalar) * 9);
|
||||
kmMat3Identity(pOut);
|
||||
pOut->mat[6] = x;
|
||||
pOut->mat[7] = y;
|
||||
// pOut->mat[8] = 1.0;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
|
||||
kmMat3* kmMat3RotationQuaternion(kmMat3* pOut, const kmQuaternion* pIn)
|
||||
{
|
||||
if (!pIn || !pOut) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// First row
|
||||
pOut->mat[0] = 1.0f - 2.0f * (pIn->y * pIn->y + pIn->z * pIn->z);
|
||||
pOut->mat[1] = 2.0f * (pIn->x * pIn->y - pIn->w * pIn->z);
|
||||
pOut->mat[2] = 2.0f * (pIn->x * pIn->z + pIn->w * pIn->y);
|
||||
|
||||
// Second row
|
||||
pOut->mat[3] = 2.0f * (pIn->x * pIn->y + pIn->w * pIn->z);
|
||||
pOut->mat[4] = 1.0f - 2.0f * (pIn->x * pIn->x + pIn->z * pIn->z);
|
||||
pOut->mat[5] = 2.0f * (pIn->y * pIn->z - pIn->w * pIn->x);
|
||||
|
||||
// Third row
|
||||
pOut->mat[6] = 2.0f * (pIn->x * pIn->z - pIn->w * pIn->y);
|
||||
pOut->mat[7] = 2.0f * (pIn->y * pIn->z + pIn->w * pIn->x);
|
||||
pOut->mat[8] = 1.0f - 2.0f * (pIn->x * pIn->x + pIn->y * pIn->y);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmMat3* kmMat3RotationAxisAngle(kmMat3* pOut, const struct kmVec3* axis, kmScalar radians)
|
||||
{
|
||||
kmScalar rcos = cosf(radians);
|
||||
kmScalar rsin = sinf(radians);
|
||||
|
||||
pOut->mat[0] = rcos + axis->x * axis->x * (1 - rcos);
|
||||
pOut->mat[1] = axis->z * rsin + axis->y * axis->x * (1 - rcos);
|
||||
pOut->mat[2] = -axis->y * rsin + axis->z * axis->x * (1 - rcos);
|
||||
|
||||
pOut->mat[3] = -axis->z * rsin + axis->x * axis->y * (1 - rcos);
|
||||
pOut->mat[4] = rcos + axis->y * axis->y * (1 - rcos);
|
||||
pOut->mat[5] = axis->x * rsin + axis->z * axis->y * (1 - rcos);
|
||||
|
||||
pOut->mat[6] = axis->y * rsin + axis->x * axis->z * (1 - rcos);
|
||||
pOut->mat[7] = -axis->x * rsin + axis->y * axis->z * (1 - rcos);
|
||||
pOut->mat[8] = rcos + axis->z * axis->z * (1 - rcos);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec3* kmMat3RotationToAxisAngle(kmVec3* pAxis, kmScalar* radians, const kmMat3* pIn)
|
||||
{
|
||||
/*Surely not this easy?*/
|
||||
kmQuaternion temp;
|
||||
kmQuaternionRotationMatrix(&temp, pIn);
|
||||
kmQuaternionToAxisAngle(&temp, pAxis, radians);
|
||||
return pAxis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds an X-axis rotation matrix and stores it in pOut, returns pOut
|
||||
*/
|
||||
kmMat3* kmMat3RotationX(kmMat3* pOut, const kmScalar radians)
|
||||
{
|
||||
/*
|
||||
| 1 0 0 |
|
||||
M = | 0 cos(A) -sin(A) |
|
||||
| 0 sin(A) cos(A) |
|
||||
|
||||
*/
|
||||
|
||||
pOut->mat[0] = 1.0f;
|
||||
pOut->mat[1] = 0.0f;
|
||||
pOut->mat[2] = 0.0f;
|
||||
|
||||
pOut->mat[3] = 0.0f;
|
||||
pOut->mat[4] = cosf(radians);
|
||||
pOut->mat[5] = sinf(radians);
|
||||
|
||||
pOut->mat[6] = 0.0f;
|
||||
pOut->mat[7] = -sinf(radians);
|
||||
pOut->mat[8] = cosf(radians);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a rotation matrix using the rotation around the Y-axis
|
||||
* The result is stored in pOut, pOut is returned.
|
||||
*/
|
||||
kmMat3* kmMat3RotationY(kmMat3* pOut, const kmScalar radians)
|
||||
{
|
||||
/*
|
||||
| cos(A) 0 sin(A) |
|
||||
M = | 0 1 0 |
|
||||
| -sin(A) 0 cos(A) |
|
||||
*/
|
||||
|
||||
pOut->mat[0] = cosf(radians);
|
||||
pOut->mat[1] = 0.0f;
|
||||
pOut->mat[2] = -sinf(radians);
|
||||
|
||||
pOut->mat[3] = 0.0f;
|
||||
pOut->mat[4] = 1.0f;
|
||||
pOut->mat[5] = 0.0f;
|
||||
|
||||
pOut->mat[6] = sinf(radians);
|
||||
pOut->mat[7] = 0.0f;
|
||||
pOut->mat[8] = cosf(radians);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a rotation matrix around the Z-axis. The resulting
|
||||
* matrix is stored in pOut. pOut is returned.
|
||||
*/
|
||||
kmMat3* kmMat3RotationZ(kmMat3* pOut, const kmScalar radians)
|
||||
{
|
||||
/*
|
||||
| cos(A) -sin(A) 0 |
|
||||
M = | sin(A) cos(A) 0 |
|
||||
| 0 0 1 |
|
||||
*/
|
||||
|
||||
pOut->mat[0] = cosf(radians);
|
||||
pOut->mat[1] =-sinf(radians);
|
||||
pOut->mat[2] = 0.0f;
|
||||
|
||||
pOut->mat[3] = sinf(radians);
|
||||
pOut->mat[4] = cosf(radians);
|
||||
pOut->mat[5] = 0.0f;
|
||||
|
||||
pOut->mat[6] = 0.0f;
|
||||
pOut->mat[7] = 0.0f;
|
||||
pOut->mat[8] = 1.0f;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec3* kmMat3GetUpVec3(kmVec3* pOut, const kmMat3* pIn) {
|
||||
pOut->x = pIn->mat[3];
|
||||
pOut->y = pIn->mat[4];
|
||||
pOut->z = pIn->mat[5];
|
||||
|
||||
kmVec3Normalize(pOut, pOut);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec3* kmMat3GetRightVec3(kmVec3* pOut, const kmMat3* pIn) {
|
||||
pOut->x = pIn->mat[0];
|
||||
pOut->y = pIn->mat[1];
|
||||
pOut->z = pIn->mat[2];
|
||||
|
||||
kmVec3Normalize(pOut, pOut);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec3* kmMat3GetForwardVec3(kmVec3* pOut, const kmMat3* pIn) {
|
||||
pOut->x = pIn->mat[6];
|
||||
pOut->y = pIn->mat[7];
|
||||
pOut->z = pIn->mat[8];
|
||||
|
||||
kmVec3Normalize(pOut, pOut);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmMat3* kmMat3LookAt(kmMat3* pOut, const kmVec3* pEye,
|
||||
const kmVec3* pCenter, const kmVec3* pUp)
|
||||
{
|
||||
kmVec3 f, up, s, u;
|
||||
|
||||
kmVec3Subtract(&f, pCenter, pEye);
|
||||
kmVec3Normalize(&f, &f);
|
||||
|
||||
kmVec3Assign(&up, pUp);
|
||||
kmVec3Normalize(&up, &up);
|
||||
|
||||
kmVec3Cross(&s, &f, &up);
|
||||
kmVec3Normalize(&s, &s);
|
||||
|
||||
kmVec3Cross(&u, &s, &f);
|
||||
kmVec3Normalize(&s, &s);
|
||||
|
||||
pOut->mat[0] = s.x;
|
||||
pOut->mat[3] = s.y;
|
||||
pOut->mat[6] = s.z;
|
||||
|
||||
pOut->mat[1] = u.x;
|
||||
pOut->mat[4] = u.y;
|
||||
pOut->mat[7] = u.z;
|
||||
|
||||
pOut->mat[2] = -f.x;
|
||||
pOut->mat[5] = -f.y;
|
||||
pOut->mat[8] = -f.z;
|
||||
|
||||
return pOut;
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
#ifndef HEADER_8E9D0ABA3C76B989
|
||||
#define HEADER_8E9D0ABA3C76B989
|
||||
|
||||
/*
|
||||
Copyright (c) 2008, Luke Benstead.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef MAT3_H_INCLUDED
|
||||
#define MAT3_H_INCLUDED
|
||||
|
||||
#include "utility.h"
|
||||
|
||||
struct kmVec3;
|
||||
struct kmQuaternion;
|
||||
struct kmMat4;
|
||||
|
||||
typedef struct kmMat3{
|
||||
kmScalar mat[9];
|
||||
} kmMat3;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
kmMat3* kmMat3Fill(kmMat3* pOut, const kmScalar* pMat);
|
||||
kmMat3* kmMat3Adjugate(kmMat3* pOut, const kmMat3* pIn);
|
||||
kmMat3* kmMat3Identity(kmMat3* pOut);
|
||||
kmMat3* kmMat3Inverse(kmMat3* pOut, const kmMat3* pM);
|
||||
int kmMat3IsIdentity(const kmMat3* pIn);
|
||||
kmMat3* kmMat3Transpose(kmMat3* pOut, const kmMat3* pIn);
|
||||
kmScalar kmMat3Determinant(const kmMat3* pIn);
|
||||
kmMat3* kmMat3Multiply(kmMat3* pOut, const kmMat3* pM1, const kmMat3* pM2);
|
||||
kmMat3* kmMat3ScalarMultiply(kmMat3* pOut, const kmMat3* pM, const kmScalar pFactor);
|
||||
|
||||
kmMat3* kmMat3Assign(kmMat3* pOut, const kmMat3* pIn);
|
||||
kmMat3* kmMat3AssignMat4(kmMat3* pOut, const struct kmMat4* pIn);
|
||||
int kmMat3AreEqual(const kmMat3* pM1, const kmMat3* pM2);
|
||||
|
||||
struct kmVec3* kmMat3GetUpVec3(struct kmVec3* pOut, const kmMat3* pIn);
|
||||
struct kmVec3* kmMat3GetRightVec3(struct kmVec3* pOut, const kmMat3* pIn);
|
||||
struct kmVec3* kmMat3GetForwardVec3(struct kmVec3* pOut, const kmMat3* pIn);
|
||||
|
||||
kmMat3* kmMat3RotationX(kmMat3* pOut, const kmScalar radians);
|
||||
kmMat3* kmMat3RotationY(kmMat3* pOut, const kmScalar radians);
|
||||
kmMat3* kmMat3RotationZ(kmMat3* pOut, const kmScalar radians);
|
||||
|
||||
kmMat3* kmMat3Rotation(kmMat3* pOut, const kmScalar radians);
|
||||
kmMat3* kmMat3Scaling(kmMat3* pOut, const kmScalar x, const kmScalar y);
|
||||
kmMat3* kmMat3Translation(kmMat3* pOut, const kmScalar x, const kmScalar y);
|
||||
|
||||
kmMat3* kmMat3RotationQuaternion(kmMat3* pOut, const struct kmQuaternion* pIn);
|
||||
|
||||
kmMat3* kmMat3RotationAxisAngle(kmMat3* pOut, const struct kmVec3* axis, kmScalar radians);
|
||||
struct kmVec3* kmMat3RotationToAxisAngle(struct kmVec3* pAxis, kmScalar* radians, const kmMat3* pIn);
|
||||
kmMat3* kmMat3LookAt(kmMat3* pOut, const struct kmVec3* pEye, const struct kmVec3* pCenter, const struct kmVec3* pUp);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // MAT3_H_INCLUDED
|
||||
|
||||
|
||||
#endif // header guard
|
|
@ -0,0 +1,805 @@
|
|||
/*
|
||||
Copyright (c) 2008, Luke Benstead.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file mat4.c
|
||||
*/
|
||||
#include <memory.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "utility.h"
|
||||
#include "vec3.h"
|
||||
#include "mat4.h"
|
||||
#include "mat3.h"
|
||||
#include "quaternion.h"
|
||||
#include "plane.h"
|
||||
#include "neon_matrix_impl.h"
|
||||
|
||||
|
||||
/**
|
||||
* Fills a kmMat4 structure with the values from a 16
|
||||
* element array of kmScalars
|
||||
* @Params pOut - A pointer to the destination matrix
|
||||
* pMat - A 16 element array of kmScalars
|
||||
* @Return Returns pOut so that the call can be nested
|
||||
*/
|
||||
kmMat4* kmMat4Fill(kmMat4* pOut, const kmScalar* pMat)
|
||||
{
|
||||
memcpy(pOut->mat, pMat, sizeof(kmScalar) * 16);
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets pOut to an identity matrix returns pOut
|
||||
* @Params pOut - A pointer to the matrix to set to identity
|
||||
* @Return Returns pOut so that the call can be nested
|
||||
*/
|
||||
kmMat4* kmMat4Identity(kmMat4* pOut)
|
||||
{
|
||||
memset(pOut->mat, 0, sizeof(kmScalar) * 16);
|
||||
pOut->mat[0] = pOut->mat[5] = pOut->mat[10] = pOut->mat[15] = 1.0f;
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the inverse of pM and stores the result in
|
||||
* pOut.
|
||||
* @Return Returns NULL if there is no inverse, else pOut
|
||||
*/
|
||||
kmMat4* kmMat4Inverse(kmMat4* pOut, const kmMat4* pM) {
|
||||
kmMat4 tmp;
|
||||
double det;
|
||||
int i;
|
||||
|
||||
tmp.mat[0] = pM->mat[5] * pM->mat[10] * pM->mat[15] -
|
||||
pM->mat[5] * pM->mat[11] * pM->mat[14] -
|
||||
pM->mat[9] * pM->mat[6] * pM->mat[15] +
|
||||
pM->mat[9] * pM->mat[7] * pM->mat[14] +
|
||||
pM->mat[13] * pM->mat[6] * pM->mat[11] -
|
||||
pM->mat[13] * pM->mat[7] * pM->mat[10];
|
||||
|
||||
tmp.mat[4] = -pM->mat[4] * pM->mat[10] * pM->mat[15] +
|
||||
pM->mat[4] * pM->mat[11] * pM->mat[14] +
|
||||
pM->mat[8] * pM->mat[6] * pM->mat[15] -
|
||||
pM->mat[8] * pM->mat[7] * pM->mat[14] -
|
||||
pM->mat[12] * pM->mat[6] * pM->mat[11] +
|
||||
pM->mat[12] * pM->mat[7] * pM->mat[10];
|
||||
|
||||
tmp.mat[8] = pM->mat[4] * pM->mat[9] * pM->mat[15] -
|
||||
pM->mat[4] * pM->mat[11] * pM->mat[13] -
|
||||
pM->mat[8] * pM->mat[5] * pM->mat[15] +
|
||||
pM->mat[8] * pM->mat[7] * pM->mat[13] +
|
||||
pM->mat[12] * pM->mat[5] * pM->mat[11] -
|
||||
pM->mat[12] * pM->mat[7] * pM->mat[9];
|
||||
|
||||
tmp.mat[12] = -pM->mat[4] * pM->mat[9] * pM->mat[14] +
|
||||
pM->mat[4] * pM->mat[10] * pM->mat[13] +
|
||||
pM->mat[8] * pM->mat[5] * pM->mat[14] -
|
||||
pM->mat[8] * pM->mat[6] * pM->mat[13] -
|
||||
pM->mat[12] * pM->mat[5] * pM->mat[10] +
|
||||
pM->mat[12] * pM->mat[6] * pM->mat[9];
|
||||
|
||||
tmp.mat[1] = -pM->mat[1] * pM->mat[10] * pM->mat[15] +
|
||||
pM->mat[1] * pM->mat[11] * pM->mat[14] +
|
||||
pM->mat[9] * pM->mat[2] * pM->mat[15] -
|
||||
pM->mat[9] * pM->mat[3] * pM->mat[14] -
|
||||
pM->mat[13] * pM->mat[2] * pM->mat[11] +
|
||||
pM->mat[13] * pM->mat[3] * pM->mat[10];
|
||||
|
||||
tmp.mat[5] = pM->mat[0] * pM->mat[10] * pM->mat[15] -
|
||||
pM->mat[0] * pM->mat[11] * pM->mat[14] -
|
||||
pM->mat[8] * pM->mat[2] * pM->mat[15] +
|
||||
pM->mat[8] * pM->mat[3] * pM->mat[14] +
|
||||
pM->mat[12] * pM->mat[2] * pM->mat[11] -
|
||||
pM->mat[12] * pM->mat[3] * pM->mat[10];
|
||||
|
||||
tmp.mat[9] = -pM->mat[0] * pM->mat[9] * pM->mat[15] +
|
||||
pM->mat[0] * pM->mat[11] * pM->mat[13] +
|
||||
pM->mat[8] * pM->mat[1] * pM->mat[15] -
|
||||
pM->mat[8] * pM->mat[3] * pM->mat[13] -
|
||||
pM->mat[12] * pM->mat[1] * pM->mat[11] +
|
||||
pM->mat[12] * pM->mat[3] * pM->mat[9];
|
||||
|
||||
tmp.mat[13] = pM->mat[0] * pM->mat[9] * pM->mat[14] -
|
||||
pM->mat[0] * pM->mat[10] * pM->mat[13] -
|
||||
pM->mat[8] * pM->mat[1] * pM->mat[14] +
|
||||
pM->mat[8] * pM->mat[2] * pM->mat[13] +
|
||||
pM->mat[12] * pM->mat[1] * pM->mat[10] -
|
||||
pM->mat[12] * pM->mat[2] * pM->mat[9];
|
||||
|
||||
tmp.mat[2] = pM->mat[1] * pM->mat[6] * pM->mat[15] -
|
||||
pM->mat[1] * pM->mat[7] * pM->mat[14] -
|
||||
pM->mat[5] * pM->mat[2] * pM->mat[15] +
|
||||
pM->mat[5] * pM->mat[3] * pM->mat[14] +
|
||||
pM->mat[13] * pM->mat[2] * pM->mat[7] -
|
||||
pM->mat[13] * pM->mat[3] * pM->mat[6];
|
||||
|
||||
tmp.mat[6] = -pM->mat[0] * pM->mat[6] * pM->mat[15] +
|
||||
pM->mat[0] * pM->mat[7] * pM->mat[14] +
|
||||
pM->mat[4] * pM->mat[2] * pM->mat[15] -
|
||||
pM->mat[4] * pM->mat[3] * pM->mat[14] -
|
||||
pM->mat[12] * pM->mat[2] * pM->mat[7] +
|
||||
pM->mat[12] * pM->mat[3] * pM->mat[6];
|
||||
|
||||
tmp.mat[10] = pM->mat[0] * pM->mat[5] * pM->mat[15] -
|
||||
pM->mat[0] * pM->mat[7] * pM->mat[13] -
|
||||
pM->mat[4] * pM->mat[1] * pM->mat[15] +
|
||||
pM->mat[4] * pM->mat[3] * pM->mat[13] +
|
||||
pM->mat[12] * pM->mat[1] * pM->mat[7] -
|
||||
pM->mat[12] * pM->mat[3] * pM->mat[5];
|
||||
|
||||
tmp.mat[14] = -pM->mat[0] * pM->mat[5] * pM->mat[14] +
|
||||
pM->mat[0] * pM->mat[6] * pM->mat[13] +
|
||||
pM->mat[4] * pM->mat[1] * pM->mat[14] -
|
||||
pM->mat[4] * pM->mat[2] * pM->mat[13] -
|
||||
pM->mat[12] * pM->mat[1] * pM->mat[6] +
|
||||
pM->mat[12] * pM->mat[2] * pM->mat[5];
|
||||
|
||||
tmp.mat[3] = -pM->mat[1] * pM->mat[6] * pM->mat[11] +
|
||||
pM->mat[1] * pM->mat[7] * pM->mat[10] +
|
||||
pM->mat[5] * pM->mat[2] * pM->mat[11] -
|
||||
pM->mat[5] * pM->mat[3] * pM->mat[10] -
|
||||
pM->mat[9] * pM->mat[2] * pM->mat[7] +
|
||||
pM->mat[9] * pM->mat[3] * pM->mat[6];
|
||||
|
||||
tmp.mat[7] = pM->mat[0] * pM->mat[6] * pM->mat[11] -
|
||||
pM->mat[0] * pM->mat[7] * pM->mat[10] -
|
||||
pM->mat[4] * pM->mat[2] * pM->mat[11] +
|
||||
pM->mat[4] * pM->mat[3] * pM->mat[10] +
|
||||
pM->mat[8] * pM->mat[2] * pM->mat[7] -
|
||||
pM->mat[8] * pM->mat[3] * pM->mat[6];
|
||||
|
||||
tmp.mat[11] = -pM->mat[0] * pM->mat[5] * pM->mat[11] +
|
||||
pM->mat[0] * pM->mat[7] * pM->mat[9] +
|
||||
pM->mat[4] * pM->mat[1] * pM->mat[11] -
|
||||
pM->mat[4] * pM->mat[3] * pM->mat[9] -
|
||||
pM->mat[8] * pM->mat[1] * pM->mat[7] +
|
||||
pM->mat[8] * pM->mat[3] * pM->mat[5];
|
||||
|
||||
tmp.mat[15] = pM->mat[0] * pM->mat[5] * pM->mat[10] -
|
||||
pM->mat[0] * pM->mat[6] * pM->mat[9] -
|
||||
pM->mat[4] * pM->mat[1] * pM->mat[10] +
|
||||
pM->mat[4] * pM->mat[2] * pM->mat[9] +
|
||||
pM->mat[8] * pM->mat[1] * pM->mat[6] -
|
||||
pM->mat[8] * pM->mat[2] * pM->mat[5];
|
||||
|
||||
det = pM->mat[0] * tmp.mat[0] + pM->mat[1] * tmp.mat[4] + pM->mat[2] * tmp.mat[8] + pM->mat[3] * tmp.mat[12];
|
||||
|
||||
if (det == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
det = 1.0 / det;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
pOut->mat[i] = tmp.mat[i] * det;
|
||||
}
|
||||
|
||||
return pOut;
|
||||
}
|
||||
/**
|
||||
* Returns KM_TRUE if pIn is an identity matrix
|
||||
* KM_FALSE otherwise
|
||||
*/
|
||||
int kmMat4IsIdentity(const kmMat4* pIn)
|
||||
{
|
||||
static kmScalar identity [] = { 1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
};
|
||||
|
||||
return (memcmp(identity, pIn->mat, sizeof(kmScalar) * 16) == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets pOut to the transpose of pIn, returns pOut
|
||||
*/
|
||||
kmMat4* kmMat4Transpose(kmMat4* pOut, const kmMat4* pIn)
|
||||
{
|
||||
int x, z;
|
||||
|
||||
for (z = 0; z < 4; ++z) {
|
||||
for (x = 0; x < 4; ++x) {
|
||||
pOut->mat[(z * 4) + x] = pIn->mat[(x * 4) + z];
|
||||
}
|
||||
}
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies pM1 with pM2, stores the result in pOut, returns pOut
|
||||
*/
|
||||
kmMat4* kmMat4Multiply(kmMat4* pOut, const kmMat4* pM1, const kmMat4* pM2)
|
||||
{
|
||||
#if defined(__ARM_NEON__) && !defined(__arm64__)
|
||||
|
||||
// It is possible to skip the memcpy() since "out" does not overwrite p1 or p2.
|
||||
// otherwise a temp must be needed.
|
||||
float *mat = pOut->mat;
|
||||
|
||||
// Invert column-order with row-order
|
||||
NEON_Matrix4Mul( &pM2->mat[0], &pM1->mat[0], &mat[0] );
|
||||
|
||||
#else
|
||||
|
||||
kmScalar mat[16];
|
||||
|
||||
const kmScalar *m1 = pM1->mat, *m2 = pM2->mat;
|
||||
|
||||
mat[0] = m1[0] * m2[0] + m1[4] * m2[1] + m1[8] * m2[2] + m1[12] * m2[3];
|
||||
mat[1] = m1[1] * m2[0] + m1[5] * m2[1] + m1[9] * m2[2] + m1[13] * m2[3];
|
||||
mat[2] = m1[2] * m2[0] + m1[6] * m2[1] + m1[10] * m2[2] + m1[14] * m2[3];
|
||||
mat[3] = m1[3] * m2[0] + m1[7] * m2[1] + m1[11] * m2[2] + m1[15] * m2[3];
|
||||
|
||||
mat[4] = m1[0] * m2[4] + m1[4] * m2[5] + m1[8] * m2[6] + m1[12] * m2[7];
|
||||
mat[5] = m1[1] * m2[4] + m1[5] * m2[5] + m1[9] * m2[6] + m1[13] * m2[7];
|
||||
mat[6] = m1[2] * m2[4] + m1[6] * m2[5] + m1[10] * m2[6] + m1[14] * m2[7];
|
||||
mat[7] = m1[3] * m2[4] + m1[7] * m2[5] + m1[11] * m2[6] + m1[15] * m2[7];
|
||||
|
||||
mat[8] = m1[0] * m2[8] + m1[4] * m2[9] + m1[8] * m2[10] + m1[12] * m2[11];
|
||||
mat[9] = m1[1] * m2[8] + m1[5] * m2[9] + m1[9] * m2[10] + m1[13] * m2[11];
|
||||
mat[10] = m1[2] * m2[8] + m1[6] * m2[9] + m1[10] * m2[10] + m1[14] * m2[11];
|
||||
mat[11] = m1[3] * m2[8] + m1[7] * m2[9] + m1[11] * m2[10] + m1[15] * m2[11];
|
||||
|
||||
mat[12] = m1[0] * m2[12] + m1[4] * m2[13] + m1[8] * m2[14] + m1[12] * m2[15];
|
||||
mat[13] = m1[1] * m2[12] + m1[5] * m2[13] + m1[9] * m2[14] + m1[13] * m2[15];
|
||||
mat[14] = m1[2] * m2[12] + m1[6] * m2[13] + m1[10] * m2[14] + m1[14] * m2[15];
|
||||
mat[15] = m1[3] * m2[12] + m1[7] * m2[13] + m1[11] * m2[14] + m1[15] * m2[15];
|
||||
|
||||
|
||||
memcpy(pOut->mat, mat, sizeof(kmScalar)*16);
|
||||
#endif
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns the value of pIn to pOut
|
||||
*/
|
||||
kmMat4* kmMat4Assign(kmMat4* pOut, const kmMat4* pIn)
|
||||
{
|
||||
assert(pOut != pIn && "You have tried to self-assign!!");
|
||||
|
||||
memcpy(pOut->mat, pIn->mat, sizeof(kmScalar)*16);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmMat4* kmMat4AssignMat3(kmMat4* pOut, const kmMat3* pIn) {
|
||||
kmMat4Identity(pOut);
|
||||
|
||||
pOut->mat[0] = pIn->mat[0];
|
||||
pOut->mat[1] = pIn->mat[1];
|
||||
pOut->mat[2] = pIn->mat[2];
|
||||
pOut->mat[3] = 0.0;
|
||||
|
||||
pOut->mat[4] = pIn->mat[3];
|
||||
pOut->mat[5] = pIn->mat[4];
|
||||
pOut->mat[6] = pIn->mat[5];
|
||||
pOut->mat[7] = 0.0;
|
||||
|
||||
pOut->mat[8] = pIn->mat[6];
|
||||
pOut->mat[9] = pIn->mat[7];
|
||||
pOut->mat[10] = pIn->mat[8];
|
||||
pOut->mat[11] = 0.0;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns KM_TRUE if the 2 matrices are equal (approximately)
|
||||
*/
|
||||
int kmMat4AreEqual(const kmMat4* pMat1, const kmMat4* pMat2)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
assert(pMat1 != pMat2 && "You are comparing the same thing!");
|
||||
|
||||
for (i = 0; i < 16; ++i)
|
||||
{
|
||||
if (!(pMat1->mat[i] + kmEpsilon > pMat2->mat[i] &&
|
||||
pMat1->mat[i] - kmEpsilon < pMat2->mat[i])) {
|
||||
return KM_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return KM_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a rotation matrix from an axis and an angle. Result is stored in pOut.
|
||||
* pOut is returned.
|
||||
*/
|
||||
kmMat4* kmMat4RotationAxisAngle(kmMat4* pOut, const kmVec3* axis, kmScalar radians)
|
||||
{
|
||||
kmQuaternion quat;
|
||||
kmQuaternionRotationAxisAngle(&quat, axis, radians);
|
||||
kmMat4RotationQuaternion(pOut, &quat);
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds an X-axis rotation matrix and stores it in pOut, returns pOut
|
||||
*/
|
||||
kmMat4* kmMat4RotationX(kmMat4* pOut, const kmScalar radians)
|
||||
{
|
||||
/*
|
||||
| 1 0 0 0 |
|
||||
M = | 0 cos(A) -sin(A) 0 |
|
||||
| 0 sin(A) cos(A) 0 |
|
||||
| 0 0 0 1 |
|
||||
|
||||
*/
|
||||
|
||||
pOut->mat[0] = 1.0f;
|
||||
pOut->mat[1] = 0.0f;
|
||||
pOut->mat[2] = 0.0f;
|
||||
pOut->mat[3] = 0.0f;
|
||||
|
||||
pOut->mat[4] = 0.0f;
|
||||
pOut->mat[5] = cosf(radians);
|
||||
pOut->mat[6] = sinf(radians);
|
||||
pOut->mat[7] = 0.0f;
|
||||
|
||||
pOut->mat[8] = 0.0f;
|
||||
pOut->mat[9] = -sinf(radians);
|
||||
pOut->mat[10] = cosf(radians);
|
||||
pOut->mat[11] = 0.0f;
|
||||
|
||||
pOut->mat[12] = 0.0f;
|
||||
pOut->mat[13] = 0.0f;
|
||||
pOut->mat[14] = 0.0f;
|
||||
pOut->mat[15] = 1.0f;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a rotation matrix using the rotation around the Y-axis
|
||||
* The result is stored in pOut, pOut is returned.
|
||||
*/
|
||||
kmMat4* kmMat4RotationY(kmMat4* pOut, const kmScalar radians)
|
||||
{
|
||||
/*
|
||||
| cos(A) 0 sin(A) 0 |
|
||||
M = | 0 1 0 0 |
|
||||
| -sin(A) 0 cos(A) 0 |
|
||||
| 0 0 0 1 |
|
||||
*/
|
||||
|
||||
pOut->mat[0] = cosf(radians);
|
||||
pOut->mat[1] = 0.0f;
|
||||
pOut->mat[2] = -sinf(radians);
|
||||
pOut->mat[3] = 0.0f;
|
||||
|
||||
pOut->mat[4] = 0.0f;
|
||||
pOut->mat[5] = 1.0f;
|
||||
pOut->mat[6] = 0.0f;
|
||||
pOut->mat[7] = 0.0f;
|
||||
|
||||
pOut->mat[8] = sinf(radians);
|
||||
pOut->mat[9] = 0.0f;
|
||||
pOut->mat[10] = cosf(radians);
|
||||
pOut->mat[11] = 0.0f;
|
||||
|
||||
pOut->mat[12] = 0.0f;
|
||||
pOut->mat[13] = 0.0f;
|
||||
pOut->mat[14] = 0.0f;
|
||||
pOut->mat[15] = 1.0f;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a rotation matrix around the Z-axis. The resulting
|
||||
* matrix is stored in pOut. pOut is returned.
|
||||
*/
|
||||
kmMat4* kmMat4RotationZ(kmMat4* pOut, const kmScalar radians)
|
||||
{
|
||||
/*
|
||||
| cos(A) -sin(A) 0 0 |
|
||||
M = | sin(A) cos(A) 0 0 |
|
||||
| 0 0 1 0 |
|
||||
| 0 0 0 1 |
|
||||
*/
|
||||
|
||||
pOut->mat[0] = cosf(radians);
|
||||
pOut->mat[1] = sinf(radians);
|
||||
pOut->mat[2] = 0.0f;
|
||||
pOut->mat[3] = 0.0f;
|
||||
|
||||
pOut->mat[4] = -sinf(radians);
|
||||
pOut->mat[5] = cosf(radians);
|
||||
pOut->mat[6] = 0.0f;
|
||||
pOut->mat[7] = 0.0f;
|
||||
|
||||
pOut->mat[8] = 0.0f;
|
||||
pOut->mat[9] = 0.0f;
|
||||
pOut->mat[10] = 1.0f;
|
||||
pOut->mat[11] = 0.0f;
|
||||
|
||||
pOut->mat[12] = 0.0f;
|
||||
pOut->mat[13] = 0.0f;
|
||||
pOut->mat[14] = 0.0f;
|
||||
pOut->mat[15] = 1.0f;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a rotation matrix from pitch, yaw and roll. The resulting
|
||||
* matrix is stored in pOut and pOut is returned
|
||||
*/
|
||||
kmMat4* kmMat4RotationYawPitchRoll(kmMat4* pOut, const kmScalar pitch, const kmScalar yaw, const kmScalar roll)
|
||||
{
|
||||
|
||||
kmMat4 yaw_matrix;
|
||||
kmMat4RotationY(&yaw_matrix, yaw);
|
||||
|
||||
kmMat4 pitch_matrix;
|
||||
kmMat4RotationX(&pitch_matrix, pitch);
|
||||
|
||||
kmMat4 roll_matrix;
|
||||
kmMat4RotationZ(&roll_matrix, roll);
|
||||
|
||||
kmMat4Multiply(pOut, &pitch_matrix, &roll_matrix);
|
||||
kmMat4Multiply(pOut, &yaw_matrix, pOut);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/** Converts a quaternion to a rotation matrix,
|
||||
* the result is stored in pOut, returns pOut
|
||||
*/
|
||||
kmMat4* kmMat4RotationQuaternion(kmMat4* pOut, const kmQuaternion* pQ)
|
||||
{
|
||||
double xx = pQ->x * pQ->x;
|
||||
double xy = pQ->x * pQ->y;
|
||||
double xz = pQ->x * pQ->z;
|
||||
double xw = pQ->x * pQ->w;
|
||||
|
||||
double yy = pQ->y * pQ->y;
|
||||
double yz = pQ->y * pQ->z;
|
||||
double yw = pQ->y * pQ->w;
|
||||
|
||||
double zz = pQ->z * pQ->z;
|
||||
double zw = pQ->z * pQ->w;
|
||||
|
||||
pOut->mat[0] = 1 - 2 * (yy + zz);
|
||||
pOut->mat[1] = 2 * (xy + zw);
|
||||
pOut->mat[2] = 2 * (xz - yw);
|
||||
pOut->mat[3] = 0;
|
||||
|
||||
pOut->mat[4] = 2 * (xy - zw);
|
||||
pOut->mat[5] = 1 - 2 * (xx + zz);
|
||||
pOut->mat[6] = 2 * (yz + xw);
|
||||
pOut->mat[7] = 0.0;
|
||||
|
||||
pOut->mat[8] = 2 * (xz + yw);
|
||||
pOut->mat[9] = 2 * (yz - xw);
|
||||
pOut->mat[10] = 1 - 2 * (xx + yy);
|
||||
pOut->mat[11] = 0.0;
|
||||
|
||||
pOut->mat[12] = 0.0;
|
||||
pOut->mat[13] = 0.0;
|
||||
pOut->mat[14] = 0.0;
|
||||
pOut->mat[15] = 1.0;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/** Builds a scaling matrix */
|
||||
kmMat4* kmMat4Scaling(kmMat4* pOut, const kmScalar x, const kmScalar y,
|
||||
kmScalar z)
|
||||
{
|
||||
memset(pOut->mat, 0, sizeof(kmScalar) * 16);
|
||||
pOut->mat[0] = x;
|
||||
pOut->mat[5] = y;
|
||||
pOut->mat[10] = z;
|
||||
pOut->mat[15] = 1.0f;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a translation matrix. All other elements in the matrix
|
||||
* will be set to zero except for the diagonal which is set to 1.0
|
||||
*/
|
||||
kmMat4* kmMat4Translation(kmMat4* pOut, const kmScalar x,
|
||||
kmScalar y, const kmScalar z)
|
||||
{
|
||||
//FIXME: Write a test for this
|
||||
memset(pOut->mat, 0, sizeof(kmScalar) * 16);
|
||||
|
||||
pOut->mat[0] = 1.0f;
|
||||
pOut->mat[5] = 1.0f;
|
||||
pOut->mat[10] = 1.0f;
|
||||
|
||||
pOut->mat[12] = x;
|
||||
pOut->mat[13] = y;
|
||||
pOut->mat[14] = z;
|
||||
pOut->mat[15] = 1.0f;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the up vector from a matrix. pIn is the matrix you
|
||||
* wish to extract the vector from. pOut is a pointer to the
|
||||
* kmVec3 structure that should hold the resulting vector
|
||||
*/
|
||||
kmVec3* kmMat4GetUpVec3(kmVec3* pOut, const kmMat4* pIn)
|
||||
{
|
||||
kmVec3MultiplyMat4(pOut, &KM_VEC3_POS_Y, pIn);
|
||||
kmVec3Normalize(pOut, pOut);
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/** Extract the right vector from a 4x4 matrix. The result is
|
||||
* stored in pOut. Returns pOut.
|
||||
*/
|
||||
kmVec3* kmMat4GetRightVec3(kmVec3* pOut, const kmMat4* pIn)
|
||||
{
|
||||
kmVec3MultiplyMat4(pOut, &KM_VEC3_POS_X, pIn);
|
||||
kmVec3Normalize(pOut, pOut);
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the forward vector from a 4x4 matrix. The result is
|
||||
* stored in pOut. Returns pOut.
|
||||
*/
|
||||
kmVec3* kmMat4GetForwardVec3RH(kmVec3* pOut, const kmMat4* pIn)
|
||||
{
|
||||
kmVec3MultiplyMat4(pOut, &KM_VEC3_NEG_Z, pIn);
|
||||
kmVec3Normalize(pOut, pOut);
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec3* kmMat4GetForwardVec3LH(kmVec3* pOut, const kmMat4* pIn)
|
||||
{
|
||||
kmVec3MultiplyMat4(pOut, &KM_VEC3_POS_Z, pIn);
|
||||
kmVec3Normalize(pOut, pOut);
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a perspective projection matrix in the
|
||||
* same way as gluPerspective
|
||||
*/
|
||||
kmMat4* kmMat4PerspectiveProjection(kmMat4* pOut, kmScalar fovY,
|
||||
kmScalar aspect, kmScalar zNear,
|
||||
kmScalar zFar)
|
||||
{
|
||||
kmScalar r = kmDegreesToRadians(fovY / 2);
|
||||
kmScalar deltaZ = zFar - zNear;
|
||||
kmScalar s = sin(r);
|
||||
kmScalar cotangent = 0;
|
||||
|
||||
if (deltaZ == 0 || s == 0 || aspect == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//cos(r) / sin(r) = cot(r)
|
||||
cotangent = cos(r) / s;
|
||||
|
||||
kmMat4Identity(pOut);
|
||||
pOut->mat[0] = cotangent / aspect;
|
||||
pOut->mat[5] = cotangent;
|
||||
pOut->mat[10] = -(zFar + zNear) / deltaZ;
|
||||
pOut->mat[11] = -1;
|
||||
pOut->mat[14] = -2 * zNear * zFar / deltaZ;
|
||||
pOut->mat[15] = 0;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/** Creates an orthographic projection matrix like glOrtho */
|
||||
kmMat4* kmMat4OrthographicProjection(kmMat4* pOut, kmScalar left,
|
||||
kmScalar right, kmScalar bottom,
|
||||
kmScalar top, kmScalar nearVal,
|
||||
kmScalar farVal)
|
||||
{
|
||||
kmScalar tx = -((right + left) / (right - left));
|
||||
kmScalar ty = -((top + bottom) / (top - bottom));
|
||||
kmScalar tz = -((farVal + nearVal) / (farVal - nearVal));
|
||||
|
||||
kmMat4Identity(pOut);
|
||||
pOut->mat[0] = 2 / (right - left);
|
||||
pOut->mat[5] = 2 / (top - bottom);
|
||||
pOut->mat[10] = -2 / (farVal - nearVal);
|
||||
pOut->mat[12] = tx;
|
||||
pOut->mat[13] = ty;
|
||||
pOut->mat[14] = tz;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a translation matrix in the same way as gluLookAt()
|
||||
* the resulting matrix is stored in pOut. pOut is returned.
|
||||
*/
|
||||
kmMat4* kmMat4LookAt(kmMat4* pOut, const kmVec3* pEye,
|
||||
const kmVec3* pCenter, const kmVec3* pUp)
|
||||
{
|
||||
kmVec3 f, up, s, u;
|
||||
kmMat4 translate;
|
||||
|
||||
kmVec3Subtract(&f, pCenter, pEye);
|
||||
kmVec3Normalize(&f, &f);
|
||||
|
||||
kmVec3Assign(&up, pUp);
|
||||
kmVec3Normalize(&up, &up);
|
||||
|
||||
kmVec3Cross(&s, &f, &up);
|
||||
kmVec3Normalize(&s, &s);
|
||||
|
||||
kmVec3Cross(&u, &s, &f);
|
||||
kmVec3Normalize(&s, &s);
|
||||
|
||||
kmMat4Identity(pOut);
|
||||
|
||||
pOut->mat[0] = s.x;
|
||||
pOut->mat[4] = s.y;
|
||||
pOut->mat[8] = s.z;
|
||||
|
||||
pOut->mat[1] = u.x;
|
||||
pOut->mat[5] = u.y;
|
||||
pOut->mat[9] = u.z;
|
||||
|
||||
pOut->mat[2] = -f.x;
|
||||
pOut->mat[6] = -f.y;
|
||||
pOut->mat[10] = -f.z;
|
||||
|
||||
kmMat4Translation(&translate, -pEye->x, -pEye->y, -pEye->z);
|
||||
kmMat4Multiply(pOut, pOut, &translate);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract a 3x3 rotation matrix from the input 4x4 transformation.
|
||||
* Stores the result in pOut, returns pOut
|
||||
*/
|
||||
kmMat3* kmMat4ExtractRotation(kmMat3* pOut, const kmMat4* pIn)
|
||||
{
|
||||
pOut->mat[0] = pIn->mat[0];
|
||||
pOut->mat[1] = pIn->mat[1];
|
||||
pOut->mat[2] = pIn->mat[2];
|
||||
|
||||
pOut->mat[3] = pIn->mat[4];
|
||||
pOut->mat[4] = pIn->mat[5];
|
||||
pOut->mat[5] = pIn->mat[6];
|
||||
|
||||
pOut->mat[6] = pIn->mat[8];
|
||||
pOut->mat[7] = pIn->mat[9];
|
||||
pOut->mat[8] = pIn->mat[10];
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Take the rotation from a 4x4 transformation matrix, and return it as an axis and an angle (in radians)
|
||||
* returns the output axis.
|
||||
*/
|
||||
kmVec3* kmMat4RotationToAxisAngle(kmVec3* pAxis, kmScalar* radians, const kmMat4* pIn)
|
||||
{
|
||||
/*Surely not this easy?*/
|
||||
kmQuaternion temp;
|
||||
kmMat3 rotation;
|
||||
kmMat4ExtractRotation(&rotation, pIn);
|
||||
kmQuaternionRotationMatrix(&temp, &rotation);
|
||||
kmQuaternionToAxisAngle(&temp, pAxis, radians);
|
||||
return pAxis;
|
||||
}
|
||||
|
||||
/** Build a 4x4 OpenGL transformation matrix using a 3x3 rotation matrix,
|
||||
* and a 3d vector representing a translation. Assign the result to pOut,
|
||||
* pOut is also returned.
|
||||
*/
|
||||
kmMat4* kmMat4RotationTranslation(kmMat4* pOut, const kmMat3* rotation, const kmVec3* translation)
|
||||
{
|
||||
pOut->mat[0] = rotation->mat[0];
|
||||
pOut->mat[1] = rotation->mat[1];
|
||||
pOut->mat[2] = rotation->mat[2];
|
||||
pOut->mat[3] = 0.0f;
|
||||
|
||||
pOut->mat[4] = rotation->mat[3];
|
||||
pOut->mat[5] = rotation->mat[4];
|
||||
pOut->mat[6] = rotation->mat[5];
|
||||
pOut->mat[7] = 0.0f;
|
||||
|
||||
pOut->mat[8] = rotation->mat[6];
|
||||
pOut->mat[9] = rotation->mat[7];
|
||||
pOut->mat[10] = rotation->mat[8];
|
||||
pOut->mat[11] = 0.0f;
|
||||
|
||||
pOut->mat[12] = translation->x;
|
||||
pOut->mat[13] = translation->y;
|
||||
pOut->mat[14] = translation->z;
|
||||
pOut->mat[15] = 1.0f;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmPlane* kmMat4ExtractPlane(kmPlane* pOut, const kmMat4* pIn, const kmEnum plane)
|
||||
{
|
||||
kmScalar t = 1.0f;
|
||||
|
||||
switch(plane) {
|
||||
case KM_PLANE_RIGHT:
|
||||
pOut->a = pIn->mat[3] - pIn->mat[0];
|
||||
pOut->b = pIn->mat[7] - pIn->mat[4];
|
||||
pOut->c = pIn->mat[11] - pIn->mat[8];
|
||||
pOut->d = pIn->mat[15] - pIn->mat[12];
|
||||
break;
|
||||
case KM_PLANE_LEFT:
|
||||
pOut->a = pIn->mat[3] + pIn->mat[0];
|
||||
pOut->b = pIn->mat[7] + pIn->mat[4];
|
||||
pOut->c = pIn->mat[11] + pIn->mat[8];
|
||||
pOut->d = pIn->mat[15] + pIn->mat[12];
|
||||
break;
|
||||
case KM_PLANE_BOTTOM:
|
||||
pOut->a = pIn->mat[3] + pIn->mat[1];
|
||||
pOut->b = pIn->mat[7] + pIn->mat[5];
|
||||
pOut->c = pIn->mat[11] + pIn->mat[9];
|
||||
pOut->d = pIn->mat[15] + pIn->mat[13];
|
||||
break;
|
||||
case KM_PLANE_TOP:
|
||||
pOut->a = pIn->mat[3] - pIn->mat[1];
|
||||
pOut->b = pIn->mat[7] - pIn->mat[5];
|
||||
pOut->c = pIn->mat[11] - pIn->mat[9];
|
||||
pOut->d = pIn->mat[15] - pIn->mat[13];
|
||||
break;
|
||||
case KM_PLANE_FAR:
|
||||
pOut->a = pIn->mat[3] - pIn->mat[2];
|
||||
pOut->b = pIn->mat[7] - pIn->mat[6];
|
||||
pOut->c = pIn->mat[11] - pIn->mat[10];
|
||||
pOut->d = pIn->mat[15] - pIn->mat[14];
|
||||
break;
|
||||
case KM_PLANE_NEAR:
|
||||
pOut->a = pIn->mat[3] + pIn->mat[2];
|
||||
pOut->b = pIn->mat[7] + pIn->mat[6];
|
||||
pOut->c = pIn->mat[11] + pIn->mat[10];
|
||||
pOut->d = pIn->mat[15] + pIn->mat[14];
|
||||
break;
|
||||
default:
|
||||
assert(0 && "Invalid plane index");
|
||||
}
|
||||
|
||||
t = sqrtf(pOut->a * pOut->a +
|
||||
pOut->b * pOut->b +
|
||||
pOut->c * pOut->c);
|
||||
pOut->a /= t;
|
||||
pOut->b /= t;
|
||||
pOut->c /= t;
|
||||
pOut->d /= t;
|
||||
|
||||
return pOut;
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
Copyright (c) 2008, Luke Benstead.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef MAT4_H_INCLUDED
|
||||
#define MAT4_H_INCLUDED
|
||||
|
||||
#include "utility.h"
|
||||
|
||||
struct kmVec3;
|
||||
struct kmMat3;
|
||||
struct kmQuaternion;
|
||||
struct kmPlane;
|
||||
|
||||
/*
|
||||
A 4x4 matrix
|
||||
|
||||
| 0 4 8 12 |
|
||||
mat = | 1 5 9 13 |
|
||||
| 2 6 10 14 |
|
||||
| 3 7 11 15 |
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct kmMat4 {
|
||||
kmScalar mat[16];
|
||||
} kmMat4;
|
||||
|
||||
kmMat4* kmMat4Fill(kmMat4* pOut, const kmScalar* pMat);
|
||||
|
||||
|
||||
kmMat4* kmMat4Identity(kmMat4* pOut);
|
||||
|
||||
kmMat4* kmMat4Inverse(kmMat4* pOut, const kmMat4* pM);
|
||||
|
||||
|
||||
int kmMat4IsIdentity(const kmMat4* pIn);
|
||||
|
||||
kmMat4* kmMat4Transpose(kmMat4* pOut, const kmMat4* pIn);
|
||||
kmMat4* kmMat4Multiply(kmMat4* pOut, const kmMat4* pM1, const kmMat4* pM2);
|
||||
|
||||
kmMat4* kmMat4Assign(kmMat4* pOut, const kmMat4* pIn);
|
||||
kmMat4* kmMat4AssignMat3(kmMat4* pOut, const struct kmMat3* pIn);
|
||||
|
||||
int kmMat4AreEqual(const kmMat4* pM1, const kmMat4* pM2);
|
||||
|
||||
kmMat4* kmMat4RotationX(kmMat4* pOut, const kmScalar radians);
|
||||
kmMat4* kmMat4RotationY(kmMat4* pOut, const kmScalar radians);
|
||||
kmMat4* kmMat4RotationZ(kmMat4* pOut, const kmScalar radians);
|
||||
kmMat4* kmMat4RotationYawPitchRoll(kmMat4* pOut, const kmScalar pitch, const kmScalar yaw, const kmScalar roll);
|
||||
kmMat4* kmMat4RotationQuaternion(kmMat4* pOut, const struct kmQuaternion* pQ);
|
||||
kmMat4* kmMat4RotationTranslation(kmMat4* pOut, const struct kmMat3* rotation, const struct kmVec3* translation);
|
||||
kmMat4* kmMat4Scaling(kmMat4* pOut, const kmScalar x, const kmScalar y, const kmScalar z);
|
||||
kmMat4* kmMat4Translation(kmMat4* pOut, const kmScalar x, const kmScalar y, const kmScalar z);
|
||||
|
||||
struct kmVec3* kmMat4GetUpVec3(struct kmVec3* pOut, const kmMat4* pIn);
|
||||
struct kmVec3* kmMat4GetRightVec3(struct kmVec3* pOut, const kmMat4* pIn);
|
||||
struct kmVec3* kmMat4GetForwardVec3RH(struct kmVec3* pOut, const kmMat4* pIn);
|
||||
struct kmVec3* kmMat4GetForwardVec3LH(struct kmVec3* pOut, const kmMat4* pIn);
|
||||
|
||||
kmMat4* kmMat4PerspectiveProjection(kmMat4* pOut, kmScalar fovY, kmScalar aspect, kmScalar zNear, kmScalar zFar);
|
||||
kmMat4* kmMat4OrthographicProjection(kmMat4* pOut, kmScalar left, kmScalar right, kmScalar bottom, kmScalar top, kmScalar nearVal, kmScalar farVal);
|
||||
kmMat4* kmMat4LookAt(kmMat4* pOut, const struct kmVec3* pEye, const struct kmVec3* pCenter, const struct kmVec3* pUp);
|
||||
|
||||
kmMat4* kmMat4RotationAxisAngle(kmMat4* pOut, const struct kmVec3* axis, kmScalar radians);
|
||||
struct kmMat3* kmMat4ExtractRotation(struct kmMat3* pOut, const kmMat4* pIn);
|
||||
struct kmPlane* kmMat4ExtractPlane(struct kmPlane* pOut, const kmMat4* pIn, const kmEnum plane);
|
||||
struct kmVec3* kmMat4RotationToAxisAngle(struct kmVec3* pAxis, kmScalar* radians, const kmMat4* pIn);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* MAT4_H_INCLUDED */
|
|
@ -0,0 +1,254 @@
|
|||
/*
|
||||
Copyright (c) 2008, Luke Benstead.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "vec3.h"
|
||||
#include "vec4.h"
|
||||
#include "plane.h"
|
||||
#include "mat4.h"
|
||||
|
||||
kmScalar kmPlaneDot(const kmPlane* pP, const kmVec4* pV)
|
||||
{
|
||||
//a*x + b*y + c*z + d*w
|
||||
|
||||
return (pP->a * pV->x +
|
||||
pP->b * pV->y +
|
||||
pP->c * pV->z +
|
||||
pP->d * pV->w);
|
||||
}
|
||||
|
||||
kmScalar kmPlaneDotCoord(const kmPlane* pP, const kmVec3* pV)
|
||||
{
|
||||
return (pP->a * pV->x +
|
||||
pP->b * pV->y +
|
||||
pP->c * pV->z + pP->d);
|
||||
}
|
||||
|
||||
kmScalar kmPlaneDotNormal(const kmPlane* pP, const kmVec3* pV)
|
||||
{
|
||||
return (pP->a * pV->x +
|
||||
pP->b * pV->y +
|
||||
pP->c * pV->z);
|
||||
}
|
||||
|
||||
kmPlane* kmPlaneFromNormalAndDistance(kmPlane* plane, const struct kmVec3* normal, const kmScalar dist) {
|
||||
plane->a = normal->x;
|
||||
plane->b = normal->y;
|
||||
plane->c = normal->z;
|
||||
plane->d = dist;
|
||||
|
||||
return plane;
|
||||
}
|
||||
|
||||
kmPlane* kmPlaneFromPointAndNormal(kmPlane* pOut, const kmVec3* pPoint, const kmVec3* pNormal)
|
||||
{
|
||||
/*
|
||||
Planea = Nx
|
||||
Planeb = Ny
|
||||
Planec = Nz
|
||||
Planed = −N⋅P
|
||||
*/
|
||||
|
||||
|
||||
pOut->a = pNormal->x;
|
||||
pOut->b = pNormal->y;
|
||||
pOut->c = pNormal->z;
|
||||
pOut->d = -kmVec3Dot(pNormal, pPoint);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a plane from 3 points. The result is stored in pOut.
|
||||
* pOut is returned.
|
||||
*/
|
||||
kmPlane* kmPlaneFromPoints(kmPlane* pOut, const kmVec3* p1, const kmVec3* p2, const kmVec3* p3)
|
||||
{
|
||||
/*
|
||||
v = (B − A) × (C − A)
|
||||
n = 1⁄|v| v
|
||||
Outa = nx
|
||||
Outb = ny
|
||||
Outc = nz
|
||||
Outd = −n⋅A
|
||||
*/
|
||||
|
||||
kmVec3 n, v1, v2;
|
||||
kmVec3Subtract(&v1, p2, p1); //Create the vectors for the 2 sides of the triangle
|
||||
kmVec3Subtract(&v2, p3, p1);
|
||||
kmVec3Cross(&n, &v1, &v2); //Use the cross product to get the normal
|
||||
|
||||
kmVec3Normalize(&n, &n); //Normalize it and assign to pOut->m_N
|
||||
|
||||
pOut->a = n.x;
|
||||
pOut->b = n.y;
|
||||
pOut->c = n.z;
|
||||
pOut->d = kmVec3Dot(kmVec3Scale(&n, &n, -1.0), p1);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
// Added by tlensing (http://icedcoffee-framework.org)
|
||||
kmVec3* kmPlaneIntersectLine(kmVec3* pOut, const kmPlane* pP, const kmVec3* pV1, const kmVec3* pV2)
|
||||
{
|
||||
/*
|
||||
n = (Planea, Planeb, Planec)
|
||||
d = V − U
|
||||
Out = U − d⋅(Pd + n⋅U)⁄(d⋅n) [iff d⋅n ≠ 0]
|
||||
*/
|
||||
kmVec3 d; // direction from V1 to V2
|
||||
kmVec3Subtract(&d, pV2, pV1); // Get the direction vector
|
||||
|
||||
kmVec3 n; // plane normal
|
||||
n.x = pP->a;
|
||||
n.y = pP->b;
|
||||
n.z = pP->c;
|
||||
kmVec3Normalize(&n, &n);
|
||||
|
||||
kmScalar nt = -(n.x * pV1->x + n.y * pV1->y + n.z * pV1->z + pP->d);
|
||||
kmScalar dt = (n.x * d.x + n.y * d.y + n.z * d.z);
|
||||
|
||||
if (fabs(dt) < kmEpsilon) {
|
||||
pOut = NULL;
|
||||
return pOut; // line parallel or contained
|
||||
}
|
||||
|
||||
kmScalar t = nt/dt;
|
||||
pOut->x = pV1->x + d.x * t;
|
||||
pOut->y = pV1->y + d.y * t;
|
||||
pOut->z = pV1->z + d.z * t;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmPlane* kmPlaneNormalize(kmPlane* pOut, const kmPlane* pP)
|
||||
{
|
||||
kmVec3 n;
|
||||
kmScalar l = 0;
|
||||
|
||||
if (!pP->a && !pP->b && !pP->c) {
|
||||
pOut->a = pP->a;
|
||||
pOut->b = pP->b;
|
||||
pOut->c = pP->c;
|
||||
pOut->d = pP->d;
|
||||
return pOut;
|
||||
}
|
||||
|
||||
n.x = pP->a;
|
||||
n.y = pP->b;
|
||||
n.z = pP->c;
|
||||
|
||||
l = 1.0f / kmVec3Length(&n); //Get 1/length
|
||||
kmVec3Normalize(&n, &n); //Normalize the vector and assign to pOut
|
||||
|
||||
pOut->a = n.x;
|
||||
pOut->b = n.y;
|
||||
pOut->c = n.z;
|
||||
|
||||
pOut->d = pP->d * l; //Scale the D value and assign to pOut
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmPlane* kmPlaneScale(kmPlane* pOut, const kmPlane* pP, kmScalar s)
|
||||
{
|
||||
assert(0 && "Not implemented");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns POINT_INFRONT_OF_PLANE if pP is infront of pIn. Returns
|
||||
* POINT_BEHIND_PLANE if it is behind. Returns POINT_ON_PLANE otherwise
|
||||
*/
|
||||
KM_POINT_CLASSIFICATION kmPlaneClassifyPoint(const kmPlane* pIn, const kmVec3* pP)
|
||||
{
|
||||
// This function will determine if a point is on, in front of, or behind
|
||||
// the plane. First we store the dot product of the plane and the point.
|
||||
kmScalar distance = pIn->a * pP->x + pIn->b * pP->y + pIn->c * pP->z + pIn->d;
|
||||
|
||||
// Simply put if the dot product is greater than 0 then it is infront of it.
|
||||
// If it is less than 0 then it is behind it. And if it is 0 then it is on it.
|
||||
if(distance > kmEpsilon) return POINT_INFRONT_OF_PLANE;
|
||||
if(distance < -kmEpsilon) return POINT_BEHIND_PLANE;
|
||||
|
||||
return POINT_ON_PLANE;
|
||||
}
|
||||
|
||||
kmPlane* kmPlaneExtractFromMat4(kmPlane* pOut, const struct kmMat4* pIn, kmInt row) {
|
||||
int scale = (row < 0) ? -1 : 1;
|
||||
row = abs(row) - 1;
|
||||
|
||||
pOut->a = pIn->mat[3] + scale * pIn->mat[row];
|
||||
pOut->b = pIn->mat[7] + scale * pIn->mat[row + 4];
|
||||
pOut->c = pIn->mat[11] + scale * pIn->mat[row + 8];
|
||||
pOut->d = pIn->mat[15] + scale * pIn->mat[row + 12];
|
||||
|
||||
return kmPlaneNormalize(pOut, pOut);
|
||||
}
|
||||
|
||||
kmVec3* kmPlaneGetIntersection(kmVec3* pOut, const kmPlane* p1, const kmPlane* p2, const kmPlane* p3) {
|
||||
kmVec3 n1, n2, n3, cross;
|
||||
kmVec3 r1, r2, r3;
|
||||
double denom = 0;
|
||||
|
||||
kmVec3Fill(&n1, p1->a, p1->b, p1->c);
|
||||
kmVec3Fill(&n2, p2->a, p2->b, p2->c);
|
||||
kmVec3Fill(&n3, p3->a, p3->b, p3->c);
|
||||
|
||||
kmVec3Cross(&cross, &n2, &n3);
|
||||
|
||||
denom = kmVec3Dot(&n1, &cross);
|
||||
|
||||
if (kmAlmostEqual(denom, 0.0)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
kmVec3Cross(&r1, &n2, &n3);
|
||||
kmVec3Cross(&r2, &n3, &n1);
|
||||
kmVec3Cross(&r3, &n1, &n2);
|
||||
|
||||
kmVec3Scale(&r1, &r1, -p1->d);
|
||||
kmVec3Scale(&r2, &r2, p2->d);
|
||||
kmVec3Scale(&r3, &r3, p3->d);
|
||||
|
||||
kmVec3Subtract(pOut, &r1, &r2);
|
||||
kmVec3Subtract(pOut, pOut, &r3);
|
||||
kmVec3Scale(pOut, pOut, 1.0 / denom);
|
||||
|
||||
//p = -d1 * ( n2.Cross ( n3 ) ) – d2 * ( n3.Cross ( n1 ) ) – d3 * ( n1.Cross ( n2 ) ) / denom;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmPlane* kmPlaneFill(kmPlane* plane, kmScalar a, kmScalar b, kmScalar c, kmScalar d) {
|
||||
plane->a = a;
|
||||
plane->b = b;
|
||||
plane->c = c;
|
||||
plane->d = d;
|
||||
|
||||
return plane;
|
||||
}
|
|
@ -33,7 +33,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#define KM_PLANE_NEAR 4
|
||||
#define KM_PLANE_FAR 5
|
||||
|
||||
#include "CCPlatformMacros.h"
|
||||
#include "utility.h"
|
||||
|
||||
struct kmVec3;
|
||||
|
@ -41,28 +40,33 @@ struct kmVec4;
|
|||
struct kmMat4;
|
||||
|
||||
typedef struct kmPlane {
|
||||
kmScalar a, b, c, d;
|
||||
kmScalar a, b, c, d;
|
||||
} kmPlane;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum POINT_CLASSIFICATION {
|
||||
POINT_INFRONT_OF_PLANE = 0,
|
||||
POINT_BEHIND_PLANE,
|
||||
POINT_ON_PLANE,
|
||||
} POINT_CLASSIFICATION;
|
||||
typedef enum KM_POINT_CLASSIFICATION {
|
||||
POINT_BEHIND_PLANE = -1,
|
||||
POINT_ON_PLANE = 0,
|
||||
POINT_INFRONT_OF_PLANE = 1
|
||||
} KM_POINT_CLASSIFICATION;
|
||||
|
||||
CC_DLL const kmScalar kmPlaneDot(const kmPlane* pP, const struct kmVec4* pV);
|
||||
CC_DLL const kmScalar kmPlaneDotCoord(const kmPlane* pP, const struct kmVec3* pV);
|
||||
CC_DLL const kmScalar kmPlaneDotNormal(const kmPlane* pP, const struct kmVec3* pV);
|
||||
CC_DLL kmPlane* const kmPlaneFromPointNormal(kmPlane* pOut, const struct kmVec3* pPoint, const struct kmVec3* pNormal);
|
||||
CC_DLL kmPlane* const kmPlaneFromPoints(kmPlane* pOut, const struct kmVec3* p1, const struct kmVec3* p2, const struct kmVec3* p3);
|
||||
CC_DLL kmVec3* const kmPlaneIntersectLine(struct kmVec3* pOut, const kmPlane* pP, const struct kmVec3* pV1, const struct kmVec3* pV2);
|
||||
CC_DLL kmPlane* const kmPlaneNormalize(kmPlane* pOut, const kmPlane* pP);
|
||||
CC_DLL kmPlane* const kmPlaneScale(kmPlane* pOut, const kmPlane* pP, kmScalar s);
|
||||
CC_DLL const POINT_CLASSIFICATION kmPlaneClassifyPoint(const kmPlane* pIn, const kmVec3* pP); /** Classifies a point against a plane */
|
||||
kmPlane* kmPlaneFill(kmPlane* plane, float a, float b, float c, float d);
|
||||
kmScalar kmPlaneDot(const kmPlane* pP, const struct kmVec4* pV);
|
||||
kmScalar kmPlaneDotCoord(const kmPlane* pP, const struct kmVec3* pV);
|
||||
kmScalar kmPlaneDotNormal(const kmPlane* pP, const struct kmVec3* pV);
|
||||
kmPlane* kmPlaneFromNormalAndDistance(kmPlane* plane, const struct kmVec3* normal, const kmScalar dist);
|
||||
kmPlane* kmPlaneFromPointAndNormal(kmPlane* pOut, const struct kmVec3* pPoint, const struct kmVec3* pNormal);
|
||||
kmPlane* kmPlaneFromPoints(kmPlane* pOut, const struct kmVec3* p1, const struct kmVec3* p2, const struct kmVec3* p3);
|
||||
struct kmVec3* kmPlaneIntersectLine(struct kmVec3* pOut, const kmPlane* pP, const struct kmVec3* pV1, const struct kmVec3* pV2);
|
||||
kmPlane* kmPlaneNormalize(kmPlane* pOut, const kmPlane* pP);
|
||||
kmPlane* kmPlaneScale(kmPlane* pOut, const kmPlane* pP, kmScalar s);
|
||||
KM_POINT_CLASSIFICATION kmPlaneClassifyPoint(const kmPlane* pIn, const struct kmVec3* pP); /** Classifys a point against a plane */
|
||||
|
||||
kmPlane* kmPlaneExtractFromMat4(kmPlane* pOut, const struct kmMat4* pIn, kmInt row);
|
||||
struct kmVec3* kmPlaneGetIntersection(struct kmVec3* pOut, const kmPlane* p1, const kmPlane* p2, const kmPlane* p3);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
|
@ -0,0 +1,609 @@
|
|||
/*
|
||||
Copyright (c) 2008, Luke Benstead.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <memory.h>
|
||||
#include <string.h>
|
||||
#include "mat4.h"
|
||||
#include "utility.h"
|
||||
#include "mat3.h"
|
||||
#include "vec3.h"
|
||||
#include "quaternion.h"
|
||||
|
||||
int kmQuaternionAreEqual(const kmQuaternion* p1, const kmQuaternion* p2) {
|
||||
if ((p1->x < (p2->x + kmEpsilon) && p1->x > (p2->x - kmEpsilon)) &&
|
||||
(p1->y < (p2->y + kmEpsilon) && p1->y > (p2->y - kmEpsilon)) &&
|
||||
(p1->z < (p2->z + kmEpsilon) && p1->z > (p2->z - kmEpsilon)) &&
|
||||
(p1->w < (p2->w + kmEpsilon) && p1->w > (p2->w - kmEpsilon))) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
kmQuaternion* kmQuaternionFill(kmQuaternion* pOut, kmScalar x, kmScalar y, kmScalar z, kmScalar w) {
|
||||
pOut->x = x;
|
||||
pOut->y = y;
|
||||
pOut->z = z;
|
||||
pOut->w = w;
|
||||
return pOut;
|
||||
}
|
||||
///< Returns the dot product of the 2 quaternions
|
||||
kmScalar kmQuaternionDot(const kmQuaternion* q1, const kmQuaternion* q2)
|
||||
{
|
||||
/* A dot B = B dot A = AtBt + AxBx + AyBy + AzBz */
|
||||
|
||||
return (q1->w * q2->w +
|
||||
q1->x * q2->x +
|
||||
q1->y * q2->y +
|
||||
q1->z * q2->z);
|
||||
}
|
||||
|
||||
///< Returns the exponential of the quaternion
|
||||
kmQuaternion* kmQuaternionExp(kmQuaternion* pOut, const kmQuaternion* pIn)
|
||||
{
|
||||
assert(0);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
///< Makes the passed quaternion an identity quaternion
|
||||
kmQuaternion* kmQuaternionIdentity(kmQuaternion* pOut)
|
||||
{
|
||||
pOut->x = 0.0;
|
||||
pOut->y = 0.0;
|
||||
pOut->z = 0.0;
|
||||
pOut->w = 1.0;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
///< Returns the inverse of the passed Quaternion
|
||||
kmQuaternion* kmQuaternionInverse(kmQuaternion* pOut,
|
||||
const kmQuaternion* pIn)
|
||||
{
|
||||
kmScalar l = kmQuaternionLength(pIn);
|
||||
|
||||
if (fabs(l) < kmEpsilon)
|
||||
{
|
||||
pOut->x = 0.0;
|
||||
pOut->y = 0.0;
|
||||
pOut->z = 0.0;
|
||||
pOut->w = 0.0;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
pOut->x = -pIn->x;
|
||||
pOut->y = -pIn->y;
|
||||
pOut->z = -pIn->z;
|
||||
pOut->w = pIn->w;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
///< Returns true if the quaternion is an identity quaternion
|
||||
int kmQuaternionIsIdentity(const kmQuaternion* pIn)
|
||||
{
|
||||
return (pIn->x == 0.0 && pIn->y == 0.0 && pIn->z == 0.0 &&
|
||||
pIn->w == 1.0);
|
||||
}
|
||||
|
||||
///< Returns the length of the quaternion
|
||||
kmScalar kmQuaternionLength(const kmQuaternion* pIn)
|
||||
{
|
||||
return sqrt(kmQuaternionLengthSq(pIn));
|
||||
}
|
||||
|
||||
///< Returns the length of the quaternion squared (prevents a sqrt)
|
||||
kmScalar kmQuaternionLengthSq(const kmQuaternion* pIn)
|
||||
{
|
||||
return pIn->x * pIn->x + pIn->y * pIn->y + pIn->z * pIn->z + pIn->w * pIn->w;
|
||||
}
|
||||
|
||||
///< Returns the natural logarithm
|
||||
kmQuaternion* kmQuaternionLn(kmQuaternion* pOut,
|
||||
const kmQuaternion* pIn)
|
||||
{
|
||||
/*
|
||||
A unit quaternion, is defined by:
|
||||
Q == (cos(theta), sin(theta) * v) where |v| = 1
|
||||
The natural logarithm of Q is, ln(Q) = (0, theta * v)
|
||||
*/
|
||||
|
||||
assert(0);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
///< Multiplies 2 quaternions together
|
||||
extern
|
||||
kmQuaternion* kmQuaternionMultiply(kmQuaternion* pOut,
|
||||
const kmQuaternion* qu1,
|
||||
const kmQuaternion* qu2)
|
||||
{
|
||||
kmQuaternion tmp1, tmp2;
|
||||
kmQuaternionAssign(&tmp1, qu1);
|
||||
kmQuaternionAssign(&tmp2, qu2);
|
||||
|
||||
//Just aliasing
|
||||
kmQuaternion* q1 = &tmp1;
|
||||
kmQuaternion* q2 = &tmp2;
|
||||
|
||||
pOut->x = q1->w * q2->x + q1->x * q2->w + q1->y * q2->z - q1->z * q2->y;
|
||||
pOut->y = q1->w * q2->y + q1->y * q2->w + q1->z * q2->x - q1->x * q2->z;
|
||||
pOut->z = q1->w * q2->z + q1->z * q2->w + q1->x * q2->y - q1->y * q2->x;
|
||||
pOut->w = q1->w * q2->w - q1->x * q2->x - q1->y * q2->y - q1->z * q2->z;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
///< Normalizes a quaternion
|
||||
kmQuaternion* kmQuaternionNormalize(kmQuaternion* pOut,
|
||||
const kmQuaternion* pIn)
|
||||
{
|
||||
kmScalar length = kmQuaternionLength(pIn);
|
||||
|
||||
if (fabs(length) < kmEpsilon)
|
||||
{
|
||||
pOut->x = 0.0;
|
||||
pOut->y = 0.0;
|
||||
pOut->z = 0.0;
|
||||
pOut->w = 0.0;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmQuaternionFill(pOut,
|
||||
pOut->x / length,
|
||||
pOut->y / length,
|
||||
pOut->z / length,
|
||||
pOut->w / length
|
||||
);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
///< Rotates a quaternion around an axis
|
||||
kmQuaternion* kmQuaternionRotationAxisAngle(kmQuaternion* pOut,
|
||||
const kmVec3* pV,
|
||||
kmScalar angle)
|
||||
{
|
||||
kmScalar rad = angle * 0.5f;
|
||||
kmScalar scale = sinf(rad);
|
||||
|
||||
pOut->x = pV->x * scale;
|
||||
pOut->y = pV->y * scale;
|
||||
pOut->z = pV->z * scale;
|
||||
pOut->w = cosf(rad);
|
||||
|
||||
kmQuaternionNormalize(pOut, pOut);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
///< Creates a quaternion from a rotation matrix
|
||||
kmQuaternion* kmQuaternionRotationMatrix(kmQuaternion* pOut,
|
||||
const kmMat3* pIn)
|
||||
{
|
||||
/*
|
||||
Note: The OpenGL matrices are transposed from the description below
|
||||
taken from the Matrix and Quaternion FAQ
|
||||
|
||||
if ( mat[0] > mat[5] && mat[0] > mat[10] ) { // Column 0:
|
||||
S = sqrt( 1.0 + mat[0] - mat[5] - mat[10] ) * 2;
|
||||
X = 0.25 * S;
|
||||
Y = (mat[4] + mat[1] ) / S;
|
||||
Z = (mat[2] + mat[8] ) / S;
|
||||
W = (mat[9] - mat[6] ) / S;
|
||||
} else if ( mat[5] > mat[10] ) { // Column 1:
|
||||
S = sqrt( 1.0 + mat[5] - mat[0] - mat[10] ) * 2;
|
||||
X = (mat[4] + mat[1] ) / S;
|
||||
Y = 0.25 * S;
|
||||
Z = (mat[9] + mat[6] ) / S;
|
||||
W = (mat[2] - mat[8] ) / S;
|
||||
} else { // Column 2:
|
||||
S = sqrt( 1.0 + mat[10] - mat[0] - mat[5] ) * 2;
|
||||
X = (mat[2] + mat[8] ) / S;
|
||||
Y = (mat[9] + mat[6] ) / S;
|
||||
Z = 0.25 * S;
|
||||
W = (mat[4] - mat[1] ) / S;
|
||||
}
|
||||
*/
|
||||
|
||||
kmScalar x, y, z, w;
|
||||
kmScalar *pMatrix = NULL;
|
||||
kmScalar m4x4[16] = {0};
|
||||
kmScalar scale = 0.0f;
|
||||
kmScalar diagonal = 0.0f;
|
||||
|
||||
if(!pIn) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* 0 3 6
|
||||
1 4 7
|
||||
2 5 8
|
||||
|
||||
0 1 2 3
|
||||
4 5 6 7
|
||||
8 9 10 11
|
||||
12 13 14 15*/
|
||||
|
||||
m4x4[0] = pIn->mat[0];
|
||||
m4x4[1] = pIn->mat[3];
|
||||
m4x4[2] = pIn->mat[6];
|
||||
m4x4[4] = pIn->mat[1];
|
||||
m4x4[5] = pIn->mat[4];
|
||||
m4x4[6] = pIn->mat[7];
|
||||
m4x4[8] = pIn->mat[2];
|
||||
m4x4[9] = pIn->mat[5];
|
||||
m4x4[10] = pIn->mat[8];
|
||||
m4x4[15] = 1;
|
||||
pMatrix = &m4x4[0];
|
||||
|
||||
diagonal = pMatrix[0] + pMatrix[5] + pMatrix[10] + 1;
|
||||
|
||||
if(diagonal > kmEpsilon) {
|
||||
// Calculate the scale of the diagonal
|
||||
scale = (kmScalar)sqrt(diagonal ) * 2;
|
||||
|
||||
// Calculate the x, y, x and w of the quaternion through the respective equation
|
||||
x = ( pMatrix[9] - pMatrix[6] ) / scale;
|
||||
y = ( pMatrix[2] - pMatrix[8] ) / scale;
|
||||
z = ( pMatrix[4] - pMatrix[1] ) / scale;
|
||||
w = 0.25f * scale;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the first element of the diagonal is the greatest value
|
||||
if ( pMatrix[0] > pMatrix[5] && pMatrix[0] > pMatrix[10] )
|
||||
{
|
||||
// Find the scale according to the first element, and double that value
|
||||
scale = (kmScalar)sqrt( 1.0f + pMatrix[0] - pMatrix[5] - pMatrix[10] ) * 2.0f;
|
||||
|
||||
// Calculate the x, y, x and w of the quaternion through the respective equation
|
||||
x = 0.25f * scale;
|
||||
y = (pMatrix[4] + pMatrix[1] ) / scale;
|
||||
z = (pMatrix[2] + pMatrix[8] ) / scale;
|
||||
w = (pMatrix[9] - pMatrix[6] ) / scale;
|
||||
}
|
||||
// Else if the second element of the diagonal is the greatest value
|
||||
else if (pMatrix[5] > pMatrix[10])
|
||||
{
|
||||
// Find the scale according to the second element, and double that value
|
||||
scale = (kmScalar)sqrt( 1.0f + pMatrix[5] - pMatrix[0] - pMatrix[10] ) * 2.0f;
|
||||
|
||||
// Calculate the x, y, x and w of the quaternion through the respective equation
|
||||
x = (pMatrix[4] + pMatrix[1] ) / scale;
|
||||
y = 0.25f * scale;
|
||||
z = (pMatrix[9] + pMatrix[6] ) / scale;
|
||||
w = (pMatrix[2] - pMatrix[8] ) / scale;
|
||||
}
|
||||
// Else the third element of the diagonal is the greatest value
|
||||
else
|
||||
{
|
||||
// Find the scale according to the third element, and double that value
|
||||
scale = (kmScalar)sqrt( 1.0f + pMatrix[10] - pMatrix[0] - pMatrix[5] ) * 2.0f;
|
||||
|
||||
// Calculate the x, y, x and w of the quaternion through the respective equation
|
||||
x = (pMatrix[2] + pMatrix[8] ) / scale;
|
||||
y = (pMatrix[9] + pMatrix[6] ) / scale;
|
||||
z = 0.25f * scale;
|
||||
w = (pMatrix[4] - pMatrix[1] ) / scale;
|
||||
}
|
||||
}
|
||||
|
||||
pOut->x = x;
|
||||
pOut->y = y;
|
||||
pOut->z = z;
|
||||
pOut->w = w;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
///< Create a quaternion from yaw, pitch and roll
|
||||
kmQuaternion* kmQuaternionRotationPitchYawRoll(kmQuaternion* pOut,
|
||||
kmScalar pitch,
|
||||
kmScalar yaw,
|
||||
kmScalar roll)
|
||||
{
|
||||
assert(pitch <= 2*kmPI);
|
||||
assert(yaw <= 2*kmPI);
|
||||
assert(roll <= 2*kmPI);
|
||||
|
||||
// Finds the Sin and Cosin for each half angles.
|
||||
float sY = sinf(yaw * 0.5);
|
||||
float cY = cosf(yaw * 0.5);
|
||||
float sZ = sinf(roll * 0.5);
|
||||
float cZ = cosf(roll * 0.5);
|
||||
float sX = sinf(pitch * 0.5);
|
||||
float cX = cosf(pitch * 0.5);
|
||||
|
||||
// Formula to construct a new Quaternion based on Euler Angles.
|
||||
pOut->w = cY * cZ * cX - sY * sZ * sX;
|
||||
pOut->x = sY * sZ * cX + cY * cZ * sX;
|
||||
pOut->y = sY * cZ * cX + cY * sZ * sX;
|
||||
pOut->z = cY * sZ * cX - sY * cZ * sX;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
///< Interpolate between 2 quaternions
|
||||
kmQuaternion* kmQuaternionSlerp(kmQuaternion* pOut,
|
||||
const kmQuaternion* q1,
|
||||
const kmQuaternion* q2,
|
||||
kmScalar t)
|
||||
{
|
||||
|
||||
kmScalar dot = kmQuaternionDot(q1, q2);
|
||||
const double DOT_THRESHOLD = 0.9995;
|
||||
|
||||
if (dot > DOT_THRESHOLD) {
|
||||
kmQuaternion diff;
|
||||
kmQuaternionSubtract(&diff, q2, q1);
|
||||
kmQuaternionScale(&diff, &diff, t);
|
||||
|
||||
kmQuaternionAdd(pOut, q1, &diff);
|
||||
kmQuaternionNormalize(pOut, pOut);
|
||||
return pOut;
|
||||
}
|
||||
|
||||
dot = kmClamp(dot, -1, 1);
|
||||
|
||||
kmScalar theta_0 = acos(dot);
|
||||
kmScalar theta = theta_0 * t;
|
||||
|
||||
kmQuaternion tmp;
|
||||
kmQuaternionScale(&tmp, q1, dot);
|
||||
kmQuaternionSubtract(&tmp, q2, &tmp);
|
||||
kmQuaternionNormalize(&tmp, &tmp);
|
||||
|
||||
kmQuaternion t1, t2;
|
||||
kmQuaternionScale(&t1, q1, cos(theta));
|
||||
kmQuaternionScale(&t2, &tmp, sin(theta));
|
||||
|
||||
kmQuaternionAdd(pOut, &t1, &t2);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
///< Get the axis and angle of rotation from a quaternion
|
||||
void kmQuaternionToAxisAngle(const kmQuaternion* pIn,
|
||||
kmVec3* pAxis,
|
||||
kmScalar* pAngle)
|
||||
{
|
||||
kmScalar tempAngle; // temp angle
|
||||
kmScalar scale; // temp vars
|
||||
|
||||
tempAngle = acosf(pIn->w);
|
||||
scale = sqrtf(kmSQR(pIn->x) + kmSQR(pIn->y) + kmSQR(pIn->z));
|
||||
|
||||
if (((scale > -kmEpsilon) && scale < kmEpsilon)
|
||||
|| (scale < 2*kmPI + kmEpsilon && scale > 2*kmPI - kmEpsilon)) // angle is 0 or 360 so just simply set axis to 0,0,1 with angle 0
|
||||
{
|
||||
*pAngle = 0.0f;
|
||||
|
||||
pAxis->x = 0.0f;
|
||||
pAxis->y = 0.0f;
|
||||
pAxis->z = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pAngle = tempAngle * 2.0f; // angle in radians
|
||||
|
||||
pAxis->x = pIn->x / scale;
|
||||
pAxis->y = pIn->y / scale;
|
||||
pAxis->z = pIn->z / scale;
|
||||
kmVec3Normalize(pAxis, pAxis);
|
||||
}
|
||||
}
|
||||
|
||||
kmQuaternion* kmQuaternionScale(kmQuaternion* pOut,
|
||||
const kmQuaternion* pIn,
|
||||
kmScalar s)
|
||||
{
|
||||
pOut->x = pIn->x * s;
|
||||
pOut->y = pIn->y * s;
|
||||
pOut->z = pIn->z * s;
|
||||
pOut->w = pIn->w * s;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmQuaternion* kmQuaternionAssign(kmQuaternion* pOut, const kmQuaternion* pIn)
|
||||
{
|
||||
memcpy(pOut, pIn, sizeof(kmScalar) * 4);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmQuaternion* kmQuaternionSubtract(kmQuaternion* pOut, const kmQuaternion* pQ1, const kmQuaternion* pQ2) {
|
||||
pOut->x = pQ1->x - pQ2->x;
|
||||
pOut->y = pQ1->y - pQ2->y;
|
||||
pOut->z = pQ1->z - pQ2->z;
|
||||
pOut->w = pQ1->w - pQ2->w;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmQuaternion* kmQuaternionAdd(kmQuaternion* pOut, const kmQuaternion* pQ1, const kmQuaternion* pQ2)
|
||||
{
|
||||
pOut->x = pQ1->x + pQ2->x;
|
||||
pOut->y = pQ1->y + pQ2->y;
|
||||
pOut->z = pQ1->z + pQ2->z;
|
||||
pOut->w = pQ1->w + pQ2->w;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/** Adapted from the OGRE engine!
|
||||
|
||||
Gets the shortest arc quaternion to rotate this vector to the destination
|
||||
vector.
|
||||
@remarks
|
||||
If you call this with a dest vector that is close to the inverse
|
||||
of this vector, we will rotate 180 degrees around the 'fallbackAxis'
|
||||
(if specified, or a generated axis if not) since in this case
|
||||
ANY axis of rotation is valid.
|
||||
*/
|
||||
|
||||
kmQuaternion* kmQuaternionRotationBetweenVec3(kmQuaternion* pOut, const kmVec3* vec1, const kmVec3* vec2, const kmVec3* fallback) {
|
||||
|
||||
kmVec3 v1, v2;
|
||||
kmScalar a;
|
||||
|
||||
kmVec3Assign(&v1, vec1);
|
||||
kmVec3Assign(&v2, vec2);
|
||||
|
||||
kmVec3Normalize(&v1, &v1);
|
||||
kmVec3Normalize(&v2, &v2);
|
||||
|
||||
a = kmVec3Dot(&v1, &v2);
|
||||
|
||||
if (a >= 1.0) {
|
||||
kmQuaternionIdentity(pOut);
|
||||
return pOut;
|
||||
}
|
||||
|
||||
if (a < (1e-6f - 1.0f)) {
|
||||
if (fabs(kmVec3LengthSq(fallback)) < kmEpsilon) {
|
||||
kmQuaternionRotationAxisAngle(pOut, fallback, kmPI);
|
||||
} else {
|
||||
kmVec3 axis;
|
||||
kmVec3 X;
|
||||
X.x = 1.0;
|
||||
X.y = 0.0;
|
||||
X.z = 0.0;
|
||||
|
||||
|
||||
kmVec3Cross(&axis, &X, vec1);
|
||||
|
||||
//If axis is zero
|
||||
if (fabs(kmVec3LengthSq(&axis)) < kmEpsilon) {
|
||||
kmVec3 Y;
|
||||
Y.x = 0.0;
|
||||
Y.y = 1.0;
|
||||
Y.z = 0.0;
|
||||
|
||||
kmVec3Cross(&axis, &Y, vec1);
|
||||
}
|
||||
|
||||
kmVec3Normalize(&axis, &axis);
|
||||
|
||||
kmQuaternionRotationAxisAngle(pOut, &axis, kmPI);
|
||||
}
|
||||
} else {
|
||||
kmScalar s = sqrtf((1+a) * 2);
|
||||
kmScalar invs = 1 / s;
|
||||
|
||||
kmVec3 c;
|
||||
kmVec3Cross(&c, &v1, &v2);
|
||||
|
||||
pOut->x = c.x * invs;
|
||||
pOut->y = c.y * invs;
|
||||
pOut->z = c.z * invs;
|
||||
pOut->w = s * 0.5f;
|
||||
|
||||
kmQuaternionNormalize(pOut, pOut);
|
||||
}
|
||||
|
||||
return pOut;
|
||||
|
||||
}
|
||||
|
||||
kmVec3* kmQuaternionMultiplyVec3(kmVec3* pOut, const kmQuaternion* q, const kmVec3* v) {
|
||||
kmVec3 uv, uuv, qvec;
|
||||
|
||||
qvec.x = q->x;
|
||||
qvec.y = q->y;
|
||||
qvec.z = q->z;
|
||||
|
||||
kmVec3Cross(&uv, &qvec, v);
|
||||
kmVec3Cross(&uuv, &qvec, &uv);
|
||||
|
||||
kmVec3Scale(&uv, &uv, (2.0f * q->w));
|
||||
kmVec3Scale(&uuv, &uuv, 2.0f);
|
||||
|
||||
kmVec3Add(pOut, v, &uv);
|
||||
kmVec3Add(pOut, pOut, &uuv);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec3* kmQuaternionGetUpVec3(kmVec3* pOut, const kmQuaternion* pIn) {
|
||||
return kmQuaternionMultiplyVec3(pOut, pIn, &KM_VEC3_POS_Y);
|
||||
}
|
||||
|
||||
kmVec3* kmQuaternionGetRightVec3(kmVec3* pOut, const kmQuaternion* pIn) {
|
||||
return kmQuaternionMultiplyVec3(pOut, pIn, &KM_VEC3_POS_X);
|
||||
}
|
||||
|
||||
kmVec3* kmQuaternionGetForwardVec3RH(kmVec3* pOut, const kmQuaternion* pIn) {
|
||||
return kmQuaternionMultiplyVec3(pOut, pIn, &KM_VEC3_NEG_Z);
|
||||
}
|
||||
|
||||
kmVec3* kmQuaternionGetForwardVec3LH(kmVec3* pOut, const kmQuaternion* pIn) {
|
||||
return kmQuaternionMultiplyVec3(pOut, pIn, &KM_VEC3_POS_Z);
|
||||
}
|
||||
|
||||
kmScalar kmQuaternionGetPitch(const kmQuaternion* q) {
|
||||
float result = atan2(2 * (q->y * q->z + q->w * q->x), q->w * q->w - q->x * q->x - q->y * q->y + q->z * q->z);
|
||||
return result;
|
||||
}
|
||||
|
||||
kmScalar kmQuaternionGetYaw(const kmQuaternion* q) {
|
||||
float result = asin(-2 * (q->x * q->z - q->w * q->y));
|
||||
return result;
|
||||
}
|
||||
|
||||
kmScalar kmQuaternionGetRoll(const kmQuaternion* q) {
|
||||
float result = atan2(2 * (q->x * q->y + q->w * q->z), q->w * q->w + q->x * q->x - q->y * q->y - q->z * q->z);
|
||||
return result;
|
||||
}
|
||||
|
||||
kmQuaternion* kmQuaternionLookRotation(kmQuaternion* pOut, const kmVec3* direction, const kmVec3* up) {
|
||||
kmMat3 tmp;
|
||||
kmMat3LookAt(&tmp, &KM_VEC3_ZERO, direction, up);
|
||||
return kmQuaternionNormalize(pOut, kmQuaternionRotationMatrix(pOut, &tmp));
|
||||
/*
|
||||
if(!direction->x && !direction->y && !direction->z) {
|
||||
return kmQuaternionIdentity(pOut);
|
||||
}
|
||||
|
||||
kmVec3 right;
|
||||
kmVec3Cross(&right, up, direction);
|
||||
|
||||
pOut->w = sqrtf(1.0f + right.x + up->y + direction->z) * 0.5f;
|
||||
|
||||
float w4_recip = 1.0f / (4.0f * pOut->w);
|
||||
|
||||
pOut->x = (up->z - direction->y) * w4_recip;
|
||||
pOut->y = (direction->x - right.z) * w4_recip;
|
||||
pOut->z = (right.y - up->x) * w4_recip;
|
||||
|
||||
return kmQuaternionNormalize(pOut, pOut);*/
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
Copyright (c) 2008, Luke Benstead.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef QUATERNION_H_INCLUDED
|
||||
#define QUATERNION_H_INCLUDED
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "utility.h"
|
||||
|
||||
struct kmMat4;
|
||||
struct kmMat3;
|
||||
struct kmVec3;
|
||||
|
||||
typedef struct kmQuaternion {
|
||||
kmScalar x;
|
||||
kmScalar y;
|
||||
kmScalar z;
|
||||
kmScalar w;
|
||||
} kmQuaternion;
|
||||
|
||||
int kmQuaternionAreEqual(const kmQuaternion* p1, const kmQuaternion* p2);
|
||||
kmQuaternion* kmQuaternionFill(kmQuaternion* pOut, kmScalar x, kmScalar y, kmScalar z, kmScalar w);
|
||||
kmScalar kmQuaternionDot(const kmQuaternion* q1, const kmQuaternion* q2); ///< Returns the dot product of the 2 quaternions
|
||||
|
||||
kmQuaternion* kmQuaternionExp(kmQuaternion* pOut, const kmQuaternion* pIn); ///< Returns the exponential of the quaternion
|
||||
|
||||
///< Makes the passed quaternion an identity quaternion
|
||||
|
||||
kmQuaternion* kmQuaternionIdentity(kmQuaternion* pOut);
|
||||
|
||||
///< Returns the inverse of the passed Quaternion
|
||||
|
||||
kmQuaternion* kmQuaternionInverse(kmQuaternion* pOut, const kmQuaternion* pIn);
|
||||
|
||||
///< Returns true if the quaternion is an identity quaternion
|
||||
|
||||
int kmQuaternionIsIdentity(const kmQuaternion* pIn);
|
||||
|
||||
///< Returns the length of the quaternion
|
||||
|
||||
kmScalar kmQuaternionLength(const kmQuaternion* pIn);
|
||||
|
||||
///< Returns the length of the quaternion squared (prevents a sqrt)
|
||||
|
||||
kmScalar kmQuaternionLengthSq(const kmQuaternion* pIn);
|
||||
|
||||
///< Returns the natural logarithm
|
||||
|
||||
kmQuaternion* kmQuaternionLn(kmQuaternion* pOut, const kmQuaternion* pIn);
|
||||
|
||||
///< Multiplies 2 quaternions together
|
||||
|
||||
kmQuaternion* kmQuaternionMultiply(kmQuaternion* pOut, const kmQuaternion* q1, const kmQuaternion* q2);
|
||||
|
||||
///< Normalizes a quaternion
|
||||
|
||||
kmQuaternion* kmQuaternionNormalize(kmQuaternion* pOut, const kmQuaternion* pIn);
|
||||
|
||||
///< Rotates a quaternion around an axis
|
||||
|
||||
kmQuaternion* kmQuaternionRotationAxisAngle(kmQuaternion* pOut, const struct kmVec3* pV, kmScalar angle);
|
||||
|
||||
///< Creates a quaternion from a rotation matrix
|
||||
|
||||
kmQuaternion* kmQuaternionRotationMatrix(kmQuaternion* pOut, const struct kmMat3* pIn);
|
||||
|
||||
///< Create a quaternion from yaw, pitch and roll
|
||||
|
||||
kmQuaternion* kmQuaternionRotationPitchYawRoll(kmQuaternion* pOut, kmScalar pitch, kmScalar yaw, kmScalar roll);
|
||||
///< Interpolate between 2 quaternions
|
||||
kmQuaternion* kmQuaternionSlerp(kmQuaternion* pOut, const kmQuaternion* q1, const kmQuaternion* q2, kmScalar t);
|
||||
|
||||
///< Get the axis and angle of rotation from a quaternion
|
||||
void kmQuaternionToAxisAngle(const kmQuaternion* pIn, struct kmVec3* pVector, kmScalar* pAngle);
|
||||
|
||||
///< Scale a quaternion
|
||||
kmQuaternion* kmQuaternionScale(kmQuaternion* pOut, const kmQuaternion* pIn, kmScalar s);
|
||||
kmQuaternion* kmQuaternionAssign(kmQuaternion* pOut, const kmQuaternion* pIn);
|
||||
kmQuaternion* kmQuaternionAdd(kmQuaternion* pOut, const kmQuaternion* pQ1, const kmQuaternion* pQ2);
|
||||
kmQuaternion* kmQuaternionSubtract(kmQuaternion* pOut, const kmQuaternion* pQ1, const kmQuaternion* pQ2);
|
||||
|
||||
kmQuaternion* kmQuaternionRotationBetweenVec3(kmQuaternion* pOut, const struct kmVec3* vec1, const struct kmVec3* vec2, const struct kmVec3* fallback);
|
||||
struct kmVec3* kmQuaternionMultiplyVec3(struct kmVec3* pOut, const kmQuaternion* q, const struct kmVec3* v);
|
||||
|
||||
kmVec3* kmQuaternionGetUpVec3(kmVec3* pOut, const kmQuaternion* pIn);
|
||||
kmVec3* kmQuaternionGetRightVec3(kmVec3* pOut, const kmQuaternion* pIn);
|
||||
kmVec3* kmQuaternionGetForwardVec3RH(kmVec3* pOut, const kmQuaternion* pIn);
|
||||
kmVec3* kmQuaternionGetForwardVec3LH(kmVec3* pOut, const kmQuaternion* pIn);
|
||||
|
||||
kmScalar kmQuaternionGetPitch(const kmQuaternion* q);
|
||||
kmScalar kmQuaternionGetYaw(const kmQuaternion* q);
|
||||
kmScalar kmQuaternionGetRoll(const kmQuaternion* q);
|
||||
|
||||
kmQuaternion* kmQuaternionLookRotation(kmQuaternion* pOut, const kmVec3* direction, const kmVec3* up);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,200 @@
|
|||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include "ray2.h"
|
||||
|
||||
void kmRay2Fill(kmRay2* ray, kmScalar px, kmScalar py, kmScalar vx, kmScalar vy) {
|
||||
ray->start.x = px;
|
||||
ray->start.y = py;
|
||||
ray->dir.x = vx;
|
||||
ray->dir.y = vy;
|
||||
}
|
||||
|
||||
kmBool kmRay2IntersectLineSegment(const kmRay2* ray, const kmVec2* p1, const kmVec2* p2, kmVec2* intersection) {
|
||||
|
||||
kmScalar x1 = ray->start.x;
|
||||
kmScalar y1 = ray->start.y;
|
||||
kmScalar x2 = ray->start.x + ray->dir.x;
|
||||
kmScalar y2 = ray->start.y + ray->dir.y;
|
||||
kmScalar x3 = p1->x;
|
||||
kmScalar y3 = p1->y;
|
||||
kmScalar x4 = p2->x;
|
||||
kmScalar y4 = p2->y;
|
||||
|
||||
kmScalar denom = (y4 -y3) * (x2 - x1) - (x4 - x3) * (y2 - y1);
|
||||
|
||||
//If denom is zero, the lines are parallel
|
||||
if(denom > -kmEpsilon && denom < kmEpsilon) {
|
||||
return KM_FALSE;
|
||||
}
|
||||
|
||||
kmScalar ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / denom;
|
||||
kmScalar ub = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / denom;
|
||||
|
||||
kmScalar x = x1 + ua * (x2 - x1);
|
||||
kmScalar y = y1 + ua * (y2 - y1);
|
||||
|
||||
if((0.0 <= ua) && (ua <= 1.0) && (0.0 <= ub) && (ub <= 1.0)) {
|
||||
intersection->x = x;
|
||||
intersection->y = y;
|
||||
|
||||
return KM_TRUE;
|
||||
}
|
||||
|
||||
return KM_FALSE;
|
||||
}
|
||||
|
||||
void calculate_line_normal(kmVec2 p1, kmVec2 p2, kmVec2 other_point, kmVec2* normal_out) {
|
||||
/*
|
||||
A = (3,4)
|
||||
B = (2,1)
|
||||
C = (1,3)
|
||||
|
||||
AB = (2,1) - (3,4) = (-1,-3)
|
||||
AC = (1,3) - (3,4) = (-2,-1)
|
||||
N = n(AB) = (-3,1)
|
||||
D = dot(N,AC) = 6 + -1 = 5
|
||||
|
||||
since D > 0:
|
||||
N = -N = (3,-1)
|
||||
*/
|
||||
|
||||
kmVec2 edge, other_edge;
|
||||
kmVec2Subtract(&edge, &p2, &p1);
|
||||
kmVec2Subtract(&other_edge, &other_point, &p1);
|
||||
kmVec2Normalize(&edge, &edge);
|
||||
kmVec2Normalize(&other_edge, &other_edge);
|
||||
|
||||
kmVec2 n;
|
||||
n.x = edge.y;
|
||||
n.y = -edge.x;
|
||||
|
||||
kmScalar d = kmVec2Dot(&n, &other_edge);
|
||||
if(d > 0.0f) {
|
||||
n.x = -n.x;
|
||||
n.y = -n.y;
|
||||
}
|
||||
|
||||
normal_out->x = n.x;
|
||||
normal_out->y = n.y;
|
||||
kmVec2Normalize(normal_out, normal_out);
|
||||
}
|
||||
|
||||
kmBool kmRay2IntersectTriangle(const kmRay2* ray, const kmVec2* p1, const kmVec2* p2, const kmVec2* p3, kmVec2* intersection, kmVec2* normal_out, kmScalar* distance_out) {
|
||||
kmVec2 intersect;
|
||||
kmVec2 final_intersect;
|
||||
kmVec2 normal;
|
||||
kmScalar distance = 10000.0f;
|
||||
kmBool intersected = KM_FALSE;
|
||||
|
||||
if(kmRay2IntersectLineSegment(ray, p1, p2, &intersect)) {
|
||||
kmVec2 tmp;
|
||||
kmScalar this_distance = kmVec2Length(kmVec2Subtract(&tmp, &intersect, &ray->start));
|
||||
kmVec2 this_normal;
|
||||
calculate_line_normal(*p1, *p2, *p3, &this_normal);
|
||||
if(this_distance < distance && kmVec2Dot(&this_normal, &ray->dir) < 0.0f) {
|
||||
final_intersect.x = intersect.x;
|
||||
final_intersect.y = intersect.y;
|
||||
distance = this_distance;
|
||||
kmVec2Assign(&normal, &this_normal);
|
||||
intersected = KM_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if(kmRay2IntersectLineSegment(ray, p2, p3, &intersect)) {
|
||||
kmVec2 tmp;
|
||||
kmScalar this_distance = kmVec2Length(kmVec2Subtract(&tmp, &intersect, &ray->start));
|
||||
|
||||
kmVec2 this_normal;
|
||||
calculate_line_normal(*p2, *p3, *p1, &this_normal);
|
||||
|
||||
if(this_distance < distance && kmVec2Dot(&this_normal, &ray->dir) < 0.0f) {
|
||||
final_intersect.x = intersect.x;
|
||||
final_intersect.y = intersect.y;
|
||||
distance = this_distance;
|
||||
kmVec2Assign(&normal, &this_normal);
|
||||
intersected = KM_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if(kmRay2IntersectLineSegment(ray, p3, p1, &intersect)) {
|
||||
|
||||
kmVec2 tmp;
|
||||
kmScalar this_distance = kmVec2Length(kmVec2Subtract(&tmp, &intersect, &ray->start));
|
||||
|
||||
kmVec2 this_normal;
|
||||
calculate_line_normal(*p3, *p1, *p2, &this_normal);
|
||||
if(this_distance < distance && kmVec2Dot(&this_normal, &ray->dir) < 0.0f) {
|
||||
final_intersect.x = intersect.x;
|
||||
final_intersect.y = intersect.y;
|
||||
distance = this_distance;
|
||||
kmVec2Assign(&normal, &this_normal);
|
||||
intersected = KM_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if(intersected) {
|
||||
intersection->x = final_intersect.x;
|
||||
intersection->y = final_intersect.y;
|
||||
if(normal_out) {
|
||||
normal_out->x = normal.x;
|
||||
normal_out->y = normal.y;
|
||||
}
|
||||
if(distance) {
|
||||
*distance_out = distance;
|
||||
}
|
||||
}
|
||||
|
||||
return intersected;
|
||||
}
|
||||
|
||||
kmBool kmRay2IntersectBox(const kmRay2* ray, const kmVec2* p1, const kmVec2* p2, const kmVec2* p3, const kmVec2* p4,
|
||||
kmVec2* intersection, kmVec2* normal_out) {
|
||||
kmBool intersected = KM_FALSE;
|
||||
kmVec2 intersect, final_intersect, normal;
|
||||
kmScalar distance = 10000.0f;
|
||||
|
||||
const kmVec2* points[4];
|
||||
points[0] = p1;
|
||||
points[1] = p2;
|
||||
points[2] = p3;
|
||||
points[3] = p4;
|
||||
|
||||
unsigned int i = 0;
|
||||
for(; i < 4; ++i) {
|
||||
const kmVec2* this_point = points[i];
|
||||
const kmVec2* next_point = (i == 3) ? points[0] : points[i+1];
|
||||
const kmVec2* other_point = (i == 3 || i == 0) ? points[1] : points[0];
|
||||
|
||||
if(kmRay2IntersectLineSegment(ray, this_point, next_point, &intersect)) {
|
||||
|
||||
kmVec2 tmp;
|
||||
kmScalar this_distance = kmVec2Length(kmVec2Subtract(&tmp, &intersect, &ray->start));
|
||||
|
||||
kmVec2 this_normal;
|
||||
|
||||
calculate_line_normal(*this_point, *next_point, *other_point, &this_normal);
|
||||
if(this_distance < distance && kmVec2Dot(&this_normal, &ray->dir) < 0.0f) {
|
||||
kmVec2Assign(&final_intersect, &intersect);
|
||||
distance = this_distance;
|
||||
intersected = KM_TRUE;
|
||||
kmVec2Assign(&normal, &this_normal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(intersected) {
|
||||
intersection->x = final_intersect.x;
|
||||
intersection->y = final_intersect.y;
|
||||
if(normal_out) {
|
||||
normal_out->x = normal.x;
|
||||
normal_out->y = normal.y;
|
||||
}
|
||||
}
|
||||
|
||||
return intersected;
|
||||
}
|
||||
|
||||
kmBool kmRay2IntersectCircle(const kmRay2* ray, const kmVec2 centre, const kmScalar radius, kmVec2* intersection) {
|
||||
assert(0 && "Not implemented");
|
||||
return KM_TRUE;
|
||||
}
|
|
@ -26,7 +26,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#ifndef RAY_2_H
|
||||
#define RAY_2_H
|
||||
|
||||
#include "CCPlatformMacros.h"
|
||||
#include "utility.h"
|
||||
#include "vec2.h"
|
||||
|
||||
|
@ -39,10 +38,14 @@ typedef struct kmRay2 {
|
|||
kmVec2 dir;
|
||||
} kmRay2;
|
||||
|
||||
CC_DLL void kmRay2Fill(kmRay2* ray, kmScalar px, kmScalar py, kmScalar vx, kmScalar vy);
|
||||
CC_DLL kmBool kmRay2IntersectLineSegment(const kmRay2* ray, const kmVec2* p1, const kmVec2* p2, kmVec2* intersection);
|
||||
CC_DLL kmBool kmRay2IntersectTriangle(const kmRay2* ray, const kmVec2* p1, const kmVec2* p2, const kmVec2* p3, kmVec2* intersection, kmVec2* normal_out);
|
||||
CC_DLL kmBool kmRay2IntersectCircle(const kmRay2* ray, const kmVec2 centre, const kmScalar radius, kmVec2* intersection);
|
||||
void kmRay2Fill(kmRay2* ray, kmScalar px, kmScalar py, kmScalar vx, kmScalar vy);
|
||||
kmBool kmRay2IntersectLineSegment(const kmRay2* ray, const kmVec2* p1, const kmVec2* p2, kmVec2* intersection);
|
||||
kmBool kmRay2IntersectTriangle(const kmRay2* ray, const kmVec2* p1, const kmVec2* p2, const kmVec2* p3, kmVec2* intersection, kmVec2* normal_out, kmScalar* distance);
|
||||
|
||||
kmBool kmRay2IntersectBox(const kmRay2* ray, const kmVec2* p1, const kmVec2* p2, const kmVec2* p3, const kmVec2* p4,
|
||||
kmVec2* intersection, kmVec2* normal_out);
|
||||
|
||||
kmBool kmRay2IntersectCircle(const kmRay2* ray, const kmVec2 centre, const kmScalar radius, kmVec2* intersection);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
#include "plane.h"
|
||||
#include "ray3.h"
|
||||
|
||||
kmRay3* kmRay3Fill(kmRay3* ray, kmScalar px, kmScalar py, kmScalar pz, kmScalar vx, kmScalar vy, kmScalar vz) {
|
||||
ray->start.x = px;
|
||||
ray->start.y = py;
|
||||
ray->start.z = pz;
|
||||
|
||||
ray->dir.x = vx;
|
||||
ray->dir.y = vy;
|
||||
ray->dir.z = vz;
|
||||
|
||||
return ray;
|
||||
}
|
||||
|
||||
kmRay3* kmRay3FromPointAndDirection(kmRay3* ray, const kmVec3* point, const kmVec3* direction) {
|
||||
kmVec3Assign(&ray->start, point);
|
||||
kmVec3Assign(&ray->dir, direction);
|
||||
return ray;
|
||||
}
|
||||
|
||||
kmBool kmRay3IntersectPlane(kmVec3* pOut, const kmRay3* ray, const kmPlane* plane) {
|
||||
//t = - (A*org.x + B*org.y + C*org.z + D) / (A*dir.x + B*dir.y + C*dir.z )
|
||||
|
||||
kmScalar d = (plane->a * ray->dir.x +
|
||||
plane->b * ray->dir.y +
|
||||
plane->c * ray->dir.z);
|
||||
|
||||
if(d == 0)
|
||||
{
|
||||
return KM_FALSE;
|
||||
}
|
||||
|
||||
kmScalar t = -(plane->a * ray->start.x +
|
||||
plane->b * ray->start.y +
|
||||
plane->c * ray->start.z + plane->d) / d;
|
||||
|
||||
if(t < 0)
|
||||
{
|
||||
return KM_FALSE;
|
||||
}
|
||||
|
||||
kmVec3 scaled_dir;
|
||||
kmVec3Scale(&scaled_dir, &ray->dir, t);
|
||||
kmVec3Add(pOut, &ray->start, &scaled_dir);
|
||||
return KM_TRUE;
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef RAY3_H
|
||||
#define RAY3_H
|
||||
|
||||
#include "utility.h"
|
||||
#include "vec3.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct kmRay3 {
|
||||
kmVec3 start;
|
||||
kmVec3 dir;
|
||||
} kmRay3;
|
||||
|
||||
struct kmPlane;
|
||||
|
||||
kmRay3* kmRay3Fill(kmRay3* ray, kmScalar px, kmScalar py, kmScalar pz, kmScalar vx, kmScalar vy, kmScalar vz);
|
||||
kmRay3* kmRay3FromPointAndDirection(kmRay3* ray, const kmVec3* point, const kmVec3* direction);
|
||||
kmBool kmRay3IntersectPlane(kmVec3* pOut, const kmRay3* ray, const struct kmPlane* plane);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // RAY3_H
|
|
@ -23,27 +23,27 @@ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "kazmath/utility.h"
|
||||
#include "utility.h"
|
||||
|
||||
/**
|
||||
* Returns the square of s (e.g. s*s)
|
||||
*/
|
||||
kmScalar kmSQR(kmScalar s) {
|
||||
return s*s;
|
||||
return s*s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns degrees as radians.
|
||||
*/
|
||||
kmScalar kmDegreesToRadians(kmScalar degrees) {
|
||||
return degrees * kmPIOver180;
|
||||
return degrees * kmPIOver180;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns radians as degrees
|
||||
*/
|
||||
kmScalar kmRadiansToDegrees(kmScalar radians) {
|
||||
return radians * kmPIUnder180;
|
||||
return radians * kmPIUnder180;
|
||||
}
|
||||
|
||||
kmScalar kmMin(kmScalar lhs, kmScalar rhs) {
|
||||
|
@ -57,3 +57,13 @@ kmScalar kmMax(kmScalar lhs, kmScalar rhs) {
|
|||
kmBool kmAlmostEqual(kmScalar lhs, kmScalar rhs) {
|
||||
return (lhs + kmEpsilon > rhs && lhs - kmEpsilon < rhs);
|
||||
}
|
||||
|
||||
kmScalar kmClamp(kmScalar x, kmScalar min, kmScalar max)
|
||||
{
|
||||
return x < min ? min : (x > max ? max : x);
|
||||
}
|
||||
|
||||
kmScalar kmLerp(kmScalar x, kmScalar y, kmScalar t )
|
||||
{
|
||||
return x + t * ( y - x );
|
||||
}
|
|
@ -26,21 +26,37 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#ifndef UTILITY_H_INCLUDED
|
||||
#define UTILITY_H_INCLUDED
|
||||
|
||||
#include "CCPlatformMacros.h"
|
||||
#include <math.h>
|
||||
|
||||
#ifndef kmScalar
|
||||
#ifdef USE_DOUBLE_PRECISION
|
||||
#define kmScalar double
|
||||
#else
|
||||
#define kmScalar float
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef kmBool
|
||||
#define kmBool unsigned char
|
||||
#endif
|
||||
|
||||
#ifndef kmUchar
|
||||
#define kmUchar unsigned char
|
||||
#endif
|
||||
|
||||
#ifndef kmEnum
|
||||
#define kmEnum unsigned int
|
||||
#endif
|
||||
|
||||
#ifndef kmUint
|
||||
#define kmUint unsigned int
|
||||
#endif
|
||||
|
||||
#ifndef kmInt
|
||||
#define kmInt int
|
||||
#endif
|
||||
|
||||
#ifndef KM_FALSE
|
||||
#define KM_FALSE 0
|
||||
#endif
|
||||
|
@ -49,24 +65,29 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#define KM_TRUE 1
|
||||
#endif
|
||||
|
||||
#define kmPI 3.141592f
|
||||
#define kmPIOver180 0.017453f // PI / 180
|
||||
#define kmPIUnder180 57.295779f // 180 / PI
|
||||
#define kmEpsilon 1.0 / 64.0
|
||||
|
||||
#define kmPI 3.14159265358979323846f
|
||||
#define kmPIOver180 (kmPI / 180.0f)
|
||||
#define kmPIUnder180 (180.0 / kmPI)
|
||||
#define kmEpsilon 0.0001
|
||||
|
||||
#define KM_CONTAINS_NONE 0
|
||||
#define KM_CONTAINS_PARTIAL 1
|
||||
#define KM_CONTAINS_ALL 2
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
CC_DLL kmScalar kmSQR(kmScalar s);
|
||||
CC_DLL kmScalar kmDegreesToRadians(kmScalar degrees);
|
||||
CC_DLL kmScalar kmRadiansToDegrees(kmScalar radians);
|
||||
extern kmScalar kmSQR(kmScalar s);
|
||||
extern kmScalar kmDegreesToRadians(kmScalar degrees);
|
||||
extern kmScalar kmRadiansToDegrees(kmScalar radians);
|
||||
|
||||
CC_DLL kmScalar kmMin(kmScalar lhs, kmScalar rhs);
|
||||
CC_DLL kmScalar kmMax(kmScalar lhs, kmScalar rhs);
|
||||
CC_DLL kmBool kmAlmostEqual(kmScalar lhs, kmScalar rhs);
|
||||
extern kmScalar kmMin(kmScalar lhs, kmScalar rhs);
|
||||
extern kmScalar kmMax(kmScalar lhs, kmScalar rhs);
|
||||
extern kmBool kmAlmostEqual(kmScalar lhs, kmScalar rhs);
|
||||
|
||||
extern kmScalar kmClamp(kmScalar x, kmScalar min, kmScalar max);
|
||||
extern kmScalar kmLerp(kmScalar x, kmScalar y, kmScalar factor);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
|
@ -0,0 +1,239 @@
|
|||
/*
|
||||
Copyright (c) 2008, Luke Benstead.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "mat3.h"
|
||||
#include "vec2.h"
|
||||
#include "utility.h"
|
||||
|
||||
const kmVec2 KM_VEC2_POS_Y = { 0, 1 };
|
||||
const kmVec2 KM_VEC2_NEG_Y = { 0, -1 };
|
||||
const kmVec2 KM_VEC2_NEG_X = { -1, 0 };
|
||||
const kmVec2 KM_VEC2_POS_X = { 1, 0 };
|
||||
const kmVec2 KM_VEC2_ZERO = { 0, 0 };
|
||||
|
||||
kmVec2* kmVec2Fill(kmVec2* pOut, kmScalar x, kmScalar y)
|
||||
{
|
||||
pOut->x = x;
|
||||
pOut->y = y;
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmScalar kmVec2Length(const kmVec2* pIn)
|
||||
{
|
||||
return sqrtf(kmSQR(pIn->x) + kmSQR(pIn->y));
|
||||
}
|
||||
|
||||
kmScalar kmVec2LengthSq(const kmVec2* pIn)
|
||||
{
|
||||
return kmSQR(pIn->x) + kmSQR(pIn->y);
|
||||
}
|
||||
|
||||
kmVec2* kmVec2Lerp(kmVec2* pOut, const kmVec2* pV1, const kmVec2* pV2, kmScalar t) {
|
||||
pOut->x = pV1->x + t * ( pV2->x - pV1->x );
|
||||
pOut->y = pV1->y + t * ( pV2->y - pV1->y );
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec2* kmVec2Normalize(kmVec2* pOut, const kmVec2* pIn)
|
||||
{
|
||||
if (!pIn->x && !pIn->y)
|
||||
return kmVec2Assign(pOut, pIn);
|
||||
|
||||
kmScalar l = 1.0f / kmVec2Length(pIn);
|
||||
|
||||
kmVec2 v;
|
||||
v.x = pIn->x * l;
|
||||
v.y = pIn->y * l;
|
||||
|
||||
pOut->x = v.x;
|
||||
pOut->y = v.y;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec2* kmVec2Add(kmVec2* pOut, const kmVec2* pV1, const kmVec2* pV2)
|
||||
{
|
||||
pOut->x = pV1->x + pV2->x;
|
||||
pOut->y = pV1->y + pV2->y;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmScalar kmVec2Dot(const kmVec2* pV1, const kmVec2* pV2)
|
||||
{
|
||||
return pV1->x * pV2->x + pV1->y * pV2->y;
|
||||
}
|
||||
|
||||
kmScalar kmVec2Cross(const kmVec2* pV1, const kmVec2* pV2)
|
||||
{
|
||||
return pV1->x * pV2->y - pV1->y * pV2->x;
|
||||
}
|
||||
|
||||
kmVec2* kmVec2Subtract(kmVec2* pOut, const kmVec2* pV1, const kmVec2* pV2)
|
||||
{
|
||||
pOut->x = pV1->x - pV2->x;
|
||||
pOut->y = pV1->y - pV2->y;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec2* kmVec2Mul( kmVec2* pOut,const kmVec2* pV1, const kmVec2* pV2 ) {
|
||||
pOut->x = pV1->x * pV2->x;
|
||||
pOut->y = pV1->y * pV2->y;
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec2* kmVec2Div( kmVec2* pOut,const kmVec2* pV1, const kmVec2* pV2 ) {
|
||||
if ( pV2->x && pV2->y ){
|
||||
pOut->x = pV1->x / pV2->x;
|
||||
pOut->y = pV1->y / pV2->y;
|
||||
}
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec2* kmVec2Transform(kmVec2* pOut, const kmVec2* pV, const kmMat3* pM)
|
||||
{
|
||||
kmVec2 v;
|
||||
|
||||
v.x = pV->x * pM->mat[0] + pV->y * pM->mat[3] + pM->mat[6];
|
||||
v.y = pV->x * pM->mat[1] + pV->y * pM->mat[4] + pM->mat[7];
|
||||
|
||||
pOut->x = v.x;
|
||||
pOut->y = v.y;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec2* kmVec2TransformCoord(kmVec2* pOut, const kmVec2* pV, const kmMat3* pM)
|
||||
{
|
||||
assert(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
kmVec2* kmVec2Scale(kmVec2* pOut, const kmVec2* pIn, const kmScalar s)
|
||||
{
|
||||
pOut->x = pIn->x * s;
|
||||
pOut->y = pIn->y * s;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
int kmVec2AreEqual(const kmVec2* p1, const kmVec2* p2)
|
||||
{
|
||||
return (
|
||||
(p1->x < p2->x + kmEpsilon && p1->x > p2->x - kmEpsilon) &&
|
||||
(p1->y < p2->y + kmEpsilon && p1->y > p2->y - kmEpsilon)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns pIn to pOut. Returns pOut. If pIn and pOut are the same
|
||||
* then nothing happens but pOut is still returned
|
||||
*/
|
||||
kmVec2* kmVec2Assign(kmVec2* pOut, const kmVec2* pIn) {
|
||||
if (pOut == pIn) {
|
||||
return pOut;
|
||||
}
|
||||
|
||||
pOut->x = pIn->x;
|
||||
pOut->y = pIn->y;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotates the point anticlockwise around a center
|
||||
* by an amount of degrees.
|
||||
*
|
||||
* Code ported from Irrlicht: http://irrlicht.sourceforge.net/
|
||||
*/
|
||||
kmVec2* kmVec2RotateBy(kmVec2* pOut, const kmVec2* pIn,
|
||||
const kmScalar degrees, const kmVec2* center)
|
||||
{
|
||||
kmScalar x, y;
|
||||
const kmScalar radians = kmDegreesToRadians(degrees);
|
||||
const kmScalar cs = cosf(radians), sn = sinf(radians);
|
||||
|
||||
pOut->x = pIn->x - center->x;
|
||||
pOut->y = pIn->y - center->y;
|
||||
|
||||
x = pOut->x * cs - pOut->y * sn;
|
||||
y = pOut->x * sn + pOut->y * cs;
|
||||
|
||||
pOut->x = x + center->x;
|
||||
pOut->y = y + center->y;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the angle in degrees between the two vectors
|
||||
*/
|
||||
kmScalar kmVec2DegreesBetween(const kmVec2* v1, const kmVec2* v2) {
|
||||
if(kmVec2AreEqual(v1, v2)) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
kmVec2 t1, t2;
|
||||
kmVec2Normalize(&t1, v1);
|
||||
kmVec2Normalize(&t2, v2);
|
||||
|
||||
kmScalar cross = kmVec2Cross(&t1, &t2);
|
||||
kmScalar dot = kmVec2Dot(&t1, &t2);
|
||||
|
||||
/*
|
||||
* acos is only defined for -1 to 1. Outside the range we
|
||||
* get NaN even if that's just because of a floating point error
|
||||
* so we clamp to the -1 - 1 range
|
||||
*/
|
||||
|
||||
if(dot > 1.0) dot = 1.0;
|
||||
if(dot < -1.0) dot = -1.0;
|
||||
|
||||
return kmRadiansToDegrees(atan2(cross, dot));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the distance between the two points
|
||||
*/
|
||||
kmScalar kmVec2DistanceBetween(const kmVec2* v1, const kmVec2* v2) {
|
||||
kmVec2 diff;
|
||||
kmVec2Subtract(&diff, v2, v1);
|
||||
return fabs(kmVec2Length(&diff));
|
||||
}
|
||||
/**
|
||||
* Returns the point mid-way between two others
|
||||
*/
|
||||
kmVec2* kmVec2MidPointBetween(kmVec2* pOut, const kmVec2* v1, const kmVec2* v2) {
|
||||
kmVec2 sum;
|
||||
kmVec2Add(&sum, v1, v2);
|
||||
pOut->x = sum.x / 2.0f;
|
||||
pOut->y = sum.y / 2.0f;
|
||||
|
||||
return pOut;
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
Copyright (c) 2008, Luke Benstead.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef VEC2_H_INCLUDED
|
||||
#define VEC2_H_INCLUDED
|
||||
|
||||
#include "utility.h"
|
||||
|
||||
struct kmMat3;
|
||||
|
||||
#pragma pack(push) /* push current alignment to stack */
|
||||
#pragma pack(1) /* set alignment to 1 byte boundary */
|
||||
typedef struct kmVec2 {
|
||||
kmScalar x;
|
||||
kmScalar y;
|
||||
} kmVec2;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
kmVec2* kmVec2Fill(kmVec2* pOut, kmScalar x, kmScalar y);
|
||||
kmScalar kmVec2Length(const kmVec2* pIn); ///< Returns the length of the vector
|
||||
kmScalar kmVec2LengthSq(const kmVec2* pIn); ///< Returns the square of the length of the vector
|
||||
kmVec2* kmVec2Normalize(kmVec2* pOut, const kmVec2* pIn); ///< Returns the vector passed in set to unit length
|
||||
kmVec2* kmVec2Lerp(kmVec2* pOut, const kmVec2* pV1, const kmVec2* pV2, kmScalar t);
|
||||
kmVec2* kmVec2Add(kmVec2* pOut, const kmVec2* pV1, const kmVec2* pV2); ///< Adds 2 vectors and returns the result
|
||||
kmScalar kmVec2Dot(const kmVec2* pV1, const kmVec2* pV2); /** Returns the Dot product which is the cosine of the angle between the two vectors multiplied by their lengths */
|
||||
kmScalar kmVec2Cross(const kmVec2* pV1, const kmVec2* pV2);
|
||||
kmVec2* kmVec2Subtract(kmVec2* pOut, const kmVec2* pV1, const kmVec2* pV2); ///< Subtracts 2 vectors and returns the result
|
||||
kmVec2* kmVec2Mul( kmVec2* pOut,const kmVec2* pV1, const kmVec2* pV2 ); ///< Component-wise multiplication
|
||||
kmVec2* kmVec2Div( kmVec2* pOut,const kmVec2* pV1, const kmVec2* pV2 ); ///< Component-wise division
|
||||
kmVec2* kmVec2Transform(kmVec2* pOut, const kmVec2* pV1, const struct kmMat3* pM); /** Transform the Vector */
|
||||
kmVec2* kmVec2TransformCoord(kmVec2* pOut, const kmVec2* pV, const struct kmMat3* pM); ///<Transforms a 2D vector by a given matrix, projecting the result back into w = 1.
|
||||
kmVec2* kmVec2Scale(kmVec2* pOut, const kmVec2* pIn, const kmScalar s); ///< Scales a vector to length s
|
||||
int kmVec2AreEqual(const kmVec2* p1, const kmVec2* p2); ///< Returns 1 if both vectors are equal
|
||||
kmVec2* kmVec2Assign(kmVec2* pOut, const kmVec2* pIn);
|
||||
kmVec2* kmVec2RotateBy(kmVec2* pOut, const kmVec2* pIn, const kmScalar degrees, const kmVec2* center); ///<Rotates the point anticlockwise around a center by an amount of degrees.
|
||||
kmScalar kmVec2DegreesBetween(const kmVec2* v1, const kmVec2* v2);
|
||||
kmScalar kmVec2DistanceBetween(const kmVec2* v1, const kmVec2* v2);
|
||||
kmVec2* kmVec2MidPointBetween(kmVec2* pOut, const kmVec2* v1, const kmVec2* v2);
|
||||
|
||||
extern const kmVec2 KM_VEC2_POS_Y;
|
||||
extern const kmVec2 KM_VEC2_NEG_Y;
|
||||
extern const kmVec2 KM_VEC2_NEG_X;
|
||||
extern const kmVec2 KM_VEC2_POS_X;
|
||||
extern const kmVec2 KM_VEC2_ZERO;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif // VEC2_H_INCLUDED
|
|
@ -0,0 +1,444 @@
|
|||
/*
|
||||
Copyright (c) 2008, Luke Benstead.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file vec3.c
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <memory.h>
|
||||
|
||||
#include "utility.h"
|
||||
#include "vec4.h"
|
||||
#include "mat4.h"
|
||||
#include "mat3.h"
|
||||
#include "vec3.h"
|
||||
#include "plane.h"
|
||||
#include "ray3.h"
|
||||
|
||||
const kmVec3 KM_VEC3_POS_Z = { 0, 0, 1 };
|
||||
const kmVec3 KM_VEC3_NEG_Z = { 0, 0, -1 };
|
||||
const kmVec3 KM_VEC3_POS_Y = { 0, 1, 0 };
|
||||
const kmVec3 KM_VEC3_NEG_Y = { 0, -1, 0 };
|
||||
const kmVec3 KM_VEC3_NEG_X = { -1, 0, 0 };
|
||||
const kmVec3 KM_VEC3_POS_X = { 1, 0, 0 };
|
||||
const kmVec3 KM_VEC3_ZERO = { 0, 0, 0 };
|
||||
|
||||
/**
|
||||
* Fill a kmVec3 structure using 3 floating point values
|
||||
* The result is store in pOut, returns pOut
|
||||
*/
|
||||
kmVec3* kmVec3Fill(kmVec3* pOut, kmScalar x, kmScalar y, kmScalar z)
|
||||
{
|
||||
pOut->x = x;
|
||||
pOut->y = y;
|
||||
pOut->z = z;
|
||||
return pOut;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the length of the vector
|
||||
*/
|
||||
kmScalar kmVec3Length(const kmVec3* pIn)
|
||||
{
|
||||
return sqrtf(kmSQR(pIn->x) + kmSQR(pIn->y) + kmSQR(pIn->z));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the square of the length of the vector
|
||||
*/
|
||||
kmScalar kmVec3LengthSq(const kmVec3* pIn)
|
||||
{
|
||||
return kmSQR(pIn->x) + kmSQR(pIn->y) + kmSQR(pIn->z);
|
||||
}
|
||||
|
||||
/// Returns the interpolation of 2 4D vectors based on t.
|
||||
kmVec3* kmVec3Lerp(kmVec3* pOut, const kmVec3* pV1, const kmVec3* pV2, kmScalar t) {
|
||||
pOut->x = pV1->x + t * ( pV2->x - pV1->x );
|
||||
pOut->y = pV1->y + t * ( pV2->y - pV1->y );
|
||||
pOut->z = pV1->z + t * ( pV2->z - pV1->z );
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the vector passed in set to unit length
|
||||
* the result is stored in pOut.
|
||||
*/
|
||||
kmVec3* kmVec3Normalize(kmVec3* pOut, const kmVec3* pIn)
|
||||
{
|
||||
if (!pIn->x && !pIn->y && !pIn->z)
|
||||
return kmVec3Assign(pOut, pIn);
|
||||
|
||||
kmScalar l = 1.0f / kmVec3Length(pIn);
|
||||
|
||||
kmVec3 v;
|
||||
v.x = pIn->x * l;
|
||||
v.y = pIn->y * l;
|
||||
v.z = pIn->z * l;
|
||||
|
||||
pOut->x = v.x;
|
||||
pOut->y = v.y;
|
||||
pOut->z = v.z;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a vector perpendicular to 2 other vectors.
|
||||
* The result is stored in pOut.
|
||||
*/
|
||||
kmVec3* kmVec3Cross(kmVec3* pOut, const kmVec3* pV1, const kmVec3* pV2)
|
||||
{
|
||||
|
||||
kmVec3 v;
|
||||
|
||||
v.x = (pV1->y * pV2->z) - (pV1->z * pV2->y);
|
||||
v.y = (pV1->z * pV2->x) - (pV1->x * pV2->z);
|
||||
v.z = (pV1->x * pV2->y) - (pV1->y * pV2->x);
|
||||
|
||||
pOut->x = v.x;
|
||||
pOut->y = v.y;
|
||||
pOut->z = v.z;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the cosine of the angle between 2 vectors
|
||||
*/
|
||||
kmScalar kmVec3Dot(const kmVec3* pV1, const kmVec3* pV2)
|
||||
{
|
||||
return ( pV1->x * pV2->x
|
||||
+ pV1->y * pV2->y
|
||||
+ pV1->z * pV2->z );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds 2 vectors and returns the result. The resulting
|
||||
* vector is stored in pOut.
|
||||
*/
|
||||
kmVec3* kmVec3Add(kmVec3* pOut, const kmVec3* pV1, const kmVec3* pV2)
|
||||
{
|
||||
kmVec3 v;
|
||||
|
||||
v.x = pV1->x + pV2->x;
|
||||
v.y = pV1->y + pV2->y;
|
||||
v.z = pV1->z + pV2->z;
|
||||
|
||||
pOut->x = v.x;
|
||||
pOut->y = v.y;
|
||||
pOut->z = v.z;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtracts 2 vectors and returns the result. The result is stored in
|
||||
* pOut.
|
||||
*/
|
||||
kmVec3* kmVec3Subtract(kmVec3* pOut, const kmVec3* pV1, const kmVec3* pV2)
|
||||
{
|
||||
kmVec3 v;
|
||||
|
||||
v.x = pV1->x - pV2->x;
|
||||
v.y = pV1->y - pV2->y;
|
||||
v.z = pV1->z - pV2->z;
|
||||
|
||||
pOut->x = v.x;
|
||||
pOut->y = v.y;
|
||||
pOut->z = v.z;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec3* kmVec3Mul( kmVec3* pOut,const kmVec3* pV1, const kmVec3* pV2 ) {
|
||||
pOut->x = pV1->x * pV2->x;
|
||||
pOut->y = pV1->y * pV2->y;
|
||||
pOut->z = pV1->z * pV2->z;
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec3* kmVec3Div( kmVec3* pOut,const kmVec3* pV1, const kmVec3* pV2 ) {
|
||||
if ( pV2->x && pV2->y && pV2->z ){
|
||||
pOut->x = pV1->x / pV2->x;
|
||||
pOut->y = pV1->y / pV2->y;
|
||||
pOut->z = pV1->z / pV2->z;
|
||||
}
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec3* kmVec3MultiplyMat3(kmVec3* pOut, const kmVec3* pV, const kmMat3* pM) {
|
||||
kmVec3 v;
|
||||
|
||||
v.x = pV->x * pM->mat[0] + pV->y * pM->mat[3] + pV->z * pM->mat[6];
|
||||
v.y = pV->x * pM->mat[1] + pV->y * pM->mat[4] + pV->z * pM->mat[7];
|
||||
v.z = pV->x * pM->mat[2] + pV->y * pM->mat[5] + pV->z * pM->mat[8];
|
||||
|
||||
pOut->x = v.x;
|
||||
pOut->y = v.y;
|
||||
pOut->z = v.z;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies vector (x, y, z, 1) by a given matrix. The result
|
||||
* is stored in pOut. pOut is returned.
|
||||
*/
|
||||
|
||||
kmVec3* kmVec3MultiplyMat4(kmVec3* pOut, const kmVec3* pV, const kmMat4* pM) {
|
||||
kmVec3 v;
|
||||
|
||||
v.x = pV->x * pM->mat[0] + pV->y * pM->mat[4] + pV->z * pM->mat[8] + pM->mat[12];
|
||||
v.y = pV->x * pM->mat[1] + pV->y * pM->mat[5] + pV->z * pM->mat[9] + pM->mat[13];
|
||||
v.z = pV->x * pM->mat[2] + pV->y * pM->mat[6] + pV->z * pM->mat[10] + pM->mat[14];
|
||||
|
||||
pOut->x = v.x;
|
||||
pOut->y = v.y;
|
||||
pOut->z = v.z;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
|
||||
kmVec3* kmVec3Transform(kmVec3* pOut, const kmVec3* pV, const kmMat4* pM)
|
||||
{
|
||||
/*
|
||||
@deprecated Should intead use kmVec3MultiplyMat4
|
||||
*/
|
||||
return kmVec3MultiplyMat4(pOut, pV, pM);
|
||||
}
|
||||
|
||||
kmVec3* kmVec3InverseTransform(kmVec3* pOut, const kmVec3* pVect, const kmMat4* pM)
|
||||
{
|
||||
kmVec3 v1, v2;
|
||||
|
||||
v1.x = pVect->x - pM->mat[12];
|
||||
v1.y = pVect->y - pM->mat[13];
|
||||
v1.z = pVect->z - pM->mat[14];
|
||||
|
||||
v2.x = v1.x * pM->mat[0] + v1.y * pM->mat[1] + v1.z * pM->mat[2];
|
||||
v2.y = v1.x * pM->mat[4] + v1.y * pM->mat[5] + v1.z * pM->mat[6];
|
||||
v2.z = v1.x * pM->mat[8] + v1.y * pM->mat[9] + v1.z * pM->mat[10];
|
||||
|
||||
pOut->x = v2.x;
|
||||
pOut->y = v2.y;
|
||||
pOut->z = v2.z;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec3* kmVec3InverseTransformNormal(kmVec3* pOut, const kmVec3* pVect, const kmMat4* pM)
|
||||
{
|
||||
kmVec3 v;
|
||||
|
||||
v.x = pVect->x * pM->mat[0] + pVect->y * pM->mat[1] + pVect->z * pM->mat[2];
|
||||
v.y = pVect->x * pM->mat[4] + pVect->y * pM->mat[5] + pVect->z * pM->mat[6];
|
||||
v.z = pVect->x * pM->mat[8] + pVect->y * pM->mat[9] + pVect->z * pM->mat[10];
|
||||
|
||||
pOut->x = v.x;
|
||||
pOut->y = v.y;
|
||||
pOut->z = v.z;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
|
||||
kmVec3* kmVec3TransformCoord(kmVec3* pOut, const kmVec3* pV, const kmMat4* pM)
|
||||
{
|
||||
/*
|
||||
a = (Vx, Vy, Vz, 1)
|
||||
b = (a×M)T
|
||||
Out = 1⁄bw(bx, by, bz)
|
||||
*/
|
||||
|
||||
kmVec4 v;
|
||||
kmVec4 inV;
|
||||
kmVec4Fill(&inV, pV->x, pV->y, pV->z, 1.0);
|
||||
|
||||
kmVec4Transform(&v, &inV,pM);
|
||||
|
||||
pOut->x = v.x / v.w;
|
||||
pOut->y = v.y / v.w;
|
||||
pOut->z = v.z / v.w;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec3* kmVec3TransformNormal(kmVec3* pOut, const kmVec3* pV, const kmMat4* pM)
|
||||
{
|
||||
/*
|
||||
a = (Vx, Vy, Vz, 0)
|
||||
b = (a×M)T
|
||||
Out = (bx, by, bz)
|
||||
*/
|
||||
//Omits the translation, only scaling + rotating
|
||||
kmVec3 v;
|
||||
|
||||
v.x = pV->x * pM->mat[0] + pV->y * pM->mat[4] + pV->z * pM->mat[8];
|
||||
v.y = pV->x * pM->mat[1] + pV->y * pM->mat[5] + pV->z * pM->mat[9];
|
||||
v.z = pV->x * pM->mat[2] + pV->y * pM->mat[6] + pV->z * pM->mat[10];
|
||||
|
||||
pOut->x = v.x;
|
||||
pOut->y = v.y;
|
||||
pOut->z = v.z;
|
||||
|
||||
return pOut;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Scales a vector to length s. Does not normalize first,
|
||||
* you should do that!
|
||||
*/
|
||||
kmVec3* kmVec3Scale(kmVec3* pOut, const kmVec3* pIn, const kmScalar s)
|
||||
{
|
||||
pOut->x = pIn->x * s;
|
||||
pOut->y = pIn->y * s;
|
||||
pOut->z = pIn->z * s;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns KM_TRUE if the 2 vectors are approximately equal
|
||||
*/
|
||||
int kmVec3AreEqual(const kmVec3* p1, const kmVec3* p2)
|
||||
{
|
||||
if ((p1->x < (p2->x + kmEpsilon) && p1->x > (p2->x - kmEpsilon)) &&
|
||||
(p1->y < (p2->y + kmEpsilon) && p1->y > (p2->y - kmEpsilon)) &&
|
||||
(p1->z < (p2->z + kmEpsilon) && p1->z > (p2->z - kmEpsilon))) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns pIn to pOut. Returns pOut. If pIn and pOut are the same
|
||||
* then nothing happens but pOut is still returned
|
||||
*/
|
||||
kmVec3* kmVec3Assign(kmVec3* pOut, const kmVec3* pIn) {
|
||||
if (pOut == pIn) {
|
||||
return pOut;
|
||||
}
|
||||
|
||||
pOut->x = pIn->x;
|
||||
pOut->y = pIn->y;
|
||||
pOut->z = pIn->z;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets all the elements of pOut to zero. Returns pOut.
|
||||
*/
|
||||
kmVec3* kmVec3Zero(kmVec3* pOut) {
|
||||
pOut->x = 0.0f;
|
||||
pOut->y = 0.0f;
|
||||
pOut->z = 0.0f;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rotations that would make a (0,0,1) direction vector point in the same direction as this direction vector.
|
||||
* Useful for orienting vector towards a point.
|
||||
*
|
||||
* Returns a rotation vector containing the X (pitch) and Y (raw) rotations (in degrees) that when applied to a
|
||||
* +Z (e.g. 0, 0, 1) direction vector would make it point in the same direction as this vector. The Z (roll) rotation
|
||||
* is always 0, since two Euler rotations are sufficient to point in any given direction.
|
||||
*
|
||||
* Code ported from Irrlicht: http://irrlicht.sourceforge.net/
|
||||
*/
|
||||
kmVec3* kmVec3GetHorizontalAngle(kmVec3* pOut, const kmVec3 *pIn) {
|
||||
const kmScalar z1 = sqrt(pIn->x * pIn->x + pIn->z * pIn->z);
|
||||
|
||||
pOut->y = kmRadiansToDegrees(atan2(pIn->x, pIn->z));
|
||||
if (pOut->y < 0)
|
||||
pOut->y += 360;
|
||||
if (pOut->y >= 360)
|
||||
pOut->y -= 360;
|
||||
|
||||
pOut->x = kmRadiansToDegrees(atan2(z1, pIn->y)) - 90.0;
|
||||
if (pOut->x < 0)
|
||||
pOut->x += 360;
|
||||
if (pOut->x >= 360)
|
||||
pOut->x -= 360;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a direction vector from input vector.
|
||||
* Input vector is assumed to be rotation vector composed from 3 Euler angle rotations, in degrees.
|
||||
* The forwards vector will be rotated by the input vector
|
||||
*
|
||||
* Code ported from Irrlicht: http://irrlicht.sourceforge.net/
|
||||
*/
|
||||
kmVec3* kmVec3RotationToDirection(kmVec3* pOut, const kmVec3* pIn, const kmVec3* forwards)
|
||||
{
|
||||
const kmScalar xr = kmDegreesToRadians(pIn->x);
|
||||
const kmScalar yr = kmDegreesToRadians(pIn->y);
|
||||
const kmScalar zr = kmDegreesToRadians(pIn->z);
|
||||
const kmScalar cr = cos(xr), sr = sin(xr);
|
||||
const kmScalar cp = cos(yr), sp = sin(yr);
|
||||
const kmScalar cy = cos(zr), sy = sin(zr);
|
||||
|
||||
const kmScalar srsp = sr*sp;
|
||||
const kmScalar crsp = cr*sp;
|
||||
|
||||
const kmScalar pseudoMatrix[] = {
|
||||
(cp*cy), (cp*sy), (-sp),
|
||||
(srsp*cy-cr*sy), (srsp*sy+cr*cy), (sr*cp),
|
||||
(crsp*cy+sr*sy), (crsp*sy-sr*cy), (cr*cp)
|
||||
};
|
||||
|
||||
pOut->x = forwards->x * pseudoMatrix[0] +
|
||||
forwards->y * pseudoMatrix[3] +
|
||||
forwards->z * pseudoMatrix[6];
|
||||
|
||||
pOut->y = forwards->x * pseudoMatrix[1] +
|
||||
forwards->y * pseudoMatrix[4] +
|
||||
forwards->z * pseudoMatrix[7];
|
||||
|
||||
pOut->z = forwards->x * pseudoMatrix[2] +
|
||||
forwards->y * pseudoMatrix[5] +
|
||||
forwards->z * pseudoMatrix[8];
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec3* kmVec3ProjectOnToPlane(kmVec3* pOut, const kmVec3* point, const struct kmPlane* plane) {
|
||||
kmRay3 ray;
|
||||
kmVec3Assign(&ray.start, point);
|
||||
ray.dir.x = -plane->a;
|
||||
ray.dir.y = -plane->b;
|
||||
ray.dir.z = -plane->c;
|
||||
|
||||
kmRay3IntersectPlane(pOut, &ray, plane);
|
||||
return pOut;
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
Copyright (c) 2008, Luke Benstead.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef VEC3_H_INCLUDED
|
||||
#define VEC3_H_INCLUDED
|
||||
|
||||
#include <assert.h>
|
||||
#include "utility.h"
|
||||
|
||||
struct kmMat4;
|
||||
struct kmMat3;
|
||||
struct kmPlane;
|
||||
|
||||
typedef struct kmVec3 {
|
||||
kmScalar x;
|
||||
kmScalar y;
|
||||
kmScalar z;
|
||||
} kmVec3;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
kmVec3* kmVec3Fill(kmVec3* pOut, kmScalar x, kmScalar y, kmScalar z);
|
||||
kmScalar kmVec3Length(const kmVec3* pIn); /** Returns the length of the vector */
|
||||
kmScalar kmVec3LengthSq(const kmVec3* pIn); /** Returns the square of the length of the vector */
|
||||
kmVec3* kmVec3Lerp(kmVec3* pOut, const kmVec3* pV1, const kmVec3* pV2, kmScalar t);
|
||||
kmVec3* kmVec3Normalize(kmVec3* pOut, const kmVec3* pIn); /** Returns the vector passed in set to unit length */
|
||||
kmVec3* kmVec3Cross(kmVec3* pOut, const kmVec3* pV1, const kmVec3* pV2); /** Returns a vector perpendicular to 2 other vectors */
|
||||
kmScalar kmVec3Dot(const kmVec3* pV1, const kmVec3* pV2); /** Returns the cosine of the angle between 2 vectors */
|
||||
kmVec3* kmVec3Add(kmVec3* pOut, const kmVec3* pV1, const kmVec3* pV2); /** Adds 2 vectors and returns the result */
|
||||
kmVec3* kmVec3Subtract(kmVec3* pOut, const kmVec3* pV1, const kmVec3* pV2); /** Subtracts 2 vectors and returns the result */
|
||||
kmVec3* kmVec3Mul( kmVec3* pOut,const kmVec3* pV1, const kmVec3* pV2 );
|
||||
kmVec3* kmVec3Div( kmVec3* pOut,const kmVec3* pV1, const kmVec3* pV2 );
|
||||
|
||||
kmVec3* kmVec3MultiplyMat3(kmVec3 *pOut, const kmVec3 *pV, const struct kmMat3* pM);
|
||||
kmVec3* kmVec3MultiplyMat4(kmVec3* pOut, const kmVec3* pV, const struct kmMat4* pM);
|
||||
|
||||
kmVec3* kmVec3Transform(kmVec3* pOut, const kmVec3* pV1, const struct kmMat4* pM); /** Transforms a vector (assuming w=1) by a given matrix */
|
||||
kmVec3* kmVec3TransformNormal(kmVec3* pOut, const kmVec3* pV, const struct kmMat4* pM);/**Transforms a 3D normal by a given matrix */
|
||||
kmVec3* kmVec3TransformCoord(kmVec3* pOut, const kmVec3* pV, const struct kmMat4* pM); /**Transforms a 3D vector by a given matrix, projecting the result back into w = 1. */
|
||||
|
||||
kmVec3* kmVec3Scale(kmVec3* pOut, const kmVec3* pIn, const kmScalar s); /** Scales a vector to length s */
|
||||
int kmVec3AreEqual(const kmVec3* p1, const kmVec3* p2);
|
||||
kmVec3* kmVec3InverseTransform(kmVec3* pOut, const kmVec3* pV, const struct kmMat4* pM);
|
||||
kmVec3* kmVec3InverseTransformNormal(kmVec3* pOut, const kmVec3* pVect, const struct kmMat4* pM);
|
||||
kmVec3* kmVec3Assign(kmVec3* pOut, const kmVec3* pIn);
|
||||
kmVec3* kmVec3Zero(kmVec3* pOut);
|
||||
kmVec3* kmVec3GetHorizontalAngle(kmVec3* pOut, const kmVec3 *pIn); /** Get the rotations that would make a (0,0,1) direction vector point in the same direction as this direction vector. */
|
||||
kmVec3* kmVec3RotationToDirection(kmVec3* pOut, const kmVec3* pIn, const kmVec3* forwards); /** Builds a direction vector from input vector. */
|
||||
|
||||
kmVec3* kmVec3ProjectOnToPlane(kmVec3* pOut, const kmVec3* point, const struct kmPlane* plane);
|
||||
|
||||
extern const kmVec3 KM_VEC3_NEG_Z;
|
||||
extern const kmVec3 KM_VEC3_POS_Z;
|
||||
extern const kmVec3 KM_VEC3_POS_Y;
|
||||
extern const kmVec3 KM_VEC3_NEG_Y;
|
||||
extern const kmVec3 KM_VEC3_NEG_X;
|
||||
extern const kmVec3 KM_VEC3_POS_X;
|
||||
extern const kmVec3 KM_VEC3_ZERO;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* VEC3_H_INCLUDED */
|
|
@ -27,9 +27,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <memory.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "kazmath/utility.h"
|
||||
#include "kazmath/vec4.h"
|
||||
#include "kazmath/mat4.h"
|
||||
#include "utility.h"
|
||||
#include "vec4.h"
|
||||
#include "mat4.h"
|
||||
|
||||
|
||||
kmVec4* kmVec4Fill(kmVec4* pOut, kmScalar x, kmScalar y, kmScalar z, kmScalar w)
|
||||
|
@ -45,74 +45,98 @@ kmVec4* kmVec4Fill(kmVec4* pOut, kmScalar x, kmScalar y, kmScalar z, kmScalar w)
|
|||
/// Adds 2 4D vectors together. The result is store in pOut, the function returns
|
||||
/// pOut so that it can be nested in another function.
|
||||
kmVec4* kmVec4Add(kmVec4* pOut, const kmVec4* pV1, const kmVec4* pV2) {
|
||||
pOut->x = pV1->x + pV2->x;
|
||||
pOut->y = pV1->y + pV2->y;
|
||||
pOut->z = pV1->z + pV2->z;
|
||||
pOut->w = pV1->w + pV2->w;
|
||||
pOut->x = pV1->x + pV2->x;
|
||||
pOut->y = pV1->y + pV2->y;
|
||||
pOut->z = pV1->z + pV2->z;
|
||||
pOut->w = pV1->w + pV2->w;
|
||||
|
||||
return pOut;
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/// Returns the dot product of 2 4D vectors
|
||||
kmScalar kmVec4Dot(const kmVec4* pV1, const kmVec4* pV2) {
|
||||
return ( pV1->x * pV2->x
|
||||
+ pV1->y * pV2->y
|
||||
+ pV1->z * pV2->z
|
||||
+ pV1->w * pV2->w );
|
||||
return ( pV1->x * pV2->x
|
||||
+ pV1->y * pV2->y
|
||||
+ pV1->z * pV2->z
|
||||
+ pV1->w * pV2->w );
|
||||
}
|
||||
|
||||
/// Returns the length of a 4D vector, this uses a sqrt so if the squared length will do use
|
||||
/// kmVec4LengthSq
|
||||
kmScalar kmVec4Length(const kmVec4* pIn) {
|
||||
return sqrtf(kmSQR(pIn->x) + kmSQR(pIn->y) + kmSQR(pIn->z) + kmSQR(pIn->w));
|
||||
return sqrtf(kmSQR(pIn->x) + kmSQR(pIn->y) + kmSQR(pIn->z) + kmSQR(pIn->w));
|
||||
}
|
||||
|
||||
/// Returns the length of the 4D vector squared.
|
||||
kmScalar kmVec4LengthSq(const kmVec4* pIn) {
|
||||
return kmSQR(pIn->x) + kmSQR(pIn->y) + kmSQR(pIn->z) + kmSQR(pIn->w);
|
||||
return kmSQR(pIn->x) + kmSQR(pIn->y) + kmSQR(pIn->z) + kmSQR(pIn->w);
|
||||
}
|
||||
|
||||
/// Returns the interpolation of 2 4D vectors based on t. Currently not implemented!
|
||||
/// Returns the interpolation of 2 4D vectors based on t.
|
||||
kmVec4* kmVec4Lerp(kmVec4* pOut, const kmVec4* pV1, const kmVec4* pV2, kmScalar t) {
|
||||
assert(0);
|
||||
pOut->x = pV1->x + t * ( pV2->x - pV1->x );
|
||||
pOut->y = pV1->y + t * ( pV2->y - pV1->y );
|
||||
pOut->z = pV1->z + t * ( pV2->z - pV1->z );
|
||||
pOut->w = pV1->w + t * ( pV2->w - pV1->w );
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/// Normalizes a 4D vector. The result is stored in pOut. pOut is returned
|
||||
kmVec4* kmVec4Normalize(kmVec4* pOut, const kmVec4* pIn) {
|
||||
kmScalar l = 1.0f / kmVec4Length(pIn);
|
||||
if (!pIn->x && !pIn->y && !pIn->z && !pIn->w){
|
||||
return kmVec4Assign(pOut, pIn);
|
||||
}
|
||||
|
||||
pOut->x *= l;
|
||||
pOut->y *= l;
|
||||
pOut->z *= l;
|
||||
pOut->w *= l;
|
||||
kmScalar l = 1.0f / kmVec4Length(pIn);
|
||||
pOut->x = pIn->x * l;
|
||||
pOut->y = pIn->y * l;
|
||||
pOut->z = pIn->z * l;
|
||||
pOut->w = pIn->w * l;
|
||||
|
||||
return pOut;
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/// Scales a vector to the required length. This performs a Normalize before multiplying by S.
|
||||
kmVec4* kmVec4Scale(kmVec4* pOut, const kmVec4* pIn, const kmScalar s) {
|
||||
kmVec4Normalize(pOut, pIn);
|
||||
kmVec4Normalize(pOut, pIn);
|
||||
|
||||
pOut->x *= s;
|
||||
pOut->y *= s;
|
||||
pOut->z *= s;
|
||||
pOut->w *= s;
|
||||
return pOut;
|
||||
pOut->x *= s;
|
||||
pOut->y *= s;
|
||||
pOut->z *= s;
|
||||
pOut->w *= s;
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/// Subtracts one 4D pV2 from pV1. The result is stored in pOut. pOut is returned
|
||||
kmVec4* kmVec4Subtract(kmVec4* pOut, const kmVec4* pV1, const kmVec4* pV2) {
|
||||
pOut->x = pV1->x - pV2->x;
|
||||
pOut->y = pV1->y - pV2->y;
|
||||
pOut->z = pV1->z - pV2->z;
|
||||
pOut->w = pV1->w - pV2->w;
|
||||
pOut->x = pV1->x - pV2->x;
|
||||
pOut->y = pV1->y - pV2->y;
|
||||
pOut->z = pV1->z - pV2->z;
|
||||
pOut->w = pV1->w - pV2->w;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec4* kmVec4Mul( kmVec4* pOut,const kmVec4* pV1, const kmVec4* pV2 ) {
|
||||
pOut->x = pV1->x * pV2->x;
|
||||
pOut->y = pV1->y * pV2->y;
|
||||
pOut->z = pV1->z * pV2->z;
|
||||
pOut->w = pV1->w * pV2->w;
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/// Transforms a 4D vector by a matrix, the result is stored in pOut, and pOut is returned.
|
||||
kmVec4* kmVec4Transform(kmVec4* pOut, const kmVec4* pV, const kmMat4* pM) {
|
||||
kmVec4* kmVec4Div( kmVec4* pOut,const kmVec4* pV1, const kmVec4* pV2 ) {
|
||||
if ( pV2->x && pV2->y && pV2->z && pV2->w){
|
||||
pOut->x = pV1->x / pV2->x;
|
||||
pOut->y = pV1->y / pV2->y;
|
||||
pOut->z = pV1->z / pV2->z;
|
||||
pOut->w = pV1->w / pV2->w;
|
||||
}
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/// Multiplies a 4D vector by a matrix, the result is stored in pOut, and pOut is returned.
|
||||
kmVec4* kmVec4MultiplyMat4(kmVec4* pOut, const kmVec4* pV, const struct kmMat4* pM) {
|
||||
pOut->x = pV->x * pM->mat[0] + pV->y * pM->mat[4] + pV->z * pM->mat[8] + pV->w * pM->mat[12];
|
||||
pOut->y = pV->x * pM->mat[1] + pV->y * pM->mat[5] + pV->z * pM->mat[9] + pV->w * pM->mat[13];
|
||||
pOut->z = pV->x * pM->mat[2] + pV->y * pM->mat[6] + pV->z * pM->mat[10] + pV->w * pM->mat[14];
|
||||
|
@ -120,9 +144,13 @@ kmVec4* kmVec4Transform(kmVec4* pOut, const kmVec4* pV, const kmMat4* pM) {
|
|||
return pOut;
|
||||
}
|
||||
|
||||
kmVec4* kmVec4Transform(kmVec4* pOut, const kmVec4* pV, const kmMat4* pM) {
|
||||
return kmVec4MultiplyMat4(pOut, pV, pM);
|
||||
}
|
||||
|
||||
/// Loops through an input array transforming each vec4 by the matrix.
|
||||
kmVec4* kmVec4TransformArray(kmVec4* pOut, unsigned int outStride,
|
||||
const kmVec4* pV, unsigned int vStride, const kmMat4* pM, unsigned int count) {
|
||||
const kmVec4* pV, unsigned int vStride, const kmMat4* pM, unsigned int count) {
|
||||
unsigned int i = 0;
|
||||
//Go through all of the vectors
|
||||
while (i < count) {
|
||||
|
@ -136,19 +164,19 @@ kmVec4* kmVec4TransformArray(kmVec4* pOut, unsigned int outStride,
|
|||
}
|
||||
|
||||
int kmVec4AreEqual(const kmVec4* p1, const kmVec4* p2) {
|
||||
return (
|
||||
(p1->x < p2->x + kmEpsilon && p1->x > p2->x - kmEpsilon) &&
|
||||
(p1->y < p2->y + kmEpsilon && p1->y > p2->y - kmEpsilon) &&
|
||||
(p1->z < p2->z + kmEpsilon && p1->z > p2->z - kmEpsilon) &&
|
||||
(p1->w < p2->w + kmEpsilon && p1->w > p2->w - kmEpsilon)
|
||||
);
|
||||
return (
|
||||
(p1->x < p2->x + kmEpsilon && p1->x > p2->x - kmEpsilon) &&
|
||||
(p1->y < p2->y + kmEpsilon && p1->y > p2->y - kmEpsilon) &&
|
||||
(p1->z < p2->z + kmEpsilon && p1->z > p2->z - kmEpsilon) &&
|
||||
(p1->w < p2->w + kmEpsilon && p1->w > p2->w - kmEpsilon)
|
||||
);
|
||||
}
|
||||
|
||||
kmVec4* kmVec4Assign(kmVec4* pOut, const kmVec4* pIn) {
|
||||
assert(pOut != pIn);
|
||||
assert(pOut != pIn);
|
||||
|
||||
memcpy(pOut, pIn, sizeof(float) * 4);
|
||||
memcpy(pOut, pIn, sizeof(kmScalar) * 4);
|
||||
|
||||
return pOut;
|
||||
return pOut;
|
||||
}
|
||||
|
|
@ -26,7 +26,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#ifndef VEC4_H_INCLUDED
|
||||
#define VEC4_H_INCLUDED
|
||||
|
||||
#include "CCPlatformMacros.h"
|
||||
#include "utility.h"
|
||||
|
||||
struct kmMat4;
|
||||
|
@ -34,11 +33,12 @@ struct kmMat4;
|
|||
#pragma pack(push) /* push current alignment to stack */
|
||||
#pragma pack(1) /* set alignment to 1 byte boundary */
|
||||
|
||||
typedef struct kmVec4 {
|
||||
kmScalar x;
|
||||
kmScalar y;
|
||||
kmScalar z;
|
||||
kmScalar w;
|
||||
typedef struct kmVec4
|
||||
{
|
||||
kmScalar x;
|
||||
kmScalar y;
|
||||
kmScalar z;
|
||||
kmScalar w;
|
||||
} kmVec4;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
@ -47,20 +47,24 @@ typedef struct kmVec4 {
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
CC_DLL kmVec4* kmVec4Fill(kmVec4* pOut, kmScalar x, kmScalar y, kmScalar z, kmScalar w);
|
||||
CC_DLL kmVec4* kmVec4Add(kmVec4* pOut, const kmVec4* pV1, const kmVec4* pV2);
|
||||
CC_DLL kmScalar kmVec4Dot(const kmVec4* pV1, const kmVec4* pV2);
|
||||
CC_DLL kmScalar kmVec4Length(const kmVec4* pIn);
|
||||
CC_DLL kmScalar kmVec4LengthSq(const kmVec4* pIn);
|
||||
CC_DLL kmVec4* kmVec4Lerp(kmVec4* pOut, const kmVec4* pV1, const kmVec4* pV2, kmScalar t);
|
||||
CC_DLL kmVec4* kmVec4Normalize(kmVec4* pOut, const kmVec4* pIn);
|
||||
CC_DLL kmVec4* kmVec4Scale(kmVec4* pOut, const kmVec4* pIn, const kmScalar s); ///< Scales a vector to length s
|
||||
CC_DLL kmVec4* kmVec4Subtract(kmVec4* pOut, const kmVec4* pV1, const kmVec4* pV2);
|
||||
CC_DLL kmVec4* kmVec4Transform(kmVec4* pOut, const kmVec4* pV, const struct kmMat4* pM);
|
||||
CC_DLL kmVec4* kmVec4TransformArray(kmVec4* pOut, unsigned int outStride,
|
||||
const kmVec4* pV, unsigned int vStride, const struct kmMat4* pM, unsigned int count);
|
||||
CC_DLL int kmVec4AreEqual(const kmVec4* p1, const kmVec4* p2);
|
||||
CC_DLL kmVec4* kmVec4Assign(kmVec4* pOut, const kmVec4* pIn);
|
||||
kmVec4* kmVec4Fill(kmVec4* pOut, kmScalar x, kmScalar y, kmScalar z, kmScalar w);
|
||||
kmVec4* kmVec4Add(kmVec4* pOut, const kmVec4* pV1, const kmVec4* pV2);
|
||||
kmScalar kmVec4Dot(const kmVec4* pV1, const kmVec4* pV2);
|
||||
kmScalar kmVec4Length(const kmVec4* pIn);
|
||||
kmScalar kmVec4LengthSq(const kmVec4* pIn);
|
||||
kmVec4* kmVec4Lerp(kmVec4* pOut, const kmVec4* pV1, const kmVec4* pV2, kmScalar t);
|
||||
kmVec4* kmVec4Normalize(kmVec4* pOut, const kmVec4* pIn);
|
||||
kmVec4* kmVec4Scale(kmVec4* pOut, const kmVec4* pIn, const kmScalar s); ///< Scales a vector to length s
|
||||
kmVec4* kmVec4Subtract(kmVec4* pOut, const kmVec4* pV1, const kmVec4* pV2);
|
||||
kmVec4* kmVec4Mul( kmVec4* pOut,const kmVec4* pV1, const kmVec4* pV2 );
|
||||
kmVec4* kmVec4Div( kmVec4* pOut,const kmVec4* pV1, const kmVec4* pV2 );
|
||||
|
||||
kmVec4* kmVec4MultiplyMat4(kmVec4* pOut, const kmVec4* pV, const struct kmMat4* pM);
|
||||
kmVec4* kmVec4Transform(kmVec4* pOut, const kmVec4* pV, const struct kmMat4* pM);
|
||||
kmVec4* kmVec4TransformArray(kmVec4* pOut, unsigned int outStride,
|
||||
const kmVec4* pV, unsigned int vStride, const struct kmMat4* pM, unsigned int count);
|
||||
int kmVec4AreEqual(const kmVec4* p1, const kmVec4* p2);
|
||||
kmVec4* kmVec4Assign(kmVec4* pOut, const kmVec4* pIn);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
|
||||
#ADD_LIBRARY(Kazmath STATIC ${KAZMATH_SRCS})
|
||||
#INSTALL(TARGETS Kazmath ARCHIVE DESTINATION lib)
|
||||
|
||||
INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/include )
|
||||
|
||||
ADD_LIBRARY(kazmath STATIC ${KAZMATH_SOURCES})
|
||||
INSTALL(TARGETS kazmath ARCHIVE DESTINATION lib)
|
||||
|
||||
#ADD_LIBRARY(KazmathGL STATIC ${GL_UTILS_SRCS})
|
||||
#INSTALL(TARGETS KazmathGL ARCHIVE DESTINATION lib)
|
||||
|
||||
INSTALL(FILES ${KAZMATH_HEADERS} DESTINATION include/kazmath)
|
||||
INSTALL(FILES ${GL_UTILS_HEADERS} DESTINATION include/kazmath/GL)
|
|
@ -1,738 +0,0 @@
|
|||
------------------------------------------------------------
|
||||
revno: 111
|
||||
committer: Kazade <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Thu 2010-08-19 12:07:29 +0100
|
||||
message:
|
||||
Fix #620352. Fix a reference to kmMat4RotationAxisAngle
|
||||
------------------------------------------------------------
|
||||
revno: 110
|
||||
committer: Carsten Haubld <carstenhaubold@googlemail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Wed 2010-04-21 12:55:39 +0200
|
||||
message:
|
||||
applied the change to the header files as well
|
||||
------------------------------------------------------------
|
||||
revno: 109
|
||||
committer: Carsten Haubld <carstenhaubold@googlemail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Wed 2010-04-21 12:54:06 +0200
|
||||
message:
|
||||
fixed kmMat4RotationAxis
|
||||
------------------------------------------------------------
|
||||
revno: 108 [merge]
|
||||
committer: Carsten Haubld <carstenhaubold@googlemail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Wed 2010-04-21 12:27:53 +0200
|
||||
message:
|
||||
fixed CMake in kazmathxx due to missing utility.h
|
||||
------------------------------------------------------------
|
||||
revno: 107
|
||||
committer: Carsten Haubld <carstenhaubold@googlemail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Wed 2010-04-21 12:22:40 +0200
|
||||
message:
|
||||
fixed mat4 rotation axis by normalizing the axis first
|
||||
------------------------------------------------------------
|
||||
revno: 106
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sat 2010-01-09 16:56:04 +0000
|
||||
message:
|
||||
Add cmake module
|
||||
------------------------------------------------------------
|
||||
revno: 105
|
||||
committer: Luke Benstead <luke@Hydrogen>
|
||||
branch nick: kazmath
|
||||
timestamp: Sat 2010-01-09 16:23:31 +0000
|
||||
message:
|
||||
Remove kazmodel - it really should belong in its own repo
|
||||
------------------------------------------------------------
|
||||
revno: 104
|
||||
committer: Luke Benstead <luke@Hydrogen>
|
||||
branch nick: kazmath
|
||||
timestamp: Fri 2010-01-08 23:03:13 +0000
|
||||
message:
|
||||
Reorganize the headers so that the tests can compile in place
|
||||
------------------------------------------------------------
|
||||
revno: 103
|
||||
committer: Carsten Haubld <carstenhaubold@googlemail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Mon 2009-08-31 11:21:42 +0200
|
||||
message:
|
||||
Operators now inline, constructors fixed
|
||||
------------------------------------------------------------
|
||||
revno: 102
|
||||
committer: Carsten Haubld <carstenhaubold@googlemail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sat 2009-08-29 11:42:59 +0200
|
||||
message:
|
||||
fixed some compilation errors - still how do we define operators in headers correctly??
|
||||
------------------------------------------------------------
|
||||
revno: 101
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Wed 2009-08-26 10:37:52 +0100
|
||||
message:
|
||||
Added the header defines
|
||||
------------------------------------------------------------
|
||||
revno: 100
|
||||
committer: Luke Benstead <luke@sidney>
|
||||
branch nick: kazmath
|
||||
timestamp: Wed 2009-08-26 09:38:47 +0100
|
||||
message:
|
||||
Added a V2 for kazmathxx
|
||||
------------------------------------------------------------
|
||||
revno: 99
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sun 2009-08-02 08:08:26 +0100
|
||||
message:
|
||||
Added missing header file to one of the tests
|
||||
------------------------------------------------------------
|
||||
revno: 98
|
||||
committer: Carsten Haubld <carstenhaubold@googlemail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sat 2009-08-01 12:05:25 +0200
|
||||
message:
|
||||
No longer doing self assignment in kmMat4Inverse
|
||||
------------------------------------------------------------
|
||||
revno: 97
|
||||
committer: Carsten Haubld <carstenhaubold@googlemail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sat 2009-08-01 11:15:36 +0200
|
||||
message:
|
||||
Fixed kmMat4Inverse
|
||||
------------------------------------------------------------
|
||||
revno: 96
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sat 2009-08-01 09:20:33 +0100
|
||||
message:
|
||||
Fixed some whitespace issues in plane.c
|
||||
------------------------------------------------------------
|
||||
revno: 95
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sat 2009-08-01 09:17:01 +0100
|
||||
message:
|
||||
Rename kmAABBPointInBox to kmAABBContainsPoint
|
||||
------------------------------------------------------------
|
||||
revno: 94
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sat 2009-08-01 09:16:28 +0100
|
||||
message:
|
||||
Implement kmAABBPointInBox
|
||||
------------------------------------------------------------
|
||||
revno: 93
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sat 2009-08-01 09:14:00 +0100
|
||||
message:
|
||||
Implement kmAABBAssign
|
||||
------------------------------------------------------------
|
||||
revno: 92
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sat 2009-08-01 09:10:36 +0100
|
||||
message:
|
||||
Fixed some whitespace and added some comments
|
||||
------------------------------------------------------------
|
||||
revno: 91
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sat 2009-08-01 08:56:13 +0100
|
||||
message:
|
||||
Implemented (untested) kmMat4RotationTranslation to construct a 4x4 matrix from a 3x3 + vec3
|
||||
------------------------------------------------------------
|
||||
revno: 90
|
||||
committer: Luke Benstead <luke@hydrogen>
|
||||
branch nick: kazmath
|
||||
timestamp: Sun 2009-07-05 07:55:45 +0100
|
||||
message:
|
||||
Added kmMat3RotationX, kmMat3RotationY and kmMat3RotationZ
|
||||
------------------------------------------------------------
|
||||
revno: 89
|
||||
committer: Carsten Haubld <carstenhaubold@googlemail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sat 2009-06-27 09:38:20 +0200
|
||||
message:
|
||||
Fixed a crash?
|
||||
------------------------------------------------------------
|
||||
revno: 88
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Tue 2009-04-28 09:52:57 +0100
|
||||
message:
|
||||
Added a test for kmMat4Transpose
|
||||
------------------------------------------------------------
|
||||
revno: 87
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Tue 2009-04-28 08:49:59 +0100
|
||||
message:
|
||||
Added a commented test for kmMat4Inverse, however kmMat4Adjugate and kmMat4Determinate need implementing
|
||||
------------------------------------------------------------
|
||||
revno: 86
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Tue 2009-04-28 08:46:03 +0100
|
||||
message:
|
||||
Fixed bug in kmQuaternionRotationMatrix
|
||||
------------------------------------------------------------
|
||||
revno: 85
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Tue 2009-04-28 08:41:27 +0100
|
||||
message:
|
||||
Added missing include to test_mat3.cpp
|
||||
------------------------------------------------------------
|
||||
revno: 84
|
||||
committer: Carsten Haubld <carstenhaubold@googlemail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Mon 2009-04-27 22:59:08 +0200
|
||||
message:
|
||||
fixed CMakeLists.txt for the tests
|
||||
------------------------------------------------------------
|
||||
revno: 83
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Mon 2009-04-27 21:34:20 +0100
|
||||
message:
|
||||
Added a test for kmMat3Translation
|
||||
------------------------------------------------------------
|
||||
revno: 82
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Mon 2009-04-27 21:32:19 +0100
|
||||
message:
|
||||
Fixed bugs in kmMat3Scaling and kmMat3Translation, added test for kmMat3Scaling
|
||||
------------------------------------------------------------
|
||||
revno: 81 [merge]
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Mon 2009-04-27 19:04:56 +0100
|
||||
message:
|
||||
Merge from upstream. Fixed mismatching prototype in quaternion.c
|
||||
------------------------------------------------------------
|
||||
revno: 80
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Mon 2009-04-27 19:01:35 +0100
|
||||
message:
|
||||
Added a test for kmMat3AreEqual. Fixed a bug in kmMat3AreEqual
|
||||
------------------------------------------------------------
|
||||
revno: 79
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Mon 2009-04-27 18:57:28 +0100
|
||||
message:
|
||||
Added a test for kmMat3IsIdentity
|
||||
------------------------------------------------------------
|
||||
revno: 78
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Mon 2009-04-27 18:54:48 +0100
|
||||
message:
|
||||
Added a test for kmMat3Identity
|
||||
------------------------------------------------------------
|
||||
revno: 77
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Mon 2009-04-27 18:52:14 +0100
|
||||
message:
|
||||
Added a test for kmMat3Fill
|
||||
------------------------------------------------------------
|
||||
revno: 76
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Mon 2009-04-27 18:46:30 +0100
|
||||
message:
|
||||
Added some mat3 unit tests. Fixed a bug in kmMat3AreEqual
|
||||
------------------------------------------------------------
|
||||
revno: 75
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Mon 2009-04-27 11:08:43 +0100
|
||||
message:
|
||||
Added mat4 test stub
|
||||
------------------------------------------------------------
|
||||
revno: 74
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Mon 2009-04-27 11:06:12 +0100
|
||||
message:
|
||||
Enabled unit testing in cmake
|
||||
------------------------------------------------------------
|
||||
revno: 73
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Mon 2009-04-27 10:44:37 +0100
|
||||
message:
|
||||
Added cmakelists.txt to the tests subfolder
|
||||
------------------------------------------------------------
|
||||
revno: 72
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Mon 2009-04-27 10:37:34 +0100
|
||||
message:
|
||||
Added stub mat3 test file
|
||||
------------------------------------------------------------
|
||||
revno: 71
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Mon 2009-04-27 10:35:48 +0100
|
||||
message:
|
||||
Added tests folder for new boost::unit based tests
|
||||
------------------------------------------------------------
|
||||
revno: 70
|
||||
committer: Carsten Haubld <carstenhaubold@googlemail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sun 2009-04-26 14:25:48 +0200
|
||||
message:
|
||||
Fixed the new quaternion -> Matrix -> AngleAxis methods and added them to mat4
|
||||
------------------------------------------------------------
|
||||
revno: 69
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sun 2009-04-26 12:40:08 +0100
|
||||
message:
|
||||
Added kazmodel to the kazlibs repo
|
||||
------------------------------------------------------------
|
||||
revno: 68 [merge]
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sun 2009-04-26 12:34:27 +0100
|
||||
message:
|
||||
Merge from upstream
|
||||
------------------------------------------------------------
|
||||
revno: 67
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sun 2009-04-26 12:33:43 +0100
|
||||
message:
|
||||
Reorganized bzr
|
||||
------------------------------------------------------------
|
||||
revno: 66
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sun 2009-04-26 10:00:18 +0100
|
||||
message:
|
||||
Renamed kmMat3RotationAxis to kmMat3RotationAxisAngle to be more accurate
|
||||
------------------------------------------------------------
|
||||
revno: 65
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sun 2009-04-26 09:57:19 +0100
|
||||
message:
|
||||
Fixed some compilation errors
|
||||
------------------------------------------------------------
|
||||
revno: 64
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sun 2009-04-26 09:54:12 +0100
|
||||
message:
|
||||
Added untested implementation of kmMat3RotationToAxisAngle
|
||||
------------------------------------------------------------
|
||||
revno: 63
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sun 2009-04-26 09:49:17 +0100
|
||||
message:
|
||||
Added stub for kmMat3RotationToAxisAngle()
|
||||
------------------------------------------------------------
|
||||
revno: 62
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sun 2009-04-26 09:45:58 +0100
|
||||
message:
|
||||
Corrected a typo
|
||||
------------------------------------------------------------
|
||||
revno: 61
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sun 2009-04-26 09:44:39 +0100
|
||||
message:
|
||||
Fixed broken Quaternion functions
|
||||
Added (untested) kmMat3RotationAxis()
|
||||
------------------------------------------------------------
|
||||
revno: 60
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sat 2009-04-18 08:55:29 +0100
|
||||
message:
|
||||
Fixed some errors in the quaternion header.
|
||||
Changed kmQuaternionRotationMatrix to accept a kmMat3 instead of kmMat4
|
||||
------------------------------------------------------------
|
||||
revno: 59
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sat 2009-04-18 08:42:38 +0100
|
||||
message:
|
||||
Added kmMat3RotationQuaternion
|
||||
------------------------------------------------------------
|
||||
revno: 58
|
||||
committer: Carsten Haubld <carstenhaubold@googlemail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sun 2009-04-05 11:58:29 +0200
|
||||
message:
|
||||
Added mat3
|
||||
------------------------------------------------------------
|
||||
revno: 57 [merge]
|
||||
committer: Carsten Haubld <carstenhaubold@googlemail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sun 2009-04-05 11:54:15 +0200
|
||||
message:
|
||||
Implemented mat4 and vec4 for kazmathxx
|
||||
------------------------------------------------------------
|
||||
revno: 56
|
||||
committer: Carsten Haubld <carstenhaubold@googlemail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Sun 2009-04-05 11:53:07 +0200
|
||||
message:
|
||||
Implemented mat4 and vec4 for kazmathxx
|
||||
------------------------------------------------------------
|
||||
revno: 55
|
||||
committer: Carsten Haubld <carstenhaubold@googlemail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Fri 2009-03-13 16:46:26 +0100
|
||||
message:
|
||||
added km::vec3 to kazmathxx
|
||||
------------------------------------------------------------
|
||||
revno: 54
|
||||
committer: Carsten Haubld <carstenhaubold@googlemail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Fri 2009-03-13 16:14:51 +0100
|
||||
message:
|
||||
Fixed: kmVec2 is no longer transformed by kmMat4\nAdded km::vec2
|
||||
------------------------------------------------------------
|
||||
revno: 53
|
||||
committer: Carsten Haubld <carstenhaubold@googlemail.com>
|
||||
branch nick: kazmath
|
||||
timestamp: Fri 2009-03-13 15:38:53 +0100
|
||||
message:
|
||||
Added folder for kazmathxx
|
||||
------------------------------------------------------------
|
||||
revno: 52 [merge]
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: trunk
|
||||
timestamp: Fri 2009-03-13 14:04:32 +0000
|
||||
message:
|
||||
Merge from upstream
|
||||
------------------------------------------------------------
|
||||
revno: 51
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
branch nick: trunk
|
||||
timestamp: Fri 2009-03-13 14:00:14 +0000
|
||||
message:
|
||||
Fixed for C89
|
||||
------------------------------------------------------------
|
||||
revno: 50
|
||||
committer: Carsten Haubold <CarstenHaubold@googlemail.com>
|
||||
timestamp: Tue 2008-12-30 12:45:23 +0100
|
||||
message:
|
||||
fixed kmGLTranslate
|
||||
------------------------------------------------------------
|
||||
revno: 49
|
||||
committer: Carsten Haubold <CarstenHaubold@googlemail.com>
|
||||
timestamp: Tue 2008-12-30 12:15:27 +0100
|
||||
message:
|
||||
fixed some stack memory leaks
|
||||
------------------------------------------------------------
|
||||
revno: 48
|
||||
committer: Carsten Haubold <CarstenHaubold@googlemail.com>
|
||||
timestamp: Tue 2008-12-30 11:01:35 +0100
|
||||
message:
|
||||
The GL matrix stacks now work as expected - matrix multiplication was the wrong way round
|
||||
------------------------------------------------------------
|
||||
revno: 47
|
||||
committer: Carsten Haubold <CarstenHaubold@googlemail.com>
|
||||
timestamp: Tue 2008-12-30 10:52:28 +0100
|
||||
message:
|
||||
Debug output
|
||||
------------------------------------------------------------
|
||||
revno: 46
|
||||
committer: Carsten Haubold <CarstenHaubold@googlemail.com>
|
||||
timestamp: Mon 2008-12-29 18:32:13 +0100
|
||||
message:
|
||||
Fixed some compiler errors
|
||||
------------------------------------------------------------
|
||||
revno: 45
|
||||
committer: Luke <kazade@gmail.com>
|
||||
timestamp: Wed 2008-11-19 08:36:47 +0000
|
||||
message:
|
||||
Added kmGLTranslatef, kmGLScalef and kmGLRotatef
|
||||
------------------------------------------------------------
|
||||
revno: 44
|
||||
committer: Luke <kazade@gmail.com>
|
||||
timestamp: Tue 2008-11-04 20:57:30 +0000
|
||||
message:
|
||||
Fixed up kazmathxx
|
||||
------------------------------------------------------------
|
||||
revno: 43
|
||||
committer: Luke <kazade@gmail.com>
|
||||
timestamp: Wed 2008-10-29 09:24:32 +0000
|
||||
message:
|
||||
Started implementing C++ operators in kazmathxx.h
|
||||
------------------------------------------------------------
|
||||
revno: 42
|
||||
committer: Luke <kazade@gmail.com>
|
||||
timestamp: Tue 2008-10-28 18:21:16 +0000
|
||||
message:
|
||||
Added kazmathxx.h for C++ usage
|
||||
------------------------------------------------------------
|
||||
revno: 41
|
||||
committer: Luke <kazade@gmail.com>
|
||||
timestamp: Tue 2008-10-28 11:00:41 +0000
|
||||
message:
|
||||
Added Doxygen documentation
|
||||
------------------------------------------------------------
|
||||
revno: 40
|
||||
committer: Luke <kazade@gmail.com>
|
||||
timestamp: Tue 2008-10-28 08:46:19 +0000
|
||||
message:
|
||||
Began documenting the kmPlane functions.
|
||||
Changed some assert(0)s to include a not implemented message
|
||||
------------------------------------------------------------
|
||||
revno: 39
|
||||
committer: Luke <kazade@gmail.com>
|
||||
timestamp: Tue 2008-10-28 08:42:24 +0000
|
||||
message:
|
||||
- Wrote stubs for the AABB functions which raise assertions if used.
|
||||
- Documented the AABB functions
|
||||
- Changed the definition of kmAABBPointInBox so that it actually makes sense
|
||||
------------------------------------------------------------
|
||||
revno: 38
|
||||
committer: Luke <kazade@gmail.com>
|
||||
timestamp: Tue 2008-10-28 08:38:48 +0000
|
||||
message:
|
||||
- Documented utility.c
|
||||
------------------------------------------------------------
|
||||
revno: 37
|
||||
committer: Luke <kazade@gmail.com>
|
||||
timestamp: Tue 2008-10-28 08:36:30 +0000
|
||||
message:
|
||||
- Documented vec3.c in detail.
|
||||
- Fixed up a not-implemented assertion.
|
||||
- Changed existing doc strings to C style - /** */
|
||||
------------------------------------------------------------
|
||||
revno: 36
|
||||
committer: Luke <kazade@gmail.com>
|
||||
timestamp: Tue 2008-10-28 08:30:00 +0000
|
||||
message:
|
||||
Removed uneccessary files from git
|
||||
------------------------------------------------------------
|
||||
revno: 35
|
||||
committer: Luke <kazade@gmail.com>
|
||||
timestamp: Tue 2008-10-28 08:28:49 +0000
|
||||
message:
|
||||
- Documented all the functions in mat4.c
|
||||
- Fixed up all asserts in mat4.c to include a message
|
||||
- Tidied up the code. Mat4.c is now done.
|
||||
------------------------------------------------------------
|
||||
revno: 34
|
||||
committer: Luke <kazade@gmail.com>
|
||||
timestamp: Mon 2008-10-27 21:52:33 +0000
|
||||
message:
|
||||
Added potential 0.1 release binary
|
||||
------------------------------------------------------------
|
||||
revno: 33
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
timestamp: Mon 2008-10-27 21:46:55 +0000
|
||||
message:
|
||||
Changed the README to include the BSD license
|
||||
------------------------------------------------------------
|
||||
revno: 32
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
timestamp: Mon 2008-10-27 21:45:51 +0000
|
||||
message:
|
||||
Added the modified BSD license to all source files
|
||||
------------------------------------------------------------
|
||||
revno: 31
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
timestamp: Mon 2008-10-27 21:11:51 +0000
|
||||
message:
|
||||
Fixed the installation of header files in CMake
|
||||
------------------------------------------------------------
|
||||
revno: 30
|
||||
committer: Luke <kazade@gmail.com>
|
||||
timestamp: Mon 2008-10-27 21:05:51 +0000
|
||||
message:
|
||||
Added kazmath project files
|
||||
------------------------------------------------------------
|
||||
revno: 29 [merge]
|
||||
committer: Luke <kazade@gmail.com>
|
||||
timestamp: Mon 2008-10-27 21:03:22 +0000
|
||||
message:
|
||||
Merge branch 'master' of git@github.com:Kazade/kazmath
|
||||
------------------------------------------------------------
|
||||
revno: 28
|
||||
committer: Luke <kazade@gmail.com>
|
||||
timestamp: Mon 2008-10-27 21:02:04 +0000
|
||||
message:
|
||||
Finally got kazmath compiling on VC++, man that compiler sucks! Have MS not heard of C99?
|
||||
------------------------------------------------------------
|
||||
revno: 27
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
timestamp: Sun 2008-10-26 21:35:24 +0000
|
||||
message:
|
||||
Changed the readme slightly, we need to change the license everywhere
|
||||
------------------------------------------------------------
|
||||
revno: 26
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
timestamp: Sun 2008-10-26 21:21:47 +0000
|
||||
message:
|
||||
Implemented the stacks test, fixed the undefined references I was getting
|
||||
------------------------------------------------------------
|
||||
revno: 25
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
timestamp: Sun 2008-10-26 20:59:34 +0000
|
||||
message:
|
||||
Removed the old matrix stack stuff
|
||||
------------------------------------------------------------
|
||||
revno: 24
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
timestamp: Sun 2008-10-26 20:11:58 +0000
|
||||
message:
|
||||
Started implementing the matrix stack tests
|
||||
------------------------------------------------------------
|
||||
revno: 23
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
timestamp: Sun 2008-10-26 10:56:51 +0000
|
||||
message:
|
||||
Started new implementation of the GL matrix stack
|
||||
------------------------------------------------------------
|
||||
revno: 22
|
||||
committer: Carsten Haubold <CarstenHaubold@googlemail.com>
|
||||
timestamp: Thu 2008-08-28 12:37:41 +0200
|
||||
message:
|
||||
Added kmGLRotation
|
||||
------------------------------------------------------------
|
||||
revno: 21
|
||||
committer: Luke Benstead <luke@helium.(none)>
|
||||
timestamp: Thu 2008-08-28 09:24:00 +0100
|
||||
message:
|
||||
We now have a working matrix stack
|
||||
------------------------------------------------------------
|
||||
revno: 20
|
||||
committer: Luke Benstead <luke@helium.(none)>
|
||||
timestamp: Wed 2008-08-27 13:34:49 +0100
|
||||
message:
|
||||
Fixed the stack memory constants
|
||||
------------------------------------------------------------
|
||||
revno: 19
|
||||
committer: Luke Benstead <luke@helium.(none)>
|
||||
timestamp: Wed 2008-08-27 13:33:12 +0100
|
||||
message:
|
||||
Added the initial gl_utils implementation for replacing the matrix functionality deprecated in OpenGL 3.0
|
||||
------------------------------------------------------------
|
||||
revno: 18
|
||||
committer: Carsten Haubold <dumbo@dumbo-laptop.(none)>
|
||||
timestamp: Mon 2008-08-25 12:46:16 +0200
|
||||
message:
|
||||
Fixed a bug in kmMat4LookAt
|
||||
------------------------------------------------------------
|
||||
revno: 17 [merge]
|
||||
committer: Carsten Haubold <dumbo@dumbo-laptop.(none)>
|
||||
timestamp: Sun 2008-08-24 22:07:49 +0200
|
||||
message:
|
||||
Merge branch 'master' of git@github.com:Kazade/kazmath
|
||||
------------------------------------------------------------
|
||||
revno: 16
|
||||
committer: Carsten Haubold <dumbo@dumbo-laptop.(none)>
|
||||
timestamp: Sun 2008-08-24 22:06:45 +0200
|
||||
message:
|
||||
Added kmMat4LookAt
|
||||
------------------------------------------------------------
|
||||
revno: 15
|
||||
committer: Carsten Haubold <dumbo@dumbo-laptop.(none)>
|
||||
timestamp: Wed 2008-08-20 11:18:10 +0200
|
||||
message:
|
||||
Added Fill methods for all Vec and Mat structs
|
||||
------------------------------------------------------------
|
||||
revno: 14
|
||||
committer: Carsten Haubold <dumbo@dumbo-laptop.(none)>
|
||||
timestamp: Tue 2008-08-19 22:31:55 +0200
|
||||
message:
|
||||
Added UnitTests, changed bool to int and fixed some minor bugs
|
||||
------------------------------------------------------------
|
||||
revno: 13
|
||||
committer: Carsten Haubold <dumbo@dumbo-laptop.(none)>
|
||||
timestamp: Sun 2008-08-17 23:19:21 +0200
|
||||
message:
|
||||
removed .svn entries which did not belong here
|
||||
------------------------------------------------------------
|
||||
revno: 12
|
||||
committer: Carsten Haubold <dumbo@dumbo-laptop.(none)>
|
||||
timestamp: Sun 2008-08-17 23:17:07 +0200
|
||||
message:
|
||||
some tweaks on matrices and first test-app, PerspectiveProjection is correct !
|
||||
------------------------------------------------------------
|
||||
revno: 11
|
||||
committer: Carsten Haubold <dumbo@dumbo-laptop.(none)>
|
||||
timestamp: Sun 2008-08-17 16:04:09 +0200
|
||||
message:
|
||||
Renamed cotangent to cotangens
|
||||
------------------------------------------------------------
|
||||
revno: 10
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
timestamp: Sat 2008-08-16 21:51:22 +0100
|
||||
message:
|
||||
Added kmMat4PerspectiveProjection and kmMat4OrthographicProjection
|
||||
------------------------------------------------------------
|
||||
revno: 9
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
timestamp: Thu 2008-08-14 21:15:45 +0100
|
||||
message:
|
||||
Added the aabb struct
|
||||
------------------------------------------------------------
|
||||
revno: 8
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
timestamp: Thu 2008-08-14 17:57:43 +0100
|
||||
message:
|
||||
Added the kmAABB structure
|
||||
------------------------------------------------------------
|
||||
revno: 7
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
timestamp: Thu 2008-08-14 14:32:24 +0100
|
||||
message:
|
||||
Fixed broken kmMat3Transpose
|
||||
------------------------------------------------------------
|
||||
revno: 6
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
timestamp: Thu 2008-08-14 14:21:04 +0100
|
||||
message:
|
||||
Fixed broken kmMat4Translation, w component was not set
|
||||
------------------------------------------------------------
|
||||
revno: 5
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
timestamp: Thu 2008-08-14 14:01:47 +0100
|
||||
message:
|
||||
Added mat3.c and mat3.h to the cmake file
|
||||
------------------------------------------------------------
|
||||
revno: 4
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
timestamp: Thu 2008-08-14 13:56:26 +0100
|
||||
message:
|
||||
Added the authors section to the readme
|
||||
------------------------------------------------------------
|
||||
revno: 3
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
timestamp: Thu 2008-08-14 13:55:41 +0100
|
||||
message:
|
||||
Updated the readme file
|
||||
------------------------------------------------------------
|
||||
revno: 2
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
timestamp: Thu 2008-08-14 13:53:26 +0100
|
||||
message:
|
||||
Added kazmath to git
|
||||
------------------------------------------------------------
|
||||
revno: 1
|
||||
committer: Luke Benstead <kazade@gmail.com>
|
||||
timestamp: Thu 2008-08-14 13:47:51 +0100
|
||||
message:
|
||||
First commit
|
||||
------------------------------------------------------------
|
||||
Use --include-merges or -n0 to see merged revisions.
|
|
@ -1,63 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2008, Luke Benstead.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "kazmath/aabb.h"
|
||||
|
||||
/**
|
||||
* Returns KM_TRUE if point is in the specified AABB, returns
|
||||
* KM_FALSE otherwise.
|
||||
*/
|
||||
const int kmAABBContainsPoint(const kmVec3* pPoint, const kmAABB* pBox)
|
||||
{
|
||||
if(pPoint->x >= pBox->min.x && pPoint->x <= pBox->max.x &&
|
||||
pPoint->y >= pBox->min.y && pPoint->y <= pBox->max.y &&
|
||||
pPoint->z >= pBox->min.z && pPoint->z <= pBox->max.z) {
|
||||
return KM_TRUE;
|
||||
}
|
||||
|
||||
return KM_FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns pIn to pOut, returns pOut.
|
||||
*/
|
||||
kmAABB* const kmAABBAssign(kmAABB* pOut, const kmAABB* pIn)
|
||||
{
|
||||
kmVec3Assign(&pOut->min, &pIn->min);
|
||||
kmVec3Assign(&pOut->max, &pIn->max);
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scales pIn by s, stores the resulting AABB in pOut. Returns pOut
|
||||
*/
|
||||
kmAABB* const kmAABBScale(kmAABB* pOut, const kmAABB* pIn, kmScalar s)
|
||||
{
|
||||
assert(0 && "Not implemented");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,372 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2008, Luke Benstead.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "kazmath/utility.h"
|
||||
#include "kazmath/vec3.h"
|
||||
#include "kazmath/mat3.h"
|
||||
#include "kazmath/quaternion.h"
|
||||
|
||||
kmMat3* const kmMat3Fill(kmMat3* pOut, const kmScalar* pMat)
|
||||
{
|
||||
memcpy(pOut->mat, pMat, sizeof(kmScalar) * 9);
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/** Sets pOut to an identity matrix returns pOut*/
|
||||
kmMat3* const kmMat3Identity(kmMat3* pOut)
|
||||
{
|
||||
memset(pOut->mat, 0, sizeof(float) * 9);
|
||||
pOut->mat[0] = pOut->mat[4] = pOut->mat[8] = 1.0f;
|
||||
return pOut;
|
||||
}
|
||||
|
||||
const kmScalar kmMat3Determinant(const kmMat3* pIn)
|
||||
{
|
||||
kmScalar output;
|
||||
/*
|
||||
calculating the determinant following the rule of sarus,
|
||||
| 0 3 6 | 0 3 |
|
||||
m = | 1 4 7 | 1 4 |
|
||||
| 2 5 8 | 2 5 |
|
||||
now sum up the products of the diagonals going to the right (i.e. 0,4,8)
|
||||
and subtract the products of the other diagonals (i.e. 2,4,6)
|
||||
*/
|
||||
|
||||
output = pIn->mat[0] * pIn->mat[4] * pIn->mat[8] + pIn->mat[1] * pIn->mat[5] * pIn->mat[6] + pIn->mat[2] * pIn->mat[3] * pIn->mat[7];
|
||||
output -= pIn->mat[2] * pIn->mat[4] * pIn->mat[6] + pIn->mat[0] * pIn->mat[5] * pIn->mat[7] + pIn->mat[1] * pIn->mat[3] * pIn->mat[8];
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
kmMat3* const kmMat3Adjugate(kmMat3* pOut, const kmMat3* pIn)
|
||||
{
|
||||
pOut->mat[0] = pIn->mat[4] * pIn->mat[8] - pIn->mat[5] * pIn->mat[7];
|
||||
pOut->mat[1] = pIn->mat[2] * pIn->mat[7] - pIn->mat[1] * pIn->mat[8];
|
||||
pOut->mat[2] = pIn->mat[1] * pIn->mat[5] - pIn->mat[2] * pIn->mat[4];
|
||||
pOut->mat[3] = pIn->mat[5] * pIn->mat[6] - pIn->mat[3] * pIn->mat[8];
|
||||
pOut->mat[4] = pIn->mat[0] * pIn->mat[8] - pIn->mat[2] * pIn->mat[6];
|
||||
pOut->mat[5] = pIn->mat[2] * pIn->mat[3] - pIn->mat[0] * pIn->mat[5];
|
||||
pOut->mat[6] = pIn->mat[3] * pIn->mat[7] - pIn->mat[4] * pIn->mat[6];
|
||||
|
||||
// XXX: pIn->mat[9] is invalid!
|
||||
// pOut->mat[7] = pIn->mat[1] * pIn->mat[6] - pIn->mat[9] * pIn->mat[7];
|
||||
pOut->mat[8] = pIn->mat[0] * pIn->mat[4] - pIn->mat[1] * pIn->mat[3];
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmMat3* const kmMat3Inverse(kmMat3* pOut, const kmScalar pDeterminate, const kmMat3* pM)
|
||||
{
|
||||
kmScalar detInv;
|
||||
kmMat3 adjugate;
|
||||
|
||||
if(pDeterminate == 0.0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
detInv = 1.0f / pDeterminate;
|
||||
|
||||
kmMat3Adjugate(&adjugate, pM);
|
||||
kmMat3ScalarMultiply(pOut, &adjugate, detInv);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/** Returns true if pIn is an identity matrix */
|
||||
const int kmMat3IsIdentity(const kmMat3* pIn)
|
||||
{
|
||||
static const float identity [] = { 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f};
|
||||
|
||||
return (memcmp(identity, pIn->mat, sizeof(float) * 9) == 0);
|
||||
}
|
||||
|
||||
/** Sets pOut to the transpose of pIn, returns pOut */
|
||||
kmMat3* const kmMat3Transpose(kmMat3* pOut, const kmMat3* pIn)
|
||||
{
|
||||
int z, x;
|
||||
for (z = 0; z < 3; ++z) {
|
||||
for (x = 0; x < 3; ++x) {
|
||||
pOut->mat[(z * 3) + x] = pIn->mat[(x * 3) + z];
|
||||
}
|
||||
}
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/* Multiplies pM1 with pM2, stores the result in pOut, returns pOut */
|
||||
kmMat3* const kmMat3Multiply(kmMat3* pOut, const kmMat3* pM1, const kmMat3* pM2)
|
||||
{
|
||||
float mat[9];
|
||||
|
||||
const float *m1 = pM1->mat, *m2 = pM2->mat;
|
||||
|
||||
mat[0] = m1[0] * m2[0] + m1[3] * m2[1] + m1[6] * m2[2];
|
||||
mat[1] = m1[1] * m2[0] + m1[4] * m2[1] + m1[7] * m2[2];
|
||||
mat[2] = m1[2] * m2[0] + m1[5] * m2[1] + m1[8] * m2[2];
|
||||
|
||||
mat[3] = m1[0] * m2[3] + m1[3] * m2[4] + m1[6] * m2[5];
|
||||
mat[4] = m1[1] * m2[3] + m1[4] * m2[4] + m1[7] * m2[5];
|
||||
mat[5] = m1[2] * m2[3] + m1[5] * m2[4] + m1[8] * m2[5];
|
||||
|
||||
mat[6] = m1[0] * m2[6] + m1[3] * m2[7] + m1[6] * m2[8];
|
||||
mat[7] = m1[1] * m2[6] + m1[4] * m2[7] + m1[7] * m2[8];
|
||||
mat[8] = m1[2] * m2[6] + m1[5] * m2[7] + m1[8] * m2[8];
|
||||
|
||||
memcpy(pOut->mat, mat, sizeof(float)*9);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmMat3* const kmMat3ScalarMultiply(kmMat3* pOut, const kmMat3* pM, const kmScalar pFactor)
|
||||
{
|
||||
float mat[9];
|
||||
int i;
|
||||
|
||||
for(i = 0; i < 9; i++)
|
||||
{
|
||||
mat[i] = pM->mat[i] * pFactor;
|
||||
}
|
||||
|
||||
memcpy(pOut->mat, mat, sizeof(float)*9);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/** Assigns the value of pIn to pOut */
|
||||
kmMat3* const kmMat3Assign(kmMat3* pOut, const kmMat3* pIn)
|
||||
{
|
||||
assert(pOut != pIn); //You have tried to self-assign!!
|
||||
|
||||
memcpy(pOut->mat, pIn->mat, sizeof(float)*9);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/** Returns true if the 2 matrices are equal (approximately) */
|
||||
const int kmMat3AreEqual(const kmMat3* pMat1, const kmMat3* pMat2)
|
||||
{
|
||||
int i;
|
||||
if (pMat1 == pMat2) {
|
||||
return KM_TRUE;
|
||||
}
|
||||
|
||||
for (i = 0; i < 9; ++i) {
|
||||
if (!(pMat1->mat[i] + kmEpsilon > pMat2->mat[i] &&
|
||||
pMat1->mat[i] - kmEpsilon < pMat2->mat[i])) {
|
||||
return KM_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return KM_TRUE;
|
||||
}
|
||||
|
||||
/* Rotation around the z axis so everything stays planar in XY */
|
||||
kmMat3* const kmMat3Rotation(kmMat3* pOut, const float radians)
|
||||
{
|
||||
/*
|
||||
| cos(A) -sin(A) 0 |
|
||||
M = | sin(A) cos(A) 0 |
|
||||
| 0 0 1 |
|
||||
*/
|
||||
|
||||
pOut->mat[0] = cosf(radians);
|
||||
pOut->mat[1] = sinf(radians);
|
||||
pOut->mat[2] = 0.0f;
|
||||
|
||||
pOut->mat[3] = -sinf(radians);;
|
||||
pOut->mat[4] = cosf(radians);
|
||||
pOut->mat[5] = 0.0f;
|
||||
|
||||
pOut->mat[6] = 0.0f;
|
||||
pOut->mat[7] = 0.0f;
|
||||
pOut->mat[8] = 1.0f;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/** Builds a scaling matrix */
|
||||
kmMat3* const kmMat3Scaling(kmMat3* pOut, const kmScalar x, const kmScalar y)
|
||||
{
|
||||
// memset(pOut->mat, 0, sizeof(float) * 9);
|
||||
kmMat3Identity(pOut);
|
||||
pOut->mat[0] = x;
|
||||
pOut->mat[4] = y;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmMat3* const kmMat3Translation(kmMat3* pOut, const kmScalar x, const kmScalar y)
|
||||
{
|
||||
// memset(pOut->mat, 0, sizeof(float) * 9);
|
||||
kmMat3Identity(pOut);
|
||||
pOut->mat[6] = x;
|
||||
pOut->mat[7] = y;
|
||||
// pOut->mat[8] = 1.0;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
|
||||
kmMat3* const kmMat3RotationQuaternion(kmMat3* pOut, const kmQuaternion* pIn)
|
||||
{
|
||||
if (!pIn || !pOut) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// First row
|
||||
pOut->mat[0] = 1.0f - 2.0f * (pIn->y * pIn->y + pIn->z * pIn->z);
|
||||
pOut->mat[1] = 2.0f * (pIn->x * pIn->y - pIn->w * pIn->z);
|
||||
pOut->mat[2] = 2.0f * (pIn->x * pIn->z + pIn->w * pIn->y);
|
||||
|
||||
// Second row
|
||||
pOut->mat[3] = 2.0f * (pIn->x * pIn->y + pIn->w * pIn->z);
|
||||
pOut->mat[4] = 1.0f - 2.0f * (pIn->x * pIn->x + pIn->z * pIn->z);
|
||||
pOut->mat[5] = 2.0f * (pIn->y * pIn->z - pIn->w * pIn->x);
|
||||
|
||||
// Third row
|
||||
pOut->mat[6] = 2.0f * (pIn->x * pIn->z - pIn->w * pIn->y);
|
||||
pOut->mat[7] = 2.0f * (pIn->y * pIn->z + pIn->w * pIn->x);
|
||||
pOut->mat[8] = 1.0f - 2.0f * (pIn->x * pIn->x + pIn->y * pIn->y);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmMat3* const kmMat3RotationAxisAngle(kmMat3* pOut, const struct kmVec3* axis, kmScalar radians)
|
||||
{
|
||||
float rcos = cosf(radians);
|
||||
float rsin = sinf(radians);
|
||||
|
||||
pOut->mat[0] = rcos + axis->x * axis->x * (1 - rcos);
|
||||
pOut->mat[1] = axis->z * rsin + axis->y * axis->x * (1 - rcos);
|
||||
pOut->mat[2] = -axis->y * rsin + axis->z * axis->x * (1 - rcos);
|
||||
|
||||
pOut->mat[3] = -axis->z * rsin + axis->x * axis->y * (1 - rcos);
|
||||
pOut->mat[4] = rcos + axis->y * axis->y * (1 - rcos);
|
||||
pOut->mat[5] = axis->x * rsin + axis->z * axis->y * (1 - rcos);
|
||||
|
||||
pOut->mat[6] = axis->y * rsin + axis->x * axis->z * (1 - rcos);
|
||||
pOut->mat[7] = -axis->x * rsin + axis->y * axis->z * (1 - rcos);
|
||||
pOut->mat[8] = rcos + axis->z * axis->z * (1 - rcos);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec3* const kmMat3RotationToAxisAngle(kmVec3* pAxis, kmScalar* radians, const kmMat3* pIn)
|
||||
{
|
||||
/*Surely not this easy?*/
|
||||
kmQuaternion temp;
|
||||
kmQuaternionRotationMatrix(&temp, pIn);
|
||||
kmQuaternionToAxisAngle(&temp, pAxis, radians);
|
||||
return pAxis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds an X-axis rotation matrix and stores it in pOut, returns pOut
|
||||
*/
|
||||
kmMat3* const kmMat3RotationX(kmMat3* pOut, const float radians)
|
||||
{
|
||||
/*
|
||||
| 1 0 0 |
|
||||
M = | 0 cos(A) -sin(A) |
|
||||
| 0 sin(A) cos(A) |
|
||||
|
||||
*/
|
||||
|
||||
pOut->mat[0] = 1.0f;
|
||||
pOut->mat[1] = 0.0f;
|
||||
pOut->mat[2] = 0.0f;
|
||||
|
||||
pOut->mat[3] = 0.0f;
|
||||
pOut->mat[4] = cosf(radians);
|
||||
pOut->mat[5] = sinf(radians);
|
||||
|
||||
pOut->mat[6] = 0.0f;
|
||||
pOut->mat[7] = -sinf(radians);
|
||||
pOut->mat[8] = cosf(radians);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a rotation matrix using the rotation around the Y-axis
|
||||
* The result is stored in pOut, pOut is returned.
|
||||
*/
|
||||
kmMat3* const kmMat3RotationY(kmMat3* pOut, const float radians)
|
||||
{
|
||||
/*
|
||||
| cos(A) 0 sin(A) |
|
||||
M = | 0 1 0 |
|
||||
| -sin(A) 0 cos(A) |
|
||||
*/
|
||||
|
||||
pOut->mat[0] = cosf(radians);
|
||||
pOut->mat[1] = 0.0f;
|
||||
pOut->mat[2] = -sinf(radians);
|
||||
|
||||
pOut->mat[3] = 0.0f;
|
||||
pOut->mat[4] = 1.0f;
|
||||
pOut->mat[5] = 0.0f;
|
||||
|
||||
pOut->mat[6] = sinf(radians);
|
||||
pOut->mat[7] = 0.0f;
|
||||
pOut->mat[8] = cosf(radians);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a rotation matrix around the Z-axis. The resulting
|
||||
* matrix is stored in pOut. pOut is returned.
|
||||
*/
|
||||
kmMat3* const kmMat3RotationZ(kmMat3* pOut, const float radians)
|
||||
{
|
||||
/*
|
||||
| cos(A) -sin(A) 0 |
|
||||
M = | sin(A) cos(A) 0 |
|
||||
| 0 0 1 |
|
||||
*/
|
||||
|
||||
pOut->mat[0] = cosf(radians);
|
||||
pOut->mat[1] =-sinf(radians);
|
||||
pOut->mat[2] = 0.0f;
|
||||
|
||||
pOut->mat[3] = sinf(radians);;
|
||||
pOut->mat[4] = cosf(radians);
|
||||
pOut->mat[5] = 0.0f;
|
||||
|
||||
pOut->mat[6] = 0.0f;
|
||||
pOut->mat[7] = 0.0f;
|
||||
pOut->mat[8] = 1.0f;
|
||||
|
||||
return pOut;
|
||||
}
|
|
@ -1,792 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2008, Luke Benstead.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file mat4.c
|
||||
*/
|
||||
#include <memory.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "kazmath/utility.h"
|
||||
#include "kazmath/vec3.h"
|
||||
#include "kazmath/mat4.h"
|
||||
#include "kazmath/mat3.h"
|
||||
#include "kazmath/quaternion.h"
|
||||
#include "kazmath/plane.h"
|
||||
|
||||
#include "kazmath/neon_matrix_impl.h"
|
||||
|
||||
/**
|
||||
* Fills a kmMat4 structure with the values from a 16
|
||||
* element array of floats
|
||||
* @Params pOut - A pointer to the destination matrix
|
||||
* pMat - A 16 element array of floats
|
||||
* @Return Returns pOut so that the call can be nested
|
||||
*/
|
||||
kmMat4* const kmMat4Fill(kmMat4* pOut, const kmScalar* pMat)
|
||||
{
|
||||
memcpy(pOut->mat, pMat, sizeof(kmScalar) * 16);
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets pOut to an identity matrix returns pOut
|
||||
* @Params pOut - A pointer to the matrix to set to identity
|
||||
* @Return Returns pOut so that the call can be nested
|
||||
*/
|
||||
kmMat4* const kmMat4Identity(kmMat4* pOut)
|
||||
{
|
||||
memset(pOut->mat, 0, sizeof(float) * 16);
|
||||
pOut->mat[0] = pOut->mat[5] = pOut->mat[10] = pOut->mat[15] = 1.0f;
|
||||
return pOut;
|
||||
}
|
||||
|
||||
|
||||
float get(const kmMat4 * pIn, int row, int col)
|
||||
{
|
||||
return pIn->mat[row + 4*col];
|
||||
}
|
||||
|
||||
void set(kmMat4 * pIn, int row, int col, float value)
|
||||
{
|
||||
pIn->mat[row + 4*col] = value;
|
||||
}
|
||||
|
||||
void swap(kmMat4 * pIn, int r1, int c1, int r2, int c2)
|
||||
{
|
||||
float tmp = get(pIn,r1,c1);
|
||||
set(pIn,r1,c1,get(pIn,r2,c2));
|
||||
set(pIn,r2,c2, tmp);
|
||||
}
|
||||
|
||||
//Returns an upper and a lower triangular matrix which are L and R in the Gauss algorithm
|
||||
int gaussj(kmMat4 *a, kmMat4 *b)
|
||||
{
|
||||
int i, icol = 0, irow = 0, j, k, l, ll, n = 4, m = 4;
|
||||
float big, dum, pivinv;
|
||||
int indxc[4] = {0};
|
||||
int indxr[4] = {0};
|
||||
int ipiv[4] = {0};
|
||||
|
||||
for (j = 0; j < n; j++) {
|
||||
ipiv[j] = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
big = 0.0f;
|
||||
for (j = 0; j < n; j++) {
|
||||
if (ipiv[j] != 1) {
|
||||
for (k = 0; k < n; k++) {
|
||||
if (ipiv[k] == 0) {
|
||||
if (abs(get(a,j, k)) >= big) {
|
||||
big = abs(get(a,j, k));
|
||||
irow = j;
|
||||
icol = k;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
++(ipiv[icol]);
|
||||
if (irow != icol) {
|
||||
for (l = 0; l < n; l++) {
|
||||
swap(a,irow, l, icol, l);
|
||||
}
|
||||
for (l = 0; l < m; l++) {
|
||||
swap(b,irow, l, icol, l);
|
||||
}
|
||||
}
|
||||
indxr[i] = irow;
|
||||
indxc[i] = icol;
|
||||
if (get(a,icol, icol) == 0.0) {
|
||||
return KM_FALSE;
|
||||
}
|
||||
pivinv = 1.0f / get(a,icol, icol);
|
||||
set(a,icol, icol, 1.0f);
|
||||
for (l = 0; l < n; l++) {
|
||||
set(a,icol, l, get(a,icol, l) * pivinv);
|
||||
}
|
||||
for (l = 0; l < m; l++) {
|
||||
set(b,icol, l, get(b,icol, l) * pivinv);
|
||||
}
|
||||
|
||||
for (ll = 0; ll < n; ll++) {
|
||||
if (ll != icol) {
|
||||
dum = get(a,ll, icol);
|
||||
set(a,ll, icol, 0.0f);
|
||||
for (l = 0; l < n; l++) {
|
||||
set(a,ll, l, get(a,ll, l) - get(a,icol, l) * dum);
|
||||
}
|
||||
for (l = 0; l < m; l++) {
|
||||
set(b,ll, l, get(a,ll, l) - get(b,icol, l) * dum);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// This is the end of the main loop over columns of the reduction. It only remains to unscram-
|
||||
// ble the solution in view of the column interchanges. We do this by interchanging pairs of
|
||||
// columns in the reverse order that the permutation was built up.
|
||||
for (l = n - 1; l >= 0; l--) {
|
||||
if (indxr[l] != indxc[l]) {
|
||||
for (k = 0; k < n; k++) {
|
||||
swap(a,k, indxr[l], k, indxc[l]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return KM_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the inverse of pM and stores the result in
|
||||
* pOut.
|
||||
* @Return Returns NULL if there is no inverse, else pOut
|
||||
*/
|
||||
kmMat4* const kmMat4Inverse(kmMat4* pOut, const kmMat4* pM)
|
||||
{
|
||||
kmMat4 inv;
|
||||
kmMat4 tmp;
|
||||
|
||||
kmMat4Assign(&inv, pM);
|
||||
|
||||
kmMat4Identity(&tmp);
|
||||
|
||||
if(gaussj(&inv, &tmp) == KM_FALSE) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
kmMat4Assign(pOut, &inv);
|
||||
return pOut;
|
||||
}
|
||||
/**
|
||||
* Returns KM_TRUE if pIn is an identity matrix
|
||||
* KM_FALSE otherwise
|
||||
*/
|
||||
const int kmMat4IsIdentity(const kmMat4* pIn)
|
||||
{
|
||||
static const float identity [] = { 1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
};
|
||||
|
||||
return (memcmp(identity, pIn->mat, sizeof(float) * 16) == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets pOut to the transpose of pIn, returns pOut
|
||||
*/
|
||||
kmMat4* const kmMat4Transpose(kmMat4* pOut, const kmMat4* pIn)
|
||||
{
|
||||
int x, z;
|
||||
|
||||
for (z = 0; z < 4; ++z) {
|
||||
for (x = 0; x < 4; ++x) {
|
||||
pOut->mat[(z * 4) + x] = pIn->mat[(x * 4) + z];
|
||||
}
|
||||
}
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies pM1 with pM2, stores the result in pOut, returns pOut
|
||||
*/
|
||||
kmMat4* const kmMat4Multiply(kmMat4* pOut, const kmMat4* pM1, const kmMat4* pM2)
|
||||
{
|
||||
#if defined(__ARM_NEON__) && !defined(__arm64__)
|
||||
|
||||
// It is possible to skip the memcpy() since "out" does not overwrite p1 or p2.
|
||||
// otherwise a temp must be needed.
|
||||
float *mat = pOut->mat;
|
||||
|
||||
// Invert column-order with row-order
|
||||
NEON_Matrix4Mul( &pM2->mat[0], &pM1->mat[0], &mat[0] );
|
||||
|
||||
#else
|
||||
float mat[16];
|
||||
|
||||
const float *m1 = pM1->mat, *m2 = pM2->mat;
|
||||
|
||||
mat[0] = m1[0] * m2[0] + m1[4] * m2[1] + m1[8] * m2[2] + m1[12] * m2[3];
|
||||
mat[1] = m1[1] * m2[0] + m1[5] * m2[1] + m1[9] * m2[2] + m1[13] * m2[3];
|
||||
mat[2] = m1[2] * m2[0] + m1[6] * m2[1] + m1[10] * m2[2] + m1[14] * m2[3];
|
||||
mat[3] = m1[3] * m2[0] + m1[7] * m2[1] + m1[11] * m2[2] + m1[15] * m2[3];
|
||||
|
||||
mat[4] = m1[0] * m2[4] + m1[4] * m2[5] + m1[8] * m2[6] + m1[12] * m2[7];
|
||||
mat[5] = m1[1] * m2[4] + m1[5] * m2[5] + m1[9] * m2[6] + m1[13] * m2[7];
|
||||
mat[6] = m1[2] * m2[4] + m1[6] * m2[5] + m1[10] * m2[6] + m1[14] * m2[7];
|
||||
mat[7] = m1[3] * m2[4] + m1[7] * m2[5] + m1[11] * m2[6] + m1[15] * m2[7];
|
||||
|
||||
mat[8] = m1[0] * m2[8] + m1[4] * m2[9] + m1[8] * m2[10] + m1[12] * m2[11];
|
||||
mat[9] = m1[1] * m2[8] + m1[5] * m2[9] + m1[9] * m2[10] + m1[13] * m2[11];
|
||||
mat[10] = m1[2] * m2[8] + m1[6] * m2[9] + m1[10] * m2[10] + m1[14] * m2[11];
|
||||
mat[11] = m1[3] * m2[8] + m1[7] * m2[9] + m1[11] * m2[10] + m1[15] * m2[11];
|
||||
|
||||
mat[12] = m1[0] * m2[12] + m1[4] * m2[13] + m1[8] * m2[14] + m1[12] * m2[15];
|
||||
mat[13] = m1[1] * m2[12] + m1[5] * m2[13] + m1[9] * m2[14] + m1[13] * m2[15];
|
||||
mat[14] = m1[2] * m2[12] + m1[6] * m2[13] + m1[10] * m2[14] + m1[14] * m2[15];
|
||||
mat[15] = m1[3] * m2[12] + m1[7] * m2[13] + m1[11] * m2[14] + m1[15] * m2[15];
|
||||
|
||||
memcpy(pOut->mat, mat, sizeof(pOut->mat));
|
||||
|
||||
#endif
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns the value of pIn to pOut
|
||||
*/
|
||||
kmMat4* const kmMat4Assign(kmMat4* pOut, const kmMat4* pIn)
|
||||
{
|
||||
assert(pOut != pIn && "You have tried to self-assign!!");
|
||||
|
||||
memcpy(pOut->mat, pIn->mat, sizeof(float)*16);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns KM_TRUE if the 2 matrices are equal (approximately)
|
||||
*/
|
||||
const int kmMat4AreEqual(const kmMat4* pMat1, const kmMat4* pMat2)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
assert(pMat1 != pMat2 && "You are comparing the same thing!");
|
||||
|
||||
for (i = 0; i < 16; ++i)
|
||||
{
|
||||
if (!(pMat1->mat[i] + kmEpsilon > pMat2->mat[i] &&
|
||||
pMat1->mat[i] - kmEpsilon < pMat2->mat[i])) {
|
||||
return KM_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return KM_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a rotation matrix from an axis and an angle. Result is stored in pOut.
|
||||
* pOut is returned.
|
||||
*/
|
||||
kmMat4* const kmMat4RotationAxisAngle(kmMat4* pOut, const kmVec3* axis, kmScalar radians)
|
||||
{
|
||||
float rcos = cosf(radians);
|
||||
float rsin = sinf(radians);
|
||||
|
||||
kmVec3 normalizedAxis;
|
||||
kmVec3Normalize(&normalizedAxis, axis);
|
||||
|
||||
pOut->mat[0] = rcos + normalizedAxis.x * normalizedAxis.x * (1 - rcos);
|
||||
pOut->mat[1] = normalizedAxis.z * rsin + normalizedAxis.y * normalizedAxis.x * (1 - rcos);
|
||||
pOut->mat[2] = -normalizedAxis.y * rsin + normalizedAxis.z * normalizedAxis.x * (1 - rcos);
|
||||
pOut->mat[3] = 0.0f;
|
||||
|
||||
pOut->mat[4] = -normalizedAxis.z * rsin + normalizedAxis.x * normalizedAxis.y * (1 - rcos);
|
||||
pOut->mat[5] = rcos + normalizedAxis.y * normalizedAxis.y * (1 - rcos);
|
||||
pOut->mat[6] = normalizedAxis.x * rsin + normalizedAxis.z * normalizedAxis.y * (1 - rcos);
|
||||
pOut->mat[7] = 0.0f;
|
||||
|
||||
pOut->mat[8] = normalizedAxis.y * rsin + normalizedAxis.x * normalizedAxis.z * (1 - rcos);
|
||||
pOut->mat[9] = -normalizedAxis.x * rsin + normalizedAxis.y * normalizedAxis.z * (1 - rcos);
|
||||
pOut->mat[10] = rcos + normalizedAxis.z * normalizedAxis.z * (1 - rcos);
|
||||
pOut->mat[11] = 0.0f;
|
||||
|
||||
pOut->mat[12] = 0.0f;
|
||||
pOut->mat[13] = 0.0f;
|
||||
pOut->mat[14] = 0.0f;
|
||||
pOut->mat[15] = 1.0f;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds an X-axis rotation matrix and stores it in pOut, returns pOut
|
||||
*/
|
||||
kmMat4* const kmMat4RotationX(kmMat4* pOut, const float radians)
|
||||
{
|
||||
/*
|
||||
| 1 0 0 0 |
|
||||
M = | 0 cos(A) -sin(A) 0 |
|
||||
| 0 sin(A) cos(A) 0 |
|
||||
| 0 0 0 1 |
|
||||
|
||||
*/
|
||||
|
||||
pOut->mat[0] = 1.0f;
|
||||
pOut->mat[1] = 0.0f;
|
||||
pOut->mat[2] = 0.0f;
|
||||
pOut->mat[3] = 0.0f;
|
||||
|
||||
pOut->mat[4] = 0.0f;
|
||||
pOut->mat[5] = cosf(radians);
|
||||
pOut->mat[6] = sinf(radians);
|
||||
pOut->mat[7] = 0.0f;
|
||||
|
||||
pOut->mat[8] = 0.0f;
|
||||
pOut->mat[9] = -sinf(radians);
|
||||
pOut->mat[10] = cosf(radians);
|
||||
pOut->mat[11] = 0.0f;
|
||||
|
||||
pOut->mat[12] = 0.0f;
|
||||
pOut->mat[13] = 0.0f;
|
||||
pOut->mat[14] = 0.0f;
|
||||
pOut->mat[15] = 1.0f;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a rotation matrix using the rotation around the Y-axis
|
||||
* The result is stored in pOut, pOut is returned.
|
||||
*/
|
||||
kmMat4* const kmMat4RotationY(kmMat4* pOut, const float radians)
|
||||
{
|
||||
/*
|
||||
| cos(A) 0 sin(A) 0 |
|
||||
M = | 0 1 0 0 |
|
||||
| -sin(A) 0 cos(A) 0 |
|
||||
| 0 0 0 1 |
|
||||
*/
|
||||
|
||||
pOut->mat[0] = cosf(radians);
|
||||
pOut->mat[1] = 0.0f;
|
||||
pOut->mat[2] = -sinf(radians);
|
||||
pOut->mat[3] = 0.0f;
|
||||
|
||||
pOut->mat[4] = 0.0f;
|
||||
pOut->mat[5] = 1.0f;
|
||||
pOut->mat[6] = 0.0f;
|
||||
pOut->mat[7] = 0.0f;
|
||||
|
||||
pOut->mat[8] = sinf(radians);
|
||||
pOut->mat[9] = 0.0f;
|
||||
pOut->mat[10] = cosf(radians);
|
||||
pOut->mat[11] = 0.0f;
|
||||
|
||||
pOut->mat[12] = 0.0f;
|
||||
pOut->mat[13] = 0.0f;
|
||||
pOut->mat[14] = 0.0f;
|
||||
pOut->mat[15] = 1.0f;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a rotation matrix around the Z-axis. The resulting
|
||||
* matrix is stored in pOut. pOut is returned.
|
||||
*/
|
||||
kmMat4* const kmMat4RotationZ(kmMat4* pOut, const float radians)
|
||||
{
|
||||
/*
|
||||
| cos(A) -sin(A) 0 0 |
|
||||
M = | sin(A) cos(A) 0 0 |
|
||||
| 0 0 1 0 |
|
||||
| 0 0 0 1 |
|
||||
*/
|
||||
|
||||
pOut->mat[0] = cosf(radians);
|
||||
pOut->mat[1] = sinf(radians);
|
||||
pOut->mat[2] = 0.0f;
|
||||
pOut->mat[3] = 0.0f;
|
||||
|
||||
pOut->mat[4] = -sinf(radians);;
|
||||
pOut->mat[5] = cosf(radians);
|
||||
pOut->mat[6] = 0.0f;
|
||||
pOut->mat[7] = 0.0f;
|
||||
|
||||
pOut->mat[8] = 0.0f;
|
||||
pOut->mat[9] = 0.0f;
|
||||
pOut->mat[10] = 1.0f;
|
||||
pOut->mat[11] = 0.0f;
|
||||
|
||||
pOut->mat[12] = 0.0f;
|
||||
pOut->mat[13] = 0.0f;
|
||||
pOut->mat[14] = 0.0f;
|
||||
pOut->mat[15] = 1.0f;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a rotation matrix from pitch, yaw and roll. The resulting
|
||||
* matrix is stored in pOut and pOut is returned
|
||||
*/
|
||||
kmMat4* const kmMat4RotationPitchYawRoll(kmMat4* pOut, const kmScalar pitch, const kmScalar yaw, const kmScalar roll)
|
||||
{
|
||||
double cr = cos(pitch);
|
||||
double sr = sin(pitch);
|
||||
double cp = cos(yaw);
|
||||
double sp = sin(yaw);
|
||||
double cy = cos(roll);
|
||||
double sy = sin(roll);
|
||||
double srsp = sr * sp;
|
||||
double crsp = cr * sp;
|
||||
|
||||
pOut->mat[0] = (kmScalar) cp * cy;
|
||||
pOut->mat[4] = (kmScalar) cp * sy;
|
||||
pOut->mat[8] = (kmScalar) - sp;
|
||||
|
||||
pOut->mat[1] = (kmScalar) srsp * cy - cr * sy;
|
||||
pOut->mat[5] = (kmScalar) srsp * sy + cr * cy;
|
||||
pOut->mat[9] = (kmScalar) sr * cp;
|
||||
|
||||
pOut->mat[2] = (kmScalar) crsp * cy + sr * sy;
|
||||
pOut->mat[6] = (kmScalar) crsp * sy - sr * cy;
|
||||
pOut->mat[10] = (kmScalar) cr * cp;
|
||||
|
||||
pOut->mat[3] = pOut->mat[7] = pOut->mat[11] = 0.0;
|
||||
pOut->mat[15] = 1.0;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/** Converts a quaternion to a rotation matrix,
|
||||
* the result is stored in pOut, returns pOut
|
||||
*/
|
||||
kmMat4* const kmMat4RotationQuaternion(kmMat4* pOut, const kmQuaternion* pQ)
|
||||
{
|
||||
pOut->mat[0] = 1.0f - 2.0f * (pQ->y * pQ->y + pQ->z * pQ->z );
|
||||
pOut->mat[1] = 2.0f * (pQ->x * pQ->y + pQ->z * pQ->w);
|
||||
pOut->mat[2] = 2.0f * (pQ->x * pQ->z - pQ->y * pQ->w);
|
||||
pOut->mat[3] = 0.0f;
|
||||
|
||||
// Second row
|
||||
pOut->mat[4] = 2.0f * ( pQ->x * pQ->y - pQ->z * pQ->w );
|
||||
pOut->mat[5] = 1.0f - 2.0f * ( pQ->x * pQ->x + pQ->z * pQ->z );
|
||||
pOut->mat[6] = 2.0f * (pQ->z * pQ->y + pQ->x * pQ->w );
|
||||
pOut->mat[7] = 0.0f;
|
||||
|
||||
// Third row
|
||||
pOut->mat[8] = 2.0f * ( pQ->x * pQ->z + pQ->y * pQ->w );
|
||||
pOut->mat[9] = 2.0f * ( pQ->y * pQ->z - pQ->x * pQ->w );
|
||||
pOut->mat[10] = 1.0f - 2.0f * ( pQ->x * pQ->x + pQ->y * pQ->y );
|
||||
pOut->mat[11] = 0.0f;
|
||||
|
||||
// Fourth row
|
||||
pOut->mat[12] = 0;
|
||||
pOut->mat[13] = 0;
|
||||
pOut->mat[14] = 0;
|
||||
pOut->mat[15] = 1.0f;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/** Builds a scaling matrix */
|
||||
kmMat4* const kmMat4Scaling(kmMat4* pOut, const kmScalar x, const kmScalar y,
|
||||
const kmScalar z)
|
||||
{
|
||||
memset(pOut->mat, 0, sizeof(float) * 16);
|
||||
pOut->mat[0] = x;
|
||||
pOut->mat[5] = y;
|
||||
pOut->mat[10] = z;
|
||||
pOut->mat[15] = 1.0f;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a translation matrix. All other elements in the matrix
|
||||
* will be set to zero except for the diagonal which is set to 1.0
|
||||
*/
|
||||
kmMat4* const kmMat4Translation(kmMat4* pOut, const kmScalar x,
|
||||
const kmScalar y, const kmScalar z)
|
||||
{
|
||||
//FIXME: Write a test for this
|
||||
memset(pOut->mat, 0, sizeof(float) * 16);
|
||||
|
||||
pOut->mat[0] = 1.0f;
|
||||
pOut->mat[5] = 1.0f;
|
||||
pOut->mat[10] = 1.0f;
|
||||
|
||||
pOut->mat[12] = x;
|
||||
pOut->mat[13] = y;
|
||||
pOut->mat[14] = z;
|
||||
pOut->mat[15] = 1.0f;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the up vector from a matrix. pIn is the matrix you
|
||||
* wish to extract the vector from. pOut is a pointer to the
|
||||
* kmVec3 structure that should hold the resulting vector
|
||||
*/
|
||||
kmVec3* const kmMat4GetUpVec3(kmVec3* pOut, const kmMat4* pIn)
|
||||
{
|
||||
pOut->x = pIn->mat[4];
|
||||
pOut->y = pIn->mat[5];
|
||||
pOut->z = pIn->mat[6];
|
||||
|
||||
kmVec3Normalize(pOut, pOut);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/** Extract the right vector from a 4x4 matrix. The result is
|
||||
* stored in pOut. Returns pOut.
|
||||
*/
|
||||
kmVec3* const kmMat4GetRightVec3(kmVec3* pOut, const kmMat4* pIn)
|
||||
{
|
||||
pOut->x = pIn->mat[0];
|
||||
pOut->y = pIn->mat[1];
|
||||
pOut->z = pIn->mat[2];
|
||||
|
||||
kmVec3Normalize(pOut, pOut);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the forward vector from a 4x4 matrix. The result is
|
||||
* stored in pOut. Returns pOut.
|
||||
*/
|
||||
kmVec3* const kmMat4GetForwardVec3(kmVec3* pOut, const kmMat4* pIn)
|
||||
{
|
||||
pOut->x = pIn->mat[8];
|
||||
pOut->y = pIn->mat[9];
|
||||
pOut->z = pIn->mat[10];
|
||||
|
||||
kmVec3Normalize(pOut, pOut);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a perspective projection matrix in the
|
||||
* same way as gluPerspective
|
||||
*/
|
||||
kmMat4* const kmMat4PerspectiveProjection(kmMat4* pOut, kmScalar fovY,
|
||||
kmScalar aspect, kmScalar zNear,
|
||||
kmScalar zFar)
|
||||
{
|
||||
kmScalar r = kmDegreesToRadians(fovY / 2);
|
||||
kmScalar deltaZ = zFar - zNear;
|
||||
kmScalar s = sin(r);
|
||||
kmScalar cotangent = 0;
|
||||
|
||||
if (deltaZ == 0 || s == 0 || aspect == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//cos(r) / sin(r) = cot(r)
|
||||
cotangent = cos(r) / s;
|
||||
|
||||
kmMat4Identity(pOut);
|
||||
pOut->mat[0] = cotangent / aspect;
|
||||
pOut->mat[5] = cotangent;
|
||||
pOut->mat[10] = -(zFar + zNear) / deltaZ;
|
||||
pOut->mat[11] = -1;
|
||||
pOut->mat[14] = -2 * zNear * zFar / deltaZ;
|
||||
pOut->mat[15] = 0;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/** Creates an orthographic projection matrix like glOrtho */
|
||||
kmMat4* const kmMat4OrthographicProjection(kmMat4* pOut, kmScalar left,
|
||||
kmScalar right, kmScalar bottom,
|
||||
kmScalar top, kmScalar nearVal,
|
||||
kmScalar farVal)
|
||||
{
|
||||
kmScalar tx = -((right + left) / (right - left));
|
||||
kmScalar ty = -((top + bottom) / (top - bottom));
|
||||
kmScalar tz = -((farVal + nearVal) / (farVal - nearVal));
|
||||
|
||||
kmMat4Identity(pOut);
|
||||
pOut->mat[0] = 2 / (right - left);
|
||||
pOut->mat[5] = 2 / (top - bottom);
|
||||
pOut->mat[10] = -2 / (farVal - nearVal);
|
||||
pOut->mat[12] = tx;
|
||||
pOut->mat[13] = ty;
|
||||
pOut->mat[14] = tz;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a translation matrix in the same way as gluLookAt()
|
||||
* the resulting matrix is stored in pOut. pOut is returned.
|
||||
*/
|
||||
kmMat4* const kmMat4LookAt(kmMat4* pOut, const kmVec3* pEye,
|
||||
const kmVec3* pCenter, const kmVec3* pUp)
|
||||
{
|
||||
kmVec3 f, up, s, u;
|
||||
kmMat4 translate;
|
||||
|
||||
kmVec3Subtract(&f, pCenter, pEye);
|
||||
kmVec3Normalize(&f, &f);
|
||||
|
||||
kmVec3Assign(&up, pUp);
|
||||
kmVec3Normalize(&up, &up);
|
||||
|
||||
kmVec3Cross(&s, &f, &up);
|
||||
kmVec3Normalize(&s, &s);
|
||||
|
||||
kmVec3Cross(&u, &s, &f);
|
||||
kmVec3Normalize(&s, &s);
|
||||
|
||||
kmMat4Identity(pOut);
|
||||
|
||||
pOut->mat[0] = s.x;
|
||||
pOut->mat[4] = s.y;
|
||||
pOut->mat[8] = s.z;
|
||||
|
||||
pOut->mat[1] = u.x;
|
||||
pOut->mat[5] = u.y;
|
||||
pOut->mat[9] = u.z;
|
||||
|
||||
pOut->mat[2] = -f.x;
|
||||
pOut->mat[6] = -f.y;
|
||||
pOut->mat[10] = -f.z;
|
||||
|
||||
kmMat4Translation(&translate, -pEye->x, -pEye->y, -pEye->z);
|
||||
kmMat4Multiply(pOut, pOut, &translate);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract a 3x3 rotation matrix from the input 4x4 transformation.
|
||||
* Stores the result in pOut, returns pOut
|
||||
*/
|
||||
kmMat3* const kmMat4ExtractRotation(kmMat3* pOut, const kmMat4* pIn)
|
||||
{
|
||||
pOut->mat[0] = pIn->mat[0];
|
||||
pOut->mat[1] = pIn->mat[1];
|
||||
pOut->mat[2] = pIn->mat[2];
|
||||
|
||||
pOut->mat[3] = pIn->mat[4];
|
||||
pOut->mat[4] = pIn->mat[5];
|
||||
pOut->mat[5] = pIn->mat[6];
|
||||
|
||||
pOut->mat[6] = pIn->mat[8];
|
||||
pOut->mat[7] = pIn->mat[9];
|
||||
pOut->mat[8] = pIn->mat[10];
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Take the rotation from a 4x4 transformation matrix, and return it as an axis and an angle (in radians)
|
||||
* returns the output axis.
|
||||
*/
|
||||
kmVec3* const kmMat4RotationToAxisAngle(kmVec3* pAxis, kmScalar* radians, const kmMat4* pIn)
|
||||
{
|
||||
/*Surely not this easy?*/
|
||||
kmQuaternion temp;
|
||||
kmMat3 rotation;
|
||||
kmMat4ExtractRotation(&rotation, pIn);
|
||||
kmQuaternionRotationMatrix(&temp, &rotation);
|
||||
kmQuaternionToAxisAngle(&temp, pAxis, radians);
|
||||
return pAxis;
|
||||
}
|
||||
|
||||
/** Build a 4x4 OpenGL transformation matrix using a 3x3 rotation matrix,
|
||||
* and a 3d vector representing a translation. Assign the result to pOut,
|
||||
* pOut is also returned.
|
||||
*/
|
||||
kmMat4* const kmMat4RotationTranslation(kmMat4* pOut, const kmMat3* rotation, const kmVec3* translation)
|
||||
{
|
||||
pOut->mat[0] = rotation->mat[0];
|
||||
pOut->mat[1] = rotation->mat[1];
|
||||
pOut->mat[2] = rotation->mat[2];
|
||||
pOut->mat[3] = 0.0f;
|
||||
|
||||
pOut->mat[4] = rotation->mat[3];
|
||||
pOut->mat[5] = rotation->mat[4];
|
||||
pOut->mat[6] = rotation->mat[5];
|
||||
pOut->mat[7] = 0.0f;
|
||||
|
||||
pOut->mat[8] = rotation->mat[6];
|
||||
pOut->mat[9] = rotation->mat[7];
|
||||
pOut->mat[10] = rotation->mat[8];
|
||||
pOut->mat[11] = 0.0f;
|
||||
|
||||
pOut->mat[12] = translation->x;
|
||||
pOut->mat[13] = translation->y;
|
||||
pOut->mat[14] = translation->z;
|
||||
pOut->mat[15] = 1.0f;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmPlane* const kmMat4ExtractPlane(kmPlane* pOut, const kmMat4* pIn, const kmEnum plane)
|
||||
{
|
||||
float t = 1.0f;
|
||||
|
||||
switch(plane) {
|
||||
case KM_PLANE_RIGHT:
|
||||
pOut->a = pIn->mat[3] - pIn->mat[0];
|
||||
pOut->b = pIn->mat[7] - pIn->mat[4];
|
||||
pOut->c = pIn->mat[11] - pIn->mat[8];
|
||||
pOut->d = pIn->mat[15] - pIn->mat[12];
|
||||
break;
|
||||
case KM_PLANE_LEFT:
|
||||
pOut->a = pIn->mat[3] + pIn->mat[0];
|
||||
pOut->b = pIn->mat[7] + pIn->mat[4];
|
||||
pOut->c = pIn->mat[11] + pIn->mat[8];
|
||||
pOut->d = pIn->mat[15] + pIn->mat[12];
|
||||
break;
|
||||
case KM_PLANE_BOTTOM:
|
||||
pOut->a = pIn->mat[3] + pIn->mat[1];
|
||||
pOut->b = pIn->mat[7] + pIn->mat[5];
|
||||
pOut->c = pIn->mat[11] + pIn->mat[9];
|
||||
pOut->d = pIn->mat[15] + pIn->mat[13];
|
||||
break;
|
||||
case KM_PLANE_TOP:
|
||||
pOut->a = pIn->mat[3] - pIn->mat[1];
|
||||
pOut->b = pIn->mat[7] - pIn->mat[5];
|
||||
pOut->c = pIn->mat[11] - pIn->mat[9];
|
||||
pOut->d = pIn->mat[15] - pIn->mat[13];
|
||||
break;
|
||||
case KM_PLANE_FAR:
|
||||
pOut->a = pIn->mat[3] - pIn->mat[2];
|
||||
pOut->b = pIn->mat[7] - pIn->mat[6];
|
||||
pOut->c = pIn->mat[11] - pIn->mat[10];
|
||||
pOut->d = pIn->mat[15] - pIn->mat[14];
|
||||
break;
|
||||
case KM_PLANE_NEAR:
|
||||
pOut->a = pIn->mat[3] + pIn->mat[2];
|
||||
pOut->b = pIn->mat[7] + pIn->mat[6];
|
||||
pOut->c = pIn->mat[11] + pIn->mat[10];
|
||||
pOut->d = pIn->mat[15] + pIn->mat[14];
|
||||
break;
|
||||
default:
|
||||
assert(0 && "Invalid plane index");
|
||||
}
|
||||
|
||||
t = sqrtf(pOut->a * pOut->a +
|
||||
pOut->b * pOut->b +
|
||||
pOut->c * pOut->c);
|
||||
pOut->a /= t;
|
||||
pOut->b /= t;
|
||||
pOut->c /= t;
|
||||
pOut->d /= t;
|
||||
|
||||
return pOut;
|
||||
}
|
|
@ -1,175 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2008, Luke Benstead.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "kazmath/vec3.h"
|
||||
#include "kazmath/vec4.h"
|
||||
#include "kazmath/plane.h"
|
||||
|
||||
const kmScalar kmPlaneDot(const kmPlane* pP, const kmVec4* pV)
|
||||
{
|
||||
//a*x + b*y + c*z + d*w
|
||||
|
||||
return (pP->a * pV->x +
|
||||
pP->b * pV->y +
|
||||
pP->c * pV->z +
|
||||
pP->d * pV->w);
|
||||
}
|
||||
|
||||
const kmScalar kmPlaneDotCoord(const kmPlane* pP, const kmVec3* pV)
|
||||
{
|
||||
return (pP->a * pV->x +
|
||||
pP->b * pV->y +
|
||||
pP->c * pV->z + pP->d);
|
||||
}
|
||||
|
||||
const kmScalar kmPlaneDotNormal(const kmPlane* pP, const kmVec3* pV)
|
||||
{
|
||||
return (pP->a * pV->x +
|
||||
pP->b * pV->y +
|
||||
pP->c * pV->z);
|
||||
}
|
||||
|
||||
kmPlane* const kmPlaneFromPointNormal(kmPlane* pOut, const kmVec3* pPoint, const kmVec3* pNormal)
|
||||
{
|
||||
/*
|
||||
Planea = Nx
|
||||
Planeb = Ny
|
||||
Planec = Nz
|
||||
Planed = −N⋅P
|
||||
*/
|
||||
|
||||
|
||||
pOut->a = pNormal->x;
|
||||
pOut->b = pNormal->y;
|
||||
pOut->c = pNormal->z;
|
||||
pOut->d = -kmVec3Dot(pNormal, pPoint);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a plane from 3 points. The result is stored in pOut.
|
||||
* pOut is returned.
|
||||
*/
|
||||
kmPlane* const kmPlaneFromPoints(kmPlane* pOut, const kmVec3* p1, const kmVec3* p2, const kmVec3* p3)
|
||||
{
|
||||
/*
|
||||
v = (B − A) × (C − A)
|
||||
n = 1⁄|v| v
|
||||
Outa = nx
|
||||
Outb = ny
|
||||
Outc = nz
|
||||
Outd = −n⋅A
|
||||
*/
|
||||
|
||||
kmVec3 n, v1, v2;
|
||||
kmVec3Subtract(&v1, p2, p1); //Create the vectors for the 2 sides of the triangle
|
||||
kmVec3Subtract(&v2, p3, p1);
|
||||
kmVec3Cross(&n, &v1, &v2); //Use the cross product to get the normal
|
||||
|
||||
kmVec3Normalize(&n, &n); //Normalize it and assign to pOut->m_N
|
||||
|
||||
pOut->a = n.x;
|
||||
pOut->b = n.y;
|
||||
pOut->c = n.z;
|
||||
pOut->d = kmVec3Dot(kmVec3Scale(&n, &n, -1.0), p1);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec3* const kmPlaneIntersectLine(kmVec3* pOut, const kmPlane* pP, const kmVec3* pV1, const kmVec3* pV2)
|
||||
{
|
||||
/*
|
||||
n = (Planea, Planeb, Planec)
|
||||
d = V − U
|
||||
Out = U − d⋅(Pd + n⋅U)⁄(d⋅n) [iff d⋅n ≠ 0]
|
||||
*/
|
||||
kmVec3 d;
|
||||
assert(0 && "Not implemented");
|
||||
|
||||
|
||||
kmVec3Subtract(&d, pV2, pV1); //Get the direction vector
|
||||
|
||||
|
||||
//TODO: Continue here!
|
||||
/*if (fabs(kmVec3Dot(&pP->m_N, &d)) > kmEpsilon)
|
||||
{
|
||||
//If we get here then the plane and line are parallel (i.e. no intersection)
|
||||
pOut = nullptr; //Set to nullptr
|
||||
|
||||
return pOut;
|
||||
} */
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
kmPlane* const kmPlaneNormalize(kmPlane* pOut, const kmPlane* pP)
|
||||
{
|
||||
kmVec3 n;
|
||||
kmScalar l = 0;
|
||||
|
||||
n.x = pP->a;
|
||||
n.y = pP->b;
|
||||
n.z = pP->c;
|
||||
|
||||
l = 1.0f / kmVec3Length(&n); //Get 1/length
|
||||
kmVec3Normalize(&n, &n); //Normalize the vector and assign to pOut
|
||||
|
||||
pOut->a = n.x;
|
||||
pOut->b = n.y;
|
||||
pOut->c = n.z;
|
||||
|
||||
pOut->d = pP->d * l; //Scale the D value and assign to pOut
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmPlane* const kmPlaneScale(kmPlane* pOut, const kmPlane* pP, kmScalar s)
|
||||
{
|
||||
assert(0 && "Not implemented");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns POINT_INFRONT_OF_PLANE if pP is infront of pIn. Returns
|
||||
* POINT_BEHIND_PLANE if it is behind. Returns POINT_ON_PLANE otherwise
|
||||
*/
|
||||
const POINT_CLASSIFICATION kmPlaneClassifyPoint(const kmPlane* pIn, const kmVec3* pP)
|
||||
{
|
||||
// This function will determine if a point is on, in front of, or behind
|
||||
// the plane. First we store the dot product of the plane and the point.
|
||||
float distance = pIn->a * pP->x + pIn->b * pP->y + pIn->c * pP->z + pIn->d;
|
||||
|
||||
// Simply put if the dot product is greater than 0 then it is infront of it.
|
||||
// If it is less than 0 then it is behind it. And if it is 0 then it is on it.
|
||||
if(distance > 0.001) return POINT_INFRONT_OF_PLANE;
|
||||
if(distance < -0.001) return POINT_BEHIND_PLANE;
|
||||
|
||||
return POINT_ON_PLANE;
|
||||
}
|
||||
|
|
@ -1,586 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2008, Luke Benstead.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <memory.h>
|
||||
|
||||
#include "kazmath/utility.h"
|
||||
#include "kazmath/mat3.h"
|
||||
#include "kazmath/vec3.h"
|
||||
#include "kazmath/quaternion.h"
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL ((void *)0)
|
||||
#endif
|
||||
|
||||
///< Returns pOut, sets pOut to the conjugate of pIn
|
||||
kmQuaternion* const kmQuaternionConjugate(kmQuaternion* pOut, const kmQuaternion* pIn)
|
||||
{
|
||||
pOut->x = -pIn->x;
|
||||
pOut->y = -pIn->y;
|
||||
pOut->z = -pIn->z;
|
||||
pOut->w = pIn->w;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
///< Returns the dot product of the 2 quaternions
|
||||
const kmScalar kmQuaternionDot(const kmQuaternion* q1, const kmQuaternion* q2)
|
||||
{
|
||||
// A dot B = B dot A = AtBt + AxBx + AyBy + AzBz
|
||||
|
||||
return (q1->w * q2->w +
|
||||
q1->x * q2->x +
|
||||
q1->y * q2->y +
|
||||
q1->z * q2->z);
|
||||
}
|
||||
|
||||
///< Returns the exponential of the quaternion
|
||||
kmQuaternion* kmQuaternionExp(kmQuaternion* pOut, const kmQuaternion* pIn)
|
||||
{
|
||||
assert(0);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
///< Makes the passed quaternion an identity quaternion
|
||||
kmQuaternion* kmQuaternionIdentity(kmQuaternion* pOut)
|
||||
{
|
||||
pOut->x = 0.0;
|
||||
pOut->y = 0.0;
|
||||
pOut->z = 0.0;
|
||||
pOut->w = 1.0;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
///< Returns the inverse of the passed Quaternion
|
||||
kmQuaternion* kmQuaternionInverse(kmQuaternion* pOut,
|
||||
const kmQuaternion* pIn)
|
||||
{
|
||||
kmScalar l = kmQuaternionLength(pIn);
|
||||
kmQuaternion tmp;
|
||||
|
||||
if (fabs(l) > kmEpsilon)
|
||||
{
|
||||
pOut->x = 0.0;
|
||||
pOut->y = 0.0;
|
||||
pOut->z = 0.0;
|
||||
pOut->w = 0.0;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
|
||||
|
||||
///Get the conjugute and divide by the length
|
||||
kmQuaternionScale(pOut,
|
||||
kmQuaternionConjugate(&tmp, pIn), 1.0f / l);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
///< Returns true if the quaternion is an identity quaternion
|
||||
int kmQuaternionIsIdentity(const kmQuaternion* pIn)
|
||||
{
|
||||
return (pIn->x == 0.0 && pIn->y == 0.0 && pIn->z == 0.0 &&
|
||||
pIn->w == 1.0);
|
||||
}
|
||||
|
||||
///< Returns the length of the quaternion
|
||||
kmScalar kmQuaternionLength(const kmQuaternion* pIn)
|
||||
{
|
||||
return sqrtf(kmQuaternionLengthSq(pIn));
|
||||
}
|
||||
|
||||
///< Returns the length of the quaternion squared (prevents a sqrt)
|
||||
kmScalar kmQuaternionLengthSq(const kmQuaternion* pIn)
|
||||
{
|
||||
return pIn->x * pIn->x + pIn->y * pIn->y +
|
||||
pIn->z * pIn->z + pIn->w * pIn->w;
|
||||
}
|
||||
|
||||
///< Returns the natural logarithm
|
||||
kmQuaternion* kmQuaternionLn(kmQuaternion* pOut,
|
||||
const kmQuaternion* pIn)
|
||||
{
|
||||
/*
|
||||
A unit quaternion, is defined by:
|
||||
Q == (cos(theta), sin(theta) * v) where |v| = 1
|
||||
The natural logarithm of Q is, ln(Q) = (0, theta * v)
|
||||
*/
|
||||
|
||||
assert(0);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
///< Multiplies 2 quaternions together
|
||||
extern
|
||||
kmQuaternion* kmQuaternionMultiply(kmQuaternion* pOut,
|
||||
const kmQuaternion* q1,
|
||||
const kmQuaternion* q2)
|
||||
{
|
||||
pOut->w = q1->w * q2->w - q1->x * q2->x - q1->y * q2->y - q1->z * q2->z;
|
||||
pOut->x = q1->w * q2->x + q1->x * q2->w + q1->y * q2->z - q1->z * q2->y;
|
||||
pOut->y = q1->w * q2->y + q1->y * q2->w + q1->z * q2->x - q1->x * q2->z;
|
||||
pOut->z = q1->w * q2->z + q1->z * q2->w + q1->x * q2->y - q1->y * q2->x;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
///< Normalizes a quaternion
|
||||
kmQuaternion* kmQuaternionNormalize(kmQuaternion* pOut,
|
||||
const kmQuaternion* pIn)
|
||||
{
|
||||
kmScalar length = kmQuaternionLength(pIn);
|
||||
assert(fabs(length) > kmEpsilon);
|
||||
kmQuaternionScale(pOut, pIn, 1.0f / length);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
///< Rotates a quaternion around an axis
|
||||
kmQuaternion* kmQuaternionRotationAxis(kmQuaternion* pOut,
|
||||
const kmVec3* pV,
|
||||
kmScalar angle)
|
||||
{
|
||||
kmScalar rad = angle * 0.5f;
|
||||
kmScalar scale = sinf(rad);
|
||||
|
||||
pOut->w = cosf(rad);
|
||||
pOut->x = pV->x * scale;
|
||||
pOut->y = pV->y * scale;
|
||||
pOut->z = pV->z * scale;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
///< Creates a quaternion from a rotation matrix
|
||||
kmQuaternion* kmQuaternionRotationMatrix(kmQuaternion* pOut,
|
||||
const kmMat3* pIn)
|
||||
{
|
||||
/*
|
||||
Note: The OpenGL matrices are transposed from the description below
|
||||
taken from the Matrix and Quaternion FAQ
|
||||
|
||||
if ( mat[0] > mat[5] && mat[0] > mat[10] ) { // Column 0:
|
||||
S = sqrt( 1.0 + mat[0] - mat[5] - mat[10] ) * 2;
|
||||
X = 0.25 * S;
|
||||
Y = (mat[4] + mat[1] ) / S;
|
||||
Z = (mat[2] + mat[8] ) / S;
|
||||
W = (mat[9] - mat[6] ) / S;
|
||||
} else if ( mat[5] > mat[10] ) { // Column 1:
|
||||
S = sqrt( 1.0 + mat[5] - mat[0] - mat[10] ) * 2;
|
||||
X = (mat[4] + mat[1] ) / S;
|
||||
Y = 0.25 * S;
|
||||
Z = (mat[9] + mat[6] ) / S;
|
||||
W = (mat[2] - mat[8] ) / S;
|
||||
} else { // Column 2:
|
||||
S = sqrt( 1.0 + mat[10] - mat[0] - mat[5] ) * 2;
|
||||
X = (mat[2] + mat[8] ) / S;
|
||||
Y = (mat[9] + mat[6] ) / S;
|
||||
Z = 0.25 * S;
|
||||
W = (mat[4] - mat[1] ) / S;
|
||||
}
|
||||
*/
|
||||
|
||||
float x, y, z, w;
|
||||
float *pMatrix = NULL;
|
||||
float m4x4[16] = {0};
|
||||
float scale = 0.0f;
|
||||
float diagonal = 0.0f;
|
||||
|
||||
if(!pIn) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* 0 3 6
|
||||
1 4 7
|
||||
2 5 8
|
||||
|
||||
0 1 2 3
|
||||
4 5 6 7
|
||||
8 9 10 11
|
||||
12 13 14 15*/
|
||||
|
||||
m4x4[0] = pIn->mat[0];
|
||||
m4x4[1] = pIn->mat[3];
|
||||
m4x4[2] = pIn->mat[6];
|
||||
m4x4[4] = pIn->mat[1];
|
||||
m4x4[5] = pIn->mat[4];
|
||||
m4x4[6] = pIn->mat[7];
|
||||
m4x4[8] = pIn->mat[2];
|
||||
m4x4[9] = pIn->mat[5];
|
||||
m4x4[10] = pIn->mat[8];
|
||||
m4x4[15] = 1;
|
||||
pMatrix = &m4x4[0];
|
||||
|
||||
diagonal = pMatrix[0] + pMatrix[5] + pMatrix[10] + 1;
|
||||
|
||||
if(diagonal > kmEpsilon) {
|
||||
// Calculate the scale of the diagonal
|
||||
scale = (float)sqrt(diagonal ) * 2;
|
||||
|
||||
// Calculate the x, y, x and w of the quaternion through the respective equation
|
||||
x = ( pMatrix[9] - pMatrix[6] ) / scale;
|
||||
y = ( pMatrix[2] - pMatrix[8] ) / scale;
|
||||
z = ( pMatrix[4] - pMatrix[1] ) / scale;
|
||||
w = 0.25f * scale;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the first element of the diagonal is the greatest value
|
||||
if ( pMatrix[0] > pMatrix[5] && pMatrix[0] > pMatrix[10] )
|
||||
{
|
||||
// Find the scale according to the first element, and double that value
|
||||
scale = (float)sqrt( 1.0f + pMatrix[0] - pMatrix[5] - pMatrix[10] ) * 2.0f;
|
||||
|
||||
// Calculate the x, y, x and w of the quaternion through the respective equation
|
||||
x = 0.25f * scale;
|
||||
y = (pMatrix[4] + pMatrix[1] ) / scale;
|
||||
z = (pMatrix[2] + pMatrix[8] ) / scale;
|
||||
w = (pMatrix[9] - pMatrix[6] ) / scale;
|
||||
}
|
||||
// Else if the second element of the diagonal is the greatest value
|
||||
else if (pMatrix[5] > pMatrix[10])
|
||||
{
|
||||
// Find the scale according to the second element, and double that value
|
||||
scale = (float)sqrt( 1.0f + pMatrix[5] - pMatrix[0] - pMatrix[10] ) * 2.0f;
|
||||
|
||||
// Calculate the x, y, x and w of the quaternion through the respective equation
|
||||
x = (pMatrix[4] + pMatrix[1] ) / scale;
|
||||
y = 0.25f * scale;
|
||||
z = (pMatrix[9] + pMatrix[6] ) / scale;
|
||||
w = (pMatrix[2] - pMatrix[8] ) / scale;
|
||||
}
|
||||
// Else the third element of the diagonal is the greatest value
|
||||
else
|
||||
{
|
||||
// Find the scale according to the third element, and double that value
|
||||
scale = (float)sqrt( 1.0f + pMatrix[10] - pMatrix[0] - pMatrix[5] ) * 2.0f;
|
||||
|
||||
// Calculate the x, y, x and w of the quaternion through the respective equation
|
||||
x = (pMatrix[2] + pMatrix[8] ) / scale;
|
||||
y = (pMatrix[9] + pMatrix[6] ) / scale;
|
||||
z = 0.25f * scale;
|
||||
w = (pMatrix[4] - pMatrix[1] ) / scale;
|
||||
}
|
||||
}
|
||||
|
||||
pOut->x = x;
|
||||
pOut->y = y;
|
||||
pOut->z = z;
|
||||
pOut->w = w;
|
||||
|
||||
return pOut;
|
||||
|
||||
#if 0
|
||||
kmScalar T = pIn->mat[0] + pIn->mat[5] + pIn->mat[10];
|
||||
|
||||
if (T > kmEpsilon) {
|
||||
//If the trace is greater than zero we always use this calculation:
|
||||
/* S = sqrt(T) * 2;
|
||||
X = ( mat[9] - mat[6] ) / S;
|
||||
Y = ( mat[2] - mat[8] ) / S;
|
||||
Z = ( mat[4] - mat[1] ) / S;
|
||||
W = 0.25 * S;*/
|
||||
|
||||
/* kmScalar s = sqrtf(T) * 2;
|
||||
pOut->x = (pIn->mat[9] - pIn->mat[6]) / s;
|
||||
pOut->y = (pIn->mat[8] - pIn->mat[2]) / s;
|
||||
pOut->z = (pIn->mat[1] - pIn->mat[4]) / s;
|
||||
pOut->w = 0.25f * s;
|
||||
|
||||
kmQuaternionNormalize(pOut, pOut);
|
||||
return pOut;
|
||||
}
|
||||
|
||||
//Otherwise the calculation depends on which major diagonal element has the greatest value.
|
||||
|
||||
if (pIn->mat[0] > pIn->mat[5] && pIn->mat[0] > pIn->mat[10]) {
|
||||
kmScalar s = sqrtf(1 + pIn->mat[0] - pIn->mat[5] - pIn->mat[10]) * 2;
|
||||
pOut->x = 0.25f * s;
|
||||
pOut->y = (pIn->mat[1] + pIn->mat[4]) / s;
|
||||
pOut->z = (pIn->mat[8] + pIn->mat[2]) / s;
|
||||
pOut->w = (pIn->mat[9] - pIn->mat[6]) / s;
|
||||
}
|
||||
else if (pIn->mat[5] > pIn->mat[10]) {
|
||||
kmScalar s = sqrtf(1 + pIn->mat[5] - pIn->mat[0] - pIn->mat[10]) * 2;
|
||||
pOut->x = (pIn->mat[1] + pIn->mat[4]) / s;
|
||||
pOut->y = 0.25f * s;
|
||||
pOut->z = (pIn->mat[9] + pIn->mat[6]) / s;
|
||||
pOut->w = (pIn->mat[8] - pIn->mat[2]) / s;
|
||||
}
|
||||
else {
|
||||
kmScalar s = sqrt(1.0f + pIn->mat[10] - pIn->mat[0] - pIn->mat[5]) * 2.0f;
|
||||
pOut->x = (pIn->mat[8] + pIn->mat[2] ) / s;
|
||||
pOut->y = (pIn->mat[6] + pIn->mat[9] ) / s;
|
||||
pOut->z = 0.25f * s;
|
||||
pOut->w = (pIn->mat[1] - pIn->mat[4] ) / s;
|
||||
}
|
||||
|
||||
kmQuaternionNormalize(pOut, pOut);
|
||||
return pOut;*/
|
||||
#endif // 0
|
||||
}
|
||||
|
||||
///< Create a quaternion from yaw, pitch and roll
|
||||
kmQuaternion* kmQuaternionRotationYawPitchRoll(kmQuaternion* pOut,
|
||||
kmScalar yaw,
|
||||
kmScalar pitch,
|
||||
kmScalar roll)
|
||||
{
|
||||
kmScalar ex, ey, ez; // temp half euler angles
|
||||
kmScalar cr, cp, cy, sr, sp, sy, cpcy, spsy; // temp vars in roll,pitch yaw
|
||||
|
||||
ex = kmDegreesToRadians(pitch) / 2.0f; // convert to rads and half them
|
||||
ey = kmDegreesToRadians(yaw) / 2.0f;
|
||||
ez = kmDegreesToRadians(roll) / 2.0f;
|
||||
|
||||
cr = cosf(ex);
|
||||
cp = cosf(ey);
|
||||
cy = cosf(ez);
|
||||
|
||||
sr = sinf(ex);
|
||||
sp = sinf(ey);
|
||||
sy = sinf(ez);
|
||||
|
||||
cpcy = cp * cy;
|
||||
spsy = sp * sy;
|
||||
|
||||
pOut->w = cr * cpcy + sr * spsy;
|
||||
|
||||
pOut->x = sr * cpcy - cr * spsy;
|
||||
pOut->y = cr * sp * cy + sr * cp * sy;
|
||||
pOut->z = cr * cp * sy - sr * sp * cy;
|
||||
|
||||
kmQuaternionNormalize(pOut, pOut);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
///< Interpolate between 2 quaternions
|
||||
kmQuaternion* kmQuaternionSlerp(kmQuaternion* pOut,
|
||||
const kmQuaternion* q1,
|
||||
const kmQuaternion* q2,
|
||||
kmScalar t)
|
||||
{
|
||||
|
||||
/*float CosTheta = Q0.DotProd(Q1);
|
||||
float Theta = acosf(CosTheta);
|
||||
float SinTheta = sqrtf(1.0f-CosTheta*CosTheta);
|
||||
|
||||
float Sin_T_Theta = sinf(T*Theta)/SinTheta;
|
||||
float Sin_OneMinusT_Theta = sinf((1.0f-T)*Theta)/SinTheta;
|
||||
|
||||
Quaternion Result = Q0*Sin_OneMinusT_Theta;
|
||||
Result += (Q1*Sin_T_Theta);
|
||||
|
||||
return Result;*/
|
||||
|
||||
if (q1->x == q2->x &&
|
||||
q1->y == q2->y &&
|
||||
q1->z == q2->z &&
|
||||
q1->w == q2->w) {
|
||||
|
||||
pOut->x = q1->x;
|
||||
pOut->y = q1->y;
|
||||
pOut->z = q1->z;
|
||||
pOut->w = q1->w;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
{
|
||||
kmScalar ct = kmQuaternionDot(q1, q2);
|
||||
kmScalar theta = acosf(ct);
|
||||
kmScalar st = sqrtf(1.0 - kmSQR(ct));
|
||||
|
||||
kmScalar stt = sinf(t * theta) / st;
|
||||
kmScalar somt = sinf((1.0 - t) * theta) / st;
|
||||
|
||||
kmQuaternion temp, temp2;
|
||||
kmQuaternionScale(&temp, q1, somt);
|
||||
kmQuaternionScale(&temp2, q2, stt);
|
||||
kmQuaternionAdd(pOut, &temp, &temp2);
|
||||
}
|
||||
return pOut;
|
||||
}
|
||||
|
||||
///< Get the axis and angle of rotation from a quaternion
|
||||
void kmQuaternionToAxisAngle(const kmQuaternion* pIn,
|
||||
kmVec3* pAxis,
|
||||
kmScalar* pAngle)
|
||||
{
|
||||
kmScalar tempAngle; // temp angle
|
||||
kmScalar scale; // temp vars
|
||||
|
||||
tempAngle = acosf(pIn->w);
|
||||
scale = sqrtf(kmSQR(pIn->x) + kmSQR(pIn->y) + kmSQR(pIn->z));
|
||||
|
||||
if (((scale > -kmEpsilon) && scale < kmEpsilon)
|
||||
|| (scale < 2*kmPI + kmEpsilon && scale > 2*kmPI - kmEpsilon)) // angle is 0 or 360 so just simply set axis to 0,0,1 with angle 0
|
||||
{
|
||||
*pAngle = 0.0f;
|
||||
|
||||
pAxis->x = 0.0f;
|
||||
pAxis->y = 0.0f;
|
||||
pAxis->z = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pAngle = tempAngle * 2.0f; // angle in radians
|
||||
|
||||
pAxis->x = pIn->x / scale;
|
||||
pAxis->y = pIn->y / scale;
|
||||
pAxis->z = pIn->z / scale;
|
||||
kmVec3Normalize(pAxis, pAxis);
|
||||
}
|
||||
}
|
||||
|
||||
kmQuaternion* kmQuaternionScale(kmQuaternion* pOut,
|
||||
const kmQuaternion* pIn,
|
||||
kmScalar s)
|
||||
{
|
||||
pOut->x = pIn->x * s;
|
||||
pOut->y = pIn->y * s;
|
||||
pOut->z = pIn->z * s;
|
||||
pOut->w = pIn->w * s;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmQuaternion* kmQuaternionAssign(kmQuaternion* pOut, const kmQuaternion* pIn)
|
||||
{
|
||||
memcpy(pOut, pIn, sizeof(float) * 4);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmQuaternion* kmQuaternionAdd(kmQuaternion* pOut, const kmQuaternion* pQ1, const kmQuaternion* pQ2)
|
||||
{
|
||||
pOut->x = pQ1->x + pQ2->x;
|
||||
pOut->y = pQ1->y + pQ2->y;
|
||||
pOut->z = pQ1->z + pQ2->z;
|
||||
pOut->w = pQ1->w + pQ2->w;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/** Adapted from the OGRE engine!
|
||||
|
||||
Gets the shortest arc quaternion to rotate this vector to the destination
|
||||
vector.
|
||||
@remarks
|
||||
If you call this with a dest vector that is close to the inverse
|
||||
of this vector, we will rotate 180 degrees around the 'fallbackAxis'
|
||||
(if specified, or a generated axis if not) since in this case
|
||||
ANY axis of rotation is valid.
|
||||
*/
|
||||
|
||||
kmQuaternion* kmQuaternionRotationBetweenVec3(kmQuaternion* pOut, const kmVec3* vec1, const kmVec3* vec2, const kmVec3* fallback) {
|
||||
|
||||
kmVec3 v1, v2;
|
||||
kmScalar a;
|
||||
|
||||
kmVec3Assign(&v1, vec1);
|
||||
kmVec3Assign(&v2, vec2);
|
||||
|
||||
kmVec3Normalize(&v1, &v1);
|
||||
kmVec3Normalize(&v2, &v2);
|
||||
|
||||
a = kmVec3Dot(&v1, &v2);
|
||||
|
||||
if (a >= 1.0) {
|
||||
kmQuaternionIdentity(pOut);
|
||||
return pOut;
|
||||
}
|
||||
|
||||
if (a < (1e-6f - 1.0f)) {
|
||||
if (fabs(kmVec3LengthSq(fallback)) < kmEpsilon) {
|
||||
kmQuaternionRotationAxis(pOut, fallback, kmPI);
|
||||
} else {
|
||||
kmVec3 axis;
|
||||
kmVec3 X;
|
||||
X.x = 1.0;
|
||||
X.y = 0.0;
|
||||
X.z = 0.0;
|
||||
|
||||
|
||||
kmVec3Cross(&axis, &X, vec1);
|
||||
|
||||
//If axis is zero
|
||||
if (fabs(kmVec3LengthSq(&axis)) < kmEpsilon) {
|
||||
kmVec3 Y;
|
||||
Y.x = 0.0;
|
||||
Y.y = 1.0;
|
||||
Y.z = 0.0;
|
||||
|
||||
kmVec3Cross(&axis, &Y, vec1);
|
||||
}
|
||||
|
||||
kmVec3Normalize(&axis, &axis);
|
||||
|
||||
kmQuaternionRotationAxis(pOut, &axis, kmPI);
|
||||
}
|
||||
} else {
|
||||
kmScalar s = sqrtf((1+a) * 2);
|
||||
kmScalar invs = 1 / s;
|
||||
|
||||
kmVec3 c;
|
||||
kmVec3Cross(&c, &v1, &v2);
|
||||
|
||||
pOut->x = c.x * invs;
|
||||
pOut->y = c.y * invs;
|
||||
pOut->z = c.z * invs;
|
||||
pOut->w = s * 0.5f;
|
||||
|
||||
kmQuaternionNormalize(pOut, pOut);
|
||||
}
|
||||
|
||||
return pOut;
|
||||
|
||||
}
|
||||
|
||||
kmVec3* kmQuaternionMultiplyVec3(kmVec3* pOut, const kmQuaternion* q, const kmVec3* v) {
|
||||
kmVec3 uv, uuv, qvec;
|
||||
|
||||
qvec.x = q->x;
|
||||
qvec.y = q->y;
|
||||
qvec.z = q->z;
|
||||
|
||||
kmVec3Cross(&uv, &qvec, v);
|
||||
kmVec3Cross(&uuv, &qvec, &uv);
|
||||
|
||||
kmVec3Scale(&uv, &uv, (2.0f * q->w));
|
||||
kmVec3Scale(&uuv, &uuv, 2.0f);
|
||||
|
||||
kmVec3Add(pOut, v, &uv);
|
||||
kmVec3Add(pOut, pOut, &uuv);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
|
@ -1,186 +0,0 @@
|
|||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include "kazmath/ray2.h"
|
||||
|
||||
void kmRay2Fill(kmRay2* ray, kmScalar px, kmScalar py, kmScalar vx, kmScalar vy) {
|
||||
ray->start.x = px;
|
||||
ray->start.y = py;
|
||||
ray->dir.x = vx;
|
||||
ray->dir.y = vy;
|
||||
}
|
||||
|
||||
kmBool kmRay2IntersectLineSegment(const kmRay2* ray, const kmVec2* p1, const kmVec2* p2, kmVec2* intersection) {
|
||||
|
||||
float x1 = ray->start.x;
|
||||
float y1 = ray->start.y;
|
||||
float x2 = ray->start.x + ray->dir.x;
|
||||
float y2 = ray->start.y + ray->dir.y;
|
||||
float x3 = p1->x;
|
||||
float y3 = p1->y;
|
||||
float x4 = p2->x;
|
||||
float y4 = p2->y;
|
||||
|
||||
float denom = (y4 -y3) * (x2 - x1) - (x4 - x3) * (y2 - y1);
|
||||
float ua, x, y;
|
||||
//If denom is zero, the lines are parallel
|
||||
if(denom > -kmEpsilon && denom < kmEpsilon) {
|
||||
return KM_FALSE;
|
||||
}
|
||||
|
||||
ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / denom;
|
||||
// float ub = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / denom;
|
||||
|
||||
x = x1 + ua * (x2 - x1);
|
||||
y = y1 + ua * (y2 - y1);
|
||||
|
||||
if(x < kmMin(p1->x, p2->x) - kmEpsilon ||
|
||||
x > kmMax(p1->x, p2->x) + kmEpsilon ||
|
||||
y < kmMin(p1->y, p2->y) - kmEpsilon ||
|
||||
y > kmMax(p1->y, p2->y) + kmEpsilon) {
|
||||
//Outside of line
|
||||
//printf("Outside of line, %f %f (%f %f)(%f, %f)\n", x, y, p1->x, p1->y, p2->x, p2->y);
|
||||
return KM_FALSE;
|
||||
}
|
||||
|
||||
if(x < kmMin(x1, x2) - kmEpsilon ||
|
||||
x > kmMax(x1, x2) + kmEpsilon ||
|
||||
y < kmMin(y1, y2) - kmEpsilon ||
|
||||
y > kmMax(y1, y2) + kmEpsilon) {
|
||||
//printf("Outside of ray, %f %f (%f %f)(%f, %f)\n", x, y, x1, y1, x2, y2);
|
||||
return KM_FALSE;
|
||||
}
|
||||
|
||||
intersection->x = x;
|
||||
intersection->y = y;
|
||||
|
||||
return KM_TRUE;
|
||||
|
||||
|
||||
/*
|
||||
kmScalar A1, B1, C1;
|
||||
kmScalar A2, B2, C2;
|
||||
|
||||
A1 = ray->dir.y;
|
||||
B1 = ray->dir.x;
|
||||
C1 = A1 * ray->start.x + B1 * ray->start.y;
|
||||
|
||||
A2 = p2->y - p1->y;
|
||||
B2 = p2->x - p1->x;
|
||||
C2 = A2 * p1->x + B2 * p1->y;
|
||||
|
||||
double det = (A1 * B2) - (A2 * B1);
|
||||
if(det == 0) {
|
||||
printf("Parallel\n");
|
||||
return KM_FALSE;
|
||||
}
|
||||
|
||||
double x = (B2*C1 - B1*C2) / det;
|
||||
double y = (A1*C2 - A2*C1) / det;
|
||||
|
||||
if(x < min(p1->x, p2->x) - kmEpsilon ||
|
||||
x > max(p1->x, p2->x) + kmEpsilon ||
|
||||
y < min(p1->y, p2->y) - kmEpsilon ||
|
||||
y > max(p1->y, p2->y) + kmEpsilon) {
|
||||
//Outside of line
|
||||
printf("Outside of line, %f %f (%f %f)(%f, %f)\n", x, y, p1->x, p1->y, p2->x, p2->y);
|
||||
return KM_FALSE;
|
||||
}
|
||||
|
||||
kmScalar x1 = ray->start.x;
|
||||
kmScalar x2 = ray->start.x + ray->dir.x;
|
||||
|
||||
kmScalar y1 = ray->start.y;
|
||||
kmScalar y2 = ray->start.y + ray->dir.y;
|
||||
|
||||
if(x < min(x1, x2) - kmEpsilon ||
|
||||
x > max(x1, x2) + kmEpsilon ||
|
||||
y < min(y1, y2) - kmEpsilon ||
|
||||
y > max(y1, y2) + kmEpsilon) {
|
||||
printf("Outside of ray, %f %f (%f %f)(%f, %f)\n", x, y, x1, y1, x2, y2);
|
||||
return KM_FALSE;
|
||||
}
|
||||
|
||||
intersection->x = x;
|
||||
intersection->y = y;
|
||||
|
||||
return KM_TRUE;*/
|
||||
}
|
||||
|
||||
void calculate_line_normal(kmVec2 p1, kmVec2 p2, kmVec2* normal_out) {
|
||||
kmVec2 tmp;
|
||||
kmVec2Subtract(&tmp, &p2, &p1); //Get direction vector
|
||||
|
||||
normal_out->x = -tmp.y;
|
||||
normal_out->y = tmp.x;
|
||||
kmVec2Normalize(normal_out, normal_out);
|
||||
|
||||
//TODO: should check that the normal is pointing out of the triangle
|
||||
}
|
||||
|
||||
kmBool kmRay2IntersectTriangle(const kmRay2* ray, const kmVec2* p1, const kmVec2* p2, const kmVec2* p3, kmVec2* intersection, kmVec2* normal_out) {
|
||||
kmVec2 intersect;
|
||||
kmVec2 final_intersect = {0., 0.}, normal = {0., 0.}; // Silencing LLVM SA.
|
||||
kmScalar distance = 10000.0f;
|
||||
kmBool intersected = KM_FALSE;
|
||||
|
||||
if(kmRay2IntersectLineSegment(ray, p1, p2, &intersect)) {
|
||||
kmVec2 tmp;
|
||||
kmScalar this_distance;
|
||||
|
||||
intersected = KM_TRUE;
|
||||
this_distance = kmVec2Length(kmVec2Subtract(&tmp, &intersect, &ray->start));
|
||||
if(this_distance < distance) {
|
||||
final_intersect.x = intersect.x;
|
||||
final_intersect.y = intersect.y;
|
||||
distance = this_distance;
|
||||
|
||||
calculate_line_normal(*p1, *p2, &normal);
|
||||
}
|
||||
}
|
||||
|
||||
if(kmRay2IntersectLineSegment(ray, p2, p3, &intersect)) {
|
||||
kmVec2 tmp;
|
||||
kmScalar this_distance;
|
||||
intersected = KM_TRUE;
|
||||
|
||||
this_distance = kmVec2Length(kmVec2Subtract(&tmp, &intersect, &ray->start));
|
||||
if(this_distance < distance) {
|
||||
final_intersect.x = intersect.x;
|
||||
final_intersect.y = intersect.y;
|
||||
distance = this_distance;
|
||||
|
||||
calculate_line_normal(*p2, *p3, &normal);
|
||||
}
|
||||
}
|
||||
|
||||
if(kmRay2IntersectLineSegment(ray, p3, p1, &intersect)) {
|
||||
kmVec2 tmp;
|
||||
kmScalar this_distance;
|
||||
intersected = KM_TRUE;
|
||||
|
||||
this_distance = kmVec2Length(kmVec2Subtract(&tmp, &intersect, &ray->start));
|
||||
if(this_distance < distance) {
|
||||
final_intersect.x = intersect.x;
|
||||
final_intersect.y = intersect.y;
|
||||
//distance = this_distance;
|
||||
|
||||
calculate_line_normal(*p3, *p1, &normal);
|
||||
}
|
||||
}
|
||||
|
||||
if(intersected) {
|
||||
intersection->x = final_intersect.x;
|
||||
intersection->y = final_intersect.y;
|
||||
if(normal_out) {
|
||||
normal_out->x = normal.x;
|
||||
normal_out->y = normal.y;
|
||||
}
|
||||
}
|
||||
|
||||
return intersected;
|
||||
}
|
||||
|
||||
kmBool kmRay2IntersectCircle(const kmRay2* ray, const kmVec2 centre, const kmScalar radius, kmVec2* intersection) {
|
||||
assert(0 && "Not implemented");
|
||||
return 0;
|
||||
}
|
|
@ -1,118 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2008, Luke Benstead.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "kazmath/mat3.h"
|
||||
#include "kazmath/vec2.h"
|
||||
#include "kazmath/utility.h"
|
||||
|
||||
kmVec2* kmVec2Fill(kmVec2* pOut, kmScalar x, kmScalar y)
|
||||
{
|
||||
pOut->x = x;
|
||||
pOut->y = y;
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmScalar kmVec2Length(const kmVec2* pIn)
|
||||
{
|
||||
return sqrtf(kmSQR(pIn->x) + kmSQR(pIn->y));
|
||||
}
|
||||
|
||||
kmScalar kmVec2LengthSq(const kmVec2* pIn)
|
||||
{
|
||||
return kmSQR(pIn->x) + kmSQR(pIn->y);
|
||||
}
|
||||
|
||||
kmVec2* kmVec2Normalize(kmVec2* pOut, const kmVec2* pIn)
|
||||
{
|
||||
kmScalar l = 1.0f / kmVec2Length(pIn);
|
||||
|
||||
kmVec2 v;
|
||||
v.x = pIn->x * l;
|
||||
v.y = pIn->y * l;
|
||||
|
||||
pOut->x = v.x;
|
||||
pOut->y = v.y;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec2* kmVec2Add(kmVec2* pOut, const kmVec2* pV1, const kmVec2* pV2)
|
||||
{
|
||||
pOut->x = pV1->x + pV2->x;
|
||||
pOut->y = pV1->y + pV2->y;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmScalar kmVec2Dot(const kmVec2* pV1, const kmVec2* pV2)
|
||||
{
|
||||
return pV1->x * pV2->x + pV1->y * pV2->y;
|
||||
}
|
||||
|
||||
kmVec2* kmVec2Subtract(kmVec2* pOut, const kmVec2* pV1, const kmVec2* pV2)
|
||||
{
|
||||
pOut->x = pV1->x - pV2->x;
|
||||
pOut->y = pV1->y - pV2->y;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec2* kmVec2Transform(kmVec2* pOut, const kmVec2* pV, const kmMat3* pM)
|
||||
{
|
||||
kmVec2 v;
|
||||
|
||||
v.x = pV->x * pM->mat[0] + pV->y * pM->mat[3] + pM->mat[6];
|
||||
v.y = pV->x * pM->mat[1] + pV->y * pM->mat[4] + pM->mat[7];
|
||||
|
||||
pOut->x = v.x;
|
||||
pOut->y = v.y;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec2* kmVec2TransformCoord(kmVec2* pOut, const kmVec2* pV, const kmMat3* pM)
|
||||
{
|
||||
assert(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
kmVec2* kmVec2Scale(kmVec2* pOut, const kmVec2* pIn, const kmScalar s)
|
||||
{
|
||||
pOut->x = pIn->x * s;
|
||||
pOut->y = pIn->y * s;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
int kmVec2AreEqual(const kmVec2* p1, const kmVec2* p2)
|
||||
{
|
||||
return (
|
||||
(p1->x < p2->x + kmEpsilon && p1->x > p2->x - kmEpsilon) &&
|
||||
(p1->y < p2->y + kmEpsilon && p1->y > p2->y - kmEpsilon)
|
||||
);
|
||||
}
|
|
@ -1,310 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2008, Luke Benstead.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file vec3.c
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <memory.h>
|
||||
|
||||
#include "kazmath/utility.h"
|
||||
#include "kazmath/vec4.h"
|
||||
#include "kazmath/mat4.h"
|
||||
#include "kazmath/vec3.h"
|
||||
|
||||
/**
|
||||
* Fill a kmVec3 structure using 3 floating point values
|
||||
* The result is store in pOut, returns pOut
|
||||
*/
|
||||
kmVec3* kmVec3Fill(kmVec3* pOut, kmScalar x, kmScalar y, kmScalar z)
|
||||
{
|
||||
pOut->x = x;
|
||||
pOut->y = y;
|
||||
pOut->z = z;
|
||||
return pOut;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the length of the vector
|
||||
*/
|
||||
kmScalar kmVec3Length(const kmVec3* pIn)
|
||||
{
|
||||
return sqrtf(kmSQR(pIn->x) + kmSQR(pIn->y) + kmSQR(pIn->z));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the square of the length of the vector
|
||||
*/
|
||||
kmScalar kmVec3LengthSq(const kmVec3* pIn)
|
||||
{
|
||||
return kmSQR(pIn->x) + kmSQR(pIn->y) + kmSQR(pIn->z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the vector passed in set to unit length
|
||||
* the result is stored in pOut.
|
||||
*/
|
||||
kmVec3* kmVec3Normalize(kmVec3* pOut, const kmVec3* pIn)
|
||||
{
|
||||
kmScalar l = 1.0f / kmVec3Length(pIn);
|
||||
|
||||
kmVec3 v;
|
||||
v.x = pIn->x * l;
|
||||
v.y = pIn->y * l;
|
||||
v.z = pIn->z * l;
|
||||
|
||||
pOut->x = v.x;
|
||||
pOut->y = v.y;
|
||||
pOut->z = v.z;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a vector perpendicular to 2 other vectors.
|
||||
* The result is stored in pOut.
|
||||
*/
|
||||
kmVec3* kmVec3Cross(kmVec3* pOut, const kmVec3* pV1, const kmVec3* pV2)
|
||||
{
|
||||
|
||||
kmVec3 v;
|
||||
|
||||
v.x = (pV1->y * pV2->z) - (pV1->z * pV2->y);
|
||||
v.y = (pV1->z * pV2->x) - (pV1->x * pV2->z);
|
||||
v.z = (pV1->x * pV2->y) - (pV1->y * pV2->x);
|
||||
|
||||
pOut->x = v.x;
|
||||
pOut->y = v.y;
|
||||
pOut->z = v.z;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the cosine of the angle between 2 vectors
|
||||
*/
|
||||
kmScalar kmVec3Dot(const kmVec3* pV1, const kmVec3* pV2)
|
||||
{
|
||||
return ( pV1->x * pV2->x
|
||||
+ pV1->y * pV2->y
|
||||
+ pV1->z * pV2->z );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds 2 vectors and returns the result. The resulting
|
||||
* vector is stored in pOut.
|
||||
*/
|
||||
kmVec3* kmVec3Add(kmVec3* pOut, const kmVec3* pV1, const kmVec3* pV2)
|
||||
{
|
||||
kmVec3 v;
|
||||
|
||||
v.x = pV1->x + pV2->x;
|
||||
v.y = pV1->y + pV2->y;
|
||||
v.z = pV1->z + pV2->z;
|
||||
|
||||
pOut->x = v.x;
|
||||
pOut->y = v.y;
|
||||
pOut->z = v.z;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtracts 2 vectors and returns the result. The result is stored in
|
||||
* pOut.
|
||||
*/
|
||||
kmVec3* kmVec3Subtract(kmVec3* pOut, const kmVec3* pV1, const kmVec3* pV2)
|
||||
{
|
||||
kmVec3 v;
|
||||
|
||||
v.x = pV1->x - pV2->x;
|
||||
v.y = pV1->y - pV2->y;
|
||||
v.z = pV1->z - pV2->z;
|
||||
|
||||
pOut->x = v.x;
|
||||
pOut->y = v.y;
|
||||
pOut->z = v.z;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms vector (x, y, z, 1) by a given matrix. The result
|
||||
* is stored in pOut. pOut is returned.
|
||||
*/
|
||||
kmVec3* kmVec3Transform(kmVec3* pOut, const kmVec3* pV, const kmMat4* pM)
|
||||
{
|
||||
/*
|
||||
a = (Vx, Vy, Vz, 1)
|
||||
b = (a×M)T
|
||||
Out = (bx, by, bz)
|
||||
*/
|
||||
|
||||
kmVec3 v;
|
||||
|
||||
v.x = pV->x * pM->mat[0] + pV->y * pM->mat[4] + pV->z * pM->mat[8] + pM->mat[12];
|
||||
v.y = pV->x * pM->mat[1] + pV->y * pM->mat[5] + pV->z * pM->mat[9] + pM->mat[13];
|
||||
v.z = pV->x * pM->mat[2] + pV->y * pM->mat[6] + pV->z * pM->mat[10] + pM->mat[14];
|
||||
|
||||
pOut->x = v.x;
|
||||
pOut->y = v.y;
|
||||
pOut->z = v.z;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec3* kmVec3InverseTransform(kmVec3* pOut, const kmVec3* pVect, const kmMat4* pM)
|
||||
{
|
||||
kmVec3 v1, v2;
|
||||
|
||||
v1.x = pVect->x - pM->mat[12];
|
||||
v1.y = pVect->y - pM->mat[13];
|
||||
v1.z = pVect->z - pM->mat[14];
|
||||
|
||||
v2.x = v1.x * pM->mat[0] + v1.y * pM->mat[1] + v1.z * pM->mat[2];
|
||||
v2.y = v1.x * pM->mat[4] + v1.y * pM->mat[5] + v1.z * pM->mat[6];
|
||||
v2.z = v1.x * pM->mat[8] + v1.y * pM->mat[9] + v1.z * pM->mat[10];
|
||||
|
||||
pOut->x = v2.x;
|
||||
pOut->y = v2.y;
|
||||
pOut->z = v2.z;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec3* kmVec3InverseTransformNormal(kmVec3* pOut, const kmVec3* pVect, const kmMat4* pM)
|
||||
{
|
||||
kmVec3 v;
|
||||
|
||||
v.x = pVect->x * pM->mat[0] + pVect->y * pM->mat[1] + pVect->z * pM->mat[2];
|
||||
v.y = pVect->x * pM->mat[4] + pVect->y * pM->mat[5] + pVect->z * pM->mat[6];
|
||||
v.z = pVect->x * pM->mat[8] + pVect->y * pM->mat[9] + pVect->z * pM->mat[10];
|
||||
|
||||
pOut->x = v.x;
|
||||
pOut->y = v.y;
|
||||
pOut->z = v.z;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
|
||||
kmVec3* kmVec3TransformCoord(kmVec3* pOut, const kmVec3* pV, const kmMat4* pM)
|
||||
{
|
||||
/*
|
||||
a = (Vx, Vy, Vz, 1)
|
||||
b = (a×M)T
|
||||
Out = 1⁄bw(bx, by, bz)
|
||||
*/
|
||||
|
||||
kmVec4 v;
|
||||
kmVec4 inV;
|
||||
kmVec4Fill(&inV, pV->x, pV->y, pV->z, 1.0);
|
||||
|
||||
kmVec4Transform(&v, &inV,pM);
|
||||
|
||||
pOut->x = v.x / v.w;
|
||||
pOut->y = v.y / v.w;
|
||||
pOut->z = v.z / v.w;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec3* kmVec3TransformNormal(kmVec3* pOut, const kmVec3* pV, const kmMat4* pM)
|
||||
{
|
||||
/*
|
||||
a = (Vx, Vy, Vz, 0)
|
||||
b = (a×M)T
|
||||
Out = (bx, by, bz)
|
||||
*/
|
||||
//Omits the translation, only scaling + rotating
|
||||
kmVec3 v;
|
||||
|
||||
v.x = pV->x * pM->mat[0] + pV->y * pM->mat[4] + pV->z * pM->mat[8];
|
||||
v.y = pV->x * pM->mat[1] + pV->y * pM->mat[5] + pV->z * pM->mat[9];
|
||||
v.z = pV->x * pM->mat[2] + pV->y * pM->mat[6] + pV->z * pM->mat[10];
|
||||
|
||||
pOut->x = v.x;
|
||||
pOut->y = v.y;
|
||||
pOut->z = v.z;
|
||||
|
||||
return pOut;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Scales a vector to length s. Does not normalize first,
|
||||
* you should do that!
|
||||
*/
|
||||
kmVec3* kmVec3Scale(kmVec3* pOut, const kmVec3* pIn, const kmScalar s)
|
||||
{
|
||||
pOut->x = pIn->x * s;
|
||||
pOut->y = pIn->y * s;
|
||||
pOut->z = pIn->z * s;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns KM_TRUE if the 2 vectors are approximately equal
|
||||
*/
|
||||
int kmVec3AreEqual(const kmVec3* p1, const kmVec3* p2)
|
||||
{
|
||||
if ((p1->x < (p2->x + kmEpsilon) && p1->x > (p2->x - kmEpsilon)) &&
|
||||
(p1->y < (p2->y + kmEpsilon) && p1->y > (p2->y - kmEpsilon)) &&
|
||||
(p1->z < (p2->z + kmEpsilon) && p1->z > (p2->z - kmEpsilon))) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns pIn to pOut. Returns pOut. If pIn and pOut are the same
|
||||
* then nothing happens but pOut is still returned
|
||||
*/
|
||||
kmVec3* kmVec3Assign(kmVec3* pOut, const kmVec3* pIn) {
|
||||
if (pOut == pIn) {
|
||||
return pOut;
|
||||
}
|
||||
|
||||
pOut->x = pIn->x;
|
||||
pOut->y = pIn->y;
|
||||
pOut->z = pIn->z;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets all the elements of pOut to zero. Returns pOut.
|
||||
*/
|
||||
kmVec3* kmVec3Zero(kmVec3* pOut) {
|
||||
pOut->x = 0.0f;
|
||||
pOut->y = 0.0f;
|
||||
pOut->z = 0.0f;
|
||||
|
||||
return pOut;
|
||||
}
|
Loading…
Reference in New Issue