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

		I3DShModifier.h

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

		I3DShModifier definition

		Author:	Joshua
		Date:	09/25/98

		Revision History

		when		who			what & why
		==========	==========	======================================================
		09/28/99	Mathieu		GetMaxTimeWithoutComputation()
		08/10/99	Arnaud		FacetMesh is now counted.

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

#ifndef __I3DSHMODIFIER__
#define __I3DSHMODIFIER__

#if CP_PRAGMA_ONCE
#pragma once
#endif

#include "COMTypes.h"
#include "I3DShFacetMesh.h"

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

MCDEFINE_GUID(IID_I3DShModifier, 0x2706cd41, 0x54a8, 0x11d2, 0x88, 0x4c, 0x0, 0x60, 0x97, 0x14, 0x85, 0x21);

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

struct TDeformInfo;

/// \addtogroup ShellInterface
/// \{

/// I3DShModifier is the shell interface of a modifier.
///
/// <P>There are two interfaces to access a modifier: The shell interface (I3DShModifier) and
/// the external interface (I3DExModifier) . You can get one from the other using QueryInterface.</P>
///
/// <P>Whenever it is possible you should use the Shell interface (I3DShModifier) 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 I3DExModifier
///
struct I3DShModifier: public IMCUnknown
{
	// ****************************************************************************
	//								Apply
	// 
	/// Gives access to all the parameters of the tree the modifier is on. To implement
	/// a behavior, just change the transforms.
	///
	/// \param tree The tree to which the modifier is applied
	///
	virtual MCCOMErr	MCCOMAPI Apply							(I3DShTreeElement* tree) = 0;

	// ****************************************************************************
	//								GetMaxTimeWithoutComputation
	// 
	/// Tells the shell how much cached data the behavior has (starting at zero).
	///
	/// \param tree The tree to which the modifier is applied
	///
	virtual MicroTick	MCCOMAPI GetMaxTimeWithoutComputation	(I3DShTreeElement* tree) = 0;

	// ****************************************************************************
	//								IsIKTerminator
	// 
	/// Returns true if the modifier is an IK Terminator.
	/// \param outExcludeFromChain	Tells if the tree should be excluded from the chain.
	///
	virtual boolean		MCCOMAPI IsIKTerminator					(boolean& outExcludeFromChain) const = 0;

	// ****************************************************************************
	//								SetBoundingBox
	// 
	/// Is called by the 3D Shell to tell the 3D deformation modifier in which boundaries
	/// the 3D data to deform is going to be. This is the bounding box of the facet mesh
	/// before the deformation is applied.
	///
	/// \param bbox The Bounding Box
	///
	virtual void		MCCOMAPI SetBoundingBox	(const TBBox3D &bbox) = 0;

	// ****************************************************************************
	//								DeformPoint
	// 
	/// Computes result of the deformation of a given point (in local coordinates).
	/// DeformPoint is called by the shell if you do not implement DeformFacetMesh or DeformVertex3D
	/// (the shell will automatically subdivide the facet mesh to achieve a smooth deformation).
	///
	/// \param point The point that needs to be moved
	/// \param result The position of the point after deformation.
	///
	virtual void		MCCOMAPI DeformPoint	(const TVector3 & point,  TVector3 & result) = 0;
	
	// ****************************************************************************
	//								DeformVertex3D
	// 
	/// Computes the result of the deformation of a given vertex (in local coordinates).
	/// DeformVertex3D called by the 3D Shell if you do not implement DeformFacetMesh
	/// (the shell will automatically subdivide the facet mesh to achieve a smooth deformation).
	///
	/// \param vertex The vertex that needs to be moved
	/// \param result The vertex after deformation.
	///
	/// \return MC_S_OK if it is implemented, MC_E_NOTIMPL if not.
	///
	virtual void		MCCOMAPI DeformVertex3D	(const TVertex3D& vertex, TVertex3D& result) = 0;
	
	// ****************************************************************************
	//								DeformFacetMesh
	// 
	/// <P>Deforms or creates 3D facets. Given the original facet mesh of a primitive, 
	/// it  produces a (new) deformed mesh. You can modify whatever you want on the mesh:
	/// you can add or remove vertices, normals, facets, or change their position.</P>
	///
	/// <P>But you should NOT modify the in mesh. You need to create a new mesh and return
	/// it in outMesh (yet you can clone in to outMesh and then change outMesh). </P>
	///
	/// If the parameters of your deformer won't deform the mesh, you can have outMesh reference
	/// in thus:
	///
	/// \code
	/// TMCCountedGetHelper<FacetMesh> result(outMesh); result= in;
	/// \endcode
	///
	/// \param lod Level of detail (LOD) of the output mesh (0 is the best quality)
	/// \param in The facet mesh that needs to be deformed.
	/// \param outMesh The mesh after deformation
	///
	/// \return MC_S_OK if it is implemented, MC_E_NOTIMPL if not.
	///
	virtual void		MCCOMAPI DeformFacetMesh(real lod,FacetMesh* in, FacetMesh** outMesh) = 0;
	
	// ****************************************************************************
	//								DeformBBox
	// 
	/// Returns an approximation of how the modifier affects a given zone of space
	/// contained in the box in, and returns the box that encompass the deformed space in out.
	///
	/// \param in The bounding box before deformation (in local coordinates)
	/// \param out The bounding box after deformation (in local coordinates)
	///
	/// \return MC_S_OK if it is implemented, MC_E_NOTIMPL if not.
	///
	virtual void		MCCOMAPI DeformBBox		(const TBBox3D& in,TBBox3D& out) = 0;
	
	// ****************************************************************************
	//								GetNeededLOD
	// 
	/// Returns the level of detail the modifier needs to produce a result at the
	/// precision outputLOD.
	///
	/// \param outputLOD The desired output precision
	/// \param neededLod The necessary input precision to get that result.
	///
	virtual void		MCCOMAPI GetNeededLOD	(const real outputLOD, real &neededLod) = 0;
	
	// ****************************************************************************
	//								GetDeformerInfo
	// 
	/// Returns information about the modifier. If you implement only DeformPoint
	/// or DeformVertex3D and not DeformFacetMesh, use this function to give the shell
	/// some directions to guide the facet mesh subdivision process.
	///
	/// \param lod The level of detail
	/// \param deformInfo The deformer information.
	///
	virtual void		MCCOMAPI GetDeformerInfo(real lod, TDeformInfo& deformInfo) = 0;
	
	// ****************************************************************************
	//								GetNeededLOD2
	// 
	/// Returns the level of detail the modifier needs to produce a result at the
	/// precision outputLOD.
	///
	/// \param outputLOD The desired output precision
	/// \param neededLod The necessary input precision to get that result.
	///
	virtual boolean		MCCOMAPI GetNeededLOD2	(const real outputLOD, real &neededLod) = 0;

};

/// \}

#endif