mirror of
https://github.com/bulletphysics/bullet3
synced 2024-12-13 13:20:07 +00:00
Add preliminary support for VR/OpenVR for HTC Vive and Oculus Rift,
(Windows-only first, later Linux and OSX) Use premake to build, use --enable_openvr flag
This commit is contained in:
parent
eae90eb201
commit
58206b7962
@ -29,6 +29,11 @@
|
|||||||
description = "Try to link and use the system OpenGL headers version instead of dynamically loading OpenGL (dlopen is default)"
|
description = "Try to link and use the system OpenGL headers version instead of dynamically loading OpenGL (dlopen is default)"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
newoption
|
||||||
|
{
|
||||||
|
trigger = "enable_openvr",
|
||||||
|
description = "Enable experimental Virtual Reality examples, using OpenVR for HTC Vive and Oculus Rift"
|
||||||
|
}
|
||||||
newoption
|
newoption
|
||||||
{
|
{
|
||||||
trigger = "enable_system_x11",
|
trigger = "enable_system_x11",
|
||||||
|
@ -59,6 +59,7 @@ end
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
project "App_BasicExampleGuiWithSoftwareRenderer"
|
project "App_BasicExampleGuiWithSoftwareRenderer"
|
||||||
|
|
||||||
if _OPTIONS["ios"] then
|
if _OPTIONS["ios"] then
|
||||||
@ -133,3 +134,62 @@ files {
|
|||||||
"../TinyRenderer/TinyRenderer.cpp",
|
"../TinyRenderer/TinyRenderer.cpp",
|
||||||
"../Utils/b3ResourcePath.cpp"
|
"../Utils/b3ResourcePath.cpp"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if _OPTIONS["enable_openvr"] then
|
||||||
|
|
||||||
|
project "App_BasicExampleVR"
|
||||||
|
|
||||||
|
if _OPTIONS["ios"] then
|
||||||
|
kind "WindowedApp"
|
||||||
|
else
|
||||||
|
kind "ConsoleApp"
|
||||||
|
end
|
||||||
|
defines {"B3_USE_STANDALONE_EXAMPLE","BT_ENABLE_VR"}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
includedirs {"../../src",
|
||||||
|
"../ThirdPartyLibs/openvr/headers",
|
||||||
|
"../ThirdPartyLibs/openvr/samples/shared"}
|
||||||
|
|
||||||
|
links {
|
||||||
|
"BulletDynamics","BulletCollision", "LinearMath", "OpenGL_Window","Bullet3Common", "openvr_api"
|
||||||
|
}
|
||||||
|
|
||||||
|
initOpenGL()
|
||||||
|
initGlew()
|
||||||
|
|
||||||
|
|
||||||
|
language "C++"
|
||||||
|
|
||||||
|
files {
|
||||||
|
"BasicExample.cpp",
|
||||||
|
"*.h",
|
||||||
|
"../StandaloneMain/hellovr_opengl_main.cpp",
|
||||||
|
"../ExampleBrowser/OpenGLGuiHelper.cpp",
|
||||||
|
"../ExampleBrowser/GL_ShapeDrawer.cpp",
|
||||||
|
"../ExampleBrowser/CollisionShape2TriangleMesh.cpp",
|
||||||
|
"../ThirdPartyLibs/openvr/samples/shared/lodepng.cpp",
|
||||||
|
"../ThirdPartyLibs/openvr/samples/shared/lodepng.h",
|
||||||
|
"../ThirdPartyLibs/openvr/samples/shared/Matrices.cpp",
|
||||||
|
"../ThirdPartyLibs/openvr/samples/shared/Matrices.h",
|
||||||
|
"../ThirdPartyLibs/openvr/samples/shared/pathtools.cpp",
|
||||||
|
"../ThirdPartyLibs/openvr/samples/shared/pathtools.h",
|
||||||
|
"../ThirdPartyLibs/openvr/samples/shared/Vectors.h",
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if os.is("Windows") then
|
||||||
|
libdirs {"../ThirdPartyLibs/openvr/lib/win32"}
|
||||||
|
end
|
||||||
|
|
||||||
|
if os.is("Linux") then initX11() end
|
||||||
|
|
||||||
|
if os.is("MacOSX") then
|
||||||
|
links{"Cocoa.framework"}
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
@ -158,10 +158,13 @@ struct InternalDataRenderer : public GLInstanceRendererInternalData
|
|||||||
GLRenderToTexture* m_shadowMap;
|
GLRenderToTexture* m_shadowMap;
|
||||||
GLuint m_shadowTexture;
|
GLuint m_shadowTexture;
|
||||||
|
|
||||||
|
GLuint m_renderFrameBuffer;
|
||||||
|
|
||||||
|
|
||||||
InternalDataRenderer() :
|
InternalDataRenderer() :
|
||||||
m_shadowMap(0),
|
m_shadowMap(0),
|
||||||
m_shadowTexture(0)
|
m_shadowTexture(0),
|
||||||
|
m_renderFrameBuffer(0)
|
||||||
{
|
{
|
||||||
//clear to zero to make it obvious if the matrix is used uninitialized
|
//clear to zero to make it obvious if the matrix is used uninitialized
|
||||||
for (int i=0;i<16;i++)
|
for (int i=0;i<16;i++)
|
||||||
@ -1663,7 +1666,7 @@ b3Assert(glGetError() ==GL_NO_ERROR);
|
|||||||
{
|
{
|
||||||
glDisable (GL_BLEND);
|
glDisable (GL_BLEND);
|
||||||
}
|
}
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -1688,6 +1691,7 @@ b3Assert(glGetError() ==GL_NO_ERROR);
|
|||||||
{
|
{
|
||||||
// writeTextureToPng(shadowMapWidth,shadowMapHeight,"shadowmap.png",4);
|
// writeTextureToPng(shadowMapWidth,shadowMapHeight,"shadowmap.png",4);
|
||||||
m_data->m_shadowMap->disable();
|
m_data->m_shadowMap->disable();
|
||||||
|
glBindFramebuffer( GL_FRAMEBUFFER, m_data->m_renderFrameBuffer);
|
||||||
glViewport(dims[0],dims[1],dims[2],dims[3]);
|
glViewport(dims[0],dims[1],dims[2],dims[3]);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1733,4 +1737,10 @@ int GLInstancingRenderer::getInstanceCapacity() const
|
|||||||
{
|
{
|
||||||
return m_data->m_maxNumObjectCapacity;
|
return m_data->m_maxNumObjectCapacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GLInstancingRenderer::setRenderFrameBuffer(unsigned int renderFrameBuffer)
|
||||||
|
{
|
||||||
|
m_data->m_renderFrameBuffer = (GLuint) renderFrameBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
#endif //NO_OPENGL3
|
#endif //NO_OPENGL3
|
||||||
|
@ -132,6 +132,7 @@ public:
|
|||||||
}
|
}
|
||||||
virtual void clearZBuffer();
|
virtual void clearZBuffer();
|
||||||
|
|
||||||
|
virtual void setRenderFrameBuffer(unsigned int renderFrameBuffer);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //GL_INSTANCING_RENDERER_H
|
#endif //GL_INSTANCING_RENDERER_H
|
||||||
|
1986
examples/StandaloneMain/hellovr_opengl_main.cpp
Normal file
1986
examples/StandaloneMain/hellovr_opengl_main.cpp
Normal file
File diff suppressed because it is too large
Load Diff
BIN
examples/ThirdPartyLibs/openvr/bin/linux32/libopenvr_api.so
Normal file
BIN
examples/ThirdPartyLibs/openvr/bin/linux32/libopenvr_api.so
Normal file
Binary file not shown.
BIN
examples/ThirdPartyLibs/openvr/bin/linux64/libopenvr_api.so
Normal file
BIN
examples/ThirdPartyLibs/openvr/bin/linux64/libopenvr_api.so
Normal file
Binary file not shown.
BIN
examples/ThirdPartyLibs/openvr/bin/osx32/libopenvr_api.dylib
Normal file
BIN
examples/ThirdPartyLibs/openvr/bin/osx32/libopenvr_api.dylib
Normal file
Binary file not shown.
BIN
examples/ThirdPartyLibs/openvr/bin/win32/openvr_api.dll
Normal file
BIN
examples/ThirdPartyLibs/openvr/bin/win32/openvr_api.dll
Normal file
Binary file not shown.
BIN
examples/ThirdPartyLibs/openvr/bin/win64/openvr_api.dll
Normal file
BIN
examples/ThirdPartyLibs/openvr/bin/win64/openvr_api.dll
Normal file
Binary file not shown.
3227
examples/ThirdPartyLibs/openvr/headers/openvr.h
Normal file
3227
examples/ThirdPartyLibs/openvr/headers/openvr.h
Normal file
File diff suppressed because it is too large
Load Diff
4187
examples/ThirdPartyLibs/openvr/headers/openvr_api.cs
Normal file
4187
examples/ThirdPartyLibs/openvr/headers/openvr_api.cs
Normal file
File diff suppressed because it is too large
Load Diff
3347
examples/ThirdPartyLibs/openvr/headers/openvr_api.json
Normal file
3347
examples/ThirdPartyLibs/openvr/headers/openvr_api.json
Normal file
File diff suppressed because it is too large
Load Diff
1626
examples/ThirdPartyLibs/openvr/headers/openvr_capi.h
Normal file
1626
examples/ThirdPartyLibs/openvr/headers/openvr_capi.h
Normal file
File diff suppressed because it is too large
Load Diff
1829
examples/ThirdPartyLibs/openvr/headers/openvr_driver.h
Normal file
1829
examples/ThirdPartyLibs/openvr/headers/openvr_driver.h
Normal file
File diff suppressed because it is too large
Load Diff
BIN
examples/ThirdPartyLibs/openvr/lib/linux32/libopenvr_api.so
Normal file
BIN
examples/ThirdPartyLibs/openvr/lib/linux32/libopenvr_api.so
Normal file
Binary file not shown.
BIN
examples/ThirdPartyLibs/openvr/lib/linux64/libopenvr_api.so
Normal file
BIN
examples/ThirdPartyLibs/openvr/lib/linux64/libopenvr_api.so
Normal file
Binary file not shown.
BIN
examples/ThirdPartyLibs/openvr/lib/osx32/libopenvr_api.dylib
Normal file
BIN
examples/ThirdPartyLibs/openvr/lib/osx32/libopenvr_api.dylib
Normal file
Binary file not shown.
BIN
examples/ThirdPartyLibs/openvr/lib/win32/openvr_api.lib
Normal file
BIN
examples/ThirdPartyLibs/openvr/lib/win32/openvr_api.lib
Normal file
Binary file not shown.
BIN
examples/ThirdPartyLibs/openvr/lib/win64/openvr_api.lib
Normal file
BIN
examples/ThirdPartyLibs/openvr/lib/win64/openvr_api.lib
Normal file
Binary file not shown.
581
examples/ThirdPartyLibs/openvr/samples/shared/Matrices.cpp
Normal file
581
examples/ThirdPartyLibs/openvr/samples/shared/Matrices.cpp
Normal file
@ -0,0 +1,581 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Matrice.cpp
|
||||||
|
// ===========
|
||||||
|
// NxN Matrix Math classes
|
||||||
|
//
|
||||||
|
// The elements of the matrix are stored as column major order.
|
||||||
|
// | 0 2 | | 0 3 6 | | 0 4 8 12 |
|
||||||
|
// | 1 3 | | 1 4 7 | | 1 5 9 13 |
|
||||||
|
// | 2 5 8 | | 2 6 10 14 |
|
||||||
|
// | 3 7 11 15 |
|
||||||
|
//
|
||||||
|
// AUTHOR: Song Ho Ahn (song.ahn@gmail.com)
|
||||||
|
// CREATED: 2005-06-24
|
||||||
|
// UPDATED: 2014-09-21
|
||||||
|
//
|
||||||
|
// Copyright (C) 2005 Song Ho Ahn
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <algorithm>
|
||||||
|
#include "Matrices.h"
|
||||||
|
|
||||||
|
const float DEG2RAD = 3.141593f / 180;
|
||||||
|
const float EPSILON = 0.00001f;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// transpose 2x2 matrix
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
Matrix2& Matrix2::transpose()
|
||||||
|
{
|
||||||
|
std::swap(m[1], m[2]);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// return the determinant of 2x2 matrix
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
float Matrix2::getDeterminant()
|
||||||
|
{
|
||||||
|
return m[0] * m[3] - m[1] * m[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// inverse of 2x2 matrix
|
||||||
|
// If cannot find inverse, set identity matrix
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
Matrix2& Matrix2::invert()
|
||||||
|
{
|
||||||
|
float determinant = getDeterminant();
|
||||||
|
if(fabs(determinant) <= EPSILON)
|
||||||
|
{
|
||||||
|
return identity();
|
||||||
|
}
|
||||||
|
|
||||||
|
float tmp = m[0]; // copy the first element
|
||||||
|
float invDeterminant = 1.0f / determinant;
|
||||||
|
m[0] = invDeterminant * m[3];
|
||||||
|
m[1] = -invDeterminant * m[1];
|
||||||
|
m[2] = -invDeterminant * m[2];
|
||||||
|
m[3] = invDeterminant * tmp;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// transpose 3x3 matrix
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
Matrix3& Matrix3::transpose()
|
||||||
|
{
|
||||||
|
std::swap(m[1], m[3]);
|
||||||
|
std::swap(m[2], m[6]);
|
||||||
|
std::swap(m[5], m[7]);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// return determinant of 3x3 matrix
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
float Matrix3::getDeterminant()
|
||||||
|
{
|
||||||
|
return m[0] * (m[4] * m[8] - m[5] * m[7]) -
|
||||||
|
m[1] * (m[3] * m[8] - m[5] * m[6]) +
|
||||||
|
m[2] * (m[3] * m[7] - m[4] * m[6]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// inverse 3x3 matrix
|
||||||
|
// If cannot find inverse, set identity matrix
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
Matrix3& Matrix3::invert()
|
||||||
|
{
|
||||||
|
float determinant, invDeterminant;
|
||||||
|
float tmp[9];
|
||||||
|
|
||||||
|
tmp[0] = m[4] * m[8] - m[5] * m[7];
|
||||||
|
tmp[1] = m[2] * m[7] - m[1] * m[8];
|
||||||
|
tmp[2] = m[1] * m[5] - m[2] * m[4];
|
||||||
|
tmp[3] = m[5] * m[6] - m[3] * m[8];
|
||||||
|
tmp[4] = m[0] * m[8] - m[2] * m[6];
|
||||||
|
tmp[5] = m[2] * m[3] - m[0] * m[5];
|
||||||
|
tmp[6] = m[3] * m[7] - m[4] * m[6];
|
||||||
|
tmp[7] = m[1] * m[6] - m[0] * m[7];
|
||||||
|
tmp[8] = m[0] * m[4] - m[1] * m[3];
|
||||||
|
|
||||||
|
// check determinant if it is 0
|
||||||
|
determinant = m[0] * tmp[0] + m[1] * tmp[3] + m[2] * tmp[6];
|
||||||
|
if(fabs(determinant) <= EPSILON)
|
||||||
|
{
|
||||||
|
return identity(); // cannot inverse, make it idenety matrix
|
||||||
|
}
|
||||||
|
|
||||||
|
// divide by the determinant
|
||||||
|
invDeterminant = 1.0f / determinant;
|
||||||
|
m[0] = invDeterminant * tmp[0];
|
||||||
|
m[1] = invDeterminant * tmp[1];
|
||||||
|
m[2] = invDeterminant * tmp[2];
|
||||||
|
m[3] = invDeterminant * tmp[3];
|
||||||
|
m[4] = invDeterminant * tmp[4];
|
||||||
|
m[5] = invDeterminant * tmp[5];
|
||||||
|
m[6] = invDeterminant * tmp[6];
|
||||||
|
m[7] = invDeterminant * tmp[7];
|
||||||
|
m[8] = invDeterminant * tmp[8];
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// transpose 4x4 matrix
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
Matrix4& Matrix4::transpose()
|
||||||
|
{
|
||||||
|
std::swap(m[1], m[4]);
|
||||||
|
std::swap(m[2], m[8]);
|
||||||
|
std::swap(m[3], m[12]);
|
||||||
|
std::swap(m[6], m[9]);
|
||||||
|
std::swap(m[7], m[13]);
|
||||||
|
std::swap(m[11], m[14]);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// inverse 4x4 matrix
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
Matrix4& Matrix4::invert()
|
||||||
|
{
|
||||||
|
// If the 4th row is [0,0,0,1] then it is affine matrix and
|
||||||
|
// it has no projective transformation.
|
||||||
|
if(m[3] == 0 && m[7] == 0 && m[11] == 0 && m[15] == 1)
|
||||||
|
this->invertAffine();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->invertGeneral();
|
||||||
|
/*@@ invertProjective() is not optimized (slower than generic one)
|
||||||
|
if(fabs(m[0]*m[5] - m[1]*m[4]) > EPSILON)
|
||||||
|
this->invertProjective(); // inverse using matrix partition
|
||||||
|
else
|
||||||
|
this->invertGeneral(); // generalized inverse
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// compute the inverse of 4x4 Euclidean transformation matrix
|
||||||
|
//
|
||||||
|
// Euclidean transformation is translation, rotation, and reflection.
|
||||||
|
// With Euclidean transform, only the position and orientation of the object
|
||||||
|
// will be changed. Euclidean transform does not change the shape of an object
|
||||||
|
// (no scaling). Length and angle are reserved.
|
||||||
|
//
|
||||||
|
// Use inverseAffine() if the matrix has scale and shear transformation.
|
||||||
|
//
|
||||||
|
// M = [ R | T ]
|
||||||
|
// [ --+-- ] (R denotes 3x3 rotation/reflection matrix)
|
||||||
|
// [ 0 | 1 ] (T denotes 1x3 translation matrix)
|
||||||
|
//
|
||||||
|
// y = M*x -> y = R*x + T -> x = R^-1*(y - T) -> x = R^T*y - R^T*T
|
||||||
|
// (R is orthogonal, R^-1 = R^T)
|
||||||
|
//
|
||||||
|
// [ R | T ]-1 [ R^T | -R^T * T ] (R denotes 3x3 rotation matrix)
|
||||||
|
// [ --+-- ] = [ ----+--------- ] (T denotes 1x3 translation)
|
||||||
|
// [ 0 | 1 ] [ 0 | 1 ] (R^T denotes R-transpose)
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
Matrix4& Matrix4::invertEuclidean()
|
||||||
|
{
|
||||||
|
// transpose 3x3 rotation matrix part
|
||||||
|
// | R^T | 0 |
|
||||||
|
// | ----+-- |
|
||||||
|
// | 0 | 1 |
|
||||||
|
float tmp;
|
||||||
|
tmp = m[1]; m[1] = m[4]; m[4] = tmp;
|
||||||
|
tmp = m[2]; m[2] = m[8]; m[8] = tmp;
|
||||||
|
tmp = m[6]; m[6] = m[9]; m[9] = tmp;
|
||||||
|
|
||||||
|
// compute translation part -R^T * T
|
||||||
|
// | 0 | -R^T x |
|
||||||
|
// | --+------- |
|
||||||
|
// | 0 | 0 |
|
||||||
|
float x = m[12];
|
||||||
|
float y = m[13];
|
||||||
|
float z = m[14];
|
||||||
|
m[12] = -(m[0] * x + m[4] * y + m[8] * z);
|
||||||
|
m[13] = -(m[1] * x + m[5] * y + m[9] * z);
|
||||||
|
m[14] = -(m[2] * x + m[6] * y + m[10]* z);
|
||||||
|
|
||||||
|
// last row should be unchanged (0,0,0,1)
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// compute the inverse of a 4x4 affine transformation matrix
|
||||||
|
//
|
||||||
|
// Affine transformations are generalizations of Euclidean transformations.
|
||||||
|
// Affine transformation includes translation, rotation, reflection, scaling,
|
||||||
|
// and shearing. Length and angle are NOT preserved.
|
||||||
|
// M = [ R | T ]
|
||||||
|
// [ --+-- ] (R denotes 3x3 rotation/scale/shear matrix)
|
||||||
|
// [ 0 | 1 ] (T denotes 1x3 translation matrix)
|
||||||
|
//
|
||||||
|
// y = M*x -> y = R*x + T -> x = R^-1*(y - T) -> x = R^-1*y - R^-1*T
|
||||||
|
//
|
||||||
|
// [ R | T ]-1 [ R^-1 | -R^-1 * T ]
|
||||||
|
// [ --+-- ] = [ -----+---------- ]
|
||||||
|
// [ 0 | 1 ] [ 0 + 1 ]
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
Matrix4& Matrix4::invertAffine()
|
||||||
|
{
|
||||||
|
// R^-1
|
||||||
|
Matrix3 r(m[0],m[1],m[2], m[4],m[5],m[6], m[8],m[9],m[10]);
|
||||||
|
r.invert();
|
||||||
|
m[0] = r[0]; m[1] = r[1]; m[2] = r[2];
|
||||||
|
m[4] = r[3]; m[5] = r[4]; m[6] = r[5];
|
||||||
|
m[8] = r[6]; m[9] = r[7]; m[10]= r[8];
|
||||||
|
|
||||||
|
// -R^-1 * T
|
||||||
|
float x = m[12];
|
||||||
|
float y = m[13];
|
||||||
|
float z = m[14];
|
||||||
|
m[12] = -(r[0] * x + r[3] * y + r[6] * z);
|
||||||
|
m[13] = -(r[1] * x + r[4] * y + r[7] * z);
|
||||||
|
m[14] = -(r[2] * x + r[5] * y + r[8] * z);
|
||||||
|
|
||||||
|
// last row should be unchanged (0,0,0,1)
|
||||||
|
//m[3] = m[7] = m[11] = 0.0f;
|
||||||
|
//m[15] = 1.0f;
|
||||||
|
|
||||||
|
return * this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// inverse matrix using matrix partitioning (blockwise inverse)
|
||||||
|
// It devides a 4x4 matrix into 4 of 2x2 matrices. It works in case of where
|
||||||
|
// det(A) != 0. If not, use the generic inverse method
|
||||||
|
// inverse formula.
|
||||||
|
// M = [ A | B ] A, B, C, D are 2x2 matrix blocks
|
||||||
|
// [ --+-- ] det(M) = |A| * |D - ((C * A^-1) * B)|
|
||||||
|
// [ C | D ]
|
||||||
|
//
|
||||||
|
// M^-1 = [ A' | B' ] A' = A^-1 - (A^-1 * B) * C'
|
||||||
|
// [ ---+--- ] B' = (A^-1 * B) * -D'
|
||||||
|
// [ C' | D' ] C' = -D' * (C * A^-1)
|
||||||
|
// D' = (D - ((C * A^-1) * B))^-1
|
||||||
|
//
|
||||||
|
// NOTE: I wrap with () if it it used more than once.
|
||||||
|
// The matrix is invertable even if det(A)=0, so must check det(A) before
|
||||||
|
// calling this function, and use invertGeneric() instead.
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
Matrix4& Matrix4::invertProjective()
|
||||||
|
{
|
||||||
|
// partition
|
||||||
|
Matrix2 a(m[0], m[1], m[4], m[5]);
|
||||||
|
Matrix2 b(m[8], m[9], m[12], m[13]);
|
||||||
|
Matrix2 c(m[2], m[3], m[6], m[7]);
|
||||||
|
Matrix2 d(m[10], m[11], m[14], m[15]);
|
||||||
|
|
||||||
|
// pre-compute repeated parts
|
||||||
|
a.invert(); // A^-1
|
||||||
|
Matrix2 ab = a * b; // A^-1 * B
|
||||||
|
Matrix2 ca = c * a; // C * A^-1
|
||||||
|
Matrix2 cab = ca * b; // C * A^-1 * B
|
||||||
|
Matrix2 dcab = d - cab; // D - C * A^-1 * B
|
||||||
|
|
||||||
|
// check determinant if |D - C * A^-1 * B| = 0
|
||||||
|
//NOTE: this function assumes det(A) is already checked. if |A|=0 then,
|
||||||
|
// cannot use this function.
|
||||||
|
float determinant = dcab[0] * dcab[3] - dcab[1] * dcab[2];
|
||||||
|
if(fabs(determinant) <= EPSILON)
|
||||||
|
{
|
||||||
|
return identity();
|
||||||
|
}
|
||||||
|
|
||||||
|
// compute D' and -D'
|
||||||
|
Matrix2 d1 = dcab; // (D - C * A^-1 * B)
|
||||||
|
d1.invert(); // (D - C * A^-1 * B)^-1
|
||||||
|
Matrix2 d2 = -d1; // -(D - C * A^-1 * B)^-1
|
||||||
|
|
||||||
|
// compute C'
|
||||||
|
Matrix2 c1 = d2 * ca; // -D' * (C * A^-1)
|
||||||
|
|
||||||
|
// compute B'
|
||||||
|
Matrix2 b1 = ab * d2; // (A^-1 * B) * -D'
|
||||||
|
|
||||||
|
// compute A'
|
||||||
|
Matrix2 a1 = a - (ab * c1); // A^-1 - (A^-1 * B) * C'
|
||||||
|
|
||||||
|
// assemble inverse matrix
|
||||||
|
m[0] = a1[0]; m[4] = a1[2]; /*|*/ m[8] = b1[0]; m[12]= b1[2];
|
||||||
|
m[1] = a1[1]; m[5] = a1[3]; /*|*/ m[9] = b1[1]; m[13]= b1[3];
|
||||||
|
/*-----------------------------+-----------------------------*/
|
||||||
|
m[2] = c1[0]; m[6] = c1[2]; /*|*/ m[10]= d1[0]; m[14]= d1[2];
|
||||||
|
m[3] = c1[1]; m[7] = c1[3]; /*|*/ m[11]= d1[1]; m[15]= d1[3];
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// compute the inverse of a general 4x4 matrix using Cramer's Rule
|
||||||
|
// If cannot find inverse, return indentity matrix
|
||||||
|
// M^-1 = adj(M) / det(M)
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
Matrix4& Matrix4::invertGeneral()
|
||||||
|
{
|
||||||
|
// get cofactors of minor matrices
|
||||||
|
float cofactor0 = getCofactor(m[5],m[6],m[7], m[9],m[10],m[11], m[13],m[14],m[15]);
|
||||||
|
float cofactor1 = getCofactor(m[4],m[6],m[7], m[8],m[10],m[11], m[12],m[14],m[15]);
|
||||||
|
float cofactor2 = getCofactor(m[4],m[5],m[7], m[8],m[9], m[11], m[12],m[13],m[15]);
|
||||||
|
float cofactor3 = getCofactor(m[4],m[5],m[6], m[8],m[9], m[10], m[12],m[13],m[14]);
|
||||||
|
|
||||||
|
// get determinant
|
||||||
|
float determinant = m[0] * cofactor0 - m[1] * cofactor1 + m[2] * cofactor2 - m[3] * cofactor3;
|
||||||
|
if(fabs(determinant) <= EPSILON)
|
||||||
|
{
|
||||||
|
return identity();
|
||||||
|
}
|
||||||
|
|
||||||
|
// get rest of cofactors for adj(M)
|
||||||
|
float cofactor4 = getCofactor(m[1],m[2],m[3], m[9],m[10],m[11], m[13],m[14],m[15]);
|
||||||
|
float cofactor5 = getCofactor(m[0],m[2],m[3], m[8],m[10],m[11], m[12],m[14],m[15]);
|
||||||
|
float cofactor6 = getCofactor(m[0],m[1],m[3], m[8],m[9], m[11], m[12],m[13],m[15]);
|
||||||
|
float cofactor7 = getCofactor(m[0],m[1],m[2], m[8],m[9], m[10], m[12],m[13],m[14]);
|
||||||
|
|
||||||
|
float cofactor8 = getCofactor(m[1],m[2],m[3], m[5],m[6], m[7], m[13],m[14],m[15]);
|
||||||
|
float cofactor9 = getCofactor(m[0],m[2],m[3], m[4],m[6], m[7], m[12],m[14],m[15]);
|
||||||
|
float cofactor10= getCofactor(m[0],m[1],m[3], m[4],m[5], m[7], m[12],m[13],m[15]);
|
||||||
|
float cofactor11= getCofactor(m[0],m[1],m[2], m[4],m[5], m[6], m[12],m[13],m[14]);
|
||||||
|
|
||||||
|
float cofactor12= getCofactor(m[1],m[2],m[3], m[5],m[6], m[7], m[9], m[10],m[11]);
|
||||||
|
float cofactor13= getCofactor(m[0],m[2],m[3], m[4],m[6], m[7], m[8], m[10],m[11]);
|
||||||
|
float cofactor14= getCofactor(m[0],m[1],m[3], m[4],m[5], m[7], m[8], m[9], m[11]);
|
||||||
|
float cofactor15= getCofactor(m[0],m[1],m[2], m[4],m[5], m[6], m[8], m[9], m[10]);
|
||||||
|
|
||||||
|
// build inverse matrix = adj(M) / det(M)
|
||||||
|
// adjugate of M is the transpose of the cofactor matrix of M
|
||||||
|
float invDeterminant = 1.0f / determinant;
|
||||||
|
m[0] = invDeterminant * cofactor0;
|
||||||
|
m[1] = -invDeterminant * cofactor4;
|
||||||
|
m[2] = invDeterminant * cofactor8;
|
||||||
|
m[3] = -invDeterminant * cofactor12;
|
||||||
|
|
||||||
|
m[4] = -invDeterminant * cofactor1;
|
||||||
|
m[5] = invDeterminant * cofactor5;
|
||||||
|
m[6] = -invDeterminant * cofactor9;
|
||||||
|
m[7] = invDeterminant * cofactor13;
|
||||||
|
|
||||||
|
m[8] = invDeterminant * cofactor2;
|
||||||
|
m[9] = -invDeterminant * cofactor6;
|
||||||
|
m[10]= invDeterminant * cofactor10;
|
||||||
|
m[11]= -invDeterminant * cofactor14;
|
||||||
|
|
||||||
|
m[12]= -invDeterminant * cofactor3;
|
||||||
|
m[13]= invDeterminant * cofactor7;
|
||||||
|
m[14]= -invDeterminant * cofactor11;
|
||||||
|
m[15]= invDeterminant * cofactor15;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// return determinant of 4x4 matrix
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
float Matrix4::getDeterminant()
|
||||||
|
{
|
||||||
|
return m[0] * getCofactor(m[5],m[6],m[7], m[9],m[10],m[11], m[13],m[14],m[15]) -
|
||||||
|
m[1] * getCofactor(m[4],m[6],m[7], m[8],m[10],m[11], m[12],m[14],m[15]) +
|
||||||
|
m[2] * getCofactor(m[4],m[5],m[7], m[8],m[9], m[11], m[12],m[13],m[15]) -
|
||||||
|
m[3] * getCofactor(m[4],m[5],m[6], m[8],m[9], m[10], m[12],m[13],m[14]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// compute cofactor of 3x3 minor matrix without sign
|
||||||
|
// input params are 9 elements of the minor matrix
|
||||||
|
// NOTE: The caller must know its sign.
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
float Matrix4::getCofactor(float m0, float m1, float m2,
|
||||||
|
float m3, float m4, float m5,
|
||||||
|
float m6, float m7, float m8)
|
||||||
|
{
|
||||||
|
return m0 * (m4 * m8 - m5 * m7) -
|
||||||
|
m1 * (m3 * m8 - m5 * m6) +
|
||||||
|
m2 * (m3 * m7 - m4 * m6);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// translate this matrix by (x, y, z)
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
Matrix4& Matrix4::translate(const Vector3& v)
|
||||||
|
{
|
||||||
|
return translate(v.x, v.y, v.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
Matrix4& Matrix4::translate(float x, float y, float z)
|
||||||
|
{
|
||||||
|
m[0] += m[3] * x; m[4] += m[7] * x; m[8] += m[11]* x; m[12]+= m[15]* x;
|
||||||
|
m[1] += m[3] * y; m[5] += m[7] * y; m[9] += m[11]* y; m[13]+= m[15]* y;
|
||||||
|
m[2] += m[3] * z; m[6] += m[7] * z; m[10]+= m[11]* z; m[14]+= m[15]* z;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// uniform scale
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
Matrix4& Matrix4::scale(float s)
|
||||||
|
{
|
||||||
|
return scale(s, s, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
Matrix4& Matrix4::scale(float x, float y, float z)
|
||||||
|
{
|
||||||
|
m[0] *= x; m[4] *= x; m[8] *= x; m[12] *= x;
|
||||||
|
m[1] *= y; m[5] *= y; m[9] *= y; m[13] *= y;
|
||||||
|
m[2] *= z; m[6] *= z; m[10]*= z; m[14] *= z;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// build a rotation matrix with given angle(degree) and rotation axis, then
|
||||||
|
// multiply it with this object
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
Matrix4& Matrix4::rotate(float angle, const Vector3& axis)
|
||||||
|
{
|
||||||
|
return rotate(angle, axis.x, axis.y, axis.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
Matrix4& Matrix4::rotate(float angle, float x, float y, float z)
|
||||||
|
{
|
||||||
|
float c = cosf(angle * DEG2RAD); // cosine
|
||||||
|
float s = sinf(angle * DEG2RAD); // sine
|
||||||
|
float c1 = 1.0f - c; // 1 - c
|
||||||
|
float m0 = m[0], m4 = m[4], m8 = m[8], m12= m[12],
|
||||||
|
m1 = m[1], m5 = m[5], m9 = m[9], m13= m[13],
|
||||||
|
m2 = m[2], m6 = m[6], m10= m[10], m14= m[14];
|
||||||
|
|
||||||
|
// build rotation matrix
|
||||||
|
float r0 = x * x * c1 + c;
|
||||||
|
float r1 = x * y * c1 + z * s;
|
||||||
|
float r2 = x * z * c1 - y * s;
|
||||||
|
float r4 = x * y * c1 - z * s;
|
||||||
|
float r5 = y * y * c1 + c;
|
||||||
|
float r6 = y * z * c1 + x * s;
|
||||||
|
float r8 = x * z * c1 + y * s;
|
||||||
|
float r9 = y * z * c1 - x * s;
|
||||||
|
float r10= z * z * c1 + c;
|
||||||
|
|
||||||
|
// multiply rotation matrix
|
||||||
|
m[0] = r0 * m0 + r4 * m1 + r8 * m2;
|
||||||
|
m[1] = r1 * m0 + r5 * m1 + r9 * m2;
|
||||||
|
m[2] = r2 * m0 + r6 * m1 + r10* m2;
|
||||||
|
m[4] = r0 * m4 + r4 * m5 + r8 * m6;
|
||||||
|
m[5] = r1 * m4 + r5 * m5 + r9 * m6;
|
||||||
|
m[6] = r2 * m4 + r6 * m5 + r10* m6;
|
||||||
|
m[8] = r0 * m8 + r4 * m9 + r8 * m10;
|
||||||
|
m[9] = r1 * m8 + r5 * m9 + r9 * m10;
|
||||||
|
m[10]= r2 * m8 + r6 * m9 + r10* m10;
|
||||||
|
m[12]= r0 * m12+ r4 * m13+ r8 * m14;
|
||||||
|
m[13]= r1 * m12+ r5 * m13+ r9 * m14;
|
||||||
|
m[14]= r2 * m12+ r6 * m13+ r10* m14;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Matrix4& Matrix4::rotateX(float angle)
|
||||||
|
{
|
||||||
|
float c = cosf(angle * DEG2RAD);
|
||||||
|
float s = sinf(angle * DEG2RAD);
|
||||||
|
float m1 = m[1], m2 = m[2],
|
||||||
|
m5 = m[5], m6 = m[6],
|
||||||
|
m9 = m[9], m10= m[10],
|
||||||
|
m13= m[13], m14= m[14];
|
||||||
|
|
||||||
|
m[1] = m1 * c + m2 *-s;
|
||||||
|
m[2] = m1 * s + m2 * c;
|
||||||
|
m[5] = m5 * c + m6 *-s;
|
||||||
|
m[6] = m5 * s + m6 * c;
|
||||||
|
m[9] = m9 * c + m10*-s;
|
||||||
|
m[10]= m9 * s + m10* c;
|
||||||
|
m[13]= m13* c + m14*-s;
|
||||||
|
m[14]= m13* s + m14* c;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Matrix4& Matrix4::rotateY(float angle)
|
||||||
|
{
|
||||||
|
float c = cosf(angle * DEG2RAD);
|
||||||
|
float s = sinf(angle * DEG2RAD);
|
||||||
|
float m0 = m[0], m2 = m[2],
|
||||||
|
m4 = m[4], m6 = m[6],
|
||||||
|
m8 = m[8], m10= m[10],
|
||||||
|
m12= m[12], m14= m[14];
|
||||||
|
|
||||||
|
m[0] = m0 * c + m2 * s;
|
||||||
|
m[2] = m0 *-s + m2 * c;
|
||||||
|
m[4] = m4 * c + m6 * s;
|
||||||
|
m[6] = m4 *-s + m6 * c;
|
||||||
|
m[8] = m8 * c + m10* s;
|
||||||
|
m[10]= m8 *-s + m10* c;
|
||||||
|
m[12]= m12* c + m14* s;
|
||||||
|
m[14]= m12*-s + m14* c;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Matrix4& Matrix4::rotateZ(float angle)
|
||||||
|
{
|
||||||
|
float c = cosf(angle * DEG2RAD);
|
||||||
|
float s = sinf(angle * DEG2RAD);
|
||||||
|
float m0 = m[0], m1 = m[1],
|
||||||
|
m4 = m[4], m5 = m[5],
|
||||||
|
m8 = m[8], m9 = m[9],
|
||||||
|
m12= m[12], m13= m[13];
|
||||||
|
|
||||||
|
m[0] = m0 * c + m1 *-s;
|
||||||
|
m[1] = m0 * s + m1 * c;
|
||||||
|
m[4] = m4 * c + m5 *-s;
|
||||||
|
m[5] = m4 * s + m5 * c;
|
||||||
|
m[8] = m8 * c + m9 *-s;
|
||||||
|
m[9] = m8 * s + m9 * c;
|
||||||
|
m[12]= m12* c + m13*-s;
|
||||||
|
m[13]= m12* s + m13* c;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
909
examples/ThirdPartyLibs/openvr/samples/shared/Matrices.h
Normal file
909
examples/ThirdPartyLibs/openvr/samples/shared/Matrices.h
Normal file
@ -0,0 +1,909 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Matrice.h
|
||||||
|
// =========
|
||||||
|
// NxN Matrix Math classes
|
||||||
|
//
|
||||||
|
// The elements of the matrix are stored as column major order.
|
||||||
|
// | 0 2 | | 0 3 6 | | 0 4 8 12 |
|
||||||
|
// | 1 3 | | 1 4 7 | | 1 5 9 13 |
|
||||||
|
// | 2 5 8 | | 2 6 10 14 |
|
||||||
|
// | 3 7 11 15 |
|
||||||
|
//
|
||||||
|
// AUTHOR: Song Ho Ahn (song.ahn@gmail.com)
|
||||||
|
// CREATED: 2005-06-24
|
||||||
|
// UPDATED: 2013-09-30
|
||||||
|
//
|
||||||
|
// Copyright (C) 2005 Song Ho Ahn
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef MATH_MATRICES_H
|
||||||
|
#define MATH_MATRICES_H
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <iomanip>
|
||||||
|
#include "Vectors.h"
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// 2x2 matrix
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
class Matrix2
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// constructors
|
||||||
|
Matrix2(); // init with identity
|
||||||
|
Matrix2(const float src[4]);
|
||||||
|
Matrix2(float m0, float m1, float m2, float m3);
|
||||||
|
|
||||||
|
void set(const float src[4]);
|
||||||
|
void set(float m0, float m1, float m2, float m3);
|
||||||
|
void setRow(int index, const float row[2]);
|
||||||
|
void setRow(int index, const Vector2& v);
|
||||||
|
void setColumn(int index, const float col[2]);
|
||||||
|
void setColumn(int index, const Vector2& v);
|
||||||
|
|
||||||
|
const float* get() const;
|
||||||
|
float getDeterminant();
|
||||||
|
|
||||||
|
Matrix2& identity();
|
||||||
|
Matrix2& transpose(); // transpose itself and return reference
|
||||||
|
Matrix2& invert();
|
||||||
|
|
||||||
|
// operators
|
||||||
|
Matrix2 operator+(const Matrix2& rhs) const; // add rhs
|
||||||
|
Matrix2 operator-(const Matrix2& rhs) const; // subtract rhs
|
||||||
|
Matrix2& operator+=(const Matrix2& rhs); // add rhs and update this object
|
||||||
|
Matrix2& operator-=(const Matrix2& rhs); // subtract rhs and update this object
|
||||||
|
Vector2 operator*(const Vector2& rhs) const; // multiplication: v' = M * v
|
||||||
|
Matrix2 operator*(const Matrix2& rhs) const; // multiplication: M3 = M1 * M2
|
||||||
|
Matrix2& operator*=(const Matrix2& rhs); // multiplication: M1' = M1 * M2
|
||||||
|
bool operator==(const Matrix2& rhs) const; // exact compare, no epsilon
|
||||||
|
bool operator!=(const Matrix2& rhs) const; // exact compare, no epsilon
|
||||||
|
float operator[](int index) const; // subscript operator v[0], v[1]
|
||||||
|
float& operator[](int index); // subscript operator v[0], v[1]
|
||||||
|
|
||||||
|
friend Matrix2 operator-(const Matrix2& m); // unary operator (-)
|
||||||
|
friend Matrix2 operator*(float scalar, const Matrix2& m); // pre-multiplication
|
||||||
|
friend Vector2 operator*(const Vector2& vec, const Matrix2& m); // pre-multiplication
|
||||||
|
friend std::ostream& operator<<(std::ostream& os, const Matrix2& m);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
private:
|
||||||
|
float m[4];
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// 3x3 matrix
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
class Matrix3
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// constructors
|
||||||
|
Matrix3(); // init with identity
|
||||||
|
Matrix3(const float src[9]);
|
||||||
|
Matrix3(float m0, float m1, float m2, // 1st column
|
||||||
|
float m3, float m4, float m5, // 2nd column
|
||||||
|
float m6, float m7, float m8); // 3rd column
|
||||||
|
|
||||||
|
void set(const float src[9]);
|
||||||
|
void set(float m0, float m1, float m2, // 1st column
|
||||||
|
float m3, float m4, float m5, // 2nd column
|
||||||
|
float m6, float m7, float m8); // 3rd column
|
||||||
|
void setRow(int index, const float row[3]);
|
||||||
|
void setRow(int index, const Vector3& v);
|
||||||
|
void setColumn(int index, const float col[3]);
|
||||||
|
void setColumn(int index, const Vector3& v);
|
||||||
|
|
||||||
|
const float* get() const;
|
||||||
|
float getDeterminant();
|
||||||
|
|
||||||
|
Matrix3& identity();
|
||||||
|
Matrix3& transpose(); // transpose itself and return reference
|
||||||
|
Matrix3& invert();
|
||||||
|
|
||||||
|
// operators
|
||||||
|
Matrix3 operator+(const Matrix3& rhs) const; // add rhs
|
||||||
|
Matrix3 operator-(const Matrix3& rhs) const; // subtract rhs
|
||||||
|
Matrix3& operator+=(const Matrix3& rhs); // add rhs and update this object
|
||||||
|
Matrix3& operator-=(const Matrix3& rhs); // subtract rhs and update this object
|
||||||
|
Vector3 operator*(const Vector3& rhs) const; // multiplication: v' = M * v
|
||||||
|
Matrix3 operator*(const Matrix3& rhs) const; // multiplication: M3 = M1 * M2
|
||||||
|
Matrix3& operator*=(const Matrix3& rhs); // multiplication: M1' = M1 * M2
|
||||||
|
bool operator==(const Matrix3& rhs) const; // exact compare, no epsilon
|
||||||
|
bool operator!=(const Matrix3& rhs) const; // exact compare, no epsilon
|
||||||
|
float operator[](int index) const; // subscript operator v[0], v[1]
|
||||||
|
float& operator[](int index); // subscript operator v[0], v[1]
|
||||||
|
|
||||||
|
friend Matrix3 operator-(const Matrix3& m); // unary operator (-)
|
||||||
|
friend Matrix3 operator*(float scalar, const Matrix3& m); // pre-multiplication
|
||||||
|
friend Vector3 operator*(const Vector3& vec, const Matrix3& m); // pre-multiplication
|
||||||
|
friend std::ostream& operator<<(std::ostream& os, const Matrix3& m);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
private:
|
||||||
|
float m[9];
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// 4x4 matrix
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
class Matrix4
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// constructors
|
||||||
|
Matrix4(); // init with identity
|
||||||
|
Matrix4(const float src[16]);
|
||||||
|
Matrix4(float m00, float m01, float m02, float m03, // 1st column
|
||||||
|
float m04, float m05, float m06, float m07, // 2nd column
|
||||||
|
float m08, float m09, float m10, float m11, // 3rd column
|
||||||
|
float m12, float m13, float m14, float m15);// 4th column
|
||||||
|
|
||||||
|
void set(const float src[16]);
|
||||||
|
void set(float m00, float m01, float m02, float m03, // 1st column
|
||||||
|
float m04, float m05, float m06, float m07, // 2nd column
|
||||||
|
float m08, float m09, float m10, float m11, // 3rd column
|
||||||
|
float m12, float m13, float m14, float m15);// 4th column
|
||||||
|
void setRow(int index, const float row[4]);
|
||||||
|
void setRow(int index, const Vector4& v);
|
||||||
|
void setRow(int index, const Vector3& v);
|
||||||
|
void setColumn(int index, const float col[4]);
|
||||||
|
void setColumn(int index, const Vector4& v);
|
||||||
|
void setColumn(int index, const Vector3& v);
|
||||||
|
|
||||||
|
const float* get() const;
|
||||||
|
const float* getTranspose(); // return transposed matrix
|
||||||
|
float getDeterminant();
|
||||||
|
|
||||||
|
Matrix4& identity();
|
||||||
|
Matrix4& transpose(); // transpose itself and return reference
|
||||||
|
Matrix4& invert(); // check best inverse method before inverse
|
||||||
|
Matrix4& invertEuclidean(); // inverse of Euclidean transform matrix
|
||||||
|
Matrix4& invertAffine(); // inverse of affine transform matrix
|
||||||
|
Matrix4& invertProjective(); // inverse of projective matrix using partitioning
|
||||||
|
Matrix4& invertGeneral(); // inverse of generic matrix
|
||||||
|
|
||||||
|
// transform matrix
|
||||||
|
Matrix4& translate(float x, float y, float z); // translation by (x,y,z)
|
||||||
|
Matrix4& translate(const Vector3& v); //
|
||||||
|
Matrix4& rotate(float angle, const Vector3& axis); // rotate angle(degree) along the given axix
|
||||||
|
Matrix4& rotate(float angle, float x, float y, float z);
|
||||||
|
Matrix4& rotateX(float angle); // rotate on X-axis with degree
|
||||||
|
Matrix4& rotateY(float angle); // rotate on Y-axis with degree
|
||||||
|
Matrix4& rotateZ(float angle); // rotate on Z-axis with degree
|
||||||
|
Matrix4& scale(float scale); // uniform scale
|
||||||
|
Matrix4& scale(float sx, float sy, float sz); // scale by (sx, sy, sz) on each axis
|
||||||
|
|
||||||
|
// operators
|
||||||
|
Matrix4 operator+(const Matrix4& rhs) const; // add rhs
|
||||||
|
Matrix4 operator-(const Matrix4& rhs) const; // subtract rhs
|
||||||
|
Matrix4& operator+=(const Matrix4& rhs); // add rhs and update this object
|
||||||
|
Matrix4& operator-=(const Matrix4& rhs); // subtract rhs and update this object
|
||||||
|
Vector4 operator*(const Vector4& rhs) const; // multiplication: v' = M * v
|
||||||
|
Vector3 operator*(const Vector3& rhs) const; // multiplication: v' = M * v
|
||||||
|
Matrix4 operator*(const Matrix4& rhs) const; // multiplication: M3 = M1 * M2
|
||||||
|
Matrix4& operator*=(const Matrix4& rhs); // multiplication: M1' = M1 * M2
|
||||||
|
bool operator==(const Matrix4& rhs) const; // exact compare, no epsilon
|
||||||
|
bool operator!=(const Matrix4& rhs) const; // exact compare, no epsilon
|
||||||
|
float operator[](int index) const; // subscript operator v[0], v[1]
|
||||||
|
float& operator[](int index); // subscript operator v[0], v[1]
|
||||||
|
|
||||||
|
friend Matrix4 operator-(const Matrix4& m); // unary operator (-)
|
||||||
|
friend Matrix4 operator*(float scalar, const Matrix4& m); // pre-multiplication
|
||||||
|
friend Vector3 operator*(const Vector3& vec, const Matrix4& m); // pre-multiplication
|
||||||
|
friend Vector4 operator*(const Vector4& vec, const Matrix4& m); // pre-multiplication
|
||||||
|
friend std::ostream& operator<<(std::ostream& os, const Matrix4& m);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
private:
|
||||||
|
float getCofactor(float m0, float m1, float m2,
|
||||||
|
float m3, float m4, float m5,
|
||||||
|
float m6, float m7, float m8);
|
||||||
|
|
||||||
|
float m[16];
|
||||||
|
float tm[16]; // transpose m
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// inline functions for Matrix2
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
inline Matrix2::Matrix2()
|
||||||
|
{
|
||||||
|
// initially identity matrix
|
||||||
|
identity();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline Matrix2::Matrix2(const float src[4])
|
||||||
|
{
|
||||||
|
set(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline Matrix2::Matrix2(float m0, float m1, float m2, float m3)
|
||||||
|
{
|
||||||
|
set(m0, m1, m2, m3);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline void Matrix2::set(const float src[4])
|
||||||
|
{
|
||||||
|
m[0] = src[0]; m[1] = src[1]; m[2] = src[2]; m[3] = src[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline void Matrix2::set(float m0, float m1, float m2, float m3)
|
||||||
|
{
|
||||||
|
m[0]= m0; m[1] = m1; m[2] = m2; m[3]= m3;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline void Matrix2::setRow(int index, const float row[2])
|
||||||
|
{
|
||||||
|
m[index] = row[0]; m[index + 2] = row[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline void Matrix2::setRow(int index, const Vector2& v)
|
||||||
|
{
|
||||||
|
m[index] = v.x; m[index + 2] = v.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline void Matrix2::setColumn(int index, const float col[2])
|
||||||
|
{
|
||||||
|
m[index*2] = col[0]; m[index*2 + 1] = col[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline void Matrix2::setColumn(int index, const Vector2& v)
|
||||||
|
{
|
||||||
|
m[index*2] = v.x; m[index*2 + 1] = v.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline const float* Matrix2::get() const
|
||||||
|
{
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline Matrix2& Matrix2::identity()
|
||||||
|
{
|
||||||
|
m[0] = m[3] = 1.0f;
|
||||||
|
m[1] = m[2] = 0.0f;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline Matrix2 Matrix2::operator+(const Matrix2& rhs) const
|
||||||
|
{
|
||||||
|
return Matrix2(m[0]+rhs[0], m[1]+rhs[1], m[2]+rhs[2], m[3]+rhs[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline Matrix2 Matrix2::operator-(const Matrix2& rhs) const
|
||||||
|
{
|
||||||
|
return Matrix2(m[0]-rhs[0], m[1]-rhs[1], m[2]-rhs[2], m[3]-rhs[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline Matrix2& Matrix2::operator+=(const Matrix2& rhs)
|
||||||
|
{
|
||||||
|
m[0] += rhs[0]; m[1] += rhs[1]; m[2] += rhs[2]; m[3] += rhs[3];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline Matrix2& Matrix2::operator-=(const Matrix2& rhs)
|
||||||
|
{
|
||||||
|
m[0] -= rhs[0]; m[1] -= rhs[1]; m[2] -= rhs[2]; m[3] -= rhs[3];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline Vector2 Matrix2::operator*(const Vector2& rhs) const
|
||||||
|
{
|
||||||
|
return Vector2(m[0]*rhs.x + m[2]*rhs.y, m[1]*rhs.x + m[3]*rhs.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline Matrix2 Matrix2::operator*(const Matrix2& rhs) const
|
||||||
|
{
|
||||||
|
return Matrix2(m[0]*rhs[0] + m[2]*rhs[1], m[1]*rhs[0] + m[3]*rhs[1],
|
||||||
|
m[0]*rhs[2] + m[2]*rhs[3], m[1]*rhs[2] + m[3]*rhs[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline Matrix2& Matrix2::operator*=(const Matrix2& rhs)
|
||||||
|
{
|
||||||
|
*this = *this * rhs;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Matrix2::operator==(const Matrix2& rhs) const
|
||||||
|
{
|
||||||
|
return (m[0] == rhs[0]) && (m[1] == rhs[1]) && (m[2] == rhs[2]) && (m[3] == rhs[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Matrix2::operator!=(const Matrix2& rhs) const
|
||||||
|
{
|
||||||
|
return (m[0] != rhs[0]) || (m[1] != rhs[1]) || (m[2] != rhs[2]) || (m[3] != rhs[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline float Matrix2::operator[](int index) const
|
||||||
|
{
|
||||||
|
return m[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline float& Matrix2::operator[](int index)
|
||||||
|
{
|
||||||
|
return m[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline Matrix2 operator-(const Matrix2& rhs)
|
||||||
|
{
|
||||||
|
return Matrix2(-rhs[0], -rhs[1], -rhs[2], -rhs[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline Matrix2 operator*(float s, const Matrix2& rhs)
|
||||||
|
{
|
||||||
|
return Matrix2(s*rhs[0], s*rhs[1], s*rhs[2], s*rhs[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline Vector2 operator*(const Vector2& v, const Matrix2& rhs)
|
||||||
|
{
|
||||||
|
return Vector2(v.x*rhs[0] + v.y*rhs[1], v.x*rhs[2] + v.y*rhs[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline std::ostream& operator<<(std::ostream& os, const Matrix2& m)
|
||||||
|
{
|
||||||
|
os << std::fixed << std::setprecision(5);
|
||||||
|
os << "[" << std::setw(10) << m[0] << " " << std::setw(10) << m[2] << "]\n"
|
||||||
|
<< "[" << std::setw(10) << m[1] << " " << std::setw(10) << m[3] << "]\n";
|
||||||
|
os << std::resetiosflags(std::ios_base::fixed | std::ios_base::floatfield);
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
// END OF MATRIX2 INLINE //////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// inline functions for Matrix3
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
inline Matrix3::Matrix3()
|
||||||
|
{
|
||||||
|
// initially identity matrix
|
||||||
|
identity();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline Matrix3::Matrix3(const float src[9])
|
||||||
|
{
|
||||||
|
set(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline Matrix3::Matrix3(float m0, float m1, float m2,
|
||||||
|
float m3, float m4, float m5,
|
||||||
|
float m6, float m7, float m8)
|
||||||
|
{
|
||||||
|
set(m0, m1, m2, m3, m4, m5, m6, m7, m8);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline void Matrix3::set(const float src[9])
|
||||||
|
{
|
||||||
|
m[0] = src[0]; m[1] = src[1]; m[2] = src[2];
|
||||||
|
m[3] = src[3]; m[4] = src[4]; m[5] = src[5];
|
||||||
|
m[6] = src[6]; m[7] = src[7]; m[8] = src[8];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline void Matrix3::set(float m0, float m1, float m2,
|
||||||
|
float m3, float m4, float m5,
|
||||||
|
float m6, float m7, float m8)
|
||||||
|
{
|
||||||
|
m[0] = m0; m[1] = m1; m[2] = m2;
|
||||||
|
m[3] = m3; m[4] = m4; m[5] = m5;
|
||||||
|
m[6] = m6; m[7] = m7; m[8] = m8;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline void Matrix3::setRow(int index, const float row[3])
|
||||||
|
{
|
||||||
|
m[index] = row[0]; m[index + 3] = row[1]; m[index + 6] = row[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline void Matrix3::setRow(int index, const Vector3& v)
|
||||||
|
{
|
||||||
|
m[index] = v.x; m[index + 3] = v.y; m[index + 6] = v.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline void Matrix3::setColumn(int index, const float col[3])
|
||||||
|
{
|
||||||
|
m[index*3] = col[0]; m[index*3 + 1] = col[1]; m[index*3 + 2] = col[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline void Matrix3::setColumn(int index, const Vector3& v)
|
||||||
|
{
|
||||||
|
m[index*3] = v.x; m[index*3 + 1] = v.y; m[index*3 + 2] = v.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline const float* Matrix3::get() const
|
||||||
|
{
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline Matrix3& Matrix3::identity()
|
||||||
|
{
|
||||||
|
m[0] = m[4] = m[8] = 1.0f;
|
||||||
|
m[1] = m[2] = m[3] = m[5] = m[6] = m[7] = 0.0f;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline Matrix3 Matrix3::operator+(const Matrix3& rhs) const
|
||||||
|
{
|
||||||
|
return Matrix3(m[0]+rhs[0], m[1]+rhs[1], m[2]+rhs[2],
|
||||||
|
m[3]+rhs[3], m[4]+rhs[4], m[5]+rhs[5],
|
||||||
|
m[6]+rhs[6], m[7]+rhs[7], m[8]+rhs[8]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline Matrix3 Matrix3::operator-(const Matrix3& rhs) const
|
||||||
|
{
|
||||||
|
return Matrix3(m[0]-rhs[0], m[1]-rhs[1], m[2]-rhs[2],
|
||||||
|
m[3]-rhs[3], m[4]-rhs[4], m[5]-rhs[5],
|
||||||
|
m[6]-rhs[6], m[7]-rhs[7], m[8]-rhs[8]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline Matrix3& Matrix3::operator+=(const Matrix3& rhs)
|
||||||
|
{
|
||||||
|
m[0] += rhs[0]; m[1] += rhs[1]; m[2] += rhs[2];
|
||||||
|
m[3] += rhs[3]; m[4] += rhs[4]; m[5] += rhs[5];
|
||||||
|
m[6] += rhs[6]; m[7] += rhs[7]; m[8] += rhs[8];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline Matrix3& Matrix3::operator-=(const Matrix3& rhs)
|
||||||
|
{
|
||||||
|
m[0] -= rhs[0]; m[1] -= rhs[1]; m[2] -= rhs[2];
|
||||||
|
m[3] -= rhs[3]; m[4] -= rhs[4]; m[5] -= rhs[5];
|
||||||
|
m[6] -= rhs[6]; m[7] -= rhs[7]; m[8] -= rhs[8];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline Vector3 Matrix3::operator*(const Vector3& rhs) const
|
||||||
|
{
|
||||||
|
return Vector3(m[0]*rhs.x + m[3]*rhs.y + m[6]*rhs.z,
|
||||||
|
m[1]*rhs.x + m[4]*rhs.y + m[7]*rhs.z,
|
||||||
|
m[2]*rhs.x + m[5]*rhs.y + m[8]*rhs.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline Matrix3 Matrix3::operator*(const Matrix3& rhs) const
|
||||||
|
{
|
||||||
|
return Matrix3(m[0]*rhs[0] + m[3]*rhs[1] + m[6]*rhs[2], m[1]*rhs[0] + m[4]*rhs[1] + m[7]*rhs[2], m[2]*rhs[0] + m[5]*rhs[1] + m[8]*rhs[2],
|
||||||
|
m[0]*rhs[3] + m[3]*rhs[4] + m[6]*rhs[5], m[1]*rhs[3] + m[4]*rhs[4] + m[7]*rhs[5], m[2]*rhs[3] + m[5]*rhs[4] + m[8]*rhs[5],
|
||||||
|
m[0]*rhs[6] + m[3]*rhs[7] + m[6]*rhs[8], m[1]*rhs[6] + m[4]*rhs[7] + m[7]*rhs[8], m[2]*rhs[6] + m[5]*rhs[7] + m[8]*rhs[8]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline Matrix3& Matrix3::operator*=(const Matrix3& rhs)
|
||||||
|
{
|
||||||
|
*this = *this * rhs;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Matrix3::operator==(const Matrix3& rhs) const
|
||||||
|
{
|
||||||
|
return (m[0] == rhs[0]) && (m[1] == rhs[1]) && (m[2] == rhs[2]) &&
|
||||||
|
(m[3] == rhs[3]) && (m[4] == rhs[4]) && (m[5] == rhs[5]) &&
|
||||||
|
(m[6] == rhs[6]) && (m[7] == rhs[7]) && (m[8] == rhs[8]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Matrix3::operator!=(const Matrix3& rhs) const
|
||||||
|
{
|
||||||
|
return (m[0] != rhs[0]) || (m[1] != rhs[1]) || (m[2] != rhs[2]) ||
|
||||||
|
(m[3] != rhs[3]) || (m[4] != rhs[4]) || (m[5] != rhs[5]) ||
|
||||||
|
(m[6] != rhs[6]) || (m[7] != rhs[7]) || (m[8] != rhs[8]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline float Matrix3::operator[](int index) const
|
||||||
|
{
|
||||||
|
return m[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline float& Matrix3::operator[](int index)
|
||||||
|
{
|
||||||
|
return m[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline Matrix3 operator-(const Matrix3& rhs)
|
||||||
|
{
|
||||||
|
return Matrix3(-rhs[0], -rhs[1], -rhs[2], -rhs[3], -rhs[4], -rhs[5], -rhs[6], -rhs[7], -rhs[8]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline Matrix3 operator*(float s, const Matrix3& rhs)
|
||||||
|
{
|
||||||
|
return Matrix3(s*rhs[0], s*rhs[1], s*rhs[2], s*rhs[3], s*rhs[4], s*rhs[5], s*rhs[6], s*rhs[7], s*rhs[8]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline Vector3 operator*(const Vector3& v, const Matrix3& m)
|
||||||
|
{
|
||||||
|
return Vector3(v.x*m[0] + v.y*m[1] + v.z*m[2], v.x*m[3] + v.y*m[4] + v.z*m[5], v.x*m[6] + v.y*m[7] + v.z*m[8]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline std::ostream& operator<<(std::ostream& os, const Matrix3& m)
|
||||||
|
{
|
||||||
|
os << std::fixed << std::setprecision(5);
|
||||||
|
os << "[" << std::setw(10) << m[0] << " " << std::setw(10) << m[3] << " " << std::setw(10) << m[6] << "]\n"
|
||||||
|
<< "[" << std::setw(10) << m[1] << " " << std::setw(10) << m[4] << " " << std::setw(10) << m[7] << "]\n"
|
||||||
|
<< "[" << std::setw(10) << m[2] << " " << std::setw(10) << m[5] << " " << std::setw(10) << m[8] << "]\n";
|
||||||
|
os << std::resetiosflags(std::ios_base::fixed | std::ios_base::floatfield);
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
// END OF MATRIX3 INLINE //////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// inline functions for Matrix4
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
inline Matrix4::Matrix4()
|
||||||
|
{
|
||||||
|
// initially identity matrix
|
||||||
|
identity();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline Matrix4::Matrix4(const float src[16])
|
||||||
|
{
|
||||||
|
set(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline Matrix4::Matrix4(float m00, float m01, float m02, float m03,
|
||||||
|
float m04, float m05, float m06, float m07,
|
||||||
|
float m08, float m09, float m10, float m11,
|
||||||
|
float m12, float m13, float m14, float m15)
|
||||||
|
{
|
||||||
|
set(m00, m01, m02, m03, m04, m05, m06, m07, m08, m09, m10, m11, m12, m13, m14, m15);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline void Matrix4::set(const float src[16])
|
||||||
|
{
|
||||||
|
m[0] = src[0]; m[1] = src[1]; m[2] = src[2]; m[3] = src[3];
|
||||||
|
m[4] = src[4]; m[5] = src[5]; m[6] = src[6]; m[7] = src[7];
|
||||||
|
m[8] = src[8]; m[9] = src[9]; m[10]= src[10]; m[11]= src[11];
|
||||||
|
m[12]= src[12]; m[13]= src[13]; m[14]= src[14]; m[15]= src[15];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline void Matrix4::set(float m00, float m01, float m02, float m03,
|
||||||
|
float m04, float m05, float m06, float m07,
|
||||||
|
float m08, float m09, float m10, float m11,
|
||||||
|
float m12, float m13, float m14, float m15)
|
||||||
|
{
|
||||||
|
m[0] = m00; m[1] = m01; m[2] = m02; m[3] = m03;
|
||||||
|
m[4] = m04; m[5] = m05; m[6] = m06; m[7] = m07;
|
||||||
|
m[8] = m08; m[9] = m09; m[10]= m10; m[11]= m11;
|
||||||
|
m[12]= m12; m[13]= m13; m[14]= m14; m[15]= m15;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline void Matrix4::setRow(int index, const float row[4])
|
||||||
|
{
|
||||||
|
m[index] = row[0]; m[index + 4] = row[1]; m[index + 8] = row[2]; m[index + 12] = row[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline void Matrix4::setRow(int index, const Vector4& v)
|
||||||
|
{
|
||||||
|
m[index] = v.x; m[index + 4] = v.y; m[index + 8] = v.z; m[index + 12] = v.w;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline void Matrix4::setRow(int index, const Vector3& v)
|
||||||
|
{
|
||||||
|
m[index] = v.x; m[index + 4] = v.y; m[index + 8] = v.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline void Matrix4::setColumn(int index, const float col[4])
|
||||||
|
{
|
||||||
|
m[index*4] = col[0]; m[index*4 + 1] = col[1]; m[index*4 + 2] = col[2]; m[index*4 + 3] = col[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline void Matrix4::setColumn(int index, const Vector4& v)
|
||||||
|
{
|
||||||
|
m[index*4] = v.x; m[index*4 + 1] = v.y; m[index*4 + 2] = v.z; m[index*4 + 3] = v.w;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline void Matrix4::setColumn(int index, const Vector3& v)
|
||||||
|
{
|
||||||
|
m[index*4] = v.x; m[index*4 + 1] = v.y; m[index*4 + 2] = v.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline const float* Matrix4::get() const
|
||||||
|
{
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline const float* Matrix4::getTranspose()
|
||||||
|
{
|
||||||
|
tm[0] = m[0]; tm[1] = m[4]; tm[2] = m[8]; tm[3] = m[12];
|
||||||
|
tm[4] = m[1]; tm[5] = m[5]; tm[6] = m[9]; tm[7] = m[13];
|
||||||
|
tm[8] = m[2]; tm[9] = m[6]; tm[10]= m[10]; tm[11]= m[14];
|
||||||
|
tm[12]= m[3]; tm[13]= m[7]; tm[14]= m[11]; tm[15]= m[15];
|
||||||
|
return tm;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline Matrix4& Matrix4::identity()
|
||||||
|
{
|
||||||
|
m[0] = m[5] = m[10] = m[15] = 1.0f;
|
||||||
|
m[1] = m[2] = m[3] = m[4] = m[6] = m[7] = m[8] = m[9] = m[11] = m[12] = m[13] = m[14] = 0.0f;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline Matrix4 Matrix4::operator+(const Matrix4& rhs) const
|
||||||
|
{
|
||||||
|
return Matrix4(m[0]+rhs[0], m[1]+rhs[1], m[2]+rhs[2], m[3]+rhs[3],
|
||||||
|
m[4]+rhs[4], m[5]+rhs[5], m[6]+rhs[6], m[7]+rhs[7],
|
||||||
|
m[8]+rhs[8], m[9]+rhs[9], m[10]+rhs[10], m[11]+rhs[11],
|
||||||
|
m[12]+rhs[12], m[13]+rhs[13], m[14]+rhs[14], m[15]+rhs[15]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline Matrix4 Matrix4::operator-(const Matrix4& rhs) const
|
||||||
|
{
|
||||||
|
return Matrix4(m[0]-rhs[0], m[1]-rhs[1], m[2]-rhs[2], m[3]-rhs[3],
|
||||||
|
m[4]-rhs[4], m[5]-rhs[5], m[6]-rhs[6], m[7]-rhs[7],
|
||||||
|
m[8]-rhs[8], m[9]-rhs[9], m[10]-rhs[10], m[11]-rhs[11],
|
||||||
|
m[12]-rhs[12], m[13]-rhs[13], m[14]-rhs[14], m[15]-rhs[15]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline Matrix4& Matrix4::operator+=(const Matrix4& rhs)
|
||||||
|
{
|
||||||
|
m[0] += rhs[0]; m[1] += rhs[1]; m[2] += rhs[2]; m[3] += rhs[3];
|
||||||
|
m[4] += rhs[4]; m[5] += rhs[5]; m[6] += rhs[6]; m[7] += rhs[7];
|
||||||
|
m[8] += rhs[8]; m[9] += rhs[9]; m[10]+= rhs[10]; m[11]+= rhs[11];
|
||||||
|
m[12]+= rhs[12]; m[13]+= rhs[13]; m[14]+= rhs[14]; m[15]+= rhs[15];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline Matrix4& Matrix4::operator-=(const Matrix4& rhs)
|
||||||
|
{
|
||||||
|
m[0] -= rhs[0]; m[1] -= rhs[1]; m[2] -= rhs[2]; m[3] -= rhs[3];
|
||||||
|
m[4] -= rhs[4]; m[5] -= rhs[5]; m[6] -= rhs[6]; m[7] -= rhs[7];
|
||||||
|
m[8] -= rhs[8]; m[9] -= rhs[9]; m[10]-= rhs[10]; m[11]-= rhs[11];
|
||||||
|
m[12]-= rhs[12]; m[13]-= rhs[13]; m[14]-= rhs[14]; m[15]-= rhs[15];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline Vector4 Matrix4::operator*(const Vector4& rhs) const
|
||||||
|
{
|
||||||
|
return Vector4(m[0]*rhs.x + m[4]*rhs.y + m[8]*rhs.z + m[12]*rhs.w,
|
||||||
|
m[1]*rhs.x + m[5]*rhs.y + m[9]*rhs.z + m[13]*rhs.w,
|
||||||
|
m[2]*rhs.x + m[6]*rhs.y + m[10]*rhs.z + m[14]*rhs.w,
|
||||||
|
m[3]*rhs.x + m[7]*rhs.y + m[11]*rhs.z + m[15]*rhs.w);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline Vector3 Matrix4::operator*(const Vector3& rhs) const
|
||||||
|
{
|
||||||
|
return Vector3(m[0]*rhs.x + m[4]*rhs.y + m[8]*rhs.z,
|
||||||
|
m[1]*rhs.x + m[5]*rhs.y + m[9]*rhs.z,
|
||||||
|
m[2]*rhs.x + m[6]*rhs.y + m[10]*rhs.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline Matrix4 Matrix4::operator*(const Matrix4& n) const
|
||||||
|
{
|
||||||
|
return Matrix4(m[0]*n[0] + m[4]*n[1] + m[8]*n[2] + m[12]*n[3], m[1]*n[0] + m[5]*n[1] + m[9]*n[2] + m[13]*n[3], m[2]*n[0] + m[6]*n[1] + m[10]*n[2] + m[14]*n[3], m[3]*n[0] + m[7]*n[1] + m[11]*n[2] + m[15]*n[3],
|
||||||
|
m[0]*n[4] + m[4]*n[5] + m[8]*n[6] + m[12]*n[7], m[1]*n[4] + m[5]*n[5] + m[9]*n[6] + m[13]*n[7], m[2]*n[4] + m[6]*n[5] + m[10]*n[6] + m[14]*n[7], m[3]*n[4] + m[7]*n[5] + m[11]*n[6] + m[15]*n[7],
|
||||||
|
m[0]*n[8] + m[4]*n[9] + m[8]*n[10] + m[12]*n[11], m[1]*n[8] + m[5]*n[9] + m[9]*n[10] + m[13]*n[11], m[2]*n[8] + m[6]*n[9] + m[10]*n[10] + m[14]*n[11], m[3]*n[8] + m[7]*n[9] + m[11]*n[10] + m[15]*n[11],
|
||||||
|
m[0]*n[12] + m[4]*n[13] + m[8]*n[14] + m[12]*n[15], m[1]*n[12] + m[5]*n[13] + m[9]*n[14] + m[13]*n[15], m[2]*n[12] + m[6]*n[13] + m[10]*n[14] + m[14]*n[15], m[3]*n[12] + m[7]*n[13] + m[11]*n[14] + m[15]*n[15]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline Matrix4& Matrix4::operator*=(const Matrix4& rhs)
|
||||||
|
{
|
||||||
|
*this = *this * rhs;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Matrix4::operator==(const Matrix4& n) const
|
||||||
|
{
|
||||||
|
return (m[0] == n[0]) && (m[1] == n[1]) && (m[2] == n[2]) && (m[3] == n[3]) &&
|
||||||
|
(m[4] == n[4]) && (m[5] == n[5]) && (m[6] == n[6]) && (m[7] == n[7]) &&
|
||||||
|
(m[8] == n[8]) && (m[9] == n[9]) && (m[10]== n[10]) && (m[11]== n[11]) &&
|
||||||
|
(m[12]== n[12]) && (m[13]== n[13]) && (m[14]== n[14]) && (m[15]== n[15]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Matrix4::operator!=(const Matrix4& n) const
|
||||||
|
{
|
||||||
|
return (m[0] != n[0]) || (m[1] != n[1]) || (m[2] != n[2]) || (m[3] != n[3]) ||
|
||||||
|
(m[4] != n[4]) || (m[5] != n[5]) || (m[6] != n[6]) || (m[7] != n[7]) ||
|
||||||
|
(m[8] != n[8]) || (m[9] != n[9]) || (m[10]!= n[10]) || (m[11]!= n[11]) ||
|
||||||
|
(m[12]!= n[12]) || (m[13]!= n[13]) || (m[14]!= n[14]) || (m[15]!= n[15]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline float Matrix4::operator[](int index) const
|
||||||
|
{
|
||||||
|
return m[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline float& Matrix4::operator[](int index)
|
||||||
|
{
|
||||||
|
return m[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline Matrix4 operator-(const Matrix4& rhs)
|
||||||
|
{
|
||||||
|
return Matrix4(-rhs[0], -rhs[1], -rhs[2], -rhs[3], -rhs[4], -rhs[5], -rhs[6], -rhs[7], -rhs[8], -rhs[9], -rhs[10], -rhs[11], -rhs[12], -rhs[13], -rhs[14], -rhs[15]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline Matrix4 operator*(float s, const Matrix4& rhs)
|
||||||
|
{
|
||||||
|
return Matrix4(s*rhs[0], s*rhs[1], s*rhs[2], s*rhs[3], s*rhs[4], s*rhs[5], s*rhs[6], s*rhs[7], s*rhs[8], s*rhs[9], s*rhs[10], s*rhs[11], s*rhs[12], s*rhs[13], s*rhs[14], s*rhs[15]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline Vector4 operator*(const Vector4& v, const Matrix4& m)
|
||||||
|
{
|
||||||
|
return Vector4(v.x*m[0] + v.y*m[1] + v.z*m[2] + v.w*m[3], v.x*m[4] + v.y*m[5] + v.z*m[6] + v.w*m[7], v.x*m[8] + v.y*m[9] + v.z*m[10] + v.w*m[11], v.x*m[12] + v.y*m[13] + v.z*m[14] + v.w*m[15]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline Vector3 operator*(const Vector3& v, const Matrix4& m)
|
||||||
|
{
|
||||||
|
return Vector3(v.x*m[0] + v.y*m[1] + v.z*m[2], v.x*m[4] + v.y*m[5] + v.z*m[6], v.x*m[8] + v.y*m[9] + v.z*m[10]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline std::ostream& operator<<(std::ostream& os, const Matrix4& m)
|
||||||
|
{
|
||||||
|
os << std::fixed << std::setprecision(5);
|
||||||
|
os << "[" << std::setw(10) << m[0] << " " << std::setw(10) << m[4] << " " << std::setw(10) << m[8] << " " << std::setw(10) << m[12] << "]\n"
|
||||||
|
<< "[" << std::setw(10) << m[1] << " " << std::setw(10) << m[5] << " " << std::setw(10) << m[9] << " " << std::setw(10) << m[13] << "]\n"
|
||||||
|
<< "[" << std::setw(10) << m[2] << " " << std::setw(10) << m[6] << " " << std::setw(10) << m[10] << " " << std::setw(10) << m[14] << "]\n"
|
||||||
|
<< "[" << std::setw(10) << m[3] << " " << std::setw(10) << m[7] << " " << std::setw(10) << m[11] << " " << std::setw(10) << m[15] << "]\n";
|
||||||
|
os << std::resetiosflags(std::ios_base::fixed | std::ios_base::floatfield);
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
// END OF MATRIX4 INLINE //////////////////////////////////////////////////////
|
||||||
|
#endif
|
530
examples/ThirdPartyLibs/openvr/samples/shared/Vectors.h
Normal file
530
examples/ThirdPartyLibs/openvr/samples/shared/Vectors.h
Normal file
@ -0,0 +1,530 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Vectors.h
|
||||||
|
// =========
|
||||||
|
// 2D/3D/4D vectors
|
||||||
|
//
|
||||||
|
// AUTHOR: Song Ho Ahn (song.ahn@gmail.com)
|
||||||
|
// CREATED: 2007-02-14
|
||||||
|
// UPDATED: 2013-01-20
|
||||||
|
//
|
||||||
|
// Copyright (C) 2007-2013 Song Ho Ahn
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef VECTORS_H_DEF
|
||||||
|
#define VECTORS_H_DEF
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// 2D vector
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
struct Vector2
|
||||||
|
{
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
|
||||||
|
// ctors
|
||||||
|
Vector2() : x(0), y(0) {};
|
||||||
|
Vector2(float x, float y) : x(x), y(y) {};
|
||||||
|
|
||||||
|
// utils functions
|
||||||
|
void set(float x, float y);
|
||||||
|
float length() const; //
|
||||||
|
float distance(const Vector2& vec) const; // distance between two vectors
|
||||||
|
Vector2& normalize(); //
|
||||||
|
float dot(const Vector2& vec) const; // dot product
|
||||||
|
bool equal(const Vector2& vec, float e) const; // compare with epsilon
|
||||||
|
|
||||||
|
// operators
|
||||||
|
Vector2 operator-() const; // unary operator (negate)
|
||||||
|
Vector2 operator+(const Vector2& rhs) const; // add rhs
|
||||||
|
Vector2 operator-(const Vector2& rhs) const; // subtract rhs
|
||||||
|
Vector2& operator+=(const Vector2& rhs); // add rhs and update this object
|
||||||
|
Vector2& operator-=(const Vector2& rhs); // subtract rhs and update this object
|
||||||
|
Vector2 operator*(const float scale) const; // scale
|
||||||
|
Vector2 operator*(const Vector2& rhs) const; // multiply each element
|
||||||
|
Vector2& operator*=(const float scale); // scale and update this object
|
||||||
|
Vector2& operator*=(const Vector2& rhs); // multiply each element and update this object
|
||||||
|
Vector2 operator/(const float scale) const; // inverse scale
|
||||||
|
Vector2& operator/=(const float scale); // scale and update this object
|
||||||
|
bool operator==(const Vector2& rhs) const; // exact compare, no epsilon
|
||||||
|
bool operator!=(const Vector2& rhs) const; // exact compare, no epsilon
|
||||||
|
bool operator<(const Vector2& rhs) const; // comparison for sort
|
||||||
|
float operator[](int index) const; // subscript operator v[0], v[1]
|
||||||
|
float& operator[](int index); // subscript operator v[0], v[1]
|
||||||
|
|
||||||
|
friend Vector2 operator*(const float a, const Vector2 vec);
|
||||||
|
friend std::ostream& operator<<(std::ostream& os, const Vector2& vec);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// 3D vector
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
struct Vector3
|
||||||
|
{
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
float z;
|
||||||
|
|
||||||
|
// ctors
|
||||||
|
Vector3() : x(0), y(0), z(0) {};
|
||||||
|
Vector3(float x, float y, float z) : x(x), y(y), z(z) {};
|
||||||
|
|
||||||
|
// utils functions
|
||||||
|
void set(float x, float y, float z);
|
||||||
|
float length() const; //
|
||||||
|
float distance(const Vector3& vec) const; // distance between two vectors
|
||||||
|
Vector3& normalize(); //
|
||||||
|
float dot(const Vector3& vec) const; // dot product
|
||||||
|
Vector3 cross(const Vector3& vec) const; // cross product
|
||||||
|
bool equal(const Vector3& vec, float e) const; // compare with epsilon
|
||||||
|
|
||||||
|
// operators
|
||||||
|
Vector3 operator-() const; // unary operator (negate)
|
||||||
|
Vector3 operator+(const Vector3& rhs) const; // add rhs
|
||||||
|
Vector3 operator-(const Vector3& rhs) const; // subtract rhs
|
||||||
|
Vector3& operator+=(const Vector3& rhs); // add rhs and update this object
|
||||||
|
Vector3& operator-=(const Vector3& rhs); // subtract rhs and update this object
|
||||||
|
Vector3 operator*(const float scale) const; // scale
|
||||||
|
Vector3 operator*(const Vector3& rhs) const; // multiplay each element
|
||||||
|
Vector3& operator*=(const float scale); // scale and update this object
|
||||||
|
Vector3& operator*=(const Vector3& rhs); // product each element and update this object
|
||||||
|
Vector3 operator/(const float scale) const; // inverse scale
|
||||||
|
Vector3& operator/=(const float scale); // scale and update this object
|
||||||
|
bool operator==(const Vector3& rhs) const; // exact compare, no epsilon
|
||||||
|
bool operator!=(const Vector3& rhs) const; // exact compare, no epsilon
|
||||||
|
bool operator<(const Vector3& rhs) const; // comparison for sort
|
||||||
|
float operator[](int index) const; // subscript operator v[0], v[1]
|
||||||
|
float& operator[](int index); // subscript operator v[0], v[1]
|
||||||
|
|
||||||
|
friend Vector3 operator*(const float a, const Vector3 vec);
|
||||||
|
friend std::ostream& operator<<(std::ostream& os, const Vector3& vec);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// 4D vector
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
struct Vector4
|
||||||
|
{
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
float z;
|
||||||
|
float w;
|
||||||
|
|
||||||
|
// ctors
|
||||||
|
Vector4() : x(0), y(0), z(0), w(0) {};
|
||||||
|
Vector4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) {};
|
||||||
|
|
||||||
|
// utils functions
|
||||||
|
void set(float x, float y, float z, float w);
|
||||||
|
float length() const; //
|
||||||
|
float distance(const Vector4& vec) const; // distance between two vectors
|
||||||
|
Vector4& normalize(); //
|
||||||
|
float dot(const Vector4& vec) const; // dot product
|
||||||
|
bool equal(const Vector4& vec, float e) const; // compare with epsilon
|
||||||
|
|
||||||
|
// operators
|
||||||
|
Vector4 operator-() const; // unary operator (negate)
|
||||||
|
Vector4 operator+(const Vector4& rhs) const; // add rhs
|
||||||
|
Vector4 operator-(const Vector4& rhs) const; // subtract rhs
|
||||||
|
Vector4& operator+=(const Vector4& rhs); // add rhs and update this object
|
||||||
|
Vector4& operator-=(const Vector4& rhs); // subtract rhs and update this object
|
||||||
|
Vector4 operator*(const float scale) const; // scale
|
||||||
|
Vector4 operator*(const Vector4& rhs) const; // multiply each element
|
||||||
|
Vector4& operator*=(const float scale); // scale and update this object
|
||||||
|
Vector4& operator*=(const Vector4& rhs); // multiply each element and update this object
|
||||||
|
Vector4 operator/(const float scale) const; // inverse scale
|
||||||
|
Vector4& operator/=(const float scale); // scale and update this object
|
||||||
|
bool operator==(const Vector4& rhs) const; // exact compare, no epsilon
|
||||||
|
bool operator!=(const Vector4& rhs) const; // exact compare, no epsilon
|
||||||
|
bool operator<(const Vector4& rhs) const; // comparison for sort
|
||||||
|
float operator[](int index) const; // subscript operator v[0], v[1]
|
||||||
|
float& operator[](int index); // subscript operator v[0], v[1]
|
||||||
|
|
||||||
|
friend Vector4 operator*(const float a, const Vector4 vec);
|
||||||
|
friend std::ostream& operator<<(std::ostream& os, const Vector4& vec);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// fast math routines from Doom3 SDK
|
||||||
|
inline float invSqrt(float x)
|
||||||
|
{
|
||||||
|
float xhalf = 0.5f * x;
|
||||||
|
int i = *(int*)&x; // get bits for floating value
|
||||||
|
i = 0x5f3759df - (i>>1); // gives initial guess
|
||||||
|
x = *(float*)&i; // convert bits back to float
|
||||||
|
x = x * (1.5f - xhalf*x*x); // Newton step
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// inline functions for Vector2
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
inline Vector2 Vector2::operator-() const {
|
||||||
|
return Vector2(-x, -y);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector2 Vector2::operator+(const Vector2& rhs) const {
|
||||||
|
return Vector2(x+rhs.x, y+rhs.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector2 Vector2::operator-(const Vector2& rhs) const {
|
||||||
|
return Vector2(x-rhs.x, y-rhs.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector2& Vector2::operator+=(const Vector2& rhs) {
|
||||||
|
x += rhs.x; y += rhs.y; return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector2& Vector2::operator-=(const Vector2& rhs) {
|
||||||
|
x -= rhs.x; y -= rhs.y; return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector2 Vector2::operator*(const float a) const {
|
||||||
|
return Vector2(x*a, y*a);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector2 Vector2::operator*(const Vector2& rhs) const {
|
||||||
|
return Vector2(x*rhs.x, y*rhs.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector2& Vector2::operator*=(const float a) {
|
||||||
|
x *= a; y *= a; return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector2& Vector2::operator*=(const Vector2& rhs) {
|
||||||
|
x *= rhs.x; y *= rhs.y; return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector2 Vector2::operator/(const float a) const {
|
||||||
|
return Vector2(x/a, y/a);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector2& Vector2::operator/=(const float a) {
|
||||||
|
x /= a; y /= a; return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Vector2::operator==(const Vector2& rhs) const {
|
||||||
|
return (x == rhs.x) && (y == rhs.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Vector2::operator!=(const Vector2& rhs) const {
|
||||||
|
return (x != rhs.x) || (y != rhs.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Vector2::operator<(const Vector2& rhs) const {
|
||||||
|
if(x < rhs.x) return true;
|
||||||
|
if(x > rhs.x) return false;
|
||||||
|
if(y < rhs.y) return true;
|
||||||
|
if(y > rhs.y) return false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float Vector2::operator[](int index) const {
|
||||||
|
return (&x)[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float& Vector2::operator[](int index) {
|
||||||
|
return (&x)[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Vector2::set(float x, float y) {
|
||||||
|
this->x = x; this->y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float Vector2::length() const {
|
||||||
|
return sqrtf(x*x + y*y);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float Vector2::distance(const Vector2& vec) const {
|
||||||
|
return sqrtf((vec.x-x)*(vec.x-x) + (vec.y-y)*(vec.y-y));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector2& Vector2::normalize() {
|
||||||
|
//@@const float EPSILON = 0.000001f;
|
||||||
|
float xxyy = x*x + y*y;
|
||||||
|
//@@if(xxyy < EPSILON)
|
||||||
|
//@@ return *this;
|
||||||
|
|
||||||
|
//float invLength = invSqrt(xxyy);
|
||||||
|
float invLength = 1.0f / sqrtf(xxyy);
|
||||||
|
x *= invLength;
|
||||||
|
y *= invLength;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float Vector2::dot(const Vector2& rhs) const {
|
||||||
|
return (x*rhs.x + y*rhs.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Vector2::equal(const Vector2& rhs, float epsilon) const {
|
||||||
|
return fabs(x - rhs.x) < epsilon && fabs(y - rhs.y) < epsilon;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector2 operator*(const float a, const Vector2 vec) {
|
||||||
|
return Vector2(a*vec.x, a*vec.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::ostream& operator<<(std::ostream& os, const Vector2& vec) {
|
||||||
|
os << "(" << vec.x << ", " << vec.y << ")";
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
// END OF VECTOR2 /////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// inline functions for Vector3
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
inline Vector3 Vector3::operator-() const {
|
||||||
|
return Vector3(-x, -y, -z);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector3 Vector3::operator+(const Vector3& rhs) const {
|
||||||
|
return Vector3(x+rhs.x, y+rhs.y, z+rhs.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector3 Vector3::operator-(const Vector3& rhs) const {
|
||||||
|
return Vector3(x-rhs.x, y-rhs.y, z-rhs.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector3& Vector3::operator+=(const Vector3& rhs) {
|
||||||
|
x += rhs.x; y += rhs.y; z += rhs.z; return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector3& Vector3::operator-=(const Vector3& rhs) {
|
||||||
|
x -= rhs.x; y -= rhs.y; z -= rhs.z; return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector3 Vector3::operator*(const float a) const {
|
||||||
|
return Vector3(x*a, y*a, z*a);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector3 Vector3::operator*(const Vector3& rhs) const {
|
||||||
|
return Vector3(x*rhs.x, y*rhs.y, z*rhs.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector3& Vector3::operator*=(const float a) {
|
||||||
|
x *= a; y *= a; z *= a; return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector3& Vector3::operator*=(const Vector3& rhs) {
|
||||||
|
x *= rhs.x; y *= rhs.y; z *= rhs.z; return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector3 Vector3::operator/(const float a) const {
|
||||||
|
return Vector3(x/a, y/a, z/a);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector3& Vector3::operator/=(const float a) {
|
||||||
|
x /= a; y /= a; z /= a; return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Vector3::operator==(const Vector3& rhs) const {
|
||||||
|
return (x == rhs.x) && (y == rhs.y) && (z == rhs.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Vector3::operator!=(const Vector3& rhs) const {
|
||||||
|
return (x != rhs.x) || (y != rhs.y) || (z != rhs.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Vector3::operator<(const Vector3& rhs) const {
|
||||||
|
if(x < rhs.x) return true;
|
||||||
|
if(x > rhs.x) return false;
|
||||||
|
if(y < rhs.y) return true;
|
||||||
|
if(y > rhs.y) return false;
|
||||||
|
if(z < rhs.z) return true;
|
||||||
|
if(z > rhs.z) return false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float Vector3::operator[](int index) const {
|
||||||
|
return (&x)[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float& Vector3::operator[](int index) {
|
||||||
|
return (&x)[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Vector3::set(float x, float y, float z) {
|
||||||
|
this->x = x; this->y = y; this->z = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float Vector3::length() const {
|
||||||
|
return sqrtf(x*x + y*y + z*z);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float Vector3::distance(const Vector3& vec) const {
|
||||||
|
return sqrtf((vec.x-x)*(vec.x-x) + (vec.y-y)*(vec.y-y) + (vec.z-z)*(vec.z-z));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector3& Vector3::normalize() {
|
||||||
|
//@@const float EPSILON = 0.000001f;
|
||||||
|
float xxyyzz = x*x + y*y + z*z;
|
||||||
|
//@@if(xxyyzz < EPSILON)
|
||||||
|
//@@ return *this; // do nothing if it is ~zero vector
|
||||||
|
|
||||||
|
//float invLength = invSqrt(xxyyzz);
|
||||||
|
float invLength = 1.0f / sqrtf(xxyyzz);
|
||||||
|
x *= invLength;
|
||||||
|
y *= invLength;
|
||||||
|
z *= invLength;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float Vector3::dot(const Vector3& rhs) const {
|
||||||
|
return (x*rhs.x + y*rhs.y + z*rhs.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector3 Vector3::cross(const Vector3& rhs) const {
|
||||||
|
return Vector3(y*rhs.z - z*rhs.y, z*rhs.x - x*rhs.z, x*rhs.y - y*rhs.x);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Vector3::equal(const Vector3& rhs, float epsilon) const {
|
||||||
|
return fabs(x - rhs.x) < epsilon && fabs(y - rhs.y) < epsilon && fabs(z - rhs.z) < epsilon;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector3 operator*(const float a, const Vector3 vec) {
|
||||||
|
return Vector3(a*vec.x, a*vec.y, a*vec.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::ostream& operator<<(std::ostream& os, const Vector3& vec) {
|
||||||
|
os << "(" << vec.x << ", " << vec.y << ", " << vec.z << ")";
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
// END OF VECTOR3 /////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// inline functions for Vector4
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
inline Vector4 Vector4::operator-() const {
|
||||||
|
return Vector4(-x, -y, -z, -w);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector4 Vector4::operator+(const Vector4& rhs) const {
|
||||||
|
return Vector4(x+rhs.x, y+rhs.y, z+rhs.z, w+rhs.w);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector4 Vector4::operator-(const Vector4& rhs) const {
|
||||||
|
return Vector4(x-rhs.x, y-rhs.y, z-rhs.z, w-rhs.w);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector4& Vector4::operator+=(const Vector4& rhs) {
|
||||||
|
x += rhs.x; y += rhs.y; z += rhs.z; w += rhs.w; return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector4& Vector4::operator-=(const Vector4& rhs) {
|
||||||
|
x -= rhs.x; y -= rhs.y; z -= rhs.z; w -= rhs.w; return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector4 Vector4::operator*(const float a) const {
|
||||||
|
return Vector4(x*a, y*a, z*a, w*a);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector4 Vector4::operator*(const Vector4& rhs) const {
|
||||||
|
return Vector4(x*rhs.x, y*rhs.y, z*rhs.z, w*rhs.w);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector4& Vector4::operator*=(const float a) {
|
||||||
|
x *= a; y *= a; z *= a; w *= a; return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector4& Vector4::operator*=(const Vector4& rhs) {
|
||||||
|
x *= rhs.x; y *= rhs.y; z *= rhs.z; w *= rhs.w; return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector4 Vector4::operator/(const float a) const {
|
||||||
|
return Vector4(x/a, y/a, z/a, w/a);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector4& Vector4::operator/=(const float a) {
|
||||||
|
x /= a; y /= a; z /= a; w /= a; return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Vector4::operator==(const Vector4& rhs) const {
|
||||||
|
return (x == rhs.x) && (y == rhs.y) && (z == rhs.z) && (w == rhs.w);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Vector4::operator!=(const Vector4& rhs) const {
|
||||||
|
return (x != rhs.x) || (y != rhs.y) || (z != rhs.z) || (w != rhs.w);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Vector4::operator<(const Vector4& rhs) const {
|
||||||
|
if(x < rhs.x) return true;
|
||||||
|
if(x > rhs.x) return false;
|
||||||
|
if(y < rhs.y) return true;
|
||||||
|
if(y > rhs.y) return false;
|
||||||
|
if(z < rhs.z) return true;
|
||||||
|
if(z > rhs.z) return false;
|
||||||
|
if(w < rhs.w) return true;
|
||||||
|
if(w > rhs.w) return false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float Vector4::operator[](int index) const {
|
||||||
|
return (&x)[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float& Vector4::operator[](int index) {
|
||||||
|
return (&x)[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Vector4::set(float x, float y, float z, float w) {
|
||||||
|
this->x = x; this->y = y; this->z = z; this->w = w;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float Vector4::length() const {
|
||||||
|
return sqrtf(x*x + y*y + z*z + w*w);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float Vector4::distance(const Vector4& vec) const {
|
||||||
|
return sqrtf((vec.x-x)*(vec.x-x) + (vec.y-y)*(vec.y-y) + (vec.z-z)*(vec.z-z) + (vec.w-w)*(vec.w-w));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector4& Vector4::normalize() {
|
||||||
|
//NOTE: leave w-component untouched
|
||||||
|
//@@const float EPSILON = 0.000001f;
|
||||||
|
float xxyyzz = x*x + y*y + z*z;
|
||||||
|
//@@if(xxyyzz < EPSILON)
|
||||||
|
//@@ return *this; // do nothing if it is zero vector
|
||||||
|
|
||||||
|
//float invLength = invSqrt(xxyyzz);
|
||||||
|
float invLength = 1.0f / sqrtf(xxyyzz);
|
||||||
|
x *= invLength;
|
||||||
|
y *= invLength;
|
||||||
|
z *= invLength;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float Vector4::dot(const Vector4& rhs) const {
|
||||||
|
return (x*rhs.x + y*rhs.y + z*rhs.z + w*rhs.w);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Vector4::equal(const Vector4& rhs, float epsilon) const {
|
||||||
|
return fabs(x - rhs.x) < epsilon && fabs(y - rhs.y) < epsilon &&
|
||||||
|
fabs(z - rhs.z) < epsilon && fabs(w - rhs.w) < epsilon;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector4 operator*(const float a, const Vector4 vec) {
|
||||||
|
return Vector4(a*vec.x, a*vec.y, a*vec.z, a*vec.w);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::ostream& operator<<(std::ostream& os, const Vector4& vec) {
|
||||||
|
os << "(" << vec.x << ", " << vec.y << ", " << vec.z << ", " << vec.w << ")";
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
// END OF VECTOR4 /////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#endif
|
6104
examples/ThirdPartyLibs/openvr/samples/shared/lodepng.cpp
Normal file
6104
examples/ThirdPartyLibs/openvr/samples/shared/lodepng.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1702
examples/ThirdPartyLibs/openvr/samples/shared/lodepng.h
Normal file
1702
examples/ThirdPartyLibs/openvr/samples/shared/lodepng.h
Normal file
File diff suppressed because it is too large
Load Diff
560
examples/ThirdPartyLibs/openvr/samples/shared/pathtools.cpp
Normal file
560
examples/ThirdPartyLibs/openvr/samples/shared/pathtools.cpp
Normal file
@ -0,0 +1,560 @@
|
|||||||
|
//========= Copyright Valve Corporation ============//
|
||||||
|
#include "pathtools.h"
|
||||||
|
//#include "hmdplatform_private.h"
|
||||||
|
//#include "vrcommon/strtools.h"
|
||||||
|
|
||||||
|
#if defined( _WIN32)
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <direct.h>
|
||||||
|
#include <Shobjidl.h>
|
||||||
|
#include <KnownFolders.h>
|
||||||
|
#elif defined OSX
|
||||||
|
#include <mach-o/dyld.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include "osxfilebridge.h"
|
||||||
|
#define _S_IFDIR S_IFDIR // really from tier0/platform.h which we dont have yet
|
||||||
|
#define _MAX_PATH MAX_PATH // yet another form of _PATH define we use
|
||||||
|
#elif defined(LINUX)
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
/** Returns the path (including filename) to the current executable */
|
||||||
|
std::string Path_GetExecutablePath()
|
||||||
|
{
|
||||||
|
bool bSuccess = false;
|
||||||
|
char rchPath[ 1024 ];
|
||||||
|
size_t nBuff = sizeof(rchPath);
|
||||||
|
#if defined( _WIN32 )
|
||||||
|
bSuccess = ::GetModuleFileNameA(NULL, rchPath, (DWORD)nBuff) > 0;
|
||||||
|
#elif defined OSX
|
||||||
|
uint32_t _nBuff = nBuff;
|
||||||
|
bSuccess = _NSGetExecutablePath(rchPath, &_nBuff) == 0;
|
||||||
|
rchPath[nBuff-1] = '\0';
|
||||||
|
#elif defined LINUX
|
||||||
|
ssize_t nRead = readlink("/proc/self/exe", rchPath, nBuff-1 );
|
||||||
|
if ( nRead != -1 )
|
||||||
|
{
|
||||||
|
rchPath[ nRead ] = 0;
|
||||||
|
bSuccess = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rchPath[ 0 ] = '\0';
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
AssertMsg( false, "Implement Plat_GetExecutablePath" );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if( bSuccess )
|
||||||
|
return rchPath;
|
||||||
|
else
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the path of the current working directory */
|
||||||
|
std::string Path_GetWorkingDirectory()
|
||||||
|
{
|
||||||
|
std::string sPath;
|
||||||
|
char buf[ 1024 ];
|
||||||
|
#if defined( _WIN32 )
|
||||||
|
sPath = _getcwd( buf, sizeof( buf ) );
|
||||||
|
#else
|
||||||
|
sPath = getcwd( buf, sizeof( buf ) );
|
||||||
|
#endif
|
||||||
|
return sPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sets the path of the current working directory. Returns true if this was successful. */
|
||||||
|
bool Path_SetWorkingDirectory( const std::string & sPath )
|
||||||
|
{
|
||||||
|
bool bSuccess;
|
||||||
|
#if defined( _WIN32 )
|
||||||
|
bSuccess = 0 == _chdir( sPath.c_str() );
|
||||||
|
#else
|
||||||
|
bSuccess = 0 == chdir( sPath.c_str() );
|
||||||
|
#endif
|
||||||
|
return bSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Path_GetModulePath()
|
||||||
|
{
|
||||||
|
#if defined( _WIN32 )
|
||||||
|
char path[32768];
|
||||||
|
HMODULE hm = NULL;
|
||||||
|
|
||||||
|
if (!GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
|
||||||
|
(LPCSTR) &Path_GetModulePath,
|
||||||
|
&hm))
|
||||||
|
{
|
||||||
|
int ret = GetLastError();
|
||||||
|
fprintf(stderr, "GetModuleHandle returned %d\n", ret);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
GetModuleFileNameA(hm, path, sizeof(path));
|
||||||
|
FreeLibrary( hm );
|
||||||
|
return path;
|
||||||
|
#else
|
||||||
|
Dl_info dl_info;
|
||||||
|
dladdr((void *)Path_GetModulePath, &dl_info);
|
||||||
|
return dl_info.dli_fname;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the specified path without its filename */
|
||||||
|
std::string Path_StripFilename( const std::string & sPath, char slash )
|
||||||
|
{
|
||||||
|
if( slash == 0 )
|
||||||
|
slash = Path_GetSlash();
|
||||||
|
|
||||||
|
std::string::size_type n = sPath.find_last_of( slash );
|
||||||
|
if( n == std::string::npos )
|
||||||
|
return sPath;
|
||||||
|
else
|
||||||
|
return std::string( sPath.begin(), sPath.begin() + n );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** returns just the filename from the provided full or relative path. */
|
||||||
|
std::string Path_StripDirectory( const std::string & sPath, char slash )
|
||||||
|
{
|
||||||
|
if( slash == 0 )
|
||||||
|
slash = Path_GetSlash();
|
||||||
|
|
||||||
|
std::string::size_type n = sPath.find_last_of( slash );
|
||||||
|
if( n == std::string::npos )
|
||||||
|
return sPath;
|
||||||
|
else
|
||||||
|
return std::string( sPath.begin() + n + 1, sPath.end() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** returns just the filename with no extension of the provided filename.
|
||||||
|
* If there is a path the path is left intact. */
|
||||||
|
std::string Path_StripExtension( const std::string & sPath )
|
||||||
|
{
|
||||||
|
for( std::string::const_reverse_iterator i = sPath.rbegin(); i != sPath.rend(); i++ )
|
||||||
|
{
|
||||||
|
if( *i == '.' )
|
||||||
|
{
|
||||||
|
return std::string( sPath.begin(), i.base() - 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we find a slash there is no extension
|
||||||
|
if( *i == '\\' || *i == '/' )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we didn't find an extension
|
||||||
|
return sPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Path_IsAbsolute( const std::string & sPath )
|
||||||
|
{
|
||||||
|
if( sPath.empty() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if( sPath.find( ':' ) != std::string::npos )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if( sPath[0] == '\\' || sPath[0] == '/' )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Makes an absolute path from a relative path and a base path */
|
||||||
|
std::string Path_MakeAbsolute( const std::string & sRelativePath, const std::string & sBasePath, char slash )
|
||||||
|
{
|
||||||
|
if( slash == 0 )
|
||||||
|
slash = Path_GetSlash();
|
||||||
|
|
||||||
|
if( Path_IsAbsolute( sRelativePath ) )
|
||||||
|
return sRelativePath;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( !Path_IsAbsolute( sBasePath ) )
|
||||||
|
return "";
|
||||||
|
|
||||||
|
std::string sCompacted = Path_Compact( Path_Join( sBasePath, sRelativePath, slash ), slash );
|
||||||
|
if( Path_IsAbsolute( sCompacted ) )
|
||||||
|
return sCompacted;
|
||||||
|
else
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Fixes the directory separators for the current platform */
|
||||||
|
std::string Path_FixSlashes( const std::string & sPath, char slash )
|
||||||
|
{
|
||||||
|
if( slash == 0 )
|
||||||
|
slash = Path_GetSlash();
|
||||||
|
|
||||||
|
std::string sFixed = sPath;
|
||||||
|
for( std::string::iterator i = sFixed.begin(); i != sFixed.end(); i++ )
|
||||||
|
{
|
||||||
|
if( *i == '/' || *i == '\\' )
|
||||||
|
*i = slash;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sFixed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char Path_GetSlash()
|
||||||
|
{
|
||||||
|
#if defined(_WIN32)
|
||||||
|
return '\\';
|
||||||
|
#else
|
||||||
|
return '/';
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Jams two paths together with the right kind of slash */
|
||||||
|
std::string Path_Join( const std::string & first, const std::string & second, char slash )
|
||||||
|
{
|
||||||
|
if( slash == 0 )
|
||||||
|
slash = Path_GetSlash();
|
||||||
|
|
||||||
|
// only insert a slash if we don't already have one
|
||||||
|
std::string::size_type nLen = first.length();
|
||||||
|
#if defined(_WIN32)
|
||||||
|
if( first.back() == '\\' || first.back() == '/' )
|
||||||
|
nLen--;
|
||||||
|
#else
|
||||||
|
char last_char = first[first.length()-1];
|
||||||
|
if (last_char == '\\' || last_char == '/')
|
||||||
|
nLen--;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return first.substr( 0, nLen ) + std::string( 1, slash ) + second;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string Path_Join( const std::string & first, const std::string & second, const std::string & third, char slash )
|
||||||
|
{
|
||||||
|
return Path_Join( Path_Join( first, second, slash ), third, slash );
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Path_Join( const std::string & first, const std::string & second, const std::string & third, const std::string &fourth, char slash )
|
||||||
|
{
|
||||||
|
return Path_Join( Path_Join( Path_Join( first, second, slash ), third, slash ), fourth, slash );
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Path_Join(
|
||||||
|
const std::string & first,
|
||||||
|
const std::string & second,
|
||||||
|
const std::string & third,
|
||||||
|
const std::string & fourth,
|
||||||
|
const std::string & fifth,
|
||||||
|
char slash )
|
||||||
|
{
|
||||||
|
return Path_Join( Path_Join( Path_Join( Path_Join( first, second, slash ), third, slash ), fourth, slash ), fifth, slash );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Removes redundant <dir>/.. elements in the path. Returns an empty path if the
|
||||||
|
* specified path has a broken number of directories for its number of ..s */
|
||||||
|
std::string Path_Compact( const std::string & sRawPath, char slash )
|
||||||
|
{
|
||||||
|
if( slash == 0 )
|
||||||
|
slash = Path_GetSlash();
|
||||||
|
|
||||||
|
std::string sPath = Path_FixSlashes( sRawPath, slash );
|
||||||
|
std::string sSlashString( 1, slash );
|
||||||
|
|
||||||
|
// strip out all /./
|
||||||
|
for( std::string::size_type i = 0; (i + 3) < sPath.length(); )
|
||||||
|
{
|
||||||
|
if( sPath[ i ] == slash && sPath[ i+1 ] == '.' && sPath[ i+2 ] == slash )
|
||||||
|
{
|
||||||
|
sPath.replace( i, 3, sSlashString );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// get rid of trailing /. but leave the path separator
|
||||||
|
if( sPath.length() > 2 )
|
||||||
|
{
|
||||||
|
std::string::size_type len = sPath.length();
|
||||||
|
if( sPath[ len-1 ] == '.' && sPath[ len-2 ] == slash )
|
||||||
|
{
|
||||||
|
// sPath.pop_back();
|
||||||
|
sPath[len-1] = 0; // for now, at least
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// get rid of leading ./
|
||||||
|
if( sPath.length() > 2 )
|
||||||
|
{
|
||||||
|
if( sPath[ 0 ] == '.' && sPath[ 1 ] == slash )
|
||||||
|
{
|
||||||
|
sPath.replace( 0, 2, "" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// each time we encounter .. back up until we've found the previous directory name
|
||||||
|
// then get rid of both
|
||||||
|
std::string::size_type i = 0;
|
||||||
|
while( i < sPath.length() )
|
||||||
|
{
|
||||||
|
if( i > 0 && sPath.length() - i >= 2
|
||||||
|
&& sPath[i] == '.'
|
||||||
|
&& sPath[i+1] == '.'
|
||||||
|
&& ( i + 2 == sPath.length() || sPath[ i+2 ] == slash )
|
||||||
|
&& sPath[ i-1 ] == slash )
|
||||||
|
{
|
||||||
|
// check if we've hit the start of the string and have a bogus path
|
||||||
|
if( i == 1 )
|
||||||
|
return "";
|
||||||
|
|
||||||
|
// find the separator before i-1
|
||||||
|
std::string::size_type iDirStart = i-2;
|
||||||
|
while( iDirStart > 0 && sPath[ iDirStart - 1 ] != slash )
|
||||||
|
--iDirStart;
|
||||||
|
|
||||||
|
// remove everything from iDirStart to i+2
|
||||||
|
sPath.replace( iDirStart, (i - iDirStart) + 3, "" );
|
||||||
|
|
||||||
|
// start over
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MAX_UNICODE_PATH 32768
|
||||||
|
#define MAX_UNICODE_PATH_IN_UTF8 ( MAX_UNICODE_PATH * 4 )
|
||||||
|
|
||||||
|
/** Returns the path to the current DLL or exe */
|
||||||
|
std::string GetThisModulePath()
|
||||||
|
{
|
||||||
|
// gets the path of vrclient.dll itself
|
||||||
|
#ifdef WIN32
|
||||||
|
HMODULE hmodule = NULL;
|
||||||
|
|
||||||
|
::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, reinterpret_cast<LPCTSTR>(GetThisModulePath), &hmodule);
|
||||||
|
|
||||||
|
wchar_t *pwchPath = new wchar_t[MAX_UNICODE_PATH];
|
||||||
|
char *pchPath = new char[ MAX_UNICODE_PATH_IN_UTF8 ];
|
||||||
|
::GetModuleFileNameW( hmodule, pwchPath, MAX_UNICODE_PATH );
|
||||||
|
WideCharToMultiByte( CP_UTF8, 0, pwchPath, -1, pchPath, MAX_UNICODE_PATH_IN_UTF8, NULL, NULL );
|
||||||
|
delete[] pwchPath;
|
||||||
|
|
||||||
|
std::string sPath = pchPath;
|
||||||
|
delete [] pchPath;
|
||||||
|
return sPath;
|
||||||
|
|
||||||
|
#elif defined( OSX ) || defined( LINUX )
|
||||||
|
// get the addr of a function in vrclient.so and then ask the dlopen system about it
|
||||||
|
Dl_info info;
|
||||||
|
dladdr( (void *)GetThisModulePath, &info );
|
||||||
|
return info.dli_fname;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** returns true if the specified path exists and is a directory */
|
||||||
|
bool Path_IsDirectory( const std::string & sPath )
|
||||||
|
{
|
||||||
|
std::string sFixedPath = Path_FixSlashes( sPath );
|
||||||
|
if( sFixedPath.empty() )
|
||||||
|
return false;
|
||||||
|
char cLast = sFixedPath[ sFixedPath.length() - 1 ];
|
||||||
|
if( cLast == '/' || cLast == '\\' )
|
||||||
|
sFixedPath.erase( sFixedPath.end() - 1, sFixedPath.end() );
|
||||||
|
|
||||||
|
// see if the specified path actually exists.
|
||||||
|
struct stat buf;
|
||||||
|
if ( stat ( sFixedPath.c_str(), &buf ) == -1)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(LINUX)
|
||||||
|
return S_ISDIR( buf.st_mode );
|
||||||
|
#else
|
||||||
|
return ( buf.st_mode & _S_IFDIR ) != 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: returns true if the the path exists
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool Path_Exists( const std::string & sPath )
|
||||||
|
{
|
||||||
|
std::string sFixedPath = Path_FixSlashes( sPath );
|
||||||
|
if( sFixedPath.empty() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
struct stat buf;
|
||||||
|
if ( stat ( sFixedPath.c_str(), &buf ) == -1)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: helper to find a directory upstream from a given path
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
std::string Path_FindParentDirectoryRecursively( const std::string &strStartDirectory, const std::string &strDirectoryName )
|
||||||
|
{
|
||||||
|
std::string strFoundPath = "";
|
||||||
|
std::string strCurrentPath = Path_FixSlashes( strStartDirectory );
|
||||||
|
if ( strCurrentPath.length() == 0 )
|
||||||
|
return "";
|
||||||
|
|
||||||
|
bool bExists = Path_Exists( strCurrentPath );
|
||||||
|
std::string strCurrentDirectoryName = Path_StripDirectory( strCurrentPath );
|
||||||
|
if ( bExists && stricmp( strCurrentDirectoryName.c_str(), strDirectoryName.c_str() ) == 0 )
|
||||||
|
return strCurrentPath;
|
||||||
|
|
||||||
|
while( bExists && strCurrentPath.length() != 0 )
|
||||||
|
{
|
||||||
|
strCurrentPath = Path_StripFilename( strCurrentPath );
|
||||||
|
strCurrentDirectoryName = Path_StripDirectory( strCurrentPath );
|
||||||
|
bExists = Path_Exists( strCurrentPath );
|
||||||
|
if ( bExists && stricmp( strCurrentDirectoryName.c_str(), strDirectoryName.c_str() ) == 0 )
|
||||||
|
return strCurrentPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: helper to find a subdirectory upstream from a given path
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
std::string Path_FindParentSubDirectoryRecursively( const std::string &strStartDirectory, const std::string &strDirectoryName )
|
||||||
|
{
|
||||||
|
std::string strFoundPath = "";
|
||||||
|
std::string strCurrentPath = Path_FixSlashes( strStartDirectory );
|
||||||
|
if ( strCurrentPath.length() == 0 )
|
||||||
|
return "";
|
||||||
|
|
||||||
|
bool bExists = Path_Exists( strCurrentPath );
|
||||||
|
while( bExists && strCurrentPath.length() != 0 )
|
||||||
|
{
|
||||||
|
strCurrentPath = Path_StripFilename( strCurrentPath );
|
||||||
|
bExists = Path_Exists( strCurrentPath );
|
||||||
|
|
||||||
|
if( Path_Exists( Path_Join( strCurrentPath, strDirectoryName ) ) )
|
||||||
|
{
|
||||||
|
strFoundPath = Path_Join( strCurrentPath, strDirectoryName );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return strFoundPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: reading and writing files in the vortex directory
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
unsigned char * Path_ReadBinaryFile( const std::string &strFilename, int *pSize )
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
#if defined( POSIX )
|
||||||
|
f = fopen( strFilename.c_str(), "rb" );
|
||||||
|
#else
|
||||||
|
errno_t err = fopen_s(&f, strFilename.c_str(), "rb");
|
||||||
|
if ( err != 0 )
|
||||||
|
{
|
||||||
|
f = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
unsigned char* buf = NULL;
|
||||||
|
|
||||||
|
if ( f != NULL )
|
||||||
|
{
|
||||||
|
fseek(f, 0, SEEK_END);
|
||||||
|
int size = ftell(f);
|
||||||
|
fseek(f, 0, SEEK_SET);
|
||||||
|
|
||||||
|
buf = new unsigned char[size];
|
||||||
|
if (buf && fread(buf, size, 1, f) == 1)
|
||||||
|
{
|
||||||
|
if (pSize)
|
||||||
|
*pSize = size;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
delete[] buf;
|
||||||
|
buf = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string Path_ReadTextFile( const std::string &strFilename )
|
||||||
|
{
|
||||||
|
// doing it this way seems backwards, but I don't
|
||||||
|
// see an easy way to do this with C/C++ style IO
|
||||||
|
// that isn't worse...
|
||||||
|
int size;
|
||||||
|
unsigned char* buf = Path_ReadBinaryFile( strFilename, &size );
|
||||||
|
if (!buf)
|
||||||
|
return "";
|
||||||
|
|
||||||
|
// convert CRLF -> LF
|
||||||
|
int outsize = 1;
|
||||||
|
for (int i=1; i < size; i++)
|
||||||
|
{
|
||||||
|
if (buf[i] == '\n' && buf[i-1] == '\r') // CRLF
|
||||||
|
buf[outsize-1] = '\n'; // ->LF
|
||||||
|
else
|
||||||
|
buf[outsize++] = buf[i]; // just copy
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ret((char *)buf, (char *)(buf + outsize));
|
||||||
|
delete[] buf;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Path_WriteStringToTextFile( const std::string &strFilename, const char *pchData )
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
#if defined( POSIX )
|
||||||
|
f = fopen( strFilename.c_str(), "w" );
|
||||||
|
#else
|
||||||
|
errno_t err = fopen_s(&f, strFilename.c_str(), "w");
|
||||||
|
if ( err != 0 )
|
||||||
|
{
|
||||||
|
f = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool ok = false;
|
||||||
|
|
||||||
|
if ( f != NULL )
|
||||||
|
{
|
||||||
|
ok = fputs( pchData, f) >= 0;
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ok;
|
||||||
|
}
|
98
examples/ThirdPartyLibs/openvr/samples/shared/pathtools.h
Normal file
98
examples/ThirdPartyLibs/openvr/samples/shared/pathtools.h
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
//========= Copyright Valve Corporation ============//
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
/** Returns the path (including filename) to the current executable */
|
||||||
|
std::string Path_GetExecutablePath();
|
||||||
|
|
||||||
|
/** Returns the path of the current working directory */
|
||||||
|
std::string Path_GetWorkingDirectory();
|
||||||
|
|
||||||
|
/** Sets the path of the current working directory. Returns true if this was successful. */
|
||||||
|
bool Path_SetWorkingDirectory( const std::string & sPath );
|
||||||
|
|
||||||
|
/** returns the path (including filename) of the current shared lib or DLL */
|
||||||
|
std::string Path_GetModulePath();
|
||||||
|
|
||||||
|
/** Returns the specified path without its filename.
|
||||||
|
* If slash is unspecified the native path separator of the current platform
|
||||||
|
* will be used. */
|
||||||
|
std::string Path_StripFilename( const std::string & sPath, char slash = 0 );
|
||||||
|
|
||||||
|
/** returns just the filename from the provided full or relative path. */
|
||||||
|
std::string Path_StripDirectory( const std::string & sPath, char slash = 0 );
|
||||||
|
|
||||||
|
/** returns just the filename with no extension of the provided filename.
|
||||||
|
* If there is a path the path is left intact. */
|
||||||
|
std::string Path_StripExtension( const std::string & sPath );
|
||||||
|
|
||||||
|
/** Returns true if the path is absolute */
|
||||||
|
bool Path_IsAbsolute( const std::string & sPath );
|
||||||
|
|
||||||
|
/** Makes an absolute path from a relative path and a base path */
|
||||||
|
std::string Path_MakeAbsolute( const std::string & sRelativePath, const std::string & sBasePath, char slash = 0 );
|
||||||
|
|
||||||
|
/** Fixes the directory separators for the current platform.
|
||||||
|
* If slash is unspecified the native path separator of the current platform
|
||||||
|
* will be used. */
|
||||||
|
std::string Path_FixSlashes( const std::string & sPath, char slash = 0 );
|
||||||
|
|
||||||
|
/** Returns the path separator for the current platform */
|
||||||
|
char Path_GetSlash();
|
||||||
|
|
||||||
|
/** Jams two paths together with the right kind of slash */
|
||||||
|
std::string Path_Join( const std::string & first, const std::string & second, char slash = 0 );
|
||||||
|
std::string Path_Join( const std::string & first, const std::string & second, const std::string & third, char slash = 0 );
|
||||||
|
std::string Path_Join( const std::string & first, const std::string & second, const std::string & third, const std::string &fourth, char slash = 0 );
|
||||||
|
std::string Path_Join(
|
||||||
|
const std::string & first,
|
||||||
|
const std::string & second,
|
||||||
|
const std::string & third,
|
||||||
|
const std::string & fourth,
|
||||||
|
const std::string & fifth,
|
||||||
|
char slash = 0 );
|
||||||
|
|
||||||
|
|
||||||
|
/** Removes redundant <dir>/.. elements in the path. Returns an empty path if the
|
||||||
|
* specified path has a broken number of directories for its number of ..s.
|
||||||
|
* If slash is unspecified the native path separator of the current platform
|
||||||
|
* will be used. */
|
||||||
|
std::string Path_Compact( const std::string & sRawPath, char slash = 0 );
|
||||||
|
|
||||||
|
/** returns true if the specified path exists and is a directory */
|
||||||
|
bool Path_IsDirectory( const std::string & sPath );
|
||||||
|
|
||||||
|
/** Returns the path to the current DLL or exe */
|
||||||
|
std::string GetThisModulePath();
|
||||||
|
|
||||||
|
/** returns true if the the path exists */
|
||||||
|
bool Path_Exists( const std::string & sPath );
|
||||||
|
|
||||||
|
/** Helper functions to find parent directories or subdirectories of parent directories */
|
||||||
|
std::string Path_FindParentDirectoryRecursively( const std::string &strStartDirectory, const std::string &strDirectoryName );
|
||||||
|
std::string Path_FindParentSubDirectoryRecursively( const std::string &strStartDirectory, const std::string &strDirectoryName );
|
||||||
|
|
||||||
|
/** Path operations to read or write text/binary files */
|
||||||
|
unsigned char * Path_ReadBinaryFile( const std::string &strFilename, int *pSize );
|
||||||
|
std::string Path_ReadTextFile( const std::string &strFilename );
|
||||||
|
bool Path_WriteStringToTextFile( const std::string &strFilename, const char *pchData );
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
#if defined(_WIN32)
|
||||||
|
#define DYNAMIC_LIB_EXT ".dll"
|
||||||
|
#ifdef _WIN64
|
||||||
|
#define PLATSUBDIR "win64"
|
||||||
|
#else
|
||||||
|
#define PLATSUBDIR "win32"
|
||||||
|
#endif
|
||||||
|
#elif defined(OSX)
|
||||||
|
#define DYNAMIC_LIB_EXT ".dylib"
|
||||||
|
#define PLATSUBDIR "osx32"
|
||||||
|
#elif defined(LINUX)
|
||||||
|
#define DYNAMIC_LIB_EXT ".so"
|
||||||
|
#define PLATSUBDIR "linux32"
|
||||||
|
#else
|
||||||
|
#warning "Unknown platform for PLATSUBDIR"
|
||||||
|
#define PLATSUBDIR "unknown_platform"
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user