Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00019 * All rights reserved. 00020 * 00021 * The Original Code is: all of this file. 00022 * 00023 * Contributor(s): none yet. 00024 * 00025 * ***** END GPL LICENSE BLOCK ***** 00026 */ 00027 00033 #include <stdio.h> 00034 #include <math.h> 00035 #include <string.h> 00036 00037 #include "MEM_guardedalloc.h" 00038 00039 #include "BLI_blenlib.h" 00040 #include "BLI_editVert.h" 00041 #include "BLI_math.h" 00042 #include "BLI_rand.h" 00043 #include "BLI_utildefines.h" 00044 00045 #include "DNA_anim_types.h" 00046 #include "DNA_armature_types.h" 00047 #include "DNA_group_types.h" 00048 #include "DNA_key_types.h" 00049 #include "DNA_meshdata_types.h" 00050 #include "DNA_scene_types.h" 00051 #include "DNA_vfont_types.h" 00052 00053 #include "BKE_animsys.h" 00054 #include "BKE_curve.h" 00055 #include "BKE_DerivedMesh.h" 00056 #include "BKE_depsgraph.h" 00057 #include "BKE_font.h" 00058 #include "BKE_group.h" 00059 #include "BKE_global.h" 00060 #include "BKE_key.h" 00061 #include "BKE_lattice.h" 00062 #include "BKE_main.h" 00063 #include "BKE_mesh.h" 00064 #include "BKE_object.h" 00065 #include "BKE_particle.h" 00066 #include "BKE_scene.h" 00067 #include "BKE_utildefines.h" 00068 #include "BKE_depsgraph.h" 00069 #include "BKE_anim.h" 00070 #include "BKE_report.h" 00071 00072 00073 // XXX bad level call... 00074 00075 /* --------------------- */ 00076 /* forward declarations */ 00077 00078 static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[][4], int level, int animated); 00079 00080 /* ******************************************************************** */ 00081 /* Animation Visualisation */ 00082 00083 /* Initialise the default settings for animation visualisation */ 00084 void animviz_settings_init(bAnimVizSettings *avs) 00085 { 00086 /* sanity check */ 00087 if (avs == NULL) 00088 return; 00089 00090 /* ghosting settings */ 00091 avs->ghost_bc= avs->ghost_ac= 10; 00092 00093 avs->ghost_sf= 1; // xxx - take from scene instead? 00094 avs->ghost_ef= 250; // xxx - take from scene instead? 00095 00096 avs->ghost_step= 1; 00097 00098 00099 /* path settings */ 00100 avs->path_bc= avs->path_ac= 10; 00101 00102 avs->path_sf= 1; // xxx - take from scene instead? 00103 avs->path_ef= 250; // xxx - take from scene instead? 00104 00105 avs->path_viewflag= (MOTIONPATH_VIEW_KFRAS|MOTIONPATH_VIEW_KFNOS); 00106 00107 avs->path_step= 1; 00108 } 00109 00110 /* ------------------- */ 00111 00112 /* Free the given motion path's cache */ 00113 void animviz_free_motionpath_cache(bMotionPath *mpath) 00114 { 00115 /* sanity check */ 00116 if (mpath == NULL) 00117 return; 00118 00119 /* free the path if necessary */ 00120 if (mpath->points) 00121 MEM_freeN(mpath->points); 00122 00123 /* reset the relevant parameters */ 00124 mpath->points= NULL; 00125 mpath->length= 0; 00126 } 00127 00128 /* Free the given motion path instance and its data 00129 * NOTE: this frees the motion path given! 00130 */ 00131 void animviz_free_motionpath(bMotionPath *mpath) 00132 { 00133 /* sanity check */ 00134 if (mpath == NULL) 00135 return; 00136 00137 /* free the cache first */ 00138 animviz_free_motionpath_cache(mpath); 00139 00140 /* now the instance itself */ 00141 MEM_freeN(mpath); 00142 } 00143 00144 /* ------------------- */ 00145 00146 /* Setup motion paths for the given data 00147 * - scene: current scene (for frame ranges, etc.) 00148 * - ob: object to add paths for (must be provided) 00149 * - pchan: posechannel to add paths for (optional; if not provided, object-paths are assumed) 00150 */ 00151 bMotionPath *animviz_verify_motionpaths(ReportList *reports, Scene *scene, Object *ob, bPoseChannel *pchan) 00152 { 00153 bAnimVizSettings *avs; 00154 bMotionPath *mpath, **dst; 00155 00156 /* sanity checks */ 00157 if (ELEM(NULL, scene, ob)) 00158 return NULL; 00159 00160 /* get destination data */ 00161 if (pchan) { 00162 /* paths for posechannel - assume that posechannel belongs to the object */ 00163 avs= &ob->pose->avs; 00164 dst= &pchan->mpath; 00165 } 00166 else { 00167 /* paths for object */ 00168 avs= &ob->avs; 00169 dst= &ob->mpath; 00170 } 00171 00172 /* avoid 0 size allocs */ 00173 if (avs->path_sf >= avs->path_ef) { 00174 BKE_reportf(reports, RPT_ERROR, 00175 "Motion Path frame extents invalid for %s (%d to %d).%s\n", 00176 (pchan)? pchan->name : ob->id.name, 00177 avs->path_sf, avs->path_ef, 00178 (avs->path_sf == avs->path_ef)? " Cannot have single-frame paths." : ""); 00179 return NULL; 00180 } 00181 00182 /* if there is already a motionpath, just return that, 00183 * but provided it's settings are ok 00184 */ 00185 if (*dst != NULL) { 00186 mpath= *dst; 00187 00188 /* if range is not invalid, and/or length is set ok, just return */ 00189 if ((mpath->start_frame != mpath->end_frame) && (mpath->length > 0)) 00190 return mpath; 00191 } 00192 else { 00193 /* create a new motionpath, and assign it */ 00194 mpath= MEM_callocN(sizeof(bMotionPath), "bMotionPath"); 00195 *dst= mpath; 00196 } 00197 00198 /* set settings from the viz settings */ 00199 mpath->start_frame= avs->path_sf; 00200 mpath->end_frame= avs->path_ef; 00201 00202 mpath->length= mpath->end_frame - mpath->start_frame; 00203 00204 if (avs->path_bakeflag & MOTIONPATH_BAKE_HEADS) 00205 mpath->flag |= MOTIONPATH_FLAG_BHEAD; 00206 else 00207 mpath->flag &= ~MOTIONPATH_FLAG_BHEAD; 00208 00209 /* allocate a cache */ 00210 mpath->points= MEM_callocN(sizeof(bMotionPathVert)*mpath->length, "bMotionPathVerts"); 00211 00212 /* tag viz settings as currently having some path(s) which use it */ 00213 avs->path_bakeflag |= MOTIONPATH_BAKE_HAS_PATHS; 00214 00215 /* return it */ 00216 return mpath; 00217 } 00218 00219 /* ------------------- */ 00220 00221 /* Motion path needing to be baked (mpt) */ 00222 typedef struct MPathTarget { 00223 struct MPathTarget *next, *prev; 00224 00225 bMotionPath *mpath; /* motion path in question */ 00226 00227 Object *ob; /* source object */ 00228 bPoseChannel *pchan; /* source posechannel (if applicable) */ 00229 } MPathTarget; 00230 00231 /* ........ */ 00232 00233 /* get list of motion paths to be baked for the given object 00234 * - assumes the given list is ready to be used 00235 */ 00236 // TODO: it would be nice in future to be able to update objects dependant on these bones too? 00237 void animviz_get_object_motionpaths(Object *ob, ListBase *targets) 00238 { 00239 MPathTarget *mpt; 00240 00241 /* object itself first */ 00242 if ((ob->avs.recalc & ANIMVIZ_RECALC_PATHS) && (ob->mpath)) { 00243 /* new target for object */ 00244 mpt= MEM_callocN(sizeof(MPathTarget), "MPathTarget Ob"); 00245 BLI_addtail(targets, mpt); 00246 00247 mpt->mpath= ob->mpath; 00248 mpt->ob= ob; 00249 } 00250 00251 /* bones */ 00252 if ((ob->pose) && (ob->pose->avs.recalc & ANIMVIZ_RECALC_PATHS)) { 00253 bArmature *arm= ob->data; 00254 bPoseChannel *pchan; 00255 00256 for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { 00257 if ((pchan->bone) && (arm->layer & pchan->bone->layer) && (pchan->mpath)) { 00258 /* new target for bone */ 00259 mpt= MEM_callocN(sizeof(MPathTarget), "MPathTarget PoseBone"); 00260 BLI_addtail(targets, mpt); 00261 00262 mpt->mpath= pchan->mpath; 00263 mpt->ob= ob; 00264 mpt->pchan= pchan; 00265 } 00266 } 00267 } 00268 } 00269 00270 /* ........ */ 00271 00272 /* Note on evaluation optimisations: 00273 * Optimisations currently used here play tricks with the depsgraph in order to try and 00274 * evaluate as few objects as strictly necessary to get nicer performance under standard 00275 * production conditions. For those people who really need the accurate version, 00276 * disable the ifdef (i.e. 1 -> 0) and comment out the call to motionpaths_calc_optimise_depsgraph() 00277 */ 00278 00279 /* tweak the object ordering to trick depsgraph into making MotionPath calculations run faster */ 00280 static void motionpaths_calc_optimise_depsgraph(Scene *scene, ListBase *targets) 00281 { 00282 Base *base, *baseNext; 00283 MPathTarget *mpt; 00284 00285 /* make sure our temp-tag isn't already in use */ 00286 for (base= scene->base.first; base; base= base->next) 00287 base->object->flag &= ~BA_TEMP_TAG; 00288 00289 /* for each target, dump its object to the start of the list if it wasn't moved already */ 00290 for (mpt= targets->first; mpt; mpt= mpt->next) { 00291 for (base=scene->base.first; base; base=baseNext) { 00292 baseNext = base->next; 00293 00294 if ((base->object == mpt->ob) && !(mpt->ob->flag & BA_TEMP_TAG)) { 00295 BLI_remlink(&scene->base, base); 00296 BLI_addhead(&scene->base, base); 00297 00298 mpt->ob->flag |= BA_TEMP_TAG; 00299 break; // we really don't need to continue anymore once this happens, but this line might really 'break' 00300 } 00301 } 00302 } 00303 00304 /* "brew me a list that's sorted a bit faster now depsy" */ 00305 DAG_scene_sort(G.main, scene); 00306 } 00307 00308 /* update scene for current frame */ 00309 static void motionpaths_calc_update_scene(Scene *scene) 00310 { 00311 #if 1 // 'production' optimisations always on 00312 Base *base, *last=NULL; 00313 00314 /* only stuff that moves or needs display still */ 00315 DAG_scene_update_flags(G.main, scene, scene->lay, TRUE); 00316 00317 /* find the last object with the tag 00318 * - all those afterwards are assumed to not be relevant for our calculations 00319 */ 00320 // optimise further by moving out... 00321 for (base=scene->base.first; base; base=base->next) { 00322 if (base->object->flag & BA_TEMP_TAG) 00323 last = base; 00324 } 00325 00326 /* perform updates for tagged objects */ 00327 // XXX: this will break if rigs depend on scene or other data that 00328 // is animated but not attached to/updatable from objects 00329 for (base=scene->base.first; base; base=base->next) { 00330 /* update this object */ 00331 object_handle_update(scene, base->object); 00332 00333 /* if this is the last one we need to update, let's stop to save some time */ 00334 if (base == last) 00335 break; 00336 } 00337 #else // original, 'always correct' version 00338 /* do all updates 00339 * - if this is too slow, resort to using a more efficient way 00340 * that doesn't force complete update, but for now, this is the 00341 * most accurate way! 00342 */ 00343 scene_update_for_newframe(G.main, scene, scene->lay); // XXX this is the best way we can get anything moving 00344 #endif 00345 } 00346 00347 /* ........ */ 00348 00349 /* perform baking for the targets on the current frame */ 00350 static void motionpaths_calc_bake_targets(Scene *scene, ListBase *targets) 00351 { 00352 MPathTarget *mpt; 00353 00354 /* for each target, check if it can be baked on the current frame */ 00355 for (mpt= targets->first; mpt; mpt= mpt->next) { 00356 bMotionPath *mpath= mpt->mpath; 00357 bMotionPathVert *mpv; 00358 00359 /* current frame must be within the range the cache works for 00360 * - is inclusive of the first frame, but not the last otherwise we get buffer overruns 00361 */ 00362 if ((CFRA < mpath->start_frame) || (CFRA >= mpath->end_frame)) 00363 continue; 00364 00365 /* get the relevant cache vert to write to */ 00366 mpv= mpath->points + (CFRA - mpath->start_frame); 00367 00368 /* pose-channel or object path baking? */ 00369 if (mpt->pchan) { 00370 /* heads or tails */ 00371 if (mpath->flag & MOTIONPATH_FLAG_BHEAD) { 00372 copy_v3_v3(mpv->co, mpt->pchan->pose_head); 00373 } 00374 else { 00375 copy_v3_v3(mpv->co, mpt->pchan->pose_tail); 00376 } 00377 00378 /* result must be in worldspace */ 00379 mul_m4_v3(mpt->ob->obmat, mpv->co); 00380 } 00381 else { 00382 /* worldspace object location */ 00383 copy_v3_v3(mpv->co, mpt->ob->obmat[3]); 00384 } 00385 } 00386 } 00387 00388 /* Perform baking of the given object's and/or its bones' transforms to motion paths 00389 * - scene: current scene 00390 * - ob: object whose flagged motionpaths should get calculated 00391 * - recalc: whether we need to 00392 */ 00393 // TODO: include reports pointer? 00394 void animviz_calc_motionpaths(Scene *scene, ListBase *targets) 00395 { 00396 MPathTarget *mpt; 00397 int sfra, efra; 00398 int cfra; 00399 00400 /* sanity check */ 00401 if (ELEM(NULL, targets, targets->first)) 00402 return; 00403 00404 /* set frame values */ 00405 cfra = CFRA; 00406 sfra = efra = cfra; 00407 00408 // TODO: this method could be improved... 00409 // 1) max range for standard baking 00410 // 2) minimum range for recalc baking (i.e. between keyframes, but how?) 00411 for (mpt= targets->first; mpt; mpt= mpt->next) { 00412 /* try to increase area to do (only as much as needed) */ 00413 sfra= MIN2(sfra, mpt->mpath->start_frame); 00414 efra= MAX2(efra, mpt->mpath->end_frame); 00415 } 00416 if (efra <= sfra) return; 00417 00418 /* optimise the depsgraph for faster updates */ 00419 // TODO: whether this is used should depend on some setting for the level of optimisations used 00420 motionpaths_calc_optimise_depsgraph(scene, targets); 00421 00422 /* calculate path over requested range */ 00423 for (CFRA=sfra; CFRA<=efra; CFRA++) { 00424 /* update relevant data for new frame */ 00425 motionpaths_calc_update_scene(scene); 00426 00427 /* perform baking for targets */ 00428 motionpaths_calc_bake_targets(scene, targets); 00429 } 00430 00431 /* reset original environment */ 00432 CFRA= cfra; 00433 motionpaths_calc_update_scene(scene); 00434 00435 /* clear recalc flags from targets */ 00436 for (mpt= targets->first; mpt; mpt= mpt->next) { 00437 bAnimVizSettings *avs; 00438 00439 /* get pointer to animviz settings for each target */ 00440 if (mpt->pchan) 00441 avs= &mpt->ob->pose->avs; 00442 else 00443 avs= &mpt->ob->avs; 00444 00445 /* clear the flag requesting recalculation of targets */ 00446 avs->recalc &= ~ANIMVIZ_RECALC_PATHS; 00447 } 00448 } 00449 00450 /* ******************************************************************** */ 00451 /* Curve Paths - for curve deforms and/or curve following */ 00452 00453 /* free curve path data 00454 * NOTE: frees the path itself! 00455 * NOTE: this is increasingly innacurate with non-uniform BevPoint subdivisions [#24633] 00456 */ 00457 void free_path(Path *path) 00458 { 00459 if(path->data) MEM_freeN(path->data); 00460 MEM_freeN(path); 00461 } 00462 00463 /* calculate a curve-deform path for a curve 00464 * - only called from displist.c -> do_makeDispListCurveTypes 00465 */ 00466 void calc_curvepath(Object *ob) 00467 { 00468 BevList *bl; 00469 BevPoint *bevp, *bevpn, *bevpfirst, *bevplast; 00470 PathPoint *pp; 00471 Curve *cu; 00472 Nurb *nu; 00473 Path *path; 00474 float *fp, *dist, *maxdist, xyz[3]; 00475 float fac, d=0, fac1, fac2; 00476 int a, tot, cycl=0; 00477 ListBase *nurbs; 00478 00479 /* in a path vertices are with equal differences: path->len = number of verts */ 00480 /* NOW WITH BEVELCURVE!!! */ 00481 00482 if(ob==NULL || ob->type != OB_CURVE) return; 00483 cu= ob->data; 00484 00485 nurbs= BKE_curve_nurbs(cu); 00486 nu= nurbs->first; 00487 00488 if(cu->path) free_path(cu->path); 00489 cu->path= NULL; 00490 00491 bl= cu->bev.first; 00492 if(bl==NULL || !bl->nr) return; 00493 00494 cu->path=path= MEM_callocN(sizeof(Path), "calc_curvepath"); 00495 00496 /* if POLY: last vertice != first vertice */ 00497 cycl= (bl->poly!= -1); 00498 00499 if(cycl) tot= bl->nr; 00500 else tot= bl->nr-1; 00501 00502 path->len= tot+1; 00503 /* exception: vector handle paths and polygon paths should be subdivided at least a factor resolu */ 00504 if(path->len<nu->resolu*SEGMENTSU(nu)) path->len= nu->resolu*SEGMENTSU(nu); 00505 00506 dist= (float *)MEM_mallocN((tot+1)*4, "calcpathdist"); 00507 00508 /* all lengths in *dist */ 00509 bevp= bevpfirst= (BevPoint *)(bl+1); 00510 fp= dist; 00511 *fp= 0; 00512 for(a=0; a<tot; a++) { 00513 fp++; 00514 if(cycl && a==tot-1) 00515 sub_v3_v3v3(xyz, bevpfirst->vec, bevp->vec); 00516 else 00517 sub_v3_v3v3(xyz, (bevp+1)->vec, bevp->vec); 00518 00519 *fp= *(fp-1)+len_v3(xyz); 00520 bevp++; 00521 } 00522 00523 path->totdist= *fp; 00524 00525 /* the path verts in path->data */ 00526 /* now also with TILT value */ 00527 pp= path->data = (PathPoint *)MEM_callocN(sizeof(PathPoint)*path->len, "pathdata"); 00528 00529 bevp= bevpfirst; 00530 bevpn= bevp+1; 00531 bevplast= bevpfirst + (bl->nr-1); 00532 fp= dist+1; 00533 maxdist= dist+tot; 00534 fac= 1.0f/((float)path->len-1.0f); 00535 fac = fac * path->totdist; 00536 00537 for(a=0; a<path->len; a++) { 00538 00539 d= ((float)a)*fac; 00540 00541 /* we're looking for location (distance) 'd' in the array */ 00542 while((d>= *fp) && fp<maxdist) { 00543 fp++; 00544 if(bevp<bevplast) bevp++; 00545 bevpn= bevp+1; 00546 if(bevpn>bevplast) { 00547 if(cycl) bevpn= bevpfirst; 00548 else bevpn= bevplast; 00549 } 00550 } 00551 00552 fac1= *(fp)- *(fp-1); 00553 fac2= *(fp)-d; 00554 fac1= fac2/fac1; 00555 fac2= 1.0f-fac1; 00556 00557 interp_v3_v3v3(pp->vec, bevp->vec, bevpn->vec, fac2); 00558 pp->vec[3]= fac1*bevp->alfa + fac2*bevpn->alfa; 00559 pp->radius= fac1*bevp->radius + fac2*bevpn->radius; 00560 pp->weight= fac1*bevp->weight + fac2*bevpn->weight; 00561 interp_qt_qtqt(pp->quat, bevp->quat, bevpn->quat, fac2); 00562 normalize_qt(pp->quat); 00563 00564 pp++; 00565 } 00566 00567 MEM_freeN(dist); 00568 } 00569 00570 00571 /* is this only used internally?*/ 00572 int interval_test(int min, int max, int p1, int cycl) 00573 { 00574 if(cycl) { 00575 if(p1 < min) 00576 p1= ((p1 -min) % (max-min+1)) + max+1; 00577 else if(p1 > max) 00578 p1= ((p1 -min) % (max-min+1)) + min; 00579 } 00580 else { 00581 if(p1 < min) p1= min; 00582 else if(p1 > max) p1= max; 00583 } 00584 return p1; 00585 } 00586 00587 00588 /* calculate the deformation implied by the curve path at a given parametric position, and returns whether this operation succeeded 00589 * - *vec needs FOUR items! 00590 * - ctime is normalized range <0-1> 00591 */ 00592 int where_on_path(Object *ob, float ctime, float *vec, float *dir, float *quat, float *radius, float *weight) /* returns OK */ 00593 { 00594 Curve *cu; 00595 Nurb *nu; 00596 BevList *bl; 00597 Path *path; 00598 PathPoint *pp, *p0, *p1, *p2, *p3; 00599 float fac; 00600 float data[4]; 00601 int cycl=0, s0, s1, s2, s3; 00602 00603 if(ob==NULL || ob->type != OB_CURVE) return 0; 00604 cu= ob->data; 00605 if(cu->path==NULL || cu->path->data==NULL) { 00606 printf("no path!\n"); 00607 return 0; 00608 } 00609 path= cu->path; 00610 pp= path->data; 00611 00612 /* test for cyclic */ 00613 bl= cu->bev.first; 00614 if (!bl) return 0; 00615 if (!bl->nr) return 0; 00616 if(bl->poly> -1) cycl= 1; 00617 00618 ctime *= (path->len-1); 00619 00620 s1= (int)floor(ctime); 00621 fac= (float)(s1+1)-ctime; 00622 00623 /* path->len is corected for cyclic */ 00624 s0= interval_test(0, path->len-1-cycl, s1-1, cycl); 00625 s1= interval_test(0, path->len-1-cycl, s1, cycl); 00626 s2= interval_test(0, path->len-1-cycl, s1+1, cycl); 00627 s3= interval_test(0, path->len-1-cycl, s1+2, cycl); 00628 00629 p0= pp + s0; 00630 p1= pp + s1; 00631 p2= pp + s2; 00632 p3= pp + s3; 00633 00634 /* note, commented out for follow constraint */ 00635 //if(cu->flag & CU_FOLLOW) { 00636 00637 key_curve_tangent_weights(1.0f-fac, data, KEY_BSPLINE); 00638 00639 interp_v3_v3v3v3v3(dir, p0->vec, p1->vec, p2->vec, p3->vec, data); 00640 00641 /* make compatible with vectoquat */ 00642 negate_v3(dir); 00643 //} 00644 00645 nu= cu->nurb.first; 00646 00647 /* make sure that first and last frame are included in the vectors here */ 00648 if(nu->type == CU_POLY) key_curve_position_weights(1.0f-fac, data, KEY_LINEAR); 00649 else if(nu->type == CU_BEZIER) key_curve_position_weights(1.0f-fac, data, KEY_LINEAR); 00650 else if(s0==s1 || p2==p3) key_curve_position_weights(1.0f-fac, data, KEY_CARDINAL); 00651 else key_curve_position_weights(1.0f-fac, data, KEY_BSPLINE); 00652 00653 vec[0]= data[0]*p0->vec[0] + data[1]*p1->vec[0] + data[2]*p2->vec[0] + data[3]*p3->vec[0] ; /* X */ 00654 vec[1]= data[0]*p0->vec[1] + data[1]*p1->vec[1] + data[2]*p2->vec[1] + data[3]*p3->vec[1] ; /* Y */ 00655 vec[2]= data[0]*p0->vec[2] + data[1]*p1->vec[2] + data[2]*p2->vec[2] + data[3]*p3->vec[2] ; /* Z */ 00656 vec[3]= data[0]*p0->vec[3] + data[1]*p1->vec[3] + data[2]*p2->vec[3] + data[3]*p3->vec[3] ; /* Tilt, should not be needed since we have quat still used */ 00657 00658 if (quat) { 00659 float totfac, q1[4], q2[4]; 00660 00661 totfac= data[0]+data[3]; 00662 if(totfac>FLT_EPSILON) interp_qt_qtqt(q1, p0->quat, p3->quat, data[3] / totfac); 00663 else copy_qt_qt(q1, p1->quat); 00664 00665 totfac= data[1]+data[2]; 00666 if(totfac>FLT_EPSILON) interp_qt_qtqt(q2, p1->quat, p2->quat, data[2] / totfac); 00667 else copy_qt_qt(q2, p3->quat); 00668 00669 totfac = data[0]+data[1]+data[2]+data[3]; 00670 if(totfac>FLT_EPSILON) interp_qt_qtqt(quat, q1, q2, (data[1]+data[2]) / totfac); 00671 else copy_qt_qt(quat, q2); 00672 } 00673 00674 if(radius) 00675 *radius= data[0]*p0->radius + data[1]*p1->radius + data[2]*p2->radius + data[3]*p3->radius; 00676 00677 if(weight) 00678 *weight= data[0]*p0->weight + data[1]*p1->weight + data[2]*p2->weight + data[3]*p3->weight; 00679 00680 return 1; 00681 } 00682 00683 /* ******************************************************************** */ 00684 /* Dupli-Geometry */ 00685 00686 static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], int lay, int index, int type, int animated) 00687 { 00688 DupliObject *dob= MEM_callocN(sizeof(DupliObject), "dupliobject"); 00689 00690 BLI_addtail(lb, dob); 00691 dob->ob= ob; 00692 copy_m4_m4(dob->mat, mat); 00693 copy_m4_m4(dob->omat, ob->obmat); 00694 dob->origlay= ob->lay; 00695 dob->index= index; 00696 dob->type= type; 00697 dob->animated= (type == OB_DUPLIGROUP) && animated; 00698 ob->lay= lay; 00699 00700 return dob; 00701 } 00702 00703 static void group_duplilist(ListBase *lb, Scene *scene, Object *ob, int level, int animated) 00704 { 00705 DupliObject *dob; 00706 Group *group; 00707 GroupObject *go; 00708 float mat[4][4], tmat[4][4]; 00709 00710 if(ob->dup_group==NULL) return; 00711 group= ob->dup_group; 00712 00713 /* simple preventing of too deep nested groups */ 00714 if(level>MAX_DUPLI_RECUR) return; 00715 00716 /* handles animated groups, and */ 00717 /* we need to check update for objects that are not in scene... */ 00718 group_handle_recalc_and_update(scene, ob, group); 00719 animated= animated || group_is_animated(ob, group); 00720 00721 for(go= group->gobject.first; go; go= go->next) { 00722 /* note, if you check on layer here, render goes wrong... it still deforms verts and uses parent imat */ 00723 if(go->ob!=ob) { 00724 00725 /* group dupli offset, should apply after everything else */ 00726 if(!is_zero_v3(group->dupli_ofs)) { 00727 copy_m4_m4(tmat, go->ob->obmat); 00728 sub_v3_v3v3(tmat[3], tmat[3], group->dupli_ofs); 00729 mult_m4_m4m4(mat, ob->obmat, tmat); 00730 } 00731 else { 00732 mult_m4_m4m4(mat, ob->obmat, go->ob->obmat); 00733 } 00734 00735 dob= new_dupli_object(lb, go->ob, mat, ob->lay, 0, OB_DUPLIGROUP, animated); 00736 00737 /* check the group instance and object layers match, also that the object visible flags are ok. */ 00738 if( (dob->origlay & group->layer)==0 || 00739 (G.rendering==0 && dob->ob->restrictflag & OB_RESTRICT_VIEW) || 00740 (G.rendering && dob->ob->restrictflag & OB_RESTRICT_RENDER) 00741 ) { 00742 dob->no_draw= 1; 00743 } 00744 else { 00745 dob->no_draw= 0; 00746 } 00747 00748 if(go->ob->transflag & OB_DUPLI) { 00749 copy_m4_m4(dob->ob->obmat, dob->mat); 00750 object_duplilist_recursive(&group->id, scene, go->ob, lb, ob->obmat, level+1, animated); 00751 copy_m4_m4(dob->ob->obmat, dob->omat); 00752 } 00753 } 00754 } 00755 } 00756 00757 static void frames_duplilist(ListBase *lb, Scene *scene, Object *ob, int level, int animated) 00758 { 00759 extern int enable_cu_speed; /* object.c */ 00760 Object copyob; 00761 int cfrao = scene->r.cfra; 00762 int dupend = ob->dupend; 00763 00764 /* simple prevention of too deep nested groups */ 00765 if (level > MAX_DUPLI_RECUR) return; 00766 00767 /* if we don't have any data/settings which will lead to object movement, 00768 * don't waste time trying, as it will all look the same... 00769 */ 00770 if (ob->parent==NULL && ob->constraints.first==NULL && ob->adt==NULL) 00771 return; 00772 00773 /* make a copy of the object's original data (before any dupli-data overwrites it) 00774 * as we'll need this to keep track of unkeyed data 00775 * - this doesn't take into account other data that can be reached from the object, 00776 * for example it's shapekeys or bones, hence the need for an update flush at the end 00777 */ 00778 copyob = *ob; 00779 00780 /* duplicate over the required range */ 00781 if (ob->transflag & OB_DUPLINOSPEED) enable_cu_speed= 0; 00782 00783 for (scene->r.cfra= ob->dupsta; scene->r.cfra<=dupend; scene->r.cfra++) { 00784 short ok= 1; 00785 00786 /* - dupoff = how often a frames within the range shouldn't be made into duplis 00787 * - dupon = the length of each "skipping" block in frames 00788 */ 00789 if (ob->dupoff) { 00790 ok= scene->r.cfra - ob->dupsta; 00791 ok= ok % (ob->dupon+ob->dupoff); 00792 ok= (ok < ob->dupon); 00793 } 00794 00795 if (ok) { 00796 DupliObject *dob; 00797 00798 /* WARNING: doing animation updates in this way is not terribly accurate, as the dependencies 00799 * and/or other objects which may affect this object's transforms are not updated either. 00800 * However, this has always been the way that this worked (i.e. pre 2.5), so I guess that it'll be fine! 00801 */ 00802 BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, (float)scene->r.cfra, ADT_RECALC_ANIM); /* ob-eval will do drivers, so we don't need to do them */ 00803 where_is_object_time(scene, ob, (float)scene->r.cfra); 00804 00805 dob= new_dupli_object(lb, ob, ob->obmat, ob->lay, scene->r.cfra, OB_DUPLIFRAMES, animated); 00806 copy_m4_m4(dob->omat, copyob.obmat); 00807 } 00808 } 00809 00810 enable_cu_speed= 1; 00811 00812 /* reset frame to original frame, then re-evaluate animation as above 00813 * as 2.5 animation data may have far-reaching consequences 00814 */ 00815 scene->r.cfra= cfrao; 00816 00817 BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, (float)scene->r.cfra, ADT_RECALC_ANIM); /* ob-eval will do drivers, so we don't need to do them */ 00818 where_is_object_time(scene, ob, (float)scene->r.cfra); 00819 00820 /* but, to make sure unkeyed object transforms are still sane, 00821 * let's copy object's original data back over 00822 */ 00823 *ob = copyob; 00824 } 00825 00826 typedef struct vertexDupliData { 00827 ID *id; /* scene or group, for recursive loops */ 00828 int level; 00829 int animated; 00830 ListBase *lb; 00831 float pmat[4][4]; 00832 float obmat[4][4]; /* Only used for dupliverts inside dupligroups, where the ob->obmat is modified */ 00833 Scene *scene; 00834 Object *ob, *par; 00835 float (*orco)[3]; 00836 } vertexDupliData; 00837 00838 /* ------------- */ 00839 00840 static void vertex_dupli__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s) 00841 { 00842 DupliObject *dob; 00843 vertexDupliData *vdd= userData; 00844 float vec[3], q2[4], mat[3][3], tmat[4][4], obmat[4][4]; 00845 int origlay; 00846 00847 mul_v3_m4v3(vec, vdd->pmat, co); 00848 sub_v3_v3(vec, vdd->pmat[3]); 00849 add_v3_v3(vec, vdd->obmat[3]); 00850 00851 copy_m4_m4(obmat, vdd->obmat); 00852 copy_v3_v3(obmat[3], vec); 00853 00854 if(vdd->par->transflag & OB_DUPLIROT) { 00855 if(no_f) { 00856 vec[0]= -no_f[0]; vec[1]= -no_f[1]; vec[2]= -no_f[2]; 00857 } 00858 else if(no_s) { 00859 vec[0]= -no_s[0]; vec[1]= -no_s[1]; vec[2]= -no_s[2]; 00860 } 00861 00862 vec_to_quat( q2,vec, vdd->ob->trackflag, vdd->ob->upflag); 00863 00864 quat_to_mat3( mat,q2); 00865 copy_m4_m4(tmat, obmat); 00866 mul_m4_m4m3(obmat, tmat, mat); 00867 } 00868 00869 origlay = vdd->ob->lay; 00870 00871 dob= new_dupli_object(vdd->lb, vdd->ob, obmat, vdd->par->lay, index, OB_DUPLIVERTS, vdd->animated); 00872 00873 /* restore the original layer so that each dupli will have proper dob->origlay */ 00874 vdd->ob->lay = origlay; 00875 00876 if(vdd->orco) 00877 copy_v3_v3(dob->orco, vdd->orco[index]); 00878 00879 if(vdd->ob->transflag & OB_DUPLI) { 00880 float tmpmat[4][4]; 00881 copy_m4_m4(tmpmat, vdd->ob->obmat); 00882 copy_m4_m4(vdd->ob->obmat, obmat); /* pretend we are really this mat */ 00883 object_duplilist_recursive((ID *)vdd->id, vdd->scene, vdd->ob, vdd->lb, obmat, vdd->level+1, vdd->animated); 00884 copy_m4_m4(vdd->ob->obmat, tmpmat); 00885 } 00886 } 00887 00888 static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int level, int animated) 00889 { 00890 Object *ob, *ob_iter; 00891 Mesh *me= par->data; 00892 Base *base = NULL; 00893 DerivedMesh *dm; 00894 vertexDupliData vdd; 00895 Scene *sce = NULL; 00896 Group *group = NULL; 00897 GroupObject * go = NULL; 00898 EditMesh *em; 00899 float vec[3], no[3], pmat[4][4]; 00900 int totvert, a, oblay; 00901 unsigned int lay; 00902 00903 copy_m4_m4(pmat, par->obmat); 00904 00905 /* simple preventing of too deep nested groups */ 00906 if(level>MAX_DUPLI_RECUR) return; 00907 00908 em = BKE_mesh_get_editmesh(me); 00909 00910 if(em) { 00911 dm= editmesh_get_derived_cage(scene, par, em, CD_MASK_BAREMESH); 00912 BKE_mesh_end_editmesh(me, em); 00913 } else 00914 dm= mesh_get_derived_deform(scene, par, CD_MASK_BAREMESH); 00915 00916 if(G.rendering) { 00917 vdd.orco= (float(*)[3])get_mesh_orco_verts(par); 00918 transform_mesh_orco_verts(me, vdd.orco, me->totvert, 0); 00919 } 00920 else 00921 vdd.orco= NULL; 00922 00923 totvert = dm->getNumVerts(dm); 00924 00925 /* having to loop on scene OR group objects is NOT FUN */ 00926 if (GS(id->name) == ID_SCE) { 00927 sce = (Scene *)id; 00928 lay= sce->lay; 00929 base= sce->base.first; 00930 } else { 00931 group = (Group *)id; 00932 lay= group->layer; 00933 go = group->gobject.first; 00934 } 00935 00936 /* Start looping on Scene OR Group objects */ 00937 while (base || go) { 00938 if (sce) { 00939 ob_iter= base->object; 00940 oblay = base->lay; 00941 } else { 00942 ob_iter= go->ob; 00943 oblay = ob_iter->lay; 00944 } 00945 00946 if (lay & oblay && scene->obedit!=ob_iter) { 00947 ob=ob_iter->parent; 00948 while(ob) { 00949 if(ob==par) { 00950 ob = ob_iter; 00951 /* End Scene/Group object loop, below is generic */ 00952 00953 00954 /* par_space_mat - only used for groups so we can modify the space dupli's are in 00955 when par_space_mat is NULL ob->obmat can be used instead of ob__obmat 00956 */ 00957 if(par_space_mat) 00958 mult_m4_m4m4(vdd.obmat, par_space_mat, ob->obmat); 00959 else 00960 copy_m4_m4(vdd.obmat, ob->obmat); 00961 00962 vdd.id= id; 00963 vdd.level= level; 00964 vdd.animated= animated; 00965 vdd.lb= lb; 00966 vdd.ob= ob; 00967 vdd.scene= scene; 00968 vdd.par= par; 00969 copy_m4_m4(vdd.pmat, pmat); 00970 00971 /* mballs have a different dupli handling */ 00972 if(ob->type!=OB_MBALL) ob->flag |= OB_DONE; /* doesnt render */ 00973 00974 if(me->edit_mesh) { 00975 dm->foreachMappedVert(dm, vertex_dupli__mapFunc, (void*) &vdd); 00976 } 00977 else { 00978 for(a=0; a<totvert; a++) { 00979 dm->getVertCo(dm, a, vec); 00980 dm->getVertNo(dm, a, no); 00981 00982 vertex_dupli__mapFunc(&vdd, a, vec, no, NULL); 00983 } 00984 } 00985 if(sce) { 00986 /* Set proper layer in case of scene looping, 00987 * in case of groups the object layer will be 00988 * changed when it's duplicated due to the 00989 * group duplication. 00990 */ 00991 ob->lay = vdd.par->lay; 00992 } 00993 00994 break; 00995 } 00996 ob= ob->parent; 00997 } 00998 } 00999 if (sce) base= base->next; /* scene loop */ 01000 else go= go->next; /* group loop */ 01001 } 01002 01003 if(vdd.orco) 01004 MEM_freeN(vdd.orco); 01005 dm->release(dm); 01006 } 01007 01008 static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int level, int animated) 01009 { 01010 Object *ob, *ob_iter; 01011 Base *base = NULL; 01012 DupliObject *dob; 01013 DerivedMesh *dm; 01014 Mesh *me= par->data; 01015 MTFace *mtface; 01016 MFace *mface; 01017 MVert *mvert; 01018 float pmat[4][4], imat[3][3], (*orco)[3] = NULL, w; 01019 int lay, oblay, totface, a; 01020 Scene *sce = NULL; 01021 Group *group = NULL; 01022 GroupObject *go = NULL; 01023 EditMesh *em; 01024 float ob__obmat[4][4]; /* needed for groups where the object matrix needs to be modified */ 01025 01026 /* simple preventing of too deep nested groups */ 01027 if(level>MAX_DUPLI_RECUR) return; 01028 01029 copy_m4_m4(pmat, par->obmat); 01030 01031 em = BKE_mesh_get_editmesh(me); 01032 if(em) { 01033 dm= editmesh_get_derived_cage(scene, par, em, CD_MASK_BAREMESH); 01034 BKE_mesh_end_editmesh(me, em); 01035 } 01036 else { 01037 dm = mesh_get_derived_deform(scene, par, CD_MASK_BAREMESH); 01038 } 01039 01040 totface= dm->getNumFaces(dm); 01041 mface= dm->getFaceArray(dm); 01042 mvert= dm->getVertArray(dm); 01043 01044 if(G.rendering) { 01045 01046 orco= (float(*)[3])get_mesh_orco_verts(par); 01047 transform_mesh_orco_verts(me, orco, me->totvert, 0); 01048 mtface= me->mtface; 01049 } 01050 else { 01051 orco= NULL; 01052 mtface= NULL; 01053 } 01054 01055 /* having to loop on scene OR group objects is NOT FUN */ 01056 if (GS(id->name) == ID_SCE) { 01057 sce = (Scene *)id; 01058 lay= sce->lay; 01059 base= sce->base.first; 01060 } else { 01061 group = (Group *)id; 01062 lay= group->layer; 01063 go = group->gobject.first; 01064 } 01065 01066 /* Start looping on Scene OR Group objects */ 01067 while (base || go) { 01068 if (sce) { 01069 ob_iter= base->object; 01070 oblay = base->lay; 01071 } else { 01072 ob_iter= go->ob; 01073 oblay = ob_iter->lay; 01074 } 01075 01076 if (lay & oblay && scene->obedit!=ob_iter) { 01077 ob=ob_iter->parent; 01078 while(ob) { 01079 if(ob==par) { 01080 ob = ob_iter; 01081 /* End Scene/Group object loop, below is generic */ 01082 01083 /* par_space_mat - only used for groups so we can modify the space dupli's are in 01084 when par_space_mat is NULL ob->obmat can be used instead of ob__obmat 01085 */ 01086 if(par_space_mat) 01087 mult_m4_m4m4(ob__obmat, par_space_mat, ob->obmat); 01088 else 01089 copy_m4_m4(ob__obmat, ob->obmat); 01090 01091 copy_m3_m4(imat, ob->parentinv); 01092 01093 /* mballs have a different dupli handling */ 01094 if(ob->type!=OB_MBALL) ob->flag |= OB_DONE; /* doesnt render */ 01095 01096 for(a=0; a<totface; a++) { 01097 int mv1 = mface[a].v1; 01098 int mv2 = mface[a].v2; 01099 int mv3 = mface[a].v3; 01100 int mv4 = mface[a].v4; 01101 float *v1= mvert[mv1].co; 01102 float *v2= mvert[mv2].co; 01103 float *v3= mvert[mv3].co; 01104 float *v4= (mv4)? mvert[mv4].co: NULL; 01105 float cent[3], quat[4], mat[3][3], mat3[3][3], tmat[4][4], obmat[4][4]; 01106 01107 /* translation */ 01108 if(v4) 01109 cent_quad_v3(cent, v1, v2, v3, v4); 01110 else 01111 cent_tri_v3(cent, v1, v2, v3); 01112 mul_m4_v3(pmat, cent); 01113 01114 sub_v3_v3v3(cent, cent, pmat[3]); 01115 add_v3_v3(cent, ob__obmat[3]); 01116 01117 copy_m4_m4(obmat, ob__obmat); 01118 01119 copy_v3_v3(obmat[3], cent); 01120 01121 /* rotation */ 01122 tri_to_quat( quat,v1, v2, v3); 01123 quat_to_mat3( mat,quat); 01124 01125 /* scale */ 01126 if(par->transflag & OB_DUPLIFACES_SCALE) { 01127 float size= v4? area_quad_v3(v1, v2, v3, v4): area_tri_v3(v1, v2, v3); 01128 size= sqrtf(size) * par->dupfacesca; 01129 mul_m3_fl(mat, size); 01130 } 01131 01132 copy_m3_m3(mat3, mat); 01133 mul_m3_m3m3(mat, imat, mat3); 01134 01135 copy_m4_m4(tmat, obmat); 01136 mul_m4_m4m3(obmat, tmat, mat); 01137 01138 dob= new_dupli_object(lb, ob, obmat, par->lay, a, OB_DUPLIFACES, animated); 01139 if(G.rendering) { 01140 w= (mv4)? 0.25f: 1.0f/3.0f; 01141 01142 if(orco) { 01143 madd_v3_v3v3fl(dob->orco, dob->orco, orco[mv1], w); 01144 madd_v3_v3v3fl(dob->orco, dob->orco, orco[mv2], w); 01145 madd_v3_v3v3fl(dob->orco, dob->orco, orco[mv3], w); 01146 if (mv4) { 01147 madd_v3_v3v3fl(dob->orco, dob->orco, orco[mv4], w); 01148 } 01149 } 01150 01151 if(mtface) { 01152 madd_v2_v2v2fl(dob->uv, dob->uv, mtface[a].uv[0], w); 01153 madd_v2_v2v2fl(dob->uv, dob->uv, mtface[a].uv[1], w); 01154 madd_v2_v2v2fl(dob->uv, dob->uv, mtface[a].uv[2], w); 01155 if (mv4) { 01156 madd_v2_v2v2fl(dob->uv, dob->uv, mtface[a].uv[3], w); 01157 } 01158 } 01159 } 01160 01161 if(ob->transflag & OB_DUPLI) { 01162 float tmpmat[4][4]; 01163 copy_m4_m4(tmpmat, ob->obmat); 01164 copy_m4_m4(ob->obmat, obmat); /* pretend we are really this mat */ 01165 object_duplilist_recursive((ID *)id, scene, ob, lb, ob->obmat, level+1, animated); 01166 copy_m4_m4(ob->obmat, tmpmat); 01167 } 01168 } 01169 01170 break; 01171 } 01172 ob= ob->parent; 01173 } 01174 } 01175 if (sce) base= base->next; /* scene loop */ 01176 else go= go->next; /* group loop */ 01177 } 01178 01179 if(orco) 01180 MEM_freeN(orco); 01181 01182 dm->release(dm); 01183 } 01184 01185 static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], ParticleSystem *psys, int level, int animated) 01186 { 01187 GroupObject *go; 01188 Object *ob=NULL, **oblist=NULL, obcopy, *obcopylist=NULL; 01189 DupliObject *dob; 01190 ParticleDupliWeight *dw; 01191 ParticleSettings *part; 01192 ParticleData *pa; 01193 ChildParticle *cpa=NULL; 01194 ParticleKey state; 01195 ParticleCacheKey *cache; 01196 float ctime, pa_time, scale = 1.0f; 01197 float tmat[4][4], mat[4][4], pamat[4][4], vec[3], size=0.0; 01198 float (*obmat)[4], (*oldobmat)[4]; 01199 int a, b, counter, hair = 0; 01200 int totpart, totchild, totgroup=0 /*, pa_num */; 01201 01202 int no_draw_flag = PARS_UNEXIST; 01203 01204 if(psys==NULL) return; 01205 01206 /* simple preventing of too deep nested groups */ 01207 if(level>MAX_DUPLI_RECUR) return; 01208 01209 part=psys->part; 01210 01211 if(part==NULL) 01212 return; 01213 01214 if(!psys_check_enabled(par, psys)) 01215 return; 01216 01217 if(G.rendering == 0) 01218 no_draw_flag |= PARS_NO_DISP; 01219 01220 ctime = BKE_curframe(scene); /* NOTE: in old animsys, used parent object's timeoffset... */ 01221 01222 totpart = psys->totpart; 01223 totchild = psys->totchild; 01224 01225 BLI_srandom(31415926 + psys->seed); 01226 01227 if((psys->renderdata || part->draw_as==PART_DRAW_REND) && ELEM(part->ren_as, PART_DRAW_OB, PART_DRAW_GR)) { 01228 ParticleSimulationData sim= {NULL}; 01229 sim.scene= scene; 01230 sim.ob= par; 01231 sim.psys= psys; 01232 sim.psmd= psys_get_modifier(par, psys); 01233 /* make sure emitter imat is in global coordinates instead of render view coordinates */ 01234 invert_m4_m4(par->imat, par->obmat); 01235 01236 /* first check for loops (particle system object used as dupli object) */ 01237 if(part->ren_as == PART_DRAW_OB) { 01238 if(ELEM(part->dup_ob, NULL, par)) 01239 return; 01240 } 01241 else { /*PART_DRAW_GR */ 01242 if(part->dup_group == NULL || part->dup_group->gobject.first == NULL) 01243 return; 01244 01245 for(go=part->dup_group->gobject.first; go; go=go->next) 01246 if(go->ob == par) 01247 return; 01248 } 01249 01250 /* if we have a hair particle system, use the path cache */ 01251 if(part->type == PART_HAIR) { 01252 if(psys->flag & PSYS_HAIR_DONE) 01253 hair= (totchild == 0 || psys->childcache) && psys->pathcache; 01254 if(!hair) 01255 return; 01256 01257 /* we use cache, update totchild according to cached data */ 01258 totchild = psys->totchildcache; 01259 totpart = psys->totcached; 01260 } 01261 01262 psys_check_group_weights(part); 01263 01264 psys->lattice = psys_get_lattice(&sim); 01265 01266 /* gather list of objects or single object */ 01267 if(part->ren_as==PART_DRAW_GR) { 01268 group_handle_recalc_and_update(scene, par, part->dup_group); 01269 01270 if(part->draw & PART_DRAW_COUNT_GR) { 01271 for(dw=part->dupliweights.first; dw; dw=dw->next) 01272 totgroup += dw->count; 01273 } 01274 else { 01275 for(go=part->dup_group->gobject.first; go; go=go->next) 01276 totgroup++; 01277 } 01278 01279 /* we also copy the actual objects to restore afterwards, since 01280 * where_is_object_time will change the object which breaks transform */ 01281 oblist = MEM_callocN(totgroup*sizeof(Object *), "dupgroup object list"); 01282 obcopylist = MEM_callocN(totgroup*sizeof(Object), "dupgroup copy list"); 01283 01284 01285 if(part->draw & PART_DRAW_COUNT_GR && totgroup) { 01286 dw = part->dupliweights.first; 01287 01288 for(a=0; a<totgroup; dw=dw->next) { 01289 for(b=0; b<dw->count; b++, a++) { 01290 oblist[a] = dw->ob; 01291 obcopylist[a] = *dw->ob; 01292 } 01293 } 01294 } 01295 else { 01296 go = part->dup_group->gobject.first; 01297 for(a=0; a<totgroup; a++, go=go->next) { 01298 oblist[a] = go->ob; 01299 obcopylist[a] = *go->ob; 01300 } 01301 } 01302 } 01303 else { 01304 ob = part->dup_ob; 01305 obcopy = *ob; 01306 } 01307 01308 if(totchild==0 || part->draw & PART_DRAW_PARENT) 01309 a = 0; 01310 else 01311 a = totpart; 01312 01313 for(pa=psys->particles,counter=0; a<totpart+totchild; a++,pa++,counter++) { 01314 if(a<totpart) { 01315 /* handle parent particle */ 01316 if(pa->flag & no_draw_flag) 01317 continue; 01318 01319 /* pa_num = pa->num; */ /* UNUSED */ 01320 pa_time = pa->time; 01321 size = pa->size; 01322 } 01323 else { 01324 /* handle child particle */ 01325 cpa = &psys->child[a - totpart]; 01326 01327 /* pa_num = a; */ /* UNUSED */ 01328 pa_time = psys->particles[cpa->parent].time; 01329 size = psys_get_child_size(psys, cpa, ctime, NULL); 01330 } 01331 01332 /* some hair paths might be non-existent so they can't be used for duplication */ 01333 if(hair && 01334 ((a < totpart && psys->pathcache[a]->steps < 0) || 01335 (a >= totpart && psys->childcache[a-totpart]->steps < 0))) 01336 continue; 01337 01338 if(part->ren_as==PART_DRAW_GR) { 01339 /* prevent divide by zero below [#28336] */ 01340 if(totgroup == 0) 01341 continue; 01342 01343 /* for groups, pick the object based on settings */ 01344 if(part->draw&PART_DRAW_RAND_GR) 01345 b= BLI_rand() % totgroup; 01346 else 01347 b= a % totgroup; 01348 01349 ob = oblist[b]; 01350 obmat = oblist[b]->obmat; 01351 oldobmat = obcopylist[b].obmat; 01352 } 01353 else { 01354 obmat= ob->obmat; 01355 oldobmat= obcopy.obmat; 01356 } 01357 01358 if(hair) { 01359 /* hair we handle separate and compute transform based on hair keys */ 01360 if(a < totpart) { 01361 cache = psys->pathcache[a]; 01362 psys_get_dupli_path_transform(&sim, pa, NULL, cache, pamat, &scale); 01363 } 01364 else { 01365 cache = psys->childcache[a-totpart]; 01366 psys_get_dupli_path_transform(&sim, NULL, cpa, cache, pamat, &scale); 01367 } 01368 01369 copy_v3_v3(pamat[3], cache->co); 01370 pamat[3][3]= 1.0f; 01371 01372 } 01373 else { 01374 /* first key */ 01375 state.time = ctime; 01376 if(psys_get_particle_state(&sim, a, &state, 0) == 0) { 01377 continue; 01378 } 01379 else { 01380 float tquat[4]; 01381 normalize_qt_qt(tquat, state.rot); 01382 quat_to_mat4(pamat, tquat); 01383 copy_v3_v3(pamat[3], state.co); 01384 pamat[3][3]= 1.0f; 01385 } 01386 } 01387 01388 if(part->ren_as==PART_DRAW_GR && psys->part->draw & PART_DRAW_WHOLE_GR) { 01389 for(go= part->dup_group->gobject.first, b=0; go; go= go->next, b++) { 01390 01391 /* group dupli offset, should apply after everything else */ 01392 if(!is_zero_v3(part->dup_group->dupli_ofs)) { 01393 copy_m4_m4(tmat, oblist[b]->obmat); 01394 sub_v3_v3v3(tmat[3], tmat[3], part->dup_group->dupli_ofs); 01395 mult_m4_m4m4(tmat, pamat, tmat); 01396 } 01397 else { 01398 mult_m4_m4m4(tmat, pamat, oblist[b]->obmat); 01399 } 01400 01401 mul_mat3_m4_fl(tmat, size*scale); 01402 if(par_space_mat) 01403 mult_m4_m4m4(mat, par_space_mat, tmat); 01404 else 01405 copy_m4_m4(mat, tmat); 01406 01407 dob= new_dupli_object(lb, go->ob, mat, par->lay, counter, OB_DUPLIPARTS, animated); 01408 copy_m4_m4(dob->omat, obcopylist[b].obmat); 01409 if(G.rendering) 01410 psys_get_dupli_texture(psys, part, sim.psmd, pa, cpa, dob->uv, dob->orco); 01411 } 01412 } 01413 else { 01414 /* to give ipos in object correct offset */ 01415 where_is_object_time(scene, ob, ctime-pa_time); 01416 01417 copy_v3_v3(vec, obmat[3]); 01418 obmat[3][0] = obmat[3][1] = obmat[3][2] = 0.0f; 01419 01420 /* particle rotation uses x-axis as the aligned axis, so pre-rotate the object accordingly */ 01421 if((part->draw & PART_DRAW_ROTATE_OB) == 0) { 01422 float xvec[3], q[4]; 01423 xvec[0] = -1.f; 01424 xvec[1] = xvec[2] = 0; 01425 vec_to_quat(q, xvec, ob->trackflag, ob->upflag); 01426 quat_to_mat4(obmat, q); 01427 obmat[3][3]= 1.0f; 01428 } 01429 01430 /* Normal particles and cached hair live in global space so we need to 01431 * remove the real emitter's transformation before 2nd order duplication. 01432 */ 01433 if(par_space_mat && GS(id->name) != ID_GR) 01434 mult_m4_m4m4(mat, psys->imat, pamat); 01435 else 01436 copy_m4_m4(mat, pamat); 01437 01438 mult_m4_m4m4(tmat, mat, obmat); 01439 mul_mat3_m4_fl(tmat, size*scale); 01440 01441 if(par_space_mat) 01442 mult_m4_m4m4(mat, par_space_mat, tmat); 01443 else 01444 copy_m4_m4(mat, tmat); 01445 01446 if(part->draw & PART_DRAW_GLOBAL_OB) 01447 add_v3_v3v3(mat[3], mat[3], vec); 01448 01449 dob= new_dupli_object(lb, ob, mat, ob->lay, counter, GS(id->name) == ID_GR ? OB_DUPLIGROUP : OB_DUPLIPARTS, animated); 01450 copy_m4_m4(dob->omat, oldobmat); 01451 if(G.rendering) 01452 psys_get_dupli_texture(psys, part, sim.psmd, pa, cpa, dob->uv, dob->orco); 01453 } 01454 } 01455 01456 /* restore objects since they were changed in where_is_object_time */ 01457 if(part->ren_as==PART_DRAW_GR) { 01458 for(a=0; a<totgroup; a++) 01459 *(oblist[a])= obcopylist[a]; 01460 } 01461 else 01462 *ob= obcopy; 01463 } 01464 01465 /* clean up */ 01466 if(oblist) 01467 MEM_freeN(oblist); 01468 if(obcopylist) 01469 MEM_freeN(obcopylist); 01470 01471 if(psys->lattice) { 01472 end_latt_deform(psys->lattice); 01473 psys->lattice = NULL; 01474 } 01475 } 01476 01477 static Object *find_family_object(Object **obar, char *family, char ch) 01478 { 01479 Object *ob; 01480 int flen; 01481 01482 if( obar[(int)ch] ) return obar[(int)ch]; 01483 01484 flen= strlen(family); 01485 01486 ob= G.main->object.first; 01487 while(ob) { 01488 if( ob->id.name[flen+2]==ch ) { 01489 if( strncmp(ob->id.name+2, family, flen)==0 ) break; 01490 } 01491 ob= ob->id.next; 01492 } 01493 01494 obar[(int)ch]= ob; 01495 01496 return ob; 01497 } 01498 01499 01500 static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int level, int animated) 01501 { 01502 Object *ob, *obar[256]= {NULL}; 01503 Curve *cu; 01504 struct chartrans *ct, *chartransdata; 01505 float vec[3], obmat[4][4], pmat[4][4], fsize, xof, yof; 01506 int slen, a; 01507 01508 /* simple preventing of too deep nested groups */ 01509 if(level>MAX_DUPLI_RECUR) return; 01510 01511 copy_m4_m4(pmat, par->obmat); 01512 01513 /* in par the family name is stored, use this to find the other objects */ 01514 01515 chartransdata= BKE_text_to_curve(G.main, scene, par, FO_DUPLI); 01516 if(chartransdata==NULL) return; 01517 01518 cu= par->data; 01519 slen= strlen(cu->str); 01520 fsize= cu->fsize; 01521 xof= cu->xof; 01522 yof= cu->yof; 01523 01524 ct= chartransdata; 01525 01526 for(a=0; a<slen; a++, ct++) { 01527 01528 ob= find_family_object(obar, cu->family, cu->str[a]); 01529 if(ob) { 01530 vec[0]= fsize*(ct->xof - xof); 01531 vec[1]= fsize*(ct->yof - yof); 01532 vec[2]= 0.0; 01533 01534 mul_m4_v3(pmat, vec); 01535 01536 copy_m4_m4(obmat, par->obmat); 01537 copy_v3_v3(obmat[3], vec); 01538 01539 new_dupli_object(lb, ob, obmat, par->lay, a, OB_DUPLIVERTS, animated); 01540 } 01541 } 01542 01543 MEM_freeN(chartransdata); 01544 } 01545 01546 /* ------------- */ 01547 01548 static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[][4], int level, int animated) 01549 { 01550 if((ob->transflag & OB_DUPLI)==0) 01551 return; 01552 01553 /* Should the dupli's be generated for this object? - Respect restrict flags */ 01554 if (G.rendering) { 01555 if (ob->restrictflag & OB_RESTRICT_RENDER) { 01556 return; 01557 } 01558 } else { 01559 if (ob->restrictflag & OB_RESTRICT_VIEW) { 01560 return; 01561 } 01562 } 01563 01564 if(ob->transflag & OB_DUPLIPARTS) { 01565 ParticleSystem *psys = ob->particlesystem.first; 01566 for(; psys; psys=psys->next) 01567 new_particle_duplilist(duplilist, id, scene, ob, par_space_mat, psys, level+1, animated); 01568 } 01569 else if(ob->transflag & OB_DUPLIVERTS) { 01570 if(ob->type==OB_MESH) { 01571 vertex_duplilist(duplilist, id, scene, ob, par_space_mat, level+1, animated); 01572 } 01573 else if(ob->type==OB_FONT) { 01574 if (GS(id->name)==ID_SCE) { /* TODO - support dupligroups */ 01575 font_duplilist(duplilist, scene, ob, level+1, animated); 01576 } 01577 } 01578 } 01579 else if(ob->transflag & OB_DUPLIFACES) { 01580 if(ob->type==OB_MESH) 01581 face_duplilist(duplilist, id, scene, ob, par_space_mat, level+1, animated); 01582 } 01583 else if(ob->transflag & OB_DUPLIFRAMES) { 01584 if (GS(id->name)==ID_SCE) { /* TODO - support dupligroups */ 01585 frames_duplilist(duplilist, scene, ob, level+1, animated); 01586 } 01587 } else if(ob->transflag & OB_DUPLIGROUP) { 01588 DupliObject *dob; 01589 01590 group_duplilist(duplilist, scene, ob, level+1, animated); /* now recursive */ 01591 01592 if (level==0) { 01593 for(dob= duplilist->first; dob; dob= dob->next) 01594 if(dob->type == OB_DUPLIGROUP) 01595 copy_m4_m4(dob->ob->obmat, dob->mat); 01596 } 01597 } 01598 } 01599 01600 /* Returns a list of DupliObject 01601 * note; group dupli's already set transform matrix. see note in group_duplilist() */ 01602 ListBase *object_duplilist(Scene *sce, Object *ob) 01603 { 01604 ListBase *duplilist= MEM_mallocN(sizeof(ListBase), "duplilist"); 01605 duplilist->first= duplilist->last= NULL; 01606 object_duplilist_recursive((ID *)sce, sce, ob, duplilist, NULL, 0, 0); 01607 return duplilist; 01608 } 01609 01610 void free_object_duplilist(ListBase *lb) 01611 { 01612 DupliObject *dob; 01613 01614 /* loop in reverse order, if object is instanced multiple times 01615 the original layer may not really be original otherwise, proper 01616 solution is more complicated */ 01617 for(dob= lb->last; dob; dob= dob->prev) { 01618 dob->ob->lay= dob->origlay; 01619 copy_m4_m4(dob->ob->obmat, dob->omat); 01620 } 01621 01622 BLI_freelistN(lb); 01623 MEM_freeN(lb); 01624 } 01625 01626 int count_duplilist(Object *ob) 01627 { 01628 if(ob->transflag & OB_DUPLI) { 01629 if(ob->transflag & OB_DUPLIVERTS) { 01630 if(ob->type==OB_MESH) { 01631 if(ob->transflag & OB_DUPLIVERTS) { 01632 ParticleSystem *psys = ob->particlesystem.first; 01633 int pdup=0; 01634 01635 for(; psys; psys=psys->next) 01636 pdup += psys->totpart; 01637 01638 if(pdup==0){ 01639 Mesh *me= ob->data; 01640 return me->totvert; 01641 } 01642 else 01643 return pdup; 01644 } 01645 } 01646 } 01647 else if(ob->transflag & OB_DUPLIFRAMES) { 01648 int tot= ob->dupend - ob->dupsta; 01649 tot/= (ob->dupon+ob->dupoff); 01650 return tot*ob->dupon; 01651 } 01652 } 01653 return 1; 01654 }