0001: // ----------------------------------------------------------------------------
0002: //
0003: // CSkinModel.h - スキンメッシュ管理クラス
0004: // 
0005: // Copyright (c) 2002 imagire (imagire@gmail.com)
0006: // All Rights Reserved.
0007: //
0008: // ----------------------------------------------------------------------------
0009: #include <windows.h>
0010: #include <d3d8.h>
0011: 
0012: #ifndef _CSkinModel_h
0013: #define _CSkinModel_h
0014: 
0015: //-----------------------------------------------------------------------------
0016: // 定数
0017: //-----------------------------------------------------------------------------
0018: enum METHOD { // 実装方法
0019:     D3DNONINDEXED,
0020:     D3DINDEXED,
0021:     SOFTWARE,
0022:     D3DINDEXEDVS,
0023:     NONE
0024: };
0025: 
0026: //-----------------------------------------------------------------------------
0027: //-----------------------------------------------------------------------------
0028: // 構造体
0029: //-----------------------------------------------------------------------------
0030: //-----------------------------------------------------------------------------
0031: 
0032: // 定義前に参照されるので先に宣言
0033: class SDrawElement; // 
0034: class CSkinModel;
0035: 
0036: //-----------------------------------------------------------------------------
0037: // メッシュの情報が格納される
0038: //-----------------------------------------------------------------------------
0039: class SMeshContainer
0040: {
0041: public:
0042:     ID3DXMesh *pMesh;
0043:     D3DMATERIAL8 *rgMaterials;
0044:     LPDIRECT3DTEXTURE8 *pTextures;
0045:     DWORD cpattr;
0046:     DWORD cMaterials;
0047:     DWORD iAttrSplit;
0048: 
0049:     SMeshContainer *pmcNext;
0050: 
0051:     char *szName;
0052: 
0053:     // スキンの情報
0054:     LPD3DXSKINMESH      m_pSkinMesh;
0055:     D3DXATTRIBUTERANGE* m_pAttrTable;
0056:     D3DXMATRIX**        m_pBoneMatrix;
0057:     LPD3DXBUFFER        m_pBoneNamesBuf;
0058:     LPD3DXBUFFER        m_pBoneOffsetBuf;
0059:     D3DXMATRIX*         m_pBoneOffsetMat;
0060:     DWORD*              m_rgiAdjacency;
0061:     DWORD               m_numBoneComb;
0062:     DWORD               m_maxFaceInfl;
0063:     LPD3DXBUFFER        m_pBoneCombinationBuf;
0064:     METHOD              m_Method;
0065:     DWORD               m_paletteSize;
0066:     BOOL                m_bUseSW;
0067: 
0068:     SMeshContainer();
0069:     ~SMeshContainer();
0070: };
0071: // ----------------------------------------------------------------------------
0072: // Xファイルの情報
0073: // ----------------------------------------------------------------------------
0074: struct SRotateKeyXFile
0075: {
0076:     DWORD           dwTime;
0077:     DWORD           dwFloats;   
0078:     float           w;
0079:     float           x;
0080:     float           y;
0081:     float           z;
0082: };
0083: // ----------------------------------------------------------------------------
0084: struct SScaleKeyXFile
0085: {
0086:     DWORD   dwTime;
0087:     DWORD   dwFloats;   
0088:     D3DXVECTOR3 vScale; 
0089: };
0090: // ----------------------------------------------------------------------------
0091: struct SPositionKeyXFile
0092: {
0093:     DWORD   dwTime;
0094:     DWORD   dwFloats;   
0095:     D3DXVECTOR3 vPos;   
0096: };
0097: // ----------------------------------------------------------------------------
0098: struct SMatrixKeyXFile
0099: {
0100:     DWORD   dwTime;
0101:     DWORD   dwFloats;   
0102:     D3DXMATRIX  mat;    
0103: };
0104: // ----------------------------------------------------------------------------
0105: // メモリに格納されるときのXファイルの情報
0106: // ----------------------------------------------------------------------------
0107: struct SRotateKey
0108: {
0109:     DWORD           dwTime;
0110:     D3DXQUATERNION  quatRotate; 
0111: };
0112: // ----------------------------------------------------------------------------
0113: struct SPositionKey
0114: {
0115:     DWORD   dwTime;
0116:     D3DXVECTOR3 vPos;   
0117: };
0118: // ----------------------------------------------------------------------------
0119: struct SScaleKey
0120: {
0121:     DWORD   dwTime;
0122:     D3DXVECTOR3 vScale; 
0123: };
0124: // ----------------------------------------------------------------------------
0125: struct SMatrixKey
0126: {
0127:     DWORD   dwTime;
0128:     D3DXMATRIXA16   mat;    
0129: };
0130: // ----------------------------------------------------------------------------
0131: 
0132: // ----------------------------------------------------------------------------
0133: // メッシュのアニメーション管理
0134: // ----------------------------------------------------------------------------
0135: class SFrame
0136: {
0137: private:
0138:     HRESULT _LoadMesh(LPDIRECTXFILEDATA pxofobjCur,
0139:                     DWORD options, CSkinModel &model);
0140:     HRESULT _LoadAnimationSet(LPDIRECTXFILEDATA pxofobjCur, SDrawElement *pde,
0141:                     DWORD options, CSkinModel &model);
0142:     HRESULT _LoadAnimation(LPDIRECTXFILEDATA pxofobjCur, SDrawElement *pde,
0143:                     DWORD options, CSkinModel &model);
0144: public:
0145:     SMeshContainer *pmcMesh;
0146:     D3DXMATRIXA16 matRot;
0147:     D3DXMATRIXA16 matTrans;
0148:     D3DXMATRIXA16 matRotOrig;
0149:     D3DXMATRIXA16 matCombined;
0150: 
0151:     // アニメの情報
0152:     SPositionKey *m_pPositionKeys;
0153:     UINT m_cPositionKeys;
0154:     SRotateKey *m_pRotateKeys;
0155:     UINT m_cRotateKeys;
0156:     SScaleKey *m_pScaleKeys;
0157:     UINT m_cScaleKeys;
0158:     SMatrixKey *m_pMatrixKeys;
0159:     UINT m_cMatrixKeys;
0160: 
0161:     SFrame *pframeAnimNext;
0162:     SFrame *pframeToAnimate;
0163: 
0164:     SFrame *pframeSibling;      // きょうだい
0165:     SFrame *pframeFirstChild;   // 子供
0166: 
0167:     bool bAnimationFrame;
0168:     char *szName;
0169: 
0170:     SFrame();
0171:     ~SFrame();
0172: 
0173:     void ResetMatrix();                   // 行列を単位行列に初期化する
0174:     void AddFrame(SFrame *pframe);        // フレームを追加する
0175:     void AddMesh(SMeshContainer *pmc);    // 先頭に新しいメッシュを追加する
0176:     void SetTime(float fTime);
0177: 
0178:     SFrame *FindFrame(char *szFrame);     // 自分の子兄弟でszFrameの名前をもったやつがいるか調べる
0179:     HRESULT FindBones(SDrawElement *pde); // 骨構造の行列を設定する
0180:     
0181:     HRESULT LoadFrames(LPDIRECTXFILEDATA pxofobjCur, SDrawElement *pde,
0182:                       DWORD options, CSkinModel &model);
0183: 
0184:     HRESULT CalculateRadius(D3DXMATRIX *pmatCur, D3DXVECTOR3 *pvCenter, float *pfRadiusSq); // 半径の計算
0185:     HRESULT CalculateSum(D3DXMATRIX *pmatCur, D3DXVECTOR3 *pvCenter, UINT *pcVertices); // 重心を求める
0186:     void ReleaseDeviceDependentMeshes();    // メッシュとして確保したメモリを開放する
0187:     HRESULT UpdateFrames(D3DXMATRIX &matCur);
0188: };
0189: //-----------------------------------------------------------------------------
0190: // 
0191: //-----------------------------------------------------------------------------
0192: class SDrawElement
0193: {
0194: private:
0195: public:
0196:     char *szName;                               // エレメントの名前
0197:     SFrame *pframeRoot;                         // フレームの木の根元
0198:     SFrame *pframeAnimHead;                     // アニメーションのフレームをリストで管理する先頭
0199:     D3DXVECTOR3 vCenter;                        // ポリゴン全部の重心
0200:     float fRadius;                              // 大きさ
0201: 
0202:     float fCurTime;                             // カウンタ
0203: 
0204:     SDrawElement();
0205:     ~SDrawElement();
0206: 
0207:     void AddAnimationFrame(SFrame *pframeAnim); // 先頭にアニメーションフレームを追加する
0208:     SFrame *FindFrame(char *szName);            // 名前からフレームを検索する
0209:     HRESULT CalculateBoundingSphere();          // バウンディング球の計算
0210: };
0211: 
0212: 
0213: class CSkinModel{
0214: protected:
0215:     TCHAR               m_szPath[MAX_PATH];     // ファイル名
0216:     LPDIRECT3DDEVICE8   m_pD3DDev;              // いちいち指定するのは面倒なので保持しておく
0217:     D3DSURFACE_DESC     m_d3dsdBackBuffer;      // サーフェスの記述を取得する
0218:     D3DCAPS8            m_d3dCaps;
0219:     DWORD               m_1st_time;             // 基準時間
0220:     SDrawElement        *m_pdeMesh;             // 読み込んだメッシュ
0221:     DWORD               m_maxBones;             // 各フレームで使っている骨の最大数
0222:     DWORD               m_dwFVF;                // フレキシブル頂点フォーマット
0223:     METHOD              m_method;               // 描画方法
0224:     DWORD               m_dwIndexedVertexShader[4];
0225: 
0226:     D3DXMATRIXA16       m_Rot;                  // 回転
0227:     D3DXMATRIXA16       m_Trans;                // 平行移動
0228:     D3DXMATRIXA16       m_View;                 // ビュー行列
0229: 
0230:     
0231:     HRESULT _LoadMeshHierarchy(LPDIRECT3DDEVICE8 pD3DDev);
0232:     void _SetDevice(LPDIRECT3DDEVICE8 pD3DDev){m_pD3DDev=pD3DDev;}
0233:     HRESULT _SetProjectionMatrix();
0234:     HRESULT _InvalidateDeviceObjects();
0235:     HRESULT _DeleteDeviceObjects();
0236:     HRESULT _DeleteSelectedMesh();
0237:     
0238:     HRESULT _GenerateMeshNonIndexed(SMeshContainer *pmcMesh);
0239:     HRESULT _GenerateMeshIndexedVs (SMeshContainer *pmcMesh);
0240:     HRESULT _GenerateMeshIndexed   (SMeshContainer *pmcMesh);
0241:     HRESULT _GenerateMeshSoftware  (SMeshContainer *pmcMesh);
0242: 
0243:     HRESULT _DrawMeshContainerNoSkin(SMeshContainer *pmcMesh);
0244:     HRESULT _DrawMeshContainerNonIndexed(SMeshContainer *pmcMesh);
0245:     HRESULT _DrawMeshContainerIndexed(SMeshContainer *pmcMesh);
0246:     HRESULT _DrawMeshContainerIndexedVs(SMeshContainer *pmcMesh);
0247:     HRESULT _DrawMeshContainerSoftware(SMeshContainer *pmcMesh);
0248:     HRESULT _DrawMeshContainer(SMeshContainer *pmcMesh);
0249:     HRESULT _DrawFrames(SFrame *pframe, UINT &cTriangles);
0250: public:
0251:     LPD3DXMATRIXA16     m_pBoneMatrices;        // 骨の行列
0252: 
0253:     CSkinModel();
0254:     virtual ~CSkinModel(){}
0255:     
0256:     // 操作関数
0257:     HRESULT Init(DWORD time, LPDIRECT3DDEVICE8 pD3DDev, D3DCAPS8 &caps);// 最初の初期化
0258:     HRESULT _CreateVertexShader();                                      // 頂点シェーダーの生成
0259:     HRESULT RestoreDeviceObjects(LPDIRECT3DDEVICE8 pD3DDev);            // シーンの初期化
0260:     HRESULT Load(const TCHAR *filename);                                // xFileのロード
0261:     HRESULT GenerateMesh (SMeshContainer *pmcMesh);                     // メッシュの生成
0262:     HRESULT FrameMove(DWORD time);                                      // 動かす
0263:     HRESULT Render();                                                   // 描画する
0264:     HRESULT Release();                                                  // 開放する
0265:     
0266:     // 情報所得、操作系
0267:     const TCHAR *     GetFileName() const {return m_szPath;}
0268:     void              Set1stTime(DWORD time) {m_1st_time = time;}
0269:     LPDIRECT3DDEVICE8 GetDevice()   const {return m_pD3DDev;}
0270:     void              SetMaxBorns(DWORD num) {m_maxBones = num;}
0271:     DWORD             GetMaxBorns() const {return m_maxBones;}
0272:     const D3DCAPS8*   GetCaps ()    const {return &m_d3dCaps;}
0273:     void              SetMethod(METHOD method) {m_method = method;}
0274:     METHOD            GetMethod()   const {return m_method;}
0275:     float             GetRadius() const {return m_pdeMesh->fRadius;}    // モデルのバウンディング球を求める
0276:     void              SetRot  (const D3DXMATRIXA16 &rot  ) {m_Rot   = rot;}
0277:     void              SetTrans(const D3DXMATRIXA16 &trans) {m_Trans = trans;}
0278:     void              SetView (const D3DXMATRIXA16 &view)  {m_View  = view;}
0279: };
0280: 
0281: 
0282: #endif // _CSkinModel_h
0283: