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
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <math.h>
00035
00036 #include "blender_texlib.h"
00037
00038 namespace blender {
00039
00040 typedef unsigned long long r_uint64;
00041
00042 #define RNG_MULTIPLIER 0x5DEECE66Dll
00043 #define RNG_MASK 0x0000FFFFFFFFFFFFll
00044 #define RNG_ADDEND 0xB
00045
00046 struct RNG {
00047 r_uint64 X;
00048 };
00049
00050 static RNG theBLI_rng = {0};
00051
00052 int rng_getInt(RNG *rng) {
00053 rng->X = (RNG_MULTIPLIER * rng->X + RNG_ADDEND) & RNG_MASK;
00054 return (int) (rng->X >> 17);
00055 }
00056
00057 int BLI_rand(void) {
00058 return rng_getInt(&theBLI_rng);
00059 }
00060
00061
00062
00063 static int blend(const Tex *tex, const float *texvec, TexResult *texres) {
00064 float x, y, t;
00065
00066 if (tex->flag & TEX_FLIPBLEND) {
00067 x = texvec[1];
00068 y = texvec[0];
00069 } else {
00070 x = texvec[0];
00071 y = texvec[1];
00072 }
00073
00074 if (tex->stype == TEX_LIN) {
00075 texres->tin = (1.0 + x) / 2.0;
00076 } else if (tex->stype == TEX_QUAD) {
00077 texres->tin = (1.0 + x) / 2.0;
00078 if (texres->tin < 0.0) texres->tin = 0.0;
00079 else texres->tin *= texres->tin;
00080 } else if (tex->stype == TEX_EASE) {
00081 texres->tin = (1.0 + x) / 2.0;
00082 if (texres->tin <= .0) texres->tin = 0.0;
00083 else if (texres->tin >= 1.0) texres->tin = 1.0;
00084 else {
00085 t = texres->tin * texres->tin;
00086 texres->tin = (3.0 * t - 2.0 * t * texres->tin);
00087 }
00088 } else if (tex->stype == TEX_DIAG) {
00089 texres->tin = (2.0 + x + y) / 4.0;
00090 } else if (tex->stype == TEX_RAD) {
00091 texres->tin = (atan2(y, x) / (2 * M_PI) + 0.5);
00092 } else {
00093 texres->tin = 1.0 - sqrt(x * x + y * y + texvec[2] * texvec[2]);
00094 if (texres->tin < 0.0) texres->tin = 0.0;
00095 if (tex->stype == TEX_HALO) texres->tin *= texres->tin;
00096 }
00097
00098 BRICONT;
00099
00100 return TEX_INT;
00101 }
00102
00103
00104
00105
00106
00107
00108 static int clouds(const Tex *tex, const float *texvec, TexResult *texres) {
00109 int rv = TEX_INT;
00110
00111 texres->tin = BLI_gTurbulence(tex->noisesize, texvec[0], texvec[1], texvec[2], tex->noisedepth, (tex->noisetype != TEX_NOISESOFT), tex->noisebasis);
00112
00113 if (tex->stype == TEX_COLOR) {
00114
00115
00116 texres->tr = texres->tin;
00117 texres->tg = BLI_gTurbulence(tex->noisesize, texvec[1], texvec[0], texvec[2], tex->noisedepth, (tex->noisetype != TEX_NOISESOFT), tex->noisebasis);
00118 texres->tb = BLI_gTurbulence(tex->noisesize, texvec[1], texvec[2], texvec[0], tex->noisedepth, (tex->noisetype != TEX_NOISESOFT), tex->noisebasis);
00119 BRICONTRGB;
00120 texres->ta = 1.0;
00121 return (rv | TEX_RGB);
00122 }
00123
00124 BRICONT;
00125
00126 return rv;
00127
00128 }
00129
00130
00131 static float tex_sin(float a) {
00132 a = 0.5 + 0.5 * sin(a);
00133
00134 return a;
00135 }
00136
00137
00138 static float tex_saw(float a) {
00139 const float b = 2 * M_PI;
00140
00141 int n = (int) (a / b);
00142 a -= n*b;
00143 if (a < 0) a += b;
00144 return a / b;
00145 }
00146
00147
00148 static float tex_tri(float a) {
00149 const float b = 2 * M_PI;
00150 const float rmax = 1.0;
00151
00152 a = rmax - 2.0 * fabs(floor((a * (1.0 / b)) + 0.5) - (a * (1.0 / b)));
00153
00154 return a;
00155 }
00156
00157
00158 static float wood_int(const Tex *tex, float x, float y, float z) {
00159 float wi = 0;
00160 short wf = tex->noisebasis2;
00161 short wt = tex->stype;
00162
00163 float (*waveform[3])(float);
00164 waveform[0] = tex_sin;
00165 waveform[1] = tex_saw;
00166 waveform[2] = tex_tri;
00167
00168 if ((wf > TEX_TRI) || (wf < TEX_SIN)) wf = 0;
00169
00170 if (wt == TEX_BAND) {
00171 wi = waveform[wf]((x + y + z)*10.0);
00172 } else if (wt == TEX_RING) {
00173 wi = waveform[wf](sqrt(x * x + y * y + z * z)*20.0);
00174 } else if (wt == TEX_BANDNOISE) {
00175 wi = tex->turbul * BLI_gNoise(tex->noisesize, x, y, z, (tex->noisetype != TEX_NOISESOFT), tex->noisebasis);
00176 wi = waveform[wf]((x + y + z)*10.0 + wi);
00177 } else if (wt == TEX_RINGNOISE) {
00178 wi = tex->turbul * BLI_gNoise(tex->noisesize, x, y, z, (tex->noisetype != TEX_NOISESOFT), tex->noisebasis);
00179 wi = waveform[wf](sqrt(x * x + y * y + z * z)*20.0 + wi);
00180 }
00181
00182 return wi;
00183 }
00184
00185 static int wood(const Tex *tex, const float *texvec, TexResult *texres) {
00186 int rv = TEX_INT;
00187
00188 texres->tin = wood_int(tex, texvec[0], texvec[1], texvec[2]);
00189
00190 BRICONT;
00191
00192 return rv;
00193 }
00194 #include <stdio.h>
00195
00196 static float marble_int(const Tex *tex, float x, float y, float z) {
00197 float n, mi;
00198 short wf = tex->noisebasis2;
00199 short mt = tex->stype;
00200
00201 float (*waveform[3])(float);
00202 waveform[0] = tex_sin;
00203 waveform[1] = tex_saw;
00204 waveform[2] = tex_tri;
00205
00206 if ((wf > TEX_TRI) || (wf < TEX_SIN)) wf = 0;
00207
00208 n = 5.0 * (x + y + z);
00209
00210 mi = n + tex->turbul * BLI_gTurbulence(tex->noisesize, x, y, z, tex->noisedepth, (tex->noisetype != TEX_NOISESOFT), tex->noisebasis);
00211
00212 if (mt >= TEX_SOFT) {
00213 mi = waveform[wf](mi);
00214 if (mt == TEX_SHARP) {
00215 mi = sqrt(mi);
00216 }
00217 else if (mt == TEX_SHARPER) {
00218 mi = sqrt(sqrt(mi));
00219 }
00220 }
00221
00222 return mi;
00223 }
00224
00225 static int marble(const Tex *tex, const float *texvec, TexResult *texres) {
00226 int rv = TEX_INT;
00227
00228 texres->tin = marble_int(tex, texvec[0], texvec[1], texvec[2]);
00229
00230 BRICONT;
00231
00232 return rv;
00233 }
00234
00235
00236
00237 static int magic(const Tex *tex, const float *texvec, TexResult *texres) {
00238 float x, y, z, turb = 1.0;
00239 int n;
00240
00241 n = tex->noisedepth;
00242 turb = tex->turbul / 5.0;
00243
00244 x = sin((texvec[0] + texvec[1] + texvec[2])*5.0);
00245 y = cos((-texvec[0] + texvec[1] - texvec[2])*5.0);
00246 z = -cos((-texvec[0] - texvec[1] + texvec[2])*5.0);
00247 if (n > 0) {
00248 x *= turb;
00249 y *= turb;
00250 z *= turb;
00251 y = -cos(x - y + z);
00252 y *= turb;
00253 if (n > 1) {
00254 x = cos(x - y - z);
00255 x *= turb;
00256 if (n > 2) {
00257 z = sin(-x - y - z);
00258 z *= turb;
00259 if (n > 3) {
00260 x = -cos(-x + y - z);
00261 x *= turb;
00262 if (n > 4) {
00263 y = -sin(-x + y + z);
00264 y *= turb;
00265 if (n > 5) {
00266 y = -cos(-x + y + z);
00267 y *= turb;
00268 if (n > 6) {
00269 x = cos(x + y + z);
00270 x *= turb;
00271 if (n > 7) {
00272 z = sin(x + y - z);
00273 z *= turb;
00274 if (n > 8) {
00275 x = -cos(-x - y + z);
00276 x *= turb;
00277 if (n > 9) {
00278 y = -sin(x - y + z);
00279 y *= turb;
00280 }
00281 }
00282 }
00283 }
00284 }
00285 }
00286 }
00287 }
00288 }
00289 }
00290
00291 if (turb != 0.0) {
00292 turb *= 2.0;
00293 x /= turb;
00294 y /= turb;
00295 z /= turb;
00296 }
00297 texres->tr = 0.5 - x;
00298 texres->tg = 0.5 - y;
00299 texres->tb = 0.5 - z;
00300
00301 texres->tin = 0.3333 * (texres->tr + texres->tg + texres->tb);
00302
00303 BRICONTRGB;
00304 texres->ta = 1.0;
00305
00306 return TEX_RGB;
00307 }
00308
00309
00310
00311
00312 static int stucci(const Tex *tex, const float *texvec, TexResult *texres) {
00313 float nor[3], b2, ofs;
00314 int retval = TEX_INT;
00315
00316 b2 = BLI_gNoise(tex->noisesize, texvec[0], texvec[1], texvec[2], (tex->noisetype != TEX_NOISESOFT), tex->noisebasis);
00317
00318 ofs = tex->turbul / 200.0;
00319
00320 if (tex->stype) ofs *= (b2 * b2);
00321 nor[0] = BLI_gNoise(tex->noisesize, texvec[0] + ofs, texvec[1], texvec[2], (tex->noisetype != TEX_NOISESOFT), tex->noisebasis);
00322 nor[1] = BLI_gNoise(tex->noisesize, texvec[0], texvec[1] + ofs, texvec[2], (tex->noisetype != TEX_NOISESOFT), tex->noisebasis);
00323 nor[2] = BLI_gNoise(tex->noisesize, texvec[0], texvec[1], texvec[2] + ofs, (tex->noisetype != TEX_NOISESOFT), tex->noisebasis);
00324
00325 texres->tin = nor[2];
00326
00327 if (tex->stype == TEX_WALLOUT)
00328 texres->tin = 1.0f - texres->tin;
00329
00330 if (texres->tin < 0.0f)
00331 texres->tin = 0.0f;
00332
00333 return retval;
00334 }
00335
00336
00337
00338
00339
00340 static float mg_mFractalOrfBmTex(const Tex *tex, const float *texvec, TexResult *texres) {
00341 int rv = TEX_INT;
00342 float (*mgravefunc)(float, float, float, float, float, float, int);
00343
00344 if (tex->stype == TEX_MFRACTAL)
00345 mgravefunc = mg_MultiFractal;
00346 else
00347 mgravefunc = mg_fBm;
00348
00349 texres->tin = tex->ns_outscale * mgravefunc(texvec[0], texvec[1], texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->noisebasis);
00350
00351 BRICONT;
00352
00353 return rv;
00354 }
00355
00356 static float mg_ridgedOrHybridMFTex(const Tex *tex, const float *texvec, TexResult *texres) {
00357 int rv = TEX_INT;
00358 float (*mgravefunc)(float, float, float, float, float, float, float, float, int);
00359
00360 if (tex->stype == TEX_RIDGEDMF)
00361 mgravefunc = mg_RidgedMultiFractal;
00362 else
00363 mgravefunc = mg_HybridMultiFractal;
00364
00365 texres->tin = tex->ns_outscale * mgravefunc(texvec[0], texvec[1], texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->mg_gain, tex->noisebasis);
00366
00367 BRICONT;
00368
00369 return rv;
00370 }
00371
00372 static float mg_HTerrainTex(const Tex *tex, const float *texvec, TexResult *texres) {
00373 int rv = TEX_INT;
00374
00375 texres->tin = tex->ns_outscale * mg_HeteroTerrain(texvec[0], texvec[1], texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->noisebasis);
00376
00377 BRICONT;
00378
00379 return rv;
00380
00381 }
00382
00383 static float mg_distNoiseTex(const Tex *tex, const float *texvec, TexResult *texres) {
00384 int rv = TEX_INT;
00385
00386 texres->tin = mg_VLNoise(texvec[0], texvec[1], texvec[2], tex->dist_amount, tex->noisebasis, tex->noisebasis2);
00387
00388 BRICONT;
00389
00390 return rv;
00391 }
00392
00393
00394
00395
00396
00397
00398 static float voronoiTex(const Tex *tex, const float *texvec, TexResult *texres) {
00399 int rv = TEX_INT;
00400 float da[4], pa[12];
00401 float aw1 = fabs(tex->vn_w1);
00402 float aw2 = fabs(tex->vn_w2);
00403 float aw3 = fabs(tex->vn_w3);
00404 float aw4 = fabs(tex->vn_w4);
00405 float sc = (aw1 + aw2 + aw3 + aw4);
00406 if (sc != 0.f) sc = tex->ns_outscale / sc;
00407
00408 voronoi(texvec[0], texvec[1], texvec[2], da, pa, tex->vn_mexp, tex->vn_distm);
00409 texres->tin = sc * fabs(tex->vn_w1 * da[0] + tex->vn_w2 * da[1] + tex->vn_w3 * da[2] + tex->vn_w4 * da[3]);
00410
00411 if (tex->vn_coltype) {
00412 float ca[3];
00413 cellNoiseV(pa[0], pa[1], pa[2], ca);
00414 texres->tr = aw1 * ca[0];
00415 texres->tg = aw1 * ca[1];
00416 texres->tb = aw1 * ca[2];
00417 cellNoiseV(pa[3], pa[4], pa[5], ca);
00418 texres->tr += aw2 * ca[0];
00419 texres->tg += aw2 * ca[1];
00420 texres->tb += aw2 * ca[2];
00421 cellNoiseV(pa[6], pa[7], pa[8], ca);
00422 texres->tr += aw3 * ca[0];
00423 texres->tg += aw3 * ca[1];
00424 texres->tb += aw3 * ca[2];
00425 cellNoiseV(pa[9], pa[10], pa[11], ca);
00426 texres->tr += aw4 * ca[0];
00427 texres->tg += aw4 * ca[1];
00428 texres->tb += aw4 * ca[2];
00429 if (tex->vn_coltype >= 2) {
00430 float t1 = (da[1] - da[0])*10;
00431 if (t1 > 1) t1 = 1;
00432 if (tex->vn_coltype == 3) t1 *= texres->tin;
00433 else t1 *= sc;
00434 texres->tr *= t1;
00435 texres->tg *= t1;
00436 texres->tb *= t1;
00437 } else {
00438 texres->tr *= sc;
00439 texres->tg *= sc;
00440 texres->tb *= sc;
00441 }
00442 }
00443
00444 if (tex->vn_coltype) {
00445 BRICONTRGB;
00446 texres->ta = 1.0;
00447 return (rv | TEX_RGB);
00448 }
00449
00450 BRICONT;
00451
00452 return rv;
00453
00454 }
00455
00456
00457
00458 static int texnoise(const Tex *tex, TexResult *texres) {
00459 float div = 3.0;
00460 int val, ran, loop;
00461
00462 ran = BLI_rand();
00463 val = (ran & 3);
00464
00465 loop = tex->noisedepth;
00466 while (loop--) {
00467 ran = (ran >> 2);
00468 val *= (ran & 3);
00469 div *= 3.0;
00470 }
00471
00472 texres->tin = ((float) val) / div;
00473 ;
00474
00475 BRICONT;
00476 return TEX_INT;
00477 }
00478
00479
00480
00481 int multitex(const Tex *tex, const float *texvec, TexResult *texres) {
00482 float tmpvec[3];
00483 int retval = 0;
00484
00485 texres->talpha = 0;
00486
00487 switch (tex->type) {
00488
00489 case 0:
00490 texres->tin = 0.0f;
00491 return 0;
00492 case TEX_CLOUDS:
00493 retval = clouds(tex, texvec, texres);
00494 break;
00495 case TEX_WOOD:
00496 retval = wood(tex, texvec, texres);
00497 break;
00498 case TEX_MARBLE:
00499 retval = marble(tex, texvec, texres);
00500 break;
00501 case TEX_MAGIC:
00502 retval = magic(tex, texvec, texres);
00503 break;
00504 case TEX_BLEND:
00505 retval = blend(tex, texvec, texres);
00506 break;
00507 case TEX_STUCCI:
00508 retval = stucci(tex, texvec, texres);
00509 break;
00510 case TEX_NOISE:
00511 retval = texnoise(tex, texres);
00512 break;
00513 case TEX_MUSGRAVE:
00514
00515
00516
00517
00518
00519 VECCOPY(tmpvec, texvec);
00520 VecMulf(tmpvec, 1.0 / tex->noisesize);
00521
00522 switch (tex->stype) {
00523 case TEX_MFRACTAL:
00524 case TEX_FBM:
00525 retval = mg_mFractalOrfBmTex(tex, tmpvec, texres);
00526 break;
00527 case TEX_RIDGEDMF:
00528 case TEX_HYBRIDMF:
00529 retval = mg_ridgedOrHybridMFTex(tex, tmpvec, texres);
00530 break;
00531 case TEX_HTERRAIN:
00532 retval = mg_HTerrainTex(tex, tmpvec, texres);
00533 break;
00534 }
00535 break;
00536
00537 case TEX_VORONOI:
00538
00539
00540
00541 VECCOPY(tmpvec, texvec);
00542 VecMulf(tmpvec, 1.0 / tex->noisesize);
00543
00544 retval = voronoiTex(tex, tmpvec, texres);
00545 break;
00546 case TEX_DISTNOISE:
00547
00548
00549
00550 VECCOPY(tmpvec, texvec);
00551 VecMulf(tmpvec, 1.0 / tex->noisesize);
00552
00553 retval = mg_distNoiseTex(tex, tmpvec, texres);
00554 break;
00555 }
00556
00557 return retval;
00558 }
00559
00560 }