All I did was change the functions a little to work with my VectorX(),Y,Z conventions, which I find a little more robust. Since these return four values, the w value is returned by the function itself. This will be rewritten as a userlib, eventually, to go with the vector3D and plane3D libs.
; Quat.bb : v1.0 : 15/11/02 ; A tutorial on how to use this file is at <a href="http://www.dscho.co.uk/blitz/tutorials/quaternions.shtml" target="_blank">http://www.dscho.co.uk/blitz/tutorials/quaternions.shtml</a> Global vectorx#,vectory#,vectorz# Function VectorX#() Return vectorx# End Function Function VectorY#() Return vectory# End Function Function VectorZ#() Return vectorz# End Function ; Change these constants if you notice slips in accuracy Const QuatToEulerAccuracy# = 0.001 Const QuatSlerpAccuracy# = 0.0001 ;convert a Rotation to a Quat Function EulerToQuat(pitch#,yaw#,roll#) ;NB roll is inverted due to change in handedness of coordinate systems Local cr# = Cos(-roll/2) Local cp# = Cos(pitch/2) Local cy# = Cos(yaw/2) Local sr# = Sin(-roll/2) Local sp# = Sin(pitch/2) Local sy# = Sin(yaw/2) ;These variables are only here to cut down on the number of multiplications Local cpcy# = cp * cy Local spsy# = sp * sy Local spcy# = sp * cy Local cpsy# = cp * sy ;Generate the output quat w# = cr * cpcy + sr * spsy vectorx = sr * cpcy - cr * spsy vectory = cr * spcy + sr * cpsy vectorz = cr * cpsy - sr * spcy End Function ; convert a Quat to a Rotation Function QuatToEuler(quatx#,quaty#,quatz#,quatw#) Local sint#, cost#, sinv#, cosv#, sinf#, cosf# Local cost_temp# sint = (2 * quatw * quaty) - (2 * quatx * quatz) cost_temp = 1.0 - (sint * sint) If Abs(cost_temp) > QuatToEulerAccuracy cost = Sqr(cost_temp) Else cost = 0 EndIf If Abs(cost) > QuatToEulerAccuracy sinv = ((2 * quaty * quatz) + (2 * quatw * quatx)) / cost cosv = (1 - (2 * quatx * quatx) - (2 * quaty * quaty)) / cost sinf = ((2 * quatx * quaty) + (2 * quatw * quatz)) / cost cosf = (1 - (2 * quaty * quaty) - (2 * quatz * quatz)) / cost Else sinv = (2 * quatw * quatx) - (2 * quaty * quatz) cosv = 1 - (2 * quatx * quatx) - (2 * quatz * quatz) sinf = 0 cosf = 1 EndIf ;Generate the output rotation vectorx = -ATan2(sinv, cosv) ; inverted due to change in handedness of coordinate system vectory = ATan2(sint, cost) vectorz = ATan2(sinf, cosf) End Function ;use this to interpolate between quaternions Function QuatSlerp(Ax#,Ay#,Az#,Aw#,Bx#,By#,Bz#,Bw#,t#) Local scaler_w#, scaler_x#, scaler_y#, scaler_z# Local omega#, cosom#, sinom#, scale0#, scale1# cosom = Ax * Bx + Ay * By + Az * Bz + Aw * Bw If cosom <= 0.0 cosom = -cosom scaler_w = -Bw scaler_x = -Bx scaler_y = -By scaler_z = -Bz Else scaler_w = Bw scaler_x = Bx scaler_y = By scaler_z = Bz EndIf If (1 - cosom) > QuatSlerpAccuracy omega = ACos(cosom) sinom = Sin(omega) scale0 = Sin((1 - t) * omega) / sinom scale1 = Sin(t * omega) / sinom Else ;Angle too small: use linear interpolation instead scale0 = 1 - t scale1 = t EndIf vectorx# = scale0 * start\x + scale1 * scaler_x vectory# = scale0 * start\y + scale1 * scaler_y vectorz# = scale0 * start\z + scale1 * scaler_z w# = scale0 * start\w + scale1 * scaler_w Return w# End Function ; result will be the same rotation as doing q1 then q2 (order matters!) Function MultiplyQuat#(Ax#,Ay#,Az#,Aw#,Bx#,By#,Bz#,Bw#) Local a#, b#, c#, d#, e#, f#, g#, h# a = (Aw + Ax) * (Bw + Bx) b = (Az - Ay) * (By - Bz) c = (Aw - Ax) * (By + Bz) d = (Ay + Az) * (Bw - Bx) e = (Ax + Az) * (Bx + By) f = (Ax - Az) * (Bx - By) g = (Aw + Ay) * (Bw - Bz) h = (Aw - Ay) * (Bw + Bz) w# = b + (-e - f + g + h) / 2 vectorx# = a - ( e + f + g + h) / 2 vectory# = c + ( e - f + g - h) / 2 vectorz# = d + ( e - f - g + h) / 2 Return w# End Function