' Version 2020-10-04
' Meta
' Hardware.
'SCREEN _NEWIMAGE(640, 480, 32)
'SCREEN _NEWIMAGE(1024, 768, 32)
' Color constants.
' Mathematical constants.
' Types.
' Scale.
bignumber = 6000000
' Cluster setup.
ClusterIndexTicker = 0
ClusterFillCounter = 0
' Group linked list setup.
GroupIdTicker = 0
' Path
PathIndexTicker = 0
' Basis vectors defined in three-space.
xhat(1) = 1: xhat(2) = 0: xhat(3) = 0
yhat(1) = 0: yhat(2) = 1: yhat(3) = 0
zhat(1) = 0: zhat(2) = 0: zhat(3) = 1
' Camera orientation vectors.
' Camera position.
' Field-of-view distance.
fovd = -192
' Clipping planes.
DIM SHARED nearplane
(4), farplane
(4), rightplane
(4), leftplane
(4), topplane
(4), bottomplane
(4) nearplane(4) = 1
farplane(4) = -180
rightplane(4) = -17 ' (10 looks better than 1.)
leftplane(4) = -17
topplane(4) = -17
bottomplane(4) = -17
' World vectors.
DIM SHARED vec
(bignumber
, 3) ' Relative Position DIM SHARED vec3Dvel
(bignumber
, 3) ' Linear velocity DIM SHARED vec3Dvis
(bignumber
) ' Visible toggle DIM SHARED vec2D
(bignumber
, 2) ' Projection onto 2D plane
' Mission.
' Interface.
' Initialize.
ToggleAnimate = 1
ToggleHUD = 1
PlayerCamera.Position.x = -40
PlayerCamera.Position.y = 30
PlayerCamera.Position.z = 40
uhat(1) = -.2078192: uhat(2) = -.9781672: uhat(3) = 0
vhat(1) = 0: vhat(2) = 0: vhat(3) = 1
CALL CalculateScreenVectors
' Prime main loop.
' Start main loop.
' Subs and Functions
a = ""
b = ""
'''
'''
MissionTicker = 0
a = MissionPool(k)
b = b + a
MissionTicker = MissionTicker + 1
Mission(MissionTicker).Label = a
Mission(MissionTicker).Discovered = 0
' Initialize linked list.
gtmp = CreateNewGroup&(0, 0, 0, 0, 0, 1)
' Atmospheric dust
FOR w
= (100 + 35 / 2) TO (800 - 35 + 35 / 2) STEP 35 gtmp = NewCube&(gtmp, "Atmospheric dust", 5 * (1 - w / 800), i, j, w, 35, 35, 35, DarkGray, White, Snow, -1)
'Black hole
z0 = 300
i = 100
j = 25
k
= SQR(u
* u
+ v
* v
+ w
* w
) gtmp = NewCube&(gtmp, "Black hole", j, x0 + u, y0 + v, z0 + w, j, j, j, DarkGray, White, Snow, -1)
CALL SetParticleVelocity
(gtmp
, -.25 * u
/ k
, -.25 * v
/ k
, -.25 * w
/ k
) gtmp = NewShell&("Singularity", 10, x0, y0, z0, Black, Black, Black, 2, 5, -1)
' Comet
PathIndexTicker = PathIndexTicker + 1
FixedPath
(PathIndexTicker
, p
).x
= .25 * COS(u
+ 2 * pi
* (24 * 60) * (p
- 1) / 86400) FixedPath
(PathIndexTicker
, p
).y
= .25 * SIN(u
+ 2 * pi
* (24 * 60) * (p
- 1) / 86400) FixedPath
(PathIndexTicker
, p
).z
= .15 * COS(u
+ 2 * pi
* (24 * 60) * (p
- 1) / 86400) x0
= 150 + (RND - .5) * 2 * 550 y0
= 150 + (RND - .5) * 2 * 550 gtmp
= NewCube&
(gtmp
, "Comet" + STR$(n
), 300, x0
, y0
, z0
, 25, 25, 25, Teal
, Cyan
, DodgerBlue
, PathIndexTicker
) FOR k
= Group
(gtmp
).FirstVector
TO Group
(gtmp
).LastVector
vec3Dvel
(k
, 1) = (RND - .5) * .20 vec3Dvel
(k
, 2) = (RND - .5) * .20 vec3Dvel
(k
, 3) = (RND - .5) * .20 gtmp
= NewShell&
("Comet" + STR$(n
), 15, x0
, y0
, z0
, Teal
, Cyan
, DodgerBlue
, 1, 80, PathIndexTicker
)
' Demon orb
PathIndexTicker = PathIndexTicker + 1
FixedPath
(PathIndexTicker
, p
).x
= .25 * COS(u
+ 2 * pi
* (24 * 60) * (p
- 1) / 86400) FixedPath
(PathIndexTicker
, p
).y
= .25 * SIN(u
+ 2 * pi
* (24 * 60) * (p
- 1) / 86400) FixedPath
(PathIndexTicker
, p
).z
= .15 * COS(u
+ 2 * pi
* (24 * 60) * (p
- 1) / 86400) x0
= (RND - .5) * 2 * 1000 y0
= (RND - .5) * 2 * 1000 gtmp = NewCube&(gtmp, "Demon orb", 300, x0, y0, z0, 25, 25, 25, Red, SunsetOrange, Sunglow, PathIndexTicker)
FOR k
= Group
(gtmp
).FirstVector
TO Group
(gtmp
).LastVector
vec3Dvel
(k
, 1) = (RND - .5) * .20 vec3Dvel
(k
, 2) = (RND - .5) * .20 vec3Dvel
(k
, 3) = (RND - .5) * .20 gtmp = NewShell&("Demon orb", 15, x0, y0, z0, Red, SunsetOrange, Sunglow, 1, 80, PathIndexTicker)
' Death Star
PathIndexTicker = PathIndexTicker + 1
FixedPath
(PathIndexTicker
, p
).x
= -.1 * COS(2 * pi
* (24 * 60) * (p
- 1) / 86400) FixedPath
(PathIndexTicker
, p
).y
= -.1 * SIN(2 * pi
* (24 * 60) * (p
- 1) / 86400) FixedPath(PathIndexTicker, p).z = 0
x0
= 100 + (RND - .5) * 2 * 250 y0
= 100 + (RND - .5) * 2 * 250 gtmp = NewShell&("Death Star", 75, x0, y0, 400, Gray, DarkGray, White, 0, 0, PathIndexTicker)
gtmp = NewShell&("Death Star reactor", 15, x0, y0, 400, Cyan, Teal, Blue, 1, 20, PathIndexTicker)
gtmp = NewCube&(gtmp, "Plasma core", 300, x0, y0, 400, 25, 25, 25, Cyan, Teal, Blue, PathIndexTicker)
FOR p
= Group
(gtmp
).FirstVector
TO Group
(gtmp
).LastVector
vec3Dvel
(p
, 1) = (RND - .5) * .20 vec3Dvel
(p
, 2) = (RND - .5) * .20 vec3Dvel
(p
, 3) = (RND - .5) * .20 gtmp
= NewCube&
(gtmp
, "Laser", 300, x0
+ 75 / SQR(2) + (n
- 1) * 25, y0
+ .5 * n
* 25, 400 + 75 / SQR(2) + .5 * (n
- 1) * 25, 25, 25, 25, Lime
, Green
, White
, PathIndexTicker
) FOR p
= Group
(gtmp
).FirstVector
TO Group
(gtmp
).LastVector
vec3Dvel
(p
, 1) = (RND - .5) * .50 vec3Dvel
(p
, 2) = (RND - .5) * .50 vec3Dvel
(p
, 3) = (RND - .5) * .50
' Dirt and sand
gtmp = NewCube&(gtmp, "Dirt and sand", 5, i, j, w, 35, 35, 35, SaddleBrown, DarkKhaki, Sienna, -1)
' Grave and Pyramid (1/2)
gtmp = NewCube&(gtmp, "Grave", 200, u, v, (1) * 10 - 10 / 2, 10, 10, 10, Gray, SlateGray, DarkGray, -1)
gtmp = NewCube&(gtmp, "Grave", 200, u, v, (2) * 10 - 10 / 2, 10, 10, 10, Gray, SlateGray, DarkGray, -1)
gtmp = NewCube&(gtmp, "Grave", 200, u, v, (3) * 10 - 10 / 2, 10, 10, 10, Gray, SlateGray, DarkGray, -1)
gtmp = NewCube&(gtmp, "Grave", 200, u - 10, v, (4) * 10 - 10 / 2, 10, 10, 10, Gray, SlateGray, DarkGray, -1)
gtmp = NewCube&(gtmp, "Grave", 200, u, v, (4) * 10 - 10 / 2, 10, 10, 10, Gray, SlateGray, DarkGray, -1)
gtmp = NewCube&(gtmp, "Grave", 200, u + 10, v, (4) * 10 - 10 / 2, 10, 10, 10, Gray, SlateGray, DarkGray, -1)
gtmp = NewCube&(gtmp, "Grave", 200, u, v, (5) * 10 - 10 / 2, 10, 10, 10, Gray, SlateGray, DarkGray, -1)
' Grave and Pyramid (2/2)
k = k + pi
gtmp = NewCube&(gtmp, "Pyramid", 35, x0 + u, y0 + v, w, 13, 13, 13, DarkKhaki, SunsetOrange, DarkGoldenRod, -1)
' Hell Sparks
gtmp = NewCube&(gtmp, "Hell sparks", 15, i, j, -850, 35, 35, 100, Red, SunsetOrange, Sunglow, -1)
CALL SetParticleVelocity
(gtmp
, 0, 0, .75 + RND * .25)
' Lake of Fire
gtmp = NewTerrain&("Lake of Fire", 2800, 2800, 35, 0, 0, -900, Red, SunsetOrange, Sunglow, 4, 30)
' Planet
PathIndexTicker = PathIndexTicker + 1
FixedPath
(PathIndexTicker
, p
).x
= .1 * COS(2 * pi
* (24 * 60) * (p
- 1) / 86400) FixedPath
(PathIndexTicker
, p
).y
= .1 * SIN(2 * pi
* (24 * 60) * (p
- 1) / 86400) FixedPath(PathIndexTicker, p).z = 0
x0
= 100 + (RND - .5) * 2 * 250 y0
= 100 + (RND - .5) * 2 * 250 gtmp = NewPlanet&(350, 35, x0, y0, 900, PathIndexTicker)
' Rain
IF (u
* u
+ v
* v
<= 350 ^ 2) THEN gtmp = NewCube&(gtmp, "Rain", 15, u, v, 50, 35, 35, 100, Blue, DodgerBlue, Blue, -1)
CALL SetParticleVelocity
(gtmp
, 0, 0, -.75 - RND * .25)
' Realm of Heaven
gtmp = NewTerrain&("Realm of Heaven", 2800, 2800, 35, 0, 0, 1400, BlueViolet, Cyan, White, 4, 30)
' Sky and Terrain
gtmp = NewTerrain&("Cloudy sky", 1400, 1400, 35, 0, 0, 100, RoyalBlue, DarkGray, Snow, 4, 30)
gtmp = NewTerrain&("Lush terrain", 1400, 1400, 35, 0, 0, 0, Green, LightSeaGreen, Blue, 4, 30)
gtmp = NewTerrain&("Northern desert sand", 2100, 700, 35, 350, 700 + 350 + 35, 0, DarkKhaki, PaleGoldenRod, Sunglow, 4, 30)
gtmp = NewTerrain&("Northern desert sky", 2100, 700, 35, 350, 700 + 350 + 35, 100, RoyalBlue, DarkGray, Indigo, 4, 30)
gtmp = NewTerrain&("Southern desert sand", 2100, 700, 35, -350, -700 - 350 - 35, 0, DarkKhaki, PaleGoldenRod, Sunglow, 4, 30)
gtmp = NewTerrain&("Southern desert sky", 2100, 700, 35, -350, -700 - 350 - 35, 100, RoyalBlue, DarkGray, Indigo, 4, 30)
gtmp = NewTerrain&("Eastern desert sand", 700, 2100, 35, 700 + 350 + 35, -350, 0, DarkKhaki, PaleGoldenRod, Sunglow, 4, 30)
gtmp = NewTerrain&("Eastern desert sky", 700, 2100, 35, 700 + 350 + 35, -350, 100, RoyalBlue, DarkGray, Indigo, 4, 30)
gtmp = NewTerrain&("Western desert sand", 700, 2100, 35, -700 - 350 - 35, 350, 0, DarkKhaki, PaleGoldenRod, Sunglow, 4, 30)
gtmp = NewTerrain&("Western desert sky", 700, 2100, 35, -700 - 350 - 35, 350, 100, RoyalBlue, DarkGray, Indigo, 4, 30)
' Tornado
PathIndexTicker = PathIndexTicker + 1
FixedPath
(PathIndexTicker
, p
).x
= 1 * COS(u
+ 2 * pi
* (24 * 60) * (p
- 1) / 86400) FixedPath
(PathIndexTicker
, p
).y
= 1 * SIN(u
+ 2 * pi
* (24 * 60) * (p
- 1) / 86400) FixedPath(PathIndexTicker, p).z = 0
x0
= (RND - .5) * 2 * 750 y0
= (RND - .5) * 2 * 750 gtmp
= NewCube&
(gtmp
, "Tornado" + STR$(n
), 35, x0
+ v
* COS(w
), y0
+ v
* SIN(w
), u
, 15, 15, 15, DarkGray
, SunsetOrange
, DarkGoldenRod
, PathIndexTicker
) CALL SetParticleVelocity
(gtmp
, -SIN(w
), COS(w
), 0)
' Stellar dust
gtmp = NewCube&(gtmp, "Stellar dust", 15, i, j, 1350, 35, 35, 100, BlueViolet, Cyan, White, -1)
CALL SetParticleVelocity
(gtmp
, 0, 0, -.75 - RND * .25)
''' Rocket
gtmp = NewCube&(gtmp, "Rocket", 200, 0, 0, 0, 15, 15, 35, Green, Green, Green, 0)
gtmp = NewCube&(gtmp, "Rocket", 200, 0, 0, 0, 15, 15, 15, Red, Red, Red, 0)
Cluster(ClusterIndexTicker).Velocity.x = 0
Cluster(ClusterIndexTicker).Velocity.y = 0
Cluster(ClusterIndexTicker).Velocity.z = 1
'PRINT
'PRINT "Total clusters: " + STR$(ClusterIndexTicker)
'PRINT "Total groups: " + STR$(GroupIdTicker)
'PRINT "Total particles: " + STR$(Group(gtmp).LastVector)
'_DISPLAY
'SLEEP 5
fps = 0
CALL CalculateScreenVectors
fps = fps + 1
fpstimer = tt
FPSReport = fps
fps = 0
' Elevated-order primitive group.
FOR rtemp
= ChunkSize
TO TheRadius
STEP ChunkSize
r
= SQR(u
* u
+ v
* v
+ w
* w
) IF r
<= rtemp
AND r
>= rtemp
- ChunkSize
THEN ShadeA = Gradient~&(Red, SaddleBrown, r / TheRadius)
ShadeB = Gradient~&(SunsetOrange, DarkKhaki, r / TheRadius)
ShadeC = DarkKhaki
gtmp = NewCube&(1, "Planet Interior", ChunkSize, PosX + u, PosY + v, PosZ + w, ChunkSize, ChunkSize, ChunkSize, ShadeA, ShadeB, ShadeC, TheDynamic)
Group(gtmp).GroupName = "Planet center"
CALL SetParticleVelocity
(gtmp
, .25 * u
/ r
, .25 * v
/ r
, .25 * w
/ r
) gtmp = NewShell&("Planet surface", TheRadius, PosX, PosY, PosZ, Green, DarkKhaki, DodgerBlue, 2, 20, TheDynamic)
gtmp = NewShell&("Planet core", TheRadius / 10, PosX, PosY, PosZ, Red, Yellow, DarkGoldenRod, 2, 5, TheDynamic)
FOR w
= 0 + ChunkSize
/ 4 TO PosZ
- TheRadius
- ChunkSize
/ 4 STEP ChunkSize
/ 2 gtmp = NewCube&(1, "Planet column", 2 * ChunkSize, PosX, PosY, w, ChunkSize / 2, ChunkSize / 2, ChunkSize / 2, Cyan, Teal, Blue, TheDynamic)
CALL SetParticleVelocity
(gtmp
, .15 * (RND - .5), .15 * (RND - .5), .25 * RND) NewPlanet& = gtmp
' Medium-order primitive group(s).
FUNCTION NewTerrain&
(TheName
AS STRING, SizeX
AS DOUBLE, SizeY
AS DOUBLE, TheResolution
AS DOUBLE, PosX
AS DOUBLE, PosY
AS DOUBLE, PosZ
AS DOUBLE, ShadeA
AS _UNSIGNED LONG, ShadeB
AS _UNSIGNED LONG, ShadeC
AS _UNSIGNED LONG, BumpFactor
AS DOUBLE, SmoothFactor
AS INTEGER)
factor1 = TheResolution
factor2 = factor1 / 10
wi = 0
wj = 0
wa = 0
wb = 0
wi = wi + 1
wj = wj + 1
wa = wa + 1
wb = wb + 1
vgrid
(ia
, jb
, 1) = factor1
* RND vgrid(ia, jb, 2) = 1
vgrid
(ia
, jb
, 1) = -factor1
* RND / 2 vgrid(ia, jb, 2) = 1
vgrid(ia, jb, 1) = 0
vgrid(ia, jb, 2) = 0
FOR k
= 1 TO SmoothFactor
vgrid2(ia, jb) = vgrid(ia, jb, 1)
FOR ia
= 1 + 1 TO wi
* wa
- 1 FOR jb
= 1 + 1 TO wj
* wb
- 1 IF (k
= SmoothFactor
- 5) THEN vgrid(ia, jb, 2) = 0
vgrid(ia, jb, 1) = (1 / 4) * (vgrid2(ia - 1, jb) + vgrid2(ia + 1, jb) + vgrid2(ia, jb - 1) + vgrid2(ia, jb + 1))
ci = 0
cj = 0
ca = 0
cb = 0
g = 1
ci = ci + 1
cj = 0
cj = cj + 1
u = i
v = j
w = 0
q = LatestIdentity&(g)
vindex = Group(q).LastVector
g = CreateNewGroup&(q, PosX + u, PosY + v, PosZ + w, 0, 24)
Group(g).GroupName = TheName
Group(g).Volume.x = SizeX
Group(g).Volume.y = SizeY
Group
(g
).Volume.z
= SQR(SizeX
* SizeX
+ SizeY
* SizeY
) Group(g).FirstVector = vindex + 1
ca = 0
ca = ca + 1
cb = 0
cb = cb + 1
rr = vgrid((ci - 1) * wa + ca, (cj - 1) * wb + cb, 1)
vindex = vindex + 1
vec3Dpos
(vindex
, 1) = -u
+ a
+ BumpFactor
* (RND - .5) vec3Dpos
(vindex
, 2) = -v
+ b
+ BumpFactor
* (RND - .5) vec3Dpos
(vindex
, 3) = -w
+ rr
+ BumpFactor
* (RND - .5) vec3Dcolor(vindex) = Gradient~&(ShadeA, ShadeB, rr / 10)
vec3Dcolor(vindex) = ShadeC
Group(g).LastVector = vindex
NewTerrain& = g
FUNCTION NewShell&
(TheName
AS STRING, TheRadius
AS DOUBLE, PosX
AS DOUBLE, PosY
AS DOUBLE, PosZ
AS DOUBLE, ShadeA
AS _UNSIGNED LONG, ShadeB
AS _UNSIGNED LONG, ShadeC
AS _UNSIGNED LONG, BumpFactor
AS DOUBLE, SmoothFactor
AS INTEGER, TheDynamic
AS INTEGER)
factor1
= (2) * 2 * pi
/ (10 ^ (INT(LOG(TheRadius
) / LOG(10)))) factor1
= (1) * 2 * pi
/ (10 ^ (INT(LOG(TheRadius
) / LOG(10)))) factor2 = factor1 / (10)
wi = 0
wj = 0
wa = 0
wb = 0
wi = wi + 1
wj = wj + 1
wa = wa + 1
wb = wb + 1
vgrid(ia, jb, 1) = TheRadius - BumpFactor * (TheRadius / 50)
vgrid(ia, jb, 2) = 1
vgrid(ia, jb, 1) = TheRadius + BumpFactor * (TheRadius / 50)
vgrid(ia, jb, 2) = 1
vgrid(ia, jb, 1) = TheRadius
vgrid(ia, jb, 2) = 0
FOR k
= 1 TO SmoothFactor
vgrid2(ia, jb) = vgrid(ia, jb, 1)
FOR ia
= 1 + 1 TO wi
* wa
- 1 FOR jb
= 1 + 1 TO wj
* wb
- 1 IF (k
= SmoothFactor
- 5) THEN vgrid(ia, jb, 2) = 0
vgrid(ia, jb, 1) = (1 / 4) * (vgrid2(ia - 1, jb) + vgrid2(ia + 1, jb) + vgrid2(ia, jb - 1) + vgrid2(ia, jb + 1))
ci = 0
cj = 0
ca = 0
cb = 0
g = 1
ci = ci + 1
cj = 0
cj = cj + 1
u
= TheRadius
* SIN(j
) * COS(i
) v
= TheRadius
* SIN(j
) * SIN(i
) q = LatestIdentity&(g)
vindex = Group(q).LastVector
g = CreateNewGroup&(q, PosX + u, PosY + v, PosZ + w, TheDynamic, 64)
Group(g).GroupName = TheName
Group(g).Volume.x = TheRadius
Group(g).Volume.y = TheRadius
Group(g).Volume.z = TheRadius
Group(g).FirstVector = vindex + 1
ca = 0
ca = ca + 1
cb = 0
cb = cb + 1
rr = vgrid((ci - 1) * wa + ca, (cj - 1) * wb + cb, 1)
vindex = vindex + 1
vec3Dpos
(vindex
, 1) = -u
+ rr
* SIN(b
) * COS(a
) + BumpFactor
* (RND - .5) * 2 vec3Dpos
(vindex
, 2) = -v
+ rr
* SIN(b
) * SIN(a
) + BumpFactor
* (RND - .5) * 2 vec3Dpos
(vindex
, 3) = -w
+ rr
* COS(b
) + BumpFactor
* (RND - .5) * 2 vec3Dcolor
(vindex
) = Gradient~&
(ShadeA
, ShadeB
, COS(j
) ^ 2) vec3Dcolor(vindex) = ShadeC
Group(g).LastVector = vindex
NewShell& = g
' Low-order primitive group(s).
FUNCTION NewCube&
(StartingIdentity
AS LONG, TheName
AS STRING, Weight
AS INTEGER, PosX
AS DOUBLE, PosY
AS DOUBLE, PosZ
AS DOUBLE, VolX
AS DOUBLE, VolY
AS DOUBLE, VolZ
AS DOUBLE, ShadeA
AS _UNSIGNED LONG, ShadeB
AS _UNSIGNED LONG, ShadeC
AS _UNSIGNED LONG, TheDynamic
AS INTEGER) q = LatestIdentity&(StartingIdentity)
vindex = Group(q).LastVector
g = CreateNewGroup(q, PosX, PosY, PosZ, TheDynamic, 64)
Group(g).GroupName = TheName
Group(g).Volume.x = VolX
Group(g).Volume.y = VolY
Group(g).Volume.z = VolZ
Group(g).FirstVector = vindex + 1
vindex = vindex + 1
vec3Dpos
(vindex
, 1) = (RND - .5) * VolX
vec3Dpos
(vindex
, 2) = (RND - .5) * VolY
vec3Dpos
(vindex
, 3) = (RND - .5) * VolZ
vec3Dcolor(vindex) = ShadeA
vec3Dcolor(vindex) = ShadeB
vec3Dcolor(vindex) = ShadeC
Group(g).LastVector = vindex
NewCube& = g
' Linked list utility.
p = StartingID
q = p
p = Group(q).Pointer
TheReturn = q
LatestIdentity& = TheReturn
GroupIdTicker = GroupIdTicker + 1
Group(GroupIdTicker).Identity = GroupIdTicker
Group(GroupIdTicker).Pointer = -999
Group(GroupIdTicker).Lagger = TheLaggerIn
Group(GroupIdTicker).Centroid.x = CenterX
Group(GroupIdTicker).Centroid.y = CenterY
Group(GroupIdTicker).Centroid.z = CenterZ
Group(TheLaggerIn).Pointer = Group(GroupIdTicker).Identity
'''
ClusterFillCounter = ClusterFillCounter + 1
IF (ClusterFillCounter
= 1) THEN ClusterIndexTicker = ClusterIndexTicker + 1
Cluster(ClusterIndexTicker).FirstGroup = Group(GroupIdTicker).Identity
Cluster(ClusterIndexTicker).MotionType = TheDynamic
IF (ClusterFillCounter
= ClusterSize
) THEN CALL ClusterPinch
(Group
(GroupIdTicker
).Identity
) '''
CreateNewGroup& = Group(GroupIdTicker).Identity
ClusterFillCounter = 0
Cluster(ClusterIndexTicker).LastGroup = TheLastGroup
CALL ClusterCentroidCalc
(ClusterIndexTicker
)
SUB ClusterCentroidCalc
(TheClusterIndex
AS LONG) Cluster(TheClusterIndex).Centroid.x = 0
Cluster(TheClusterIndex).Centroid.y = 0
Cluster(TheClusterIndex).Centroid.z = 0
k = Cluster(TheClusterIndex).FirstGroup
n = 0
Cluster(TheClusterIndex).Centroid.x = Cluster(TheClusterIndex).Centroid.x + Group(k).Centroid.x
Cluster(TheClusterIndex).Centroid.y = Cluster(TheClusterIndex).Centroid.y + Group(k).Centroid.y
Cluster(TheClusterIndex).Centroid.z = Cluster(TheClusterIndex).Centroid.z + Group(k).Centroid.z
n = n + 1
k = Group(k).Pointer
Cluster(TheClusterIndex).Centroid.x = Cluster(TheClusterIndex).Centroid.x / n
Cluster(TheClusterIndex).Centroid.y = Cluster(TheClusterIndex).Centroid.y / n
Cluster(TheClusterIndex).Centroid.z = Cluster(TheClusterIndex).Centroid.z / n
' Vector manipulation.
m = Group(TheGroup).FirstVector
n = Group(TheGroup).LastVector
vec3Dvel(j, 1) = vx
vec3Dvel(j, 2) = vy
vec3Dvel(j, 3) = vz
' Cluster manipulation.
IF (Cluster
(TheClusterIndex
).MotionType
= 0) THEN dx = Cluster(TheClusterIndex).Velocity.x
dy = Cluster(TheClusterIndex).Velocity.y
dz = Cluster(TheClusterIndex).Velocity.z
v = t - u
dx = v * FixedPath(Cluster(TheClusterIndex).MotionType, u).x + (1 - v) * FixedPath(Cluster(TheClusterIndex).MotionType, u - 1).x
dy = v * FixedPath(Cluster(TheClusterIndex).MotionType, u).y + (1 - v) * FixedPath(Cluster(TheClusterIndex).MotionType, u - 1).y
dz = v * FixedPath(Cluster(TheClusterIndex).MotionType, u).z + (1 - v) * FixedPath(Cluster(TheClusterIndex).MotionType, u - 1).z
CALL TranslateCluster
(TheClusterIndex
, dx
, dy
, dz
)
k = Cluster(TheClusterIndex).FirstGroup
Group(k).Centroid.x = Group(k).Centroid.x + dx
Group(k).Centroid.y = Group(k).Centroid.y + dy
Group(k).Centroid.z = Group(k).Centroid.z + dz
k = Group(k).Pointer
Cluster(TheClusterIndex).Centroid.x = Cluster(TheClusterIndex).Centroid.x + dx
Cluster(TheClusterIndex).Centroid.y = Cluster(TheClusterIndex).Centroid.y + dy
Cluster(TheClusterIndex).Centroid.z = Cluster(TheClusterIndex).Centroid.z + dz
' Particle manipulation.
xdim = Group(TheGroup).Volume.x
ydim = Group(TheGroup).Volume.y
zdim = Group(TheGroup).Volume.z
FOR k
= Group
(TheGroup
).FirstVector
TO Group
(TheGroup
).LastVector
' Position update with periodic boundaries inside group volume
dx = 1 * vec3Dvel(k, 1)
dy = 1 * vec3Dvel(k, 2)
dz = 1 * vec3Dvel(k, 3)
px = vec3Dpos(k, 1) + dx
px = -xdim / 2
px = xdim / 2
vec3Dpos(k, 1) = px
py = vec3Dpos(k, 2) + dy
py = -ydim / 2
py = ydim / 2
vec3Dpos(k, 2) = py
pz = vec3Dpos(k, 3) + dz
pz = -zdim / 2
pz = zdim / 2
vec3Dpos(k, 3) = pz
SUB CalculateScreenVectors
uhatmag
= SQR(uhat
(1) * uhat
(1) + uhat
(2) * uhat
(2) + uhat
(3) * uhat
(3)) uhat(1) = uhat(1) / uhatmag: uhat(2) = uhat(2) / uhatmag: uhat(3) = uhat(3) / uhatmag
vhatmag
= SQR(vhat
(1) * vhat
(1) + vhat
(2) * vhat
(2) + vhat
(3) * vhat
(3)) vhat(1) = vhat(1) / vhatmag: vhat(2) = vhat(2) / vhatmag: vhat(3) = vhat(3) / vhatmag
uhatdotvhat = uhat(1) * vhat(1) + uhat(2) * vhat(2) + uhat(3) * vhat(3)
nhat(1) = uhat(2) * vhat(3) - uhat(3) * vhat(2)
nhat(2) = uhat(3) * vhat(1) - uhat(1) * vhat(3)
nhat(3) = uhat(1) * vhat(2) - uhat(2) * vhat(1)
nearplane(1) = -nhat(1)
nearplane(2) = -nhat(2)
nearplane(3) = -nhat(3)
farplane(1) = nhat(1)
farplane(2) = nhat(2)
farplane(3) = nhat(3)
rightplane(1) = h2 * fovd * uhat(1) - h2 * w2 * nhat(1)
rightplane(2) = h2 * fovd * uhat(2) - h2 * w2 * nhat(2)
rightplane(3) = h2 * fovd * uhat(3) - h2 * w2 * nhat(3)
mag
= SQR(rightplane
(1) * rightplane
(1) + rightplane
(2) * rightplane
(2) + rightplane
(3) * rightplane
(3)) rightplane(1) = rightplane(1) / mag
rightplane(2) = rightplane(2) / mag
rightplane(3) = rightplane(3) / mag
leftplane(1) = -h2 * fovd * uhat(1) - h2 * w2 * nhat(1)
leftplane(2) = -h2 * fovd * uhat(2) - h2 * w2 * nhat(2)
leftplane(3) = -h2 * fovd * uhat(3) - h2 * w2 * nhat(3)
mag
= SQR(leftplane
(1) * leftplane
(1) + leftplane
(2) * leftplane
(2) + leftplane
(3) * leftplane
(3)) leftplane(1) = leftplane(1) / mag
leftplane(2) = leftplane(2) / mag
leftplane(3) = leftplane(3) / mag
topplane(1) = w2 * fovd * vhat(1) - h2 * w2 * nhat(1)
topplane(2) = w2 * fovd * vhat(2) - h2 * w2 * nhat(2)
topplane(3) = w2 * fovd * vhat(3) - h2 * w2 * nhat(3)
mag
= SQR(topplane
(1) * topplane
(1) + topplane
(2) * topplane
(2) + topplane
(3) * topplane
(3)) topplane(1) = topplane(1) / mag
topplane(2) = topplane(2) / mag
topplane(3) = topplane(3) / mag
bottomplane(1) = -w2 * fovd * vhat(1) - h2 * w2 * nhat(1)
bottomplane(2) = -w2 * fovd * vhat(2) - h2 * w2 * nhat(2)
bottomplane(3) = -w2 * fovd * vhat(3) - h2 * w2 * nhat(3)
mag
= SQR(bottomplane
(1) * bottomplane
(1) + bottomplane
(2) * bottomplane
(2) + bottomplane
(3) * bottomplane
(3)) bottomplane(1) = bottomplane(1) / mag
bottomplane(2) = bottomplane(2) / mag
bottomplane(3) = bottomplane(3) / mag
FOR i
= Group
(TheGroup
).FirstVector
TO Group
(TheGroup
).LastVector
vec(i, 1) = Group(TheGroup).Centroid.x + vec3Dpos(i, 1) - PlayerCamera.Position.x
vec(i, 2) = Group(TheGroup).Centroid.y + vec3Dpos(i, 2) - PlayerCamera.Position.y
vec(i, 3) = Group(TheGroup).Centroid.z + vec3Dpos(i, 3) - PlayerCamera.Position.z
f = -1
vec3Dvis(i) = 0
vectorinview = 1
IF vec
(i
, 1) * nearplane
(1) + vec
(i
, 2) * nearplane
(2) + vec
(i
, 3) * nearplane
(3) - nearplane
(4) < 0 THEN vectorinview
= 0 'IF vec(i, 1) * farplane(1) + vec(i, 2) * farplane(2) + vec(i, 3) * farplane(3) - farplane(4) < 0 THEN vectorinview = 0
IF vec
(i
, 1) * farplane
(1) + vec
(i
, 2) * farplane
(2) + vec
(i
, 3) * farplane
(3) - farplane
(4) * .85 < 0 THEN f
= 1 'IF vec(i, 1) * rightplane(1) + vec(i, 2) * rightplane(2) + vec(i, 3) * rightplane(3) - rightplane(4) < 0 THEN vectorinview = 0
'IF vec(i, 1) * leftplane(1) + vec(i, 2) * leftplane(2) + vec(i, 3) * leftplane(3) - leftplane(4) < 0 THEN vectorinview = 0
'IF vec(i, 1) * topplane(1) + vec(i, 2) * topplane(2) + vec(i, 3) * topplane(3) - topplane(4) < 0 THEN vectorinview = 0
'IF vec(i, 1) * bottomplane(1) + vec(i, 2) * bottomplane(2) + vec(i, 3) * bottomplane(3) - bottomplane(4) < 0 THEN vectorinview = 0
vec3Dvis(i) = 1
vec3Ddotnhat = vec(i, 1) * nhat(1) + vec(i, 2) * nhat(2) + vec(i, 3) * nhat(3)
vec2D(i, 1) = (vec(i, 1) * uhat(1) + vec(i, 2) * uhat(2) + vec(i, 3) * uhat(3)) * fovd / vec3Ddotnhat
vec2D(i, 2) = (vec(i, 1) * vhat(1) + vec(i, 2) * vhat(2) + vec(i, 3) * vhat(3)) * fovd / vec3Ddotnhat
vec2Dcolor(i) = Gray
vec2Dcolor(i) = vec3Dcolor(i)
' TheDynamics
ClosestGroup = 1
closestdist2 = 10000000
fp42 = farplane(4) * farplane(4)
FOR i
= 1 TO ClusterIndexTicker
dx = Cluster(i).Centroid.x - PlayerCamera.Position.x
dy = Cluster(i).Centroid.y - PlayerCamera.Position.y
dz = Cluster(i).Centroid.z - PlayerCamera.Position.z
dist2 = dx * dx + dy * dy + dz * dz
Cluster(i).Visible = 0
IF (Cluster
(i
).MotionType
> -1) THEN Cluster(i).Visible = 1
k = Cluster(i).FirstGroup
IF ((Cluster
(i
).MotionType
> -1) AND (ToggleAnimate
= 1)) THEN dx = Group(k).Centroid.x - PlayerCamera.Position.x
dy = Group(k).Centroid.y - PlayerCamera.Position.y
dz = Group(k).Centroid.z - PlayerCamera.Position.z
dist2 = dx * dx + dy * dy + dz * dz
Group(k).Visible = 0
GroupInView = 1
IF dx
* nearplane
(1) + dy
* nearplane
(2) + dz
* nearplane
(3) - nearplane
(4) < 0 THEN GroupInView
= 0 'IF dx * farplane(1) + dy * farplane(2) + dz * farplane(3) - farplane(4) < 0 THEN groupinview = 0 ''' Redundant
IF dx
* rightplane
(1) + dy
* rightplane
(2) + dz
* rightplane
(3) - rightplane
(4) < 0 THEN GroupInView
= 0 IF dx
* leftplane
(1) + dy
* leftplane
(2) + dz
* leftplane
(3) - leftplane
(4) < 0 THEN GroupInView
= 0 IF dx
* topplane
(1) + dy
* topplane
(2) + dz
* topplane
(3) - topplane
(4) < 0 THEN GroupInView
= 0 IF dx
* bottomplane
(1) + dy
* bottomplane
(2) + dz
* bottomplane
(3) - bottomplane
(4) < 0 THEN GroupInView
= 0 Group(k).Visible = 1
IF (dist2
< closestdist2
) THEN closestdist2 = dist2
ClosestGroup = k
Group(k).Distance2 = dist2
IF (ToggleAnimate
= 1) THEN CALL EvolveParticles
(k
) k = Group(k).Pointer
' Graphics
NumClusterVisible = 0
NumVectorVisible = 0
SortedGroupsCount = 0
FOR i
= 1 TO ClusterIndexTicker
IF (Cluster
(i
).Visible
= 1) THEN NumClusterVisible = NumClusterVisible + 1
k = Cluster(i).FirstGroup
IF (Group
(k
).Visible
= 1) THEN SortedGroupsCount = SortedGroupsCount + 1
SortedGroups(SortedGroupsCount) = k
k = Group(k).Pointer
NumGroupVisible = SortedGroupsCount
' Bubble sort might be a shitty choice but it works for now. Replace with quicksort prolly.
FOR i
= 2 TO SortedGroupsCount
- 1 a = Group(SortedGroups(i - 1)).Distance2
b = Group(SortedGroups(i)).Distance2
c = SortedGroups(i - 1)
d = SortedGroups(i)
SortedGroups(i - 1) = d
SortedGroups(i) = c
PlayerCamera.Shade = AverageShadeMix~&(vec3Dcolor(Group(ClosestGroup).FirstVector), PlayerCamera.Shade, .01)
FOR j
= 1 TO SortedGroupsCount
k = SortedGroups(j)
FOR i
= Group
(k
).FirstVector
TO Group
(k
).LastVector
- 1 NumVectorVisible = NumVectorVisible + 1
clrtmp = Yellow
clrtmp = vec2Dcolor(i)
x1 = vec2D(i, 1)
y1 = vec2D(i, 2)
x2 = vec2D(i + 1, 1)
y2 = vec2D(i + 1, 2)
IF (((x2
- x1
) * (x2
- x1
) + (y2
- y1
) * (y2
- y1
)) < 225) THEN CALL cline
(x1
, y1
, x2
, y2
, clrtmp
) CALL ccircle
(x1
, y1
, 1, clrtmp
)
CALL cline
(0, 0, 25 * (xhat
(1) * uhat
(1) + xhat
(2) * uhat
(2) + xhat
(3) * uhat
(3)), 25 * (xhat
(1) * vhat
(1) + xhat
(2) * vhat
(2) + xhat
(3) * vhat
(3)), _RGBA(255, 0, 0, 200)) CALL cline
(0, 0, 25 * (yhat
(1) * uhat
(1) + yhat
(2) * uhat
(2) + yhat
(3) * uhat
(3)), 25 * (yhat
(1) * vhat
(1) + yhat
(2) * vhat
(2) + yhat
(3) * vhat
(3)), _RGBA(0, 255, 0, 200)) CALL cline
(0, 0, 25 * (zhat
(1) * uhat
(1) + zhat
(2) * uhat
(2) + zhat
(3) * uhat
(3)), 25 * (zhat
(1) * vhat
(1) + zhat
(2) * vhat
(2) + zhat
(3) * vhat
(3)), _RGBA(30, 144, 255, 200)) 'COLOR LimeGreen
'_PRINTSTRING ((1) * 8, (9) * 16), "View"
'COLOR DarkKhaki
'_PRINTSTRING ((1) * 8, (9) * 16), "FPS: " + LTRIM$(RTRIM$(STR$(FPSReport))) + "/30"
'_PRINTSTRING ((1) * 8, (10) * 16), "Clusters: " + LTRIM$(RTRIM$(STR$(NumClusterVisible)))
'_PRINTSTRING ((1) * 8, (11) * 16), "Groups: " + LTRIM$(RTRIM$(STR$(NumGroupVisible)))
'_PRINTSTRING ((1) * 8, (12) * 16), "Particles: " + LTRIM$(RTRIM$(STR$(NumVectorVisible)))
FOR k
= 1 TO MissionTicker
a = " " + Mission(k).Label + " "
IF (Mission
(k
).Discovered
= 0) THEN a = " - Closest - "
a = " SPACE = Hide "
a = " " + Group(ClosestGroup).GroupName + " "
' Interface
CALL StrafeCameraNhatMinus
PlayerCamera.Velocity.x = PlayerCamera.Velocity.x - .05 * nhat(1)
PlayerCamera.Velocity.y = PlayerCamera.Velocity.y - .05 * nhat(2)
PlayerCamera.Velocity.z = PlayerCamera.Velocity.z - .05 * nhat(3)
CALL StrafeCameraNhatPlus
PlayerCamera.Velocity.x = PlayerCamera.Velocity.x + .05 * nhat(1)
PlayerCamera.Velocity.y = PlayerCamera.Velocity.y + .05 * nhat(2)
PlayerCamera.Velocity.z = PlayerCamera.Velocity.z + .05 * nhat(3)
CALL StrafeCameraUhatMinus
PlayerCamera.Velocity.x = PlayerCamera.Velocity.x - .05 * uhat(1)
PlayerCamera.Velocity.y = PlayerCamera.Velocity.y - .05 * uhat(2)
PlayerCamera.Velocity.z = PlayerCamera.Velocity.z - .05 * uhat(3)
CALL StrafeCameraUhatPlus
PlayerCamera.Velocity.x = PlayerCamera.Velocity.x + .05 * uhat(1)
PlayerCamera.Velocity.y = PlayerCamera.Velocity.y + .05 * uhat(2)
PlayerCamera.Velocity.z = PlayerCamera.Velocity.z + .05 * uhat(3)
CALL StrafeCameraVhatMinus
PlayerCamera.Velocity.x = PlayerCamera.Velocity.x - .05 * vhat(1)
PlayerCamera.Velocity.y = PlayerCamera.Velocity.y - .05 * vhat(2)
PlayerCamera.Velocity.z = PlayerCamera.Velocity.z - .05 * vhat(3)
CALL StrafeCameraVhatPlus
PlayerCamera.Velocity.x = PlayerCamera.Velocity.x + .05 * vhat(1)
PlayerCamera.Velocity.y = PlayerCamera.Velocity.y + .05 * vhat(2)
PlayerCamera.Velocity.z = PlayerCamera.Velocity.z + .05 * vhat(3)
ToggleHUD = -ToggleHUD
gtmp = NewCube&(1, "Custom block", 350, PlayerCamera.Position.x - 40 * nhat(1), PlayerCamera.Position.y - 40 * nhat(2), PlayerCamera.Position.z - 40 * nhat(3), 10, 10, 10, Lime, Purple, Teal, 0)
' set -999? delete actual vectors?
p = Group(ClosestGroup).Pointer
l = Group(ClosestGroup).Lagger
Group(l).Pointer = p
Group(p).Lagger = l
FOR k
= Group
(ClosestGroup
).FirstVector
TO Group
(ClosestGroup
).LastVector
vec3Dvel
(k
, 1) = (RND - .5) * .20 vec3Dvel
(k
, 2) = (RND - .5) * .20 vec3Dvel
(k
, 3) = (RND - .5) * .20 PlayerCamera.Position.x = -40
PlayerCamera.Position.y = 30
PlayerCamera.Position.z = 40
uhat(1) = -.2078192: uhat(2) = -.9781672: uhat(3) = 0
vhat(1) = 0: vhat(2) = 0: vhat(3) = 1
CALL CalculateScreenVectors
ToggleAnimate = -ToggleAnimate
' Color utility.
' Cartesian plotting.
' Camera transformation
PlayerCamera.Velocity.x = .95 * PlayerCamera.Velocity.x
PlayerCamera.Velocity.y = .95 * PlayerCamera.Velocity.y
PlayerCamera.Velocity.z = .95 * PlayerCamera.Velocity.z
PlayerCamera.Position.x = PlayerCamera.Position.x + PlayerCamera.Velocity.x
PlayerCamera.Position.y = PlayerCamera.Position.y + PlayerCamera.Velocity.y
PlayerCamera.Position.z = PlayerCamera.Position.z + PlayerCamera.Velocity.z
FOR k
= 1 TO MissionTicker
IF (Group
(ClosestGroup
).GroupName
= Mission
(k
).Label
) THEN IF (Mission
(k
).Discovered
= 0) THEN Mission(k).Discovered = 1
uhat(1) = uhat(1) + nhat(1) * .0333
uhat(2) = uhat(2) + nhat(2) * .0333
uhat(3) = uhat(3) + nhat(3) * .0333
uhat(1) = uhat(1) - nhat(1) * .0333
uhat(2) = uhat(2) - nhat(2) * .0333
uhat(3) = uhat(3) - nhat(3) * .0333
vhat(1) = vhat(1) + nhat(1) * .0333
vhat(2) = vhat(2) + nhat(2) * .0333
vhat(3) = vhat(3) + nhat(3) * .0333
vhat(1) = vhat(1) - nhat(1) * .0333
vhat(2) = vhat(2) - nhat(2) * .0333
vhat(3) = vhat(3) - nhat(3) * .0333
SUB RotateCounterclockwise
v1 = vhat(1)
v2 = vhat(2)
v3 = vhat(3)
vhat(1) = v1 + uhat(1) * .0333
vhat(2) = v2 + uhat(2) * .0333
vhat(3) = v3 + uhat(3) * .0333
uhat(1) = uhat(1) - v1 * .0333
uhat(2) = uhat(2) - v2 * .0333
uhat(3) = uhat(3) - v3 * .0333
v1 = vhat(1)
v2 = vhat(2)
v3 = vhat(3)
vhat(1) = v1 - uhat(1) * .0333
vhat(2) = v2 - uhat(2) * .0333
vhat(3) = v3 - uhat(3) * .0333
uhat(1) = uhat(1) + v1 * .0333
uhat(2) = uhat(2) + v2 * .0333
uhat(3) = uhat(3) + v3 * .0333
PlayerCamera.Position.x = PlayerCamera.Position.x + uhat(1)
PlayerCamera.Position.y = PlayerCamera.Position.y + uhat(2)
PlayerCamera.Position.z = PlayerCamera.Position.z + uhat(3)
SUB StrafeCameraUhatMinus
PlayerCamera.Position.x = PlayerCamera.Position.x - uhat(1)
PlayerCamera.Position.y = PlayerCamera.Position.y - uhat(2)
PlayerCamera.Position.z = PlayerCamera.Position.z - uhat(3)
PlayerCamera.Position.x = PlayerCamera.Position.x + vhat(1)
PlayerCamera.Position.y = PlayerCamera.Position.y + vhat(2)
PlayerCamera.Position.z = PlayerCamera.Position.z + vhat(3)
SUB StrafeCameraVhatMinus
PlayerCamera.Position.x = PlayerCamera.Position.x - vhat(1)
PlayerCamera.Position.y = PlayerCamera.Position.y - vhat(2)
PlayerCamera.Position.z = PlayerCamera.Position.z - vhat(3)
PlayerCamera.Position.x = PlayerCamera.Position.x + nhat(1)
PlayerCamera.Position.y = PlayerCamera.Position.y + nhat(2)
PlayerCamera.Position.z = PlayerCamera.Position.z + nhat(3)
SUB StrafeCameraNhatMinus
PlayerCamera.Position.x = PlayerCamera.Position.x - nhat(1)
PlayerCamera.Position.y = PlayerCamera.Position.y - nhat(2)
PlayerCamera.Position.z = PlayerCamera.Position.z - nhat(3)