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

		I3DExPoserSkinningAlgorithm.h
		Copyright: (c) 2007 DAZ Productions. All rights reserved.

		Author:	Eric
		Date:	5/7/2007

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

#ifndef __I3DExPoserSkinningAlgorithm__
#define __I3DExPoserSkinningAlgorithm__

#if CP_PRAGMA_ONCE
#pragma once
#endif

#include "MCCompObj.h"
#include "InterfaceIDs.h"
#include "I3DExVertexPrimitive.h"
#include "I3DExSkinningAlgorithm.h"

MCDEFINE_GUID_H(IID_I3DExPoserSkinningAlgorithm);



struct IPoserJointParam : public IMCUnknown
{
	enum EType
	{
		kRotationParam,
		kRotationTwistParam,
		kCurveParam,
		kSmoothScaleParam,
	};

	virtual EType		GetType() = 0;
	virtual int32		GetAxis() = 0;
	virtual boolean		IsFlipped() const = 0;
	virtual boolean		IsActive(boolean isChildren) const = 0;

	virtual boolean		UseSpheres() const = 0;
	virtual void		GetSpheres(TTransform3D& staticSphere, TTransform3D& dynamicSphere) const = 0;

	virtual boolean		UseAngles() const = 0;
	virtual void		GetAngles(float &staticA, float &dynamicB, float &dynamicC, float &staticD) const = 0;

	virtual boolean		UseBulges() const = 0;
	virtual void		GetBulges(float &posLeftBulge, float &posRightBulge, float &negLeftBulge, 
							float &negRightBulge) const = 0;

	virtual boolean		UseTwist() const = 0;
	virtual void		GetTwist(float &start, float &end) const = 0;

	virtual boolean		UseSmooth() const = 0;
	virtual void		GetSmooth(float &loEnd, float &loStart, float &hiStart, float &hiEnd) const = 0;

	virtual boolean		GetDeformParent() const = 0;

	virtual real32		GetWeight(const TVector3& position, real32* posBulgeWeight=NULL, real32* negBulgeWeight=NULL) = 0;		// the position is given in the joint local space


	// bulge are only supported for rotation joint
	virtual boolean		HasBulge() = 0;

	virtual void		Clone(IPoserJointParam** clone) = 0;
	virtual void		Write(IShTokenStream& stream) = 0;
	virtual void		Read(IShTokenStream& stream) = 0;
};

struct TJointSkinningData
{
	int32				fWeightCount;

	int32				fRotationWeight[3];
	int32				fSmoothScaleWeight;
	int32				fCurveWeight;
	boolean				fDoBulge;
	int32				fNegBulgeWeight[3];
	int32				fPosBulgeWeight[3];
};

struct I3DExPoserSkinningAlgorithm : public I3DExSkinningAlgorithm
{
	virtual void		SetJointBend(int32 jointIndex, boolean bend) = 0;
	virtual void		AddJointParam(int32 jointIndex, IPoserJointParam* jointParam) = 0;
	virtual void		ValidateJointParams() = 0;
	virtual void		ComputeWeights(I3DExVertexPrimitive* vertexPrimitive) = 0;
	virtual void		ComputeWeights(TVertexSkinInfo& vertexInfo, const TVector3& vertex) = 0;
	virtual void		GetGlobalOrigins(TMCArray<TVector3>& outOrigins) = 0;
	virtual void		GetJointReferenceTransform(int32 jointIndex, TTransform3D& outTransform) = 0;
	virtual void		GetJointSkinData(int32 jointIndex, TJointSkinningData& jointSkinningData) = 0;
	virtual boolean		GetJointBend(int32 jointIndex) = 0;
	virtual int32		GetJointCount() = 0;
	virtual IPoserJointParam*	GetRotationParam(int32 jointIndex, int32 axis) = 0;
	virtual IPoserJointParam*	GetScaleParam(int32 jointIndex) = 0;
	virtual IPoserJointParam*	GetCurveParam(int32 jointIndex) = 0;
	virtual void		SetJointSkinData(int32 jointIndex, const TJointSkinningData& jointSkinningData) = 0;
};

#endif