fix: some file didn't have the svn:eol-style native yet
This commit is contained in:
@@ -1,35 +1,35 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library Maya Plugin
|
||||
Copyright (c) 2008 Walt Disney Studios
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising
|
||||
from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must
|
||||
not claim that you wrote the original software. If you use this
|
||||
software in a product, an acknowledgment in the product documentation
|
||||
would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must
|
||||
not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
Written by: Nicola Candussi <nicola@fluidinteractive.com>
|
||||
*/
|
||||
|
||||
//base.h
|
||||
|
||||
#ifndef MVL_BASE_H
|
||||
#define MVL_BASE_H
|
||||
|
||||
namespace mvl {
|
||||
|
||||
|
||||
|
||||
} //namespace mvl
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library Maya Plugin
|
||||
Copyright (c) 2008 Walt Disney Studios
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising
|
||||
from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must
|
||||
not claim that you wrote the original software. If you use this
|
||||
software in a product, an acknowledgment in the product documentation
|
||||
would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must
|
||||
not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
Written by: Nicola Candussi <nicola@fluidinteractive.com>
|
||||
*/
|
||||
|
||||
//base.h
|
||||
|
||||
#ifndef MVL_BASE_H
|
||||
#define MVL_BASE_H
|
||||
|
||||
namespace mvl {
|
||||
|
||||
|
||||
|
||||
} //namespace mvl
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,399 +1,399 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library Maya Plugin
|
||||
Copyright (c) 2008 Walt Disney Studios
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising
|
||||
from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must
|
||||
not claim that you wrote the original software. If you use this
|
||||
software in a product, an acknowledgment in the product documentation
|
||||
would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must
|
||||
not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
Written by: Nicola Candussi <nicola@fluidinteractive.com>
|
||||
*/
|
||||
|
||||
//mat.h
|
||||
|
||||
#ifndef MVL_MAT_H
|
||||
#define MVL_MAT_H
|
||||
|
||||
#include <cmath>
|
||||
#include "base.h"
|
||||
#include "traits.h"
|
||||
|
||||
namespace mvl {
|
||||
|
||||
template<typename T, std::size_t R, std::size_t C>
|
||||
class mat
|
||||
{
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T& reference;
|
||||
typedef T const& const_reference;
|
||||
typedef T* iterator;
|
||||
typedef T const* const_iterator;
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
public:
|
||||
enum {
|
||||
Rows = R,
|
||||
Cols = C,
|
||||
Size = Rows * Cols,
|
||||
};
|
||||
|
||||
public:
|
||||
//constructors
|
||||
explicit mat() {}
|
||||
|
||||
template<typename T2>
|
||||
mat(mat<T2, Rows, Cols> const& m)
|
||||
{
|
||||
*this = m;
|
||||
}
|
||||
|
||||
explicit mat(value_type val)
|
||||
{
|
||||
for(int i = 0; i < Size; ++i){
|
||||
m_data[i] = val;
|
||||
}
|
||||
}
|
||||
|
||||
explicit mat(value_type m00, value_type m01,
|
||||
value_type m10, value_type m11)
|
||||
{
|
||||
operator()(0, 0) = m00; operator()(0, 1) = m01;
|
||||
operator()(1, 0) = m10; operator()(1, 1) = m11;
|
||||
}
|
||||
|
||||
explicit mat(value_type m00, value_type m01, value_type m02,
|
||||
value_type m10, value_type m11, value_type m12,
|
||||
value_type m20, value_type m21, value_type m22)
|
||||
{
|
||||
operator()(0, 0) = m00; operator()(0, 1) = m01; operator()(0, 2) = m02;
|
||||
operator()(1, 0) = m10; operator()(1, 1) = m11; operator()(1, 2) = m12;
|
||||
operator()(2, 0) = m20; operator()(2, 1) = m21; operator()(2, 2) = m22;
|
||||
}
|
||||
|
||||
explicit mat(value_type m00, value_type m01, value_type m02, value_type m03,
|
||||
value_type m10, value_type m11, value_type m12, value_type m13,
|
||||
value_type m20, value_type m21, value_type m22, value_type m23,
|
||||
value_type m30, value_type m31, value_type m32, value_type m33)
|
||||
{
|
||||
operator()(0, 0) = m00; operator()(0, 1) = m01; operator()(0, 2) = m02; operator()(0, 3) = m03;
|
||||
operator()(1, 0) = m10; operator()(1, 1) = m11; operator()(1, 2) = m12; operator()(1, 3) = m13;
|
||||
operator()(2, 0) = m20; operator()(2, 1) = m21; operator()(2, 2) = m22; operator()(2, 3) = m23;
|
||||
operator()(3, 0) = m30; operator()(3, 1) = m31; operator()(3, 2) = m32; operator()(3, 3) = m33;
|
||||
}
|
||||
|
||||
public:
|
||||
//data access
|
||||
value_type operator()(std::size_t i, std::size_t j) const { return m_data[j * Rows + i]; }
|
||||
reference operator()(std::size_t i, std::size_t j) { return m_data[j * Rows + i]; }
|
||||
|
||||
public:
|
||||
//stl
|
||||
static std::size_t size() { return Size; }
|
||||
static std::size_t max_size() { return Size; }
|
||||
static bool empty() { return false; }
|
||||
|
||||
iterator begin() { return m_data; }
|
||||
iterator end() { return m_data + Size; }
|
||||
const_iterator begin() const { return m_data; }
|
||||
const_iterator end() const { return m_data + Size; }
|
||||
reverse_iterator rbegin() { return reverse_iterator(end()); }
|
||||
reverse_iterator rend() { return reverse_iterator(begin()); }
|
||||
const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
|
||||
const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
|
||||
|
||||
value_type front() { return m_data[0]; }
|
||||
value_type back() { return m_data[Size - 1]; }
|
||||
const_reference front() const { return m_data[0]; }
|
||||
const_reference back() const { return m_data[Size - 1]; }
|
||||
|
||||
friend std::ostream& operator << (std::ostream& out, mat const& m) {
|
||||
out << "(";
|
||||
for(size_t i = 0; i < Rows - 1; i++) {
|
||||
for(size_t j = 0; j < Cols; j++) {
|
||||
out << m(i, j) << ", ";
|
||||
}
|
||||
out << std::endl;
|
||||
}
|
||||
for(size_t j = 0; j < Cols - 1; j++) {
|
||||
out << m(Rows - 1, j) << ", ";
|
||||
}
|
||||
out << m(Rows - 1, Cols - 1) << ")";
|
||||
return out;
|
||||
}
|
||||
|
||||
public:
|
||||
//
|
||||
mat& operator=(mat const& rhs) {
|
||||
std::copy(rhs.begin(),rhs.end(), begin());
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T2>
|
||||
mat& operator=(mat<T2, Rows, Cols> const& rhs) {
|
||||
std::copy(rhs.begin(),rhs.end(), begin());
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
//data is stored in column major order, so the matrix can passed directly to the graphics APIs
|
||||
T m_data[Size];
|
||||
};
|
||||
|
||||
//assignment operators
|
||||
// OP(mat<T1>, mat<T2>)
|
||||
// OP(mat<T>, T)
|
||||
|
||||
#define MAT_IMPLEMENT_MACRO(OP) \
|
||||
template<typename T1, typename T2, std::size_t R, std::size_t C> \
|
||||
inline \
|
||||
mat<T1, R, C>& \
|
||||
operator OP(mat<T1, R, C>& lhs, mat<T2, R, C> const& rhs) { \
|
||||
for(int i = 0; i < C * R; ++i) { \
|
||||
lhs[i] OP rhs[i]; \
|
||||
} \
|
||||
return lhs; \
|
||||
} \
|
||||
\
|
||||
template<typename T, std::size_t R, std::size_t C> \
|
||||
inline \
|
||||
mat<T, R, C>& \
|
||||
operator OP(mat<T, R, C>& lhs, typename mat<T, R, C>::value_type const& rhs) { \
|
||||
for(int i = 0; i < C * R; ++i) { \
|
||||
lhs[i] OP rhs[i]; \
|
||||
} \
|
||||
return lhs; \
|
||||
} \
|
||||
|
||||
MAT_IMPLEMENT_MACRO(+=)
|
||||
MAT_IMPLEMENT_MACRO(-=)
|
||||
MAT_IMPLEMENT_MACRO(*=)
|
||||
MAT_IMPLEMENT_MACRO(/=)
|
||||
|
||||
#undef MAT_IMPLEMENT_MACRO
|
||||
|
||||
//operator + (mat, mat)
|
||||
template<typename T1, typename T2, std::size_t R, std::size_t C>
|
||||
inline
|
||||
mat<typename promote_traits<T1, T2>::value_type, R, C>
|
||||
operator + (mat<T1, R, C> const& lhs, mat<T2, R, C> const& rhs) {
|
||||
mat<typename promote_traits<T1, T2>::value_type, R, C> res;
|
||||
for(int i = 0; i < R ; ++i) {
|
||||
for(int j = 0; j < C; ++j) {
|
||||
res(i, j) = lhs(i, j) + rhs(i, j);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//operator - (mat, mat)
|
||||
template<typename T1, typename T2, std::size_t R, std::size_t C>
|
||||
inline
|
||||
mat<typename promote_traits<T1, T2>::value_type, R, C>
|
||||
operator - (mat<T1, R, C> const& lhs, mat<T2, R, C> const& rhs) {
|
||||
mat<typename promote_traits<T1, T2>::value_type, R, C> res;
|
||||
for(int i = 0; i < R ; ++i) {
|
||||
for(int j = 0; j < C; ++j) {
|
||||
res(i, j) = lhs(i, j) - rhs(i, j);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//operator * (mat, POD)
|
||||
template<typename T1, typename T2, std::size_t R, std::size_t C>
|
||||
inline
|
||||
mat<typename promote_traits<T1, T2>::value_type, R, C>
|
||||
operator * (mat<T1, R, C> const& lhs, T2 const& rhs) {
|
||||
mat<typename promote_traits<T1, T2>::value_type, R, C> res;
|
||||
for(int i = 0; i < R ; ++i) {
|
||||
for(int j = 0; j < C; ++j) {
|
||||
res(i, j) = lhs(i, j) * rhs;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//operator * (POD, mat)
|
||||
template<typename T1, typename T2, std::size_t R, std::size_t C>
|
||||
inline
|
||||
mat<typename promote_traits<T1, T2>::value_type, R, C>
|
||||
operator * (T1 const& lhs, mat<T2, R, C> const& rhs) {
|
||||
mat<typename promote_traits<T1, T2>::value_type, R, C> res;
|
||||
for(int i = 0; i < R ; ++i) {
|
||||
for(int j = 0; j < C; ++j) {
|
||||
res(i, j) = lhs * rhs(i, j);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//operator / (mat, POD)
|
||||
template<typename T1, typename T2, std::size_t R, std::size_t C>
|
||||
inline
|
||||
mat<typename promote_traits<T1, T2>::value_type, R, C>
|
||||
operator / (mat<T1, R, C> const& lhs, T2 const& rhs) {
|
||||
mat<typename promote_traits<T1, T2>::value_type, R, C> res;
|
||||
for(int i = 0; i < R ; ++i) {
|
||||
for(int j = 0; j < C; ++j) {
|
||||
res(i, j) = lhs(i, j) / rhs;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//element_prod(mat, mat)
|
||||
template<typename T1, typename T2, std::size_t R, std::size_t C>
|
||||
inline
|
||||
mat<typename promote_traits<T1, T2>::value_type, R, C>
|
||||
element_prod(mat<T1, R, C> const& lhs, mat<T2, R, C> const& rhs) {
|
||||
mat<typename promote_traits<T1, T2>::value_type, R, C> res;
|
||||
for(int i = 0; i < R ; ++i) {
|
||||
for(int j = 0; j < C; ++j) {
|
||||
res(i, j) = lhs(i, j) * rhs(i, j);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//element_div(mat, mat)
|
||||
template<typename T1, typename T2, std::size_t R, std::size_t C>
|
||||
inline
|
||||
mat<typename promote_traits<T1, T2>::value_type, R, C>
|
||||
element_div(mat<T1, R, C> const& lhs, mat<T2, R, C> const& rhs) {
|
||||
mat<typename promote_traits<T1, T2>::value_type, R, C> res;
|
||||
for(int i = 0; i < R ; ++i) {
|
||||
for(int j = 0; j < C; ++j) {
|
||||
res(i, j) = lhs(i, j) / rhs(i, j);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//unary operator -(mat)
|
||||
template<typename T, std::size_t R, std::size_t C>
|
||||
inline
|
||||
mat<T, R, C>
|
||||
operator -(mat<T, R, C> const& rhs) {
|
||||
mat<T, R, C> res;
|
||||
for(int i = 0; i < R ; ++i) {
|
||||
for(int j = 0; j < C; ++j) {
|
||||
res(i, j) = -rhs(i, j);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//matrix transpose
|
||||
template<typename T, std::size_t R, std::size_t C>
|
||||
inline
|
||||
mat<T, R, C>
|
||||
trans(mat<T, R, C> const& rhs) {
|
||||
mat<T, R, C> res;
|
||||
for(int i = 0; i < R ; ++i) {
|
||||
for(int j = 0; j < C; ++j) {
|
||||
res(i, j) = rhs(j, i);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//identity matrix
|
||||
template<typename T, std::size_t Sz>
|
||||
inline
|
||||
mat<T, Sz, Sz>
|
||||
identity() {
|
||||
mat<T, Sz, Sz> res;
|
||||
for(int i = 0; i < Sz ; ++i) {
|
||||
for(int j = 0; j < Sz; ++j) {
|
||||
res(i, j) = i == j ? 1 : 0;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//matrix diagonal as vector (for square matrices)
|
||||
template<typename T, std::size_t N>
|
||||
inline
|
||||
vec<T, N>
|
||||
diag(mat<T, N, N> const& rhs) {
|
||||
vec<T, N> res;
|
||||
for(int i = 0; i < N; ++i) {
|
||||
res[i] = rhs(i, i);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//matrix row as vector
|
||||
template<typename T, std::size_t R, std::size_t C>
|
||||
inline
|
||||
vec<T, C>
|
||||
row(mat<T, R, C> const& rhs, std::size_t r) {
|
||||
vec<T, C> res;
|
||||
for(int i = 0; i < C; ++i) {
|
||||
res[i] = rhs(r, i);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//matrix column as vector
|
||||
template<typename T, std::size_t R, std::size_t C>
|
||||
inline
|
||||
vec<T, R>
|
||||
col(mat<T, R, C> const& rhs, std::size_t c) {
|
||||
vec<T, R> res;
|
||||
for(int i = 0; i < R; ++i) {
|
||||
res[i] = rhs(i, c);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
//matrix-matrix product
|
||||
template<typename T1, typename T2, std::size_t R1, std::size_t C1, std::size_t C2>
|
||||
inline
|
||||
mat<typename promote_traits<T1, T2>::value_type, R1, C2>
|
||||
prod(mat<T1, R1, C1> const& lhs, mat<T2, C1, C2> const& rhs) {
|
||||
mat<typename promote_traits<T1, T2>::value_type, R1, C2> res;
|
||||
for(int i = 0; i < R1; ++i) {
|
||||
for(int j = 0; j < C2; ++j) {
|
||||
res(i, j) = 0;
|
||||
for(int k = 0; k < C1; ++k) {
|
||||
res(i, j) += lhs(i, k) * rhs(k, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//matrix - column vector product
|
||||
template<typename T1, typename T2, std::size_t R, std::size_t C>
|
||||
inline
|
||||
vec<typename promote_traits<T1, T2>::value_type, R>
|
||||
prod(mat<T1, R, C> const& lhs, vec<T2, C> const& rhs) {
|
||||
vec<typename promote_traits<T1, T2>::value_type, R> res;
|
||||
for(int i = 0; i < R; ++i) {
|
||||
res(i) = 0;
|
||||
for(int j = 0; j < C; ++j) {
|
||||
res(i) += lhs(i, j) * rhs(j);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
} // namespace mvl
|
||||
|
||||
#endif
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library Maya Plugin
|
||||
Copyright (c) 2008 Walt Disney Studios
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising
|
||||
from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must
|
||||
not claim that you wrote the original software. If you use this
|
||||
software in a product, an acknowledgment in the product documentation
|
||||
would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must
|
||||
not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
Written by: Nicola Candussi <nicola@fluidinteractive.com>
|
||||
*/
|
||||
|
||||
//mat.h
|
||||
|
||||
#ifndef MVL_MAT_H
|
||||
#define MVL_MAT_H
|
||||
|
||||
#include <cmath>
|
||||
#include "base.h"
|
||||
#include "traits.h"
|
||||
|
||||
namespace mvl {
|
||||
|
||||
template<typename T, std::size_t R, std::size_t C>
|
||||
class mat
|
||||
{
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T& reference;
|
||||
typedef T const& const_reference;
|
||||
typedef T* iterator;
|
||||
typedef T const* const_iterator;
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
public:
|
||||
enum {
|
||||
Rows = R,
|
||||
Cols = C,
|
||||
Size = Rows * Cols,
|
||||
};
|
||||
|
||||
public:
|
||||
//constructors
|
||||
explicit mat() {}
|
||||
|
||||
template<typename T2>
|
||||
mat(mat<T2, Rows, Cols> const& m)
|
||||
{
|
||||
*this = m;
|
||||
}
|
||||
|
||||
explicit mat(value_type val)
|
||||
{
|
||||
for(int i = 0; i < Size; ++i){
|
||||
m_data[i] = val;
|
||||
}
|
||||
}
|
||||
|
||||
explicit mat(value_type m00, value_type m01,
|
||||
value_type m10, value_type m11)
|
||||
{
|
||||
operator()(0, 0) = m00; operator()(0, 1) = m01;
|
||||
operator()(1, 0) = m10; operator()(1, 1) = m11;
|
||||
}
|
||||
|
||||
explicit mat(value_type m00, value_type m01, value_type m02,
|
||||
value_type m10, value_type m11, value_type m12,
|
||||
value_type m20, value_type m21, value_type m22)
|
||||
{
|
||||
operator()(0, 0) = m00; operator()(0, 1) = m01; operator()(0, 2) = m02;
|
||||
operator()(1, 0) = m10; operator()(1, 1) = m11; operator()(1, 2) = m12;
|
||||
operator()(2, 0) = m20; operator()(2, 1) = m21; operator()(2, 2) = m22;
|
||||
}
|
||||
|
||||
explicit mat(value_type m00, value_type m01, value_type m02, value_type m03,
|
||||
value_type m10, value_type m11, value_type m12, value_type m13,
|
||||
value_type m20, value_type m21, value_type m22, value_type m23,
|
||||
value_type m30, value_type m31, value_type m32, value_type m33)
|
||||
{
|
||||
operator()(0, 0) = m00; operator()(0, 1) = m01; operator()(0, 2) = m02; operator()(0, 3) = m03;
|
||||
operator()(1, 0) = m10; operator()(1, 1) = m11; operator()(1, 2) = m12; operator()(1, 3) = m13;
|
||||
operator()(2, 0) = m20; operator()(2, 1) = m21; operator()(2, 2) = m22; operator()(2, 3) = m23;
|
||||
operator()(3, 0) = m30; operator()(3, 1) = m31; operator()(3, 2) = m32; operator()(3, 3) = m33;
|
||||
}
|
||||
|
||||
public:
|
||||
//data access
|
||||
value_type operator()(std::size_t i, std::size_t j) const { return m_data[j * Rows + i]; }
|
||||
reference operator()(std::size_t i, std::size_t j) { return m_data[j * Rows + i]; }
|
||||
|
||||
public:
|
||||
//stl
|
||||
static std::size_t size() { return Size; }
|
||||
static std::size_t max_size() { return Size; }
|
||||
static bool empty() { return false; }
|
||||
|
||||
iterator begin() { return m_data; }
|
||||
iterator end() { return m_data + Size; }
|
||||
const_iterator begin() const { return m_data; }
|
||||
const_iterator end() const { return m_data + Size; }
|
||||
reverse_iterator rbegin() { return reverse_iterator(end()); }
|
||||
reverse_iterator rend() { return reverse_iterator(begin()); }
|
||||
const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
|
||||
const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
|
||||
|
||||
value_type front() { return m_data[0]; }
|
||||
value_type back() { return m_data[Size - 1]; }
|
||||
const_reference front() const { return m_data[0]; }
|
||||
const_reference back() const { return m_data[Size - 1]; }
|
||||
|
||||
friend std::ostream& operator << (std::ostream& out, mat const& m) {
|
||||
out << "(";
|
||||
for(size_t i = 0; i < Rows - 1; i++) {
|
||||
for(size_t j = 0; j < Cols; j++) {
|
||||
out << m(i, j) << ", ";
|
||||
}
|
||||
out << std::endl;
|
||||
}
|
||||
for(size_t j = 0; j < Cols - 1; j++) {
|
||||
out << m(Rows - 1, j) << ", ";
|
||||
}
|
||||
out << m(Rows - 1, Cols - 1) << ")";
|
||||
return out;
|
||||
}
|
||||
|
||||
public:
|
||||
//
|
||||
mat& operator=(mat const& rhs) {
|
||||
std::copy(rhs.begin(),rhs.end(), begin());
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T2>
|
||||
mat& operator=(mat<T2, Rows, Cols> const& rhs) {
|
||||
std::copy(rhs.begin(),rhs.end(), begin());
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
//data is stored in column major order, so the matrix can passed directly to the graphics APIs
|
||||
T m_data[Size];
|
||||
};
|
||||
|
||||
//assignment operators
|
||||
// OP(mat<T1>, mat<T2>)
|
||||
// OP(mat<T>, T)
|
||||
|
||||
#define MAT_IMPLEMENT_MACRO(OP) \
|
||||
template<typename T1, typename T2, std::size_t R, std::size_t C> \
|
||||
inline \
|
||||
mat<T1, R, C>& \
|
||||
operator OP(mat<T1, R, C>& lhs, mat<T2, R, C> const& rhs) { \
|
||||
for(int i = 0; i < C * R; ++i) { \
|
||||
lhs[i] OP rhs[i]; \
|
||||
} \
|
||||
return lhs; \
|
||||
} \
|
||||
\
|
||||
template<typename T, std::size_t R, std::size_t C> \
|
||||
inline \
|
||||
mat<T, R, C>& \
|
||||
operator OP(mat<T, R, C>& lhs, typename mat<T, R, C>::value_type const& rhs) { \
|
||||
for(int i = 0; i < C * R; ++i) { \
|
||||
lhs[i] OP rhs[i]; \
|
||||
} \
|
||||
return lhs; \
|
||||
} \
|
||||
|
||||
MAT_IMPLEMENT_MACRO(+=)
|
||||
MAT_IMPLEMENT_MACRO(-=)
|
||||
MAT_IMPLEMENT_MACRO(*=)
|
||||
MAT_IMPLEMENT_MACRO(/=)
|
||||
|
||||
#undef MAT_IMPLEMENT_MACRO
|
||||
|
||||
//operator + (mat, mat)
|
||||
template<typename T1, typename T2, std::size_t R, std::size_t C>
|
||||
inline
|
||||
mat<typename promote_traits<T1, T2>::value_type, R, C>
|
||||
operator + (mat<T1, R, C> const& lhs, mat<T2, R, C> const& rhs) {
|
||||
mat<typename promote_traits<T1, T2>::value_type, R, C> res;
|
||||
for(int i = 0; i < R ; ++i) {
|
||||
for(int j = 0; j < C; ++j) {
|
||||
res(i, j) = lhs(i, j) + rhs(i, j);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//operator - (mat, mat)
|
||||
template<typename T1, typename T2, std::size_t R, std::size_t C>
|
||||
inline
|
||||
mat<typename promote_traits<T1, T2>::value_type, R, C>
|
||||
operator - (mat<T1, R, C> const& lhs, mat<T2, R, C> const& rhs) {
|
||||
mat<typename promote_traits<T1, T2>::value_type, R, C> res;
|
||||
for(int i = 0; i < R ; ++i) {
|
||||
for(int j = 0; j < C; ++j) {
|
||||
res(i, j) = lhs(i, j) - rhs(i, j);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//operator * (mat, POD)
|
||||
template<typename T1, typename T2, std::size_t R, std::size_t C>
|
||||
inline
|
||||
mat<typename promote_traits<T1, T2>::value_type, R, C>
|
||||
operator * (mat<T1, R, C> const& lhs, T2 const& rhs) {
|
||||
mat<typename promote_traits<T1, T2>::value_type, R, C> res;
|
||||
for(int i = 0; i < R ; ++i) {
|
||||
for(int j = 0; j < C; ++j) {
|
||||
res(i, j) = lhs(i, j) * rhs;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//operator * (POD, mat)
|
||||
template<typename T1, typename T2, std::size_t R, std::size_t C>
|
||||
inline
|
||||
mat<typename promote_traits<T1, T2>::value_type, R, C>
|
||||
operator * (T1 const& lhs, mat<T2, R, C> const& rhs) {
|
||||
mat<typename promote_traits<T1, T2>::value_type, R, C> res;
|
||||
for(int i = 0; i < R ; ++i) {
|
||||
for(int j = 0; j < C; ++j) {
|
||||
res(i, j) = lhs * rhs(i, j);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//operator / (mat, POD)
|
||||
template<typename T1, typename T2, std::size_t R, std::size_t C>
|
||||
inline
|
||||
mat<typename promote_traits<T1, T2>::value_type, R, C>
|
||||
operator / (mat<T1, R, C> const& lhs, T2 const& rhs) {
|
||||
mat<typename promote_traits<T1, T2>::value_type, R, C> res;
|
||||
for(int i = 0; i < R ; ++i) {
|
||||
for(int j = 0; j < C; ++j) {
|
||||
res(i, j) = lhs(i, j) / rhs;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//element_prod(mat, mat)
|
||||
template<typename T1, typename T2, std::size_t R, std::size_t C>
|
||||
inline
|
||||
mat<typename promote_traits<T1, T2>::value_type, R, C>
|
||||
element_prod(mat<T1, R, C> const& lhs, mat<T2, R, C> const& rhs) {
|
||||
mat<typename promote_traits<T1, T2>::value_type, R, C> res;
|
||||
for(int i = 0; i < R ; ++i) {
|
||||
for(int j = 0; j < C; ++j) {
|
||||
res(i, j) = lhs(i, j) * rhs(i, j);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//element_div(mat, mat)
|
||||
template<typename T1, typename T2, std::size_t R, std::size_t C>
|
||||
inline
|
||||
mat<typename promote_traits<T1, T2>::value_type, R, C>
|
||||
element_div(mat<T1, R, C> const& lhs, mat<T2, R, C> const& rhs) {
|
||||
mat<typename promote_traits<T1, T2>::value_type, R, C> res;
|
||||
for(int i = 0; i < R ; ++i) {
|
||||
for(int j = 0; j < C; ++j) {
|
||||
res(i, j) = lhs(i, j) / rhs(i, j);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//unary operator -(mat)
|
||||
template<typename T, std::size_t R, std::size_t C>
|
||||
inline
|
||||
mat<T, R, C>
|
||||
operator -(mat<T, R, C> const& rhs) {
|
||||
mat<T, R, C> res;
|
||||
for(int i = 0; i < R ; ++i) {
|
||||
for(int j = 0; j < C; ++j) {
|
||||
res(i, j) = -rhs(i, j);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//matrix transpose
|
||||
template<typename T, std::size_t R, std::size_t C>
|
||||
inline
|
||||
mat<T, R, C>
|
||||
trans(mat<T, R, C> const& rhs) {
|
||||
mat<T, R, C> res;
|
||||
for(int i = 0; i < R ; ++i) {
|
||||
for(int j = 0; j < C; ++j) {
|
||||
res(i, j) = rhs(j, i);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//identity matrix
|
||||
template<typename T, std::size_t Sz>
|
||||
inline
|
||||
mat<T, Sz, Sz>
|
||||
identity() {
|
||||
mat<T, Sz, Sz> res;
|
||||
for(int i = 0; i < Sz ; ++i) {
|
||||
for(int j = 0; j < Sz; ++j) {
|
||||
res(i, j) = i == j ? 1 : 0;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//matrix diagonal as vector (for square matrices)
|
||||
template<typename T, std::size_t N>
|
||||
inline
|
||||
vec<T, N>
|
||||
diag(mat<T, N, N> const& rhs) {
|
||||
vec<T, N> res;
|
||||
for(int i = 0; i < N; ++i) {
|
||||
res[i] = rhs(i, i);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//matrix row as vector
|
||||
template<typename T, std::size_t R, std::size_t C>
|
||||
inline
|
||||
vec<T, C>
|
||||
row(mat<T, R, C> const& rhs, std::size_t r) {
|
||||
vec<T, C> res;
|
||||
for(int i = 0; i < C; ++i) {
|
||||
res[i] = rhs(r, i);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//matrix column as vector
|
||||
template<typename T, std::size_t R, std::size_t C>
|
||||
inline
|
||||
vec<T, R>
|
||||
col(mat<T, R, C> const& rhs, std::size_t c) {
|
||||
vec<T, R> res;
|
||||
for(int i = 0; i < R; ++i) {
|
||||
res[i] = rhs(i, c);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
//matrix-matrix product
|
||||
template<typename T1, typename T2, std::size_t R1, std::size_t C1, std::size_t C2>
|
||||
inline
|
||||
mat<typename promote_traits<T1, T2>::value_type, R1, C2>
|
||||
prod(mat<T1, R1, C1> const& lhs, mat<T2, C1, C2> const& rhs) {
|
||||
mat<typename promote_traits<T1, T2>::value_type, R1, C2> res;
|
||||
for(int i = 0; i < R1; ++i) {
|
||||
for(int j = 0; j < C2; ++j) {
|
||||
res(i, j) = 0;
|
||||
for(int k = 0; k < C1; ++k) {
|
||||
res(i, j) += lhs(i, k) * rhs(k, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//matrix - column vector product
|
||||
template<typename T1, typename T2, std::size_t R, std::size_t C>
|
||||
inline
|
||||
vec<typename promote_traits<T1, T2>::value_type, R>
|
||||
prod(mat<T1, R, C> const& lhs, vec<T2, C> const& rhs) {
|
||||
vec<typename promote_traits<T1, T2>::value_type, R> res;
|
||||
for(int i = 0; i < R; ++i) {
|
||||
res(i) = 0;
|
||||
for(int j = 0; j < C; ++j) {
|
||||
res(i) += lhs(i, j) * rhs(j);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
} // namespace mvl
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,279 +1,279 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library Maya Plugin
|
||||
Copyright (c) 2008 Walt Disney Studios
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising
|
||||
from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must
|
||||
not claim that you wrote the original software. If you use this
|
||||
software in a product, an acknowledgment in the product documentation
|
||||
would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must
|
||||
not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
Written by: Nicola Candussi <nicola@fluidinteractive.com>
|
||||
*/
|
||||
|
||||
//quat.h
|
||||
|
||||
#ifndef MVL_QUAT_H
|
||||
#define MVL_QUAT_H
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include "vec.h"
|
||||
#include "mat.h"
|
||||
|
||||
//quaternions are vectors of size 4
|
||||
// it's assumed that the layout is in the form (w, (x, y, z)),
|
||||
// so that the identity quaternion is (1, 0, 0, 0)
|
||||
|
||||
namespace mvl {
|
||||
|
||||
//quaternion conjugate
|
||||
template<typename T>
|
||||
inline vec<T, 4>
|
||||
qconj(vec<T, 4> const& rhs) {
|
||||
return vec<T, 4>(-rhs[0], rhs[1], rhs[2], rhs[3]);
|
||||
}
|
||||
|
||||
//quaternion identity
|
||||
template<typename T>
|
||||
inline
|
||||
vec<T, 4>
|
||||
qidentity() {
|
||||
return vec<T, 4>(1, 0, 0, 0);
|
||||
}
|
||||
|
||||
//quaternion - quaternion product
|
||||
template<typename T1, typename T2>
|
||||
inline
|
||||
vec<typename promote_traits<T1, T2>::value_type, 4>
|
||||
qprod(vec<T1, 4> const& lhs, vec<T2, 4> const& rhs) {
|
||||
typedef typename promote_traits<T1, T2>::value_type value_type;
|
||||
return vec<value_type, 4>((lhs(0)*rhs(0)) - (lhs(1)*rhs(1)) - (lhs(2)*rhs(2)) - (lhs(3)*rhs(3)),
|
||||
(lhs(0)*rhs(1)) + (lhs(1)*rhs(0)) + (lhs(2)*rhs(3)) - (lhs(3)*rhs(2)),
|
||||
(lhs(0)*rhs(2)) - (lhs(1)*rhs(3)) + (lhs(2)*rhs(0)) + (lhs(3)*rhs(1)),
|
||||
(lhs(0)*rhs(3)) + (lhs(1)*rhs(2)) - (lhs(2)*rhs(1)) + (lhs(3)*rhs(0)));
|
||||
}
|
||||
|
||||
//quanternion - vector product (rotation)
|
||||
template<typename T1, typename T2>
|
||||
inline
|
||||
vec<typename promote_traits<T1, T2>::value_type, 3>
|
||||
qprod(vec<T1, 4> const& q, vec<T2, 3> const& v) {
|
||||
typedef typename promote_traits<T1, T2>::value_type value_type;
|
||||
vec<value_type, 4> tmp = qprod(qprod(q, vec<value_type, 4>(0, v[0], v[1], v[2])), qconj(q));
|
||||
return vec<value_type, 3>(tmp[0], tmp[1], tmp[2]);
|
||||
}
|
||||
|
||||
//spherical interpolation between q0 and q1
|
||||
template <typename T1, typename T2, typename T3>
|
||||
inline
|
||||
vec<typename promote_traits<T1, T2>::value_type, 4>
|
||||
qslerp(vec<T1, 4> const& q1, vec<T2, 4> const& q2, T3 t) {
|
||||
typedef typename promote_traits<T1, T2>::value_type value_type;
|
||||
value_type omega, cosom, sinom, scale0, scale1;
|
||||
vec<value_type, 4> tmp;
|
||||
|
||||
cosom = dot(q1, q2);
|
||||
|
||||
if (cosom < static_cast<value_type>(0.0)) {
|
||||
cosom = -cosom;
|
||||
tmp = -q2;
|
||||
} else {
|
||||
tmp = q2;
|
||||
}
|
||||
|
||||
if ((static_cast<value_type>(1.0) - cosom) > std::numeric_limits<value_type>::epsilon()) {
|
||||
omega = (value_type) acos(cosom);
|
||||
sinom = sin(omega);
|
||||
scale0 = sin((static_cast<value_type>(1.0) - t) * omega) / sinom;
|
||||
scale1 = sin(t * omega) / sinom;
|
||||
} else {
|
||||
scale0 = static_cast<value_type>(1.0) - t;
|
||||
scale1 = t;
|
||||
}
|
||||
|
||||
return scale0 * q1 + scale1 * tmp;
|
||||
}
|
||||
|
||||
//init quaternion from axis-angle
|
||||
template<typename T1, typename T2>
|
||||
inline
|
||||
vec<typename promote_traits<T1, T2>::value_type, 4>
|
||||
q_from_axis_angle(vec<T1, 3> const& axis, T2 theta) {
|
||||
typedef typename promote_traits<T1, T2>::value_type value_type;
|
||||
value_type sin_theta = sin(static_cast<value_type>(static_cast<value_type>(0.5)) * theta);
|
||||
return vec<value_type, 4>(cos(static_cast<value_type>(static_cast<value_type>(0.5)) * theta),
|
||||
sin_theta * axis[0],
|
||||
sin_theta * axis[1],
|
||||
sin_theta * axis[2]);
|
||||
}
|
||||
|
||||
//get the axis/angle from quaternion
|
||||
template<typename T1, typename T2, typename T3>
|
||||
inline
|
||||
void
|
||||
q_to_axis_angle(vec<T1, 4> const& q, vec<T2, 3>& axis, T3& theta)
|
||||
{
|
||||
T3 half_theta= acos(q[0]);
|
||||
|
||||
if(half_theta > 10 * std::numeric_limits<T3>::epsilon()) {
|
||||
T3 oost = 1 / sin(half_theta);
|
||||
|
||||
axis[0] = oost * q[1];
|
||||
axis[1] = oost * q[2];
|
||||
axis[2] = oost * q[3];
|
||||
theta = 2 * half_theta;
|
||||
} else {
|
||||
axis[0] = axis[1] = axis[2] = 0;
|
||||
theta = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//init quaternion from rotation matrix
|
||||
template<typename T1>
|
||||
inline
|
||||
vec<T1, 4>
|
||||
q_from_mat(mat<T1, 3, 3> const& m) {
|
||||
T1 trace, s, hos;
|
||||
trace = m(0, 0) + m(1, 1) + m(2, 2);
|
||||
if (trace > static_cast<T1>(0.0)) {
|
||||
s = sqrt(trace + static_cast<T1>(1.0));
|
||||
hos = static_cast<T1>(0.5) / s;
|
||||
return vec<T1, 4>(s * static_cast<T1>(0.5), (m(2, 1) - m(1, 2)) * hos, (m(0, 2) - m(2, 0)) * hos, (m(1, 0) - m(0, 1)) * hos);
|
||||
} else {
|
||||
int biggest;
|
||||
enum {A,T,I};
|
||||
if (m(0, 0) > m(1, 1)) {
|
||||
if (m(2, 2) > m(0, 0)) biggest = I;
|
||||
else biggest = A;
|
||||
} else {
|
||||
if (m(2, 2) > m(0, 0)) biggest = I;
|
||||
else biggest = T;
|
||||
}
|
||||
switch (biggest) {
|
||||
case A:
|
||||
s = sqrt( m(0, 0) - (m(1, 1) + m(2, 2)) + static_cast<T1>(1.0));
|
||||
if (s > (100 * std::numeric_limits<T1>::epsilon())) {
|
||||
hos = static_cast<T1>(0.5) / s;
|
||||
return vec<T1, 4>((m(2, 1) - m(1, 2)) * hos, s * static_cast<T1>(0.5), (m(0, 1) + m(1, 0)) * hos, (m(0, 2) + m(2, 0)) * hos);
|
||||
}
|
||||
// I
|
||||
s = sqrt( m(2, 2) - (m(0, 0) + m(1, 1)) + static_cast<T1>(1.0));
|
||||
if (s > (100 * std::numeric_limits<T1>::epsilon())) {
|
||||
hos = static_cast<T1>(0.5) / s;
|
||||
return vec<T1, 4>((m(1, 0) - m(0, 1)) * hos, (m(2, 0) + m(0, 2)) * hos, (m(2, 1) + m(1, 2)) * hos, s * static_cast<T1>(0.5));
|
||||
}
|
||||
// T
|
||||
s = sqrt( m(1, 1) - (m(2, 2) + m(0, 0)) + static_cast<T1>(1.0));
|
||||
if (s > (100 * std::numeric_limits<T1>::epsilon())) {
|
||||
hos = static_cast<T1>(0.5) / s;
|
||||
return vec<T1, 4>((m(0, 2) - m(2, 0)) * hos, (m(1, 0) + m(0, 1)) * hos, s * static_cast<T1>(0.5), (m(1, 2) + m(2, 1)) * hos);
|
||||
}
|
||||
break;
|
||||
case T:
|
||||
s = sqrt( m(1, 1) - (m(2, 2) + m(0, 0)) + static_cast<T1>(1.0));
|
||||
if (s > (100 * std::numeric_limits<T1>::epsilon())) {
|
||||
hos = static_cast<T1>(0.5) / s;
|
||||
return vec<T1, 4>((m(0, 2) - m(2, 0)) * hos, (m(1, 0) + m(0, 1)) * hos, s * static_cast<T1>(0.5), (m(1, 2) + m(2, 1)) * hos);
|
||||
}
|
||||
// I
|
||||
s = sqrt( m(2, 2) - (m(0, 0) + m(1, 1)) + static_cast<T1>(1.0));
|
||||
if (s > (100 * std::numeric_limits<T1>::epsilon())) {
|
||||
hos = static_cast<T1>(0.5) / s;
|
||||
return vec<T1, 4>((m(1, 0) - m(0, 1)) * hos, (m(2, 0) + m(0, 2)) * hos, (m(2, 1) + m(1, 2)) * hos, s * static_cast<T1>(0.5));
|
||||
}
|
||||
// A
|
||||
s = sqrt( m(0, 0) - (m(1, 1) + m(2, 2)) + static_cast<T1>(1.0));
|
||||
if (s > (100 * std::numeric_limits<T1>::epsilon())) {
|
||||
hos = static_cast<T1>(0.5) / s;
|
||||
return vec<T1, 4>((m(2, 1) - m(1, 2)) * hos, s * static_cast<T1>(0.5), (m(0, 1) + m(1, 0)) * hos, (m(0, 2) + m(2, 0)) * hos);
|
||||
}
|
||||
break;
|
||||
case I:
|
||||
s = sqrt( m(2, 2) - (m(0, 0) + m(1, 1)) + static_cast<T1>(1.0));
|
||||
if (s > (100 * std::numeric_limits<T1>::epsilon())) {
|
||||
hos = static_cast<T1>(0.5) / s;
|
||||
return vec<T1, 4>((m(1, 0) - m(0, 1)) * hos, (m(2, 0) + m(0, 2)) * hos, (m(2, 1) + m(1, 2)) * hos, s * static_cast<T1>(0.5));
|
||||
}
|
||||
// A
|
||||
s = sqrt( m(0, 0) - (m(1, 1) + m(2, 2)) + static_cast<T1>(1.0));
|
||||
if (s > (100 * std::numeric_limits<T1>::epsilon())) {
|
||||
hos = static_cast<T1>(0.5) / s;
|
||||
return vec<T1, 4>((m(2, 1) - m(1, 2)) * hos, s * static_cast<T1>(0.5), (m(0, 1) + m(1, 0)) * hos, (m(0, 2) + m(2, 0)) * hos);
|
||||
}
|
||||
// T
|
||||
s = sqrt( m(1, 1) - (m(2, 2) + m(0, 0)) + static_cast<T1>(1.0));
|
||||
if (s > (100 * std::numeric_limits<T1>::epsilon())) {
|
||||
hos = static_cast<T1>(0.5) / s;
|
||||
return vec<T1, 4>((m(0, 2) - m(2, 0)) * hos, (m(1, 0) + m(0, 1)) * hos, s * static_cast<T1>(0.5), (m(1, 2) + m(2, 1)) * hos);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//get rotation matrix from quaternion
|
||||
template<typename T>
|
||||
inline
|
||||
void
|
||||
q_to_mat(vec<T, 4> const& q, mat<T, 3, 3>& m) {
|
||||
T X2,Y2,Z2; //2*QX, 2*QY, 2*QZ
|
||||
T XX2,YY2,ZZ2; //2*QX*QX, 2*QY*QY, 2*QZ*QZ
|
||||
T XY2,XZ2,XW2; //2*QX*QY, 2*QX*QZ, 2*QX*QW
|
||||
T YZ2,YW2,ZW2; // ...
|
||||
|
||||
X2 = 2 * q[1];
|
||||
XX2 = X2 * q[1];
|
||||
XY2 = X2 * q[2];
|
||||
XZ2 = X2 * q[3];
|
||||
XW2 = X2 * q[0];
|
||||
|
||||
Y2 = 2 * q[2];
|
||||
YY2 = Y2 * q[2];
|
||||
YZ2 = Y2 * q[3];
|
||||
YW2 = Y2 * q[0];
|
||||
|
||||
Z2 = 2 * q[3];
|
||||
ZZ2 = Z2 * q[3];
|
||||
ZW2 = Z2 * q[0];
|
||||
|
||||
m(0, 0) = 1 - YY2 - ZZ2;
|
||||
m(0, 1) = XY2 - ZW2;
|
||||
m(0, 2) = XZ2 + YW2;
|
||||
|
||||
m(1, 0) = XY2 + ZW2;
|
||||
m(1, 1) = 1 - XX2 - ZZ2;
|
||||
m(1, 2) = YZ2 - XW2;
|
||||
|
||||
m(2, 0) = XZ2 - YW2;
|
||||
m(2, 1) = YZ2 + XW2;
|
||||
m(2, 2) = 1 - XX2 - YY2;
|
||||
|
||||
}
|
||||
|
||||
template<typename T, size_t R, size_t C>
|
||||
mat<T, R, C>
|
||||
cmat(T const* m)
|
||||
{
|
||||
mat<T, R, C> res;
|
||||
for(int i = 0; i < R; ++i) {
|
||||
for(int j = 0; j < C; ++j) {
|
||||
res(i, j) = m[i * C + j];
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
} //namespace mvl
|
||||
|
||||
|
||||
#endif
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library Maya Plugin
|
||||
Copyright (c) 2008 Walt Disney Studios
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising
|
||||
from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must
|
||||
not claim that you wrote the original software. If you use this
|
||||
software in a product, an acknowledgment in the product documentation
|
||||
would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must
|
||||
not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
Written by: Nicola Candussi <nicola@fluidinteractive.com>
|
||||
*/
|
||||
|
||||
//quat.h
|
||||
|
||||
#ifndef MVL_QUAT_H
|
||||
#define MVL_QUAT_H
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include "vec.h"
|
||||
#include "mat.h"
|
||||
|
||||
//quaternions are vectors of size 4
|
||||
// it's assumed that the layout is in the form (w, (x, y, z)),
|
||||
// so that the identity quaternion is (1, 0, 0, 0)
|
||||
|
||||
namespace mvl {
|
||||
|
||||
//quaternion conjugate
|
||||
template<typename T>
|
||||
inline vec<T, 4>
|
||||
qconj(vec<T, 4> const& rhs) {
|
||||
return vec<T, 4>(-rhs[0], rhs[1], rhs[2], rhs[3]);
|
||||
}
|
||||
|
||||
//quaternion identity
|
||||
template<typename T>
|
||||
inline
|
||||
vec<T, 4>
|
||||
qidentity() {
|
||||
return vec<T, 4>(1, 0, 0, 0);
|
||||
}
|
||||
|
||||
//quaternion - quaternion product
|
||||
template<typename T1, typename T2>
|
||||
inline
|
||||
vec<typename promote_traits<T1, T2>::value_type, 4>
|
||||
qprod(vec<T1, 4> const& lhs, vec<T2, 4> const& rhs) {
|
||||
typedef typename promote_traits<T1, T2>::value_type value_type;
|
||||
return vec<value_type, 4>((lhs(0)*rhs(0)) - (lhs(1)*rhs(1)) - (lhs(2)*rhs(2)) - (lhs(3)*rhs(3)),
|
||||
(lhs(0)*rhs(1)) + (lhs(1)*rhs(0)) + (lhs(2)*rhs(3)) - (lhs(3)*rhs(2)),
|
||||
(lhs(0)*rhs(2)) - (lhs(1)*rhs(3)) + (lhs(2)*rhs(0)) + (lhs(3)*rhs(1)),
|
||||
(lhs(0)*rhs(3)) + (lhs(1)*rhs(2)) - (lhs(2)*rhs(1)) + (lhs(3)*rhs(0)));
|
||||
}
|
||||
|
||||
//quanternion - vector product (rotation)
|
||||
template<typename T1, typename T2>
|
||||
inline
|
||||
vec<typename promote_traits<T1, T2>::value_type, 3>
|
||||
qprod(vec<T1, 4> const& q, vec<T2, 3> const& v) {
|
||||
typedef typename promote_traits<T1, T2>::value_type value_type;
|
||||
vec<value_type, 4> tmp = qprod(qprod(q, vec<value_type, 4>(0, v[0], v[1], v[2])), qconj(q));
|
||||
return vec<value_type, 3>(tmp[0], tmp[1], tmp[2]);
|
||||
}
|
||||
|
||||
//spherical interpolation between q0 and q1
|
||||
template <typename T1, typename T2, typename T3>
|
||||
inline
|
||||
vec<typename promote_traits<T1, T2>::value_type, 4>
|
||||
qslerp(vec<T1, 4> const& q1, vec<T2, 4> const& q2, T3 t) {
|
||||
typedef typename promote_traits<T1, T2>::value_type value_type;
|
||||
value_type omega, cosom, sinom, scale0, scale1;
|
||||
vec<value_type, 4> tmp;
|
||||
|
||||
cosom = dot(q1, q2);
|
||||
|
||||
if (cosom < static_cast<value_type>(0.0)) {
|
||||
cosom = -cosom;
|
||||
tmp = -q2;
|
||||
} else {
|
||||
tmp = q2;
|
||||
}
|
||||
|
||||
if ((static_cast<value_type>(1.0) - cosom) > std::numeric_limits<value_type>::epsilon()) {
|
||||
omega = (value_type) acos(cosom);
|
||||
sinom = sin(omega);
|
||||
scale0 = sin((static_cast<value_type>(1.0) - t) * omega) / sinom;
|
||||
scale1 = sin(t * omega) / sinom;
|
||||
} else {
|
||||
scale0 = static_cast<value_type>(1.0) - t;
|
||||
scale1 = t;
|
||||
}
|
||||
|
||||
return scale0 * q1 + scale1 * tmp;
|
||||
}
|
||||
|
||||
//init quaternion from axis-angle
|
||||
template<typename T1, typename T2>
|
||||
inline
|
||||
vec<typename promote_traits<T1, T2>::value_type, 4>
|
||||
q_from_axis_angle(vec<T1, 3> const& axis, T2 theta) {
|
||||
typedef typename promote_traits<T1, T2>::value_type value_type;
|
||||
value_type sin_theta = sin(static_cast<value_type>(static_cast<value_type>(0.5)) * theta);
|
||||
return vec<value_type, 4>(cos(static_cast<value_type>(static_cast<value_type>(0.5)) * theta),
|
||||
sin_theta * axis[0],
|
||||
sin_theta * axis[1],
|
||||
sin_theta * axis[2]);
|
||||
}
|
||||
|
||||
//get the axis/angle from quaternion
|
||||
template<typename T1, typename T2, typename T3>
|
||||
inline
|
||||
void
|
||||
q_to_axis_angle(vec<T1, 4> const& q, vec<T2, 3>& axis, T3& theta)
|
||||
{
|
||||
T3 half_theta= acos(q[0]);
|
||||
|
||||
if(half_theta > 10 * std::numeric_limits<T3>::epsilon()) {
|
||||
T3 oost = 1 / sin(half_theta);
|
||||
|
||||
axis[0] = oost * q[1];
|
||||
axis[1] = oost * q[2];
|
||||
axis[2] = oost * q[3];
|
||||
theta = 2 * half_theta;
|
||||
} else {
|
||||
axis[0] = axis[1] = axis[2] = 0;
|
||||
theta = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//init quaternion from rotation matrix
|
||||
template<typename T1>
|
||||
inline
|
||||
vec<T1, 4>
|
||||
q_from_mat(mat<T1, 3, 3> const& m) {
|
||||
T1 trace, s, hos;
|
||||
trace = m(0, 0) + m(1, 1) + m(2, 2);
|
||||
if (trace > static_cast<T1>(0.0)) {
|
||||
s = sqrt(trace + static_cast<T1>(1.0));
|
||||
hos = static_cast<T1>(0.5) / s;
|
||||
return vec<T1, 4>(s * static_cast<T1>(0.5), (m(2, 1) - m(1, 2)) * hos, (m(0, 2) - m(2, 0)) * hos, (m(1, 0) - m(0, 1)) * hos);
|
||||
} else {
|
||||
int biggest;
|
||||
enum {A,T,I};
|
||||
if (m(0, 0) > m(1, 1)) {
|
||||
if (m(2, 2) > m(0, 0)) biggest = I;
|
||||
else biggest = A;
|
||||
} else {
|
||||
if (m(2, 2) > m(0, 0)) biggest = I;
|
||||
else biggest = T;
|
||||
}
|
||||
switch (biggest) {
|
||||
case A:
|
||||
s = sqrt( m(0, 0) - (m(1, 1) + m(2, 2)) + static_cast<T1>(1.0));
|
||||
if (s > (100 * std::numeric_limits<T1>::epsilon())) {
|
||||
hos = static_cast<T1>(0.5) / s;
|
||||
return vec<T1, 4>((m(2, 1) - m(1, 2)) * hos, s * static_cast<T1>(0.5), (m(0, 1) + m(1, 0)) * hos, (m(0, 2) + m(2, 0)) * hos);
|
||||
}
|
||||
// I
|
||||
s = sqrt( m(2, 2) - (m(0, 0) + m(1, 1)) + static_cast<T1>(1.0));
|
||||
if (s > (100 * std::numeric_limits<T1>::epsilon())) {
|
||||
hos = static_cast<T1>(0.5) / s;
|
||||
return vec<T1, 4>((m(1, 0) - m(0, 1)) * hos, (m(2, 0) + m(0, 2)) * hos, (m(2, 1) + m(1, 2)) * hos, s * static_cast<T1>(0.5));
|
||||
}
|
||||
// T
|
||||
s = sqrt( m(1, 1) - (m(2, 2) + m(0, 0)) + static_cast<T1>(1.0));
|
||||
if (s > (100 * std::numeric_limits<T1>::epsilon())) {
|
||||
hos = static_cast<T1>(0.5) / s;
|
||||
return vec<T1, 4>((m(0, 2) - m(2, 0)) * hos, (m(1, 0) + m(0, 1)) * hos, s * static_cast<T1>(0.5), (m(1, 2) + m(2, 1)) * hos);
|
||||
}
|
||||
break;
|
||||
case T:
|
||||
s = sqrt( m(1, 1) - (m(2, 2) + m(0, 0)) + static_cast<T1>(1.0));
|
||||
if (s > (100 * std::numeric_limits<T1>::epsilon())) {
|
||||
hos = static_cast<T1>(0.5) / s;
|
||||
return vec<T1, 4>((m(0, 2) - m(2, 0)) * hos, (m(1, 0) + m(0, 1)) * hos, s * static_cast<T1>(0.5), (m(1, 2) + m(2, 1)) * hos);
|
||||
}
|
||||
// I
|
||||
s = sqrt( m(2, 2) - (m(0, 0) + m(1, 1)) + static_cast<T1>(1.0));
|
||||
if (s > (100 * std::numeric_limits<T1>::epsilon())) {
|
||||
hos = static_cast<T1>(0.5) / s;
|
||||
return vec<T1, 4>((m(1, 0) - m(0, 1)) * hos, (m(2, 0) + m(0, 2)) * hos, (m(2, 1) + m(1, 2)) * hos, s * static_cast<T1>(0.5));
|
||||
}
|
||||
// A
|
||||
s = sqrt( m(0, 0) - (m(1, 1) + m(2, 2)) + static_cast<T1>(1.0));
|
||||
if (s > (100 * std::numeric_limits<T1>::epsilon())) {
|
||||
hos = static_cast<T1>(0.5) / s;
|
||||
return vec<T1, 4>((m(2, 1) - m(1, 2)) * hos, s * static_cast<T1>(0.5), (m(0, 1) + m(1, 0)) * hos, (m(0, 2) + m(2, 0)) * hos);
|
||||
}
|
||||
break;
|
||||
case I:
|
||||
s = sqrt( m(2, 2) - (m(0, 0) + m(1, 1)) + static_cast<T1>(1.0));
|
||||
if (s > (100 * std::numeric_limits<T1>::epsilon())) {
|
||||
hos = static_cast<T1>(0.5) / s;
|
||||
return vec<T1, 4>((m(1, 0) - m(0, 1)) * hos, (m(2, 0) + m(0, 2)) * hos, (m(2, 1) + m(1, 2)) * hos, s * static_cast<T1>(0.5));
|
||||
}
|
||||
// A
|
||||
s = sqrt( m(0, 0) - (m(1, 1) + m(2, 2)) + static_cast<T1>(1.0));
|
||||
if (s > (100 * std::numeric_limits<T1>::epsilon())) {
|
||||
hos = static_cast<T1>(0.5) / s;
|
||||
return vec<T1, 4>((m(2, 1) - m(1, 2)) * hos, s * static_cast<T1>(0.5), (m(0, 1) + m(1, 0)) * hos, (m(0, 2) + m(2, 0)) * hos);
|
||||
}
|
||||
// T
|
||||
s = sqrt( m(1, 1) - (m(2, 2) + m(0, 0)) + static_cast<T1>(1.0));
|
||||
if (s > (100 * std::numeric_limits<T1>::epsilon())) {
|
||||
hos = static_cast<T1>(0.5) / s;
|
||||
return vec<T1, 4>((m(0, 2) - m(2, 0)) * hos, (m(1, 0) + m(0, 1)) * hos, s * static_cast<T1>(0.5), (m(1, 2) + m(2, 1)) * hos);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//get rotation matrix from quaternion
|
||||
template<typename T>
|
||||
inline
|
||||
void
|
||||
q_to_mat(vec<T, 4> const& q, mat<T, 3, 3>& m) {
|
||||
T X2,Y2,Z2; //2*QX, 2*QY, 2*QZ
|
||||
T XX2,YY2,ZZ2; //2*QX*QX, 2*QY*QY, 2*QZ*QZ
|
||||
T XY2,XZ2,XW2; //2*QX*QY, 2*QX*QZ, 2*QX*QW
|
||||
T YZ2,YW2,ZW2; // ...
|
||||
|
||||
X2 = 2 * q[1];
|
||||
XX2 = X2 * q[1];
|
||||
XY2 = X2 * q[2];
|
||||
XZ2 = X2 * q[3];
|
||||
XW2 = X2 * q[0];
|
||||
|
||||
Y2 = 2 * q[2];
|
||||
YY2 = Y2 * q[2];
|
||||
YZ2 = Y2 * q[3];
|
||||
YW2 = Y2 * q[0];
|
||||
|
||||
Z2 = 2 * q[3];
|
||||
ZZ2 = Z2 * q[3];
|
||||
ZW2 = Z2 * q[0];
|
||||
|
||||
m(0, 0) = 1 - YY2 - ZZ2;
|
||||
m(0, 1) = XY2 - ZW2;
|
||||
m(0, 2) = XZ2 + YW2;
|
||||
|
||||
m(1, 0) = XY2 + ZW2;
|
||||
m(1, 1) = 1 - XX2 - ZZ2;
|
||||
m(1, 2) = YZ2 - XW2;
|
||||
|
||||
m(2, 0) = XZ2 - YW2;
|
||||
m(2, 1) = YZ2 + XW2;
|
||||
m(2, 2) = 1 - XX2 - YY2;
|
||||
|
||||
}
|
||||
|
||||
template<typename T, size_t R, size_t C>
|
||||
mat<T, R, C>
|
||||
cmat(T const* m)
|
||||
{
|
||||
mat<T, R, C> res;
|
||||
for(int i = 0; i < R; ++i) {
|
||||
for(int j = 0; j < C; ++j) {
|
||||
res(i, j) = m[i * C + j];
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
} //namespace mvl
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,85 +1,85 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library Maya Plugin
|
||||
Copyright (c) 2008 Walt Disney Studios
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising
|
||||
from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must
|
||||
not claim that you wrote the original software. If you use this
|
||||
software in a product, an acknowledgment in the product documentation
|
||||
would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must
|
||||
not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
Written by: Nicola Candussi <nicola@fluidinteractive.com>
|
||||
*/
|
||||
|
||||
//traits.h
|
||||
|
||||
#ifndef MVL_TRAITS_H
|
||||
#define MVL_TRAITS_H
|
||||
|
||||
namespace mvl {
|
||||
|
||||
//simple promotion for now
|
||||
|
||||
//check if a type is a POD
|
||||
template<typename T>
|
||||
struct isPOD { enum { value = false }; };
|
||||
template<> struct isPOD<char> { enum { value = true }; };
|
||||
template<> struct isPOD<short> { enum { value = true }; };
|
||||
template<> struct isPOD<int> { enum { value = true }; };
|
||||
template<> struct isPOD<float> { enum { value = true }; };
|
||||
template<> struct isPOD<double> { enum { value = true }; };
|
||||
template<> struct isPOD<long double> { enum { value = true }; };
|
||||
|
||||
//
|
||||
template<bool Condition, typename T1, typename T2> struct ifThenElse { typedef T2 value_type; };
|
||||
template<typename T1, typename T2> struct ifThenElse<true, T1, T2> { typedef T1 value_type; };
|
||||
|
||||
template<typename T1, typename T2>
|
||||
struct promote_traits
|
||||
{
|
||||
typedef typename ifThenElse<isPOD<T1>::value, T2, T1>::value_type value_type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct promote_traits<T, T>
|
||||
{
|
||||
typedef T value_type;
|
||||
};
|
||||
|
||||
#define TRAITS_DEFINE_MACRO(T1, T2, TP) \
|
||||
template<> \
|
||||
struct promote_traits<T1, T2> \
|
||||
{ \
|
||||
typedef TP value_type; \
|
||||
}; \
|
||||
template<> \
|
||||
struct promote_traits<T2, T1> \
|
||||
{ \
|
||||
typedef TP value_type; \
|
||||
};
|
||||
|
||||
TRAITS_DEFINE_MACRO(int, float, float)
|
||||
TRAITS_DEFINE_MACRO(int, double, double)
|
||||
TRAITS_DEFINE_MACRO(int, long double, long double)
|
||||
|
||||
TRAITS_DEFINE_MACRO(float, double, double)
|
||||
TRAITS_DEFINE_MACRO(float, long double, long double)
|
||||
|
||||
TRAITS_DEFINE_MACRO(double, long double, long double)
|
||||
|
||||
#undef TRAITS_DEFINE_MACRO
|
||||
|
||||
|
||||
} // namespace mvl
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library Maya Plugin
|
||||
Copyright (c) 2008 Walt Disney Studios
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising
|
||||
from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must
|
||||
not claim that you wrote the original software. If you use this
|
||||
software in a product, an acknowledgment in the product documentation
|
||||
would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must
|
||||
not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
Written by: Nicola Candussi <nicola@fluidinteractive.com>
|
||||
*/
|
||||
|
||||
//traits.h
|
||||
|
||||
#ifndef MVL_TRAITS_H
|
||||
#define MVL_TRAITS_H
|
||||
|
||||
namespace mvl {
|
||||
|
||||
//simple promotion for now
|
||||
|
||||
//check if a type is a POD
|
||||
template<typename T>
|
||||
struct isPOD { enum { value = false }; };
|
||||
template<> struct isPOD<char> { enum { value = true }; };
|
||||
template<> struct isPOD<short> { enum { value = true }; };
|
||||
template<> struct isPOD<int> { enum { value = true }; };
|
||||
template<> struct isPOD<float> { enum { value = true }; };
|
||||
template<> struct isPOD<double> { enum { value = true }; };
|
||||
template<> struct isPOD<long double> { enum { value = true }; };
|
||||
|
||||
//
|
||||
template<bool Condition, typename T1, typename T2> struct ifThenElse { typedef T2 value_type; };
|
||||
template<typename T1, typename T2> struct ifThenElse<true, T1, T2> { typedef T1 value_type; };
|
||||
|
||||
template<typename T1, typename T2>
|
||||
struct promote_traits
|
||||
{
|
||||
typedef typename ifThenElse<isPOD<T1>::value, T2, T1>::value_type value_type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct promote_traits<T, T>
|
||||
{
|
||||
typedef T value_type;
|
||||
};
|
||||
|
||||
#define TRAITS_DEFINE_MACRO(T1, T2, TP) \
|
||||
template<> \
|
||||
struct promote_traits<T1, T2> \
|
||||
{ \
|
||||
typedef TP value_type; \
|
||||
}; \
|
||||
template<> \
|
||||
struct promote_traits<T2, T1> \
|
||||
{ \
|
||||
typedef TP value_type; \
|
||||
};
|
||||
|
||||
TRAITS_DEFINE_MACRO(int, float, float)
|
||||
TRAITS_DEFINE_MACRO(int, double, double)
|
||||
TRAITS_DEFINE_MACRO(int, long double, long double)
|
||||
|
||||
TRAITS_DEFINE_MACRO(float, double, double)
|
||||
TRAITS_DEFINE_MACRO(float, long double, long double)
|
||||
|
||||
TRAITS_DEFINE_MACRO(double, long double, long double)
|
||||
|
||||
#undef TRAITS_DEFINE_MACRO
|
||||
|
||||
|
||||
} // namespace mvl
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,61 +1,61 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library Maya Plugin
|
||||
Copyright (c) 2008 Walt Disney Studios
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising
|
||||
from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must
|
||||
not claim that you wrote the original software. If you use this
|
||||
software in a product, an acknowledgment in the product documentation
|
||||
would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must
|
||||
not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
Written by: Nicola Candussi <nicola@fluidinteractive.com>
|
||||
*/
|
||||
|
||||
//util.h
|
||||
|
||||
#ifndef MVL_UTIL_H
|
||||
#define MVL_UTIL_H
|
||||
|
||||
#include <cmath>
|
||||
#include "base.h"
|
||||
#include "traits.h"
|
||||
#include "vec.h"
|
||||
|
||||
namespace mvl {
|
||||
|
||||
//translation
|
||||
template<typename T>
|
||||
inline
|
||||
mat<T, 4, 4> translation(vec<T, 3> const& v)
|
||||
{
|
||||
return mat<T, 4, 4>(1, 0, 0, v(0),
|
||||
0, 1, 0, v(1),
|
||||
0, 0, 1, v(2),
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
||||
//scale
|
||||
template<typename T>
|
||||
inline
|
||||
mat<T, 4, 4> scale(vec<T, 3> const& v)
|
||||
{
|
||||
return mat<T, 4, 4> (v(0), 0, 0, 0,
|
||||
0, v(1), 0, 0,
|
||||
0, 0, v(2), 0,
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
||||
} // namespace mvl
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library Maya Plugin
|
||||
Copyright (c) 2008 Walt Disney Studios
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising
|
||||
from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must
|
||||
not claim that you wrote the original software. If you use this
|
||||
software in a product, an acknowledgment in the product documentation
|
||||
would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must
|
||||
not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
Written by: Nicola Candussi <nicola@fluidinteractive.com>
|
||||
*/
|
||||
|
||||
//util.h
|
||||
|
||||
#ifndef MVL_UTIL_H
|
||||
#define MVL_UTIL_H
|
||||
|
||||
#include <cmath>
|
||||
#include "base.h"
|
||||
#include "traits.h"
|
||||
#include "vec.h"
|
||||
|
||||
namespace mvl {
|
||||
|
||||
//translation
|
||||
template<typename T>
|
||||
inline
|
||||
mat<T, 4, 4> translation(vec<T, 3> const& v)
|
||||
{
|
||||
return mat<T, 4, 4>(1, 0, 0, v(0),
|
||||
0, 1, 0, v(1),
|
||||
0, 0, 1, v(2),
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
||||
//scale
|
||||
template<typename T>
|
||||
inline
|
||||
mat<T, 4, 4> scale(vec<T, 3> const& v)
|
||||
{
|
||||
return mat<T, 4, 4> (v(0), 0, 0, 0,
|
||||
0, v(1), 0, 0,
|
||||
0, 0, v(2), 0,
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
||||
} // namespace mvl
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,347 +1,347 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library Maya Plugin
|
||||
Copyright (c) 2008 Walt Disney Studios
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising
|
||||
from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must
|
||||
not claim that you wrote the original software. If you use this
|
||||
software in a product, an acknowledgment in the product documentation
|
||||
would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must
|
||||
not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
Written by: Nicola Candussi <nicola@fluidinteractive.com>
|
||||
*/
|
||||
|
||||
//vec.h
|
||||
|
||||
#ifndef MVL_VEC_H
|
||||
#define MVL_VEC_H
|
||||
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
#include "base.h"
|
||||
#include "traits.h"
|
||||
|
||||
namespace mvl {
|
||||
|
||||
template<typename T, std::size_t Sz>
|
||||
class vec
|
||||
{
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T& reference;
|
||||
typedef T const& const_reference;
|
||||
typedef T* iterator;
|
||||
typedef T const* const_iterator;
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
public:
|
||||
enum {
|
||||
Size = Sz,
|
||||
};
|
||||
|
||||
public:
|
||||
//constructors
|
||||
explicit vec() {}
|
||||
|
||||
template<typename T2>
|
||||
vec(vec<T2, Size> const& v)
|
||||
{
|
||||
*this = v;
|
||||
}
|
||||
|
||||
explicit vec(value_type val)
|
||||
{
|
||||
for(int i = 0; i < Size; ++i) {
|
||||
m_data[i] = val;
|
||||
}
|
||||
}
|
||||
|
||||
explicit vec(value_type x0, value_type x1)
|
||||
{
|
||||
m_data[0] = x0; m_data[1] = x1;
|
||||
}
|
||||
|
||||
explicit vec(value_type x0, value_type x1, value_type x2)
|
||||
{
|
||||
m_data[0] = x0; m_data[1] = x1; m_data[2] = x2;
|
||||
}
|
||||
|
||||
explicit vec(value_type x0, value_type x1, value_type x2, value_type x3)
|
||||
{
|
||||
m_data[0] = x0; m_data[1] = x1; m_data[2] = x2; m_data[3] = x3;
|
||||
}
|
||||
|
||||
explicit vec(value_type x0, value_type x1, value_type x2, value_type x3, value_type x4)
|
||||
{
|
||||
m_data[0] = x0; m_data[1] = x1; m_data[2] = x2; m_data[3] = x3; m_data[4] = x4;
|
||||
}
|
||||
|
||||
explicit vec(value_type x0, value_type x1, value_type x2, value_type x3, value_type x4, value_type x5)
|
||||
{
|
||||
m_data[0] = x0; m_data[1] = x1; m_data[2] = x2; m_data[3] = x3; m_data[4] = x4; m_data[5] = x5;
|
||||
}
|
||||
|
||||
public:
|
||||
//data access
|
||||
value_type operator[](std::size_t i) const { return m_data[i]; }
|
||||
reference operator[](std::size_t i) { return m_data[i]; }
|
||||
|
||||
value_type operator()(std::size_t i) const { return m_data[i]; }
|
||||
reference operator()(std::size_t i) { return m_data[i]; }
|
||||
|
||||
public:
|
||||
//stl
|
||||
static std::size_t size() { return Size; }
|
||||
static std::size_t max_size() { return Size; }
|
||||
static bool empty() { return false; }
|
||||
|
||||
iterator begin() { return m_data; }
|
||||
iterator end() { return m_data + Size; }
|
||||
const_iterator begin() const { return m_data; }
|
||||
const_iterator end() const { return m_data + Size; }
|
||||
reverse_iterator rbegin() { return reverse_iterator(end()); }
|
||||
reverse_iterator rend() { return reverse_iterator(begin()); }
|
||||
const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
|
||||
const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
|
||||
|
||||
value_type front() { return m_data[0]; }
|
||||
value_type back() { return m_data[Size - 1]; }
|
||||
const_reference front() const { return m_data[0]; }
|
||||
const_reference back() const { return m_data[Size - 1]; }
|
||||
|
||||
friend std::ostream& operator << (std::ostream& out, vec const& v) {
|
||||
out << "(";
|
||||
for(size_t i = 0; i < Size - 1; i++) {
|
||||
out << v(i) << ", ";
|
||||
}
|
||||
out << v(Size - 1) << ")";
|
||||
return out;
|
||||
}
|
||||
|
||||
public:
|
||||
//assignment
|
||||
vec& operator=(vec const& rhs) {
|
||||
for(int i = 0; i < Size; ++i) {
|
||||
m_data[i] = rhs[i];
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T2>
|
||||
vec& operator=(vec<T2, Size> const& rhs) {
|
||||
for(int i = 0; i < Size; ++i) {
|
||||
m_data[i] = rhs[i];
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
T m_data[Size];
|
||||
};
|
||||
|
||||
|
||||
//assignment operators
|
||||
// OP(vec<T1>, vec<T2>)
|
||||
// OP(vec<T>, T)
|
||||
|
||||
#define VEC_IMPLEMENT_MACRO(OP) \
|
||||
template<typename T1, typename T2, std::size_t Sz> \
|
||||
inline \
|
||||
vec<T1, Sz>& \
|
||||
operator OP(vec<T1, Sz>& lhs, vec<T2, Sz> const& rhs) { \
|
||||
for(int i = 0; i < Sz; ++i) { \
|
||||
lhs[i] OP rhs[i]; \
|
||||
} \
|
||||
return lhs; \
|
||||
} \
|
||||
\
|
||||
template<typename T, std::size_t Sz> \
|
||||
inline \
|
||||
vec<T, Sz>& \
|
||||
operator OP(vec<T, Sz>& lhs, T const& rhs) { \
|
||||
for(int i = 0; i < Sz; ++i) { \
|
||||
lhs[i] OP rhs; \
|
||||
} \
|
||||
return lhs; \
|
||||
} \
|
||||
|
||||
VEC_IMPLEMENT_MACRO(+=)
|
||||
VEC_IMPLEMENT_MACRO(-=)
|
||||
VEC_IMPLEMENT_MACRO(*=)
|
||||
VEC_IMPLEMENT_MACRO(/=)
|
||||
|
||||
#undef VEC_IMPLEMENT_MACRO
|
||||
|
||||
//operator + (vec, vec)
|
||||
template<typename T1, typename T2, std::size_t Sz>
|
||||
inline
|
||||
vec<typename promote_traits<T1, T2>::value_type, Sz>
|
||||
operator + (vec<T1, Sz> const& lhs, vec<T2, Sz> const& rhs)
|
||||
{
|
||||
vec<typename promote_traits<T1, T2>::value_type, Sz> res;
|
||||
for(int i = 0; i < Sz; ++i) {
|
||||
res[i] = lhs[i] + rhs[i];
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//operator - (vec, vec)
|
||||
template<typename T1, typename T2, std::size_t Sz>
|
||||
inline
|
||||
vec<typename promote_traits<T1, T2>::value_type, Sz>
|
||||
operator - (vec<T1, Sz> const& lhs, vec<T2, Sz> const& rhs)
|
||||
{
|
||||
vec<typename promote_traits<T1, T2>::value_type, Sz> res;
|
||||
for(int i = 0; i < Sz; ++i) {
|
||||
res[i] = lhs[i] - rhs[i];
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//operator * (vec, POD)
|
||||
template<typename T1, typename T2, std::size_t Sz>
|
||||
inline
|
||||
vec<typename promote_traits<T1, T2>::value_type, Sz>
|
||||
operator * (vec<T1, Sz> const& lhs, T2 const& rhs) {
|
||||
vec<typename promote_traits<T1, T2>::value_type, Sz> res;
|
||||
for(int i = 0; i < Sz; ++i) {
|
||||
res[i] = lhs[i] * rhs;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//operator * (POD, vec)
|
||||
template<typename T1, typename T2, std::size_t Sz>
|
||||
inline
|
||||
vec<typename promote_traits<T1, T2>::value_type, Sz>
|
||||
operator * (T1 const& lhs, vec<T2, Sz> const& rhs) {
|
||||
vec<typename promote_traits<T1, T2>::value_type, Sz> res;
|
||||
for(int i = 0; i < Sz; ++i) {
|
||||
res[i] = lhs * rhs[i];
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//operator / (vec, POD)
|
||||
template<typename T1, typename T2, std::size_t Sz>
|
||||
inline
|
||||
vec<typename promote_traits<T1, T2>::value_type, Sz>
|
||||
operator / (vec<T1, Sz> const& lhs, T2 const& rhs) {
|
||||
vec<typename promote_traits<T1, T2>::value_type, Sz> res;
|
||||
for(int i = 0; i < Sz; ++i) {
|
||||
res[i] = lhs[i] / rhs;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//element_prod(vec, vec)
|
||||
template<typename T1, typename T2, std::size_t Sz>
|
||||
inline
|
||||
vec<typename promote_traits<T1, T2>::value_type, Sz>
|
||||
element_prod(vec<T1, Sz> const& lhs, vec<T2, Sz> const& rhs) {
|
||||
vec<typename promote_traits<T1, T2>::value_type, Sz> res;
|
||||
for(int i = 0; i < Sz; ++i) {
|
||||
res[i] = lhs[i] * rhs[i];
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//element_div(vec, vec)
|
||||
template<typename T1, typename T2, std::size_t Sz>
|
||||
inline
|
||||
vec<typename promote_traits<T1, T2>::value_type, Sz>
|
||||
element_div(vec<T1, Sz> const& lhs, vec<T2, Sz> const& rhs) {
|
||||
vec<typename promote_traits<T1, T2>::value_type, Sz> res;
|
||||
for(int i = 0; i < Sz; ++i) {
|
||||
res[i] = lhs[i] / rhs[i];
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//unary operator -(expr_vec)
|
||||
template<typename T, std::size_t Sz>
|
||||
inline
|
||||
vec<T, Sz>
|
||||
operator -(vec<T, Sz> const& rhs) {
|
||||
vec<T, Sz> res;
|
||||
for(int i = 0; i < Sz; ++i) {
|
||||
res[i] = -rhs[i];
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//dot product
|
||||
template<typename T1, typename T2, std::size_t Sz>
|
||||
inline
|
||||
typename promote_traits<T1, T2>::value_type
|
||||
dot(vec<T1, Sz> const& lhs, vec<T2, Sz> const& rhs)
|
||||
{
|
||||
typename promote_traits<T1, T2>::value_type res(0);
|
||||
for(int i = 0; i < Sz; ++i) {
|
||||
res += rhs[i] * lhs[i];
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
//cross product
|
||||
template<typename T1, typename T2>
|
||||
inline
|
||||
vec<typename promote_traits<T1, T2>::value_type, 3>
|
||||
cross(vec<T1, 3> const& lhs, vec<T2, 3> const& rhs) {
|
||||
typedef typename promote_traits<T1, T2>::value_type value_type;
|
||||
return vec<value_type, 3>(lhs(1)*rhs(2) - rhs(1)*lhs(2),
|
||||
rhs(0)*lhs(2) - lhs(0)*rhs(2),
|
||||
lhs(0)*rhs(1) - rhs(0)*lhs(1));
|
||||
}
|
||||
|
||||
//length of the vector
|
||||
template<typename T, std::size_t Sz>
|
||||
inline T
|
||||
norm2(vec<T, Sz> const& rhs)
|
||||
{
|
||||
return static_cast<T>(sqrt(dot(rhs, rhs)));
|
||||
}
|
||||
|
||||
//length of the vector squared
|
||||
template<typename T, std::size_t Sz>
|
||||
inline T
|
||||
norm_squared(vec<T, Sz> const& rhs)
|
||||
{
|
||||
return dot(rhs, rhs);
|
||||
}
|
||||
|
||||
//normalize the vector
|
||||
template<typename T, std::size_t Sz>
|
||||
inline
|
||||
vec<T, Sz>
|
||||
normalize(vec<T, Sz> const& v) {
|
||||
typedef T value_type;
|
||||
T tmp = norm2(v);
|
||||
if(tmp == value_type(0)) {
|
||||
tmp = value_type(0);
|
||||
} else {
|
||||
tmp = value_type(1) / tmp;
|
||||
}
|
||||
vec<T, Sz> res;
|
||||
for(int i = 0; i < Sz; ++i) {
|
||||
res[i] = v[i] * tmp;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
} //namespace mvl
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library Maya Plugin
|
||||
Copyright (c) 2008 Walt Disney Studios
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising
|
||||
from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must
|
||||
not claim that you wrote the original software. If you use this
|
||||
software in a product, an acknowledgment in the product documentation
|
||||
would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must
|
||||
not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
Written by: Nicola Candussi <nicola@fluidinteractive.com>
|
||||
*/
|
||||
|
||||
//vec.h
|
||||
|
||||
#ifndef MVL_VEC_H
|
||||
#define MVL_VEC_H
|
||||
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
#include "base.h"
|
||||
#include "traits.h"
|
||||
|
||||
namespace mvl {
|
||||
|
||||
template<typename T, std::size_t Sz>
|
||||
class vec
|
||||
{
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T& reference;
|
||||
typedef T const& const_reference;
|
||||
typedef T* iterator;
|
||||
typedef T const* const_iterator;
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
public:
|
||||
enum {
|
||||
Size = Sz,
|
||||
};
|
||||
|
||||
public:
|
||||
//constructors
|
||||
explicit vec() {}
|
||||
|
||||
template<typename T2>
|
||||
vec(vec<T2, Size> const& v)
|
||||
{
|
||||
*this = v;
|
||||
}
|
||||
|
||||
explicit vec(value_type val)
|
||||
{
|
||||
for(int i = 0; i < Size; ++i) {
|
||||
m_data[i] = val;
|
||||
}
|
||||
}
|
||||
|
||||
explicit vec(value_type x0, value_type x1)
|
||||
{
|
||||
m_data[0] = x0; m_data[1] = x1;
|
||||
}
|
||||
|
||||
explicit vec(value_type x0, value_type x1, value_type x2)
|
||||
{
|
||||
m_data[0] = x0; m_data[1] = x1; m_data[2] = x2;
|
||||
}
|
||||
|
||||
explicit vec(value_type x0, value_type x1, value_type x2, value_type x3)
|
||||
{
|
||||
m_data[0] = x0; m_data[1] = x1; m_data[2] = x2; m_data[3] = x3;
|
||||
}
|
||||
|
||||
explicit vec(value_type x0, value_type x1, value_type x2, value_type x3, value_type x4)
|
||||
{
|
||||
m_data[0] = x0; m_data[1] = x1; m_data[2] = x2; m_data[3] = x3; m_data[4] = x4;
|
||||
}
|
||||
|
||||
explicit vec(value_type x0, value_type x1, value_type x2, value_type x3, value_type x4, value_type x5)
|
||||
{
|
||||
m_data[0] = x0; m_data[1] = x1; m_data[2] = x2; m_data[3] = x3; m_data[4] = x4; m_data[5] = x5;
|
||||
}
|
||||
|
||||
public:
|
||||
//data access
|
||||
value_type operator[](std::size_t i) const { return m_data[i]; }
|
||||
reference operator[](std::size_t i) { return m_data[i]; }
|
||||
|
||||
value_type operator()(std::size_t i) const { return m_data[i]; }
|
||||
reference operator()(std::size_t i) { return m_data[i]; }
|
||||
|
||||
public:
|
||||
//stl
|
||||
static std::size_t size() { return Size; }
|
||||
static std::size_t max_size() { return Size; }
|
||||
static bool empty() { return false; }
|
||||
|
||||
iterator begin() { return m_data; }
|
||||
iterator end() { return m_data + Size; }
|
||||
const_iterator begin() const { return m_data; }
|
||||
const_iterator end() const { return m_data + Size; }
|
||||
reverse_iterator rbegin() { return reverse_iterator(end()); }
|
||||
reverse_iterator rend() { return reverse_iterator(begin()); }
|
||||
const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
|
||||
const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
|
||||
|
||||
value_type front() { return m_data[0]; }
|
||||
value_type back() { return m_data[Size - 1]; }
|
||||
const_reference front() const { return m_data[0]; }
|
||||
const_reference back() const { return m_data[Size - 1]; }
|
||||
|
||||
friend std::ostream& operator << (std::ostream& out, vec const& v) {
|
||||
out << "(";
|
||||
for(size_t i = 0; i < Size - 1; i++) {
|
||||
out << v(i) << ", ";
|
||||
}
|
||||
out << v(Size - 1) << ")";
|
||||
return out;
|
||||
}
|
||||
|
||||
public:
|
||||
//assignment
|
||||
vec& operator=(vec const& rhs) {
|
||||
for(int i = 0; i < Size; ++i) {
|
||||
m_data[i] = rhs[i];
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T2>
|
||||
vec& operator=(vec<T2, Size> const& rhs) {
|
||||
for(int i = 0; i < Size; ++i) {
|
||||
m_data[i] = rhs[i];
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
T m_data[Size];
|
||||
};
|
||||
|
||||
|
||||
//assignment operators
|
||||
// OP(vec<T1>, vec<T2>)
|
||||
// OP(vec<T>, T)
|
||||
|
||||
#define VEC_IMPLEMENT_MACRO(OP) \
|
||||
template<typename T1, typename T2, std::size_t Sz> \
|
||||
inline \
|
||||
vec<T1, Sz>& \
|
||||
operator OP(vec<T1, Sz>& lhs, vec<T2, Sz> const& rhs) { \
|
||||
for(int i = 0; i < Sz; ++i) { \
|
||||
lhs[i] OP rhs[i]; \
|
||||
} \
|
||||
return lhs; \
|
||||
} \
|
||||
\
|
||||
template<typename T, std::size_t Sz> \
|
||||
inline \
|
||||
vec<T, Sz>& \
|
||||
operator OP(vec<T, Sz>& lhs, T const& rhs) { \
|
||||
for(int i = 0; i < Sz; ++i) { \
|
||||
lhs[i] OP rhs; \
|
||||
} \
|
||||
return lhs; \
|
||||
} \
|
||||
|
||||
VEC_IMPLEMENT_MACRO(+=)
|
||||
VEC_IMPLEMENT_MACRO(-=)
|
||||
VEC_IMPLEMENT_MACRO(*=)
|
||||
VEC_IMPLEMENT_MACRO(/=)
|
||||
|
||||
#undef VEC_IMPLEMENT_MACRO
|
||||
|
||||
//operator + (vec, vec)
|
||||
template<typename T1, typename T2, std::size_t Sz>
|
||||
inline
|
||||
vec<typename promote_traits<T1, T2>::value_type, Sz>
|
||||
operator + (vec<T1, Sz> const& lhs, vec<T2, Sz> const& rhs)
|
||||
{
|
||||
vec<typename promote_traits<T1, T2>::value_type, Sz> res;
|
||||
for(int i = 0; i < Sz; ++i) {
|
||||
res[i] = lhs[i] + rhs[i];
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//operator - (vec, vec)
|
||||
template<typename T1, typename T2, std::size_t Sz>
|
||||
inline
|
||||
vec<typename promote_traits<T1, T2>::value_type, Sz>
|
||||
operator - (vec<T1, Sz> const& lhs, vec<T2, Sz> const& rhs)
|
||||
{
|
||||
vec<typename promote_traits<T1, T2>::value_type, Sz> res;
|
||||
for(int i = 0; i < Sz; ++i) {
|
||||
res[i] = lhs[i] - rhs[i];
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//operator * (vec, POD)
|
||||
template<typename T1, typename T2, std::size_t Sz>
|
||||
inline
|
||||
vec<typename promote_traits<T1, T2>::value_type, Sz>
|
||||
operator * (vec<T1, Sz> const& lhs, T2 const& rhs) {
|
||||
vec<typename promote_traits<T1, T2>::value_type, Sz> res;
|
||||
for(int i = 0; i < Sz; ++i) {
|
||||
res[i] = lhs[i] * rhs;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//operator * (POD, vec)
|
||||
template<typename T1, typename T2, std::size_t Sz>
|
||||
inline
|
||||
vec<typename promote_traits<T1, T2>::value_type, Sz>
|
||||
operator * (T1 const& lhs, vec<T2, Sz> const& rhs) {
|
||||
vec<typename promote_traits<T1, T2>::value_type, Sz> res;
|
||||
for(int i = 0; i < Sz; ++i) {
|
||||
res[i] = lhs * rhs[i];
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//operator / (vec, POD)
|
||||
template<typename T1, typename T2, std::size_t Sz>
|
||||
inline
|
||||
vec<typename promote_traits<T1, T2>::value_type, Sz>
|
||||
operator / (vec<T1, Sz> const& lhs, T2 const& rhs) {
|
||||
vec<typename promote_traits<T1, T2>::value_type, Sz> res;
|
||||
for(int i = 0; i < Sz; ++i) {
|
||||
res[i] = lhs[i] / rhs;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//element_prod(vec, vec)
|
||||
template<typename T1, typename T2, std::size_t Sz>
|
||||
inline
|
||||
vec<typename promote_traits<T1, T2>::value_type, Sz>
|
||||
element_prod(vec<T1, Sz> const& lhs, vec<T2, Sz> const& rhs) {
|
||||
vec<typename promote_traits<T1, T2>::value_type, Sz> res;
|
||||
for(int i = 0; i < Sz; ++i) {
|
||||
res[i] = lhs[i] * rhs[i];
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//element_div(vec, vec)
|
||||
template<typename T1, typename T2, std::size_t Sz>
|
||||
inline
|
||||
vec<typename promote_traits<T1, T2>::value_type, Sz>
|
||||
element_div(vec<T1, Sz> const& lhs, vec<T2, Sz> const& rhs) {
|
||||
vec<typename promote_traits<T1, T2>::value_type, Sz> res;
|
||||
for(int i = 0; i < Sz; ++i) {
|
||||
res[i] = lhs[i] / rhs[i];
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//unary operator -(expr_vec)
|
||||
template<typename T, std::size_t Sz>
|
||||
inline
|
||||
vec<T, Sz>
|
||||
operator -(vec<T, Sz> const& rhs) {
|
||||
vec<T, Sz> res;
|
||||
for(int i = 0; i < Sz; ++i) {
|
||||
res[i] = -rhs[i];
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//dot product
|
||||
template<typename T1, typename T2, std::size_t Sz>
|
||||
inline
|
||||
typename promote_traits<T1, T2>::value_type
|
||||
dot(vec<T1, Sz> const& lhs, vec<T2, Sz> const& rhs)
|
||||
{
|
||||
typename promote_traits<T1, T2>::value_type res(0);
|
||||
for(int i = 0; i < Sz; ++i) {
|
||||
res += rhs[i] * lhs[i];
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
//cross product
|
||||
template<typename T1, typename T2>
|
||||
inline
|
||||
vec<typename promote_traits<T1, T2>::value_type, 3>
|
||||
cross(vec<T1, 3> const& lhs, vec<T2, 3> const& rhs) {
|
||||
typedef typename promote_traits<T1, T2>::value_type value_type;
|
||||
return vec<value_type, 3>(lhs(1)*rhs(2) - rhs(1)*lhs(2),
|
||||
rhs(0)*lhs(2) - lhs(0)*rhs(2),
|
||||
lhs(0)*rhs(1) - rhs(0)*lhs(1));
|
||||
}
|
||||
|
||||
//length of the vector
|
||||
template<typename T, std::size_t Sz>
|
||||
inline T
|
||||
norm2(vec<T, Sz> const& rhs)
|
||||
{
|
||||
return static_cast<T>(sqrt(dot(rhs, rhs)));
|
||||
}
|
||||
|
||||
//length of the vector squared
|
||||
template<typename T, std::size_t Sz>
|
||||
inline T
|
||||
norm_squared(vec<T, Sz> const& rhs)
|
||||
{
|
||||
return dot(rhs, rhs);
|
||||
}
|
||||
|
||||
//normalize the vector
|
||||
template<typename T, std::size_t Sz>
|
||||
inline
|
||||
vec<T, Sz>
|
||||
normalize(vec<T, Sz> const& v) {
|
||||
typedef T value_type;
|
||||
T tmp = norm2(v);
|
||||
if(tmp == value_type(0)) {
|
||||
tmp = value_type(0);
|
||||
} else {
|
||||
tmp = value_type(1) / tmp;
|
||||
}
|
||||
vec<T, Sz> res;
|
||||
for(int i = 0; i < Sz; ++i) {
|
||||
res[i] = v[i] * tmp;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
} //namespace mvl
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user