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