Advertisement
expired6978

Morpher

Apr 17th, 2017
121
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.68 KB | None | 0 0
  1. #include "Morpher.h"
  2. #include <cmath>
  3. #undef min
  4. #undef max
  5. #include "half.hpp"
  6. #include "f4se/BSGeometry.h"
  7.  
  8. float round(float num)
  9. {
  10.     return (num > 0.0) ? floor(num + 0.5) : ceil(num - 0.5);
  11. }
  12.  
  13. MorphApplicator::MorphApplicator(BSTriShape * _geometry, std::function<void(std::vector<Morpher::Vector3> &)> morph) : geometry(_geometry), morphFunc(morph)
  14. {
  15.     UInt64 vertexDesc = geometry->vertexDesc;
  16.     UInt32 vertexSize = geometry->GetVertexSize();
  17.     UInt32 blockSize = geometry->numVertices * vertexSize;
  18.     BSGeometryData * geomData = geometry->geometryData;
  19.     UInt32 numVertices = geometry->numVertices;
  20.  
  21.     // Pull the base data from the vertex block
  22.     rawVertices.resize(numVertices);
  23.     rawNormals.resize(numVertices);
  24.  
  25.     if(vertexDesc & BSTriShape::kFlag_UVs)
  26.         rawUV.resize(numVertices);
  27.  
  28.     if(vertexDesc & BSTriShape::kFlag_Normals)
  29.     {
  30.         rawNormals.resize(numVertices);
  31.         if(vertexDesc & BSTriShape::kFlag_Tangents) {
  32.             rawTangents.resize(numVertices);
  33.             rawBitangents.resize(numVertices);
  34.         }
  35.     }
  36.  
  37.     UInt8 * vertexBlock = geomData->vertexData->vertexBlock;
  38.  
  39.     for(UInt32 i = 0; i < numVertices; i++)
  40.     {
  41.         UInt8 * vBegin = &vertexBlock[i * vertexSize];
  42.  
  43.         if(vertexDesc & BSTriShape::kFlag_FullPrecision)
  44.         {
  45.             rawVertices[i].x = (*(float *)vBegin); vBegin += 4;
  46.             rawVertices[i].y = (*(float *)vBegin); vBegin += 4;
  47.             rawVertices[i].z = (*(float *)vBegin); vBegin += 4;
  48.  
  49.             vBegin += 4; // Skip BitangetX
  50.         }
  51.         else
  52.         {
  53.             rawVertices[i].x = (*(half_float::half *)vBegin); vBegin += 2;
  54.             rawVertices[i].y = (*(half_float::half *)vBegin); vBegin += 2;
  55.             rawVertices[i].z = (*(half_float::half *)vBegin); vBegin += 2;
  56.  
  57.             vBegin += 2; // Skip BitangetX
  58.         }
  59.  
  60.         if(vertexDesc & BSTriShape::kFlag_UVs)
  61.         {
  62.             rawUV[i].u = (*(half_float::half *)vBegin); vBegin += 2;
  63.             rawUV[i].v = (*(half_float::half *)vBegin); vBegin += 2;
  64.         }
  65.  
  66.         if(vertexDesc & BSTriShape::kFlag_Normals)
  67.         {
  68.             rawNormals[i].x = (float)(*(SInt8*)vBegin) / 255.0f; vBegin += 1;
  69.             rawNormals[i].y = (float)(*(SInt8*)vBegin) / 255.0f; vBegin += 1;
  70.             rawNormals[i].z = (float)(*(SInt8*)vBegin) / 255.0f; vBegin += 1;
  71.         }
  72.     }
  73.  
  74.     morphFunc(rawVertices);
  75.  
  76.     Morpher::Triangle* triangles = nullptr;
  77.     auto triangleData = geomData->triangleData;
  78.     if(triangleData)
  79.         triangles = (Morpher::Triangle*)triangleData->triangles;
  80.  
  81.     RecalcNormals(geometry->numTriangles, triangles);
  82.     CalcTangentSpace(geometry->numTriangles, triangles);
  83.    
  84.     vertexBlock = geomData->vertexData->vertexBlock;
  85.     for(UInt32 i = 0; i < numVertices; i++)
  86.     {
  87.         UInt8 * vBegin = &vertexBlock[i * vertexSize];
  88.  
  89.         if(vertexDesc & BSTriShape::kFlag_FullPrecision)
  90.         {
  91.             (*(float *)vBegin) = rawVertices[i].x; vBegin += 4;
  92.             (*(float *)vBegin) = rawVertices[i].y; vBegin += 4;
  93.             (*(float *)vBegin) = rawVertices[i].z; vBegin += 4;
  94.  
  95.             (*(float *)vBegin) = rawBitangents[i].x; vBegin += 4;
  96.         }
  97.         else
  98.         {
  99.             (*(half_float::half *)vBegin) = rawVertices[i].x; vBegin += 2;
  100.             (*(half_float::half *)vBegin) = rawVertices[i].y; vBegin += 2;
  101.             (*(half_float::half *)vBegin) = rawVertices[i].z; vBegin += 2;
  102.  
  103.             (*(half_float::half *)vBegin) = rawBitangents[i].x; vBegin += 2;
  104.         }
  105.  
  106.         // Skip UV write
  107.         if(vertexDesc & BSTriShape::kFlag_UVs)
  108.         {
  109.             vBegin += 4;
  110.         }
  111.  
  112.         if(vertexDesc & BSTriShape::kFlag_Normals)
  113.         {
  114.             *(SInt8*)vBegin = (UInt8)round((((rawNormals[i].x + 1.0f) / 2.0f) * 255.0f)); vBegin += 1;
  115.             *(SInt8*)vBegin = (UInt8)round((((rawNormals[i].y + 1.0f) / 2.0f) * 255.0f)); vBegin += 1;
  116.             *(SInt8*)vBegin = (UInt8)round((((rawNormals[i].z + 1.0f) / 2.0f) * 255.0f)); vBegin += 1;
  117.  
  118.             *(SInt8*)vBegin = (UInt8)round((((rawBitangents[i].y + 1.0f) / 2.0f) * 255.0f)); vBegin += 1;
  119.  
  120.             if(vertexDesc & BSTriShape::kFlag_Tangents)
  121.             {
  122.                 *(SInt8*)vBegin = (UInt8)round((((rawTangents[i].x + 1.0f) / 2.0f) * 255.0f)); vBegin += 1;
  123.                 *(SInt8*)vBegin = (UInt8)round((((rawTangents[i].y + 1.0f) / 2.0f) * 255.0f)); vBegin += 1;
  124.                 *(SInt8*)vBegin = (UInt8)round((((rawTangents[i].z + 1.0f) / 2.0f) * 255.0f)); vBegin += 1;
  125.  
  126.                 *(SInt8*)vBegin = (UInt8)round((((rawBitangents[i].z + 1.0f) / 2.0f) * 255.0f)); vBegin += 1;
  127.             }
  128.         }
  129.     }
  130. }
  131.  
  132. void MorphApplicator::RecalcNormals(UInt32 numTriangles, Morpher::Triangle* triangles, const bool smooth, const float smoothThresh)
  133. {
  134.     UInt32 numVertices = rawVertices.size();
  135.  
  136.     std::vector<Morpher::Vector3> verts(numVertices);
  137.     std::vector<Morpher::Vector3> norms(numVertices);
  138.  
  139.     for (UInt32 i = 0; i < numVertices; i++)
  140.     {
  141.         verts[i].x = rawVertices[i].x * -0.1f;
  142.         verts[i].z = rawVertices[i].y * 0.1f;
  143.         verts[i].y = rawVertices[i].z * 0.1f;
  144.     }
  145.  
  146.     // Face normals
  147.     Morpher::Vector3 tn;
  148.     for (UInt32 t = 0; t < numTriangles; t++)
  149.     {
  150.         triangles[t].trinormal(verts, &tn);
  151.         norms[triangles[t].p1] += tn;
  152.         norms[triangles[t].p2] += tn;
  153.         norms[triangles[t].p3] += tn;
  154.     }
  155.  
  156.     for (auto &n : norms)
  157.         n.Normalize();
  158.  
  159.     // Smooth normals
  160.     if (smooth) {
  161.         kd_matcher matcher(verts.data(), numVertices);
  162.         for (int i = 0; i < matcher.matches.size(); i++)
  163.         {
  164.             std::pair<Morpher::Vector3*, int>& a = matcher.matches[i].first;
  165.             std::pair<Morpher::Vector3*, int>& b = matcher.matches[i].second;
  166.  
  167.             Morpher::Vector3& an = norms[a.second];
  168.             Morpher::Vector3& bn = norms[b.second];
  169.             if (an.angle(bn) < smoothThresh * DEG2RAD) {
  170.                 Morpher::Vector3 anT = an;
  171.                 an += bn;
  172.                 bn += anT;
  173.             }
  174.         }
  175.  
  176.         for (auto &n : norms)
  177.             n.Normalize();
  178.     }
  179.  
  180.     for (UInt32 i = 0; i < numVertices; i++)
  181.     {
  182.         rawNormals[i].x = -norms[i].x;
  183.         rawNormals[i].y = norms[i].z;
  184.         rawNormals[i].z = norms[i].y;
  185.     }
  186. }
  187.  
  188. void MorphApplicator::CalcTangentSpace(UInt32 numTriangles, Morpher::Triangle * triangles)
  189. {
  190.     UInt32 numVertices = rawVertices.size();
  191.  
  192.     std::vector<Morpher::Vector3> tan1;
  193.     std::vector<Morpher::Vector3> tan2;
  194.     tan1.resize(numVertices);
  195.     tan2.resize(numVertices);
  196.  
  197.     for (UInt32 i = 0; i < numTriangles; i++)
  198.     {
  199.         int i1 = triangles[i].p1;
  200.         int i2 = triangles[i].p2;
  201.         int i3 = triangles[i].p3;
  202.  
  203.         Morpher::Vector3 v1 = rawVertices[i1];
  204.         Morpher::Vector3 v2 = rawVertices[i2];
  205.         Morpher::Vector3 v3 = rawVertices[i3];
  206.  
  207.         Morpher::Vector2 w1 = rawUV[i1];
  208.         Morpher::Vector2 w2 = rawUV[i2];
  209.         Morpher::Vector2 w3 = rawUV[i3];
  210.  
  211.         float x1 = v2.x - v1.x;
  212.         float x2 = v3.x - v1.x;
  213.         float y1 = v2.y - v1.y;
  214.         float y2 = v3.y - v1.y;
  215.         float z1 = v2.z - v1.z;
  216.         float z2 = v3.z - v1.z;
  217.  
  218.         float s1 = w2.u - w1.u;
  219.         float s2 = w3.u - w1.u;
  220.         float t1 = w2.v - w1.v;
  221.         float t2 = w3.v - w1.v;
  222.  
  223.         float r = (s1 * t2 - s2 * t1);
  224.         r = (r >= 0.0f ? +1.0f : -1.0f);
  225.  
  226.         Morpher::Vector3 sdir = Morpher::Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r);
  227.         Morpher::Vector3 tdir = Morpher::Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r);
  228.  
  229.         sdir.Normalize();
  230.         tdir.Normalize();
  231.  
  232.         tan1[i1] += tdir;
  233.         tan1[i2] += tdir;
  234.         tan1[i3] += tdir;
  235.  
  236.         tan2[i1] += sdir;
  237.         tan2[i2] += sdir;
  238.         tan2[i3] += sdir;
  239.     }
  240.  
  241.     for (UInt32 i = 0; i < numVertices; i++)
  242.     {
  243.         rawTangents[i] = tan1[i];
  244.         rawBitangents[i] = tan2[i];
  245.  
  246.         if (rawTangents[i].IsZero() || rawBitangents[i].IsZero())
  247.         {
  248.             rawTangents[i].x = rawNormals[i].y;
  249.             rawTangents[i].y = rawNormals[i].z;
  250.             rawTangents[i].z = rawNormals[i].x;
  251.             rawBitangents[i] = rawNormals[i].cross(rawTangents[i]);
  252.         }
  253.         else
  254.         {
  255.             rawTangents[i].Normalize();
  256.             rawTangents[i] = (rawTangents[i] - rawNormals[i] * rawNormals[i].dot(rawTangents[i]));
  257.             rawTangents[i].Normalize();
  258.  
  259.             rawBitangents[i].Normalize();
  260.  
  261.             rawBitangents[i] = (rawBitangents[i] - rawNormals[i] * rawNormals[i].dot(rawBitangents[i]));
  262.             rawBitangents[i] = (rawBitangents[i] - rawTangents[i] * rawTangents[i].dot(rawBitangents[i]));
  263.  
  264.             rawBitangents[i].Normalize();
  265.         }
  266.     }
  267. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement