I took the working code from MiniB3D for aligning the z axis, then I swapped the matrix rows to add correct calculation for x and y. It's pretty powerful because you can specify a roll value for any axis, and the rate/smoothing works as well.
However, this is extremely bloated and does not seem to work with scaling:
However, this is extremely bloated and does not seem to work with scaling:
Method AlignToVector(dir:TVec3,axis=3,rate#=1.0,roll_value#=0.0) Local pitch#,yaw#,roll#,dist# Local i:TVec3,j:TVec3,k:TVec3 dist#=Sqr(dir.x#*dir.x#+dir.z#*dir.z#) pitch#=ATan2(-dir.y#,dist#) yaw#=ATan2(-dir.x#,dir.z#) roll#=roll_value If rate=1.0 SetRotation vec3(pitch,yaw,roll),1 Else Select axis Case 1 i:TVec3=mat.i() k:TVec3=mat.k() mat.kx=i.x mat.ky=i.y mat.kz=i.z mat.ix=k.x mat.iy=k.y mat.iz=k.z mat.jx:*-1.0 mat.jy:*-1.0 mat.jz:*-1.0 Case 2 j:TVec3=mat.j() k:TVec3=mat.k() mat.kx=j.x mat.ky=j.y mat.kz=j.z mat.jx=k.x mat.jy=k.y mat.jz=k.z mat.ix:*-1.0 mat.iy:*-1.0 mat.iz:*-1.0 EndSelect quaternion=mat.rotation().slerp(vec3(pitch,yaw,roll).toquat(),rate) SetRotation quaternion.toeuler(),1 EndIf Select axis Case 1 i:TVec3=mat.i() k:TVec3=mat.k() mat.kx=i.x mat.ky=i.y mat.kz=i.z mat.ix=k.x mat.iy=k.y mat.iz=k.z mat.jx:*-1.0 mat.jy:*-1.0 mat.jz:*-1.0 Case 2 j:TVec3=mat.j() k:TVec3=mat.k() mat.kx=j.x mat.ky=j.y mat.kz=j.z mat.jx=k.x mat.jy=k.y mat.jz=k.z mat.ix:*-1.0 mat.iy:*-1.0 mat.iz:*-1.0 Case 3 Return EndSelect quaternion=TFormQuat(mat.rotation(),Null,parent) SetRotation quaternion.toeuler() EndMethod