2.5 - Animation Playback Tweaks
[blender.git] / source / blender / blenkernel / intern / anim.c
index 8c71a1d807ead12d4f33394fa74b58d589a4deb9..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"
@@ -72,6 +73,8 @@
 #include <config.h>
 #endif
 
+#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)
@@ -223,14 +226,16 @@ int where_on_path(Object *ob, float ctime, float *vec, float *dir)        /* returns OK
        cu= ob->data;
        if(cu->path==NULL || cu->path->data==NULL) {
                printf("no path!\n");
+               return 0;
        }
        path= cu->path;
        fp= path->data;
        
        /* test for cyclic */
        bl= cu->bev.first;
+       if (!bl) return 0;
        if (!bl->nr) return 0;
-       if(bl && bl->poly> -1) cycl= 1;
+       if(bl->poly> -1) cycl= 1;
 
        ctime *= (path->len-1);
        
@@ -445,6 +450,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl
        Scene *sce = NULL;
        Group *group = NULL;
        GroupObject * go = NULL;
+       EditMesh *em;
        float vec[3], no[3], pmat[4][4];
        int lay, totvert, a, oblay;
        
@@ -452,12 +458,15 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl
        
        /* simple preventing of too deep nested groups */
        if(level>MAX_DUPLI_RECUR) return;
-
-       if(me->edit_mesh)
-               dm= editmesh_get_derived_cage(scene, par, me->edit_mesh, CD_MASK_BAREMESH);
-       else
+       
+       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) {
                vdd.orco= (float(*)[3])get_mesh_orco_verts(par);
                transform_mesh_orco_verts(me, vdd.orco, me->totvert, 0);
@@ -557,17 +566,19 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa
        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(me->edit_mesh) {
+       
+       em = BKE_mesh_get_editmesh(me);
+       if(em) {
                int totvert;
                
-               dm= editmesh_get_derived_cage(scene, par, me->edit_mesh, 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");
@@ -575,6 +586,8 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa
                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(scene, par, CD_MASK_BAREMESH);
@@ -748,7 +761,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
        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, step_nbr = 0, counter, hair = 0;
+       int lay, a, b, counter, hair = 0;
        int totpart, totchild, totgroup=0, pa_num;
 
        if(psys==0) return;
@@ -773,13 +786,9 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
        BLI_srandom(31415926 + psys->seed);
        
        lay= 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)) {
-
-               if(psys->flag & (PSYS_HAIR_DONE|PSYS_KEYED) && part->draw & PART_DRAW_KEYS)
-                       step_nbr = part->keys_step;
-               else
-                       step_nbr = 0;
+       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) {
@@ -796,7 +805,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
                psys->lattice = psys_get_lattice(scene, par, psys);
 
                /* gather list of objects or single object */
-               if(part->draw_as==PART_DRAW_GR) {
+               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)
@@ -842,7 +851,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
                                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;
@@ -860,80 +869,69 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
                                oldobmat= obcopy.obmat;
                        }
 
-                       for(k=0; k<=step_nbr; k++, counter++) {
-                               if(hair) {
-                                       /* hair we handle separate and compute transform based on hair keys */
-                                       if(a < totpart) {
-                                               cache = psys->pathcache[a];
-                                               psys_get_dupli_path_transform(par, psys, psmd, pa, 0, cache, pamat, &scale);
-                                       }
-                                       else {
-                                               cache = psys->childcache[a-totpart];
-                                               psys_get_dupli_path_transform(par, psys, psmd, 0, cpa, cache, pamat, &scale);
-                                       }
-
-                                       VECCOPY(pamat[3], cache->co);
-                                       pamat[3][3]= 1.0f;
-                                       
-                               }
-                               else if(step_nbr) {
-                                       /* other keys */
-                                       state.time = (float)k / (float)step_nbr;
-                                       psys_get_particle_on_path(scene, par, psys, a, &state, 0);
-
-                                       QuatToMat4(state.rot, pamat);
-                                       VECCOPY(pamat[3], state.co);
-                                       pamat[3][3]= 1.0f;
+                       if(hair) {
+                               /* hair we handle separate and compute transform based on hair keys */
+                               if(a < totpart) {
+                                       cache = psys->pathcache[a];
+                                       psys_get_dupli_path_transform(par, psys, psmd, pa, 0, cache, pamat, &scale);
                                }
                                else {
-                                       /* first key */
-                                       state.time = -1.0;
-                                       if(psys_get_particle_state(scene, par, psys, a, &state, 0) == 0)
-                                               continue;
-
-                                       QuatToMat4(state.rot, pamat);
-                                       VECCOPY(pamat[3], state.co);
-                                       pamat[3][3]= 1.0f;
+                                       cache = psys->childcache[a-totpart];
+                                       psys_get_dupli_path_transform(par, psys, psmd, 0, cpa, cache, pamat, &scale);
                                }
 
-                               if(part->draw_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);
-                                               if(par_space_mat)
-                                                       Mat4MulMat4(mat, tmat, par_space_mat);
-                                               else
-                                                       Mat4CpyMat4(mat, tmat);
+                               VECCOPY(pamat[3], cache->co);
+                               pamat[3][3]= 1.0f;
+                               
+                       }
+                       else {
+                               /* first key */
+                               state.time = ctime;
+                               if(psys_get_particle_state(scene, par, psys, a, &state, 0) == 0)
+                                       continue;
 
-                                               dob= new_dupli_object(lb, go->ob, mat, par->lay, counter, OB_DUPLIPARTS, animated);
-                                               Mat4CpyMat4(dob->omat, obcopylist[b].obmat);
-                                               if(G.rendering)
-                                                       psys_get_dupli_texture(par, part, psmd, pa, cpa, dob->uv, dob->orco);
-                                       }
-                               }
-                               else {
-                                       /* to give ipos in object correct offset */
-                                       where_is_object_time(scene, ob, ctime-pa_time);
-                                       
-                                       Mat4CpyMat4(mat, pamat);
+                               QuatToMat4(state.rot, pamat);
+                               VECCOPY(pamat[3], state.co);
+                               pamat[3][3]= 1.0f;
+                       }
 
-                                       Mat4MulMat4(tmat, obmat, mat);
+                       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);
                                        if(par_space_mat)
                                                Mat4MulMat4(mat, tmat, par_space_mat);
                                        else
                                                Mat4CpyMat4(mat, tmat);
 
-                                       dob= new_dupli_object(lb, ob, mat, par->lay, counter, OB_DUPLIPARTS, animated);
-                                       Mat4CpyMat4(dob->omat, oldobmat);
+                                       dob= new_dupli_object(lb, go->ob, mat, par->lay, counter, OB_DUPLIPARTS, animated);
+                                       Mat4CpyMat4(dob->omat, obcopylist[b].obmat);
                                        if(G.rendering)
                                                psys_get_dupli_texture(par, part, psmd, pa, cpa, dob->uv, dob->orco);
                                }
                        }
+                       else {
+                               /* to give ipos in object correct offset */
+                               where_is_object_time(scene, ob, ctime-pa_time);
+                               
+                               Mat4CpyMat4(mat, pamat);
+
+                               Mat4MulMat4(tmat, obmat, mat);
+                               Mat4MulFloat3((float *)tmat, size*scale);
+                               if(par_space_mat)
+                                       Mat4MulMat4(mat, tmat, par_space_mat);
+                               else
+                                       Mat4CpyMat4(mat, tmat);
+
+                               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);
+                       }
                }
 
                /* 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];
                }