Just another screenshot of terrain with trees this time.
I spent about a week reorganizing the code into functional blocks, so progress has been a little slow.
As you can see, LOD hasn't been implemented yet so the engine stops drawing trees not too far in the distance, about 750ft.
The next important things I'll be working on are LOD and terrain/plant/scrounge placement so things don't end up on top of each other sometimes.
The following is just to show how things are loaded into the engine, and how easy it can be to manage objects using names rather than object numbers.
LoadTexture("skybox\moonc.png", "Moon", 1)
LoadMesh("skybox\moona.x", "Planetoid", "Moon", "Moon")
TextureMesh("Moon", "Moon")
PositionMesh("Moon", 0, 7500, 24500)
MeshCullOn("Moon")
MeshFogOff("Moon")
MeshLightOn("Moon")
SetMeshEmissive("Moon", rgb(255, 255, 255))
LoadMesh("Terrains\plain.x", "Terrain Base", "Base", "Plain")
PositionMesh("Plain", 0, 0, 0)
ColorMesh("Plain", rgb(150, 50, 40))
MeshCullOn("Plain")
MeshFogOn("Plain")
MeshLightOn("Plain")
LoadTexture("skybox\skye.png", "Sky", 1)
LoadMesh("Skybox\skyspherea.x", "Sky", "Skysphere", "Sky")
PositionMesh("Sky", 0, 0, 0)
TextureMesh("Sky", "Sky")
MeshCullOn("Sky")
MeshFogOff("Sky")
MeshLightOff("Sky")
SetMeshEmissive("Sky", rgb(255, 255, 255))
for a = 1 to 12
LoadMesh("Terrains\mesaa.x", "Terrain", "Base", "Mesa A" + str$(a))
PositionMesh("Mesa A" + str$(a), RandomWithSign(25000), 0, RandomWithSign(25000))
RotateMesh("Mesa A" + str$(a), 0, RandomWithSign(180), 0)
MeshCullOn("Mesa A" + str$(a))
ColorMesh("Mesa A" + str$(a), rgb(150, 50, 40))
next a
for a = 1 to 12
LoadMesh("Terrains\mesab.x", "Terrain", "Base", "Mesa B" + str$(a))
PositionMesh("Mesa B" + str$(a), RandomWithSign(25000), 0, RandomWithSign(25000))
RotateMesh("Mesa B" + str$(a), 0, RandomWithSign(180), 0)
MeshCullOn("Mesa B" + str$(a))
MeshLightOn("Mesa B" + str$(a))
ColorMesh("Mesa B" + str$(a), rgb(150, 50, 40))
next a
for a = 1 to 10
LoadTexture("plants\trees\scrub pines\scrub pine.png", "Scrub Pine", 1)
LoadMesh("plants\trees\scrub pines\scrub pine a1.x", "Foliage", "Tree", "Scrub Pine A" + str$(a))
PositionMesh("Scrub Pine A" + str$(a), RandomWithSign(250), 0, RandomWithSign(250))
RotateMesh("Scrub Pine A" + str$(a), 0, RandomWithSign(180), 0)
MeshCullOn("Scrub Pine A" + str$(a))
MeshLightOn("Scrub Pine A" + str$(a))
TextureMesh("Scrub Pine A" + str$(a), "Scrub Pine")
next a
for a = 1 to 10
LoadTexture("plants\trees\scrub pines\scrub pine.png", "Scrub Pine", 1)
LoadMesh("plants\trees\scrub pines\scrub pine b1.x", "Foliage", "Tree", "Scrub Pine B" + str$(a))
PositionMesh("Scrub Pine B" + str$(a), RandomWithSign(250), 0, RandomWithSign(250))
RotateMesh("Scrub Pine B" + str$(a), 0, RandomWithSign(180), 0)
MeshCullOn("Scrub Pine B" + str$(a))
MeshLightOn("Scrub Pine B" + str$(a))
TextureMesh("Scrub Pine B" + str$(a), "Scrub Pine")
next a
for a = 1 to 56
LoadTexture("plants\trees\scrub pines\scrub pine.png", "Scrub Pine", 1)
LoadMesh("plants\trees\scrub pines\scrub pine c1.x", "Foliage", "Tree", "Scrub Pine C" + str$(a))
PositionMesh("Scrub Pine C" + str$(a), RandomWithSign(250), 0, RandomWithSign(250))
RotateMesh("Scrub Pine C" + str$(a), 0, RandomWithSign(180), 0)
MeshCullOn("Scrub Pine C" + str$(a))
MeshLightOn("Scrub Pine C" + str$(a))
TextureMesh("Scrub Pine C" + str$(a), "Scrub Pine")
next a
When a request to load a resource such as a texture or mesh(object) is received by the various managers, they check to see if that particular file has already been loaded. If it has its just assigned a new number and cloned (in the case of objects). Otherwise its loaded from disk. After that its assigned the name specified by the "load" command. No two resources can have the same name, as this is the way resources are normally referenced by other processes. Resources also are grouped into classes for tasks such as collision checking, placement checking, etc. For example, "Foliage" would be a class, "Tree" a subclass, and "Scrub Pine C" the name of a particular object.
The reason for classes and subclasses is to allow easy parameter checking. The following illustrates this:
function GetTerrainHeight(X#, Y#, Z#)
Name$ = NearestMeshClass("Terrain", X#, Y#, Z#, "", "", "")
if WithinMeshBounds(Name$, X#, Y#, Z#)
rem If we are here it means that a terrain feature is closest to us
YMax# = Y# + 10000
TerrainHeight# = YMax# - IntersectMesh(Name$, X#, YMax#, Z#, X#, -YMax#, Z#)
if WithinBounds(TerrainHeight#, 9999.9, 10000.1) < 0
exitfunction TerrainHeight#
else
rem If we are here it means that we didn't hit the terrain feature's mesh
YMax# = Y# + 10000
TerrainHeight# = YMax# - IntersectMesh("Plain", X#, YMax#, Z#, X#, -YMax#, Z#)
endif
else
rem If we are here it means we aren't near any terrain feature
YMax# = Y# + 10000
TerrainHeight# = YMax# - IntersectMesh("Plain", X#, YMax#, Z#, X#, -YMax#, Z#)
endif
endfunction TerrainHeight#
The line "Name$ = NearestMeshClass("Terrain", X#, Y#, Z#, "", "", "")" returns the name of the nearest mesh to the given x, y, z coordinates. A class can also be specified, which is "Terrain" in this case, so it will return the name of the nearest terrain feature. Also notice the three empty strings at the end of the line. They are used to exclude up to three different named objects from the check for other functions such as object placement calculations.
The Great Nateholio
<img src="http://ixeelectronics.com/Nateholio/Pictures/Sigblock.PNG">