Skip to content
This repository was archived by the owner on Apr 11, 2026. It is now read-only.
/ GLKeeper Public archive

Commit 7008935

Browse files
committed
-
1 parent 0eb4e44 commit 7008935

10 files changed

Lines changed: 164 additions & 23 deletions

src/SimpleTriangleMesh.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
// simple triangle mesh
44

5+
#include "VertexFormat.h"
6+
57
template<typename TVertexFormat>
68
class SimpleTriangleMesh
79
{
@@ -126,4 +128,7 @@ class SimpleTriangleMesh
126128
VerticesArray mVertices;
127129

128130
cxx::aabbox mBoundingBox;
129-
};
131+
};
132+
133+
// alias
134+
using Vertex3D_TriMesh = SimpleTriangleMesh<Vertex3D_Format>;

src/StaticMeshComponent.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ void StaticMeshComponent::ClearMesh()
4242
void StaticMeshComponent::UpdateBounds()
4343
{
4444
cxx::aabbox bounds;
45-
for (TriMeshPart& currMeshPart: mTriMeshParts)
45+
for (Vertex3D_TriMesh& currMeshPart: mTriMeshParts)
4646
{
4747
currMeshPart.ComputeBounds();
4848
bounds.extend(currMeshPart.mBoundingBox);

src/StaticMeshComponent.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ class StaticMeshComponent: public RenderableComponent
1414
public:
1515
// mesh data, available for both read and write
1616
// after making modifications you need invalidate and update bounds manually
17-
using TriMeshPart = SimpleTriangleMesh<Vertex3D_Format>;
18-
std::vector<TriMeshPart> mTriMeshParts;
17+
std::vector<Vertex3D_TriMesh> mTriMeshParts;
1918

2019
public:
2120
StaticMeshComponent(GameObject* gameObject);

src/StaticMeshRenderer.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ void StaticMeshRenderer::PrepareRenderdata(StaticMeshComponent* component)
7171

7272
int overallVertexCount = 0;
7373
int overallTriangleCount = 0;
74-
for (StaticMeshComponent::TriMeshPart& currPart: component->mTriMeshParts)
74+
for (Vertex3D_TriMesh& currPart: component->mTriMeshParts)
7575
{
7676
overallVertexCount += (int) currPart.mVertices.size();
7777
overallTriangleCount += (int) currPart.mTriangles.size();
@@ -130,7 +130,7 @@ void StaticMeshRenderer::PrepareRenderdata(StaticMeshComponent* component)
130130
unsigned int vertexDataOffset = 0;
131131
unsigned int triangleDataOffset = 0;
132132

133-
for (StaticMeshComponent::TriMeshPart& currPart: component->mTriMeshParts)
133+
for (Vertex3D_TriMesh& currPart: component->mTriMeshParts)
134134
{
135135
StaticMeshComponent::DrawCall& drawCall = component->mDrawCalls[iCurentPart];
136136
drawCall.mMaterialIndex = iCurentPart;

src/TerrainHeightField.cpp

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,15 @@ void TerrainHeightField::UpdateHeights(TerrainTile* terrainTile)
4242
const float MaxHeight = TERRAIN_BLOCK_HEIGHT + TERRAIN_FLOOR_LEVEL;
4343
const float MinHeight = 0.0f;
4444

45-
float stepLength = TERRAIN_BLOCK_SIZE / (SubdividePointsCount * 1.0f);
45+
const float stepLength = TERRAIN_BLOCK_SIZE / (SubdivideCount * 1.0f);
4646
for (int iy = 0; iy < SubdividePointsCount; ++iy)
4747
for (int ix = 0; ix < SubdividePointsCount; ++ix)
4848
{
49-
glm::vec3 origin {blockCoordinate.x + (iy * stepLength), MaxHeight + 1.0f, blockCoordinate.y + (ix * stepLength) };
5049
cxx::ray3d ray;
50+
ray.mDirection = -SceneAxisY;
51+
ray.mOrigin[0] = blockCoordinate.x + (ix * stepLength);
52+
ray.mOrigin[1] = MaxHeight + 1.0f;
53+
ray.mOrigin[2] = blockCoordinate.z + (iy * stepLength);
5154
float h0 = ComputeTerrainHeight(terrainTile->mFaces[eTileFace_Ceiling], ray);
5255
float h1 = ComputeTerrainHeight(terrainTile->mFaces[eTileFace_Floor], ray);
5356
float height = glm::clamp((h0 > h1) ? h0 : h1, MinHeight, MaxHeight); // choose max height
@@ -80,6 +83,54 @@ float TerrainHeightField::GetTerrainHeight(float coordx, float coordz) const
8083
return 0.0f;
8184
}
8285

86+
void TerrainHeightField::GenerateMesh(Vertex3D_TriMesh& outputMesh) const
87+
{
88+
const float StepLength = TERRAIN_BLOCK_SIZE / (SubdivideCount * 1.0f);
89+
const float MaxHeight = TERRAIN_BLOCK_HEIGHT + TERRAIN_FLOOR_LEVEL;
90+
91+
outputMesh.Clear();
92+
outputMesh.mVertices.reserve(mDimensions.x * mDimensions.y * SubdividePointsCount * SubdividePointsCount);
93+
outputMesh.mTriangles.reserve(mDimensions.x * mDimensions.y * SubdivideCount * SubdivideCount * 2);
94+
for (int iy = 0; iy < mDimensions.y; ++iy)
95+
for (int ix = 0; ix < mDimensions.x; ++ix)
96+
{
97+
const HeightFieldCell& cell = mHeightCells[iy * mDimensions.x + ix];
98+
99+
glm::vec3 blockCoordinate;
100+
GetTerrainBlockCoordinate(Point (ix, iy), blockCoordinate);
101+
102+
int baseVertex = (int) outputMesh.mVertices.size();
103+
104+
// add vertices
105+
for (int pointy = 0; pointy < SubdividePointsCount; ++pointy)
106+
for (int pointx = 0; pointx < SubdividePointsCount; ++pointx)
107+
{
108+
Vertex3D vertex;
109+
vertex.mPosition.x = blockCoordinate.x + (pointx * StepLength);
110+
vertex.mPosition.y = 0.024f + MaxHeight * (cell.mPoints[pointx][pointy] / 255.0f);
111+
vertex.mPosition.z = blockCoordinate.z + (pointy * StepLength);
112+
outputMesh.mVertices.push_back(vertex);
113+
}
114+
115+
for (int quady = 0; quady < SubdivideCount; ++quady)
116+
for (int quadx = 0; quadx < SubdivideCount; ++quadx)
117+
{
118+
glm::ivec3 triangle0 {
119+
baseVertex + quadx + (quady * SubdividePointsCount),
120+
baseVertex + quadx + ((quady + 1) * SubdividePointsCount),
121+
baseVertex + (quadx + 1) + (quady * SubdividePointsCount),
122+
};
123+
outputMesh.mTriangles.push_back(triangle0);
124+
glm::ivec3 triangle1 {
125+
triangle0[2],
126+
triangle0[1],
127+
baseVertex + (quadx + 1) + ((quady + 1) * SubdividePointsCount),
128+
};
129+
outputMesh.mTriangles.push_back(triangle1);
130+
}
131+
}
132+
}
133+
83134
float TerrainHeightField::ComputeTerrainHeight(const TileFaceData& sourceData, const cxx::ray3d& processRay) const
84135
{
85136
debug_assert(IsInitialized());

src/TerrainHeightField.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include "Texture2D_Image.h"
44
#include "TerrainTile.h"
5+
#include "SimpleTriangleMesh.h"
56

67
// holds information about terrain height
78
class TerrainHeightField
@@ -27,6 +28,9 @@ class TerrainHeightField
2728
// minimum height is 0
2829
float GetTerrainHeight(float coordx, float coordz) const;
2930

31+
// for debug purposes
32+
void GenerateMesh(Vertex3D_TriMesh& outputMesh) const;
33+
3034
private:
3135
// internal computations
3236
float ComputeTerrainHeight(const TileFaceData& sourceData, const cxx::ray3d& processRay) const;

src/TerrainManager.cpp

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
#include "TerrainMeshComponent.h"
1212
#include "WaterLavaMeshComponent.h"
1313
#include "Texture2D.h"
14+
#include "StaticMeshComponent.h"
15+
16+
//#define DRAW_HEIGHT_FIELD_MESH
1417

1518
const int TerrainMeshSizeTiles = 8; // 8x8 tiles per terrain mesh
1619

@@ -44,6 +47,9 @@ void TerrainManager::EnterWorld()
4447
InitTerrainMeshList();
4548
InitWaterLavaMeshList();
4649
InitHighhlightTilesTexture();
50+
51+
mHeightField.InitHeightField(gGameWorld.mMapData.mDimensions);
52+
InitHeightFieldDebugMesh();
4753
}
4854

4955
void TerrainManager::ClearWorld()
@@ -54,6 +60,9 @@ void TerrainManager::ClearWorld()
5460

5561
mMeshInvalidatedTiles.clear();
5662
mHighlightTiles.clear();
63+
64+
mHeightField.Cleanup();
65+
FreeHeightFieldDebugMesh();
5766
}
5867

5968
void TerrainManager::PreRenderScene()
@@ -164,6 +173,13 @@ void TerrainManager::UpdateTerrainMesh()
164173
meshComponent->InvalidateMesh();
165174
}
166175

176+
// update heightfield
177+
for (TerrainTile* currentTile: mMeshInvalidatedTiles)
178+
{
179+
mHeightField.UpdateHeights(currentTile);
180+
}
181+
182+
UpdateHeightFieldDebugMesh();
167183

168184
// update terrain mesh objects
169185
//for (GameObject* currTerrainMesh: mTerrainMeshArray)
@@ -231,6 +247,16 @@ void TerrainManager::BuildFullTerrainMesh()
231247

232248
ClearInvalidatedTiles();
233249

250+
// update heightfield
251+
tilesIterator.Reset();
252+
for (TerrainTile* currMapTile = tilesIterator.NextTile(); currMapTile;
253+
currMapTile = tilesIterator.NextTile())
254+
{
255+
mHeightField.UpdateHeights(currMapTile);
256+
}
257+
258+
UpdateHeightFieldDebugMesh();
259+
234260
// update terrain mesh objects
235261
for (GameObject* currTerrainMesh: mTerrainMeshArray)
236262
{
@@ -403,6 +429,57 @@ void TerrainManager::UpdateHighhlightTilesTexture()
403429
mHighlightTilesTexture->UpdateTexture(0, pixels);
404430
}
405431

432+
void TerrainManager::InitHeightFieldDebugMesh()
433+
{
434+
#ifndef DRAW_HEIGHT_FIELD_MESH
435+
return;
436+
#endif
437+
if (mHeightField.IsInitialized())
438+
{
439+
mHeightFieldDebugMesh = gGameObjectsManager.CreateGameObject();
440+
StaticMeshComponent* component = mHeightFieldDebugMesh->AddComponent<StaticMeshComponent>();
441+
442+
MeshMaterial material;
443+
material.mDiffuseTexture = gTexturesManager.mWhiteTexture;
444+
material.mMaterialColor = Color32_Yellow;
445+
material.mMaterialColor.mA = 200;
446+
material.mRenderStates.mIsFaceCullingEnabled = false;
447+
material.mRenderStates.mPolygonFillMode = ePolygonFillMode_WireFrame;
448+
material.mRenderStates.mIsAlphaBlendEnabled = true;
449+
component->SetMeshMaterialsCount(1);
450+
component->SetMeshMaterial(0, material);
451+
}
452+
}
453+
454+
void TerrainManager::FreeHeightFieldDebugMesh()
455+
{
456+
#ifndef DRAW_HEIGHT_FIELD_MESH
457+
return;
458+
#endif
459+
if (mHeightFieldDebugMesh)
460+
{
461+
gGameObjectsManager.DestroyGameObject(mHeightFieldDebugMesh);
462+
mHeightFieldDebugMesh = nullptr;
463+
}
464+
}
465+
466+
void TerrainManager::UpdateHeightFieldDebugMesh()
467+
{
468+
#ifndef DRAW_HEIGHT_FIELD_MESH
469+
return;
470+
#endif
471+
if (mHeightFieldDebugMesh)
472+
{
473+
StaticMeshComponent* component = mHeightFieldDebugMesh->GetComponent<StaticMeshComponent>();
474+
debug_assert(component);
475+
component->mTriMeshParts.resize(1);
476+
mHeightField.GenerateMesh(component->mTriMeshParts[0]);
477+
component->InvalidateMesh();
478+
component->UpdateBounds();
479+
component->PrepareRenderResources();
480+
}
481+
}
482+
406483
GameObject* TerrainManager::CreateObjectTerrain(const Rectangle& mapArea)
407484
{
408485
GameObject* gameObject = gGameObjectsManager.CreateGameObject();

src/TerrainManager.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
#pragma once
22

33
#include "Texture2D_Image.h"
4+
#include "TerrainHeightField.h"
45

56
// dungeon terrain manager
67
class TerrainManager: public cxx::noncopyable
78
{
89
friend class TerrainMeshRenderer;
910

11+
public:
12+
// readonly
13+
TerrainHeightField mHeightField;
14+
1015
public:
1116
// setup terrain manager internal resources
1217
bool Initialize();
@@ -41,6 +46,10 @@ class TerrainManager: public cxx::noncopyable
4146
void FreeHighhlightTilesTexture();
4247
void UpdateHighhlightTilesTexture();
4348

49+
void InitHeightFieldDebugMesh();
50+
void FreeHeightFieldDebugMesh();
51+
void UpdateHeightFieldDebugMesh();
52+
4453
GameObject* CreateObjectTerrain(const Rectangle& mapArea);
4554
GameObject* CreateObjectLava(const TilesList& tilesArray);
4655
GameObject* CreateObjectWater(const TilesList& tilesArray);
@@ -51,6 +60,8 @@ class TerrainManager: public cxx::noncopyable
5160
std::vector<GameObject*> mWaterLavaMeshArray;
5261
std::vector<GameObject*> mTerrainMeshArray;
5362

63+
GameObject* mHeightFieldDebugMesh = nullptr;
64+
5465
TilesList mMeshInvalidatedTiles;
5566
TilesList mHighlightTiles;
5667

src/TerrainTilesCursor.cpp

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ void TerrainTilesCursor::Initialize()
1212
mMeshObject = gGameObjectsManager.CreateGameObject();
1313
if (mMeshObject)
1414
{
15-
mMeshObject->AddComponent<StaticMeshComponent>();
15+
StaticMeshComponent* component = mMeshObject->AddComponent<StaticMeshComponent>();
1616
mMeshObject->mDebugColor.mA = 0; // hide debug box
17-
SetupCursorMeshMaterial();
17+
SetupCursorMeshMaterial(component);
1818
}
1919
debug_assert(mMeshObject);
2020
}
@@ -101,7 +101,7 @@ void TerrainTilesCursor::SetupCursorMesh()
101101

102102
// setup selection trimesh
103103
renderable->mTriMeshParts.resize(1);
104-
StaticMeshComponent::TriMeshPart& triMesh = renderable->mTriMeshParts[0];
104+
Vertex3D_TriMesh& triMesh = renderable->mTriMeshParts[0];
105105

106106
/*
107107
/1--------/3
@@ -127,7 +127,7 @@ void TerrainTilesCursor::SetupCursorMesh()
127127
curr_edge.z += (curr_edge.z > center.z) ? displacement : -displacement;
128128
}
129129

130-
auto PushSelectionLine = [&center](StaticMeshComponent::TriMeshPart& trimesh,
130+
auto PushSelectionLine = [&center](Vertex3D_TriMesh& trimesh,
131131
const glm::vec3& point_start,
132132
const glm::vec3& point_end, bool isDiagonal)
133133
{
@@ -186,20 +186,14 @@ void TerrainTilesCursor::SetupCursorMesh()
186186
renderable->UpdateBounds();
187187
}
188188

189-
void TerrainTilesCursor::SetupCursorMeshMaterial()
189+
void TerrainTilesCursor::SetupCursorMeshMaterial(StaticMeshComponent* component)
190190
{
191191
debug_assert(mMeshObject);
192+
debug_assert(component);
192193

193-
StaticMeshComponent* renderable = mMeshObject->mRenderableComponent->CastComponent<StaticMeshComponent>();
194-
if (renderable == nullptr)
195-
{
196-
debug_assert(false);
197-
return;
198-
}
199-
200-
renderable->SetMeshMaterialsCount(1);
194+
component->SetMeshMaterialsCount(1);
201195

202-
MeshMaterial* material = renderable->GetMeshMaterial();
196+
MeshMaterial* material = component->GetMeshMaterial();
203197
debug_assert(material);
204198

205199
material->mRenderStates.mIsDepthWriteEnabled = false;

src/TerrainTilesCursor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class TerrainTilesCursor: public cxx::noncopyable
2121

2222
private:
2323
void SetupCursorMesh();
24-
void SetupCursorMeshMaterial();
24+
void SetupCursorMeshMaterial(StaticMeshComponent* component);
2525

2626
private:
2727
GameObject* mMeshObject = nullptr;

0 commit comments

Comments
 (0)