Browse Source

Initial commit for native fbx exporter

Simon 10 năm trước cách đây
mục cha
commit
89f06535e9
100 tập tin đã thay đổi với 103018 bổ sung0 xóa
  1. 1141 0
      Exporters/FBX/3rdParty/DirectXTex/BC.cpp
  2. 892 0
      Exporters/FBX/3rdParty/DirectXTex/BC.h
  3. 548 0
      Exporters/FBX/3rdParty/DirectXTex/BC4BC5.cpp
  4. 2871 0
      Exporters/FBX/3rdParty/DirectXTex/BC6HBC7.cpp
  5. 604 0
      Exporters/FBX/3rdParty/DirectXTex/BCDirectCompute.cpp
  6. 68 0
      Exporters/FBX/3rdParty/DirectXTex/BCDirectCompute.h
  7. 239 0
      Exporters/FBX/3rdParty/DirectXTex/DDS.h
  8. 616 0
      Exporters/FBX/3rdParty/DirectXTex/DirectXTex.h
  9. 352 0
      Exporters/FBX/3rdParty/DirectXTex/DirectXTex.inl
  10. 809 0
      Exporters/FBX/3rdParty/DirectXTex/DirectXTexCompress.cpp
  11. 402 0
      Exporters/FBX/3rdParty/DirectXTex/DirectXTexCompressGPU.cpp
  12. 4515 0
      Exporters/FBX/3rdParty/DirectXTex/DirectXTexConvert.cpp
  13. 875 0
      Exporters/FBX/3rdParty/DirectXTex/DirectXTexD3D11.cpp
  14. 2002 0
      Exporters/FBX/3rdParty/DirectXTex/DirectXTexDDS.cpp
  15. 331 0
      Exporters/FBX/3rdParty/DirectXTex/DirectXTexFlipRotate.cpp
  16. 821 0
      Exporters/FBX/3rdParty/DirectXTex/DirectXTexImage.cpp
  17. 3051 0
      Exporters/FBX/3rdParty/DirectXTex/DirectXTexMipmaps.cpp
  18. 354 0
      Exporters/FBX/3rdParty/DirectXTex/DirectXTexMisc.cpp
  19. 383 0
      Exporters/FBX/3rdParty/DirectXTex/DirectXTexNormalMaps.cpp
  20. 209 0
      Exporters/FBX/3rdParty/DirectXTex/DirectXTexP.h
  21. 229 0
      Exporters/FBX/3rdParty/DirectXTex/DirectXTexPMAlpha.cpp
  22. 1034 0
      Exporters/FBX/3rdParty/DirectXTex/DirectXTexResize.cpp
  23. 1391 0
      Exporters/FBX/3rdParty/DirectXTex/DirectXTexTGA.cpp
  24. 1029 0
      Exporters/FBX/3rdParty/DirectXTex/DirectXTexUtil.cpp
  25. 1128 0
      Exporters/FBX/3rdParty/DirectXTex/DirectXTexWIC.cpp
  26. 432 0
      Exporters/FBX/3rdParty/DirectXTex/DirectXTex_Desktop_2012.vcxproj
  27. 38 0
      Exporters/FBX/3rdParty/DirectXTex/DirectXTex_Desktop_2012.vcxproj.filters
  28. 436 0
      Exporters/FBX/3rdParty/DirectXTex/DirectXTex_Desktop_2013.vcxproj
  29. 38 0
      Exporters/FBX/3rdParty/DirectXTex/DirectXTex_Desktop_2013.vcxproj.filters
  30. 424 0
      Exporters/FBX/3rdParty/DirectXTex/Filters.h
  31. 2566 0
      Exporters/FBX/3rdParty/DirectXTex/Shaders/BC6HEncode.hlsl
  32. 1907 0
      Exporters/FBX/3rdParty/DirectXTex/Shaders/BC7Encode.hlsl
  33. 37 0
      Exporters/FBX/3rdParty/DirectXTex/Shaders/CompileShaders.cmd
  34. 22215 0
      Exporters/FBX/3rdParty/DirectXTex/Shaders/Compiled/BC6HEncode_EncodeBlockCS.inc
  35. 3375 0
      Exporters/FBX/3rdParty/DirectXTex/Shaders/Compiled/BC6HEncode_TryModeG10CS.inc
  36. 5103 0
      Exporters/FBX/3rdParty/DirectXTex/Shaders/Compiled/BC6HEncode_TryModeLE10CS.inc
  37. 10152 0
      Exporters/FBX/3rdParty/DirectXTex/Shaders/Compiled/BC7Encode_EncodeBlockCS.inc
  38. 3824 0
      Exporters/FBX/3rdParty/DirectXTex/Shaders/Compiled/BC7Encode_TryMode02CS.inc
  39. 3962 0
      Exporters/FBX/3rdParty/DirectXTex/Shaders/Compiled/BC7Encode_TryMode137CS.inc
  40. 3027 0
      Exporters/FBX/3rdParty/DirectXTex/Shaders/Compiled/BC7Encode_TryMode456CS.inc
  41. 34 0
      Exporters/FBX/3rdParty/DirectXTex/scoped.h
  42. 273 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk.h
  43. 419 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/arch/fbxalloc.h
  44. 247 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/arch/fbxarch.h
  45. 93 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/arch/fbxdebug.h
  46. 510 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/arch/fbxnew.h
  47. 97 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/arch/fbxstdcompliant.h
  48. 264 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/arch/fbxtypes.h
  49. 487 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/base/fbxarray.h
  50. 90 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/base/fbxbitset.h
  51. 95 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/base/fbxcharptrset.h
  52. 213 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/base/fbxcontainerallocators.h
  53. 324 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/base/fbxdynamicarray.h
  54. 257 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/base/fbxfile.h
  55. 80 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/base/fbxfolder.h
  56. 411 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/base/fbxhashmap.h
  57. 262 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/base/fbxintrusivelist.h
  58. 408 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/base/fbxmap.h
  59. 67 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/base/fbxmemorypool.h
  60. 115 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/base/fbxmultimap.h
  61. 62 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/base/fbxpair.h
  62. 1398 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/base/fbxredblacktree.h
  63. 227 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/base/fbxset.h
  64. 119 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/base/fbxstatus.h
  65. 505 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/base/fbxstring.h
  66. 368 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/base/fbxstringlist.h
  67. 648 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/base/fbxtime.h
  68. 99 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/base/fbxtimecode.h
  69. 168 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/base/fbxutils.h
  70. 166 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxclassid.h
  71. 312 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxconnectionpoint.h
  72. 267 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxdatatypes.h
  73. 94 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxemitter.h
  74. 188 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxevent.h
  75. 129 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxeventhandler.h
  76. 121 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxlistener.h
  77. 86 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxloadingstrategy.h
  78. 555 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxmanager.h
  79. 49 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxmodule.h
  80. 1617 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxobject.h
  81. 96 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxperipheral.h
  82. 264 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxplugin.h
  83. 74 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxplugincontainer.h
  84. 1286 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxproperty.h
  85. 146 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxpropertydef.h
  86. 576 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxpropertyhandle.h
  87. 1736 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxpropertypage.h
  88. 1174 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxpropertytypes.h
  89. 260 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxquery.h
  90. 57 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxqueryevent.h
  91. 58 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxscopedloadingdirectory.h
  92. 64 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxscopedloadingfilename.h
  93. 126 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxstream.h
  94. 135 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxsymbol.h
  95. 219 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxsystemunit.h
  96. 227 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxxref.h
  97. 340 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/math/fbxaffinematrix.h
  98. 325 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/math/fbxdualquaternion.h
  99. 501 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/math/fbxmath.h
  100. 0 0
      Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/math/fbxmatrix.h

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1141 - 0
Exporters/FBX/3rdParty/DirectXTex/BC.cpp


+ 892 - 0
Exporters/FBX/3rdParty/DirectXTex/BC.h

@@ -0,0 +1,892 @@
+//-------------------------------------------------------------------------------------
+// BC.h
+//  
+// Block-compression (BC) functionality
+//
+// 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=248926
+//-------------------------------------------------------------------------------------
+
+#if defined(_MSC_VER) && (_MSC_VER > 1000)
+#pragma once
+#endif
+
+#include <assert.h>
+#include <directxmath.h>
+#include <directxpackedvector.h>
+
+namespace DirectX
+{
+
+//-------------------------------------------------------------------------------------
+// Constants
+//-------------------------------------------------------------------------------------
+
+const uint16_t F16S_MASK    = 0x8000;   // f16 sign mask
+const uint16_t F16EM_MASK   = 0x7fff;   // f16 exp & mantissa mask
+const uint16_t F16MAX       = 0x7bff;   // MAXFLT bit pattern for XMHALF
+
+#define SIGN_EXTEND(x,nb) ((((x)&(1<<((nb)-1)))?((~0)<<(nb)):0)|(x))
+
+// Because these are used in SAL annotations, they need to remain macros rather than const values
+#define NUM_PIXELS_PER_BLOCK 16
+#define BC6H_MAX_REGIONS 2
+#define BC6H_MAX_INDICES 16
+#define BC7_MAX_REGIONS 3
+#define BC7_MAX_INDICES 16
+
+const size_t BC6H_NUM_CHANNELS = 3;
+const size_t BC6H_MAX_SHAPES = 32;
+
+const size_t BC7_NUM_CHANNELS = 4;
+const size_t BC7_MAX_SHAPES = 64;
+
+const int32_t BC67_WEIGHT_MAX = 64;
+const uint32_t BC67_WEIGHT_SHIFT = 6;
+const int32_t BC67_WEIGHT_ROUND = 32;
+
+extern const int g_aWeights2[4];
+extern const int g_aWeights3[8];
+extern const int g_aWeights4[16];
+
+enum BC_FLAGS
+{
+    BC_FLAGS_NONE       = 0x0,
+    BC_FLAGS_DITHER_RGB = 0x10000,  // Enables dithering for RGB colors for BC1-3
+    BC_FLAGS_DITHER_A   = 0x20000,  // Enables dithering for Alpha channel for BC1-3
+    BC_FLAGS_UNIFORM    = 0x40000,  // By default, uses perceptual weighting for BC1-3; this flag makes it a uniform weighting
+};
+
+//-------------------------------------------------------------------------------------
+// Structures
+//-------------------------------------------------------------------------------------
+class HDRColorA;
+
+class LDRColorA
+{
+public:
+    uint8_t r, g, b, a;
+
+    LDRColorA() {}
+    LDRColorA(uint8_t _r, uint8_t _g, uint8_t _b, uint8_t _a) : r(_r), g(_g), b(_b), a(_a) {}
+
+    const uint8_t& operator [] (_In_range_(0,3) size_t uElement) const
+    {
+        switch(uElement)
+        {
+        case 0: return r;
+        case 1: return g;
+        case 2: return b;
+        case 3: return a;
+        default: assert(false); return r;
+        }
+    }
+
+    uint8_t& operator [] (_In_range_(0,3) size_t uElement)
+    {
+        switch(uElement)
+        {
+        case 0: return r;
+        case 1: return g;
+        case 2: return b;
+        case 3: return a;
+        default: assert(false); return r;
+        }
+    }
+
+    LDRColorA operator = (_In_ const HDRColorA& c);
+
+    static void InterpolateRGB(_In_ const LDRColorA& c0, _In_ const LDRColorA& c1, _In_ size_t wc, _In_ _In_range_(2, 4) size_t wcprec, _Out_ LDRColorA& out)
+    {
+        const int* aWeights = nullptr;
+        switch(wcprec)
+        {
+        case 2: aWeights = g_aWeights2; assert( wc < 4 ); _Analysis_assume_( wc < 4 ); break;
+        case 3: aWeights = g_aWeights3; assert( wc < 8 ); _Analysis_assume_( wc < 8 ); break;
+        case 4: aWeights = g_aWeights4; assert( wc < 16 ); _Analysis_assume_( wc < 16 ); break;
+        default: assert(false); out.r = out.g = out.b = 0; return;
+        }
+        out.r = uint8_t((uint32_t(c0.r) * uint32_t(BC67_WEIGHT_MAX - aWeights[wc]) + uint32_t(c1.r) * uint32_t(aWeights[wc]) + BC67_WEIGHT_ROUND) >> BC67_WEIGHT_SHIFT);
+        out.g = uint8_t((uint32_t(c0.g) * uint32_t(BC67_WEIGHT_MAX - aWeights[wc]) + uint32_t(c1.g) * uint32_t(aWeights[wc]) + BC67_WEIGHT_ROUND) >> BC67_WEIGHT_SHIFT);
+        out.b = uint8_t((uint32_t(c0.b) * uint32_t(BC67_WEIGHT_MAX - aWeights[wc]) + uint32_t(c1.b) * uint32_t(aWeights[wc]) + BC67_WEIGHT_ROUND) >> BC67_WEIGHT_SHIFT);
+    }
+
+    static void InterpolateA(_In_ const LDRColorA& c0, _In_ const LDRColorA& c1, _In_ size_t wa, _In_range_(2, 4) _In_ size_t waprec, _Out_ LDRColorA& out)
+    {
+        const int* aWeights = nullptr;
+        switch(waprec)
+        {
+        case 2: aWeights = g_aWeights2; assert( wa < 4 ); _Analysis_assume_( wa < 4 ); break;
+        case 3: aWeights = g_aWeights3; assert( wa < 8 ); _Analysis_assume_( wa < 8 ); break;
+        case 4: aWeights = g_aWeights4; assert( wa < 16 ); _Analysis_assume_( wa < 16 ); break;
+        default: assert(false); out.a = 0; return;
+        }
+        out.a = uint8_t((uint32_t(c0.a) * uint32_t(BC67_WEIGHT_MAX - aWeights[wa]) + uint32_t(c1.a) * uint32_t(aWeights[wa]) + BC67_WEIGHT_ROUND) >> BC67_WEIGHT_SHIFT);
+    }
+
+    static void Interpolate(_In_ const LDRColorA& c0, _In_ const LDRColorA& c1, _In_ size_t wc, _In_ size_t wa, _In_ _In_range_(2, 4) size_t wcprec, _In_ _In_range_(2, 4) size_t waprec, _Out_ LDRColorA& out)
+    {
+        InterpolateRGB(c0, c1, wc, wcprec, out);
+        InterpolateA(c0, c1, wa, waprec, out);
+    }
+};
+
+static_assert( sizeof(LDRColorA) == 4, "Unexpected packing");
+
+class HDRColorA
+{
+public:
+    float r, g, b, a;
+
+public:
+    HDRColorA() {}
+    HDRColorA(float _r, float _g, float _b, float _a) : r(_r), g(_g), b(_b), a(_a) {}
+    HDRColorA(const HDRColorA& c) : r(c.r), g(c.g), b(c.b), a(c.a) {}
+    HDRColorA(const LDRColorA& c)
+    {
+        r = float(c.r) * (1.0f/255.0f);
+        g = float(c.g) * (1.0f/255.0f);
+        b = float(c.b) * (1.0f/255.0f);
+        a = float(c.a) * (1.0f/255.0f);
+    }
+
+    // binary operators
+    HDRColorA operator + ( _In_ const HDRColorA& c ) const
+    {
+        return HDRColorA(r + c.r, g + c.g, b + c.b, a + c.a);
+    }
+
+    HDRColorA operator - ( _In_ const HDRColorA& c ) const
+    {
+        return HDRColorA(r - c.r, g - c.g, b - c.b, a - c.a);
+    }
+
+    HDRColorA operator * ( _In_ float f ) const
+    {
+        return HDRColorA(r * f, g * f, b * f, a * f);
+    }
+
+    HDRColorA operator / ( _In_ float f ) const
+    {
+        float fInv = 1.0f / f;
+        return HDRColorA(r * fInv, g * fInv, b * fInv, a * fInv);
+    }
+
+    float operator * ( _In_ const HDRColorA& c ) const
+    {
+        return r * c.r + g * c.g + b * c.b + a * c.a;
+    }
+
+    // assignment operators
+    HDRColorA& operator += ( _In_ const HDRColorA& c )
+    {
+        r += c.r;
+        g += c.g;
+        b += c.b;
+        a += c.a;
+        return *this;
+    }
+    
+    HDRColorA& operator -= ( _In_ const HDRColorA& c )
+    {
+        r -= c.r;
+        g -= c.g;
+        b -= c.b;
+        a -= c.a;
+        return *this;
+    }
+    
+    HDRColorA& operator *= ( _In_ float f )
+    {
+        r *= f;
+        g *= f;
+        b *= f;
+        a *= f;
+        return *this;
+    }
+    
+    HDRColorA& operator /= ( _In_ float f )
+    {
+        float fInv = 1.0f / f;
+        r *= fInv;
+        g *= fInv;
+        b *= fInv;
+        a *= fInv;
+        return *this;
+    }
+
+    HDRColorA& operator = (_In_ const LDRColorA& c)
+    {
+        r = (float) c.r;
+        g = (float) c.g;
+        b = (float) c.b;
+        a = (float) c.a;
+        return *this;
+    }
+
+    HDRColorA& Clamp(_In_ float fMin, _In_ float fMax)
+    {
+        r = std::min<float>(fMax, std::max<float>(fMin, r));
+        g = std::min<float>(fMax, std::max<float>(fMin, g));
+        b = std::min<float>(fMax, std::max<float>(fMin, b));
+        a = std::min<float>(fMax, std::max<float>(fMin, a));
+        return *this;
+    }
+
+    LDRColorA ToLDRColorA() const
+    {
+        return LDRColorA((uint8_t) (r + 0.01f), (uint8_t) (g + 0.01f), (uint8_t) (b + 0.01f), (uint8_t) (a + 0.01f));
+    }
+};
+
+inline LDRColorA LDRColorA::operator = (_In_ const HDRColorA& c)
+{
+    LDRColorA ret;
+    HDRColorA tmp(c);
+    tmp = tmp.Clamp(0.0f, 1.0f) * 255.0f;
+    ret.r = uint8_t(tmp.r + 0.001f);
+    ret.g = uint8_t(tmp.g + 0.001f);
+    ret.b = uint8_t(tmp.b + 0.001f);
+    ret.a = uint8_t(tmp.a + 0.001f);
+    return ret;
+}
+
+struct LDREndPntPair
+{
+    LDRColorA A;
+    LDRColorA B;
+};
+
+struct HDREndPntPair
+{
+    HDRColorA A;
+    HDRColorA B;
+};
+
+inline HDRColorA* HDRColorALerp(_Out_ HDRColorA *pOut, _In_ const HDRColorA *pC1, _In_ const HDRColorA *pC2, _In_ float s)
+{
+    pOut->r = pC1->r + s * (pC2->r - pC1->r);
+    pOut->g = pC1->g + s * (pC2->g - pC1->g);
+    pOut->b = pC1->b + s * (pC2->b - pC1->b);
+    pOut->a = pC1->a + s * (pC2->a - pC1->a);
+    return pOut;
+}
+
+#pragma pack(push,1)
+// BC1/DXT1 compression (4 bits per texel)
+struct D3DX_BC1
+{
+    uint16_t    rgb[2]; // 565 colors
+    uint32_t    bitmap; // 2bpp rgb bitmap
+};
+
+// BC2/DXT2/3 compression (8 bits per texel)
+struct D3DX_BC2
+{
+    uint32_t    bitmap[2];  // 4bpp alpha bitmap
+    D3DX_BC1    bc1;        // BC1 rgb data
+};
+
+// BC3/DXT4/5 compression (8 bits per texel)
+struct D3DX_BC3
+{
+    uint8_t     alpha[2];   // alpha values
+    uint8_t     bitmap[6];  // 3bpp alpha bitmap
+    D3DX_BC1    bc1;        // BC1 rgb data
+};
+#pragma pack(pop)
+
+class INTColor
+{
+public:
+    int r, g, b;
+    int pad;
+
+public:
+    INTColor() {}
+    INTColor(int nr, int ng, int nb) {r = nr; g = ng; b = nb;}
+    INTColor(const INTColor& c) {r = c.r; g = c.g; b = c.b;}
+
+    INTColor operator - ( _In_ const INTColor& c ) const
+    {
+        return INTColor(r - c.r, g - c.g, b - c.b);
+    }
+
+    INTColor& operator += ( _In_ const INTColor& c )
+    {
+        r += c.r;
+        g += c.g;
+        b += c.b;
+        return *this;
+    }
+
+    INTColor& operator -= ( _In_ const INTColor& c )
+    {
+        r -= c.r;
+        g -= c.g;
+        b -= c.b;
+        return *this;
+    }
+
+    INTColor& operator &= ( _In_ const INTColor& c )
+    {
+        r &= c.r;
+        g &= c.g;
+        b &= c.b;
+        return *this;
+    }
+
+    int& operator [] ( _In_ uint8_t i )
+    {
+        assert(i < sizeof(INTColor) / sizeof(int));
+        _Analysis_assume_(i < sizeof(INTColor) / sizeof(int));
+        return ((int*) this)[i];
+    }
+
+    void Set(_In_ const HDRColorA& c, _In_ bool bSigned)
+    {
+        PackedVector::XMHALF4 aF16;
+
+        XMVECTOR v = XMLoadFloat4( (const XMFLOAT4*)& c );
+        XMStoreHalf4( &aF16, v );
+
+        r = F16ToINT(aF16.x, bSigned);
+        g = F16ToINT(aF16.y, bSigned);
+        b = F16ToINT(aF16.z, bSigned);
+    }
+
+    INTColor& Clamp(_In_ int iMin, _In_ int iMax)
+    {
+        r = std::min<int>(iMax, std::max<int>(iMin, r));
+        g = std::min<int>(iMax, std::max<int>(iMin, g));
+        b = std::min<int>(iMax, std::max<int>(iMin, b));
+        return *this;
+    }
+
+    INTColor& SignExtend(_In_ const LDRColorA& Prec)
+    {
+        r = SIGN_EXTEND(r, Prec.r);
+        g = SIGN_EXTEND(g, Prec.g);
+        b = SIGN_EXTEND(b, Prec.b);
+        return *this;
+    }
+
+    void ToF16(_Out_writes_(3) PackedVector::HALF aF16[3], _In_ bool bSigned) const
+    {
+        aF16[0] = INT2F16(r, bSigned);
+        aF16[1] = INT2F16(g, bSigned);
+        aF16[2] = INT2F16(b, bSigned);
+    }
+
+private:
+    static int F16ToINT(_In_ const PackedVector::HALF& f, _In_ bool bSigned)
+    {
+        uint16_t input = *((const uint16_t*) &f);
+        int out, s;
+        if(bSigned)
+        {
+            s = input & F16S_MASK;
+            input &= F16EM_MASK;
+            if(input > F16MAX) out = F16MAX;
+            else out = input;
+            out = s ? -out : out;
+        }
+        else
+        {
+            if(input & F16S_MASK) out = 0;
+            else out = input;
+        }
+        return out;
+    }
+
+    static PackedVector::HALF INT2F16(_In_ int input, _In_ bool bSigned)
+    {
+        PackedVector::HALF h;
+        uint16_t out;
+        if(bSigned)
+        {
+            int s = 0;
+            if(input < 0)
+            {
+                s = F16S_MASK;
+                input = -input;
+            }
+            out = uint16_t(s | input);
+        }
+        else
+        {
+            assert(input >= 0 && input <= F16MAX);
+            out = (uint16_t) input;
+        }
+
+        *((uint16_t*) &h) = out;
+        return h;
+    }
+};
+
+static_assert( sizeof(INTColor) == 16, "Unexpected packing");
+
+struct INTEndPntPair
+{
+    INTColor A;
+    INTColor B;
+};
+
+template< size_t SizeInBytes >
+class CBits
+{
+public:
+    uint8_t GetBit(_Inout_ size_t& uStartBit) const
+    {
+        assert(uStartBit < 128);
+        _Analysis_assume_(uStartBit < 128);
+        size_t uIndex = uStartBit >> 3;
+        uint8_t ret = (m_uBits[uIndex] >> (uStartBit - (uIndex << 3))) & 0x01;
+        uStartBit++;
+        return ret;
+    }
+
+    uint8_t GetBits(_Inout_ size_t& uStartBit, _In_ size_t uNumBits) const
+    {
+        if(uNumBits == 0) return 0;
+        assert(uStartBit + uNumBits <= 128 && uNumBits <= 8);
+        _Analysis_assume_(uStartBit + uNumBits <= 128 && uNumBits <= 8);
+        uint8_t ret;
+        size_t uIndex = uStartBit >> 3;
+        size_t uBase = uStartBit - (uIndex << 3);
+        if(uBase + uNumBits > 8)
+        {
+            size_t uFirstIndexBits = 8 - uBase;
+            size_t uNextIndexBits = uNumBits - uFirstIndexBits;
+            ret = (m_uBits[uIndex] >> uBase) | ((m_uBits[uIndex+1] & ((1 << uNextIndexBits) - 1)) << uFirstIndexBits);
+        }
+        else
+        {
+            ret = (m_uBits[uIndex] >> uBase) & ((1 << uNumBits) - 1);
+        }
+        assert(ret < (1 << uNumBits));
+        uStartBit += uNumBits;
+        return ret;
+    }
+
+    void SetBit(_Inout_ size_t& uStartBit, _In_ uint8_t uValue)
+    {
+        assert(uStartBit < 128 && uValue < 2);
+        _Analysis_assume_(uStartBit < 128 && uValue < 2);
+        size_t uIndex = uStartBit >> 3;
+        size_t uBase = uStartBit - (uIndex << 3);
+        m_uBits[uIndex] &= ~(1 << uBase);
+        m_uBits[uIndex] |= uValue << uBase;
+        uStartBit++;
+    }
+
+    void SetBits(_Inout_ size_t& uStartBit, _In_ size_t uNumBits, _In_ uint8_t uValue)
+    {
+        if(uNumBits == 0)
+            return;
+        assert(uStartBit + uNumBits <= 128 && uNumBits <= 8);
+        _Analysis_assume_(uStartBit + uNumBits <= 128 && uNumBits <= 8);
+        assert(uValue < (1 << uNumBits));
+        size_t uIndex = uStartBit >> 3;
+        size_t uBase = uStartBit - (uIndex << 3);
+        if(uBase + uNumBits > 8)
+        {
+            size_t uFirstIndexBits = 8 - uBase;
+            size_t uNextIndexBits = uNumBits - uFirstIndexBits;
+            m_uBits[uIndex] &= ~(((1 << uFirstIndexBits) - 1) << uBase);
+            m_uBits[uIndex] |= uValue << uBase;
+            m_uBits[uIndex+1] &= ~((1 << uNextIndexBits) - 1);
+            m_uBits[uIndex+1] |= uValue >> uFirstIndexBits;
+        }
+        else
+        {
+            m_uBits[uIndex] &= ~(((1 << uNumBits) - 1) << uBase);
+            m_uBits[uIndex] |= uValue << uBase;
+        }
+        uStartBit += uNumBits;
+    }
+
+private:
+    uint8_t m_uBits[ SizeInBytes ];
+};
+
+// BC6H compression (16 bits per texel)
+class D3DX_BC6H : private CBits< 16 >
+{
+public:
+    void Decode(_In_ bool bSigned, _Out_writes_(NUM_PIXELS_PER_BLOCK) HDRColorA* pOut) const;
+    void Encode(_In_ bool bSigned, _In_reads_(NUM_PIXELS_PER_BLOCK) const HDRColorA* const pIn);
+
+private:
+#pragma warning(push)
+#pragma warning(disable : 4480)
+    enum EField : uint8_t
+    {
+        NA, // N/A
+        M,  // Mode
+        D,  // Shape
+        RW,
+        RX,
+        RY,
+        RZ,
+        GW,
+        GX,
+        GY,
+        GZ,
+        BW,
+        BX,
+        BY,
+        BZ,
+    };
+#pragma warning(pop)
+
+    struct ModeDescriptor
+    {
+        EField m_eField;
+        uint8_t   m_uBit;
+    };
+
+    struct ModeInfo
+    {
+        uint8_t uMode;
+        uint8_t uPartitions;
+        bool bTransformed;
+        uint8_t uIndexPrec;
+        LDRColorA RGBAPrec[BC6H_MAX_REGIONS][2];
+    };
+
+#pragma warning(push)
+#pragma warning(disable : 4512)
+    struct EncodeParams
+    {
+        float fBestErr;
+        const bool bSigned;
+        uint8_t uMode;
+        uint8_t uShape;
+        const HDRColorA* const aHDRPixels;
+        INTEndPntPair aUnqEndPts[BC6H_MAX_SHAPES][BC6H_MAX_REGIONS];
+        INTColor aIPixels[NUM_PIXELS_PER_BLOCK];
+
+        EncodeParams(const HDRColorA* const aOriginal, bool bSignedFormat) :
+            aHDRPixels(aOriginal), fBestErr(FLT_MAX), bSigned(bSignedFormat)
+        {
+            for(size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i)
+            {
+                aIPixels[i].Set(aOriginal[i], bSigned);
+            }
+        }
+    };
+#pragma warning(pop)
+
+    static int Quantize(_In_ int iValue, _In_ int prec, _In_ bool bSigned);
+    static int Unquantize(_In_ int comp, _In_ uint8_t uBitsPerComp, _In_ bool bSigned);
+    static int FinishUnquantize(_In_ int comp, _In_ bool bSigned);
+
+    static bool EndPointsFit(_In_ const EncodeParams* pEP, _In_reads_(BC6H_MAX_REGIONS) const INTEndPntPair aEndPts[]);
+
+    void GeneratePaletteQuantized(_In_ const EncodeParams* pEP, _In_ const INTEndPntPair& endPts,
+                                  _Out_writes_(BC6H_MAX_INDICES) INTColor aPalette[]) const;
+    float MapColorsQuantized(_In_ const EncodeParams* pEP, _In_reads_(np) const INTColor aColors[], _In_ size_t np, _In_ const INTEndPntPair &endPts) const;
+    float PerturbOne(_In_ const EncodeParams* pEP, _In_reads_(np) const INTColor aColors[], _In_ size_t np, _In_ uint8_t ch,
+                     _In_ const INTEndPntPair& oldEndPts, _Out_ INTEndPntPair& newEndPts, _In_ float fOldErr, _In_ int do_b) const;
+    void OptimizeOne(_In_ const EncodeParams* pEP, _In_reads_(np) const INTColor aColors[], _In_ size_t np, _In_ float aOrgErr,
+                     _In_ const INTEndPntPair &aOrgEndPts, _Out_ INTEndPntPair &aOptEndPts) const;
+    void OptimizeEndPoints(_In_ const EncodeParams* pEP, _In_reads_(BC6H_MAX_REGIONS) const float aOrgErr[],
+                           _In_reads_(BC6H_MAX_REGIONS) const INTEndPntPair aOrgEndPts[],
+                           _Inout_updates_all_(BC6H_MAX_REGIONS) INTEndPntPair aOptEndPts[]) const;
+    static void SwapIndices(_In_ const EncodeParams* pEP, _Inout_updates_all_(BC6H_MAX_REGIONS) INTEndPntPair aEndPts[],
+                            _In_reads_(NUM_PIXELS_PER_BLOCK) size_t aIndices[]);
+    void AssignIndices(_In_ const EncodeParams* pEP, _In_reads_(BC6H_MAX_REGIONS) const INTEndPntPair aEndPts[],
+                        _Out_writes_(NUM_PIXELS_PER_BLOCK) size_t aIndices[],
+                        _Out_writes_(BC6H_MAX_REGIONS) float aTotErr[]) const;
+    void QuantizeEndPts(_In_ const EncodeParams* pEP, _Out_writes_(BC6H_MAX_REGIONS) INTEndPntPair* qQntEndPts) const;
+    void EmitBlock(_In_ const EncodeParams* pEP, _In_reads_(BC6H_MAX_REGIONS) const INTEndPntPair aEndPts[],
+                   _In_reads_(NUM_PIXELS_PER_BLOCK) const size_t aIndices[]);
+    void Refine(_Inout_ EncodeParams* pEP);
+
+    static void GeneratePaletteUnquantized(_In_ const EncodeParams* pEP, _In_ size_t uRegion, _Out_writes_(BC6H_MAX_INDICES) INTColor aPalette[]);
+    float MapColors(_In_ const EncodeParams* pEP, _In_ size_t uRegion, _In_ size_t np, _In_reads_(np) const size_t* auIndex) const;
+    float RoughMSE(_Inout_ EncodeParams* pEP) const;
+
+private:
+    const static ModeDescriptor ms_aDesc[][82];
+    const static ModeInfo ms_aInfo[];
+    const static int ms_aModeToInfo[];
+};
+
+// BC67 compression (16b bits per texel)
+class D3DX_BC7 : private CBits< 16 >
+{
+public:
+    void Decode(_Out_writes_(NUM_PIXELS_PER_BLOCK) HDRColorA* pOut) const;
+    void Encode(_In_reads_(NUM_PIXELS_PER_BLOCK) const HDRColorA* const pIn);
+
+private:
+    struct ModeInfo
+    {
+        uint8_t uPartitions;
+        uint8_t uPartitionBits;
+        uint8_t uPBits;
+        uint8_t uRotationBits;
+        uint8_t uIndexModeBits;
+        uint8_t uIndexPrec;
+        uint8_t uIndexPrec2;
+        LDRColorA RGBAPrec;
+        LDRColorA RGBAPrecWithP;
+    };
+
+#pragma warning(push)
+#pragma warning(disable : 4512)
+    struct EncodeParams
+    {
+        uint8_t uMode;
+        LDREndPntPair aEndPts[BC7_MAX_SHAPES][BC7_MAX_REGIONS];
+        LDRColorA aLDRPixels[NUM_PIXELS_PER_BLOCK];
+        const HDRColorA* const aHDRPixels;
+
+        EncodeParams(const HDRColorA* const aOriginal) : aHDRPixels(aOriginal) {}
+    };
+#pragma warning(pop)
+
+    static uint8_t Quantize(_In_ uint8_t comp, _In_ uint8_t uPrec)
+    {
+        assert(0 < uPrec && uPrec <= 8);
+        uint8_t rnd = (uint8_t) std::min<uint16_t>(255, uint16_t(comp) + (1 << (7 - uPrec)));
+        return rnd >> (8 - uPrec);
+    }
+
+    static LDRColorA Quantize(_In_ const LDRColorA& c, _In_ const LDRColorA& RGBAPrec)
+    {
+        LDRColorA q;
+        q.r = Quantize(c.r, RGBAPrec.r);
+        q.g = Quantize(c.g, RGBAPrec.g);
+        q.b = Quantize(c.b, RGBAPrec.b);
+        if(RGBAPrec.a)
+            q.a = Quantize(c.a, RGBAPrec.a);
+        else
+            q.a = 255;
+        return q;
+    }
+
+    static uint8_t Unquantize(_In_ uint8_t comp, _In_ size_t uPrec)
+    {
+        assert(0 < uPrec && uPrec <= 8);
+        comp = comp << (8 - uPrec);
+        return comp | (comp >> uPrec);
+    }
+
+    static LDRColorA Unquantize(_In_ const LDRColorA& c, _In_ const LDRColorA& RGBAPrec)
+    {
+        LDRColorA q;
+        q.r = Unquantize(c.r, RGBAPrec.r);
+        q.g = Unquantize(c.g, RGBAPrec.g);
+        q.b = Unquantize(c.b, RGBAPrec.b);
+        q.a = RGBAPrec.a > 0 ? Unquantize(c.a, RGBAPrec.a) : 255;
+        return q;
+    }
+
+    void GeneratePaletteQuantized(_In_ const EncodeParams* pEP, _In_ size_t uIndexMode, _In_ const LDREndPntPair& endpts,
+                                  _Out_writes_(BC7_MAX_INDICES) LDRColorA aPalette[]) const;
+    float PerturbOne(_In_ const EncodeParams* pEP, _In_reads_(np) const LDRColorA colors[], _In_ size_t np, _In_ size_t uIndexMode,
+                     _In_ size_t ch, _In_ const LDREndPntPair &old_endpts,
+                     _Out_ LDREndPntPair &new_endpts, _In_ float old_err, _In_ uint8_t do_b) const;
+    void Exhaustive(_In_ const EncodeParams* pEP, _In_reads_(np) const LDRColorA aColors[], _In_ size_t np, _In_ size_t uIndexMode,
+                    _In_ size_t ch, _Inout_ float& fOrgErr, _Inout_ LDREndPntPair& optEndPt) const;
+    void OptimizeOne(_In_ const EncodeParams* pEP, _In_reads_(np) const LDRColorA colors[], _In_ size_t np, _In_ size_t uIndexMode,
+                     _In_ float orig_err, _In_ const LDREndPntPair &orig_endpts, _Out_ LDREndPntPair &opt_endpts) const;
+    void OptimizeEndPoints(_In_ const EncodeParams* pEP, _In_ size_t uShape, _In_ size_t uIndexMode,
+                           _In_reads_(BC7_MAX_REGIONS) const float orig_err[],
+                           _In_reads_(BC7_MAX_REGIONS) const LDREndPntPair orig_endpts[],
+                           _Out_writes_(BC7_MAX_REGIONS) LDREndPntPair opt_endpts[]) const;
+    void AssignIndices(_In_ const EncodeParams* pEP, _In_ size_t uShape, _In_ size_t uIndexMode,
+                       _In_reads_(BC7_MAX_REGIONS) LDREndPntPair endpts[],
+                       _Out_writes_(NUM_PIXELS_PER_BLOCK) size_t aIndices[], _Out_writes_(NUM_PIXELS_PER_BLOCK) size_t aIndices2[],
+                       _Out_writes_(BC7_MAX_REGIONS) float afTotErr[]) const;
+    void EmitBlock(_In_ const EncodeParams* pEP, _In_ size_t uShape, _In_ size_t uRotation, _In_ size_t uIndexMode,
+                   _In_reads_(BC7_MAX_REGIONS) const LDREndPntPair aEndPts[],
+                   _In_reads_(NUM_PIXELS_PER_BLOCK) const size_t aIndex[],
+                   _In_reads_(NUM_PIXELS_PER_BLOCK) const size_t aIndex2[]);
+    float Refine(_In_ const EncodeParams* pEP, _In_ size_t uShape, _In_ size_t uRotation, _In_ size_t uIndexMode);
+
+    float MapColors(_In_ const EncodeParams* pEP, _In_reads_(np) const LDRColorA aColors[], _In_ size_t np, _In_ size_t uIndexMode,
+                    _In_ const LDREndPntPair& endPts, _In_ float fMinErr) const;
+    static float RoughMSE(_Inout_ EncodeParams* pEP, _In_ size_t uShape, _In_ size_t uIndexMode);
+
+private:
+    const static ModeInfo ms_aInfo[];
+};
+
+//-------------------------------------------------------------------------------------
+#pragma warning(push)
+#pragma warning(disable : 4127)
+template <bool bRange> void OptimizeAlpha(float *pX, float *pY, const float *pPoints, size_t cSteps)
+{
+    static const float pC6[] = { 5.0f/5.0f, 4.0f/5.0f, 3.0f/5.0f, 2.0f/5.0f, 1.0f/5.0f, 0.0f/5.0f };
+    static const float pD6[] = { 0.0f/5.0f, 1.0f/5.0f, 2.0f/5.0f, 3.0f/5.0f, 4.0f/5.0f, 5.0f/5.0f };
+    static const float pC8[] = { 7.0f/7.0f, 6.0f/7.0f, 5.0f/7.0f, 4.0f/7.0f, 3.0f/7.0f, 2.0f/7.0f, 1.0f/7.0f, 0.0f/7.0f };
+    static const float pD8[] = { 0.0f/7.0f, 1.0f/7.0f, 2.0f/7.0f, 3.0f/7.0f, 4.0f/7.0f, 5.0f/7.0f, 6.0f/7.0f, 7.0f/7.0f };
+
+    const float *pC = (6 == cSteps) ? pC6 : pC8;
+    const float *pD = (6 == cSteps) ? pD6 : pD8;
+
+    float MAX_VALUE = 1.0f;
+    float MIN_VALUE;
+    if (bRange)
+    {
+        MIN_VALUE = -1.0f;
+    }
+    else
+    {
+        MIN_VALUE = 0.0f;
+    }
+
+    // Find Min and Max points, as starting point
+    float fX = MAX_VALUE;
+    float fY = MIN_VALUE;
+
+    if(8 == cSteps)
+    {
+        for(size_t iPoint = 0; iPoint < NUM_PIXELS_PER_BLOCK; iPoint++)
+        {
+            if(pPoints[iPoint] < fX)
+                fX = pPoints[iPoint];
+    
+            if(pPoints[iPoint] > fY)
+                fY = pPoints[iPoint];
+        }
+    }
+    else
+    {
+        for(size_t iPoint = 0; iPoint < NUM_PIXELS_PER_BLOCK; iPoint++)
+        {
+            if(pPoints[iPoint] < fX && pPoints[iPoint] > MIN_VALUE)
+                fX = pPoints[iPoint];
+    
+            if(pPoints[iPoint] > fY && pPoints[iPoint] < MAX_VALUE)
+                fY = pPoints[iPoint];
+        }
+
+        if (fX == fY)
+        {
+            fY = MAX_VALUE;
+        }
+    }
+
+    // Use Newton's Method to find local minima of sum-of-squares error.
+    float fSteps = (float) (cSteps - 1);
+
+    for(size_t iIteration = 0; iIteration < 8; iIteration++)
+    {
+        float fScale;
+
+        if((fY - fX) < (1.0f / 256.0f))
+            break;
+        
+        fScale = fSteps / (fY - fX);
+
+        // Calculate new steps
+        float pSteps[8];
+
+        for(size_t iStep = 0; iStep < cSteps; iStep++)
+            pSteps[iStep] = pC[iStep] * fX + pD[iStep] * fY;
+
+        if(6 == cSteps)
+        {
+            pSteps[6] = MIN_VALUE;
+            pSteps[7] = MAX_VALUE;
+        }
+
+        // Evaluate function, and derivatives
+        float dX  = 0.0f;
+        float dY  = 0.0f;
+        float d2X = 0.0f;
+        float d2Y = 0.0f;
+
+        for(size_t iPoint = 0; iPoint < NUM_PIXELS_PER_BLOCK; iPoint++)
+        {
+            float fDot = (pPoints[iPoint] - fX) * fScale;
+
+            size_t iStep;
+
+            if(fDot <= 0.0f)
+                iStep = ((6 == cSteps) && (pPoints[iPoint] <= fX * 0.5f)) ? 6 : 0;
+            else if(fDot >= fSteps)
+                iStep = ((6 == cSteps) && (pPoints[iPoint] >= (fY + 1.0f) * 0.5f)) ? 7 : (cSteps - 1);
+            else
+                iStep = static_cast<int32_t>(fDot + 0.5f);
+
+
+            if(iStep < cSteps)
+            {
+                // D3DX had this computation backwards (pPoints[iPoint] - pSteps[iStep])
+                // this fix improves RMS of the alpha component
+                float fDiff = pSteps[iStep] - pPoints[iPoint];
+
+                dX  += pC[iStep] * fDiff;
+                d2X += pC[iStep] * pC[iStep];
+
+                dY  += pD[iStep] * fDiff; 
+                d2Y += pD[iStep] * pD[iStep];
+            }
+        }
+
+        // Move endpoints
+        if(d2X > 0.0f)
+            fX -= dX / d2X;
+
+        if(d2Y > 0.0f)
+            fY -= dY / d2Y;
+
+        if(fX > fY)
+        {
+            float f = fX; fX = fY; fY = f;
+        }
+
+        if((dX * dX < (1.0f / 64.0f)) && (dY * dY < (1.0f / 64.0f)))
+            break;
+    }
+
+    *pX = (fX < MIN_VALUE) ? MIN_VALUE : (fX > MAX_VALUE) ? MAX_VALUE : fX;
+    *pY = (fY < MIN_VALUE) ? MIN_VALUE : (fY > MAX_VALUE) ? MAX_VALUE : fY;
+}
+#pragma warning(pop)
+
+
+//-------------------------------------------------------------------------------------
+// Functions
+//-------------------------------------------------------------------------------------
+
+typedef void (*BC_DECODE)(XMVECTOR *pColor, const uint8_t *pBC);
+typedef void (*BC_ENCODE)(uint8_t *pDXT, const XMVECTOR *pColor, DWORD flags);
+
+void D3DXDecodeBC1(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(8) const uint8_t *pBC);
+void D3DXDecodeBC2(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(16) const uint8_t *pBC);
+void D3DXDecodeBC3(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(16) const uint8_t *pBC);
+void D3DXDecodeBC4U(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(8) const uint8_t *pBC);
+void D3DXDecodeBC4S(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(8) const uint8_t *pBC);
+void D3DXDecodeBC5U(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(16) const uint8_t *pBC);
+void D3DXDecodeBC5S(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(16) const uint8_t *pBC);
+void D3DXDecodeBC6HU(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(16) const uint8_t *pBC);
+void D3DXDecodeBC6HS(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(16) const uint8_t *pBC);
+void D3DXDecodeBC7(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(16) const uint8_t *pBC);
+
+void D3DXEncodeBC1(_Out_writes_(8) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ float alphaRef, _In_ DWORD flags);
+    // BC1 requires one additional parameter, so it doesn't match signature of BC_ENCODE above
+
+void D3DXEncodeBC2(_Out_writes_(16) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ DWORD flags);
+void D3DXEncodeBC3(_Out_writes_(16) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ DWORD flags);
+void D3DXEncodeBC4U(_Out_writes_(8) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ DWORD flags);
+void D3DXEncodeBC4S(_Out_writes_(8) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ DWORD flags);
+void D3DXEncodeBC5U(_Out_writes_(16) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ DWORD flags);
+void D3DXEncodeBC5S(_Out_writes_(16) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ DWORD flags);
+void D3DXEncodeBC6HU(_Out_writes_(16) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ DWORD flags);
+void D3DXEncodeBC6HS(_Out_writes_(16) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ DWORD flags);
+void D3DXEncodeBC7(_Out_writes_(16) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ DWORD flags);
+
+}; // namespace

+ 548 - 0
Exporters/FBX/3rdParty/DirectXTex/BC4BC5.cpp

@@ -0,0 +1,548 @@
+//-------------------------------------------------------------------------------------
+// BC4BC5.cpp
+//  
+// Block-compression (BC) functionality for BC4 and BC5 (DirectX 10 texture compression)
+//
+// 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=248926
+//-------------------------------------------------------------------------------------
+
+#include "directxtexp.h"
+
+#include "BC.h"
+
+namespace DirectX
+{
+
+//------------------------------------------------------------------------------------
+// Constants
+//------------------------------------------------------------------------------------
+
+// Because these are used in SAL annotations, they need to remain macros rather than const values
+#define BLOCK_LEN 4
+    // length of each block in texel
+
+#define BLOCK_SIZE (BLOCK_LEN * BLOCK_LEN)
+    // total texels in a 4x4 block.
+
+//------------------------------------------------------------------------------------
+// Structures
+//-------------------------------------------------------------------------------------
+
+#pragma warning(push)
+#pragma warning(disable : 4201)
+
+// BC4U/BC5U
+struct BC4_UNORM
+{
+    float R(size_t uOffset) const
+    {
+        size_t uIndex = GetIndex(uOffset);
+        return DecodeFromIndex(uIndex);
+    }
+
+    float DecodeFromIndex(size_t uIndex) const
+    {
+        if (uIndex == 0)
+            return red_0 / 255.0f;
+        if (uIndex == 1)
+            return red_1 / 255.0f;
+        float fred_0 = red_0 / 255.0f;
+        float fred_1 = red_1 / 255.0f;
+        if (red_0 > red_1)
+        {
+            uIndex -= 1;
+            return (fred_0 * (7-uIndex) + fred_1 * uIndex) / 7.0f;
+        }
+        else
+        {
+            if (uIndex == 6)
+                return 0.0f;
+            if (uIndex == 7)
+                return 1.0f;
+            uIndex -= 1;
+            return (fred_0 * (5-uIndex) + fred_1 * uIndex) / 5.0f;
+        }
+    }
+
+    size_t GetIndex(size_t uOffset) const
+    {
+        return (size_t) ((data >> (3*uOffset + 16)) & 0x07);
+    }    
+
+    void SetIndex(size_t uOffset, size_t uIndex)
+    {
+        data &= ~((uint64_t) 0x07 << (3*uOffset + 16));
+        data |= ((uint64_t) uIndex << (3*uOffset + 16));
+    }
+
+    union
+    {
+        struct 
+        {
+            uint8_t red_0;
+            uint8_t red_1;
+            uint8_t indices[6]; 
+        };
+        uint64_t data;
+    };
+};
+
+// BC4S/BC5S
+struct BC4_SNORM
+{
+    float R(size_t uOffset) const
+    {
+        size_t uIndex = GetIndex(uOffset);
+        return DecodeFromIndex(uIndex);
+    }
+
+    float DecodeFromIndex(size_t uIndex) const
+    {
+        int8_t sred_0 = (red_0 == -128)? -127 : red_0;
+        int8_t sred_1 = (red_1 == -128)? -127 : red_1;
+
+        if (uIndex == 0)
+            return sred_0 / 127.0f;
+        if (uIndex == 1)
+            return sred_1 / 127.0f;
+        float fred_0 = sred_0 / 127.0f;
+        float fred_1 = sred_1 / 127.0f;
+        if (red_0 > red_1)
+        {
+            uIndex -= 1;
+            return (fred_0 * (7-uIndex) + fred_1 * uIndex) / 7.0f;
+        }
+        else
+        {
+            if (uIndex == 6)
+                return -1.0f;
+            if (uIndex == 7)
+                return 1.0f;  
+            uIndex -= 1;
+            return (fred_0 * (5-uIndex) + fred_1 * uIndex) / 5.0f;
+        }
+    }
+
+    size_t GetIndex(size_t uOffset) const
+    {
+        return (size_t) ((data >> (3*uOffset + 16)) & 0x07);
+    }    
+
+    void SetIndex(size_t uOffset, size_t uIndex)
+    {
+        data &= ~((uint64_t) 0x07 << (3*uOffset + 16));
+        data |= ((uint64_t) uIndex << (3*uOffset + 16));
+    }
+
+    union
+    {
+        struct 
+        {
+            int8_t red_0;
+            int8_t red_1;
+            uint8_t indices[6]; 
+        };
+        uint64_t data;
+    };
+};
+
+#pragma warning(pop)
+
+//-------------------------------------------------------------------------------------
+// Convert a floating point value to an 8-bit SNORM
+//-------------------------------------------------------------------------------------
+static void inline FloatToSNorm( _In_ float fVal, _Out_ int8_t *piSNorm )
+{
+    const uint32_t dwMostNeg = ( 1 << ( 8 * sizeof( int8_t ) - 1 ) );
+
+    if( _isnan( fVal ) )
+        fVal = 0;
+    else
+        if( fVal > 1 )
+            fVal = 1;    // Clamp to 1
+        else
+            if( fVal < -1 )
+                fVal = -1;    // Clamp to -1
+
+    fVal = fVal * (int8_t) ( dwMostNeg - 1 );
+
+    if( fVal >= 0 )
+        fVal += .5f;
+    else
+        fVal -= .5f;
+
+    *piSNorm = (int8_t) (fVal);
+}
+
+
+//------------------------------------------------------------------------------
+static void FindEndPointsBC4U( _In_reads_(BLOCK_SIZE) const float theTexelsU[], _Out_ uint8_t &endpointU_0, _Out_ uint8_t &endpointU_1)
+{
+    // The boundary of codec for signed/unsigned format
+    float MIN_NORM;
+    float MAX_NORM = 1.0f;
+    int8_t iStart, iEnd;
+    size_t i;
+
+    MIN_NORM = 0.0f;
+
+    // Find max/min of input texels
+    float fBlockMax = theTexelsU[0];
+    float fBlockMin = theTexelsU[0];
+    for (i = 0; i < BLOCK_SIZE; ++i)
+    {    
+        if (theTexelsU[i]<fBlockMin)
+        {
+            fBlockMin = theTexelsU[i];
+        }
+        else if (theTexelsU[i]>fBlockMax)
+        {
+            fBlockMax = theTexelsU[i];
+        }
+    }
+
+    //  If there are boundary values in input texels, Should use 4 block-codec to guarantee
+    //  the exact code of the boundary values.
+    bool bUsing4BlockCodec = ( MIN_NORM == fBlockMin || MAX_NORM == fBlockMax );
+
+    // Using Optimize
+    float fStart, fEnd;
+
+    if (!bUsing4BlockCodec)
+    {   
+        OptimizeAlpha<false>(&fStart, &fEnd, theTexelsU, 8);
+
+        iStart = (uint8_t) (fStart * 255.0f);
+        iEnd   = (uint8_t) (fEnd   * 255.0f);
+
+        endpointU_0 = iEnd;
+        endpointU_1 = iStart;
+    }
+    else
+    {
+        OptimizeAlpha<false>(&fStart, &fEnd, theTexelsU, 6);
+
+        iStart = (uint8_t) (fStart * 255.0f);
+        iEnd   = (uint8_t) (fEnd   * 255.0f);
+
+        endpointU_1 = iEnd;
+        endpointU_0 = iStart;
+    }
+}
+
+static void FindEndPointsBC4S(_In_reads_(BLOCK_SIZE) const float theTexelsU[], _Out_ int8_t &endpointU_0, _Out_ int8_t &endpointU_1)
+{
+    //  The boundary of codec for signed/unsigned format
+    float MIN_NORM;
+    float MAX_NORM = 1.0f;
+    int8_t iStart, iEnd;
+    size_t i;
+
+    MIN_NORM = -1.0f;
+
+    // Find max/min of input texels
+    float fBlockMax = theTexelsU[0];
+    float fBlockMin = theTexelsU[0];
+    for (i = 0; i < BLOCK_SIZE; ++i)
+    {    
+        if (theTexelsU[i]<fBlockMin)
+        {
+            fBlockMin = theTexelsU[i];
+        }
+        else if (theTexelsU[i]>fBlockMax)
+        {
+            fBlockMax = theTexelsU[i];
+        }
+    }
+
+    //  If there are boundary values in input texels, Should use 4 block-codec to guarantee
+    //  the exact code of the boundary values.
+    bool bUsing4BlockCodec = ( MIN_NORM == fBlockMin || MAX_NORM == fBlockMax );
+
+    // Using Optimize
+    float fStart, fEnd;
+
+    if (!bUsing4BlockCodec)
+    {   
+        OptimizeAlpha<true>(&fStart, &fEnd, theTexelsU, 8);
+
+        FloatToSNorm(fStart, &iStart);
+        FloatToSNorm(fEnd, &iEnd);
+
+        endpointU_0 = iEnd;
+        endpointU_1 = iStart;
+    }
+    else
+    {
+        OptimizeAlpha<true>(&fStart, &fEnd, theTexelsU, 6);
+
+        FloatToSNorm(fStart, &iStart);
+        FloatToSNorm(fEnd, &iEnd);
+
+        endpointU_1 = iEnd;
+        endpointU_0 = iStart;
+    }
+}
+
+
+//------------------------------------------------------------------------------
+static inline void FindEndPointsBC5U( _In_reads_(BLOCK_SIZE) const float theTexelsU[], _In_reads_(BLOCK_SIZE) const float theTexelsV[],
+                                      _Out_ uint8_t &endpointU_0, _Out_ uint8_t &endpointU_1, _Out_ uint8_t &endpointV_0, _Out_ uint8_t &endpointV_1)
+{
+    //Encoding the U and V channel by BC4 codec separately.
+    FindEndPointsBC4U( theTexelsU, endpointU_0, endpointU_1);
+    FindEndPointsBC4U( theTexelsV, endpointV_0, endpointV_1);
+}
+
+static inline void FindEndPointsBC5S( _In_reads_(BLOCK_SIZE) const float theTexelsU[], _In_reads_(BLOCK_SIZE) const float theTexelsV[],
+                                      _Out_ int8_t &endpointU_0, _Out_ int8_t &endpointU_1, _Out_ int8_t &endpointV_0, _Out_ int8_t &endpointV_1)
+{
+    //Encoding the U and V channel by BC4 codec separately.
+    FindEndPointsBC4S( theTexelsU, endpointU_0, endpointU_1);
+    FindEndPointsBC4S( theTexelsV, endpointV_0, endpointV_1);
+}
+
+
+//------------------------------------------------------------------------------
+static void FindClosestUNORM(_Inout_ BC4_UNORM* pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const float theTexelsU[])
+{
+    float rGradient[8];
+    int i;
+    for (i = 0; i < 8; ++i)
+    {
+        rGradient[i] = pBC->DecodeFromIndex(i);
+    }
+    for (i = 0; i < NUM_PIXELS_PER_BLOCK; ++i)
+    {
+        size_t uBestIndex = 0;
+        float fBestDelta = 100000;
+        for (size_t uIndex = 0; uIndex < 8; uIndex++)
+        {
+            float fCurrentDelta = fabsf(rGradient[uIndex]-theTexelsU[i]);
+            if (fCurrentDelta < fBestDelta)
+            {
+                uBestIndex = uIndex;
+                fBestDelta = fCurrentDelta;
+            }
+        }
+        pBC->SetIndex(i, uBestIndex);
+    }
+}
+
+static void FindClosestSNORM(_Inout_ BC4_SNORM* pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const float theTexelsU[])
+{    
+    float rGradient[8];
+    int i;
+    for (i = 0; i < 8; ++i)
+    {
+        rGradient[i] = pBC->DecodeFromIndex(i);
+    }
+    for (i = 0; i < NUM_PIXELS_PER_BLOCK; ++i)
+    {
+        size_t uBestIndex = 0;
+        float fBestDelta = 100000;
+        for (size_t uIndex = 0; uIndex < 8; uIndex++)
+        {
+            float fCurrentDelta = fabsf(rGradient[uIndex]-theTexelsU[i]);
+            if (fCurrentDelta < fBestDelta)
+            {
+                uBestIndex = uIndex;
+                fBestDelta = fCurrentDelta;
+            }
+        }
+        pBC->SetIndex(i, uBestIndex);
+    }
+}
+
+
+//=====================================================================================
+// Entry points
+//=====================================================================================
+
+//-------------------------------------------------------------------------------------
+// BC4 Compression
+//-------------------------------------------------------------------------------------
+_Use_decl_annotations_
+void D3DXDecodeBC4U( XMVECTOR *pColor, const uint8_t *pBC )
+{
+    assert( pColor && pBC );
+    static_assert( sizeof(BC4_UNORM) == 8, "BC4_UNORM should be 8 bytes" );
+
+    auto pBC4 = reinterpret_cast<const BC4_UNORM*>(pBC);
+
+    for (size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i)
+    {
+        #pragma prefast(suppress:22103, "writing blocks in two halves confuses tool")
+        pColor[i] = XMVectorSet( pBC4->R(i), 0, 0, 1.0f);
+    }       
+}
+
+_Use_decl_annotations_
+void D3DXDecodeBC4S(XMVECTOR *pColor, const uint8_t *pBC)
+{
+    assert( pColor && pBC );
+    static_assert( sizeof(BC4_SNORM) == 8, "BC4_SNORM should be 8 bytes" );
+
+    auto pBC4 = reinterpret_cast<const BC4_SNORM*>(pBC);
+
+    for (size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i)
+    {
+        #pragma prefast(suppress:22103, "writing blocks in two halves confuses tool")
+        pColor[i] = XMVectorSet( pBC4->R(i), 0, 0, 1.0f);
+    }       
+}
+
+_Use_decl_annotations_
+void D3DXEncodeBC4U( uint8_t *pBC, const XMVECTOR *pColor, DWORD flags )
+{
+    UNREFERENCED_PARAMETER( flags );
+
+    assert( pBC && pColor );
+    static_assert( sizeof(BC4_UNORM) == 8, "BC4_UNORM should be 8 bytes" );
+
+    memset(pBC, 0, sizeof(BC4_UNORM));
+    auto pBC4 = reinterpret_cast<BC4_UNORM*>(pBC);
+    float theTexelsU[NUM_PIXELS_PER_BLOCK];
+
+    for (size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i)
+    {
+        theTexelsU[i] = XMVectorGetX( pColor[i] );
+    }
+
+    FindEndPointsBC4U(theTexelsU, pBC4->red_0, pBC4->red_1);
+    FindClosestUNORM(pBC4, theTexelsU);
+}
+
+_Use_decl_annotations_
+void D3DXEncodeBC4S( uint8_t *pBC, const XMVECTOR *pColor, DWORD flags )
+{
+    UNREFERENCED_PARAMETER( flags );
+
+    assert( pBC && pColor );
+    static_assert( sizeof(BC4_SNORM) == 8, "BC4_SNORM should be 8 bytes" );
+
+    memset(pBC, 0, sizeof(BC4_UNORM));
+    auto pBC4 = reinterpret_cast<BC4_SNORM*>(pBC);
+    float theTexelsU[NUM_PIXELS_PER_BLOCK];
+
+    for (size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i)
+    {
+        theTexelsU[i] = XMVectorGetX( pColor[i] );
+    }
+
+    FindEndPointsBC4S(theTexelsU, pBC4->red_0, pBC4->red_1);
+    FindClosestSNORM(pBC4, theTexelsU);
+}
+
+
+//-------------------------------------------------------------------------------------
+// BC5 Compression
+//-------------------------------------------------------------------------------------
+_Use_decl_annotations_
+void D3DXDecodeBC5U(XMVECTOR *pColor, const uint8_t *pBC)
+{
+    assert( pColor && pBC );
+    static_assert( sizeof(BC4_UNORM) == 8, "BC4_UNORM should be 8 bytes" );
+
+    auto pBCR = reinterpret_cast<const BC4_UNORM*>(pBC);
+    auto pBCG = reinterpret_cast<const BC4_UNORM*>(pBC+sizeof(BC4_UNORM));
+
+    for (size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i)
+    {
+        #pragma prefast(suppress:22103, "writing blocks in two halves confuses tool")
+        pColor[i] = XMVectorSet(pBCR->R(i), pBCG->R(i), 0, 1.0f);
+    }       
+}
+
+_Use_decl_annotations_
+void D3DXDecodeBC5S(XMVECTOR *pColor, const uint8_t *pBC)
+{
+    assert( pColor && pBC );
+    static_assert( sizeof(BC4_SNORM) == 8, "BC4_SNORM should be 8 bytes" );
+
+    auto pBCR = reinterpret_cast<const BC4_SNORM*>(pBC);
+    auto pBCG = reinterpret_cast<const BC4_SNORM*>(pBC+sizeof(BC4_SNORM));
+
+    for (size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i)
+    {
+        #pragma prefast(suppress:22103, "writing blocks in two halves confuses tool")
+        pColor[i] = XMVectorSet(pBCR->R(i), pBCG->R(i), 0, 1.0f);
+    }       
+}
+
+_Use_decl_annotations_
+void D3DXEncodeBC5U( uint8_t *pBC, const XMVECTOR *pColor, DWORD flags )
+{
+    UNREFERENCED_PARAMETER( flags );
+
+    assert( pBC && pColor );
+    static_assert( sizeof(BC4_UNORM) == 8, "BC4_UNORM should be 8 bytes" );
+
+    memset(pBC, 0, sizeof(BC4_UNORM)*2);
+    auto pBCR = reinterpret_cast<BC4_UNORM*>(pBC);
+    auto pBCG = reinterpret_cast<BC4_UNORM*>(pBC+sizeof(BC4_UNORM));
+    float theTexelsU[NUM_PIXELS_PER_BLOCK];
+    float theTexelsV[NUM_PIXELS_PER_BLOCK];
+
+    for (size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i)
+    {   
+        XMFLOAT4A clr;
+        XMStoreFloat4A( &clr, pColor[i] );
+        theTexelsU[i] = clr.x;
+        theTexelsV[i] = clr.y;
+    }
+
+    FindEndPointsBC5U(
+        theTexelsU,
+        theTexelsV,
+        pBCR->red_0,
+        pBCR->red_1,
+        pBCG->red_0,
+        pBCG->red_1);
+
+    FindClosestUNORM(pBCR, theTexelsU);
+    FindClosestUNORM(pBCG, theTexelsV);
+}
+
+_Use_decl_annotations_
+void D3DXEncodeBC5S( uint8_t *pBC, const XMVECTOR *pColor, DWORD flags )
+{
+    UNREFERENCED_PARAMETER( flags );
+
+    assert( pBC && pColor );
+    static_assert( sizeof(BC4_SNORM) == 8, "BC4_SNORM should be 8 bytes" );
+
+    memset(pBC, 0, sizeof(BC4_UNORM)*2);
+    auto pBCR = reinterpret_cast<BC4_SNORM*>(pBC);
+    auto pBCG = reinterpret_cast<BC4_SNORM*>(pBC+sizeof(BC4_SNORM));
+    float theTexelsU[NUM_PIXELS_PER_BLOCK];
+    float theTexelsV[NUM_PIXELS_PER_BLOCK];
+
+    for (size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i)
+    {
+        XMFLOAT4A clr;
+        XMStoreFloat4A( &clr, pColor[i] );
+        theTexelsU[i] = clr.x;
+        theTexelsV[i] = clr.y;
+    }
+
+    FindEndPointsBC5S(
+        theTexelsU,
+        theTexelsV,
+        pBCR->red_0,
+        pBCR->red_1,
+        pBCG->red_0,
+        pBCG->red_1);
+
+    FindClosestSNORM(pBCR, theTexelsU);
+    FindClosestSNORM(pBCG, theTexelsV);
+}
+
+} // namespace

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 2871 - 0
Exporters/FBX/3rdParty/DirectXTex/BC6HBC7.cpp


+ 604 - 0
Exporters/FBX/3rdParty/DirectXTex/BCDirectCompute.cpp

@@ -0,0 +1,604 @@
+//-------------------------------------------------------------------------------------
+// BCDirectCompute.cpp
+//  
+// Direct3D 11 Compute Shader BC Compressor
+//
+// 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.
+//-------------------------------------------------------------------------------------
+
+#include "directxtexp.h"
+
+#include "BCDirectCompute.h"
+
+#if defined(_DEBUG) || defined(PROFILE)
+#pragma comment(lib,"dxguid.lib")
+#endif
+
+using Microsoft::WRL::ComPtr;
+
+namespace
+{
+    #include "Shaders\Compiled\BC7Encode_EncodeBlockCS.inc"
+    #include "Shaders\Compiled\BC7Encode_TryMode02CS.inc"
+    #include "Shaders\Compiled\BC7Encode_TryMode137CS.inc"
+    #include "Shaders\Compiled\BC7Encode_TryMode456CS.inc"
+    #include "Shaders\Compiled\BC6HEncode_EncodeBlockCS.inc"
+    #include "Shaders\Compiled\BC6HEncode_TryModeG10CS.inc"
+    #include "Shaders\Compiled\BC6HEncode_TryModeLE10CS.inc"
+
+    struct BufferBC6HBC7
+    {
+        UINT color[4];
+    };
+
+    struct ConstantsBC6HBC7
+    {
+        UINT    tex_width;
+        UINT    num_block_x;
+        UINT    format;
+        UINT    mode_id;
+        UINT    start_block_id;
+        UINT    num_total_blocks;
+        float   alpha_weight;
+        UINT    reserved;
+    };
+
+    static_assert( sizeof(ConstantsBC6HBC7) == sizeof(UINT)*8, "Constant buffer size mismatch" );
+
+    inline void RunComputeShader( ID3D11DeviceContext* pContext,
+                                  ID3D11ComputeShader* shader,
+                                  ID3D11ShaderResourceView** pSRVs, 
+                                  UINT srvCount,
+                                  ID3D11Buffer* pCB, 
+                                  ID3D11UnorderedAccessView* pUAV,
+                                  UINT X )
+    {
+        // Force UAV to nullptr before setting SRV since we are swapping buffers
+        ID3D11UnorderedAccessView* nullUAV = nullptr;
+        pContext->CSSetUnorderedAccessViews( 0, 1, &nullUAV, nullptr );
+
+        pContext->CSSetShader( shader, nullptr, 0 );
+        pContext->CSSetShaderResources( 0, srvCount, pSRVs );
+        pContext->CSSetUnorderedAccessViews( 0, 1, &pUAV, nullptr );
+        pContext->CSSetConstantBuffers( 0, 1, &pCB );
+        pContext->Dispatch( X, 1, 1 );
+    }
+
+    inline void ResetContext( ID3D11DeviceContext* pContext )
+    {
+        ID3D11UnorderedAccessView* nullUAV = nullptr;
+        pContext->CSSetUnorderedAccessViews( 0, 1, &nullUAV, nullptr );
+
+        ID3D11ShaderResourceView* nullSRV[3] = { nullptr, nullptr, nullptr };
+        pContext->CSSetShaderResources( 0, 3, nullSRV );
+
+        ID3D11Buffer* nullBuffer[1] = { nullptr };
+        pContext->CSSetConstantBuffers( 0, 1, nullBuffer );
+    }
+};
+
+namespace DirectX
+{
+
+GPUCompressBC::GPUCompressBC() :
+    m_bcformat(DXGI_FORMAT_UNKNOWN),
+    m_srcformat(DXGI_FORMAT_UNKNOWN),
+    m_alphaWeight(1.f),
+    m_width(0),
+    m_height(0)
+{
+}
+
+
+//-------------------------------------------------------------------------------------
+_Use_decl_annotations_
+HRESULT GPUCompressBC::Initialize( ID3D11Device* pDevice )
+{
+    if ( !pDevice )
+        return E_INVALIDARG;
+
+    // Check for DirectCompute support
+    D3D_FEATURE_LEVEL fl = pDevice->GetFeatureLevel();
+
+    if ( fl < D3D_FEATURE_LEVEL_10_0 )
+    {
+        // DirectCompute not supported on Feature Level 9.x hardware
+        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+    }
+
+    if ( fl < D3D_FEATURE_LEVEL_11_0 )
+    {
+        // DirectCompute support on Feature Level 10.x hardware is optional, and this function needs it
+        D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS hwopts;
+        HRESULT hr = pDevice->CheckFeatureSupport( D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS, &hwopts, sizeof(hwopts) );
+        if ( FAILED(hr) )
+        {
+            memset( &hwopts, 0, sizeof(hwopts) );
+        }
+
+        if ( !hwopts.ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x )
+        {
+            return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+        }
+    }
+
+    // Save a device reference and obtain immediate context
+    m_device = pDevice;
+
+    pDevice->GetImmediateContext( m_context.ReleaseAndGetAddressOf() );
+    assert( m_context );
+
+    //--- Create compute shader library: BC6H -----------------------------------------
+
+    // Modes 11-14
+    HRESULT hr = pDevice->CreateComputeShader( BC6HEncode_TryModeG10CS, sizeof(BC6HEncode_TryModeG10CS), nullptr, m_BC6H_tryModeG10CS.ReleaseAndGetAddressOf() );
+    if ( FAILED(hr) )
+        return hr;
+
+    // Modes 1-10
+    hr = pDevice->CreateComputeShader( BC6HEncode_TryModeLE10CS, sizeof(BC6HEncode_TryModeLE10CS), nullptr, m_BC6H_tryModeLE10CS.ReleaseAndGetAddressOf() );
+    if ( FAILED(hr) )
+        return hr;
+
+    // Encode
+    hr = pDevice->CreateComputeShader( BC6HEncode_EncodeBlockCS, sizeof(BC6HEncode_EncodeBlockCS), nullptr, m_BC6H_encodeBlockCS.ReleaseAndGetAddressOf() );
+    if ( FAILED(hr) )
+        return hr;
+
+    //--- Create compute shader library: BC7 ------------------------------------------
+
+    // Modes 4, 5, 6
+    hr = pDevice->CreateComputeShader( BC7Encode_TryMode456CS, sizeof(BC7Encode_TryMode456CS), nullptr, m_BC7_tryMode456CS.ReleaseAndGetAddressOf() );
+    if ( FAILED(hr) )
+        return hr;
+
+    // Modes 1, 3, 7
+    hr = pDevice->CreateComputeShader( BC7Encode_TryMode137CS, sizeof(BC7Encode_TryMode137CS), nullptr, m_BC7_tryMode137CS.ReleaseAndGetAddressOf() );
+    if ( FAILED(hr) )
+        return hr;
+
+    // Modes 0, 2
+    hr = pDevice->CreateComputeShader( BC7Encode_TryMode02CS, sizeof(BC7Encode_TryMode02CS), nullptr, m_BC7_tryMode02CS.ReleaseAndGetAddressOf() );
+    if ( FAILED(hr) )
+        return hr;
+
+    // Encode
+    hr = pDevice->CreateComputeShader( BC7Encode_EncodeBlockCS, sizeof(BC7Encode_EncodeBlockCS), nullptr, m_BC7_encodeBlockCS.ReleaseAndGetAddressOf() );
+    if ( FAILED(hr) )
+        return hr;
+
+    return S_OK;
+}
+
+
+//-------------------------------------------------------------------------------------
+_Use_decl_annotations_
+HRESULT GPUCompressBC::Prepare( size_t width, size_t height, DXGI_FORMAT format, float alphaWeight )
+{
+    if ( !width || !height || alphaWeight < 0.f )
+        return E_INVALIDARG;
+
+#ifdef _M_X64
+    if ( (width > 0xFFFFFFFF) || (height > 0xFFFFFFFF) )
+        return E_INVALIDARG;
+#endif
+
+    m_width = width;
+    m_height = height;
+
+    m_alphaWeight = alphaWeight;
+
+    size_t xblocks = std::max<size_t>( 1, (width + 3) >> 2 );
+    size_t yblocks = std::max<size_t>( 1, (height + 3) >> 2 );
+    size_t num_blocks = xblocks * yblocks;
+
+    switch( format )
+    {
+    // BC6H GPU compressor takes RGBAF32 as input
+    case DXGI_FORMAT_BC6H_TYPELESS:
+    case DXGI_FORMAT_BC6H_UF16:
+    case DXGI_FORMAT_BC6H_SF16:
+        m_srcformat = DXGI_FORMAT_R32G32B32A32_FLOAT;
+        break;
+
+    // BC7 GPU compressor takes RGBA32 as input
+    case DXGI_FORMAT_BC7_TYPELESS:
+    case DXGI_FORMAT_BC7_UNORM:
+        m_srcformat = DXGI_FORMAT_R8G8B8A8_UNORM;
+        break;
+
+    case DXGI_FORMAT_BC7_UNORM_SRGB:
+        m_srcformat = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
+        break;
+
+    default:
+        m_bcformat = m_srcformat = DXGI_FORMAT_UNKNOWN;
+        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+    }
+
+    m_bcformat = format;
+
+    auto pDevice = m_device.Get();
+    if ( !pDevice )
+        return E_POINTER;
+
+    // Create structured buffers
+    size_t bufferSize = num_blocks * sizeof( BufferBC6HBC7 );
+    {
+        D3D11_BUFFER_DESC desc;
+        memset( &desc, 0, sizeof(desc) );
+        desc.BindFlags = D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE;
+        desc.Usage = D3D11_USAGE_DEFAULT;
+        desc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;
+        desc.StructureByteStride = sizeof( BufferBC6HBC7 );
+        desc.ByteWidth = static_cast<UINT>( bufferSize );
+
+        HRESULT hr = pDevice->CreateBuffer( &desc, nullptr, m_output.ReleaseAndGetAddressOf() );
+        if ( FAILED(hr) )
+        {
+            return hr;
+        }
+
+        hr = pDevice->CreateBuffer( &desc, nullptr, m_err1.ReleaseAndGetAddressOf() );
+        if ( FAILED(hr) )
+        {
+            return hr;
+        }
+
+        hr = pDevice->CreateBuffer( &desc, nullptr, m_err2.ReleaseAndGetAddressOf() );
+        if ( FAILED(hr) )
+        {
+            return hr;
+        }
+    }
+
+    // Create staging output buffer
+    {
+        D3D11_BUFFER_DESC desc;
+        memset( &desc, 0, sizeof(desc) );
+        desc.Usage = D3D11_USAGE_STAGING;
+        desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
+        desc.ByteWidth = static_cast<UINT>( bufferSize );
+
+        HRESULT hr = pDevice->CreateBuffer( &desc, nullptr, m_outputCPU.ReleaseAndGetAddressOf() );
+        if ( FAILED(hr) )
+        {
+            return hr;
+        }
+    }
+
+    // Create constant buffer
+    {
+        D3D11_BUFFER_DESC desc;
+        memset( &desc, 0, sizeof(desc) );
+        desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
+        desc.Usage = D3D11_USAGE_DYNAMIC;
+        desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+        desc.ByteWidth = sizeof( ConstantsBC6HBC7 );
+
+        HRESULT hr = pDevice->CreateBuffer( &desc, nullptr, m_constBuffer.ReleaseAndGetAddressOf() );
+        if ( FAILED(hr) )
+        {
+            return hr;
+        }
+    }
+
+    // Create shader resource views
+    {
+        D3D11_SHADER_RESOURCE_VIEW_DESC desc;
+        memset( &desc, 0, sizeof(desc) );
+        desc.Buffer.NumElements = static_cast<UINT>( num_blocks );
+        desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
+
+        HRESULT hr = pDevice->CreateShaderResourceView( m_err1.Get(), &desc, m_err1SRV.ReleaseAndGetAddressOf() );
+        if ( FAILED(hr) )
+        {
+            return hr;
+        }
+
+        hr = pDevice->CreateShaderResourceView( m_err2.Get(), &desc, m_err2SRV.ReleaseAndGetAddressOf() );
+        if ( FAILED(hr) )
+        {
+            return hr;
+        }
+    }
+
+    // Create unordered access views
+    {
+        D3D11_UNORDERED_ACCESS_VIEW_DESC desc;
+        memset( &desc, 0, sizeof(desc) );
+        desc.Buffer.NumElements = static_cast<UINT>( num_blocks );
+        desc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
+
+        HRESULT hr = pDevice->CreateUnorderedAccessView( m_output.Get(), &desc, m_outputUAV.ReleaseAndGetAddressOf() );
+        if ( FAILED(hr) )
+        {
+            return hr;
+        }
+
+        hr = pDevice->CreateUnorderedAccessView( m_err1.Get(), &desc, m_err1UAV.ReleaseAndGetAddressOf() );
+        if ( FAILED(hr) )
+        {
+            return hr;
+        }
+
+        hr = pDevice->CreateUnorderedAccessView( m_err2.Get(), &desc, m_err2UAV.ReleaseAndGetAddressOf() );
+        if ( FAILED(hr) )
+        {
+            return hr;
+        }
+    }
+    
+    return S_OK;
+}
+
+
+//-------------------------------------------------------------------------------------
+_Use_decl_annotations_
+HRESULT GPUCompressBC::Compress( const Image& srcImage, const Image& destImage )
+{
+    if ( !srcImage.pixels || !destImage.pixels )
+        return E_INVALIDARG;
+
+    if ( srcImage.width != destImage.width
+         || srcImage.height != destImage.height
+         || srcImage.width != m_width
+         || srcImage.height != m_height
+         || srcImage.format != m_srcformat
+         || destImage.format != m_bcformat )
+    {
+        return E_UNEXPECTED;
+    }
+
+    //--- Create input texture --------------------------------------------------------
+    auto pDevice = m_device.Get();
+    if ( !pDevice )
+        return E_POINTER;
+
+    // We need to avoid the hardware doing additional colorspace conversion
+    DXGI_FORMAT inputFormat = ( m_srcformat == DXGI_FORMAT_R8G8B8A8_UNORM_SRGB ) ? DXGI_FORMAT_R8G8B8A8_UNORM : m_srcformat;
+
+    ComPtr<ID3D11Texture2D> sourceTex;
+    {
+        D3D11_TEXTURE2D_DESC desc;
+        memset( &desc, 0, sizeof(desc) );
+        desc.Width = static_cast<UINT>( srcImage.width );
+        desc.Height = static_cast<UINT>( srcImage.height ); 
+        desc.MipLevels = 1;
+        desc.ArraySize = 1;
+        desc.Format = inputFormat;
+        desc.SampleDesc.Count = 1;
+        desc.Usage = D3D11_USAGE_DEFAULT;
+        desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
+
+        D3D11_SUBRESOURCE_DATA initData;
+        initData.pSysMem = srcImage.pixels;
+        initData.SysMemPitch = static_cast<DWORD>( srcImage.rowPitch );
+        initData.SysMemSlicePitch = static_cast<DWORD>( srcImage.slicePitch );
+
+        HRESULT hr = pDevice->CreateTexture2D( &desc, &initData, sourceTex.GetAddressOf() );
+        if ( FAILED(hr) )
+        {
+            return hr;
+        }
+    }
+
+    ComPtr<ID3D11ShaderResourceView> sourceSRV;
+    {
+        D3D11_SHADER_RESOURCE_VIEW_DESC desc;
+        memset( &desc, 0, sizeof(desc) );
+        desc.Texture2D.MipLevels = 1;
+        desc.Format = inputFormat;
+        desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
+
+        HRESULT hr = pDevice->CreateShaderResourceView( sourceTex.Get(), &desc, sourceSRV.GetAddressOf() );
+        if ( FAILED(hr) )
+        {
+            return hr;
+        }
+    }
+
+    //--- Compress using DirectCompute ------------------------------------------------
+    bool isbc7 = false;
+    switch( m_bcformat )
+    {
+    case DXGI_FORMAT_BC6H_TYPELESS:
+    case DXGI_FORMAT_BC6H_UF16:
+    case DXGI_FORMAT_BC6H_SF16:
+        break;
+
+    case DXGI_FORMAT_BC7_TYPELESS:
+    case DXGI_FORMAT_BC7_UNORM:
+    case DXGI_FORMAT_BC7_UNORM_SRGB:
+        isbc7 = true;
+        break;
+
+    default:
+        return E_UNEXPECTED;
+    }
+
+    const UINT MAX_BLOCK_BATCH = 64;
+
+    auto pContext = m_context.Get();
+    if ( !pContext )
+        return E_UNEXPECTED;
+
+    size_t xblocks = std::max<size_t>( 1, (m_width + 3) >> 2 );
+    size_t yblocks = std::max<size_t>( 1, (m_height + 3) >> 2 );
+
+    UINT num_total_blocks = static_cast<UINT>( xblocks * yblocks );
+    UINT num_blocks = num_total_blocks;
+    int start_block_id = 0;
+    while (num_blocks > 0)
+    {
+        UINT n = std::min<UINT>( num_blocks, MAX_BLOCK_BATCH );
+        UINT uThreadGroupCount = n;
+
+        {
+            D3D11_MAPPED_SUBRESOURCE mapped;
+            HRESULT hr = pContext->Map( m_constBuffer.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped );
+            if ( FAILED(hr) )
+                return hr;
+
+            ConstantsBC6HBC7 param;
+            param.tex_width = static_cast<UINT>( srcImage.width );
+            param.num_block_x = static_cast<UINT>( xblocks );
+            param.format = m_bcformat;
+            param.mode_id = 0;
+            param.start_block_id = start_block_id;
+            param.num_total_blocks = num_total_blocks;
+            param.alpha_weight = m_alphaWeight;
+            memcpy( mapped.pData, &param, sizeof( param ) );
+
+            pContext->Unmap( m_constBuffer.Get(), 0 );
+        }
+
+        if ( isbc7 )
+        {
+            //--- BC7 -----------------------------------------------------------------
+            ID3D11ShaderResourceView* pSRVs[] = { sourceSRV.Get(), nullptr };
+            RunComputeShader( pContext, m_BC7_tryMode456CS.Get(), pSRVs, 2, m_constBuffer.Get(),
+                              m_err1UAV.Get(), std::max<UINT>( (uThreadGroupCount + 3) / 4, 1) );
+
+            for ( UINT i = 0; i < 3; ++i )
+            {
+                static const UINT modes[] = { 1, 3, 7 };
+                {
+                    D3D11_MAPPED_SUBRESOURCE mapped;
+                    HRESULT hr = pContext->Map( m_constBuffer.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped );
+                    if ( FAILED(hr) )
+                    {
+                        ResetContext( pContext );
+                        return hr;
+                    }
+
+                    ConstantsBC6HBC7 param;
+                    param.tex_width = static_cast<UINT>( srcImage.width );
+                    param.num_block_x = static_cast<UINT>( xblocks );
+                    param.format = m_bcformat;
+                    param.mode_id = modes[i];
+                    param.start_block_id = start_block_id;
+                    param.num_total_blocks = num_total_blocks;
+                    param.alpha_weight = m_alphaWeight;
+                    memcpy( mapped.pData, &param, sizeof( param ) );
+                    pContext->Unmap( m_constBuffer.Get(), 0 );
+                }
+
+                pSRVs[1] = (i & 1) ? m_err2SRV.Get() : m_err1SRV.Get();
+                RunComputeShader( pContext, m_BC7_tryMode137CS.Get(), pSRVs, 2, m_constBuffer.Get(),
+                                  (i & 1) ? m_err1UAV.Get() : m_err2UAV.Get(), uThreadGroupCount );
+            }               
+
+            for ( UINT i = 0; i < 2; ++i )
+            {
+                static const UINT modes[] = { 0, 2 };
+                {
+                    D3D11_MAPPED_SUBRESOURCE mapped;
+                    HRESULT hr = pContext->Map( m_constBuffer.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped );
+                    if ( FAILED(hr) )
+                    {
+                        ResetContext( pContext );
+                        return hr;
+                    }
+
+                    ConstantsBC6HBC7 param;
+                    param.tex_width = static_cast<UINT>( srcImage.width );
+                    param.num_block_x = static_cast<UINT>( xblocks );
+                    param.format = m_bcformat;
+                    param.mode_id = modes[i];
+                    param.start_block_id = start_block_id;
+                    param.num_total_blocks = num_total_blocks;
+                    param.alpha_weight = m_alphaWeight;
+                    memcpy( mapped.pData, &param, sizeof( param ) );
+                    pContext->Unmap( m_constBuffer.Get(), 0 );
+                }
+
+                pSRVs[1] = (i & 1) ? m_err1SRV.Get() : m_err2SRV.Get();
+                RunComputeShader( pContext, m_BC7_tryMode02CS.Get(), pSRVs, 2, m_constBuffer.Get(),
+                                  (i & 1) ? m_err2UAV.Get() : m_err1UAV.Get(), uThreadGroupCount );
+            }
+
+            pSRVs[1] = m_err2SRV.Get();
+            RunComputeShader( pContext, m_BC7_encodeBlockCS.Get(), pSRVs, 2, m_constBuffer.Get(),
+                              m_outputUAV.Get(), std::max<UINT>( (uThreadGroupCount + 3) / 4, 1) );
+        }
+        else
+        {
+            //--- BC6H ----------------------------------------------------------------
+            ID3D11ShaderResourceView* pSRVs[] = { sourceSRV.Get(), nullptr };
+            RunComputeShader( pContext, m_BC6H_tryModeG10CS.Get(), pSRVs, 2, m_constBuffer.Get(),
+                              m_err1UAV.Get(), std::max<UINT>( (uThreadGroupCount + 3) / 4, 1) );
+
+            for ( UINT i = 0; i < 10; ++i )
+            {
+                {
+                    D3D11_MAPPED_SUBRESOURCE mapped;
+                    HRESULT hr = pContext->Map( m_constBuffer.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped );
+                    if ( FAILED(hr) )
+                    {
+                        ResetContext( pContext );
+                        return hr;
+                    }
+
+                    ConstantsBC6HBC7 param;
+                    param.tex_width = static_cast<UINT>( srcImage.width );
+                    param.num_block_x = static_cast<UINT>( xblocks );
+                    param.format = m_bcformat;
+                    param.mode_id = i;
+                    param.start_block_id = start_block_id;
+                    param.num_total_blocks = num_total_blocks;
+                    memcpy( mapped.pData, &param, sizeof( param ) );
+                    pContext->Unmap( m_constBuffer.Get(), 0 );
+                }
+
+                pSRVs[1] = (i & 1) ? m_err2SRV.Get() : m_err1SRV.Get();
+                RunComputeShader( pContext, m_BC6H_tryModeLE10CS.Get(), pSRVs, 2, m_constBuffer.Get(),
+                                  (i & 1) ? m_err1UAV.Get() : m_err2UAV.Get(), std::max<UINT>( (uThreadGroupCount + 1) / 2, 1) );
+            }               
+
+            pSRVs[1] = m_err1SRV.Get();
+            RunComputeShader( pContext, m_BC6H_encodeBlockCS.Get(), pSRVs, 2, m_constBuffer.Get(),
+                              m_outputUAV.Get(), std::max<UINT>( (uThreadGroupCount + 1) / 2, 1) );
+        }
+
+        start_block_id += n;
+        num_blocks -= n;
+    }
+
+    ResetContext( pContext );
+
+    //--- Copy output texture back to CPU ---------------------------------------------
+
+    pContext->CopyResource( m_outputCPU.Get(), m_output.Get() );
+
+    D3D11_MAPPED_SUBRESOURCE mapped;
+    HRESULT hr = pContext->Map( m_outputCPU.Get(), 0, D3D11_MAP_READ, 0, &mapped );
+    if ( SUCCEEDED(hr) )
+    {
+        const uint8_t *pSrc = reinterpret_cast<const uint8_t *>( mapped.pData );
+        uint8_t *pDest = destImage.pixels;
+
+        size_t pitch = xblocks * sizeof( BufferBC6HBC7 );
+
+        size_t rows = std::max<size_t>( 1, ( destImage.height + 3 ) >> 2 );
+
+        for( size_t h = 0; h < rows; ++h )
+        {
+            memcpy( pDest, pSrc, destImage.rowPitch );
+
+            pSrc += pitch;
+            pDest += destImage.rowPitch;
+        }
+
+        pContext->Unmap( m_outputCPU.Get(), 0 );
+    }
+
+    return hr;
+}
+
+}; // namespace

+ 68 - 0
Exporters/FBX/3rdParty/DirectXTex/BCDirectCompute.h

@@ -0,0 +1,68 @@
+//-------------------------------------------------------------------------------------
+// BCDirectCompute.h
+//  
+// Direct3D 11 Compute Shader BC Compressor
+//
+// 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.
+//-------------------------------------------------------------------------------------
+
+#if defined(_MSC_VER) && (_MSC_VER > 1000)
+#pragma once
+#endif
+
+namespace DirectX
+{
+
+class GPUCompressBC
+{
+public:
+    GPUCompressBC();
+
+    HRESULT Initialize( _In_ ID3D11Device* pDevice );
+
+    HRESULT Prepare( _In_ size_t width, _In_ size_t height, _In_ DXGI_FORMAT format, _In_ float alphaWeight = 1.f );
+
+    HRESULT Compress( _In_ const Image& srcImage, _In_ const Image& destImage );
+
+    DXGI_FORMAT GetSourceFormat() const { return m_srcformat; }
+
+private:
+    DXGI_FORMAT                                         m_bcformat;
+    DXGI_FORMAT                                         m_srcformat;
+    float                                               m_alphaWeight;
+    size_t                                              m_width;
+    size_t                                              m_height;
+
+    Microsoft::WRL::ComPtr<ID3D11Device>                m_device;
+    Microsoft::WRL::ComPtr<ID3D11DeviceContext>         m_context;
+
+    Microsoft::WRL::ComPtr<ID3D11Buffer>                m_err1;
+    Microsoft::WRL::ComPtr<ID3D11UnorderedAccessView>   m_err1UAV;
+    Microsoft::WRL::ComPtr<ID3D11ShaderResourceView>    m_err1SRV;
+
+    Microsoft::WRL::ComPtr<ID3D11Buffer>                m_err2;
+    Microsoft::WRL::ComPtr<ID3D11UnorderedAccessView>   m_err2UAV;
+    Microsoft::WRL::ComPtr<ID3D11ShaderResourceView>    m_err2SRV;
+
+    Microsoft::WRL::ComPtr<ID3D11Buffer>                m_output;
+    Microsoft::WRL::ComPtr<ID3D11Buffer>                m_outputCPU;
+    Microsoft::WRL::ComPtr<ID3D11UnorderedAccessView>   m_outputUAV;
+    Microsoft::WRL::ComPtr<ID3D11Buffer>                m_constBuffer;
+    
+    // Compute shader library
+    Microsoft::WRL::ComPtr<ID3D11ComputeShader>         m_BC6H_tryModeG10CS;
+    Microsoft::WRL::ComPtr<ID3D11ComputeShader>         m_BC6H_tryModeLE10CS;
+    Microsoft::WRL::ComPtr<ID3D11ComputeShader>         m_BC6H_encodeBlockCS;
+
+    Microsoft::WRL::ComPtr<ID3D11ComputeShader>         m_BC7_tryMode456CS;
+    Microsoft::WRL::ComPtr<ID3D11ComputeShader>         m_BC7_tryMode137CS;
+    Microsoft::WRL::ComPtr<ID3D11ComputeShader>         m_BC7_tryMode02CS;
+    Microsoft::WRL::ComPtr<ID3D11ComputeShader>         m_BC7_encodeBlockCS;    
+};
+
+}; // namespace

+ 239 - 0
Exporters/FBX/3rdParty/DirectXTex/DDS.h

@@ -0,0 +1,239 @@
+//--------------------------------------------------------------------------------------
+// dds.h
+//
+// This header defines constants and structures that are useful when parsing 
+// DDS files.  DDS files were originally designed to use several structures
+// and constants that are native to DirectDraw and are defined in ddraw.h,
+// such as DDSURFACEDESC2 and DDSCAPS2.  This file defines similar 
+// (compatible) constants and structures so that one can use DDS files 
+// without needing to include ddraw.h.
+//
+// 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=248926
+//--------------------------------------------------------------------------------------
+
+#if defined(_MSC_VER) && (_MSC_VER > 1000)
+#pragma once
+#endif
+
+#if defined(_XBOX_ONE) && defined(_TITLE) && MONOLITHIC
+#include <d3d11_x.h>
+#else
+#include <dxgiformat.h>
+#endif
+
+// VS 2010's stdint.h conflicts with intsafe.h
+#pragma warning(push)
+#pragma warning(disable : 4005)
+#include <stdint.h>
+#pragma warning(pop)
+
+namespace DirectX
+{
+
+#pragma pack(push,1)
+
+const uint32_t DDS_MAGIC = 0x20534444; // "DDS "
+
+struct DDS_PIXELFORMAT
+{
+    uint32_t    dwSize;
+    uint32_t    dwFlags;
+    uint32_t    dwFourCC;
+    uint32_t    dwRGBBitCount;
+    uint32_t    dwRBitMask;
+    uint32_t    dwGBitMask;
+    uint32_t    dwBBitMask;
+    uint32_t    dwABitMask;
+};
+
+#define DDS_FOURCC      0x00000004  // DDPF_FOURCC
+#define DDS_RGB         0x00000040  // DDPF_RGB
+#define DDS_RGBA        0x00000041  // DDPF_RGB | DDPF_ALPHAPIXELS
+#define DDS_LUMINANCE   0x00020000  // DDPF_LUMINANCE
+#define DDS_LUMINANCEA  0x00020001  // DDPF_LUMINANCE | DDPF_ALPHAPIXELS
+#define DDS_ALPHA       0x00000002  // DDPF_ALPHA
+#define DDS_PAL8        0x00000020  // DDPF_PALETTEINDEXED8
+
+#ifndef MAKEFOURCC
+    #define MAKEFOURCC(ch0, ch1, ch2, ch3)                              \
+                ((uint32_t)(uint8_t)(ch0) | ((uint32_t)(uint8_t)(ch1) << 8) |       \
+                ((uint32_t)(uint8_t)(ch2) << 16) | ((uint32_t)(uint8_t)(ch3) << 24 ))
+#endif /* defined(MAKEFOURCC) */
+
+extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_DXT1 =
+    { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','1'), 0, 0, 0, 0, 0 };
+
+extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_DXT2 =
+    { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','2'), 0, 0, 0, 0, 0 };
+
+extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_DXT3 =
+    { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','3'), 0, 0, 0, 0, 0 };
+
+extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_DXT4 =
+    { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','4'), 0, 0, 0, 0, 0 };
+
+extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_DXT5 =
+    { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','5'), 0, 0, 0, 0, 0 };
+
+extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_BC4_UNORM =
+    { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('B','C','4','U'), 0, 0, 0, 0, 0 };
+
+extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_BC4_SNORM =
+    { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('B','C','4','S'), 0, 0, 0, 0, 0 };
+
+extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_BC5_UNORM =
+    { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('B','C','5','U'), 0, 0, 0, 0, 0 };
+
+extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_BC5_SNORM =
+    { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('B','C','5','S'), 0, 0, 0, 0, 0 };
+
+extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_R8G8_B8G8 =
+    { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('R','G','B','G'), 0, 0, 0, 0, 0 };
+
+extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_G8R8_G8B8 =
+    { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('G','R','G','B'), 0, 0, 0, 0, 0 };
+
+extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_YUY2 =
+    { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('Y','U','Y','2'), 0, 0, 0, 0, 0 };
+
+extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_A8R8G8B8 =
+    { sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 };
+
+extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_X8R8G8B8 =
+    { sizeof(DDS_PIXELFORMAT), DDS_RGB,  0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000 };
+
+extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_A8B8G8R8 =
+    { sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 };
+
+extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_X8B8G8R8 =
+    { sizeof(DDS_PIXELFORMAT), DDS_RGB,  0, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000 };
+
+extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_G16R16 =
+    { sizeof(DDS_PIXELFORMAT), DDS_RGB,  0, 32, 0x0000ffff, 0xffff0000, 0x00000000, 0x00000000 };
+
+extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_R5G6B5 =
+    { sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 16, 0x0000f800, 0x000007e0, 0x0000001f, 0x00000000 };
+
+extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_A1R5G5B5 =
+    { sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 16, 0x00007c00, 0x000003e0, 0x0000001f, 0x00008000 };
+
+extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_A4R4G4B4 =
+    { sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 16, 0x00000f00, 0x000000f0, 0x0000000f, 0x0000f000 };
+
+extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_R8G8B8 =
+    { sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000 };
+
+extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_L8 =
+    { sizeof(DDS_PIXELFORMAT), DDS_LUMINANCE, 0,  8, 0xff, 0x00, 0x00, 0x00 };
+
+extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_L16 =
+    { sizeof(DDS_PIXELFORMAT), DDS_LUMINANCE, 0, 16, 0xffff, 0x0000, 0x0000, 0x0000 };
+
+extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_A8L8 =
+    { sizeof(DDS_PIXELFORMAT), DDS_LUMINANCEA, 0, 16, 0x00ff, 0x0000, 0x0000, 0xff00 };
+
+extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_A8 =
+    { sizeof(DDS_PIXELFORMAT), DDS_ALPHA, 0, 8, 0x00, 0x00, 0x00, 0xff };
+
+// D3DFMT_A2R10G10B10/D3DFMT_A2B10G10R10 should be written using DX10 extension to avoid D3DX 10:10:10:2 reversal issue
+
+// This indicates the DDS_HEADER_DXT10 extension is present (the format is in dxgiFormat)
+extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_DX10 =
+    { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','1','0'), 0, 0, 0, 0, 0 };
+
+#define DDS_HEADER_FLAGS_TEXTURE        0x00001007  // DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT 
+#define DDS_HEADER_FLAGS_MIPMAP         0x00020000  // DDSD_MIPMAPCOUNT
+#define DDS_HEADER_FLAGS_VOLUME         0x00800000  // DDSD_DEPTH
+#define DDS_HEADER_FLAGS_PITCH          0x00000008  // DDSD_PITCH
+#define DDS_HEADER_FLAGS_LINEARSIZE     0x00080000  // DDSD_LINEARSIZE
+
+#define DDS_HEIGHT 0x00000002 // DDSD_HEIGHT
+#define DDS_WIDTH  0x00000004 // DDSD_WIDTH
+
+#define DDS_SURFACE_FLAGS_TEXTURE 0x00001000 // DDSCAPS_TEXTURE
+#define DDS_SURFACE_FLAGS_MIPMAP  0x00400008 // DDSCAPS_COMPLEX | DDSCAPS_MIPMAP
+#define DDS_SURFACE_FLAGS_CUBEMAP 0x00000008 // DDSCAPS_COMPLEX
+
+#define DDS_CUBEMAP_POSITIVEX 0x00000600 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX
+#define DDS_CUBEMAP_NEGATIVEX 0x00000a00 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEX
+#define DDS_CUBEMAP_POSITIVEY 0x00001200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEY
+#define DDS_CUBEMAP_NEGATIVEY 0x00002200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEY
+#define DDS_CUBEMAP_POSITIVEZ 0x00004200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEZ
+#define DDS_CUBEMAP_NEGATIVEZ 0x00008200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEZ
+
+#define DDS_CUBEMAP_ALLFACES ( DDS_CUBEMAP_POSITIVEX | DDS_CUBEMAP_NEGATIVEX |\
+                               DDS_CUBEMAP_POSITIVEY | DDS_CUBEMAP_NEGATIVEY |\
+                               DDS_CUBEMAP_POSITIVEZ | DDS_CUBEMAP_NEGATIVEZ )
+
+#define DDS_CUBEMAP 0x00000200 // DDSCAPS2_CUBEMAP
+
+#define DDS_FLAGS_VOLUME 0x00200000 // DDSCAPS2_VOLUME
+
+// Subset here matches D3D10_RESOURCE_DIMENSION and D3D11_RESOURCE_DIMENSION
+enum DDS_RESOURCE_DIMENSION
+{
+    DDS_DIMENSION_TEXTURE1D	= 2,
+    DDS_DIMENSION_TEXTURE2D	= 3,
+    DDS_DIMENSION_TEXTURE3D	= 4,
+};
+
+// Subset here matches D3D10_RESOURCE_MISC_FLAG and D3D11_RESOURCE_MISC_FLAG
+enum DDS_RESOURCE_MISC_FLAG
+{
+    DDS_RESOURCE_MISC_TEXTURECUBE = 0x4L,
+};
+
+enum DDS_MISC_FLAGS2
+{
+    DDS_MISC_FLAGS2_ALPHA_MODE_MASK = 0x7L,
+};
+
+enum DDS_ALPHA_MODE
+{
+    DDS_ALPHA_MODE_UNKNOWN       = 0,
+    DDS_ALPHA_MODE_STRAIGHT      = 1,
+    DDS_ALPHA_MODE_PREMULTIPLIED = 2,
+    DDS_ALPHA_MODE_OPAQUE        = 3,
+    DDS_ALPHA_MODE_CUSTOM        = 4,
+};
+
+struct DDS_HEADER
+{
+    uint32_t    dwSize;
+    uint32_t    dwFlags;
+    uint32_t    dwHeight;
+    uint32_t    dwWidth;
+    uint32_t    dwPitchOrLinearSize;
+    uint32_t    dwDepth; // only if DDS_HEADER_FLAGS_VOLUME is set in dwFlags
+    uint32_t    dwMipMapCount;
+    uint32_t    dwReserved1[11];
+    DDS_PIXELFORMAT ddspf;
+    uint32_t    dwCaps;
+    uint32_t    dwCaps2;
+    uint32_t    dwCaps3;
+    uint32_t    dwCaps4;
+    uint32_t    dwReserved2;
+};
+
+struct DDS_HEADER_DXT10
+{
+    DXGI_FORMAT dxgiFormat;
+    uint32_t    resourceDimension;
+    uint32_t    miscFlag; // see DDS_RESOURCE_MISC_FLAG
+    uint32_t    arraySize;
+    uint32_t    miscFlags2; // see DDS_MISC_FLAGS2
+};
+
+#pragma pack(pop)
+
+static_assert( sizeof(DDS_HEADER) == 124, "DDS Header size mismatch" );
+static_assert( sizeof(DDS_HEADER_DXT10) == 20, "DDS DX10 Extended Header size mismatch");
+
+}; // namespace

+ 616 - 0
Exporters/FBX/3rdParty/DirectXTex/DirectXTex.h

@@ -0,0 +1,616 @@
+//-------------------------------------------------------------------------------------
+// DirectXTex.h
+//  
+// DirectX Texture Library
+//
+// 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=248926
+//-------------------------------------------------------------------------------------
+
+#if defined(_MSC_VER) && (_MSC_VER > 1000)
+#pragma once
+#endif
+
+#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) && (_WIN32_WINNT <= _WIN32_WINNT_WIN8)
+#error WIC is not supported on Windows Phone 8.0
+#endif
+
+// VS 2010's stdint.h conflicts with intsafe.h
+#pragma warning(push)
+#pragma warning(disable : 4005)
+#include <stdint.h>
+#pragma warning(pop)
+
+#include <algorithm>
+#include <functional>
+
+#if defined(_XBOX_ONE) && defined(_TITLE) && MONOLITHIC
+#include <d3d11_x.h>
+#define DCOMMON_H_INCLUDED
+#else
+#include <d3d11_1.h>
+#endif
+
+#include <ocidl.h>
+
+#define DIRECTX_TEX_VERSION 130
+
+namespace DirectX
+{
+
+    //---------------------------------------------------------------------------------
+    // DXGI Format Utilities
+    bool IsValid( _In_ DXGI_FORMAT fmt );
+    bool IsCompressed( _In_ DXGI_FORMAT fmt );
+    bool IsPacked( _In_ DXGI_FORMAT fmt );
+    bool IsVideo( _In_ DXGI_FORMAT fmt );
+    bool IsPlanar( _In_ DXGI_FORMAT fmt );
+    bool IsPalettized( _In_ DXGI_FORMAT fmt );
+    bool IsDepthStencil(_In_ DXGI_FORMAT fmt );
+    bool IsSRGB( _In_ DXGI_FORMAT fmt );
+    bool IsTypeless( _In_ DXGI_FORMAT fmt, _In_ bool partialTypeless = true );
+
+    bool HasAlpha( _In_ DXGI_FORMAT fmt );
+
+    size_t BitsPerPixel( _In_ DXGI_FORMAT fmt );
+
+    size_t BitsPerColor( _In_ DXGI_FORMAT fmt );
+
+    enum CP_FLAGS
+    {
+        CP_FLAGS_NONE               = 0x0,      // Normal operation
+        CP_FLAGS_LEGACY_DWORD       = 0x1,      // Assume pitch is DWORD aligned instead of BYTE aligned
+        CP_FLAGS_PARAGRAPH          = 0x2,      // Assume pitch is 16-byte aligned instead of BYTE aligned
+        CP_FLAGS_24BPP              = 0x10000,  // Override with a legacy 24 bits-per-pixel format size
+        CP_FLAGS_16BPP              = 0x20000,  // Override with a legacy 16 bits-per-pixel format size
+        CP_FLAGS_8BPP               = 0x40000,  // Override with a legacy 8 bits-per-pixel format size
+    };
+
+    void ComputePitch( _In_ DXGI_FORMAT fmt, _In_ size_t width, _In_ size_t height,
+                       _Out_ size_t& rowPitch, _Out_ size_t& slicePitch, _In_ DWORD flags = CP_FLAGS_NONE );
+
+    size_t ComputeScanlines( _In_ DXGI_FORMAT fmt, _In_ size_t height );
+
+    DXGI_FORMAT MakeSRGB( _In_ DXGI_FORMAT fmt );
+    DXGI_FORMAT MakeTypeless( _In_ DXGI_FORMAT fmt );
+    DXGI_FORMAT MakeTypelessUNORM( _In_ DXGI_FORMAT fmt );
+    DXGI_FORMAT MakeTypelessFLOAT( _In_ DXGI_FORMAT fmt );
+
+    //---------------------------------------------------------------------------------
+    // Texture metadata
+    enum TEX_DIMENSION
+        // Subset here matches D3D10_RESOURCE_DIMENSION and D3D11_RESOURCE_DIMENSION
+    {
+        TEX_DIMENSION_TEXTURE1D    = 2,
+        TEX_DIMENSION_TEXTURE2D    = 3,
+        TEX_DIMENSION_TEXTURE3D    = 4,
+    };
+
+    enum TEX_MISC_FLAG
+        // Subset here matches D3D10_RESOURCE_MISC_FLAG and D3D11_RESOURCE_MISC_FLAG
+    {
+        TEX_MISC_TEXTURECUBE = 0x4L,
+    };
+
+    enum TEX_MISC_FLAG2
+    {
+        TEX_MISC2_ALPHA_MODE_MASK = 0x7L,
+    };
+
+    enum TEX_ALPHA_MODE
+        // Matches DDS_ALPHA_MODE, encoded in MISC_FLAGS2
+    {
+        TEX_ALPHA_MODE_UNKNOWN       = 0,
+        TEX_ALPHA_MODE_STRAIGHT      = 1,
+        TEX_ALPHA_MODE_PREMULTIPLIED = 2,
+        TEX_ALPHA_MODE_OPAQUE        = 3,
+        TEX_ALPHA_MODE_CUSTOM        = 4,
+    };
+
+    struct TexMetadata
+    {
+        size_t          width;
+        size_t          height;     // Should be 1 for 1D textures
+        size_t          depth;      // Should be 1 for 1D or 2D textures
+        size_t          arraySize;  // For cubemap, this is a multiple of 6
+        size_t          mipLevels;
+        uint32_t        miscFlags;
+        uint32_t        miscFlags2;
+        DXGI_FORMAT     format;
+        TEX_DIMENSION   dimension;
+
+        size_t ComputeIndex( _In_ size_t mip, _In_ size_t item, _In_ size_t slice ) const;
+            // Returns size_t(-1) to indicate an out-of-range error
+
+        bool IsCubemap() const { return (miscFlags & TEX_MISC_TEXTURECUBE) != 0; }
+            // Helper for miscFlags
+
+        bool IsPMAlpha() const { return ((miscFlags2 & TEX_MISC2_ALPHA_MODE_MASK) == TEX_ALPHA_MODE_PREMULTIPLIED) != 0; }
+        void SetAlphaMode( TEX_ALPHA_MODE mode ) { miscFlags2 = (miscFlags2 & ~TEX_MISC2_ALPHA_MODE_MASK) | static_cast<uint32_t>(mode); }
+            // Helpers for miscFlags2
+
+        bool IsVolumemap() const { return (dimension == TEX_DIMENSION_TEXTURE3D); }
+            // Helper for dimension
+    };
+
+    enum DDS_FLAGS
+    {
+        DDS_FLAGS_NONE                  = 0x0,
+
+        DDS_FLAGS_LEGACY_DWORD          = 0x1,
+            // Assume pitch is DWORD aligned instead of BYTE aligned (used by some legacy DDS files)
+
+        DDS_FLAGS_NO_LEGACY_EXPANSION   = 0x2,
+            // Do not implicitly convert legacy formats that result in larger pixel sizes (24 bpp, 3:3:2, A8L8, A4L4, P8, A8P8) 
+
+        DDS_FLAGS_NO_R10B10G10A2_FIXUP  = 0x4,
+            // Do not use work-around for long-standing D3DX DDS file format issue which reversed the 10:10:10:2 color order masks
+
+        DDS_FLAGS_FORCE_RGB             = 0x8,
+            // Convert DXGI 1.1 BGR formats to DXGI_FORMAT_R8G8B8A8_UNORM to avoid use of optional WDDM 1.1 formats
+
+        DDS_FLAGS_NO_16BPP              = 0x10,
+            // Conversions avoid use of 565, 5551, and 4444 formats and instead expand to 8888 to avoid use of optional WDDM 1.2 formats
+
+        DDS_FLAGS_EXPAND_LUMINANCE      = 0x20,
+            // When loading legacy luminance formats expand replicating the color channels rather than leaving them packed (L8, L16, A8L8)
+
+        DDS_FLAGS_FORCE_DX10_EXT        = 0x10000,
+            // Always use the 'DX10' header extension for DDS writer (i.e. don't try to write DX9 compatible DDS files)
+
+        DDS_FLAGS_FORCE_DX10_EXT_MISC2  = 0x20000,
+            // DDS_FLAGS_FORCE_DX10_EXT including miscFlags2 information (result may not be compatible with D3DX10 or D3DX11)
+    };
+
+    enum WIC_FLAGS
+    {
+        WIC_FLAGS_NONE                  = 0x0,
+
+        WIC_FLAGS_FORCE_RGB             = 0x1,
+            // Loads DXGI 1.1 BGR formats as DXGI_FORMAT_R8G8B8A8_UNORM to avoid use of optional WDDM 1.1 formats
+
+        WIC_FLAGS_NO_X2_BIAS            = 0x2,
+            // Loads DXGI 1.1 X2 10:10:10:2 format as DXGI_FORMAT_R10G10B10A2_UNORM
+
+        WIC_FLAGS_NO_16BPP              = 0x4,
+            // Loads 565, 5551, and 4444 formats as 8888 to avoid use of optional WDDM 1.2 formats
+
+        WIC_FLAGS_ALLOW_MONO            = 0x8,
+            // Loads 1-bit monochrome (black & white) as R1_UNORM rather than 8-bit grayscale
+
+        WIC_FLAGS_ALL_FRAMES            = 0x10,
+            // Loads all images in a multi-frame file, converting/resizing to match the first frame as needed, defaults to 0th frame otherwise
+
+        WIC_FLAGS_IGNORE_SRGB           = 0x20,
+            // Ignores sRGB metadata if present in the file
+
+        WIC_FLAGS_DITHER                = 0x10000,
+            // Use ordered 4x4 dithering for any required conversions
+
+        WIC_FLAGS_DITHER_DIFFUSION      = 0x20000,
+            // Use error-diffusion dithering for any required conversions
+
+        WIC_FLAGS_FILTER_POINT          = 0x100000,
+        WIC_FLAGS_FILTER_LINEAR         = 0x200000,
+        WIC_FLAGS_FILTER_CUBIC          = 0x300000,
+        WIC_FLAGS_FILTER_FANT           = 0x400000, // Combination of Linear and Box filter
+            // Filtering mode to use for any required image resizing (only needed when loading arrays of differently sized images; defaults to Fant)
+    };
+
+    HRESULT GetMetadataFromDDSMemory( _In_reads_bytes_(size) LPCVOID pSource, _In_ size_t size, _In_ DWORD flags,
+                                      _Out_ TexMetadata& metadata );
+    HRESULT GetMetadataFromDDSFile( _In_z_ LPCWSTR szFile, _In_ DWORD flags,
+                                    _Out_ TexMetadata& metadata );
+
+    HRESULT GetMetadataFromTGAMemory( _In_reads_bytes_(size) LPCVOID pSource, _In_ size_t size,
+                                      _Out_ TexMetadata& metadata );
+    HRESULT GetMetadataFromTGAFile( _In_z_ LPCWSTR szFile,
+                                    _Out_ TexMetadata& metadata );
+
+    HRESULT GetMetadataFromWICMemory( _In_reads_bytes_(size) LPCVOID pSource, _In_ size_t size, _In_ DWORD flags,
+                                      _Out_ TexMetadata& metadata );
+    HRESULT GetMetadataFromWICFile( _In_z_ LPCWSTR szFile, _In_ DWORD flags,
+                                    _Out_ TexMetadata& metadata );
+
+    //---------------------------------------------------------------------------------
+    // Bitmap image container
+    struct Image
+    {
+        size_t      width;
+        size_t      height;
+        DXGI_FORMAT format;
+        size_t      rowPitch;
+        size_t      slicePitch;
+        uint8_t*    pixels;
+    };
+
+    class ScratchImage
+    {
+    public:
+        ScratchImage()
+            : _nimages(0), _size(0), _image(nullptr), _memory(nullptr) {}
+        ScratchImage(ScratchImage&& moveFrom)
+            : _nimages(0), _size(0), _image(nullptr), _memory(nullptr) { *this = std::move(moveFrom); }
+        ~ScratchImage() { Release(); }
+
+        ScratchImage& operator= (ScratchImage&& moveFrom);
+
+        HRESULT Initialize( _In_ const TexMetadata& mdata, _In_ DWORD flags = CP_FLAGS_NONE );
+
+        HRESULT Initialize1D( _In_ DXGI_FORMAT fmt, _In_ size_t length, _In_ size_t arraySize, _In_ size_t mipLevels, _In_ DWORD flags = CP_FLAGS_NONE );
+        HRESULT Initialize2D( _In_ DXGI_FORMAT fmt, _In_ size_t width, _In_ size_t height, _In_ size_t arraySize, _In_ size_t mipLevels, _In_ DWORD flags = CP_FLAGS_NONE );
+        HRESULT Initialize3D( _In_ DXGI_FORMAT fmt, _In_ size_t width, _In_ size_t height, _In_ size_t depth, _In_ size_t mipLevels, _In_ DWORD flags = CP_FLAGS_NONE );
+        HRESULT InitializeCube( _In_ DXGI_FORMAT fmt, _In_ size_t width, _In_ size_t height, _In_ size_t nCubes, _In_ size_t mipLevels, _In_ DWORD flags = CP_FLAGS_NONE );
+
+        HRESULT InitializeFromImage( _In_ const Image& srcImage, _In_ bool allow1D = false, _In_ DWORD flags = CP_FLAGS_NONE );
+        HRESULT InitializeArrayFromImages( _In_reads_(nImages) const Image* images, _In_ size_t nImages, _In_ bool allow1D = false, _In_ DWORD flags = CP_FLAGS_NONE ); 
+        HRESULT InitializeCubeFromImages( _In_reads_(nImages) const Image* images, _In_ size_t nImages, _In_ DWORD flags = CP_FLAGS_NONE );
+        HRESULT Initialize3DFromImages( _In_reads_(depth) const Image* images, _In_ size_t depth, _In_ DWORD flags = CP_FLAGS_NONE );
+
+        void Release();
+
+        bool OverrideFormat( _In_ DXGI_FORMAT f );
+
+        const TexMetadata& GetMetadata() const { return _metadata; }
+        const Image* GetImage(_In_ size_t mip, _In_ size_t item, _In_ size_t slice) const;
+
+        const Image* GetImages() const { return _image; }
+        size_t GetImageCount() const { return _nimages; }
+
+        uint8_t* GetPixels() const { return _memory; }
+        size_t GetPixelsSize() const { return _size; }
+
+        bool IsAlphaAllOpaque() const;
+
+    private:
+        size_t      _nimages;
+        size_t      _size;
+        TexMetadata _metadata;
+        Image*      _image;
+        uint8_t*    _memory;
+
+        // Hide copy constructor and assignment operator
+        ScratchImage( const ScratchImage& );
+        ScratchImage& operator=( const ScratchImage& );
+    };
+
+    //---------------------------------------------------------------------------------
+    // Memory blob (allocated buffer pointer is always 16-byte aligned)
+    class Blob
+    {
+    public:
+        Blob() : _buffer(nullptr), _size(0) {}
+        Blob(Blob&& moveFrom) : _buffer(nullptr), _size(0) { *this = std::move(moveFrom); }
+        ~Blob() { Release(); }
+
+        Blob& operator= (Blob&& moveFrom);
+
+        HRESULT Initialize( _In_ size_t size );
+
+        void Release();
+
+        void *GetBufferPointer() const { return _buffer; }
+        size_t GetBufferSize() const { return _size; }
+
+    private:
+        void*   _buffer;
+        size_t  _size;
+
+        // Hide copy constructor and assignment operator
+        Blob( const Blob& );
+        Blob& operator=( const Blob& );
+    };
+
+    //---------------------------------------------------------------------------------
+    // Image I/O
+
+    // DDS operations
+    HRESULT LoadFromDDSMemory( _In_reads_bytes_(size) LPCVOID pSource, _In_ size_t size, _In_ DWORD flags,
+                               _Out_opt_ TexMetadata* metadata, _Out_ ScratchImage& image );
+    HRESULT LoadFromDDSFile( _In_z_ LPCWSTR szFile, _In_ DWORD flags,
+                             _Out_opt_ TexMetadata* metadata, _Out_ ScratchImage& image );
+
+    HRESULT SaveToDDSMemory( _In_ const Image& image, _In_ DWORD flags,
+                             _Out_ Blob& blob );
+    HRESULT SaveToDDSMemory( _In_reads_(nimages) const Image* images, _In_ size_t nimages, _In_ const TexMetadata& metadata, _In_ DWORD flags,
+                             _Out_ Blob& blob );
+
+    HRESULT SaveToDDSFile( _In_ const Image& image, _In_ DWORD flags, _In_z_ LPCWSTR szFile );
+    HRESULT SaveToDDSFile( _In_reads_(nimages) const Image* images, _In_ size_t nimages, _In_ const TexMetadata& metadata, _In_ DWORD flags, _In_z_ LPCWSTR szFile );
+
+    // TGA operations
+    HRESULT LoadFromTGAMemory( _In_reads_bytes_(size) LPCVOID pSource, _In_ size_t size,
+                               _Out_opt_ TexMetadata* metadata, _Out_ ScratchImage& image );
+    HRESULT LoadFromTGAFile( _In_z_ LPCWSTR szFile,
+                             _Out_opt_ TexMetadata* metadata, _Out_ ScratchImage& image );
+
+    HRESULT SaveToTGAMemory( _In_ const Image& image, _Out_ Blob& blob );
+    HRESULT SaveToTGAFile( _In_ const Image& image, _In_z_ LPCWSTR szFile );
+
+    // WIC operations
+    HRESULT LoadFromWICMemory( _In_reads_bytes_(size) LPCVOID pSource, _In_ size_t size, _In_ DWORD flags,
+                               _Out_opt_ TexMetadata* metadata, _Out_ ScratchImage& image );
+    HRESULT LoadFromWICFile( _In_z_ LPCWSTR szFile, _In_ DWORD flags,
+                             _Out_opt_ TexMetadata* metadata, _Out_ ScratchImage& image );
+
+    HRESULT SaveToWICMemory( _In_ const Image& image, _In_ DWORD flags, _In_ REFGUID guidContainerFormat,
+                             _Out_ Blob& blob, _In_opt_ const GUID* targetFormat = nullptr, _In_opt_ std::function<void(IPropertyBag2*)> setCustomProps = nullptr );
+    HRESULT SaveToWICMemory( _In_count_(nimages) const Image* images, _In_ size_t nimages, _In_ DWORD flags, _In_ REFGUID guidContainerFormat,
+                             _Out_ Blob& blob, _In_opt_ const GUID* targetFormat = nullptr, _In_opt_ std::function<void(IPropertyBag2*)> setCustomProps = nullptr );
+
+    HRESULT SaveToWICFile( _In_ const Image& image, _In_ DWORD flags, _In_ REFGUID guidContainerFormat,
+                           _In_z_ LPCWSTR szFile, _In_opt_ const GUID* targetFormat = nullptr, _In_opt_ std::function<void(IPropertyBag2*)> setCustomProps = nullptr );
+    HRESULT SaveToWICFile( _In_count_(nimages) const Image* images, _In_ size_t nimages, _In_ DWORD flags, _In_ REFGUID guidContainerFormat,
+                           _In_z_ LPCWSTR szFile, _In_opt_ const GUID* targetFormat = nullptr, _In_opt_ std::function<void(IPropertyBag2*)> setCustomProps = nullptr );
+
+    enum WICCodecs
+    {
+        WIC_CODEC_BMP       =1,     // Windows Bitmap (.bmp)
+        WIC_CODEC_JPEG,             // Joint Photographic Experts Group (.jpg, .jpeg)
+        WIC_CODEC_PNG,              // Portable Network Graphics (.png)
+        WIC_CODEC_TIFF,             // Tagged Image File Format  (.tif, .tiff)
+        WIC_CODEC_GIF,              // Graphics Interchange Format  (.gif)
+        WIC_CODEC_WMP,              // Windows Media Photo / HD Photo / JPEG XR (.hdp, .jxr, .wdp)
+        WIC_CODEC_ICO,              // Windows Icon (.ico)
+    };
+
+    REFGUID GetWICCodec( _In_ WICCodecs codec );
+
+    //---------------------------------------------------------------------------------
+    // Texture conversion, resizing, mipmap generation, and block compression
+
+    enum TEX_FR_FLAGS
+    {
+        TEX_FR_ROTATE0          = 0x0,
+        TEX_FR_ROTATE90         = 0x1,
+        TEX_FR_ROTATE180        = 0x2,
+        TEX_FR_ROTATE270        = 0x3,
+        TEX_FR_FLIP_HORIZONTAL  = 0x08,
+        TEX_FR_FLIP_VERTICAL    = 0x10,
+    };
+
+    HRESULT FlipRotate( _In_ const Image& srcImage, _In_ DWORD flags, _Out_ ScratchImage& image );
+    HRESULT FlipRotate( _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata,
+                        _In_ DWORD flags, _Out_ ScratchImage& result );
+        // Flip and/or rotate image
+
+    enum TEX_FILTER_FLAGS
+    {
+        TEX_FILTER_DEFAULT          = 0,
+
+        TEX_FILTER_WRAP_U           = 0x1,
+        TEX_FILTER_WRAP_V           = 0x2,
+        TEX_FILTER_WRAP_W           = 0x4,
+        TEX_FILTER_WRAP             = ( TEX_FILTER_WRAP_U | TEX_FILTER_WRAP_V | TEX_FILTER_WRAP_W ),
+        TEX_FILTER_MIRROR_U         = 0x10,
+        TEX_FILTER_MIRROR_V         = 0x20,
+        TEX_FILTER_MIRROR_W         = 0x40,
+        TEX_FILTER_MIRROR          = ( TEX_FILTER_MIRROR_U | TEX_FILTER_MIRROR_V | TEX_FILTER_MIRROR_W ),
+            // Wrap vs. Mirror vs. Clamp filtering options
+
+        TEX_FILTER_SEPARATE_ALPHA   = 0x100,
+            // Resize color and alpha channel independently
+
+        TEX_FILTER_RGB_COPY_RED     = 0x1000,
+        TEX_FILTER_RGB_COPY_GREEN   = 0x2000,
+        TEX_FILTER_RGB_COPY_BLUE    = 0x4000,
+            // When converting RGB to R, defaults to using grayscale. These flags indicate copying a specific channel instead
+            // When converting RGB to RG, defaults to copying RED | GREEN. These flags control which channels are selected instead.
+
+        TEX_FILTER_DITHER           = 0x10000,
+            // Use ordered 4x4 dithering for any required conversions
+        TEX_FILTER_DITHER_DIFFUSION = 0x20000,
+            // Use error-diffusion dithering for any required conversions
+
+        TEX_FILTER_POINT            = 0x100000,
+        TEX_FILTER_LINEAR           = 0x200000,
+        TEX_FILTER_CUBIC            = 0x300000,
+        TEX_FILTER_BOX              = 0x400000,
+        TEX_FILTER_FANT             = 0x400000, // Equiv to Box filtering for mipmap generation
+        TEX_FILTER_TRIANGLE         = 0x500000,
+            // Filtering mode to use for any required image resizing
+
+        TEX_FILTER_SRGB_IN          = 0x1000000,
+        TEX_FILTER_SRGB_OUT         = 0x2000000,
+        TEX_FILTER_SRGB             = ( TEX_FILTER_SRGB_IN | TEX_FILTER_SRGB_OUT ),
+            // sRGB <-> RGB for use in conversion operations
+            // if the input format type is IsSRGB(), then SRGB_IN is on by default
+            // if the output format type is IsSRGB(), then SRGB_OUT is on by default
+
+        TEX_FILTER_FORCE_NON_WIC    = 0x10000000,
+            // Forces use of the non-WIC path when both are an option
+
+        TEX_FILTER_FORCE_WIC        = 0x20000000,
+            // Forces use of the WIC path even when logic would have picked a non-WIC path when both are an option
+    };
+
+    HRESULT Resize( _In_ const Image& srcImage, _In_ size_t width, _In_ size_t height, _In_ DWORD filter,
+                    _Out_ ScratchImage& image );
+    HRESULT Resize( _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata,
+                    _In_ size_t width, _In_ size_t height, _In_ DWORD filter, _Out_ ScratchImage& result );
+        // Resize the image to width x height. Defaults to Fant filtering.
+        // Note for a complex resize, the result will always have mipLevels == 1
+
+    HRESULT Convert( _In_ const Image& srcImage, _In_ DXGI_FORMAT format, _In_ DWORD filter, _In_ float threshold,
+                     _Out_ ScratchImage& image );
+    HRESULT Convert( _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata,
+                     _In_ DXGI_FORMAT format, _In_ DWORD filter, _In_ float threshold, _Out_ ScratchImage& result );
+        // Convert the image to a new format
+    
+    HRESULT ConvertToSinglePlane( _In_ const Image& srcImage, _Out_ ScratchImage& image );
+    HRESULT ConvertToSinglePlane( _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata,
+                                  _Out_ ScratchImage& image );
+        // Converts the image from a planar format to an equivalent non-planar format
+
+    HRESULT GenerateMipMaps( _In_ const Image& baseImage, _In_ DWORD filter, _In_ size_t levels,
+                             _Inout_ ScratchImage& mipChain, _In_ bool allow1D = false );
+    HRESULT GenerateMipMaps( _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata,
+                             _In_ DWORD filter, _In_ size_t levels, _Inout_ ScratchImage& mipChain );
+        // levels of '0' indicates a full mipchain, otherwise is generates that number of total levels (including the source base image)
+        // Defaults to Fant filtering which is equivalent to a box filter
+
+    HRESULT GenerateMipMaps3D( _In_reads_(depth) const Image* baseImages, _In_ size_t depth, _In_ DWORD filter, _In_ size_t levels,
+                               _Out_ ScratchImage& mipChain );
+    HRESULT GenerateMipMaps3D( _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata,
+                               _In_ DWORD filter, _In_ size_t levels, _Out_ ScratchImage& mipChain );
+        // levels of '0' indicates a full mipchain, otherwise is generates that number of total levels (including the source base image)
+        // Defaults to Fant filtering which is equivalent to a box filter
+
+    enum TEX_PMALPHA_FLAGS
+    {
+        TEX_PMALPHA_DEFAULT         = 0,
+
+        TEX_PMALPHA_IGNORE_SRGB     = 0x1,
+            // ignores sRGB colorspace conversions
+
+        TEX_PMALPHA_SRGB_IN         = 0x1000000,
+        TEX_PMALPHA_SRGB_OUT        = 0x2000000,
+        TEX_PMALPHA_SRGB            = ( TEX_PMALPHA_SRGB_IN | TEX_PMALPHA_SRGB_OUT ),
+            // if the input format type is IsSRGB(), then SRGB_IN is on by default
+            // if the output format type is IsSRGB(), then SRGB_OUT is on by default
+    };
+
+    HRESULT PremultiplyAlpha( _In_ const Image& srcImage, _In_ DWORD flags, _Out_ ScratchImage& image );
+    HRESULT PremultiplyAlpha( _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata, _In_ DWORD flags, _Out_ ScratchImage& result );
+        // Converts to a premultiplied alpha version of the texture
+
+    enum TEX_COMPRESS_FLAGS
+    {
+        TEX_COMPRESS_DEFAULT        = 0,
+
+        TEX_COMPRESS_RGB_DITHER     = 0x10000,
+            // Enables dithering RGB colors for BC1-3 compression
+
+        TEX_COMPRESS_A_DITHER       = 0x20000,
+            // Enables dithering alpha for BC1-3 compression
+
+        TEX_COMPRESS_DITHER         = 0x30000,
+            // Enables both RGB and alpha dithering for BC1-3 compression
+
+        TEX_COMPRESS_UNIFORM        = 0x40000,
+            // Uniform color weighting for BC1-3 compression; by default uses perceptual weighting
+
+        TEX_COMPRESS_SRGB_IN        = 0x1000000,
+        TEX_COMPRESS_SRGB_OUT       = 0x2000000,
+        TEX_COMPRESS_SRGB           = ( TEX_COMPRESS_SRGB_IN | TEX_COMPRESS_SRGB_OUT ),
+            // if the input format type is IsSRGB(), then SRGB_IN is on by default
+            // if the output format type is IsSRGB(), then SRGB_OUT is on by default
+
+        TEX_COMPRESS_PARALLEL       = 0x10000000,
+            // Compress is free to use multithreading to improve performance (by default it does not use multithreading)
+    };
+
+    HRESULT Compress( _In_ const Image& srcImage, _In_ DXGI_FORMAT format, _In_ DWORD compress, _In_ float alphaRef,
+                      _Out_ ScratchImage& cImage );
+    HRESULT Compress( _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata,
+                      _In_ DXGI_FORMAT format, _In_ DWORD compress, _In_ float alphaRef, _Out_ ScratchImage& cImages );
+        // Note that alphaRef is only used by BC1. 0.5f is a typical value to use
+
+    HRESULT Compress( _In_ ID3D11Device* pDevice, _In_ const Image& srcImage, _In_ DXGI_FORMAT format, _In_ DWORD compress,
+                      _In_ float alphaWeight, _Out_ ScratchImage& image );
+    HRESULT Compress( _In_ ID3D11Device* pDevice, _In_ const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata,
+                      _In_ DXGI_FORMAT format, _In_ DWORD compress, _In_ float alphaWeight, _Out_ ScratchImage& cImages );
+        // DirectCompute-based compression (alphaWeight is only used by BC7. 1.0 is the typical value to use)
+
+    HRESULT Decompress( _In_ const Image& cImage, _In_ DXGI_FORMAT format, _Out_ ScratchImage& image );
+    HRESULT Decompress( _In_reads_(nimages) const Image* cImages, _In_ size_t nimages, _In_ const TexMetadata& metadata,
+                        _In_ DXGI_FORMAT format, _Out_ ScratchImage& images );
+
+    //---------------------------------------------------------------------------------
+    // Normal map operations
+
+    enum CNMAP_FLAGS
+    {
+        CNMAP_DEFAULT           = 0,
+
+        CNMAP_CHANNEL_RED       = 0x1,
+        CNMAP_CHANNEL_GREEN     = 0x2,
+        CNMAP_CHANNEL_BLUE      = 0x3,
+        CNMAP_CHANNEL_ALPHA     = 0x4,
+        CNMAP_CHANNEL_LUMINANCE = 0x5,
+            // Channel selection when evaluting color value for height
+            // Luminance is a combination of red, green, and blue
+
+        CNMAP_MIRROR_U          = 0x1000,
+        CNMAP_MIRROR_V          = 0x2000,
+        CNMAP_MIRROR            = 0x3000,
+            // Use mirror semantics for scanline references (defaults to wrap)
+
+        CNMAP_INVERT_SIGN       = 0x4000,
+            // Inverts normal sign
+
+        CNMAP_COMPUTE_OCCLUSION = 0x8000,
+            // Computes a crude occlusion term stored in the alpha channel
+    };
+
+    HRESULT ComputeNormalMap( _In_ const Image& srcImage, _In_ DWORD flags, _In_ float amplitude,
+                              _In_ DXGI_FORMAT format, _Out_ ScratchImage& normalMap );
+    HRESULT ComputeNormalMap( _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata,
+                              _In_ DWORD flags, _In_ float amplitude, _In_ DXGI_FORMAT format, _Out_ ScratchImage& normalMaps );
+
+    //---------------------------------------------------------------------------------
+    // Misc image operations
+    struct Rect
+    {
+        size_t x;
+        size_t y;
+        size_t w;
+        size_t h;
+
+        Rect() {}
+        Rect( size_t _x, size_t _y, size_t _w, size_t _h ) : x(_x), y(_y), w(_w), h(_h) {}
+    };
+
+    HRESULT CopyRectangle( _In_ const Image& srcImage, _In_ const Rect& srcRect, _In_ const Image& dstImage,
+                           _In_ DWORD filter, _In_ size_t xOffset, _In_ size_t yOffset );
+
+    enum CMSE_FLAGS
+    {
+        CMSE_DEFAULT                = 0,
+
+        CMSE_IMAGE1_SRGB            = 0x1,
+        CMSE_IMAGE2_SRGB            = 0x2,
+            // Indicates that image needs gamma correction before comparision
+
+        CMSE_IGNORE_RED             = 0x10,
+        CMSE_IGNORE_GREEN           = 0x20,
+        CMSE_IGNORE_BLUE            = 0x40,
+        CMSE_IGNORE_ALPHA           = 0x80,
+            // Ignore the channel when computing MSE
+
+        CMSE_IMAGE1_X2_BIAS         = 0x100,
+        CMSE_IMAGE2_X2_BIAS         = 0x200,
+            // Indicates that image should be scaled and biased before comparison (i.e. UNORM -> SNORM)
+    };
+
+    HRESULT ComputeMSE( _In_ const Image& image1, _In_ const Image& image2, _Out_ float& mse, _Out_writes_opt_(4) float* mseV, _In_ DWORD flags = 0 );
+
+    //---------------------------------------------------------------------------------
+    // Direct3D 11 functions
+    bool IsSupportedTexture( _In_ ID3D11Device* pDevice, _In_ const TexMetadata& metadata );
+
+    HRESULT CreateTexture( _In_ ID3D11Device* pDevice, _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata,
+                           _Outptr_ ID3D11Resource** ppResource );
+
+    HRESULT CreateShaderResourceView( _In_ ID3D11Device* pDevice, _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata,
+                                      _Outptr_ ID3D11ShaderResourceView** ppSRV );
+
+    HRESULT CreateTextureEx( _In_ ID3D11Device* pDevice, _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata,
+                             _In_ D3D11_USAGE usage, _In_ unsigned int bindFlags, _In_ unsigned int cpuAccessFlags, _In_ unsigned int miscFlags, _In_ bool forceSRGB,
+                             _Outptr_ ID3D11Resource** ppResource );
+
+    HRESULT CreateShaderResourceViewEx( _In_ ID3D11Device* pDevice, _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata,
+                                        _In_ D3D11_USAGE usage, _In_ unsigned int bindFlags, _In_ unsigned int cpuAccessFlags, _In_ unsigned int miscFlags, _In_ bool forceSRGB,
+                                        _Outptr_ ID3D11ShaderResourceView** ppSRV );
+
+    HRESULT CaptureTexture( _In_ ID3D11Device* pDevice, _In_ ID3D11DeviceContext* pContext, _In_ ID3D11Resource* pSource, _Out_ ScratchImage& result );
+
+#include "DirectXTex.inl"
+
+}; // namespace

+ 352 - 0
Exporters/FBX/3rdParty/DirectXTex/DirectXTex.inl

@@ -0,0 +1,352 @@
+//-------------------------------------------------------------------------------------
+// DirectXTex.inl
+//  
+// DirectX Texture Library
+//
+// 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=248926
+//-------------------------------------------------------------------------------------
+
+#if defined(_MSC_VER) && (_MSC_VER > 1000)
+#pragma once
+#endif
+
+//=====================================================================================
+// DXGI Format Utilities
+//=====================================================================================
+
+_Use_decl_annotations_
+inline bool IsValid( DXGI_FORMAT fmt )
+{
+    return ( static_cast<size_t>(fmt) >= 1 && static_cast<size_t>(fmt) <= 120 );
+}
+
+_Use_decl_annotations_
+inline bool IsCompressed( DXGI_FORMAT fmt )
+{
+    switch ( fmt )
+    {
+    case DXGI_FORMAT_BC1_TYPELESS:
+    case DXGI_FORMAT_BC1_UNORM:
+    case DXGI_FORMAT_BC1_UNORM_SRGB:
+    case DXGI_FORMAT_BC2_TYPELESS:
+    case DXGI_FORMAT_BC2_UNORM:
+    case DXGI_FORMAT_BC2_UNORM_SRGB:
+    case DXGI_FORMAT_BC3_TYPELESS:
+    case DXGI_FORMAT_BC3_UNORM:
+    case DXGI_FORMAT_BC3_UNORM_SRGB:
+    case DXGI_FORMAT_BC4_TYPELESS:
+    case DXGI_FORMAT_BC4_UNORM:
+    case DXGI_FORMAT_BC4_SNORM:
+    case DXGI_FORMAT_BC5_TYPELESS:
+    case DXGI_FORMAT_BC5_UNORM:
+    case DXGI_FORMAT_BC5_SNORM:
+    case DXGI_FORMAT_BC6H_TYPELESS:
+    case DXGI_FORMAT_BC6H_UF16:
+    case DXGI_FORMAT_BC6H_SF16:
+    case DXGI_FORMAT_BC7_TYPELESS:
+    case DXGI_FORMAT_BC7_UNORM:
+    case DXGI_FORMAT_BC7_UNORM_SRGB:
+        return true;
+
+    default:
+        return false;
+    }
+}
+
+_Use_decl_annotations_
+inline bool IsPacked( DXGI_FORMAT fmt )
+{
+    switch( fmt )
+    {
+    case DXGI_FORMAT_R8G8_B8G8_UNORM:
+    case DXGI_FORMAT_G8R8_G8B8_UNORM:
+    case DXGI_FORMAT_YUY2: // 4:2:2 8-bit
+    case DXGI_FORMAT_Y210: // 4:2:2 10-bit
+    case DXGI_FORMAT_Y216: // 4:2:2 16-bit
+        return true;
+
+    default:
+        return false;
+    }
+}
+
+_Use_decl_annotations_
+inline bool IsPlanar( DXGI_FORMAT fmt )
+{
+    switch ( static_cast<int>(fmt) )
+    {
+    case DXGI_FORMAT_NV12:      // 4:2:0 8-bit
+    case DXGI_FORMAT_P010:      // 4:2:0 10-bit
+    case DXGI_FORMAT_P016:      // 4:2:0 16-bit
+    case DXGI_FORMAT_420_OPAQUE:// 4:2:0 8-bit
+    case DXGI_FORMAT_NV11:      // 4:1:1 8-bit
+        return true;
+
+    case 118 /* DXGI_FORMAT_D16_UNORM_S8_UINT */:
+    case 119 /* DXGI_FORMAT_R16_UNORM_X8_TYPELESS */:
+    case 120 /* DXGI_FORMAT_X16_TYPELESS_G8_UINT */:
+        // These are Xbox One platform specific types
+        return true;
+
+    default:
+        return false;
+    }
+}
+
+_Use_decl_annotations_
+inline bool IsPalettized( DXGI_FORMAT fmt )
+{
+    switch( fmt )
+    {
+    case DXGI_FORMAT_AI44:
+    case DXGI_FORMAT_IA44:
+    case DXGI_FORMAT_P8:
+    case DXGI_FORMAT_A8P8:
+        return true;
+
+    default:
+        return false;
+    }
+}
+
+_Use_decl_annotations_
+inline bool IsVideo( DXGI_FORMAT fmt )
+{
+    switch ( fmt )
+    {
+    case DXGI_FORMAT_AYUV:
+    case DXGI_FORMAT_Y410:
+    case DXGI_FORMAT_Y416:
+    case DXGI_FORMAT_NV12:
+    case DXGI_FORMAT_P010:
+    case DXGI_FORMAT_P016:
+    case DXGI_FORMAT_YUY2:
+    case DXGI_FORMAT_Y210:
+    case DXGI_FORMAT_Y216:
+    case DXGI_FORMAT_NV11:
+        // These video formats can be used with the 3D pipeline through special view mappings
+
+    case DXGI_FORMAT_420_OPAQUE:
+    case DXGI_FORMAT_AI44:
+    case DXGI_FORMAT_IA44:
+    case DXGI_FORMAT_P8:
+    case DXGI_FORMAT_A8P8:
+        // These are limited use video formats not usable in any way by the 3D pipeline
+        return true;
+
+    default:
+        return false;
+    }
+}
+
+_Use_decl_annotations_
+inline bool IsDepthStencil( DXGI_FORMAT fmt )
+{
+    switch( static_cast<int>(fmt) )
+    {
+    case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
+    case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
+    case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
+    case DXGI_FORMAT_D32_FLOAT:
+    case DXGI_FORMAT_D24_UNORM_S8_UINT:
+    case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
+    case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
+    case DXGI_FORMAT_D16_UNORM:
+    case 118 /* DXGI_FORMAT_D16_UNORM_S8_UINT */:
+    case 119 /* DXGI_FORMAT_R16_UNORM_X8_TYPELESS */:
+    case 120 /* DXGI_FORMAT_X16_TYPELESS_G8_UINT */:
+        return true;
+
+    default:
+        return false;
+    }
+}
+
+_Use_decl_annotations_
+inline bool IsSRGB( DXGI_FORMAT fmt )
+{
+    switch( fmt )
+    {
+    case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
+    case DXGI_FORMAT_BC1_UNORM_SRGB:
+    case DXGI_FORMAT_BC2_UNORM_SRGB:
+    case DXGI_FORMAT_BC3_UNORM_SRGB:
+    case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
+    case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
+    case DXGI_FORMAT_BC7_UNORM_SRGB:
+        return true;
+
+    default:
+        return false;
+    }
+}
+
+_Use_decl_annotations_
+inline bool IsTypeless( DXGI_FORMAT fmt, bool partialTypeless )
+{
+    switch( static_cast<int>(fmt) )
+    {
+    case DXGI_FORMAT_R32G32B32A32_TYPELESS:
+    case DXGI_FORMAT_R32G32B32_TYPELESS:
+    case DXGI_FORMAT_R16G16B16A16_TYPELESS:
+    case DXGI_FORMAT_R32G32_TYPELESS:
+    case DXGI_FORMAT_R32G8X24_TYPELESS:
+    case DXGI_FORMAT_R10G10B10A2_TYPELESS:
+    case DXGI_FORMAT_R8G8B8A8_TYPELESS:
+    case DXGI_FORMAT_R16G16_TYPELESS:
+    case DXGI_FORMAT_R32_TYPELESS:
+    case DXGI_FORMAT_R24G8_TYPELESS:
+    case DXGI_FORMAT_R8G8_TYPELESS:
+    case DXGI_FORMAT_R16_TYPELESS:
+    case DXGI_FORMAT_R8_TYPELESS:
+    case DXGI_FORMAT_BC1_TYPELESS:
+    case DXGI_FORMAT_BC2_TYPELESS:
+    case DXGI_FORMAT_BC3_TYPELESS:
+    case DXGI_FORMAT_BC4_TYPELESS:
+    case DXGI_FORMAT_BC5_TYPELESS:
+    case DXGI_FORMAT_B8G8R8A8_TYPELESS:
+    case DXGI_FORMAT_B8G8R8X8_TYPELESS:
+    case DXGI_FORMAT_BC6H_TYPELESS:
+    case DXGI_FORMAT_BC7_TYPELESS:
+        return true;
+
+    case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
+    case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
+    case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
+    case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
+        return partialTypeless;
+
+    case 119 /* DXGI_FORMAT_R16_UNORM_X8_TYPELESS */:
+    case 120 /* DXGI_FORMAT_X16_TYPELESS_G8_UINT */:
+        // These are Xbox One platform specific types
+        return partialTypeless;
+
+    default:
+        return false;
+    }
+}
+
+_Use_decl_annotations_
+inline bool HasAlpha( DXGI_FORMAT fmt )
+{
+    switch( static_cast<int>(fmt) )
+    {
+    case DXGI_FORMAT_R32G32B32A32_TYPELESS:
+    case DXGI_FORMAT_R32G32B32A32_FLOAT:
+    case DXGI_FORMAT_R32G32B32A32_UINT:
+    case DXGI_FORMAT_R32G32B32A32_SINT:
+    case DXGI_FORMAT_R16G16B16A16_TYPELESS:
+    case DXGI_FORMAT_R16G16B16A16_FLOAT:
+    case DXGI_FORMAT_R16G16B16A16_UNORM:
+    case DXGI_FORMAT_R16G16B16A16_UINT:
+    case DXGI_FORMAT_R16G16B16A16_SNORM:
+    case DXGI_FORMAT_R16G16B16A16_SINT:
+    case DXGI_FORMAT_R10G10B10A2_TYPELESS:
+    case DXGI_FORMAT_R10G10B10A2_UNORM:
+    case DXGI_FORMAT_R10G10B10A2_UINT:
+    case DXGI_FORMAT_R8G8B8A8_TYPELESS:
+    case DXGI_FORMAT_R8G8B8A8_UNORM:
+    case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
+    case DXGI_FORMAT_R8G8B8A8_UINT:
+    case DXGI_FORMAT_R8G8B8A8_SNORM:
+    case DXGI_FORMAT_R8G8B8A8_SINT:
+    case DXGI_FORMAT_A8_UNORM:
+    case DXGI_FORMAT_BC1_TYPELESS:
+    case DXGI_FORMAT_BC1_UNORM:
+    case DXGI_FORMAT_BC1_UNORM_SRGB:
+    case DXGI_FORMAT_BC2_TYPELESS:
+    case DXGI_FORMAT_BC2_UNORM:
+    case DXGI_FORMAT_BC2_UNORM_SRGB:
+    case DXGI_FORMAT_BC3_TYPELESS:
+    case DXGI_FORMAT_BC3_UNORM:
+    case DXGI_FORMAT_BC3_UNORM_SRGB:
+    case DXGI_FORMAT_B5G5R5A1_UNORM:
+    case DXGI_FORMAT_B8G8R8A8_UNORM:
+    case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:
+    case DXGI_FORMAT_B8G8R8A8_TYPELESS:
+    case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
+    case DXGI_FORMAT_BC7_TYPELESS:
+    case DXGI_FORMAT_BC7_UNORM:
+    case DXGI_FORMAT_BC7_UNORM_SRGB:
+    case DXGI_FORMAT_AYUV:
+    case DXGI_FORMAT_Y410:
+    case DXGI_FORMAT_Y416:
+    case DXGI_FORMAT_AI44:
+    case DXGI_FORMAT_IA44:
+    case DXGI_FORMAT_A8P8:
+    case DXGI_FORMAT_B4G4R4A4_UNORM:
+        return true;
+
+    case 116 /* DXGI_FORMAT_R10G10B10_7E3_A2_FLOAT */:
+    case 117 /* DXGI_FORMAT_R10G10B10_6E4_A2_FLOAT */:
+        // These are Xbox One platform specific types
+        return true;
+
+    default:
+        return false;
+    }
+}
+
+_Use_decl_annotations_
+inline size_t ComputeScanlines( DXGI_FORMAT fmt, size_t height )
+{
+    if ( IsCompressed(fmt) )
+    {
+        return std::max<size_t>( 1, (height + 3) / 4 );
+    }
+    else if ( fmt == DXGI_FORMAT_NV11 )
+    {
+        // Direct3D makes this simplifying assumption, although it is larger than the 4:1:1 data
+        return height * 2;
+    }
+    else if ( IsPlanar(fmt) )
+    {
+        return height + ( ( height + 1 ) >> 1 );
+    }
+    else
+    {
+        return height;
+    }
+}
+
+//=====================================================================================
+// Image I/O
+//=====================================================================================
+_Use_decl_annotations_
+inline HRESULT SaveToDDSMemory( const Image& image, DWORD flags, Blob& blob )
+{
+    TexMetadata mdata;
+    memset( &mdata, 0, sizeof(mdata) );
+    mdata.width = image.width;
+    mdata.height = image.height;
+    mdata.depth = 1;
+    mdata.arraySize = 1;
+    mdata.mipLevels = 1;
+    mdata.format = image.format;
+    mdata.dimension = TEX_DIMENSION_TEXTURE2D;
+
+    return SaveToDDSMemory( &image, 1, mdata, flags, blob );
+}
+
+_Use_decl_annotations_
+inline HRESULT SaveToDDSFile( const Image& image, DWORD flags, LPCWSTR szFile )
+{
+    TexMetadata mdata;
+    memset( &mdata, 0, sizeof(mdata) );
+    mdata.width = image.width;
+    mdata.height = image.height;
+    mdata.depth = 1;
+    mdata.arraySize = 1;
+    mdata.mipLevels = 1;
+    mdata.format = image.format;
+    mdata.dimension = TEX_DIMENSION_TEXTURE2D;
+
+    return SaveToDDSFile( &image, 1, mdata, flags, szFile );
+}

+ 809 - 0
Exporters/FBX/3rdParty/DirectXTex/DirectXTexCompress.cpp

@@ -0,0 +1,809 @@
+//-------------------------------------------------------------------------------------
+// DirectXTexCompress.cpp
+//  
+// DirectX Texture Library - Texture compression
+//
+// 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=248926
+//-------------------------------------------------------------------------------------
+
+#include "directxtexp.h"
+
+#ifdef _OPENMP
+#include <omp.h>
+#pragma warning(disable : 4616 6993)
+#endif
+
+#include "bc.h"
+
+
+namespace DirectX
+{
+
+inline static DWORD _GetBCFlags( _In_ DWORD compress )
+{
+    static_assert( TEX_COMPRESS_RGB_DITHER == BC_FLAGS_DITHER_RGB, "TEX_COMPRESS_* flags should match BC_FLAGS_*" );
+    static_assert( TEX_COMPRESS_A_DITHER == BC_FLAGS_DITHER_A, "TEX_COMPRESS_* flags should match BC_FLAGS_*"  );
+    static_assert( TEX_COMPRESS_DITHER == (BC_FLAGS_DITHER_RGB | BC_FLAGS_DITHER_A), "TEX_COMPRESS_* flags should match BC_FLAGS_*"  );
+    static_assert( TEX_COMPRESS_UNIFORM == BC_FLAGS_UNIFORM, "TEX_COMPRESS_* flags should match BC_FLAGS_*"  );
+    return ( compress & (BC_FLAGS_DITHER_RGB|BC_FLAGS_DITHER_A|BC_FLAGS_UNIFORM) );
+}
+
+inline static DWORD _GetSRGBFlags( _In_ DWORD compress )
+{
+    static_assert( TEX_COMPRESS_SRGB_IN == TEX_FILTER_SRGB_IN, "TEX_COMPRESS_SRGB* should match TEX_FILTER_SRGB*" );
+    static_assert( TEX_COMPRESS_SRGB_OUT == TEX_FILTER_SRGB_OUT, "TEX_COMPRESS_SRGB* should match TEX_FILTER_SRGB*" );
+    static_assert( TEX_COMPRESS_SRGB == TEX_FILTER_SRGB, "TEX_COMPRESS_SRGB* should match TEX_FILTER_SRGB*" );
+    return ( compress & TEX_COMPRESS_SRGB );
+}
+
+inline static bool _DetermineEncoderSettings( _In_ DXGI_FORMAT format, _Out_ BC_ENCODE& pfEncode, _Out_ size_t& blocksize, _Out_ DWORD& cflags )
+{
+    switch(format)
+    {
+    case DXGI_FORMAT_BC1_UNORM:
+    case DXGI_FORMAT_BC1_UNORM_SRGB:    pfEncode = nullptr;         blocksize = 8;   cflags = 0; break;
+    case DXGI_FORMAT_BC2_UNORM:
+    case DXGI_FORMAT_BC2_UNORM_SRGB:    pfEncode = D3DXEncodeBC2;   blocksize = 16;  cflags = 0; break;
+    case DXGI_FORMAT_BC3_UNORM:
+    case DXGI_FORMAT_BC3_UNORM_SRGB:    pfEncode = D3DXEncodeBC3;   blocksize = 16;  cflags = 0; break;
+    case DXGI_FORMAT_BC4_UNORM:         pfEncode = D3DXEncodeBC4U;  blocksize = 8;   cflags = TEX_FILTER_RGB_COPY_RED; break;
+    case DXGI_FORMAT_BC4_SNORM:         pfEncode = D3DXEncodeBC4S;  blocksize = 8;   cflags = TEX_FILTER_RGB_COPY_RED; break;
+    case DXGI_FORMAT_BC5_UNORM:         pfEncode = D3DXEncodeBC5U;  blocksize = 16;  cflags = TEX_FILTER_RGB_COPY_RED | TEX_FILTER_RGB_COPY_GREEN; break;
+    case DXGI_FORMAT_BC5_SNORM:         pfEncode = D3DXEncodeBC5S;  blocksize = 16;  cflags = TEX_FILTER_RGB_COPY_RED | TEX_FILTER_RGB_COPY_GREEN; break;
+    case DXGI_FORMAT_BC6H_UF16:         pfEncode = D3DXEncodeBC6HU; blocksize = 16;  cflags = 0; break;
+    case DXGI_FORMAT_BC6H_SF16:         pfEncode = D3DXEncodeBC6HS; blocksize = 16;  cflags = 0; break;
+    case DXGI_FORMAT_BC7_UNORM:
+    case DXGI_FORMAT_BC7_UNORM_SRGB:    pfEncode = D3DXEncodeBC7;   blocksize = 16;  cflags = 0; break;
+    default:                            pfEncode = nullptr;         blocksize = 0;   cflags = 0; return false;
+    }
+
+    return true;
+}
+
+
+//-------------------------------------------------------------------------------------
+static HRESULT _CompressBC( _In_ const Image& image, _In_ const Image& result, _In_ DWORD bcflags,
+                            _In_ DWORD srgb, _In_ float alphaRef )
+{
+    if ( !image.pixels || !result.pixels )
+        return E_POINTER;
+
+    assert( image.width == result.width );
+    assert( image.height == result.height );
+
+    const DXGI_FORMAT format = image.format;
+    size_t sbpp = BitsPerPixel( format );
+    if ( !sbpp )
+        return E_FAIL;
+
+    if ( sbpp < 8 )
+    {
+        // We don't support compressing from monochrome (DXGI_FORMAT_R1_UNORM)
+        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+    }
+
+    // Round to bytes
+    sbpp = ( sbpp + 7 ) / 8;
+
+    uint8_t *pDest = result.pixels;
+
+    // Determine BC format encoder
+    BC_ENCODE pfEncode;
+    size_t blocksize;
+    DWORD cflags;
+    if ( !_DetermineEncoderSettings( result.format, pfEncode, blocksize, cflags ) )
+        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+
+    XMVECTOR temp[16];
+    const uint8_t *pSrc = image.pixels;
+    const size_t rowPitch = image.rowPitch;
+    for( size_t h=0; h < image.height; h += 4 )
+    {
+        const uint8_t *sptr = pSrc;
+        uint8_t* dptr = pDest;
+        size_t ph = std::min<size_t>( 4, image.height - h );
+        size_t w = 0;
+        for( size_t count = 0; count < rowPitch; count += sbpp*4, w += 4 )
+        {
+            size_t pw = std::min<size_t>( 4, image.width - w );
+            assert( pw > 0 && ph > 0 );
+
+            if ( !_LoadScanline( &temp[0], pw, sptr, rowPitch, format ) )
+                return E_FAIL;
+
+            if ( ph > 1 )
+            {
+                if ( !_LoadScanline( &temp[4], pw, sptr + rowPitch, rowPitch, format ) )
+                    return E_FAIL;
+
+                if ( ph > 2 )
+                {
+                    if ( !_LoadScanline( &temp[8], pw, sptr + rowPitch*2, rowPitch, format ) )
+                        return E_FAIL;
+
+                    if ( ph > 3 )
+                    {
+                        if ( !_LoadScanline( &temp[12], pw, sptr + rowPitch*3, rowPitch, format ) )
+                            return E_FAIL;
+                    }
+                }
+            }
+
+            if ( pw != 4 || ph != 4 )
+            {
+                // Replicate pixels for partial block
+                static const size_t uSrc[] = { 0, 0, 0, 1 };
+
+                if ( pw < 4 )
+                {
+                    for( size_t t = 0; t < ph && t < 4; ++t )
+                    {
+                        for( size_t s = pw; s < 4; ++s )
+                        {
+#pragma prefast(suppress: 26000, "PREFAST false positive")
+                            temp[ (t << 2) | s ] = temp[ (t << 2) | uSrc[s] ]; 
+                        }
+                    }
+                }
+
+                if ( ph < 4 )
+                {
+                    for( size_t t = ph; t < 4; ++t )
+                    {
+                        for( size_t s = 0; s < 4; ++s )
+                        {
+#pragma prefast(suppress: 26000, "PREFAST false positive")
+                            temp[ (t << 2) | s ] = temp[ (uSrc[t] << 2) | s ]; 
+                        }
+                    }
+                }
+            }
+
+            _ConvertScanline( temp, 16, result.format, format, cflags | srgb );
+            
+            if ( pfEncode )
+                pfEncode( dptr, temp, bcflags );
+            else
+                D3DXEncodeBC1( dptr, temp, alphaRef, bcflags );
+
+            sptr += sbpp*4;
+            dptr += blocksize;
+        }
+
+        pSrc += rowPitch*4;
+        pDest += result.rowPitch;
+    }
+
+    return S_OK;
+}
+
+
+//-------------------------------------------------------------------------------------
+#ifdef _OPENMP
+static HRESULT _CompressBC_Parallel( _In_ const Image& image, _In_ const Image& result, _In_ DWORD bcflags,
+                                     _In_ DWORD srgb, _In_ float alphaRef )
+{
+    if ( !image.pixels || !result.pixels )
+        return E_POINTER;
+
+    assert( image.width == result.width );
+    assert( image.height == result.height );
+
+    const DXGI_FORMAT format = image.format;
+    size_t sbpp = BitsPerPixel( format );
+    if ( !sbpp )
+        return E_FAIL;
+
+    if ( sbpp < 8 )
+    {
+        // We don't support compressing from monochrome (DXGI_FORMAT_R1_UNORM)
+        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+    }
+
+    // Round to bytes
+    sbpp = ( sbpp + 7 ) / 8;
+
+    // Determine BC format encoder
+    BC_ENCODE pfEncode;
+    size_t blocksize;
+    DWORD cflags;
+    if ( !_DetermineEncoderSettings( result.format, pfEncode, blocksize, cflags ) )
+        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+
+    // Refactored version of loop to support parallel independance
+    const size_t nBlocks = std::max<size_t>(1, (image.width + 3) / 4 ) * std::max<size_t>(1, (image.height + 3) / 4 );
+
+    bool fail = false;
+
+#pragma omp parallel for
+    for( int nb=0; nb < static_cast<int>( nBlocks ); ++nb )
+    {
+        const size_t nbWidth = std::max<size_t>(1, (image.width + 3) / 4 );
+
+        const size_t y = nb / nbWidth;
+        const size_t x = nb - (y*nbWidth);
+
+        assert( x < image.width && y < image.height );
+
+        size_t rowPitch = image.rowPitch;
+        const uint8_t *pSrc = image.pixels + (y*4*rowPitch) + (x*4*sbpp);
+
+        uint8_t *pDest = result.pixels + (nb*blocksize);
+
+        size_t ph = std::min<size_t>( 4, image.height - y );
+        size_t pw = std::min<size_t>( 4, image.width - x );
+        assert( pw > 0 && ph > 0 );
+
+        XMVECTOR temp[16];
+        if ( !_LoadScanline( &temp[0], pw, pSrc, rowPitch, format ) )
+            fail = true;
+
+        if ( ph > 1 )
+        {
+            if ( !_LoadScanline( &temp[4], pw, pSrc + rowPitch, rowPitch, format ) )
+                fail = true;
+
+            if ( ph > 2 )
+            {
+                if ( !_LoadScanline( &temp[8], pw, pSrc + rowPitch*2, rowPitch, format ) )
+                    fail = true;
+
+                if ( ph > 3 )
+                {
+                    if ( !_LoadScanline( &temp[12], pw, pSrc + rowPitch*3, rowPitch, format ) )
+                        fail = true;
+                }
+            }
+        }
+
+        if ( pw != 4 || ph != 4 )
+        {
+            // Replicate pixels for partial block
+            static const size_t uSrc[] = { 0, 0, 0, 1 };
+
+            if ( pw < 4 )
+            {
+                for( size_t t = 0; t < ph && t < 4; ++t )
+                {
+                    for( size_t s = pw; s < 4; ++s )
+                    {
+                        temp[ (t << 2) | s ] = temp[ (t << 2) | uSrc[s] ]; 
+                    }
+                }
+            }
+
+            if ( ph < 4 )
+            {
+                for( size_t t = ph; t < 4; ++t )
+                {
+                    for( size_t s = 0; s < 4; ++s )
+                    {
+                        temp[ (t << 2) | s ] = temp[ (uSrc[t] << 2) | s ]; 
+                    }
+                }
+            }
+        }
+
+        _ConvertScanline( temp, 16, result.format, format, cflags | srgb );
+            
+        if ( pfEncode )
+            pfEncode( pDest, temp, bcflags );
+        else
+            D3DXEncodeBC1( pDest, temp, alphaRef, bcflags );
+    }
+
+    return (fail) ? E_FAIL : S_OK;
+}
+
+#endif // _OPENMP
+
+
+//-------------------------------------------------------------------------------------
+static DXGI_FORMAT _DefaultDecompress( _In_ DXGI_FORMAT format )
+{
+    switch( format )
+    {
+    case DXGI_FORMAT_BC1_TYPELESS:
+    case DXGI_FORMAT_BC1_UNORM:
+    case DXGI_FORMAT_BC2_TYPELESS:
+    case DXGI_FORMAT_BC2_UNORM:
+    case DXGI_FORMAT_BC3_TYPELESS:
+    case DXGI_FORMAT_BC3_UNORM:
+    case DXGI_FORMAT_BC7_TYPELESS:
+    case DXGI_FORMAT_BC7_UNORM:
+        return DXGI_FORMAT_R8G8B8A8_UNORM;
+
+    case DXGI_FORMAT_BC1_UNORM_SRGB:
+    case DXGI_FORMAT_BC2_UNORM_SRGB:
+    case DXGI_FORMAT_BC3_UNORM_SRGB:
+    case DXGI_FORMAT_BC7_UNORM_SRGB:
+        return DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
+
+    case DXGI_FORMAT_BC4_TYPELESS:
+    case DXGI_FORMAT_BC4_UNORM:
+        return DXGI_FORMAT_R8_UNORM;
+
+    case DXGI_FORMAT_BC4_SNORM:
+        return DXGI_FORMAT_R8_SNORM;
+
+    case DXGI_FORMAT_BC5_TYPELESS:
+    case DXGI_FORMAT_BC5_UNORM:
+        return DXGI_FORMAT_R8G8_UNORM;
+
+    case DXGI_FORMAT_BC5_SNORM:
+        return DXGI_FORMAT_R8G8_SNORM;
+
+    case DXGI_FORMAT_BC6H_TYPELESS:
+    case DXGI_FORMAT_BC6H_UF16:
+    case DXGI_FORMAT_BC6H_SF16:
+        // We could use DXGI_FORMAT_R32G32B32_FLOAT here since BC6H is always Alpha 1.0,
+        // but this format is more supported by viewers
+        return DXGI_FORMAT_R32G32B32A32_FLOAT;
+
+    default:
+        return DXGI_FORMAT_UNKNOWN;
+    }
+}
+
+
+//-------------------------------------------------------------------------------------
+static HRESULT _DecompressBC( _In_ const Image& cImage, _In_ const Image& result )
+{
+    if ( !cImage.pixels || !result.pixels )
+        return E_POINTER;
+
+    assert( cImage.width == result.width );
+    assert( cImage.height == result.height );
+
+    const DXGI_FORMAT format = result.format;
+    size_t dbpp = BitsPerPixel( format );
+    if ( !dbpp )
+        return E_FAIL;
+
+    if ( dbpp < 8 )
+    {
+        // We don't support decompressing to monochrome (DXGI_FORMAT_R1_UNORM)
+        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+    }
+
+    // Round to bytes
+    dbpp = ( dbpp + 7 ) / 8;
+
+    uint8_t *pDest = result.pixels;
+    if ( !pDest )
+        return E_POINTER;
+
+    // Promote "typeless" BC formats
+    DXGI_FORMAT cformat;
+    switch( cImage.format )
+    {
+    case DXGI_FORMAT_BC1_TYPELESS:  cformat = DXGI_FORMAT_BC1_UNORM; break;
+    case DXGI_FORMAT_BC2_TYPELESS:  cformat = DXGI_FORMAT_BC2_UNORM; break;
+    case DXGI_FORMAT_BC3_TYPELESS:  cformat = DXGI_FORMAT_BC3_UNORM; break;
+    case DXGI_FORMAT_BC4_TYPELESS:  cformat = DXGI_FORMAT_BC4_UNORM; break;
+    case DXGI_FORMAT_BC5_TYPELESS:  cformat = DXGI_FORMAT_BC5_UNORM; break;
+    case DXGI_FORMAT_BC6H_TYPELESS: cformat = DXGI_FORMAT_BC6H_UF16; break;
+    case DXGI_FORMAT_BC7_TYPELESS:  cformat = DXGI_FORMAT_BC7_UNORM; break;
+    default:                        cformat = cImage.format;         break;
+    }
+
+    // Determine BC format decoder
+    BC_DECODE pfDecode;
+    size_t sbpp;
+    switch(cformat)
+    {
+    case DXGI_FORMAT_BC1_UNORM:
+    case DXGI_FORMAT_BC1_UNORM_SRGB:    pfDecode = D3DXDecodeBC1;   sbpp = 8;   break;
+    case DXGI_FORMAT_BC2_UNORM:
+    case DXGI_FORMAT_BC2_UNORM_SRGB:    pfDecode = D3DXDecodeBC2;   sbpp = 16;  break;
+    case DXGI_FORMAT_BC3_UNORM:
+    case DXGI_FORMAT_BC3_UNORM_SRGB:    pfDecode = D3DXDecodeBC3;   sbpp = 16;  break;
+    case DXGI_FORMAT_BC4_UNORM:         pfDecode = D3DXDecodeBC4U;  sbpp = 8;   break;
+    case DXGI_FORMAT_BC4_SNORM:         pfDecode = D3DXDecodeBC4S;  sbpp = 8;   break;
+    case DXGI_FORMAT_BC5_UNORM:         pfDecode = D3DXDecodeBC5U;  sbpp = 16;  break;
+    case DXGI_FORMAT_BC5_SNORM:         pfDecode = D3DXDecodeBC5S;  sbpp = 16;  break;
+    case DXGI_FORMAT_BC6H_UF16:         pfDecode = D3DXDecodeBC6HU; sbpp = 16;  break;
+    case DXGI_FORMAT_BC6H_SF16:         pfDecode = D3DXDecodeBC6HS; sbpp = 16;  break;
+    case DXGI_FORMAT_BC7_UNORM:
+    case DXGI_FORMAT_BC7_UNORM_SRGB:    pfDecode = D3DXDecodeBC7;   sbpp = 16;  break;
+    default:
+        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+    }
+
+    XMVECTOR temp[16];
+    const uint8_t *pSrc = cImage.pixels;
+    const size_t rowPitch = result.rowPitch;
+    for( size_t h=0; h < cImage.height; h += 4 )
+    {
+        const uint8_t *sptr = pSrc;
+        uint8_t* dptr = pDest;
+        size_t ph = std::min<size_t>( 4, cImage.height - h );
+        size_t w = 0;
+        for( size_t count = 0; count < cImage.rowPitch; count += sbpp, w += 4 )
+        {
+            pfDecode( temp, sptr );
+            _ConvertScanline( temp, 16, format, cformat, 0 );
+
+            size_t pw = std::min<size_t>( 4, cImage.width - w );
+            assert( pw > 0 && ph > 0 );
+
+            if ( !_StoreScanline( dptr, rowPitch, format, &temp[0], pw ) )
+                return E_FAIL;
+
+            if ( ph > 1 )
+            {
+                if ( !_StoreScanline( dptr + rowPitch, rowPitch, format, &temp[4], pw ) )
+                    return E_FAIL;
+
+                if ( ph > 2 )
+                {
+                    if ( !_StoreScanline( dptr + rowPitch*2, rowPitch, format, &temp[8], pw ) )
+                        return E_FAIL;
+
+                    if ( ph > 3 )
+                    {
+                        if ( !_StoreScanline( dptr + rowPitch*3, rowPitch, format, &temp[12], pw ) )
+                            return E_FAIL;
+                    }
+                }
+            }
+
+            sptr += sbpp;
+            dptr += dbpp*4;
+        }
+
+        pSrc += cImage.rowPitch;
+        pDest += rowPitch*4;
+    }
+
+    return S_OK;
+}
+
+
+//-------------------------------------------------------------------------------------
+bool _IsAlphaAllOpaqueBC( _In_ const Image& cImage )
+{
+    if ( !cImage.pixels )
+        return false;
+
+    // Promote "typeless" BC formats
+    DXGI_FORMAT cformat;
+    switch( cImage.format )
+    {
+    case DXGI_FORMAT_BC1_TYPELESS:  cformat = DXGI_FORMAT_BC1_UNORM; break;
+    case DXGI_FORMAT_BC2_TYPELESS:  cformat = DXGI_FORMAT_BC2_UNORM; break;
+    case DXGI_FORMAT_BC3_TYPELESS:  cformat = DXGI_FORMAT_BC3_UNORM; break;
+    case DXGI_FORMAT_BC7_TYPELESS:  cformat = DXGI_FORMAT_BC7_UNORM; break;
+    default:                        cformat = cImage.format;         break;
+    }
+
+    // Determine BC format decoder
+    BC_DECODE pfDecode;
+    size_t sbpp;
+    switch(cformat)
+    {
+    case DXGI_FORMAT_BC1_UNORM:
+    case DXGI_FORMAT_BC1_UNORM_SRGB:    pfDecode = D3DXDecodeBC1;   sbpp = 8;   break;
+    case DXGI_FORMAT_BC2_UNORM:
+    case DXGI_FORMAT_BC2_UNORM_SRGB:    pfDecode = D3DXDecodeBC2;   sbpp = 16;  break;
+    case DXGI_FORMAT_BC3_UNORM:
+    case DXGI_FORMAT_BC3_UNORM_SRGB:    pfDecode = D3DXDecodeBC3;   sbpp = 16;  break;
+    case DXGI_FORMAT_BC7_UNORM:
+    case DXGI_FORMAT_BC7_UNORM_SRGB:    pfDecode = D3DXDecodeBC7;   sbpp = 16;  break;
+    default:
+        // BC4, BC5, and BC6 don't have alpha channels
+        return false;
+    }
+
+    // Scan blocks for non-opaque alpha
+    static const XMVECTORF32 threshold = { 0.99f, 0.99f, 0.99f, 0.99f };
+
+    XMVECTOR temp[16];
+    const uint8_t *pPixels = cImage.pixels;
+    for( size_t h = 0; h < cImage.height; h += 4 )
+    {
+        const uint8_t *ptr = pPixels;
+        size_t ph = std::min<size_t>( 4, cImage.height - h );
+        size_t w = 0;
+        for( size_t count = 0; count < cImage.rowPitch; count += sbpp, w += 4 )
+        {
+            pfDecode( temp, ptr );
+
+            size_t pw = std::min<size_t>( 4, cImage.width - w );
+            assert( pw > 0 && ph > 0 );
+
+            if ( pw == 4 && ph == 4 )
+            {
+                // Full blocks
+                for( size_t j = 0; j < 16; ++j )
+                {
+                    XMVECTOR alpha = XMVectorSplatW( temp[j] );
+                    if ( XMVector4Less( alpha, threshold ) )
+                        return false;
+                }
+            }
+            else
+            {
+                // Handle partial blocks
+                for( size_t y = 0; y < ph; ++y )
+                {
+                    for( size_t x = 0; x < pw; ++x )
+                    {
+                        XMVECTOR alpha = XMVectorSplatW( temp[ y * 4 + x ] );
+                        if ( XMVector4Less( alpha, threshold ) )
+                            return false;
+                    }
+                }
+            }
+
+            ptr += sbpp;
+        }
+
+        pPixels += cImage.rowPitch;
+    }
+
+    return true;
+}
+
+
+//=====================================================================================
+// Entry-points
+//=====================================================================================
+
+//-------------------------------------------------------------------------------------
+// Compression
+//-------------------------------------------------------------------------------------
+_Use_decl_annotations_
+HRESULT Compress( const Image& srcImage, DXGI_FORMAT format, DWORD compress, float alphaRef, ScratchImage& image )
+{
+    if ( IsCompressed(srcImage.format) || !IsCompressed(format) )
+        return E_INVALIDARG;
+
+    if ( IsTypeless(format)
+         || IsTypeless(srcImage.format) || IsPlanar(srcImage.format) || IsPalettized(srcImage.format) )
+        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+
+    // Create compressed image
+    HRESULT hr = image.Initialize2D( format, srcImage.width, srcImage.height, 1, 1 );
+    if ( FAILED(hr) )
+        return hr;
+
+    const Image *img = image.GetImage( 0, 0, 0 );
+    if ( !img )
+    {
+        image.Release();
+        return E_POINTER;
+    }
+
+    // Compress single image
+    if (compress & TEX_COMPRESS_PARALLEL)
+    {
+#ifndef _OPENMP
+        return E_NOTIMPL;
+#else
+        hr = _CompressBC_Parallel( srcImage, *img, _GetBCFlags( compress ), _GetSRGBFlags( compress ), alphaRef );
+#endif // _OPENMP
+    }
+    else
+    {
+        hr = _CompressBC( srcImage, *img, _GetBCFlags( compress ), _GetSRGBFlags( compress ), alphaRef );
+    }
+
+    if ( FAILED(hr) )
+        image.Release();
+
+    return hr;
+}
+
+_Use_decl_annotations_
+HRESULT Compress( const Image* srcImages, size_t nimages, const TexMetadata& metadata,
+                  DXGI_FORMAT format, DWORD compress, float alphaRef, ScratchImage& cImages )
+{
+    if ( !srcImages || !nimages )
+        return E_INVALIDARG;
+
+    if ( IsCompressed(metadata.format) || !IsCompressed(format) )
+        return E_INVALIDARG;
+
+    if ( IsTypeless(format)
+         || IsTypeless(metadata.format) || IsPlanar(metadata.format) || IsPalettized(metadata.format) )
+        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+
+    cImages.Release();
+
+    TexMetadata mdata2 = metadata;
+    mdata2.format = format;
+    HRESULT hr = cImages.Initialize( mdata2 );
+    if ( FAILED(hr) )
+        return hr;
+
+    if ( nimages != cImages.GetImageCount() )
+    {
+        cImages.Release();
+        return E_FAIL;
+    }
+
+    const Image* dest = cImages.GetImages();
+    if ( !dest  )
+    {
+        cImages.Release();
+        return E_POINTER;
+    }
+
+    for( size_t index=0; index < nimages; ++index )
+    {
+        assert( dest[ index ].format == format );
+
+        const Image& src = srcImages[ index ];
+
+        if ( src.width != dest[ index ].width || src.height != dest[ index ].height )
+        {
+            cImages.Release();
+            return E_FAIL;
+        }
+
+        if ( (compress & TEX_COMPRESS_PARALLEL) )
+        {
+#ifndef _OPENMP
+            return E_NOTIMPL;
+#else
+            if ( compress & TEX_COMPRESS_PARALLEL )
+            {
+                hr = _CompressBC_Parallel( src, dest[ index ], _GetBCFlags( compress ), _GetSRGBFlags( compress ), alphaRef );
+                if ( FAILED(hr) )
+                {
+                    cImages.Release();
+                    return  hr;
+                }
+            }
+#endif // _OPENMP
+        }
+        else
+        {
+            hr = _CompressBC( src, dest[ index ], _GetBCFlags( compress ), _GetSRGBFlags( compress ), alphaRef );
+            if ( FAILED(hr) )
+            {
+                cImages.Release();
+                return hr;
+            }
+        }
+    }
+
+    return S_OK;
+}
+
+
+//-------------------------------------------------------------------------------------
+// Decompression
+//-------------------------------------------------------------------------------------
+_Use_decl_annotations_
+HRESULT Decompress( const Image& cImage, DXGI_FORMAT format, ScratchImage& image )
+{
+    if ( !IsCompressed(cImage.format) || IsCompressed(format) )
+        return E_INVALIDARG;
+
+    if ( format == DXGI_FORMAT_UNKNOWN )
+    {
+        // Pick a default decompressed format based on BC input format
+        format = _DefaultDecompress( cImage.format );
+        if ( format == DXGI_FORMAT_UNKNOWN )
+        {
+            // Input is not a compressed format
+            return E_INVALIDARG;
+        }
+    }
+    else
+    {
+        if ( !IsValid(format) )
+            return E_INVALIDARG;
+
+        if ( IsTypeless(format) || IsPlanar(format) || IsPalettized(format) )
+            return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+    }
+
+    // Create decompressed image
+    HRESULT hr = image.Initialize2D( format, cImage.width, cImage.height, 1, 1 );
+    if ( FAILED(hr) )
+        return hr;
+
+    const Image *img = image.GetImage( 0, 0, 0 );
+    if ( !img )
+    {
+        image.Release();
+        return E_POINTER;
+    }
+
+    // Decompress single image
+    hr = _DecompressBC( cImage, *img );
+    if ( FAILED(hr) )
+        image.Release();
+
+    return hr;
+}
+
+_Use_decl_annotations_
+HRESULT Decompress( const Image* cImages, size_t nimages, const TexMetadata& metadata,
+                    DXGI_FORMAT format, ScratchImage& images )
+{
+    if ( !cImages || !nimages )
+        return E_INVALIDARG;
+
+    if ( !IsCompressed(metadata.format) || IsCompressed(format) )
+        return E_INVALIDARG;
+
+    if ( format == DXGI_FORMAT_UNKNOWN )
+    {
+        // Pick a default decompressed format based on BC input format
+        format = _DefaultDecompress( cImages[0].format );
+        if ( format == DXGI_FORMAT_UNKNOWN )
+        {
+            // Input is not a compressed format
+            return E_FAIL;
+        }
+    }
+    else
+    {
+        if ( !IsValid(format) )
+            return E_INVALIDARG;
+
+        if ( IsTypeless(format) || IsPlanar(format) || IsPalettized(format) )
+            HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+    }
+
+    images.Release();
+
+    TexMetadata mdata2 = metadata;
+    mdata2.format = format;
+    HRESULT hr = images.Initialize( mdata2 );
+    if ( FAILED(hr) )
+        return hr;
+
+    if ( nimages != images.GetImageCount() )
+    {
+        images.Release();
+        return E_FAIL;
+    }
+
+    const Image* dest = images.GetImages();
+    if ( !dest )
+    {
+        images.Release();
+        return E_POINTER;
+    }
+
+    for( size_t index=0; index < nimages; ++index )
+    {
+        assert( dest[ index ].format == format );
+
+        const Image& src = cImages[ index ];
+        if ( !IsCompressed( src.format ) )
+        {
+            images.Release();
+            return E_FAIL;
+        }
+
+        if ( src.width != dest[ index ].width || src.height != dest[ index ].height )
+        {
+            images.Release();
+            return E_FAIL;
+        }
+
+        hr = _DecompressBC( src, dest[ index ] );
+        if ( FAILED(hr) )
+        {
+            images.Release();
+            return hr;
+        }
+    }
+
+    return S_OK;
+}
+
+}; // namespace

+ 402 - 0
Exporters/FBX/3rdParty/DirectXTex/DirectXTexCompressGPU.cpp

@@ -0,0 +1,402 @@
+//-------------------------------------------------------------------------------------
+// DirectXTexCompressGPU.cpp
+//  
+// DirectX Texture Library - DirectCompute-based texture compression
+//
+// 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=248926
+//-------------------------------------------------------------------------------------
+
+#include "directxtexp.h"
+
+#include "bcdirectcompute.h"
+
+namespace DirectX
+{
+
+inline static DWORD _GetSRGBFlags( _In_ DWORD compress )
+{
+    static_assert( TEX_COMPRESS_SRGB_IN == TEX_FILTER_SRGB_IN, "TEX_COMPRESS_SRGB* should match TEX_FILTER_SRGB*" );
+    static_assert( TEX_COMPRESS_SRGB_OUT == TEX_FILTER_SRGB_OUT, "TEX_COMPRESS_SRGB* should match TEX_FILTER_SRGB*" );
+    static_assert( TEX_COMPRESS_SRGB == TEX_FILTER_SRGB, "TEX_COMPRESS_SRGB* should match TEX_FILTER_SRGB*" );
+    return ( compress & TEX_COMPRESS_SRGB );
+}
+
+
+//-------------------------------------------------------------------------------------
+// Converts to R8G8B8A8_UNORM or R8G8B8A8_UNORM_SRGB doing any conversion logic needed
+//-------------------------------------------------------------------------------------
+static HRESULT _ConvertToRGBA32( _In_ const Image& srcImage, _In_ ScratchImage& image, bool srgb, _In_ DWORD filter )
+{
+    if ( !srcImage.pixels )
+        return E_POINTER;
+
+    DXGI_FORMAT format = srgb ? DXGI_FORMAT_R8G8B8A8_UNORM_SRGB : DXGI_FORMAT_R8G8B8A8_UNORM;
+
+    HRESULT hr = image.Initialize2D( format, srcImage.width, srcImage.height, 1, 1 );
+    if ( FAILED(hr) )
+        return hr;
+
+    const Image *img = image.GetImage( 0, 0, 0 );
+    if ( !img )
+    {
+        image.Release();
+        return E_POINTER;
+    }
+
+    uint8_t* pDest = img->pixels;
+    if ( !pDest )
+    {
+        image.Release();
+        return E_POINTER;
+    }
+
+    ScopedAlignedArrayXMVECTOR scanline( reinterpret_cast<XMVECTOR*>( _aligned_malloc( ( sizeof(XMVECTOR) * srcImage.width ), 16 ) ) );
+    if ( !scanline )
+    {
+        image.Release();
+        return E_OUTOFMEMORY;
+    }
+
+    const uint8_t *pSrc = srcImage.pixels;
+    for( size_t h = 0; h < srcImage.height; ++h )
+    {
+        if ( !_LoadScanline( scanline.get(), srcImage.width, pSrc, srcImage.rowPitch, srcImage.format ) )
+        {
+            image.Release();
+            return E_FAIL;
+        }
+
+        _ConvertScanline( scanline.get(), srcImage.width, format, srcImage.format, filter );
+
+        if ( !_StoreScanline( pDest, img->rowPitch, format, scanline.get(), srcImage.width ) )
+        {
+            image.Release();
+            return E_FAIL;
+        }
+
+        pSrc += srcImage.rowPitch;
+        pDest += img->rowPitch;
+    }
+
+    return S_OK;
+}
+
+
+//-------------------------------------------------------------------------------------
+// Converts to DXGI_FORMAT_R32G32B32A32_FLOAT doing any conversion logic needed
+//-------------------------------------------------------------------------------------
+static HRESULT _ConvertToRGBAF32( const Image& srcImage, ScratchImage& image, _In_ DWORD filter )
+{
+    if ( !srcImage.pixels )
+        return E_POINTER;
+
+    HRESULT hr = image.Initialize2D( DXGI_FORMAT_R32G32B32A32_FLOAT, srcImage.width, srcImage.height, 1, 1 );
+    if ( FAILED(hr) )
+        return hr;
+
+    const Image *img = image.GetImage( 0, 0, 0 );
+    if ( !img )
+    {
+        image.Release();
+        return E_POINTER;
+    }
+
+    uint8_t* pDest = img->pixels;
+    if ( !pDest )
+    {
+        image.Release();
+        return E_POINTER;
+    }
+
+    const uint8_t *pSrc = srcImage.pixels;
+    for( size_t h = 0; h < srcImage.height; ++h )
+    {
+        if ( !_LoadScanline( reinterpret_cast<XMVECTOR*>(pDest), srcImage.width, pSrc, srcImage.rowPitch, srcImage.format ) )
+        {
+            image.Release();
+            return E_FAIL;
+        }
+
+        _ConvertScanline( reinterpret_cast<XMVECTOR*>(pDest), srcImage.width, DXGI_FORMAT_R32G32B32A32_FLOAT, srcImage.format, filter );
+
+        pSrc += srcImage.rowPitch;
+        pDest += img->rowPitch;
+    }
+
+    return S_OK;
+}
+
+
+//-------------------------------------------------------------------------------------
+// Compress using GPU, converting to the proper input format for the shader if needed
+//-------------------------------------------------------------------------------------
+inline static HRESULT _GPUCompress( _In_ GPUCompressBC* gpubc, _In_ const Image& srcImage, _In_ const Image& destImage, _In_ DWORD compress )
+{
+    if ( !gpubc )
+        return E_POINTER;
+
+    assert( srcImage.pixels && destImage.pixels );
+
+    DXGI_FORMAT format = gpubc->GetSourceFormat();
+
+    if ( srcImage.format == format )
+    {
+        // Input is already in our required source format
+        return gpubc->Compress( srcImage, destImage );
+    }
+    else
+    {
+        // Convert format and then use as the source image
+        ScratchImage image;
+        HRESULT hr;
+
+        DWORD srgb = _GetSRGBFlags( compress );
+
+        switch( format )
+        {
+        case DXGI_FORMAT_R8G8B8A8_UNORM:
+            hr = _ConvertToRGBA32( srcImage, image, false, srgb );
+            break;
+
+        case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
+            hr = _ConvertToRGBA32( srcImage, image, true, srgb );
+            break;
+
+        case DXGI_FORMAT_R32G32B32A32_FLOAT:
+            hr = _ConvertToRGBAF32( srcImage, image, srgb );
+            break;
+
+        default:
+            hr = E_UNEXPECTED;
+            break;
+        }
+
+        if ( FAILED(hr) )
+            return hr;
+
+        const Image *img = image.GetImage( 0, 0, 0 );
+        if ( !img )
+            return E_POINTER;
+
+        return gpubc->Compress( *img, destImage );
+    }
+}
+
+
+//=====================================================================================
+// Entry-points
+//=====================================================================================
+
+//-------------------------------------------------------------------------------------
+// Compression
+//-------------------------------------------------------------------------------------
+_Use_decl_annotations_
+HRESULT Compress( ID3D11Device* pDevice, const Image& srcImage, DXGI_FORMAT format, DWORD compress, float alphaWeight, ScratchImage& image )
+{
+    if ( !pDevice || IsCompressed(srcImage.format) || !IsCompressed(format) )
+        return E_INVALIDARG;
+
+    if ( IsTypeless(format)
+         || IsTypeless(srcImage.format) || IsPlanar(srcImage.format) || IsPalettized(srcImage.format) )
+        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+
+    // Setup GPU compressor
+    std::unique_ptr<GPUCompressBC> gpubc( new (std::nothrow) GPUCompressBC );
+    if ( !gpubc )
+        return E_OUTOFMEMORY;
+
+    HRESULT hr = gpubc->Initialize( pDevice );
+    if ( FAILED(hr) )
+        return hr;
+
+    hr = gpubc->Prepare( srcImage.width, srcImage.height, format, alphaWeight );
+    if ( FAILED(hr) )
+        return hr;
+
+    // Create workspace for result
+    hr = image.Initialize2D( format, srcImage.width, srcImage.height, 1, 1 );
+    if ( FAILED(hr) )
+        return hr;
+
+    const Image *img = image.GetImage( 0, 0, 0 );
+    if ( !img )
+    {
+        image.Release();
+        return E_POINTER;
+    }
+
+    hr = _GPUCompress( gpubc.get(), srcImage, *img, compress );
+    if ( FAILED(hr) )
+        image.Release();
+
+    return hr;
+}
+
+_Use_decl_annotations_
+HRESULT Compress( ID3D11Device* pDevice, const Image* srcImages, size_t nimages, const TexMetadata& metadata,
+                  DXGI_FORMAT format, DWORD compress, float alphaWeight, ScratchImage& cImages )
+{
+    if ( !pDevice || !srcImages || !nimages )
+        return E_INVALIDARG;
+
+    if ( IsCompressed(metadata.format) || !IsCompressed(format) )
+        return E_INVALIDARG;
+
+    if ( IsTypeless(format)
+         || IsTypeless(metadata.format) || IsPlanar(metadata.format) || IsPalettized(metadata.format) )
+        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+
+    cImages.Release();
+
+    // Setup GPU compressor
+    std::unique_ptr<GPUCompressBC> gpubc( new (std::nothrow) GPUCompressBC );
+    if ( !gpubc )
+        return E_OUTOFMEMORY;
+
+    HRESULT hr = gpubc->Initialize( pDevice );
+    if ( FAILED(hr) )
+        return hr;
+
+    // Create workspace for result
+    TexMetadata mdata2 = metadata;
+    mdata2.format = format;
+    hr = cImages.Initialize( mdata2 );
+    if ( FAILED(hr) )
+        return hr;
+
+    if ( nimages != cImages.GetImageCount() )
+    {
+        cImages.Release();
+        return E_FAIL;
+    }
+
+    const Image* dest = cImages.GetImages();
+    if ( !dest  )
+    {
+        cImages.Release();
+        return E_POINTER;
+    }
+
+    // Process images (ordered by size)
+    switch( metadata.dimension )
+    {
+    case TEX_DIMENSION_TEXTURE1D:
+    case TEX_DIMENSION_TEXTURE2D:
+        {
+            size_t w = metadata.width;
+            size_t h = metadata.height;
+
+            for( size_t level=0; level < metadata.mipLevels; ++level )
+            {
+                hr = gpubc->Prepare( w, h, format, alphaWeight );
+                if ( FAILED(hr) )
+                {
+                    cImages.Release();
+                    return hr;
+                }
+
+                for( size_t item = 0; item < metadata.arraySize; ++item )
+                {
+                    size_t index = metadata.ComputeIndex( level, item, 0 );
+                    if ( index >= nimages )
+                    {
+                        cImages.Release();
+                        return E_FAIL;
+                    }
+
+                    assert( dest[ index ].format == format );
+
+                    const Image& src = srcImages[ index ];
+
+                    if ( src.width != dest[ index ].width || src.height != dest[ index ].height )
+                    {
+                        cImages.Release();
+                        return E_FAIL;
+                    }
+
+                    hr = _GPUCompress( gpubc.get(), src, dest[ index ], compress );
+                    if ( FAILED(hr) )
+                    {
+                        cImages.Release();
+                        return hr;
+                    }
+                }
+
+                if ( h > 1 )
+                    h >>= 1;
+
+                if ( w > 1 )
+                    w >>= 1;
+            }
+        }
+        break;
+
+    case TEX_DIMENSION_TEXTURE3D:
+        {
+            size_t w = metadata.width;
+            size_t h = metadata.height;
+            size_t d = metadata.depth;
+
+            for( size_t level=0; level < metadata.mipLevels; ++level )
+            {
+                hr = gpubc->Prepare( w, h, format, alphaWeight );
+                if ( FAILED(hr) )
+                {
+                    cImages.Release();
+                    return hr;
+                }
+
+                for( size_t slice=0; slice < d; ++slice )
+                {
+                    size_t index = metadata.ComputeIndex( level, 0, slice );
+                    if ( index >= nimages )
+                    {
+                        cImages.Release();
+                        return E_FAIL;
+                    }
+
+                    assert( dest[ index ].format == format );
+
+                    const Image& src = srcImages[ index ];
+
+                    if ( src.width != dest[ index ].width || src.height != dest[ index ].height )
+                    {
+                        cImages.Release();
+                        return E_FAIL;
+                    }
+
+                    hr = _GPUCompress( gpubc.get(), src, dest[ index ], compress );
+                    if ( FAILED(hr) )
+                    {
+                        cImages.Release();
+                        return hr;
+                    }
+                }
+
+                if ( h > 1 )
+                    h >>= 1;
+
+                if ( w > 1 )
+                    w >>= 1;
+
+                if ( d > 1 )
+                    d >>= 1;
+            }
+        }
+        break;
+
+    default:
+        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+    }
+
+    return S_OK;
+}
+
+}; // namespace

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 4515 - 0
Exporters/FBX/3rdParty/DirectXTex/DirectXTexConvert.cpp


+ 875 - 0
Exporters/FBX/3rdParty/DirectXTex/DirectXTexD3D11.cpp

@@ -0,0 +1,875 @@
+//-------------------------------------------------------------------------------------
+// DirectXTexD3D11.cpp
+//  
+// DirectX Texture Library - Direct3D 11 helpers
+//
+// 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=248926
+//-------------------------------------------------------------------------------------
+
+#include "directxtexp.h"
+
+#if !defined(_XBOX_ONE) || !defined(_TITLE) || !MONOLITHIC
+#include <d3d10.h>
+#endif
+
+using Microsoft::WRL::ComPtr;
+
+namespace DirectX
+{
+
+static HRESULT _Capture( _In_ ID3D11DeviceContext* pContext, _In_ ID3D11Resource* pSource, _In_ const TexMetadata& metadata,
+                         _In_ const ScratchImage& result )
+{
+    if ( !pContext || !pSource || !result.GetPixels() )
+        return E_POINTER;
+
+    if ( metadata.IsVolumemap() )
+    {
+        //--- Volume texture ----------------------------------------------------------
+        assert( metadata.arraySize == 1 );
+
+        size_t height = metadata.height;
+        size_t depth = metadata.depth;
+
+        for( size_t level = 0; level < metadata.mipLevels; ++level )
+        {
+            UINT dindex = D3D11CalcSubresource( static_cast<UINT>( level ), 0, static_cast<UINT>( metadata.mipLevels ) );
+
+            D3D11_MAPPED_SUBRESOURCE mapped;
+            HRESULT hr = pContext->Map( pSource, dindex, D3D11_MAP_READ, 0, &mapped );
+            if ( FAILED(hr) )
+                return hr;
+
+            auto pslice = reinterpret_cast<const uint8_t*>( mapped.pData );
+            if ( !pslice )
+            {
+                pContext->Unmap( pSource, dindex );
+                return E_POINTER;
+            }
+
+            size_t lines = ComputeScanlines( metadata.format, height );
+            if ( !lines )
+            {
+                pContext->Unmap( pSource, dindex );
+                return E_UNEXPECTED;
+            }
+
+            for( size_t slice = 0; slice < depth; ++slice )
+            {
+                const Image* img = result.GetImage( level, 0, slice );
+                if ( !img )
+                {
+                    pContext->Unmap( pSource, dindex );
+                    return E_FAIL;
+                }
+
+                if ( !img->pixels )
+                {
+                    pContext->Unmap( pSource, dindex );
+                    return E_POINTER;
+                }
+
+                const uint8_t* sptr = pslice;
+                uint8_t* dptr = img->pixels;
+                for( size_t h = 0; h < lines; ++h )
+                {
+                    size_t msize = std::min<size_t>( img->rowPitch, mapped.RowPitch );
+                    memcpy_s( dptr, img->rowPitch, sptr, msize );
+                    sptr += mapped.RowPitch;
+                    dptr += img->rowPitch;
+                }
+
+                pslice += mapped.DepthPitch;
+            }
+
+            pContext->Unmap( pSource, dindex );
+
+            if ( height > 1 )
+                height >>= 1;
+            if ( depth > 1 )
+                depth >>= 1;
+        }
+    }
+    else
+    {
+        //--- 1D or 2D texture --------------------------------------------------------
+        assert( metadata.depth == 1 );
+
+        for( size_t item = 0; item < metadata.arraySize; ++item )
+        {
+            size_t height = metadata.height;
+
+            for( size_t level = 0; level < metadata.mipLevels; ++level )
+            {
+                UINT dindex = D3D11CalcSubresource( static_cast<UINT>( level ), static_cast<UINT>( item ), static_cast<UINT>( metadata.mipLevels ) );
+
+                D3D11_MAPPED_SUBRESOURCE mapped;
+                HRESULT hr = pContext->Map( pSource, dindex, D3D11_MAP_READ, 0, &mapped );
+                if ( FAILED(hr) )
+                    return hr;
+
+                const Image* img = result.GetImage( level, item, 0 );
+                if ( !img )
+                {
+                    pContext->Unmap( pSource, dindex );
+                    return E_FAIL;
+                }
+
+                if ( !img->pixels )
+                {
+                    pContext->Unmap( pSource, dindex );
+                    return E_POINTER;
+                }
+
+                size_t lines = ComputeScanlines( metadata.format, height );
+                if ( !lines )
+                {
+                    pContext->Unmap( pSource, dindex );
+                    return E_UNEXPECTED;
+                }
+
+                auto sptr = reinterpret_cast<const uint8_t*>( mapped.pData );
+                uint8_t* dptr = img->pixels;
+                for( size_t h = 0; h < lines; ++h )
+                {
+                    size_t msize = std::min<size_t>( img->rowPitch, mapped.RowPitch );
+                    memcpy_s( dptr, img->rowPitch, sptr, msize );
+                    sptr += mapped.RowPitch;
+                    dptr += img->rowPitch;
+                }
+
+                pContext->Unmap( pSource, dindex );
+
+                if ( height > 1 )
+                    height >>= 1;
+            }
+        }
+    }
+
+    return S_OK;
+}
+
+
+//=====================================================================================
+// Entry-points
+//=====================================================================================
+
+//-------------------------------------------------------------------------------------
+// Determine if given texture metadata is supported on the given device
+//-------------------------------------------------------------------------------------
+_Use_decl_annotations_
+bool IsSupportedTexture( ID3D11Device* pDevice, const TexMetadata& metadata )
+{
+    if ( !pDevice )
+        return false;
+
+    D3D_FEATURE_LEVEL fl = pDevice->GetFeatureLevel();
+
+    // Validate format
+    DXGI_FORMAT fmt = metadata.format;
+
+    if ( !IsValid( fmt ) )
+        return false;
+
+    switch( fmt )
+    {
+    case DXGI_FORMAT_BC4_TYPELESS:
+    case DXGI_FORMAT_BC4_UNORM:
+    case DXGI_FORMAT_BC4_SNORM:
+    case DXGI_FORMAT_BC5_TYPELESS:
+    case DXGI_FORMAT_BC5_UNORM:
+    case DXGI_FORMAT_BC5_SNORM:
+        if ( fl < D3D_FEATURE_LEVEL_10_0 )
+            return false;
+        break;
+
+    case DXGI_FORMAT_BC6H_TYPELESS:
+    case DXGI_FORMAT_BC6H_UF16:
+    case DXGI_FORMAT_BC6H_SF16:
+    case DXGI_FORMAT_BC7_TYPELESS:
+    case DXGI_FORMAT_BC7_UNORM:
+    case DXGI_FORMAT_BC7_UNORM_SRGB:
+        if ( fl < D3D_FEATURE_LEVEL_11_0 )
+            return false;
+        break;
+    }
+
+    // Validate miplevel count
+    if ( metadata.mipLevels > D3D11_REQ_MIP_LEVELS )
+        return false;
+       
+    // Validate array size, dimension, and width/height
+    size_t arraySize = metadata.arraySize;
+    size_t iWidth = metadata.width;
+    size_t iHeight = metadata.height;
+    size_t iDepth = metadata.depth;
+
+    // Most cases are known apriori based on feature level, but we use this for robustness to handle the few optional cases
+    UINT formatSupport = 0;
+    HRESULT hr = pDevice->CheckFormatSupport( fmt, &formatSupport );
+    if ( FAILED(hr) )
+    {
+        formatSupport = 0;
+    }
+
+    switch ( metadata.dimension )
+    {
+    case TEX_DIMENSION_TEXTURE1D:
+        if ( !(formatSupport & D3D11_FORMAT_SUPPORT_TEXTURE1D) )
+            return false;
+
+        if ( (arraySize > D3D11_REQ_TEXTURE1D_ARRAY_AXIS_DIMENSION)
+             || (iWidth > D3D11_REQ_TEXTURE1D_U_DIMENSION) )
+            return false;
+
+        if ( fl < D3D_FEATURE_LEVEL_11_0 )
+        {
+            if ( (arraySize > D3D10_REQ_TEXTURE1D_ARRAY_AXIS_DIMENSION)
+                 || (iWidth > D3D10_REQ_TEXTURE1D_U_DIMENSION) )
+                return false;
+
+            if ( fl < D3D_FEATURE_LEVEL_10_0 )
+            {
+                if ( (arraySize > 1) || (iWidth > D3D_FL9_3_REQ_TEXTURE1D_U_DIMENSION) )
+                    return false;
+
+                if ( (fl < D3D_FEATURE_LEVEL_9_3) && (iWidth > D3D_FL9_1_REQ_TEXTURE1D_U_DIMENSION ) )
+                    return false;
+            }
+        }
+        break;
+
+    case TEX_DIMENSION_TEXTURE2D:
+        if ( metadata.IsCubemap() )
+        {
+            if ( !(formatSupport & D3D11_FORMAT_SUPPORT_TEXTURECUBE) )
+                return false;
+
+            if ( (arraySize > D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION)
+                 || (iWidth > D3D11_REQ_TEXTURECUBE_DIMENSION) 
+                 || (iHeight > D3D11_REQ_TEXTURECUBE_DIMENSION))
+                return false;
+
+            if ( fl < D3D_FEATURE_LEVEL_11_0 )
+            {
+                if ( (arraySize > D3D10_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION)
+                     || (iWidth > D3D10_REQ_TEXTURECUBE_DIMENSION) 
+                     || (iHeight > D3D10_REQ_TEXTURECUBE_DIMENSION))
+                    return false;
+
+                if ( (fl < D3D_FEATURE_LEVEL_10_1) && (arraySize != 6) )
+                    return false;
+
+                if ( fl < D3D_FEATURE_LEVEL_10_0 )
+                {
+                    if ( (iWidth > D3D_FL9_3_REQ_TEXTURECUBE_DIMENSION )
+                         || (iHeight > D3D_FL9_3_REQ_TEXTURECUBE_DIMENSION ) )
+                        return false;
+
+                    if ( (fl < D3D_FEATURE_LEVEL_9_3)
+                         && ( (iWidth > D3D_FL9_1_REQ_TEXTURECUBE_DIMENSION)
+                              || (iHeight > D3D_FL9_1_REQ_TEXTURECUBE_DIMENSION) ) )
+                        return false;
+                }
+            }
+        }
+        else // Not a cube map
+        {
+            if ( !(formatSupport & D3D11_FORMAT_SUPPORT_TEXTURE2D) )
+                return false;
+
+            if ( (arraySize > D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION)
+                 || (iWidth > D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION) 
+                 || (iHeight > D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION))
+                return false;
+
+            if ( fl < D3D_FEATURE_LEVEL_11_0 )
+            {
+                if ( (arraySize > D3D10_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION)
+                     || (iWidth > D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION) 
+                     || (iHeight > D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION))
+                    return false;
+
+                if ( fl < D3D_FEATURE_LEVEL_10_0 )
+                {
+                    if ( (arraySize > 1)
+                         || (iWidth > D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION)
+                         || (iHeight > D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION) )
+                        return false;
+
+                    if ( (fl < D3D_FEATURE_LEVEL_9_3)
+                         && ( (iWidth > D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION)
+                              || (iHeight > D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION) ) )
+                        return false;
+                }
+            }
+        }
+        break;
+
+    case TEX_DIMENSION_TEXTURE3D:
+        if ( !(formatSupport & D3D11_FORMAT_SUPPORT_TEXTURE3D) )
+            return false;
+
+        if ( (arraySize > 1)
+             || (iWidth > D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION) 
+             || (iHeight > D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION)
+             || (iDepth > D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION) )
+            return false;
+
+        if ( fl < D3D_FEATURE_LEVEL_11_0 )
+        {
+            if ( (iWidth > D3D10_REQ_TEXTURE3D_U_V_OR_W_DIMENSION) 
+                 || (iHeight > D3D10_REQ_TEXTURE3D_U_V_OR_W_DIMENSION)
+                 || (iDepth > D3D10_REQ_TEXTURE3D_U_V_OR_W_DIMENSION) )
+                return false;
+
+            if ( fl < D3D_FEATURE_LEVEL_10_0 )
+            {
+                if ( (iWidth > D3D_FL9_1_REQ_TEXTURE3D_U_V_OR_W_DIMENSION)
+                     || (iHeight > D3D_FL9_1_REQ_TEXTURE3D_U_V_OR_W_DIMENSION)
+                     || (iDepth > D3D_FL9_1_REQ_TEXTURE3D_U_V_OR_W_DIMENSION) )
+                    return false;
+            }
+        }
+        break;
+
+    default:
+        // Not a supported dimension
+        return false;
+    }
+
+    return true;
+}
+
+
+//-------------------------------------------------------------------------------------
+// Create a texture resource
+//-------------------------------------------------------------------------------------
+_Use_decl_annotations_
+HRESULT CreateTexture( ID3D11Device* pDevice, const Image* srcImages, size_t nimages, const TexMetadata& metadata,
+                       ID3D11Resource** ppResource )
+{
+    return CreateTextureEx( pDevice, srcImages, nimages, metadata,
+                            D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, false,
+                            ppResource );
+}
+
+_Use_decl_annotations_
+HRESULT CreateTextureEx( ID3D11Device* pDevice, const Image* srcImages, size_t nimages, const TexMetadata& metadata,
+                         D3D11_USAGE usage, unsigned int bindFlags, unsigned int cpuAccessFlags, unsigned int miscFlags, bool forceSRGB,
+                         ID3D11Resource** ppResource )
+{
+    if ( !pDevice || !srcImages || !nimages || !ppResource )
+        return E_INVALIDARG;
+
+    *ppResource = nullptr;
+
+    if ( !metadata.mipLevels || !metadata.arraySize )
+        return E_INVALIDARG;
+
+#ifdef _M_X64
+    if ( (metadata.width > 0xFFFFFFFF) || (metadata.height > 0xFFFFFFFF)
+         || (metadata.mipLevels > 0xFFFFFFFF) || (metadata.arraySize > 0xFFFFFFFF) )
+        return E_INVALIDARG;
+#endif
+
+    std::unique_ptr<D3D11_SUBRESOURCE_DATA[]> initData( new (std::nothrow) D3D11_SUBRESOURCE_DATA[ metadata.mipLevels * metadata.arraySize ] );
+    if ( !initData )
+        return E_OUTOFMEMORY;
+
+    // Fill out subresource array
+    if ( metadata.IsVolumemap() )
+    {
+        //--- Volume case -------------------------------------------------------------
+        if ( !metadata.depth )
+            return E_INVALIDARG;
+
+#ifdef _M_X64
+        if ( metadata.depth > 0xFFFFFFFF )
+            return E_INVALIDARG;
+#endif
+
+        if ( metadata.arraySize > 1 )
+            // Direct3D 11 doesn't support arrays of 3D textures
+            return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+
+        size_t depth = metadata.depth;
+
+        size_t idx = 0;
+        for( size_t level = 0; level < metadata.mipLevels; ++level )
+        {
+            size_t index = metadata.ComputeIndex( level, 0, 0 );
+            if ( index >= nimages )
+                return E_FAIL;
+
+            const Image& img = srcImages[ index ];
+
+            if ( img.format != metadata.format )
+                return E_FAIL;
+
+            if ( !img.pixels )
+                return E_POINTER;
+
+            // Verify pixels in image 1 .. (depth-1) are exactly image->slicePitch apart
+            // For 3D textures, this relies on all slices of the same miplevel being continous in memory
+            // (this is how ScratchImage lays them out), which is why we just give the 0th slice to Direct3D 11
+            const uint8_t* pSlice = img.pixels + img.slicePitch;
+            for( size_t slice = 1; slice < depth; ++slice )
+            {
+                size_t tindex = metadata.ComputeIndex( level, 0, slice );
+                if ( tindex >= nimages )
+                    return E_FAIL;
+
+                const Image& timg = srcImages[ tindex ];
+
+                if ( !timg.pixels )
+                    return E_POINTER;
+
+                if ( timg.pixels != pSlice
+                     || timg.format != metadata.format
+                     || timg.rowPitch != img.rowPitch
+                     || timg.slicePitch != img.slicePitch )
+                    return E_FAIL;
+
+                pSlice = timg.pixels + img.slicePitch;
+            }
+
+            assert( idx < (metadata.mipLevels * metadata.arraySize) );
+
+            initData[idx].pSysMem = img.pixels;
+            initData[idx].SysMemPitch = static_cast<DWORD>( img.rowPitch );
+            initData[idx].SysMemSlicePitch = static_cast<DWORD>( img.slicePitch );
+            ++idx;
+
+            if ( depth > 1 )
+                depth >>= 1;
+        }
+    }
+    else
+    {
+        //--- 1D or 2D texture case ---------------------------------------------------
+        size_t idx = 0;
+        for( size_t item = 0; item < metadata.arraySize; ++item )
+        {
+            for( size_t level = 0; level < metadata.mipLevels; ++level )
+            {
+                size_t index = metadata.ComputeIndex( level, item, 0 );
+                if ( index >= nimages )
+                    return E_FAIL;
+
+                const Image& img = srcImages[ index ];
+
+                if ( img.format != metadata.format )
+                    return E_FAIL;
+
+                if ( !img.pixels )
+                    return E_POINTER;
+
+                assert( idx < (metadata.mipLevels * metadata.arraySize) );
+
+                initData[idx].pSysMem = img.pixels;
+                initData[idx].SysMemPitch = static_cast<DWORD>( img.rowPitch );
+                initData[idx].SysMemSlicePitch = static_cast<DWORD>( img.slicePitch );
+                ++idx;
+            }
+        }
+    }
+
+    // Create texture using static initialization data
+    HRESULT hr = E_FAIL;
+
+    DXGI_FORMAT tformat = ( forceSRGB ) ? MakeSRGB( metadata.format ) : metadata.format;
+
+    switch ( metadata.dimension )
+    {
+    case TEX_DIMENSION_TEXTURE1D:
+        {
+            D3D11_TEXTURE1D_DESC desc;
+            desc.Width = static_cast<UINT>( metadata.width );
+            desc.MipLevels = static_cast<UINT>( metadata.mipLevels );
+            desc.ArraySize = static_cast<UINT>( metadata.arraySize );
+            desc.Format = tformat;
+            desc.Usage = usage;
+            desc.BindFlags = bindFlags;
+            desc.CPUAccessFlags = cpuAccessFlags;
+            desc.MiscFlags = miscFlags & ~D3D11_RESOURCE_MISC_TEXTURECUBE;
+
+            hr = pDevice->CreateTexture1D( &desc, initData.get(), reinterpret_cast<ID3D11Texture1D**>(ppResource) );
+        }
+        break;
+
+    case TEX_DIMENSION_TEXTURE2D:
+        {
+            D3D11_TEXTURE2D_DESC desc;
+            desc.Width = static_cast<UINT>( metadata.width );
+            desc.Height = static_cast<UINT>( metadata.height ); 
+            desc.MipLevels = static_cast<UINT>( metadata.mipLevels );
+            desc.ArraySize = static_cast<UINT>( metadata.arraySize );
+            desc.Format = tformat;
+            desc.SampleDesc.Count = 1;
+            desc.SampleDesc.Quality = 0;
+            desc.Usage = usage;
+            desc.BindFlags = bindFlags;
+            desc.CPUAccessFlags = cpuAccessFlags;
+            if ( metadata.IsCubemap() )
+                desc.MiscFlags =  miscFlags | D3D11_RESOURCE_MISC_TEXTURECUBE;
+            else
+                desc.MiscFlags =  miscFlags & ~D3D11_RESOURCE_MISC_TEXTURECUBE;
+
+            hr = pDevice->CreateTexture2D( &desc, initData.get(), reinterpret_cast<ID3D11Texture2D**>(ppResource) );
+        }
+        break;
+
+    case TEX_DIMENSION_TEXTURE3D:
+        {
+            D3D11_TEXTURE3D_DESC desc;
+            desc.Width = static_cast<UINT>( metadata.width );
+            desc.Height = static_cast<UINT>( metadata.height );
+            desc.Depth = static_cast<UINT>( metadata.depth );
+            desc.MipLevels = static_cast<UINT>( metadata.mipLevels );
+            desc.Format = tformat;
+            desc.Usage = usage;
+            desc.BindFlags = bindFlags;
+            desc.CPUAccessFlags = cpuAccessFlags;
+            desc.MiscFlags = miscFlags & ~D3D11_RESOURCE_MISC_TEXTURECUBE;
+
+            hr = pDevice->CreateTexture3D( &desc, initData.get(), reinterpret_cast<ID3D11Texture3D**>(ppResource) );
+        }
+        break;
+    }
+
+    return hr;
+}
+
+
+//-------------------------------------------------------------------------------------
+// Create a shader resource view and associated texture
+//-------------------------------------------------------------------------------------
+_Use_decl_annotations_
+HRESULT CreateShaderResourceView( ID3D11Device* pDevice, const Image* srcImages, size_t nimages, const TexMetadata& metadata,
+                                  ID3D11ShaderResourceView** ppSRV )
+{
+    return CreateShaderResourceViewEx( pDevice, srcImages, nimages, metadata,
+                                       D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, false,
+                                       ppSRV );
+}
+
+_Use_decl_annotations_
+HRESULT CreateShaderResourceViewEx( ID3D11Device* pDevice, const Image* srcImages, size_t nimages, const TexMetadata& metadata,
+                                    D3D11_USAGE usage, unsigned int bindFlags, unsigned int cpuAccessFlags, unsigned int miscFlags, bool forceSRGB,
+                                    ID3D11ShaderResourceView** ppSRV )
+{
+    if ( !ppSRV )
+        return E_INVALIDARG;
+
+    *ppSRV = nullptr;
+
+    ComPtr<ID3D11Resource> resource;
+    HRESULT hr = CreateTextureEx( pDevice, srcImages, nimages, metadata,
+                                  usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB,
+                                  resource.GetAddressOf() );
+    if ( FAILED(hr) )
+        return hr;
+
+    assert( resource );
+
+    D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc;
+    memset( &SRVDesc, 0, sizeof(SRVDesc) );
+    if ( forceSRGB )
+        SRVDesc.Format = MakeSRGB( metadata.format );
+    else
+        SRVDesc.Format = metadata.format;
+
+    switch ( metadata.dimension )
+    {
+    case TEX_DIMENSION_TEXTURE1D:
+        if ( metadata.arraySize > 1 )
+        {
+            SRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE1DARRAY;
+            SRVDesc.Texture1DArray.MipLevels = static_cast<UINT>( metadata.mipLevels );
+            SRVDesc.Texture1DArray.ArraySize = static_cast<UINT>( metadata.arraySize );
+        }
+        else
+        {
+            SRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE1D;
+            SRVDesc.Texture1D.MipLevels = static_cast<UINT>( metadata.mipLevels );
+        }
+        break;
+
+    case TEX_DIMENSION_TEXTURE2D:
+        if ( metadata.IsCubemap() )
+        {
+            if (metadata.arraySize > 6)
+            {
+                assert( (metadata.arraySize % 6) == 0 );
+                SRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURECUBEARRAY;
+                SRVDesc.TextureCubeArray.MipLevels = static_cast<UINT>( metadata.mipLevels );
+                SRVDesc.TextureCubeArray.NumCubes = static_cast<UINT>( metadata.arraySize / 6 );
+            }
+            else
+            {
+                SRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURECUBE;
+                SRVDesc.TextureCube.MipLevels = static_cast<UINT>( metadata.mipLevels );
+            }
+        }
+        else if ( metadata.arraySize > 1 )
+        {
+            SRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE2DARRAY;
+            SRVDesc.Texture2DArray.MipLevels = static_cast<UINT>( metadata.mipLevels );
+            SRVDesc.Texture2DArray.ArraySize = static_cast<UINT>( metadata.arraySize );
+        }
+        else
+        {
+            SRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE2D;
+            SRVDesc.Texture2D.MipLevels = static_cast<UINT>( metadata.mipLevels );
+        }
+        break;
+
+    case TEX_DIMENSION_TEXTURE3D:
+        assert( metadata.arraySize == 1 );
+        SRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE3D;
+        SRVDesc.Texture3D.MipLevels = static_cast<UINT>( metadata.mipLevels );
+        break;
+
+    default:
+        return E_FAIL;
+    }
+
+    hr = pDevice->CreateShaderResourceView( resource.Get(), &SRVDesc, ppSRV );
+    if ( FAILED(hr) )
+        return hr;
+
+    assert( *ppSRV );
+
+    return S_OK;
+}
+
+
+//-------------------------------------------------------------------------------------
+// Save a texture resource to a DDS file in memory/on disk
+//-------------------------------------------------------------------------------------
+_Use_decl_annotations_
+HRESULT CaptureTexture( ID3D11Device* pDevice, ID3D11DeviceContext* pContext, ID3D11Resource* pSource, ScratchImage& result )
+{
+    if ( !pDevice || !pContext || !pSource )
+        return E_INVALIDARG;
+
+    D3D11_RESOURCE_DIMENSION resType = D3D11_RESOURCE_DIMENSION_UNKNOWN;
+    pSource->GetType( &resType );
+
+    HRESULT hr;
+
+    switch( resType )
+    {
+    case D3D11_RESOURCE_DIMENSION_TEXTURE1D:
+        {
+            ComPtr<ID3D11Texture1D> pTexture;
+            hr = pSource->QueryInterface( __uuidof(ID3D11Texture1D), reinterpret_cast<void**>( pTexture.GetAddressOf() ) );
+            if ( FAILED(hr) )
+                break;
+
+            assert( pTexture );
+
+            D3D11_TEXTURE1D_DESC desc;
+            pTexture->GetDesc( &desc );
+
+            desc.BindFlags = 0;
+            desc.MiscFlags = 0;
+            desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
+            desc.Usage = D3D11_USAGE_STAGING;
+
+            ComPtr<ID3D11Texture1D> pStaging;
+            hr = pDevice->CreateTexture1D( &desc, 0, pStaging.GetAddressOf() );
+            if ( FAILED(hr) )
+                break;
+
+            assert( pStaging );
+
+            pContext->CopyResource( pStaging.Get(), pSource );
+
+            TexMetadata mdata;
+            mdata.width = desc.Width;
+            mdata.height = mdata.depth = 1;
+            mdata.arraySize = desc.ArraySize;
+            mdata.mipLevels = desc.MipLevels;
+            mdata.miscFlags = 0;
+            mdata.miscFlags2 = 0;
+            mdata.format = desc.Format;
+            mdata.dimension = TEX_DIMENSION_TEXTURE1D;
+
+            hr = result.Initialize( mdata );
+            if ( FAILED(hr) )
+                break;
+
+            hr = _Capture( pContext, pStaging.Get(), mdata, result );
+        }
+        break;
+
+    case D3D11_RESOURCE_DIMENSION_TEXTURE2D:
+        {
+            ComPtr<ID3D11Texture2D> pTexture;
+            hr = pSource->QueryInterface( __uuidof(ID3D11Texture2D), reinterpret_cast<void**>( pTexture.GetAddressOf() ) );
+            if ( FAILED(hr) )
+                break;
+
+            assert( pTexture );
+
+            D3D11_TEXTURE2D_DESC desc;
+            pTexture->GetDesc( &desc );
+
+            ComPtr<ID3D11Texture2D> pStaging;
+            if ( desc.SampleDesc.Count > 1 )
+            {
+                desc.SampleDesc.Count = 1;
+                desc.SampleDesc.Quality = 0;
+
+                ComPtr<ID3D11Texture2D> pTemp;
+                hr = pDevice->CreateTexture2D( &desc, 0, pTemp.GetAddressOf() );
+                if ( FAILED(hr) )
+                    break;
+
+                assert( pTemp );
+
+                DXGI_FORMAT fmt = desc.Format;
+                if ( IsTypeless(fmt) )
+                {
+                    // Assume a UNORM if it exists otherwise use FLOAT
+                    fmt = MakeTypelessUNORM( fmt );
+                    fmt = MakeTypelessFLOAT( fmt );
+                }
+
+                UINT support = 0;
+                hr = pDevice->CheckFormatSupport( fmt, &support );
+                if ( FAILED(hr) )
+                    break;
+
+                if ( !(support & D3D11_FORMAT_SUPPORT_MULTISAMPLE_RESOLVE) )
+                {
+                    hr = E_FAIL;
+                    break;
+                }
+
+                for( UINT item = 0; item < desc.ArraySize; ++item )
+                {
+                    for( UINT level = 0; level < desc.MipLevels; ++level )
+                    {
+                        UINT index = D3D11CalcSubresource( level, item, desc.MipLevels );
+                        pContext->ResolveSubresource( pTemp.Get(), index, pSource, index, fmt );
+                    }
+                }
+
+                desc.BindFlags = 0;
+                desc.MiscFlags &= D3D11_RESOURCE_MISC_TEXTURECUBE;
+                desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
+                desc.Usage = D3D11_USAGE_STAGING;
+
+                hr = pDevice->CreateTexture2D( &desc, 0, pStaging.GetAddressOf() );
+                if ( FAILED(hr) )
+                    break;
+
+                assert( pStaging );
+
+                pContext->CopyResource( pStaging.Get(), pTemp.Get() );
+            }
+            else
+            {
+                desc.BindFlags = 0;
+                desc.MiscFlags &= D3D11_RESOURCE_MISC_TEXTURECUBE;
+                desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
+                desc.Usage = D3D11_USAGE_STAGING;
+
+                hr = pDevice->CreateTexture2D( &desc, 0, &pStaging );
+                if ( FAILED(hr) )
+                    break;
+
+                assert( pStaging );
+
+                pContext->CopyResource( pStaging.Get(), pSource );
+            }
+
+            TexMetadata mdata;
+            mdata.width = desc.Width;
+            mdata.height = desc.Height;
+            mdata.depth = 1;
+            mdata.arraySize = desc.ArraySize;
+            mdata.mipLevels = desc.MipLevels;
+            mdata.miscFlags = (desc.MiscFlags & D3D11_RESOURCE_MISC_TEXTURECUBE) ? TEX_MISC_TEXTURECUBE : 0;
+            mdata.miscFlags2 = 0;
+            mdata.format = desc.Format;
+            mdata.dimension = TEX_DIMENSION_TEXTURE2D;
+
+            hr = result.Initialize( mdata );
+            if ( FAILED(hr) )
+                break;
+
+            hr = _Capture( pContext, pStaging.Get(), mdata, result );
+        }
+        break;
+
+    case D3D11_RESOURCE_DIMENSION_TEXTURE3D:
+        {
+            ComPtr<ID3D11Texture3D> pTexture;
+            hr = pSource->QueryInterface( __uuidof(ID3D11Texture3D), reinterpret_cast<void**>( pTexture.GetAddressOf() ) );
+            if ( FAILED(hr) )
+                break;
+
+            assert( pTexture );
+
+            D3D11_TEXTURE3D_DESC desc;
+            pTexture->GetDesc( &desc );
+
+            desc.BindFlags = 0;
+            desc.MiscFlags = 0;
+            desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
+            desc.Usage = D3D11_USAGE_STAGING;
+
+            ComPtr<ID3D11Texture3D> pStaging;
+            hr = pDevice->CreateTexture3D( &desc, 0, pStaging.GetAddressOf() );
+            if ( FAILED(hr) )
+                break;
+
+            assert( pStaging );
+
+            pContext->CopyResource( pStaging.Get(), pSource );
+
+            TexMetadata mdata;
+            mdata.width = desc.Width;
+            mdata.height = desc.Height;
+            mdata.depth = desc.Depth;
+            mdata.arraySize = 1;
+            mdata.mipLevels = desc.MipLevels;
+            mdata.miscFlags = 0;
+            mdata.miscFlags2 = 0;
+            mdata.format = desc.Format;
+            mdata.dimension = TEX_DIMENSION_TEXTURE3D;
+
+            hr = result.Initialize( mdata );
+            if ( FAILED(hr) )
+                break;
+
+            hr = _Capture( pContext, pStaging.Get(), mdata, result );
+        }
+        break;
+
+    default:
+        hr = E_FAIL;
+        break;
+    }
+
+    if ( FAILED(hr) )
+    {
+        result.Release();
+        return hr;
+    }
+
+    return S_OK;
+}
+
+}; // namespace

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 2002 - 0
Exporters/FBX/3rdParty/DirectXTex/DirectXTexDDS.cpp


+ 331 - 0
Exporters/FBX/3rdParty/DirectXTex/DirectXTexFlipRotate.cpp

@@ -0,0 +1,331 @@
+//-------------------------------------------------------------------------------------
+// DirectXTexFlipRotate.cpp
+//  
+// DirectX Texture Library - Image flip/rotate operations
+//
+// 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=248926
+//-------------------------------------------------------------------------------------
+
+#include "directxtexp.h"
+
+using Microsoft::WRL::ComPtr;
+
+namespace DirectX
+{
+
+//-------------------------------------------------------------------------------------
+// Do flip/rotate operation using WIC
+//-------------------------------------------------------------------------------------
+static HRESULT _PerformFlipRotateUsingWIC( _In_ const Image& srcImage, _In_ DWORD flags,
+                                           _In_ const WICPixelFormatGUID& pfGUID, _In_ const Image& destImage )
+{
+    if ( !srcImage.pixels || !destImage.pixels )
+        return E_POINTER;
+
+    assert( srcImage.format == destImage.format );
+
+    IWICImagingFactory* pWIC = _GetWIC();
+    if ( !pWIC )
+        return E_NOINTERFACE;
+
+    ComPtr<IWICBitmap> source;
+    HRESULT hr = pWIC->CreateBitmapFromMemory( static_cast<UINT>( srcImage.width ), static_cast<UINT>( srcImage.height ), pfGUID,
+                                               static_cast<UINT>( srcImage.rowPitch ), static_cast<UINT>( srcImage.slicePitch ),
+                                               srcImage.pixels, source.GetAddressOf() );
+    if ( FAILED(hr) )
+        return hr;
+
+    ComPtr<IWICBitmapFlipRotator> FR;
+    hr = pWIC->CreateBitmapFlipRotator( FR.GetAddressOf() );
+    if ( FAILED(hr) )
+        return hr;
+
+    hr = FR->Initialize( source.Get(), static_cast<WICBitmapTransformOptions>( flags ) );
+    if ( FAILED(hr) )
+        return hr;
+
+    WICPixelFormatGUID pfFR;
+    hr = FR->GetPixelFormat( &pfFR );
+    if ( FAILED(hr) )
+        return hr;
+
+    if ( memcmp( &pfFR, &pfGUID, sizeof(GUID) ) != 0 )
+    {
+        // Flip/rotate should return the same format as the source...
+        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+    }
+
+    UINT nwidth, nheight;
+    hr = FR->GetSize( &nwidth, &nheight );
+    if ( FAILED(hr) )
+        return hr;
+
+    if ( destImage.width != nwidth || destImage.height != nheight )
+        return E_FAIL;
+
+    hr = FR->CopyPixels( 0, static_cast<UINT>( destImage.rowPitch ), static_cast<UINT>( destImage.slicePitch ), destImage.pixels );
+    if ( FAILED(hr) )
+        return hr;
+
+    return S_OK;
+}
+
+
+//-------------------------------------------------------------------------------------
+// Do conversion, flip/rotate using WIC, conversion cycle
+//-------------------------------------------------------------------------------------
+static HRESULT _PerformFlipRotateViaF32( _In_ const Image& srcImage, _In_ DWORD flags, _In_ const Image& destImage )
+{
+    if ( !srcImage.pixels || !destImage.pixels )
+        return E_POINTER;
+
+    assert( srcImage.format != DXGI_FORMAT_R32G32B32A32_FLOAT );
+    assert( srcImage.format == destImage.format );
+
+    ScratchImage temp;
+    HRESULT hr = _ConvertToR32G32B32A32( srcImage, temp );
+    if ( FAILED(hr) )
+        return hr;
+
+    const Image *tsrc = temp.GetImage( 0, 0, 0 );
+    if ( !tsrc )
+        return E_POINTER;
+
+    ScratchImage rtemp;
+    hr = rtemp.Initialize2D( DXGI_FORMAT_R32G32B32A32_FLOAT, destImage.width, destImage.height, 1, 1 );
+    if ( FAILED(hr) )
+        return hr;
+
+    const Image *tdest = rtemp.GetImage( 0, 0, 0 );
+    if ( !tdest )
+        return E_POINTER;
+
+    hr = _PerformFlipRotateUsingWIC( *tsrc, flags, GUID_WICPixelFormat128bppRGBAFloat, *tdest );
+    if ( FAILED(hr) )
+        return hr;
+
+    temp.Release();
+
+    hr = _ConvertFromR32G32B32A32( *tdest, destImage );
+    if ( FAILED(hr) )
+        return hr;
+
+    return S_OK;
+}
+
+
+//=====================================================================================
+// Entry-points
+//=====================================================================================
+
+//-------------------------------------------------------------------------------------
+// Flip/rotate image
+//-------------------------------------------------------------------------------------
+_Use_decl_annotations_
+HRESULT FlipRotate( const Image& srcImage, DWORD flags, ScratchImage& image )
+{
+    if ( !srcImage.pixels )
+        return E_POINTER;
+
+    if ( !flags )
+        return E_INVALIDARG;
+
+#ifdef _M_X64
+    if ( (srcImage.width > 0xFFFFFFFF) || (srcImage.height > 0xFFFFFFFF) )
+        return E_INVALIDARG;
+#endif
+
+    if ( IsCompressed( srcImage.format ) )
+    {
+        // We don't support flip/rotate operations on compressed images
+        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+    }
+
+    static_assert( TEX_FR_ROTATE0 == WICBitmapTransformRotate0, "TEX_FR_ROTATE0 no longer matches WIC" );
+    static_assert( TEX_FR_ROTATE90 == WICBitmapTransformRotate90, "TEX_FR_ROTATE90 no longer matches WIC" );
+    static_assert( TEX_FR_ROTATE180 == WICBitmapTransformRotate180, "TEX_FR_ROTATE180 no longer matches WIC" );
+    static_assert( TEX_FR_ROTATE270 == WICBitmapTransformRotate270, "TEX_FR_ROTATE270 no longer matches WIC" );
+    static_assert( TEX_FR_FLIP_HORIZONTAL == WICBitmapTransformFlipHorizontal, "TEX_FR_FLIP_HORIZONTAL no longer matches WIC" );
+    static_assert( TEX_FR_FLIP_VERTICAL == WICBitmapTransformFlipVertical, "TEX_FR_FLIP_VERTICAL no longer matches WIC" );
+
+    // Only supports 90, 180, 270, or no rotation flags... not a combination of rotation flags
+    switch ( flags & (TEX_FR_ROTATE90|TEX_FR_ROTATE180|TEX_FR_ROTATE270) )
+    {
+    case 0:
+    case TEX_FR_ROTATE90:
+    case TEX_FR_ROTATE180:
+    case TEX_FR_ROTATE270:
+        break;
+
+    default:
+        return E_INVALIDARG;
+    }
+
+    size_t nwidth = srcImage.width;
+    size_t nheight = srcImage.height;
+
+    if (flags & (TEX_FR_ROTATE90|TEX_FR_ROTATE270))
+    {
+        nwidth = srcImage.height;
+        nheight = srcImage.width;
+    }
+
+    HRESULT hr = image.Initialize2D( srcImage.format, nwidth, nheight, 1, 1 );
+    if ( FAILED(hr) )
+        return hr;
+   
+    const Image *rimage = image.GetImage( 0, 0, 0 );
+    if ( !rimage )
+        return E_POINTER;
+
+    WICPixelFormatGUID pfGUID;
+    if ( _DXGIToWIC( srcImage.format, pfGUID ) )
+    {
+        // Case 1: Source format is supported by Windows Imaging Component
+        hr = _PerformFlipRotateUsingWIC( srcImage, flags, pfGUID, *rimage );
+    }
+    else
+    {
+        // Case 2: Source format is not supported by WIC, so we have to convert, flip/rotate, and convert back
+        hr = _PerformFlipRotateViaF32( srcImage, flags, *rimage );
+    }
+
+    if ( FAILED(hr) )
+    {
+        image.Release();
+        return hr;
+    }
+
+    return S_OK;
+}
+
+
+//-------------------------------------------------------------------------------------
+// Flip/rotate image (complex)
+//-------------------------------------------------------------------------------------
+_Use_decl_annotations_
+HRESULT FlipRotate( const Image* srcImages, size_t nimages, const TexMetadata& metadata,
+                    DWORD flags, ScratchImage& result )
+{
+    if ( !srcImages || !nimages )
+        return E_INVALIDARG;
+
+    if ( IsCompressed( metadata.format ) )
+    {
+        // We don't support flip/rotate operations on compressed images
+        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+    }
+
+    static_assert( TEX_FR_ROTATE0 == WICBitmapTransformRotate0, "TEX_FR_ROTATE0 no longer matches WIC" );
+    static_assert( TEX_FR_ROTATE90 == WICBitmapTransformRotate90, "TEX_FR_ROTATE90 no longer matches WIC" );
+    static_assert( TEX_FR_ROTATE180 == WICBitmapTransformRotate180, "TEX_FR_ROTATE180 no longer matches WIC" );
+    static_assert( TEX_FR_ROTATE270 == WICBitmapTransformRotate270, "TEX_FR_ROTATE270 no longer matches WIC" );
+    static_assert( TEX_FR_FLIP_HORIZONTAL == WICBitmapTransformFlipHorizontal, "TEX_FR_FLIP_HORIZONTAL no longer matches WIC" );
+    static_assert( TEX_FR_FLIP_VERTICAL == WICBitmapTransformFlipVertical, "TEX_FR_FLIP_VERTICAL no longer matches WIC" );
+
+    // Only supports 90, 180, 270, or no rotation flags... not a combination of rotation flags
+    switch ( flags & (TEX_FR_ROTATE90|TEX_FR_ROTATE180|TEX_FR_ROTATE270) )
+    {
+    case 0:
+    case TEX_FR_ROTATE90:
+    case TEX_FR_ROTATE180:
+    case TEX_FR_ROTATE270:
+        break;
+
+    default:
+        return E_INVALIDARG;
+    }
+
+    TexMetadata mdata2 = metadata;
+
+    bool flipwh = false;
+    if (flags & (TEX_FR_ROTATE90|TEX_FR_ROTATE270))
+    {
+        flipwh = true;
+        mdata2.width = metadata.height;
+        mdata2.height = metadata.width;
+    }
+
+    HRESULT hr = result.Initialize( mdata2 );
+    if ( FAILED(hr) )
+        return hr;
+
+    if ( nimages != result.GetImageCount() )
+    {
+        result.Release();
+        return E_FAIL;
+    }
+
+    const Image* dest = result.GetImages();
+    if ( !dest )
+    {
+        result.Release();
+        return E_POINTER;
+    }
+
+    WICPixelFormatGUID pfGUID;
+    bool wicpf = _DXGIToWIC( metadata.format, pfGUID );
+
+    for( size_t index=0; index < nimages; ++index )
+    {
+        const Image& src = srcImages[ index ];
+        if ( src.format != metadata.format )
+        {
+            result.Release();
+            return E_FAIL;
+        }
+
+#ifdef _M_X64
+        if ( (src.width > 0xFFFFFFFF) || (src.height > 0xFFFFFFFF) )
+            return E_FAIL;
+#endif
+
+        const Image& dst = dest[ index ];
+        assert( dst.format == metadata.format );
+
+        if ( flipwh )
+        {
+            if ( src.width != dst.height || src.height != dst.width )
+            {
+                result.Release();
+                return E_FAIL;
+            }
+        }
+        else
+        {
+            if ( src.width != dst.width || src.height != dst.height )
+            {
+                result.Release();
+                return E_FAIL;
+            }
+        }
+
+        if (wicpf)
+        {
+            // Case 1: Source format is supported by Windows Imaging Component
+            hr = _PerformFlipRotateUsingWIC( src, flags, pfGUID, dst );
+        }
+        else
+        {
+            // Case 2: Source format is not supported by WIC, so we have to convert, flip/rotate, and convert back
+            hr = _PerformFlipRotateViaF32( src, flags, dst );
+        }
+
+        if ( FAILED(hr) )
+        {
+            result.Release();
+            return hr;
+        }
+    }
+
+    return S_OK;
+}
+
+}; // namespace

+ 821 - 0
Exporters/FBX/3rdParty/DirectXTex/DirectXTexImage.cpp

@@ -0,0 +1,821 @@
+//-------------------------------------------------------------------------------------
+// DirectXTexImage.cpp
+//  
+// DirectX Texture Library - Image container
+//
+// 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=248926
+//-------------------------------------------------------------------------------------
+
+#include "directxtexp.h"
+
+namespace DirectX
+{
+
+extern bool _CalculateMipLevels( _In_ size_t width, _In_ size_t height, _Inout_ size_t& mipLevels );
+extern bool _CalculateMipLevels3D( _In_ size_t width, _In_ size_t height, _In_ size_t depth, _Inout_ size_t& mipLevels );
+extern bool _IsAlphaAllOpaqueBC( _In_ const Image& cImage );
+
+//-------------------------------------------------------------------------------------
+// Determines number of image array entries and pixel size
+//-------------------------------------------------------------------------------------
+_Use_decl_annotations_
+void _DetermineImageArray( const TexMetadata& metadata, DWORD cpFlags,
+                           size_t& nImages, size_t& pixelSize )
+{
+    assert( metadata.width > 0 && metadata.height > 0 && metadata.depth > 0 );
+    assert( metadata.arraySize > 0 );
+    assert( metadata.mipLevels > 0 );
+
+    size_t _pixelSize = 0;
+    size_t _nimages = 0;
+
+    switch( metadata.dimension )
+    {
+    case TEX_DIMENSION_TEXTURE1D:
+    case TEX_DIMENSION_TEXTURE2D:
+        for( size_t item = 0; item < metadata.arraySize; ++item )
+        {
+            size_t w = metadata.width;
+            size_t h = metadata.height;
+
+            for( size_t level=0; level < metadata.mipLevels; ++level )
+            {
+                size_t rowPitch, slicePitch;
+                ComputePitch( metadata.format, w, h, rowPitch, slicePitch, cpFlags );
+
+                _pixelSize += slicePitch;
+                ++_nimages;
+
+                if ( h > 1 )
+                    h >>= 1;
+
+                if ( w > 1 )
+                    w >>= 1;
+            }
+        }
+        break;
+
+    case TEX_DIMENSION_TEXTURE3D:
+        {
+            size_t w = metadata.width;
+            size_t h = metadata.height;
+            size_t d = metadata.depth;
+
+            for( size_t level=0; level < metadata.mipLevels; ++level )
+            {
+                size_t rowPitch, slicePitch;
+                ComputePitch( metadata.format, w, h, rowPitch, slicePitch, cpFlags );
+
+                for( size_t slice=0; slice < d; ++slice )
+                {
+                    _pixelSize += slicePitch;
+                    ++_nimages;
+                }
+
+                if ( h > 1 )
+                    h >>= 1;
+
+                if ( w > 1 )
+                    w >>= 1;
+
+                if ( d > 1 )
+                    d >>= 1;
+            }
+        }
+        break;
+
+    default:
+        assert( false );
+        break;
+    }
+
+    nImages = _nimages;
+    pixelSize = _pixelSize;
+}
+
+
+//-------------------------------------------------------------------------------------
+// Fills in the image array entries
+//-------------------------------------------------------------------------------------
+_Use_decl_annotations_
+bool _SetupImageArray( uint8_t *pMemory, size_t pixelSize,
+                       const TexMetadata& metadata, DWORD cpFlags,
+                       Image* images, size_t nImages )
+{
+    assert( pMemory );
+    assert( pixelSize > 0 );
+    assert( nImages > 0 );
+
+    if ( !images )
+        return false;
+
+    size_t index = 0;
+    uint8_t* pixels = pMemory;
+    const uint8_t* pEndBits = pMemory + pixelSize;
+
+    switch( metadata.dimension )
+    {
+    case TEX_DIMENSION_TEXTURE1D:
+    case TEX_DIMENSION_TEXTURE2D:
+        if (metadata.arraySize == 0 || metadata.mipLevels == 0)
+        {
+            return false;
+        }
+
+        for( size_t item = 0; item < metadata.arraySize; ++item )
+        {
+            size_t w = metadata.width;
+            size_t h = metadata.height;
+
+            for( size_t level=0; level < metadata.mipLevels; ++level )
+            {
+                if ( index >= nImages )
+                {
+                    return false;
+                }
+
+                size_t rowPitch, slicePitch;
+                ComputePitch( metadata.format, w, h, rowPitch, slicePitch, cpFlags );
+
+                images[index].width = w;
+                images[index].height = h;
+                images[index].format = metadata.format;
+                images[index].rowPitch = rowPitch;
+                images[index].slicePitch = slicePitch;
+                images[index].pixels = pixels;
+                ++index;
+
+                pixels += slicePitch;
+                if ( pixels > pEndBits )
+                {
+                    return false;
+                }
+            
+                if ( h > 1 )
+                    h >>= 1;
+
+                if ( w > 1 )
+                    w >>= 1;
+            }
+        }
+        return true;
+
+    case TEX_DIMENSION_TEXTURE3D:
+        {
+            if (metadata.mipLevels == 0 || metadata.depth == 0)
+            {
+                return false;
+            }
+
+            size_t w = metadata.width;
+            size_t h = metadata.height;
+            size_t d = metadata.depth;
+
+            for( size_t level=0; level < metadata.mipLevels; ++level )
+            {
+                size_t rowPitch, slicePitch;
+                ComputePitch( metadata.format, w, h, rowPitch, slicePitch, cpFlags );
+
+                for( size_t slice=0; slice < d; ++slice )
+                {
+                    if ( index >= nImages )
+                    {
+                        return false;
+                    }
+
+                    // We use the same memory organization that Direct3D 11 needs for D3D11_SUBRESOURCE_DATA
+                    // with all slices of a given miplevel being continuous in memory
+                    images[index].width = w;
+                    images[index].height = h;
+                    images[index].format = metadata.format;
+                    images[index].rowPitch = rowPitch;
+                    images[index].slicePitch = slicePitch;
+                    images[index].pixels = pixels;
+                    ++index;
+
+                    pixels += slicePitch;
+                    if ( pixels > pEndBits )
+                    {
+                        return false;
+                    }
+                }
+            
+                if ( h > 1 )
+                    h >>= 1;
+
+                if ( w > 1 )
+                    w >>= 1;
+
+                if ( d > 1 )
+                    d >>= 1;
+            }
+        }
+        return true;
+
+    default:
+        return false;
+    }
+}
+
+
+//=====================================================================================
+// ScratchImage - Bitmap image container
+//=====================================================================================
+
+ScratchImage& ScratchImage::operator= (ScratchImage&& moveFrom)
+{
+    if ( this != &moveFrom )
+    {
+        Release();
+
+        _nimages = moveFrom._nimages;
+        _size = moveFrom._size;
+        _metadata = moveFrom._metadata;
+        _image = moveFrom._image;
+        _memory = moveFrom._memory;
+
+        moveFrom._nimages = 0;
+        moveFrom._size = 0;
+        moveFrom._image = nullptr;
+        moveFrom._memory = nullptr;
+    }
+    return *this;
+}
+
+
+//-------------------------------------------------------------------------------------
+// Methods
+//-------------------------------------------------------------------------------------
+_Use_decl_annotations_
+HRESULT ScratchImage::Initialize( const TexMetadata& mdata, DWORD flags )
+{
+    if ( !IsValid(mdata.format) )
+        return E_INVALIDARG;
+
+    if ( IsPalettized(mdata.format) )
+        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+
+    size_t mipLevels = mdata.mipLevels;
+
+    switch( mdata.dimension )
+    {
+    case TEX_DIMENSION_TEXTURE1D:
+        if ( !mdata.width || mdata.height != 1 || mdata.depth != 1 || !mdata.arraySize )
+            return E_INVALIDARG;
+
+        if ( IsVideo(mdata.format) )
+            return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+
+        if ( !_CalculateMipLevels(mdata.width,1,mipLevels) )
+            return E_INVALIDARG;
+        break;
+
+    case TEX_DIMENSION_TEXTURE2D:
+        if ( !mdata.width || !mdata.height || mdata.depth != 1 || !mdata.arraySize )
+            return E_INVALIDARG;
+
+        if ( mdata.IsCubemap() )
+        {
+            if ( (mdata.arraySize % 6) != 0 )
+                return E_INVALIDARG;
+
+            if ( IsVideo(mdata.format) )
+                return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+        }
+
+        if ( !_CalculateMipLevels(mdata.width,mdata.height,mipLevels) )
+            return E_INVALIDARG;
+        break;
+
+    case TEX_DIMENSION_TEXTURE3D:
+        if ( !mdata.width || !mdata.height || !mdata.depth || mdata.arraySize != 1 )
+            return E_INVALIDARG;
+        
+        if ( IsVideo(mdata.format) || IsPlanar(mdata.format) || IsDepthStencil(mdata.format) )
+            return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+
+        if ( !_CalculateMipLevels3D(mdata.width,mdata.height,mdata.depth,mipLevels) )
+            return E_INVALIDARG;
+        break;
+
+    default:
+        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+    }
+
+    Release();
+
+    _metadata.width = mdata.width;
+    _metadata.height = mdata.height;
+    _metadata.depth = mdata.depth;
+    _metadata.arraySize = mdata.arraySize;
+    _metadata.mipLevels = mipLevels;
+    _metadata.miscFlags = mdata.miscFlags;
+    _metadata.miscFlags2 = mdata.miscFlags2;
+    _metadata.format = mdata.format;
+    _metadata.dimension = mdata.dimension;
+
+    size_t pixelSize, nimages;
+    _DetermineImageArray( _metadata, flags, nimages, pixelSize );
+
+    _image = new (std::nothrow) Image[ nimages ];
+    if ( !_image )
+        return E_OUTOFMEMORY;
+
+    _nimages = nimages;
+    memset( _image, 0, sizeof(Image) * nimages );
+
+    _memory = reinterpret_cast<uint8_t*>( _aligned_malloc( pixelSize, 16 ) );
+    if ( !_memory )
+    {
+        Release();
+        return E_OUTOFMEMORY;
+    }
+    _size = pixelSize;
+    if ( !_SetupImageArray( _memory, pixelSize, _metadata, flags, _image, nimages ) )
+    {
+        Release();
+        return E_FAIL;
+    }
+
+    return S_OK;
+}
+
+_Use_decl_annotations_
+HRESULT ScratchImage::Initialize1D( DXGI_FORMAT fmt, size_t length, size_t arraySize, size_t mipLevels, DWORD flags )
+{
+    if ( !length || !arraySize )
+        return E_INVALIDARG;
+
+    if ( IsVideo(fmt) )
+        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+
+    // 1D is a special case of the 2D case
+    HRESULT hr = Initialize2D( fmt, length, 1, arraySize, mipLevels, flags );
+    if ( FAILED(hr) )
+        return hr;
+
+    _metadata.dimension = TEX_DIMENSION_TEXTURE1D;
+
+    return S_OK;
+}
+
+_Use_decl_annotations_
+HRESULT ScratchImage::Initialize2D( DXGI_FORMAT fmt, size_t width, size_t height, size_t arraySize, size_t mipLevels, DWORD flags )
+{
+    if ( !IsValid(fmt) || !width || !height || !arraySize )
+        return E_INVALIDARG;
+
+    if ( IsPalettized(fmt) )
+        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+
+    if ( !_CalculateMipLevels(width,height,mipLevels) )
+        return E_INVALIDARG;
+
+    Release();
+
+    _metadata.width = width;
+    _metadata.height = height;
+    _metadata.depth = 1;
+    _metadata.arraySize = arraySize;
+    _metadata.mipLevels = mipLevels;
+    _metadata.miscFlags = 0;
+    _metadata.miscFlags2 = 0;
+    _metadata.format = fmt;
+    _metadata.dimension = TEX_DIMENSION_TEXTURE2D;
+
+    size_t pixelSize, nimages;
+    _DetermineImageArray( _metadata, flags, nimages, pixelSize );
+
+    _image = new (std::nothrow) Image[ nimages ];
+    if ( !_image )
+        return E_OUTOFMEMORY;
+
+    _nimages = nimages;
+    memset( _image, 0, sizeof(Image) * nimages );
+
+    _memory = reinterpret_cast<uint8_t*>( _aligned_malloc( pixelSize, 16 ) );
+    if ( !_memory )
+    {
+        Release();
+        return E_OUTOFMEMORY;
+    }
+    _size = pixelSize;
+    if ( !_SetupImageArray( _memory, pixelSize, _metadata, flags, _image, nimages ) )
+    {
+        Release();
+        return E_FAIL;
+    }
+
+    return S_OK;
+}
+
+_Use_decl_annotations_
+HRESULT ScratchImage::Initialize3D( DXGI_FORMAT fmt, size_t width, size_t height, size_t depth, size_t mipLevels, DWORD flags )
+{
+    if ( !IsValid(fmt) || !width || !height || !depth )
+        return E_INVALIDARG;
+
+    if ( IsVideo(fmt) || IsPlanar(fmt) || IsDepthStencil(fmt) )
+        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+
+    if ( !_CalculateMipLevels3D(width,height,depth,mipLevels) )
+        return E_INVALIDARG;
+
+    Release();
+
+    _metadata.width = width;
+    _metadata.height = height;
+    _metadata.depth = depth;
+    _metadata.arraySize = 1;    // Direct3D 10.x/11 does not support arrays of 3D textures
+    _metadata.mipLevels = mipLevels;
+    _metadata.miscFlags = 0;
+    _metadata.miscFlags2 = 0;
+    _metadata.format = fmt;
+    _metadata.dimension = TEX_DIMENSION_TEXTURE3D;
+
+    size_t pixelSize, nimages;
+    _DetermineImageArray( _metadata, flags, nimages, pixelSize );
+
+    _image = new (std::nothrow) Image[ nimages ];
+    if ( !_image )
+    {
+        Release();
+        return E_OUTOFMEMORY;
+    }
+    _nimages = nimages;
+    memset( _image, 0, sizeof(Image) * nimages );
+
+    _memory = reinterpret_cast<uint8_t*>( _aligned_malloc( pixelSize, 16 ) );
+    if ( !_memory )
+    {
+        Release();
+        return E_OUTOFMEMORY;
+    }
+    _size = pixelSize;
+
+    if ( !_SetupImageArray( _memory, pixelSize, _metadata, flags, _image, nimages ) )
+    {
+        Release();
+        return E_FAIL;
+    }
+
+    return S_OK;
+}
+
+_Use_decl_annotations_
+HRESULT ScratchImage::InitializeCube( DXGI_FORMAT fmt, size_t width, size_t height, size_t nCubes, size_t mipLevels, DWORD flags )
+{
+    if ( !width || !height || !nCubes )
+        return E_INVALIDARG;
+
+    if ( IsVideo(fmt) )
+        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+    
+    // A DirectX11 cubemap is just a 2D texture array that is a multiple of 6 for each cube
+    HRESULT hr = Initialize2D( fmt, width, height, nCubes * 6, mipLevels, flags );
+    if ( FAILED(hr) )
+        return hr;
+
+    _metadata.miscFlags |= TEX_MISC_TEXTURECUBE;
+
+    return S_OK;
+}
+
+_Use_decl_annotations_
+HRESULT ScratchImage::InitializeFromImage( const Image& srcImage, bool allow1D, DWORD flags )
+{
+    HRESULT hr = ( srcImage.height > 1 || !allow1D )
+                 ? Initialize2D( srcImage.format, srcImage.width, srcImage.height, 1, 1, flags )
+                 : Initialize1D( srcImage.format, srcImage.width, 1, 1, flags );
+
+    if ( FAILED(hr) )
+        return hr;
+
+    size_t rowCount = ComputeScanlines( srcImage.format, srcImage.height );
+    if ( !rowCount )
+        return E_UNEXPECTED;
+
+    const uint8_t* sptr = reinterpret_cast<const uint8_t*>( srcImage.pixels );
+    if ( !sptr )
+        return E_POINTER;
+
+    auto dptr = reinterpret_cast<uint8_t*>( _image[0].pixels );
+    if ( !dptr )
+        return E_POINTER;
+
+    size_t spitch = srcImage.rowPitch;
+    size_t dpitch = _image[0].rowPitch;
+
+    size_t size = std::min<size_t>( dpitch, spitch );
+
+    for( size_t y = 0; y < rowCount; ++y )
+    {
+        memcpy_s( dptr, dpitch, sptr, size );
+        sptr += spitch;
+        dptr += dpitch;
+    }
+
+    return S_OK;
+}
+
+_Use_decl_annotations_
+HRESULT ScratchImage::InitializeArrayFromImages( const Image* images, size_t nImages, bool allow1D, DWORD flags )
+{
+    if ( !images || !nImages )
+        return E_INVALIDARG;
+
+    DXGI_FORMAT format = images[0].format;
+    size_t width = images[0].width;
+    size_t height = images[0].height;
+
+    for( size_t index=0; index < nImages; ++index )
+    {
+        if ( !images[index].pixels )
+            return E_POINTER;
+
+        if ( images[index].format != format || images[index].width != width || images[index].height != height )
+        {
+            // All images must be the same format, width, and height
+            return E_FAIL;
+        }
+    }
+
+    HRESULT hr = ( height > 1 || !allow1D )
+                 ? Initialize2D( format, width, height, nImages, 1, flags )
+                 : Initialize1D( format, width, nImages, 1, flags );
+
+    if ( FAILED(hr) )
+        return hr;
+
+    size_t rowCount = ComputeScanlines( format, height );
+    if ( !rowCount )
+        return E_UNEXPECTED;
+
+    for( size_t index=0; index < nImages; ++index )
+    {
+        auto sptr = reinterpret_cast<const uint8_t*>( images[index].pixels );
+        if ( !sptr )
+            return E_POINTER;
+
+        assert( index < _nimages );
+        auto dptr = reinterpret_cast<uint8_t*>( _image[index].pixels );
+        if ( !dptr )
+            return E_POINTER;
+
+        size_t spitch = images[index].rowPitch;
+        size_t dpitch = _image[index].rowPitch;
+
+        size_t size = std::min<size_t>( dpitch, spitch );
+
+        for( size_t y = 0; y < rowCount; ++y )
+        {
+            memcpy_s( dptr, dpitch, sptr, size );
+            sptr += spitch;
+            dptr += dpitch;
+        }
+    }
+
+    return S_OK;
+}
+
+_Use_decl_annotations_
+HRESULT ScratchImage::InitializeCubeFromImages( const Image* images, size_t nImages, DWORD flags )
+{
+    if ( !images || !nImages )
+        return E_INVALIDARG;
+
+    // A DirectX11 cubemap is just a 2D texture array that is a multiple of 6 for each cube
+    if ( ( nImages % 6 ) != 0 )
+        return E_INVALIDARG;
+
+    if ( IsVideo(images[0].format) || IsPalettized(images[0].format) )
+        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+
+    HRESULT hr = InitializeArrayFromImages( images, nImages, false, flags );
+    if ( FAILED(hr) )
+        return hr;
+
+    _metadata.miscFlags |= TEX_MISC_TEXTURECUBE;
+
+    return S_OK;
+}
+
+_Use_decl_annotations_
+HRESULT ScratchImage::Initialize3DFromImages( const Image* images, size_t depth, DWORD flags )
+{
+    if ( !images || !depth )
+        return E_INVALIDARG;
+
+    DXGI_FORMAT format = images[0].format;
+    size_t width = images[0].width;
+    size_t height = images[0].height;
+
+    for( size_t slice=0; slice < depth; ++slice )
+    {
+        if ( !images[slice].pixels )
+            return E_POINTER;
+
+        if ( images[slice].format != format || images[slice].width != width || images[slice].height != height )
+        {
+            // All images must be the same format, width, and height
+            return E_FAIL;
+        }
+    }
+
+    HRESULT hr = Initialize3D( format, width, height, depth, 1, flags );
+    if ( FAILED(hr) )
+        return hr;
+
+    size_t rowCount = ComputeScanlines( format, height );
+    if ( !rowCount )
+        return E_UNEXPECTED;
+
+    for( size_t slice=0; slice < depth; ++slice )
+    {
+        auto sptr = reinterpret_cast<const uint8_t*>( images[slice].pixels );
+        if ( !sptr )
+            return E_POINTER;
+
+        assert( slice < _nimages );
+        auto dptr = reinterpret_cast<uint8_t*>( _image[slice].pixels );
+        if ( !dptr )
+            return E_POINTER;
+
+        size_t spitch = images[slice].rowPitch;
+        size_t dpitch = _image[slice].rowPitch;
+
+        size_t size = std::min<size_t>( dpitch, spitch );
+
+        for( size_t y = 0; y < rowCount; ++y )
+        {
+            memcpy_s( dptr, dpitch, sptr, size );
+            sptr += spitch;
+            dptr += dpitch;
+        }
+    }
+
+    return S_OK;
+}
+
+void ScratchImage::Release()
+{
+    _nimages = 0;
+    _size = 0;
+
+    if ( _image )
+    {
+        delete [] _image;
+        _image = 0;
+    }
+
+    if ( _memory )
+    {
+        _aligned_free( _memory );
+        _memory = 0;
+    }
+    
+    memset(&_metadata, 0, sizeof(_metadata));
+}
+
+_Use_decl_annotations_
+bool ScratchImage::OverrideFormat( DXGI_FORMAT f )
+{
+    if ( !_image )
+        return false;
+
+    if ( !IsValid( f ) || IsPlanar( f ) || IsPalettized( f ) )
+        return false;
+
+    if ( ( BitsPerPixel( f ) != BitsPerPixel( _metadata.format ) )
+         || ( IsCompressed( f ) != IsCompressed( _metadata.format ) )
+         || ( IsPacked( f ) != IsPacked( _metadata.format ) )
+         || ( IsVideo( f ) != IsVideo( _metadata.format ) ) )
+    {
+         // Can't change the effective pitch of the format this way
+         return false;
+    }
+
+    for( size_t index = 0; index < _nimages; ++index )
+    {
+        _image[ index ].format = f;
+    }
+
+    _metadata.format = f;
+
+    return true;
+}
+
+_Use_decl_annotations_
+const Image* ScratchImage::GetImage(size_t mip, size_t item, size_t slice) const
+{
+    if ( mip >= _metadata.mipLevels )
+        return nullptr;
+
+    size_t index = 0;
+
+    switch( _metadata.dimension )
+    {
+    case TEX_DIMENSION_TEXTURE1D:
+    case TEX_DIMENSION_TEXTURE2D:
+        if ( slice > 0 )
+            return nullptr;
+
+        if ( item >= _metadata.arraySize )
+            return nullptr;
+
+        index = item*( _metadata.mipLevels ) + mip;
+        break;
+
+    case TEX_DIMENSION_TEXTURE3D:
+        if ( item > 0 )
+        {
+            // No support for arrays of volumes
+            return nullptr;
+        }
+        else
+        {
+            size_t d = _metadata.depth;
+
+            for( size_t level = 0; level < mip; ++level )
+            {
+                index += d;
+                if ( d > 1 )
+                    d >>= 1;
+            }
+
+            if ( slice >= d )
+                return nullptr;
+
+            index += slice;
+        }
+        break;
+
+    default:
+        return nullptr;
+    }
+ 
+    return &_image[index];
+}
+
+bool ScratchImage::IsAlphaAllOpaque() const
+{
+    if ( !_image )
+        return false;
+
+    if ( !HasAlpha( _metadata.format ) )
+        return true;
+
+    if ( IsCompressed( _metadata.format ) )
+    {
+        for( size_t index = 0; index < _nimages; ++index )
+        {
+            if ( !_IsAlphaAllOpaqueBC( _image[ index ] ) )
+                return false;
+        }
+    }
+    else
+    {
+        ScopedAlignedArrayXMVECTOR scanline( reinterpret_cast<XMVECTOR*>( _aligned_malloc( (sizeof(XMVECTOR)*_metadata.width), 16 ) ) );
+        if ( !scanline )
+            return false;
+
+        static const XMVECTORF32 threshold = { 0.99f, 0.99f, 0.99f, 0.99f };
+
+        for( size_t index = 0; index < _nimages; ++index )
+        {
+#pragma warning( suppress : 6011 )
+            const Image& img = _image[ index ];
+
+            const uint8_t *pPixels = img.pixels;
+            assert( pPixels );
+
+            for( size_t h = 0; h < img.height; ++h )
+            {
+                if ( !_LoadScanline( scanline.get(), img.width, pPixels, img.rowPitch, img.format ) )
+                    return false;
+
+                XMVECTOR* ptr = scanline.get();
+                for( size_t w = 0; w < img.width; ++w )
+                {
+                    XMVECTOR alpha = XMVectorSplatW( *ptr );
+                    if ( XMVector4Less( alpha, threshold ) )
+                        return false;
+                    ++ptr;
+                }
+
+                pPixels += img.rowPitch;
+            }
+        }
+    }
+
+    return true;
+}
+
+}; // namespace

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 3051 - 0
Exporters/FBX/3rdParty/DirectXTex/DirectXTexMipmaps.cpp


+ 354 - 0
Exporters/FBX/3rdParty/DirectXTex/DirectXTexMisc.cpp

@@ -0,0 +1,354 @@
+//-------------------------------------------------------------------------------------
+// DirectXTexMisc.cpp
+//  
+// DirectX Texture Library - Misc image operations
+//
+// 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=248926
+//-------------------------------------------------------------------------------------
+
+#include "directxtexp.h"
+
+namespace DirectX
+{
+static const XMVECTORF32 g_Gamma22 = { 2.2f, 2.2f, 2.2f, 1.f };
+
+//-------------------------------------------------------------------------------------
+static HRESULT _ComputeMSE( _In_ const Image& image1, _In_ const Image& image2,
+                            _Out_ float& mse, _Out_writes_opt_(4) float* mseV,
+                            _In_ DWORD flags )
+{
+    if ( !image1.pixels || !image2.pixels )
+        return E_POINTER;
+
+    assert( image1.width == image2.width && image1.height == image2.height );
+    assert( !IsCompressed( image1.format ) && !IsCompressed( image2.format )  );
+
+    const size_t width = image1.width;
+
+    ScopedAlignedArrayXMVECTOR scanline( reinterpret_cast<XMVECTOR*>( _aligned_malloc( (sizeof(XMVECTOR)*width)*2, 16 ) ) );
+    if ( !scanline )
+        return E_OUTOFMEMORY;
+
+    // Flags implied from image formats
+    switch( image1.format )
+    {
+    case DXGI_FORMAT_B8G8R8X8_UNORM:
+        flags |= CMSE_IGNORE_ALPHA;
+        break;
+
+    case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
+        flags |= CMSE_IMAGE1_SRGB | CMSE_IGNORE_ALPHA;
+        break;
+
+    case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
+    case DXGI_FORMAT_BC1_UNORM_SRGB:
+    case DXGI_FORMAT_BC2_UNORM_SRGB:
+    case DXGI_FORMAT_BC3_UNORM_SRGB:
+    case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
+    case DXGI_FORMAT_BC7_UNORM_SRGB:
+        flags |= CMSE_IMAGE1_SRGB;
+        break;
+    }
+
+    switch( image2.format )
+    {
+    case DXGI_FORMAT_B8G8R8X8_UNORM:
+        flags |= CMSE_IGNORE_ALPHA;
+        break;
+
+    case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
+        flags |= CMSE_IMAGE2_SRGB | CMSE_IGNORE_ALPHA;
+        break;
+
+    case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
+    case DXGI_FORMAT_BC1_UNORM_SRGB:
+    case DXGI_FORMAT_BC2_UNORM_SRGB:
+    case DXGI_FORMAT_BC3_UNORM_SRGB:
+    case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
+    case DXGI_FORMAT_BC7_UNORM_SRGB:
+        flags |= CMSE_IMAGE2_SRGB;
+        break;
+    }
+
+    const uint8_t *pSrc1 = image1.pixels;
+    const size_t rowPitch1 = image1.rowPitch;
+
+    const uint8_t *pSrc2 = image2.pixels;
+    const size_t rowPitch2 = image2.rowPitch;
+
+    XMVECTOR acc = g_XMZero;
+    static XMVECTORF32 two = { 2.0f, 2.0f, 2.0f, 2.0f };
+
+    for( size_t h = 0; h < image1.height; ++h )
+    {
+        XMVECTOR* ptr1 = scanline.get();
+        if ( !_LoadScanline( ptr1, width, pSrc1, rowPitch1, image1.format ) )
+            return E_FAIL;
+
+        XMVECTOR* ptr2 = scanline.get() + width;
+        if ( !_LoadScanline( ptr2, width, pSrc2, rowPitch2, image2.format ) )
+            return E_FAIL;
+
+        for( size_t i = 0; i < width; ++i )
+        {
+            XMVECTOR v1 = *(ptr1++);
+            if ( flags & CMSE_IMAGE1_SRGB )
+            {
+                v1 = XMVectorPow( v1, g_Gamma22 );
+            }
+            if ( flags & CMSE_IMAGE1_X2_BIAS )
+            {
+                v1 = XMVectorMultiplyAdd( v1, two, g_XMNegativeOne );
+            }
+
+            XMVECTOR v2 = *(ptr2++);
+            if ( flags & CMSE_IMAGE2_SRGB )
+            {
+                v2 = XMVectorPow( v2, g_Gamma22 );
+            }
+            if ( flags & CMSE_IMAGE2_X2_BIAS )
+            {
+                v1 = XMVectorMultiplyAdd( v2, two, g_XMNegativeOne );
+            }
+
+            // sum[ (I1 - I2)^2 ]
+            XMVECTOR v = XMVectorSubtract( v1, v2 );
+            if ( flags & CMSE_IGNORE_RED )
+            {
+                v = XMVectorSelect( v, g_XMZero, g_XMMaskX );
+            }
+            if ( flags & CMSE_IGNORE_GREEN )
+            {
+                v = XMVectorSelect( v, g_XMZero, g_XMMaskY );
+            }
+            if ( flags & CMSE_IGNORE_BLUE )
+            {
+                v = XMVectorSelect( v, g_XMZero, g_XMMaskZ );
+            }
+            if ( flags & CMSE_IGNORE_ALPHA )
+            {
+                v = XMVectorSelect( v, g_XMZero, g_XMMaskW );
+            }
+
+            acc = XMVectorMultiplyAdd( v, v, acc );
+        }
+
+        pSrc1 += rowPitch1;
+        pSrc2 += rowPitch2;
+    }
+
+    // MSE = sum[ (I1 - I2)^2 ] / w*h
+    XMVECTOR d = XMVectorReplicate( float(image1.width * image1.height) );
+    XMVECTOR v = XMVectorDivide( acc, d );
+    if ( mseV )
+    {
+        XMStoreFloat4( reinterpret_cast<XMFLOAT4*>( mseV ), v );
+        mse = mseV[0] + mseV[1] + mseV[2] + mseV[3];
+    }
+    else
+    {
+        XMFLOAT4 _mseV;
+        XMStoreFloat4( &_mseV, v );
+        mse = _mseV.x + _mseV.y + _mseV.z + _mseV.w;
+    }
+
+    return S_OK; 
+}
+
+
+//=====================================================================================
+// Entry points
+//=====================================================================================
+        
+//-------------------------------------------------------------------------------------
+// Copies a rectangle from one image into another
+//-------------------------------------------------------------------------------------
+_Use_decl_annotations_
+HRESULT CopyRectangle( const Image& srcImage, const Rect& srcRect, const Image& dstImage, DWORD filter, size_t xOffset, size_t yOffset )
+{
+    if ( !srcImage.pixels || !dstImage.pixels )
+        return E_POINTER;
+
+    if ( IsCompressed( srcImage.format ) || IsCompressed( dstImage.format )
+         || IsPlanar( srcImage.format ) || IsPlanar( dstImage.format )
+         || IsPalettized( srcImage.format ) || IsPalettized( dstImage.format ) )
+        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+
+    // Validate rectangle/offset
+    if ( !srcRect.w || !srcRect.h || ( (srcRect.x + srcRect.w) > srcImage.width ) || ( (srcRect.y + srcRect.h) > srcImage.height ) )
+    {
+        return E_INVALIDARG;
+    }
+
+    if ( ( (xOffset + srcRect.w) > dstImage.width ) || ( (yOffset + srcRect.h) > dstImage.height ) )
+    {
+        return E_INVALIDARG;
+    }
+
+    // Compute source bytes-per-pixel
+    size_t sbpp = BitsPerPixel( srcImage.format );
+    if ( !sbpp )
+        return E_FAIL;
+
+    if ( sbpp < 8 )
+    {
+        // We don't support monochrome (DXGI_FORMAT_R1_UNORM)
+        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+    }
+
+    const uint8_t* pEndSrc = srcImage.pixels + srcImage.rowPitch*srcImage.height;
+    const uint8_t* pEndDest = dstImage.pixels + dstImage.rowPitch*dstImage.height;
+
+    // Round to bytes
+    sbpp = ( sbpp + 7 ) / 8;
+
+    const uint8_t* pSrc = srcImage.pixels + (srcRect.y * srcImage.rowPitch) + (srcRect.x * sbpp);
+
+    if ( srcImage.format == dstImage.format )
+    {
+        // Direct copy case (avoid intermediate conversions)
+        uint8_t* pDest = dstImage.pixels + (yOffset * dstImage.rowPitch) + (xOffset * sbpp);
+        const size_t copyW = srcRect.w * sbpp;
+        for( size_t h=0; h < srcRect.h; ++h )
+        {
+            if ( ( (pSrc+copyW) > pEndSrc ) || (pDest > pEndDest) )
+                return E_FAIL;
+
+            memcpy_s( pDest, pEndDest - pDest, pSrc, copyW );
+
+            pSrc += srcImage.rowPitch;
+            pDest += dstImage.rowPitch;
+        }
+
+        return S_OK;
+    }
+
+    // Compute destination bytes-per-pixel (not the same format as source)
+    size_t dbpp = BitsPerPixel( dstImage.format );
+    if ( !dbpp )
+        return E_FAIL;
+
+    if ( dbpp < 8 )
+    {
+        // We don't support monochrome (DXGI_FORMAT_R1_UNORM)
+        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+    }
+
+    // Round to bytes
+    dbpp = ( dbpp + 7 ) / 8;
+
+    uint8_t* pDest = dstImage.pixels + (yOffset * dstImage.rowPitch) + (xOffset * dbpp);
+
+    ScopedAlignedArrayXMVECTOR scanline( reinterpret_cast<XMVECTOR*>( _aligned_malloc( (sizeof(XMVECTOR)*srcRect.w), 16 ) ) );
+    if ( !scanline )
+        return E_OUTOFMEMORY;
+
+    const size_t copyS = srcRect.w * sbpp;
+    const size_t copyD = srcRect.w * dbpp;
+
+    for( size_t h=0; h < srcRect.h; ++h )
+    {
+        if ( ( (pSrc+copyS) > pEndSrc) || ((pDest+copyD) > pEndDest) )
+            return E_FAIL;
+
+        if ( !_LoadScanline( scanline.get(), srcRect.w, pSrc, copyS, srcImage.format ) )
+            return E_FAIL;
+
+        _ConvertScanline( scanline.get(), srcRect.w, dstImage.format, srcImage.format, filter );
+
+        if ( !_StoreScanline( pDest, copyD, dstImage.format, scanline.get(), srcRect.w ) )
+            return E_FAIL;
+
+        pSrc += srcImage.rowPitch;
+        pDest += dstImage.rowPitch;
+    }
+
+    return S_OK;
+}
+
+    
+//-------------------------------------------------------------------------------------
+// Computes the Mean-Squared-Error (MSE) between two images
+//-------------------------------------------------------------------------------------
+_Use_decl_annotations_
+HRESULT ComputeMSE( const Image& image1, const Image& image2, float& mse, float* mseV, DWORD flags )
+{
+    if ( !image1.pixels || !image2.pixels )
+        return E_POINTER;
+
+    if ( image1.width != image2.width || image1.height != image2.height )
+        return E_INVALIDARG;
+
+    if ( IsPlanar( image1.format ) || IsPlanar( image2.format )
+         || IsPalettized( image1.format ) || IsPalettized( image2.format ) )
+        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+
+    if ( IsCompressed(image1.format) )
+    {
+        if ( IsCompressed(image2.format) )
+        {
+            // Case 1: both images are compressed, expand to RGBA32F
+            ScratchImage temp1;
+            HRESULT hr = Decompress( image1, DXGI_FORMAT_R32G32B32A32_FLOAT, temp1 );
+            if ( FAILED(hr) )
+                return hr;
+
+            ScratchImage temp2;
+            hr = Decompress(  image2, DXGI_FORMAT_R32G32B32A32_FLOAT, temp2 );
+            if ( FAILED(hr) )
+                return hr;
+
+            const Image* img1 = temp1.GetImage(0,0,0);
+            const Image* img2 = temp2.GetImage(0,0,0);
+            if ( !img1 || !img2 )
+                return E_POINTER;
+
+            return _ComputeMSE( *img1, *img2, mse, mseV, flags );
+        }
+        else
+        {
+            // Case 2: image1 is compressed, expand to RGBA32F
+            ScratchImage temp;
+            HRESULT hr = Decompress( image1, DXGI_FORMAT_R32G32B32A32_FLOAT, temp );
+            if ( FAILED(hr) )
+                return hr;
+
+            const Image* img = temp.GetImage(0,0,0);
+            if ( !img )
+                return E_POINTER;
+
+            return _ComputeMSE( *img, image2, mse, mseV, flags );
+        }
+    }
+    else
+    {
+        if ( IsCompressed(image2.format) )
+        {
+            // Case 3: image2 is compressed, expand to RGBA32F
+            ScratchImage temp;
+            HRESULT hr = Decompress( image2, DXGI_FORMAT_R32G32B32A32_FLOAT, temp );
+            if ( FAILED(hr) )
+                return hr;
+
+            const Image* img = temp.GetImage(0,0,0);
+            if ( !img )
+                return E_POINTER;
+
+            return _ComputeMSE( image1, *img, mse, mseV, flags );
+        }
+        else
+        {
+            // Case 4: neither image is compressed
+            return _ComputeMSE( image1, image2, mse, mseV, flags );
+        }
+    }
+}
+
+}; // namespace

+ 383 - 0
Exporters/FBX/3rdParty/DirectXTex/DirectXTexNormalMaps.cpp

@@ -0,0 +1,383 @@
+//-------------------------------------------------------------------------------------
+// DirectXTexNormalMaps.cpp
+//  
+// DirectX Texture Library - Normal map operations
+//
+// 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=248926
+//-------------------------------------------------------------------------------------
+
+#include "directxtexp.h"
+
+namespace DirectX
+{
+
+#pragma prefast(suppress : 25000, "FXMVECTOR is 16 bytes")
+static inline float _EvaluateColor( _In_ FXMVECTOR val, _In_ DWORD flags )
+{
+    XMFLOAT4A f;
+
+    static XMVECTORF32 lScale = { 0.2125f, 0.7154f, 0.0721f, 1.f };
+
+    static_assert( CNMAP_CHANNEL_RED == 0x1, "CNMAP_CHANNEL_ flag values don't match mask" );
+    switch( flags & 0xf )
+    {
+    case 0:
+    case CNMAP_CHANNEL_RED:     return XMVectorGetX( val );
+    case CNMAP_CHANNEL_GREEN:   return XMVectorGetY( val );
+    case CNMAP_CHANNEL_BLUE:    return XMVectorGetZ( val );
+    case CNMAP_CHANNEL_ALPHA:   return XMVectorGetW( val );
+
+    case CNMAP_CHANNEL_LUMINANCE:
+        {
+            XMVECTOR v = XMVectorMultiply( val, lScale );
+            XMStoreFloat4A( &f, v );
+            return f.x + f.y + f.z;
+        }
+        break;
+
+    default:
+        assert(false);
+        return 0.f;
+    }
+}
+
+static void _EvaluateRow( _In_reads_(width) const XMVECTOR* pSource, _Out_writes_(width+2) float* pDest,
+                          _In_ size_t width, _In_ DWORD flags )
+{
+    assert( pSource && pDest );
+    assert( width > 0 );
+
+    for( size_t x = 0; x < width; ++x )
+    {
+        pDest[x+1] = _EvaluateColor( pSource[x], flags );
+    }
+
+    if ( flags & CNMAP_MIRROR_U )
+    {
+        // Mirror in U
+        pDest[0] = _EvaluateColor( pSource[0], flags );
+        pDest[width+1] = _EvaluateColor( pSource[width-1], flags );
+    }
+    else
+    {
+        // Wrap in U
+        pDest[0] = _EvaluateColor( pSource[width-1], flags );
+        pDest[width+1] = _EvaluateColor( pSource[0], flags );
+    }
+}
+
+static HRESULT _ComputeNMap( _In_ const Image& srcImage, _In_ DWORD flags, _In_ float amplitude,
+                             _In_ DXGI_FORMAT format, _In_ const Image& normalMap )
+{
+    if ( !srcImage.pixels || !normalMap.pixels )
+        return E_INVALIDARG;
+
+    const DWORD convFlags = _GetConvertFlags( format );
+    if ( !convFlags )
+        return E_FAIL;
+
+    if ( !( convFlags & (CONVF_UNORM | CONVF_SNORM | CONVF_FLOAT) ) )
+        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+
+    const size_t width = srcImage.width;
+    const size_t height = srcImage.height;
+    if ( width != normalMap.width || height != normalMap.height )
+        return E_FAIL;
+
+    // Allocate temporary space (4 scanlines and 3 evaluated rows)
+    ScopedAlignedArrayXMVECTOR scanline( reinterpret_cast<XMVECTOR*>( _aligned_malloc( (sizeof(XMVECTOR)*width*4), 16 ) ) );
+    if ( !scanline )
+        return E_OUTOFMEMORY;
+
+    ScopedAlignedArrayFloat buffer( reinterpret_cast<float*>( _aligned_malloc( ( ( sizeof(float) * ( width + 2 ) ) * 3 ), 16 ) ) );
+    if ( !buffer )
+        return E_OUTOFMEMORY;
+
+    uint8_t* pDest = normalMap.pixels;
+    if ( !pDest )
+        return E_POINTER;
+
+    XMVECTOR* row0 = scanline.get();
+    XMVECTOR* row1 = row0 + width;
+    XMVECTOR* row2 = row1 + width;
+    XMVECTOR* target = row2 + width;
+
+    float* val0 = buffer.get();
+    float* val1 = val0 + width + 2;
+    float* val2 = val1 + width + 2;
+
+    const size_t rowPitch = srcImage.rowPitch;
+    const uint8_t* pSrc = srcImage.pixels;
+
+    // Read first scanline row into 'row1'
+    if ( !_LoadScanline( row1, width, pSrc, rowPitch, srcImage.format ) )
+        return E_FAIL;
+
+    // Setup 'row0'
+    if ( flags & CNMAP_MIRROR_V )
+    {
+        // Mirror first row
+        memcpy_s( row0, rowPitch, row1, rowPitch );
+    }
+    else
+    {
+        // Read last row (Wrap V)
+        if ( !_LoadScanline( row0, width, pSrc + (rowPitch * (height-1)), rowPitch, srcImage.format ) )
+            return E_FAIL;
+    }
+
+    // Evaluate the initial rows
+    _EvaluateRow( row0, val0, width, flags );
+    _EvaluateRow( row1, val1, width, flags );
+
+    pSrc += rowPitch;
+
+    for( size_t y = 0; y < height; ++y )
+    {
+        // Load next scanline of source image
+        if ( y < (height-1) )
+        {
+            if ( !_LoadScanline( row2, width, pSrc, rowPitch, srcImage.format ) )
+                return E_FAIL;
+        }
+        else
+        {
+            if ( flags & CNMAP_MIRROR_V )
+            {
+                // Use last row of source image
+                if ( !_LoadScanline( row2, width, srcImage.pixels + (rowPitch * (height-1)), rowPitch, srcImage.format ) )
+                    return E_FAIL;
+            }
+            else
+            {
+                // Use first row of source image (Wrap V)
+                if ( !_LoadScanline( row2, width, srcImage.pixels, rowPitch, srcImage.format ) )
+                    return E_FAIL;
+            }
+        }
+
+        // Evaluate row
+        _EvaluateRow( row2, val2, width, flags );
+
+        // Generate target scanline
+        XMVECTOR *dptr = target;
+        for( size_t x = 0; x < width; ++x )
+        {
+            // Compute normal via central differencing
+            float totDelta = ( val0[x] - val0[x+2] ) + ( val1[x] - val1[x+2] ) + ( val2[x] - val2[x+2] );
+            float deltaZX = totDelta * amplitude / 6.f;
+
+            totDelta = ( val0[x] - val2[x] ) + ( val0[x+1] - val2[x+1] ) + ( val0[x+2] - val2[x+2] );
+            float deltaZY = totDelta * amplitude / 6.f;
+
+            XMVECTOR vx = XMVectorSetZ( g_XMNegIdentityR0, deltaZX );   // (-1.0f, 0.0f, deltaZX)
+            XMVECTOR vy = XMVectorSetZ( g_XMNegIdentityR1, deltaZY );   // (0.0f, -1.0f, deltaZY)
+
+            XMVECTOR normal = XMVector3Normalize( XMVector3Cross( vx, vy ) );
+
+            // Compute alpha (1.0 or an occlusion term)
+            float alpha = 1.f;
+
+            if ( flags & CNMAP_COMPUTE_OCCLUSION )
+            {
+                float delta = 0.f;
+                float c = val1[x+1];
+
+                float t = val0[x] - c;  if ( t > 0.f ) delta += t;
+                t = val0[x+1]   - c;    if ( t > 0.f ) delta += t;
+                t = val0[x+2]   - c;    if ( t > 0.f ) delta += t;
+                t = val1[x]     - c;    if ( t > 0.f ) delta += t;
+                // Skip current pixel
+                t = val1[x+2]   - c;    if ( t > 0.f ) delta += t;
+                t = val2[x]     - c;    if ( t > 0.f ) delta += t;
+                t = val2[x+1]   - c;    if ( t > 0.f ) delta += t;
+                t = val2[x+2]   - c;    if ( t > 0.f ) delta += t;
+
+                // Average delta (divide by 8, scale by amplitude factor)
+                delta *= 0.125f * amplitude;
+                if ( delta > 0.f )
+                {
+                    // If < 0, then no occlusion
+                    float r = sqrtf( 1.f + delta*delta );
+                    alpha = (r - delta) / r;
+                }
+            }
+
+            // Encode based on target format
+            if ( convFlags & CONVF_UNORM )
+            {
+                // 0.5f*normal + 0.5f -or- invert sign case: -0.5f*normal + 0.5f
+                XMVECTOR n1 = XMVectorMultiplyAdd( (flags & CNMAP_INVERT_SIGN) ? g_XMNegativeOneHalf : g_XMOneHalf, normal, g_XMOneHalf ); 
+                *dptr++ = XMVectorSetW( n1, alpha );
+            }
+            else if ( flags & CNMAP_INVERT_SIGN )
+            {
+                *dptr++ = XMVectorSetW( XMVectorNegate( normal ), alpha );
+            }
+            else
+            {
+                *dptr++ = XMVectorSetW( normal, alpha );
+            }
+        }
+
+        if ( !_StoreScanline( pDest, normalMap.rowPitch, format, target, width ) )
+            return E_FAIL;
+
+        // Cycle buffers
+        float* temp = val0;
+        val0 = val1;
+        val1 = val2;
+        val2 = temp;
+
+        pSrc += rowPitch;
+        pDest += normalMap.rowPitch;
+    }
+
+    return S_OK;
+}
+
+
+//=====================================================================================
+// Entry points
+//=====================================================================================
+        
+//-------------------------------------------------------------------------------------
+// Generates a normal map from a height-map
+//-------------------------------------------------------------------------------------
+_Use_decl_annotations_
+HRESULT ComputeNormalMap( const Image& srcImage, DWORD flags, float amplitude,
+                          DXGI_FORMAT format, ScratchImage& normalMap )
+{
+    if ( !srcImage.pixels || !IsValid(format) )
+        return E_INVALIDARG;
+
+    static_assert( CNMAP_CHANNEL_RED == 0x1, "CNMAP_CHANNEL_ flag values don't match mask" );
+    switch( flags & 0xf )
+    {
+    case 0:
+    case CNMAP_CHANNEL_RED:
+    case CNMAP_CHANNEL_GREEN:
+    case CNMAP_CHANNEL_BLUE:
+    case CNMAP_CHANNEL_ALPHA:
+    case CNMAP_CHANNEL_LUMINANCE:
+        break;
+
+    default:
+        return E_INVALIDARG;
+    }
+
+    if ( IsCompressed(format) || IsCompressed(srcImage.format)
+         || IsTypeless(format) || IsTypeless(srcImage.format) 
+         || IsPlanar(format) || IsPlanar(srcImage.format) 
+         || IsPalettized(format) || IsPalettized(srcImage.format) )
+        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+
+    // Setup target image
+    normalMap.Release();
+
+    HRESULT hr = normalMap.Initialize2D( format, srcImage.width, srcImage.height, 1, 1 );
+    if ( FAILED(hr) )
+        return hr;
+
+    const Image *img = normalMap.GetImage( 0, 0, 0 );
+    if ( !img )
+    {
+        normalMap.Release();
+        return E_POINTER;
+    }
+
+    hr = _ComputeNMap( srcImage, flags, amplitude, format, *img );
+    if ( FAILED(hr) )
+    {
+        normalMap.Release();
+        return hr;
+    }
+
+    return S_OK;
+}
+
+_Use_decl_annotations_
+HRESULT ComputeNormalMap( const Image* srcImages, size_t nimages, const TexMetadata& metadata,
+                          DWORD flags, float amplitude, DXGI_FORMAT format, ScratchImage& normalMaps )
+{
+    if ( !srcImages || !nimages || !IsValid(format) )
+        return E_INVALIDARG;
+
+    if ( IsCompressed(format) || IsCompressed(metadata.format)
+         || IsTypeless(format) || IsTypeless(metadata.format) 
+         || IsPlanar(format) || IsPlanar(metadata.format) 
+         || IsPalettized(format) || IsPalettized(metadata.format) )
+        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+
+    static_assert( CNMAP_CHANNEL_RED == 0x1, "CNMAP_CHANNEL_ flag values don't match mask" );
+    switch( flags & 0xf )
+    {
+    case 0:
+    case CNMAP_CHANNEL_RED:
+    case CNMAP_CHANNEL_GREEN:
+    case CNMAP_CHANNEL_BLUE:
+    case CNMAP_CHANNEL_ALPHA:
+    case CNMAP_CHANNEL_LUMINANCE:
+        break;
+
+    default:
+        return E_INVALIDARG;
+    }
+
+    normalMaps.Release();
+
+    TexMetadata mdata2 = metadata;
+    mdata2.format = format;
+    HRESULT hr = normalMaps.Initialize( mdata2 );
+    if ( FAILED(hr) )
+        return hr;
+
+    if ( nimages != normalMaps.GetImageCount() )
+    {
+        normalMaps.Release();
+        return E_FAIL;
+    }
+
+    const Image* dest = normalMaps.GetImages();
+    if ( !dest )
+    {
+        normalMaps.Release();
+        return E_POINTER;
+    }
+
+    for( size_t index=0; index < nimages; ++index )
+    {
+        assert( dest[ index ].format == format );
+
+        const Image& src = srcImages[ index ];
+        if ( IsCompressed( src.format ) || IsTypeless( src.format ) )
+        {
+            normalMaps.Release();
+            return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+        }
+
+        if ( src.width != dest[ index ].width || src.height != dest[ index ].height )
+        {
+            normalMaps.Release();
+            return E_FAIL;
+        }
+
+        hr = _ComputeNMap( src, flags, amplitude, format, dest[ index ] );
+        if ( FAILED(hr) )
+        {
+            normalMaps.Release();
+            return hr;
+        }
+    }
+
+    return S_OK;
+}
+
+}; // namespace

+ 209 - 0
Exporters/FBX/3rdParty/DirectXTex/DirectXTexP.h

@@ -0,0 +1,209 @@
+//-------------------------------------------------------------------------------------
+// DirectXTexp.h
+//  
+// DirectX Texture Library - Private header
+//
+// 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=248926
+//-------------------------------------------------------------------------------------
+
+#if defined(_MSC_VER) && (_MSC_VER > 1000)
+#pragma once
+#endif
+
+#define NOMINMAX
+#include <windows.h>
+#include <directxmath.h>
+#include <directxpackedvector.h>
+#include <assert.h>
+
+#include <malloc.h>
+#include <memory>
+
+#include <vector>
+
+#include <stdlib.h>
+#include <search.h>
+
+#include <ole2.h>
+
+#include "directxtex.h"
+
+// VS 2010's stdint.h conflicts with intsafe.h
+#pragma warning(push)
+#pragma warning(disable : 4005)
+#include <wincodec.h>
+#include <wrl.h>
+#pragma warning(pop)
+
+#include "scoped.h"
+
+struct IWICImagingFactory;
+
+#define TEX_FILTER_MASK 0xF00000
+
+namespace DirectX
+{
+    //---------------------------------------------------------------------------------
+    // WIC helper functions
+    DXGI_FORMAT _WICToDXGI( _In_ const GUID& guid );
+    bool _DXGIToWIC( _In_ DXGI_FORMAT format, _Out_ GUID& guid, _In_ bool ignoreRGBvsBGR = false );
+
+    DWORD _CheckWICColorSpace( _In_ const GUID& sourceGUID, _In_ const GUID& targetGUID );
+
+    IWICImagingFactory* _GetWIC();
+
+    bool _IsWIC2();
+
+    inline WICBitmapDitherType _GetWICDither( _In_ DWORD flags )
+    {
+        static_assert( TEX_FILTER_DITHER == 0x10000, "TEX_FILTER_DITHER* flag values don't match mask" );
+
+        static_assert( TEX_FILTER_DITHER == WIC_FLAGS_DITHER, "TEX_FILTER_DITHER* should match WIC_FLAGS_DITHER*" );
+        static_assert( TEX_FILTER_DITHER_DIFFUSION == WIC_FLAGS_DITHER_DIFFUSION, "TEX_FILTER_DITHER* should match WIC_FLAGS_DITHER*" );
+
+        switch( flags & 0xF0000 )
+        {
+        case TEX_FILTER_DITHER:
+            return WICBitmapDitherTypeOrdered4x4;
+
+        case TEX_FILTER_DITHER_DIFFUSION:
+            return WICBitmapDitherTypeErrorDiffusion;
+
+        default:
+            return WICBitmapDitherTypeNone;
+        }
+    }
+
+    inline WICBitmapInterpolationMode _GetWICInterp( _In_ DWORD flags )
+    {
+        static_assert( TEX_FILTER_POINT == 0x100000, "TEX_FILTER_ flag values don't match TEX_FILTER_MASK" );
+
+        static_assert( TEX_FILTER_POINT == WIC_FLAGS_FILTER_POINT, "TEX_FILTER_* flags should match WIC_FLAGS_FILTER_*" );
+        static_assert( TEX_FILTER_LINEAR == WIC_FLAGS_FILTER_LINEAR, "TEX_FILTER_* flags should match WIC_FLAGS_FILTER_*"  );
+        static_assert( TEX_FILTER_CUBIC == WIC_FLAGS_FILTER_CUBIC, "TEX_FILTER_* flags should match WIC_FLAGS_FILTER_*"  );
+        static_assert( TEX_FILTER_FANT == WIC_FLAGS_FILTER_FANT, "TEX_FILTER_* flags should match WIC_FLAGS_FILTER_*"  );
+
+        switch( flags & TEX_FILTER_MASK )
+        {
+        case TEX_FILTER_POINT:
+            return WICBitmapInterpolationModeNearestNeighbor;
+
+        case TEX_FILTER_LINEAR:
+            return WICBitmapInterpolationModeLinear;
+
+        case TEX_FILTER_CUBIC:
+            return WICBitmapInterpolationModeCubic;
+
+        case TEX_FILTER_FANT:
+        default:
+            return WICBitmapInterpolationModeFant;
+        }
+    }
+
+    //---------------------------------------------------------------------------------
+    // Image helper functions
+    void _DetermineImageArray( _In_ const TexMetadata& metadata, _In_ DWORD cpFlags,
+                               _Out_ size_t& nImages, _Out_ size_t& pixelSize );
+
+    _Success_(return != false)
+    bool _SetupImageArray( _In_reads_bytes_(pixelSize) uint8_t *pMemory, _In_ size_t pixelSize,
+                           _In_ const TexMetadata& metadata, _In_ DWORD cpFlags,
+                           _Out_writes_(nImages) Image* images, _In_ size_t nImages );
+
+    //---------------------------------------------------------------------------------
+    // Conversion helper functions
+
+    enum TEXP_SCANLINE_FLAGS
+    {
+        TEXP_SCANLINE_NONE          = 0,
+        TEXP_SCANLINE_SETALPHA      = 0x1,  // Set alpha channel to known opaque value
+        TEXP_SCANLINE_LEGACY        = 0x2,  // Enables specific legacy format conversion cases
+    };
+
+    enum CONVERT_FLAGS
+    {
+        CONVF_FLOAT     = 0x1,
+        CONVF_UNORM     = 0x2,
+        CONVF_UINT      = 0x4,
+        CONVF_SNORM     = 0x8, 
+        CONVF_SINT      = 0x10,
+        CONVF_DEPTH     = 0x20,
+        CONVF_STENCIL   = 0x40,
+        CONVF_SHAREDEXP = 0x80,
+        CONVF_BGR       = 0x100,
+        CONVF_XR        = 0x200,
+        CONVF_PACKED    = 0x400,
+        CONVF_BC        = 0x800,
+        CONVF_YUV       = 0x1000,
+        CONVF_R         = 0x10000,
+        CONVF_G         = 0x20000,
+        CONVF_B         = 0x40000,
+        CONVF_A         = 0x80000,
+        CONVF_RGB_MASK  = 0x70000,
+        CONVF_RGBA_MASK = 0xF0000,
+    };
+
+    DWORD _GetConvertFlags( _In_ DXGI_FORMAT format );
+
+    void _CopyScanline( _When_(pDestination == pSource, _Inout_updates_bytes_(outSize))
+                        _When_(pDestination != pSource, _Out_writes_bytes_(outSize))
+                        LPVOID pDestination, _In_ size_t outSize, 
+                        _In_reads_bytes_(inSize) LPCVOID pSource, _In_ size_t inSize,
+                        _In_ DXGI_FORMAT format, _In_ DWORD flags );
+
+    void _SwizzleScanline( _When_(pDestination == pSource, _In_)
+                           _When_(pDestination != pSource, _Out_writes_bytes_(outSize))
+                           LPVOID pDestination, _In_ size_t outSize, 
+                           _In_reads_bytes_(inSize) LPCVOID pSource, _In_ size_t inSize,
+                           _In_ DXGI_FORMAT format, _In_ DWORD flags );
+
+    _Success_(return != false)
+    bool _ExpandScanline( _Out_writes_bytes_(outSize) LPVOID pDestination, _In_ size_t outSize,
+                          _In_ DXGI_FORMAT outFormat, 
+                          _In_reads_bytes_(inSize) LPCVOID pSource, _In_ size_t inSize,
+                          _In_ DXGI_FORMAT inFormat, _In_ DWORD flags );
+
+    _Success_(return != false)
+    bool _LoadScanline( _Out_writes_(count) XMVECTOR* pDestination, _In_ size_t count,
+                        _In_reads_bytes_(size) LPCVOID pSource, _In_ size_t size, _In_ DXGI_FORMAT format );
+
+    _Success_(return != false)
+    bool _LoadScanlineLinear( _Out_writes_(count) XMVECTOR* pDestination, _In_ size_t count,
+                             _In_reads_bytes_(size) LPCVOID pSource, _In_ size_t size, _In_ DXGI_FORMAT format, _In_ DWORD flags  );
+
+    _Success_(return != false)
+    bool _StoreScanline( LPVOID pDestination, _In_ size_t size, _In_ DXGI_FORMAT format,
+                         _In_reads_(count) const XMVECTOR* pSource, _In_ size_t count, _In_ float threshold = 0 );
+
+    _Success_(return != false)
+    bool _StoreScanlineLinear( LPVOID pDestination, _In_ size_t size, _In_ DXGI_FORMAT format,
+                               _Inout_updates_all_(count) XMVECTOR* pSource, _In_ size_t count, _In_ DWORD flags );
+
+    _Success_(return != false)
+    bool _StoreScanlineDither( LPVOID pDestination, _In_ size_t size, _In_ DXGI_FORMAT format,
+                               _Inout_updates_all_(count) XMVECTOR* pSource, _In_ size_t count, _In_ float threshold, size_t y, size_t z,
+                               _Inout_updates_all_opt_(count+2) XMVECTOR* pDiffusionErrors );
+
+    HRESULT _ConvertToR32G32B32A32( _In_ const Image& srcImage, _Inout_ ScratchImage& image );
+
+    HRESULT _ConvertFromR32G32B32A32( _In_ const Image& srcImage, _In_ const Image& destImage );
+    HRESULT _ConvertFromR32G32B32A32( _In_ const Image& srcImage, _In_ DXGI_FORMAT format, _Inout_ ScratchImage& image );
+    HRESULT _ConvertFromR32G32B32A32( _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata,
+                                      _In_ DXGI_FORMAT format, _Out_ ScratchImage& result );
+
+    void _ConvertScanline( _Inout_updates_all_(count) XMVECTOR* pBuffer, _In_ size_t count,
+                           _In_ DXGI_FORMAT outFormat, _In_ DXGI_FORMAT inFormat, _In_ DWORD flags );
+
+    //---------------------------------------------------------------------------------
+    // DDS helper functions
+    HRESULT _EncodeDDSHeader( _In_ const TexMetadata& metadata, DWORD flags,
+                              _Out_writes_bytes_to_opt_(maxsize, required) LPVOID pDestination, _In_ size_t maxsize, _Out_ size_t& required );
+
+}; // namespace

+ 229 - 0
Exporters/FBX/3rdParty/DirectXTex/DirectXTexPMAlpha.cpp

@@ -0,0 +1,229 @@
+//-------------------------------------------------------------------------------------
+// DirectXTexPMAlpha.cpp
+//  
+// DirectX Texture Library - Premultiplied alpha operations
+//
+// 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=248926
+//-------------------------------------------------------------------------------------
+
+#include "directxtexp.h"
+
+namespace DirectX
+{
+
+static HRESULT _PremultiplyAlpha( _In_ const Image& srcImage, _In_ const Image& destImage )
+{
+    assert( srcImage.width == destImage.width );
+    assert( srcImage.height == destImage.height );
+
+    ScopedAlignedArrayXMVECTOR scanline( reinterpret_cast<XMVECTOR*>( _aligned_malloc( (sizeof(XMVECTOR)*srcImage.width), 16 ) ) );
+    if ( !scanline )
+        return E_OUTOFMEMORY;
+
+    const uint8_t *pSrc = srcImage.pixels;
+    uint8_t *pDest = destImage.pixels;
+    if ( !pSrc || !pDest )
+        return E_POINTER;
+
+    for( size_t h = 0; h < srcImage.height; ++h )
+    {
+        if ( !_LoadScanline( scanline.get(), srcImage.width, pSrc, srcImage.rowPitch, srcImage.format ) )
+            return E_FAIL;
+
+        XMVECTOR* ptr = scanline.get();
+        for( size_t w = 0; w < srcImage.width; ++w )
+        {
+            XMVECTOR v = *ptr;
+            XMVECTOR alpha = XMVectorSplatW( *ptr );
+            alpha = XMVectorMultiply( v, alpha );
+            *(ptr++) = XMVectorSelect( v, alpha, g_XMSelect1110 );
+        }
+
+        if ( !_StoreScanline( pDest, destImage.rowPitch, destImage.format, scanline.get(), srcImage.width ) )
+            return E_FAIL;
+
+        pSrc += srcImage.rowPitch;
+        pDest += destImage.rowPitch;
+    }
+
+    return S_OK;
+}
+
+static HRESULT _PremultiplyAlphaLinear( _In_ const Image& srcImage, _In_ DWORD flags, _In_ const Image& destImage )
+{
+    assert( srcImage.width == destImage.width );
+    assert( srcImage.height == destImage.height );
+
+    static_assert( TEX_PMALPHA_SRGB_IN == TEX_FILTER_SRGB_IN, "TEX_PMALHPA_SRGB* should match TEX_FILTER_SRGB*" );
+    static_assert( TEX_PMALPHA_SRGB_OUT == TEX_FILTER_SRGB_OUT, "TEX_PMALHPA_SRGB* should match TEX_FILTER_SRGB*" );
+    static_assert( TEX_PMALPHA_SRGB == TEX_FILTER_SRGB, "TEX_PMALHPA_SRGB* should match TEX_FILTER_SRGB*" );
+    flags &= TEX_PMALPHA_SRGB;
+
+    ScopedAlignedArrayXMVECTOR scanline( reinterpret_cast<XMVECTOR*>( _aligned_malloc( (sizeof(XMVECTOR)*srcImage.width), 16 ) ) );
+    if ( !scanline )
+        return E_OUTOFMEMORY;
+
+    const uint8_t *pSrc = srcImage.pixels;
+    uint8_t *pDest = destImage.pixels;
+    if ( !pSrc || !pDest )
+        return E_POINTER;
+
+    for( size_t h = 0; h < srcImage.height; ++h )
+    {
+        if ( !_LoadScanlineLinear( scanline.get(), srcImage.width, pSrc, srcImage.rowPitch, srcImage.format, flags ) )
+            return E_FAIL;
+
+        XMVECTOR* ptr = scanline.get();
+        for( size_t w = 0; w < srcImage.width; ++w )
+        {
+            XMVECTOR v = *ptr;
+            XMVECTOR alpha = XMVectorSplatW( *ptr );
+            alpha = XMVectorMultiply( v, alpha );
+            *(ptr++) = XMVectorSelect( v, alpha, g_XMSelect1110 );
+        }
+
+        if ( !_StoreScanlineLinear( pDest, destImage.rowPitch, destImage.format, scanline.get(), srcImage.width, flags ) )
+            return E_FAIL;
+
+        pSrc += srcImage.rowPitch;
+        pDest += destImage.rowPitch;
+    }
+
+    return S_OK;
+}
+
+
+//=====================================================================================
+// Entry-points
+//=====================================================================================
+
+//-------------------------------------------------------------------------------------
+// Converts to a premultiplied alpha version of the texture
+//-------------------------------------------------------------------------------------
+_Use_decl_annotations_
+HRESULT PremultiplyAlpha( const Image& srcImage, DWORD flags, ScratchImage& image )
+{
+    if ( !srcImage.pixels )
+        return E_POINTER;
+
+    if ( IsCompressed(srcImage.format)
+         || IsPlanar(srcImage.format)
+         || IsPalettized(srcImage.format)
+         || IsTypeless(srcImage.format)
+         || !HasAlpha(srcImage.format) )
+        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+
+#ifdef _M_X64
+    if ( (srcImage.width > 0xFFFFFFFF) || (srcImage.height > 0xFFFFFFFF) )
+        return E_INVALIDARG;
+#endif
+
+    HRESULT hr = image.Initialize2D( srcImage.format, srcImage.width, srcImage.height, 1, 1 );
+    if ( FAILED(hr) )
+        return hr;
+   
+    const Image *rimage = image.GetImage( 0, 0, 0 );
+    if ( !rimage )
+    {
+        image.Release();
+        return E_POINTER;
+    }
+
+    hr = ( flags & TEX_PMALPHA_IGNORE_SRGB ) ? _PremultiplyAlpha( srcImage, *rimage ) : _PremultiplyAlphaLinear( srcImage, flags, *rimage );
+    if ( FAILED(hr) )
+    {
+        image.Release();
+        return hr;
+    }
+
+    return S_OK;
+}
+
+
+//-------------------------------------------------------------------------------------
+// Converts to a premultiplied alpha version of the texture (complex)
+//-------------------------------------------------------------------------------------
+_Use_decl_annotations_
+HRESULT PremultiplyAlpha( const Image* srcImages, size_t nimages, const TexMetadata& metadata, DWORD flags, ScratchImage& result )
+{
+    if ( !srcImages || !nimages )
+        return E_INVALIDARG;
+
+    if ( IsCompressed(metadata.format)
+         || IsPlanar(metadata.format)
+         || IsPalettized(metadata.format)
+         || IsTypeless(metadata.format)
+         || !HasAlpha(metadata.format) )
+        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+
+#ifdef _M_X64
+    if ( (metadata.width > 0xFFFFFFFF) || (metadata.height > 0xFFFFFFFF) )
+        return E_INVALIDARG;
+#endif
+
+    if ( metadata.IsPMAlpha() )
+    {
+        // Already premultiplied
+        return E_FAIL;
+    }
+
+    TexMetadata mdata2 = metadata;
+    mdata2.SetAlphaMode(TEX_ALPHA_MODE_PREMULTIPLIED);
+    HRESULT hr = result.Initialize( mdata2 );
+    if ( FAILED(hr) )
+        return hr;
+
+    if ( nimages != result.GetImageCount() )
+    {
+        result.Release();
+        return E_FAIL;
+    }
+
+    const Image* dest = result.GetImages();
+    if ( !dest )
+    {
+        result.Release();
+        return E_POINTER;
+    }
+
+    for( size_t index=0; index < nimages; ++index )
+    {
+        const Image& src = srcImages[ index ];
+        if ( src.format != metadata.format )
+        {
+            result.Release();
+            return E_FAIL;
+        }
+
+#ifdef _M_X64
+        if ( (src.width > 0xFFFFFFFF) || (src.height > 0xFFFFFFFF) )
+            return E_FAIL;
+#endif
+        const Image& dst = dest[ index ];
+        assert( dst.format == metadata.format );
+
+        if ( src.width != dst.width || src.height != dst.height )
+        {
+            result.Release();
+            return E_FAIL;
+        }
+
+        hr = ( flags & TEX_PMALPHA_IGNORE_SRGB ) ? _PremultiplyAlpha( src, dst ) : _PremultiplyAlphaLinear( src, flags, dst );
+        if ( FAILED(hr) )
+        {
+            result.Release();
+            return hr;
+        }
+    }
+
+    return S_OK;
+}
+
+}; // namespace

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1034 - 0
Exporters/FBX/3rdParty/DirectXTex/DirectXTexResize.cpp


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1391 - 0
Exporters/FBX/3rdParty/DirectXTex/DirectXTexTGA.cpp


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1029 - 0
Exporters/FBX/3rdParty/DirectXTex/DirectXTexUtil.cpp


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1128 - 0
Exporters/FBX/3rdParty/DirectXTex/DirectXTexWIC.cpp


+ 432 - 0
Exporters/FBX/3rdParty/DirectXTex/DirectXTex_Desktop_2012.vcxproj

@@ -0,0 +1,432 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Profile|Win32">
+      <Configuration>Profile</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Profile|x64">
+      <Configuration>Profile</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectName>DirectXTex</ProjectName>
+    <ProjectGuid>{371B9FA9-4C90-4AC6-A123-ACED756D6C77}</ProjectGuid>
+    <RootNamespace>DirectXTex</RootNamespace>
+    <Keyword>Win32Proj</Keyword>
+    <VCTargetsPath Condition="'$(VCTargetsPath11)' != '' and '$(VSVersion)' == '' and $(VisualStudioVersion) == ''">$(VCTargetsPath11)</VCTargetsPath>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|X64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|X64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|X64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings" />
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <OutDir>Bin\Desktop_2012\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>Bin\Desktop_2012\$(Platform)\$(Configuration)\</IntDir>
+    <TargetName>DirectXTex</TargetName>
+    <LinkIncremental>true</LinkIncremental>
+    <GenerateManifest>true</GenerateManifest>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|X64'">
+    <OutDir>Bin\Desktop_2012\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>Bin\Desktop_2012\$(Platform)\$(Configuration)\</IntDir>
+    <TargetName>DirectXTex</TargetName>
+    <LinkIncremental>true</LinkIncremental>
+    <GenerateManifest>true</GenerateManifest>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <OutDir>Bin\Desktop_2012\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>Bin\Desktop_2012\$(Platform)\$(Configuration)\</IntDir>
+    <TargetName>DirectXTex</TargetName>
+    <LinkIncremental>false</LinkIncremental>
+    <GenerateManifest>true</GenerateManifest>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|X64'">
+    <OutDir>Bin\Desktop_2012\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>Bin\Desktop_2012\$(Platform)\$(Configuration)\</IntDir>
+    <TargetName>DirectXTex</TargetName>
+    <LinkIncremental>false</LinkIncremental>
+    <GenerateManifest>true</GenerateManifest>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">
+    <OutDir>Bin\Desktop_2012\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>Bin\Desktop_2012\$(Platform)\$(Configuration)\</IntDir>
+    <TargetName>DirectXTex</TargetName>
+    <LinkIncremental>false</LinkIncremental>
+    <GenerateManifest>true</GenerateManifest>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|X64'">
+    <OutDir>Bin\Desktop_2012\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>Bin\Desktop_2012\$(Platform)\$(Configuration)\</IntDir>
+    <TargetName>DirectXTex</TargetName>
+    <LinkIncremental>false</LinkIncremental>
+    <GenerateManifest>true</GenerateManifest>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <WarningLevel>Level4</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <OpenMPSupport>true</OpenMPSupport>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <FloatingPointModel>Fast</FloatingPointModel>
+      <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
+      <ExceptionHandling>Sync</ExceptionHandling>
+      <AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
+      <PreprocessorDefinitions>_UNICODE;UNICODE;WIN32;_DEBUG;_LIB;_WIN7_PLATFORM_UPDATE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <PrecompiledHeaderFile>DirectXTexP.h</PrecompiledHeaderFile>
+      <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+    </ClCompile>
+    <Link>
+      <AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <LargeAddressAware>true</LargeAddressAware>
+      <RandomizedBaseAddress>true</RandomizedBaseAddress>
+      <DataExecutionPrevention>true</DataExecutionPrevention>
+      <TargetMachine>MachineX86</TargetMachine>
+      <UACExecutionLevel>AsInvoker</UACExecutionLevel>
+      <DelayLoadDLLs>%(DelayLoadDLLs)</DelayLoadDLLs>
+    </Link>
+    <Manifest>
+      <EnableDPIAwareness>false</EnableDPIAwareness>
+    </Manifest>
+    <PreBuildEvent>
+      <Command>
+      </Command>
+    </PreBuildEvent>
+    <PostBuildEvent>
+      <Command>
+      </Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|X64'">
+    <ClCompile>
+      <WarningLevel>Level4</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <OpenMPSupport>true</OpenMPSupport>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <FloatingPointModel>Fast</FloatingPointModel>
+      <ExceptionHandling>Sync</ExceptionHandling>
+      <AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
+      <PreprocessorDefinitions>_UNICODE;UNICODE;WIN32;_DEBUG;_LIB;_WIN7_PLATFORM_UPDATE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <PrecompiledHeaderFile>DirectXTexP.h</PrecompiledHeaderFile>
+      <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+    </ClCompile>
+    <Link>
+      <AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <LargeAddressAware>true</LargeAddressAware>
+      <RandomizedBaseAddress>true</RandomizedBaseAddress>
+      <DataExecutionPrevention>true</DataExecutionPrevention>
+      <TargetMachine>MachineX64</TargetMachine>
+      <UACExecutionLevel>AsInvoker</UACExecutionLevel>
+      <DelayLoadDLLs>%(DelayLoadDLLs)</DelayLoadDLLs>
+    </Link>
+    <Manifest>
+      <EnableDPIAwareness>false</EnableDPIAwareness>
+    </Manifest>
+    <PreBuildEvent>
+      <Command>
+      </Command>
+    </PreBuildEvent>
+    <PostBuildEvent>
+      <Command>
+      </Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level4</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <OpenMPSupport>true</OpenMPSupport>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <FloatingPointModel>Fast</FloatingPointModel>
+      <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
+      <ExceptionHandling>Sync</ExceptionHandling>
+      <AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
+      <PreprocessorDefinitions>_UNICODE;UNICODE;WIN32;NDEBUG;_LIB;_WIN7_PLATFORM_UPDATE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <PrecompiledHeaderFile>DirectXTexP.h</PrecompiledHeaderFile>
+      <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+    </ClCompile>
+    <Link>
+      <AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Windows</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <LargeAddressAware>true</LargeAddressAware>
+      <RandomizedBaseAddress>true</RandomizedBaseAddress>
+      <DataExecutionPrevention>true</DataExecutionPrevention>
+      <TargetMachine>MachineX86</TargetMachine>
+      <UACExecutionLevel>AsInvoker</UACExecutionLevel>
+      <DelayLoadDLLs>%(DelayLoadDLLs)</DelayLoadDLLs>
+    </Link>
+    <Manifest>
+      <EnableDPIAwareness>false</EnableDPIAwareness>
+    </Manifest>
+    <PreBuildEvent>
+      <Command>
+      </Command>
+    </PreBuildEvent>
+    <PostBuildEvent>
+      <Command>
+      </Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|X64'">
+    <ClCompile>
+      <WarningLevel>Level4</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <OpenMPSupport>true</OpenMPSupport>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <FloatingPointModel>Fast</FloatingPointModel>
+      <ExceptionHandling>Sync</ExceptionHandling>
+      <AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
+      <PreprocessorDefinitions>_UNICODE;UNICODE;WIN32;NDEBUG;_LIB;_WIN7_PLATFORM_UPDATE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <PrecompiledHeaderFile>DirectXTexP.h</PrecompiledHeaderFile>
+      <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+    </ClCompile>
+    <Link>
+      <AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Windows</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <LargeAddressAware>true</LargeAddressAware>
+      <RandomizedBaseAddress>true</RandomizedBaseAddress>
+      <DataExecutionPrevention>true</DataExecutionPrevention>
+      <TargetMachine>MachineX64</TargetMachine>
+      <UACExecutionLevel>AsInvoker</UACExecutionLevel>
+      <DelayLoadDLLs>%(DelayLoadDLLs)</DelayLoadDLLs>
+    </Link>
+    <Manifest>
+      <EnableDPIAwareness>false</EnableDPIAwareness>
+    </Manifest>
+    <PreBuildEvent>
+      <Command>
+      </Command>
+    </PreBuildEvent>
+    <PostBuildEvent>
+      <Command>
+      </Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">
+    <ClCompile>
+      <WarningLevel>Level4</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <OpenMPSupport>true</OpenMPSupport>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <FloatingPointModel>Fast</FloatingPointModel>
+      <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
+      <ExceptionHandling>Sync</ExceptionHandling>
+      <AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
+      <PreprocessorDefinitions>_UNICODE;UNICODE;WIN32;NDEBUG;PROFILE;_LIB;_WIN7_PLATFORM_UPDATE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <PrecompiledHeaderFile>DirectXTexP.h</PrecompiledHeaderFile>
+      <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+    </ClCompile>
+    <Link>
+      <AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Windows</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <LargeAddressAware>true</LargeAddressAware>
+      <RandomizedBaseAddress>true</RandomizedBaseAddress>
+      <DataExecutionPrevention>true</DataExecutionPrevention>
+      <TargetMachine>MachineX86</TargetMachine>
+      <UACExecutionLevel>AsInvoker</UACExecutionLevel>
+      <DelayLoadDLLs>%(DelayLoadDLLs)</DelayLoadDLLs>
+    </Link>
+    <Manifest>
+      <EnableDPIAwareness>false</EnableDPIAwareness>
+    </Manifest>
+    <PreBuildEvent>
+      <Command>
+      </Command>
+    </PreBuildEvent>
+    <PostBuildEvent>
+      <Command>
+      </Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Profile|X64'">
+    <ClCompile>
+      <WarningLevel>Level4</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <OpenMPSupport>true</OpenMPSupport>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <FloatingPointModel>Fast</FloatingPointModel>
+      <ExceptionHandling>Sync</ExceptionHandling>
+      <AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
+      <PreprocessorDefinitions>_UNICODE;UNICODE;WIN32;NDEBUG;PROFILE;_LIB;_WIN7_PLATFORM_UPDATE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <PrecompiledHeaderFile>DirectXTexP.h</PrecompiledHeaderFile>
+      <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+    </ClCompile>
+    <Link>
+      <AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Windows</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <LargeAddressAware>true</LargeAddressAware>
+      <RandomizedBaseAddress>true</RandomizedBaseAddress>
+      <DataExecutionPrevention>true</DataExecutionPrevention>
+      <TargetMachine>MachineX64</TargetMachine>
+      <UACExecutionLevel>AsInvoker</UACExecutionLevel>
+      <DelayLoadDLLs>%(DelayLoadDLLs)</DelayLoadDLLs>
+    </Link>
+    <Manifest>
+      <EnableDPIAwareness>false</EnableDPIAwareness>
+    </Manifest>
+    <PreBuildEvent>
+      <Command>
+      </Command>
+    </PreBuildEvent>
+    <PostBuildEvent>
+      <Command>
+      </Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <CLInclude Include="BC.h" />
+    <ClCompile Include="BC.cpp" />
+    <ClCompile Include="BC4BC5.cpp" />
+    <ClCompile Include="BC6HBC7.cpp" />
+    <ClInclude Include="BCDirectCompute.h" />
+    <CLInclude Include="DDS.h" />
+    <ClInclude Include="filters.h" />
+    <CLInclude Include="scoped.h" />
+    <CLInclude Include="DirectXTex.h" />
+    <CLInclude Include="DirectXTexp.h" />
+    <CLInclude Include="DirectXTex.inl" />
+    <ClCompile Include="BCDirectCompute.cpp" />
+    <ClCompile Include="DirectXTexCompress.cpp" />
+    <ClCompile Include="DirectXTexCompressGPU.cpp" />
+    <ClCompile Include="DirectXTexConvert.cpp" />
+    <ClCompile Include="DirectXTexD3D11.cpp" />
+    <ClCompile Include="DirectXTexDDS.cpp" />
+    <ClCompile Include="DirectXTexFlipRotate.cpp" />
+    <ClCompile Include="DirectXTexImage.cpp" />
+    <ClCompile Include="DirectXTexMipMaps.cpp" />
+    <ClCompile Include="DirectXTexMisc.cpp" />
+    <ClCompile Include="DirectXTexNormalMaps.cpp" />
+    <ClCompile Include="DirectXTexPMAlpha.cpp" />
+    <ClCompile Include="DirectXTexResize.cpp" />
+    <ClCompile Include="DirectXTexTGA.cpp" />
+    <ClCompile Include="DirectXTexUtil.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Profile|x64'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="DirectXTexWIC.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+  </ItemGroup>
+  <ItemGroup>
+  </ItemGroup>
+  <ItemGroup>
+  </ItemGroup>
+  <ItemGroup>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets" />
+</Project>

+ 38 - 0
Exporters/FBX/3rdParty/DirectXTex/DirectXTex_Desktop_2012.vcxproj.filters

@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns:atg="http://atg.xbox.com" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Resource Files">
+      <UniqueIdentifier>{8e114980-c1a3-4ada-ad7c-83caadf5daeb}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <CLInclude Include="BC.h" />
+    <ClCompile Include="BC.cpp" />
+    <ClCompile Include="BC4BC5.cpp" />
+    <ClCompile Include="BC6HBC7.cpp" />
+    <CLInclude Include="DDS.h" />
+    <ClInclude Include="filters.h" />
+    <CLInclude Include="scoped.h" />
+    <CLInclude Include="DirectXTex.h" />
+    <CLInclude Include="DirectXTexp.h" />
+    <CLInclude Include="DirectXTex.inl" />
+    <ClCompile Include="DirectXTexCompress.cpp" />
+    <ClCompile Include="DirectXTexConvert.cpp" />
+    <ClCompile Include="DirectXTexD3D11.cpp" />
+    <ClCompile Include="DirectXTexDDS.cpp" />
+    <ClCompile Include="DirectXTexFlipRotate.cpp" />
+    <ClCompile Include="DirectXTexImage.cpp" />
+    <ClCompile Include="DirectXTexMipMaps.cpp" />
+    <ClCompile Include="DirectXTexMisc.cpp" />
+    <ClCompile Include="DirectXTexNormalMaps.cpp" />
+    <ClCompile Include="DirectXTexPMAlpha.cpp" />
+    <ClCompile Include="DirectXTexResize.cpp" />
+    <ClCompile Include="DirectXTexTGA.cpp" />
+    <ClCompile Include="DirectXTexUtil.cpp" />
+    <ClCompile Include="DirectXTexWIC.cpp" />
+    <ClInclude Include="BCDirectCompute.h" />
+    <ClCompile Include="BCDirectCompute.cpp" />
+    <ClCompile Include="DirectXTexCompressGPU.cpp" />
+  </ItemGroup>
+</Project>

+ 436 - 0
Exporters/FBX/3rdParty/DirectXTex/DirectXTex_Desktop_2013.vcxproj

@@ -0,0 +1,436 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Profile|Win32">
+      <Configuration>Profile</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Profile|x64">
+      <Configuration>Profile</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectName>DirectXTex</ProjectName>
+    <ProjectGuid>{371B9FA9-4C90-4AC6-A123-ACED756D6C77}</ProjectGuid>
+    <RootNamespace>DirectXTex</RootNamespace>
+    <Keyword>Win32Proj</Keyword>
+    <SccProjectName>SAK</SccProjectName>
+    <SccAuxPath>SAK</SccAuxPath>
+    <SccLocalPath>SAK</SccLocalPath>
+    <SccProvider>SAK</SccProvider>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|X64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|X64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|X64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings" />
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <OutDir>Bin\Desktop_2013\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>Bin\Desktop_2013\$(Platform)\$(Configuration)\</IntDir>
+    <TargetName>DirectXTex</TargetName>
+    <LinkIncremental>true</LinkIncremental>
+    <GenerateManifest>true</GenerateManifest>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|X64'">
+    <OutDir>Bin\Desktop_2013\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>Bin\Desktop_2013\$(Platform)\$(Configuration)\</IntDir>
+    <TargetName>DirectXTex</TargetName>
+    <LinkIncremental>true</LinkIncremental>
+    <GenerateManifest>true</GenerateManifest>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <OutDir>Bin\Desktop_2013\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>Bin\Desktop_2013\$(Platform)\$(Configuration)\</IntDir>
+    <TargetName>DirectXTex</TargetName>
+    <LinkIncremental>false</LinkIncremental>
+    <GenerateManifest>true</GenerateManifest>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|X64'">
+    <OutDir>Bin\Desktop_2013\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>Bin\Desktop_2013\$(Platform)\$(Configuration)\</IntDir>
+    <TargetName>DirectXTex</TargetName>
+    <LinkIncremental>false</LinkIncremental>
+    <GenerateManifest>true</GenerateManifest>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">
+    <OutDir>Bin\Desktop_2013\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>Bin\Desktop_2013\$(Platform)\$(Configuration)\</IntDir>
+    <TargetName>DirectXTex</TargetName>
+    <LinkIncremental>false</LinkIncremental>
+    <GenerateManifest>true</GenerateManifest>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|X64'">
+    <OutDir>Bin\Desktop_2013\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>Bin\Desktop_2013\$(Platform)\$(Configuration)\</IntDir>
+    <TargetName>DirectXTex</TargetName>
+    <LinkIncremental>false</LinkIncremental>
+    <GenerateManifest>true</GenerateManifest>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <WarningLevel>Level4</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <OpenMPSupport>true</OpenMPSupport>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <FloatingPointModel>Fast</FloatingPointModel>
+      <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
+      <ExceptionHandling>Sync</ExceptionHandling>
+      <AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
+      <PreprocessorDefinitions>_UNICODE;UNICODE;WIN32;_DEBUG;_LIB;_WIN7_PLATFORM_UPDATE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <PrecompiledHeaderFile>DirectXTexP.h</PrecompiledHeaderFile>
+      <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+    </ClCompile>
+    <Link>
+      <AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <LargeAddressAware>true</LargeAddressAware>
+      <RandomizedBaseAddress>true</RandomizedBaseAddress>
+      <DataExecutionPrevention>true</DataExecutionPrevention>
+      <TargetMachine>MachineX86</TargetMachine>
+      <UACExecutionLevel>AsInvoker</UACExecutionLevel>
+      <DelayLoadDLLs>%(DelayLoadDLLs)</DelayLoadDLLs>
+    </Link>
+    <Manifest>
+      <EnableDPIAwareness>false</EnableDPIAwareness>
+    </Manifest>
+    <PreBuildEvent>
+      <Command>
+      </Command>
+    </PreBuildEvent>
+    <PostBuildEvent>
+      <Command>
+      </Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|X64'">
+    <ClCompile>
+      <WarningLevel>Level4</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <OpenMPSupport>true</OpenMPSupport>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <FloatingPointModel>Fast</FloatingPointModel>
+      <ExceptionHandling>Sync</ExceptionHandling>
+      <AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
+      <PreprocessorDefinitions>_UNICODE;UNICODE;WIN32;_DEBUG;_LIB;_WIN7_PLATFORM_UPDATE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <PrecompiledHeaderFile>DirectXTexP.h</PrecompiledHeaderFile>
+      <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+    </ClCompile>
+    <Link>
+      <AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <LargeAddressAware>true</LargeAddressAware>
+      <RandomizedBaseAddress>true</RandomizedBaseAddress>
+      <DataExecutionPrevention>true</DataExecutionPrevention>
+      <TargetMachine>MachineX64</TargetMachine>
+      <UACExecutionLevel>AsInvoker</UACExecutionLevel>
+      <DelayLoadDLLs>%(DelayLoadDLLs)</DelayLoadDLLs>
+    </Link>
+    <Manifest>
+      <EnableDPIAwareness>false</EnableDPIAwareness>
+    </Manifest>
+    <PreBuildEvent>
+      <Command>
+      </Command>
+    </PreBuildEvent>
+    <PostBuildEvent>
+      <Command>
+      </Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level4</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <OpenMPSupport>true</OpenMPSupport>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <FloatingPointModel>Fast</FloatingPointModel>
+      <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
+      <ExceptionHandling>Sync</ExceptionHandling>
+      <AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
+      <PreprocessorDefinitions>_UNICODE;UNICODE;WIN32;NDEBUG;_LIB;_WIN7_PLATFORM_UPDATE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <PrecompiledHeaderFile>DirectXTexP.h</PrecompiledHeaderFile>
+      <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+    </ClCompile>
+    <Link>
+      <AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Windows</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <LargeAddressAware>true</LargeAddressAware>
+      <RandomizedBaseAddress>true</RandomizedBaseAddress>
+      <DataExecutionPrevention>true</DataExecutionPrevention>
+      <TargetMachine>MachineX86</TargetMachine>
+      <UACExecutionLevel>AsInvoker</UACExecutionLevel>
+      <DelayLoadDLLs>%(DelayLoadDLLs)</DelayLoadDLLs>
+    </Link>
+    <Manifest>
+      <EnableDPIAwareness>false</EnableDPIAwareness>
+    </Manifest>
+    <PreBuildEvent>
+      <Command>
+      </Command>
+    </PreBuildEvent>
+    <PostBuildEvent>
+      <Command>
+      </Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|X64'">
+    <ClCompile>
+      <WarningLevel>Level4</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <OpenMPSupport>true</OpenMPSupport>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <FloatingPointModel>Fast</FloatingPointModel>
+      <ExceptionHandling>Sync</ExceptionHandling>
+      <AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
+      <PreprocessorDefinitions>_UNICODE;UNICODE;WIN32;NDEBUG;_LIB;_WIN7_PLATFORM_UPDATE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <PrecompiledHeaderFile>DirectXTexP.h</PrecompiledHeaderFile>
+      <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+    </ClCompile>
+    <Link>
+      <AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Windows</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <LargeAddressAware>true</LargeAddressAware>
+      <RandomizedBaseAddress>true</RandomizedBaseAddress>
+      <DataExecutionPrevention>true</DataExecutionPrevention>
+      <TargetMachine>MachineX64</TargetMachine>
+      <UACExecutionLevel>AsInvoker</UACExecutionLevel>
+      <DelayLoadDLLs>%(DelayLoadDLLs)</DelayLoadDLLs>
+    </Link>
+    <Manifest>
+      <EnableDPIAwareness>false</EnableDPIAwareness>
+    </Manifest>
+    <PreBuildEvent>
+      <Command>
+      </Command>
+    </PreBuildEvent>
+    <PostBuildEvent>
+      <Command>
+      </Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">
+    <ClCompile>
+      <WarningLevel>Level4</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <OpenMPSupport>true</OpenMPSupport>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <FloatingPointModel>Fast</FloatingPointModel>
+      <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
+      <ExceptionHandling>Sync</ExceptionHandling>
+      <AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
+      <PreprocessorDefinitions>_UNICODE;UNICODE;WIN32;NDEBUG;PROFILE;_LIB;_WIN7_PLATFORM_UPDATE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <PrecompiledHeaderFile>DirectXTexP.h</PrecompiledHeaderFile>
+      <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+    </ClCompile>
+    <Link>
+      <AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Windows</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <LargeAddressAware>true</LargeAddressAware>
+      <RandomizedBaseAddress>true</RandomizedBaseAddress>
+      <DataExecutionPrevention>true</DataExecutionPrevention>
+      <TargetMachine>MachineX86</TargetMachine>
+      <UACExecutionLevel>AsInvoker</UACExecutionLevel>
+      <DelayLoadDLLs>%(DelayLoadDLLs)</DelayLoadDLLs>
+    </Link>
+    <Manifest>
+      <EnableDPIAwareness>false</EnableDPIAwareness>
+    </Manifest>
+    <PreBuildEvent>
+      <Command>
+      </Command>
+    </PreBuildEvent>
+    <PostBuildEvent>
+      <Command>
+      </Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Profile|X64'">
+    <ClCompile>
+      <WarningLevel>Level4</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <OpenMPSupport>true</OpenMPSupport>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <FloatingPointModel>Fast</FloatingPointModel>
+      <ExceptionHandling>Sync</ExceptionHandling>
+      <AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
+      <PreprocessorDefinitions>_UNICODE;UNICODE;WIN32;NDEBUG;PROFILE;_LIB;_WIN7_PLATFORM_UPDATE;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <PrecompiledHeaderFile>DirectXTexP.h</PrecompiledHeaderFile>
+      <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+    </ClCompile>
+    <Link>
+      <AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Windows</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <LargeAddressAware>true</LargeAddressAware>
+      <RandomizedBaseAddress>true</RandomizedBaseAddress>
+      <DataExecutionPrevention>true</DataExecutionPrevention>
+      <TargetMachine>MachineX64</TargetMachine>
+      <UACExecutionLevel>AsInvoker</UACExecutionLevel>
+      <DelayLoadDLLs>%(DelayLoadDLLs)</DelayLoadDLLs>
+    </Link>
+    <Manifest>
+      <EnableDPIAwareness>false</EnableDPIAwareness>
+    </Manifest>
+    <PreBuildEvent>
+      <Command>
+      </Command>
+    </PreBuildEvent>
+    <PostBuildEvent>
+      <Command>
+      </Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemGroup />
+  <ItemGroup>
+    <CLInclude Include="BC.h" />
+    <ClCompile Include="BC.cpp" />
+    <ClCompile Include="BC4BC5.cpp" />
+    <ClCompile Include="BC6HBC7.cpp" />
+    <ClInclude Include="BCDirectCompute.h" />
+    <CLInclude Include="DDS.h" />
+    <ClInclude Include="filters.h" />
+    <CLInclude Include="scoped.h" />
+    <CLInclude Include="DirectXTex.h" />
+    <CLInclude Include="DirectXTexp.h" />
+    <CLInclude Include="DirectXTex.inl" />
+    <ClCompile Include="BCDirectCompute.cpp" />
+    <ClCompile Include="DirectXTexCompress.cpp" />
+    <ClCompile Include="DirectXTexCompressGPU.cpp" />
+    <ClCompile Include="DirectXTexConvert.cpp" />
+    <ClCompile Include="DirectXTexD3D11.cpp" />
+    <ClCompile Include="DirectXTexDDS.cpp" />
+    <ClCompile Include="DirectXTexFlipRotate.cpp" />
+    <ClCompile Include="DirectXTexImage.cpp" />
+    <ClCompile Include="DirectXTexMipMaps.cpp" />
+    <ClCompile Include="DirectXTexMisc.cpp" />
+    <ClCompile Include="DirectXTexNormalMaps.cpp" />
+    <ClCompile Include="DirectXTexPMAlpha.cpp" />
+    <ClCompile Include="DirectXTexResize.cpp" />
+    <ClCompile Include="DirectXTexTGA.cpp" />
+    <ClCompile Include="DirectXTexUtil.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Profile|x64'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="DirectXTexWIC.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+  </ItemGroup>
+  <ItemGroup>
+  </ItemGroup>
+  <ItemGroup>
+  </ItemGroup>
+  <ItemGroup>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets" />
+</Project>

+ 38 - 0
Exporters/FBX/3rdParty/DirectXTex/DirectXTex_Desktop_2013.vcxproj.filters

@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns:atg="http://atg.xbox.com" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Resource Files">
+      <UniqueIdentifier>{8e114980-c1a3-4ada-ad7c-83caadf5daeb}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <CLInclude Include="BC.h" />
+    <ClCompile Include="BC.cpp" />
+    <ClCompile Include="BC4BC5.cpp" />
+    <ClCompile Include="BC6HBC7.cpp" />
+    <CLInclude Include="DDS.h" />
+    <ClInclude Include="filters.h" />
+    <CLInclude Include="scoped.h" />
+    <CLInclude Include="DirectXTex.h" />
+    <CLInclude Include="DirectXTexp.h" />
+    <CLInclude Include="DirectXTex.inl" />
+    <ClCompile Include="DirectXTexCompress.cpp" />
+    <ClCompile Include="DirectXTexConvert.cpp" />
+    <ClCompile Include="DirectXTexD3D11.cpp" />
+    <ClCompile Include="DirectXTexDDS.cpp" />
+    <ClCompile Include="DirectXTexFlipRotate.cpp" />
+    <ClCompile Include="DirectXTexImage.cpp" />
+    <ClCompile Include="DirectXTexMipMaps.cpp" />
+    <ClCompile Include="DirectXTexMisc.cpp" />
+    <ClCompile Include="DirectXTexNormalMaps.cpp" />
+    <ClCompile Include="DirectXTexPMAlpha.cpp" />
+    <ClCompile Include="DirectXTexResize.cpp" />
+    <ClCompile Include="DirectXTexTGA.cpp" />
+    <ClCompile Include="DirectXTexUtil.cpp" />
+    <ClCompile Include="DirectXTexWIC.cpp" />
+    <ClInclude Include="BCDirectCompute.h" />
+    <ClCompile Include="BCDirectCompute.cpp" />
+    <ClCompile Include="DirectXTexCompressGPU.cpp" />
+  </ItemGroup>
+</Project>

+ 424 - 0
Exporters/FBX/3rdParty/DirectXTex/Filters.h

@@ -0,0 +1,424 @@
+//-------------------------------------------------------------------------------------
+// filters.h
+//  
+// Utility header with helpers for implementing image filters
+//
+// 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.
+//-------------------------------------------------------------------------------------
+
+#if defined(_MSC_VER) && (_MSC_VER > 1000)
+#pragma once
+#endif
+
+#include <directxmath.h>
+#include <directxpackedvector.h>
+
+#include <memory>
+
+#include "scoped.h"
+
+namespace DirectX
+{
+
+//-------------------------------------------------------------------------------------
+// Box filtering helpers
+//-------------------------------------------------------------------------------------
+
+XMGLOBALCONST XMVECTORF32 g_boxScale = { 0.25f, 0.25f, 0.25f, 0.25f };
+XMGLOBALCONST XMVECTORF32 g_boxScale3D = { 0.125f, 0.125f, 0.125f, 0.125f };
+
+#define AVERAGE4( res, p0, p1, p2, p3 ) \
+{ \
+    XMVECTOR v = XMVectorAdd( (p0), (p1) ); \
+    v = XMVectorAdd( v, (p2) ); \
+    v = XMVectorAdd( v, (p3) ); \
+    res = XMVectorMultiply( v, g_boxScale ); \
+}
+
+#define AVERAGE8( res, p0, p1, p2, p3, p4, p5, p6, p7) \
+{ \
+    XMVECTOR v = XMVectorAdd( (p0), (p1) ); \
+    v = XMVectorAdd( v, (p2) ); \
+    v = XMVectorAdd( v, (p3) ); \
+    v = XMVectorAdd( v, (p4) ); \
+    v = XMVectorAdd( v, (p5) ); \
+    v = XMVectorAdd( v, (p6) ); \
+    v = XMVectorAdd( v, (p7) ); \
+    res = XMVectorMultiply( v, g_boxScale3D ); \
+}
+
+
+//-------------------------------------------------------------------------------------
+// Linear filtering helpers
+//-------------------------------------------------------------------------------------
+
+struct LinearFilter
+{
+    size_t  u0;
+    float   weight0;
+    size_t  u1;
+    float   weight1;
+};
+
+inline void _CreateLinearFilter( _In_ size_t source, _In_ size_t dest, _In_ bool wrap, _Out_writes_(dest) LinearFilter* lf )
+{
+    assert( source > 0 );
+    assert( dest > 0 );
+    assert( lf != 0 );
+
+    float scale = float(source) / float(dest);
+
+    // Mirror is the same case as clamp for linear
+
+    for( size_t u = 0; u < dest; ++u )
+    {
+        float srcB = ( float(u) + 0.5f ) * scale + 0.5f;
+
+        ptrdiff_t isrcB = ptrdiff_t(srcB);
+        ptrdiff_t isrcA = isrcB - 1;
+        
+        if ( isrcA < 0 )
+        {
+            isrcA = ( wrap ) ? ( source - 1) : 0;
+        }
+
+        if ( size_t(isrcB) >= source )
+        {
+            isrcB = ( wrap ) ? 0 : ( source - 1);
+        }
+
+        float weight = 1.0f + float(isrcB) - srcB;
+
+        auto& entry = lf[ u ];
+        entry.u0 = size_t(isrcA);
+        entry.weight0 = weight;
+
+        entry.u1 = size_t(isrcB);
+        entry.weight1 = 1.0f - weight;
+    }
+}
+
+#define BILINEAR_INTERPOLATE( res, x, y, r0, r1 ) \
+    res = ( y.weight0 * ( (r0)[ x.u0 ] * x.weight0 + (r0)[ x.u1 ] * x.weight1 ) ) \
+          + ( y.weight1 * ( (r1)[ x.u0 ] * x.weight0 + (r1)[ x.u1 ] * x.weight1 ) )
+
+#define TRILINEAR_INTERPOLATE( res, x, y, z, r0, r1, r2, r3 ) \
+    res = ( z.weight0 * ( ( y.weight0 * ( (r0)[ x.u0 ] * x.weight0 + (r0)[ x.u1 ] * x.weight1 ) ) \
+                          + ( y.weight1 * ( (r1)[ x.u0 ] * x.weight0 + (r1)[ x.u1 ] * x.weight1 ) ) ) ) \
+          + ( z.weight1 * ( ( y.weight0 * ( (r2)[ x.u0 ] * x.weight0 + (r2)[ x.u1 ] * x.weight1 ) ) \
+                             + ( y.weight1 * ( (r3)[ x.u0 ] * x.weight0 + (r3)[ x.u1 ] * x.weight1 ) ) ) )
+
+
+//-------------------------------------------------------------------------------------
+// Cubic filtering helpers
+//-------------------------------------------------------------------------------------
+
+XMGLOBALCONST XMVECTORF32 g_cubicThird = { 1.f/3.f, 1.f/3.f, 1.f/3.f, 1.f/3.f }; 
+XMGLOBALCONST XMVECTORF32 g_cubicSixth = { 1.f/6.f, 1.f/6.f, 1.f/6.f, 1.f/6.f }; 
+XMGLOBALCONST XMVECTORF32 g_cubicHalf = { 1.f/2.f, 1.f/2.f, 1.f/2.f, 1.f/2.f };
+
+inline ptrdiff_t bounduvw( ptrdiff_t u, ptrdiff_t maxu, bool wrap, bool mirror )
+{
+    if ( wrap )
+    {
+        if ( u < 0 )
+        {
+            u = maxu + u + 1;
+        }
+        else if ( u > maxu )
+        {
+            u = u - maxu - 1;
+        }
+    }
+    else if ( mirror )
+    {
+        if ( u < 0 )
+        {
+            u = ( -u ) - 1;
+        }
+        else if ( u > maxu )
+        {
+            u = maxu - (u - maxu - 1);
+        }
+    }
+
+    // Handles clamp, but also a safety factor for degenerate images for wrap/mirror
+    u = std::min<ptrdiff_t>( u, maxu );
+    u = std::max<ptrdiff_t>( u, 0 );
+
+    return u;
+}
+
+struct CubicFilter
+{
+    size_t  u0;
+    size_t  u1;
+    size_t  u2;
+    size_t  u3;
+    float   x;
+};
+
+inline void _CreateCubicFilter( _In_ size_t source, _In_ size_t dest, _In_ bool wrap, _In_ bool mirror, _Out_writes_(dest) CubicFilter* cf )
+{
+    assert( source > 0 );
+    assert( dest > 0 );
+    assert( cf != 0 );
+
+    float scale = float(source) / float(dest);
+
+    for( size_t u = 0; u < dest; ++u )
+    {
+        float srcB = ( float(u) + 0.5f ) * scale - 0.5f;
+
+        ptrdiff_t isrcB = bounduvw( ptrdiff_t(srcB), source - 1, wrap, mirror );
+        ptrdiff_t isrcA = bounduvw( isrcB - 1, source - 1, wrap, mirror );
+        ptrdiff_t isrcC = bounduvw( isrcB + 1, source - 1, wrap, mirror );
+        ptrdiff_t isrcD = bounduvw( isrcB + 2, source - 1, wrap, mirror );
+
+        auto& entry = cf[ u ];
+        entry.u0 = size_t(isrcA);
+        entry.u1 = size_t(isrcB);
+        entry.u2 = size_t(isrcC);
+        entry.u3 = size_t(isrcD);
+
+        float x = srcB - float(isrcB);
+        entry.x = x;
+    }
+}
+
+#define CUBIC_INTERPOLATE( res, dx, p0, p1, p2, p3 ) \
+{ \
+    XMVECTOR a0 = (p1); \
+    XMVECTOR d0 = (p0) - a0; \
+    XMVECTOR d2 = (p2) - a0; \
+    XMVECTOR d3 = (p3) - a0; \
+    XMVECTOR a1 = d2 - g_cubicThird*d0 - g_cubicSixth*d3; \
+    XMVECTOR a2 = g_cubicHalf*d0 + g_cubicHalf*d2; \
+    XMVECTOR a3 = g_cubicSixth*d3 - g_cubicSixth*d0 - g_cubicHalf*d2;  \
+    XMVECTOR vdx = XMVectorReplicate( dx ); \
+    XMVECTOR vdx2 = vdx * vdx; \
+    XMVECTOR vdx3 = vdx2 * vdx; \
+    res = a0 + a1*vdx + a2*vdx2 + a3*vdx3; \
+}
+
+
+//-------------------------------------------------------------------------------------
+// Triangle filtering helpers
+//-------------------------------------------------------------------------------------
+
+namespace TriangleFilter
+{
+    struct FilterTo
+    {
+        size_t      u;
+        float       weight;
+    };
+
+    struct FilterFrom
+    {
+        size_t      count;
+        size_t      sizeInBytes;
+        FilterTo    to[1]; // variable-sized array
+    };
+
+    struct Filter
+    {
+        size_t      sizeInBytes;
+        size_t      totalSize;
+        FilterFrom  from[1]; // variable-sized array
+    };
+
+    struct TriangleRow
+    {
+        size_t                      remaining;
+        TriangleRow*                next;
+        ScopedAlignedArrayXMVECTOR  scanline;
+
+        TriangleRow() : remaining(0), next(nullptr) {}
+    };
+
+    static const size_t TF_FILTER_SIZE = sizeof(Filter) - sizeof(FilterFrom);
+    static const size_t TF_FROM_SIZE = sizeof(FilterFrom) - sizeof(FilterTo);
+    static const size_t TF_TO_SIZE = sizeof(FilterTo);
+
+    static const float TF_EPSILON = 0.00001f;
+
+    inline HRESULT _Create( _In_ size_t source, _In_ size_t dest, _In_ bool wrap, _Inout_ std::unique_ptr<Filter>& tf )
+    {
+        assert( source > 0 );
+        assert( dest > 0 );
+
+        float scale = float(dest) / float(source);
+        float scaleInv = 0.5f / scale;
+
+        // Determine storage required for filter and allocate memory if needed
+        size_t totalSize = TF_FILTER_SIZE + TF_FROM_SIZE + TF_TO_SIZE;
+        float repeat = (wrap) ? 1.f : 0.f;
+
+        for( size_t u = 0; u < source; ++u )
+        {
+            float src = float(u) - 0.5f;
+            float destMin = src * scale;
+            float destMax = destMin + scale;
+
+            totalSize += TF_FROM_SIZE + TF_TO_SIZE + size_t( destMax - destMin + repeat + 1.f ) * TF_TO_SIZE * 2;
+        }
+
+        uint8_t* pFilter = nullptr;
+
+        if ( tf )
+        {
+            // See if existing filter memory block is large enough to reuse
+            if ( tf->totalSize >= totalSize )
+            {
+                pFilter = reinterpret_cast<uint8_t*>( tf.get() );
+            }
+            else
+            {
+                // Need to reallocate filter memory block
+                tf.reset( nullptr );
+            }
+        }
+
+        if ( !tf )
+        {
+            // Allocate filter memory block
+            pFilter = new (std::nothrow) uint8_t[ totalSize ];
+            if ( !pFilter )
+                return E_OUTOFMEMORY;
+
+            tf.reset( reinterpret_cast<Filter*>( pFilter ) );
+            tf->totalSize = totalSize;
+        }
+
+        assert( pFilter != 0 );
+
+        // Filter setup
+        size_t sizeInBytes = TF_FILTER_SIZE;
+        size_t accumU = 0;
+        float accumWeight = 0.f;
+
+        for( size_t u = 0; u < source; ++u )
+        {
+            // Setup from entry
+            size_t sizeFrom = sizeInBytes;
+            auto pFrom = reinterpret_cast<FilterFrom*>( pFilter + sizeInBytes );
+            sizeInBytes += TF_FROM_SIZE;
+
+            if ( sizeInBytes > totalSize )
+                return E_FAIL;
+
+            size_t toCount = 0;
+
+            // Perform two passes to capture the influences from both sides
+            for( size_t j = 0; j < 2; ++j )
+            {
+                float src = float( u + j ) - 0.5f;
+
+                float destMin = src * scale;
+                float destMax = destMin + scale;
+
+                if ( !wrap )
+                {
+                    // Clamp
+                    if ( destMin < 0.f )
+                        destMin = 0.f;
+                    if ( destMax > float(dest) )
+                        destMax = float(dest);
+                }
+
+                for( auto k = static_cast<ptrdiff_t>( floorf( destMin ) ); float(k) < destMax; ++k )
+                {
+                    float d0 = float(k);
+                    float d1 = d0 + 1.f;
+
+                    size_t u0;
+                    if ( k < 0 )
+                    {
+                        // Handle wrap
+                        u0 = size_t( k + ptrdiff_t(dest) );
+                    }
+                    else if ( k >= ptrdiff_t(dest) )
+                    {
+                        // Handle wrap
+                        u0 = size_t( k - ptrdiff_t(dest) );
+                    }
+                    else
+                    {
+                        u0 = size_t( k );
+                    }
+
+                    // Save previous accumulated weight (if any)
+                    if ( u0 != accumU )
+                    {
+                        if ( accumWeight > TF_EPSILON )
+                        {
+                            auto pTo = reinterpret_cast<FilterTo*>( pFilter + sizeInBytes );
+                            sizeInBytes += TF_TO_SIZE;
+                            ++toCount;
+
+                            if ( sizeInBytes > totalSize )
+                                return E_FAIL;
+
+                            pTo->u = accumU;
+                            pTo->weight = accumWeight;
+                        }
+
+                        accumWeight = 0.f;
+                        accumU = u0;
+                    }
+
+                    // Clip destination
+                    if ( d0 < destMin )
+                        d0 = destMin;
+                    if ( d1 > destMax )
+                        d1 = destMax;
+
+                    // Calculate average weight over destination pixel
+
+                    float weight;
+                    if ( !wrap && src < 0.f )
+                        weight = 1.f;
+                    else if ( !wrap && ( ( src + 1.f ) >= float(source) ) )
+                        weight = 0.f;
+                    else
+                        weight = (d0 + d1) * scaleInv - src;
+
+                    accumWeight += (d1 - d0) * ( j ? (1.f - weight) : weight );
+                }
+            }
+
+            // Store accumulated weight
+            if ( accumWeight > TF_EPSILON )
+            {
+                auto pTo = reinterpret_cast<FilterTo*>( pFilter + sizeInBytes );
+                sizeInBytes += TF_TO_SIZE;
+                ++toCount;
+
+                if ( sizeInBytes > totalSize )
+                    return E_FAIL;
+
+                pTo->u = accumU;
+                pTo->weight = accumWeight;
+            }
+
+            accumWeight = 0.f;
+
+            // Finalize from entry
+            pFrom->count = toCount;
+            pFrom->sizeInBytes = sizeInBytes - sizeFrom;
+        }
+
+        tf->sizeInBytes = sizeInBytes;
+
+        return S_OK;
+    }
+
+}; // namespace
+
+}; // namespace

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 2566 - 0
Exporters/FBX/3rdParty/DirectXTex/Shaders/BC6HEncode.hlsl


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1907 - 0
Exporters/FBX/3rdParty/DirectXTex/Shaders/BC7Encode.hlsl


+ 37 - 0
Exporters/FBX/3rdParty/DirectXTex/Shaders/CompileShaders.cmd

@@ -0,0 +1,37 @@
+@echo off
+rem THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
+rem ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
+rem THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
+rem PARTICULAR PURPOSE.
+rem
+rem Copyright (c) Microsoft Corporation. All rights reserved.
+
+setlocal
+set error=0
+
+call :CompileShader BC7Encode TryMode456CS
+call :CompileShader BC7Encode TryMode137CS
+call :CompileShader BC7Encode TryMode02CS
+call :CompileShader BC7Encode EncodeBlockCS
+
+call :CompileShader BC6HEncode TryModeG10CS
+call :CompileShader BC6HEncode TryModeLE10CS
+call :CompileShader BC6HEncode EncodeBlockCS
+
+echo.
+
+if %error% == 0 (
+    echo Shaders compiled ok
+) else (
+    echo There were shader compilation errors!
+)
+
+endlocal
+exit /b
+
+:CompileShader
+set fxc=fxc /nologo %1.hlsl /Tcs_4_0 /Zpc /Qstrip_reflect /Qstrip_debug /E%2 /FhCompiled\%1_%2.inc /Vn%1_%2
+echo.
+echo %fxc%
+%fxc% || set error=1
+exit /b

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 22215 - 0
Exporters/FBX/3rdParty/DirectXTex/Shaders/Compiled/BC6HEncode_EncodeBlockCS.inc


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 3375 - 0
Exporters/FBX/3rdParty/DirectXTex/Shaders/Compiled/BC6HEncode_TryModeG10CS.inc


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 5103 - 0
Exporters/FBX/3rdParty/DirectXTex/Shaders/Compiled/BC6HEncode_TryModeLE10CS.inc


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 10152 - 0
Exporters/FBX/3rdParty/DirectXTex/Shaders/Compiled/BC7Encode_EncodeBlockCS.inc


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 3824 - 0
Exporters/FBX/3rdParty/DirectXTex/Shaders/Compiled/BC7Encode_TryMode02CS.inc


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 3962 - 0
Exporters/FBX/3rdParty/DirectXTex/Shaders/Compiled/BC7Encode_TryMode137CS.inc


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 3027 - 0
Exporters/FBX/3rdParty/DirectXTex/Shaders/Compiled/BC7Encode_TryMode456CS.inc


+ 34 - 0
Exporters/FBX/3rdParty/DirectXTex/scoped.h

@@ -0,0 +1,34 @@
+//-------------------------------------------------------------------------------------
+// scoped.h
+//  
+// Utility header with helper classes for exception-safe handling of resources
+//
+// 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.
+//-------------------------------------------------------------------------------------
+
+#if defined(_MSC_VER) && (_MSC_VER > 1000)
+#pragma once
+#endif
+
+#include <assert.h>
+#include <memory>
+#include <malloc.h>
+
+//---------------------------------------------------------------------------------
+struct aligned_deleter { void operator()(void* p) { _aligned_free(p); } };
+
+typedef std::unique_ptr<float, aligned_deleter> ScopedAlignedArrayFloat;
+
+typedef std::unique_ptr<DirectX::XMVECTOR, aligned_deleter> ScopedAlignedArrayXMVECTOR;
+
+//---------------------------------------------------------------------------------
+struct handle_closer { void operator()(HANDLE h) { assert(h != INVALID_HANDLE_VALUE); if (h) CloseHandle(h); } };
+
+typedef public std::unique_ptr<void, handle_closer> ScopedHandle;
+
+inline HANDLE safe_handle( HANDLE h ) { return (h == INVALID_HANDLE_VALUE) ? 0 : h; }

+ 273 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk.h

@@ -0,0 +1,273 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxsdk.h
+#ifndef _FBXSDK_H_
+#define _FBXSDK_H_
+
+/**
+  * \mainpage FBX SDK Reference
+  * <p>
+  * \section welcome Welcome to the FBX SDK Reference
+  * The FBX SDK Reference contains reference information on every header file, 
+  * namespace, class, method, enum, typedef, variable, and other C++ elements 
+  * that comprise the FBX software development kit (SDK).
+  * <p>
+  * The FBX SDK Reference is organized into the following sections:
+  * <ul><li>Class List: an alphabetical list of FBX SDK classes
+  *     <li>Class Hierarchy: a textual representation of the FBX SDK class structure
+  *     <li>Graphical Class Hierarchy: a graphical representation of the FBX SDK class structure
+  *     <li>File List: an alphabetical list of all documented header files</ul>
+  * <p>
+  * \section otherdocumentation Other Documentation
+  * Apart from this reference guide, an FBX SDK Programming Guide and many FBX 
+  * SDK examples are also provided.
+  * <p>
+  * \section aboutFBXSDK About the FBX SDK
+  * The FBX SDK is a C++ software development kit (SDK) that lets you import 
+  * and export 3D scenes using the Autodesk FBX file format. The FBX SDK 
+  * reads FBX files created with FiLMBOX version 2.5 and later and writes FBX 
+  * files compatible with MotionBuilder version 6.0 and up. 
+  */
+
+#pragma pack(push, 8)	//FBXSDK is compiled with default value (8)
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#ifndef FBXSDK_NAMESPACE_USING
+	#define FBXSDK_NAMESPACE_USING 1
+#endif
+
+//---------------------------------------------------------------------------------------
+//Core Base Includes
+#include <fbxsdk/core/base/fbxarray.h>
+#include <fbxsdk/core/base/fbxbitset.h>
+#include <fbxsdk/core/base/fbxcharptrset.h>
+#include <fbxsdk/core/base/fbxcontainerallocators.h>
+#include <fbxsdk/core/base/fbxdynamicarray.h>
+#include <fbxsdk/core/base/fbxstatus.h>
+#include <fbxsdk/core/base/fbxfile.h>
+#ifndef FBXSDK_ENV_WINSTORE
+	#include <fbxsdk/core/base/fbxfolder.h>
+#endif
+#include <fbxsdk/core/base/fbxhashmap.h>
+#include <fbxsdk/core/base/fbxintrusivelist.h>
+#include <fbxsdk/core/base/fbxmap.h>
+#include <fbxsdk/core/base/fbxmemorypool.h>
+#include <fbxsdk/core/base/fbxpair.h>
+#include <fbxsdk/core/base/fbxset.h>
+#include <fbxsdk/core/base/fbxstring.h>
+#include <fbxsdk/core/base/fbxstringlist.h>
+#include <fbxsdk/core/base/fbxtime.h>
+#include <fbxsdk/core/base/fbxtimecode.h>
+#include <fbxsdk/core/base/fbxutils.h>
+
+//---------------------------------------------------------------------------------------
+//Core Math Includes
+#include <fbxsdk/core/math/fbxmath.h>
+#include <fbxsdk/core/math/fbxdualquaternion.h>
+#include <fbxsdk/core/math/fbxmatrix.h>
+#include <fbxsdk/core/math/fbxquaternion.h>
+#include <fbxsdk/core/math/fbxvector2.h>
+#include <fbxsdk/core/math/fbxvector4.h>
+
+//---------------------------------------------------------------------------------------
+//Core Sync Includes
+#ifndef FBXSDK_ENV_WINSTORE
+	#include <fbxsdk/core/sync/fbxatomic.h>
+	#include <fbxsdk/core/sync/fbxclock.h>
+	#include <fbxsdk/core/sync/fbxsync.h>
+	#include <fbxsdk/core/sync/fbxthread.h>
+#endif /* !FBXSDK_ENV_WINSTORE */
+
+//---------------------------------------------------------------------------------------
+//Core Includes
+#include <fbxsdk/core/fbxclassid.h>
+#include <fbxsdk/core/fbxconnectionpoint.h>
+#include <fbxsdk/core/fbxdatatypes.h>
+#ifndef FBXSDK_ENV_WINSTORE
+	#include <fbxsdk/core/fbxmodule.h>
+	#include <fbxsdk/core/fbxloadingstrategy.h>
+#endif /* !FBXSDK_ENV_WINSTORE */
+#include <fbxsdk/core/fbxmanager.h>
+#include <fbxsdk/core/fbxobject.h>
+#include <fbxsdk/core/fbxperipheral.h>
+#ifndef FBXSDK_ENV_WINSTORE
+	#include <fbxsdk/core/fbxplugin.h>
+	#include <fbxsdk/core/fbxplugincontainer.h>
+#endif /* !FBXSDK_ENV_WINSTORE */
+#include <fbxsdk/core/fbxproperty.h>
+#include <fbxsdk/core/fbxpropertydef.h>
+#include <fbxsdk/core/fbxpropertyhandle.h>
+#include <fbxsdk/core/fbxpropertypage.h>
+#include <fbxsdk/core/fbxpropertytypes.h>
+#include <fbxsdk/core/fbxquery.h>
+#include <fbxsdk/core/fbxqueryevent.h>
+#ifndef FBXSDK_ENV_WINSTORE
+	#include <fbxsdk/core/fbxscopedloadingdirectory.h>
+	#include <fbxsdk/core/fbxscopedloadingfilename.h>
+#endif /* !FBXSDK_ENV_WINSTORE */
+#include <fbxsdk/core/fbxxref.h>
+
+//---------------------------------------------------------------------------------------
+//File I/O Includes
+#include <fbxsdk/fileio/fbxexporter.h>
+#include <fbxsdk/fileio/fbxexternaldocreflistener.h>
+#include <fbxsdk/fileio/fbxfiletokens.h>
+#include <fbxsdk/fileio/fbxglobalcamerasettings.h>
+#include <fbxsdk/fileio/fbxgloballightsettings.h>
+#include <fbxsdk/fileio/fbxgobo.h>
+#include <fbxsdk/fileio/fbximporter.h>
+#include <fbxsdk/fileio/fbxiobase.h>
+#include <fbxsdk/fileio/fbxiopluginregistry.h>
+#include <fbxsdk/fileio/fbxiosettings.h>
+#include <fbxsdk/fileio/fbxstatisticsfbx.h>
+#include <fbxsdk/fileio/fbxstatistics.h>
+
+//---------------------------------------------------------------------------------------
+//Scene Includes
+#include <fbxsdk/scene/fbxcollection.h>
+#include <fbxsdk/scene/fbxcollectionexclusive.h>
+#include <fbxsdk/scene/fbxcontainer.h>
+#include <fbxsdk/scene/fbxcontainertemplate.h>
+#include <fbxsdk/scene/fbxdisplaylayer.h>
+#include <fbxsdk/scene/fbxdocument.h>
+#include <fbxsdk/scene/fbxdocumentinfo.h>
+#include <fbxsdk/scene/fbxenvironment.h>
+#include <fbxsdk/scene/fbxgroupname.h>
+#include <fbxsdk/scene/fbxlibrary.h>
+#include <fbxsdk/scene/fbxobjectmetadata.h>
+#include <fbxsdk/scene/fbxpose.h>
+#include <fbxsdk/scene/fbxreference.h>
+#include <fbxsdk/scene/fbxscene.h>
+#include <fbxsdk/scene/fbxselectionset.h>
+#include <fbxsdk/scene/fbxselectionnode.h>
+#include <fbxsdk/scene/fbxtakeinfo.h>
+#include <fbxsdk/scene/fbxthumbnail.h>
+#include <fbxsdk/scene/fbxvideo.h>
+
+//---------------------------------------------------------------------------------------
+//Scene Animation Includes
+#include <fbxsdk/scene/animation/fbxanimcurve.h>
+#include <fbxsdk/scene/animation/fbxanimcurvebase.h>
+#include <fbxsdk/scene/animation/fbxanimcurvefilters.h>
+#include <fbxsdk/scene/animation/fbxanimcurvenode.h>
+#include <fbxsdk/scene/animation/fbxanimevalclassic.h>
+#include <fbxsdk/scene/animation/fbxanimevalstate.h>
+#include <fbxsdk/scene/animation/fbxanimevaluator.h>
+#include <fbxsdk/scene/animation/fbxanimlayer.h>
+#include <fbxsdk/scene/animation/fbxanimstack.h>
+#include <fbxsdk/scene/animation/fbxanimutilities.h>
+
+//---------------------------------------------------------------------------------------
+//Scene Constraint Includes
+#include <fbxsdk/scene/constraint/fbxcharacternodename.h>
+#include <fbxsdk/scene/constraint/fbxcharacter.h>
+#include <fbxsdk/scene/constraint/fbxcharacterpose.h>
+#include <fbxsdk/scene/constraint/fbxconstraint.h>
+#include <fbxsdk/scene/constraint/fbxconstraintaim.h>
+#include <fbxsdk/scene/constraint/fbxconstraintcustom.h>
+#include <fbxsdk/scene/constraint/fbxconstraintparent.h>
+#include <fbxsdk/scene/constraint/fbxconstraintposition.h>
+#include <fbxsdk/scene/constraint/fbxconstraintrotation.h>
+#include <fbxsdk/scene/constraint/fbxconstraintscale.h>
+#include <fbxsdk/scene/constraint/fbxconstraintsinglechainik.h>
+#include <fbxsdk/scene/constraint/fbxconstraintutils.h>
+#include <fbxsdk/scene/constraint/fbxcontrolset.h>
+#include <fbxsdk/scene/constraint/fbxhik2fbxcharacter.h>
+
+//---------------------------------------------------------------------------------------
+//Scene Geometry Includes
+#include <fbxsdk/scene/geometry/fbxblendshape.h>
+#include <fbxsdk/scene/geometry/fbxblendshapechannel.h>
+#include <fbxsdk/scene/geometry/fbxcache.h>
+#include <fbxsdk/scene/geometry/fbxcachedeffect.h>
+#include <fbxsdk/scene/geometry/fbxcamera.h>
+#include <fbxsdk/scene/geometry/fbxcamerastereo.h>
+#include <fbxsdk/scene/geometry/fbxcameraswitcher.h>
+#include <fbxsdk/scene/geometry/fbxcluster.h>
+#include <fbxsdk/scene/geometry/fbxdeformer.h>
+#include <fbxsdk/scene/geometry/fbxgenericnode.h>
+#include <fbxsdk/scene/geometry/fbxgeometry.h>
+#include <fbxsdk/scene/geometry/fbxgeometrybase.h>
+#include <fbxsdk/scene/geometry/fbxgeometryweightedmap.h>
+#include <fbxsdk/scene/geometry/fbxlight.h>
+#include <fbxsdk/scene/geometry/fbxlimitsutilities.h>
+#include <fbxsdk/scene/geometry/fbxline.h>
+#include <fbxsdk/scene/geometry/fbxlodgroup.h>
+#include <fbxsdk/scene/geometry/fbxmarker.h>
+#include <fbxsdk/scene/geometry/fbxmesh.h>
+#include <fbxsdk/scene/geometry/fbxnode.h>
+#include <fbxsdk/scene/geometry/fbxnodeattribute.h>
+#include <fbxsdk/scene/geometry/fbxnull.h>
+#include <fbxsdk/scene/geometry/fbxnurbs.h>
+#include <fbxsdk/scene/geometry/fbxnurbscurve.h>
+#include <fbxsdk/scene/geometry/fbxnurbssurface.h>
+#include <fbxsdk/scene/geometry/fbxopticalreference.h>
+#include <fbxsdk/scene/geometry/fbxpatch.h>
+#include <fbxsdk/scene/geometry/fbxproceduralgeometry.h>
+#include <fbxsdk/scene/geometry/fbxshape.h>
+#include <fbxsdk/scene/geometry/fbxskeleton.h>
+#include <fbxsdk/scene/geometry/fbxskin.h>
+#include <fbxsdk/scene/geometry/fbxsubdeformer.h>
+#include <fbxsdk/scene/geometry/fbxsubdiv.h>
+#include <fbxsdk/scene/geometry/fbxtrimnurbssurface.h>
+#include <fbxsdk/scene/geometry/fbxvertexcachedeformer.h>
+#include <fbxsdk/scene/geometry/fbxweightedmapping.h>
+
+//---------------------------------------------------------------------------------------
+//Scene Shading Includes
+#include <fbxsdk/scene/shading/fbxshadingconventions.h>
+#include <fbxsdk/scene/shading/fbxbindingsentryview.h>
+#include <fbxsdk/scene/shading/fbxbindingtable.h>
+#include <fbxsdk/scene/shading/fbxbindingtableentry.h>
+#include <fbxsdk/scene/shading/fbxbindingoperator.h>
+#include <fbxsdk/scene/shading/fbxconstantentryview.h>
+#include <fbxsdk/scene/shading/fbxentryview.h>
+#include <fbxsdk/scene/shading/fbxfiletexture.h>
+#include <fbxsdk/scene/shading/fbximplementation.h>
+#include <fbxsdk/scene/shading/fbximplementationfilter.h>
+#include <fbxsdk/scene/shading/fbximplementationutils.h>
+#include <fbxsdk/scene/shading/fbxlayeredtexture.h>
+#include <fbxsdk/scene/shading/fbxoperatorentryview.h>
+#include <fbxsdk/scene/shading/fbxproceduraltexture.h>
+#include <fbxsdk/scene/shading/fbxpropertyentryview.h>
+#include <fbxsdk/scene/shading/fbxsemanticentryview.h>
+#include <fbxsdk/scene/shading/fbxsurfacelambert.h>
+#include <fbxsdk/scene/shading/fbxsurfacematerial.h>
+#include <fbxsdk/scene/shading/fbxsurfacephong.h>
+#include <fbxsdk/scene/shading/fbxtexture.h>
+
+//---------------------------------------------------------------------------------------
+//Utilities Includes
+#include <fbxsdk/utils/fbxdeformationsevaluator.h>
+#include <fbxsdk/utils/fbxprocessor.h>
+#include <fbxsdk/utils/fbxprocessorxref.h>
+#include <fbxsdk/utils/fbxprocessorxrefuserlib.h>
+#include <fbxsdk/utils/fbxprocessorshaderdependency.h>
+#include <fbxsdk/utils/fbxclonemanager.h>
+#include <fbxsdk/utils/fbxgeometryconverter.h>
+#include <fbxsdk/utils/fbxmanipulators.h>
+#include <fbxsdk/utils/fbxmaterialconverter.h>
+#include <fbxsdk/utils/fbxrenamingstrategyfbx5.h>
+#include <fbxsdk/utils/fbxrenamingstrategyfbx6.h>
+#include <fbxsdk/utils/fbxrenamingstrategyutilities.h>
+#include <fbxsdk/utils/fbxrootnodeutility.h>
+#include <fbxsdk/utils/fbxusernotification.h>
+
+//---------------------------------------------------------------------------------------
+#if defined(FBXSDK_NAMESPACE) && (FBXSDK_NAMESPACE_USING == 1)
+	using namespace FBXSDK_NAMESPACE;
+#endif
+
+#pragma pack(pop)
+
+#endif /* _FBXSDK_H_ */

+ 419 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/arch/fbxalloc.h

@@ -0,0 +1,419 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+/** \file fbxalloc.h
+  * Allocation functions definition.
+  *
+  * It is possible to override memory allocation functions throughout the FBX SDK by
+  * providing system memory allocation functions using the handler set functions below.
+  * The Microsoft Windows implementation in debug mode allows to specify where the
+  * allocations happen by providing the standard block type, file name and line number.
+  */
+#ifndef _FBXSDK_CORE_ARCH_ALLOC_H_
+#define _FBXSDK_CORE_ARCH_ALLOC_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#if defined(_DEBUG) && defined(FBXSDK_ENV_WIN)
+	#include <crtdbg.h>
+#endif
+
+#if defined(FBXSDK_ENV_MAC)
+	#include <malloc/malloc.h>
+#else
+	#include <malloc.h>
+#endif
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+#if defined(FBXSDK_CPU_32) && !defined(FBXSDK_ENV_IOS)
+	#define FBXSDK_MEMORY_ALIGNMENT ((size_t)8U)
+#else
+	#define FBXSDK_MEMORY_ALIGNMENT ((size_t)16U)
+#endif
+
+#define FBXSDK_MEMORY_COPY(dst, src, size) {memcpy(dst,src,size);}
+
+typedef void*	(*FbxMallocProc)(size_t);			//! Function pointer signature used to replace "malloc"
+typedef void*	(*FbxCallocProc)(size_t, size_t);	//! Function pointer signature used to replace "calloc"
+typedef void*	(*FbxReallocProc)(void*, size_t);	//! Function pointer signature used to replace "realloc"
+typedef void	(*FbxFreeProc)(void*);				//! Function pointer signature used to replace "free"
+
+/** Set the global memory allocation function used internally by the FBX SDK.
+* \param pHandler Function pointer that implements the necessary procedure to allocate memory in the system. */
+FBXSDK_DLL void FbxSetMallocHandler(FbxMallocProc pHandler);
+
+/** Set the global zero'd memory allocation function used internally by the FBX SDK.
+* \param pHandler Function pointer that implements the necessary procedure to allocate zero'd memory in the system. */
+FBXSDK_DLL void FbxSetCallocHandler(FbxCallocProc pHandler);
+
+/** Set the global memory re-allocation function used internally by the FBX SDK.
+* \param pHandler Function pointer that implements the necessary procedure to re-allocate memory in the system. */
+FBXSDK_DLL void FbxSetReallocHandler(FbxReallocProc pHandler);
+
+/** Set the global memory freeing function used internally by the FBX SDK.
+* \param pHandler Function pointer that implements the necessary procedure to free memory in the system. */
+FBXSDK_DLL void FbxSetFreeHandler(FbxFreeProc pHandler);
+
+/** Get the global memory allocation function used internally by the FBX SDK.
+* \return pHandler Function pointer on FBX's internal malloc */
+FBXSDK_DLL FbxMallocProc FbxGetMallocHandler();
+
+/** Get the global zero'd memory allocation function used internally by the FBX SDK.
+* \return pHandler Function pointer on FBX's internal calloc */
+FBXSDK_DLL FbxCallocProc FbxGetCallocHandler();
+
+/** Get the global memory re-allocation function used internally by the FBX SDK.
+* \return pHandler Function pointer on FBX's internal realloc */
+FBXSDK_DLL FbxReallocProc FbxGetReallocHandler();
+
+/** Get the global memory freeing function used internally by the FBX SDK.
+* \return pHandler Function pointer on FBX's internal free */
+FBXSDK_DLL FbxFreeProc FbxGetFreeHandler();
+
+/** Get the default global memory allocation function used internally by the FBX SDK.
+* \return pHandler Function pointer on FBX's internal malloc */
+FBXSDK_DLL FbxMallocProc FbxGetDefaultMallocHandler();
+
+/** Get the default global zero'd memory allocation function used internally by the FBX SDK.
+* \return pHandler Function pointer on FBX's internal calloc */
+FBXSDK_DLL FbxCallocProc FbxGetDefaultCallocHandler();
+
+/** Get the default global memory re-allocation function used internally by the FBX SDK.
+* \return pHandler Function pointer on FBX's internal realloc */
+FBXSDK_DLL FbxReallocProc FbxGetDefaultReallocHandler();
+
+/** Get the default global memory freeing function used internally by the FBX SDK.
+* \return pHandler Function pointer on FBX's internal free */
+FBXSDK_DLL FbxFreeProc FbxGetDefaultFreeHandler();
+
+/*****************************************************************************************************************************
+** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
+*****************************************************************************************************************************/
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+	FBXSDK_DLL void* FbxMalloc(size_t pSize);
+	FBXSDK_DLL void* FbxCalloc(size_t pCount, size_t pSize);
+	FBXSDK_DLL void* FbxRealloc(void* pData, size_t pSize);
+	FBXSDK_DLL void FbxFree(void* pData);
+	FBXSDK_DLL char* FbxStrDup(const char* pString);
+	FBXSDK_DLL wchar_t* FbxStrDupWC(const wchar_t* pString);
+
+	//These versions of allocators use the default system mallocs, and on Windows we also pass the debugging parameters.
+	//If you define FBXSDK_ALLOC_DEBUG in your project, the FBX SDK will use these debug versions everywhere.
+	FBXSDK_DLL void* FbxMallocDebug(size_t pSize, int pBlock, const char* pFile, int pLine);
+	FBXSDK_DLL void* FbxCallocDebug(size_t pCount, size_t pSize, int pBlock, const char* pFile, int pLine);
+	FBXSDK_DLL void* FbxReallocDebug(void* pData, size_t pSize, int pBlock, const char* pFile, int pLine);
+	FBXSDK_DLL void FbxFreeDebug(void* pData, int pBlock);
+
+	//When FBXSDK_ALLOC_DEBUG is defined, redirect allocation calls to the debug version.
+	#if defined(FBXSDK_ALLOC_DEBUG)
+		#define FbxMalloc(s) FbxMallocDebug(s, _NORMAL_BLOCK, __FILE__, __LINE__)
+		#define FbxCalloc(c, s) FbxCallocDebug(c, s, _NORMAL_BLOCK, __FILE__, __LINE__)
+		#define FbxRealloc(p, s) FbxReallocDebug(p, s, _NORMAL_BLOCK, __FILE__, __LINE__)
+		#define FbxFree(p) FbxFreeDebug(p, _NORMAL_BLOCK)
+	#endif
+#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
+
+//! Deletion policy for pointer template classes that uses the delete operator.
+template <class Type> class FbxDeletionPolicyDefault
+{
+public:
+	//! Destruction policy implementation.
+	static inline void DeleteIt(Type** pPtr)
+	{
+		if( *pPtr )
+		{
+			delete *pPtr;
+			*pPtr = NULL;
+		}
+	}
+};
+
+//! Deletion policy for pointer template classes that uses the FbxDelete() function.
+template<typename T> void FbxDelete(T* p);
+template<typename T> void FbxDelete(const T* p);
+template <class Type> class FbxDeletionPolicyDelete
+{
+public:
+	//! Destruction policy implementation.
+	static inline void DeleteIt(Type** mPtr)
+	{
+		if( *mPtr )
+		{
+			FbxDelete(*mPtr);
+			*mPtr = NULL;
+		}
+	}
+};
+
+//! Deletion policy for pointer template classes that uses the FbxFree() function.
+template <class Type> class FbxDeletionPolicyFree
+{
+public:
+	//! Destruction policy implementation.
+	static inline void DeleteIt(Type** pPtr)
+	{
+		if( *pPtr )
+		{
+			FbxFree(*pPtr);
+			*pPtr = NULL;
+		}
+	}
+};
+
+//! Deletion policy for pointer template classes that uses the Destroy() function.
+template <class Type> class FbxDeletionPolicyObject
+{
+public:
+	//! Destruction policy implementation.
+	static inline void DeleteIt(Type** pPtr)
+	{
+		if( *pPtr )
+		{
+			(*pPtr)->Destroy();
+			*pPtr = NULL;
+		}
+	}
+};
+
+/** FbxAutoPtr mimics the \c auto_ptr class template implementation available in the C++ Standard Library. The \c auto_ptr template
+* class describes an object that stores a pointer to a single allocated object of type Type* that ensures that the object to which
+* it points gets destroyed automatically when control leaves a scope. */
+template<class Type, class Policy=FbxDeletionPolicyDefault<Type> > class FbxAutoPtr
+{
+public:
+	//! Construct from a pointer.
+	explicit FbxAutoPtr(Type* pPtr=0) : mPtr(pPtr){}
+
+	//! Destructor.
+	~FbxAutoPtr() { Policy::DeleteIt(&mPtr); }
+
+	//! Retrieve the pointer it holds.
+	inline Type* Get() const { return mPtr; }
+
+	//! Member access operator.
+	inline Type* operator->() const { return mPtr; }
+
+	//! Convert to a Type pointer.
+	inline operator Type* () const { return mPtr; }
+
+	//! Dereference operator.
+	inline Type& operator*() const { return *mPtr; }
+
+	//! Logical not operator.
+	inline bool operator!() const { return mPtr == 0; }
+
+	//! Convert to boolean value.
+	inline operator bool () const { return mPtr != 0; }
+
+	//! Reset the scoped pointer by swapping with another pointer.
+	inline void Reset(Type* pPtr=0)
+	{
+		FBX_ASSERT(pPtr == 0 || pPtr != mPtr);	//Catch self-reset errors
+		FbxAutoPtr<Type, Policy>(pPtr).Swap(*this);
+	}
+
+	//! Swap with another pointer.
+	inline void Swap(FbxAutoPtr& pOther)
+	{
+		Type* TmpPtr = pOther.mPtr;
+		pOther.mPtr = mPtr;
+		mPtr = TmpPtr;
+	}
+
+	//! Release the pointer, so that it won't perform deletion in its destruction.
+	inline Type* Release()
+	{
+		Type* TmpPtr = mPtr;
+		mPtr = NULL;
+		return TmpPtr;
+	}
+
+/*****************************************************************************************************************************
+** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
+*****************************************************************************************************************************/
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+private:
+	FbxAutoPtr(const FbxAutoPtr&);
+	FbxAutoPtr& operator=(const FbxAutoPtr&);
+
+	Type* mPtr;
+#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
+};
+
+//! Scoped pointer for FbxMalloc allocations, which call FbxFree() to deallocate.
+template <class Type> class FbxAutoFreePtr : public FbxAutoPtr<Type, FbxDeletionPolicyFree<Type> >
+{
+public:
+	//! Construct from a pointer.
+    explicit FbxAutoFreePtr(Type* pPtr=0) : FbxAutoPtr<Type, FbxDeletionPolicyFree<Type> >(pPtr){}
+};
+
+//! Scoped pointer for FbxNew allocations, which call FbxDelete() to deallocate.
+template <class Type> class FbxAutoDeletePtr : public FbxAutoPtr<Type, FbxDeletionPolicyDelete<Type> >
+{
+public:
+	//! Construct from a pointer.
+    explicit FbxAutoDeletePtr(Type* pPtr=0) : FbxAutoPtr<Type, FbxDeletionPolicyDelete<Type> >(pPtr){}
+};
+
+//! Scoped pointer for FbxObject derived classes, which call Destroy() to deallocate.
+template <class Type> class FbxAutoDestroyPtr : public FbxAutoPtr<Type, FbxDeletionPolicyObject<Type> >
+{
+public:
+	//! Construct from a pointer.
+    explicit FbxAutoDestroyPtr(Type* pPtr=0) : FbxAutoPtr<Type, FbxDeletionPolicyObject<Type> >(pPtr){}
+};
+
+
+/** FbxSharedPtr class describes an object that stores a pointer to a single allocated object of type 
+* Type* that ensures that the object to which it points gets destroyed automatically when the control 
+* leaves a scope and the reference count is 0. */
+class RefCount
+{
+public:
+ 	RefCount()	{ Init(); };
+	~RefCount() { Init(); };
+
+	void    Init()   { count = 0; }
+	void	IncRef() { count++; }
+	int	    DecRef() { count--; if (count < 0) count = 0; return count; }
+	
+private:
+	int  count;
+};
+
+template<class Type, class Policy=FbxDeletionPolicyDefault<Type> > class FbxSharedPtr
+{
+public:
+	// Default constructor.
+	FbxSharedPtr() : 
+		mPtr(0),
+		mRef(0)
+	{}
+
+	//! Construct from a pointer.
+	explicit FbxSharedPtr(Type* pPtr) : 
+		mPtr(pPtr),
+		mRef(0)
+	{ 
+		if (pPtr != 0) 
+		{
+			mRef = (RefCount*)FbxMalloc(sizeof(RefCount)); 
+			mRef->Init();
+			mRef->IncRef(); 
+		}
+	}
+
+	//! Copy constructor
+	FbxSharedPtr(const FbxSharedPtr& pSPtr) : 
+		mPtr(pSPtr.mPtr), 
+		mRef(pSPtr.mRef) 
+	{ 
+		if (pSPtr.mPtr != 0 && mRef != 0) 
+			mRef->IncRef(); 
+	}
+
+	// Assignment operator
+	FbxSharedPtr& operator=(const FbxSharedPtr& pSPtr)
+	{
+		if (this != &pSPtr) // avoid self assignment
+		{
+			Reset();
+
+			if (pSPtr.mPtr)
+			{
+				mPtr = pSPtr.mPtr;
+				mRef = pSPtr.mRef;
+				FBX_ASSERT(mRef != NULL);
+				mRef->IncRef();
+			}
+		}
+		return *this;
+	}
+
+	//! Destructor.
+	~FbxSharedPtr() { Destroy(); }
+
+	void Destroy() { Reset(); }
+
+	//! Retrieve the pointer it holds.
+	inline Type* Get() const { return mPtr; }
+
+	//! Member access operator.
+	inline Type* operator->() const { return mPtr; }
+
+	//! Convert to a Type pointer.
+	inline operator Type* () const { return mPtr; }
+
+	//! Dereference operator.
+	inline Type& operator*() const { return *mPtr; }
+
+	//! Logical not operator.
+	inline bool operator!() const { return mPtr == 0; }
+
+	//! Convert to boolean value.
+	inline operator bool () const { return mPtr != 0; }
+
+
+/*****************************************************************************************************************************
+** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
+*****************************************************************************************************************************/
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+private:
+	void Reset() 
+	{		
+		if (mRef)
+		{
+			FBX_ASSERT(mPtr != 0);
+			if (mRef->DecRef() == 0)
+			{
+				Policy::DeleteIt(&mPtr); 
+				FbxFree(mRef);
+				mRef = NULL;
+			}
+		}
+	}
+
+	Type* mPtr;
+	RefCount* mRef;
+#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
+};
+
+//! Scoped pointer for FbxMalloc allocations, which call FbxFree() to deallocate.
+template <class Type> class FbxSharedFreePtr : public FbxSharedPtr<Type, FbxDeletionPolicyFree<Type> >
+{
+public:
+	//! Construct from a pointer.
+    explicit FbxSharedFreePtr(Type* pPtr=0) : FbxSharedPtr<Type, FbxDeletionPolicyFree<Type> >(pPtr){}
+};
+
+//! Scoped pointer for FbxNew allocations, which call FbxDelete() to deallocate.
+template <class Type> class FbxSharedDeletePtr : public FbxSharedPtr<Type, FbxDeletionPolicyDelete<Type> >
+{
+public:
+	//! Construct from a pointer.
+    explicit FbxSharedDeletePtr(Type* pPtr=0) : FbxSharedPtr<Type, FbxDeletionPolicyDelete<Type> >(pPtr){}
+};
+
+//! Scoped pointer for FbxObject derived classes, which call Destroy() to deallocate.
+template <class Type> class FbxSharedDestroyPtr : public FbxSharedPtr<Type, FbxDeletionPolicyObject<Type> >
+{
+public:
+	//! Construct from a pointer.
+    explicit FbxSharedDestroyPtr(Type* pPtr=0) : FbxSharedPtr<Type, FbxDeletionPolicyObject<Type> >(pPtr){}
+};
+
+
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* _FBXSDK_CORE_ARCH_ALLOC_H_ */

+ 247 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/arch/fbxarch.h

@@ -0,0 +1,247 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+/** \file fbxarch.h
+  * Architecture definition.
+  * 
+  * List of available preprocessor defines that can appear on various systems:
+  *
+  * Operating System Environment:
+  *    FBXSDK_ENV_WIN (Windows)
+  *    FBXSDK_ENV_WINSTORE (Windows Store App)
+  *    FBXSDK_ENV_MAC (MacOSX)
+  *    FBXSDK_ENV_IOS (iOS)
+  *    FBXSDK_ENV_LINUX (Linux)
+  *
+  * Architecture:
+  *    FBXSDK_ARCH_IX86 (Intel x86)
+  *    FBXSDK_ARCH_AMD64 (AMD64)
+  *    FBXSDK_ARCH_ARM (Advanced RISC Machine)
+  *
+  * Processor:
+  *    FBXSDK_CPU_32 (32bit processor)
+  *    FBXSDK_CPU_64 (64bit processor)
+  *
+  * Compiler:
+  *    FBXSDK_COMPILER_MSC (Microsoft Compiler)
+  *    FBXSDK_COMPILER_GNU (GNU Compiler)
+  *    FBXSDK_COMPILER_INTEL (Intel Compiler)
+  *    FBXSDK_COMPILER_CLANG (Clang Compiler)
+  *
+  * These definitions are based on the information found here:
+  * http://predef.sourceforge.net/index.php
+  *
+  */
+#ifndef _FBXSDK_CORE_ARCH_ARCH_H_
+#define _FBXSDK_CORE_ARCH_ARCH_H_
+
+#if defined(_WIN32) || defined(_WIN64) //Microsoft Windows ------------------------------
+
+	#define FBXSDK_ENV_WIN 1
+
+	#if defined(WINAPI_FAMILY)
+		#if _MSC_VER >= 1800
+			// VS 2013 rewrote the winapifamily.h file 
+			#if !WINAPI_PARTITION_DESKTOP
+				#define FBXSDK_ENV_WINSTORE 1
+			#endif
+		#else
+			#if WINAPI_FAMILY_ONE_PARTITION(WINAPI_FAMILY, WINAPI_PARTITION_APP)
+				#define FBXSDK_ENV_WINSTORE 1
+			#endif
+		#endif
+	#endif
+
+	#if defined(_M_X64)
+		#define FBXSDK_ARCH_AMD64 1
+		#define FBXSDK_CPU_64 1
+	#elif defined(_M_IX86)
+		#define FBXSDK_ARCH_IX86 1
+		#define FBXSDK_CPU_32 1
+	#elif defined(_M_ARM)
+		#define FBXSDK_ARCH_ARM 1
+		#define FBXSDK_CPU_32 1
+	#else
+		#error Unsupported architecture!
+	#endif
+
+	#if defined(_MSC_VER)
+		#define FBXSDK_COMPILER_MSC 1
+	#elif defined(__GNUC__)
+		#define FBXSDK_COMPILER_GNU 1
+	#elif defined(__ICL)
+		#define FBXSDK_COMPILER_INTEL 1
+	#else
+		#error Unsupported compiler!
+	#endif
+
+#elif defined(__APPLE__) || defined(__MACH__) //Apple MacOS/X ---------------------------
+
+    #include "TargetConditionals.h"
+
+	#define FBXSDK_ENV_MAC 1
+
+    #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
+        #define FBXSDK_ENV_IOS 1
+    #endif
+
+	#if defined(__i386__)
+		#define FBXSDK_ARCH_IX86 1
+		#define FBXSDK_CPU_32 1
+	#elif defined(__x86_64__) || defined(__x86_64)
+		#define FBXSDK_ARCH_AMD64 1
+		#define FBXSDK_CPU_64 1
+	#elif defined(__arm__)
+		#define FBXSDK_ARCH_ARM 1
+		#define FBXSDK_CPU_32 1
+    #elif defined(__arm64__)
+        #define FBXSDK_ARCH_ARM 1
+        #define FBXSDK_CPU_64 1
+	#else
+		#error Unsupported architecture!
+	#endif
+
+	#if defined(__GNUC__)
+		#define FBXSDK_COMPILER_GNU 1
+	#endif
+
+    #if defined(__clang__)
+        #define FBXSDK_COMPILER_CLANG 1
+	#endif
+
+	#if !defined(FBXSDK_COMPILER_GNU) && !defined(FBXSDK_COMPILER_CLANG)
+		#error Unsupported compiler!
+	#endif
+
+#elif defined(__linux__) || defined(__CYGWIN__) || defined(EMSCRIPTEN) || defined(ANDROID) //Linux ---------------------------------
+
+	#define FBXSDK_ENV_LINUX 1
+
+  	#if defined(EMSCRIPTEN)
+  		#define FBXSDK_ENV_EMSCRIPTEN 1
+  	#endif
+
+	#if defined(ANDROID)
+		#define FBXSDK_ENV_ANDROID 1
+	#endif
+
+	#if defined(__i386__)
+		#define FBXSDK_ARCH_IX86 1
+		#define FBXSDK_CPU_32 1
+	#elif defined(__x86_64__) || defined(__x86_64)
+		#define FBXSDK_ARCH_AMD64 1
+		#define FBXSDK_CPU_64 1
+    #elif defined(__arm__)
+		#define FBXSDK_ARCH_ARM 1
+		#define FBXSDK_CPU_32 1
+	#elif defined(EMSCRIPTEN)
+  		#define FBXSDK_ARCH_AMD64 1
+		#define FBXSDK_CPU_64 1
+  	#else
+		#error Unsupported architecture!
+	#endif
+
+	#if defined(__GNUC__)
+		#define FBXSDK_COMPILER_GNU 1
+	#elif defined(EMSCRIPTEN)
+  		#define FBXSDK_COMPILER_EMSCRIPTEN 1 
+	#else
+		#error Unsupported compiler!
+	#endif
+ #else
+	#error Unsupported platform!
+#endif
+
+//---------------------------------------------------------------------------------------
+//Compiler Specifics
+#if defined(FBXSDK_SHARED)
+	#if defined(FBXSDK_COMPILER_MSC) || defined(FBXSDK_COMPILER_INTEL)
+		#define FBXSDK_DLLIMPORT __declspec(dllimport)
+		#define FBXSDK_DLLEXPORT __declspec(dllexport)
+	#elif defined(FBXSDK_COMPILER_GNU) && (__GNUC__ >= 4)
+		#define FBXSDK_DLLIMPORT __attribute__((visibility("default")))
+		#define FBXSDK_DLLEXPORT __attribute__((visibility("default")))
+	#else
+		#define FBXSDK_DLLIMPORT
+		#define FBXSDK_DLLEXPORT
+	#endif
+#else
+	#define FBXSDK_DLLIMPORT
+	#define FBXSDK_DLLEXPORT
+#endif
+
+#ifndef FBXSDK_DLL
+	#define FBXSDK_DLL FBXSDK_DLLIMPORT
+#endif
+
+#if defined(FBXSDK_COMPILER_MSC)
+	#pragma warning(disable : 4251)	//'identifier' : class 'type' needs to have dll-interface to be used by clients of class 'type2'
+    #if _MSC_VER >= 1300 // 7.1
+        #define FBX_DEPRECATED __declspec(deprecated)
+    #else
+        #define FBX_DEPRECATED
+    #endif
+#elif defined(FBXSDK_COMPILER_GNU) || defined(FBXSDK_COMPILER_EMSCRIPTEN)
+    #define FBX_DEPRECATED __attribute__((deprecated))
+#elif defined(FBXSDK_COMPILER_INTEL)
+    #if __INTEL_COMPILER >= 810
+        #define FBX_DEPRECATED __declspec(deprecated)
+    #else
+        #define FBX_DEPRECATED
+    #endif
+#else
+	#error Unsupported compiler!
+#endif
+
+#ifdef FBXSDK_COMPILER_CLANG
+	#define FBX_UNUSED(p) _Pragma(FBX_STRINGIFY(unused(p)))
+#else
+	#define FBX_UNUSED(p) (void)(p)
+#endif
+
+//---------------------------------------------------------------------------------------
+//Platform Standardization
+#ifndef NULL
+	#if defined(__GNUG__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8))
+		#define NULL (__null)
+	#else	
+    	#if defined(__cplusplus)
+    		#define NULL 0
+    	#else
+    		#define NULL ((void*)0)
+    	#endif
+    #endif
+#endif
+
+#if !defined(_MAX_PATH)
+	#define _MAX_PATH 260
+#endif
+
+#if defined(FBXSDK_ENV_WIN)
+	#define snprintf _snprintf //for stdio.h platform compatibility
+#endif
+
+#if !defined(FBXSDK_COMPILER_MSC)
+	#ifndef strcmpi
+		#define strcmpi strcasecmp
+	#endif
+	#ifndef stricmp
+		#define stricmp strcasecmp
+	#endif
+	#ifndef strncmpi
+		#define strncmpi strncasecmp
+	#endif
+	#ifndef strnicmp
+		#define strnicmp strncasecmp
+	#endif
+#endif
+
+#endif /* _FBXSDK_CORE_ARCH_ARCH_H_ */

+ 93 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/arch/fbxdebug.h

@@ -0,0 +1,93 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+/** \file fbxdebug.h
+  * Debugging macros and functions.
+  * 
+  * All macros and functions are removed in release builds. To enable asserts, a debug build is required as well
+  * as the environment variable "FBXSDK_ASSERT" set to 1 is also required. By default, assertions will pop-up
+  * a window. It is possible to disable the pop-up on the Windows platform by calling the following code:
+  * \code
+  * _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG);
+  * \endcode
+  */
+#ifndef _FBXSDK_CORE_ARCH_DEBUG_H_
+#define _FBXSDK_CORE_ARCH_DEBUG_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+/** If this environment variable is set to 1, the FBX SDK will assert in debug builds */
+#define FBXSDK_ASSERT_ENVSTR "FBXSDK_ASSERT"
+
+/** The assertion procedure signature. If a different assertion procedure must be provided, it should have this signature.
+* \param pFileName The file name where the assertion occurred.
+* \param pFunctionName The function name where the assertion occurred.
+* \param pLineNumber The line number in the file where the assertion occurred.
+* \param pMessage The message to display when the assertion occurs. */
+typedef void (*FbxAssertProc)(const char* pFileName, const char* pFunctionName, const unsigned int pLineNumber, const char* pMessage);
+
+/** Change the procedure used when assertion occurs.
+* \param pAssertProc The procedure to be called when assertions occurs. */
+FBXSDK_DLL void FbxAssertSetProc(FbxAssertProc pAssertProc);
+
+//! Change the procedure back to the default one.
+FBXSDK_DLL void FbxAssertSetDefaultProc();
+
+/*****************************************************************************************************************************
+** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
+*****************************************************************************************************************************/
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+FBXSDK_DLL void _FbxAssert(const char* pFileName, const char* pFunctionName, const unsigned int pLineNumber, bool pFormat, const char* pMessage, ...);
+FBXSDK_DLL void _FbxTrace(const char* pMessage, ...);
+
+#ifdef _DEBUG
+    template <bool x> struct FbxStaticAssertType;
+    template<> struct FbxStaticAssertType<true>			{enum{value=1};};
+    template<> struct FbxStaticAssertType<false>		{enum{value=-1};};
+	#define FBX_ASSERT(Condition)						{if(!(Condition)){_FbxAssert(__FILE__,__FUNCTION__,__LINE__,false,#Condition);}}
+	#define FBX_ASSERT_MSG(Condition, Message, ...)		{if(!(Condition)){_FbxAssert(__FILE__,__FUNCTION__,__LINE__,true,Message,##__VA_ARGS__);}}
+	#define FBX_ASSERT_NOW(Message, ...)				_FbxAssert(__FILE__,__FUNCTION__,__LINE__,true,Message,##__VA_ARGS__);
+	#define FBX_ASSERT_RETURN(Condition)				{if(!(Condition)){FBX_ASSERT_NOW(#Condition); return;}}
+	#define FBX_ASSERT_RETURN_VALUE(Condition, Value)	{if(!(Condition)){FBX_ASSERT_NOW(#Condition); return Value;}}
+	#define FBX_ASSERT_STATIC(Condition)				typedef char FbxBuildBreakIfFalse[FbxStaticAssertType<(bool)(Condition)>::value];
+	#define FBX_TRACE(Message, ...)						{_FbxTrace(Message,##__VA_ARGS__);}
+#else
+	#define FBX_ASSERT(Condition)						((void)0)
+	#define FBX_ASSERT_MSG(Condition, Message, ...)		((void)0)
+	#define FBX_ASSERT_NOW(Message, ...)				((void)0)
+	#define FBX_ASSERT_RETURN(Condition)				if(!(Condition)){return;}
+	#define FBX_ASSERT_RETURN_VALUE(Condition, Value)	if(!(Condition)){return Value;}
+	#define FBX_ASSERT_STATIC(Condition)
+	#define FBX_TRACE(Message, ...)						((void)0)
+#endif
+
+template<typename T> struct FbxIncompatibleWithArray{ enum {value = 0}; };
+
+#define FBXSDK_INCOMPATIBLE_WITH_ARRAY_TEMPLATE(T)\
+	struct FbxIncompatibleWithArray< T >{\
+		union {\
+			T t();\
+		} catcherr;\
+		enum {value = 1};}
+
+#define FBXSDK_INCOMPATIBLE_WITH_ARRAY(T)\
+	template<> FBXSDK_INCOMPATIBLE_WITH_ARRAY_TEMPLATE(T)
+
+#define FBXSDK_IS_INCOMPATIBLE_WITH_ARRAY(T) ((bool) FbxIncompatibleWithArray<T>::value)
+
+#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* _FBXSDK_CORE_ARCH_DEBUG_H_ */

+ 510 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/arch/fbxnew.h

@@ -0,0 +1,510 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+/** \file fbxnew.h
+  * New operator override templates.
+  *
+  * Instead of overloading the operator new in the FBX SDK, we provide a set of templates
+  * that are used internally to create objects. This mechanic allows the FBX SDK to call
+  * a different memory allocator.
+  * \see FbxSetMallocHandler FbxSetCallocHandler FbxSetReallocHandler FbxSetFreeHandler FbxSetMSizeHandler
+  */
+#ifndef _FBXSDK_CORE_ARCH_NEW_H_
+#define _FBXSDK_CORE_ARCH_NEW_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#include <new>
+
+#if defined(FBXSDK_COMPILER_MSC)
+	#pragma warning(push)
+	#pragma warning(disable : 4345) //warning C4345: behavior change: an object of POD type constructed with an initializer of the form () will be default-initialized
+#endif
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+//Type traits for primitive types
+template<typename T> struct FbxSimpleType { enum {value = 0}; };
+template<typename T> struct FbxSimpleType<T*> { enum {value = 1}; };
+template<typename T> struct FbxSimpleType<const T> { enum {value = FbxSimpleType<T>::value}; };
+template<typename T, size_t n> struct FbxSimpleType<T[n]> { enum {value = FbxSimpleType<T>::value}; };
+
+#define FBXSDK_DEFINE_SIMPLE_TYPE(T) template<> struct FbxSimpleType<T>{ union {T t;} catcherr; enum {value = 1};}
+
+FBXSDK_DEFINE_SIMPLE_TYPE(bool);
+FBXSDK_DEFINE_SIMPLE_TYPE(char);
+FBXSDK_DEFINE_SIMPLE_TYPE(unsigned char);
+FBXSDK_DEFINE_SIMPLE_TYPE(short);
+FBXSDK_DEFINE_SIMPLE_TYPE(unsigned short);
+FBXSDK_DEFINE_SIMPLE_TYPE(int);
+FBXSDK_DEFINE_SIMPLE_TYPE(unsigned int);
+FBXSDK_DEFINE_SIMPLE_TYPE(long);
+FBXSDK_DEFINE_SIMPLE_TYPE(unsigned long);
+FBXSDK_DEFINE_SIMPLE_TYPE(float);
+FBXSDK_DEFINE_SIMPLE_TYPE(double);
+FBXSDK_DEFINE_SIMPLE_TYPE(long double);
+FBXSDK_DEFINE_SIMPLE_TYPE(long long);
+FBXSDK_DEFINE_SIMPLE_TYPE(unsigned long long);
+
+#define FBXSDK_IS_SIMPLE_TYPE(T) ((bool)FbxSimpleType<T>::value)
+
+template<typename T> T* FbxNew()
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T();
+}
+
+template<typename T, typename T1> T* FbxNew(T1& p1)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1);
+}
+
+template<typename T, typename T1> T* FbxNew(const T1& p1)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1);
+}
+
+template<typename T, typename T1, typename T2> T* FbxNew(T1& p1, T2& p2)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1, p2);
+}
+
+template<typename T, typename T1, typename T2> T* FbxNew(T1& p1, const T2& p2)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1, p2);
+}
+
+template<typename T, typename T1, typename T2> T* FbxNew(const T1& p1, T2& p2)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1, p2);
+}
+
+template<typename T, typename T1, typename T2> T* FbxNew(const T1& p1, const T2& p2)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1, p2);
+}
+
+template<typename T, typename T1, typename T2, typename T3> T* FbxNew(T1& p1, T2& p2, T3& p3)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1, p2, p3);
+}
+
+template<typename T, typename T1, typename T2, typename T3> T* FbxNew(T1& p1, T2& p2, const T3& p3)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1, p2, p3);
+}
+
+template<typename T, typename T1, typename T2, typename T3> T* FbxNew(T1& p1, const T2& p2, T3& p3)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1, p2, p3);
+}
+
+template<typename T, typename T1, typename T2, typename T3> T* FbxNew(T1& p1, const T2& p2, const T3& p3)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1, p2, p3);
+}
+
+template<typename T, typename T1, typename T2, typename T3> T* FbxNew(const T1& p1, T2& p2, T3& p3)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1, p2, p3);
+}
+
+template<typename T, typename T1, typename T2, typename T3> T* FbxNew(const T1& p1, T2& p2, const T3& p3)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1, p2, p3);
+}
+
+template<typename T, typename T1, typename T2, typename T3> T* FbxNew(const T1& p1, const T2& p2, T3& p3)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1, p2, p3);
+}
+
+template<typename T, typename T1, typename T2, typename T3> T* FbxNew(const T1& p1, const T2& p2, const T3& p3)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1, p2, p3);
+}
+
+template<typename T, typename T1, typename T2, typename T3, typename T4> T* FbxNew(T1& p1, T2& p2, T3& p3, T4& p4)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1, p2, p3, p4);
+}
+
+template<typename T, typename T1, typename T2, typename T3, typename T4> T* FbxNew(T1& p1, T2& p2, T3& p3, const T4& p4)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1, p2, p3, p4);
+}
+
+template<typename T, typename T1, typename T2, typename T3, typename T4> T* FbxNew(T1& p1, T2& p2, const T3& p3, T4& p4)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1, p2, p3, p4);
+}
+
+template<typename T, typename T1, typename T2, typename T3, typename T4> T* FbxNew(T1& p1, T2& p2, const T3& p3, const T4& p4)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1, p2, p3, p4);
+}
+
+template<typename T, typename T1, typename T2, typename T3, typename T4> T* FbxNew(T1& p1, const T2& p2, T3& p3, T4& p4)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1, p2, p3, p4);
+}
+
+template<typename T, typename T1, typename T2, typename T3, typename T4> T* FbxNew(T1& p1, const T2& p2, T3& p3, const T4& p4)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1, p2, p3, p4);
+}
+
+template<typename T, typename T1, typename T2, typename T3, typename T4> T* FbxNew(T1& p1, const T2& p2, const T3& p3, T4& p4)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1, p2, p3, p4);
+}
+
+template<typename T, typename T1, typename T2, typename T3, typename T4> T* FbxNew(T1& p1, const T2& p2, const T3& p3, const T4& p4)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1, p2, p3, p4);
+}
+
+template<typename T, typename T1, typename T2, typename T3, typename T4> T* FbxNew(const T1& p1, T2& p2, T3& p3, T4& p4)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1, p2, p3, p4);
+}
+
+template<typename T, typename T1, typename T2, typename T3, typename T4> T* FbxNew(const T1& p1, T2& p2, T3& p3, const T4& p4)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1, p2, p3, p4);
+}
+
+template<typename T, typename T1, typename T2, typename T3, typename T4> T* FbxNew(const T1& p1, T2& p2, const T3& p3, T4& p4)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1, p2, p3, p4);
+}
+
+template<typename T, typename T1, typename T2, typename T3, typename T4> T* FbxNew(const T1& p1, T2& p2, const T3& p3, const T4& p4)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1, p2, p3, p4);
+}
+
+template<typename T, typename T1, typename T2, typename T3, typename T4> T* FbxNew(const T1& p1, const T2& p2, T3& p3, T4& p4)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1, p2, p3, p4);
+}
+
+template<typename T, typename T1, typename T2, typename T3, typename T4> T* FbxNew(const T1& p1, const T2& p2, T3& p3, const T4& p4)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1, p2, p3, p4);
+}
+
+template<typename T, typename T1, typename T2, typename T3, typename T4> T* FbxNew(const T1& p1, const T2& p2, const T3& p3, T4& p4)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1, p2, p3, p4);
+}
+
+template<typename T, typename T1, typename T2, typename T3, typename T4> T* FbxNew(const T1& p1, const T2& p2, const T3& p3, const T4& p4)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1, p2, p3, p4);
+}
+
+template<typename T, typename T1, typename T2, typename T3, typename T4, typename T5> T* FbxNew(T1& p1, T2& p2, T3& p3, T4& p4, T5& p5)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1,p2,p3,p4,p5);
+}
+
+template<typename T, typename T1, typename T2, typename T3, typename T4, typename T5> T* FbxNew(const T1& p1, T2& p2, T3& p3, T4& p4, T5& p5)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1,p2,p3,p4,p5);
+}
+
+template<typename T, typename T1, typename T2, typename T3, typename T4, typename T5> T* FbxNew(const T1& p1, const T2& p2, T3& p3, T4& p4, T5& p5)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1,p2,p3,p4,p5);
+}
+
+template<typename T, typename T1, typename T2, typename T3, typename T4, typename T5> T* FbxNew(const T1& p1, T2& p2, const T3& p3, T4& p4, T5& p5)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1,p2,p3,p4,p5);
+}
+
+template<typename T, typename T1, typename T2, typename T3, typename T4, typename T5> T* FbxNew(const T1& p1, T2& p2, T3& p3, const T4& p4, T5& p5)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1,p2,p3,p4,p5);
+}
+
+template<typename T, typename T1, typename T2, typename T3, typename T4, typename T5> T* FbxNew(const T1& p1, T2& p2, T3& p3, T4& p4, const T5& p5)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1,p2,p3,p4,p5);
+}
+
+template<typename T, typename T1, typename T2, typename T3, typename T4, typename T5> T* FbxNew(const T1& p1, const T2& p2, const T3& p3, T4& p4, T5& p5)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1,p2,p3,p4,p5);
+}
+
+template<typename T, typename T1, typename T2, typename T3, typename T4, typename T5> T* FbxNew(const T1& p1, const T2& p2, T3& p3, const T4& p4, T5& p5)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1,p2,p3,p4,p5);
+}
+
+template<typename T, typename T1, typename T2, typename T3, typename T4, typename T5> T* FbxNew(const T1& p1, const T2& p2, T3& p3, T4& p4, const T5& p5)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1,p2,p3,p4,p5);
+}
+
+template<typename T, typename T1, typename T2, typename T3, typename T4, typename T5> T* FbxNew(const T1& p1, const T2& p2, const T3& p3, const T4& p4, T5& p5)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1,p2,p3,p4,p5);
+}
+
+template<typename T, typename T1, typename T2, typename T3, typename T4, typename T5> T* FbxNew(const T1& p1, const T2& p2, const T3& p3, T4& p4, const T5& p5)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1,p2,p3,p4,p5);
+}
+
+template<typename T, typename T1, typename T2, typename T3, typename T4, typename T5> T* FbxNew(const T1& p1, const T2& p2, const T3& p3, const T4& p4, const T5& p5)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1,p2,p3,p4,p5);
+}
+
+template<typename T, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6> T* FbxNew(const T1& p1, const T2& p2, const T3& p3, const T4& p4, const T5& p5, const T6& p6)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1,p2,p3,p4,p5,p6);
+}
+
+template<typename T, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7> T* FbxNew(const T1& p1, const T2& p2, const T3& p3, const T4& p4, const T5& p5, const T6& p6, const T7& p7)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1,p2,p3,p4,p5,p6,p7);
+}
+
+template<typename T, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> T* FbxNew(const T1& p1, const T2& p2, const T3& p3, const T4& p4, const T5& p5, const T6& p6, const T7& p7, const T8& p8)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1,p2,p3,p4,p5,p6,p7,p8);
+}
+
+template<typename T, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9> T* FbxNew(const T1& p1, const T2& p2, const T3& p3, const T4& p4, const T5& p5, const T6& p6, const T7& p7, const T8& p8, const T9& p9)
+{
+	T* p = (T*)FbxMalloc(sizeof(T));
+	return new(p)T(p1,p2,p3,p4,p5,p6,p7,p8,p9);
+}
+
+template<typename T> void FbxDelete(T* p)
+{
+	if( p )
+	{
+		((T*)p)->~T();
+		FbxFree(p);
+	}
+}
+
+template<typename T> void FbxDelete(const T* p)
+{
+	if( p )
+	{
+		((T*)p)->~T();
+		FbxFree(const_cast<T*>(p));
+	}
+}
+
+template<typename T> T* FbxNewArray(const int n)
+{
+	if( FBXSDK_IS_SIMPLE_TYPE(T) )
+	{
+		return (T*)FbxMalloc(sizeof(T)*n);
+	}
+	else
+	{
+		void* pTmp = FbxMalloc(sizeof(T) * n + sizeof(int));
+		T* p = (T*)((int*)pTmp+1);
+		*((int*)pTmp) = n;
+		for( int i = 0; i < n; ++i )
+		{
+			new((T*)p+i)T;	//in-place new, not allocating memory so it is safe.
+		}
+		return p;
+	}
+}
+
+template<typename T> void FbxDeleteArray(T* p)
+{
+	if( p )
+	{
+		if( !FBXSDK_IS_SIMPLE_TYPE(T) )
+		{
+			for( int i = 0; i < ((int*)p)[-1]; ++i )
+			{
+				((T*)p)[i].~T();
+			}
+			FbxFree((int*)p-1);
+		}
+		else
+		{
+			FbxFree((void*)p);
+		}
+	}
+}
+
+#define FBXSDK_FRIEND_NEW()\
+	template<typename T>\
+	friend T* FBXSDK_NAMESPACE::FbxNew();\
+	template<typename T, typename T1>\
+	friend T* FBXSDK_NAMESPACE::FbxNew(T1& p1);\
+	template<typename T, typename T1>\
+	friend T* FBXSDK_NAMESPACE::FbxNew(const T1& p1);\
+	template<typename T, typename T1, typename T2>\
+	friend T* FBXSDK_NAMESPACE::FbxNew(T1& p1, T2& p2);\
+	template<typename T, typename T1, typename T2>\
+	friend T* FBXSDK_NAMESPACE::FbxNew(T1& p1, const T2& p2);\
+	template<typename T, typename T1, typename T2>\
+	friend T* FBXSDK_NAMESPACE::FbxNew(const T1& p1, T2& p2);\
+	template<typename T, typename T1, typename T2>\
+	friend T* FBXSDK_NAMESPACE::FbxNew(const T1& p1, const T2& p2);\
+	template<typename T, typename T1, typename T2, typename T3>\
+	friend T* FBXSDK_NAMESPACE::FbxNew(T1& p1, T2& p2, T3& p3);\
+	template<typename T, typename T1, typename T2, typename T3>\
+	friend T* FBXSDK_NAMESPACE::FbxNew(T1& p1, T2& p2, const T3& p3);\
+	template<typename T, typename T1, typename T2, typename T3>\
+	friend T* FBXSDK_NAMESPACE::FbxNew(T1& p1, const T2& p2, T3& p3);\
+	template<typename T, typename T1, typename T2, typename T3>\
+	friend T* FBXSDK_NAMESPACE::FbxNew(T1& p1, const T2& p2, const T3& p3);\
+	template<typename T, typename T1, typename T2, typename T3>\
+	friend T* FBXSDK_NAMESPACE::FbxNew(const T1& p1, T2& p2, T3& p3);\
+	template<typename T, typename T1, typename T2, typename T3>\
+	friend T* FBXSDK_NAMESPACE::FbxNew(const T1& p1, T2& p2, const T3& p3);\
+	template<typename T, typename T1, typename T2, typename T3>\
+	friend T* FBXSDK_NAMESPACE::FbxNew(const T1& p1, const T2& p2, T3& p3);\
+	template<typename T, typename T1, typename T2, typename T3>\
+	friend T* FBXSDK_NAMESPACE::FbxNew(const T1& p1, const T2& p2, const T3& p3);\
+    \
+	template<typename T, typename T1, typename T2, typename T3, typename T4>\
+	friend T* FBXSDK_NAMESPACE::FbxNew(T1& p1, T2& p2, T3& p3, T4& p4);\
+	template<typename T, typename T1, typename T2, typename T3, typename T4>\
+	friend T* FBXSDK_NAMESPACE::FbxNew(T1& p1, T2& p2, T3& p3, const T4& p4);\
+	template<typename T, typename T1, typename T2, typename T3, typename T4>\
+	friend T* FBXSDK_NAMESPACE::FbxNew(T1& p1, T2& p2, const T3& p3, T4& p4);\
+	template<typename T, typename T1, typename T2, typename T3, typename T4>\
+	friend T* FBXSDK_NAMESPACE::FbxNew(T1& p1, T2& p2, const T3& p3, const T4& p4);\
+	template<typename T, typename T1, typename T2, typename T3, typename T4>\
+	friend T* FBXSDK_NAMESPACE::FbxNew(T1& p1, const T2& p2, T3& p3, T4& p4);\
+	template<typename T, typename T1, typename T2, typename T3, typename T4>\
+	friend T* FBXSDK_NAMESPACE::FbxNew(T1& p1, const T2& p2, T3& p3, const T4& p4);\
+	template<typename T, typename T1, typename T2, typename T3, typename T4>\
+	friend T* FBXSDK_NAMESPACE::FbxNew(T1& p1, const T2& p2, const T3& p3, T4& p4);\
+	template<typename T, typename T1, typename T2, typename T3, typename T4>\
+	friend T* FBXSDK_NAMESPACE::FbxNew(T1& p1, const T2& p2, const T3& p3, const T4& p4);\
+	template<typename T, typename T1, typename T2, typename T3, typename T4>\
+	friend T* FBXSDK_NAMESPACE::FbxNew(const T1& p1, T2& p2, T3& p3, T4& p4);\
+	template<typename T, typename T1, typename T2, typename T3, typename T4>\
+	friend T* FBXSDK_NAMESPACE::FbxNew(const T1& p1, T2& p2, T3& p3, const T4& p4);\
+	template<typename T, typename T1, typename T2, typename T3, typename T4>\
+	friend T* FBXSDK_NAMESPACE::FbxNew(const T1& p1, T2& p2, const T3& p3, T4& p4);\
+	template<typename T, typename T1, typename T2, typename T3, typename T4>\
+	friend T* FBXSDK_NAMESPACE::FbxNew(const T1& p1, T2& p2, const T3& p3, const T4& p4);\
+	template<typename T, typename T1, typename T2, typename T3, typename T4>\
+	friend T* FBXSDK_NAMESPACE::FbxNew(const T1& p1, const T2& p2, T3& p3, T4& p4);\
+	template<typename T, typename T1, typename T2, typename T3, typename T4>\
+	friend T* FBXSDK_NAMESPACE::FbxNew(const T1& p1, const T2& p2, T3& p3, const T4& p4);\
+	template<typename T, typename T1, typename T2, typename T3, typename T4>\
+	friend T* FBXSDK_NAMESPACE::FbxNew(const T1& p1, const T2& p2, const T3& p3, T4& p4);\
+	template<typename T, typename T1, typename T2, typename T3, typename T4>\
+	friend T* FBXSDK_NAMESPACE::FbxNew(const T1& p1, const T2& p2, const T3& p3, const T4& p4);\
+    \
+    template<typename T, typename T1, typename T2, typename T3, typename T4, typename T5>\
+    friend T* FBXSDK_NAMESPACE::FbxNew(T1& p1, T2& p2, T3& p3, T4& p4, T5& p5);\
+    template<typename T, typename T1, typename T2, typename T3, typename T4, typename T5>\
+    friend T* FBXSDK_NAMESPACE::FbxNew(const T1& p1, T2& p2, T3& p3, T4& p4, T5& p5);\
+    template<typename T, typename T1, typename T2, typename T3, typename T4, typename T5>\
+    friend T* FBXSDK_NAMESPACE::FbxNew(const T1& p1, const T2& p2, T3& p3, T4& p4, T5& p5);\
+    template<typename T, typename T1, typename T2, typename T3, typename T4, typename T5>\
+    friend T* FBXSDK_NAMESPACE::FbxNew(const T1& p1, T2& p2, const T3& p3, T4& p4, T5& p5);\
+    template<typename T, typename T1, typename T2, typename T3, typename T4, typename T5>\
+    friend T* FBXSDK_NAMESPACE::FbxNew(const T1& p1, T2& p2, T3& p3, const T4& p4, T5& p5);\
+    template<typename T, typename T1, typename T2, typename T3, typename T4, typename T5>\
+    friend T* FBXSDK_NAMESPACE::FbxNew(const T1& p1, T2& p2, T3& p3, T4& p4, const T5& p5);\
+    template<typename T, typename T1, typename T2, typename T3, typename T4, typename T5>\
+    friend T* FBXSDK_NAMESPACE::FbxNew(const T1& p1, const T2& p2, const T3& p3, T4& p4, T5& p5);\
+    template<typename T, typename T1, typename T2, typename T3, typename T4, typename T5>\
+    friend T* FBXSDK_NAMESPACE::FbxNew(const T1& p1, const T2& p2, T3& p3, const T4& p4, T5& p5);\
+    template<typename T, typename T1, typename T2, typename T3, typename T4, typename T5>\
+    friend T* FBXSDK_NAMESPACE::FbxNew(const T1& p1, const T2& p2, T3& p3, T4& p4, const T5& p5);\
+    template<typename T, typename T1, typename T2, typename T3, typename T4, typename T5>\
+    friend T* FBXSDK_NAMESPACE::FbxNew(const T1& p1, const T2& p2, const T3& p3, const T4& p4, T5& p5);\
+    template<typename T, typename T1, typename T2, typename T3, typename T4, typename T5>\
+    friend T* FBXSDK_NAMESPACE::FbxNew(const T1& p1, const T2& p2, const T3& p3, T4& p4, const T5& p5);\
+    template<typename T, typename T1, typename T2, typename T3, typename T4, typename T5>\
+    friend T* FBXSDK_NAMESPACE::FbxNew(const T1& p1, const T2& p2, const T3& p3, const T4& p4, const T5& p5);\
+    \
+	template<typename T, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>\
+	friend T* FBXSDK_NAMESPACE::FbxNew(const T1& p1, const T2& p2, const T3& p3, const T4& p4, const T5& p5, const T6& p6);\
+	template<typename T, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>\
+	friend T* FBXSDK_NAMESPACE::FbxNew(const T1& p1, const T2& p2, const T3& p3, const T4& p4, const T5& p5, const T6& p6, const T7& p7);\
+	template<typename T, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>\
+	friend T* FBXSDK_NAMESPACE::FbxNew(const T1& p1, const T2& p2, const T3& p3, const T4& p4, const T5& p5, const T6& p6, const T7& p7, const T8& p8);\
+	template<typename T, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>\
+	friend T* FBXSDK_NAMESPACE::FbxNew(const T1& p1, const T2& p2, const T3& p3, const T4& p4, const T5& p5, const T6& p6, const T7& p7, const T8& p8, const T9& p9);\
+	template<typename T>\
+	friend void FBXSDK_NAMESPACE::FbxDelete(T* p);\
+	template<typename T>\
+	friend void FBXSDK_NAMESPACE::FbxDelete(const T* p);\
+	template<typename T>\
+	friend T* FBXSDK_NAMESPACE::FbxNewArray(const int n);\
+	template<typename T>\
+	friend void FBXSDK_NAMESPACE::FbxDeleteArray(T* p);
+
+#ifdef FBXSDK_COMPILER_MSC
+	#pragma warning(pop)
+#endif
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* _FBXSDK_CORE_ARCH_NEW_H_ */

+ 97 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/arch/fbxstdcompliant.h

@@ -0,0 +1,97 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+/** \file fbxstdcompliant.h
+* Macros to properly support the CRT secure functions. */
+#ifndef _FBXSDK_CORE_ARCH_STDCOMPLIANT_H_
+#define _FBXSDK_CORE_ARCH_STDCOMPLIANT_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+#if defined(FBXSDK_ENV_WIN)
+	#define FBXSDK_printf							printf_s
+	#define FBXSDK_fprintf							fprintf_s
+	inline int FBXSDK_sprintf(char* dst, size_t dstsize, const char* format, ...){ va_list vl; va_start(vl, format); int ret = vsprintf_s(dst, dstsize, format, vl); va_end(vl); return ret; }
+	inline int FBXSDK_snprintf(char* dst, size_t dstsize, const char* format, ...){ va_list vl; va_start(vl, format); int ret = vsnprintf_s(dst, dstsize, _TRUNCATE, format, vl); va_end(vl); return ret; }
+	inline int FBXSDK_vsprintf(char* dst, size_t dstsize, const char* format, va_list vl){ return vsprintf_s(dst, dstsize, format, vl); }
+	inline int FBXSDK_vsnprintf(char* dst, size_t dstsize, const char* format, va_list vl){ return vsnprintf_s(dst, dstsize, _TRUNCATE, format, vl); }
+	#define FBXSDK_stricmp(dst, src)				_stricmp(dst, src)
+	#define FBXSDK_strnicmp(dst, src, count)		_strnicmp(dst, src, count)
+	#define FBXSDK_strcpy(dst, size, src)			strcpy_s(dst, size, src)
+	#define FBXSDK_strncpy(dst, size, src, count)	strncpy_s(dst, size, src, count)
+	#define FBXSDK_strcat(dst, size, src)			strcat_s(dst, size, src)
+	#define FBXSDK_strtok(str, delim, ctx)			strtok_s(str, delim, ctx)
+	#define FBXSDK_wcscpy(dst, size, src)			wcscpy_s(dst, size, src)
+	#define FBXSDK_wcscat(dst, size, src)			wcscat_s(dst, size, src)
+#if !defined(FBXSDK_ENV_WINSTORE)
+	#define FBXSDK_getpid							_getpid
+	#define FBXSDK_getcwd							_getcwd
+#else
+	inline int FBXSDK_getpid(){ return 0; }
+	inline char* FBXSDK_getcwd(char*,int){ return NULL; }
+#endif
+	#define FBXSDK_localtime(ptm, time)				{ struct tm tms; ptm = &tms; localtime_s(ptm, time); }
+	#define FBXSDK_gmtime(ptm, time)				{ struct tm tms; ptm = &tms; gmtime_s(ptm, time); }
+	#define FBXSDK_fopen(fp, name, mode)			fopen_s(&fp, name, mode)
+
+#elif defined(FBXSDK_ENV_MAC) || defined(FBXSDK_ENV_LINUX)
+	#define FBXSDK_printf							printf
+	#define FBXSDK_fprintf							fprintf
+	inline int FBXSDK_sprintf(char* dst, size_t dstsize, const char* format, ...){ va_list vl; va_start(vl, format); int ret = vsprintf(dst, format, vl); va_end(vl); return ret; }
+	inline int FBXSDK_snprintf(char* dst, size_t dstsize, const char* format, ...){ va_list vl; va_start(vl, format); int ret = vsnprintf(dst, dstsize, format, vl); va_end(vl); return ret; }
+	inline int FBXSDK_vsprintf(char* dst, size_t dstsize, const char* format, va_list vl){ return vsprintf(dst, format, vl); }
+	inline int FBXSDK_vsnprintf(char* dst, size_t dstsize, const char* format, va_list vl){ return vsnprintf(dst, dstsize, format, vl); }
+	#define FBXSDK_stricmp(dst, src)				stricmp(dst, src)
+	#define FBXSDK_strnicmp(dst, src, count)		strnicmp(dst, src, count)
+	#define FBXSDK_strcpy(dst, size, src)			strcpy(dst, src)
+	#define FBXSDK_strncpy(dst, size, src, count)	strncpy(dst, src, count)
+	#define FBXSDK_strcat(dst, size, src)			strcat(dst, src)
+	#define FBXSDK_strtok(str, delim, ctx)			strtok(str, delim)
+	#define FBXSDK_wcscpy(dst, size, src)			wcscpy(dst, src)
+	#define FBXSDK_wcscat(dst, size, src)			wcscat_s(dst, src)
+	#define FBXSDK_getpid							getpid	
+	#define FBXSDK_getcwd							getcwd
+	#define FBXSDK_localtime(tm, time)				tm=localtime(time)
+	#define FBXSDK_gmtime(tm, time)					tm=gmtime(time)
+	#define FBXSDK_fopen(fp, name, mode)			fp=fopen(name, mode)
+
+#else
+	#error Unsupported platform!
+#endif
+
+#define FBXSDK_strdup								FbxStrDup
+
+//The scanf family functions cannot easily be used in both secure and non-secure versions because
+//Microsoft's secure version expects the size of the string/char* arguments following their address.
+//On Unix machines the scanf family functions do not have this behavior and trying to use the same
+//calls would result in compiler errors because the arguments would not match the format string.
+//Using the following macros in the code will simply desable the warning at compile time.
+#if defined(FBXSDK_COMPILER_MSC) && (_MSC_VER >= 1300)
+	#define FBXSDK_CRT_SECURE_NO_WARNING_BEGIN\
+	{\
+		__pragma(warning(push))\
+		__pragma(warning(disable : 4996))\
+	}
+    
+	#define FBXSDK_CRT_SECURE_NO_WARNING_END\
+	{\
+		__pragma(warning(pop))\
+	}
+#else
+	#define FBXSDK_CRT_SECURE_NO_WARNING_BEGIN
+	#define FBXSDK_CRT_SECURE_NO_WARNING_END
+#endif
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* _FBXSDK_CORE_ARCH_STDCOMPLIANT_H_ */

+ 264 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/arch/fbxtypes.h

@@ -0,0 +1,264 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+/** \file fbxtypes.h
+  * Basic types definition.
+  *
+  * Standard basic types used across the FBX SDK. There is also platform independent
+  * definitions that guarantee size across operating systems. The FBXSDK_SYSTEM_IS_LP64
+  * define is set to 1 when the operating system defines the "long" C++ type as 64-bit.
+  */
+#ifndef _FBXSDK_CORE_ARCH_TYPES_H_
+#define _FBXSDK_CORE_ARCH_TYPES_H_
+
+#include <fbxsdk/core/arch/fbxarch.h>
+
+//Note: On MacOSX and Linux 64-bit, long is defined as 64-bits while on Windows
+//it is still a 32-bits for backward compatibility. We stick with Windows standard.
+#if defined(FBXSDK_CPU_64) && !defined(FBXSDK_ENV_WIN)
+	#define FBXSDK_SYSTEM_IS_LP64 1
+#endif
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+class FbxObject;
+
+typedef bool			FbxBool;
+typedef signed char		FbxChar;
+typedef unsigned char	FbxUChar;
+typedef signed short	FbxShort;
+typedef unsigned short	FbxUShort;
+typedef signed int		FbxInt;
+typedef unsigned int	FbxUInt;
+typedef float			FbxFloat;
+typedef double			FbxDouble;
+
+typedef FbxBool*		FbxBoolPtr;
+typedef FbxChar*		FbxCharPtr;
+typedef FbxUChar*		FbxUCharPtr;
+typedef FbxShort*		FbxShortPtr;
+typedef FbxUShort*		FbxUShortPtr;
+typedef FbxInt*			FbxIntPtr;
+typedef FbxUInt*		FbxUIntPtr;
+typedef FbxFloat*		FbxFloatPtr;
+typedef FbxDouble*		FbxDoublePtr;
+
+typedef FbxInt			FbxEnum;
+typedef FbxObject*		FbxReference;
+
+//-------------------------------------------------------------------------------------
+//Architecture independent defines (guarantee size)
+#if defined(FBXSDK_COMPILER_MSC)
+	#define FBXSDK_LONGLONG(x)	(x##i64)
+	#define FBXSDK_ULONGLONG(x)	(x##Ui64)
+
+	typedef signed __int8		FbxInt8;
+	typedef unsigned __int8		FbxUInt8;
+	typedef signed __int16		FbxInt16;
+	typedef unsigned __int16	FbxUInt16;
+	typedef signed __int32		FbxInt32;
+	typedef unsigned __int32	FbxUInt32;
+	typedef signed __int64		FbxInt64;
+	typedef unsigned __int64	FbxUInt64;
+#else
+	#define FBXSDK_LONGLONG(x)	(x##LL)
+	#define FBXSDK_ULONGLONG(x)	(x##ULL)
+
+	typedef signed char			FbxInt8;
+	typedef unsigned char		FbxUInt8;
+	typedef signed short		FbxInt16;
+	typedef unsigned short		FbxUInt16;
+	typedef signed int			FbxInt32;
+	typedef unsigned int		FbxUInt32;
+	typedef signed long long	FbxInt64;
+	typedef unsigned long long	FbxUInt64;
+#endif
+
+#ifdef FBXSDK_SYSTEM_IS_LP64
+	typedef signed int			FbxLong;
+	typedef unsigned int		FbxULong;
+#else
+	typedef signed long			FbxLong;
+	typedef unsigned long		FbxULong;
+#endif
+typedef FbxInt64				FbxLongLong;
+typedef FbxUInt64				FbxULongLong;
+
+typedef FbxLong*				FbxLongPtr;
+typedef FbxULong*				FbxULongPtr;
+typedef FbxLongLong*			FbxLongLongPtr;
+typedef FbxULongLong*			FbxULongLongPtr;
+
+
+#if defined(FBXSDK_ENV_EMSCRIPTEN)
+	typedef FbxInt32 			__int32_t;
+	typedef FbxUInt32			__uint32_t;
+	typedef FbxInt64  			__int64_t;
+	typedef FbxUInt64			__uint64_t;
+#endif
+
+//-------------------------------------------------------------------------------------
+//Minimum and Maximum values for types
+#define FBXSDK_CHAR_MIN			-128
+#define FBXSDK_CHAR_MAX			127
+#define FBXSDK_UCHAR_MIN		0
+#define FBXSDK_UCHAR_MAX		255
+#define FBXSDK_SHORT_MIN		-32768
+#define FBXSDK_SHORT_MAX		32767
+#define FBXSDK_USHORT_MIN		0
+#define FBXSDK_USHORT_MAX		65535
+#define FBXSDK_INT_MIN			0x80000000
+#define FBXSDK_INT_MAX			0x7fffffff
+#define FBXSDK_UINT_MIN			0
+#define FBXSDK_UINT_MAX			0xffffffff
+#define FBXSDK_LONG_MIN			FBXSDK_INT_MIN
+#define FBXSDK_LONG_MAX			FBXSDK_INT_MAX
+#define FBXSDK_ULONG_MIN		FBXSDK_UINT_MIN
+#define FBXSDK_ULONG_MAX		FBXSDK_UINT_MAX
+#define FBXSDK_LONGLONG_MIN		FBXSDK_LONGLONG(0x8000000000000000)
+#define FBXSDK_LONGLONG_MAX		FBXSDK_LONGLONG(0x7fffffffffffffff)
+#define FBXSDK_ULONGLONG_MIN	FBXSDK_ULONGLONG(0)
+#define FBXSDK_ULONGLONG_MAX	FBXSDK_ULONGLONG(0xffffffffffffffff)
+#define FBXSDK_FLOAT_MIN		FLT_MIN
+#define FBXSDK_FLOAT_MAX		FLT_MAX
+#define FBXSDK_FLOAT_EPSILON	FLT_EPSILON
+#define FBXSDK_DOUBLE_MIN		DBL_MIN
+#define FBXSDK_DOUBLE_MAX		DBL_MAX
+#define FBXSDK_DOUBLE_EPSILON	DBL_EPSILON
+#define FBXSDK_TOLERANCE		(1.0e-6)
+
+//-------------------------------------------------------------------------------------
+//Handle and atomic definition (size change depending of architecture)
+#if defined(FBXSDK_CPU_32)
+	typedef FbxUInt32			FbxHandle;
+	#define FBXSDK_REF_MIN		FBXSDK_UINT_MIN
+	#define FBXSDK_REF_MAX		FBXSDK_UINT_MAX
+
+	typedef FbxLong				FbxAtomic;
+	#define FBXSDK_ATOMIC_MIN	FBXSDK_LONG_MIN
+	#define FBXSDK_ATOMIC_MAX	FBXSDK_LONG_MAX
+#elif defined(FBXSDK_CPU_64)
+	typedef FbxUInt64			FbxHandle;
+	#define FBXSDK_REF_MIN		FBXSDK_ULONGLONG_MIN
+	#define FBXSDK_REF_MAX		FBXSDK_ULONGLONG_MAX
+
+	typedef FbxInt64			FbxAtomic;
+	#define FBXSDK_ATOMIC_MIN	FBXSDK_LONGLONG_MIN
+	#define FBXSDK_ATOMIC_MAX	FBXSDK_LONGLONG_MAX
+#else
+	#error Unsupported architecture!
+#endif
+
+//-------------------------------------------------------------------------------------
+//Various utility functions for fbxsdk basic types
+inline const FbxChar				FbxMin(const FbxChar){ return FBXSDK_CHAR_MIN; }
+inline const FbxUChar				FbxMin(const FbxUChar){ return FBXSDK_UCHAR_MIN; }
+inline const FbxShort				FbxMin(const FbxShort){ return FBXSDK_SHORT_MIN; }
+inline const FbxUShort				FbxMin(const FbxUShort){ return FBXSDK_USHORT_MIN; }
+inline const FbxInt					FbxMin(const FbxInt){ return FBXSDK_INT_MIN; }
+inline const FbxUInt				FbxMin(const FbxUInt){ return FBXSDK_UINT_MIN; }
+inline const FbxLongLong			FbxMin(const FbxLongLong){ return FBXSDK_LONGLONG_MIN; }
+inline const FbxULongLong			FbxMin(const FbxULongLong){ return FBXSDK_ULONGLONG_MIN; }
+inline const FbxFloat				FbxMin(const FbxFloat){ return FBXSDK_FLOAT_MIN; }
+inline const FbxDouble				FbxMin(const FbxDouble){ return FBXSDK_DOUBLE_MIN; }
+
+inline const FbxChar				FbxMax(const FbxChar){ return FBXSDK_CHAR_MAX; }
+inline const FbxUChar				FbxMax(const FbxUChar){ return FBXSDK_UCHAR_MAX; }
+inline const FbxShort				FbxMax(const FbxShort){ return FBXSDK_SHORT_MAX; }
+inline const FbxUShort				FbxMax(const FbxUShort){ return FBXSDK_USHORT_MAX; }
+inline const FbxInt					FbxMax(const FbxInt){ return FBXSDK_INT_MAX; }
+inline const FbxUInt				FbxMax(const FbxUInt){ return FBXSDK_UINT_MAX; }
+inline const FbxLongLong			FbxMax(const FbxLongLong){ return FBXSDK_LONGLONG_MAX; }
+inline const FbxULongLong			FbxMax(const FbxULongLong){ return FBXSDK_ULONGLONG_MAX; }
+inline const FbxFloat				FbxMax(const FbxFloat){ return FBXSDK_FLOAT_MAX; }
+inline const FbxDouble				FbxMax(const FbxDouble){ return FBXSDK_DOUBLE_MAX; }
+
+#ifndef FBXSDK_SYSTEM_IS_LP64
+	inline const FbxLong			FbxMin(const FbxLong){ return FBXSDK_LONG_MIN; }
+	inline const FbxULong			FbxMin(const FbxULong){ return FBXSDK_ULONG_MIN; }
+	inline const FbxLong			FbxMax(const FbxLong){ return FBXSDK_LONG_MAX; }
+	inline const FbxULong			FbxMax(const FbxULong){ return FBXSDK_ULONG_MAX; }
+#endif
+
+template<class T> inline const T	FbxMin(const T){};
+template<class T> inline const T	FbxMax(const T){};
+
+template<class T> inline T			FbxMin(const T x, const T y){ return (x < y) ? x : y; }
+template<class T> inline T			FbxMax(const T x, const T y){ return (x > y) ? x : y; }
+
+//-------------------------------------------------------------------------------------
+//Vector Template Types
+template<class T> class FBXSDK_DLL FbxVectorTemplate2
+{
+public:
+	inline FbxVectorTemplate2(){ *this = T(0); }
+	inline explicit FbxVectorTemplate2(T pValue){ *this = pValue; }
+	inline FbxVectorTemplate2(T pData0, T pData1){ mData[0] = pData0; mData[1] = pData1; }
+	inline ~FbxVectorTemplate2(){}
+	inline T& operator[](int pIndex){ return mData[pIndex]; }
+	inline const T& operator[](int pIndex) const { return mData[pIndex]; }
+	inline FbxVectorTemplate2<T>& operator=(const T& pValue){ mData[0] = pValue; mData[1] = pValue; return *this; }
+	inline FbxVectorTemplate2<T>& operator=(const FbxVectorTemplate2<T>& pVector){ mData[0] = pVector.mData[0]; mData[1] = pVector.mData[1]; return *this; }
+	inline bool operator==(const FbxVectorTemplate2<T>& pVector) const { return ((mData[0] == pVector.mData[0]) && (mData[1] == pVector.mData[1])); }
+	inline bool operator!=(const FbxVectorTemplate2<T>& pVector) const { return !operator==( pVector ); }
+	inline T* Buffer(){ return mData; }
+	inline const T* Buffer() const { return mData; }
+	T mData[2];
+};
+
+template<class T> class FBXSDK_DLL FbxVectorTemplate3
+{
+public:
+	inline FbxVectorTemplate3(){ *this = T(0); }
+	inline explicit FbxVectorTemplate3(T pValue){ *this = pValue; }
+	inline FbxVectorTemplate3(T pData0, T pData1, T pData2){ mData[0] = pData0; mData[1] = pData1; mData[2] = pData2; }
+	inline ~FbxVectorTemplate3(){}
+	inline T& operator[](int pIndex) { return mData[pIndex]; }
+	inline const T& operator[](int pIndex) const { return mData[pIndex]; }
+	inline operator FbxVectorTemplate2<T>& () const { return *((FbxVectorTemplate2<T>*)this); }
+	inline FbxVectorTemplate3<T>& operator=(T const &pValue){ mData[0] = pValue; mData[1] = pValue; mData[2] = pValue; return *this; }
+	inline FbxVectorTemplate3<T>& operator=(const FbxVectorTemplate2<T>& pVector){ mData[0] = pVector.mData[0]; mData[1] = pVector.mData[1]; return *this; }
+	inline FbxVectorTemplate3<T>& operator=(const FbxVectorTemplate3<T>& pVector){ mData[0] = pVector.mData[0]; mData[1] = pVector.mData[1]; mData[2] = pVector.mData[2]; return *this; }
+	inline bool operator==(const FbxVectorTemplate3<T>& pVector) const { return ((mData[0] == pVector.mData[0]) && (mData[1] == pVector.mData[1]) && (mData[2] == pVector.mData[2])); }
+	inline bool operator!=(const FbxVectorTemplate3<T>& pVector) const { return !operator==(pVector); }
+	inline T* Buffer(){ return mData; }
+	inline const T* Buffer() const { return mData; }
+	T mData[3];
+};
+
+template<class T> class FBXSDK_DLL FbxVectorTemplate4
+{
+public:
+	inline FbxVectorTemplate4(){ *this = T(0); }
+	inline explicit FbxVectorTemplate4(T pValue){ *this = pValue; }
+	inline FbxVectorTemplate4(T pData0, T pData1, T pData2, T pData3){ mData[0] = pData0; mData[1] = pData1; mData[2] = pData2; mData[3] = pData3; }
+	inline ~FbxVectorTemplate4(){}
+	inline T& operator[](int pIndex){ return mData[pIndex]; }
+	inline const T& operator[](int pIndex) const { return mData[pIndex]; }
+	inline operator FbxVectorTemplate3<T>& () const { return *((FbxVectorTemplate3<T>*)this); }
+	inline FbxVectorTemplate4<T>& operator=(const T& pValue){ mData[0] = pValue; mData[1] = pValue; mData[2] = pValue; mData[3] = pValue; return *this; }
+	inline FbxVectorTemplate4<T>& operator=(const FbxVectorTemplate3<T>& pValue){ mData[0] = pValue[0]; mData[1] = pValue[1]; mData[2] = pValue[2]; return *this; }
+	inline FbxVectorTemplate4<T>& operator=(const FbxVectorTemplate4<T>& pVector){ mData[0] = pVector.mData[0]; mData[1] = pVector.mData[1]; mData[2] = pVector.mData[2]; mData[3] = pVector.mData[3]; return *this; }
+	inline bool operator==(const FbxVectorTemplate4<T>& pVector) const { return ((mData[0] == pVector.mData[0]) && (mData[1] == pVector.mData[1]) && (mData[2] == pVector.mData[2]) && (mData[3] == pVector.mData[3])); }
+	inline bool operator!=(const FbxVectorTemplate4<T>& pVector) const { return !operator==( pVector ); }
+	inline T* Buffer(){ return mData; }
+	inline const T* Buffer() const { return mData; }
+	T mData[4];
+};
+
+typedef FbxVectorTemplate2<FbxDouble> FbxDouble2;
+typedef FbxVectorTemplate3<FbxDouble> FbxDouble3;
+typedef FbxVectorTemplate4<FbxDouble> FbxDouble4;
+typedef FbxVectorTemplate4<FbxDouble4> FbxDouble4x4;
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* _FBXSDK_CORE_ARCH_TYPES_H_ */

+ 487 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/base/fbxarray.h

@@ -0,0 +1,487 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxarray.h
+#ifndef _FBXSDK_CORE_BASE_ARRAY_H_
+#define _FBXSDK_CORE_BASE_ARRAY_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+/** Class for array of basic elements such as pointers and basic types. This class will not
+* call constructor and destructor for elements, thus it is not suitable for object references.
+* Memory allocations are always done in a single contiguous memory region. */
+template <class T> class FbxArray
+{
+public:
+	//! Element compare function pointer definition
+	typedef int (*CompareFunc)(const void*, const void*);
+
+	//! Constructor.
+	FbxArray() : mSize(0), mCapacity(0), mArray(NULL){}
+
+	//! Reserve constructor.
+	FbxArray(const int pCapacity) : mSize(0), mCapacity(0), mArray(NULL){ if( pCapacity > 0 ) Reserve(pCapacity); }
+
+	//! Copy constructor.
+	FbxArray(const FbxArray& pArray) : mSize(0), mCapacity(0), mArray(NULL){ *this = pArray; }
+
+	/** Destructor.
+	* \remark The destructor for each element will not be called. */
+	~FbxArray(){ Clear(); }
+
+	/** Insert an element at the given position, growing the array if capacity is not sufficient.
+	* \param pIndex Position where to insert the element. Must be a positive value.
+	* \param pElement Element to insert in the array.
+	* \param pCompact If \c true and capacity is exceeded, grow capacity by one, otherwise double capacity (default).
+	* \return -1 if insert failed, otherwise the position of the inserted element in the array.
+	* \remark If the given index is greater than Size(), the element is appended at the end. Use compact mode only if you need to save memory. */
+	inline int InsertAt(const int pIndex, const T& pElement, bool pCompact=false)
+	{
+		FBX_ASSERT_RETURN_VALUE(pIndex >= 0, -1);
+		int lIndex = FbxMin(pIndex, mSize);
+		if( mSize >= mCapacity )
+		{
+			T lElement = pElement;	//Copy element because we might move memory
+			int lNewCapacity = FbxMax(pCompact ? mCapacity + 1 : mCapacity * 2, 1);	//We always double capacity when not compacting
+			T* lArray = Allocate(lNewCapacity);
+			FBX_ASSERT_RETURN_VALUE(lArray, -1);
+			mArray = lArray;
+			mCapacity = lNewCapacity;
+			return InsertAt(pIndex, lElement);	//Insert copied element because reference might be moved
+		}
+
+		if( lIndex < mSize )	//Move elements to leave a space open to insert the new element
+		{
+			//If pElement is inside memmove range, copy element and insert copy instead
+			if( (&pElement >= &mArray[lIndex]) && (&pElement < &mArray[mSize]) )
+			{
+				T lElement = pElement;
+				return InsertAt(pIndex, lElement);
+			}
+			memmove(&mArray[lIndex + 1], &mArray[lIndex], (mSize - lIndex) * sizeof(T));
+		}
+
+		memcpy(&mArray[lIndex], &pElement, sizeof(T));
+		mSize++;
+
+		return lIndex;
+	}
+
+	/** Append an element at the end of the array, doubling the array if capacity is not sufficient.
+	* \param pElement Element to append to the array.
+	* \return -1 if add failed, otherwise the position of the added element in the array. */
+	inline int Add(const T& pElement)
+	{
+		return InsertAt(mSize, pElement);
+	}
+
+	/** Append an element at the end of array, if not already present, doubling the array if capacity is not sufficient.
+	* \param pElement Element to append to the array.
+	* \return -1 if add failed, otherwise the position of the added element in the array. */
+	inline int AddUnique(const T& pElement)
+	{
+		int lIndex = Find(pElement);
+		return ( lIndex == -1 ) ? Add(pElement) : lIndex;
+	}
+
+	/** Append an element at the end of the array, growing the array by one element if capacity is not sufficient.
+	* \param pElement Element to append to the array.
+	* \return -1 if add failed, otherwise the position of the added element in the array. */
+	inline int AddCompact(const T& pElement)
+	{
+		return InsertAt(mSize, pElement, true);
+	}
+
+	/** Retrieve the number of element contained in the array. To increase the capacity without increasing the size, please use Reserve().
+	* \return The number of element in the array.
+	* \remark The size of the array cannot exceed its capacity. */
+	inline int Size() const { return mSize; }
+
+	/** Retrieve the current allocated memory capacity of the array.
+	* \return The capacity of the array in number of element.
+	* \remark The capacity will always be greater or equal to its size. */
+	inline int Capacity() const { return mCapacity; }
+
+	/** Retrieve a reference of the element at given index position in the array.
+	* \param pIndex Position of element in the array.
+	* \return A reference to the element at the specified position in the array.
+	* \remark No error will be thrown if the index is out of bounds. */
+	inline T& operator[](const int pIndex) const
+	{
+	#ifdef _DEBUG
+		FBX_ASSERT_MSG(pIndex >= 0, "Index is out of range!");
+		if( pIndex >= mSize )
+		{
+			if( pIndex < mCapacity )
+			{
+				FBX_ASSERT_NOW("Index is out of range, but not outside of capacity! Call SetAt() to use reserved memory.");
+			}
+			else FBX_ASSERT_NOW("Index is out of range!");
+		}
+	#endif
+		return (T&)mArray[pIndex];
+	}
+
+	/** Retrieve a copy of the element at given index position in the array.
+	* \param pIndex Position of element in the array.
+	* \return The value of the element at the specified position in the array.
+	* \remark No error will be thrown if the index is out of bounds. */
+	inline T GetAt(const int pIndex) const
+	{
+		return operator[](pIndex);
+	}
+
+	/** Retrieve a copy of the first element.
+	* \return Copy of the first element.
+	* \remark The array should have at least one element and no error will be thrown if the array is empty. */
+	inline T GetFirst() const
+	{
+		return GetAt(0);
+	}
+
+	/** Retrieve a copy of the last element.
+	* \return Copy of the last element.
+	* \remark The array should have at least one element and no error will be thrown if the array is empty. */
+	inline T GetLast() const
+	{
+		return GetAt(mSize-1);
+	}
+
+	/** Find first matching element, from first to last.
+	* \param pElement The element to be compared to each of the elements.
+	* \param pStartIndex The position to start searching from.
+	* \return Position of first matching element or -1 if there is no matching element. */
+	inline int Find(const T& pElement, const int pStartIndex=0) const
+	{
+		FBX_ASSERT_RETURN_VALUE(pStartIndex >= 0, -1);
+		for( int i = pStartIndex; i < mSize; ++i )
+		{
+			if( operator[](i) == pElement ) return i;
+		}
+		return -1;
+	}
+
+	/** Find first matching element, from last to first.
+	* \param pElement The element to be compared to each of the elements.
+	* \param pStartIndex The position to start searching from.
+	* \return Position of first matching element or -1 if there is no matching element. */
+	inline int FindReverse(const T& pElement, const int pStartIndex=FBXSDK_INT_MAX) const
+	{
+		for( int i = FbxMin(pStartIndex, mSize-1); i >= 0; --i )
+		{
+			if( operator[](i) == pElement ) return i;
+		}
+		return -1;
+	}
+
+	/** Request for allocation of additional memory without inserting new elements. After the memory has been reserved, please use SetAt() to initialize elements.
+	* \param pCapacity The number of additional element memory allocation requested.
+	* \return \c true if the memory allocation succeeded or if the capacity is unchanged, \c false otherwise.
+	* \remark If the requested capacity is less than or equal to the current capacity, this call has no effect. In either case, Size() is unchanged. */
+	inline bool Reserve(const int pCapacity)
+	{
+		FBX_ASSERT_RETURN_VALUE(pCapacity > 0, false);
+		if( pCapacity > mCapacity )
+		{
+			T* lArray = Allocate(pCapacity);
+			FBX_ASSERT_RETURN_VALUE(lArray, false);
+			mArray = lArray;
+			mCapacity = pCapacity;
+
+			//Initialize new memory to zero
+			memset(&mArray[mSize], 0, (mCapacity - mSize) * sizeof(T));
+		}
+		return true;
+	}
+
+	/** Set the element at given position in the array.
+	* \param pIndex Position of element in the array.
+	* \param pElement The new element.
+	* \remark If the index is outside range, and outside capacity, this call has no effect. However, if index is
+	* within capacity range, element count is increased such that Size() will become pIndex + 1. */
+	inline void SetAt(const int pIndex, const T& pElement)
+	{
+		FBX_ASSERT_RETURN(pIndex < mCapacity);
+		if( pIndex >= mSize ) mSize = pIndex + 1;
+		if( mArray ) memcpy(&mArray[pIndex], &pElement, sizeof(T));
+	}
+
+	/** Set the value of the first element.
+	* \param pElement The new value of the last element.
+	* \remark The array should have at least one element and no error will be thrown if the array is empty. */
+	inline void SetFirst(const T& pElement)
+	{
+		SetAt(0, pElement);
+	}
+
+	/** Set the value of the last element.
+	* \param pElement The new value of the last element.
+	* \remark The array should have at least one element and no error will be thrown if the array is empty. */
+	inline void SetLast(const T& pElement)
+	{
+		SetAt(mSize-1, pElement);
+	}
+
+	/** Remove an element at the given position in the array.
+	* \param pIndex Position of the element to remove.
+	* \return Removed element.
+	* \remark No error will be thrown if the index is out of bounds. */
+	inline T RemoveAt(const int pIndex)
+	{
+		T lElement = GetAt(pIndex);
+		if( pIndex + 1 < mSize )
+		{
+			memmove(&mArray[pIndex], &mArray[pIndex + 1], (mSize - pIndex - 1) * sizeof(T));
+		}
+		mSize--;
+		return lElement;
+	}
+
+	/** Remove the first element in the array.
+	* \return Removed element.
+	* \remark The array should have at least one element and no error will be thrown if the array is empty. */
+	inline T RemoveFirst()
+	{
+		return RemoveAt(0);
+	}
+
+	/** Remove the last element in the array.
+	* \return Removed element.
+	* \remark The array should have at least one element and no error will be thrown if the array is empty. */
+	inline T RemoveLast()
+	{
+		return RemoveAt(mSize-1);
+	}
+
+	/** Remove first matching element in the array.
+	* \param pElement Element to be removed.
+	* \return \c true if a matching element is found and removed, \c false otherwise. */
+	inline bool RemoveIt(const T& pElement)
+	{
+		int Index = Find(pElement);
+		if( Index >= 0 )
+		{
+			RemoveAt(Index);
+			return true;
+		}
+		return false;
+	}
+
+	/** Remove a range of elements at the given position in the array.
+	* \param pIndex Begin position of the elements to remove.
+	* \param pCount The count of elements to remove.
+	* \return \c true if successful, otherwise \c false. */
+	inline void RemoveRange(const int pIndex, const int pCount)
+	{
+		if( pIndex + pCount < mSize )
+		{
+			memmove(&mArray[pIndex], &mArray[pIndex + pCount], (mSize - pIndex - pCount) * sizeof(T));
+		}
+		mSize -= pCount;
+	}
+
+	/** Inserts or erases elements at the end such that Size() becomes pSize, increasing capacity if needed. Please use SetAt() to initialize any new elements.
+	* \param pSize The new count of elements to set the array to. Must be greater or equal to zero.
+	* \return \c true if the memory (re)allocation succeeded, \c false otherwise.
+	* \remark If the requested element count is less than or equal to the current count, elements are freed from memory. Otherwise, the array grows and elements are unchanged. */
+	inline bool Resize(const int pSize)
+	{
+		if( pSize == mSize && mSize == mCapacity ) return true;
+
+		if( pSize == 0 )
+		{
+			Clear();
+			return true;
+		}
+
+		FBX_ASSERT_RETURN_VALUE(pSize > 0, false);
+		if( pSize != mCapacity )
+		{
+			T* lArray = Allocate(pSize);
+			FBX_ASSERT_RETURN_VALUE(lArray, false);
+			mArray = lArray;
+		}
+
+		if( pSize > mCapacity )	//Initialize new memory to zero
+		{
+			memset(&mArray[mSize], 0, (pSize - mSize) * sizeof(T));
+		}
+
+		mSize = pSize;
+		mCapacity = pSize;
+		return true;
+	}
+
+	/** Increase size of array by the specified size.
+	* \param pSize The size to add to the array size.
+	* \return \c true if operation succeeded, \c false otherwise. */
+	inline bool Grow(const int pSize)
+	{
+		return Resize(mSize + pSize);
+	}
+
+	/** Reduce size of array by the specified size.
+	* \param pSize The size to remove from the array size.
+	* \return \c true if operation succeeded, \c false otherwise. */
+	inline bool Shrink(const int pSize)
+	{
+		return Resize(mSize - pSize);
+	}
+
+	/** Compact the array so that its capacity is the same as its size.
+	* \return \c true if operation succeeded, \c false otherwise. */
+	inline bool Compact()
+	{
+		return Resize(mSize);
+	}
+
+	/** Reset the number of element to zero and free the memory allocated.
+	* \remark This only free the memory allocated by the array, and doesn't call the destructor of each element. */
+	inline void Clear()
+	{
+		if( mArray != NULL )
+		{
+			mSize = 0;
+			mCapacity = 0;
+			FbxFree(mArray);
+			mArray = NULL;
+		}
+	}
+
+	/** Sort the array using the specified compare function pointer
+	* \param pCompareFunc The compare function to use to sort elements. */
+	inline void Sort(CompareFunc pCompareFunc)
+	{
+		qsort(mArray, mSize, sizeof(T), pCompareFunc);
+	}
+
+	//! Get pointer to internal array of elements.
+	inline T* GetArray() const { return mArray ? (T*)mArray : NULL; }
+
+	//! Cast operator.
+	inline operator T* (){ return mArray ? (T*)mArray : NULL; }
+
+	/** Append another array at the end of this array.
+	* \param pOther The other array to append to this array. */
+	inline void AddArray(const FbxArray<T>& pOther)
+	{
+		if( Grow(pOther.mSize) )
+		{
+			memcpy(&mArray[mSize - pOther.mSize], pOther.mArray, pOther.mSize * sizeof(T));
+		}
+	}
+
+	/** Append the elements of another array at the end of this array if they are not present.
+	* \param pOther Another array. */
+	inline void AddArrayNoDuplicate(const FbxArray<T>& pOther)
+	{
+		for( int i = 0, c = pOther.mSize; i < c; ++i )
+		{
+			AddUnique(pOther[i]);
+		}
+	}
+
+	/** Remove the elements of another array from this array is they are present.
+	* \param pOther Another array. */
+	inline void RemoveArray(const FbxArray<T>& pOther)
+	{
+		for( int i = 0, c = pOther.mSize; i < c; ++i )
+		{
+			RemoveIt(pOther[i]);
+		}
+	}
+
+	/** Operator to copy elements of an array.
+	* \return this array containing a copy of pOther elements. */
+	inline FbxArray<T>& operator=(const FbxArray<T>& pOther)
+	{
+		if( this != &pOther )
+		{
+			if( Resize(pOther.mSize) )
+			{
+				memcpy(mArray, pOther.mArray, pOther.mSize * sizeof(T));
+			}
+		}
+		return *this;
+	}
+
+	/** Operator to compare elements of an array.
+	* \return \c true if the two arrays are equal, otherwise \c false. */
+	inline bool operator==(const FbxArray<T>& pOther) const
+	{
+		if( this == &pOther ) return true;
+		if( mSize != pOther.mSize ) return false;
+		return memcmp(mArray, pOther.mArray, sizeof(T) * mSize) == 0;
+	}
+
+/*****************************************************************************************************************************
+** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
+*****************************************************************************************************************************/
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+	inline int GetCount() const { return mSize; }
+
+private:
+	inline T* Allocate(const int pCapacity)
+	{
+		return (T*)FbxRealloc(mArray, pCapacity * sizeof(T));
+	}
+
+	int	mSize;
+	int	mCapacity;
+	T*	mArray;
+
+#if defined(FBXSDK_COMPILER_MSC)
+    //Previously class FbxArray is for pointers. Somehow, it's used to store other types. Here's a compile-time checking for known incompatible classes.
+    //If it happens you find new incompatible ones, declare them with macro FBXSDK_INCOMPATIBLE_WITH_ARRAY. Also see file fbxstring.h.
+    FBX_ASSERT_STATIC(FBXSDK_IS_SIMPLE_TYPE(T) || __is_enum(T) || (__has_trivial_constructor(T)&&__has_trivial_destructor(T)) || !FBXSDK_IS_INCOMPATIBLE_WITH_ARRAY(T));
+#endif
+
+#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
+};
+
+//! Call FbxFree on each element of the array, and then clear it.
+template <class T> inline void FbxArrayFree(FbxArray<T>& pArray)
+{
+	for( int i = 0, c = pArray.Size(); i < c; ++i )
+	{
+		FbxFree(pArray[i]);
+	}
+	pArray.Clear();
+}
+
+//! Call FbxDelete on each element of the array, and then clear it.
+template <class T> inline void FbxArrayDelete(FbxArray<T>& pArray)
+{
+	for( int i = 0, c = pArray.Size(); i < c; ++i )
+	{
+		FbxDelete(pArray[i]);
+	}
+	pArray.Clear();
+}
+
+//! Call Destroy on each element of the array, and then clear it.
+template <class T> inline void FbxArrayDestroy(FbxArray<T>& pArray)
+{
+	for( int i = 0, c = pArray.Size(); i < c; ++i )
+	{
+		(pArray[i])->Destroy();
+	}
+	pArray.Clear();
+}
+
+//! Make sure to break build if someone try to make FbxArray<FbxArray<T>>, which is not supported.
+template <class T> FBXSDK_INCOMPATIBLE_WITH_ARRAY_TEMPLATE(FbxArray<T>);
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* _FBXSDK_CORE_BASE_ARRAY_H_ */

+ 90 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/base/fbxbitset.h

@@ -0,0 +1,90 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxbitset.h
+#ifndef _FBXSDK_CORE_BASE_BITSET_H_
+#define _FBXSDK_CORE_BASE_BITSET_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+/** An automatic growing array of bit.
+  *
+  * The bit array will automatically grow when specifying bit indexes that are greater
+  * than the array size when calling SetBit or UnsetBit. Indexes can vary from 0 to
+  * FBXSDK_UINT_MAX-1. When an invalid index is returned from any functions, FBXSDK_UINT_MAX
+  * is returned. The bit array is not thread safe.
+  */
+class FBXSDK_DLL FbxBitSet
+{
+public:
+	/** Constructor.
+	  * \param pInitialSize Initial bit array size in bit count (not in byte count!).
+	  */
+	FbxBitSet(const FbxUInt pInitialSize=0);
+
+	//! Destructor.
+	virtual ~FbxBitSet();
+
+	/** Set the bit at the specified bit index to true regardless of its current value.
+	  * \param pBitIndex The bit index in the array in the range of [0, FBXSDK_UINT_MAX-1].
+	  */
+	void SetBit(const FbxUInt pBitIndex);
+
+	/** Set all the bits to the specified value regardless of their current value.
+	  * \param pValue The boolean value to set to all bits.
+	  */
+	void SetAllBits(const bool pValue);
+
+	/** Set the bit at the specified bit index to false regardless of its current value.
+	  * \param pBitIndex The bit index in the array in the range of [0, FBXSDK_UINT_MAX-1].
+	  */
+	void UnsetBit(const FbxUInt pBitIndex);
+
+	/** Get the bit boolean value at the specified bit index.
+	  * \param pBitIndex The bit index in the array in the range of [0, FBXSDK_UINT_MAX-1].
+	  * \return True if the bit is set, false otherwise.
+	  */
+	bool GetBit(const FbxUInt pBitIndex) const;
+
+	/** Get the bit index of the first bit that is currently set.
+	  * \return The bit index of the first set bit, FBXSDK_UINT_MAX if none found.
+	  */
+	FbxUInt GetFirstSetBitIndex() const;
+
+	/** Get the bit index of the last bit that is currently set.
+	  * \return The bit index of the last set bit, FBXSDK_UINT_MAX if none found.
+	  */
+	FbxUInt GetLastSetBitIndex() const;
+
+	/** Get the bit index of the next set bit after the specified bit index.
+	  * \param pBitIndex The start bit index in the array in the range of [0, FBXSDK_UINT_MAX-1].
+	  * \return The bit index of the next set bit, FBXSDK_UINT_MAX if none found.
+	  */
+	FbxUInt GetNextSetBitIndex(const FbxUInt pBitIndex) const;
+
+	/** Get the bit index of the previous set bit before the specified bit index.
+	  * \param pBitIndex The start bit index in the array in the range of [0, FBXSDK_UINT_MAX-1].
+	  * \return The bit index of the previous set bit, FBXSDK_UINT_MAX if none found.
+	  */
+	FbxUInt GetPreviousSetBitIndex(const FbxUInt pBitIndex) const;
+
+private:
+	void Grow(const FbxUInt pNewSize);
+
+	void* mData;
+	FbxUInt mSize;
+};
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* _FBXSDK_CORE_BASE_BITSET_H_ */

+ 95 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/base/fbxcharptrset.h

@@ -0,0 +1,95 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxcharptrset.h
+#ifndef _FBXSDK_CORE_BASE_CHARPTRSET_H_
+#define _FBXSDK_CORE_BASE_CHARPTRSET_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+/** This class contains the data structure support for char pointer set.
+  */
+class FBXSDK_DLL FbxCharPtrSet
+{
+public:
+	/** Class constructor
+	* \param pItemPerBlock Number of item per block. Default is 20. */
+	FbxCharPtrSet(int pItemPerBlock=20);
+
+	//! Class destructor
+	~FbxCharPtrSet();
+
+	/** Add a new item.
+	* \param pReference char pointer reference to the item.
+	* \param pItem FbxHandle to the item. */
+	void Add(const char* pReference, FbxHandle pItem);
+
+	/** Removes an item.
+	* \param pReference char reference to the item.
+	* \return true if successful. */
+	bool Remove(const char* pReference);
+
+	/** Get an item's reference.
+	* \param pReference char reference to the item.
+	* \param PIndex index to the item.
+	* \return FbxHandle to the item, NULL if fails. */
+	FbxHandle Get(const char* pReference, int* PIndex=NULL);
+
+	/** Get an item's reference from index.
+	* \param pIndex index to the item.
+	* \return FbxHandle to the item, NULL if fails. */
+	FbxHandle& operator[](int pIndex);
+
+	/** Get an item's reference from index.
+	* \param pIndex index to the item.
+	* \param pReference char reference to the item.
+	* \return FbxHandle to the item, NULL if fails. */
+	FbxHandle GetFromIndex(int pIndex, const char** pReference=NULL);
+
+	/** Removes an item by index.
+	* \param pIndex index to the item. */
+	void RemoveFromIndex(int pIndex);
+
+	/** Get the number of item in the array.
+	* \return the number of element in the set. */
+	inline int GetCount() const { return mCharPtrSetCount; }
+
+	//! Sorts the array.
+	void Sort();
+
+	//! Clears the array.
+	void Clear();
+
+/*****************************************************************************************************************************
+** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
+*****************************************************************************************************************************/
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+	struct CharPtrSet;
+
+	inline void SetCaseSensitive(bool pIsCaseSensitive){ mIsCaseSensitive = pIsCaseSensitive; }
+
+private:
+	CharPtrSet*	FindEqual(const char* pReference) const;
+
+	CharPtrSet*	mCharPtrSetArray;
+	int			mCharPtrSetCount;
+	int			mBlockCount;
+	int			mItemPerBlock;
+	bool		mIsChanged;
+	bool		mIsCaseSensitive;
+#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
+};
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* _FBXSDK_CORE_BASE_CHARPTRSET_H_ */

+ 213 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/base/fbxcontainerallocators.h

@@ -0,0 +1,213 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxcontainerallocators.h
+#ifndef _FBXSDK_CORE_BASE_CONTAINER_ALLOCATORS_H_
+#define _FBXSDK_CORE_BASE_CONTAINER_ALLOCATORS_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+/** An allocator class for use as a template parameter to one of the
+  * container class (FbxMap, FbxSet, FbxDynamicArray...) must implement these.
+  */
+class FBXSDK_DLL FbxBaseAllocator
+{
+public:
+	/** The class constructor.  
+	  * \param pRecordSize the size of one record held by the container. 
+	  * \remarks The parameter pRecordSize is not necessarily the same 
+	  *  size as of the value type, since the
+	  *  container may wrap the value into a private class.
+	  */
+	FbxBaseAllocator(const size_t pRecordSize) :
+		mRecordSize(pRecordSize)
+	{
+	}
+
+	/** This tells the allocator that we are about to call AllocateRecords
+	  * one or many times to allocate pRecordCount records. 
+	  * \param pRecordCount
+	  * \remarks This gives the allocator a chance to do whatever it deems necessary
+	  * to optimize subsequent allocations, for example, by preallocating a
+	  * sufficiently large pool of memory.
+	  */
+	void Reserve(const size_t /*pRecordCount*/)
+	{
+		// By default, ignore all preallocating requests.
+	}
+
+	/** Returns a pointer to a uninitialized continuous block of memory
+	  * able to hold pRecordCount * pRecordSize  bytes.  
+	  * \param pRecordCount
+	  * \remarks pRecordSize was defined in the Constructor description, above.
+	  */
+	void* AllocateRecords(const size_t pRecordCount=1)
+	{
+		return FbxMalloc(pRecordCount * mRecordSize);
+	}
+
+	/** Frees a block of memory returned by AllocateRecords. 
+	  * \param pRecord
+	  */
+	void FreeMemory(void* pRecord)
+	{
+		FbxFree(pRecord);
+	}
+
+	/** \return the size of each record allocated. 
+	  */
+	size_t GetRecordSize() const
+	{
+		return mRecordSize;
+	}
+
+private:
+	size_t mRecordSize;
+};
+
+/** This allocator only frees the allocated memory when it is deleted.
+  * This is a good allocator for building dictionaries, where we only
+  * add things to a container, but never remove them.
+  */
+class FbxHungryAllocator
+{
+public:
+	FbxHungryAllocator(size_t pRecordSize) :
+		mRecordSize(pRecordSize),
+		mRecordPoolSize(0),
+		mData(NULL)
+	{
+	}
+
+	FbxHungryAllocator(const FbxHungryAllocator& pOther) :
+		mRecordSize(pOther.mRecordSize),
+		mRecordPoolSize(pOther.mRecordPoolSize),
+		mData(NULL)
+	{
+	}
+
+	~FbxHungryAllocator()
+	{
+		MemoryBlock* lCurrent = mData;
+		MemoryBlock* lNext = lCurrent ? lCurrent->mNextBlock : 0;
+		while (lCurrent)
+		{
+			FbxDelete(lCurrent);
+			lCurrent = lNext;
+			lNext = lCurrent ? lCurrent->mNextBlock : 0;
+		}
+	}
+
+	void Reserve(const size_t pRecordCount)
+	{
+		MemoryBlock* lMem = FbxNew< MemoryBlock >(pRecordCount* mRecordSize);
+		lMem->mNextBlock = mData;
+		mData = lMem;
+		mRecordPoolSize += pRecordCount;
+	}
+
+	void* AllocateRecords(const size_t pRecordCount = 1)
+	{
+		MemoryBlock* lBlock = mData;
+		void* lRecord = NULL;
+
+		while( (lBlock != NULL) && ((lRecord = lBlock->GetChunk(pRecordCount * mRecordSize)) == NULL) )
+		{
+			lBlock = lBlock->mNextBlock;
+		}
+
+		if( lRecord == NULL )
+		{
+			size_t lNumRecordToAllocate = mRecordPoolSize / 8 == 0 ? 2 : mRecordPoolSize / 8;
+			if( lNumRecordToAllocate < pRecordCount )
+			{
+				lNumRecordToAllocate = pRecordCount;
+			}
+			Reserve(lNumRecordToAllocate);
+			lRecord = AllocateRecords(pRecordCount);
+		}
+		return lRecord;
+	}
+
+	void FreeMemory(void* /*pRecord*/)
+	{
+		// "Hungry": release memory only when the allocator is destroyed.
+	}
+
+	size_t GetRecordSize() const
+	{
+		return mRecordSize;
+	}
+
+	FbxHungryAllocator& operator=(const FbxHungryAllocator& pOther)
+	{
+		if( this != &pOther )
+		{
+			// The next call to AllocateRecords() may skip over currently reserved
+			// records if the size changes drastically, but otherwise GetChunk()
+			// is size-oblivious.
+			if( mRecordSize < pOther.mRecordSize )
+			{
+				mRecordPoolSize = 0;
+			}
+
+			mRecordSize = pOther.mRecordSize;
+		}
+		return(*this);
+	}
+
+private:
+	class MemoryBlock
+	{
+	public:
+		MemoryBlock(size_t pSize) :
+			mNextBlock(NULL),
+			mData(NULL),
+			mFreeData(NULL),
+			mEnd(NULL)
+		{
+			mData = FbxMalloc(pSize);
+			mFreeData = mData;
+			mEnd = reinterpret_cast<char*>(mData) + pSize;
+		}
+
+		~MemoryBlock()
+		{
+			FbxFree(mData);
+		}
+
+		void* GetChunk(const size_t pSize)
+		{
+			if( reinterpret_cast<char*>(mFreeData) + pSize < mEnd )
+			{
+				void* lChunk = mFreeData;
+				mFreeData = reinterpret_cast<char*>(mFreeData) + pSize;
+				return lChunk;
+			}
+			return NULL;
+		}
+
+		MemoryBlock*	mNextBlock;
+		void*			mData;
+		void*			mFreeData;
+		void*			mEnd;
+	};
+
+	size_t			mRecordSize;
+	size_t			mRecordPoolSize;
+	MemoryBlock*	mData;
+};
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* _FBXSDK_CORE_BASE_CONTAINER_ALLOCATORS_H_ */

+ 324 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/base/fbxdynamicarray.h

@@ -0,0 +1,324 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxdynamicarray.h
+#ifndef _FBXSDK_CORE_BASE_DYNAMICARRAY_H_
+#define _FBXSDK_CORE_BASE_DYNAMICARRAY_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#include <fbxsdk/core/base/fbxcontainerallocators.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+/** Template class for dynamic array holding objects.
+  * \nosubgrouping
+  * \see FbxStaticArray
+  */
+template <typename Type, typename Allocator=FbxBaseAllocator> class FbxDynamicArray
+{
+public:
+	//! Default constructor.
+	FbxDynamicArray() :
+		mArray(NULL),
+		mCapacity(0),
+		mSize(0),
+		mAllocator(sizeof(Type))
+	{
+	}
+
+	/** Constructor.
+	* \param pInitialSize initial capacity of this array */
+	FbxDynamicArray(const size_t pInitialSize) :
+		mArray(NULL),
+		mCapacity(0),
+		mSize(0),
+		mAllocator(sizeof(Type))
+	{
+		Reserve(pInitialSize);
+	}
+
+	/** Copy constructor.
+	* \remarks The copy constructor of \c Type will be 
+	* invoked in order to copy the value of elements to the
+	* new array.
+	*/
+	FbxDynamicArray(const FbxDynamicArray& pArray) :
+		mArray(NULL),
+		mCapacity(0),
+		mSize(0),
+		mAllocator(sizeof(Type))
+	{
+		Reserve(pArray.mCapacity);
+		CopyArray(mArray, pArray.mArray, pArray.mSize);
+		mSize = pArray.mSize;
+	}
+
+	//! Destructor.
+	~FbxDynamicArray()
+	{
+		for( size_t i = 0; i < mSize; ++i )
+		{
+			mArray[i].~Type();
+		}
+		mAllocator.FreeMemory(mArray);
+	}
+
+	//! Gets the current capacity of the array.
+	size_t Capacity() const
+	{
+		return mCapacity;
+	}
+
+	//! Gets the size of the array.
+	size_t Size() const
+	{
+		return mSize;
+	}
+
+	/** Assures that sufficient memory is allocated to hold n objects in the array, and increases the capacity if necessary.
+	* \param pCount Number of objects to reserve */
+	void Reserve(const size_t pCount)
+	{
+		if( pCount > mCapacity )
+		{
+			//We don't use mAllocator.PreAllocate, because we want our array to be continuous in memory.
+			Type* lNewArray = (Type*)mAllocator.AllocateRecords(pCount);
+			MoveArray(lNewArray, mArray, mSize);
+			mAllocator.FreeMemory(mArray);
+			mArray = lNewArray;
+			mCapacity = pCount;
+		}
+	}
+
+	/** Appends n objects at the end of the array.
+	* \param pItem object to append
+	* \param pNCopies number of copies to append */
+	void PushBack(const Type& pItem, const size_t pNCopies = 1)
+	{
+		if( mSize + pNCopies > mCapacity )
+		{
+			size_t lNewSize = mCapacity + mCapacity / 2;	//grow by 50%
+			if( mSize + pNCopies > lNewSize )
+			{
+				lNewSize = mSize + pNCopies;
+			}
+			Reserve(lNewSize);
+		}
+		FBX_ASSERT(mSize + pNCopies <= mCapacity);
+		Fill(mArray + mSize, pItem, pNCopies);
+		mSize += pNCopies;
+	}
+
+	/** Inserts n objects at the specified position.
+	* \param pIndex position index
+	* \param pItem object to insert
+	* \param pNCopies number of copies to append */
+	void Insert(const size_t pIndex, const Type& pItem, const size_t pNCopies=1)
+	{
+		FBX_ASSERT(pIndex >= 0);
+		FBX_ASSERT(pIndex <= mSize);
+		Type lValue = pItem; // in case pItem is in array
+		if( pNCopies == 0 )
+		{
+		}
+		else if( pIndex >= mSize )
+		{
+			PushBack(pItem, pNCopies);
+		}
+		else if( mSize + pNCopies > mCapacity )
+		{
+			size_t lNewSize = mCapacity + mCapacity / 2;	//not enough room, grow by 50%
+			if( mSize + pNCopies > lNewSize )
+			{
+				lNewSize = mSize + pNCopies;
+			}
+
+			Type* lNewArray = (Type*)mAllocator.AllocateRecords(lNewSize);
+			MoveArray(lNewArray, mArray, pIndex); // copy prefix
+			Fill(lNewArray + pIndex, pItem, pNCopies); // copy values
+			MoveArray(lNewArray + pIndex + pNCopies, mArray + pIndex, mSize - pIndex); // copy suffix
+			mAllocator.FreeMemory(mArray);
+			mArray = lNewArray;
+			mSize += pNCopies;
+			mCapacity = lNewSize;
+		}
+		else
+		{
+			// copy suffix backwards
+			MoveArrayBackwards(mArray + pIndex + pNCopies, mArray + pIndex, mSize - pIndex);
+			Fill(mArray + pIndex, pItem, pNCopies); // copy values
+			mSize += pNCopies;
+		}
+	}
+
+	/** Removes n objects at the end.
+	* \param pNElements number of objects to remove */
+	void PopBack(size_t pNElements=1)
+	{
+		FBX_ASSERT(pNElements <= mSize);
+		for( size_t i = mSize - pNElements; i < mSize; ++i )
+		{
+			mArray[i].~Type();
+		}
+		mSize -= pNElements;
+	}
+
+	/** Removes n objects at the specified position.
+	* \param pIndex position index
+	* \param pNElements number of objects to remove */
+	void Remove(const size_t pIndex, size_t pNElements=1)
+	{
+		FBX_ASSERT(pIndex >= 0);
+		FBX_ASSERT(pIndex <= mSize);
+		FBX_ASSERT(pIndex + pNElements <= mSize);
+		if( pIndex + pNElements >= mSize )
+		{
+			PopBack(pNElements);
+		}
+		else
+		{            
+			for( size_t i = pIndex; i < pIndex + pNElements; ++i )
+			{
+				mArray[i].~Type();
+			}
+			MoveOverlappingArray(&mArray[pIndex], &mArray[pIndex + pNElements], mSize - pIndex - pNElements);
+			mSize -= pNElements;
+		}
+	}
+
+	/** Gets nth object in the array.
+	* \param pIndex position index */
+	Type& operator[](const size_t pIndex)
+	{
+		return mArray[pIndex];
+	}
+
+	/** Gets nth object in the array.
+	* \param pIndex position index */
+	const Type& operator[](const size_t pIndex) const
+	{
+		return mArray[pIndex];
+	}
+
+	/** Retrieve the first item in the array.
+	* \return The first item in the array. */
+	Type& First()
+	{
+		return operator[](0);
+	}
+
+	/** Retrieve the first item in the array.
+	* \return The first item in the array. */
+	const Type& First() const
+	{
+		return operator[](0);
+	}
+
+	/** Retrieve the last item in the array.
+	* \return The last item in the array. */
+	Type& Last()
+	{
+		return operator[](mSize-1);
+	}
+
+	/** Retrieve the last item in the array.
+	* \return The last item in the array. */
+	const Type& Last() const
+	{
+		return operator[](mSize-1);
+	}
+
+	/** Find first matching element, from first to last.
+	* \param pItem The item to try to find in the array.
+	* \param pStartIndex The index to start searching from.
+	* \return Index of the first matching item, otherwise returns -1 (equivalent of SIZE_MAX for size_t). */
+	size_t Find(const Type& pItem, const size_t pStartIndex=0) const
+	{
+		for( size_t i = pStartIndex; i < mSize; ++i )
+		{
+			if( operator[](i) == pItem ) return i;
+		}
+		return -1;
+	}
+
+	/** Assignment operator.
+	* \remarks The copy constructor of \c Type will be invoked in order to copy the value of elements to the new array. */
+	FbxDynamicArray& operator=(const FbxDynamicArray& pArray)
+	{
+		Reserve(pArray.mCapacity);
+		CopyArray(mArray, pArray.mArray, pArray.mSize);
+		mSize = pArray.mSize;
+		return *this;
+	}
+
+/*****************************************************************************************************************************
+** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
+*****************************************************************************************************************************/
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+private:
+	static void CopyArray(Type* pDest, const Type* pSrc, size_t pCount)
+	{
+		for( int i = 0; i < int(pCount); i++ )
+		{
+			new(&(pDest[i])) Type(pSrc[i]);	//in-place new won't allocate memory, so it is safe
+		}
+	}
+
+	static void MoveArray(Type* pDest, const Type* pSrc, size_t pCount)
+	{
+		for( int i = 0; i < int(pCount); i++ )
+		{
+			new(&(pDest[i])) Type(pSrc[i]);	//in-place new won't allocate memory, so it is safe
+		}
+
+		for( int i = 0; i < int(pCount); i++ )
+		{
+			pSrc[i].~Type();
+		}
+	}
+
+	static void MoveOverlappingArray(Type* pDest, const Type* pSrc, size_t pCount)
+	{
+		for( int i = 0; i < int(pCount); i++ )
+		{
+			new(&(pDest[i])) Type(pSrc[i]);	//in-place new won't allocate memory, so it is safe
+			pSrc[i].~Type();
+		}
+	}
+
+	static void MoveArrayBackwards(Type* pDest, const Type* pSrc, size_t pCount)
+	{
+		for( int i = 0; i < int(pCount); ++i )
+		{
+			new(&(pDest[pCount-1-i])) Type(pSrc[pCount-1-i]);	//in-place new won't allocate memory, so it is safe
+			pSrc[pCount-1-i].~Type();
+		}
+	}
+
+	static void Fill(Type* pDest, const Type& pItem, size_t pCount)
+	{
+		for( int i = 0; i < int(pCount); i++ )
+		{
+			new(&(pDest[i])) Type(pItem);	//in-place new won't allocate memory, so it is safe
+		}
+	}
+
+    Type*		mArray;
+    size_t		mCapacity;
+    size_t		mSize;
+    Allocator	mAllocator;
+#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
+};
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* _FBXSDK_CORE_BASE_DYNAMICARRAY_H_ */

+ 257 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/base/fbxfile.h

@@ -0,0 +1,257 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxfile.h
+#ifndef _FBXSDK_CORE_BASE_FILE_H_
+#define _FBXSDK_CORE_BASE_FILE_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#include <fbxsdk/core/base/fbxstring.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+class FbxStream;
+
+/**
+    Class for interfacing with files, providing a similar interface for files independant of the OS or filesystem.
+*/
+class FBXSDK_DLL FbxFile
+{
+public:
+	enum EMode {eNone, eReadOnly, eReadWrite, eCreateWriteOnly, eCreateReadWrite, eCreateAppend};
+	enum ESeekPos {eBegin, eCurrent, eEnd};
+
+    FbxFile();
+    virtual ~FbxFile();
+
+	/** Opens a file on disk using the specified read/write mode.
+	  * \param pFileName_UTF8 Filename in UTF8 (compatible with ASCII)
+      * \param pMode Mode in which to open the file, e.g. eReadOnly, eCreateReadWrite, etc.
+      * \param pBinary Whether the file is to be opened in binary or text mode.
+	  * \return True if opening is successful.
+	  */
+    virtual bool        Open(const char* pFileName_UTF8, const EMode pMode=eCreateReadWrite, const bool pBinary=true);
+
+	/** Opens a file from a data stream using the specified read/write mode.
+	  * \param pStream Stream instance with which the file will be read/written
+      * \param pStreamData User-defined data to pass as a parameter to the stream's Open() method.
+      * \param pMode Deprecated/Unused.
+	  * \return True if opening is successful.
+	  */
+    virtual bool        Open(FbxStream* pStream, void* pStreamData, const char* pMode);
+
+	/** Closes a file, freeing its handle.
+	  * \return True if closing is successful.
+	  */
+    virtual bool        Close();
+
+    /** Seek to a specific position in the file, starting from either beginning, current position or end
+	  * \param pOffset Offset to seek to (advance the file position cursor) starting from pSeekPos
+      * \param pSeekPos Starting position from which to seek to.  Beginning, current position or end.
+	  */
+    virtual void		Seek(const FbxInt64 pOffset, const ESeekPos pSeekPos=eBegin);
+
+	/** Returns the position at which the file cursor currently is.  For example, will be ==0 for beginning and ==FileSize for end.
+	  * \return The position at which the file cursor currently is.
+	  */
+    virtual FbxInt64	Tell() const;
+
+	/** Read a part of the file into a buffer
+      * \param pDstBuf Pre-allocated buffer in which to read data
+      * \param pSize Size of the data chunk to be read in bytes
+	  * \return Number of bytes read.
+	  */
+    virtual	size_t		Read(void* pDstBuf, const size_t pSize);
+
+	/** Read a part of the file as a string into a buffer
+      * \param pDstBuf Pre-allocated buffer in which to read the string
+      * \param pDstSize Size of the data chunk to be read in characters
+      * \param pStopAtFirstWhiteSpace If true, will stop reading at first white space, otherwise it will stop at the first line feed (\n)
+	  * \return Pointer on the data read.  Equivalent to parameter pDstBuf
+	  */
+	virtual char*		ReadString(char* pDstBuf, const size_t pDstSize, bool pStopAtFirstWhiteSpace=false);
+
+	/** Write a buffer to an opened file
+      * \param pSrcBuf Pre-allocated buffer from which to write data
+      * \param pSize Size of the data chunk to be written in bytes
+	  * \return Number of bytes written.
+	  */
+    virtual size_t		Write(const void* pSrcBuf, const size_t pSize);
+
+	/** Write a formatted string to an opened file
+      * \param pFormat Pre-allocated format buffer from which to write data
+      * \param ... Variable number of arguments describing the values in the previous parameter. 
+	  * \return True if data was successfully written
+	  */
+    virtual bool		WriteFormat(const char* pFormat, ...);
+
+	/** Modify the size of a file. Null characters ('\0') are appended if the file is extended. 
+      * If the file is truncated, all data from the end of the shortened file to the original length of the file is lost.
+      * Please note that this function considers the current file cursor as the beginning of the file.
+      * It is therefore required to use Seek(0) prior to calling it if we want the size specified by the
+      * pSize parameter to be absolute.
+      * \param pSize New desired file size
+	  * \return True if file was successfully truncated
+	  */
+    virtual bool		Truncate(const FbxInt64 pSize);
+
+	/** Checks whether the current file cursor position is at the end of file.
+	  * \return True if the cursor is at the end of file, false otherwise.
+	  */
+    virtual bool		EndOfFile() const;
+
+	/** Gets the size of the currently opened file.
+	  * \return File size
+	  */
+	virtual FbxInt64	GetSize();
+
+    /** Unused function in this default implementation.  Must be implemented by memory files.       
+      * \param pMemPtr Unused
+	  * \param pSize Unused
+	  */
+	virtual void		GetMemoryFileInfo(void** pMemPtr, size_t pSize);
+
+	/** Checks whether the file is currently opened.
+	  * \return True if file is opened, false otherwise
+	  */
+    bool                IsOpen() const;
+
+	/** Checks whether the file is currently opened with a user-provided streaming interface instead of just the file name
+	  * \return True if file has been opened with a stream interface, false otherwise
+	  */
+    bool                IsStream() const;
+
+	/** Returns the full file path name, as provided when opening it.
+	  * \return File full path
+	  */
+    const char*			GetFilePathName() const;
+
+	/** Returns the mode with which the file was opened, when calling the Open() method.
+	  * \return Mode with which the file was opened
+	  */
+    EMode				GetFileMode() const;
+
+	/** Returns last encountered error when performing any operation on the file.
+	  * \return Last error code
+	  */
+    int                 GetLastError();
+
+	/** Resets the current error code and the end of file indicator of the opened file
+	  */
+    void                ClearError();
+
+protected:
+	FILE*				mFilePtr;
+    FbxStream*          mStreamPtr;
+	bool                mIsOpen;
+	bool                mIsStream;
+	EMode				mMode;
+	FbxString			mFileName;
+};
+
+class FBXSDK_DLL FbxFileUtils
+{
+public:
+	/** Delete a file from disk.
+	  * \param pFileName_UTF8 The file to be deleted.
+	  * \return True if delete is successful.
+	  */
+    static bool Delete(const char* pFileName_UTF8);
+
+	/** Rename a file on disk.
+	  * \param pFileName_UTF8 The file to be renamed.
+	  * \param pNewName_UTF8 The new file name upon rename.
+	  * \return True if rename is successful.
+	  */
+    static bool Rename(const char* pFileName_UTF8, const char* pNewName_UTF8);
+
+	/** Copy one file's content to another file (if the destination file not exist, it will be created).
+	  * \param pDestination_UTF8 The destination file path
+	  * \param pSource_UTF8 The source file path
+	  * \return Return true if copy is successfully.
+	  */
+	static bool Copy(const char* pDestination_UTF8, const char* pSource_UTF8);
+
+	//! Get given file's size.
+	static FbxInt64 Size(const char* pFilePath_UTF8);
+
+	/** Find if the specified file exist.
+	  * \param pFilePath_UTF8 The file path to test against.
+	  * \return Returns true if the file exist.
+	  */
+	static bool Exist(const char* pFilePath_UTF8);
+
+	/** Find if the specified file is in read-only mode.
+	  * \param pFilePath_UTF8 The file path to test against.
+	  * \return Returns true if the file is in read-only mode.
+	  */
+	static bool IsReadOnly(const char* pFilePath_UTF8);
+
+	// We return a KLong that in fact is a cast of a time_t.
+	//! Get given file's last date.
+	static FbxLong GetLastDate(const char* pPath_UTF8);
+
+	//! Set the given file's last date as the given date.
+	static bool SetLastDate(const char* pPath_UTF8, FbxLong pTime);
+
+	/** Get some content of a file.
+	  * \param pStr The content get from file.
+	  * \param pSize The size of content.
+	  * \param pStream The opened stream of file.
+	  */
+	static char* FGets(char* pStr, int pSize, FILE* pStream);
+};
+
+template<class T> inline const T FbxSwab(const T x)
+{
+	switch( sizeof(x) )
+	{
+		case 2:
+		{
+			FbxUInt8 t[2];
+			t[0] = ((FbxUInt8*)&x)[1];
+			t[1] = ((FbxUInt8*)&x)[0];
+			return *(T*)&t;
+		}
+
+		case 4:
+		{
+			FbxUInt8 t[4];
+			t[0] = ((FbxUInt8*)&x)[3];
+			t[1] = ((FbxUInt8*)&x)[2];
+			t[2] = ((FbxUInt8*)&x)[1];
+			t[3] = ((FbxUInt8*)&x)[0];
+			return *(T*)&t;
+		}
+
+		case 8:
+		{
+			FbxUInt8 t[8];
+			t[0] = ((FbxUInt8*)&x)[7];
+			t[1] = ((FbxUInt8*)&x)[6];
+			t[2] = ((FbxUInt8*)&x)[5];
+			t[3] = ((FbxUInt8*)&x)[4];
+			t[4] = ((FbxUInt8*)&x)[3];
+			t[5] = ((FbxUInt8*)&x)[2];
+			t[6] = ((FbxUInt8*)&x)[1];
+			t[7] = ((FbxUInt8*)&x)[0];
+			return *(T*)&t;
+		}
+
+		default:
+			return x;
+	}
+}
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* _FBXSDK_CORE_BASE_FILE_H_ */

+ 80 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/base/fbxfolder.h

@@ -0,0 +1,80 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxfolder.h
+#ifndef _FBXSDK_CORE_BASE_FOLDER_H_
+#define _FBXSDK_CORE_BASE_FOLDER_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#ifndef FBXSDK_ENV_WINSTORE
+
+#include <fbxsdk/core/base/fbxstring.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+/** Class for iterating into file system folders and the items contained. */
+class FBXSDK_DLL FbxFolder
+{
+public:
+	//! The different entry type that can be found in folders.
+	enum EEntryType
+	{
+		eRegularEntry,	//!< Regular entry, such as file.
+		eFolderEntry	//!< Folder entry that potentially contain more files.
+	};
+
+	/** Open the specified folder for browsing its content.
+	* \param pFolderPath_UTF8 The folder path to open.
+	* \return True if the folder path was successfully open, false otherwise. */
+	bool Open(const char* pFolderPath_UTF8);
+
+	/** Get the next item in the folder.
+	* \return True if another item was found after the current one. */
+	bool Next();
+
+	/** Get the type of the current entry in the folder.
+	* \return The entry type. */
+	EEntryType GetEntryType() const;
+
+	/** Retrieve the name of the current entry in the folder.
+	* \return The name of the current entry. */
+	FbxString GetEntryName() const;
+
+	/** Retrieve the extension name of the current entry.
+	* \return The extension name of the current entry. */
+	char* GetEntryExtension() const;
+
+	/** Close the folder when done browsing its content. */
+	void Close();
+
+	/** Find out if the folder was successfully opened the last time Open was called.
+	* \return True if the folder is currently open. */
+	bool IsOpen() const;
+
+/*****************************************************************************************************************************
+** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
+*****************************************************************************************************************************/
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+	FbxFolder();
+	~FbxFolder();
+
+private:
+	struct FolderImpl;
+	FolderImpl* mImpl;
+#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
+};
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* !FBXSDK_ENV_WINSTORE */
+
+#endif /* _FBXSDK_CORE_BASE_FOLDER_H_ */

+ 411 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/base/fbxhashmap.h

@@ -0,0 +1,411 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxhashmap.h
+#ifndef _FBXSDK_CORE_BASE_HASHMAP_H_
+#define _FBXSDK_CORE_BASE_HASHMAP_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#include <fbxsdk/core/base/fbxarray.h>
+#include <fbxsdk/core/base/fbxmap.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+template<class T> class FbxNoOpDestruct { public: static inline void DoIt(T&) {} };
+template<class T> class FbxPtrDestruct  { public: static inline void DoIt(T& v) { FbxDelete(v); v = NULL; } };
+
+//True if equal, false otherwise
+template<class T> class FbxDefaultComparator{ public: static inline bool CompareIt( const T& t1, const T& t2 ) { return t1 == t2; } };
+
+/** \brief This object represents a standard hash map.  You must provide the typename of KEY and VALUE as well
+    as the typename of the class that contains the hash function to use to hash values.   The hash class must
+    overload operator() and be built like this.
+    \code
+    class SimpleHash
+    {
+    public:
+        inline unsigned int operator() ( const int pKey ) const
+        {
+            return pKey;
+        }
+    };
+    \endcode
+  * \nosubgrouping
+  */
+template< typename KEY, typename VALUE, typename HASH, class Destruct = FbxNoOpDestruct<VALUE>, class Comparator = FbxDefaultComparator<KEY> >
+class FbxHashMap
+{
+public:
+	typedef KEY KeyType;
+	typedef VALUE ValueType;
+	typedef HASH HashFunctorType;
+
+private:
+
+	class ListItem
+	{
+	public:
+		ListItem* mNext;
+		ValueType mValue;
+		KeyType mKey;
+
+		ListItem()
+			:
+		mNext(NULL)
+		{
+		}
+
+        ~ListItem()
+        {
+            Destruct::DoIt(mValue);        
+        }
+	};
+
+public:
+    /**
+    Iterate through every element in a hash map.
+    */
+	class Iterator
+	{
+	public:
+
+		typedef ListItem ListItemType;
+		typedef FbxPair< KeyType, ValueType > KeyValuePair;
+
+        /**
+        Copy constructor
+        */
+		Iterator( const Iterator& pOther )
+			:
+			mMap( pOther.mMap ),
+			mBucketIndex( pOther.mBucketIndex ),
+			mCurrentItem( pOther.mCurrentItem )
+		{
+
+		}
+
+        /**
+        Destructor
+        */
+		~Iterator(){};
+
+        /**
+        Used to dereference an iterator and give it a behavior more similar to a pointer.
+        \return The KeyValuePair currently referenced by the iterator
+        */
+		KeyValuePair operator*() const
+		{
+			KeyValuePair lItem;
+
+			if( mCurrentItem )
+			{
+				lItem.mFirst = mCurrentItem->mKey;
+				lItem.mSecond = mCurrentItem->mValue;
+				return lItem;
+			}
+
+			FBX_ASSERT_NOW("Accessing out of bounds iterator");
+
+			return lItem;
+		}
+
+        /**
+        Advances the iterator to the next keyvaluepair in the hashmap.  It does not wrap around so 
+        advancing after reaching the last element will not point back to the first one.
+        */
+		void Next()
+		{
+			if( !mCurrentItem )
+				return;
+
+			if( mCurrentItem->mNext )
+			{
+				mCurrentItem = mCurrentItem->mNext;
+				return;
+			}
+			else
+			{
+				mBucketIndex++;
+				for( ; mBucketIndex < mMap->mBuckets.GetCount(); ++mBucketIndex )
+				{
+					if( mMap->mBuckets[ mBucketIndex ] )
+					{
+						mCurrentItem = mMap->mBuckets[ mBucketIndex ];
+						return;
+					}
+				}
+				
+				if( mBucketIndex >= mMap->mBuckets.GetCount() )
+				{
+					*this = mMap->End();
+					return;
+				}
+			}
+		}
+
+        /**
+        Check equivalence between two iterators.  There are 3 conditions for equivalence between 2 iterators:
+        1) Item being referenced by the iterator must be equivalent
+        2) They must point at the same index
+        3) They must point on the same map
+        \return true if both iterators are equal, false otherwise
+        */
+		bool operator==( const Iterator& pOther ) const
+		{
+			return	mCurrentItem == pOther.mCurrentItem && 
+					mBucketIndex == pOther.mBucketIndex &&
+					mMap == pOther.mMap;
+		}
+
+        /**
+        Check inequivalence between 2 iterators.  Please see operator== for more information.
+        \return true if both iterators are NOT equal, false if they are
+        */
+		bool operator!=( const Iterator& pOther ) const
+		{
+			return !(*this == pOther);
+		}
+
+		/**
+        Assign the current iterator to the one on the right hand side of the operator.  After assignment they will
+        reference the same object, at the same index, in the same map.
+        \return The new iterator
+        */
+		Iterator& operator=( const Iterator& pOther )
+		{
+			this->mBucketIndex = pOther.mBucketIndex;
+			this->mMap = pOther.mMap;
+			this->mCurrentItem = pOther.mCurrentItem;
+			return *this;
+		}
+
+    private:
+		const FbxHashMap* mMap;		
+
+		int mBucketIndex;
+		ListItemType* mCurrentItem;
+		
+		Iterator(const FbxHashMap* pMap, int pBucketIndex, ListItemType* pCurrentItem)
+			:
+			mMap( pMap ),
+			mBucketIndex(pBucketIndex),
+			mCurrentItem(pCurrentItem)
+		{
+
+		}
+
+		friend class FbxHashMap;
+	};
+	
+	/**
+    Construct a FbxHashMap with an user-defined maximum number of elements.
+    \param pBucketSize Initial maximum number of elements.
+    */
+	FbxHashMap( int pBucketSize )
+	{
+		mBuckets.Resize( pBucketSize );
+	}
+
+	/**
+    Construct a FbxHashMap with the default maximum number of elements (30)
+    */
+    FbxHashMap()
+    {
+        mBuckets.Resize(30);
+    }
+
+	/**
+    Clear all elements in the hash map before destroying itself
+    */
+	~FbxHashMap()
+	{
+		Clear();
+		mBuckets.Clear();
+	}
+
+	/**
+    Calls operator delete on all elements of the hashmap, de-allocating all memory and destroying them
+    */
+	void Clear()
+	{
+		for( int i = 0; i < mBuckets.GetCount(); ++i)
+		{
+			if( mBuckets[i] )
+			{
+				ListItem* lNext = mBuckets[i]->mNext;
+				while( lNext )
+				{
+					ListItem* lNextNext = lNext->mNext;
+					FbxDelete(lNext);
+					lNext = lNextNext;
+				}
+
+				FbxDelete(mBuckets[i]);
+				mBuckets[i] = NULL;
+			}
+		}
+	}
+
+	/**
+    Find an element in the hashmap.  If no element exist with the specified key, returns an iterator pointing on the
+    end of the map (not an actual KeyValuePair).
+    \param pKey The value of the key corresponding to the element
+    \return An Iterator referencing that element
+    */
+	const Iterator Find( const KeyType& pKey ) const
+	{
+		unsigned int lIndex = mHashFunctor(pKey);
+		lIndex = lIndex % mBuckets.GetCount();
+		ListItem* lItem = mBuckets[lIndex];
+		while( lItem )
+		{
+            if( Comparator::CompareIt( lItem->mKey, pKey ) )
+			{
+				Iterator lIt( this, lIndex, lItem );
+				return lIt;
+			}
+			lItem = lItem->mNext;
+		}
+		
+		return End();
+	}
+	
+	/**
+    Remove an element in the hashmap.
+    \param pKey The key value of the element to remove
+    \return The value of the element that was just deleted.  If the element does not exist, a value created with its default constructor will be returned
+    */
+	VALUE Remove( const KEY& pKey )
+    {
+		unsigned int lIndex = mHashFunctor(pKey);
+		lIndex = lIndex % mBuckets.GetCount();
+		ListItem* lItem = mBuckets.GetAt(lIndex);
+        ListItem* lLastItem = NULL;
+		
+        while( lItem )
+		{
+			if( lItem->mKey == pKey )
+			{
+                if( lLastItem )
+                    lLastItem->mNext = lItem->mNext;
+
+                if( mBuckets.GetAt(lIndex) == lItem ) 
+                    mBuckets.SetAt(lIndex, lItem->mNext );
+
+                VALUE lValue = lItem->mValue;
+                FbxDelete(lItem);
+                
+                return lValue;
+			}
+
+            lLastItem = lItem;
+			lItem = lItem->mNext;
+		}
+		
+        return VALUE();
+    }
+
+    /** Add or retrieve a KeyValuePair from the Hashmap.  If there is already an entry in the map for an element
+    with key value specified in parameter, the value will be returned.  Otherwise, a new entry will be created
+    with this key value and the default value for ValueType will be returned.  It can be modified using the 
+    assignment operator
+    \param pKey The key for which to retrieve/add a value.
+    \return Value of the element referenced by the key specified in parameter.
+    */
+	ValueType& operator[]( const KeyType& pKey )
+	{
+        unsigned int lIndex = 0;
+		Iterator lIt = InternalFind( pKey, lIndex);
+		if( lIt != End() )
+		{
+			return lIt.mCurrentItem->mValue;
+		}
+
+		lIndex = lIndex % mBuckets.GetCount();
+		ListItem* lItem = FbxNew< ListItem >();
+		lItem->mNext = NULL;
+		lItem->mKey = pKey;
+
+		if( !mBuckets.GetAt(lIndex) )
+		{
+			mBuckets.SetAt(lIndex, lItem);
+		}
+		else
+		{
+			lItem->mNext = mBuckets.GetAt(lIndex);
+			mBuckets.SetAt(lIndex, lItem);
+		}
+
+		return lItem->mValue;
+	}
+
+    /** Returns an iterator pointing on the first non-null element in the map
+    \return An iterator pointing on the first non-null element in the map.
+    */
+	Iterator Start() const
+	{
+		for( int i = 0; i < mBuckets.GetCount(); ++i )
+		{
+			if( mBuckets[i] )
+			{
+				Iterator lIt( this, i, mBuckets[i] );
+				return lIt;
+			}
+		}
+
+		return End();
+	}
+
+    /** Returns an iterator pointing on the last element in the map.  This is not an actual KeyValuePair but 
+    * but an iterator pointing on a null element. 
+    \return Iterator pointing on a null value at the end of the map
+    */
+	Iterator End() const
+	{
+		Iterator lIt( this, 0, NULL );
+		return lIt;
+	}
+
+private:
+
+    // Avoid calculating the hashvalue twice
+	const Iterator InternalFind( const KeyType& pKey, unsigned int& pOutCalculatedIndex ) const
+	{
+		pOutCalculatedIndex = mHashFunctor(pKey);
+		unsigned int lIndex = pOutCalculatedIndex % mBuckets.GetCount();
+		ListItem* lItem = mBuckets[lIndex];
+		while( lItem )
+		{
+            if( Comparator::CompareIt( lItem->mKey, pKey ) )
+			{
+				Iterator lIt( this, lIndex, lItem );
+				return lIt;
+			}
+			lItem = lItem->mNext;
+		}
+		
+		return End();
+	}
+
+
+	// not implemented yet!
+	FbxHashMap( const FbxHashMap& pOther ) {};
+
+	FbxArray<ListItem*> mBuckets;
+	HashFunctorType mHashFunctor;
+
+	friend class Iterator;
+};
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* _FBXSDK_CORE_BASE_HASHMAP_H_ */

+ 262 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/base/fbxintrusivelist.h

@@ -0,0 +1,262 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxintrusivelist.h
+#ifndef _FBXSDK_CORE_BASE_INTRUSIVE_LIST_H_
+#define _FBXSDK_CORE_BASE_INTRUSIVE_LIST_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+/*****************************************************************************************************************************
+** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
+*****************************************************************************************************************************/
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+#define FBXSDK_INTRUSIVE_LIST_NODE(Class, NodeCount)\
+    public: inline FbxListNode<Class>& GetListNode(int index = 0){ return this->mNode[index]; }\
+    private: FbxListNode<Class> mNode[NodeCount];
+
+template <typename T> class FbxListNode
+{
+    typedef FbxListNode<T> NodeT; 
+
+public:
+	explicit FbxListNode(T* pData = 0):mNext(0),mPrev(0),mData(pData){}
+	~FbxListNode(){ Disconnect(); }
+
+	void Disconnect()
+	{
+		if ( mPrev != 0 )
+			mPrev->mNext = mNext;
+
+		if ( mNext != 0 )
+			mNext->mPrev = mPrev;
+
+		mPrev = mNext = 0;
+	}
+
+	NodeT*	mNext;
+	NodeT*	mPrev;
+	T*		mData;
+};
+
+//-----------------------------------------------------------------
+// template arg T: Type listed
+//          arg NodeIndex: If an object listed has  multiple list node, which
+//                         index corresponds to the right node
+template <typename T, int NodeIndex=0> class FbxIntrusiveList
+{
+public:
+    typedef T         allocator_type;
+    typedef T         value_type;
+    typedef T&        reference;
+    typedef const T&  const_reference;
+    typedef T*        pointer;
+    typedef const T*  const_pointer;
+
+    typedef FbxListNode<T> NodeT;
+
+    // Construction / Destruction
+    FbxIntrusiveList():mHead(0)
+    {
+        mHead.mNext = mHead.mPrev = &mHead;
+    }
+    ~FbxIntrusiveList()
+    {
+        while(!Empty())
+            Begin().Get()->Disconnect();  // LINUXNote:  should be Erase(Begin()); but there's an issue with gcc 4.2
+    };
+
+    // true if the list's size is 0.
+    bool Empty() const
+    {
+        return ((mHead.mNext==&mHead)&&(mHead.mPrev==&mHead));
+    }
+
+    // Back Insertion Sequence  Inserts a new element at the end.  
+    void PushBack(T& pElement)
+    {
+        NodeT* pNode = &pElement.GetListNode(NodeIndex);
+        pNode->mData = &pElement;
+
+        if (Empty())
+        {
+            pNode->mNext = &mHead;
+            pNode->mPrev = &mHead;
+            mHead.mNext = pNode;
+            mHead.mPrev = pNode;
+        }
+        else
+        {
+            pNode->mNext = &mHead;
+            pNode->mPrev = mHead.mPrev;
+
+            pNode->mPrev->mNext = pNode;
+            mHead.mPrev = pNode;
+        }
+    }
+
+    void PushFront(T& pElement)
+    {
+        NodeT* pNode = &pElement.GetListNode(NodeIndex);
+        pNode->mData = &pElement;
+
+        if (Empty())
+        {
+            pNode->mNext = &mHead;
+            pNode->mPrev = &mHead;
+            mHead.mNext = pNode;
+            mHead.mPrev = pNode;
+        }
+        else
+        {
+            pNode->mNext = mHead.mNext;
+            pNode->mPrev = &mHead;
+
+            pNode->mNext->mPrev = pNode;
+            mHead.mNext = pNode;
+        }
+    }
+
+    void PopFront()
+    {
+        iterator begin = Begin();
+        Erase(begin);
+    }
+
+    void PopBack()
+    {
+        Erase(--(End()));
+    }
+
+public:
+    class IntrusiveListIterator
+    {
+    public:
+        explicit IntrusiveListIterator(NodeT* ptr=0):mPtr(ptr){}
+
+        // pre-increment
+        IntrusiveListIterator& operator++()
+        {
+            mPtr = mPtr->mNext;return (*this);
+        }
+        // post-increment
+        const IntrusiveListIterator operator++(int)
+        {
+            IntrusiveListIterator temp = *this;
+            ++*this;
+            return (temp);
+        }
+        // pre-decrement
+        IntrusiveListIterator& operator--()
+        {
+            mPtr = mPtr->mPrev;return *this;
+        }
+        // post-decrement
+        const IntrusiveListIterator operator--(int)
+        {
+            IntrusiveListIterator temp = *this;
+            --*this;
+            return (temp);
+        }
+        IntrusiveListIterator& operator=(const IntrusiveListIterator &other){mPtr = other.mPtr; return *this;}
+
+        reference operator*() const { return *(mPtr->mData); }
+        pointer operator->() const { return (&**this); }
+        bool operator==(const IntrusiveListIterator& other)const{ return mPtr==other.mPtr; } 
+        bool operator!=(const IntrusiveListIterator& other)const{ return !(*this == other); } 
+
+        inline NodeT* Get()const { return mPtr; }
+
+    private:
+        NodeT* mPtr;
+    };
+
+    class  IntrusiveListConstIterator
+    {
+    public:
+        explicit IntrusiveListConstIterator(const NodeT* ptr=0):mPtr(ptr){}
+
+       // pre-increment
+        IntrusiveListConstIterator& operator++()
+        {
+            mPtr = mPtr->mNext;return (*this);
+        }
+        // post-increment
+        const IntrusiveListConstIterator operator++(int)
+        {
+            IntrusiveListConstIterator temp = *this;
+            ++*this;
+            return (temp);
+        }
+        // pre-decrement
+        IntrusiveListConstIterator& operator--()
+        {
+            mPtr = mPtr->mPrev;return *this;
+        }
+        // post-decrement
+        const IntrusiveListConstIterator operator--(int)
+        {
+            IntrusiveListConstIterator temp = *this;
+            --*this;
+            return (temp);
+        }
+        IntrusiveListConstIterator& operator=(const IntrusiveListConstIterator &other){mPtr = other.mPtr; return *this;}
+
+        const_reference operator*() const { return *(mPtr->mData); }
+        const_pointer operator->() const { return (&**this); }
+        bool operator==(const IntrusiveListConstIterator& other)const{ return mPtr==other.mPtr; } 
+        bool operator!=(const IntrusiveListConstIterator& other)const{ return !(*this == other); } 
+
+        inline const NodeT* Get()const { return mPtr; }
+
+    private:
+        mutable const NodeT* mPtr;
+    };
+
+    // --- Iterator definitions ---
+    typedef IntrusiveListIterator iterator;
+    typedef IntrusiveListConstIterator const_iterator;
+
+    // iterator support
+    inline iterator Begin() { return iterator(mHead.mNext); }
+    inline const_iterator Begin() const { return const_iterator(mHead.mNext); }
+    inline iterator End() { return iterator(&mHead); }
+    inline const_iterator End() const { return const_iterator(&mHead); }
+
+    // Because there is no real use, for the reverse iterators, 
+    // they have not been implemented. 
+
+    reference Front(){return (*Begin());}
+    const_reference Front() const { return (*Begin()); }
+    reference Back(){ return (*(--End())); }
+    const_reference Back() const{ return (*(--End())); }
+
+    iterator& Erase(iterator& it)
+    {
+        it.Get()->Disconnect();
+        return (++it);
+    }
+private:
+    NodeT mHead;
+
+    // Not copyable
+    FbxIntrusiveList(const FbxIntrusiveList&);
+    FbxIntrusiveList& operator=(const FbxIntrusiveList& Right){return (*this);}
+};
+
+#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* _FBXSDK_CORE_BASE_INTRUSIVE_LIST_H_ */

+ 408 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/base/fbxmap.h

@@ -0,0 +1,408 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxmap.h
+#ifndef _FBXSDK_CORE_BASE_MAP_H_
+#define _FBXSDK_CORE_BASE_MAP_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#include <fbxsdk/core/base/fbxstring.h>
+#include <fbxsdk/core/base/fbxredblacktree.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+class FbxObject;
+
+/** Default compare functor for FbxMap and FbxSet, which assumes operator < is defined.
+Here is examples of different compare class implementations:
+With Key = int
+\code
+class IntCompare
+{
+    inline int operator()(int pKeyA, int pKeyB) const
+    {
+        return pKeyA < pKeyB ? -1 : (pKeyA > pKeyB ? 1 : 0);
+    }
+};
+\endcode
+With Key = Class
+\code
+class ClassCompare
+{
+	inline int operator()(const Class& pKeyA, const Class& pKeyB) const
+	{
+		return pKeyA < pKeyB ? -1 : (pKeyA > pKeyB ? 1 : 0);
+	}
+};
+\endcode
+With Key = char*
+\code
+class StrCompare
+{
+	inline int operator()(const char* pKeyA, const char* pKeyB) const
+	{
+		return strcmp(pKeyA, pKeyB);
+	}
+};
+\endcode
+*/
+template <typename Type> struct FbxLessCompare
+{
+    inline int operator()(const Type& pLeft, const Type& pRight) const
+    {
+        return (pLeft < pRight) ? -1 : ((pRight < pLeft) ? 1 : 0);
+    }
+};
+
+/** This class implements an efficient map based on key comparison, which stores key-value pairs.
+It executes insertion, deletion and query operations in O(log(n)) time. */
+template <typename Key, typename Type, typename Compare=FbxLessCompare<Key>, typename Allocator=FbxBaseAllocator> class FbxMap
+{
+protected:
+	//! This class defines the key-value pairs used by the map.
+	class KeyValuePair : private FbxPair<const Key, Type>
+	{
+	/*****************************************************************************************************************************
+	** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
+	*****************************************************************************************************************************/
+	#ifndef DOXYGEN_SHOULD_SKIP_THIS
+	public:
+		typedef const Key	KeyType;
+		typedef const Key	ConstKeyType;
+		typedef Type		ValueType;
+		typedef const Type	ConstValueType;
+
+		KeyValuePair(const Key& pFirst, const Type& pSecond) : FbxPair<const Key, Type>(pFirst, pSecond){}
+		ConstKeyType& GetKey() const { return this->mFirst; }
+		KeyType& GetKey(){ return this->mFirst; }
+		ConstValueType& GetValue() const { return this->mSecond; }
+		ValueType& GetValue(){ return this->mSecond; }
+	#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
+	};
+
+	//! Declaration of the storage type used by the map.
+	typedef FbxRedBlackTree<KeyValuePair, Compare, Allocator> StorageType;
+
+public:
+	typedef Type									ValueType;
+	typedef Key										KeyType;
+	typedef typename StorageType::RecordType		RecordType;
+	typedef typename StorageType::IteratorType		Iterator;
+	typedef typename StorageType::ConstIteratorType	ConstIterator;
+
+	/** Preallocate memory.
+	* \param pRecordCount The number of elements. */
+	inline void Reserve(unsigned int pRecordCount)
+	{
+		mTree.Reserve(pRecordCount);
+	}
+
+	//! Retrieve the number of key-value pairs it holds.
+	inline int GetSize() const
+	{
+		return mTree.GetSize();
+	}
+
+	/** Insert a key-value pair.
+	* \param pKey The key.
+	* \param pValue The value.
+	* \return If the key is already present in the map, returns the existing pair and false; else returns the pointer to the new key-value and true. */
+	inline FbxPair<RecordType*, bool> Insert(const KeyType& pKey, const ValueType& pValue)
+	{
+		return mTree.Insert(KeyValuePair(pKey, pValue));
+	}
+
+	/** Delete a key-value pair.
+	* \param pKey The key.
+	* \return \c true if success, \c false if key is not found. */
+	inline bool Remove(const KeyType& pKey)
+	{
+		return mTree.Remove(pKey);
+	}
+
+	//! Clear the map.
+	inline void Clear()
+	{
+		mTree.Clear();
+	}
+
+	//! Query whether the map is empty.
+	inline bool Empty() const
+	{
+		return mTree.Empty();
+	}
+
+	//! Retrieve the begin iterator of the map.
+	Iterator Begin()
+	{
+		return Iterator(Minimum());
+	}
+
+	//! Retrieve the end iterator of the map.
+	Iterator End()
+	{
+		return Iterator();
+	}
+
+	//! Retrieve the begin iterator of the map.
+	ConstIterator Begin() const
+	{
+		return ConstIterator(Minimum());
+	}
+
+	//! Retrieve the end iterator of the map.
+	ConstIterator End() const
+	{
+		return ConstIterator();
+	}
+
+	/** Query a key.
+	* \param pKey The key.
+	* \return A key-value pair if success, NULL if the key is not found. */
+	inline const RecordType* Find(const KeyType& pKey) const
+	{
+		return mTree.Find(pKey);
+	}
+
+	/** Query a key.
+	* \param pKey The key.
+	* \return A key-value pair if success, NULL if it's not found. */
+	inline RecordType* Find(const KeyType& pKey)
+	{
+		return mTree.Find(pKey);
+	}
+
+	/** Find the key-value pair with the smallest key greater than a specified key.
+	* \param pKey The key.
+	* \return The found key-value pair. */
+	inline const RecordType* UpperBound(const KeyType& pKey) const
+	{
+		return mTree.UpperBound(pKey);
+	}
+
+	/** Find the key-value pair with the smallest key greater than a specified key.
+	* \param pKey The key.
+	* \return The found key-value pair. */
+	inline RecordType* UpperBound(const KeyType& pKey)
+	{
+		return mTree.UpperBound(pKey);
+	}
+
+	/** Retrieve the reference of the value in the key-value pairs in map.
+	* \param pKey The key.
+	* \return The reference of the value.
+	* \remark If the key is not found, a new key-value pair will be inserted. */
+	inline ValueType& operator[](const KeyType& pKey)
+	{
+		RecordType* lRecord = Find(pKey);
+
+		if( !lRecord )
+		{
+			lRecord = Insert(pKey, ValueType()).mFirst;
+		}
+
+		return lRecord->GetValue();
+	}
+
+	//! Retrieve the key-value pair which is the minimum key in map.
+	inline const RecordType* Minimum() const
+	{
+		return mTree.Minimum();
+	}
+
+	//! Retrieve the key-value pair which is the minimum key in map.
+	inline RecordType* Minimum()
+	{
+		return mTree.Minimum();
+	}
+
+	//! Retrieve the key-value pair which is the maximum key in map.
+	inline const RecordType* Maximum() const
+	{
+		return mTree.Maximum();
+	}
+
+	//! Retrieve the key-value pair which is the maximum key in map.
+	inline RecordType* Maximum()
+	{
+		return mTree.Maximum();
+	}
+
+/*****************************************************************************************************************************
+** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
+*****************************************************************************************************************************/
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+	inline FbxMap(){}
+	inline FbxMap(const FbxMap& pMap) : mTree(pMap.mTree){}
+	inline ~FbxMap(){ Clear(); }
+
+private:
+	StorageType mTree;
+#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
+};
+
+/** A simple map class representing a dictionary-like data structure.
+* \nosubgrouping */
+template <class Key, class Type, class Compare> class FBXSDK_DLL FbxSimpleMap
+{
+public:
+    typedef typename FbxMap<Key, Type, Compare>::RecordType* Iterator;
+
+	/** Add a key-value pair as an element.
+	* \param pKey The new key.
+	* \param pValue The new value. */
+	inline void Add(const Key& pKey, const Type& pValue)
+	{
+		mMap.Insert(pKey, pValue);
+	}
+
+	/** Find an element with a given key.
+	* \param pKey The given key.
+	* \return The iterator pointing to the found element or NULL if fails. */
+	inline Iterator Find(const Key& pKey) const
+	{
+		return (Iterator)mMap.Find(pKey);
+	}
+
+	/** Find an element with a given value.
+	* \param pValue The given value.
+	* \return The iterator pointing to the found element or NULL if fails. */
+	inline Iterator Find(const Type& pValue) const
+	{
+		Iterator lIterator = GetFirst();
+		while( lIterator )
+		{
+			if( lIterator->GetValue() == pValue )
+			{
+				return lIterator;
+			}
+			lIterator = GetNext(lIterator);
+		}
+		return 0;
+	}
+
+	/** Remove an element from the map.
+	* \param pIterator The given element. */
+	inline void Remove(Iterator pIterator)
+	{
+		if( pIterator ) mMap.Remove(pIterator->GetKey());
+	}
+
+	/** Get the first element.
+	* \return The the heading element. */
+	inline Iterator GetFirst() const
+	{
+		return (Iterator)mMap.Minimum();
+	}
+
+	/** Get the next element of a given element.
+	* \param pIterator The given element.
+	* \return The next element. */
+	inline Iterator GetNext(Iterator pIterator) const
+	{
+		return (Iterator)pIterator ? pIterator->Successor() : 0;
+	}
+
+	//! Remove all of the elements.
+	inline void Clear() 
+	{
+		mMap.Clear();
+	}
+
+	/** Reserve the space for given number elements.
+	* \param pSize The given number. */
+	inline void Reserve(int pSize)
+	{
+		mMap.Reserve(pSize);
+	}
+
+	/** Query the count of elements in the map.
+	* \return The count of elements. */
+	inline int GetCount() const
+	{
+		return mMap.GetSize();
+	}
+
+/*****************************************************************************************************************************
+** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
+*****************************************************************************************************************************/
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+	inline FbxSimpleMap(){}
+
+private:
+    FbxMap<Key, Type, Compare> mMap;
+#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
+};
+
+/** This class template declare a simple FbxObject map.
+* \nosubgrouping */
+template <class Type, class Compare> class FBXSDK_DLL FbxObjectMap : public FbxSimpleMap<Type, FbxObject*, Compare>
+{
+public:
+    //! Constructor
+    inline FbxObjectMap(){}
+
+    /** Get the object contained in an element.
+      * \param pIterator The given element.
+      * \return The object.
+      */
+    inline FbxObject* Get(typename FbxSimpleMap<Type, FbxObject*, Compare>::Iterator pIterator)
+    {
+        return pIterator ? pIterator->GetValue() : 0;
+    }
+};
+
+/** A class that maps strings to objects with a basic string comparator.
+* \nosubgrouping */
+class FBXSDK_DLL FbxObjectStringMap : public FbxObjectMap<FbxString, FbxStringCompare>
+{
+public:
+    //! Constructor
+    inline FbxObjectStringMap(){}
+};
+
+//! Call FbxFree on each element of the map, and then clear it.
+template <typename K, typename V, typename C, typename A> inline void FbxMapFree(FbxMap<K, V, C, A>& pMap)
+{
+	for( typename FbxMap<K, V, C, A>::Iterator i = pMap.Begin(); i != pMap.End(); ++i )
+	{
+		FbxFree(i->GetValue());
+	}
+	pMap.Clear();
+}
+
+//! Call FbxDelete on each element of the map, and then clear it.
+template <typename K, typename V, typename C, typename A> inline void FbxMapDelete(FbxMap<K, V, C, A>& pMap)
+{
+	for( typename FbxMap<K, V, C, A>::Iterator i = pMap.Begin(); i != pMap.End(); ++i )
+	{
+		FbxDelete(i->GetValue());
+	}
+	pMap.Clear();
+}
+
+//! Call Destroy on each element of the map, and then clear it.
+template <typename K, typename V, typename C, typename A> inline void FbxMapDestroy(FbxMap<K, V, C, A>& pMap)
+{
+	for( typename FbxMap<K, V, C, A>::Iterator i = pMap.Begin(); i != pMap.End(); ++i )
+	{
+		i->GetValue()->Destroy();
+	}
+	pMap.Clear();
+}
+
+template class FbxSimpleMap<FbxString, FbxObject*, FbxStringCompare>;
+template class FbxObjectMap<FbxString, FbxStringCompare>;
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* _FBXSDK_CORE_BASE_MAP_H_ */

+ 67 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/base/fbxmemorypool.h

@@ -0,0 +1,67 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxmemorypool.h
+#ifndef _FBXSDK_CORE_BASE_MEMORY_H_
+#define _FBXSDK_CORE_BASE_MEMORY_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#include <fbxsdk/core/sync/fbxatomic.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+/** \brief Class to create a simple fixed-size-blocks memory pool to allocate memory dynamically. */
+class FBXSDK_DLL FbxMemoryPool
+{
+public:
+	/** Memory pool constructor.
+	* \param pBlockSize		The size of one memory block.
+	* \param pBlockCount	The count of block that should be pre-allocated.
+	* \param pResizable		Whether memory pool can grow if no block are availalbe upon calling Allocate.
+	* \param pConcurrent	Whether the pool supports concurrent allocation and release operations.
+	* \remark				All memory blocks must be released before the memory pool is destroyed, otherwise a memory leak will occur. */
+	FbxMemoryPool(size_t pBlockSize, FbxInt64 pBlockCount=0, bool pResizable=true, bool pConcurrent=true);
+
+	/** Memory pool destructor. Upon destruction, all memory blocks of the pool will be de-allocated. */
+	~FbxMemoryPool();
+
+	/** Free memory of all memory blocks from this memory pool, also effectively resetting the block count to zero.
+	* \remark The block size and alignment/resize/concurrent support will remain unchanged. */
+	void Reset();
+
+	/** Allocate or lock a memory block for usage.
+	* \return An memory block pointer that can be NULL if the memory pool cannot grow in size and no blocks are available. */
+	void* Allocate();
+
+	/** Dispose or unlock a memory block.
+	* \param pMemBlock A pointer to the memory block to release. This will not free the block's memory, instead simply putting it back in the available stack. */
+	void Release(void* pMemBlock);
+
+/*****************************************************************************************************************************
+** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
+*****************************************************************************************************************************/
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+private:
+    void*		Pop();
+
+	FbxInt64	mMaxBlockCount;
+    FbxAtomic	mFreeBlockCount;
+    void*		mFreeBlocksStack;
+    size_t		mBlockSize;
+    bool		mResizable;
+    bool		mSupportConcurrentAccess;
+#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
+};
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* _FBXSDK_CORE_BASE_MEMORY_H_ */

+ 115 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/base/fbxmultimap.h

@@ -0,0 +1,115 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxmultimap.h
+#ifndef _FBXSDK_CORE_BASE_MULTIMAP_H_
+#define _FBXSDK_CORE_BASE_MULTIMAP_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+/** Class to manipulate a map that can contain multiple times the same key.
+* \nosubgrouping */
+class FBXSDK_DLL FbxMultiMap
+{
+public:
+	struct Pair
+	{
+		FbxHandle mKey;
+		FbxHandle mItem;
+	};
+
+	/** If can't find the matching item,append a item at the end of the array.
+	* If find the matching item ,insert the new item before the matching item. 
+    * \param pKey The value of Key in new item, also is the character for matching.
+	* \param pItem The value of Item in new item.
+	* \return If add successfully return true,otherwise return false.
+    */
+    bool Add(FbxHandle pKey, FbxHandle pItem);
+	
+	/** Remove the first matching item, whose reference is the same as given.
+	* \param pKey The given reference.
+	* \return If remove successfully return true,otherwise return false.
+	*/
+    bool Remove(FbxHandle pKey);
+	
+	/** Remove all the matching item, whose item is the same as given.
+	* \param pItem The given item.
+	* \return If remove successfully return true,otherwise return false.
+	*/
+    bool RemoveItem(FbxHandle pItem);
+
+    /** Set first matching item with the given parameter.
+    * \param pKey The character for matching.
+	* \param pItem  The value of Item that the matching item will be set.
+	* \return If set successfully return true,otherwise return false.
+    */
+    bool SetItem(FbxHandle pKey, FbxHandle pItem);
+
+    /** Get first matching item with the given parameter.
+    * \param pKey The character for matching.
+	* \param pIndex The pointer to the index of the matching item.
+	* \return The value of Item in the matching item.
+    * \remarks If there are multiple elements that match the character, the index returned is unspecified.
+    */
+    FbxHandle Get(FbxHandle pKey, int* pIndex=NULL);
+
+	//! Delete the array.
+    void Clear();
+
+	/** Get the item of the given index.
+    * \param pIndex The index for matching.
+	* \param pKey The pointer to the Key of the matching item.
+	* \return The value of Item in the matching item.
+    */
+    FbxHandle GetFromIndex(int pIndex, FbxHandle* pKey=NULL);
+
+	/** Remove the item of the given index
+	* \param pIndex The given index.
+	* \return If remove successfully return true,otherwise return false.
+	*/
+    bool RemoveFromIndex(int pIndex);
+
+	/** Get number of items in the array.
+	* \return The number of items in the array. */
+    int GetCount() const { return mSetCount; }
+
+	/** Swap the value of Key and Item in every item of array, and sort the new array with the value of Key. */
+    void Swap();
+
+	/** Sort the array according the value of Key in each item. */
+    void Sort();
+
+/*****************************************************************************************************************************
+** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
+*****************************************************************************************************************************/
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+	FbxMultiMap(int pItemPerBlock=20);
+	FbxMultiMap(const FbxMultiMap& pOther);
+	~FbxMultiMap();
+
+    FbxMultiMap& operator=(const FbxMultiMap&);
+
+private:
+    Pair*	FindEqual(FbxHandle pKey) const;
+
+    Pair*	mSetArray;
+    int		mSetCount;
+    int		mBlockCount;
+    int		mItemPerBlock;
+    bool	mIsChanged;
+#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
+};
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* _FBXSDK_CORE_BASE_MULTIMAP_H_ */

+ 62 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/base/fbxpair.h

@@ -0,0 +1,62 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxpair.h
+#ifndef _FBXSDK_CORE_BASE_PAIR_H_
+#define _FBXSDK_CORE_BASE_PAIR_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+/** This class template holds a pair of objects.
+* \nosubgrouping */
+template <typename First, typename Second> class FbxPair
+{
+public:
+	//! Constructor.
+	inline FbxPair() : mFirst(), mSecond() {}
+
+	/** Constructor.
+	* \param pFirst The first object.
+	* \param pSecond The second object. */
+	inline FbxPair(const First& pFirst, const Second& pSecond) : mFirst(pFirst), mSecond(pSecond) {}
+
+	/** Assignment operator.
+	* \param pOther The pair to be copied. */
+	inline FbxPair<First, Second>& operator=(const FbxPair<First, Second>& pOther)
+	{
+		mFirst = pOther.mFirst;
+		mSecond = pOther.mSecond;
+		return *this;
+	}
+
+	/** Comparison operator.
+	* \param pOther The pair to be compared. */
+	inline bool operator==(const FbxPair<First, Second>& pOther)
+	{
+		return mFirst == pOther.mFirst && mSecond == pOther.mSecond;
+	}
+
+	/** Inverse comparison operator.
+	* \param pOther The pair to be compared. */
+	inline bool operator!=(const FbxPair<First, Second>& pOther)
+	{
+		return !operator==(pOther);
+	}
+
+	First mFirst;	//!< The first object in the pair.
+	Second mSecond;	//!< The second object in the pair.
+};
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* _FBXSDK_CORE_BASE_PAIR_H_ */

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1398 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/base/fbxredblacktree.h


+ 227 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/base/fbxset.h

@@ -0,0 +1,227 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxset.h
+#ifndef _FBXSDK_CORE_BASE_SET_H_
+#define _FBXSDK_CORE_BASE_SET_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#include <fbxsdk/core/base/fbxredblacktree.h>
+#include <fbxsdk/core/base/fbxmap.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+/** This class implements an efficient set based on value comparison, which stores values.
+* It executes insertion, deletion and query operations in O(log(n)) time. */
+template <typename Type, typename Compare=FbxLessCompare<Type>, typename Allocator=FbxBaseAllocator> class FbxSet
+{
+protected:
+	//! This class defines the value type used by the set.
+	class Value
+	{
+	/*****************************************************************************************************************************
+	** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
+	*****************************************************************************************************************************/
+	#ifndef DOXYGEN_SHOULD_SKIP_THIS
+	public:
+		typedef const Type KeyType;
+		typedef const Type ConstKeyType;
+		typedef const Type ValueType;
+		typedef const Type ConstValueType;
+
+		inline Value(const Type& pValue) : mValue(pValue){}
+		inline KeyType& GetKey() const { return mValue; }
+		inline ConstKeyType& GetKey(){ return mValue; }
+		inline ValueType& GetValue() const { return mValue; }
+		inline ConstValueType& GetValue(){ return mValue; }
+
+	protected:
+		ValueType mValue;
+
+	private:
+		Value& operator=(const Value&);
+	#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
+	};
+
+	//! Declaration of the storage type used by the set.
+	typedef FbxRedBlackTree<Value, Compare, Allocator> StorageType;
+
+public:
+	typedef Type ValueType;
+	typedef typename StorageType::RecordType        RecordType;
+	typedef typename StorageType::IteratorType      Iterator;
+	typedef typename StorageType::ConstIteratorType ConstIterator;
+
+	/** Preallocate memory.
+	* \param pRecordCount The number of elements.
+	*/
+	inline void Reserve(unsigned int pRecordCount)
+	{
+		mTree.Reserve(pRecordCount);
+	}
+
+	//! Retrieve the number of values it holds.
+	inline int GetSize() const
+	{
+		return mTree.GetSize();
+	}
+
+	/** Insert a value.
+	* \param pValue The value.
+	* \return If the value is already present in the map, returns the existing value and false; else returns the pointer to the new value and true. */
+	inline FbxPair<RecordType*, bool> Insert(const ValueType& pValue)
+	{
+		return mTree.Insert(Value(pValue));
+	}
+
+	/** Delete a value.
+	* \param pValue The value.
+	* \return \c true if success, \c false if value is not found. */
+	inline int Remove(const ValueType& pValue)
+	{
+		return mTree.Remove(pValue);
+	}
+
+	//! Clear the set.
+	inline void Clear()
+	{
+		mTree.Clear();
+	}
+
+	//! Query whether the set is empty.
+	inline bool Empty() const
+	{
+		return mTree.Empty();
+	}
+
+	//! Retrieve the begin iterator of the set.
+	Iterator Begin()
+	{
+		return Iterator(Minimum());
+	}
+
+	//! Retrieve the end iterator of the set.
+	Iterator End()
+	{
+		return Iterator();
+	}
+
+	//! Retrieve the begin iterator of the set.
+	ConstIterator Begin() const
+	{
+		return ConstIterator(Minimum());
+	}
+
+	//! Retrieve the end iterator of the set.
+	ConstIterator End() const
+	{
+		return ConstIterator();
+	}
+
+	/** Find a given value in the set.
+	* \param pValue The value to find.
+	* \return The value in the set, or NULL if the value is not found in the set. */
+	inline const RecordType* Find(const ValueType& pValue) const
+	{
+		return mTree.Find(pValue);
+	}
+
+	/** Find a given value in the set.
+	* \param pValue The value to find.
+	* \return The value in the set, or NULL if the value is not found in the set. */
+	inline RecordType* Find(const ValueType& pValue)
+	{
+		return mTree.Find(pValue);
+	}
+
+	//! Retrieve the minimum value in the set.
+	inline const RecordType* Minimum() const
+	{
+		return mTree.Minimum();
+	}
+
+	//! Retrieve the minimum value in the set.
+	inline RecordType* Minimum()
+	{
+		return mTree.Minimum();
+	}
+
+	//! Retrieve the maximum value in the set.
+	inline const RecordType* Maximum() const
+	{
+		return mTree.Maximum();
+	}
+
+	//! Retrieve the maximum value in the set.
+	inline RecordType* Maximum()
+	{
+		return mTree.Maximum();
+	}
+
+	//! Equality operator.
+	inline bool operator==(const FbxSet<Type, Compare, Allocator>& pOther) const
+	{
+		return (this == &pOther) || (mTree == pOther.mTree);
+	}
+
+	//! Inequality operator.
+	inline bool operator != (const FbxSet<Type, Compare, Allocator>& pOther) const
+	{
+		return !(*this == pOther);
+	}
+
+	/** Intersect with another set.
+	* \param pOther The other set.
+	* \return The intersection set of the two sets. */
+	inline FbxSet Intersect(const FbxSet& pOther) const
+	{
+		FbxSet lReturn;
+		ConstIterator lBegin = Begin();
+		for (; lBegin != End(); ++lBegin)
+		{
+			if (pOther.Find(lBegin->GetValue()) != NULL)
+				lReturn.Insert(lBegin->GetValue());
+		}
+		return lReturn;
+	}
+
+	/** Unite with another set.
+	* \param pOther The other set.
+	* \return The union set of the two sets (no duplicated items). */
+	inline FbxSet Union(const FbxSet& pOther) const
+	{
+		FbxSet lReturn(*this);
+		ConstIterator lBegin = pOther.Begin();
+		for (; lBegin != End(); ++lBegin)
+		{
+			if (Find(lBegin->GetValue()) == NULL)
+				lReturn.Insert(lBegin->GetValue());
+		}
+		return lReturn;
+	}
+
+/*****************************************************************************************************************************
+** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
+*****************************************************************************************************************************/
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+    inline FbxSet(){}
+    inline FbxSet(const FbxSet& pSet) : mTree(pSet.mTree){}
+    inline ~FbxSet(){ Clear(); }
+
+private:
+    StorageType mTree;
+#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
+};
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* _FBXSDK_CORE_BASE_SET_H_ */

+ 119 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/base/fbxstatus.h

@@ -0,0 +1,119 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxstatus.h
+#ifndef _FBXSDK_CORE_BASE_STATUS_H_
+#define _FBXSDK_CORE_BASE_STATUS_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#include <fbxsdk/core/base/fbxstring.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+/** This class facilitates the testing/reporting of errors.  It encapsulates the
+  * status code and the internal FBXSDK error code as returned by the API functions.
+  * \nosubgrouping
+  */
+class FBXSDK_DLL FbxStatus
+{
+public:
+
+
+    //! Available status codes.
+    enum EStatusCode {        
+        eSuccess = 0,                           //!< Operation was successful
+        eFailure,                               //!< Operation failed
+        eInsufficientMemory,                    //!< Operation failed due to insufficient memory
+        eInvalidParameter,                      //!< An invalid parameter was provided
+        eIndexOutOfRange,                       //!< Index value outside the valid range
+        ePasswordError,                         //!< Operation on FBX file password failed
+        eInvalidFileVersion,                    //!< File version not supported (anymore or yet)
+        eInvalidFile                            //!< Operation on the file access failed
+    };
+
+    //! Default constructor.
+    FbxStatus();
+
+    FbxStatus(EStatusCode pCode);
+    FbxStatus(const FbxStatus& rhs);
+
+    FbxStatus&      operator=(const FbxStatus& rhs);
+
+    /** Equivalence operator.
+      * \param rhs Status object to compare.
+      * \return \c True if all the members of \e rhs are equal to this instance members and \c False otherwise.
+      */
+    bool            operator==(const FbxStatus& rhs)    const   { return (mCode == rhs.mCode); }
+    /** Equivalence operator.
+      * \param pCode Status code to compare.
+      * \return \c True if the code member of this instance equals \e pCode and \c False otherwise.
+      */
+    bool            operator==(const EStatusCode pCode) const   { return (mCode == pCode); }
+    /** Non-Equivalence operator.
+      * \param rhs Status object to compare.
+      * \return \c True if at least one member of \e rhs is not equal to this instance member and \c True otherwise.
+      */
+    bool            operator!=(const FbxStatus& rhs)    const   { return (mCode != rhs.mCode); }
+    /** Non-Equivalence operator.
+      * \param rhs Status code to compare.
+      * \return \c True if the code member of this instance equals \e rhs and \c False otherwise.
+      */
+    bool            operator!=(const EStatusCode rhs)   const   { return (mCode != rhs); }
+
+    /** The conversion operator that converts a FbxStatus object to bool.
+      *	The result it returns will be \c True if the FbxStatus does not contain
+      * an error, and \c False if it does.
+      */
+    operator        bool() const    { return mCode==eSuccess; }
+
+    /** Determines whether there is an error.
+      * \return \c True if an error occured and \c False if the operation was sucessful.
+      */
+    bool            Error() const   { return !this->operator bool(); }
+
+    //! Clear error code and message from the instance. After this call, it will behave as if it contained eSuccess.
+    void            Clear();
+
+    //! Retrieve the type of error that occurred, as specified in the enumeration.
+    EStatusCode     GetCode() const { return mCode; }
+
+    /** Change the current code of the instance.
+      * \param rhs New code value.
+      */
+    void            SetCode(const EStatusCode rhs);
+
+    /** Change the current code of the instance.
+      * \param rhs New code value.
+      * \param pErrorMsg Optional error description string. This string can have formatting characters
+      *                  The function will use the vsnprintf function to assemble the final string
+      *                  using an internal buffer of 4096 characters.
+      */
+    void            SetCode(const EStatusCode rhs, const char* pErrorMsg, ...);
+
+    //! Get the error message string corresponding to the current code.
+    const char*     GetErrorString() const;
+
+/*****************************************************************************************************************************
+** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
+*****************************************************************************************************************************/
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+private:
+    EStatusCode     mCode;
+    FbxString       mErrorString;
+
+#endif /* !DOXYGEN_SHOULD_SKIP_THIS */
+};
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* _FBXSDK_CORE_BASE_STATUS_H_ */

+ 505 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/base/fbxstring.h

@@ -0,0 +1,505 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxstring.h
+#ifndef _FBXSDK_CORE_BASE_STRING_H_
+#define _FBXSDK_CORE_BASE_STRING_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+/** Convert string from UTF8 to wide-char
+* \param pInUTF8 Input string
+* \param pOutWideChar output string
+* \param pOutWideCharSize size of the allocated output string buffer
+* \remark Output buffer should be release by caller */
+FBXSDK_DLL void FbxUTF8ToWC(const char* pInUTF8, wchar_t*& pOutWideChar, size_t* pOutWideCharSize=NULL);
+
+/** Convert string from wide-char to UTF8
+* \param pInWideChar input string
+* \param pOutUTF8 output string
+* \param pOutUTF8Size size of the allocated output string buffer
+* \remark Output buffer should be release by caller */
+FBXSDK_DLL void FbxWCToUTF8(const wchar_t* pInWideChar, char*& pOutUTF8, size_t* pOutUTF8Size=NULL);
+
+#if defined(FBXSDK_ENV_WIN)
+	/** Convert string from wide-char to ANSI
+	* \param pInWideChar input string
+	* \param pOutANSI output string
+	* \param pOutANSISize size of the allocated output string buffer
+	* \remark Output buffer should be release by caller */
+	FBXSDK_DLL void FbxWCToAnsi(const wchar_t* pInWideChar, char*& pOutANSI, size_t* pOutANSISize=NULL);
+
+	/** Convert string from ANSI to wide-char
+	* \param pInANSI input string
+	* \param pOutWideChar output string
+	* \param pOutWideCharSize size of the allocated output string buffer
+	* \remark Output buffer should be release by caller */
+	FBXSDK_DLL void FbxAnsiToWC(const char* pInANSI, wchar_t*& pOutWideChar, size_t* pOutWideCharSize=NULL);
+
+	/** Convert string from ANSI to UTF8
+	* \param pInANSI input string
+	* \param outUTF8 output string
+	* \param pOutUTF8Size size of the allocated output string buffer
+	* \remark Output buffer should be release by caller */
+	FBXSDK_DLL void FbxAnsiToUTF8(const char* pInANSI, char*& pOutUTF8, size_t* pOutUTF8Size=NULL);
+
+	/** Convert string from UTF8 to ANSI
+	* \param pInUTF8 input string
+	* \param pOutANSI output string
+	* \param pOutANSISize size of the allocated output string buffer
+	* \remark Output buffer should be release by caller */
+	FBXSDK_DLL void FbxUTF8ToAnsi(const char* pInUTF8, char*& pOutANSI, size_t* pOutANSISize=NULL);
+#endif
+
+/** Utility class to manipulate strings.
+* \nosubgrouping */
+class FBXSDK_DLL FbxString
+{
+public:
+	/**
+	* \name Constructors and Destructor
+	*/
+	//@{
+		//! Default constructor.
+		FbxString();
+
+		/** Copy constructor.
+		* \param pString The FbxString to be copied. */
+		FbxString(const FbxString& pString);
+
+		/** String constructor.
+		* \param pString The string used to construct FbxString. */
+		FbxString(const char* pString);
+
+		/** Character constructor.
+		* \param pChar The character used to construct FbxString.
+		* \param pNbRepeat The number of times to repeat the character. Default value is 1 */
+		FbxString(char pChar, size_t pNbRepeat=1);
+
+		/** String constructor with maximum length.
+		* \param pCharPtr The string used to construct FbxString. 
+		* \param pLength  Maximum length. */
+		FbxString(const char* pCharPtr, size_t pLength);
+
+		/** Integer constructor.
+		* \param pValue The int value used to construct FbxString. */
+		FbxString(const int pValue);
+
+		/** Float constructor.
+		* \param pValue The float value used to construct FbxString. */
+		FbxString(const float pValue);
+
+		/** Double constructor.
+		* \param pValue The double value used to construct FbxString. */
+		FbxString(const double pValue);
+
+		//! Destructor.
+		~FbxString();
+	//@}
+
+	/**
+	* \name Buffer Access and Validation
+	*/
+	//@{
+		//! Get string length like "C" strlen().
+		size_t GetLen() const;
+
+		//! Get string length like "C" strlen().
+		size_t Size() const;
+
+		//! Return \c true if string length equal zero.
+		bool IsEmpty() const;
+
+		//! Discard the content of the string.
+		FbxString& Clear();
+
+		/** Access by reference.
+		* \param pIndex   The index.
+		* \return The reference of the char at pIndex. */
+		char& operator[](int pIndex);
+
+		/** Access by copy.
+		* \param pIndex   The index.
+		* \return The char at pIndex. */
+		char operator[](int pIndex) const;
+
+		//! Non-const buffer access.
+		char* Buffer();
+
+		//! Const buffer access.
+		const char* Buffer()const;
+	//@}
+
+	/**
+	* \name String Operations
+	*/
+	//@{
+		/** FbxString assignment operator.
+		* \param pString The FbxString to be assigned. */
+		const FbxString& operator=(const FbxString& pString);
+
+		/** Character assignment operator.
+		* \param pChar The character to be assigned. */
+		const FbxString& operator=(char pChar);
+
+		/** String assignment operator.
+		* \param pString The string to be assigned. */
+		const FbxString& operator=(const char* pString);
+
+		/** Int assignment operator.
+		* \param pValue The int value to be assigned. */
+		const FbxString& operator=(int pValue);
+
+		/** Float assignment operator.
+		* \param pValue The float value to be assigned. */
+		const FbxString& operator=(float pValue);
+
+		/** Double assignment operator.
+		* \param pValue The double value to be assigned. */
+		const FbxString& operator=(double pValue);
+
+		/** FbxString append.
+		* \param pString The FbxString to be appended. */
+		const FbxString& operator+=(const FbxString& pString);
+
+		/** Character append.
+		* \param pChar  The character to be appended. */
+		const FbxString& operator+=(char pChar);
+
+		/** String append.
+		* \param pString The string to be appended. */
+		const FbxString& operator+=(const char* pString);
+
+		/** Integer append.
+		* \param pValue The int value to be appended. */
+		const FbxString& operator+=(int pValue);
+
+		/** Float append.
+		* \param pValue The float value to be appended. */
+		const FbxString& operator+=(float pValue);
+
+		/** Double append.
+		* \param pValue The double value to be appended. */
+		const FbxString& operator+=(double pValue);
+
+		/** Equality operator.
+		* \param pString The FbxString to be compared. */
+		bool operator== (const FbxString& pString) const;
+
+		/** Inequality operator.
+		* \param pString The FbxString to be compared. */
+		bool operator!= (const FbxString& pString) const;
+
+		/** Inferior to operator.
+		* \param pString The FbxString to be compared. */
+		bool operator< (const FbxString& pString) const;
+
+		/** Inferior or equal to operator.
+		* \param pString The FbxString to be compared. */
+		bool operator<= (const FbxString& pString) const;
+
+		/** Superior or equal to operator.
+		* \param pString The FbxString to be compared. */
+		bool operator>= (const FbxString& pString) const;
+
+		/** Superior to operator.
+		* \param pString The FbxString to be compared. */
+		bool operator> (const FbxString& pString) const;
+
+		/** Equality operator.
+		* \param pString The string to be compared. */
+		bool operator== (const char* pString) const;
+
+		/** Inequality operator.
+		* \param pString The string to be compared. */
+		bool operator!= (const char* pString) const;
+
+		/** Inferior to operator.
+		* \param pString The string to be compared. */
+		bool operator< (const char* pString) const;
+
+		/** Inferior or equal to operator.
+		* \param pString The string to be compared. */
+		bool operator<= (const char* pString) const;
+
+		/** Superior or equal to operator.
+		* \param pString The string to be compared. */
+		bool operator>= (const char* pString) const;
+
+		/** Superior to operator.
+		* \param pString The string to be compared. */
+		bool operator> (const char* pString) const;
+
+		/** FbxString concatenation.
+		* \param pString1 FbxString 1 to be concatenated to FbxString 2.
+		* \param pString2 FbxString 2 to be concatenated to FbxString 1 */
+		friend FBXSDK_DLL FbxString operator+(const FbxString& pString1, const FbxString& pString2);
+
+		/** Character concatenation.
+		* \param pString  FbxString to be concatenated to Character.
+		* \param pChar  Character to be concatenated to FbxString */
+		friend FBXSDK_DLL FbxString operator+(const FbxString& pString, char pChar);
+
+		/** Character concatenation.
+		* \param pChar  Character to be concatenated to FbxString
+		* \param pString  FbxString to be concatenated to Character. */
+		friend FBXSDK_DLL FbxString operator+(char pChar, const FbxString& pString);
+
+		/** String concatenation.
+		* \param pString1  FbxString to be concatenated to String.
+		* \param pString2  String to be concatenated to FbxString */
+		friend FBXSDK_DLL FbxString operator+(const FbxString& pString1, const char* pString2);
+
+		/** String concatenation.
+		* \param pString1  String to be concatenated to FbxString
+		* \param pString2  FbxString to be concatenated to String. */
+		friend FBXSDK_DLL FbxString operator+(const char* pString1, const FbxString& pString2);
+
+		/** Integer concatenation.
+		* \param pString  FbxString to be concatenated to Integer.
+		* \param pValue  Integer to be concatenated to FbxString */
+		friend FBXSDK_DLL FbxString operator+(const FbxString& pString, int pValue);
+
+		/** Integer concatenation.
+		* \param pValue  Integer to be concatenated to FbxString 
+		* \param pString  FbxString to be concatenated to Integer. */
+		friend FBXSDK_DLL FbxString operator+(int pValue, const FbxString& pString);
+
+		/** Float concatenation.
+		* \param pString  FbxString to be concatenated to Float.
+		* \param pValue  Float to be concatenated to FbxString */
+		friend FBXSDK_DLL FbxString operator+(const FbxString& pString, float pValue);
+
+		/** Float concatenation.
+		* \param pValue  Float to be concatenated to FbxString
+		* \param pString  FbxString to be concatenated to Float. */
+		friend FBXSDK_DLL FbxString operator+( float pValue, const FbxString& pString);
+
+		/** Double concatenation.
+		* \param pString  FbxString to be concatenated to Double.
+		* \param pValue  Double to be concatenated to FbxString */
+		friend FBXSDK_DLL FbxString operator+(const FbxString& pString, double pValue);
+
+		//! Cast operator.
+		operator const char*() const;
+
+		/** String assignment function with maximum length.
+		  * \param pString The string to be assigned.
+		  * \param pLength The maximum length of string to be assigned. */
+		const FbxString& Copy(const char* pString, size_t pLength);
+
+		/** Append as "C" strncat().
+		* \param pString The string to be appended.
+		* \param pLength The length of chars to be appended. */
+		const FbxString& Append(const char* pString, size_t pLength);
+
+		/** Compare as "C" strcmp().
+		* \param pString    The string to be compared. */
+		int Compare(const char* pString) const;
+
+		/** Compare as "C" stricmp().
+		* \param pString    The string to be compared. */
+		int CompareNoCase(const char* pString) const;
+
+		/** Swap the contents of two strings.
+		* \param pString The FbxString to be swapped. */
+		void Swap(FbxString& pString);
+
+		//! Uppercase conversion.
+		FbxString Upper() const;
+
+		//! Lowercase conversion.
+		FbxString Lower() const;
+	//@}
+
+    /**
+    * \name Substring Extraction
+    */
+    //@{
+		/** Extract middle string for a given length.
+		* \param pFirst The start index of FbxString to be extracted.
+		* \param pCount The length of sub-string to be extracted. */
+		FbxString Mid(size_t pFirst, size_t pCount) const;
+
+		/** Extract middle string up to the end.
+		* \param pFirst The start index of FbxString to be extracted. */
+		FbxString Mid(size_t pFirst) const;
+
+		/** Extract left string.
+		* \param pCount The length of sub-string to be extracted. */
+		FbxString Left(size_t pCount) const;
+
+		/** Extract right string.
+		* \param pCount The length of sub-string to be extracted. */
+		FbxString Right(size_t pCount) const;
+	//@}
+
+	/**
+	* \name Padding
+	*/
+	//@{
+		/** \enum EPaddingType      Padding types.
+		* - \e eRight
+		* - \e eLeft
+		* - \e eBoth */
+		enum EPaddingType {eRight, eLeft, eBoth};
+
+		/** Add padding characters.
+		* \param pPadding The padding type.
+		* \param pLen The length limit of FbxString after padding. 
+		* \param pCar The character to be padded. */
+		FbxString Pad(EPaddingType pPadding, size_t pLen, char pCar=' ') const;
+
+		/** Remove padding characters.
+		* \param pPadding The padding type.
+		* \param pCar The character to be padded. 
+		* \remark If pCar == '\0' the function will remove all the characters that are tested by isspace(). */
+		FbxString UnPad(EPaddingType pPadding, char pCar='\0') const;
+	//@}
+
+	/**
+	* \name Search
+	*/
+	//@{
+		/** Look for a single character match, like "C" strchr().
+		* \param pChar The character to look for.
+		* \param pStartPosition  Start position to look for.
+		* \return Index or -1 if not found. */
+		int Find(char pChar, size_t pStartPosition=0) const;
+
+		/** Look for a substring match, like "C" strstr().
+		* \param pStrSub The substring to look for.
+		* \param pStartPosition  Start position to look for.
+		* \return Starting index or -1 if not found. */
+		int Find(const char* pStrSub, size_t pStartPosition=0) const;
+
+		/** Look for the last occurrence of character in string, like "C" strrchr().
+		* \param pChar The character to look for.
+		* \return Index or -1 if not found. */
+		int ReverseFind(char pChar) const;
+
+		/** Look for a single character match, like "C" strpbrk().
+		* \param pStrCharSet The character set.
+		* \param pStartPosition The start position.
+		* \return Index or -1 if not found. */
+		int FindOneOf(const char* pStrCharSet, size_t pStartPosition=0) const;
+
+		/** Replace a substring.
+		* \param pFind The substring to look for.
+		* \param pReplaceBy The string to replace by.
+		* \param pStartPosition The start position. 
+		* \return \c true if substring found and replaced. */
+		bool FindAndReplace(const char* pFind, const char* pReplaceBy, size_t pStartPosition=0);
+
+		/** Replace all occurrence of a substring.
+		* \param pFind The substring to look for.
+		* \param pReplaceBy The string to replace by.
+		* \return \c true if something got replaced. */
+		bool ReplaceAll(const char* pFind, const char* pReplaceBy);
+
+        /** Replace all occurrence of character to find by replacement character.
+		* \param pFind The character to look for.
+		* \param pReplaceBy The character to replace by.
+		* \return \c true if character found and replaced. */
+		bool ReplaceAll(char pFind, char pReplaceBy);
+	//@}
+
+	/**
+	* \name Token Extraction
+	*/
+	//@{
+		/** Get number of tokens.
+		* \param pSpans The span
+		* \return The number of tokens. */
+		int GetTokenCount(const char* pSpans) const;
+
+		/** Get token at given index.
+		* \param pTokenIndex The token index.
+		* \param pSpans The span */
+		FbxString GetToken(int pTokenIndex, const char* pSpans) const;
+	//@}
+
+private:
+	// Lengths/sizes in characters. 
+	// Note: an extra character is always allocated.
+	char* mData; // Actual string (zero terminated).
+
+	FbxString(size_t pSrc1Len, const char* pSrc1Data, size_t pSrc2Len, const char* pSrc2Data); // Previously ConcatCopy
+	void Init();
+
+	//! Invalidate string.
+	void Invalidate();
+
+	void FreeBuffer();
+	void FreeBuffer(char *&pOldData);
+
+	bool AllocCopy(FbxString& pDest, size_t pCopyLen, size_t pCopyIndex) const;
+	bool AllocBuffer(size_t pLen);
+	bool AllocBuffer(size_t pLen, char*& pOldData);
+
+	bool AssignCopy(size_t pSrcLen, const char* pSrcData);
+	bool ConcatInPlace(size_t pSrcLen, const char* pSrcData);
+
+	bool IsIn(char pChar, const char* pString) const;
+	bool InternalFindAndReplace(const char* pFind, const char* pReplaceBy, size_t& pStartPosition); 
+};
+
+FBXSDK_INCOMPATIBLE_WITH_ARRAY(FbxString);
+
+//! FbxString concatenation.
+FBXSDK_DLL FbxString operator+(const FbxString& pString1, const FbxString& pString2);
+
+//! Character concatenation.
+FBXSDK_DLL FbxString operator+(const FbxString& pString, char pChar);
+
+//! String concatenation.
+FBXSDK_DLL FbxString operator+(const FbxString& pString1, const char* pString2);
+
+//! Integer concatenation.
+FBXSDK_DLL FbxString operator+(const FbxString& pString, int pValue);
+
+//! Float concatenation.
+FBXSDK_DLL FbxString operator+(const FbxString& pString, float pValue);
+
+//! Double concatenation.
+FBXSDK_DLL FbxString operator+(const FbxString& pString, double pValue);
+
+//! Functor to compare FbxString
+struct FbxStringCompare { inline int operator()(const FbxString& pKeyA, const FbxString& pKeyB) const { return pKeyA.Compare(pKeyB); } };
+
+//! Functor to compare FbxString without case sensitivity
+struct FbxStringCompareNoCase { inline int operator()(const FbxString& pKeyA, const FbxString& pKeyB) const { return pKeyA.CompareNoCase(pKeyB); } };
+
+//! Functor to compare "C" strings
+struct FbxCharPtrCompare { inline int operator()(const char* pKeyA, const char* pKeyB) const { return strcmp(pKeyA, pKeyB); } };
+
+//! Functor to compare "C" strings without case sensitivity
+struct FbxCharPtrCompareNoCase { inline int operator()(const char* pKeyA, const char* pKeyB) const { return FBXSDK_stricmp(pKeyA, pKeyB); } };
+
+/** Remove the given char in the given string.
+* \param pString The given string.
+* \param pToRemove The given char that ought to be removed.
+* \remarks Strings used in this function are case-sensitive. */
+inline void FbxRemoveChar(FbxString& pString, char pToRemove)
+{
+    int lPos = pString.ReverseFind(pToRemove);
+    while( lPos >= 0 )
+    {
+        pString = pString.Left(lPos) + pString.Mid(lPos + 1);
+        lPos = pString.ReverseFind(pToRemove);
+    }
+}
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* _FBXSDK_CORE_BASE_STRING_H_ */

+ 368 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/base/fbxstringlist.h

@@ -0,0 +1,368 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxstringlist.h
+#ifndef _FBXSDK_CORE_BASE_STRING_LIST_H_
+#define _FBXSDK_CORE_BASE_STRING_LIST_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#include <fbxsdk/core/base/fbxarray.h>
+#include <fbxsdk/core/base/fbxstring.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+//! Wraps a string (FbxString) and a pointer (FbxHandle).
+class FbxStringListItem
+{
+public:
+    FbxStringListItem(){ mReference = 0; }
+    FbxStringListItem(const char* pString, FbxHandle pRef=0){ mString = pString; mReference = pRef; }
+
+    FbxString	mString; 
+    FbxHandle		mReference;
+};
+
+inline int FbxCompareStringListSort(const void* E1, const void* E2)
+{
+	return FBXSDK_stricmp((*(FbxStringListItem**)E1)->mString.Buffer(), (*(FbxStringListItem**)E2)->mString.Buffer());
+}
+
+inline int FbxCompareStringListFindEqual(const void* E1, const void* E2)
+{
+	return FBXSDK_stricmp((*(FbxStringListItem*)E1).mString.Buffer(), (*(FbxStringListItem**)E2)->mString.Buffer());
+}
+
+inline int FbxCompareCaseSensitiveStringList(const void *E1,const void *E2)
+{
+	return strcmp((*(FbxStringListItem*)E1).mString.Buffer(), (*(FbxStringListItem**)E2)->mString.Buffer());
+}
+ 
+//! Base class of FbxStringList.
+template <class Type> class FbxStringListT
+{
+protected:
+    FbxArray<Type*> mList;
+
+public:
+	/**
+     * \name Operation With The Array 
+     */
+   //@{
+
+	 /** Append a item at the end of the array.
+    * \return Index of appended pointer.
+    */
+    int		AddItem( Type* pItem )		{ return mList.Add( pItem ); }
+
+    /** Insert a item in the array.
+    * \param pIndex Position where to insert the item.
+    * \param pItem  Item to insert.
+    * \return Position of the inserted item in the array.
+    * \remarks If the given index is out of range, the pointer is appended at the end of the array.
+    */
+	int		InsertItemAt( int pIndex, Type* pItem )	{ return mList.InsertAt( pIndex, pItem ); }
+
+	//! Access item at given index.
+    Type*   GetItemAt( int pIndex )	const	{ return mList[pIndex]; }
+
+	/** Find first matching item.
+    * \return Index of first matching item found or -1 if there is no matching element.
+    */
+    int		FindItem( Type* pItem )	const	{ return mList.Find( pItem ); }
+	//}@
+
+public : 
+    /**
+     * \name Constructor and Destructor
+     */
+   //@{
+
+	//! Default constructor.
+    FbxStringListT()
+    {
+    }
+
+	//! Destructor.
+    virtual ~FbxStringListT() { Clear(); }
+	//}@
+
+	//!Remove the item at the end of the array and delete the associated object.
+    void RemoveLast() { RemoveAt( mList.GetCount()-1 ); }
+
+	/** Get number of items in the array.
+     * \return The number of items in the array.
+     */
+    inline int		GetCount() const { return mList.GetCount(); }
+
+	//! Access the string in the item at given index.
+    FbxString&   operator[](int pIndex) { return mList[pIndex]->mString; }
+
+    //! Access the value of reference in the item at given index.
+    FbxHandle		GetReferenceAt(int pIndex) const { return mList[pIndex]->mReference; }
+
+    //! Set the value of reference at given index.        
+    void			SetReferenceAt(int pIndex, FbxHandle pRef) { mList[pIndex]->mReference = pRef; }
+
+	//! Access the pointer of string at given index.
+    char*		GetStringAt(int pIndex) const { if (pIndex<mList.GetCount()) return mList[pIndex]->mString.Buffer(); else return NULL; }
+    
+	//! Set string at given index.
+	virtual bool	SetStringAt(int pIndex, const char* pString) 
+    { 
+	    if (pIndex<mList.GetCount()) 
+	    {
+		    mList[pIndex]->mString = pString; 
+		    return true;
+	    } else return false; 
+    }
+   
+    /** Find first matching item.
+    * \return Index of first matching item found or -1 if  there is no
+    * matching element.
+    */
+    int Find( Type& pItem ) const
+    { 
+	    for (int Count=0; Count<mList.GetCount(); Count++) {
+		    if (mList[Count]==&pItem) {
+			    return Count;
+		    }
+	    }
+	    return -1;
+    }
+
+	/** Find first matching item which has the same reference as given parameter.
+    * \return Index of first matching item found or -1 if  there is no
+    * matching element.
+    */
+    int FindIndex( FbxHandle pReference ) const
+    { 
+	    for (int Count=0; Count<mList.GetCount(); Count++) {
+		    if (mList[Count]->mReference==pReference) {
+			    return Count;
+		    }
+	    }
+	    return -1;
+    }
+
+	/** Find first matching item in array whose string address is the same as given pointer.
+    * \return Index of first matching item found or -1 if  there is no
+    * matching element.
+    */
+    int FindIndex( const char* pString ) const
+    { 
+	    for (int lCount=0; lCount<mList.GetCount(); lCount++) {
+		    if (mList[lCount]->mString==pString) {
+			    return lCount;
+		    }
+	    }
+	    return -1;
+    }
+
+	/** Access the value of reference of the first matching item in array 
+	* whose string address is the same as given pointer.
+    * \return The value of reference of the first matching item found or NULL if  there is no
+    * matching element.
+    */
+    FbxHandle FindReference(const char* pString ) const
+    {
+    int lIndex = FindIndex( pString );
+	    if (lIndex!=-1) {
+		    return mList[lIndex]->mReference;
+	    }
+	    return 0; // NULL
+    }
+
+	//! Remove first matching item.
+    bool Remove ( Type& pItem )
+    {
+    int lIndex = Find( pItem );
+        if (lIndex>=0) {
+		    RemoveAt( lIndex );
+		    return true;
+	    }
+	    return false;
+    }
+
+	//! Remove first matching item in array whose string address is the same as given pointer.
+    bool Remove (const char* pString )
+    {
+    int lIndex = FindIndex( pString );
+        if (lIndex>=0) {
+		    RemoveAt( lIndex );
+		    return true;
+	    }
+	    return false;
+    }
+
+	//! Remove first matching item.
+    bool RemoveIt ( Type& pItem )
+    {
+    int lIndex = Find( pItem );
+        if (lIndex>=0) {
+		    RemoveAt( lIndex );
+		    return true;
+	    }
+	    return false;
+    }
+
+	//! Sort the array by the string of every item,not case sensitive.
+    void Sort( )
+    {
+	    qsort( &(mList.GetArray()[0]),mList.GetCount(),sizeof(FbxStringListItem*),FbxCompareStringListSort );
+    }
+
+    /** Find first matching item which has the same string as given parameter,not case sensitive.
+    * \return the pointer of matching item found or NULL if  there is no
+    * matching element.
+	* \remark To cast the returned pointer to the FbxStringListItem you need a double indirection: (FbxStringListItem**)
+    */
+	void* FindEqual(const char* pString) const
+    {
+    FbxStringListItem Key(pString);  
+    
+	    if (mList.GetCount() != 0)
+	    {
+		    return bsearch ( &Key, &(mList.GetArray()[0]),mList.GetCount(),sizeof(FbxStringListItem*),FbxCompareStringListFindEqual );
+	    }
+	    else
+	    {
+		    return NULL ;
+	    }
+    }
+
+	/** Find first matching item which has the same string as given parameter, case sensitive.
+    * \return the pointer of matching item found or NULL if  there is no
+    * matching element.
+	* \remark To cast the returned pointer to the FbxStringListItem you need a double indirection: (FbxStringListItem**)
+    */
+	void* FindCaseSensitive(const char* pString) const
+	{
+    FbxStringListItem Key(pString);  
+    
+	    if (mList.GetCount() != 0)
+	    {
+		    return bsearch ( &Key, &(mList.GetArray()[0]),mList.GetCount(),sizeof(FbxStringListItem*), FbxCompareCaseSensitiveStringList);
+	    }
+	    else
+	    {
+		    return NULL ;
+	    }
+	
+	}
+
+
+	//! Add a new item at the end of array.
+    int Add( const char* pString, FbxHandle pItem=0 ) 
+    { 
+	    return InsertAt( mList.GetCount(),pString,pItem ); 
+    }
+
+    virtual int InsertAt( int pIndex, const char* pString, FbxHandle pItem=0 ) 
+    { 
+	    return mList.InsertAt( pIndex,FbxNew< Type >( pString,(FbxHandle)pItem )); 
+    }
+
+    /** Remove the item at the given position in the array and delete the associated object.
+    * \param pIndex Position of the item to remove.
+    * \remarks If the index is not valid, nothing is performed. Otherwise,
+    * the item is removed from the array and the items are shifted to fill the
+    * empty slot.
+    */
+	virtual void RemoveAt(int pIndex)
+    { 
+	    FbxDelete(mList.RemoveAt(pIndex));
+    }
+
+	//! Delete the array.
+    virtual void Clear()
+    {
+		FbxArrayDelete(mList);
+    }
+
+	/** Get the string of all the item.
+    * \return The text of string, each item's string separated by '~'.
+    */
+   virtual void GetText(FbxString& pText) const
+    {
+	    int	lCount;
+	    for (lCount=0; lCount<mList.GetCount(); lCount++) 
+        {
+            pText += mList[lCount]->mString;
+            if (lCount<mList.GetCount()-1) 
+            {               
+                pText += "~";               
+            }
+	    }
+    }
+
+    /** Clear the array and set the array's new items with the substring separated by '~' from the given string.
+    * \param pList The string which used to generate the new items.
+	* \return The last index of the item in the new array.
+    * \remarks The number of items in the new array is the same as the number of substrings, 
+	* and the string of each item is decided by the content of each substring.
+    */ 
+    virtual int SetText(const char* pList)
+    {
+    int		lPos=0, lOldPos = 0;
+    int		lLastIndex=0;
+    FbxString	lName=pList;
+
+	    Clear();
+	    for (lPos=0; lName.Buffer()[lPos]!=0; lPos++) {
+    	    if (lName.Buffer()[lPos]=='~') {
+        	    lName.Buffer()[lPos]=0;
+        	    lLastIndex = Add(lName.Buffer()+lOldPos);
+        	    lOldPos=lPos+1;
+    	    }
+	    }
+
+	    if(lOldPos != lPos)
+	    {
+	        lLastIndex = Add(lName.Buffer()+lOldPos);
+	    }
+	    return lLastIndex;
+    } 
+
+
+};
+
+/** Array that stores pairs of FbxString and a pointer.
+  */
+class FBXSDK_DLL FbxStringList : public FbxStringListT<FbxStringListItem>
+{
+public:
+	/**
+	  * \name Constructors
+	  */
+	//@{
+		//! Default constructor.
+		FbxStringList(); 
+
+		//! Copy constructor.
+		FbxStringList( const FbxStringList& pOriginal );
+	//@}
+
+	/**
+	 * \name Assignment Operators
+	 */
+	//@{
+		//! FbxStringList assignment function.
+		void CopyFrom( const FbxStringList* pOriginal  );
+
+		//! FbxStringList assignment operator.
+		FbxStringList& operator=(const FbxStringList& pOriginal);
+	//@}
+};
+	  
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* _FBXSDK_CORE_BASE_STRING_LIST_H_ */

+ 648 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/base/fbxtime.h

@@ -0,0 +1,648 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxtime.h
+#ifndef _FBXSDK_CORE_BASE_TIME_H_
+#define _FBXSDK_CORE_BASE_TIME_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#include <fbxsdk/core/base/fbxtimecode.h>
+#include <fbxsdk/core/base/fbxstring.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+#define FBXSDK_TIME_INFINITE		FbxTime(FBXSDK_TC_INFINITY)
+#define FBXSDK_TIME_MINUS_INFINITE	FbxTime(FBXSDK_TC_MINFINITY)
+#define FBXSDK_TIME_ZERO			FbxTime(FBXSDK_TC_ZERO)
+#define FBXSDK_TIME_EPSILON			FbxTime(FBXSDK_TC_EPSILON)
+#define FBXSDK_TIME_ONE_SECOND		FbxTime(FBXSDK_TC_SECOND)
+#define FBXSDK_TIME_ONE_MINUTE		FbxTime(FBXSDK_TC_MINUTE)
+#define FBXSDK_TIME_ONE_HOUR		FbxTime(FBXSDK_TC_HOUR)
+#define FBXSDK_TIME_ASSERT_EPSILON	0.5
+#define FBXSDK_TIME_FORWARD			1
+#define FBXSDK_TIME_BACKWARD		-1
+
+class FbxTimeModeObject;
+
+/** Class to encapsulate time units.
+  * \nosubgrouping
+  * FbxTime can measure time in hour, minute, second, frame, field, residual and also combination of these units.
+  * It is recommended to use FbxTime for all time related operations. For example, currently it is used in FbxGlobalSettings,
+  * FbxGlobalTimeSettings, FbxCache, all curve filters and all animation-related classes, etc.
+  * FbxTime is just used to represent a moment, to represent a period of time, FbxTimeSpan should be used.
+  * \see FbxTimeSpan
+  */
+class FBXSDK_DLL FbxTime 
+{
+public:
+	/** Long long constructor.
+	  * \param pTime Initial value defined as a 64bit integer.
+	  */
+	FbxTime(const FbxLongLong pTime=0){ mTime = pTime; }
+
+	/**
+	  * \name Time Modes and Protocols
+	  */
+    //@{
+		/** Time modes.
+		  * \remarks
+		  * EMode \c eNTSCDropFrame is used for broadcasting operations where 
+		  * clock time must be (almost) in sync with time code. To bring back color 
+		  * NTSC time code with clock time, this mode drops 2 frames per minute
+		  * except for every 10 minutes (00, 10, 20, 30, 40, 50). 108 frames are 
+		  * dropped per hour. Over 24 hours the error is 2 frames and 1/4 of a 
+		  * frame. A time-code of 01:00:03:18 equals a clock time of 01:00:00:00
+		  * 
+		  * \par
+		  * EMode \c eNTSCFullFrame represents a time address and therefore is NOT 
+		  * IN SYNC with clock time. A time code of 01:00:00:00 equals a clock time 
+		  * of 01:00:03:18.
+		  * 
+		  * - \e eDefaultMode		
+		  * - \e eFrames120			120 frames/s
+		  * - \e eFrames100			100 frames/s
+		  * - \e eFrames60          60 frames/s
+		  * - \e eFrames50          50 frames/s
+		  * - \e eFrames48          48 frame/s
+		  * - \e eFrames30          30 frames/s (black and white NTSC)
+		  * - \e eFrames30Drop		30 frames/s (use when display in frame is selected, equivalent to NTSC drop)
+		  * - \e eNTSCDropFrame		~29.97 frames/s drop color NTSC
+		  * - \e eNTSCFullFrame		~29.97 frames/s color NTSC
+		  * - \e ePAL				25 frames/s	PAL/SECAM
+		  * - \e eFrames24			24 frames/s Film/Cinema
+		  * - \e eFrames1000		1000 milli/s (use for date time)
+		  * - \e eFilmFullFrame		~23.976 frames/s
+		  * - \e eCustom            Custom frame rate value
+		  * - \e eFrames96			96 frames/s
+		  * - \e eFrames72			72 frames/s
+		  * - \e eFrames59dot94		~59.94 frames/s
+		  * - \e eModesCount		Number of time modes
+		  */
+		enum EMode
+		{
+			eDefaultMode,
+			eFrames120,
+			eFrames100,
+			eFrames60,
+			eFrames50,
+			eFrames48,
+			eFrames30,
+			eFrames30Drop,
+			eNTSCDropFrame,
+			eNTSCFullFrame,
+			ePAL,
+			eFrames24,
+			eFrames1000,
+			eFilmFullFrame,
+			eCustom,
+			eFrames96,
+			eFrames72,
+			eFrames59dot94,
+			eModesCount
+		};
+
+		/** Time protocols enumaration
+		  * - \e eSMPTE				SMPTE EProtocol
+		  * - \e eFrameCount		Frame count
+		  * - \e eDefaultProtocol	Default protocol (initialized to eFRAMES)
+		  */
+		enum EProtocol {eSMPTE, eFrameCount, eDefaultProtocol};
+
+		/** Set default time mode.
+		  * \param pTimeMode  Time mode identifier.
+		  * \param pFrameRate Custom framerate, only have effect in case of pTimeMode = FbxTime::eCustom
+		  * \remarks It is meaningless to set default time mode to \c eDefaultMode.
+		  */
+		static void SetGlobalTimeMode(EMode pTimeMode, double pFrameRate=0.0);
+
+		/** Get default time mode.
+		  * \return Currently set time mode identifier.
+		  * \remarks Default time mode initial value is eFrames30.
+		  */
+		static EMode GetGlobalTimeMode();
+
+		/** Set default time protocol.
+		  * \param pTimeProtocol Time protocol identifier.
+		  * \remarks It is meaningless to set default time protocol to \c eDefaultProtocol.
+		  */
+		static void SetGlobalTimeProtocol(EProtocol pTimeProtocol);
+
+		/** Get default time protocol.
+		  * \return Currently set time protocol identifier.
+		  * \remarks Default time protocol initial value is eSMPTE.
+		  */
+		static EProtocol GetGlobalTimeProtocol();
+
+		/** Get frame rate associated with time mode, in frames per second.
+		  * \param pTimeMode Time mode identifier.
+		  * \return Frame rate value.
+		  */
+		static double GetFrameRate(EMode pTimeMode);
+
+		/** Get time mode associated with frame rate.
+		  * \param pFrameRate The frame rate value.
+		  * \param pPrecision The tolerance value.
+		  * \return The corresponding time mode identifier or \c eDefaultMode if no time 
+		  * mode associated to the given frame rate is found.
+		  */
+		static EMode ConvertFrameRateToTimeMode(double pFrameRate, double pPrecision=0.00000001);
+	//@}
+	
+	/**
+	  * \name Time Conversion
+	  */
+	//@{
+		/** Set time in internal format.
+		  * \param pTime Time value to set.
+		  */
+		inline void Set(FbxLongLong pTime){ mTime = pTime; }
+
+		/** Get time in internal format.
+		  * \return Time value.
+		  */
+		inline FbxLongLong Get() const { return mTime; }
+
+		/** Set time in milliseconds.
+		  * \param pMilliSeconds Time value to set.
+		  */
+		inline void SetMilliSeconds(FbxLongLong pMilliSeconds){ mTime = pMilliSeconds * FBXSDK_TC_MILLISECOND; }
+
+		/** Get time in milliseconds.
+		  * \return Time value.
+		  */
+		inline FbxLongLong GetMilliSeconds() const { return mTime / FBXSDK_TC_MILLISECOND; }
+
+		/** Set time in seconds.
+		  * \param pTime Time value to set.
+		  */
+		void SetSecondDouble(double pTime);
+
+		/** Get time in seconds.
+		  * \return Time value.
+		  */
+		double GetSecondDouble() const;
+
+		/** Set time in hour/minute/second/frame/field format.
+		  * \param pHour The hours value.
+		  * \param pMinute    The minutes value.
+		  * \param pSecond    The seconds value.
+		  * \param pFrame     The frames values.
+		  * \param pField     The field value.
+		  * \param pTimeMode  Time mode identifier.
+		  * \remarks Parameters pHour, pMinute, pSecond, pFrame and pField are summed together.
+		  * For example, it is possible to set the time to 83 seconds in the following
+		  * ways: SetTime(0,1,23) or SetTime(0,0,83).
+		  */
+		void SetTime(int pHour, int pMinute, int pSecond, int pFrame=0, int pField=0, EMode pTimeMode=eDefaultMode);
+
+		/** Set time in hour/minute/second/frame/field/residual format.
+		  * \param pHour The hours value.
+		  * \param pMinute       The minutes value.
+		  * \param pSecond       The seconds value.
+		  * \param pFrame        The frames values.
+		  * \param pField        The field value.
+		  * \param pResidual     The hundredths of frame value.
+		  * \param pTimeMode     Time mode identifier.
+		  * \remarks Parameters pHour, pMinute, pSecond, pFrame, pField and pResidual 
+		  * are summed together, just like above.
+		  * pResidual represents hundredths of frame, and won't necessarily
+		  * correspond to an exact internal value.
+		  *
+		  * \remarks The time mode can't have a default value, because
+		  *         otherwise SetTime(int, int, int, int, int, int)
+		  *         would be ambiguous. Please specify DEFAULT_MODE.
+		  */
+		void SetTime(int pHour, int pMinute, int pSecond, int pFrame, int pField, int pResidual, EMode pTimeMode);
+
+		/** Get time in hour/minute/second/frame/field/residual format.
+		  * \param pHour       The returned hours value.
+		  * \param pMinute     The returned minutes value.
+		  * \param pSecond     The returned seconds value.
+		  * \param pFrame      The returned frames values.
+		  * \param pField      The returned field value.
+		  * \param pResidual   The returned hundredths of frame value.
+		  * \param pTimeMode   The time mode identifier which will dictate the extraction algorithm.
+		  * \return \c true if the pTimeMode parameter is a valid identifier and thus the extraction
+		  * succeeded. If the function returns \c false, all the values are set to 0.
+		  */
+		bool GetTime(int& pHour, int& pMinute, int& pSecond, int& pFrame, int& pField, int& pResidual, EMode pTimeMode=eDefaultMode) const;
+
+		/** Snaps a time value to the time value associated with the nearest frame.
+		  * \param pRound  If \c true the return value is rounded to the nearest integer.
+		  * \return        The snapped time value.
+		  */
+		FbxTime	GetFramedTime(bool pRound=true) const;
+
+		/** Set time in frame format.
+		  * \param pFrames The number of frames.
+		  * \param pTimeMode The time mode identifier which will dictate the extraction algorithm.
+		  */
+		void SetFrame(FbxLongLong pFrames, EMode pTimeMode=eDefaultMode);
+
+		/** Set time in frame format, including fractions.
+		  * \param pFrames The number of frames in decimal value.
+		  * \param pTimeMode The time mode identifier which will dictate the extraction algorithm.
+		  */
+		void SetFramePrecise(FbxDouble pFrames, EMode pTimeMode=eDefaultMode);
+
+		/** Get number of hours in time.
+		  * \return Hours value.
+		  */
+		int GetHourCount() const;
+
+		/** Get number of minutes in time.
+		  * \return Minutes value.
+		  */
+		int GetMinuteCount() const;
+
+		/** Get number of seconds in time.
+		  * \return Seconds value.
+		  */
+		int GetSecondCount() const;
+
+		/** Get number of frames in time.
+		  * \param pTimeMode Time mode identifier.
+		  * \return Integer value representing the frame count.
+		  */
+		FbxLongLong GetFrameCount(EMode pTimeMode=eDefaultMode) const;
+
+		/** Get precise number of frames in time, including fractions.
+		  * \param pTimeMode Time mode identifier.
+		  * \return Decimal value representing the frame count, including fractions.
+		  */
+		FbxDouble GetFrameCountPrecise(EMode pTimeMode=eDefaultMode) const;
+
+		/** Get number of fields in time.
+		  * \param pTimeMode Time mode identifier.
+		  * \return Fields value.
+		  */
+		FbxLongLong GetFieldCount(EMode pTimeMode=eDefaultMode) const;
+
+		/** Get residual time exceeding last full field.
+		  * \param pTimeMode Time mode identifier.
+		  * \return Residual value.
+		  */
+		int GetResidual(EMode pTimeMode=eDefaultMode) const;
+
+		/** Test for Drop Frame mode
+		  * \param pTimeMode Time mode identifier.
+		  * \return True if the pTimeMode is a Drop Frame mode.
+		  */
+		static bool IsDropFrame(EMode pTimeMode=eDefaultMode);
+
+		/** Separator char between second and frame.
+		  * \param pTimeMode Time mode identifier.
+		  * \return ';' is returned if pTimeMode is a DropFrame mode otherwise ':'.
+		  */
+		char GetFrameSeparator(EMode pTimeMode=eDefaultMode) const;
+
+		/** Get time in a human readable format.
+		  * \param pTimeString An array large enough to contain a minimum of 19 characters.
+          * \param pTimeStringSize Size of the pTimeString buffer used with secure functions.
+		  * \param pInfo The amount of information if time protocol is \c eSMPTE:
+		  * <ul><li>1 means hours only
+		  *     <li>2 means hours and minutes
+		  *     <li>3 means hours, minutes and seconds
+		  *     <li>4 means hours, minutes, seconds and frames
+		  *     <li>5 means hours, minutes, seconds, frames and field
+		  *     <li>6 means hours, minutes, seconds, frames, field and residual value</ul>
+		  * \param pTimeMode Requested time mode.
+		  * \param pTimeFormat Requested time protocol.
+		  * \return pTimeString parameter filled with a time value or set to a empty string
+		  * if parameter pInfo is not valid.
+		  */
+		char* GetTimeString(char* pTimeString, const FbxUShort& pTimeStringSize, int pInfo=5, EMode pTimeMode=eDefaultMode, EProtocol pTimeFormat=eDefaultProtocol) const;
+
+		enum EElement {eHours, eMinutes, eSeconds, eFrames, eField, eResidual};
+
+		/** Get the time in a human readable format.
+		* \param pStart The starting element type used to format the time string.
+		* \param pEnd The last element type used to format the time string.
+		* \param pTimeMode The time mode requested.
+		* \param pTimeFormat The time format requested.
+		* \return The human readable time string. */
+		FbxString GetTimeString(EElement pStart=eHours, EElement pEnd=eResidual, EMode pTimeMode=eDefaultMode, EProtocol pTimeFormat=eDefaultProtocol) const;
+
+        /** Set time in a human readable format.
+		  * \param pTime An array of a maximum of 18 characters.
+		  * If time protocol is \c eSMPTE, pTimeString must be formatted this way:
+		  * "[hours:]minutes[:seconds[.frames[.fields]]]". Hours, minutes, seconds, 
+		  * frames and fields are parsed as integers and brackets indicate optional 
+		  * parts. 
+		  * If time protocol is \c eFRAME, pTimeString must be formatted this way:
+		  * "frames". Frames is parsed as a 64 bits integer.
+		  * \param pTimeMode   Given time mode.
+		  * \param pTimeFormat Given time protocol.
+		  * \return True if the set time string succeed, otherwise return false.
+		  */
+		bool SetTimeString(const char* pTime, EMode pTimeMode=eDefaultMode, EProtocol pTimeFormat=eDefaultProtocol);
+    //@}
+
+	/**
+	  * \name Time Operators
+	  */
+	//@{
+		/** Equality operator.
+		  * \param pTime The FbxTime to be compared.
+		  * \return \c true if equal, \c false otherwise.
+		  */
+		inline bool operator==(const FbxTime& pTime) const { return mTime == pTime.mTime; }
+
+		/** Inequality operator.
+		  * \param pTime The FbxTime to be compared.
+		  * \return \c true if unequal, \c false otherwise.
+		  */
+		inline bool operator!=(const FbxTime& pTime) const { return mTime != pTime.mTime; }
+
+		/** Superior or equal to operator.
+		  * \param pTime The FbxTime to be compared.
+		  * \return \c true if this FbxTime is superior or equal to the passed FbxTime, \c false otherwise.
+		  */
+		inline bool operator>=(const FbxTime& pTime) const { return mTime >= pTime.mTime; }
+
+		/** Inferior or equal to operator.
+		  * \param pTime The FbxTime to be compared.
+		  * \return \c true if this FbxTime is inferior or equal to the passed FbxTime, \c false otherwise.
+		  */
+		inline bool operator<=(const FbxTime& pTime) const { return mTime <= pTime.mTime; }
+
+		/** Superior to operator.
+		  * \param pTime The FbxTime to be compared.
+		  * \return \c true if this FbxTime is superior to the passed FbxTime, \c false otherwise.
+		  */
+		inline bool operator>(const FbxTime& pTime) const { return mTime > pTime.mTime; }
+
+		/** Inferior to operator.
+		  * \param pTime The FbxTime to be compared.
+		  * \return \c true if this FbxTime is inferior to the passed FbxTime, \c false otherwise.
+		  */
+		inline bool operator<(const FbxTime& pTime) const { return mTime < pTime.mTime; } 
+
+		/** Assignment operator.
+		  * \param pTime The FbxTime to be assigned.
+		  */
+		inline FbxTime& operator=(const FbxTime& pTime) { mTime = pTime.mTime; return *this; }
+
+		/** Addition operator.
+		  * \param  pTime The FbxTime to be added.
+		  * \return This FbxTime after addition.
+		  */
+		inline FbxTime& operator+=(const FbxTime& pTime) { mTime += pTime.mTime; return *this; }
+
+		/** Subtraction operator.
+		  * \param pTime The FbxTime to be subtracted.
+		  * \return This FbxTime after subtraction.
+		  */
+		inline FbxTime& operator-=(const FbxTime& pTime) { mTime -= pTime.mTime; return *this; }
+
+		/** Addition operator.
+		  * \param pTime The FbxTime to be added.
+		  * \return A temporary FbxTime after addition. 
+		  */
+		FbxTime operator+(const FbxTime& pTime) const;
+
+		/** Subtraction operator.
+		  * \param pTime The FbxTime to be subtracted.
+		  * \return A temporary FbxTime after subtraction. 
+		  */
+		FbxTime operator-(const FbxTime& pTime) const;
+
+		/** Multiplication operator.
+		  * \param Mult Multiply this FbxTime by int Mult.
+		  * \return A temporary FbxTime after multiplication. 
+		  */
+		FbxTime operator*(const int Mult) const;
+
+		/** Division operator.
+		  * \param pTime Divide this FbxTime by pTime.
+		  * \return A temporary FbxTime after division. 
+		  */
+		FbxTime operator/(const FbxTime& pTime) const;
+
+		/** Multiplication operator.
+		  * \param pTime Multiply this FbxTime by pTime.
+		  * \return A temporary FbxTime after multiplication. 
+		  */
+		FbxTime operator*(const FbxTime& pTime) const;
+/*
+		//! Increment time of one unit of the internal format (prefix form).
+		inline FbxTime& operator++() { mTime += 1; return (*this); }
+
+		//! Increment time of one unit of the internal format (postfix form).
+		inline const FbxTime operator++(int) { FbxTime lOld = *this; ++(*this); return lOld; }
+
+		//! Decrement time of one unit of the internal format (prefix form).
+		inline FbxTime& operator--() { mTime -= 1; return (*this); }
+
+		//! Decrement time of one unit of the internal format (postfix form).
+		inline const FbxTime operator--(int) { FbxTime lOld = *this; --(*this); return lOld; }*/
+	//@}
+
+	/** One frame value for a specified time mode.
+	  * \param pTimeMode Time mode identifier.
+	  * \return the time code of a one frame.
+	  */
+	static FbxLongLong GetOneFrameValue(EMode pTimeMode=eDefaultMode);
+
+/*****************************************************************************************************************************
+** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
+*****************************************************************************************************************************/
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+	// Keep compatibility with old fbx format
+	enum EOldMode
+	{
+		eOLD_DEFAULT_MODE,		//Default mode set using FbxTime::SetGlobalTimeMode(EMode pTimeMode)
+		eOLD_CINEMA,			//24 frameOLD_s/s
+		eOLD_PAL,				//25 frameOLD_s/s	 PAL/SECAM
+		eOLD_FRAMES30,			//30 frameOLD_s/s	 BLACK & WHITE NTSC
+		eOLD_NTSC_DROP_FRAME,   //29.97002617 frameOLD_s/s COLOR NTSC
+		eOLD_FRAMES50,			//50 frameOLD_s/s
+		eOLD_FRAMES60,			//60 frameOLD_s/s
+		eOLD_FRAMES100,			//100 frameOLD_s/s
+		eOLD_FRAMES120,			//120 frameOLD_s/s
+		eOLD_NTSC_FULL_FRAME,	//29.97002617 frameOLD_s/s COLOR NTSC
+		eOLD_FRAMES30_DROP,		//30 frameOLD_s/s
+		eOLD_FRAMES1000			//1000 frameOLD_s/s
+	};
+
+private:
+	FbxLongLong					mTime; //In 1 / 46,186,158,000 Seconds
+
+	static EMode				gsGlobalTimeMode;
+	static EProtocol			gsGlobalTimeProtocol;
+	static FbxTimeModeObject*	gsTimeObject;
+
+	void InternalSetTime(int pHour, int pMinute, int pSecond, FbxLongLong pFrame, int pField, EMode pTimeMode);
+
+    friend FBXSDK_DLL FbxTime::EMode		FbxGetGlobalTimeMode();
+	friend FBXSDK_DLL FbxTimeModeObject*	FbxGetGlobalTimeModeObject();
+    friend FBXSDK_DLL FbxTime::EProtocol	FbxGetGlobalTimeFormat();
+	friend FBXSDK_DLL void					FbxSetGlobalTimeMode(FbxTime::EMode pTimeMode, double pFrameRate);
+    friend FBXSDK_DLL void					FbxSetGlobalTimeFormat(FbxTime::EProtocol pTimeFormat);
+#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
+};
+
+/** FbxTime in seconds constructor.
+  * \param pTime 
+  */
+FBXSDK_DLL inline FbxTime FbxTimeSeconds(const FbxDouble& pTime=0.0)
+{
+	FbxTime lTime;
+	lTime.SetSecondDouble(pTime);
+	return lTime;
+}
+
+/** Class to encapsulate time intervals.
+  * \nosubgrouping
+  * \see FbxTime 
+  */
+class FBXSDK_DLL FbxTimeSpan
+{
+public:
+	//! Constructor.
+	FbxTimeSpan() {}
+
+	/** Constructor.
+	  * \param pStart Beginning of the time interval.
+	  * \param pStop  Ending of the time interval.
+	  */
+	FbxTimeSpan(FbxTime pStart, FbxTime pStop){ mStart = pStart; mStop = pStop; }
+
+	/** Set start and stop time.
+	  * \param pStart Beginning of the time interval.
+	  * \param pStop  Ending of the time interval.
+	  */
+	inline void Set(FbxTime pStart, FbxTime pStop){ mStart = pStart; mStop = pStop; }
+
+	/** Set start time.
+	  * \param pStart Beginning of the time interval.
+	  */
+	inline void SetStart(FbxTime pStart){ mStart = pStart; }
+
+	/** Set stop time.
+	  * \param pStop  Ending of the time interval.
+	  */
+	inline void SetStop(FbxTime pStop){ mStop = pStop; }
+
+	/** Get start time.
+	  * \return Beginning of time interval.
+	  */
+	inline FbxTime GetStart() const { return mStart; }
+
+	/** Get stop time.
+	  * \return Ending of time interval.
+	  */
+	inline FbxTime GetStop() const { return mStop; }
+
+	/** Get time interval in absolute value.
+	  * \return Time interval.
+	  */
+	inline FbxTime GetDuration() const { if( mStop > mStart ) return mStop - mStart; else return mStart - mStop; }
+
+	/** Get time interval.
+	  * \return Signed time interval.
+	  */
+	inline FbxTime GetSignedDuration() const { return mStop - mStart; }
+
+	/** Get direction of the time interval.
+	  * \return \c FBXSDK_TIME_FORWARD if time interval is forward, \c FBXSDK_TIME_BACKWARD if backward.
+	  */
+	inline int GetDirection() const { if( mStop >= mStart ) return FBXSDK_TIME_FORWARD; else return FBXSDK_TIME_BACKWARD; }
+
+	/** Return \c true if the time is inside the timespan.
+	  * \param pTime Judge whether pTime is inside the timespan.
+	  * \return \c True if is, \c false otherwise.
+	  */
+	bool IsInside(FbxTime pTime) const;
+
+	/** Return the intersection of the two time spans.
+	  * \param pTime 
+	  * \return The intersection of pTime and this FbxTimeSpan.
+	  */
+	FbxTimeSpan Intersect(const FbxTimeSpan& pTime) const;
+
+	/** Inequality operator.
+	  * \param pTime FbxTimeSpan compared with this one.
+	  * \return \c True if unequal, \c false otherwise.
+	  */
+	bool operator!=(const FbxTimeSpan& pTime) const;
+
+	/** Equality operator.
+	  * \param pTime FbxTimeSpan compared with this one.
+	  * \return \c True if equal, \c false otherwise.
+	  */
+	bool operator==(const FbxTimeSpan& pTime) const;
+
+	/** Unite with another FbxTimeSpan
+	  * \param pSpan The FbxTimeSpan
+	  * \param pDirection FBXSDK_TIME_FORWARD or FBXSDK_TIME_BACKWARD
+	  * \remarks This function assumes both of the FbxTimeSpan objects are in the same direction.
+	  * Use FBXSDK_TIME_FORWARD when start < stop in both timespan
+	  * Use FBXSDK_TIME_BACKWARD when start > stop in both timespan
+	  */
+	void UnionAssignment(const FbxTimeSpan& pSpan, int pDirection=FBXSDK_TIME_FORWARD);
+
+/*****************************************************************************************************************************
+** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
+*****************************************************************************************************************************/
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+private:
+	FbxTime mStart;
+	FbxTime mStop;
+#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
+};
+
+class FBXSDK_DLL FbxLocalTime
+{
+public:
+	FbxLocalTime();
+
+	int mYear;
+	int mMonth;
+	int mDay;
+	int mHour;
+	int mMinute;
+	int mSecond;
+	int mMillisecond;
+};
+
+FBXSDK_DLL void					FbxGetCurrentLocalTime(FbxLocalTime& pLocalTime);
+
+FBXSDK_DLL FbxTime::EMode		FbxGetGlobalTimeMode();
+FBXSDK_DLL FbxTimeModeObject*	FbxGetGlobalTimeModeObject();
+FBXSDK_DLL FbxTime::EProtocol	FbxGetGlobalTimeFormat();
+FBXSDK_DLL void					FbxSetGlobalTimeMode(FbxTime::EMode pTimeMode, double pFrameRate=0.0);
+FBXSDK_DLL void					FbxSetGlobalTimeFormat(FbxTime::EProtocol pTimeFormat);
+
+// Use those functions to keep the compatibility with old time mode since we added new time mode.
+FBXSDK_DLL FbxTime::EOldMode		FbxGetOldTimeModeCorrespondance(FbxTime::EMode pMode);
+FBXSDK_DLL FbxTime::EMode		FbxGetTimeModeFromOldValue(FbxTime::EOldMode pOldMode);
+
+// We now store the framerate instead of the time mode.
+FBXSDK_DLL FbxTime::EMode		FbxGetTimeModeFromFrameRate(char* pFrameRate);
+FBXSDK_DLL void					FbxGetControlStringList(char* pControlString, FbxTime::EProtocol pTimeFormat);
+FBXSDK_DLL const char*			FbxGetGlobalFrameRateString(FbxTime::EMode pTimeMode);
+FBXSDK_DLL const char*			FbxGetGlobalTimeModeString(FbxTime::EMode pTimeMode);
+FBXSDK_DLL double				FbxGetFrameRate(FbxTime::EMode pTimeMode);
+
+// Time format
+FBXSDK_DLL FbxTime::EProtocol	FbxSelectionToTimeFormat(int pSelection);
+FBXSDK_DLL FbxTime::EMode		FbxSelectionToTimeMode(int pSelection);
+FBXSDK_DLL int					FbxTimeToSelection(FbxTime::EMode pTimeMode=FbxTime::eDefaultMode, int pTimeFormat=FbxTime::eDefaultProtocol);
+FBXSDK_DLL const char*			FbxGetTimeModeName(FbxTime::EMode pTimeMode);
+FBXSDK_DLL int					FbxGetFrameRateStringListIndex(FbxTime::EMode pTimeMode);
+FBXSDK_DLL bool					FbxIsValidCustomFrameRate(double pFramerate);
+FBXSDK_DLL bool					FbxGetNearestCustomFrameRate(double pFramerate, double& pNearestRate);
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* _FBXSDK_CORE_BASE_TIME_H_ */

+ 99 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/base/fbxtimecode.h

@@ -0,0 +1,99 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxtimecode.h
+#ifndef _FBXSDK_CORE_BASE_TIMECODE_H_
+#define _FBXSDK_CORE_BASE_TIMECODE_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+#define FBXSDK_TC_ZERO					FBXSDK_LONGLONG(0)  
+#define FBXSDK_TC_EPSILON				FBXSDK_LONGLONG(1)
+#define FBXSDK_TC_MINFINITY				FBXSDK_LONGLONG(-0x7fffffffffffffff)
+#define FBXSDK_TC_INFINITY				FBXSDK_LONGLONG(0x7fffffffffffffff)
+#define FBXSDK_TC_FIX_DEN				FBXSDK_LONGLONG(100000000)
+
+#define FBXSDK_TC_MILLISECOND			FBXSDK_LONGLONG(46186158)
+#define FBXSDK_TC_SECOND				FbxLongLong(FBXSDK_TC_MILLISECOND*1000)
+#define FBXSDK_TC_MINUTE				FbxLongLong(FBXSDK_TC_SECOND*60)
+#define FBXSDK_TC_HOUR					FbxLongLong(FBXSDK_TC_MINUTE*60)
+#define FBXSDK_TC_DAY					FbxLongLong(FBXSDK_TC_HOUR*24)
+
+// Frame @ 30 Hz
+#define FBXSDK_TC_NTSC_FIELD			FbxLongLong(FBXSDK_TC_SECOND/30/2)
+#define FBXSDK_TC_NTSC_FRAME			FbxLongLong(FBXSDK_TC_SECOND/30)
+
+// Frame @ 29.9700299700 Hz
+#define FBXSDK_TC_MNTSC_FIELD			FbxLongLong(FBXSDK_TC_MNTSC_FRAME/2)
+#define FBXSDK_TC_MNTSC_FRAME			FbxLongLong(FBXSDK_TC_SECOND/30*1001/1000)
+#define FBXSDK_TC_MNTSC_2_FRAMES		FbxLongLong(FBXSDK_TC_MNTSC_FRAME*2)
+#define FBXSDK_TC_MNTSC_30_FRAMES		FbxLongLong(FBXSDK_TC_MNTSC_FRAME*30)
+#define FBXSDK_TC_MNTSC_1798_FRAMES		FbxLongLong(FBXSDK_TC_MNTSC_FRAME*1798)		// leap minute
+#define FBXSDK_TC_MNTSC_1800_FRAMES		FbxLongLong(FBXSDK_TC_MNTSC_FRAME*1800)		// ~1 minute
+#define FBXSDK_TC_MNTSC_17982_FRAMES	FbxLongLong(FBXSDK_TC_MNTSC_FRAME*17982)	// ~10 minutes
+#define FBXSDK_TC_MNTSC_107892_FRAMES	FbxLongLong(FBXSDK_TC_MNTSC_FRAME*107892)	// ~1 hour
+#define FBXSDK_TC_MNTSC_108000_FRAMES	FbxLongLong(FBXSDK_TC_MNTSC_FRAME*108000)
+
+// For 29.9700299700 non-drop, btw : same values as with 23.976
+#define FBXSDK_TC_MNTSC_1_SECOND		FbxLongLong(FBXSDK_TC_MNTSC_FRAME*30)		// 1 frame * 30
+#define FBXSDK_TC_MNTSC_1_MINUTE		FbxLongLong(FBXSDK_TC_MNTSC_1_SECOND*60)	// 1 minute (1800 frames)
+#define FBXSDK_TC_MNTSC_1_HOUR			FbxLongLong(FBXSDK_TC_MNTSC_1_SECOND*3600)	// 1 hour
+
+#define FBXSDK_TC_MNTSC_NUM				FbxULong(FBXSDK_TC_FIX_DEN*1000*30/1001)
+#define FBXSDK_TC_MNTSC_DEN				FBXSDK_TC_FIX_DEN
+
+// Frame @ 25 Hz
+#define FBXSDK_TC_PAL_FIELD				FbxLongLong(FBXSDK_TC_SECOND/25/2)
+#define FBXSDK_TC_PAL_FRAME				FbxLongLong(FBXSDK_TC_SECOND/25)
+
+// Frame @ 24 Hz
+#define FBXSDK_TC_FILM_FRAME			FbxLongLong(FBXSDK_TC_SECOND/24)
+
+// Frame @ 23.9760239760 Hz
+#define FBXSDK_TC_MFILM_FIELD			FbxLongLong(FBXSDK_TC_MFILM_FRAME/2)
+#define FBXSDK_TC_MFILM_FRAME			FbxLongLong(FBXSDK_TC_SECOND/24*1001/1000)
+#define FBXSDK_TC_MFILM_1_SECOND		FbxLongLong(FBXSDK_TC_MFILM_FRAME*24)		// 1 frame * 24   
+#define FBXSDK_TC_MFILM_1_MINUTE		FbxLongLong(FBXSDK_TC_MFILM_1_SECOND*60)	// 1 minute (1440 frames)
+#define FBXSDK_TC_MFILM_1_HOUR			FbxLongLong(FBXSDK_TC_MFILM_1_SECOND*3600)	// 1 hour
+
+#define FBXSDK_TC_MFILM_NUM				FbxULong(FBXSDK_TC_FIX_DEN*1000*24/1001)
+#define FBXSDK_TC_MFILM_DEN				FBXSDK_TC_FIX_DEN
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
+#define FBXSDK_TC_REM(quot, num, den)		((quot) = (num) / (den), (quot) * (den))
+#define FBXSDK_TC_HOUR_REM(quot, num, den)	((quot) = ((num - (-FbxLongLong(num < 0) & (den - 1))) / (den)), (quot) * (den))
+
+FBXSDK_DLL FbxLongLong FbxTCSeconds(FbxLongLong pTime);
+FBXSDK_DLL FbxLongLong FbxTCMinutes(FbxLongLong pTime);
+FBXSDK_DLL FbxLongLong FbxTCHours(FbxLongLong pTime);
+FBXSDK_DLL FbxLongLong FbxTCSetRate(int pHour, int pMinute, int pSecond, FbxLongLong pFrame, FbxLongLong pPeriod);
+FBXSDK_DLL FbxLongLong FbxTCGetRate(FbxLongLong pTime, int& pHour, int& pMinute, int& pSecond, int& pFrame, FbxLongLong pPeriod);
+FBXSDK_DLL FbxLongLong FbxTCSetNTSC(int pHour, int pMinute, int pSecond, FbxLongLong pFrame, int pField);
+FBXSDK_DLL FbxLongLong FbxTCGetNTSC(FbxLongLong pTime, int& pHour, int& pMinute, int& pSecond, int& pFrame, int& pField);
+FBXSDK_DLL FbxLongLong FbxTCSetMNTSCnd(int pHour, int pMinute, int pSecond, FbxLongLong pFrame, int pField);
+FBXSDK_DLL FbxLongLong FbxTCGetMNTSCnd(FbxLongLong pTime, int& pHour, int& pMinute, int& pSecond, int& pFrame, int& pField);
+FBXSDK_DLL FbxLongLong FbxTCSetMNTSC_2Xnd(int pHour, int pMinute, int pSecond, FbxLongLong pFrame, int pField);
+FBXSDK_DLL FbxLongLong FbxTCGetMNTSC_2Xnd(FbxLongLong pTime, int& pHour, int& pMinute, int& pSecond, int& pFrame, int& pField);
+FBXSDK_DLL FbxLongLong FbxTCSetMNTSC(int pHour, int pMinute, int pSecond, FbxLongLong pFrame, int pField);
+FBXSDK_DLL FbxLongLong FbxTCGetMNTSC(FbxLongLong pTime, int& pHour, int& pMinute, int& pSecond, int& pFrame, int& pField);
+FBXSDK_DLL FbxLongLong FbxTCSetPAL(int pHour, int pMinute, int pSecond, FbxLongLong pFrame, int pField);
+FBXSDK_DLL FbxLongLong FbxTCGetPAL(FbxLongLong pTime, int& pHour, int& pMinute, int& pSecond, int& pFrame, int& pField);
+FBXSDK_DLL FbxLongLong FbxTCSetFILM(int pHour, int pMinute, int pSecond, FbxLongLong pFrame);
+FBXSDK_DLL FbxLongLong FbxTCGetFILM(FbxLongLong pTime, int& pHour, int& pMinute, int& pSecond, int& pFrame);
+FBXSDK_DLL FbxLongLong FbxTCSetFILMND(int pHour, int pMinute, int pSecond, FbxLongLong pFrame, int pField);
+FBXSDK_DLL FbxLongLong FbxTCGetFILMND(FbxLongLong pTime, int& pHour, int& pMinute, int& pSecond, int& pFrame, int& pField);
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* _FBXSDK_CORE_BASE_TIMECODE_H_ */

+ 168 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/base/fbxutils.h

@@ -0,0 +1,168 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxutils.h
+#ifndef _FBXSDK_CORE_BASE_UTILITIES_H_
+#define _FBXSDK_CORE_BASE_UTILITIES_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#include <fbxsdk/core/base/fbxstring.h>
+#include <fbxsdk/core/base/fbxstatus.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+#ifndef FBXSDK_ENV_WINSTORE
+	/** Retrieve the environment variable value.
+	* \return A new string containing the environment variable value. */
+	FBXSDK_DLL FbxString FbxGetEnv(const char* pEnvVar);
+
+	/** Get the application directory
+	* \return The application directory. */
+	FBXSDK_DLL FbxString FbxGetApplicationDirectory();
+#endif
+
+/** Retrieve the system temporary folder path name.
+* \return A new string containing the system temporary folder path name. */
+FBXSDK_DLL FbxString FbxGetSystemTempPath();
+
+/** Override the system temporary folder path name.
+* \param pPathUTF8 The system temporary folder to use for override. */
+FBXSDK_DLL void FbxSetSystemTempPath(const char* pPathUTF8);
+
+/** Retrieve the working directory of the system in UTF8 format.
+* \return A string that contain the current working directory of the system. */
+FBXSDK_DLL FbxString FbxGetCurrentWorkPath();
+
+/** Change the working directory of the system. */
+FBXSDK_DLL void FbxSetCurrentWorkPath(const char* pPath_UTF8);
+
+class FBXSDK_DLL FbxPathUtils
+{
+public:
+	/** Bind together a root path with a file path.
+	  * \param pRootPath The root path that will get binded to the file path.
+	  * \param pFilePath The file path to bind to the root path.
+	  * \param pCleanPath If true, the resulting path will be cleaned via FbxPathUtils::Clean().
+	  * \return Both paths binded together forming a new file path.
+	  * \remark If the file path is already a full valid path, pFilePath is returned.
+	  */
+	static FbxString Bind(const char* pRootPath, const char* pFilePath, bool pCleanPath=true);
+
+	/** Extract the folder name from the given file path.
+	  * \param pFilePath The given file path.
+	  * \return The folder name. If there isn't any '\\' or '/' in  the given file path, it will return pFilePath.
+	  */
+	static FbxString GetFolderName(const char* pFilePath);
+
+	/** Extract file name from the given file path.
+	  * \param pFilePath The given file path.
+	  * \param pWithExtension Decide the file name with extension or without extension.
+	  * If it is true, return the file name with extension;
+	  * if it is false, return the file name without extension.
+	  */
+	static FbxString GetFileName(const char* pFilePath, bool pWithExtension=true);
+
+	/** Extract the file extension in the given file path.
+	  * \param pFilePath The file path to extract the extension.
+	  * \return The file extension without the '.' character.
+	  * \remark Return empty string if the file path doesn't contain a valid extension.
+	  */
+	static FbxString GetExtensionName(const char* pFilePath);
+
+	/** Change or append a file extension to the specified file path.
+	  * \param pFilePath The file path to change the file extension
+	  * \param pExtension The extension to change or append to the file path.
+	  * \return The file path with the file extension changed/added.
+	  * \remark If the file path doesn't end with a valid file name, pFilePath is returned.
+	  */
+	static FbxString ChangeExtension(const char* pFilePath, const char* pExtension);
+
+	//! Test if the given path is relative path, if it is return true.
+	static bool IsRelative(const char* pPath);
+
+	/** Get the given new path's relative path to the given root path.
+	  * \param pRootPath The given root path
+	  * \param pNewPath The given new path. If it is only file name, the default directory is work directory.
+	  * \return The relative path.
+	  * \remarks If the given two paths have the same drive, the function will turn  '\\' in the relative path to  '/'.
+	  */
+	static FbxString GetRelativePath(const char* pRootPath, const char* pNewPath);
+
+	//! Get the given new path's relative path to the given root path.
+	static FbxString GetRelativeFilePath(const char* pRootPath, const char* pNewFilePath);
+
+	/** Get the full path of given path (if the given path is relative path,
+	  * it will take current directory as default root path.)
+	  */
+	static FbxString Resolve(const char* pRelPath);
+
+	//! Clean the redundant and useless denotations in given path name.
+	static FbxString Clean(const char* pPath);
+
+	/** Generate full safe file path name you can use to create new file.
+	  * \param pFolder The folder where the file name should be attempted to be created.
+	  * \param pPrefix The prefix of generated file name.
+	  * \return A valid file path that can safely be used to create a new file.
+	  */
+	static FbxString GenerateFileName(const char* pFolder, const char* pPrefix);
+
+	/** Verify if the specified folder path exist.
+	* \param pFolderPathUTF8 The folder path to test its existance.
+	* \return True if the folder path exist, false otherwise.
+	* \remark This function work for relative paths. It will search from the current work path. */
+	static bool Exist(const char* pFolderPathUTF8);
+
+	/** Create the specified folder path if it doesn't exist.
+	* \param pFolderPathUTF8 The folder path to create, in UTF8 encoding.
+	* \return True if folder path already exist, or if it was successfully created, false otherwise.
+	* \remark This function will create multiple folders if needed, and it also work for relative paths. */
+	static bool Create(const char* pFolderPathUTF8);
+
+	/** Delete the specified folder path and all its content recursively.
+	* \param pFolderPathUTF8 The folder path to delete, in UTF8 encoding.
+	* \return True if folder path was successfully deleted, false otherwise.
+	* \remark This function work for relative paths. It will search from the current work path. */
+	static bool Delete(const char* pFolderPathUTF8);
+
+#ifndef FBXSDK_ENV_WINSTORE
+	/** Verify if the folder contains items or not.
+	* \param pFolderPath_UTF8 The folder path to test if it contains items.
+	* \return True if the folder contain any kind of entry type. */
+	static bool IsEmpty(const char* pFolderPath_UTF8);
+#endif
+};
+
+/** Global accessor to an FbxStatus object.
+* This object is not used internally by the FBX SDK. It is provided for convenience and its usage is shown in the custom reader/writers samples. */
+class FBXSDK_DLL FbxStatusGlobal
+{
+public:
+	static FbxStatus& GetRef() 
+	{ 
+		if( !mStatusPtr )
+		{ 
+			mStatusPtr = FbxNew<FbxStatus>(); 
+		} 
+		return *mStatusPtr; 
+	}
+
+private:
+	FbxStatusGlobal(){ mStatusPtr = NULL; }
+	~FbxStatusGlobal(){ FbxDelete<FbxStatus>(mStatusPtr); }
+	static FbxStatusGlobal sgFbxStatusGlobal;
+	static FbxStatus* mStatusPtr;
+};
+
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* _FBXSDK_CORE_BASE_UTILITIES_H_ */

+ 166 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxclassid.h

@@ -0,0 +1,166 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxclassid.h
+#ifndef _FBXSDK_CORE_CLASSID_H_
+#define _FBXSDK_CORE_CLASSID_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+class FbxClassIdInfo;
+class FbxObject;
+class FbxPropertyHandle;
+class FbxManager;
+
+//! The function pointer type for object constructor functions.
+typedef FbxObject* (*FbxObjectCreateProc)(FbxManager& pManager, const char* pName, const FbxObject* pFrom);
+
+/** Internal class used to differentiate objects during run-time. Essentially, each class has an unique ClassId, that the
+* system can request in order to test if the class match the description. This class implement the necessary tools to be able
+* to perform hierarchic class testing. This means that a class B that inherits from the class A will answer yes to a "Is A"
+* query of type A or B, but will answer no to a class C that can still inherit from A. All class must inherit from FbxObject
+* before they can have their own ClassId. When using the standard macros to create new types of objects in the FBX SDK, a
+* static ClassId will automatically be generated for that new class.
+*
+* When objects are exported to an FBX file, their class type is maintained using 3 sort of strings. They are the Object Type
+* string, the Object Sub Type string and the Object Type Prefix. There is no good or bad way to choose the value of these
+* identifiers, but it is preferable to use meaningful values to keep the ASCII version of FBX readable and easy to understand.
+* \see FbxObject */
+class FBXSDK_DLL FbxClassId
+{
+public:
+	//! Constructor.
+	FbxClassId();
+
+	/** Advanced constructor were we can specify the general parameters for this ClassId.
+	* \param pClassName The name of the class represented.
+	* \param pParentClassId The parent ClassId of this class.
+	* \param pConstructor A function pointer to a construction method for this ClassId.
+	* \param pFBXType The FBX file Object Type string associated to this class.
+	* \param pFBXSubType The FBX file Object Sub Type string associated to this class. */
+	FbxClassId(const char* pClassName, const FbxClassId& pParentClassId, FbxObjectCreateProc pConstructor=0, const char* pFBXType=NULL, const char* pFBXSubType=NULL);
+
+	//! Destructor.
+	void Destroy();
+
+	/** Retrieve the class name.
+	* \return The class identification string name. */
+	const char* GetName() const;
+
+    /** Retrieve the parent ClassId.
+	* \return The parent ClassId. */
+	FbxClassId GetParent() const;
+
+	/** Create an instance of this class.
+	* \param pManager The FBX SDK Manager to be used to instantiate this object. This allow the object to use the same memory manager as the provided manager.
+	* \param pName The name to assign to this new object instance.
+	* \param pFrom An object to clone if it matches the same ClassId. This is an optional parameter.
+	* \return The newly created instance of this class. */
+	FbxObject* Create(FbxManager& pManager, const char* pName, const FbxObject* pFrom);
+
+	/** Override the function pointer method to construct this object.
+	* \param pConstructor A newly defined function pointer to a construction method to replace the existing one.
+	* \return True if the operation was successful. */
+	bool Override(FbxObjectCreateProc pConstructor);
+
+	/** Test if this class is a hierarchical children of the specified class type. This is the standard method to differentiate object classes.
+	* \param pId The class type to test against self.
+	* \return True if the object is a hierarchical children of the type specified.
+	* \remark This function will perform a complete search until it reaches the top level class, but it will stop as soon as one ClassId matches the test. */
+	bool Is(const FbxClassId& pId) const;
+
+	/** Equivalence operator.
+	* \param pClassId The class type to test against self.
+	* \return \c true if the ClassId is exactly the same, \c false otherwise.
+	* \remark This function only perform direct equality test, and doesn't test hierarchic children. */
+	bool operator==(const FbxClassId& pClassId) const;
+
+	/** Inequivalence operator.
+	* \param pClassId The class type to test against self.
+	* \return \c true if the ClassId is not the same, \c false otherwise.
+	* \remark This function only perform direct inequality test, and doesn't test hierarchic children. */
+	bool operator!=(const FbxClassId& pClassId) const;
+
+	/** Retrieve the FBX file Object Type string associated to this class.
+	* \param pAskParent If \c true, retrieve the parent ClassId, but only if self ClassId is not valid.
+	* \return The FBX file Object Type string associated to this class. */
+	const char* GetFbxFileTypeName(bool pAskParent=false) const;
+
+	/** Retrieve the FBX file Object Sub Type string associated to this class.
+	* \return The FBX file Object Sub Type string associated to this class. */
+	const char* GetFbxFileSubTypeName() const;
+
+	/** Find out if self ClassId is valid or not.
+	* \return \c true if self ClassId is valid, \c false otherwise. */
+	inline bool IsValid() const { return mClassInfo ? true : false; }
+    
+	/** Set the Object Type Prefix string associated to this class. This will change the "ObjectTypePrefix::" found in front
+	* of object name in the FBX file. This is useful to differentiate objects by their name without using the Object Type or
+	* Sub Type strings in the file.
+	* \param pObjectTypePrefix The Object Type prefix string. */
+	void SetObjectTypePrefix(const char* pObjectTypePrefix);
+
+	/** Retrieve the Object Type Prefix string associated to this class.
+	* \return The Object Type Prefix string. */
+	const char* GetObjectTypePrefix();
+   
+	/** Retrieve the root property handle of this class. This is useful to access the default property hierarchy for this
+	* class. This allow users to retrieve information such as the default value for all properties of this class.
+	* \return The root property handle for this class. */
+	FbxPropertyHandle* GetRootClassDefaultPropertyHandle();
+
+	/** Increase the instance reference count for this class type.
+	* \return the new count of reference to this class after increment. */
+	int ClassInstanceIncRef();
+
+	/** Decrease the instance reference count for this class type.
+	* \return the new count of reference to this class after decrement. */
+	int ClassInstanceDecRef();
+	 
+	/** Retrieve the instance reference count for this class type.
+	* \return The reference count of this class type. */
+	int GetInstanceRef();
+
+/*****************************************************************************************************************************
+** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
+*****************************************************************************************************************************/
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+	inline FbxClassIdInfo* GetClassIdInfo() { return mClassInfo; }
+    inline const FbxClassIdInfo* GetClassIdInfo() const { return mClassInfo; }
+
+private:
+	FbxClassId(FbxClassIdInfo* mClassInfo);
+
+	bool SetFbxFileTypeName(const char* pName);
+	bool SetFbxFileSubTypeName(const char* pName);
+
+	FbxClassIdInfo* mClassInfo;
+
+	friend class FbxManager;
+#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
+};
+
+//! Functor to compare FbxClassId
+struct FbxClassIdCompare
+{
+	inline int operator()(const FbxClassId& pKeyA, const FbxClassId& pKeyB) const
+	{
+		const FbxClassIdInfo* lKeyA = pKeyA.GetClassIdInfo();
+		const FbxClassIdInfo* lKeyB = pKeyB.GetClassIdInfo();
+		return lKeyA < lKeyB ? -1 : (lKeyA > lKeyB ? 1 : 0);
+	}
+};
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* _FBXSDK_CORE_CLASSID_H_ */

+ 312 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxconnectionpoint.h

@@ -0,0 +1,312 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxconnectionpoint.h
+#ifndef _FBXSDK_CORE_CONNECTION_POINT_H_
+#define _FBXSDK_CORE_CONNECTION_POINT_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#include <fbxsdk/core/base/fbxarray.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+class FBXSDK_DLL FbxConnection
+{
+public:
+	enum EType
+	{ 
+		eNone = 0,
+		// System or user
+		eSystem = 1 << 0,
+		eUser = 1 << 1,
+		eSystemOrUser = eUser | eSystem,
+		// Type of Link
+		eReference = 1 << 2,
+		eContains = 1 << 3,
+		eData = 1 << 4,
+		eLinkType = eReference | eContains | eData,
+		eDefault = eUser | eReference,
+		eUnidirectional = 1 << 7
+	};
+};
+
+class FbxConnectionPointFilter;
+
+class FBXSDK_DLL FbxConnectionPoint
+{
+public:
+	enum EDirection
+	{ 
+		eDirSrc = 1 << 0,	// Contains sources
+		eDirDst = 1 << 1,	// Contains destinations
+		eDirUni = 1 << 2,	// Connection is not 2 ways
+		eDirBoth = eDirSrc | eDirDst,
+		eDirMask = eDirSrc | eDirDst | eDirUni
+	};
+
+	enum EType
+	{
+		eStandard = 0,
+		eSubConnection = 1 << 3,		// Connect is a sub Connect of another
+		eTypeMask = eSubConnection
+	}; 
+
+	enum EAttribute
+	{
+		eDefault = 0,
+		eCache = 1 << 4,			
+		eAttributeMask = eCache
+	}; 
+
+	enum EAllocFlag
+	{
+		eNotAllocated = 0,
+		eAllocated = 1 << 5,
+		eAllocFlagMask = eAllocated
+	};
+
+	enum ECleanedFlag
+	{
+		eNotCleaned = 0,
+		eCleaned = 1 << 6,
+		eCleanedFlagMask = eCleaned
+	};
+
+	enum EEvent
+	{
+		eSrcConnectRequest,
+		eDstConnectRequest,
+		eSrcConnect,
+		eDstConnect,
+		eSrcConnected,
+		eDstConnected,
+		eSrcDisconnect,
+		eDstDisconnect,
+		eSrcDisconnected,
+		eDstDisconnected,
+		eSrcReplaceBegin,
+		eSrcReplaceEnd,
+		eDstReplaceBegin,
+		eDstReplaceEnd,
+		eSrcReorder,
+		eSrcReordered
+	};
+
+	// Constructor/Destructor	
+	FbxConnectionPoint(void* pData=0);
+	virtual ~FbxConnectionPoint();
+
+	void SetFilter(FbxConnectionPointFilter* pConnectFilter, EType pType=eStandard);
+	void InternalClear();
+
+	//! Clear the ConnectList without any regards to what is connected
+	void WipeConnectionList();
+	void Destroy();
+	void SubConnectRemoveAll();
+
+	inline FbxConnectionPoint*			GetSubOwnerConnect(){ return GetConnectType() == eSubConnection ? mOwner : NULL; }
+	inline FbxConnectionPointFilter*	GetFilter(){ return mFilter; }
+
+	virtual bool		IsInReplace(FbxConnectionPoint* p1, FbxConnectionPoint* p2);
+
+	inline void			SetConnectType(EType pType){ mFlags = (mFlags & ~eTypeMask) | pType; }
+	inline EType		GetConnectType(){ return EType(mFlags & eTypeMask); }
+	inline void			SetDirection(int pDirections){ mFlags = (mFlags & ~eDirMask) | pDirections; }
+	inline EDirection	GetDirection(){ return EDirection(mFlags & eDirMask); }
+	inline void			SetAttribute(int pAttributes){ mFlags = (mFlags & ~eAttributeMask) | pAttributes; }
+	inline EAttribute	GetAttribute(){ return EAttribute(mFlags & eAttributeMask); }
+	inline void			SetAllocatedFlag(bool pBool){ mFlags = ( pBool ) ? mFlags | eAllocated : mFlags & ~eAllocFlagMask; }
+	inline bool			GetAllocatedFlag(){ return ( mFlags & eAllocFlagMask ) ? true : false; }
+	inline void			SetCleanedFlag(bool pBool){ mFlags = ( pBool ) ? mFlags | eCleaned : mFlags & ~eCleanedFlagMask; }
+	inline bool			GetCleanedFlag(){ return ( mFlags & eCleanedFlagMask ) ? true : false; }		
+
+	bool				IsValidSrc(FbxConnectionPoint* pConnect);
+	bool				IsValidDst(FbxConnectionPoint* pConnect);
+	bool				IsValidSrcConnection(FbxConnectionPoint* pConnect, FbxConnection::EType pConnectionType);
+	bool				IsValidDstConnection(FbxConnectionPoint* pConnect, FbxConnection::EType pConnectionType);
+	bool				RequestValidSrcConnection(FbxConnectionPoint* pConnect, FbxConnection::EType pConnectionType );
+	bool				RequestValidDstConnection(FbxConnectionPoint* pConnect, FbxConnection::EType pConnectionType );
+
+	bool				ConnectSrc(FbxConnectionPoint* pSrc,FbxConnection::EType pConnectionType=FbxConnection::eNone);
+	bool				ConnectDst(FbxConnectionPoint* pDst,FbxConnection::EType pConnectionType=FbxConnection::eNone);
+	bool				ConnectSrcAt(int pDst_SrcIndex, FbxConnectionPoint* pSrc, FbxConnection::EType pConnectionType=FbxConnection::eNone);
+	bool				ConnectDstAt(int pSrc_DstIndex, FbxConnectionPoint* pDst, FbxConnection::EType pConnectionType=FbxConnection::eNone);
+	static bool			ConnectConnect(FbxConnectionPoint* pSrc,FbxConnectionPoint* pDst,FbxConnection::EType pConnectionType);
+	static bool			ConnectAt(FbxConnectionPoint* pSrc, int pSrc_DstIndex, FbxConnectionPoint* pDst, int pDst_SrcIndex, FbxConnection::EType pConnectionType);
+
+	bool				DisconnectDst(FbxConnectionPoint* pSrc);
+	bool				DisconnectSrc(FbxConnectionPoint* pSrc);
+	void				DisconnectAllSrc();
+	void				DisconnectAllDst();
+	static bool			DisconnectConnect(FbxConnectionPoint* pSrc,FbxConnectionPoint* pDst);
+	bool				DisconnectDstAt(int pIndex);
+	bool				DisconnectSrcAt(int pIndex);
+
+	bool				ReplaceInDst(FbxConnectionPoint* pDstOld, FbxConnectionPoint* pDstNew, int pIndexInNew);
+	bool				ReplaceInSrc(FbxConnectionPoint* pSrcOld, FbxConnectionPoint* pSrcNew, int pIndexInNew);
+	bool				ReplaceDstAt(int pIndex, FbxConnectionPoint* pDst);
+	bool				ReplaceSrcAt(int pIndex, FbxConnectionPoint* pSrc);
+	bool				SwapSrc(int pIndexA, int pIndexB);
+
+	/** Change the position of a source Connect.
+	* \param pIndex	Position of the Connect to move.
+	* \param pAtIndex	Position where to move the Connect.
+	* \return			\c True if the Connect was moved.
+	* \remarks After the move, the Connect will be precisely at position pAtIndex.
+	*/
+	bool MoveSrcAt(int pIndex, int pAtIndex);
+
+	/** Change the position of a source Connect.
+	* \param pSrc		Connect to move.
+	* \param pAtSrc	Connect at which position to move.
+	* \return			\c True if the Connect was moved.
+	* \remarks After the move, the Connect will be precisely at the position where pAtSrc was before the move.
+	*/
+	bool MoveSrcAt(FbxConnectionPoint* pSrc, FbxConnectionPoint* pAtSrc);
+
+	// Access services
+	bool IsConnectedSrc(FbxConnectionPoint*);
+	bool IsConnectedDst(FbxConnectionPoint*);
+	inline bool IsConnected(FbxConnectionPoint* pConnect) { return IsConnectedSrc(pConnect) || IsConnectedDst(pConnect); }
+
+	inline int					GetSrcCount() const { return mConnectionList.GetSrcCount(); }
+	inline FbxConnectionPoint*	GetSrc(int pIndex) const { return mConnectionList.GetSrc(pIndex);}
+	inline FbxConnection::EType	GetSrcType(int pIndex) const { return mConnectionList.GetSrcType(pIndex);}
+	inline int					GetDstCount() const { return mConnectionList.GetDstCount(); }
+	inline FbxConnectionPoint*	GetDst(int pIndex) const { return mConnectionList.GetDst(pIndex);}
+	inline FbxConnection::EType	GetDstType(int pIndex) const { return mConnectionList.GetDstType(pIndex);}
+
+	inline int					FindSrc(FbxConnectionPoint* pConnect){ return mConnectionList.FindSrc(pConnect); }
+	inline int					FindDst(FbxConnectionPoint* pConnect){ return mConnectionList.FindDst(pConnect); }
+
+	// Filtered versions	
+	inline int					GetSrcCount(FbxConnectionPointFilter* pFilter){ return (pFilter) ? SubConnectGetOrCreate(pFilter)->GetSrcCount() : GetSrcCount(); }
+	inline FbxConnectionPoint*	GetSrc(int pIndex,FbxConnectionPointFilter* pFilter){ return (pFilter) ? SubConnectGetOrCreate(pFilter)->GetSrc(pIndex) : GetSrc(pIndex); }
+	inline FbxConnection::EType	GetSrcType(int pIndex,FbxConnectionPointFilter* pFilter){ return (pFilter) ? SubConnectGetOrCreate(pFilter)->GetSrcType(pIndex) : GetSrcType(pIndex); }
+	inline int					GetDstCount(FbxConnectionPointFilter* pFilter){ return (pFilter) ? SubConnectGetOrCreate(pFilter)->GetDstCount() : GetDstCount(); }
+	inline FbxConnectionPoint*	GetDst(int pIndex,FbxConnectionPointFilter* pFilter){ return (pFilter) ? SubConnectGetOrCreate(pFilter)->GetDst(pIndex): GetDst(pIndex); }
+	inline FbxConnection::EType	GetDstType(int pIndex,FbxConnectionPointFilter* pFilter){ return (pFilter) ? SubConnectGetOrCreate(pFilter)->GetDstType(pIndex) : GetDstType(pIndex); }
+
+	void* GetData(){ return mData; }
+
+/*****************************************************************************************************************************
+** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
+*****************************************************************************************************************************/
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+protected:
+	class ConnectionList
+	{
+	public:
+		ConnectionList();
+		~ConnectionList();
+
+		void					Clear();
+
+		void					InsertSrcAt(int pIndex, FbxConnectionPoint* pConnect, FbxConnection::EType pType);
+		void					AddSrc(FbxConnectionPoint* pConnect, FbxConnection::EType pType);
+		void					RemoveSrcAt(int pIndex);
+		int						FindSrc(FbxConnectionPoint* pConnect) const;
+		int						GetSrcCount() const; 
+		FbxConnectionPoint*		GetSrc(int pIndex) const;
+		FbxConnection::EType	GetSrcType(int pIndex) const;
+
+		void					InsertDstAt(int pIndex, FbxConnectionPoint* pConnect, FbxConnection::EType pType);
+		void					AddDst(FbxConnectionPoint* pConnect, FbxConnection::EType pType);
+		void					RemoveDstAt(int pIndex);
+		int						FindDst(FbxConnectionPoint* pConnect) const;
+		int						GetDstCount() const;
+		FbxConnectionPoint*		GetDst(int pIndex) const;
+		FbxConnection::EType	GetDstType(int pIndex) const;
+
+	protected:
+		struct Connection {
+			Connection(FbxConnectionPoint* pPoint, FbxConnection::EType pType) : mPoint(pPoint), mType(pType){}
+			FbxConnectionPoint* mPoint; FbxConnection::EType mType;
+		};
+		FbxArray<Connection>	mSrcList;
+		FbxArray<Connection>	mDstList;
+	};
+
+	void				SubConnectAdd(FbxConnectionPoint* pConnect);
+	void				SubConnectRemove(FbxConnectionPoint* pConnect);
+	FbxConnectionPoint* SubConnectFind(FbxConnectionPointFilter* pFilter);
+	FbxConnectionPoint* SubConnectGetOrCreate(FbxConnectionPointFilter* pFilter);
+	void				SubConnectFill(FbxConnectionPoint*	pConnect);
+
+	virtual	bool		ConnectNotify(EEvent pAction, FbxConnectionPoint* pThis, int pIndex, FbxConnectionPoint* pConnect=NULL, FbxConnection::EType pConnectionType=FbxConnection::eNone, FbxConnectionPoint* pNewConnect=NULL);
+	virtual void		ConnectCleanUp(FbxConnectionPoint* pThis);
+
+	int					FindSrcIndexFromOwnerConnectIndex(FbxConnectionPoint* pOwner, int pOwnerIndex);
+	int					FindDstIndexFromOwnerConnectIndex(FbxConnectionPoint* pOwner, int pOwnerIndex);
+
+	bool				InternalMoveSrcBefore(int pIndex, int pBeforeIndex);
+
+private:
+	inline void			InsertSrcAt(int pIndex, FbxConnectionPoint* pConnect, FbxConnection::EType pConnectionType){ mConnectionList.InsertSrcAt(pIndex, pConnect, pConnectionType); }
+	inline void			InsertDstAt(int pIndex, FbxConnectionPoint* pConnect, FbxConnection::EType pConnectionType){ mConnectionList.InsertDstAt(pIndex, pConnect, pConnectionType); }
+	inline void			RemoveSrcAt(int pIndex){ mConnectionList.RemoveSrcAt(pIndex); }
+	inline void			RemoveDstAt(int pIndex){ mConnectionList.RemoveDstAt(pIndex); }    	
+
+	static bool			InternalConnectBefore(FbxConnectionPoint* pSrc, FbxConnectionPoint* pSrc_BeforeDst, FbxConnectionPoint* pDst, FbxConnectionPoint* pDst_BeforeSrc, FbxConnection::EType pConnectionType);
+	static bool			UserConnectBefore(FbxConnectionPoint* pSrc, FbxConnectionPoint* pSrc_BeforeDst, FbxConnectionPoint* pDst, FbxConnectionPoint* pDst_BeforeSrc, FbxConnection::EType pConnectionType);
+	static bool			EmitReplaceNotify(FbxConnectionPoint* pDstOwner, FbxConnectionPoint* pSrcOwner, FbxConnectionPoint* pDst, FbxConnectionPoint* pSrc, EEvent pConnectAction, FbxConnectionPoint* pNew);
+
+	virtual bool				SetOwnerConnect(FbxConnectionPoint* pConnect);
+	inline FbxConnectionPoint*	GetOwnerConnect(){ return mOwner;  }
+	bool						ConnectOwnedConnect(FbxConnectionPoint* pConnect);
+	bool						DisconnectOwnedConnect(FbxConnectionPoint* pConnect);
+
+	void*							mData;
+	int								mFlags;
+	FbxConnectionPoint*				mOwner;
+	ConnectionList					mConnectionList;
+	FbxArray<FbxConnectionPoint*>	mSubConnectList;
+	FbxArray<FbxConnectionPoint*>	mSubConnectCreatedList;		
+	FbxConnectionPointFilter*		mFilter;
+#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
+};
+
+/** Class to manage Connect Filter */
+class FBXSDK_DLL FbxConnectionPointFilter
+{
+public: 
+    virtual ~FbxConnectionPointFilter() {};
+    
+	//! Return reference ConnectionPoint filter.
+	virtual FbxConnectionPointFilter* Ref();
+
+	//! Cancel reference
+	virtual void Unref();
+
+	//! Get unique filter ID
+	virtual FbxInt GetUniqueId() const { return 0; }
+
+	/** Judge if the given Connection Point is valid
+	* \param pConnect The given Connection Point.
+	* \return \c True if valid, \c false if not valid. */
+	virtual bool IsValid(FbxConnectionPoint* pConnect) const;
+
+	/** Judge if the given Connection Point is a valid connection
+	* \param pConnect The given Connection Point.
+	* \param pType Connection type.
+	* \return \c True if valid, \c false if not valid. */
+	virtual bool IsValidConnection(FbxConnectionPoint* pConnect, FbxConnection::EType pType) const;
+
+	/** Judge if it is equal with the given  ConnectionPoint filter.
+	* \param pConnectFilter The given  ConnectionPoint filter.
+	* \return \c True if equal, \c false if unequal. */
+	virtual bool IsEqual(FbxConnectionPointFilter* pConnectFilter) const;
+};
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* _FBXSDK_CORE_CONNECTION_POINT_H_ */

+ 267 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxdatatypes.h

@@ -0,0 +1,267 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxdatatypes.h
+#ifndef _FBXSDK_CORE_DATA_TYPES_H_
+#define _FBXSDK_CORE_DATA_TYPES_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#include <fbxsdk/core/fbxpropertytypes.h>
+#include <fbxsdk/core/fbxpropertyhandle.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+/** FBX SDK data type class
+  * \nosubgrouping
+  */
+class FBXSDK_DLL FbxDataType
+{
+public:
+	static FbxDataType Create(const char* pName, const EFbxType pType);
+	static FbxDataType Create(const char* pName, const FbxDataType& pDataType);
+
+	/**
+	  *\name Constructor and Destructor.
+	  */
+	//@{
+		//! Constructor.
+		FbxDataType();
+
+		/** Copy constructor.
+		  * \param pDataType Another FbxDataType object copied to this one.
+		  */
+		FbxDataType(const FbxDataType& pDataType);
+
+		//! Destroy this datatype.
+		void Destroy();
+
+		/** Constructor.
+		  * \param pTypeInfoHandle Type information handle
+		  */
+		FbxDataType(const FbxPropertyHandle& pTypeInfoHandle);
+
+		//! Destructor.
+		~FbxDataType();
+	//@}
+
+	/** Assignment operator
+	  * \param pDataType Datatype whose value is assigned to this datatype.
+	  * \return This datatype
+	  */
+    inline FbxDataType& operator=(const FbxDataType& pDataType){ mTypeInfoHandle=pDataType.mTypeInfoHandle; return *this; }
+
+	/**
+	  * \name boolean operation
+	  */
+	//@{
+		/** Equality operator
+		  * \param pDataType Datatype to compare to.
+		  * \return \c true if equal,\c false otherwise.
+		  */
+		inline bool operator==(const FbxDataType& pDataType) const { return mTypeInfoHandle==pDataType.mTypeInfoHandle; }
+
+		/** Non-equality operator
+		  * \param pDataType Datatype to compare to.
+		  * \return \c true if unequal,\c false otherwise.
+		  */
+		inline bool operator!=(const FbxDataType& pDataType) const { return mTypeInfoHandle!=pDataType.mTypeInfoHandle; }
+	//@}
+
+	/** Test whether this datatype is a valid datatype.
+	  * \return \c true if valid, \c false otherwise.
+	  */
+	inline bool Valid() const { return mTypeInfoHandle.Valid(); }
+
+	/** Test if this datatype is the specified datatype. 
+	  * \param pDataType Datatype to compare to.
+	  * \return \c true if this datatype is the specified datatype, \c false otherwise. 
+	  */
+	inline bool Is(const FbxDataType& pDataType) const { return mTypeInfoHandle.Is(pDataType.mTypeInfoHandle); }
+
+	/** Retrieve this data type.
+	  * \return This data type.
+	  */
+	EFbxType GetType() const;
+
+	/** Retrieve data type name.
+	  * \return Data type name.
+	  */
+	const char* GetName() const;
+
+	/** Retrieve the information handle of this data type.
+	  * \return Information handle of this data type.
+	  */
+	inline const FbxPropertyHandle& GetTypeInfoHandle() const { return mTypeInfoHandle; }
+
+private:
+	FbxPropertyHandle mTypeInfoHandle;
+    friend class FbxManager;
+};
+
+/** Retrieve data type from type enumeration index
+  * \param pType The type enumeration index
+  * \return The corresponding data type
+  */
+FBXSDK_DLL const FbxDataType& FbxGetDataTypeFromEnum(const EFbxType pType);
+
+/** Retrieve data type name string used by I/O operations
+  * \param pDataType The data type instance to retrieve its I/O name string
+  * \return The data type name string
+  * \remark This function is only used during I/O operations. It is not equal
+  *         to the actual data type name.
+  */
+FBXSDK_DLL const char* FbxGetDataTypeNameForIO(const FbxDataType& pDataType);
+
+//! \name Basic Data Types
+//@{
+	extern FBXSDK_DLL FbxDataType FbxUndefinedDT;
+	extern FBXSDK_DLL FbxDataType FbxBoolDT;
+	extern FBXSDK_DLL FbxDataType FbxCharDT;
+	extern FBXSDK_DLL FbxDataType FbxUCharDT;
+	extern FBXSDK_DLL FbxDataType FbxShortDT;
+	extern FBXSDK_DLL FbxDataType FbxUShortDT;
+	extern FBXSDK_DLL FbxDataType FbxIntDT;
+	extern FBXSDK_DLL FbxDataType FbxUIntDT;
+	extern FBXSDK_DLL FbxDataType FbxLongLongDT;
+	extern FBXSDK_DLL FbxDataType FbxULongLongDT;
+	extern FBXSDK_DLL FbxDataType FbxFloatDT;
+	extern FBXSDK_DLL FbxDataType FbxHalfFloatDT;
+	extern FBXSDK_DLL FbxDataType FbxDoubleDT;
+	extern FBXSDK_DLL FbxDataType FbxDouble2DT;
+	extern FBXSDK_DLL FbxDataType FbxDouble3DT;
+	extern FBXSDK_DLL FbxDataType FbxDouble4DT;
+	extern FBXSDK_DLL FbxDataType FbxDouble4x4DT;
+	extern FBXSDK_DLL FbxDataType FbxEnumDT;
+	extern FBXSDK_DLL FbxDataType FbxStringDT;
+	extern FBXSDK_DLL FbxDataType FbxTimeDT;
+	extern FBXSDK_DLL FbxDataType FbxReferenceDT;
+	extern FBXSDK_DLL FbxDataType FbxBlobDT;
+	extern FBXSDK_DLL FbxDataType FbxDistanceDT;
+	extern FBXSDK_DLL FbxDataType FbxDateTimeDT;
+//@}
+
+//! \name Extended Data Types
+//@{
+	extern FBXSDK_DLL FbxDataType FbxColor3DT;
+	extern FBXSDK_DLL FbxDataType FbxColor4DT;
+	extern FBXSDK_DLL FbxDataType FbxCompoundDT;
+	extern FBXSDK_DLL FbxDataType FbxReferenceObjectDT;
+	extern FBXSDK_DLL FbxDataType FbxReferencePropertyDT;
+	extern FBXSDK_DLL FbxDataType FbxVisibilityDT;
+	extern FBXSDK_DLL FbxDataType FbxVisibilityInheritanceDT;
+	extern FBXSDK_DLL FbxDataType FbxUrlDT;
+	extern FBXSDK_DLL FbxDataType FbxXRefUrlDT;
+//@}
+
+//! \name Transform Data Types
+//@{
+	extern FBXSDK_DLL FbxDataType FbxTranslationDT;
+	extern FBXSDK_DLL FbxDataType FbxRotationDT;
+	extern FBXSDK_DLL FbxDataType FbxScalingDT;
+	extern FBXSDK_DLL FbxDataType FbxQuaternionDT;
+	extern FBXSDK_DLL FbxDataType FbxLocalTranslationDT;
+	extern FBXSDK_DLL FbxDataType FbxLocalRotationDT;
+	extern FBXSDK_DLL FbxDataType FbxLocalScalingDT;
+	extern FBXSDK_DLL FbxDataType FbxLocalQuaternionDT;
+	extern FBXSDK_DLL FbxDataType FbxTransformMatrixDT;
+	extern FBXSDK_DLL FbxDataType FbxTranslationMatrixDT;
+	extern FBXSDK_DLL FbxDataType FbxRotationMatrixDT;
+	extern FBXSDK_DLL FbxDataType FbxScalingMatrixDT;
+//@}
+
+//! \name Material Data Types
+//@{
+	extern FBXSDK_DLL FbxDataType FbxMaterialEmissiveDT;
+	extern FBXSDK_DLL FbxDataType FbxMaterialEmissiveFactorDT;
+	extern FBXSDK_DLL FbxDataType FbxMaterialAmbientDT;
+	extern FBXSDK_DLL FbxDataType FbxMaterialAmbientFactorDT;
+	extern FBXSDK_DLL FbxDataType FbxMaterialDiffuseDT;
+	extern FBXSDK_DLL FbxDataType FbxMaterialDiffuseFactorDT;
+	extern FBXSDK_DLL FbxDataType FbxMaterialBumpDT;
+	extern FBXSDK_DLL FbxDataType FbxMaterialNormalMapDT;
+	extern FBXSDK_DLL FbxDataType FbxMaterialTransparentColorDT;
+	extern FBXSDK_DLL FbxDataType FbxMaterialTransparencyFactorDT;
+	extern FBXSDK_DLL FbxDataType FbxMaterialSpecularDT;
+	extern FBXSDK_DLL FbxDataType FbxMaterialSpecularFactorDT;
+	extern FBXSDK_DLL FbxDataType FbxMaterialShininessDT;
+	extern FBXSDK_DLL FbxDataType FbxMaterialReflectionDT;
+	extern FBXSDK_DLL FbxDataType FbxMaterialReflectionFactorDT;
+	extern FBXSDK_DLL FbxDataType FbxMaterialDisplacementDT;
+	extern FBXSDK_DLL FbxDataType FbxMaterialVectorDisplacementDT;
+	extern FBXSDK_DLL FbxDataType FbxMaterialCommonFactorDT;
+	extern FBXSDK_DLL FbxDataType FbxMaterialCommonTextureDT;
+//@}
+
+//! \name Layer Element Data Types
+//@{
+	extern FBXSDK_DLL FbxDataType FbxLayerElementUndefinedDT;
+	extern FBXSDK_DLL FbxDataType FbxLayerElementNormalDT;
+	extern FBXSDK_DLL FbxDataType FbxLayerElementBinormalDT;
+	extern FBXSDK_DLL FbxDataType FbxLayerElementTangentDT;
+	extern FBXSDK_DLL FbxDataType FbxLayerElementMaterialDT;
+	extern FBXSDK_DLL FbxDataType FbxLayerElementTextureDT;
+	extern FBXSDK_DLL FbxDataType FbxLayerElementPolygonGroupDT;
+	extern FBXSDK_DLL FbxDataType FbxLayerElementUVDT;
+	extern FBXSDK_DLL FbxDataType FbxLayerElementVertexColorDT;
+	extern FBXSDK_DLL FbxDataType FbxLayerElementSmoothingDT;
+	extern FBXSDK_DLL FbxDataType FbxLayerElementCreaseDT;
+	extern FBXSDK_DLL FbxDataType FbxLayerElementHoleDT;
+	extern FBXSDK_DLL FbxDataType FbxLayerElementUserDataDT;
+	extern FBXSDK_DLL FbxDataType FbxLayerElementVisibilityDT;
+//@}
+
+//! \name I/O Specialized Data Types
+//@{
+	extern FBXSDK_DLL FbxDataType FbxAliasDT;
+	extern FBXSDK_DLL FbxDataType FbxPresetsDT;
+	extern FBXSDK_DLL FbxDataType FbxStatisticsDT;
+	extern FBXSDK_DLL FbxDataType FbxTextLineDT;
+	extern FBXSDK_DLL FbxDataType FbxUnitsDT;
+	extern FBXSDK_DLL FbxDataType FbxWarningDT;
+	extern FBXSDK_DLL FbxDataType FbxWebDT;
+//@}
+
+//! \name External Support Data Types
+//@{
+	extern FBXSDK_DLL FbxDataType FbxActionDT;
+	extern FBXSDK_DLL FbxDataType FbxCameraIndexDT;
+	extern FBXSDK_DLL FbxDataType FbxCharPtrDT;
+	extern FBXSDK_DLL FbxDataType FbxConeAngleDT;
+	extern FBXSDK_DLL FbxDataType FbxEventDT;
+	extern FBXSDK_DLL FbxDataType FbxFieldOfViewDT;
+	extern FBXSDK_DLL FbxDataType FbxFieldOfViewXDT;
+	extern FBXSDK_DLL FbxDataType FbxFieldOfViewYDT;
+	extern FBXSDK_DLL FbxDataType FbxFogDT;
+	extern FBXSDK_DLL FbxDataType FbxHSBDT;
+	extern FBXSDK_DLL FbxDataType FbxIKReachTranslationDT;
+	extern FBXSDK_DLL FbxDataType FbxIKReachRotationDT;
+	extern FBXSDK_DLL FbxDataType FbxIntensityDT;
+	extern FBXSDK_DLL FbxDataType FbxLookAtDT;
+	extern FBXSDK_DLL FbxDataType FbxOcclusionDT;
+	extern FBXSDK_DLL FbxDataType FbxOpticalCenterXDT;
+	extern FBXSDK_DLL FbxDataType FbxOpticalCenterYDT;
+	extern FBXSDK_DLL FbxDataType FbxOrientationDT;
+	extern FBXSDK_DLL FbxDataType FbxRealDT;
+	extern FBXSDK_DLL FbxDataType FbxRollDT;
+	extern FBXSDK_DLL FbxDataType FbxScalingUVDT;
+	extern FBXSDK_DLL FbxDataType FbxShapeDT;
+	extern FBXSDK_DLL FbxDataType FbxStringListDT;
+	extern FBXSDK_DLL FbxDataType FbxTextureRotationDT;
+	extern FBXSDK_DLL FbxDataType FbxTimeCodeDT;
+	extern FBXSDK_DLL FbxDataType FbxTimeWarpDT;
+	extern FBXSDK_DLL FbxDataType FbxTranslationUVDT;
+	extern FBXSDK_DLL FbxDataType FbxWeightDT;
+//@}
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* _FBXSDK_CORE_DATA_TYPES_H_ */

+ 94 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxemitter.h

@@ -0,0 +1,94 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxemitter.h
+#ifndef _FBXSDK_CORE_EMITTER_H_
+#define _FBXSDK_CORE_EMITTER_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#include <fbxsdk/core/base/fbxintrusivelist.h>
+#include <fbxsdk/core/fbxeventhandler.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+class FbxListener;
+
+/** Base class to emit event with the specified event type.
+* The event type could be a specific class which derived from FbxEvent. Please read FbxEmitter::Emit() for more details. 
+* Event emitter contains a list of event handlers.
+* FBX object could be used as emitter, since FbxObject is derived from FbxEmitter.
+* Before using emitter to emit an event, one or more event handlers must be added to the handlers list of current emitter.
+* In other words, it's "bind event handlers to emitter".
+* There are two ways to bind event handlers to emitter.
+* \li 1. If you already got an event handler and would like to bind it to current emitter, please call FbxEmitter::AddListener().
+* \li 2. Or you can create an event listener first and then call FbxListener::Bind().
+* It will create an event handler automatically and bind the handler to the specified emitter.
+* It's similar to unbind or remove an even handler. For more details, 
+* \see FbxEmitter::RemoveListener()
+* \see FbxListener::Unbind()
+* \remarks An object(emitter) can emit a certain type of event, the plug-in(listener) who are listening to that type of event, 
+* will receive a signal and take action to process the event data. 
+* \par The whole process of event is:
+* \li 1. Create an emitter and a listener, then bind them together via the same event handler.
+* \li 2. Emitter can emit an event at certain conditions. The event could be handled by event handler.
+* \li 3. Once an event is emitted, the listener to this event will receive a signal. 
+* \li 4. And then the listener could process the event data according to the types of event, by calling event handler.
+* \note The event data is process by the callback function of event handler.
+* \nosubgrouping
+* \see FbxListener FbxEventHandler FbxEvent FbxEventBase
+*/
+class FBXSDK_DLL FbxEmitter
+{
+public:
+	/** Add the specified event handler to current emitter list.
+	* \param pHandler The event handler will be added to the handlers list of current emitter. */
+	void AddListener(FbxEventHandler& pHandler);
+
+	/** Remove the specified event handler from current emitter list.
+	* \param pHandler The event handler will be removed from the handlers list of current emitter. */
+	void RemoveListener(FbxEventHandler& pHandler);
+
+	/** Emit an event with the specified the event type. One the event is emitted, the listener to this event will receive a signal.
+	* \param pEvent Specify the event type to emit. Could be a specific class which derived from FbxEvent, such as FbxObjectPropertyChanged.
+	* \see FbxEventBase FbxObjectPropertyChanged FbxEventReferencedDocument FbxEventPostExport
+	* \see FbxEventPostImport FbxEventPreExport FbxEventPreImport FbxEventPopulateSystemLibrary */
+	template <typename EventType> void Emit(const EventType& pEvent) const
+	{
+		if( !mData ) return;
+		EventHandlerList::iterator itBegin = mData->mEventHandlerList.Begin();
+		EventHandlerList::iterator itEnd = mData->mEventHandlerList.End();
+		for( EventHandlerList::iterator it = itBegin; it != itEnd; ++it )
+		{
+			if ((*it).GetHandlerEventType() == pEvent.GetTypeId())
+			{
+				(*it).FunctionCall(pEvent);
+			}
+		}
+	}
+
+/*****************************************************************************************************************************
+** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
+*****************************************************************************************************************************/
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+	FbxEmitter();
+	~FbxEmitter();
+
+protected:
+    typedef FbxIntrusiveList<FbxEventHandler, FbxEventHandler::eEmitter> EventHandlerList;
+    struct EventData { EventHandlerList mEventHandlerList; };
+    EventData* mData;
+#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
+};
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* _FBXSDK_CORE_EMITTER_H_ */

+ 188 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxevent.h

@@ -0,0 +1,188 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxevent.h
+#ifndef _FBXSDK_CORE_EVENT_H_
+#define _FBXSDK_CORE_EVENT_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#include <fbxsdk/core/fbxpropertytypes.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+/** FBX SDK event base class. 
+  * An event is something that is emitted by an emitter, with the goal of being filled by the listener that listen to it. 
+  * You can see that like a form that you send to some people. If those people know how to fill the form, they fill it and return
+  * it to you with the right information in it. FBX object could be used as emitter, since FbxObject is derived from FbxEmitter.
+  * Meanwhile, plug-in could be used as listener, since FbxPlugin is derived from FbxListener.
+  * The derived class of FbxEventBase contains a type ID to distinguish different types of events.
+  * FBX object can emit different types of FBX events at different conditions. 
+  * \par The whole process of event is:
+  * \li 1. Create an emitter and a listener, then bind them together via the same event handler.
+  * \li 2. Emitter can emit an event at certain conditions. The event could be handled by event handler.
+  * \li 3. Once an event is emitted, the listener to this event will receive a signal. 
+  * \li 4. And then the listener could process the event data according to the types of event, by calling event handler.
+  * \note The event data is process by the callback function of event handler.
+  * For example, if a certain property of a FBX object is changed, the FBX object(emitter) can emit an event which type is FbxObjectPropertyChanged.
+  * The plug-in(listener) who are listening to FbxObjectPropertyChanged, will receive a signal and take action to process the event data. 
+  * \nosubgrouping
+  * \see FbxEvent FbxEventHandler FbxListener FbxEmitter
+  */
+class FBXSDK_DLL FbxEventBase
+{
+  public:
+	 /**
+	   * \name Constructor and Destructor
+	   */
+     //@{
+	 //!Destructor
+     virtual ~FbxEventBase();
+	 //@}
+
+	 /** Retrieve the event type ID
+	   * \return            type id
+	   */
+     virtual int GetTypeId() const = 0;
+
+	 /** Force events to give us a name
+	   * \return            event name 
+	   */
+     virtual const char* GetEventName() const = 0;   
+
+	protected:
+     static int GetStaticTypeId(const char*);
+};
+
+// Force events to declare a name by using an abstract method, and force them to use 
+// the proper name by making the call from FbxEvent<> go through the private static
+// method.
+#define FBXSDK_EVENT_DECLARE(Class)												\
+	public: virtual const char* GetEventName() const { return FbxEventName(); }	\
+	private: static const char* FbxEventName() { return #Class; }				\
+	friend class FbxEvent<Class>;												\
+
+//
+// Similar to above, but to be used when you've got an event template, and the
+// type is something know to FBX
+//
+#define FBXSDK_EVENT_TYPE_DECLARE(Class, FBXType)                                  \
+  public: virtual const char* GetEventName() const { return FbxEventName(); }      \
+  private:                                                                         \
+     static const char* FbxEventName() {                                           \
+     static FbxString lEventName = FbxString(#Class) + FbxString("<") +                  \
+     FbxGetDataTypeFromEnum(FbxTypeOf(*((const FBXType *)0))).GetName() + ">";               \
+                                                                                   \
+     return lEventName.Buffer();                                                   \
+  }                                                                                \
+  friend class FbxEvent< Class<FBXType> >;
+
+
+
+//This is for templates classes that will uses non fbxtypes in their templates
+//We force the the creation of an UNIQUE string for each types so that we can
+//retrieve the event within multiple DLLs
+
+//to be able to use this, the char EventName[] = "uniqueEventName"; must be declared
+//globally.
+
+#define FBXSDK_EVENT_TEMPLATE_HEADER(ClassName, TemplateName)\
+template < class TemplateName, const char* T > \
+class ClassName: public  FbxEvent< ClassName <TemplateName,T> >\
+{\
+    public: virtual const char* GetEventName() const {return FbxEventName();}\
+    private: static const char* FbxEventName() {\
+    static FbxString lEventName = (FbxString(#ClassName) +"<"+ FbxString(T) +">");\
+    return lEventName.Buffer();\
+    }\
+    friend class FbxEvent< ClassName<TemplateName, T> >;
+
+
+//This is the footer macro, to put at the end to close the template class
+//created by FBXSDK_EVENT_TEMPLATE_HEADER
+#define FBXSDK_EVENT_TEMPLATE_FOOTER()\
+};
+
+/** FBX event class, derived from FbxEventBase, and it contains a type ID for event. 
+* It's a template class. You can derive your own types of even. Such as:
+* \code class FbxEventCustom : public FbxEvent<FbxEventCustom> \endcode
+* \see FbxObjectPropertyChanged FbxEventReferencedDocument FbxEventPostExport
+* \see FbxEventPostImport FbxEventPreExport FbxEventPreImport FbxEventPopulateSystemLibrary
+* \nosubgrouping
+* \remarks A FBX event is something that is emitted by an emitter, with the goal of being filled by the listener that listen to it. 
+* An object(emitter) can emit a certain type of event, the plug-in(listener) who are listening to that type of event, 
+* will receive a signal and take action to process the event data. 
+* \par The whole process of event is:
+* \li 1. Create an emitter and a listener, then bind them together via the same event handler.
+* \li 2. Emitter can emit an event at certain conditions. The event could be handled by event handler.
+* \li 3. Once an event is emitted, the listener to this event will receive a signal. 
+* \li 4. And then the listener could process the event data according to the types of event, by calling event handler.
+* \note The event data is process by the callback function of event handler.
+* \see FbxEventBase FbxEventHandler FbxListener FbxEmitter
+*/
+//---------------------------------------------------
+// T : We use the curiously recurring template pattern
+//          to initialize the typeId of each event type
+template<typename T> class FbxEvent : public FbxEventBase
+{
+public:
+    //!Destructor
+    virtual ~FbxEvent(){}
+
+    /** Update the type ID of current event with the given type ID.
+    * \param pTypeId     the new type ID.
+    */
+    static void ForceTypeId(int pTypeId)
+    {
+        // This is to handle specific cases where the type ID must be hard coded
+        // It is useful for shared event across DLL. We can then guarantee that
+        // The ID of a certain type will always have the same ID
+        smTypeId = pTypeId;
+    }
+
+    /** Retrieve the event type ID
+    * \note This may be called from multiple threads.
+    * \return            type id
+    */
+    virtual int GetTypeId() const 
+    {
+		return GetStaticTypeId();
+    }
+
+    /** Retrieve the event type ID
+    * \return            type id
+    */
+    static int GetStaticTypeId() 
+    {
+        if( !smTypeId )
+        {
+            if( !smTypeId )
+            {
+                // If this does not compile, you need to add 
+                // FBXSDK_EVENT_DECLARE(YourEventClassName) to your class declaration
+                smTypeId  = FbxEventBase::GetStaticTypeId(T::FbxEventName());
+            }
+        }
+
+       return smTypeId;
+    }
+
+private:
+    //! The type ID of event
+    static int smTypeId;
+};
+
+// Static members implementation
+template<typename T> int FbxEvent<T>::smTypeId = 0;
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* _FBXSDK_CORE_EVENT_H_ */

+ 129 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxeventhandler.h

@@ -0,0 +1,129 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxeventhandler.h
+#ifndef _FBXSDK_CORE_EVENT_HANDLER_H_
+#define _FBXSDK_CORE_EVENT_HANDLER_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#include <fbxsdk/core/fbxevent.h>
+#include <fbxsdk/core/base/fbxintrusivelist.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+class FbxListener;
+
+/** Event handler class contains a listener and a callback function.
+* Event handler is used to bind emitter and listener together. Its callback function can process event data.
+* To generate a valid event handler, you can create an event emitter and event listener first and then call FbxListener::Bind().
+* It will create an event handler automatically and bind the handler to the listener and the created emitter. 
+* After that, the emitter and listener are bound together via event handler.
+* \remarks An object(emitter) can emit a certain type of event, the object(listener) who are listening to that type of event, 
+* will receive a signal and take action to process the event data. 
+* \par The whole process of event is:
+* \li 1. Create an emitter and a listener, then bind them together via the same event handler.
+* \li 2. Emitter can emit an event at certain conditions. The event could be handled by event handler.
+* \li 3. Once an event is emitted, the listener to this event will receive a signal. 
+* \li 4. And then the listener could process the event data according to the types of event, by calling event handler.
+* \note The event data is process by the callback function of event handler.
+* \nosubgrouping
+* \see FbxListener FbxEventBase FbxEvent FbxEmitter
+*/
+class FbxEventHandler
+{
+public:
+	//! Event handler base type.
+	enum EType
+	{
+		eListener,	//!< Listener event handler type.
+		eEmitter,	//!< Emitter event handler type.
+		eCount		//!< Count of different event handler types.
+	};
+
+	/** Get event type of current handler.
+	* \return The type ID of event. */
+	virtual int GetHandlerEventType()=0;
+
+	/** Call function that process event data.
+	* \param pEvent specify the event type. pEvent could be a specific class which derived from FbxEventBase.
+	* \see FbxEventBase */
+	virtual void FunctionCall(const FbxEventBase& pEvent)=0;
+
+	/** Get listener of current handler.
+	* \return A pointer to the listener object. */
+	virtual FbxListener* GetListener()=0;
+
+/*****************************************************************************************************************************
+** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
+*****************************************************************************************************************************/
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+    FbxEventHandler(){}
+    virtual ~FbxEventHandler(){}
+
+	FBXSDK_INTRUSIVE_LIST_NODE(FbxEventHandler, eCount);
+#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
+};
+
+/*****************************************************************************************************************************
+** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
+*****************************************************************************************************************************/
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+template <typename EventType, typename ListenerType> class FbxMemberFuncEventHandler : public FbxEventHandler
+{
+	typedef void (ListenerType::*CallbackFnc)(const EventType*);
+
+public:
+    FbxMemberFuncEventHandler(ListenerType* pListenerInstance, CallbackFnc pFunction) : mListener(pListenerInstance), mFunction(pFunction){}
+	virtual int GetHandlerEventType(){ return EventType::GetStaticTypeId(); }  
+	virtual void FunctionCall(const FbxEventBase& pEvent){ (*mListener.*mFunction)(reinterpret_cast<const EventType*>(&pEvent)); } 
+	virtual FbxListener* GetListener(){ return mListener; }
+
+private:
+	ListenerType*	mListener;
+	CallbackFnc		mFunction;
+};
+
+template <typename EventType, typename ListenerType> class FbxConstMemberFuncEventHandler : public FbxEventHandler
+{
+	typedef void (ListenerType::*CallbackFnc)(const EventType*) const;
+
+public:
+	FbxConstMemberFuncEventHandler(ListenerType* pListenerInstance, CallbackFnc pFunction) : mListener(pListenerInstance), mFunction(pFunction){}
+	virtual int GetHandlerEventType(){ return EventType::GetStaticTypeId(); }    
+	virtual void FunctionCall(const FbxEventBase& pEvent){ (*mListener.*mFunction)(reinterpret_cast<const EventType*>(&pEvent)); }
+	virtual FbxListener* GetListener(){ return mListener; }
+
+private:
+	ListenerType*	mListener;
+	CallbackFnc		mFunction;
+};
+
+template <typename EventType> class FbxFuncEventHandler : public FbxEventHandler
+{
+	typedef void (*CallbackFnc)(const EventType*, FbxListener*);
+
+public:
+	FbxFuncEventHandler(FbxListener* pListener, CallbackFnc pFunction) : mListener(pListener), mFunction(pFunction){}
+	virtual int GetHandlerEventType(){ return EventType::GetStaticTypeId(); }   
+	virtual void FunctionCall(const FbxEventBase& pEvent){ (*mFunction)(reinterpret_cast<const EventType*>(&pEvent), mListener); }
+	virtual FbxListener* GetListener(){ return mListener; }
+
+private:
+	FbxListener*	mListener;
+	CallbackFnc		mFunction;
+};
+#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* _FBXSDK_CORE_EVENT_HANDLER_H_ */

+ 121 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxlistener.h

@@ -0,0 +1,121 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxlistener.h
+#ifndef _FBXSDK_CORE_LISTENER_H_
+#define _FBXSDK_CORE_LISTENER_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#include <fbxsdk/core/fbxemitter.h>
+#include <fbxsdk/core/fbxeventhandler.h>
+#include <fbxsdk/core/base/fbxintrusivelist.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+/**FBX SDK listener class. Once an event is emitted by an emitter, a listener should be created to listen to the event. 
+  * The listener could receive a signal and take action to process the event data. 
+  * \note The data will be process by the callback function of FbxListener::Bind().
+  * Plug-in could be used as listener, since FbxPlugin is derived from FbxListener.
+  * To emit event, you could create an emitter and a listener, and then bind them together via event handler.
+  * To listen to an event which is emitted by an emitter, you should bind current listener to the emitter by calling FbxListener::Bind(). 
+  * Event listener contains a list of event handlers.
+  * \remarks An object(emitter) can emit a certain type of event, the plug-in(listener) who are listening to that type of event, 
+  * will receive a signal and take action to process the event data. 
+  * \par The whole process of event is:
+  * \li 1. Create an emitter and a listener, then bind them together via the same event handler.
+  * \li 2. Emitter can emit an event at certain conditions. The event could be handled by event handler.
+  * \li 3. Once an event is emitted, the listener to this event will receive a signal. 
+  * \li 4. And then the listener could process the event data according to the types of event, by calling event handler.
+  * \note The event data is process by the callback function of event handler.
+  * \see FbxEmitter FbxEventHandler FbxEvent FbxEventBase
+  */
+class FBXSDK_DLL FbxListener
+{
+public:
+	/**
+	  * \name Constructor and Destructor
+	  */
+	//@{
+	//!Destructor.
+    ~FbxListener();
+	//!Constructor.
+    FbxListener(){}
+	//@}
+   
+	////////////////////////////////////////////////////////////////////////////////////////
+    /**
+    * \name Bind and unbind methods
+    */
+    //@{
+
+    /**Bind current listener and the specified emitter together via an automatically created event handler. 
+     * An event handler will be created automatically and added to the handlers list of current listener and the specified emitter.
+     * After that, the listener can listen to the event which is emitted by the specified emitter.
+	 * \param pEmitter          Event emitter to bind. Current listener can listen to the event which is emitted by pEmitter.
+	 * \param pFunc             The callback function to process event date.
+	 * \return                  The automatically created event handler.
+	 */
+    template <typename EventType,typename ListenerType> FbxEventHandler* Bind(FbxEmitter& pEmitter, void (ListenerType::*pFunc)(const EventType*))
+    {
+        FbxMemberFuncEventHandler<EventType,ListenerType>* eventHandler = 
+            FbxNew< FbxMemberFuncEventHandler<EventType,ListenerType> >(static_cast<ListenerType*>(this),pFunc);
+        pEmitter.AddListener(*eventHandler);
+        mEventHandler.PushBack(*eventHandler);
+        return eventHandler;
+    }
+
+    /**Bind current listener and the specified emitter together via an automatically created event handler. 
+    * An event handler will be created automatically and added to the handlers list of current listener and the specified emitter.
+    * After that, the listener can listen to the event which is emitted by the specified emitter.
+    * \param pEmitter          Event emitter to bind. Current listener can listen to the event which is emitted by pEmitter.
+    * \param pFunc             The callback function to process event date.
+    * \return                  The automatically created event handler.
+    */
+    template <typename EventType,typename ListenerType> FbxEventHandler* Bind(FbxEmitter& pEmitter, void (ListenerType::*pFunc)(const EventType*)const)
+    {
+        FbxConstMemberFuncEventHandler<EventType,ListenerType>* eventHandler = 
+                    FbxNew< FbxConstMemberFuncEventHandler<EventType,ListenerType> >(static_cast<ListenerType*>(this),pFunc);
+        pEmitter.AddListener(*eventHandler);
+        mEventHandler.PushBack(*eventHandler);
+        return eventHandler;
+    }
+
+    /**Bind current listener and the specified emitter together via an automatically created event handler. 
+    * An event handler will be created automatically and added to the handlers list of current listener and the specified emitter.
+    * After that, the listener can listen to the event which is emitted by the specified emitter.
+    * \param pEmitter          Event emitter to bind. Current listener can listen to the event which is emitted by pEmitter.
+    * \param pFunc             The callback function to process event date.
+    * \return                  The automatically created event handler.
+    */
+    template <typename EventType> FbxEventHandler* Bind(FbxEmitter& pEmitter, void (*pFunc)(const EventType*,FbxListener*))
+    {
+        FbxFuncEventHandler<EventType>* eventHandler = 
+                        FbxNew< FbxFuncEventHandler<EventType> >(this, pFunc);
+        pEmitter.AddListener(*eventHandler);
+        mEventHandler.PushBack(*eventHandler);
+        return eventHandler;
+    }
+    
+	/**Unbind an event handler. The specified event handler will be removed from the handlers list of current listener. 
+	  * \param aBindId       The event handler to unbind.
+	  */
+    void Unbind(const FbxEventHandler* aBindId);
+	//@}
+
+private:
+    typedef FbxIntrusiveList<FbxEventHandler, FbxEventHandler::eListener> EventHandlerList;
+    EventHandlerList mEventHandler;
+};
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* _FBXSDK_CORE_LISTENER_H_ */

+ 86 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxloadingstrategy.h

@@ -0,0 +1,86 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxloadingstrategy.h
+#ifndef _FBXSDK_CORE_LOADING_STRATEGY_H_
+#define _FBXSDK_CORE_LOADING_STRATEGY_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#ifndef FBXSDK_ENV_WINSTORE
+
+#include <fbxsdk/core/fbxplugin.h>
+#include <fbxsdk/core/fbxplugincontainer.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+/** 
+ * Abstract class used to implemented some plug-in loading strategy.
+ * A loading strategy dictate how some plug-ins will be loaded for instance.
+ * We could have a simple strategy that loads only a single dll on PC. 
+ * We could also implement a strategy that load multiple dlls from a directory.
+ */
+class FBXSDK_DLL FbxLoadingStrategy : public FbxPluginContainer
+{
+public:
+    /** Result state of loading plug-in.
+     */
+    enum EState
+	{
+        eAllLoaded,     //!< All plug-in are loaded.
+        eNoneLoaded,    //!< No plug-in is loaded, i.e., there is not plug-in to load. 
+        eAllFailed,     //!< All plug-in are failed to load.
+        eSomeFailed     //!< Some plug-ins are loaded but some are failed.
+    };
+
+    /**
+    *\name Public interface
+    */
+    //@{
+		/** Execute the operation of loading the plug-in(s). The way it is executed is determined by the specific implementations.
+		* \param pData  Plug in data that can be access inside the plug-ins.
+		* \return If the plugin loading is successful return \c true, otherwise return \c false.
+		*/
+		EState Load(FbxPluginData& pData);
+
+		/** Execute the operation of unloading the plug-in(s). The way it is executed is determined by the specific implementations.
+		*/
+		void Unload();
+    //@}
+
+protected:
+    /**
+    *\name User implementation
+    */
+    //@{
+		/** Called by the Load method, it contains the specific user implementation strategy to load the desired plug-in(s).
+		* \param pData  Plug in data that can be access inside the plug-ins.
+		* \return If the plugin loading is successful return \c true, otherwise return \c false
+		*/
+		virtual bool SpecificLoad(FbxPluginData& pData) = 0;
+
+		/** Called by the Unload method, it contains the specific user implementation strategy to unload the desired plug-in(s).
+		*/
+		virtual void SpecificUnload(FbxPluginData& pData) = 0;
+    //@}
+
+    //! Whether the plugin is loaded or not.
+    EState mPluginsLoadedState;
+
+private:
+    FbxPluginData mData;
+};
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* !FBXSDK_ENV_WINSTORE */
+
+#endif /* _FBXSDK_CORE_LOADING_STRATEGY_H_ */

+ 555 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxmanager.h

@@ -0,0 +1,555 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxmanager.h
+#ifndef _FBXSDK_CORE_MANAGER_H_
+#define _FBXSDK_CORE_MANAGER_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#include <fbxsdk/core/fbxobject.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+class FbxIOSettings;
+class FbxIOPluginRegistry;
+class FbxAnimEvaluator;
+class FbxSceneReference;
+class FbxUserNotification;
+class FbxMessageEmitter;
+class FbxLocalizationManager;
+class FbxXRefManager;
+class FbxManager_internal;
+
+#ifndef FBXSDK_ENV_WINSTORE
+	class FbxPlugin;
+#endif
+
+/** SDK object manager.
+  *   The SDK manager is in charge of:
+  *     \li scene element allocation, for example, FbxScene::Create(pSdkManager, "").
+  *     \li scene element deallocation, call FbxManager::Destroy() to deallocates all object created by the SDK manager.
+  *     \li scene element search and access, please see \ref GlobalObjectManagement section.
+  *
+  * It is possible to override memory allocation functions throughout the FBX SDK by
+  * providing system memory allocation functions using the handler set functions below.
+  * It must be done before the first FbxManager creation.
+  *
+  *	FbxSetMallocHandler();
+  * FbxSetCallocHandler();
+  * FbxSetReallocHandler();
+  * FbxSetFreeHandler();
+  *
+  * Upon destruction, all objects allocated by the SDK manager and not explicitly destroyed are destroyed as well. 
+  * A derived class can be defined to allocate and deallocate specialized scene elements.
+  * \remarks You could create more than one SDK manager. However, it's better to NOT share the same object among different managers.
+  * \nosubgrouping
+  */
+class FBXSDK_DLL FbxManager
+{
+public:
+	/**
+	  * \name FBX SDK Manager Creation/Destruction
+	  */
+	//@{
+		/** SDK manager allocation method.
+		  * \return A pointer to the SDK manager or \c NULL if this is an
+		  * evaluation copy of the FBX SDK and it is expired.
+		  */
+		static FbxManager* Create();
+
+		/** Destructor.
+		  * Deallocates all object previously created by the SDK manager.
+		  */
+		virtual void Destroy();
+	//@}
+
+	/**
+	  * \name Versions Queries
+	  */
+	//@{
+		/** Get FBX SDK version string.
+		  * \param pFull	If true, the complete version string including revision number and release date will be returned,
+		  *					otherwise only the version numbering is returned.
+		  */
+		static const char* GetVersion(bool pFull=true);
+
+		/** Get the current default FBX file format version number for this version of the FBX SDK.
+		  * \param pMajor        Version major number.
+		  * \param pMinor        Version minor number.
+		  * \param pRevision     Version revision number.
+		  */
+		static void GetFileFormatVersion(int& pMajor, int& pMinor, int& pRevision);
+	//@}
+
+
+	/**
+	  * \name Object Registration, Definition and Management
+	  */
+	//@{
+		/** Class registration.
+		  * \param pName				The class name. For example, "FbxMesh" for FbxMesh class.
+		  * \param T1					FBX type of the specified class.
+		  * \param T2					FBX type of parent class.
+		  * \param pFbxFileTypeName     The type name of the class in FBX file.
+		  * \param pFbxFileSubTypeName  The sub type name of the class in FBX file.
+		  * \return The class Id of the newly register class.
+		  * Such as:
+		  * \code RegisterFbxClass("FbxCamera", FBX_TYPE(FbxCamera), FBX_TYPE(FbxNodeAttribute)); \endcode
+		  */
+		template <typename T1, typename T2> inline FbxClassId RegisterFbxClass(const char* pName, const T1* /*T1*/, const T2* /*T2*/, const char* pFbxFileTypeName=0, const char* pFbxFileSubTypeName=0)
+		{
+			T1::ClassId = Internal_RegisterFbxClass(pName, T2::ClassId, (FbxObjectCreateProc)T1::Allocate, pFbxFileTypeName, pFbxFileSubTypeName);
+			return T1::ClassId;
+		}
+	 
+		/** Runtime class registration.
+		  * \param pName                    The class name. For example, "FbxUIWidgetBoolean".
+		  * \param T						FBX type of parent class.
+		  * \param pFbxFileTypeName         The type name of the class in FBX file.
+		  * \param pFbxFileSubTypeName      The sub type name of the class in FBX file.
+		  * \return The class Id of the newly register class.
+		  * Such as:
+		  * \code RegisterRuntimeFbxClass( "FbxUIWidgetBoolean", FBX_TYPE(FbxUIWidgetDefinition), NULL, "FbxUIWidgetBoolean"); \endcode
+		  */
+		template <typename T> inline FbxClassId RegisterRuntimeFbxClass(const char* pName, const T* /*T*/, const char* pFbxFileTypeName=0,const char* pFbxFileSubTypeName=0)
+		{
+			return Internal_RegisterFbxClass(pName, T::ClassId, (FbxObjectCreateProc)T::Allocate, pFbxFileTypeName, pFbxFileSubTypeName);
+		}
+	    
+		/** Runtime class unregistration.
+		  * \param pName The class name.
+		  */
+		inline void UnregisterRuntimeFbxClass(const char* pName)
+		{
+			FbxClassId lClassId = FindClass(pName);
+			if( !(lClassId == FbxClassId()) )
+			{
+				Internal_UnregisterFbxClass(lClassId);
+			}
+		}
+	    
+		/** Override class.
+		  * \param pFBX_TYPE_Class      FBX type of class.
+		  * \param pFBX_TYPE_OverridenClass FBX type of overridden class.
+		  * \return The class Id
+		  */
+		template <typename T1,typename T2> inline FbxClassId OverrideFbxClass(const T1* pFBX_TYPE_Class, const T2* pFBX_TYPE_OverridenClass)
+		{
+			T1::ClassId  = Internal_OverrideFbxClass(T2::ClassId,(FbxObjectCreateProc)T1::Allocate );
+			return T1::ClassId;
+		}
+
+		/** Create a new object of the specified ClassId.
+		  * \param pClassId		The ClassId of the object to be created.
+		  * \param pName		The name given to the newly created object.
+		  * \param pContainer	An optional parameter to specify which object will "contain" the new object. By contain, we mean
+		  *						the new object will become a source to the container, connection-wise.
+		  * \param pCloneFrom	A valid object pointer to use as the reference for cloning the object upon construction.
+		  * \return				If not null, a new instance of the specified class.
+		  * \remark				This function will return NULL if the ClassId used is invalid. New ClassId can be registered using
+		  *						the function RegisterFbxClass().
+		  */
+		FbxObject* CreateNewObjectFromClassId(FbxClassId pClassId, const char* pName, FbxObject* pContainer=NULL, const FbxObject* pCloneFrom=NULL);
+
+		/** Find class by the specified name.
+		  * \param pClassName Class Name to find.
+		  */
+		FbxClassId FindClass(const char* pClassName) const;
+
+		/** Find file class.
+		  * \param pFbxFileTypeName     Specify the type name in FBX file to find.
+		  * \param pFbxFileSubTypeName  Specify by The sub type name in FBX file to find.
+		  */
+		FbxClassId FindFbxFileClass(const char* pFbxFileTypeName, const char* pFbxFileSubTypeName) const;
+
+		/** Class unregistration.
+		  * \param pFBX_TYPE_Class  FBX type of unregistered class.
+		  */
+		template <typename T> inline void UnregisterFbxClass(const T* pFBX_TYPE_Class)
+		{
+			Internal_UnregisterFbxClass(T::ClassId);
+			T::ClassId = FbxClassId();
+		}
+	//@}
+
+	/**
+	  * \name Data Type Management
+	  */
+	//@{
+		/** Register a new data type to the manager
+		 *  \param pName The type name.
+		 *  \param pType The data type.
+		 *  \return The newly created FbxDataType
+		 */
+		FbxDataType CreateDataType(const char* pName, const EFbxType pType);
+
+		/** List the data types
+		 *  \return the number of registered datatypes
+		 */
+		int GetDataTypeCount() const;
+
+		/** Find a data types at pIndex.
+		 *  \param pIndex The data type index.
+		 *  \return the found datatype. return null if not found
+		 */
+		FbxDataType& GetDataType(const int pIndex) const;
+
+		/** Find a data type from the type name.
+		 *  \param pDataType The type name.
+		 *  \return the found datatype. return null if not found
+		 */
+		FbxDataType& GetDataTypeFromName(const char* pDataType) const;
+	//@}
+
+	/**
+	  * \name User Notification Object
+	  */
+	//@{
+		/** Access to the unique UserNotification object.
+		  * \return The pointer to the user notification or \c NULL \c if the object
+		  * has not been allocated.
+		*/
+		FbxUserNotification* GetUserNotification() const;
+
+		/** Set the user notification
+		  * \param pUN  
+		  */
+		void SetUserNotification(FbxUserNotification* pUN);
+	//@}
+
+	/**
+	  * \name IOSettings Object
+	  */
+	//@{
+		/** Access to a IOSettings object.
+		  * \return The pointer to IOSettings or \c NULL \c if the object
+		  * has not been allocated.
+		*/
+		virtual FbxIOSettings* GetIOSettings() const;
+
+		/** Set the IOSettings pointer
+		  * \param pIOSettings  
+		  */
+		virtual void SetIOSettings(FbxIOSettings* pIOSettings);
+	//@}
+
+
+	/**
+	  * \name Message Emitter (for Message Logging)
+	  */
+	//@{
+		/** Access to the unique FbxMessageEmitter object.
+		  * \return The pointer to the message emitter.
+		*/
+		FbxMessageEmitter& GetMessageEmitter();
+		/** Sets to the unique FbxMessageEmitter object.
+		  * \param pMessageEmitter the emitter to use, passing NULL will reset to the default emitter.
+		  * The object will be deleted when the SDK manager is destroyed, thus ownership is transfered.
+		*/
+		bool SetMessageEmitter(FbxMessageEmitter* pMessageEmitter);
+	//@}
+
+        
+	/**
+	  * \name Localization Hierarchy
+	  */
+	//@{
+		/** Add a localization object to the known localization providers.
+		  * \param pLocManager the localization object to register.
+		*/
+		void AddLocalization(FbxLocalizationManager* pLocManager);
+
+		/** Remove a localization object from the known localization providers.
+		  * \param pLocManager the localization object to remove.
+		*/
+		void RemoveLocalization(FbxLocalizationManager* pLocManager);
+
+		/** Select the current locale for localization.
+		  * \param pLocale the locale name, for example "fr" or "en-US".
+		*/
+		bool SetLocale(const char* pLocale);
+
+		/** Localization helper function. Calls each registered localization manager
+		  * until one can localizes the text.
+		  * \param pID the identifier for the text to localize.
+		  * \param pDefault the default text. Uses pID if NULL.
+		  * \return the potentially localized text. May return the parameter passed in.
+		*/
+		const char* Localize(const char* pID, const char* pDefault=NULL) const;
+	//@}
+
+	/**
+	  * \name XRef Manager
+	  */
+	//@{
+		/** Retrieve the manager responsible for managing object XRef resolution.
+		  * \return The XRef manager for this SDK manager.
+		  */
+		FbxXRefManager& GetXRefManager();
+	//@}
+
+	/**
+	  * \name Library Management
+	  */
+	//@{
+		/** Retrieve the main object Libraries
+		  * \return The Root library
+		  */
+		FbxLibrary* GetRootLibrary() const;
+		FbxLibrary* GetSystemLibraries() const;
+		FbxLibrary* GetUserLibraries() const;
+	//@}
+
+	/**
+	  * \name Plug-in Registry Object
+	  */
+	//@{
+		/** Access to the unique FbxIOPluginRegistry object.
+		  * \return The pointer to the user FbxIOPluginRegistry
+		*/
+		FbxIOPluginRegistry* GetIOPluginRegistry() const;
+	//@}
+
+	/**
+	  * \name Fbx Generic Plugins Management
+	  */
+	//@{
+	#ifndef FBXSDK_ENV_WINSTORE
+		/** Load plug-ins directory
+		  * \param pFilename The directory path.
+		  * \param pExtensions The plug in extension.
+		  * \return \c True
+		  */
+		bool LoadPluginsDirectory(const char* pFilename, const char* pExtensions=NULL);
+
+		/** Load plug-in
+		  * \param pFilename The file name
+		  * \return \c True
+		  */
+		bool LoadPlugin(const char* pFilename);
+
+		/** Unload all plug-ins
+		*/
+		bool UnloadPlugins();
+
+		/** Emit plugins event.
+		  * \param pEvent The event to be emitted.
+		  */
+		bool EmitPluginsEvent(const FbxEventBase& pEvent);
+	   
+		//!Get plugins.
+		FbxArray<const FbxPlugin*> GetPlugins() const;
+
+		/** get plugins count
+		  * \return The number of plugins.
+		  */
+		int GetPluginCount() const;
+
+		/** Find plug in.
+		  * \param pName The plug in name.
+		  * \param pVersion The plug in version.
+		  * \return The plugin, \c null if not found.
+		  */
+		FbxPlugin* FindPlugin(const char* pName, const char* pVersion) const;
+	#endif /* !FBXSDK_ENV_WINSTORE */
+	//@}
+
+
+	/**
+	  * \name IO Settings
+	  */
+	//@{
+	// Add IOSettings in hierarchy from different modules
+
+		/** Fill IO Settings for registered readers. 
+		  * \param pIOS The properties hierarchies to fill.
+		  */
+		void FillIOSettingsForReadersRegistered(FbxIOSettings& pIOS);
+
+		/** Fill IO Settings for registered writers. 
+		  * \param pIOS The properties hierarchies to fill.
+		  */
+		void FillIOSettingsForWritersRegistered(FbxIOSettings& pIOS);
+
+		/** Fill common IO Settings 
+		  * \param pIOS The properties hierarchies to fill.
+		  * \param pImport If \c true, import properties are set, otherwise export properties are set.
+		  */
+		void FillCommonIOSettings(FbxIOSettings& pIOS, bool pImport);
+	//@}
+
+	/**
+	  * \name Global Object Management 
+	  */
+	//@{
+		/** Register object with the manager.
+		  * \internal
+		  * \param pObject The object to be registered.
+		  * \anchor GlobalObjectManagement
+		  */
+		void RegisterObject(FbxObject* pObject);
+
+		/** Unregister object with the manager.
+		  * \internal
+		  * \param pObject The object to be unregistered.
+		  */
+		void UnregisterObject(FbxObject* pObject);
+
+		/** Register a list of objects with the manager.
+		  * \internal
+		  * \param pArray The list of object to be registered.
+		  */
+		void RegisterObjects(const FbxArray<FbxObject*>& pArray);
+
+		/** Unregister a list of objects with the manager.
+		  * \internal
+		  * \param pArray The list of object to be unregistered.
+		  */
+		void UnregisterObjects(const FbxArray<FbxObject*>& pArray);
+
+		/** Increment the scene destroying counter. 
+		  * \remarks Call this function before the destroying list is changed.
+		 */
+		void IncreaseDestroyingSceneFlag();
+		/** Shrink the object list and decrements the scene destroying counter.
+		  * \remarks Call this function after the destroying is changed.
+		  * Use IncreasDestroyingSceneFlag() and DecreaseDestroyingSceneFlag() in pairs.
+		 */
+		void DecreaseDestroyingSceneFlag();
+	/**
+	* \name Reference Management
+	*/
+	//@{
+		/** Get number of references.
+		* \return Number of references.
+		*/
+		int GetReferenceCount() const;
+
+		/** Get reference at given index.
+		* \param pIndex Position in the list of references.
+		* \return Pointer to the reference or \c NULL if index is out of bounds.
+		*/
+		FbxSceneReference* GetReference(int pIndex) const;
+
+		/** Add a reference.
+		* \param pReference The reference to be added.
+		* \return If the reference is correctly added to the scene, return \c true otherwise, if the reference is
+		*  already there, returns \c false.
+		*/
+		int AddReference(FbxSceneReference* pReference);
+
+		/** Remove the specified reference from reference list.
+		* \param pReference The reference to be removed.
+		* \return If the reference was successfully removed, return \c true otherwise, if the
+		*  reference could not be found returns \c false.
+		*/
+		bool RemoveReference(FbxSceneReference* pReference);
+
+		/** Clear the specified reference from the SDK manager.
+		* \param pReference The reference to be removed.
+		* \return If the reference was successfully cleared from the SDK manager, return \c true otherwise, if the
+		*  reference could not be found returns \c false.
+		*/
+		bool ClearReference(FbxSceneReference* pReference);
+	//@}
+
+    /** Add a prefix to a name.
+      * \param pPrefix The prefix to be added to the \c pName. This
+      * string must contain the "::" characters in order to be considered
+      * as a prefix.
+      * \param pName The name to be prefix.
+      * \return The prefixed string
+      * \remarks If a prefix already exists, it is removed before
+      * adding \c pPrefix.
+      */
+    static FbxString PrefixName(const char* pPrefix, const char* pName);
+
+	/** Get the count of document available in this manager
+	  * \return The count of document owned by this manager.
+	  */
+	int GetDocumentCount();
+
+	/** Get the document at pIndex in the manager's list.
+	  * \param pIndex The index of the document to retrieve.
+	  * \return The document at the specified index. Will return NULL if index is invalid.
+	  */
+	FbxDocument* GetDocument(int pIndex);
+
+/*****************************************************************************************************************************
+** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
+*****************************************************************************************************************************/
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+	static FbxManager*	GetDefaultManager();
+	void				CreateMissingBindPoses(FbxScene* pScene);
+	int					GetBindPoseCount(FbxScene *pScene) const;
+	int					GetFbxClassCount() const;
+	FbxClassId			GetNextFbxClass(FbxClassId pClassId /* invalid id: first one */) const;
+
+protected:
+	FbxManager();
+	virtual ~FbxManager();
+
+	void Clear();
+	void ClassInit();
+	void ClassRelease();
+	void DataTypeInit();
+	void DataTypeRelease();
+
+private:
+	bool		CanAutoDestroySrcObject(FbxObject* pObject, FbxObject* pSrcObject, bool pRecursive) const;
+
+	void		Create_Common_Import_IOSettings_Groups(FbxIOSettings& pIOS);
+	void		Create_Common_Export_IOSettings_Groups(FbxIOSettings& pIOS);
+	void		Add_Common_Import_IOSettings(FbxIOSettings& pIOS);
+	void		Add_Common_Export_IOSettings(FbxIOSettings& pIOS);
+	void		Add_Common_RW_Import_IOSettings(FbxIOSettings& pIOS);
+	void		Add_Common_RW_Export_IOSettings(FbxIOSettings& pIOS);
+
+	FbxClassId	Internal_RegisterFbxClass(const char* pClassName, FbxClassId pParentClassId, FbxObjectCreateProc=0, const char* pFbxFileTypeName=0, const char* pFbxFileSubTypeName=0);
+	bool		Internal_RegisterFbxClass(FbxClassId pClassId);
+	FbxClassId	Internal_OverrideFbxClass(FbxClassId pClassId, FbxObjectCreateProc=0);
+	void		Internal_UnregisterFbxClass(FbxClassId pClassId);
+
+	void		RemoveObjectsOfType(const FbxClassId& pClassId);
+
+	FbxAnimEvaluator* GetDefaultAnimationEvaluator();
+
+    FbxArray<FbxObject*>				mObjects;
+	FbxArray<FbxDocument*>				mDocuments;
+
+	FbxIOSettings*						mIOSettings;
+	FbxIOPluginRegistry*				mRegistry;
+	FbxUserNotification*				mUserNotification;
+	FbxMessageEmitter*					mMessageEmitter;
+	FbxArray<FbxLocalizationManager*>	mLocalizationManagerArray;
+	FbxArray<FbxSceneReference*>		mSceneReferenceArray;
+	FbxAnimEvaluator*					mDefaultAnimationEvaluator;
+
+	FbxArray<FbxObject*>				mDestroyingObjects;
+	FbxArray<FbxDocument*>				mDestroyingDocuments;
+    int									mIsDestroyingScene;
+
+	FbxManager_internal*				mInternal;
+	static FbxManager*					smDefaultManager;
+
+	FBXSDK_FRIEND_NEW();
+	friend class FbxObject;
+	friend class FbxProperty;		//For GetDefaultAnimationEvaluator()
+	friend class FbxNode;			//For GetDefaultAnimationEvaluator()
+	friend class FbxScene;			//For GetDefaultAnimationEvaluator()
+	friend class FbxAnimEvaluator;	//For GetDefaultAnimationEvaluator()
+#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
+};
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* _FBXSDK_CORE_MANAGER_H_ */

+ 49 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxmodule.h

@@ -0,0 +1,49 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxmodule.h
+#ifndef _FBXSDK_CORE_MODULE_H_
+#define _FBXSDK_CORE_MODULE_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#ifndef FBXSDK_ENV_WINSTORE
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+typedef void* FbxModule;
+
+/** Loads the specified module into the address space of the calling process.
+  * \param pFilePath The full file path name of the module to load.
+  * \return The module handle if it successfully loaded, otherwise NULL.
+  * \remark The specified module may cause other modules to be loaded.
+  */
+FBXSDK_DLL FbxModule FbxModuleLoad(const char* pFilePath);
+
+/** Retrieves the address of an exported function or variable from the specified module.
+  * \param pModuleHandle A valid module handle.
+  * \param pProcName The procedure name to search.
+  * \return The procedure handle if valid, otherwise NULL.
+  */
+FBXSDK_DLL void* FbxModuleGetProc(FbxModule pModuleHandle, const char* pProcName);
+
+/** Frees the loaded module and, if necessary, decrements its reference count.
+  * \param pModuleHandle A valid module handle.
+  * \return \c true on success, \c false otherwise.
+  * \remark When the reference count reaches zero, the module is unloaded from the address space of the calling process and the handle is no longer valid.
+  */
+FBXSDK_DLL bool FbxModuleFree(FbxModule pModuleHandle);
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* !FBXSDK_ENV_WINSTORE */
+
+#endif /* _FBXSDK_CORE_MODULE_H_ */

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1617 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxobject.h


+ 96 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxperipheral.h

@@ -0,0 +1,96 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxperipheral.h
+#ifndef _FBXSDK_CORE_PERIPHERAL_H_
+#define _FBXSDK_CORE_PERIPHERAL_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+class FbxObject;
+
+/** FbxPeripheral is an interface to load/unload content of FbxObject from memory to
+somewhere you defined, for example, to a temporary file on disk .
+* \nosubgrouping
+* You need to inherited your own peripheral class from this class and overload
+* the functions to control what information of a FbxObject you want to load/unload,
+* and where you are going to load/unload these information to.
+* For example, you can ask an object to dump itself on disk to free some memory and vice-versa 
+* when you want to load/unload this object from your scene flexibly.
+*/
+class FBXSDK_DLL FbxPeripheral 
+{
+public:
+	/**
+	  * \name Constructor and Destructor
+	  */
+	//@{
+
+	//!Constructor.
+	FbxPeripheral();
+
+    //!Destructor.
+	virtual ~FbxPeripheral();
+	//@}
+
+	/** Reset the peripheral to its initial state.
+	  */
+	virtual void Reset() = 0;
+
+	/** Unload the content of pObject.
+	  * \param pObject                 Object whose content is to be offloaded into 
+	  * the peripheral storage area.
+	  * \return                        \c true if the object content has been successfully transferred.
+	  * \c false otherwise.
+	  */
+	virtual bool UnloadContentOf(FbxObject* pObject) = 0;
+
+	/** Load the content of pObject.
+	  * \param pObject                 Object whose content is to be loaded from
+	  * the peripheral storage area.
+	  * \return                        \c true if the object content has been successfully transferred.
+	  * \c false otherwise.
+	  */
+	virtual bool LoadContentOf(FbxObject* pObject) = 0;
+
+	/** Check if this peripheral can unload the given object content.
+	  * \param pObject                 Object whose content has to be transferred.
+	  * \return                        \c true if the peripheral can handle this object content and
+	  * has enough space in its storage area.\c false otherwise.
+	  */
+	virtual bool CanUnloadContentOf(FbxObject* pObject) = 0;
+
+    /** Check if this peripheral can load the given object content.
+    * \param pObject                  Object whose content has to be transferred.
+    * \return                         \c true if the peripheral can handle this object content.
+	* \c false otherwise.
+    */
+    virtual bool CanLoadContentOf(FbxObject* pObject) = 0;
+
+    /** Initialize the connections of an object
+    * \param pObject                  Object on which the request for connection is done.
+    */
+    virtual void InitializeConnectionsOf(FbxObject* pObject) = 0;
+
+    /** Uninitialize the connections of an object
+    * \param pObject                 Object on which the request for disconnection is done.
+    */
+    virtual void UninitializeConnectionsOf(FbxObject* pObject) = 0;
+};
+
+// predefined offload peripherals
+extern FBXSDK_DLL FbxPeripheral* NULL_PERIPHERAL;
+extern FBXSDK_DLL FbxPeripheral* TMPFILE_PERIPHERAL;
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* _FBXSDK_CORE_PERIPHERAL_H_ */

+ 264 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxplugin.h

@@ -0,0 +1,264 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxplugin.h
+#ifndef _FBXSDK_CORE_PLUGIN_H_
+#define _FBXSDK_CORE_PLUGIN_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#ifndef FBXSDK_ENV_WINSTORE
+
+#include <fbxsdk/core/fbxobject.h>
+#include <fbxsdk/core/fbxmodule.h>
+#include <fbxsdk/core/fbxlistener.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+class FbxManager;
+class FbxPluginContainer;
+
+//! Plug-in declaration macro that must to be used when defining new FbxPlugin objects.
+#define FBXSDK_PLUGIN_DECLARE(Plugin)\
+	FBXSDK_FRIEND_NEW();\
+public:\
+	static Plugin * Create(const FbxPluginDef& pDefinition, FbxModule pModuleHandle);\
+	void Destroy();
+
+//! Plug-in implementation macro that must be used when implementing new FbxPlugin objects.
+#define FBXSDK_PLUGIN_IMPLEMENT(Plugin)\
+	Plugin* Plugin::Create(const FbxPluginDef& pDefinition, FbxModule pModuleHandle){ return FbxNew<Plugin>(pDefinition, pModuleHandle); }\
+	void Plugin::Destroy(){ FbxDelete(this); }
+
+/** Structure used by plug-ins for identification purposes.
+  * \note To avoid confusions in the system, it is recommended to choose an appropriate unique identifier string name when
+  * defining your plug-in, as well as incrementing the version string to a correct value whenever something changes in the
+  * implementation of the plug-in. Both of these string are used when comparing plug-ins for searches, as well as
+  * identification in FBX files.
+  */
+struct FBXSDK_DLL FbxPluginDef
+{
+	//! Constructor
+	FbxPluginDef() :
+		mName("Unknown Name"),
+		mVersion("Unknown Version")
+	{
+	}
+
+	FbxString mName;		//!< The identifier name string of the plug-in. If the name is already used by another plug-in, the plug-in will still register.
+	FbxString mVersion;	//!< The version string of the plug-in.
+};
+
+/** Data used to communicate information between an application and the plug-in.
+  */
+struct FBXSDK_DLL FbxPluginData
+{
+	//! Constructor
+	FbxPluginData() :
+		mQueryEmitter(NULL),
+		mSDKManager(NULL),
+		mPluginContainer(NULL)
+	{
+	}
+
+	//! Copy Constructor
+	explicit FbxPluginData(const FbxPluginData& pOther) :
+		mQueryEmitter(pOther.mQueryEmitter),
+		mSDKManager(pOther.mSDKManager),
+		mPluginContainer(pOther.mPluginContainer)
+	{
+	}
+
+	FbxEmitter*			mQueryEmitter;		//!< The emitter on which the plug-in can listen to receive events.
+	FbxManager*			mSDKManager;		//!< The FBX SDK Manager on which the plug-in was instanced.
+	FbxPluginContainer*	mPluginContainer;   //!< The container which will have the ownership of the plug-in.
+};
+
+/** The base class to inherit from when creating new plug-ins for the FBX SDK. Plug-ins for the FBX SDK are extremely flexible
+  * allowing a wide-range of possibilities. For example, one can write his own plug-in to add new readers/writers to the current list
+  * of supported I/O formats, or add new dynamic classes to instantiate custom objects that can later be stored in FBX files. We also use the same
+  * interface for plug-ins written using the FBX Extension SDK, which allow additional callbacks for other various Autodesk products
+  * enabling greater interoperability with multiple various SDKs.
+  *
+  * Here is typical implementation of an FBX SDK plug-in that doesn't do anything else than just registering itself:
+  * \code
+  * class MyPlugin : public FbxPlugin
+  * {
+  *     FBXSDK_PLUGIN_DECLARE(MyPlugin); //This macro is mandatory for any plug-in definition
+  *
+  * protected:
+  *     explicit MyPlugin(const FbxPluginDef& pDefinition, FbxModule pModuleHandle) : FbxPlugin(pDefinition, pModuleHandle)
+  *     {
+  *     }
+  *
+  *     //Abstract functions that *must* be implemented
+  *     virtual bool SpecificInitialize()
+  *     {
+  *         //For example, here we could register as many new I/O readers/writers as we would like, or classes, etc.
+  *         return true;
+  *     }
+  *
+  *     virtual bool SpecificTerminate()
+  *     {
+  *         //Here we would have to unregister whatever we registered to the FBX SDK
+  *         return true;
+  *     }
+  * };
+  *
+  * FBXSDK_PLUGIN_IMPLEMENT(MyPlugin); //This macro is mandatory for any plug-in implementation
+  *
+  * //Standard C export needed for any new FBX SDK plug-in
+  * extern "C"
+  * {
+  *     static MyPlugin* sMyPluginInstance = NULL; //The module is owner of the plug-in
+  *
+  *     //This function will be called when an application will request the plug-in
+  * #ifdef FBXSDK_ENV_WIN
+  *     __declspec(dllexport) void FBXPluginRegistration(FbxPluginContainer& pContainer, FbxModule pModuleHandle)
+  * #else
+  *     void FBXPluginRegistration(FbxPluginContainer& pContainer, FbxModule pModuleHandle)
+  * #endif
+  *     {
+  *         if( sPlugin == NULL )
+  *         {
+  *             //Create the plug-in definition which contains the information about the plug-in
+  *             FbxPluginDef sPluginDef;
+  *             sPluginDef.mName = "My Plugin";
+  *             sPluginDef.mVersion = "1.0";
+  *
+  *             //Create an instance of the plug-in
+  *             sMyPluginInstance = MyPlugin::Create(sPluginDef, pLibHandle);
+  *
+  *             //Register the plug-in with the FBX SDK
+  *             pContainer.Register(*sPlugin);
+  *         }
+  *     }
+  * }
+  * \endcode
+  * \see FbxPluginDef, FbxPluginData
+  */
+class FBXSDK_DLL FbxPlugin : public FbxListener
+{
+	FBXSDK_INTRUSIVE_LIST_NODE(FbxPlugin, 1);
+
+public:
+	/** Abstract function called once at the end of the plug-in construction. At that moment, plug-in data have been properly initialized.
+	  * This function must be implemented by anyone who writes a new plug-in for the FBX SDK.
+	  */
+	virtual bool SpecificInitialize()=0;
+
+	/** Abstract function called once at the beginning of the plug-in destruction. At that moment, plug-in data is fully available.
+	  * This function must be implemented by anyone who writes a new plug-in for the FBX SDK.
+	  */
+	virtual bool SpecificTerminate()=0;
+
+	/** Virtual function called once when the FBX SDK is about to write an FBX file. Users can re-implement it in their plug-in if they need
+	  * to perform tasks at that moment. The scene provided in parameter can be altered. If not re-implemented, this function does nothing.
+	  * \param pScene The scene that is about to be written in the FBX file.
+	  */
+	virtual void WriteBegin(FbxScene& pScene);
+
+	/** Virtual function called once when the FBX SDK is about to write plug-in's parameters. Users can re-implement it in their plug-in if they need
+	  * to store properties in the FBX file for their own usage. The object in parameter is used to store those properties.
+	  * If not re-implemented, this function does nothing.
+	  * \param pParams An abstract object that can be used as a property container, to allow the plug-in to store properties about the plug-in.
+	  */
+	virtual void WriteParameters(FbxObject& pParams);
+
+	/** Virtual function called once after the FBX SDK wrote an FBX file. Users can re-implement it in their plug-in if they need
+	  * to perform tasks at that moment. The scene provided in parameter can be altered, but the changes will not appear in the FBX file.
+	  * If not re-implemented, this function does nothing.
+	  * \param pScene The scene that was written in the FBX file.
+	  */
+	virtual void WriteEnd(FbxScene& pScene);
+
+	/** Virtual function called once when the FBX SDK is about to read an FBX file. Users can re-implement it in their plug-in if they need
+	  * to perform tasks at that moment. The scene provided in parameter can be altered. If not re-implemented, this function does nothing.
+	  * \param pScene The scene that is about to be read in the FBX file.
+	  */
+	virtual void ReadBegin(FbxScene& pScene);
+
+	/** Virtual function called once after the FBX SDK reads the plug-in's parameters. Users can re-implement it in their plug-in if they need
+	  * to retrieve properties for their own usage. The object in parameter is used to retrieve those properties.
+	  * If not re-implemented, this function does nothing.
+	  * \param pParams An abstract object that can be used as a property container, to allow the plug-in to read properties about the plug-in.
+	  */
+	virtual void ReadParameters(FbxObject& pParams);
+
+	/** Virtual function called once after the FBX SDK read an FBX file. Users can re-implement it in their plug-in if they need
+	  * to perform tasks at that moment. The scene provided in parameter can be altered. If not re-implemented, this function does nothing.
+	  * \param pScene The scene that was read in the FBX file.
+	  */
+	virtual void ReadEnd(FbxScene& pScene);
+
+	/** Accessor to the plug-in definition structure that contains basic information on the plug-in like its name or version. This is
+	  * the only method available to differentiate plug-ins.
+	  * \return The definition structure for this plug-in.
+	  */
+	const FbxPluginDef& GetDefinition() const;
+
+	/** Retrieve the module address pointer for this plug-in. With this module instance handle, for example someone can query procedures addresses,
+	  * allowing more complex interactions, as well as other operating system module specific functions.
+	  */
+	FbxModule GetModuleHdl();
+
+protected:
+	/** Use the Create() and Destroy() methods declared and implemented in the FBXSDK_PLUGIN_DECLARE and FBXSDK_PLUGIN_IMPLEMENT macros to construct and destroy FbxPlugin objects.
+	  * \param pDefinition The definition associated with this plug-in. Each plug-in must have its own definition to differentiate it with other plug-ins.
+	  * \param pModuleHandle A pointer to the plug-in module address.
+	  */
+	explicit FbxPlugin(const FbxPluginDef& pDefinition, FbxModule pModuleHandle);
+
+	/** Accessor to the plug-in private data.
+	  * \return The data for the current plug-in.
+	  */
+	FbxPluginData& GetData();
+
+	/** Const accessor to the plug-in private data.
+	  * \return The const data for the current plug-in.
+	  */
+	const FbxPluginData& GetData() const;
+
+/*****************************************************************************************************************************
+** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
+*****************************************************************************************************************************/
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+public:
+	inline FbxObject& GetPluginSettings() { return *mPluginSettings; }
+	inline const FbxObject& GetPluginSettings() const { return *mPluginSettings; }
+	template <typename EventType, typename ListernerType> inline FbxEventHandler* Bind(void (ListernerType::*pFunc)(const EventType*))
+	{
+		return FbxListener::Bind<EventType,ListernerType>(*(GetData().mQueryEmitter), pFunc );
+	}
+	virtual void Destroy() = 0;
+
+protected:
+	virtual ~FbxPlugin();
+
+private:
+	bool							Initialize(const FbxPluginData& pData);
+	bool							Terminate();
+
+	bool							mInitialized;
+	FbxPluginData					mData;
+	FbxPluginDef					mDefinition;
+	FbxModule						mModuleHandle;
+	FbxObject*						mPluginSettings;
+
+	friend class FbxLoadingStrategy;
+#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
+};
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* !FBXSDK_ENV_WINSTORE */
+
+#endif /* _FBXSDK_CORE_PLUGIN_H_ */

+ 74 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxplugincontainer.h

@@ -0,0 +1,74 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxplugincontainer.h
+#ifndef _FBXSDK_CORE_PLUGIN_CONTAINER_H_
+#define _FBXSDK_CORE_PLUGIN_CONTAINER_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#ifndef FBXSDK_ENV_WINSTORE
+
+#include <fbxsdk/core/fbxplugin.h>
+#include <fbxsdk/core/fbxemitter.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+/** Manages registration and ownership of FBX SDK plug-ins (FbxPlugin). 
+  * The FBX SDK will provide a pointer to FbxPluginContainer as an argument
+  * to the FBXPluginRegistration() function exported from a plug-in's DLL.
+  * A plug-in must register itself explicitly with the FbxPluginContainer
+  * by calling FbxPluginContainer::Register() after it is constructed. 
+  * For an example of this process see the code example in the FbxPlugin 
+  * class documentation.
+  * \see FbxPlugin
+  */
+class FBXSDK_DLL FbxPluginContainer : public FbxEmitter
+{
+public:
+	//! Definition of a plug-in list.
+	typedef FbxIntrusiveList<FbxPlugin> PluginList;
+
+	/** The registration function that must be called when the module containing the plug-in is loaded.
+	  * \param pPlugin The plug-in to register.
+	  */
+	void Register(FbxPlugin& pPlugin);
+
+	/** The unregistration function that must be called when the module containing the plug-in is unloaded.
+	  * \param pPlugin The plug-in to unregister.
+	  */
+	void Unregister(FbxPlugin& pPlugin);
+
+	/** Const accessor to the list of plug-ins owned by the container.
+	  * \return A list of plug-in registered to this container.
+	  */
+	const PluginList& GetPlugins() const;
+
+	/** Accessor to the list of plug-ins owned by the container.
+	  * \return A list of plug-in registered to this container.
+	  */
+	PluginList& GetPlugins();
+
+/*****************************************************************************************************************************
+** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
+*****************************************************************************************************************************/
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+protected:
+	virtual ~FbxPluginContainer();
+	PluginList mPlugins;
+#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
+};
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* !FBXSDK_ENV_WINSTORE */
+
+#endif /* _FBXSDK_CORE_PLUGIN_CONTAINER_H_ */

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1286 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxproperty.h


+ 146 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxpropertydef.h

@@ -0,0 +1,146 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxpropertydef.h
+#ifndef _FBXSDK_CORE_PROPERTY_DEFINITION_H_
+#define _FBXSDK_CORE_PROPERTY_DEFINITION_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#include <fbxsdk/core/fbxpropertytypes.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+#define FBXSDK_PROPERTY_ID_NULL	-1
+#define FBXSDK_PROPERTY_ID_ROOT 0
+
+class FbxPropertyPage;
+
+class FBXSDK_DLL FbxPropertyFlags
+{
+public:
+	//! Property inherit types
+	enum EInheritType
+	{
+		eOverride,	//!< Property override this flag from its reference property.
+		eInherit,	//!< Property inherit this flag from its reference property.
+		eDeleted	//!< Property has been deleted, so inheritance is invalid.
+	};
+
+	//! Property flags that affect their behaviors
+	enum EFlags
+	{
+		eNone = 0,					//!< No flag.
+		eStatic = 1 << 0,			//!< Property is defined in the class declaration, so it wasn't created dynamically.
+		eAnimatable = 1 << 1,		//!< Property can be animated, thus is can have am animation curve node connected.
+		eAnimated = 1 << 2,			//!< Property is animated, so it also has an animation curve node connected.
+		eImported = 1 << 3,			//!< Property has been created during import process when reading FBX file.
+		eUserDefined = 1 << 4,		//!< Property has been defined by user, not by the FBX SDK.
+		eHidden = 1 << 5,			//!< Property should not be displayed on user interface.
+		eNotSavable = 1 << 6,		//!< Property value must not be exported when writing FBX files.
+
+        eLockedMember0 = 1 << 7,	//!< This property has its member #0 locked.
+        eLockedMember1 = 1 << 8,	//!< This property has its member #1 locked.
+        eLockedMember2 = 1 << 9,	//!< This property has its member #2 locked.
+        eLockedMember3 = 1 << 10,	//!< This property has its member #3 locked.
+        eLockedAll = eLockedMember0 | eLockedMember1 | eLockedMember2 | eLockedMember3,
+        eMutedMember0 = 1 << 11,	//!< This property has its member #0 muted.
+        eMutedMember1 = 1 << 12,	//!< This property has its member #1 muted.
+        eMutedMember2 = 1 << 13,	//!< This property has its member #2 muted.
+        eMutedMember3 = 1 << 14,	//!< This property has its member #3 muted.
+        eMutedAll = eMutedMember0 | eMutedMember1 | eMutedMember2 | eMutedMember3,
+
+		//Private flags
+		eUIDisabled = 1 << 15,		//!< Private flag for dynamic UI in FBX plug-ins.
+		eUIGroup = 1 << 16,			//!< Private flag for dynamic UI in FBX plug-ins.
+		eUIBoolGroup = 1 << 17,		//!< Private flag for dynamic UI in FBX plug-ins.
+		eUIExpanded = 1 << 18,		//!< Private flag for dynamic UI in FBX plug-ins.
+		eUINoCaption = 1 << 19,		//!< Private flag for dynamic UI in FBX plug-ins.
+		eUIPanel = 1 << 20,			//!< Private flag for dynamic UI in FBX plug-ins.
+		eUILeftLabel = 1 << 21,		//!< Private flag for dynamic UI in FBX plug-ins.
+		eUIHidden = 1 << 22,		//!< Private flag for dynamic UI in FBX plug-ins.
+
+		eCtrlFlags = eStatic | eAnimatable | eAnimated | eImported | eUserDefined | eHidden | eNotSavable | eLockedAll | eMutedAll,
+		eUIFlags = eUIDisabled | eUIGroup | eUIBoolGroup | eUIExpanded | eUINoCaption | eUIPanel | eUILeftLabel | eUIHidden,
+		eAllFlags = eCtrlFlags | eUIFlags,
+
+		eFlagCount = 23,
+	};
+
+	bool SetFlags(FbxPropertyFlags::EFlags pMask, FbxPropertyFlags::EFlags pFlags);
+	FbxPropertyFlags::EFlags GetFlags() const;
+	FbxPropertyFlags::EFlags GetMergedFlags(FbxPropertyFlags::EFlags pFlags) const;
+	bool ModifyFlags(FbxPropertyFlags::EFlags pFlags, bool pValue);
+	FbxPropertyFlags::EInheritType GetFlagsInheritType(FbxPropertyFlags::EFlags pFlags) const;
+
+	bool SetMask(FbxPropertyFlags::EFlags pFlags);
+	bool UnsetMask(FbxPropertyFlags::EFlags pFlags);
+	FbxPropertyFlags::EFlags GetMask() const;
+
+	bool Equal(const FbxPropertyFlags& pOther, FbxPropertyFlags::EFlags pFlags) const;
+
+/*****************************************************************************************************************************
+** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
+*****************************************************************************************************************************/
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+	FbxPropertyFlags();
+	explicit FbxPropertyFlags(FbxPropertyFlags::EFlags pFlags);
+	FbxPropertyFlags Clone(FbxPropertyPage* pPage);
+
+    static const int sLockedMembersMax = 4;			//Maximum number of property sub-member that can be locked.
+    static const int sLockedMembersBitOffset = 7;	//Number of bits to shift to get to the first locked member flag.
+    static const int sMutedMembersMax = 4;			//Maximum number of property sub-member that can be muted.
+    static const int sMutedMembersBitOffset = 11;	//Number of bits to shift to get to the first muted member flag.
+
+private:
+    FbxUInt32 mFlagData, mMaskData;
+
+	FBX_ASSERT_STATIC(sizeof(FbxUInt32) * 8 >= FbxPropertyFlags::eFlagCount);
+#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
+};
+
+class FBXSDK_DLL FbxPropertyValue
+{
+public:
+	static FbxPropertyValue* Create(void* pData, EFbxType pType);
+	void Destroy();
+	FbxPropertyValue* Clone(FbxPropertyPage*);
+
+	bool Get(void* pValue, EFbxType pValueType);
+	bool Set(const void* pValue, EFbxType pValueType);
+	size_t GetSizeOf() const;
+	size_t GetComponentCount() const;
+
+	void IncRef();
+	void DecRef();
+	int GetRef();
+
+/*****************************************************************************************************************************
+** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
+*****************************************************************************************************************************/
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+	FbxPropertyValue();
+
+private:
+	FbxPropertyValue(void* pValue, EFbxType pType);
+	~FbxPropertyValue();
+
+	int			mRef;
+	EFbxType	mType;
+	void*		mValue;
+
+	FBXSDK_FRIEND_NEW();
+#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
+};
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* _FBXSDK_CORE_PROPERTY_DEFINITION_H_ */

+ 576 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxpropertyhandle.h

@@ -0,0 +1,576 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxpropertyhandle.h
+#ifndef _FBXSDK_CORE_PROPERTY_HANDLE_H_
+#define _FBXSDK_CORE_PROPERTY_HANDLE_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#include <fbxsdk/core/fbxconnectionpoint.h>
+#include <fbxsdk/core/fbxpropertytypes.h>
+#include <fbxsdk/core/fbxpropertydef.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+class FbxPropertyPage;
+class FbxPropertyHandle;
+class FbxConnectionPointFilter;
+
+//!	\brief Class to manage property handle.
+class FBXSDK_DLL FbxPropertyHandle
+{
+public:
+	/**
+	* \name Constructor and Destructor
+	*/
+	//@{
+		//! Create an instance
+		static FbxPropertyHandle Create();
+
+		/** Create an instance with given instance.
+		* \param pInstanceOf The given instance. */
+		static FbxPropertyHandle Create(const FbxPropertyHandle& pInstanceOf);
+
+		/** Create an instance with given name and type.
+		* \param pName Property name.
+		* \param pType Property type. */
+		static FbxPropertyHandle Create(const char* pName, EFbxType pType=eFbxUndefined);
+
+		/** Create an instance with given name and type info.
+		* \param pName
+		* \param pTypeInfo */
+		static FbxPropertyHandle Create(const char* pName, FbxPropertyHandle pTypeInfo);
+
+		/** If this property is root property, delete the property page, otherwise delete the property.
+		* \return  If succeed, return true. */
+		bool Destroy();
+
+		//! Default constructor. 
+		FbxPropertyHandle();
+
+		/** Copy constructor.
+		* \param pAddress FbxPropertyHandle copied to this one. */
+		FbxPropertyHandle(const FbxPropertyHandle& pAddress);
+
+		//! Destructor
+		~FbxPropertyHandle();
+
+		/**  Character constructor.
+		* \param pPage
+		* \param pId */
+		FbxPropertyHandle(FbxPropertyPage* pPage, FbxInt pId=FBXSDK_PROPERTY_ID_ROOT);
+	//@}
+
+	/**
+	* \name Assignment and basic info
+	*/
+	//@{
+		/** FbxPropertyHandle assignment operator.
+		* \param pHandle FbxPropertyHandle assigned to this one. */
+		FbxPropertyHandle& operator=(const FbxPropertyHandle& pHandle);
+
+		/** Equality operator.
+		* \param pHandle FbxPropertyHandle compared with this one.
+		* \return \c True if equal, \c false otherwise. */
+		bool operator==(const FbxPropertyHandle& pHandle) const;
+
+		/** Inequality operator.
+		* \param pHandle FbxPropertyHandle compared with this one.
+		* \return \c True if unequal, \c false otherwise. */
+		bool operator!=(const FbxPropertyHandle& pHandle) const;
+
+		/** Lesser operator, used to sort property handle in map.
+		* \param pHandle The property handle compared to this property handle.
+		* \return \c true if less, \c false otherwise. */
+		bool operator< (const FbxPropertyHandle& pHandle) const;
+
+		/** Greater operator, used to sort property handle in map.
+		* \param pProperty The property handle compared to this property handle.
+		* \return \c true if greater, \c false otherwise. */
+		bool operator> (const FbxPropertyHandle& pHandle) const;
+
+		/** Compare type info together
+		* \param pHandle FbxPropertyHandle compared with this one.   
+		* \return \c True if equal, \c false otherwise. */
+		bool Is(const FbxPropertyHandle& pHandle) const;
+
+		//! Judge validity
+		bool Valid() const;
+
+		//! Get the property name
+		const char*	GetName() const;
+
+		//! Get the property label
+		const char*	GetLabel() const;
+
+		/** Set a label to the property
+		* \param pLabel The given label string
+		* \return \c true if successful. */
+		bool SetLabel(const char* pLabel);
+
+		//! Get the property type
+		EFbxType GetType() const;
+
+		//! Get the property type info
+		FbxPropertyHandle GetTypeInfo() const;
+
+		//! Get the property attribute state
+		FbxPropertyFlags::EFlags	GetFlags() const;
+	
+		/**	Gets the inheritance type for the given flag. 
+		* \param pFlags The flag to query
+		* \param pCheckReferences Decide whether check instance. If it is true, check instance.
+		* \return The inheritance type */
+		FbxPropertyFlags::EInheritType GetFlagsInheritType(FbxPropertyFlags::EFlags pFlags, bool pCheckReferences) const;
+
+		/**	According the given parameter Change the attributes of the property.
+		* \param pFlags The given flags used as mask.
+		* \param pValue If pValue is true, set mask with given flags, otherwise unset mask with given flags.
+		* \return  If succeed, return true. */
+		bool ModifyFlags(FbxPropertyFlags::EFlags pFlags, bool pValue);
+
+		/**Sets the inheritance type for the given flag
+		* \param pFlags The flag to set 
+		* \param pType The inheritance type to set 
+		* \return  If succeed, return true. */
+		bool SetFlagsInheritType(FbxPropertyFlags::EFlags pFlags, FbxPropertyFlags::EInheritType pType);
+
+		//! Get the property user data.
+		void* GetUserData() const;
+
+		/** Set user data to the property
+		* \param pUserData The given user data
+		* \return  If succeed, return true. */
+		bool SetUserData(const void* pUserData);
+
+		//! Get the property user tag
+		int GetUserTag() const;
+
+		/** Set user tag to the property
+		* \param pUserData The given user tag
+		* \return  If succeed, return true. */
+		bool SetUserTag(int pUserData);
+	//@}
+
+	/**
+	* \name Enum management
+	*/
+	//@{
+		/** Add new value at the end of the enum list in the property.
+		* \param pStringValue The given new value
+		* \return  The index of the value. */
+		int AddEnumValue(const char* pStringValue);
+
+		/** Insert new value at the given index of the enum list in property.
+		* \param pIndex The given index
+		* \param pStringValue The given new value */
+		void InsertEnumValue(int pIndex, const char* pStringValue);
+
+		/** Get the enum count of enum list in property
+		* \return The enum count of enum list in property */
+		int GetEnumCount();
+
+		/** Set value at the given index of the enum list in the property.
+		* \param pIndex  The given index
+		* \param pStringValue The given new value used to instead the old value. */
+		void SetEnumValue(int pIndex, const char* pStringValue);
+
+		/** Remove the value at the index of the enum list in the property.
+		* \param pIndex The given index */
+		void RemoveEnumValue(int pIndex);
+
+		/** Get the value at the index of enum list in the property.
+		* \param pIndex    The given index
+		* \return The value at the given index */
+		char* GetEnumValue(int pIndex);
+	//@}
+
+	/**
+	* \name Child and Struct management
+	*/
+	//@{
+		//! Create the map for find property in the property page
+		void BeginCreateOrFindProperty();
+
+		//! Clear the map which created for find property.
+		void EndCreateOrFindProperty();
+
+		/** Judge if the property is the root property.
+		* \return Return true if this property is root property. */
+		inline bool	IsRoot() const { return ( mPage && mId == 0 ) ? true : false; }
+
+		/** Judge if the property is the child property of the given parent property.
+		* \param pParent The given parent property handle
+		* \return Return true if this property is child of given property. */
+		bool IsChildOf(const FbxPropertyHandle& pParent) const;
+
+		/** Judge if the property is descendent property of the given property.
+		* \param pParent The given parent property handle
+		* \return Return true if this property is descendant of given property. */
+		bool IsDescendentOf(const FbxPropertyHandle& pParent) const;
+
+		/** Set parent property handle.No matter what enters,the result is always false.
+		* \param pOther
+		* \return False */
+		bool SetParent(const FbxPropertyHandle& pOther );
+
+		/** Add a property to the property page.
+		* \param pName The name of property.
+		* \param pTypeInfo The added property's type info.
+		* \return The handle of the new added property */
+		FbxPropertyHandle Add(const char* pName, const FbxPropertyHandle& pTypeInfo);
+
+		/** Get parent property
+		* \return If the parent property exists, return the property handle,otherwise return -1. */
+		FbxPropertyHandle GetParent() const;
+
+		/**  Get child property 
+		* \return  If the child property is exist, return the property handle,otherwise return -1. */
+		FbxPropertyHandle GetChild() const;
+
+		/**  Get sibling property  
+		* \return If the sibling property is exist, return the property handle,otherwise return -1. */
+		FbxPropertyHandle GetSibling() const;
+
+		/**  Get first descendent property 
+		* \return If the descendent property is exist, return the first descendent property handle,otherwise return -1. */
+		FbxPropertyHandle GetFirstDescendent() const;
+
+		/**  Get first descendent property which after the given property 
+		* \param pHandle The given property handle
+		* \return If the descendent property can be found after the given property, 
+		* return the first found property handle,otherwise return -1. */
+		FbxPropertyHandle GetNextDescendent(const FbxPropertyHandle& pHandle) const;
+
+		/** Find the property with given name 
+		* \param pName The given property name
+		* \param pCaseSensitive Decide if the given property name is case sensitive
+		* \return  Return a property handle which be created with the found property. */
+		FbxPropertyHandle Find(const char* pName, bool pCaseSensitive) const;
+
+		/** Find the property with given name and type info.
+		* \param pName The given property name
+		* \param pTypeInfo The given property type info
+		* \param pCaseSensitive Decide if the given property name is case sensitive
+		* \return  Return a property handle which be created with the found property. */
+		FbxPropertyHandle Find(const char* pName, const FbxPropertyHandle& pTypeInfo, bool pCaseSensitive) const;
+
+		/** Separate the given name by  children separator string and then find the property.The step is  
+		*  strip the first part of the name and search, if the property can be found, strip the second part  
+		*  of the name and continue search, until no property be found,then return the last found property.
+		* \param pName The given property name
+		* \param pChildrenSeparator The given children separator string 
+		* \param pCaseSensitive Decide if the given property name is case sensitive
+		* \return  Return a property handle which be created with the found property. */
+		FbxPropertyHandle Find(const char* pName, const char* pChildrenSeparator, bool pCaseSensitive) const;
+
+		/** Separate the given name by  children separator string and then find the property.The step is  
+		*  strip the first part of the name and search, if the property can be found, strip the second part  
+		*  of the name and continue search, until no property be found,then return the last found property.
+		* \param pName The given property name
+		* \param pChildrenSeparator The given children separator string 
+		* \param pTypeInfo The given property type info
+		* \param pCaseSensitive Decide if the given property name is case sensitive
+		* \return  Return a property handle which be created with the found property. */
+		FbxPropertyHandle Find(const char* pName, const char* pChildrenSeparator, const FbxPropertyHandle& pTypeInfo, bool pCaseSensitive) const;
+	//@}
+
+	/**
+	* \name Connection management
+	*/
+	//@{
+		/** Connect source property.
+		* \param pSrc    The given source property
+		* \param pType    The given property type
+		* \return If connect successfully, return true,otherwise, return false. */
+		bool ConnectSrc(const FbxPropertyHandle& pSrc, const FbxConnection::EType pType=FbxConnection::eDefault); 
+
+		/** Get source properties' count.
+		* \param pFilter    The filter used to get sub connection point. If it is not zero, return the source count of the sub connection point.
+		* Otherwise, return the src count of this property.
+		* \return The count of source properties */
+		int GetSrcCount(FbxConnectionPointFilter* pFilter=0) const; 
+
+		/** Get source property with the given index.
+		* \param pFilter    The filter used to get sub connection point. If it is not zero, return the source property of the sub connection point.
+		* Otherwise, return the source property of this property.
+		* \param pIndex    The given index
+		* \return The source property handle. */
+		FbxPropertyHandle GetSrc(FbxConnectionPointFilter* pFilter=0, int pIndex=0) const; 
+
+		/** Disconnect source property.
+		* \param pSrc    The given source property
+		* \return If disconnect successfully, return true, otherwise return false. */
+		bool DisconnectSrc(const FbxPropertyHandle& pSrc);
+
+		/** Judge if it is connected with the given source property.
+		* \param pSrc    The given source property
+		* \return If it is connected, return true, otherwise return false. */
+		bool IsConnectedSrc(const FbxPropertyHandle& pSrc);
+
+		/** Connect destination property.
+		* \param pDst    The given destination property
+		* \param pType    The given property type
+		* \return If connect successfully, return true,otherwise, return false. */
+		bool ConnectDst(const FbxPropertyHandle& pDst, const FbxConnection::EType pType=FbxConnection::eDefault); 
+
+		/** Get destination properties' count.
+		* \param pFilter    The filter used to get sub connection point.If it is not zero,return the destination count of the sub connection point.
+		* Otherwise, return the destination count of this property.
+		* \return The count of destination properties */
+		int GetDstCount(FbxConnectionPointFilter* pFilter=0) const; 
+
+		/** Get destination property with the given index.
+		* \param pFilter    The filter used to get sub connection point.If it is not zero,return the destination property of the sub connection point.
+		* Otherwise, return the destination property of this property.
+		* \param pIndex    The given index
+		* \return The destination property handle. */
+		FbxPropertyHandle GetDst(FbxConnectionPointFilter* pFilter=0, int pIndex=0) const; 
+
+		/** Disconnect destination property.
+		* \param pDst    The given destination property
+		* \return If disconnect successfully, return true,otherwise, return false. */
+		bool DisconnectDst(const FbxPropertyHandle& pDst);
+
+		/** Judge if it is connected with the given destination property.
+		* \param pDst    The given destination property
+		* \return If it is connected, return true,otherwise, return false. */
+		bool IsConnectedDst(const FbxPropertyHandle& pDst);
+
+		//! Clear connect cache
+		void ClearConnectCache();
+
+		//! Clear all connect without sending any notification (Internal use ONLY)
+		void WipeAllConnections();
+	//@}
+
+	/** \name Limits Functions
+	* Minimum and maximum value limits can be associated with properties, but FBX 
+	* will not verify that these limits are respected. FBX however will store and 
+	* retrieve limits from files, and will assure that they are persistent in memory 
+	* while the property handle object exists. 
+	*
+	* Soft minimums and maximums values are specifying a second set of limits that can be 
+	* used for UI objects such as sliders. FBX will handle them the same way it does
+	* with the normal limits. */
+	//@{
+		/** Judge if this property has a minimum value.
+		* \return If the minimum value exist, return true,otherwise, return false. */
+		bool HasMin() const;
+
+		/** Get the minimum value and value type of this property.
+		* \param pValue    The minimum value of this property.
+		* \param pValueType The value type of this property.
+		* \return If the minimum value exist, return true,otherwise, return false. */
+		bool GetMin(void* pValue, EFbxType pValueType) const;
+
+		/** Set the minimum value and value type for this property.
+		* \param pValue    The given minimum value .
+		* \param pValueType The given value type .
+		* \return If it be set successfully, return true,otherwise, return false. */
+		bool SetMin(const void* pValue, EFbxType pValueType);
+
+		/** According the given value and its value type, set the minimum value and value type for this property.
+		* \param pValue    The given value .
+		* \return If it be set successfully, return true,otherwise, return false.
+		*/
+		template <class T> inline bool SetMin(const T& pValue){ return SetMin(&pValue, FbxTypeOf(pValue)); }
+
+		/** Get the minimum value of this property.
+		* \param pFBX_TYPE    Not used in this function. This is a dummy argument for 
+		*                     the correct instantiation of the templated function.
+		* \return The minimum value of this property */
+		template <class T> inline T GetMin(const T* pFBX_TYPE) const { T lValue; GetMin(&lValue, FbxTypeOf(lValue)); return lValue; }
+
+		/** Judge if this property has soft minimum value.
+		* \return If the soft minimum value exist, return true,otherwise, return false. */
+		bool HasSoftMin() const;
+
+		/** Get the soft minimum value and value type of this property.
+		* \param pValue    The soft minimum value of this property.
+		* \param pValueType The value type of this property.
+		* \return If the soft minimum value exist, return true,otherwise, return false. */
+		bool GetSoftMin(void* pValue, EFbxType pValueType) const;
+
+		/** Set the soft minimum value and value type for this property.
+		* \param pValue    The given soft minimum value .
+		* \param pValueType The given value type .
+		* \return If it be set successfully, return true,otherwise, return false. */
+		bool SetSoftMin(const void* pValue, EFbxType pValueType);
+
+		/** According the given value and its value type, set the soft minimum value and value type for this property.
+		* \param pValue    The given value .
+		* \return If it be set successfully, return true,otherwise, return false. */
+		template <class T> inline bool SetSoftMin(const T& pValue){ return SetSoftMin(&pValue, FbxTypeOf(pValue)); }
+
+		/** Get the soft minimum value of this property.
+		* \param pFBX_TYPE    Not used in this function. This is a dummy argument for 
+		*                     the correct instantiation of the templated function.
+		* \return The soft minimum value of this property */
+		template <class T> inline T GetSoftMin(const T* pFBX_TYPE) const { T lValue; GetSoftMin(&lValue, FbxTypeOf(lValue)); return lValue; }
+
+		/** Judge if this property has maximum value.
+		* \return If the maximum value exist, return true,otherwise, return false. */
+		bool HasMax() const;
+
+		/** Get the maximum value and value type of this property.
+		* \param pValue    The maximum value of this property.
+		* \param pValueType The value type of this property.
+		* \return If the maximum value exist, return true,otherwise, return false. */
+		bool GetMax(void* pValue, EFbxType pValueType) const;
+
+		/** Set the maximum value and value type for this property.
+		* \param pValue    The given maximum value .
+		* \param pValueType The given value type .
+		* \return If it be set successfully, return true,otherwise, return false. */
+		bool SetMax(const void* pValue, EFbxType pValueType);
+
+		/** According the given value and its value type, set the maximum value and value type for this property.
+		* \param pValue    The given value .
+		* \return If it be set successfully, return true,otherwise, return false. */
+		template <class T> inline bool SetMax(const T& pValue){ return SetMax(&pValue, FbxTypeOf(pValue)); }
+
+		/** Get the maximum value of this property.
+		* \param pFBX_TYPE    Not used in this function. This is a dummy argument for 
+		*                     the correct instantiation of the templated function.
+		* \return The maximum value of this property */
+		template <class T> inline T GetMax(const T* pFBX_TYPE) const { T lValue; GetMax(&lValue, FbxTypeOf(lValue)); return lValue; }
+
+		/** Judge if this property has soft maximum value.
+		* \return If the soft maximum value exist, return true,otherwise, return false. */
+		bool HasSoftMax() const;
+
+		/** Get the soft maximum value and value type of this property.
+		* \param pValue    The soft maximum value of this property.
+		* \param pValueType The value type of this property.
+		* \return If the soft maximum value exist, return true,otherwise, return false. */
+		bool GetSoftMax(void* pValue, EFbxType pValueType) const;
+
+		/** Set the soft maximum value and value type for this property.
+		* \param pValue    The given soft maximum value .
+		* \param pValueType The given value type .
+		* \return If it be set successfully, return true,otherwise, return false. */
+		bool SetSoftMax(const void* pValue, EFbxType pValueType);
+
+		/** According the given value and its value type, set the soft maximum value and value type for this property.
+		* \param pValue    The given value .
+		* \return If it be set successfully, return true,otherwise, return false. */
+		template <class T> inline bool SetSoftMax(const T& pValue){ return SetSoftMax(&pValue, FbxTypeOf(pValue)); }
+
+		/** Get the soft maximum value of this property.
+		* \param pFBX_TYPE    Not used in this function. This is a dummy argument for 
+		*                     the correct instantiation of the templated function.
+		* \return The soft maximum value of this property */
+		template <class T> inline T GetSoftMax(const T* pFBX_TYPE) const { T lValue; GetSoftMax(&lValue, FbxTypeOf(lValue)); return lValue; }
+	//@}
+
+	/**
+	* \name Value 
+	*/
+	//@{
+		/** Get value inherit type of this property.
+		* \param pCheckReferences   If it is true,check instance of this property page,otherwise,only check this page.
+		* \return The value inherit type of this property */
+		FbxPropertyFlags::EInheritType GetValueInheritType(bool pCheckReferences) const;
+
+		/** Set value inherit type for this property .
+		* \param pType  The given value inherit type.
+		* \return If set successfully, return true,otherwise, return false. */
+		bool SetValueInheritType(FbxPropertyFlags::EInheritType pType);
+
+		/** Get default value and value type of this property .
+		* \param pValue  The gotten default value of this property.
+		* \param pValueType The gotten default value type of this property.
+		* \return If default value be gotten successfully, return true,otherwise, return false. */
+		bool GetDefaultValue(void* pValue, EFbxType pValueType) const;
+
+		/** Get value and value type of this property .
+		* \param pValue  The gotten value of this property.
+		* \param pValueType The gotten value type of this property.
+		* \return If value be gotten successfully, return true,otherwise, return false. */
+		bool Get(void* pValue, EFbxType pValueType) const;
+
+		/** Set property value and value type for this property.
+		* \param pValue    The given property value .
+		* \param pValueType The given property value type 
+		* \param pCheckValueEquality If it is true, when the given value is equal with
+		* the property value, the property value will not be set.
+		* \return If the property value be set successfully, return true,otherwise, return false. */
+		bool Set(const void* pValue, EFbxType pValueType, bool pCheckValueEquality);
+
+		/** Set property value with the given value .
+		* \param pValue  The given value .
+		* \return If set successfully, return true,otherwise, return false. */
+		template <class T> inline bool Set(const T& pValue){ return Set(&pValue, FbxTypeOf(pValue)); }
+
+		/** get property value.
+		* \param pFBX_TYPE  Not be used.
+		* \return The gotten property value. */
+		template <class T> inline T Get(const T* pFBX_TYPE) const { T lValue; Get(&lValue, FbxTypeOf(lValue)); return lValue; }
+	//@}
+
+	/**
+	* \name Page settings
+	*/
+	//@{
+		/** Set the property page data pointer.
+		* \param pData  The given page data pointer. */
+		void SetPageDataPtr(void* pData);
+
+		/** Get property page data pointer.
+		* \return The gotten property page data pointer. */
+		void* GetPageDataPtr() const;
+	//@}
+
+	/**
+	* \name Page Internal Entry Management
+	*/
+	//@{
+		/** Push properties to parent instance.
+		* \return If push successful return true,otherwise,return false. */
+		bool PushPropertiesToParentInstance();
+	//@}
+
+	/**
+	* \name Reference Management
+	*/
+	//@{
+		/** Judge if this property page is a instance of other page.
+		* \return If this property page is a instance of other page, return true,otherwise,return false. */
+		bool IsAReferenceTo(void) const;
+
+		/** Get the property page which this property page make reference to
+		* \return The property page which this property page make reference to */
+		void* GetReferenceTo(void) const;
+
+		/** Judge if this property page is referenced by other pages.
+		* \return If this property page is referenced by other pages, return true,otherwise,return false. */
+		bool IsReferencedBy(void) const;
+
+		/** Get the count of property pages which make reference to this property page.
+		* \return The count of property pages which make reference to this property page. */
+		int GetReferencedByCount(void) const;
+
+		/** According the given index,get the property page which make reference to this property page.
+		* \param pIndex The given index
+		* \return The pointer to the property page which reference to this property page and be found by index. */
+		void* GetReferencedBy(int pIndex) const; 
+	//@}
+
+private:
+	FbxPropertyPage*	mPage;
+	FbxInt				mId;
+};
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* _FBXSDK_CORE_PROPERTY_HANDLE_H_ */

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1736 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxpropertypage.h


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1174 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxpropertytypes.h


+ 260 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxquery.h

@@ -0,0 +1,260 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxquery.h
+#ifndef _FBXSDK_CORE_QUERY_H_
+#define _FBXSDK_CORE_QUERY_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#include <fbxsdk/core/fbxclassid.h>
+#include <fbxsdk/core/fbxconnectionpoint.h>
+#include <fbxsdk/core/base/fbxmap.h>
+#include <fbxsdk/core/base/fbxmemorypool.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+#define FBXSDK_QUERY_UNIQUE_ID 0x14000000
+
+class FbxProperty;
+
+/** Base class to manage query. A query contains a filter and reference ID, which will be used to search and retrieve objects. 
+* The derived query classes are used to create FbxCriteria.
+* \nosubgrouping */
+class FBXSDK_DLL FbxQuery
+{
+public:
+	//! Get unique filter Id
+	virtual FbxInt GetUniqueId() const { return FBXSDK_QUERY_UNIQUE_ID; }
+
+	/** Judge if the given property is valid.
+	* \param pProperty The given property.
+	* \return \c true always, not implemented. */
+	virtual bool IsValid(const FbxProperty& pProperty) const;
+
+	/** This compares whether two FbxQuery are the same, NOT whether the query matches or not. It's strictly the equivalent of an operator==, but virtual.
+	* \param pOtherQuery The given FbxQuery */
+	virtual bool IsEqual(FbxQuery* pOtherQuery) const;
+
+	//! Add one to ref count.
+	void Ref();
+
+	//! Minus one to ref count, if ref count is zero, delete this query object.
+	void Unref();
+
+/*****************************************************************************************************************************
+** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
+*****************************************************************************************************************************/
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+protected:
+    FbxQuery();
+    virtual ~FbxQuery();
+
+private:
+    class InternalFilter : public FbxConnectionPointFilter
+	{
+	public:
+		InternalFilter(FbxQuery* pQuery);
+		~InternalFilter();
+
+	public:
+		FbxConnectionPointFilter*	Ref();
+		void						Unref();
+		FbxInt						GetUniqueId() const { return mQuery->GetUniqueId(); }
+		bool						IsValid(FbxConnectionPoint* pConnect) const;
+		bool						IsEqual(FbxConnectionPointFilter* pConnectFilter) const;
+
+		FbxQuery*					mQuery;
+    };
+
+    InternalFilter	mFilter;
+    int				mRefCount;
+
+    FBXSDK_FRIEND_NEW();
+    friend class FbxProperty;
+#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
+};
+
+/** Defines a filtering criteria for a query of objects, connections and properties, so that only those satisfying the criteria are
+* affected by the query. Some examples of kinds of criteria are object type, connection type, or property. Criteria can be combined
+* using logical operators such as "and" and "or".
+* \note 
+* Objects are basic elements in FBX. Each of them has a hierarchy type and some properties. Objects and properties can be connected
+* through a connection to represent a relationship between them. (e.g. child-parent, container membership, reference, etc.,). In a
+* query, you could select object or properties based on these criteria.
+* Here are some examples:
+* \code
+* FbxObject* lObject = FbxObject::Create(lManager, "Object");
+* int lSrcLightCount = lObject->RootProperty.GetSrcObjectCount(FbxCriteria::ObjectType(FbxLight::ClassId));
+* int lSrcDeformerCount = lObject->RootProperty.GetSrcObjectCount(FbxCriteria::ObjectTypeStrict(FbxDeformer::ClassId));
+* int lSrcPropertyCount = lObject->RootProperty.GetSrcCount(FbxCriteria::IsProperty());
+* \endcode
+* \see FbxQuery
+* \see FbxProperty::GetSrcObjectCount(const FbxCriteria&) const
+* \see FbxCollection::GetMemberCount(const FbxCriteria&) const
+* \nosubgrouping */
+class FBXSDK_DLL FbxCriteria
+{
+public:
+	/** Creates a new query criteria that only selects objects which have a specific
+	* class ID or derive from a class with a specific class ID.
+	* \param pClassId The base type class ID */
+	static FbxCriteria ObjectType(const FbxClassId& pClassId);
+
+	/** Creates a new query criteria that only selects objects which have a specific class ID.
+	* \param pClassId The type class ID */
+	static FbxCriteria ObjectTypeStrict(const FbxClassId& pClassId);
+
+	//! Creates a new query criteria that only selects properties.
+	static FbxCriteria IsProperty();
+
+	/** Gets a logical conjunction (and) criteria from this and the specified criteria.
+	* \param pCriteria The specified criteria */
+	FbxCriteria operator&&(const FbxCriteria& pCriteria) const;
+
+	/** Gets a logical disjunction (or) criteria from this and the specified criteria.
+	* \param pCriteria The specified criteria */
+	FbxCriteria operator||(const FbxCriteria& pCriteria) const;
+
+	//! Returns a negated version of the criteria.
+	FbxCriteria operator!() const;
+
+	/** Retrieves the query.
+	* \return The query of this criteria */
+	FbxQuery* GetQuery() const;
+
+/*****************************************************************************************************************************
+** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
+*****************************************************************************************************************************/
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+	FbxCriteria();
+	FbxCriteria(const FbxCriteria& pCriteria);
+	FbxCriteria(FbxQuery* pQuery);
+	~FbxCriteria();
+
+	FbxCriteria& operator=(const FbxCriteria& pCriteria);
+
+private:
+    FbxQuery* mQuery;
+
+	static void FreeGlobalCache();
+
+    FBXSDK_FRIEND_NEW();
+	friend class FbxManager;
+#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
+};
+
+//! Functor to compare FbxCriteria
+struct FbxCriteriaCompare
+{
+	inline int operator()(const FbxCriteria& pKeyA, const FbxCriteria& pKeyB) const
+	{
+		const FbxQuery* lKeyA = pKeyA.GetQuery();
+		const FbxQuery* lKeyB = pKeyB.GetQuery();
+		return lKeyA < lKeyB ? -1 : (lKeyA > lKeyB ? 1 : 0);
+	}
+};
+
+/*****************************************************************************************************************************
+** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
+*****************************************************************************************************************************/
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+class FBXSDK_DLL FbxQueryOperator : public FbxQuery
+{
+public:
+    FBXSDK_FRIEND_NEW();
+
+	enum EType {eAND, eOR};
+
+    static FbxQueryOperator* Create(FbxQuery* pA, EType pOperator, FbxQuery* pB);
+    virtual FbxInt GetUniqueId() const { return FBXSDK_QUERY_UNIQUE_ID+1; }
+    virtual bool IsValid(const FbxProperty& pProperty) const;
+    virtual bool IsEqual(FbxQuery* pOtherQuery) const;
+
+protected:
+    FbxQueryOperator(FbxQuery* pA, EType pOperator, FbxQuery* pB);
+    virtual ~FbxQueryOperator();
+
+private:
+    FbxQuery	*mA, *mB;
+    EType		mOperator;
+};
+
+class FBXSDK_DLL FbxQueryOperatorUnary : public FbxQuery
+{
+public:
+    FBXSDK_FRIEND_NEW();
+
+    static FbxQueryOperatorUnary* Create(FbxQuery* pA);
+    virtual FbxInt GetUniqueId() const{ return FBXSDK_QUERY_UNIQUE_ID+2; }
+    virtual bool IsValid(const FbxProperty& pProperty) const;
+    virtual bool IsEqual(FbxQuery* pOtherQuery) const;
+
+protected:
+    FbxQueryOperatorUnary(FbxQuery* pA);
+    virtual ~FbxQueryOperatorUnary();
+
+private:
+    FbxQuery* mA;
+};
+
+class FBXSDK_DLL FbxQueryClassId : public FbxQuery
+{
+public:
+    FBXSDK_FRIEND_NEW();
+
+    static FbxQueryClassId* Create(const FbxClassId& pClassId);
+    virtual FbxInt GetUniqueId() const{ return FBXSDK_QUERY_UNIQUE_ID+3; }
+    virtual bool IsValid(const FbxProperty& pProperty) const;
+    virtual bool IsEqual(FbxQuery* pOtherQuery) const;
+
+protected:
+    FbxQueryClassId(const FbxClassId& pClassId);
+
+private:
+    FbxClassId	mClassId;
+};
+
+class FBXSDK_DLL FbxQueryIsA : public FbxQuery
+{
+public:
+    FBXSDK_FRIEND_NEW();
+
+    static FbxQueryIsA* Create(const FbxClassId& pClassId);       
+    virtual FbxInt GetUniqueId() const{ return FBXSDK_QUERY_UNIQUE_ID+4; }
+    virtual bool IsValid(const FbxProperty& pProperty) const;
+    virtual bool IsEqual(FbxQuery* pOtherQuery) const;
+
+protected:
+    FbxQueryIsA(const FbxClassId& pClassId);
+
+private:
+    FbxClassId mClassId;
+};
+
+class FBXSDK_DLL FbxQueryIsProperty : public FbxQuery
+{
+public:
+    FBXSDK_FRIEND_NEW();
+
+    static FbxQueryIsProperty* Create();
+    virtual FbxInt GetUniqueId() const{ return FBXSDK_QUERY_UNIQUE_ID+5; }
+    virtual bool IsValid(const FbxProperty& pProperty) const;
+    virtual bool IsEqual(FbxQuery* pOtherQuery) const;
+
+protected:
+    FbxQueryIsProperty();
+};
+#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* _FBXSDK_CORE_QUERY_H_ */

+ 57 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxqueryevent.h

@@ -0,0 +1,57 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxqueryevent.h
+#ifndef _FBXSDK_CORE_QUERY_EVENT_H_
+#define _FBXSDK_CORE_QUERY_EVENT_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#include <fbxsdk/core/fbxevent.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+/** A query event is something that is emitted by an entity, with the goal of being filled by someone that listen to it. 
+*  You can see that like a form that you send to some people. If those people know how to fill the form, they fill it and return
+*  it to you with the right information in it.  A query event is emitted, and plug-in who are listening to that type of query, 
+*  fill the data that can be accessed by the query emitter.
+*/
+template <typename QueryT> class FbxQueryEvent : public FbxEvent<FbxQueryEvent<QueryT> >
+{
+public:
+    /**
+    *\name Public interface
+    */
+    //@{
+    /** Constructor.
+	  * \param pData The requested data.  
+      */
+    explicit FbxQueryEvent(QueryT* pData):mData(pData){}
+
+    /** Accessor to a mutable reference to the data. Event are usually const and can't be modified by listener. 
+     * This special type of event can have is content modified via this accessor.
+     * \return A mutable reference the requested data.
+    */
+    QueryT& GetData()const { return *mData; }
+    //@}
+
+private:
+    mutable QueryT* mData;
+
+private:
+    virtual const char* GetEventName() const { FBX_ASSERT(false); return ""; }
+    static const char* FbxEventName() { FBX_ASSERT(false); return ""; }
+    friend class FbxEvent< FbxQueryEvent<QueryT> >;
+};
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* _FBXSDK_CORE_QUERY_EVENT_H_ */

+ 58 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxscopedloadingdirectory.h

@@ -0,0 +1,58 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxscopedloadingdirectory.h
+#ifndef _FBXSDK_CORE_SCOPED_LOADING_DIRECTORY_H_
+#define _FBXSDK_CORE_SCOPED_LOADING_DIRECTORY_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#ifndef FBXSDK_ENV_WINSTORE
+
+#include <fbxsdk/core/fbxloadingstrategy.h>
+#include <fbxsdk/core/fbxmodule.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+class FbxPluginHandle;
+
+//! A plug-in loading strategy that loads all DLLs with a specific extension from a specific directory. When this class is destroyed all of the plug-ins are unloaded.
+class FBXSDK_DLL FbxScopedLoadingDirectory : public FbxLoadingStrategy
+{
+public:
+	/** Constructor, which also load plug-ins in the folder specified.
+	* \param pDirectoryPath The directory path.
+	* \param pPluginExtension The plug-in extension. */
+	FbxScopedLoadingDirectory(const char* pDirectoryPath, const char* pPluginExtension);
+
+	/** Destructor. Unload plug-ins. */
+	virtual ~FbxScopedLoadingDirectory();
+
+/*****************************************************************************************************************************
+** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
+*****************************************************************************************************************************/
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+private:
+	virtual bool SpecificLoad(FbxPluginData& pData);
+	virtual void SpecificUnload(FbxPluginData& pData);
+
+	FbxString mDirectoryPath;
+	FbxString mExtension;
+
+	FbxArray<FbxModule> mPluginHandles;
+#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
+};
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* !FBXSDK_ENV_WINSTORE */
+
+#endif /* _FBXSDK_CORE_SCOPED_LOADING_DIRECTORY_H_ */

+ 64 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxscopedloadingfilename.h

@@ -0,0 +1,64 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxscopedloadingfilename.h
+#ifndef _FBXSDK_CORE_SCOPED_LOADING_FILENAME_H_
+#define _FBXSDK_CORE_SCOPED_LOADING_FILENAME_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#ifndef FBXSDK_ENV_WINSTORE
+
+#include <fbxsdk/core/fbxloadingstrategy.h>
+#include <fbxsdk/core/fbxmodule.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+/** 
+ * A plug-in loading strategy that loads a single DLL by specifying the file name in the constructor, and unloads the DLL in its destructor.
+ */
+class FBXSDK_DLL FbxScopedLoadingFileName : public FbxLoadingStrategy
+{
+public:
+    /**
+     *\name Public interface
+     */
+    //@{
+		/** Constructor.
+		  * Load plug-in.
+		  * \param pPath The file path.
+		  */
+		explicit FbxScopedLoadingFileName(const char* pPath);
+
+		/** Destructor.
+		 * Unload plug-in.
+		 */
+		virtual ~FbxScopedLoadingFileName();
+    //@}
+
+/*****************************************************************************************************************************
+** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
+*****************************************************************************************************************************/
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+private:
+    virtual bool SpecificLoad(FbxPluginData& pData);
+    virtual void SpecificUnload(FbxPluginData& pData);
+
+    FbxModule mInstance;
+    FbxString mPath;
+#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
+};
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* !FBXSDK_ENV_WINSTORE */
+
+#endif /* _FBXSDK_CORE_SCOPED_LOADING_FILENAME_H_ */

+ 126 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxstream.h

@@ -0,0 +1,126 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxstream.h
+#ifndef _FBXSDK_CORE_STREAM_H_
+#define _FBXSDK_CORE_STREAM_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#include <fbxsdk/core/base/fbxfile.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+/** Abstract class for implementing I/O operations through a stream of data.
+* For instance, it can be used to read data from a memory source, thus making it possible to import files from memory. However, 
+* for the time being, the FbxStream class is only supported with FBX files. 
+*/
+class FBXSDK_DLL FbxStream
+{
+public:
+	/** Current stream state. */
+	enum EState
+	{
+		eClosed,	//!< The stream is closed.
+		eOpen,		//!< The stream is open.
+		eEmpty		//!< The stream is empty.
+	};
+
+	/** Query the current state of the stream. */
+	virtual EState GetState() = 0;
+
+	/** Open the stream.
+	* \return True if successful.
+	* \remark Each time the stream is open or closed, the stream position must be reset to zero. */
+	virtual bool Open(void* pStreamData) = 0;
+
+	/** Close the stream.
+	* \return True if successful.
+	* \remark Each time the stream is open or closed, the stream position must be reset to zero. */
+	virtual bool Close() = 0;
+
+	/** Empties the internal data of the stream.
+	* \return True if successful. */
+	virtual bool Flush() = 0;
+
+	/** Writes a memory block.
+	* \param pData Pointer to the memory block to write.
+	* \param pSize Size (in bytes) of the memory block to write.
+	* \return The number of bytes written in the stream. */
+	virtual int Write(const void* /*pData*/, int /*pSize*/) = 0;
+
+	/** Read bytes from the stream and store them in the memory block.
+	* \param pData Pointer to the memory block where the read bytes are stored.
+	* \param pSize Number of bytes read from the stream.
+	* \return The actual number of bytes successfully read from the stream. */
+	virtual int Read(void* /*pData*/, int /*pSize*/) const = 0;
+
+	/** Read a string from the stream.
+	* The default implementation is written in terms of Read() but does not cope with DOS line endings.
+	* Subclasses may need to override this if DOS line endings are to be supported.
+	* \param pBuffer Pointer to the memory block where the read bytes are stored.
+	* \param pMaxSize Maximum number of bytes to be read from the stream.
+	* \param pStopAtFirstWhiteSpace Stop reading when any whitespace is encountered. Otherwise read to end of line (like fgets()).
+	* \return pBuffer, if successful, else NULL.
+	* \remark The default implementation terminates the \e pBuffer with a null character and assumes there is enough room for it.
+	* For example, a call with \e pMaxSize = 1 will fill \e pBuffer with the null character only. */
+	virtual char* ReadString(char* pBuffer, int pMaxSize, bool pStopAtFirstWhiteSpace=false);
+
+	/** If not specified by KFbxImporter::Initialize(), the importer will ask
+	* the stream to select an appropriate reader ID to associate with the stream.
+	* FbxIOPluginRegistry can be used to locate id by extension or description.
+	* Return -1 to allow FBX to select an appropriate default. */
+	virtual int GetReaderID() const = 0;
+
+	/** If not specified by KFbxExporter::Initialize(), the exporter will ask
+	* the stream to select an appropriate writer ID to associate with the stream.
+	* KFbxIOPluginRegistry can be used to locate id by extension or description.
+	* Return -1 to allow FBX to select an appropriate default. */
+	virtual int GetWriterID() const = 0;
+
+	/** Adjust the current stream position.
+	* \param pSeekPos Pre-defined position where offset is added (FbxFile::eBegin, FbxFile::eCurrent:, FbxFile::eEnd)
+	* \param pOffset Number of bytes to offset from pSeekPos. */
+	virtual void Seek(const FbxInt64& pOffset, const FbxFile::ESeekPos& pSeekPos)=0;
+
+	/** Get the current stream position.
+	* \return Current number of bytes from the beginning of the stream. */
+	virtual long GetPosition() const = 0;
+
+	/** Set the current stream position.
+	* \param pPosition Number of bytes from the beginning of the stream to seek to. */
+	virtual void SetPosition(long pPosition)=0;
+
+	/** Return 0 if no errors occurred. Otherwise, return 1 to indicate
+	* an error. This method will be invoked whenever FBX needs to verify
+	* that the last operation succeeded. */
+	virtual int GetError() const = 0;
+
+	/** Clear current error condition by setting the current error value to 0. */
+	virtual void ClearError() = 0;
+
+/*****************************************************************************************************************************
+** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
+*****************************************************************************************************************************/
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+	FbxStream(){};
+	virtual ~FbxStream(){};
+
+	int Write(const char* pData, int pSize){ return Write((void*)pData, pSize); }
+	int Write(const int* pData, int pSize){ return Write((void*)pData, pSize); }
+	int Read(char* pData, int pSize) const { return Read((void*)pData, pSize); }
+	int Read(int* pData, int pSize) const { return Read((void*)pData, pSize); }
+#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
+};
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* _FBXSDK_CORE_STREAM_H_ */

+ 135 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxsymbol.h

@@ -0,0 +1,135 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxsymbol.h
+#ifndef _FBXSDK_CORE_SYMBOL_H_
+#define _FBXSDK_CORE_SYMBOL_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#include <fbxsdk/core/base/fbxstring.h>
+#include <fbxsdk/core/base/fbxmap.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+/** Defines a symbol string. A symbol string is a string that is unique and stored in a global symbol table.
+* \nosubgrouping */
+class FBXSDK_DLL FbxSymbol
+{
+public:
+    /**
+    * \name Constructors and Destructor
+    */
+    //@{
+
+    /** Constructor.
+    * Construct a symbol and add it to global symbol table.
+    * \param pName Symbol name.
+    * \param pRealm The real value for this symbol. 
+    */
+    FbxSymbol(const char* pName, const char* pRealm);
+
+    //! Destructor.
+    ~FbxSymbol();
+    //@}
+
+    /**
+    * \name Access function.
+    */
+    //@{
+    /**
+    * Get ID in global symbol table.
+    * \return Symbol ID in global symbol table.
+    */
+    unsigned int GetID() const;
+    //@}
+
+    /**
+    * \name Symbol comparison
+    */
+    //@{
+    /** Equality operator.
+    * \param pSymbol The symbol to be compared. 
+    */
+    bool operator==(FbxSymbol const& pSymbol) const;
+
+    /** Inequality operator.
+    * \param pSymbol The symbol to be compared. 
+    */
+    bool operator!=(FbxSymbol const& pSymbol) const;
+    //@}
+
+private:
+    unsigned int mID;
+};
+
+typedef FbxMap< FbxString, int, FbxStringCompare > FbxStringSymbolMap;
+
+
+/** This class is to mark a string as symbol.
+  * String Symbol only has its name.
+  * /remarks Each symbol is unique. That means there are no symbols which have the same name.
+* \nosubgrouping */
+class FBXSDK_DLL FbxStringSymbol
+{
+public:
+    /**
+    * \name Constructors and Destructor
+    */
+    //@{
+
+    //! Default constructor.
+    FbxStringSymbol();
+
+    /** Constructor.
+    * Construct a symbol and add it to global symbol table.
+    * \param pName Symbol name.
+    */
+    FbxStringSymbol(const char* pName);
+
+    //! Copy constructor.
+    FbxStringSymbol(const FbxStringSymbol& pOther);
+
+    //! Destructor.
+    ~FbxStringSymbol();
+    //@}
+
+    //! Cast operator to const char* type.
+    inline operator const char*() const { return mItem ? ((const char*) mItem->GetKey()) : NULL; }
+
+
+    /** Determine the symbol empty or not.
+    * \return \c true if empty. \c false otherwise.
+    */    
+    inline bool IsEmpty() const
+    {
+        return !mItem || mItem->GetKey().IsEmpty();
+    }
+
+    //! Static function to allocate global string symbol map.
+    static void AllocateGlobalStringSymbolMap();
+
+    //! Static function to deallocate global string symbol map.
+    static void FreeGlobalStringSymbolMap();
+
+    /** Assignment operator.
+    * \param pName  The symbol value. 
+    * \return       The self after assignment.
+    */
+    FbxStringSymbol& operator=(const char* pName);
+
+private:
+    FbxStringSymbolMap::RecordType* mItem;
+};
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* _FBXSDK_CORE_SYMBOL_H_ */

+ 219 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxsystemunit.h

@@ -0,0 +1,219 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxsystemunit.h
+#ifndef _FBXSDK_CORE_SYSTEM_UNIT_H_
+#define _FBXSDK_CORE_SYSTEM_UNIT_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#include <fbxsdk/core/base/fbxstring.h>
+#include <fbxsdk/core/base/fbxarray.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+class FbxAMatrix;
+class FbxScene;
+class FbxNode;
+class FbxAnimCurveNode;
+
+/** \brief This class describes the units of measurement used within a particular scene.
+  * \nosubgrouping
+  */
+class FBXSDK_DLL FbxSystemUnit 
+{
+public:
+
+    /** Struct to define various options that you can use to convert the system unit of a scene.
+      * The default values are:
+      *         mConvertRrsNodes = true
+      *         mConvertLimits = true
+      *         mConvertClusters = true
+      *         mConvertLightIntensity = true
+      *         mConvertPhotometricLProperties = true
+      *         mConvertCameraClipPlanes = true
+      *
+      * The default configuration have been tested to give the best conversion results in the majority of the case. 
+      * \remark Changing any of these values will have a direct impact on the whole scene behavior. 
+      */
+    struct ConversionOptions
+    {
+        //! This flag indicates whether or not to convert the nodes that do not inherit their parent's scale.
+        bool mConvertRrsNodes;  
+
+        //! This flag indicates whether or not to convert limits.
+        bool mConvertLimits;
+
+        //! This flag indicates whether or not to convert clusters.
+        bool mConvertClusters;
+
+        //! This flag indicates whether or not to convert the light intensity property.
+        bool mConvertLightIntensity;	
+
+        //! This flag indicates whether or not to convert photometric lights properties.
+        bool mConvertPhotometricLProperties;
+
+        //! This flag indicates whether or not to convert the cameras clip planes.
+        bool mConvertCameraClipPlanes;
+    };
+
+	FbxSystemUnit();
+
+    /** Constructor.
+      * \param pScaleFactor The equivalent number of centimeters in the new system unit. 
+      *                     For example, an inch unit uses a scale factor of 2.54.
+      * \param pMultiplier  A multiplier factor of pScaleFactor.
+      */
+    FbxSystemUnit(double pScaleFactor, double pMultiplier = 1.0);
+
+    /** Destructor.
+      */
+    ~FbxSystemUnit();
+
+    //! Predefined system unit for millimeters.
+    static const FbxSystemUnit mm;
+
+    //! Predefined system unit for decimeters.
+    static const FbxSystemUnit dm;
+
+    //! Predefined system unit for centimeters.
+    static const FbxSystemUnit cm;
+
+    //! Predefined system unit for meters.
+    static const FbxSystemUnit m;
+
+    //! Predefined system unit for kilometers.
+    static const FbxSystemUnit km;
+
+    //! Predefined system unit for inches.
+    static const FbxSystemUnit Inch;
+
+    //! Predefined system unit for feet.
+    static const FbxSystemUnit Foot;
+    
+    //! Predefined system unit for miles.
+    static const FbxSystemUnit Mile;
+
+    //! Predefined system unit for yards.
+    static const FbxSystemUnit Yard;
+
+    #define FBXSDK_SYSTEM_UNIT_PREDEF_COUNT 9
+
+    //! Points to a FbxSystemUnit array to store the predefined system units. The array size is FBXSDK_SYSTEM_UNIT_PREDEF_COUNT.
+    static const FbxSystemUnit *sPredefinedUnits;
+
+    //! Stores the default conversion options.
+    static const ConversionOptions DefaultConversionOptions;
+
+    /** Converts a scene from its system units to this system unit.
+      * \param pScene The scene to convert.
+      * \param pOptions Conversion options, see:FbxSystemUnit::ConversionOptions.
+      */
+    void ConvertScene( FbxScene* pScene, const ConversionOptions& pOptions = DefaultConversionOptions ) const;
+
+    /** Converts the child (or children) of the given node from the system unit to this system unit.
+      * Unlike the ConvertScene() method, this method does not set the axis system 
+      * of the scene to which the pRoot node belongs. It also does not adjust FbxPose
+      * as they are not stored under the scene, and not under a particular node.
+      * \param pRoot The given node.
+      * \param pSrcUnit The source system unit.
+      * \param pOptions Conversion options, see:FbxSystemUnit::ConversionOptions.
+      */
+    void ConvertChildren( FbxNode* pRoot, const FbxSystemUnit& pSrcUnit, const ConversionOptions& pOptions = DefaultConversionOptions ) const;
+
+    /** Converts a scene from its system unit to this system unit, using the specified 
+      * Fbx_Root node. This method is provided for backwards compatibility only
+      * and instead you should use ConvertScene( FbxScene* , const ConversionOptions&  ) whenever possible.
+      * \param pScene The scene to convert.
+      * \param pFbxRoot The Fbx_Root node to use for conversion.
+      * \param pOptions Conversion options, see:FbxSystemUnit::ConversionOptions
+      */
+    void ConvertScene( FbxScene* pScene, FbxNode* pFbxRoot, const ConversionOptions& pOptions = DefaultConversionOptions ) const;
+
+    /** Returns the system unit's scale factor, relative to centimeters.
+      * This factor scales system unit values to centimeters. If you want to scale values to centimeters, use this value.
+      * Ignore the "multiplier" (returned by GetMultiplier()) value. 
+      * \return The the system unit's scale factor, relative to centimeters.
+      */
+    double GetScaleFactor() const;
+
+    /** Returns a unit label for the current scale factor.
+      * \param pAbbreviated If \c true, returns abbreviated string. 
+      * \return The unit label for the current scale factor.
+      */
+    FbxString GetScaleFactorAsString(bool pAbbreviated = true) const;
+
+    /** Returns a unit label for the current scale factor. 
+      * The first letter of the label is in upper case and the label should be pluralized. 
+      * \return The unit label for the current scale factor.
+      */
+    FbxString GetScaleFactorAsString_Plurial() const;
+
+    /** Returns the multiplier factor of the system unit.
+      */
+    double GetMultiplier() const;
+
+    /** Equivalence operator.
+      * \param pOther Another system unit compared with this system unit.
+      * \return \c True if equal, \c false otherwise.
+      */   
+    bool operator==(const FbxSystemUnit& pOther) const;
+
+    /** Non-equivalence operator.
+      * \param pOther Another system unit compared with this system unit.
+      * \return \c True if unequal, \c false otherwise.
+      */  
+    bool operator!=(const FbxSystemUnit& pOther) const;
+
+    /** Assignment operation.
+      * \param pSystemUnit Unit system assigned to this one.
+      */
+	FbxSystemUnit& operator=(const FbxSystemUnit& pSystemUnit);
+
+    /** Returns the conversion factor from this system unit to the target system unit, excluding the multiplier factor.
+      * \param pTarget The target system unit.
+      */
+    double GetConversionFactorTo( const FbxSystemUnit& pTarget ) const;
+
+    /** Returns the conversion factor from the source system unit to this system unit, excluding the multiplier factor.
+      * \param pSource The source system unit.
+      */
+    double GetConversionFactorFrom( const FbxSystemUnit& pSource ) const;
+
+/*****************************************************************************************************************************
+** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
+*****************************************************************************************************************************/
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+private:
+    void ApplyMultiplier(FbxNode* pRoot, bool pSubChildrenOnly) const;
+    void ConvertSTProperties(FbxArray<FbxNode*>& pNodes, double pConversionFactor) const;
+    void ConvertSProperty(FbxArray<FbxNode*>& pNodes, double pConversionFactor) const;
+    void ConvertAnimCurveNode(FbxArray<FbxAnimCurveNode*>& pFCurves, double pConversionFactor) const;
+    double GetConversionFactor(double pTargetScaleFactor, double pSourceScaleFactor) const;
+    void AdjustPivots(FbxNode* pNode, double pConversionFactor, FbxAMatrix& pOriginalGlobalM ) const;
+    void AdjustLimits(FbxNode* pNode, double pConversionFactor) const;
+    void AdjustPoses(FbxScene* pScene, double pConversionFactor) const;
+    void AdjustCluster(FbxNode* pNode, double pConversionFactor) const;
+    void AdjustLightIntensity(FbxNode* pNode, const double pConversionFactor) const;
+    void AdjustPhotometricLightProperties(FbxNode* pNode, const double pConversionFactor) const;
+    void AdjustCameraClipPlanes(FbxNode* pNode, const double pConversionFactor) const;
+    void ConvertChildren(FbxNode* pRoot, const FbxSystemUnit& pSrcUnit, bool pSubChildrenOnly, const ConversionOptions& pOptions) const;
+
+    double mScaleFactor;
+    double mMultiplier;
+
+    friend class FbxGlobalSettings;
+#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
+};
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* _FBXSDK_CORE_SYSTEM_UNIT_H_ */

+ 227 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxxref.h

@@ -0,0 +1,227 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxxref.h
+#ifndef _FBXSDK_CORE_XREF_H_
+#define _FBXSDK_CORE_XREF_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#include <fbxsdk/core/base/fbxarray.h>
+#include <fbxsdk/core/base/fbxstring.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+class FbxProperty;
+class FbxDocument;
+class FbxXRefManagerProject;
+
+/** This class manages external references to files.
+  * \nosubgrouping
+  */
+class FBXSDK_DLL FbxXRefManager
+{
+public:
+    //! Default constructor.
+    FbxXRefManager();
+
+    //! Destructor.
+    virtual ~FbxXRefManager();
+
+    /**
+      * \name Predefined Project Types
+      */
+    //@{
+
+        //! This project represents an URL for storing temporary files.
+        static const char* sTemporaryFileProject;
+
+        //! This project represents an URL for configuration files.
+        static const char* sConfigurationProject;
+
+        //! This project represents an URL for storing localization files (that is not part of the asset library).
+        static const char* sLocalizationProject;
+
+        /** This project is used for creating the ".fbm" folders that are used for
+          * storing embedded resources in FBX files.
+          *  
+          * When not set, or if the folder is not writable, the ".fbm"
+          * folder is created alongside the FBX file.
+          *  
+          * If we cannot write in that folder, we look at the sTemporaryFileProject location.
+          * If no folder is set in the sTemporaryFileProject location, or it is not
+          * writable, the operating system's Temp folder becomes the location.
+          */
+        static const char* sEmbeddedFileProject;
+    //@}
+
+    /**
+      * \name XRef URL properties
+      */
+    //@{
+        /** Returns the number of URLs that are stored in a property.
+		  * \param pProperty                The property. 
+          * \return                         The URL count.
+          */
+        static int     GetUrlCount(FbxProperty const &pProperty);
+
+        /** Returns the number of URLs that are stored in a string.
+		  * \param pUrl                     The string.
+		  * \return                         The URL count.
+		  */
+		 
+        static int     GetUrlCount(FbxString const& pUrl);
+
+        /** Checks whether the URL at the given index stored in the property is relative or not.
+		  * \param pProperty                The property.
+		  * \param pIndex                   The URL index.
+          * \return                         \c True if the URL is relative, \c false if the URL is not relative.
+          */
+        static bool IsRelativeUrl  (FbxProperty const &pProperty,int pIndex);
+
+        /** Returns the URL stored in the property at the given index.
+		  * \param pProperty                The property.
+		  * \param pIndex                   The URL index.
+          * \return The URL
+          */
+        static FbxString GetUrl(FbxProperty const &pProperty,int pIndex);
+
+        /** Tries to resolve the URL stored in the property at the given index.
+		  * \param pProperty                The property.
+		  * \param pIndex                   The URL index.
+		  * \param pResolvedPath            Filled with the resolved path.
+          * \return                         \c True if the URL is resolved, return \c false if the URL is not resolved.
+          */
+        bool GetResolvedUrl (FbxProperty const &pProperty,int pIndex,FbxString & pResolvedPath) const;
+    
+        /** Tries to resolve the specified URL.
+		  * \param pUrl                     The specified URL.
+		  * \param pDoc                     The document whose ".fbm" folder is used to resolve the URL.
+		  * \param pResolvedPath            Filled with the resolved path.
+          * \return                         \c True if the URL is resolved, return \c false if the URL is not resolved.
+          */
+        bool GetResolvedUrl (const char* pUrl, FbxDocument* pDoc, FbxString& pResolvedPath) const;
+    //@}
+
+        /** Looks for the first file that matches a specified "pattern",
+          * which is built as:
+          *
+          * if pOptExt is given:         prefix*.ext
+          * If pOptExt is NULL:          prefix*
+          * if pOptExt is "" or ".":     prefix*.
+          *
+          * Returns the URL of the first matching files. This function cannot be
+          * used to resolve folders, only files.
+          *
+          * If a document is given, we start by looking at the document's ".fbm" folder.
+	      * \param pPrefix                  The prefix of the pattern.
+	      * \param pOptExt                  The extension of the pattern.
+	      * \param pDoc                     The given document.
+	      * \param pResolvedPath            Filled with the first matching URL.
+	      * \return                         \c True if one matching file is found, returns \c false if no matching file is found.
+          */
+        bool GetFirstMatchingUrl(const char* pPrefix, const char* pOptExt, const FbxDocument* pDoc, FbxString& pResolvedPath) const;
+
+    /**
+      * \name XRef Resolve URL and Projects
+      */
+    //@{
+
+        /** Adds an XRef Project.
+          * Note:Only one URL is associated with a project. Calling 
+          * this on an existing project replaces the project's existing URL.
+          * \param pName                    The name of the project
+          * \param pUrl                     The URL to be associated with the project.
+          * \return                         \c True if the project is added successfully, \c false if no project is added.
+         */
+        bool        AddXRefProject   (const char *pName,const char *pUrl);
+
+        /** Adds an XRef Project.
+          * Note:Only one URL is associated with a project. Calling 
+          * this on an existing project replaces the project's existing URL.
+          * \param pName                    The name of the project
+		  * \param pExtension               The extension of the project.
+          * \param pUrl                     The URL to be associated with the project.
+          * \return                         \c True if the project is added successfully, returns \c false if no project is added.
+         */
+        bool        AddXRefProject   (const char *pName,const char *pExtension,const char *pUrl);
+
+        /** Adds an XRef project based on the document's EmbeddedUrl 
+          * property if set, if EmbeddedUrl is not set, based on its current URL property. 
+          * \param pDoc                     The document used to name the project and to specify the URL.
+          * \return                         \c True if the project is added successfully, returns \c false if no project is added.
+          * \remarks                        The project name is set as the document name and the URL is set as EmbeddedUrl or URL of the document.
+          */
+        bool        AddXRefProject   (FbxDocument* pDoc);
+
+		/** Removes an XRef Projects.
+		  * \param pName                    The name of the project to be removed.
+		  * \return                         \c True if the project is removed successfully, returns \c false if the project with the name does not exist.
+		  */
+        bool        RemoveXRefProject(const char *pName);
+
+		/** Removes all XRef Projects. 
+          * \return                         \c True always.
+          */
+        bool        RemoveAllXRefProjects();
+
+        /** Returns the number of XRef Projects.
+		  * \return                         The number of XRef Projects.
+		  */
+        int         GetXRefProjectCount() const;
+
+		/** Returns the name of the XRef project at the specified index.
+		  * \param pIndex                   The XRef project index.
+		  * \return                         The XRef project name.
+		  */
+        const char *GetXRefProjectName(int pIndex) const;
+
+        /** Returns the base URL for the given project.
+          * \param pName                    The name of the given project
+          * \return                         The base URL of the project or returns NULL if the project with the name is not found.
+          */
+        const char* GetXRefProjectUrl(const char* pName);   // FIXME: Should be const, will break AV.
+
+        /** Returns the base URL for the given project.
+          * \param pName                    The name of the given project
+          * \return                         The base URL of the project or returns NULL if the project with the name is not found.
+          */
+        const char* GetXRefProjectUrl(const char* pName) const;
+
+        /** Returns the base URL for the given project.
+          * \param pIndex                   The index of the project.
+          * \return                         The base URL of the project or NULL if the index is out of bounds.
+          */
+        const char* GetXRefProjectUrl(int pIndex) const;
+
+        /** Checks if a project with the given name is defined in this manager.
+		  * \param pName                    The name of the project.
+		  * \return                         \c True if the project is defined in this manager, returns \c false if it isn't defined in this manager.
+		  */
+        inline bool HasXRefProject( const char* pName ) { return GetXRefProjectUrl(pName) != NULL; }
+
+        /** Tries to resolve an relative URL
+		  * \param pUrl                     The relative URL to be resolved.
+		  * \param pResolvePath             Filled with the resolved path.
+          * \return                         \c True if the URL is resolved, returns \c false if the URL is not resolved.
+          */
+        bool GetResolvedUrl (const char* pUrl,FbxString & pResolvePath) const;
+
+    //@}
+private:
+    FbxArray<FbxXRefManagerProject*>    mProjects;
+
+    static bool UrlExist(const char* pUrl);
+};
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* _FBXSDK_CORE_XREF_H_ */

+ 340 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/math/fbxaffinematrix.h

@@ -0,0 +1,340 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxaffinematrix.h
+#ifndef _FBXSDK_CORE_MATH_AFFINE_MATRIX_H_
+#define _FBXSDK_CORE_MATH_AFFINE_MATRIX_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#include <fbxsdk/core/math/fbxvector4.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+/**	FBX SDK affine matrix class.
+  * \nosubgrouping
+  * Matrices are defined using the Column Major scheme. When a FbxAMatrix represents a transformation (translation, rotation and scale), 
+  * the last row of the matrix represents the translation part of the transformation.
+  *
+  * \remarks It is important to realize that an affine matrix must respect a certain structure.  To be sure the structure is respected,
+  * use SetT, SetR, SetS, SetQ, SetTRS or SetTQS.  If by mistake bad data is entered in this affine matrix, some functions such as 
+  * Inverse() will yield wrong results.  If a matrix is needed to hold values that aren't associate with an affine matrix, please use FbxMatrix instead.
+  */
+class FBXSDK_DLL FbxAMatrix : public FbxDouble4x4
+{
+public:
+	/**
+	  * \name Constructors and Destructor
+	  */
+	//@{
+		//! Constructor.
+		FbxAMatrix();
+
+		/** Copy constructor.
+		  * \param pOther FbxAMatrix copied to this one.
+		  */
+		FbxAMatrix(const FbxAMatrix& pOther);
+
+		/** Constructor.
+		  *	\param pT     Translation vector.
+		  *	\param pR     Euler rotation vector.
+		  *	\param pS     Scale vector.
+		  */
+		FbxAMatrix(const FbxVector4& pT, const FbxVector4& pR, const FbxVector4& pS);
+
+		//! Destructor.
+		~FbxAMatrix();
+	//@}
+
+	/**
+	  * \name Access
+	  */
+	//@{
+		/** Retrieve matrix element.
+		  *	\param pY     Row index.
+		  *	\param pX     Column index.
+		  * \return       Cell [ pX, pY ] value.
+		  */
+		double Get(int pY, int pX) const;
+
+		/** Extract translation vector.
+		  * \return     Translation vector.
+		  */
+		FbxVector4 GetT() const;
+
+		/** Extract rotation vector.
+		  * \return     Rotation vector.
+		  * \remarks    The returned rotation vector is in Euler angle and the rotation order is XYZ.
+		  */
+		FbxVector4 GetR() const;
+
+		/** Extract quaternion vector.
+		  * \return     Quaternion vector.
+		  */
+		FbxQuaternion GetQ() const;
+
+		/** Extract scale vector.
+		  * \return     Scale vector.
+		  */
+		FbxVector4 GetS() const;
+
+		/** Extract a row vector.
+		  *	\param pY     Row index.
+		  * \return       The row vector.
+		  */
+		FbxVector4 GetRow(int pY) const;
+
+		/** Extract a column vector.
+		  *	\param pX     Column index.
+		  * \return       The column vector.
+		  */
+		FbxVector4 GetColumn(int pX) const;
+
+		//! Set matrix to identity.
+		void SetIdentity();
+
+		/** Set matrix's translation.
+		  * \param pT     Translation vector.
+		  */
+		void SetT(const FbxVector4& pT);
+
+		/** Set matrix's Euler rotation.
+		  * \param pR     X, Y and Z rotation values expressed as a vector.
+		  * \remarks      The rotation transform is constructed in rotation order XYZ.
+		  */
+		void SetR(const FbxVector4& pR);
+
+		/** Set matrix's quaternion.
+		  * \param pQ     The new quaternion.
+		  */
+		void SetQ(const FbxQuaternion& pQ);
+
+		/** Set matrix's scale.
+		  * \param pS     X, Y and Z scaling factors expressed as a vector.
+		  */
+		void SetS(const FbxVector4& pS);
+
+		/** Set matrix.
+		  *	\param pT     Translation vector.
+		  *	\param pR     Rotation vector.
+		  *	\param pS     Scale vector.
+		  */
+		void SetTRS(const FbxVector4& pT, const FbxVector4& pR, const FbxVector4& pS);
+
+		/** Set matrix.
+		  *	\param pT     Translation vector.
+		  *	\param pQ     Quaternion vector.
+		  *	\param pS     Scale vector.
+		  */
+		void SetTQS(const FbxVector4& pT, const FbxQuaternion& pQ, const FbxVector4& pS);
+
+		/** Assignment operator.
+		  * \param pM FbxAMatrix assigned to this one.
+		  */
+		FbxAMatrix& operator=(const FbxAMatrix& pM);
+	//@}
+
+	/**
+	  * \name Scalar Operations
+	  */
+	//@{
+		/** Multiply matrix by a scalar value.
+		  * \param pValue     Scalar value.
+		  * \return           The scaled matrix.
+		  * \remarks          The passed value is not checked. 
+		  *                   This operator operates on the first three rows and columns of the matrix. 
+		  *                   So only the rotation and scaling are scaled, not the translation part.
+		  *                   After operation, the translation vector will be set as (0,0,0,1);
+		  */
+		FbxAMatrix operator*(double pValue) const;
+
+		/** Divide matrix by a scalar value.
+		  * \param pValue     Scalar value.
+		  * \return           The divided matrix.
+		  * \remarks          The passed value is not checked.
+		  *                   This operator operates on the first three rows and columns of the matrix. 
+		  *                   So only the rotation and scaling are scaled, not the translation part. 
+		  *                   After operation, the translation vector will be set as (0,0,0,1);
+		  */
+		FbxAMatrix operator/(double pValue) const;
+
+		/** Multiply matrix by a scalar value.
+		  * \param pValue     Scalar value.
+		  * \return           \e this updated with the result of the multiplication.
+		  * \remarks          The passed value is not checked.
+		  *                   This operator operates on the first three rows and columns of the matrix. 
+		  *                   So only the rotation and scaling are scaled, not the translation part. 
+		  *                   After operation, the translation vector will keep original value.
+		  */
+		FbxAMatrix& operator*=(double pValue);
+
+		/** Divide matrix by a scalar value.
+		  * \param pValue     Scalar value.
+		  * \return           \e this updated with the result of the division.
+		  * \remarks          The passed value is not checked.
+		  *                   This operator operates on the first three rows and columns of the matrix. 
+		  *                   So only the rotation and scaling are scaled, not the translation part. 
+		  *                   After operation, the translation vector will keep original value.
+		  */
+		FbxAMatrix& operator/=(double pValue);
+	//@}
+
+	/**
+	  * \name Vector Operations
+	  */
+	//@{
+		/** Multiply matrix by a translation vector.
+		  * \param pVector4     Translation vector.
+		  * \return             t' = M * t
+		  */
+		FbxVector4 MultT(const FbxVector4& pVector4) const;
+
+		/** Multiply matrix by an Euler rotation vector.
+		  * \param pVector4     Euler Rotation vector.
+		  * \return             r' = M * r
+		  */
+		FbxVector4 MultR(const FbxVector4& pVector4) const;
+		
+		/** Multiply matrix by a quaternion.
+		  * \param pQuaternion     Rotation value.
+		  * \return                q' = M * q
+		  */
+		FbxQuaternion MultQ(const FbxQuaternion& pQuaternion) const;
+
+		/** Multiply matrix by a scale vector.
+		  * \param pVector4     Scaling vector.
+		  * \return             s' = M * s
+		  */
+		FbxVector4 MultS(const FbxVector4& pVector4) const;
+	//@}
+
+	/**
+	  * \name Matrix Operations
+	  */
+	//@{	
+		/**	Unary minus operator.
+		  * \return     A matrix where each element is multiplied by -1.
+		  */
+		FbxAMatrix operator-() const;
+		
+		/** Multiply two matrices together.
+		  * \param pOther     A Matrix.
+		  * \return             this * pMatrix.
+		  * \remarks            Transformations are pre-multiplied.
+		  *  That means to scale, then rotate, and then translate a vector V, the transform should be T * R * S * V. \n
+		  *  Below is an example of code that shows how to construct rotation transform in XYZ rotation order.
+		  *  \code
+		  *  FbxAMatrix lRotateXM, lRotateYM, lRotateZM, lRotateXYZM, lRotateM;
+		  *  // Construct rotation matrix around X, Y and Z axises separately and then combine them.
+		  *  FbxVector4 lRotateX(10, 0, 0);
+		  *  FbxVector4 lRotateY(0, 10, 0);
+		  *  FbxVector4 lRotateZ(0, 0, 10);
+		  *  lRotateXM.SetR(lRotateX);
+		  *  lRotateYM.SetR(lRotateY);
+		  *  lRotateZM.SetR(lRotateZ);
+		  *  lRotateXYZM = lRotateZM * lRotateYM * lRotateXM;
+		  *
+		  *  // Alternatively, we can use SetR() directly.
+		  *  // lRotateXYZM and lRotateM will be the same.
+		  *  FbxVector4 lRotateXYZ (10, 10, 10);
+		  *  lRotateM.SetR(lRotateXYZ);
+		  *  \endcode
+		  * \note                Please refer to the FBX SDK programmers guide for more details.
+		  */
+		FbxAMatrix operator*(const FbxAMatrix& pOther) const;
+
+		/** Multiply two matrices together.
+		  * \param pOther     A Matrix.
+		  * \return             \e this updated with the result of the multiplication.
+		  */
+		FbxAMatrix& operator*=(const FbxAMatrix& pOther);
+
+		/** Calculate the matrix inverse.
+		  * \return     The inverse matrix of \e this.
+		  */
+		FbxAMatrix Inverse() const;
+
+		/** Calculate the matrix transpose.
+		  * \return     The transposed matrix of \e this.
+		  */
+		FbxAMatrix Transpose() const;
+
+		/** Calculate a spherical linear interpolation matrix.
+		* \param pOther The other rotation matrix to interpolate with.
+		* \param pWeight A value between 0.0 and 1.0 to specify the interpolation amount.
+		* \remark This matrix and other matrix should contain only rotations, otherwise result may be undefined. */
+		FbxAMatrix Slerp(const FbxAMatrix& pOther, double pWeight) const;
+	//@}
+
+	/**
+	  * \name Boolean Operations
+	  */
+	//@{
+		/**	Equivalence operator.
+		  * \param pOther     The matrix to be compared to \e this.
+		  * \return             \c true if the two matrices are equal (each element is within a FBXSDK_TOLERANCE tolerance) and \c false otherwise.
+		  */
+		bool operator==(const FbxAMatrix& pOther) const;
+
+		/**	Non-equivalence operator.
+		  * \param pOther     The matrix to be compared to \e this.
+		  * \return            \c false if the two matrices are equal (each element is within a FBXSDK_TOLERANCE tolerance) and \c true otherwise.
+		  */
+		bool operator!=(const FbxAMatrix& pOther) const;
+	//@}
+
+	/**
+	  * \name Casting
+	  */
+	//@{
+		//! Cast the matrix in a double pointer.
+		operator double* ();
+		//! Cast the matrix in a const double pointer.
+		operator const double* () const;
+		//! Define 4*4 array as a new type 
+		typedef const double(kDouble44)[4][4] ;
+		//! Cast the matrix in a reference to a 4*4 array.
+		inline kDouble44 & Double44() const { return *((kDouble44 *)&mData[0][0]); }
+	//@}
+
+	/** Find out if the matrix is equal to identity matrix.
+	* \return \c true if the matrix is equal to identity matrix, \c false otherwise. */
+	bool IsIdentity(const double pThreshold=FBXSDK_TOLERANCE);
+
+/*****************************************************************************************************************************
+** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
+*****************************************************************************************************************************/
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+	FbxAMatrix(const FbxVector4& pT, const FbxQuaternion& pQ, const FbxVector4& pS);
+
+	void SetTRS(const FbxVector4& pT, const FbxAMatrix& pRM, const FbxVector4& pS);
+    void SetRow(int pY, const FbxVector4& pRow);
+    void SetTOnly(const FbxVector4& pT);
+    void SetROnly(const FbxVector4& pR);
+    void SetQOnly(const FbxQuaternion& pQ);
+	FbxVector4 GetROnly() const;
+    FbxQuaternion GetUnnormalizedQ() const;
+
+	// pOrd is assumed to be an FbxEuler::EOrder (or its synonym EFbxRotationOrder)
+    void SetR(const FbxVector4& pV, const int pOrd); 
+	FbxVector4 GetR(const int pOrd) const;
+
+    void MultRM(const FbxVector4& pR);
+    void MultSM(const FbxVector4& pS);
+    bool IsRightHand() const;
+    double Determinant() const;
+	int Compare(const FbxAMatrix pM, const double pThreshold=FBXSDK_TOLERANCE) const;
+#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
+};
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* _FBXSDK_CORE_MATH_AFFINE_MATRIX_H_ */

+ 325 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/math/fbxdualquaternion.h

@@ -0,0 +1,325 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxdualquaternion.h
+#ifndef _FBXSDK_CORE_MATH_DUAL_QUATERNION_H_
+#define _FBXSDK_CORE_MATH_DUAL_QUATERNION_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#include <fbxsdk/core/math/fbxquaternion.h>
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+/**	FBX SDK dual quaternion class to represent rigid transformation, which is combined by two quaternions.
+  * A transformation is said to be rigid if it preserves relative distances and angles.
+  * That means rotation and translation.
+  * \nosubgrouping
+  */
+class FBXSDK_DLL FbxDualQuaternion
+{
+public:
+	/**
+	  * \name Constructors and Destructor
+	  */
+	//@{
+		//! Constructor.
+		FbxDualQuaternion();
+
+		/** Constructor.
+		* \param pV1 FbxQuaternion object.
+		* \param pV2 FbxQuaternion object.
+		*/
+		FbxDualQuaternion(const FbxQuaternion& pV1, const FbxQuaternion& pV2);
+
+		/** Copy constructor.
+		  * \param pV FbxQuaternion object copied to this one.
+		  */
+		FbxDualQuaternion(const FbxDualQuaternion& pV);
+
+		/** Constructor.
+		* \param pRotation     The rotation the dual quaternion is going to represent.
+		* \param pTranslation  The translation the dual quaternion is going to represent.
+		*/
+		FbxDualQuaternion(const FbxQuaternion& pRotation, const FbxVector4& pTranslation);
+
+		/** Constructor.
+		  * \param pX1     The X component of the first quaternion.
+		  * \param pY1     The Y component of the first quaternion.
+		  * \param pZ1     The Z component of the first quaternion.
+		  * \param pW1     The W component of the first quaternion.
+		  * \param pX2     The X component of the second quaternion.
+		  * \param pY2     The Y component of the second quaternion.
+		  * \param pZ2     The Z component of the second quaternion.
+		  * \param pW2     The W component of the second quaternion.
+		  */
+		FbxDualQuaternion(double pX1, double pY1, double pZ1, double pW1, double pX2, double pY2, double pZ2, double pW2);
+
+		//! Destructor.
+		~FbxDualQuaternion();
+	//@}
+
+	/**
+	* \name Access
+	*/
+	//@{
+		/** Assignment operation.
+		* \param pDualQuaternion FbxDualQuaternion object assigned to this one.
+		*/
+		FbxDualQuaternion& operator=(const FbxDualQuaternion& pDualQuaternion);
+
+		/** Set vector.
+		* \param pX1     The X component of the first quaternion.
+		* \param pY1     The Y component of the first quaternion.
+		* \param pZ1     The Z component of the first quaternion.
+		* \param pW1     The W component of the first quaternion.
+		* \param pX2     The X component of the second quaternion.
+		* \param pY2     The Y component of the second quaternion.
+		* \param pZ2     The Z component of the second quaternion.
+		* \param pW2     The W component of the second quaternion.
+		*/
+		void Set(double pX1, double pY1, double pZ1, double pW1, double pX2, double pY2, double pZ2, double pW2);
+
+		/** Get the first quaternion of the dual quaternion.
+		* \return The first quaternion of the dual quaternion.
+		*/
+		FbxQuaternion& GetFirstQuaternion();
+
+		/** Get the second quaternion of the dual quaternion.
+		* \return The second quaternion of the dual quaternion.
+		*/
+		FbxQuaternion& GetSecondQuaternion();
+
+		/** Get the first quaternion of the dual quaternion.
+		* \return The first quaternion of the dual quaternion.
+		*/
+		const FbxQuaternion& GetFirstQuaternion() const;
+
+		/** Get the second quaternion of the dual quaternion.
+		* \return The second quaternion of the dual quaternion.
+		*/
+		const FbxQuaternion& GetSecondQuaternion() const;
+
+		/** Get the rotation part from the dual quaternion.
+		* \return FbxQuaternion object to represent rotation.
+		*/
+		FbxQuaternion GetRotation() const;
+
+		/** Get the translation part from the dual quaternion.
+		* \return FbxVector4 object to represent translation.
+		* \remarks A dual quaternion can represent rotation followed by translation, or translation followed by rotation.
+		* This method assumes that the rotation is expressed first, followed by translation, as is done by most DCC tools.
+		*/
+		FbxVector4 GetTranslation() const;
+	//@}
+
+	/**
+	  * \name Scalar Operations
+	  */
+	//@{
+		/** Add a value to all vector components.
+		  * \param pValue     The value to add to each component of the vector.
+		  * \return           New vector.
+		  * \remarks          The passed value is not checked.
+		  */
+		FbxDualQuaternion operator+(double pValue) const;
+
+		/** Subtract a value from all vector components.
+		  * \param pValue     The value to subtract from each component of the vector.
+		  * \return           New vector.
+		  * \remarks          The passed value is not checked.
+		  */
+		FbxDualQuaternion operator-(double pValue) const;
+
+		/** Multiply all vector components by a value.
+		  * \param pValue     The value multiplying each component of the vector.
+		  * \return           New vector.
+		  * \remarks          The passed value is not checked.
+		  */
+		FbxDualQuaternion operator*(double pValue) const;
+
+		/**	Divide all vector components by a value.
+		  * \param pValue     The value dividing each component of the vector.
+		  * \return           New vector.
+		  * \remarks          The passed value is not checked.
+		  */
+		FbxDualQuaternion operator/(double pValue) const;
+
+		/** Add a value to all vector components.
+		  * \param pValue     The value to add to each component of the vector.
+		  * \return           The result of adding pValue to each component of the vector, replacing this dual quaternion.
+		  * \remarks          The passed value is not checked.
+		  */
+		FbxDualQuaternion& operator+=(double pValue);
+
+		/** Subtract a value from all vector components.
+		  * \param pValue     The value to subtract from each component of the vector.
+		  * \return           The result of subtracting pValue from each component of the vector, replacing this dual quaternion.
+		  * \remarks          The passed value is not checked.
+		  */
+		FbxDualQuaternion& operator-=(double pValue);
+
+		/** Multiply a value to all vector elements.
+		  * \param pValue     The value multiplying each component of the vector.
+		  * \return           The result of multiplying each component of the vector by pValue, replacing this dual quaternion.
+		  * \remarks          The passed value is not checked.
+		  */
+		FbxDualQuaternion& operator*=(double pValue);
+
+		/**	Divide all vector elements by a value.
+		  * \param pValue     The value dividing each component of the vector.
+		  * \return           The result of dividing each component of the vector by pValue, replacing this dual quaternion.
+		  * \remarks          The passed value is not checked.
+		  */
+		FbxDualQuaternion& operator/=(double pValue);
+	//@}
+
+	/**
+	  * \name Vector Operations
+	  */
+	//@{
+		/**	Unary minus operator.
+		  * \return      A dual quaternion where each component is multiplied by -1.
+		  */
+		FbxDualQuaternion operator-() const;
+
+		/** Add two vectors together.
+		  * \param pDualQuaternion     Dual quaternion to add.
+		  * \return                The dual quaternion v' = this + pDualQuaternion.
+		  * \remarks               The values in pDualQuaternion are not checked.
+		  */
+		FbxDualQuaternion operator+(const FbxDualQuaternion& pDualQuaternion) const;
+
+		/** Subtract a quaternion from another quaternion.
+		  * \param pDualQuaternion     Dual quaternion to subtract.
+		  * \return                The dual quaternion v' = this - pDualQuaternion.
+		  * \remarks               The values in pDualQuaternion are not checked.
+		  */
+		FbxDualQuaternion operator-(const FbxDualQuaternion& pDualQuaternion) const;
+
+		/** Memberwise multiplication of two vectors.
+		  * \param pDualQuaternion     Multiplying dual quaternion.
+		  * \return                The dual quaternion v' = this * pQuaternion.
+		  * \remarks               The values in pDualQuaternion are not checked.
+		  */
+		FbxDualQuaternion operator*(const FbxDualQuaternion& pDualQuaternion) const;
+
+		/** Memberwise division of a dual quaternion with another dual quaternion.
+		  * \param pDualQuaternion     Dividing dual quaternion.
+		  * \return                The dual quaternion v' = this / pQuaternion.
+		  * \remarks               The values in pDualQuaternion are not checked.
+		  */
+		FbxDualQuaternion operator/(const FbxDualQuaternion& pDualQuaternion) const;
+
+		/** Add two quaternions together.
+		  * \param pDualQuaternion     Dual quaternion to add.
+		  * \return                The dual quaternion v' = this + pQuaternion, replacing this dual quaternion.
+		  * \remarks               The values in pDualQuaternion are not checked.
+		  */
+		FbxDualQuaternion& operator+=(const FbxDualQuaternion& pDualQuaternion);
+
+		/** Subtract a dual quaternion from another vector.
+		  * \param pDualQuaternion     Dual quaternion to subtract.
+		  * \return                The dual quaternion v' = this - pQuaternion, replacing this dual quaternion.
+		  * \remarks               The values in pDualQuaternion are not checked.
+		  */
+		FbxDualQuaternion& operator-=(const FbxDualQuaternion& pDualQuaternion);
+
+		/** Memberwise multiplication of two quaternions.
+		  * \param pDualQuaternion     Multiplying dual quaternion.
+		  * \return                The dual quaternion v' = this * pQuaternion, replacing this dual quaternion.
+		  * \remarks               The values in pDualQuaternion are not checked.
+		  */
+		FbxDualQuaternion& operator*=(const FbxDualQuaternion& pDualQuaternion);
+
+		/** Memberwise division of a dual quaternion by another dual quaternion.
+		  * \param pDualQuaternion     Dividing dual quaternion.
+		  * \return                The dual quaternion v' = this / pQuaternion, replacing this dual quaternion.
+		  * \remarks               The values in pDualQuaternion are not checked.
+		  */
+		FbxDualQuaternion& operator/=(const FbxDualQuaternion& pDualQuaternion);
+
+		/** Multiplication of a dual quaternion by a FbxVector4.
+		* \param pVector     The FbxVector4 to multiply with.
+		* \return            The dual quaternion v' = FbxDualQuaternion(mQ1, (mQ1 * pVector) + mQ2).
+		* \remarks           The values in pDualQuaternion are not checked.
+		*/
+		FbxDualQuaternion operator*(const FbxVector4 pVector) const;
+
+		/** Return dual quaternion product.
+		* \param pDualQuaternion	Product dual quaternion.
+		* \return					The dual quaternion that is the product of this and pDualQuaternion.
+		*/
+		FbxDualQuaternion Product(const FbxDualQuaternion& pDualQuaternion) const;
+
+		/** Normalize the dual quaternion, length set to 1.
+		*/
+		void Normalize();
+
+		/** Calculate the dual quaternion's inverse.
+		* \return      The inverse of this dual quaternion. 
+		*/
+		void Inverse();
+
+		/** Deform a point by this dual quaternion.
+		* \return      The inverse of this quaternion. 
+		*/
+		FbxVector4 Deform(FbxVector4& pPoint);
+	//@}
+
+	/**
+	* \name Conjugate Operations
+	* \brief Dual quaternion has three types of conjugate.
+	*/
+	//@{
+		/** Conjugate both quaternions of this dual quaternion.
+		*/
+		void Conjugate();
+
+		/** Conjugate in dual space.
+		*/
+		void Dual();
+
+		/** Conjugate both quaternions of this dual quaternion in dual space.
+		*/
+		void DualConjugate();
+	//@}
+
+	/**
+	  * \name Boolean Operations
+	  */
+	//@{
+		/**	Equivalence operator.
+		  * \param pV     The quaternion to be compared to this quaternion.
+		  * \return       \c true  if the two quaternions are equal (each element is within a FBXSDK_TOLERANCE tolerance), \c false  otherwise.
+		  */
+		bool operator==(const FbxDualQuaternion & pV) const;
+
+		/**	Non equivalence operator.
+		  * \param pV     The quaternion to be compared to \e this.
+		  * \return       \c  false if the two quaternions are equal (each element is within a FBXSDK_TOLERANCE tolerance), \c true  otherwise.
+		  */
+		bool operator!=(const FbxDualQuaternion & pV) const;
+	//@}
+
+/*****************************************************************************************************************************
+** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
+*****************************************************************************************************************************/
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+private:
+	FbxQuaternion mQ1;
+	FbxQuaternion mQ2;
+#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
+};
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* _FBXSDK_CORE_MATH_DUAL_QUATERNION_H_ */

+ 501 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/math/fbxmath.h

@@ -0,0 +1,501 @@
+/****************************************************************************************
+ 
+   Copyright (C) 2015 Autodesk, Inc.
+   All rights reserved.
+ 
+   Use of this software is subject to the terms of the Autodesk license agreement
+   provided at the time of installation or download, or which otherwise accompanies
+   this software in either electronic or hard copy form.
+ 
+****************************************************************************************/
+
+//! \file fbxmath.h
+#ifndef _FBXSDK_CORE_MATH_H_
+#define _FBXSDK_CORE_MATH_H_
+
+#include <fbxsdk/fbxsdk_def.h>
+
+#include <fbxsdk/core/math/fbxvector2.h>
+#include <fbxsdk/core/math/fbxvector4.h>
+#include <fbxsdk/core/math/fbxmatrix.h>
+#include <fbxsdk/core/math/fbxaffinematrix.h>
+
+//On Mac OS, cmath will include math.h and undef "isnan"
+#if defined(FBXSDK_ENV_MAC)
+	#include <cmath>
+	extern "C" int isnan (double);
+#endif
+
+#include <fbxsdk/fbxsdk_nsbegin.h>
+
+#if defined(FBXSDK_ENV_WIN)
+	#ifndef isnan
+		#define isnan	_isnan
+	#endif
+	#ifndef finite
+		#define finite	_finite
+	#endif
+#endif
+
+//---------------------------------------------------------------------------------------
+//Common Constants
+#define FBXSDK_PI				3.1415926535897932384626433832795028841971693993751		//!< PI mathematic constant
+#define FBXSDK_PI_DIV_2			1.5707963267948966192313216916397514420985846996875		//!< PI divided by 2
+#define FBXSDK_PI_DIV_180		0.017453292519943295769236907684886127134428718885417	//!< PI divived by 180
+#define FBXSDK_180_DIV_PI		57.295779513082320876798154814105170332405472466565		//!< 180 divided by PI
+#define FBXSDK_1_DIV_LN2		1.4426950408889634073599246810018921374266459541530		//!< 1 divided by LogN2
+
+//---------------------------------------------------------------------------------------
+//Unit Convertion Ratio
+#define FBXSDK_DEG_TO_RAD		FBXSDK_PI_DIV_180	//!< Degree to Radian
+#define FBXSDK_RAD_TO_DEG		FBXSDK_180_DIV_PI	//!< Radian to Degree
+#define FBXSDK_IN_TO_CM			2.54				//!< Inch to Centimeter
+#define FBXSDK_MM_TO_CM			0.1					//!< Millimeter to Centimeter
+#define FBXSDK_CM_TO_IN			0.393700787			//!< Centimeter to Inch
+#define	FBXSDK_IN_TO_MM			25.4				//!< Inch to Millimeter
+#define FBXSDK_MM_TO_IN			0.0393700787		//!< Millimeter to Inch
+#define FBXSDK_FT_TO_M			0.3048				//!< Feet to Meter
+#define FBXSDK_M_TO_FT			3.2808399			//!< Meter to Feet
+#define FBXSDK_YD_TO_FT			3					//!< Yard to Feet
+#define FBXSDK_FT_TO_YD			0.333333333			//!< Feet to Yard
+#define FBXSDK_KM_TO_MILE		0.621371192			//!< Kilometer to Mile
+#define FBXSDK_MILE_TO_KM		1.609344			//!< Mile to Kilometer
+#define FBXSDK_YD_TO_M			0.9144				//!< Yard to Meter
+#define FBXSDK_M_TO_YD			1.0936133			//!< Meter to Yard
+
+//---------------------------------------------------------------------------------------
+//Euler Definition
+#define FBXSDK_EULER_DEGENERATE	(16.0*FBXSDK_FLOAT_EPSILON)	//!< Euler degenerate threshold
+
+class FBXSDK_DLL FbxEuler
+{
+public:
+	enum EAxis {eAxisX=0, eAxisY=1, eAxisZ=2};
+
+	enum EOrder
+	{
+		eOrderXYZ,
+		eOrderXZY,
+		eOrderYZX,
+		eOrderYXZ,
+		eOrderZXY,
+		eOrderZYX,
+		eOrderSphericXYZ
+	};
+
+	static bool IsParityOdd(EOrder pOrder);
+	static bool IsRepeat(EOrder pOrder);
+
+	static const int AxisTableSize;
+	static const int AxisTable[][3];
+};
+
+/** Rotation order flags.
+  * Each rotate order produces a different end orientation. For example, if the rotation order for an object is set to XYZ,
+  * the object first rotates about its X-axis, then its Y-axis, and finally its Z-axis.
+  */
+
+#define EFbxRotationOrder	FbxEuler::EOrder
+#define eEulerXYZ			FbxEuler::eOrderXYZ
+#define eEulerXZY			FbxEuler::eOrderXZY
+#define eEulerYZX			FbxEuler::eOrderYZX
+#define eEulerYXZ			FbxEuler::eOrderYXZ
+#define eEulerZXY			FbxEuler::eOrderZXY
+#define eEulerZYX			FbxEuler::eOrderZYX
+#define eSphericXYZ			FbxEuler::eOrderSphericXYZ
+
+
+
+/** Quaternion interpolation modes.  */
+enum EFbxQuatInterpMode
+{
+    eQuatInterpOff,					//!< Do not evaluate using quaternion interpolation.
+    eQuatInterpClassic,				//!< Legacy quaternion interpolation mode.
+    eQuatInterpSlerp,				//!< Spherical linear interpolation.
+    eQuatInterpCubic,				//!< Cubic interpolation.
+    eQuatInterpTangentDependent,	//!< Mix between Slerp and cubic interpolation, depending on the specified tangents for each key.
+    eQuatInterpCount				//!< Number of quaternion interpolation modes. Mark the end of this enum.
+};
+
+extern FBXSDK_DLL const FbxDouble FbxIdentityMatrix[4][4];
+extern FBXSDK_DLL const FbxVector4 FbxZeroVector4;
+
+inline float FbxFloor(const float x)
+{
+	return float(floor(x));
+}
+
+inline double FbxFloor(const double x)
+{
+	return floor(x);
+}
+
+inline float FbxCeil(const float x)
+{
+	return float(ceil(x));
+}
+
+inline double FbxCeil(const double x)
+{
+	return ceil(x);
+}
+
+template<class T> inline T FbxSign(const T x)
+{
+	return (x < 0) ? T(-1) : T(1);
+}
+
+template<class T> inline T FbxRound(const T x)
+{
+	T y = FbxFloor(x);
+	return (x - y < T(0.5)) ? y : y + T(1);
+}
+
+inline FbxUChar FbxAbs(const FbxUChar x)
+{
+	return x;
+}
+
+inline FbxUShort FbxAbs(const FbxUShort x)
+{
+	return x;
+}
+
+inline FbxUInt FbxAbs(const FbxUInt x)
+{
+	return x;
+}
+
+#ifndef FBXSDK_SYSTEM_IS_LP64
+	inline FbxULong FbxAbs(const FbxULong x)
+	{
+		return x;
+	}
+#endif
+
+inline FbxULongLong FbxAbs(const FbxULongLong x)
+{
+	return x;
+}
+
+inline FbxFloat FbxAbs(const FbxFloat x)
+{
+	return fabs(x);
+}
+
+inline FbxDouble FbxAbs(const FbxDouble x)
+{
+	return fabs(x);
+}
+
+template<class T> inline T FbxAbs(const T x)
+{
+	return (x >= 0) ? x : ((x > FbxMin(x)) ? -x : FbxMax(x));
+}
+
+template<class T> inline T FbxClamp(const T value, const T min, const T max)
+{
+	return (value < min) ? min : ((value > max) ? max : value);
+}
+
+template<class T> inline bool FbxEqual(const T x, const T y, const T e=(T)FBXSDK_TOLERANCE)
+{
+	return FbxAbs(x - y) <= e;
+}
+
+inline bool FbxEqual(const FbxDouble2& x, const FbxDouble2& y, const double e=FBXSDK_TOLERANCE)
+{
+	return ( FbxEqual(x.mData[0], y.mData[0], e) && FbxEqual(x.mData[1], y.mData[1], e) );
+}
+
+inline bool FbxEqual(const FbxDouble3& x, const FbxDouble3& y, const double e=FBXSDK_TOLERANCE)
+{
+	return ( FbxEqual(x.mData[0], y.mData[0], e) && FbxEqual(x.mData[1], y.mData[1], e) && FbxEqual(x.mData[2], y.mData[2], e) );
+}
+
+inline bool FbxEqual(const FbxDouble4& x, const FbxDouble4& y, const double e=FBXSDK_TOLERANCE)
+{
+	return ( FbxEqual(x.mData[0], y.mData[0], e) && FbxEqual(x.mData[1], y.mData[1], e) && FbxEqual(x.mData[2], y.mData[2], e) && FbxEqual(x.mData[3], y.mData[3], e) );
+}
+
+inline bool FbxEqual(const FbxDouble4x4& x, const FbxDouble4x4& y, const double e=FBXSDK_TOLERANCE)
+{
+	return ( FbxEqual(x[0], y[0], e) && FbxEqual(x[1], y[1], e) && FbxEqual(x[2], y[2], e) && FbxEqual(x[3], y[3], e) );
+}
+
+inline bool FbxEqual(const FbxVector2& x, const FbxVector2& y, const double e=FBXSDK_TOLERANCE)
+{
+	return ( FbxEqual(x.mData[0], y.mData[0], e) && FbxEqual(x.mData[1], y.mData[1], e) );
+}
+
+inline bool FbxEqual(const FbxVector4& x, const FbxVector4& y, const double e=FBXSDK_TOLERANCE)
+{
+	return ( FbxEqual(x.mData[0], y.mData[0], e) && FbxEqual(x.mData[1], y.mData[1], e) && FbxEqual(x.mData[2], y.mData[2], e) && FbxEqual(x.mData[3], y.mData[3], e) );
+}
+
+inline bool FbxEqual(const FbxMatrix& x, const FbxMatrix& y, const double e=FBXSDK_TOLERANCE)
+{
+	return ( FbxEqual(x[0], y[0], e) && FbxEqual(x[1], y[1], e) && FbxEqual(x[2], y[2], e) && FbxEqual(x[3], y[3], e) );
+}
+
+inline bool FbxEqual(const FbxAMatrix& x, const FbxAMatrix& y, const double e=FBXSDK_TOLERANCE)
+{
+	return ( FbxEqual(x[0], y[0], e) && FbxEqual(x[1], y[1], e) && FbxEqual(x[2], y[2], e) && FbxEqual(x[3], y[3], e) );
+}
+
+inline FbxDouble FbxMod(const FbxFloat x, FbxFloat& i)
+{
+	return modff(x, &i);
+}
+
+inline FbxDouble FbxMod(const FbxDouble x, FbxDouble& i)
+{
+	return modf(x, &i);
+}
+
+inline FbxDouble FbxMod(const FbxFloat x)
+{
+	FbxFloat i;
+	return modff(x, &i);
+}
+
+inline FbxDouble FbxMod(const FbxDouble x)
+{
+	FbxDouble i;
+	return modf(x, &i);
+}
+
+template<class T> inline T FbxReciprocal(const T x)
+{
+	return T(1) / x;
+}
+
+inline double FbxSqrt(const double x)
+{
+	return sqrt(x);
+}
+
+inline float FbxSqrt(const float x)
+{
+	return sqrtf(x);
+}
+
+template<class T> inline T FbxSqrt(const T x)
+{
+	if( x > 1 )
+	{
+		T z, y = x >> 1; 
+		do 
+		{ 
+			z = y; 
+			y = (y + (x / y)) >> 1; 
+		}
+		while(y < z); 
+
+		return z;
+	}
+	else
+	{
+		return x;
+	}
+}
+
+inline float FbxExp(const float x)
+{
+	return expf(x);
+}
+
+inline double FbxExp(const double x)
+{
+	return exp(x);
+}
+
+inline float FbxLog(const float x)
+{
+	return float(log(x));
+}
+
+inline double FbxLog(const double x)
+{
+	return log(x);
+}
+
+template<class T> inline T FbxPow(const T x, const T y)
+{
+	return (T)FbxExp(y * FbxLog((double)x));
+}
+
+template<class T> inline T FbxLog2(const T x)
+{
+	return (T)(FbxLog(x) * FBXSDK_1_DIV_LN2);
+}
+
+inline float FbxSin(const float x)
+{
+	return sinf(x);
+}
+
+inline double FbxSin(const double x)
+{
+	return sin(x);
+}
+
+inline float FbxCos(const float x)
+{
+	return cosf(x);
+}
+
+inline double FbxCos(const double x)
+{
+	return cos(x);
+}
+
+inline float FbxTan(const float x)
+{
+	return tanf(x);
+}
+
+inline double FbxTan(const double x)
+{
+	return tan(x);
+}
+
+// *y = cos(x), sin(x)
+template<class T> inline T FbxSinCos(const T x, T* y)
+{
+	return *y = FbxCos(x), FbxSin(x);
+}
+
+// *y = cos(x * pi/180), sin(x * pi/180)
+template<class T> inline T FbxSinCosd(const T x, T* y)
+{
+	return FbxSinCos(T(x * FBXSDK_PI_DIV_180), y);
+}
+
+inline float FbxASin(const float x)
+{
+	return asinf(x);
+}
+
+inline double FbxASin(const double x)
+{
+	return asin(x);
+}
+
+template<class T> inline T FbxASind(const T x)
+{
+	return (T)(FbxASin((double)x) * FBXSDK_180_DIV_PI);
+}
+
+inline float FbxACos(const float x)
+{
+	return acosf(x);
+}
+
+inline double FbxACos(const double x)
+{
+	return acos(x);
+}
+
+template<class T> inline T FbxACosd(const T x)
+{
+	return (T)(FbxACos(x) * FBXSDK_180_DIV_PI);
+}
+
+inline float FbxATan(const float x)
+{
+	return atanf(x);
+}
+
+inline double FbxATan(const double x)
+{
+	return atan(x);
+}
+
+template<class T> inline T FbxATand(const T x)
+{
+	return (T)(FbxATan(x) * FBXSDK_180_DIV_PI);
+}
+
+inline float FbxATan(const float y, const float x)
+{
+	return atan2f(y, x);
+}
+
+inline double FbxATan(const double y, const double x)
+{
+	return atan2(y, x);
+}
+
+template<class T> inline T FbxATand(const T y, const T x)
+{
+	return (T)(FbxATan(y, x) * FBXSDK_180_DIV_PI);
+}
+
+template<class T> inline T FbxNorm(const T x, const T y)
+{
+	return FbxSqrt(x * x + y * y);
+}
+
+template<class T> inline T FbxNorm(const T x, const T y, const T z)
+{
+	return FbxSqrt(x * x + y * y + z * z);
+}
+
+template<class T> inline T FbxNorm(const T w, const T x, const T y, const T z)
+{
+	return FbxSqrt(w * w + x * x + y * y + z * z);
+}
+
+template<class T> inline T FbxHypot(const T x, const T y)
+{
+	return FbxSqrt(x * x + y * y);
+}
+
+template<class T> inline T FbxHypot(const T x, const T y, const T z)
+{
+	return FbxSqrt(x * x + y * y + z * z);
+}
+
+template<class T> inline T FbxHypot(const T w, const T x, const T y, const T z)
+{
+	return FbxSqrt(w * w + x * x + y * y + z * z);
+}
+
+inline FbxVector4 FbxRejection(const FbxVector4& a, const FbxVector4& b)
+{
+    return a - b * (a.DotProduct(b) / b.DotProduct(b));
+}
+
+template<class T> inline int FbxBitCount(const T x)
+{
+	int n = 0;
+	T c = x;
+	while( c )
+	{
+		n += int(c & 1);
+		c = (c >> 1);
+	}
+	return n;
+}
+
+template<class T> inline void FbxFixInfinite(T& x)
+{
+	if( x != x || x > FbxMax(x) || x < -FbxMax(x) )
+	{
+		x = T(0);
+	}
+}
+
+template<class T> inline T FbxExp(const T x);
+template<class T> inline T FbxLog(const T x);
+template<class T> inline T FbxSin(const T x);
+template<class T> inline T FbxCos(const T x);
+template<class T> inline T FbxASin(const T x);
+template<class T> inline T FbxACos(const T x);
+template<class T> inline T FbxATan(const T x);
+template<class T> inline T FbxATan(const T y, const T x);
+
+#include <fbxsdk/fbxsdk_nsend.h>
+
+#endif /* _FBXSDK_CORE_MATH_H_ */

+ 0 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/math/fbxmatrix.h


Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác