#include "StdAfx.h" #include "Avatar.h" #include "Utils/ClientUtils.h" #include "ResourceManager.h" static char AvatarNodeName[MAX_INVENTORY_TYPES+3][30] = { //{"Error"}, // {"Helmet_Node"}, // 头盔 {"Gloves"}, // 手套 {"Chest"}, // 胸甲 {"Pants"}, // 腿 {"Boot"}, // 鞋 {"RightHand_Node"}, // 武器 {"LeftHand_Node"}, {"Necklace_Node"}, // 项链 {"RightShoulder_Node"}, // 肩甲 {"Belt"}, // 腰带 //{"Kneecap"}, // 护膝 // {"xxx"}, // 手链 {"xxx"}, // 戒指1 {"xxx"}, // 戒指2 {"xxx"}, // 饰品 {"xxx"}, // 饰品2 {"BacksideWing_Node"}, // hunter {"Helmet_Node"}, // hunter {"RightShoulder_Node"}, // hunter {"Chest"}, // hunter {"Pants"}, // hunter {"Boot"}, // hunter {"Shield_Node"}, {"RightHand_Node"}, {"bag"}, {"LeftHand_Node"}, // 骑乘点 }; static char AttachmementName[MAX_ATTACHMENT_SLOT][30] = { {"BacksideRightWeapon_Node"}, {"BacksideLeftWeapon_Node"} }; bool IsMeshLoaded(NiNode* pRootNode, int iPart, unsigned int uiId) { // // Get Object // Get Extra Data NiFixedString strNodeName = AvatarNodeName[iPart]; NiAVObject* pkAVObject = pRootNode->GetObjectByName(strNodeName); if(!pkAVObject) return false; if(NiIsKindOf(NiNode, pkAVObject)) { NiNode* pkNode = NiDynamicCast(NiNode,pkAVObject); if(pkNode && pkNode->GetArrayCount()) pkAVObject = pkNode->GetAt(0); if(!pkAVObject) return false; } NiIntegerExtraData* pkExtraData; pkExtraData = (NiIntegerExtraData*)pkAVObject->GetExtraData("ModelId"); if(pkExtraData == NULL) return false; if(pkExtraData->GetValue() == uiId) return true; return false; } bool IsTextureLoaded(NiNode* pRootNode, int iPart, NiFixedString& strTextureName) { // // Get Object // Get Texture Name NiFixedString strPartName = AvatarNodeName[iPart]; NiAVObject* pAVObj = pRootNode->GetObjectByName(strPartName); if(!pAVObj) return false; NiGeometry* pGemo = NULL; RecursiveGetGeometry(pAVObj, &pGemo); if(!pGemo) return false; NiTexturingProperty* pTexProperty = (NiTexturingProperty*)pGemo->GetProperty(NiProperty::TEXTURING); if(!pTexProperty) return false; NiTexturingProperty::Map* pBaseMap = pTexProperty->GetBaseMap(); if(!pBaseMap) return false; NiSourceTexture* pTexture = (NiSourceTexture*)pBaseMap->GetTexture(); if(!pTexture) return false; if(strcmp(strTextureName, pTexture->GetFilename()) != 0) return false; return true; } void GetNodeName(NiFixedString strSerNodeName, NiFixedString* strBaseNodeName, NiFixedString* strAttNodeName, unsigned int& uiNodeCount, int iAttachmentSlot) { if(strSerNodeName == "RightHand_Node") { strBaseNodeName[0] = "RightWeapon";// strBaseNodeName[1] = "LeftHand_Node"; strAttNodeName[0] = "AttackRightHand_Node";// strAttNodeName[1] = "LeftWeapon"; uiNodeCount = 1; } else if(strSerNodeName == "LeftHand_Node") { strBaseNodeName[0] = "LeftWeapon"; strAttNodeName[0] = "AttackLeftHand_Node"; uiNodeCount = 1; } else if(strSerNodeName == "Hair_Node") { strBaseNodeName[0] = "Hair"; strAttNodeName[0] = "Hair_Node"; uiNodeCount = 1; } else if(strSerNodeName == "RightShoulder_Node") { strBaseNodeName[0] = "Rshoulder"; strBaseNodeName[1] = "Lshoulder"; strAttNodeName[0] = "RightShoulder_Node"; strAttNodeName[1] = "LeftShoulder_Node"; uiNodeCount = 2; } else if(strSerNodeName == "Helmet_Node") { strBaseNodeName[0] = "Helmet"; strAttNodeName[0] = "Helmet_Node"; uiNodeCount = 1; } else if(strSerNodeName == "Shield_Node") { strAttNodeName[0] = "Shield_Node"; strBaseNodeName[0] = "ShieldNode"; uiNodeCount = 1; } else if(strSerNodeName == "Pet_Node01") { strAttNodeName[0] = "Role_Node"; strBaseNodeName[0] = "Pet"; uiNodeCount = 1; } else if(strSerNodeName == "BacksideWing_Node") { strAttNodeName[0] = "BacksideWing_Node"; strBaseNodeName[0] = "Wing"; uiNodeCount = 1; } } // 挂点特效 void GetNodeName(unsigned int uiPart, NiFixedString& strBaseNodeName, NiFixedString* strAttNodeName, unsigned int& uiNodeCount, int iAttachmentSlot) { NiFixedString strSerNodeName = AvatarNodeName[uiPart]; if(strSerNodeName == "Helmet_Node") { strAttNodeName[0] = "Eg_Helmet"; uiNodeCount = 1; strBaseNodeName = ""; } else if(strSerNodeName == "RightShoulder_Node") { strAttNodeName[0] = "Eg_Lshoulder"; strAttNodeName[1] = "Eg_Rshoulder"; strBaseNodeName = ""; uiNodeCount = 2; } else if(strSerNodeName == "Gloves") { strAttNodeName[0] = "Eg_Lgloves"; strAttNodeName[1] = "Eg_Rgloves"; strBaseNodeName = ""; uiNodeCount = 2; } else if(strSerNodeName == "Chest") { strAttNodeName[0] = "Eg_Chest"; strBaseNodeName = ""; uiNodeCount = 1; } else if(strSerNodeName == "Pants") { strAttNodeName[0] = "Eg_Lpants"; strAttNodeName[1] = "Eg_Rpants"; strBaseNodeName = ""; uiNodeCount = 2; } else if(strSerNodeName == "Boot") { strAttNodeName[0] = "Eg_Lboot"; strAttNodeName[1] = "Eg_Rboot"; strBaseNodeName = ""; uiNodeCount = 2; } else if(strSerNodeName == "RightHand_Node" || strSerNodeName == "LeftHand_Node" || strSerNodeName == "Shield_Node") { strAttNodeName[0] = "Effect_01"; strAttNodeName[1] = "Effect_02"; strAttNodeName[2] = "Effect_03"; strAttNodeName[3] = "Effect_04"; strAttNodeName[4] = "Effect_05"; uiNodeCount = 5; if (iAttachmentSlot != AS_None) { if (uiPart != INVTYPE_SHIELD) { strBaseNodeName = AttachmementName[iAttachmentSlot]; } }else { if (strSerNodeName == "RightHand_Node") { strBaseNodeName = "AttackRightHand_Node"; } if (strSerNodeName == "Shield_Node") { strBaseNodeName = "ShieldNode"; } if (strSerNodeName == "LeftHand_Node") { strBaseNodeName = "AttackLeftHand_Node"; } } } } bool CAvatar::ChangeAvatar(NiActorManager* pActorManager, NiObject* pAvatarObject, SAvatarInfo& sAvatarInfo, int iAttachmentSlot /*= -1*/) { if(!pActorManager || !pAvatarObject) return false; NiNode* pRootNode = (NiNode*)pActorManager->GetNIFRoot(); return ChangeAvatar(pRootNode, pAvatarObject, sAvatarInfo, iAttachmentSlot); } bool CAvatar::ChangeAvatar(NiNode* pkRootNode, NiObject* pkAvatarObject, SAvatarInfo& sAvatarInfo, int iAttachmentSlot /*= -1*/, NiBoneLODController* pkLODCtrl /*= 0*/) { if(sAvatarInfo.eType == Avatar_Model) { switch(sAvatarInfo.uiPart) { case INVTYPE_CHEST: // 胸部 case INVTYPE_WAIST: // 腰带 case INVTYPE_TROUSERS: // 护膝 case INVTYPE_GLOVES: // 手套 case INVTYPE_BOOTS: // 鞋子 case INVTYPE_HOUNTER_SHANGYI: case INVTYPE_HOUNTER_XIAYI: case INVTYPE_HOUNTER_XIEZI: SkinAvatar(pkRootNode, (NiNode*)pkAvatarObject, sAvatarInfo, pkLODCtrl); break; case INVTYPE_WEAPONMAINHAND: // 武器 case INVTYPE_WEAPONOFFHAND: // 武器 case INVTYPE_HEAD: // 头盔 case INVTYPE_SHOULDERS: // 肩部 case INVTYPE_SHIELD: case INVTYPE_2HWEAPON: case INVTYPE_BAOZHU: //case INVTYPE_NECK: // 项链 //case 16: // 骑乘点 case INVTYPE_HOUNTER_BEIBU: case INVTYPE_HOUNTER_TOUBU: case INVTYPE_HOUNTER_JIANBANG: AttachmentAvatar(pkRootNode, (NiNode*)pkAvatarObject, sAvatarInfo, iAttachmentSlot); break; } } return true; } bool CAvatar::AddEffectToEquip(NiNode* pkRootNode, std::string pkeffectFile, SAvatarInfo& sAvatarInfo, int iAttachmentSlot /* = -1 */) { NiFixedString strAttNodeName[5]; NiFixedString strBaseNodeName ; unsigned int uiAttNodeCount = 0; GetNodeName(sAvatarInfo.uiPart,strBaseNodeName,strAttNodeName, uiAttNodeCount, iAttachmentSlot); NiNode* pkNode = NULL; if (strBaseNodeName.Exists()) { pkNode= NiDynamicCast(NiNode,pkRootNode->GetObjectByName(strBaseNodeName)); } if (!pkNode) { if (sAvatarInfo.uiPart == INVTYPE_SHIELD || sAvatarInfo.uiPart == INVTYPE_WEAPONOFFHAND) { return true; } pkNode = pkRootNode ; } for(unsigned int ui = 0; ui < uiAttNodeCount; ui++) { NiNode* pkBaseNode = NiDynamicCast(NiNode,pkNode->GetObjectByName(strAttNodeName[ui])); if(pkBaseNode == NULL) continue; unsigned int uiChildCount = pkBaseNode->GetArrayCount(); for(unsigned int uiChild = 0; uiChild < uiChildCount; uiChild++) { g_ResMgr->FreeNif(pkBaseNode->GetAt(uiChild)); pkBaseNode->DetachChildAt(uiChild); } NiAVObject* spEffectObject = NULL; if (pkeffectFile.size()) { spEffectObject = g_ResMgr->LoadNif(pkeffectFile.c_str()); } if(!spEffectObject) continue; pkBaseNode->AttachChild(spEffectObject); spEffectObject->SetScale(sAvatarInfo.fScale); } return true; } static char* AvatarEffectNodeName[MAX_INVENTORY_TYPES+3][2] = { {"Helmet_Effect", NULL}, // 头盔 {"Gloves_L_Effect", "Gloves_R_Effect"}, // 手套 {"Chest_Effect", NULL}, // 胸甲 {"Pants_L_Effect", "Pants_R_Effect"}, // 腿 {"Boot_L_Effect", "Boot_R_Effect"}, // 鞋 {NULL, NULL}, // 武器 {NULL, NULL}, {NULL, NULL}, // 项链 {"Shoulder_L_Effect", "Shoulder_R_Effect"}, // 肩甲 {"Belt_Effect", NULL}, // 腰带 }; void AttachEffects(NiNode* pkRootNode, NiNode* pkEquipNode, unsigned int uiPart) { if(uiPart >= MAX_INVENTORY_TYPES || !pkEquipNode || !pkRootNode) return; //Attach特效 if(AvatarEffectNodeName[uiPart][0]) { NiAVObject* effect = pkEquipNode->GetObjectByName(AvatarEffectNodeName[uiPart][0]); if(effect && effect->GetParent()) { const NiFixedString kName = effect->GetParent()->GetName(); NiAVObject* pkAVObject = pkRootNode->GetObjectByName(kName); if(pkAVObject && pkAVObject->IsNode()) { ((NiNode*)pkAVObject)->AttachChild(effect); } } } if(AvatarEffectNodeName[uiPart][1]) { NiAVObject* effect = pkEquipNode->GetObjectByName(AvatarEffectNodeName[uiPart][1]); if(effect && effect->GetParent()) { const NiFixedString kName = effect->GetParent()->GetName(); NiAVObject* pkAVObject = pkRootNode->GetObjectByName(kName); if(pkAVObject && pkAVObject->IsNode()) { ((NiNode*)pkAVObject)->AttachChild(effect); } } } } void DetachEffects(NiNode* pkRootNode, unsigned int uiPart) { if(uiPart >= MAX_INVENTORY_TYPES || !pkRootNode) return; //Detach特效 if(AvatarEffectNodeName[uiPart][0]) { NiAVObject* effect = pkRootNode->GetObjectByName(AvatarEffectNodeName[uiPart][0]); if(effect && effect->GetParent()) { effect->GetParent()->DetachChild(effect); } } if(AvatarEffectNodeName[uiPart][1]) { NiAVObject* effect = pkRootNode->GetObjectByName(AvatarEffectNodeName[uiPart][1]); if(effect && effect->GetParent()) { effect->GetParent()->DetachChild(effect); } } } bool CAvatar::SkinAvatar(NiNode* pkRootNode, NiNode* pkEquipNode, SAvatarInfo& sAvatarInfo, NiBoneLODController* pkLODCtrl /*= 0*/) { if(!pkRootNode || !pkRootNode->IsNode() || !pkEquipNode) { g_ResMgr->FreeNif(pkEquipNode); return false; } bool bFoundLODSkin = false; NiAVObject* pkBaseObj = pkRootNode->GetObjectByName(AvatarNodeName[sAvatarInfo.uiPart]); if (pkLODCtrl && pkBaseObj) { NiBoneLODController::NiNodeSet kBoneRootNodes; NiTPointerMap kExistLODSkins; NiBoneLODController::FindBoneRootNodes(pkRootNode, kBoneRootNodes); if (kBoneRootNodes.GetSize() > 0) { pkLODCtrl->FindSkinGeometry(pkBaseObj, kExistLODSkins, kBoneRootNodes.GetAt(0)); NiTMapIterator pos = kExistLODSkins.GetFirstPos(); while (pos) { NiTriBasedGeom* kBasedGeom = 0; NiUnsignedIntSet* pkSkinLODSet = 0; kExistLODSkins.GetNext(pos, kBasedGeom, pkSkinLODSet); if (kBasedGeom) { pkLODCtrl->RemoveSkinFromAllLODs(kBasedGeom); } NiDelete pkSkinLODSet; } } } NiAVObject* pkEquipObj = pkEquipNode->GetObjectByName(AvatarNodeName[sAvatarInfo.uiPart]); if (pkLODCtrl && pkEquipObj) { NiBoneLODController::NiNodeSet kBoneRootNodes; NiBoneLODController::FindBoneRootNodes(pkEquipNode, kBoneRootNodes); NiTPointerMap kSkinToLOD; if (kBoneRootNodes.GetSize() > 0) { pkLODCtrl->FindSkinGeometry(pkEquipObj, kSkinToLOD, kBoneRootNodes.GetAt(0)); if (!kSkinToLOD.IsEmpty()) { NIASSERT(kSkinToLOD.GetCount() > 0); bFoundLODSkin = true; pkLODCtrl->AddSkinInfo(kSkinToLOD, true, pkRootNode); } NiTMapIterator kIter = kSkinToLOD.GetFirstPos(); while (kIter) { NiTriBasedGeom* pkTemp; NiUnsignedIntSet* pkSet; kSkinToLOD.GetNext(kIter, pkTemp, pkSet); NiDelete pkSet; } } } if(pkBaseObj) { //释放资源 g_ResMgr->FreeNif(pkBaseObj); pkRootNode->DetachChild(pkBaseObj); } DetachEffects(pkRootNode, sAvatarInfo.uiPart); if(!pkEquipObj) { g_ResMgr->FreeNif(pkEquipNode); return false; } // Add ExtraData NiIntegerExtraData* pkExtraData = NiNew NiIntegerExtraData(sAvatarInfo.uiId); pkExtraData->SetName("ModelId"); pkEquipObj->AddExtraData(pkExtraData); //记录下所属资源的名称,删除装备的时候需要释放相应的资源 const NiFixedString* pkFilename = g_ResMgr->GetResData(pkEquipNode); if(pkFilename) g_ResMgr->AddResData(pkEquipObj, *pkFilename); pkRootNode->AttachChild(pkEquipObj); AttachEffects(pkRootNode, pkEquipNode, sAvatarInfo.uiPart); if (!bFoundLODSkin) { std::vector stEquipGeometry; RecursiveGetGeometry(pkEquipObj, stEquipGeometry); for(unsigned int ui = 0; ui < stEquipGeometry.size(); ++ui) { NiGeometry* pkEquipGeometry = stEquipGeometry[ui]; NiSkinInstance* pkEquipSkinInst = pkEquipGeometry->GetSkinInstance(); if(pkEquipSkinInst == NULL) continue; NiAVObject* pkSkinParent = pkRootNode->GetObjectByName(pkEquipSkinInst->GetRootParent()->GetName()); pkEquipSkinInst->SetRootParent(pkSkinParent); int iBoneCount = pkEquipSkinInst->GetSkinData()->GetBoneCount(); NiAVObject*const* ppkBones = pkEquipSkinInst->GetBones(); for(int iBone = 0; iBone < iBoneCount ; ++iBone) { NiNode* pkBone = NiDynamicCast(NiNode,pkRootNode->GetObjectByName(ppkBones[iBone]->GetName())); if(!pkBone) { pkBone = NiDynamicCast(NiNode,pkEquipNode->GetObjectByName(ppkBones[iBone]->GetName())); ((NiNode*)pkRootNode->GetObjectByName(pkBone->GetParent()->GetName()))->AttachChild(pkBone); pkEquipSkinInst->SetBone(iBone, pkBone); } else { pkEquipSkinInst->SetBone(iBone, pkBone); } RecursiveSetCycleType(pkBone); } // Detach/Attach //pAvatarObj->DetachAllProperties(); //NiTListIterator kIter = pAVObj->GetPropertyList().GetHeadPos(); //while (kIter != NULL) //{ // NiProperty* pkProp = pAVObj->GetPropertyList().GetNext(kIter); // pAvatarObj->AttachProperty(pkProp); //} } } pkRootNode->UpdateNodeBound(); // 只更新 skin 的bound return true; } bool CAvatar::AttachmentAvatar(NiNode* pkRootNode, NiNode* pkEquipNode, SAvatarInfo& sAvatarInfo, int iAttachmentSlot /*= AS_None*/) { if(!pkRootNode || !pkRootNode->IsNode()) { g_ResMgr->FreeNif(pkEquipNode); return false; } NiFixedString strBaseNodeName[2]; NiFixedString strAttNodeName[2]; unsigned int uiAttNodeCount = 0; GetNodeName(AvatarNodeName[sAvatarInfo.uiPart], strBaseNodeName, strAttNodeName, uiAttNodeCount, iAttachmentSlot); NiFixedString strAttachmentName; if (iAttachmentSlot != AS_None) { if (INVTYPE_SHIELD == sAvatarInfo.uiPart) { strAttachmentName = "ShieldNode"; } else { strAttachmentName = "DoubleNode"; } uiAttNodeCount = 1; strAttNodeName[0] = AttachmementName[iAttachmentSlot]; } bool bResAttach = false; unsigned int ui = 0; for(; ui < uiAttNodeCount; ui++) { NiNode* pkBaseNode = NiDynamicCast(NiNode,pkRootNode->GetObjectByName(/*strBaseNodeName*/strAttNodeName[ui])); if(pkBaseNode == NULL) break; //if(/*strBaseNodeName*/strAttNodeName[ui].Equals("RightHand_Node")) //{ // NiAVObject* pArrow = pkBaseNode->GetAt(0); // if (pArrow && pArrow->GetName().Equals("Arrow")) // { // continue; // } //} unsigned int uiChildCount = pkBaseNode->GetArrayCount(); for(unsigned int uiChild = 0; uiChild < uiChildCount; uiChild++) { g_ResMgr->FreeNif(pkBaseNode->GetAt(uiChild)); pkBaseNode->DetachChildAt(uiChild); } if(!pkEquipNode) continue; NiAVObject* pkEquipObj = pkEquipNode->GetObjectByName(strBaseNodeName[ui]); if(pkEquipObj == NULL) { if(strBaseNodeName[ui].Equals("LeftWeapon")) { pkEquipObj = pkEquipNode->GetObjectByName("RightWeapon"); } if(!pkEquipObj) continue; } NiNode* pkAttachment = 0; if (strAttachmentName.Exists()) { pkAttachment = NiDynamicCast(NiNode,pkEquipNode->GetObjectByName(strAttachmentName)); if (pkAttachment) { NiTransform kTemp; kTemp.MakeIdentity(); pkAttachment->SetLocalTransform(kTemp); pkBaseNode->AttachChild(pkAttachment); pkAttachment->SetScale(sAvatarInfo.fScale); } else { NIASSERT(0); continue; } } else { NiTransform kTemp; kTemp.MakeIdentity(); pkEquipObj->SetLocalTransform(kTemp); pkBaseNode->AttachChild(pkEquipObj); pkEquipObj->SetScale(sAvatarInfo.fScale); } // Add ExtraData NiIntegerExtraData* pkExtraData = NiNew NiIntegerExtraData(sAvatarInfo.uiId); pkExtraData->SetName("ModelId"); pkEquipObj->AddExtraData(pkExtraData); if(!bResAttach) { //记录下所属资源的名称,删除的时候需要释放相应的资源 //只在其中一个记录 bResAttach = true; const NiFixedString* pkName = g_ResMgr->GetResData(pkEquipNode); if(pkName) { if(pkAttachment) g_ResMgr->AddResData(pkAttachment, *pkName); else g_ResMgr->AddResData(pkEquipObj, *pkName); } } } if(!bResAttach) g_ResMgr->FreeNif(pkEquipNode); return (ui == uiAttNodeCount); } void CAvatar::FreeAvatar(NiAVObject* pkAVObject) { if(pkAVObject == NULL) return; g_ResMgr->FreeNif(pkAVObject); if(pkAVObject->IsNode()) { NiNode* pkNode = (NiNode*)pkAVObject; for(unsigned int ui = 0; ui < pkNode->GetArrayCount(); ++ui) FreeAvatar(pkNode->GetAt(ui)); } } bool CAvatar::ChangeAvatarSZ(NiNode* pkRootNode, NiNode* pkEquipNode, const char* szNodeName, NiBoneLODController* pkLODCtrl) { if(!pkRootNode || !pkRootNode->IsNode() || !pkEquipNode) { g_ResMgr->FreeNif(pkEquipNode); return false; } bool bFoundLODSkin = false; NiAVObject* pkBaseObj = pkRootNode->GetObjectByName( szNodeName ); if (pkLODCtrl && pkBaseObj) { NiBoneLODController::NiNodeSet kBoneRootNodes; NiTPointerMap kExistLODSkins; NiBoneLODController::FindBoneRootNodes(pkRootNode, kBoneRootNodes); if (kBoneRootNodes.GetSize() > 0) { pkLODCtrl->FindSkinGeometry(pkBaseObj, kExistLODSkins, kBoneRootNodes.GetAt(0)); NiTMapIterator pos = kExistLODSkins.GetFirstPos(); while (pos) { NiTriBasedGeom* kBasedGeom = 0; NiUnsignedIntSet* pkSkinLODSet = 0; kExistLODSkins.GetNext(pos, kBasedGeom, pkSkinLODSet); if (kBasedGeom) { pkLODCtrl->RemoveSkinFromAllLODs(kBasedGeom); } NiDelete pkSkinLODSet; } } } NiAVObject* pkEquipObj = pkEquipNode->GetObjectByName( szNodeName ); if (pkLODCtrl && pkEquipObj) { NiBoneLODController::NiNodeSet kBoneRootNodes; NiBoneLODController::FindBoneRootNodes(pkEquipNode, kBoneRootNodes); NiTPointerMap kSkinToLOD; if (kBoneRootNodes.GetSize() > 0) { pkLODCtrl->FindSkinGeometry(pkEquipObj, kSkinToLOD, kBoneRootNodes.GetAt(0)); if (!kSkinToLOD.IsEmpty()) { NIASSERT(kSkinToLOD.GetCount() > 0); bFoundLODSkin = true; pkLODCtrl->AddSkinInfo(kSkinToLOD, true, pkRootNode); } NiTMapIterator kIter = kSkinToLOD.GetFirstPos(); while (kIter) { NiTriBasedGeom* pkTemp; NiUnsignedIntSet* pkSet; kSkinToLOD.GetNext(kIter, pkTemp, pkSet); NiDelete pkSet; } } } if(pkBaseObj) { //释放资源 g_ResMgr->FreeNif(pkBaseObj); pkRootNode->DetachChild(pkBaseObj); } if(!pkEquipObj) { g_ResMgr->FreeNif(pkEquipNode); return false; } //记录下所属资源的名称,删除装备的时候需要释放相应的资源 const NiFixedString* pkFilename = g_ResMgr->GetResData(pkEquipNode); if(pkFilename) g_ResMgr->AddResData(pkEquipObj, *pkFilename); pkRootNode->AttachChild(pkEquipObj); //AttachEffects(pkRootNode, pkEquipNode, sAvatarInfo.uiPart); if (!bFoundLODSkin) { std::vector stEquipGeometry; RecursiveGetGeometry(pkEquipObj, stEquipGeometry); for(unsigned int ui = 0; ui < stEquipGeometry.size(); ++ui) { NiGeometry* pkEquipGeometry = stEquipGeometry[ui]; NiSkinInstance* pkEquipSkinInst = pkEquipGeometry->GetSkinInstance(); if(pkEquipSkinInst == NULL) continue; NiAVObject* pkSkinParent = pkRootNode->GetObjectByName(pkEquipSkinInst->GetRootParent()->GetName()); pkEquipSkinInst->SetRootParent(pkSkinParent); int iBoneCount = pkEquipSkinInst->GetSkinData()->GetBoneCount(); NiAVObject*const* ppkBones = pkEquipSkinInst->GetBones(); for(int iBone = 0; iBone < iBoneCount ; ++iBone) { NiNode* pkBone = NiDynamicCast(NiNode,pkRootNode->GetObjectByName(ppkBones[iBone]->GetName())); if(!pkBone) { pkBone = NiDynamicCast(NiNode,pkEquipNode->GetObjectByName(ppkBones[iBone]->GetName())); ((NiNode*)pkRootNode->GetObjectByName(pkBone->GetParent()->GetName()))->AttachChild(pkBone); pkEquipSkinInst->SetBone(iBone, pkBone); } else { pkEquipSkinInst->SetBone(iBone, pkBone); } RecursiveSetCycleType(pkBone); } // Detach/Attach //pAvatarObj->DetachAllProperties(); //NiTListIterator kIter = pAVObj->GetPropertyList().GetHeadPos(); //while (kIter != NULL) //{ // NiProperty* pkProp = pAVObj->GetPropertyList().GetNext(kIter); // pAvatarObj->AttachProperty(pkProp); //} } } pkRootNode->UpdateNodeBound(); // 只更新 skin 的bound return true; }