Are there any plans to replace the matrix math with quaternions? The transformation and positioning code is very good, but it will only be completely reliable with quaternions. I think fixing the entity system is more important than any additions or emulation of extra Blitz3D routines. In fact, it would be nice to have a bulletproof entity.mod that just handled transformations and rotations.
I notice I only get errors when I try to parent a null-parented entity to another entity. If I take a rotated entity's child and set the parent to null, it works fine.
Here's the quaternion code from my engine. I don't know how to implement this into MiniB3D's matrix system:
Const QuatToEulerAccuracy#=0.001
Global VECTOR_X#
Global VECTOR_Y#
Global VECTOR_Z#
Global VECTOR_W#
Function VectorX#()
Return VECTOR_X
EndFunction
Function VectorY#()
Return VECTOR_Y
EndFunction
Function VectorZ#()
Return VECTOR_Z
EndFunction
Function VectorW#()
Return VECTOR_W
EndFunction
Function EulerAsQuat(pitch#,yaw#,roll#)
cr#=Cos(-roll#/2.0)
cp#=Cos(pitch#/2.0)
cy#=Cos(yaw#/2.0)
sr#=Sin(-roll#/2.0)
sp#=Sin(pitch#/2.0)
sy#=Sin(yaw#/2.0)
cpcy#=cp#*cy#
spsy#=sp#*sy#
spcy#=sp#*cy#
cpsy#=cp#*sy#
VECTOR_w#=cr#*cpcy#+sr#*spsy#
VECTOR_x#=sr#*cpcy#-cr#*spsy#
VECTOR_y#=cr#*spcy#+sr#*cpsy#
VECTOR_z#=cr#*cpsy#-sr#*spcy#
End Function
Function QuatAsEuler(x#,y#,z#,w#)
sint#=(2.0*w*y)-(2.0*x*z)
cost_temp#=1.0-(sint#*sint#)
If Abs(cost_temp#)>QuatToEulerAccuracy
cost#=Sqr(cost_temp#)
Else
cost#=0.0
EndIf
If Abs(cost#)>QuatToEulerAccuracy
sinv#=((2.0*y*z)+(2.0*w*x))/cost#
cosv#=(1.0-(2.0*x*x)-(2.0*y*y))/cost#
sinf#=((2.0*x*y)+(2.0*w*z))/cost#
cosf#=(1.0-(2.0*y*y)-(2.0*z*z))/cost#
Else
sinv#=(2.0*w*x)-(2.0*y*z)
cosv#=1.0-(2.0*x*x)-(2.0*z*z)
sinf#=0.0
cosf#=1.0
EndIf
VECTOR_z#=-ATan2(sinv#,cosv#)
VECTOR_x#=ATan2(sint#,cost#)
VECTOR_y#=ATan2(sinf#,cosf#)
End Function
Function MulQuat(Ax#,Ay#,Az#,Aw#,Bx#,By#,Bz#,Bw#)
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#)
VECTOR_w#=b#+(-e#-f#+g#+h#)/2.0
VECTOR_x#=a#-(e#+f#+g#+h#)/2.0
VECTOR_y#=c#+(e#-f#+g#-h#)/2.0
VECTOR_z#=d#+(e#-f#-g#+h#)/2.0
End Function
Function Slerp(Ax#,Ay#,Az#,Aw#,Bx#,By#,Bz#,Bw#,t#)
If Abs(ax-bx)<0.001 And Abs(ay-by)<0.001 And Abs(az-bz)<0.001 And Abs(aw-bw)<0.001
VECTOR_x#=ax
VECTOR_y#=ay
VECTOR_z#=az
VECTOR_w#=aw
Return True
EndIf
cosineom#=Ax#*Bx#+Ay#*By#+Az#*Bz#+Aw#*Bw#
If cosineom# <= 0.0
cosineom#=-cosineom#
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.0 - cosineom#)>0.00001
omega#=ACos(cosineom#)
sineom#=Sin(omega#)
scale0#=Sin((1.0-t#)*omega#)/sineom#
scale1#=Sin(t#*omega#)/sineom#
Else
scale0#=1.0-t#
scale1#=t#
EndIf
VECTOR_w#=scale0#*Aw#+scale1#*scaler_w#
VECTOR_x#=scale0#*Ax#+scale1#*scaler_x#
VECTOR_y#=scale0#*Ay#+scale1#*scaler_y#
VECTOR_z#=scale0#*Az#+scale1#*scaler_z#
EndFunction
Function TurnQuat(Ax#,Ay#,Az#,Aw#,x#,y#,z#)
EulerAsQuat(x#,y#,z#)
mulquat(ax#,ay#,az#,aw#,VECTOR_x#,VECTOR_y#,VECTOR_z#,VECTOR_w#)
EndFunction
|