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

📄 radgen.cpp

📁 使用stl技术,(还没看,是听说的)
💻 CPP
📖 第 1 页 / 共 4 页
字号:

					// Bottom row for the [M]ask and [C]olor maps (for convenience)...

					geom::Color3 *	bmRow = static_cast<geom::Color3 *>(0);
					geom::Color3 *	bcRow = static_cast<geom::Color3 *>(0);
					if (v < lh-1)
					{
						bmRow = cmRow + lw;
						bcRow = ccRow + lw;
					}

					for (unsigned int u = 0; u < lw; ++u)
					{
						// We're only averaging non-masked (i.e. un-occupied) pixels

						if (cmRow[u].r()) continue;

						// Average each of the 8 neighboring pixels (that have mask colors)

						unsigned int	count = 0;
						geom::Color3	totalColor(0,0,0);

						// Top row

						if (tmRow)
						{
							if (u >    0 && tmRow[u-1].r()) totalColor += tcRow[u-1], ++count;
							if (            tmRow[u  ].r()) totalColor += tcRow[u  ], ++count;
							if (u < lw-1 && tmRow[u+1].r()) totalColor += tcRow[u+1], ++count;
						}

						// Current row

						{
							if (u >    0 && cmRow[u-1].r()) totalColor += ccRow[u-1], ++count;
							if (u < lw-1 && cmRow[u+1].r()) totalColor += ccRow[u+1], ++count;
						}

						// Bottom row

						if (bmRow)
						{
							if (u >    0 && bmRow[u-1].r()) totalColor += bcRow[u-1], ++count;
							if (            bmRow[u  ].r()) totalColor += bcRow[u  ], ++count;
							if (u < lw-1 && bmRow[u+1].r()) totalColor += bcRow[u+1], ++count;
						}

						// The average

						if (count)	ccRow[u] = totalColor / static_cast<float>(count);
						else		ccRow[u] = geom::Color3(0,0,0);
					}
				}
			}
		}
	}
}

// ---------------------------------------------------------------------------------------------------------------------------------

void	RadGen::addAmbient()
{
	if (ambient() == geom::Color3(0,0,0)) return;

	progress()->setCurrentStatus("Adding post-processing ambient light");

	for (unsigned int i = 0; i < geometry().lightmaps().size(); ++i)
	{
		if (!(i&0xf))
		{
			progress()->setCurrentPercent(static_cast<float>(i) / static_cast<float>(geometry().lightmaps().size()) * 100.0f);
			if (progress()->stopRequested()) throw "";
		}

		geometry().lightmaps()[i].addAmbient(ambient());
	}
}

// ---------------------------------------------------------------------------------------------------------------------------------

void	RadGen::doGammaCorrection()
{
	if (gamma() == 1.0f) return;

	progress()->setCurrentStatus("Gamma correction");

	for (unsigned int i = 0; i < geometry().lightmaps().size(); ++i)
	{
		if (!(i&0xf))
		{
			progress()->setCurrentPercent(static_cast<float>(i) / static_cast<float>(geometry().lightmaps().size()) * 100.0f);
			if (progress()->stopRequested()) throw "";
		}

		geometry().lightmaps()[i].applyGamma(gamma());
	}
}

// ---------------------------------------------------------------------------------------------------------------------------------

void	RadGen::doClamping()
{
	if (clamping() == ClampSaturate)
	{
		progress()->setCurrentStatus("Clamping with saturation");

		for (unsigned int i = 0; i < geometry().lightmaps().size(); ++i)
		{
			if (!(i&0xf))
			{
				progress()->setCurrentPercent(static_cast<float>(i) / static_cast<float>(geometry().lightmaps().size()) * 100.0f);
				if (progress()->stopRequested()) throw "";
			}

			geometry().lightmaps()[i].clampSaturate();
		}
	}
	else if (clamping() == ClampRetain)
	{
		progress()->setCurrentStatus("Clamping with color ratio");

		for (unsigned int i = 0; i < geometry().lightmaps().size(); ++i)
		{
			if (!(i&0xf))
			{
				progress()->setCurrentPercent(static_cast<float>(i) / static_cast<float>(geometry().lightmaps().size()) * 100.0f);
				if (progress()->stopRequested()) throw "";
			}

			geometry().lightmaps()[i].clampRetainColorRatio();
		}
	}
}

// ---------------------------------------------------------------------------------------------------------------------------------

void	RadGen::go(ProgressDlg * owner)
{
	try
	{
		// Put up the progress dialog...

		progress() = owner;

		// Load up the geometry
		{
			//SK:
			if (!geometry().readSCENE(inputFilename(), writeOctFilename(), *progress(), defaultReflectivity()))
			{
				// Error if they didn't ask to stop

				if (!progress()->stopRequested())
				{
					throw "Unable to load the geometry";
				}
			}
		}

		// Generate lightmaping coordinates and lightmaps for these polygons
		{
			LMapGen	lmg;
			lmg.lightmapWidth() = lightmapWidth();
			lmg.lightmapHeight() = lightmapHeight();
			lmg.uTexelsPerUnit() = uTexelsPerUnit();
			lmg.vTexelsPerUnit() = vTexelsPerUnit();

			if (!lmg.generate(*progress(), geometry().polys(), geometry().lightmaps()))
			{
				throw "Unable to generate lightmap coordinates & lightmaps";
			}
		}

		// Initial energy goes into the lightmaps to color the lights of their own color

		distributeInitialEnergy();

		// Count up the total patches & elements

		countPatchesAndElements();

		// Build the octree

		SOctree	octree;
		SOctree::sBuildInfo bi;
		{
			bi.thresholdLimiter = octreeThreshold();
			bi.minRadiusLimiter = octreeMinRadius();
			bi.maxDepthLimiter = octreeMaxDepth();
			bi.bspQuantizeResolution = bspGaussianResolution();
			bi.bspLeastDepthErrorBoundsPercent = bspMinSplitRange();
			bi.progressDialog = progress();
			bi.patchSubdivisionU = subdivisionU();
			bi.patchSubdivisionV = subdivisionV();

			if (!octree.build(geometry(), bi))
			{
				// Error if they didn't ask to stop

				if (!progress()->stopRequested()) throw "Unable to build the Octree";

				// If they _did_ ask to stop, bail without an error

				else throw "";
			}
		}

		// Initial stats

		totalAbsorbedEnergy() = geom::Color3(0,0,0);
		totalEscapedEnergy() = geom::Color3(0,0,0);
		iterationsProcessed() = 0;
		initialEnergy() = calcTotalEnergy();
		energyThisPass() = 0;
		updateStats(*progress());
		lightsToProcess() = geometry().lights().size() != 0;

		// Run the ratiosity process

		octree.traverse(_processEnergy, static_cast<void *>(this));

		// Check for a request to bail...

		if (progress()->stopRequested())
		{
			if (progress()->saveResults())
				progress()->resetStopped();
			else
				throw "";
		}

		// Ambient term estimation for unshot light

		geom::Color3	estimatedAmbientTerm(0,0,0);
		if (ambientTerm()) estimatedAmbientTerm = calcAmbientTerm();

		// Correct polygon edges within the lightmap & add the ambient term

		expandEdges();

		// Ambient light (yech!)

		addAmbient();

		// Gamma correction

		doGammaCorrection();

		// Clamping/Saturation

		doClamping();

		// Output the .scene file

		if (writeOctFile())
		{
			progress()->setCurrentStatus("Writing scene file");
			geometry().writeSCENE(writeOctFilename(), *progress());
		}

		// Write the raw data?

		if (writeRawLightmaps())
		{
			progress()->setCurrentStatus("Writing lightmaps");

			for (unsigned int i = 0; i < geometry().lightmaps().size(); ++i)
			{
				if (!(i&0xf))
				{
					progress()->setCurrentPercent(static_cast<float>(i) / static_cast<float>(geometry().lightmaps().size()) * 100.0f);
					if (progress()->stopRequested()) throw "";
				}

				// Write the lightmap
				geometry().lightmaps()[i].writePNG(writeRawLightmapsFolder());
			}
		}

		// Deal with results
		{
			progress()->setFinished();

			// Cleanup the progress dialog

			progress()->setCurrentStatus("FINISHED");
			progress()->setCurrentPercent(0);
		}
	}
	catch(const char *err)
	{
		if (err && *err) progress()->error(err);
	}

	//SK:delete progress();
	progress() = NULL;
}

// ---------------------------------------------------------------------------------------------------------------------------------

void	RadGen::readDefaultParms()
{
	// Desktop

	/*SK:
	char	desktopPath[MAX_PATH];
	memset(desktopPath, 0, sizeof(desktopPath));
	SHGetSpecialFolderPath(NULL, desktopPath, CSIDL_DESKTOPDIRECTORY, 0);
	fstl::string	defaultOctOutput = fstl::string(desktopPath) + "\\output.oct";

	// Lightmap parms

	lightmapWidth() = theApp.GetProfileInt("Options", "lightmapWidth", 128);
	lightmapHeight() = theApp.GetProfileInt("Options", "lightmapHeight", 128);
	uTexelsPerUnit() = 1 / static_cast<float>(atof(theApp.GetProfileString("Options", "uTexelsPerUnitInverse", "16")));
	vTexelsPerUnit() = 1 / static_cast<float>(atof(theApp.GetProfileString("Options", "vTexelsPerUnitInverse", "16")));

	// Octree parameters

	octreeThreshold() = theApp.GetProfileInt("Options", "OctreePolysPerNode", 50000);
	octreeMaxDepth() = theApp.GetProfileInt("Options", "OctreeMaxDepth", 50);
	octreeMinRadius() = static_cast<float>(atof(theApp.GetProfileString("Options", "OctreeMinRadius", "5.0")));

	// Reflectivity

	float	rr = static_cast<float>(atof(theApp.GetProfileString("Options", "rReflectivity", "0.78")));
	float	rg = static_cast<float>(atof(theApp.GetProfileString("Options", "rReflectivity", "0.78")));
	float	rb = static_cast<float>(atof(theApp.GetProfileString("Options", "rReflectivity", "0.78")));
	defaultReflectivity() = geom::Color3(rr, rg, rb);

	// BSP parameters

	bspMinSplitRange() = static_cast<float>(atof(theApp.GetProfileString("Options", "BSPMinSplitRange", "5.0")));
	bspGaussianResolution() = theApp.GetProfileInt("Options", "BSPGaussianResolution", 8);

	// Input/output parameters

	writeRawLightmapsFolder() = fstl::string(theApp.GetProfileString("Options", "outputRawDirectory", desktopPath));
	writeRawLightmaps() = theApp.GetProfileInt("Options", "outputRawDirectoryFlag", 0) ? true:false;
	writeOctFile() = theApp.GetProfileInt("Options", "outputOctFileFlag", 1) ? true:false;
	writeOctFilename() = fstl::string(theApp.GetProfileString("Options", "outputOctFilename", defaultOctOutput.asArray()));
	inputFilename() = fstl::string(theApp.GetProfileString("Options", "inputFilename", ""));

	// General parms

	convergence() = theApp.GetProfileInt("Options", "convergence", 10);
	maxIterations() = theApp.GetProfileInt("Options", "enableMaxIterations", 0) ? true:false;
	maxIterationsCount() = theApp.GetProfileInt("Options", "maxIterationsCount", 1000);
	areaLightMultiplier() = theApp.GetProfileInt("Options", "areaLightMultiplier", 1000000);
	pointLightMultiplier() = static_cast<float>(atof(theApp.GetProfileString("Options", "pointLightMultiplier", "0.6")));
	subdivisionU() = theApp.GetProfileInt("Options", "subdivisionU", 4);
	subdivisionV() = theApp.GetProfileInt("Options", "subdivisionV", 4);
	ambientTerm() = theApp.GetProfileInt("Options", "ambientTerm", 1) ? true:false;
	useNusselt() = theApp.GetProfileInt("Options", "useNusselt", 0) ? true:false;
	directLightOnly() = theApp.GetProfileInt("Options", "directLightOnly", 0) ? true:false;
	adaptiveMaxSubdivisionU() = theApp.GetProfileInt("Options", "adaptiveMaxSubdivisionU", 256);
	adaptiveMaxSubdivisionV() = theApp.GetProfileInt("Options", "adaptiveMaxSubdivisionV", 256);
	adaptivePatchSubdivision() = theApp.GetProfileInt("Options", "adaptivePatchSubdivision", 1) ? true:false;
	adaptiveThreshold() = theApp.GetProfileInt("Options", "adaptiveThreshold", 15);

	leaveResults() = false;

	// Post-processing parms

	gamma() = static_cast<float>(theApp.GetProfileInt("Options", "gamma", 0)) / 100.0f;
	ambient().r() = static_cast<float>(theApp.GetProfileInt("Options", "rAmbient", 0));
	ambient().g() = static_cast<float>(theApp.GetProfileInt("Options", "gAmbient", 0));
	ambient().b() = static_cast<float>(theApp.GetProfileInt("Options", "bAmbient", 0));

	switch(theApp.GetProfileInt("Options", "clamping", RadGen::ClampNone))
	{
		case	ClampSaturate:	clamping() = ClampSaturate;	break;
		case	ClampRetain:	clamping() = ClampRetain;	break;
		default:		clamping() = ClampNone;		break;
	}
	*/
}

// ---------------------------------------------------------------------------------------------------------------------------------
// RadGen.cpp - End of file
// ---------------------------------------------------------------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -