📄 iceindexedtriangle.cpp
字号:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* 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 + -