[Bf-blender-cvs] [e93ec66] gooseberry: Experimental hair shape key control with textures.

Lukas Tönne noreply at git.blender.org
Mon Feb 23 10:13:05 CET 2015


Commit: e93ec66dd0d61f42cf2ba0551c82dfcf4aa8ff5f
Author: Lukas Tönne
Date:   Mon Feb 23 10:03:46 2015 +0100
Branches: gooseberry
https://developer.blender.org/rBe93ec66dd0d61f42cf2ba0551c82dfcf4aa8ff5f

Experimental hair shape key control with textures.

Rationale for this feature goes like this:

In meshes the influence of shape keys can be limited to certain vertex
groups. This allows shapes to be applied selectively on parts of the
mesh and possibly even be animated by changing vertex group weights over
time.

With hair shape keys there is no equivalent feature to vertex groups
(defining a vertex group on hair keys would be rather tedious anyway).
It would be possible to use the emitter mesh vgroups to assign a
per-strand blending weight, but since hairs usually are much more dense
than mesh vertices this would sacrifice accuracy.

A better option is to allow textures to influence the hair shape key
blending. For this purpose there is now a new texture influence.
A shape key name needs to be assigned to the MTex in addition to a
factor. It will then act as a multiplier for the shape key weight,
i.e. the base shapekey value still works as an overall control.

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

M	release/scripts/startup/bl_ui/properties_texture.py
M	source/blender/blenkernel/BKE_key.h
M	source/blender/blenkernel/BKE_particle.h
M	source/blender/blenkernel/intern/key.c
M	source/blender/blenkernel/intern/particle.c
M	source/blender/blenkernel/intern/particle_system.c
M	source/blender/makesdna/DNA_particle_types.h
M	source/blender/makesdna/DNA_texture_types.h
M	source/blender/makesrna/intern/rna_particle.c

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

diff --git a/release/scripts/startup/bl_ui/properties_texture.py b/release/scripts/startup/bl_ui/properties_texture.py
index a48e062..11729df 100644
--- a/release/scripts/startup/bl_ui/properties_texture.py
+++ b/release/scripts/startup/bl_ui/properties_texture.py
@@ -1169,6 +1169,9 @@ class TEXTURE_PT_influence(TextureSlotPanel, Panel):
             factor_but(col, "use_map_kink_freq", "kink_freq_factor", "Kink Frequency")
             factor_but(col, "use_map_rough", "rough_factor", "Rough")
 
+            sub = factor_but(layout, "use_map_shapekey", "shapekey_factor", "Shape Key")
+            sub.prop(tex, "shapekey", text="")
+
         elif isinstance(idblock, FreestyleLineStyle):
             split = layout.split()
 
diff --git a/source/blender/blenkernel/BKE_key.h b/source/blender/blenkernel/BKE_key.h
index afa9a41..61aac25 100644
--- a/source/blender/blenkernel/BKE_key.h
+++ b/source/blender/blenkernel/BKE_key.h
@@ -71,10 +71,10 @@ float *BKE_key_evaluate_object_ex(
 float *BKE_key_evaluate_object(
         struct Object *ob, int *r_totelem);
 float *BKE_key_evaluate_particles_ex(
-        struct Object *ob, struct ParticleSystem *psys, int *r_totelem,
+        struct Object *ob, struct ParticleSystem *psys, float cfra, int *r_totelem,
         float *arr, size_t arr_size);
 float *BKE_key_evaluate_particles(
-        struct Object *ob, struct ParticleSystem *psys, int *r_totelem);
+        struct Object *ob, struct ParticleSystem *psys, float cfra, int *r_totelem);
 
 struct Key      *BKE_key_from_object(struct Object *ob);
 struct KeyBlock *BKE_keyblock_from_object(struct Object *ob);
@@ -96,7 +96,7 @@ typedef struct WeightsArrayCache {
 } WeightsArrayCache;
 
 float **BKE_keyblock_get_per_block_object_weights(struct Object *ob, struct Key *key, struct WeightsArrayCache *cache);
-float **BKE_keyblock_get_per_block_particle_weights(struct ParticleSystem *psys, struct Key *key, struct WeightsArrayCache *cache);
+float **BKE_keyblock_get_per_block_particle_weights(struct Object *ob, struct ParticleSystem *psys, float cfra, 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/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index bd825e1..ab3231d 100644
--- a/source/blender/blenkernel/BKE_particle.h
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -437,7 +437,9 @@ float psys_get_dietime_from_cache(struct PointCache *cache, int index);
 void psys_free_pdd(struct ParticleSystem *psys);
 
 float *psys_cache_vgroup(struct DerivedMesh *dm, struct ParticleSystem *psys, int vgroup);
+bool particle_mtex_eval(struct ParticleSimulationData *sim, MTex *mtex, ParticleData *pa, float cfra, float *value, float rgba[4]);
 void psys_get_texture(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ParticleTexture *ptex, int event, float cfra);
+float psys_get_texture_shapefac(struct ParticleSimulationData *sim, struct ParticleData *pa, float cfra, const char *shapekey);
 void psys_interpolate_face(struct MVert *mvert, struct MFace *mface, struct MTFace *tface,
                            float (*orcodata)[3], float w[4], float vec[3], float nor[3], float utan[3], float vtan[3],
                            float orco[3], float ornor[3]);
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c
index 6583588..f598be0 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -45,11 +45,14 @@
 #include "DNA_anim_types.h"
 #include "DNA_key_types.h"
 #include "DNA_lattice_types.h"
+#include "DNA_material_types.h"
 #include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
 #include "DNA_object_types.h"
 #include "DNA_particle_types.h"
 #include "DNA_scene_types.h"
+#include "DNA_texture_types.h"
 
 #include "BKE_animsys.h"
 #include "BKE_curve.h"
@@ -59,12 +62,14 @@
 #include "BKE_key.h"
 #include "BKE_lattice.h"
 #include "BKE_library.h"
+#include "BKE_particle.h"
 #include "BKE_editmesh.h"
 #include "BKE_scene.h"
 
-
 #include "RNA_access.h"
 
+#include "RE_render_ext.h"
+
 #define KEY_MODE_DUMMY      0 /* use where mode isn't checked for */
 #define KEY_MODE_BPOINT     1
 #define KEY_MODE_BEZTRIPLE  2
@@ -1188,20 +1193,74 @@ float **BKE_keyblock_get_per_block_object_weights(Object *ob, Key *key, WeightsA
 	return per_keyblock_weights;
 }
 
-static float *get_particle_weights_array(ParticleSystem *UNUSED(psys), char *vgroup, WeightsArrayCache *UNUSED(cache))
+static int particle_count_keys(ParticleSystem *psys)
 {
-//	MDeformVert *dvert = NULL;
-//	int totvert = 0, defgrp_index = 0;
+	ParticleData *pa;
+	int p;
+	int totkey = 0;
+	for (p = 0, pa = psys->particles; p < psys->totpart; ++p, ++pa) {
+		totkey += pa->totkey;
+	}
+	return totkey;
+}
+
+static float *get_particle_weights_array(Object *ob, ParticleSystem *psys, const char *name, float cfra)
+{
+	ParticleSettings *part = psys->part;
+	ParticleSimulationData sim;
+	MTex **mtexp;
+	int m, i, p, k;
+	int totvert = 0;
+	float *weights = NULL;
 	
-	/* no vgroup string set? */
-	if (vgroup[0] == 0) return NULL;
+	sim.scene = NULL;
+	sim.ob = ob;
+	sim.psys = psys;
+	sim.psmd = psys_get_modifier(ob, psys);
+	
+	for (m = 0, mtexp = part->mtex; m < MAX_MTEX; ++m, ++mtexp) {
+		MTex *mtex = *mtexp;
+		if (mtex && (mtex->mapto & PAMAP_SHAPEKEY) && STREQ(mtex->shapekey, name)) {
+			const float def = mtex->def_var;
+			const short blend = mtex->blendtype;
+			
+			ParticleData *pa;
+			float value, rgba[4];
+			
+			/* lazy init */
+			if (!weights) {
+				totvert = particle_count_keys(psys);
+				weights = MEM_mallocN(totvert * sizeof(float), "weights");
+				for (i = 0; i < totvert; ++i)
+					weights[i] = 1.0f;
+			}
+			
+			i = 0;
+			for (p = 0, pa = psys->particles; p < psys->totpart; ++p, ++pa) {
+				if (particle_mtex_eval(&sim, mtex, pa, cfra, &value, rgba)) {
+					/* weight is the same for all hair keys, 
+					 * only need to evaluate the texture once!
+					 */
+					float result = texture_value_blend(def, weights[i], value, mtex->shapefac, blend);
+					for (k = 0; k < pa->totkey; ++k) {
+						weights[i + k] = result;
+					}
+				}
+				
+				i += pa->totkey;
+			}
+		}
+	}
 	
-	// XXX TODO
+	if (weights) {
+		for (i = 0; i < totvert; ++i)
+			CLAMP(weights[i], 0.0f, 1.0f);
+	}
 	
-	return NULL;
+	return weights;
 }
 
-float **BKE_keyblock_get_per_block_particle_weights(ParticleSystem *psys, Key *key, WeightsArrayCache *cache)
+float **BKE_keyblock_get_per_block_particle_weights(Object *ob, ParticleSystem *psys, float cfra, Key *key, WeightsArrayCache *UNUSED(cache))
 {
 	KeyBlock *keyblock;
 	float **per_keyblock_weights;
@@ -1215,7 +1274,7 @@ float **BKE_keyblock_get_per_block_particle_weights(ParticleSystem *psys, Key *k
 	     keyblock;
 	     keyblock = keyblock->next, keyblock_index++)
 	{
-		per_keyblock_weights[keyblock_index] = get_particle_weights_array(psys, keyblock->vgroup, cache);
+		per_keyblock_weights[keyblock_index] = get_particle_weights_array(ob, psys, keyblock->name, cfra);
 	}
 
 	return per_keyblock_weights;
@@ -1367,7 +1426,7 @@ static void do_latt_key(Object *ob, Key *key, char *out, const int tot)
 	if (lt->flag & LT_OUTSIDE) outside_lattice(lt);
 }
 
-static void do_psys_key(ParticleSystem *psys, Key *key, char *out, const int tot)
+static void do_psys_key(Object *ob, ParticleSystem *psys, float cfra, Key *key, char *out, const int tot)
 {
 	KeyBlock *k[4], *actkb = BKE_keyblock_from_particles(psys);
 	float t[4];
@@ -1377,7 +1436,7 @@ static void do_psys_key(ParticleSystem *psys, Key *key, char *out, const int tot
 		WeightsArrayCache cache = {0, NULL};
 		float **per_keyblock_weights;
 		
-		per_keyblock_weights = BKE_keyblock_get_per_block_particle_weights(psys, key, &cache);
+		per_keyblock_weights = BKE_keyblock_get_per_block_particle_weights(ob, psys, cfra, 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);
 	}
@@ -1496,7 +1555,7 @@ float *BKE_key_evaluate_object(Object *ob, int *r_totelem)
 }
 
 /* returns key coordinates when key applied, NULL otherwise */
-float *BKE_key_evaluate_particles_ex(Object *ob, ParticleSystem *psys, int *r_totelem,
+float *BKE_key_evaluate_particles_ex(Object *ob, ParticleSystem *psys, float cfra, int *r_totelem,
                                      float *arr, size_t arr_size)
 {
 	Key *key = psys->key;
@@ -1546,14 +1605,14 @@ float *BKE_key_evaluate_particles_ex(Object *ob, ParticleSystem *psys, int *r_to
 			psys->shapenr = 1;
 		}
 		
-		weights = get_particle_weights_array(psys, kb->vgroup, NULL);
+		weights = get_particle_weights_array(ob, psys, kb->name, cfra);
 		
 		cp_key(0, tot, tot, out, key, actkb, kb, weights, 0);
 		
 		if (weights) MEM_freeN(weights);
 	}
 	else {
-		do_psys_key(psys, key, out, tot);
+		do_psys_key(ob, psys, cfra, key, out, tot);
 	}
 	
 	if (r_totelem) {
@@ -1562,9 +1621,9 @@ float *BKE_key_evaluate_particles_ex(Object *ob, ParticleSystem *psys, int *r_to
 	return (float *)out;
 }
 
-float *BKE_key_evaluate_particles(Object *ob, ParticleSystem *psys, int *r_totelem)
+float *BKE_key_evaluate_particles(Object *ob, ParticleSystem *psys, float cfra, int *r_totelem)
 {
-	return BKE_key_evaluate_particles_ex(ob, psys, r_totelem, NULL, 0);
+	return BKE_key_evaluate_particles_ex(ob, psys, cfra, r_totelem, NULL, 0);
 }
 
 Key *BKE_key_from_object(Object *ob)
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 2046d56..7469dcd 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -361,7 +361,7 @@ int psys_uses_gravity(ParticleSimulationData *sim)
 	return sim->scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY && sim->psys->part && sim->psys->part->effector_

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list