Merged back with last version where collisions worked at least a bit (rev 12296)...
authorDaniel Genrich <daniel.genrich@gmx.net>
Mon, 7 Jan 2008 03:20:43 +0000 (03:20 +0000)
committerDaniel Genrich <daniel.genrich@gmx.net>
Mon, 7 Jan 2008 03:20:43 +0000 (03:20 +0000)
14 files changed:
CMakeLists.txt
source/blender/blenkernel/BKE_cloth.h
source/blender/blenkernel/BKE_modifier.h
source/blender/blenkernel/intern/cloth.c
source/blender/blenkernel/intern/collision.c
source/blender/blenkernel/intern/implicit.c
source/blender/blenkernel/intern/modifier.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/makesdna/DNA_cloth_types.h
source/blender/makesdna/DNA_modifier_types.h
source/blender/src/buttons_object.c
source/blender/src/drawobject.c
source/blender/src/vpaint.c

index d79c22201045b83c6138051293702982028dcbb1..4eb5e9c659d95818280320160cb6c4ce7b819717 100644 (file)
@@ -65,8 +65,9 @@ OPTION(WITH_ELBEEM            "Enable Elbeem (Fluid Simulation)"                      ON)
 OPTION(WITH_QUICKTIME          "Enable Quicktime Support"                              OFF)
 OPTION(WITH_OPENEXR            "Enable OpenEXR Support (http://www.openexr.com)"       OFF)
 OPTION(WITH_FFMPEG             "Enable FFMPeg Support (http://ffmpeg.mplayerhq.hu/)"   OFF)
-OPTION(WITH_OPENAL             "Enable OpenAL Support (http://www.openal.org)" ON)
-OPTION(YESIAMSTUPID            "Enable execution on 64-bit platforms"                                  OFF)
+OPTION(WITH_OPENAL             "Enable OpenAL Support (http://www.openal.org)"         ON)
+OPTION(YESIAMSTUPID            "Enable execution on 64-bit platforms"                  OFF)
+OPTION(WITH_OPENMP             "Enable OpenMP (has to be supported by the compiler)"   OFF)
 
 IF(NOT WITH_GAMEENGINE AND WITH_PLAYER)
   MESSAGE("WARNING: WITH_PLAYER needs WITH_GAMEENGINE")
@@ -184,6 +185,13 @@ IF(UNIX)
 
   SET(LLIBS "-lXi -lutil -lc -lm -lpthread -lstdc++")
 
+  IF(WITH_OPENMP)
+    SET(LLIBS "${LLIBS} -lgomp ")
+    SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fopenmp ")
+    SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp ")
+  ENDIF(WITH_OPENMP)
+
+
   SET(PLATFORM_CFLAGS "-pipe -fPIC -funsigned-char -fno-strict-aliasing -DXP_UNIX -Wno-char-subscripts")
 
   SET(PLATFORM_LINKFLAGS "-pthread")
@@ -270,6 +278,11 @@ IF(WIN32)
   SET(CMAKE_C_FLAGS_MINSIZEREL "/D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /wd4800 /wd4244 /wd4305 /O1 /Ob1 /DNDEBUG /EHsc /MT /W3 /nologo /J" CACHE STRING "MSVC MT flags " FORCE)
   SET(CMAKE_C_FLAGS_RELWITHDEBINFO "/D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /wd4800 /wd4244 /wd4305 /O2 /Ob1 /DNDEBUG /EHsc /MT /W3 /nologo /Zi /J" CACHE STRING "MSVC MT flags " FORCE)
 
+  IF(WITH_OPENMP)
+    SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /openmp ")
+    SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /openmp ")
+  ENDIF(WITH_OPENMP)
+
   SET(SDL ${LIBDIR}/sdl)
   SET(SDL_INC ${SDL}/include)
   SET(SDL_LIB SDL)
@@ -347,6 +360,12 @@ IF(APPLE)
   SET(PLATFORM_CFLAGS "-pipe -fPIC -funsigned-char -fno-strict-aliasing")
   SET(PLATFORM_LINKFLAGS "-fexceptions -framework CoreServices -framework Foundation -framework IOKit -framework AppKit -framework Carbon -framework AGL -framework AudioUnit -framework AudioToolbox -framework CoreAudio -framework QuickTime")
 
+  IF(WITH_OPENMP)
+    SET(LLIBS "${LLIBS} -lgomp ")
+    SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fopenmp ")
+    SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp ")
+  ENDIF(WITH_OPENMP)
+
   SET(SDL ${LIBDIR}/sdl)
   SET(SDL_INC ${SDL}/include)
   SET(SDL_LIB SDL)
index b122347998dfa127094adf5b10d05ef269476829..eb1f33ae6005429d14acfd0a97ef9b28558f370d 100644 (file)
 #ifndef BKE_CLOTH_H
 #define BKE_CLOTH_H
 
-#include "BKE_customdata.h"
 #include "BLI_linklist.h"
+#include "BKE_customdata.h"
 #include "BKE_DerivedMesh.h"
-#include "BKE_object.h"
-
 #include "DNA_cloth_types.h"
 #include "DNA_customdata_types.h"
 #include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_object_types.h"
 
 struct Object;
 struct Cloth;
@@ -49,8 +49,8 @@ struct MFace;
 struct DerivedMesh;
 struct ClothModifierData;
 
-// this is needed for inlining behaviour
 
+// this is needed for inlining behaviour
 #ifndef _WIN32
 #define LINUX
 #define DO_INLINE inline
@@ -60,71 +60,6 @@ struct ClothModifierData;
 
 #define CLOTH_MAX_THREAD 2
 
-typedef struct fc
-{
-       float *d, *d0;                  // density
-       float *T, *T0;                  // temperature
-       float *u, *u0;                  // velocity in x direction
-       float *v, *v0;                  // velocity in y direction
-       float *w, *w0;                  // velocity in z direction
-       unsigned char* _texture_data;   
-       float _light_dir[3];
-       int _ray_templ[4096][3];
-       FILE* _fp;
-       int _cur_frame;
-       int _nframes;
-} fc;
-fc *f_init(void);
-void f_free(fc *m_fc);
-void step(fc *m_fc, float dt);
-
-
-typedef struct ClothVertex {
-       int     flags;          /* General flags per vertex.            */
-       float   mass;           /* mass / weight of the vertex          */
-       float   goal;           /* goal, from SB                        */
-       float   impulse[3];     /* used in collision.c */
-       unsigned int impulse_count; /* same as above */
-       float collball;
-       char octantflag;
-       float weight;
-} ClothVertex;
-
-typedef struct ClothSpring {
-       unsigned int    ij;             /* Pij from the paper, one end of the spring.   */
-       unsigned int    kl;             /* Pkl from the paper, one end of the spring.   */
-       float   restlen;        /* The original length of the spring.   */
-       unsigned int    matrix_index;   /* needed for implicit solver (fast lookup) */
-       int     type;           /* types defined in BKE_cloth.h ("springType") */
-       int     flags;          /* defined in BKE_cloth.h, e.g. deactivated due to tearing */
-       float dfdx[3][3];
-       float dfdv[3][3];
-       float f[3];
-} ClothSpring;
-
-typedef struct Cloth {
-       struct ClothVertex      *verts;                 /* The vertices that represent this cloth. */
-       struct LinkNode         *springs;               /* The springs connecting the mesh. */
-       struct BVH              *tree;          /* collision tree for this cloth object */
-       struct BVH              *selftree;              /* self collision tree for this cloth object */
-       struct MFace            *mfaces;
-       struct Implicit_Data    *implicit;      /* our implicit solver connects to this pointer */
-       struct EdgeHash         *edgehash; /* used for fast checking adjacent points */
-       unsigned int            numverts;               /* The number of verts == m * n. */
-       unsigned int            numsprings;             /* The count of springs. */
-       unsigned int            numfaces;
-       unsigned int            numothersprings;
-       unsigned int            numspringssave;
-       unsigned int            old_solver_type;
-       float                   (*x)[3]; /* The current position of all vertices.*/
-       float                   (*xold)[3]; /* The previous position of all vertices.*/
-       float                   (*current_x)[3]; /* The TEMPORARY current position of all vertices.*/
-       float                   (*current_xold)[3]; /* The TEMPORARY previous position of all vertices.*/
-       float                   (*v)[4]; /* the current velocity of all vertices */
-       float                   (*current_v)[3];
-       float                   (*xconst)[3];
-       struct fc               *m_fc;
-} Cloth;
 
 /* goal defines */
 #define SOFTGOALSNAP  0.999f
@@ -155,9 +90,7 @@ typedef enum
     CLOTH_SIMSETTINGS_FLAG_COLLOBJ = ( 1 << 2 ),       // object is only collision object, no cloth simulation is done
     CLOTH_SIMSETTINGS_FLAG_GOAL = ( 1 << 3 ),          // we have goals enabled
     CLOTH_SIMSETTINGS_FLAG_TEARING = ( 1 << 4 ), // true if tearing is enabled
-    CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT = ( 1 << 5 ),
-    CLOTH_SIMSETTINGS_FLAG_BIG_FORCE = ( 1 << 6 ), // true if we have big spring force for bending
-    CLOTH_SIMSETTINGS_FLAG_SLEEP = ( 1 << 7 ), // true if we let the cloth go to sleep
+    CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT = ( 1 << 5 ), // true if tearing is enabled
 } CLOTH_SIMSETTINGS_FLAGS;
 
 /* SPRING FLAGS */
@@ -172,7 +105,6 @@ typedef enum
     CLOTH_SPRING_TYPE_STRUCTURAL = 0,
     CLOTH_SPRING_TYPE_SHEAR,
     CLOTH_SPRING_TYPE_BENDING,
-    CLOTH_SPRING_TYPE_COLLISION,
 } CLOTH_SPRING_TYPES;
 
 /* SPRING FLAGS */
@@ -188,32 +120,91 @@ typedef enum
 
 
 // needed for buttons_object.c
-void cloth_clear_cache(struct Object *ob, struct ClothModifierData *clmd, float framenr);
-void cloth_free_modifier ( struct ClothModifierData *clmd );
+void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr);
 
 // needed for cloth.c
-void implicit_set_positions ( struct ClothModifierData *clmd );
+void implicit_set_positions ( ClothModifierData *clmd );
 
 // from cloth.c, needed for modifier.c
-DerivedMesh *clothModifier_do(struct ClothModifierData *clmd, struct Object *ob, struct DerivedMesh *dm, int useRenderParams, int isFinalCalc);
+void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, float ( *vertexCos ) [3], int numverts );
+
+// used in collision.c
+typedef struct Tree
+{
+       struct Tree *nodes[4]; // 4 children --> quad-tree
+       struct Tree *parent;
+       struct Tree *nextLeaf;
+       struct Tree *prevLeaf;
+       float   bv[26]; // Bounding volume of all nodes / we have 7 axes on a 14-DOP
+       unsigned int tri_index; // this saves the index of the face
+       int     count_nodes; // how many nodes are used
+       int     traversed;  // how many nodes already traversed until this level?
+       int     isleaf;
+}
+Tree;
+
+typedef struct Tree TreeNode;
+
+typedef struct BVH
+{
+       unsigned int    numfaces;
+       unsigned int    numverts;
+       ClothVertex     *verts; // just a pointer to the original datastructure
+       MFace           *mfaces; // just a pointer to the original datastructure
+       struct LinkNode *tree;
+       TreeNode        *root; // TODO: saving the root --> is this really needed? YES!
+       TreeNode        *leaf_tree; /* Tail of the leaf linked list.    */
+       TreeNode        *leaf_root;     /* Head of the leaf linked list.        */
+       float           epsilon; /* epslion is used for inflation of the k-dop     */
+       int             flags; /* bvhFlags */
+}
+BVH;
+
+typedef void ( *CM_COLLISION_RESPONSE ) ( ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree * tree1, Tree * tree2 );
+
+
+/////////////////////////////////////////////////
+// collision.c
+////////////////////////////////////////////////
 
-// needed in implicit.c
-int cloth_bvh_objcollision(struct ClothModifierData *clmd, float step, float prevstep, float dt);
+// needed for implicit.c
+void bvh_collision_response ( ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree * tree1, Tree * tree2 );
+int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt );
 
 ////////////////////////////////////////////////
 
 
+/////////////////////////////////////////////////
+// kdop.c
+////////////////////////////////////////////////
+
+// needed for cloth.c
+void bvh_free ( BVH * bvh );
+BVH *bvh_build ( ClothModifierData *clmd, float epsilon );
+LinkNode *BLI_linklist_append_fast ( LinkNode **listp, void *ptr );
+
+// needed for collision.c
+int bvh_traverse ( ClothModifierData * clmd, ClothModifierData * coll_clmd, Tree * tree1, Tree * tree2, float step, CM_COLLISION_RESPONSE collision_response );
+void bvh_update ( ClothModifierData * clmd, BVH * bvh, int moving );
+
+////////////////////////////////////////////////
+
+
+
 /////////////////////////////////////////////////
 // cloth.c
 ////////////////////////////////////////////////
-void cloth_free_modifier ( struct ClothModifierData *clmd );
-void cloth_init ( struct ClothModifierData *clmd );
+void cloth_free_modifier ( ClothModifierData *clmd );
+void cloth_init ( ClothModifierData *clmd );
+void cloth_deform_verts ( struct Object *ob, float framenr, float ( *vertexCos ) [3], int numVerts, void *derivedData, ClothModifierData *clmd );
+void cloth_update_normals ( ClothVertex *verts, int nVerts, MFace *face, int totface );
+
 ////////////////////////////////////////////////
 
 
 /* Typedefs for function pointers we need for solvers and collision detection. */
-typedef void ( *CM_COLLISION_SELF ) ( struct ClothModifierData *clmd, int step );
-// typedef void ( *CM_COLLISION_OBJ ) ( ClothModifierData *clmd, int step, CM_COLLISION_RESPONSE collision_response );
+typedef void ( *CM_COLLISION_SELF ) ( ClothModifierData *clmd, int step );
+typedef void ( *CM_COLLISION_OBJ ) ( ClothModifierData *clmd, int step, CM_COLLISION_RESPONSE collision_response );
 
 
 /* This enum provides the IDs for our solvers. */
@@ -229,26 +220,29 @@ typedef struct
 {
        char            *name;
        CM_SOLVER_ID    id;
-       int     ( *init ) ( struct Object *ob, struct ClothModifierData *clmd );
-       int     ( *solver ) ( struct Object *ob, float framenr, struct ClothModifierData *clmd, struct ListBase *effectors );
-       int     ( *free ) ( struct ClothModifierData *clmd );
+       int     ( *init ) ( Object *ob, ClothModifierData *clmd );
+       int     ( *solver ) ( Object *ob, float framenr, ClothModifierData *clmd, ListBase *effectors );
+       int     ( *free ) ( ClothModifierData *clmd );
 }
 CM_SOLVER_DEF;
 
 
 /* new C implicit simulator */
-int implicit_init ( struct Object *ob, struct ClothModifierData *clmd );
-int implicit_free ( struct ClothModifierData *clmd );
-int implicit_solver ( struct Object *ob, float frame, struct ClothModifierData *clmd, struct ListBase *effectors );
-
-/* explicit verlet simulator */
-int verlet_init ( struct Object *ob, struct ClothModifierData *clmd );
-int verlet_free ( struct ClothModifierData *clmd );
-int verlet_solver ( struct Object *ob, float frame, struct ClothModifierData *clmd, struct ListBase *effectors );
+int implicit_init ( Object *ob, ClothModifierData *clmd );
+int implicit_free ( ClothModifierData *clmd );
+int implicit_solver ( Object *ob, float frame, ClothModifierData *clmd, ListBase *effectors );
 
+/* used for caching in implicit.c */
+typedef struct Frame
+{
+       ClothVertex *verts;
+       ClothSpring *springs;
+       unsigned int numverts, numsprings;
+       float time; /* we need float since we want to support sub-frames */
+}
+Frame;
 
 /* used for collisions in collision.c */
-/*
 typedef struct CollPair
 {
        unsigned int face1; // cloth face
@@ -263,7 +257,6 @@ typedef struct CollPair
        unsigned int pointsb[4];
 }
 CollPair;
-*/
 
 /* used for collisions in collision.c */
 typedef struct EdgeCollPair
@@ -289,8 +282,5 @@ typedef struct FaceCollPair
 }
 FaceCollPair;
 
-// function definitions from implicit.c
-DO_INLINE void mul_fvector_S(float to[3], float from[3], float scalar);
-
 #endif
 
index 8927584de1b04779ff34d46c193488d86dc45afb..682eb1a00dda5baddbcdac4bd518e624e0ce5ebc 100644 (file)
@@ -287,7 +287,7 @@ int           modifiers_getCageIndex(struct Object *ob,
                                      int *lastPossibleCageIndex_r);
 
 int           modifiers_isSoftbodyEnabled(struct Object *ob);
-struct ClothModifierData *modifiers_isClothEnabled(Object *ob);
+ModifierData * modifiers_isClothEnabled(Object *ob);
 int           modifiers_isParticleEnabled(struct Object *ob);
 
 struct Object *modifiers_isDeformedByArmature(struct Object *ob);
index 318d6eac41049705e9433345c912b07bf029a6ac..fef932174a1f8e46781d314aff3713aa311c490a 100644 (file)
 
 /* types */
 #include "DNA_curve_types.h"
-#include "DNA_cloth_types.h"
 #include "DNA_object_types.h"
 #include "DNA_object_force.h"
+#include "DNA_cloth_types.h"
 #include "DNA_key_types.h"
-#include "DNA_lattice_types.h"
 #include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
-#include "DNA_modifier_types.h"
+#include "DNA_lattice_types.h"
 #include "DNA_scene_types.h"
+#include "DNA_modifier_types.h"
 
 #include "BLI_blenlib.h"
 #include "BLI_arithb.h"
@@ -55,8 +55,6 @@
 #include "BLI_linklist.h"
 
 #include "BKE_curve.h"
-#include "BKE_cloth.h"
-#include "BKE_collisions.h"
 #include "BKE_deform.h"
 #include "BKE_DerivedMesh.h"
 #include "BKE_cdderivedmesh.h"
 #include "BKE_global.h"
 #include "BKE_key.h"
 #include "BKE_mesh.h"
-#include "BKE_modifier.h"
 #include "BKE_object.h"
-#include "BKE_pointcache.h"
+#include "BKE_cloth.h"
+#include "BKE_modifier.h"
 #include "BKE_utildefines.h"
-
+#include "BKE_DerivedMesh.h"
 #include "BIF_editdeform.h"
 #include "BIF_editkey.h"
 #include "DNA_screen_types.h"
 #include "BIF_space.h"
 #include "mydevice.h"
 
-#ifdef WIN32
-#include <windows.h>
-#endif // WIN32
-#ifdef __APPLE__
-#define GL_GLEXT_LEGACY 1
-#include <OpenGL/gl.h>
-#include <OpenGL/glu.h>
-#else
-#include <GL/gl.h>
-#if defined(__sun__) && !defined(__sparc__)
-#include <mesa/glu.h>
-#else
-#include <GL/glu.h>
-#endif
-#endif
+#include "BKE_pointcache.h"
 
 #ifdef _WIN32
 void tstart ( void )
@@ -106,9 +90,9 @@ double tval()
 }
 #else
 #include <sys/time.h>
-                        static struct timeval _tstart, _tend;
-        static struct timezone tz;
-        void tstart ( void )
+static struct timeval _tstart, _tend;
+static struct timezone tz;
+void tstart ( void )
 {
        gettimeofday ( &_tstart, &tz );
 }
@@ -128,82 +112,88 @@ double tval()
 /* Our available solvers. */
 // 255 is the magic reserved number, so NEVER try to put 255 solvers in here!
 // 254 = MAX!
-static CM_SOLVER_DEF solvers [] =
-{
-       { "Implicit", CM_IMPLICIT, implicit_init, implicit_solver, implicit_free },
-};
+static CM_SOLVER_DEF   solvers [] =
+    {
+        { "Implicit", CM_IMPLICIT, implicit_init, implicit_solver, implicit_free },
+        // { "Implicit C++", CM_IMPLICITCPP, implicitcpp_init, implicitcpp_solver, implicitcpp_free },
+    };
 
 /* ********** cloth engine ******* */
 /* Prototypes for internal functions.
 */
-static void cloth_to_object (Object *ob,  DerivedMesh *dm, ClothModifierData *clmd);
-static void cloth_from_mesh (Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float framenr);
-static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, DerivedMesh *olddm, float framenr);
+static void cloth_to_object ( Object *ob, ClothModifierData *clmd, float ( *vertexCos ) [3], unsigned int numverts );
+static void cloth_from_mesh ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm );
+static int cloth_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float ( *vertexCos ) [3], unsigned int numverts, float framenr );
+static int collobj_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float ( *vertexCos ) [3], unsigned int numverts );
+int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm );
+static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm, short vgroup );
+
 
-int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm );
-static void cloth_apply_vgroup(ClothModifierData *clmd, DerivedMesh *dm, short vgroup);
 /******************************************************************************
 *
 * External interface called by modifier.c clothModifier functions.
 *
 ******************************************************************************/
 /**
- * cloth_init -  creates a new cloth simulation.
- *
- * 1. create object
- * 2. fill object with standard values or with the GUI settings if given 
- */
-void cloth_init (ClothModifierData *clmd)
+* cloth_init -  creates a new cloth simulation.
+*
+* 1. create object
+* 2. fill object with standard values or with the GUI settings if given
+*/
+void cloth_init ( ClothModifierData *clmd )
 {
        /* Initialize our new data structure to reasonable values. */
-       clmd->sim_parms->gravity [0] = 0.0;
-       clmd->sim_parms->gravity [1] = 0.0;
-       clmd->sim_parms->gravity [2] = -9.81;
-       clmd->sim_parms->structural = 100.0;
-       clmd->sim_parms->shear = 100.0;
-       clmd->sim_parms->bending = 1.0;
-       clmd->sim_parms->Cdis = 5.0;
-       clmd->sim_parms->Cvi = 1.0;
-       clmd->sim_parms->mass = 1.0f;
-       clmd->sim_parms->stepsPerFrame = 5;
-       clmd->sim_parms->sim_time = 1.0;
-       clmd->sim_parms->flags = CLOTH_SIMSETTINGS_FLAG_RESET;
-       clmd->sim_parms->solver_type = 0; 
-       clmd->sim_parms->preroll = 0;
-       clmd->sim_parms->maxspringlen = 10;
-       clmd->coll_parms->self_friction = 5.0;
-       clmd->coll_parms->friction = 10.0;
-       clmd->coll_parms->loop_count = 1;
-       clmd->coll_parms->epsilon = 0.01;
-       clmd->coll_parms->selfepsilon = 0.49;
-       
+       clmd->sim_parms.gravity [0] = 0.0;
+       clmd->sim_parms.gravity [1] = 0.0;
+       clmd->sim_parms.gravity [2] = -9.81;
+       clmd->sim_parms.structural = 100.0;
+       clmd->sim_parms.shear = 100.0;
+       clmd->sim_parms.bending = 1.0;
+       clmd->sim_parms.Cdis = 5.0;
+       clmd->sim_parms.Cvi = 1.0;
+       clmd->sim_parms.mass = 1.0f;
+       clmd->sim_parms.stepsPerFrame = 5;
+       clmd->sim_parms.sim_time = 1.0;
+       clmd->sim_parms.flags = CLOTH_SIMSETTINGS_FLAG_RESET;
+       clmd->sim_parms.solver_type = 0;
+       clmd->sim_parms.preroll = 0;
+       clmd->sim_parms.maxspringlen = 10;
+       clmd->sim_parms.firstframe = 1;
+       clmd->sim_parms.lastframe = 250;
+       clmd->coll_parms.self_friction = 5.0;
+       clmd->coll_parms.friction = 10.0;
+       clmd->coll_parms.loop_count = 1;
+       clmd->coll_parms.epsilon = 0.01f;
+       clmd->coll_parms.flags = 0;
+
        /* These defaults are copied from softbody.c's
        * softbody_calc_forces() function.
        */
-       clmd->sim_parms->eff_force_scale = 1000.0;
-       clmd->sim_parms->eff_wind_scale = 250.0;
+       clmd->sim_parms.eff_force_scale = 1000.0;
+       clmd->sim_parms.eff_wind_scale = 250.0;
 
        // also from softbodies
-       clmd->sim_parms->maxgoal = 1.0;
-       clmd->sim_parms->mingoal = 0.0;
-       clmd->sim_parms->defgoal = 0.0;
-       clmd->sim_parms->goalspring = 100.0;
-       clmd->sim_parms->goalfrict = 0.0;
+       clmd->sim_parms.maxgoal = 1.0f;
+       clmd->sim_parms.mingoal = 0.0f;
+       clmd->sim_parms.defgoal = 0.7f;
+       clmd->sim_parms.goalspring = 100.0f;
+       clmd->sim_parms.goalfrict = 0.0f;
+
+       clmd->sim_parms.cache = NULL;
 }
 
 // unused in the moment, cloth needs quads from mesh
-DerivedMesh *CDDM_convert_to_triangle(DerivedMesh *dm)
+DerivedMesh *CDDM_convert_to_triangle ( DerivedMesh *dm )
 {
-       /*
        DerivedMesh *result = NULL;
        int i;
-       int numverts = dm->getNumVerts(dm);
-       int numedges = dm->getNumEdges(dm);
-       int numfaces = dm->getNumFaces(dm);
+       int numverts = dm->getNumVerts ( dm );
+       int numedges = dm->getNumEdges ( dm );
+       int numfaces = dm->getNumFaces ( dm );
 
-       MVert *mvert = CDDM_get_verts(dm);
-       MEdge *medge = CDDM_get_edges(dm);
-       MFace *mface = CDDM_get_faces(dm);
+       MVert *mvert = CDDM_get_verts ( dm );
+       MEdge *medge = CDDM_get_edges ( dm );
+       MFace *mface = CDDM_get_faces ( dm );
 
        MVert *mvert2;
        MFace *mface2;
@@ -215,121 +205,118 @@ DerivedMesh *CDDM_convert_to_triangle(DerivedMesh *dm)
        float vec1[3], vec2[3], vec3[3], vec4[3], vec5[3];
        float mag1=0, mag2=0;
 
-       for(i = 0; i < numfaces; i++)
+       for ( i = 0; i < numfaces; i++ )
        {
-       if(mface[i].v4)
-       numquads++;
-       else
-       numtris++;      
-}
+               if ( mface[i].v4 )
+                       numquads++;
+               else
+                       numtris++;
+       }
 
-       result = CDDM_from_template(dm, numverts, 0, numtris + 2*numquads);
+       result = CDDM_from_template ( dm, numverts, 0, numtris + 2*numquads );
 
-       if(!result)
-       return NULL;
+       if ( !result )
+               return NULL;
 
        // do verts
-       mvert2 = CDDM_get_verts(result);
-       for(a=0; a<numverts; a++) 
+       mvert2 = CDDM_get_verts ( result );
+       for ( a=0; a<numverts; a++ )
        {
-       MVert *inMV;
-       MVert *mv = &mvert2[a];
+               MVert *inMV;
+               MVert *mv = &mvert2[a];
 
-       inMV = &mvert[a];
+               inMV = &mvert[a];
 
-       DM_copy_vert_data(dm, result, a, a, 1);
-       *mv = *inMV;
-}
+               DM_copy_vert_data ( dm, result, a, a, 1 );
+               *mv = *inMV;
+       }
 
 
        // do faces
-       mface2 = CDDM_get_faces(result);
-       for(a=0, i=0; a<numfaces; a++) 
+       mface2 = CDDM_get_faces ( result );
+       for ( a=0, i=0; a<numfaces; a++ )
        {
-       MFace *mf = &mface2[i];
-       MFace *inMF;
-       inMF = &mface[a];
+               MFace *mf = &mface2[i];
+               MFace *inMF;
+               inMF = &mface[a];
 
-               
-               // DM_copy_face_data(dm, result, a, i, 1);
+               /*
+               DM_copy_face_data(dm, result, a, i, 1);
 
-               // *mf = *inMF;
-               
+               *mf = *inMF;
+               */
 
-       if(mface[a].v4 && random==1)
-       {
-       mf->v1 = mface[a].v2;
-       mf->v2 = mface[a].v3;
-       mf->v3 = mface[a].v4;
-}
-       else
-       {
-       mf->v1 = mface[a].v1;
-       mf->v2 = mface[a].v2;
-       mf->v3 = mface[a].v3;
-}
+               if ( mface[a].v4 && random==1 )
+               {
+                       mf->v1 = mface[a].v2;
+                       mf->v2 = mface[a].v3;
+                       mf->v3 = mface[a].v4;
+               }
+               else
+               {
+                       mf->v1 = mface[a].v1;
+                       mf->v2 = mface[a].v2;
+                       mf->v3 = mface[a].v3;
+               }
 
-       mf->v4 = 0;
-       mf->flag |= ME_SMOOTH;
+               mf->v4 = 0;
+               mf->flag |= ME_SMOOTH;
 
-       test_index_face(mf, NULL, 0, 3);
+               test_index_face ( mf, NULL, 0, 3 );
 
-       if(mface[a].v4)
-       {
-       MFace *mf2;
+               if ( mface[a].v4 )
+               {
+                       MFace *mf2;
 
-       i++;
+                       i++;
 
-       mf2 = &mface2[i];
-                       
-                       // DM_copy_face_data(dm, result, a, i, 1);
+                       mf2 = &mface2[i];
+                       /*
+                       DM_copy_face_data(dm, result, a, i, 1);
 
-                       // *mf2 = *inMF;
-                       
+                       *mf2 = *inMF;
+                       */
 
-       if(random==1)
-       {
-       mf2->v1 = mface[a].v1;
-       mf2->v2 = mface[a].v2;
-       mf2->v3 = mface[a].v4;
-}
-       else
-       {
-       mf2->v1 = mface[a].v4;
-       mf2->v2 = mface[a].v1;
-       mf2->v3 = mface[a].v3;
-}
-       mf2->v4 = 0;
-       mf2->flag |= ME_SMOOTH;
+                       if ( random==1 )
+                       {
+                               mf2->v1 = mface[a].v1;
+                               mf2->v2 = mface[a].v2;
+                               mf2->v3 = mface[a].v4;
+                       }
+                       else
+                       {
+                               mf2->v1 = mface[a].v4;
+                               mf2->v2 = mface[a].v1;
+                               mf2->v3 = mface[a].v3;
+                       }
+                       mf2->v4 = 0;
+                       mf2->flag |= ME_SMOOTH;
 
-       test_index_face(mf2, NULL, 0, 3);
-}
+                       test_index_face ( mf2, NULL, 0, 3 );
+               }
 
-       i++;
-}
+               i++;
+       }
 
-       CDDM_calc_edges(result);
-       CDDM_calc_normals(result);
+       CDDM_calc_edges ( result );
+       CDDM_calc_normals ( result );
 
        return result;
-       */
-       
-       return NULL;
+
 }
 
 
-DerivedMesh *CDDM_create_tearing(ClothModifierData *clmd, DerivedMesh *dm)
+DerivedMesh *CDDM_create_tearing ( ClothModifierData *clmd, DerivedMesh *dm )
 {
-       /*
        DerivedMesh *result = NULL;
        unsigned int i = 0, a = 0, j=0;
-       int numverts = dm->getNumVerts(dm);
-       int numedges = dm->getNumEdges(dm);
-       int numfaces = dm->getNumFaces(dm);
+       int numverts = dm->getNumVerts ( dm );
+       int numedges = dm->getNumEdges ( dm );
+       int numfaces = dm->getNumFaces ( dm );
 
-       MVert *mvert = CDDM_get_verts(dm);
-       MEdge *medge = CDDM_get_edges(dm);
-       MFace *mface = CDDM_get_faces(dm);
+       MVert *mvert = CDDM_get_verts ( dm );
+       MEdge *medge = CDDM_get_edges ( dm );
+       MFace *mface = CDDM_get_faces ( dm );
 
        MVert *mvert2;
        MFace *mface2;
@@ -339,91 +326,90 @@ DerivedMesh *CDDM_create_tearing(ClothModifierData *clmd, DerivedMesh *dm)
        Cloth *cloth = clmd->clothObject;
        ClothSpring *springs = cloth->springs;
        unsigned int numsprings = cloth->numsprings;
-       
+
        // create spring tearing hash
        edgehash = BLI_edgehash_new();
-       
-       for(i = 0; i < numsprings; i++)
-       {
-       if((springs[i].flags & CSPRING_FLAG_DEACTIVATE)
-       &&(!BLI_edgehash_haskey(edgehash, springs[i].ij, springs[i].kl)))
+
+       for ( i = 0; i < numsprings; i++ )
        {
-       BLI_edgehash_insert(edgehash, springs[i].ij, springs[i].kl, NULL);
-       BLI_edgehash_insert(edgehash, springs[i].kl, springs[i].ij, NULL);
-       j++;
-}
-}
-       
+               if ( ( springs[i].flags & CLOTH_SPRING_FLAG_DEACTIVATE )
+                       && ( !BLI_edgehash_haskey ( edgehash, springs[i].ij, springs[i].kl ) ) )
+               {
+                       BLI_edgehash_insert ( edgehash, springs[i].ij, springs[i].kl, NULL );
+                       BLI_edgehash_insert ( edgehash, springs[i].kl, springs[i].ij, NULL );
+                       j++;
+               }
+       }
+
        // printf("found %d tears\n", j);
-       
-       result = CDDM_from_template(dm, numverts, 0, numfaces);
 
-       if(!result)
-       return NULL;
+       result = CDDM_from_template ( dm, numverts, 0, numfaces );
+
+       if ( !result )
+               return NULL;
 
        // do verts
-       mvert2 = CDDM_get_verts(result);
-       for(a=0; a<numverts; a++) 
+       mvert2 = CDDM_get_verts ( result );
+       for ( a=0; a<numverts; a++ )
        {
-       MVert *inMV;
-       MVert *mv = &mvert2[a];
+               MVert *inMV;
+               MVert *mv = &mvert2[a];
 
-       inMV = &mvert[a];
+               inMV = &mvert[a];
 
-       DM_copy_vert_data(dm, result, a, a, 1);
-       *mv = *inMV;
-}
+               DM_copy_vert_data ( dm, result, a, a, 1 );
+               *mv = *inMV;
+       }
 
 
        // do faces
-       mface2 = CDDM_get_faces(result);
-       for(a=0, i=0; a<numfaces; a++) 
+       mface2 = CDDM_get_faces ( result );
+       for ( a=0, i=0; a<numfaces; a++ )
        {
-       MFace *mf = &mface2[i];
-       MFace *inMF;
-       inMF = &mface[a];
+               MFace *mf = &mface2[i];
+               MFace *inMF;
+               inMF = &mface[a];
 
-               
-               // DM_copy_face_data(dm, result, a, i, 1);
+               /*
+               DM_copy_face_data(dm, result, a, i, 1);
 
-               // *mf = *inMF;
-               
-               
-       if((!BLI_edgehash_haskey(edgehash, mface[a].v1, mface[a].v2))
-       &&(!BLI_edgehash_haskey(edgehash, mface[a].v2, mface[a].v3))
-       &&(!BLI_edgehash_haskey(edgehash, mface[a].v3, mface[a].v4))
-       &&(!BLI_edgehash_haskey(edgehash, mface[a].v4, mface[a].v1)))
-       {
-       mf->v1 = mface[a].v1;
-       mf->v2 = mface[a].v2;
-       mf->v3 = mface[a].v3;
-       mf->v4 = mface[a].v4;
-       
-       test_index_face(mf, NULL, 0, 4);
-       
-       i++;
-}
-}
+               *mf = *inMF;
+               */
 
-       CDDM_lower_num_faces(result, i);
-       CDDM_calc_edges(result);
-       CDDM_calc_normals(result);
-       
-       BLI_edgehash_free(edgehash, NULL);
+               if ( ( !BLI_edgehash_haskey ( edgehash, mface[a].v1, mface[a].v2 ) )
+                       && ( !BLI_edgehash_haskey ( edgehash, mface[a].v2, mface[a].v3 ) )
+                       && ( !BLI_edgehash_haskey ( edgehash, mface[a].v3, mface[a].v4 ) )
+                       && ( !BLI_edgehash_haskey ( edgehash, mface[a].v4, mface[a].v1 ) ) )
+               {
+                       mf->v1 = mface[a].v1;
+                       mf->v2 = mface[a].v2;
+                       mf->v3 = mface[a].v3;
+                       mf->v4 = mface[a].v4;
+
+                       test_index_face ( mf, NULL, 0, 4 );
+
+                       i++;
+               }
+       }
+
+       CDDM_lower_num_faces ( result, i );
+       CDDM_calc_edges ( result );
+       CDDM_calc_normals ( result );
+
+       BLI_edgehash_free ( edgehash, NULL );
 
        return result;
-       */
-       
-       return NULL;
 }
 
+
+
 int modifiers_indexInObject(Object *ob, ModifierData *md_seek);
 
 void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr)
 {
        int stack_index = -1;
        
-       if(!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT))
+       if(!(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT))
        {
                stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd);
                
@@ -447,9 +433,9 @@ static void cloth_write_cache(Object *ob, ClothModifierData *clmd, float framenr
        
        for(a = 0; a < cloth->numverts; a++)
        {
-               fwrite(&cloth->x[a], sizeof(float),4,fp);
-               fwrite(&cloth->xconst[a], sizeof(float),4,fp);
-               fwrite(&cloth->v[a], sizeof(float),4,fp);
+               fwrite(&cloth->verts[a].x, sizeof(float),4,fp);
+               fwrite(&cloth->verts[a].xconst, sizeof(float),4,fp);
+               fwrite(&cloth->verts[a].v, sizeof(float),4,fp);
        }
        
        fclose(fp);
@@ -472,17 +458,17 @@ static int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr)
        else {
                for(a = 0; a < cloth->numverts; a++)
                {
-                       if(fread(&cloth->x[a], sizeof(float), 4, fp) != 4) 
+                       if(fread(&cloth->verts[a].x, sizeof(float), 4, fp) != 4) 
                        {
                                ret = 0;
                                break;
                        }
-                       if(fread(&cloth->xconst[a], sizeof(float), 4, fp) != 4) 
+                       if(fread(&cloth->verts[a].xconst, sizeof(float), 4, fp) != 4) 
                        {
                                ret = 0;
                                break;
                        }
-                       if(fread(&cloth->v[a], sizeof(float), 4, fp) != 4) 
+                       if(fread(&cloth->verts[a].v, sizeof(float), 4, fp) != 4) 
                        {
                                ret = 0;
                                break;
@@ -492,182 +478,200 @@ static int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr)
                fclose(fp);
        }
        
-       if(clmd->sim_parms->solver_type == 0)
+       if(clmd->sim_parms.solver_type == 0)
                implicit_set_positions(clmd);
                
        return ret;
 }
 
-int m_fc_open(ClothModifierData *clmd)
-{
-       Cloth *cloth = clmd->clothObject;
-       int _N;
-       fc *m_fc = NULL;
-       
-       if(!cloth)
-               return 0;
-       
-       m_fc = cloth->m_fc;
-
-       m_fc->_fp = fopen("/home/daniel/Desktop/f32rand.dat", "rb");
-       if (!m_fc->_fp)
-               return 0;
-
-       fread(&_N, sizeof(int), 1, m_fc->_fp);
-       fread(&_N, sizeof(int), 1, m_fc->_fp);
-       printf("Resolution: %dx%dx%d\n", _N, _N, _N);
-       
-       fread(&m_fc->_nframes, sizeof(int), 1, m_fc->_fp);
-       printf("Number of frames: %d\n", m_fc->_nframes);
-       m_fc->_cur_frame = 0;
-       
-       return 1;
-}
-
 
-
-/************************************************
- * clothModifier_do - main simulation function
-************************************************/
-DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc)
+/**
+* cloth_deform_verts - simulates one step, framenr is in frames.
+*
+**/
+void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm,
+                        float ( *vertexCos ) [3], int numverts )
 {
        unsigned int i;
-       unsigned int numverts = -1;
        unsigned int numedges = -1;
        unsigned int numfaces = -1;
        MVert *mvert = NULL;
        MEdge *medge = NULL;
        MFace *mface = NULL;
-       DerivedMesh *result = NULL;
+       DerivedMesh *result = NULL, *result2 = NULL;
        Cloth *cloth = clmd->clothObject;
-       unsigned int framenr = (float)G.scene->r.cfra;
-       float current_time = bsystem_time(ob, (float)G.scene->r.cfra, 0.0);
-       ListBase *effectors = NULL;
-       float deltaTime = current_time - clmd->sim_parms->sim_time;
+       unsigned int framenr = ( float ) G.scene->r.cfra;
+       float current_time = bsystem_time ( ob, ( float ) G.scene->r.cfra, 0.0 );
+       ListBase        *effectors = NULL;
+       ClothVertex *newframe= NULL, *verts;
+       Frame *frame = NULL;
+       LinkNode *search = NULL;
+       float deltaTime = current_time - clmd->sim_parms.sim_time;
+       
+       clmd->sim_parms.ob = ob;
 
-       clmd->sim_parms->dt = 1.0f / (clmd->sim_parms->stepsPerFrame * G.scene->r.frs_sec);
 
-       result = CDDM_copy(dm);
-       
-       if(!result)
-       {
-               return dm;
-       }
-       
-       numverts = result->getNumVerts(result);
-       numedges = result->getNumEdges(result);
-       numfaces = result->getNumFaces(result);
-       mvert = CDDM_get_verts(result);
-       medge = CDDM_get_edges(result);
-       mface = CDDM_get_faces(result);
-
-       clmd->sim_parms->sim_time = current_time;
-       
-       if ( current_time < clmd->sim_parms->firstframe )
-               return result;
-       
        // only be active during a specific period:
        // that's "first frame" and "last frame" on GUI
        /*
-       if ( clmd->clothObject )
-       {
-       if ( clmd->sim_parms->cache )
-       {
-       if ( current_time < clmd->sim_parms->firstframe )
-       {
-       int frametime = cloth_cache_first_frame ( clmd );
-       if ( cloth_cache_search_frame ( clmd, frametime ) )
-       {
-       cloth_cache_get_frame ( clmd, frametime );
-       cloth_to_object ( ob, result, clmd );
-}
-       return result;
-}
-       else if ( current_time > clmd->sim_parms->lastframe )
-       {
-       int frametime = cloth_cache_last_frame ( clmd );
-       if ( cloth_cache_search_frame ( clmd, frametime ) )
+       if ( ! ( clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ ) )
        {
-       cloth_cache_get_frame ( clmd, frametime );
-       cloth_to_object ( ob, result, clmd );
-}
-       return result;
-}
-       else if ( ABS ( deltaTime ) >= 2.0f ) // no timewarps allowed
+               if ( clmd->clothObject )
+               {
+                       if ( clmd->sim_parms.cache )
+                       {
+                               if ( current_time < clmd->sim_parms.firstframe )
+                               {
+                                       int frametime = cloth_cache_first_frame ( clmd );
+                                       if ( cloth_cache_search_frame ( clmd, frametime ) )
+                                       {
+                                               cloth_cache_get_frame ( clmd, frametime );
+                                               cloth_to_object ( ob, clmd, vertexCos, numverts );
+                                       }
+                                       return;
+                               }
+                               else if ( current_time > clmd->sim_parms.lastframe )
+                               {
+                                       int frametime = cloth_cache_last_frame ( clmd );
+                                       if ( cloth_cache_search_frame ( clmd, frametime ) )
+                                       {
+                                               cloth_cache_get_frame ( clmd, frametime );
+                                               cloth_to_object ( ob, clmd, vertexCos, numverts );
+                                       }
+                                       return;
+                               }
+                               else if ( ABS ( deltaTime ) >= 2.0f ) // no timewarps allowed
+                               {
+                                       if ( cloth_cache_search_frame ( clmd, framenr ) )
+                                       {
+                                               cloth_cache_get_frame ( clmd, framenr );
+                                               cloth_to_object ( ob, clmd, vertexCos, numverts );
+                                       }
+                                       clmd->sim_parms.sim_time = current_time;
+                                       return;
+                               }
+                       }
+
+               }
+       }
+       */
+
+       // unused in the moment, calculated seperately in implicit.c
+       clmd->sim_parms.dt = 1.0f / clmd->sim_parms.stepsPerFrame;
+
+       clmd->sim_parms.sim_time = current_time;
+
+       // check if cloth object was some collision object before and needs freeing now
+       if ( ! ( clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ ) && ( clmd->clothObject != NULL ) && ( clmd->clothObject->old_solver_type == 255 ) )
        {
-       if ( cloth_cache_search_frame ( clmd, framenr ) )
+               // temporary set CSIMSETT_FLAG_COLLOBJ flag for proper freeing
+               clmd->sim_parms.flags |= CLOTH_SIMSETTINGS_FLAG_COLLOBJ;
+               cloth_free_modifier ( clmd );
+               clmd->sim_parms.flags &= ~CLOTH_SIMSETTINGS_FLAG_COLLOBJ;
+       }
+
+       // This is for collisions objects: check special case CSIMSETT_FLAG_COLLOBJ
+       if ( clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ )
        {
-       cloth_cache_get_frame ( clmd, framenr );
-       cloth_to_object ( ob, result, clmd );
-}
-       clmd->sim_parms->sim_time = current_time;
-       return result;
-}
-}
-}
-       */
-       
-       if(deltaTime == 1.0f)
+               // save next position + time
+               if ( ( clmd->clothObject == NULL ) || ( numverts != clmd->clothObject->numverts ) )
+               {
+                       if ( !collobj_from_object ( ob, clmd, dm, vertexCos, framenr ) )
+                       {
+                               clmd->sim_parms.flags |= CLOTH_SIMSETTINGS_FLAG_COLLOBJ;
+                               cloth_free_modifier ( clmd );
+                               return;
+                       }
+
+                       if ( clmd->clothObject == NULL )
+                               return;
+
+                       cloth = clmd->clothObject;
+               }
+
+               // Save old position
+               clmd->sim_parms.sim_time_old = clmd->sim_parms.sim_time;
+               clmd->sim_parms.sim_time = current_time;
+
+               verts = cloth->verts;
+
+               for ( i = 0; i < clmd->clothObject->numverts; i++, verts++ )
+               {
+                       // Save the previous position.
+                       VECCOPY ( verts->xold, verts->x );
+                       VECCOPY ( verts->txold, verts->x );
+
+                       // Get the current position.
+                       VECCOPY ( verts->x, vertexCos[i] );
+                       Mat4MulVecfl ( ob->obmat, verts->x );
+
+                       // Compute the vertices "velocity".
+                       // (no dt correction here because of float error)
+                       VECSUB ( verts->v, verts->x, verts->xold );
+               }
+
+               return;
+       }
+
+       if ( deltaTime == 1.0f )
        {
-               if ((clmd->clothObject == NULL) || (numverts != clmd->clothObject->numverts) ) 
+               if ( ( clmd->clothObject == NULL ) || ( numverts != clmd->clothObject->numverts ) )
                {
                        cloth_clear_cache(ob, clmd, 0);
                        
-                       if(!cloth_from_object (ob, clmd, result, dm, framenr))
-                               return result;
+                       if ( !cloth_from_object ( ob, clmd, dm, vertexCos, numverts, framenr ) )
+                               return;
 
-                       if(clmd->clothObject == NULL)
-                               return result;
+                       if ( clmd->clothObject == NULL )
+                               return;
 
                        cloth = clmd->clothObject;
                }
-               /*
-               deltaTime = 0;
-               while( deltaTime < 1.0)
-               {
-                       step(cloth->m_fc, 0.1);
-                       deltaTime+=0.1;
-               }
-               */
-               clmd->clothObject->old_solver_type = clmd->sim_parms->solver_type;
+
+               clmd->clothObject->old_solver_type = clmd->sim_parms.solver_type;
 
                // Insure we have a clmd->clothObject, in case allocation failed.
-               if (clmd->clothObject != NULL) 
+               if ( clmd->clothObject != NULL )
                {
                        if(!cloth_read_cache(ob, clmd, framenr))
                        {
+                               verts = cloth->verts;
+
                                // Force any pinned verts to their constrained location.
-                               // has to be commented for verlet
-                               for ( i = 0; i < clmd->clothObject->numverts; i++ )
+                               for ( i = 0; i < clmd->clothObject->numverts; i++, verts++ )
                                {
                                        // Save the previous position.
-                                       VECCOPY ( cloth->xold[i], cloth->xconst[i] );
-                                       VECCOPY ( cloth->current_xold[i], cloth->x[i] );
+                                       VECCOPY ( verts->xold, verts->xconst );
+                                       VECCOPY ( verts->txold, verts->x );
+
                                        // Get the current position.
-                                       VECCOPY ( cloth->xconst[i], mvert[i].co );
-                                       Mat4MulVecfl ( ob->obmat, cloth->xconst[i] );
+                                       VECCOPY ( verts->xconst, vertexCos[i] );
+                                       Mat4MulVecfl ( ob->obmat, verts->xconst );
                                }
-                               
+
                                tstart();
-                               
-                               /* Call the solver. */
-                               
-                               if (solvers [clmd->sim_parms->solver_type].solver)
-                                       solvers [clmd->sim_parms->solver_type].solver (ob, framenr, clmd, effectors);
-                               
+
+                               // Call the solver.
+                               if ( solvers [clmd->sim_parms.solver_type].solver )
+                                       solvers [clmd->sim_parms.solver_type].solver ( ob, framenr, clmd, effectors );
+
                                tend();
-                               
-                               printf("Cloth simulation time: %f\n", tval());
-                               
+                               printf ( "Cloth simulation time: %f\n", ( float ) tval() );
+
                                cloth_write_cache(ob, clmd, framenr);
+
+                       }
+                       else // just retrieve the cached frame
+                       {
+                               cloth_read_cache(ob, clmd, framenr);
                        }
 
                        // Copy the result back to the object.
-                       cloth_to_object (ob, result, clmd);
-                       
+                       cloth_to_object ( ob, clmd, vertexCos, numverts );
+
                        // bvh_free(clmd->clothObject->tree);
-                       // clmd->clothObject->tree = bvh_build(clmd, clmd->coll_parms->epsilon);
-               } 
+                       // clmd->clothObject->tree = bvh_build(clmd, clmd->coll_parms.epsilon);
+               }
 
        }
        else if ( ( deltaTime <= 0.0f ) || ( deltaTime > 1.0f ) )
@@ -675,147 +679,85 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d
                if ( clmd->clothObject != NULL )
                {
                        if(cloth_read_cache(ob, clmd, framenr))
-                               cloth_to_object (ob, result, clmd);
+                               cloth_to_object ( ob, clmd, vertexCos, numverts );
                }
                else
                {
                        cloth_clear_cache(ob, clmd, 0);
                }
        }
-       
-       cloth = clmd->clothObject;
-       /*
-       if(cloth)
-       {
-               if (_texture_data == NULL)
-                       _texture_data = (unsigned char*) malloc((30+2)*(30+2)*(30+2)*4);
-       
-               for (i=0; i<(30+2)*(30+2)*(30+2); i++) {
-                       _texture_data[(i<<2)] = (unsigned char) (cloth->m_fc->T[i] * 255.0f);
-                       _texture_data[(i<<2)+1] = (unsigned char) (cloth->m_fc->d[i] * 255.0f);
-                       _texture_data[(i<<2)+2] = 0;
-                       _texture_data[(i<<2)+3] = 255;
-               }
-               
-               // from ligth constructor
-               _light_dir[0] = -1.0f;
-               _light_dir[1] = 0.5f;
-               _light_dir[2] = 0.0f;
-               
-               gen_ray_templ(_ray_templ, _light_dir, 30 + 2);
-       
-               cast_light(_texture_data, _ray_templ, _light_dir, 30+2);
-       
-               glActiveTextureARB(GL_TEXTURE0_ARB);
-               glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 30+2, 30+2, 30+2, 0, GL_RGBA, GL_UNSIGNED_BYTE, _texture_data);
-               free(_texture_data);
-       }
-       */
-       return result;
+
 }
 
 /* frees all */
-void cloth_free_modifier (ClothModifierData *clmd)
+void cloth_free_modifier ( ClothModifierData *clmd )
 {
        Cloth   *cloth = NULL;
-
-       if(!clmd)
+       Object *ob = clmd->sim_parms.ob;
+       
+       if ( !clmd )
                return;
 
        cloth = clmd->clothObject;
 
-       // free our frame cache
-       // cloth_clear_cache(ob, clmd, 0);
-
-       /* Calls the solver and collision frees first as they
-       * might depend on data in clmd->clothObject. */
-
-       if (cloth) 
-       {       
-               f_free(cloth->m_fc);
-               
-               // If our solver provides a free function, call it
-               if (cloth->old_solver_type < 255 && solvers [cloth->old_solver_type].free) 
-               {       
-                       solvers [cloth->old_solver_type].free (clmd);
-               }
-               
-               // Free the verts.
-               if (cloth->verts != NULL)
-                       MEM_freeN (cloth->verts);
-               
-               // Free the faces.
-               if ( cloth->mfaces != NULL )
-                       MEM_freeN ( cloth->mfaces );
-               
-               // Free the verts.
-               if ( cloth->x != NULL )
-                       MEM_freeN ( cloth->x );
-               
-               // Free the verts.
-               if ( cloth->xold != NULL )
-                       MEM_freeN ( cloth->xold );
-               
-               // Free the verts.
-               if ( cloth->v != NULL )
-                       MEM_freeN ( cloth->v );
-               
-               // Free the verts.
-               if ( cloth->current_x != NULL )
-                       MEM_freeN ( cloth->current_x );
-               
-               // Free the verts.
-               if ( cloth->current_xold != NULL )
-                       MEM_freeN ( cloth->current_xold );
-               
-               // Free the verts.
-               if ( cloth->current_v != NULL )
-                       MEM_freeN ( cloth->current_v );
-               
-               // Free the verts.
-               if ( cloth->xconst != NULL )
-                       MEM_freeN ( cloth->xconst );
-               
-               cloth->verts = NULL;
-               cloth->numverts = -1;
-               
-               // Free the springs.
-               if ( cloth->springs != NULL )
+       if ( ! ( clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT ) )
+       {
+               if ( cloth )
                {
-                       LinkNode *search = cloth->springs;
-                       while(search)
+                       // free our frame cache, TODO: but get to first position before
+                       if(ob)
+                               cloth_clear_cache ( ob, clmd, 0 );
+                       
+                       // If our solver provides a free function, call it
+                       if ( cloth->old_solver_type < 255 && solvers [cloth->old_solver_type].free )
                        {
-                               ClothSpring *spring = search->link;
-                                               
-                               MEM_freeN ( spring );
-                               search = search->next;
+                               solvers [cloth->old_solver_type].free ( clmd );
                        }
-                       BLI_linklist_free(cloth->springs, NULL);
-               
+
+                       // Free the verts.
+                       if ( cloth->verts != NULL )
+                               MEM_freeN ( cloth->verts );
+
+                       cloth->verts = NULL;
+                       cloth->numverts = 0;
+
+                       // Free the springs.
+                       if ( cloth->springs != NULL )
+                       {
+                               LinkNode *search = cloth->springs;
+                               while(search)
+                               {
+                                       ClothSpring *spring = search->link;
+                                                       
+                                       MEM_freeN ( spring );
+                                       search = search->next;
+                               }
+                               BLI_linklist_free(cloth->springs, NULL);
+                       
+                               cloth->springs = NULL;
+                       }
+
                        cloth->springs = NULL;
+                       cloth->numsprings = 0;
+
+                       // free BVH collision tree
+                       if ( cloth->tree )
+                               bvh_free ( ( BVH * ) cloth->tree );
+
+                       // we save our faces for collision objects
+                       if ( cloth->mfaces )
+                               MEM_freeN ( cloth->mfaces );
+                       /*
+                       if(clmd->clothObject->facemarks)
+                               MEM_freeN(clmd->clothObject->facemarks);
+                       */
+                       MEM_freeN ( cloth );
+                       clmd->clothObject = NULL;
                }
-
-               cloth->numsprings = -1;
-               
-               // free BVH collision tree
-               if(cloth->tree)
-                       bvh_free((BVH *)cloth->tree);
-               
-               // free BVH self collision tree
-               if(cloth->selftree)
-                       bvh_free((BVH *)cloth->selftree);
-               
-               if(cloth->edgehash)
-                       BLI_edgehash_free ( cloth->edgehash, NULL );
-               
-               MEM_freeN (cloth);
-               clmd->clothObject = NULL;
        }
-
 }
 
 
-
 /******************************************************************************
 *
 * Internal functions.
@@ -823,44 +765,42 @@ void cloth_free_modifier (ClothModifierData *clmd)
 ******************************************************************************/
 
 /**
- * cloth_to_object - copies the deformed vertices to the object.
- *
- * This function is a modified version of the softbody.c:softbody_to_object() function.
- **/
-static void cloth_to_object (Object *ob,  DerivedMesh *dm, ClothModifierData *clmd)
+* cloth_to_object - copies the deformed vertices to the object.
+*
+* This function is a modified version of the softbody.c:softbody_to_object() function.
+**/
+static void cloth_to_object ( Object *ob, ClothModifierData *clmd, float ( *vertexCos ) [3], unsigned int numverts )
 {
+       ClothVertex     *verts = NULL;
        unsigned int    i = 0;
-       MVert *mvert = NULL;
-       unsigned int numverts;
-       Cloth *cloth = clmd->clothObject;
 
-       if (clmd->clothObject) {
-               /* inverse matrix is not uptodate... */
-               Mat4Invert (ob->imat, ob->obmat);
+       if ( clmd->clothObject )
+       {
+               verts = clmd->clothObject->verts;
 
-               mvert = CDDM_get_verts(dm);
-               numverts = dm->getNumVerts(dm);
+               /* inverse matrix is not uptodate... */
+               Mat4Invert ( ob->imat, ob->obmat );
 
-               for (i = 0; i < numverts; i++)
+               for ( i = 0; i < numverts; i++, verts++ )
                {
-                       VECCOPY (mvert[i].co, cloth->x[i]);
-                       Mat4MulVecfl (ob->imat, mvert[i].co);   /* cloth is in global coords */
+                       VECCOPY ( vertexCos[i], verts->x );
+                       Mat4MulVecfl ( ob->imat, vertexCos[i] );        /* softbody is in global coords */
                }
        }
 }
 
 
 /**
- * cloth_apply_vgroup - applies a vertex group as specified by type
- *
- **/
-static void cloth_apply_vgroup(ClothModifierData *clmd, DerivedMesh *dm, short vgroup)
+* cloth_apply_vgroup - applies a vertex group as specified by type
+*
+**/
+static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm, short vgroup )
 {
        unsigned int i = 0;
        unsigned int j = 0;
-       MDeformVert     *dvert = NULL;
+       MDeformVert *dvert = NULL;
        Cloth *clothObj = NULL;
-       unsigned int numverts = 0;
+       unsigned int numverts = dm->getNumVerts ( dm );
        float goalfac = 0;
        ClothVertex *verts = NULL;
 
@@ -869,7 +809,7 @@ static void cloth_apply_vgroup(ClothModifierData *clmd, DerivedMesh *dm, short v
        if ( !dm )
                return;
 
-       numverts = dm->getNumVerts(dm);
+       numverts = dm->getNumVerts ( dm );
 
        /* vgroup is 1 based, decrement so we can match the right group. */
        --vgroup;
@@ -879,7 +819,7 @@ static void cloth_apply_vgroup(ClothModifierData *clmd, DerivedMesh *dm, short v
        for ( i = 0; i < numverts; i++, verts++ )
        {
                // LATER ON, support also mass painting here
-               if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )
+               if ( clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL )
                {
                        dvert = dm->getVertData ( dm, i, CD_MDEFORMVERT );
                        if ( dvert )
@@ -890,7 +830,7 @@ static void cloth_apply_vgroup(ClothModifierData *clmd, DerivedMesh *dm, short v
                                        {
                                                verts->goal = dvert->dw [j].weight;
 
-                                               goalfac= ABS ( clmd->sim_parms->maxgoal - clmd->sim_parms->mingoal );
+                                               goalfac= ABS ( clmd->sim_parms.maxgoal - clmd->sim_parms.mingoal );
                                                verts->goal  = ( float ) pow ( verts->goal , 4.0f );
 
                                                if ( dvert->dw [j].weight >=SOFTGOALSNAP )
@@ -907,194 +847,226 @@ static void cloth_apply_vgroup(ClothModifierData *clmd, DerivedMesh *dm, short v
                }
        }
 }
-               
+
 // only meshes supported at the moment
-static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, DerivedMesh *olddm, float framenr)
+/* collision objects */
+static int collobj_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float ( *vertexCos ) [3], unsigned int numverts )
 {
        unsigned int i;
-       unsigned int numverts = dm->getNumVerts(dm);
-       MVert *mvert = CDDM_get_verts(dm);
+       MVert *mvert = NULL;
+       ClothVertex *verts = NULL;
        float tnull[3] = {0,0,0};
-       Cloth *cloth = NULL;
-       
+
        /* If we have a clothObject, free it. */
-       if (clmd->clothObject != NULL)
-               cloth_free_modifier (clmd);
+       if ( clmd->clothObject != NULL )
+               cloth_free_modifier ( clmd );
 
        /* Allocate a new cloth object. */
-       clmd->clothObject = MEM_callocN (sizeof(Cloth), "cloth");
-       if (clmd->clothObject) 
+       clmd->clothObject = MEM_callocN ( sizeof ( Cloth ), "cloth" );
+       if ( clmd->clothObject )
        {
                clmd->clothObject->old_solver_type = 255;
-               clmd->clothObject->edgehash = NULL;
+               // clmd->clothObject->old_collision_type = 255;
        }
-       else if (clmd->clothObject == NULL) 
+       else if ( clmd->clothObject == NULL )
        {
-               modifier_setError (&(clmd->modifier), "Out of memory on allocating clmd->clothObject.");
+               modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject." );
                return 0;
        }
-       
-       cloth = clmd->clothObject;
-       
-       cloth->m_fc = f_init();
 
-       // open file
-       m_fc_open(clmd);
+       switch ( ob->type )
+       {
+               case OB_MESH:
+
+                       // mesh input objects need DerivedMesh
+                       if ( !dm )
+                               return 0;
+
+                       cloth_from_mesh ( ob, clmd, dm );
+
+                       if ( clmd->clothObject != NULL )
+                       {
+                               if ( !dm ) return 0;
+                               if ( !dm->getNumVerts ( dm ) || !dm->getNumFaces ( dm ) ) return 0;
+
+                               mvert = dm->getVertArray ( dm );
+                               verts = clmd->clothObject->verts;
+                               numverts = clmd->clothObject->numverts = dm->getNumVerts ( dm );
+
+                               for ( i = 0; i < numverts; i++, verts++ )
+                               {
+                                       VECCOPY ( verts->x, mvert[i].co );
+                                       Mat4MulVecfl ( ob->obmat, verts->x );
+                                       verts->flags = 0;
+                                       VECCOPY ( verts->xold, verts->x );
+                                       VECCOPY ( verts->txold, verts->x );
+                                       VECCOPY ( verts->tx, verts->x );
+                                       VecMulf ( verts->v, 0.0f );
+                                       verts->impulse_count = 0;
+                                       VECCOPY ( verts->impulse, tnull );
+                               }
+                               clmd->clothObject->tree =  bvh_build ( clmd,clmd->coll_parms.epsilon );
+
+                       }
+
+                       return 1;
+               default: return 0; // TODO - we do not support changing meshes
+       }
+}
+
+/*
+helper function to get proper spring length
+when object is rescaled
+*/
+float cloth_globallen ( float *v1,float *v2,Object *ob )
+{
+       float p1[3],p2[3];
+       VECCOPY ( p1,v1 );
+       Mat4MulVecfl ( ob->obmat, p1 );
+       VECCOPY ( p2,v2 );
+       Mat4MulVecfl ( ob->obmat, p2 );
+       return VecLenf ( p1,p2 );
+}
+
+// only meshes supported at the moment
+static int cloth_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float ( *vertexCos ) [3], unsigned int numverts, float framenr )
+{
+       unsigned int i = 0;
+       // dm->getNumVerts(dm);
+       MVert *mvert = NULL; // CDDM_get_verts(dm);
+       ClothVertex *verts = NULL;
+       float tnull[3] = {0,0,0};
+
+       /* If we have a clothObject, free it. */
+       if ( clmd->clothObject != NULL )
+               cloth_free_modifier ( clmd );
+
+       /* Allocate a new cloth object. */
+       clmd->clothObject = MEM_callocN ( sizeof ( Cloth ), "cloth" );
+       if ( clmd->clothObject )
+       {
+               clmd->clothObject->old_solver_type = 255;
+               // clmd->clothObject->old_collision_type = 255;
+       }
+       else if ( !clmd->clothObject )
+       {
+               modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject." );
+               return 0;
+       }
+       
+       clmd->sim_parms.ob = ob;
 
-       switch (ob->type)
+       switch ( ob->type )
        {
                case OB_MESH:
-               
+
                        // mesh input objects need DerivedMesh
                        if ( !dm )
                                return 0;
 
-                       cloth_from_mesh (ob, clmd, dm, framenr);
+                       cloth_from_mesh ( ob, clmd, dm );
 
                        if ( clmd->clothObject != NULL )
                        {
                                /* create springs */
                                clmd->clothObject->springs = NULL;
                                clmd->clothObject->numsprings = -1;
-                                       
+                               
+                               mvert = CDDM_get_verts ( dm );
+                               verts = clmd->clothObject->verts;
+
                                /* set initial values */
-                               for (i = 0; i < numverts; ++i)
+                               for ( i = 0; i < numverts; i++, verts++ )
                                {
-                                       VECCOPY (clmd->clothObject->x[i], mvert[i].co);
-                                       Mat4MulVecfl(ob->obmat, clmd->clothObject->x[i]);
-       
-                                       clmd->clothObject->verts [i].mass = clmd->sim_parms->mass;
-                                       if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )
-                                               clmd->clothObject->verts [i].goal= clmd->sim_parms->defgoal;
+                                       VECCOPY ( verts->x, mvert[i].co );
+                                       Mat4MulVecfl ( ob->obmat, verts->x );
+
+                                       verts->mass = clmd->sim_parms.mass;
+
+                                       if ( clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL )
+                                               verts->goal= clmd->sim_parms.defgoal;
                                        else
-                                               clmd->clothObject->verts [i].goal= 0.0;
-                                       clmd->clothObject->verts [i].flags = 0;
-                                       VECCOPY(clmd->clothObject->xold[i], clmd->clothObject->x[i]);
-                                       VECCOPY(clmd->clothObject->xconst[i], clmd->clothObject->x[i]);
-                                       VECCOPY(clmd->clothObject->current_xold[i], clmd->clothObject->x[i]);
-                                       VecMulf(clmd->clothObject->v[i], 0.0);
-       
-                                       clmd->clothObject->verts [i].impulse_count = 0;
-                                       VECCOPY ( clmd->clothObject->verts [i].impulse, tnull );
+                                               verts->goal= 0.0f;
+
+                                       verts->flags = 0;
+                                       VECCOPY ( verts->xold, verts->x );
+                                       VECCOPY ( verts->xconst, verts->x );
+                                       VECCOPY ( verts->txold, verts->x );
+                                       VecMulf ( verts->v, 0.0f );
+
+                                       verts->impulse_count = 0;
+                                       VECCOPY ( verts->impulse, tnull );
                                }
                                
-                               if (!cloth_build_springs (clmd, dm) )
+                               if ( !cloth_build_springs ( clmd->clothObject, dm ) )
                                {
-                                       modifier_setError (&(clmd->modifier), "Can't build springs.");
+                                       modifier_setError ( & ( clmd->modifier ), "Can't build springs." );
                                        return 0;
-                               }  
-       
-                               /* apply / set vertex groups */
-                               if (clmd->sim_parms->vgroup_mass > 0)
-                                       cloth_apply_vgroup (clmd, olddm, clmd->sim_parms->vgroup_mass);
-       
-                               /* init our solver */
-                               if (solvers [clmd->sim_parms->solver_type].init)
-                                       solvers [clmd->sim_parms->solver_type].init (ob, clmd);
-       
-                               clmd->clothObject->tree = bvh_build_from_float3(CDDM_get_faces(dm), dm->getNumFaces(dm), clmd->clothObject->x, numverts, clmd->coll_parms->epsilon);
-                               
-                               clmd->clothObject->selftree = bvh_build_from_float3(NULL, 0, clmd->clothObject->x, numverts, clmd->coll_parms->selfepsilon);
-                               
-                               // save initial state
+                               }
+
+                               // apply / set vertex groups
+                               if ( clmd->sim_parms.vgroup_mass > 0 )
+                                       cloth_apply_vgroup ( clmd, dm, clmd->sim_parms.vgroup_mass );
+
+                               // init our solver
+                               if ( solvers [clmd->sim_parms.solver_type].init )
+                                       solvers [clmd->sim_parms.solver_type].init ( ob, clmd );
+
+                               clmd->clothObject->tree = bvh_build ( clmd, clmd->coll_parms.epsilon );
+
                                cloth_write_cache(ob, clmd, framenr-1);
                        }
+
+                       return 1;
+               case OB_LATTICE:
+                       printf ( "Not supported: OB_LATTICE\n" );
+                       // lattice_to_softbody(ob);
+                       return 1;
+               case OB_CURVE:
+               case OB_SURF:
+                       printf ( "Not supported: OB_SURF| OB_CURVE\n" );
                        return 1;
-                       default: return 0; // TODO - we do not support changing meshes
+               default: return 0; // TODO - we do not support changing meshes
        }
-       
+
        return 0;
 }
 
-static void cloth_from_mesh (Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float framenr)
+static void cloth_from_mesh ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm )
 {
-       unsigned int numverts = dm->getNumVerts(dm);
-       unsigned int numfaces = dm->getNumFaces(dm);
-       MFace *mface = CDDM_get_faces(dm);
+       unsigned int numverts = dm->getNumVerts ( dm );
+       unsigned int numfaces = dm->getNumFaces ( dm );
+       MFace *mface = dm->getFaceArray ( dm );
+       unsigned int i = 0;
 
        /* Allocate our vertices.
        */
        clmd->clothObject->numverts = numverts;
-       clmd->clothObject->verts = MEM_callocN (sizeof (ClothVertex) * clmd->clothObject->numverts, "clothVertex");
-       if (clmd->clothObject->verts == NULL) 
-       {
-               cloth_free_modifier (clmd);
-               modifier_setError (&(clmd->modifier), "Out of memory on allocating clmd->clothObject->verts.");
-               return;
-       }
-       
-       clmd->clothObject->x = MEM_callocN ( sizeof ( float ) * clmd->clothObject->numverts * 4, "Cloth MVert_x" );
-       if ( clmd->clothObject->x == NULL )
+       clmd->clothObject->verts = MEM_callocN ( sizeof ( ClothVertex ) * clmd->clothObject->numverts, "clothVertex" );
+       if ( clmd->clothObject->verts == NULL )
        {
                cloth_free_modifier ( clmd );
-               modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->x." );
-               return;
-       }
-       
-       clmd->clothObject->xold = MEM_callocN ( sizeof ( float ) * clmd->clothObject->numverts * 4, "Cloth MVert_xold" );
-       if ( clmd->clothObject->xold == NULL )
-       {
-               cloth_free_modifier ( clmd );
-               modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->xold." );
-               return;
-       }
-       
-       clmd->clothObject->v = MEM_callocN ( sizeof ( float ) * clmd->clothObject->numverts * 4, "Cloth MVert_v" );
-       if ( clmd->clothObject->v == NULL )
-       {
-               cloth_free_modifier ( clmd );
-               modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->v." );
-               return;
-       }
-       
-       clmd->clothObject->current_x = MEM_callocN ( sizeof ( float ) * clmd->clothObject->numverts * 4, "Cloth MVert_current_x" );
-       if ( clmd->clothObject->current_x == NULL )
-       {
-               cloth_free_modifier ( clmd );
-               modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->current_x." );
-               return;
-       }
-       
-       clmd->clothObject->current_xold = MEM_callocN ( sizeof ( float ) * clmd->clothObject->numverts * 4, "Cloth MVert_current_xold" );
-       if ( clmd->clothObject->current_xold == NULL )
-       {
-               cloth_free_modifier ( clmd );
-               modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->current_xold." );
-               return;
-       }
-       
-       clmd->clothObject->current_v = MEM_callocN ( sizeof ( float ) * clmd->clothObject->numverts * 4, "Cloth MVert_current_v" );
-       if ( clmd->clothObject->current_v == NULL )
-       {
-               cloth_free_modifier ( clmd );
-               modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->current_v." );
-               return;
-       }
-       
-       clmd->clothObject->xconst = MEM_callocN ( sizeof ( float ) * clmd->clothObject->numverts * 4, "Cloth MVert_xconst" );
-       if ( clmd->clothObject->xconst == NULL )
-       {
-               cloth_free_modifier ( clmd );
-               modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->xconst." );
+               modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->verts." );
                return;
        }
 
        // save face information
        clmd->clothObject->numfaces = numfaces;
-       clmd->clothObject->mfaces = MEM_callocN (sizeof (MFace) * clmd->clothObject->numfaces, "clothMFaces");
-       if (clmd->clothObject->mfaces == NULL) 
+       clmd->clothObject->mfaces = MEM_callocN ( sizeof ( MFace ) * clmd->clothObject->numfaces, "clothMFaces" );
+       if ( clmd->clothObject->mfaces == NULL )
        {
-               cloth_free_modifier (clmd);
-               modifier_setError (&(clmd->modifier), "Out of memory on allocating clmd->clothObject->mfaces.");
+               cloth_free_modifier ( clmd );
+               modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->mfaces." );
                return;
        }
-       memcpy(clmd->clothObject->mfaces, mface, sizeof(MFace)*numfaces);
+       for ( i = 0; i < numfaces; i++ )
+               memcpy ( &clmd->clothObject->mfaces[i], &mface[i], sizeof ( MFace ) );
 
        /* Free the springs since they can't be correct if the vertices
        * changed.
        */
-       if (clmd->clothObject->springs != NULL)
-               MEM_freeN (clmd->clothObject->springs);
+       if ( clmd->clothObject->springs != NULL )
+               MEM_freeN ( clmd->clothObject->springs );
 
 }
 
@@ -1103,7 +1075,6 @@ static void cloth_from_mesh (Object *ob, ClothModifierData *clmd, DerivedMesh *d
 ***************************************************************************************/
 
 // be carefull: implicit solver has to be resettet when using this one!
-// --> only for implicit handling of this spring!
 int cloth_add_spring ( ClothModifierData *clmd, unsigned int indexA, unsigned int indexB, float restlength, int spring_type)
 {
        Cloth *cloth = clmd->clothObject;
@@ -1130,12 +1101,11 @@ int cloth_add_spring ( ClothModifierData *clmd, unsigned int indexA, unsigned in
        return 0;
 }
 
-int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
+int cloth_build_springs ( Cloth *cloth, 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, j = 0, akku_count;
+       unsigned int i = 0;
        unsigned int numverts = dm->getNumVerts ( dm );
        unsigned int numedges = dm->getNumEdges ( dm );
        unsigned int numfaces = dm->getNumFaces ( dm );
@@ -1145,9 +1115,9 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
        LinkNode **edgelist = NULL;
        EdgeHash *edgehash = NULL;
        LinkNode *search = NULL, *search2 = NULL;
-       float temp[3], akku, min, max;
-       LinkNode *node = NULL, *node2 = NULL;
-       
+       float temp[3];
+       ClothVertex *verts = NULL;
+
        // error handling
        if ( numedges==0 )
                return 0;
@@ -1162,6 +1132,8 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
 
        if ( cloth->springs )
                MEM_freeN ( cloth->springs );
+       
+       verts = cloth->verts;
 
        // create spring network hash
        edgehash = BLI_edgehash_new();
@@ -1175,54 +1147,16 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
                {
                        spring->ij = medge[i].v1;
                        spring->kl = medge[i].v2;
-                       VECSUB ( temp, cloth->x[spring->kl], cloth->x[spring->ij] );
+                       VECSUB ( temp, verts[spring->kl].x, verts[spring->ij].x );
                        spring->restlen =  sqrt ( INPR ( temp, temp ) );
                        spring->type = CLOTH_SPRING_TYPE_STRUCTURAL;
                        spring->flags = 0;
                        struct_springs++;
-                       
-                       if(!i)
-                               node2 = BLI_linklist_append_fast ( &cloth->springs, spring );
-                       else
-                               node2 = BLI_linklist_append_fast ( &node->next, spring );
-                       node = node2;
-               }
-       }
-       
-       // calc collision balls *slow*
-       // better: use precalculated list with O(1) index access to all springs of a vertex
-       // missing for structural since it's not needed for building bending springs
-       for ( i = 0; i < numverts; i++ )
-       {
-               akku_count = 0;
-               akku = 0.0;
-               cloth->verts[i].collball=0;
-               min = 1e22f;
-               max = -1e22f;
-               
-               search = cloth->springs;
-               for ( j = 0; j < struct_springs; j++ )
-               {
-                       if ( !search )
-                               break;
 
-                       tspring = search->link;
-                       
-                       if((tspring->ij == i) || (tspring->kl == i))
-                       {
-                               akku += spring->restlen;
-                               akku_count++;
-                               min = MIN2(spring->restlen,min);
-                               max = MAX2(spring->restlen,max);
-                       }
+                       BLI_linklist_append ( &cloth->springs, spring );
                }
-               
-               if (akku_count > 0) {
-                       cloth->verts[i].collball = akku/(float)akku_count*clmd->coll_parms->selfepsilon;
-               }
-               else cloth->verts[i].collball=0;
        }
-       
+
        // shear springs
        for ( i = 0; i < numfaces; i++ )
        {
@@ -1230,7 +1164,7 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
 
                spring->ij = mface[i].v1;
                spring->kl = mface[i].v3;
-               VECSUB ( temp, cloth->x[spring->kl], cloth->x[spring->ij] );
+               VECSUB ( temp, verts[spring->kl].x, verts[spring->ij].x );
                spring->restlen =  sqrt ( INPR ( temp, temp ) );
                spring->type = CLOTH_SPRING_TYPE_SHEAR;
 
@@ -1238,8 +1172,7 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
                BLI_linklist_append ( &edgelist[spring->kl], spring );
                shear_springs++;
 
-               node2 = BLI_linklist_append_fast ( &node->next, spring );
-               node = node2;
+               BLI_linklist_append ( &cloth->springs, spring );
 
                if ( mface[i].v4 )
                {
@@ -1247,19 +1180,18 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
 
                        spring->ij = mface[i].v2;
                        spring->kl = mface[i].v4;
-                       VECSUB ( temp, cloth->x[spring->kl], cloth->x[spring->ij] );
-                       spring->restlen =  sqrt ( INPR ( temp, temp ) );
-                       spring->type = CLOTH_SPRING_TYPE_SHEAR;
+                       VECSUB ( temp, verts[spring->kl].x, verts[spring->ij].x );
+                               spring->restlen =  sqrt ( INPR ( temp, temp ) );
+                               spring->type = CLOTH_SPRING_TYPE_SHEAR;
 
-                       BLI_linklist_append ( &edgelist[spring->ij], spring );
-                       BLI_linklist_append ( &edgelist[spring->kl], spring );
-                       shear_springs++;
+                               BLI_linklist_append ( &edgelist[spring->ij], spring );
+                               BLI_linklist_append ( &edgelist[spring->kl], spring );
+                               shear_springs++;
 
-                       node2 = BLI_linklist_append_fast ( &node->next, spring );
-                       node = node2;
+                               BLI_linklist_append ( &cloth->springs, spring );
                }
        }
-       
+
        // bending springs
        search2 = cloth->springs;
        for ( i = struct_springs; i < struct_springs+shear_springs; i++ )
@@ -1277,38 +1209,36 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
                        // check for existing spring
                        // check also if startpoint is equal to endpoint
                        if ( !BLI_edgehash_haskey ( edgehash, index2, tspring2->ij )
-                       && !BLI_edgehash_haskey ( edgehash, tspring2->ij, index2 )
-                       && ( index2!=tspring2->ij ) )
+                               && !BLI_edgehash_haskey ( edgehash, tspring2->ij, index2 )
+                               && ( index2!=tspring2->ij ) )
                        {
                                spring = ( ClothSpring * ) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" );
 
                                spring->ij = tspring2->ij;
                                spring->kl = index2;
-                               VECSUB ( temp, cloth->x[index2], cloth->x[tspring2->ij] );
+                               VECSUB ( temp, verts[index2].x, verts[tspring2->ij].x );
                                spring->restlen =  sqrt ( INPR ( temp, temp ) );
                                spring->type = CLOTH_SPRING_TYPE_BENDING;
                                BLI_edgehash_insert ( edgehash, spring->ij, index2, NULL );
                                bend_springs++;
 
-                               node2 = BLI_linklist_append_fast ( &node->next, spring );
-                               node = node2;
+                               BLI_linklist_append ( &cloth->springs, spring );
                        }
                        search = search->next;
                }
                search2 = search2->next;
        }
-       
-       cloth->numspringssave = cloth->numsprings = struct_springs + shear_springs + bend_springs;
-       cloth->numothersprings = struct_springs + shear_springs;
-       
+
+       cloth->numsprings = struct_springs + shear_springs + bend_springs;
+
        for ( i = 0; i < numverts; i++ )
        {
                BLI_linklist_free ( edgelist[i],NULL );
        }
        if ( edgelist )
                MEM_freeN ( edgelist );
-       
-       cloth->edgehash = edgehash;
+
+       BLI_edgehash_free ( edgehash, NULL );
 
        return 1;
 
@@ -1317,344 +1247,3 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
 * SPRING NETWORK BUILDING IMPLEMENTATION END
 ***************************************************************************************/
 
-#define F_ITER 20
-#define m_diffusion 0.00001f
-#define m_viscosity 0.000f
-#define m_buoyancy  1.5f
-#define m_cooling   1.0f
-#define m_vc_eps    4.0f
-
-#define GRID_SIZE 30
-#define SIZE ((GRID_SIZE+2)*(GRID_SIZE+2)*(GRID_SIZE+2))
-#define _I(x,y,z) (((z)<<10)+((y)<<5)+x)
-
-#define SWAPFPTR(x,y) {float *t=x;x=y;y=t;}
-
-float buffers[10][SIZE];
-float sd[SIZE], su[SIZE], sv[SIZE], sw[SIZE], sT[SIZE];
-
-
-// nothing to do in this mode
-// add code for 2nd mode
-void set_bnd(int b, float* x, int N)
-{
-}
-
-void lin_solve(int b, float *x, float *x0, float a, float c, int N)
-{
-       float cRecip = 1.0 / c;
-       int i, j, k, l;
-       for (l=0; l<F_ITER; l++) 
-       {
-               for (k=1; k<=N; k++)
-               {
-                       for (j=1; j<=N; j++)
-                       {
-                               for (i=1; i<=N; i++)
-                               {
-                                       x[_I(i,j,k)] = (x0[_I(i,j,k)] + a*(
-                                       x[_I(i-1,j,k)]+x[_I(i+1,j,k)]+
-                                       x[_I(i,j-1,k)]+x[_I(i,j+1,k)]+
-                                       x[_I(i,j,k-1)]+x[_I(i,j,k+1)]))*cRecip;
-                               }
-                       }
-               }
-               set_bnd(b, x, N);
-       }
-}
-
-void add_source(float* src, float *dst, float dt, int N)
-{
-       int i, size=(N+2)*(N+2)*(N+2);
-
-       for (i=0; i<size; i++)
-               dst[i] += src[i]*dt;
-}
-
-void add_buoyancy(float *v, float* T, float dt, float buoyancy, int N)
-{
-       int i, size=(N+2)*(N+2)*(N+2);
-
-       for (i=0; i<size; i++)
-               v[i] += -T[i]*buoyancy*dt;
-}
-
-void diffuse(int b, float* x0, float* x, float diff, float dt, int N)
-{
-       float a=dt*diff*N*N*N;
-       lin_solve(b, x, x0, a, 1 + 6 * a, N);
-}
-
-
-void advect(int b, float* x0, float* x, float* uu, float* vv, float* ww, float dt, int N)
-{
-       int i, j, k, i0, j0, k0, i1, j1, k1;
-       float sx0, sx1, sy0, sy1, sz0, sz1, v0, v1;
-       float xx, yy, zz, dt0;
-       dt0 = dt*N;
-       for (k=1; k<=N; k++)
-       {
-               for (j=1; j<=N; j++)
-               {
-                       for (i=1; i<=N; i++)
-                       {
-                               xx = i-dt0*uu[_I(i,j,k)];
-                               yy = j-dt0*vv[_I(i,j,k)];
-                               zz = k-dt0*ww[_I(i,j,k)];
-                               if (xx<0.5) xx=0.5f; if (xx>N+0.5) xx=N+0.5f; i0=(int)xx; i1=i0+1;
-                               if (yy<0.5) yy=0.5f; if (yy>N+0.5) yy=N+0.5f; j0=(int)yy; j1=j0+1;
-                               if (zz<0.5) zz=0.5f; if (zz>N+0.5) zz=N+0.5f; k0=(int)zz; k1=k0+1;
-                               sx1 = xx-i0; sx0 = 1-sx1;
-                               sy1 = yy-j0; sy0 = 1-sy1;
-                               sz1 = zz-k0; sz0 = 1-sz1;
-                               v0 = sx0*(sy0*x0[_I(i0,j0,k0)]+sy1*x0[_I(i0,j1,k0)])+sx1*(sy0*x0[_I(i1,j0,k0)]+sy1*x0[_I(i1,j1,k0)]);
-                               v1 = sx0*(sy0*x0[_I(i0,j0,k1)]+sy1*x0[_I(i0,j1,k1)])+sx1*(sy0*x0[_I(i1,j0,k1)]+sy1*x0[_I(i1,j1,k1)]);
-                               x[_I(i,j,k)] = sz0*v0 + sz1*v1;
-                       }
-               }
-       }
-       set_bnd(b,x, N);
-}
-
-void advect_cool(int b, float* x0, float* x, float* y0, float* y, float* uu, float* vv, float* ww, float dt, float cooling, int N)
-{
-       int i, j, k, i0, j0, k0, i1, j1, k1;
-       float sx0, sx1, sy0, sy1, sz0, sz1, v0, v1;
-       float xx, yy, zz, dt0, c0;
-       dt0 = dt*N;
-       c0 = 1.0f - cooling*dt;
-       for (k=1; k<=N; k++)
-       {
-               for (j=1; j<=N; j++)
-               {
-                       for (i=1; i<=N; i++)
-                       {
-                               xx = i-dt0*uu[_I(i,j,k)];
-                               yy = j-dt0*vv[_I(i,j,k)];
-                               zz = k-dt0*ww[_I(i,j,k)];
-                               if (xx<0.5) xx=0.5f; if (xx>N+0.5) xx=N+0.5f; i0=(int)xx; i1=i0+1;
-                               if (yy<0.5) yy=0.5f; if (yy>N+0.5) yy=N+0.5f; j0=(int)yy; j1=j0+1;
-                               if (zz<0.5) zz=0.5f; if (zz>N+0.5) zz=N+0.5f; k0=(int)zz; k1=k0+1;
-                               sx1 = xx-i0; sx0 = 1-sx1;
-                               sy1 = yy-j0; sy0 = 1-sy1;
-                               sz1 = zz-k0; sz0 = 1-sz1;
-                               v0 = sx0*(sy0*x0[_I(i0,j0,k0)]+sy1*x0[_I(i0,j1,k0)])+sx1*(sy0*x0[_I(i1,j0,k0)]+sy1*x0[_I(i1,j1,k0)]);
-                               v1 = sx0*(sy0*x0[_I(i0,j0,k1)]+sy1*x0[_I(i0,j1,k1)])+sx1*(sy0*x0[_I(i1,j0,k1)]+sy1*x0[_I(i1,j1,k1)]);
-                               x[_I(i,j,k)] = sz0*v0 + sz1*v1;
-                               v0 = sx0*(sy0*y0[_I(i0,j0,k0)]+sy1*y0[_I(i0,j1,k0)])+sx1*(sy0*y0[_I(i1,j0,k0)]+sy1*y0[_I(i1,j1,k0)]);
-                               v1 = sx0*(sy0*y0[_I(i0,j0,k1)]+sy1*y0[_I(i0,j1,k1)])+sx1*(sy0*y0[_I(i1,j0,k1)]+sy1*y0[_I(i1,j1,k1)]);
-                               y[_I(i,j,k)] = (sz0*v0 + sz1*v1)*c0;
-                       }
-               }
-       }
-       set_bnd(b,x, N);
-       set_bnd(b,y, N);
-}
-
-void fproject(float* u, float* u0, float* v, float* v0, float* w, float* w0, int N)
-{
-       float* p = u0;  float* div = v0;        // temporary buffers, use old velocity buffers
-       int i, j, k;
-       float h;
-       h = 1.0f/N;
-       for (k=1; k<=N; k++) {
-               for (j=1; j<=N; j++) {
-                       for (i=1; i<=N; i++) {
-                               div[_I(i,j,k)] = -h*(
-                               u[_I(i+1,j,k)]-u[_I(i-1,j,k)]+
-                               v[_I(i,j+1,k)]-v[_I(i,j-1,k)]+
-                               w[_I(i,j,k+1)]-w[_I(i,j,k-1)])*0.5;
-                               p[_I(i,j,k)] = 0;
-                       }
-               }
-       }
-       set_bnd(0, div, N); 
-       set_bnd(0, p, N);
-       lin_solve(0, p, div, 1, 6, N);
-       
-       for (k=1; k<=N; k++) {
-               for (j=1; j<=N; j++) {
-                       for (i=1; i<=N; i++) {
-                               u[_I(i,j,k)] -= (p[_I(i+1,j,k)]-p[_I(i-1,j,k)])*0.5*N;
-                               v[_I(i,j,k)] -= (p[_I(i,j+1,k)]-p[_I(i,j-1,k)])*0.5*N;
-                               w[_I(i,j,k)] -= (p[_I(i,j,k+1)]-p[_I(i,j,k-1)])*0.5*N;
-                       }
-               }
-       }
-       set_bnd(1, u, N); 
-       set_bnd(2, v, N);
-       set_bnd(3, w, N);
-}
-
-void vorticity_confinement(float *T0, float* u, float* u0, float* v, float* v0, float* w, float* w0, float dt, float vc_eps, int N)
-{
-       int i,j,k,ijk;
-       float *curlx = u0, *curly = v0, *curlz=w0, *curl=T0;            // temp buffers
-       float dt0 = dt * vc_eps;
-       float x,y,z;
-
-
-       for (k=1; k<N; k++) {
-               for (j=1; j<N; j++) {
-                       for (i=1; i<N; i++) {
-                               ijk = _I(i,j,k);
-                                       // curlx = dw/dy - dv/dz
-                               x = curlx[ijk] = (w[_I(i,j+1,k)] - w[_I(i,j-1,k)]) * 0.5f -
-                                               (v[_I(i,j,k+1)] - v[_I(i,j,k-1)]) * 0.5f;
-
-                                       // curly = du/dz - dw/dx
-                               y = curly[ijk] = (u[_I(i,j,k+1)] - u[_I(i,j,k-1)]) * 0.5f -
-                                               (w[_I(i+1,j,k)] - w[_I(i-1,j,k)]) * 0.5f;
-
-                                       // curlz = dv/dx - du/dy
-                               z = curlz[ijk] = (v[_I(i+1,j,k)] - v[_I(i-1,j,k)]) * 0.5f -
-                                               (u[_I(i,j+1,k)] - u[_I(i,j-1,k)]) * 0.5f;
-
-                                       // curl = |curl|
-                               curl[ijk] = sqrtf(x*x+y*y+z*z);
-                       }
-               }
-       }
-
-       for (k=1; k<N; k++) {
-               for (j=1; j<N; j++) {
-                       for (i=1; i<N; i++) {
-                               float Nx = (curl[_I(i+1,j,k)] - curl[_I(i-1,j,k)]) * 0.5f;
-                               float Ny = (curl[_I(i,j+1,k)] - curl[_I(i,j-1,k)]) * 0.5f;
-                               float Nz = (curl[_I(i,j,k+1)] - curl[_I(i,j,k-1)]) * 0.5f;
-                               float len1 = 1.0f/(sqrtf(Nx*Nx+Ny*Ny+Nz*Nz)+0.0000001f);
-                               ijk = _I(i,j,k);
-                               Nx *= len1;
-                               Ny *= len1;
-                               Nz *= len1;
-                               u[ijk] += (Ny*curlz[ijk] - Nz*curly[ijk]) * dt0;
-                               v[ijk] += (Nz*curlx[ijk] - Nx*curlz[ijk]) * dt0;
-                               w[ijk] += (Nx*curly[ijk] - Ny*curlx[ijk]) * dt0;
-                       }
-               }
-       }
-}
-
-
-
-#define DIFFUSE
-#define ADVECT
-
-void vel_step(float *su, float *sv, float *sw, float* u, float* u0, float* v, float* v0, float* w, float* w0, float *T, float *T0, float dt, int N)
-{
-       add_source(su, u, dt, N);
-       add_source(sv, v, dt, N);
-       add_source(sw, w, dt, N);
-       
-       // external force
-       add_buoyancy(v, T, dt, m_buoyancy, N); // better is using gravity normal vector instead of v
-       
-       vorticity_confinement(T0, u, u0, v, v0, w, w0, dt, m_vc_eps, N);
-
-#ifdef DIFFUSE
-       SWAPFPTR(u0, u); SWAPFPTR(v0, v); SWAPFPTR(w0, w);
-       diffuse(1, u0, u, m_viscosity, dt, N);
-       diffuse(2, v0, v, m_viscosity, dt, N);
-       diffuse(3, w0, w, m_viscosity, dt, N);
-       fproject(u, u0, v, v0, w, w0, N);
-#endif
-#ifdef ADVECT
-       SWAPFPTR(u0, u); SWAPFPTR(v0, v); SWAPFPTR(w0, w);
-       advect(1, u0, u, u0, v0, w0, dt, N);
-       advect(2, v0, v, u0, v0, w0, dt, N);
-       advect(3, w0, w, u0, v0, w0, dt, N);
-       fproject(u, u0, v, v0, w, w0, N);
-#endif
-}
-
-void dens_step(float *sd, float *d, float *d0, float *u, float *v, float *w, float dt, int N)
-{
-       add_source(sd, d, dt, N);
-#ifdef DIFFUSE
-       SWAPFPTR(d0, d);
-       diffuse(0, d0, d, m_diffusion, dt, N);
-#endif
-#ifdef ADVECT
-       SWAPFPTR(d0, d);
-       advect(0, d0, d, u, v, w, dt, N);
-#endif
-}
-
-void dens_temp_step(float *sd, float *sT, float *T, float *T0, float *d, float *d0, float *u, float *v, float *w, float dt, int N)
-{
-       add_source(sd, d, dt, N);
-       add_source(sT, T, dt, N);
-       SWAPFPTR(d0, d);
-       diffuse(0, d0, d, m_diffusion, dt, N);
-       SWAPFPTR(d0, d);
-       SWAPFPTR(T0, T);
-       advect_cool(0, d0, d, T0, T, u, v, w, dt, m_cooling, N);
-}
-
-void step(fc *m_fc, float dt)
-{
-       vel_step(su, sv, sw, m_fc->u, m_fc->u0, m_fc->v, m_fc->v0, m_fc->w, m_fc->w0, m_fc->T, m_fc->T0, dt, GRID_SIZE);
-       dens_temp_step(sd, sT, m_fc->T, m_fc->T0, m_fc->d, m_fc->d0, m_fc->u, m_fc->v, m_fc->w, dt, GRID_SIZE);
-}
-
-
-
-void clear_buffer(float* x)
-{
-       int i;
-       for (i=0; i<SIZE; i++) {
-               x[i] = 0.0f;
-       }
-}
-
-void clear_sources(float *sd, float *su, float *sv)
-{
-       int i;
-       for (i=0; i<SIZE; i++) {
-               sd[i] = su[i] = sv[i] = 0.0f;
-       }
-}
-
-fc *f_init(void)
-{
-       int i;
-       int size;
-       
-       fc *m_fc = MEM_callocN(sizeof(fc), "f_c");
-       for (i=0; i<10; i++)
-               clear_buffer(buffers[i]);
-
-       i=0;
-       m_fc->d=buffers[i++]; m_fc->d0=buffers[i++];
-       m_fc->T=buffers[i++]; m_fc->T0=buffers[i++];
-       m_fc->u=buffers[i++]; m_fc->u0=buffers[i++];
-       m_fc->v=buffers[i++]; m_fc->v0=buffers[i++];
-       m_fc->w=buffers[i++]; m_fc->w0=buffers[i++];
-
-       clear_sources(sd, su, sv);
-
-       size=(GRID_SIZE+2)*(GRID_SIZE+2)*(GRID_SIZE+2);
-       for (i=0; i<size; i++)
-               m_fc->v[i] = -0.5f;
-       
-       m_fc->_texture_data = (unsigned char*) MEM_callocN((30+2)*(30+2)*(30+2)*4, "fc_texture_data");
-       
-       m_fc->_fp = 0;
-       
-       return m_fc;
-}
-
-void f_free(fc *m_fc)
-{
-       if(m_fc)
-       {
-               if(m_fc->_texture_data)
-                       MEM_freeN(m_fc->_texture_data);
-               
-               if(m_fc->_fp)
-               fclose(m_fc->_fp);
-               
-               MEM_freeN(m_fc);
-       }
-}
-
index 4bc1efc1e70cb1ae96196f036eaa1662d7c75260..4a03f579fe84fa29692fe0278d4285ef1a3083c8 100644 (file)
@@ -49,7 +49,6 @@
 #include "BLI_arithb.h"
 #include "BLI_edgehash.h"
 #include "BLI_linklist.h"
-#include "BKE_collisions.h"
 #include "BKE_curve.h"
 #include "BKE_deform.h"
 #include "BKE_DerivedMesh.h"
 
 #include "Bullet-C-Api.h"
 
-// step is limited from 0 (frame start position) to 1 (frame end position)
-void collision_move_object(CollisionModifierData *collmd, float step, float prevstep)
-{
-       float tv[3] = {0,0,0};
-       unsigned int i = 0;
-       
-       for ( i = 0; i < collmd->numverts; i++ )
-       {
-               VECSUB(tv, collmd->xnew[i].co, collmd->x[i].co);
-               VECADDS(collmd->current_x[i].co, collmd->x[i].co, tv, prevstep);
-               VECADDS(collmd->current_xnew[i].co, collmd->x[i].co, tv, step);
-               VECSUB(collmd->current_v[i].co, collmd->current_xnew[i].co, collmd->current_x[i].co);
-       }
-}
 
 
 /**
@@ -232,7 +217,7 @@ int gsl_poly_solve_quadratic (float a, float b, float c,  float *x0, float *x1)
  *     page 4, left column
  */
 
-int collisions_get_collision_time(float a[3], float b[3], float c[3], float d[3], float e[3], float f[3], float solution[3]) 
+int cloth_get_collision_time(float a[3], float b[3], float c[3], float d[3], float e[3], float f[3], float solution[3]) 
 {
        int num_sols = 0;
        
@@ -333,7 +318,7 @@ int collisions_get_collision_time(float a[3], float b[3], float c[3], float d[3]
 }
 
 // w3 is not perfect
-void collisions_compute_barycentric (float pv[3], float p1[3], float p2[3], float p3[3], float *w1, float *w2, float *w3)
+void cloth_compute_barycentric (float pv[3], float p1[3], float p2[3], float p3[3], float *w1, float *w2, float *w3)
 {
        double  tempV1[3], tempV2[3], tempV4[3];
        double  a,b,c,d,e,f;
@@ -376,3 +361,884 @@ DO_INLINE void interpolateOnTriangle(float to[3], float v1[3], float v2[3], floa
        VECADDMUL(to, v3, w3);
 }
 
+// unused in the moment, has some bug in
+DO_INLINE void calculateFrictionImpulse(float to[3], float vrel[3], float normal[3], double normalVelocity,
+                                       double frictionConstant, double delta_V_n) 
+{
+       float vrel_t_pre[3];
+       float vrel_t[3];
+       VECSUBS(vrel_t_pre, vrel, normal, normalVelocity);
+       VECCOPY(to, vrel_t_pre);
+       VecMulf(to, MAX2(1.0f - frictionConstant * delta_V_n / INPR(vrel_t_pre,vrel_t_pre), 0.0f));
+}
+
+int cloth_collision_response_static(ClothModifierData *clmd, ClothModifierData *coll_clmd)
+{
+       unsigned int i = 0;
+       int result = 0;
+       LinkNode *search = NULL;
+       CollPair *collpair = NULL;
+       Cloth *cloth1, *cloth2;
+       float w1, w2, w3, u1, u2, u3;
+       float v1[3], v2[3], relativeVelocity[3];
+       float magrelVel;
+       
+       cloth1 = clmd->clothObject;
+       cloth2 = coll_clmd->clothObject;
+
+       search = clmd->coll_parms.collision_list;
+       
+       while(search)
+       {
+               collpair = search->link;
+               
+               // compute barycentric coordinates for both collision points
+               cloth_compute_barycentric(collpair->pa,
+                                       cloth1->verts[collpair->ap1].txold,
+                                       cloth1->verts[collpair->ap2].txold,
+                                       cloth1->verts[collpair->ap3].txold, 
+                                       &w1, &w2, &w3);
+       
+               cloth_compute_barycentric(collpair->pb,
+                                       cloth2->verts[collpair->bp1].txold,
+                                       cloth2->verts[collpair->bp2].txold,
+                                       cloth2->verts[collpair->bp3].txold,
+                                       &u1, &u2, &u3);
+       
+               // Calculate relative "velocity".
+               interpolateOnTriangle(v1, cloth1->verts[collpair->ap1].tv, cloth1->verts[collpair->ap2].tv, cloth1->verts[collpair->ap3].tv, w1, w2, w3);
+               
+               interpolateOnTriangle(v2, cloth2->verts[collpair->bp1].tv, cloth2->verts[collpair->bp2].tv, cloth2->verts[collpair->bp3].tv, u1, u2, u3);
+               
+               VECSUB(relativeVelocity, v1, v2);
+                       
+               // Calculate the normal component of the relative velocity (actually only the magnitude - the direction is stored in 'normal').
+               magrelVel = INPR(relativeVelocity, collpair->normal);
+               
+               // printf("magrelVel: %f\n", magrelVel);
+                               
+               // Calculate masses of points.
+               
+               // If v_n_mag < 0 the edges are approaching each other.
+               if(magrelVel < -ALMOST_ZERO) 
+               {
+                       // Calculate Impulse magnitude to stop all motion in normal direction.
+                       // const double I_mag = v_n_mag / (1/m1 + 1/m2);
+                       float magnitude_i = magrelVel / 2.0f; // TODO implement masses
+                       float tangential[3], magtangent, magnormal, collvel[3];
+                       float vrel_t_pre[3];
+                       float vrel_t[3];
+                       double impulse;
+                       float epsilon = clmd->coll_parms.epsilon;
+                       float overlap = (epsilon + ALMOST_ZERO-collpair->distance);
+                       
+                       // calculateFrictionImpulse(tangential, relativeVelocity, collpair->normal, magrelVel, clmd->coll_parms.friction*0.01, magrelVel);
+                       
+                       // magtangent = INPR(tangential, tangential);
+                       
+                       // Apply friction impulse.
+                       if (magtangent < -ALMOST_ZERO) 
+                       {
+                               
+                               // printf("friction applied: %f\n", magtangent);
+                               // TODO check original code 
+                               /*
+                               VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v1].tv,tangential);
+                               VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v2].tv,tangential);
+                               VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v3].tv,tangential);
+                               VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v4].tv,tangential);
+                               */
+                       }
+                       
+
+                       impulse = -2.0f * magrelVel / ( 1.0 + w1*w1 + w2*w2 + w3*w3);
+                       
+                       // printf("impulse: %f\n", impulse);
+                       
+                       VECADDMUL(cloth1->verts[collpair->ap1].impulse, collpair->normal, w1 * impulse); 
+                       cloth1->verts[collpair->ap1].impulse_count++;
+                       
+                       VECADDMUL(cloth1->verts[collpair->ap2].impulse, collpair->normal, w2 * impulse); 
+                       cloth1->verts[collpair->ap2].impulse_count++;
+                       
+                       VECADDMUL(cloth1->verts[collpair->ap3].impulse, collpair->normal, w3 * impulse); 
+                       cloth1->verts[collpair->ap3].impulse_count++;
+                       
+                       result = 1;
+                       
+                       /*
+                       if (overlap > ALMOST_ZERO) {
+                       double I_mag  = overlap * 0.1;
+                               
+                       impulse = -I_mag / ( 1.0 + w1*w1 + w2*w2 + w3*w3);
+                               
+                       VECADDMUL(cloth1->verts[collpair->ap1].impulse, collpair->normal, w1 * impulse); 
+                       cloth1->verts[collpair->ap1].impulse_count++;
+                                                       
+                       VECADDMUL(cloth1->verts[collpair->ap2].impulse, collpair->normal, w2 * impulse); 
+                       cloth1->verts[collpair->ap2].impulse_count++;
+                       
+                       VECADDMUL(cloth1->verts[collpair->ap3].impulse, collpair->normal, w3 * impulse); 
+                       cloth1->verts[collpair->ap3].impulse_count++;
+               }
+                       */
+               
+                       // printf("magnitude_i: %f\n", magnitude_i); // negative before collision in my case
+                       
+                       // Apply the impulse and increase impulse counters.
+
+                       /*                      
+                       // calculateFrictionImpulse(tangential, collvel, collpair->normal, magtangent, clmd->coll_parms.friction*0.01, magtangent);
+                       VECSUBS(vrel_t_pre, collvel, collpair->normal, magnormal);
+                       // VecMulf(vrel_t_pre, clmd->coll_parms.friction*0.01f/INPR(vrel_t_pre,vrel_t_pre));
+                       magtangent = Normalize(vrel_t_pre);
+                       VecMulf(vrel_t_pre, MIN2(clmd->coll_parms.friction*0.01f*magnormal,magtangent));
+                       
+                       VECSUB(cloth1->verts[face1->v1].tv, cloth1->verts[face1->v1].tv,vrel_t_pre);
+                       */
+                       
+                       
+                       
+               }
+               
+               search = search->next;
+       }
+       
+               
+       return result;
+}
+
+int cloth_collision_response_moving_tris(ClothModifierData *clmd, ClothModifierData *coll_clmd)
+{
+       
+}
+
+
+int cloth_collision_response_moving_edges(ClothModifierData *clmd, ClothModifierData *coll_clmd)
+{
+       
+}
+
+void cloth_collision_static(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2)
+{
+       CollPair *collpair = NULL;
+       Cloth *cloth1=NULL, *cloth2=NULL;
+       MFace *face1=NULL, *face2=NULL;
+       ClothVertex *verts1=NULL, *verts2=NULL;
+       double distance = 0;
+       float epsilon = clmd->coll_parms.epsilon;
+       unsigned int i = 0;
+
+       for(i = 0; i < 4; i++)
+       {
+               collpair = (CollPair *)MEM_callocN(sizeof(CollPair), "cloth coll pair");                
+               
+               cloth1 = clmd->clothObject;
+               cloth2 = coll_clmd->clothObject;
+               
+               verts1 = cloth1->verts;
+               verts2 = cloth2->verts;
+       
+               face1 = &(cloth1->mfaces[tree1->tri_index]);
+               face2 = &(cloth2->mfaces[tree2->tri_index]);
+               
+               // check all possible pairs of triangles
+               if(i == 0)
+               {
+                       collpair->ap1 = face1->v1;
+                       collpair->ap2 = face1->v2;
+                       collpair->ap3 = face1->v3;
+                       
+                       collpair->bp1 = face2->v1;
+                       collpair->bp2 = face2->v2;
+                       collpair->bp3 = face2->v3;
+                       
+               }
+               
+               if(i == 1)
+               {
+                       if(face1->v4)
+                       {
+                               collpair->ap1 = face1->v3;
+                               collpair->ap2 = face1->v4;
+                               collpair->ap3 = face1->v1;
+                               
+                               collpair->bp1 = face2->v1;
+                               collpair->bp2 = face2->v2;
+                               collpair->bp3 = face2->v3;
+                       }
+                       else
+                               i++;
+               }
+               
+               if(i == 2)
+               {
+                       if(face2->v4)
+                       {
+                               collpair->ap1 = face1->v1;
+                               collpair->ap2 = face1->v2;
+                               collpair->ap3 = face1->v3;
+                               
+                               collpair->bp1 = face2->v3;
+                               collpair->bp2 = face2->v4;
+                               collpair->bp3 = face2->v1;
+                       }
+                       else
+                               i+=2;
+               }
+               
+               if(i == 3)
+               {
+                       if((face1->v4)&&(face2->v4))
+                       {
+                               collpair->ap1 = face1->v3;
+                               collpair->ap2 = face1->v4;
+                               collpair->ap3 = face1->v1;
+                               
+                               collpair->bp1 = face2->v3;
+                               collpair->bp2 = face2->v4;
+                               collpair->bp3 = face2->v1;
+                       }
+                       else
+                               i++;
+               }
+               
+               // calc SIPcode (?)
+               
+               if(i < 4)
+               {
+                       // calc distance + normal       
+                       distance = plNearestPoints(
+                                       verts1[collpair->ap1].txold, verts1[collpair->ap2].txold, verts1[collpair->ap3].txold, verts2[collpair->bp1].txold, verts2[collpair->bp2].txold, verts2[collpair->bp3].txold, collpair->pa,collpair->pb,collpair->vector);
+                       
+                       if (distance <= (epsilon + ALMOST_ZERO))
+                       {
+                               // printf("dist: %f\n", (float)distance);
+                               
+                               // collpair->face1 = tree1->tri_index;
+                               // collpair->face2 = tree2->tri_index;
+                               
+                               VECCOPY(collpair->normal, collpair->vector);
+                               Normalize(collpair->normal);
+                               
+                               collpair->distance = distance;
+                               BLI_linklist_append(&clmd->coll_parms.collision_list, collpair);
+                       }
+                       else
+                       {
+                               MEM_freeN(collpair);
+                       }
+               }
+               else
+               {
+                       MEM_freeN(collpair);
+               }
+       }
+}
+
+int cloth_are_edges_adjacent(ClothModifierData *clmd, ClothModifierData *coll_clmd, EdgeCollPair *edgecollpair)
+{
+       Cloth *cloth1, *cloth2;
+       ClothVertex *verts1, *verts2;
+       float temp[3];
+        
+       cloth1 = clmd->clothObject;
+       cloth2 = coll_clmd->clothObject;
+       
+       verts1 = cloth1->verts;
+       verts2 = cloth2->verts;
+       
+       VECSUB(temp, verts1[edgecollpair->p11].xold, verts2[edgecollpair->p21].xold);
+       if(ABS(INPR(temp, temp)) < ALMOST_ZERO)
+               return 1;
+       
+       VECSUB(temp, verts1[edgecollpair->p11].xold, verts2[edgecollpair->p22].xold);
+       if(ABS(INPR(temp, temp)) < ALMOST_ZERO)
+               return 1;
+       
+       VECSUB(temp, verts1[edgecollpair->p12].xold, verts2[edgecollpair->p21].xold);
+       if(ABS(INPR(temp, temp)) < ALMOST_ZERO)
+               return 1;
+       
+       VECSUB(temp, verts1[edgecollpair->p12].xold, verts2[edgecollpair->p22].xold);
+       if(ABS(INPR(temp, temp)) < ALMOST_ZERO)
+               return 1;
+               
+       return 0;
+}
+
+void cloth_collision_moving_edges(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2)
+{
+       EdgeCollPair edgecollpair;
+       Cloth *cloth1=NULL, *cloth2=NULL;
+       MFace *face1=NULL, *face2=NULL;
+       ClothVertex *verts1=NULL, *verts2=NULL;
+       double distance = 0;
+       float epsilon = clmd->coll_parms.epsilon;
+       unsigned int i = 0, j = 0, k = 0;
+       int numsolutions = 0;
+       float a[3], b[3], c[3], d[3], e[3], f[3], solution[3];
+       
+       cloth1 = clmd->clothObject;
+       cloth2 = coll_clmd->clothObject;
+       
+       verts1 = cloth1->verts;
+       verts2 = cloth2->verts;
+
+       face1 = &(cloth1->mfaces[tree1->tri_index]);
+       face2 = &(cloth2->mfaces[tree2->tri_index]);
+       
+       for( i = 0; i < 5; i++)
+       {
+               if(i == 0) 
+               {
+                       edgecollpair.p11 = face1->v1;
+                       edgecollpair.p12 = face1->v2;
+               }
+               else if(i == 1) 
+               {
+                       edgecollpair.p11 = face1->v2;
+                       edgecollpair.p12 = face1->v3;
+               }
+               else if(i == 2) 
+               {
+                       if(face1->v4) 
+                       {
+                               edgecollpair.p11 = face1->v3;
+                               edgecollpair.p12 = face1->v4;
+                       }
+                       else 
+                       {
+                               edgecollpair.p11 = face1->v3;
+                               edgecollpair.p12 = face1->v1;
+                               i+=5; // get out of here after this edge pair is handled
+                       }
+               }
+               else if(i == 3) 
+               {
+                       if(face1->v4) 
+                       {
+                               edgecollpair.p11 = face1->v4;
+                               edgecollpair.p12 = face1->v1;
+                       }       
+                       else
+                               continue;
+               }
+               else
+               {
+                       edgecollpair.p11 = face1->v3;
+                       edgecollpair.p12 = face1->v1;
+               }
+
+               
+               for( j = 0; j < 5; j++)
+               {
+                       if(j == 0)
+                       {
+                               edgecollpair.p21 = face2->v1;
+                               edgecollpair.p22 = face2->v2;
+                       }
+                       else if(j == 1)
+                       {
+                               edgecollpair.p21 = face2->v2;
+                               edgecollpair.p22 = face2->v3;
+                       }
+                       else if(j == 2)
+                       {
+                               if(face2->v4) 
+                               {
+                                       edgecollpair.p21 = face2->v3;
+                                       edgecollpair.p22 = face2->v4;
+                               }
+                               else 
+                               {
+                                       edgecollpair.p21 = face2->v3;
+                                       edgecollpair.p22 = face2->v1;
+                               }
+                       }
+                       else if(j == 3)
+                       {
+                               if(face2->v4) 
+                               {
+                                       edgecollpair.p21 = face2->v4;
+                                       edgecollpair.p22 = face2->v1;
+                               }
+                               else
+                                       continue;
+                       }
+                       else
+                       {
+                               edgecollpair.p21 = face2->v3;
+                               edgecollpair.p22 = face2->v1;
+                       }
+                       
+                       
+                       if(!cloth_are_edges_adjacent(clmd, coll_clmd, &edgecollpair))
+                       {
+                               VECSUB(a, verts1[edgecollpair.p12].xold, verts1[edgecollpair.p11].xold);
+                               VECSUB(b, verts1[edgecollpair.p12].v, verts1[edgecollpair.p11].v);
+                               VECSUB(c, verts1[edgecollpair.p21].xold, verts1[edgecollpair.p11].xold);
+                               VECSUB(d, verts1[edgecollpair.p21].v, verts1[edgecollpair.p11].v);
+                               VECSUB(e, verts2[edgecollpair.p22].xold, verts1[edgecollpair.p11].xold);
+                               VECSUB(f, verts2[edgecollpair.p22].v, verts1[edgecollpair.p11].v);
+                               
+                               numsolutions = cloth_get_collision_time(a, b, c, d, e, f, solution);
+                               
+                               for (k = 0; k < numsolutions; k++) 
+                               {                                                               
+                                       if ((solution[k] >= 0.0) && (solution[k] <= 1.0)) 
+                                       {
+                                               float out_collisionTime = solution[k];
+                                               
+                                               // TODO: check for collisions 
+                                               
+                                               // TODO: put into (edge) collision list
+                                               
+                                               // printf("Moving edge found!\n");
+                                       }
+                               }
+                       }
+               }
+       }               
+}
+
+void cloth_collision_moving_tris(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2)
+{
+       CollPair collpair;
+       Cloth *cloth1=NULL, *cloth2=NULL;
+       MFace *face1=NULL, *face2=NULL;
+       ClothVertex *verts1=NULL, *verts2=NULL;
+       double distance = 0;
+       float epsilon = clmd->coll_parms.epsilon;
+       unsigned int i = 0, j = 0, k = 0;
+       int numsolutions = 0;
+       float a[3], b[3], c[3], d[3], e[3], f[3], solution[3];
+
+       for(i = 0; i < 2; i++)
+       {               
+               cloth1 = clmd->clothObject;
+               cloth2 = coll_clmd->clothObject;
+               
+               verts1 = cloth1->verts;
+               verts2 = cloth2->verts;
+       
+               face1 = &(cloth1->mfaces[tree1->tri_index]);
+               face2 = &(cloth2->mfaces[tree2->tri_index]);
+               
+               // check all possible pairs of triangles
+               if(i == 0)
+               {
+                       collpair.ap1 = face1->v1;
+                       collpair.ap2 = face1->v2;
+                       collpair.ap3 = face1->v3;
+                       
+                       collpair.pointsb[0] = face2->v1;
+                       collpair.pointsb[1] = face2->v2;
+                       collpair.pointsb[2] = face2->v3;
+                       collpair.pointsb[3] = face2->v4;
+               }
+               
+               if(i == 1)
+               {
+                       if(face1->v4)
+                       {
+                               collpair.ap1 = face1->v3;
+                               collpair.ap2 = face1->v4;
+                               collpair.ap3 = face1->v1;
+                               
+                               collpair.pointsb[0] = face2->v1;
+                               collpair.pointsb[1] = face2->v2;
+                               collpair.pointsb[2] = face2->v3;
+                               collpair.pointsb[3] = face2->v4;
+                       }
+                       else
+                               i++;
+               }
+               
+               // calc SIPcode (?)
+               
+               if(i < 2)
+               {
+                       VECSUB(a, verts1[collpair.ap2].xold, verts1[collpair.ap1].xold);
+                       VECSUB(b, verts1[collpair.ap2].v, verts1[collpair.ap1].v);
+                       VECSUB(c, verts1[collpair.ap3].xold, verts1[collpair.ap1].xold);
+                       VECSUB(d, verts1[collpair.ap3].v, verts1[collpair.ap1].v);
+                               
+                       for(j = 0; j < 4; j++)
+                       {                                       
+                               if((j==3) && !(face2->v4))
+                                       break;
+                               
+                               VECSUB(e, verts2[collpair.pointsb[j]].xold, verts1[collpair.ap1].xold);
+                               VECSUB(f, verts2[collpair.pointsb[j]].v, verts1[collpair.ap1].v);
+                               
+                               numsolutions = cloth_get_collision_time(a, b, c, d, e, f, solution);
+                               
+                               for (k = 0; k < numsolutions; k++) 
+                               {                                                               
+                                       if ((solution[k] >= 0.0) && (solution[k] <= 1.0)) 
+                                       {
+                                               float out_collisionTime = solution[k];
+                                               
+                                               // TODO: check for collisions 
+                                               
+                                               // TODO: put into (point-face) collision list
+                                               
+                                               // printf("Moving found!\n");
+                                               
+                                       }
+                               }
+                               
+                               // TODO: check borders for collisions
+                       }
+                       
+               }
+       }
+}
+
+void cloth_collision_moving(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2)
+{
+       // TODO: check for adjacent
+       cloth_collision_moving_edges(clmd, coll_clmd, tree1, tree2);
+       
+       cloth_collision_moving_tris(clmd, coll_clmd, tree1, tree2);
+       cloth_collision_moving_tris(coll_clmd, clmd, tree2, tree1);
+}
+
+// move collision objects forward in time and update static bounding boxes
+void cloth_update_collision_objects(float step)
+{
+       Base *base=NULL;
+       ClothModifierData *coll_clmd=NULL;
+       Object *coll_ob=NULL;
+       unsigned int i=0;
+       
+       // search all objects for collision object
+       for (base = G.scene->base.first; base; base = base->next)
+       {
+
+               coll_ob = base->object;
+               coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth);
+               if (!coll_clmd)
+                       continue;
+
+               // if collision object go on
+               if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ)
+               {
+                       if (coll_clmd->clothObject && coll_clmd->clothObject->tree) 
+                       {
+                               Cloth *coll_cloth = coll_clmd->clothObject;
+                               BVH *coll_bvh = coll_clmd->clothObject->tree;
+                               unsigned int coll_numverts = coll_cloth->numverts;
+
+                               // update position of collision object
+                               for(i = 0; i < coll_numverts; i++)
+                               {
+                                       VECCOPY(coll_cloth->verts[i].txold, coll_cloth->verts[i].tx);
+
+                                       VECADDS(coll_cloth->verts[i].tx, coll_cloth->verts[i].xold, coll_cloth->verts[i].v, step);
+                                       
+                                       // no dt here because of float rounding errors
+                                       VECSUB(coll_cloth->verts[i].tv, coll_cloth->verts[i].tx, coll_cloth->verts[i].txold);
+                               }
+                               
+                               // update BVH of collision object
+                               bvh_update(coll_clmd, coll_bvh, 0); // 0 means STATIC, 1 means MOVING 
+                       }
+                       else
+                               printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n");
+               }
+       }
+}
+
+// CLOTH_MAX_THRESHOLD defines how much collision rounds/loops should be taken
+#define CLOTH_MAX_THRESHOLD 10
+
+// cloth - object collisions
+int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt)
+{
+       Base *base=NULL;
+       ClothModifierData *coll_clmd=NULL;
+       Cloth *cloth=NULL;
+       Object *coll_ob=NULL;
+       BVH *cloth_bvh=NULL;
+       unsigned int i=0, j = 0, numfaces = 0, numverts = 0;
+       unsigned int result = 0, ic = 0, rounds = 0; // result counts applied collisions; ic is for debug output; 
+       ClothVertex *verts = NULL;
+       float tnull[3] = {0,0,0};
+       int ret = 0;
+
+       if ((clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) || !(((Cloth *)clmd->clothObject)->tree))
+       {
+               return 0;
+       }
+       cloth = clmd->clothObject;
+       verts = cloth->verts;
+       cloth_bvh = (BVH *) cloth->tree;
+       numfaces = clmd->clothObject->numfaces;
+       numverts = clmd->clothObject->numverts;
+       
+       ////////////////////////////////////////////////////////////
+       // static collisions
+       ////////////////////////////////////////////////////////////
+
+       // update cloth bvh
+       bvh_update(clmd, cloth_bvh, 0); // 0 means STATIC, 1 means MOVING (see later in this function)
+       
+       // update collision objects
+       cloth_update_collision_objects(step);
+       
+       do
+       {
+               result = 0;
+               ic = 0;
+               clmd->coll_parms.collision_list = NULL; 
+               
+               // check all collision objects
+               for (base = G.scene->base.first; base; base = base->next)
+               {
+                       coll_ob = base->object;
+                       coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth);
+                       
+                       if (!coll_clmd)
+                               continue;
+                       
+                       // if collision object go on
+                       if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ)
+                       {
+                               if (coll_clmd->clothObject && coll_clmd->clothObject->tree) 
+                               {
+                                       BVH *coll_bvh = coll_clmd->clothObject->tree;
+                                       
+                                       bvh_traverse(clmd, coll_clmd, cloth_bvh->root, coll_bvh->root, step, cloth_collision_static);
+                               }
+                               else
+                                       printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n");
+                       }
+               }
+               
+               // process all collisions (calculate impulses, TODO: also repulses if distance too short)
+               result = 1;
+               for(j = 0; j < 10; j++) // 10 is just a value that ensures convergence
+               {
+                       result = 0;
+                       
+                       // handle all collision objects
+                       for (base = G.scene->base.first; base; base = base->next)
+                       {
+               
+                               coll_ob = base->object;
+                               coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth);
+                               if (!coll_clmd)
+                                       continue;
+               
+                               // if collision object go on
+                               if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ)
+                               {
+                                       if (coll_clmd->clothObject) 
+                                               result += cloth_collision_response_static(clmd, coll_clmd);
+                                       else
+                                               printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n");
+                               }
+                       }
+                       
+                       // apply impulses in parallel
+                       ic=0;
+                       for(i = 0; i < numverts; i++)
+                       {
+                               // calculate "velocities" (just xnew = xold + v; no dt in v)
+                               if(verts[i].impulse_count)
+                               {
+                                       VECADDMUL(verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count);
+                                       VECCOPY(verts[i].impulse, tnull);
+                                       verts[i].impulse_count = 0;
+                               
+                                       ic++;
+                                       ret++;
+                               }
+                       }
+               }
+               
+               // free collision list
+               if(clmd->coll_parms.collision_list)
+               {
+                       LinkNode *search = clmd->coll_parms.collision_list;
+                       while(search)
+                       {
+                               CollPair *coll_pair = search->link;
+                                                       
+                               MEM_freeN(coll_pair);
+                               search = search->next;
+                       }
+                       BLI_linklist_free(clmd->coll_parms.collision_list,NULL);
+                       
+                       clmd->coll_parms.collision_list = NULL;
+               }
+               
+               printf("ic: %d\n", ic);
+               rounds++;
+       }
+       while(result && (CLOTH_MAX_THRESHOLD>rounds));
+       
+       printf("\n");
+                       
+       ////////////////////////////////////////////////////////////
+       // update positions
+       // this is needed for bvh_calc_DOP_hull_moving() [kdop.c]
+       ////////////////////////////////////////////////////////////
+       
+       // verts come from clmd
+       for(i = 0; i < numverts; i++)
+       {
+               VECADD(verts[i].tx, verts[i].txold, verts[i].tv);
+       }
+       ////////////////////////////////////////////////////////////
+
+       ////////////////////////////////////////////////////////////
+       // moving collisions
+       ////////////////////////////////////////////////////////////
+
+       
+       // update cloth bvh
+       bvh_update(clmd, cloth_bvh, 1);  // 0 means STATIC, 1 means MOVING 
+       
+       // update moving bvh for collision object once
+       for (base = G.scene->base.first; base; base = base->next)
+       {
+               
+               coll_ob = base->object;
+               coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth);
+               if (!coll_clmd)
+                       continue;
+               
+               if(!coll_clmd->clothObject)
+                       continue;
+               
+                               // if collision object go on
+               if (coll_clmd->clothObject && coll_clmd->clothObject->tree) 
+               {
+                       BVH *coll_bvh = coll_clmd->clothObject->tree;
+                       
+                       bvh_update(coll_clmd, coll_bvh, 1);  // 0 means STATIC, 1 means MOVING  
+               }
+       }
+       
+       
+       do
+       {
+               result = 0;
+               ic = 0;
+               clmd->coll_parms.collision_list = NULL; 
+               
+               // check all collision objects
+               for (base = G.scene->base.first; base; base = base->next)
+               {
+                       coll_ob = base->object;
+                       coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth);
+                       
+                       if (!coll_clmd)
+                               continue;
+                       
+                       // if collision object go on
+                       if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ)
+                       {
+                               if (coll_clmd->clothObject && coll_clmd->clothObject->tree) 
+                               {
+                                       BVH *coll_bvh = coll_clmd->clothObject->tree;
+                                       
+                                       bvh_traverse(clmd, coll_clmd, cloth_bvh->root, coll_bvh->root, step, cloth_collision_moving);
+                               }
+                               else
+                                       printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n");
+                       }
+               }
+               
+               // process all collisions (calculate impulses, TODO: also repulses if distance too short)
+               result = 1;
+               for(j = 0; j < 10; j++) // 10 is just a value that ensures convergence
+               {
+                       result = 0;
+                               
+                       // handle all collision objects
+                       for (base = G.scene->base.first; base; base = base->next)
+                       {
+                       
+                               coll_ob = base->object;
+                               coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth);
+                                               
+                               if (!coll_clmd)
+                               continue;
+                               
+                               // if collision object go on
+                               if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ)
+                               {
+                                       if (coll_clmd->clothObject) 
+                                       result += cloth_collision_response_moving_tris(clmd, coll_clmd);
+                                       else
+                                       printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n");
+                               }
+                       }
+                                               
+                       // apply impulses in parallel
+                       ic=0;
+                       for(i = 0; i < numverts; i++)
+                       {
+                               // calculate "velocities" (just xnew = xold + v; no dt in v)
+                               if(verts[i].impulse_count)
+                               {
+                                       VECADDMUL(verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count);
+                                       VECCOPY(verts[i].impulse, tnull);
+                                       verts[i].impulse_count = 0;
+                                                       
+                                       ic++;
+                                       ret++;
+                               }
+                       }
+               }
+               
+               
+               // verts come from clmd
+               for(i = 0; i < numverts; i++)
+               {
+                       VECADD(verts[i].tx, verts[i].txold, verts[i].tv);
+               }
+               
+               // update cloth bvh
+               bvh_update(clmd, cloth_bvh, 1);  // 0 means STATIC, 1 means MOVING 
+               
+               
+               // free collision list
+               if(clmd->coll_parms.collision_list)
+               {
+                       LinkNode *search = clmd->coll_parms.collision_list;
+                       while(search)
+                       {
+                               CollPair *coll_pair = search->link;
+                                                       
+                               MEM_freeN(coll_pair);
+                               search = search->next;
+                       }
+                       BLI_linklist_free(clmd->coll_parms.collision_list,NULL);
+                       
+                       clmd->coll_parms.collision_list = NULL;
+               }
+               
+               printf("ic: %d\n", ic);
+               rounds++;
+       }
+       while(result && (CLOTH_MAX_THRESHOLD>rounds));
+       
+       
+       ////////////////////////////////////////////////////////////
+       // update positions + velocities
+       ////////////////////////////////////////////////////////////
+       
+       // verts come from clmd
+       for(i = 0; i < numverts; i++)
+       {
+               VECADD(verts[i].tx, verts[i].txold, verts[i].tv);
+       }
+       ////////////////////////////////////////////////////////////
+
+       return MIN2(ret, 1);
+}
index a1d60b34125436e9f35993d7dd050e8fc174224e..b154cb0e7554c6e09db775bd73249c8b49e0e521 100644 (file)
 #include "DNA_lattice_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_modifier_types.h"
-#include "BLI_arithb.h"
 #include "BLI_blenlib.h"
-#include "BLI_edgehash.h"
+#include "BLI_arithb.h"
 #include "BLI_threads.h"
-#include "BKE_collisions.h"
 #include "BKE_curve.h"
 #include "BKE_displist.h"
 #include "BKE_effect.h"
@@ -63,7 +61,6 @@
 #include "BKE_global.h"
 #include  "BIF_editdeform.h"
 
-#include "Bullet-C-Api.h"
 
 #ifdef _WIN32
 #include <windows.h>
@@ -85,14 +82,18 @@ void itend(void)
 double itval()
 {
        return ((double)_itend.QuadPart -
-                       (double)_itstart.QuadPart)/((double)ifreq.QuadPart);
+               (double)_itstart.QuadPart)/((double)ifreq.QuadPart);
 }
 #else
 #include <sys/time.h>
+// intrinsics need better compile flag checking
+// #include <xmmintrin.h>
+// #include <pmmintrin.h>
+// #include <pthread.h>
 
-                        static struct timeval _itstart, _itend;
-        static struct timezone itz;
-        void itstart(void)
+static struct timeval _itstart, _itend;
+static struct timezone itz;
+void itstart(void)
 {
        gettimeofday(&_itstart, &itz);
 }
@@ -108,7 +109,14 @@ double itval()
        return t2-t1;
 }
 #endif
-
+/*
+#define C99
+#ifdef C99
+#defineDO_INLINE inline 
+#else 
+#defineDO_INLINE static 
+#endif
+*/
 struct Cloth;
 
 //////////////////////////////////////////
@@ -172,7 +180,7 @@ void print_fvector(float m3[3])
 // long float vector float (*)[3]
 ///////////////////////////
 /* print long vector on console: for debug output */
-DO_INLINE void print_lfvector(lfVector *fLongVector, unsigned int verts)
+DO_INLINE void print_lfvector(float (*fLongVector)[3], unsigned int verts)
 {
        unsigned int i = 0;
        for(i = 0; i < verts; i++)
@@ -188,7 +196,7 @@ DO_INLINE lfVector *create_lfvector(unsigned int verts)
        // return (lfVector *)cloth_aligned_malloc(&MEMORY_BASE, verts * sizeof(lfVector));
 }
 /* delete long vector */
-DO_INLINE void del_lfvector(lfVector *fLongVector)
+DO_INLINE void del_lfvector(float (*fLongVector)[3])
 {
        if (fLongVector != NULL)
        {
@@ -202,7 +210,7 @@ DO_INLINE void cp_lfvector(float (*to)[3], float (*from)[3], unsigned int verts)
        memcpy(to, from, verts * sizeof(lfVector));
 }
 /* init long vector with float[3] */
-DO_INLINE void init_lfvector(lfVector *fLongVector, float vector[3], unsigned int verts)
+DO_INLINE void init_lfvector(float (*fLongVector)[3], float vector[3], unsigned int verts)
 {
        unsigned int i = 0;
        for(i = 0; i < verts; i++)
@@ -216,7 +224,7 @@ DO_INLINE void zero_lfvector(float (*to)[3], unsigned int verts)
        memset(to, 0.0f, verts * sizeof(lfVector));
 }
 /* multiply long vector with scalar*/
-DO_INLINE void mul_lfvectorS(float (*to)[3], lfVector *fLongVector, float scalar, unsigned int verts)
+DO_INLINE void mul_lfvectorS(float (*to)[3], float (*fLongVector)[3], float scalar, unsigned int verts)
 {
        unsigned int i = 0;
 
@@ -227,7 +235,7 @@ DO_INLINE void mul_lfvectorS(float (*to)[3], lfVector *fLongVector, float scalar
 }
 /* multiply long vector with scalar*/
 /* A -= B * float */
-DO_INLINE void submul_lfvectorS(float (*to)[3], lfVector *fLongVector, float scalar, unsigned int verts)
+DO_INLINE void submul_lfvectorS(float (*to)[3], float (*fLongVector)[3], float scalar, unsigned int verts)
 {
        unsigned int i = 0;
        for(i = 0; i < verts; i++)
@@ -236,12 +244,12 @@ DO_INLINE void submul_lfvectorS(float (*to)[3], lfVector *fLongVector, float sca
        }
 }
 /* dot product for big vector */
-DO_INLINE float dot_lfvector(lfVector *fLongVectorA, lfVector *fLongVectorB, unsigned int verts)
+DO_INLINE float dot_lfvector(float (*fLongVectorA)[3], float (*fLongVectorB)[3], unsigned int verts)
 {
        unsigned int i = 0;
        float temp = 0.0;
 // schedule(guided, 2)
-#pragma omp parallel for reduction(+: temp) private(i)
+#pragma omp parallel for reduction(+: temp)
        for(i = 0; i < verts; i++)
        {
                temp += INPR(fLongVectorA[i], fLongVectorB[i]);
@@ -249,7 +257,7 @@ DO_INLINE float dot_lfvector(lfVector *fLongVectorA, lfVector *fLongVectorB, uns
        return temp;
 }
 /* A = B + C  --> for big vector */
-DO_INLINE void add_lfvector_lfvector(float (*to)[3], lfVector *fLongVectorA, lfVector *fLongVectorB, unsigned int verts)
+DO_INLINE void add_lfvector_lfvector(float (*to)[3], float (*fLongVectorA)[3], float (*fLongVectorB)[3], unsigned int verts)
 {
        unsigned int i = 0;
 
@@ -260,7 +268,7 @@ DO_INLINE void add_lfvector_lfvector(float (*to)[3], lfVector *fLongVectorA, lfV
 
 }
 /* A = B + C * float --> for big vector */
-DO_INLINE void add_lfvector_lfvectorS(float (*to)[3], lfVector *fLongVectorA, lfVector *fLongVectorB, float bS, unsigned int verts)
+DO_INLINE void add_lfvector_lfvectorS(float (*to)[3], float (*fLongVectorA)[3], float (*fLongVectorB)[3], float bS, unsigned int verts)
 {
        unsigned int i = 0;
 
@@ -271,7 +279,7 @@ DO_INLINE void add_lfvector_lfvectorS(float (*to)[3], lfVector *fLongVectorA, lf
        }
 }
 /* A = B * float + C * float --> for big vector */
-DO_INLINE void add_lfvectorS_lfvectorS(float (*to)[3], lfVector *fLongVectorA, float aS, lfVector *fLongVectorB, float bS, unsigned int verts)
+DO_INLINE void add_lfvectorS_lfvectorS(float (*to)[3], float (*fLongVectorA)[3], float aS, float (*fLongVectorB)[3], float bS, unsigned int verts)
 {
        unsigned int i = 0;
 
@@ -281,7 +289,7 @@ DO_INLINE void add_lfvectorS_lfvectorS(float (*to)[3], lfVector *fLongVectorA, f
        }
 }
 /* A = B - C * float --> for big vector */
-DO_INLINE void sub_lfvector_lfvectorS(float (*to)[3], lfVector *fLongVectorA, lfVector *fLongVectorB, float bS, unsigned int verts)
+DO_INLINE void sub_lfvector_lfvectorS(float (*to)[3], float (*fLongVectorA)[3], float (*fLongVectorB)[3], float bS, unsigned int verts)
 {
        unsigned int i = 0;
        for(i = 0; i < verts; i++)
@@ -291,7 +299,7 @@ DO_INLINE void sub_lfvector_lfvectorS(float (*to)[3], lfVector *fLongVectorA, lf
 
 }
 /* A = B - C --> for big vector */
-DO_INLINE void sub_lfvector_lfvector(float (*to)[3], lfVector *fLongVectorA, lfVector *fLongVectorB, unsigned int verts)
+DO_INLINE void sub_lfvector_lfvector(float (*to)[3], float (*fLongVectorA)[3], float (*fLongVectorB)[3], unsigned int verts)
 {
        unsigned int i = 0;
 
@@ -323,7 +331,7 @@ DO_INLINE void cp_fmatrix(float to[3][3], float from[3][3])
 DO_INLINE float det_fmatrix(float m[3][3])
 {
        return  m[0][0]*m[1][1]*m[2][2] + m[1][0]*m[2][1]*m[0][2] + m[0][1]*m[1][2]*m[2][0] 
-                       -m[0][0]*m[1][2]*m[2][1] - m[0][1]*m[1][0]*m[2][2] - m[2][0]*m[1][1]*m[0][2];
+       -m[0][0]*m[1][2]*m[2][1] - m[0][1]*m[1][0]*m[2][2] - m[2][0]*m[1][1]*m[0][2];
 }
 DO_INLINE void inverse_fmatrix(float to[3][3], float from[3][3])
 {
@@ -561,38 +569,35 @@ DO_INLINE void mul_bfmatrix_S(fmatrix3x3 *matrix, float scalar)
 
 /* SPARSE SYMMETRIC multiply big matrix with long vector*/
 /* STATUS: verified */
-DO_INLINE void mul_bfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, lfVector *fLongVector)
+DO_INLINE void mul_bfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, float (*fLongVector)[3])
 {
        unsigned int i = 0;
-       lfVector *temp = create_lfvector(from[0].vcount);
-       
        zero_lfvector(to, from[0].vcount);
+       /* process diagonal elements */ 
+       for(i = 0; i < from[0].vcount; i++)
+       {
+               muladd_fmatrix_fvector(to[from[i].r], from[i].m, fLongVector[from[i].c]);       
+       }
 
-#pragma omp parallel sections private(i)
+       /* process off-diagonal entries (every off-diagonal entry needs to be symmetric) */
+       // TODO: pragma below is wrong, correct it!
+       // #pragma omp parallel for shared(to,from, fLongVector) private(i) 
+       for(i = from[0].vcount; i < from[0].vcount+from[0].scount; i++)
        {
-#pragma omp section
-               {
-                       for(i = from[0].vcount; i < from[0].vcount+from[0].scount; i++)
-                       {
-                               muladd_fmatrix_fvector(to[from[i].c], from[i].m, fLongVector[from[i].r]);
-                       }
-               }       
-#pragma omp section
-               {
-                       for(i = 0; i < from[0].vcount+from[0].scount; i++)
-                       {
-                               muladd_fmatrix_fvector(temp[from[i].r], from[i].m, fLongVector[from[i].c]);
-                       }
-               }
+               // muladd_fmatrix_fvector(to[from[i].c], from[i].m, fLongVector[from[i].r]);
+               
+               to[from[i].c][0] += INPR(from[i].m[0],fLongVector[from[i].r]);
+               to[from[i].c][1] += INPR(from[i].m[1],fLongVector[from[i].r]);
+               to[from[i].c][2] += INPR(from[i].m[2],fLongVector[from[i].r]);  
+               
+               // muladd_fmatrix_fvector(to[from[i].r], from[i].m, fLongVector[from[i].c]);
+               
+               to[from[i].r][0] += INPR(from[i].m[0],fLongVector[from[i].c]);
+               to[from[i].r][1] += INPR(from[i].m[1],fLongVector[from[i].c]);
+               to[from[i].r][2] += INPR(from[i].m[2],fLongVector[from[i].c]);  
        }
-       add_lfvector_lfvector(to, to, temp, from[0].vcount);
-       
-       del_lfvector(temp);
-       
-       
 }
 
-
 /* SPARSE SYMMETRIC multiply big matrix with long vector (for diagonal preconditioner) */
 /* STATUS: verified */
 DO_INLINE void mul_prevfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, lfVector *fLongVector)
@@ -699,7 +704,7 @@ static float I[3][3] = {{1,0,0},{0,1,0},{0,0,1}};
 static float ZERO[3][3] = {{0,0,0}, {0,0,0}, {0,0,0}};
 typedef struct Implicit_Data 
 {
-       lfVector *X, *V, *Xnew, *Vnew, *F, *B, *dV, *z;
+       lfVector *X, *V, *Xnew, *Vnew, *olddV, *F, *B, *dV, *z;
        fmatrix3x3 *A, *dFdV, *dFdX, *S, *P, *Pinv, *bigI; 
 } Implicit_Data;
 
@@ -735,6 +740,8 @@ int implicit_init (Object *ob, ClothModifierData *clmd)
        id->Xnew = create_lfvector(cloth->numverts);
        id->V = create_lfvector(cloth->numverts);
        id->Vnew = create_lfvector(cloth->numverts);
+       id->olddV = create_lfvector(cloth->numverts);
+       zero_lfvector(id->olddV, cloth->numverts);
        id->F = create_lfvector(cloth->numverts);
        id->B = create_lfvector(cloth->numverts);
        id->dV = create_lfvector(cloth->numverts);
@@ -767,7 +774,7 @@ int implicit_init (Object *ob, ClothModifierData *clmd)
 
                // dFdV_start[i].c = big_I[i].c = big_zero[i].c = 
                id->A[i+cloth->numverts].c = id->dFdV[i+cloth->numverts].c = id->dFdX[i+cloth->numverts].c = 
-                               id->P[i+cloth->numverts].c = id->Pinv[i+cloth->numverts].c = id->bigI[i+cloth->numverts].c = spring->kl;
+                       id->P[i+cloth->numverts].c = id->Pinv[i+cloth->numverts].c = id->bigI[i+cloth->numverts].c = spring->kl;
 
                spring->matrix_index = i + cloth->numverts;
                
@@ -776,7 +783,7 @@ int implicit_init (Object *ob, ClothModifierData *clmd)
 
        for(i = 0; i < cloth->numverts; i++)
        {               
-               VECCOPY(id->X[i], cloth->x[i]);
+               VECCOPY(id->X[i], verts[i].x);
        }
 
        return 1;
@@ -805,6 +812,7 @@ int implicit_free (ClothModifierData *clmd)
                        del_lfvector(id->Xnew);
                        del_lfvector(id->V);
                        del_lfvector(id->Vnew);
+                       del_lfvector(id->olddV);
                        del_lfvector(id->F);
                        del_lfvector(id->B);
                        del_lfvector(id->dV);
@@ -817,31 +825,6 @@ int        implicit_free (ClothModifierData *clmd)
        return 1;
 }
 
-void cloth_bending_mode(ClothModifierData *clmd, int enabled)
-{
-       Cloth *cloth = clmd->clothObject;
-       Implicit_Data *id;
-       
-       if(cloth)
-       {
-               id = cloth->implicit;
-               
-               if(id)
-               {
-                       if(enabled)
-                       {
-                               cloth->numsprings = cloth->numspringssave;
-                       }
-                       else
-                       {
-                               cloth->numsprings = cloth->numothersprings;
-                       }
-                       
-                       id->A[0].scount = id->dFdV[0].scount = id->dFdX[0].scount = id->P[0].scount = id->Pinv[0].scount = id->bigI[0].scount = cloth->numsprings;
-               }       
-       }
-}
-
 DO_INLINE float fb(float length, float L)
 {
        float x = length/L;
@@ -892,7 +875,7 @@ DO_INLINE void filter(lfVector *V, fmatrix3x3 *S)
        }
 }
 
-int cg_filtered(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix3x3 *S)
+int  cg_filtered(lfVector *ldV, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix3x3 *S)
 {
        // Solves for unknown X in equation AX=B
        unsigned int conjgrad_loopcount=0, conjgrad_looplimit=100;
@@ -905,14 +888,14 @@ int cg_filtered(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix
        tmp = create_lfvector(numverts);
        r = create_lfvector(numverts);
 
-       // zero_lfvector(dv, CLOTHPARTICLES);
-       filter(dv, S);
+       // zero_lfvector(ldV, CLOTHPARTICLES);
+       filter(ldV, S);
 
-       add_lfvector_lfvector(dv, dv, z, numverts);
+       add_lfvector_lfvector(ldV, ldV, z, numverts);
 
        // r = B - Mul(tmp,A,X);    // just use B if X known to be zero
        cp_lfvector(r, lB, numverts);
-       mul_bfmatrix_lfvector(tmp, lA, dv);
+       mul_bfmatrix_lfvector(tmp, lA, ldV);
        sub_lfvector_lfvector(r, r, tmp, numverts);
 
        filter(r,S);
@@ -932,7 +915,7 @@ int cg_filtered(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix
                a = s/dot_lfvector(d, q, numverts);
 
                // X = X + d*a;
-               add_lfvector_lfvectorS(dv, dv, d, a, numverts);
+               add_lfvector_lfvectorS(ldV, ldV, d, a, numverts);
 
                // r = r - q*a;
                sub_lfvector_lfvectorS(r, r, q, a, numverts);
@@ -947,16 +930,12 @@ int cg_filtered(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix
 
                conjgrad_loopcount++;
        }
-       // itend();
-       // printf("cg_filtered time: %f\n", (float)itval());
-       
        conjgrad_lasterror = s;
 
        del_lfvector(q);
        del_lfvector(d);
        del_lfvector(tmp);
        del_lfvector(r);
-       
        // printf("W/O conjgrad_loopcount: %d\n", conjgrad_loopcount);
 
        return conjgrad_loopcount<conjgrad_looplimit;  // true means we reached desired accuracy in given time - ie stable
@@ -1101,13 +1080,15 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s,
        float vel[3];
        float k = 0.0f;
        float L = s->restlen;
-       float cb = clmd->sim_parms->structural;
+       float cb = clmd->sim_parms.structural;
 
        float nullf[3] = {0,0,0};
        float stretch_force[3] = {0,0,0};
        float bending_force[3] = {0,0,0};
        float damping_force[3] = {0,0,0};
        float nulldfdx[3][3]={ {0,0,0}, {0,0,0}, {0,0,0}};
+       Cloth *cloth = clmd->clothObject;
+       ClothVertex *verts = cloth->verts;
        
        VECCOPY(s->f, nullf);
        cp_fmatrix(s->dfdx, nulldfdx);
@@ -1125,13 +1106,13 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s,
                /*
                if(length>L)
                {
-               if((clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED) 
-               && ((((length-L)*100.0f/L) > clmd->sim_parms->maxspringlen))) // cut spring!
-               {
-               s->flags |= CSPRING_FLAG_DEACTIVATE;
-               return;
-       }
-       } 
+                       if((clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED) 
+                       && ((((length-L)*100.0f/L) > clmd->sim_parms.maxspringlen))) // cut spring!
+                       {
+                               s->flags |= CSPRING_FLAG_DEACTIVATE;
+                               return;
+                       }
+               
                */
                mul_fvector_S(dir, extent, 1.0f/length);
        }
@@ -1141,19 +1122,6 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s,
        }
        
        
-       /*
-       if(s->type == CLOTH_SPRING_TYPE_COLLISION)
-       {
-               if(length < L)
-               {
-                       mul_fvector_S(stretch_force, dir, (100.0*(length-L))); 
-       
-                       VECADD(s->f, s->f, stretch_force);
-               }
-               return;
-       }
-       */
-       
        // calculate force of structural + shear springs
        if(s->type != CLOTH_SPRING_TYPE_BENDING)
        {
@@ -1161,72 +1129,56 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s,
                {
                        s->flags |= CLOTH_SPRING_FLAG_NEEDED;
 
-                       k = clmd->sim_parms->structural;        
+                       k = clmd->sim_parms.structural; 
 
                        mul_fvector_S(stretch_force, dir, (k*(length-L))); 
 
                        VECADD(s->f, s->f, stretch_force);
 
                        // Ascher & Boxman, p.21: Damping only during elonglation
-                       mul_fvector_S(damping_force, extent, clmd->sim_parms->Cdis * 0.01 * ((INPR(vel,extent)/length))); 
+                       mul_fvector_S(damping_force, extent, clmd->sim_parms.Cdis * ((INPR(vel,extent)/length))); 
                        VECADD(s->f, s->f, damping_force);
 
                        dfdx_spring_type1(s->dfdx, dir,length,L,k);
 
-                       dfdv_damp(s->dfdv, dir,clmd->sim_parms->Cdis);
+                       dfdv_damp(s->dfdv, dir,clmd->sim_parms.Cdis);
                }
        }
        else // calculate force of bending springs
        {
                if(length < L)
                {
-                       // clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_BIG_FORCE;
-                       
                        s->flags |= CLOTH_SPRING_FLAG_NEEDED;
                        
-                       k = clmd->sim_parms->bending;   
+                       k = clmd->sim_parms.bending;    
 
                        mul_fvector_S(bending_force, dir, fbstar(length, L, k, cb));
                        VECADD(s->f, s->f, bending_force);
-                       
-                       // if(INPR(bending_force,bending_force) > 0.13*0.13)
-                       {
-                               clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_BIG_FORCE;
-                       }
-                       
-                       
+
                        dfdx_spring_type2(s->dfdx, dir,length,L,k, cb);
-                       /*
-                       if(s->ij == 300 || s->kl == 300)
-                               printf("id->F[0]: %f, id->F[1]: %f, id->F[2]: %f\n", s->f[0], s->f[1], s->f[2]);
-                       */
                }
        }
 }
 
-DO_INLINE int cloth_apply_spring_force(ClothModifierData *clmd, ClothSpring *s, lfVector *lF, lfVector *X, lfVector *V, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX)
+DO_INLINE void cloth_apply_spring_force(ClothModifierData *clmd, ClothSpring *s, lfVector *lF, lfVector *X, lfVector *V, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX)
 {
        if(s->flags & CLOTH_SPRING_FLAG_NEEDED)
        {
-               VECADD(lF[s->ij], lF[s->ij], s->f);
-               VECSUB(lF[s->kl], lF[s->kl], s->f);     
-                       
                if(s->type != CLOTH_SPRING_TYPE_BENDING)
                {
                        sub_fmatrix_fmatrix(dFdV[s->ij].m, dFdV[s->ij].m, s->dfdv);
                        sub_fmatrix_fmatrix(dFdV[s->kl].m, dFdV[s->kl].m, s->dfdv);
-                       add_fmatrix_fmatrix(dFdV[s->matrix_index].m, dFdV[s->matrix_index].m, s->dfdv);
+                       add_fmatrix_fmatrix(dFdV[s->matrix_index].m, dFdV[s->matrix_index].m, s->dfdv); 
                }
-               else if(!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_BIG_FORCE))
-                       return 0;
-               
+
+               VECADD(lF[s->ij], lF[s->ij], s->f);
+               VECSUB(lF[s->kl], lF[s->kl], s->f);
+
                sub_fmatrix_fmatrix(dFdX[s->ij].m, dFdX[s->ij].m, s->dfdx);
                sub_fmatrix_fmatrix(dFdX[s->kl].m, dFdX[s->kl].m, s->dfdx);
 
                add_fmatrix_fmatrix(dFdX[s->matrix_index].m, dFdX[s->matrix_index].m, s->dfdx);
-       }
-       
-       return 1;
+       }       
 }
 
 DO_INLINE void calculateTriangleNormal(float to[3], lfVector *X, MFace mface)
@@ -1275,7 +1227,7 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec
        /* Collect forces and derivatives:  F,dFdX,dFdV */
        Cloth           *cloth          = clmd->clothObject;
        unsigned int    i               = 0;
-       float           spring_air      = clmd->sim_parms->Cvi * 0.01f; /* viscosity of air scaled in percent */
+       float           spring_air      = clmd->sim_parms.Cvi * 0.01f; /* viscosity of air scaled in percent */
        float           gravity[3];
        float           tm2[3][3]       = {{-spring_air,0,0}, {0,-spring_air,0},{0,0,-spring_air}};
        ClothVertex *verts = cloth->verts;
@@ -1286,7 +1238,8 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec
        float kd, ks;
        LinkNode *search = cloth->springs;
 
-       VECCOPY(gravity, clmd->sim_parms->gravity);
+
+       VECCOPY(gravity, clmd->sim_parms.gravity);
        mul_fvector_S(gravity, gravity, 0.001f); /* scale gravity force */
 
        /* set dFdX jacobi matrix to zero */
@@ -1299,24 +1252,24 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec
        submul_lfvectorS(lF, lV, spring_air, numverts);
 
        /* do goal stuff */
-       if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) 
+       if(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) 
        {       
                for(i = 0; i < numverts; i++)
                {                       
                        if(verts [i].goal < SOFTGOALSNAP)
                        {                       
                                // current_position = xold + t * (newposition - xold)
-                               VECSUB(tvect, cloth->xconst[i], cloth->xold[i]);
+                               VECSUB(tvect, verts[i].xconst, verts[i].xold);
                                mul_fvector_S(tvect, tvect, time);
-                               VECADD(tvect, tvect, cloth->xold[i]);
+                               VECADD(tvect, tvect, verts[i].xold);
 
                                VECSUB(auxvect, tvect, lX[i]);
-                               ks  = 1.0f/(1.0f- verts [i].goal*clmd->sim_parms->goalspring)-1.0f ;
+                               ks  = 1.0f/(1.0f- verts [i].goal*clmd->sim_parms.goalspring)-1.0f ;
                                VECADDS(lF[i], lF[i], auxvect, -ks);
 
                                // calulate damping forces generated by goals                           
-                               VECSUB(velgoal, cloth->xold[i], cloth->xconst[i]);
-                               kd =  clmd->sim_parms->goalfrict * 0.01f; // friction force scale taken from SB
+                               VECSUB(velgoal,verts[i].xold, verts[i].xconst);
+                               kd =  clmd->sim_parms.goalfrict * 0.01f; // friction force scale taken from SB
                                VECSUBADDSS(lF[i], velgoal, kd, lV[i], kd);
                                
                        }
@@ -1329,7 +1282,7 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec
                float speed[3] = {0.0f, 0.0f,0.0f};
                float force[3]= {0.0f, 0.0f, 0.0f};
                
-// #pragma omp parallel for private (i) shared(lF)
+               #pragma omp parallel for private (i) shared(lF)
                for(i = 0; i < cloth->numverts; i++)
                {
                        float vertexnormal[3]={0,0,0};
@@ -1353,42 +1306,24 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec
        while(search)
        {
                // only handle active springs
-               // if(((clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED) && !(springs[i].flags & CSPRING_FLAG_DEACTIVATE))|| !(clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED)){}
+               // if(((clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED) && !(springs[i].flags & CSPRING_FLAG_DEACTIVATE))|| !(clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED)){}
                cloth_calc_spring_force(clmd, search->link, lF, lX, lV, dFdV, dFdX);
 
                search = search->next;
        }
        
-       if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_BIG_FORCE)
-       {       
-               if(cloth->numspringssave != cloth->numsprings)
-               {
-                       cloth_bending_mode(clmd, 1);
-               }
-       }
-       else
-       {
-               if(cloth->numspringssave == cloth->numsprings)
-               {
-                       cloth_bending_mode(clmd, 0);
-               }
-       }
-       
        // apply spring forces
        search = cloth->springs;
        while(search)
        {
                // only handle active springs
-               // if(((clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED) && !(springs[i].flags & CSPRING_FLAG_DEACTIVATE))|| !(clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED))  
-               if(!cloth_apply_spring_force(clmd, search->link, lF, lX, lV, dFdV, dFdX))
-                       break;
+               // if(((clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED) && !(springs[i].flags & CSPRING_FLAG_DEACTIVATE))|| !(clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED))    
+               cloth_apply_spring_force(clmd, search->link, lF, lX, lV, dFdV, dFdX);
                search = search->next;
        }
-       
-       clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_BIG_FORCE;
 }
 
-void simulate_implicit_euler(lfVector *Vnew, lfVector *lX, lfVector *lV, lfVector *lF, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, float dt, fmatrix3x3 *A, lfVector *B, lfVector *dV, fmatrix3x3 *S, lfVector *z, fmatrix3x3 *P, fmatrix3x3 *Pinv)
+void simulate_implicit_euler(lfVector *Vnew, lfVector *lX, lfVector *lV, lfVector *lF, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, float dt, fmatrix3x3 *A, lfVector *B, lfVector *dV, fmatrix3x3 *S, lfVector *z, lfVector *olddV, fmatrix3x3 *P, fmatrix3x3 *Pinv)
 {
        unsigned int numverts = dFdV[0].vcount;
 
@@ -1396,46 +1331,48 @@ void simulate_implicit_euler(lfVector *Vnew, lfVector *lX, lfVector *lV, lfVecto
        initdiag_bfmatrix(A, I);
        zero_lfvector(dV, numverts);
 
-       subadd_bfmatrixS_bfmatrixS(A, dFdV, dt, dFdX, (dt*dt));
+       subadd_bfmatrixS_bfmatrixS(A, dFdV, dt, dFdX, (dt*dt));   
+
        mul_bfmatrix_lfvector(dFdXmV, dFdX, lV);
+
        add_lfvectorS_lfvectorS(B, lF, dt, dFdXmV, (dt*dt), numverts);
        
-       // TODO: unstable with quality=5 + stiffness=7000 + no zero_lfvector()
+       itstart();
+       
        cg_filtered(dV, A, B, z, S); /* conjugate gradient algorithm to solve Ax=b */
+       // cg_filtered_pre(dV, A, B, z, olddV, P, Pinv, dt);
        
-       // TODO: unstable with quality=5 + stiffness=7000
-       // cg_filtered_pre(dV, A, B, z, S, P, Pinv);
+       itend();
+       // printf("cg_filtered calc time: %f\n", (float)itval());
        
+       cp_lfvector(olddV, dV, numverts);
+
        // advance velocities
        add_lfvector_lfvector(Vnew, lV, dV, numverts);
        
+
        del_lfvector(dFdXmV);
 }
 
 int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase *effectors)
-{
-       unsigned int i=0;
+{              
+       unsigned int i=0, j;
        float step=0.0f, tf=1.0f;
        Cloth *cloth = clmd->clothObject;
        ClothVertex *verts = cloth->verts;
        unsigned int numverts = cloth->numverts;
-       float dt = 1.0f / clmd->sim_parms->stepsPerFrame;
+       float dt = 1.0f / clmd->sim_parms.stepsPerFrame;
        Implicit_Data *id = cloth->implicit;
        int result = 0;
-       float force = 0, lastforce = 0;
-       // lfVector *dx;
        
-       if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) /* do goal stuff */
+       if(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) /* do goal stuff */
        {
                for(i = 0; i < numverts; i++)
                {                       
                        // update velocities with constrained velocities from pinned verts
                        if(verts [i].goal >= SOFTGOALSNAP)
                        {                       
-                               float temp[3];
-                               VECSUB(temp, cloth->xconst[i], cloth->xold[i]);
-                               VECSUB(id->z[i], temp, id->V[i]);
-                               
+                               VECSUB(id->V[i], verts[i].xconst, verts[i].xold);
                                // VecMulf(id->V[i], 1.0 / dt);
                        }
                }       
@@ -1445,43 +1382,13 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase
        {               
                effectors= pdInitEffectors(ob,NULL);
                
-               // clear constraint matrix from collisions
-               if(clmd->coll_parms->flags & CLOTH_COLLISIONSETTINGS_FLAG_ENABLED)
-               {
-                       for(i = 0; i < id->S[0].vcount; i++)
-                       {
-                               if(!(verts [id->S[i].r].goal >= SOFTGOALSNAP))
-                               {
-                                       id->S[0].vcount = i-1;
-                                       break;
-                               }
-                       }
-               }
-               
                // calculate 
-               cloth_calc_force(clmd, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step );
+               cloth_calc_force(clmd, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step );      
+               simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt, id->A, id->B, id->dV, id->S, id->z, id->olddV, id->P, id->Pinv);
                
-               // check for sleeping
-               // if(!(clmd->coll_parms->flags & CLOTH_SIMSETTINGS_FLAG_SLEEP))
-               {
-                       simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt, id->A, id->B, id->dV, id->S, id->z, id->P, id->Pinv);
+               add_lfvector_lfvectorS(id->Xnew, id->X, id->Vnew, dt, numverts);
                
-                       add_lfvector_lfvectorS(id->Xnew, id->X, id->Vnew, dt, numverts);
-               }
-               /*
-               dx = create_lfvector(numverts);
-               sub_lfvector_lfvector(dx, id->Xnew, id->X, numverts);
-               force = dot_lfvector(dx, dx, numverts);
-               del_lfvector(dx);
-               
-               if((force < 0.00001) && (lastforce >= force))
-               clmd->coll_parms->flags |= CLOTH_SIMSETTINGS_FLAG_SLEEP;
-               else if((lastforce*2 < force))
-               clmd->coll_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_SLEEP;
-               */
-               lastforce = force;
-               
-               if(clmd->coll_parms->flags & CLOTH_COLLISIONSETTINGS_FLAG_ENABLED)
+               if(clmd->coll_parms.flags & CLOTH_COLLISIONSETTINGS_FLAG_ENABLED)
                {
                        // collisions 
                        // itstart();
@@ -1489,42 +1396,46 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase
                        // update verts to current positions
                        for(i = 0; i < numverts; i++)
                        {               
-                               if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) /* do goal stuff */
+                               if(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL) /* do goal stuff */
                                {                       
                                        if(verts [i].goal >= SOFTGOALSNAP)
                                        {                       
                                                float tvect[3] = {.0,.0,.0};
                                                // VECSUB(tvect, id->Xnew[i], verts[i].xold);
                                                mul_fvector_S(tvect, id->V[i], step+dt);
-                                               VECADD(tvect, tvect, cloth->xold[i]);
+                                               VECADD(tvect, tvect, verts[i].xold);
                                                VECCOPY(id->Xnew[i], tvect);
                                        }
                                                
                                }
                                
-                               VECCOPY(cloth->current_x[i], id->Xnew[i]);
-                               VECSUB(cloth->current_v[i], cloth->current_x[i], cloth->current_xold[i]);
-                               VECCOPY(cloth->v[i], cloth->current_v[i]);
+                               VECCOPY(verts[i].tx, id->Xnew[i]);
+                               
+                               VECSUB(verts[i].tv, verts[i].tx, verts[i].txold);
+                               VECCOPY(verts[i].v, verts[i].tv);
                        }
-                       
+       
                        // call collision function
-                       result = cloth_bvh_objcollision(clmd, step + dt, step, dt);
-                       
+                       result = cloth_bvh_objcollision(clmd, step + dt, dt);
+       
                        // copy corrected positions back to simulation
-                       if(result)
-                       {
-                               memcpy(cloth->current_xold, cloth->current_x, sizeof(lfVector) * numverts);
-                               memcpy(id->Xnew, cloth->current_x, sizeof(lfVector) * numverts);
-                               
-                               for(i = 0; i < numverts; i++)
-                               {       
-                                       VECCOPY(id->Vnew[i], cloth->current_v[i]);
+                       for(i = 0; i < numverts; i++)
+                       {               
+                               if(result)
+                               {
+                                       // VECADD(verts[i].tx, verts[i].txold, verts[i].tv);
+                                       
+                                       VECCOPY(verts[i].txold, verts[i].tx);
+                                       
+                                       VECCOPY(id->Xnew[i], verts[i].tx);
+                                       
+                                       VECCOPY(id->Vnew[i], verts[i].tv);
                                        VecMulf(id->Vnew[i], 1.0f / dt);
                                }
-                       }
-                       else
-                       {
-                               memcpy(cloth->current_xold, id->Xnew, sizeof(lfVector) * numverts);
+                               else
+                               {
+                                       VECCOPY(verts[i].txold, id->Xnew[i]);
+                               }
                        }
                        
                        // X = Xnew;
@@ -1538,9 +1449,8 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase
                                
                                // calculate 
                                cloth_calc_force(clmd, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step);       
-                               simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt / 2.0f, id->A, id->B, id->dV, id->S, id->z, id->P, id->Pinv);
+                               simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt / 2.0f, id->A, id->B, id->dV, id->S, id->z, id->olddV, id->P, id->Pinv);
                        }
-                       
                }
                else
                {
@@ -1553,817 +1463,49 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase
                
                // V = Vnew;
                cp_lfvector(id->V, id->Vnew, numverts);
-               
+
                step += dt;
 
                if(effectors) pdEndEffectors(effectors);
        }
-       
-       if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL)
-       {
-               for(i = 0; i < numverts; i++)
+
+       for(i = 0; i < numverts; i++)
+       {                               
+               if(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL)
                {
                        if(verts [i].goal < SOFTGOALSNAP)
                        {
-                               VECCOPY(cloth->current_xold[i], id->X[i]);
-                               VECCOPY(cloth->x[i], id->X[i]);
+                               VECCOPY(verts[i].txold, id->X[i]);
+                               VECCOPY(verts[i].x, id->X[i]);
+                               VECCOPY(verts[i].v, id->V[i]);
                        }
                        else
                        {
-                               VECCOPY(cloth->current_xold[i], cloth->xconst[i]);
-                               VECCOPY(cloth->x[i], cloth->xconst[i]);
+                               VECCOPY(verts[i].txold, verts[i].xconst);
+                               VECCOPY(verts[i].x, verts[i].xconst);
+                               VECCOPY(verts[i].v, id->V[i]);
                        }
                }
+               else
+               {
+                       VECCOPY(verts[i].txold, id->X[i]);
+                       VECCOPY(verts[i].x, id->X[i]);
+                       VECCOPY(verts[i].v, id->V[i]);
+               }
        }
-       else
-       {
-               memcpy(cloth->current_xold, id->X, sizeof(lfVector) * numverts);
-               memcpy(cloth->x, id->X, sizeof(lfVector) * numverts);
-       }
-       
-       memcpy(cloth->v, id->V, sizeof(lfVector) * numverts);
-       
        return 1;
 }
 
 void implicit_set_positions (ClothModifierData *clmd)
 {              
        Cloth *cloth = clmd->clothObject;
-       unsigned int numverts = cloth->numverts;
-       Implicit_Data *id = cloth->implicit;
-       
-       memcpy(id->X, cloth->x, sizeof(lfVector) * numverts);   
-       memcpy(id->V, cloth->v, sizeof(lfVector) * numverts);   
-}
-
-unsigned int implicit_getcreate_S_index(ClothModifierData *clmd, unsigned int index)
-{
-       Cloth *cloth = clmd->clothObject;
+       ClothVertex *verts = cloth->verts;
+       unsigned int numverts = cloth->numverts, i;
        Implicit_Data *id = cloth->implicit;
-       unsigned int i = 0, pinned = 0;
-       
-       pinned = id->S[0].vcount;
-       
-       for(i = 0; i < pinned; i++)
-       {
-               if(id->S[i].r == index)
-               {
-                       return index;
-               }
-       }
-       
-       // create new PINNED entry in constraint matrix
-       id->S[0].vcount++;
-       id->S[pinned].c = id->S[pinned].r = index;
-       return pinned;
-}
-
-int collisions_collision_response_static ( ClothModifierData *clmd, CollisionModifierData *collmd, CollisionPair *collpair )
-{
-
-       unsigned int i = 0;
-       int result = 0;
-       LinkNode *search = NULL;
-       Cloth *cloth1 = NULL;
-       float w1, w2, w3, u1, u2, u3;
-       float v1[3], v2[3], relativeVelocity[3];
-       float magrelVel = 0.0;
-       float epsilon = clmd->coll_parms->epsilon;
-       
-
-       cloth1 = clmd->clothObject;
-       
-       if(!collpair)
-       {
-               return 0;
-       }
-       
-       // TODO: check distance & calc normal
-                       // calc distance + normal       
-       collpair->distance = plNearestPoints(
-               cloth1->current_xold[collpair->point_indexA[0]],
-               cloth1->current_xold[collpair->point_indexA[1]],
-               cloth1->current_xold[collpair->point_indexA[2]], 
-               collmd->current_x[collpair->point_indexB[0]].co,
-               collmd->current_x[collpair->point_indexB[1]].co,
-               collmd->current_x[collpair->point_indexB[2]].co, 
-               collpair->pa,collpair->pb,collpair->vector);
-                       
-       if (collpair->distance > (epsilon + ALMOST_ZERO))
-       {
-               printf("collpair->distance > (epsilon + ALMOST_ZERO)\n");
-               return 0;
-       }
-       
-       printf("IN1\n");
-
-       // compute barycentric coordinates for both collision points
-       collisions_compute_barycentric (collpair->pa,
-                                       cloth1->current_xold[collpair->point_indexA[0]],
-                                       cloth1->current_xold[collpair->point_indexA[1]],
-                                       cloth1->current_xold[collpair->point_indexA[2]],
-                                       &w1, &w2, &w3 );
-
-       collisions_compute_barycentric (collpair->pb,
-                                       collmd->current_x[collpair->point_indexB[0]].co,
-                                       collmd->current_x[collpair->point_indexB[1]].co,
-                                       collmd->current_x[collpair->point_indexB[2]].co,
-                                       &u1, &u2, &u3 );
-
-       // Calculate relative "velocity".
-       interpolateOnTriangle ( v1, cloth1->current_v[collpair->point_indexA[0]], cloth1->current_v[collpair->point_indexA[1]], cloth1->current_v[collpair->point_indexA[2]], w1, w2, w3 );
-
-       interpolateOnTriangle ( v2, collmd->current_v[collpair->point_indexB[0]].co, collmd->current_v[collpair->point_indexB[1]].co, collmd->current_v[collpair->point_indexB[2]].co, u1, u2, u3 );
-
-       VECSUB ( relativeVelocity, v1, v2 );
-
-       // Calculate the normal component of the relative velocity (actually only the magnitude - the direction is stored in 'normal').
-       magrelVel = INPR ( relativeVelocity, collpair->normal );
-
-       // printf("magrelVel: %f\n", magrelVel);
-
-       // Calculate masses of points.
-
-       // If v_n_mag < 0 the edges are approaching each other.
-       if ( magrelVel < -ALMOST_ZERO )
-       {
-               
-               // Calculate Impulse magnitude to stop all motion in normal direction.
-               // const double I_mag = v_n_mag / (1/m1 + 1/m2);
-               float magnitude_i = magrelVel / 2.0f; // TODO implement masses
-               float tangential[3], magtangent, magnormal, collvel[3];
-               float vrel_t_pre[3];
-               float vrel_t[3];
-               double impulse;
-               float overlap = ( epsilon + ALMOST_ZERO-collpair->distance );
-               
-               printf("magrelVel < -ALMOST_ZERO\n");
-
-               // calculateFrictionImpulse(tangential, relativeVelocity, collpair->normal, magrelVel, clmd->coll_parms.friction*0.01, magrelVel);
-
-               // magtangent = INPR(tangential, tangential);
-
-               // Apply friction impulse.
-               if ( magtangent < -ALMOST_ZERO )
-               {
-
-                       // printf("friction applied: %f\n", magtangent);
-                       // TODO check original code
-               }
-
-
-               impulse = -2.0f * magrelVel / ( 1.0 + w1*w1 + w2*w2 + w3*w3 );
-
-               // printf("impulse: %f\n", impulse);
-
-               // face A
-               VECADDMUL ( cloth1->verts[collpair->point_indexA[0]].impulse, collpair->normal, w1 * impulse );
-               cloth1->verts[collpair->point_indexA[0]].impulse_count++;
-
-               VECADDMUL ( cloth1->verts[collpair->point_indexA[1]].impulse, collpair->normal, w2 * impulse );
-               cloth1->verts[collpair->point_indexA[1]].impulse_count++;
-
-               VECADDMUL ( cloth1->verts[collpair->point_indexA[2]].impulse, collpair->normal, w3 * impulse );
-               cloth1->verts[collpair->point_indexA[2]].impulse_count++;
-
-               // face B
-               /*
-               VECADDMUL ( collmd->verts[collpair->point_indexB[0]].impulse, collpair->normal, u1 * impulse );
-               collmd->verts[collpair->point_indexB[0]].impulse_count++;
-
-               VECADDMUL ( collmd->verts[collpair->point_indexB[1]].impulse, collpair->normal, u2 * impulse );
-               collmd->verts[collpair->point_indexB[1]].impulse_count++;
-
-               VECADDMUL ( collmd->verts[collpair->point_indexB[2]].impulse, collpair->normal, u3 * impulse );
-               collmd->verts[collpair->point_indexB[2]].impulse_count++;
-               */
-               
-               
-               result = 1;
-
-               // printf("magnitude_i: %f\n", magnitude_i); // negative before collision in my case
-
-               // Apply the impulse and increase impulse counters.
-
-       }
-       
-       return result;
-}
-
-
-int collisions_collision_response_moving_tris(ClothModifierData *clmd, ClothModifierData *coll_clmd)
-{
-       return 0;
-}
-
-
-int collisions_collision_response_moving_edges(ClothModifierData *clmd, ClothModifierData *coll_clmd)
-{
-       return 0;
-}
-
-void cloth_collision_static(ClothModifierData *clmd, LinkNode *collision_list)
-{
-       /*
-       CollPair *collpair = NULL;
-       Cloth *cloth1=NULL, *cloth2=NULL;
-       MFace *face1=NULL, *face2=NULL;
-       ClothVertex *verts1=NULL, *verts2=NULL;
-       double distance = 0;
-       float epsilon = clmd->coll_parms->epsilon;
-       unsigned int i = 0;
-
-       for(i = 0; i < 4; i++)
-       {
-       collpair = (CollPair *)MEM_callocN(sizeof(CollPair), "cloth coll pair");        
-               
-       cloth1 = clmd->clothObject;
-       cloth2 = coll_clmd->clothObject;
-               
-       verts1 = cloth1->verts;
-       verts2 = cloth2->verts;
        
-       face1 = &(cloth1->mfaces[tree1->tri_index]);
-       face2 = &(cloth2->mfaces[tree2->tri_index]);
-               
-               // check all possible pairs of triangles
-       if(i == 0)
-       {
-       collpair->ap1 = face1->v1;
-       collpair->ap2 = face1->v2;
-       collpair->ap3 = face1->v3;
-                       
-       collpair->bp1 = face2->v1;
-       collpair->bp2 = face2->v2;
-       collpair->bp3 = face2->v3;
-                       
-}
-               
-       if(i == 1)
-       {
-       if(face1->v4)
-       {
-       collpair->ap1 = face1->v3;
-       collpair->ap2 = face1->v4;
-       collpair->ap3 = face1->v1;
-                               
-       collpair->bp1 = face2->v1;
-       collpair->bp2 = face2->v2;
-       collpair->bp3 = face2->v3;
-}
-       else
-       i++;
-}
-               
-       if(i == 2)
-       {
-       if(face2->v4)
-       {
-       collpair->ap1 = face1->v1;
-       collpair->ap2 = face1->v2;
-       collpair->ap3 = face1->v3;
-                               
-       collpair->bp1 = face2->v3;
-       collpair->bp2 = face2->v4;
-       collpair->bp3 = face2->v1;
-}
-       else
-       i+=2;
-}
-               
-       if(i == 3)
-       {
-       if((face1->v4)&&(face2->v4))
-       {
-       collpair->ap1 = face1->v3;
-       collpair->ap2 = face1->v4;
-       collpair->ap3 = face1->v1;
-                               
-       collpair->bp1 = face2->v3;
-       collpair->bp2 = face2->v4;
-       collpair->bp3 = face2->v1;
-}
-       else
-       i++;
-}
-       
-               
-       if(i < 4)
-       {
-                       // calc distance + normal       
-       distance = plNearestPoints(
-       verts1[collpair->ap1].txold, verts1[collpair->ap2].txold, verts1[collpair->ap3].txold, verts2[collpair->bp1].txold, verts2[collpair->bp2].txold, verts2[collpair->bp3].txold, collpair->pa,collpair->pb,collpair->vector);
-                       
-       if (distance <= (epsilon + ALMOST_ZERO))
-       {
-                               // printf("dist: %f\n", (float)distance);
-                               
-                               // collpair->face1 = tree1->tri_index;
-                               // collpair->face2 = tree2->tri_index;
-                               
-                               // VECCOPY(collpair->normal, collpair->vector);
-                               // Normalize(collpair->normal);
-                               
-                               // collpair->distance = distance;
-                               
-}
-       else
-       {
-       MEM_freeN(collpair);
-}
-}
-       else
-       {
-       MEM_freeN(collpair);
-}
-}
-       */
-}
-
-int collisions_are_edges_adjacent(ClothModifierData *clmd, ClothModifierData *coll_clmd, EdgeCollPair *edgecollpair)
-{
-       Cloth *cloth1, *cloth2;
-       ClothVertex *verts1, *verts2;
-       float temp[3];
-        /*
-       cloth1 = clmd->clothObject;
-       cloth2 = coll_clmd->clothObject;
-       
-       verts1 = cloth1->verts;
-       verts2 = cloth2->verts;
-       
-       VECSUB(temp, verts1[edgecollpair->p11].xold, verts2[edgecollpair->p21].xold);
-       if(ABS(INPR(temp, temp)) < ALMOST_ZERO)
-       return 1;
-       
-       VECSUB(temp, verts1[edgecollpair->p11].xold, verts2[edgecollpair->p22].xold);
-       if(ABS(INPR(temp, temp)) < ALMOST_ZERO)
-       return 1;
-       
-       VECSUB(temp, verts1[edgecollpair->p12].xold, verts2[edgecollpair->p21].xold);
-       if(ABS(INPR(temp, temp)) < ALMOST_ZERO)
-       return 1;
-       
-       VECSUB(temp, verts1[edgecollpair->p12].xold, verts2[edgecollpair->p22].xold);
-       if(ABS(INPR(temp, temp)) < ALMOST_ZERO)
-       return 1;
-        */
-       return 0;
-}
-
-
-void collisions_collision_moving_edges(ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree *tree1, CollisionTree *tree2)
-{
-       /*
-       EdgeCollPair edgecollpair;
-       Cloth *cloth1=NULL, *cloth2=NULL;
-       MFace *face1=NULL, *face2=NULL;
-       ClothVertex *verts1=NULL, *verts2=NULL;
-       double distance = 0;
-       float epsilon = clmd->coll_parms->epsilon;
-       unsigned int i = 0, j = 0, k = 0;
-       int numsolutions = 0;
-       float a[3], b[3], c[3], d[3], e[3], f[3], solution[3];
-       
-       cloth1 = clmd->clothObject;
-       cloth2 = coll_clmd->clothObject;
-       
-       verts1 = cloth1->verts;
-       verts2 = cloth2->verts;
-
-       face1 = &(cloth1->mfaces[tree1->tri_index]);
-       face2 = &(cloth2->mfaces[tree2->tri_index]);
-       
-       for( i = 0; i < 5; i++)
-       {
-       if(i == 0) 
-       {
-       edgecollpair.p11 = face1->v1;
-       edgecollpair.p12 = face1->v2;
-}
-       else if(i == 1) 
-       {
-       edgecollpair.p11 = face1->v2;
-       edgecollpair.p12 = face1->v3;
-}
-       else if(i == 2) 
-       {
-       if(face1->v4) 
-       {
-       edgecollpair.p11 = face1->v3;
-       edgecollpair.p12 = face1->v4;
-}
-       else 
-       {
-       edgecollpair.p11 = face1->v3;
-       edgecollpair.p12 = face1->v1;
-       i+=5; // get out of here after this edge pair is handled
-}
-}
-       else if(i == 3) 
-       {
-       if(face1->v4) 
-       {
-       edgecollpair.p11 = face1->v4;
-       edgecollpair.p12 = face1->v1;
-}      
-       else
-       continue;
-}
-       else
-       {
-       edgecollpair.p11 = face1->v3;
-       edgecollpair.p12 = face1->v1;
-}
-
-               
-       for( j = 0; j < 5; j++)
-       {
-       if(j == 0)
-       {
-       edgecollpair.p21 = face2->v1;
-       edgecollpair.p22 = face2->v2;
-}
-       else if(j == 1)
-       {
-       edgecollpair.p21 = face2->v2;
-       edgecollpair.p22 = face2->v3;
-}
-       else if(j == 2)
-       {
-       if(face2->v4) 
-       {
-       edgecollpair.p21 = face2->v3;
-       edgecollpair.p22 = face2->v4;
-}
-       else 
-       {
-       edgecollpair.p21 = face2->v3;
-       edgecollpair.p22 = face2->v1;
-}
-}
-       else if(j == 3)
-       {
-       if(face2->v4) 
-       {
-       edgecollpair.p21 = face2->v4;
-       edgecollpair.p22 = face2->v1;
-}
-       else
-       continue;
-}
-       else
-       {
-       edgecollpair.p21 = face2->v3;
-       edgecollpair.p22 = face2->v1;
-}
-                       
-                       
-       if(!collisions_are_edges_adjacent(clmd, coll_clmd, &edgecollpair))
-       {
-       VECSUB(a, verts1[edgecollpair.p12].xold, verts1[edgecollpair.p11].xold);
-       VECSUB(b, verts1[edgecollpair.p12].v, verts1[edgecollpair.p11].v);
-       VECSUB(c, verts1[edgecollpair.p21].xold, verts1[edgecollpair.p11].xold);
-       VECSUB(d, verts1[edgecollpair.p21].v, verts1[edgecollpair.p11].v);
-       VECSUB(e, verts2[edgecollpair.p22].xold, verts1[edgecollpair.p11].xold);
-       VECSUB(f, verts2[edgecollpair.p22].v, verts1[edgecollpair.p11].v);
-                               
-       numsolutions = collisions_get_collision_time(a, b, c, d, e, f, solution);
-                               
-       for (k = 0; k < numsolutions; k++) 
-       {                                                               
-       if ((solution[k] >= 0.0) && (solution[k] <= 1.0)) 
-       {
-       float out_collisionTime = solution[k];
-                                               
-                                               // TODO: check for collisions 
-                                               
-                                               // TODO: put into (edge) collision list
-                                               
-       printf("Moving edge found!\n");
-}
-}
-}
-}
-}      
-       */      
-}
-
-void collisions_collision_moving_tris(ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree *tree1, CollisionTree *tree2)
-{
-       /*
-       CollPair collpair;
-       Cloth *cloth1=NULL, *cloth2=NULL;
-       MFace *face1=NULL, *face2=NULL;
-       ClothVertex *verts1=NULL, *verts2=NULL;
-       double distance = 0;
-       float epsilon = clmd->coll_parms->epsilon;
-       unsigned int i = 0, j = 0, k = 0;
-       int numsolutions = 0;
-       float a[3], b[3], c[3], d[3], e[3], f[3], solution[3];
-
-       for(i = 0; i < 2; i++)
-       {               
-       cloth1 = clmd->clothObject;
-       cloth2 = coll_clmd->clothObject;
-               
-       verts1 = cloth1->verts;
-       verts2 = cloth2->verts;
-       
-       face1 = &(cloth1->mfaces[tree1->tri_index]);
-       face2 = &(cloth2->mfaces[tree2->tri_index]);
-               
-               // check all possible pairs of triangles
-       if(i == 0)
-       {
-       collpair.ap1 = face1->v1;
-       collpair.ap2 = face1->v2;
-       collpair.ap3 = face1->v3;
-                       
-       collpair.pointsb[0] = face2->v1;
-       collpair.pointsb[1] = face2->v2;
-       collpair.pointsb[2] = face2->v3;
-       collpair.pointsb[3] = face2->v4;
-}
-               
-       if(i == 1)
-       {
-       if(face1->v4)
-       {
-       collpair.ap1 = face1->v3;
-       collpair.ap2 = face1->v4;
-       collpair.ap3 = face1->v1;
-                               
-       collpair.pointsb[0] = face2->v1;
-       collpair.pointsb[1] = face2->v2;
-       collpair.pointsb[2] = face2->v3;
-       collpair.pointsb[3] = face2->v4;
-}
-       else
-       i++;
-}
-               
-               // calc SIPcode (?)
-               
-       if(i < 2)
-       {
-       VECSUB(a, verts1[collpair.ap2].xold, verts1[collpair.ap1].xold);
-       VECSUB(b, verts1[collpair.ap2].v, verts1[collpair.ap1].v);
-       VECSUB(c, verts1[collpair.ap3].xold, verts1[collpair.ap1].xold);
-       VECSUB(d, verts1[collpair.ap3].v, verts1[collpair.ap1].v);
-                               
-       for(j = 0; j < 4; j++)
-       {                                       
-       if((j==3) && !(face2->v4))
-       break;
-                               
-       VECSUB(e, verts2[collpair.pointsb[j]].xold, verts1[collpair.ap1].xold);
-       VECSUB(f, verts2[collpair.pointsb[j]].v, verts1[collpair.ap1].v);
-                               
-       numsolutions = collisions_get_collision_time(a, b, c, d, e, f, solution);
-                               
-       for (k = 0; k < numsolutions; k++) 
-       {                                                               
-       if ((solution[k] >= 0.0) && (solution[k] <= 1.0)) 
-       {
-       float out_collisionTime = solution[k];
-                                               
-                                               // TODO: check for collisions 
-                                               
-                                               // TODO: put into (point-face) collision list
-                                               
-       printf("Moving found!\n");
-                                               
-}
-}
-                               
-                               // TODO: check borders for collisions
-}
-                       
-}
-}
-       */
-}
-
-void collisions_collision_moving(ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree *tree1, CollisionTree *tree2)
-{
-       /*
-       // TODO: check for adjacent
-       collisions_collision_moving_edges(clmd, coll_clmd, tree1, tree2);
-       
-       collisions_collision_moving_tris(clmd, coll_clmd, tree1, tree2);
-       collisions_collision_moving_tris(coll_clmd, clmd, tree2, tree1);
-       */
-}
-
-// cloth - object collisions
-int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep, float dt)
-{
-       
-       Base *base = NULL;
-       CollisionModifierData *collmd = NULL;
-       Cloth *cloth = NULL;
-       Object *ob2 = NULL;
-       BVH *bvh1 = NULL, *bvh2 = NULL, *self_bvh;
-       LinkNode *collision_list = NULL; 
-       unsigned int i = 0, j = 0, index;
-       int collisions = 0, count = 0;
-       float (*current_x)[3];
-       Implicit_Data *id = NULL;
-       int ret = 0;
-       
-       if (!(((Cloth *)clmd->clothObject)->tree))
-       {
-               printf("No BVH found\n");
-               return 0;
-       }
-       
-       cloth = clmd->clothObject;
-       bvh1 = cloth->tree;
-       self_bvh = cloth->selftree;
-       id = cloth->implicit;
-       
-       ////////////////////////////////////////////////////////////
-       // static collisions
-       ////////////////////////////////////////////////////////////
-       
-       // update cloth bvh
-       bvh_update_from_float3 ( bvh1, cloth->current_xold, cloth->numverts, cloth->current_x, 0 ); // 0 means STATIC, 1 means MOVING (see later in this function)
-       
-       // check all collision objects
-       for ( base = G.scene->base.first; base; base = base->next )
-       {
-               ob2 = base->object;
-               collmd = ( CollisionModifierData * ) modifiers_findByType ( ob2, eModifierType_Collision );
-       
-               if ( !collmd )
-                       continue;
-       
-               // check if there is a bounding volume hierarchy
-               if ( collmd->tree )
-               {
-                       bvh2 = collmd->tree;
-       
-                       // update position + bvh of collision object
-                       collision_move_object ( collmd, step, prevstep );
-                       bvh_update_from_mvert ( collmd->tree, collmd->current_x, collmd->numverts, NULL, 0 );
-       
-                       // fill collision list
-                       collisions += bvh_traverse ( bvh1->root, bvh2->root, &collision_list );
-                       
-                       // call static collision response
-                       if ( collision_list )
-                       {
-                               LinkNode *search = collision_list;
-                               
-                               while ( search )
-                               {
-                                       collisions_collision_response_static(clmd, collmd, (CollisionPair *)search->link);
-                                       
-                                       search = search->next;
-                               }
-                       }
-                       
-                       // free collision list
-                       if ( collision_list )
-                       {
-                               LinkNode *search = collision_list;
-       
-                               while ( search )
-                               {
-                                       CollisionPair *coll_pair = search->link;
-       
-                                       MEM_freeN ( coll_pair );
-                                       search = search->next;
-                               }
-                               BLI_linklist_free ( collision_list,NULL );
-       
-                               collision_list = NULL;
-                       }
-               }
-       }
-       
-       // vertex weight = 2
-       
-       for(i = 0; i < cloth->numverts; i++)
-               if ((cloth->verts[i].impulse_count > 0) && !(cloth->verts[i].flags & CVERT_FLAG_PINNED))
-               {
-                       printf("applying impulse\n");
-                       
-                       VECADDS(cloth->current_v[i], cloth->current_v[i], cloth->verts[i].impulse, 1.0 / (cloth->verts[i].impulse_count * 2.0));
-                       
-                       // reset
-                       cloth->verts[i].impulse_count = 0;
-                       cloth->verts[i].impulse[0] = 0.0;
-                       cloth->verts[i].impulse[1] = 0.0;
-                       cloth->verts[i].impulse[2] = 0.0;
-                       
-                       ret = 1;
-               }
-       
-       //////////////////////////////////////////////
-       // update velocities + positions
-       //////////////////////////////////////////////
-       for(i = 0; i < cloth->numverts; i++)
-       {
-               VECADD(cloth->current_x[i], cloth->current_xold[i], cloth->current_v[i]);
-       }
-       //////////////////////////////////////////////
-       
-       
-       // Test on *simple* selfcollisions
-       collisions = 1;
-       count = 0;
-       current_x = cloth->current_x; // needed for openMP
-       /*
-       // #pragma omp parallel for private(i,j, collisions) shared(current_x)
-       // for ( count = 0; count < 6; count++ )
-       {
-               collisions = 0;
-       
-               for ( i = 0; i < cloth->numverts; i++ )
-               {
-                       float mindistance1 = cloth->verts[i].collball;
-                       
-                       for ( j = i + 1; j < cloth->numverts; j++ )
-                       {
-                               float temp[3];
-                               float length = 0;
-                               
-                               float mindistance2 = cloth->verts[j].collball;
-       
-                               if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )
-                               {
-                                       if ( ( cloth->verts [i].goal >= SOFTGOALSNAP )
-                                               && ( cloth->verts [j].goal >= SOFTGOALSNAP ) )
-                                       {
-                                               continue;
-                                       }
-                               }
-       
-                               // check for adjacent points
-                               if ( BLI_edgehash_haskey ( cloth->edgehash, i, j ) )
-                               {
-                                       continue;
-                               }
-       
-                               VECSUB ( temp, current_x[i], current_x[j] );
-       
-                               length = Normalize ( temp );
-       
-                               if ( length < ((mindistance1 + mindistance2)) )
-                               {
-                                       float correction = ((mindistance1 + mindistance2)) - length;
-                                       
-                                       if ( ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) && ( cloth->verts [i].goal >= SOFTGOALSNAP ) )
-                                       {
-                                               VecMulf ( temp, -correction );
-                                               VECADD ( current_x[j], current_x[j], temp );
-                                       }
-                                       else if ( ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) && ( cloth->verts [j].goal >= SOFTGOALSNAP ) )
-                                       {
-                                               VecMulf ( temp, correction );
-                                               VECADD ( current_x[i], current_x[i], temp );
-                                       }
-                                       else
-                                       {
-                                               unsigned int pinned = id->S[0].vcount;
-                                               
-                                               printf("correction: %f\n", correction);
-                                               
-                                               VecMulf ( temp, -correction*0.5 );
-                                               VECADD ( current_x[j], current_x[j], temp );
-                                               VECSUB ( cloth->current_v[j], cloth->current_x[j], cloth->current_xold[j] );
-                                               
-                                               index = implicit_getcreate_S_index(clmd, j);
-                                               id->S[index].pinned = 1;
-                                               
-                                               VECSUB ( current_x[i], current_x[i], temp );
-                                               VECSUB ( cloth->current_v[i], cloth->current_x[i], cloth->current_xold[i] );
-                                               
-                                               index = implicit_getcreate_S_index(clmd, i);
-                                               id->S[index].pinned = 1;
-                                               
-                                               cloth_add_spring (clmd, i, j, mindistance1 + mindistance2, CLOTH_SPRING_TYPE_COLLISION);
-                                       }
-       
-                                       collisions = 1;
-                               }
-                       }
-               }
-       }
-       */
-       
-       //////////////////////////////////////////////
-       // SELFCOLLISIONS: update velocities
-       //////////////////////////////////////////////
-       /*
-       for ( i = 0; i < cloth->numverts; i++ )
-       {
-               VECSUB ( cloth->current_v[i], cloth->current_x[i], cloth->current_xold[i] );
-       }
-       */
-       //////////////////////////////////////////////
-
-       return ret;
+       for(i = 0; i < numverts; i++)
+       {                               
+               VECCOPY(id->X[i], verts[i].x);
+               VECCOPY(id->V[i], verts[i].v);
+       }       
 }
index e7ce752424da556d505cc84b97b836bf75ae7e09..3b69f47b1f4f9e9171c24f2944f86187c64a2004 100644 (file)
@@ -75,7 +75,6 @@
 #include "BKE_main.h"
 #include "BKE_anim.h"
 #include "BKE_bad_level_calls.h"
-#include "BKE_collisions.h"
 #include "BKE_curve.h"
 #include "BKE_customdata.h"
 #include "BKE_global.h"
@@ -2727,7 +2726,7 @@ static void displaceModifier_foreachIDLink(ModifierData *md, Object *ob,
 {
        DisplaceModifierData *dmd = (DisplaceModifierData*) md;
 
-       walk(userData, ob, (ID **)&dmd->texture);
+       walk(userData, ob, &dmd->texture);
 
        displaceModifier_foreachObjectLink(md, ob, (ObjectWalkFunc) walk, userData);
 }
@@ -4947,15 +4946,9 @@ static void softbodyModifier_deformVerts(
 static void clothModifier_initData(ModifierData *md) 
 {
        ClothModifierData *clmd = (ClothModifierData*) md;
-       
-       clmd->sim_parms = MEM_callocN(sizeof(SimulationSettings),
-                   "cloth sim parms");
-       clmd->coll_parms = MEM_callocN(sizeof(CollisionSettings),
-                                     "cloth coll parms");
-       
        cloth_init (clmd);
 }
-/*
+
 static void clothModifier_deformVerts(
                ModifierData *md, Object *ob, DerivedMesh *derivedData,
                float (*vertexCos)[3], int numVerts)
@@ -4978,23 +4971,6 @@ static void clothModifier_deformVerts(
        if(dm)
                dm->release(dm);
 }
-*/
-
-static DerivedMesh *clothModifier_applyModifier(
-                 ModifierData *md, Object *ob, DerivedMesh *derivedData,
-                 int useRenderParams, int isFinalCalc)
-{
-       ClothModifierData *clmd = (ClothModifierData*) md;
-       DerivedMesh *result=NULL;
-
-       result = clothModifier_do(clmd, ob, derivedData, useRenderParams, isFinalCalc);
-
-       if(result)
-       {
-               return result;
-       }
-       return derivedData;
-}
 
 static void clothModifier_updateDepgraph(
                 ModifierData *md, DagForest *forest, Object *ob,
@@ -5011,13 +4987,14 @@ static void clothModifier_updateDepgraph(
                        Object *ob1= base->object;
                        if(ob1 != ob)
                        {
-                               CollisionModifierData *collmd = (CollisionModifierData *)modifiers_findByType(ob1, eModifierType_Collision);
-                               if(collmd)
-                               {
-                                       DagNode *curNode = dag_get_node(forest, ob1);
-                                       
-                                       dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA|DAG_RL_OB_DATA);
-                               
+                               ClothModifierData *coll_clmd = (ClothModifierData *)modifiers_findByType(ob1, eModifierType_Cloth);
+                               if(coll_clmd)
+                               {                                       
+                                       if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) 
+                                       {
+                                               DagNode *curNode = dag_get_node(forest, ob1);                                   
+                                               dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA|DAG_RL_OB_DATA);
+                                       }
                                }
                        }
                }
@@ -5026,12 +5003,12 @@ static void clothModifier_updateDepgraph(
 
 CustomDataMask clothModifier_requiredDataMask(ModifierData *md)
 {
-       ClothModifierData *clmd = (ClothModifierData *)md;
+       ClothModifierData *clmd = (HookModifierData *)md;
        CustomDataMask dataMask = 0;
 
        /* ask for vertexgroups if we need them */
-       if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL)
-               if (clmd->sim_parms->vgroup_mass > 0)
+       if(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL)
+               if (clmd->sim_parms.vgroup_mass > 0)
                        dataMask |= (1 << CD_MDEFORMVERT);
 
        return dataMask;
@@ -5049,154 +5026,9 @@ static void clothModifier_freeData(ModifierData *md)
        
        if (clmd) 
        {
-               
-               clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT;
+               clmd->sim_parms.flags &= ~CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT;
                cloth_free_modifier (clmd);
-               
-               MEM_freeN(clmd->sim_parms);
-               MEM_freeN(clmd->coll_parms);
-       }
-}
-
-/* Collision */
-
-static void collisionModifier_initData(ModifierData *md) 
-{
-       CollisionModifierData *collmd = (CollisionModifierData*) md;
-       
-       collmd->x = NULL;
-       collmd->xnew = NULL;
-       collmd->current_x = NULL;
-       collmd->current_xnew = NULL;
-       collmd->current_v = NULL;
-       collmd->time = -1;
-       collmd->numverts = 0;
-       collmd->tree = NULL;
-}
-
-static void collisionModifier_freeData(ModifierData *md)
-{
-       CollisionModifierData *collmd = (CollisionModifierData*) md;
-       
-       if (collmd) 
-       {
-               if(collmd->tree)
-                       bvh_free(collmd->tree);
-               if(collmd->x)
-                       MEM_freeN(collmd->x);
-               if(collmd->xnew)
-                       MEM_freeN(collmd->xnew);
-               if(collmd->current_x)
-                       MEM_freeN(collmd->current_x);
-               if(collmd->current_xnew)
-                       MEM_freeN(collmd->current_xnew);
-               if(collmd->current_v)
-                       MEM_freeN(collmd->current_v);
-               
-               collmd->x = NULL;
-               collmd->xnew = NULL;
-               collmd->current_x = NULL;
-               collmd->current_xnew = NULL;
-               collmd->current_v = NULL;
-               collmd->time = -1;
-               collmd->numverts = 0;
-               collmd->tree = NULL;
-       }
-}
-
-static int collisionModifier_dependsOnTime(ModifierData *md)
-{
-       return 1;
-}
-
-static void collisionModifier_deformVerts(
-                                     ModifierData *md, Object *ob, DerivedMesh *derivedData,
-         float (*vertexCos)[3], int numVerts)
-{
-       CollisionModifierData *collmd = (CollisionModifierData*) md;
-       DerivedMesh *dm = NULL;
-       float current_time = 0;
-       unsigned int numverts = 0, i = 0;
-       MVert *tempVert = NULL;
-
-       // if possible use/create DerivedMesh
-       
-       if(derivedData) dm = CDDM_copy(derivedData);
-       else if(ob->type==OB_MESH) dm = CDDM_from_mesh(ob->data, ob);
-       
-       if(!ob->pd)
-       {
-               printf("collisionModifier_deformVerts: Should not happen!\n");
-               return;
-       }
-       
-       if(dm)
-       {
-               CDDM_apply_vert_coords(dm, vertexCos);
-               CDDM_calc_normals(dm);
-       
-       
-               current_time = bsystem_time ( ob, ( float ) G.scene->r.cfra, 0.0 );
-               
-               if(current_time > collmd->time)
-               {
-                       numverts = dm->getNumVerts ( dm );
-                       
-                       // check if mesh has changed
-                       if(collmd->x && (numverts != collmd->numverts))
-                               collisionModifier_freeData((ModifierData *)collmd);
-                       
-                       if(collmd->time == -1) // first time
-                       {
-                               collmd->x = dm->dupVertArray(dm); // frame start position
-                               
-                               for ( i = 0; i < numverts; i++ )
-                               {
-                                       // we save global positions
-                                       Mat4MulVecfl ( ob->obmat, collmd->x[i].co );
-                               }
-                               
-                               collmd->xnew = MEM_dupallocN(collmd->x); // frame end position
-                               collmd->current_x = MEM_dupallocN(collmd->x); // inter-frame
-                               collmd->current_xnew = MEM_dupallocN(collmd->x); // inter-frame
-                               collmd->current_v = MEM_dupallocN(collmd->x); // inter-frame
-
-                               collmd->numverts = numverts;
-                               
-                               // TODO: epsilon
-                               // create bounding box hierarchy
-                               collmd->tree = bvh_build_from_mvert(dm->getFaceArray(dm), dm->getNumFaces(dm), collmd->current_x, numverts, ob->pd->pdef_sbift);
-                       }
-                       else if(numverts == collmd->numverts)
-                       {
-                               // put positions to old positions
-                               tempVert = collmd->x;
-                               collmd->x = collmd->xnew;
-                               collmd->xnew = tempVert;
-                               
-                               memcpy(collmd->xnew, dm->getVertArray(dm), numverts*sizeof(MVert));
-                               
-                               for ( i = 0; i < numverts; i++ )
-                               {
-                                       // we save global positions
-                                       Mat4MulVecfl ( ob->obmat, collmd->xnew[i].co );
-                               }
-                               
-                               memcpy(collmd->current_xnew, dm->getVertArray(dm), numverts*sizeof(MVert));
-                               memcpy(collmd->current_x, dm->getVertArray(dm), numverts*sizeof(MVert));
-                               
-                               // recalc static bounding boxes
-                               bvh_update_from_mvert(collmd->tree, collmd->current_x, numverts, NULL, 0);
-                               
-                               printf("bvh_update_from_mvert\n");
-                       }
-                       
-                       collmd->time = current_time;
-               }
        }
-       
-       if(dm)
-               dm->release(dm);
 }
 
 /* Boolean */
@@ -7010,10 +6842,10 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
                mti->deformVerts = softbodyModifier_deformVerts;
        
                mti = INIT_TYPE(Cloth);
-               mti->type = eModifierTypeType_Nonconstructive;
+               mti->type = eModifierTypeType_OnlyDeform;
                mti->initData = clothModifier_initData;
-               mti->flags = eModifierTypeFlag_AcceptsMesh
-                               | eModifierTypeFlag_RequiresOriginalData;
+               mti->flags = eModifierTypeFlag_AcceptsCVs;
+                                       // | eModifierTypeFlag_RequiresOriginalData;
                                        // | eModifierTypeFlag_SupportsMapping
                                        // | eModifierTypeFlag_SupportsEditmode 
                                        // | eModifierTypeFlag_EnableInEditmode;
@@ -7021,19 +6853,8 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
                mti->freeData = clothModifier_freeData; 
                mti->requiredDataMask = clothModifier_requiredDataMask;
                // mti->copyData = clothModifier_copyData;
-               // mti->deformVerts = clothModifier_deformVerts;
-               mti->applyModifier = clothModifier_applyModifier;
+               mti->deformVerts = clothModifier_deformVerts;
                mti->updateDepgraph = clothModifier_updateDepgraph;
-               
-               mti = INIT_TYPE(Collision);
-               mti->type = eModifierTypeType_OnlyDeform;
-               mti->initData = collisionModifier_initData;
-               mti->flags = eModifierTypeFlag_AcceptsMesh 
-                               | eModifierTypeFlag_RequiresOriginalData;
-               mti->dependsOnTime = collisionModifier_dependsOnTime;
-               mti->freeData = collisionModifier_freeData; 
-               mti->deformVerts = collisionModifier_deformVerts;
-               // mti->copyData = collisionModifier_copyData;
 
                mti = INIT_TYPE(Boolean);
                mti->type = eModifierTypeType_Nonconstructive;
@@ -7293,11 +7114,11 @@ int modifiers_isSoftbodyEnabled(Object *ob)
        return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render));
 }
 
-ClothModifierData *modifiers_isClothEnabled(Object *ob)
+ModifierData * modifiers_isClothEnabled(Object *ob)
 {
-       ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+       ModifierData *md = modifiers_findByType(ob, eModifierType_Cloth);
 
-       return clmd;
+       return md;
 }
 
 int modifiers_isParticleEnabled(Object *ob)
index d215bdf67cd334b75764d333c68638771dcb3f80..37d15b65de5c87dfe8ba11fba067bd99d3445e18 100644 (file)
@@ -2986,12 +2986,14 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
                   ClothModifierData    *clmd = (ClothModifierData*) md;
 
                   clmd->clothObject = NULL;
-                  
+                  /*
                   clmd->sim_parms= newdataadr(fd, clmd->sim_parms);
                   clmd->coll_parms= newdataadr(fd, clmd->coll_parms);
+                  */
                   
                } 
                else if (md->type==eModifierType_Collision) {
+                       /*
                        CollisionModifierData *collmd = (CollisionModifierData*) md;
                        
                        collmd->x = NULL;
@@ -3001,6 +3003,7 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
                        collmd->time = -1;
                        collmd->numverts = 0;
                        collmd->tree = NULL;
+                       */
                }
                else if (md->type==eModifierType_Hook) {
                        HookModifierData *hmd = (HookModifierData*) md;
index 275e3b18c4c4dd5b1ec486f682351159be644a12..3326d38c56f9747427e7d3db4e6842935fdc4327 100644 (file)
@@ -827,8 +827,10 @@ static void write_modifiers(WriteData *wd, ListBase *modbase)
                }
                else if(md->type==eModifierType_Cloth) {
                        ClothModifierData *clmd = (ClothModifierData*) md;
+                       /*
                        writestruct(wd, DATA, "SimulationSettings", 1, clmd->sim_parms);
                        writestruct(wd, DATA, "CollisionSettings", 1, clmd->coll_parms);
+                       */
                } 
                else if (md->type==eModifierType_MeshDeform) {
                        MeshDeformModifierData *mmd = (MeshDeformModifierData*) md;
index 4d8fbf1a6fc7f639a7cc9caf8933e583c5a10c47..2bbe328d170b68002544d39bb67d4746a69fa95b 100644 (file)
 #ifndef DNA_CLOTH_TYPES_H
 #define DNA_CLOTH_TYPES_H
 
-typedef struct SimulationSettings {
+#include "DNA_listBase.h"
+
+
+/**
+* Pin and unpin frames are the frames on which the vertices stop moving.
+* They will assume the position they had prior to pinFrame until unpinFrame
+* is reached.
+*/
+typedef struct ClothVertex
+{
+       int     flags;          /* General flags per vertex.            */
+       float   v [3];          /* The velocity of the point.           */
+       float   xconst [3];     /* constrained position                 */
+       float   x [3];          /* The current position of this vertex. */
+       float   xold [3];       /* The previous position of this vertex.*/
+       float   tx [3];         /* temporary position */
+       float   txold [3];      /* temporary old position */
+       float   tv[3];          /* temporary "velocity", mostly used as tv = tx-txold */
+       float   mass;           /* mass / weight of the vertex          */
+       float   goal;           /* goal, from SB                        */
+       float   impulse[3];     /* used in collision.c */
+       unsigned int impulse_count; /* same as above */
+}
+ClothVertex;
+
+
+/**
+* The definition of a spring.
+*/
+typedef struct ClothSpring
+{
+       int     ij;             /* Pij from the paper, one end of the spring.   */
+       int     kl;             /* Pkl from the paper, one end of the spring.   */
+       float   restlen;        /* The original length of the spring.   */
+       int     matrix_index;   /* needed for implicit solver (fast lookup) */
+       int     type;           /* types defined in BKE_cloth.h ("springType") */
+       int     flags;          /* defined in BKE_cloth.h, e.g. deactivated due to tearing */
+       float dfdx[3][3];
+       float dfdv[3][3];
+       float f[3];
+}
+ClothSpring;
+
+
+
+/**
+* This struct contains all the global data required to run a simulation.
+* At the time of this writing, this structure contains data appropriate
+* to run a simulation as described in Deformation Constraints in a
+* Mass-Spring Model to Describe Rigid Cloth Behavior by Xavier Provot.
+*
+* I've tried to keep similar, if not exact names for the variables as
+* are presented in the paper.  Where I've changed the concept slightly,
+* as in stepsPerFrame comapred to the time step in the paper, I've used
+* variables with different names to minimize confusion.
+**/
+typedef struct SimulationSettings
+{
        short   vgroup_mass;    /* optional vertexgroup name for assigning weight.      */
        short   pad;
        float   mingoal;        /* see SB */
@@ -55,23 +112,56 @@ typedef struct SimulationSettings {
        float   eff_force_scale;/* Scaling of effector forces (see softbody_calc_forces).*/
        float   eff_wind_scale; /* Scaling of effector wind (see softbody_calc_forces). */
        float   sim_time_old;
+       struct  LinkNode *cache;
        float   defgoal;
-       float   goalfrict;
+       int     goalfrict;
        float   goalspring;
        int     maxspringlen;   /* in percent!; if tearing enabled, a spring will get cut */
        int     lastframe;      /* frame on which simulation stops */
        int     firstframe;     /* frame on which simulation starts */
-} SimulationSettings;
+       struct Object *ob;
+}
+SimulationSettings;
+
 
-typedef struct CollisionSettings {
+typedef struct CollisionSettings
+{
        float   epsilon;                /* The radius of a particle in the cloth.               */
        float   self_friction;          /* Fiction/damping with self contact.                   */
        float   friction;               /* Friction/damping applied on contact with other object.*/
        short   collision_type;         /* which collision system is used.                      */
        short   loop_count;             /* How many iterations for the collision loop.          */
+       struct  LinkNode *collision_list;       /* e.g. pointer to temp memory for collisions */
        int     flags;                  /* collision flags defined in BKE_cloth.h */
-       float   selfepsilon;
-} CollisionSettings;
+       int     pad;
+}
+CollisionSettings;
 
 
+/**
+* This structure describes a cloth object against which the
+* simulation can run.
+*
+* The m and n members of this structure represent the assumed
+* rectangular ordered grid for which the original paper is written.
+* At some point they need to disappear and we need to determine out
+* own connectivity of the mesh based on the actual edges in the mesh.
+*
+**/
+typedef struct Cloth
+{
+       struct ClothVertex      *verts;                 /* The vertices that represent this cloth. */
+       struct  LinkNode        *springs;               /* The springs connecting the mesh. */
+       unsigned int            numverts;               /* The number of verts == m * n. */
+       unsigned int            numsprings;             /* The count of springs. */
+       unsigned int            numfaces;
+       unsigned char           old_solver_type;
+       unsigned char           pad2;
+       short                   pad3;
+       void                    *tree;                  /* collision tree for this cloth object */
+       struct MFace            *mfaces;
+       void                    *implicit;              /* our implicit solver connects to this pointer */
+}
+Cloth;
+
 #endif
index 384ac37484d33e5ee87289823730e185b9f21272..f8b6f4202a5b49faeddbb7afec56ff55e27284de 100644 (file)
@@ -7,6 +7,8 @@
 
 #define MODSTACK_DEBUG 1
 
+#include "DNA_cloth_types.h"
+
 /* WARNING ALERT! TYPEDEF VALUES ARE WRITTEN IN FILES! SO DO NOT CHANGE! */
 
 typedef enum ModifierType {
@@ -347,8 +349,8 @@ typedef struct ClothModifierData {
    ModifierData                modifier;
 
    struct Cloth *clothObject; /* The internal data structure for cloth. */
-   struct SimulationSettings *sim_parms; /* definition is in DNA_cloth_types.h */
-   struct CollisionSettings *coll_parms; /* definition is in DNA_cloth_types.h */
+   struct SimulationSettings sim_parms; /* definition is in DNA_cloth_types.h */
+   struct CollisionSettings coll_parms; /* definition is in DNA_cloth_types.h */
 } ClothModifierData;
 
 typedef struct CollisionModifierData {
index f71f6adb051edf3c8d137112525030278b9070c1..662e0df093b0b1bab3b816b6e2650d35fd977d36 100644 (file)
@@ -48,7 +48,6 @@
 
 #include "BKE_action.h"
 #include "BKE_cloth.h"
-#include "BKE_collisions.h"
 #include "BKE_global.h"
 #include "BKE_main.h"
 #include "BKE_library.h"
@@ -2989,29 +2988,66 @@ void do_effects_panels(unsigned short event)
                allqueue(REDRAWVIEW3D, 0);
                break;
        case B_CLOTH_CLEARCACHEALL:
+       {
+               ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+               if(clmd)
+               {
+                       CFRA= 1;
+                       update_for_newframe_muted();
+                       DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); 
+                       cloth_clear_cache(ob, clmd, 2); 
+                       allqueue(REDRAWBUTSOBJECT, 0);
+                       allqueue(REDRAWVIEW3D, 0);
+               }       
+       }
+       break;  
+       case B_CLOTH_CLEARCACHEFRAME:
+       {
+               ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+               if(clmd)
                {
-                       ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
-                       if(clmd)
+                       cloth_clear_cache(ob, clmd, MAX2(2.0,G.scene->r.cfra + 1.0));
+                       allqueue(REDRAWBUTSOBJECT, 0);
+               }
+       }
+       break;  
+       case B_CLOTH_CHANGEPREROLL:
+       {
+               ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+               if(clmd)
+               {
+                       if(clmd->sim_parms.cache)
                        {
                                CFRA= 1;
                                update_for_newframe_muted();
                                DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); 
-                               cloth_clear_cache(ob, clmd, 2); 
                                allqueue(REDRAWBUTSOBJECT, 0);
                                allqueue(REDRAWVIEW3D, 0);
-                       }       
+                       }
                }
-               break;  
+       }
+       break;  
+       case B_CLOTH_DEL_VG:
+       {
+               ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+               if(clmd)
+               {
+                       clmd->sim_parms.vgroup_mass = 0;
+                       do_object_panels(B_CLOTH_RENEW);
+               }
+               allqueue(REDRAWBUTSOBJECT, 0);
+       }
+       break;  
        case B_CLOTH_RENEW:
+       {
+               ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+               if(clmd)
                {
-                       ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
-                       if(clmd)
-                       {
-                               do_object_panels(B_CLOTH_CLEARCACHEALL);
-                               cloth_free_modifier (clmd);
-                       }
+                       do_object_panels(B_CLOTH_CLEARCACHEALL);
+                       cloth_free_modifier (clmd);
                }
-               break;
+       }
+       break;
        default:
                if(event>=B_SELEFFECT && event<B_SELEFFECT+MAX_EFFECT) {
                        ob= OBACT;
@@ -4787,9 +4823,9 @@ static void object_panel_cloth(Object *ob)
        
        if(clmd)
        {
-               // but = uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_COLLOBJ, B_EFFECT_DEP, "Collision Object",     170,200,130,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Sets object to become a cloth collision object");
+               but = uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_COLLOBJ, B_EFFECT_DEP, "Collision Object",        170,200,130,20, &clmd->sim_parms.flags, 0, 0, 0, 0, "Sets object to become a cloth collision object");
 
-               if (!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ))
+               if (!(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ))
                {
                        Cloth *cloth = clmd->clothObject;
                        int defCount;
@@ -4798,18 +4834,18 @@ static void object_panel_cloth(Object *ob)
        
                        val2=0;
        
-       //              uiDefButBitI(block, TOG, CSIMSETT_FLAG_ADVANCED, REDRAWBUTSOBJECT, "Advanced",  180,200,130,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Enable advanced mode");
+       //              uiDefButBitI(block, TOG, CSIMSETT_FLAG_ADVANCED, REDRAWBUTSOBJECT, "Advanced",  180,200,130,20, &clmd->sim_parms.flags, 0, 0, 0, 0, "Enable advanced mode");
                        
                        /* GENERAL STUFF */
                        uiClearButLock();
                        uiBlockBeginAlign(block);
-                       uiDefButF(block, NUM, B_CLOTH_RENEW, "StructStiff:",       10,170,150,20, &clmd->sim_parms->structural, 1.0, 10000.0, 100, 0, "Overall stiffness of structure");
-                       uiDefButF(block, NUM, B_CLOTH_RENEW, "BendStiff:",         160,170,150,20, &clmd->sim_parms->bending, 0.0, 10000.0, 1000, 0, "Wrinkle possibility");
-                       uiDefButI(block, NUM, B_CLOTH_RENEW, "Quality:",  10,150,150,20, &clmd->sim_parms->stepsPerFrame, 3.0, 10.0, 5, 0, "Quality of the simulation (higher=>better=>slower)");
+                       uiDefButF(block, NUM, B_CLOTH_RENEW, "StructStiff:",       10,170,150,20, &clmd->sim_parms.structural, 1.0, 10000.0, 100, 0, "Overall stiffness of structure");
+                       uiDefButF(block, NUM, B_CLOTH_RENEW, "BendStiff:",         160,170,150,20, &clmd->sim_parms.bending, 0.0, 10000.0, 1000, 0, "Wrinkle possibility");
+                       uiDefButI(block, NUM, B_CLOTH_RENEW, "Steps per Frame:",           10,150,150,20, &clmd->sim_parms.stepsPerFrame, 1.0, 100.0, 5, 0, "Quality of the simulation (higher=better=slower)");
                        uiBlockEndAlign(block);
                        uiBlockBeginAlign(block);
-                       uiDefButF(block, NUM, B_CLOTH_RENEW, "Spring Damp:",       160,150,150,20, &clmd->sim_parms->Cdis, 0.0, 10.0, 10, 0, "Spring damping");
-                       uiDefButF(block, NUM, B_DIFF, "Air Damp:",         10,130,150,20, &clmd->sim_parms->Cvi, 0.0, 10.0, 10, 0, "Apply gravitation to point movement");
+                       uiDefButF(block, NUM, B_CLOTH_RENEW, "Spring Damp:",       160,150,150,20, &clmd->sim_parms.Cdis, 0.0, 10.0, 10, 0, "Spring damping");
+                       uiDefButF(block, NUM, B_DIFF, "Air Damp:",         10,130,150,20, &clmd->sim_parms.Cvi, 0.0, 10.0, 10, 0, "Apply gravitation to point movement");
                        uiBlockEndAlign(block);                 
                        
                        uiClearButLock();
@@ -4818,15 +4854,15 @@ static void object_panel_cloth(Object *ob)
                        uiDefBut(block, LABEL, 0, "Gravity:",  10,100,60,20, NULL, 0.0, 0, 0, 0, "");
                        // uiClearButLock();
                        
-                       uiDefButF(block, NUM, B_CLOTH_RENEW, "X:",         70,100,80,20, &clmd->sim_parms->gravity[0], -100.0, 100.0, 10, 0, "Apply gravitation to point movement");
-                       uiDefButF(block, NUM, B_CLOTH_RENEW, "Y:",         150,100,80,20, &clmd->sim_parms->gravity[1], -100.0, 100.0, 10, 0, "Apply gravitation to point movement");
-                       uiDefButF(block, NUM, B_CLOTH_RENEW, "Z:",         230,100,80,20, &clmd->sim_parms->gravity[2], -100.0, 100.0, 10, 0, "Apply gravitation to point movement");
+                       uiDefButF(block, NUM, B_CLOTH_RENEW, "X:",         70,100,80,20, &clmd->sim_parms.gravity[0], -100.0, 100.0, 10, 0, "Apply gravitation to point movement");
+                       uiDefButF(block, NUM, B_CLOTH_RENEW, "Y:",         150,100,80,20, &clmd->sim_parms.gravity[1], -100.0, 100.0, 10, 0, "Apply gravitation to point movement");
+                       uiDefButF(block, NUM, B_CLOTH_RENEW, "Z:",         230,100,80,20, &clmd->sim_parms.gravity[2], -100.0, 100.0, 10, 0, "Apply gravitation to point movement");
                        uiBlockEndAlign(block);
                        
                        /* GOAL STUFF */
                        uiBlockBeginAlign(block);
-                       uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_GOAL, REDRAWVIEW3D, "Use Goal", 10,70,130,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Define forces for vertices to stick to animated position");
-                       if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL)
+                       uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_GOAL, REDRAWVIEW3D, "Use Goal", 10,70,130,20, &clmd->sim_parms.flags, 0, 0, 0, 0, "Define forces for vertices to stick to animated position");
+                       if (clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL)
                        {
                                if(ob->type==OB_MESH) 
                                {
@@ -4841,17 +4877,17 @@ static void object_panel_cloth(Object *ob)
                                        defCount = BLI_countlist (&ob->defbase);
                                        if (defCount == 0) 
                                        {
-                                               clmd->sim_parms->vgroup_mass = 0;
+                                               clmd->sim_parms.vgroup_mass = 0;
                                        }
                                        sprintf (clvg2, "%s%s", clmvg, clvg1);
                                        
-                                       uiDefButS(block, MENU, B_CLOTH_RENEW, clvg2,    140,70,20,20, &clmd->sim_parms->vgroup_mass, 0, defCount, 0, 0, "Browses available vertex groups");     
+                                       uiDefButS(block, MENU, B_CLOTH_RENEW, clvg2,    140,70,20,20, &clmd->sim_parms.vgroup_mass, 0, defCount, 0, 0, "Browses available vertex groups");      
                                        MEM_freeN (clvg1);
                                        MEM_freeN (clvg2);
                                        
-                                       if(clmd->sim_parms->vgroup_mass) 
+                                       if(clmd->sim_parms.vgroup_mass) 
                                        {
-                                               bDeformGroup *defGroup = BLI_findlink(&ob->defbase, clmd->sim_parms->vgroup_mass-1);
+                                               bDeformGroup *defGroup = BLI_findlink(&ob->defbase, clmd->sim_parms.vgroup_mass-1);
                                                if(defGroup)
                                                        uiDefBut(block, BUT, B_DIFF, defGroup->name,    160,70,130,20, NULL, 0.0, 0.0, 0, 0, "Name of current vertex group");
                                                else
@@ -4861,31 +4897,31 @@ static void object_panel_cloth(Object *ob)
                                                
                                        }
                                        else
-                                               uiDefButF(block, NUM, B_CLOTH_RENEW, "Goal:",   160,70,150,20, &clmd->sim_parms->defgoal, 0.0, 1.0, 10, 0, "Default Goal (vertex target position) value, when no Vertex Group used");
+                                               uiDefButF(block, NUM, B_CLOTH_RENEW, "Goal:",   160,70,150,20, &clmd->sim_parms.defgoal, 0.0, 1.0, 10, 0, "Default Goal (vertex target position) value, when no Vertex Group used");
                                
                                }
                                else 
                                {
-                                       uiDefButS(block, TOG, B_CLOTH_RENEW, "W",                       140,70,20,20, &clmd->sim_parms->vgroup_mass, 0, 1, 0, 0, "Use control point weight values");
-                                       uiDefButF(block, NUM, B_CLOTH_RENEW, "Goal:",   160,70,150,20, &clmd->sim_parms->defgoal, 0.0, 1.0, 10, 0, "Default Goal (vertex target position) value, when no Vertex Group used");
+                                       uiDefButS(block, TOG, B_CLOTH_RENEW, "W",                       140,70,20,20, &clmd->sim_parms.vgroup_mass, 0, 1, 0, 0, "Use control point weight values");
+                                       uiDefButF(block, NUM, B_CLOTH_RENEW, "Goal:",   160,70,150,20, &clmd->sim_parms.defgoal, 0.0, 1.0, 10, 0, "Default Goal (vertex target position) value, when no Vertex Group used");
                                }
                                
-                               uiDefButF(block, NUM, B_CLOTH_RENEW, "G Stiff:",        10,50,150,20, &clmd->sim_parms->goalspring, 0.0, 500.0, 10, 0, "Goal (vertex target position) spring stiffness");
-                               uiDefButF(block, NUM, B_CLOTH_RENEW, "G Damp:", 160,50,150,20, &clmd->sim_parms->goalfrict, 0.0, 50.0, 10, 0, "Goal (vertex target position) friction");
-                               uiDefButF(block, NUM, B_CLOTH_RENEW, "G Min:",          10,30,150,20, &clmd->sim_parms->mingoal, 0.0, 1.0, 10, 0, "Goal minimum, vertex group weights are scaled to match this range");
-                               uiDefButF(block, NUM, B_CLOTH_RENEW, "G Max:",          160,30,150,20, &clmd->sim_parms->maxgoal, 0.0, 1.0, 10, 0, "Goal maximum, vertex group weights are scaled to match this range");
+                               uiDefButF(block, NUM, B_CLOTH_RENEW, "G Stiff:",        10,50,150,20, &clmd->sim_parms.goalspring, 0.0, 500.0, 10, 0, "Goal (vertex target position) spring stiffness");
+                               uiDefButF(block, NUM, B_CLOTH_RENEW, "G Damp:", 160,50,150,20, &clmd->sim_parms.goalfrict  , 0.0, 50.0, 10, 0, "Goal (vertex target position) friction");
+                               uiDefButF(block, NUM, B_CLOTH_RENEW, "G Min:",          10,30,150,20, &clmd->sim_parms.mingoal, 0.0, 1.0, 10, 0, "Goal minimum, vertex group weights are scaled to match this range");
+                               uiDefButF(block, NUM, B_CLOTH_RENEW, "G Max:",          160,30,150,20, &clmd->sim_parms.maxgoal, 0.0, 1.0, 10, 0, "Goal maximum, vertex group weights are scaled to match this range");
                        }
                        uiBlockEndAlign(block); 
                        
                        /*
                        // no tearing supported anymore since modifier stack restrictions 
                        uiBlockBeginAlign(block);
-                       uiDefButBitI(block, TOG, CSIMSETT_FLAG_TEARING_ENABLED, B_EFFECT_DEP, "Tearing",        10,0,150,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Sets object to become a cloth collision object");
+                       uiDefButBitI(block, TOG, CSIMSETT_FLAG_TEARING_ENABLED, B_EFFECT_DEP, "Tearing",        10,0,150,20, &clmd->sim_parms.flags, 0, 0, 0, 0, "Sets object to become a cloth collision object");
                        
-                       if (clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED)
+                       if (clmd->sim_parms.flags & CSIMSETT_FLAG_TEARING_ENABLED)
                        {
-                               uiDefButI(block, NUM, B_DIFF, "Max extent:",       160,0,150,20, &clmd->sim_parms->maxspringlen, 1.0, 1000.0, 10, 0, "Maximum extension before spring gets cut");
-                       }
+                       uiDefButI(block, NUM, B_DIFF, "Max extent:",       160,0,150,20, &clmd->sim_parms.maxspringlen, 1.0, 1000.0, 10, 0, "Maximum extension before spring gets cut");
+               }
                        
                        uiBlockEndAlign(block); 
                        */
@@ -4904,7 +4940,7 @@ static void object_panel_cloth_II(Object *ob)
        clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
        if(clmd)
        {
-               if (!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ))
+               if (!(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ))
                {
                        Cloth *cloth = clmd->clothObject;
                        char str[128];
@@ -4915,18 +4951,18 @@ static void object_panel_cloth_II(Object *ob)
                
                        uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
                        
-                       uiDefButI(block, NUM, B_DIFF, "First Frame:",           10,160,150,20, &clmd->sim_parms->firstframe, 0, MAXFRAME, 1, 0, "Frame on which the simulation starts");
-                       uiDefButI(block, NUM, B_DIFF, "Last Frame:",            160,160,150,20, &clmd->sim_parms->lastframe, 0, MAXFRAME, 10, 0, "Frame on which the simulation stops");
-                       /*
-                       if(clmd->sim_parms->cache)
+                       uiDefButI(block, NUM, B_DIFF, "First Frame:",           10,160,150,20, &clmd->sim_parms.firstframe, 0, MAXFRAME, 1, 0, "Frame on which the simulation starts");
+                       uiDefButI(block, NUM, B_DIFF, "Last Frame:",            160,160,150,20, &clmd->sim_parms.lastframe, 0, MAXFRAME, 10, 0, "Frame on which the simulation stops");
+
+                       if(clmd->sim_parms.cache)
                        {
-                               int length = BLI_linklist_length(clmd->sim_parms->cache);
+                               int length = BLI_linklist_length(clmd->sim_parms.cache);
                                
-                               // correct spelling if only 1 frame cacheed --> only gimmick  
-                               if(length-clmd->sim_parms->preroll>1)
-                                       sprintf (str, "Frame 1 - %d cached. [%d in preroll, %d in total]", length-clmd->sim_parms->preroll, clmd->sim_parms->preroll, length);
+                               /* correct spelling if only 1 frame cacheed --> only gimmick  */
+                               if(length-clmd->sim_parms.preroll>1)
+                                       sprintf (str, "Frame 1 - %d cached. [%d in preroll, %d in total]", length-clmd->sim_parms.preroll, clmd->sim_parms.preroll, length);
                                else
-                                       sprintf (str, "Frame %d cached. [%d in preroll, %d in total]", length-clmd->sim_parms->preroll, clmd->sim_parms->preroll, length);
+                                       sprintf (str, "Frame %d cached. [%d in preroll, %d in total]", length-clmd->sim_parms.preroll, clmd->sim_parms.preroll, length);
                                
                                uiDefBut(block, LABEL, 0, str,  10,140,290,20, NULL, 0.0, 0, 0, 0, "");
                                uiDefBut(block, LABEL, 0, "Clear cache:",  10,120,290,20, NULL, 0.0, 0, 0, 0, "");
@@ -4934,15 +4970,15 @@ static void object_panel_cloth_II(Object *ob)
                                uiDefBut(block, BUT, B_CLOTH_CLEARCACHEALL, "All", 10, 100,145,20, NULL, 0.0, 0.0, 0, 0, "Free cloth cache without preroll");
                                uiDefBut(block, BUT, B_CLOTH_CLEARCACHEFRAME, "From next frame", 155, 100,145,20, NULL, 0.0, 0.0, 0, 0, "Free cloth cache");    
                                if(length>1) // B_CLOTH_CHANGEPREROLL
-                                       uiDefButI(block, NUM, B_CLOTH_CHANGEPREROLL, "Preroll:", 10,80,145,20, &clmd->sim_parms->preroll, 0, length-1, 1, 0, "Simulation starts on this frame");        
+                                       uiDefButI(block, NUM, B_CLOTH_CHANGEPREROLL, "Preroll:", 10,80,145,20, &clmd->sim_parms.preroll, 0, length-1, 1, 0, "Simulation starts on this frame"); 
                                else
                                        uiDefBut(block, LABEL, 0, " ",  10,80,145,20, NULL, 0.0, 0, 0, 0, "");
                        }
-                       else 
+                       else
                        {
                                uiDefBut(block, LABEL, 0, "No frames cached.",  10,120,290,20, NULL, 0.0, 0, 0, 0, "");
-                       }*/
-                       uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT, REDRAWVIEW3D, "Protect Cache",  10,50,145,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Protect cache from automatic freeing when scene changed");
+                       }
+                       uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT, REDRAWVIEW3D, "Protect Cache",  10,50,145,20, &clmd->sim_parms.flags, 0, 0, 0, 0, "Protect cache from automatic freeing when scene changed");
                        uiBlockEndAlign(block);
                }
        }
@@ -4952,32 +4988,41 @@ static void object_panel_cloth_II(Object *ob)
 static void object_panel_cloth_III(Object *ob)
 {
        uiBlock *block;
+       static int val;
+       uiBut *but;
        ClothModifierData *clmd = NULL;
        
        clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
        if(clmd)
-       {       
-               block= uiNewBlock(&curarea->uiblocks, "object_panel_cloth_III", UI_EMBOSS, UI_HELV, curarea->win);
-               uiNewPanelTabbed("Cloth", "Physics");
-               if(uiNewPanel(curarea, block, "Cloth Collisions", "Physics", 651, 0, 318, 204)==0) return;
-       
-               uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
-               
-               uiBlockBeginAlign(block);
-               uiDefButBitI(block, TOG, CLOTH_COLLISIONSETTINGS_FLAG_ENABLED, REDRAWVIEW3D, "Enable collisions",       10,160,130,20, &clmd->coll_parms->flags, 0, 0, 0, 0, "Enable collisions with this object");
-               if (clmd->coll_parms->flags & CLOTH_COLLISIONSETTINGS_FLAG_ENABLED)
+       {
+               if (!(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ))
                {
-                       // uiDefBut(block, LABEL, 0, "",10,10,300,20, NULL, 0.0, 0, 0, 0, ""); /* tell UI we go to 10,10*/
-                       uiDefButF(block, NUM, B_CLOTH_RENEW, "Min Distance:",      10,140,150,20, &clmd->coll_parms->epsilon, 0.001f, 1.0, 0.01f, 0, "Minimum distance between collision objects before collision response takes in");
-                       uiDefBut(block, LABEL, 0, "",160,140,150,20, NULL, 0.0, 0, 0, 0, "");
-                       uiDefButF(block, NUM, B_CLOTH_RENEW, "Selfcoll balls:",    10,120,150,20, &clmd->coll_parms->selfepsilon, 0.001f, 1.0, 0.49f, 0, "Minimum distance between two selfcollision points");
+                       Cloth *cloth = clmd->clothObject;
+                       char str[128];
+                       
+                       block= uiNewBlock(&curarea->uiblocks, "object_panel_cloth_III", UI_EMBOSS, UI_HELV, curarea->win);
+                       uiNewPanelTabbed("Cloth", "Physics");
+                       if(uiNewPanel(curarea, block, "Cloth Collisions", "Physics", 651, 0, 318, 204)==0) return;
+               
+                       uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
+                       
+                       uiBlockBeginAlign(block);
+                       uiDefButBitI(block, TOG, CLOTH_COLLISIONSETTINGS_FLAG_ENABLED, REDRAWVIEW3D, "Enable collisions",       10,70,130,20, &clmd->coll_parms.flags, 0, 0, 0, 0, "Enable collisions with this object");
+                       if (clmd->coll_parms.flags & CLOTH_COLLISIONSETTINGS_FLAG_ENABLED)
+                       {
+                               // uiDefBut(block, LABEL, 0, "",10,10,300,20, NULL, 0.0, 0, 0, 0, ""); /* tell UI we go to 10,10*/
+                               uiDefButF(block, NUM, B_CLOTH_RENEW, "Min Distance:",      10,30,150,20, &clmd->coll_parms.epsilon, 0.001f, 1.0, 0.01f, 0, "Minimum distance between collision objects before collision response takes in");
+                               uiDefBut(block, LABEL, 0, "",160,30,150,20, NULL, 0.0, 0, 0, 0, "");
+                       }
+                       else
+                               uiDefBut(block, LABEL, 0, "",140,10,170,20, NULL, 0.0, 0, 0, 0, "");
+                       uiBlockEndAlign(block);
                }
-               else
-                       uiDefBut(block, LABEL, 0, "",140,10,170,20, NULL, 0.0, 0, 0, 0, "");
-               uiBlockEndAlign(block);
        }
+       // uiBlockEndAlign(block);
 }
 
+
 void object_panels()
 {
        Object *ob;
index 111f0789ee9a8da7aed84d1c2dd42b1ba1d49aeb..61e4c6d566092b4a31cba16e520435ad473fe394 100644 (file)
@@ -2454,112 +2454,6 @@ void draw_slices ( float m[][4] )
        }
 }
 
-
-void draw_fl(ClothModifierData *clmd)
-{
-       int i;
-       float m[4][4];
-       Cloth *cloth = clmd->clothObject;
-       fc *m_fc = NULL;
-       
-       if(!cloth)
-               return;
-       
-       m_fc = cloth->m_fc;
-
-       glClearColor(0, 0, 0, 0);
-       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
-       glMatrixMode(GL_MODELVIEW);
-       glLoadIdentity();
-       // gluLookAt(0, 0, -_dist,  0, 0, 0,  0, 1, 0);
-
-       // build_rotmatrix(m, _quat);
-
-       glMultMatrixf(&m[0][0]);
-       
-       // ----------------------------------------
-       // from ligth constructor
-       m_fc->_light_dir[0] = -1.0f;
-       m_fc->_light_dir[1] = 0.5f;
-       m_fc->_light_dir[2] = 0.0f;
-       
-       gen_ray_templ(m_fc->_ray_templ, m_fc->_light_dir, 30 + 2);
-       
-       cast_light(m_fc->_texture_data, m_fc->_ray_templ, m_fc->_light_dir, 30+2);
-       
-       glActiveTextureARB(GL_TEXTURE0_ARB);
-       glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 30+2, 30+2, 30+2, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_fc->_texture_data);
-       // ----------------------------------------
-       
-       draw_slices(m);
-/*
-       if (_dispstring != NULL) {
-               glMatrixMode(GL_PROJECTION);
-               glLoadMatrixd(_ortho_m);
-               glMatrixMode(GL_MODELVIEW);
-               glLoadIdentity();
-
-               glDisable(GL_TEXTURE_3D);
-               glDisable(GL_FRAGMENT_PROGRAM_ARB);
-               glColor4f(1.0, 1.0, 1.0, 1.0);
-               glRasterPos2i(-_sx/2 + 10, _sy/2 - 15);
-
-               print_string(_dispstring);
-
-               glMatrixMode(GL_PROJECTION);
-               glLoadMatrixd(_persp_m);
-               glMatrixMode(GL_MODELVIEW);
-       }
-*/
-}
-
-void fc_load_frame(ClothModifierData *clmd)
-{
-       float* tmp = (float*) MEM_callocN(30*30*30*sizeof(float), "fc_tmp");
-       float tmin=9999999, tmax=-99999999;
-       Cloth *cloth = clmd->clothObject;
-       fc *m_fc = NULL;
-       int i = 0;
-       
-       if(!cloth)
-               return;
-       
-       m_fc = cloth->m_fc;
-
-       if (++m_fc->_cur_frame == m_fc->_nframes) {
-               fseek(m_fc->_fp, 12, SEEK_SET);
-               m_fc->_cur_frame = 0;
-       }
-
-       fread(tmp, sizeof(float), 30*30*30, m_fc->_fp);
-
-       for (i=0; i<30*30*30; i++)
-       {
-               m_fc->_texture_data[(i<<2)+1] = (unsigned char) (tmp[i]*255.0f);
-       }
-
-       fread(tmp, sizeof(float), 30*30*30, m_fc->_fp);
-
-       for (i=0; i<30*30*30; i++)
-       {
-               m_fc->_texture_data[(i<<2)] = (unsigned char) (tmp[i]*255.0f);
-               if (tmp[i]<tmin)
-                       tmin = tmp[i];
-               if (tmp[i]>tmax)
-                       tmax = tmp[i];
-               m_fc->_texture_data[(i<<2)+2] = 0;
-               m_fc->_texture_data[(i<<2)+3] = 255;
-       }
-
-       MEM_freeN(tmp);
-
-       // cast_light(_N); DG NOT NEEDED
-
-       glActiveTextureARB(GL_TEXTURE0_ARB);
-       glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 30, 30, 30, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_fc->_texture_data);
-}
-
 static void draw_mesh_object_outline(Object *ob, DerivedMesh *dm)
 {
        
index 615a9566b974f4ff47cd5e7f269c06b0e3d1efe2..2e4ecd9570974a950e6eecc821c34ddbca587150 100644 (file)
@@ -51,6 +51,7 @@
 #include "DNA_action_types.h"
 #include "DNA_armature_types.h"
 #include "DNA_brush_types.h"
+#include "DNA_cloth_types.h"
 #include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
 #include "DNA_modifier_types.h"
@@ -747,7 +748,7 @@ static int sample_backbuf_area(VPaint *vp, int *indexar, int totface, int x, int
        struct ImBuf *ibuf;
        int x1, y1, x2, y2, a, tot=0, index;
        
-       if(totface>=MAXINDEX) return 0;
+       if(totface+4>=MAXINDEX) return 0;
        
        if(size>64.0) size= 64.0;
        
@@ -777,7 +778,7 @@ static int sample_backbuf_area(VPaint *vp, int *indexar, int totface, int x, int
        size= (y2-y1)*(x2-x1);
        if(size<=0) return 0;
 
-       memset(indexar, 0, sizeof(int)*totface+2);      /* plus 2! first element is total */
+       memset(indexar, 0, sizeof(int)*totface+4);      /* plus 2! first element is total, +2 was giving valgrind errors, +4 seems ok */
        
        while(size--) {
                        
@@ -1350,7 +1351,7 @@ void weight_paint(void)
        
        // same goes for cloth
        if(modifiers_isClothEnabled(ob)) {
-               cloth_free_modifier(modifiers_isClothEnabled(ob));
+               cloth_free_modifier((ClothModifierData *)modifiers_isClothEnabled(ob));
        }       
        
        BIF_undo_push("Weight Paint");