00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef VRS_VEC_MAT_OPS_H
00019 #define VRS_VEC_MAT_OPS_H
00020
00021
00022 #include <vrs/vec.h>
00023 #include <vrs/mat.h>
00024
00025 namespace VRS {
00026
00028 inline double radians(double degrees) { return (degrees * M_PI / 180.0); }
00029 inline float radians(float degrees) { return static_cast<float>(degrees * M_PI / 180.0); }
00030 template<unsigned int DIM, typename T>
00031 inline Vec<DIM, T> radians(Vec<DIM, T> const& degrees) { Vec<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = radians(degrees[i]); } return result; }
00032 template<unsigned int DIM, typename T>
00033 inline Mat<DIM, T> radians(Mat<DIM, T> const& degrees) { Mat<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = radians(degrees[i]); } return result; }
00034
00036 inline double degrees(double radians) { return (radians * 180.0 / M_PI); }
00037 inline float degrees(float radians) { return static_cast<float>(radians * 180.0 / M_PI); }
00038 template<unsigned int DIM, typename T>
00039 inline Vec<DIM, T> degrees(Vec<DIM, T> const& radians) { Vec<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = degrees(radians[i]); } return result; }
00040 template<unsigned int DIM, typename T>
00041 inline Mat<DIM, T> degrees(Mat<DIM, T> const& radians) { Mat<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = degrees(radians[i]); } return result; }
00042
00044 using ::sin;
00045 template<unsigned int DIM, typename T>
00046 inline Vec<DIM, T> sin(Vec<DIM, T> const& angleRadians) { Vec<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = sin(angleRadians[i]); } return result; }
00047 template<unsigned int DIM, typename T>
00048 inline Mat<DIM, T> sin(Mat<DIM, T> const& angleRadians) { Mat<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = sin(angleRadians[i]); } return result; }
00049
00051 using ::cos;
00052 template<unsigned int DIM, typename T>
00053 inline Vec<DIM, T> cos(Vec<DIM, T> const& angleRadians) { Vec<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = sin(angleRadians[i]); } return result; }
00054 template<unsigned int DIM, typename T>
00055 inline Mat<DIM, T> cos(Mat<DIM, T> const& angleRadians) { Mat<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = sin(angleRadians[i]); } return result; }
00056
00058 using ::tan;
00059 template<unsigned int DIM, typename T>
00060 inline Vec<DIM, T> tan(Vec<DIM, T> const& angleRadians) { Vec<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = tan(angleRadians[i]); } return result; }
00061 template<unsigned int DIM, typename T>
00062 inline Mat<DIM, T> tan(Mat<DIM, T> const& angleRadians) { Mat<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = tan(angleRadians[i]); } return result; }
00063
00065 using ::asin;
00066 template<unsigned int DIM, typename T>
00067 inline Vec<DIM, T> asin(Vec<DIM, T> const& x) { Vec<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = asin(x[i]); } return result; }
00068 template<unsigned int DIM, typename T>
00069 inline Mat<DIM, T> asin(Mat<DIM, T> const& x) { Mat<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = asin(x[i]); } return result; }
00070
00072 using ::acos;
00073 template<unsigned int DIM, typename T>
00074 inline Vec<DIM, T> acos(Vec<DIM, T> const& x) { Vec<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = acos(x[i]); } return result; }
00075 template<unsigned int DIM, typename T>
00076 inline Mat<DIM, T> acos(Mat<DIM, T> const& x) { Mat<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = acos(x[i]); } return result; }
00077
00079 using ::atan;
00080 template<unsigned int DIM, typename T>
00081 inline Vec<DIM, T> atan(Vec<DIM, T> const& y_over_x) { Vec<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = atan(y_over_x[i]); } return result; }
00082 template<unsigned int DIM, typename T>
00083 inline Mat<DIM, T> atan(Mat<DIM, T> const& y_over_x) { Mat<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = atan(y_over_x[i]); } return result; }
00084
00086 inline double atan(double y, double x) { return ::atan2(y, x); }
00087 inline float atan(float y, float x) { return ::atan2(y, x); }
00088 template<unsigned int DIM, typename T>
00089 inline Vec<DIM, T> atan(Vec<DIM, T> const& y, Vec<DIM, T> const& x) { Vec<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = atan(y[i], x[i]); } return result; }
00090 template<unsigned int DIM, typename T>
00091 inline Vec<DIM, T> atan(T y, Vec<DIM, T> const& x) { return atan(Vec<DIM, T>(y), x); }
00092 template<unsigned int DIM, typename T>
00093 inline Vec<DIM, T> atan(Vec<DIM, T> const& y, T x) { return atan(y, Vec<DIM, T>(x)); }
00094 template<unsigned int DIM, typename T>
00095 inline Mat<DIM, T> atan(Mat<DIM, T> const& y, Mat<DIM, T> const& x) { Mat<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = atan(y[i], x[i]); } return result; }
00096
00098 using ::pow;
00099 template<unsigned int DIM, typename T>
00100 inline Vec<DIM, T> pow(Vec<DIM, T> const& x, Vec<DIM, T> const& y) { Vec<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = pow(x[i], y[i]); } return result; }
00101 template<unsigned int DIM, typename T>
00102 inline Vec<DIM, T> pow(T x, Vec<DIM, T> const& y) { return pow(Vec<DIM, T>(x), y); }
00103 template<unsigned int DIM, typename T>
00104 inline Vec<DIM, T> pow(Vec<DIM, T> const& x, T y) { return pow(x, Vec<DIM, T>(y)); }
00105 template<unsigned int DIM, typename T>
00106 inline Mat<DIM, T> pow(Mat<DIM, T> const& x, Mat<DIM, T> const& y) { Mat<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = pow(x[i], y[i]); } return result; }
00107
00109 using ::exp;
00110 template<unsigned int DIM, typename T>
00111 inline Vec<DIM, T> exp(Vec<DIM, T> const& x) { Vec<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = exp(x[i]); } return result; }
00112 template<unsigned int DIM, typename T>
00113 inline Mat<DIM, T> exp(Mat<DIM, T> const& x) { Mat<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = exp(x[i]); } return result; }
00114
00116 using ::log;
00117 template<unsigned int DIM, typename T>
00118 inline Vec<DIM, T> log(Vec<DIM, T> const& x) { Vec<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = log(x[i]); } return result; }
00119 template<unsigned int DIM, typename T>
00120 inline Mat<DIM, T> log(Mat<DIM, T> const& x) { Mat<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = log(x[i]); } return result; }
00121
00123 inline double exp2(double x) { return (exp(x) / exp(2.0)); }
00124 inline float exp2(float x) { return (exp(x) / exp(2.0f)); }
00125 template<unsigned int DIM, typename T>
00126 inline Vec<DIM, T> exp2(Vec<DIM, T> const& x) { Vec<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = exp2(x[i]); } return result; }
00127 template<unsigned int DIM, typename T>
00128 inline Mat<DIM, T> exp2(Mat<DIM, T> const& x) { Mat<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = exp2(x[i]); } return result; }
00129
00131 inline double log2(double x) { return (log(x) - log(2.0)); }
00132 inline float log2(float x) { return (log(x) - log(2.0f)); }
00133 template<unsigned int DIM, typename T>
00134 inline Vec<DIM, T> log2(Vec<DIM, T> const& x) { Vec<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = log2(x[i]); } return result; }
00135 template<unsigned int DIM, typename T>
00136 inline Mat<DIM, T> log2(Mat<DIM, T> const& x) { Mat<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = log2(x[i]); } return result; }
00137
00139 using ::sqrt;
00140 template<unsigned int DIM, typename T>
00141 inline Vec<DIM, T> sqrt(Vec<DIM, T> const& x) { Vec<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = sqrt(x[i]); } return result; }
00142 template<unsigned int DIM, typename T>
00143 inline Mat<DIM, T> sqrt(Mat<DIM, T> const& x) { Mat<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = sqrt(x[i]); } return result; }
00144
00146 inline double inversesqrt(double x) { return (1.0 / sqrt(x)); }
00147 inline float inversesqrt(float x) { return (1.0f / sqrt(x)); }
00148 template<unsigned int DIM, typename T>
00149 inline Vec<DIM, T> inversesqrt(Vec<DIM, T> const& x) { Vec<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = inversesqrt(x[i]); } return result; }
00150 template<unsigned int DIM, typename T>
00151 inline Mat<DIM, T> inversesqrt(Mat<DIM, T> const& x) { Mat<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = inversesqrt(x[i]); } return result; }
00152
00154 inline double abs(double x) { return ::fabs(x); }
00155 inline float abs(float x) { return ::fabs(x); }
00156 inline int abs(int x) { return ::abs(x); }
00157 template<unsigned int DIM, typename T>
00158 inline Vec<DIM, T> abs(Vec<DIM, T> const& x) { Vec<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = abs(x[i]); } return result; }
00159 template<unsigned int DIM, typename T>
00160 inline Mat<DIM, T> abs(Mat<DIM, T> const& x) { Mat<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = abs(x[i]); } return result; }
00161
00163 inline double sign(double x) { return ((x > 0.0) ? 1.0 : ((x < 0.0) ? -1.0 : 0.0)); }
00164 inline float sign(float x) { return ((x > 0.0f) ? 1.0f : ((x < 0.0f) ? -1.0f : 0.0f)); }
00165 inline int sign(int x) { return ((x > 0) ? 1 : ((x < 0) ? -1 : 0)); }
00166 template<unsigned int DIM, typename T>
00167 inline Vec<DIM, T> sign(Vec<DIM, T> const& x) { Vec<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = sign(x[i]); } return result; }
00168 template<unsigned int DIM, typename T>
00169 inline Mat<DIM, T> sign(Mat<DIM, T> const& x) { Mat<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = sign(x[i]); } return result; }
00170
00172 using ::floor;
00173 template<unsigned int DIM, typename T>
00174 inline Vec<DIM, T> floor(Vec<DIM, T> const& x) { Vec<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = floor(x[i]); } return result; }
00175 template<unsigned int DIM, typename T>
00176 inline Mat<DIM, T> floor(Mat<DIM, T> const& x) { Mat<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = floor(x[i]); } return result; }
00177
00179 using ::ceil;
00180 template<unsigned int DIM, typename T>
00181 inline Vec<DIM, T> ceil(Vec<DIM, T> const& x) { Vec<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = ceil(x[i]); } return result; }
00182 template<unsigned int DIM, typename T>
00183 inline Mat<DIM, T> ceil(Mat<DIM, T> const& x) { Mat<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = ceil(x[i]); } return result; }
00184
00186 inline double fract(double x) { return (x - floor(x)); }
00187 inline float fract(float x) { return (x - floor(x)); }
00188 template<unsigned int DIM, typename T>
00189 inline Vec<DIM, T> fract(Vec<DIM, T> const& x) { Vec<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = fract(x[i]); } return result; }
00190 template<unsigned int DIM, typename T>
00191 inline Mat<DIM, T> fract(Mat<DIM, T> const& x) { Mat<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = fract(x[i]); } return result; }
00192
00194 inline double mod(double x, double y) { return (x - y * floor(x/y)); }
00195 inline float mod(float x, float y) { return (x - y * floor(x/y)); }
00196 template<unsigned int DIM, typename T>
00197 inline Vec<DIM, T> mod(Vec<DIM, T> const& x, Vec<DIM, T> const& y) { Vec<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = mod(x[i], y[i]); } return result; }
00198 template<unsigned int DIM, typename T>
00199 inline Vec<DIM, T> mod(T x, Vec<DIM, T> const& y) { return mod(Vec<DIM, T>(x), y); }
00200 template<unsigned int DIM, typename T>
00201 inline Vec<DIM, T> mod(Vec<DIM, T> const& x, T y) { return mod(x, Vec<DIM, T>(y)); }
00202 template<unsigned int DIM, typename T>
00203 inline Mat<DIM, T> mod(Mat<DIM, T> const& x, Mat<DIM, T> const& y) { Mat<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = mod(x[i], y[i]); } return result; }
00204
00206 using std::min;
00207 template<unsigned int DIM, typename T>
00208 inline Vec<DIM, T> min(Vec<DIM, T> const& x, Vec<DIM, T> const& y) { Vec<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = min(x[i], y[i]); } return result; }
00209 template<unsigned int DIM, typename T>
00210 inline Mat<DIM, T> min(Mat<DIM, T> const& x, Mat<DIM, T> const& y) { Mat<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = min(x[i], y[i]); } return result; }
00211
00213 using std::max;
00214 template<unsigned int DIM, typename T>
00215 inline Vec<DIM, T> max(Vec<DIM, T> const& x, Vec<DIM, T> const& y) { Vec<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = max(x[i], y[i]); } return result; }
00216 template<unsigned int DIM, typename T>
00217 inline Mat<DIM, T> max(Mat<DIM, T> const& x, Mat<DIM, T> const& y) { Mat<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = max(x[i], y[i]); } return result; }
00218
00220 inline double clamp(double x, double minVal, double maxVal) { return min(max(x, minVal), maxVal); }
00221 inline float clamp(float x, float minVal, float maxVal) { return min(max(x, minVal), maxVal); }
00222 template<unsigned int DIM, typename T>
00223 inline Vec<DIM, T> clamp(Vec<DIM, T> const& x, Vec<DIM, T> const& minVal, Vec<DIM, T> const& maxVal) { Vec<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = clamp(x[i], minVal[i], maxVal[i]); } return result; }
00224 template<unsigned int DIM, typename T>
00225 inline Vec<DIM, T> clamp(T x, Vec<DIM, T> const& minVal, Vec<DIM, T> const& maxVal) { return clamp(Vec<DIM, T>(x), minVal, maxVal); }
00226 template<unsigned int DIM, typename T>
00227 inline Vec<DIM, T> clamp(Vec<DIM, T> const& x, T minVal, T maxVal) { return clamp(x, Vec<DIM, T>(minVal), Vec<DIM, T>(maxVal)); }
00228 template<unsigned int DIM, typename T>
00229 inline Mat<DIM, T> clamp(Mat<DIM, T> const& x, Mat<DIM, T> const& minVal, Mat<DIM, T> const& maxVal) { Mat<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = clamp(x[i], minVal[i], maxVal[i]); } return result; }
00230
00232 inline double mix(double x, double y, double a) { return ((1.0-a)*x + a*y); }
00233 inline float mix(float x, float y, float a) { return ((1.0f-a)*x + a*y); }
00234 template<unsigned int DIM, typename T>
00235 inline Vec<DIM, T> mix(Vec<DIM, T> const& x, Vec<DIM, T> const& y, Vec<DIM, T> const& a) { Vec<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = mix(x[i], y[i], a[i]); } return result; }
00236 template<unsigned int DIM, typename T>
00237 inline Vec<DIM, T> mix(T x, T y, Vec<DIM, T> const& a) { return mix(Vec<DIM, T>(x), Vec<DIM, T>(y), a); }
00238 template<unsigned int DIM, typename T>
00239 inline Vec<DIM, T> mix(Vec<DIM, T> const& x, Vec<DIM, T> const& y, T a) { return mix(x, y, Vec<DIM, T>(a)); }
00240 template<unsigned int DIM, typename T>
00241 inline Mat<DIM, T> mix(Mat<DIM, T> const& x, Mat<DIM, T> const& y, Mat<DIM, T> const& a) { Mat<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = mix(x[i], y[i], a[i]); } return result; }
00242
00244 inline double step(double edge, double x) { return ((x < edge) ? 0.0 : 1.0); }
00245 inline float step(float edge, float x) { return ((x < edge) ? 0.0f : 1.0f); }
00246 template<unsigned int DIM, typename T>
00247 inline Vec<DIM, T> step(Vec<DIM, T> const& edge, Vec<DIM, T> const& x) { Vec<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = step(edge[i], x[i]); } return result; }
00248 template<unsigned int DIM, typename T>
00249 inline Vec<DIM, T> step(T edge, Vec<DIM, T> const& x) { return step(Vec<DIM, T>(edge), x); }
00250 template<unsigned int DIM, typename T>
00251 inline Vec<DIM, T> step(Vec<DIM, T> const& edge, T x) { return step(edge, Vec<DIM, T>(x)); }
00252 template<unsigned int DIM, typename T>
00253 inline Mat<DIM, T> step(Mat<DIM, T> const& edge, Mat<DIM, T> const& x) { Mat<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = step(edge[i], x[i]); } return result; }
00254
00258 inline double smoothstep(double edge0, double edge1, double x) { const double t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0); return (t * t * (3.0 - 2.0 * t)); }
00259 inline float smoothstep(float edge0, float edge1, float x) { const float t = clamp((x - edge0) / (edge1 - edge0), 0.0f, 1.0f); return (t * t * (3.0f - 2.0f * t)); }
00260 template<unsigned int DIM, typename T>
00261 inline Vec<DIM, T> smoothstep(Vec<DIM, T> const& edge0, Vec<DIM, T> const& edge1, Vec<DIM, T> const& x) { Vec<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = smoothstep(edge0[i], edge1[i], x[i]); } return result; }
00262 template<unsigned int DIM, typename T>
00263 inline Vec<DIM, T> smoothstep(T edge0, T edge1, Vec<DIM, T> const& x) { return smoothstep(Vec<DIM, T>(edge0), Vec<DIM, T>(edge1), x); }
00264 template<unsigned int DIM, typename T>
00265 inline Vec<DIM, T> smoothstep(Vec<DIM, T> const& edge0, Vec<DIM, T> const& edge1, T x) { return smoothstep(edge0, edge1, Vec<DIM, T>(x)); }
00266 template<unsigned int DIM, typename T>
00267 inline Mat<DIM, T> smoothstep(Mat<DIM, T> const& edge0, Mat<DIM, T> const& edge1, Mat<DIM, T> const& x) { Mat<DIM, T> result; for(size_t i = 0; i < DIM; ++i) { result[i] = smoothstep(edge0[i], edge1[i], x[i]); } return result; }
00268
00270 template<unsigned int DIM, typename T>
00271 inline T dot(Vec<DIM, T> const& x, Vec<DIM, T> const& y) { T result = T(0); for(size_t i = 0; i < DIM; ++i) { result += x[i] * y[i]; } return result; }
00272 template<unsigned int DIM, typename T>
00273 inline T dot(T x, Vec<DIM, T> const& y) { return dot(Vec<DIM, T>(x), y); }
00274 template<unsigned int DIM, typename T>
00275 inline T dot(Vec<DIM, T> const& x, T y) { return dot(x, Vec<DIM, T>(y)); }
00276
00278 template<unsigned int DIM, typename T>
00279 inline T length2(Vec<DIM, T> const& x) { return dot(x, x); }
00280
00282 template<unsigned int DIM, typename T>
00283 inline T length(Vec<DIM, T> const& x) { return sqrt(length2(x)); }
00284
00286 template<unsigned int DIM, typename T>
00287 inline T distance2(Vec<DIM, T> const& x, Vec<DIM, T> const& y) { return length2(x - y); }
00288 template<unsigned int DIM, typename T>
00289 inline T distance2(T x, Vec<DIM, T> const& y) { return distance2(Vec<DIM, T>(x), y); }
00290 template<unsigned int DIM, typename T>
00291 inline T distance2(Vec<DIM, T> const& x, T y) { return distance2(x, Vec<DIM, T>(y)); }
00292
00294 template<unsigned int DIM, typename T>
00295 inline T distance(Vec<DIM, T> const& x, Vec<DIM, T> const& y) { return length(x - y); }
00296 template<unsigned int DIM, typename T>
00297 inline T distance(T x, Vec<DIM, T> const& y) { return distance(Vec<DIM, T>(x), y); }
00298 template<unsigned int DIM, typename T>
00299 inline T distance(Vec<DIM, T> const& x, T y) { return distance(x, Vec<DIM, T>(y)); }
00300
00302 template<typename T>
00303 inline Vec<3, T> cross(Vec<3, T> const& x, Vec<3, T> const& y) { return Vec<3, T>(x[1]*y[2] - y[1]*x[2], x[2]*y[0] - y[2]*x[0], x[0]*y[1] - y[0]*x[1] ); }
00304 template<typename T>
00305 inline Vec<3, T> cross(T x, Vec<3, T> const& y) { return cross(Vec<3, T>(x), y); }
00306 template<typename T>
00307 inline Vec<3, T> cross(Vec<3, T> const& x, T y) { return cross(x, Vec<3, T>(y)); }
00308
00310 template<unsigned int DIM, typename T>
00311 inline Vec<DIM, T> normalize(Vec<DIM, T> const& x) { return (x / length(x)); }
00312
00314 template<unsigned int DIM, typename T>
00315 inline Vec<DIM, T> faceforward(Vec<DIM, T> const& N, Vec<DIM, T> const& I, Vec<DIM, T> const& Nref) { return ((dot(Nref, I) < 0.0) ? N : -N); }
00316
00320 template<unsigned int DIM, typename T>
00321 inline Vec<DIM, T> reflect(Vec<DIM, T> const& I, Vec<DIM, T> const& N) { return (I – 2 * dot(N, I) * N); }
00322
00326 template<unsigned int DIM, typename T>
00327 inline Vec<DIM, T> refract(Vec<DIM, T> const& I, Vec<DIM, T> const& N, T eta) {
00328 const T k = T(1) - eta * eta * (T(1) - dot(N, I) * dot(N, I));
00329 if(k < T(0)) { return Vec<DIM, T>(T(0)); }
00330 return (eta * I - (eta * dot(N, I) + sqrt(k)) * N);
00331 }
00332
00333 }
00334
00335 #endif // VRS_VEC_MAT_OPS_H