Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- bool MorphHandler::SaveJsonPreset(const char * filePath)
- {
- Json::StyledWriter writer;
- Json::Value root;
- IFileStream currentFile;
- IFileStream::MakeAllDirs(filePath);
- if (!currentFile.Create(filePath))
- {
- _ERROR("%s: couldn't create preset file (%s) Error (%d)", __FUNCTION__, filePath, GetLastError());
- return true;
- }
- Json::Value versionInfo;
- versionInfo["signature"] = PresetHeader::kSignature;
- versionInfo["formatVersion"] = PresetHeader::kVersion;
- versionInfo["skseVersion"] = PACKED_SKSE_VERSION;
- versionInfo["runtimeVersion"] = RUNTIME_VERSION_1_9_32_0;
- PlayerCharacter * player = (*g_thePlayer);
- TESNPC * npc = DYNAMIC_CAST(player->baseForm, TESForm, TESNPC);
- DataHandler * dataHandler = DataHandler::GetSingleton();
- bool isFemale = false;
- if (npc)
- isFemale = CALL_MEMBER_FN(npc, GetSex)() == 1;
- std::map<UInt8, const char *> modList;
- std::map<UInt8, BGSHeadPart*> partList;
- UInt32 numHeadParts = 0;
- BGSHeadPart ** headParts = NULL;
- if (CALL_MEMBER_FN(npc, HasOverlays)()) {
- numHeadParts = GetNumActorBaseOverlays(npc);
- headParts = GetActorBaseOverlays(npc);
- }
- else {
- numHeadParts = npc->numHeadParts;
- headParts = npc->headparts;
- }
- for (UInt32 i = 0; i < numHeadParts; i++) // Acquire all unique parts
- {
- BGSHeadPart * headPart = headParts[i];
- if (headPart && !headPart->IsExtraPart()) {
- UInt8 modIndex = headPart->formID >> 24;
- ModInfo* modInfo = dataHandler->modList.modInfoList.GetNthItem(modIndex);
- if (modInfo) {
- modList.emplace(modInfo->modIndex, modInfo->name);
- partList.emplace(i, headPart);
- }
- }
- }
- std::map<UInt8, std::pair<UInt32, const char*>> tintList;
- for (UInt32 i = 0; i < player->tintMasks.count; i++)
- {
- TintMask * tintMask = NULL;
- if (player->tintMasks.GetNthItem(i, tintMask))
- {
- UInt32 tintColor = ((UInt32)(tintMask->alpha * 255.0) << 24) | tintMask->color.red << 16 | tintMask->color.green << 8 | tintMask->color.blue;
- if (tintMask->texture)
- tintList.emplace(i, std::make_pair(tintColor, tintMask->texture->str.data));
- }
- }
- Json::Value modInfo;
- for (auto mIt = modList.begin(); mIt != modList.end(); ++mIt)
- {
- Json::Value mod;
- mod["index"] = mIt->first;
- mod["name"] = mIt->second;
- modInfo.append(mod);
- }
- Json::Value headPartInfo;
- for (auto pIt = partList.begin(); pIt != partList.end(); ++pIt)
- {
- Json::Value partInfo;
- partInfo["type"] = pIt->first;
- partInfo["formId"] = (Json::UInt)pIt->second->formID;
- headPartInfo.append(partInfo);
- }
- Json::Value tintInfo;
- for (auto tmIt = tintList.begin(); tmIt != tintList.end(); ++tmIt)
- {
- Json::Value tint;
- tint["index"] = tmIt->first;
- tint["color"] = (Json::UInt)tmIt->second.first;
- tint["texture"] = tmIt->second.second;
- tintInfo.append(tint);
- }
- Json::Value morphInfo;
- if (npc->faceMorph)
- {
- for (UInt8 p = 0; p < TESNPC::FaceMorphs::kNumPresets; p++) {
- Json::Value morphValue = (Json::UInt)npc->faceMorph->presets[p];
- morphInfo["presets"].append(morphValue);
- }
- for (UInt8 o = 0; o < TESNPC::FaceMorphs::kNumOptions; o++) {
- Json::Value morphValue = npc->faceMorph->option[o];
- morphInfo["morphs"].append(morphValue);
- }
- }
- Json::Value customMorphInfo;
- ValueSet * valueSet = m_valueMap.GetValueSet(npc);
- if (valueSet)
- {
- for (auto it = valueSet->begin(); it != valueSet->end(); ++it)
- {
- if (it->second != 0.0) {
- Json::Value morphValue;
- morphValue["name"] = it->first.data;
- morphValue["value"] = it->second;
- customMorphInfo.append(morphValue);
- }
- }
- }
- Json::Value sculptData;
- auto sculptTarget = GetSculptTarget(npc, false);
- if (sculptTarget) {
- for (UInt32 i = 0; i < numHeadParts; i++) // Acquire all unique parts
- {
- BGSHeadPart * headPart = headParts[i];
- if (headPart) {
- BSFixedString morphPath = SculptData::GetHostByPart(headPart);
- auto sculptHost = sculptTarget->GetSculptHost(morphPath, false);
- if (sculptHost) {
- Json::Value hostData;
- hostData["host"] = morphPath.data;
- TRIModelData data;
- GetModelTri(morphPath, data);
- hostData["vertices"] = (Json::UInt)data.vertexCount;
- for (auto morph : *sculptHost) {
- Json::Value value;
- value.append(morph.first);
- value.append((Json::Int)(morph.second.x * VERTEX_MULTIPLIER));
- value.append((Json::Int)(morph.second.y * VERTEX_MULTIPLIER));
- value.append((Json::Int)(morph.second.z * VERTEX_MULTIPLIER));
- hostData["data"].append(value);
- }
- sculptData.append(hostData);
- }
- }
- }
- }
- Json::Value textureInfo;
- BGSHeadPart * facePart = npc->GetCurrentHeadPartByType(BGSHeadPart::kTypeFace);
- if (facePart) {
- BGSTextureSet * textureSet = GetTextureSetForPart(npc, facePart);
- if (textureSet) {
- for (UInt8 i = 0; i < BSShaderTextureSet::kNumTextures; i++) {
- const char * texturePath = textureSet->textureSet.GetTexturePath(i);
- if (texturePath != NULL) {
- Json::Value textureValue;
- textureValue["index"] = i;
- textureValue["texture"] = texturePath;
- textureInfo.append(textureValue);
- }
- }
- }
- }
- // Collect override data
- PresetData::OverrideData overrideData;
- if (g_overrideInterface) {
- g_overrideInterface->VisitNodes(player, [&overrideData](BSFixedString node, OverrideVariant & value)
- {
- overrideData[node].push_back(value);
- });
- }
- // Collect transform data
- PresetData::TransformData transformData[2];
- if (g_transformInterface) {
- for (UInt32 i = 0; i <= 1; i++) {
- g_transformInterface->VisitNodes(player, i == 1, isFemale, [&i, &transformData](BSFixedString node, OverrideRegistration<BSFixedString> * keys)
- {
- keys->Visit([&i, &node, &transformData](const BSFixedString & key, OverrideSet * set)
- {
- set->Visit([&i, &node, &transformData, &key](OverrideVariant * value)
- {
- transformData[i][node][key].push_back(*value);
- return false;
- });
- return false;
- });
- return false;
- });
- }
- }
- // Collect body morph data
- PresetData::BodyMorphData bodyMorphData;
- if (g_bodyMorphInterface) {
- g_bodyMorphInterface->VisitMorphs(player, [&](BSFixedString name, float value)
- {
- bodyMorphData[name] = value;
- });
- }
- for (UInt32 i = 0; i <= 1; i++) {
- for (auto & data : transformData[i]) {
- Json::Value transform;
- transform["firstPerson"] = (bool)(i == 1);
- transform["node"] = data.first.data;
- for (auto & key : data.second) {
- Json::Value transformKey;
- transformKey["name"] = key.first.data;
- for (auto & value : key.second) {
- Json::Value jvalue;
- jvalue["key"] = value.key;
- jvalue["type"] = value.type;
- jvalue["index"] = value.index;
- switch (value.type) {
- case OverrideVariant::kType_Bool:
- jvalue["data"] = value.data.b;
- break;
- case OverrideVariant::kType_Int:
- jvalue["data"] = value.data.i;
- break;
- case OverrideVariant::kType_Float:
- jvalue["data"] = value.data.f;
- break;
- case OverrideVariant::kType_String:
- jvalue["data"] = value.data.GetStr()->data;
- break;
- }
- transformKey["values"].append(jvalue);
- }
- transform["keys"].append(transformKey);
- }
- root["transforms"].append(transform);
- }
- }
- for (auto & data : overrideData) {
- Json::Value ovr;
- ovr["node"] = data.first.data;
- for (auto & value : data.second) {
- Json::Value jvalue;
- jvalue["key"] = value.key;
- jvalue["type"] = value.type;
- jvalue["index"] = value.index;
- switch (value.type) {
- case OverrideVariant::kType_Bool:
- jvalue["data"] = value.data.b;
- break;
- case OverrideVariant::kType_Int:
- jvalue["data"] = value.data.i;
- break;
- case OverrideVariant::kType_Float:
- jvalue["data"] = value.data.f;
- break;
- case OverrideVariant::kType_String:
- jvalue["data"] = value.data.GetStr()->data;
- break;
- }
- ovr["values"].append(jvalue);
- }
- root["overrides"].append(ovr);
- }
- for (auto & data : bodyMorphData) {
- Json::Value bm;
- bm["name"] = data.first.data;
- bm["value"] = data.second;
- root["bodyMorphs"].append(bm);
- }
- root["version"] = versionInfo;
- root["mods"] = modInfo;
- root["headParts"] = headPartInfo;
- root["actor"]["weight"] = npc->weight;
- if (npc->headData) {
- auto hairColor = npc->headData->hairColor;
- if (hairColor)
- root["actor"]["hairColor"] = (Json::UInt)(hairColor->color.red << 16 | hairColor->color.green << 8 | hairColor->color.blue);
- }
- root["tintInfo"] = tintInfo;
- root["faceTextures"] = textureInfo;
- root["morphs"]["default"] = morphInfo;
- root["morphs"]["custom"] = customMorphInfo;
- root["morphs"]["sculptDivisor"] = VERTEX_MULTIPLIER;
- root["morphs"]["sculpt"] = sculptData;
- std::string data = writer.write(root);
- currentFile.WriteBuf(data.c_str(), data.length());
- currentFile.Close();
- return false;
- }
- bool MorphHandler::LoadJsonPreset(const char * filePath, PresetDataPtr presetData)
- {
- bool loadError = false;
- BSResourceNiBinaryStream file(filePath);
- if (!file.IsValid()) {
- _ERROR("%s: File %s failed to open.", __FUNCTION__, filePath);
- loadError = true;
- return loadError;
- }
- std::string in;
- BSReadAll(&file, &in);
- Json::Features features;
- features.all();
- Json::Value root;
- Json::Reader reader(features);
- bool parseSuccess = reader.parse(in, root);
- if (!parseSuccess) {
- _ERROR("%s: Error occured parsing json for %s.", __FUNCTION__, filePath);
- loadError = true;
- return loadError;
- }
- Json::Value defaultValue;
- Json::Value version = root["version"];
- if (version.empty()) {
- _ERROR("%s: No version header.", __FUNCTION__);
- loadError = true;
- return loadError;
- }
- UInt32 signature = version["signature"].asUInt();
- if (signature != PresetHeader::kSignature)
- {
- _ERROR("%s: invalid file signature (found %08X expected %08X)", __FUNCTION__, signature, PresetHeader::kSignature);
- loadError = true;
- return loadError;
- }
- UInt32 formatVersion = version["formatVersion"].asUInt();
- if (formatVersion <= PresetHeader::kVersion_Invalid)
- {
- _ERROR("%s: version invalid (%08X)", __FUNCTION__, formatVersion);
- loadError = true;
- return loadError;
- }
- Json::Value mods = root["mods"];
- if (mods.empty()) {
- _ERROR("%s: No mods header.", __FUNCTION__);
- loadError = true;
- return loadError;
- }
- DataHandler * dataHandler = DataHandler::GetSingleton();
- std::map<UInt8, std::string> modList;
- if (mods.type() == Json::arrayValue) {
- for (auto & mod : mods) {
- UInt8 modIndex = mod["index"].asUInt();
- std::string modName = mod["name"].asString();
- modList.emplace(modIndex, modName);
- presetData->modList.push_back(modName);
- }
- }
- Json::Value headParts = root["headParts"];
- if (!headParts.empty() && headParts.type() == Json::arrayValue) {
- for (auto & part : headParts) {
- UInt8 partType = part["type"].asUInt();
- UInt32 formId = part["formId"].asUInt();
- UInt8 modIndex = formId >> 24;
- auto it = modList.find(modIndex);
- if (it != modList.end()) {
- UInt8 gameIndex = dataHandler->GetModIndex(it->second.c_str());
- if (gameIndex != 255) {
- formId = (formId & 0x00FFFFFF) | (gameIndex << 24);
- TESForm * headPartForm = LookupFormByID(formId);
- if (headPartForm) {
- BGSHeadPart * headPart = DYNAMIC_CAST(headPartForm, TESForm, BGSHeadPart);
- if (headPart) {
- presetData->headParts.push_back(headPart);
- }
- }
- else {
- _WARNING("Could not resolve part %08X", formId);
- }
- }
- else {
- _WARNING("Could not load part type %d from %s; mod not found.", partType, it->second.c_str());
- }
- }
- }
- }
- Json::Value actor = root["actor"];
- if (!actor.empty() && actor.type() == Json::objectValue) {
- presetData->weight = actor["weight"].asFloat();
- presetData->hairColor = actor["hairColor"].asUInt();
- }
- Json::Value tintInfo = root["tintInfo"];
- if (!tintInfo.empty() && tintInfo.type() == Json::arrayValue) {
- for (auto & tint : tintInfo) {
- PresetData::Tint tintData;
- tintData.color = tint["color"].asUInt();
- tintData.index = tint["index"].asUInt();
- tintData.name = tint["texture"].asString().c_str();
- presetData->tints.push_back(tintData);
- }
- }
- Json::Value faceTextures = root["faceTextures"];
- if (!faceTextures.empty() && faceTextures.type() == Json::arrayValue) {
- for (auto & faceTexture : faceTextures) {
- PresetData::Texture texture;
- texture.index = faceTexture["index"].asUInt();
- texture.name = faceTexture["texture"].asString().c_str();
- presetData->faceTextures.push_back(texture);
- }
- }
- Json::Value morphs = root["morphs"];
- if (!morphs.empty()) {
- Json::Value defaultMorphs = morphs["default"];
- if (!defaultMorphs.empty()) {
- Json::Value presets = defaultMorphs["presets"];
- for (auto & preset : presets) {
- UInt32 presetValue = preset.asUInt();
- if (presetValue == 255)
- presetValue = -1;
- presetData->presets.push_back(presetValue);
- }
- Json::Value morphs = defaultMorphs["morphs"];
- for (auto & morph : morphs) {
- presetData->morphs.push_back(morph.asFloat());
- }
- }
- Json::Value customMorphs = morphs["custom"];
- if (!customMorphs.empty()) {
- for (auto & customMorph : customMorphs) {
- PresetData::Morph morph;
- morph.name = customMorph["name"].asString().c_str();
- morph.value = customMorph["value"].asFloat();
- presetData->customMorphs.push_back(morph);
- }
- }
- SInt32 multiplier = -1;
- Json::Value sculptMult = morphs["sculptDivisor"];
- if (!sculptMult.empty())
- multiplier = sculptMult.asInt();
- Json::Value sculptData = morphs["sculpt"];
- if (!sculptData.empty()) {
- presetData->sculptData = std::make_shared<SculptData>();
- for (auto & hostFile : sculptData) {
- BSFixedString host = hostFile["host"].asString().c_str();
- Json::Value data = hostFile["data"];
- auto sculptedData = std::make_shared<MappedSculptData>();
- for (auto & morphData : data) {
- UInt16 index = morphData[0].asUInt();
- NiPoint3 pt;
- if (multiplier > 0) {
- pt.x = (float)morphData[1].asInt() / (float)multiplier;
- pt.y = (float)morphData[2].asInt() / (float)multiplier;
- pt.z = (float)morphData[3].asInt() / (float)multiplier;
- } else {
- pt.x = morphData[1].asFloat();
- pt.y = morphData[2].asFloat();
- pt.z = morphData[3].asFloat();
- }
- sculptedData->force_insert(std::make_pair(index, pt));
- }
- presetData->sculptData->emplace(host, sculptedData);
- }
- }
- }
- Json::Value transforms = root["transforms"];
- if (!transforms.empty()) {
- for (auto & xForm : transforms) {
- bool isFirstPerson = xForm["firstPerson"].asBool();
- BSFixedString nodeName = xForm["node"].asString().c_str();
- Json::Value keys = xForm["keys"];
- for (auto & key : keys) {
- BSFixedString keyName = key["name"].asString().c_str();
- Json::Value values = key["values"];
- for (auto & jvalue : values) {
- OverrideVariant value;
- value.key = jvalue["key"].asUInt();
- value.type = jvalue["type"].asInt();
- value.index = jvalue["index"].asInt();
- switch (value.type) {
- case OverrideVariant::kType_Bool:
- value.data.b = jvalue["data"].asBool();
- break;
- case OverrideVariant::kType_Int:
- value.data.i = jvalue["data"].asInt();
- break;
- case OverrideVariant::kType_Float:
- value.data.f = jvalue["data"].asFloat();
- break;
- case OverrideVariant::kType_String:
- value.data.str = BSFixedString(jvalue["data"].asString().c_str()).data;
- break;
- }
- presetData->transformData[isFirstPerson ? 1 : 0][nodeName][keyName].push_back(value);
- }
- }
- }
- }
- Json::Value overrides = root["overrides"];
- if (!overrides.empty()) {
- for (auto & ovr : overrides) {
- BSFixedString node = ovr["node"].asString().c_str();
- Json::Value values = ovr["values"];
- for (auto & jvalue : values) {
- OverrideVariant value;
- value.key = jvalue["key"].asUInt();
- value.type = jvalue["type"].asInt();
- value.index = jvalue["index"].asInt();
- switch (value.type) {
- case OverrideVariant::kType_Bool:
- value.data.b = jvalue["data"].asBool();
- break;
- case OverrideVariant::kType_Int:
- value.data.i = jvalue["data"].asInt();
- break;
- case OverrideVariant::kType_Float:
- value.data.f = jvalue["data"].asFloat();
- break;
- case OverrideVariant::kType_String:
- value.data.str = BSFixedString(jvalue["data"].asString().c_str()).data;
- break;
- }
- presetData->overrideData[node].push_back(value);
- }
- }
- }
- Json::Value bodyMorphs = root["bodyMorphs"];
- if (!bodyMorphs.empty()) {
- for (auto & bm : bodyMorphs) {
- BSFixedString name = bm["name"].asString().c_str();
- float value = bm["value"].asFloat();
- presetData->bodyMorphData[name] = value;
- }
- }
- return loadError;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement