// Mesh.cpp

#include <windows.h>
//#include <stdio.h>

#include "Types.h"
#include "Math.h"
#include "Misc.h"
#include "Object.h"
#include "Model.h"
#include "Box.h"
#include "Mesh.h"


extern CModel
	Model;


CMesh::CMesh()
{
	Obj = NULL;
	Used = NULL;

	NumVerts = 0;
	NumFaces = 0;
	NumNodes = 0;

	VertList = NULL;
	FaceList = NULL;
	NodeList = NULL;
}


CMesh::~CMesh()
{
	Obj = NULL;
	delete [] Used;
	Used = NULL;

	NumVerts = 0;
	NumFaces = 0;
	NumNodes = 0;

	delete [] VertList;
	delete [] FaceList;
	delete [] NodeList;

	VertList = NULL;
	FaceList = NULL;
	NodeList = NULL;
}


void CMesh::Object( const char *name )
{
	s32
		i;

	Obj = Model.Find( name );
	if (!Obj)
	{
		Error( "Cannot find object: '%s'", name );
		return;
	}


	Used = new s8[Obj->NumFaces];
	for (i=0; i<Obj->NumFaces; i++)
		Used[i] = FALSE;


	NumVerts = Obj->NumVerts;
	VertList = new CTwinVert[NumVerts];

	for (i=0; i<NumVerts; i++)
	{
		VertList[i].Set( 0, Obj->GetVert( 0, i ) );
		VertList[i].Set( 1, Obj->GetVert( 1, i ) );
	}
}


void CMesh::Tag( const char *name )
{
	CObject
		*obj;
	CBox
		box;
	SFace
		*face;
	s32
		i,
		j,
		count;

	if (!Obj)
		return;


	obj = Model.Find( name );
	if (!obj)
	{
		Error( "Cannot find object: '%s'", name );
		return;
	}

	box.Load( obj );


	for (i=0; i<Obj->NumFaces; i++)
	{
		face = Obj->GetFace( i );

		count = 0;
		for (j=0; j<3; j++)
		{
			if (box.ContainsPoint( Obj->GetVert( 0, face->vtx[j] )))
				count++;
		}

		if (count == 3)
			Used[i] = TRUE;
	}
}


void CMesh::UnTag( const char *name )
{
	CObject
		*obj;
	CBox
		box;
	SFace
		*face;
	s32
		i,
		j,
		count;

	if (!Obj)
		return;


	obj = Model.Find( name );
	if (!obj)
	{
		Error( "Cannot find object: '%s'", name );
		return;
	}

	box.Load( obj );


	for (i=0; i<Obj->NumFaces; i++)
	{
		face = Obj->GetFace( i );

		count = 0;
		for (j=0; j<3; j++)
		{
			if (box.ContainsPoint( Obj->GetVert( 0, face->vtx[j] )))
				count++;
		}

		if (count == 3)
			Used[i] = FALSE;
	}
}


void CMesh::TagAll()
{
	s32
		i;

	if (!Obj)
		return;


	for (i=0; i<Obj->NumFaces; i++)
		Used[i] = TRUE;
}


void CMesh::Grab()
{
	s32
		i,
		j;

	if (!Obj)
		return;


	NumFaces = 0;
	for (i=0; i<Obj->NumFaces; i++)
	{
		if (Used[i])
			NumFaces++;
	}


	FaceList = new SFace[NumFaces];
	j = 0;
	for (i=0; i<Obj->NumFaces; i++)
	{
		if (Used[i])
		{
			FaceList[j] = *Obj->GetFace( i );
			j++;
		}
	}
}


Vector3 *CMesh::GetVert( const s32 frame, const s32 index )
{
	return( VertList[index].Get( frame ) );
}
