Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

ShWorleyImpl.hpp

00001 // Sh: A GPU metaprogramming language.
00002 //
00003 // Copyright (c) 2003 University of Waterloo Computer Graphics Laboratory
00004 // Project administrator: Michael D. McCool
00005 // Authors: Zheng Qin, Stefanus Du Toit, Kevin Moule, Tiberiu S. Popa,
00006 //          Bryan Chan, Michael D. McCool
00007 // 
00008 // This software is provided 'as-is', without any express or implied
00009 // warranty. In no event will the authors be held liable for any damages
00010 // arising from the use of this software.
00011 // 
00012 // Permission is granted to anyone to use this software for any purpose,
00013 // including commercial applications, and to alter it and redistribute it
00014 // freely, subject to the following restrictions:
00015 // 
00016 // 1. The origin of this software must not be misrepresented; you must
00017 // not claim that you wrote the original software. If you use this
00018 // software in a product, an acknowledgment in the product documentation
00019 // would be appreciated but is not required.
00020 // 
00021 // 2. Altered source versions must be plainly marked as such, and must
00022 // not be misrepresented as being the original software.
00023 // 
00024 // 3. This notice may not be removed or altered from any source
00025 // distribution.
00027 
00028 #ifndef SHUTIL_WORLEYIMPL_HPP 
00029 #define SHUTIL_WORLEYIMPL_HPP
00030 
00031 #include <cstdlib>
00032 #include "ShSyntax.hpp"
00033 #include "ShWorley.hpp"
00034 #include "ShNoise.hpp"
00035 #include "ShFunc.hpp"
00036 #include "ShImage.hpp"
00037 #include "ShTexCoord.hpp"
00038 
00039 namespace ShUtil {
00040 
00041 using namespace SH;
00042 
00043 template<int D, typename T>
00044 void GridGenFactory<D, T>::operator()(const ShGeneric<D, T> &p, Generator<D, T> result[]) const {
00045   ShAttrib<D, SH_TEMP, T> pCell = floor(p);
00046 
00047   // each set of two bits represents offset along one dimension
00048   // if the bit value = 0, offset by -1, 1 = no offset, 2 = offset by 1 
00049   int i, j, offsetBits;
00050   ShConstAttrib3f offsets(-1, 0, 1);
00051   int offsetSwiz[D];
00052   j = 0;
00053   for(offsetBits = 0; offsetBits < (1 << (D * 2)); ++offsetBits) {
00054     for(i = 0; i < D; ++i) {
00055       offsetSwiz[i] = ((offsetBits >> (i * 2)) & 3); 
00056       if(offsetSwiz[i] == 3) break;
00057     }
00058     if(i < D) continue;
00059 
00060     Generator<D, T> gen;
00061     result[j].offset = offsets.template swiz<D>(offsetSwiz); 
00062     SH_DEBUG_PRINT("Offset:" << result[j].offset); 
00063     result[j].cell = pCell + result[j].offset;
00064     makePos(result[j]);
00065     ++j;
00066   }
00067 }
00068 
00069 
00070 template<int D, typename T>
00071 void DefaultGenFactory<D, T>::makePos(Generator<D, T> &g) const {
00072   g.pos = g.cell + cellnoise<D>(g.cell, m_useTexture);
00073 }
00074 
00075 template<int D, typename T>
00076 void NullGenFactory<D, T>::makePos(Generator<D, T> &g) const {
00077   g.pos = g.cell + fillcast<D>(ShAttrib<1, SH_CONST, T>(0.5f)); 
00078 }
00079 
00080 template<int D, typename T>
00081 LerpGenFactory<D, T>::LerpGenFactory(const ShGeneric<1, T> &time, bool useTexture)
00082   : m_time(time), m_useTexture(useTexture) {}
00083 
00084 template<int D, typename T>
00085 void LerpGenFactory<D, T>::makePos(Generator<D, T> &g) const {
00086   ShAttrib<1, SH_TEMP, T> lastTime = floor(m_time);
00087   ShAttrib<1, SH_TEMP, T> timeOffset = frac(m_time);
00088   ShAttrib<D + 1, SH_TEMP, T> offsetCell;
00089 
00090   offsetCell = fillcast<D+1>(g.cell);
00091   offsetCell(D) = lastTime;
00092   ShAttrib<D, SH_TEMP, T> p1 = cellnoise<D>(offsetCell, m_useTexture); 
00093 
00094   offsetCell(D) += 1;
00095   ShAttrib<D, SH_TEMP, T> p2 = cellnoise<D>(offsetCell, m_useTexture); 
00096 
00097   g.pos = g.cell + lerp(timeOffset, p2, p1);
00098 }
00099 
00100 template<int N, int D, typename T, typename P1, typename P2>
00101 CombinedPropFactory<N, D, T, P1, P2>::CombinedPropFactory(const P1 *propFactory1, const P2 *propFactory2)
00102   : m_propFactory1(propFactory1), m_propFactory2(propFactory2) {}
00103 
00104 template<int N, int D, typename T, typename P1, typename P2>
00105 ShGeneric<N, T> CombinedPropFactory<N, D, T, P1, P2>::operator()(
00106     const ShGeneric<D, T> &p, const Generator<D, T> &g) const {
00107   return join((*m_propFactory1)(p, g), (*m_propFactory2)(p, g));
00108 }
00109 
00110 template<typename P1, typename P2>
00111 PropertyFactory<P1::NUM_PROPS + P2::NUM_PROPS, P1::DIM, typename P1::PropType>*
00112 combine(const P1 *propFactory1, const P2 *propFactory2) {
00113   const int N = P1::NUM_PROPS + P2::NUM_PROPS;
00114   return new CombinedPropFactory<N, P1::DIM, typename P1::PropType, P1, P2>(propFactory1, propFactory2);
00115 }
00116 
00117 template<int D, typename T>
00118 ShGeneric<1, T> DistSqPropFactory<D, T>::operator()(
00119     const ShGeneric<D, T> &p, const Generator<D, T> &g) const {
00120   ShAttrib<D, SH_TEMP, T> delta = p - g.pos;
00121   return delta | delta; 
00122 }
00123 
00124 template<int D, typename T>
00125 ShGeneric<1, T> Dist_1PropFactory<D, T>::operator() (
00126     const ShGeneric<D, T> &p, const Generator<D, T> &g) const {
00127   ShAttrib<D, SH_TEMP, T> delta = abs(p - g.pos);
00128   return delta | fillcast<D>(ShConstAttrib1f(1.0f)); 
00129 }
00130 
00131 template<int D, typename T>
00132 ShGeneric<1, T> Dist_InfPropFactory<D, T>::operator() (
00133     const ShGeneric<D, T> &p, const Generator<D, T> &g) const {
00134   ShAttrib<D, SH_TEMP, T> delta = abs(p - g.pos);
00135 
00136   // TODO replace with tuple max function when implemented 
00137   ShAttrib<1, SH_TEMP, T> result = 0; 
00138   for(int i = 0; i < D; ++i) result = max(result, delta(i));
00139   return result;
00140 }
00141 
00142 template<int D, typename T>
00143 ShGeneric<D + 1, T> DistSqGradientPropFactory<D, T>::operator() (
00144     const ShGeneric<D, T> &p, const Generator<D, T> &g) const {
00145   ShAttrib<D + 1, SH_TEMP, T> result;
00146   ShAttrib<D, SH_TEMP, T> delta = p - g.pos;
00147 
00148   result(0) = delta | delta; 
00149   for(int i = 1; i < D + 1; ++i) {
00150     result(i) = delta(i-1) * result(0);
00151   }
00152   return result;
00153 };
00154 
00155 template<int D, typename T>
00156 ShGeneric<D + 1, T> Dist_1GradientPropFactory<D, T>::operator() (
00157     const ShGeneric<D, T> &p, const Generator<D, T> &g) const {
00158 
00159   ShAttrib<D + 1, SH_TEMP, T> result;
00160   ShAttrib<D, SH_TEMP, T> delta = p - g.pos;
00161 
00162   ShAttrib<1, SH_CONST, T> ONE(1);
00163   result(0) = abs(delta) | fillcast<D>(ONE);
00164   for(int i = 1; i < D + 1; ++i) { // TODO switch to a swizzled version
00165     result(i) = cond(delta(i-1), ONE, -ONE); 
00166   }
00167   return result;
00168 };
00169 
00170 template<int D, typename T>
00171 ShGeneric<D + 1, T> Dist_InfGradientPropFactory<D, T>::operator() (
00172     const ShGeneric<D, T> &p, const Generator<D, T> &g) const {
00173   ShAttrib<D + 1, SH_TEMP, T> result;
00174   ShAttrib<D, SH_TEMP, T> delta = p - g.pos;
00175   ShAttrib<D, SH_TEMP, T> absDelta = abs(delta); 
00176 
00177   result(0) = 0;
00178   for(int i = 0; i < D; ++i) result(0) = max(result(0), absDelta(i)); 
00179 
00180   // TODO remove this when constant folding is available
00181   ShAttrib<1, SH_CONST, T> ONE(1);
00182   for(int i = 1; i < D + 1; ++i) { // TODO switch to a swizzled version
00183     result(i) = (absDelta(i-1) >= result(0)) * cond(delta(i-1), ONE, -ONE); 
00184   }
00185   return result;
00186 };
00187 
00188 template<int N, int D, typename T>
00189 ShGeneric<N, T> CellnoisePropFactory<N, D, T>::operator() (
00190     const ShGeneric<D, T> &p, const Generator<D, T> &g) const {
00191   // TODO remove frac once Issue58 fixed
00192   return frac(cellnoise<N>(g.cell, m_useTexture));
00193 };
00194 
00195 template<typename TexType, typename T>
00196 Tex2DPropFactory<TexType, T>::Tex2DPropFactory(
00197     const ShBaseTexture2D<TexType> &tex, const ShGeneric<1, T> &scale)
00198   : m_tex(tex), m_scale(scale), invScale(ShConstAttrib2f(1.0f, 1.0f) / tex.size()) {}
00199 
00200 /* Moved to ShWorley.hpp
00201 template<typename TexType, typename T>
00202 ShGeneric<TexType::typesize, T> Tex2DPropFactory<TexType, T>::operator()(
00203     const ShGeneric<2, T> &p, const Generator<2, T> &g) const {
00204 }
00205 */
00206 
00207 template<int N, int K, int P, typename T>
00208 void kSelect(const ShGeneric<P, T> vals[N], ShGeneric<K, T> result[N], float LARGE = 1e10) {
00209   result[0] = fillcast<K>(ShConstAttrib1f(LARGE));
00210 
00211   int i, j, k, l;
00212   int shiftswiz[K];
00213   ShAttrib1f c;
00214   for(i = 0; i < K; ++i) shiftswiz[i] = (i == 0 ? 0 : i - 1);
00215 
00216   // insert into result one by one
00217   for(i = 0; i < P; ++i) {
00218     // check if smaller than the first one
00219     c = vals[0](i) < result[0](0);
00220     for(j = 0; j < N; ++j) {
00221       result[0] = lerp(c, result[0].template swiz<K>(shiftswiz), result[0]); 
00222       result[0](0) = lerp(c, vals[0](i), result[0](0));
00223     }
00224 
00225     // check for the other ones
00226     for(j = 1; j < K; ++j) {
00227       c = (result[0](j-1) < vals[0](i)) * (vals[0](i) < result[0](j));
00228       for(k = 0; k < N; ++k) {
00229         for(l = 0; l < K; ++l) shiftswiz[l] = l + ( l >= j ? -1 : 0); 
00230         result[k] = lerp(c, result[k].template swiz<K>(shiftswiz), result[k]);
00231         result[k](j) = lerp(c, vals[k](i), result[k](j));
00232       }
00233     }
00234   }
00235 }
00236 
00237 template<int K, int L, int P, int D, typename T>
00238 void worley(ShGeneric<K, T> result[], const ShGeneric<D, T> &p,
00239     const GeneratorFactory<P, D, T> *genFactory,
00240     const PropertyFactory<L, D, T> *propFactory) {
00241 
00242   int i, j;
00243   Generator<D, T> generators[P];
00244   ShAttrib<P, SH_TEMP, T> props[L]; 
00245   ShAttrib<L, SH_TEMP, T> propTemp; 
00246 
00247   (*genFactory)(p, generators); // make generators
00248   for(i = 0; i < P; ++i) {
00249     propTemp = (*propFactory)(p, generators[i]);
00250     for(j = 0; j < L; ++j) props[j](i) = propTemp(j);
00251   }
00252 
00253   // sort points & gradients by distance
00254   groupEvenOddSort<L>(props); 
00255 
00256   // weighted sum of basis function values to get final result
00257   for(j = 0; j < L; ++j) result[j] = cast<K>(props[j]);
00258 }
00259 
00260 template<int K, int D, typename T>
00261 #ifdef WIn32
00262 ShGeneric<K, T> worley(const ShGeneric<D, T> &p, bool useTexture=true) {
00263 #else
00264 ShGeneric<K, T> worley(const ShGeneric<D, T> &p, bool useTexture=true) {
00265 #endif
00266   DefaultGenFactory<D, T> genFactory(useTexture);
00267   DistSqPropFactory<D, T> propFactory;
00268   ShAttrib<K, SH_TEMP, T> result;
00269   worley(&result, p, &genFactory, &propFactory);
00270   return result;
00271 }
00272 
00273 template<int K, int D, typename T>
00274 #ifdef WIn32
00275 ShProgram shWorley(bool useTexture=true) {
00276 #else
00277 ShProgram shWorley(bool useTexture) {
00278 #endif
00279   DefaultGenFactory<D, T> genFactory(useTexture);
00280   DistSqPropFactory<D, T> propFactory;
00281   return shWorley<K>(&genFactory, &propFactory); 
00282 }
00283 
00284 template<int K, int L, int P, int D, typename T>
00285 ShProgram shWorley(const GeneratorFactory<P, D, T> *genFactory,
00286         const PropertyFactory<L, D, T> *propFactory) {
00287   ShProgram program = SH_BEGIN_PROGRAM() {
00288     ShTexCoord<D, SH_INPUT, T> SH_DECL(texcoord);
00289 
00290     ShAttrib<K, SH_OUTPUT, T> result[L]; 
00291     worley(&result[0], texcoord, genFactory, propFactory); 
00292   } SH_END_PROGRAM;
00293   return program;
00294 }
00295 
00296 }
00297 
00298 #endif

Generated on Mon Jan 24 18:36:37 2005 for Sh by  doxygen 1.4.1