Ric, that snippet is really really, cool.
Anyway, here's my final entry. There's still a few bugs with the torque, but it looks right most of the time. Friction should work ok, and I also added some motion blur. Code:
ROWS=3
COLS=3
rem rigid body amount = ROWS * COLS
sync on
sync rate 0
cls
set display mode 1024,768,32
autocam off
position camera 0,0,-100
set camera range 50,150
rotate camera 0,0,0
color backdrop 0
global max_body_amount=100
global max_vertex_amount=20
global max_collision_data_amount=100
global max_material_amount=20
type xy
x as float
y as float
endtype
type xyw
x as float
y as float
w as float
endtype
type body_type
p as xyw
avgv as xyw
v as xyw
force as xyw
avgforce as xyw
impulse as xyw
mass as float
moi as float
vertex_amount
push as xyw
exist as boolean
gravity as boolean
active as boolean
autofreeze as boolean
object
lin_damp as float
ang_damp as float
collision_radius as float
material
endtype
type collision_data_type
vertex_amount
exist as boolean
endtype
type world_type
min as xy
max as xy
onexit
standard_gravity as xy
endtype
type collision_type
pt as xy
n as xy
distance as float
edge1
edge2
edge_length1 as float
edge_length2 as float
exist1 as boolean
exist2 as boolean
endtype
type rbd_type
world as world_type
last_time
collision as collision_type
endtype
type material_type
sfriction as float
kfriction as float
elasticity as float
collidable as boolean
endtype
dim body(max_body_amount) as body_type
dim bodycontact(max_body_amount,max_body_amount)
dim body_shape(max_body_amount,max_vertex_amount) as xy
dim collision_data(max_collision_data_amount+2) as collision_data_type
dim collision_data_v(max_collision_data_amount,max_vertex_amount) as xy
dim material(max_material_amount,max_material_amount) as material_type
dim groupid(max_material_amount)
global RBD as rbd_type
global RBD_V1=1
global RBD_V2=2
global RBD_V3=3
global RBD_V4=4
global RBD_V5=5
global RBD_V6=6
type debug_type
torque as boolean
force as boolean
collision as boolean
velocity as boolean
endtype
global debug as debug_type
n=make vector2(RBD_V1)
n=make vector2(RBD_V2)
n=make vector2(RBD_V3)
n=make vector2(RBD_V4)
n=make vector2(RBD_V5)
n=make vector2(RBD_V6)
RBD_Create()
n=0
for y=1 to ROWS
for x=1 to COLS
inc n
sx#=5*(rnd(2)+2)
sy#=5*(rnd(2)+2)
col=RBD_CreateBox(sx#,sy#)
make object box n,sx#,sy#,0.01
color object n,hsl(rnd(100.0)/100.0,1.0,0.5)
b=RBD_CreateBody(col)
mass#=sx#*sy#
moi#=RBD_CalculateMIBoxSolid(mass#,sx#,sy#)
RBD_BodySetMass(b,mass#,moi#)
RBD_BodySetDBProData(b, n)
body(b).p.y=30*(y-1)-55
body(b).p.x=30.0*(x-2.5)
next x
next y
n=n+1
col=RBD_CreateBox(200.0,5.0)
make object plain n,200.0,5.0
b=RBD_CreateBody(col)
RBD_BodySetDBProData(b, n)
body(b).mass=0
body(b).p.y=-60
body(b).p.w=0
body(b).p.x=0
inc n
make object plain n,200.0,5.0
b=RBD_CreateBody(col)
RBD_BodySetDBProData(b, n)
body(b).p.w=90
body(b).p.x=-80
body(b).p.y=0
body(b).mass=0
inc n
make object plain n,200.0,5.0
b=RBD_CreateBody(col)
RBD_BodySetDBProData(b, n)
body(b).p.w=0
body(b).p.x=0
body(b).p.y=60
body(b).mass=0
inc n
make object plain n,200.0,5.0
b=RBD_CreateBody(col)
RBD_BodySetDBProData(b, n)
body(b).p.w=90
body(b).p.x=80
body(b).p.y=0
body(b).mass=0
inc n
col=RBD_CreateBox(80.0,5.0)
make object plain n,80.0,5.0
bar=n
b=RBD_CreateBody(col)
body(b).autofreeze=0
RBD_BodySetDBProData(b, n)
body(b).mass=0
body(b).p.y=20
body(b).p.w=0
body(b).p.x=0
inc n
global time# as float
drag_body=-1
grabx#=0
graby#=0
global screen=10000
make object plain screen,10000,10000
position object screen,0,0,2
color object screen,0
set object light screen,0
ghost object on screen,1
`hide object screen
global dummy_obj=10001
make object cube dummy_obj,0
global last_body
backdrop off
make object plain 10002,5000,5000
`lock object on 10002
`move object 10002,52
position object 10002,0,0,10
color object 10002,0
set alpha mapping on 10002,20
set object ambient 10002,0
RBD_SetStandardGravity(0.0,-49)
go=1
`debug.collision=1
`debug.torque=1
`debug.force=1
do
time#=RBD_GetElapsedTimeInSec()
if go=1 then RBD_Update(time#)
if spacekey()=1 and sp=0
go=1-go
endif
sp=spacekey()
set cursor 0,0
print "FPS:",screen fps()
set vector2 RBD_V1,0,1
set vector2 RBD_V2,0,30*(upkey()-downkey())
RBD_BodyAddForceLocal(body1)
` set vector2 RBD_V1,-(rightkey()-leftkey())*200.0,0
` RBD_BodyAddTorque(body1)
body(RBD_GetBody(bar)).p.w=body(RBD_GetBody(bar)).p.w+(leftkey()-rightkey())
if mouseclick()=1 and drag_body=-1
obj=pick object(mousex(),mousey(),1,100)
b=RBD_GetBody(obj)
if b>=0
if body(b).mass>0
drag_body=b
set vector2 RBD_V1,get pick vector x()+camera position x(),get pick vector y()+camera position y()
set vector2 RBD_V1,x vector2(RBD_V1)-body(b).p.x,y vector2(RBD_V1)-body(b).p.y
rotate_vector2(RBD_V1,-body(b).p.w)
grabx#=x vector2(RBD_V1)
graby#=y vector2(RBD_V1)
endif
endif
endif
print "Selected body:",last_body
print "Velocity:",str$(body(last_body).v.x),",",str$(body(last_body).v.y)
print "Angular Velocity:",str$(body(last_body).v.w)
print "Mass:",str$(body(last_body).mass)
print "Moment of Inertia:",str$(body(last_body).moi)
if mouseclick()=0 then drag_body=-1
if drag_body>=0
obj=pick object(mousex(),mousey(),screen,screen)
set vector2 RBD_V1,grabx#,graby#
rotate_vector2(RBD_V1,body(drag_body).p.w)
set vector2 RBD_V1,x vector2(RBD_V1)+body(drag_body).p.x,y vector2(RBD_V1)+body(drag_body).p.y
dx#=get pick vector x()+camera position x()-x vector2(RBD_V1)
dy#=get pick vector y()+camera position y()-y vector2(RBD_V1)
d2#=dx#^2+dy#^2
d#=sqrt(d2#)
dx#=dx#/d#
dy#=dy#/d#
force#=body(drag_body).mass*(d2#)
set vector2 RBD_V2,force#*dx#,force#*dy#
RBD_BodyAddForceGlobal(drag_body)
line mousex(),mousey(),screenx(x vector2(RBD_V1)),screeny(y vector2(RBD_V1))
body(drag_body).v.x=body(drag_body).v.x*0.992
body(drag_body).v.y=body(drag_body).v.y*0.992
body(drag_body).v.w=body(drag_body).v.w*0.992
last_body=drag_body
body(last_body).active=1
endif
if shiftkey()=1
body(last_body).v.x=0
body(last_body).v.y=0
if keystate(30)=1
for b=0 to max_body_amount
body(b).v.x=0
body(b).v.y=0
body(b).force.x=0
body(b).force.y=0
next b
endif
endif
if controlkey()=1
body(last_body).v.w=0
if keystate(30)=1
for b=0 to max_body_amount
body(b).v.w=0
body(b).force.w=0
next b
endif
endif
if keystate(34)=1 and key34=0
key34=1
body(last_body).gravity=1-body(last_body).gravity
endif
key34=keystate(34)
sync
loop
function RBD_Create()
RBD.world.min.x=-100.0
RBD.world.max.x=100.0
RBD.world.min.y=-100.0
RBD.world.max.y=100.0
RBD.world.standard_gravity.x=0
RBD.world.standard_gravity.y=-9.8
RBD.last_time=timer()
RBD.world.onexit=0
local b
for b=0 to max_body_amount
body(b).exist=0
next b
material(0,0).collidable=1
material(0,0).elasticity=0.4
material(0,0).sfriction=0.4
material(0,0).kfriction=0.4
groupid(0)=1
endfunction
function RBD_Update(time#)
for b=0 to max_body_amount
if body(b).exist=1
if RBD.world.onexit=1
if body(b).p.x<RBD.world.min.x or body(b).p.y<RBD.world.min.y or body(b).p.x>RBD.world.max.x or body(b).p.y>RBD.world.max.y then body(b).exist=0
endif
for l=1 to 2
for b2=0 to max_body_amount
if body(b2).exist=1
mat1=body(b).material
mat2=body(b2).material
if mat2<mat1
t=mat1
mat1=mat2
mat2=t
endif
if b<>b2 and material(mat1,mat2).collidable=1 and body(b).mass>0
d2#=(body(b).p.x-body(b2).p.x)^2+(body(b).p.y-body(b2).p.y)^2
if d2#<(body(b).collision_radius+body(b2).collision_radius)^2
ink rgb(0,255,0),0
col=BodyCollision(b,b2)
if col=1
body(b).active=1
body(b2).active=1
if l=1 and b<b2
`line screenx(RBD.collision.pt.x),screeny(RBD.collision.pt.y),screenx(RBD.collision.pt.x+RBD.collision.n.x*10.0),screeny(RBD.collision.pt.y+RBD.collision.n.y*10.0)
position object dummy_obj,RBD.collision.pt.x,RBD.collision.pt.y,0
cx=object screen x(dummy_obj)
cy=object screen y(dummy_obj)
position object dummy_obj,RBD.collision.pt.x+2.0*RBD.collision.n.x*RBD.collision.distance,RBD.collision.pt.y+2.0*RBD.collision.n.y*RBD.collision.distance,0
dx=object screen x(dummy_obj)
dy=object screen y(dummy_obj)
rem calculate normal impulse
nx#=RBD.collision.n.x
ny#=RBD.collision.n.y
rAPx#=RBD.collision.pt.x-body(b).p.x
rAPy#=RBD.collision.pt.y-body(b).p.y
rAP#=sqrt(rAPx#^2+rAPy#^2)
rBPx#=RBD.collision.pt.x-body(b2).p.x
rBPy#=RBD.collision.pt.y-body(b2).p.y
rBP#=sqrt(rBPx#^2+rBPy#^2)
rTAPx#=-rAPy#
rTAPy#=rAPx#
rTBPx#=-rBPy#
rTBPy#=rBPx#
if debug.collision=1
ink rgb(100,25,255),0
line screenx(RBD.collision.pt.x),screeny(RBD.collision.pt.y),screenx(RBD.collision.pt.x-rAPx#),screeny(RBD.collision.pt.y-rAPy#)
line screenx(RBD.collision.pt.x),screeny(RBD.collision.pt.y),screenx(RBD.collision.pt.x+rTAPx#),screeny(RBD.collision.pt.y+rTAPy#)
ink rgb(255,25,100),0
line screenx(RBD.collision.pt.x),screeny(RBD.collision.pt.y),screenx(RBD.collision.pt.x-rBPx#),screeny(RBD.collision.pt.y-rBPy#)
line screenx(RBD.collision.pt.x),screeny(RBD.collision.pt.y),screenx(RBD.collision.pt.x+rTBPx#),screeny(RBD.collision.pt.y+rTBPy#)
ink rgb(255,0,0),0
box screenx(RBD.collision.pt.x)-3,screeny(RBD.collision.pt.y)-3, screenx(RBD.collision.pt.x)+3,screeny(RBD.collision.pt.y)+3
endif
vA1x#=body(b).v.x
vA1y#=body(b).v.y
wA1#=body(b).v.w
vAP1x#=vA1x# +wA1#*rTAPx#
vAP1y#=vA1y# +wA1#*rTAPy#
vB1x#=body(b2).v.x
vB1y#=body(b2).v.y
wB1#=body(b2).v.w
vBP1x#=vB1x# +wB1#*rTBPx#
vBP1y#=vB1y# +wB1#*rTBPy#
vAB1x#=vBP1x#-vAP1x#
vAB1y#=vBP1y#-vAP1y#
vAB1#=vAB1x#*nx#+vAB1y#*ny#
e#=material(mat1,mat2).elasticity
if body(b).mass>0
dma#=1.0/body(b).mass
dmoia#=(rTAPx#*nx#+rTAPy#*ny#)^2/body(b).moi
else
rem 0 mass = infinite mass.
dma#=0
dmoia#=0
endif
if body(b2).mass>0
dmb#=1.0/body(b2).mass
dmoib#=(rTBPx#*nx#+rTBPy#*ny#)^2/body(b2).moi
else
rem 0 mass = infinite mass.
dmb#=0
dmoib#=0
endif
j#=(VAB1x#*nx#+VAB1y#*ny#)/(dma#+dmb#+dmoia#+dmoib#)
frictionj#=(VAB1x#*(-ny#)+VAB1y#*nx#)/(dma#+dmb#+dmoia#+dmoib#)
j#=j#*(1.0+e#)
if j#>0
j#=0
endif
if abs(frictionj#)> abs(j#)*material(mat1,mat2).kfriction
frictionj#=frictionj#/abs(frictionj#)*abs(j#)*material(mat1,mat2).kfriction
endif
ivA2x#=(j#)*nx#+frictionj#*(-ny#)
ivA2y#=(j#)*ny#+frictionj#*nx#
ivB2x#=-(j#)*nx#-frictionj#*(-ny#)
ivB2y#=-(j#)*ny#-frictionj#*nx#
`iwA2#=(rTAPx#*j#*nx#+rTAPy#*j#*ny#)/rAP#^2+(rTAPx#*frictionj#*(-ny#)+rTAPy#*frictionj#*nx#)/rAP#^2
`iwB2#=(rTBPx#*j#*nx#+rTBPy#*j#*ny#)/rBP#^2+(rTBPx#*frictionj#*(-ny#)+rTBPy#*frictionj#*nx#)/rBP#^2
k#=1.0
body(b).impulse.x=body(b).impulse.x+ivA2x#*k#
body(b).impulse.y=body(b).impulse.y+ivA2y#*k#
body(b).impulse.w=body(b).impulse.w+iwA2#*k#
body(b2).impulse.x=body(b2).impulse.x+ivB2x#*k#
body(b2).impulse.y=body(b2).impulse.y+ivB2y#*k#
body(b2).impulse.w=body(b2).impulse.w+iwB2#*k#
` if j#>-0.1*(body(b).mass+body(b2).mass) or RBD.collision.distance>-2
rem calculate normal force
forcevA1x#=body(b).force.x
forcevA1y#=body(b).force.y
forcewA1#=body(b).avgforce.w*0.5
forcevAP1x#=forcevA1x#+forcewA1#*rTAPx#/rAP#^2
forcevAP1y#=forcevA1y#+forcewA1#*rTAPy#/rAP#^2
forcevB1x#=body(b2).force.x
forcevB1y#=body(b2).force.y
forcewB1#=body(b2).avgforce.w*0.5
` if body(b2).collision_radius>body(b).collision_radius
forcevBP1x#=forcevB1x#+forcewB1#*rTBPx#/rBP#^2
forcevBP1y#=forcevB1y#+forcewB1#*rTBPy#/rBP#^2
` else
` forcevBP1x#=forcevB1x#+forcewB1#*rTBPx#/rBP#^2
` forcevBP1y#=forcevB1y#+forcewB1#*rTBPy#/rBP#^2
` endif
forcevAB1x#=forcevBP1x#-forcevAP1x#
forcevAB1y#=forcevBP1y#-forcevAP1y#
forcevAB1#=forcevAB1x#*nx#+forcevAB1y#*ny#
forcej#=(forceVAB1x#*nx#+forceVAB1y#*ny#)
if forcej#<0
` line screenx(RBD.collision.pt.x),screeny(RBD.collision.pt.y),screenx(RBD.collision.pt.x+forcevAP1x#),screeny(RBD.collision.pt.y+forcevAP1y#)
forceivA2x#=(forcej#)*nx#
forceivA2y#=(forcej#)*ny#
forceivB2x#=-(forcej#)*nx#
forceivB2y#=-(forcej#)*ny#
forceiwA2#=(rTAPx#*forcej#*nx#+rTAPy#*forcej#*ny#)
` if body(b2).collision_radius>body(b).collision_radius
` forceiwB2#=(rTBPx#*forcej#*nx#+rTBPy#*forcej#*ny#)
` else
forceiwB2#=-(rTBPx#*forcej#*nx#+rTBPy#*forcej#*ny#)
` endif
` line screenx(RBD.collision.pt.x),screeny(RBD.collision.pt.y),screenx(RBD.collision.pt.x+forceiwA2#*rTAPx#/(rAP#*10000.0)),screeny(RBD.collision.pt.y+forceiwA2#*rTAPy#/(rAP#*10000.0))
surfaceforce#=forcevAB1x#*(-ny#)+forcevAB1y#*nx#
normalforce#=abs(forcej#)
frictionforcej#=abs(normalforce#*material(mat1,mat2).kfriction)
if abs(frictionforcej#)>abs(frictionj#/(2*time#)) then frictionforcej#=abs(frictionj#/(2*time#))
frictionforcej#=-frictionforcej#*frictionj#/abs(frictionj#)
if abs(vAB1x#*(-ny#)+vAB1y#*nx#)<3
frictionforcej#=0
endif
frictionforcej#=0
` line screenx(RBD.collision.pt.x),screeny(RBD.collision.pt.y),screenx(RBD.collision.pt.x+frictionforcej#*frictionnx#*10.0),screeny(RBD.collision.pt.y+frictionforcej#*frictionny#*10.0)
`line screenx(RBD.collision.pt.x),screeny(RBD.collision.pt.y),screenx(RBD.collision.pt.x+frictionforcej#*(-ny#)/1000.0),screeny(RBD.collision.pt.y+frictionforcej#*nx#/1000.0)
frictionforceivA2x#=(frictionforcej#)*(-ny#)
frictionforceivA2y#=(frictionforcej#)*nx#
frictionforceivB2x#=-(frictionforcej#)*(-ny#)
frictionforceivB2y#=-(frictionforcej#)*(nx#)
frictionforceiwA2#=(rTAPx#*frictionforcej#*(-ny#)+rTAPy#*frictionforcej#*nx#)
frictionforceiwB2#=(rTBPx#*frictionforcej#*(-ny#)+rTBPy#*frictionforcej#*nx#)
k#=1
body(b).force.x=body(b).force.x+forceivA2x#*k# +frictionforceivA2x#*k#
body(b).force.y=body(b).force.y+forceivA2y#*k# +frictionforceivA2y#*k#
body(b).force.w=body(b).force.w+forceiwA2#*k# +frictionforceiwA2#*k#
body(b2).force.x=body(b2).force.x+forceivB2x#*k# +frictionforceivB2x#*k#
body(b2).force.y=body(b2).force.y+forceivB2y#*k# +frictionforceivB2y#*k#
body(b2).force.w=body(b2).force.w+forceiwB2#*k# +frictionforceiwB2#*k#
` body(b).avgforce.x=(body(b).avgforce.x*1.0+body(b).force.x)/2.0
` body(b).avgforce.y=(body(b).avgforce.y*1.0+body(b).force.y)/2.0
body(b).avgforce.x=body(b).force.x
body(b).avgforce.y=body(b).force.y
body(b).avgforce.w=(body(b).avgforce.w*1.0+body(b).force.w)/2.0
endif
`endif
endif
rem this alters the position of the bodies (encourages them to not overlap)
`if b<b2
if body(b2).mass=0
body(b).p.x=body(b).p.x+RBD.collision.distance*(RBD.collision.n.x)*0.5
body(b).p.y=body(b).p.y+RBD.collision.distance*(RBD.collision.n.y)*0.5
body(b2).force.x=0
body(b2).force.y=0
body(b2).force.w=0
else
body(b).p.x=body(b).p.x+RBD.collision.distance*(RBD.collision.n.x)*body(b).mass/(body(b).mass+body(b2).mass)*0.5
body(b).p.y=body(b).p.y+RBD.collision.distance*(RBD.collision.n.y)*body(b).mass/(body(b).mass+body(b2).mass)*0.5
body(b2).p.x=body(b2).p.x-RBD.collision.distance*(RBD.collision.n.x)*body(b).mass/(body(b).mass+body(b2).mass)*0.5
body(b2).p.y=body(b2).p.y-RBD.collision.distance*(RBD.collision.n.y)*body(b).mass/(body(b).mass+body(b2).mass)*0.5
endif
`endif
` endif
endif
endif
endif
endif
next b2
next l
body(b).force.x=body(b).force.x-body(b).lin_damp*body(b).v.x*abs(body(b).v.x)*time#
body(b).force.y=body(b).force.y-body(b).lin_damp*body(b).v.y*abs(body(b).v.y)*time#
body(b).force.w=body(b).force.w-body(b).ang_damp*body(b).v.w*abs(body(b).v.w)*time#
if body(b).mass=0
body(b).v.x=0
body(b).v.y=0
body(b).v.w=0
endif
if b=last_body
` print "Sum of all forces being applied to object:",str$(body(last_body).force.x,2),",",str$(body(last_body).force.y,2)
endif
if body(b).active=1 and body(b).mass>0
if debug.torque=1
for r=1 to 10
line screenx(body(b).p.x+(r*0.01+5)*cos(body(b).avgforce.w*r*0.001)),screeny(body(b).p.y+(r*0.01+5)*sin(body(b).avgforce.w*r*0.001)),screenx(body(b).p.x+((r+1)*0.01+5)*cos(body(b).avgforce.w*(r+1)*0.001)),screeny(body(b).p.y+((r+1)*0.01+5)*sin(body(b).avgforce.w*(r+1)*0.001))
next r
endif
if debug.force=1
line screenx(body(b).p.x),screeny(body(b).p.y),screenx(body(b).p.x+body(b).force.x*0.01),screeny(body(b).p.y+body(b).force.y*0.01)
endif
body(b).v.x=body(b).v.x+body(b).force.x/body(b).mass*time#+body(b).impulse.x/body(b).mass
body(b).v.y=body(b).v.y+body(b).force.y/body(b).mass*time#+body(b).impulse.y/body(b).mass
body(b).v.w=body(b).v.w+body(b).force.w/body(b).moi*time#+body(b).impulse.w/body(b).moi
body(b).p.x=body(b).p.x+body(b).push.x
body(b).p.y=body(b).p.y+body(b).push.y
body(b).p.w=body(b).p.w+body(b).push.w
body(b).avgforce.x=body(b).force.x
body(b).avgforce.y=body(b).force.y
body(b).avgforce.w=body(b).force.w
body(b).force.x=RBD.world.standard_gravity.x*body(b).mass*body(b).gravity
body(b).force.y=RBD.world.standard_gravity.y*body(b).mass*body(b).gravity
body(b).force.w=0
body(b).impulse.x=0
body(b).impulse.y=0
body(b).impulse.w=0
body(b).push.x=0
body(b).push.y=0
body(b).push.w=0
body(b).p.x=body(b).p.x+body(b).v.x*time#
body(b).p.y=body(b).p.y+body(b).v.y*time#
body(b).p.w=body(b).p.w+body(b).v.w*time#*180.0/3.14159
else
body(b).v.x=0
body(b).v.y=0
body(b).v.w=0
body(b).force.x=0
body(b).force.y=0
body(b).force.w=0
body(b).impulse.x=0
body(b).impulse.y=0
body(b).impulse.w=0
body(b).push.x=0
body(b).push.y=0
body(b).push.w=0
endif
if body(b).active=1
check=0
if abs(body(b).force.x)<0.4
` body(b).force.x=0
inc check
endif
if abs(body(b).v.x)<0.4
` body(b).v.x=0
inc check
endif
if abs(body(b).force.y)<0.4
` body(b).force.y=0
inc check
endif
if abs(body(b).v.y)<0.4
` body(b).v.y=0
inc check
endif
if abs(body(b).force.w)<0.4
` body(b).force.w=0
inc check
endif
if abs(body(b).v.w)<0.4
` body(b).v.w=0
inc check
endif
if check=6 and body(b).autofreeze=1
body(b).active=0
endif
else
check=0
if abs(body(b).force.x)>100 or abs(body(b).force.y)>100 or abs(body(b).force.w)>100 then body(b).active=1
endif
if body(b).object>0
position object body(b).object,curvevalue(body(b).p.x,object position x(body(b).object),1.5),curvevalue(body(b).p.y,object position y(body(b).object),1.5),0
rotate object body(b).object,0,0,curveangle(body(b).p.w,object angle z(body(b).object),1.5)
`text screenx(body(b).p.x),screeny(body(b).p.y),str$(b)
endif
rem wrap objects around if they get out of the screen
if body(b).p.y<-70 then body(b).p.y=70
if body(b).p.y>70 then body(b).p.y=-70
if body(b).p.x<-90 then body(b).p.x=90
if body(b).p.x>90 then body(b).p.x=-90
endif
next b
local c
for c=0 to max_collision_data_amount
collision_data(c).exist=0
next c
endfunction
function RBD_GetElapsedTimeInSec()
t#=(timer()-RBD.last_time)*0.001
RBD.last_time=timer()
if t#<0.001 then t#=0.001
endfunction t#
function RBD_SetWorldSize()
RBD.world.min.x=x vector2(RBD_V1)
RBD.world.min.y=y vector2(RBD_V1)
RBD.world.max.x=x vector2(RBD_V2)
RBD.world.max.y=y vector2(RBD_V2)
endfunction
function RBD_CreateBox(sx#,sy#)
local c=0
while collision_data(c).exist=1
inc c
endwhile
collision_data(c).exist=1
collision_data(c).vertex_amount=4
collision_data_v(c,0).x=sx#*0.5
collision_data_v(c,0).y=sy#*0.5
collision_data_v(c,1).x=sx#*0.5
collision_data_v(c,1).y=-sy#*0.5
collision_data_v(c,2).x=-sx#*0.5
collision_data_v(c,2).y=-sy#*0.5
collision_data_v(c,3).x=-sx#*0.5
collision_data_v(c,3).y=sy#*0.5
endfunction c
function RBD_CreateBody(col)
local b=0
while body(b).exist=1
inc b
endwhile
body(b).exist=1
body(b).gravity=1
body(b).mass=1
body(b).p.x=0
body(b).p.y=0
body(b).p.w=0
body(b).v.x=0
body(b).v.y=0
body(b).v.w=0
body(b).force.x=0
body(b).force.y=0-98*body(b).mass*body(b).gravity
body(b).force.w=0
body(b).impulse.x=0
body(b).impulse.y=0
body(b).impulse.w=0
body(b).moi=1
body(b).active=1
body(b).autofreeze=1
body(b).lin_damp=0.1
body(b).ang_damp=0.1
body(b).vertex_amount=collision_data(col).vertex_amount
body(b).material=0
local v
rad2#=0
for v=0 to body(b).vertex_amount-1
body_shape(b,v).x=collision_data_v(col,v).x
body_shape(b,v).y=collision_data_v(col,v).y
r#=collision_data_v(col,v).x^2+collision_data_v(col,v).y^2
if r#>rad2#
rad2#=r#
endif
next v
body(b).collision_radius=sqrt(rad2#)
endfunction b
function RBD_DestroyBody(b)
body(b).exist=0
endfunction
function RBD_BodyGetRotation(b)
set vector2 RBD_V1,body(b).p.w,0
endfunction
function RBD_BodyGetPosition(b)
set vector2 RBD_V1,body(b).p.x,body(b).p.y
endfunction
function RBD_DestroyAllBodies()
local b
for b=0 to max_body_amount
RBD_DestroyBody(b)
next b
endfunction
function RBD_SetBodyLeaveWorldEvent(flag)
RBD.world.onexit=flag
endfunction
function RBD_BodySetDBProData(body, db_num)
body(body).object=db_num
endfunction
function RBD_BodySetVelocity(body)
body(body).v.x=x vector2(RBD_V1)
body(body).v.y=y vector2(RBD_V1)
endfunction
function RBD_BodyGetVelocity(body)
set vector2 RBD_V1,body(body).v.x,body(body).v.y
endfunction
function RBD_BodySetOmega(body)
body(body).v.w=x vector2(RBD_V1)
endfunction
function RBD_BodyGetOmega(body)
set vector2 RBD_V1,body(body).v.w,0
endfunction
function RBD_BodySetLinearDamping(body, lin_damp#)
body(body).lin_damp=lin_damp#
endfunction
function RBD_BodyGetLinearDamping(body)
d#=body(body).lin_damp
endfunction d#
function RBD_BodySetAngularDamping(body, ang_damp#)
body(body).ang_damp=ang_damp#
endfunction
function RBD_BodyGetAngularDamping(body)
d#=body(body).ang_damp
endfunction d#
function RBD_BodyAddTorque(body)
body(body).force.w=body(body).force.w+x vector2(RBD_V1)
endfunction
function RBD_BodySetTorque(body)
body(body).force.w=x vector2(RBD_V1)
endfunction
function RBD_BodyAddForceGlobal(b)
RX#=x vector2(RBD_V1)-body(b).p.x
RY#=y vector2(RBD_V1)-body(b).p.y
FX#=x vector2(RBD_V2)
FY#=y vector2(RBD_V2)
torque#=(RX#*FY#-RY#*FX#)
R#=sqrt(RX#^2+RY#^2)
body(b).force.w=body(b).force.w+torque#
body(b).force.x=body(b).force.x+FX#*abs(RX#/R#)
body(b).force.y=body(b).force.y+FY#*abs(RY#/R#)
endfunction
function RBD_BodyAddForceLocal(b)
rotate_vector2(RBD_V1,body(b).p.w)
set vector2 RBD_V1,x vector2(RBD_V1)+body(b).p.x,y vector2(RBD_V1)+body(b).p.y
rotate_vector2(RBD_V2,body(b).p.w)
RBD_BodyAddForceGlobal(b)
endfunction
function RBD_BodySetForceGlobal(b)
RX#=x vector2(RBD_V1)-body(b).p.x
RY#=y vector2(RBD_V1)-body(b).p.y
FX#=x vector2(RBD_V2)
FY#=y vector2(RBD_V2)
torque#=(RX#*FY#-RY#*FX#)
body(b).force.w=torque#
R#=sqrt(RX#^2+RY#^2)
body(b).force.x=FX#*abs(RX#/R#)
body(b).force.y=FY#*abs(RY#/R#)
endfunction
function RBD_BodySetForceLocal(b)
rotate_vector2(RBD_V1,body(b).p.w)
set vector2 RBD_V1,x vector2(RBD_V1)+body(b).p.x,y vector2(RBD_V1)+body(b).p.y
rotate_vector2(RBD_V2,body(b).p.w)
RBD_BodySetForceGlobal(b)
endfunction
function RBD_BodyAddImpulseGlobal(b)
RX#=x vector2(RBD_V1)-body(b).p.x
RY#=y vector2(RBD_V1)-body(b).p.y
FX#=x vector2(RBD_V2)
FY#=y vector2(RBD_V2)
R#=sqrt(RX#^2+RY#^2)
torque#=(RX#*FY#-RY#*FX#)
body(b).impulse.w=body(b).impulse.w+torque#/R#^2
body(b).impulse.x=body(b).impulse.x+FX#*abs(RX#/R#)
body(b).impulse.y=body(b).impulse.y+FY#*abs(RY#/R#)
endfunction
function RBD_BodyAddImpulseLocal(b)
rotate_vector2(RBD_V1,body(b).p.w)
set vector2 RBD_V1,x vector2(RBD_V1)+body(b).p.x,y vector2(RBD_V1)+body(b).p.y
rotate_vector2(RBD_V2,body(b).p.w)
RBD_BodyAddImpulseGlobal(b)
endfunction
function rotate_vector2(v,r#)
set vector2 RBD_V3,cos(r#),sin(r#)
set vector2 RBD_V4,-y vector2(RBD_V3),x vector2(RBD_V3)
set vector2 v,x vector2(v)*x vector2(RBD_V3)+y vector2(v)*x vector2(RBD_V4),x vector2(v)*y vector2(RBD_V3)+y vector2(v)*y vector2(RBD_V4)
endfunction
function BodyCollision(b1,b2)
if body(b2).vertex_amount<body(b1).vertex_amount
bt=b1
b1=b2
b2=bt
endif
va1=body(b1).vertex_amount
va2=body(b2).vertex_amount
RBD_collision_distance1#=100000
RBD_collision_distance2#=100000
RBD.collision.exist1=0
RBD.collision.exist2=0
RBD.collision.pt.x=0
RBD.collision.pt.y=0
RBD.collision.n.x=0
RBD.collision.n.y=0
` RBD.collision.point_amount=0
for v=0 to va1-1
px#=body_shape(b1,v).x
py#=body_shape(b1,v).y
set vector2 RBD_V1,px#,py#
rotate_vector2(RBD_V1,body(b1).p.w)
px#=x vector2(RBD_v1)+body(b1).p.x
py#=y vector2(RBD_v1)+body(b1).p.y
vx#=body_shape(b1,mod((v+1),(va1))).x-body_shape(b1,v).x
vy#=body_shape(b1,mod((v+1),(va1))).y-body_shape(b1,v).y
set vector2 RBD_V1,vx#,vy#
length#=length vector2(RBD_V1)
rotate_vector2(RBD_V1,body(b1).p.w+90)
normalize vector2 RBD_V1,RBD_V1
nx#=x vector2(RBD_V1)
ny#=y vector2(RBD_V1)
minv1#=100000
minv1=0
maxv1#=-100000
maxv1=0
minv2#=100000
minv2=0
maxv2#=-100000
maxv2=0
for v2=0 to va2-1
set vector2 RBD_V2,body_shape(b2,v2).x,body_shape(b2,v2).y
rotate_vector2(RBD_V2,body(b2).p.w)
set vector2 RBD_V2,x vector2(RBD_V2)+body(b2).p.x-px#,y vector2(RBD_V2)+body(b2).p.y-py#
v2#=x vector2(RBD_V2)*x vector2(RBD_V1)+y vector2(RBD_V2)*y vector2(RBD_V1)
if v2#<minv2#
minv2#=v2#
minv2=v2
vx#=body_shape(b2,mod((v2+1),(va2))).x-body_shape(b2,v2).x
vy#=body_shape(b2,mod((v2+1),(va2))).y-body_shape(b2,v2).y
set vector2 RBD_V6,vx#,vy#
rotate_vector2(RBD_V6,body(b2).p.w)
e1nx#=x vector2(RBD_V6)
e1ny#=y vector2(RBD_V6)
vx#=(body_shape(b2,mod((v2+1),(va2))).x+body_shape(b2,v2).x)/2.0
vy#=(body_shape(b2,mod((v2+1),(va2))).y+body_shape(b2,v2).y)/2.0
set vector2 RBD_V6,vx#,vy#
rotate_vector2(RBD_V6,body(b2).p.w)
e1ax#=x vector2(RBD_V6)+body(b2).p.x
e1ay#=y vector2(RBD_V6)+body(b2).p.y
vx#=body_shape(b2,mod((v2-1),(va2))).x-body_shape(b2,v2).x
vy#=body_shape(b2,mod((v2-1),(va2))).y-body_shape(b2,v2).y
set vector2 RBD_V6,vx#,vy#
rotate_vector2(RBD_V6,body(b2).p.w)
e2nx#=x vector2(RBD_V6)
e2ny#=y vector2(RBD_V6)
vx#=(body_shape(b2,mod((v2-1),(va2))).x+body_shape(b2,v2).x)/2.0
vy#=(body_shape(b2,mod((v2-1),(va2))).y+body_shape(b2,v2).y)/2.0
set vector2 RBD_V6,vx#,vy#
rotate_vector2(RBD_V6,body(b2).p.w)
e2ax#=x vector2(RBD_V6)+body(b2).p.x
e2ay#=y vector2(RBD_V6)+body(b2).p.y
endif
if v2#>maxv2#
maxv2#=v2#
maxv2=v2
endif
next v2
if minv2#>0
exitfunction 0
else
d#=0-minv2#
cv=minv2
if d#>0
if d#<=RBD_collision_distance1#
RBD_collision_distance1#=d#
RBD.collision.edge1=v
RBD.collision.edge_length1=length#
RBD.collision.exist1=1
` line screenx(e1ax#),screeny(e1ay#),screenx(e1ax#+e1nx#*20.0),screeny(e1ay#+e1ny#*20.0)
` line screenx(e2ax#),screeny(e2ay#),screenx(e2ax#+e2nx#*20.0),screeny(e2ay#+e2ny#*20.0)
endif
endif
endif
next v
for v=0 to va2-1
px#=body_shape(b2,v).x
py#=body_shape(b2,v).y
set vector2 RBD_V1,px#,py#
rotate_vector2(RBD_V1,body(b2).p.w)
px#=x vector2(RBD_v1)+body(b2).p.x
py#=y vector2(RBD_v1)+body(b2).p.y
vx#=body_shape(b2,mod((v+1),(va2))).x-body_shape(b2,v).x
vy#=body_shape(b2,mod((v+1),(va2))).y-body_shape(b2,v).y
set vector2 RBD_V1,vx#,vy#
length#=length vector2(RBD_V1)
rotate_vector2(RBD_V1,body(b2).p.w+90)
normalize vector2 RBD_V1,RBD_V1
nx#=x vector2(RBD_V1)
ny#=y vector2(RBD_V1)
minv1#=100000
minv1=0
maxv1#=-100000
maxv1=0
minv2#=100000
minv2=0
maxv2#=-100000
maxv2=0
for v1=0 to va1-1
set vector2 RBD_V2,body_shape(b1,v1).x,body_shape(b1,v1).y
rotate_vector2(RBD_V2,body(b1).p.w)
set vector2 RBD_V2,x vector2(RBD_V2)+body(b1).p.x-px#,y vector2(RBD_V2)+body(b1).p.y-py#
v1#=x vector2(RBD_V2)*x vector2(RBD_V1)+y vector2(RBD_V2)*y vector2(RBD_V1)
if v1#<minv1#
minv1#=v1#
minv1=v1
vx#=body_shape(b1,mod((v1+1),(va1))).x-body_shape(b1,v1).x
vy#=body_shape(b1,mod((v1+1),(va1))).y-body_shape(b1,v1).y
set vector2 RBD_V6,vx#,vy#
rotate_vector2(RBD_V6,body(b1).p.w)
e1nx#=x vector2(RBD_V6)
e1ny#=y vector2(RBD_V6)
vx#=(body_shape(b1,mod((v1+1),(va1))).x+body_shape(b1,v1).x)/2.0
vy#=(body_shape(b1,mod((v1+1),(va1))).y+body_shape(b1,v1).y)/2.0
set vector2 RBD_V6,vx#,vy#
rotate_vector2(RBD_V6,body(b1).p.w)
e1ax#=x vector2(RBD_V6)+body(b1).p.x
e1ay#=y vector2(RBD_V6)+body(b1).p.y
vx#=body_shape(b1,mod((v1-1),(va1))).x-body_shape(b1,v1).x
vy#=body_shape(b1,mod((v1-1),(va1))).y-body_shape(b1,v1).y
set vector2 RBD_V6,vx#,vy#
rotate_vector2(RBD_V6,body(b1).p.w)
e2nx#=x vector2(RBD_V6)
e2ny#=y vector2(RBD_V6)
vx#=(body_shape(b1,mod((v1-1),(va1))).x+body_shape(b1,v1).x)/2.0
vy#=(body_shape(b1,mod((v1-1),(va1))).y+body_shape(b1,v1).y)/2.0
set vector2 RBD_V6,vx#,vy#
rotate_vector2(RBD_V6,body(b1).p.w)
e2ax#=x vector2(RBD_V6)+body(b1).p.x
e2ay#=y vector2(RBD_V6)+body(b1).p.y
endif
if v1#>maxv1#
maxv1#=v1#
maxv1=v1
endif
next v1
if minv1#>0
exitfunction 0
else
d#=0-minv1#
cv=minv1
if d#>0
if d#<=RBD_collision_distance2#
RBD_collision_distance2#=d#
RBD.collision.edge2=v
RBD.collision.edge_length2=length#
RBD.collision.exist2=1
` line screenx(e1ax#),screeny(e1ay#),screenx(e1ax#+e1nx#*20.0),screeny(e1ay#+e1ny#*20.0)
` line screenx(e2ax#),screeny(e2ay#),screenx(e2ax#+e2nx#*20.0),screeny(e2ay#+e2ny#*20.0)
endif
endif
endif
next v
point_amount=0
if RBD.collision.exist1=1
maxd#=0
v=RBD.collision.edge1
vx#=body_shape(b1,mod((v+1),body(b1).vertex_amount)).x-body_shape(b1,v).x
vy#=body_shape(b1,mod((v+1),body(b1).vertex_amount)).y-body_shape(b1,v).y
set vector2 RBD_V1,vx#,vy#
length#=length vector2(RBD_V1)
normalize vector2 RBD_V1,RBD_V1
rotate_vector2(RBD_V1,body(b1).p.w)
tx#=x vector2(RBD_V1)
ty#=y vector2(RBD_V1)
rotate_vector2(RBD_V1,-90)
nx#=x vector2(RBD_V1)
ny#=y vector2(RBD_V1)
set vector2 RBD_V5,body_shape(b1,v).x,body_shape(b1,v).y
rotate_vector2(RBD_V5,body(b1).p.w)
set vector2 RBD_V5,x vector2(RBD_V5)+body(b1).p.x,y vector2(RBD_V5)+body(b1).p.y
set vector2 RBD_V1,body_shape(b1,v).x,body_shape(b1,v).y
rotate_vector2(RBD_V1,body(b1).p.w)
px#=body(b1).p.x+x vector2(RBD_V1)
py#=body(b1).p.y+y vector2(RBD_V1)
set vector2 RBD_V1,body_shape(b1,v).x,body_shape(b1,v).y
rotate_vector2(RBD_V1,body(b1).p.w)
set vector2 RBD_V6,x vector2(RBD_V1)+body(b1).p.x-px#,y vector2(RBD_V1)+body(b1).p.y-py#
v2#=x vector2(RBD_V6)*nx#+y vector2(RBD_V6)*ny#
for v2=0 to body(b2).vertex_amount-1
set vector2 RBD_V1,body_shape(b2,v2).x,body_shape(b2,v2).y
rotate_vector2(RBD_V1,body(b2).p.w)
set vector2 RBD_V6,x vector2(RBD_V1)+body(b2).p.x-px#,y vector2(RBD_V1)+body(b2).p.y-py#
v2#=x vector2(RBD_V6)*nx#+y vector2(RBD_V6)*ny#
if v2#>-0.3
cx#=x vector2(RBD_V6)*tx#+y vector2(RBD_V6)*ty#
if cx#>-0.0001 and cx#<RBD.collision.edge_length1+0.0001
x#=x#+cx#
d#=v2#
if d#>maxd#
maxd#=d#
endif
inc point_amount
endif
endif
next v2
if point_amount>0
x#=x#/point_amount
RBD_collision_distance1#=-maxd#
RBD.collision.pt.x=RBD.collision.pt.x+x#*tx#+px#
RBD.collision.pt.y=RBD.collision.pt.y+x#*ty#+py#
RBD.collision.n.x=-nx#
RBD.collision.n.y=-ny#
if RBD.collision.exist2=0
RBD.collision.distance=RBD_collision_distance1#
else
nx1#=-nx#
ny1#=-ny#
endif
else
RBD.collision.exist1=0
endif
endif
point_amount=0
if RBD.collision.exist2=1
maxd#=0
v=RBD.collision.edge2
vx#=body_shape(b2,mod((v+1),body(b2).vertex_amount)).x-body_shape(b2,v).x
vy#=body_shape(b2,mod((v+1),body(b2).vertex_amount)).y-body_shape(b2,v).y
set vector2 RBD_V1,vx#,vy#
length#=length vector2(RBD_V1)
normalize vector2 RBD_V1,RBD_V1
rotate_vector2(RBD_V1,body(b2).p.w)
tx#=x vector2(RBD_V1)
ty#=y vector2(RBD_V1)
rotate_vector2(RBD_V1,-90)
nx#=x vector2(RBD_V1)
ny#=y vector2(RBD_V1)
set vector2 RBD_V5,body_shape(b2,v).x,body_shape(b2,v).y
rotate_vector2(RBD_V5,body(b2).p.w)
set vector2 RBD_V5,x vector2(RBD_V5)+body(b2).p.x,y vector2(RBD_V5)+body(b2).p.y
set vector2 RBD_V1,body_shape(b2,v).x,body_shape(b2,v).y
rotate_vector2(RBD_V1,body(b2).p.w)
px#=body(b2).p.x+x vector2(RBD_V1)
py#=body(b2).p.y+y vector2(RBD_V1)
set vector2 RBD_V1,body_shape(b2,v).x,body_shape(b2,v).y
rotate_vector2(RBD_V1,body(b2).p.w)
set vector2 RBD_V6,x vector2(RBD_V1)+body(b2).p.x-px#,y vector2(RBD_V1)+body(b2).p.y-py#
v2#=x vector2(RBD_V6)*nx#+y vector2(RBD_V6)*ny#
for v2=0 to body(b1).vertex_amount-1
set vector2 RBD_V1,body_shape(b1,v2).x,body_shape(b1,v2).y
rotate_vector2(RBD_V1,body(b1).p.w)
set vector2 RBD_V6,x vector2(RBD_V1)+body(b1).p.x-px#,y vector2(RBD_V1)+body(b1).p.y-py#
v2#=x vector2(RBD_V6)*nx#+y vector2(RBD_V6)*ny#
if v2#>-0.3
cx#=x vector2(RBD_V6)*tx#+y vector2(RBD_V6)*ty#
if cx#>-0.0001 and cx#<RBD.collision.edge_length2+0.0001
x#=x#+cx#
d#=v2#
if d#>maxd#
maxd#=d#
endif
inc point_amount
endif
endif
next v2
if point_amount>0
x#=x#/point_amount
RBD_collision_distance2#=-maxd#
RBD.collision.pt.x=RBD.collision.pt.x+x#*tx#+px#
RBD.collision.pt.y=RBD.collision.pt.y+x#*ty#+py#
RBD.collision.n.x=nx#
RBD.collision.n.y=ny#
if RBD.collision.exist1=0
RBD.collision.distance=RBD_collision_distance2#
else
nx2#=nx#
ny2#=ny#
endif
else
RBD.collision.exist2=0
endif
endif
if RBD.collision.exist1 and RBD.collision.exist2
RBD.collision.pt.x=RBD.collision.pt.x/2.0
RBD.collision.pt.y=RBD.collision.pt.y/2.0
if RBD_collision_distance1#<RBD_collision_distance2#
RBD.collision.distance=RBD_collision_distance1#
RBD.collision.n.x=nx1#
RBD.collision.n.y=ny1#
else
RBD.collision.distance=RBD_collision_distance2#
RBD.collision.n.x=nx2#
RBD.collision.n.y=ny2#
endif
endif
` line screenx(RBD.collision.pt.x),screeny(RBD.collision.pt.y),screenx(RBD.collision.pt.x+RBD.collision.n.x*20.0),screeny(RBD.collision.pt.y+RBD.collision.n.y*20.0)
x=screenx(RBD.collision.pt.x)
y=screeny(RBD.collision.pt.y)
if debug.collision=1 then box x-3,y-3,x+3,y+3
endfunction 1
function screenx(x#)
position object dummy_obj,x#,0,0
x#=object screen x(dummy_obj)
endfunction x#
function screeny(y#)
position object dummy_obj,0,y#,0
y#=object screen y(dummy_obj)
endfunction y#
function mod(a,b)
if a<0 then a=a+b
RV = int(a / b)
RV = RV * b
RV = a - RV
endfunction RV
function RBD_GetBody(obj)
for b=0 to max_body_amount
if body(b).exist=1
if body(b).object=obj
exitfunction b
endif
endif
next b
endfunction -1
function RBD_GetDBPro(body)
obj=body(body).object
endfunction obj
function RBD_MaterialGetDefaultGroupID()
endfunction 0
function RBD_MaterialCreateGroupID()
i=0
while groupid(i)=1
inc i
endwhile
groupid(i)=1
for n=0 to max_material_amount
material(i,n).collidable=1
material(i,n).elasticity=1.0
next n
endfunction i
function RBD_MaterialSetDefaultCollidable(mat1,mat2,state)
material(mat1,mat2).collidable=state
endfunction
function RBD_MaterialSetDefaultFriction(mat1,mat2,sfriction#,kfriction#)
material(mat1,mat2).sfriction=sfriction#
material(mat1,mat2).kfriction=kfriction#
endfunction
function RBD_MaterialSetDefaultElasticity(mat1,mat2,elasticity#)
material(mat1,mat2).elasticity=elasticity#
endfunction
function RBD_CalculateMIBoxSolid(mass#,sx#,sy#)
moi#=(1.0/12.0)*mass#*(sx#^2+sy#^2)
endfunction moi#
function RBD_CalculateMICircleSolid(mass#,r#)
moi#=1.0/2*mass#*r#^2
endfunction moi#
function RBD_BodySetMass(b,mass#,moi#)
body(b).mass=mass#
if moi#<>0
body(b).moi=moi#
endif
endfunction
function RBD_SetStandardGravity(x#,y#)
RBD.world.standard_gravity.x=x#
RBD.world.standard_gravity.y=y#
endfunction
function RBD_GetStandardGravity()
set vector2 RBD_V1,RBD.world.standard_gravity.x,RBD.world.standard_gravity.y
endfunction
function hsl(H#,S#,L#)
if ( S# = 0 ) `HSL values = 0 ÷ 1
rR# = L# * 255 `RGB results = 0 ÷ 255
rG# = L# * 255
rB# = L# * 255
else
if ( L# < 0.5 )
var_2# = L# * ( 1 + S# )
else
var_2# = ( L# + S# ) - ( S# * L# )
endif
var_1# = (2 * L#) - var_2#
R = 255.0 * Hue_2_RGB( var_1#, var_2#, H# + ( 1.0 / 3.0 ) )
G = 255.0 * Hue_2_RGB( var_1#, var_2#, H# )
B = 255.0 * Hue_2_RGB( var_1#, var_2#, H# - ( 1.0 / 3.0 ) )
endif
color=rgb(r,g,b)
endfunction color
Function Hue_2_RGB( v1#, v2#, vH# )
if ( vH# < 0 ) then vH# = vH# + 1
if ( vH# > 1 ) then vH# = vH# - 1
if ( ( 6 * vH# ) < 1 ) then res#=( v1# + ( v2# - v1# ) * 6.0 * vH# ): exitfunction ( res# )
if ( ( 2 * vH# ) < 1 ) then exitfunction ( v2# )
if ( ( 3 * vH# ) < 2 ) then res#=( v1# + ( v2# - v1# ) * ( ( 2.0 / 3.0 ) - vH# ) * 6.0 ):exitfunction ( res# )
Endfunction v1#
edit: removed the precision argument to the str$() commands and gave the boxes slightly brighter colors.