IOS/Mac OK: remove kazMath

Make code compatible with old tests
This commit is contained in:
Huabing.Xu 2014-04-21 17:37:52 +08:00
parent e74f8719cf
commit 68e058b12d
34 changed files with 497 additions and 4931 deletions

View File

@ -1 +1 @@
6317ab72408dd11d925c99ccebee59b12e41074d
e6cb148185cfef8c71e62f3e83178e3eede69200

View File

@ -173,4 +173,399 @@ void ccPointSize( GLfloat pointSize )
DrawPrimitives::setPointSize(pointSize);
}
MATRIX_STACK_TYPE currentActiveStackType = MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW;
void CC_DLL kmGLFreeAll(void)
{
Director::getInstance()->resetMatrixStack();
}
void CC_DLL kmGLPushMatrix(void)
{
Director::getInstance()->pushMatrix(currentActiveStackType);
}
void CC_DLL kmGLPopMatrix(void)
{
Director::getInstance()->popMatrix(currentActiveStackType);
}
void CC_DLL kmGLMatrixMode(unsigned int mode)
{
if(KM_GL_MODELVIEW == mode)
currentActiveStackType = MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW;
else if(KM_GL_PROJECTION == mode)
currentActiveStackType = MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION;
else if(KM_GL_TEXTURE == mode)
currentActiveStackType = MATRIX_STACK_TYPE::MATRIX_STACK_TEXTURE;
else
{
CC_ASSERT(false);
}
}
void CC_DLL kmGLLoadIdentity(void)
{
Director::getInstance()->loadIdentityMatrix(currentActiveStackType);
}
void CC_DLL kmGLLoadMatrix(const Matrix* pIn)
{
Director::getInstance()->loadMatrix(currentActiveStackType, *pIn);
}
void CC_DLL kmGLMultMatrix(const Matrix* pIn)
{
Director::getInstance()->multiplyMatrix(currentActiveStackType, *pIn);
}
void CC_DLL kmGLTranslatef(float x, float y, float z)
{
Matrix mat;
Matrix::createTranslation(Vector3(x, y, z), &mat);
Director::getInstance()->multiplyMatrix(currentActiveStackType, mat);
}
void CC_DLL kmGLRotatef(float angle, float x, float y, float z)
{
Matrix mat;
Matrix::createRotation(Vector3(x, y, z), angle, &mat);
Director::getInstance()->multiplyMatrix(currentActiveStackType, mat);
}
void CC_DLL kmGLScalef(float x, float y, float z)
{
Matrix mat;
Matrix::createScale(x, y, z, &mat);
Director::getInstance()->multiplyMatrix(currentActiveStackType, mat);
}
void CC_DLL kmGLGetMatrix(unsigned int mode, Matrix* pOut)
{
if(KM_GL_MODELVIEW == mode)
*pOut = Director::getInstance()->getMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
else if(KM_GL_PROJECTION == mode)
*pOut = Director::getInstance()->getMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION);
else if(KM_GL_TEXTURE == mode)
*pOut = Director::getInstance()->getMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_TEXTURE);
else
{
CC_ASSERT(false);
}
}
Matrix* kmMat4Fill(Matrix* pOut, const float* pMat)
{
pOut->set(pMat);
return pOut;
}
Matrix* kmMat4Assign(Matrix* pOut, const Matrix* pIn)
{
pOut->set(pIn->m);
return pOut;
}
Matrix* kmMat4Identity(Matrix* pOut)
{
*pOut = Matrix::identity();
return pOut;
}
Matrix* kmMat4Inverse(Matrix* pOut, const Matrix* pM)
{
pM->invert(pOut);
return pOut;
}
Matrix* kmMat4Transpose(Matrix* pOut, const Matrix* pIn)
{
pIn->transpose(pOut);
return pOut;
}
Matrix* kmMat4Multiply(Matrix* pOut, const Matrix* pM1, const Matrix* pM2)
{
*pOut = (*pM1) * (*pM2);
return pOut;
}
Matrix* kmMat4Translation(Matrix* pOut, const float x, const float y, const float z)
{
Matrix::createTranslation(x, y, z, pOut);
return pOut;
}
Matrix* kmMat4RotationX(Matrix* pOut, const float radians)
{
Matrix::createRotationX(radians, pOut);
return pOut;
}
Matrix* kmMat4RotationY(Matrix* pOut, const float radians)
{
Matrix::createRotationY(radians, pOut);
return pOut;
}
Matrix* kmMat4RotationZ(Matrix* pOut, const float radians)
{
Matrix::createRotationZ(radians, pOut);
return pOut;
}
Matrix* kmMat4RotationAxisAngle(Matrix* pOut, const struct Vector3* axis, float radians)
{
Matrix::createRotation(*axis, radians, pOut);
return pOut;
}
Matrix* kmMat4Scaling(Matrix* pOut, const float x, const float y, const float z)
{
Matrix::createScale(x, y, z, pOut);
return pOut;
}
Matrix* kmMat4PerspectiveProjection(Matrix* pOut, float fovY, float aspect, float zNear, float zFar)
{
Matrix::createPerspective(fovY, aspect, zNear, zFar, pOut);
return pOut;
}
Matrix* kmMat4OrthographicProjection(Matrix* pOut, float left, float right, float bottom, float top, float nearVal, float farVal)
{
Matrix::createOrthographicOffCenter(left, right, bottom, top, nearVal, farVal, pOut);
return pOut;
}
Matrix* kmMat4LookAt(Matrix* pOut, const struct Vector3* pEye, const struct Vector3* pCenter, const struct Vector3* pUp)
{
Matrix::createLookAt(*pEye, *pCenter, *pUp, pOut);
return pOut;
}
Vector3* kmVec3Fill(Vector3* pOut, float x, float y, float z)
{
pOut->x = x;
pOut->y = y;
pOut->z = z;
return pOut;
}
float kmVec3Length(const Vector3* pIn)
{
return pIn->length();
}
float kmVec3LengthSq(const Vector3* pIn)
{
return pIn->lengthSquared();
}
CC_DLL Vector3* kmVec3Lerp(Vector3* pOut, const Vector3* pV1, const Vector3* pV2, float 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;
}
Vector3* kmVec3Normalize(Vector3* pOut, const Vector3* pIn)
{
pIn->normalize(pOut);
return pOut;
}
Vector3* kmVec3Cross(Vector3* pOut, const Vector3* pV1, const Vector3* pV2)
{
Vector3::cross(*pV1, *pV2, pOut);
return pOut;
}
float kmVec3Dot(const Vector3* pV1, const Vector3* pV2)
{
return Vector3::dot(*pV1, *pV2);
}
Vector3* kmVec3Add(Vector3* pOut, const Vector3* pV1, const Vector3* pV2)
{
Vector3::add(*pV1, *pV2, pOut);
return pOut;
}
Vector3* kmVec3Subtract(Vector3* pOut, const Vector3* pV1, const Vector3* pV2)
{
Vector3::subtract(*pV1, *pV2, pOut);
return pOut;
}
Vector3* kmVec3Transform(Vector3* pOut, const Vector3* pV1, const Matrix* pM)
{
pM->transformPoint(*pV1, pOut);
return pOut;
}
Vector3* kmVec3TransformNormal(Vector3* pOut, const Vector3* pV, const Matrix* pM)
{
pM->transformVector(*pV, pOut);
return pOut;
}
Vector3* kmVec3TransformCoord(Vector3* pOut, const Vector3* pV, const Matrix* pM)
{
Vector4 v(pV->x, pV->y, pV->z, 1);
pM->transformVector(&v);
v = v * (1/v.w);
pOut->set(v.x, v.y, v.z);
return pOut;
}
Vector3* kmVec3Scale(Vector3* pOut, const Vector3* pIn, const float s)
{
*pOut = *pIn * s;
return pOut;
}
Vector3* kmVec3Assign(Vector3* pOut, const Vector3* pIn)
{
*pOut = *pIn;
return pOut;
}
Vector3* kmVec3Zero(Vector3* pOut)
{
pOut->set(0, 0, 0);
return pOut;
}
Vector2* kmVec2Fill(Vector2* pOut, float x, float y)
{
pOut->set(x, y);
return pOut;
}
float kmVec2Length(const Vector2* pIn)
{
return pIn->length();
}
float kmVec2LengthSq(const Vector2* pIn)
{
return pIn->lengthSquared();
}
Vector2* kmVec2Normalize(Vector2* pOut, const Vector2* pIn)
{
pIn->normalize(pOut);
return pOut;
}
Vector2* kmVec2Lerp(Vector2* pOut, const Vector2* pV1, const Vector2* pV2, float t)
{
pOut->x = pV1->x + t * ( pV2->x - pV1->x );
pOut->y = pV1->y + t * ( pV2->y - pV1->y );
return pOut;
}
Vector2* kmVec2Add(Vector2* pOut, const Vector2* pV1, const Vector2* pV2)
{
Vector2::add(*pV1, *pV2, pOut);
return pOut;
}
float kmVec2Dot(const Vector2* pV1, const Vector2* pV2)
{
return Vector2::dot(*pV1, *pV2);
}
Vector2* kmVec2Subtract(Vector2* pOut, const Vector2* pV1, const Vector2* pV2)
{
Vector2::subtract(*pV1, *pV2, pOut);
return pOut;
}
Vector2* kmVec2Scale(Vector2* pOut, const Vector2* pIn, const float s)
{
*pOut = *pIn * s;
return pOut;
}
Vector2* kmVec2Assign(Vector2* pOut, const Vector2* pIn)
{
*pOut = *pIn;
return pOut;
}
Vector4* kmVec4Fill(Vector4* pOut, float x, float y, float z, float w)
{
pOut->set(x, y, z, w);
return pOut;
}
Vector4* kmVec4Add(Vector4* pOut, const Vector4* pV1, const Vector4* pV2)
{
Vector4::add(*pV1, *pV2, pOut);
return pOut;
}
float kmVec4Dot(const Vector4* pV1, const Vector4* pV2)
{
return Vector4::dot(*pV1, *pV2);
}
float kmVec4Length(const Vector4* pIn)
{
return pIn->length();
}
float kmVec4LengthSq(const Vector4* pIn)
{
return pIn->lengthSquared();
}
Vector4* kmVec4Lerp(Vector4* pOut, const Vector4* pV1, const Vector4* pV2, float 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 );
pOut->w = pV1->w + t * ( pV2->w - pV1->w );
return pOut;
}
Vector4* kmVec4Normalize(Vector4* pOut, const Vector4* pIn)
{
pIn->normalize(pOut);
return pOut;
}
Vector4* kmVec4Scale(Vector4* pOut, const Vector4* pIn, const float s)
{
*pOut = *pIn * s;
return pOut;
}
Vector4* kmVec4Subtract(Vector4* pOut, const Vector4* pV1, const Vector4* pV2)
{
Vector4::subtract(*pV1, *pV2, pOut);
return pOut;
}
Vector4* kmVec4Assign(Vector4* pOut, const Vector4* pIn)
{
*pOut = *pIn;
return pOut;
}
Vector4* kmVec4MultiplyMat4(Vector4* pOut, const Vector4* pV, const Matrix* pM)
{
pM->transformVector(*pV, pOut);
return pOut;
}
Vector4* kmVec4Transform(Vector4* pOut, const Vector4* pV, const Matrix* pM)
{
pM->transformVector(*pV, pOut);
return pOut;
}
NS_CC_END

View File

@ -1051,6 +1051,107 @@ CC_DEPRECATED_ATTRIBUTE typedef __RGBAProtocol RGBAProtocol;
CC_DEPRECATED_ATTRIBUTE typedef __NodeRGBA NodeRGBA;
CC_DEPRECATED_ATTRIBUTE typedef __LayerRGBA LayerRGBA;
//deprecated attributes and methods for kazMath
CC_DEPRECATED_ATTRIBUTE typedef float kmScalar;
//kmMat4 and kmMat4 stack
CC_DEPRECATED_ATTRIBUTE typedef Matrix kmMat4;
CC_DEPRECATED_ATTRIBUTE const unsigned int KM_GL_MODELVIEW = 0x1700;
CC_DEPRECATED_ATTRIBUTE const unsigned int KM_GL_PROJECTION = 0x1701;
CC_DEPRECATED_ATTRIBUTE const unsigned int KM_GL_TEXTURE = 0x1702;
CC_DEPRECATED_ATTRIBUTE void CC_DLL kmGLFreeAll(void);
CC_DEPRECATED_ATTRIBUTE void CC_DLL kmGLPushMatrix(void);
CC_DEPRECATED_ATTRIBUTE void CC_DLL kmGLPopMatrix(void);
CC_DEPRECATED_ATTRIBUTE void CC_DLL kmGLMatrixMode(unsigned int mode);
CC_DEPRECATED_ATTRIBUTE void CC_DLL kmGLLoadIdentity(void);
CC_DEPRECATED_ATTRIBUTE void CC_DLL kmGLLoadMatrix(const Matrix* pIn);
CC_DEPRECATED_ATTRIBUTE void CC_DLL kmGLMultMatrix(const Matrix* pIn);
CC_DEPRECATED_ATTRIBUTE void CC_DLL kmGLTranslatef(float x, float y, float z);
CC_DEPRECATED_ATTRIBUTE void CC_DLL kmGLRotatef(float angle, float x, float y, float z);
CC_DEPRECATED_ATTRIBUTE void CC_DLL kmGLScalef(float x, float y, float z);
CC_DEPRECATED_ATTRIBUTE void CC_DLL kmGLGetMatrix(unsigned int mode, Matrix* pOut);
CC_DEPRECATED_ATTRIBUTE CC_DLL Matrix* kmMat4Fill(Matrix* pOut, const float* pMat);
CC_DEPRECATED_ATTRIBUTE CC_DLL Matrix* kmMat4Assign(Matrix* pOut, const Matrix* pIn);
CC_DEPRECATED_ATTRIBUTE CC_DLL Matrix* kmMat4Identity(Matrix* pOut);
CC_DEPRECATED_ATTRIBUTE CC_DLL Matrix* kmMat4Inverse(Matrix* pOut, const Matrix* pM);
CC_DEPRECATED_ATTRIBUTE CC_DLL Matrix* kmMat4Transpose(Matrix* pOut, const Matrix* pIn);
CC_DEPRECATED_ATTRIBUTE CC_DLL Matrix* kmMat4Multiply(Matrix* pOut, const Matrix* pM1, const Matrix* pM2);
CC_DEPRECATED_ATTRIBUTE CC_DLL Matrix* kmMat4Translation(Matrix* pOut, const float x, const float y, const float z);
CC_DEPRECATED_ATTRIBUTE CC_DLL Matrix* kmMat4RotationX(Matrix* pOut, const float radians);
CC_DEPRECATED_ATTRIBUTE CC_DLL Matrix* kmMat4RotationY(Matrix* pOut, const float radians);
CC_DEPRECATED_ATTRIBUTE CC_DLL Matrix* kmMat4RotationZ(Matrix* pOut, const float radians);
CC_DEPRECATED_ATTRIBUTE CC_DLL Matrix* kmMat4RotationAxisAngle(Matrix* pOut, const struct Vector3* axis, float radians);
CC_DEPRECATED_ATTRIBUTE CC_DLL Matrix* kmMat4Scaling(Matrix* pOut, const float x, const float y, const float z);
CC_DEPRECATED_ATTRIBUTE CC_DLL Matrix* kmMat4PerspectiveProjection(Matrix* pOut, float fovY, float aspect, float zNear, float zFar);
CC_DEPRECATED_ATTRIBUTE CC_DLL Matrix* kmMat4OrthographicProjection(Matrix* pOut, float left, float right, float bottom, float top, float nearVal, float farVal);
CC_DEPRECATED_ATTRIBUTE CC_DLL Matrix* kmMat4LookAt(Matrix* pOut, const struct Vector3* pEye, const struct Vector3* pCenter, const struct Vector3* pUp);
//kmVec3
CC_DEPRECATED_ATTRIBUTE typedef Vector3 kmVec3;
CC_DEPRECATED_ATTRIBUTE CC_DLL Vector3* kmVec3Fill(Vector3* pOut, float x, float y, float z);
CC_DEPRECATED_ATTRIBUTE CC_DLL float kmVec3Length(const Vector3* pIn);
CC_DEPRECATED_ATTRIBUTE CC_DLL float kmVec3LengthSq(const Vector3* pIn);
CC_DEPRECATED_ATTRIBUTE CC_DLL Vector3* kmVec3Lerp(Vector3* pOut, const Vector3* pV1, const Vector3* pV2, float t);
CC_DEPRECATED_ATTRIBUTE CC_DLL Vector3* kmVec3Normalize(Vector3* pOut, const Vector3* pIn);
CC_DEPRECATED_ATTRIBUTE CC_DLL Vector3* kmVec3Cross(Vector3* pOut, const Vector3* pV1, const Vector3* pV2);
CC_DEPRECATED_ATTRIBUTE CC_DLL float kmVec3Dot(const Vector3* pV1, const Vector3* pV2);
CC_DEPRECATED_ATTRIBUTE CC_DLL Vector3* kmVec3Add(Vector3* pOut, const Vector3* pV1, const Vector3* pV2);
CC_DEPRECATED_ATTRIBUTE CC_DLL Vector3* kmVec3Subtract(Vector3* pOut, const Vector3* pV1, const Vector3* pV2);
CC_DEPRECATED_ATTRIBUTE CC_DLL Vector3* kmVec3Transform(Vector3* pOut, const Vector3* pV1, const Matrix* pM);
CC_DEPRECATED_ATTRIBUTE CC_DLL Vector3* kmVec3TransformNormal(Vector3* pOut, const Vector3* pV, const Matrix* pM);
CC_DEPRECATED_ATTRIBUTE CC_DLL Vector3* kmVec3TransformCoord(Vector3* pOut, const Vector3* pV, const Matrix* pM);
CC_DEPRECATED_ATTRIBUTE CC_DLL Vector3* kmVec3Scale(Vector3* pOut, const Vector3* pIn, const float s);
CC_DEPRECATED_ATTRIBUTE CC_DLL Vector3* kmVec3Assign(Vector3* pOut, const Vector3* pIn);
CC_DEPRECATED_ATTRIBUTE CC_DLL Vector3* kmVec3Zero(Vector3* pOut);
CC_DEPRECATED_ATTRIBUTE const Vector3 KM_VEC3_NEG_Z = Vector3(0, 0, -1);
CC_DEPRECATED_ATTRIBUTE const Vector3 KM_VEC3_POS_Z = Vector3(0, 0, 1);
CC_DEPRECATED_ATTRIBUTE const Vector3 KM_VEC3_POS_Y = Vector3(0, 1, 0);
CC_DEPRECATED_ATTRIBUTE const Vector3 KM_VEC3_NEG_Y = Vector3(0, -1, 0);
CC_DEPRECATED_ATTRIBUTE const Vector3 KM_VEC3_NEG_X = Vector3(-1, 0, 0);
CC_DEPRECATED_ATTRIBUTE const Vector3 KM_VEC3_POS_X = Vector3(1, 0, 0);
CC_DEPRECATED_ATTRIBUTE const Vector3 KM_VEC3_ZERO = Vector3(0, 0, 0);
//kmVec2
CC_DEPRECATED_ATTRIBUTE typedef Vector2 kmVec2;
CC_DEPRECATED_ATTRIBUTE CC_DLL Vector2* kmVec2Fill(Vector2* pOut, float x, float y);
CC_DEPRECATED_ATTRIBUTE CC_DLL float kmVec2Length(const Vector2* pIn);
CC_DEPRECATED_ATTRIBUTE CC_DLL float kmVec2LengthSq(const Vector2* pIn);
CC_DEPRECATED_ATTRIBUTE CC_DLL Vector2* kmVec2Normalize(Vector2* pOut, const Vector2* pIn);
CC_DEPRECATED_ATTRIBUTE CC_DLL Vector2* kmVec2Lerp(Vector2* pOut, const Vector2* pV1, const Vector2* pV2, float t);
CC_DEPRECATED_ATTRIBUTE CC_DLL Vector2* kmVec2Add(Vector2* pOut, const Vector2* pV1, const Vector2* pV2);
CC_DEPRECATED_ATTRIBUTE CC_DLL float kmVec2Dot(const Vector2* pV1, const Vector2* pV2);
CC_DEPRECATED_ATTRIBUTE CC_DLL Vector2* kmVec2Subtract(Vector2* pOut, const Vector2* pV1, const Vector2* pV2);
CC_DEPRECATED_ATTRIBUTE CC_DLL Vector2* kmVec2Scale(Vector2* pOut, const Vector2* pIn, const float s);
CC_DEPRECATED_ATTRIBUTE CC_DLL Vector2* kmVec2Assign(Vector2* pOut, const Vector2* pIn);
CC_DEPRECATED_ATTRIBUTE const Vector2 KM_VEC2_POS_Y = Vector2(0, 1);
CC_DEPRECATED_ATTRIBUTE const Vector2 KM_VEC2_NEG_Y = Vector2(0, -1);
CC_DEPRECATED_ATTRIBUTE const Vector2 KM_VEC2_NEG_X = Vector2(-1, 0);
CC_DEPRECATED_ATTRIBUTE const Vector2 KM_VEC2_POS_X = Vector2(1, 0);
CC_DEPRECATED_ATTRIBUTE const Vector2 KM_VEC2_ZERO = Vector2(0, 0);
//kmVec4
CC_DEPRECATED_ATTRIBUTE typedef Vector4 kmVec4;
CC_DEPRECATED_ATTRIBUTE CC_DLL Vector4* kmVec4Fill(Vector4* pOut, float x, float y, float z, float w);
CC_DEPRECATED_ATTRIBUTE CC_DLL Vector4* kmVec4Add(Vector4* pOut, const Vector4* pV1, const Vector4* pV2);
CC_DEPRECATED_ATTRIBUTE CC_DLL float kmVec4Dot(const Vector4* pV1, const Vector4* pV2);
CC_DEPRECATED_ATTRIBUTE CC_DLL float kmVec4Length(const Vector4* pIn);
CC_DEPRECATED_ATTRIBUTE CC_DLL float kmVec4LengthSq(const Vector4* pIn);
CC_DEPRECATED_ATTRIBUTE CC_DLL Vector4* kmVec4Lerp(Vector4* pOut, const Vector4* pV1, const Vector4* pV2, float t);
CC_DEPRECATED_ATTRIBUTE CC_DLL Vector4* kmVec4Normalize(Vector4* pOut, const Vector4* pIn);
CC_DEPRECATED_ATTRIBUTE CC_DLL Vector4* kmVec4Scale(Vector4* pOut, const Vector4* pIn, const float s);
CC_DEPRECATED_ATTRIBUTE CC_DLL Vector4* kmVec4Subtract(Vector4* pOut, const Vector4* pV1, const Vector4* pV2);
CC_DEPRECATED_ATTRIBUTE CC_DLL Vector4* kmVec4Assign(Vector4* pOut, const Vector4* pIn);
CC_DEPRECATED_ATTRIBUTE CC_DLL Vector4* kmVec4MultiplyMat4(Vector4* pOut, const Vector4* pV, const Matrix* pM);
CC_DEPRECATED_ATTRIBUTE CC_DLL Vector4* kmVec4Transform(Vector4* pOut, const Vector4* pV, const Matrix* pM);
//end of deprecated attributes and methods for kazMath
NS_CC_END

View File

@ -1,24 +0,0 @@
SET(KAZMATH_SOURCES
mat4.c
mat3.c
plane.c
vec4.c
quaternion.c
vec2.c
vec3.c
utility.c
aabb.c
ray2.c
ray3.c
GL/mat4stack.c
GL/matrix.c
)
ADD_SUBDIRECTORY(kazmath)
set_target_properties(kazmath
PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
)

View File

@ -1,18 +0,0 @@
#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)

View File

@ -1,80 +0,0 @@
/*
Copyright (c) 2008, Luke Benstead.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include <memory.h>
#include <assert.h>
#include <stdio.h>
#define INITIAL_SIZE 30
#define INCREMENT 50
#include "kazmath/GL/mat4stack.h"
void km_mat4_stack_initialize(km_mat4_stack* stack) {
stack->stack = (kmMat4*) malloc(sizeof(kmMat4) * INITIAL_SIZE); //allocate the memory
stack->capacity = INITIAL_SIZE; //Set the capacity to 10
stack->top = NULL; //Set the top to NULL
stack->item_count = 0;
};
void km_mat4_stack_push(km_mat4_stack* stack, const kmMat4* item)
{
stack->top = &stack->stack[stack->item_count];
kmMat4Assign(stack->top, item);
stack->item_count++;
if(stack->item_count >= stack->capacity)
{
kmMat4* temp = NULL;
stack->capacity += INCREMENT;
temp = stack->stack;
stack->stack = (kmMat4*) malloc(stack->capacity*sizeof(kmMat4));
memcpy(stack->stack, temp, sizeof(kmMat4)*(stack->capacity - INCREMENT));
free(temp);
stack->top = &stack->stack[stack->item_count - 1];
}
}
void km_mat4_stack_pop(km_mat4_stack* stack, kmMat4* pOut)
{
assert(stack->item_count && "Cannot pop an empty stack");
stack->item_count--;
stack->top = &stack->stack[stack->item_count - 1];
}
void km_mat4_stack_release(km_mat4_stack* stack)
{
if (stack->stack)
{
free(stack->stack);
stack->stack = NULL;
}
stack->top = NULL;
stack->item_count = 0;
stack->capacity = 0;
}

View File

@ -1,51 +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 C_STACK_H_INCLUDED
#define C_STACK_H_INCLUDED
#include "../mat4.h"
typedef struct km_mat4_stack {
int capacity; //The total item capacity
int item_count; //The number of items
kmMat4* top;
kmMat4* stack;
} km_mat4_stack;
#ifdef __cplusplus
extern "C" {
#endif
void km_mat4_stack_initialize(km_mat4_stack* stack);
void km_mat4_stack_push(km_mat4_stack* stack, const kmMat4* item);
void km_mat4_stack_pop(km_mat4_stack* stack, kmMat4* pOut);
void km_mat4_stack_release(km_mat4_stack* stack);
#ifdef __cplusplus
}
#endif
#endif // C_STACK_H_INCLUDED

View File

@ -1,191 +0,0 @@
/*
Copyright (c) 2008, Luke Benstead.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include <assert.h>
#include "kazmath/GL/matrix.h"
#include "kazmath/GL/mat4stack.h"
km_mat4_stack modelview_matrix_stack;
km_mat4_stack projection_matrix_stack;
km_mat4_stack texture_matrix_stack;
km_mat4_stack* current_stack = NULL;
static unsigned char initialized = 0;
void lazyInitialize()
{
if (!initialized) {
kmMat4 identity; //Temporary identity matrix
//Initialize all 3 stacks
//modelview_matrix_stack = (km_mat4_stack*) malloc(sizeof(km_mat4_stack));
km_mat4_stack_initialize(&modelview_matrix_stack);
//projection_matrix_stack = (km_mat4_stack*) malloc(sizeof(km_mat4_stack));
km_mat4_stack_initialize(&projection_matrix_stack);
//texture_matrix_stack = (km_mat4_stack*) malloc(sizeof(km_mat4_stack));
km_mat4_stack_initialize(&texture_matrix_stack);
current_stack = &modelview_matrix_stack;
initialized = 1;
kmMat4Identity(&identity);
//Make sure that each stack has the identity matrix
km_mat4_stack_push(&modelview_matrix_stack, &identity);
km_mat4_stack_push(&projection_matrix_stack, &identity);
km_mat4_stack_push(&texture_matrix_stack, &identity);
}
}
void kmGLMatrixMode(kmGLEnum mode)
{
lazyInitialize();
switch(mode)
{
case KM_GL_MODELVIEW:
current_stack = &modelview_matrix_stack;
break;
case KM_GL_PROJECTION:
current_stack = &projection_matrix_stack;
break;
case KM_GL_TEXTURE:
current_stack = &texture_matrix_stack;
break;
default:
assert(0 && "Invalid matrix mode specified"); //TODO: Proper error handling
break;
}
}
void kmGLPushMatrix(void)
{
kmMat4 top;
lazyInitialize(); //Initialize the stacks if they haven't been already
//Duplicate the top of the stack (i.e the current matrix)
kmMat4Assign(&top, current_stack->top);
km_mat4_stack_push(current_stack, &top);
}
void kmGLPopMatrix(void)
{
assert(initialized && "Cannot Pop empty matrix stack");
//No need to lazy initialize, you shouldn't be popping first anyway!
km_mat4_stack_pop(current_stack, NULL);
}
void kmGLLoadIdentity()
{
lazyInitialize();
kmMat4Identity(current_stack->top); //Replace the top matrix with the identity matrix
}
void kmGLFreeAll()
{
//Clear the matrix stacks
km_mat4_stack_release(&modelview_matrix_stack);
km_mat4_stack_release(&projection_matrix_stack);
km_mat4_stack_release(&texture_matrix_stack);
//Delete the matrices
initialized = 0; //Set to uninitialized
current_stack = NULL; //Set the current stack to point nowhere
}
void kmGLMultMatrix(const kmMat4* pIn)
{
lazyInitialize();
kmMat4Multiply(current_stack->top, current_stack->top, pIn);
}
void kmGLLoadMatrix(const kmMat4* pIn)
{
lazyInitialize();
kmMat4Assign(current_stack->top, pIn);
}
void kmGLGetMatrix(kmGLEnum mode, kmMat4* pOut)
{
lazyInitialize();
switch(mode)
{
case KM_GL_MODELVIEW:
kmMat4Assign(pOut, modelview_matrix_stack.top);
break;
case KM_GL_PROJECTION:
kmMat4Assign(pOut, projection_matrix_stack.top);
break;
case KM_GL_TEXTURE:
kmMat4Assign(pOut, texture_matrix_stack.top);
break;
default:
assert(1 && "Invalid matrix mode specified"); //TODO: Proper error handling
break;
}
}
void kmGLTranslatef(float x, float y, float z)
{
kmMat4 translation;
//Create a rotation matrix using the axis and the angle
kmMat4Translation(&translation,x,y,z);
//Multiply the rotation matrix by the current matrix
kmMat4Multiply(current_stack->top, current_stack->top, &translation);
}
void kmGLRotatef(float angle, float x, float y, float z)
{
kmVec3 axis;
kmMat4 rotation;
//Create an axis vector
kmVec3Fill(&axis, x, y, z);
//Create a rotation matrix using the axis and the angle
kmMat4RotationAxisAngle(&rotation, &axis, kmDegreesToRadians(angle));
//Multiply the rotation matrix by the current matrix
kmMat4Multiply(current_stack->top, current_stack->top, &rotation);
}
void kmGLScalef(float x, float y, float z)
{
kmMat4 scaling;
kmMat4Scaling(&scaling, x, y, z);
kmMat4Multiply(current_stack->top, current_stack->top, &scaling);
}

View File

@ -1,60 +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 KM_GL_MATRIX_H_INCLUDED
#define KM_GL_MATRIX_H_INCLUDED
#include "CCPlatformMacros.h"
#define KM_GL_MODELVIEW 0x1700
#define KM_GL_PROJECTION 0x1701
#define KM_GL_TEXTURE 0x1702
typedef unsigned int kmGLEnum;
#include "../mat4.h"
#include "../vec3.h"
#ifdef __cplusplus
extern "C" {
#endif
void CC_DLL kmGLFreeAll(void);
void CC_DLL kmGLPushMatrix(void);
void CC_DLL kmGLPopMatrix(void);
void CC_DLL kmGLMatrixMode(kmGLEnum mode);
void CC_DLL kmGLLoadIdentity(void);
void CC_DLL kmGLLoadMatrix(const kmMat4* pIn);
void CC_DLL kmGLMultMatrix(const kmMat4* pIn);
void CC_DLL kmGLTranslatef(float x, float y, float z);
void CC_DLL kmGLRotatef(float angle, float x, float y, float z);
void CC_DLL kmGLScalef(float x, float y, float z);
void CC_DLL kmGLGetMatrix(kmGLEnum mode, kmMat4* pOut);
#ifdef __cplusplus
}
#endif
#endif // MATRIX_H_INCLUDED

View File

@ -1,142 +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 "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);
kmUchar i;
for(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;
}

View File

@ -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.
*/
#ifndef KAZMATH_AABB_H_INCLUDED
#define KAZMATH_AABB_H_INCLUDED
#include "CCPlatformMacros.h"
#include "vec3.h"
#include "utility.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* A struture that represents an axis-aligned
* bounding box.
*/
typedef struct kmAABB {
kmVec3 min; /** The max corner of the box */
kmVec3 max; /** The min corner of the box */
} kmAABB;
CC_DLL kmAABB* kmAABBInitialize(kmAABB* pBox, const kmVec3* centre, const kmScalar width, const kmScalar height, const kmScalar depth);
CC_DLL int kmAABBContainsPoint(const kmAABB* pBox, const kmVec3* pPoint);
CC_DLL kmAABB* kmAABBAssign(kmAABB* pOut, const kmAABB* pIn);
CC_DLL kmAABB* kmAABBScale(kmAABB* pOut, const kmAABB* pIn, kmScalar s);
CC_DLL kmBool kmAABBIntersectsTriangle(kmAABB* box, const kmVec3* p1, const kmVec3* p2, const kmVec3* p3);
CC_DLL kmEnum kmAABBContainsAABB(const kmAABB* container, const kmAABB* to_check);
CC_DLL kmScalar kmAABBDiameterX(const kmAABB* aabb);
CC_DLL kmScalar kmAABBDiameterY(const kmAABB* aabb);
CC_DLL kmScalar kmAABBDiameterZ(const kmAABB* aabb);
CC_DLL kmVec3* kmAABBCentre(const kmAABB* aabb, kmVec3* pOut);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,41 +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 KAZMATH_H_INCLUDED
#define KAZMATH_H_INCLUDED
#include "vec2.h"
#include "vec3.h"
#include "vec4.h"
#include "mat3.h"
#include "mat4.h"
#include "utility.h"
#include "quaternion.h"
#include "plane.h"
#include "aabb.h"
#include "ray2.h"
#include "ray3.h"
#endif // KAZMATH_H_INCLUDED

View File

@ -1,458 +0,0 @@
/*
Copyright (c) 2008, Luke Benstead.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include <memory.h>
#include <assert.h>
#include "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;
}

View File

@ -1,87 +0,0 @@
#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 "CCPlatformMacros.h"
#include "utility.h"
struct kmVec3;
struct kmQuaternion;
struct kmMat4;
typedef struct kmMat3{
kmScalar mat[9];
} kmMat3;
#ifdef __cplusplus
extern "C" {
#endif
CC_DLL kmMat3* kmMat3Fill(kmMat3* pOut, const kmScalar* pMat);
CC_DLL kmMat3* kmMat3Adjugate(kmMat3* pOut, const kmMat3* pIn);
CC_DLL kmMat3* kmMat3Identity(kmMat3* pOut);
CC_DLL kmMat3* kmMat3Inverse(kmMat3* pOut, const kmMat3* pM);
CC_DLL int kmMat3IsIdentity(const kmMat3* pIn);
CC_DLL kmMat3* kmMat3Transpose(kmMat3* pOut, const kmMat3* pIn);
CC_DLL kmScalar kmMat3Determinant(const kmMat3* pIn);
CC_DLL kmMat3* kmMat3Multiply(kmMat3* pOut, const kmMat3* pM1, const kmMat3* pM2);
CC_DLL kmMat3* kmMat3ScalarMultiply(kmMat3* pOut, const kmMat3* pM, const kmScalar pFactor);
CC_DLL kmMat3* kmMat3Assign(kmMat3* pOut, const kmMat3* pIn);
CC_DLL kmMat3* kmMat3AssignMat4(kmMat3* pOut, const struct kmMat4* pIn);
CC_DLL int kmMat3AreEqual(const kmMat3* pM1, const kmMat3* pM2);
CC_DLL struct kmVec3* kmMat3GetUpVec3(struct kmVec3* pOut, const kmMat3* pIn);
CC_DLL struct kmVec3* kmMat3GetRightVec3(struct kmVec3* pOut, const kmMat3* pIn);
CC_DLL struct kmVec3* kmMat3GetForwardVec3(struct kmVec3* pOut, const kmMat3* pIn);
CC_DLL kmMat3* kmMat3RotationX(kmMat3* pOut, const kmScalar radians);
CC_DLL kmMat3* kmMat3RotationY(kmMat3* pOut, const kmScalar radians);
CC_DLL kmMat3* kmMat3RotationZ(kmMat3* pOut, const kmScalar radians);
CC_DLL kmMat3* kmMat3Rotation(kmMat3* pOut, const kmScalar radians);
CC_DLL kmMat3* kmMat3Scaling(kmMat3* pOut, const kmScalar x, const kmScalar y);
CC_DLL kmMat3* kmMat3Translation(kmMat3* pOut, const kmScalar x, const kmScalar y);
CC_DLL kmMat3* kmMat3RotationQuaternion(kmMat3* pOut, const struct kmQuaternion* pIn);
CC_DLL kmMat3* kmMat3RotationAxisAngle(kmMat3* pOut, const struct kmVec3* axis, kmScalar radians);
CC_DLL struct kmVec3* kmMat3RotationToAxisAngle(struct kmVec3* pAxis, kmScalar* radians, const kmMat3* pIn);
CC_DLL 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

View File

@ -1,805 +0,0 @@
/*
Copyright (c) 2008, Luke Benstead.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file mat4.c
*/
#include <memory.h>
#include <assert.h>
#include <stdlib.h>
#include "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;
}

View File

@ -1,98 +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* kmMat4Fill(kmMat4* pOut, const kmScalar* pMat);
CC_DLL kmMat4* kmMat4Identity(kmMat4* pOut);
CC_DLL kmMat4* kmMat4Inverse(kmMat4* pOut, const kmMat4* pM);
CC_DLL int kmMat4IsIdentity(const kmMat4* pIn);
CC_DLL kmMat4* kmMat4Transpose(kmMat4* pOut, const kmMat4* pIn);
CC_DLL kmMat4* kmMat4Multiply(kmMat4* pOut, const kmMat4* pM1, const kmMat4* pM2);
CC_DLL kmMat4* kmMat4Assign(kmMat4* pOut, const kmMat4* pIn);
CC_DLL kmMat4* kmMat4AssignMat3(kmMat4* pOut, const struct kmMat3* pIn);
CC_DLL int kmMat4AreEqual(const kmMat4* pM1, const kmMat4* pM2);
CC_DLL kmMat4* kmMat4RotationX(kmMat4* pOut, const kmScalar radians);
CC_DLL kmMat4* kmMat4RotationY(kmMat4* pOut, const kmScalar radians);
CC_DLL kmMat4* kmMat4RotationZ(kmMat4* pOut, const kmScalar radians);
CC_DLL kmMat4* kmMat4RotationYawPitchRoll(kmMat4* pOut, const kmScalar pitch, const kmScalar yaw, const kmScalar roll);
CC_DLL kmMat4* kmMat4RotationQuaternion(kmMat4* pOut, const struct kmQuaternion* pQ);
CC_DLL kmMat4* kmMat4RotationTranslation(kmMat4* pOut, const struct kmMat3* rotation, const struct kmVec3* translation);
CC_DLL kmMat4* kmMat4Scaling(kmMat4* pOut, const kmScalar x, const kmScalar y, const kmScalar z);
CC_DLL kmMat4* kmMat4Translation(kmMat4* pOut, const kmScalar x, const kmScalar y, const kmScalar z);
CC_DLL struct kmVec3* kmMat4GetUpVec3(struct kmVec3* pOut, const kmMat4* pIn);
CC_DLL struct kmVec3* kmMat4GetRightVec3(struct kmVec3* pOut, const kmMat4* pIn);
CC_DLL struct kmVec3* kmMat4GetForwardVec3RH(struct kmVec3* pOut, const kmMat4* pIn);
CC_DLL struct kmVec3* kmMat4GetForwardVec3LH(struct kmVec3* pOut, const kmMat4* pIn);
CC_DLL kmMat4* kmMat4PerspectiveProjection(kmMat4* pOut, kmScalar fovY, kmScalar aspect, kmScalar zNear, kmScalar zFar);
CC_DLL kmMat4* kmMat4OrthographicProjection(kmMat4* pOut, kmScalar left, kmScalar right, kmScalar bottom, kmScalar top, kmScalar nearVal, kmScalar farVal);
CC_DLL kmMat4* kmMat4LookAt(kmMat4* pOut, const struct kmVec3* pEye, const struct kmVec3* pCenter, const struct kmVec3* pUp);
CC_DLL kmMat4* kmMat4RotationAxisAngle(kmMat4* pOut, const struct kmVec3* axis, kmScalar radians);
CC_DLL struct kmMat3* kmMat4ExtractRotation(struct kmMat3* pOut, const kmMat4* pIn);
CC_DLL struct kmPlane* kmMat4ExtractPlane(struct kmPlane* pOut, const kmMat4* pIn, const kmEnum plane);
CC_DLL struct kmVec3* kmMat4RotationToAxisAngle(struct kmVec3* pAxis, kmScalar* radians, const kmMat4* pIn);
#ifdef __cplusplus
}
#endif
#endif /* MAT4_H_INCLUDED */

View File

@ -1,98 +0,0 @@
/*
NEON math library for the iPhone / iPod touch
Copyright (c) 2009 Justin Saunders
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising
from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must
not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "kazmath/neon_matrix_impl.h"
#if defined(__ARM_NEON__) && !defined(__arm64__)
void NEON_Matrix4Mul(const float* a, const float* b, float* output )
{
__asm__ volatile
(
// Store A & B leaving room for q4-q7, which should be preserved
"vldmia %1, { q0-q3 } \n\t"
"vldmia %2, { q8-q11 }\n\t"
// result = first column of B x first row of A
"vmul.f32 q12, q8, d0[0]\n\t"
"vmul.f32 q13, q8, d2[0]\n\t"
"vmul.f32 q14, q8, d4[0]\n\t"
"vmul.f32 q15, q8, d6[0]\n\t"
// result += second column of B x second row of A
"vmla.f32 q12, q9, d0[1]\n\t"
"vmla.f32 q13, q9, d2[1]\n\t"
"vmla.f32 q14, q9, d4[1]\n\t"
"vmla.f32 q15, q9, d6[1]\n\t"
// result += third column of B x third row of A
"vmla.f32 q12, q10, d1[0]\n\t"
"vmla.f32 q13, q10, d3[0]\n\t"
"vmla.f32 q14, q10, d5[0]\n\t"
"vmla.f32 q15, q10, d7[0]\n\t"
// result += last column of B x last row of A
"vmla.f32 q12, q11, d1[1]\n\t"
"vmla.f32 q13, q11, d3[1]\n\t"
"vmla.f32 q14, q11, d5[1]\n\t"
"vmla.f32 q15, q11, d7[1]\n\t"
// output = result registers
"vstmia %0, { q12-q15 }"
: // no output
: "r" (output), "r" (a), "r" (b) // input - note *value* of pointer doesn't change
: "memory", "q0", "q1", "q2", "q3", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15" //clobber
);
}
void NEON_Matrix4Vector4Mul(const float* m, const float* v, float* output)
{
__asm__ volatile
(
// Store m & v - avoiding q4-q7 which need to be preserved - q0 = result
"vldmia %1, { q8-q11 } \n\t" // q8-q11 = m
"vldmia %2, { q1 } \n\t" // q1 = v
// result = first column of A x V.x
"vmul.f32 q0, q8, d2[0]\n\t"
// result += second column of A x V.y
"vmla.f32 q0, q9, d2[1]\n\t"
// result += third column of A x V.z
"vmla.f32 q0, q10, d3[0]\n\t"
// result += last column of A x V.w
"vmla.f32 q0, q11, d3[1]\n\t"
// output = result registers
"vstmia %0, { q0 }"
: // no output
: "r" (output), "r" (m), "r" (v) // input - note *value* of pointer doesn't change
: "memory", "q0", "q1", "q8", "q9", "q10", "q11" //clobber
);
}
#endif

View File

@ -1,45 +0,0 @@
/*
NEON math library for the iPhone / iPod touch
Copyright (c) 2009 Justin Saunders
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising
from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must
not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef __NEON_MATRIX_IMPL_H__
#define __NEON_MATRIX_IMPL_H__
#ifdef __arm__
#if defined(__QNX__) || defined(CC_TARGET_QT5)|| defined(ANDROID) || defined(I3D_ARCH_ARM) || defined(__native_client__) || defined(TIZEN) // MARMALADE CHANGE: Added for Marmalade support
// blackberry and android don't have arm/arch.h but it defines __arm__
#else
#include "arm/arch.h"
#endif
#endif // __arm__
// Matrices are assumed to be stored in column major format according to OpenGL
// specification.
// Multiplies two 4x4 matrices (a,b) outputting a 4x4 matrix (output)
void NEON_Matrix4Mul(const float* a, const float* b, float* output );
// Multiplies a 4x4 matrix (m) with a vector 4 (v), outputting a vector 4
void NEON_Matrix4Vector4Mul(const float* m, const float* v, float* output);
#endif // __NEON_MATRIX_IMPL_H__

View File

@ -1,254 +0,0 @@
/*
Copyright (c) 2008, Luke Benstead.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <assert.h>
#include <stdlib.h>
#include "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 = NP
*/
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 = nA
*/
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 + nU)(dn) [iff dn 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;
}

View File

@ -1,77 +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 PLANE_H_INCLUDED
#define PLANE_H_INCLUDED
#define KM_PLANE_LEFT 0
#define KM_PLANE_RIGHT 1
#define KM_PLANE_BOTTOM 2
#define KM_PLANE_TOP 3
#define KM_PLANE_NEAR 4
#define KM_PLANE_FAR 5
#include "CCPlatformMacros.h"
#include "utility.h"
struct kmVec3;
struct kmVec4;
struct kmMat4;
typedef struct kmPlane {
kmScalar a, b, c, d;
} kmPlane;
#ifdef __cplusplus
extern "C" {
#endif
typedef enum KM_POINT_CLASSIFICATION {
POINT_BEHIND_PLANE = -1,
POINT_ON_PLANE = 0,
POINT_INFRONT_OF_PLANE = 1
} KM_POINT_CLASSIFICATION;
CC_DLL kmPlane* kmPlaneFill(kmPlane* plane, float a, float b, float c, float d);
CC_DLL kmScalar kmPlaneDot(const kmPlane* pP, const struct kmVec4* pV);
CC_DLL kmScalar kmPlaneDotCoord(const kmPlane* pP, const struct kmVec3* pV);
CC_DLL kmScalar kmPlaneDotNormal(const kmPlane* pP, const struct kmVec3* pV);
CC_DLL kmPlane* kmPlaneFromNormalAndDistance(kmPlane* plane, const struct kmVec3* normal, const kmScalar dist);
CC_DLL kmPlane* kmPlaneFromPointAndNormal(kmPlane* pOut, const struct kmVec3* pPoint, const struct kmVec3* pNormal);
CC_DLL kmPlane* kmPlaneFromPoints(kmPlane* pOut, const struct kmVec3* p1, const struct kmVec3* p2, const struct kmVec3* p3);
CC_DLL struct kmVec3* kmPlaneIntersectLine(struct kmVec3* pOut, const kmPlane* pP, const struct kmVec3* pV1, const struct kmVec3* pV2);
CC_DLL kmPlane* kmPlaneNormalize(kmPlane* pOut, const kmPlane* pP);
CC_DLL kmPlane* kmPlaneScale(kmPlane* pOut, const kmPlane* pP, kmScalar s);
CC_DLL KM_POINT_CLASSIFICATION kmPlaneClassifyPoint(const kmPlane* pIn, const struct kmVec3* pP); /** Classifys a point against a plane */
CC_DLL kmPlane* kmPlaneExtractFromMat4(kmPlane* pOut, const struct kmMat4* pIn, kmInt row);
CC_DLL struct kmVec3* kmPlaneGetIntersection(struct kmVec3* pOut, const kmPlane* p1, const kmPlane* p2, const kmPlane* p3);
#ifdef __cplusplus
}
#endif
#endif // PLANE_H_INCLUDED

View File

@ -1,609 +0,0 @@
/*
Copyright (c) 2008, Luke Benstead.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <assert.h>
#include <memory.h>
#include <string.h>
#include "mat4.h"
#include "utility.h"
#include "mat3.h"
#include "vec3.h"
#include "quaternion.h"
int kmQuaternionAreEqual(const kmQuaternion* p1, const kmQuaternion* p2) {
if ((p1->x < (p2->x + kmEpsilon) && p1->x > (p2->x - kmEpsilon)) &&
(p1->y < (p2->y + kmEpsilon) && p1->y > (p2->y - kmEpsilon)) &&
(p1->z < (p2->z + kmEpsilon) && p1->z > (p2->z - kmEpsilon)) &&
(p1->w < (p2->w + kmEpsilon) && p1->w > (p2->w - kmEpsilon))) {
return 1;
}
return 0;
}
kmQuaternion* kmQuaternionFill(kmQuaternion* pOut, kmScalar x, kmScalar y, kmScalar z, kmScalar w) {
pOut->x = x;
pOut->y = y;
pOut->z = z;
pOut->w = w;
return pOut;
}
///< Returns the dot product of the 2 quaternions
kmScalar kmQuaternionDot(const kmQuaternion* q1, const kmQuaternion* q2)
{
/* A dot B = B dot A = AtBt + AxBx + AyBy + AzBz */
return (q1->w * q2->w +
q1->x * q2->x +
q1->y * q2->y +
q1->z * q2->z);
}
///< Returns the exponential of the quaternion
kmQuaternion* kmQuaternionExp(kmQuaternion* pOut, const kmQuaternion* pIn)
{
assert(0);
return pOut;
}
///< Makes the passed quaternion an identity quaternion
kmQuaternion* kmQuaternionIdentity(kmQuaternion* pOut)
{
pOut->x = 0.0;
pOut->y = 0.0;
pOut->z = 0.0;
pOut->w = 1.0;
return pOut;
}
///< Returns the inverse of the passed Quaternion
kmQuaternion* kmQuaternionInverse(kmQuaternion* pOut,
const kmQuaternion* pIn)
{
kmScalar l = kmQuaternionLength(pIn);
if (fabs(l) < kmEpsilon)
{
pOut->x = 0.0;
pOut->y = 0.0;
pOut->z = 0.0;
pOut->w = 0.0;
return pOut;
}
pOut->x = -pIn->x;
pOut->y = -pIn->y;
pOut->z = -pIn->z;
pOut->w = pIn->w;
return pOut;
}
///< Returns true if the quaternion is an identity quaternion
int kmQuaternionIsIdentity(const kmQuaternion* pIn)
{
return (pIn->x == 0.0 && pIn->y == 0.0 && pIn->z == 0.0 &&
pIn->w == 1.0);
}
///< Returns the length of the quaternion
kmScalar kmQuaternionLength(const kmQuaternion* pIn)
{
return sqrt(kmQuaternionLengthSq(pIn));
}
///< Returns the length of the quaternion squared (prevents a sqrt)
kmScalar kmQuaternionLengthSq(const kmQuaternion* pIn)
{
return pIn->x * pIn->x + pIn->y * pIn->y + pIn->z * pIn->z + pIn->w * pIn->w;
}
///< Returns the natural logarithm
kmQuaternion* kmQuaternionLn(kmQuaternion* pOut,
const kmQuaternion* pIn)
{
/*
A unit quaternion, is defined by:
Q == (cos(theta), sin(theta) * v) where |v| = 1
The natural logarithm of Q is, ln(Q) = (0, theta * v)
*/
assert(0);
return pOut;
}
///< Multiplies 2 quaternions together
extern
kmQuaternion* kmQuaternionMultiply(kmQuaternion* pOut,
const kmQuaternion* qu1,
const kmQuaternion* qu2)
{
kmQuaternion tmp1, tmp2;
kmQuaternionAssign(&tmp1, qu1);
kmQuaternionAssign(&tmp2, qu2);
//Just aliasing
kmQuaternion* q1 = &tmp1;
kmQuaternion* q2 = &tmp2;
pOut->x = q1->w * q2->x + q1->x * q2->w + q1->y * q2->z - q1->z * q2->y;
pOut->y = q1->w * q2->y + q1->y * q2->w + q1->z * q2->x - q1->x * q2->z;
pOut->z = q1->w * q2->z + q1->z * q2->w + q1->x * q2->y - q1->y * q2->x;
pOut->w = q1->w * q2->w - q1->x * q2->x - q1->y * q2->y - q1->z * q2->z;
return pOut;
}
///< Normalizes a quaternion
kmQuaternion* kmQuaternionNormalize(kmQuaternion* pOut,
const kmQuaternion* pIn)
{
kmScalar length = kmQuaternionLength(pIn);
if (fabs(length) < kmEpsilon)
{
pOut->x = 0.0;
pOut->y = 0.0;
pOut->z = 0.0;
pOut->w = 0.0;
return pOut;
}
kmQuaternionFill(pOut,
pOut->x / length,
pOut->y / length,
pOut->z / length,
pOut->w / length
);
return pOut;
}
///< Rotates a quaternion around an axis
kmQuaternion* kmQuaternionRotationAxisAngle(kmQuaternion* pOut,
const kmVec3* pV,
kmScalar angle)
{
kmScalar rad = angle * 0.5f;
kmScalar scale = sinf(rad);
pOut->x = pV->x * scale;
pOut->y = pV->y * scale;
pOut->z = pV->z * scale;
pOut->w = cosf(rad);
kmQuaternionNormalize(pOut, pOut);
return pOut;
}
///< Creates a quaternion from a rotation matrix
kmQuaternion* kmQuaternionRotationMatrix(kmQuaternion* pOut,
const kmMat3* pIn)
{
/*
Note: The OpenGL matrices are transposed from the description below
taken from the Matrix and Quaternion FAQ
if ( mat[0] > mat[5] && mat[0] > mat[10] ) { // Column 0:
S = sqrt( 1.0 + mat[0] - mat[5] - mat[10] ) * 2;
X = 0.25 * S;
Y = (mat[4] + mat[1] ) / S;
Z = (mat[2] + mat[8] ) / S;
W = (mat[9] - mat[6] ) / S;
} else if ( mat[5] > mat[10] ) { // Column 1:
S = sqrt( 1.0 + mat[5] - mat[0] - mat[10] ) * 2;
X = (mat[4] + mat[1] ) / S;
Y = 0.25 * S;
Z = (mat[9] + mat[6] ) / S;
W = (mat[2] - mat[8] ) / S;
} else { // Column 2:
S = sqrt( 1.0 + mat[10] - mat[0] - mat[5] ) * 2;
X = (mat[2] + mat[8] ) / S;
Y = (mat[9] + mat[6] ) / S;
Z = 0.25 * S;
W = (mat[4] - mat[1] ) / S;
}
*/
kmScalar x, y, z, w;
kmScalar *pMatrix = NULL;
kmScalar m4x4[16] = {0};
kmScalar scale = 0.0f;
kmScalar diagonal = 0.0f;
if(!pIn) {
return NULL;
}
/* 0 3 6
1 4 7
2 5 8
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15*/
m4x4[0] = pIn->mat[0];
m4x4[1] = pIn->mat[3];
m4x4[2] = pIn->mat[6];
m4x4[4] = pIn->mat[1];
m4x4[5] = pIn->mat[4];
m4x4[6] = pIn->mat[7];
m4x4[8] = pIn->mat[2];
m4x4[9] = pIn->mat[5];
m4x4[10] = pIn->mat[8];
m4x4[15] = 1;
pMatrix = &m4x4[0];
diagonal = pMatrix[0] + pMatrix[5] + pMatrix[10] + 1;
if(diagonal > kmEpsilon) {
// Calculate the scale of the diagonal
scale = (kmScalar)sqrt(diagonal ) * 2;
// Calculate the x, y, x and w of the quaternion through the respective equation
x = ( pMatrix[9] - pMatrix[6] ) / scale;
y = ( pMatrix[2] - pMatrix[8] ) / scale;
z = ( pMatrix[4] - pMatrix[1] ) / scale;
w = 0.25f * scale;
}
else
{
// If the first element of the diagonal is the greatest value
if ( pMatrix[0] > pMatrix[5] && pMatrix[0] > pMatrix[10] )
{
// Find the scale according to the first element, and double that value
scale = (kmScalar)sqrt( 1.0f + pMatrix[0] - pMatrix[5] - pMatrix[10] ) * 2.0f;
// Calculate the x, y, x and w of the quaternion through the respective equation
x = 0.25f * scale;
y = (pMatrix[4] + pMatrix[1] ) / scale;
z = (pMatrix[2] + pMatrix[8] ) / scale;
w = (pMatrix[9] - pMatrix[6] ) / scale;
}
// Else if the second element of the diagonal is the greatest value
else if (pMatrix[5] > pMatrix[10])
{
// Find the scale according to the second element, and double that value
scale = (kmScalar)sqrt( 1.0f + pMatrix[5] - pMatrix[0] - pMatrix[10] ) * 2.0f;
// Calculate the x, y, x and w of the quaternion through the respective equation
x = (pMatrix[4] + pMatrix[1] ) / scale;
y = 0.25f * scale;
z = (pMatrix[9] + pMatrix[6] ) / scale;
w = (pMatrix[2] - pMatrix[8] ) / scale;
}
// Else the third element of the diagonal is the greatest value
else
{
// Find the scale according to the third element, and double that value
scale = (kmScalar)sqrt( 1.0f + pMatrix[10] - pMatrix[0] - pMatrix[5] ) * 2.0f;
// Calculate the x, y, x and w of the quaternion through the respective equation
x = (pMatrix[2] + pMatrix[8] ) / scale;
y = (pMatrix[9] + pMatrix[6] ) / scale;
z = 0.25f * scale;
w = (pMatrix[4] - pMatrix[1] ) / scale;
}
}
pOut->x = x;
pOut->y = y;
pOut->z = z;
pOut->w = w;
return pOut;
}
///< Create a quaternion from yaw, pitch and roll
kmQuaternion* kmQuaternionRotationPitchYawRoll(kmQuaternion* pOut,
kmScalar pitch,
kmScalar yaw,
kmScalar roll)
{
assert(pitch <= 2*kmPI);
assert(yaw <= 2*kmPI);
assert(roll <= 2*kmPI);
// Finds the Sin and Cosin for each half angles.
float sY = sinf(yaw * 0.5);
float cY = cosf(yaw * 0.5);
float sZ = sinf(roll * 0.5);
float cZ = cosf(roll * 0.5);
float sX = sinf(pitch * 0.5);
float cX = cosf(pitch * 0.5);
// Formula to construct a new Quaternion based on Euler Angles.
pOut->w = cY * cZ * cX - sY * sZ * sX;
pOut->x = sY * sZ * cX + cY * cZ * sX;
pOut->y = sY * cZ * cX + cY * sZ * sX;
pOut->z = cY * sZ * cX - sY * cZ * sX;
return pOut;
}
///< Interpolate between 2 quaternions
kmQuaternion* kmQuaternionSlerp(kmQuaternion* pOut,
const kmQuaternion* q1,
const kmQuaternion* q2,
kmScalar t)
{
kmScalar dot = kmQuaternionDot(q1, q2);
const double DOT_THRESHOLD = 0.9995;
if (dot > DOT_THRESHOLD) {
kmQuaternion diff;
kmQuaternionSubtract(&diff, q2, q1);
kmQuaternionScale(&diff, &diff, t);
kmQuaternionAdd(pOut, q1, &diff);
kmQuaternionNormalize(pOut, pOut);
return pOut;
}
dot = kmClamp(dot, -1, 1);
kmScalar theta_0 = acos(dot);
kmScalar theta = theta_0 * t;
kmQuaternion tmp;
kmQuaternionScale(&tmp, q1, dot);
kmQuaternionSubtract(&tmp, q2, &tmp);
kmQuaternionNormalize(&tmp, &tmp);
kmQuaternion t1, t2;
kmQuaternionScale(&t1, q1, cos(theta));
kmQuaternionScale(&t2, &tmp, sin(theta));
kmQuaternionAdd(pOut, &t1, &t2);
return pOut;
}
///< Get the axis and angle of rotation from a quaternion
void kmQuaternionToAxisAngle(const kmQuaternion* pIn,
kmVec3* pAxis,
kmScalar* pAngle)
{
kmScalar tempAngle; // temp angle
kmScalar scale; // temp vars
tempAngle = acosf(pIn->w);
scale = sqrtf(kmSQR(pIn->x) + kmSQR(pIn->y) + kmSQR(pIn->z));
if (((scale > -kmEpsilon) && scale < kmEpsilon)
|| (scale < 2*kmPI + kmEpsilon && scale > 2*kmPI - kmEpsilon)) // angle is 0 or 360 so just simply set axis to 0,0,1 with angle 0
{
*pAngle = 0.0f;
pAxis->x = 0.0f;
pAxis->y = 0.0f;
pAxis->z = 1.0f;
}
else
{
*pAngle = tempAngle * 2.0f; // angle in radians
pAxis->x = pIn->x / scale;
pAxis->y = pIn->y / scale;
pAxis->z = pIn->z / scale;
kmVec3Normalize(pAxis, pAxis);
}
}
kmQuaternion* kmQuaternionScale(kmQuaternion* pOut,
const kmQuaternion* pIn,
kmScalar s)
{
pOut->x = pIn->x * s;
pOut->y = pIn->y * s;
pOut->z = pIn->z * s;
pOut->w = pIn->w * s;
return pOut;
}
kmQuaternion* kmQuaternionAssign(kmQuaternion* pOut, const kmQuaternion* pIn)
{
memcpy(pOut, pIn, sizeof(kmScalar) * 4);
return pOut;
}
kmQuaternion* kmQuaternionSubtract(kmQuaternion* pOut, const kmQuaternion* pQ1, const kmQuaternion* pQ2) {
pOut->x = pQ1->x - pQ2->x;
pOut->y = pQ1->y - pQ2->y;
pOut->z = pQ1->z - pQ2->z;
pOut->w = pQ1->w - pQ2->w;
return pOut;
}
kmQuaternion* kmQuaternionAdd(kmQuaternion* pOut, const kmQuaternion* pQ1, const kmQuaternion* pQ2)
{
pOut->x = pQ1->x + pQ2->x;
pOut->y = pQ1->y + pQ2->y;
pOut->z = pQ1->z + pQ2->z;
pOut->w = pQ1->w + pQ2->w;
return pOut;
}
/** Adapted from the OGRE engine!
Gets the shortest arc quaternion to rotate this vector to the destination
vector.
@remarks
If you call this with a dest vector that is close to the inverse
of this vector, we will rotate 180 degrees around the 'fallbackAxis'
(if specified, or a generated axis if not) since in this case
ANY axis of rotation is valid.
*/
kmQuaternion* kmQuaternionRotationBetweenVec3(kmQuaternion* pOut, const kmVec3* vec1, const kmVec3* vec2, const kmVec3* fallback) {
kmVec3 v1, v2;
kmScalar a;
kmVec3Assign(&v1, vec1);
kmVec3Assign(&v2, vec2);
kmVec3Normalize(&v1, &v1);
kmVec3Normalize(&v2, &v2);
a = kmVec3Dot(&v1, &v2);
if (a >= 1.0) {
kmQuaternionIdentity(pOut);
return pOut;
}
if (a < (1e-6f - 1.0f)) {
if (fabs(kmVec3LengthSq(fallback)) < kmEpsilon) {
kmQuaternionRotationAxisAngle(pOut, fallback, kmPI);
} else {
kmVec3 axis;
kmVec3 X;
X.x = 1.0;
X.y = 0.0;
X.z = 0.0;
kmVec3Cross(&axis, &X, vec1);
//If axis is zero
if (fabs(kmVec3LengthSq(&axis)) < kmEpsilon) {
kmVec3 Y;
Y.x = 0.0;
Y.y = 1.0;
Y.z = 0.0;
kmVec3Cross(&axis, &Y, vec1);
}
kmVec3Normalize(&axis, &axis);
kmQuaternionRotationAxisAngle(pOut, &axis, kmPI);
}
} else {
kmScalar s = sqrtf((1+a) * 2);
kmScalar invs = 1 / s;
kmVec3 c;
kmVec3Cross(&c, &v1, &v2);
pOut->x = c.x * invs;
pOut->y = c.y * invs;
pOut->z = c.z * invs;
pOut->w = s * 0.5f;
kmQuaternionNormalize(pOut, pOut);
}
return pOut;
}
kmVec3* kmQuaternionMultiplyVec3(kmVec3* pOut, const kmQuaternion* q, const kmVec3* v) {
kmVec3 uv, uuv, qvec;
qvec.x = q->x;
qvec.y = q->y;
qvec.z = q->z;
kmVec3Cross(&uv, &qvec, v);
kmVec3Cross(&uuv, &qvec, &uv);
kmVec3Scale(&uv, &uv, (2.0f * q->w));
kmVec3Scale(&uuv, &uuv, 2.0f);
kmVec3Add(pOut, v, &uv);
kmVec3Add(pOut, pOut, &uuv);
return pOut;
}
kmVec3* kmQuaternionGetUpVec3(kmVec3* pOut, const kmQuaternion* pIn) {
return kmQuaternionMultiplyVec3(pOut, pIn, &KM_VEC3_POS_Y);
}
kmVec3* kmQuaternionGetRightVec3(kmVec3* pOut, const kmQuaternion* pIn) {
return kmQuaternionMultiplyVec3(pOut, pIn, &KM_VEC3_POS_X);
}
kmVec3* kmQuaternionGetForwardVec3RH(kmVec3* pOut, const kmQuaternion* pIn) {
return kmQuaternionMultiplyVec3(pOut, pIn, &KM_VEC3_NEG_Z);
}
kmVec3* kmQuaternionGetForwardVec3LH(kmVec3* pOut, const kmQuaternion* pIn) {
return kmQuaternionMultiplyVec3(pOut, pIn, &KM_VEC3_POS_Z);
}
kmScalar kmQuaternionGetPitch(const kmQuaternion* q) {
float result = atan2(2 * (q->y * q->z + q->w * q->x), q->w * q->w - q->x * q->x - q->y * q->y + q->z * q->z);
return result;
}
kmScalar kmQuaternionGetYaw(const kmQuaternion* q) {
float result = asin(-2 * (q->x * q->z - q->w * q->y));
return result;
}
kmScalar kmQuaternionGetRoll(const kmQuaternion* q) {
float result = atan2(2 * (q->x * q->y + q->w * q->z), q->w * q->w + q->x * q->x - q->y * q->y - q->z * q->z);
return result;
}
kmQuaternion* kmQuaternionLookRotation(kmQuaternion* pOut, const kmVec3* direction, const kmVec3* up) {
kmMat3 tmp;
kmMat3LookAt(&tmp, &KM_VEC3_ZERO, direction, up);
return kmQuaternionNormalize(pOut, kmQuaternionRotationMatrix(pOut, &tmp));
/*
if(!direction->x && !direction->y && !direction->z) {
return kmQuaternionIdentity(pOut);
}
kmVec3 right;
kmVec3Cross(&right, up, direction);
pOut->w = sqrtf(1.0f + right.x + up->y + direction->z) * 0.5f;
float w4_recip = 1.0f / (4.0f * pOut->w);
pOut->x = (up->z - direction->y) * w4_recip;
pOut->y = (direction->x - right.z) * w4_recip;
pOut->z = (right.y - up->x) * w4_recip;
return kmQuaternionNormalize(pOut, pOut);*/
}

View File

@ -1,125 +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 "utility.h"
struct kmMat4;
struct kmMat3;
struct kmVec3;
typedef struct kmQuaternion {
kmScalar x;
kmScalar y;
kmScalar z;
kmScalar w;
} kmQuaternion;
CC_DLL int kmQuaternionAreEqual(const kmQuaternion* p1, const kmQuaternion* p2);
CC_DLL kmQuaternion* kmQuaternionFill(kmQuaternion* pOut, kmScalar x, kmScalar y, kmScalar z, kmScalar w);
CC_DLL 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* kmQuaternionRotationAxisAngle(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* kmQuaternionRotationPitchYawRoll(kmQuaternion* pOut, kmScalar pitch, kmScalar yaw, 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* kmQuaternionSubtract(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);
CC_DLL kmVec3* kmQuaternionGetUpVec3(kmVec3* pOut, const kmQuaternion* pIn);
CC_DLL kmVec3* kmQuaternionGetRightVec3(kmVec3* pOut, const kmQuaternion* pIn);
CC_DLL kmVec3* kmQuaternionGetForwardVec3RH(kmVec3* pOut, const kmQuaternion* pIn);
CC_DLL kmVec3* kmQuaternionGetForwardVec3LH(kmVec3* pOut, const kmQuaternion* pIn);
CC_DLL kmScalar kmQuaternionGetPitch(const kmQuaternion* q);
CC_DLL kmScalar kmQuaternionGetYaw(const kmQuaternion* q);
CC_DLL kmScalar kmQuaternionGetRoll(const kmQuaternion* q);
CC_DLL kmQuaternion* kmQuaternionLookRotation(kmQuaternion* pOut, const kmVec3* direction, const kmVec3* up);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,200 +0,0 @@
#include <assert.h>
#include <stdio.h>
#include "ray2.h"
void kmRay2Fill(kmRay2* ray, kmScalar px, kmScalar py, kmScalar vx, kmScalar vy) {
ray->start.x = px;
ray->start.y = py;
ray->dir.x = vx;
ray->dir.y = vy;
}
kmBool kmRay2IntersectLineSegment(const kmRay2* ray, const kmVec2* p1, const kmVec2* p2, kmVec2* intersection) {
kmScalar x1 = ray->start.x;
kmScalar y1 = ray->start.y;
kmScalar x2 = ray->start.x + ray->dir.x;
kmScalar y2 = ray->start.y + ray->dir.y;
kmScalar x3 = p1->x;
kmScalar y3 = p1->y;
kmScalar x4 = p2->x;
kmScalar y4 = p2->y;
kmScalar denom = (y4 -y3) * (x2 - x1) - (x4 - x3) * (y2 - y1);
//If denom is zero, the lines are parallel
if(denom > -kmEpsilon && denom < kmEpsilon) {
return KM_FALSE;
}
kmScalar ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / denom;
kmScalar ub = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / denom;
kmScalar x = x1 + ua * (x2 - x1);
kmScalar y = y1 + ua * (y2 - y1);
if((0.0 <= ua) && (ua <= 1.0) && (0.0 <= ub) && (ub <= 1.0)) {
intersection->x = x;
intersection->y = y;
return KM_TRUE;
}
return KM_FALSE;
}
void calculate_line_normal(kmVec2 p1, kmVec2 p2, kmVec2 other_point, kmVec2* normal_out) {
/*
A = (3,4)
B = (2,1)
C = (1,3)
AB = (2,1) - (3,4) = (-1,-3)
AC = (1,3) - (3,4) = (-2,-1)
N = n(AB) = (-3,1)
D = dot(N,AC) = 6 + -1 = 5
since D > 0:
N = -N = (3,-1)
*/
kmVec2 edge, other_edge;
kmVec2Subtract(&edge, &p2, &p1);
kmVec2Subtract(&other_edge, &other_point, &p1);
kmVec2Normalize(&edge, &edge);
kmVec2Normalize(&other_edge, &other_edge);
kmVec2 n;
n.x = edge.y;
n.y = -edge.x;
kmScalar d = kmVec2Dot(&n, &other_edge);
if(d > 0.0f) {
n.x = -n.x;
n.y = -n.y;
}
normal_out->x = n.x;
normal_out->y = n.y;
kmVec2Normalize(normal_out, normal_out);
}
kmBool kmRay2IntersectTriangle(const kmRay2* ray, const kmVec2* p1, const kmVec2* p2, const kmVec2* p3, kmVec2* intersection, kmVec2* normal_out, kmScalar* distance_out) {
kmVec2 intersect;
kmVec2 final_intersect;
kmVec2 normal;
kmScalar distance = 10000.0f;
kmBool intersected = KM_FALSE;
if(kmRay2IntersectLineSegment(ray, p1, p2, &intersect)) {
kmVec2 tmp;
kmScalar this_distance = kmVec2Length(kmVec2Subtract(&tmp, &intersect, &ray->start));
kmVec2 this_normal;
calculate_line_normal(*p1, *p2, *p3, &this_normal);
if(this_distance < distance && kmVec2Dot(&this_normal, &ray->dir) < 0.0f) {
final_intersect.x = intersect.x;
final_intersect.y = intersect.y;
distance = this_distance;
kmVec2Assign(&normal, &this_normal);
intersected = KM_TRUE;
}
}
if(kmRay2IntersectLineSegment(ray, p2, p3, &intersect)) {
kmVec2 tmp;
kmScalar this_distance = kmVec2Length(kmVec2Subtract(&tmp, &intersect, &ray->start));
kmVec2 this_normal;
calculate_line_normal(*p2, *p3, *p1, &this_normal);
if(this_distance < distance && kmVec2Dot(&this_normal, &ray->dir) < 0.0f) {
final_intersect.x = intersect.x;
final_intersect.y = intersect.y;
distance = this_distance;
kmVec2Assign(&normal, &this_normal);
intersected = KM_TRUE;
}
}
if(kmRay2IntersectLineSegment(ray, p3, p1, &intersect)) {
kmVec2 tmp;
kmScalar this_distance = kmVec2Length(kmVec2Subtract(&tmp, &intersect, &ray->start));
kmVec2 this_normal;
calculate_line_normal(*p3, *p1, *p2, &this_normal);
if(this_distance < distance && kmVec2Dot(&this_normal, &ray->dir) < 0.0f) {
final_intersect.x = intersect.x;
final_intersect.y = intersect.y;
distance = this_distance;
kmVec2Assign(&normal, &this_normal);
intersected = KM_TRUE;
}
}
if(intersected) {
intersection->x = final_intersect.x;
intersection->y = final_intersect.y;
if(normal_out) {
normal_out->x = normal.x;
normal_out->y = normal.y;
}
if(distance) {
*distance_out = distance;
}
}
return intersected;
}
kmBool kmRay2IntersectBox(const kmRay2* ray, const kmVec2* p1, const kmVec2* p2, const kmVec2* p3, const kmVec2* p4,
kmVec2* intersection, kmVec2* normal_out) {
kmBool intersected = KM_FALSE;
kmVec2 intersect, final_intersect, normal;
kmScalar distance = 10000.0f;
const kmVec2* points[4];
points[0] = p1;
points[1] = p2;
points[2] = p3;
points[3] = p4;
unsigned int i = 0;
for(; i < 4; ++i) {
const kmVec2* this_point = points[i];
const kmVec2* next_point = (i == 3) ? points[0] : points[i+1];
const kmVec2* other_point = (i == 3 || i == 0) ? points[1] : points[0];
if(kmRay2IntersectLineSegment(ray, this_point, next_point, &intersect)) {
kmVec2 tmp;
kmScalar this_distance = kmVec2Length(kmVec2Subtract(&tmp, &intersect, &ray->start));
kmVec2 this_normal;
calculate_line_normal(*this_point, *next_point, *other_point, &this_normal);
if(this_distance < distance && kmVec2Dot(&this_normal, &ray->dir) < 0.0f) {
kmVec2Assign(&final_intersect, &intersect);
distance = this_distance;
intersected = KM_TRUE;
kmVec2Assign(&normal, &this_normal);
}
}
}
if(intersected) {
intersection->x = final_intersect.x;
intersection->y = final_intersect.y;
if(normal_out) {
normal_out->x = normal.x;
normal_out->y = normal.y;
}
}
return intersected;
}
kmBool kmRay2IntersectCircle(const kmRay2* ray, const kmVec2 centre, const kmScalar radius, kmVec2* intersection) {
assert(0 && "Not implemented");
return KM_TRUE;
}

View File

@ -1,54 +0,0 @@
/*
Copyright (c) 2011, 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 RAY_2_H
#define RAY_2_H
#include "utility.h"
#include "vec2.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct kmRay2 {
kmVec2 start;
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, kmScalar* distance);
CC_DLL kmBool kmRay2IntersectBox(const kmRay2* ray, const kmVec2* p1, const kmVec2* p2, const kmVec2* p3, const kmVec2* p4,
CC_DLL kmVec2* intersection, kmVec2* normal_out);
CC_DLL kmBool kmRay2IntersectCircle(const kmRay2* ray, const kmVec2 centre, const kmScalar radius, kmVec2* intersection);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,47 +0,0 @@
#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;
}

View File

@ -1,26 +0,0 @@
#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;
CC_DLL kmRay3* kmRay3Fill(kmRay3* ray, kmScalar px, kmScalar py, kmScalar pz, kmScalar vx, kmScalar vy, kmScalar vz);
CC_DLL kmRay3* kmRay3FromPointAndDirection(kmRay3* ray, const kmVec3* point, const kmVec3* direction);
CC_DLL kmBool kmRay3IntersectPlane(kmVec3* pOut, const kmRay3* ray, const struct kmPlane* plane);
#ifdef __cplusplus
}
#endif
#endif // RAY3_H

View File

@ -1,69 +0,0 @@
/*
Copyright (c) 2008, Luke Benstead.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "utility.h"
/**
* Returns the square of s (e.g. s*s)
*/
kmScalar kmSQR(kmScalar s) {
return s*s;
}
/**
* Returns degrees as radians.
*/
kmScalar kmDegreesToRadians(kmScalar degrees) {
return degrees * kmPIOver180;
}
/**
* Returns radians as degrees
*/
kmScalar kmRadiansToDegrees(kmScalar radians) {
return radians * kmPIUnder180;
}
kmScalar kmMin(kmScalar lhs, kmScalar rhs) {
return (lhs < rhs)? lhs : rhs;
}
kmScalar kmMax(kmScalar lhs, kmScalar rhs) {
return (lhs > rhs)? lhs : 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 );
}

View File

@ -1,96 +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 UTILITY_H_INCLUDED
#define UTILITY_H_INCLUDED
#include <math.h>
#ifndef kmScalar
#ifdef USE_DOUBLE_PRECISION
#define kmScalar double
#else
#define kmScalar float
#endif
#endif
#ifndef kmBool
#define kmBool unsigned char
#endif
#ifndef kmUchar
#define kmUchar unsigned char
#endif
#ifndef kmEnum
#define kmEnum unsigned int
#endif
#ifndef kmUint
#define kmUint unsigned int
#endif
#ifndef kmInt
#define kmInt int
#endif
#ifndef KM_FALSE
#define KM_FALSE 0
#endif
#ifndef KM_TRUE
#define KM_TRUE 1
#endif
#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
extern kmScalar kmSQR(kmScalar s);
extern kmScalar kmDegreesToRadians(kmScalar degrees);
extern kmScalar kmRadiansToDegrees(kmScalar radians);
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
}
#endif
#endif /* UTILITY_H_INCLUDED */

View File

@ -1,239 +0,0 @@
/*
Copyright (c) 2008, Luke Benstead.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <assert.h>
#include <stdlib.h>
#include "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;
}

View File

@ -1,79 +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"
#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
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* kmVec2Lerp(kmVec2* pOut, const kmVec2* pV1, const kmVec2* pV2, kmScalar t);
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 kmScalar kmVec2Cross(const kmVec2* pV1, const kmVec2* pV2);
CC_DLL kmVec2* kmVec2Subtract(kmVec2* pOut, const kmVec2* pV1, const kmVec2* pV2); ///< Subtracts 2 vectors and returns the result
CC_DLL kmVec2* kmVec2Mul( kmVec2* pOut,const kmVec2* pV1, const kmVec2* pV2 ); ///< Component-wise multiplication
CC_DLL kmVec2* kmVec2Div( kmVec2* pOut,const kmVec2* pV1, const kmVec2* pV2 ); ///< Component-wise division
CC_DLL kmVec2* kmVec2Transform(kmVec2* pOut, const kmVec2* pV1, const struct kmMat3* pM); /** Transform the Vector */
CC_DLL kmVec2* kmVec2TransformCoord(kmVec2* pOut, const kmVec2* pV, const struct kmMat3* pM); ///<Transforms a 2D vector by a given matrix, projecting the result back into w = 1.
CC_DLL kmVec2* kmVec2Scale(kmVec2* pOut, const kmVec2* pIn, const kmScalar s); ///< Scales a vector to length s
CC_DLL int kmVec2AreEqual(const kmVec2* p1, const kmVec2* p2); ///< Returns 1 if both vectors are equal
CC_DLL kmVec2* kmVec2Assign(kmVec2* pOut, const kmVec2* pIn);
CC_DLL kmVec2* kmVec2RotateBy(kmVec2* pOut, const kmVec2* pIn, const kmScalar degrees, const kmVec2* center); ///<Rotates the point anticlockwise around a center by an amount of degrees.
CC_DLL kmScalar kmVec2DegreesBetween(const kmVec2* v1, const kmVec2* v2);
CC_DLL kmScalar kmVec2DistanceBetween(const kmVec2* v1, const kmVec2* v2);
CC_DLL kmVec2* kmVec2MidPointBetween(kmVec2* pOut, const kmVec2* v1, const kmVec2* v2);
extern const kmVec2 KM_VEC2_POS_Y;
extern const kmVec2 KM_VEC2_NEG_Y;
extern const kmVec2 KM_VEC2_NEG_X;
extern const kmVec2 KM_VEC2_POS_X;
extern const kmVec2 KM_VEC2_ZERO;
#ifdef __cplusplus
}
#endif
#endif // VEC2_H_INCLUDED

View File

@ -1,444 +0,0 @@
/*
Copyright (c) 2008, Luke Benstead.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file vec3.c
*/
#include <assert.h>
#include <memory.h>
#include "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 = 1bw(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;
}

View File

@ -1,89 +0,0 @@
/*
Copyright (c) 2008, Luke Benstead.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef VEC3_H_INCLUDED
#define VEC3_H_INCLUDED
#include "CCPlatformMacros.h"
#include <assert.h>
#include "utility.h"
struct kmMat4;
struct kmMat3;
struct kmPlane;
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* kmVec3Lerp(kmVec3* pOut, const kmVec3* pV1, const kmVec3* pV2, kmScalar t);
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* kmVec3Mul( kmVec3* pOut,const kmVec3* pV1, const kmVec3* pV2 );
CC_DLL kmVec3* kmVec3Div( kmVec3* pOut,const kmVec3* pV1, const kmVec3* pV2 );
CC_DLL kmVec3* kmVec3MultiplyMat3(kmVec3 *pOut, const kmVec3 *pV, const struct kmMat3* pM);
CC_DLL kmVec3* kmVec3MultiplyMat4(kmVec3* pOut, const kmVec3* pV, const struct kmMat4* pM);
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);
CC_DLL 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. */
CC_DLL kmVec3* kmVec3RotationToDirection(kmVec3* pOut, const kmVec3* pIn, const kmVec3* forwards); /** Builds a direction vector from input vector. */
CC_DLL 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 */

View File

@ -1,187 +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 <memory.h>
#include <assert.h>
#include "utility.h"
#include "vec4.h"
#include "mat4.h"
#include "neon_matrix_impl.h"
kmVec4* kmVec4Fill(kmVec4* pOut, kmScalar x, kmScalar y, kmScalar z, kmScalar w)
{
pOut->x = x;
pOut->y = y;
pOut->z = z;
pOut->w = w;
return pOut;
}
/// 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;
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 );
}
/// 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));
}
/// 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);
}
/// Returns the interpolation of 2 4D vectors based on t.
kmVec4* kmVec4Lerp(kmVec4* pOut, const kmVec4* pV1, const kmVec4* 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 );
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) {
if (!pIn->x && !pIn->y && !pIn->z && !pIn->w){
return kmVec4Assign(pOut, pIn);
}
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;
}
/// 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);
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;
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;
}
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) {
#if defined(__ARM_NEON__) && !defined(__arm64__)
NEON_Matrix4Vector4Mul(&pM->mat[0], (const float*)pV, (float*)pOut);
#else
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];
pOut->w = pV->x * pM->mat[3] + pV->y * pM->mat[7] + pV->z * pM->mat[11] + pV->w * pM->mat[15];
#endif
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) {
unsigned int i = 0;
//Go through all of the vectors
while (i < count) {
const kmVec4* in = pV + (i * vStride); //Get a pointer to the current input
kmVec4* out = pOut + (i * outStride); //and the current output
kmVec4Transform(out, in, pM); //Perform transform on it
++i;
}
return pOut;
}
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)
);
}
kmVec4* kmVec4Assign(kmVec4* pOut, const kmVec4* pIn) {
assert(pOut != pIn);
memcpy(pOut, pIn, sizeof(kmScalar) * 4);
return pOut;
}

View File

@ -1,74 +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 VEC4_H_INCLUDED
#define VEC4_H_INCLUDED
#include "CCPlatformMacros.h"
#include "utility.h"
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;
} kmVec4;
#pragma pack(pop)
#ifdef __cplusplus
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* kmVec4Mul( kmVec4* pOut,const kmVec4* pV1, const kmVec4* pV2 );
CC_DLL kmVec4* kmVec4Div( kmVec4* pOut,const kmVec4* pV1, const kmVec4* pV2 );
CC_DLL kmVec4* kmVec4MultiplyMat4(kmVec4* pOut, const kmVec4* pV, const struct kmMat4* pM);
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);
#ifdef __cplusplus
}
#endif
#endif // VEC4_H_INCLUDED