I have updated the first post with the concept.
The clearest code for the 3d visualisation can be found here:
// Project: AA 3d Visualisation
// Created: 2015-12-07
// set window properties
SetWindowTitle( "AA 3d Visualisation" )
SetWindowSize( 1920, 1080, 0 )
// set display properties
SetVirtualResolution( 1920, 1080 )
SetOrientationAllowed( 0, 0, 1, 0 )
// activate different sensors
show_accel=1
show_gyro=1
show_magnetic=1
show_custom=1
show_rotation1=1
show_rotation2=1
// create a hollow cube as graph-space
create_hollow_cube(0,0,0,100,100,100)
// create graph media
origin=CreateObjectBox(1,1,1)
accel=CreateObjectBox(1,1,1)
SetObjectColor(accel,255,0,0,0)
magneto=CreateObjectBox(1,1,1)
SetObjectColor(magneto,0,255,0,0)
gyro=CreateObjectBox(1,1,1)
SetObjectColor(gyro,0,0,255,0)
rotation=CreateObjectBox(1,1,1)
SetObjectColor(rotation,255,255,0,0)
rotation2=CreateObjectBox(1,1,1)
SetObjectColor(rotation2,255,0,255,0)
custom=CreateObjectBox(1,1,1)
SetObjectColor(custom,0,255,255,0)
target=CreateObjectBox(4,4,4)
SetObjectColor(target,0,0,255,0)
// buttons
create_button(1,"left",200,1080-60)
create_button(2,"right",360,1080-60)
create_button(3,"+",200+400,1080-60)
create_button(4,"-",360+400,1080-60)
create_button(5,"calib",1800,1080-60)
// display text
if show_accel=1
x=0 : y=0
create_text(1,0+x,0+y,"Raw Acceleration",50,255,0,0,0)
create_text(2,20+x,40+y+20,"X: 0.0",40,255,255,255,0)
create_text(3,20+x,80+y+20,"Y: 0.0",40,255,255,255,0)
create_text(4,20+x,120+y+20,"Z: 0.0",40,255,255,255,0)
endif
if show_magnetic=1
x=600 : y=0
create_text(5,0+x,0+y,"Magnetic",50,0,255,0,0)
create_text(6,20+x,40+y+20,"X: 0.0",40,255,255,255,0)
create_text(7,20+x,80+y+20,"Y: 0.0",40,255,255,255,0)
create_text(8,20+x,120+y+20,"Z: 0.0",40,255,255,255,0)
endif
if show_gyro=1
x=1200 : y=0
create_text(9,0+x,0+y,"Gyro",50,0,0,255,0)
create_text(10,20+x,40+y+20,"X: 0.0",40,255,255,255,0)
create_text(11,20+x,80+y+20,"Y: 0.0",40,255,255,255,0)
create_text(12,20+x,120+y+20,"Z: 0.0",40,255,255,255,0)
endif
create_text(13,0,0+180*4+40,"Estimated angle between"+chr(10)+"magnetic and acceleration:",40,255,255,255,0)
create_text(14,20,80+180*4+40,"Angle: 0.0",40,255,255,255,0)
create_text(15,1920/2+70,1035,"calibrate on a flat surface",40,255,255,255,0)
if show_rotation1=1
x=0 : y=400
create_text(16,0+x,0+y,"Fused Rotation 1",50,255,255,0,0)
create_text(17,20+x,40+y+20,"X: 0.0",40,255,255,255,0)
create_text(18,20+x,80+y+20,"Y: 0.0",40,255,255,255,0)
create_text(19,20+x,120+y+20,"Z: 0.0",40,255,255,255,0)
endif
if show_rotation2=1
x=1300 : y=400
create_text(20,0+x,0+y,"Fused Rotation 2",50,255,0,255,0)
create_text(21,20+x,40+y+20,"X: 0.0",40,255,255,255,0)
create_text(22,20+x,80+y+20,"Y: 0.0",40,255,255,255,0)
create_text(23,20+x,120+y+20,"Z: 0.0",40,255,255,255,0)
endif
if show_custom=1
x=1300 : y=700
create_text(24,0+x,0+y,"Custom",50,0,255,255,0)
create_text(25,20+x,40+y+20,"X: 0.0",40,255,255,255,0)
create_text(26,20+x,80+y+20,"Y: 0.0",40,255,255,255,0)
create_text(27,20+x,120+y+20,"Z: 0.0",40,255,255,255,0)
endif
// camera initial radius
r#=300
do
// handle buttons
if GetButtonstate(1)=1 then x#=x#-0.6
if GetButtonstate(2)=1 then x#=x#+0.6
if GetButtonstate(3)=1 then r#=r#-0.6
if GetButtonstate(4)=1 then r#=r#+0.6
// reset values
if GetButtonpressed(5)=1
addx# = GetObjectAngleX(magneto)
addy# = GetObjectAngleY(magneto)
addz# = GetObjectAngleZ(magneto)
ox4#=0
oy4#=0
oz4#=0
movx#=GetRawMagneticX()
movy#=GetRawMagneticY()
movz#=GetRawMagneticZ()+50
SetObjectRotation(magneto,GetObjectAngleX(magneto)*-1,GetObjectAngleY(magneto),GetObjectAngleZ(magneto))
lox8#=-GetObjectAngleX(rotation)
loy8#=-GetObjectAngleY(rotation)
loz8#=-GetObjectAngleZ(rotation)
endif
// fused rotation 1
if show_rotation1=1
ox8#=GetRawRotationVectorX()
oy8#=GetRawRotationVectorY()
oz8#=GetRawRotationVectorZ()
ow8#=GetRawRotationVectorW()
SetObjectPosition(rotation,0,0,0)
size#=sqrt(ox8#^2+oy8#^2+oz8#^2)
size#=50
SetObjectScale(rotation,1,1,size#)
//SetObjectLookAt(rotation,ox8#*2,oy8#,oz8#,0)
SetObjectRotationQuat(rotation,ow8#,ox8#,oy8#,oz8#)
// RotateObjectGlobalX( rotation,180)
RotateObjectGlobalZ( rotation,180)
//SetObjectRotation(rotation,GetObjectAngleX(rotation),GetObjectAngleY(rotation),GetObjectAngleZ(rotation))
MoveObjectLocalZ(rotation,size#/2)
settextstring(17,"X: "+str(ox8#))
settextstring(18,"Y: "+str(oy8#))
settextstring(19,"Z: "+str(oz8#))
endif
// fused rotation 2
if show_rotation2=1
ox9#=GetRawRotationVectorX2()
oy9#=GetRawRotationVectorY2()
oz9#=GetRawRotationVectorZ2()
ow9#=GetRawRotationVectorW2()
SetObjectPosition(rotation2,0,0,0)
size#=sqrt(ox9#^2+oy9#^2+oz9#^2)
size#=50
SetObjectScale(rotation2,1,1,size#)
//SetObjectLookAt(rotation,ox8#*2,oy8#,oz8#,0)
SetObjectRotationQuat(rotation2,ow9#,ox9#,oy9#,oz9#)
// RotateObjectGlobalX( rotation2,180)
MoveObjectLocalZ(rotation2,size#/2)
settextstring(21,"X: "+str(ox9#))
settextstring(22,"Y: "+str(oy9#))
settextstring(23,"Z: "+str(oz9#))
endif
// custom
if show_custom=1
ox9#=0
oy9#=0
oz9#=0
SetObjectPosition(custom,0,0,0)
size#=sqrt(ox9#^2+oy9#^2+oz9#^2)
size#=50
SetObjectScale(custom,1,1,size#)
//SetObjectLookAt(rotation,ox8#*2,oy8#,oz8#,0)
// SetObjectRotationQuat(rotation,ow8#,ox8#,oy8#,oz8#)
SetObjectRotation(custom,ox9#,oy9#,oz9#)
RotateObjectGlobalX(custom,180)
// RotateObjectGlobalX( rotation,90)
MoveObjectLocalZ(custom,size#/2)
settextstring(25,"X: "+str(ox9#))
settextstring(26,"Y: "+str(oy9#))
settextstring(27,"Z: "+str(oz9#))
endif
// magnetic
if show_magnetic=1
ox2#=GetRawMagneticX()
oy2#=GetRawMagneticY()
oz2#=GetRawMagneticZ()
settextstring(6,"X: "+str(ox2#))
settextstring(7,"Y: "+str(oy2#))
settextstring(8,"Z: "+str(oz2#))
SetObjectPosition(magneto,0,0,0)
size#=sqrt(ox2#^2+oy2#^2+oz2#^2)
SetObjectScale(magneto,1,1,size#)
SetObjectLookAt(magneto,ox2#,oy2#,oz2#,0)
// SetObjectRotation(magneto,GetObjectAngleX(magneto),GetObjectAngleY(magneto),GetObjectAngleZ(magneto))
addx#=60
MoveObjectLocalZ(magneto,size#/2)
endif
// accel
if show_accel=1
ox#=-GetRawAccelX()*50
oy#=-GetRawAccelY()*50
oz#=-GetRawAccelZ()*50
settextstring(2,"X: "+str(ox#))
settextstring(3,"Y: "+str(oy#))
settextstring(4,"Z: "+str(oz#))
SetObjectPosition(accel,0,0,0)
size#=sqrt(ox#^2+oy#^2+oz#^2)
SetObjectScale(accel,1,1,size#)
SetObjectLookAt(accel,ox#,oy#,oz#,0)
MoveObjectLocalZ(accel,size#/2)
SetObjectPosition(target,ox#,oy#,oz#)
endif
// angle between (does not work quite well :/)
ang#=vector_angle(ox#,oy#,oz#,ox9#,oy9#,oz9#)
settextstring(14,"Angle: "+str(ang#))
// gyro
if show_gyro=1
ox3# = (GetRawGyroVelocityX())
oy3# = (GetRawGyroVelocityY())
oz3# = (GetRawGyroVelocityZ())
ox4#=ox4#+(ox3#+lox3#)/2
oy4#=oy4#+(oy3#+loy3#)/2
oz4#=oz4#+(oz3#+loz3#)/2
lox3# = (GetRawGyroVelocityX())
loy3# = (GetRawGyroVelocityY())
loz3# = (GetRawGyroVelocityZ())
settextstring(10,"X: "+str(ox4#))
settextstring(11,"Y: "+str(oy4#))
settextstring(12,"Z: "+str(oz4#))
SetObjectPosition(gyro,0,0,0)
size#=sqrt(ox4#^2+oy4#^2+oz4#^2)
size#=50.0
SetObjectScale(gyro,1,1,size#)
// SetObjectLookAt(gyro,ox4#,oy4#,oz4#,0)
SetObjectRotation(gyro,-ox4#,-oy4#,0)
RotateObjectGlobalX( gyro,180)
MoveObjectLocalZ(gyro,-size#/2)
endif
// control camera rotation
SetCameraPosition(1,sin(x#)*r#,70,cos(x#)*r#)
SetCameraLookAt(1,0,0,0,0)
Sync()
loop
function create_hollow_cube(px#,py#,pz#,sx#,sy#,sz#)
strength#=1.0
// create floor
o=CreateObjectBox(sx#,strength#,strength#)
SetObjectPosition(o,px#,py#-sy#/2,pz#-sz#/2)
o=CreateObjectBox(sx#,strength#,strength#)
SetObjectPosition(o,px#,py#-sy#/2,pz#+sz#/2)
o=CreateObjectBox(strength#,strength#,sz#)
SetObjectPosition(o,px#-sx#/2,py#-sy#/2,pz#)
o=CreateObjectBox(strength#,strength#,sz#)
SetObjectPosition(o,px#+sx#/2,py#-sy#/2,pz#)
// create top
o=CreateObjectBox(sx#,strength#,strength#)
SetObjectPosition(o,px#,py#+sy#/2,pz#-sz#/2)
o=CreateObjectBox(sx#,strength#,strength#)
SetObjectPosition(o,px#,py#+sy#/2,pz#+sz#/2)
o=CreateObjectBox(strength#,strength#,sz#)
SetObjectPosition(o,px#-sx#/2,py#+sy#/2,pz#)
o=CreateObjectBox(strength#,strength#,sz#)
SetObjectPosition(o,px#+sx#/2,py#+sy#/2,pz#)
// create connections
o=CreateObjectBox(strength#,sy#,strength#)
SetObjectPosition(o,px#-sx#/2,py#,pz#-sz#/2)
o=CreateObjectBox(strength#,sy#,strength#)
SetObjectPosition(o,px#+sx#/2,py#,pz#+sz#/2)
o=CreateObjectBox(strength#,sy#,strength#)
SetObjectPosition(o,px#+sx#/2,py#,pz#-sz#/2)
o=CreateObjectBox(strength#,sy#,strength#)
SetObjectPosition(o,px#-sx#/2,py#,pz#+sz#/2)
endfunction
function create_button(button,txt$,x,y)
if button=0
repeat
inc button
until GetVirtualButtonExists(button)=0
endif
AddVirtualButton(button,20,20,20)
SetVirtualButtonAlpha(button,192)
SetVirtualButtonColor(button,255,255,0)
SetVirtualButtonPosition(button,x,y)
SetVirtualButtonSize(button,120)
SetVirtualButtonText(button,txt$)
SetVirtualButtonVisible(button,1)
endfunction button
function vector_angle(abx#,aby#,abz#,adx#,ady#,adz#)
va#=sqrt(abx#^2+aby#^2)
vb#=sqrt(adx#^2+ady#^2)
// vc#=sqrt(adz#^2+adz#^2)
scal#=abx#*adx#+aby#*ady#
rad#=ACos(scal#/(va#*vb#))
endfunction rad#
function create_text(num,x,y,str$,size,r,g,b,alig)
CreateText(num,"")
settextstring(num,str$)
SetTextPosition(num,x,y)
settextsize(num,size)
SetTextColor(num,r,g,b,255)
SetTextAlignment(num,alig)
endfunction
The following code only uses two axis of the magnetic sensor to compare them with the fused orientation vector.
The interesting part is, that the magnetic sensor and orientation vector are the same once the device has a 90 degree angle to the ground.
Does the fused orientation (
GetRawRotationVector) use the magnetic sensor at least once? I think so.
x,z - Magnetic sensor:
// Project: AA 3d Visualisation
// Created: 2015-12-07
// set window properties
SetWindowTitle( "AA 3d Visualisation" )
SetWindowSize( 1920, 1080, 0 )
// set display properties
SetVirtualResolution( 1920, 1080 )
SetOrientationAllowed( 0, 0, 1, 0 )
// activate different sensors
show_accel=1
show_gyro=0
show_magnetic=1
show_custom=0
show_rotation1=0
show_rotation2=1
// create a hollow cube as graph-space
create_hollow_cube(0,0,0,100,100,100)
// create graph media
origin=CreateObjectBox(1,1,1)
accel=CreateObjectBox(1,1,1)
SetObjectColor(accel,255,0,0,0)
magneto=CreateObjectBox(1,1,1)
SetObjectColor(magneto,0,255,0,0)
gyro=CreateObjectBox(1,1,1)
SetObjectColor(gyro,0,0,255,0)
rotation=CreateObjectBox(1,1,1)
SetObjectColor(rotation,255,255,0,0)
rotation2=CreateObjectBox(1,1,1)
SetObjectColor(rotation2,255,0,255,0)
custom=CreateObjectBox(1,1,1)
SetObjectColor(custom,0,255,255,0)
target=CreateObjectBox(4,4,4)
SetObjectColor(target,0,0,255,0)
// buttons
create_button(1,"left",200,1080-60)
create_button(2,"right",360,1080-60)
create_button(3,"+",200+400,1080-60)
create_button(4,"-",360+400,1080-60)
create_button(5,"calib",1800,1080-60)
// display text
if show_accel=1
x=0 : y=0
create_text(1,0+x,0+y,"Raw Acceleration",50,255,0,0,0)
create_text(2,20+x,40+y+20,"X: 0.0",40,255,255,255,0)
create_text(3,20+x,80+y+20,"Y: 0.0",40,255,255,255,0)
create_text(4,20+x,120+y+20,"Z: 0.0",40,255,255,255,0)
endif
if show_magnetic=1
x=600 : y=0
create_text(5,0+x,0+y,"Magnetic",50,0,255,0,0)
create_text(6,20+x,40+y+20,"X: 0.0",40,255,255,255,0)
create_text(7,20+x,80+y+20,"Y: 0.0",40,255,255,255,0)
create_text(8,20+x,120+y+20,"Z: 0.0",40,255,255,255,0)
endif
if show_gyro=1
x=1200 : y=0
create_text(9,0+x,0+y,"Gyro",50,0,0,255,0)
create_text(10,20+x,40+y+20,"X: 0.0",40,255,255,255,0)
create_text(11,20+x,80+y+20,"Y: 0.0",40,255,255,255,0)
create_text(12,20+x,120+y+20,"Z: 0.0",40,255,255,255,0)
endif
create_text(13,0,0+180*4+40,"Estimated angle between"+chr(10)+"magnetic and acceleration:",40,255,255,255,0)
create_text(14,20,80+180*4+40,"Angle: 0.0",40,255,255,255,0)
create_text(15,1920/2+70,1035,"calibrate on a flat surface",40,255,255,255,0)
if show_rotation1=1
x=0 : y=400
create_text(16,0+x,0+y,"Fused Rotation 1",50,255,255,0,0)
create_text(17,20+x,40+y+20,"X: 0.0",40,255,255,255,0)
create_text(18,20+x,80+y+20,"Y: 0.0",40,255,255,255,0)
create_text(19,20+x,120+y+20,"Z: 0.0",40,255,255,255,0)
endif
if show_rotation2=1
x=1300 : y=400
create_text(20,0+x,0+y,"Fused Rotation 2",50,255,0,255,0)
create_text(21,20+x,40+y+20,"X: 0.0",40,255,255,255,0)
create_text(22,20+x,80+y+20,"Y: 0.0",40,255,255,255,0)
create_text(23,20+x,120+y+20,"Z: 0.0",40,255,255,255,0)
endif
if show_custom=1
x=1300 : y=700
create_text(24,0+x,0+y,"Custom",50,0,255,255,0)
create_text(25,20+x,40+y+20,"X: 0.0",40,255,255,255,0)
create_text(26,20+x,80+y+20,"Y: 0.0",40,255,255,255,0)
create_text(27,20+x,120+y+20,"Z: 0.0",40,255,255,255,0)
endif
// camera initial radius
r#=300
do
// handle buttons
if GetButtonstate(1)=1 then x#=x#-0.6
if GetButtonstate(2)=1 then x#=x#+0.6
if GetButtonstate(3)=1 then r#=r#-0.6
if GetButtonstate(4)=1 then r#=r#+0.6
// reset values
if GetButtonpressed(5)=1
addx# = GetObjectAngleX(magneto)
addy# = GetObjectAngleY(magneto)
addz# = GetObjectAngleZ(magneto)
ox4#=0
oy4#=0
oz4#=0
movx#=GetRawMagneticX()
movy#=GetRawMagneticY()
movz#=GetRawMagneticZ()+50
SetObjectRotation(magneto,GetObjectAngleX(magneto)*-1,GetObjectAngleY(magneto),GetObjectAngleZ(magneto))
lox8#=-GetObjectAngleX(rotation)
loy8#=-GetObjectAngleY(rotation)
loz8#=-GetObjectAngleZ(rotation)
endif
// fused rotation 1
if show_rotation1=1
ox8#=GetRawRotationVectorX()
oy8#=GetRawRotationVectorY()
oz8#=GetRawRotationVectorZ()
ow8#=GetRawRotationVectorW()
SetObjectPosition(rotation,0,0,0)
size#=sqrt(ox8#^2+oy8#^2+oz8#^2)
size#=50
SetObjectScale(rotation,1,1,size#)
//SetObjectLookAt(rotation,ox8#*2,oy8#,oz8#,0)
SetObjectRotationQuat(rotation,ow8#,ox8#,oy8#,oz8#)
// RotateObjectGlobalX( rotation,180)
RotateObjectGlobalZ( rotation,180)
//SetObjectRotation(rotation,GetObjectAngleX(rotation),GetObjectAngleY(rotation),GetObjectAngleZ(rotation))
MoveObjectLocalZ(rotation,size#/2)
settextstring(17,"X: "+str(ox8#))
settextstring(18,"Y: "+str(oy8#))
settextstring(19,"Z: "+str(oz8#))
endif
// fused rotation 2
if show_rotation2=1
ox9#=GetRawRotationVectorX2()
oy9#=GetRawRotationVectorY2()
oz9#=GetRawRotationVectorZ2()
ow9#=GetRawRotationVectorW2()
SetObjectPosition(rotation2,0,0,0)
size#=sqrt(ox9#^2+oy9#^2+oz9#^2)
size#=50
SetObjectScale(rotation2,1,1,size#)
//SetObjectLookAt(rotation,ox8#*2,oy8#,oz8#,0)
SetObjectRotationQuat(rotation2,ow9#,ox9#,oy9#,oz9#)
// RotateObjectGlobalX( rotation2,180)
MoveObjectLocalZ(rotation2,size#/2)
settextstring(21,"X: "+str(ox9#))
settextstring(22,"Y: "+str(oy9#))
settextstring(23,"Z: "+str(oz9#))
endif
// custom
if show_custom=1
ox9#=0
oy9#=0
oz9#=0
SetObjectPosition(custom,0,0,0)
size#=sqrt(ox9#^2+oy9#^2+oz9#^2)
size#=50
SetObjectScale(custom,1,1,size#)
//SetObjectLookAt(rotation,ox8#*2,oy8#,oz8#,0)
// SetObjectRotationQuat(rotation,ow8#,ox8#,oy8#,oz8#)
SetObjectRotation(custom,ox9#,oy9#,oz9#)
RotateObjectGlobalX(custom,180)
// RotateObjectGlobalX( rotation,90)
MoveObjectLocalZ(custom,size#/2)
settextstring(25,"X: "+str(ox9#))
settextstring(26,"Y: "+str(oy9#))
settextstring(27,"Z: "+str(oz9#))
endif
// accel
if show_accel=1
ox#=GetRawAccelX()*50
oz#=GetRawAccelY()*50
oy#=-GetRawAccelZ()*50
settextstring(2,"X: "+str(ox#))
settextstring(3,"Y: "+str(oy#))
settextstring(4,"Z: "+str(oz#))
SetObjectPosition(accel,0,0,0)
size#=sqrt(ox#^2+oy#^2+oz#^2)
SetObjectScale(accel,1,1,size#)
SetObjectLookAt(accel,ox#,oy#,oz#,0)
MoveObjectLocalZ(accel,size#/2)
SetObjectPosition(target,ox#,oy#,oz#)
endif
// magnetic
if show_magnetic=1
oy2#=0 // -GetRawMagneticX()
ox2#=GetRawMagneticY()
oz2#=-GetRawMagneticZ()
settextstring(6,"X: "+str(ox2#))
settextstring(7,"Y: "+str(oy2#))
settextstring(8,"Z: "+str(oz2#))
SetObjectPosition(magneto,0,0,0)
size#=sqrt(ox2#^2+oy2#^2+oz2#^2)
SetObjectScale(magneto,1,1,size#)
SetObjectLookAt(magneto,ox2#,oy2#,oz2#,1)
// bSetObjectRotation(magneto,GetObjectAngleX(accel),GetObjectAngleY(magneto),GetObjectAngleZ(magneto))
// RotateObjectGlobalX( magneto,180)
MoveObjectLocalZ(magneto,size#/2)
endif
// angle between (does not work quite well :/)
ang#=vector_angle(ox#,oy#,oz#,ox9#,oy9#,oz9#)
settextstring(14,"Angle: "+str(ang#))
// gyro
if show_gyro=1
ox3# = (GetRawGyroVelocityX())
oy3# = (GetRawGyroVelocityY())
oz3# = (GetRawGyroVelocityZ())
ox4#=ox4#+ox3#
oy4#=oy4#+oy3#
oz4#=oz4#+oz3#
lox3# = (GetRawGyroVelocityX())
loy3# = (GetRawGyroVelocityY())
loz3# = (GetRawGyroVelocityZ())
settextstring(10,"X: "+str(ox4#))
settextstring(11,"Y: "+str(oy4#))
settextstring(12,"Z: "+str(oz4#))
SetObjectPosition(gyro,0,0,0)
size#=sqrt(ox4#^2+oy4#^2+oz4#^2)
size#=50.0
SetObjectScale(gyro,1,1,size#)
// SetObjectLookAt(gyro,ox4#,oy4#,oz4#,0)
SetObjectRotation(gyro,-ox4#,-oy4#,0)
RotateObjectGlobalX( gyro,-90)
// RotateObjectGlobalY( gyro,-oy4#)
MoveObjectLocalZ(gyro,-size#/2)
endif
// control camera rotation
SetCameraPosition(1,sin(x#)*r#,70,cos(x#)*r#)
SetCameraLookAt(1,0,0,0,0)
Sync()
loop
function create_hollow_cube(px#,py#,pz#,sx#,sy#,sz#)
strength#=1.0
// create floor
o=CreateObjectBox(sx#,strength#,strength#)
SetObjectPosition(o,px#,py#-sy#/2,pz#-sz#/2)
o=CreateObjectBox(sx#,strength#,strength#)
SetObjectPosition(o,px#,py#-sy#/2,pz#+sz#/2)
o=CreateObjectBox(strength#,strength#,sz#)
SetObjectPosition(o,px#-sx#/2,py#-sy#/2,pz#)
o=CreateObjectBox(strength#,strength#,sz#)
SetObjectPosition(o,px#+sx#/2,py#-sy#/2,pz#)
// create top
o=CreateObjectBox(sx#,strength#,strength#)
SetObjectPosition(o,px#,py#+sy#/2,pz#-sz#/2)
o=CreateObjectBox(sx#,strength#,strength#)
SetObjectPosition(o,px#,py#+sy#/2,pz#+sz#/2)
o=CreateObjectBox(strength#,strength#,sz#)
SetObjectPosition(o,px#-sx#/2,py#+sy#/2,pz#)
o=CreateObjectBox(strength#,strength#,sz#)
SetObjectPosition(o,px#+sx#/2,py#+sy#/2,pz#)
// create connections
o=CreateObjectBox(strength#,sy#,strength#)
SetObjectPosition(o,px#-sx#/2,py#,pz#-sz#/2)
o=CreateObjectBox(strength#,sy#,strength#)
SetObjectPosition(o,px#+sx#/2,py#,pz#+sz#/2)
o=CreateObjectBox(strength#,sy#,strength#)
SetObjectPosition(o,px#+sx#/2,py#,pz#-sz#/2)
o=CreateObjectBox(strength#,sy#,strength#)
SetObjectPosition(o,px#-sx#/2,py#,pz#+sz#/2)
endfunction
function create_button(button,txt$,x,y)
if button=0
repeat
inc button
until GetVirtualButtonExists(button)=0
endif
AddVirtualButton(button,20,20,20)
SetVirtualButtonAlpha(button,192)
SetVirtualButtonColor(button,255,255,0)
SetVirtualButtonPosition(button,x,y)
SetVirtualButtonSize(button,120)
SetVirtualButtonText(button,txt$)
SetVirtualButtonVisible(button,1)
endfunction button
function vector_angle(abx#,aby#,abz#,adx#,ady#,adz#)
va#=sqrt(abx#^2+aby#^2)
vb#=sqrt(adx#^2+ady#^2)
// vc#=sqrt(adz#^2+adz#^2)
scal#=abx#*adx#+aby#*ady#
rad#=ACos(scal#/(va#*vb#))
endfunction rad#
function create_text(num,x,y,str$,size,r,g,b,alig)
CreateText(num,"")
settextstring(num,str$)
SetTextPosition(num,x,y)
settextsize(num,size)
SetTextColor(num,r,g,b,255)
SetTextAlignment(num,alig)
endfunction