00001 //--------------------------------------------------------------------------------------------- 00002 // This file is a part of "DinoKod". 00003 // Copyright © 2003 Dino Productions. All Rights Reserved. 00004 // 00005 // File : MdlMesh.cpp 00006 // Author : Sebastien LEIX sebastien.leix@wanadoo.fr 00007 // Date : 09/09/2002 00008 // Modification : 00009 // 00010 //--------------------------------------------------------------------------------------------- 00011 #include "Model/MdlMesh.h" 00012 00013 //--------------------------------------------------------------------------------------------------------------------- 00014 KMdlMesh::KMdlMesh() 00015 { 00016 m_Type = KMMT_MESH; 00017 m_pFather = NULL; 00018 m_RenderEffect = KMMRE_NORMAL; 00019 00020 // Anim 00021 m_MaxFrame = 0; 00022 m_CurrentFrame = 0; 00023 m_pFastFrameMatrix = NULL; 00024 00025 m_BlendMatrix.LoadIdentity(); 00026 m_CurrentWorldMatrix.LoadIdentity(); 00027 m_FirstWorldMatrix.LoadIdentity(); 00028 } 00029 00030 //--------------------------------------------------------------------------------------------------------------------- 00031 KMdlMesh::~KMdlMesh() 00032 { 00033 m_pChildrens.Clear(); 00034 00035 u32 i; 00036 // Primitives 00037 for( i = 0; i < m_Primitives.GetSize(); i ++ ) 00038 Deletep( m_Primitives[i] ); 00039 m_Primitives.Clear(); 00040 00041 // Matrice de transformation 00042 for( i = 0; i < m_FrameMatrix.GetSize(); i ++ ) 00043 Deletep( m_FrameMatrix[i] ); 00044 m_FrameMatrix.Clear(); 00045 00046 // Bones 00047 for( i = 0; i < m_Bones.GetSize(); i ++ ) 00048 Deletep( m_Bones[i] ); 00049 m_Bones.Clear(); 00050 00051 // Matrices optimisées 00052 if( m_pFastFrameMatrix ) 00053 Deletev( m_pFastFrameMatrix ); 00054 } 00055 00056 //--------------------------------------------------------------------------------------------------------------------- 00057 void KMdlMesh::Save( KFile& File ) 00058 { 00059 WRITEMAGIC( MAGIC_MESH ); 00060 File.WriteString( m_Name ); 00061 File.WriteString( m_FatherName ); 00062 File << m_Type; 00063 00064 // Matrice de transformation 00065 u32 nMatrices = m_FrameMatrix.GetSize(); 00066 File << nMatrices; 00067 for( u32 MatrixId = 0; MatrixId < nMatrices; MatrixId ++ ) 00068 m_FrameMatrix[MatrixId]->Save( File ); 00069 00070 // Primitives 00071 u32 nPrimitives = m_Primitives.GetSize(); 00072 File << nPrimitives; 00073 for( u32 PrimitiveId = 0; PrimitiveId < nPrimitives; PrimitiveId ++ ) 00074 m_Primitives[PrimitiveId]->Save( File ); 00075 00076 // Bones 00077 u32 nBones = m_Bones.GetSize(); 00078 File << nBones; 00079 for( u32 BoneId = 0; BoneId < nBones; BoneId ++ ) 00080 m_Bones[BoneId]->Save( File ); 00081 } 00082 00083 //--------------------------------------------------------------------------------------------------------------------- 00084 void KMdlMesh::Load( KFile& File, s32 EndFrame ) 00085 { 00086 TESTMAGIC( MAGIC_MESH ); 00087 File.ReadString( m_Name ); 00088 File.ReadString( m_FatherName ); 00089 File >> m_Type; 00090 00091 // End Frame 00092 m_MaxFrame = EndFrame; 00093 00094 // Matrice de transformation 00095 u32 nMatrices; 00096 KMdlFrameMatrix* pFrameMatrix; 00097 00098 File >> nMatrices; 00099 for( u32 MatrixId = 0; MatrixId < nMatrices; MatrixId ++ ) 00100 { 00101 pFrameMatrix = new KMdlFrameMatrix(); 00102 pFrameMatrix->Load( File ); 00103 m_FrameMatrix.Add( pFrameMatrix ); 00104 } 00105 00106 // Primitives 00107 u32 nPrimitives; 00108 KMdlPrimitive* pPrimitive; 00109 00110 File >> nPrimitives; 00111 for( u32 PrimitiveId = 0; PrimitiveId < nPrimitives; PrimitiveId ++ ) 00112 { 00113 pPrimitive = new KMdlPrimitive(); 00114 pPrimitive->Load( File ); 00115 m_Primitives.Add( pPrimitive ); 00116 } 00117 00118 // Bones 00119 u32 nBones; 00120 KMdlBone* pBone; 00121 00122 File >> nBones; 00123 for( u32 BoneId = 0; BoneId < nBones; BoneId ++ ) 00124 { 00125 pBone = new KMdlBone(); 00126 pBone->Load( File ); 00127 m_Bones.Add( pBone ); 00128 } 00129 00130 // Genere les matrices par frame 00131 GenerateFastFrameMatrix(); 00132 } 00133 00134 //--------------------------------------------------------------------------------------------------------------------- 00135 KMdlFrameMatrix* KMdlMesh::GetSlowFrameMatrix( u32 Frame ) 00136 { 00137 // Cherche la matrice clé en fonctione de la frame 00138 KMdlFrameMatrix* pFrameMatrix = NULL; 00139 for( u32 i = 0; i < m_FrameMatrix.GetSize(); i ++ ) 00140 { 00141 if( m_FrameMatrix[i]->m_FrameId <= Frame ) 00142 pFrameMatrix = m_FrameMatrix[i]; 00143 else 00144 if( !pFrameMatrix ) 00145 continue; // La 1ere clé n'est pas forcement là 0, donc on cherche un peu plus loin... 00146 else 00147 return pFrameMatrix; 00148 } 00149 00150 // Si aucune clé n'a été trouvée, on prend la premiere 00151 if( !pFrameMatrix && m_FrameMatrix.GetSize() ) 00152 { 00153 pFrameMatrix = m_FrameMatrix[0]; 00154 } 00155 00156 return pFrameMatrix; 00157 } 00158 00159 //--------------------------------------------------------------------------------------------------------------------- 00160 void KMdlMesh::GenerateFastFrameMatrix() 00161 { 00162 KASSERT( m_FrameMatrix.GetSize() ); 00163 KASSERT( !m_pFastFrameMatrix ); 00164 00165 // Génère autant de matrice qu'il y a de frame pour un acces memoire plus rapide 00166 // m_MaxFrame = m_FrameMatrix[m_FrameMatrix.GetSize() - 1]->m_FrameId; 00167 m_pFastFrameMatrix = new KMdlFrameMatrix*[m_MaxFrame + 1]; 00168 for( u32 i = 0; i < m_MaxFrame + 1; i ++ ) 00169 m_pFastFrameMatrix[i] = GetSlowFrameMatrix( i ); 00170 } 00171 00172 //--------------------------------------------------------------------------------------------------------------------- 00173 void KMdlMesh::SetMeshFrame( KMdlMesh* pMesh, u32 Frame, bool bInherit ) 00174 { 00175 KASSERT( pMesh ); 00176 00177 pMesh->SetFrame( (Frame <= pMesh->m_MaxFrame) ? Frame : pMesh->m_MaxFrame ); 00178 00179 // Hérite l'anim aux fils si demandé 00180 if( bInherit ) 00181 { 00182 for( KMdlMesh* pChild = pMesh->m_pChildrens.GetFirst(); pChild; pChild = pMesh->m_pChildrens.GetNext( pChild ) ) 00183 { 00184 SetMeshFrame( pChild, Frame, bInherit ); 00185 } 00186 } 00187 } 00188 00189 //--------------------------------------------------------------------------------------------------------------------- 00190 // PRIMITIVE 00191 //--------------------------------------------------------------------------------------------------------------------- 00192 KMdlPrimitive::KMdlPrimitive() 00193 { 00194 m_ShaderId = (u32)-1; 00195 m_nFrames = 0; 00196 m_nIndices = 0; 00197 m_pIndices = NULL; 00198 m_nVertices = 0; 00199 m_MaxFrames = 0; 00200 m_pFastFrameVertex = NULL; 00201 m_pTranformedVertices = NULL; 00202 } 00203 00204 //--------------------------------------------------------------------------------------------------------------------- 00205 KMdlPrimitive::~KMdlPrimitive() 00206 { 00207 Free(); 00208 } 00209 00210 //--------------------------------------------------------------------------------------------------------------------- 00211 void KMdlPrimitive::Free() 00212 { 00213 if( m_pIndices ) 00214 Deletev( m_pIndices ); 00215 00216 for( u32 i = 0; i < m_FrameVertices.GetSize(); i ++ ) 00217 Deletep( m_FrameVertices[i] ); 00218 m_FrameVertices.Clear(); 00219 00220 SafeDeletev( m_pFastFrameVertex ); 00221 SafeDeletev( m_pTranformedVertices ); 00222 } 00223 00224 //--------------------------------------------------------------------------------------------------------------------- 00225 void KMdlPrimitive::Save( KFile& File ) 00226 { 00227 WRITEMAGIC( MAGIC_PRIMITIVE ); 00228 File << m_ShaderId; 00229 File << m_nFrames; 00230 File << m_nIndices; 00231 File << m_nVertices; 00232 00233 u32 IndiceId; 00234 for( IndiceId = 0; IndiceId < m_nIndices; IndiceId ++ ) 00235 File << m_pIndices[IndiceId]; 00236 00237 u32 FrameId; 00238 for( FrameId = 0; FrameId < m_nFrames; FrameId ++ ) 00239 m_FrameVertices[FrameId]->Save( File ); 00240 } 00241 00242 //--------------------------------------------------------------------------------------------------------------------- 00243 void KMdlPrimitive::Load( KFile& File ) 00244 { 00245 Free(); 00246 00247 TESTMAGIC( MAGIC_PRIMITIVE ); 00248 File >> m_ShaderId; 00249 File >> m_nFrames; 00250 File >> m_nIndices; 00251 File >> m_nVertices; 00252 00253 if( m_nIndices ) 00254 { 00255 m_pIndices = new u16[m_nIndices]; 00256 00257 u32 IndiceId; 00258 for( IndiceId = 0; IndiceId < m_nIndices; IndiceId ++ ) 00259 File >> m_pIndices[IndiceId]; 00260 } 00261 00262 KMdlFrameVertex* pFrameVertex; 00263 u32 FrameId; 00264 for( FrameId = 0; FrameId < m_nFrames; FrameId ++ ) 00265 { 00266 pFrameVertex = new KMdlFrameVertex(); 00267 pFrameVertex->Load( File ); 00268 m_FrameVertices.Add( pFrameVertex ); 00269 } 00270 00271 00272 m_pTranformedVertices = new KVertex[m_nVertices]; 00273 00274 GenerateFastFrameVertex(); 00275 } 00276 00277 //--------------------------------------------------------------------------------------------------------------------- 00278 KMdlFrameVertex* KMdlPrimitive::GetSlowFrameVertex( u32 Frame ) 00279 { 00280 KMdlFrameVertex* pFrameVertex = NULL; 00281 for( u32 i = 0; i < m_FrameVertices.GetSize(); i ++ ) 00282 { 00283 if( m_FrameVertices[i]->m_FrameId <= Frame ) 00284 pFrameVertex = m_FrameVertices[i]; 00285 else 00286 return pFrameVertex; 00287 } 00288 return pFrameVertex; 00289 } 00290 00291 //--------------------------------------------------------------------------------------------------------------------- 00292 void KMdlPrimitive::GenerateFastFrameVertex() 00293 { 00294 KASSERT( m_FrameVertices.GetSize() ); 00295 KASSERT( !m_pFastFrameVertex ); 00296 m_MaxFrames = m_FrameVertices[m_FrameVertices.GetSize() - 1]->m_FrameId; 00297 m_pFastFrameVertex = new KMdlFrameVertex*[m_MaxFrames + 1]; 00298 for( u32 i = 0; i < m_MaxFrames + 1; i ++ ) 00299 m_pFastFrameVertex[i] = GetSlowFrameVertex( i ); 00300 } 00301 00302 //--------------------------------------------------------------------------------------------------------------------- 00303 KMdlFrameVertex* KMdlPrimitive::GetFrameVertex( u32 Frame ) 00304 { 00305 KASSERT( Frame >= 0 ); 00306 // KASSERT( Frame <= m_MaxFrames ); 00307 KASSERT( m_pFastFrameVertex ); 00308 00309 return (Frame > m_MaxFrames) ? m_pFastFrameVertex[m_MaxFrames] : m_pFastFrameVertex[Frame]; 00310 }
1.5.1-p1