35 static const char*
fabs_docstring =
"float abs(float x)\nabsolute value of x";
38 static const char*
deg_docstring =
"float deg(float angle)\nradians to degrees";
39 static const char*
rad_docstring =
"float deg(float angle)\ndegrees to radians";
41 static const char*
cosd_docstring =
"float cosd(float angle)\ncosine in degrees";
42 static const char*
sind_docstring =
"float sind(float angle)\nsine in degrees";
43 static const char*
tand_docstring =
"float tand(float angle)\ntangent in degrees";
44 static const char*
acosd_docstring =
"float acosd(float angle)\narc cosine in degrees";
45 static const char*
asind_docstring =
"float asind(float angle)\narc sine in degrees";
46 static const char*
atand_docstring =
"float atand(float angle)\narc tangent in degrees";
48 "float atan2d(float y,float x)\narc tangent in degrees of y/x between -180 and 180";
50 static const char*
cos_docstring =
"float cos(float angle)\ncosine in radians";
51 static const char*
sin_docstring =
"float sin(float angle)\nsine in radians";
52 static const char*
tan_docstring =
"float tan(float angle)\ntangent in radians";
53 static const char*
acos_docstring =
"float acos(float angle)\narc cosine in radians";
54 static const char*
asin_docstring =
"float asin(float angle)\narc sine in radians";
55 static const char*
atan_docstring =
"float atan(float angle)\narc tangent in radians";
56 static const char*
atan2_docstring =
"float atan2(float y,float x)\narc tangent in radians of y/x between -PI and PI";
58 static const char*
cosh_docstring =
"float cosh(float angle)\nhyperbolic cosine in radians";
59 static const char*
sinh_docstring =
"float sinh(float angle)\nhyperbolic sine in radians";
60 static const char*
tanh_docstring =
"float tanh(float angle)\nhyperbolic tangent in radians";
61 static const char*
acosh_docstring =
"float acosh(float angle)\nhyperbolic arc cosine in radians";
62 static const char*
asinh_docstring =
"float asinh(float angle)\nhyperbolic arc sine in radians";
63 static const char*
atanh_docstring =
"float atanh(float angle)\nhyperbolic arc tangent in radians";
65 static const char*
clamp_docstring =
"float clamp(float x,float lo,float hi)\nconstrain x to range [lo,hi]";
66 static const char*
round_docstring =
"float round(float x)\nconstrain x to range [lo,hi]";
67 static const char*
max_docstring =
"float max(float a,float b)\ngreater of a and b";
68 static const char*
min_docstring =
"float min(float a,float b)\nlesser of a and b";
69 static const char*
trunc_docstring =
"float trunc(float a)\nnearest integer towards zero";
71 static const char*
ceil_docstring =
"float ceil(float a)\nnext higher integer";
76 static const char*
exp_docstring =
"float exp(float x)\nE raised to the x power";
77 static const char*
pow_docstring =
"float pow(float x)\nx to the y power, also available as ^";
78 static const char*
log_docstring =
"float log(float x)\nNatural logarithm";
80 static const char*
fmod_docstring =
"float fmod(float x,float y)\nremainder of x/y (also available as % operator)";
82 "float turbulence(vector v,int octaves=6,float lacunarity=2,float gain=.5)\nAbsolute value of each noise term is "
83 "taken. This gives billowy appearance";
85 "color cturbulence(vector v,int octaves=6,float lacunarity=2,float gain=.5)\nAbsolute value of each noise term is "
86 "taken. This gives billowy appearance";
88 "vector vturbulence(vector v,int octaves=6,float lacunarity=2,float gain=.5)\nAbsolute value of each noise term is "
89 "taken. This gives billowy appearance";
91 double compress(
double x,
double lo,
double hi) {
return (hi - lo) * x + lo; }
92 static const char*
compress_docstring =
"float compress(float x,float lo,float hi)\nRemaps x in [0,1] to [lo,hi]";
94 double expand(
double x,
double lo,
double hi) {
95 if (lo == hi)
return x < lo ? 0 : 1;
96 return (x - lo) / (hi - lo);
98 static const char*
expand_docstring =
"float expand(float x,float lo,float hi)\nRemaps x in [lo,hi] to [0,1]";
100 double fit(
double x,
double a1,
double b1,
double a2,
double b2) {
101 return (x * (b2 - a2) - a1 * b2 + b1 * a2) / (b1 -
a1);
104 "float fit(float x,float a1,float b1,float a2,float b2)\nLinearly remaps x in [a1,b1] to [a2,b2]";
106 double gamma(
double x,
double g) {
return pow(x, 1 / g); }
107 static const char*
gamma_docstring =
"float gamma(float x, float g)\nGamma correction of x with gamma factor g";
110 static double C = 1 / log(0.5);
111 return pow(x, log(b) * C);
114 "float bias(float x, float g)\nVariation of gamma where values less than 0.5 pull the curve down\nand values "
115 "greater than 0.5 pull the curve up\npow(x,log(b)/log(0.5))";
119 return 0.5 *
bias(1 - c, 2 * x);
121 return 1 - 0.5 *
bias(1 - c, 2 - 2 * x);
124 "float contrast(float x,float x)\nAdjust the contrast. For c from 0 to 0.5, the contrast is decreased. "
125 "For c > 0.5, the contrast is increased.";
127 double boxstep(
double x,
double a) {
return x < a ? 0.0 : 1.0; }
128 static const char*
boxstep_docstring =
"float boxstep(float x,float a)\n if x < a then 0 otherwise 1";
132 return x < a ? 0 : (x > b ? 1 : (x -
a) / (b - a));
134 return 1 - (x < b ? 0 : (x > a ? 1 : (x -
b) / (a - b)));
139 "float linearstep(float x,float a,float b)\n if x < a then 0, if x > b then 1, and\nx transitions linearly "
140 "when < x < b ";
145 if (x >= b)
return 1;
146 x = (x -
a) / (b - a);
148 if (x <= b)
return 1;
150 x = 1 - (x -
b) / (a - b);
153 return x * x * (3 - 2 *
x);
156 "float smoothstep(float x,float a,float b)\n if x < a then 0, if x > b then 1, and\nx transitions smoothly "
157 "(cubic) when < x < b";
162 if (x >= b)
return 1;
163 x = 1 - (x -
a) / (b - a);
165 if (x <= b)
return 1;
167 x = (x -
b) / (a - b);
170 return pow(2, -8 * x * x);
173 "float gasussstep(float x,float a,float b)\n if x < a then 0, if x > b then 1, and\nx transitions smoothly "
174 "(exponentially) when < x < b";
176 double remap(
double x,
double source,
double range,
double falloff,
double interp) {
178 falloff = fabs(falloff);
180 if (falloff == 0)
return fabs(x - source) < range;
191 switch (
int(interp)) {
201 "remap(float x, float\n"
202 "source, float range, float falloff, float interp)\nGeneral remapping function.\n"
203 "When x is within +/- <i>range</i> of source, the result is one.\n"
204 "The result falls to zero beyond that range over <i>falloff</i> distance.\n"
205 "The falloff shape is controlled by <i>interp</i>. Numeric values\n"
206 "or named constants may be used:\n"
207 " int <b>linear</b>\n"
209 " int <b>smooth</b> = 1\n"
210 " int <b>gaussian</b> = 2\n";
212 double mix(
double x,
double y,
double alpha) {
return x * (1 - alpha) + y * alpha; }
213 static const char*
mix_docstring =
"mix(float a,float b,float alpha)\nBlend of a and b according to alpha.";
217 hsl[0] += h * (1.0 / 360);
223 if (n < 4)
return 0.0;
225 double h = args[1][0];
226 double s = args[2][0];
227 double i = args[3][0];
230 double m = args[4][0];
238 "color hsi(color x, float h, float s, float i, float map=1)\n"
239 "The hsi function shifts the hue by h\n"
240 "(in degrees) and scales the saturation and intensity by s and i\n"
241 "respectively. An map may be supplied which will control the shift\n"
242 "- the full shift will happen when the map is one and no shift will\n"
243 "happen when the map is zero. The shift will be scaled back for\n"
244 "values between zero and one.";
247 if (n < 4)
return 0.0;
249 double h = args[1][0];
250 double s = args[2][0];
251 double i = args[3][0];
254 double m = args[4][0];
258 double falloff = 1, interp = 0;
259 if (n >= 6) falloff = args[5][0];
260 if (n >= 7) interp = args[6][0];
262 m = -
remap(-m, 1, 0, falloff, interp);
264 m =
remap(m, 1, 0, falloff, interp);
268 float absm = fabs(m);
269 s = s * absm + 1 - absm;
270 i = i * absm + 1 - absm;
279 "color midhsi(color x, float h, float s, float i, float map, float falloff=1, int interp=0)\n"
280 "The midhsi function is just like the hsi function except that\n"
281 "the control map is centered around the mid point (value of 0.5)\n"
282 "and can scale the shift in both directions.";
288 double R, G, B, H, S, L,
x,
y, sum, diff;
292 x = R < G ? (R < B ? R : B) : (G < B ? G : B);
293 y = R > G ? (R > B ? R : B) : (G > B ? G : B);
300 return Vec3d(0, 0, L);
312 S = diff / (2 - sum);
319 H = (B - R) / diff + 2;
321 H = (R - G) / diff + 4;
325 return Vec3d(H, S, L);
328 "color rgbtohsl(color rgb)\n"
329 "RGB to HSL color space conversion.\n"
330 "HSL is Hue, Saturation, Lightness (all in range [0..1] )\n"
331 "These functions have also been extended to support rgb and hsl values\n"
332 "outside of the range [0..1] in a reasonable way. For any rgb or\n"
333 "hsl value (except for negative s values), the conversion is\n"
334 "well-defined and reversible.";
340 return x + (y -
x) * H * 6;
344 return x + (y -
x) * (4 / 6. - H) * 6;
353 double H, S, L, R, G, B,
x,
y;
358 return Vec3d(L, L, L);
378 return Vec3d(R, G, B);
381 "color hsltorgb(color hsl)\n"
382 "RGB to HSL color space conversion.\n"
383 "HSL is Hue, Saturation, Lightness (all in range [0..1] )\n"
384 "These functions have also been extended to support rgb and hsl values\n"
385 "outside of the range [0..1] in a reasonable way. For any rgb or\n"
386 "hsl value (except for negative s values), the conversion is\n"
387 "well-defined and reversible.";
390 const Vec3d lum(.2126,.7152,.0722);
392 if (result[0] < 0) result[0] = 0;
393 if (result[1] < 0) result[1] = 0;
394 if (result[2] < 0) result[2] = 0;
399 if (n < 2)
return 0.0;
400 return saturate(args[0], args[1][0]);
403 "color saturate(color val, float amt)\n"
404 "Scale saturation of color by amt.\n"
405 "The color is scaled around the rec709 luminance value,\n"
406 "and negative results are clamped at zero.\n";
408 double hash(
int n,
double* args) {
411 for (
int i = 0; i < n; i++) {
414 double frac = frexp(args[i] *
double(M_E * M_PI), &exp);
415 uint32_t s = (uint32_t)(frac * UINT32_MAX) ^ (uint32_t)exp;
418 static const uint32_t M = 1664525, C = 1013904223;
419 seed = seed * M + s + C;
423 seed ^= (seed >> 11);
424 seed ^= (seed << 7) & 0x9d2c5680UL;
425 seed ^= (seed << 15) & 0xefc60000UL;
426 seed ^= (seed >> 18);
429 static unsigned char p[256] = {
430 148, 201, 203, 34, 85, 225, 163, 200, 174, 137, 51, 24, 19, 252, 107, 173, 110, 251, 149, 69, 180, 152,
431 141, 132, 22, 20, 147, 219, 37, 46, 154, 114, 59, 49, 155, 161, 239, 77, 47, 10, 70, 227, 53, 235,
432 30, 188, 143, 73, 88, 193, 214, 194, 18, 120, 176, 36, 212, 84, 211, 142, 167, 57, 153, 71, 159, 151,
433 126, 115, 229, 124, 172, 101, 79, 183, 32, 38, 68, 11, 67, 109, 221, 3, 4, 61, 122, 94, 72, 117,
434 12, 240, 199, 76, 118, 5, 48, 197, 128, 62, 119, 89, 14, 45, 226, 195, 80, 50, 40, 192, 60, 65,
435 166, 106, 90, 215, 213, 232, 250, 207, 104, 52, 182, 29, 157, 103, 242, 97, 111, 17, 8, 175, 254, 108,
436 208, 224, 191, 112, 105, 187, 43, 56, 185, 243, 196, 156, 246, 249, 184, 7, 135, 6, 158, 82, 130, 234,
437 206, 255, 160, 236, 171, 230, 42, 98, 54, 74, 209, 205, 33, 177, 15, 138, 178, 44, 116, 96, 140, 253,
438 233, 125, 21, 133, 136, 86, 245, 58, 23, 1, 75, 165, 92, 217, 39, 0, 218, 91, 179, 55, 238, 170,
439 134, 83, 25, 189, 216, 100, 129, 150, 241, 210, 123, 99, 2, 164, 16, 220, 121, 139, 168, 64, 190, 9,
440 31, 228, 95, 247, 244, 81, 102, 145, 204, 146, 26, 87, 113, 198, 181, 127, 237, 169, 28, 93, 27, 41,
441 231, 248, 78, 162, 13, 186, 63, 66, 131, 202, 35, 144, 222, 223};
447 u2.c[3] = p[u1.c[0]];
448 u2.c[2] = p[(u1.c[1] + u2.c[3]) & 0xff];
449 u2.c[1] = p[(u1.c[2] + u2.c[2]) & 0xff];
450 u2.c[0] = p[(u1.c[3] + u2.c[1]) & 0xff];
453 return u2.i * (1.0 / UINT32_MAX);
456 "float hash(float seed1,[float seed2, ...])\n"
457 "Like rand, but with no internal seeds. Any number of seeds may be given\n"
458 "and the result will be a random function based on all the seeds.";
465 double p[3] = {args[0][0], args[0][1], args[0][2]};
466 Noise<3, 1>(
p, &result);
467 return .5 * result + .5;
472 for (
int i = 0; i < n; i++) p[i] = args[i][0];
476 Noise<1, 1>(
p, &result);
479 Noise<2, 1>(
p, &result);
482 Noise<3, 1>(
p, &result);
485 Noise<4, 1>(
p, &result);
491 return .5 * result + .5;
494 "float noise ( vector v ) <br>\n"
495 "float noise ( float x, float y )\n"
496 "float noise ( float x, float y, float z )\n"
497 "float noise ( float x, float y, float z, float w )\n"
498 "Original perlin noise at location (C2 interpolant)";
502 double args[3] = {p[0], p[1], p[2]};
503 Noise<3, 1>(args, &result);
507 "float snoise ( vector v)\n"
508 "signed noise w/ range -1 to 1 formed with original perlin noise at location (C2 interpolant)";
512 double args[3] = {p[0], p[1], p[2]};
513 Noise<3, 3>(args, &result[0]);
517 "vector vnoise ( vector v)\n"
518 "vector noise formed with original perlin noise at location (C2 interpolant)";
522 "color cnoise ( vector v)\n"
523 "color noise formed with original perlin noise at location (C2 interpolant)";
527 double procargs[4] = {args[0][0], args[0][1], args[0][2], args[1][0]};
528 Noise<4, 1>(procargs, &result);
532 "float snoise4 ( vector v,float t)\n"
533 "4D signed noise w/ range -1 to 1 formed with original perlin noise at location (C2 interpolant)";
537 double procargs[4] = {args[0][0], args[0][1], args[0][2], args[1][0]};
538 Noise<4, 3>(procargs, &result[0]);
542 "vector vnoise4 ( vector v,float t)\n"
543 "4D vector noise formed with original perlin noise at location (C2 interpolant)";
547 "color cnoise4 ( vector v,float t)\n"
548 "4D color noise formed with original perlin noise at location (C2 interpolant)";
553 double lacunarity = 2;
561 lacunarity = args[2][0];
563 octaves = int(
clamp(args[1][0], 1, 8));
569 double P[3] = {p[0], p[1], p[2]};
570 FBM<3, 1, true>(P, &result, octaves, lacunarity, gain);
571 return .5 * result + .5;
577 double lacunarity = 2;
585 lacunarity = args[2][0];
587 octaves = int(
clamp(args[1][0], 1, 8));
593 double P[3] = {p[0], p[1], p[2]};
594 FBM<3, 3, true>(P, &result[0], octaves, lacunarity, gain);
603 double lacunarity = 2;
611 lacunarity = args[2][0];
613 octaves = int(
clamp(args[1][0], 1, 8));
619 double P[3] = {p[0], p[1], p[2]};
620 FBM<3, 1, false>(P, &result, octaves, lacunarity, gain);
621 return .5 * result + .5;
624 "float fbm(vector v,int octaves=6,float lacunarity=2,float gain=.5)\n"
625 "fbm (Fractal Brownian Motion) is a multi-frequency noise function. \n"
626 "The base frequency is the same as the \"noise\" function. The total \n"
627 "number of frequencies is controlled by octaves. The lacunarity is the \n"
628 "spacing between the frequencies - a value of 2 means each octave is \n"
629 "twice the previous frequency. The gain< controls how much each \n"
630 "frequency is scaled relative to the previous frequency.";
635 double lacunarity = 2;
643 lacunarity = args[2][0];
645 octaves = int(
clamp(args[1][0], 1, 8));
651 double P[3] = {p[0], p[1], p[2]};
652 FBM<3, 3, false>(P, &result[0], octaves, lacunarity, gain);
655 static const char*
vfbm_docstring =
"vector vfbm(vector vint octaves=6,float lacunarity=2,float gain=.5)";
660 double lacunarity = 2;
669 lacunarity = args[3][0];
671 octaves = int(
clamp(args[2][0], 1, 8));
679 double P[4] = {p[0], p[1], p[2], time};
680 FBM<4, 1, false>(P, &result, octaves, lacunarity, gain);
681 return .5 * result + .5;
684 "float fbm4(vector v,float time,int octaves=6,float lacunarity=2,float gain=.5)\n"
685 "fbm (Fractal Brownian Motion) is a multi-frequency noise function. \n"
686 "The base frequency is the same as the \"noise\" function. The total \n"
687 "number of frequencies is controlled by octaves. The lacunarity is the \n"
688 "spacing between the frequencies - a value of 2 means each octave is \n"
689 "twice the previous frequency. The gain< controls how much each \n"
690 "frequency is scaled relative to the previous frequency.";
695 double lacunarity = 2;
704 lacunarity = args[3][0];
706 octaves = int(
clamp(args[2][0], 1, 8));
714 double P[4] = {p[0], p[1], p[2], time};
715 FBM<4, 3, false>(P, &result[0], octaves, lacunarity, gain);
718 static const char*
vfbm4_docstring =
"vector vfbm4(vector v,float time,int octaves=6,float lacunarity=2,float gain=.5)";
721 static const char*
cfbm_docstring =
"color cfbm(vector vint octaves=6,float lacunarity=2,float gain=.5)";
724 static const char*
cfbm4_docstring =
"color cfbm4(vector v,float time,int octaves=6,float lacunarity=2,float gain=.5)";
728 double args[3] = {p[0], p[1], p[2]};
729 CellNoise<3, 1>(args, &result);
733 "float cellnoise(vector v)\n"
734 "cellnoise generates a field of constant colored cubes based on the integer location.\n"
735 "This is the same as the prman cellnoise function.";
739 double args[3] = {p[0], p[1], p[2]};
740 CellNoise<3, 3>(args, &result[0]);
744 "color cellnoise(vector v)\n"
745 "cellnoise generates a field of constant colored cubes based on the integer location.\n"
746 "This is the same as the prman cellnoise function.";
750 double args[3] = {p[0], p[1], p[2]};
751 int pargs[3] = {
max(1,(
int)period[0]),
752 max(1,(
int)period[1]),
753 max(1,(
int)period[2])};
754 PNoise<3, 1>(args, pargs, &result);
758 "float pnoise ( vector v, vector period )\n"
773 for (
double i = -1; i <= 1; i++) {
774 for (
double j = -1; j <= 1; j++) {
775 for (
double k = -1; k <= 1; k++, n++) {
786 Vec3d thiscell(floor(p[0]) + 0.5, floor(p[1]) + 0.5, floor(p[2]) + 0.5);
790 Vec3d* end = pos + 27;
792 for (; pos != end; pos++) {
794 double dist = offset.
dot(offset);
811 Vec3d thiscell(floor(p[0]) + 0.5, floor(p[1]) + 0.5, floor(p[2]) + 0.5);
814 Vec3d* end = pos + 27;
816 for (; pos != end; pos++) {
818 double dist = offset.
dot(offset);
824 }
else if (dist < f2) {
840 double fbmOctaves = 4;
841 double fbmLacunarity = 2;
842 double fbmGain = 0.5;
845 fbmGain = args[6][0];
847 fbmLacunarity = args[5][0];
849 fbmOctaves = args[4][0];
851 fbmScale = args[3][0];
853 jitter =
clamp(args[2][0], 1e-3, 1);
855 type = int(args[1][0]);
863 fbmArgs[1] = fbmOctaves;
864 fbmArgs[2] = fbmLacunarity;
865 fbmArgs[3] = fbmGain;
866 p += fbmScale *
vfbm(4, fbmArgs);
888 return smoothstep(f2 - f1, 0, 0.1 * scalefactor);
895 "float voronoi(vector v, int type=1,float jitter=0.5, float fbmScale=0, int fbmOctaves=4,float fbmLacunarity=2, "
896 "float fbmGain=.5)\n"
897 "voronoi is a cellular noise pattern. It is a jittered variant of cellnoise.";
906 double fbmOctaves = 4;
907 double fbmLacunarity = 2;
908 double fbmGain = 0.5;
911 fbmGain = args[6][0];
913 fbmLacunarity = args[5][0];
915 fbmOctaves = args[4][0];
917 fbmScale = args[3][0];
919 jitter =
clamp(args[2][0], 1e-3, 1);
921 type = int(args[1][0]);
929 fbmArgs[1] = fbmOctaves;
930 fbmArgs[2] = fbmLacunarity;
931 fbmArgs[3] = fbmGain;
932 p += fbmScale *
vfbm(4, fbmArgs);
952 return (f2 - f1) * color;
955 return smoothstep(f2 - f1, 0, 0.1 * scalefactor) * color;
962 "color cvoronoi(vector v, int type=1,float jitter=0.5, float fbmScale=0, int fbmOctaves=4,float fbmLacunarity=2, "
963 "float fbmGain=.5)\n"
964 "returns color in cellular pattern. It is a jittered variant of cellnoise.";
972 double fbmOctaves = 4;
973 double fbmLacunarity = 2;
974 double fbmGain = 0.5;
977 fbmGain = args[5][0];
979 fbmLacunarity = args[4][0];
981 fbmOctaves = args[3][0];
983 fbmScale = args[2][0];
985 jitter =
clamp(args[1][0], 1e-3, 1);
993 fbmArgs[1] = fbmOctaves;
994 fbmArgs[2] = fbmLacunarity;
995 fbmArgs[3] = fbmGain;
996 p += fbmScale *
vfbm(4, fbmArgs);
1005 "color pvoronoi(vector v, int type=1,float jitter=0.5, float fbmScale=0, int fbmOctaves=4,float fbmLacunarity=2, "
1006 "float fbmGain=.5)\n"
1007 "returns center of voronoi cell.";
1017 if (nargs < 1 || nargs > 7) {
1018 node->
addError(
"Wrong number of arguments, should be 1 to 7");
1023 valid &= node->
checkArg(0, ExprType().FP(3).Varying(), envBuilder);
1024 for (
int i = 1; i < nargs; i++) valid &= node->
checkArg(i, ExprType().FP(1).Constant(), envBuilder);
1025 return valid ? ExprType().FP(3).Varying() : ExprType().Error();
1034 int nargs = args.
nargs();
1037 for (
int i = 0; i < nargs; i++)
1038 for (
int j = 0; j < 3; j++) sevArgs[i][j] = args.
inFp<3>(i)[j];
1041 double* out = &args.
outFp;
1042 for (
int i = 0; i < 3; i++) out[i] = result[i];
1051 double dist(
double ax,
double ay,
double az,
double bx,
double by,
double bz) {
1055 return sqrt(x * x + y * y + z * z);
1058 "float dist(vector a, vector b)\n"
1059 "distance between two points";
1061 double length(
const Vec3d& v) {
return sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); }
1063 "float length(vector v)\n"
1066 double hypot(
double x,
double y) {
return sqrt(x * x + y * y); }
1068 "float hypot(vector v)\n"
1069 "length of 2d vector [x,y]";
1071 double dot(
const Vec3d&
a,
const Vec3d&
b) {
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; }
1073 "float dot(vector a,vector b)\n"
1074 "vector dot product";
1084 "vector norm(vector v)\n"
1085 "vector scaled to unit length";
1088 return Vec3d(a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]);
1091 "vector cross(vector a,vector b)\n"
1092 "vector cross product";
1096 if (len == 0)
return 0;
1097 return acos(
dot(a, b) / len);
1100 "float angle(vector a,vector b)\n"
1101 "angle between two vectors (in radians)";
1105 "vector angle(vector a,vector b)\n"
1106 "normalized vector orthogonal to a and b scaled to unit length";
1109 if (n != 3)
return 0.0;
1110 const Vec3d& P = args[0];
1111 const Vec3d& axis = args[1];
1112 float angle = args[2][0];
1113 double len = axis.
length();
1115 return P.
rotateBy(axis / len, angle);
1118 "vector rotate(vector v,vector axis,float angle)\n"
1119 "rotates v around axis by given angle (in radians)";
1123 Vec3d yAxis(0, 1, 0);
1127 "vector up(vector P,vector upvec)\n"
1128 "rotates v such that the Y axis points in the given up direction";
1131 int lo = int(loRange);
1132 int hi = int(hiRange);
1133 int range = hi - lo + 1;
1134 if (range <= 0)
return lo;
1135 int result = int(index) % range;
1136 if (result < 0) result += range;
1140 "int cycle(int index, int loRange, int hiRange )\n"
1141 "Cycles through values between loRange and hiRange based on supplied index.\n"
1142 "This is an offset \"mod\" function. The result is rotates v such that the\n"
1143 "Y axis points in the given up direction";
1145 double pick(
int n,
double* params) {
1146 if (n < 3)
return 0;
1150 int range = hiRange - loRange + 1;
1151 if (range <= 0)
return loRange;
1152 int numWeights = n - 3;
1153 if (numWeights > range) numWeights = range;
1156 double* cutoffs = (
double*)alloca(
sizeof(
double) * range);
1157 double* weights = (
double*)alloca(
sizeof(
double) * range);
1159 for (
int i = 0; i < range; i++) {
1160 double weight = i < numWeights ? params[i + 3] : 1;
1163 weights[i] = weight;
1166 if (total == 0)
return loRange;
1172 int lo = 0, hi = range - 1;
1174 int m = (lo + hi) / 2;
1175 if (index <= cutoffs[m])
1182 if (weights[lo] == 0) {
1183 if (lo > 0 && cutoffs[lo] > 0)
1184 while (--lo > 0 && weights[lo] == 0)
1186 else if (lo < range - 1)
1187 while (++lo < range - 1 && weights[lo] == 0)
1192 return loRange + lo;
1195 "int pick(float index, int loRange, int hiRange, [float weights, ...] )\n"
1196 "Picks values randomly between loRange and hiRange based on supplied index (which is\n"
1197 "automatically hashed). The values will be distributed according\n"
1198 "to the supplied weights. Any weights not supplied are assumed to\n"
1202 return choose(n, params);
1205 "color swatch(float index, color choice0, color choice1, color choice2, [...])\n"
1206 "Chooses one of the supplied color choices based on the index (assumed to be in range [0..1]).";
1209 if (n < 3)
return 0;
1210 double key = params[0];
1212 if (key != key)
return 0;
1214 return params[1 + int(
clamp(key * nvals, 0, nvals - 1))];
1217 "float choose(float index,float choice1, float choice2, [...])\n"
1218 "Chooses one of the supplied choices based on the index (assumed to be in range [0..1]).";
1221 if (n < 5)
return 0;
1222 double key = params[0];
1224 if (key != key)
return 0;
1225 int nvals = (n - 1) / 2;
1228 double* cutoffs = (
double*)alloca(
sizeof(
double) * nvals);
1229 double* weights = (
double*)alloca(
sizeof(
double) * nvals);
1231 for (
int i = 0; i < nvals; i++) {
1232 double weight = params[i * 2 + 2];
1235 weights[i] = weight;
1238 if (total == 0)
return params[1];
1244 int lo = 0, hi = nvals - 1;
1246 int m = (lo + hi) / 2;
1247 if (key <= cutoffs[m])
1254 if (weights[lo] == 0) {
1255 if (lo > 0 && cutoffs[lo] > 0)
1256 while (--lo > 0 && weights[lo] == 0)
1258 else if (lo < nvals - 1)
1259 while (++lo < nvals - 1 && weights[lo] == 0)
1264 return params[lo * 2 + 1];
1267 "float wchoose(float index,float choice1, float weight1, float choice2, float weight2, [...] )\n"
1268 "Chooses one of the supplied choices based on the index (assumed to be in range[0..1]).\n"
1269 "The values will be distributed according to the supplied weights.";
1272 if (n < 5)
return 0;
1273 double u =
clamp(params[0], 0, 1);
1274 if (u == 0)
return params[2];
1275 if (u == 1)
return params[n - 2];
1278 u = modf(u * nsegs, &seg);
1279 double*
p = ¶ms[int(seg) + 1];
1282 return 0.5 * (p[0] * (-u3 + 2 * u2 - u) + p[1] * (3 * u3 - 5 * u2 + 2) + p[2] * (-3 * u3 + 4 * u2 + u) +
1286 "float spline(float param,float y1,float y2,float y3,float y4,[...])\n\n"
1287 "Interpolates a set of values to the parameter specified where y1, ..., yn are\n"
1288 "distributed evenly from [0...1]";
1303 if ((nargs - 1) % 3) {
1304 node->
addError(
"Wrong number of arguments, should be multiple of 3 plus 1");
1310 for (
int i = 1; i < nargs; i += 3) {
1320 for (
int i = 1; i < args.
nargs() - 2; i += 3) {
1321 double pos = args.
inFp<1>(i)[0];
1322 double val = args.
inFp<1>(i + 1)[0];
1323 double interpDouble = args.
inFp<1>(i + 2)[0];
1324 int interpInt = (int)interpDouble;
1329 data->
curve.addPoint(pos, val, interpolant);
1331 data->
curve.preparePoints();
1337 double param = args.
inFp<1>(0)[0];
1343 "float curve(float param,float pos0,float val0,int interp0,float pos1,float val1,int interp1,[...])\n\n"
1344 "Interpolates a 1D ramp defined by control points at 'param'. Control points are specified \n"
1345 "by triples of parameters pos_i, val_i, and interp_i. Interpolation codes are \n"
1346 "0 - none, 1 - linear, 2 - smooth, 3 - spline, \n"
1347 "4-monotone (non oscillating spline)";
1353 if ((nargs - 1) % 3) {
1354 node->
addError(
"Wrong number of arguments, should be multiple of 3 plus 1");
1360 for (
int i = 1; i < nargs; i += 3) {
1370 for (
int i = 1; i < args.
nargs() - 2; i += 3) {
1371 double pos = args.
inFp<1>(i)[0];
1373 double interpDouble = args.
inFp<1>(i + 2)[0];
1374 int interpInt = (int)interpDouble;
1379 data->
curve.addPoint(pos, val, interpolant);
1381 data->
curve.preparePoints();
1387 double param = args.
inFp<1>(0)[0];
1389 double* out = &args.
outFp;
1390 for (
int k = 0; k < 3; k++) out[k] = result[k];
1398 "color curve(float param,float pos0,color val0,int interp0,float pos1,color val1,int interp1,[...])\n\n"
1399 "Interpolates color ramp given by control points at 'param'. Control points are specified \n"
1400 "by triples of parameters pos_i, val_i, and interp_i. Interpolation codes are \n"
1401 "0 - none, 1 - linear, 2 - smooth, 3 - spline, \n"
1402 "4 - monotone (non oscillating spline)";
1406 typedef void(*
func)(
double *in,
double* out);
1416 std::string varName = node->
getStrArg(0);
1418 ExprType varType = varNode->
prep(wantScalar, envBuilder);
1419 if (varType.isValid()) {
1426 varType = node->
child(0)->
prep(wantScalar, envBuilder);
1438 static void f(
double* out,
double* in){
1439 for(
int k=0;k<d;k++) out[k]=in[k];
1446 double* out=&args.
outFp;
1449 if(data->
f) data->
f(out,&args.
inFp<1>(0)[0]);
1450 else throw std::runtime_error(
"getVar does not support non FP types right now got type");
1458 "getVar(string varName,vector defaultValue)\n"
1459 "return value of varName if variable exists, otherwise return defaultValue";
1471 node->
addError(
"Wrong number of arguments, should be GE 1");
1477 for (
int i = 1; i < nargs; ++i)
1484 unsigned int bakeStart = 0;
1485 int searchStart = 0;
1489 std::string& format = data->
format;
1490 std::vector<std::pair<int, int> >& ranges = data->
ranges;
1494 std::size_t percentStart = format.find(
'%', searchStart);
1495 if (percentStart == std::string::npos)
break;
1496 if (percentStart + 1 == format.length()) {
1500 }
else if (format[percentStart + 1] ==
'%') {
1501 searchStart = percentStart + 2;
1503 }
else if (format[percentStart + 1] ==
'v' || format[percentStart + 1] ==
'f') {
1504 char c = format[percentStart + 1];
1505 int code = (c ==
'v') ? -1 : -2;
1507 if (bakeStart != percentStart) ranges.push_back(std::pair<int, int>(bakeStart, percentStart));
1508 ranges.push_back(std::pair<int, int>(code, code));
1510 searchStart = percentStart + 2;
1511 bakeStart = searchStart;
1521 if (bakeStart != format.length()) ranges.push_back(std::pair<int, int>(bakeStart, format.length()));
1523 if (items != args.
nargs() - 1) {
1538 for (
unsigned int i = 0; i < data->
ranges.size(); i++) {
1539 const std::pair<int, int>& range = data->
ranges[i];
1540 if (range.first == -2) {
1541 std::cerr << args.
inFp<1>(item)[0];
1543 }
else if (range.first == -1) {
1544 std::cerr <<
"[" << args.
inFp<3>(item)[0] <<
"," << args.
inFp<3>(item)[1] <<
","
1545 << args.
inFp<3>(item)[2] <<
"]";
1548 std::cerr << data->
format.substr(range.first, range.second - range.first);
1551 std::cerr << std::endl;
1560 "printf(string format,[vec0, vec1, ...])\n"
1561 "Prints out a string to STDOUT, Format parameter allowed is %v";
1588 return new MyData(args.inFp<1>(1)[0]);
1590 virtual void eval(ArgHandle args)
1592 MyData* data=
static_cast<MyData*
>(args.data);
1597 static const char* testfunc_docstring=
"fdsA";
1604 #define FUNCADOC(name, func) define3(name, ExprFunc(::func), func##_docstring)
1605 #define FUNCDOC(func) define3(#func, ExprFunc(::func), func##_docstring)
1625 #ifndef SEEXPR_WIN32
1637 #define FUNCDOC(func) define3(#func, ExprFunc(SeExpr2::func), func##_docstring)
1638 #define FUNCNDOC(func, min, max) define3(#func, ExprFunc(SeExpr2::func, min, max), func##_docstring)
double cellnoise(const Vec3d &p)
static const char * getVar_docstring
void(* Define3)(const char *name, ExprFunc f, const char *docString)
static const char * max_docstring
static const char * bias_docstring
static const char * atan2_docstring
static const char * remap_docstring
Defined as float g float float float a2
CachedVoronoiFunc(VoronoiFunc *vfunc)
static const char * atan2d_docstring
static const char * cfbm_docstring
static const char * log10_docstring
Vec3d hsi(int n, const Vec3d *args)
T_VEC_VALUE rotateBy(const Vec< T, 3, refother > &axis, T angle) const
const ExprType & type() const
The type of the node.
virtual ExprFuncNode::Data * evalConstant(const ExprFuncNode *node, ArgHandle args) const
Vec3d up(const Vec3d &P, const Vec3d &upvec)
SeExpr2::CurveFuncX curve
static const char * acos_docstring
double dot(const Vec3d &a, const Vec3d &b)
double swatch(int n, double *params)
static double hslvalue(double x, double y, double H)
void addError(const std::string &error) const
Register error. This will allow users and sophisticated editors to highlight where in code problem wa...
ExprType & Varying()
Mutate this into a varying lifetime.
static const char * norm_docstring
static const char * dot_docstring
SeExpr2::CachedVoronoiFunc ExprFuncSimple pvoronoi(pvoronoiFn)
static const char * fit_docstring
Vec3d vfbm(int n, const Vec3d *args)
CachedVoronoiFunc(VoronoiFunc *vfunc)
virtual ExprFuncNode::Data * evalConstant(const ExprFuncNode *node, ArgHandle args) const
For applying the gamma function to a map adjusts the gamma of all three color channels< br >< br >< h4 >< aname="Curve_Functions"></a > Curve Functions</h4 >< p > Interpolation of parameter values to a set of control points is governed by the following functions</p >< p > color< b > and interp_i Interpolation codes are float float int float pos1
static const char * gaussstep_docstring
static const char * sind_docstring
double atan2d(double y, double x)
Vec3d ccellnoise(const Vec3d &p)
#define FUNCADOC(name, func)
static const char * ortho_docstring
Interpolation curve class for double->double and double->Vec3D.
static const char * snoise4_docstring
Vec3d pvoronoiFn(VoronoiPointData &data, int n, const Vec3d *args)
static void voronoi_f1_3d(VoronoiPointData &data, const Vec3d &p, double jitter, double &f1, Vec3d &pos1)
static const char * fabs_docstring
static Vec3d * voronoi_points(VoronoiPointData &data, const Vec3d &cell, double jitter)
void swapChildren(size_t i, size_t j)
Swap children, do not use unless you know what you are doing.
static const char * vturbulence_docstring
static const char * invert_docstring
static const char * cnoise_docstring
Vec3d hsiAdjust(const Vec3d &rgb, double h, double s, double i)
Vec3d cturbulence(int n, const Vec3d *args)
bool isFP() const
Direct is predicate checks.
Node that references a variable.
void defineBuiltins(ExprFunc::Define define, ExprFunc::Define3 define3)
The result is computed int loRange
The result is computed int int hiRange
static const char * tan_docstring
virtual void eval(ArgHandle args)
static const char * expand_docstring
double snoise4(int n, const Vec3d *args)
static const char * snoise_docstring
SeExpr2::PrintFuncX printf
static const char * sinh_docstring
static const char * wchoose_docstring
double remap(double x, double source, double range, double falloff, double interp)
static const char * mix_docstring
static const char * cvoronoi_docstring
virtual ~CachedVoronoiFunc()
double expand(double x, double lo, double hi)
virtual void eval(ArgHandle args)
static const char * swatch_docstring
ExprFuncNode::Data * data
static const char * atanh_docstring
static const char * pnoise_docstring
Vec3d vnoise4(int n, const Vec3d *args)
double choose(int n, double *params)
static const char * printf_docstring
double smoothstep(double x, double a, double b)
double pick(int n, double *params)
Vec< double, d, true > inFp(int i)
static const char * length_docstring
virtual ExprType prep(bool dontNeedScalar, ExprVarEnvBuilder &envBuilder)
static const char * trunc_docstring
static const char * hsi_docstring
static const char * cycle_docstring
std::string getStrArg(int n) const
static const char * pick_docstring
SeExpr2::CurveData voronoi
double length(const Vec3d &v)
static const char * deg_docstring
Vec3d cnoise(const Vec3d &p)
virtual ExprType prep(bool wantScalar, ExprVarEnvBuilder &envBuilder)
static const char * asin_docstring
static const char * vnoise4_docstring
static const char * acosd_docstring
static const char * atan_docstring
static const char * sin_docstring
double max(double x, double y)
static const char * ccurve_docstring
#define FUNCNDOC(func, min, max)
Vec3d voronoiFn(VoronoiPointData &data, int n, const Vec3d *args)
Node that calls a function.
static const char * smoothstep_docstring
double bias(double x, double b)
static const char * fbm4_docstring
The result is computed int int< br >< divstyle="margin-left:40px;"> Picks values randomly between loRange and hiRange based on supplied index(which is automatically hashed). 
static const char * vnoise_docstring
Defined as float g float a1
double cycle(double index, double loRange, double hiRange)
static const char * voronoi_docstring
static const char * asind_docstring
Vec< double, 3, false > Vec3d
Vec3d cfbm4(int n, const Vec3d *args)
static const char * hash_docstring
static const char * rad_docstring
virtual ExprType prep(ExprFuncNode *node, bool scalarWanted, ExprVarEnvBuilder &envBuilder) const
< br > pow($a, 0.5)+$b< br >< br ></div > External variables can also be overridden by local assignment. 
static const char * pow_docstring
static const char * cnoise4_docstring
double contrast(double x, double c)
static const char * cturbulence_docstring
static const char * curve_docstring
bool checkArg(int argIndex, ExprType type, ExprVarEnvBuilder &envBuilder)
double min(double x, double y)
double wchoose(int n, double *params)
double fbm(int n, const Vec3d *args)
Vec3d vnoise(const Vec3d &p)
double fbm4(int n, const Vec3d *args)
static const char * boxstep_docstring
double dist(double ax, double ay, double az, double bx, double by, double bz)
static const char * cbrt_docstring
static const char * turbulence_docstring
double gamma(double x, double g)
ExprType & Constant()
Mutate this into a constant lifetime.
static const char * tand_docstring
double linearstep(double x, double a, double b)
static const char * rotate_docstring
static const char * pvoronoi_docstring
void(* Define)(const char *name, ExprFunc f)
base class for custom instance data
</pre >< h3 > A simple variable reference</h3 > This is not a very interesting subclass of expression until we add some additional variables Variables on some applications may be very dynamic In this we only need x
void(* func)(double *in, double *out)
static const char * acosh_docstring
static const char * choose_docstring
void removeLastChild()
Remove last child and delete the entry.
static const char * log_docstring
static const char * cross_docstring
int numChildren() const
Number of children.
Vec3d cvoronoiFn(VoronoiPointData &data, int n, const Vec3d *args)
Vec3d cross(const Vec3d &a, const Vec3d &b)
void addChild(ExprNode *child)
Add a child to the child list (for parser use only)
double mix(double x, double y, double alpha)
T length() const
Euclidean (2) norm.
static const char * cosd_docstring
double fit(double x, double a1, double b1, double a2, double b2)
Vec3d midhsi(int n, const Vec3d *args)
static const char * clamp_docstring
virtual ExprType prep(ExprFuncNode *node, bool wantScalar, ExprVarEnvBuilder &envBuilder) const
static const char * vfbm_docstring
const Expression * expr() const
Access expression.
static const char * min_docstring
static const char * vfbm4_docstring
static const char * fmod_docstring
Vec3d vturbulence(int n, const Vec3d *args)
static const char * cellnoise_docstring
When x is within< i > range</i > of source
This is the same as the prman cellnoise function< br ></div >< br > float< b > float y< br > float< b > float float z
static const char * midhsi_docstring
double boxstep(double x, double a)
static const char * round_docstring
static const char * up_docstring
double clamp(double x, double lo, double hi)
static const char * fbm_docstring
static const char * ccellnoise_docstring
static void f(double *out, double *in)
static const char * atand_docstring
virtual ExprType prep(ExprFuncNode *node, bool scalarWanted, ExprVarEnvBuilder &envBuilder) const
SeExpr2::CCurveFuncX ccurve
virtual void eval(ArgHandle args)
static const char * exp_docstring
const ExprNode * child(size_t i) const
Get 0 indexed child.
static const char * asinh_docstring
Defined as float g float float b1
static const char * hsltorgb_docstring
static const char * linearstep_docstring
double hypot(double x, double y)
double turbulence(int n, const Vec3d *args)
std::vector< std::pair< int, int > > ranges
static const char * cfbm4_docstring
double angle(const Vec3d &a, const Vec3d &b)
double snoise(const Vec3d &p)
virtual ExprType prep(ExprFuncNode *node, bool scalarWanted, ExprVarEnvBuilder &envBuilder) const
Vec3d rgbtohsl(const Vec3d &rgb)
virtual void eval(ArgHandle args)
virtual ExprType prep(ExprFuncNode *node, bool wantScalar, ExprVarEnvBuilder &envBuilder) const
double spline(int n, double *params)
virtual void eval(ArgHandle args)
static const char * cosh_docstring
static const char * noise_docstring
static const char * contrast_docstring
InterpType
Supported interpolation types.
static const char * floor_docstring
static const char * cos_docstring
Vec3d hsltorgb(const Vec3d &hsl)
ExprType & FP(int d)
Mutate this into a floating point type of dimension d.
Vec3d rotate(int n, const Vec3d *args)
static const char * saturate_docstring
Vec3d cnoise4(int n, const Vec3d *args)
static void voronoi_f1f2_3d(VoronoiPointData &data, const Vec3d &p, double jitter, double &f1, Vec3d &pos1, double &f2, Vec3d &pos2)
virtual void eval(ArgHandle args)
static const char * angle_docstring
static const char * tanh_docstring
static const char * spline_docstring
static const char * compress_docstring
virtual ExprFuncNode::Data * evalConstant(const ExprFuncNode *node, ArgHandle args) const
virtual ExprFuncNode::Data * evalConstant(const ExprFuncNode *node, ArgHandle args) const
Defined as a *alpha b *alpha< br ></div >< br > float< b > float a
Vec3d norm(const Vec3d &a)
static const char * sqrt_docstring
SeExpr2::CachedVoronoiFunc ExprFuncSimple cvoronoi(cvoronoiFn)
T dot(const Vec< T, d, refother > &o) const
static const char * ceil_docstring
double compress(double x, double lo, double hi)
Vec3d vfbm4(int n, const Vec3d *args)
static const char * rgbtohsl_docstring
virtual ExprFuncNode::Data * evalConstant(const ExprFuncNode *node, ArgHandle args) const
ExprType & Error()
Mutate this into an error type.
* sin(val)/val" </pre> we would get <pre> | | | | | </pre> or if we did <pre> ./asciiGraph "x-3" </pre> we'd get <pre> | | ------------------------------|----------------- | | | | | </pre> <h2>Implement the subclass</h2> First we subclass Expression and give it a const ructor
virtual ExprFuncNode::Data * evalConstant(const ExprFuncNode *node, ArgHandle args) const
double pnoise(const Vec3d &p, const Vec3d &period)
virtual ExprType prep(ExprFuncNode *node, bool wantScalar, ExprVarEnvBuilder &envBuilder) const
Vec3d ortho(const Vec3d &a, const Vec3d &b)
This is the same as the prman cellnoise function< br ></div >< br > float< b > float y< br > float< b > float y
static const char * dist_docstring
static const char * hypot_docstring
Vec3d VoronoiFunc(VoronoiPointData &data, int n, const Vec3d *args)
double hash(int n, double *args)
static const char * gamma_docstring
Variable scope builder is used by the type checking and code gen to track visiblity of variables and ...
double noise(int n, const Vec3d *args)
static Vec3d saturate(const Vec3d &Cin, double amt)
double gaussstep(double x, double a, double b)
Vec3d cfbm(int n, const Vec3d *args)