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

📄 mlrindexedpolymesh.cpp

📁 机甲指挥官2源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//===========================================================================//
// Copyright (C) Microsoft Corporation. All rights reserved.                 //
//===========================================================================//

#include "MLRHeaders.hpp"

#include "OwnTrace.hpp"

#if defined(TRACE_ENABLED) && defined(MLR_TRACE)
	BitTrace *MLRIndexedPolyMesh_Clip;
	#define SET_MLRIndexedPolyMesh_CLIP() MLRIndexedPolyMesh_Clip->Set()
	#define CLEAR_MLRIndexedPolyMesh_CLIP() MLRIndexedPolyMesh_Clip->Clear()
#else
	#define SET_MLRIndexedPolyMesh_CLIP()
	#define CLEAR_MLRIndexedPolyMesh_CLIP()
#endif

//#############################################################################
//###############################    MLRIndexedPolyMesh    ##################################
//#############################################################################

MLRIndexedPolyMesh::ClassData*
	MLRIndexedPolyMesh::DefaultData = NULL;
MemoryBlock*
	MLRIndexedPolyMesh::AllocatedMemory = NULL;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRIndexedPolyMesh::InitializeClass()
{
	Verify(!AllocatedMemory);
	AllocatedMemory =
		new MemoryBlock(
			sizeof(MLRIndexedPolyMesh),
			100,
			100,
			"MLRIndexedPolyMesh"
		);
	Register_Object(AllocatedMemory);

	Verify(!DefaultData);
	DefaultData =
		new ClassData(
			MLRIndexedPolyMeshClassID,
			"MidLevelRenderer::MLRIndexedPolyMesh",
			MLRIndexedPrimitive::DefaultData,
			(MLRPrimitive::Factory)&Make
		);
	Register_Object(DefaultData);

	#if defined(TRACE_ENABLED) && defined(MLR_TRACE)
		MLRIndexedPolyMesh_Clip = new BitTrace("MLRIndexedPolyMesh_Clip");
		Register_Object(MLRIndexedPolyMesh_Clip);
	#endif
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRIndexedPolyMesh::TerminateClass()
{
	Unregister_Object(DefaultData);
	delete DefaultData;
	DefaultData = NULL;

	Unregister_Object(AllocatedMemory);
	delete AllocatedMemory;
	AllocatedMemory = NULL;

	#if defined(TRACE_ENABLED) && defined(MLR_TRACE)
		Unregister_Object(MLRIndexedPolyMesh_Clip);
		delete MLRIndexedPolyMesh_Clip;
	#endif
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRIndexedPolyMesh::MLRIndexedPolyMesh(
	MemoryStream *stream,
	int version
):
	MLRIndexedPrimitive(DefaultData, stream, version)
{
	Check_Pointer(this);
	Check_Pointer(stream);

	facePlanes.SetLength(GetNumPrimitives());
	testList.SetLength(GetNumPrimitives());

	FindFacePlanes();
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRIndexedPolyMesh::MLRIndexedPolyMesh():
	MLRIndexedPrimitive(DefaultData)
{
	Check_Pointer(this);

	drawMode = SortData::TriIndexedList;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRIndexedPolyMesh::~MLRIndexedPolyMesh()
{
	Check_Object(this);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRIndexedPolyMesh*
	MLRIndexedPolyMesh::Make(
		MemoryStream *stream,
		int version
	)
{
	return new MLRIndexedPolyMesh(stream, version);
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRIndexedPolyMesh::Save(MemoryStream *stream)
{
	Check_Object(this);
	Check_Object(stream);

	MLRIndexedPrimitive::Save(stream);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRIndexedPolyMesh::TestInstance() const
{
	Verify(IsDerivedFrom(DefaultData));
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRIndexedPolyMesh::InitializeDrawPrimitive(int vis, int parameter)
{
	MLRIndexedPrimitive::InitializeDrawPrimitive(vis, parameter);

	if(parameter & 1)
	{
		ResetTestList();
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRIndexedPolyMesh::SetPrimitiveLength (unsigned char *data, int numPrimitives)
{
	Check_Object(this); 

	lengths.AssignData(data, numPrimitives);

	facePlanes.SetLength(numPrimitives);

	testList.SetLength(numPrimitives);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRIndexedPolyMesh::GetPrimitiveLength (unsigned char **data, int *l)
{
	Check_Object(this);
	*l = lengths.GetLength();
	*data = lengths.GetData();
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRIndexedPolyMesh::FindFacePlanes()
{
	Check_Object(this); 

	int i, j, stride, numPrimitives = GetNumPrimitives();
	Vector3D v;

	Verify(index.GetLength() > 0);

	for(i=0,j=0;i<numPrimitives;i++)
	{
		stride = lengths[i];

		facePlanes[i].BuildPlane(
			coords[index[j]],
			coords[index[j+1]],
			coords[index[j+2]]
		);

		j += stride;
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
	MLRIndexedPolyMesh::FindBackFace(const Point3D& u)
{
	Check_Object(this);

	int i, numPrimitives = GetNumPrimitives();
	int ret = 0, len = lengths.GetLength();
	unsigned char *iPtr;
	Plane *p;

	if(len <= 0)
	{
		visible = 0;

		return 0;
	}

	p = &facePlanes[0];
	iPtr = &testList[0];

	if(state.GetBackFaceMode() == MLRState::BackFaceOffMode)
	{
		ResetTestList();
		ret = 1;
	}
	else
	{
		for(i=0;i<numPrimitives;i++,p++,iPtr++)
		{
//			Scalar s = p->DistanceTo(u);

//			*iPtr = !Get_Sign_Bit(s);

			*iPtr = (p->DistanceTo(u) >= 0.0f) ? (unsigned char)1: (unsigned char)0;
			
			ret += *iPtr;
		}

		visible = ret ? (unsigned char)1 : (unsigned char)0;
	}

	visible = ret ? (unsigned char)1 : (unsigned char)0;

	FindVisibleVertices();

	return ret;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRIndexedPolyMesh::ResetTestList()
{
	int i, numPrimitives = GetNumPrimitives();
	unsigned char *iPtr = &testList[0];

	for(i=0;i<numPrimitives;i++,iPtr++)
	{
		*iPtr = 1;
	}

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
	MLRIndexedPolyMesh::FindVisibleVertices()
{
	Check_Object(this);
	Verify(index.GetLength() > 0);

	int ret, i, j, k, stride, len = lengths.GetLength();

	Verify(index.GetLength() > 0);
	
	for(i=0,j=0,ret=0;i<len;i++)
	{
		stride = lengths[i];

		Verify(stride >= 3);

		if(testList[i] == 0)
		{
			j += stride;
			continue;
		}

		for(k=j;k<j+stride;k++)
		{
			visibleIndexedVertices[index[k]] = 1;
			ret++;
		}

		j += stride;
	}
	visibleIndexedVerticesKey = true;

	return ret;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRIndexedPolyMesh::Transform(Matrix4D *mat)
{
	Check_Object(this);

	Verify(index.GetLength() > 0);
	int i, len = coords.GetLength();

	if(visibleIndexedVerticesKey == false)
	{
		FindVisibleVertices();
	}

	for(i=0;i<len;i++)
	{
		if(visibleIndexedVertices[i] != 0)
		{
			transformedCoords[i].Multiply(coords[i], *mat);
#ifdef LAB_ONLY
			Statistics::MLR_TransformedVertices++;
#endif
		}
	}
	
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRIndexedPolyMesh::TransformNoClip(Matrix4D *mat, GOSVertexPool *vt)
{
	Check_Object(this);
	Check_Object(vt);
	Verify(index.GetLength() > 0);

	SET_MLRIndexedPolyMesh_CLIP();

	unsigned short stride;
	int i, j, k, len = lengths.GetLength();
	gos_vertices = vt->GetActualVertexPool();
	numGOSVertices = 0;

	Verify(index.GetLength() > 0);
	
	k = visibleIndexedVertices.GetLength();

	if(visibleIndexedVerticesKey == false)
	{
		FindVisibleVertices();
	}

	for(j=0,stride=0;j<k;j++)
	{
		if(visibleIndexedVertices[j] == 0)
		{
			stride++;
		}
		else
		{
			visibleIndexedVertices[j] = stride;

			transformedCoords[j].Multiply(coords[j], *mat);

#ifdef LAB_ONLY
			Statistics::MLR_TransformedVertices++;
#endif

//
//--------------------------------------------------------
// JM claims all vertices are in. lets check it. who knows
//--------------------------------------------------------
//
			Verify(transformedCoords[j].x >= 0.0f && transformedCoords[j].x <= transformedCoords[j].w );
			Verify(transformedCoords[j].y >= 0.0f && transformedCoords[j].y <= transformedCoords[j].w );
			Verify(transformedCoords[j].z >= 0.0f && transformedCoords[j].z <= transformedCoords[j].w );
			GOSCopyData(
				&gos_vertices[numGOSVertices],
				transformedCoords.GetData(),
				actualColors->GetData(),
				texCoords.GetData(),
				j
			);
			numGOSVertices++;
		}
	}

	#ifdef LAB_ONLY
		Statistics::MLR_NonClippedVertices += numGOSVertices;
	#endif

	Check_Object(vt);
	vt->Increase(numGOSVertices);

	gos_indices = vt->GetActualIndexPool();
	numGOSIndices = 0;

	for(i=0,j=0;i<len;i++)
	{
		stride = lengths[i];

		Verify(stride >= 3);

		if(testList[i] == 0)
		{
			j += stride;
			continue;
		}

		for(k=1;k<stride-1;k++)
		{
			Verify((vt->GetLastIndex() + 3 + numGOSIndices) < vt->GetLength());

			gos_indices[numGOSIndices] = (unsigned short)(index[j] - visibleIndexedVertices[index[j]]);
			gos_indices[numGOSIndices+1] = (unsigned short)(index[j+k+1] - visibleIndexedVertices[index[j+k+1]]);
			gos_indices[numGOSIndices+2] = (unsigned short)(index[j+k] - visibleIndexedVertices[index[j+k]]);

			numGOSIndices += 3;
		}
		j += stride;
	}
	Check_Object(vt);
	vt->IncreaseIndex(numGOSIndices);

	visible = numGOSVertices ? 1 : 0;
	CLEAR_MLRIndexedPolyMesh_CLIP();
}

static MLRClippingState theAnd, theOr, theTest;
static int clipTrick[6][2] = {
	{ 1, 1},
	{ 1, 0},
	{ 0, 1},
	{ 0, 0},
	{ 2, 0},
	{ 2, 1}
};

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Now it gets serious
int
	MLRIndexedPolyMesh::Clip(MLRClippingState clippingFlags, GOSVertexPool *vt)
{
	StartCycleTiming( &Statistics::MLR_ClipTime );
	SET_MLRIndexedPolyMesh_CLIP();

	Check_Object(this);

	unsigned short stride, l;
	int i, j, k, ret = 0;
	int len = lengths.GetLength();

	Verify(len == testList.GetLength());
	Verify(clippingFlags.GetClippingState() != 0);

	//
	//--------------------------------------
	// See if we don't have to draw anything
	//--------------------------------------
	//
	if(len <= 0)
	{
		visible = 0;

		CLEAR_MLRIndexedPolyMesh_CLIP();
		EndCycleTiming( &Statistics::MLR_ClipTime );

		return visible;
	}

	int mask, end, k0, k1, ct=0;
	Scalar a=0.0f;
//	Scalar bc0=0.0f, bc1=0.0f;

	int	myNumberUsedClipVertex, myNumberUsedClipIndex, myNumberUsedClipLength;

	myNumberUsedClipVertex = 0;
	myNumberUsedClipIndex = 0;
	myNumberUsedClipLength = 0;

	Verify(index.GetLength() > 0);
	
	if(visibleIndexedVerticesKey == false)
	{
		FindVisibleVertices();
	}

	//
	//------------------------
	// Handle the indexed case
	//------------------------
	//

	//
	//-----------------------------------------------------------------
	// Step through each vertex and check visibility
	// backfaced polygons
	//-----------------------------------------------------------------
	//
	k = transformedCoords.GetLength();
	Stuff::Vector4D *v4d = transformedCoords.GetData();
	MLRClippingState *cs = clipPerVertex.GetData();

 	for(i=0;i<k;i++,v4d++,cs++)
	{
		if(visibleIndexedVertices[i] == 0)
		{
			continue;
		}

		cs->SetClippingState(0);

		if( clippingFlags.IsFarClipped() && v4d->w < v4d->z)
		{
			cs->SetFarClip();
		}

		if( clippingFlags.IsNearClipped() && v4d->z < 0.0f)
		{
			cs->SetNearClip();
		}

		if( clippingFlags.IsRightClipped() && v4d->x < 0.0f)
		{
			cs->SetRightClip();
		}

		if( clippingFlags.IsLeftClipped() && v4d->w < v4d->x)
		{
			cs->SetLeftClip();
		}

		if( clippingFlags.IsBottomClipped() && v4d->y < 0.0f)
		{
			cs->SetBottomClip();
		}

		if(clippingFlags.IsTopClipped() && v4d->w < v4d->y)
		{
			cs->SetTopClip();
		}

#ifdef LAB_ONLY
		if( (*cs)==0)
		{
			Statistics::MLR_NonClippedVertices++;
		}
		else
		{
			Statistics::MLR_ClippedVertices++;
		}
#endif
	}

	//	initialize visibleIndexedVertices
	memset(visibleIndexedVertices.GetData(), 0, visibleIndexedVertices.GetSize());

	//
	//-----------------------------------------------------------------
	// Step through each polygon, making sure that we don't try to clip
	// backfaced polygons
	//-----------------------------------------------------------------
	//
	for(i=0,j=0;i<len;i++)
	{
		stride = lengths[i];

		if(testList[i] == 0)
		{
			j += stride;
			continue;
		}

		//
		//---------------------------------------------------------------
		// Test each vertex of the polygon against the allowed clipping
		// planes, and accumulate status for which planes always clip and
		// which planes clipped at least once
		//---------------------------------------------------------------
		//
		theAnd.SetClippingState(0x3f);
		theOr.SetClippingState(0);
		end = j+stride;
		
		for(k=j;k<end;k++)
		{
			theAnd &= clipPerVertex[index[k]];

			theOr |= clipPerVertex[index[k]];
		}

		theAnd = theOr = 0;		//ASSUME NO CLIPPING NEEDED FOR MC2.  Its just not done here!

		//
		//-------------------------------------------------------------------
		// If any bit is set for all vertices, then the polygon is completely
		// outside the viewing space and we don't have to draw it.  On the
		// other hand, if no bits at all were ever set, we can do a trivial
		// accept of the polygon
		//-------------------------------------------------------------------
		//
		if (theAnd != 0)
		{
			testList[i] = 0;
#ifdef LAB_ONLY
			Statistics::MLR_PolysClippedButOutside++;
#endif
		}
		else if (theOr == 0)

⌨️ 快捷键说明

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