Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- void SKSETaskExportHead::Run()
- {
- if (!m_actor)
- return;
- BSFaceGenNiNode * faceNode = m_actor->GetFaceGenNiNode();
- TESNPC * actorBase = DYNAMIC_CAST(m_actor->baseForm, TESForm, TESNPC);
- if (!actorBase)
- return;
- if (!faceNode)
- return;
- BSFaceGenAnimationData * animationData = m_actor->GetFaceGenAnimationData();
- if (animationData) {
- FaceGen::GetSingleton()->isReset = 0;
- for (UInt32 t = BSFaceGenAnimationData::kKeyframeType_Expression; t <= BSFaceGenAnimationData::kKeyframeType_Phoneme; t++)
- {
- BSFaceGenKeyframeMultiple * keyframe = &animationData->keyFrames[t];
- for (UInt32 i = 0; i < keyframe->count; i++)
- keyframe->values[i] = 0.0;
- keyframe->isUpdated = 0;
- }
- UpdateModelFace(faceNode);
- }
- IFileStream::MakeAllDirs(m_nifPath.data);
- BSFadeNode * rootNode = BSFadeNode::Create();
- rootNode->IncRef();
- NiNode * skinnedNode = NiNode::Create(0);
- skinnedNode->m_name = BSFixedString("BSFaceGenNiNodeSkinned").data;
- std::map<NiAVObject*, NiAVObject*> boneMap;
- for (UInt32 i = 0; i < faceNode->m_children.m_size; i++)
- {
- NiAVObject * object = faceNode->m_children.m_data[i];
- if (NiTriShape * trishape = object->GetAsNiTriShape()) {
- NiTriShapeData * trishapeData = niptr_cast<NiTriShapeData>(trishape->m_spModelData);
- NiTriShapeData * newTrishapeData = NULL;
- if (trishapeData)
- CALL_MEMBER_FN(trishapeData, DeepCopy)((NiObject **)&newTrishapeData);
- NiProperty * trishapeEffect = niptr_cast<NiProperty>(trishape->m_spEffectState);
- NiProperty * newTrishapeEffect = NULL;
- if (trishapeEffect)
- CALL_MEMBER_FN(trishapeEffect, DeepCopy)((NiObject **)&newTrishapeEffect);
- NiProperty * trishapeProperty = niptr_cast<NiProperty>(trishape->m_spPropertyState);
- NiProperty * newTrishapeProperty = NULL;
- if (trishapeProperty)
- CALL_MEMBER_FN(trishapeProperty, DeepCopy)((NiObject **)&newTrishapeProperty);
- NiSkinInstance * skinInstance = niptr_cast<NiSkinInstance>(trishape->m_spSkinInstance);
- NiSkinInstance * newSkinInstance = NULL;
- if (skinInstance) {
- BSDismemberSkinInstance * dismemberSkinInstance = ni_cast(skinInstance, BSDismemberSkinInstance);
- if (dismemberSkinInstance) {
- newSkinInstance = BSDismemberSkinInstance::Create();
- }
- else {
- newSkinInstance = NiSkinInstance::Create();
- }
- BSDismemberSkinInstance * newDismemberSkinInstance = ni_cast(newSkinInstance, BSDismemberSkinInstance);
- if (newDismemberSkinInstance) {
- newDismemberSkinInstance->numPartitions = dismemberSkinInstance->numPartitions;
- newDismemberSkinInstance->partitionFlags = (UInt32*)FormHeap_Allocate(newDismemberSkinInstance->numPartitions * sizeof(UInt32));
- memcpy(newDismemberSkinInstance->partitionFlags, dismemberSkinInstance->partitionFlags, newDismemberSkinInstance->numPartitions * sizeof(UInt32));
- }
- newSkinInstance->m_pkRootParent = skinnedNode;
- UInt32 numBones = 0;
- NiSkinData * skinData = niptr_cast<NiSkinData>(skinInstance->m_spSkinData);
- NiSkinData * newSkinData = NULL;
- if (skinData) {
- numBones = skinData->m_uiBones;
- CALL_MEMBER_FN(skinData, DeepCopy)((NiObject **)&newSkinData);
- }
- NiSkinPartition * skinPartition = niptr_cast<NiSkinPartition>(skinInstance->m_spSkinPartition);
- NiSkinPartition * newSkinPartition = NULL;
- if (skinPartition)
- CALL_MEMBER_FN(skinPartition, DeepCopy)((NiObject **)&newSkinPartition);
- newSkinInstance->m_spSkinData = newSkinData;
- newSkinInstance->m_spSkinPartition = newSkinPartition;
- // Remap the bones to new NiNode instances
- if (numBones > 0) {
- newSkinInstance->m_ppkBones = (NiAVObject**)FormHeap_Allocate(numBones * sizeof(NiAVObject*));
- for (UInt32 i = 0; i < numBones; i++)
- {
- NiAVObject * bone = skinInstance->m_ppkBones[i];
- auto it = boneMap.find(bone);
- if (it == boneMap.end()) {
- NiNode * newBone = NiNode::Create();
- newBone->m_name = bone->m_name;
- newBone->m_flags = bone->m_flags;
- boneMap.insert(std::make_pair(bone, newBone));
- newSkinInstance->m_ppkBones[i] = newBone;
- }
- else
- newSkinInstance->m_ppkBones[i] = it->second;
- }
- }
- }
- NiTriShape * newTrishape = NiTriShape::Create(newTrishapeData);
- newTrishape->m_localTransform = trishape->m_localTransform;
- newTrishape->m_name = trishape->m_name;
- memcpy(&newTrishape->unk88, &trishape->unk88, 0x1F);
- newTrishape->SetEffectState(newTrishapeEffect);
- newTrishape->SetPropertyState(newTrishapeProperty);
- newTrishape->SetSkinInstance(newSkinInstance);
- auto textureData = GetTextureSetForPartByName(actorBase, newTrishape->m_name);
- if (textureData.first && textureData.second) {
- BSShaderProperty * shaderProperty = niptr_cast<BSShaderProperty>(newTrishape->m_spEffectState);
- if (shaderProperty) {
- if (shaderProperty->GetRTTI() == NiRTTI_BSLightingShaderProperty) {
- BSLightingShaderProperty * lightingShader = (BSLightingShaderProperty *)shaderProperty;
- BSLightingShaderMaterial * material = (BSLightingShaderMaterial *)shaderProperty->material;
- for (UInt32 i = 0; i < BGSTextureSet::kNumTextures; i++)
- material->textureSet->SetTexturePath(i, textureData.first->textureSet.GetTexturePath(i));
- if (textureData.second->type == BGSHeadPart::kTypeFace)
- material->textureSet->SetTexturePath(6, m_ddsPath.data);
- }
- }
- // Save the previous tint mask
- BSShaderProperty * originalShaderProperty = niptr_cast<BSShaderProperty>(trishape->m_spEffectState);
- if (originalShaderProperty) {
- if (originalShaderProperty->GetRTTI() == NiRTTI_BSLightingShaderProperty) {
- BSLightingShaderProperty * lightingShader = (BSLightingShaderProperty *)originalShaderProperty;
- BSLightingShaderMaterial * material = (BSLightingShaderMaterial *)originalShaderProperty->material;
- if (material->GetShaderType() == BSShaderMaterial::kShaderType_FaceTint) {
- BSMaskedShaderMaterial * maskedMaterial = (BSMaskedShaderMaterial *)material;
- SaveRenderedDDS(maskedMaterial->renderedTexture, m_ddsPath.data);
- }
- }
- }
- }
- skinnedNode->AttachChild(newTrishape, true);
- }
- }
- for (auto & bones : boneMap)
- rootNode->AttachChild(bones.second, true);
- rootNode->AttachChild(skinnedNode, true);
- UInt8 niStreamMemory[0x5B4];
- memset(niStreamMemory, 0, 0x5B4);
- NiStream * niStream = (NiStream *)niStreamMemory;
- CALL_MEMBER_FN(niStream, ctor)();
- CALL_MEMBER_FN(niStream, AddObject)(rootNode);
- niStream->SavePath(m_nifPath.data);
- CALL_MEMBER_FN(niStream, dtor)();
- rootNode->DecRef();
- if (animationData) {
- animationData->overrideFlag = 0;
- CALL_MEMBER_FN(animationData, Reset)(1.0, 1, 1, 0, 0);
- FaceGen::GetSingleton()->isReset = 1;
- UpdateModelFace(faceNode);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement