Merging r58464 through r58474 from trunk into soc-2013-depsgraph_mt
[blender.git] / source / blender / blenkernel / intern / anim.c
index 50fe1f7a433d3375f701a2ef085278a88a7207c7..b817236781de5479eb3710454f40ac616b0f1fa0 100644 (file)
 #include "BKE_object.h"
 #include "BKE_particle.h"
 #include "BKE_scene.h"
-#include "BKE_tessmesh.h"
+#include "BKE_editmesh.h"
 #include "BKE_depsgraph.h"
 #include "BKE_anim.h"
 #include "BKE_report.h"
-#include "BKE_rigidbody.h"
 
 
 // XXX bad level call...
@@ -327,39 +326,38 @@ static void motionpaths_calc_optimise_depsgraph(Scene *scene, ListBase *targets)
 static void motionpaths_calc_update_scene(Scene *scene)
 {
 #if 1 // 'production' optimizations always on
-       Base *base, *last = NULL;
-       float ctime = BKE_scene_frame_get(scene);
-       
-       /* only stuff that moves or needs display still */
-       DAG_scene_update_flags(G.main, scene, scene->lay, TRUE);
-       
-       /* find the last object with the tag 
-        * - all those afterwards are assumed to not be relevant for our calculations
-        */
-       /* optimize further by moving out... */
-       for (base = scene->base.first; base; base = base->next) {
-               if (base->object->flag & BA_TEMP_TAG)
-                       last = base;
+
+       /* rigid body simulation needs complete update to work correctly for now */
+       /* RB_TODO investigate if we could avoid updating everything */
+       if (BKE_scene_check_rigidbody_active(scene)) {
+               BKE_scene_update_for_newframe(G.main, scene, scene->lay);
        }
-       
-       /* run rigidbody sim 
-        * NOTE: keep in sync with BKE_scene_update_for_newframe() in scene.c
-        */
-       // XXX: this position may still change, objects not being updated correctly before simulation is run
-       // NOTE: current position is so that rigidbody sim affects other objects
-       if (BKE_scene_check_rigidbody_active(scene))
-               BKE_rigidbody_do_simulation(scene, ctime);
-       
-       /* perform updates for tagged objects */
-       /* XXX: this will break if rigs depend on scene or other data that
-        * is animated but not attached to/updatable from objects */
-       for (base = scene->base.first; base; base = base->next) {
-               /* update this object */
-               BKE_object_handle_update(scene, base->object);
+       else { /* otherwise we can optimize by restricting updates */
+               Base *base, *last = NULL;
+               
+               /* only stuff that moves or needs display still */
+               DAG_scene_update_flags(G.main, scene, scene->lay, TRUE);
                
-               /* if this is the last one we need to update, let's stop to save some time */
-               if (base == last)
-                       break;
+               /* find the last object with the tag 
+                * - all those afterwards are assumed to not be relevant for our calculations
+                */
+               /* optimize further by moving out... */
+               for (base = scene->base.first; base; base = base->next) {
+                       if (base->object->flag & BA_TEMP_TAG)
+                               last = base;
+               }
+               
+               /* perform updates for tagged objects */
+               /* XXX: this will break if rigs depend on scene or other data that
+                * is animated but not attached to/updatable from objects */
+               for (base = scene->base.first; base; base = base->next) {
+                       /* update this object */
+                       BKE_object_handle_update(scene, base->object);
+                       
+                       /* if this is the last one we need to update, let's stop to save some time */
+                       if (base == last)
+                               break;
+               }
        }
 #else // original, 'always correct' version
          /* do all updates
@@ -490,7 +488,7 @@ void free_path(Path *path)
 /* calculate a curve-deform path for a curve 
  *  - only called from displist.c -> do_makeDispListCurveTypes
  */
-void calc_curvepath(Object *ob)
+void calc_curvepath(Object *ob, ListBase *nurbs)
 {
        BevList *bl;
        BevPoint *bevp, *bevpn, *bevpfirst, *bevplast;
@@ -501,7 +499,6 @@ void calc_curvepath(Object *ob)
        float *fp, *dist, *maxdist, xyz[3];
        float fac, d = 0, fac1, fac2;
        int a, tot, cycl = 0;
-       ListBase *nurbs;
        
        /* in a path vertices are with equal differences: path->len = number of verts */
        /* NOW WITH BEVELCURVE!!! */
@@ -511,19 +508,18 @@ void calc_curvepath(Object *ob)
        }
        cu = ob->data;
 
-       if (cu->path) free_path(cu->path);
-       cu->path = NULL;
+       if (ob->curve_cache->path) free_path(ob->curve_cache->path);
+       ob->curve_cache->path = NULL;
        
        /* weak! can only use first curve */
-       bl = cu->bev.first;
+       bl = ob->curve_cache->bev.first;
        if (bl == NULL || !bl->nr) {
                return;
        }
 
-       nurbs = BKE_curve_nurbs_get(cu);
        nu = nurbs->first;
 
-       cu->path = path = MEM_callocN(sizeof(Path), "calc_curvepath");
+       ob->curve_cache->path = path = MEM_callocN(sizeof(Path), "calc_curvepath");
        
        /* if POLY: last vertice != first vertice */
        cycl = (bl->poly != -1);
@@ -628,18 +624,19 @@ int where_on_path(Object *ob, float ctime, float vec[4], float dir[3], float qua
        float fac;
        float data[4];
        int cycl = 0, s0, s1, s2, s3;
+       ListBase *nurbs;
 
        if (ob == NULL || ob->type != OB_CURVE) return 0;
        cu = ob->data;
-       if (cu->path == NULL || cu->path->data == NULL) {
+       if (ob->curve_cache == NULL || ob->curve_cache->path == NULL || ob->curve_cache->path->data == NULL) {
                printf("no path!\n");
                return 0;
        }
-       path = cu->path;
+       path = ob->curve_cache->path;
        pp = path->data;
        
        /* test for cyclic */
-       bl = cu->bev.first;
+       bl = ob->curve_cache->bev.first;
        if (!bl) return 0;
        if (!bl->nr) return 0;
        if (bl->poly > -1) cycl = 1;
@@ -670,8 +667,11 @@ int where_on_path(Object *ob, float ctime, float vec[4], float dir[3], float qua
        /* make compatible with vectoquat */
        negate_v3(dir);
        //}
-       
-       nu = cu->nurb.first;
+
+       nurbs = BKE_curve_editNurbs_get(cu);
+       if (!nurbs)
+               nurbs = &cu->nurb;
+       nu = nurbs->first;
 
        /* make sure that first and last frame are included in the vectors here  */
        if (nu->type == CU_POLY) key_curve_position_weights(1.0f - fac, data, KEY_LINEAR);
@@ -768,10 +768,10 @@ static void group_duplilist(ListBase *lb, Scene *scene, Object *ob, int persiste
        if (flag & DUPLILIST_DO_UPDATE) {
                /* note: update is optional because we don't always need object
                 * transformations to be correct. Also fixes bug [#29616]. */
-               group_handle_recalc_and_update(scene, ob, group);
+               BKE_group_handle_recalc_and_update(scene, ob, group);
        }
 
-       if (group_is_animated(ob, group))
+       if (BKE_group_is_animated(group, ob))
                flag |= DUPLILIST_ANIMATED;
        
        for (go = group->gobject.first, id = 0; go; go = go->next, id++) {
@@ -782,10 +782,10 @@ static void group_duplilist(ListBase *lb, Scene *scene, Object *ob, int persiste
                        if (!is_zero_v3(group->dupli_ofs)) {
                                copy_m4_m4(tmat, go->ob->obmat);
                                sub_v3_v3v3(tmat[3], tmat[3], group->dupli_ofs);
-                               mult_m4_m4m4(mat, ob->obmat, tmat);
+                               mul_m4_m4m4(mat, ob->obmat, tmat);
                        }
                        else {
-                               mult_m4_m4m4(mat, ob->obmat, go->ob->obmat);
+                               mul_m4_m4m4(mat, ob->obmat, go->ob->obmat);
                        }
                        
                        dob = new_dupli_object(lb, go->ob, mat, ob->lay, persistent_id, level, id, OB_DUPLIGROUP, flag);
@@ -955,24 +955,27 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl
        float vec[3], no[3], pmat[4][4];
        int totvert, a, oblay;
        unsigned int lay;
+       CustomDataMask dm_mask;
        
        copy_m4_m4(pmat, par->obmat);
        
        /* simple preventing of too deep nested groups */
        if (level > MAX_DUPLI_RECUR) return;
        
-       em = BMEdit_FromObject(par);
+       em = BKE_editmesh_from_object(par);
        
-       if (em) {
-               dm = editbmesh_get_derived_cage(scene, par, em, CD_MASK_BAREMESH);
-       }
+       /* get derived mesh */
+       dm_mask = CD_MASK_BAREMESH;
+       if (flag & DUPLILIST_FOR_RENDER)
+               dm_mask |= CD_MASK_ORCO;
+       
+       if (em)
+               dm = editbmesh_get_derived_cage(scene, par, em, dm_mask);
        else
-               dm = mesh_get_derived_final(scene, par, CD_MASK_BAREMESH);
+               dm = mesh_get_derived_final(scene, par, dm_mask);
        
-       if (flag & DUPLILIST_FOR_RENDER) {
-               vdd.orco = (float(*)[3])BKE_mesh_orco_verts_get(par);
-               BKE_mesh_orco_verts_transform(me, vdd.orco, me->totvert, 0);
-       }
+       if (flag & DUPLILIST_FOR_RENDER)
+               vdd.orco = dm->getVertDataArray(dm, CD_ORCO);
        else
                vdd.orco = NULL;
        
@@ -1013,7 +1016,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl
                                         * when par_space_mat is NULL ob->obmat can be used instead of ob__obmat
                                         */
                                        if (par_space_mat)
-                                               mult_m4_m4m4(vdd.obmat, par_space_mat, ob->obmat);
+                                               mul_m4_m4m4(vdd.obmat, par_space_mat, ob->obmat);
                                        else
                                                copy_m4_m4(vdd.obmat, ob->obmat);
 
@@ -1059,8 +1062,6 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl
                else go = go->next;             /* group loop */
        }
 
-       if (vdd.orco)
-               MEM_freeN(vdd.orco);
        dm->release(dm);
 }
 
@@ -1071,7 +1072,6 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa
        Base *base = NULL;
        DupliObject *dob;
        DerivedMesh *dm;
-       Mesh *me = par->data;
        MLoopUV *mloopuv;
        MPoly *mpoly, *mp;
        MLoop *mloop;
@@ -1083,18 +1083,24 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa
        GroupObject *go = NULL;
        BMEditMesh *em;
        float ob__obmat[4][4]; /* needed for groups where the object matrix needs to be modified */
+       CustomDataMask dm_mask;
        
        /* simple preventing of too deep nested groups */
        if (level > MAX_DUPLI_RECUR) return;
        
        copy_m4_m4(pmat, par->obmat);
-       em = BMEdit_FromObject(par);
+       em = BKE_editmesh_from_object(par);
+
+       /* get derived mesh */
+       dm_mask = CD_MASK_BAREMESH;
+       if (flag & DUPLILIST_FOR_RENDER)
+               dm_mask |= CD_MASK_ORCO | CD_MASK_MLOOPUV;
 
        if (em) {
-               dm = editbmesh_get_derived_cage(scene, par, em, CD_MASK_BAREMESH);
+               dm = editbmesh_get_derived_cage(scene, par, em, dm_mask);
        }
        else {
-               dm = mesh_get_derived_final(scene, par, CD_MASK_BAREMESH);
+               dm = mesh_get_derived_final(scene, par, dm_mask);
        }
 
        totface = dm->getNumPolys(dm);
@@ -1103,9 +1109,8 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa
        mvert = dm->getVertArray(dm);
 
        if (flag & DUPLILIST_FOR_RENDER) {
-               orco = (float(*)[3])BKE_mesh_orco_verts_get(par);
-               BKE_mesh_orco_verts_transform(me, orco, me->totvert, 0);
-               mloopuv = me->mloopuv;
+               orco = dm->getVertDataArray(dm, CD_ORCO);
+               mloopuv = dm->getLoopDataArray(dm, CD_MLOOPUV);
        }
        else {
                orco = NULL;
@@ -1146,7 +1151,7 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa
                                         * when par_space_mat is NULL ob->obmat can be used instead of ob__obmat
                                         */
                                        if (par_space_mat)
-                                               mult_m4_m4m4(ob__obmat, par_space_mat, ob->obmat);
+                                               mul_m4_m4m4(ob__obmat, par_space_mat, ob->obmat);
                                        else
                                                copy_m4_m4(ob__obmat, ob->obmat);
                                        
@@ -1156,10 +1161,6 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa
                                        if (ob->type != OB_MBALL) ob->flag |= OB_DONE;  /* doesnt render */
 
                                        for (a = 0, mp = mpoly; a < totface; a++, mp++) {
-                                               int mv1;
-                                               int mv2;
-                                               int mv3;
-                                               /* int mv4; */ /* UNUSED */
                                                float *v1;
                                                float *v2;
                                                float *v3;
@@ -1173,9 +1174,9 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa
                                                }
                                                else {
                                                        BKE_mesh_calc_poly_normal(mp, mloop + mp->loopstart, mvert, f_no);
-                                                       v1 = mvert[(mv1 = loopstart[0].v)].co;
-                                                       v2 = mvert[(mv2 = loopstart[1].v)].co;
-                                                       v3 = mvert[(mv3 = loopstart[2].v)].co;
+                                                       v1 = mvert[loopstart[0].v].co;
+                                                       v2 = mvert[loopstart[1].v].co;
+                                                       v3 = mvert[loopstart[2].v].co;
                                                }
 
                                                /* translation */
@@ -1221,7 +1222,7 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa
                                                        if (mloopuv) {
                                                                int j;
                                                                for (j = 0; j < mpoly->totloop; j++) {
-                                                                       madd_v2_v2fl(dob->orco, mloopuv[loopstart[j].v].uv, w);
+                                                                       madd_v2_v2fl(dob->uv, mloopuv[mp->loopstart + j].uv, w);
                                                                }
                                                        }
                                                }
@@ -1244,9 +1245,6 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa
                else go = go->next;             /* group loop */
        }
 
-       if (orco)
-               MEM_freeN(orco);
-       
        dm->release(dm);
 }
 
@@ -1332,12 +1330,12 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
 
                psys_check_group_weights(part);
 
-               psys->lattice = psys_get_lattice(&sim);
+               psys->lattice_deform_data = psys_create_lattice_deform_data(&sim);
 
                /* gather list of objects or single object */
                if (part->ren_as == PART_DRAW_GR) {
                        if (flag & DUPLILIST_DO_UPDATE) {
-                               group_handle_recalc_and_update(scene, par, part->dup_group);
+                               BKE_group_handle_recalc_and_update(scene, par, part->dup_group);
                        }
 
                        if (part->draw & PART_DRAW_COUNT_GR) {
@@ -1471,10 +1469,10 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
                                        if (!is_zero_v3(part->dup_group->dupli_ofs))
                                                sub_v3_v3v3(tmat[3], tmat[3], part->dup_group->dupli_ofs);
                                        /* individual particle transform */
-                                       mult_m4_m4m4(tmat, pamat, tmat);
+                                       mul_m4_m4m4(tmat, pamat, tmat);
 
                                        if (par_space_mat)
-                                               mult_m4_m4m4(mat, par_space_mat, tmat);
+                                               mul_m4_m4m4(mat, par_space_mat, tmat);
                                        else
                                                copy_m4_m4(mat, tmat);
 
@@ -1514,7 +1512,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
                                        
                                        /* add scaling if requested */
                                        if ((part->draw & PART_DRAW_NO_SCALE_OB) == 0)
-                                               mult_m4_m4m4(obmat, obmat, size_mat);
+                                               mul_m4_m4m4(obmat, obmat, size_mat);
                                }
                                else if (part->draw & PART_DRAW_NO_SCALE_OB) {
                                        /* remove scaling */
@@ -1524,22 +1522,22 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
                                        size_to_mat4(size_mat, original_size);
                                        invert_m4(size_mat);
 
-                                       mult_m4_m4m4(obmat, obmat, size_mat);
+                                       mul_m4_m4m4(obmat, obmat, size_mat);
                                }
                                
                                /* Normal particles and cached hair live in global space so we need to
                                 * remove the real emitter's transformation before 2nd order duplication.
                                 */
                                if (par_space_mat && GS(id->name) != ID_GR)
-                                       mult_m4_m4m4(mat, psys->imat, pamat);
+                                       mul_m4_m4m4(mat, psys->imat, pamat);
                                else
                                        copy_m4_m4(mat, pamat);
 
-                               mult_m4_m4m4(tmat, mat, obmat);
+                               mul_m4_m4m4(tmat, mat, obmat);
                                mul_mat3_m4_fl(tmat, size * scale);
 
                                if (par_space_mat)
-                                       mult_m4_m4m4(mat, par_space_mat, tmat);
+                                       mul_m4_m4m4(mat, par_space_mat, tmat);
                                else
                                        copy_m4_m4(mat, tmat);
 
@@ -1569,9 +1567,9 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
        if (obcopylist)
                MEM_freeN(obcopylist);
 
-       if (psys->lattice) {
-               end_latt_deform(psys->lattice);
-               psys->lattice = NULL;
+       if (psys->lattice_deform_data) {
+               end_latt_deform(psys->lattice_deform_data);
+               psys->lattice_deform_data = NULL;
        }
 }
 
@@ -1718,14 +1716,17 @@ static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBas
 
 /* Returns a list of DupliObject
  * note; group dupli's already set transform matrix. see note in group_duplilist() */
-ListBase *object_duplilist_ex(Scene *sce, Object *ob, int update, int for_render)
+ListBase *object_duplilist_ex(Scene *sce, Object *ob, bool update, bool for_render)
 {
        ListBase *duplilist = MEM_mallocN(sizeof(ListBase), "duplilist");
        int persistent_id[MAX_DUPLI_RECUR] = {0};
        int flag = 0;
 
-       if (update)     flag |= DUPLILIST_DO_UPDATE;
-       if (for_render) flag |= DUPLILIST_FOR_RENDER;
+       /* don't allow BKE_object_handle_update for viewport during render, can crash */
+       if (update && !(G.is_rendering && !for_render))
+               flag |= DUPLILIST_DO_UPDATE;
+       if (for_render)
+               flag |= DUPLILIST_FOR_RENDER;
 
        duplilist->first = duplilist->last = NULL;
        object_duplilist_recursive((ID *)sce, sce, ob, duplilist, NULL, persistent_id, 0, 0, flag);
@@ -1734,9 +1735,9 @@ ListBase *object_duplilist_ex(Scene *sce, Object *ob, int update, int for_render
 
 /* note: previously updating was always done, this is why it defaults to be on
  * but there are likely places it can be called without updating */
-ListBase *object_duplilist(Scene *sce, Object *ob, int for_render)
+ListBase *object_duplilist(Scene *sce, Object *ob, bool for_render)
 {
-       return object_duplilist_ex(sce, ob, TRUE, for_render);
+       return object_duplilist_ex(sce, ob, true, for_render);
 }