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

📄 mlrshape.cpp

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

#include "MLRHeaders.hpp"

//#############################################################################
//###############################    MLRShape    ##################################
//#############################################################################

MLRShape::ClassData*
	MLRShape::DefaultData = NULL;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRShape::InitializeClass()
{
	Verify(!DefaultData);
	Verify(gos_GetCurrentHeap() == StaticHeap);
	DefaultData =
		new ClassData(
			MLRShapeClassID,
			"MidLevelRenderer::MLRShape",
			Plug::DefaultData
		);
	Register_Object(DefaultData);
}

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

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRShape::MLRShape(
	MemoryStream *stream,
	int version
):
	Plug(DefaultData)
{ 
	Check_Pointer(this);
	Check_Object(stream);
	Verify(gos_GetCurrentHeap() == Heap);

	*stream >> numPrimitives;
	int i;

	allPrimitives.SetLength(numPrimitives);

	for(i=0;i<numPrimitives;i++)
	{
		MLRPrimitiveBase *pt = NULL;
		switch(version)
		{
			case 1:
			case 2:
			{
				STOP(("Lower than version 3 is not supported anymore !"));
/*
				MLRPrimitive *pt_old;

				RegisteredClass::ClassID class_id;
				*stream >> class_id;
				MLRPrimitive::ClassData* class_data =
					Cast_Object(MLRPrimitive::ClassData*, FindClassData(class_id));
				pt_old = (*class_data->primitiveFactory)(stream, version);
				Register_Object(pt_old);

				int i, nr, test;

				if(pt_old->GetReferenceState().GetLightingMode() == MLRState::LightingOffMode)
				{
					test = 0;
				}
				else
				{
					test = 2;
				}

#if COLOR_AS_DWORD
				DWORD* colors;
#else
				RGBAColor *colors, testColor(1.0f, 1.0f, 1.0f, 1.0f);
#endif
				Cast_Pointer(MLRIndexedPolyMesh*, pt_old)->GetColorData(&colors, &nr);

				for(i=0;i<nr;i++)
				{
#if COLOR_AS_DWORD
					if(colors[i] != 0xffffffff)
#else
					if(colors[i] != testColor)
#endif
					{
						break;
					}
				}
				if(i<nr)
				{
					test |= 1;
				}

				switch (test)
				{
					case 0:
						pt = new MLR_I_PMesh;

						Cast_Pointer(MLR_I_PMesh*, pt)->Copy(Cast_Pointer(MLRIndexedPolyMesh*, pt_old));
					break;
					case 1:
						pt = new MLR_I_C_PMesh;

						Cast_Pointer(MLR_I_C_PMesh*, pt)->Copy(Cast_Pointer(MLRIndexedPolyMesh*, pt_old));
					break;
					default:
						pt = new MLR_I_L_PMesh;

						Cast_Pointer(MLR_I_L_PMesh*, pt)->Copy(Cast_Pointer(MLRIndexedPolyMesh*, pt_old));
					break;
				}
				pt_old->DetachReference();
*/
			}
			break;
			default:
			{


				RegisteredClass::ClassID class_id;
				*stream >> class_id;
				MLRPrimitiveBase::ClassData* class_data =
					Cast_Pointer(MLRPrimitiveBase::ClassData*, FindClassData(class_id));
				Check_Object(class_data);
				pt = (*class_data->primitiveFactory)(stream, version);
				Register_Object(pt);

				if(
					ConvertToTriangleMeshes == true && (
						pt->IsDerivedFrom(MLR_I_PMesh::DefaultData) ||
						pt->IsDerivedFrom(MLR_I_C_PMesh::DefaultData) ||
						pt->IsDerivedFrom(MLR_I_L_PMesh::DefaultData)
					)
				)
				{
					unsigned char *length;
					int i, num, threes, nonThrees;

					pt->GetSubprimitiveLengths(&length, &num);

					for(i=0,threes=0,nonThrees=0;i<num;i++)
					{
						if(length[i]==3)
						{
							threes++;
						}
						else
						{
							nonThrees++;
						}
					}
					if(threes>0 && nonThrees==0)	//threes > 9*nonThrees)
					{
						MLRPrimitiveBase *pt_old = pt;
				
						if(pt->GetClassData() == MLR_I_L_PMesh::DefaultData)
						{
							pt = new MLR_I_L_TMesh;
							Register_Object(pt);

							Cast_Pointer(MLR_I_L_TMesh*, pt)->Copy(Cast_Pointer(MLR_I_L_PMesh*, pt_old));
						}
						else if(pt->GetClassData() == MLR_I_C_PMesh::DefaultData)
						{
							pt = new MLR_I_C_TMesh;
							Register_Object(pt);

							Cast_Pointer(MLR_I_C_TMesh*, pt)->Copy(Cast_Pointer(MLR_I_C_PMesh*, pt_old));
						}
						else if(pt->GetClassData() == MLR_I_PMesh::DefaultData)
						{
							pt = new MLR_I_TMesh;
							Register_Object(pt);

							Cast_Pointer(MLR_I_TMesh*, pt)->Copy(Cast_Pointer(MLR_I_PMesh*, pt_old));
						}
						else if(pt->GetClassData() == MLR_I_L_DT_PMesh::DefaultData)
						{
							pt = new MLR_I_L_DT_TMesh;
							Register_Object(pt);

							Cast_Pointer(MLR_I_L_DT_TMesh*, pt)->Copy(Cast_Pointer(MLR_I_L_DT_PMesh*, pt_old));
						}
						else if(pt->GetClassData() == MLR_I_C_DT_PMesh::DefaultData)
						{
							pt = new MLR_I_C_DT_TMesh;
							Register_Object(pt);

							Cast_Pointer(MLR_I_C_DT_TMesh*, pt)->Copy(Cast_Pointer(MLR_I_C_DT_PMesh*, pt_old));
						}
						else if(pt->GetClassData() == MLR_I_DT_PMesh::DefaultData)
						{
							pt = new MLR_I_DT_TMesh;
							Register_Object(pt);

							Cast_Pointer(MLR_I_DT_TMesh*, pt)->Copy(Cast_Pointer(MLR_I_DT_PMesh*, pt_old));
						}
						else if(pt->GetClassData() == MLR_I_L_DeT_PMesh::DefaultData)
						{
							pt = new MLR_I_L_DeT_TMesh;
							Register_Object(pt);

							Cast_Pointer(MLR_I_L_DeT_TMesh*, pt)->Copy(Cast_Pointer(MLR_I_L_DeT_PMesh*, pt_old));
						}
						else if(pt->GetClassData() == MLR_I_C_DeT_PMesh::DefaultData)
						{
							pt = new MLR_I_C_DeT_TMesh;
							Register_Object(pt);

							Cast_Pointer(MLR_I_C_DeT_TMesh*, pt)->Copy(Cast_Pointer(MLR_I_C_DeT_PMesh*, pt_old));
						}
						else if(pt->GetClassData() == MLR_I_DeT_PMesh::DefaultData)
						{
							pt = new MLR_I_DeT_TMesh;
							Register_Object(pt);

							Cast_Pointer(MLR_I_DeT_TMesh*, pt)->Copy(Cast_Pointer(MLR_I_DeT_PMesh*, pt_old));
						}
						pt_old->DetachReference();
					}
				}
			}
			break;
		}

		allPrimitives[i] = pt;
	}

	referenceCount = 1;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRShape::MLRShape(int nr):
	Plug(DefaultData), allPrimitives(nr ? nr : 4)
{ 
	Verify(gos_GetCurrentHeap() == Heap);
	numPrimitives = 0;
	referenceCount = 1;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRShape::~MLRShape()
{
	int i;
	MLRPrimitiveBase *pt;

	for(i=numPrimitives-1;i>=0;i--)
	{
		pt = allPrimitives[i];
		allPrimitives[i] = NULL;

		pt->DetachReference();

	}

	Verify(referenceCount==0);
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRShape*
	MLRShape::Make(
		MemoryStream *stream,
		int version
	)
{
	Check_Object(stream);

	gos_PushCurrentHeap(Heap);
	MLRShape *shape = new MLRShape(stream, version);
	gos_PopCurrentHeap();

	return shape;
}

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

	*stream << numPrimitives;

	int i;

	for(i=0;i<numPrimitives;i++)
	{
		Check_Object(allPrimitives[i]);
		allPrimitives[i]->Save(stream);
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRShape::Add (MLRPrimitiveBase *p)
{
	Check_Object(this); 

	if(numPrimitives >= allPrimitives.GetLength() || allPrimitives.GetLength() == 0)
	{
		gos_PushCurrentHeap(Heap);
		allPrimitives.SetLength(numPrimitives + 4);
		gos_PopCurrentHeap();
	}

	allPrimitives[numPrimitives] = p;
	p->AttachReference();

	numPrimitives++;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
	MLRShape::GetNumPrimitives()
{
	int i, ret = 0;

	for(i=0;i<numPrimitives;i++)
	{
		Check_Object(allPrimitives[i]);
		ret += allPrimitives[i]->GetNumPrimitives();
	}

	return ret;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
	MLRShape::GetNumDrawnTriangles()
{
	int i, j, ret = 0;

	for(i=0;i<numPrimitives;i++)
	{
		Check_Object(allPrimitives[i]);
		if(allPrimitives[i]->IsDerivedFrom(MLRIndexedPrimitiveBase::DefaultData))
		{
			j = (Cast_Pointer(MLRIndexedPrimitiveBase*, allPrimitives[i]))->GetNumGOSIndices();
		}
		else
		{
			j = allPrimitives[i]->GetNumGOSVertices();
		}
		if(j!=0xffff)
		{
			ret += j;
		}
	}

	return ret;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRPrimitiveBase*
	MLRShape::Find (int i)
{
	Check_Object(this); 

	Verify(i<numPrimitives);

	return allPrimitives[i];
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
	MLRShape::Find (MLRPrimitiveBase *p)
{
	Check_Object(this); 
	Check_Object(p);

	int i;

	for(i=0;i<numPrimitives;i++)
	{
		Check_Object(allPrimitives[i]); 

		if(allPrimitives[i] == p)
		{
			return i;
		}
	}

	return -1;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MLRShape::Replace (MLRPrimitiveBase *pout, MLRPrimitiveBase *pin)
{
	Check_Object(this); 
	Check_Object(pout);
	Check_Object(pin);

	int num = Find (pout);

	if(num>=0)
	{
		pout->DetachReference();
		allPrimitives[num] = pin;
		pin->AttachReference();
	}
	else
	{
		return false;
	}

	return true;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRPrimitiveBase*
	MLRShape::Remove(MLRPrimitiveBase *p)
{
	Check_Object(this); 
	Check_Object(p);

	int i, nr = Find(p);

	if(nr < 0)
	{
		return NULL;
	}

	for(i=nr;i<numPrimitives-1;i++)
	{
		allPrimitives[i] = allPrimitives[i+1];
	}

	allPrimitives[i] = NULL;

	numPrimitives--;
	p->DetachReference();

	return p;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRPrimitiveBase*
	MLRShape::Remove(int nr)
{
	Check_Object(this); 

	int i;
	MLRPrimitiveBase *p = Find(nr);

	if(nr < 0 || nr >= numPrimitives)
	{
		return NULL;
	}

	for(i=nr;i<numPrimitives-1;i++)
	{
		allPrimitives[i] = allPrimitives[i+1];
	}

	allPrimitives[i] = NULL;

	numPrimitives--;
	p->DetachReference();

	return p;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
 	MLRShape::Insert(MLRPrimitiveBase *p, int nr)
{
	Check_Object(this); 

	if(nr >= numPrimitives)
	{
		Add(p);

		return numPrimitives;
	}

	if(numPrimitives >= allPrimitives.GetLength() || allPrimitives.GetLength() == 0)
	{
		gos_PushCurrentHeap(Heap);
		allPrimitives.SetLength(numPrimitives + 4);
		gos_PopCurrentHeap();
	}


	int i;

	for(i=numPrimitives;i>nr;i--)
	{
		allPrimitives[i] = allPrimitives[i-1];
	}

	allPrimitives[i] = p;
	p->AttachReference();

	numPrimitives++;

	return numPrimitives;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRShape::InitializePrimitives(unsigned char vis, const MLRState& master, int parameter)
{
	Check_Object(this); 

	int i;

	for(i=0;i<numPrimitives;i++)
	{
		Check_Object(allPrimitives[i]);

		allPrimitives[i]->InitializeDrawPrimitive(vis, parameter);
		
		allPrimitives[i]->CombineStates(master);
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// p is the eye point
void
	MLRShape::HurtMe(const Stuff::LinearMatrix4D& pain, Stuff::Scalar radius)
{
	for(int i=0;i<numPrimitives;i++)
	{
		Check_Object(allPrimitives[i]);

		allPrimitives[i]->HurtMe(pain, radius);
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// p is the eye point
int
	MLRShape::FindBackFace(const Point3D& p)
{
	Check_Object(this); 

	int i, ret = 0;

	Point3D sp;
	
	sp.Multiply(p, *worldToShape);

	for(i=0;i<numPrimitives;i++)
	{
		Check_Object(allPrimitives[i]);

		ret += allPrimitives[i]->FindBackFace(sp);
	}

	return ret;
}

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

	 int i;

	for(i=0;i<numPrimitives;i++)
	{
		Check_Object(allPrimitives[i]);

		allPrimitives[i]->Transform(mat);
	}
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRShape::Transform()
{
	Check_Object(this); 

	 int i;

	for(i=0;i<numPrimitives;i++)
	{
		Check_Object(allPrimitives[i]);

		allPrimitives[i]->Transform(&shapeToClipMatrix);
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
	MLRShape::Clip(MLRClippingState clippingFlags, GOSVertexPool *vp)
{
	Check_Object(this); 

	int i, ret = 0;

	gos_GetViewport( &ViewportScalars::MulX, &ViewportScalars::MulY, &ViewportScalars::AddX, &ViewportScalars::AddY );

	for(i=0;i<numPrimitives;i++)
	{
		Check_Object(allPrimitives[i]);

		ret += allPrimitives[i]->Clip(clippingFlags, vp);
	}

	return ret;
}
*/

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRShape::Lighting (
		const LinearMatrix4D& WorldToShape, 
		MLRLight* const* lights,
		int nrLights
	)
{
	Check_Object(this);
	Check_Object(&WorldToShape);

	if(nrLights == 0)
	{
		return;
	}

	int i;

	for(i=0;i<nrLights;i++)
	{
		lights[i]->SetLightToShapeMatrix(WorldToShape);
	}

	for(i=0;i<numPrimitives;i++)
	{
		Check_Object(allPrimitives[i]);

		allPrimitives[i]->Lighting(lights, nrLights);
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MLRShape::CastRay (
		Line3D *line,
		Normal3D *normal
	)
{
	Check_Object(this);
	Check_Object(line);
	Check_Pointer(normal);

	bool result = false;
	for(int i=0; i<numPrimitives; i++)
	{
		Check_Object(allPrimitives[i]);
		if (allPrimitives[i]->CastRay(line, normal))
			result = true;
	}
	return result;
}

⌨️ 快捷键说明

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