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

📄 iceindexedtriangle.cpp

📁 opcode是功能强大
💻 CPP
📖 第 1 页 / 共 2 页
字号:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
 *	Contains a handy indexed triangle class.
 *	\file		IceIndexedTriangle.cpp
 *	\author		Pierre Terdiman
 *	\date		January, 17, 2000
 */
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Precompiled Header
#include "Opcode/Stdafx.h"

using namespace IceMaths;

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
 *	Contains an indexed triangle class.
 *
 *	\class		Triangle
 *	\author		Pierre Terdiman
 *	\version	1.0
 *	\date		08.15.98
*/
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
 *	Flips the winding order.
 */
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void IndexedTriangle::Flip()
{
	Swap(mVRef[1], mVRef[2]);
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
 *	Computes the triangle area.
 *	\param		verts	[in] the list of indexed vertices
 *	\return		the area
 */
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
float IndexedTriangle::Area(const Point* verts)	const
{
	if(!verts)	return 0.0f;
	const Point& p0 = verts[0];
	const Point& p1 = verts[1];
	const Point& p2 = verts[2];
	return ((p0-p1)^(p0-p2)).Magnitude() * 0.5f;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
 *	Computes the triangle perimeter.
 *	\param		verts	[in] the list of indexed vertices
 *	\return		the perimeter
 */
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
float IndexedTriangle::Perimeter(const Point* verts)	const
{
	if(!verts)	return 0.0f;
	const Point& p0 = verts[0];
	const Point& p1 = verts[1];
	const Point& p2 = verts[2];
	return		p0.Distance(p1)
			+	p0.Distance(p2)
			+	p1.Distance(p2);
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
 *	Computes the triangle compacity.
 *	\param		verts	[in] the list of indexed vertices
 *	\return		the compacity
 */
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
float IndexedTriangle::Compacity(const Point* verts) const
{
	if(!verts)	return 0.0f;
	float P = Perimeter(verts);
	if(P==0.0f)	return 0.0f;
	return (4.0f*PI*Area(verts)/(P*P));
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
 *	Computes the triangle normal.
 *	\param		verts	[in] the list of indexed vertices
 *	\param		normal	[out] the computed normal
 */
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void IndexedTriangle::Normal(const Point* verts, Point& normal)	const
{
	if(!verts)	return;

	const Point& p0 = verts[mVRef[0]];
	const Point& p1 = verts[mVRef[1]];
	const Point& p2 = verts[mVRef[2]];
	normal = ((p2-p1)^(p0-p1)).Normalize();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
 *	Computes the triangle denormalized normal.
 *	\param		verts	[in] the list of indexed vertices
 *	\param		normal	[out] the computed normal
 */
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void IndexedTriangle::DenormalizedNormal(const Point* verts, Point& normal)	const
{
	if(!verts)	return;

	const Point& p0 = verts[mVRef[0]];
	const Point& p1 = verts[mVRef[1]];
	const Point& p2 = verts[mVRef[2]];
	normal = ((p2-p1)^(p0-p1));
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
 *	Computes the triangle center.
 *	\param		verts	[in] the list of indexed vertices
 *	\param		center	[out] the computed center
 */
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void IndexedTriangle::Center(const Point* verts, Point& center)	const
{
	if(!verts)	return;

	const Point& p0 = verts[mVRef[0]];
	const Point& p1 = verts[mVRef[1]];
	const Point& p2 = verts[mVRef[2]];
	center = (p0+p1+p2)*INV3;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
 *	Computes the centered normal
 *	\param		verts	[in] the list of indexed vertices
 *	\param		normal	[out] the computed centered normal
 */
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void IndexedTriangle::CenteredNormal(const Point* verts, Point& normal)	const
{
	if(!verts)	return;

	const Point& p0 = verts[mVRef[0]];
	const Point& p1 = verts[mVRef[1]];
	const Point& p2 = verts[mVRef[2]];
	Point Center = (p0+p1+p2)*INV3;
	normal = Center + ((p2-p1)^(p0-p1)).Normalize();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
 *	Computes a random point within the triangle.
 *	\param		verts	[in] the list of indexed vertices
 *	\param		normal	[out] the computed centered normal
 */
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void IndexedTriangle::RandomPoint(const Point* verts, Point& random)	const
{
	if(!verts)	return;

	// Random barycentric coords
	float Alpha	= UnitRandomFloat();
	float Beta	= UnitRandomFloat();
	float Gamma	= UnitRandomFloat();
	float OneOverTotal = 1.0f / (Alpha + Beta + Gamma);
	Alpha	*= OneOverTotal;
	Beta	*= OneOverTotal;
	Gamma	*= OneOverTotal;

	const Point& p0 = verts[mVRef[0]];
	const Point& p1 = verts[mVRef[1]];
	const Point& p2 = verts[mVRef[2]];
	random = Alpha*p0 + Beta*p1 + Gamma*p2;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
 *	Computes backface culling.
 *	\param		verts	[in] the list of indexed vertices
 *	\param		source	[in] source point (in local space) from which culling must be computed
 *	\return		true if the triangle is visible from the source point
 */
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool IndexedTriangle::IsVisible(const Point* verts, const Point& source)	const
{
	// Checkings
	if(!verts)	return false;

	const Point& p0 = verts[mVRef[0]];
	const Point& p1 = verts[mVRef[1]];
	const Point& p2 = verts[mVRef[2]];

	// Compute denormalized normal
	Point Normal = (p2 - p1)^(p0 - p1);

	// Backface culling
	return (Normal | source) >= 0.0f;

// Same as:
//	Plane PL(verts[mVRef[0]], verts[mVRef[1]], verts[mVRef[2]]);
//	return PL.Distance(source) > PL.d;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
 *	Computes backface culling.
 *	\param		verts	[in] the list of indexed vertices
 *	\param		source	[in] source point (in local space) from which culling must be computed
 *	\return		true if the triangle is visible from the source point
 */
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool IndexedTriangle::BackfaceCulling(const Point* verts, const Point& source)	const
{
	// Checkings
	if(!verts)	return false;

	const Point& p0 = verts[mVRef[0]];
	const Point& p1 = verts[mVRef[1]];
	const Point& p2 = verts[mVRef[2]];

	// Compute base
//	Point Base = (p0 + p1 + p2)*INV3;

	// Compute denormalized normal
	Point Normal = (p2 - p1)^(p0 - p1);

	// Backface culling
//	return (Normal | (source - Base)) >= 0.0f;
	return (Normal | (source - p0)) >= 0.0f;

// Same as: (but a bit faster)
//	Plane PL(verts[mVRef[0]], verts[mVRef[1]], verts[mVRef[2]]);
//	return PL.Distance(source)>0.0f;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
 *	Computes the occlusion potential of the triangle.
 *	\param		verts	[in] the list of indexed vertices
 *	\param		source	[in] source point (in local space) from which occlusion potential must be computed
 *	\return		the occlusion potential
 */
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
float IndexedTriangle::ComputeOcclusionPotential(const Point* verts, const Point& view)	const
{
	if(!verts)	return 0.0f;
	// Occlusion potential: -(A * (N|V) / d^2)
	// A = polygon area
	// N = polygon normal
	// V = view vector
	// d = distance viewpoint-center of polygon

	float A = Area(verts);
	Point N;	Normal(verts, N);
	Point C;	Center(verts, C);
	float d = view.Distance(C);
	return -(A*(N|view))/(d*d);
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
 *	Replaces a vertex reference with another one.
 *	\param		oldref	[in] the vertex reference to replace
 *	\param		newref	[in] the new vertex reference
 *	\return		true if success, else false if the input vertex reference doesn't belong to the triangle
 */
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool IndexedTriangle::ReplaceVertex(udword oldref, udword newref)
{
			if(mVRef[0]==oldref)	{ mVRef[0] = newref; return true; }

⌨️ 快捷键说明

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