
///////////////////////////////////////////////////////////////////////////////
//
// File   : Asura_Animation_IK_Chain_MarkerPoint.cpp
// Author : Will Plano
// Date   : 24/08/2007
//
// Copyright (C) 2007 Rebellion, All Rights Reserved.
//
///////////////////////////////////////////////////////////////////////////////

#include "Core/Asura.h"

#ifdef ASURA_USE_ANIMATION_IK_SOLVER

#include "Core/Asura_Maths.h"

#include "Animation/IK/Asura_Animation_IK_Chain_MarkerPoint.h"

#include "Animation/Asura_Animation.h"
#include "Animation/IK/Asura_Animation_IK_Link.h"
#include "Debugging/Asura_DebugLineRender.h"
#include "Interface/Asura_CommandConsole.h"

DVSVAR bool  g_bRenderDebugInfo = false;

#if defined(ASURA_SUPPORT_COMMAND_CONSOLE) && defined(ASURA_DEBUG_VARIABLE_SYSTEM)
void Asura_Animation_IK_Chain_MarkerPoint::AddConsoleVars()
{
#if !defined(ASURA_NO_DEBUG_OUTPUT)
	Asura_CommandConsole::AddVar( L"IK.RenderMPDebugInfo", &g_bRenderDebugInfo, Asura_CommandConsole::REMOVE_AT_SHUTDOWN );
#endif
}
#endif

//////////////////////////////////////////////////////////////////////////
// class Asura_Animation_IK_Chain_MarkerPoint
//////////////////////////////////////////////////////////////////////////

Asura_Animation_IK_Chain_MarkerPoint::Asura_Animation_IK_Chain_MarkerPoint( const u_int uNumBones /* = 0 */, const u_int uMarkerPointHash /* = 0 */, const Asura_Animation* pxAnim /* = NULL */, bool bUseOri /*= false*/ )
: PARENT( uNumBones )
, m_uMarkerPointHash( uMarkerPointHash )
, m_pxAnim( pxAnim )
, m_bUseOri( bUseOri )
, m_bAddOriOffset( false )
{

}

Asura_Animation_IK_Chain_MarkerPoint::Asura_Animation_IK_Chain_MarkerPoint( const int* piBoneIDs, const int* piTwistBoneIDs /* = NULL */, const u_int uMarkerPointHash /* = 0 */, const Asura_Animation* pxAnim /* = NULL */, bool bUseOri /*= false */ )
: PARENT( piBoneIDs, piTwistBoneIDs )
, m_uMarkerPointHash( uMarkerPointHash )
, m_pxAnim( pxAnim )
, m_bUseOri( bUseOri )
, m_bAddOriOffset( false )
{

}

Asura_Animation_IK_Chain_MarkerPoint::~Asura_Animation_IK_Chain_MarkerPoint()
{

}
void Asura_Animation_IK_Chain_MarkerPoint::SetMatrixOffset( Asura_Matrix_3x3& xOriOffset )
{
	m_bAddOriOffset = true;
	m_xOriOffset = xOriOffset;
}

bool Asura_Animation_IK_Chain_MarkerPoint::CalculateTarget()
{
	Asura_Vector_3 xPos;
	Asura_Matrix_3x3 xOri;
	if ( !m_pxAnim )
	{
		Asura_Assert( false, "No anim for getting marker point location." );
		return false;
	}
	bool bOK = m_pxAnim->GetMarkerLocationFromHash( m_uMarkerPointHash, &xPos, &xOri, true );
	if ( bOK )
	{
		if( m_bAddOriOffset )
		{
			xOri = xOri*m_xOriOffset;
		}

		m_xTargetPosition = xPos;
		if ( m_bUseOri )
		{
			Asura_Quat xInvEndOri = m_pxLastLink->GetAnimQuat();
			xInvEndOri.Invert();
			m_xTargetOrientationDelta = Asura_Quat( xOri ) * xInvEndOri;
		}
#ifndef ASURA_NO_DEBUG_OUTPUT
		if ( g_bRenderDebugInfo )
		{
			Asura_DebugLineRender::AddLine( m_xTargetPosition - Asura_AVector3( 0.1f, 0.0f, 0.0f ), m_xTargetPosition + Asura_AVector3( 0.1f, 0.0f, 0.0f ), 0xFF00FF00 );
			Asura_DebugLineRender::AddLine( m_xTargetPosition - Asura_AVector3( 0.0f, 0.1f, 0.0f ), m_xTargetPosition + Asura_AVector3( 0.0f, 0.1f, 0.0f ), 0xFF00FF00 );
			Asura_DebugLineRender::AddLine( m_xTargetPosition - Asura_AVector3( 0.0f, 0.0f, 0.1f ), m_xTargetPosition + Asura_AVector3( 0.0f, 0.0f, 0.1f ), 0xFF00FF00 );
		}
#endif
	}
	return bOK;
}

#endif // ASURA_USE_ANIMATION_IK_SOLVER
