Turret example using some new axis-angle rotation commands I just finished coding:
set display mode 1024,768,32
cls
cls
sync
ink rgb(192,192,192),0
box 0,0,100,100
for n=1 to 10
ink rgb(rnd(255),rnd(255),rnd(255)),0
w=rnd(20)+10
h=rnd(20)+10
x=rnd(100-w)
y=rnd(100-h)
box x,y,x+w,y+h
next n
sync
get image 1,1,1,100,100
sync on
sync rate 0
cls
autocam off
type turret_type
base as integer
barrel as integer
ax as float
ay as float
az as float
exist
rollspeed as float
endtype
dim turret(100) as turret_type
for n=1 to 2
o=freeobj()
size#=20+2
make object cube o,size#
position object o,-30+(n-1)*60,0,0
rotate object o,rnd(360),rnd(360),rnd(360)
x#=object position x(o):y#=object position y(o):z#=object position z(o)
move object o,size#/2
ax#=object position x(o)-x#:ay#=object position y(o)-y#:az#=object position z(o)-z#
make_turret(object position x(o),object position y(o),object position z(o),ax#,ay#,az#)
move object o,-size#
ax#=object position x(o)-x#:ay#=object position y(o)-y#:az#=object position z(o)-z#
make_turret(object position x(o),object position y(o),object position z(o),ax#,ay#,az#)
move object o,size#/2
move object right o,size#/2
ax#=object position x(o)-x#:ay#=object position y(o)-y#:az#=object position z(o)-z#
make_turret(object position x(o),object position y(o),object position z(o),ax#,ay#,az#)
move object right o,-size#
ax#=object position x(o)-x#:ay#=object position y(o)-y#:az#=object position z(o)-z#
make_turret(object position x(o),object position y(o),object position z(o),ax#,ay#,az#)
move object right o,size#/2
move object up o,size#/2
ax#=object position x(o)-x#:ay#=object position y(o)-y#:az#=object position z(o)-z#
make_turret(object position x(o),object position y(o),object position z(o),ax#,ay#,az#)
move object up o,-size#
ax#=object position x(o)-x#:ay#=object position y(o)-y#:az#=object position z(o)-z#
make_turret(object position x(o),object position y(o),object position z(o),ax#,ay#,az#)
move object up o,size#/2
next n
type xyz
x as float
y as float
z as float
endtype
type ship_type
v as xyz
typ as string
object
exist
turnspeed as float
rollspeed as float
pitchspeed as float
fthrust as float
rthrust as float
uthrust as float
vf as float
vr as float
vu as float
endtype
dim ship(1) as ship_type
make_ship(1,"Human")
position object ship(1).object,0,0,0
controlship=1
viewship=1
global time as float
lasttimer=timer()
rem main loop
do
set cursor 0,0
print "FPS:",screen fps()
time=(timer()-lasttimer)*0.001
lasttimer=timer()
gosub inpt
gosub physics
gosub camera
gosub turrets
sync
loop
turrets:
for t=1 to 100
if turret(t).exist=1
tx#=object position x(ship(1).object)
ty#=object position y(ship(1).object)
tz#=object position z(ship(1).object)
targ_y#=FindAxisAngleYtoPoint(turret(t).base,turret(t).ax,turret(t).ay,turret(t).az,tx#,ty#,tz#)
RotateAxisAngleY(turret(t).base,turret(t).ax,turret(t).ay,turret(t).az,curveangle(targ_y#,Axis_Angle_Y(turret(t).base,turret(t).ax,turret(t).ay,turret(t).az),20))
RotateAxisAngleY(turret(t).barrel,turret(t).ax,turret(t).ay,turret(t).az,Axis_Angle_Y(turret(t).base,turret(t).ax,turret(t).ay,turret(t).az))
targ_x#=FindAxisAngleXtoPoint(turret(t).barrel,turret(t).ax,turret(t).ay,turret(t).az,tx#,ty#,tz#)
if targ_x#<180 then targ_x#=0
if targ_x#>180 and targ_x#<270 then targ_x#=270
RotateAxisAngleX(turret(t).barrel,turret(t).ax,turret(t).ay,turret(t).az,curveangle(targ_x#,Axis_Angle_X(turret(t).barrel,turret(t).ax,turret(t).ay,turret(t).az),20))
RotateAxisAngleX(turret(t).base,turret(t).ax,turret(t).ay,turret(t).az,0)
RotateAxisAngleZ(turret(t).base,turret(t).ax,turret(t).ay,turret(t).az,0)
az#=Axis_Angle_Z(turret(t).barrel,turret(t).ax,turret(t).ay,turret(t).az)
if az#>180 then az#=az#-360
if (tx#-object position x(turret(t).base))^2+(ty#-object position y(turret(t).base))^2+(tz#-object position z(turret(t).base))^2<40^2
turret(t).rollspeed=turret(t).rollspeed+0.5
turret(t).rollspeed=(turret(t).rollspeed)*0.9
else
turret(t).rollspeed=(turret(t).rollspeed-az#*0.001)*0.9
endif
rotate_LZ(turret(t).barrel,turret(t).rollspeed)
endif
next t
return
function make_ship(num,typ$)
o=freeobj()
ship(num).exist=1
ship(num).v.x=0
ship(num).v.y=0
ship(num).v.z=0
ship(num).typ=typ$
ship(num).object=o
make object box o,2,1,3
endfunction
inpt:
ship(controlship).turnspeed=mousex()-screen width()/2.0
ship(controlship).pitchspeed=mousey()-screen height()/2.0
ship(controlship).rollspeed=curvevalue((keystate(32)-keystate(30))*180,ship(controlship).rollspeed,50)
ship(controlship).fthrust=curvevalue((keystate(17)*2.0-keystate(31)*1.0)*0.3,ship(controlship).fthrust,70)
ship(controlship).rthrust=curvevalue((keystate(35)-keystate(33))*0.2,ship(controlship).rthrust,70)
ship(controlship).uthrust=curvevalue((keystate(20)-keystate(34))*0.2,ship(controlship).uthrust,70)
return
physics:
for s=1 to 1
if ship(s).exist=1
o=ship(s).object
turn object right o,ship(s).turnspeed*time
pitch object down o,ship(s).pitchspeed*time
roll object right o,ship(s).rollspeed*time
position object o,object position x(o)+ship(s).v.x*time,object position y(o)+ship(s).v.y*time,object position z(o)+ship(s).v.z*time
fx#=object position x(o)
fy#=object position y(o)
fz#=object position z(o)
move object o,1
fx#=object position x(o)-fx#
fy#=object position y(o)-fy#
fz#=object position z(o)-fz#
move object o,-1
rx#=object position x(o)
ry#=object position y(o)
rz#=object position z(o)
move object right o,1
rx#=object position x(o)-rx#
ry#=object position y(o)-ry#
rz#=object position z(o)-rz#
move object right o,-1
ux#=object position x(o)
uy#=object position y(o)
uz#=object position z(o)
move object up o,1
ux#=object position x(o)-ux#
uy#=object position y(o)-uy#
uz#=object position z(o)-uz#
move object up o,-1
ship(s).vf=fx#*ship(s).v.x+fy#*ship(s).v.y+fz#*ship(s).v.z
ship(s).vr=rx#*ship(s).v.x+ry#*ship(s).v.y+rz#*ship(s).v.z
ship(s).vu=ux#*ship(s).v.x+uy#*ship(s).v.y+uz#*ship(s).v.z
ship(s).v.x=ship(s).v.x+ship(s).fthrust*fx#+ship(s).rthrust*rx#+ship(s).uthrust*ux#
ship(s).v.y=ship(s).v.y+ship(s).fthrust*fy#+ship(s).rthrust*ry#+ship(s).uthrust*uy#
ship(s).v.z=ship(s).v.z+ship(s).fthrust*fz#+ship(s).rthrust*rz#+ship(s).uthrust*uz#
ship(s).v.x=ship(s).v.x*0.99
ship(s).v.y=ship(s).v.y*0.99
ship(s).v.z=ship(s).v.z*0.99
endif
next s
return
camera:
if viewship>0
o=ship(viewship).object
fx#=object position x(o)
fy#=object position y(o)
fz#=object position z(o)
move object o,1
fx#=object position x(o)-fx#
fy#=object position y(o)-fy#
fz#=object position z(o)-fz#
move object o,-1
rx#=object position x(o)
ry#=object position y(o)
rz#=object position z(o)
move object right o,1
rx#=object position x(o)-rx#
ry#=object position y(o)-ry#
rz#=object position z(o)-rz#
move object right o,-1
ux#=object position x(o)
uy#=object position y(o)
uz#=object position z(o)
move object up o,1
ux#=object position x(o)-ux#
uy#=object position y(o)-uy#
uz#=object position z(o)-uz#
move object up o,-1
o=ship(viewship).object
ink rgb(0,255,0),0
box screen width()/2.0-2,screen height()/2.0-2,screen width()/2.0+2,screen height()/2.0+2
position camera object position x(o),object position y(o), object position z(o)
set camera to object orientation o
pitch camera down 5
move camera -10
cx#=camera position x()
cy#=camera position y()
cz#=camera position z()
position camera object position x(o),object position y(o), object position z(o)
point camera object position x(o)+ship(viewship).v.x,object position y(o)+ship(viewship).v.y, object position z(o)+ship(viewship).v.z
speed#=sqrt(ship(viewship).v.x^2+ship(viewship).v.y^2+ship(viewship).v.z^2)
move camera -2*speed#/200.0
cx2#=camera position x()
cy2#=camera position y()
cz2#=camera position z()
set camera to object orientation o
wx#=cx2#
wy#=cy2#
wz#=cz2#
wx#=(cx#+cx2#)/2.0
wy#=(cy#+cy2#)/2.0
wz#=(cz#+cz2#)/2.0
dx#=wx#-object position x(o)
dy#=wy#-object position y(o)
dz#=wz#-object position z(o)
lz#=dx#*fx#+dy#*fy#+dz#*fz#
lx#=dx#*rx#+dy#*ry#+dz#*rz#
ly#=dx#*ux#+dy#*uy#+dz#*uz#
d#=sqrt(dx#^2+dy#^2+dz#^2)
nx#=dx#/d#
ny#=dy#/d#
nz#=dz#/d#
wx#=wx#+(10-d#)*nx#
wy#=wy#+(10-d#)*ny#
wz#=wz#+(10-d#)*nz#
print "Speed along relative Z axis:",ship(viewship).vf
print "Speed along relative X axis:",ship(viewship).vr
print "Speed along relative Y axis:",ship(viewship).vu
position camera wx#,wy#,wz#
set camera to object orientation o
turn camera left atanfull(lx#,-lz#)
pitch camera down atanfull(ly#,sqrt(lx#^2+lz#^2))
line screen width()/2.0,screen height()/2.0,screen width()/2.0+ship(viewship).vr,screen height()/2.0-ship(viewship).vu
ink rgb(255,0,0),0
line screen width()/2.0,screen height()/2.0,screen width()/2.0,screen height()/2.0-ship(viewship).vf
endif
return
function make_turret(px#,py#,pz#,ax#,ay#,az#)
n=0
repeat
inc n
until turret(n).exist=0
turret(n).exist=1
turret(n).ax=ax#
turret(n).ay=ay#
turret(n).az=az#
turret(n).base=freeobj()
make object box turret(n).base,6,3,6
position object turret(n).base,px#,py#,pz#
turret(n).barrel=freeobj()
make object box turret(n).barrel,4,2,10
offset limb turret(n).barrel,0,0,0,6
a#=sqrt(ax#^2+ay#^2+az#^2)
position object turret(n).barrel,px#+ax#/a#,py#+ay#/a#,pz#+az#/a#
texture object turret(n).base,1
texture object turret(n).barrel,1
endfunction
function freeobj()
repeat:inc o:until object exist(o)=0
endfunction o
remstart Rotate_GX
This function rotates the given object around the global (world) x axis by
the given amount.
Param obj The object to rotate
Param amount# The angle to rotate the object by
remend
function rotate_GX(obj as integer,amount# as float)
rem get normal vectors for X, Y, and Z axes of the object
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object right obj,1
xx#=object position x(obj)-x#:xy#=object position y(obj)-y#:xz#=object position z(obj)-z#
move object left obj,1:move object up obj,1
yx#=object position x(obj)-x#:yy#=object position y(obj)-y#:yz#=object position z(obj)-z#
move object down obj,1:move object obj,1
zx#=object position x(obj)-x#:zy#=object position y(obj)-y#:zz#=object position z(obj)-z#
move object obj,-1
rem rotate the vectors
xx1#=xx#
xy1#=xy#*cos(amount#)-xz#*sin(amount#)
xz1#=xz#*cos(amount#)+xy#*sin(amount#)
zx1#=zx#
zy1#=zy#*cos(amount#)-zz#*sin(amount#)
zz1#=zz#*cos(amount#)+zy#*sin(amount#)
rem calculate angle z
zr#=atanfull(xy1#,xx1#)
rem calculate angle y
xx2#=xx1#*cos(zr#)+xy1#*sin(zr#)
xy2#=xy1#*cos(zr#)-xx1#*sin(zr#)
xz2#=xz1#
zx2#=zx1#*cos(zr#)+zy1#*sin(zr#)
zy2#=zy1#*cos(zr#)-zx1#*sin(zr#)
zz2#=zz1#
yr#=atanfull(xx2#,xz2#)-90
rem calculate angle x
zx3#=zx2#*cos(yr#+90)-zz2#*sin(yr#+90)
zy3#=zy2#
xr#=atanfull(zy3#,zx3#)+180
if xr#+1>xr# and yr#+1>yr# and zr#+1>zr#
rotate object obj,xr#,yr#,zr#
endif
endfunction
remstart Rotate_GY
This function rotates the given object around the global (world) y axis by
the given amount.
Param obj The object to rotate
Param amount# The angle to rotate the object by
remend
function rotate_GY(obj,amount#)
rem get normal vectors for X, Y, and Z axes of the object
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object right obj,1
xx#=object position x(obj)-x#:xy#=object position y(obj)-y#:xz#=object position z(obj)-z#
move object left obj,1:move object up obj,1
yx#=object position x(obj)-x#:yy#=object position y(obj)-y#:yz#=object position z(obj)-z#
move object down obj,1:move object obj,1
zx#=object position x(obj)-x#:zy#=object position y(obj)-y#:zz#=object position z(obj)-z#
move object obj,-1
rem rotate the vectors
xx1#=xx#*cos(amount#)+xz#*sin(amount#)
xy1#=xy#
xz1#=xz#*cos(amount#)-xx#*sin(amount#)
zx1#=zx#*cos(amount#)+zz#*sin(amount#)
zy1#=zy#
zz1#=zz#*cos(amount#)-zx#*sin(amount#)
rem calculate angle z
zr#=atanfull(xy1#,xx1#)
rem calculate angle y
xx2#=xx1#*cos(zr#)+xy1#*sin(zr#)
xy2#=xy1#*cos(zr#)-xx1#*sin(zr#)
xz2#=xz1#
zx2#=zx1#*cos(zr#)+zy1#*sin(zr#)
zy2#=zy1#*cos(zr#)-zx1#*sin(zr#)
zz2#=zz1#
yr#=atanfull(xx2#,xz2#)-90
rem calculate angle x
zx3#=zx2#*cos(yr#+90)-zz2#*sin(yr#+90)
zy3#=zy2#
xr#=atanfull(zy3#,zx3#)+180
if xr#+1>xr# and yr#+1>yr# and zr#+1>zr#
rotate object obj,xr#,yr#,zr#
endif
endfunction
remstart Rotate_GZ
This function rotates the given object around the global (world) z axis by
the given amount.
Param obj The object to rotate
Param amount# The angle to rotate the object by
remend
function rotate_GZ(obj,amount#)
rem Rotating around the global Z axis is trivial
rem as it is the first rotation anyway in the default ZYX rotation order
rotate object obj,object angle x(obj),object angle y(obj),object angle z(obj)+amount#
endfunction
remstart Rotate_axis
This function rotates the given object around the given axis by the given
amount. This function is called by many other functions.
Param obj The object to rotate
Param ax#,ay#,az# The x,y and z components of the rotation axis
Param amount# The angle to rotate the object by
remend
function rotate_axis(obj,ax#,ay#,az#,amount#)
rem get normal vectors for X, Y, and Z axes of the object
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object right obj,1
xx#=object position x(obj)-x#:xy#=object position y(obj)-y#:xz#=object position z(obj)-z#
move object left obj,1:move object up obj,1
yx#=object position x(obj)-x#:yy#=object position y(obj)-y#:yz#=object position z(obj)-z#
move object down obj,1:move object obj,1
zx#=object position x(obj)-x#:zy#=object position y(obj)-y#:zz#=object position z(obj)-z#
move object obj,-1
rem rotate the vectors
rem 1) rotate space about the x axis so that the rotation axis lies in the xz plane
xangle#=atanfull(ay#,az#)
xx1#=xx#
xy1#=xy#*cos(xangle#)-xz#*sin(xangle#)
xz1#=xz#*cos(xangle#)+xy#*sin(xangle#)
zx1#=zx#
zy1#=zy#*cos(xangle#)-zz#*sin(xangle#)
zz1#=zz#*cos(xangle#)+zy#*sin(xangle#)
ax1#=ax#
ay1#=ay#*cos(xangle#)-az#*sin(xangle#)
az1#=az#*cos(xangle#)+ay#*sin(xangle#)
rem 2) rotate space about the y axis so that the rotation axis lies along the z axis
yangle#=-atanfull(ax1#,az1#)
xx2#=xx1#*cos(yangle#)+xz1#*sin(yangle#)
xy2#=xy1#
xz2#=xz1#*cos(yangle#)-xx1#*sin(yangle#)
zx2#=zx1#*cos(yangle#)+zz1#*sin(yangle#)
zy2#=zy1#
zz2#=zz1#*cos(yangle#)-zx1#*sin(yangle#)
ax2#=ax1#*cos(yangle#)+az1#*sin(yangle#)
ay2#=ay1#
az2#=az1#*cos(yangle#)-ax1#*sin(yangle#)
rem 3) perform the desired rotation by theta about the z axis
xx3#=xx2#*cos(amount#)-xy2#*sin(amount#)
xy3#=xy2#*cos(amount#)+xx2#*sin(amount#)
xz3#=xz2#
zx3#=zx2#*cos(amount#)-zy2#*sin(amount#)
zy3#=zy2#*cos(amount#)+zx2#*sin(amount#)
zz3#=zz2#
rem 4) Inverse of step 2
xx4#=xx3#*cos(-yangle#)+xz3#*sin(-yangle#)
xy4#=xy3#
xz4#=xz3#*cos(-yangle#)-xx3#*sin(-yangle#)
zx4#=zx3#*cos(-yangle#)+zz3#*sin(-yangle#)
zy4#=zy3#
zz4#=zz3#*cos(-yangle#)-zx3#*sin(-yangle#)
rem 5) Inverse of step 1
xx1#=xx4#
xy1#=xy4#*cos(-xangle#)-xz4#*sin(-xangle#)
xz1#=xz4#*cos(-xangle#)+xy4#*sin(-xangle#)
zx1#=zx4#
zy1#=zy4#*cos(-xangle#)-zz4#*sin(-xangle#)
zz1#=zz4#*cos(-xangle#)+zy4#*sin(-xangle#)
rem calculate angle z
zr#=atanfull(xy1#,xx1#)
rem calculate angle y
xx2#=xx1#*cos(zr#)+xy1#*sin(zr#)
xy2#=xy1#*cos(zr#)-xx1#*sin(zr#)
xz2#=xz1#
zx2#=zx1#*cos(zr#)+zy1#*sin(zr#)
zy2#=zy1#*cos(zr#)-zx1#*sin(zr#)
zz2#=zz1#
yr#=atanfull(xx2#,xz2#)-90
rem calculate angle x
zx3#=zx2#*cos(yr#+90)-zz2#*sin(yr#+90)
zy3#=zy2#
xr#=atanfull(zy3#,zx3#)+180
if xr#+1>xr# and yr#+1>yr# and zr#+1>zr#
rotate object obj,xr#,yr#,zr#
endif
endfunction
remstart Rotate_LX
This function rotates the given object around the object's local x axis by
the given amount. This function calls rotate_axis() to do the rotation.
Param obj The object to rotate
Param amount# The angle to rotate the object by
remend
function rotate_LX(obj as integer,amount# as float)
rem Rotating around the local X axis is trivial
rem as it is the last rotation anyway in the default ZYX rotation order
rotate object obj,object angle x(obj)+amount#,object angle y(obj),object angle z(obj)
endfunction
remstart Rotate_LY
This function rotates the given object around the object's local y axis by
the given amount. This function calls rotate_axis() to do the rotation.
Param obj The object to rotate
Param amount# The angle to rotate the object by
remend
function rotate_LY(obj as integer,amount# as float)
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object up obj,1
yx#=object position x(obj)-x#:yy#=object position y(obj)-y#:yz#=object position z(obj)-z#
move object down obj,1
rotate_axis(obj,yx#,yy#,yz#,amount#)
endfunction
remstart Rotate_LZ
This function rotates the given object around the object's local z axis by
the given amount. This function calls rotate_axis() to do the rotation.
Param obj The object to rotate
Param amount# The angle to rotate the object by
remend
function rotate_LZ(obj as integer,amount# as float)
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object obj,1
zx#=object position x(obj)-x#:zy#=object position y(obj)-y#:zz#=object position z(obj)-z#
move object obj,-1
rotate_axis(obj,zx#,zy#,zz#,amount#)
endfunction
remstart AngleBetweenPoints
This function takes an origin and 2 points and finds the angle between them
through the given origin.
Param originX#,originY#,originX# The point that is to be the origin
Param point1X#,point1Y#,point1Z# The first point
Param point2X#,point2Y#,point2Z# The second point
Return angle# The angle between the 2 points
remend
function AngleBetweenPoints(originX#, originY#, originZ#, point1X#, point1Y#, point1Z#, point2X#, point2Y#, point2Z#)
v1x#=point1X#-originX#
v1y#=point1Y#-originY#
v1z#=point1Z#-originZ#
v1#=sqrt(v1x#*v1x#+v1y#*v1y#+v1z#*v1z#)
v2x#=point2X#-originX#
v2y#=point2Y#-originY#
v2z#=point2Z#-originZ#
v2#=sqrt(v2x#*v2x#+v2y#*v2y#+v2z#*v2z#)
angle#=acos((v1x#*v2x#+v1y#*v2y#+v1z#*v2z#)/(v1#*v2#))
endfunction angle#
remstart Align_Axes
This function aligns an arbitrary axis local to the object to an arbitrary
global axis. When called every frame, the function effectively "locks" the
object so that it can only rotate around the given global axis.
Param obj The object to rotate
Param lx#,ly#,lz# The local axis
Param gx#,gy#,gz# The global axis
remend
function Align_Axes(obj,lx#,ly#,lz#,gx#,gy#,gz#)
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object right obj,lx#:move object up obj,ly#:move object obj,lz#
glx#=object position x(obj)-x#:gly#=object position y(obj)-y#:glz#=object position z(obj)-z#
move object right obj,-lx#:move object up obj,-ly#:move object obj,-lz#
l#=sqrt(glx#^2+gly#^2+glz#^2)
g#=sqrt(gx#^2+gy#^2+gz#^2)
angle#=acos((glx#*gx#+gly#*gy#+glz#*gz#)/(l#*g#))
crosspx#=(gly# * gz# - glz# * gy#)
crosspy#=(glz# * gx# - glx# * gz#)
crosspz#=(glx# * gy# - gly# * gx#)
rotate_axis(obj,crosspx#,crosspy#,crosspz#,angle#)
endfunction
remstart Smooth_Align_Axes
This function aligns an arbitrary axis local to the object to an arbitrary
global axis. The function will rotate no more than the given maximum angle
so that the alignment can be smoothed out over multiple frames.
Param obj The object to rotate
Param lx#,ly#,lz# The local axis
Param gx#,gy#,gz# The global axis
Param max_angle# The maximum angle by which the object may be rotated
remend
function Smooth_Align_Axes(obj,lx#,ly#,lz#,gx#,gy#,gz#,max_angle#)
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object right obj,lx#:move object up obj,ly#:move object obj,lz#
glx#=object position x(obj)-x#:gly#=object position y(obj)-y#:glz#=object position z(obj)-z#
move object right obj,-lx#:move object up obj,-ly#:move object obj,-lz#
l#=sqrt(glx#^2+gly#^2+glz#^2)
g#=sqrt(gx#^2+gy#^2+gz#^2)
angle#=acos((glx#*gx#+gly#*gy#+glz#*gz#)/(l#*g#))
if angle#>max_angle#
angle#=max_angle#
endif
if angle#<-max_angle#
angle#=-max_angle#
endif
crosspx#=(gly# * gz# - glz# * gy#)
crosspy#=(glz# * gx# - glx# * gz#)
crosspz#=(glx# * gy# - gly# * gx#)
rotate_axis(obj,crosspx#,crosspy#,crosspz#,angle#)
endfunction
remstart Angle_Axes
This function rotates the object such that the given local axis has an angle
equal to the given angle with the global axis. Al
Param obj The object to rotate
Param lx#,ly#,lz# The local axis
Param gx#,gy#,gz# The global axis
Param ang# The given angle to keep between the local and global
axes. Flag also uses it to provide more functionality.
Param flag Used to decide when to perform the actual rotation
Flag Usage:
If flag=0, the rotation will occur.
If flag<0, the rotation will occur if the angle between the axes is less
than the given angle.
If flag>0, the rotation will occur if the angle between the axes is
greater than the given angle.
remend
function Angle_Axes(obj,lx#,ly#,lz#,gx#,gy#,gz#,ang#,flag)
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object right obj,lx#:move object up obj,ly#:move object obj,lz#
glx#=object position x(obj)-x#:gly#=object position y(obj)-y#:glz#=object position z(obj)-z#
move object right obj,-lx#:move object up obj,-ly#:move object obj,-lz#
l#=sqrt(glx#^2+gly#^2+glz#^2)
g#=sqrt(gx#^2+gy#^2+gz#^2)
angle#=acos((glx#*gx#+gly#*gy#+glz#*gz#)/(l#*g#))
angle#=angle#-ang#
if flag=0 or (flag<0 and angle#<0) or (flag>0 and angle#>0)
crosspx#=(gly# * gz# - glz# * gy#)
crosspy#=(glz# * gx# - glx# * gz#)
crosspz#=(glx# * gy# - gly# * gx#)
rotate_axis(obj,crosspx#,crosspy#,crosspz#,angle#)
endif
endfunction
remstart Angle_Axes
This function rotates the object such that the given local axis has an angle
equal to the given angle with the global axis. The function will rotate no
more than the given maximum angle so that the alignment can be smoothed out
over multiple frames.
Param obj The object to rotate
Param lx#,ly#,lz# The local axis
Param gx#,gy#,gz# The global axis
Param ang# The given angle to keep between the local and global
axes. Flag also uses it to provide more functionality.
Param flag Used to decide when to perform the actual rotation
Param max_angle# The maximum angle by which the object may be rotated
Flag Usage:
If flag=0, the rotation will occur.
If flag<0, the rotation will occur if the angle between the axes is less
than the given angle.
If flag>0, the rotation will occur if the angle between the axes is
greater than the given angle.
remend
function Smooth_Angle_Axes(obj,lx#,ly#,lz#,gx#,gy#,gz#,ang#,flag,max_angle#)
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object right obj,lx#:move object up obj,ly#:move object obj,lz#
glx#=object position x(obj)-x#:gly#=object position y(obj)-y#:glz#=object position z(obj)-z#
move object right obj,-lx#:move object up obj,-ly#:move object obj,-lz#
l#=sqrt(glx#^2+gly#^2+glz#^2)
g#=sqrt(gx#^2+gy#^2+gz#^2)
angle#=acos((glx#*gx#+gly#*gy#+glz#*gz#)/(l#*g#))
angle#=angle#-ang#
if flag=0 or (flag<0 and angle#<0) or (flag>0 and angle#>0)
if angle#>max_angle#
angle#=max_angle#
endif
if angle#<-max_angle#
angle#=-max_angle#
endif
crosspx#=(gly# * gz# - glz# * gy#)
crosspy#=(glz# * gx# - glx# * gz#)
crosspz#=(glx# * gy# - gly# * gx#)
rotate_axis(obj,crosspx#,crosspy#,crosspz#,angle#)
endif
endfunction
function Axis_Angle_Y(obj,ayx#,ayy#,ayz#)
rem get normal vectors for X, Y, and Z axes of the object
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object right obj,1
xx#=object position x(obj)-x#:xy#=object position y(obj)-y#:xz#=object position z(obj)-z#
move object left obj,1:move object up obj,1
yx#=object position x(obj)-x#:yy#=object position y(obj)-y#:yz#=object position z(obj)-z#
move object down obj,1:move object obj,1
zx#=object position x(obj)-x#:zy#=object position y(obj)-y#:zz#=object position z(obj)-z#
move object obj,-1
rem rotate the vectors
rem 1) rotate space about the y axis so that the rotation axis lies along the yz plane
yangle#=-atanfull(ayx#,ayz#)
xx1#=xx#*cos(yangle#)+xz#*sin(yangle#)
xy1#=xy#
xz1#=xz#*cos(yangle#)-xx#*sin(yangle#)
zx1#=zx#*cos(yangle#)+zz#*sin(yangle#)
zy1#=zy#
zz1#=zz#*cos(yangle#)-zx#*sin(yangle#)
ayx1#=ayx#*cos(yangle#)+ayz#*sin(yangle#)
ayy1#=ayy#
ayz1#=ayz#*cos(yangle#)-ayx#*sin(yangle#)
rem 2) rotate space about the x axis so that the rotation axis lies in the z axis
xangle#=atanfull(ayy1#,ayz1#)
xx2#=xx1#
xy2#=xy1#*cos(xangle#)-xz1#*sin(xangle#)
xz2#=xz1#*cos(xangle#)+xy1#*sin(xangle#)
zx2#=zx1#
zy2#=zy1#*cos(xangle#)-zz1#*sin(xangle#)
zz2#=zz1#*cos(xangle#)+zy1#*sin(xangle#)
ayx2#=ayx1#
ayy2#=ayy1#*cos(xangle#)-ayz1#*sin(xangle#)
ayz2#=ayz1#*cos(xangle#)+ayy1#*sin(xangle#)
rem 3) perform the desired rotation by theta about the z axis
xx3#=xx2#*cos(amount#)-xy2#*sin(amount#)
xy3#=xy2#*cos(amount#)+xx2#*sin(amount#)
xz3#=xz2#
zx3#=zx2#*cos(amount#)-zy2#*sin(amount#)
zy3#=zy2#*cos(amount#)+zx2#*sin(amount#)
zz3#=zz2#
angle#=wrapvalue(atanfull(zx3#,-zy3#))
endfunction angle#
function Axis_Angle_X(obj,ayx#,ayy#,ayz#)
rem get normal vectors for X, Y, and Z axes of the object
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object right obj,1
xx#=object position x(obj)-x#:xy#=object position y(obj)-y#:xz#=object position z(obj)-z#
move object left obj,1:move object up obj,1
yx#=object position x(obj)-x#:yy#=object position y(obj)-y#:yz#=object position z(obj)-z#
move object down obj,1:move object obj,1
zx#=object position x(obj)-x#:zy#=object position y(obj)-y#:zz#=object position z(obj)-z#
move object obj,-1
rem rotate the vectors
rem 1) rotate space about the y axis so that the rotation axis lies along the yz plane
yangle#=-atanfull(ayx#,ayz#)
xx1#=xx#*cos(yangle#)+xz#*sin(yangle#)
xy1#=xy#
xz1#=xz#*cos(yangle#)-xx#*sin(yangle#)
zx1#=zx#*cos(yangle#)+zz#*sin(yangle#)
zy1#=zy#
zz1#=zz#*cos(yangle#)-zx#*sin(yangle#)
ayx1#=ayx#*cos(yangle#)+ayz#*sin(yangle#)
ayy1#=ayy#
ayz1#=ayz#*cos(yangle#)-ayx#*sin(yangle#)
rem 2) rotate space about the x axis so that the rotation axis lies in the z axis
xangle#=atanfull(ayy1#,ayz1#)
xx2#=xx1#
xy2#=xy1#*cos(xangle#)-xz1#*sin(xangle#)
xz2#=xz1#*cos(xangle#)+xy1#*sin(xangle#)
zx2#=zx1#
zy2#=zy1#*cos(xangle#)-zz1#*sin(xangle#)
zz2#=zz1#*cos(xangle#)+zy1#*sin(xangle#)
ayx2#=ayx1#
ayy2#=ayy1#*cos(xangle#)-ayz1#*sin(xangle#)
ayz2#=ayz1#*cos(xangle#)+ayy1#*sin(xangle#)
rem 3) perform the desired rotation by theta about the z axis
xx3#=xx2#*cos(amount#)-xy2#*sin(amount#)
xy3#=xy2#*cos(amount#)+xx2#*sin(amount#)
xz3#=xz2#
zx3#=zx2#*cos(amount#)-zy2#*sin(amount#)
zy3#=zy2#*cos(amount#)+zx2#*sin(amount#)
zz3#=zz2#
angle#=wrapvalue(-atanfull(zz3#,sqrt(zx3#^2+zy3#^2)))
endfunction angle#
function Axis_Angle_Z(obj,ayx#,ayy#,ayz#)
rem get normal vectors for X, Y, and Z axes of the object
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object right obj,1
xx#=object position x(obj)-x#:xy#=object position y(obj)-y#:xz#=object position z(obj)-z#
move object left obj,1:move object up obj,1
yx#=object position x(obj)-x#:yy#=object position y(obj)-y#:yz#=object position z(obj)-z#
move object down obj,1:move object obj,1
zx#=object position x(obj)-x#:zy#=object position y(obj)-y#:zz#=object position z(obj)-z#
move object obj,-1
rem rotate the vectors
rem 1) rotate space about the y axis so that the rotation axis lies along the yz plane
yangle#=-atanfull(ayx#,ayz#)
xx1#=xx#*cos(yangle#)+xz#*sin(yangle#)
xy1#=xy#
xz1#=xz#*cos(yangle#)-xx#*sin(yangle#)
zx1#=zx#*cos(yangle#)+zz#*sin(yangle#)
zy1#=zy#
zz1#=zz#*cos(yangle#)-zx#*sin(yangle#)
ayx1#=ayx#*cos(yangle#)+ayz#*sin(yangle#)
ayy1#=ayy#
ayz1#=ayz#*cos(yangle#)-ayx#*sin(yangle#)
rem 2) rotate space about the x axis so that the rotation axis lies in the z axis
xangle#=atanfull(ayy1#,ayz1#)
xx2#=xx1#
xy2#=xy1#*cos(xangle#)-xz1#*sin(xangle#)
xz2#=xz1#*cos(xangle#)+xy1#*sin(xangle#)
zx2#=zx1#
zy2#=zy1#*cos(xangle#)-zz1#*sin(xangle#)
zz2#=zz1#*cos(xangle#)+zy1#*sin(xangle#)
ayx2#=ayx1#
ayy2#=ayy1#*cos(xangle#)-ayz1#*sin(xangle#)
ayz2#=ayz1#*cos(xangle#)+ayy1#*sin(xangle#)
rem 1) rotate space about the z axis so that the rotation axis lies in the xz plane
zangle#=atanfull(zx2#,-zy2#)
xx3#=xx2#*cos(zangle#)+xy2#*sin(zangle#)
xy3#=xy2#*cos(zangle#)-xx2#*sin(zangle#)
xz3#=xz2#
zx3#=zx2#*cos(zangle#)+zy2#*sin(zangle#)
zy3#=zy2#*cos(zangle#)-zx2#*sin(zangle#)
zz3#=zz2#
rem 2) rotate space about the y axis so that the rotation axis lies along the z axis
xangle#=atanfull(zy3#,zz3#)
xx4#=xx3#
xy4#=xy3#*cos(xangle#)-xz3#*sin(xangle#)
xz4#=xz3#*cos(xangle#)+xy3#*sin(xangle#)
zx4#=zx3#
zy4#=zy3#*cos(xangle#)-zz3#*sin(xangle#)
zz4#=zz3#*cos(xangle#)+zy3#*sin(xangle#)
angle#=wrapvalue(atanfull(xy4#,xx4#))
endfunction angle#
function FindAxisAngleYtoPoint(obj,ayx#,ayy#,ayz#,px#,py#,pz#)
rem get normal vectors for X, Y, and Z axes of the object
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object right obj,1
xx#=object position x(obj)-x#:xy#=object position y(obj)-y#:xz#=object position z(obj)-z#
move object left obj,1:move object up obj,1
yx#=object position x(obj)-x#:yy#=object position y(obj)-y#:yz#=object position z(obj)-z#
move object down obj,1:move object obj,1
zx#=object position x(obj)-x#:zy#=object position y(obj)-y#:zz#=object position z(obj)-z#
move object obj,-1
dx#=px#-object position x(obj)
dy#=py#-object position y(obj)
dz#=pz#-object position z(obj)
rem rotate the vectors
rem 1) rotate space about the y axis so that the rotation axis lies along the yz plane
yangle#=-atanfull(ayx#,ayz#)
xx1#=xx#*cos(yangle#)+xz#*sin(yangle#)
xy1#=xy#
xz1#=xz#*cos(yangle#)-xx#*sin(yangle#)
zx1#=zx#*cos(yangle#)+zz#*sin(yangle#)
zy1#=zy#
zz1#=zz#*cos(yangle#)-zx#*sin(yangle#)
dx1#=dx#*cos(yangle#)+dz#*sin(yangle#)
dy1#=dy#
dz1#=dz#*cos(yangle#)-dx#*sin(yangle#)
ayx1#=ayx#*cos(yangle#)+ayz#*sin(yangle#)
ayy1#=ayy#
ayz1#=ayz#*cos(yangle#)-ayx#*sin(yangle#)
rem 2) rotate space about the x axis so that the rotation axis lies in the z axis
xangle#=atanfull(ayy1#,ayz1#)
xx2#=xx1#
xy2#=xy1#*cos(xangle#)-xz1#*sin(xangle#)
xz2#=xz1#*cos(xangle#)+xy1#*sin(xangle#)
zx2#=zx1#
zy2#=zy1#*cos(xangle#)-zz1#*sin(xangle#)
zz2#=zz1#*cos(xangle#)+zy1#*sin(xangle#)
dx2#=dx1#
dy2#=dy1#*cos(xangle#)-dz1#*sin(xangle#)
dz2#=dz1#*cos(xangle#)+dy1#*sin(xangle#)
ayx2#=ayx1#
ayy2#=ayy1#*cos(xangle#)-ayz1#*sin(xangle#)
ayz2#=ayz1#*cos(xangle#)+ayy1#*sin(xangle#)
angle#=wrapvalue(atanfull(dx2#,-dy2#))
endfunction angle#
function FindAxisAngleXtoPoint(obj,ayx#,ayy#,ayz#,px#,py#,pz#)
rem get normal vectors for X, Y, and Z axes of the object
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object right obj,1
xx#=object position x(obj)-x#:xy#=object position y(obj)-y#:xz#=object position z(obj)-z#
move object left obj,1:move object up obj,1
yx#=object position x(obj)-x#:yy#=object position y(obj)-y#:yz#=object position z(obj)-z#
move object down obj,1:move object obj,1
zx#=object position x(obj)-x#:zy#=object position y(obj)-y#:zz#=object position z(obj)-z#
move object obj,-1
dx#=px#-object position x(obj)
dy#=py#-object position y(obj)
dz#=pz#-object position z(obj)
rem rotate the vectors
rem 1) rotate space about the y axis so that the rotation axis lies along the yz plane
yangle#=-atanfull(ayx#,ayz#)
xx1#=xx#*cos(yangle#)+xz#*sin(yangle#)
xy1#=xy#
xz1#=xz#*cos(yangle#)-xx#*sin(yangle#)
zx1#=zx#*cos(yangle#)+zz#*sin(yangle#)
zy1#=zy#
zz1#=zz#*cos(yangle#)-zx#*sin(yangle#)
dx1#=dx#*cos(yangle#)+dz#*sin(yangle#)
dy1#=dy#
dz1#=dz#*cos(yangle#)-dx#*sin(yangle#)
ayx1#=ayx#*cos(yangle#)+ayz#*sin(yangle#)
ayy1#=ayy#
ayz1#=ayz#*cos(yangle#)-ayx#*sin(yangle#)
rem 2) rotate space about the x axis so that the rotation axis lies in the z axis
xangle#=atanfull(ayy1#,ayz1#)
xx2#=xx1#
xy2#=xy1#*cos(xangle#)-xz1#*sin(xangle#)
xz2#=xz1#*cos(xangle#)+xy1#*sin(xangle#)
zx2#=zx1#
zy2#=zy1#*cos(xangle#)-zz1#*sin(xangle#)
zz2#=zz1#*cos(xangle#)+zy1#*sin(xangle#)
dx2#=dx1#
dy2#=dy1#*cos(xangle#)-dz1#*sin(xangle#)
dz2#=dz1#*cos(xangle#)+dy1#*sin(xangle#)
ayx2#=ayx1#
ayy2#=ayy1#*cos(xangle#)-ayz1#*sin(xangle#)
ayz2#=ayz1#*cos(xangle#)+ayy1#*sin(xangle#)
angle#=wrapvalue(atanfull(-dz2#,sqrt(dx2#^2+dy2#^2)))
endfunction angle#
function RotateAxisAngleY(obj,ax#,ay#,az#,amount#)
rotate_axis(obj,ax#,ay#,az#,amount#-Axis_Angle_Y(obj,ax#,ay#,az#))
endfunction
function RotateAxisAngleX(obj,ax#,ay#,az#,amount#)
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object obj,1
zx#=object position x(obj)-x#:zy#=object position y(obj)-y#:zz#=object position z(obj)-z#
move object obj,-1
crosspx#=(ay# * zz# - az# * zy#)
crosspy#=(az# * zx# - ax# * zz#)
crosspz#=(ax# * zy# - ay# * zx#)
rotate_axis(obj,crosspx#,crosspy#,crosspz#,amount#-Axis_Angle_X(obj,ax#,ay#,az#))
endfunction
function RotateAxisAngleZ(obj,ax#,ay#,az#,amount#)
Rotate_LZ(obj,amount#-Axis_Angle_Z(obj,ax#,ay#,az#))
endfunction
function Orbit(obj,px#,py#,pz#,ax#,ay#,az#,amount#)
dx#=object position x(obj)-px#
dy#=object position y(obj)-py#
dz#=object position z(obj)-pz#
rem get normal vectors for X, Y, and Z axes of the object
x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
move object right obj,1
xx#=object position x(obj)-x#:xy#=object position y(obj)-y#:xz#=object position z(obj)-z#
move object left obj,1:move object up obj,1
yx#=object position x(obj)-x#:yy#=object position y(obj)-y#:yz#=object position z(obj)-z#
move object down obj,1:move object obj,1
zx#=object position x(obj)-x#:zy#=object position y(obj)-y#:zz#=object position z(obj)-z#
move object obj,-1
rem rotate the vectors
rem 1) rotate space about the x axis so that the rotation axis lies in the xz plane
xangle#=atanfull(ay#,az#)
xx1#=xx#
xy1#=xy#*cos(xangle#)-xz#*sin(xangle#)
xz1#=xz#*cos(xangle#)+xy#*sin(xangle#)
zx1#=zx#
zy1#=zy#*cos(xangle#)-zz#*sin(xangle#)
zz1#=zz#*cos(xangle#)+zy#*sin(xangle#)
dx1#=dx#
dy1#=dy#*cos(xangle#)-dz#*sin(xangle#)
dz1#=dz#*cos(xangle#)+dy#*sin(xangle#)
ax1#=ax#
ay1#=ay#*cos(xangle#)-az#*sin(xangle#)
az1#=az#*cos(xangle#)+ay#*sin(xangle#)
rem 2) rotate space about the y axis so that the rotation axis lies along the z axis
yangle#=-atanfull(ax1#,az1#)
xx2#=xx1#*cos(yangle#)+xz1#*sin(yangle#)
xy2#=xy1#
xz2#=xz1#*cos(yangle#)-xx1#*sin(yangle#)
zx2#=zx1#*cos(yangle#)+zz1#*sin(yangle#)
zy2#=zy1#
zz2#=zz1#*cos(yangle#)-zx1#*sin(yangle#)
dx2#=dx1#*cos(yangle#)+dz1#*sin(yangle#)
dy2#=dy1#
dz2#=dz1#*cos(yangle#)-dx1#*sin(yangle#)
ax2#=ax1#*cos(yangle#)+az1#*sin(yangle#)
ay2#=ay1#
az2#=az1#*cos(yangle#)-ax1#*sin(yangle#)
rem 3) perform the desired rotation by theta about the z axis
xx3#=xx2#*cos(amount#)-xy2#*sin(amount#)
xy3#=xy2#*cos(amount#)+xx2#*sin(amount#)
xz3#=xz2#
zx3#=zx2#*cos(amount#)-zy2#*sin(amount#)
zy3#=zy2#*cos(amount#)+zx2#*sin(amount#)
zz3#=zz2#
dx3#=dx2#*cos(amount#)-dy2#*sin(amount#)
dy3#=dy2#*cos(amount#)+dx2#*sin(amount#)
dz3#=dz2#
rem 4) Inverse of step 2
xx4#=xx3#*cos(-yangle#)+xz3#*sin(-yangle#)
xy4#=xy3#
xz4#=xz3#*cos(-yangle#)-xx3#*sin(-yangle#)
zx4#=zx3#*cos(-yangle#)+zz3#*sin(-yangle#)
zy4#=zy3#
zz4#=zz3#*cos(-yangle#)-zx3#*sin(-yangle#)
dx4#=dx3#*cos(-yangle#)+dz3#*sin(-yangle#)
dy4#=dy3#
dz4#=dz3#*cos(-yangle#)-dx3#*sin(-yangle#)
rem 5) Inverse of step 1
xx1#=xx4#
xy1#=xy4#*cos(-xangle#)-xz4#*sin(-xangle#)
xz1#=xz4#*cos(-xangle#)+xy4#*sin(-xangle#)
zx1#=zx4#
zy1#=zy4#*cos(-xangle#)-zz4#*sin(-xangle#)
zz1#=zz4#*cos(-xangle#)+zy4#*sin(-xangle#)
ndx#=dx4#
ndy#=dy4#*cos(-xangle#)-dz4#*sin(-xangle#)
ndz#=dz4#*cos(-xangle#)+dy4#*sin(-xangle#)
position object obj,px#+ndx#,py#+ndy#,pz#+ndz#
rem calculate angle z
zr#=atanfull(xy1#,xx1#)
rem calculate angle y
xx2#=xx1#*cos(zr#)+xy1#*sin(zr#)
xy2#=xy1#*cos(zr#)-xx1#*sin(zr#)
xz2#=xz1#
zx2#=zx1#*cos(zr#)+zy1#*sin(zr#)
zy2#=zy1#*cos(zr#)-zx1#*sin(zr#)
zz2#=zz1#
yr#=atanfull(xx2#,xz2#)-90
rem calculate angle x
zx3#=zx2#*cos(yr#+90)-zz2#*sin(yr#+90)
zy3#=zy2#
xr#=atanfull(zy3#,zx3#)+180
if xr#+1>xr# and yr#+1>yr# and zr#+1>zr#
rotate object obj,xr#,yr#,zr#
endif
endfunction
There's a turret on each face of both cubes. Screen shot:
You can see that the turrets mounted on each face of the cubes are pointing at the ship (box) in the center of the screen.
Even though the turrets are on every face of both cube and the cubes are rotated at random angles, the code that controls each turret is simply this:
targ_y#=FindAxisAngleYtoPoint(turret(t).base,turret(t).ax,turret(t).ay,turret(t).az,tx#,ty#,tz#)
RotateAxisAngleY(turret(t).base,turret(t).ax,turret(t).ay,turret(t).az,curveangle(targ_y#,Axis_Angle_Y(turret(t).base,turret(t).ax,turret(t).ay,turret(t).az),20))
RotateAxisAngleY(turret(t).barrel,turret(t).ax,turret(t).ay,turret(t).az,Axis_Angle_Y(turret(t).base,turret(t).ax,turret(t).ay,turret(t).az))
targ_x#=FindAxisAngleXtoPoint(turret(t).barrel,turret(t).ax,turret(t).ay,turret(t).az,tx#,ty#,tz#)
if targ_x#<180 then targ_x#=0
if targ_x#>180 and targ_x#<270 then targ_x#=270
RotateAxisAngleX(turret(t).barrel,turret(t).ax,turret(t).ay,turret(t).az,curveangle(targ_x#,Axis_Angle_X(turret(t).barrel,turret(t).ax,turret(t).ay,turret(t).az),20))
RotateAxisAngleX(turret(t).base,turret(t).ax,turret(t).ay,turret(t).az,0)
RotateAxisAngleZ(turret(t).base,turret(t).ax,turret(t).ay,turret(t).az,0)
az#=Axis_Angle_Z(turret(t).barrel,turret(t).ax,turret(t).ay,turret(t).az)
if az#>180 then az#=az#-360
if (tx#-object position x(turret(t).base))^2+(ty#-object position y(turret(t).base))^2+(tz#-object position z(turret(t).base))^2<40^2
turret(t).rollspeed=turret(t).rollspeed+0.5
turret(t).rollspeed=(turret(t).rollspeed)*0.9
else
turret(t).rollspeed=(turret(t).rollspeed-az#*0.001)*0.9
endif
rotate_LZ(turret(t).barrel,turret(t).rollspeed)
Here's what each part does:
The first line, "targ_y#=FindAxisAngleYtoPoint(turret(t).base,turret(t).ax,turret(t).ay,turret(t).az,tx#,ty#,tz#)", finds the local Y angle to the point based on the Axis-Angle system. Each turret has it's own ax,ay,az, which is the "up" direction. Each face of a cube has a different up direction, so this is set when the turret is created.
The next two lines rotate the base of the turret and the barrel to this angle using the RotateAxisAngleY() function.
The next line, "targ_x#=FindAxisAngleXtoPoint(turret(t).barrel,turret(t).ax,turret(t).ay,turret(t).az,tx#,ty#,tz#)", finds the X angle to the target, again based on the Axis-Angle system.
After that, "if targ_x#<180 then targ_x#=0" and "if targ_x#<270 and targ_x#>180 then targ_x#=270" limit the rotation to make sure it can only be between 360 and 270 degrees (so it can't point down relative to the way it is mounted).
"RotateAxisAngleX(turret(t).barrel,turret(t).ax,turret(t).ay,turret(t).az,curveangle(targ_x#,Axis_Angle_X(turret(t).barrel,turret(t).ax,turret(t).ay,turret(t).az),20))" rotates the barrel so it has the right pitch.
A few other lines are called to make sure the base of the turret has no x or z angle relative to the up direction. Also, some code makes the barrel roll when the ship gets close, like a shooting animation of some sort. Also, when you get to far away the barrel will stop rolling and will return to a relative Z angle of 0 in the Axis-Angle system.
Edit:Updated first post with new rotation functions