'$ExeIcon:'sanctum.ico'
' Hardware.
'Screen _NewImage(640, 480, 32)
'Screen _NewImage(1024, 768, 32)
' Performance.
FPSTarget = 60
' Color constants.
' Mathematical constants.
' Divine numbers.
bignumber = 10 ^ 7
WorldSeed = 3 'Int(Timer)
' Fundamental types.
' World-specific types.
' Vectors to specify points.
Dim Shared vec3Dpos
(bignumber
) As Vector3
' Absolute position
' A collection of vectors is a Group.
GroupIdTicker = 0
' Groups will eventually be sorted based on distance^2.
' A collection of groups is a Cluster.
ClusterIdTicker = 0
ClusterFillCounter = 0
' Main terrain setup. This is a surface z=f(x,y).
' Terrain elements are formally groups whose size and density are specified here.
BlockSize = 40
BlockStep
= Int(BlockSize
/ 8)
' World features.
' Fixed paths. Primary ticks are one per second, with total cycle of one day.
FixedPathIndexTicker = 0
' Three-space basis vectors.
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 As Double nearplane
(4), farplane
(4), rightplane
(4), leftplane
(4), topplane
(4), bottomplane
(4) nearplane(4) = 1
farplane(4) = -256
rightplane(4) = -BlockSize / 2
leftplane(4) = -BlockSize / 2
topplane(4) = -BlockSize / 2
bottomplane(4) = -BlockSize / 2
' Temporary counters.
' Interface.
' Prime and start main loop.
' Subs and Functions
fps = 0
fps = fps + 1
fpstimer = tt
FPSReport = fps
fps = 0
k = 0
k = k + 1: Strata(k).Height = -50: Strata(k).Label = "Water": Strata(k).Shade = RoyalBlue
k = k + 1: Strata(k).Height = 0: Strata(k).Label = "Meadow": Strata(k).Shade = ForestGreen
k = k + 1: Strata(k).Height = 50: Strata(k).Label = "Grassland": Strata(k).Shade = DarkKhaki
k = k + 1: Strata(k).Height = 100: Strata(k).Label = "Rocky Terrain": Strata(k).Shade = DarkGoldenRod
k = k + 1: Strata(k).Height = 150: Strata(k).Label = "Snowy Terrain": Strata(k).Shade = White
k = 0
k = k + 1: CloudLayer(k).Height = 140: CloudLayer(k).Label = "Dark Cloud": CloudLayer(k).Shade = SlateGray
k = k + 1: CloudLayer(k).Height = 160: CloudLayer(k).Label = "Gray Cloud": CloudLayer(k).Shade = Gray
k = k + 1: CloudLayer(k).Height = 180: CloudLayer(k).Label = "Azul Cloud": CloudLayer(k).Shade = DarkBlue
k = k + 1: CloudLayer(k).Height = 200: CloudLayer(k).Label = "Heavy Cloud": CloudLayer(k).Shade = Snow
k = k + 1: CloudLayer(k).Height = 220: CloudLayer(k).Label = "Icy Cloud": CloudLayer(k).Shade = Ivory
u = u + pi / 2
v
= (w
/ 2) * (.8 + Rnd * .5) Plateau
(k
).Location.x
= Int(v
* Cos(u
)) Plateau
(k
).Location.y
= Int(v
* Sin(u
)) Plateau(k).Location.z = -250
Plateau(k).Location.x = 0
Plateau(k).Location.y = 0
Plateau(k).Location.z = Strata(k).Height
u = u + pi / 2
v
= (w
/ 2) * (.8 + Rnd * .5) Plateau
(k
).Location.x
= Int(v
* Cos(u
)) Plateau
(k
).Location.y
= Int(v
* Sin(u
)) Plateau(k).Location.z = Strata(k).Height
Plateau(k).Radius = 15
' Initialize and populate list.
k = 0
k
= k
+ 1:
Call TextCenter
(".:. Let there be light .:.", k
* 16, DarkKhaki
) k
= k
+ 1:
Call TextCenter
("(Initialize linked list)", k
* 16, ForestGreen
) g = NewGroup&(0, 0, 0, 0, 1, 0, 0)
k
= k
+ 2:
Call TextCenter
(".:. Let there be a firmament .:.", k
* 16, DarkKhaki
) k
= k
+ 1:
Call TextCenter
("(Using seed " + LTrim$(RTrim$(Str$(WorldSeed
))) + ")", k
* 16, ForestGreen
) k
= k
+ 1:
Call TextCenter
("(Generate random terrain)", k
* 16, ForestGreen
) g = CreateTerrainGroups&(g)
k
= k
+ 2:
Call TextCenter
(".:. Let the dry land appear; bring forth the grass .:.", k
* 16, DarkKhaki
) k
= k
+ 1:
Call TextCenter
("(Relax terrain mesh)", k
* 16, ForestGreen
) k
= k
+ 1:
Call TextCenter
("(Fill terrain volumes)", k
* 16, ForestGreen
) k
= k
+ 1:
Call TextCenter
("(Cover terrain surfaces)", k
* 16, ForestGreen
) g = CreateTerrainVectors&(g)
g = CreateTerrainVolume&(g)
g = CreateClover&(g)
g = CreateFern&(g)
g = CreateGrass&(g)
k
= k
+ 2:
Call TextCenter
(".:. Divide the day from the night .:.", k
* 16, DarkKhaki
) k
= k
+ 1:
Call TextCenter
("(Create celestial objects)", k
* 16, ForestGreen
) k
= k
+ 1:
Call TextCenter
("(Create weather events)", k
* 16, ForestGreen
) g = CreateSun&(g)
g = CreateMoon&(g)
g = CreateTornado&(g)
g = CreateWeather&(g)
k
= k
+ 2:
Call TextCenter
(".:. Let waters bring forth .:.", k
* 16, DarkKhaki
) k
= k
+ 1:
Call TextCenter
("(Create fish)", k
* 16, ForestGreen
) g = CreateFish&(g)
k
= k
+ 2:
Call TextCenter
(".:. Let us make man .:.", k
* 16, DarkKhaki
) k
= k
+ 1:
Call TextCenter
("(Initialize player)", k
* 16, ForestGreen
) k
= k
+ 2:
Call TextCenter
(".:. ...blessed the seventh day and Sanctified it .:.", k
* 16, DarkKhaki
) k
= k
+ 1:
Call TextCenter
("(Rest)", k
* 16, ForestGreen
) k
= k
+ 3:
Call TextCenter
("PRESS ANY KEY", k
* 16, Sunglow
)
' High-order clusters and groups.
g = LagAddressIn
' Create world mesh and set extreme points.
' Overall slant of world.
tempworldmesh2
(i
, j
, 1) = (u
* i
+ v
* j
- UBound(WorldMesh
, 1) / 2 - UBound(WorldMesh
, 2) / 2)
' Peaks and valleys.
tempworldmesh2
(i
, j
, 1) = tempworldmesh2
(i
, j
, 1) - (100 + Rnd * 100) tempworldmesh2(i, j, 2) = 1 ' fixed
tempworldmesh2
(i
, j
, 1) = tempworldmesh2
(i
, j
, 1) + (100 + Rnd * 300) tempworldmesh2(i, j, 2) = 1 ' fixed
tempworldmesh2(i, j, 1) = tempworldmesh2(i, j, 1) + 0
tempworldmesh2(i, j, 2) = 0 'free
' Plateaus.
ii
= i
- Plateau
(k
).Location.x
- UBound(WorldMesh
, 1) / 2 jj
= j
- Plateau
(k
).Location.y
- UBound(WorldMesh
, 2) / 2 If (ii
^ 2 + jj
^ 2 < Plateau
(k
).Radius
^ 2) Then tempworldmesh2(i, j, 1) = Plateau(k).Location.z
tempworldmesh2(i, j, 2) = 1 ' fixed
' Relax the world mesh to generate terrain.
SmoothFactor = 30
tempworldmesh1(i, j) = tempworldmesh2(i, j, 1)
' Before last iteration, allow extreme points to relax.
If (k
= 1) Then tempworldmesh2
(i
, j
, 2) = 0 If (tempworldmesh2
(i
, j
, 2) = 0) Then tempworldmesh2(i, j, 1) = (1 / 4) * (tempworldmesh1(i - 1, j) + tempworldmesh1(i + 1, j) + tempworldmesh1(i, j - 1) + tempworldmesh1(i, j + 1))
WorldMesh(i, j) = tempworldmesh2(i, j, 1)
' Create terrain groups.
u
= BlockSize
* (i
- (UBound(WorldMesh
, 1) / 2)) v
= BlockSize
* (j
- (UBound(WorldMesh
, 2) / 2)) w = WorldMesh(i, j)
' Store first address.
g = NewGroup&(g, u, v, w, 10, 0, 0)
Group(g).Label = TerrainHeightLabel$(w)
Group(g).Volume.x = BlockSize
Group(g).Volume.y = BlockSize
Group
(g
).Volume.z
= Sqr(BlockSize
* BlockSize
+ BlockSize
* BlockSize
) Group(g).PlotMode = 0
WorldMeshAddress(i, j) = g
CreateTerrainGroups& = g0
g = LagAddressIn
' Create fine-grain block mesh to relax terrain.
BlockBins = BlockSize / BlockStep
Dim blockmesh1
(BlockBins
, BlockBins
) Dim blockmesh2
(BlockBins
, BlockBins
, 2) vindex = Group(Group(g).Lagger).LastVector
g = WorldMeshAddress(i, j)
Group(g).FirstVector = vindex + 1
' For each world mesh location, use the block mesh whose boundary heights are determined by neighbors.
' Lock boundaries.
blockmesh2(ii, jj, 2) = 1
blockmesh2(ii, jj, 2) = 1
' Set boundary values.
blockmesh2(ii, jj, 1) = -WorldMesh(i, j) + (1 / 2) * (WorldMesh(i, j) + WorldMesh(i - 1, j))
blockmesh2(ii, jj, 1) = -WorldMesh(i, j) + (1 / 2) * (WorldMesh(i, j) + WorldMesh(i, j - 1))
blockmesh2(ii, jj, 1) = -WorldMesh(i, j) + (1 / 2) * (WorldMesh(i, j) + WorldMesh(i + 1, j))
blockmesh2(ii, jj, 1) = -WorldMesh(i, j) + (1 / 2) * (WorldMesh(i, j) + WorldMesh(i, j + 1))
' Set extreme points.
blockmesh2
(ii
, jj
, 1) = -Rnd * 20 blockmesh2(ii, jj, 2) = 1 ' fixed
blockmesh2
(ii
, jj
, 1) = Rnd * 20 blockmesh2(ii, jj, 2) = 1 ' fixed
blockmesh2(ii, jj, 1) = 0
blockmesh2(ii, jj, 2) = 0 'free
' Copy mesh.
blockmesh1(ii, jj) = blockmesh2(ii, jj, 1)
' Relax mesh body.
Smoothfactor = 30
' Before last iteration, allow extreme points to relax.
If (k
= 5) Then blockmesh2
(ii
, jj
, 2) = 0 If (blockmesh2
(ii
, jj
, 2) = 0) Then blockmesh2(ii, jj, 1) = (1 / 4) * (blockmesh1(ii - 1, jj) + blockmesh1(ii + 1, jj) + blockmesh1(ii, jj - 1) + blockmesh1(ii, jj + 1))
' Upate mesh with relaxed version.
blockmesh1(ii, jj) = blockmesh2(ii, jj, 1)
' Relax mesh boundaries once.
jj = 1
blockmesh2(ii, jj, 1) = (1 / 3) * (blockmesh1(ii - 1, jj) + blockmesh1(ii + 1, jj) + blockmesh1(ii, jj + 1))
blockmesh2(ii, jj, 1) = (1 / 3) * (blockmesh1(ii - 1, jj) + blockmesh1(ii + 1, jj) + blockmesh1(ii, jj - 1))
ii = 1
blockmesh2(ii, jj, 1) = (1 / 3) * (blockmesh1(ii + 1, jj) + blockmesh1(ii, jj - 1) + blockmesh1(ii, jj + 1))
blockmesh2(ii, jj, 1) = (1 / 3) * (blockmesh1(ii - 1, jj) + blockmesh1(ii, jj - 1) + blockmesh1(ii, jj + 1))
ii = 1
jj = 1
blockmesh2(ii, jj, 1) = (1 / 2) * (blockmesh1(ii + 1, jj) + blockmesh1(ii, jj + 1))
blockmesh2(ii, jj, 1) = (1 / 2) * (blockmesh1(ii - 1, jj) + blockmesh1(ii, jj - 1))
ii = 1
blockmesh2(ii, jj, 1) = (1 / 2) * (blockmesh1(ii + 1, jj) + blockmesh1(ii, jj - 1))
jj = 1
blockmesh2(ii, jj, 1) = (1 / 2) * (blockmesh1(ii - 1, jj) + blockmesh1(ii, jj + 1))
' Upate mesh with relaxed version.
blockmesh1(ii, jj) = blockmesh2(ii, jj, 1)
' Set particle positions relative to group center. Add random fuzz.
vindex = vindex + 1
vec3Dpos
(vindex
).x
= BlockStep
* ii
- BlockSize
/ 2 + 3 * (Rnd - .5) vec3Dpos
(vindex
).y
= BlockStep
* jj
- BlockSize
/ 2 + 3 * (Rnd - .5) vec3Dpos(vindex).z = blockmesh1(ii, jj)
cc = TerrainHeightShade~&(WorldMesh(i, j) + blockmesh1(ii, jj))
dd = TerrainHeightShade~&(WorldMesh(i, j) + blockmesh1(ii, jj) + BlockSize)
vec3Dcolor(vindex) = ShadeMix~&(cc, ShadeMix~&(cc, dd, blockmesh1(ii, jj) / 10), .5)
Group(g).LastVector = vindex + 1 ''' why on earth is this +1?
CreateTerrainVectors& = g
g = LagAddressIn
groupcount = 0
clustertick = 0
z = WorldMesh(i, j) + BlockSize / 2
groupcount = groupcount + 1
u
= BlockSize
* (i
- (UBound(WorldMesh
, 1) / 2)) v
= BlockSize
* (j
- (UBound(WorldMesh
, 2) / 2)) g = NewCube&(g, "Water", 50, u, v, WorldMesh(i, j) - z / 2, BlockSize, BlockSize, -z, Blue, RoyalBlue, DarkBlue, 0, 0)
For k
= Group
(g
).FirstVector
To Group
(g
).LastVector
vec3Dvel
(k
).x
= (Rnd - .5) * .20 vec3Dvel
(k
).y
= (Rnd - .5) * .20 vec3Dvel(k).z = 0
clustertick = clustertick + 1
clustertick = 0
groupcount = 0
groupcount = 0
clustertick = 0
z = WorldMesh(i, j) + BlockSize / 2
groupcount = groupcount + 1
u
= BlockSize
* (i
- (UBound(WorldMesh
, 1) / 2)) v
= BlockSize
* (j
- (UBound(WorldMesh
, 2) / 2)) g = NewCube&(g, "Dirt and Sand", 20, u, v, WorldMesh(i, j) / 2 - BlockSize / 4, BlockSize, BlockSize, WorldMesh(i, j), SaddleBrown, DarkKhaki, Sienna, 0, 0)
g = NewCube&(g, "Dirt and Sand", 20, u, v, -50, BlockSize, BlockSize, 80, SaddleBrown, DarkKhaki, Sienna, 0, 0)
clustertick = clustertick + 1
clustertick = 0
groupcount = 0
groupcount = 0
clustertick = 0
groupcount = groupcount + 1
u
= BlockSize
* (i
- (UBound(WorldMesh
, 1) / 2)) v
= BlockSize
* (j
- (UBound(WorldMesh
, 2) / 2)) z = WorldMesh(i, j)
g = NewCube&(g, "Atmospheric Dust", 30, u, v, 100 + BlockSize * (3 - 1 / 2) + z, BlockSize, BlockSize, BlockSize * 3, DarkGray, White, Snow, 0, 0)
clustertick = clustertick + 1
clustertick = 0
groupcount = 0
CreateTerrainVolume& = g
g = LagAddressIn
FixedPathIndexTicker = FixedPathIndexTicker + 1
x0
= BlockSize
* 30 * Cos(u
+ 2 * pi
* (6 * 30) * (p
- 1) / 86400) y0
= BlockSize
* 30 * Sin(u
+ 2 * pi
* (6 * 30) * (p
- 1) / 86400) FixedPath(FixedPathIndexTicker, p).x = x0
FixedPath(FixedPathIndexTicker, p).y = y0
wi
= 1 + Int(x0
/ BlockSize
+ UBound(WorldMesh
, 1) / 2) wj
= 1 + Int(y0
/ BlockSize
+ UBound(WorldMesh
, 2) / 2) z0 = WorldMesh(wi, wj)
FixedPath(FixedPathIndexTicker, p).z = z0 + 50
g
= NewCube&
(g
, "Tornado", 35, v
* Cos(w
), v
* Sin(w
), u
, 15, 15, 15, DarkGray
, SunsetOrange
, DarkGoldenRod
, FixedPathIndexTicker
, 0) CreateTornado& = g
g = LagAddressIn
FixedPathIndexTicker = FixedPathIndexTicker + 1
v
= Rnd * .7 * BlockSize
* Sqr((UBound(WorldMesh
, 1) / 2) ^ 2 + (UBound(WorldMesh
, 2) / 2) ^ 2) w = pi / 2
tallness
= Rnd * (CloudLayer
(UBound(CloudLayer
)).Height
- CloudLayer
(1).Height
) x0
= v
* Cos(u
+ 2 * pi
* (1 * 30) * (p
- 1) / 86400 + w
) y0
= v
* Sin(u
+ 4 * pi
* (1 * 30) * (p
- 1) / 86400) FixedPath(FixedPathIndexTicker, p).x = x0
FixedPath(FixedPathIndexTicker, p).y = y0
wi
= 1 + Int(x0
/ BlockSize
+ UBound(WorldMesh
, 1) / 2) wj
= 1 + Int(y0
/ BlockSize
+ UBound(WorldMesh
, 2) / 2) z0 = WorldMesh(wi, wj)
z0 = z0 + CloudLayer(1).Height + tallness
FixedPath(FixedPathIndexTicker, p).z = z0
v = u
z0
= z0
+ 10 * (Rnd - .5) g
= NewCube&
(g
, CloudHeightLabel$
(z0
), 20, v
* Cos(w
), v
* Sin(w
), z0
, BlockSize
/ 2, BlockSize
/ 2, BlockSize
/ 2, Red
, Red
, Red
, FixedPathIndexTicker
, 0) Call SetParticleVelocity
(g
, .01 * (Rnd - .5), .01 * (Rnd - .5), 0) For p
= Group
(g
).FirstVector
To Group
(g
).LastVector
vec3Dcolor(p) = CloudHeightShade~&(Group(g).Centroid.z + vec3Dpos(p).z)
Group(g).PlotMode = 0
z0 = Group(g).Centroid.z
g
= NewCube&
(g
, "Rain", 20, v
* Cos(w
), v
* Sin(w
), z0
/ 2 - BlockSize
/ 2, BlockSize
/ 2, BlockSize
/ 2, z0
, Blue
, RoyalBlue
, DodgerBlue
, 0, 0) Call SetParticleVelocity
(g
, 0, 0, -1)
CreateWeather& = g
g = LagAddressIn
z = WorldMesh(i, j)
If (TerrainHeightIndex
(z
) = 1) Then x
= (Rnd - .5) * BlockSize
+ BlockSize
* (i
- (UBound(WorldMesh
, 1) / 2)) y
= (Rnd - .5) * BlockSize
+ BlockSize
* (j
- (UBound(WorldMesh
, 2) / 2)) scale
= 1 / (4 + Rnd * 3) g = NewGroup&(g, x, y, z, 12, 0, 0)
Group(g).Label = "Clover"
Group(g).Volume.x = BlockSize
Group(g).Volume.y = BlockSize
Group(g).Volume.z = BlockSize
vindex = Group(Group(g).Lagger).LastVector
Group(g).FirstVector = vindex + 1
Group(g).PlotMode = 1
vindex = vindex + 1
vec3Dpos
(vindex
).x
= scale
* ((Group
(g
).Volume.x
) * (0 + Cos(pedals
* u
) * Cos(u
))) * Cos(t
) vec3Dpos
(vindex
).y
= scale
* ((Group
(g
).Volume.y
) * (0 + Cos(pedals
* u
) * Cos(u
))) * Sin(t
) vec3Dpos
(vindex
).z
= scale
* ((Group
(g
).Volume.z
) * (height
+ Cos(pedals
* u
) * Sin(u
))) vec3Dcolor(vindex) = Magenta
vec3Dcolor(vindex) = Lime
For u
= (Group
(g
).Volume.z
) * height
To 0 Step -(Group
(g
).Volume.z
) * height
/ 10 vindex = vindex + 1
vec3Dpos
(vindex
).x
= scale
* (0 + (Rnd - .5)) vec3Dpos
(vindex
).y
= scale
* (0 + (Rnd - .5)) vec3Dpos(vindex).z = scale * (u)
vec3Dcolor(vindex) = LimeGreen
Group(g).LastVector = vindex '''+ 1 ''' why on earth is this +1?
CreateClover& = g
g = LagAddressIn
z = WorldMesh(i, j)
If (TerrainHeightIndex
(z
) = 2) Then x
= (Rnd - .5) * BlockSize
+ BlockSize
* (i
- (UBound(WorldMesh
, 1) / 2)) y
= (Rnd - .5) * BlockSize
+ BlockSize
* (j
- (UBound(WorldMesh
, 2) / 2)) scale
= 1 / (4 + Rnd * 3) g = NewGroup&(g, x, y, z, 16, 0, 0)
Group(g).Label = "Grass"
Group(g).Volume.x = BlockSize
Group(g).Volume.y = BlockSize
Group(g).Volume.z = BlockSize
vindex = Group(Group(g).Lagger).LastVector
Group(g).FirstVector = vindex + 1
Group(g).PlotMode = 1
x0
= BlockSize
* 1 * (Rnd - .5) y0
= BlockSize
* 1 * (Rnd - .5) For u
= (Group
(g
).Volume.z
) * height
To 0 Step -(Group
(g
).Volume.z
) * height
/ 5 vindex = vindex + 1
vec3Dpos
(vindex
).x
= scale
* (x0
+ (Rnd - .5)) vec3Dpos
(vindex
).y
= scale
* (y0
+ (Rnd - .5)) vec3Dpos(vindex).z = scale * (u)
vec3Dcolor
(vindex
) = ShadeMix~&
(DarkGoldenRod
, Sienna
, Rnd) Group(g).LastVector = vindex '''+ 1 ''' why on earth is this +1?
CreateGrass& = g
g = LagAddressIn
z = WorldMesh(i, j)
If (TerrainHeightIndex
(z
) = 1) Then x
= (Rnd - .5) * BlockSize
+ BlockSize
* (i
- (UBound(WorldMesh
, 1) / 2)) y
= (Rnd - .5) * BlockSize
+ BlockSize
* (j
- (UBound(WorldMesh
, 2) / 2)) g = NewGroup&(g, x, y, z, 12, 0, 0)
Group(g).Label = "Fern"
Group(g).Volume.x = BlockSize
Group(g).Volume.y = BlockSize
Group(g).Volume.z = BlockSize
vindex = Group(Group(g).Lagger).LastVector
Group(g).FirstVector = vindex + 1
Group(g).PlotMode = 2
xx = 0
yy = xx
zz = 0
xx = 0
zz = .16 * zz
xx = .85 * xx + .04 * zz
zz = -.04 * xx + .85 * zz + 1.6
xx = .2 * xx - .26 * zz
zz = .23 * xx + .22 * zz + 1.6
xx = -.15 * xx + .28 * zz
zz = .26 * xx + .24 * zz + .44
yy = xx
vindex = vindex + 1
vec3Dpos
(vindex
).x
= scale
* Group
(g
).Volume.x
* xx
* Cos(t
) vec3Dpos
(vindex
).y
= scale
* Group
(g
).Volume.y
* yy
* Sin(t
) vec3Dpos(vindex).z = scale * Group(g).Volume.z * zz
vec3Dcolor(vindex) = Lime
Group(g).LastVector = vindex '''+ 1 ''' why on earth is this +1?
CreateFern& = g
g = LagAddressIn
FixedPathIndexTicker = FixedPathIndexTicker + 1
phase = -2 * pi * (24) * (p - 1) / 86400 - pi / 2
y0 = 0
FixedPath(FixedPathIndexTicker, p).x = x0
FixedPath(FixedPathIndexTicker, p).y = y0
FixedPath(FixedPathIndexTicker, p).z = z0
xx
= (Rnd - .5) * 6 * BlockSize
yy
= (Rnd - .5) * 6 * BlockSize
zz
= (Rnd - .5) * 6 * BlockSize
Loop Until ((xx
^ 2 + yy
^ 2 + zz
^ 2) < (.5 * 6 * BlockSize
) ^ 2) g = NewCube&(g, "Sun", 50, xx, yy, zz, BlockSize * 6, BlockSize * 6, BlockSize * 6, Red, Red, Red, FixedPathIndexTicker, 0)
For p
= Group
(g
).FirstVector
To Group
(g
).LastVector
vec3Dcolor
(p
) = ShadeMix~&
(Sunglow
, SunsetOrange
, Rnd) Call SetParticleVelocity
(g
, .5 * (Rnd - .5), .5 * (Rnd - .5), .5 * (Rnd - .5)) Group(g).PlotMode = 0
SunClusterAddress = ClusterIdTicker
CreateSun& = g
g = LagAddressIn
FixedPathIndexTicker = FixedPathIndexTicker + 1
phase = -2 * pi * (48) * (p - 1) / 86400 + pi / 2
x0 = 0
FixedPath(FixedPathIndexTicker, p).x = x0
FixedPath(FixedPathIndexTicker, p).y = y0
FixedPath(FixedPathIndexTicker, p).z = z0
xx
= (Rnd - .5) * 5 * BlockSize
yy
= (Rnd - .5) * 5 * BlockSize
zz
= (Rnd - .5) * 5 * BlockSize
Loop Until ((xx
^ 2 + yy
^ 2 + zz
^ 2) < (.5 * 5 * BlockSize
) ^ 2) g = NewCube&(g, "Moon", 50, xx, yy, zz, 5 * BlockSize, 5 * BlockSize, 5 * BlockSize, Gray, DarkGray, SlateGray, FixedPathIndexTicker, 0)
Group(g).PlotMode = 0
MoonClusterAddress = ClusterIdTicker
CreateMoon& = g
g = LagAddressIn
FixedPathIndexTicker = FixedPathIndexTicker + 1
x0
= BlockSize
* Plateau
(1).Location.x
+ BlockSize
* (4 + Cos(2 * pi
* n
/ 12)) * Cos(u
+ 2 * pi
* (24 * 30) * (p
- 1) / 86400) y0
= BlockSize
* Plateau
(1).Location.y
+ BlockSize
* (4 + Cos(2 * pi
* n
/ 12)) * Sin(u
+ 2 * pi
* (24 * 30) * (p
- 1) / 86400) FixedPath(FixedPathIndexTicker, p).x = x0
FixedPath(FixedPathIndexTicker, p).y = y0
wi
= 1 + Int(x0
/ BlockSize
+ UBound(WorldMesh
, 1) / 2) wj
= 1 + Int(y0
/ BlockSize
+ UBound(WorldMesh
, 2) / 2) z0
= WorldMesh
(wi
, wj
) + 100 + 80 * Cos(2 * pi
* n
/ 12) * Cos(2 * pi
* (24 * 30) * (p
- 1) / 86400) FixedPath(FixedPathIndexTicker, p).z = z0
' In the following group, there are 48 frames with 36 vectors per frame. The +1 offset is fishy, no pun.
g = NewCube&(g, "Fish", 36 * (48 + 1), 0, 0, 0, BlockSize / 4, BlockSize / 4, BlockSize / 4, LimeGreen, SunsetOrange, DarkGoldenRod, FixedPathIndexTicker, 1)
Group(g).FrameLength = 36
u = 0
For p
= Group
(g
).FirstVector
To Group
(g
).FirstVector
+ Group
(g
).FrameLength
- 1 u = u + 2 * pi / Group(g).FrameLength
vec3Dpos
(p
).x
= Group
(g
).Volume.x
* (Cos(u
) - Sin(u
) ^ 2 / Sqr(2)) vec3Dpos(p).y = 0
vec3Dpos
(p
).z
= Group
(g
).Volume.z
* (Cos(u
) * Sin(u
)) v = 0
v = v - 2 * pi / 48
p0 = 0
For p
= Group
(g
).FirstVector
+ Group
(g
).FrameLength
* (m
) To Group
(g
).FirstVector
+ Group
(g
).FrameLength
* (m
+ 1) - 1 vec3Dpos
(p
).x
= Cos(v
) * vec3Dpos
(Group
(g
).FirstVector
+ p0
).x
+ Sin(v
) * vec3Dpos
(Group
(g
).FirstVector
+ p0
).y
vec3Dpos
(p
).y
= -Sin(v
) * vec3Dpos
(Group
(g
).FirstVector
+ p0
).x
+ Cos(v
) * vec3Dpos
(Group
(g
).FirstVector
+ p0
).y
vec3Dpos(p).z = vec3Dpos(Group(g).FirstVector + p0).z
p0 = p0 + 1
CreateFish& = g
ToggleAnimate = 1
PlayerCamera.Position.x = 0
PlayerCamera.Position.y = 0
PlayerCamera.Position.z
= 100 + 40 + WorldMesh
(UBound(WorldMesh
, 1) / 2, UBound(WorldMesh
, 2) / 2) PlayerCamera.Velocity.x = 0
PlayerCamera.Velocity.y = 0
PlayerCamera.Velocity.z = .1
PlayerCamera.Acceleration.x = 0
PlayerCamera.Acceleration.y = 0
PlayerCamera.Acceleration.z = -.5
uhat(1) = 1: uhat(2) = 0: uhat(3) = 0
vhat(1) = 0: vhat(2) = 0: vhat(3) = 1
Call CalculateScreenVectors
dx = -nhat(1)
dy = -nhat(2)
If ((dx
> 0) And (dy
> 0)) Then t
= -pi
/ 2 + (Atn(dy
/ dx
)) If ((dx
< 0) And (dy
> 0)) Then t
= -pi
/ 2 + pi
+ (Atn(dy
/ dx
)) If ((dx
< 0) And (dy
< 0)) Then t
= -pi
/ 2 + pi
+ (Atn(dy
/ dx
)) If ((dx
> 0) And (dy
< 0)) Then t
= -pi
/ 2 + 2 * pi
+ (Atn(dy
/ dx
)) uhat
(1) = Cos(t
): uhat
(2) = Sin(t
): uhat
(3) = 0 vhat(1) = 0: vhat(2) = 0: vhat(3) = 1
Call CalculateScreenVectors
' Terrain tools.
h0 = -1
If (z0
<= Strata
(j
).Height
) Then h0 = j - 1
TerrainHeightIndex = h0
h0 = -1
If (z0
<= Strata
(j
).Height
) Then h0 = j - 1
sh1 = Strata(1).Shade
sh2 = Strata(1).Shade
alpha = 0
sh1 = Strata(h0).Shade
sh2 = Strata(h0).Shade
alpha = 0
sh1 = Strata(h0).Shade
sh2 = Strata(h0 + 1).Shade
u = z0 - Strata(h0).Height
v = Strata(h0 + 1).Height - Strata(h0).Height
alpha = u / v
TerrainHeightShade~& = ShadeMix~&(sh1, sh2, alpha)
h0 = -1
If (z0
<= Strata
(j
).Height
) Then h0 = j
TheReturn = Strata(1).Label
TheReturn = Strata(h0).Label
TheReturn = Strata(h0).Label
TerrainHeightLabel$ = TheReturn
h0 = -1
If (z0
<= CloudLayer
(j
).Height
) Then h0 = j - 1
sh1 = CloudLayer(1).Shade
sh2 = CloudLayer(1).Shade
alpha = 0
sh1 = CloudLayer(h0).Shade
sh2 = CloudLayer(h0).Shade
alpha = 0
sh1 = CloudLayer(h0).Shade
sh2 = CloudLayer(h0 + 1).Shade
u = z0 - CloudLayer(h0).Height
v = CloudLayer(h0 + 1).Height - CloudLayer(h0).Height
alpha = u / v
CloudHeightShade~& = ShadeMix~&(sh1, sh2, alpha)
h0 = -1
If (z0
<= CloudLayer
(j
).Height
) Then h0 = j
TheReturn = CloudLayer(1).Label
TheReturn = CloudLayer(h0).Label
TheReturn = CloudLayer(h0).Label
CloudHeightLabel$ = TheReturn
' Low-order groups.
Function NewCube&
(LagAddressIn
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, Framing
As Integer) q = LagAddressIn
vindex = Group(q).LastVector
g = NewGroup&(q, PosX, PosY, PosZ, 64, TheDynamic, Framing)
Group(g).Label = TheName
Group(g).Volume.x = VolX
Group(g).Volume.y = VolY
Group(g).Volume.z = VolZ
Group(g).FirstVector = vindex + 1
Group(g).PlotMode = 1
vindex = vindex + 1
vec3Dpos
(vindex
).x
= (Rnd - .5) * VolX
vec3Dpos
(vindex
).y
= (Rnd - .5) * VolY
vec3Dpos
(vindex
).z
= (Rnd - .5) * VolZ
vec3Dcolor(vindex) = ShadeA
vec3Dcolor(vindex) = ShadeB
vec3Dcolor(vindex) = ShadeC
Group(g).LastVector = vindex
NewCube& = g
q = LagAddressIn
vindex = Group(q).LastVector
g = NewGroup&(q, PosX, PosY, PosZ, 64, TheDynamic, 0)
Group(g).Label = TheName
Group(g).Volume.x = VolX
Group(g).Volume.y = VolY
Group(g).Volume.z = VolZ
Group(g).FirstVector = vindex + 1
Group(g).PlotMode = -1
vindex = vindex + 1
vec3Dpos(vindex).x = (0 - .5) * VolX
vec3Dpos(vindex).y = (0 - .5) * VolY
vec3Dpos(vindex).z = (0 - .5) * VolZ
vec3Dcolor(vindex) = ShadeA
vindex = vindex + 1
vec3Dpos(vindex).x = (1 - .5) * VolX
vec3Dpos(vindex).y = (0 - .5) * VolY
vec3Dpos(vindex).z = (0 - .5) * VolZ
vec3Dcolor(vindex) = ShadeA
vindex = vindex + 1
vec3Dpos(vindex).x = (0 - .5) * VolX
vec3Dpos(vindex).y = (1 - .5) * VolY
vec3Dpos(vindex).z = (0 - .5) * VolZ
vec3Dcolor(vindex) = ShadeA
vindex = vindex + 1
vec3Dpos(vindex).x = (1 - .5) * VolX
vec3Dpos(vindex).y = (1 - .5) * VolY
vec3Dpos(vindex).z = (0 - .5) * VolZ
vec3Dcolor(vindex) = ShadeA
vindex = vindex + 1
vec3Dpos(vindex).x = (0 - .5) * VolX
vec3Dpos(vindex).y = (0 - .5) * VolY
vec3Dpos(vindex).z = (1 - .5) * VolZ
vec3Dcolor(vindex) = ShadeA
vindex = vindex + 1
vec3Dpos(vindex).x = (1 - .5) * VolX
vec3Dpos(vindex).y = (0 - .5) * VolY
vec3Dpos(vindex).z = (1 - .5) * VolZ
vec3Dcolor(vindex) = ShadeA
vindex = vindex + 1
vec3Dpos(vindex).x = (0 - .5) * VolX
vec3Dpos(vindex).y = (1 - .5) * VolY
vec3Dpos(vindex).z = (1 - .5) * VolZ
vec3Dcolor(vindex) = ShadeA
vindex = vindex + 1
vec3Dpos(vindex).x = (1 - .5) * VolX
vec3Dpos(vindex).y = (1 - .5) * VolY
vec3Dpos(vindex).z = (1 - .5) * VolZ
vec3Dcolor(vindex) = ShadeA
Group(g).LastVector = vindex
NewWireCube& = g
' Linked list utility.
p = StartingID
q = 0
q = p
p = Group(q).Pointer
TheReturn = q
LatestGroupIdentity& = TheReturn
p = StartingID
q = 0
q = p
p = Cluster(q).Pointer
TheReturn = q
LatestClusterIdentity& = TheReturn
g0 = LatestGroupIdentity&(LagAddressIn)
GroupIdTicker = GroupIdTicker + 1
Group(GroupIdTicker).Identity = GroupIdTicker
Group(GroupIdTicker).Pointer = -999
Group(GroupIdTicker).Lagger = g0
Group(GroupIdTicker).Centroid.x = CenterX
Group(GroupIdTicker).Centroid.y = CenterY
Group(GroupIdTicker).Centroid.z = CenterZ
Group(GroupIdTicker).FrameLength = 0
Group(GroupIdTicker).ActiveFrame = 0
If (Group
(GroupIdTicker
).Lagger
<> 0) Then Group(g0).Pointer = GroupIdTicker
' Adjust corresponding cluster.
ClusterFillCounter = ClusterFillCounter + 1
If (ClusterFillCounter
= 1) Then Call NewCluster
(1, Group
(GroupIdTicker
).Identity
, TheDynamic
, Framing
) ''' If (ClusterFillCounter
= ClusterSize
) Then Call ClusterPinch
(Group
(GroupIdTicker
).Identity
)
NewGroup& = Group(GroupIdTicker).Identity
k0 = -1
k0 = LatestClusterIdentity&(ClusterLagIn)
ClusterIdTicker = ClusterIdTicker + 1
Cluster(ClusterIdTicker).Identity = ClusterIdTicker
Cluster(ClusterIdTicker).Pointer = -999
Cluster(ClusterIdTicker).Lagger = k0
Cluster(ClusterIdTicker).FirstGroup = FirstGroupIn
Cluster(ClusterIdTicker).MotionType = TheDynamic
Cluster(ClusterIdTicker).Framed = Framing
If (ClusterIdTicker
> 1) Then Cluster
(k0
).Pointer
= ClusterIdTicker
g = TheAddressIn
f = 0
k = 1
If (Cluster
(k
).FirstGroup
= g
) And (Cluster
(k
).LastGroup
<> g
) Then f = 1
ci = k
If (Cluster
(k
).FirstGroup
<> g
) And (Cluster
(k
).LastGroup
= g
) Then f = 2
ci = k
If ((Cluster
(k
).LastGroup
= g
) And (Cluster
(k
).LastGroup
= g
)) Then f = 3
ci = k
k = Cluster(k).Pointer
p = Group(g).Pointer
l = Group(g).Lagger
Group(l).Pointer = p
Group(p).Lagger = l
p = Group(g).Pointer
l = Group(g).Lagger
Group(l).Pointer = p
Group(p).Lagger = l
Cluster(ci).FirstGroup = p
Call ClusterCentroidCalc
(ci
) p = Group(g).Pointer
l = Group(g).Lagger
Group(l).Pointer = p
Group(p).Lagger = l
Cluster(ci).LastGroup = l
Call ClusterCentroidCalc
(ci
) p = Group(g).Pointer
l = Group(g).Lagger
Group(l).Pointer = p
Group(p).Lagger = l
k = TheAddressIn
p = Cluster(k).Pointer
l = Cluster(k).Lagger
Cluster(l).Pointer = p
Cluster(p).Lagger = l
ClusterFillCounter = 0
Cluster(ClusterIdTicker).LastGroup = TheLastGroup
Call ClusterCentroidCalc
(ClusterIdTicker
)
Cluster(TheCluster).Centroid.x = 0
Cluster(TheCluster).Centroid.y = 0
Cluster(TheCluster).Centroid.z = 0
g = Cluster(TheCluster).FirstGroup
n = 0
Cluster(TheCluster).Centroid.x = Cluster(TheCluster).Centroid.x + Group(g).Centroid.x
Cluster(TheCluster).Centroid.y = Cluster(TheCluster).Centroid.y + Group(g).Centroid.y
Cluster(TheCluster).Centroid.z = Cluster(TheCluster).Centroid.z + Group(g).Centroid.z
n = n + 1
g = Group(g).Pointer
Cluster(TheCluster).Centroid.x = Cluster(TheCluster).Centroid.x / n
Cluster(TheCluster).Centroid.y = Cluster(TheCluster).Centroid.y / n
Cluster(TheCluster).Centroid.z = Cluster(TheCluster).Centroid.z / n
' Player Dynamics
' Player kinematics
PlayerCamera.Velocity.x = PlayerCamera.Velocity.x + PlayerCamera.Acceleration.x
PlayerCamera.Velocity.y = PlayerCamera.Velocity.y + PlayerCamera.Acceleration.y
PlayerCamera.Velocity.z = PlayerCamera.Velocity.z + PlayerCamera.Acceleration.z
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
' Terrain traversal.
qi
= (PlayerCamera.Position.x
) / BlockSize
+ UBound(WorldMesh
, 1) / 2 qj
= (PlayerCamera.Position.y
) / BlockSize
+ UBound(WorldMesh
, 2) / 2 If (PlayerCamera.Velocity.z
= 0) Then PlayerCamera.Position.z = PlayerCamera.Position.z + .15 * ((40 + WorldMesh(wi, wj) - PlayerCamera.Position.z))
' Collision with ground after jump.
If ((PlayerCamera.Velocity.z
<> 0) And (PlayerCamera.Position.z
< (40 + WorldMesh
(wi
, wj
)))) Then PlayerCamera.Acceleration.z = 0
PlayerCamera.Velocity.z = 0
' Collision with tornado.
If (Group
(ClosestGroup
).Label
= "Tornado") Then PlayerCamera.Velocity.x
= (Rnd - .5) * 20 PlayerCamera.Velocity.y
= (Rnd - .5) * 20 PlayerCamera.Velocity.z = 20
PlayerCamera.Acceleration.z = -.5
'Un-zoom camera.
fovd
= Int(.5 * (fovd
- 192)) + 1 farplane(4) = -256 'Int(.5 * (farplane(4) - 256))
' Compute Visible Scene
ClosestGroup = 1
closestdist2 = 10000000
fp42 = farplane(4) * farplane(4)
k = 1
dx = Cluster(k).Centroid.x - PlayerCamera.Position.x
dy = Cluster(k).Centroid.y - PlayerCamera.Position.y
dz = Cluster(k).Centroid.z - PlayerCamera.Position.z
dist2 = dx * dx + dy * dy + dz * dz
'''
If k
= SunClusterAddress
And Cluster
(k
).Centroid.z
> 0 Then GoTo 100 If k
= MoonClusterAddress
And Cluster
(k
).Centroid.z
> 0 Then GoTo 100 '''
Cluster(k).Visible = 0
If ((Cluster
(k
).MotionType
<> 0) And (ToggleAnimate
= 1)) Then '''
100
'''
Cluster(k).Visible = 1
g = Cluster(k).FirstGroup
If ((Cluster
(k
).MotionType
<> 0) And (ToggleAnimate
= 1)) Then dx = Group(g).Centroid.x - PlayerCamera.Position.x
dy = Group(g).Centroid.y - PlayerCamera.Position.y
dz = Group(g).Centroid.z - PlayerCamera.Position.z
dist2 = dx * dx + dy * dy + dz * dz
Group(g).Visible = 0
'''
'''
'''
200
'''
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(g).Visible = 1
If (dist2
< closestdist2
) Then closestdist2 = dist2
ClosestGroup = g
Group(g).Distance2 = dist2
If (ToggleAnimate
= 1) And (Group
(g
).FrameLength
= 0) Then Call EvolveVectors
(g
)
'''
If k
= SunClusterAddress
Or k
= MoonClusterAddress
Then If PlayerCamera.Position.z
< -40 Then Call ProjectGroup
(g
, Group
(g
).FirstVector
, Group
(g
).LastVector
, 1) Call ProjectGroup
(g
, Group
(g
).FirstVector
, Group
(g
).LastVector
, 0) If Group
(g
).FrameLength
<> 0 And Group
(g
).ActiveFrame
<> 0 Then Call ProjectGroup
(g
, Group
(g
).FirstVector
+ Group
(g
).ActiveFrame
* Group
(g
).FrameLength
, Group
(g
).FirstVector
+ Group
(g
).ActiveFrame
* Group
(g
).FrameLength
+ Group
(g
).FrameLength
, 1) Call ProjectGroup
(g
, Group
(g
).FirstVector
, Group
(g
).LastVector
, 1) '''
g = Group(g).Pointer
k = Cluster(k).Pointer
Sub CalculateScreenVectors
mag
= 1 / Sqr(uhat
(1) * uhat
(1) + uhat
(2) * uhat
(2) + uhat
(3) * uhat
(3)) uhat(1) = uhat(1) * mag: uhat(2) = uhat(2) * mag: uhat(3) = uhat(3) * mag
mag
= 1 / Sqr(vhat
(1) * vhat
(1) + vhat
(2) * vhat
(2) + vhat
(3) * vhat
(3)) vhat(1) = vhat(1) * mag: vhat(2) = vhat(2) * mag: vhat(3) = vhat(3) * mag
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)
h2 = TheHeight * .5
w2 = TheWidth * .5
h2f = h2 * fovd
w2f = w2 * fovd
h2w2 = h2 * w2
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) = h2f * uhat(1) - h2w2 * nhat(1)
rightplane(2) = h2f * uhat(2) - h2w2 * nhat(2)
rightplane(3) = h2f * uhat(3) - h2w2 * nhat(3)
mag
= 1 / 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) = -h2f * uhat(1) - h2w2 * nhat(1)
leftplane(2) = -h2f * uhat(2) - h2w2 * nhat(2)
leftplane(3) = -h2f * uhat(3) - h2w2 * nhat(3)
mag
= 1 / 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) = w2f * vhat(1) - h2w2 * nhat(1)
topplane(2) = w2f * vhat(2) - h2w2 * nhat(2)
topplane(3) = w2f * vhat(3) - h2w2 * nhat(3)
mag
= 1 / 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) = -w2f * vhat(1) - h2w2 * nhat(1)
bottomplane(2) = -w2f * vhat(2) - h2w2 * nhat(2)
bottomplane(3) = -w2f * vhat(3) - h2w2 * nhat(3)
mag
= 1 / 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
= LowIndex
To HighIndex
vec(i).x = Group(TheGroup).Centroid.x + vec3Dpos(i).x - PlayerCamera.Position.x
vec(i).y = Group(TheGroup).Centroid.y + vec3Dpos(i).y - PlayerCamera.Position.y
vec(i).z = Group(TheGroup).Centroid.z + vec3Dpos(i).z - PlayerCamera.Position.z
f = -1
vec3Dvis(i) = 0
vectorinview = 1
If vec
(i
).x
* nearplane
(1) + vec
(i
).y
* nearplane
(2) + vec
(i
).z
* nearplane
(3) - nearplane
(4) < 0 Then vectorinview
= 0 'IF vec(i).x * farplane(1) + vec(i).y * farplane(2) + vec(i).z* farplane(3) - farplane(4) < 0 THEN vectorinview = 0
If vec
(i
).x
* farplane
(1) + vec
(i
).y
* farplane
(2) + vec
(i
).z
* farplane
(3) - farplane
(4) * .85 < 0 Then f
= 1 'IF vec(i).x * rightplane(1) + vec(i).y * rightplane(2) + vec(i).z * rightplane(3) - rightplane(4) < 0 THEN vectorinview = 0
'IF vec(i).x * leftplane(1) + vec(i).y * leftplane(2) + vec(i).z * leftplane(3) - leftplane(4) < 0 THEN vectorinview = 0
'IF vec(i).x * topplane(1) + vec(i).y * topplane(2) + vec(i).z * topplane(3) - topplane(4) < 0 THEN vectorinview = 0
'IF vec(i).x * bottomplane(1) + vec(i).y * bottomplane(2) + vec(i).z* bottomplane(3) - bottomplane(4) < 0 THEN vectorinview = 0
vec3Dvis(i) = 1
vec3ddotnhat = vec(i).x * nhat(1) + vec(i).y * nhat(2) + vec(i).z * nhat(3)
vec2D(i).u = (vec(i).x * uhat(1) + vec(i).y * uhat(2) + vec(i).z * uhat(3)) * fovd / vec3ddotnhat
vec2D(i).v = (vec(i).x * vhat(1) + vec(i).y * vhat(2) + vec(i).z * vhat(3)) * fovd / vec3ddotnhat
vec2Dcolor(i) = Gray
vec2Dcolor(i) = vec3Dcolor(i)
Dim As Single xx
, yy
, zz
' Needs to be single otherwise the fish flip flop. wtf? 'Dim xx, yy, zz, x0, y0, dx, dy, dz, t, v As Double
' Do nothing.
' Freefall and explode.
Cluster(TheCluster).Velocity.x = Cluster(TheCluster).Velocity.x + Cluster(TheCluster).Acceleration.x
Cluster(TheCluster).Velocity.y = Cluster(TheCluster).Velocity.y + Cluster(TheCluster).Acceleration.y
Cluster(TheCluster).Velocity.z = Cluster(TheCluster).Velocity.z + Cluster(TheCluster).Acceleration.z
dx = Cluster(TheCluster).Velocity.x
dy = Cluster(TheCluster).Velocity.y
dz = Cluster(TheCluster).Velocity.z
Call TranslateCluster
(TheCluster
, dx
, dy
, dz
) wi
= 1 + Int((Cluster
(TheCluster
).Centroid.x
) / BlockSize
+ UBound(WorldMesh
, 1) / 2) wj
= 1 + Int((Cluster
(TheCluster
).Centroid.y
) / BlockSize
+ UBound(WorldMesh
, 2) / 2) If (Cluster
(TheCluster
).Centroid.z
<= WorldMesh
(wi
, wj
)) Then Cluster(TheCluster).Acceleration.x = 0
Cluster(TheCluster).Acceleration.y = 0
Cluster(TheCluster).Acceleration.z = 0
Cluster(TheCluster).Velocity.x = 0
Cluster(TheCluster).Velocity.y = 0
Cluster(TheCluster).Velocity.z = 0
Cluster(TheCluster).MotionType = -9
Cluster
(TheCluster
).DeathTimer
= Timer + 2 k = Cluster(TheCluster).FirstGroup
Group(k).Volume.x = BlockSize * 3
Group(k).Volume.y = BlockSize * 3
Group(k).Volume.z = BlockSize * 3
For u
= Group
(k
).FirstVector
To Group
(k
).LastVector
vec3Dvel
(u
).x
= (Rnd - .5) * .8 vec3Dvel
(u
).y
= (Rnd - .5) * .8 vec3Dvel
(u
).z
= (Rnd - 0) * .8 k = Group(k).Pointer
' Freefall and stack.
Cluster(TheCluster).Velocity.x = Cluster(TheCluster).Velocity.x + Cluster(TheCluster).Acceleration.x
Cluster(TheCluster).Velocity.y = Cluster(TheCluster).Velocity.y + Cluster(TheCluster).Acceleration.y
Cluster(TheCluster).Velocity.z = Cluster(TheCluster).Velocity.z + Cluster(TheCluster).Acceleration.z
dx = Cluster(TheCluster).Velocity.x
dy = Cluster(TheCluster).Velocity.y
dz = Cluster(TheCluster).Velocity.z
Call TranslateCluster
(TheCluster
, dx
, dy
, dz
) wi
= 1 + Int((Cluster
(TheCluster
).Centroid.x
) / BlockSize
+ UBound(WorldMesh
, 1) / 2) wj
= 1 + Int((Cluster
(TheCluster
).Centroid.y
) / BlockSize
+ UBound(WorldMesh
, 2) / 2) If (Cluster
(TheCluster
).Centroid.z
<= WorldMesh
(wi
, wj
)) Then Cluster(TheCluster).Acceleration.x = 0
Cluster(TheCluster).Acceleration.y = 0
Cluster(TheCluster).Acceleration.z = 0
Cluster(TheCluster).Velocity.x = 0
Cluster(TheCluster).Velocity.y = 0
Cluster(TheCluster).Velocity.z = 0
Cluster(TheCluster).MotionType = 0
WorldMesh(wi, wj) = WorldMesh(wi, wj) + BlockSize / 3
Call RemoveCluster
(TheCluster
)
' Fixed path.
' Note: This chunk of code is subject to the midnight bug.
v = t - u
xx = v * FixedPath(Cluster(TheCluster).MotionType, u).x + (1 - v) * FixedPath(Cluster(TheCluster).MotionType, u - 1).x
yy = v * FixedPath(Cluster(TheCluster).MotionType, u).y + (1 - v) * FixedPath(Cluster(TheCluster).MotionType, u - 1).y
zz = v * FixedPath(Cluster(TheCluster).MotionType, u).z + (1 - v) * FixedPath(Cluster(TheCluster).MotionType, u - 1).z
' Choose frame based on derived velocity vector.
If (Cluster
(TheCluster
).Framed
= 1) Then k = Cluster(TheCluster).FirstGroup
If (Group
(k
).FrameLength
<> 0) Then x0 = Group(k).Centroid.x
y0 = Group(k).Centroid.y
'z0 = Group(k).Centroid.z
dx = xx - x0
dy = yy - y0
'dz = zz - z0
If ((dx
> 0) And (dy
> 0)) Then Group
(k
).ActiveFrame
= 1 + Int(((48 / (2 * pi
)) * (Atn(dy
/ dx
)))) If ((dx
< 0) And (dy
> 0)) Then Group
(k
).ActiveFrame
= 1 + 24 + Int(((48 / (2 * pi
)) * (Atn(dy
/ dx
)))) If ((dx
< 0) And (dy
< 0)) Then Group
(k
).ActiveFrame
= 1 + 24 + Int(((48 / (2 * pi
)) * (Atn(dy
/ dx
)))) If ((dx
> 0) And (dy
< 0)) Then Group
(k
).ActiveFrame
= 1 + 48 + Int(((48 / (2 * pi
)) * (Atn(dy
/ dx
)))) k = Group(k).Pointer
Call PlaceCluster
(TheCluster
, xx
, yy
, zz
)
x0 = Cluster(TheCluster).Centroid.x
y0 = Cluster(TheCluster).Centroid.y
z0 = Cluster(TheCluster).Centroid.z
Cluster(TheCluster).Centroid.x = xc
Cluster(TheCluster).Centroid.y = yc
Cluster(TheCluster).Centroid.z = zc
g = Cluster(TheCluster).FirstGroup
Group(g).Centroid.x = Group(g).Centroid.x + xc - x0
Group(g).Centroid.y = Group(g).Centroid.y + yc - y0
Group(g).Centroid.z = Group(g).Centroid.z + zc - z0
g = Group(g).Pointer
g = Cluster(TheCluster).FirstGroup
Group(g).Centroid.x = Group(g).Centroid.x + dx
Group(g).Centroid.y = Group(g).Centroid.y + dy
Group(g).Centroid.z = Group(g).Centroid.z + dz
g = Group(g).Pointer
Cluster(TheCluster).Centroid.x = Cluster(TheCluster).Centroid.x + dx
Cluster(TheCluster).Centroid.y = Cluster(TheCluster).Centroid.y + dy
Cluster(TheCluster).Centroid.z = Cluster(TheCluster).Centroid.z + dz
xdim = Group(TheGroup).Volume.x
ydim = Group(TheGroup).Volume.y
zdim = Group(TheGroup).Volume.z
For g
= Group
(TheGroup
).FirstVector
To Group
(TheGroup
).LastVector
' Position update with periodic boundaries inside group volume.
dx = vec3Dvel(g).x
dy = vec3Dvel(g).y
dz = vec3Dvel(g).z
px = vec3Dpos(g).x + dx
px = -xdim / 2
px = xdim / 2
vec3Dpos(g).x = px
py = vec3Dpos(g).y + dy
py = -ydim / 2
py = ydim / 2
vec3Dpos(g).y = py
pz = vec3Dpos(g).z + dz
pz = -zdim / 2
pz = zdim / 2
vec3Dpos(g).z = pz
m = Group(TheGroup).FirstVector
n = Group(TheGroup).LastVector
vec3Dvel(j).x = vx
vec3Dvel(j).y = vy
vec3Dvel(j).z = vz
' Sorting
If (LowLimit
< HighLimit
) Then piv = Partition(LowLimit, HighLimit)
Call QuickSort
(LowLimit
, piv
- 1) Call QuickSort
(piv
+ 1, HighLimit
)
pivot = Group(SortedGroups(HighLimit)).Distance2
i = LowLimit - 1
For j
= LowLimit
To HighLimit
- 1 tmp = Group(SortedGroups(j)).Distance2 - pivot
i = i + 1
Swap SortedGroups
(i
), SortedGroups
(j
) Swap SortedGroups
(i
+ 1), SortedGroups
(HighLimit
) Partition = i + 1
'Sub BubbleSort
' ' Antiquated but works fine.
' Dim As Integer i, j
' Dim As Double u, v
' For j = SortedGroupsCount To 1 Step -1
' For i = 2 To SortedGroupsCount
' u = Group(SortedGroups(i - 1)).Distance2
' v = Group(SortedGroups(i)).Distance2
' If (u < v) Then
' Swap SortedGroups(i - 1), SortedGroups(i)
' End If
' Next
' Next
'End Sub
' Graphics
NumClusterVisible = 0
NumVectorVisible = 0
SortedGroupsCount = 0
k = 1
If (Cluster
(k
).Visible
= 1) Then NumClusterVisible = NumClusterVisible + 1
g = Cluster(k).FirstGroup
If (Group
(g
).Visible
= 1) Then SortedGroupsCount = SortedGroupsCount + 1
SortedGroups(SortedGroupsCount) = g
g = Group(g).Pointer
k = Cluster(k).Pointer
NumGroupVisible = SortedGroupsCount
Call QuickSort
(1, SortedGroupsCount
) 'Call BubbleSort
PlayerCamera.Shade
= ShadeMix~&
(PlayerCamera.Shade
, _RGB32(_Red32(vec3Dcolor
(Group
(ClosestGroup
).FirstVector
)), _Green32(vec3Dcolor
(Group
(ClosestGroup
).FirstVector
)), _Blue32(vec3Dcolor
(Group
(ClosestGroup
).FirstVector
)), 200), .01) PlayerCamera.Shade
= ShadeMix~&
(PlayerCamera.Shade
, _RGB32(0, 0, 0, 255), .01)
For j
= 1 To SortedGroupsCount
g = SortedGroups(j)
ThePlotMode = Group(g).PlotMode
If (ThePlotMode
= -1) Then ' Wire cube p = Group(g).FirstVector
clrtmp = vec2Dcolor(p)
x1 = vec2D(p).u: y1 = vec2D(p).v: x2 = vec2D(p + 1).u: y2 = vec2D(p + 1).v: x3 = vec2D(p + 2).u: y3 = vec2D(p + 2).v: x4 = vec2D(p + 4).u: y4 = vec2D(p + 4).v
Call CLine
(x1
, y1
, x2
, y2
, clrtmp
) Call CLine
(x1
, y1
, x3
, y3
, clrtmp
) Call CLine
(x1
, y1
, x4
, y4
, clrtmp
) x1 = vec2D(p + 3).u: y1 = vec2D(p + 3).v: x2 = vec2D(p + 1).u: y2 = vec2D(p + 1).v: x3 = vec2D(p + 2).u: y3 = vec2D(p + 2).v: x4 = vec2D(p + 7).u: y4 = vec2D(p + 7).v
Call CLine
(x1
, y1
, x2
, y2
, clrtmp
) Call CLine
(x1
, y1
, x3
, y3
, clrtmp
) Call CLine
(x1
, y1
, x4
, y4
, clrtmp
) x1 = vec2D(p + 5).u: y1 = vec2D(p + 5).v: x2 = vec2D(p + 4).u: y2 = vec2D(p + 4).v: x3 = vec2D(p + 7).u: y3 = vec2D(p + 7).v: x4 = vec2D(p + 1).u: y4 = vec2D(p + 1).v
Call CLine
(x1
, y1
, x2
, y2
, clrtmp
) Call CLine
(x1
, y1
, x3
, y3
, clrtmp
) Call CLine
(x1
, y1
, x4
, y4
, clrtmp
) x1 = vec2D(p + 6).u: y1 = vec2D(p + 6).v: x2 = vec2D(p + 4).u: y2 = vec2D(p + 4).v: x3 = vec2D(p + 7).u: y3 = vec2D(p + 7).v: x4 = vec2D(p + 2).u: y4 = vec2D(p + 2).v
Call CLine
(x1
, y1
, x2
, y2
, clrtmp
) Call CLine
(x1
, y1
, x3
, y3
, clrtmp
) Call CLine
(x1
, y1
, x4
, y4
, clrtmp
)
If Group
(g
).ActiveFrame
= 0 Then lowlim = Group(g).FirstVector
highlim = Group(g).LastVector - 1
lowlim = Group(g).FirstVector + Group(g).FrameLength * (Group(g).ActiveFrame)
highlim = Group(g).FirstVector + Group(g).FrameLength * (Group(g).ActiveFrame + 1) - 2
For p
= lowlim
To highlim
NumVectorVisible = NumVectorVisible + 1
clrtmp = Yellow
clrtmp = vec2Dcolor(p)
x1 = vec2D(p).u
y1 = vec2D(p).v
Call BlockPoint
(x1
, y1
, clrtmp
) x1 = vec2D(p).u
y1 = vec2D(p).v
x2 = vec2D(p + 1).u
y2 = vec2D(p + 1).v
If (((x2
- x1
) * (x2
- x1
) + (y2
- y1
) * (y2
- y1
)) < 225) Then 'Call cline(x1, y1, x2, y2, clrtmp)
Call LineSmooth
(x1
, y1
, x2
, y2
, clrtmp
) Call CCircle
(x1
, y1
, 1, clrtmp
) '''
'If p = highlim Then Call CCircle(x2, y2, 1, clrtmp)
'''
x1 = vec2D(p).u
y1 = vec2D(p).v
Call CCircle
(x1
, y1
, 1, clrtmp
)
Call LineSmooth
(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)), _RGB32(255, 0, 0, 150)) Call LineSmooth
(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)), _RGB32(0, 255, 0, 150)) Call LineSmooth
(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)), _RGB32(30, 144, 255, 150)) Call TextCenter
(" Closest ", (1) * 16, LimeGreen
) a = " " + Group(ClosestGroup).Label + " "
'_PrintString ((1) * 8, (5) * 16), "Clusters: " + LTrim$(RTrim$(Str$(NumClusterVisible)))
'_PrintString ((1) * 8, (4) * 16), "Groups: " + LTrim$(RTrim$(Str$(NumGroupVisible)))
Call TextCenter
(" SPACE = Ascend ", _Height - (2) * 16, LimeGreen
)
wi
= 1 + Int((PlayerCamera.Position.x
) / BlockSize
+ UBound(WorldMesh
, 1) / 2) wj
= 1 + Int((PlayerCamera.Position.y
) / BlockSize
+ UBound(WorldMesh
, 2) / 2) Shade = TerrainHeightShade~&(WorldMesh(i, j))
Call CCircle
(wi
+ u
, wj
+ v
, 2, Red
) Call LineSmooth
(wi
+ u
, wj
+ v
, wi
+ u
- 5 * nhat
(1) * Sqr((fovd
/ -192)), wj
+ v
- 5 * nhat
(2) * Sqr((fovd
/ -192)), White
) Color DarkKhaki
, PlayerCamera.Shade
dx = -nhat(1)
dy = -nhat(2)
' Interface
modifier = 0.05
PlayerCamera.Velocity.z = 5
PlayerCamera.Acceleration.z = -.5
Call StrafeCameraNhat
(-1, -1, 0) If ((nhat
(3) <> 0) Or (uhat
(3) <> 0)) Then Call RegulateCamera
PlayerCamera.Velocity.x = PlayerCamera.Velocity.x - modifier * nhat(1)
PlayerCamera.Velocity.y = PlayerCamera.Velocity.y - modifier * nhat(2)
'PlayerCamera.Velocity.z = PlayerCamera.Velocity.z - modifier * nhat(3)
Call StrafeCameraNhat
(1, 1, 0) If ((nhat
(3) <> 0) Or (uhat
(3) <> 0)) Then Call RegulateCamera
PlayerCamera.Velocity.x = PlayerCamera.Velocity.x + modifier * nhat(1)
PlayerCamera.Velocity.y = PlayerCamera.Velocity.y + modifier * nhat(2)
'PlayerCamera.Velocity.z = PlayerCamera.Velocity.z + modifier * nhat(3)
If ((nhat
(3) <> 0) Or (uhat
(3) <> 0)) Then Call RegulateCamera
Call StrafeCameraUhat
(-1, -1, -1) PlayerCamera.Velocity.x = PlayerCamera.Velocity.x - modifier * uhat(1)
PlayerCamera.Velocity.y = PlayerCamera.Velocity.y - modifier * uhat(2)
'PlayerCamera.Velocity.z = PlayerCamera.Velocity.z - modifier * uhat(3)
If ((nhat
(3) <> 0) Or (uhat
(3) <> 0)) Then Call RegulateCamera
Call StrafeCameraUhat
(1, 1, 1) PlayerCamera.Velocity.x = PlayerCamera.Velocity.x + modifier * uhat(1)
PlayerCamera.Velocity.y = PlayerCamera.Velocity.y + modifier * uhat(2)
'PlayerCamera.Velocity.z = PlayerCamera.Velocity.z + modifier * uhat(3)
'If ((_KeyDown(81) <> 0) Or (_KeyDown(113) <> 0)) Then ' Q or q
' Call StrafeCameraVhat(1, 1, 1)
' If (ToggleAnimate = 1) Then
' PlayerCamera.Velocity.x = PlayerCamera.Velocity.x - modifier * vhat(1)
' PlayerCamera.Velocity.y = PlayerCamera.Velocity.y - modifier * vhat(2)
' PlayerCamera.Velocity.z = PlayerCamera.Velocity.z - modifier * vhat(3)
' End If
'End If
'If ((_KeyDown(69) <> 0) Or (_KeyDown(101) <> 0)) Then ' E or e
' Call StrafeCameraVhat(-1, -1, -1)
' If (ToggleAnimate = 1) Then
' PlayerCamera.Velocity.x = PlayerCamera.Velocity.x + modifier * vhat(1)
' PlayerCamera.Velocity.y = PlayerCamera.Velocity.y + modifier * vhat(2)
' PlayerCamera.Velocity.z = PlayerCamera.Velocity.z + modifier * vhat(3)
' End If
'End If
fovd = fovd - 5
fovd = -600
farplane(4) = farplane(4) - 5
modifier = 0.0333
If (_KeyDown(49) <> 0) Then Call RotateUhat
(-modifier
, -modifier
, -modifier
):
Call CalculateScreenVectors:
Call RotateUV
(-modifier
, -modifier
, -modifier
) ' 1 If (_KeyDown(51) <> 0) Then Call RotateUhat
(modifier
, modifier
, modifier
):
Call CalculateScreenVectors:
Call RotateUV
(modifier
, modifier
, modifier
) ' 3
'modifier = 0.0222
'Do While _MouseInput
' If (_MouseMovementX > 0) Then Call RotateUhat(modifier, modifier, modifier): Call CalculateScreenVectors
' If (_MouseMovementX < 0) Then Call RotateUhat(-modifier, -modifier, -modifier): Call CalculateScreenVectors
' If (_MouseMovementY > 0) Then Call RotateVhat(modifier, modifier, modifier): Call CalculateScreenVectors
' If (_MouseMovementY < 0) Then Call RotateVhat(-modifier, -modifier, -modifier): Call CalculateScreenVectors
'Loop
x0 = (PlayerCamera.Position.x - 40 * nhat(1))
y0 = (PlayerCamera.Position.y - 40 * nhat(2))
z0 = (PlayerCamera.Position.z - 40 * nhat(3))
x0
= x0
- x0
Mod BlockSize
/ 3 y0
= y0
- y0
Mod BlockSize
/ 3 z0
= z0
- z0
Mod BlockSize
/ 3 g = LatestGroupIdentity&(1)
g = NewCube&(g, "Custom block", 100, x0, y0, z0, BlockSize / 3, BlockSize / 3, BlockSize / 3, Lime, Purple, Teal, -2, 0)
g = NewWireCube&(g, "Custom block", x0, y0, z0, BlockSize / 3, BlockSize / 3, BlockSize / 3, Lime, -2)
Cluster(ClusterIdTicker).Acceleration.x = 0
Cluster(ClusterIdTicker).Acceleration.y = 0
Cluster(ClusterIdTicker).Acceleration.z = -.15
x0 = (PlayerCamera.Position.x - 40 * nhat(1))
y0 = (PlayerCamera.Position.y - 40 * nhat(2))
z0 = (PlayerCamera.Position.z - 40 * nhat(3))
g = LatestGroupIdentity&(1)
g = NewCube&(g, "Potion", 150, x0, y0, z0, 10, 10, 10, Red, Purple, Teal, -1, 0)
g = NewCube&(g, "Potion", 50, x0, y0, z0 + 10, 2, 2, 10, Blue, Purple, Teal, -1, 0)
Cluster(ClusterIdTicker).Acceleration.x = 0
Cluster(ClusterIdTicker).Acceleration.y = 0
Cluster(ClusterIdTicker).Acceleration.z = -.15
Cluster(ClusterIdTicker).Velocity.x = -5 * nhat(1)
Cluster(ClusterIdTicker).Velocity.y = -5 * nhat(2)
Cluster(ClusterIdTicker).Velocity.z = -5 * nhat(3)
For p
= Group
(ClosestGroup
).FirstVector
To Group
(ClosestGroup
).LastVector
vec3Dvel
(p
).x
= (Rnd - .5) * .20 vec3Dvel
(p
).y
= (Rnd - .5) * .20 vec3Dvel
(p
).z
= (Rnd - .5) * .20
Call RemoveGroup
(ClosestGroup
)
ToggleAnimate = -ToggleAnimate
' Plotting and color tools.
' source: https://en.wikipedia.org/w/index.php?title=Xiaolin_Wu%27s_line_algorithm&oldid=852445548
' translated: FellippeHeitor @ qb64.org
' updated slightly for this project
steep
= Abs(y1
- y0
) > Abs(x1
- x0
)
dx = x1 - x0
dy = y1 - y0
gradient = dy / dx
gradient = 1
'handle first endpoint
Dim xend
, yend
, xgap
, xpxl1
, ypxl1
yend = y0 + gradient * (xend - x0)
xgap
= (1 - ((x0
+ .5) - Int(x0
+ .5))) xpxl1 = xend 'this will be used in the main loop
plX = ypxl1
plY = xpxl1
plI
= (1 - (yend
- Int(yend
))) * xgap
plX = ypxl1 + 1
plY = xpxl1
plI
= (yend
- Int(yend
)) * xgap
plX = xpxl1
plY = ypxl1
plI
= (1 - (yend
- Int(yend
))) * xgap
plX = xpxl1
plY = ypxl1 + 1
plI
= (yend
- Int(yend
)) * xgap
intery = yend + gradient 'first y-intersection for the main loop
'handle second endpoint
yend = y1 + gradient * (xend - x1)
xgap
= ((x1
+ .5) - Int(x1
+ .5)) xpxl2 = xend 'this will be used in the main loop
plX = ypxl2
plY = xpxl2
plI
= (1 - (yend
- Int(yend
))) * xgap
plX = ypxl2 + 1
plY = xpxl2
plI
= (yend
- Int(yend
)) * xgap
plX = xpxl2
plY = ypxl2
plI
= (1 - (yend
- Int(yend
))) * xgap
plX = xpxl2
plY = ypxl2 + 1
plI
= (yend
- Int(yend
)) * xgap
'main loop
For x
= xpxl1
+ 1 To xpxl2
- 1 plY = x
plI
= (1 - (intery
- Int(intery
)))
plY = x
plI
= (intery
- Int(intery
))
intery = intery + gradient
For x
= xpxl1
+ 1 To xpxl2
- 1 plX = x
plI
= (1 - (intery
- Int(intery
)))
plX = x
plI
= (intery
- Int(intery
))
intery = intery + gradient
plot:
' Change to regular PSET for standard coordinate orientation.
' Camera transformation
uhat(1) = uhat(1) + nhat(1) * dx
uhat(2) = uhat(2) + nhat(2) * dy
uhat(3) = uhat(3) + nhat(3) * dz
vhat(1) = vhat(1) + nhat(1) * dx
vhat(2) = vhat(2) + nhat(2) * dy
vhat(3) = vhat(3) + nhat(3) * dz
v1 = vhat(1)
v2 = vhat(2)
v3 = vhat(3)
vhat(1) = v1 + uhat(1) * dx
vhat(2) = v2 + uhat(2) * dy
vhat(3) = v3 + uhat(3) * dz
uhat(1) = uhat(1) - v1 * dx
uhat(2) = uhat(2) - v2 * dy
uhat(3) = uhat(3) - v3 * dz
PlayerCamera.Position.x = PlayerCamera.Position.x + uhat(1) * dx
PlayerCamera.Position.y = PlayerCamera.Position.y + uhat(2) * dy
PlayerCamera.Position.z = PlayerCamera.Position.z + uhat(3) * dz
PlayerCamera.Position.x = PlayerCamera.Position.x + vhat(1) * dx
PlayerCamera.Position.y = PlayerCamera.Position.y + vhat(2) * dy
PlayerCamera.Position.z = PlayerCamera.Position.z + vhat(3) * dz
PlayerCamera.Position.x = PlayerCamera.Position.x + nhat(1) * dx
PlayerCamera.Position.y = PlayerCamera.Position.y + nhat(2) * dy
PlayerCamera.Position.z = PlayerCamera.Position.z + nhat(3) * dz
'''