Advertisement
expired6978

CharGen Code

Jun 29th, 2014
392
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.76 KB | None | 0 0
  1.  
  2. class FaceGenVisitor : public TriBasedGeometryVisitor
  3. {
  4. public:
  5.     FaceGenVisitor::FaceGenVisitor(BSFixedString faceNode, std::vector<PresetData::Texture> * faceTextures, BSFixedString tintTexture, UInt32 hairColor) : m_faceTextures(faceTextures), m_faceNode(faceNode), m_tintTexture(tintTexture), m_hairColor(hairColor) {};
  6.  
  7.     virtual bool Accept(NiTriBasedGeom * geometry)
  8.     {
  9.         BSShaderProperty * shaderProperty = niptr_cast<BSShaderProperty>(geometry->m_spEffectState);
  10.         if(shaderProperty) {
  11.             if(shaderProperty->GetRTTI() == NiRTTI_BSLightingShaderProperty) {
  12.                 BSLightingShaderProperty * lightingShader = (BSLightingShaderProperty *)shaderProperty;
  13.                 BSLightingShaderMaterial * material = (BSLightingShaderMaterial *)shaderProperty->material;
  14.                 if(BSFixedString(geometry->m_name) == m_faceNode) {
  15.                     for(std::vector<PresetData::Texture>::iterator it = m_faceTextures->begin(); it != m_faceTextures->end(); ++it)
  16.                         material->textureSet->SetTexturePath((*it).index, (*it).name.data);
  17.                     material->textureSet->SetTexturePath(6, m_tintTexture.data);
  18.                     material->ReleaseTextures();
  19.                     CALL_MEMBER_FN(lightingShader, InvalidateTextures)(0);
  20.                     CALL_MEMBER_FN(lightingShader, InitializeShader)(geometry);
  21.                 } else if(material->GetShaderType() == BSLightingShaderMaterial::kShaderType_HairTint) {
  22.                     BSTintedShaderMaterial * tintedMaterial = (BSTintedShaderMaterial *)material; // I don't know what this * 2.0 bullshit is.
  23.                     tintedMaterial->tintColor.r = (((m_hairColor >> 16) & 0xFF) / 255.0) * 2.0;
  24.                     tintedMaterial->tintColor.g = (((m_hairColor >> 8) & 0xFF) / 255.0) * 2.0;
  25.                     tintedMaterial->tintColor.b = ((m_hairColor & 0xFF) / 255.0) * 2.0;
  26.                 }
  27.             }
  28.         }
  29.  
  30.         return false;
  31.     }
  32.  
  33.     BSFixedString                       m_faceNode;
  34.     std::vector<PresetData::Texture>    * m_faceTextures;
  35.     BSFixedString                       m_tintTexture;
  36.     UInt32                              m_hairColor;
  37. };
  38.  
  39.  
  40.  
  41.  
  42.  
  43. class SKSETaskOverlayCharacter : public TaskDelegate
  44. {
  45.     virtual void Run()
  46.     {
  47.         if(m_actor && m_presetData)
  48.         {
  49.             TESNPC * npc = DYNAMIC_CAST(m_actor->baseForm, TESForm, TESNPC);
  50.             BSFaceGenNiNode * faceNode = m_actor->GetFaceGenNiNode();
  51.             if(!npc || !faceNode) {
  52.                 return;
  53.             }
  54.  
  55.             for(std::vector<BGSHeadPart*>::iterator it = m_presetData->headParts.begin(); it != m_presetData->headParts.end(); ++it) {
  56.                 BGSHeadPart * oldPart = npc->GetCurrentHeadPartByType((*it)->type);
  57.                 CALL_MEMBER_FN(npc, ChangeHeadPart)(*it);
  58.                 ChangeActorHeadPart(m_actor, oldPart, (*it));
  59.             }
  60.  
  61.             BGSHeadPart * facePart = npc->GetCurrentHeadPartByType(BGSHeadPart::kTypeFace);
  62.             if(facePart) {
  63.                 FaceGenVisitor faceVisitor(facePart->partName, &m_presetData->faceTextures, m_tintPath, m_presetData->hairColor);
  64.                 VisitGeometry(faceNode, &faceVisitor);
  65.             }
  66.         }
  67.     }
  68.  
  69.     virtual void Dispose()
  70.     {
  71.         s_loadCharacterLock.Leave();
  72.         if(m_presetData)
  73.             delete m_presetData;
  74.         delete this;
  75.     }
  76.  
  77. public:
  78.     SKSETaskOverlayCharacter::SKSETaskOverlayCharacter(Actor * actor, PresetData * presetData, BSFixedString tintPath) : m_actor(actor), m_presetData(presetData), m_tintPath(tintPath) {};
  79.  
  80.     Actor           * m_actor;
  81.     PresetData      * m_presetData;
  82.     BSFixedString   m_tintPath;
  83. };
  84.  
  85.  
  86.  
  87.  
  88.  
  89.  
  90.  
  91.     bool LoadCharacter(StaticFunctionTag*, Actor * actor, TESRace * race, BSFixedString fileName)
  92.     {
  93.         if(!s_loadCharacterLock.TryEnter()) {
  94.             return false;
  95.         }
  96.  
  97.         PresetData * presetData = new PresetData;
  98.         std::string path = "Data\\SKSE\\Plugins\\CharGen\\Exported\\";
  99.         std::string slot = path;
  100.         slot.append(fileName.data);
  101.         slot.append(".slot");
  102.  
  103.         if(g_morphHandler.LoadPreset(slot.c_str(), presetData, true)) {
  104.             s_loadCharacterLock.Leave();
  105.             return false;
  106.         }
  107.  
  108.         std::string tint = "Data\\Textures\\CharGen\\Exported\\";
  109.         tint.append(fileName.data);
  110.         tint.append(".dds");
  111.  
  112.         BSFixedString tintPath(tint.c_str());
  113.  
  114.         TESNPC * npc = DYNAMIC_CAST(actor->baseForm, TESForm, TESNPC);
  115.         BSFaceGenNiNode * faceNode = actor->GetFaceGenNiNode();
  116.         if(!npc || !faceNode) {
  117.             s_loadCharacterLock.Leave();
  118.             return false;
  119.         }
  120.  
  121.         CALL_MEMBER_FN(actor, SetRace)(race, actor == (*g_thePlayer));
  122.  
  123.         npc->weight = presetData->weight;
  124.  
  125.         UInt32 i = 0;
  126.         for(std::vector<SInt32>::iterator it = presetData->presets.begin(); it != presetData->presets.end(); ++it) {
  127.             npc->faceMorph->presets[i] = *it;
  128.             i++;
  129.         }
  130.  
  131.         i = 0;
  132.         for(std::vector<float>::iterator it = presetData->morphs.begin(); it != presetData->morphs.end(); ++it) {
  133.             npc->faceMorph->option[i] = *it;
  134.             i++;
  135.         }
  136.  
  137.         // Assign custom morphs here (values only)
  138.         g_morphHandler.Revert(npc);
  139.         for(std::vector<PresetData::Morph>::iterator it = presetData->customMorphs.begin(); it != presetData->customMorphs.end(); ++it) {
  140.             g_morphHandler.SetMorphValue(npc, it->name, it->value);
  141.         }
  142.  
  143.         // Forcing a part change should invalidate the listing
  144.         for(std::vector<BGSHeadPart*>::iterator it = presetData->headParts.begin(); it != presetData->headParts.end(); ++it)
  145.             CALL_MEMBER_FN(npc, ChangeHeadPart)(*it);
  146.  
  147.         // Grab the skin tint and convert it from RGBA to RGB on NPC
  148.         if(presetData->tints.size() > 0) {
  149.             PresetData::Tint & tint = presetData->tints.at(0);
  150.             float alpha = (tint.color >> 24) / 255.0;
  151.             TintMask tintMask;
  152.             tintMask.color.red = (tint.color >> 16) & 0xFF;
  153.             tintMask.color.green = (tint.color >> 8) & 0xFF;
  154.             tintMask.color.blue = tint.color & 0xFF;
  155.             tintMask.alpha = alpha;
  156.             tintMask.tintType = TintMask::kMaskType_SkinTone;
  157.  
  158.             NiColorA colorResult;
  159.             CALL_MEMBER_FN(npc, SetSkinFromTint)(&colorResult, &tintMask, 1, 0);
  160.         }
  161.  
  162.         // Queue a node update
  163.         CALL_MEMBER_FN(actor, QueueNiNodeUpdate)(true);
  164.  
  165.         // Queue custom task (should happen after node update) to apply the exported FaceTint file and hair color
  166.         g_task->AddTask(new SKSETaskOverlayCharacter(actor, presetData, tintPath));
  167.         return true;
  168.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement