mirror of https://github.com/axmolengine/axmol.git
IOS/Mac OK: remove kazMath
Make code compatible with old tests
This commit is contained in:
parent
e74f8719cf
commit
68e058b12d
|
@ -1 +1 @@
|
|||
6317ab72408dd11d925c99ccebee59b12e41074d
|
||||
e6cb148185cfef8c71e62f3e83178e3eede69200
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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"
|
||||
)
|
|
@ -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)
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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 */
|
|
@ -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
|
|
@ -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__
|
|
@ -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 = −N⋅P
|
||||
*/
|
||||
|
||||
|
||||
pOut->a = pNormal->x;
|
||||
pOut->b = pNormal->y;
|
||||
pOut->c = pNormal->z;
|
||||
pOut->d = -kmVec3Dot(pNormal, pPoint);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a plane from 3 points. The result is stored in pOut.
|
||||
* pOut is returned.
|
||||
*/
|
||||
kmPlane* kmPlaneFromPoints(kmPlane* pOut, const kmVec3* p1, const kmVec3* p2, const kmVec3* p3)
|
||||
{
|
||||
/*
|
||||
v = (B − A) × (C − A)
|
||||
n = 1⁄|v| v
|
||||
Outa = nx
|
||||
Outb = ny
|
||||
Outc = nz
|
||||
Outd = −n⋅A
|
||||
*/
|
||||
|
||||
kmVec3 n, v1, v2;
|
||||
kmVec3Subtract(&v1, p2, p1); //Create the vectors for the 2 sides of the triangle
|
||||
kmVec3Subtract(&v2, p3, p1);
|
||||
kmVec3Cross(&n, &v1, &v2); //Use the cross product to get the normal
|
||||
|
||||
kmVec3Normalize(&n, &n); //Normalize it and assign to pOut->m_N
|
||||
|
||||
pOut->a = n.x;
|
||||
pOut->b = n.y;
|
||||
pOut->c = n.z;
|
||||
pOut->d = kmVec3Dot(kmVec3Scale(&n, &n, -1.0), p1);
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
// Added by tlensing (http://icedcoffee-framework.org)
|
||||
kmVec3* kmPlaneIntersectLine(kmVec3* pOut, const kmPlane* pP, const kmVec3* pV1, const kmVec3* pV2)
|
||||
{
|
||||
/*
|
||||
n = (Planea, Planeb, Planec)
|
||||
d = V − U
|
||||
Out = U − d⋅(Pd + n⋅U)⁄(d⋅n) [iff d⋅n ≠ 0]
|
||||
*/
|
||||
kmVec3 d; // direction from V1 to V2
|
||||
kmVec3Subtract(&d, pV2, pV1); // Get the direction vector
|
||||
|
||||
kmVec3 n; // plane normal
|
||||
n.x = pP->a;
|
||||
n.y = pP->b;
|
||||
n.z = pP->c;
|
||||
kmVec3Normalize(&n, &n);
|
||||
|
||||
kmScalar nt = -(n.x * pV1->x + n.y * pV1->y + n.z * pV1->z + pP->d);
|
||||
kmScalar dt = (n.x * d.x + n.y * d.y + n.z * d.z);
|
||||
|
||||
if (fabs(dt) < kmEpsilon) {
|
||||
pOut = NULL;
|
||||
return pOut; // line parallel or contained
|
||||
}
|
||||
|
||||
kmScalar t = nt/dt;
|
||||
pOut->x = pV1->x + d.x * t;
|
||||
pOut->y = pV1->y + d.y * t;
|
||||
pOut->z = pV1->z + d.z * t;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmPlane* kmPlaneNormalize(kmPlane* pOut, const kmPlane* pP)
|
||||
{
|
||||
kmVec3 n;
|
||||
kmScalar l = 0;
|
||||
|
||||
if (!pP->a && !pP->b && !pP->c) {
|
||||
pOut->a = pP->a;
|
||||
pOut->b = pP->b;
|
||||
pOut->c = pP->c;
|
||||
pOut->d = pP->d;
|
||||
return pOut;
|
||||
}
|
||||
|
||||
n.x = pP->a;
|
||||
n.y = pP->b;
|
||||
n.z = pP->c;
|
||||
|
||||
l = 1.0f / kmVec3Length(&n); //Get 1/length
|
||||
kmVec3Normalize(&n, &n); //Normalize the vector and assign to pOut
|
||||
|
||||
pOut->a = n.x;
|
||||
pOut->b = n.y;
|
||||
pOut->c = n.z;
|
||||
|
||||
pOut->d = pP->d * l; //Scale the D value and assign to pOut
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmPlane* kmPlaneScale(kmPlane* pOut, const kmPlane* pP, kmScalar s)
|
||||
{
|
||||
assert(0 && "Not implemented");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns POINT_INFRONT_OF_PLANE if pP is infront of pIn. Returns
|
||||
* POINT_BEHIND_PLANE if it is behind. Returns POINT_ON_PLANE otherwise
|
||||
*/
|
||||
KM_POINT_CLASSIFICATION kmPlaneClassifyPoint(const kmPlane* pIn, const kmVec3* pP)
|
||||
{
|
||||
// This function will determine if a point is on, in front of, or behind
|
||||
// the plane. First we store the dot product of the plane and the point.
|
||||
kmScalar distance = pIn->a * pP->x + pIn->b * pP->y + pIn->c * pP->z + pIn->d;
|
||||
|
||||
// Simply put if the dot product is greater than 0 then it is infront of it.
|
||||
// If it is less than 0 then it is behind it. And if it is 0 then it is on it.
|
||||
if(distance > kmEpsilon) return POINT_INFRONT_OF_PLANE;
|
||||
if(distance < -kmEpsilon) return POINT_BEHIND_PLANE;
|
||||
|
||||
return POINT_ON_PLANE;
|
||||
}
|
||||
|
||||
kmPlane* kmPlaneExtractFromMat4(kmPlane* pOut, const struct kmMat4* pIn, kmInt row) {
|
||||
int scale = (row < 0) ? -1 : 1;
|
||||
row = abs(row) - 1;
|
||||
|
||||
pOut->a = pIn->mat[3] + scale * pIn->mat[row];
|
||||
pOut->b = pIn->mat[7] + scale * pIn->mat[row + 4];
|
||||
pOut->c = pIn->mat[11] + scale * pIn->mat[row + 8];
|
||||
pOut->d = pIn->mat[15] + scale * pIn->mat[row + 12];
|
||||
|
||||
return kmPlaneNormalize(pOut, pOut);
|
||||
}
|
||||
|
||||
kmVec3* kmPlaneGetIntersection(kmVec3* pOut, const kmPlane* p1, const kmPlane* p2, const kmPlane* p3) {
|
||||
kmVec3 n1, n2, n3, cross;
|
||||
kmVec3 r1, r2, r3;
|
||||
double denom = 0;
|
||||
|
||||
kmVec3Fill(&n1, p1->a, p1->b, p1->c);
|
||||
kmVec3Fill(&n2, p2->a, p2->b, p2->c);
|
||||
kmVec3Fill(&n3, p3->a, p3->b, p3->c);
|
||||
|
||||
kmVec3Cross(&cross, &n2, &n3);
|
||||
|
||||
denom = kmVec3Dot(&n1, &cross);
|
||||
|
||||
if (kmAlmostEqual(denom, 0.0)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
kmVec3Cross(&r1, &n2, &n3);
|
||||
kmVec3Cross(&r2, &n3, &n1);
|
||||
kmVec3Cross(&r3, &n1, &n2);
|
||||
|
||||
kmVec3Scale(&r1, &r1, -p1->d);
|
||||
kmVec3Scale(&r2, &r2, p2->d);
|
||||
kmVec3Scale(&r3, &r3, p3->d);
|
||||
|
||||
kmVec3Subtract(pOut, &r1, &r2);
|
||||
kmVec3Subtract(pOut, pOut, &r3);
|
||||
kmVec3Scale(pOut, pOut, 1.0 / denom);
|
||||
|
||||
//p = -d1 * ( n2.Cross ( n3 ) ) – d2 * ( n3.Cross ( n1 ) ) – d3 * ( n1.Cross ( n2 ) ) / denom;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmPlane* kmPlaneFill(kmPlane* plane, kmScalar a, kmScalar b, kmScalar c, kmScalar d) {
|
||||
plane->a = a;
|
||||
plane->b = b;
|
||||
plane->c = c;
|
||||
plane->d = d;
|
||||
|
||||
return plane;
|
||||
}
|
|
@ -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
|
|
@ -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);*/
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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 );
|
||||
}
|
|
@ -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 */
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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 = 1⁄bw(bx, by, bz)
|
||||
*/
|
||||
|
||||
kmVec4 v;
|
||||
kmVec4 inV;
|
||||
kmVec4Fill(&inV, pV->x, pV->y, pV->z, 1.0);
|
||||
|
||||
kmVec4Transform(&v, &inV,pM);
|
||||
|
||||
pOut->x = v.x / v.w;
|
||||
pOut->y = v.y / v.w;
|
||||
pOut->z = v.z / v.w;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec3* kmVec3TransformNormal(kmVec3* pOut, const kmVec3* pV, const kmMat4* pM)
|
||||
{
|
||||
/*
|
||||
a = (Vx, Vy, Vz, 0)
|
||||
b = (a×M)T
|
||||
Out = (bx, by, bz)
|
||||
*/
|
||||
//Omits the translation, only scaling + rotating
|
||||
kmVec3 v;
|
||||
|
||||
v.x = pV->x * pM->mat[0] + pV->y * pM->mat[4] + pV->z * pM->mat[8];
|
||||
v.y = pV->x * pM->mat[1] + pV->y * pM->mat[5] + pV->z * pM->mat[9];
|
||||
v.z = pV->x * pM->mat[2] + pV->y * pM->mat[6] + pV->z * pM->mat[10];
|
||||
|
||||
pOut->x = v.x;
|
||||
pOut->y = v.y;
|
||||
pOut->z = v.z;
|
||||
|
||||
return pOut;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Scales a vector to length s. Does not normalize first,
|
||||
* you should do that!
|
||||
*/
|
||||
kmVec3* kmVec3Scale(kmVec3* pOut, const kmVec3* pIn, const kmScalar s)
|
||||
{
|
||||
pOut->x = pIn->x * s;
|
||||
pOut->y = pIn->y * s;
|
||||
pOut->z = pIn->z * s;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns KM_TRUE if the 2 vectors are approximately equal
|
||||
*/
|
||||
int kmVec3AreEqual(const kmVec3* p1, const kmVec3* p2)
|
||||
{
|
||||
if ((p1->x < (p2->x + kmEpsilon) && p1->x > (p2->x - kmEpsilon)) &&
|
||||
(p1->y < (p2->y + kmEpsilon) && p1->y > (p2->y - kmEpsilon)) &&
|
||||
(p1->z < (p2->z + kmEpsilon) && p1->z > (p2->z - kmEpsilon))) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns pIn to pOut. Returns pOut. If pIn and pOut are the same
|
||||
* then nothing happens but pOut is still returned
|
||||
*/
|
||||
kmVec3* kmVec3Assign(kmVec3* pOut, const kmVec3* pIn) {
|
||||
if (pOut == pIn) {
|
||||
return pOut;
|
||||
}
|
||||
|
||||
pOut->x = pIn->x;
|
||||
pOut->y = pIn->y;
|
||||
pOut->z = pIn->z;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets all the elements of pOut to zero. Returns pOut.
|
||||
*/
|
||||
kmVec3* kmVec3Zero(kmVec3* pOut) {
|
||||
pOut->x = 0.0f;
|
||||
pOut->y = 0.0f;
|
||||
pOut->z = 0.0f;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rotations that would make a (0,0,1) direction vector point in the same direction as this direction vector.
|
||||
* Useful for orienting vector towards a point.
|
||||
*
|
||||
* Returns a rotation vector containing the X (pitch) and Y (raw) rotations (in degrees) that when applied to a
|
||||
* +Z (e.g. 0, 0, 1) direction vector would make it point in the same direction as this vector. The Z (roll) rotation
|
||||
* is always 0, since two Euler rotations are sufficient to point in any given direction.
|
||||
*
|
||||
* Code ported from Irrlicht: http://irrlicht.sourceforge.net/
|
||||
*/
|
||||
kmVec3* kmVec3GetHorizontalAngle(kmVec3* pOut, const kmVec3 *pIn) {
|
||||
const kmScalar z1 = sqrt(pIn->x * pIn->x + pIn->z * pIn->z);
|
||||
|
||||
pOut->y = kmRadiansToDegrees(atan2(pIn->x, pIn->z));
|
||||
if (pOut->y < 0)
|
||||
pOut->y += 360;
|
||||
if (pOut->y >= 360)
|
||||
pOut->y -= 360;
|
||||
|
||||
pOut->x = kmRadiansToDegrees(atan2(z1, pIn->y)) - 90.0;
|
||||
if (pOut->x < 0)
|
||||
pOut->x += 360;
|
||||
if (pOut->x >= 360)
|
||||
pOut->x -= 360;
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a direction vector from input vector.
|
||||
* Input vector is assumed to be rotation vector composed from 3 Euler angle rotations, in degrees.
|
||||
* The forwards vector will be rotated by the input vector
|
||||
*
|
||||
* Code ported from Irrlicht: http://irrlicht.sourceforge.net/
|
||||
*/
|
||||
kmVec3* kmVec3RotationToDirection(kmVec3* pOut, const kmVec3* pIn, const kmVec3* forwards)
|
||||
{
|
||||
const kmScalar xr = kmDegreesToRadians(pIn->x);
|
||||
const kmScalar yr = kmDegreesToRadians(pIn->y);
|
||||
const kmScalar zr = kmDegreesToRadians(pIn->z);
|
||||
const kmScalar cr = cos(xr), sr = sin(xr);
|
||||
const kmScalar cp = cos(yr), sp = sin(yr);
|
||||
const kmScalar cy = cos(zr), sy = sin(zr);
|
||||
|
||||
const kmScalar srsp = sr*sp;
|
||||
const kmScalar crsp = cr*sp;
|
||||
|
||||
const kmScalar pseudoMatrix[] = {
|
||||
(cp*cy), (cp*sy), (-sp),
|
||||
(srsp*cy-cr*sy), (srsp*sy+cr*cy), (sr*cp),
|
||||
(crsp*cy+sr*sy), (crsp*sy-sr*cy), (cr*cp)
|
||||
};
|
||||
|
||||
pOut->x = forwards->x * pseudoMatrix[0] +
|
||||
forwards->y * pseudoMatrix[3] +
|
||||
forwards->z * pseudoMatrix[6];
|
||||
|
||||
pOut->y = forwards->x * pseudoMatrix[1] +
|
||||
forwards->y * pseudoMatrix[4] +
|
||||
forwards->z * pseudoMatrix[7];
|
||||
|
||||
pOut->z = forwards->x * pseudoMatrix[2] +
|
||||
forwards->y * pseudoMatrix[5] +
|
||||
forwards->z * pseudoMatrix[8];
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
kmVec3* kmVec3ProjectOnToPlane(kmVec3* pOut, const kmVec3* point, const struct kmPlane* plane) {
|
||||
kmRay3 ray;
|
||||
kmVec3Assign(&ray.start, point);
|
||||
ray.dir.x = -plane->a;
|
||||
ray.dir.y = -plane->b;
|
||||
ray.dir.z = -plane->c;
|
||||
|
||||
kmRay3IntersectPlane(pOut, &ray, plane);
|
||||
return pOut;
|
||||
}
|
|
@ -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 */
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
Loading…
Reference in New Issue