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

📄 face.cpp

📁 手机 GAME c++ 版
💻 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 + -