Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt23
-rw-r--r--source/blender/blenkernel/BKE_cloth.h188
-rw-r--r--source/blender/blenkernel/BKE_modifier.h2
-rw-r--r--source/blender/blenkernel/intern/cloth.c1653
-rw-r--r--source/blender/blenkernel/intern/collision.c900
-rw-r--r--source/blender/blenkernel/intern/implicit.c1194
-rw-r--r--source/blender/blenkernel/intern/modifier.c221
-rw-r--r--source/blender/blenloader/intern/readfile.c5
-rw-r--r--source/blender/blenloader/intern/writefile.c2
-rw-r--r--source/blender/makesdna/DNA_cloth_types.h102
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h6
-rw-r--r--source/blender/src/buttons_object.c189
-rw-r--r--source/blender/src/drawobject.c106
-rw-r--r--source/blender/src/vpaint.c7
14 files changed, 2031 insertions, 2567 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d79c2220104..4eb5e9c659d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -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)
diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h
index b122347998d..eb1f33ae600 100644
--- a/source/blender/blenkernel/BKE_cloth.h
+++ b/source/blender/blenkernel/BKE_cloth.h
@@ -34,14 +34,14 @@
#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
diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h
index 8927584de1b..682eb1a00dd 100644
--- a/source/blender/blenkernel/BKE_modifier.h
+++ b/source/blender/blenkernel/BKE_modifier.h
@@ -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);
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index 318d6eac410..fef932174a1 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -39,15 +39,15 @@
/* 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"
@@ -65,11 +63,11 @@
#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"
@@ -78,21 +76,7 @@
#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 )
+ if ( ! ( clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ ) )
{
- 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 ) )
- {
- 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);
+ if ( ! ( clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT ) )
+ {
+ if ( cloth )
+ {
+ // 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 )
+ {
+ solvers [cloth->old_solver_type].free ( clmd );
+ }
+
+ // Free the verts.
+ if ( cloth->verts != NULL )
+ MEM_freeN ( cloth->verts );
- /* Calls the solver and collision frees first as they
- * might depend on data in clmd->clothObject. */
+ cloth->verts = NULL;
+ cloth->numverts = 0;
- 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 )
- {
- LinkNode *search = cloth->springs;
- while(search)
+ // Free the springs.
+ if ( cloth->springs != NULL )
{
- ClothSpring *spring = search->link;
-
- MEM_freeN ( spring );
- search = search->next;
+ 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;
}
- BLI_linklist_free(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
+ }
+}
- switch (ob->type)
+/*
+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 )
{
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;
- default: return 0; // TODO - we do not support changing meshes
+ 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
}
-
+
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 )
- {
- 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 )
+ 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->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);
- }
-}
-
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c
index 4bc1efc1e70..4a03f579fe8 100644
--- a/source/blender/blenkernel/intern/collision.c
+++ b/source/blender/blenkernel/intern/collision.c
@@ -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"
@@ -71,20 +70,6 @@
#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);
+}
diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c
index a1d60b34125..b154cb0e755 100644
--- a/source/blender/blenkernel/intern/implicit.c
+++ b/source/blender/blenkernel/intern/implicit.c
@@ -46,11 +46,9 @@
#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);
+ }
}
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index e7ce752424d..3b69f47b1f4 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -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)
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index d215bdf67cd..37d15b65de5 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -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;
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 275e3b18c4c..3326d38c56f 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -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;
diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h
index 4d8fbf1a6fc..2bbe328d170 100644
--- a/source/blender/makesdna/DNA_cloth_types.h
+++ b/source/blender/makesdna/DNA_cloth_types.h
@@ -32,7 +32,64 @@
#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
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 384ac37484d..f8b6f4202a5 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -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 {
diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c
index f71f6adb051..662e0df093b 100644
--- a/source/blender/src/buttons_object.c
+++ b/source/blender/src/buttons_object.c
@@ -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;
diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c
index 111f0789ee9..61e4c6d5660 100644
--- a/source/blender/src/drawobject.c
+++ b/source/blender/src/drawobject.c
@@ -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)
{
diff --git a/source/blender/src/vpaint.c b/source/blender/src/vpaint.c
index 615a9566b97..2e4ecd95709 100644
--- a/source/blender/src/vpaint.c
+++ b/source/blender/src/vpaint.c
@@ -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");