/** * MaNGOS is a full featured server for World of Warcraft, supporting * the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8 * * Copyright (C) 2005-2020 MaNGOS * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * World of Warcraft, and all World of Warcraft or Warcraft art, images, * and lore are copyrighted by Blizzard Entertainment, Inc. */ #include "IntermediateValues.h" namespace MMAP { IntermediateValues::~IntermediateValues() { rcFreeCompactHeightfield(compactHeightfield); rcFreeHeightField(heightfield); rcFreeContourSet(contours); rcFreePolyMesh(polyMesh); rcFreePolyMeshDetail(polyMeshDetail); } void IntermediateValues::writeIV(int mapID, int tileX, int tileY) { char fileName[255]; char tileString[25]; sprintf(tileString, "[%02u,%02u]: ", tileX, tileY); printf("%sWriting debug output... \r", tileString); string name("meshes/%03u%02i%02i."); #define DEBUG_WRITE(fileExtension,data) \ do { \ sprintf(fileName, (name + fileExtension).c_str(), mapID, tileY, tileX); \ FILE* file = fopen(fileName, "wb"); \ if (!file) \ { \ char message[1024]; \ sprintf(message, "%sFailed to open %s for writing!\n", tileString, fileName); \ perror(message); \ } \ else \ debugWrite(file, data); \ if(file) fclose(file); \ printf("%sWriting debug output... \r", tileString); \ } while (false) if (heightfield) { DEBUG_WRITE("hf", heightfield); } if (compactHeightfield) { DEBUG_WRITE("chf", compactHeightfield); } if (contours) { DEBUG_WRITE("cs", contours); } if (polyMesh) { DEBUG_WRITE("pmesh", polyMesh); } if (polyMeshDetail) { DEBUG_WRITE("dmesh", polyMeshDetail); } #undef DEBUG_WRITE } void IntermediateValues::debugWrite(FILE* file, const rcHeightfield* mesh) { if (!file || !mesh) { return; } fwrite(&(mesh->cs), sizeof(float), 1, file); fwrite(&(mesh->ch), sizeof(float), 1, file); fwrite(&(mesh->width), sizeof(int), 1, file); fwrite(&(mesh->height), sizeof(int), 1, file); fwrite(mesh->bmin, sizeof(float), 3, file); fwrite(mesh->bmax, sizeof(float), 3, file); for (int y = 0; y < mesh->height; ++y) for (int x = 0; x < mesh->width; ++x) { rcSpan* span = mesh->spans[x + y * mesh->width]; // first, count the number of spans int spanCount = 0; while (span) { spanCount++; span = span->next; } // write the span count fwrite(&spanCount, sizeof(int), 1, file); // write the spans span = mesh->spans[x + y * mesh->width]; while (span) { fwrite(span, sizeof(rcSpan), 1, file); span = span->next; } } } void IntermediateValues::debugWrite(FILE* file, const rcCompactHeightfield* chf) { if (!file | !chf) { return; } fwrite(&(chf->width), sizeof(chf->width), 1, file); fwrite(&(chf->height), sizeof(chf->height), 1, file); fwrite(&(chf->spanCount), sizeof(chf->spanCount), 1, file); fwrite(&(chf->walkableHeight), sizeof(chf->walkableHeight), 1, file); fwrite(&(chf->walkableClimb), sizeof(chf->walkableClimb), 1, file); fwrite(&(chf->maxDistance), sizeof(chf->maxDistance), 1, file); fwrite(&(chf->maxRegions), sizeof(chf->maxRegions), 1, file); fwrite(chf->bmin, sizeof(chf->bmin), 1, file); fwrite(chf->bmax, sizeof(chf->bmax), 1, file); fwrite(&(chf->cs), sizeof(chf->cs), 1, file); fwrite(&(chf->ch), sizeof(chf->ch), 1, file); int tmp = 0; if (chf->cells) { tmp |= 1; } if (chf->spans) { tmp |= 2; } if (chf->dist) { tmp |= 4; } if (chf->areas) { tmp |= 8; } fwrite(&tmp, sizeof(tmp), 1, file); if (chf->cells) { fwrite(chf->cells, sizeof(rcCompactCell), chf->width * chf->height, file); } if (chf->spans) { fwrite(chf->spans, sizeof(rcCompactSpan), chf->spanCount, file); } if (chf->dist) { fwrite(chf->dist, sizeof(unsigned short), chf->spanCount, file); } if (chf->areas) { fwrite(chf->areas, sizeof(unsigned char), chf->spanCount, file); } } void IntermediateValues::debugWrite(FILE* file, const rcContourSet* cs) { if (!file || !cs) { return; } fwrite(&(cs->cs), sizeof(float), 1, file); fwrite(&(cs->ch), sizeof(float), 1, file); fwrite(cs->bmin, sizeof(float), 3, file); fwrite(cs->bmax, sizeof(float), 3, file); fwrite(&(cs->nconts), sizeof(int), 1, file); for (int i = 0; i < cs->nconts; ++i) { fwrite(&cs->conts[i].area, sizeof(unsigned char), 1, file); fwrite(&cs->conts[i].reg, sizeof(unsigned short), 1, file); fwrite(&cs->conts[i].nverts, sizeof(int), 1, file); fwrite(cs->conts[i].verts, sizeof(int), cs->conts[i].nverts * 4, file); fwrite(&cs->conts[i].nrverts, sizeof(int), 1, file); fwrite(cs->conts[i].rverts, sizeof(int), cs->conts[i].nrverts * 4, file); } } void IntermediateValues::debugWrite(FILE* file, const rcPolyMesh* mesh) { if (!file || !mesh) { return; } fwrite(&(mesh->cs), sizeof(float), 1, file); fwrite(&(mesh->ch), sizeof(float), 1, file); fwrite(&(mesh->nvp), sizeof(int), 1, file); fwrite(mesh->bmin, sizeof(float), 3, file); fwrite(mesh->bmax, sizeof(float), 3, file); fwrite(&(mesh->nverts), sizeof(int), 1, file); fwrite(mesh->verts, sizeof(unsigned short), mesh->nverts * 3, file); fwrite(&(mesh->npolys), sizeof(int), 1, file); fwrite(mesh->polys, sizeof(unsigned short), mesh->npolys * mesh->nvp * 2, file); fwrite(mesh->flags, sizeof(unsigned short), mesh->npolys, file); fwrite(mesh->areas, sizeof(unsigned char), mesh->npolys, file); fwrite(mesh->regs, sizeof(unsigned short), mesh->npolys, file); } void IntermediateValues::debugWrite(FILE* file, const rcPolyMeshDetail* mesh) { if (!file || !mesh) { return; } fwrite(&(mesh->nverts), sizeof(int), 1, file); fwrite(mesh->verts, sizeof(float), mesh->nverts * 3, file); fwrite(&(mesh->ntris), sizeof(int), 1, file); fwrite(mesh->tris, sizeof(char), mesh->ntris * 4, file); fwrite(&(mesh->nmeshes), sizeof(int), 1, file); fwrite(mesh->meshes, sizeof(int), mesh->nmeshes * 4, file); } void IntermediateValues::generateObjFile(int mapID, int tileX, int tileY, MeshData& meshData) { char objFileName[255]; sprintf(objFileName, "meshes/map%03u%02u%02u.obj", mapID, tileY, tileX); FILE* objFile = fopen(objFileName, "wb"); if (!objFile) { char message[1024]; sprintf(message, "Failed to open %s for writing!\n", objFileName); perror(message); return; } G3D::Array allVerts; G3D::Array allTris; allTris.append(meshData.liquidTris); allVerts.append(meshData.liquidVerts); TerrainBuilder::copyIndices(meshData.solidTris, allTris, allVerts.size() / 3); allVerts.append(meshData.solidVerts); float* verts = allVerts.getCArray(); int vertCount = allVerts.size() / 3; int* tris = allTris.getCArray(); int triCount = allTris.size() / 3; for (int i = 0; i < allVerts.size() / 3; i++) { fprintf(objFile, "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, "f %i %i %i\n", tris[i * 3] + 1, tris[i * 3 + 1] + 1, tris[i * 3 + 2] + 1); } fclose(objFile); char tileString[25]; sprintf(tileString, "[%02u,%02u]: ", tileY, tileX); printf("%sWriting debug output... \r", tileString); sprintf(objFileName, "meshes/%03u.map", mapID); objFile = fopen(objFileName, "wb"); if (!objFile) { char message[1024]; sprintf(message, "Failed to open %s for writing!\n", objFileName); perror(message); return; } char b = '\0'; fwrite(&b, sizeof(char), 1, objFile); fclose(objFile); sprintf(objFileName, "meshes/%03u%02u%02u.mesh", mapID, tileY, tileX); objFile = fopen(objFileName, "wb"); if (!objFile) { char message[1024]; sprintf(message, "Failed to open %s for writing!\n", objFileName); perror(message); return; } fwrite(&vertCount, sizeof(int), 1, objFile); fwrite(verts, sizeof(float), vertCount * 3, objFile); fflush(objFile); fwrite(&triCount, sizeof(int), 1, objFile); fwrite(tris, sizeof(int), triCount * 3, objFile); fflush(objFile); fclose(objFile); } }