diff --git a/autobuild.xml b/autobuild.xml
index 297df9d099280f43b1a1790be5ece5e598669437..559b898c250f199e5689f3d40b71bded19e17e7d 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -1792,6 +1792,18 @@
       </map>
       <key>mikktspace</key>
       <map>
+        <key>canonical_repo</key>
+        <string>https://bitbucket.org/lindenlab/3p-mikktspace</string>
+        <key>copyright</key>
+        <string>Copyright (C) 2011 by Morten S. Mikkelsen, Copyright (C) 2022 Blender Authors</string>
+        <key>description</key>
+        <string>Mikktspace Tangent Generator</string>
+        <key>license</key>
+        <string>Apache 2.0</string>
+        <key>license_file</key>
+        <string>mikktspace.txt</string>
+        <key>name</key>
+        <string>mikktspace</string>
         <key>platforms</key>
         <map>
           <key>darwin64</key>
@@ -1799,58 +1811,46 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>6cc1585dba85b0226a2e7033a7e2a2ceaae7c983</string>
+              <string>65edf85c36a10001e32bdee582bec4732137208b</string>
               <key>hash_algorithm</key>
               <string>sha1</string>
               <key>url</key>
-              <string>https://github.com/secondlife/3p-mikktspace/releases/download/v1-5cee1f4/mikktspace-1-darwin64-5cee1f4.tar.zst</string>
+              <string>https://github.com/secondlife/3p-mikktspace/releases/download/v2-e967e1b/mikktspace-1-darwin64-8756084692.tar.zst</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
           </map>
-          <key>windows64</key>
+          <key>linux64</key>
           <map>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>6b7d01ad54e4a88a001f66840c32329cedb28202</string>
+              <string>fa9dcee4584df7e7271fdf69c08e6fd3122a47fc</string>
               <key>hash_algorithm</key>
               <string>sha1</string>
               <key>url</key>
-              <string>https://github.com/secondlife/3p-mikktspace/releases/download/v1-5cee1f4/mikktspace-1-windows64-5cee1f4.tar.zst</string>
+              <string>https://github.com/secondlife/3p-mikktspace/releases/download/v2-e967e1b/mikktspace-1-linux64-8756084692.tar.zst</string>
             </map>
             <key>name</key>
-            <string>windows64</string>
+            <string>linux64</string>
           </map>
-          <key>linux64</key>
+          <key>windows64</key>
           <map>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>edc9782bf209e17ad1845498b42f16d733582082</string>
+              <string>130b33a70bdb3a8a188376c6a91840bdb61380a8</string>
               <key>hash_algorithm</key>
               <string>sha1</string>
               <key>url</key>
-              <string>https://github.com/secondlife/3p-mikktspace/releases/download/v1-5cee1f4/mikktspace-1-linux64-5cee1f4.tar.zst</string>
+              <string>https://github.com/secondlife/3p-mikktspace/releases/download/v2-e967e1b/mikktspace-1-windows64-8756084692.tar.zst</string>
             </map>
             <key>name</key>
-            <string>linux64</string>
+            <string>windows64</string>
           </map>
         </map>
-        <key>license</key>
-        <string>Copyright (C) 2011 by Morten S. Mikkelsen</string>
-        <key>license_file</key>
-        <string>mikktspace.txt</string>
-        <key>copyright</key>
-        <string>Copyright (C) 2011 by Morten S. Mikkelsen</string>
         <key>version</key>
         <string>1</string>
-        <key>name</key>
-        <string>mikktspace</string>
-        <key>canonical_repo</key>
-        <string>https://bitbucket.org/lindenlab/3p-mikktspace</string>
-        <key>description</key>
-        <string>Mikktspace Tangent Generator</string>
       </map>
       <key>minizip-ng</key>
       <map>
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index 2f25a4359d7b2e9e02c754e1550b03e9e3a0f570..4384c732b2f1867fa5f43ec2bf9fc1ce87127985 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -53,8 +53,7 @@
 #include "lltimer.h"
 #include "llvolumeoctree.h"
 
-#include "mikktspace/mikktspace.h"
-#include "mikktspace/mikktspace.c" // insert mikktspace implementation into llvolume object file
+#include "mikktspace/mikktspace.hh"
 
 #include "meshoptimizer/meshoptimizer.h"
 
@@ -5436,6 +5435,40 @@ struct MikktData
             }
         }
     }
+
+	uint32_t GetNumFaces()
+	{
+		return uint32_t(face->mNumIndices / 3);
+	}
+
+	uint32_t GetNumVerticesOfFace(const uint32_t face_num)
+	{
+		return 3;
+	}
+
+	mikk::float3 GetPosition(const uint32_t face_num, const uint32_t vert_num)
+	{
+		F32* v = p[face_num * 3 + vert_num].mV;
+		return mikk::float3(v);
+	}
+
+	mikk::float3 GetTexCoord(const uint32_t face_num, const uint32_t vert_num)
+	{
+		F32* uv = tc[face_num * 3 + vert_num].mV;
+		return mikk::float3(uv[0], uv[1], 1.0f);
+	}
+
+	mikk::float3 GetNormal(const uint32_t face_num, const uint32_t vert_num)
+	{
+		F32* normal = n[face_num * 3 + vert_num].mV;
+		return mikk::float3(normal);
+	}
+
+	void SetTangentSpace(const uint32_t face_num, const uint32_t vert_num, mikk::float3 T, bool orientation)
+	{
+		S32 i = face_num * 3 + vert_num;
+		t[i].set(T.x, T.y, T.z, orientation ? 1.0f : -1.0f);
+	}
 };
 
 bool LLVolumeFace::cacheOptimize(bool gen_tangents)
@@ -5448,62 +5481,9 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents)
     { // generate mikkt space tangents before cache optimizing since the index buffer may change
         // a bit of a hack to do this here, but this function gets called exactly once for the lifetime of a mesh
         // and is executed on a background thread
-        SMikkTSpaceInterface ms;
-
-        ms.m_getNumFaces = [](const SMikkTSpaceContext* pContext)
-        {
-            MikktData* data = (MikktData*)pContext->m_pUserData;
-            LLVolumeFace* face = data->face;
-            return face->mNumIndices / 3;
-        };
-
-        ms.m_getNumVerticesOfFace = [](const SMikkTSpaceContext* pContext, const int iFace)
-        {
-            return 3;
-        };
-
-        ms.m_getPosition = [](const SMikkTSpaceContext* pContext, float fvPosOut[], const int iFace, const int iVert)
-        {
-            MikktData* data = (MikktData*)pContext->m_pUserData;
-            F32* v = data->p[iFace * 3 + iVert].mV;
-            fvPosOut[0] = v[0];
-            fvPosOut[1] = v[1];
-            fvPosOut[2] = v[2];
-        };
-
-        ms.m_getNormal = [](const SMikkTSpaceContext* pContext, float fvNormOut[], const int iFace, const int iVert)
-        {
-            MikktData* data = (MikktData*)pContext->m_pUserData;
-            F32* n = data->n[iFace * 3 + iVert].mV;
-            fvNormOut[0] = n[0];
-            fvNormOut[1] = n[1];
-            fvNormOut[2] = n[2];
-        };
-
-        ms.m_getTexCoord = [](const SMikkTSpaceContext* pContext, float fvTexcOut[], const int iFace, const int iVert)
-        {
-            MikktData* data = (MikktData*)pContext->m_pUserData;
-            F32* tc = data->tc[iFace * 3 + iVert].mV;
-            fvTexcOut[0] = tc[0];
-            fvTexcOut[1] = tc[1];
-        };
-
-        ms.m_setTSpaceBasic = [](const SMikkTSpaceContext* pContext, const float fvTangent[], const float fSign, const int iFace, const int iVert)
-        {
-            MikktData* data = (MikktData*)pContext->m_pUserData;
-            S32 i = iFace * 3 + iVert;
-            
-            data->t[i].set(fvTangent);
-            data->t[i].mV[3] = fSign;
-        };
-
-        ms.m_setTSpace = nullptr;
-
         MikktData data(this);
-
-        SMikkTSpaceContext ctx = { &ms, &data };
-
-        genTangSpaceDefault(&ctx);
+		mikk::Mikktspace ctx(data);
+		ctx.genTangSpace();
 
         //re-weld
         meshopt_Stream mos[] =
@@ -5524,9 +5504,6 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents)
 
         if (vert_count < 65535 && vert_count != 0)
         {
-            std::vector<U32> indices;
-            indices.resize(mNumIndices);
-
             //copy results back into volume
             resizeVertices(vert_count);