Ex3
This commit is contained in:
@@ -1,611 +0,0 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* MantaFlow fluid solver framework
|
||||
* Copyright 2011-2016 Tobias Pfaff, Nils Thuerey
|
||||
*
|
||||
* This program is free software, distributed under the terms of the
|
||||
* GNU General Public License (GPL)
|
||||
* http://www.gnu.org/licenses
|
||||
*
|
||||
* Basic vector class
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef _VECTORBASE_H
|
||||
#define _VECTORBASE_H
|
||||
|
||||
// get rid of windos min/max defines
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
# define NOMINMAX
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
#include <limits>
|
||||
#include <iostream>
|
||||
#include "general.h"
|
||||
|
||||
// if min/max are still around...
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
# undef min
|
||||
# undef max
|
||||
#endif
|
||||
|
||||
// redefine usage of some windows functions
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
# ifndef snprintf
|
||||
# define snprintf _snprintf
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// use which fp-precision? 1=float, 2=double
|
||||
#ifndef FLOATINGPOINT_PRECISION
|
||||
# define FLOATINGPOINT_PRECISION 1
|
||||
#endif
|
||||
|
||||
// VECTOR_EPSILON is the minimal vector length
|
||||
// In order to be able to discriminate floating point values near zero, and
|
||||
// to be sure not to fail a comparison because of roundoff errors, use this
|
||||
// value as a threshold.
|
||||
#if FLOATINGPOINT_PRECISION==1
|
||||
typedef float Real;
|
||||
# define VECTOR_EPSILON (1e-6f)
|
||||
#else
|
||||
typedef double Real;
|
||||
# define VECTOR_EPSILON (1e-10)
|
||||
#endif
|
||||
|
||||
#ifndef M_PI
|
||||
# define M_PI 3.1415926536
|
||||
#endif
|
||||
#ifndef M_E
|
||||
# define M_E 2.7182818284
|
||||
#endif
|
||||
|
||||
namespace Manta
|
||||
{
|
||||
|
||||
//! Basic inlined vector class
|
||||
template<class S>
|
||||
class Vector3D
|
||||
{
|
||||
public:
|
||||
//! Constructor
|
||||
inline Vector3D() : x(0),y(0),z(0) {}
|
||||
|
||||
//! Copy-Constructor
|
||||
inline Vector3D ( const Vector3D<S> &v ) : x(v.x), y(v.y), z(v.z) {}
|
||||
|
||||
//! Copy-Constructor
|
||||
inline Vector3D ( const float * v) : x((S)v[0]), y((S)v[1]), z((S)v[2]) {}
|
||||
|
||||
//! Copy-Constructor
|
||||
inline Vector3D ( const double * v) : x((S)v[0]), y((S)v[1]), z((S)v[2]) {}
|
||||
|
||||
//! Construct a vector from one S
|
||||
inline Vector3D ( S v) : x(v), y(v), z(v) {}
|
||||
|
||||
//! Construct a vector from three Ss
|
||||
inline Vector3D ( S vx, S vy, S vz) : x(vx), y(vy), z(vz) {}
|
||||
|
||||
// Operators
|
||||
|
||||
//! Assignment operator
|
||||
inline const Vector3D<S>& operator= ( const Vector3D<S>& v ) {
|
||||
x = v.x;
|
||||
y = v.y;
|
||||
z = v.z;
|
||||
return *this;
|
||||
}
|
||||
//! Assignment operator
|
||||
inline const Vector3D<S>& operator= ( S s ) {
|
||||
x = y = z = s;
|
||||
return *this;
|
||||
}
|
||||
//! Assign and add operator
|
||||
inline const Vector3D<S>& operator+= ( const Vector3D<S>& v ) {
|
||||
x += v.x;
|
||||
y += v.y;
|
||||
z += v.z;
|
||||
return *this;
|
||||
}
|
||||
//! Assign and add operator
|
||||
inline const Vector3D<S>& operator+= ( S s ) {
|
||||
x += s;
|
||||
y += s;
|
||||
z += s;
|
||||
return *this;
|
||||
}
|
||||
//! Assign and sub operator
|
||||
inline const Vector3D<S>& operator-= ( const Vector3D<S>& v ) {
|
||||
x -= v.x;
|
||||
y -= v.y;
|
||||
z -= v.z;
|
||||
return *this;
|
||||
}
|
||||
//! Assign and sub operator
|
||||
inline const Vector3D<S>& operator-= ( S s ) {
|
||||
x -= s;
|
||||
y -= s;
|
||||
z -= s;
|
||||
return *this;
|
||||
}
|
||||
//! Assign and mult operator
|
||||
inline const Vector3D<S>& operator*= ( const Vector3D<S>& v ) {
|
||||
x *= v.x;
|
||||
y *= v.y;
|
||||
z *= v.z;
|
||||
return *this;
|
||||
}
|
||||
//! Assign and mult operator
|
||||
inline const Vector3D<S>& operator*= ( S s ) {
|
||||
x *= s;
|
||||
y *= s;
|
||||
z *= s;
|
||||
return *this;
|
||||
}
|
||||
//! Assign and div operator
|
||||
inline const Vector3D<S>& operator/= ( const Vector3D<S>& v ) {
|
||||
x /= v.x;
|
||||
y /= v.y;
|
||||
z /= v.z;
|
||||
return *this;
|
||||
}
|
||||
//! Assign and div operator
|
||||
inline const Vector3D<S>& operator/= ( S s ) {
|
||||
x /= s;
|
||||
y /= s;
|
||||
z /= s;
|
||||
return *this;
|
||||
}
|
||||
//! Negation operator
|
||||
inline Vector3D<S> operator- () const {
|
||||
return Vector3D<S> (-x, -y, -z);
|
||||
}
|
||||
|
||||
//! Get smallest component
|
||||
inline S min() const {
|
||||
return ( x<y ) ? ( ( x<z ) ? x:z ) : ( ( y<z ) ? y:z );
|
||||
}
|
||||
//! Get biggest component
|
||||
inline S max() const {
|
||||
return ( x>y ) ? ( ( x>z ) ? x:z ) : ( ( y>z ) ? y:z );
|
||||
}
|
||||
|
||||
//! Test if all components are zero
|
||||
inline bool empty() {
|
||||
return x==0 && y==0 && z==0;
|
||||
}
|
||||
|
||||
//! access operator
|
||||
inline S& operator[] ( unsigned int i ) {
|
||||
return value[i];
|
||||
}
|
||||
//! constant access operator
|
||||
inline const S& operator[] ( unsigned int i ) const {
|
||||
return value[i];
|
||||
}
|
||||
|
||||
//! debug output vector to a string
|
||||
std::string toString() const;
|
||||
|
||||
//! test if nans are present
|
||||
bool isValid() const;
|
||||
|
||||
//! actual values
|
||||
union {
|
||||
S value[3];
|
||||
struct {
|
||||
S x;
|
||||
S y;
|
||||
S z;
|
||||
};
|
||||
struct {
|
||||
S X;
|
||||
S Y;
|
||||
S Z;
|
||||
};
|
||||
};
|
||||
|
||||
//! zero element
|
||||
static const Vector3D<S> Zero, Invalid;
|
||||
|
||||
//! For compatibility with 4d vectors (discards 4th comp)
|
||||
inline Vector3D ( S vx, S vy, S vz, S vDummy) : x(vx), y(vy), z(vz) {}
|
||||
|
||||
protected:
|
||||
|
||||
};
|
||||
|
||||
//************************************************************************
|
||||
// Additional operators
|
||||
//************************************************************************
|
||||
|
||||
//! Addition operator
|
||||
template<class S>
|
||||
inline Vector3D<S> operator+ ( const Vector3D<S> &v1, const Vector3D<S> &v2 ) {
|
||||
return Vector3D<S> ( v1.x+v2.x, v1.y+v2.y, v1.z+v2.z );
|
||||
}
|
||||
//! Addition operator
|
||||
template<class S, class S2>
|
||||
inline Vector3D<S> operator+ ( const Vector3D<S>& v, S2 s ) {
|
||||
return Vector3D<S> ( v.x+s, v.y+s, v.z+s );
|
||||
}
|
||||
//! Addition operator
|
||||
template<class S, class S2>
|
||||
inline Vector3D<S> operator+ ( S2 s, const Vector3D<S>& v ) {
|
||||
return Vector3D<S> ( v.x+s, v.y+s, v.z+s );
|
||||
}
|
||||
|
||||
//! Subtraction operator
|
||||
template<class S>
|
||||
inline Vector3D<S> operator- ( const Vector3D<S> &v1, const Vector3D<S> &v2 ) {
|
||||
return Vector3D<S> ( v1.x-v2.x, v1.y-v2.y, v1.z-v2.z );
|
||||
}
|
||||
//! Subtraction operator
|
||||
template<class S, class S2>
|
||||
inline Vector3D<S> operator- ( const Vector3D<S>& v, S2 s ) {
|
||||
return Vector3D<S> ( v.x-s, v.y-s, v.z-s );
|
||||
}
|
||||
//! Subtraction operator
|
||||
template<class S, class S2>
|
||||
inline Vector3D<S> operator- ( S2 s, const Vector3D<S>& v ) {
|
||||
return Vector3D<S> ( s-v.x, s-v.y, s-v.z );
|
||||
}
|
||||
|
||||
//! Multiplication operator
|
||||
template<class S>
|
||||
inline Vector3D<S> operator* ( const Vector3D<S> &v1, const Vector3D<S> &v2 ) {
|
||||
return Vector3D<S> ( v1.x*v2.x, v1.y*v2.y, v1.z*v2.z );
|
||||
}
|
||||
//! Multiplication operator
|
||||
template<class S, class S2>
|
||||
inline Vector3D<S> operator* ( const Vector3D<S>& v, S2 s ) {
|
||||
return Vector3D<S> ( v.x*s, v.y*s, v.z*s );
|
||||
}
|
||||
//! Multiplication operator
|
||||
template<class S, class S2>
|
||||
inline Vector3D<S> operator* ( S2 s, const Vector3D<S>& v ) {
|
||||
return Vector3D<S> ( s*v.x, s*v.y, s*v.z );
|
||||
}
|
||||
|
||||
//! Division operator
|
||||
template<class S>
|
||||
inline Vector3D<S> operator/ ( const Vector3D<S> &v1, const Vector3D<S> &v2 ) {
|
||||
return Vector3D<S> ( v1.x/v2.x, v1.y/v2.y, v1.z/v2.z );
|
||||
}
|
||||
//! Division operator
|
||||
template<class S, class S2>
|
||||
inline Vector3D<S> operator/ ( const Vector3D<S>& v, S2 s ) {
|
||||
return Vector3D<S> ( v.x/s, v.y/s, v.z/s );
|
||||
}
|
||||
//! Division operator
|
||||
template<class S, class S2>
|
||||
inline Vector3D<S> operator/ ( S2 s, const Vector3D<S>& v ) {
|
||||
return Vector3D<S> ( s/v.x, s/v.y, s/v.z );
|
||||
}
|
||||
|
||||
//! Comparison operator
|
||||
template<class S>
|
||||
inline bool operator== (const Vector3D<S>& s1, const Vector3D<S>& s2) {
|
||||
return s1.x == s2.x && s1.y == s2.y && s1.z == s2.z;
|
||||
}
|
||||
|
||||
//! Comparison operator
|
||||
template<class S>
|
||||
inline bool operator!= (const Vector3D<S>& s1, const Vector3D<S>& s2) {
|
||||
return s1.x != s2.x || s1.y != s2.y || s1.z != s2.z;
|
||||
}
|
||||
|
||||
//************************************************************************
|
||||
// External functions
|
||||
//************************************************************************
|
||||
|
||||
//! Min operator
|
||||
template<class S>
|
||||
inline Vector3D<S> vmin (const Vector3D<S>& s1, const Vector3D<S>& s2) {
|
||||
return Vector3D<S>(std::min(s1.x,s2.x), std::min(s1.y,s2.y), std::min(s1.z,s2.z));
|
||||
}
|
||||
|
||||
//! Min operator
|
||||
template<class S, class S2>
|
||||
inline Vector3D<S> vmin (const Vector3D<S>& s1, S2 s2) {
|
||||
return Vector3D<S>(std::min(s1.x,s2), std::min(s1.y,s2), std::min(s1.z,s2));
|
||||
}
|
||||
|
||||
//! Min operator
|
||||
template<class S1, class S>
|
||||
inline Vector3D<S> vmin (S1 s1, const Vector3D<S>& s2) {
|
||||
return Vector3D<S>(std::min(s1,s2.x), std::min(s1,s2.y), std::min(s1,s2.z));
|
||||
}
|
||||
|
||||
//! Max operator
|
||||
template<class S>
|
||||
inline Vector3D<S> vmax (const Vector3D<S>& s1, const Vector3D<S>& s2) {
|
||||
return Vector3D<S>(std::max(s1.x,s2.x), std::max(s1.y,s2.y), std::max(s1.z,s2.z));
|
||||
}
|
||||
|
||||
//! Max operator
|
||||
template<class S, class S2>
|
||||
inline Vector3D<S> vmax (const Vector3D<S>& s1, S2 s2) {
|
||||
return Vector3D<S>(std::max(s1.x,s2), std::max(s1.y,s2), std::max(s1.z,s2));
|
||||
}
|
||||
|
||||
//! Max operator
|
||||
template<class S1, class S>
|
||||
inline Vector3D<S> vmax (S1 s1, const Vector3D<S>& s2) {
|
||||
return Vector3D<S>(std::max(s1,s2.x), std::max(s1,s2.y), std::max(s1,s2.z));
|
||||
}
|
||||
|
||||
//! Dot product
|
||||
template<class S>
|
||||
inline S dot ( const Vector3D<S> &t, const Vector3D<S> &v ) {
|
||||
return t.x*v.x + t.y*v.y + t.z*v.z;
|
||||
}
|
||||
|
||||
//! Cross product
|
||||
template<class S>
|
||||
inline Vector3D<S> cross ( const Vector3D<S> &t, const Vector3D<S> &v ) {
|
||||
Vector3D<S> cp (
|
||||
( ( t.y*v.z ) - ( t.z*v.y ) ),
|
||||
( ( t.z*v.x ) - ( t.x*v.z ) ),
|
||||
( ( t.x*v.y ) - ( t.y*v.x ) ) );
|
||||
return cp;
|
||||
}
|
||||
|
||||
//! Project a vector into a plane, defined by its normal
|
||||
/*! Projects a vector into a plane normal to the given vector, which must
|
||||
have unit length. Self is modified.
|
||||
\param v The vector to project
|
||||
\param n The plane normal
|
||||
\return The projected vector */
|
||||
template<class S>
|
||||
inline const Vector3D<S>& projectNormalTo ( const Vector3D<S>& v, const Vector3D<S> &n) {
|
||||
S sprod = dot (v, n);
|
||||
return v - n * dot(v, n);
|
||||
}
|
||||
|
||||
//! Compute the magnitude (length) of the vector
|
||||
//! (clamps to 0 and 1 with VECTOR_EPSILON)
|
||||
template<class S>
|
||||
inline S norm ( const Vector3D<S>& v ) {
|
||||
S l = v.x*v.x + v.y*v.y + v.z*v.z;
|
||||
if ( l <= VECTOR_EPSILON*VECTOR_EPSILON ) return(0.);
|
||||
return ( fabs ( l-1. ) < VECTOR_EPSILON*VECTOR_EPSILON ) ? 1. : sqrt ( l );
|
||||
}
|
||||
|
||||
//! Compute squared magnitude
|
||||
template<class S>
|
||||
inline S normSquare ( const Vector3D<S>& v ) {
|
||||
return v.x*v.x + v.y*v.y + v.z*v.z;
|
||||
}
|
||||
|
||||
//! compatibility, allow use of int, Real and Vec inputs with norm/normSquare
|
||||
inline Real norm(const Real v) { return fabs(v); }
|
||||
inline Real normSquare(const Real v) { return square(v); }
|
||||
inline Real norm(const int v) { return abs(v); }
|
||||
inline Real normSquare(const int v) { return square(v); }
|
||||
|
||||
//! Returns a normalized vector
|
||||
template<class S>
|
||||
inline Vector3D<S> getNormalized ( const Vector3D<S>& v ) {
|
||||
S l = v.x*v.x + v.y*v.y + v.z*v.z;
|
||||
if ( fabs ( l-1. ) < VECTOR_EPSILON*VECTOR_EPSILON )
|
||||
return v; /* normalized "enough"... */
|
||||
else if ( l > VECTOR_EPSILON*VECTOR_EPSILON )
|
||||
{
|
||||
S fac = 1./sqrt ( l );
|
||||
return Vector3D<S> ( v.x*fac, v.y*fac, v.z*fac );
|
||||
}
|
||||
else
|
||||
return Vector3D<S> ( ( S ) 0 );
|
||||
}
|
||||
|
||||
//! Compute the norm of the vector and normalize it.
|
||||
/*! \return The value of the norm */
|
||||
template<class S>
|
||||
inline S normalize ( Vector3D<S> &v ) {
|
||||
S norm;
|
||||
S l = v.x*v.x + v.y*v.y + v.z*v.z;
|
||||
if ( fabs ( l-1. ) < VECTOR_EPSILON*VECTOR_EPSILON ) {
|
||||
norm = 1.;
|
||||
} else if ( l > VECTOR_EPSILON*VECTOR_EPSILON ) {
|
||||
norm = sqrt ( l );
|
||||
v *= 1./norm;
|
||||
} else {
|
||||
v = Vector3D<S>::Zero;
|
||||
norm = 0.;
|
||||
}
|
||||
return ( S ) norm;
|
||||
}
|
||||
|
||||
//! Obtain an orthogonal vector
|
||||
/*! Compute a vector that is orthonormal to the given vector.
|
||||
* Nothing else can be assumed for the direction of the new vector.
|
||||
* \return The orthonormal vector */
|
||||
template<class S>
|
||||
Vector3D<S> getOrthogonalVector(const Vector3D<S>& v) {
|
||||
// Determine the component with max. absolute value
|
||||
int maxIndex= ( fabs ( v.x ) > fabs ( v.y ) ) ? 0 : 1;
|
||||
maxIndex= ( fabs ( v[maxIndex] ) > fabs ( v.z ) ) ? maxIndex : 2;
|
||||
|
||||
// Choose another axis than the one with max. component and project
|
||||
// orthogonal to self
|
||||
Vector3D<S> o ( 0.0 );
|
||||
o[ ( maxIndex+1 ) %3]= 1;
|
||||
|
||||
Vector3D<S> c = cross(v, o);
|
||||
normalize(c);
|
||||
return c;
|
||||
}
|
||||
|
||||
//! Convert vector to polar coordinates
|
||||
/*! Stable vector to angle conversion
|
||||
*\param v vector to convert
|
||||
\param phi unique angle [0,2PI]
|
||||
\param theta unique angle [0,PI]
|
||||
*/
|
||||
template<class S>
|
||||
inline void vecToAngle ( const Vector3D<S>& v, S& phi, S& theta )
|
||||
{
|
||||
if ( fabs ( v.y ) < VECTOR_EPSILON )
|
||||
theta = M_PI/2;
|
||||
else if ( fabs ( v.x ) < VECTOR_EPSILON && fabs ( v.z ) < VECTOR_EPSILON )
|
||||
theta = ( v.y>=0 ) ? 0:M_PI;
|
||||
else
|
||||
theta = atan ( sqrt ( v.x*v.x+v.z*v.z ) /v.y );
|
||||
if ( theta<0 ) theta+=M_PI;
|
||||
|
||||
if ( fabs ( v.x ) < VECTOR_EPSILON )
|
||||
phi = M_PI/2;
|
||||
else
|
||||
phi = atan ( v.z/v.x );
|
||||
if ( phi<0 ) phi+=M_PI;
|
||||
if ( fabs ( v.z ) < VECTOR_EPSILON )
|
||||
phi = ( v.x>=0 ) ? 0 : M_PI;
|
||||
else if ( v.z < 0 )
|
||||
phi += M_PI;
|
||||
}
|
||||
|
||||
//! Compute vector reflected at a surface
|
||||
/*! Compute a vector, that is self (as an incoming vector)
|
||||
* reflected at a surface with a distinct normal vector.
|
||||
* Note that the normal is reversed, if the scalar product with it is positive.
|
||||
\param t The incoming vector
|
||||
\param n The surface normal
|
||||
\return The new reflected vector
|
||||
*/
|
||||
template<class S>
|
||||
inline Vector3D<S> reflectVector ( const Vector3D<S>& t, const Vector3D<S>& n ) {
|
||||
Vector3D<S> nn= ( dot ( t, n ) > 0.0 ) ? ( n*-1.0 ) : n;
|
||||
return ( t - nn * ( 2.0 * dot ( nn, t ) ) );
|
||||
}
|
||||
|
||||
//! Compute vector refracted at a surface
|
||||
/*! \param t The incoming vector
|
||||
* \param n The surface normal
|
||||
* \param nt The "inside" refraction index
|
||||
* \param nair The "outside" refraction index
|
||||
* \param refRefl Set to 1 on total reflection
|
||||
* \return The refracted vector
|
||||
*/
|
||||
template<class S>
|
||||
inline Vector3D<S> refractVector ( const Vector3D<S> &t, const Vector3D<S> &normal, S nt, S nair, int &refRefl ) {
|
||||
// from Glassner's book, section 5.2 (Heckberts method)
|
||||
S eta = nair / nt;
|
||||
S n = -dot ( t, normal );
|
||||
S tt = 1.0 + eta*eta* ( n*n-1.0 );
|
||||
if ( tt<0.0 ) {
|
||||
// we have total reflection!
|
||||
refRefl = 1;
|
||||
} else {
|
||||
// normal reflection
|
||||
tt = eta*n - sqrt ( tt );
|
||||
return ( t*eta + normal*tt );
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
//! Outputs the object in human readable form as string
|
||||
template<class S> std::string Vector3D<S>::toString() const {
|
||||
char buf[256];
|
||||
snprintf ( buf,256,"[%+4.6f,%+4.6f,%+4.6f]", ( double ) ( *this ) [0], ( double ) ( *this ) [1], ( double ) ( *this ) [2] );
|
||||
// for debugging, optionally increase precision:
|
||||
//snprintf ( buf,256,"[%+4.16f,%+4.16f,%+4.16f]", ( double ) ( *this ) [0], ( double ) ( *this ) [1], ( double ) ( *this ) [2] );
|
||||
return std::string ( buf );
|
||||
}
|
||||
|
||||
template<> std::string Vector3D<int>::toString() const;
|
||||
|
||||
|
||||
//! Outputs the object in human readable form to stream
|
||||
/*! Output format [x,y,z] */
|
||||
template<class S>
|
||||
std::ostream& operator<< ( std::ostream& os, const Vector3D<S>& i ) {
|
||||
os << i.toString();
|
||||
return os;
|
||||
}
|
||||
|
||||
//! Reads the contents of the object from a stream
|
||||
/*! Input format [x,y,z] */
|
||||
template<class S>
|
||||
std::istream& operator>> ( std::istream& is, Vector3D<S>& i ) {
|
||||
char c;
|
||||
char dummy[3];
|
||||
is >> c >> i[0] >> dummy >> i[1] >> dummy >> i[2] >> c;
|
||||
return is;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
// Define default vector alias
|
||||
/**************************************************************************/
|
||||
|
||||
//! 3D vector class of type Real (typically float)
|
||||
typedef Vector3D<Real> Vec3;
|
||||
|
||||
//! 3D vector class of type int
|
||||
typedef Vector3D<int> Vec3i;
|
||||
|
||||
//! convert to Real Vector
|
||||
template<class T> inline Vec3 toVec3 ( T v ) {
|
||||
return Vec3 ( v[0],v[1],v[2] );
|
||||
}
|
||||
|
||||
//! convert to int Vector
|
||||
template<class T> inline Vec3i toVec3i ( T v ) {
|
||||
return Vec3i ( ( int ) v[0], ( int ) v[1], ( int ) v[2] );
|
||||
}
|
||||
|
||||
//! convert to int Vector
|
||||
template<class T> inline Vec3i toVec3i ( T v0, T v1, T v2 ) {
|
||||
return Vec3i ( ( int ) v0, ( int ) v1, ( int ) v2 );
|
||||
}
|
||||
|
||||
//! round, and convert to int Vector
|
||||
template<class T> inline Vec3i toVec3iRound ( T v ) {
|
||||
return Vec3i ( ( int ) round ( v[0] ), ( int ) round ( v[1] ), ( int ) round ( v[2] ) );
|
||||
}
|
||||
|
||||
//! convert to int Vector if values are close enough to an int
|
||||
template<class T> inline Vec3i toVec3iChecked ( T v ) {
|
||||
Vec3i ret;
|
||||
for (size_t i=0; i<3; i++) {
|
||||
Real a = v[i];
|
||||
if (fabs(a-floor(a+0.5)) > 1e-5)
|
||||
errMsg("argument is not an int, cannot convert");
|
||||
ret[i] = (int) (a+0.5);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
//! convert to double Vector
|
||||
template<class T> inline Vector3D<double> toVec3d ( T v ) {
|
||||
return Vector3D<double> ( v[0], v[1], v[2] );
|
||||
}
|
||||
|
||||
//! convert to float Vector
|
||||
template<class T> inline Vector3D<float> toVec3f ( T v ) {
|
||||
return Vector3D<float> ( v[0], v[1], v[2] );
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
// Specializations for common math functions
|
||||
/**************************************************************************/
|
||||
|
||||
template<> inline Vec3 clamp<Vec3>(const Vec3& a, const Vec3& b, const Vec3& c) {
|
||||
return Vec3 ( clamp(a.x, b.x, c.x),
|
||||
clamp(a.y, b.y, c.y),
|
||||
clamp(a.z, b.z, c.z) );
|
||||
}
|
||||
template<> inline Vec3 safeDivide<Vec3>(const Vec3 &a, const Vec3& b) {
|
||||
return Vec3(safeDivide(a.x,b.x), safeDivide(a.y,b.y), safeDivide(a.z,b.z));
|
||||
}
|
||||
template<> inline Vec3 nmod<Vec3>(const Vec3& a, const Vec3& b) {
|
||||
return Vec3(nmod(a.x,b.x),nmod(a.y,b.y),nmod(a.z,b.z));
|
||||
}
|
||||
|
||||
}; // namespace
|
||||
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user