⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 geomdb.cpp

📁 使用stl技术,(还没看,是听说的)
💻 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 + -