Max 5 API Reference
00001 /* 00002 * Copyright 2001-2005 - Cycling '74 00003 * Derek Gerstmann - derek@cycling74.com 00004 * 00005 * Coherent cubic spline interpolated value noise functor object 00006 * 00007 */ 00008 00009 /*************************************************************************/ 00010 00011 #include "jit.noise.h" 00012 #include "jit.common.h" 00013 #include "jit.functor.h" 00014 #include "ext_systhread.h" 00015 00016 /*************************************************************************/ 00017 00018 // the value noise object 00019 typedef struct _jit_functor_noise_gradient 00020 { 00021 t_jit_object ob; 00022 00023 // type of filtering transfer function 00024 t_symbol *filter; 00025 00026 // pseudo random permutation table 00027 long *p; 00028 00029 // lattice of uniform values [0-1] 00030 t_jit_functor_combined_dynarray lattice; 00031 00032 // array of gradient directions 00033 t_jit_functor_combined_dimvalue *gradients; 00034 00035 // current dimcount for gradient directions 00036 long dimcount; 00037 00038 // size and mask for tables 00039 long tablesize; 00040 long tablemask; 00041 00042 // seed for random number generation 00043 long seed; 00044 00045 // signed mode (0 = unsigned, 1 = signed) 00046 long sign; 00047 00048 // abs mode (0 = normal, 1 = absolute) 00049 long abs; 00050 00051 // cubic spline basis data for interpolation 00052 t_jit_functor_wrapper evaluator; 00053 00054 // lock on our dir init which can be called during parallel evaluation 00055 long spinwait; 00056 00057 } t_jit_functor_noise_gradient; 00058 00059 t_class *_jit_functor_noise_gradient_class; 00060 t_symbol *ps_jit_functor_noise_gradient_filter; 00061 00062 /*************************************************************************/ 00063 00064 t_jit_object *jit_functor_noise_gradient_new(void); 00065 t_jit_err jit_functor_noise_gradient_free(t_jit_functor_noise_gradient *x); 00066 00067 t_jit_err jit_functor_noise_gradient_abs(t_jit_functor_noise_gradient *x, void *attr, long argc, t_atom *argv); 00068 t_jit_err jit_functor_noise_gradient_sign(t_jit_functor_noise_gradient *x, void *attr, long argc, t_atom *argv); 00069 t_jit_err jit_functor_noise_gradient_seed(t_jit_functor_noise_gradient *x, void *attr, long argc, t_atom *argv); 00070 t_jit_err jit_functor_noise_gradient_tablesize(t_jit_functor_noise_gradient *x, void *attr, long argc, t_atom *argv); 00071 t_jit_err jit_functor_noise_gradient_filter(t_jit_functor_noise_gradient *x, void *attr, long argc, t_atom *argv); 00072 t_jit_err jit_functor_noise_gradient_recalc(t_jit_functor_noise_gradient *x); 00073 00074 long jit_functor_noise_gradient_eval_fixed_ndim( 00075 t_jit_functor_noise_gradient *x, long dimcount, long *vals); 00076 00077 float jit_functor_noise_gradient_eval_float32_ndim( 00078 t_jit_functor_noise_gradient *x, long dimcount, float *vals); 00079 00080 double jit_functor_noise_gradient_eval_float64_ndim( 00081 t_jit_functor_noise_gradient *x, long dimcount, double *vals); 00082 00083 long jit_functor_noise_gradient_eval_fixed( 00084 t_jit_functor_noise_gradient *x, long dimcount, long *vals); 00085 00086 float jit_functor_noise_gradient_eval_float32( 00087 t_jit_functor_noise_gradient *x, long dimcount, float *vals); 00088 00089 double jit_functor_noise_gradient_eval_float64( 00090 t_jit_functor_noise_gradient *x, long dimcount, double *vals); 00091 00092 t_jit_object *jit_functor_noise_gradient_subfunctor( 00093 t_jit_functor_noise_gradient *x, t_symbol *name); 00094 00095 t_jit_err jit_functor_noise_gradient_dir_init( 00096 t_jit_functor_noise_gradient *x); 00097 00098 t_jit_err jit_functor_noise_gradient_evaluator_init( 00099 t_jit_functor_wrapper *x, t_symbol *name ); 00100 00101 /*************************************************************************/ 00102 00103 t_jit_err jit_functor_noise_gradient_init(void) 00104 { 00105 t_jit_object *attr; 00106 00107 // create class 00108 _jit_functor_noise_gradient_class = jit_class_new("jit_functor_noise_gradient", 00109 (method)jit_functor_noise_gradient_new,(method)jit_functor_noise_gradient_free, 00110 sizeof(t_jit_functor_noise_gradient),0L); 00111 00112 // add attribute methods 00113 attr = jit_object_new(_jit_sym_jit_attr_offset,"abs",_jit_sym_long,0, 00114 (method)0L,(method)jit_functor_noise_gradient_abs, 00115 calcoffset(t_jit_functor_noise_gradient,abs)); 00116 jit_class_addattr(_jit_functor_noise_gradient_class,attr); 00117 attr = jit_object_new(_jit_sym_jit_attr_offset,"sign",_jit_sym_long,0, 00118 (method)0L,(method)jit_functor_noise_gradient_sign, 00119 calcoffset(t_jit_functor_noise_gradient,sign)); 00120 jit_class_addattr(_jit_functor_noise_gradient_class,attr); 00121 attr = jit_object_new(_jit_sym_jit_attr_offset,"seed",_jit_sym_long,0, 00122 (method)0L,(method)jit_functor_noise_gradient_seed, 00123 calcoffset(t_jit_functor_noise_gradient,seed)); 00124 jit_class_addattr(_jit_functor_noise_gradient_class,attr); 00125 attr = jit_object_new(_jit_sym_jit_attr_offset,"tablesize",_jit_sym_long,0, 00126 (method)0L,(method)jit_functor_noise_gradient_tablesize, 00127 calcoffset(t_jit_functor_noise_gradient,tablesize)); 00128 jit_class_addattr(_jit_functor_noise_gradient_class,attr); 00129 attr = jit_object_new(_jit_sym_jit_attr_offset,"filter",_jit_sym_long,0, 00130 (method)0L,(method)jit_functor_noise_gradient_filter, 00131 calcoffset(t_jit_functor_noise_gradient,filter)); 00132 jit_class_addattr(_jit_functor_noise_gradient_class,attr); 00133 00134 // add evaluation methods 00135 jit_class_addmethod(_jit_functor_noise_gradient_class, 00136 (method)jit_functor_noise_gradient_eval_fixed, "evalfixed", A_CANT, 0L); 00137 jit_class_addmethod(_jit_functor_noise_gradient_class, 00138 (method)jit_functor_noise_gradient_eval_float32, "evalfloat32", A_CANT, 0L); 00139 jit_class_addmethod(_jit_functor_noise_gradient_class, 00140 (method)jit_functor_noise_gradient_eval_float64, "evalfloat64", A_CANT, 0L); 00141 00142 // exposing subfunctor to set/getattr interface 00143 jit_class_addmethod(_jit_functor_noise_gradient_class, 00144 (method)jit_functor_noise_gradient_subfunctor, "subfunctor", A_CANT, 0L); 00145 00146 // register functor *then* class 00147 jit_functor_setup_class(_jit_functor_noise_gradient_class,"noise","gradient"); 00148 jit_class_register(_jit_functor_noise_gradient_class); 00149 00150 // generate symbols 00151 ps_jit_functor_noise_gradient_filter = gensym("filter"); 00152 return JIT_ERR_NONE; 00153 } 00154 00155 t_jit_object *jit_functor_noise_gradient_new(void) 00156 { 00157 long i, j; 00158 t_jit_functor_noise_gradient *x; 00159 00160 if (x = (t_jit_functor_noise_gradient *)jit_object_alloc(_jit_functor_noise_gradient_class)) { 00161 00162 // initialization 00163 x->p = NULL; 00164 00165 x->lattice.fixed = NULL; 00166 x->lattice.float32 = NULL; 00167 x->lattice.float64 = NULL; 00168 00169 x->abs = FALSE; 00170 x->sign = FALSE; 00171 00172 x->seed = JIT_NOISE_DEFAULT_SEED; 00173 x->tablesize = jit_math_roundup_poweroftwo(JIT_NOISE_DEFAULT_TABLESIZE); 00174 x->tablemask = x->tablesize - 1; 00175 00176 // default to cubic filtering 00177 x->filter = gensym("cubic"); 00178 00179 // default to 2d gradients 00180 x->dimcount = 0; 00181 x->gradients = NULL; 00182 00183 x->evaluator.fm = NULL; 00184 x->evaluator.ob = NULL; 00185 00186 x->spinwait = 0; 00187 00188 // allocate permutation and uniform tables 00189 jit_functor_noise_permutations_init(&x->p, x->tablesize, x->seed); 00190 jit_functor_noise_lattice_init(&x->lattice, x->tablesize, x->seed); 00191 00192 // init evaluator 00193 jit_functor_noise_gradient_evaluator_init(&x->evaluator, x->filter); 00194 jit_functor_noise_gradient_recalc(x); 00195 } 00196 00197 return (t_jit_object *)x; 00198 } 00199 00200 t_jit_err jit_functor_noise_gradient_free(t_jit_functor_noise_gradient *x) 00201 { 00202 // free any allocated memory 00203 jit_functor_combined_dynarray_destroy(&x->lattice); 00204 00205 if(x->p) 00206 jit_disposeptr((char*)x->p); 00207 x->p = NULL; 00208 00209 if(x->gradients) 00210 jit_disposeptr((char*)x->gradients); 00211 x->gradients = NULL; 00212 00213 if(x->evaluator.ob) 00214 jit_object_free(x->evaluator.ob); 00215 x->evaluator.ob = NULL; 00216 x->evaluator.fm = NULL; 00217 00218 return JIT_ERR_NONE; 00219 } 00220 00221 t_jit_err jit_functor_noise_gradient_abs( 00222 t_jit_functor_noise_gradient *x, void *attr, long argc, t_atom *argv) 00223 { 00224 long v; 00225 00226 if (x) { 00227 v = jit_atom_getlong(argv); 00228 if (x->abs != v) { 00229 x->abs = (v > 0) ? TRUE : FALSE; 00230 jit_functor_noise_gradient_recalc(x); 00231 } 00232 return JIT_ERR_NONE; 00233 } 00234 return JIT_ERR_INVALID_PTR; 00235 } 00236 00237 t_jit_err jit_functor_noise_gradient_sign( 00238 t_jit_functor_noise_gradient *x, void *attr, long argc, t_atom *argv) 00239 { 00240 long v; 00241 00242 if (x) { 00243 v = jit_atom_getlong(argv); 00244 if (x->sign != v) { 00245 x->sign = (v > 0) ? TRUE : FALSE; 00246 jit_functor_noise_gradient_recalc(x); 00247 } 00248 return JIT_ERR_NONE; 00249 } 00250 return JIT_ERR_INVALID_PTR; 00251 } 00252 00253 t_jit_err jit_functor_noise_gradient_seed( 00254 t_jit_functor_noise_gradient *x, void *attr, long argc, t_atom *argv) 00255 { 00256 long v; 00257 00258 if (x) { 00259 v = jit_atom_getlong(argv); 00260 if (x->seed != v) { 00261 x->seed = v; 00262 00263 // allocate permutation and uniform tables 00264 jit_functor_noise_permutations_init(&x->p, x->tablesize, x->seed); 00265 jit_functor_noise_lattice_init(&x->lattice, x->tablesize, x->seed); 00266 jit_functor_noise_gradient_recalc(x); 00267 } 00268 return JIT_ERR_NONE; 00269 } 00270 return JIT_ERR_INVALID_PTR; 00271 } 00272 00273 t_jit_err jit_functor_noise_gradient_tablesize( 00274 t_jit_functor_noise_gradient *x, void *attr, long argc, t_atom *argv) 00275 { 00276 long v; 00277 00278 if (x) { 00279 v = jit_atom_getlong(argv); 00280 if (x->tablesize != v && v > 0) { 00281 00282 x->tablesize = jit_math_roundup_poweroftwo(v); 00283 x->tablemask = x->tablesize - 1; 00284 00285 // allocate permutation and uniform tables 00286 jit_functor_noise_permutations_init(&x->p, x->tablesize, x->seed); 00287 jit_functor_noise_lattice_init(&x->lattice, x->tablesize, x->seed); 00288 jit_functor_noise_gradient_recalc(x); 00289 } 00290 return JIT_ERR_NONE; 00291 } 00292 return JIT_ERR_INVALID_PTR; 00293 } 00294 00295 t_jit_err jit_functor_noise_gradient_recalc(t_jit_functor_noise_gradient *x) 00296 { 00297 // calculate intermediary values for efficiency 00298 return JIT_ERR_NONE; 00299 } 00300 00301 t_jit_err jit_functor_noise_gradient_filter( 00302 t_jit_functor_noise_gradient *x, void *attr, long argc, t_atom *argv) 00303 { 00304 long i; 00305 t_jit_err err; 00306 t_symbol *v; 00307 00308 if (x) 00309 { 00310 v = jit_atom_getsym(argv); 00311 if(x->filter != v) 00312 { 00313 x->filter = v; 00314 err = jit_functor_noise_gradient_evaluator_init(&x->evaluator, x->filter); 00315 if(err) return err; 00316 00317 jit_functor_noise_gradient_recalc(x); 00318 } 00319 return JIT_ERR_NONE; 00320 } 00321 return JIT_ERR_INVALID_PTR; 00322 } 00323 00324 // -------------------------------------------------------------------------- 00325 00326 long jit_functor_noise_gradient_eval_fixed_ndim( 00327 t_jit_functor_noise_gradient *x, long dimcount, long *vals) 00328 { 00329 long cell[JIT_MATRIX_MAX_DIMCOUNT]; // cell coord 00330 long rem[JIT_MATRIX_MAX_DIMCOUNT]; // remainders 00331 long frac[JIT_MATRIX_MAX_DIMCOUNT]; // fractions 00332 long weight[JIT_MATRIX_MAX_DIMCOUNT]; // weights 00333 long knots[JIT_MATRIX_MAX_DIMCOUNT][2]; // knots 00334 long lattice[JIT_MATRIX_MAX_DIMCOUNT]; // lattice position 00335 long length, signal; 00336 00337 long iterators[JIT_MATRIX_MAX_DIMCOUNT]; // iterators 00338 long i, c, dim; 00339 long hash; 00340 long start = 0; 00341 long end = 1; 00342 long step = 1; 00343 long dir = JIT_NOISE_DOWN; 00344 00345 // init the values, integer coords, and remainders 00346 for(i = 0; i < dimcount; i++) 00347 { 00348 cell[i] = FixedFloor(vals[i]); 00349 rem[i] = vals[i] - cell[i]; 00350 weight[i] = x->evaluator.fm->evalfixed(x->evaluator.ob, 1, rem + i); 00351 iterators[i] = start; 00352 } 00353 00354 dim = -1; 00355 while(dim < dimcount) 00356 { 00357 if(dim < 0) 00358 dim = dimcount - 1; 00359 00360 // calculate lattice coordinates 00361 lattice[dim] = cell[dim] + iterators[dim]; 00362 frac[dim] = rem[dim] - IntToFixed(iterators[dim]); 00363 00364 if(dir == JIT_NOISE_DOWN && dim > 0) 00365 { 00366 dim--; 00367 continue; 00368 } 00369 else if(dim == 0) 00370 { 00371 // get the value at the current lattice point 00372 hash = jit_functor_noise_hash_fixed_eval(dimcount, lattice, x->p, x->tablemask); 00373 00374 // get the length of the gradients 00375 length = 0; 00376 for(i = 0; i < dimcount; i++) 00377 length += FixMul(x->gradients[hash].fixed[i], frac[i]); 00378 00379 // save the gradient lengths 00380 knots[dim][ iterators[dim] ] = length; 00381 } 00382 else if(dir == JIT_NOISE_UP) 00383 { 00384 // linearly interpolate between the two knots and the weighted value 00385 length = JIT_MATH_FIXED_LERP(weight[dim-1], knots[dim-1][0], knots[dim-1][1]); 00386 knots[ dim ][ iterators[dim] ] = length; 00387 dir = JIT_NOISE_DOWN; 00388 } 00389 00390 // step in current dim 00391 iterators[dim] += step; 00392 if(iterators[dim] > end) 00393 { 00394 // reset iterator and ascend 00395 iterators[dim] = start; 00396 dir = JIT_NOISE_UP; 00397 dim++; 00398 } 00399 } 00400 00401 // post loop evaluation 00402 signal = JIT_MATH_FIXED_LERP(weight[dim-1], knots[dim-1][0], knots[dim-1][1]); 00403 00404 // remap 00405 if(!x->sign) 00406 signal = FixMul(FloatToFixed(0.5f), signal) + FloatToFixed(0.5f); 00407 00408 if(x->abs) 00409 signal = JIT_MATH_FIXED_ABS(signal); 00410 00411 return signal; 00412 } 00413 00414 float jit_functor_noise_gradient_eval_float32_ndim( 00415 t_jit_functor_noise_gradient *x, long dimcount, float *vals) 00416 { 00417 float cell[JIT_MATRIX_MAX_DIMCOUNT]; // cell coord 00418 float rem[JIT_MATRIX_MAX_DIMCOUNT]; // remainders 00419 float frac[JIT_MATRIX_MAX_DIMCOUNT]; // fractions 00420 float weight[JIT_MATRIX_MAX_DIMCOUNT]; // weights 00421 float knots[JIT_MATRIX_MAX_DIMCOUNT][2]; // knots 00422 float lattice[JIT_MATRIX_MAX_DIMCOUNT]; // lattice position 00423 float length, signal; 00424 00425 long iterators[JIT_MATRIX_MAX_DIMCOUNT]; // iterators 00426 long i, c, dim; 00427 long hash; 00428 long start = 0; 00429 long end = 1; 00430 long step = 1; 00431 long dir = JIT_NOISE_DOWN; 00432 00433 // init the values, integer coords, and remainders 00434 for(i = 0; i < dimcount; i++) 00435 { 00436 cell[i] = JIT_MATH_F32_FLOOR(vals[i]); 00437 rem[i] = vals[i] - cell[i]; 00438 weight[i] = x->evaluator.fm->evalfloat32(x->evaluator.ob, 1, rem + i); 00439 iterators[i] = start; 00440 } 00441 00442 dim = -1; 00443 while(dim < dimcount) 00444 { 00445 if(dim < 0) 00446 dim = dimcount - 1; 00447 00448 // calculate lattice coordinates 00449 lattice[dim] = cell[dim] + iterators[dim]; 00450 frac[dim] = rem[dim] - iterators[dim]; 00451 00452 if(dir == JIT_NOISE_DOWN && dim > 0) 00453 { 00454 dim--; 00455 continue; 00456 } 00457 else if(dim == 0) 00458 { 00459 // get the value at the current lattice point 00460 hash = jit_functor_noise_hash_float32_eval(dimcount, lattice, x->p, x->tablemask); 00461 00462 // get the length of the gradients 00463 length = 0.0f; 00464 for(i = 0; i < dimcount; i++) 00465 length += x->gradients[hash].float32[i] * frac[i]; 00466 00467 // save the gradient lengths 00468 knots[dim][ iterators[dim] ] = length; 00469 } 00470 else if(dir == JIT_NOISE_UP) 00471 { 00472 // linearly interpolate between the two knots and the weighted value 00473 length = JIT_MATH_LERP(weight[dim-1], knots[dim-1][0], knots[dim-1][1]); 00474 knots[ dim ][ iterators[dim] ] = length; 00475 dir = JIT_NOISE_DOWN; 00476 } 00477 00478 // step in current dim 00479 iterators[dim] += step; 00480 if(iterators[dim] > end) 00481 { 00482 // reset iterator and ascend 00483 iterators[dim] = start; 00484 dir = JIT_NOISE_UP; 00485 dim++; 00486 } 00487 } 00488 00489 // post loop evaluation 00490 signal = JIT_MATH_LERP(weight[dim-1], knots[dim-1][0], knots[dim-1][1]); 00491 00492 // remap 00493 if(!x->sign) 00494 signal = 0.5f * signal + 0.5f; 00495 00496 if(x->abs) 00497 signal = JIT_MATH_F32_ABS(signal); 00498 00499 return signal; 00500 } 00501 00502 double jit_functor_noise_gradient_eval_float64_ndim( 00503 t_jit_functor_noise_gradient *x, long dimcount, double *vals) 00504 { 00505 double cell[JIT_MATRIX_MAX_DIMCOUNT]; // cell coord 00506 double rem[JIT_MATRIX_MAX_DIMCOUNT]; // remainders 00507 double frac[JIT_MATRIX_MAX_DIMCOUNT]; // fractions 00508 double weight[JIT_MATRIX_MAX_DIMCOUNT]; // weights 00509 double knots[JIT_MATRIX_MAX_DIMCOUNT][2]; // knots 00510 double lattice[JIT_MATRIX_MAX_DIMCOUNT]; // lattice position 00511 double length, signal; 00512 00513 long iterators[JIT_MATRIX_MAX_DIMCOUNT]; // iterators 00514 long i, c, dim; 00515 long hash; 00516 long start = 0; 00517 long end = 1; 00518 long step = 1; 00519 long dir = JIT_NOISE_DOWN; 00520 00521 // init the values, integer coords, and remainders 00522 for(i = 0; i < dimcount; i++) 00523 { 00524 cell[i] = JIT_MATH_F32_FLOOR(vals[i]); 00525 rem[i] = vals[i] - cell[i]; 00526 weight[i] = x->evaluator.fm->evalfloat64(x->evaluator.ob, 1, rem + i); 00527 iterators[i] = start; 00528 } 00529 00530 dim = -1; 00531 while(dim < dimcount) 00532 { 00533 if(dim < 0) 00534 dim = dimcount - 1; 00535 00536 // calculate lattice coordinates 00537 lattice[dim] = cell[dim] + iterators[dim]; 00538 frac[dim] = rem[dim] - iterators[dim]; 00539 00540 if(dir == JIT_NOISE_DOWN && dim > 0) 00541 { 00542 dim--; 00543 continue; 00544 } 00545 else if(dim == 0) 00546 { 00547 // get the value at the current lattice point 00548 hash = jit_functor_noise_hash_float64_eval(dimcount, lattice, x->p, x->tablemask); 00549 00550 // get the length of the gradients 00551 length = 0.0f; 00552 for(i = 0; i < dimcount; i++) 00553 length += x->gradients[hash].float64[i] * frac[i]; 00554 00555 // save the gradient lengths 00556 knots[dim][ iterators[dim] ] = length; 00557 } 00558 else if(dir == JIT_NOISE_UP) 00559 { 00560 // linearly interpolate between the two knots and the weighted value 00561 length = JIT_MATH_LERP(weight[dim-1], knots[dim-1][0], knots[dim-1][1]); 00562 knots[ dim ][ iterators[dim] ] = length; 00563 dir = JIT_NOISE_DOWN; 00564 } 00565 00566 // step in current dim 00567 iterators[dim] += step; 00568 if(iterators[dim] > end) 00569 { 00570 // reset iterator and ascend 00571 iterators[dim] = start; 00572 dir = JIT_NOISE_UP; 00573 dim++; 00574 } 00575 } 00576 00577 // post loop evaluation 00578 signal = JIT_MATH_LERP(weight[dim-1], knots[dim-1][0], knots[dim-1][1]); 00579 00580 // remap 00581 if(!x->sign) 00582 signal = 0.5 * signal + 0.5; 00583 00584 if(x->abs) 00585 signal = JIT_MATH_F64_ABS(signal); 00586 00587 return signal; 00588 } 00589 00590 // -------------------------------------------------------------------------- 00591 00592 t_jit_err jit_functor_noise_gradient_dir_init( 00593 t_jit_functor_noise_gradient *x) 00594 { 00595 long i, j; 00596 double theta, fx, fy, fz, fr, fv; 00597 double ndim[JIT_MATRIX_MAX_DIMCOUNT]; 00598 double mag; 00599 t_jit_err err = JIT_ERR_NONE; 00600 00601 if(x->gradients) 00602 jit_disposeptr((char*)x->gradients); 00603 x->gradients = NULL; 00604 00605 x->gradients = (t_jit_functor_combined_dimvalue*)jit_newptr(x->tablesize * sizeof(t_jit_functor_combined_dimvalue)); 00606 if(!x->gradients) { 00607 err = JIT_ERR_INVALID_PTR; 00608 goto out; 00609 } 00610 00611 jit_rand_setseed(x->seed); 00612 switch(x->dimcount) 00613 { 00614 case 1: 00615 case 2: 00616 case 3: 00617 { 00618 // calc spherical gradient directions 00619 for(i = 0; i < x->tablesize; i++) 00620 { 00621 // get a pseudo random uniform float 00622 fv = (jit_rand() % x->tablesize) / (double)x->tablesize; 00623 00624 // calc signed z value 00625 fz = 1.0 - 2.0 * fv; 00626 00627 // calc radius 00628 fr = jit_math_sqrt(JIT_MATH_MAX(0.0, 1.0 - JIT_MATH_SQR(fz))); 00629 00630 // get a pseudo random uniform float 00631 fv = (jit_rand() % x->tablesize) / (double)x->tablesize; 00632 00633 // determine angle 00634 theta = 2 * JIT_MATH_F64_PI * fv; 00635 00636 // calc spherical gradient directions 00637 x->gradients[i].float64[0] = fr * jit_math_cos(theta); 00638 00639 if(x->dimcount > 1) 00640 x->gradients[i].float64[1] = fr * jit_math_sin(theta); 00641 00642 if(x->dimcount > 2) 00643 x->gradients[i].float64[2] = fz; 00644 } 00645 break; 00646 } 00647 default: 00648 { 00649 // just normalize vectors in n-dim space 00650 for(i = 0; i < x->tablesize; i++) 00651 { 00652 // get n-dim pseudo random signed values 00653 for(j = 0; j < x->dimcount; j++) 00654 { 00655 fv = (jit_rand() % x->tablesize) / (double)x->tablesize; 00656 fv = 1.0 - 2.0 * fv; 00657 ndim[j] = fv; 00658 } 00659 00660 // calculate vector's magnitude 00661 mag = 0; 00662 for(j = 0; j < x->dimcount; j++) 00663 mag += JIT_MATH_SQR(ndim[i]); 00664 00665 // calculate scale factor 00666 if(mag > 0.0f) { 00667 fv = jit_math_sqrt(mag); 00668 fv = 1.0 / fv; 00669 } else { 00670 fv = 1.0f; 00671 } 00672 00673 // normalize and assign 00674 for(j = 0; j < x->dimcount; j++) 00675 { 00676 ndim[j] *= fv; 00677 x->gradients[i].float64[j] = ndim[j]; 00678 } 00679 } 00680 } 00681 }; 00682 00683 // copy and convert 00684 for(i = 0; i < x->tablesize; i++) 00685 { 00686 for(j = 0; j < x->dimcount; j++) 00687 { 00688 x->gradients[i].float32[j] = (float)x->gradients[i].float64[j]; 00689 x->gradients[i].fixed[j] = DoubleToFixed(x->gradients[i].float64[j]); 00690 } 00691 } 00692 00693 out: 00694 return err; 00695 } 00696 00697 long jit_functor_noise_gradient_eval_fixed( 00698 t_jit_functor_noise_gradient *x, long dimcount, long *vals) 00699 { 00700 // safety 00701 if(!x->evaluator.ob) 00702 return FloatToFixed(0.0f); 00703 00704 if(!x->p) 00705 jit_functor_noise_permutations_init(&x->p, x->tablesize, x->seed); 00706 00707 if(!x->lattice.fixed) 00708 jit_functor_noise_lattice_init(&x->lattice, x->tablesize, x->seed); 00709 00710 if(!x->gradients || dimcount != x->dimcount) 00711 { 00712 x->dimcount = dimcount; 00713 jit_functor_noise_gradient_dir_init(x); 00714 } 00715 00716 return jit_functor_noise_gradient_eval_fixed_ndim(x, dimcount, vals); 00717 } 00718 00719 float jit_functor_noise_gradient_eval_float32( 00720 t_jit_functor_noise_gradient *x, long dimcount, float *vals) 00721 { 00722 // safety 00723 if(!x->evaluator.ob) 00724 return 0.0f; 00725 00726 if(!x->p) 00727 jit_functor_noise_permutations_init(&x->p, x->tablesize, x->seed); 00728 00729 if(!x->lattice.float32) 00730 jit_functor_noise_lattice_init(&x->lattice, x->tablesize, x->seed); 00731 00732 if(!x->gradients || dimcount != x->dimcount) 00733 { 00734 x->dimcount = dimcount; 00735 jit_functor_noise_gradient_dir_init(x); 00736 } 00737 00738 return jit_functor_noise_gradient_eval_float32_ndim(x, dimcount, vals); 00739 } 00740 00741 double jit_functor_noise_gradient_eval_float64( 00742 t_jit_functor_noise_gradient *x, long dimcount, double *vals) 00743 { 00744 // safety 00745 if(!x->evaluator.ob) 00746 return 0.0; 00747 00748 if(!x->p) 00749 jit_functor_noise_permutations_init(&x->p, x->tablesize, x->seed); 00750 00751 if(!x->lattice.float64) 00752 jit_functor_noise_lattice_init(&x->lattice, x->tablesize, x->seed); 00753 00754 if(!x->gradients || dimcount != x->dimcount) 00755 { 00756 x->dimcount = dimcount; 00757 jit_functor_noise_gradient_dir_init(x); 00758 } 00759 00760 return jit_functor_noise_gradient_eval_float64_ndim(x, dimcount, vals); 00761 } 00762 00763 // -------------------------------------------------------------------------- 00764 00765 t_jit_err jit_functor_noise_gradient_evaluator_init( 00766 t_jit_functor_wrapper *x, t_symbol *name ) 00767 { 00768 t_jit_err err = JIT_ERR_NONE; 00769 00770 if(x) 00771 { 00772 // create the new object and get it's interface 00773 err = jit_functor_wrapper_init(x, NULL, name); 00774 } 00775 else 00776 { 00777 err = JIT_ERR_INVALID_PTR; 00778 } 00779 00780 if(err && name && name->s_name) { 00781 jit_object_error((t_object *)x,"jit.functor.noise.gradient: unable to create filter object '%s'.", name->s_name); 00782 if(x) { 00783 x->ob = NULL; 00784 x->fm = NULL; 00785 } 00786 } 00787 00788 return err; 00789 } 00790 00791 // -------------------------------------------------------------------------- 00792 00793 t_jit_object *jit_functor_noise_gradient_subfunctor( 00794 t_jit_functor_noise_gradient *x, t_symbol *name) 00795 { 00796 if (name == ps_jit_functor_noise_gradient_filter) 00797 return (t_jit_object *)x->evaluator.ob; 00798 else 00799 return NULL; 00800 }
Copyright © 2008, Cycling '74