From 4fe3b16287f067da3a94e61303b538970de85585 Mon Sep 17 00:00:00 2001 From: Ricardo Quesada Date: Tue, 4 Mar 2014 16:33:00 -0800 Subject: [PATCH] Updates to latest version of kazmath --- .../project.pbxproj.REMOVED.git-id | 2 +- .../project.pbxproj.REMOVED.git-id | 2 +- cocos/2d/renderer/CCFrustum.cpp | 24 +- cocos/math/kazmath/include/kazmath/mat3.h | 76 -- cocos/math/kazmath/include/kazmath/mat4.h | 94 -- .../math/kazmath/include/kazmath/quaternion.h | 114 --- cocos/math/kazmath/include/kazmath/vec2.h | 66 -- cocos/math/kazmath/include/kazmath/vec3.h | 69 -- cocos/math/kazmath/kazmath/CMakeLists.txt | 18 + .../kazmath/{src => kazmath}/GL/mat4stack.c | 0 .../{include => }/kazmath/GL/mat4stack.h | 0 .../math/kazmath/{src => kazmath}/GL/matrix.c | 0 .../kazmath/{include => }/kazmath/GL/matrix.h | 0 cocos/math/kazmath/kazmath/aabb.c | 141 +++ .../math/kazmath/{include => }/kazmath/aabb.h | 17 +- .../kazmath/{include => }/kazmath/kazmath.h | 2 +- cocos/math/kazmath/kazmath/mat3.c | 458 ++++++++++ cocos/math/kazmath/kazmath/mat3.h | 85 ++ cocos/math/kazmath/kazmath/mat4.c | 805 ++++++++++++++++++ cocos/math/kazmath/kazmath/mat4.h | 96 +++ .../{src => kazmath}/neon_matrix_impl.c | 0 .../{include => }/kazmath/neon_matrix_impl.h | 0 cocos/math/kazmath/kazmath/plane.c | 254 ++++++ .../kazmath/{include => }/kazmath/plane.h | 36 +- cocos/math/kazmath/kazmath/quaternion.c | 609 +++++++++++++ cocos/math/kazmath/kazmath/quaternion.h | 125 +++ cocos/math/kazmath/kazmath/ray2.c | 200 +++++ .../math/kazmath/{include => }/kazmath/ray2.h | 13 +- cocos/math/kazmath/kazmath/ray3.c | 47 + cocos/math/kazmath/kazmath/ray3.h | 26 + cocos/math/kazmath/{src => kazmath}/utility.c | 18 +- .../kazmath/{include => }/kazmath/utility.h | 45 +- cocos/math/kazmath/kazmath/vec2.c | 239 ++++++ cocos/math/kazmath/kazmath/vec2.h | 78 ++ cocos/math/kazmath/kazmath/vec3.c | 444 ++++++++++ cocos/math/kazmath/kazmath/vec3.h | 87 ++ cocos/math/kazmath/{src => kazmath}/vec4.c | 116 ++- .../math/kazmath/{include => }/kazmath/vec4.h | 44 +- cocos/math/kazmath/src/CMakeLists.txt | 14 - cocos/math/kazmath/src/ChangeLog | 738 ---------------- cocos/math/kazmath/src/aabb.c | 63 -- cocos/math/kazmath/src/mat3.c | 372 -------- cocos/math/kazmath/src/mat4.c | 792 ----------------- cocos/math/kazmath/src/plane.c | 175 ---- cocos/math/kazmath/src/quaternion.c | 586 ------------- cocos/math/kazmath/src/ray2.c | 186 ---- cocos/math/kazmath/src/vec2.c | 118 --- cocos/math/kazmath/src/vec3.c | 310 ------- 48 files changed, 3910 insertions(+), 3894 deletions(-) delete mode 100644 cocos/math/kazmath/include/kazmath/mat3.h delete mode 100644 cocos/math/kazmath/include/kazmath/mat4.h delete mode 100644 cocos/math/kazmath/include/kazmath/quaternion.h delete mode 100644 cocos/math/kazmath/include/kazmath/vec2.h delete mode 100644 cocos/math/kazmath/include/kazmath/vec3.h create mode 100644 cocos/math/kazmath/kazmath/CMakeLists.txt rename cocos/math/kazmath/{src => kazmath}/GL/mat4stack.c (100%) rename cocos/math/kazmath/{include => }/kazmath/GL/mat4stack.h (100%) rename cocos/math/kazmath/{src => kazmath}/GL/matrix.c (100%) rename cocos/math/kazmath/{include => }/kazmath/GL/matrix.h (100%) create mode 100644 cocos/math/kazmath/kazmath/aabb.c rename cocos/math/kazmath/{include => }/kazmath/aabb.h (69%) rename cocos/math/kazmath/{include => }/kazmath/kazmath.h (98%) create mode 100644 cocos/math/kazmath/kazmath/mat3.c create mode 100644 cocos/math/kazmath/kazmath/mat3.h create mode 100644 cocos/math/kazmath/kazmath/mat4.c create mode 100644 cocos/math/kazmath/kazmath/mat4.h rename cocos/math/kazmath/{src => kazmath}/neon_matrix_impl.c (100%) rename cocos/math/kazmath/{include => }/kazmath/neon_matrix_impl.h (100%) create mode 100644 cocos/math/kazmath/kazmath/plane.c rename cocos/math/kazmath/{include => }/kazmath/plane.h (55%) create mode 100644 cocos/math/kazmath/kazmath/quaternion.c create mode 100644 cocos/math/kazmath/kazmath/quaternion.h create mode 100644 cocos/math/kazmath/kazmath/ray2.c rename cocos/math/kazmath/{include => }/kazmath/ray2.h (70%) create mode 100644 cocos/math/kazmath/kazmath/ray3.c create mode 100644 cocos/math/kazmath/kazmath/ray3.h rename cocos/math/kazmath/{src => kazmath}/utility.c (86%) rename cocos/math/kazmath/{include => }/kazmath/utility.h (66%) create mode 100644 cocos/math/kazmath/kazmath/vec2.c create mode 100644 cocos/math/kazmath/kazmath/vec2.h create mode 100644 cocos/math/kazmath/kazmath/vec3.c create mode 100644 cocos/math/kazmath/kazmath/vec3.h rename cocos/math/kazmath/{src => kazmath}/vec4.c (63%) rename cocos/math/kazmath/{include => }/kazmath/vec4.h (56%) delete mode 100644 cocos/math/kazmath/src/CMakeLists.txt delete mode 100644 cocos/math/kazmath/src/ChangeLog delete mode 100644 cocos/math/kazmath/src/aabb.c delete mode 100644 cocos/math/kazmath/src/mat3.c delete mode 100644 cocos/math/kazmath/src/mat4.c delete mode 100644 cocos/math/kazmath/src/plane.c delete mode 100644 cocos/math/kazmath/src/quaternion.c delete mode 100644 cocos/math/kazmath/src/ray2.c delete mode 100644 cocos/math/kazmath/src/vec2.c delete mode 100644 cocos/math/kazmath/src/vec3.c diff --git a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id index 0535c3667c..68c96346bc 100644 --- a/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/build/cocos2d_libs.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -8fad051dc33d390c01df304fee2a78e22785136f \ No newline at end of file +e8eaf27db3b5c75d371db6c73f434cea5c0f970d \ No newline at end of file diff --git a/build/cocos2d_tests.xcodeproj/project.pbxproj.REMOVED.git-id b/build/cocos2d_tests.xcodeproj/project.pbxproj.REMOVED.git-id index 8f178036e6..70f3d61cb2 100644 --- a/build/cocos2d_tests.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/build/cocos2d_tests.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -9da17496043155938cbd8973b01514f220e7192b \ No newline at end of file +d70aa2f168a737e7a152028e2156e3099e01c3aa \ No newline at end of file diff --git a/cocos/2d/renderer/CCFrustum.cpp b/cocos/2d/renderer/CCFrustum.cpp index 4f88e2356f..606fbef35b 100644 --- a/cocos/2d/renderer/CCFrustum.cpp +++ b/cocos/2d/renderer/CCFrustum.cpp @@ -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); } } diff --git a/cocos/math/kazmath/include/kazmath/mat3.h b/cocos/math/kazmath/include/kazmath/mat3.h deleted file mode 100644 index fc0668b20d..0000000000 --- a/cocos/math/kazmath/include/kazmath/mat3.h +++ /dev/null @@ -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 - diff --git a/cocos/math/kazmath/include/kazmath/mat4.h b/cocos/math/kazmath/include/kazmath/mat4.h deleted file mode 100644 index f8ad019d5f..0000000000 --- a/cocos/math/kazmath/include/kazmath/mat4.h +++ /dev/null @@ -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 */ diff --git a/cocos/math/kazmath/include/kazmath/quaternion.h b/cocos/math/kazmath/include/kazmath/quaternion.h deleted file mode 100644 index 2e9bb582c4..0000000000 --- a/cocos/math/kazmath/include/kazmath/quaternion.h +++ /dev/null @@ -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 diff --git a/cocos/math/kazmath/include/kazmath/vec2.h b/cocos/math/kazmath/include/kazmath/vec2.h deleted file mode 100644 index d8fdf82e41..0000000000 --- a/cocos/math/kazmath/include/kazmath/vec2.h +++ /dev/null @@ -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); /// - -#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 */ diff --git a/cocos/math/kazmath/kazmath/CMakeLists.txt b/cocos/math/kazmath/kazmath/CMakeLists.txt new file mode 100644 index 0000000000..f8ce917bb2 --- /dev/null +++ b/cocos/math/kazmath/kazmath/CMakeLists.txt @@ -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) diff --git a/cocos/math/kazmath/src/GL/mat4stack.c b/cocos/math/kazmath/kazmath/GL/mat4stack.c similarity index 100% rename from cocos/math/kazmath/src/GL/mat4stack.c rename to cocos/math/kazmath/kazmath/GL/mat4stack.c diff --git a/cocos/math/kazmath/include/kazmath/GL/mat4stack.h b/cocos/math/kazmath/kazmath/GL/mat4stack.h similarity index 100% rename from cocos/math/kazmath/include/kazmath/GL/mat4stack.h rename to cocos/math/kazmath/kazmath/GL/mat4stack.h diff --git a/cocos/math/kazmath/src/GL/matrix.c b/cocos/math/kazmath/kazmath/GL/matrix.c similarity index 100% rename from cocos/math/kazmath/src/GL/matrix.c rename to cocos/math/kazmath/kazmath/GL/matrix.c diff --git a/cocos/math/kazmath/include/kazmath/GL/matrix.h b/cocos/math/kazmath/kazmath/GL/matrix.h similarity index 100% rename from cocos/math/kazmath/include/kazmath/GL/matrix.h rename to cocos/math/kazmath/kazmath/GL/matrix.h diff --git a/cocos/math/kazmath/kazmath/aabb.c b/cocos/math/kazmath/kazmath/aabb.c new file mode 100644 index 0000000000..0c5ef54013 --- /dev/null +++ b/cocos/math/kazmath/kazmath/aabb.c @@ -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; +} + diff --git a/cocos/math/kazmath/include/kazmath/aabb.h b/cocos/math/kazmath/kazmath/aabb.h similarity index 69% rename from cocos/math/kazmath/include/kazmath/aabb.h rename to cocos/math/kazmath/kazmath/aabb.h index e26d9771da..785c1aa0ba 100644 --- a/cocos/math/kazmath/include/kazmath/aabb.h +++ b/cocos/math/kazmath/kazmath/aabb.h @@ -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 } diff --git a/cocos/math/kazmath/include/kazmath/kazmath.h b/cocos/math/kazmath/kazmath/kazmath.h similarity index 98% rename from cocos/math/kazmath/include/kazmath/kazmath.h rename to cocos/math/kazmath/kazmath/kazmath.h index fcd63b4e2e..3e1063d445 100644 --- a/cocos/math/kazmath/include/kazmath/kazmath.h +++ b/cocos/math/kazmath/kazmath/kazmath.h @@ -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 diff --git a/cocos/math/kazmath/kazmath/mat3.c b/cocos/math/kazmath/kazmath/mat3.c new file mode 100644 index 0000000000..328c044c51 --- /dev/null +++ b/cocos/math/kazmath/kazmath/mat3.c @@ -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 +#include +#include + +#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; +} diff --git a/cocos/math/kazmath/kazmath/mat3.h b/cocos/math/kazmath/kazmath/mat3.h new file mode 100644 index 0000000000..8f4e4b35c1 --- /dev/null +++ b/cocos/math/kazmath/kazmath/mat3.h @@ -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 diff --git a/cocos/math/kazmath/kazmath/mat4.c b/cocos/math/kazmath/kazmath/mat4.c new file mode 100644 index 0000000000..9765917195 --- /dev/null +++ b/cocos/math/kazmath/kazmath/mat4.c @@ -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 +#include +#include + +#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; +} diff --git a/cocos/math/kazmath/kazmath/mat4.h b/cocos/math/kazmath/kazmath/mat4.h new file mode 100644 index 0000000000..ecdcd662bb --- /dev/null +++ b/cocos/math/kazmath/kazmath/mat4.h @@ -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 */ diff --git a/cocos/math/kazmath/src/neon_matrix_impl.c b/cocos/math/kazmath/kazmath/neon_matrix_impl.c similarity index 100% rename from cocos/math/kazmath/src/neon_matrix_impl.c rename to cocos/math/kazmath/kazmath/neon_matrix_impl.c diff --git a/cocos/math/kazmath/include/kazmath/neon_matrix_impl.h b/cocos/math/kazmath/kazmath/neon_matrix_impl.h similarity index 100% rename from cocos/math/kazmath/include/kazmath/neon_matrix_impl.h rename to cocos/math/kazmath/kazmath/neon_matrix_impl.h diff --git a/cocos/math/kazmath/kazmath/plane.c b/cocos/math/kazmath/kazmath/plane.c new file mode 100644 index 0000000000..1eb5dbdba4 --- /dev/null +++ b/cocos/math/kazmath/kazmath/plane.c @@ -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 +#include + +#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; +} diff --git a/cocos/math/kazmath/include/kazmath/plane.h b/cocos/math/kazmath/kazmath/plane.h similarity index 55% rename from cocos/math/kazmath/include/kazmath/plane.h rename to cocos/math/kazmath/kazmath/plane.h index a01d5fd744..ed43b23d1b 100644 --- a/cocos/math/kazmath/include/kazmath/plane.h +++ b/cocos/math/kazmath/kazmath/plane.h @@ -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 } diff --git a/cocos/math/kazmath/kazmath/quaternion.c b/cocos/math/kazmath/kazmath/quaternion.c new file mode 100644 index 0000000000..21b122186e --- /dev/null +++ b/cocos/math/kazmath/kazmath/quaternion.c @@ -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 +#include +#include +#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);*/ +} diff --git a/cocos/math/kazmath/kazmath/quaternion.h b/cocos/math/kazmath/kazmath/quaternion.h new file mode 100644 index 0000000000..05ccc1f07f --- /dev/null +++ b/cocos/math/kazmath/kazmath/quaternion.h @@ -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 diff --git a/cocos/math/kazmath/kazmath/ray2.c b/cocos/math/kazmath/kazmath/ray2.c new file mode 100644 index 0000000000..08a2939a3f --- /dev/null +++ b/cocos/math/kazmath/kazmath/ray2.c @@ -0,0 +1,200 @@ +#include +#include +#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; +} diff --git a/cocos/math/kazmath/include/kazmath/ray2.h b/cocos/math/kazmath/kazmath/ray2.h similarity index 70% rename from cocos/math/kazmath/include/kazmath/ray2.h rename to cocos/math/kazmath/kazmath/ray2.h index c93c3b4a4e..5465cf2f04 100644 --- a/cocos/math/kazmath/include/kazmath/ray2.h +++ b/cocos/math/kazmath/kazmath/ray2.h @@ -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 } diff --git a/cocos/math/kazmath/kazmath/ray3.c b/cocos/math/kazmath/kazmath/ray3.c new file mode 100644 index 0000000000..4576bf3dfc --- /dev/null +++ b/cocos/math/kazmath/kazmath/ray3.c @@ -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; +} diff --git a/cocos/math/kazmath/kazmath/ray3.h b/cocos/math/kazmath/kazmath/ray3.h new file mode 100644 index 0000000000..30f5574229 --- /dev/null +++ b/cocos/math/kazmath/kazmath/ray3.h @@ -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 diff --git a/cocos/math/kazmath/src/utility.c b/cocos/math/kazmath/kazmath/utility.c similarity index 86% rename from cocos/math/kazmath/src/utility.c rename to cocos/math/kazmath/kazmath/utility.c index 067f40dcb8..62ab29f400 100644 --- a/cocos/math/kazmath/src/utility.c +++ b/cocos/math/kazmath/kazmath/utility.c @@ -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 ); +} diff --git a/cocos/math/kazmath/include/kazmath/utility.h b/cocos/math/kazmath/kazmath/utility.h similarity index 66% rename from cocos/math/kazmath/include/kazmath/utility.h rename to cocos/math/kazmath/kazmath/utility.h index 62b196be1c..175d27cd31 100644 --- a/cocos/math/kazmath/include/kazmath/utility.h +++ b/cocos/math/kazmath/kazmath/utility.h @@ -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 #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 } diff --git a/cocos/math/kazmath/kazmath/vec2.c b/cocos/math/kazmath/kazmath/vec2.c new file mode 100644 index 0000000000..c1ee20afef --- /dev/null +++ b/cocos/math/kazmath/kazmath/vec2.c @@ -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 +#include + +#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; +} diff --git a/cocos/math/kazmath/kazmath/vec2.h b/cocos/math/kazmath/kazmath/vec2.h new file mode 100644 index 0000000000..401358e624 --- /dev/null +++ b/cocos/math/kazmath/kazmath/vec2.h @@ -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); /// +#include + +#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; +} diff --git a/cocos/math/kazmath/kazmath/vec3.h b/cocos/math/kazmath/kazmath/vec3.h new file mode 100644 index 0000000000..a9eddbaced --- /dev/null +++ b/cocos/math/kazmath/kazmath/vec3.h @@ -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 +#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 */ diff --git a/cocos/math/kazmath/src/vec4.c b/cocos/math/kazmath/kazmath/vec4.c similarity index 63% rename from cocos/math/kazmath/src/vec4.c rename to cocos/math/kazmath/kazmath/vec4.c index bfe0414531..2efc88cb78 100644 --- a/cocos/math/kazmath/src/vec4.c +++ b/cocos/math/kazmath/kazmath/vec4.c @@ -27,9 +27,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include -#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; } diff --git a/cocos/math/kazmath/include/kazmath/vec4.h b/cocos/math/kazmath/kazmath/vec4.h similarity index 56% rename from cocos/math/kazmath/include/kazmath/vec4.h rename to cocos/math/kazmath/kazmath/vec4.h index ffdb70423d..dd6d6c7241 100644 --- a/cocos/math/kazmath/include/kazmath/vec4.h +++ b/cocos/math/kazmath/kazmath/vec4.h @@ -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 } diff --git a/cocos/math/kazmath/src/CMakeLists.txt b/cocos/math/kazmath/src/CMakeLists.txt deleted file mode 100644 index a38946641f..0000000000 --- a/cocos/math/kazmath/src/CMakeLists.txt +++ /dev/null @@ -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) diff --git a/cocos/math/kazmath/src/ChangeLog b/cocos/math/kazmath/src/ChangeLog deleted file mode 100644 index f13b823ac7..0000000000 --- a/cocos/math/kazmath/src/ChangeLog +++ /dev/null @@ -1,738 +0,0 @@ ------------------------------------------------------------- -revno: 111 -committer: Kazade -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 -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 -branch nick: kazmath -timestamp: Wed 2010-04-21 12:54:06 +0200 -message: - fixed kmMat4RotationAxis ------------------------------------------------------------- -revno: 108 [merge] -committer: Carsten Haubld -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 -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 -branch nick: kazmath -timestamp: Sat 2010-01-09 16:56:04 +0000 -message: - Add cmake module ------------------------------------------------------------- -revno: 105 -committer: Luke Benstead -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 -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 -branch nick: kazmath -timestamp: Mon 2009-08-31 11:21:42 +0200 -message: - Operators now inline, constructors fixed ------------------------------------------------------------- -revno: 102 -committer: Carsten Haubld -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 -branch nick: kazmath -timestamp: Wed 2009-08-26 10:37:52 +0100 -message: - Added the header defines ------------------------------------------------------------- -revno: 100 -committer: Luke Benstead -branch nick: kazmath -timestamp: Wed 2009-08-26 09:38:47 +0100 -message: - Added a V2 for kazmathxx ------------------------------------------------------------- -revno: 99 -committer: Luke Benstead -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 -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 -branch nick: kazmath -timestamp: Sat 2009-08-01 11:15:36 +0200 -message: - Fixed kmMat4Inverse ------------------------------------------------------------- -revno: 96 -committer: Luke Benstead -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 -branch nick: kazmath -timestamp: Sat 2009-08-01 09:17:01 +0100 -message: - Rename kmAABBPointInBox to kmAABBContainsPoint ------------------------------------------------------------- -revno: 94 -committer: Luke Benstead -branch nick: kazmath -timestamp: Sat 2009-08-01 09:16:28 +0100 -message: - Implement kmAABBPointInBox ------------------------------------------------------------- -revno: 93 -committer: Luke Benstead -branch nick: kazmath -timestamp: Sat 2009-08-01 09:14:00 +0100 -message: - Implement kmAABBAssign ------------------------------------------------------------- -revno: 92 -committer: Luke Benstead -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 -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 -branch nick: kazmath -timestamp: Sun 2009-07-05 07:55:45 +0100 -message: - Added kmMat3RotationX, kmMat3RotationY and kmMat3RotationZ ------------------------------------------------------------- -revno: 89 -committer: Carsten Haubld -branch nick: kazmath -timestamp: Sat 2009-06-27 09:38:20 +0200 -message: - Fixed a crash? ------------------------------------------------------------- -revno: 88 -committer: Luke Benstead -branch nick: kazmath -timestamp: Tue 2009-04-28 09:52:57 +0100 -message: - Added a test for kmMat4Transpose ------------------------------------------------------------- -revno: 87 -committer: Luke Benstead -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 -branch nick: kazmath -timestamp: Tue 2009-04-28 08:46:03 +0100 -message: - Fixed bug in kmQuaternionRotationMatrix ------------------------------------------------------------- -revno: 85 -committer: Luke Benstead -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 -branch nick: kazmath -timestamp: Mon 2009-04-27 22:59:08 +0200 -message: - fixed CMakeLists.txt for the tests ------------------------------------------------------------- -revno: 83 -committer: Luke Benstead -branch nick: kazmath -timestamp: Mon 2009-04-27 21:34:20 +0100 -message: - Added a test for kmMat3Translation ------------------------------------------------------------- -revno: 82 -committer: Luke Benstead -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 -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 -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 -branch nick: kazmath -timestamp: Mon 2009-04-27 18:57:28 +0100 -message: - Added a test for kmMat3IsIdentity ------------------------------------------------------------- -revno: 78 -committer: Luke Benstead -branch nick: kazmath -timestamp: Mon 2009-04-27 18:54:48 +0100 -message: - Added a test for kmMat3Identity ------------------------------------------------------------- -revno: 77 -committer: Luke Benstead -branch nick: kazmath -timestamp: Mon 2009-04-27 18:52:14 +0100 -message: - Added a test for kmMat3Fill ------------------------------------------------------------- -revno: 76 -committer: Luke Benstead -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 -branch nick: kazmath -timestamp: Mon 2009-04-27 11:08:43 +0100 -message: - Added mat4 test stub ------------------------------------------------------------- -revno: 74 -committer: Luke Benstead -branch nick: kazmath -timestamp: Mon 2009-04-27 11:06:12 +0100 -message: - Enabled unit testing in cmake ------------------------------------------------------------- -revno: 73 -committer: Luke Benstead -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 -branch nick: kazmath -timestamp: Mon 2009-04-27 10:37:34 +0100 -message: - Added stub mat3 test file ------------------------------------------------------------- -revno: 71 -committer: Luke Benstead -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 -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 -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 -branch nick: kazmath -timestamp: Sun 2009-04-26 12:34:27 +0100 -message: - Merge from upstream ------------------------------------------------------------- -revno: 67 -committer: Luke Benstead -branch nick: kazmath -timestamp: Sun 2009-04-26 12:33:43 +0100 -message: - Reorganized bzr ------------------------------------------------------------- -revno: 66 -committer: Luke Benstead -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 -branch nick: kazmath -timestamp: Sun 2009-04-26 09:57:19 +0100 -message: - Fixed some compilation errors ------------------------------------------------------------- -revno: 64 -committer: Luke Benstead -branch nick: kazmath -timestamp: Sun 2009-04-26 09:54:12 +0100 -message: - Added untested implementation of kmMat3RotationToAxisAngle ------------------------------------------------------------- -revno: 63 -committer: Luke Benstead -branch nick: kazmath -timestamp: Sun 2009-04-26 09:49:17 +0100 -message: - Added stub for kmMat3RotationToAxisAngle() ------------------------------------------------------------- -revno: 62 -committer: Luke Benstead -branch nick: kazmath -timestamp: Sun 2009-04-26 09:45:58 +0100 -message: - Corrected a typo ------------------------------------------------------------- -revno: 61 -committer: Luke Benstead -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 -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 -branch nick: kazmath -timestamp: Sat 2009-04-18 08:42:38 +0100 -message: - Added kmMat3RotationQuaternion ------------------------------------------------------------- -revno: 58 -committer: Carsten Haubld -branch nick: kazmath -timestamp: Sun 2009-04-05 11:58:29 +0200 -message: - Added mat3 ------------------------------------------------------------- -revno: 57 [merge] -committer: Carsten Haubld -branch nick: kazmath -timestamp: Sun 2009-04-05 11:54:15 +0200 -message: - Implemented mat4 and vec4 for kazmathxx ------------------------------------------------------------- -revno: 56 -committer: Carsten Haubld -branch nick: kazmath -timestamp: Sun 2009-04-05 11:53:07 +0200 -message: - Implemented mat4 and vec4 for kazmathxx ------------------------------------------------------------- -revno: 55 -committer: Carsten Haubld -branch nick: kazmath -timestamp: Fri 2009-03-13 16:46:26 +0100 -message: - added km::vec3 to kazmathxx ------------------------------------------------------------- -revno: 54 -committer: Carsten Haubld -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 -branch nick: kazmath -timestamp: Fri 2009-03-13 15:38:53 +0100 -message: - Added folder for kazmathxx ------------------------------------------------------------- -revno: 52 [merge] -committer: Luke Benstead -branch nick: trunk -timestamp: Fri 2009-03-13 14:04:32 +0000 -message: - Merge from upstream ------------------------------------------------------------- -revno: 51 -committer: Luke Benstead -branch nick: trunk -timestamp: Fri 2009-03-13 14:00:14 +0000 -message: - Fixed for C89 ------------------------------------------------------------- -revno: 50 -committer: Carsten Haubold -timestamp: Tue 2008-12-30 12:45:23 +0100 -message: - fixed kmGLTranslate ------------------------------------------------------------- -revno: 49 -committer: Carsten Haubold -timestamp: Tue 2008-12-30 12:15:27 +0100 -message: - fixed some stack memory leaks ------------------------------------------------------------- -revno: 48 -committer: Carsten Haubold -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 -timestamp: Tue 2008-12-30 10:52:28 +0100 -message: - Debug output ------------------------------------------------------------- -revno: 46 -committer: Carsten Haubold -timestamp: Mon 2008-12-29 18:32:13 +0100 -message: - Fixed some compiler errors ------------------------------------------------------------- -revno: 45 -committer: Luke -timestamp: Wed 2008-11-19 08:36:47 +0000 -message: - Added kmGLTranslatef, kmGLScalef and kmGLRotatef ------------------------------------------------------------- -revno: 44 -committer: Luke -timestamp: Tue 2008-11-04 20:57:30 +0000 -message: - Fixed up kazmathxx ------------------------------------------------------------- -revno: 43 -committer: Luke -timestamp: Wed 2008-10-29 09:24:32 +0000 -message: - Started implementing C++ operators in kazmathxx.h ------------------------------------------------------------- -revno: 42 -committer: Luke -timestamp: Tue 2008-10-28 18:21:16 +0000 -message: - Added kazmathxx.h for C++ usage ------------------------------------------------------------- -revno: 41 -committer: Luke -timestamp: Tue 2008-10-28 11:00:41 +0000 -message: - Added Doxygen documentation ------------------------------------------------------------- -revno: 40 -committer: Luke -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 -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 -timestamp: Tue 2008-10-28 08:38:48 +0000 -message: - - Documented utility.c ------------------------------------------------------------- -revno: 37 -committer: Luke -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 -timestamp: Tue 2008-10-28 08:30:00 +0000 -message: - Removed uneccessary files from git ------------------------------------------------------------- -revno: 35 -committer: Luke -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 -timestamp: Mon 2008-10-27 21:52:33 +0000 -message: - Added potential 0.1 release binary ------------------------------------------------------------- -revno: 33 -committer: Luke Benstead -timestamp: Mon 2008-10-27 21:46:55 +0000 -message: - Changed the README to include the BSD license ------------------------------------------------------------- -revno: 32 -committer: Luke Benstead -timestamp: Mon 2008-10-27 21:45:51 +0000 -message: - Added the modified BSD license to all source files ------------------------------------------------------------- -revno: 31 -committer: Luke Benstead -timestamp: Mon 2008-10-27 21:11:51 +0000 -message: - Fixed the installation of header files in CMake ------------------------------------------------------------- -revno: 30 -committer: Luke -timestamp: Mon 2008-10-27 21:05:51 +0000 -message: - Added kazmath project files ------------------------------------------------------------- -revno: 29 [merge] -committer: Luke -timestamp: Mon 2008-10-27 21:03:22 +0000 -message: - Merge branch 'master' of git@github.com:Kazade/kazmath ------------------------------------------------------------- -revno: 28 -committer: Luke -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 -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 -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 -timestamp: Sun 2008-10-26 20:59:34 +0000 -message: - Removed the old matrix stack stuff ------------------------------------------------------------- -revno: 24 -committer: Luke Benstead -timestamp: Sun 2008-10-26 20:11:58 +0000 -message: - Started implementing the matrix stack tests ------------------------------------------------------------- -revno: 23 -committer: Luke Benstead -timestamp: Sun 2008-10-26 10:56:51 +0000 -message: - Started new implementation of the GL matrix stack ------------------------------------------------------------- -revno: 22 -committer: Carsten Haubold -timestamp: Thu 2008-08-28 12:37:41 +0200 -message: - Added kmGLRotation ------------------------------------------------------------- -revno: 21 -committer: Luke Benstead -timestamp: Thu 2008-08-28 09:24:00 +0100 -message: - We now have a working matrix stack ------------------------------------------------------------- -revno: 20 -committer: Luke Benstead -timestamp: Wed 2008-08-27 13:34:49 +0100 -message: - Fixed the stack memory constants ------------------------------------------------------------- -revno: 19 -committer: Luke Benstead -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 -timestamp: Mon 2008-08-25 12:46:16 +0200 -message: - Fixed a bug in kmMat4LookAt ------------------------------------------------------------- -revno: 17 [merge] -committer: Carsten Haubold -timestamp: Sun 2008-08-24 22:07:49 +0200 -message: - Merge branch 'master' of git@github.com:Kazade/kazmath ------------------------------------------------------------- -revno: 16 -committer: Carsten Haubold -timestamp: Sun 2008-08-24 22:06:45 +0200 -message: - Added kmMat4LookAt ------------------------------------------------------------- -revno: 15 -committer: Carsten Haubold -timestamp: Wed 2008-08-20 11:18:10 +0200 -message: - Added Fill methods for all Vec and Mat structs ------------------------------------------------------------- -revno: 14 -committer: Carsten Haubold -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 -timestamp: Sun 2008-08-17 23:19:21 +0200 -message: - removed .svn entries which did not belong here ------------------------------------------------------------- -revno: 12 -committer: Carsten Haubold -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 -timestamp: Sun 2008-08-17 16:04:09 +0200 -message: - Renamed cotangent to cotangens ------------------------------------------------------------- -revno: 10 -committer: Luke Benstead -timestamp: Sat 2008-08-16 21:51:22 +0100 -message: - Added kmMat4PerspectiveProjection and kmMat4OrthographicProjection ------------------------------------------------------------- -revno: 9 -committer: Luke Benstead -timestamp: Thu 2008-08-14 21:15:45 +0100 -message: - Added the aabb struct ------------------------------------------------------------- -revno: 8 -committer: Luke Benstead -timestamp: Thu 2008-08-14 17:57:43 +0100 -message: - Added the kmAABB structure ------------------------------------------------------------- -revno: 7 -committer: Luke Benstead -timestamp: Thu 2008-08-14 14:32:24 +0100 -message: - Fixed broken kmMat3Transpose ------------------------------------------------------------- -revno: 6 -committer: Luke Benstead -timestamp: Thu 2008-08-14 14:21:04 +0100 -message: - Fixed broken kmMat4Translation, w component was not set ------------------------------------------------------------- -revno: 5 -committer: Luke Benstead -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 -timestamp: Thu 2008-08-14 13:56:26 +0100 -message: - Added the authors section to the readme ------------------------------------------------------------- -revno: 3 -committer: Luke Benstead -timestamp: Thu 2008-08-14 13:55:41 +0100 -message: - Updated the readme file ------------------------------------------------------------- -revno: 2 -committer: Luke Benstead -timestamp: Thu 2008-08-14 13:53:26 +0100 -message: - Added kazmath to git ------------------------------------------------------------- -revno: 1 -committer: Luke Benstead -timestamp: Thu 2008-08-14 13:47:51 +0100 -message: - First commit ------------------------------------------------------------- -Use --include-merges or -n0 to see merged revisions. diff --git a/cocos/math/kazmath/src/aabb.c b/cocos/math/kazmath/src/aabb.c deleted file mode 100644 index 83b3748e45..0000000000 --- a/cocos/math/kazmath/src/aabb.c +++ /dev/null @@ -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; -} - - - diff --git a/cocos/math/kazmath/src/mat3.c b/cocos/math/kazmath/src/mat3.c deleted file mode 100644 index 6654d0634f..0000000000 --- a/cocos/math/kazmath/src/mat3.c +++ /dev/null @@ -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 -#include -#include - -#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; -} diff --git a/cocos/math/kazmath/src/mat4.c b/cocos/math/kazmath/src/mat4.c deleted file mode 100644 index 9c49b56071..0000000000 --- a/cocos/math/kazmath/src/mat4.c +++ /dev/null @@ -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 -#include -#include - -#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; -} diff --git a/cocos/math/kazmath/src/plane.c b/cocos/math/kazmath/src/plane.c deleted file mode 100644 index 91a7ff769c..0000000000 --- a/cocos/math/kazmath/src/plane.c +++ /dev/null @@ -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 -#include - -#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; -} - diff --git a/cocos/math/kazmath/src/quaternion.c b/cocos/math/kazmath/src/quaternion.c deleted file mode 100644 index f901cf1e62..0000000000 --- a/cocos/math/kazmath/src/quaternion.c +++ /dev/null @@ -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 -#include - -#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; -} - diff --git a/cocos/math/kazmath/src/ray2.c b/cocos/math/kazmath/src/ray2.c deleted file mode 100644 index 8f3b430233..0000000000 --- a/cocos/math/kazmath/src/ray2.c +++ /dev/null @@ -1,186 +0,0 @@ -#include -#include -#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; -} diff --git a/cocos/math/kazmath/src/vec2.c b/cocos/math/kazmath/src/vec2.c deleted file mode 100644 index 2ff18f5ab7..0000000000 --- a/cocos/math/kazmath/src/vec2.c +++ /dev/null @@ -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 -#include - -#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) - ); -} diff --git a/cocos/math/kazmath/src/vec3.c b/cocos/math/kazmath/src/vec3.c deleted file mode 100644 index 93075a0870..0000000000 --- a/cocos/math/kazmath/src/vec3.c +++ /dev/null @@ -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 -#include - -#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; -}