/****************************************************************************************

		I3DShConstraint.h

		Copyright: (c) 2001 Eovia Corp. All rights reserved.

		I3DShConstraint definition

		Author:	Ray Dream
		Date:	3/2/98

		Revision History

		when		who			what & why
		==========	==========	======================================================
		09/09/99	Guillaume	Changed the name of both class and file (old I3dShLink)

*****************************************************************************************/

#ifndef __I3DSHCONSTRAINT__
#define __I3DSHCONSTRAINT__

#if CP_PRAGMA_ONCE
#pragma once
#endif

#include "APITypes.h"
#include "MCCompObj.h"
#include "I3dExConstraint.h"

//****** Globally Unique Ids *************************************************

MCDEFINE_GUID(IID_I3DShConstraint, 0x7b481580, 0x3f31, 0x11d1, 0xa0, 0x9f, 0x0, 0xaa, 0x0d, 0x3, 0x7e, 0xb);

//****************************************************************************

/// \addtogroup ShellInterface
/// \{

/// Constraints provide constraints between Tree Elements. A constraint, known as a link in RDS,
/// defines motion links between Tree Elements. It allows you to define "mechanical" constrains (degrees of freedom)
/// between one Tree Element and its father.
///
/// <P>There are two interfaces to access a constraint: The shell interface (I3DShConstraint) and
/// the external interface (I3DExConstraint) . You can get one from the other using QueryInterface.</P>
///
/// <P>You should use the Shell interface (I3DShConstraint) to access the component
/// because the Shell will make sure that the parameter map of the external component is valid.
/// This is especially important if the component is animated. For more information on components
/// see the Overview of the SDK.</P>
///
/// \see I3DExConstraint
///
struct I3DShConstraint: public IMCUnknown
{
	// ****************************************************************************
	//								GetNbrFreedom
	// 
	/// Returns the number of degrees of freedom. Because the freedom value can be limited,
	/// you have to give the range of values. This range is defined as a range of increment/decrement
	/// around the value.
	/// 
	virtual int16	MCCOMAPI	GetNbrFreedom			() const  = 0;
	
	// ****************************************************************************
	//								IncrementFreedomValue
	// 
	/// Modify the value of a degree of freedom by adding an increment
	///
	/// \param index The degree of freedom \see EFreedomDegree
	/// \param increment The increment value
	///
	virtual MCCOMErr MCCOMAPI	IncrementFreedomValue	(int16 index, real& increment) = 0;
	
	// ****************************************************************************
	//								GetMotionLimit
	// 
	/// Returns the constraint for a given degree of freedom.
	/// 
	/// \param index  
	/// \param limit  
	/// 
	virtual MCCOMErr MCCOMAPI	GetMotionLimit			(int16 index, ELimitType& limit) const = 0;
	
	// ****************************************************************************
	//								GetFreedomRange
	// 
	/// Returns the maximum range of increment and decrement for a given degree of freedom.
	///
	/// \param index The index of the degree of freedom
	/// \param min The minimum value
	/// \param max The maximum value
	/// 
	virtual MCCOMErr MCCOMAPI	GetFreedomRange			(int16 index, real& min, real& max) const = 0;

	/// Get the current value of the given freedom
	///
	/// \param index	The degree of freedom \see EFreedomDegree
	/// \param outValue The value of the freedom
	///
	virtual MCCOMErr MCCOMAPI	GetFreedomValue(int16 index, real& outValue) const = 0;
		
	// ****************************************************************************
	//								GetTransformPartialDerivate
	// 
	/// To allow the inverse kinematics mechanism to work with a constraint, implement the
	/// GetTransfromPartialDerivate() function. A partial derivative transformation is a transformation
	/// where each element is derived by a freedom degree.
	///
	/// \param index The degree of freedom used to derivate the transform.
	/// \param transform The partial derivative of the transform.
	/// 
	virtual MCCOMErr MCCOMAPI	GetTransformPartialDerivate			(int16 index, TTransform3D& transform) const = 0;
	
	// ****************************************************************************
	//								GetTransformSecondPartialDerivative
	// 
	/// Returns the second order partial derivative of the transform. A partial derivative
	/// transformation is a transformation where each element is derived by a freedom degree.
	///
	/// \param index1 The first degree of freedom used to derivate the transform.
	/// \param index2 The second degree of freedom used to derivate the transform.
	/// \param transform The partial derivative of the transform.
	///
	virtual MCCOMErr MCCOMAPI	GetTransformSecondPartialDerivative (int16 index1, int16 index2, TTransform3D& transform) const = 0;
	
	///Returns the order used to apply the different rotations
	virtual MCCOMErr MCCOMAPI	GetRotationsOrder	(EEulerAnglesOrder& outOrder) const = 0;

	///Fix for the axis constraint that rotates its Gimbal coordinates.
	virtual MCCOMErr MCCOMAPI	GetGimbalToLocalRotation	(TMatrix33& outRotation) const = 0;

	///Returns tue if the gimbal mode is allowed for the constraint
	virtual boolean	MCCOMAPI	CanUseGimbalRotation() const = 0;

	// ****************************************************************************
	//								GetTransform
	// 
	/// Returns the rotation matrix and translation vector due to the freedom values.
	/// \note When the freedom values are initialized the function GetTransform must return
	/// the identity matrix for the rotation and a null vector for the translation.
	///
	/// \param transform A reference to a transform.
	/// 
	virtual MCCOMErr MCCOMAPI	GetTransform			(TTransform3D& transform) const = 0;

	// ****************************************************************************
	//								SetTransform
	// 
	/// Sets the transformation matrix.
	/// 
	/// \param transform  
	/// 
	virtual MCCOMErr MCCOMAPI	SetTransform			(TTransform3D& transform) = 0;

	///Returns true is the external constraint is an I3DExNewConstraint
	virtual boolean  MCCOMAPI	IsNewConstraint			() const = 0;
};

/// \}

#endif