@@ -19,6 +19,7 @@ enum AlignLockAxis {
19
19
X ;
20
20
Y ;
21
21
Z ;
22
+ ScreenZ ; // Screen-facing flat polygons rotating around Z
22
23
}
23
24
24
25
enum EmitShape {
@@ -825,11 +826,9 @@ class EmitterObject extends h3d.scene.Object {
825
826
return ;
826
827
827
828
if ( parent != null ) {
828
- invTransform .load (parent .getInvPos ());
829
829
830
- if (alignMode == Screen || alignMode == Axis ) {
831
- var cam = getScene ().camera ;
832
- tmpMat .load (cam .mcam );
830
+ if (alignMode == Screen ) {
831
+ tmpMat .load (getScene ().camera .mcam );
833
832
tmpMat .invert ();
834
833
835
834
if (simulationSpace == Local ) { // Compensate parent rotation
@@ -840,19 +839,43 @@ class EmitterObject extends h3d.scene.Object {
840
839
tmpMat .multiply (tmpMat , tmpMat2 );
841
840
}
842
841
843
- if (alignMode == Axis ) {
844
- var a = getEulerAngles (tmpMat );
845
- switch alignLockAxis {
846
- case X : screenQuat .initRotation (a .x , 0 , 0 );
847
- case Y : screenQuat .initRotation (0 , a .y , 0 );
848
- case Z : screenQuat .initRotation (0 , 0 , a .z );
849
- }
842
+ screenQuat .initRotateMatrix (tmpMat );
843
+ tmpQuat .initRotateAxis (1 ,0 ,0 ,Math .PI ); // Flip Y axis so Y is pointing down
844
+ screenQuat .multiply (screenQuat , tmpQuat );
845
+ }
846
+ else if (alignMode == Axis ) {
847
+ var lockAxis = new h3d. Vector ();
848
+ var frontAxis = new h3d. Vector (1 , 0 , 0 );
849
+ switch alignLockAxis {
850
+ case X : lockAxis .set (1 , 0 , 0 );
851
+ case Y : lockAxis .set (0 , 1 , 0 );
852
+ case Z : lockAxis .set (0 , 0 , 1 );
853
+ case ScreenZ :
854
+ lockAxis .set (0 , 0 , 1 );
855
+ frontAxis .set (0 , 1 , 0 );
850
856
}
851
- else
852
- screenQuat .initRotateMatrix (tmpMat );
853
857
854
- if (alignMode == Screen ) {
855
- tmpQuat .initRotateAxis (1 ,0 ,0 ,Math .PI ); // Flip Y axis so Y is pointing down
858
+ var lookAtPos = tmpVec ;
859
+ lookAtPos .load (getScene ().camera .pos );
860
+ invTransform .load (parent .getInvPos ());
861
+ lookAtPos .transform (invTransform );
862
+ var deltaVec = new h3d. Vector (lookAtPos .x - x , lookAtPos .y - y , lookAtPos .z - z );
863
+
864
+ var invParentQ = tmpQuat ;
865
+ invParentQ .initRotateMatrix (invTransform );
866
+
867
+ var targetOnPlane = h3d.col. Plane .fromNormalPoint (lockAxis .toPoint (), new h3d.col. Point ()).project (deltaVec .toPoint ()).toVector ();
868
+ targetOnPlane .normalize ();
869
+ var angle = hxd. Math .acos (frontAxis .dot (targetOnPlane ));
870
+
871
+ var cross = frontAxis .cross (deltaVec );
872
+ if (lockAxis .dot (cross ) < 0 )
873
+ angle = - angle ;
874
+
875
+ screenQuat .initRotateAxis (lockAxis .x , lockAxis .y , lockAxis .z , angle );
876
+ screenQuat .normalize ();
877
+ if (alignLockAxis == ScreenZ ) {
878
+ tmpQuat .initRotateAxis (1 ,0 ,0 ,- Math .PI / 2 );
856
879
screenQuat .multiply (screenQuat , tmpQuat );
857
880
}
858
881
}
@@ -1090,7 +1113,7 @@ class Emitter extends Object3D {
1090
1113
{ name : " emitSurface" , t : PBool , def : false , disp : " Surface" , groupName : " Emit Shape" },
1091
1114
// ALIGNMENT
1092
1115
{ name : " alignMode" , t : PEnum (AlignMode ), def : AlignMode . None , disp : " Mode" , groupName : " Alignment" },
1093
- { name : " alignLockAxis" , t : PEnum (AlignLockAxis ), def : AlignLockAxis .Z , disp : " Lock Axis" , groupName : " Alignment" },
1116
+ { name : " alignLockAxis" , t : PEnum (AlignLockAxis ), def : AlignLockAxis . ScreenZ , disp : " Lock Axis" , groupName : " Alignment" },
1094
1117
// COLOR
1095
1118
{ name : " useRandomColor" , t : PBool , def : false , disp : " Random Color" , groupName : " Color" },
1096
1119
{ name : " randomColor1" , t : PVec (4 ), disp : " Color 1" , def : [0 ,0 ,0 ,1 ], groupName : " Color" },
0 commit comments