diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/tools/mmaps_generator/IntermediateValues.cpp | 22 | ||||
| -rw-r--r-- | src/tools/mmaps_generator/MapBuilder.cpp | 20 | ||||
| -rw-r--r-- | src/tools/mmaps_generator/TerrainBuilder.cpp | 371 | ||||
| -rw-r--r-- | src/tools/mmaps_generator/TerrainBuilder.h | 43 | ||||
| -rw-r--r-- | src/tools/mmaps_generator/TileBuilder.cpp | 37 |
5 files changed, 228 insertions, 265 deletions
diff --git a/src/tools/mmaps_generator/IntermediateValues.cpp b/src/tools/mmaps_generator/IntermediateValues.cpp index f71e36fec0c..4845ef32639 100644 --- a/src/tools/mmaps_generator/IntermediateValues.cpp +++ b/src/tools/mmaps_generator/IntermediateValues.cpp @@ -200,24 +200,24 @@ namespace MMAP return; } - G3D::Array<float> allVerts; - G3D::Array<int> allTris; + std::vector<float> allVerts; + std::vector<int> allTris; - allTris.append(meshData.liquidTris); - allVerts.append(meshData.liquidVerts); + allTris.insert(allTris.end(), meshData.liquidTris.begin(), meshData.liquidTris.end()); + allVerts.insert(allVerts.end(), meshData.liquidVerts.begin(), meshData.liquidVerts.end()); TerrainBuilder::copyIndices(meshData.solidTris, allTris, allVerts.size() / 3); - allVerts.append(meshData.solidVerts); + allVerts.insert(allVerts.end(), meshData.solidVerts.begin(), meshData.solidVerts.end()); - float* verts = allVerts.getCArray(); + float* verts = allVerts.data(); int vertCount = allVerts.size() / 3; - int* tris = allTris.getCArray(); + int* tris = allTris.data(); int triCount = allTris.size() / 3; - for (int i = 0; i < allVerts.size() / 3; i++) - fprintf(objFile.get(), "v %f %f %f\n", verts[i*3], verts[i*3 + 1], verts[i*3 + 2]); + for (std::size_t i = 0; i < allVerts.size() / 3; i++) + fprintf(objFile.get(), "v %f %f %f\n", verts[i * 3], verts[i * 3 + 1], verts[i * 3 + 2]); - for (int i = 0; i < allTris.size() / 3; i++) - fprintf(objFile.get(), "f %i %i %i\n", tris[i*3] + 1, tris[i*3 + 1] + 1, tris[i*3 + 2] + 1); + for (std::size_t i = 0; i < allTris.size() / 3; i++) + fprintf(objFile.get(), "f %i %i %i\n", tris[i * 3] + 1, tris[i * 3 + 1] + 1, tris[i * 3 + 2] + 1); TC_LOG_INFO("maps.mmapgen.debug", "[Map {:04}] [{:02},{:02}]: Writing debug output object file...", mapID, tileY, tileX); diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index f7743fcdf38..cf1fce6a335 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -310,26 +310,20 @@ namespace MMAP if (fread(&indicesCount, sizeof(uint32), 1, file.get()) != 1) return; - std::unique_ptr<float[]> verts = std::make_unique<float[]>(verticesCount); - if (fread(verts.get(), sizeof(float), verticesCount, file.get()) != verticesCount) - return; - - std::unique_ptr<int[]> inds = std::make_unique<int[]>(indicesCount); - if (fread(inds.get(), sizeof(int), indicesCount, file.get()) != indicesCount) - return; - MeshData data; - for (uint32 i = 0; i < verticesCount; ++i) - data.solidVerts.append(verts[i]); + data.solidVerts.resize(verticesCount); + if (fread(data.solidVerts.data(), sizeof(float), verticesCount, file.get()) != verticesCount) + return; - for (uint32 i = 0; i < indicesCount; ++i) - data.solidTris.append(inds[i]); + data.solidTris.resize(indicesCount); + if (fread(data.solidTris.data(), sizeof(int), indicesCount, file.get()) != indicesCount) + return; TerrainBuilder::cleanVertices(data.solidVerts, data.solidTris); // get bounds of current tile float bmin[3], bmax[3]; - TileBuilder::getTileBounds(tileX, tileY, data.solidVerts.getCArray(), data.solidVerts.size() / 3, bmin, bmax); + TileBuilder::getTileBounds(tileX, tileY, data.solidVerts.data(), data.solidVerts.size() / 3, bmin, bmax); // build navmesh tile MapTileBuilder tileBuilder(this, m_maxWalkableAngle, m_maxWalkableAngleNotSteep, diff --git a/src/tools/mmaps_generator/TerrainBuilder.cpp b/src/tools/mmaps_generator/TerrainBuilder.cpp index ede0c32441d..9a5d89b945b 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.cpp +++ b/src/tools/mmaps_generator/TerrainBuilder.cpp @@ -25,7 +25,7 @@ #include "StringFormat.h" #include "Util.h" #include "VMapManager.h" -#include <map> +#include <unordered_map> namespace MMAP { @@ -123,8 +123,8 @@ namespace MMAP uint8 holes[16][16][8] = { }; uint16 liquid_entry[16][16] = { }; map_liquidHeaderTypeFlags liquid_flags[16][16] = { }; - G3D::Array<int> ltriangles; - G3D::Array<int> ttriangles; + std::vector<int> ltriangles; + std::vector<int> ttriangles; // terrain data if (haveTerrain) @@ -188,38 +188,35 @@ namespace MMAP } int count = meshData.solidVerts.size() / 3; + meshData.solidVerts.resize(meshData.solidVerts.size() + (V9_SIZE_SQ + V8_SIZE_SQ) * 3); + float* solidVerts = meshData.solidVerts.data() + count * 3; + float xoffset = (float(tileX)-32)*GRID_SIZE; float yoffset = (float(tileY)-32)*GRID_SIZE; - float coord[3]; - for (int i = 0; i < V9_SIZE_SQ; ++i) { - getHeightCoord(i, GRID_V9, xoffset, yoffset, coord, V9); - meshData.solidVerts.append(coord[0]); - meshData.solidVerts.append(coord[2]); - meshData.solidVerts.append(coord[1]); + getHeightCoord(i, GRID_V9, xoffset, yoffset, solidVerts, V9); + solidVerts += 3; } for (int i = 0; i < V8_SIZE_SQ; ++i) { - getHeightCoord(i, GRID_V8, xoffset, yoffset, coord, V8); - meshData.solidVerts.append(coord[0]); - meshData.solidVerts.append(coord[2]); - meshData.solidVerts.append(coord[1]); + getHeightCoord(i, GRID_V8, xoffset, yoffset, solidVerts, V8); + solidVerts += 3; } - int indices[] = { 0, 0, 0 }; int loopStart = 0, loopEnd = 0, loopInc = 0; getLoopVars(portion, loopStart, loopEnd, loopInc); for (int i = loopStart; i < loopEnd; i+=loopInc) - for (int j = TOP; j <= BOTTOM; j+=1) - { - getHeightTriangle(i, Spot(j), indices); - ttriangles.append(indices[2] + count); - ttriangles.append(indices[1] + count); - ttriangles.append(indices[0] + count); - } + { + std::size_t trianglesOffset = ttriangles.size(); + ttriangles.resize(ttriangles.size() + 12); + getHeightTriangle(i, TOP, ttriangles.data() + trianglesOffset + 0, count); + getHeightTriangle(i, RIGHT, ttriangles.data() + trianglesOffset + 3, count); + getHeightTriangle(i, LEFT, ttriangles.data() + trianglesOffset + 6, count); + getHeightTriangle(i, BOTTOM, ttriangles.data() + trianglesOffset + 9, count); + } } // liquid data @@ -257,10 +254,11 @@ namespace MMAP } int count = meshData.liquidVerts.size() / 3; + meshData.liquidVerts.resize(meshData.liquidVerts.size() + V9_SIZE_SQ * 3); + float* liquidVerts = meshData.liquidVerts.data(); float xoffset = (float(tileX)-32)*GRID_SIZE; float yoffset = (float(tileY)-32)*GRID_SIZE; - float coord[3]; int row, col; // generate coordinates @@ -276,14 +274,13 @@ namespace MMAP col < lheader.offsetX || col >= lheader.offsetX + lheader.width) { // dummy vert using invalid height - meshData.liquidVerts.append((xoffset+col*GRID_PART_SIZE)*-1, INVALID_MAP_LIQ_HEIGHT, (yoffset+row*GRID_PART_SIZE)*-1); + liquidVerts[(count + i) * 3 + 0] = (xoffset + col * GRID_PART_SIZE) * -1; + liquidVerts[(count + i) * 3 + 1] = INVALID_MAP_LIQ_HEIGHT; + liquidVerts[(count + i) * 3 + 2] = (yoffset + row * GRID_PART_SIZE) * -1; continue; } - getLiquidCoord(i, j, xoffset, yoffset, coord, liquid_map.get()); - meshData.liquidVerts.append(coord[0]); - meshData.liquidVerts.append(coord[2]); - meshData.liquidVerts.append(coord[1]); + getLiquidCoord(i, j, xoffset, yoffset, &liquidVerts[(count + i) * 3], liquid_map.get()); j++; } } @@ -293,24 +290,22 @@ namespace MMAP { row = i / V9_SIZE; col = i % V9_SIZE; - meshData.liquidVerts.append((xoffset+col*GRID_PART_SIZE)*-1, lheader.liquidLevel, (yoffset+row*GRID_PART_SIZE)*-1); + liquidVerts[(count + i) * 3 + 0] = (xoffset + col * GRID_PART_SIZE) * -1; + liquidVerts[(count + i) * 3 + 1] = lheader.liquidLevel; + liquidVerts[(count + i) * 3 + 2] = (yoffset + row * GRID_PART_SIZE) * -1; } } - int indices[] = { 0, 0, 0 }; - int loopStart = 0, loopEnd = 0, loopInc = 0, triInc = BOTTOM-TOP; + int loopStart = 0, loopEnd = 0, loopInc = 0; getLoopVars(portion, loopStart, loopEnd, loopInc); // generate triangles for (int i = loopStart; i < loopEnd; i += loopInc) { - for (int j = TOP; j <= BOTTOM; j += triInc) - { - getHeightTriangle(i, Spot(j), indices, true); - ltriangles.append(indices[2] + count); - ltriangles.append(indices[1] + count); - ltriangles.append(indices[0] + count); - } + std::size_t trianglesOffset = ltriangles.size(); + ltriangles.resize(ltriangles.size() + 6); + getHeightTriangle(i, TOP, ltriangles.data() + trianglesOffset + 0, count, true); + getHeightTriangle(i, BOTTOM, ltriangles.data() + trianglesOffset + 3, count, true); } } @@ -319,11 +314,11 @@ namespace MMAP int loopStart = 0, loopEnd = 0, loopInc = 0, tTriCount = 4; bool useTerrain, useLiquid; - float* lverts = meshData.liquidVerts.getCArray(); - int* ltris = ltriangles.getCArray(); + float* lverts = meshData.liquidVerts.data(); + int* ltris = ltriangles.data(); - float* tverts = meshData.solidVerts.getCArray(); - int* ttris = ttriangles.getCArray(); + float* tverts = meshData.solidVerts.data(); + int* ttris = ttriangles.data(); if ((ltriangles.size() + ttriangles.size()) == 0) return false; @@ -331,7 +326,7 @@ namespace MMAP // make a copy of liquid vertices // used to pad right-bottom frame due to lost vertex data at extraction std::unique_ptr<float[]> lverts_copy; - if (meshData.liquidVerts.size()) + if (!meshData.liquidVerts.empty()) { lverts_copy = std::make_unique<float[]>(meshData.liquidVerts.size()); memcpy(lverts_copy.get(), lverts, sizeof(float)* meshData.liquidVerts.size()); @@ -349,7 +344,7 @@ namespace MMAP uint8 navLiquidType = NAV_AREA_EMPTY; // if there is no liquid, don't use liquid - if (!meshData.liquidVerts.size() || !ltriangles.size()) + if (meshData.liquidVerts.empty() || ltriangles.empty()) useLiquid = false; else { @@ -369,7 +364,7 @@ namespace MMAP } // if there is no terrain, don't use terrain - if (!ttriangles.size()) + if (ttriangles.empty()) useTerrain = false; // while extracting ADT data we are losing right-bottom vertices @@ -448,14 +443,12 @@ namespace MMAP // store the result if (useLiquid) { - meshData.liquidType.append(navLiquidType); - for (int k = 0; k < 3; ++k) - meshData.liquidTris.append(ltris[k]); + meshData.liquidTris.insert(meshData.liquidTris.end(), <ris[0], <ris[3]); + meshData.liquidType.push_back(navLiquidType); } if (useTerrain) - for (int k = 0; k < 3*tTriCount/2; ++k) - meshData.solidTris.append(ttris[k]); + meshData.solidTris.insert(meshData.solidTris.end(), &ttris[0], &ttris[3 * tTriCount / 2]); // advance to next set of triangles ltris += 3; @@ -463,88 +456,88 @@ namespace MMAP } } - return meshData.solidTris.size() || meshData.liquidTris.size(); + return !meshData.solidTris.empty() || !meshData.liquidTris.empty(); } /**************************************************************************/ - void TerrainBuilder::getHeightCoord(int index, Grid grid, float xOffset, float yOffset, float* coord, float* v) + inline void TerrainBuilder::getHeightCoord(int index, Grid grid, float xOffset, float yOffset, float* coord, float* v) { // wow coords: x, y, height // coord is mirroed about the horizontal axes switch (grid) { case GRID_V9: - coord[0] = (xOffset + index%(V9_SIZE)*GRID_PART_SIZE) * -1.f; - coord[1] = (yOffset + (int)(index/(V9_SIZE))*GRID_PART_SIZE) * -1.f; - coord[2] = v[index]; + coord[0] = (xOffset + (int)(index % V9_SIZE) * GRID_PART_SIZE) * -1.f; + coord[1] = v[index]; + coord[2] = (yOffset + (int)(index / (V9_SIZE)) * GRID_PART_SIZE) * -1.f; break; case GRID_V8: - coord[0] = (xOffset + index%(V8_SIZE)*GRID_PART_SIZE + GRID_PART_SIZE/2.f) * -1.f; - coord[1] = (yOffset + (int)(index/(V8_SIZE))*GRID_PART_SIZE + GRID_PART_SIZE/2.f) * -1.f; - coord[2] = v[index]; + coord[0] = (xOffset + (int)(index % V8_SIZE) * GRID_PART_SIZE + GRID_PART_SIZE / 2.f) * -1.f; + coord[1] = v[index]; + coord[2] = (yOffset + (int)(index / (V8_SIZE)) * GRID_PART_SIZE + GRID_PART_SIZE / 2.f) * -1.f; break; } } /**************************************************************************/ - void TerrainBuilder::getHeightTriangle(int square, Spot triangle, int* indices, bool liquid/* = false*/) + inline void TerrainBuilder::getHeightTriangle(int square, Spot triangle, int* indices, int offset, bool liquid/* = false*/) { int rowOffset = square/V8_SIZE; if (!liquid) switch (triangle) { case TOP: - indices[0] = square+rowOffset; // 0-----1 .... 128 - indices[1] = square+1+rowOffset; // |\ T /| - indices[2] = (V9_SIZE_SQ)+square; // | \ / | - break; // |L 0 R| .. 127 - case LEFT: // | / \ | - indices[0] = square+rowOffset; // |/ B \| - indices[1] = (V9_SIZE_SQ)+square; // 129---130 ... 386 - indices[2] = square+V9_SIZE+rowOffset; // |\ /| - break; // | \ / | - case RIGHT: // | 128 | .. 255 - indices[0] = square+1+rowOffset; // | / \ | - indices[1] = square+V9_SIZE+1+rowOffset; // |/ \| - indices[2] = (V9_SIZE_SQ)+square; // 258---259 ... 515 + indices[0] = V9_SIZE_SQ + square + offset; // 0-----1 .... 128 + indices[1] = square + 1 + rowOffset + offset; // |\ T /| + indices[2] = square + rowOffset + offset; // | \ / | + break; // |L 0 R| .. 127 + case LEFT: // | / \ | + indices[0] = square + V9_SIZE + rowOffset + offset; // |/ B \| + indices[1] = V9_SIZE_SQ + square + offset; // 129---130 ... 386 + indices[2] = square + rowOffset + offset; // |\ /| + break; // | \ / | + case RIGHT: // | 128 | .. 255 + indices[0] = V9_SIZE_SQ + square + offset; // | / \ | + indices[1] = square + V9_SIZE + 1 + rowOffset + offset; // |/ \| + indices[2] = square + 1 + rowOffset + offset; // 258---259 ... 515 break; case BOTTOM: - indices[0] = (V9_SIZE_SQ)+square; - indices[1] = square+V9_SIZE+1+rowOffset; - indices[2] = square+V9_SIZE+rowOffset; + indices[0] = square + V9_SIZE + rowOffset + offset; + indices[1] = square + V9_SIZE + 1 + rowOffset + offset; + indices[2] = V9_SIZE_SQ + square + offset; break; default: break; } else switch (triangle) - { // 0-----1 .... 128 - case TOP: // |\ | - indices[0] = square+rowOffset; // | \ T | - indices[1] = square+1+rowOffset; // | \ | - indices[2] = square+V9_SIZE+1+rowOffset; // | B \ | - break; // | \| - case BOTTOM: // 129---130 ... 386 - indices[0] = square+rowOffset; // |\ | - indices[1] = square+V9_SIZE+1+rowOffset; // | \ | - indices[2] = square+V9_SIZE+rowOffset; // | \ | - break; // | \ | - default: break; // | \| - } // 258---259 ... 515 + { // 0-----1 .... 128 + case TOP: // |\ | + indices[0] = square + V9_SIZE + 1 + rowOffset + offset; // | \ T | + indices[1] = square + 1 + rowOffset + offset; // | \ | + indices[2] = square + rowOffset + offset; // | B \ | + break; // | \| + case BOTTOM: // 129---130 ... 386 + indices[0] = square + V9_SIZE + rowOffset + offset; // |\ | + indices[1] = square + V9_SIZE + 1 + rowOffset + offset; // | \ | + indices[2] = square + rowOffset + offset; // | \ | + break; // | \ | + default: break; // | \| + } // 258---259 ... 515 } /**************************************************************************/ - void TerrainBuilder::getLiquidCoord(int index, int index2, float xOffset, float yOffset, float* coord, float* v) + inline void TerrainBuilder::getLiquidCoord(int index, int index2, float xOffset, float yOffset, float* coord, float* v) { // wow coords: x, y, height // coord is mirroed about the horizontal axes - coord[0] = (xOffset + index%(V9_SIZE)*GRID_PART_SIZE) * -1.f; - coord[1] = (yOffset + (int)(index/(V9_SIZE))*GRID_PART_SIZE) * -1.f; - coord[2] = v[index2]; + coord[0] = (xOffset + (int)(index % V9_SIZE) * GRID_PART_SIZE) * -1.f; + coord[1] = v[index2]; + coord[2] = (yOffset + (int)(index / (V9_SIZE)) * GRID_PART_SIZE) * -1.f; } /**************************************************************************/ - bool TerrainBuilder::isHole(int square, uint8 const (&holes)[16][16][8]) + inline bool TerrainBuilder::isHole(int square, uint8 const (&holes)[16][16][8]) { int row = square / 128; int col = square % 128; @@ -557,7 +550,7 @@ namespace MMAP } /**************************************************************************/ - map_liquidHeaderTypeFlags TerrainBuilder::getLiquidType(int square, map_liquidHeaderTypeFlags const (&liquid_type)[16][16]) + inline map_liquidHeaderTypeFlags TerrainBuilder::getLiquidType(int square, map_liquidHeaderTypeFlags const (&liquid_type)[16][16]) { int row = square / 128; int col = square % 128; @@ -602,36 +595,27 @@ namespace MMAP // transform data float scale = instance.iScale; - G3D::Matrix3 rotation = instance.GetInvRot(); + G3D::Matrix3 const& rotation = instance.GetInvRot(); G3D::Vector3 position = instance.iPos; position.x -= 32 * GRID_SIZE; position.y -= 32 * GRID_SIZE; for (std::vector<VMAP::GroupModel>::const_iterator it = groupModels.begin(); it != groupModels.end(); ++it) { - std::vector<G3D::Vector3> const& tempVertices = it->GetVertices(); - std::vector<G3D::Vector3> transformedVertices; - std::vector<VMAP::MeshTriangle> const& tempTriangles = it->GetTriangles(); - VMAP::WmoLiquid const* liquid = it->GetLiquid(); - // first handle collision mesh - transform(tempVertices, transformedVertices, scale, rotation, position); - int offset = meshData.solidVerts.size() / 3; - - copyVertices(transformedVertices, meshData.solidVerts); - copyIndices(tempTriangles, meshData.solidTris, offset, isM2); + transformVertices(it->GetVertices(), meshData.solidVerts, scale, rotation, position); + copyIndices(it->GetTriangles(), meshData.solidTris, offset, isM2); // now handle liquid data + VMAP::WmoLiquid const* liquid = it->GetLiquid(); if (liquid && liquid->GetFlagsStorage()) { - std::vector<G3D::Vector3> liqVerts; - std::vector<int> liqTris; - uint32 tilesX, tilesY, vertsX, vertsY; + uint32 tilesX, tilesY; G3D::Vector3 corner; liquid->getPosInfo(tilesX, tilesY, corner); - vertsX = tilesX + 1; - vertsY = tilesY + 1; + uint32 vertsX = tilesX + 1; + uint32 vertsY = tilesY + 1; uint8 const* flags = liquid->GetFlagsStorage(); float const* data = liquid->GetHeightStorage(); uint8 type = NAV_AREA_EMPTY; @@ -649,54 +633,56 @@ namespace MMAP // tile = x*tilesY+y // flag = y*tilesY+x - G3D::Vector3 vert; + uint32 liqOffset = meshData.liquidVerts.size() / 3; + meshData.liquidVerts.resize(meshData.liquidVerts.size() + vertsX * vertsY * 3); + float* liquidVerts = meshData.liquidVerts.data(); for (uint32 x = 0; x < vertsX; ++x) { for (uint32 y = 0; y < vertsY; ++y) { - vert = G3D::Vector3(corner.x + x * GRID_PART_SIZE, corner.y + y * GRID_PART_SIZE, data[y * vertsX + x]); + G3D::Vector3 vert = G3D::Vector3(corner.x + x * GRID_PART_SIZE, corner.y + y * GRID_PART_SIZE, data[y * vertsX + x]); vert = vert * rotation * scale + position; vert.x *= -1.f; vert.y *= -1.f; - liqVerts.push_back(vert); + liquidVerts[(liqOffset + x * vertsY + y) * 3 + 0] = vert.y; + liquidVerts[(liqOffset + x * vertsY + y) * 3 + 1] = vert.z; + liquidVerts[(liqOffset + x * vertsY + y) * 3 + 2] = vert.x; } } - int idx1, idx2, idx3, idx4; - uint32 square; + std::size_t liquidSquares = 0; for (uint32 x = 0; x < tilesX; ++x) { for (uint32 y = 0; y < tilesY; ++y) { if ((flags[x + y * tilesX] & 0x0f) != 0x0f) { - square = x * tilesY + y; - idx1 = square + x; - idx2 = square + 1 + x; - idx3 = square + tilesY + 1 + 1 + x; - idx4 = square + tilesY + 1 + x; + uint32 square = x * tilesY + y; + int idx1 = square + x; + int idx2 = square + 1 + x; + int idx3 = square + tilesY + 1 + 1 + x; + int idx4 = square + tilesY + 1 + x; + + std::size_t liquidTriOffset = meshData.liquidTris.size(); + meshData.liquidTris.resize(liquidTriOffset + 6); + int* liquidTris = meshData.liquidTris.data() + liquidTriOffset; // top triangle - liqTris.push_back(idx3); - liqTris.push_back(idx2); - liqTris.push_back(idx1); + liquidTris[0] = idx2 + liqOffset; + liquidTris[1] = idx1 + liqOffset; + liquidTris[2] = idx3 + liqOffset; + // bottom triangle - liqTris.push_back(idx4); - liqTris.push_back(idx3); - liqTris.push_back(idx1); + liquidTris[3] = idx3 + liqOffset; + liquidTris[4] = idx1 + liqOffset; + liquidTris[5] = idx4 + liqOffset; + + ++liquidSquares; } } } - uint32 liqOffset = meshData.liquidVerts.size() / 3; - for (uint32 i = 0; i < liqVerts.size(); ++i) - meshData.liquidVerts.append(liqVerts[i].y, liqVerts[i].z, liqVerts[i].x); - - for (uint32 i = 0; i < liqTris.size() / 3; ++i) - { - meshData.liquidTris.append(liqTris[i * 3 + 1] + liqOffset, liqTris[i * 3 + 2] + liqOffset, liqTris[i * 3] + liqOffset); - meshData.liquidType.append(type); - } + meshData.liquidType.resize(meshData.liquidType.size() + liquidSquares * 2, type); } } } @@ -705,105 +691,90 @@ namespace MMAP } /**************************************************************************/ - void TerrainBuilder::transform(std::vector<G3D::Vector3> const& source, std::vector<G3D::Vector3>& transformedVertices, float scale, G3D::Matrix3 const& rotation, G3D::Vector3 const& position) + void TerrainBuilder::transformVertices(std::vector<G3D::Vector3> const& source, std::vector<float>& dest, float scale, G3D::Matrix3 const& rotation, G3D::Vector3 const& position) { - transformedVertices.reserve(transformedVertices.size() + source.size()); - for (G3D::Vector3 const& vertex : source) + std::size_t offset = dest.size(); + dest.resize(dest.size() + source.size() * 3); + float* d = dest.data(); + for (std::size_t i = 0; i < source.size(); ++i) { // apply tranform, then mirror along the horizontal axes - G3D::Vector3 v(vertex * rotation * scale + position); + G3D::Vector3 v(source[i] * rotation * scale + position); v.x *= -1.f; v.y *= -1.f; - transformedVertices.push_back(v); - } - } - - /**************************************************************************/ - void TerrainBuilder::copyVertices(std::vector<G3D::Vector3> const& source, G3D::Array<float>& dest) - { - dest.reserve(dest.size() + source.size() * 3); - for (G3D::Vector3 const& vertex : source) - { - dest.push_back(vertex.y); - dest.push_back(vertex.z); - dest.push_back(vertex.x); + d[offset + i * 3 + 0] = v.y; + d[offset + i * 3 + 1] = v.z; + d[offset + i * 3 + 2] = v.x; } } /**************************************************************************/ - void TerrainBuilder::copyIndices(std::vector<VMAP::MeshTriangle> const& source, G3D::Array<int>& dest, int offset, bool flip) + void TerrainBuilder::copyIndices(std::vector<VMAP::MeshTriangle> const& source, std::vector<int>& dest, int offset, bool flip) { - dest.reserve(dest.size() + source.size() * 3); + std::size_t destOffset = dest.size(); + dest.resize(dest.size() + source.size() * 3); + int* d = dest.data(); if (flip) { for (VMAP::MeshTriangle const& triangle : source) { - dest.push_back(triangle.idx2 + offset); - dest.push_back(triangle.idx1 + offset); - dest.push_back(triangle.idx0 + offset); + d[destOffset++] = triangle.idx2 + offset; + d[destOffset++] = triangle.idx1 + offset; + d[destOffset++] = triangle.idx0 + offset; } } else { - for (VMAP::MeshTriangle const& triangle : source) - { - dest.push_back(triangle.idx0 + offset); - dest.push_back(triangle.idx1 + offset); - dest.push_back(triangle.idx2 + offset); - } + static_assert(sizeof(VMAP::MeshTriangle) == 3 * sizeof(uint32)); + std::ranges::transform(reinterpret_cast<uint32 const*>(source.data()), reinterpret_cast<uint32 const*>(source.data() + source.size()), + dest.data() + destOffset, [&](int src) { return src + offset; }); } } /**************************************************************************/ - void TerrainBuilder::copyIndices(G3D::Array<int> const& source, G3D::Array<int>& dest, int offset) + void TerrainBuilder::copyIndices(std::vector<int> const& source, std::vector<int>& dest, int offset) { - int const* src = source.getCArray(); - dest.reserve(dest.size() + source.size()); - for (int32 i = 0; i < source.size(); ++i) - dest.append(src[i] + offset); + std::size_t destOffset = dest.size(); + dest.resize(destOffset + source.size()); + std::ranges::transform(source, dest.data() + destOffset, [&](int src) { return src + offset; }); } /**************************************************************************/ - void TerrainBuilder::cleanVertices(G3D::Array<float>& verts, G3D::Array<int>& tris) + void TerrainBuilder::cleanVertices(std::vector<float>& verts, std::vector<int>& tris) { - std::map<int, int> vertMap; + std::unordered_map<int, int> vertMap; + vertMap.reserve(tris.size()); - int* t = tris.getCArray(); - float* v = verts.getCArray(); + int* t = tris.data(); + float* v = verts.data(); - G3D::Array<float> cleanVerts; - int index, count = 0; + std::vector<float> cleanVerts; + cleanVerts.reserve(verts.size()); + int count = 0; // collect all the vertex indices from triangle - for (int i = 0; i < tris.size(); ++i) + for (std::size_t i = 0; i < tris.size(); ++i) { - if (vertMap.find(t[i]) != vertMap.end()) + auto [vertItr, isNew] = vertMap.try_emplace(t[i], count); + if (!isNew) continue; - std::pair<int, int> val; - val.first = t[i]; - index = val.first; - val.second = count; + std::ptrdiff_t index = t[i]; - vertMap.insert(val); - cleanVerts.append(v[index * 3], v[index * 3 + 1], v[index * 3 + 2]); + cleanVerts.insert(cleanVerts.end(), &v[index * 3], &v[index * 3 + 3]); count++; } - verts.fastClear(); - verts.append(cleanVerts); - cleanVerts.clear(); + verts = std::move(cleanVerts); // update triangles to use new indices - for (int i = 0; i < tris.size(); ++i) + for (std::size_t i = 0; i < tris.size(); ++i) { - std::map<int, int>::iterator it; - if ((it = vertMap.find(t[i])) == vertMap.end()) + auto it = vertMap.find(t[i]); + if (it == vertMap.end()) continue; - t[i] = (*it).second; + t[i] = it->second; } - - vertMap.clear(); } /**************************************************************************/ @@ -814,19 +785,19 @@ namespace MMAP if (mapID != offMeshConnection.MapId || tileX != offMeshConnection.TileX || tileY != offMeshConnection.TileY) continue; - meshData.offMeshConnections.append(offMeshConnection.From[1]); - meshData.offMeshConnections.append(offMeshConnection.From[2]); - meshData.offMeshConnections.append(offMeshConnection.From[0]); + meshData.offMeshConnections.push_back(offMeshConnection.From[1]); + meshData.offMeshConnections.push_back(offMeshConnection.From[2]); + meshData.offMeshConnections.push_back(offMeshConnection.From[0]); - meshData.offMeshConnections.append(offMeshConnection.To[1]); - meshData.offMeshConnections.append(offMeshConnection.To[2]); - meshData.offMeshConnections.append(offMeshConnection.To[0]); + meshData.offMeshConnections.push_back(offMeshConnection.To[1]); + meshData.offMeshConnections.push_back(offMeshConnection.To[2]); + meshData.offMeshConnections.push_back(offMeshConnection.To[0]); - meshData.offMeshConnectionDirs.append(offMeshConnection.Bidirectional ? 1 : 0); - meshData.offMeshConnectionRads.append(offMeshConnection.Radius); // agent size equivalent + meshData.offMeshConnectionDirs.push_back(offMeshConnection.Bidirectional ? 1 : 0); + meshData.offMeshConnectionRads.push_back(offMeshConnection.Radius); // agent size equivalent // can be used same way as polygon flags - meshData.offMeshConnectionsAreas.append(offMeshConnection.AreaId); - meshData.offMeshConnectionsFlags.append(offMeshConnection.Flags); + meshData.offMeshConnectionsAreas.push_back(offMeshConnection.AreaId); + meshData.offMeshConnectionsFlags.push_back(offMeshConnection.Flags); } } } diff --git a/src/tools/mmaps_generator/TerrainBuilder.h b/src/tools/mmaps_generator/TerrainBuilder.h index 7a7cc6ba918..c1c01e2d0db 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.h +++ b/src/tools/mmaps_generator/TerrainBuilder.h @@ -19,8 +19,6 @@ #define _MMAP_TERRAIN_BUILDER_H #include "WorldModel.h" - -#include <G3D/Array.h> #include <G3D/Vector3.h> namespace VMAP @@ -77,19 +75,19 @@ namespace MMAP struct MeshData { - G3D::Array<float> solidVerts; - G3D::Array<int> solidTris; + std::vector<float> solidVerts; + std::vector<int> solidTris; - G3D::Array<float> liquidVerts; - G3D::Array<int> liquidTris; - G3D::Array<uint8> liquidType; + std::vector<float> liquidVerts; + std::vector<int> liquidTris; + std::vector<uint8> liquidType; // offmesh connection data - G3D::Array<float> offMeshConnections; // [p0y,p0z,p0x,p1y,p1z,p1x] - per connection - G3D::Array<float> offMeshConnectionRads; - G3D::Array<unsigned char> offMeshConnectionDirs; - G3D::Array<unsigned char> offMeshConnectionsAreas; - G3D::Array<unsigned short> offMeshConnectionsFlags; + std::vector<float> offMeshConnections; // [p0y,p0z,p0x,p1y,p1z,p1x] - per connection + std::vector<float> offMeshConnectionRads; + std::vector<unsigned char> offMeshConnectionDirs; + std::vector<unsigned char> offMeshConnectionsAreas; + std::vector<unsigned short> offMeshConnectionsFlags; }; class TerrainBuilder @@ -104,36 +102,35 @@ namespace MMAP bool usesLiquids() const { return !m_skipLiquid; } // vert and triangle methods - static void transform(std::vector<G3D::Vector3> const& source, std::vector<G3D::Vector3>& transformed, + static void transformVertices(std::vector<G3D::Vector3> const& source, std::vector<float>& dest, float scale, G3D::Matrix3 const& rotation, G3D::Vector3 const& position); - static void copyVertices(std::vector<G3D::Vector3> const& source, G3D::Array<float>& dest); - static void copyIndices(std::vector<VMAP::MeshTriangle> const& source, G3D::Array<int>& dest, int offset, bool flip); - static void copyIndices(G3D::Array<int> const& source, G3D::Array<int>& dest, int offset); - static void cleanVertices(G3D::Array<float>& verts, G3D::Array<int>& tris); + static void copyIndices(std::vector<VMAP::MeshTriangle> const& source, std::vector<int>& dest, int offset, bool flip); + static void copyIndices(std::vector<int> const& source, std::vector<int>& dest, int offset); + static void cleanVertices(std::vector<float>& verts, std::vector<int>& tris); private: /// Loads a portion of a map's terrain bool loadMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData& meshData, VMAP::VMapManager* vmapManager, Spot portion); /// Sets loop variables for selecting only certain parts of a map's terrain - void getLoopVars(Spot portion, int& loopStart, int& loopEnd, int& loopInc); + static void getLoopVars(Spot portion, int& loopStart, int& loopEnd, int& loopInc); /// Controls whether liquids are loaded bool m_skipLiquid; /// Get the vector coordinate for a specific position - void getHeightCoord(int index, Grid grid, float xOffset, float yOffset, float* coord, float* v); + static void getHeightCoord(int index, Grid grid, float xOffset, float yOffset, float* coord, float* v); /// Get the triangle's vector indices for a specific position - void getHeightTriangle(int square, Spot triangle, int* indices, bool liquid = false); + static void getHeightTriangle(int square, Spot triangle, int* indices, int offset, bool liquid = false); /// Determines if the specific position's triangles should be rendered - bool isHole(int square, uint8 const (&holes)[16][16][8]); + static bool isHole(int square, uint8 const (&holes)[16][16][8]); /// Get the liquid vector coordinate for a specific position - void getLiquidCoord(int index, int index2, float xOffset, float yOffset, float* coord, float* v); + static void getLiquidCoord(int index, int index2, float xOffset, float yOffset, float* coord, float* v); /// Get the liquid type for a specific position - map_liquidHeaderTypeFlags getLiquidType(int square, map_liquidHeaderTypeFlags const (&liquid_type)[16][16]); + static map_liquidHeaderTypeFlags getLiquidType(int square, map_liquidHeaderTypeFlags const (&liquid_type)[16][16]); }; } diff --git a/src/tools/mmaps_generator/TileBuilder.cpp b/src/tools/mmaps_generator/TileBuilder.cpp index 6cbf3eef99a..815904788ec 100644 --- a/src/tools/mmaps_generator/TileBuilder.cpp +++ b/src/tools/mmaps_generator/TileBuilder.cpp @@ -105,7 +105,7 @@ namespace MMAP m_terrainBuilder.loadVMap(mapID, tileY, tileX, meshData, vmapManager.get()); // if there is no data, give up now - if (!meshData.solidVerts.size() && !meshData.liquidVerts.size()) + if (meshData.solidVerts.empty() && meshData.liquidVerts.empty()) { OnTileDone(); return; @@ -115,20 +115,21 @@ namespace MMAP TerrainBuilder::cleanVertices(meshData.solidVerts, meshData.solidTris); TerrainBuilder::cleanVertices(meshData.liquidVerts, meshData.liquidTris); - // gather all mesh data for final data check, and bounds calculation - G3D::Array<float> allVerts; - allVerts.append(meshData.liquidVerts); - allVerts.append(meshData.solidVerts); - - if (!allVerts.size()) + if (meshData.liquidVerts.empty() && meshData.solidVerts.empty()) { OnTileDone(); return; } + // gather all mesh data for final data check, and bounds calculation + std::vector<float> allVerts(meshData.liquidVerts.size() + meshData.solidVerts.size()); + auto allVertsOutput = allVerts.begin(); + allVertsOutput = std::ranges::copy(meshData.liquidVerts, allVertsOutput).out; + allVertsOutput = std::ranges::copy(meshData.solidVerts, allVertsOutput).out; + // get bounds of current tile float bmin[3], bmax[3]; - getTileBounds(tileX, tileY, allVerts.getCArray(), allVerts.size() / 3, bmin, bmax); + getTileBounds(tileX, tileY, allVerts.data(), allVerts.size() / 3, bmin, bmax); if (m_offMeshConnections) m_terrainBuilder.loadOffMeshConnections(mapID, tileX, tileY, meshData, *m_offMeshConnections); @@ -150,16 +151,16 @@ namespace MMAP IntermediateValues iv; - float* tVerts = meshData.solidVerts.getCArray(); + float* tVerts = meshData.solidVerts.data(); int tVertCount = meshData.solidVerts.size() / 3; - int* tTris = meshData.solidTris.getCArray(); + int* tTris = meshData.solidTris.data(); int tTriCount = meshData.solidTris.size() / 3; - float* lVerts = meshData.liquidVerts.getCArray(); + float* lVerts = meshData.liquidVerts.data(); int lVertCount = meshData.liquidVerts.size() / 3; - int* lTris = meshData.liquidTris.getCArray(); + int* lTris = meshData.liquidTris.data(); int lTriCount = meshData.liquidTris.size() / 3; - uint8* lTriFlags = meshData.liquidType.getCArray(); + uint8* lTriFlags = meshData.liquidType.data(); const TileConfig tileConfig = TileConfig(m_bigBaseUnit); int TILES_PER_MAP = tileConfig.TILES_PER_MAP; @@ -348,12 +349,12 @@ namespace MMAP params.detailTris = iv.polyMeshDetail->tris; params.detailTriCount = iv.polyMeshDetail->ntris; - params.offMeshConVerts = meshData.offMeshConnections.getCArray(); + params.offMeshConVerts = meshData.offMeshConnections.data(); params.offMeshConCount = meshData.offMeshConnections.size() / 6; - params.offMeshConRad = meshData.offMeshConnectionRads.getCArray(); - params.offMeshConDir = meshData.offMeshConnectionDirs.getCArray(); - params.offMeshConAreas = meshData.offMeshConnectionsAreas.getCArray(); - params.offMeshConFlags = meshData.offMeshConnectionsFlags.getCArray(); + params.offMeshConRad = meshData.offMeshConnectionRads.data(); + params.offMeshConDir = meshData.offMeshConnectionDirs.data(); + params.offMeshConAreas = meshData.offMeshConnectionsAreas.data(); + params.offMeshConFlags = meshData.offMeshConnectionsFlags.data(); params.walkableHeight = BASE_UNIT_DIM * config.walkableHeight; // agent height params.walkableRadius = BASE_UNIT_DIM * config.walkableRadius; // agent radius |
