forked from bartvdbraak/blender
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.
This commit is contained in:
parent
f5033303e1
commit
18cf21bbfe
@ -1660,17 +1660,22 @@ void psys_get_birth_coordinates(ParticleSimulationData *sim, ParticleData *pa, P
|
|||||||
{
|
{
|
||||||
Object *ob = sim->ob;
|
Object *ob = sim->ob;
|
||||||
ParticleSystem *psys = sim->psys;
|
ParticleSystem *psys = sim->psys;
|
||||||
ParticleSettings *part;
|
ParticleSettings *part = psys->part;
|
||||||
ParticleTexture ptex;
|
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 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 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 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];
|
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;
|
int p = pa - psys->particles;
|
||||||
part=psys->part;
|
|
||||||
|
|
||||||
/* get birth location from object */
|
/* 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);
|
psys_particle_on_emitter(sim->psmd, part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,utan,vtan,0,0);
|
||||||
else
|
else
|
||||||
psys_particle_on_emitter(sim->psmd, part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,0,0,0,0);
|
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 @@ void psys_get_birth_coordinates(ParticleSimulationData *sim, ParticleData *pa, P
|
|||||||
normalize_v3(nor);
|
normalize_v3(nor);
|
||||||
|
|
||||||
/* -tangent */
|
/* -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=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;
|
float phase=0.0f;
|
||||||
mul_v3_fl(vtan,-cosf((float)M_PI*(part->tanphase+phase)));
|
mul_v3_fl(vtan,-cosf((float)M_PI*(part->tanphase+phase)));
|
||||||
@ -1737,7 +1742,7 @@ void psys_get_birth_coordinates(ParticleSimulationData *sim, ParticleData *pa, P
|
|||||||
mul_qt_qtqt(r_rot,r_rot,rot);
|
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];
|
float dvec[3], q[4], mat[3][3];
|
||||||
|
|
||||||
copy_v3_v3(state->co,loc);
|
copy_v3_v3(state->co,loc);
|
||||||
@ -1853,10 +1858,10 @@ void psys_get_birth_coordinates(ParticleSimulationData *sim, ParticleData *pa, P
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* create rotation quat */
|
/* create rotation quat */
|
||||||
negate_v3(rot_vec);
|
|
||||||
|
|
||||||
if (use_global_space) {
|
if (use_global_space) {
|
||||||
/* calculate rotation in global-space */
|
negate_v3(rot_vec);
|
||||||
vec_to_quat(q2, rot_vec, OB_POSX, OB_POSZ);
|
vec_to_quat(q2, rot_vec, OB_POSX, OB_POSZ);
|
||||||
|
|
||||||
/* randomize rotation quat */
|
/* randomize rotation quat */
|
||||||
@ -1871,15 +1876,51 @@ void psys_get_birth_coordinates(ParticleSimulationData *sim, ParticleData *pa, P
|
|||||||
/* calculate rotation in local-space */
|
/* calculate rotation in local-space */
|
||||||
float q_obmat[4];
|
float q_obmat[4];
|
||||||
float q_imat[4];
|
float q_imat[4];
|
||||||
float tvec[3];
|
|
||||||
|
|
||||||
mat4_to_quat(q_obmat, ob->obmat);
|
mat4_to_quat(q_obmat, ob->obmat);
|
||||||
invert_qt_qt(q_imat, q_obmat);
|
invert_qt_qt(q_imat, q_obmat);
|
||||||
|
|
||||||
copy_v3_v3(tvec, rot_vec);
|
|
||||||
mul_qt_v3(q_imat, tvec);
|
if (part->rotmode != PART_ROT_NOR) {
|
||||||
normalize_v3(tvec);
|
float rot_vec_local[3];
|
||||||
vec_to_quat(q2, tvec, OB_POSX, OB_POSZ);
|
|
||||||
|
/* 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 */
|
/* randomize rotation quat */
|
||||||
if (part->randrotfac != 0.0f) {
|
if (part->randrotfac != 0.0f) {
|
||||||
|
Loading…
Reference in New Issue
Block a user