text: //--------------------------------------------------------------------------------------
  // File: SDKMesh.h
  //
  // SDKMESH format is generated by the legacy DirectX SDK's Content Exporter and
  // originally rendered by the DXUT helper class SDKMesh
  //
  // http://go.microsoft.com/fwlink/?LinkId=226208
  //
  // Copyright (c) Microsoft Corporation. All rights reserved.
  // Licensed under the MIT License.
  //
  // http://go.microsoft.com/fwlink/?LinkId=248929
  // http://go.microsoft.com/fwlink/?LinkID=615561
  //--------------------------------------------------------------------------------------
  
  #pragma once
  
  #include "Graphics\d3dx12.h"
  #include <d3d12.h>
  
  namespace DXUT
  {
      // .SDKMESH files
  
      // SDKMESH_HEADER
      // SDKMESH_VERTEX_BUFFER_HEADER header->VertexStreamHeadersOffset
      // SDKMESH_INDEX_BUFFER_HEADER  header->IndexStreamHeadersOffset
      // SDKMESH_MESH                 header->MeshDataOffset
      // SDKMESH_SUBSET               header->SubsetDataOffset
      // SDKMESH_FRAME                header->FrameDataOffset
      // SDKMESH_MATERIAL             header->MaterialDataOffset
      // [header->NonBufferDataSize]
      // { [ header->NumVertexBuffers]
      //      VB data
      // }
      // { [ header->NumIndexBuffers]
      //      IB data
      // }
  
  
      // .SDDKANIM files
  
      // SDKANIMATION_FILE_HEADER
      // uint8_t[] - Length of fileheader->AnimationDataSize
  
      // .SDKMESH uses Direct3D 9 decls, but only a subset of these is ever generated by the legacy DirectX SDK Content Exporter
  
      // D3DDECLUSAGE_POSITION / D3DDECLTYPE_FLOAT3
      // (D3DDECLUSAGE_BLENDWEIGHT / D3DDECLTYPE_UBYTE4N
      // D3DDECLUSAGE_BLENDINDICES / D3DDECLTYPE_UBYTE4)?
      // (D3DDECLUSAGE_NORMAL / D3DDECLTYPE_FLOAT3, D3DDECLTYPE_FLOAT16_4, D3DDECLTYPE_SHORT4N, D3DDECLTYPE_UBYTE4N, or D3DDECLTYPE_DEC3N)?
      // (D3DDECLUSAGE_COLOR / D3DDECLTYPE_D3DCOLOR)?
      // (D3DDECLUSAGE_TEXCOORD / D3DDECLTYPE_FLOAT1, D3DDECLTYPE_FLOAT2 or D3DDECLTYPE_FLOAT16_2, D3DDECLTYPE_FLOAT3 or D3DDECLTYPE_FLOAT16_4, D3DDECLTYPE_FLOAT4 or D3DDECLTYPE_FLOAT16_4)*
      // (D3DDECLUSAGE_TANGENT / same as D3DDECLUSAGE_NORMAL)?
      // (D3DDECLUSAGE_BINORMAL / same as D3DDECLUSAGE_NORMAL)?
  
      enum D3DDECLUSAGE
      {
          D3DDECLUSAGE_POSITION = 0,
          D3DDECLUSAGE_BLENDWEIGHT =1,
          D3DDECLUSAGE_BLENDINDICES =2,
          D3DDECLUSAGE_NORMAL =3,
          D3DDECLUSAGE_TEXCOORD = 5,
          D3DDECLUSAGE_TANGENT = 6,
          D3DDECLUSAGE_BINORMAL = 7,
          D3DDECLUSAGE_COLOR = 10
      };
  
      enum D3DDECLTYPE
      {
          D3DDECLTYPE_FLOAT1    =  0,  // 1D float expanded to (value, 0., 0., 1.)
          D3DDECLTYPE_FLOAT2    =  1,  // 2D float expanded to (value, value, 0., 1.)
          D3DDECLTYPE_FLOAT3    =  2,  // 3D float expanded to (value, value, value, 1.)
          D3DDECLTYPE_FLOAT4    =  3,  // 4D float
          D3DDECLTYPE_D3DCOLOR  =  4,  // 4D packed unsigned bytes mapped to 0. to 1. range
                                       // Input is in D3DCOLOR format (ARGB) expanded to (R, G, B, A)
          D3DDECLTYPE_UBYTE4    =  5,  // 4D unsigned uint8_t
          D3DDECLTYPE_UBYTE4N   =  8,  // Each of 4 bytes is normalized by dividing to 255.0
          D3DDECLTYPE_SHORT4N   = 10,  // 4D signed short normalized (v[0]/32767.0,v[1]/32767.0,v[2]/32767.0,v[3]/32767.0)
          D3DDECLTYPE_DEC3N     = 14,  // 3D signed normalized (v[0]/511.0, v[1]/511.0, v[2]/511.0, 1.)
                                       // Note: There is no equivalent to D3DDECLTYPE_DEC3N (14) as a DXGI_FORMAT
          D3DDECLTYPE_FLOAT16_2 = 15,  // Two 16-bit floating point values, expanded to (value, value, 0, 1)
          D3DDECLTYPE_FLOAT16_4 = 16,  // Four 16-bit floating point values
  
          D3DDECLTYPE_UNUSED    = 17,  // When the type field in a decl is unused.
  
          // These are extensions for DXGI-based versions of Direct3D
          D3DDECLTYPE_DXGI_R10G10B10A2_UNORM = 32 + DXGI_FORMAT_R10G10B10A2_UNORM,
          D3DDECLTYPE_DXGI_R11G11B10_FLOAT   = 32 + DXGI_FORMAT_R11G11B10_FLOAT,
          D3DDECLTYPE_DXGI_R8G8B8A8_SNORM    = 32 + DXGI_FORMAT_R8G8B8A8_SNORM
      };
  
      #pragma pack(push,4)
  
      struct D3DVERTEXELEMENT9
      {
          uint16_t Stream;     // Stream index
          uint16_t Offset;     // Offset in the stream in bytes
          uint8_t  Type;       // Data type
          uint8_t  Method;     // Processing method
          uint8_t  Usage;      // Semantics
          uint8_t  UsageIndex; // Semantic index
      };
  
      #pragma pack(pop)
  
      //--------------------------------------------------------------------------------------
      // Hard Defines for the various structures
      //--------------------------------------------------------------------------------------
      const uint32_t SDKMESH_FILE_VERSION = 101;
      const uint32_t SDKMESH_FILE_VERSION_V2 = 200;
  
      const uint32_t MAX_VERTEX_ELEMENTS = 32;
      const uint32_t MAX_VERTEX_STREAMS = 16;
      const uint32_t MAX_FRAME_NAME = 100;
      const uint32_t MAX_MESH_NAME = 100;
      const uint32_t MAX_SUBSET_NAME = 100;
      const uint32_t MAX_MATERIAL_NAME = 100;
      const uint32_t MAX_TEXTURE_NAME = MAX_PATH;
      const uint32_t MAX_MATERIAL_PATH = MAX_PATH;
      const uint32_t INVALID_FRAME = uint32_t(-1);
      const uint32_t INVALID_MESH =  uint32_t(-1);
      const uint32_t INVALID_MATERIAL = uint32_t(-1);
      const uint32_t INVALID_SUBSET = uint32_t(-1);
      const uint32_t INVALID_ANIMATION_DATA = uint32_t(-1);
      const uint32_t INVALID_SAMPLER_SLOT = uint32_t(-1);
      const uint32_t ERROR_RESOURCE_VALUE = 1;
  
      //--------------------------------------------------------------------------------------
      // 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.
      //--------------------------------------------------------------------------------------
      #pragma pack(push,8)
  
      struct SDKMESH_HEADER
      {
          //Basic Info and sizes
          uint32_t Version;
          uint8_t  IsBigEndian;
          uint64_t HeaderSize;
          uint64_t NonBufferDataSize;
          uint64_t BufferDataSize;
  
          //Stats
          uint32_t NumVertexBuffers;
          uint32_t NumIndexBuffers;
          uint32_t NumMeshes;
          uint32_t NumTotalSubsets;
          uint32_t NumFrames;
          uint32_t NumMaterials;
  
          //Offsets to Data
          uint64_t VertexStreamHeadersOffset;
          uint64_t IndexStreamHeadersOffset;
          uint64_t MeshDataOffset;
          uint64_t SubsetDataOffset;
          uint64_t FrameDataOffset;
          uint64_t MaterialDataOffset;
      };
  
      struct SDKMESH_VERTEX_BUFFER_HEADER
      {
          uint64_t NumVertices;
          uint64_t SizeBytes;
          uint64_t StrideBytes;
          D3DVERTEXELEMENT9 Decl[MAX_VERTEX_ELEMENTS];
          uint64_t DataOffset;
      };
  
      struct SDKMESH_INDEX_BUFFER_HEADER
      {
          uint64_t NumIndices;
          uint64_t SizeBytes;
          uint32_t IndexType;
          uint64_t DataOffset;
      };
  
      struct SDKMESH_MESH
      {
          char Name[MAX_MESH_NAME];
          uint8_t NumVertexBuffers;
          uint32_t VertexBuffers[MAX_VERTEX_STREAMS];
          uint32_t IndexBuffer;
          uint32_t NumSubsets;
          uint32_t NumFrameInfluences; //aka bones
  
          DirectX::XMFLOAT3 BoundingBoxCenter;
          DirectX::XMFLOAT3 BoundingBoxExtents;
  
          union
          {
              uint64_t SubsetOffset;
              INT* pSubsets;
          };
          union
          {
              uint64_t FrameInfluenceOffset;
              uint32_t* pFrameInfluences;
          };
      };
  
      struct SDKMESH_SUBSET
      {
          char Name[MAX_SUBSET_NAME];
          uint32_t MaterialID;
          uint32_t PrimitiveType;
          uint64_t IndexStart;
          uint64_t IndexCount;
          uint64_t VertexStart;
          uint64_t VertexCount;
      };
  
      struct SDKMESH_FRAME
      {
          char Name[MAX_FRAME_NAME];
          uint32_t Mesh;
          uint32_t ParentFrame;
          uint32_t ChildFrame;
          uint32_t SiblingFrame;
          DirectX::XMFLOAT4X4 Matrix;
          uint32_t 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;
  
          uint64_t Force64_1;
          uint64_t Force64_2;
          uint64_t Force64_3;
          uint64_t Force64_4;
          uint64_t Force64_5;
          uint64_t Force64_6;
      };
  
      struct SDKMESH_MATERIAL_V2
      {
          char    Name[MAX_MATERIAL_NAME];
  
          // PBR materials
          char    RMATexture[MAX_TEXTURE_NAME];
          char    AlbetoTexture[MAX_TEXTURE_NAME];
          char    NormalTexture[MAX_TEXTURE_NAME];
          char    EmissiveTexture[MAX_TEXTURE_NAME];
  
          float   Alpha;
  
          char    Reserved[60];
  
          uint64_t Force64_1;
          uint64_t Force64_2;
          uint64_t Force64_3;
          uint64_t Force64_4;
          uint64_t Force64_5;
          uint64_t Force64_6;
      };
  
      struct SDKANIMATION_FILE_HEADER
      {
          uint32_t Version;
          uint8_t  IsBigEndian;
          uint32_t FrameTransformType;
          uint32_t NumFrames;
          uint32_t NumAnimationKeys;
          uint32_t AnimationFPS;
          uint64_t AnimationDataSize;
          uint64_t AnimationDataOffset;
      };
  
      struct SDKANIMATION_DATA
      {
          DirectX::XMFLOAT3 Translation;
          DirectX::XMFLOAT4 Orientation;
          DirectX::XMFLOAT3 Scaling;
      };
  
      struct SDKANIMATION_FRAME_DATA
      {
          char FrameName[MAX_FRAME_NAME];
          uint64_t DataOffset;
      };
  
      #pragma pack(pop)
  
  } // namespace
  
  static_assert( sizeof(DXUT::D3DVERTEXELEMENT9) == 8, "Direct3D9 Decl structure size incorrect" );
  static_assert( sizeof(DXUT::SDKMESH_HEADER)== 104, "SDK Mesh structure size incorrect" );
  static_assert( sizeof(DXUT::SDKMESH_VERTEX_BUFFER_HEADER) == 288, "SDK Mesh structure size incorrect" );
  static_assert( sizeof(DXUT::SDKMESH_INDEX_BUFFER_HEADER) == 32, "SDK Mesh structure size incorrect" );
  static_assert( sizeof(DXUT::SDKMESH_MESH) == 224, "SDK Mesh structure size incorrect" );
  static_assert( sizeof(DXUT::SDKMESH_SUBSET) == 144, "SDK Mesh structure size incorrect" );
  static_assert( sizeof(DXUT::SDKMESH_FRAME) == 184, "SDK Mesh structure size incorrect" );
  static_assert( sizeof(DXUT::SDKMESH_MATERIAL) == 1256, "SDK Mesh structure size incorrect" );
  static_assert( sizeof(DXUT::SDKMESH_MATERIAL_V2) == sizeof(DXUT::SDKMESH_MATERIAL), "SDK Mesh structure size incorrect" );
  static_assert( sizeof(DXUT::SDKANIMATION_FILE_HEADER) == 40, "SDK Mesh structure size incorrect" );
  static_assert( sizeof(DXUT::SDKANIMATION_DATA) == 40, "SDK Mesh structure size incorrect" );
  static_assert( sizeof(DXUT::SDKANIMATION_FRAME_DATA) == 112, "SDK Mesh structure size incorrect" );
  