summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/graphics/core/color.h2
-rw-r--r--src/graphics/core/vertex.h22
-rw-r--r--src/graphics/engine/camera.cpp28
-rw-r--r--src/graphics/engine/cloud.cpp29
-rw-r--r--src/graphics/engine/cloud.h4
-rw-r--r--src/graphics/engine/engine.cpp12
-rw-r--r--src/graphics/engine/terrain.cpp957
-rw-r--r--src/graphics/engine/terrain.h286
-rw-r--r--src/graphics/engine/water.cpp32
-rw-r--r--src/graphics/engine/water.h6
10 files changed, 715 insertions, 663 deletions
diff --git a/src/graphics/core/color.h b/src/graphics/core/color.h
index ff8a2eb..bcd0af1 100644
--- a/src/graphics/core/color.h
+++ b/src/graphics/core/color.h
@@ -35,7 +35,7 @@ struct Color
float r, g, b, a;
//! Constructor; default values are (0,0,0,0) = black
- Color(float aR = 0.0f, float aG = 0.0f, float aB = 0.0f, float aA = 0.0f)
+ explicit Color(float aR = 0.0f, float aG = 0.0f, float aB = 0.0f, float aA = 0.0f)
: r(aR), g(aG), b(aB), a(aA) {}
inline Gfx::Color Inverse() const
diff --git a/src/graphics/core/vertex.h b/src/graphics/core/vertex.h
index 53dd642..a99d618 100644
--- a/src/graphics/core/vertex.h
+++ b/src/graphics/core/vertex.h
@@ -47,9 +47,9 @@ struct Vertex
Math::Vector normal;
Math::Point texCoord;
- Vertex(Math::Vector aCoord = Math::Vector(),
- Math::Vector aNormal = Math::Vector(),
- Math::Point aTexCoord = Math::Point())
+ explicit Vertex(Math::Vector aCoord = Math::Vector(),
+ Math::Vector aNormal = Math::Vector(),
+ Math::Point aTexCoord = Math::Point())
: coord(aCoord), normal(aNormal), texCoord(aTexCoord) {}
@@ -83,10 +83,10 @@ struct VertexCol
Gfx::Color specular;
Math::Point texCoord;
- VertexCol(Math::Vector aCoord = Math::Vector(),
- Gfx::Color aColor = Gfx::Color(),
- Gfx::Color aSpecular = Gfx::Color(),
- Math::Point aTexCoord = Math::Point())
+ explicit VertexCol(Math::Vector aCoord = Math::Vector(),
+ Gfx::Color aColor = Gfx::Color(),
+ Gfx::Color aSpecular = Gfx::Color(),
+ Math::Point aTexCoord = Math::Point())
: coord(aCoord), color(aColor), specular(aSpecular), texCoord(aTexCoord) {}
//! Returns a string "(c: [...], col: [...], sp: [...], tc: [...])"
@@ -115,10 +115,10 @@ struct VertexTex2
Math::Point texCoord;
Math::Point texCoord2;
- VertexTex2(Math::Vector aCoord = Math::Vector(),
- Math::Vector aNormal = Math::Vector(),
- Math::Point aTexCoord = Math::Point(),
- Math::Point aTexCoord2 = Math::Point())
+ explicit VertexTex2(Math::Vector aCoord = Math::Vector(),
+ Math::Vector aNormal = Math::Vector(),
+ Math::Point aTexCoord = Math::Point(),
+ Math::Point aTexCoord2 = Math::Point())
: coord(aCoord), normal(aNormal), texCoord(aTexCoord), texCoord2(aTexCoord2) {}
//! Sets the fields from Gfx::Vertex with texCoord2 = (0,0)
diff --git a/src/graphics/engine/camera.cpp b/src/graphics/engine/camera.cpp
index 2db6398..f077fff 100644
--- a/src/graphics/engine/camera.cpp
+++ b/src/graphics/engine/camera.cpp
@@ -1272,14 +1272,14 @@ bool Gfx::CCamera::EventFrameFree(const Event &event)
m_heightEye -= event.rTime * factor * m_speed;
}
- m_terrain->ValidPosition(m_eyePt, 10.0f);
+ m_terrain->AdjustToBounds(m_eyePt, 10.0f);
- if (m_terrain->MoveOnFloor(m_eyePt, true))
+ if (m_terrain->AdjustToFloor(m_eyePt, true))
{
m_eyePt.y += m_heightEye;
Math::Vector pos = m_eyePt;
- if (m_terrain->MoveOnFloor(pos, true))
+ if (m_terrain->AdjustToFloor(pos, true))
{
pos.y -= 2.0f;
if (m_eyePt.y < pos.y)
@@ -1290,7 +1290,7 @@ bool Gfx::CCamera::EventFrameFree(const Event &event)
Math::Vector lookatPt = Math::LookatPoint(m_eyePt, m_directionH, m_directionV, 50.0f);
- if (m_terrain->MoveOnFloor(lookatPt, true))
+ if (m_terrain->AdjustToFloor(lookatPt, true))
lookatPt.y += m_heightLookat;
SetViewTime(m_eyePt, lookatPt, event.rTime);
@@ -1314,14 +1314,14 @@ bool Gfx::CCamera::EventFrameEdit(const Event &event)
m_fixDirectionH = Math::NormAngle(m_fixDirectionH);
}
- m_terrain->ValidPosition(m_eyePt, 10.0f);
+ m_terrain->AdjustToBounds(m_eyePt, 10.0f);
- if (m_terrain->MoveOnFloor(m_eyePt, false))
+ if (m_terrain->AdjustToFloor(m_eyePt, false))
{
m_eyePt.y += m_editHeight;
Math::Vector pos = m_eyePt;
- if (m_terrain->MoveOnFloor(pos, false))
+ if (m_terrain->AdjustToFloor(pos, false))
{
pos.y += 2.0f;
if (m_eyePt.y < pos.y)
@@ -1332,7 +1332,7 @@ bool Gfx::CCamera::EventFrameEdit(const Event &event)
Math::Vector lookatPt = Math::LookatPoint( m_eyePt, m_directionH, m_directionV, 50.0f );
- if ( m_terrain->MoveOnFloor(lookatPt, true))
+ if ( m_terrain->AdjustToFloor(lookatPt, true))
lookatPt.y += m_heightLookat;
SetViewTime(m_eyePt, lookatPt, event.rTime);
@@ -1483,7 +1483,7 @@ bool Gfx::CCamera::EventFrameBack(const Event &event)
if ( (physics != NULL) && physics->GetLand() ) // ground?
{
Math::Vector pos = lookatPt + (lookatPt - m_eyePt);
- float floor = m_terrain->GetFloorHeight(pos) - 4.0f;
+ float floor = m_terrain->GetHeightToFloor(pos) - 4.0f;
if (floor > 0.0f)
m_eyePt.y += floor; // shows the descent in front
}
@@ -1551,14 +1551,14 @@ bool Gfx::CCamera::EventFrameExplo(const Event &event)
if (m_mouseDirH != 0.0f)
m_directionH -= m_mouseDirH * event.rTime * 0.7f * m_speed;
- m_terrain->ValidPosition(m_eyePt, 10.0f);
+ m_terrain->AdjustToBounds(m_eyePt, 10.0f);
- if ( m_terrain->MoveOnFloor(m_eyePt, false) )
+ if ( m_terrain->AdjustToFloor(m_eyePt, false) )
{
m_eyePt.y += m_heightEye;
Math::Vector pos = m_eyePt;
- if ( m_terrain->MoveOnFloor(pos, false) )
+ if ( m_terrain->AdjustToFloor(pos, false) )
{
pos.y += 2.0f;
if ( m_eyePt.y < pos.y )
@@ -1569,7 +1569,7 @@ bool Gfx::CCamera::EventFrameExplo(const Event &event)
Math::Vector lookatPt = Math::LookatPoint(m_eyePt, m_directionH, m_directionV, 50.0f);
- if (m_terrain->MoveOnFloor(lookatPt, true))
+ if (m_terrain->AdjustToFloor(lookatPt, true))
lookatPt.y += m_heightLookat;
SetViewTime(m_eyePt, lookatPt, event.rTime);
@@ -1680,7 +1680,7 @@ Math::Vector Gfx::CCamera::ExcludeTerrain(Math::Vector eye, Math::Vector lookat,
float &angleH, float &angleV)
{
Math::Vector pos = eye;
- if (m_terrain->MoveOnFloor(pos))
+ if (m_terrain->AdjustToFloor(pos))
{
float dist = Math::DistanceProjected(lookat, pos);
pos.y += 2.0f+dist*0.1f;
diff --git a/src/graphics/engine/cloud.cpp b/src/graphics/engine/cloud.cpp
index 6f6bc57..4c1d179 100644
--- a/src/graphics/engine/cloud.cpp
+++ b/src/graphics/engine/cloud.cpp
@@ -28,7 +28,8 @@
const int CLOUD_LINE_PREALLOCATE_COUNT = 100;
-const int DIMEXPAND = 4; // extension of the dimensions
+//! Extension of the bricks dimensions
+const int CLOUD_SIZE_EXPAND = 4;
Gfx::CCloud::CCloud(CInstanceManager* iMan, Gfx::CEngine* engine)
@@ -99,10 +100,10 @@ void Gfx::CCloud::Draw()
if (m_level == 0.0f) return;
if (m_lines.empty()) return;
- std::vector<Gfx::VertexTex2> vertices((m_brick+2)*2, Gfx::VertexTex2());
+ std::vector<Gfx::VertexTex2> vertices((m_brickCount+2)*2, Gfx::VertexTex2());
float iDeep = m_engine->GetDeepView();
- float deep = (m_brick*m_size)/2.0f;
+ float deep = (m_brickCount*m_brickSize)/2.0f;
m_engine->SetDeepView(deep);
m_engine->SetFocus(m_engine->GetFocus());
m_engine->UpdateMatProj(); // increases the depth of view
@@ -132,7 +133,7 @@ void Gfx::CCloud::Draw()
matrix.LoadIdentity();
device->SetTransform(Gfx::TRANSFORM_WORLD, matrix);
- float size = m_size/2.0f;
+ float size = m_brickSize/2.0f;
Math::Vector eye = m_engine->GetEyePt();
Math::Vector n = Math::Vector(0.0f, -1.0f, 0.0f);
@@ -195,11 +196,11 @@ void Gfx::CCloud::CreateLine(int x, int y, int len)
line.y = y;
line.len = len;
- float offset = m_brick*m_size/2.0f - m_size/2.0f;
+ float offset = m_brickCount*m_brickSize/2.0f - m_brickSize/2.0f;
- line.px1 = m_size* line.x - offset;
- line.px2 = m_size*(line.x+line.len) - offset;
- line.pz = m_size* line.y - offset;
+ line.px1 = m_brickSize* line.x - offset;
+ line.px2 = m_brickSize*(line.x+line.len) - offset;
+ line.pz = m_brickSize* line.y - offset;
m_lines.push_back(line);
}
@@ -223,18 +224,18 @@ void Gfx::CCloud::Create(const std::string& fileName,
m_wind = m_terrain->GetWind();
- m_brick = m_terrain->GetBrick()*m_terrain->GetMosaic()*DIMEXPAND;
- m_size = m_terrain->GetSize();
+ m_brickCount = m_terrain->GetBrickCount()*m_terrain->GetMosaicCount()*CLOUD_SIZE_EXPAND;
+ m_brickSize = m_terrain->GetBrickSize();
- m_brick /= m_subdiv*DIMEXPAND;
- m_size *= m_subdiv*DIMEXPAND;
+ m_brickCount /= m_subdiv*CLOUD_SIZE_EXPAND;
+ m_brickSize *= m_subdiv*CLOUD_SIZE_EXPAND;
if (m_level == 0.0f)
return;
m_lines.clear();
- for (int y = 0; y < m_brick; y++)
- CreateLine(0, y, m_brick);
+ for (int y = 0; y < m_brickCount; y++)
+ CreateLine(0, y, m_brickCount);
return;
}
diff --git a/src/graphics/engine/cloud.h b/src/graphics/engine/cloud.h
index abfaf26..9822c24 100644
--- a/src/graphics/engine/cloud.h
+++ b/src/graphics/engine/cloud.h
@@ -126,9 +126,9 @@ protected:
//! Wind speed
Math::Vector m_wind;
//! Brick mosaic
- int m_brick;
+ int m_brickCount;
//! Size of a brick element
- float m_size;
+ float m_brickSize;
std::vector<Gfx::CloudLine> m_lines;
diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp
index 1359cf6..ed7b9c7 100644
--- a/src/graphics/engine/engine.cpp
+++ b/src/graphics/engine/engine.cpp
@@ -142,14 +142,14 @@ Gfx::CEngine::CEngine(CInstanceManager *iMan, CApplication *app)
m_eyeDirH = 0.0f;
m_eyeDirV = 0.0f;
m_backgroundName = ""; // no background image
- m_backgroundColorUp = 0;
- m_backgroundColorDown = 0;
- m_backgroundCloudUp = 0;
- m_backgroundCloudDown = 0;
+ m_backgroundColorUp = Gfx::Color();
+ m_backgroundColorDown = Gfx::Color();
+ m_backgroundCloudUp = Gfx::Color();
+ m_backgroundCloudDown = Gfx::Color();
m_backgroundFull = false;
m_backgroundQuarter = false;
m_overFront = true;
- m_overColor = 0;
+ m_overColor = Gfx::Color();
m_overMode = ENG_RSTATE_TCOLOR_BLACK;
m_highlightRank[0] = -1; // empty list
m_highlightTime = 0.0f;
@@ -2839,7 +2839,7 @@ void Gfx::CEngine::Render()
m_statisticTriangle = 0;
m_lastState = -1;
- m_lastColor = 999;
+ m_lastColor = Gfx::Color(-1.0f);
m_lastMaterial = Gfx::Material();
m_lightMan->UpdateLights();
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);
diff --git a/src/graphics/engine/terrain.h b/src/graphics/engine/terrain.h
index 0c3fa63..80eed07 100644
--- a/src/graphics/engine/terrain.h
+++ b/src/graphics/engine/terrain.h
@@ -35,7 +35,7 @@ class CWater;
//! Limit of slope considered a flat piece of land
-const short FLATLIMIT = (5.0f*Math::PI/180.0f);
+const short TERRAIN_FLATLIMIT = (5.0f*Math::PI/180.0f);
/**
@@ -61,6 +61,10 @@ enum TerrainRes
//@}
};
+/**
+ * \struct BuildingLevel
+ * \brief Flat level for building
+ */
struct BuildingLevel
{
Math::Vector center;
@@ -81,29 +85,43 @@ struct BuildingLevel
}
};
+/**
+ * \struct TerrainMaterial
+ * \brief Material for ground surface
+ */
struct TerrainMaterial
{
+ //! Unique ID
short id;
+ //! Texture
std::string texName;
- float u,v;
+ //! UV texture coordinates
+ Math::Point uv;
+ //! Terrain hardness (defines e.g. sound of walking)
float hardness;
- char mat[4]; // up, right, down, left
+ //! IDs of neighbor materials: up, right, down, left
+ char mat[4];
TerrainMaterial()
{
id = 0;
- u = v = 0.0f;
hardness = 0.0f;
mat[0] = mat[1] = mat[2] = mat[3] = 0;
}
};
-struct DotLevel
+/**
+ * \struct TerrainMaterialPoint
+ * \brief Material used for terrain point
+ */
+struct TerrainMaterialPoint
{
+ //! ID of material
short id;
- char mat[4]; // up, right, down, left
+ //! IDs of neighbor materials: up, right, down, left
+ char mat[4];
- DotLevel()
+ TerrainMaterialPoint()
{
id = 0;
mat[0] = mat[1] = mat[2] = mat[3] = 0;
@@ -132,17 +150,73 @@ struct FlyingLimit
* \class CTerrain
* \brief Terrain loader/generator and manager
*
+ * \section Mapping Terrain mapping
+ *
* Terrain is created from relief textures specifying a XY plane with height
* values which are then scaled and translated into XZ surface forming the
* terrain of game level.
*
- * The class also facilitates creating and searching for flat space expanses
- * for construction of buildings.
+ * The basic unit of terrain is called "brick", which is two triangles
+ * forming a quad. Bricks have constant size (brick size)
+ * in X and Z direction.
+ * Points forming the bricks correspond one-to-one to relief data points
+ * (pixels in relief image).
+ *
+ * Bricks are grouped into "mosaics". Mosaic is a square containing
+ * brickCount x brickCount bricks where brickCount is an even power of 2.
+ * Each mosaic corresponds to one created engine object.
+ *
+ * The whole terrain is also a square formed by mosaicCount * mosaicCount
+ * of mosaics.
+ *
+ * Image coordinates are converted in the following way to world coordinates
+ * of brick points (Wx, Wy, Wz - world coordinates, Ix, Iy - image coordinates,
+ * Pxy - pixel value at Ix,Iy):
+ *
+ * Wx = (Ix - brickCount*mosaicCount / 2.0f) * brickSize \n
+ * Wz = (Iy - brickCount*mosaicCount / 2.0f) * brickSize \n
+ * Wy = (Pxy / 255.0f) * reliefScale
+ *
+ * To create and initialize a terrain, you must call Generate() as the first function,
+ * setting the number of bricks, mosaics etc.
+ *
+ * \section Materials Materials and textures
+ *
+ * The terrain can be textured in two ways:
+ * - by applying texture index table
+ * - by specifying one or more "materials" that cover "material points"
+ *
+ * Textures are applied to subdivisions of mosaics (groups of bricks of size
+ * brickCount / textureSubdivCount).
+ *
+ * \subsection TextureIndexes Texture indexes
+ *
+ * Texture indexes specify the texture for each textured point by concatenating
+ * base name of texture, the index number and texture extension.
+ *
+ * Texture indexes are specified directly in InitTextures().
+ *
+ * \subsection TerrainMaterials Terrain materials
+ *
+ * Terrain materials are more sophisticated system. Each material is a texture,
+ * applied to one area, but specifying also the textures to use on surrounding areas:
+ * left, right, bottom and top.
*
- * The terrain also specifies underground resources loaded from texture
- * and flying limits for the player.
+ * You specify one or more terrain materials in AddMaterial() function.
+ * The function will add a material for given circle on the ground, with some
+ * randomized matching of supplied materials and sophisticated logic for ensuring
+ * that borders between neighboring materials follow the specified rules.
*
- * ...
+ * \subsection BuildingLevels Other features
+ *
+ * Terrain can have specified building levels - flat space expanses,
+ * where relief data is specifically adjusted to level space to allow
+ * construction of buildings.
+ *
+ * Undergound resources can be supplied by loading them from image like relief data.
+ *
+ * Terrain also specifies flying limits for player: one global level and possible
+ * additional spherical restrictions.
*/
class CTerrain
{
@@ -151,25 +225,32 @@ public:
~CTerrain();
//! Generates a new flat terrain
- bool Generate(int mosaic, int brickPow2, float size, float vision, int depth, float hardness);
+ bool Generate(int mosaicCount, int brickCountPow2, float brickSize, float vision, int depth, float hardness);
+
//! Initializes the names of textures to use for the land
bool InitTextures(const std::string& baseName, int* table, int dx, int dy);
- //! Empties level
- void LevelFlush();
- //! Initializes the names of textures to use for the land
- void LevelMaterial(int id, const std::string& baseName, float u, float v, int up, int right, int down, int left, float hardness);
- //! Initializes all the ground with a material
- bool LevelInit(int id);
+
+ //! Clears all terrain materials
+ void FlushMaterials();
+ //! Adds a terrain material the names of textures to use for the land
+ void AddMaterial(int id, const std::string& baseName, const Math::Point& uv,
+ int up, int right, int down, int left, float hardness);
+ //! Initializes all the ground with one material
+ bool InitMaterials(int id);
//! Generates a level in the terrain
- bool LevelGenerate(int *id, float min, float max, float slope, float freq, Math::Vector center, float radius);
- //! Initializes a completely flat terrain
+ bool GenerateMaterials(int *id, float min, float max, float slope, float freq, Math::Vector center, float radius);
+
+ //! Clears the relief data to zero
void FlushRelief();
- //! Load relief from a PNG file
- bool ReliefFromPNG(const std::string& filename, float scaleRelief, bool adjustBorder);
- //! Load resources from a PNG file
- bool ResFromPNG(const std::string& filename);
+ //! Load relief from image
+ bool LoadRelief(const std::string& fileName, float scaleRelief, bool adjustBorder);
+
+ //! Load resources from image
+ bool LoadResources(const std::string& fileName);
+
//! Creates all objects of the terrain within the 3D engine
- bool CreateObjects(bool multiRes);
+ bool CreateObjects();
+
//! Modifies the terrain's relief
bool Terraform(const Math::Vector& p1, const Math::Vector& p2, float height);
@@ -179,24 +260,24 @@ public:
Math::Vector GetWind();
//@}
- //! Gives the exact slope of the terrain of a place given
+ //! Gives the exact slope of the terrain at 2D (XZ) position
float GetFineSlope(const Math::Vector& pos);
- //! Gives the approximate slope of the terrain of a specific location
+ //! Gives the approximate slope of the terrain at 2D (XZ) position
float GetCoarseSlope(const Math::Vector& pos);
- //! Gives the normal vector at the position p (x,-,z) of the ground
+ //! Gives the normal vector at 2D (XZ) position
bool GetNormal(Math::Vector& n, const Math::Vector &p);
- //! returns the height of the ground
- float GetFloorLevel(const Math::Vector& p, bool brut=false, bool water=false);
- //! Returns the height to the ground
- float GetFloorHeight(const Math::Vector& p, bool brut=false, bool water=false);
- //! Modifies the coordinate "y" of point "p" to rest on the ground floor
- bool MoveOnFloor(Math::Vector& p, bool brut=false, bool water=false);
- //! Modifies a coordinate so that it is on the ground
- bool ValidPosition(Math::Vector& p, float marging);
- //! Returns the resource type available underground
- Gfx::TerrainRes GetResource(const Math::Vector& p);
- //! Adjusts a position so that it does not exceed the boundaries
- void LimitPos(Math::Vector &pos);
+ //! Returns the height of the ground level at 2D (XZ) position
+ float GetFloorLevel(const Math::Vector& pos, bool brut=false, bool water=false);
+ //! Returns the distance to the ground level from 3D position
+ float GetHeightToFloor(const Math::Vector& pos, bool brut=false, bool water=false);
+ //! Modifies the Y coordinate of 3D position to rest on the ground floor
+ bool AdjustToFloor(Math::Vector& pos, bool brut=false, bool water=false);
+ //! Adjusts 3D position so that it is within standard terrain boundaries
+ bool AdjustToStandardBounds(Math::Vector &pos);
+ //! Adjusts 3D position so that it is within terrain boundaries and the given margin
+ bool AdjustToBounds(Math::Vector& pos, float margin);
+ //! Returns the resource type available underground at 2D (XZ) position
+ Gfx::TerrainRes GetResource(const Math::Vector& pos);
//! Empty the table of elevations
void FlushBuildingLevel();
@@ -207,16 +288,21 @@ public:
//! Removes the elevation for a building when it was destroyed
bool DeleteBuildingLevel(Math::Vector center);
//! Returns the influence factor whether a position is on a possible rise
- float GetBuildingFactor(const Math::Vector& p);
- float GetHardness(const Math::Vector& p);
-
- int GetMosaic();
- int GetBrick();
- float GetSize();
- float GetScaleRelief();
+ float GetBuildingFactor(const Math::Vector& pos);
+ //! Returns the hardness of the ground in a given place
+ float GetHardness(const Math::Vector& pos);
+
+ //! Returns number of mosaics
+ int GetMosaicCount();
+ //! Returns number of bricks in mosaic
+ int GetBrickCount();
+ //! Returns brick size
+ float GetBrickSize();
+ //! Returns the vertical scale of relief
+ float GetReliefScale();
//! Shows the flat areas on the ground
- void GroundFlat(Math::Vector pos);
+ void ShowFlatGround(Math::Vector pos);
//! Calculates the radius of the largest flat area available
float GetFlatZoneRadius(Math::Vector center, float max);
@@ -234,7 +320,7 @@ public:
protected:
//! Adds a point of elevation in the buffer of relief
- bool ReliefAddDot(Math::Vector pos, float scaleRelief);
+ bool AddReliefPoint(Math::Vector pos, float scaleRelief);
//! Adjust the edges of each mosaic to be compatible with all lower resolutions
void AdjustRelief();
//! Calculates a vector of the terrain
@@ -244,28 +330,28 @@ protected:
//! Creates all objects of a mosaic
bool CreateMosaic(int ox, int oy, int step, int objRank, const Gfx::Material& mat, float min, float max);
//! Creates all objects in a mesh square ground
- bool CreateSquare(bool multiRes, int x, int y);
-
- //! Seeks a materials based on theirs identifier
- Gfx::TerrainMaterial* LevelSearchMat(int id);
- //! Chooses texture to use for a given square
- void LevelTextureName(int x, int y, std::string& name, Math::Point &uv);
+ bool CreateSquare(int x, int y);
+
+ //! Seeks a material based on its ID
+ Gfx::TerrainMaterial* FindMaterial(int id);
+ //! Seeks a material based on neighbor values
+ int FindMaterialByNeighbors(char *mat);
+ //! Returns the texture name and UV coords to use for a given square
+ void GetTexture(int x, int y, std::string& name, Math::Point& uv);
//! Returns the height of the terrain
- float LevelGetHeight(int x, int y);
+ float GetHeight(int x, int y);
//! Decide whether a point is using the materials
- bool LevelGetDot(int x, int y, float min, float max, float slope);
- //! Seeks if material exists
- int LevelTestMat(char *mat);
+ bool CheckMaterialPoint(int x, int y, float min, float max, float slope);
//! Modifies the state of a point and its four neighbors, without testing if possible
- void LevelSetDot(int x, int y, int id, char *mat);
- //! Tests if a material can give a place, according to its four neighbors. If yes, puts the point.
- bool LevelIfDot(int x, int y, int id, char *mat);
+ void SetMaterialPoint(int x, int y, int id, char *mat);
//! Modifies the state of a point
- bool LevelPutDot(int x, int y, int id);
- //! Initializes a table with empty levels
- void LevelOpenTable();
- //! Closes the level table
- void LevelCloseTable();
+ bool ChangeMaterialPoint(int x, int y, int id);
+ //! Tests if a material can give a place, according to its four neighbors. If yes, puts the point.
+ bool CondChangeMaterialPoint(int x, int y, int id, char *mat);
+ //! Initializes material points array
+ void InitMaterialPoints();
+ //! Clears the material points
+ void FlushMaterialPoints();
//! Adjusts a position according to a possible rise
void AdjustBuildingLevel(Math::Vector &p);
@@ -275,39 +361,51 @@ protected:
CEngine* m_engine;
CWater* m_water;
- //! Number of mosaics
- int m_mosaic;
- //! Number of bricks per mosaics
- int m_brick;
- int m_levelDotSize;
- //! Size of an item in a brick
- float m_size;
- //! Vision before a change of resolution
- float m_vision;
- //! Table of the relief
+ //! Relief data points
std::vector<float> m_relief;
- //! Table of textures
- std::vector<int> m_texture;
- //! Table of rows of objects
- std::vector<int> m_objRank;
- //! Table of resources
+ //! Resources data
std::vector<unsigned char> m_resources;
- bool m_multiText;
- bool m_levelText;
- //! Scale of the mapping
- float m_scaleMapping;
+ //! Texture indices
+ std::vector<int> m_textures;
+ //! Object ranks for mosaic objects
+ std::vector<int> m_objRanks;
+
+ //! Number of mosaics (along one dimension)
+ int m_mosaicCount;
+ //! Number of bricks per mosaic (along one dimension)
+ int m_brickCount;
+ //! Number of terrain material dots (along one dimension)
+ int m_materialPointCount;
+ //! Size of single brick (along X and Z axis)
+ float m_brickSize;
+ //! Vertical (relief) scale
float m_scaleRelief;
- int m_subdivMapping;
+ //! Subdivision of material points in mosaic
+ int m_textureSubdivCount;
//! Number of different resolutions (1,2,3,4)
int m_depth;
+ //! Scale of texture mapping
+ float m_textureScale;
+ //! Vision before a change of resolution
+ float m_vision;
+
+ //! Base name for single texture
std::string m_texBaseName;
+ //! Extension for single texture
std::string m_texBaseExt;
- float m_defHardness;
-
- std::vector<TerrainMaterial> m_levelMats;
- std::vector<Gfx::DotLevel> m_levelDots;
- int m_levelMatMax;
- int m_levelID;
+ //! Default hardness for level material
+ float m_defaultHardness;
+
+ //! True if using terrain material mapping
+ bool m_useMaterials;
+ //! Terrain materials
+ std::vector<Gfx::TerrainMaterial> m_materials;
+ //! Material for terrain points
+ std::vector<Gfx::TerrainMaterialPoint> m_materialPoints;
+ //! Maximum level ID (no ID is >= to this)
+ int m_maxMaterialID;
+ //! Internal counter for auto generation of material IDs
+ int m_materialAutoID;
std::vector<Gfx::BuildingLevel> m_buildingLevels;
diff --git a/src/graphics/engine/water.cpp b/src/graphics/engine/water.cpp
index bf2f64d..a2ff081 100644
--- a/src/graphics/engine/water.cpp
+++ b/src/graphics/engine/water.cpp
@@ -50,7 +50,7 @@ Gfx::CWater::CWater(CInstanceManager* iMan, Gfx::CEngine* engine)
m_level = 0.0f;
m_draw = true;
m_lava = false;
- m_color = 0xffffffff;
+ m_color = Gfx::Color(1.0f, 1.0f, 1.0f, 1.0f);
m_subdiv = 4;
m_lines.reserve(WATERLINE_PREALLOCATE_COUNT);
@@ -330,7 +330,7 @@ void Gfx::CWater::DrawSurf()
if (m_type[0] == Gfx::WATER_NULL) return;
if (m_lines.empty()) return;
- std::vector<Gfx::VertexTex2> vertices((m_brick+2)*2, Gfx::VertexTex2());
+ std::vector<Gfx::VertexTex2> vertices((m_brickCount+2)*2, Gfx::VertexTex2());
Math::Vector eye = m_engine->GetEyePt();
@@ -365,7 +365,7 @@ void Gfx::CWater::DrawSurf()
device->SetRenderState(Gfx::RENDER_STATE_FOG, true);
- float size = m_size/2.0f;
+ float size = m_brickSize/2.0f;
float sizez = 0.0f;
if (under) sizez = -size;
else sizez = size;
@@ -436,8 +436,8 @@ bool Gfx::CWater::GetWater(int x, int y)
x *= m_subdiv;
y *= m_subdiv;
- float size = m_size/m_subdiv;
- float offset = m_brick*m_size/2.0f;
+ float size = m_brickSize/m_subdiv;
+ float offset = m_brickCount*m_brickSize/2.0f;
for (int dy = 0; dy <= m_subdiv; dy++)
{
@@ -463,11 +463,11 @@ void Gfx::CWater::CreateLine(int x, int y, int len)
line.y = y;
line.len = len;
- float offset = m_brick*m_size/2.0f - m_size/2.0f;
+ float offset = m_brickCount*m_brickSize/2.0f - m_brickSize/2.0f;
- line.px1 = m_size* line.x - offset;
- line.px2 = m_size*(line.x+line.len) - offset;
- line.pz = m_size* line.y - offset;
+ line.px1 = m_brickSize* line.x - offset;
+ line.px2 = m_brickSize*(line.x+line.len) - offset;
+ line.pz = m_brickSize* line.y - offset;
m_lines.push_back(line);
}
@@ -495,21 +495,21 @@ void Gfx::CWater::Create(Gfx::WaterType type1, Gfx::WaterType type2, const std::
if (m_terrain == nullptr)
m_terrain = static_cast<CTerrain*>(m_iMan->SearchInstance(CLASS_TERRAIN));
- m_brick = m_terrain->GetBrick()*m_terrain->GetMosaic();
- m_size = m_terrain->GetSize();
+ m_brickCount = m_terrain->GetBrickCount()*m_terrain->GetMosaicCount();
+ m_brickSize = m_terrain->GetBrickSize();
- m_brick /= m_subdiv;
- m_size *= m_subdiv;
+ m_brickCount /= m_subdiv;
+ m_brickSize *= m_subdiv;
if (m_type[0] == WATER_NULL)
return;
m_lines.clear();
- for (int y = 0; y < m_brick; y++)
+ for (int y = 0; y < m_brickCount; y++)
{
int len = 0;
- for (int x = 0; x < m_brick; x++)
+ for (int x = 0; x < m_brickCount; x++)
{
if (GetWater(x,y)) // water here?
{
@@ -530,7 +530,7 @@ void Gfx::CWater::Create(Gfx::WaterType type1, Gfx::WaterType type2, const std::
}
}
if (len != 0)
- CreateLine(m_brick - len, y, len);
+ CreateLine(m_brickCount - len, y, len);
}
}
diff --git a/src/graphics/engine/water.h b/src/graphics/engine/water.h
index 371a91f..9b31045 100644
--- a/src/graphics/engine/water.h
+++ b/src/graphics/engine/water.h
@@ -188,16 +188,16 @@ protected:
int m_subdiv;
//! Number of brick*mosaics
- int m_brick;
+ int m_brickCount;
//! Size of a item in an brick
- float m_size;
+ float m_brickSize;
std::vector<WaterLine> m_lines;
std::vector<WaterVapor> m_vapors;
bool m_draw;
bool m_lava;
- long m_color;
+ Gfx::Color m_color;
};
}; // namespace Gfx