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:
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