Advertisement
expired6978

SkeletonExtender

Aug 22nd, 2015
177
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.45 KB | None | 0 0
  1. #include <set>
  2. #include <algorithm>
  3. #include <iterator>
  4.  
  5. #include "SkeletonExtender.h"
  6. #include "ShaderUtilities.h"
  7. #include "json\json.h"
  8. #include "interfaces/NiTransformInterface.h"
  9.  
  10. #include "skse/NiNodes.h"
  11. #include "skse/NiObjects.h"
  12. #include "skse/NiExtraData.h"
  13. #include "skse/NiSerialization.h"
  14.  
  15. #include "skse/GameReferences.h"
  16. #include "skse/GameStreams.h"
  17. #include "skse/GameRTTI.h"
  18.  
  19. extern NiTransformInterface g_transformInterface;
  20.  
  21. void SkeletonExtender::AddTransforms(TESObjectREFR * refr, bool isFirstPerson, NiNode * skeleton, NiAVObject * objectRoot)
  22. {
  23.     std::set<BSFixedString> previous_nodes;
  24.     std::set<BSFixedString> current_nodes;
  25.     std::set<BSFixedString> diffs;
  26.  
  27.     UInt8 gender = 0;
  28.     TESNPC * actorBase = DYNAMIC_CAST(refr->baseForm, TESForm, TESNPC);
  29.     if (actorBase)
  30.         gender = CALL_MEMBER_FN(actorBase, GetSex)();
  31.  
  32.     NiStringsExtraData * globalData = ni_cast(FindExtraData(skeleton, "BNDT"), NiStringsExtraData);
  33.     if (globalData)
  34.     {
  35.         for (int i = 0; i < globalData->m_size; i++)
  36.         {
  37.             BSFixedString node(globalData->m_data[i]);
  38.             previous_nodes.insert(node);
  39.         }
  40.     }
  41.  
  42.     VisitObjects(skeleton, [&](NiAVObject*object)
  43.     {
  44.         NiStringExtraData * stringData = ni_cast(object->GetExtraData(BSFixedString("SDTA").data), NiStringExtraData);
  45.         if (stringData)
  46.         {
  47.             try
  48.             {
  49.                 Json::Features features;
  50.                 features.all();
  51.  
  52.                 Json::Value root;
  53.                 Json::Reader reader(features);
  54.  
  55.                 bool parseSuccess = reader.parse(stringData->m_pString, root);
  56.                 if (parseSuccess)
  57.                 {
  58.                     for (auto & objects : root)
  59.                     {
  60.                         BSFixedString node = objects["name"].asCString();
  61.                         current_nodes.insert(node);
  62.                     }
  63.                 }
  64.             }
  65.             catch (...)
  66.             {
  67.                 _ERROR("%s - Error - Failed to parse skeleton transform data", __FUNCTION__);
  68.             }
  69.         }
  70.  
  71.         return false;
  72.     });
  73.  
  74.     // Differences here means we lost nodes
  75.     std::set_symmetric_difference(current_nodes.begin(), current_nodes.end(),
  76.                         previous_nodes.begin(), previous_nodes.end(),
  77.                         std::inserter(diffs, diffs.begin()));
  78.  
  79.     for (auto & node : diffs)
  80.     {
  81.         g_transformInterface.RemoveNodeTransform(refr, isFirstPerson, gender == 1, node, "internal");
  82.     }
  83.  
  84.     diffs.clear();
  85.  
  86.     NiStringExtraData * stringData = ni_cast(FindExtraData(objectRoot, "SDTA"), NiStringExtraData);
  87.     ReadTransforms(refr, stringData, isFirstPerson, gender == 1, current_nodes);
  88.  
  89.     std::set_symmetric_difference(current_nodes.begin(), current_nodes.end(),
  90.                         previous_nodes.begin(), previous_nodes.end(),
  91.                         std::inserter(diffs, diffs.begin()));
  92.  
  93.     for (auto & node : diffs)
  94.     {
  95.         g_transformInterface.UpdateNodeTransforms(refr, isFirstPerson, gender == 1, node);
  96.     }
  97.  
  98.     std::vector<BSFixedString> newNodes;
  99.     for (auto & node : current_nodes)
  100.     {
  101.         newNodes.push_back(node);
  102.     }
  103.  
  104.     // Was already there, set the new current nodes
  105.     if (globalData)
  106.     {
  107.         if (newNodes.size() == 0)
  108.         {
  109.             globalData->SetData(nullptr, 0);
  110.         }
  111.         else
  112.         {
  113.             globalData->SetData(&newNodes.at(0), newNodes.size());
  114.         }
  115.        
  116.     }
  117.  
  118.     // No previous nodes, and we have new nodes
  119.     if (!globalData && current_nodes.size() > 0)
  120.     {
  121.         NiStringsExtraData * strData = NiStringsExtraData::Create("BNDT", &newNodes.at(0), newNodes.size());
  122.         skeleton->AddExtraData(strData);
  123.     }
  124. }
  125.  
  126. void SkeletonExtender::ReadTransforms(TESObjectREFR * refr, NiStringExtraData * stringData, bool isFirstPerson, bool isFemale, std::set<BSFixedString> & nodes)
  127. {
  128.     if (stringData)
  129.     {
  130.         try
  131.         {
  132.             Json::Features features;
  133.             features.all();
  134.  
  135.             Json::Value root;
  136.             Json::Reader reader(features);
  137.  
  138.             bool parseSuccess = reader.parse(stringData->m_pString, root);
  139.             if (parseSuccess)
  140.             {
  141.                 for (auto & objects : root)
  142.                 {
  143.                     BSFixedString node = objects["name"].asCString();
  144.                     nodes.insert(node);
  145.  
  146.                     Json::Value pos = objects["pos"];
  147.                     if (pos.isArray() && pos.size() == 3)
  148.                     {
  149.                         float position[3];
  150.                         position[0] = pos[0].asFloat();
  151.                         position[1] = pos[1].asFloat();
  152.                         position[2] = pos[2].asFloat();
  153.  
  154.                         OverrideVariant posV[3];
  155.                         for (UInt32 i = 0; i < 3; i++) {
  156.                             PackValue<float>(&posV[i], OverrideVariant::kParam_NodeTransformPosition, i, &position[i]);
  157.                             g_transformInterface.AddNodeTransform(refr, isFirstPerson, isFemale, node, "internal", posV[i]);
  158.                         }
  159.                     }
  160.  
  161.                     NiMatrix33 rotation;
  162.                     Json::Value rot = objects["rot"];
  163.                     if (pos.isArray() && pos.size() == 3)
  164.                     {
  165.                         float rotationEuler[3];
  166.                         rotationEuler[0] = rot[0].asFloat() * MATH_PI / 180;
  167.                         rotationEuler[1] = rot[1].asFloat() * MATH_PI / 180;
  168.                         rotationEuler[2] = rot[2].asFloat() * MATH_PI / 180;
  169.                         rotation.SetEulerAngles(rotationEuler[0], rotationEuler[1], rotationEuler[2]);
  170.  
  171.                         OverrideVariant rotV[9];
  172.                         for (UInt32 i = 0; i < 9; i++) {
  173.                             PackValue<float>(&rotV[i], OverrideVariant::kParam_NodeTransformRotation, i, &rotation.arr[i]);
  174.                             g_transformInterface.AddNodeTransform(refr, isFirstPerson, isFemale, node, "internal", rotV[i]);
  175.                         }
  176.                     }
  177.  
  178.                     Json::Value scale = objects["scale"];
  179.                     if (scale.isDouble() && scale.asFloat() > 0)
  180.                     {
  181.                         float fScale = scale.asFloat();
  182.                         OverrideVariant scaleV;
  183.                         PackValue<float>(&scaleV, OverrideVariant::kParam_NodeTransformScale, 0, &fScale);
  184.                         g_transformInterface.AddNodeTransform(refr, isFirstPerson, isFemale, node, "internal", scaleV);
  185.                     }
  186.  
  187.                 }
  188.             }
  189.         }
  190.         catch (...)
  191.         {
  192.             _ERROR("%s - Error - Failed to parse skeleton transform data", __FUNCTION__);
  193.         }
  194.     }
  195. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement