I've got some functions for you:
Trails:
sync on : sync rate 100
`Types
type TrailType
obj as integer
segments as integer
UpdateTime as integer
texture as integer
time as integer
endtype
dim Trail(0) as TrailType
`Make a trail
box 0, 0, 200, 10, rgb(255, 0, 0), rgb(255, 0, 0), 0, 0
get image 1, 0, 0, 200, 10, 1
t = CreateTrail(1, 50, 40, 1)
do
`Update the trail
ang# = wrapvalue(ang# + 0.5)
UpdateTrail(t, 3.0*cos(ang#), 3.0*sin(ang#), 0, 7.0*cos(ang#), 7.0*sin(ang#), 0.0)
position camera 0, 0, -20
point camera 0, 0, 0
sync
loop
`function CreateTrail(obj, UpdateTime, segments, texture)
`obj: object number - trail object that will be created.
`UpdateTime: Time in ms between each update of the trail
`segments: number of segments
`texture: texture image for the trail. The front of the trail is left, the back is right.
`Description: creates a trail
function CreateTrail(obj, UpdateTime, segments, texture)
`Insert new
array insert at bottom Trail()
ind = array count(Trail())
`Set data
Trail(ind).obj = obj
Trail(ind).UpdateTime = UpdateTime
Trail(ind).segments = segments
Trail(ind).texture = texture
`Create a temporary DirectXfile
`Write a temporary DirectX file
f = 0
repeat : inc f : until file open(f) = 0
tx = segments
tz = 1
`Start with open to write
if file exist("tempTrail.x") > 0 then delete file "tempTrail.x"
open to write f, "tempTrail.x"
`Write header
write string f, "xof 0302txt 0032"
`Write export information
write string f, "//Exporter created by SvenB"
`Write material
write string f, "Material ObjMaterial {"
write string f, "1.000000; 1.000000; 1.000000; 1.000000;;"
write string f, "1.000000;"
write string f, "0.000000; 0.000000; 0.000000;;"
write string f, "0.000000; 0.000000; 0.000000;;"
write string f, "}"
write string f, ""
`ONE limb
write string f, "Mesh MyWorld {"
`Write number of VERTECES
verts = (tx+1) * (tz+1)
write string f, str$(verts) + ";"
`Write vertex positions
for z = 0 to tz
for x = 0 to tx
`calculate vertex positions
x# = 0.0
z# = 0.0
`Write vertex positions
if x = tx and z = tz
write string f, str$(x#, 6) + "; 0.000000; " + str$(z#, 6) + ";;"
else
write string f, str$(x#, 6) + "; 0.000000; " + str$(z#, 6) + ";,"
endif
next x
next z
write string f, ""
`Write number of FACES
faces = tx*tz*2
write string f, str$(faces) + ";"
for z = 0 to tz - 1
for x = 0 to tx - 1
`Get first vertex
fV = (z*(tx+1)) + x
fNV = ((z+1)*(tx+1)) + x
`Write faces
write string f, "3;" + str$(fV + 1) + "," + str$(fV) + "," + str$(fNV) + ";,"
if x = tx - 1 and z = tz - 1
write string f, "3;" + str$(fV + 1) + "," + str$(fNV) + "," + str$(fNV + 1) + ";;"
else
write string f, "3;" + str$(fV + 1) + "," + str$(fNV) + "," + str$(fNV + 1) + ";,"
endif
next x
next z
write string f, ""
`MATERIAL list
write string f, "MeshMaterialList {"
write string f, "1;"
write string f, str$(faces) + ";"
for i = 1 to faces - 1
write string f, "0,"
next i
write string f, "0;;"
write string f, "{ObjMaterial}"
write string f, "}"
`NORMAL list
write string f, "MeshNormals {"
write string f, str$(verts) + ";"
for i = 1 to verts - 1
write string f, "0.000000; 1.000000; 0.000000;,"
next i
write string f, "0.000000; 1.000000; 0.000000;;"
`Define a normal for each face
write string f, str$(faces) + ";"
for z = 0 to tz - 1
for x = 0 to tx - 1
`Get first vertex
fV = (z*(tx+1)) + x
fNV = ((z+1)*(tx+1)) + x
`Write faces
write string f, "3;" + str$(fV + 1) + "," + str$(fV) + "," + str$(fNV) + ";,"
if x = tx - 1 and z = tz - 1
write string f, "3;" + str$(fV + 1) + "," + str$(fNV) + "," + str$(fNV + 1) + ";;"
else
write string f, "3;" + str$(fV + 1) + "," + str$(fNV) + "," + str$(fNV + 1) + ";,"
endif
next x
next z
write string f, "}"
`TEXTURE coordinates
write string f, "MeshTextureCoords {"
write string f, str$(verts) + ";"
`Write vertex positions
for z = 0 to tz
for x = 0 to tx
`calculate vertex positions
x# = 0.02 + (x * 0.96 / tx)
z# = 0.02 + (z * 0.96 / tz)
`Write vertex positions
if x = tx and z = tz
write string f, str$(x#, 6) + "; " + str$(z#, 6) + ";;"
else
write string f, str$(x#, 6) + "; " + str$(z#, 6) + ";,"
endif
next x
next z
write string f, "}"
write string f, "}"
close file f
`Load the object
load object "tempTrail.x", obj
delete file "tempTrail.x"
`Setup object
set object light obj, 0
set object cull obj, 0
ghost object on obj
texture object obj, texture
endfunction ind
`function SetTrailPosition(ind, x1#, y1#, z1#, x2#, y2#, z2#)
`ind: trail index
`x1#, y1#, z1#, x2#, y2#, z2#: coordinates of the two first points of the trail
`Description: sets the whole trail to these coordinates
function SetTrailPosition(ind, x1#, y1#, z1#, x2#, y2#, z2#)
`Vertexdata
lock vertexdata for limb Trail(ind).obj, 0
`Set data
vd = get vertexdata vertex count()
for v = 0 to vd/2 - 1
set vertexdata position v, x1#, y1#, z1#
next v
for v = vd/2 to vd - 1
set vertexdata position v, x2#, y2#, z2#
next v
unlock vertexdata
endfunction
`function UpdateTrail(ind, x1#, y1#, z1#, x2#, y2#, z2#)
`ind: trail index
`x1#, y1#, z1#, x2#, y2#, z2#: coordinates of the most recent points of the trail
`Description: updates the trail.
function UpdateTrail(ind, x1#, y1#, z1#, x2#, y2#, z2#)
`Lock vertexdata
lock vertexdata for limb Trail(ind).obj, 0
vd = get vertexdata vertex count()
if timer() - Trail(ind).time > Trail(ind).UpdateTime
`Set data to previous
for v = vd to 0 step -1
if v <> 0 and v <> vd/2
set vertexdata position v, get vertexdata position x(v - 1), get vertexdata position y(v - 1), get vertexdata position z(v - 1)
endif
next v
`Reset time
Trail(ind).time = timer()
endif
`Set data from first verteces
set vertexdata position 0, x1#, y1#, z1#
set vertexdata position vd/2, x2#, y2#, z2#
endfunction
`function DeleteTrail(ind)
`ind: trail index
`Deletes a trail
function DeleteTrail(ind)
`Delete the object
delete object Trail(ind).obj
array delete element Trail(), ind
endfunction
The loop is just to show how it works.
[EDIT] It should be able to keep a list of trails using vectors...
Bezier curves:
sync on
sync rate 0
`Constants
#constant ML_Start 1
#constant ML_End 2
#constant ML_StartAnchor 3
#constant ML_EndAnchor 4
`Setup
sx# = 100 : asx# = 100
sy# = 100 : asy# = 200
ex# = 600 : aex# = 600
ey# = 600 : aey# = 500
do
cls
ink rgb(255, 255, 255)
DrawBezier(sx#, sy#, asx#, asy#, ex#, ey#, aex#, aey#, 100)
DrawBezierInfo(sx#, sy#, asx#, asy#, ex#, ey#, aex#, aey#)
if mouseclick() > 0
if MLock = 0
if mousex() < sx# + 2 and mousex() > sx# - 2 and mousey() < sy# + 2 and mousey() > sy# - 2 then MLock = ML_Start
if mousex() < ex# + 2 and mousex() > ex# - 2 and mousey() < ey# + 2 and mousey() > ey# - 2 then MLock = ML_End
if mousex() < asx# + 3 and mousex() > asx# - 3 and mousey() < asy# + 3 and mousey() > asy# - 3 then MLock = ML_StartAnchor
if mousex() < aex# + 3 and mousex() > aex# - 3 and mousey() < aey# + 3 and mousey() > aey# - 3 then MLock = ML_EndAnchor
endif
endif
if MLock > 0
if mouseclick() = 0 then MLock = 0
select MLock
case ML_Start
sx# = mousex()
sy# = mousey()
endcase
case ML_End
ex# = mousex()
ey# = mousey()
endcase
case ML_StartAnchor
asx# = mousex()
asy# = mousey()
endcase
case ML_EndAnchor
aex# = mousex()
aey# = mousey()
endcase
endselect
endif
sync
loop
`[ DrawBezier ]
`sx, sy: coord start
`asx, asy: coord start anchor
`ex, ey: coord end
`aex, aey: coord end anchor
`segm: number of segments (the higher this is, the more detailed&the slower it becomes)
function DrawBezier(sx#, sy#, asx#, asy#, ex#, ey#, aex#, aey#, segm)
`Calculate constants
cx# = 3 * (asx# - sx#)
bx# = (3 * (aex# - asx#)) - cx#
ax# = ex# - sx# - cx# - bx#
cy# = 3 * (asy# - sy#)
by# = (3 * (aey# - asy#)) - cy#
ay# = ey# - sy# - cy# - by#
`Draw
st# = 1.0 / segm
ox# = sx# + BezierFunc(ax#, bx#, cx#, 0)
oy# = sy# + BezierFunc(ay#, by#, cy#, 0)
for t = 1 to segm
t# = st# * t
nx# = sx# + BezierFunc(ax#, bx#, cx#, t#)
ny# = sy# + BezierFunc(ay#, by#, cy#, t#)
if (nx# - ox# > 1.0) or (ny# - oy# > 1.0)
line ox#, oy#, nx#, ny#
ox# = nx#
oy# = ny#
endif
next t
`To finish
line ox#, oy#, nx#, ny#
endfunction
function BezierFunc(a#, b#, c#, t#)
result# = (a# * (t# * t# * t#)) + (b# * (t# * t#)) + (c# * t#)
endfunction result#
`[ DrawBezierInfo ]
function DrawBezierInfo(sx#, sy#, asx#, asy#, ex#, ey#, aex#, aey#)
`Anchors
line sx#, sy#, asx#, asy#
line ex#, ey#, aex#, aey#
circle asx#, asy#, 5
circle aex#, aey#, 5
box sx# - 2, sy# - 2, sx# + 2, sy# + 2
box ex# - 2, ey# - 2, ex# + 2, ey# + 2
endfunction
I don't know if it'll come in handy, but anyways...
It's the programmer's life:
Have a problem, solve the problem, and have a new problem to solve.