AlignToVector()

BlitzMax Forums/BlitzMax Programming/AlignToVector()

JoshK(Posted 2008) [#1]
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:
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



Dreamora(Posted 2008) [#2]
Tried to just normaly the vectors?
Especially the higher performant vector operations depend on them and break if you try to use them on non normalized vectors.


JoshK(Posted 2008) [#3]
If I just normalize the matrix at the beginning, the scale values get added back in when the rotation is performed.

This is awesome! You can align any axis, control the angle along the aligned axis, and use a rate: