turn your total x,y,z eular rotations into a quat and apply like this, is this what you were meaning?
my old quat routines aint a best fit for minib3d but they could easily be modified to work with a 2d ([,]) array instead of a flat 1d ([]) array
at any rate I dont want to spoil the fun, (gotta leave you somthing to do! ;) )
my old quat routines aint a best fit for minib3d but they could easily be modified to work with a 2d ([,]) array instead of a flat 1d ([]) array
at any rate I dont want to spoil the fun, (gotta leave you somthing to do! ;) )
Import sidesign.minib3d SuperStrict Local width:Int=640,height:Int=480,depth:Int=16,mode:Int=0 Graphics3D width,height,depth,mode Local cam:TCamera=CreateCamera() PositionEntity cam , 0 , 0 , - 10 Local light:TLight=CreateLight(1) Local cube:TMesh = CreateCube() ScaleMesh cube , 1 , 1 , 3 PositionEntity cube , 10 , 0 ,0 Global zerospot:tentity=CreateCube() ScaleEntity zerospot , 0.1 , 0.1 , 0.1 ' used by camera code Local mxs#=0 Local mys#=0 Local move#=0.5 ' used by fps code Local old_ms#=MilliSecs() Local renders:Int Local fps:Int MoveMouse width / 2 , height / 2 RotateEntity cube , 45,45,45 Global m:Float[16] Global cubeQuat:Tquat=New Tquat Local m2:Float Ptr=cube.mat.grid m[0]=m2[0] m[4]=m2[4] m[8]=m2[8] m[1]=m2[1] m[5]=m2[5] m[9]=m2[9] m[2]=m2[2] m[6]=m2[6] m[10] = m2[10] cubequat.frommatrix(m) Global xturn:Tquat=New TQuat 'xturn.w=0.99996192306417131 ' a x rotation 'xturn.x = 0.0087265354983739347 xturn.w=0.99996192306417131 ' a z roatation xturn.z=0.0087265354983739347 While Not KeyDown(KEY_ESCAPE) If KeyHit(KEY_ENTER) Then DebugStop '' control camera ' mouse look mxs#=mxs#+((MouseX()-width/2)/5.0) mys#=mys#+((MouseY()-height/2)/5.0) RotateEntity cam,mys#,-mxs#,0 MoveMouse width/2,height/2 ' move camera forwards/backwards/left/right with cursor keys If KeyDown(KEY_UP)=True Then MoveEntity cam,0,0,move# ' move camera forward If KeyDown(KEY_DOWN)=True Then MoveEntity cam,0,0,-move# ' move camera back If KeyDown(KEY_LEFT)=True Then MoveEntity cam,-move#,0,0 ' move camera left If KeyDown(KEY_RIGHT)=True Then MoveEntity cam,move#,0,0 ' move camera right '' ' TurnEntity cube,1,0,0 cubequat.multiply(xturn) m = cubequat.tomatrix() Local m2:Float Ptr=cube.mat.grid m2[0]=m[0] m2[4]=m[4] m2[8]=m[8] m2[1]=m[1] m2[5]=m[5] m2[9]=m[9] m2[2]=m[2] m2[6]=m[6] m2[10] = m[10] RenderWorld renders=renders+1 ' calculate fps If MilliSecs()-old_ms>=1000 old_ms=MilliSecs() fps=renders renders=0 EndIf Text 0,0,"FPS: "+String(fps) displaymat(m , 20 , 20) text 20 , 100 , "q " + cubequat.x + " " + cubequat.y + " " + cubequat.z + " " + cubequat.w text 20 , 120 , "t " + xturn.x + " " + xturn.y + " " + xturn.z + " " + xturn.w Flip Wend End Function floatString:String(v#,d:Int=4,p:Int=4) Local m$, e$, r$, n:Int, x#=Abs(v) If p>0 Then m$=Int((x-Floor(x))*10^p) ; e$="."+Right$("000000"+m$,p) If p=0 Or Len(m$)>p Then n=Int(x) Else n=Floor(x) If v<0 Then r$="-"+n Else r$=n Return RSet$(r$,d)+e$ End Function Function displaymat(m:Float[],x:Int,y:Int) ' glpushmatrix For Local i:Int=0 To 3 For Local j:Int=0 To 3 GLDrawText FloatString(m[i*4+j]),j*80+x,i*12+y Next Next ' glpopmatrix EndFunction Type TVec3 Field x#,y#,z# Method Set(nx#,ny#,nz#) x=nx;y=ny;z=nz EndMethod Method Normalise() Local l:Float l=Sqr(x*x+y*y+z*z) If l=1 Then Return x:/l y:/l z:/l EndMethod EndType Type TQuat Field x#,y#,z#,w# Method FromMatrix(mat:Float[]) Local T:Float= 1 + mat[0] + mat[5] + mat[10] Local S:Float If ( T > 0.00000001 ) Then S = Sqr(T) * 2 X = ( mat[6] - mat[9] ) / S Y = ( mat[8] - mat[2] ) / S Z = ( mat[1] - mat[4] ) / S W = 0.25 * S Return EndIf If mat[0] > mat[5] And mat[0] > mat[10] Then 'Column 0: S = Sqr( 1.0 + mat[0] - mat[5] - mat[10] ) * 2 X = 0.25 * S Y = (mat[1] + mat[4] ) / S Z = (mat[8] + mat[2] ) / S W = (mat[6] - mat[9] ) / S ElseIf mat[5] > mat[10] 'Column 1: S = Sqr( 1.0 + mat[5] - mat[0] - mat[10] ) * 2 X = (mat[1] + mat[4] ) / S Y = 0.25 * S Z = (mat[6] + mat[9] ) / S W = (mat[8] - mat[2] ) / S Else 'Column 2: S = Sqr( 1.0 + mat[10] - mat[0] - mat[5] ) * 2 X = (mat[8] + mat[2] ) / S Y = (mat[6] + mat[9] ) / S Z = 0.25 * S W = (mat[1] - mat[4] ) / S EndIf EndMethod Method ToMatrix:Float[]() Local xx!=x*x Local xy!=x*y Local xz!=x*z Local xw!=x*w Local yy!=y*y Local yz!=y*z Local yw!=y*w Local zz!=z*z Local zw!=z*w Local m:Float[16] m[0]= 1-2*(yy+zz) m[4]= 2*(xy-zw) m[8]= 2*(xz+yw) m[1]= 2*(xy+zw) m[5]= 1-2*(xx+zz) m[9]= 2*(yz-xw) m[2]= 2*(xz-yw) m[6]= 2*(yz+xw) m[10]=1-2*(xx+yy) m[12]=0;m[13]=0;m[14]=0 m[3]=0;m[7]=0;m[11]=0 m[15]=1 Return m EndMethod Method Normalise() Local m:Float m=Sqr(w*w+x*x+y*y+z*z) If m=1 Then Return ' is exactly 1 more often than you'd think... w:/m x:/m y:/m z:/m EndMethod Method FromAxisAngle(a#,axis:TVec3) Local sin_a# = Sin( a / 2 ) Local cos_a# = Cos( a / 2 ) X = axis.x * sin_a Y = axis.y * sin_a Z = axis.z * sin_a W = cos_a Normalise() Return EndMethod Method Multiply:TQuat(q:TQuat) Local a#, b#, c#, d#, e#, f#, g#, h# a = (w + x) * (q.w + q.x) b = (z - y) * (q.y - q.z) c = (w - x) * (q.y + q.z) d = (y + z) * (q.w - q.x) e = (x + z) * (q.x + q.y) f = (x - z) * (q.x - q.y) g = (w + y) * (q.w - q.z) h = (w - y) * (q.w + q.z) w = b + (-e - f + g + h) / 2 x = a - ( e + f + g + h) / 2 y = c + ( e - f + g - h) / 2 z = d + ( e - f - g + h) / 2 End Method Const QuatToEulerAccuracy# = 0.000000000001 Method GetEuler:TVec3() ' using vec3 to hold eulers Local sint#, cost#, sinv#, cosv#, sinf#, cosf# Local cost_temp# normalise() sint = (2 * w * y) - (2 * x * z) 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 * y * z) + (2 * w * x)) / cost cosv = (1 - (2 * x * x) - (2 * y * y)) / cost sinf = ((2 * x * y) + (2 * w * z)) / cost cosf = (1 - (2 * y * y) - (2 * z * z)) / cost Else sinv = (2 * w * x) - (2 * y * z) cosv = 1 - (2 * x * x) - (2 * z * z) sinf = 0 cosf = 1 EndIf Local out:TVec3=New Tvec3 out.x = ATan2(sinv, cosv) out.y = ATan2(sint, cost) out.z = ATan2(sinf, cosf) ' out.x=bound(out.x) ' out.y=bound(out.y) ' out.z=bound(out.z) Return out EndMethod Method Copy(q:TQuat) w=q.w x=q.x y=q.y z=q.z EndMethod Method FromEuler(src:TVec3) Local cr# = Cos(src.x/2) Local cp# = Cos(src.y/2) Local cy# = Cos(src.z/2) Local sr# = Sin(src.x/2) Local sp# = Sin(src.y/2) Local sy# = Sin(src.z/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 w = cr * cpcy + sr * spsy x = sr * cpcy - cr * spsy y = cr * spcy + sr * cpsy z = cr * cpsy - sr * spcy normalise() EndMethod Method Set(nw#,nx#,ny#,nz#) w=nw;x=nx;y=ny;z=nz EndMethod Method Invert() x=-x;y=-y;z=-z EndMethod EndType