
//	CObject
//	 |
//	 +---------------+
//	 |				 |
//	CMesh			CPointObject
//	 |				 |
//	 +				 +---------------+---------------+
//	 |				 |				 |				 |
//  CSkin			CCameraObject	CLight			CTarget
//					 |
//					 +---------------+
//					 |				 |
//					CViewer         CCamera

#ifndef	__OBJECT_H_
#define __OBJECT_H_

#include "math3d.h"

enum HE3D_OBJECTTYPES
{
	HE3DOT_SIMPLEMESH,
	HE3DOT_MESH,
	HE3DOT_SKIN,
	HE3DOT_CAMERA,
	HE3DOT_VIEWER,
	HE3DOT_LIGHT,
	HE3DOT_TARGET,
	HE3DOT_BONE,
	HE3DOT_FORCEDWORD = 0x7fffffff
};

class he3d_CScene;
class he3d_CValueEnvelope;
class he3d_CDataEnvelope;
class he3d_CMaterial;
class he3d_CKeyframer;

//--class---------------------------------------------------------------------------
//	name:	CObject
//	desc:	base class for object hierarchy 
//----------------------------------------------------------------------------------
class he3d_CObject
{
public:
	
	he3d_CScene*			pScene;								// scena do ktorej nalezy obiekt

public:

	he3d_CObject( he3d_CScene* scene ) : pScene( scene )
	{
	}

	virtual ~he3d_CObject()
	{
	}

	virtual DWORD Type() = 0;
	virtual void Render() = 0;	
	virtual void UpdateFrame( he3d_CKeyframer* keyframer ) = 0;
};


class he3d_CPointObject	: public he3d_CObject								
{
public:

	he3d_CVector			vPos;

public:

	he3d_CPointObject( he3d_CScene* scene ) : he3d_CObject( scene )
	{
	}	

	virtual DWORD Type() = 0;

	virtual void Render()
	{
	}

	virtual void UpdateFrame( he3d_CKeyframer* keyframer );	
};

class he3d_CLight : public he3d_CPointObject
{
public:

	DWORD					dwLightID;
	he3d_CVector			vColor;

public:

	he3d_CLight( he3d_CScene* scene ) : he3d_CPointObject( scene )
	{
	}	

	virtual DWORD Type()
	{
		return HE3DOT_LIGHT;
	}

	virtual void Render();
	virtual void UpdateFrame( he3d_CKeyframer* keyframer );
};

class he3d_CTarget : public he3d_CPointObject
{
public:

	he3d_CTarget( he3d_CScene* scene ) : he3d_CPointObject( scene )
	{
	}	

	virtual DWORD Type()
	{
		return HE3DOT_TARGET;
	}	
};

class he3d_CCameraObject : public he3d_CPointObject
{
public:

	he3d_CValueEnvelope*	pveFov;
	FLOAT					fFov;

	he3d_CMatrix			mtxCamera;

public:

	he3d_CCameraObject( he3d_CScene* scene ) : he3d_CPointObject( scene ), fFov( 0.33f*H_PI ), pveFov( NULL )
	{		
	}

	virtual ~he3d_CCameraObject();

	virtual void UpdateFrame( he3d_CKeyframer* keyframer );
	virtual void SetGeometry() = 0;	
};

class he3d_CViewer : public he3d_CCameraObject
{
public:

	he3d_CValueEnvelope*	pveRoll;
	FLOAT					fRoll;

	he3d_CTarget*			pTrg;

public:

	he3d_CViewer( he3d_CScene* scene ) : he3d_CCameraObject( scene ), fRoll( 0.0f ), pveRoll( NULL )
	{
	}

	virtual ~he3d_CViewer();

	virtual DWORD Type()
	{
		return HE3DOT_VIEWER;
	}

	virtual void UpdateFrame( he3d_CKeyframer* keyframer );
	virtual void SetGeometry();	
};

class he3d_CCamera : public he3d_CCameraObject
{
public:

	he3d_CCamera( he3d_CScene* scene ) : he3d_CCameraObject( scene )
	{
	}

	virtual DWORD Type()
	{
		return HE3DOT_VIEWER;
	}

	virtual void UpdateFrame( he3d_CKeyframer* keyframer );
	virtual void SetGeometry();
};

class he3d_CBoundingBox
{
public:

	he3d_CVector			bbmin;
	he3d_CVector			bbmax;

public:

	DWORD IsVisible( PDIRECT3DDEVICE8 pDevice );
};

class he3d_CMesh : public he3d_CObject
{
public:	

	he3d_CBoundingBox		bbBoundingBox;

	he3d_CDataEnvelope*		pdeMorph;
	he3d_CDataEnvelope*		pdeHide;

	he3d_CMesh*				pmeshMorphSrc;
	he3d_CMesh*				pmeshMorphTrg;
	FLOAT					fMorphFactor;
	
	DWORD					dwHide;

	he3d_CMatrix			mtxTransform;

	PDIRECT3DVERTEXBUFFER8	pvbVertices;
	PDIRECT3DINDEXBUFFER8	pibIndices;

	he3d_CVector			vCenter;

	he3d_CMaterial*			pMaterial;

	union
	{	
		DWORD				dwFVF;
		DWORD				dwVS;
	};

	DWORD					dwFlags;	
	DWORD					dwVerticesCount;
	DWORD					dwFacesCount;
	DWORD					dwIndicesCount;

public:

	he3d_CMesh( he3d_CScene* scene ) : he3d_CObject( scene ), dwHide( FALSE ), pdeMorph( NULL ), pdeHide( NULL )
	{
	}

	virtual ~he3d_CMesh();

	virtual DWORD Type()
	{
		return HE3DOT_SIMPLEMESH;
	}
	
	virtual void Render();	
	virtual void UpdateFrame( he3d_CKeyframer* keyframer );
};


class he3d_CSegmentedMesh : public he3d_CMesh
{
public:

	struct Segment
	{	
		DWORD				dwStartIndex;
		DWORD				dwFacesCount;

		he3d_CMaterial*		pMaterial;
	};

	DWORD					dwSegmentsCount;
	Segment*				ptabSegments;

public:

	he3d_CSegmentedMesh( he3d_CScene* scene ) : he3d_CMesh( scene )
	{
	}

	virtual ~he3d_CSegmentedMesh();

	virtual DWORD Type()
	{
		return HE3DOT_MESH;
	}
	
	virtual void Render();	
};

class he3d_CSkin : public he3d_CSegmentedMesh
{
public:

	class he3d_CBone
	{
	public:
		
		he3d_CKeyframer*	pBoneKeyframer;
		he3d_CMatrix		mtxRest;
	};

	DWORD					dwBonesCount;
	he3d_CBone*				ptabBones;

public:

	he3d_CSkin( he3d_CScene* scene ) : he3d_CSegmentedMesh( scene ), dwBonesCount(0)
	{
	}

	virtual ~he3d_CSkin();

	virtual DWORD Type()
	{
		return HE3DOT_SKIN;
	}
	
	virtual void Render();	
};

#endif