TrinityCore
Loading...
Searching...
No Matches
IntermediateValues.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "IntermediateValues.h"
19#include "Log.h"
20#include "Memory.h"
21#include "StringFormat.h"
22
23namespace MMAP
24{
26 {
27 rcFreeCompactHeightfield(compactHeightfield);
28 rcFreeHeightField(heightfield);
29 rcFreeContourSet(contours);
30 rcFreePolyMesh(polyMesh);
31 rcFreePolyMeshDetail(polyMeshDetail);
32 }
33
34 void IntermediateValues::writeIV(boost::filesystem::path const& outputDirectory, std::string_view fileNameSuffix, uint32 mapID, uint32 tileX, uint32 tileY)
35 {
36 TC_LOG_INFO("maps.mmapgen.debug", "[Map {:04}] [{:02},{:02}]: Writing debug output intermediate values...", mapID, tileX, tileY);
37
38 auto debugWrite = [=, outputDirectory = outputDirectory.generic_string()](char const* extension, auto const* data)
39 {
40 std::string fileName = Trinity::StringFormat("{}/meshes/{:04}_{:02}_{:02}{}.{}", outputDirectory, mapID, tileX, tileY, fileNameSuffix, extension);
41 if (auto file = Trinity::make_unique_ptr_with_deleter<&::fclose>(fopen(fileName.c_str(), "wb")))
42 {
43 IntermediateValues::debugWrite(file.get(), data);
44 }
45 else
46 TC_LOG_ERROR("maps.mmapgen.debug", "{}: [{:04}-{:02},{:02}] Failed to open {} for writing!", strerror(errno), mapID, tileX, tileY, fileName);
47 };
48
49 if (heightfield)
53 if (contours)
54 debugWrite("cs", contours);
55 if (polyMesh)
56 debugWrite("pmesh", polyMesh);
58 debugWrite("dmesh", polyMeshDetail);
59 }
60
61 void IntermediateValues::debugWrite(FILE* file, rcHeightfield const* mesh)
62 {
63 if (!file || !mesh)
64 return;
65
66 fwrite(&(mesh->cs), sizeof(float), 1, file);
67 fwrite(&(mesh->ch), sizeof(float), 1, file);
68 fwrite(&(mesh->width), sizeof(int), 1, file);
69 fwrite(&(mesh->height), sizeof(int), 1, file);
70 fwrite(mesh->bmin, sizeof(float), 3, file);
71 fwrite(mesh->bmax, sizeof(float), 3, file);
72
73 for (int y = 0; y < mesh->height; ++y)
74 for (int x = 0; x < mesh->width; ++x)
75 {
76 rcSpan* span = mesh->spans[x+y*mesh->width];
77
78 // first, count the number of spans
79 int spanCount = 0;
80 while (span)
81 {
82 spanCount++;
83 span = span->next;
84 }
85
86 // write the span count
87 fwrite(&spanCount, sizeof(int), 1, file);
88
89 // write the spans
90 span = mesh->spans[x+y*mesh->width];
91 while (span)
92 {
93 fwrite(span, sizeof(rcSpan), 1, file);
94 span = span->next;
95 }
96 }
97 }
98
99 void IntermediateValues::debugWrite(FILE* file, rcCompactHeightfield const* chf)
100 {
101 if (!file | !chf)
102 return;
103
104 fwrite(&(chf->width), sizeof(chf->width), 1, file);
105 fwrite(&(chf->height), sizeof(chf->height), 1, file);
106 fwrite(&(chf->spanCount), sizeof(chf->spanCount), 1, file);
107
108 fwrite(&(chf->walkableHeight), sizeof(chf->walkableHeight), 1, file);
109 fwrite(&(chf->walkableClimb), sizeof(chf->walkableClimb), 1, file);
110
111 fwrite(&(chf->maxDistance), sizeof(chf->maxDistance), 1, file);
112 fwrite(&(chf->maxRegions), sizeof(chf->maxRegions), 1, file);
113
114 fwrite(chf->bmin, sizeof(chf->bmin), 1, file);
115 fwrite(chf->bmax, sizeof(chf->bmax), 1, file);
116
117 fwrite(&(chf->cs), sizeof(chf->cs), 1, file);
118 fwrite(&(chf->ch), sizeof(chf->ch), 1, file);
119
120 int tmp = 0;
121 if (chf->cells) tmp |= 1;
122 if (chf->spans) tmp |= 2;
123 if (chf->dist) tmp |= 4;
124 if (chf->areas) tmp |= 8;
125
126 fwrite(&tmp, sizeof(tmp), 1, file);
127
128 if (chf->cells)
129 fwrite(chf->cells, sizeof(rcCompactCell), chf->width*chf->height, file);
130 if (chf->spans)
131 fwrite(chf->spans, sizeof(rcCompactSpan), chf->spanCount, file);
132 if (chf->dist)
133 fwrite(chf->dist, sizeof(unsigned short), chf->spanCount, file);
134 if (chf->areas)
135 fwrite(chf->areas, sizeof(unsigned char), chf->spanCount, file);
136 }
137
138 void IntermediateValues::debugWrite(FILE* file, rcContourSet const* cs)
139 {
140 if (!file || !cs)
141 return;
142
143 fwrite(&(cs->cs), sizeof(float), 1, file);
144 fwrite(&(cs->ch), sizeof(float), 1, file);
145 fwrite(cs->bmin, sizeof(float), 3, file);
146 fwrite(cs->bmax, sizeof(float), 3, file);
147 fwrite(&(cs->nconts), sizeof(int), 1, file);
148 for (int i = 0; i < cs->nconts; ++i)
149 {
150 fwrite(&cs->conts[i].area, sizeof(unsigned char), 1, file);
151 fwrite(&cs->conts[i].reg, sizeof(unsigned short), 1, file);
152 fwrite(&cs->conts[i].nverts, sizeof(int), 1, file);
153 fwrite(cs->conts[i].verts, sizeof(int), cs->conts[i].nverts*4, file);
154 fwrite(&cs->conts[i].nrverts, sizeof(int), 1, file);
155 fwrite(cs->conts[i].rverts, sizeof(int), cs->conts[i].nrverts*4, file);
156 }
157 }
158
159 void IntermediateValues::debugWrite(FILE* file, rcPolyMesh const* mesh)
160 {
161 if (!file || !mesh)
162 return;
163
164 fwrite(&(mesh->cs), sizeof(float), 1, file);
165 fwrite(&(mesh->ch), sizeof(float), 1, file);
166 fwrite(&(mesh->nvp), sizeof(int), 1, file);
167 fwrite(mesh->bmin, sizeof(float), 3, file);
168 fwrite(mesh->bmax, sizeof(float), 3, file);
169 fwrite(&(mesh->nverts), sizeof(int), 1, file);
170 fwrite(mesh->verts, sizeof(unsigned short), mesh->nverts*3, file);
171 fwrite(&(mesh->npolys), sizeof(int), 1, file);
172 fwrite(mesh->polys, sizeof(unsigned short), mesh->npolys*mesh->nvp*2, file);
173 fwrite(mesh->flags, sizeof(unsigned short), mesh->npolys, file);
174 fwrite(mesh->areas, sizeof(unsigned char), mesh->npolys, file);
175 fwrite(mesh->regs, sizeof(unsigned short), mesh->npolys, file);
176 }
177
178 void IntermediateValues::debugWrite(FILE* file, rcPolyMeshDetail const* mesh)
179 {
180 if (!file || !mesh)
181 return;
182
183 fwrite(&(mesh->nverts), sizeof(int), 1, file);
184 fwrite(mesh->verts, sizeof(float), mesh->nverts*3, file);
185 fwrite(&(mesh->ntris), sizeof(int), 1, file);
186 fwrite(mesh->tris, sizeof(char), mesh->ntris*4, file);
187 fwrite(&(mesh->nmeshes), sizeof(int), 1, file);
188 fwrite(mesh->meshes, sizeof(int), mesh->nmeshes*4, file);
189 }
190
191 void IntermediateValues::generateObjFile(boost::filesystem::path const& outputDirectory, std::string_view fileNameSuffix, uint32 mapID, uint32 tileX, uint32 tileY, MeshData const& meshData)
192 {
193 std::string objFileName;
194 objFileName = Trinity::StringFormat("{}/meshes/map{:04}_{:02}_{:02}{}.obj", outputDirectory.generic_string(), mapID, tileX, tileY, fileNameSuffix);
195
196 auto objFile = Trinity::make_unique_ptr_with_deleter<&::fclose>(fopen(objFileName.c_str(), "wb"));
197 if (!objFile)
198 {
199 TC_LOG_ERROR("maps.mmapgen.debug", "{}: Failed to open {} for writing!", strerror(errno), objFileName);
200 return;
201 }
202
203 std::vector<float> allVerts;
204 std::vector<int> allTris;
205
206 allTris.insert(allTris.end(), meshData.liquidTris.begin(), meshData.liquidTris.end());
207 allVerts.insert(allVerts.end(), meshData.liquidVerts.begin(), meshData.liquidVerts.end());
208 TerrainBuilder::copyIndices(meshData.solidTris, allTris, allVerts.size() / 3);
209 allVerts.insert(allVerts.end(), meshData.solidVerts.begin(), meshData.solidVerts.end());
210
211 float* verts = allVerts.data();
212 int vertCount = allVerts.size() / 3;
213 int* tris = allTris.data();
214 int triCount = allTris.size() / 3;
215
216 for (std::size_t i = 0; i < allVerts.size() / 3; i++)
217 fprintf(objFile.get(), "v %f %f %f\n", verts[i * 3], verts[i * 3 + 1], verts[i * 3 + 2]);
218
219 for (std::size_t i = 0; i < allTris.size() / 3; i++)
220 fprintf(objFile.get(), "f %i %i %i\n", tris[i * 3] + 1, tris[i * 3 + 1] + 1, tris[i * 3 + 2] + 1);
221
222 TC_LOG_INFO("maps.mmapgen.debug", "[Map {:04}] [{:02},{:02}]: Writing debug output object file...", mapID, tileX, tileY);
223
224 objFileName = Trinity::StringFormat("{}/meshes/map{:04}.map", outputDirectory.generic_string(), mapID);
225
226 objFile.reset(fopen(objFileName.c_str(), "wb"));
227 if (!objFile)
228 {
229 TC_LOG_ERROR("maps.mmapgen.debug", "{}: Failed to open {} for writing!", strerror(errno), objFileName);
230 return;
231 }
232
233 char b = '\0';
234 fwrite(&b, sizeof(char), 1, objFile.get());
235
236 objFileName = Trinity::StringFormat("{}/meshes/map{:04}_{:02}_{:02}{}.mesh", outputDirectory.generic_string(), mapID, tileX, tileY, fileNameSuffix);
237 objFile.reset(fopen(objFileName.c_str(), "wb"));
238 if (!objFile)
239 {
240 TC_LOG_ERROR("maps.mmapgen.debug", "{}: Failed to open {} for writing!", strerror(errno), objFileName);
241 return;
242 }
243
244 fwrite(&vertCount, sizeof(int), 1, objFile.get());
245 fwrite(verts, sizeof(float), vertCount*3, objFile.get());
246 fflush(objFile.get());
247
248 fwrite(&triCount, sizeof(int), 1, objFile.get());
249 fwrite(tris, sizeof(int), triCount*3, objFile.get());
250 fflush(objFile.get());
251 }
252}
uint32_t uint32
Definition Define.h:154
#define TC_LOG_ERROR(filterType__, message__,...)
Definition Log.h:190
#define TC_LOG_INFO(filterType__, message__,...)
Definition Log.h:184
static void copyIndices(std::vector< VMAP::MeshTriangle > const &source, std::vector< int > &dest, int offset, bool flip)
std::string StringFormat(FormatString< Args... > fmt, Args &&... args) noexcept
Default TC string format function.
rcCompactHeightfield * compactHeightfield
static void debugWrite(FILE *file, rcHeightfield const *mesh)
rcPolyMeshDetail * polyMeshDetail
void generateObjFile(boost::filesystem::path const &outputDirectory, std::string_view fileNameSuffix, uint32 mapID, uint32 tileX, uint32 tileY, MeshData const &meshData)
void writeIV(boost::filesystem::path const &outputDirectory, std::string_view fileNameSuffix, uint32 mapID, uint32 tileX, uint32 tileY)
std::vector< float > liquidVerts
std::vector< float > solidVerts
std::vector< int > solidTris
std::vector< int > liquidTris