
#include "physicslib/physaggregatedata.h"
#include "vphysx/vphysx_collisionmesh_resource.h"

native class CPhysAggregateData
{
	ushort m_nFlags;

	void AddRef();
	void Release();

	uint GetChecksum();
	
	int GetBoneCount();
	string GetBoneName( int nBoneIndex );

	int GetPartCount();

	uint GetBoneHash( int i );
	uint GetIndexHash( int i );

	inline Transform GetBindPose( int index )
	{
		return self->m_BindPose[index].ToCTransform();
	}

	inline VPhysXBodyPart_t GetPart( int index )
	{
		return self->m_Parts[index];
	}

	CPhysSurfaceProperties GetSurfaceProperties( int index );

	inline int GetSurfacePropertiesCount()
	{
		return self->m_SurfaceProperties.Count();
	}

	inline int GetCollisionAttributeCount()
	{
		return self->m_CollisionAttributes.Count();
	}

	inline string GetTag( int nAttribute, int nIndex )
	{
		return self->m_pBackingData->m_collisionAttributes[ nAttribute ].m_PhysicsTagStrings[ nIndex ];
	}
	
	inline int GetTagCount( int nAttribute )
	{
		if ( !self->m_pBackingData )
			return 0;

		if ( !self->m_pBackingData->m_collisionAttributes.IsValidIndex( nAttribute ) )
			return 0;

		return self->m_pBackingData->m_collisionAttributes[ nAttribute ].m_PhysicsTagStrings.Count();
	}

	inline int GetJointCount()
	{
		return self->m_Joints.Count();
	}

	inline VPhysXJoint_t GetJoint( int index )
	{
		return self->m_Joints[index];
	}
}


native class VPhysXBodyPart_t
{
	uint m_nFlags;
	float m_flMass;
	ushort m_nCollisionAttributeIndex;
	float m_flInertiaScale;
	float m_flLinearDamping;
	float m_flAngularDamping;
	float m_flGravityScale;

	bool m_bOverrideMassCenter;
	Vector3 m_vMassCenterOverride;

	inline int GetSphereCount()
	{
		return self->m_rnShape.m_spheres.Count();
	}

	inline RnSphereDesc_t GetSphere( int index )
	{
		return &self->m_rnShape.m_spheres[index];
	}

	inline int GetCapsuleCount()
	{
		return self->m_rnShape.m_capsules.Count();
	}

	inline RnCapsuleDesc_t GetCapsule( int index )
	{
		return &self->m_rnShape.m_capsules[index];
	}

	inline int GetHullCount()
	{
		return self->m_rnShape.m_hulls.Count();
	}

	inline RnHullDesc_t GetHull( int index )
	{
		return &self->m_rnShape.m_hulls[index];
	}

	inline int GetMeshCount()
	{
		return self->m_rnShape.m_meshes.Count();
	}

	inline RnMeshDesc_t GetMesh( int index )
	{
		return &self->m_rnShape.m_meshes[index];
	}

	inline int GetCollisionAttributeCount()
	{
		return self->m_rnShape.m_CollisionAttributeIndices.Count();
	}

	inline ushort GetCollisionAttributeIndex( int index )
	{
		return self->m_rnShape.m_CollisionAttributeIndices[index];
	}
}



native class RnSphereDesc_t
{
	Sphere m_Sphere;

	uint m_nCollisionAttributeIndex;
	uint m_nSurfacePropertyIndex;
}

native class RnCapsuleDesc_t
{
	Capsule m_Capsule;

	uint m_nCollisionAttributeIndex;
	uint m_nSurfacePropertyIndex;
}

native class RnHull_t
{
	int GetVertexCount();
	int GetEdgeCount();
	float GetVolume();
	Vector3 GetMassCenter();
	Vector3 GetCentroid();
	float GetSurfaceArea();
	int GetMemory();
	AABB_t GetBbox();
	Vector3 GetVertex( int nVertex );

	inline void GetEdgeVertex( int edge, out Vector3 a, out Vector3 b )
	{
		const RnHalfEdge_t *pEdge = self->GetEdge( edge );
		const RnHalfEdge_t *pTwin = self->GetEdge( pEdge->m_nTwin );

		*a = self->GetVertex( pEdge->m_nOrigin );
		*b = self->GetVertex( pTwin->m_nOrigin );
	}
}

native class RnHullDesc_t
{
	uint m_nCollisionAttributeIndex;
	uint m_nSurfacePropertyIndex;

	inline RnHull_t GetHull()
	{
		return &self->m_Hull;	
	}
}

native class RnMesh_t
{
	int GetTriangleCount();
	int GetHeight();
	int GetMemory();
	AABB_t GetBbox();

	int GetMaterialCount();

	inline void GetTriangle( int triangle, out Vector3 a, out Vector3 b, out Vector3 c )
	{
		const RnTriangle_t *pTriangle = self->GetTriangle( triangle );

		*a = self->GetVertex( pTriangle->m_nIndex[0] );
		*b = self->GetVertex( pTriangle->m_nIndex[1] );
		*c = self->GetVertex( pTriangle->m_nIndex[2] );
	}
}


native class RnMeshDesc_t
{
	uint m_nCollisionAttributeIndex;
	uint m_nSurfacePropertyIndex;

	inline RnMesh_t GetMesh()
	{
		return &self->m_Mesh;	
	}
}

native class CPhysSurfaceProperties as NativeEngine.CPhysSurfaceProperties
{
	string m_name;
	uint m_nameHash;

	uint m_baseNameHash;
	int m_nIndex; 
	int	m_nBaseIndex;
	int	m_AudioSurface;

	bool m_bHidden;

	string m_description;

	void UpdatePhysics( float Friction, float Elasticity, float Density, float RollingResistance, float BounceThreshold );
}

native class VPhysXJoint_t
{
	ushort m_nType;
	ushort m_nBody1;
	ushort m_nBody2;
	ushort m_nFlags;

	bool m_bEnableCollision;
	bool m_bEnableLinearLimit;
	bool m_bEnableLinearMotor;
	Vector3 m_vLinearTargetVelocity;
	float m_flMaxForce;

	bool m_bEnableSwingLimit;
	bool m_bEnableTwistLimit;

	bool m_bEnableAngularMotor;
	Vector3 m_vAngularTargetVelocity;
	float m_flMaxTorque;

	float m_flLinearFrequency;
	float m_flLinearDampingRatio;
	float m_flAngularFrequency;	
	float m_flAngularDampingRatio;

	float m_flLinearStrength;
	float m_flAngularStrength;

	Transform m_Frame1;
	Transform m_Frame2;

	inline float GetLinearLimitMin()
	{
		return self->m_LinearLimit.m_flMin;
	}

	inline float GetLinearLimitMax()
	{
		return self->m_LinearLimit.m_flMax;
	}

	inline float GetSwingLimitMin()
	{
		return self->m_SwingLimit.m_flMin;
	}

	inline float GetSwingLimitMax()
	{
		return self->m_SwingLimit.m_flMax;
	}

	inline float GetTwistLimitMin()
	{
		return self->m_TwistLimit.m_flMin;
	}

	inline float GetTwistLimitMax()
	{
		return self->m_TwistLimit.m_flMax;
	}

	inline void SetLinearLimitMin( float value )
	{
		self->m_LinearLimit.m_flMin = value;
	}

	inline void SetLinearLimitMax( float value )
	{
		self->m_LinearLimit.m_flMax = value;
	}

	inline void SetSwingLimitMin( float value )
	{
		self->m_SwingLimit.m_flMin = value;
	}

	inline void SetSwingLimitMax( float value )
	{
		self->m_SwingLimit.m_flMax = value;
	}

	inline void SetTwistLimitMin( float value )
	{
		self->m_TwistLimit.m_flMin = value;
	}

	inline void SetTwistLimitMax( float value )
	{
		self->m_TwistLimit.m_flMax = value;
	}
}
