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