Init
This commit is contained in:
76
DependentExtensions/cat/gfx/LoadBitmap.hpp
Normal file
76
DependentExtensions/cat/gfx/LoadBitmap.hpp
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
Copyright (c) 2009 Christopher A. Taylor. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of LibCat nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef LOAD_BITMAP_HPP
|
||||
#define LOAD_BITMAP_HPP
|
||||
|
||||
#include <cat/Platform.hpp>
|
||||
|
||||
namespace cat {
|
||||
|
||||
|
||||
/*
|
||||
LoadBitmap() loads a memory-mapped bitmap or a file from disk into RGBA format,
|
||||
meaning the first byte of every pixel is Red, then Green, Blue, and Alpha.
|
||||
The output data is useful for creating an OpenGL texture using GL_RGBA format.
|
||||
The output width and height will be powers of two.
|
||||
|
||||
Parameters:
|
||||
file, bytes : Memory-mapped file pointer and number of bytes in the file
|
||||
path : Alternatively, the path to the file to load
|
||||
width, height : The dimensions of the loaded file, in pixels
|
||||
|
||||
Returns: Zero on error, or a pointer to the rasterized RGBA pixels.
|
||||
|
||||
Free the allocated memory using Aligned::Delete(a);
|
||||
*/
|
||||
void *LoadBitmap(void *file, u32 bytes, u32 &width, u32 &height);
|
||||
void *LoadBitmap(const char *path, u32 &width, u32 &height);
|
||||
|
||||
|
||||
class BMPTokenizer
|
||||
{
|
||||
u8 trans_red, trans_green, trans_blue;
|
||||
|
||||
bool requirePOTS; // Require Power-of-Two Size
|
||||
|
||||
void rasterizeImage(u8 *image);
|
||||
void onImage(u32 *image, u32 newWidth, u32 newHeight);
|
||||
|
||||
public:
|
||||
BMPTokenizer();
|
||||
~BMPTokenizer();
|
||||
|
||||
public:
|
||||
bool LoadFile(const char *path);
|
||||
};
|
||||
|
||||
|
||||
} // namespace cat
|
||||
|
||||
#endif // LOAD_BITMAP_HPP
|
||||
162
DependentExtensions/cat/gfx/LoadPNG.hpp
Normal file
162
DependentExtensions/cat/gfx/LoadPNG.hpp
Normal file
@ -0,0 +1,162 @@
|
||||
/*
|
||||
Copyright (c) 2009 Christopher A. Taylor. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of LibCat nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef LOAD_PNG_HPP
|
||||
#define LOAD_PNG_HPP
|
||||
|
||||
#include <cat/AllFramework.hpp>
|
||||
#include <string>
|
||||
using namespace std;
|
||||
#include "zlib-1.2.4/zlib.h"
|
||||
|
||||
namespace cat {
|
||||
|
||||
#include "CRC32.hpp"
|
||||
|
||||
#ifdef CAT_PRAGMA_PACK
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 length;
|
||||
char type[4];
|
||||
} CAT_PACKED SectionHeader;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 length;
|
||||
char type[4];
|
||||
u32 crc;
|
||||
} CAT_PACKED EmptySection;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 width, height;
|
||||
u8 bitDepth, colorType, compressionMethod, filterMethod, interlaceMethod;
|
||||
} CAT_PACKED PNG_IHDR;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 r, g, b;
|
||||
} CAT_PACKED PLTE_Entry8;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PLTE_Entry8 table[256];
|
||||
} CAT_PACKED PNG_PLTE;
|
||||
|
||||
#ifdef CAT_PRAGMA_PACK
|
||||
#pragma pack(pop)
|
||||
#endif
|
||||
|
||||
|
||||
class PNGSkeletonTokenizer
|
||||
{
|
||||
protected:
|
||||
MMapFile mmf;
|
||||
CRC32Calculator calculator;
|
||||
string path;
|
||||
|
||||
// Split this from the ctor, so virtual overloads are in place by the time we start reading
|
||||
bool read(const u8 signature[8]); // Returns false on failure
|
||||
|
||||
public:
|
||||
PNGSkeletonTokenizer(const string &path, u32 CRC32polynomial);
|
||||
virtual ~PNGSkeletonTokenizer() {}
|
||||
|
||||
protected:
|
||||
// return true only if section is valid (no exceptions please)
|
||||
virtual bool onSection(char type[4], u8 data[], u32 len) = 0;
|
||||
};
|
||||
|
||||
|
||||
class PNGTokenizer : public PNGSkeletonTokenizer
|
||||
{
|
||||
protected:
|
||||
z_stream zstream;
|
||||
u8 *obuf;
|
||||
u32 olen;
|
||||
int lastZlibResult;
|
||||
|
||||
bool requirePOTS;
|
||||
|
||||
PNG_IHDR header;
|
||||
u16 bpp;
|
||||
u32 palette[256];
|
||||
u8 trans_red, trans_green, trans_blue;
|
||||
|
||||
void rasterizeImage(u8 *image);
|
||||
|
||||
public:
|
||||
PNGTokenizer(const string &path, bool requirePOTS);
|
||||
virtual ~PNGTokenizer();
|
||||
|
||||
protected:
|
||||
bool onSection(char type[4], u8 data[], u32 len);
|
||||
|
||||
protected:
|
||||
// Rasterized image in R8G8B8A8 format, new dimensions are powers of two
|
||||
virtual void onImage(u32 *image, u32 newWidth, u32 newHeight);
|
||||
|
||||
protected:
|
||||
// Important sections
|
||||
void onIHDR(PNG_IHDR *infohdr);
|
||||
void onPLTE(PNG_PLTE *c_palette);
|
||||
void onIDAT(u8 *data, u32 len);
|
||||
void onIEND();
|
||||
|
||||
// Transparency info
|
||||
void onTRNS_Color2(u16 red, u16 green, u16 blue);
|
||||
void onTRNS_Color3(u8 trans[256], u16 len);
|
||||
|
||||
// Color space information (all unimplemented)
|
||||
void onGAMA();
|
||||
void onCHRM();
|
||||
void onSRGB();
|
||||
void onICCP();
|
||||
|
||||
// Textual information (all unimplemented)
|
||||
void onTEXT();
|
||||
void onZTXT();
|
||||
void onITXT();
|
||||
|
||||
// Other non-essential info (all unimplemented)
|
||||
void onBKGD();
|
||||
void onPHYS();
|
||||
void onSBIT();
|
||||
void onSPLT();
|
||||
void onHIST();
|
||||
void onTIME();
|
||||
};
|
||||
|
||||
|
||||
} // namespace cat
|
||||
|
||||
#endif // LOAD_PNG_HPP
|
||||
186
DependentExtensions/cat/gfx/Matrix.hpp
Normal file
186
DependentExtensions/cat/gfx/Matrix.hpp
Normal file
@ -0,0 +1,186 @@
|
||||
/*
|
||||
Copyright (c) 2009 Christopher A. Taylor. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of LibCat nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef CAT_MATRIX_HPP
|
||||
#define CAT_MATRIX_HPP
|
||||
|
||||
#include <cat/gfx/Vector.hpp>
|
||||
|
||||
namespace cat {
|
||||
|
||||
#define FOR_EACH_ELEMENT(index) for (int index = 0; index < ELEMENTS; ++index)
|
||||
|
||||
|
||||
/*
|
||||
4x4 matrix elements arranged column major (row, column):
|
||||
|
||||
m[0] m[4] m[8] m[12]
|
||||
m[1] m[5] m[9] m[13]
|
||||
m[2] m[6] m[10] m[14]
|
||||
m[3] m[7] m[11] m[15]
|
||||
|
||||
Matrix element order corresponds to OpenGL matrix ordering s.t. in a
|
||||
4x4 matrix the elements define the following new coordinate system:
|
||||
|
||||
new x-axis vector: { m[0] m[1] m[2] }
|
||||
new y-axis vector: { m[4] m[5] m[6] }
|
||||
new z-axis vector: { m[7] m[9] m[10] }
|
||||
new origin: { m[12] m[13] m[14] }
|
||||
*/
|
||||
|
||||
template<int ROWS, int COLS, class Scalar> class Matrix
|
||||
{
|
||||
protected:
|
||||
static const int ELEMENTS = ROWS * COLS;
|
||||
Scalar _elements[ROWS * COLS];
|
||||
|
||||
public:
|
||||
// Short-hand for the current matrix type
|
||||
typedef Matrix<ROWS, COLS, Scalar> mytype;
|
||||
|
||||
// Default constructor does not initialize elements
|
||||
Matrix()
|
||||
{
|
||||
}
|
||||
|
||||
// Copy constructor
|
||||
Matrix(const mytype &u)
|
||||
{
|
||||
memcpy(_elements, u._elements, sizeof(_elements));
|
||||
}
|
||||
|
||||
// Assignment operator
|
||||
mytype &operator=(const mytype &u)
|
||||
{
|
||||
memcpy(_elements, u._elements, sizeof(_elements));
|
||||
}
|
||||
|
||||
// Load zero matrix
|
||||
void loadZero()
|
||||
{
|
||||
OBJCLR(_elements);
|
||||
}
|
||||
|
||||
// Load identity matrix
|
||||
void loadIdentity()
|
||||
{
|
||||
OBJCLR(_elements);
|
||||
|
||||
// Write a 1 along the diagonal
|
||||
for (int ii = 0; ii < ROWS && ii < COLS; ++ii)
|
||||
{
|
||||
_elements[ii * ROWS + ii] = static_cast<Scalar>( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
// Addition in-place
|
||||
mytype &operator+=(const mytype &u)
|
||||
{
|
||||
FOR_EACH_ELEMENT(ii) _elements[ii] += u._elements[ii];
|
||||
}
|
||||
|
||||
// Subtraction in-place
|
||||
mytype &operator-=(const mytype &u)
|
||||
{
|
||||
FOR_EACH_ELEMENT(ii) _elements[ii] -= u._elements[ii];
|
||||
}
|
||||
|
||||
// Multiplication by scalar in-place
|
||||
mytype &operator*=(Scalar u)
|
||||
{
|
||||
FOR_EACH_ELEMENT(ii) _elements[ii] *= u;
|
||||
}
|
||||
|
||||
// Division by scalar in-place
|
||||
mytype &operator/=(Scalar u)
|
||||
{
|
||||
FOR_EACH_ELEMENT(ii) _elements[ii] /= u;
|
||||
}
|
||||
|
||||
// Matrix multiplication
|
||||
template<int OTHER_COLS>
|
||||
Matrix<ROWS, OTHER_COLS, Scalar> operator*(const Matrix<COLS, OTHER_COLS, Scalar> &u)
|
||||
{
|
||||
Matrix<ROWS, OTHER_COLS, Scalar> result;
|
||||
|
||||
// For each row of the matrix product,
|
||||
for (int r = 0; r < ROWS; ++r)
|
||||
{
|
||||
// For each column of the matrix product,
|
||||
for (int c = 0; c < OTHER_COLS; ++c)
|
||||
{
|
||||
Scalar x = static_cast<Scalar>( 0 );
|
||||
|
||||
// For each row of the right operand (u),
|
||||
for (int ii = 0; ii < COLS; ++ii)
|
||||
{
|
||||
// Accumulate sum of products
|
||||
x += (*this)(r, ii) * u(ii, c);
|
||||
}
|
||||
|
||||
// Write the sum
|
||||
result(r, c) = x;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Accessors
|
||||
inline Scalar &operator()(int ii) { return _elements[ii]; }
|
||||
inline const Scalar &operator()(int ii) const { return _elements[ii]; }
|
||||
|
||||
inline Scalar &operator()(int row, int col) { return _elements[col * ROWS + row]; }
|
||||
inline const Scalar &operator()(int row, int col) const { return _elements[col * ROWS + row]; }
|
||||
};
|
||||
|
||||
|
||||
// Short-hand for common usages:
|
||||
|
||||
typedef Matrix<2, 2, u32> Matrix2x2u;
|
||||
typedef Matrix<3, 3, u32> Matrix3x3u;
|
||||
typedef Matrix<4, 4, u32> Matrix4x4u;
|
||||
|
||||
typedef Matrix<2, 2, s32> Matrix2x2i;
|
||||
typedef Matrix<3, 3, s32> Matrix3x3i;
|
||||
typedef Matrix<4, 4, s32> Matrix4x4i;
|
||||
|
||||
typedef Matrix<2, 2, f32> Matrix2x2f;
|
||||
typedef Matrix<3, 3, f32> Matrix3x3f;
|
||||
typedef Matrix<4, 4, f32> Matrix4x4f;
|
||||
|
||||
typedef Matrix<2, 2, f64> Matrix2x2d;
|
||||
typedef Matrix<3, 3, f64> Matrix3x3d;
|
||||
typedef Matrix<4, 4, f64> Matrix4x4d;
|
||||
|
||||
|
||||
#undef FOR_EACH_ELEMENT
|
||||
|
||||
} // namespace cat
|
||||
|
||||
#endif // CAT_MATRIX_HPP
|
||||
401
DependentExtensions/cat/gfx/Quaternion.hpp
Normal file
401
DependentExtensions/cat/gfx/Quaternion.hpp
Normal file
@ -0,0 +1,401 @@
|
||||
/*
|
||||
Copyright (c) 2009 Christopher A. Taylor. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of LibCat nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
Based on code from "Physics for Game Developers", David M. Bourg
|
||||
|
||||
slerp() code adapted from this website:
|
||||
http://www.number-none.com/product/Understanding%20Slerp,%20Then%20Not%20Using%20It/index.html
|
||||
*/
|
||||
|
||||
#ifndef CAT_QUATERNION_HPP
|
||||
#define CAT_QUATERNION_HPP
|
||||
|
||||
#include <cat/gfx/Vector.hpp>
|
||||
#include <cat/gfx/Matrix.hpp>
|
||||
|
||||
namespace cat {
|
||||
|
||||
|
||||
// Generic quaternion class for linear algebra
|
||||
template <typename Scalar, typename Double>
|
||||
class Quaternion
|
||||
{
|
||||
protected:
|
||||
// Backed by a 4D vector with elements arranged as <x,y,z,w>
|
||||
Vector<4, Scalar, Double> _v;
|
||||
|
||||
public:
|
||||
// Short-hand for the current quaternion type
|
||||
typedef Quaternion<Scalar, Double> mytype;
|
||||
|
||||
// Short-hand for the vector type
|
||||
typedef Vector<3, Scalar, Double> vectype;
|
||||
|
||||
// Uninitialized quaternion is not cleared
|
||||
Quaternion() { }
|
||||
|
||||
// Copy constructor
|
||||
Quaternion(const mytype &u)
|
||||
: _v(u._v)
|
||||
{
|
||||
}
|
||||
|
||||
// Initialization constructor
|
||||
Quaternion(const vectype &v, Scalar w)
|
||||
: _v(v)
|
||||
{
|
||||
}
|
||||
|
||||
// Initialization constructor
|
||||
Quaternion(Scalar x, Scalar y, Scalar z, Scalar w)
|
||||
: _v(x, y, z, w)
|
||||
{
|
||||
}
|
||||
|
||||
// Assignment operator
|
||||
mytype &operator=(const mytype &u)
|
||||
{
|
||||
_v.copy(u._v);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Convert from Euler angle representation
|
||||
// Pre-condition: angles in radians (see Deg2Rad in Scalar.hpp)
|
||||
void setFromEulerAngles(f32 xroll, f32 ypitch, f32 zyaw)
|
||||
{
|
||||
f64 croll = cos(0.5f * xroll);
|
||||
f64 cpitch = cos(0.5f * ypitch);
|
||||
f64 cyaw = cos(0.5f * zyaw);
|
||||
f64 sroll = sin(0.5f * xroll);
|
||||
f64 spitch = sin(0.5f * ypitch);
|
||||
f64 syaw = sin(0.5f * zyaw);
|
||||
|
||||
f64 cyawcpitch = cyaw * cpitch;
|
||||
f64 syawspitch = syaw * spitch;
|
||||
f64 cyawspitch = cyaw * spitch;
|
||||
f64 syawcpitch = syaw * cpitch;
|
||||
|
||||
_v(0) = static_cast<Scalar>( cyawcpitch * sroll - syawspitch * croll );
|
||||
_v(1) = static_cast<Scalar>( cyawspitch * croll + syawcpitch * sroll );
|
||||
_v(2) = static_cast<Scalar>( syawcpitch * croll - cyawspitch * sroll );
|
||||
_v(3) = static_cast<Scalar>( cyawcpitch * croll + syawspitch * sroll );
|
||||
|
||||
_v.normalize();
|
||||
}
|
||||
|
||||
// Convert from axis-angle representation
|
||||
// Pre-condition: axis must be unit-length
|
||||
void setFromAxisAngle(const vectype &axis, f32 angle)
|
||||
{
|
||||
angle *= 0.5f;
|
||||
|
||||
Scalar theta = static_cast<Scalar>( sin(angle) );
|
||||
|
||||
_v(0) = theta * axis(0);
|
||||
_v(1) = theta * axis(1);
|
||||
_v(2) = theta * axis(2);
|
||||
_v(3) = static_cast<Scalar>( cos(angle) );
|
||||
}
|
||||
|
||||
// Conjugate
|
||||
mytype operator~() const
|
||||
{
|
||||
return mytype(-_v(0), -_v(1), -_v(2), _v(3));
|
||||
}
|
||||
|
||||
// Conjugate in-place
|
||||
mytype &conjugate() const
|
||||
{
|
||||
_v(0) = -_v(0);
|
||||
_v(1) = -_v(1);
|
||||
_v(2) = -_v(2);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Multiply by quaternion
|
||||
mytype operator*(const mytype &u)
|
||||
{
|
||||
// Cache each of the elements since each is used 4 times
|
||||
Double x1 = _v(0), x2 = u._v(0);
|
||||
Double y1 = _v(1), y2 = u._v(1);
|
||||
Double z1 = _v(2), z2 = u._v(2);
|
||||
Double w1 = _v(3), w2 = u._v(3);
|
||||
|
||||
// Quaternion multiplication formula:
|
||||
Scalar x3 = static_cast<Scalar>( w1*x2 + x1*w2 + y1*z2 - z1*y2 );
|
||||
Scalar y3 = static_cast<Scalar>( w1*y2 - x1*z2 + y1*w2 + z1*x2 );
|
||||
Scalar z3 = static_cast<Scalar>( w1*z2 + x1*y2 - y1*x2 + z1*w2 );
|
||||
Scalar w3 = static_cast<Scalar>( w1*w2 - x1*x2 - y1*y2 - z1*z2 );
|
||||
|
||||
return mytype(x3, y3, z3, w3);
|
||||
}
|
||||
|
||||
// Multiply by quaternion in-place: this = this * u
|
||||
mytype &operator*=(const mytype &u)
|
||||
{
|
||||
// Cache each of the elements since each is used 4 times
|
||||
Double x1 = _v(0), x2 = u._v(0);
|
||||
Double y1 = _v(1), y2 = u._v(1);
|
||||
Double z1 = _v(2), z2 = u._v(2);
|
||||
Double w1 = _v(3), w2 = u._v(3);
|
||||
|
||||
// Quaternion multiplication formula:
|
||||
_v(0) = static_cast<Scalar>( w1*x2 + x1*w2 + y1*z2 - z1*y2 );
|
||||
_v(1) = static_cast<Scalar>( w1*y2 - x1*z2 + y1*w2 + z1*x2 );
|
||||
_v(2) = static_cast<Scalar>( w1*z2 + x1*y2 - y1*x2 + z1*w2 );
|
||||
_v(3) = static_cast<Scalar>( w1*w2 - x1*x2 - y1*y2 - z1*z2 );
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Multiply by quaternion in-place: this = u * this
|
||||
mytype &postMultiply(const mytype &u)
|
||||
{
|
||||
// Cache each of the elements since each is used 4 times
|
||||
Double x2 = _v(0), x1 = u._v(0);
|
||||
Double y2 = _v(1), y1 = u._v(1);
|
||||
Double z2 = _v(2), z1 = u._v(2);
|
||||
Double w2 = _v(3), w1 = u._v(3);
|
||||
|
||||
// Quaternion multiplication formula:
|
||||
_v(0) = static_cast<Scalar>( w1*x2 + x1*w2 + y1*z2 - z1*y2 );
|
||||
_v(1) = static_cast<Scalar>( w1*y2 - x1*z2 + y1*w2 + z1*x2 );
|
||||
_v(2) = static_cast<Scalar>( w1*z2 + x1*y2 - y1*x2 + z1*w2 );
|
||||
_v(3) = static_cast<Scalar>( w1*w2 - x1*x2 - y1*y2 - z1*z2 );
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Rotate given vector in-place
|
||||
void rotate(vectype &u)
|
||||
{
|
||||
// Implements the simple formula: (q1 * u2 * ~q1).getVector()
|
||||
|
||||
// Cache each of the elements since each is used 4 times
|
||||
Double x1 = _v(0), x2 = u(0);
|
||||
Double y1 = _v(1), y2 = u(1);
|
||||
Double z1 = _v(2), z2 = u(2);
|
||||
Double w1 = _v(3);
|
||||
|
||||
// Quaternion-vector multiplication formula (q3 = q1 * u2):
|
||||
Double x3 = w1*x2 + y1*z2 - z1*y2;
|
||||
Double y3 = w1*y2 - x1*z2 + z1*x2;
|
||||
Double z3 = w1*z2 + x1*y2 - y1*x2;
|
||||
Double w3 = -(x1*x2 + y1*y2 + z1*z2);
|
||||
|
||||
// Quaternion multiplication formula (q2' = q3 * ~q1):
|
||||
u(0) = static_cast<Scalar>( w1*x3 - x1*w3 + y1*z3 - z1*y3 );
|
||||
u(1) = static_cast<Scalar>( w1*y3 - x1*z3 - y1*w3 + z1*x3 );
|
||||
u(2) = static_cast<Scalar>( w1*z3 + x1*y3 - y1*x3 - z1*w3 );
|
||||
}
|
||||
|
||||
// NLERP: Very fast, non-constant velocity and torque-minimal
|
||||
// Precondition: q1, q2 are unit length
|
||||
friend void nlerp(const mytype &q1, const mytype &q2, Scalar t, mytype &result)
|
||||
{
|
||||
// Linearly interpolate and normalize result
|
||||
// This formula is a little more work than "q1 + (q2 - q1) * t"
|
||||
// but less likely to lose precision when it matters
|
||||
|
||||
// Cosine of phi, the angle between the two vectors
|
||||
Double cos_phi = q1._v.dotProduct(q2._v);
|
||||
|
||||
// I have read this may try to rotate around the "long way" sometimes and to
|
||||
// fix that we check if cos(phi) is negative and invert one of the inputs.
|
||||
if (cos_phi < 0.0)
|
||||
{
|
||||
result._v = -q1._v;
|
||||
}
|
||||
else
|
||||
{
|
||||
result._v = q1._v;
|
||||
}
|
||||
|
||||
// Simple linear interpolation
|
||||
Scalar scale0 = static_cast<Scalar>(1) - t;
|
||||
Scalar scale1 = t;
|
||||
|
||||
result._v *= scale0;
|
||||
result._v += q2._v * scale1;
|
||||
result._v.normalize();
|
||||
}
|
||||
|
||||
// SLERP: Slower, constant velocity and torque-minimal
|
||||
// Precondition: q1, q2 are unit length
|
||||
friend void slerp(const mytype &q1, const mytype &q2, Scalar t, mytype &result)
|
||||
{
|
||||
// Cosine of phi, the angle between the two vectors
|
||||
Double cos_phi = q1._v.dotProduct(q2._v);
|
||||
|
||||
// I have read this may try to rotate around the "long way" sometimes and to
|
||||
// fix that we check if cos(phi) is negative and invert one of the inputs.
|
||||
if (cos_phi < 0.0)
|
||||
{
|
||||
cos_phi = -cos_phi;
|
||||
result._v = -q1._v;
|
||||
}
|
||||
else
|
||||
{
|
||||
result._v = q1._v;
|
||||
}
|
||||
|
||||
// Default to simple linear interpolation
|
||||
Scalar scale0 = static_cast<Scalar>(1) - t;
|
||||
Scalar scale1 = t;
|
||||
|
||||
// If the distance is not small we need to do full slerp:
|
||||
if (cos_phi < 0.9995)
|
||||
{
|
||||
// cos_phi is guaranteed to be within the domain of acos(), 0..1
|
||||
Double phi = static_cast<Double>( acos(cos_phi) );
|
||||
Double inv_sin_phi = static_cast<Double>(1) / sin(phi);
|
||||
|
||||
scale0 = static_cast<Scalar>( sin(scale0 * phi) * inv_sin_phi );
|
||||
scale1 = static_cast<Scalar>( sin(scale1 * phi) * inv_sin_phi );
|
||||
}
|
||||
|
||||
result._v *= scale0;
|
||||
result._v += q2._v * scale1;
|
||||
result._v.normalize();
|
||||
}
|
||||
|
||||
// Get angle of rotation
|
||||
Scalar getAngle()
|
||||
{
|
||||
return static_cast<Scalar>( 2 ) * static_cast<Scalar>( acos(_v(3)) );
|
||||
}
|
||||
|
||||
// Get axis of rotation
|
||||
vectype getAxis()
|
||||
{
|
||||
return vectype(_v(0), _v(1), _v(2)).normalize();
|
||||
}
|
||||
|
||||
// Get matrix form of the rotation represented by this quaternion
|
||||
void getMatrix4x4(Matrix<4, 4, Scalar> &result)
|
||||
{
|
||||
Double dx = _v(0);
|
||||
Double dy = _v(1);
|
||||
Double dz = _v(2);
|
||||
Double dw = _v(3);
|
||||
|
||||
Double x2 = dx * dx;
|
||||
Double y2 = dy * dy;
|
||||
Double z2 = dz * dz;
|
||||
Double xy = dx * dy;
|
||||
Double yz = dy * dz;
|
||||
Double zx = dz * dx;
|
||||
Double xw = dx * dw;
|
||||
Double yw = dy * dw;
|
||||
Double zw = dz * dw;
|
||||
|
||||
const Double ONE = static_cast<Double>( 1 );
|
||||
const Double TWO = static_cast<Double>( 2 );
|
||||
|
||||
// Result is written in OpenGL column-major matrix order:
|
||||
result( 0) = static_cast<Scalar>( ONE - TWO * (y2 + z2) );
|
||||
result( 1) = static_cast<Scalar>( TWO * (xy - zw) );
|
||||
result( 2) = static_cast<Scalar>( TWO * (zx + yw) );
|
||||
result( 3) = static_cast<Scalar>( 0 );
|
||||
|
||||
result( 4) = static_cast<Scalar>( TWO * (xy + zw) );
|
||||
result( 5) = static_cast<Scalar>( ONE - TWO * (x2 + z2) );
|
||||
result( 6) = static_cast<Scalar>( TWO * (yz - xw) );
|
||||
result( 7) = static_cast<Scalar>( 0 );
|
||||
|
||||
result( 8) = static_cast<Scalar>( TWO * (zx - yw) );
|
||||
result( 9) = static_cast<Scalar>( TWO * (yz + xw) );
|
||||
result(10) = static_cast<Scalar>( ONE - TWO * (x2 + y2) );
|
||||
result(11) = static_cast<Scalar>( 0 );
|
||||
|
||||
result(12) = static_cast<Scalar>( 0 );
|
||||
result(13) = static_cast<Scalar>( 0 );
|
||||
result(14) = static_cast<Scalar>( 0 );
|
||||
result(15) = static_cast<Scalar>( ONE );
|
||||
}
|
||||
|
||||
// Get Euler angles
|
||||
vectype Quaternion::getEulerAngles()
|
||||
{
|
||||
Double dx = _v(0);
|
||||
Double dy = _v(1);
|
||||
Double dz = _v(2);
|
||||
Double dw = _v(3);
|
||||
|
||||
Double x2 = dx * dx;
|
||||
Double y2 = dy * dy;
|
||||
Double z2 = dz * dz;
|
||||
Double w2 = dw * dw;
|
||||
Double xy = dx * dy;
|
||||
Double yz = dy * dz;
|
||||
Double xw = dx * dw;
|
||||
Double yw = dy * dw;
|
||||
Double zw = dz * dw;
|
||||
|
||||
const Double TWO = static_cast<Double>( 2 );
|
||||
|
||||
Double r11 = w2 + x2 - y2 - z2;
|
||||
Double r21 = TWO * (xy + zw);
|
||||
Double r31 = TWO * (xy - yw);
|
||||
Double r32 = TWO * (yz + xw);
|
||||
Double r33 = w2 - x2 - y2 + z2;
|
||||
|
||||
Double tmp = fabs(r31);
|
||||
const Double LIMIT = static_cast<Double>( 0.999999 );
|
||||
|
||||
if (tmp > LIMIT)
|
||||
{
|
||||
Double xz = dx * dz;
|
||||
|
||||
Double r12 = TWO * (yz - zw);
|
||||
Double r13 = TWO * (xz + yw);
|
||||
|
||||
return vectype(static_cast<Scalar>( 0 ),
|
||||
static_cast<Scalar>( -CAT_HALF_PI_64 * r31 / tmp ),
|
||||
static_cast<Scalar>( atan2(-r12, -r31 * r13) ));
|
||||
}
|
||||
|
||||
return vectype(static_cast<Scalar>( atan2(r32, r33) ),
|
||||
static_cast<Scalar>( asin(-r31) ),
|
||||
static_cast<Scalar>( atan2(r21, r11) ));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Short-hand for common usages:
|
||||
|
||||
typedef Quaternion<f32, f64> Quaternion4f;
|
||||
typedef Quaternion<f64, f64> Quaternion4d;
|
||||
|
||||
|
||||
} // namespace cat
|
||||
|
||||
#endif // CAT_QUATERNION_HPP
|
||||
85
DependentExtensions/cat/gfx/Scalar.hpp
Normal file
85
DependentExtensions/cat/gfx/Scalar.hpp
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
Copyright (c) 2009 Christopher A. Taylor. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of LibCat nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef CAT_SCALAR_HPP
|
||||
#define CAT_SCALAR_HPP
|
||||
|
||||
#include <cat/Platform.hpp>
|
||||
#include <cmath>
|
||||
|
||||
namespace cat {
|
||||
|
||||
|
||||
// PI
|
||||
#define CAT_TWO_PI_64 6.283185307179586476925286766559
|
||||
#define CAT_TWO_PI_32 6.28318531f
|
||||
#define CAT_PI_64 3.1415926535897932384626433832795
|
||||
#define CAT_PI_32 3.14159265f
|
||||
#define CAT_HALF_PI_64 1.5707963267948966192313216916398
|
||||
#define CAT_HALF_PI_32 1.5707963268f
|
||||
#define CAT_QUARTER_PI_64 0.78539816339744830961566084581988
|
||||
#define CAT_QUARTER_PI_32 0.7853981634f
|
||||
#define CAT_INV_PI_64 0.31830988618379067153776752674503
|
||||
#define CAT_INV_PI_32 0.3183098862f
|
||||
|
||||
|
||||
// Angle conversion
|
||||
inline f64 Deg2Rad(f64 angle)
|
||||
{
|
||||
return angle * CAT_TWO_PI_64 / 360.0;
|
||||
}
|
||||
inline f32 Deg2Rad(f32 angle)
|
||||
{
|
||||
return angle * CAT_TWO_PI_32 / 360.0f;
|
||||
}
|
||||
inline f64 Rad2Deg(f64 angle)
|
||||
{
|
||||
return angle * 360.0 / CAT_TWO_PI_64;
|
||||
}
|
||||
inline f32 Rad2Deg(f32 angle)
|
||||
{
|
||||
return angle * 360.0f / CAT_TWO_PI_32;
|
||||
}
|
||||
|
||||
|
||||
// Generic clamp() function
|
||||
template<class Scalar>
|
||||
void Clamp(Scalar &x, Scalar low, Scalar high)
|
||||
{
|
||||
if (x < low) x = low;
|
||||
else if (x > high) x = high;
|
||||
}
|
||||
|
||||
|
||||
// Fast inverse square root
|
||||
f32 InvSqrt(f32 x);
|
||||
|
||||
|
||||
} // namespace cat
|
||||
|
||||
#endif // CAT_SCALAR_HPP
|
||||
389
DependentExtensions/cat/gfx/Vector.hpp
Normal file
389
DependentExtensions/cat/gfx/Vector.hpp
Normal file
@ -0,0 +1,389 @@
|
||||
/*
|
||||
Copyright (c) 2009 Christopher A. Taylor. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of LibCat nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef CAT_VECTOR_HPP
|
||||
#define CAT_VECTOR_HPP
|
||||
|
||||
#include <cat/gfx/Scalar.hpp>
|
||||
|
||||
namespace cat {
|
||||
|
||||
#define FOR_EACH_DIMENSION(index) for (int index = 0; index < DIM; ++index)
|
||||
|
||||
|
||||
// Generic vector class for linear algebra
|
||||
template<int DIM, typename Scalar, typename Double> class Vector
|
||||
{
|
||||
protected:
|
||||
// Protected internal storage of vector components
|
||||
Scalar _elements[DIM];
|
||||
|
||||
public:
|
||||
// Short-hand for the current vector type
|
||||
typedef Vector<DIM, Scalar, Double> mytype;
|
||||
|
||||
// Uninitialized vector is not cleared
|
||||
Vector() {}
|
||||
|
||||
// Component-wise initializing constructors
|
||||
Vector(Scalar x, Scalar y)
|
||||
{
|
||||
_elements[0] = x;
|
||||
_elements[1] = y;
|
||||
}
|
||||
Vector(Scalar x, Scalar y, Scalar z)
|
||||
{
|
||||
_elements[0] = x;
|
||||
_elements[1] = y;
|
||||
_elements[2] = z;
|
||||
}
|
||||
Vector(Scalar x, Scalar y, Scalar z, Scalar w)
|
||||
{
|
||||
_elements[0] = x;
|
||||
_elements[1] = y;
|
||||
_elements[2] = z;
|
||||
_elements[3] = w;
|
||||
}
|
||||
|
||||
// Make the vector a copy of a given vector
|
||||
mytype ©(const mytype &u)
|
||||
{
|
||||
memcpy(_elements, u._elements, sizeof(_elements));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Copy constructor
|
||||
Vector(const mytype &u)
|
||||
{
|
||||
copy(u);
|
||||
}
|
||||
|
||||
// Assignment operator
|
||||
mytype &operator=(const mytype &u)
|
||||
{
|
||||
return copy(u);
|
||||
}
|
||||
|
||||
// Magnitude calculation
|
||||
Double magnitude() const
|
||||
{
|
||||
Double element, sum = 0;
|
||||
|
||||
FOR_EACH_DIMENSION(ii)
|
||||
{
|
||||
element = _elements[ii];
|
||||
sum += element * element;
|
||||
}
|
||||
|
||||
return static_cast<Double>( sqrt(sum) );
|
||||
}
|
||||
|
||||
// Fast normalization for 32-bit floating point elements in-place
|
||||
mytype &normalize_fast_f32()
|
||||
{
|
||||
f32 element = _elements[0];
|
||||
f32 sum = element * element;
|
||||
|
||||
for (int ii = 1; ii < DIM; ++ii)
|
||||
{
|
||||
element = _elements[ii];
|
||||
sum += element * element;
|
||||
}
|
||||
|
||||
// If sum is not close to 1, then perform normalization:
|
||||
if (sum > 1.005f || sum < 0.995f)
|
||||
{
|
||||
f32 inv = InvSqrt(sum);
|
||||
|
||||
FOR_EACH_DIMENSION(ii) _elements[ii] *= inv;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Normalization in-place
|
||||
mytype &normalize()
|
||||
{
|
||||
Double m = magnitude();
|
||||
Double inv = static_cast<Double>( 1 ) / m;
|
||||
|
||||
FOR_EACH_DIMENSION(ii) _elements[ii] *= inv;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Zero elements
|
||||
void zero()
|
||||
{
|
||||
OBJCLR(_elements);
|
||||
}
|
||||
|
||||
// Is zero?
|
||||
bool isZero()
|
||||
{
|
||||
FOR_EACH_DIMENSION(ii)
|
||||
if (_elements[ii] != static_cast<Scalar>( 0 ))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// For consistency with Matrix class, use the () operator instead of [] to index it
|
||||
inline Scalar &operator()(int ii) { return _elements[ii]; }
|
||||
inline Scalar &x() { return _elements[0]; }
|
||||
inline Scalar &y() { return _elements[1]; }
|
||||
inline Scalar &z() { return _elements[2]; }
|
||||
inline Scalar &w() { return _elements[3]; }
|
||||
|
||||
// Const version for accessors
|
||||
inline const Scalar &operator()(int ii) const { return _elements[ii]; }
|
||||
inline const Scalar &x() const { return _elements[0]; }
|
||||
inline const Scalar &y() const { return _elements[1]; }
|
||||
inline const Scalar &z() const { return _elements[2]; }
|
||||
inline const Scalar &w() const { return _elements[3]; }
|
||||
|
||||
// Negation
|
||||
mytype operator-() const
|
||||
{
|
||||
mytype x;
|
||||
|
||||
FOR_EACH_DIMENSION(ii) x._elements[ii] = -_elements[ii];
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
// Negation in-place
|
||||
mytype &negate()
|
||||
{
|
||||
FOR_EACH_DIMENSION(ii) _elements[ii] = -_elements[ii];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Addition
|
||||
mytype operator+(const mytype &u) const
|
||||
{
|
||||
mytype x;
|
||||
|
||||
FOR_EACH_DIMENSION(ii) x._elements[ii] = _elements[ii] + u._elements[ii];
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
// Addition in-place
|
||||
mytype &operator+=(const mytype &u)
|
||||
{
|
||||
FOR_EACH_DIMENSION(ii) _elements[ii] += u._elements[ii];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Add a scalar to each element in-place
|
||||
mytype &addToEachElement(Scalar u)
|
||||
{
|
||||
FOR_EACH_DIMENSION(ii) _elements[ii] += u;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Subtraction
|
||||
mytype operator-(const mytype &u) const
|
||||
{
|
||||
mytype x;
|
||||
|
||||
FOR_EACH_DIMENSION(ii) x._elements[ii] = _elements[ii] - u._elements[ii];
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
// Subtraction in-place
|
||||
mytype &operator-=(const mytype &u)
|
||||
{
|
||||
FOR_EACH_DIMENSION(ii) _elements[ii] -= u._elements[ii];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Subtract a scalar from each element in-place
|
||||
mytype &subtractFromEachElement(Scalar u)
|
||||
{
|
||||
FOR_EACH_DIMENSION(ii) _elements[ii] -= u;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Scalar multiplication
|
||||
mytype operator*(Scalar u) const
|
||||
{
|
||||
mytype x;
|
||||
|
||||
FOR_EACH_DIMENSION(ii) x._elements[ii] = u * _elements[ii];
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
// Scalar multiplication in-place
|
||||
mytype &operator*=(Scalar u)
|
||||
{
|
||||
FOR_EACH_DIMENSION(ii) _elements[ii] *= u;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Component-wise multiply in-place
|
||||
mytype &componentMultiply(const mytype &u)
|
||||
{
|
||||
FOR_EACH_DIMENSION(ii) _elements[ii] *= u._elements[ii];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Scalar division
|
||||
mytype operator/(Scalar u) const
|
||||
{
|
||||
mytype x;
|
||||
|
||||
Scalar inv_u = static_cast<Scalar>( 1 ) / static_cast<Scalar>( u );
|
||||
|
||||
FOR_EACH_DIMENSION(ii) x._elements[ii] = _elements[ii] * inv_u;
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
// Scalar division in-place
|
||||
mytype &operator/=(Scalar u)
|
||||
{
|
||||
Scalar inv_u = static_cast<Scalar>( 1 ) / static_cast<Scalar>( u );
|
||||
|
||||
FOR_EACH_DIMENSION(ii) _elements[ii] *= inv_u;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Component-wise divide in-place
|
||||
mytype &componentDivide(const mytype &u)
|
||||
{
|
||||
FOR_EACH_DIMENSION(ii) _elements[ii] /= u._elements[ii];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Dot product
|
||||
Double dotProduct(const mytype &u) const
|
||||
{
|
||||
Double sum = 0;
|
||||
|
||||
FOR_EACH_DIMENSION(ii)
|
||||
sum += static_cast<Double>( _elements[ii] )
|
||||
* static_cast<Double>( u._elements[ii] );
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
public:
|
||||
// Only for 2-element vectors:
|
||||
|
||||
// Generate a 2D rotation vector in-place
|
||||
void generateRotation2D(f32 angle)
|
||||
{
|
||||
x() = cos(angle);
|
||||
y() = sin(angle);
|
||||
}
|
||||
|
||||
// Add rotation vector in-place
|
||||
mytype &addRotation2D(const mytype &r)
|
||||
{
|
||||
Double ax = x(), ay = y();
|
||||
Double rx = r.x(), ry = r.y();
|
||||
|
||||
x() = static_cast<Scalar>( ax*rx - ay*ry ); // cos(a+r) = cos(a)*cos(r) - sin(a)*sin(r)
|
||||
y() = static_cast<Scalar>( ay*rx + ax*ry ); // sin(a+r) = sin(a)*cos(r) + cos(a)*sin(r)
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Subtract rotation vector in-place
|
||||
mytype &subtractRotation2D(const mytype &r)
|
||||
{
|
||||
Double ax = x(), ay = y();
|
||||
Double rx = r.x(), ry = r.y();
|
||||
|
||||
x() = static_cast<Scalar>( ax*rx + ay*ry ); // cos(a-r) = cos(a)*cos(r) + sin(a)*sin(r)
|
||||
y() = static_cast<Scalar>( ay*rx - ax*ry ); // sin(a-r) = sin(a)*cos(r) - cos(a)*sin(r)
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Cross product: Result is a scalar
|
||||
f32 crossProduct2D(const mytype &u)
|
||||
{
|
||||
return x() * u.y() - y() * u.x();
|
||||
}
|
||||
|
||||
public:
|
||||
// Only for 3-element vectors:
|
||||
|
||||
// Cross product: Result is a 3D vector
|
||||
mytype crossProduct3D(const mytype &u)
|
||||
{
|
||||
mytype result;
|
||||
|
||||
result.x() = y() * u.z() - z() * u.y();
|
||||
result.y() = z() * u.x() - x() * u.z();
|
||||
result.z() = x() * u.y() - y() * u.x();
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Short-hand for common usages:
|
||||
|
||||
typedef Vector<2, u32, u32> Vector2u;
|
||||
typedef Vector<3, u32, u32> Vector3u;
|
||||
typedef Vector<4, u32, u32> Vector4u;
|
||||
|
||||
typedef Vector<2, s32, s32> Vector2s;
|
||||
typedef Vector<3, s32, s32> Vector3s;
|
||||
typedef Vector<4, s32, s32> Vector4s;
|
||||
|
||||
typedef Vector<2, f32, f64> Vector2f;
|
||||
typedef Vector<3, f32, f64> Vector3f;
|
||||
typedef Vector<4, f32, f64> Vector4f;
|
||||
|
||||
typedef Vector<2, f64, f64> Vector2d;
|
||||
typedef Vector<3, f64, f64> Vector3d;
|
||||
typedef Vector<4, f64, f64> Vector4d;
|
||||
|
||||
|
||||
#undef FOR_EACH_DIMENSION
|
||||
|
||||
} // namespace cat
|
||||
|
||||
#endif // CAT_VECTOR_HPP
|
||||
Reference in New Issue
Block a user