[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [58229] trunk/blender/source/blender/ blenkernel/intern/particle_system.c: fix relating to [#36093] Stationary Particle system - particle Y axis fails to follow emitter object rotation

Campbell Barton ideasman42 at gmail.com
Sun Jul 14 09:27:44 CEST 2013


Revision: 58229
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=58229
Author:   campbellbarton
Date:     2013-07-14 07:27:44 +0000 (Sun, 14 Jul 2013)
Log Message:
-----------
fix relating to [#36093] Stationary Particle system - particle Y axis fails to follow emitter object rotation

With deformations and on a simple cube you could get axis flipping with normal-particle alignment.
now use the normal & tangent to create the orientation to give a stable matrix that wont flip.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/intern/particle_system.c

Modified: trunk/blender/source/blender/blenkernel/intern/particle_system.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/particle_system.c	2013-07-14 01:34:29 UTC (rev 58228)
+++ trunk/blender/source/blender/blenkernel/intern/particle_system.c	2013-07-14 07:27:44 UTC (rev 58229)
@@ -1660,17 +1660,22 @@
 {
 	Object *ob = sim->ob;
 	ParticleSystem *psys = sim->psys;
-	ParticleSettings *part;
+	ParticleSettings *part = psys->part;
 	ParticleTexture ptex;
 	float fac, phasefac, nor[3] = {0,0,0},loc[3],vel[3] = {0.0,0.0,0.0},rot[4],q2[4];
 	float r_vel[3],r_ave[3],r_rot[4],vec[3],p_vel[3] = {0.0,0.0,0.0};
 	float x_vec[3] = {1.0,0.0,0.0}, utan[3] = {0.0,1.0,0.0}, vtan[3] = {0.0,0.0,1.0}, rot_vec[3] = {0.0,0.0,0.0};
 	float q_phase[4];
+
+	const bool use_boids = ((part->phystype == PART_PHYS_BOIDS) &&
+	                        (pa->boid != NULL));
+	const bool use_tangents = ((use_boids == false) &&
+	                           ((part->tanfac != 0.0f) || (part->rotmode == PART_ROT_NOR)));
+
 	int p = pa - psys->particles;
-	part=psys->part;
 
 	/* get birth location from object		*/
-	if (part->tanfac != 0.f)
+	if (use_tangents)
 		psys_particle_on_emitter(sim->psmd, part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,utan,vtan,0,0);
 	else
 		psys_particle_on_emitter(sim->psmd, part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,0,0,0,0);
@@ -1688,7 +1693,7 @@
 	normalize_v3(nor);
 
 	/* -tangent								*/
-	if (part->tanfac!=0.0f) {
+	if (use_tangents) {
 		//float phase=vg_rot?2.0f*(psys_particle_value_from_verts(sim->psmd->dm,part->from,pa,vg_rot)-0.5f):0.0f;
 		float phase=0.0f;
 		mul_v3_fl(vtan,-cosf((float)M_PI*(part->tanphase+phase)));
@@ -1737,7 +1742,7 @@
 		mul_qt_qtqt(r_rot,r_rot,rot);
 	}
 
-	if (part->phystype==PART_PHYS_BOIDS && pa->boid) {
+	if (use_boids) {
 		float dvec[3], q[4], mat[3][3];
 
 		copy_v3_v3(state->co,loc);
@@ -1853,10 +1858,10 @@
 			}
 			
 			/* create rotation quat */
-			negate_v3(rot_vec);
 
+
 			if (use_global_space) {
-				/* calculate rotation in global-space */
+				negate_v3(rot_vec);
 				vec_to_quat(q2, rot_vec, OB_POSX, OB_POSZ);
 
 				/* randomize rotation quat */
@@ -1871,16 +1876,52 @@
 				/* calculate rotation in local-space */
 				float q_obmat[4];
 				float q_imat[4];
-				float tvec[3];
 
 				mat4_to_quat(q_obmat, ob->obmat);
 				invert_qt_qt(q_imat, q_obmat);
 
-				copy_v3_v3(tvec, rot_vec);
-				mul_qt_v3(q_imat, tvec);
-				normalize_v3(tvec);
-				vec_to_quat(q2, tvec, OB_POSX, OB_POSZ);
 
+				if (part->rotmode != PART_ROT_NOR) {
+					float rot_vec_local[3];
+
+					/* rot_vec */
+					negate_v3(rot_vec);
+					copy_v3_v3(rot_vec_local, rot_vec);
+					mul_qt_v3(q_imat, rot_vec_local);
+					normalize_v3(rot_vec_local);
+
+					vec_to_quat(q2, rot_vec_local, OB_POSX, OB_POSZ);
+				}
+				else {
+					/* (part->rotmode == PART_ROT_NOR) */
+					float tmat[3][3];
+
+					/* note: utan_local is not taken from 'utan', we calculate from rot_vec/vtan */
+					/* note: it looks like rotation phase may be applied twice (once with vtan, again below)
+					 * however this isn't the case - campbell */
+					float *rot_vec_local = tmat[0];
+					float *vtan_local    = tmat[1];
+					float *utan_local    = tmat[2];
+
+					/* use tangents */
+					BLI_assert(use_tangents == true);
+
+					/* rot_vec */
+					copy_v3_v3(rot_vec_local, rot_vec);
+					mul_qt_v3(q_imat, rot_vec_local);
+
+					/* vtan_local */
+					copy_v3_v3(vtan_local, vtan);  /* flips, cant use */
+					mul_qt_v3(q_imat, vtan_local);
+
+					/* ensure orthogonal matrix (rot_vec aligned) */
+					cross_v3_v3v3(utan_local, vtan_local, rot_vec_local);
+					cross_v3_v3v3(vtan_local, utan_local, rot_vec_local);
+
+					/* note: no need to normalize */
+					mat3_to_quat(q2, tmat);
+				}
+
 				/* randomize rotation quat */
 				if (part->randrotfac != 0.0f) {
 					mul_qt_qtqt(r_rot, r_rot, q_imat);




More information about the Bf-blender-cvs mailing list