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