00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00020 #ifndef SHLIBWORLEYIMPL_HPP
00021 #define SHLIBWORLEYIMPL_HPP
00022
00023 #include "ShLibWorley.hpp"
00024 #include <cstdlib>
00025 #include "ShSyntax.hpp"
00026 #include "ShBaseTexture.hpp"
00027 #include "ShGeneric.hpp"
00028
00029 namespace SH {
00030
00031
00032
00033
00034 template<int N, int M>
00035 struct _IntPow {
00036 static const int value = N * _IntPow<N, M-1>::value;
00037 };
00038
00039 template<int N>
00040 struct _IntPow<N, 1> {
00041 static const int value = N;
00042 };
00043
00044
00045 template<int D, typename T>
00046 struct GridGenFactory: public GeneratorFactory<_IntPow<3, D>::value, D, T> {
00047 void operator()(const ShGeneric<D, T> &p, Generator<D, T> result[]) const;
00048
00049 private:
00050
00051
00052 virtual void makePos(Generator<D, T> &g) const = 0;
00053 };
00054
00055
00056
00057
00058
00059 template<int D, typename T>
00060 struct DefaultGenFactory: public GridGenFactory<D, T> {
00061 DefaultGenFactory(bool useTexture): m_useTexture(useTexture) {}
00062
00063 private:
00064 void makePos(Generator<D, T> &g) const;
00065 bool m_useTexture;
00066 };
00067
00068
00069
00070 template<int D, typename T>
00071 struct NullGenFactory: public GridGenFactory<D, T> {
00072 private:
00073 void makePos(Generator<D, T> &g) const;
00074 };
00075
00076
00077
00078
00079
00080 template<int D, typename T>
00081 struct LerpGenFactory: GridGenFactory<D, T> {
00082 LerpGenFactory(const ShGeneric<1, T> &time, bool useTexture);
00083
00084 private:
00085 void makePos(Generator<D, T> &g) const;
00086 const ShGeneric<1, T> &m_time;
00087 bool m_useTexture;
00088 };
00089
00090
00091
00092 template<int N, int D, typename T, typename P1, typename P2>
00093 struct CombinedPropFactory: public PropertyFactory<N, D, T> {
00094 CombinedPropFactory(const P1 *propFactory1, const P2 *propFactory2);
00095
00096 ShGeneric<N, T> operator()(const ShGeneric<D, T> &p,
00097 const Generator<D, T> &g) const;
00098
00099 private:
00100 const P1* m_propFactory1;
00101 const P2* m_propFactory2;
00102 };
00103
00104
00105
00106
00107
00108 template<int D, typename T>
00109 struct DistSqPropFactory: public PropertyFactory<1, D, T> {
00110 ShGeneric<1, T> operator()(const ShGeneric<D, T> &p,
00111 const Generator<D, T> &g) const;
00112 };
00113
00114 template<int D, typename T>
00115 struct Dist_1PropFactory: public PropertyFactory<1, D, T> {
00116 ShGeneric<1, T> operator()(const ShGeneric<D, T> &p,
00117 const Generator<D, T> &g) const;
00118 };
00119
00120 template<int D, typename T>
00121 struct Dist_InfPropFactory: public PropertyFactory<1, D, T> {
00122 ShGeneric<1, T> operator()(const ShGeneric<D, T> &p,
00123 const Generator<D, T> &g) const;
00124 };
00125
00126 template<int D, typename T>
00127 struct DistSqGradientPropFactory: public PropertyFactory<D + 1, D, T> {
00128 ShGeneric<D + 1, T> operator()(const ShGeneric<D, T> &p,
00129 const Generator<D, T> &g) const;
00130 };
00131
00132 template<int D, typename T>
00133 struct Dist_1GradientPropFactory: public PropertyFactory<D + 1, D, T> {
00134 ShGeneric<D + 1, T> operator()(const ShGeneric<D, T> &p,
00135 const Generator<D, T> &g) const;
00136 };
00137
00138 template<int D, typename T>
00139 struct Dist_InfGradientPropFactory: public PropertyFactory<D + 1, D, T> {
00140 ShGeneric<D + 1, T> operator()(const ShGeneric<D, T> &p,
00141 const Generator<D, T> &g) const;
00142 };
00143
00144 template<int N, int D, typename T>
00145 struct CellnoisePropFactory: public PropertyFactory<N, D, T> {
00146 CellnoisePropFactory(bool useTexture): m_useTexture(useTexture) {}
00147 ShGeneric<N, T> operator()(const ShGeneric<D, T> &p,
00148 const Generator<D, T> &g) const;
00149
00150 private:
00151 bool m_useTexture;
00152 };
00153
00154 template<typename TexType, typename T>
00155 struct Tex2DPropFactory: public PropertyFactory<TexType::typesize, 2, T> {
00156 Tex2DPropFactory(const ShBaseTexture2D<TexType> &tex,
00157 const ShGeneric<1, T> &scale);
00158 ShGeneric<TexType::typesize, T> operator()(const ShGeneric<2, T> &p,
00159 const Generator<2, T> &g) const
00160 {
00161
00162 return m_tex(frac(g.cell * invScale * m_scale)) * ShConstAttrib1f(1.0f);
00163 }
00164
00165 private:
00166 const ShBaseTexture2D<TexType> &m_tex;
00167 const ShGeneric<1, T> &m_scale;
00168 ShConstAttrib2f invScale;
00169
00170 };
00171
00172
00173
00174
00175
00176 template<int D, typename T>
00177 void GridGenFactory<D, T>::operator()(const ShGeneric<D, T> &p,
00178 Generator<D, T> result[]) const
00179 {
00180 ShAttrib<D, SH_TEMP, T> pCell = floor(p);
00181
00182
00183
00184 int i, j, offsetBits;
00185 ShConstAttrib3f offsets(-1, 0, 1);
00186 int offsetSwiz[D];
00187 j = 0;
00188 for(offsetBits = 0; offsetBits < (1 << (D * 2)); ++offsetBits) {
00189 for(i = 0; i < D; ++i) {
00190 offsetSwiz[i] = ((offsetBits >> (i * 2)) & 3);
00191 if(offsetSwiz[i] == 3) break;
00192 }
00193 if(i < D) continue;
00194
00195 Generator<D, T> gen;
00196 result[j].offset = offsets.template swiz<D>(offsetSwiz);
00197 SH_DEBUG_PRINT("Offset:" << result[j].offset);
00198 result[j].cell = pCell + result[j].offset;
00199 makePos(result[j]);
00200 ++j;
00201 }
00202 }
00203
00204 template<int D, typename T>
00205 void DefaultGenFactory<D, T>::makePos(Generator<D, T> &g) const
00206 {
00207 g.pos = g.cell + cellnoise<D>(g.cell, m_useTexture);
00208 }
00209
00210 template<int D, typename T>
00211 void NullGenFactory<D, T>::makePos(Generator<D, T> &g) const
00212 {
00213 g.pos = g.cell + fillcast<D>(ShAttrib<1, SH_CONST, T>(0.5f));
00214 }
00215
00216 template<int D, typename T>
00217 LerpGenFactory<D, T>::LerpGenFactory(const ShGeneric<1, T> &time, bool useTexture)
00218 : m_time(time), m_useTexture(useTexture)
00219 {
00220 }
00221
00222 template<int D, typename T>
00223 void LerpGenFactory<D, T>::makePos(Generator<D, T> &g) const
00224 {
00225 ShAttrib<1, SH_TEMP, T> lastTime = floor(m_time);
00226 ShAttrib<1, SH_TEMP, T> timeOffset = frac(m_time);
00227 ShAttrib<D + 1, SH_TEMP, T> offsetCell;
00228
00229 offsetCell = fillcast<D+1>(g.cell);
00230 offsetCell(D) = lastTime;
00231 ShAttrib<D, SH_TEMP, T> p1 = cellnoise<D>(offsetCell, m_useTexture);
00232
00233 offsetCell(D) += 1;
00234 ShAttrib<D, SH_TEMP, T> p2 = cellnoise<D>(offsetCell, m_useTexture);
00235
00236 g.pos = g.cell + lerp(timeOffset, p2, p1);
00237 }
00238
00239 template<int N, int D, typename T, typename P1, typename P2>
00240 CombinedPropFactory<N, D, T, P1, P2>::CombinedPropFactory(const P1 *propFactory1,
00241 const P2 *propFactory2)
00242 : m_propFactory1(propFactory1), m_propFactory2(propFactory2)
00243 {
00244 }
00245
00246 template<int N, int D, typename T, typename P1, typename P2>
00247 ShGeneric<N, T>
00248 CombinedPropFactory<N, D, T, P1, P2>::operator()(const ShGeneric<D, T> &p,
00249 const Generator<D, T> &g) const
00250 {
00251 return join((*m_propFactory1)(p, g), (*m_propFactory2)(p, g));
00252 }
00253
00254 template<typename P1, typename P2>
00255 PropertyFactory<P1::NUM_PROPS + P2::NUM_PROPS, P1::DIM, typename P1::PropType>*
00256 combine(const P1 *propFactory1, const P2 *propFactory2)
00257 {
00258 const int N = P1::NUM_PROPS + P2::NUM_PROPS;
00259 return new CombinedPropFactory<N, P1::DIM, typename P1::PropType, P1, P2>(propFactory1, propFactory2);
00260 }
00261
00262 template<int D, typename T>
00263 ShGeneric<1, T>
00264 DistSqPropFactory<D, T>::operator()(const ShGeneric<D, T> &p,
00265 const Generator<D, T> &g) const
00266 {
00267 ShAttrib<D, SH_TEMP, T> delta = p - g.pos;
00268 return delta | delta;
00269 }
00270
00271 template<int D, typename T>
00272 ShGeneric<1, T>
00273 Dist_1PropFactory<D, T>::operator() (const ShGeneric<D, T> &p,
00274 const Generator<D, T> &g) const
00275 {
00276 ShAttrib<D, SH_TEMP, T> delta = abs(p - g.pos);
00277 return delta | fillcast<D>(ShConstAttrib1f(1.0f));
00278 }
00279
00280 template<int D, typename T>
00281 ShGeneric<1, T>
00282 Dist_InfPropFactory<D, T>::operator() (const ShGeneric<D, T> &p,
00283 const Generator<D, T> &g) const
00284 {
00285 ShAttrib<D, SH_TEMP, T> delta = abs(p - g.pos);
00286
00287
00288 ShAttrib<1, SH_TEMP, T> result = 0;
00289 for(int i = 0; i < D; ++i) result = max(result, delta(i));
00290 return result;
00291 }
00292
00293 template<int D, typename T>
00294 ShGeneric<D + 1, T>
00295 DistSqGradientPropFactory<D, T>::operator() (const ShGeneric<D, T> &p,
00296 const Generator<D, T> &g) const
00297 {
00298 ShAttrib<D + 1, SH_TEMP, T> result;
00299 ShAttrib<D, SH_TEMP, T> delta = p - g.pos;
00300
00301 result(0) = delta | delta;
00302 for(int i = 1; i < D + 1; ++i) {
00303 result(i) = delta(i-1) * result(0);
00304 }
00305 return result;
00306 }
00307
00308 template<int D, typename T>
00309 ShGeneric<D + 1, T>
00310 Dist_1GradientPropFactory<D, T>::operator() (const ShGeneric<D, T> &p,
00311 const Generator<D, T> &g) const
00312 {
00313
00314 ShAttrib<D + 1, SH_TEMP, T> result;
00315 ShAttrib<D, SH_TEMP, T> delta = p - g.pos;
00316
00317 ShAttrib<1, SH_CONST, T> ONE(1);
00318 result(0) = abs(delta) | fillcast<D>(ONE);
00319 for(int i = 1; i < D + 1; ++i) {
00320 result(i) = cond(delta(i-1), ONE, -ONE);
00321 }
00322 return result;
00323 }
00324
00325 template<int D, typename T>
00326 ShGeneric<D + 1, T>
00327 Dist_InfGradientPropFactory<D, T>::operator() (const ShGeneric<D, T> &p,
00328 const Generator<D, T> &g) const
00329 {
00330 ShAttrib<D + 1, SH_TEMP, T> result;
00331 ShAttrib<D, SH_TEMP, T> delta = p - g.pos;
00332 ShAttrib<D, SH_TEMP, T> absDelta = abs(delta);
00333
00334 result(0) = 0;
00335 for(int i = 0; i < D; ++i) result(0) = max(result(0), absDelta(i));
00336
00337
00338 ShAttrib<1, SH_CONST, T> ONE(1);
00339 for(int i = 1; i < D + 1; ++i) {
00340 result(i) = (absDelta(i-1) >= result(0)) * cond(delta(i-1), ONE, -ONE);
00341 }
00342 return result;
00343 }
00344
00345 template<int N, int D, typename T>
00346 ShGeneric<N, T>
00347 CellnoisePropFactory<N, D, T>::operator() (const ShGeneric<D, T> &p,
00348 const Generator<D, T> &g) const
00349 {
00350 return cellnoise<N>(g.cell, m_useTexture);
00351 }
00352
00353 template<typename TexType, typename T>
00354 Tex2DPropFactory<TexType, T>::Tex2DPropFactory(const ShBaseTexture2D<TexType> &tex,
00355 const ShGeneric<1, T> &scale)
00356 : m_tex(tex), m_scale(scale),
00357 invScale(ShConstAttrib2f(1.0f, 1.0f) / tex.size())
00358 {
00359 }
00360
00361 template<int N, int K, int P, typename T>
00362 void kSelect(const ShGeneric<P, T> vals[N], ShGeneric<K, T> result[N],
00363 float LARGE = 1e10)
00364 {
00365 result[0] = fillcast<K>(ShConstAttrib1f(LARGE));
00366
00367 int i, j, k, l;
00368 int shiftswiz[K];
00369 ShAttrib1f c;
00370 for(i = 0; i < K; ++i) shiftswiz[i] = (i == 0 ? 0 : i - 1);
00371
00372
00373 for(i = 0; i < P; ++i) {
00374
00375 c = vals[0](i) < result[0](0);
00376 for(j = 0; j < N; ++j) {
00377 result[0] = lerp(c, result[0].template swiz<K>(shiftswiz), result[0]);
00378 result[0](0) = lerp(c, vals[0](i), result[0](0));
00379 }
00380
00381
00382 for(j = 1; j < K; ++j) {
00383 c = (result[0](j-1) < vals[0](i)) * (vals[0](i) < result[0](j));
00384 for(k = 0; k < N; ++k) {
00385 for(l = 0; l < K; ++l) shiftswiz[l] = l + ( l >= j ? -1 : 0);
00386 result[k] = lerp(c, result[k].template swiz<K>(shiftswiz), result[k]);
00387 result[k](j) = lerp(c, vals[k](i), result[k](j));
00388 }
00389 }
00390 }
00391 }
00392
00393 template<int K, int L, int P, int D, typename T>
00394 void worley(ShGeneric<K, T> result[], const ShGeneric<D, T> &p,
00395 const GeneratorFactory<P, D, T> *genFactory,
00396 const PropertyFactory<L, D, T> *propFactory)
00397 {
00398 int i, j;
00399 Generator<D, T> generators[P];
00400 ShAttrib<P, SH_TEMP, T> props[L];
00401 ShAttrib<L, SH_TEMP, T> propTemp;
00402
00403 (*genFactory)(p, generators);
00404 for(i = 0; i < P; ++i) {
00405 propTemp = (*propFactory)(p, generators[i]);
00406 for(j = 0; j < L; ++j) props[j](i) = propTemp(j);
00407 }
00408
00409
00410 groupsort<L>(props);
00411
00412
00413 for(j = 0; j < L; ++j) result[j] = cast<K>(props[j]);
00414 }
00415
00416 template<int K, int D, typename T>
00417 ShGeneric<K, T> worley(const ShGeneric<D, T> &p,
00418 #ifdef WIN32
00419 bool useTexture=true)
00420 #else
00421 bool useTexture)
00422 #endif
00423 {
00424 DefaultGenFactory<D, T> genFactory(useTexture);
00425 DistSqPropFactory<D, T> propFactory;
00426 ShAttrib<K, SH_TEMP, T> result;
00427 worley(&result, p, &genFactory, &propFactory);
00428 return result;
00429 }
00430
00431 template<int K, int D, typename T>
00432 ShProgram shWorley(
00433 #ifdef WIN32
00434 bool useTexture=true)
00435 #else
00436 bool useTexture)
00437 #endif
00438 {
00439 DefaultGenFactory<D, T> genFactory(useTexture);
00440 DistSqPropFactory<D, T> propFactory;
00441 return shWorley<K>(&genFactory, &propFactory);
00442 }
00443
00444 template<int K, int L, int P, int D, typename T>
00445 ShProgram shWorley(const GeneratorFactory<P, D, T> *genFactory,
00446 const PropertyFactory<L, D, T> *propFactory)
00447 {
00448 ShProgram program = SH_BEGIN_PROGRAM() {
00449 ShAttrib<D, SH_INPUT, T, SH_TEXCOORD> SH_DECL(texcoord);
00450
00451 ShAttrib<K, SH_OUTPUT, T> result[L];
00452 worley(&result[0], texcoord, genFactory, propFactory);
00453 } SH_END_PROGRAM;
00454 return program;
00455 }
00456
00457 }
00458
00459 #endif // SHLIBWORLEYIMPL_HPP