📄 geomdb.cpp
字号:
// ---------------------------------------------------------------------------------------------------------------------------------
// _____ _____ ____
// / ____| | __ \| _ \
// | | __ ___ ___ _ __ ___ | | | | |_) | ___ _ __ _ __
// | | |_ |/ _ \/ _ \| '_ ` _ \| | | | _ < / __| '_ \| '_ \
// | |__| | __/ (_) | | | | | | |__| | |_) | _ | (__| |_) | |_) |
// \_____|\___|\___/|_| |_| |_|_____/|____/ (_) \___| .__/| .__/
// | | | |
// |_| |_|
//
// Description:
//
// Geometry database manager
//
// Notes:
//
// Best viewed with 8-character tabs and (at least) 132 columns
//
// History:
//
// 08/03/2001 by Paul Nettle: Original creation
//
// Restrictions & freedoms pertaining to usage and redistribution of this software:
//
// This software is 100% free. If you use this software (in part or in whole) you must credit the author. This software may not be
// re-distributed (in part or in whole) in a modified form without clear documentation on how to obtain a copy of the original
// work. You may not use this software to directly or indirectly cause harm to others. This software is provided as-is and without
// warrantee -- Use at your own risk. For more information, visit HTTP://www.FluidStudios.com/
//
// Copyright 2002, Fluid Studios, Inc., all rights reserved.
// ---------------------------------------------------------------------------------------------------------------------------------
#include "stdafx.h"
#include "FSRad.h"
#include "GeomDB.h"
#include "ProgressDlg.h"
//#include "FSRadDotSceneLoader.h"
#include "DotSceneConverter.h"
// ---------------------------------------------------------------------------------------------------------------------------------
/*
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
*/
// ---------------------------------------------------------------------------------------------------------------------------------
GeomDB::GeomDB()
{
}
// ---------------------------------------------------------------------------------------------------------------------------------
GeomDB::~GeomDB()
{
}
// ---------------------------------------------------------------------------------------------------------------------------------
bool GeomDB::writeSCENE(const fstl::string & filename, ProgressDlg & prog)
{
try
{
prog.setCurrentStatus("Converting geometry");
prog.setCurrentPercent(0);
DotSceneConverter& dsl = DotSceneConverter::instance();
dsl.write();
}
catch (const char * err)
{
if (err && *err)
{
prog.error(err);
return false;
}
}
return true;
}
// ---------------------------------------------------------------------------------------------------------------------------------
bool GeomDB::readSCENE(const fstl::string & infile, const fstl::string & outfile, ProgressDlg & prog, const geom::Color3 & defaultReflectivity)
{
try
{
prog.setCurrentStatus("Converting geometry");
DotSceneConverter& dsl = DotSceneConverter::instance();
dsl.load();
}
catch (const char * err)
{
if (err && *err)
{
prog.error(err);
return false;
}
}
return true;
}
// ---------------------------------------------------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------------------------------------------------
bool GeomDB::writeOCT(const fstl::string & filename, ProgressDlg & prog)
{
// Open the file
FILE * fp = fopen(filename.asArray(), "wb");
if (!fp) return false;
// Types used by the exporter
#pragma pack(1)
typedef float octVect2[2];
typedef float octVect3[3];
typedef float octPlane[4]; // 4th float is distance
struct octHeader
{
int numVerts;
int numFaces;
int numTextures;
int numLightmaps;
int numLights;
};
struct octVert
{
octVect2 tv; // texture coordinates
octVect2 lv; // lightmap coordinates
octVect3 pos; // vertex position
};
struct octFace
{
int start; // first face vert in vertex array
int num; // number of verts in the face
int id; // texture index into the texture array
int lid; // lightmap index into the lightmap array
octPlane p;
};
struct octTexture
{
unsigned int id; // texture id
char name[64]; // texture name
};
struct octLightmap
{
unsigned int id; // lightmaps id
unsigned char map[49152]; // 128 x 128 raw RGB data
};
struct octLight
{
octVect3 pos; // Position
octVect3 color; // Color (RGB)
int intensity; // Intensity
};
#pragma pack()
// Create the header
octHeader header;
// Setup the header info
header.numFaces = polys().size();
header.numTextures = octTextures().size();
header.numLightmaps = lightmaps().size();
header.numLights = lights().size();
// Vertex count for the header
{
header.numVerts = 0;
for (RadPrimList::node *i = polys().head(); i; i = i->next())
{
header.numVerts += i->data().xyz().size();
}
}
// Write the header
if (fwrite(&header, sizeof(header), 1, fp) != 1) return false;
// Allocate some RAM
octVert * verts = new octVert[header.numVerts];
octFace * faces = new octFace[header.numFaces];
octTexture * texts = new octTexture[header.numTextures];
octLightmap * lmaps = new octLightmap[header.numLightmaps];
octLight * lites = new octLight[header.numLights];
octVect3 playerPos;
memset(faces, 0, sizeof(octFace) * header.numFaces);
memset(playerPos, 0, sizeof(playerPos));
// Save the data
try
{
// Make sure we got the memory we asked for...
if (!verts || !faces || !texts || !lmaps || !lites) throw false;
// Convert the polys & vertices
{
prog.setCurrentStatus("Converting geometry");
unsigned int pIndex = 0;
unsigned int vIndex = 0;
for (RadPrimList::node *i = polys().head(); i; i = i->next(), ++pIndex)
{
if (!(pIndex&0xf))
{
prog.setCurrentPercent(static_cast<float>(pIndex) / static_cast<float>(polys().size()) * 100.0f);
if (prog.stopRequested()) throw false;
}
RadPrim & p = i->data();
octFace & curFace = faces[pIndex];
// Populate the face
curFace.start = vIndex;
curFace.num = p.xyz().size();
curFace.id = p.polyID();
curFace.lid = p.textureID();
// Populate the verts
for (unsigned int j = 0; j < p.xyz().size(); ++j, ++vIndex)
{
octVert & curVert = verts[vIndex];
curVert.tv[0] = p.texuv()[j].u() / 128.0f;
curVert.tv[1] = p.texuv()[j].v() / 128.0f;
curVert.lv[0] = p.uv()[j].u() / 128.0f;
curVert.lv[1] = p.uv()[j].v() / 128.0f;
curVert.pos[0] = p.xyz()[j].x();
curVert.pos[1] = p.xyz()[j].y();
curVert.pos[2] = p.xyz()[j].z();
}
}
}
// Convert the textures
{
prog.setCurrentStatus("Converting textures");
for (int i = 0; i < header.numTextures; ++i)
{
if (!(i&0xf))
{
prog.setCurrentPercent(static_cast<float>(i) / static_cast<float>(header.numTextures) * 100.0f);
if (prog.stopRequested()) throw false;
}
sOctTexture & ot = octTextures()[i];
texts[i].id = ot.id;
memcpy(texts[i].name, ot.name, sizeof(ot.name));
}
}
// Convert the lights
{
prog.setCurrentStatus("Converting lights");
unsigned int idx = 0;
for (RadPatchList::node * i = lights().head(); i; i = i->next(), ++idx)
{
if (!(idx&0xf))
{
prog.setCurrentPercent(static_cast<float>(idx) / static_cast<float>(header.numLights) * 100.0f);
if (prog.stopRequested()) throw false;
}
RadPatch & patch = i->data();
lites[idx].pos[0] = patch.origin().x();
lites[idx].pos[1] = patch.origin().y();
lites[idx].pos[2] = patch.origin().z();
lites[idx].color[0] = patch.energy().r(); // these are stored incorrectly... bummer.
lites[idx].color[1] = patch.energy().g();
lites[idx].color[2] = patch.energy().b();
lites[idx].intensity = 1;
}
}
// Convert the lightmaps
{
prog.setCurrentStatus("Converting lightmaps");
for (int i = 0; i < header.numLightmaps; ++i)
{
if (!(i&0xf))
{
prog.setCurrentPercent(static_cast<float>(i) / static_cast<float>(header.numLightmaps) * 100.0f);
if (prog.stopRequested()) throw false;
}
RadLMap & lm = lightmaps()[i];
lmaps[i].id = i;
// Convert the lightmap data
{
geom::Color3 * src = &lm.data()[0];
unsigned char * dst = lmaps[i].map;
unsigned int size = 128*128;
for (unsigned int i = 0; i < size; ++i, ++src, dst += 3)
{
dst[0] = static_cast<unsigned char>(src->r());
dst[1] = static_cast<unsigned char>(src->g());
dst[2] = static_cast<unsigned char>(src->b());
}
}
}
}
// Write the data
prog.setCurrentStatus("Saving geometry");
if (header.numVerts && fwrite(verts, sizeof(octVert) * header.numVerts, 1, fp) != 1) throw false;
if (header.numFaces && fwrite(faces, sizeof(octFace) * header.numFaces, 1, fp) != 1) throw false;
if (header.numTextures && fwrite(texts, sizeof(octTexture) * header.numTextures, 1, fp) != 1) throw false;
if (header.numLightmaps && fwrite(lmaps, sizeof(octLightmap) * header.numLightmaps, 1, fp) != 1) throw false;
if (header.numLights && fwrite(lites, sizeof(octLight) * header.numLights, 1, fp) != 1) throw false;
if ( fwrite(&playerPos, sizeof(playerPos), 1, fp) != 1) throw false;
// Oki doki!
throw true;
}
catch(const bool err)
{
delete[] verts;
delete[] faces;
delete[] texts;
delete[] lmaps;
delete[] lites;
fclose(fp);
if (!err) return err;
}
fclose(fp);
return true;
}
// ---------------------------------------------------------------------------------------------------------------------------------
// GeomDB.cpp - End of file
// ---------------------------------------------------------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -