Commit: 639ff6e94de6f29064d3f613b93f1ec1ccdee4bb
Author: Lukas Tönne
Date:   Fri Oct 3 12:16:24 2014 +0200
Branches: hair_immediate_fixes
https://developer.blender.org/rB639ff6e94de6f29064d3f613b93f1ec1ccdee4bb

Evaluate shape keys when building the particle path cache.

===================================================================

M       source/blender/blenkernel/BKE_key.h
M       source/blender/blenkernel/intern/key.c
M       source/blender/blenkernel/intern/particle.c
M       source/gameengine/Converter/BL_ShapeDeformer.cpp

===================================================================

diff --git a/source/blender/blenkernel/BKE_key.h 
b/source/blender/blenkernel/BKE_key.h
index be0ee05..b0e2f49 100644
--- a/source/blender/blenkernel/BKE_key.h
+++ b/source/blender/blenkernel/BKE_key.h
@@ -65,6 +65,9 @@ void key_curve_normal_weights(float t, float data[4], int 
type);
 float *BKE_key_evaluate_object_ex(struct Scene *scene, struct Object *ob, int 
*r_totelem,
                                   float *arr, size_t arr_size);
 float *BKE_key_evaluate_object(struct Scene *scene, struct Object *ob, int 
*r_totelem);
+float *BKE_key_evaluate_particles_ex(struct Object *ob, struct ParticleSystem 
*psys, int *r_totelem,
+                                     float *arr, size_t arr_size);
+float *BKE_key_evaluate_particles(struct Object *ob, struct ParticleSystem 
*psys, int *r_totelem);
 
 struct Key      *BKE_key_from_object(struct Object *ob);
 struct KeyBlock *BKE_keyblock_from_object(struct Object *ob);
@@ -85,7 +88,8 @@ typedef struct WeightsArrayCache {
        float **defgroup_weights;
 } WeightsArrayCache;
 
-float **BKE_keyblock_get_per_block_weights(struct Object *ob, struct Key *key, 
struct WeightsArrayCache *cache);
+float **BKE_key_get_per_block_object_weights(struct Object *ob, struct Key 
*key, struct WeightsArrayCache *cache);
+float **BKE_key_get_per_block_particle_weights(struct ParticleSystem *psys, 
struct Key *key, struct WeightsArrayCache *cache);
 void BKE_keyblock_free_per_block_weights(struct Key *key, float 
**per_keyblock_weights, struct WeightsArrayCache *cache);
 void BKE_key_evaluate_relative(const int start, int end, const int tot, char 
*basispoin, struct Key *key, struct KeyBlock *actkb,
                                float **per_keyblock_weights, const int mode);
diff --git a/source/blender/blenkernel/intern/key.c 
b/source/blender/blenkernel/intern/key.c
index 7fea84a..96923e7 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -1075,7 +1075,7 @@ static void do_key(const int start, int end, const int 
tot, char *poin, Key *key
        if (freek4) MEM_freeN(freek4);
 }
 
-static float *get_weights_array(Object *ob, char *vgroup, WeightsArrayCache 
*cache)
+static float *get_object_weights_array(Object *ob, char *vgroup, 
WeightsArrayCache *cache)
 {
        MDeformVert *dvert = NULL;
        BMEditMesh *em = NULL;
@@ -1147,7 +1147,7 @@ static float *get_weights_array(Object *ob, char *vgroup, 
WeightsArrayCache *cac
        return NULL;
 }
 
-float **BKE_keyblock_get_per_block_weights(Object *ob, Key *key, 
WeightsArrayCache *cache)
+float **BKE_key_get_per_block_object_weights(Object *ob, Key *key, 
WeightsArrayCache *cache)
 {
        KeyBlock *keyblock;
        float **per_keyblock_weights;
@@ -1161,7 +1161,40 @@ float **BKE_keyblock_get_per_block_weights(Object *ob, 
Key *key, WeightsArrayCac
             keyblock;
             keyblock = keyblock->next, keyblock_index++)
        {
-               per_keyblock_weights[keyblock_index] = get_weights_array(ob, 
keyblock->vgroup, cache);
+               per_keyblock_weights[keyblock_index] = 
get_object_weights_array(ob, keyblock->vgroup, cache);
+       }
+
+       return per_keyblock_weights;
+}
+
+static float *get_particle_weights_array(ParticleSystem *psys, char *vgroup, 
WeightsArrayCache *cache)
+{
+//     MDeformVert *dvert = NULL;
+//     int totvert = 0, defgrp_index = 0;
+       
+       /* no vgroup string set? */
+       if (vgroup[0] == 0) return NULL;
+       
+       // XXX TODO
+       
+       return NULL;
+}
+
+float **BKE_key_get_per_block_particle_weights(ParticleSystem *psys, Key *key, 
WeightsArrayCache *cache)
+{
+       KeyBlock *keyblock;
+       float **per_keyblock_weights;
+       int keyblock_index;
+
+       per_keyblock_weights =
+               MEM_mallocN(sizeof(*per_keyblock_weights) * key->totkey,
+                           "per keyblock weights");
+
+       for (keyblock = key->block.first, keyblock_index = 0;
+            keyblock;
+            keyblock = keyblock->next, keyblock_index++)
+       {
+               per_keyblock_weights[keyblock_index] = 
get_particle_weights_array(psys, keyblock->vgroup, cache);
        }
 
        return per_keyblock_weights;
@@ -1227,7 +1260,7 @@ static void do_mesh_key(Scene *scene, Object *ob, Key 
*key, char *out, const int
                if (key->type == KEY_RELATIVE) {
                        WeightsArrayCache cache = {0, NULL};
                        float **per_keyblock_weights;
-                       per_keyblock_weights = 
BKE_keyblock_get_per_block_weights(ob, key, &cache);
+                       per_keyblock_weights = 
BKE_key_get_per_block_object_weights(ob, key, &cache);
                        BKE_key_evaluate_relative(0, tot, tot, (char *)out, 
key, actkb, per_keyblock_weights, KEY_MODE_DUMMY);
                        BKE_keyblock_free_per_block_weights(key, 
per_keyblock_weights, &cache);
                }
@@ -1391,7 +1424,7 @@ static void do_latt_key(Scene *scene, Object *ob, Key 
*key, char *out, const int
        else {
                if (key->type == KEY_RELATIVE) {
                        float **per_keyblock_weights;
-                       per_keyblock_weights = 
BKE_keyblock_get_per_block_weights(ob, key, NULL);
+                       per_keyblock_weights = 
BKE_key_get_per_block_object_weights(ob, key, NULL);
                        BKE_key_evaluate_relative(0, tot, tot, (char *)out, 
key, actkb, per_keyblock_weights, KEY_MODE_DUMMY);
                        BKE_keyblock_free_per_block_weights(key, 
per_keyblock_weights, NULL);
                }
@@ -1410,6 +1443,32 @@ static void do_latt_key(Scene *scene, Object *ob, Key 
*key, char *out, const int
        if (lt->flag & LT_OUTSIDE) outside_lattice(lt);
 }
 
+static void do_psys_key(ParticleSystem *psys, Key *key, char *out, const int 
tot)
+{
+       KeyBlock *k[4], *actkb = BKE_keyblock_from_particles(psys);
+       float t[4];
+       int flag = 0;
+       
+       if (key->type == KEY_RELATIVE) {
+               WeightsArrayCache cache = {0, NULL};
+               float **per_keyblock_weights;
+               
+               per_keyblock_weights = 
BKE_key_get_per_block_particle_weights(psys, key, &cache);
+               BKE_key_evaluate_relative(0, tot, tot, (char *)out, key, actkb, 
per_keyblock_weights, KEY_MODE_DUMMY);
+               BKE_keyblock_free_per_block_weights(key, per_keyblock_weights, 
&cache);
+       }
+       else {
+               const float ctime_scaled = key->ctime / 100.0f;
+               
+               flag = setkeys(ctime_scaled, &key->block, k, t, 0);
+               
+               if (flag == 0)
+                       do_key(0, tot, tot, (char *)out, key, actkb, k, t, 
KEY_MODE_DUMMY);
+               else
+                       cp_key(0, tot, tot, (char *)out, key, actkb, k[2], 
NULL, KEY_MODE_DUMMY);
+       }
+}
+
 /* returns key coordinates (+ tilt) when key applied, NULL otherwise */
 float *BKE_key_evaluate_object_ex(Scene *scene, Object *ob, int *r_totelem,
                                   float *arr, size_t arr_size)
@@ -1483,7 +1542,7 @@ float *BKE_key_evaluate_object_ex(Scene *scene, Object 
*ob, int *r_totelem,
                }
                
                if (OB_TYPE_SUPPORT_VGROUP(ob->type)) {
-                       float *weights = get_weights_array(ob, kb->vgroup, 
NULL);
+                       float *weights = get_object_weights_array(ob, 
kb->vgroup, NULL);
 
                        cp_key(0, tot, tot, out, key, actkb, kb, weights, 0);
 
@@ -1511,6 +1570,78 @@ float *BKE_key_evaluate_object(Scene *scene, Object *ob, 
int *r_totelem)
        return BKE_key_evaluate_object_ex(scene, ob, r_totelem, NULL, 0);
 }
 
+/* returns key coordinates when key applied, NULL otherwise */
+float *BKE_key_evaluate_particles_ex(Object *ob, ParticleSystem *psys, int 
*r_totelem,
+                                     float *arr, size_t arr_size)
+{
+       Key *key = psys->key;
+       KeyBlock *actkb = BKE_keyblock_from_particles(psys);
+       char *out;
+       int tot = 0, size = 0;
+       int i;
+       
+       if (key == NULL || BLI_listbase_is_empty(&key->block))
+               return NULL;
+       
+       /* compute size of output array */
+       tot = 0;
+       for (i = 0; i < psys->totpart; ++i)
+               tot += psys->particles[i].totkey;
+       size = tot * 3 * sizeof(float);
+       
+       /* if nothing to interpolate, cancel */
+       if (tot == 0 || size == 0)
+               return NULL;
+       
+       /* allocate array */
+       if (arr == NULL) {
+               out = MEM_callocN(size, "BKE_key_evaluate_object out");
+       }
+       else {
+               if (arr_size != size) {
+                       return NULL;
+               }
+               
+               out = (char *)arr;
+       }
+       
+       /* prevent python from screwing this up? anyhoo, the from pointer could 
be dropped */
+       key->from = (ID *)ob; // XXX the "from" pointer needs to be amended to 
support particle system properly
+       
+       if (ob->shapeflag & OB_SHAPE_LOCK) {
+               /* shape locked, copy the locked shape instead of blending */
+               KeyBlock *kb = BLI_findlink(&key->block, psys->shapenr - 1);
+               float *weights;
+               
+               if (kb && (kb->flag & KEYBLOCK_MUTE))
+                       kb = key->refkey;
+               
+               if (kb == NULL) {
+                       kb = key->block.first;
+                       psys->shapenr = 1;
+               }
+               
+               weights = get_particle_weights_array(psys, kb->vgroup, NULL);
+               
+               cp_key(0, tot, tot, out, key, actkb, kb, weights, 0);
+               
+               if (weights) MEM_freeN(weights);
+       }
+       else {
+               do_psys_key(psys, key, out, tot);
+       }
+       
+       if (r_totelem) {
+               *r_totelem = tot;
+       }
+       return (float *)out;
+}
+
+float *BKE_key_evaluate_particles(Object *ob, ParticleSystem *psys, int 
*r_totelem)
+{
+       return BKE_key_evaluate_particles_ex(ob, psys, r_totelem, NULL, 0);
+}
+
 Key *BKE_key_from_object(Object *ob)
 {
        if (ob == NULL) return NULL;
diff --git a/source/blender/blenkernel/intern/particle.c 
b/source/blender/blenkernel/intern/particle.c
index b015927..67ae3f5 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -2959,11 +2959,12 @@ void psys_cache_paths(ParticleSimulationData *sim, 
float cfra)
        ParticleSystem *psys = sim->psys;
        ParticleSettings *part = psys->part;
        ParticleCacheKey *ca, **cache;
+       const bool keyed = psys->flag & PSYS_KEYED;
+       const bool baked = psys->pointcache->mem_cache.first && 
psys->part->type != PART_HAIR;
+       const bool edit = psys->edit;
 
        DerivedMesh *hair_dm = (psys->part->type == PART_HAIR && psys->flag & 
PSYS_HAIR_DYNAMICS) ? psys->hair_out_dm : NULL;
        
-       ParticleKey result;
-       
        Material *ma;
        ParticleInterpolationData pind;
        ParticleTexture ptex;
@@ -2981,7 +2982,8 @@ void psys_cache_paths(ParticleSimulationData *sim, float 
cfra)
        float length, vec[3];
        float *vg_effector = NULL;
        float *vg_length = NULL, pa_length = 1.0f;
-       int keyed, baked;
+       float *shapekey_data, *shapekey;
+       int totshapekey;
 
        /* we don't have anything valid to create paths from so let's quit here 
*/
        if ((psys->flag & PSYS_HAIR_DONE || psys->flag & PSYS_KEYED || 
psys->pointcache) == 0)
@@ -2991,9 +2993,6 @@ void psys_cache_paths(ParticleSimulationData *sim, float 
cfra)
                if (psys->renderdata == 0 && (psys->edit == NULL || pset->flag 
& PE_DRAW_PART) == 0)
                        return;
 
-       keyed = psys->flag & PSYS_KEYED;
-       baked = psys->pointcache->mem_cache.first 

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to