2.5 - Animation Playback Tweaks
[blender.git] / source / blender / blenkernel / intern / anim.c
index 79c4d15b88e79f0ece6c35336b55af8171db6d78..6c1b8eb9000cb192e7954bec3aedf235a47b7bcf 100644 (file)
@@ -34,6 +34,7 @@
 
 #include "MEM_guardedalloc.h"
 #include "BLI_blenlib.h"
+#include "BLI_editVert.h"
 #include "BLI_arithb.h"
 #include "BLI_rand.h"
 #include "DNA_listBase.h"
 #include "BKE_particle.h"
 #include "BKE_utildefines.h"
 
-#include "BKE_bad_level_calls.h"
-
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
 
-static void object_duplilist_recursive(ID *id, Object *ob, ListBase *duplilist, float par_space_mat[][4], int level, int animated);
+#include "ED_mesh.h"
+
+static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[][4], int level, int animated);
 
 void free_path(Path *path)
 {
@@ -100,8 +101,10 @@ void calc_curvepath(Object *ob)
        
        if(ob==NULL || ob->type != OB_CURVE) return;
        cu= ob->data;
-       if(ob==G.obedit) nu= editNurb.first;
-       else nu= cu->nurb.first;
+       if(cu->editnurb) 
+               nu= cu->editnurb->first;
+       else 
+               nu= cu->nurb.first;
        
        if(cu->path) free_path(cu->path);
        cu->path= NULL;
@@ -301,7 +304,7 @@ static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], i
        return dob;
 }
 
-static void group_duplilist(ListBase *lb, Object *ob, int level, int animated)
+static void group_duplilist(ListBase *lb, Scene *scene, Object *ob, int level, int animated)
 {
        DupliObject *dob;
        Group *group;
@@ -316,7 +319,7 @@ static void group_duplilist(ListBase *lb, Object *ob, int level, int animated)
        
        /* handles animated groups, and */
        /* we need to check update for objects that are not in scene... */
-       group_handle_recalc_and_update(ob, group);
+       group_handle_recalc_and_update(scene, ob, group);
        animated= animated || group_is_animated(ob, group);
        
        for(go= group->gobject.first; go; go= go->next) {
@@ -337,14 +340,14 @@ static void group_duplilist(ListBase *lb, Object *ob, int level, int animated)
                        
                        if(go->ob->transflag & OB_DUPLI) {
                                Mat4CpyMat4(dob->ob->obmat, dob->mat);
-                               object_duplilist_recursive((ID *)group, go->ob, lb, ob->obmat, level+1, animated);
+                               object_duplilist_recursive((ID *)group, scene, go->ob, lb, ob->obmat, level+1, animated);
                                Mat4CpyMat4(dob->ob->obmat, dob->omat);
                        }
                }
        }
 }
 
-static void frames_duplilist(ListBase *lb, Object *ob, int level, int animated)
+static void frames_duplilist(ListBase *lb, Scene *scene, Object *ob, int level, int animated)
 {
        extern int enable_cu_speed;     /* object.c */
        Object copyob;
@@ -354,31 +357,33 @@ static void frames_duplilist(ListBase *lb, Object *ob, int level, int animated)
        /* simple preventing of too deep nested groups */
        if(level>MAX_DUPLI_RECUR) return;
        
-       cfrao= G.scene->r.cfra;
+       cfrao= scene->r.cfra;
        if(ob->parent==NULL && ob->track==NULL && ob->ipo==NULL && ob->constraints.first==NULL) return;
 
        if(ob->transflag & OB_DUPLINOSPEED) enable_cu_speed= 0;
        copyob= *ob;    /* store transform info */
 
-       for(G.scene->r.cfra= ob->dupsta; G.scene->r.cfra<=ob->dupend; G.scene->r.cfra++) {
+       for(scene->r.cfra= ob->dupsta; scene->r.cfra<=ob->dupend; scene->r.cfra++) {
 
                ok= 1;
                if(ob->dupoff) {
-                       ok= G.scene->r.cfra - ob->dupsta;
+                       ok= scene->r.cfra - ob->dupsta;
                        ok= ok % (ob->dupon+ob->dupoff);
                        if(ok < ob->dupon) ok= 1;
                        else ok= 0;
                }
                if(ok) {
-                       do_ob_ipo(ob);
-                       where_is_object_time(ob, (float)G.scene->r.cfra);
-                       dob= new_dupli_object(lb, ob, ob->obmat, ob->lay, G.scene->r.cfra, OB_DUPLIFRAMES, animated);
+#if 0 // XXX old animation system
+                       do_ob_ipo(scene, ob);
+#endif // XXX old animation system
+                       where_is_object_time(scene, ob, (float)scene->r.cfra);
+                       dob= new_dupli_object(lb, ob, ob->obmat, ob->lay, scene->r.cfra, OB_DUPLIFRAMES, animated);
                        Mat4CpyMat4(dob->omat, copyob.obmat);
                }
        }
 
        *ob= copyob;    /* restore transform info */
-       G.scene->r.cfra= cfrao;
+       scene->r.cfra= cfrao;
        enable_cu_speed= 1;
 }
 
@@ -389,6 +394,7 @@ struct vertexDupliData {
        ListBase *lb;
        float pmat[4][4];
        float obmat[4][4]; /* Only used for dupliverts inside dupligroups, where the ob->obmat is modified */
+       Scene *scene;
        Object *ob, *par;
        float (*orco)[3];
 };
@@ -429,36 +435,39 @@ static void vertex_dupli__mapFunc(void *userData, int index, float *co, float *n
                float tmpmat[4][4];
                Mat4CpyMat4(tmpmat, vdd->ob->obmat);
                Mat4CpyMat4(vdd->ob->obmat, obmat); /* pretend we are really this mat */
-               object_duplilist_recursive((ID *)vdd->id, vdd->ob, vdd->lb, obmat, vdd->level+1, vdd->animated);
+               object_duplilist_recursive((ID *)vdd->id, vdd->scene, vdd->ob, vdd->lb, obmat, vdd->level+1, vdd->animated);
                Mat4CpyMat4(vdd->ob->obmat, tmpmat);
        }
 }
 
-static void vertex_duplilist(ListBase *lb, ID *id, Object *par, float par_space_mat[][4], int level, int animated)
+static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int level, int animated)
 {
        Object *ob, *ob_iter;
-       Mesh *me;
+       Mesh *me= par->data;
        Base *base = NULL;
-       float vec[3], no[3], pmat[4][4];
-       int lay, totvert, a, oblay;
        DerivedMesh *dm;
        struct vertexDupliData vdd;
        Scene *sce = NULL;
        Group *group = NULL;
        GroupObject * go = NULL;
+       EditMesh *em;
+       float vec[3], no[3], pmat[4][4];
+       int lay, totvert, a, oblay;
        
        Mat4CpyMat4(pmat, par->obmat);
        
        /* simple preventing of too deep nested groups */
        if(level>MAX_DUPLI_RECUR) return;
-
-       if(par==G.obedit)
-               dm= editmesh_get_derived_cage(CD_MASK_BAREMESH);
-       else
-               dm= mesh_get_derived_deform(par, CD_MASK_BAREMESH);
-
+       
+       em = BKE_mesh_get_editmesh(me);
+       
+       if(em) {
+               dm= editmesh_get_derived_cage(scene, par, em, CD_MASK_BAREMESH);
+               BKE_mesh_end_editmesh(me, em);
+       } else
+               dm= mesh_get_derived_deform(scene, par, CD_MASK_BAREMESH);
+       
        if(G.rendering) {
-               me= par->data;
                vdd.orco= (float(*)[3])get_mesh_orco_verts(par);
                transform_mesh_orco_verts(me, vdd.orco, me->totvert, 0);
        }
@@ -488,7 +497,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Object *par, float par_space_
                        oblay = ob_iter->lay;
                }
                
-               if (lay & oblay && G.obedit!=ob_iter) {
+               if (lay & oblay && scene->obedit!=ob_iter) {
                        ob=ob_iter->parent;
                        while(ob) {
                                if(ob==par) {
@@ -509,13 +518,14 @@ static void vertex_duplilist(ListBase *lb, ID *id, Object *par, float par_space_
                                        vdd.animated= animated;
                                        vdd.lb= lb;
                                        vdd.ob= ob;
+                                       vdd.scene= scene;
                                        vdd.par= par;
                                        Mat4CpyMat4(vdd.pmat, pmat);
                                        
                                        /* mballs have a different dupli handling */
                                        if(ob->type!=OB_MBALL) ob->flag |= OB_DONE;     /* doesnt render */
 
-                                       if(par==G.obedit) {
+                                       if(par==scene->obedit) {
                                                dm->foreachMappedVert(dm, vertex_dupli__mapFunc, (void*) &vdd);
                                        }
                                        else {
@@ -541,13 +551,13 @@ static void vertex_duplilist(ListBase *lb, ID *id, Object *par, float par_space_
        dm->release(dm);
 }
 
-static void face_duplilist(ListBase *lb, ID *id, Object *par, float par_space_mat[][4], int level, int animated)
+static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int level, int animated)
 {
        Object *ob, *ob_iter;
        Base *base = NULL;
        DupliObject *dob;
        DerivedMesh *dm;
-       Mesh *me;
+       Mesh *me= par->data;
        MTFace *mtface;
        MFace *mface;
        MVert *mvert;
@@ -556,16 +566,19 @@ static void face_duplilist(ListBase *lb, ID *id, Object *par, float par_space_ma
        Scene *sce = NULL;
        Group *group = NULL;
        GroupObject *go = NULL;
+       EditMesh *em;
        float ob__obmat[4][4]; /* needed for groups where the object matrix needs to be modified */
        
        /* simple preventing of too deep nested groups */
        if(level>MAX_DUPLI_RECUR) return;
        
        Mat4CpyMat4(pmat, par->obmat);
-
-       if(par==G.obedit) {
+       
+       em = BKE_mesh_get_editmesh(me);
+       if(em) {
                int totvert;
-               dm= editmesh_get_derived_cage(CD_MASK_BAREMESH);
+               
+               dm= editmesh_get_derived_cage(scene, par, em, CD_MASK_BAREMESH);
                
                totface= dm->getNumFaces(dm);
                mface= MEM_mallocN(sizeof(MFace)*totface, "mface temp");
@@ -573,9 +586,11 @@ static void face_duplilist(ListBase *lb, ID *id, Object *par, float par_space_ma
                totvert= dm->getNumVerts(dm);
                mvert= MEM_mallocN(sizeof(MVert)*totvert, "mvert temp");
                dm->copyVertArray(dm, mvert);
+
+               BKE_mesh_end_editmesh(me, em);
        }
        else {
-               dm = mesh_get_derived_deform(par, CD_MASK_BAREMESH);
+               dm = mesh_get_derived_deform(scene, par, CD_MASK_BAREMESH);
                
                totface= dm->getNumFaces(dm);
                mface= dm->getFaceArray(dm);
@@ -583,7 +598,6 @@ static void face_duplilist(ListBase *lb, ID *id, Object *par, float par_space_ma
        }
 
        if(G.rendering) {
-               me= (Mesh*)par->data;
 
                orco= (float(*)[3])get_mesh_orco_verts(par);
                transform_mesh_orco_verts(me, orco, me->totvert, 0);
@@ -615,7 +629,7 @@ static void face_duplilist(ListBase *lb, ID *id, Object *par, float par_space_ma
                        oblay = ob_iter->lay;
                }
                
-               if (lay & oblay && G.obedit!=ob_iter) {
+               if (lay & oblay && scene->obedit!=ob_iter) {
                        ob=ob_iter->parent;
                        while(ob) {
                                if(ob==par) {
@@ -708,7 +722,7 @@ static void face_duplilist(ListBase *lb, ID *id, Object *par, float par_space_ma
                                                        float tmpmat[4][4];
                                                        Mat4CpyMat4(tmpmat, ob->obmat);
                                                        Mat4CpyMat4(ob->obmat, obmat); /* pretend we are really this mat */
-                                                       object_duplilist_recursive((ID *)id, ob, lb, ob->obmat, level+1, animated);
+                                                       object_duplilist_recursive((ID *)id, scene, ob, lb, ob->obmat, level+1, animated);
                                                        Mat4CpyMat4(ob->obmat, tmpmat);
                                                }
                                        }
@@ -722,7 +736,7 @@ static void face_duplilist(ListBase *lb, ID *id, Object *par, float par_space_ma
                else            go= go->next;           /* group loop */
        }
        
-       if(par==G.obedit) {
+       if(par==scene->obedit) {
                MEM_freeN(mface);
                MEM_freeN(mvert);
        }
@@ -733,7 +747,7 @@ static void face_duplilist(ListBase *lb, ID *id, Object *par, float par_space_ma
        dm->release(dm);
 }
 
-static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_space_mat[][4], ParticleSystem *psys, int level, int animated)
+static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], ParticleSystem *psys, int level, int animated)
 {
        GroupObject *go;
        Object *ob=0, **oblist=0, obcopy, *obcopylist=0;
@@ -747,7 +761,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_
        float ctime, pa_time, scale = 1.0f;
        float tmat[4][4], mat[4][4], pamat[4][4], size=0.0;
        float (*obmat)[4], (*oldobmat)[4];
-       int lay, a, b, k, counter, hair = 0;
+       int lay, a, b, counter, hair = 0;
        int totpart, totchild, totgroup=0, pa_num;
 
        if(psys==0) return;
@@ -764,16 +778,17 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_
        if(!psys_check_enabled(par, psys))
                return;
 
-       ctime = bsystem_time(par, (float)G.scene->r.cfra, 0.0);
+       ctime = bsystem_time(scene, par, (float)scene->r.cfra, 0.0);
 
        totpart = psys->totpart;
        totchild = psys->totchild;
 
        BLI_srandom(31415926 + psys->seed);
        
-       lay= G.scene->lay;
-       if((part->draw_as == PART_DRAW_OB && part->dup_ob) ||
-               (part->draw_as == PART_DRAW_GR && part->dup_group && part->dup_group->gobject.first)) {
+       lay= scene->lay;
+       if((psys->renderdata || part->draw_as==PART_DRAW_REND) &&
+               ((part->ren_as == PART_DRAW_OB && part->dup_ob) ||
+               (part->ren_as == PART_DRAW_GR && part->dup_group && part->dup_group->gobject.first))) {
 
                /* if we have a hair particle system, use the path cache */
                if(part->type == PART_HAIR) {
@@ -787,11 +802,11 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_
                        totpart = psys->totcached;
                }
 
-               psys->lattice = psys_get_lattice(par, psys);
+               psys->lattice = psys_get_lattice(scene, par, psys);
 
                /* gather list of objects or single object */
-               if(part->draw_as==PART_DRAW_GR) {
-                       group_handle_recalc_and_update(par, part->dup_group);
+               if(part->ren_as==PART_DRAW_GR) {
+                       group_handle_recalc_and_update(scene, par, part->dup_group);
 
                        for(go=part->dup_group->gobject.first; go; go=go->next)
                                totgroup++;
@@ -836,7 +851,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_
                                size = psys_get_child_size(psys, cpa, ctime, 0);
                        }
 
-                       if(part->draw_as==PART_DRAW_GR) {
+                       if(part->ren_as==PART_DRAW_GR) {
                                /* for groups, pick the object based on settings */
                                if(part->draw&PART_DRAW_RAND_GR)
                                        b= BLI_rand() % totgroup;
@@ -872,7 +887,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_
                        else {
                                /* first key */
                                state.time = ctime;
-                               if(psys_get_particle_state(par, psys, a, &state, 0) == 0)
+                               if(psys_get_particle_state(scene, par, psys, a, &state, 0) == 0)
                                        continue;
 
                                QuatToMat4(state.rot, pamat);
@@ -880,7 +895,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_
                                pamat[3][3]= 1.0f;
                        }
 
-                       if(part->draw_as==PART_DRAW_GR && psys->part->draw & PART_DRAW_WHOLE_GR) {
+                       if(part->ren_as==PART_DRAW_GR && psys->part->draw & PART_DRAW_WHOLE_GR) {
                                for(go= part->dup_group->gobject.first, b=0; go; go= go->next, b++) {
                                        Mat4MulMat4(tmat, oblist[b]->obmat, pamat);
                                        Mat4MulFloat3((float *)tmat, size*scale);
@@ -897,7 +912,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_
                        }
                        else {
                                /* to give ipos in object correct offset */
-                               where_is_object_time(ob, ctime-pa_time);
+                               where_is_object_time(scene, ob, ctime-pa_time);
                                
                                Mat4CpyMat4(mat, pamat);
 
@@ -908,7 +923,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_
                                else
                                        Mat4CpyMat4(mat, tmat);
 
-                               dob= new_dupli_object(lb, ob, mat, par->lay, counter, OB_DUPLIPARTS, animated);
+                               dob= new_dupli_object(lb, ob, mat, ob->lay, counter, OB_DUPLIPARTS, animated);
                                Mat4CpyMat4(dob->omat, oldobmat);
                                if(G.rendering)
                                        psys_get_dupli_texture(par, part, psmd, pa, cpa, dob->uv, dob->orco);
@@ -916,7 +931,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_
                }
 
                /* restore objects since they were changed in where_is_object_time */
-               if(part->draw_as==PART_DRAW_GR) {
+               if(part->ren_as==PART_DRAW_GR) {
                        for(a=0; a<totgroup; a++)
                                *(oblist[a])= obcopylist[a];
                }
@@ -931,8 +946,8 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_
                MEM_freeN(obcopylist);
 
        if(psys->lattice) {
-               end_latt_deform();
-               psys->lattice = 0;
+               end_latt_deform(psys->lattice);
+               psys->lattice = NULL;
        }
 }
 
@@ -941,7 +956,7 @@ static Object *find_family_object(Object **obar, char *family, char ch)
        Object *ob;
        int flen;
        
-       if( obar[ch] ) return obar[ch];
+       if( obar[(int)ch] ) return obar[(int)ch];
        
        flen= strlen(family);
        
@@ -953,13 +968,13 @@ static Object *find_family_object(Object **obar, char *family, char ch)
                ob= ob->id.next;
        }
        
-       obar[ch]= ob;
+       obar[(int)ch]= ob;
        
        return ob;
 }
 
 
-static void font_duplilist(ListBase *lb, Object *par, int level, int animated)
+static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int level, int animated)
 {
        Object *ob, *obar[256];
        Curve *cu;
@@ -974,7 +989,7 @@ static void font_duplilist(ListBase *lb, Object *par, int level, int animated)
        
        /* in par the family name is stored, use this to find the other objects */
        
-       chartransdata= text_to_curve(par, FO_DUPLI);
+       chartransdata= BKE_text_to_curve(scene, par, FO_DUPLI);
        if(chartransdata==0) return;
        
        memset(obar, 0, 256*sizeof(void *));
@@ -1008,7 +1023,7 @@ static void font_duplilist(ListBase *lb, Object *par, int level, int animated)
 }
 
 /* ***************************** */
-static void object_duplilist_recursive(ID *id, Object *ob, ListBase *duplilist, float par_space_mat[][4], int level, int animated)
+static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[][4], int level, int animated)
 {      
        if((ob->transflag & OB_DUPLI)==0)
                return;
@@ -1027,30 +1042,30 @@ static void object_duplilist_recursive(ID *id, Object *ob, ListBase *duplilist,
        if(ob->transflag & OB_DUPLIPARTS) {
                ParticleSystem *psys = ob->particlesystem.first;
                for(; psys; psys=psys->next)
-                       new_particle_duplilist(duplilist, id, ob, par_space_mat, psys, level+1, animated);
+                       new_particle_duplilist(duplilist, id, scene, ob, par_space_mat, psys, level+1, animated);
        }
        else if(ob->transflag & OB_DUPLIVERTS) {
                if(ob->type==OB_MESH) {
-                       vertex_duplilist(duplilist, id, ob, par_space_mat, level+1, animated);
+                       vertex_duplilist(duplilist, id, scene, ob, par_space_mat, level+1, animated);
                }
                else if(ob->type==OB_FONT) {
                        if (GS(id->name)==ID_SCE) { /* TODO - support dupligroups */
-                               font_duplilist(duplilist, ob, level+1, animated);
+                               font_duplilist(duplilist, scene, ob, level+1, animated);
                        }
                }
        }
        else if(ob->transflag & OB_DUPLIFACES) {
                if(ob->type==OB_MESH)
-                       face_duplilist(duplilist, id, ob, par_space_mat, level+1, animated);
+                       face_duplilist(duplilist, id, scene, ob, par_space_mat, level+1, animated);
        }
        else if(ob->transflag & OB_DUPLIFRAMES) {
                if (GS(id->name)==ID_SCE) { /* TODO - support dupligroups */
-                       frames_duplilist(duplilist, ob, level+1, animated);
+                       frames_duplilist(duplilist, scene, ob, level+1, animated);
                }
        } else if(ob->transflag & OB_DUPLIGROUP) {
                DupliObject *dob;
                
-               group_duplilist(duplilist, ob, level+1, animated); /* now recursive */
+               group_duplilist(duplilist, scene, ob, level+1, animated); /* now recursive */
 
                if (level==0) {
                        for(dob= duplilist->first; dob; dob= dob->next)
@@ -1066,7 +1081,7 @@ ListBase *object_duplilist(Scene *sce, Object *ob)
 {
        ListBase *duplilist= MEM_mallocN(sizeof(ListBase), "duplilist");
        duplilist->first= duplilist->last= NULL;
-       object_duplilist_recursive((ID *)sce, ob, duplilist, NULL, 0, 0);
+       object_duplilist_recursive((ID *)sce, sce, ob, duplilist, NULL, 0, 0);
        return duplilist;
 }