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

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

		Author:	charles
		Date:	5/19/2006

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

#ifndef __I3DExRigidBodySolver__
#define __I3DExRigidBodySolver__

#if CP_PRAGMA_ONCE
#pragma once
#endif

#include "APITypes.h"
#include "IExtension.h"
#include "InterfaceIDs.h"
#include "RealQuatFwd.h"
#include "I3DExConstraint.h"


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

MCDEFINE_GUID_H(IID_I3DExPhysicsSolver); 

//****** Family Id *************************************************

const FourCharT kPhysicsSolverFamilyID = kRID_PhysicsSolverFamilyID;


struct Triangle;
struct I3DExForce;


struct I3DExGeometry : public IMCUnknown
{
	// ****************************************************************************
	//								SetVerticesAndFaces
	// 
	/// Sets the vertices and the triangles of the geometry.
	/// 
	/// \param vertices   
	/// \param triangles  
	/// 
	virtual void		MCCOMAPI SetVerticesAndFaces(TMCArray<TVector3>& vertices, TMCArray<Triangle>& triangles) = 0;

	virtual void		MCCOMAPI UpdateVertices(TMCArray<TVector3>& vertices) = 0;
};


struct I3DExPhysicForce : public IMCUnknown
{
};

struct I3DExPhysicsBody : public IMCUnknown
{
	virtual void		MCCOMAPI SetFrictionCoefficient(real frictionCoef) = 0;
	virtual void		MCCOMAPI SetBounciness(real bounce) = 0;
	virtual void		MCCOMAPI SetDensity(real density) = 0;

	virtual void		MCCOMAPI SetVelocity(const TVector3d& velocity) = 0;
	virtual void		MCCOMAPI SetAngularVelocity(const TVector3d& velocity) = 0;

	virtual void		MCCOMAPI ClearForces()=0;
	virtual void		MCCOMAPI AddForce(I3DExPhysicForce* const force)=0;

	virtual void		MCCOMAPI SetCollide(boolean collide) = 0;
};

struct I3DExRigidBody : public I3DExPhysicsBody
{
	// ****************************************************************************
	//								SetTransform
	// 
	/// Sets the position of the rigid body
	/// 
	/// \param position     The position of the rigid body.
	/// \param orientation  The translation of the rigid body.
	/// 
	virtual void		MCCOMAPI SetTransform(const TVector3d& position,const TUnitQuaterniond& orientation) = 0;

	// ****************************************************************************
	//								GetTransform
	// 
	/// Returns the position of the object.
	/// 
	/// \param position     
	/// \param orientation  
	/// 
	virtual void		MCCOMAPI GetTransform(TVector3d& position,TUnitQuaterniond& orientation) = 0;

	// ****************************************************************************
	//								SetGeometry
	// 
	/// Sets the geometry associated with the mesh
	/// 
	/// \param geometry  
	/// 
	virtual void		MCCOMAPI SetGeometry(I3DExGeometry* geometry) = 0;

	virtual I3DExGeometry*	MCCOMAPI GetGeometry() = 0;

	virtual void		MCCOMAPI GeometryModified() = 0;
	
	virtual boolean		MCCOMAPI IsStatic() const = 0;

	//virtual real		MCCOMAPI GetMass() = 0;
};

struct I3DExSoftBody : public I3DExPhysicsBody
{
	virtual void		MCCOMAPI SetStiffness(real32 stiffness) = 0;
	virtual void		MCCOMAPI SetBending(real32 bending) = 0;
	virtual void		MCCOMAPI SetAero(real32 airDrag, real32 lift) = 0;
	virtual void		MCCOMAPI SetPressure(real32 pressure) = 0;
	virtual void		MCCOMAPI SetSelfCollision(boolean selfCollision) = 0;
	virtual void		MCCOMAPI SetQuality(real32 simulation, real32 collision) = 0;

	virtual void		MCCOMAPI AddPoint(const TVector3& position) = 0;
	virtual void		MCCOMAPI AddEdge(const TIndex2& edge) = 0;
	virtual void		MCCOMAPI AddFace(const Triangle& triangle) = 0;

	virtual void		MCCOMAPI AddAnchor(int32 index, I3DExRigidBody* body) = 0;

	virtual void		MCCOMAPI GetPointPosition(int32 node, TVector3& position) = 0;
};

struct I3DExPhysicConstraint : public IMCUnknown
{
	virtual void		MCCOMAPI SetFreedom(EFreedomDegree freedom, real min, real max) = 0;
};


/// \addtogroup ExternalInterface
/// \{

struct I3DExPhysicsSolver : public IMCUnknown
{
	virtual void		MCCOMAPI Init()=0;

	virtual boolean		MCCOMAPI SupportsRigidBody() const = 0;
	virtual boolean		MCCOMAPI SupportsSoftBody() const = 0;
	virtual boolean		MCCOMAPI SupportsConstraints() const = 0;

	// ****************************************************************************
	//								SetIntegrationStep
	// 
	/// 
	/// 
	/// \param newTimeStep  
	/// 
	virtual void		MCCOMAPI SetIntegrationStep(real64 newTimeStep) = 0;

	// ****************************************************************************
	//								SetCollisionPrecision
	// 
	/// Sets the precision of detecting contact points during collisions
	/// 
	/// \param precision  The precision in inches that is used to detect contact points. (0.01 inches by default)
	/// 
	virtual void		MCCOMAPI SetCollisionPrecision(real64 precision) = 0;

	// ****************************************************************************
	//								RunTo
	// 
	/// Run the simulation from current time to the newTime
	/// 
	/// \param time  
	/// 
	virtual void		MCCOMAPI RunTo(real64 time) = 0;

	// ****************************************************************************
	//								AddObject
	// 
	/// Adds a new object to the simulation a returns a pointer to that object. If
	/// you release the reference to that object, the body is deleted from the simulation.
	/// 
	/// \param body A pointer to the rigid body that is created
	/// 
	virtual void		MCCOMAPI CreateRigidBody(I3DExRigidBody** body, I3DShTreeElement* tree, boolean isStatic) = 0;

	virtual void		MCCOMAPI CreateSoftBody(I3DExSoftBody** body, I3DShTreeElement* tree) = 0;

	virtual void		MCCOMAPI CreateGeometry(I3DExGeometry** geometry, boolean isStatic) = 0;

	virtual void		MCCOMAPI CreateForce(I3DExPhysicForce** force, I3DExForce* carraraForce, I3DShTreeElement* tree) = 0;

	virtual void		MCCOMAPI CreateConstraint(I3DExPhysicConstraint** constraint, I3DExRigidBody* bodyA, I3DExRigidBody* bodyB, const TTransform3D& worldTfm) = 0;

};


/// \}





#endif
