Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--release/scripts/startup/bl_ui/properties_particle.py34
-rw-r--r--source/blender/blenkernel/intern/anim.c12
-rw-r--r--source/blender/blenkernel/intern/particle.c65
-rw-r--r--source/blender/blenloader/intern/readfile.c14
-rw-r--r--source/blender/makesdna/DNA_particle_types.h3
-rw-r--r--source/blender/makesrna/intern/rna_particle.c11
6 files changed, 99 insertions, 40 deletions
diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py
index eceefc70b5c..d24aef56a8b 100644
--- a/release/scripts/startup/bl_ui/properties_particle.py
+++ b/release/scripts/startup/bl_ui/properties_particle.py
@@ -404,10 +404,13 @@ class PARTICLE_PT_rotation(ParticleButtonsPanel, Panel):
part = context.space_data.pin_id
layout.enabled = particle_panel_enabled(context, psys)
+
+ layout.prop(part, "use_dynamic_rotation")
- row = layout.row()
- row.label(text="Initial Rotation:")
- row.prop(part, "use_dynamic_rotation")
+ if part.use_dynamic_rotation:
+ layout.label(text="Initial Rotation Axis:")
+ else:
+ layout.label(text="Rotation Axis:")
split = layout.split()
@@ -419,12 +422,18 @@ class PARTICLE_PT_rotation(ParticleButtonsPanel, Panel):
col.prop(part, "phase_factor", slider=True)
col.prop(part, "phase_factor_random", text="Random", slider=True)
- col = layout.column()
- col.label(text="Angular Velocity:")
- col.row().prop(part, "angular_velocity_mode", expand=True)
-
- if part.angular_velocity_mode != 'NONE':
- col.prop(part, "angular_velocity_factor", text="")
+ if part.type != 'HAIR':
+ col = layout.column()
+ if part.use_dynamic_rotation:
+ col.label(text="Initial Angular Velocity:")
+ else:
+ col.label(text="Angular Velocity:")
+ sub = col.row(align=True)
+ sub.prop(part, "angular_velocity_mode", text="")
+ subsub = sub.column()
+ subsub.active = part.angular_velocity_mode != 'NONE'
+ subsub.prop(part, "angular_velocity_factor", text="")
+
class PARTICLE_PT_physics(ParticleButtonsPanel, Panel):
@@ -832,7 +841,9 @@ class PARTICLE_PT_render(ParticleButtonsPanel, Panel):
elif part.render_type == 'OBJECT':
col.prop(part, "dupli_object")
- col.prop(part, "use_global_dupli")
+ sub = col.row()
+ sub.prop(part, "use_global_dupli")
+ sub.prop(part, "use_rotation_dupli")
elif part.render_type == 'GROUP':
col.prop(part, "dupli_group")
split = layout.split()
@@ -841,13 +852,14 @@ class PARTICLE_PT_render(ParticleButtonsPanel, Panel):
col.prop(part, "use_whole_group")
sub = col.column()
sub.active = (part.use_whole_group is False)
+ sub.prop(part, "use_group_pick_random")
sub.prop(part, "use_group_count")
col = split.column()
sub = col.column()
sub.active = (part.use_whole_group is False)
sub.prop(part, "use_global_dupli")
- sub.prop(part, "use_group_pick_random")
+ sub.prop(part, "use_rotation_dupli")
if part.use_group_count and not part.use_whole_group:
row = layout.row()
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c
index cd2c272a1c2..da6dd5bd39d 100644
--- a/source/blender/blenkernel/intern/anim.c
+++ b/source/blender/blenkernel/intern/anim.c
@@ -1430,6 +1430,16 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
VECCOPY(vec, obmat[3]);
obmat[3][0] = obmat[3][1] = obmat[3][2] = 0.0f;
+
+ /* particle rotation uses x-axis as the aligned axis, so pre-rotate the object accordingly */
+ if((part->draw & PART_DRAW_ROTATE_OB) == 0) {
+ float xvec[3], q[4];
+ xvec[0] = -1.f;
+ xvec[1] = xvec[2] = 0;
+ vec_to_quat(q, xvec, ob->trackflag, ob->upflag);
+ quat_to_mat4(obmat, q);
+ obmat[3][3]= 1.0f;
+ }
/* Normal particles and cached hair live in global space so we need to
* remove the real emitter's transformation before 2nd order duplication.
@@ -1448,7 +1458,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
copy_m4_m4(mat, tmat);
if(part->draw & PART_DRAW_GLOBAL_OB)
- VECADD(mat[3], mat[3], vec);
+ add_v3_v3v3(mat[3], mat[3], vec);
dob= new_dupli_object(lb, ob, mat, ob->lay, counter, GS(id->name) == ID_GR ? OB_DUPLIGROUP : OB_DUPLIPARTS, animated);
copy_m4_m4(dob->omat, oldobmat);
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 806a7871948..8669c4e0efd 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -4384,33 +4384,50 @@ void psys_get_dupli_path_transform(ParticleSimulationData *sim, ParticleData *pa
psys_particle_on_emitter(psmd,sim->psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc,nor,0,0,0,0);
else
psys_particle_on_emitter(psmd,PART_FROM_FACE,cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,loc,nor,0,0,0,0);
-
- copy_m3_m4(nmat, ob->imat);
- transpose_m3(nmat);
- mul_m3_v3(nmat, nor);
- normalize_v3(nor);
-
- /* make sure that we get a proper side vector */
- if(fabs(dot_v3v3(nor,vec))>0.999999) {
- if(fabs(dot_v3v3(nor,xvec))>0.999999) {
- nor[0] = 0.0f;
- nor[1] = 1.0f;
- nor[2] = 0.0f;
+
+ if(psys->part->rotmode == PART_ROT_VEL) {
+ copy_m3_m4(nmat, ob->imat);
+ transpose_m3(nmat);
+ mul_m3_v3(nmat, nor);
+ normalize_v3(nor);
+
+ /* make sure that we get a proper side vector */
+ if(fabs(dot_v3v3(nor,vec))>0.999999) {
+ if(fabs(dot_v3v3(nor,xvec))>0.999999) {
+ nor[0] = 0.0f;
+ nor[1] = 1.0f;
+ nor[2] = 0.0f;
+ }
+ else {
+ nor[0] = 1.0f;
+ nor[1] = 0.0f;
+ nor[2] = 0.0f;
+ }
}
- else {
- nor[0] = 1.0f;
- nor[1] = 0.0f;
- nor[2] = 0.0f;
+ cross_v3_v3v3(side, nor, vec);
+ normalize_v3(side);
+
+ /* rotate side vector around vec */
+ if(psys->part->phasefac != 0) {
+ float q_phase[4];
+ float phasefac = psys->part->phasefac;
+ if(psys->part->randphasefac != 0.0f)
+ phasefac += psys->part->randphasefac * PSYS_FRAND((pa-psys->particles) + 20);
+ axis_angle_to_quat( q_phase, vec, phasefac*(float)M_PI);
+
+ mul_qt_v3(q_phase, side);
}
- }
- cross_v3_v3v3(side, nor, vec);
- normalize_v3(side);
- cross_v3_v3v3(nor, vec, side);
- unit_m4(mat);
- VECCOPY(mat[0], vec);
- VECCOPY(mat[1], side);
- VECCOPY(mat[2], nor);
+ cross_v3_v3v3(nor, vec, side);
+
+ unit_m4(mat);
+ VECCOPY(mat[0], vec);
+ VECCOPY(mat[1], side);
+ VECCOPY(mat[2], nor);
+ }
+ else {
+ quat_to_mat4(mat, pa->state.rot);
+ }
*scale= len;
}
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 76070e42f29..84b9021d080 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -12176,6 +12176,20 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
for (ntree=main->nodetree.first; ntree; ntree=ntree->id.next)
do_versions_nodetree_image_default_alpha_output(ntree);
}
+
+ {
+ /* support old particle dupliobject rotation settings */
+ ParticleSettings *part;
+
+ for (part=main->particle.first; part; part=part->id.next) {
+ if(ELEM(part->ren_as, PART_DRAW_OB, PART_DRAW_GR)) {
+ part->draw |= PART_DRAW_ROTATE_OB;
+
+ if(part->rotmode == 0)
+ part->rotmode = PART_ROT_VEL;
+ }
+ }
+ }
}
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h
index 9fec5207dbb..da2fce4da82 100644
--- a/source/blender/makesdna/DNA_particle_types.h
+++ b/source/blender/makesdna/DNA_particle_types.h
@@ -386,7 +386,8 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in
#define PART_DRAW_HEALTH 16
#define PART_ABS_PATH_TIME 32
#define PART_DRAW_COUNT_GR 64
-#define PART_DRAW_BB_LOCK 128
+#define PART_DRAW_BB_LOCK 128 /* used with billboards */
+#define PART_DRAW_ROTATE_OB 128 /* used with dupliobjects/groups */
#define PART_DRAW_PARENT 256
#define PART_DRAW_NUM 512
#define PART_DRAW_RAND_GR 1024
diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c
index 49005e56367..43d5f87f0d5 100644
--- a/source/blender/makesrna/intern/rna_particle.c
+++ b/source/blender/makesrna/intern/rna_particle.c
@@ -1478,7 +1478,7 @@ static void rna_def_particle_settings(BlenderRNA *brna)
static EnumPropertyItem rot_mode_items[] = {
{0, "NONE", 0, "None", ""},
{PART_ROT_NOR, "NOR", 0, "Normal", ""},
- {PART_ROT_VEL, "VEL", 0, "Velocity", ""},
+ {PART_ROT_VEL, "VEL", 0, "Velocity / Hair", ""},
{PART_ROT_GLOB_X, "GLOB_X", 0, "Global X", ""},
{PART_ROT_GLOB_Y, "GLOB_Y", 0, "Global Y", ""},
{PART_ROT_GLOB_Z, "GLOB_Z", 0, "Global Z", ""},
@@ -1733,7 +1733,7 @@ static void rna_def_particle_settings(BlenderRNA *brna)
RNA_def_property_enum_sdna(prop, NULL, "rotmode");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_enum_items(prop, rot_mode_items);
- RNA_def_property_ui_text(prop, "Rotation", "Particles initial rotation");
+ RNA_def_property_ui_text(prop, "Rotation", "Particle rotation axis");
RNA_def_property_update(prop, 0, "rna_Particle_reset");
prop= RNA_def_property(srna, "angular_velocity_mode", PROP_ENUM, PROP_NONE);
@@ -1798,7 +1798,12 @@ static void rna_def_particle_settings(BlenderRNA *brna)
prop= RNA_def_property(srna, "use_global_dupli", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_DRAW_GLOBAL_OB);
- RNA_def_property_ui_text(prop, "Use Global", "Use object's global coordinates for duplication");
+ RNA_def_property_ui_text(prop, "Global", "Use object's global coordinates for duplication");
+ RNA_def_property_update(prop, 0, "rna_Particle_redo");
+
+ prop= RNA_def_property(srna, "use_rotation_dupli", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_DRAW_ROTATE_OB);
+ RNA_def_property_ui_text(prop, "Rotation", "Use object's rotation for duplication (global x-axis is aligned particle rotation axis)");
RNA_def_property_update(prop, 0, "rna_Particle_redo");
prop= RNA_def_property(srna, "use_render_adaptive", PROP_BOOLEAN, PROP_NONE);