Added new data in the cloth modifier for hair root information.
authorLukas Tönne <lukas.toenne@gmail.com>
Thu, 11 Sep 2014 12:19:52 +0000 (14:19 +0200)
committerLukas Tönne <lukas.toenne@gmail.com>
Tue, 20 Jan 2015 08:29:59 +0000 (09:29 +0100)
This will allow us to implement moving reference frames for hair and
make "fictitious" forces optional, aiding in creating stable and
controllable hair systems.

Adding data in this place is a nasty hack, but it's too difficult to
encode as a DM data layer and the whole cloth modifier/DM intermediate
data copying for hair should be removed anyway.

source/blender/blenkernel/BKE_cloth.h
source/blender/blenkernel/intern/particle_system.c
source/blender/blenloader/intern/readfile.c
source/blender/makesdna/DNA_modifier_types.h
source/blender/modifiers/intern/MOD_cloth.c

index df118276809543a4c8c636b3019ad827c6fefe91..10a336a075abb2a06137fc5dd2bf69cf07e9c4a2 100644 (file)
@@ -59,6 +59,11 @@ struct PartDeflect;
 #define CLOTH_VERT_FLAG_PINNED 1
 #define CLOTH_VERT_FLAG_NOSELFCOLL 2 /* vertex NOT used for self collisions */
 
+typedef struct ClothHairRoot {
+       float loc[3];
+       float rot[3][3];
+} ClothHairRoot;
+
 /**
  * This structure describes a cloth object against which the
  * simulation can run.
index 71656240369239c9141abe824cddc74acb903680..14082af4cbde0c5c98d01323adfd2c948f3b6991 100644 (file)
@@ -4010,12 +4010,19 @@ static void do_hair_dynamics(ParticleSimulationData *sim)
        if (dm && (totpoint != dm->getNumVerts(dm) || totedge != dm->getNumEdges(dm))) {
                dm->release(dm);
                dm = psys->hair_in_dm = NULL;
+               
+               MEM_freeN(psys->clmd->roots);
+               psys->clmd->roots = NULL;
        }
 
        if (!dm) {
                dm = psys->hair_in_dm = CDDM_new(totpoint, totedge, 0, 0, 0);
                DM_add_vert_layer(dm, CD_MDEFORMVERT, CD_CALLOC, NULL);
        }
+       
+       if (!psys->clmd->roots) {
+               psys->clmd->roots = MEM_mallocN(sizeof(ClothHairRoot) * totpoint, "hair roots");
+       }
 
        mvert = CDDM_get_verts(dm);
        medge = CDDM_get_edges(dm);
@@ -4032,6 +4039,7 @@ static void do_hair_dynamics(ParticleSimulationData *sim)
                psys_mat_hair_to_object(sim->ob, sim->psmd->dm, psys->part->from, pa, hairmat);
 
                for (k=0, key=pa->hair; k<pa->totkey; k++,key++) {
+                       ClothHairRoot *root = &psys->clmd->roots[pa->hair_index + k - 1];
                        
                        /* create fake root before actual root to resist bending */
                        if (k==0) {
@@ -4057,6 +4065,10 @@ static void do_hair_dynamics(ParticleSimulationData *sim)
                                }
                        }
 
+                       /* store root transform in cloth data */
+                       copy_v3_v3(root->loc, hairmat[3]);
+                       copy_m3_m4(root->rot, hairmat);
+
                        copy_v3_v3(mvert->co, key->co);
                        mul_m4_v3(hairmat, mvert->co);
                        mvert++;
index 902f2a418009c4399efefa3cc8a44f70988f6ac0..53ceaa0070359d11c4158d6750f62d632abe4ae4 100644 (file)
@@ -3934,6 +3934,7 @@ static void direct_link_particlesystems(FileData *fd, ListBase *particles)
                if (psys->clmd) {
                        psys->clmd = newdataadr(fd, psys->clmd);
                        psys->clmd->clothObject = NULL;
+                       psys->clmd->roots = NULL;
                        
                        psys->clmd->sim_parms= newdataadr(fd, psys->clmd->sim_parms);
                        psys->clmd->coll_parms= newdataadr(fd, psys->clmd->coll_parms);
@@ -4662,6 +4663,7 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
                        ClothModifierData *clmd = (ClothModifierData *)md;
                        
                        clmd->clothObject = NULL;
+                       clmd->roots = NULL;
                        
                        clmd->sim_parms= newdataadr(fd, clmd->sim_parms);
                        clmd->coll_parms= newdataadr(fd, clmd->coll_parms);
index 812e7d20e2a218ae46881920b5b99a714f951ed2..3dd9ebb5f3735bb0b32de9707b8581eb68f3ee77 100644 (file)
@@ -564,6 +564,8 @@ typedef struct ClothModifierData {
        struct ClothCollSettings *coll_parms; /* definition is in DNA_cloth_types.h */
        struct PointCache *point_cache;       /* definition is in DNA_object_force.h */
        struct ListBase ptcaches;
+       /* XXX nasty hack, remove once hair can be separated from cloth modifier data */
+       struct ClothHairRoot *roots;
        
        struct SimDebugData *debug_data;      /* debug info */
 } ClothModifierData;
index 15a73c0a34d6bd7b1fadb6fae4bc94c91756af34..5c5e38f34441b9b9c564e7cb960d333a83f0adf1 100644 (file)
@@ -178,6 +178,7 @@ static void copyData(ModifierData *md, ModifierData *target)
        tclmd->point_cache = BKE_ptcache_add(&tclmd->ptcaches);
        tclmd->point_cache->step = 1;
        tclmd->clothObject = NULL;
+       tclmd->roots = NULL;
        tclmd->debug_data = NULL;
 }
 
@@ -207,6 +208,9 @@ static void freeData(ModifierData *md)
                BKE_ptcache_free_list(&clmd->ptcaches);
                clmd->point_cache = NULL;
                
+               if (clmd->roots)
+                       MEM_freeN(clmd->roots);
+               
                BKE_sim_debug_data_free(clmd->debug_data);
        }
 }