00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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
00048
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
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) {
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
00181 ShAttrib<1, SH_CONST, T> ONE(1);
00182
for(
int i = 1; i < D + 1; ++i) {
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
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
00201
00202
00203
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
00217
for(i = 0; i < P; ++i) {
00218
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
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);
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
00254 groupEvenOddSort<L>(props);
00255
00256
00257
for(j = 0; j < L; ++j) result[j] = cast<K>(props[j]);
00258 }
00259
00260
template<
int K,
int D,
typename T>
00261 ShGeneric<K, T> worley(
const ShGeneric<D, T> &p,
bool useTexture) {
00262 DefaultGenFactory<D, T> genFactory(useTexture);
00263 DistSqPropFactory<D, T> propFactory;
00264
ShAttrib<K, SH_TEMP, T> result;
00265
worley(&result, p, &genFactory, &propFactory);
00266
return result;
00267 }
00268
00269
template<
int K,
int D,
typename T>
00270 ShProgram shWorley(
bool useTexture) {
00271 DefaultGenFactory<D, T> genFactory(useTexture);
00272 DistSqPropFactory<D, T> propFactory;
00273
return shWorley<K>(&genFactory, &propFactory);
00274 }
00275
00276
template<
int K,
int L,
int P,
int D,
typename T>
00277 ShProgram shWorley(
const GeneratorFactory<P, D, T> *genFactory,
00278
const PropertyFactory<L, D, T> *propFactory) {
00279 ShProgram program =
SH_BEGIN_PROGRAM() {
00280 ShTexCoord<D, SH_INPUT, T>
SH_DECL(texcoord);
00281
00282 ShAttrib<K, SH_OUTPUT, T> result[L];
00283 worley(&result[0], texcoord, genFactory, propFactory);
00284 }
SH_END_PROGRAM;
00285
return program;
00286 }
00287
00288 }
00289
00290
#endif