use static functions where possible for some local functions.
[blender.git] / source / blender / blenkernel / intern / cloth.c
index c7817b017ef454bfe4dd5dbb5b5193a9ad3a5d18..9ee6be903fa7ceb338ffba306bc3a0bf851fcd33 100644 (file)
@@ -33,6 +33,7 @@
 #include "DNA_mesh_types.h"
 #include "DNA_object_force.h"
 #include "DNA_scene_types.h"
+#include "DNA_particle_types.h"
 
 #include "BKE_deform.h"
 #include "BKE_DerivedMesh.h"
@@ -42,6 +43,7 @@
 #include "BKE_object.h"
 #include "BKE_modifier.h"
 #include "BKE_utildefines.h"
+#include "BKE_particle.h"
 
 #include "BKE_pointcache.h"
 
@@ -93,7 +95,7 @@ static CM_SOLVER_DEF  solvers [] =
 static void cloth_to_object (Object *ob,  ClothModifierData *clmd, DerivedMesh *dm);
 static void cloth_from_mesh ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm );
 static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float framenr, int first);
-int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm );
+static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm );
 static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm );
 
 
@@ -153,11 +155,11 @@ void cloth_init ( ClothModifierData *clmd )
        clmd->sim_parms->goalfrict = 0.0f;
 }
 
-BVHTree *bvhselftree_build_from_cloth (ClothModifierData *clmd, float epsilon)
+static BVHTree *bvhselftree_build_from_cloth (ClothModifierData *clmd, float epsilon)
 {
-       int i;
+       unsigned int i;
        BVHTree *bvhtree;
-       Cloth *cloth = clmd->clothObject;
+       Cloth *cloth;
        ClothVertex *verts;
        MFace *mfaces;
        float co[12];
@@ -194,11 +196,11 @@ BVHTree *bvhselftree_build_from_cloth (ClothModifierData *clmd, float epsilon)
        return bvhtree;
 }
 
-BVHTree *bvhtree_build_from_cloth (ClothModifierData *clmd, float epsilon)
+static BVHTree *bvhtree_build_from_cloth (ClothModifierData *clmd, float epsilon)
 {
-       int i;
+       unsigned int i;
        BVHTree *bvhtree;
-       Cloth *cloth = clmd->clothObject;
+       Cloth *cloth;
        ClothVertex *verts;
        MFace *mfaces;
        float co[12];
@@ -338,44 +340,6 @@ void bvhselftree_update_from_cloth(ClothModifierData *clmd, int moving)
        }
 }
 
-int modifiers_indexInObject(Object *ob, ModifierData *md_seek);
-
-int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr)
-{
-       PTCacheID pid;
-       PTCacheFile *pf;
-       Cloth *cloth = clmd->clothObject;
-       unsigned int a, ret = 1;
-       
-       if(!cloth)
-               return 0;
-       
-       BKE_ptcache_id_from_cloth(&pid, ob, clmd);
-       pf = BKE_ptcache_file_open(&pid, PTCACHE_FILE_READ, framenr);
-       if(pf) {
-               for(a = 0; a < cloth->numverts; a++) {
-                       if(!BKE_ptcache_file_read_floats(pf, cloth->verts[a].x, 3)) {
-                               ret = 0;
-                               break;
-                       }
-                       if(!BKE_ptcache_file_read_floats(pf, cloth->verts[a].xconst, 3)) {
-                               ret = 0;
-                               break;
-                       }
-                       if(!BKE_ptcache_file_read_floats(pf, cloth->verts[a].v, 3)) {
-                               ret = 0;
-                               break;
-                       }
-               }
-               
-               BKE_ptcache_file_close(pf);
-       }
-       else
-               ret = 0;
-       
-       return ret;
-}
-
 void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr)
 {
        PTCacheID pid;
@@ -383,36 +347,12 @@ void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr)
        BKE_ptcache_id_from_cloth(&pid, ob, clmd);
 
        // don't do anything as long as we're in editmode!
-       if(pid.cache->flag & PTCACHE_BAKE_EDIT_ACTIVE)
+       if(pid.cache->edit && ob->mode & OB_MODE_PARTICLE_EDIT)
                return;
        
        BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_AFTER, framenr);
 }
 
-void cloth_write_cache(Object *ob, ClothModifierData *clmd, float framenr)
-{
-       Cloth *cloth = clmd->clothObject;
-       PTCacheID pid;
-       PTCacheFile *pf;
-       unsigned int a;
-       
-       if(!cloth)
-               return;
-       
-       BKE_ptcache_id_from_cloth(&pid, ob, clmd);
-       pf = BKE_ptcache_file_open(&pid, PTCACHE_FILE_WRITE, framenr);
-       if(!pf)
-               return;
-       
-       for(a = 0; a < cloth->numverts; a++) {
-               BKE_ptcache_file_write_floats(pf, cloth->verts[a].x, 3);
-               BKE_ptcache_file_write_floats(pf, cloth->verts[a].xconst, 3);
-               BKE_ptcache_file_write_floats(pf, cloth->verts[a].v, 3);
-       }
-       
-       BKE_ptcache_file_close(pf);
-}
-
 static int do_init_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *result, int framenr)
 {
        PointCache *cache;
@@ -479,25 +419,28 @@ static int do_step_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *resul
 /************************************************
  * clothModifier_do - main simulation function
 ************************************************/
-DerivedMesh *clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc)
+DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc)
 {
        DerivedMesh *result;
        PointCache *cache;
        PTCacheID pid;
        float timescale;
        int framedelta, framenr, startframe, endframe;
+       int cache_result;
 
-       framenr= (int)G.scene->r.cfra;
+       clmd->scene= scene;     /* nice to pass on later :) */
+       framenr= (int)scene->r.cfra;
        cache= clmd->point_cache;
        result = CDDM_copy(dm);
 
        BKE_ptcache_id_from_cloth(&pid, ob, clmd);
-       BKE_ptcache_id_time(&pid, framenr, &startframe, &endframe, &timescale);
+       BKE_ptcache_id_time(&pid, scene, framenr, &startframe, &endframe, &timescale);
        clmd->sim_parms->timescale= timescale;
 
        if(!result) {
                cache->flag &= ~PTCACHE_SIMULATION_VALID;
                cache->simframe= 0;
+               cache->last_exact= 0;
                return dm;
        }
        
@@ -509,6 +452,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh *
                if(result->getNumVerts(result) != clmd->clothObject->numverts) {
                        cache->flag &= ~PTCACHE_SIMULATION_VALID;
                        cache->simframe= 0;
+                       cache->last_exact= 0;
                        return result;
                }
        }
@@ -520,6 +464,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh *
        if(BKE_ptcache_get_continue_physics()) {
                cache->flag &= ~PTCACHE_SIMULATION_VALID;
                cache->simframe= 0;
+               cache->last_exact= 0;
 
                /* do simulation */
                if(!do_init_cloth(ob, clmd, result, framenr))
@@ -535,6 +480,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh *
        if(framenr < startframe) {
                cache->flag &= ~PTCACHE_SIMULATION_VALID;
                cache->simframe= 0;
+               cache->last_exact= 0;
                return result;
        }
        else if(framenr > endframe) {
@@ -550,52 +496,61 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh *
        if(!do_init_cloth(ob, clmd, result, framenr))
                return result;
 
-       /* try to read from cache */
-       if(cloth_read_cache(ob, clmd, framenr)) {
-               cache->flag |= PTCACHE_SIMULATION_VALID;
+       if(framenr == startframe) {
+               BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
+               do_init_cloth(ob, clmd, result, framenr);
                cache->simframe= framenr;
+               cache->flag |= PTCACHE_SIMULATION_VALID;
+               cache->flag &= ~PTCACHE_REDO_NEEDED;
+               return result;
+       }
 
+       /* try to read from cache */
+       cache_result = BKE_ptcache_read_cache(&pid, (float)framenr, scene->r.frs_sec);
+
+       if(cache_result == PTCACHE_READ_EXACT || cache_result == PTCACHE_READ_INTERPOLATED) {
                implicit_set_positions(clmd);
                cloth_to_object (ob, clmd, result);
 
+               cache->simframe= framenr;
+               cache->flag |= PTCACHE_SIMULATION_VALID;
+
+               if(cache_result == PTCACHE_READ_INTERPOLATED && cache->flag & PTCACHE_REDO_NEEDED)
+                       BKE_ptcache_write_cache(&pid, framenr);
+
                return result;
        }
+       else if(cache_result==PTCACHE_READ_OLD) {
+               implicit_set_positions(clmd);
+               cache->flag |= PTCACHE_SIMULATION_VALID;
+       }
        else if(ob->id.lib || (cache->flag & PTCACHE_BAKED)) {
                /* if baked and nothing in cache, do nothing */
                cache->flag &= ~PTCACHE_SIMULATION_VALID;
                cache->simframe= 0;
+               cache->last_exact= 0;
                return result;
        }
 
-       if(framenr == startframe) {
-               cache->flag |= PTCACHE_SIMULATION_VALID;
-               cache->simframe= framenr;
+       /* if on second frame, write cache for first frame */
+       if(cache->simframe == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact==0))
+               BKE_ptcache_write_cache(&pid, startframe);
 
-               /* don't write cache on first frame, but on second frame write
-                * cache for frame 1 and 2 */
-       }
-       else if(framedelta == 1) {
-               /* if on second frame, write cache for first frame */
-               if(framenr == startframe+1)
-                       cloth_write_cache(ob, clmd, startframe);
+       clmd->sim_parms->timescale *= framenr - cache->simframe;
 
-               /* do simulation */
-               cache->flag |= PTCACHE_SIMULATION_VALID;
-               cache->simframe= framenr;
-
-               if(!do_step_cloth(ob, clmd, result, framenr)) {
-                       cache->flag &= ~PTCACHE_SIMULATION_VALID;
-                       cache->simframe= 0;
-               }
-               else
-                       cloth_write_cache(ob, clmd, framenr);
+       /* do simulation */
+       cache->flag |= PTCACHE_SIMULATION_VALID;
+       cache->simframe= framenr;
 
-               cloth_to_object (ob, clmd, result);
-       }
-       else {
+       if(!do_step_cloth(ob, clmd, result, framenr)) {
                cache->flag &= ~PTCACHE_SIMULATION_VALID;
                cache->simframe= 0;
+               cache->last_exact= 0;
        }
+       else
+               BKE_ptcache_write_cache(&pid, framenr);
+
+       cloth_to_object (ob, clmd, result);
 
        return result;
 }
@@ -782,19 +737,18 @@ static void cloth_to_object (Object *ob,  ClothModifierData *clmd, DerivedMesh *
 /* can be optimized to do all groups in one loop */
 static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm )
 {
-       unsigned int i = 0;
-       unsigned int j = 0;
+       int i = 0;
+       int j = 0;
        MDeformVert *dvert = NULL;
        Cloth *clothObj = NULL;
-       unsigned int numverts = dm->getNumVerts ( dm );
+       int numverts;
        float goalfac = 0;
        ClothVertex *verts = NULL;
 
+       if (!clmd || !dm) return;
+
        clothObj = clmd->clothObject;
 
-       if ( !dm )
-               return;
-       
        numverts = dm->getNumVerts ( dm );
 
        verts = clothObj->verts;
@@ -857,7 +811,7 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm )
 
 static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float framenr, int first)
 {
-       unsigned int i = 0;
+       int i = 0;
        MVert *mvert = NULL;
        ClothVertex *verts = NULL;
        float tnull[3] = {0,0,0};
@@ -1044,7 +998,7 @@ int cloth_add_spring ( ClothModifierData *clmd, unsigned int indexA, unsigned in
        return 0;
 }
 
-void cloth_free_errorsprings(Cloth *cloth, EdgeHash *edgehash, LinkNode **edgelist)
+static void cloth_free_errorsprings(Cloth *cloth, EdgeHash *edgehash, LinkNode **edgelist)
 {
        unsigned int i = 0;
        
@@ -1077,18 +1031,18 @@ void cloth_free_errorsprings(Cloth *cloth, EdgeHash *edgehash, LinkNode **edgeli
                BLI_edgehash_free ( cloth->edgehash, NULL );
 }
 
-int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
+static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
 {
        Cloth *cloth = clmd->clothObject;
        ClothSpring *spring = NULL, *tspring = NULL, *tspring2 = NULL;
        unsigned int struct_springs = 0, shear_springs=0, bend_springs = 0;
-       unsigned int i = 0;
-       unsigned int numverts = dm->getNumVerts ( dm );
-       unsigned int numedges = dm->getNumEdges ( dm );
-       unsigned int numfaces = dm->getNumFaces ( dm );
+       int i = 0;
+       int numverts = dm->getNumVerts ( dm );
+       int numedges = dm->getNumEdges ( dm );
+       int numfaces = dm->getNumFaces ( dm );
        MEdge *medge = CDDM_get_edges ( dm );
        MFace *mface = CDDM_get_faces ( dm );
-       unsigned int index2 = 0; // our second vertex index
+       int index2 = 0; // our second vertex index
        LinkNode **edgelist = NULL;
        EdgeHash *edgehash = NULL;
        LinkNode *search = NULL, *search2 = NULL;