khanat-opennel-code/code/nel/tools/3d/zone_dump/zone_dump.cpp
2010-09-24 10:27:31 +02:00

221 lines
5.6 KiB
C++

// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "nel/misc/stream.h"
#include "nel/misc/file.h"
#include "nel/misc/vector.h"
#include "nel/misc/time_nl.h"
#include "nel/3d/zone.h"
#include "nel/3d/landscape.h"
#include "nel/misc/triangle.h"
#include "../zone_lib/zone_utility.h" // load a header file from zone_welder project
#include <stdio.h>
#include <float.h>
using namespace std;
using namespace NLMISC;
using namespace NL3D;
void buildFaces(CLandscape& landscape, sint zoneId, sint patch, std::vector<CTriangle> &faces)
{
faces.clear();
CZone* pZone=landscape.getZone (zoneId);
// Then trace all patch.
sint N= pZone->getNumPatchs();
nlassert(patch>=0);
nlassert(patch<N);
const CPatch *pa= const_cast<const CZone*>(pZone)->getPatch(patch);
// Build the faces.
//=================
sint ordS= 4*pa->getOrderS();
sint ordT= 4*pa->getOrderT();
sint x,y;
float OOS= 1.0f/ordS;
float OOT= 1.0f/ordT;
for(y=0;y<ordT;y++)
{
for(x=0;x<ordS;x++)
{
CTriangle f;
f.V0= pa->computeVertex(x*OOS, y*OOT);
f.V1= pa->computeVertex(x*OOS, (y+1)*OOT);
f.V2= pa->computeVertex((x+1)*OOS, (y+1)*OOT);
faces.push_back(f);
f.V0= pa->computeVertex(x*OOS, y*OOT);
f.V1= pa->computeVertex((x+1)*OOS, (y+1)*OOT);
f.V2= pa->computeVertex((x+1)*OOS, y*OOT);
faces.push_back(f);
}
}
}
int main(int argc, char* argv[])
{
try
{
// Good number of args ?
if (argc!=4)
{
// Help message
printf ("zone_dump [first_zone.zone] [last_zone.zone] [output.dump]\n");
printf ("Dump file format:\n");
printf ("\t4 bytes: number of triangles\n");
printf ("\tfor each triangles:\n");
printf ("\t\t3 floats, X, Y, Z for Vertex 0\n");
printf ("\t\t3 floats, X, Y, Z for Vertex 1\n");
printf ("\t\t3 floats, X, Y, Z for Vertex 2\n");
printf ("\t\tVertices are CCW, in a right hand basis with Z axis to the top\n");
}
else
{
// Get zones coordinates
uint16 xMin;
uint16 yMin;
if (!getZoneCoordByName(getName (argv[1]).c_str(), xMin, yMin))
fprintf (stderr, "Invalid zone name: %s\n", argv[1]);
else
{
// Get zones coordinates
uint16 xMax;
uint16 yMax;
if (!getZoneCoordByName(getName (argv[2]).c_str(), xMax, yMax))
fprintf (stderr, "Invalid zone name: %s\n", argv[2]);
else
{
// Reorder coordinates
uint16 tmp;
if (xMax<xMin)
{
tmp=xMin;
xMin=xMax;
xMax=tmp;
}
if (yMax<yMin)
{
tmp=yMin;
yMin=yMax;
yMax=tmp;
}
// Open the output file
COFile output;
if (output.open (argv[3]))
{
// Serial a tmp size
uint32 zero=0;
output.serial (zero);
// Triangles counter
uint32 triangles=0;
// Get zones path name
string path=getDir (argv[1]);
string ext=getExt (argv[1]);
// For all the zones
for (int y=yMin; y<=yMax; y++)
for (int x=xMin; x<=xMax; x++)
{
// Name of the zone
string name;
// Generate the zone name
getZoneNameByCoord(x, y, name);
// Open the zone
CIFile input;
if (input.open(path+name+ext))
{
// Warning message
printf ("Dump %s\n", name.c_str());
// Landscape
CLandscape landscape;
// Create a zone
CZone zone;
// Serial the zone
zone.serial (input);
// Add the zone
landscape.addZone (zone);
// Add triangle of this zone in the quadtree
for (uint patch=0; patch<(uint)zone.getNumPatchs(); patch++)
{
// vector of triangle
std::vector<CTriangle> faces;
// Build a list of triangles at 50 cm
buildFaces (landscape, zone.getZoneId(), patch, faces);
// Add to the file
for (uint tri=0; tri<faces.size(); tri++)
{
// Serial the triangle
faces[tri].V0.serial (output);
faces[tri].V1.serial (output);
faces[tri].V2.serial (output);
}
// Triangle count
triangles+=(uint32)faces.size();
}
}
else
// Warning message
printf ("Dump %s (missing)\n", name.c_str());
}
// Get the current pos
sint32 curPos=output.getPos ();
// File at the begining
output.seek (0, NLMISC::IStream::begin);
// Write the triangle count
output.serial (triangles);
// Go to the end of the file
output.seek (curPos, NLMISC::IStream::begin);
// Close the file
output.close ();
}
else
{
fprintf (stderr, "Can't open %s for writing.", argv[3]);
}
// Export the zones
}
}
}
}
catch (Exception& e)
{
fprintf (stderr, "FATAL: %s", e.what());
}
// exit.
return 0;
}