Max 5 API Reference
00001 /* 00002 * jit.fractal.mono.c 00003 * 00004 * Copyright 2001-2005 - Cycling '74 00005 * Derek Gerstmann - derek@cycling74.com 00006 * 00007 * Functor for evaluating an additive monofractal (a varient of fractional 00008 * Brownian motion or fBm) using an arbitrary *signed* basis function. 00009 * The mono refers to the single/isotropic statistical featuristics of the 00010 * function, and additive refers to the cascade of additions that form the 00011 * loop of the fractal evaluation. 00012 * 00013 */ 00014 00015 // -------------------------------------------------------------------------- 00016 00017 #include "jit.common.h" 00018 #include "jit.functor.h" 00019 #include "jit.fractal.h" 00020 00021 // -------------------------------------------------------------------------- 00022 00023 typedef struct _jit_functor_fractal_mono 00024 { 00025 t_jit_object ob; 00026 t_symbol *basis; 00027 long seed; // seed for random rotation matrix 00028 long dimcount; // coord dimension of last evaluation 00029 long rotate; // flag for rotations per octave 00030 t_jit_functor_combined_dimvalue scale; // position scale factor for basis 00031 t_jit_functor_combined_dimvalue offset; // position offset for basis 00032 t_jit_functor_combined_value roughness; // determines the fractal dimension 00033 t_jit_functor_combined_value lacunarity; // spacing or gaps between detail 00034 t_jit_functor_combined_value detail; // determines number of octaves 00035 t_jit_functor_combined_value level; // adjusts the zero offset 00036 t_jit_functor_combined_value result; // scaling factor for result 00037 t_jit_functor_combined_dynarray exponents; // precalc-ed exponents 00038 t_jit_functor_fractal_combined_matrix_dynarray rotations; // precalc-ed rotation matrices per octave 00039 t_jit_functor_wrapper evaluator; // basis functor 00040 00041 } t_jit_functor_fractal_mono; 00042 00043 // -------------------------------------------------------------------------- 00044 00045 t_jit_object *jit_functor_fractal_mono_new(void); 00046 t_jit_err jit_functor_fractal_mono_free(t_jit_functor_fractal_mono *x); 00047 00048 t_jit_err jit_functor_fractal_mono_basis(t_jit_functor_fractal_mono *x, void *attr, long argc, t_atom *argv); 00049 t_jit_err jit_functor_fractal_mono_seed(t_jit_functor_fractal_mono *x, void *attr, long argc, t_atom *argv); 00050 t_jit_err jit_functor_fractal_mono_rotate(t_jit_functor_fractal_mono *x, void *attr, long argc, t_atom *argv); 00051 t_jit_err jit_functor_fractal_mono_scale(t_jit_functor_fractal_mono *x, void *attr, long argc, t_atom *argv); 00052 t_jit_err jit_functor_fractal_mono_offset(t_jit_functor_fractal_mono *x, void *attr, long argc, t_atom *argv); 00053 t_jit_err jit_functor_fractal_mono_roughness(t_jit_functor_fractal_mono *x, void *attr, long argc, t_atom *argv); 00054 t_jit_err jit_functor_fractal_mono_lacunarity(t_jit_functor_fractal_mono *x, void *attr, long argc, t_atom *argv); 00055 t_jit_err jit_functor_fractal_mono_detail(t_jit_functor_fractal_mono *x, void *attr, long argc, t_atom *argv); 00056 t_jit_err jit_functor_fractal_mono_level(t_jit_functor_fractal_mono *x, void *attr, long argc, t_atom *argv); 00057 t_jit_err jit_functor_fractal_mono_result(t_jit_functor_fractal_mono *x, void *attr, long argc, t_atom *argv); 00058 00059 t_jit_err jit_functor_fractal_mono_recalc(t_jit_functor_fractal_mono *x); 00060 00061 long jit_functor_fractal_mono_eval_fixed(t_jit_functor_fractal_mono *x, long dimcount, long *vals); 00062 float jit_functor_fractal_mono_eval_float32(t_jit_functor_fractal_mono *x, long dimcount, float *vals); 00063 double jit_functor_fractal_mono_eval_float64(t_jit_functor_fractal_mono *x, long dimcount, double *vals); 00064 t_jit_object *jit_functor_fractal_mono_subfunctor(t_jit_functor_fractal_mono *x, t_symbol *name); 00065 00066 t_class * _jit_functor_fractal_mono_class; 00067 t_symbol * ps_jit_functor_fractal_mono_basis; 00068 // -------------------------------------------------------------------------- 00069 00070 t_jit_err jit_functor_fractal_mono_init(void) 00071 { 00072 t_jit_object *attr; 00073 00074 // create functor class 00075 _jit_functor_fractal_mono_class = jit_class_new("jit_functor_fractal_mono", 00076 (method)jit_functor_fractal_mono_new,(method)jit_functor_fractal_mono_free, 00077 sizeof(t_jit_functor_fractal_mono),0L); 00078 00079 // add attribute methods 00080 attr = jit_object_new(_jit_sym_jit_attr_offset,"type",_jit_sym_symbol,0, 00081 (method)0L,(method)jit_functor_fractal_mono_basis, 00082 calcoffset(t_jit_functor_fractal_mono,basis)); 00083 jit_class_addattr(_jit_functor_fractal_mono_class,attr); 00084 attr = jit_object_new(_jit_sym_jit_attr_offset,"basis",_jit_sym_symbol,0, 00085 (method)0L,(method)jit_functor_fractal_mono_basis, 00086 calcoffset(t_jit_functor_fractal_mono,basis)); 00087 jit_class_addattr(_jit_functor_fractal_mono_class,attr); 00088 attr = jit_object_new(_jit_sym_jit_attr_offset,"seed",_jit_sym_long,0, 00089 (method)0L,(method)jit_functor_fractal_mono_seed, 00090 calcoffset(t_jit_functor_fractal_mono,seed)); 00091 jit_class_addattr(_jit_functor_fractal_mono_class,attr); 00092 attr = jit_object_new(_jit_sym_jit_attr_offset,"rotate",_jit_sym_long,0, 00093 (method)0L,(method)jit_functor_fractal_mono_rotate, 00094 calcoffset(t_jit_functor_fractal_mono,rotate)); 00095 jit_class_addattr(_jit_functor_fractal_mono_class,attr); 00096 attr = jit_object_new(_jit_sym_jit_attr_offset_array,"scale",_jit_sym_float64,JIT_MATRIX_MAX_DIMCOUNT,0, 00097 (method)0L,(method)jit_functor_fractal_mono_scale, 00098 calcoffset(t_jit_functor_fractal_mono,scale.dimcount), 00099 calcoffset(t_jit_functor_fractal_mono,scale.float64)); 00100 jit_class_addattr(_jit_functor_fractal_mono_class,attr); 00101 attr = jit_object_new(_jit_sym_jit_attr_offset_array,"offset",_jit_sym_float64,JIT_MATRIX_MAX_DIMCOUNT,0, 00102 (method)0L,(method)jit_functor_fractal_mono_offset, 00103 calcoffset(t_jit_functor_fractal_mono,offset.dimcount), 00104 calcoffset(t_jit_functor_fractal_mono,offset.float64)); 00105 jit_class_addattr(_jit_functor_fractal_mono_class,attr); 00106 attr = jit_object_new(_jit_sym_jit_attr_offset,"roughness",_jit_sym_float64,0, 00107 (method)0L,(method)jit_functor_fractal_mono_roughness, 00108 calcoffset(t_jit_functor_fractal_mono,roughness.float64)); 00109 jit_class_addattr(_jit_functor_fractal_mono_class,attr); 00110 attr = jit_object_new(_jit_sym_jit_attr_offset,"lacunarity",_jit_sym_float64,0, 00111 (method)0L,(method)jit_functor_fractal_mono_lacunarity, 00112 calcoffset(t_jit_functor_fractal_mono,lacunarity.float64)); 00113 jit_class_addattr(_jit_functor_fractal_mono_class,attr); 00114 attr = jit_object_new(_jit_sym_jit_attr_offset,"detail",_jit_sym_float64,0, 00115 (method)0L,(method)jit_functor_fractal_mono_detail, 00116 calcoffset(t_jit_functor_fractal_mono,detail.float64)); 00117 jit_class_addattr(_jit_functor_fractal_mono_class,attr); 00118 attr = jit_object_new(_jit_sym_jit_attr_offset,"level",_jit_sym_float64,0, 00119 (method)0L,(method)jit_functor_fractal_mono_level, 00120 calcoffset(t_jit_functor_fractal_mono,level.float64)); 00121 jit_class_addattr(_jit_functor_fractal_mono_class,attr); 00122 attr = jit_object_new(_jit_sym_jit_attr_offset,"result",_jit_sym_float64,0, 00123 (method)0L,(method)jit_functor_fractal_mono_result, 00124 calcoffset(t_jit_functor_fractal_mono,result.float64)); 00125 jit_class_addattr(_jit_functor_fractal_mono_class,attr); 00126 00127 // add evaluation methods 00128 jit_class_addmethod(_jit_functor_fractal_mono_class, 00129 (method)jit_functor_fractal_mono_eval_fixed, "evalfixed", A_CANT, 0L); 00130 jit_class_addmethod(_jit_functor_fractal_mono_class, 00131 (method)jit_functor_fractal_mono_eval_float32, "evalfloat32", A_CANT, 0L); 00132 jit_class_addmethod(_jit_functor_fractal_mono_class, 00133 (method)jit_functor_fractal_mono_eval_float64, "evalfloat64", A_CANT, 0L); 00134 00135 // exposing subfunctor to set/getattr interface 00136 jit_class_addmethod(_jit_functor_fractal_mono_class, 00137 (method)jit_functor_fractal_mono_subfunctor, "subfunctor", A_CANT, 0L); 00138 00139 // important to add last for subclassing methods 00140 jit_functor_setup_class(_jit_functor_fractal_mono_class,"fractal","mono"); 00141 jit_class_register(_jit_functor_fractal_mono_class); 00142 00143 // generate symbols 00144 ps_jit_functor_fractal_mono_basis = gensym("basis"); 00145 return JIT_ERR_NONE; 00146 } 00147 00148 t_jit_object *jit_functor_fractal_mono_new(void) 00149 { 00150 long i; 00151 t_jit_functor_fractal_mono *x; 00152 t_atom a; 00153 00154 if (x = (t_jit_functor_fractal_mono *)jit_object_alloc(_jit_functor_fractal_mono_class)) { 00155 00156 // initialization 00157 x->basis = gensym("noise.gradient"); 00158 x->seed = JIT_FRACTAL_DEFAULT_SEED; 00159 x->dimcount = 2; 00160 x->rotate = FALSE; 00161 00162 // set all data members 00163 for(i = 0; i < JIT_MATRIX_MAX_DIMCOUNT; i++) 00164 { 00165 x->scale.float64[i] = JIT_FRACTAL_DEFAULT_SCALE; 00166 x->scale.float32[i] = JIT_FRACTAL_DEFAULT_SCALE; 00167 x->scale.fixed[i] = FloatToFixed(x->scale.float32[i]); 00168 00169 x->offset.float64[i] = JIT_FRACTAL_DEFAULT_OFFSET; 00170 x->offset.float32[i] = JIT_FRACTAL_DEFAULT_OFFSET; 00171 x->offset.fixed[i] = FloatToFixed(x->offset.float32[i]); 00172 } 00173 00174 JIT_FUNCTOR_COMBINED_VALUE_SETALL(x->roughness, JIT_FRACTAL_DEFAULT_ROUGHNESS); 00175 JIT_FUNCTOR_COMBINED_VALUE_SETALL(x->lacunarity, JIT_FRACTAL_DEFAULT_LACUNARITY); 00176 JIT_FUNCTOR_COMBINED_VALUE_SETALL(x->detail, JIT_FRACTAL_DEFAULT_DETAIL); 00177 JIT_FUNCTOR_COMBINED_VALUE_SETALL(x->level, JIT_FRACTAL_DEFAULT_LEVEL); 00178 JIT_FUNCTOR_COMBINED_VALUE_SETALL(x->result, JIT_FRACTAL_DEFAULT_RESULT); 00179 00180 x->exponents.float64 = NULL; 00181 x->exponents.float32 = NULL; 00182 x->exponents.fixed = NULL; 00183 x->exponents.count = 0; 00184 00185 x->rotations.m = NULL; 00186 x->rotations.count = 0; 00187 00188 x->evaluator.ob = NULL; 00189 x->evaluator.fm = NULL; 00190 00191 jit_functor_wrapper_init(&x->evaluator, NULL, x->basis); 00192 00193 // disable signed evaluation 00194 jit_atom_setlong(&a, 0); 00195 jit_object_method(x->evaluator.ob, gensym("sign"), 1, &a); 00196 00197 // init exponents 00198 jit_functor_fractal_exponents_init( 00199 &x->exponents, x->detail.float64, 00200 x->roughness.float64, x->lacunarity.float64); 00201 00202 jit_functor_fractal_mono_recalc(x); 00203 } 00204 00205 return (t_jit_object *)x; 00206 } 00207 00208 t_jit_err jit_functor_fractal_mono_free(t_jit_functor_fractal_mono *x) 00209 { 00210 // dispose allocated mem 00211 jit_functor_combined_dynarray_destroy(&x->exponents); 00212 jit_functor_fractal_rotations_destroy(&x->rotations); 00213 00214 if(x->evaluator.ob) 00215 jit_object_free(x->evaluator.ob); 00216 x->evaluator.ob = NULL; 00217 x->evaluator.fm = NULL; 00218 00219 return JIT_ERR_NONE; 00220 } 00221 00222 t_jit_err jit_functor_fractal_mono_basis( 00223 t_jit_functor_fractal_mono *x, void *attr, long argc, t_atom *argv) 00224 { 00225 t_jit_err err; 00226 t_symbol *v; 00227 t_atom a; 00228 00229 if (x) { 00230 v = jit_atom_getsym(argv); 00231 if (x->basis != v) { 00232 x->basis = v; 00233 00234 err = jit_functor_wrapper_init(&x->evaluator, NULL, x->basis); 00235 if(err) return err; 00236 00237 jit_atom_setlong(&a, 1); 00238 err = (t_jit_err) jit_object_method(x->evaluator.ob, gensym("sign"), 1, &a); 00239 if(err) 00240 jit_object_post((t_object *)x,"jit.fractal.mono: selected evaluator may not produce an appropriate output range"); 00241 00242 jit_functor_fractal_mono_recalc(x); 00243 } 00244 return JIT_ERR_NONE; 00245 } 00246 return JIT_ERR_INVALID_PTR; 00247 } 00248 00249 t_jit_err jit_functor_fractal_mono_seed( 00250 t_jit_functor_fractal_mono *x, void *attr, long argc, t_atom *argv) 00251 { 00252 long v; 00253 00254 if (x) { 00255 v = jit_atom_getlong(argv); 00256 if (x->seed != v) { 00257 x->seed = v; 00258 jit_functor_fractal_rotations_init(&x->rotations, x->detail.float64, x->dimcount, x->seed); 00259 jit_functor_fractal_mono_recalc(x); 00260 } 00261 return JIT_ERR_NONE; 00262 } 00263 return JIT_ERR_INVALID_PTR; 00264 } 00265 00266 t_jit_err jit_functor_fractal_mono_rotate( 00267 t_jit_functor_fractal_mono *x, void *attr, long argc, t_atom *argv) 00268 { 00269 long v; 00270 00271 if (x) { 00272 v = jit_atom_getlong(argv); 00273 if (x->rotate != v) { 00274 x->rotate = (v > 0) ? TRUE : FALSE; 00275 jit_functor_fractal_rotations_init(&x->rotations, x->detail.float64, x->dimcount, x->seed); 00276 jit_functor_fractal_mono_recalc(x); 00277 } 00278 return JIT_ERR_NONE; 00279 } 00280 return JIT_ERR_INVALID_PTR; 00281 } 00282 00283 t_jit_err jit_functor_fractal_mono_offset( 00284 t_jit_functor_fractal_mono *x, void *attr, long argc, t_atom *argv) 00285 { 00286 long i; 00287 double v; 00288 char changed = FALSE; // changed flag 00289 00290 if (x) { 00291 for(i = 0; i < argc && i < JIT_MATRIX_MAX_DIMCOUNT; i++) 00292 { 00293 v = jit_atom_getfloat(argv+i); 00294 if(x->offset.float64[i] != v) 00295 { 00296 // copy and convert 00297 JIT_FUNCTOR_COMBINED_ARRAY_SETALL(i, x->offset, v); 00298 changed = TRUE; 00299 } 00300 } 00301 if(changed) { 00302 x->offset.dimcount = argc; 00303 jit_functor_fractal_mono_recalc(x); 00304 } 00305 00306 return JIT_ERR_NONE; 00307 } 00308 return JIT_ERR_INVALID_PTR; 00309 } 00310 00311 t_jit_err jit_functor_fractal_mono_scale( 00312 t_jit_functor_fractal_mono *x, void *attr, long argc, t_atom *argv) 00313 { 00314 long i; 00315 double v; 00316 char changed = FALSE; // changed flag 00317 00318 if (x) { 00319 for(i = 0; i < argc && i < JIT_MATRIX_MAX_DIMCOUNT; i++) 00320 { 00321 v = jit_atom_getfloat(argv+i); 00322 if(x->scale.float64[i] != v) 00323 { 00324 // copy and convert 00325 JIT_FUNCTOR_COMBINED_ARRAY_SETALL(i, x->scale, v); 00326 changed = TRUE; 00327 } 00328 } 00329 if(changed) { 00330 x->scale.dimcount = argc; 00331 jit_functor_fractal_mono_recalc(x); 00332 } 00333 00334 return JIT_ERR_NONE; 00335 } 00336 return JIT_ERR_INVALID_PTR; 00337 } 00338 00339 t_jit_err jit_functor_fractal_mono_roughness( 00340 t_jit_functor_fractal_mono *x, void *attr, long argc, t_atom *argv) 00341 { 00342 double v; 00343 00344 if (x) { 00345 v = jit_atom_getfloat(argv); 00346 if (x->roughness.float64 != v) { 00347 00348 // copy and convert 00349 JIT_FUNCTOR_COMBINED_VALUE_SETALL(x->roughness, v); 00350 00351 // init exponents 00352 jit_functor_fractal_exponents_init( 00353 &x->exponents, x->detail.float64, 00354 x->roughness.float64, x->lacunarity.float64); 00355 00356 jit_functor_fractal_mono_recalc(x); 00357 } 00358 return JIT_ERR_NONE; 00359 } 00360 return JIT_ERR_INVALID_PTR; 00361 } 00362 00363 t_jit_err jit_functor_fractal_mono_lacunarity( 00364 t_jit_functor_fractal_mono *x, void *attr, long argc, t_atom *argv) 00365 { 00366 double v; 00367 00368 if (x) { 00369 v = jit_atom_getfloat(argv); 00370 if (x->lacunarity.float64 != v && v > 0.0) { 00371 00372 // copy and convert 00373 JIT_FUNCTOR_COMBINED_VALUE_SETALL(x->lacunarity, v); 00374 00375 // init exponents 00376 jit_functor_fractal_exponents_init( 00377 &x->exponents, x->detail.float64, 00378 x->roughness.float64, x->lacunarity.float64); 00379 00380 jit_functor_fractal_mono_recalc(x); 00381 } 00382 return JIT_ERR_NONE; 00383 } 00384 return JIT_ERR_INVALID_PTR; 00385 } 00386 00387 t_jit_err jit_functor_fractal_mono_detail( 00388 t_jit_functor_fractal_mono *x, void *attr, long argc, t_atom *argv) 00389 { 00390 double v; 00391 00392 if (x) { 00393 v = jit_atom_getfloat(argv); 00394 if (x->detail.float64 != v && v > 0.0 && v < JIT_FRACTAL_MAX_OCTAVES) { 00395 00396 // copy and convert 00397 JIT_FUNCTOR_COMBINED_VALUE_SETALL(x->detail, v); 00398 00399 // init exponents 00400 jit_functor_fractal_exponents_init( 00401 &x->exponents, x->detail.float64, 00402 x->roughness.float64, x->lacunarity.float64); 00403 00404 // init rotation matrices 00405 if(x->rotate) 00406 jit_functor_fractal_rotations_init( 00407 &x->rotations, x->detail.float64, x->dimcount, x->seed); 00408 00409 jit_functor_fractal_mono_recalc(x); 00410 } 00411 return JIT_ERR_NONE; 00412 } 00413 return JIT_ERR_INVALID_PTR; 00414 } 00415 00416 t_jit_err jit_functor_fractal_mono_level( 00417 t_jit_functor_fractal_mono *x, void *attr, long argc, t_atom *argv) 00418 { 00419 double v; 00420 00421 if (x) { 00422 v = jit_atom_getfloat(argv); 00423 if (x->level.float64 != v) { 00424 00425 // copy and convert 00426 JIT_FUNCTOR_COMBINED_VALUE_SETALL(x->level, v); 00427 jit_functor_fractal_mono_recalc(x); 00428 } 00429 return JIT_ERR_NONE; 00430 } 00431 return JIT_ERR_INVALID_PTR; 00432 } 00433 00434 t_jit_err jit_functor_fractal_mono_result( 00435 t_jit_functor_fractal_mono *x, void *attr, long argc, t_atom *argv) 00436 { 00437 double v; 00438 00439 if (x) { 00440 v = jit_atom_getfloat(argv); 00441 if (x->result.float64 != v) { 00442 00443 // copy and convert 00444 JIT_FUNCTOR_COMBINED_VALUE_SETALL(x->result, v); 00445 jit_functor_fractal_mono_recalc(x); 00446 } 00447 return JIT_ERR_NONE; 00448 } 00449 return JIT_ERR_INVALID_PTR; 00450 } 00451 00452 t_jit_err jit_functor_fractal_mono_recalc( 00453 t_jit_functor_fractal_mono *x) 00454 { 00455 // calculate intermediary values for efficiency 00456 return JIT_ERR_NONE; 00457 } 00458 00459 // -------------------------------------------------------------------------- 00460 // vector evaluation functions 00461 // -------------------------------------------------------------------------- 00462 long jit_functor_fractal_mono_eval_fixed( 00463 t_jit_functor_fractal_mono *x, long dimcount, long *vals) 00464 { 00465 /* TODO! */ 00466 return jit_functor_eval_fixed_with_float32((t_jit_object *)x,dimcount,vals, 00467 (t_jit_functor_float32_sig)jit_functor_fractal_mono_eval_float32); 00468 } 00469 00470 float jit_functor_fractal_mono_eval_float32( 00471 t_jit_functor_fractal_mono *x, long dimcount, float *vals) 00472 { 00473 long i, j, k; 00474 long count = (long)x->detail.float32; 00475 float pos[JIT_MATRIX_MAX_DIMCOUNT]; 00476 float rot[JIT_MATRIX_MAX_DIMCOUNT]; 00477 00478 float basis; 00479 float value; 00480 float rem; 00481 00482 // safety 00483 if(!x->evaluator.ob || !x->evaluator.fm || !x->exponents.float32) 00484 return 0.0f; 00485 00486 // reinit rotations if dimcount has changed 00487 if(dimcount != x->dimcount && x->rotate) { 00488 x->dimcount = dimcount; 00489 jit_functor_fractal_rotations_init(&x->rotations, x->detail.float64, x->dimcount, x->seed); 00490 } 00491 00492 // scale and offset position 00493 for( i = 0; i < dimcount; i++) 00494 pos[i] = (vals[i] + x->offset.float32[i]) * x->scale.float32[i]; 00495 00496 value = 0.0f; 00497 for ( i = 0; i < count; i++ ) 00498 { 00499 // evaluate the basis function to create the spectrum 00500 basis = x->evaluator.fm->evalfloat32(x->evaluator.ob, dimcount, pos ); 00501 value += (basis + x->level.float32) * x->exponents.float32[i]; 00502 00503 // multipy in the lacunarity to create the gaps between octaves 00504 for( j = 0; j < dimcount; j++ ) 00505 pos[j] *= x->lacunarity.float32; 00506 00507 // apply rotation to reduce alignment artifacts 00508 if(i > 0 && x->rotate) { 00509 for( j = 0; j < dimcount; j++ ) { 00510 rot[j] = 0; 00511 for( k = 0; k < dimcount; k++ ) { 00512 rot[j] += x->rotations.m[i-1].float32[j][k] * pos[k]; 00513 } 00514 } 00515 for( j = 0; j < dimcount; j++ ) 00516 pos[j] = rot[j]; 00517 } 00518 } 00519 00520 // take care of remainder in detail using i from above 00521 rem = x->detail.float32 - count; 00522 if ( rem ) 00523 { 00524 basis = x->evaluator.fm->evalfloat32(x->evaluator.ob, dimcount, pos ); 00525 value += rem * (basis + x->level.float32) * x->exponents.float32[i]; 00526 } 00527 00528 // weight the result 00529 return value * x->result.float32; 00530 } 00531 00532 double jit_functor_fractal_mono_eval_float64( 00533 t_jit_functor_fractal_mono *x, long dimcount, double *vals) 00534 { 00535 long i, j, k; 00536 long count = (long)x->detail.float64; 00537 double pos[JIT_MATRIX_MAX_DIMCOUNT]; 00538 double rot[JIT_MATRIX_MAX_DIMCOUNT]; 00539 00540 double basis; 00541 double value; 00542 double rem; 00543 00544 // safety 00545 if(!x->evaluator.ob || !x->evaluator.fm || !x->exponents.float64) 00546 return 0.0; 00547 00548 // reinit rotations if dimcount has changed 00549 if(dimcount != x->dimcount && x->rotate) { 00550 x->dimcount = dimcount; 00551 jit_functor_fractal_rotations_init(&x->rotations, x->detail.float64, x->dimcount, x->seed); 00552 } 00553 00554 // scale and offset position 00555 for( i = 0; i < dimcount; i++) 00556 pos[i] = (vals[i] + x->offset.float64[i]) * x->scale.float64[i]; 00557 00558 value = 0.0; 00559 for ( i = 0; i < count; i++ ) 00560 { 00561 // evaluate the basis function to create the spectrum 00562 basis = x->evaluator.fm->evalfloat64(x->evaluator.ob, dimcount, pos ); 00563 value += (basis + x->level.float64) * x->exponents.float64[i]; 00564 00565 // multipy in the lacunarity to create the gaps between octaves 00566 for( j = 0; j < dimcount; j++ ) 00567 pos[j] *= x->lacunarity.float64; 00568 00569 // apply rotation to reduce alignment artifacts 00570 if(i > 0 && x->rotate) { 00571 for( j = 0; j < dimcount; j++ ) { 00572 rot[j] = 0; 00573 for( k = 0; k < dimcount; k++ ) { 00574 rot[j] += x->rotations.m[i-1].float64[j][k] * pos[k]; 00575 } 00576 } 00577 for( j = 0; j < dimcount; j++ ) 00578 pos[j] = rot[j]; 00579 } 00580 } 00581 00582 // take care of remainder in detail using i from above 00583 rem = x->detail.float64 - count; 00584 if ( rem ) 00585 { 00586 basis = x->evaluator.fm->evalfloat64(x->evaluator.ob, dimcount, pos ); 00587 value += rem * (basis + x->level.float64) * x->exponents.float64[i]; 00588 } 00589 00590 // weight the result 00591 return value * x->result.float64; 00592 } 00593 00594 // -------------------------------------------------------------------------- 00595 00596 t_jit_object *jit_functor_fractal_mono_subfunctor( 00597 t_jit_functor_fractal_mono *x, t_symbol *name) 00598 { 00599 if (name == ps_jit_functor_fractal_mono_basis) 00600 return (t_jit_object *)x->evaluator.ob; 00601 else 00602 return NULL; 00603 } 00604 00605 // --------------------------------------------------------------------------
Copyright © 2008, Cycling '74