00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00020 #ifndef SHLIBGEOMETRYIMPL_HPP
00021 #define SHLIBGEOMETRYIMPL_HPP
00022
00023 #include "ShLibClamp.hpp"
00024 #include "ShAttrib.hpp"
00025 #include "ShInstructions.hpp"
00026
00027 namespace SH {
00028
00029 template<typename T1, typename T2>
00030 ShGeneric<3, CT1T2> cross(const ShGeneric<3, T1>& left, const ShGeneric<3, T2>& right)
00031 {
00032 ShAttrib<3, SH_TEMP, CT1T2> t;
00033 shXPD(t, left, right);
00034 return t;
00035 }
00036
00037 template<typename T1, typename T2>
00038 inline
00039 ShGeneric<3, CT1T2> operator^(const ShGeneric<3, T1>& left, const ShGeneric<3, T2>& right)
00040 {
00041 return cross(left, right);
00042 }
00043
00044 template<int N, typename T>
00045 ShGeneric<N, T> normalize(const ShGeneric<N, T>& var)
00046 {
00047 ShAttrib<N, SH_TEMP, T> t;
00048 shNORM(t, var);
00049 return t;
00050 }
00051
00052 template<int N1, int N2, typename T1, typename T2>
00053 ShGeneric<1, CT1T2> dot(const ShGeneric<N1, T1>& left, const ShGeneric<N2, T2>& right)
00054 {
00055 ShAttrib<1, SH_TEMP, CT1T2> t;
00056 if (N1 == N2) {
00057 shDOT(t, left, right);
00058 } else {
00059 shError(ShException("The two vectors are not of the same size."));
00060 }
00061 return t;
00062 }
00063
00064 template<int N, typename T1, typename T2>
00065 inline
00066 ShGeneric<1, CT1T2> operator|(const ShGeneric<N, T1>& left, const ShGeneric<N, T2>& right)
00067 {
00068 return dot(left, right);
00069 }
00070 SH_SHLIB_CONST_N_OP_RETSIZE_BOTH(dot, 1);
00071
00072 template<int N, typename T1, typename T2>
00073 ShGeneric<N, CT1T2> reflect(const ShGeneric<N, T1>& a, const ShGeneric<N, T2>& b)
00074 {
00075 ShGeneric<N, T2> bn = normalize(b);
00076 return 2 * dot(a, bn) * bn - a;
00077 }
00078
00079 template<int N, typename T1, typename T2, typename T3>
00080 ShGeneric<N, CT1T2T3> refract(const ShGeneric<N, T1>& v, const ShGeneric<N, T2>& n,
00081 const ShGeneric<1, T3>& eta)
00082 {
00083 ShGeneric<N, T1> vn = normalize(v);
00084 ShGeneric<N, T2> nn = normalize(n);
00085 ShGeneric<1, CT1T2T3> c = (vn|nn);
00086
00087 ShGeneric<1, T3> theta = rcp(eta);
00088
00089 ShGeneric<1, CT1T2T3> k = c*c - ShDataTypeConstant<CT1T2T3, SH_HOST>::One;
00090 k = ShDataTypeConstant<CT1T2T3, SH_HOST>::One + theta*theta*k;
00091 k = clamp(k, ShDataTypeConstant<CT1T2T3, SH_HOST>::Zero, ShDataTypeConstant<CT1T2T3, SH_HOST>::One);
00092 ShGeneric<1, CT1T2T3> a = -theta;
00093 ShGeneric<1, CT1T2T3> b = theta*c - sqrt(k);
00094 return (a*vn + b*nn);
00095 }
00096
00097 template<int N, typename T1, typename T2>
00098 inline
00099 ShGeneric<N, CT1T2> faceforward(const ShGeneric<N, T1>& a, const ShGeneric<N, T2>& b)
00100 {
00101 return (2 * (dot(a, b) > 0) - 1) * b;
00102 }
00103
00104 template<typename T1, typename T2, typename T3>
00105 ShGeneric<4, CT1T2T3> lit(const ShGeneric<1, T1>& a,
00106 const ShGeneric<1, T2>& b,
00107 const ShGeneric<1, T3>& c)
00108 {
00109 ShAttrib<4, SH_TEMP, CT1T2T3> i;
00110 ShAttrib<4, SH_TEMP, CT1T2T3> r;
00111 shLIT(r, join(a, b, c, c));
00112 return r;
00113 }
00114
00115 template<int N, typename T>
00116 inline
00117 ShGeneric<1, T> distance(const ShGeneric<N, T>& a, const ShGeneric<N, T>& b)
00118 {
00119 return length(a-b);
00120 }
00121
00122 template<int N, typename T>
00123 inline
00124 ShGeneric<1, T> distance_1(const ShGeneric<N, T>& a, const ShGeneric<N, T>& b)
00125 {
00126 return length_1(a-b);
00127 }
00128
00129 template<int N, typename T>
00130 inline
00131 ShGeneric<1, T> distance_inf(const ShGeneric<N, T>& a, const ShGeneric<N, T>& b)
00132 {
00133 return length_inf(a-b);
00134 }
00135
00136 template<int N, typename T>
00137 inline
00138 ShGeneric<1, T> length(const ShGeneric<N, T>& a)
00139 {
00140 return sqrt(dot(a, a));
00141 }
00142
00143 template<int N, typename T>
00144 inline
00145 ShGeneric<1, T> length_1(const ShGeneric<N, T>& a)
00146 {
00147 return sum(abs(a));
00148 }
00149
00150 template<int N, typename T>
00151 inline
00152 ShGeneric<1, T> length_inf(const ShGeneric<N, T>& a)
00153 {
00154 return max(abs(a));
00155 }
00156
00157 }
00158
00159 #endif