Forráskód Böngészése

Initial commit for native fbx exporter

Simon 10 éve
szülő
commit
89f06535e9
100 módosított fájl, 103018 hozzáadás és 0 törlés
  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

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 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

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 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

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 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

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 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

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 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

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 1034 - 0
Exporters/FBX/3rdParty/DirectXTex/DirectXTexResize.cpp


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 1391 - 0
Exporters/FBX/3rdParty/DirectXTex/DirectXTexTGA.cpp


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 1029 - 0
Exporters/FBX/3rdParty/DirectXTex/DirectXTexUtil.cpp


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 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

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 2566 - 0
Exporters/FBX/3rdParty/DirectXTex/Shaders/BC6HEncode.hlsl


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 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

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 22215 - 0
Exporters/FBX/3rdParty/DirectXTex/Shaders/Compiled/BC6HEncode_EncodeBlockCS.inc


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 3375 - 0
Exporters/FBX/3rdParty/DirectXTex/Shaders/Compiled/BC6HEncode_TryModeG10CS.inc


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 5103 - 0
Exporters/FBX/3rdParty/DirectXTex/Shaders/Compiled/BC6HEncode_TryModeLE10CS.inc


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 10152 - 0
Exporters/FBX/3rdParty/DirectXTex/Shaders/Compiled/BC7Encode_EncodeBlockCS.inc


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 3824 - 0
Exporters/FBX/3rdParty/DirectXTex/Shaders/Compiled/BC7Encode_TryMode02CS.inc


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 3962 - 0
Exporters/FBX/3rdParty/DirectXTex/Shaders/Compiled/BC7Encode_TryMode137CS.inc


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 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_ */

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 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_ */

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 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_ */

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 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_ */

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 1736 - 0
Exporters/FBX/3rdParty/Fbx2016/include/fbxsdk/core/fbxpropertypage.h


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 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


Nem az összes módosított fájl került megjelenítésre, mert túl sok fájl változott