📄 vmath
字号:
return result;
}
// Generate a (4x4) orthogonal projection matrix (standard -- maps to z=0 plane)
static const Matrix<4, 4, T> genProjectScaleOrtho(const T & xScale, const T & yScale)
{
Matrix<4, 4, T> result;
result.fill(static_cast<T>(0));
result(0,0) = xScale;
result(1,1) = yScale;
result(3,3) = 1;
return result;
}
// Generate a (4x4) orthogonal projection matrix (translates to screen coordinates, maps to z=0 plane)
static const Matrix<4, 4, T> genProjectScreenOrtho(const T & width, const T & height)
{
Matrix<4, 4, T> result;
result.fill(static_cast<T>(0));
result(0,0) = 2 / width;
result(1,1) = -2 / height;
result(3,3) = 1;
result(3,0) = -1;
result(3,1) = 1;
return result;
}
// Extract the X vector from the matrix
//
// Note that the matrix must be a minimum of 3x3
inline Matrix<N, 1, T> extractXVector() const
{
TemplateAssert(M > 0);
Matrix<N, 1, T> result;
for (unsigned int i = 0; i < N; i++)
{
result(i,0) = (*this)(i,0);
}
return result;
}
// Extract the Y vector from the matrix
//
// Note that the matrix must be a minimum of 3x3
inline Matrix<N, 1, T> extractYVector() const
{
TemplateAssert(M > 1);
Matrix<N, 1, T> result;
for (unsigned int i = 0; i < N; i++)
{
result(i,0) = (*this)(i,1);
}
return result;
}
// Extract the Z vector from the matrix
//
// Note that the matrix must be a minimum of 3x3
inline Matrix<N, 1, T> extractZVector() const
{
TemplateAssert(M > 2);
Matrix<N, 1, T> result;
for (unsigned int i = 0; i < N; i++)
{
result(i,0) = (*this)(i,2);
}
return result;
}
// Extract the W vector from the matrix
//
// Note that the matrix must be a minimum of 4x4
inline Matrix<N, 1, T> extractWVector() const
{
TemplateAssert(M > 3);
Matrix<N, 1, T> result;
for (unsigned int i = 0; i < N; i++)
{
result(i,0) = (*this)(i,3);
}
return result;
}
// Extract the translation from the matrix
inline Matrix<N,1, T> extractTranslation() const
{
TemplateAssert(M <= N);
Matrix<N, 1, T> result;
for (unsigned int i = 0; i < M; i++)
{
result(i,0) = (*this)(N-1,i);
}
return result;
}
// Replace the X vector within matrix
//
// Note that the matrix must be a minimum of 3x3
inline void setXVector(const Matrix<N, 1, T> & m)
{
TemplateAssert(N > 0);
for (unsigned int i = 0; i < N; i++)
{
(*this)(i,0) = m(i,0);
}
}
// Replace the Y vector within matrix
//
// Note that the matrix must be a minimum of 3x3
inline void setYVector(const Matrix<N, 1, T> & m)
{
TemplateAssert(N > 1);
for (unsigned int i = 0; i < N; i++)
{
(*this)(i,1) = m(i,0);
}
}
// Replace the Z vector within matrix
//
// Note that the matrix must be a minimum of 3x3
inline void setZVector(const Matrix<N, 1, T> & m)
{
TemplateAssert(N > 2);
for (unsigned int i = 0; i < N; i++)
{
(*this)(i,2) = m(i,0);
}
}
// Replace the W vector within matrix
//
// Note that the matrix must be a minimum of 3x3
inline void setWVector(const Matrix<N, 1, T> & m)
{
TemplateAssert(N > 3);
for (unsigned int i = 0; i < N; i++)
{
(*this)(i,3) = m(i,0);
}
}
// Vector length calculation (squared)
//
// Specialized for Nx1 matrices (i.e. vectors)
inline const T lengthSquared() const
{
TemplateAssert(M == 1);
return dot(*this);
}
// Vector length calculation
//
// Specialized for Nx1 matrices (i.e. vectors)
inline const T length() const
{
TemplateAssert(M == 1);
return static_cast<T>(sqrt(lengthSquared()));
}
// Vector length
//
// Specialized for Nx1 matrices (i.e. vectors)
inline void setLength(const T & len)
{
TemplateAssert(M == 1);
T l = len / length();
for (unsigned int i = 0; i < N; ++i)
{
data()[i] *= l;
}
}
// Vector length
//
// Specialized for Nx1 matrices (i.e. vectors)
inline T distance(const Matrix & m) const
{
TemplateAssert(M == 1);
Matrix temp = *this - m;
return temp.length();
}
// Normalize
//
// Specialized for Nx1 matrices (i.e. vectors)
inline void normalize()
{
setLength(static_cast<T>(1));
}
// Normalize an orthogonal matrix (i.e. make sure the internal vectors are all perpendicular)
//
// Note that the matrix must be a 3x3, due to the fact that this routine uses a cross product
inline void orthoNormalize()
{
TemplateAssert(N == 3 && M == 3);
Matrix<N, 1, T> xVector = extractXVector();
Matrix<N, 1, T> yVector = extractYVector();
Matrix<N, 1, T> zVector = extractZVector();
xVector -= yVector * (xVector * yVector);
xVector -= zVector * (xVector * zVector);
xVector.normalize();
yVector -= xVector * (yVector * xVector);
yVector -= zVector * (yVector * zVector);
yVector.normalize();
zVector = xVector % yVector;
setXVector(xVector);
setYVector(yVector);
setZVector(zVector);
}
// Absolute value of all components
inline void abs()
{
for (unsigned int i = 0; i < N*M; i++)
_data[i] = static_cast<T>(fabs(static_cast<double>(_data[i])));
}
// Saturate all components
inline void saturate(const T & min, const T & max)
{
for (unsigned int i = 0; i < N*M; i++)
{
if (_data[i] < min) _data[i] = min;
if (_data[i] > max) _data[i] = max;
}
}
// Specialized 'convenience accessors' for vectors, points, etc.
//
// Note that the matrix must have a value of N large enough to store the value
// in question and M must always be 1.
inline const T & x() const {TemplateAssert(N > 0 && M == 1); return _data[0];}
inline T & x() {TemplateAssert(N > 0 && M == 1); return _data[0];}
inline const T & y() const {TemplateAssert(N > 1 && M == 1); return _data[1];}
inline T & y() {TemplateAssert(N > 1 && M == 1); return _data[1];}
inline const T & z() const {TemplateAssert(N > 2 && M == 1); return _data[2];}
inline T & z() {TemplateAssert(N > 2 && M == 1); return _data[2];}
inline const T & w() const {TemplateAssert(N > 3 && M == 1); return _data[3];}
inline T & w() {TemplateAssert(N > 3 && M == 1); return _data[3];}
// UVs (simply a convenience thing)
inline const T & u() const {return x();}
inline T & u() {return x();}
inline const T & v() const {return y();}
inline T & v() {return y();}
// For use with colors (simply a convenience thing)
inline const T & r() const {return x();}
inline T & r() {return x();}
inline const T & g() const {return y();}
inline T & g() {return y();}
inline const T & b() const {return z();}
inline T & b() {return z();}
inline const T & a() const {return w();}
inline T & a() {return w();}
inline const unsigned int rgb() const
{
TemplateAssert(N > 2 && M == 1);
unsigned int nr = static_cast<unsigned int>(r() * static_cast<T>(255));
unsigned int ng = static_cast<unsigned int>(g() * static_cast<T>(255));
unsigned int nb = static_cast<unsigned int>(b() * static_cast<T>(255));
return (nr << 16) | (ng << 8) | nb;
}
inline const unsigned int argb() const
{
TemplateAssert(N > 3 && M == 1);
unsigned int na = static_cast<unsigned int>(a() * static_cast<T>(255));
unsigned int nr = static_cast<unsigned int>(r() * static_cast<T>(255));
unsigned int ng = static_cast<unsigned int>(g() * static_cast<T>(255));
unsigned int nb = static_cast<unsigned int>(b() * static_cast<T>(255));
return (na << 24) | (nr << 16) | (ng << 8) | nb;
}
inline const unsigned int bgr() const
{
TemplateAssert(N > 2 && M == 1);
unsigned int nr = static_cast<unsigned int>(r() * static_cast<T>(255));
unsigned int ng = static_cast<unsigned int>(g() * static_cast<T>(255));
unsigned int nb = static_cast<unsigned int>(b() * static_cast<T>(255));
return (nb << 16) | (ng << 8) | nr;
}
inline const unsigned int abgr() const
{
TemplateAssert(N > 3 && M == 1);
unsigned int na = static_cast<unsigned int>(a() * static_cast<T>(255));
unsigned int nr = static_cast<unsigned int>(r() * static_cast<T>(255));
unsigned int ng = static_cast<unsigned int>(g() * static_cast<T>(255));
unsigned int nb = static_cast<unsigned int>(b() * static_cast<T>(255));
return (na << 24) | (nb << 16) | (ng << 8) | nr;
}
// Polar & spherical coordinates (simply a convenience thing)
inline const T & phi() const {return x();} // phi = rotational distance from the axis (like lattitude)
inline T & phi() {return x();}
inline const T & theta() const {return y();} // theta = rotation around the axis (like longitude)
inline T & theta() {return y();}
inline const T & rho() const {return z();} // rho = distance from origin
inline T & rho() {return z();}
// Only use this if you need to... prefer operator(int,int) for access
inline const T *data() const {return _data;}
inline T *data() {return _data;}
// Dimensions
inline unsigned int width() const {return N;}
inline unsigned int height() const {return M;}
// Debugging functions
#ifdef _MSC_VER
inline void debugTrace() const
{
for (unsigned int i = 0; i < N; i++)
{
char temp[90];
strcpy(temp, "[");
for (unsigned int j = 0; j < M; j++)
{
char t[90];
sprintf(t, "%12.5f", (*this)(i,j));
strcat(temp, t);
}
strcat(temp, " ]\n");
TRACE(temp);
}
TRACE("\n");
}
#endif
#ifdef _H_LOGGER
inline void debugLog(const char *title) const
{
LOGBLOCK(title);
for (unsigned int i = 0; i < N; i++)
{
char temp[90];
strcpy(temp, "[");
for (unsigned int j = 0; j < M; j++)
{
char t[90];
sprintf(t, "%12.5f", (*this)(i,j));
strcat(temp, t);
}
strcat(temp, " ]");
LOG(temp);
}
}
#endif
private:
T _data[N*M];
};
// ---------------------------------------------------------------------------------------------------------------------------------
// Convenience types - Most common uses
// ---------------------------------------------------------------------------------------------------------------------------------
typedef Matrix<3, 3> Matrix3;
typedef Matrix<4, 4> Matrix4;
typedef Matrix<2, 1> Vector2;
typedef Matrix<3, 1> Vector3;
typedef Matrix<4, 1> Vector4;
typedef Matrix<2, 1> Point2;
typedef Matrix<3, 1> Point3;
typedef Matrix<4, 1> Point4;
typedef Matrix<2, 1> Color2;
typedef Matrix<3, 1> Color3;
typedef Matrix<4, 1> Color4;
typedef fstl::array<Matrix3> Matrix3Array;
typedef fstl::list<Matrix3> Matrix3List;
typedef fstl::array<Matrix4> Matrix4Array;
typedef fstl::list<Matrix4> Matrix4List;
typedef fstl::array<Vector2, 3> Vector2Array;
typedef fstl::list<Vector2, 3> Vector2List;
typedef fstl::array<Vector3, 3> Vector3Array;
typedef fstl::list<Vector3, 3> Vector3List;
typedef fstl::array<Vector4, 3> Vector4Array;
typedef fstl::list<Vector4, 3> Vector4List;
typedef fstl::array<Point2, 3> Point2Array;
typedef fstl::list<Point2, 3> Point2List;
typedef fstl::array<Point3, 3> Point3Array;
typedef fstl::list<Point3, 3> Point3List;
typedef fstl::array<Point4, 3> Point4Array;
typedef fstl::list<Point4, 3> Point4List;
typedef fstl::array<Color2, 3> Color2Array;
typedef fstl::list<Color2, 3> Color2List;
typedef fstl::array<Color3, 3> Color3Array;
typedef fstl::list<Color3, 3> Color3List;
typedef fstl::array<Color4, 3> Color4Array;
typedef fstl::list<Color4, 3> Color4List;
// ---------------------------------------------------------------------------------------------------------------------------------
// Mixed-mode global overrides
// ---------------------------------------------------------------------------------------------------------------------------------
template <unsigned int N, unsigned int M, class T>
inline const Matrix<N, M, T> operator *(const T & value, const Matrix<N, M, T> & m) {return m * value;}
template <unsigned int N, unsigned int M, class T>
inline const Matrix<N, M, T> operator /(const T & value, const Matrix<N, M, T> & m) {return m.inverseDivide(value);}
template <unsigned int N, unsigned int M, class T>
inline const Matrix<N, M, T> operator +(const T & value, const Matrix<N, M, T> & m) {return m + value;}
template <unsigned int N, unsigned int M, class T>
inline const Matrix<N, M, T> operator -(const T & value, const Matrix<N, M, T> & m) {return m.inverseSubtract(value);}
GEOM_NAMESPACE_END
#endif // _FGTL_VMATH
// ---------------------------------------------------------------------------------------------------------------------------------
// vmath - End of file
// ---------------------------------------------------------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -