📄 face.cpp
字号:
////////////////////////////////////////////////////////////////////////
//
// Face.cpp
//
// Copyright (c) 2003 Nokia Mobile Phones Ltd. All rights reserved.
//
////////////////////////////////////////////////////////////////////////
#include "Face.h"
#include "ScanConverter.h"
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
TShadedColor::TShadedColor(TUint16 aFlatColor)
{
iFlatColor = aFlatColor;
}
////////////////////////////////////////////////////////////////////////
TUint16 TShadedColor::GetValue(TInt aIllumination)
{
TInt red = iFlatColor & redMask;
TInt green = iFlatColor & greenMask;
TInt blue = iFlatColor & blueMask;
red = ( ( red * aIllumination ) >> illuminationUnityLog ) & redMask;
green = ( ( green * aIllumination ) >> illuminationUnityLog ) & greenMask;
blue = ( ( blue * aIllumination ) >> illuminationUnityLog ) & blueMask;
return (TUint16)( red | green | blue );
}
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
TFace::TFace(TUint16 aFlatColor, TInt aNumVerts, TInt aVertIndex[], const TVector3 * aVertPtr) :
iBaseColor( aFlatColor ),
iIllumination( TShadedColor::illuminationUnity )
{
// To do: assert that number of verts is legal.
iNumVerts = aNumVerts;
for ( TInt v = 0 ; v < aNumVerts ; v++ )
{
iVertIndex[v] = aVertIndex[v];
}
// Generate face plane:
iPlane = TPlane(aVertPtr[iVertIndex[0]], aVertPtr[iVertIndex[1]], aVertPtr[iVertIndex[2]]);
}
////////////////////////////////////////////////////////////////////////
void TFace::Render
(
TScanConverter &aScanConverter,
TMathLookup &aMath,
const TScreenVertex * aTransVertPtr,
TVector3 &aCameraInModelSpace
)
{
// Is the camera outside the plane of the face?
if ( iPlane.PointIsOutside(aCameraInModelSpace) )
{
// Yes, so face may be visible: we'll render it.
TClipFace clipFace( iBaseColor.GetValue( iIllumination ) );
for ( TInt v = 0 ; v < iNumVerts ; v++ )
{
clipFace.AddVertex(aTransVertPtr[ iVertIndex[v] ]);
}
clipFace.Render(aScanConverter, aMath);
}
}
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
TClipFace::TClipFace(TUint16 aFlatColor)
{
iFlatColor = aFlatColor;
//
Reset();
}
////////////////////////////////////////////////////////////////////////
void TClipFace::Reset()
{
iNumVerts = 0;
iOutcodeOr = 0x0000;
iOutcodeAnd = 0xffff;
}
////////////////////////////////////////////////////////////////////////
void TClipFace::AddVertex(const TScreenVertex &aVertex)
{
// To do: assert that number of verts is less than max.
iVertex[iNumVerts] = aVertex;
iOutcodeOr |= aVertex.iOutcodes;
iOutcodeAnd &= aVertex.iOutcodes;
iNumVerts++;
}
////////////////////////////////////////////////////////////////////////
void TClipFace::Render(TScanConverter &aScanConverter, TMathLookup &aMath)
{
if ( !IsDrawable() )
{
return;
}
else if ( iOutcodeOr != 0 )
{
// Make alternate face, and we'll clip from one to the other:
TClipFace alternateClipFace(iFlatColor);
aScanConverter.ClipAndRender(*this, alternateClipFace, aMath);
}
else
{
RenderUnclipped(aScanConverter, aMath);
}
}
////////////////////////////////////////////////////////////////////////
void TClipFace::ClipSelf
(
TClipFace &aDestFace,
TPlane &aClipPlane,
TInt aBoundIndex,
TCamera &aCamera,
TMathLookup &aMath
)
{
aDestFace.Reset();
TInt startIndex = iNumVerts - 1;
TUint16 outcodeMask = (TUint16)( 1 << aBoundIndex );
for ( TInt endIndex = 0 ; endIndex < iNumVerts ; endIndex++ )
{
TUint16 outcodesStart = iVertex[startIndex].iOutcodes;
TUint16 outcodesEnd = iVertex[endIndex].iOutcodes;
// Are the endpoints of this edge on opposite sides of the clip plane?
if ( ( (outcodesStart ^ outcodesEnd) & outcodeMask ) != 0 )
{
// Yes, so interpolate the intersection point of edge against plane
// and add as a vertex:
TScreenVertex interpVertex;
aClipPlane.IntersectLineSegment(iVertex[startIndex].iSpacePos,
iVertex[endIndex].iSpacePos, interpVertex.iSpacePos, aMath);
aCamera.PrepareForScreen(interpVertex, aBoundIndex + 1);
aDestFace.AddVertex(interpVertex);
}
// Is the endpoint inside the clip plane?
if ( ( outcodesEnd & outcodeMask ) == 0 )
{
// Yes, so copy end vertex across as is:
aDestFace.AddVertex( iVertex[endIndex] );
}
startIndex = endIndex;
}
}
////////////////////////////////////////////////////////////////////////
void TClipFace::RenderUnclipped(TScanConverter &aScanConverter, TMathLookup &aMath)
{
aScanConverter.ResetScan();
TInt startIndex = iNumVerts - 1;
for ( TInt endIndex = 0 ; endIndex < iNumVerts ; endIndex++ )
{
aScanConverter.ScanEdge(iVertex[startIndex], iVertex[endIndex], aMath);
startIndex = endIndex;
}
aScanConverter.Fill(iFlatColor);
}
////////////////////////////////////////////////////////////////////////
TBool TClipFace::IsDrawable()
{
if ( ( iNumVerts < 3 ) || ( iOutcodeAnd != 0 ) )
{
// ( iNumVerts < 3 ) => Degenerate shape: no pixels to draw.
//
// ( iOutcodeAnd != 0 ) => All vertices lie outside one bounding plane, so face
// does not intersect with view volume and can be culled.
return false;
}
else
{
return true;
}
}
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -