📄 mgcgprendererclip.cpp
字号:
rkNE1.Triangle(0) = uiNT1;
rkNE1.Triangle(1) = MgcGPTriMesh::INVALID_INDEX;
rkNT0.Vertex(0) = uiV0;
rkNT0.Vertex(1) = uiClipV0;
rkNT0.Vertex(2) = uiV2;
rkNT0.Edge(0) = uiE;
rkNT0.Edge(1) = uiNE0;
rkNT0.Edge(2) = uiE2;
rkNT1.Vertex(0) = uiClipV0;
rkNT1.Vertex(1) = uiClipV1;
rkNT1.Vertex(2) = uiV2;
rkNT1.Edge(0) = uiNE1;
rkNT1.Edge(1) = uiAE;
rkNT1.Edge(2) = uiNE0;
m_kMesh.Edge(uiE).Triangle(i) = uiNT0;
MgcGPTriMesh::EdgeRecord& rkAE0 = m_kMesh.Edge(uiE2);
if ( rkAE0.Triangle(0) == uiT )
rkAE0.Triangle(0) = uiNT0;
else
rkAE0.Triangle(1) = uiNT0;
MgcGPTriMesh::EdgeRecord& rkAE1 = m_kMesh.Edge(uiAE);
if ( rkAE1.Triangle(0) == uiT )
rkAE1.Triangle(0) = uiNT1;
else
rkAE1.Triangle(1) = uiNT1;
}
else
{
// triangle is clipped exactly at vertex uiV2
// add edge
uiNE = m_kMesh.AddEdge();
MgcGPTriMesh::EdgeRecord& rkNE = m_kMesh.Edge(uiNE);
// add triangle
uiNT = m_kMesh.AddTriangle();
MgcGPTriMesh::TriangleRecord& rkNT = m_kMesh.Triangle(uiNT);
// update fields
rkNE.Vertex(0) = uiClipV0;
rkNE.Vertex(1) = uiV2;
rkNE.Triangle(0) = uiNT;
rkNE.Triangle(1) = MgcGPTriMesh::INVALID_INDEX;
rkNT.Vertex(0) = uiV0;
rkNT.Vertex(1) = uiClipV0;
rkNT.Vertex(2) = uiV2;
rkNT.Edge(0) = uiE;
rkNT.Edge(1) = uiNE;
rkNT.Edge(2) = uiE2;
m_kMesh.Edge(uiE).Triangle(i) = uiNT;
MgcGPTriMesh::EdgeRecord& rkAE = m_kMesh.Edge(uiE2);
if ( rkAE.Triangle(0) == uiT )
rkAE.Triangle(0) = uiNT;
else
rkAE.Triangle(1) = uiNT;
}
// cull old triangle
m_kMesh.m_abEdgeVisible[uiE1] = false;
m_kMesh.m_abTriangleVisible[uiT] = false;
}
}
// update visibility flags for triangles
bool bAllTrianglesCulled = true;
for (uiT = 0; uiT < m_kMesh.m_uiTrianglesUsed; uiT++)
{
if ( m_kMesh.m_abTriangleVisible[uiT] )
{
MgcGPTriMesh::TriangleRecord& rkTri = m_kMesh.Triangle(uiT);
unsigned int uiV0 = rkTri.Vertex(0);
unsigned int uiV1 = rkTri.Vertex(1);
unsigned int uiV2 = rkTri.Vertex(2);
unsigned int uiE0 = rkTri.Edge(0);
unsigned int uiE1 = rkTri.Edge(1);
unsigned int uiE2 = rkTri.Edge(2);
assert( uiV0 < m_kMesh.m_uiVerticesUsed );
assert( uiV1 < m_kMesh.m_uiVerticesUsed );
assert( uiV2 < m_kMesh.m_uiVerticesUsed );
assert( uiE0 < m_kMesh.m_uiEdgesUsed );
assert( uiE1 < m_kMesh.m_uiEdgesUsed );
assert( uiE2 < m_kMesh.m_uiEdgesUsed );
if ( m_kMesh.m_afDistance[uiV0] <= 0.0
&& m_kMesh.m_afDistance[uiV1] <= 0.0
&& m_kMesh.m_afDistance[uiV2] <= 0.0 )
{
// triangle is not visible, cull it
m_kMesh.m_abTriangleVisible[uiT] = false;
m_kMesh.m_abVertexVisible[uiV0] = false;
m_kMesh.m_abVertexVisible[uiV1] = false;
m_kMesh.m_abVertexVisible[uiV2] = false;
m_kMesh.m_abEdgeVisible[uiE0] = false;
m_kMesh.m_abEdgeVisible[uiE1] = false;
m_kMesh.m_abEdgeVisible[uiE2] = false;
}
else
{
// Triangle is visible. It is possible that vertices and
// edges shared between a visible and an invisible triangle
// were marked as invisible earlier. Reset those vertices
// and edges since the current triangle is visible. (This
// may happen because of floating point round-off error or
// when a clipping plane exactly contains a vertex.)
bAllTrianglesCulled = false;
m_kMesh.m_abVertexVisible[uiV0] = true;
m_kMesh.m_abVertexVisible[uiV1] = true;
m_kMesh.m_abVertexVisible[uiV2] = true;
m_kMesh.m_abEdgeVisible[uiE0] = true;
m_kMesh.m_abEdgeVisible[uiE1] = true;
m_kMesh.m_abEdgeVisible[uiE2] = true;
}
}
}
return bAllTrianglesCulled;
}
//---------------------------------------------------------------------------
bool MgcGPRenderer::ClipNear ()
{
// constraint: W - 1 >= 0
// compute vertex distances to plane
for (unsigned int uiV = 0; uiV < m_kMesh.m_uiVerticesUsed; uiV++)
{
if ( m_kMesh.m_abVertexVisible[uiV] )
{
MgcVector3& rkPoint = m_kMesh.Vertex(uiV);
m_kMesh.m_afDistance[uiV] = rkPoint.z - 1.0;
if ( m_kMesh.m_afDistance[uiV] < 0.0 )
m_kMesh.m_abVertexVisible[uiV] = false;
}
}
return ClipTriMesh();
}
//---------------------------------------------------------------------------
bool MgcGPRenderer::ClipFar ()
{
// constraint: F/N - W >= 0
MgcReal fFarDivideNear = GetCamera()->GetFarDivideNear();
// compute vertex distances to plane
for (unsigned int uiV = 0; uiV < m_kMesh.m_uiVerticesUsed; uiV++)
{
if ( m_kMesh.m_abVertexVisible[uiV] )
{
MgcVector3& rkPoint = m_kMesh.Vertex(uiV);
m_kMesh.m_afDistance[uiV] = fFarDivideNear - rkPoint.z;
if ( m_kMesh.m_afDistance[uiV] < 0.0 )
m_kMesh.m_abVertexVisible[uiV] = false;
}
}
return ClipTriMesh();
}
//---------------------------------------------------------------------------
bool MgcGPRenderer::ClipLeft ()
{
// constraint: W + X >= 0
// compute vertex distances to plane
for (unsigned int uiV = 0; uiV < m_kMesh.m_uiVerticesUsed; uiV++)
{
if ( m_kMesh.m_abVertexVisible[uiV] )
{
MgcVector3& rkPoint = m_kMesh.Vertex(uiV);
m_kMesh.m_afDistance[uiV] = rkPoint.z + rkPoint.x;
if ( m_kMesh.m_afDistance[uiV] < 0.0 )
m_kMesh.m_abVertexVisible[uiV] = false;
}
}
return ClipTriMesh();
}
//---------------------------------------------------------------------------
bool MgcGPRenderer::ClipRight ()
{
// constraint: W - X >= 0
// compute vertex distances to plane
for (unsigned int uiV = 0; uiV < m_kMesh.m_uiVerticesUsed; uiV++)
{
if ( m_kMesh.m_abVertexVisible[uiV] )
{
MgcVector3& rkPoint = m_kMesh.Vertex(uiV);
m_kMesh.m_afDistance[uiV] = rkPoint.z - rkPoint.x;
if ( m_kMesh.m_afDistance[uiV] < 0.0 )
m_kMesh.m_abVertexVisible[uiV] = false;
}
}
return ClipTriMesh();
}
//---------------------------------------------------------------------------
bool MgcGPRenderer::ClipTop ()
{
// constraint: W - Y >= 0
// compute vertex distances to plane
for (unsigned int uiV = 0; uiV < m_kMesh.m_uiVerticesUsed; uiV++)
{
if ( m_kMesh.m_abVertexVisible[uiV] )
{
MgcVector3& rkPoint = m_kMesh.Vertex(uiV);
m_kMesh.m_afDistance[uiV] = rkPoint.z - rkPoint.y;
if ( m_kMesh.m_afDistance[uiV] < 0.0 )
m_kMesh.m_abVertexVisible[uiV] = false;
}
}
return ClipTriMesh();
}
//---------------------------------------------------------------------------
bool MgcGPRenderer::ClipBottom ()
{
// constraint: W + Y >= 0
// compute vertex distances to plane
for (unsigned int uiV = 0; uiV < m_kMesh.m_uiVerticesUsed; uiV++)
{
if ( m_kMesh.m_abVertexVisible[uiV] )
{
MgcVector3& rkPoint = m_kMesh.Vertex(uiV);
m_kMesh.m_afDistance[uiV] = rkPoint.z + rkPoint.y;
if ( m_kMesh.m_afDistance[uiV] < 0.0 )
m_kMesh.m_abVertexVisible[uiV] = false;
}
}
return ClipTriMesh();
}
//---------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -