summaryrefslogtreecommitdiffstats
path: root/src/graphics/engine/terrain.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/graphics/engine/terrain.cpp')
-rw-r--r--src/graphics/engine/terrain.cpp957
1 files changed, 455 insertions, 502 deletions
diff --git a/src/graphics/engine/terrain.cpp b/src/graphics/engine/terrain.cpp
index 971eed1..3e70719 100644
--- a/src/graphics/engine/terrain.cpp
+++ b/src/graphics/engine/terrain.cpp
@@ -44,111 +44,88 @@ Gfx::CTerrain::CTerrain(CInstanceManager* iMan)
m_engine = static_cast<Gfx::CEngine*>( m_iMan->SearchInstance(CLASS_ENGINE) );
m_water = static_cast<Gfx::CWater*>( m_iMan->SearchInstance(CLASS_WATER) );
- m_mosaic = 20;
- m_brick = 1 << 4;
- m_size = 10.0f;
- m_vision = 200.0f;
- m_scaleMapping = 0.01f;
- m_scaleRelief = 1.0f;
- m_subdivMapping = 1;
- m_depth = 2;
- m_levelMatMax = 0;
- m_multiText = true;
- m_levelText = false;
- m_wind = Math::Vector(0.0f, 0.0f, 0.0f);
- m_defHardness = 0.5f;
-
- m_levelMats.reserve(LEVEL_MAT_PREALLOCATE_COUNT);
+ m_mosaicCount = 20;
+ m_brickCount = 1 << 4;
+ m_brickSize = 10.0f;
+ m_vision = 200.0f;
+ m_textureScale = 0.01f;
+ m_scaleRelief = 1.0f;
+ m_textureSubdivCount = 1;
+ m_depth = 2;
+ m_maxMaterialID = 0;
+ m_wind = Math::Vector(0.0f, 0.0f, 0.0f);
+ m_defaultHardness = 0.5f;
+ m_useMaterials = false;
+
+ m_materials.reserve(LEVEL_MAT_PREALLOCATE_COUNT);
m_flyingLimits.reserve(FLYING_LIMIT_PREALLOCATE_COUNT);
m_buildingLevels.reserve(BUILDING_LEVEL_PREALLOCATE_COUNT);
+
+ FlushBuildingLevel();
+ FlushFlyingLimit();
+ FlushMaterials();
}
Gfx::CTerrain::~CTerrain()
{
}
-/**
- The terrain is composed of mosaics, themselves composed of bricks.
- Each brick is composed of two triangles.
- mosaic: number of mosaics along the axes X and Z
- brick: number of bricks (power of 2)
- size: size of a brick along the axes X and Z
- vision: vision before a change of resolution
- scaleMapping: scale textures for mapping
-
-\verbatim
- ^ z
- | <---> brick*size
- +---+---+---+---+
- | | | |_|_| mosaic = 4
- | | | | | | brick = 2 (brickP2=1)
- +---+---+---+---+
- |\ \| | | |
- |\ \| | | |
- +---+---o---+---+---> x
- | | | | |
- | | | | |
- +---+---+---+---+
- | | | | | The land is viewed from above here.
- | | | | |
- +---+---+---+---+
- <---------------> mosaic*brick*size
-\endverbatim */
-bool Gfx::CTerrain::Generate(int mosaic, int brickPow2, float size, float vision,
- int depth, float hardness)
+bool Gfx::CTerrain::Generate(int mosaicCount, int brickCountPow2, float brickSize,
+ float vision, int depth, float hardness)
{
- m_mosaic = mosaic;
- m_brick = 1 << brickPow2;
- m_size = size;
+ m_mosaicCount = mosaicCount;
+ m_brickCount = 1 << brickCountPow2;
+ m_brickSize = brickSize;
m_vision = vision;
m_depth = depth;
- m_defHardness = hardness;
+ m_defaultHardness = hardness;
m_engine->SetTerrainVision(vision);
- m_multiText = true;
- m_levelText = false;
- m_scaleMapping = 1.0f / (m_brick*m_size);
- m_subdivMapping = 1;
+ m_textureScale = 1.0f / (m_brickCount*m_brickSize);
+ m_textureSubdivCount = 1;
+
+ m_useMaterials = false;
int dim = 0;
- dim = (m_mosaic*m_brick+1)*(m_mosaic*m_brick+1);
+ dim = (m_mosaicCount*m_brickCount+1)*(m_mosaicCount*m_brickCount+1);
std::vector<float>(dim).swap(m_relief);
- dim = m_mosaic*m_subdivMapping*m_mosaic*m_subdivMapping;
- std::vector<int>(dim).swap(m_texture);
+ dim = m_mosaicCount*m_textureSubdivCount*m_mosaicCount*m_textureSubdivCount;
+ std::vector<int>(dim).swap(m_textures);
- dim = m_mosaic*m_mosaic;
- std::vector<int>(dim).swap(m_objRank);
+ dim = m_mosaicCount*m_mosaicCount;
+ std::vector<int>(dim).swap(m_objRanks);
return true;
}
-int Gfx::CTerrain::GetMosaic()
+int Gfx::CTerrain::GetMosaicCount()
{
- return m_mosaic;
+ return m_mosaicCount;
}
-int Gfx::CTerrain::GetBrick()
+int Gfx::CTerrain::GetBrickCount()
{
- return m_brick;
+ return m_brickCount;
}
-float Gfx::CTerrain::GetSize()
+float Gfx::CTerrain::GetBrickSize()
{
- return m_size;
+ return m_brickSize;
}
-float Gfx::CTerrain::GetScaleRelief()
+float Gfx::CTerrain::GetReliefScale()
{
return m_scaleRelief;
}
bool Gfx::CTerrain::InitTextures(const std::string& baseName, int* table, int dx, int dy)
{
- m_levelText = false;
+ m_useMaterials = false;
+
m_texBaseName = baseName;
size_t pos = baseName.find('.');
if (pos == baseName.npos)
@@ -161,69 +138,60 @@ bool Gfx::CTerrain::InitTextures(const std::string& baseName, int* table, int dx
m_texBaseExt = m_texBaseName.substr(pos);
}
- for (int y = 0; y < m_mosaic*m_subdivMapping; y++)
+ for (int y = 0; y < m_mosaicCount*m_textureSubdivCount; y++)
{
- for (int x = 0; x < m_mosaic*m_subdivMapping; x++)
+ for (int x = 0; x < m_mosaicCount*m_textureSubdivCount; x++)
{
- m_texture[x+y*m_mosaic] = table[(x%dx)+(y%dy)*dx];
+ m_textures[x+y*m_mosaicCount] = table[(x%dx)+(y%dy)*dx];
}
}
return true;
}
-void Gfx::CTerrain::LevelFlush()
+void Gfx::CTerrain::FlushMaterials()
{
- m_levelMats.clear();
- m_levelMatMax = 0;
- m_levelID = 1000;
- LevelCloseTable();
+ m_materials.clear();
+ m_maxMaterialID = 0;
+ m_materialAutoID = 1000;
+ FlushMaterialPoints();
}
-void Gfx::CTerrain::LevelMaterial(int id, const std::string& baseName, float u, float v,
- int up, int right, int down, int left,
- float hardness)
+void Gfx::CTerrain::AddMaterial(int id, const std::string& texName, const Math::Point &uv,
+ int up, int right, int down, int left,
+ float hardness)
{
- LevelOpenTable();
+ InitMaterialPoints();
if (id == 0)
- id = m_levelID++; // puts an ID internal standard
+ id = m_materialAutoID++;
Gfx::TerrainMaterial tm;
- tm.texName = baseName;
+ tm.texName = texName;
tm.id = id;
- tm.u = u;
- tm.v = v;
+ tm.uv = uv;
tm.mat[0] = up;
tm.mat[1] = right;
tm.mat[2] = down;
tm.mat[3] = left;
tm.hardness = hardness;
- m_levelMats.push_back(tm);
+ m_materials.push_back(tm);
- if (m_levelMatMax < up+1 ) m_levelMatMax = up+1;
- if (m_levelMatMax < right+1) m_levelMatMax = right+1;
- if (m_levelMatMax < down+1 ) m_levelMatMax = down+1;
- if (m_levelMatMax < left+1 ) m_levelMatMax = left+1;
+ if (m_maxMaterialID < up+1 ) m_maxMaterialID = up+1;
+ if (m_maxMaterialID < right+1) m_maxMaterialID = right+1;
+ if (m_maxMaterialID < down+1 ) m_maxMaterialID = down+1;
+ if (m_maxMaterialID < left+1 ) m_maxMaterialID = left+1;
- m_levelText = true;
- m_subdivMapping = 4;
+ m_useMaterials = true;
+ m_textureSubdivCount = 4;
}
/**
- The size of the image must be dimension dx and dy with dx=dy=(mosaic*brick)+1.
- The image must be 24 bits/pixel
-
- Converts coordinated image (x;y) -> world (x;-;z) :
- Wx = 5*Ix-400
- Wz = -(5*Iy-400)
-
- Converts coordinated world (x;-;z) -> image (x;y) :
- Ix = (400+Wx)/5
- Iy = (400-Wz)/5 */
-bool Gfx::CTerrain::ResFromPNG(const std::string& fileName)
+ * The image must be 24 bits/pixel and grayscale and dx x dy in size
+ * with dx = dy = (mosaic*brick)+1 */
+bool Gfx::CTerrain::LoadResources(const std::string& fileName)
{
CImage img;
if (! img.Load(CApplication::GetInstance().GetDataFilePath(m_engine->GetTextureDir(), fileName)))
@@ -231,7 +199,7 @@ bool Gfx::CTerrain::ResFromPNG(const std::string& fileName)
ImageData *data = img.GetData();
- int size = (m_mosaic*m_brick)+1;
+ int size = (m_mosaicCount*m_brickCount)+1;
m_resources.clear();
@@ -257,14 +225,14 @@ Gfx::TerrainRes Gfx::CTerrain::GetResource(const Math::Vector &p)
if (m_resources.empty())
return Gfx::TR_NULL;
- int x = static_cast<int>((p.x + (m_mosaic*m_brick*m_size)/2.0f)/m_size);
- int y = static_cast<int>((p.z + (m_mosaic*m_brick*m_size)/2.0f)/m_size);
+ int x = static_cast<int>((p.x + (m_mosaicCount*m_brickCount*m_brickSize)/2.0f)/m_brickSize);
+ int y = static_cast<int>((p.z + (m_mosaicCount*m_brickCount*m_brickSize)/2.0f)/m_brickSize);
- if ( x < 0 || x > m_mosaic*m_brick ||
- y < 0 || y > m_mosaic*m_brick )
+ if ( x < 0 || x > m_mosaicCount*m_brickCount ||
+ y < 0 || y > m_mosaicCount*m_brickCount )
return Gfx::TR_NULL;
- int size = (m_mosaic*m_brick)+1;
+ int size = (m_mosaicCount*m_brickCount)+1;
int resR = m_resources[3*x+3*size*(size-y-1)];
int resG = m_resources[3*x+3*size*(size-y-1)+1];
@@ -289,20 +257,10 @@ void Gfx::CTerrain::FlushRelief()
}
/**
- The size of the image must be dimension dx and dy with dx=dy=(mosaic*brick)+1.
- The image must be 24 bits/pixel, but gray scale:
- white = ground (y=0)
- black = mountain (y=255*scaleRelief)
-
- Converts coordinated image(x;y) -> world (x;-;z) :
- Wx = 5*Ix-400
- Wz = -(5*Iy-400)
-
- Converts coordinated world (x;-;z) -> image (x;y) :
- Ix = (400+Wx)/5
- Iy = (400-Wz)/5 */
-bool Gfx::CTerrain::ReliefFromPNG(const std::string &fileName, float scaleRelief,
- bool adjustBorder)
+ * The image must be 24 bits/pixel and dx x dy in size
+ * with dx = dy = (mosaic*brick)+1 */
+bool Gfx::CTerrain::LoadRelief(const std::string &fileName, float scaleRelief,
+ bool adjustBorder)
{
m_scaleRelief = scaleRelief;
@@ -312,7 +270,7 @@ bool Gfx::CTerrain::ReliefFromPNG(const std::string &fileName, float scaleRelief
ImageData *data = img.GetData();
- int size = (m_mosaic*m_brick)+1;
+ int size = (m_mosaicCount*m_brickCount)+1;
if ( (data->surface->w != size) || (data->surface->h != size) ||
(data->surface->format->BytesPerPixel != 3) )
@@ -346,13 +304,13 @@ bool Gfx::CTerrain::ReliefFromPNG(const std::string &fileName, float scaleRelief
return true;
}
-bool Gfx::CTerrain::ReliefAddDot(Math::Vector pos, float scaleRelief)
+bool Gfx::CTerrain::AddReliefPoint(Math::Vector pos, float scaleRelief)
{
- float dim = (m_mosaic*m_brick*m_size)/2.0f;
- int size = (m_mosaic*m_brick)+1;
+ float dim = (m_mosaicCount*m_brickCount*m_brickSize)/2.0f;
+ int size = (m_mosaicCount*m_brickCount)+1;
- pos.x = (pos.x+dim)/m_size;
- pos.z = (pos.z+dim)/m_size;
+ pos.x = (pos.x+dim)/m_brickSize;
+ pos.z = (pos.z+dim)/m_brickSize;
int x = static_cast<int>(pos.x);
int y = static_cast<int>(pos.z);
@@ -366,33 +324,20 @@ bool Gfx::CTerrain::ReliefAddDot(Math::Vector pos, float scaleRelief)
return true;
}
-void Gfx::CTerrain::LimitPos(Math::Vector &pos)
-{
-// TODO: #if _TEEN
-// dim = (m_mosaic*m_brick*m_size)/2.0f*0.98f;
-
- float dim = (m_mosaic*m_brick*m_size)/2.0f*0.92f;
-
- if (pos.x < -dim) pos.x = -dim;
- if (pos.x > dim) pos.x = dim;
- if (pos.z < -dim) pos.z = -dim;
- if (pos.z > dim) pos.z = dim;
-}
-
void Gfx::CTerrain::AdjustRelief()
{
- if (m_depth == 1) return;
+ if (m_depth == 1) return;
- int ii = m_mosaic*m_brick+1;
+ int ii = m_mosaicCount*m_brickCount+1;
int b = 1 << (m_depth-1);
- for (int y = 0; y < m_mosaic*m_brick; y += b)
+ for (int y = 0; y < m_mosaicCount*m_brickCount; y += b)
{
- for (int x = 0; x < m_mosaic*m_brick; x += b)
+ for (int x = 0; x < m_mosaicCount*m_brickCount; x += b)
{
int xx = 0;
int yy = 0;
- if ((y+yy)%m_brick == 0)
+ if ((y+yy)%m_brickCount == 0)
{
float level1 = m_relief[(x+0)+(y+yy)*ii];
float level2 = m_relief[(x+b)+(y+yy)*ii];
@@ -403,7 +348,7 @@ void Gfx::CTerrain::AdjustRelief()
}
yy = b;
- if ((y+yy)%m_brick == 0)
+ if ((y+yy)%m_brickCount == 0)
{
float level1 = m_relief[(x+0)+(y+yy)*ii];
float level2 = m_relief[(x+b)+(y+yy)*ii];
@@ -414,7 +359,7 @@ void Gfx::CTerrain::AdjustRelief()
}
xx = 0;
- if ((x+xx)%m_brick == 0)
+ if ((x+xx)%m_brickCount == 0)
{
float level1 = m_relief[(x+xx)+(y+0)*ii];
float level2 = m_relief[(x+xx)+(y+b)*ii];
@@ -425,7 +370,7 @@ void Gfx::CTerrain::AdjustRelief()
}
xx = b;
- if ((x+xx)%m_brick == 0)
+ if ((x+xx)%m_brickCount == 0)
{
float level1 = m_relief[(x+xx)+(y+0)*ii];
float level2 = m_relief[(x+xx)+(y+b)*ii];
@@ -441,14 +386,14 @@ void Gfx::CTerrain::AdjustRelief()
Math::Vector Gfx::CTerrain::GetVector(int x, int y)
{
Math::Vector p;
- p.x = x*m_size - (m_mosaic*m_brick*m_size)/2;
- p.z = y*m_size - (m_mosaic*m_brick*m_size)/2;
+ p.x = x*m_brickSize - (m_mosaicCount*m_brickCount*m_brickSize) / 2.0;
+ p.z = y*m_brickSize - (m_mosaicCount*m_brickCount*m_brickSize) / 2.0;
- if ( !m_relief.empty() &&
- x >= 0 && x <= m_mosaic*m_brick &&
- y >= 0 && y <= m_mosaic*m_brick )
+ if ( !m_relief.empty() &&
+ x >= 0 && x <= m_mosaicCount*m_brickCount &&
+ y >= 0 && y <= m_mosaicCount*m_brickCount )
{
- p.y = m_relief[x+y*(m_mosaic*m_brick+1)];
+ p.y = m_relief[x+y*(m_mosaicCount*m_brickCount+1)];
}
else
{
@@ -458,7 +403,7 @@ Math::Vector Gfx::CTerrain::GetVector(int x, int y)
return p;
}
-/** Calculates a normal soft, taking into account the six adjacent triangles:
+/** Calculates an averaged normal, taking into account the six adjacent triangles:
\verbatim
^ y
@@ -487,16 +432,16 @@ Gfx::VertexTex2 Gfx::CTerrain::GetVertex(int x, int y, int step)
Math::Vector s(0.0f, 0.0f, 0.0f);
- if (x-step >= 0 && y+step <= m_mosaic*m_brick+1)
+ if (x-step >= 0 && y+step <= m_mosaicCount*m_brickCount+1)
{
s += Math::NormalToPlane(b,a,o);
s += Math::NormalToPlane(c,b,o);
}
- if (x+step <= m_mosaic*m_brick+1 && y+step <= m_mosaic*m_brick+1)
+ if (x+step <= m_mosaicCount*m_brickCount+1 && y+step <= m_mosaicCount*m_brickCount+1)
s += Math::NormalToPlane(d,c,o);
- if (x+step <= m_mosaic*m_brick+1 && y-step >= 0)
+ if (x+step <= m_mosaicCount*m_brickCount+1 && y-step >= 0)
{
s += Math::NormalToPlane(e,d,o);
s += Math::NormalToPlane(f,e,o);
@@ -508,19 +453,11 @@ Gfx::VertexTex2 Gfx::CTerrain::GetVertex(int x, int y, int step)
s = Normalize(s);
v.normal = s;
- if (m_multiText)
- {
- int brick = m_brick/m_subdivMapping;
- Math::Vector oo = GetVector((x/brick)*brick, (y/brick)*brick);
- o = GetVector(x, y);
- v.texCoord.x = (o.x-oo.x)*m_scaleMapping*m_subdivMapping;
- v.texCoord.y = 1.0f - (o.z-oo.z)*m_scaleMapping*m_subdivMapping;
- }
- else
- {
- v.texCoord.x = o.x*m_scaleMapping;
- v.texCoord.y = o.z*m_scaleMapping;
- }
+ int brick = m_brickCount/m_textureSubdivCount;
+ Math::Vector oo = GetVector((x/brick)*brick, (y/brick)*brick);
+ o = GetVector(x, y);
+ v.texCoord.x = (o.x-oo.x)*m_textureScale*m_textureSubdivCount;
+ v.texCoord.y = 1.0f - (o.z-oo.z)*m_textureScale*m_textureSubdivCount;
return v;
}
@@ -545,7 +482,7 @@ bool Gfx::CTerrain::CreateMosaic(int ox, int oy, int step, int objRank,
if ( step == 1 && m_engine->GetGroundSpot() )
{
- int i = (ox/5) + (oy/5)*(m_mosaic/5);
+ int i = (ox/5) + (oy/5)*(m_mosaicCount/5);
std::stringstream s;
s << "shadow";
s.width(2);
@@ -555,9 +492,9 @@ bool Gfx::CTerrain::CreateMosaic(int ox, int oy, int step, int objRank,
texName2 = s.str();
}
- int brick = m_brick/m_subdivMapping;
+ int brick = m_brickCount/m_textureSubdivCount;
- Gfx::VertexTex2 o = GetVertex(ox*m_brick+m_brick/2, oy*m_brick+m_brick/2, step);
+ Gfx::VertexTex2 o = GetVertex(ox*m_brickCount+m_brickCount/2, oy*m_brickCount+m_brickCount/2, step);
int total = ((brick/step)+1)*2;
float pixel = 1.0f/256.0f; // 1 pixel cover (*)
@@ -565,24 +502,24 @@ bool Gfx::CTerrain::CreateMosaic(int ox, int oy, int step, int objRank,
Math::Point uv;
- for (int my = 0; my < m_subdivMapping; my++)
+ for (int my = 0; my < m_textureSubdivCount; my++)
{
- for (int mx = 0; mx < m_subdivMapping; mx++)
+ for (int mx = 0; mx < m_textureSubdivCount; mx++)
{
- if (m_levelText)
+ if (m_useMaterials)
{
- int xx = ox*m_brick + mx*(m_brick/m_subdivMapping);
- int yy = oy*m_brick + my*(m_brick/m_subdivMapping);
- LevelTextureName(xx, yy, texName1, uv);
+ int xx = ox*m_brickCount + mx*(m_brickCount/m_textureSubdivCount);
+ int yy = oy*m_brickCount + my*(m_brickCount/m_textureSubdivCount);
+ GetTexture(xx, yy, texName1, uv);
}
else
{
- int i = (ox*m_subdivMapping+mx)+(oy*m_subdivMapping+my)*m_mosaic;
+ int i = (ox*m_textureSubdivCount+mx)+(oy*m_textureSubdivCount+my)*m_mosaicCount;
std::stringstream s;
s << m_texBaseName;
s.width(3);
s.fill('0');
- s << m_texture[i];
+ s << m_textures[i];
s << m_texBaseExt;
texName1 = s.str();
}
@@ -603,36 +540,33 @@ bool Gfx::CTerrain::CreateMosaic(int ox, int oy, int step, int objRank,
for (int x = 0; x <= brick; x += step)
{
- Gfx::VertexTex2 p1 = GetVertex(ox*m_brick+mx*brick+x, oy*m_brick+my*brick+y+0 , step);
- Gfx::VertexTex2 p2 = GetVertex(ox*m_brick+mx*brick+x, oy*m_brick+my*brick+y+step, step);
+ Gfx::VertexTex2 p1 = GetVertex(ox*m_brickCount+mx*brick+x, oy*m_brickCount+my*brick+y+0 , step);
+ Gfx::VertexTex2 p2 = GetVertex(ox*m_brickCount+mx*brick+x, oy*m_brickCount+my*brick+y+step, step);
p1.coord.x -= o.coord.x; p1.coord.z -= o.coord.z;
p2.coord.x -= o.coord.x; p2.coord.z -= o.coord.z;
- if (m_multiText)
+ if (x == 0)
{
- if (x == 0)
- {
- p1.texCoord.x = 0.0f+(0.5f/256.0f);
- p2.texCoord.x = 0.0f+(0.5f/256.0f);
- }
- if (x == brick)
- {
- p1.texCoord.x = 1.0f-(0.5f/256.0f);
- p2.texCoord.x = 1.0f-(0.5f/256.0f);
- }
- if (y == 0)
- p1.texCoord.y = 1.0f-(0.5f/256.0f);
-
- if (y == brick - step)
- p2.texCoord.y = 0.0f+(0.5f/256.0f);
+ p1.texCoord.x = 0.0f+(0.5f/256.0f);
+ p2.texCoord.x = 0.0f+(0.5f/256.0f);
+ }
+ if (x == brick)
+ {
+ p1.texCoord.x = 1.0f-(0.5f/256.0f);
+ p2.texCoord.x = 1.0f-(0.5f/256.0f);
}
+ if (y == 0)
+ p1.texCoord.y = 1.0f-(0.5f/256.0f);
+
+ if (y == brick - step)
+ p2.texCoord.y = 0.0f+(0.5f/256.0f);
- if (m_levelText)
+ if (m_useMaterials)
{
- p1.texCoord.x /= m_subdivMapping; // 0..1 -> 0..0.25
- p1.texCoord.y /= m_subdivMapping;
- p2.texCoord.x /= m_subdivMapping;
- p2.texCoord.y /= m_subdivMapping;
+ p1.texCoord.x /= m_textureSubdivCount; // 0..1 -> 0..0.25
+ p1.texCoord.y /= m_textureSubdivCount;
+ p2.texCoord.x /= m_textureSubdivCount;
+ p2.texCoord.y /= m_textureSubdivCount;
if (x == 0)
{
@@ -641,11 +575,11 @@ bool Gfx::CTerrain::CreateMosaic(int ox, int oy, int step, int objRank,
}
if (x == brick)
{
- p1.texCoord.x = (1.0f/m_subdivMapping)-dp;
- p2.texCoord.x = (1.0f/m_subdivMapping)-dp;
+ p1.texCoord.x = (1.0f/m_textureSubdivCount)-dp;
+ p2.texCoord.x = (1.0f/m_textureSubdivCount)-dp;
}
if (y == 0)
- p1.texCoord.y = (1.0f/m_subdivMapping)-dp;
+ p1.texCoord.y = (1.0f/m_textureSubdivCount)-dp;
if (y == brick - step)
p2.texCoord.y = 0.0f+dp;
@@ -656,12 +590,12 @@ bool Gfx::CTerrain::CreateMosaic(int ox, int oy, int step, int objRank,
p2.texCoord.y += uv.y;
}
- int xx = mx*(m_brick/m_subdivMapping) + x;
- int yy = my*(m_brick/m_subdivMapping) + y;
- p1.texCoord2.x = (static_cast<float>(ox%5)*m_brick+xx+0.0f)/(m_brick*5);
- p1.texCoord2.y = (static_cast<float>(oy%5)*m_brick+yy+0.0f)/(m_brick*5);
- p2.texCoord2.x = (static_cast<float>(ox%5)*m_brick+xx+0.0f)/(m_brick*5);
- p2.texCoord2.y = (static_cast<float>(oy%5)*m_brick+yy+1.0f)/(m_brick*5);
+ int xx = mx*(m_brickCount/m_textureSubdivCount) + x;
+ int yy = my*(m_brickCount/m_textureSubdivCount) + y;
+ p1.texCoord2.x = (static_cast<float>(ox%5)*m_brickCount+xx+0.0f)/(m_brickCount*5);
+ p1.texCoord2.y = (static_cast<float>(oy%5)*m_brickCount+yy+0.0f)/(m_brickCount*5);
+ p2.texCoord2.x = (static_cast<float>(ox%5)*m_brickCount+xx+0.0f)/(m_brickCount*5);
+ p2.texCoord2.y = (static_cast<float>(oy%5)*m_brickCount+yy+1.0f)/(m_brickCount*5);
// Correction for 1 pixel cover
// There is 1 pixel cover around each of the 16 surfaces:
@@ -699,40 +633,38 @@ bool Gfx::CTerrain::CreateMosaic(int ox, int oy, int step, int objRank,
return true;
}
-Gfx::TerrainMaterial* Gfx::CTerrain::LevelSearchMat(int id)
+Gfx::TerrainMaterial* Gfx::CTerrain::FindMaterial(int id)
{
- for (int i = 0; i < static_cast<int>( m_levelMats.size() ); i++)
+ for (int i = 0; i < static_cast<int>( m_materials.size() ); i++)
{
- if (id == m_levelMats[i].id)
- return &m_levelMats[i];
+ if (id == m_materials[i].id)
+ return &m_materials[i];
}
return nullptr;
}
-void Gfx::CTerrain::LevelTextureName(int x, int y, std::string& name, Math::Point &uv)
+void Gfx::CTerrain::GetTexture(int x, int y, std::string& name, Math::Point &uv)
{
- x /= m_brick/m_subdivMapping;
- y /= m_brick/m_subdivMapping;
+ x /= m_brickCount/m_textureSubdivCount;
+ y /= m_brickCount/m_textureSubdivCount;
- TerrainMaterial* tm = LevelSearchMat(m_levelDots[x+y*m_levelDotSize].id);
+ TerrainMaterial* tm = FindMaterial(m_materialPoints[x+y*m_materialPointCount].id);
if (tm == nullptr)
{
name = "xxx.png";
- uv.x = 0.0f;
- uv.y = 0.0f;
+ uv = Math::Point(0.0f, 0.0f);
}
else
{
name = tm->texName;
- uv.x = tm->u;
- uv.y = tm->v;
+ uv = tm->uv;
}
}
-float Gfx::CTerrain::LevelGetHeight(int x, int y)
+float Gfx::CTerrain::GetHeight(int x, int y)
{
- int size = (m_mosaic*m_brick+1);
+ int size = (m_mosaicCount*m_brickCount+1);
if (x < 0 ) x = 0;
if (x >= size) x = size-1;
@@ -742,15 +674,15 @@ float Gfx::CTerrain::LevelGetHeight(int x, int y)
return m_relief[x+y*size];
}
-bool Gfx::CTerrain::LevelGetDot(int x, int y, float min, float max, float slope)
+bool Gfx::CTerrain::CheckMaterialPoint(int x, int y, float min, float max, float slope)
{
- float hc = LevelGetHeight(x, y);
+ float hc = GetHeight(x, y);
float h[4] =
{
- LevelGetHeight(x+0, y+1),
- LevelGetHeight(x+1, y+0),
- LevelGetHeight(x+0, y-1),
- LevelGetHeight(x-1, y+0)
+ GetHeight(x+0, y+1),
+ GetHeight(x+1, y+0),
+ GetHeight(x+0, y-1),
+ GetHeight(x-1, y+0)
};
if (hc < min || hc > max)
@@ -782,25 +714,22 @@ bool Gfx::CTerrain::LevelGetDot(int x, int y, float min, float max, float slope)
return false;
}
-
-/** Returns the index within m_levelMats or -1 if there is not.
- m_levelMats[i].id gives the identifier. */
-int Gfx::CTerrain::LevelTestMat(char *mat)
+int Gfx::CTerrain::FindMaterialByNeighbors(char *mat)
{
- for (int i = 0; i < static_cast<int>( m_levelMats.size() ); i++)
+ for (int i = 0; i < static_cast<int>( m_materials.size() ); i++)
{
- if ( m_levelMats[i].mat[0] == mat[0] &&
- m_levelMats[i].mat[1] == mat[1] &&
- m_levelMats[i].mat[2] == mat[2] &&
- m_levelMats[i].mat[3] == mat[3] ) return i;
+ if ( m_materials[i].mat[0] == mat[0] &&
+ m_materials[i].mat[1] == mat[1] &&
+ m_materials[i].mat[2] == mat[2] &&
+ m_materials[i].mat[3] == mat[3] ) return i;
}
return -1;
}
-void Gfx::CTerrain::LevelSetDot(int x, int y, int id, char *mat)
+void Gfx::CTerrain::SetMaterialPoint(int x, int y, int id, char *mat)
{
- TerrainMaterial* tm = LevelSearchMat(id);
+ TerrainMaterial* tm = FindMaterial(id);
if (tm == nullptr) return;
if ( tm->mat[0] != mat[0] ||
@@ -808,310 +737,310 @@ void Gfx::CTerrain::LevelSetDot(int x, int y, int id, char *mat)
tm->mat[2] != mat[2] ||
tm->mat[3] != mat[3] ) // id incompatible with mat?
{
- int ii = LevelTestMat(mat);
+ int ii = FindMaterialByNeighbors(mat);
if (ii == -1) return;
- id = m_levelMats[ii].id; // looking for a id compatible with mat
+ id = m_materials[ii].id; // looking for a id compatible with mat
}
// Changes the point
- m_levelDots[x+y*m_levelDotSize].id = id;
- m_levelDots[x+y*m_levelDotSize].mat[0] = mat[0];
- m_levelDots[x+y*m_levelDotSize].mat[1] = mat[1];
- m_levelDots[x+y*m_levelDotSize].mat[2] = mat[2];
- m_levelDots[x+y*m_levelDotSize].mat[3] = mat[3];
+ m_materialPoints[x+y*m_materialPointCount].id = id;
+ m_materialPoints[x+y*m_materialPointCount].mat[0] = mat[0];
+ m_materialPoints[x+y*m_materialPointCount].mat[1] = mat[1];
+ m_materialPoints[x+y*m_materialPointCount].mat[2] = mat[2];
+ m_materialPoints[x+y*m_materialPointCount].mat[3] = mat[3];
// Changes the lower neighbor
- if ( (x+0) >= 0 && (x+0) < m_levelDotSize &&
- (y-1) >= 0 && (y-1) < m_levelDotSize )
+ if ( (x+0) >= 0 && (x+0) < m_materialPointCount &&
+ (y-1) >= 0 && (y-1) < m_materialPointCount )
{
- int i = (x+0)+(y-1)*m_levelDotSize;
- if (m_levelDots[i].mat[0] != mat[2])
+ int i = (x+0)+(y-1)*m_materialPointCount;
+ if (m_materialPoints[i].mat[0] != mat[2])
{
- m_levelDots[i].mat[0] = mat[2];
- int ii = LevelTestMat(m_levelDots[i].mat);
+ m_materialPoints[i].mat[0] = mat[2];
+ int ii = FindMaterialByNeighbors(m_materialPoints[i].mat);
if (ii != -1)
- m_levelDots[i].id = m_levelMats[ii].id;
+ m_materialPoints[i].id = m_materials[ii].id;
}
}
// Modifies the left neighbor
- if ( (x-1) >= 0 && (x-1) < m_levelDotSize &&
- (y+0) >= 0 && (y+0) < m_levelDotSize )
+ if ( (x-1) >= 0 && (x-1) < m_materialPointCount &&
+ (y+0) >= 0 && (y+0) < m_materialPointCount )
{
- int i = (x-1)+(y+0)*m_levelDotSize;
- if (m_levelDots[i].mat[1] != mat[3])
+ int i = (x-1)+(y+0)*m_materialPointCount;
+ if (m_materialPoints[i].mat[1] != mat[3])
{
- m_levelDots[i].mat[1] = mat[3];
- int ii = LevelTestMat(m_levelDots[i].mat);
+ m_materialPoints[i].mat[1] = mat[3];
+ int ii = FindMaterialByNeighbors(m_materialPoints[i].mat);
if (ii != -1)
- m_levelDots[i].id = m_levelMats[ii].id;
+ m_materialPoints[i].id = m_materials[ii].id;
}
}
// Changes the upper neighbor
- if ( (x+0) >= 0 && (x+0) < m_levelDotSize &&
- (y+1) >= 0 && (y+1) < m_levelDotSize )
+ if ( (x+0) >= 0 && (x+0) < m_materialPointCount &&
+ (y+1) >= 0 && (y+1) < m_materialPointCount )
{
- int i = (x+0)+(y+1)*m_levelDotSize;
- if (m_levelDots[i].mat[2] != mat[0])
+ int i = (x+0)+(y+1)*m_materialPointCount;
+ if (m_materialPoints[i].mat[2] != mat[0])
{
- m_levelDots[i].mat[2] = mat[0];
- int ii = LevelTestMat(m_levelDots[i].mat);
+ m_materialPoints[i].mat[2] = mat[0];
+ int ii = FindMaterialByNeighbors(m_materialPoints[i].mat);
if (ii != -1)
- m_levelDots[i].id = m_levelMats[ii].id;
+ m_materialPoints[i].id = m_materials[ii].id;
}
}
// Changes the right neighbor
- if ( (x+1) >= 0 && (x+1) < m_levelDotSize &&
- (y+0) >= 0 && (y+0) < m_levelDotSize )
+ if ( (x+1) >= 0 && (x+1) < m_materialPointCount &&
+ (y+0) >= 0 && (y+0) < m_materialPointCount )
{
- int i = (x+1)+(y+0)*m_levelDotSize;
- if ( m_levelDots[i].mat[3] != mat[1] )
+ int i = (x+1)+(y+0)*m_materialPointCount;
+ if ( m_materialPoints[i].mat[3] != mat[1] )
{
- m_levelDots[i].mat[3] = mat[1];
- int ii = LevelTestMat(m_levelDots[i].mat);
+ m_materialPoints[i].mat[3] = mat[1];
+ int ii = FindMaterialByNeighbors(m_materialPoints[i].mat);
if (ii != -1)
- m_levelDots[i].id = m_levelMats[ii].id;
+ m_materialPoints[i].id = m_materials[ii].id;
}
}
}
-bool Gfx::CTerrain::LevelIfDot(int x, int y, int id, char *mat)
+bool Gfx::CTerrain::CondChangeMaterialPoint(int x, int y, int id, char *mat)
{
char test[4];
// Compatible with lower neighbor?
- if ( x+0 >= 0 && x+0 < m_levelDotSize &&
- y-1 >= 0 && y-1 < m_levelDotSize )
+ if ( x+0 >= 0 && x+0 < m_materialPointCount &&
+ y-1 >= 0 && y-1 < m_materialPointCount )
{
test[0] = mat[2];
- test[1] = m_levelDots[(x+0)+(y-1)*m_levelDotSize].mat[1];
- test[2] = m_levelDots[(x+0)+(y-1)*m_levelDotSize].mat[2];
- test[3] = m_levelDots[(x+0)+(y-1)*m_levelDotSize].mat[3];
+ test[1] = m_materialPoints[(x+0)+(y-1)*m_materialPointCount].mat[1];
+ test[2] = m_materialPoints[(x+0)+(y-1)*m_materialPointCount].mat[2];
+ test[3] = m_materialPoints[(x+0)+(y-1)*m_materialPointCount].mat[3];
- if ( LevelTestMat(test) == -1 ) return false;
+ if ( FindMaterialByNeighbors(test) == -1 ) return false;
}
// Compatible with left neighbor?
- if ( x-1 >= 0 && x-1 < m_levelDotSize &&
- y+0 >= 0 && y+0 < m_levelDotSize )
+ if ( x-1 >= 0 && x-1 < m_materialPointCount &&
+ y+0 >= 0 && y+0 < m_materialPointCount )
{
- test[0] = m_levelDots[(x-1)+(y+0)*m_levelDotSize].mat[0];
+ test[0] = m_materialPoints[(x-1)+(y+0)*m_materialPointCount].mat[0];
test[1] = mat[3];
- test[2] = m_levelDots[(x-1)+(y+0)*m_levelDotSize].mat[2];
- test[3] = m_levelDots[(x-1)+(y+0)*m_levelDotSize].mat[3];
+ test[2] = m_materialPoints[(x-1)+(y+0)*m_materialPointCount].mat[2];
+ test[3] = m_materialPoints[(x-1)+(y+0)*m_materialPointCount].mat[3];
- if ( LevelTestMat(test) == -1 ) return false;
+ if ( FindMaterialByNeighbors(test) == -1 ) return false;
}
// Compatible with upper neighbor?
- if ( x+0 >= 0 && x+0 < m_levelDotSize &&
- y+1 >= 0 && y+1 < m_levelDotSize )
+ if ( x+0 >= 0 && x+0 < m_materialPointCount &&
+ y+1 >= 0 && y+1 < m_materialPointCount )
{
- test[0] = m_levelDots[(x+0)+(y+1)*m_levelDotSize].mat[0];
- test[1] = m_levelDots[(x+0)+(y+1)*m_levelDotSize].mat[1];
+ test[0] = m_materialPoints[(x+0)+(y+1)*m_materialPointCount].mat[0];
+ test[1] = m_materialPoints[(x+0)+(y+1)*m_materialPointCount].mat[1];
test[2] = mat[0];
- test[3] = m_levelDots[(x+0)+(y+1)*m_levelDotSize].mat[3];
+ test[3] = m_materialPoints[(x+0)+(y+1)*m_materialPointCount].mat[3];
- if ( LevelTestMat(test) == -1 ) return false;
+ if ( FindMaterialByNeighbors(test) == -1 ) return false;
}
// Compatible with right neighbor?
- if ( x+1 >= 0 && x+1 < m_levelDotSize &&
- y+0 >= 0 && y+0 < m_levelDotSize )
+ if ( x+1 >= 0 && x+1 < m_materialPointCount &&
+ y+0 >= 0 && y+0 < m_materialPointCount )
{
- test[0] = m_levelDots[(x+1)+(y+0)*m_levelDotSize].mat[0];
- test[1] = m_levelDots[(x+1)+(y+0)*m_levelDotSize].mat[1];
- test[2] = m_levelDots[(x+1)+(y+0)*m_levelDotSize].mat[2];
+ test[0] = m_materialPoints[(x+1)+(y+0)*m_materialPointCount].mat[0];
+ test[1] = m_materialPoints[(x+1)+(y+0)*m_materialPointCount].mat[1];
+ test[2] = m_materialPoints[(x+1)+(y+0)*m_materialPointCount].mat[2];
test[3] = mat[1];
- if ( LevelTestMat(test) == -1 ) return false;
+ if ( FindMaterialByNeighbors(test) == -1 ) return false;
}
- LevelSetDot(x, y, id, mat); // puts the point
+ SetMaterialPoint(x, y, id, mat); // puts the point
return true;
}
-bool Gfx::CTerrain::LevelPutDot(int x, int y, int id)
+bool Gfx::CTerrain::ChangeMaterialPoint(int x, int y, int id)
{
char mat[4];
- x /= m_brick/m_subdivMapping;
- y /= m_brick/m_subdivMapping;
+ x /= m_brickCount/m_textureSubdivCount;
+ y /= m_brickCount/m_textureSubdivCount;
- if ( x < 0 || x >= m_levelDotSize ||
- y < 0 || y >= m_levelDotSize ) return false;
+ if ( x < 0 || x >= m_materialPointCount ||
+ y < 0 || y >= m_materialPointCount ) return false;
- TerrainMaterial* tm = LevelSearchMat(id);
+ TerrainMaterial* tm = FindMaterial(id);
if (tm == nullptr) return false;
// Tries without changing neighbors.
- if ( LevelIfDot(x, y, id, tm->mat) ) return true;
+ if ( CondChangeMaterialPoint(x, y, id, tm->mat) ) return true;
// Tries changing a single neighbor (4x).
- for (int up = 0; up < m_levelMatMax; up++)
+ for (int up = 0; up < m_maxMaterialID; up++)
{
mat[0] = up;
mat[1] = tm->mat[1];
mat[2] = tm->mat[2];
mat[3] = tm->mat[3];
- if (LevelIfDot(x, y, id, mat)) return true;
+ if (CondChangeMaterialPoint(x, y, id, mat)) return true;
}
- for (int right = 0; right < m_levelMatMax; right++)
+ for (int right = 0; right < m_maxMaterialID; right++)
{
mat[0] = tm->mat[0];
mat[1] = right;
mat[2] = tm->mat[2];
mat[3] = tm->mat[3];
- if (LevelIfDot(x, y, id, mat)) return true;
+ if (CondChangeMaterialPoint(x, y, id, mat)) return true;
}
- for (int down = 0; down < m_levelMatMax; down++)
+ for (int down = 0; down < m_maxMaterialID; down++)
{
mat[0] = tm->mat[0];
mat[1] = tm->mat[1];
mat[2] = down;
mat[3] = tm->mat[3];
- if (LevelIfDot(x, y, id, mat)) return true;
+ if (CondChangeMaterialPoint(x, y, id, mat)) return true;
}
- for (int left = 0; left < m_levelMatMax; left++)
+ for (int left = 0; left < m_maxMaterialID; left++)
{
mat[0] = tm->mat[0];
mat[1] = tm->mat[1];
mat[2] = tm->mat[2];
mat[3] = left;
- if (LevelIfDot(x, y, id, mat)) return true;
+ if (CondChangeMaterialPoint(x, y, id, mat)) return true;
}
// Tries changing two neighbors (6x).
- for (int up = 0; up < m_levelMatMax; up++)
+ for (int up = 0; up < m_maxMaterialID; up++)
{
- for (int down = 0; down < m_levelMatMax; down++)
+ for (int down = 0; down < m_maxMaterialID; down++)
{
mat[0] = up;
mat[1] = tm->mat[1];
mat[2] = down;
mat[3] = tm->mat[3];
- if (LevelIfDot(x, y, id, mat)) return true;
+ if (CondChangeMaterialPoint(x, y, id, mat)) return true;
}
}
- for (int right = 0; right < m_levelMatMax; right++)
+ for (int right = 0; right < m_maxMaterialID; right++)
{
- for (int left = 0; left < m_levelMatMax; left++)
+ for (int left = 0; left < m_maxMaterialID; left++)
{
mat[0] = tm->mat[0];
mat[1] = right;
mat[2] = tm->mat[2];
mat[3] = left;
- if (LevelIfDot(x, y, id, mat)) return true;
+ if (CondChangeMaterialPoint(x, y, id, mat)) return true;
}
}
- for (int up = 0; up < m_levelMatMax; up++)
+ for (int up = 0; up < m_maxMaterialID; up++)
{
- for (int right = 0; right < m_levelMatMax; right++)
+ for (int right = 0; right < m_maxMaterialID; right++)
{
mat[0] = up;
mat[1] = right;
mat[2] = tm->mat[2];
mat[3] = tm->mat[3];
- if (LevelIfDot(x, y, id, mat)) return true;
+ if (CondChangeMaterialPoint(x, y, id, mat)) return true;
}
}
- for (int right = 0; right < m_levelMatMax; right++)
+ for (int right = 0; right < m_maxMaterialID; right++)
{
- for (int down = 0; down < m_levelMatMax; down++)
+ for (int down = 0; down < m_maxMaterialID; down++)
{
mat[0] = tm->mat[0];
mat[1] = right;
mat[2] = down;
mat[3] = tm->mat[3];
- if (LevelIfDot(x, y, id, mat)) return true;
+ if (CondChangeMaterialPoint(x, y, id, mat)) return true;
}
}
- for (int down = 0; down < m_levelMatMax; down++)
+ for (int down = 0; down < m_maxMaterialID; down++)
{
- for (int left = 0; left < m_levelMatMax; left++)
+ for (int left = 0; left < m_maxMaterialID; left++)
{
mat[0] = tm->mat[0];
mat[1] = tm->mat[1];
mat[2] = down;
mat[3] = left;
- if (LevelIfDot(x, y, id, mat)) return true;
+ if (CondChangeMaterialPoint(x, y, id, mat)) return true;
}
}
- for (int up = 0; up < m_levelMatMax; up++)
+ for (int up = 0; up < m_maxMaterialID; up++)
{
- for (int left = 0; left < m_levelMatMax; left++)
+ for (int left = 0; left < m_maxMaterialID; left++)
{
mat[0] = up;
mat[1] = tm->mat[1];
mat[2] = tm->mat[2];
mat[3] = left;
- if (LevelIfDot(x, y, id, mat)) return true;
+ if (CondChangeMaterialPoint(x, y, id, mat)) return true;
}
}
// Tries changing all the neighbors.
- for (int up = 0; up < m_levelMatMax; up++)
+ for (int up = 0; up < m_maxMaterialID; up++)
{
- for (int right = 0; right < m_levelMatMax; right++)
+ for (int right = 0; right < m_maxMaterialID; right++)
{
- for (int down = 0; down < m_levelMatMax; down++)
+ for (int down = 0; down < m_maxMaterialID; down++)
{
- for (int left = 0; left < m_levelMatMax; left++)
+ for (int left = 0; left < m_maxMaterialID; left++)
{
mat[0] = up;
mat[1] = right;
mat[2] = down;
mat[3] = left;
- if (LevelIfDot(x, y, id, mat)) return true;
+ if (CondChangeMaterialPoint(x, y, id, mat)) return true;
}
}
}
}
- GetLogger()->Error("LevelPutDot error\n");
+ GetLogger()->Error("AddMaterialPoint error\n");
return false;
}
-bool Gfx::CTerrain::LevelInit(int id)
+bool Gfx::CTerrain::InitMaterials(int id)
{
- TerrainMaterial* tm = LevelSearchMat(id);
+ TerrainMaterial* tm = FindMaterial(id);
if (tm == nullptr) return false;
- for (int i = 0; i < m_levelDotSize*m_levelDotSize; i++)
+ for (int i = 0; i < m_materialPointCount*m_materialPointCount; i++)
{
- m_levelDots[i].id = id;
+ m_materialPoints[i].id = id;
for (int j = 0; j < 4; j++)
- m_levelDots[i].mat[j] = tm->mat[j];
+ m_materialPoints[i].mat[j] = tm->mat[j];
}
return true;
}
-bool Gfx::CTerrain::LevelGenerate(int *id, float min, float max,
- float slope, float freq,
- Math::Vector center, float radius)
+bool Gfx::CTerrain::GenerateMaterials(int *id, float min, float max,
+ float slope, float freq,
+ Math::Vector center, float radius)
{
static char random[100] =
{
@@ -1130,40 +1059,40 @@ bool Gfx::CTerrain::LevelGenerate(int *id, float min, float max,
TerrainMaterial* tm = nullptr;
int i = 0;
- while ( id[i] != 0 )
+ while (id[i] != 0)
{
- tm = LevelSearchMat(id[i++]);
- if (tm == nullptr) return false;
+ tm = FindMaterial(id[i++]);
+ if (tm == nullptr) return false;
}
int numID = i;
- int group = m_brick / m_subdivMapping;
+ int group = m_brickCount / m_textureSubdivCount;
if (radius > 0.0f && radius < 5.0f) // just a square?
{
- float dim = (m_mosaic*m_brick*m_size)/2.0f;
+ float dim = (m_mosaicCount*m_brickCount*m_brickSize)/2.0f;
- int xx = static_cast<int>((center.x+dim)/m_size);
- int yy = static_cast<int>((center.z+dim)/m_size);
+ int xx = static_cast<int>((center.x+dim)/m_brickSize);
+ int yy = static_cast<int>((center.z+dim)/m_brickSize);
int x = xx/group;
int y = yy/group;
- tm = LevelSearchMat(id[0]);
+ tm = FindMaterial(id[0]);
if (tm != nullptr)
- LevelSetDot(x, y, id[0], tm->mat); // puts the point
+ SetMaterialPoint(x, y, id[0], tm->mat); // puts the point
}
else
{
- for (int y = 0; y < m_levelDotSize; y++)
+ for (int y = 0; y < m_materialPointCount; y++)
{
- for (int x = 0; x < m_levelDotSize; x++)
+ for (int x = 0; x < m_materialPointCount; x++)
{
if (radius != 0.0f)
{
Math::Vector pos;
- pos.x = (static_cast<float>(x)-m_levelDotSize/2.0f)*group*m_size;
- pos.z = (static_cast<float>(y)-m_levelDotSize/2.0f)*group*m_size;
+ pos.x = (static_cast<float>(x)-m_materialPointCount/2.0f)*group*m_brickSize;
+ pos.z = (static_cast<float>(y)-m_materialPointCount/2.0f)*group*m_brickSize;
if (Math::DistanceProjected(pos, center) > radius) continue;
}
@@ -1176,11 +1105,11 @@ bool Gfx::CTerrain::LevelGenerate(int *id, float min, float max,
int xx = x*group + group/2;
int yy = y*group + group/2;
- if (LevelGetDot(xx, yy, min, max, slope))
+ if (CheckMaterialPoint(xx, yy, min, max, slope))
{
int rnd = random[(x%10)+(y%10)*10];
int ii = rnd % numID;
- LevelPutDot(xx, yy, id[ii]);
+ ChangeMaterialPoint(xx, yy, id[ii]);
}
}
}
@@ -1189,66 +1118,59 @@ bool Gfx::CTerrain::LevelGenerate(int *id, float min, float max,
return true;
}
-void Gfx::CTerrain::LevelOpenTable()
+void Gfx::CTerrain::InitMaterialPoints()
{
- if (! m_levelText) return;
- if (! m_levelDots.empty()) return; // already allocated
+ if (! m_useMaterials) return;
+ if (! m_materialPoints.empty()) return; // already allocated
- m_levelDotSize = (m_mosaic*m_brick)/(m_brick/m_subdivMapping)+1;
- std::vector<Gfx::DotLevel>(m_levelDotSize*m_levelDotSize).swap(m_levelDots);
+ m_materialPointCount = (m_mosaicCount*m_brickCount)/(m_brickCount/m_textureSubdivCount)+1;
+ std::vector<Gfx::TerrainMaterialPoint>(m_materialPointCount*m_materialPointCount).swap(m_materialPoints);
- for (int i = 0; i < m_levelDotSize * m_levelDotSize; i++)
+ for (int i = 0; i < m_materialPointCount * m_materialPointCount; i++)
{
for (int j = 0; j < 4; j++)
- m_levelDots[i].mat[j] = 0;
+ m_materialPoints[i].mat[j] = 0;
}
}
-void Gfx::CTerrain::LevelCloseTable()
+void Gfx::CTerrain::FlushMaterialPoints()
{
- m_levelDots.clear();
+ m_materialPoints.clear();
}
-bool Gfx::CTerrain::CreateSquare(bool multiRes, int x, int y)
+bool Gfx::CTerrain::CreateSquare(int x, int y)
{
Gfx::Material mat;
mat.diffuse = Gfx::Color(1.0f, 1.0f, 1.0f);
mat.ambient = Gfx::Color(0.0f, 0.0f, 0.0f);
int objRank = m_engine->CreateObject();
- m_engine->SetObjectType(objRank, Gfx::ENG_OBJTYPE_TERRAIN); // it is a terrain
+ m_engine->SetObjectType(objRank, Gfx::ENG_OBJTYPE_TERRAIN);
- m_objRank[x+y*m_mosaic] = objRank;
+ m_objRanks[x+y*m_mosaicCount] = objRank;
- if (multiRes)
- {
- float min = 0.0f;
- float max = m_vision;
- max *= m_engine->GetClippingDistance();
- for (int step = 0; step < m_depth; step++)
- {
- CreateMosaic(x, y, 1 << step, objRank, mat, min, max);
- min = max;
- max *= 2;
- if (step == m_depth-1) max = Math::HUGE_NUM;
- }
- }
- else
+ float min = 0.0f;
+ float max = m_vision;
+ max *= m_engine->GetClippingDistance();
+ for (int step = 0; step < m_depth; step++)
{
- CreateMosaic(x, y, 1, objRank, mat, 0.0f, Math::HUGE_NUM);
+ CreateMosaic(x, y, 1 << step, objRank, mat, min, max);
+ min = max;
+ max *= 2;
+ if (step == m_depth-1) max = Math::HUGE_NUM;
}
return true;
}
-bool Gfx::CTerrain::CreateObjects(bool multiRes)
+bool Gfx::CTerrain::CreateObjects()
{
AdjustRelief();
- for (int y = 0; y < m_mosaic; y++)
+ for (int y = 0; y < m_mosaicCount; y++)
{
- for (int x = 0; x < m_mosaic; x++)
- CreateSquare(multiRes, x, y);
+ for (int x = 0; x < m_mosaicCount; x++)
+ CreateSquare(x, y);
}
return true;
@@ -1257,29 +1179,29 @@ bool Gfx::CTerrain::CreateObjects(bool multiRes)
/** ATTENTION: ok only with m_depth = 2! */
bool Gfx::CTerrain::Terraform(const Math::Vector &p1, const Math::Vector &p2, float height)
{
- float dim = (m_mosaic*m_brick*m_size)/2.0f;
+ float dim = (m_mosaicCount*m_brickCount*m_brickSize)/2.0f;
Math::IntPoint tp1, tp2;
- tp1.x = static_cast<int>((p1.x+dim+m_size/2.0f)/m_size);
- tp1.y = static_cast<int>((p1.z+dim+m_size/2.0f)/m_size);
- tp2.x = static_cast<int>((p2.x+dim+m_size/2.0f)/m_size);
- tp2.y = static_cast<int>((p2.z+dim+m_size/2.0f)/m_size);
+ tp1.x = static_cast<int>((p1.x+dim+m_brickSize/2.0f)/m_brickSize);
+ tp1.y = static_cast<int>((p1.z+dim+m_brickSize/2.0f)/m_brickSize);
+ tp2.x = static_cast<int>((p2.x+dim+m_brickSize/2.0f)/m_brickSize);
+ tp2.y = static_cast<int>((p2.z+dim+m_brickSize/2.0f)/m_brickSize);
if (tp1.x > tp2.x)
{
- int x = tp1.x;
+ int x = tp1.x;
tp1.x = tp2.x;
tp2.x = x;
}
if (tp1.y > tp2.y)
{
- int y = tp1.y;
+ int y = tp1.y;
tp1.y = tp2.y;
tp2.y = y;
}
- int size = (m_mosaic*m_brick)+1;
+ int size = (m_mosaicCount*m_brickCount)+1;
// Calculates the current average height
float avg = 0.0f;
@@ -1301,13 +1223,13 @@ bool Gfx::CTerrain::Terraform(const Math::Vector &p1, const Math::Vector &p2, fl
{
m_relief[x+y*size] = avg+height;
- if (x % m_brick == 0 && y % m_depth != 0)
+ if (x % m_brickCount == 0 && y % m_depth != 0)
{
m_relief[(x+0)+(y-1)*size] = avg+height;
m_relief[(x+0)+(y+1)*size] = avg+height;
}
- if (y % m_brick == 0 && x % m_depth != 0)
+ if (y % m_brickCount == 0 && x % m_depth != 0)
{
m_relief[(x-1)+(y+0)*size] = avg+height;
m_relief[(x+1)+(y+0)*size] = avg+height;
@@ -1317,22 +1239,22 @@ bool Gfx::CTerrain::Terraform(const Math::Vector &p1, const Math::Vector &p2, fl
AdjustRelief();
Math::IntPoint pp1, pp2;
- pp1.x = (tp1.x-2)/m_brick;
- pp1.y = (tp1.y-2)/m_brick;
- pp2.x = (tp2.x+1)/m_brick;
- pp2.y = (tp2.y+1)/m_brick;
+ pp1.x = (tp1.x-2)/m_brickCount;
+ pp1.y = (tp1.y-2)/m_brickCount;
+ pp2.x = (tp2.x+1)/m_brickCount;
+ pp2.y = (tp2.y+1)/m_brickCount;
- if (pp1.x < 0 ) pp1.x = 0;
- if (pp1.x >= m_mosaic) pp1.x = m_mosaic-1;
- if (pp1.y < 0 ) pp1.y = 0;
- if (pp1.y >= m_mosaic) pp1.y = m_mosaic-1;
+ if (pp1.x < 0 ) pp1.x = 0;
+ if (pp1.x >= m_mosaicCount) pp1.x = m_mosaicCount-1;
+ if (pp1.y < 0 ) pp1.y = 0;
+ if (pp1.y >= m_mosaicCount) pp1.y = m_mosaicCount-1;
for (int y = pp1.y; y <= pp2.y; y++)
{
for (int x = pp1.x; x <= pp2.x; x++)
{
- m_engine->DeleteObject(m_objRank[x+y*m_mosaic]);
- CreateSquare(m_multiText, x, y); // recreates the square
+ m_engine->DeleteObject(m_objRanks[x+y*m_mosaicCount]);
+ CreateSquare(x, y); // recreates the square
}
}
m_engine->Update();
@@ -1361,37 +1283,37 @@ float Gfx::CTerrain::GetCoarseSlope(const Math::Vector &pos)
{
if (m_relief.empty()) return 0.0f;
- float dim = (m_mosaic*m_brick*m_size)/2.0f;
+ float dim = (m_mosaicCount*m_brickCount*m_brickSize)/2.0f;
- int x = static_cast<int>((pos.x+dim)/m_size);
- int y = static_cast<int>((pos.z+dim)/m_size);
+ int x = static_cast<int>((pos.x+dim)/m_brickSize);
+ int y = static_cast<int>((pos.z+dim)/m_brickSize);
- if ( x < 0 || x >= m_mosaic*m_brick ||
- y < 0 || y >= m_mosaic*m_brick ) return 0.0f;
+ if ( x < 0 || x >= m_mosaicCount*m_brickCount ||
+ y < 0 || y >= m_mosaicCount*m_brickCount ) return 0.0f;
float level[4] =
{
- m_relief[(x+0)+(y+0)*(m_mosaic*m_brick+1)],
- m_relief[(x+1)+(y+0)*(m_mosaic*m_brick+1)],
- m_relief[(x+0)+(y+1)*(m_mosaic*m_brick+1)],
- m_relief[(x+1)+(y+1)*(m_mosaic*m_brick+1)],
+ m_relief[(x+0)+(y+0)*(m_mosaicCount*m_brickCount+1)],
+ m_relief[(x+1)+(y+0)*(m_mosaicCount*m_brickCount+1)],
+ m_relief[(x+0)+(y+1)*(m_mosaicCount*m_brickCount+1)],
+ m_relief[(x+1)+(y+1)*(m_mosaicCount*m_brickCount+1)],
};
float min = Math::Min(level[0], level[1], level[2], level[3]);
float max = Math::Max(level[0], level[1], level[2], level[3]);
- return atanf((max-min)/m_size);
+ return atanf((max-min)/m_brickSize);
}
bool Gfx::CTerrain::GetNormal(Math::Vector &n, const Math::Vector &p)
{
- float dim = (m_mosaic*m_brick*m_size)/2.0f;
+ float dim = (m_mosaicCount*m_brickCount*m_brickSize)/2.0f;
- int x = static_cast<int>((p.x+dim)/m_size);
- int y = static_cast<int>((p.z+dim)/m_size);
+ int x = static_cast<int>((p.x+dim)/m_brickSize);
+ int y = static_cast<int>((p.z+dim)/m_brickSize);
- if ( x < 0 || x > m_mosaic*m_brick ||
- y < 0 || y > m_mosaic*m_brick ) return false;
+ if ( x < 0 || x > m_mosaicCount*m_brickCount ||
+ y < 0 || y > m_mosaicCount*m_brickCount ) return false;
Math::Vector p1 = GetVector(x+0, y+0);
Math::Vector p2 = GetVector(x+1, y+0);
@@ -1406,23 +1328,23 @@ bool Gfx::CTerrain::GetNormal(Math::Vector &n, const Math::Vector &p)
return true;
}
-float Gfx::CTerrain::GetFloorLevel(const Math::Vector &p, bool brut, bool water)
+float Gfx::CTerrain::GetFloorLevel(const Math::Vector &pos, bool brut, bool water)
{
- float dim = (m_mosaic*m_brick*m_size)/2.0f;
+ float dim = (m_mosaicCount*m_brickCount*m_brickSize)/2.0f;
- int x = static_cast<int>((p.x+dim)/m_size);
- int y = static_cast<int>((p.z+dim)/m_size);
+ int x = static_cast<int>((pos.x+dim)/m_brickSize);
+ int y = static_cast<int>((pos.z+dim)/m_brickSize);
- if ( x < 0 || x > m_mosaic*m_brick ||
- y < 0 || y > m_mosaic*m_brick ) return false;
+ if ( x < 0 || x > m_mosaicCount*m_brickCount ||
+ y < 0 || y > m_mosaicCount*m_brickCount ) return false;
Math::Vector p1 = GetVector(x+0, y+0);
Math::Vector p2 = GetVector(x+1, y+0);
Math::Vector p3 = GetVector(x+0, y+1);
Math::Vector p4 = GetVector(x+1, y+1);
- Math::Vector ps = p;
- if ( fabs(p.z-p2.z) < fabs(p.x-p2.x) )
+ Math::Vector ps = pos;
+ if ( fabs(pos.z-p2.z) < fabs(pos.x-p2.x) )
{
if ( !IntersectY(p1, p2, p3, ps) ) return 0.0f;
}
@@ -1442,25 +1364,23 @@ float Gfx::CTerrain::GetFloorLevel(const Math::Vector &p, bool brut, bool water)
return ps.y;
}
-
-/** This height is positive when you are above the ground */
-float Gfx::CTerrain::GetFloorHeight(const Math::Vector &p, bool brut, bool water)
+float Gfx::CTerrain::GetHeightToFloor(const Math::Vector &pos, bool brut, bool water)
{
- float dim = (m_mosaic*m_brick*m_size)/2.0f;
+ float dim = (m_mosaicCount*m_brickCount*m_brickSize)/2.0f;
- int x = static_cast<int>((p.x+dim)/m_size);
- int y = static_cast<int>((p.z+dim)/m_size);
+ int x = static_cast<int>((pos.x+dim)/m_brickSize);
+ int y = static_cast<int>((pos.z+dim)/m_brickSize);
- if ( x < 0 || x > m_mosaic*m_brick ||
- y < 0 || y > m_mosaic*m_brick ) return false;
+ if ( x < 0 || x > m_mosaicCount*m_brickCount ||
+ y < 0 || y > m_mosaicCount*m_brickCount ) return false;
Math::Vector p1 = GetVector(x+0, y+0);
Math::Vector p2 = GetVector(x+1, y+0);
Math::Vector p3 = GetVector(x+0, y+1);
Math::Vector p4 = GetVector(x+1, y+1);
- Math::Vector ps = p;
- if ( fabs(p.z-p2.z) < fabs(p.x-p2.x) )
+ Math::Vector ps = pos;
+ if ( fabs(pos.z-p2.z) < fabs(pos.x-p2.x) )
{
if ( !IntersectY(p1, p2, p3, ps) ) return 0.0f;
}
@@ -1474,76 +1394,114 @@ float Gfx::CTerrain::GetFloorHeight(const Math::Vector &p, bool brut, bool water
if (water) // not going underwater?
{
float level = m_water->GetLevel();
- if ( ps.y < level ) ps.y = level; // not under water
+ if (ps.y < level ) ps.y = level; // not under water
}
- return p.y-ps.y;
+ return pos.y-ps.y;
}
-bool Gfx::CTerrain::MoveOnFloor(Math::Vector &p, bool brut, bool water)
+bool Gfx::CTerrain::AdjustToFloor(Math::Vector &pos, bool brut, bool water)
{
- float dim = (m_mosaic*m_brick*m_size)/2.0f;
+ float dim = (m_mosaicCount*m_brickCount*m_brickSize)/2.0f;
- int x = static_cast<int>((p.x + dim) / m_size);
- int y = static_cast<int>((p.z + dim) / m_size);
+ int x = static_cast<int>((pos.x + dim) / m_brickSize);
+ int y = static_cast<int>((pos.z + dim) / m_brickSize);
- if ( x < 0 || x > m_mosaic*m_brick ||
- y < 0 || y > m_mosaic*m_brick ) return false;
+ if ( x < 0 || x > m_mosaicCount*m_brickCount ||
+ y < 0 || y > m_mosaicCount*m_brickCount ) return false;
Math::Vector p1 = GetVector(x+0, y+0);
Math::Vector p2 = GetVector(x+1, y+0);
Math::Vector p3 = GetVector(x+0, y+1);
Math::Vector p4 = GetVector(x+1, y+1);
- if (fabs(p.z - p2.z) < fabs(p.x - p2.x))
+ if (fabs(pos.z - p2.z) < fabs(pos.x - p2.x))
{
- if (! Math::IntersectY(p1, p2, p3, p)) return false;
+ if (! Math::IntersectY(p1, p2, p3, pos)) return false;
}
else
{
- if (! Math::IntersectY(p2, p4, p3, p)) return false;
+ if (! Math::IntersectY(p2, p4, p3, pos)) return false;
}
- if (! brut) AdjustBuildingLevel(p);
+ if (! brut) AdjustBuildingLevel(pos);
if (water) // not going underwater?
{
float level = m_water->GetLevel();
- if (p.y < level) p.y = level; // not under water
+ if (pos.y < level) pos.y = level; // not under water
}
return true;
}
-
-/** Returns false if the initial coordinate was too far */
-bool Gfx::CTerrain::ValidPosition(Math::Vector &p, float marging)
+/**
+ * @returns \c false if the initial coordinate was outside terrain area; \c true otherwise
+ */
+bool Gfx::CTerrain::AdjustToStandardBounds(Math::Vector& pos)
{
bool ok = true;
- float limit = m_mosaic*m_brick*m_size/2.0f - marging;
+ // TODO: _TEEN ... * 0.98f;
+ float limit = (m_mosaicCount*m_brickCount*m_brickSize)/2.0f*0.92f;
- if (p.x < -limit)
+ if (pos.x < -limit)
{
- p.x = -limit;
+ pos.x = -limit;
ok = false;
}
- if (p.z < -limit)
+ if (pos.z < -limit)
{
- p.z = -limit;
+ pos.z = -limit;
ok = false;
}
- if (p.x > limit)
+ if (pos.x > limit)
{
- p.x = limit;
+ pos.x = limit;
ok = false;
}
- if (p.z > limit)
+ if (pos.z > limit)
{
- p.z = limit;
+ pos.z = limit;
+ ok = false;
+ }
+
+ return ok;
+}
+
+/**
+ * @param margin margin to the terrain border
+ * @returns \c false if the initial coordinate was outside terrain area; \c true otherwise
+ */
+bool Gfx::CTerrain::AdjustToBounds(Math::Vector& pos, float margin)
+{
+ bool ok = true;
+ float limit = m_mosaicCount*m_brickCount*m_brickSize/2.0f - margin;
+
+ if (pos.x < -limit)
+ {
+ pos.x = -limit;
+ ok = false;
+ }
+
+ if (pos.z < -limit)
+ {
+ pos.z = -limit;
+ ok = false;
+ }
+
+ if (pos.x > limit)
+ {
+ pos.x = limit;
+ ok = false;
+ }
+
+ if (pos.z > limit)
+ {
+ pos.z = limit;
ok = false;
}
@@ -1670,46 +1628,41 @@ void Gfx::CTerrain::AdjustBuildingLevel(Math::Vector &p)
}
}
-
-// returns the hardness of the ground in a given place.
-// The hardness determines the noise (SOUND_STEP and SOUND_BOUM).
-
float Gfx::CTerrain::GetHardness(const Math::Vector &p)
{
float factor = GetBuildingFactor(p);
- if (factor != 1.0f) return 1.0f; // on building
+ if (factor != 1.0f) return 1.0f; // on building level
- if (m_levelDots.empty()) return m_defHardness;
+ if (m_materialPoints.empty()) return m_defaultHardness;
- float dim = (m_mosaic*m_brick*m_size)/2.0f;
+ float dim = (m_mosaicCount*m_brickCount*m_brickSize)/2.0f;
int x, y;
- x = static_cast<int>((p.x+dim)/m_size);
- y = static_cast<int>((p.z+dim)/m_size);
+ x = static_cast<int>((p.x+dim)/m_brickSize);
+ y = static_cast<int>((p.z+dim)/m_brickSize);
- if ( x < 0 || x > m_mosaic*m_brick ||
- y < 0 || y > m_mosaic*m_brick ) return m_defHardness;
+ if ( x < 0 || x > m_mosaicCount*m_brickCount ||
+ y < 0 || y > m_mosaicCount*m_brickCount ) return m_defaultHardness;
- x /= m_brick/m_subdivMapping;
- y /= m_brick/m_subdivMapping;
+ x /= m_brickCount/m_textureSubdivCount;
+ y /= m_brickCount/m_textureSubdivCount;
- if ( x < 0 || x >= m_levelDotSize ||
- y < 0 || y >= m_levelDotSize ) return m_defHardness;
+ if ( x < 0 || x >= m_materialPointCount ||
+ y < 0 || y >= m_materialPointCount ) return m_defaultHardness;
- int id = m_levelDots[x+y*m_levelDotSize].id;
- TerrainMaterial* tm = LevelSearchMat(id);
- if (tm == nullptr) return m_defHardness;
+ int id = m_materialPoints[x+y*m_materialPointCount].id;
+ TerrainMaterial* tm = FindMaterial(id);
+ if (tm == nullptr) return m_defaultHardness;
return tm->hardness;
}
-void Gfx::CTerrain::GroundFlat(Math::Vector pos)
+void Gfx::CTerrain::ShowFlatGround(Math::Vector pos)
{
- static char table[41*41];
-
+ static char table[41*41] = { 1 };
- float rapport = 3200.0f/1024.0f;
+ float radius = 3200.0f/1024.0f;
for (int y = 0; y <= 40; y++)
{
@@ -1719,16 +1672,16 @@ void Gfx::CTerrain::GroundFlat(Math::Vector pos)
table[i] = 0;
Math::Vector p;
- p.x = (x-20)*rapport;
- p.z = (y-20)*rapport;
+ p.x = (x-20)*radius;
+ p.z = (y-20)*radius;
p.y = 0.0f;
- if (Math::Point(p.x, p.y).Length() > 20.0f*rapport)
+ if (Math::Point(p.x, p.y).Length() > 20.0f*radius)
continue;
float angle = GetFineSlope(pos+p);
- if (angle < FLATLIMIT)
+ if (angle < Gfx::TERRAIN_FLATLIMIT)
table[i] = 1;
else
table[i] = 2;
@@ -1741,7 +1694,7 @@ void Gfx::CTerrain::GroundFlat(Math::Vector pos)
float Gfx::CTerrain::GetFlatZoneRadius(Math::Vector center, float max)
{
float angle = GetFineSlope(center);
- if (angle >= Gfx::FLATLIMIT)
+ if (angle >= Gfx::TERRAIN_FLATLIMIT)
return 0.0f;
float ref = GetFloorLevel(center, true);