[Bf-blender-cvs] [639ff6e] hair_immediate_fixes: Evaluate shape keys when building the particle path cache.
Lukas Tönne
noreply at git.blender.org
Fri Oct 3 14:20:34 CEST 2014
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. @@
More information about the Bf-blender-cvs
mailing list