#pragma once //#define CACHE_DEFORMED_VERTEX #include "../eterlib/GrpImage.h" #include "../eterlib/GrpCollisionObject.h" #include "Model.h" #include "Motion.h" class CGrannyModelInstance : public CGraphicCollisionObject { public: enum { ANIFPS_MIN = 30, ANIFPS_MAX = 120, }; public: static void DestroySystem(); static CGrannyModelInstance* New(); static void Delete(CGrannyModelInstance* pkInst); static CDynamicPool ms_kPool; public: struct FCreateDeviceObjects { void operator() (CGrannyModelInstance * pModelInstance) {pModelInstance->CreateDeviceObjects();} }; struct FDestroyDeviceObjects { void operator() (CGrannyModelInstance * pModelInstance) {pModelInstance->DestroyDeviceObjects();} }; public: CGrannyModelInstance(); virtual ~CGrannyModelInstance(); bool IsEmpty(); void Clear(); bool CreateDeviceObjects(); void DestroyDeviceObjects(); // Update & Render void Update(DWORD dwAniFPS); void UpdateLocalTime(float fElapsedTime); void UpdateTransform(D3DXMATRIX * pMatrix, float fSecondsElapsed); void UpdateSkeleton(const D3DXMATRIX * c_pWorldMatrix, float fLocalTime); void DeformNoSkin(const D3DXMATRIX * c_pWorldMatrix); void Deform(const D3DXMATRIX * c_pWorldMatrix); // FIXME : 현재는 하드웨어의 한계로 2장의 텍스춰로 제한이 되어있는 상태이기에 이런 // 불안정한 아키텍춰가 가능하지만, 궁극적인 방향은 (모델 텍스춰 전부) + (효과용 텍스춰) // 이런식의 자동 셋팅이 이뤄져야 되지 않나 생각합니다. - [levites] // NOTE : 내부에 if문을 포함 시키기 보다는 조금은 번거롭지만 이렇게 함수 콜 자체를 분리 // 시키는 것이 퍼포먼스 적인 측면에서는 더 나은 것 같습니다. - [levites] // NOTE : 건물은 무조건 OneTexture. 캐릭터는 경우에 따라 TwoTexture. void RenderWithOneTexture(); void RenderWithTwoTexture(); void BlendRenderWithOneTexture(); void BlendRenderWithTwoTexture(); void RenderWithoutTexture(); // Model CGrannyModel* GetModel(); void SetMaterialImagePointer(const char* c_szImageName, CGraphicImage* pImage); void SetMaterialData(const char* c_szImageName, const SMaterialData& c_rkMaterialData); void SetSpecularInfo(const char* c_szMtrlName, BOOL bEnable, float fPower); void SetMainModelPointer(CGrannyModel* pkModel, CGraphicVertexBuffer* pkSharedDefromableVertexBuffer); void SetLinkedModelPointer(CGrannyModel* pkModel, CGraphicVertexBuffer* pkSharedDefromableVertexBuffer, CGrannyModelInstance** ppkSkeletonInst); // Motion void SetMotionPointer(const CGrannyMotion* pMotion, float blendTime=0.0f, int loopCount=0, float speedRatio=1.0f); void ChangeMotionPointer(const CGrannyMotion* pMotion, int loopCount=0, float speedRatio=1.0f); void SetMotionAtEnd(); bool IsMotionPlaying(); void CopyMotion(CGrannyModelInstance * pModelInstance, bool bIsFreeSourceControl=false); // Time void SetLocalTime(float fLocalTime); int ResetLocalTime(); float GetLocalTime(); float GetNextTime(); // WORK DWORD GetDeformableVertexCount(); DWORD GetVertexCount(); // END_OF_WORK // Bone & Attaching const float * GetBoneMatrixPointer(int iBone) const; const float * GetCompositeBoneMatrixPointer(int iBone) const; bool GetMeshMatrixPointer(int iMesh, const D3DXMATRIX ** c_ppMatrix) const; bool GetBoneIndexByName(const char * c_szBoneName, int * pBoneIndex) const; void SetParentModelInstance(const CGrannyModelInstance* c_pParentModelInstance, const char * c_szBoneName); void SetParentModelInstance(const CGrannyModelInstance* c_pParentModelInstance, int iBone); // Collision Detection bool Intersect(const D3DXMATRIX * c_pMatrix, float * pu, float * pv, float * pt); void MakeBoundBox(TBoundBox* pBoundBox, const float* mat, const float* OBBMin, const float* OBBMax, D3DXVECTOR3* vtMin, D3DXVECTOR3* vtMax); void GetBoundBox(D3DXVECTOR3 * vtMin, D3DXVECTOR3* vtMax); // Reload Texture void ReloadTexture(); protected: void __Initialize(); void __DestroyModelInstance(); void __DestroyMeshMatrices(); void __DestroyDynamicVertexBuffer(); void __CreateModelInstance(); void __CreateMeshMatrices(); void __CreateDynamicVertexBuffer(); // WORK void __DestroyWorldPose(); void __CreateWorldPose(CGrannyModelInstance* pkSrcModelInst); bool __CreateMeshBindingVector(CGrannyModelInstance* pkDstModelInst); void __DestroyMeshBindingVector(); int* __GetMeshBoneIndices(unsigned int iMeshBinding) const; bool __IsDeformableVertexBuffer(); void __SetSharedDeformableVertexBuffer(CGraphicVertexBuffer* pkSharedDeformableVertexBuffer); IDirect3DVertexBuffer9* __GetDeformableD3DVertexBufferPtr(); CGraphicVertexBuffer& __GetDeformableVertexBufferRef(); granny_world_pose* __GetWorldPosePtr() const; // END_OF_WORK // Update & Render void UpdateWorldPose(); void UpdateWorldMatrices(const D3DXMATRIX * c_pWorldMatrix); void DeformPNTVertices(void * pvDest); void RenderMeshNodeListWithOneTexture(CGrannyMesh::EType eMeshType, CGrannyMaterial::EType eMtrlType); void RenderMeshNodeListWithTwoTexture(CGrannyMesh::EType eMeshType, CGrannyMaterial::EType eMtrlType); void RenderMeshNodeListWithoutTexture(CGrannyMesh::EType eMeshType, CGrannyMaterial::EType eMtrlType); protected: // Static Data CGrannyModel * m_pModel; // Granny Data granny_model_instance * m_pgrnModelInstance; //granny_world_pose * m_pgrnWorldPose; // 현재 월드 포즈 포인터 granny_control * m_pgrnCtrl; granny_animation * m_pgrnAni; // Meshes' Transform Data D3DXMATRIX * m_meshMatrices; // Attaching Data const CGrannyModelInstance * mc_pParentInstance; int m_iParentBoneIndex; // Game Data float m_fLocalTime; float m_fSecondsElapsed; DWORD m_dwOldUpdateFrame; CGrannyMaterialPalette m_kMtrlPal; // WORK granny_world_pose* m_pgrnWorldPoseReal; // 실제 메모리는 여기에 할당 std::vector m_vct_pgrnMeshBinding; // Dynamic Vertex Buffer CGraphicVertexBuffer* m_pkSharedDeformableVertexBuffer; CGraphicVertexBuffer m_kLocalDeformableVertexBuffer; bool m_isDeformableVertexBuffer; // END_OF_WORK // TEST CGrannyModelInstance** m_ppkSkeletonInst; // END_OF_TEST #ifdef _TEST D3DXMATRIX TEST_matWorld; #endif public: bool HaveBlendThing() { return m_pModel->HaveBlendThing(); } };