[Bf-blender-cvs] [67cec973879] master: Simple hair children: Make twist affected by vertex group

Sergey Sharybin noreply at git.blender.org
Thu Feb 15 12:27:56 CET 2018


Commit: 67cec97387965009dfaa57f7f4c8ab948e048e70
Author: Sergey Sharybin
Date:   Wed Feb 14 16:46:29 2018 +0100
Branches: master
https://developer.blender.org/rB67cec97387965009dfaa57f7f4c8ab948e048e70

Simple hair children: Make twist affected by vertex group

The idea is to give a control over direction of twist, and maybe amount of
twist as well. More concrete example: make braids on left and right side of
character head to be twisting opposite directions.

Now, tricky part: we need some negative values to flip direction, but weights
can not be negative. So we use same trick as displacement map and tangent normal
maps, where 0.5 is neutral, values below 0.5 are considered negative and values
above 0.5 are considered positive.

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

M	release/scripts/startup/bl_ui/properties_particle.py
M	source/blender/blenkernel/BKE_particle.h
M	source/blender/blenkernel/intern/particle.c
M	source/blender/blenkernel/intern/particle_child.c
M	source/blender/blenkernel/intern/particle_system.c
M	source/blender/makesdna/DNA_particle_types.h
M	source/blender/makesrna/intern/rna_particle.c

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

diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py
index e552ff35ffa..27a19d5636e 100644
--- a/release/scripts/startup/bl_ui/properties_particle.py
+++ b/release/scripts/startup/bl_ui/properties_particle.py
@@ -1391,6 +1391,10 @@ class PARTICLE_PT_vertexgroups(ParticleButtonsPanel, Panel):
         row.prop_search(psys, "vertex_group_roughness_end", ob, "vertex_groups", text="Roughness End")
         row.prop(psys, "invert_vertex_group_roughness_end", text="", toggle=True, icon='ARROW_LEFTRIGHT')
 
+        row = col.row(align=True)
+        row.prop_search(psys, "vertex_group_twist", ob, "vertex_groups", text="Twist")
+        row.prop(psys, "invert_vertex_group_twist", text="", toggle=True, icon='ARROW_LEFTRIGHT')
+
         # Commented out vertex groups don't work and are still waiting for better implementation
         # row = layout.row()
         # row.prop_search(psys, "vertex_group_velocity", ob, "vertex_groups", text="Velocity")
diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index 747a6b65bb0..0cda7dceb33 100644
--- a/source/blender/blenkernel/BKE_particle.h
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -112,6 +112,7 @@ typedef struct ParticleTexture {
 	float damp, gravity, field;           /* used in physics */
 	float length, clump, kink_freq, kink_amp, effector;  /* used in path caching */
 	float rough1, rough2, roughe;         /* used in path caching */
+	float twist;  /* used in path caching */
 } ParticleTexture;
 
 typedef struct ParticleSeam {
@@ -159,6 +160,7 @@ typedef struct ParticleThreadContext {
 	float *vg_length, *vg_clump, *vg_kink;
 	float *vg_rough1, *vg_rough2, *vg_roughe;
 	float *vg_effector;
+	float *vg_twist;
 
 	struct CurveMapping *clumpcurve;
 	struct CurveMapping *roughcurve;
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index ea27e23ed2f..723bb86cb47 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -2136,6 +2136,7 @@ static bool psys_thread_context_init_path(
 	ctx->vg_rough1 = psys_cache_vgroup(ctx->dm, psys, PSYS_VG_ROUGH1);
 	ctx->vg_rough2 = psys_cache_vgroup(ctx->dm, psys, PSYS_VG_ROUGH2);
 	ctx->vg_roughe = psys_cache_vgroup(ctx->dm, psys, PSYS_VG_ROUGHE);
+	ctx->vg_twist = psys_cache_vgroup(ctx->dm, psys, PSYS_VG_TWIST);
 	if (psys->part->flag & PART_CHILD_EFFECT)
 		ctx->vg_effector = psys_cache_vgroup(ctx->dm, psys, PSYS_VG_EFFECTOR);
 
@@ -3502,6 +3503,7 @@ static void get_cpa_texture(DerivedMesh *dm, ParticleSystem *psys, ParticleSetti
 	ptex->ivel = ptex->life = ptex->exist = ptex->size = ptex->damp =
 	ptex->gravity = ptex->field = ptex->time = ptex->clump = ptex->kink_freq = ptex->kink_amp =
 	ptex->effector = ptex->rough1 = ptex->rough2 = ptex->roughe = 1.0f;
+	ptex->twist = 1.0f;
 
 	ptex->length = 1.0f - part->randlength * psys_frand(psys, child_index + 26);
 	ptex->length *= part->clength_thres < psys_frand(psys, child_index + 27) ? part->clength : 1.0f;
@@ -3579,6 +3581,7 @@ void psys_get_texture(ParticleSimulationData *sim, ParticleData *pa, ParticleTex
 	ptex->ivel = ptex->life = ptex->exist = ptex->size = ptex->damp =
 	ptex->gravity = ptex->field = ptex->length = ptex->clump = ptex->kink_freq = ptex->kink_amp =
 	ptex->effector = ptex->rough1 = ptex->rough2 = ptex->roughe = 1.0f;
+	ptex->twist = 1.0f;
 
 	ptex->time = (float)(pa - sim->psys->particles) / (float)sim->psys->totpart;
 
@@ -3744,6 +3747,8 @@ static void get_child_modifier_parameters(ParticleSettings *part, ParticleThread
 		ptex->roughe *= psys_interpolate_value_from_verts(ctx->dm, cpa_from, cpa_num, cpa_fuv, ctx->vg_roughe);
 	if (ctx->vg_effector)
 		ptex->effector *= psys_interpolate_value_from_verts(ctx->dm, cpa_from, cpa_num, cpa_fuv, ctx->vg_effector);
+	if (ctx->vg_twist)
+		ptex->twist *= psys_interpolate_value_from_verts(ctx->dm, cpa_from, cpa_num, cpa_fuv, ctx->vg_twist);
 }
 /* get's hair (or keyed) particles state at the "path time" specified in state->time */
 void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey *state, const bool vel)
diff --git a/source/blender/blenkernel/intern/particle_child.c b/source/blender/blenkernel/intern/particle_child.c
index 53bf577d4f4..fae304d6580 100644
--- a/source/blender/blenkernel/intern/particle_child.c
+++ b/source/blender/blenkernel/intern/particle_child.c
@@ -734,6 +734,7 @@ static void do_twist(const ParticleChildModifierContext *modifier_ctx,
 {
 	ParticleThreadContext *thread_ctx = modifier_ctx->thread_ctx;
 	ParticleSimulationData *sim = modifier_ctx->sim;
+	ParticleTexture *ptex = modifier_ctx->ptex;
 	ParticleSettings *part = sim->psys->part;
 	/* Early output checks. */
 	if (part->childtype != PART_CHILD_PARTICLES) {
@@ -757,6 +758,9 @@ static void do_twist(const ParticleChildModifierContext *modifier_ctx,
 	twist_get_axis(modifier_ctx, time, axis);
 	/* Angle of rotation. */
 	float angle = part->twist;
+	if (ptex != NULL) {
+		angle *= (ptex->twist - 0.5f) * 2.0f;
+	}
 	if (twist_curve != NULL) {
 		const int num_segments = twist_num_segments(modifier_ctx);
 		angle *= curvemapping_integrate_clamped(twist_curve,
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index bae76354705..7851cd5e801 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -497,6 +497,8 @@ void psys_thread_context_free(ParticleThreadContext *ctx)
 		MEM_freeN(ctx->vg_rough2);
 	if (ctx->vg_roughe)
 		MEM_freeN(ctx->vg_roughe);
+	if (ctx->vg_twist)
+		MEM_freeN(ctx->vg_twist);
 
 	if (ctx->sim.psys->lattice_deform_data) {
 		end_latt_deform(ctx->sim.psys->lattice_deform_data);
diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h
index 371b53567a6..8dd4d46a596 100644
--- a/source/blender/makesdna/DNA_particle_types.h
+++ b/source/blender/makesdna/DNA_particle_types.h
@@ -307,7 +307,8 @@ typedef struct ParticleSystem {
 	char bb_uvname[3][64];					/* billboard uv name, MAX_CUSTOMDATA_LAYER_NAME */
 
 	/* if you change these remember to update array lengths to PSYS_TOT_VG! */
-	short vgroup[12], vg_neg, rt3;			/* vertex groups, 0==disable, 1==starting index */
+	short vgroup[13], vg_neg, rt3;			/* vertex groups, 0==disable, 1==starting index */
+	char pad[6];
 
 	/* temporary storage during render */
 	struct ParticleRenderData *renderdata;
@@ -567,7 +568,7 @@ typedef enum eParticleChildFlag {
 #define PART_DUPLIW_CURRENT	1
 
 /* psys->vg */
-#define PSYS_TOT_VG			12
+#define PSYS_TOT_VG			13
 
 #define PSYS_VG_DENSITY		0
 #define PSYS_VG_VEL			1
@@ -581,6 +582,7 @@ typedef enum eParticleChildFlag {
 #define PSYS_VG_TAN			9
 #define PSYS_VG_ROT			10
 #define PSYS_VG_EFFECTOR	11
+#define PSYS_VG_TWIST	12
 
 /* ParticleTarget->flag */
 #define PTARGET_CURRENT		1
diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c
index e9bbc981a13..caf120e0ea1 100644
--- a/source/blender/makesrna/intern/rna_particle.c
+++ b/source/blender/makesrna/intern/rna_particle.c
@@ -1313,6 +1313,7 @@ static void rna_ParticleVGroup_name_get_8(PointerRNA *ptr, char *value) { psys_v
 static void rna_ParticleVGroup_name_get_9(PointerRNA *ptr, char *value) { psys_vg_name_get__internal(ptr, value, 9); }
 static void rna_ParticleVGroup_name_get_10(PointerRNA *ptr, char *value) { psys_vg_name_get__internal(ptr, value, 10); }
 static void rna_ParticleVGroup_name_get_11(PointerRNA *ptr, char *value) { psys_vg_name_get__internal(ptr, value, 11); }
+static void rna_ParticleVGroup_name_get_12(PointerRNA *ptr, char *value) { psys_vg_name_get__internal(ptr, value, 12); }
 
 static int rna_ParticleVGroup_name_len_0(PointerRNA *ptr) { return psys_vg_name_len__internal(ptr, 0); }
 static int rna_ParticleVGroup_name_len_1(PointerRNA *ptr) { return psys_vg_name_len__internal(ptr, 1); }
@@ -1326,6 +1327,7 @@ static int rna_ParticleVGroup_name_len_8(PointerRNA *ptr) { return psys_vg_name_
 static int rna_ParticleVGroup_name_len_9(PointerRNA *ptr) { return psys_vg_name_len__internal(ptr, 9); }
 static int rna_ParticleVGroup_name_len_10(PointerRNA *ptr) { return psys_vg_name_len__internal(ptr, 10); }
 static int rna_ParticleVGroup_name_len_11(PointerRNA *ptr) { return psys_vg_name_len__internal(ptr, 11); }
+static int rna_ParticleVGroup_name_len_12(PointerRNA *ptr) { return psys_vg_name_len__internal(ptr, 12); }
 
 static void rna_ParticleVGroup_name_set_0(PointerRNA *ptr, const char *value) { psys_vg_name_set__internal(ptr, value, 0); }
 static void rna_ParticleVGroup_name_set_1(PointerRNA *ptr, const char *value) { psys_vg_name_set__internal(ptr, value, 1); }
@@ -1339,6 +1341,7 @@ static void rna_ParticleVGroup_name_set_8(PointerRNA *ptr, const char *value) {
 static void rna_ParticleVGroup_name_set_9(PointerRNA *ptr, const char *value) { psys_vg_name_set__internal(ptr, value, 9); }
 static void rna_ParticleVGroup_name_set_10(PointerRNA *ptr, const char *value) { psys_vg_name_set__internal(ptr, value, 10); }
 static void rna_ParticleVGroup_name_set_11(PointerRNA *ptr, const char *value) { psys_vg_name_set__internal(ptr, value, 11); }
+static void rna_ParticleVGroup_name_set_12(PointerRNA *ptr, const char *value) { psys_vg_name_set__internal(ptr, value, 12); }
 
 
 #else
@@ -3535,6 +3538,18 @@ static void rna_def_particle_system(BlenderRNA *brna)
 	RNA_def_property_ui_text(prop, "Vertex Group Field Negate", "Negate the effect of the field vertex group");
 	RNA_def_property_update(prop, 0, "rna_Particle_reset");
 
+	prop = RNA_def_property(srna, "vertex_group_twist", PROP_STRING, PROP_NONE);
+	RNA_def_property_string_funcs(prop, "rna_ParticleVGroup_name_get_12", "rna_ParticleVGroup_name_len_12",
+	                              "rna_ParticleVGroup_name_set_12");
+	RNA_def_property_ui_text(prop, "Vertex Group Twist", "Vertex group to control twist");
+	RNA_def_property_update(prop, 0, "rna_Particle_redo_child");
+
+	prop = RNA_def_property(srna, "invert_vertex_group_twist", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list