//////////////////////////////////////////////////////////////////////////////////////////
//
// FILE : Asura_Dynamic_Extents.cpp
//
// AUTHORS : Martin G. Harris
//
// Copyright (C) 2003 Rebellion, All Rights Reserved.
//
//////////////////////////////////////////////////////////////////////////////////////////

//////////////
// Includes //
//////////////

#include "Core/Asura.h"

#include "Entity/PhysicalObject/Asura_Dynamic_Extents.h"

#include "Debugging/Asura_Assert.h"
#include "Dynamics/Asura_Collision_Object.h"
#include "Entity/PhysicalObject/Asura_ServerEntity_PhysicalObject.h"
#include "Shapes/Asura_Shape_System.h"

///////////////////////////////////////////////////
// Default collision box if no other is defined. //
///////////////////////////////////////////////////
static const Asura_Collision_Box g_xDefaultBox(-0.3f, 0.3f, -1.8f, 0.0f, -0.3f, 0.3f);

///////////////////////////
// Asura_Dynamic_Extents //
///////////////////////////
Asura_Dynamic_Extents::PFN_Extents_Handler Asura_Dynamic_Extents::s_pfnProjectHandler = NULL;

///////////////////////////////////////////////////////////////////////////////////
// GetCollisionObject: Return the collision object according to the given index. //
///////////////////////////////////////////////////////////////////////////////////
const Asura_Collision_Object* Asura_Dynamic_Extents::GetCollisionObject(int iIndex, Asura_Hash_ID uShapeHash, Asura_Guid uGuid)
{
	const Asura_Collision_Object*	pxCollisionObject;

	// Do we have a project-specific handler?
	if(s_pfnProjectHandler == NULL)
	{
		pxCollisionObject	= NULL;
	}
	else
	{
		pxCollisionObject	= s_pfnProjectHandler(iIndex, uShapeHash, uGuid);
	}
	
	// Do we need to check the shape?
	if(pxCollisionObject == NULL)
	{
		pxCollisionObject	= GetCollisionObjectForShape(uShapeHash);
	}

	// Do we need to check the skins?
	if(pxCollisionObject == NULL)
	{
		pxCollisionObject	= GetCollisionObjectForEntity(uGuid);
	}

	// Did we find a collision-mesh?
	if(pxCollisionObject == NULL)
	{
		return(&g_xDefaultBox);
	}
	else
	{
		return(pxCollisionObject);
	}
}

/////////////////////////////////////////////////////////
// Set a handler to return project specific box sizes. //
/////////////////////////////////////////////////////////
void Asura_Dynamic_Extents::SetExtentsHandler(PFN_Extents_Handler pfnHandler)
{
	s_pfnProjectHandler = pfnHandler;
}

///////////////////
// GetDefaultBox //
///////////////////
const Asura_Collision_Object* Asura_Dynamic_Extents::GetDefaultBox()
{
	return &g_xDefaultBox;
}


////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_Dynamic_Extents::GetCollisionObjectForShape
// Author       : Andy Tate
// Date         : 22-Feb-2007
////////////////////////////////////////////////////////////////////////////////

const Asura_Collision_Object* Asura_Dynamic_Extents::GetCollisionObjectForShape(const Asura_Hash_ID uShapeHash)
{
	if(uShapeHash == ASURA_HASH_ID_UNSET)
	{
		return(NULL);
	}
	else
	{
		const Asura_Shape*	pxShape	= Asura_Shape_System::GetShape(uShapeHash);

		// Use the shape collision-mesh...
		if(pxShape == NULL)
		{
			return(NULL);
		}
		else
		{
			return(pxShape->GetDynamicsCollisionData());
		}
	}
}

/// End of function 'Asura_Dynamic_Extents::GetCollisionObjectForShape'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Asura_Dynamic_Extents::GetCollisionObjectForEntity
// Author       : Andy Tate
// Date         : 22-Feb-2007
////////////////////////////////////////////////////////////////////////////////

const Asura_Collision_Object* Asura_Dynamic_Extents::GetCollisionObjectForEntity(const Asura_Guid uGuid)
{
	const Asura_ServerEntity_PhysicalObject*	pxEntity	= Asura_ServerEntity_PhysicalObject::FindEntity(uGuid);

	if(pxEntity == NULL)
	{
		return(NULL);
	}
	else
	{
		const Asura_Hash_ID	uSkinHash	= pxEntity->GetSkinID();

		if(uSkinHash == ASURA_HASH_ID_UNSET)
		{
			return(NULL);
		}
		else
		{
			Asura_Hierarchy_Skin*	pxSkin	= Asura_Animation_System::GetSkinByHash(uSkinHash);

			// Use the skin collision-mesh...
			if(pxSkin == NULL)
			{
				return(NULL);
			}
			else
			{
#if defined(ASURA_TOOLS)
				if(pxSkin->m_pxSectionBoundingBoxData == NULL)
				{
					pxSkin->InitSectionBoundingBoxes();
				}
#endif	// defined(ASURA_TOOLS)

				return(pxSkin->GetCollisionObject());
			}
		}   
	}
}

/// End of function 'Asura_Dynamic_Extents::GetCollisionObjectForEntity'. ///


/// End of file. ///
