//-------------------------------------------------------------------------------------- // File: SDKMesh.h // // Disclaimer: // The SDK Mesh format (.sdkmesh) is not a recommended file format for shipping titles. // It was designed to meet the specific needs of the SDK samples. Any real-world // applications should avoid this file format in favor of a destination format that // meets the specific needs of the application. // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // Copyright (c) Microsoft Corporation. All rights reserved. // // http://go.microsoft.com/fwlink/?LinkId=320437 //-------------------------------------------------------------------------------------- #pragma once #undef D3DCOLOR_ARGB #include //-------------------------------------------------------------------------------------- // Hard Defines for the various structures //-------------------------------------------------------------------------------------- #define SDKMESH_FILE_VERSION 101 #define MAX_VERTEX_ELEMENTS 32 #define MAX_VERTEX_STREAMS 16 #define MAX_FRAME_NAME 100 #define MAX_MESH_NAME 100 #define MAX_SUBSET_NAME 100 #define MAX_MATERIAL_NAME 100 #define MAX_TEXTURE_NAME MAX_PATH #define MAX_MATERIAL_PATH MAX_PATH #define INVALID_FRAME ((UINT)-1) #define INVALID_MESH ((UINT)-1) #define INVALID_MATERIAL ((UINT)-1) #define INVALID_SUBSET ((UINT)-1) #define INVALID_ANIMATION_DATA ((UINT)-1) #define INVALID_SAMPLER_SLOT ((UINT)-1) #define ERROR_RESOURCE_VALUE 1 template BOOL IsErrorResource( TYPE data ) { if( ( TYPE )ERROR_RESOURCE_VALUE == data ) return TRUE; return FALSE; } //-------------------------------------------------------------------------------------- // Enumerated Types. //-------------------------------------------------------------------------------------- enum SDKMESH_PRIMITIVE_TYPE { PT_TRIANGLE_LIST = 0, PT_TRIANGLE_STRIP, PT_LINE_LIST, PT_LINE_STRIP, PT_POINT_LIST, PT_TRIANGLE_LIST_ADJ, PT_TRIANGLE_STRIP_ADJ, PT_LINE_LIST_ADJ, PT_LINE_STRIP_ADJ, PT_QUAD_PATCH_LIST, PT_TRIANGLE_PATCH_LIST, }; enum SDKMESH_INDEX_TYPE { IT_16BIT = 0, IT_32BIT, }; enum FRAME_TRANSFORM_TYPE { FTT_RELATIVE = 0, FTT_ABSOLUTE, //This is not currently used but is here to support absolute transformations in the future }; //-------------------------------------------------------------------------------------- // Structures. Unions with pointers are forced to 64bit. //-------------------------------------------------------------------------------------- #pragma pack(push,8) struct SDKMESH_HEADER { //Basic Info and sizes UINT Version; BYTE IsBigEndian; UINT64 HeaderSize; UINT64 NonBufferDataSize; UINT64 BufferDataSize; //Stats UINT NumVertexBuffers; UINT NumIndexBuffers; UINT NumMeshes; UINT NumTotalSubsets; UINT NumFrames; UINT NumMaterials; //Offsets to Data UINT64 VertexStreamHeadersOffset; UINT64 IndexStreamHeadersOffset; UINT64 MeshDataOffset; UINT64 SubsetDataOffset; UINT64 FrameDataOffset; UINT64 MaterialDataOffset; }; struct SDKMESH_VERTEX_BUFFER_HEADER { UINT64 NumVertices; UINT64 SizeBytes; UINT64 StrideBytes; D3DVERTEXELEMENT9 Decl[MAX_VERTEX_ELEMENTS]; union { UINT64 DataOffset; //(This also forces the union to 64bits) ID3D11Buffer* pVB11; }; }; struct SDKMESH_INDEX_BUFFER_HEADER { UINT64 NumIndices; UINT64 SizeBytes; UINT IndexType; union { UINT64 DataOffset; //(This also forces the union to 64bits) ID3D11Buffer* pIB11; }; }; struct SDKMESH_MESH { char Name[MAX_MESH_NAME]; BYTE NumVertexBuffers; UINT VertexBuffers[MAX_VERTEX_STREAMS]; UINT IndexBuffer; UINT NumSubsets; UINT NumFrameInfluences; //aka bones DirectX::XMFLOAT3 BoundingBoxCenter; DirectX::XMFLOAT3 BoundingBoxExtents; union { UINT64 SubsetOffset; //Offset to list of subsets (This also forces the union to 64bits) UINT* pSubsets; //Pointer to list of subsets }; union { UINT64 FrameInfluenceOffset; //Offset to list of frame influences (This also forces the union to 64bits) UINT* pFrameInfluences; //Pointer to list of frame influences }; }; struct SDKMESH_SUBSET { char Name[MAX_SUBSET_NAME]; UINT MaterialID; UINT PrimitiveType; UINT64 IndexStart; UINT64 IndexCount; UINT64 VertexStart; UINT64 VertexCount; }; struct SDKMESH_FRAME { char Name[MAX_FRAME_NAME]; UINT Mesh; UINT ParentFrame; UINT ChildFrame; UINT SiblingFrame; DirectX::XMFLOAT4X4 Matrix; UINT AnimationDataIndex; //Used to index which set of keyframes transforms this frame }; struct SDKMESH_MATERIAL { char Name[MAX_MATERIAL_NAME]; // Use MaterialInstancePath char MaterialInstancePath[MAX_MATERIAL_PATH]; // Or fall back to d3d8-type materials char DiffuseTexture[MAX_TEXTURE_NAME]; char NormalTexture[MAX_TEXTURE_NAME]; char SpecularTexture[MAX_TEXTURE_NAME]; DirectX::XMFLOAT4 Diffuse; DirectX::XMFLOAT4 Ambient; DirectX::XMFLOAT4 Specular; DirectX::XMFLOAT4 Emissive; float Power; union { UINT64 Force64_1; //Force the union to 64bits ID3D11Texture2D* pDiffuseTexture11; }; union { UINT64 Force64_2; //Force the union to 64bits ID3D11Texture2D* pNormalTexture11; }; union { UINT64 Force64_3; //Force the union to 64bits ID3D11Texture2D* pSpecularTexture11; }; union { UINT64 Force64_4; //Force the union to 64bits ID3D11ShaderResourceView* pDiffuseRV11; }; union { UINT64 Force64_5; //Force the union to 64bits ID3D11ShaderResourceView* pNormalRV11; }; union { UINT64 Force64_6; //Force the union to 64bits ID3D11ShaderResourceView* pSpecularRV11; }; }; struct SDKANIMATION_FILE_HEADER { UINT Version; BYTE IsBigEndian; UINT FrameTransformType; UINT NumFrames; UINT NumAnimationKeys; UINT AnimationFPS; UINT64 AnimationDataSize; UINT64 AnimationDataOffset; }; struct SDKANIMATION_DATA { DirectX::XMFLOAT3 Translation; DirectX::XMFLOAT4 Orientation; DirectX::XMFLOAT3 Scaling; }; struct SDKANIMATION_FRAME_DATA { char FrameName[MAX_FRAME_NAME]; union { UINT64 DataOffset; SDKANIMATION_DATA* pAnimationData; }; }; #pragma pack(pop) static_assert( sizeof(D3DVERTEXELEMENT9) == 8, "Direct3D9 Decl structure size incorrect" ); static_assert( sizeof(SDKMESH_HEADER)== 104, "SDK Mesh structure size incorrect" ); static_assert( sizeof(SDKMESH_VERTEX_BUFFER_HEADER) == 288, "SDK Mesh structure size incorrect" ); static_assert( sizeof(SDKMESH_INDEX_BUFFER_HEADER) == 32, "SDK Mesh structure size incorrect" ); static_assert( sizeof(SDKMESH_MESH) == 224, "SDK Mesh structure size incorrect" ); static_assert( sizeof(SDKMESH_SUBSET) == 144, "SDK Mesh structure size incorrect" ); static_assert( sizeof(SDKMESH_FRAME) == 184, "SDK Mesh structure size incorrect" ); static_assert( sizeof(SDKMESH_MATERIAL) == 1256, "SDK Mesh structure size incorrect" ); static_assert( sizeof(SDKANIMATION_FILE_HEADER) == 40, "SDK Mesh structure size incorrect" ); static_assert( sizeof(SDKANIMATION_DATA) == 40, "SDK Mesh structure size incorrect" ); static_assert( sizeof(SDKANIMATION_FRAME_DATA) == 112, "SDK Mesh structure size incorrect" ); #ifndef _CONVERTER_APP_ //-------------------------------------------------------------------------------------- // AsyncLoading callbacks //-------------------------------------------------------------------------------------- typedef void ( CALLBACK*LPCREATETEXTUREFROMFILE11 )( _In_ ID3D11Device* pDev, _In_z_ char* szFileName, _Outptr_ ID3D11ShaderResourceView** ppRV, _In_opt_ void* pContext ); typedef void ( CALLBACK*LPCREATEVERTEXBUFFER11 )( _In_ ID3D11Device* pDev, _Outptr_ ID3D11Buffer** ppBuffer, _In_ D3D11_BUFFER_DESC BufferDesc, _In_ void* pData, _In_opt_ void* pContext ); typedef void ( CALLBACK*LPCREATEINDEXBUFFER11 )( _In_ ID3D11Device* pDev, _Outptr_ ID3D11Buffer** ppBuffer, _In_ D3D11_BUFFER_DESC BufferDesc, _In_ void* pData, _In_opt_ void* pContext ); struct SDKMESH_CALLBACKS11 { LPCREATETEXTUREFROMFILE11 pCreateTextureFromFile; LPCREATEVERTEXBUFFER11 pCreateVertexBuffer; LPCREATEINDEXBUFFER11 pCreateIndexBuffer; void* pContext; }; //-------------------------------------------------------------------------------------- // CDXUTSDKMesh class. This class reads the sdkmesh file format for use by the samples //-------------------------------------------------------------------------------------- class CDXUTSDKMesh { private: UINT m_NumOutstandingResources; bool m_bLoading; //BYTE* m_pBufferData; HANDLE m_hFile; HANDLE m_hFileMappingObject; std::vector m_MappedPointers; ID3D11Device* m_pDev11; ID3D11DeviceContext* m_pDevContext11; protected: //These are the pointers to the two chunks of data loaded in from the mesh file BYTE* m_pStaticMeshData; BYTE* m_pHeapData; BYTE* m_pAnimationData; BYTE** m_ppVertices; BYTE** m_ppIndices; //Keep track of the path WCHAR m_strPathW[MAX_PATH]; char m_strPath[MAX_PATH]; //General mesh info SDKMESH_HEADER* m_pMeshHeader; SDKMESH_VERTEX_BUFFER_HEADER* m_pVertexBufferArray; SDKMESH_INDEX_BUFFER_HEADER* m_pIndexBufferArray; SDKMESH_MESH* m_pMeshArray; SDKMESH_SUBSET* m_pSubsetArray; SDKMESH_FRAME* m_pFrameArray; SDKMESH_MATERIAL* m_pMaterialArray; // Adjacency information (not part of the m_pStaticMeshData, so it must be created and destroyed separately ) SDKMESH_INDEX_BUFFER_HEADER* m_pAdjacencyIndexBufferArray; //Animation SDKANIMATION_FILE_HEADER* m_pAnimationHeader; SDKANIMATION_FRAME_DATA* m_pAnimationFrameData; DirectX::XMFLOAT4X4* m_pBindPoseFrameMatrices; DirectX::XMFLOAT4X4* m_pTransformedFrameMatrices; DirectX::XMFLOAT4X4* m_pWorldPoseFrameMatrices; protected: void LoadMaterials( _In_ ID3D11Device* pd3dDevice, _In_reads_(NumMaterials) SDKMESH_MATERIAL* pMaterials, _In_ UINT NumMaterials, _In_opt_ SDKMESH_CALLBACKS11* pLoaderCallbacks = nullptr ); HRESULT CreateVertexBuffer( _In_ ID3D11Device* pd3dDevice, _In_ SDKMESH_VERTEX_BUFFER_HEADER* pHeader, _In_reads_(pHeader->SizeBytes) void* pVertices, _In_opt_ SDKMESH_CALLBACKS11* pLoaderCallbacks = nullptr ); HRESULT CreateIndexBuffer( _In_ ID3D11Device* pd3dDevice, _In_ SDKMESH_INDEX_BUFFER_HEADER* pHeader, _In_reads_(pHeader->SizeBytes) void* pIndices, _In_opt_ SDKMESH_CALLBACKS11* pLoaderCallbacks = nullptr ); virtual HRESULT CreateFromFile( _In_opt_ ID3D11Device* pDev11, _In_z_ LPCWSTR szFileName, _In_opt_ SDKMESH_CALLBACKS11* pLoaderCallbacks11 = nullptr ); virtual HRESULT CreateFromMemory( _In_opt_ ID3D11Device* pDev11, _In_reads_(DataBytes) BYTE* pData, _In_ size_t DataBytes, _In_ bool bCopyStatic, _In_opt_ SDKMESH_CALLBACKS11* pLoaderCallbacks11 = nullptr ); //frame manipulation void TransformBindPoseFrame( _In_ UINT iFrame, _In_ DirectX::CXMMATRIX parentWorld ); void TransformFrame( _In_ UINT iFrame, _In_ DirectX::CXMMATRIX parentWorld, _In_ double fTime ); void TransformFrameAbsolute( _In_ UINT iFrame, _In_ double fTime ); //Direct3D 11 rendering helpers void RenderMesh( _In_ UINT iMesh, _In_ bool bAdjacent, _In_ ID3D11DeviceContext* pd3dDeviceContext, _In_ UINT iDiffuseSlot, _In_ UINT iNormalSlot, _In_ UINT iSpecularSlot ); void RenderFrame( _In_ UINT iFrame, _In_ bool bAdjacent, _In_ ID3D11DeviceContext* pd3dDeviceContext, _In_ UINT iDiffuseSlot, _In_ UINT iNormalSlot, _In_ UINT iSpecularSlot ); public: CDXUTSDKMesh(); virtual ~CDXUTSDKMesh(); virtual HRESULT Create( _In_ ID3D11Device* pDev11, _In_z_ LPCWSTR szFileName, _In_opt_ SDKMESH_CALLBACKS11* pLoaderCallbacks = nullptr ); virtual HRESULT Create( _In_ ID3D11Device* pDev11, BYTE* pData, size_t DataBytes, _In_ bool bCopyStatic=false, _In_opt_ SDKMESH_CALLBACKS11* pLoaderCallbacks = nullptr ); virtual HRESULT LoadAnimation( _In_z_ const WCHAR* szFileName ); virtual void Destroy(); //Frame manipulation void TransformBindPose( _In_ DirectX::CXMMATRIX world ) { TransformBindPoseFrame( 0, world ); }; void TransformMesh( _In_ DirectX::CXMMATRIX world, _In_ double fTime ); //Direct3D 11 Rendering virtual void Render( _In_ ID3D11DeviceContext* pd3dDeviceContext, _In_ UINT iDiffuseSlot = INVALID_SAMPLER_SLOT, _In_ UINT iNormalSlot = INVALID_SAMPLER_SLOT, _In_ UINT iSpecularSlot = INVALID_SAMPLER_SLOT ); virtual void RenderAdjacent( _In_ ID3D11DeviceContext* pd3dDeviceContext, _In_ UINT iDiffuseSlot = INVALID_SAMPLER_SLOT, _In_ UINT iNormalSlot = INVALID_SAMPLER_SLOT, _In_ UINT iSpecularSlot = INVALID_SAMPLER_SLOT ); //Helpers (D3D11 specific) static D3D11_PRIMITIVE_TOPOLOGY GetPrimitiveType11( _In_ SDKMESH_PRIMITIVE_TYPE PrimType ); DXGI_FORMAT GetIBFormat11( _In_ UINT iMesh ) const; ID3D11Buffer* GetVB11( _In_ UINT iMesh, _In_ UINT iVB ) const; ID3D11Buffer* GetIB11( _In_ UINT iMesh ) const; SDKMESH_INDEX_TYPE GetIndexType( _In_ UINT iMesh ) const; ID3D11Buffer* GetAdjIB11( _In_ UINT iMesh ) const; //Helpers (general) const char* GetMeshPathA() const; const WCHAR* GetMeshPathW() const; UINT GetNumMeshes() const; UINT GetNumMaterials() const; UINT GetNumVBs() const; UINT GetNumIBs() const; ID3D11Buffer* GetVB11At( _In_ UINT iVB ) const; ID3D11Buffer* GetIB11At( _In_ UINT iIB ) const; BYTE* GetRawVerticesAt( _In_ UINT iVB ) const; BYTE* GetRawIndicesAt( _In_ UINT iIB ) const; SDKMESH_MATERIAL* GetMaterial( _In_ UINT iMaterial ) const; SDKMESH_MESH* GetMesh( _In_ UINT iMesh ) const; UINT GetNumSubsets( _In_ UINT iMesh ) const; SDKMESH_SUBSET* GetSubset( _In_ UINT iMesh, _In_ UINT iSubset ) const; UINT GetVertexStride( _In_ UINT iMesh, _In_ UINT iVB ) const; UINT GetNumFrames() const; SDKMESH_FRAME* GetFrame( _In_ UINT iFrame ) const; SDKMESH_FRAME* FindFrame( _In_z_ const char* pszName ) const; UINT64 GetNumVertices( _In_ UINT iMesh, _In_ UINT iVB ) const; UINT64 GetNumIndices( _In_ UINT iMesh ) const; DirectX::XMVECTOR GetMeshBBoxCenter( _In_ UINT iMesh ) const; DirectX::XMVECTOR GetMeshBBoxExtents( _In_ UINT iMesh ) const; UINT GetOutstandingResources() const; UINT GetOutstandingBufferResources() const; bool CheckLoadDone(); bool IsLoaded() const; bool IsLoading() const; void SetLoading( _In_ bool bLoading ); BOOL HadLoadingError() const; //Animation UINT GetNumInfluences( _In_ UINT iMesh ) const; DirectX::XMMATRIX GetMeshInfluenceMatrix( _In_ UINT iMesh, _In_ UINT iInfluence ) const; UINT GetAnimationKeyFromTime( _In_ double fTime ) const; DirectX::XMMATRIX GetWorldMatrix( _In_ UINT iFrameIndex ) const; DirectX::XMMATRIX GetInfluenceMatrix( _In_ UINT iFrameIndex ) const; bool GetAnimationProperties( _Out_ UINT* pNumKeys, _Out_ float* pFrameTime ) const; }; #endif