/*---------------------------------------------------------------------------*/ NiNodeRef NifPrepareUtility::parse4Blender(NiNodeRef pNode) { vector<NiAVObjectRef> childList(pNode->GetChildren()); list<NiExtraDataRef> extraList(pNode->GetExtraData()); // parse extra data for BSInvMarker for (auto pIter(extraList.begin()), pEnd(extraList.end()); pIter != pEnd; pIter++) { if (_remBSInvMarker && (DynamicCast<BSInvMarker>(*pIter) != NULL)) { pNode->RemoveExtraData(*pIter); } } // unlink children pNode->ClearChildren(); // iterate over children for (auto pIter(childList.begin()), pEnd(childList.end()); pIter != pEnd; pIter++) { // NiTriShape => remove BSLightingShaderProperty if (DynamicCast<NiTriShape>(*pIter) != NULL) { if (_remBSProperties) { NiTriShapeRef pShape (DynamicCast<NiTriShape>(*pIter)); // remove properties (Bethesda uses max. 2) pShape->SetBSProperty(0, NULL); pShape->SetBSProperty(1, NULL); } // add shape to node pNode->AddChild(*pIter); } // BSInvMarker => remove whole object else if (_remBSInvMarker && (DynamicCast<BSInvMarker>(*pIter) != NULL)) { // skip entry => do not add to final list } // NiNode (and derived classes?) => iterate subnodes else if (DynamicCast<NiNode>(*pIter) != NULL) { pNode->AddChild(&(*parse4Blender(DynamicCast<NiNode>(*pIter)))); } } // for (auto pIter(childList.begin()), pEnd(childList.end()); pIter != pEnd; pIter++) return pNode; }
Exporter::Result Exporter::exportLight(NiNodeRef parent, INode *node, GenLight* light) { TimeValue t = 0; NiLightRef niLight; switch (light->Type()) { case OMNI_LIGHT: { if (light->GetAmbientOnly()) { niLight = new NiAmbientLight(); } else { NiPointLightRef pointLight = new NiPointLight(); float atten = light->GetAtten(t, ATTEN_START); switch (light->GetDecayType()) { case 0: pointLight->SetConstantAttenuation(1.0f); break; case 1: pointLight->SetLinearAttenuation( atten / 4.0f ); break; case 2: pointLight->SetQuadraticAttenuation( sqrt(atten / 4.0f) ); break; } niLight = StaticCast<NiLight>(pointLight); } } break; case TSPOT_LIGHT: case FSPOT_LIGHT: niLight = new NiSpotLight(); break; case DIR_LIGHT: case TDIR_LIGHT: niLight = new NiDirectionalLight(); break; } if (niLight == NULL) return Skip; niLight->SetName(node->GetName()); Matrix3 tm = getObjectTransform(node, t, !mFlattenHierarchy); niLight->SetLocalTransform( TOMATRIX4(tm, false) ); niLight->SetDimmer( light->GetIntensity(0) ); Color3 rgbcolor = TOCOLOR3( light->GetRGBColor(0) ); if (light->GetAmbientOnly()) { niLight->SetDiffuseColor(Color3(0,0,0)); niLight->SetSpecularColor(Color3(0,0,0)); niLight->SetAmbientColor(rgbcolor); } else { niLight->SetDiffuseColor(rgbcolor); niLight->SetSpecularColor(rgbcolor); niLight->SetAmbientColor(Color3(0,0,0)); } parent->AddChild( DynamicCast<NiAVObject>(niLight) ); return Ok; }
/** * @brief writes the given nif to the given file. */ void dumpNif(const std::string& n, CellMeshList& l){ using namespace Niflib; NiNodeRef node = new NiNode; for ( std::list<NiAVObjectRef>::iterator iter = l.begin(); l.end() != iter; ++iter) if ( *iter ) node->AddChild(*iter); NiObjectRef obj = DynamicCast<NiObject>( node ); unsigned ver = 67108866; WriteNifTree(n, obj, NifInfo(ver)); }
/*---------------------------------------------------------------------------*/ NiNodeRef NifConvertUtility::convertNiNode(NiNodeRef pSrcNode, NiTriShapeRef pTmplNode, NiNodeRef pRootNode, NiAlphaPropertyRef pTmplAlphaProp) { NiNodeRef pDstNode (pSrcNode); vector<NiAVObjectRef> srcShapeList(pDstNode->GetChildren()); // find NiAlphaProperty and use as template in sub-nodes if (DynamicCast<NiAlphaProperty>(pDstNode->GetPropertyByType(NiAlphaProperty::TYPE)) != NULL) { pTmplAlphaProp = DynamicCast<NiAlphaProperty>(pDstNode->GetPropertyByType(NiAlphaProperty::TYPE)); } // unlink protperties -> not used in new format pDstNode->ClearProperties(); // shift extra data to new version pDstNode->ShiftExtraData(VER_20_2_0_7); // unlink children pDstNode->ClearChildren(); // iterate over source nodes and convert using template for (vector<NiAVObjectRef>::iterator ppIter = srcShapeList.begin(); ppIter != srcShapeList.end(); ppIter++) { // NiTriShape //Type t = (*ppIter)->GetType(); if (DynamicCast<NiTriShape>(*ppIter) != NULL) { pDstNode->AddChild(&(*convertNiTriShape(DynamicCast<NiTriShape>(*ppIter), pTmplNode, pTmplAlphaProp))); } // NiNode (and derived classes?) else if (DynamicCast<NiNode>(*ppIter) != NULL) { pDstNode->AddChild(&(*convertNiNode(DynamicCast<NiNode>(*ppIter), pTmplNode, pRootNode, pTmplAlphaProp))); } } return pDstNode; }
NiNodeRef Exporter::makeNode(NiNodeRef &parent, INode *maxNode, bool local) { string name = (char*)maxNode->GetName(); NiNodeRef node = getNode(maxNode); Matrix33 rot; Vector3 trans; TimeValue t = 0; nodeTransform(rot, trans, maxNode, t, local); node->SetLocalRotation(rot); node->SetLocalTranslation(trans); exportUPB(node, maxNode); // Normal Embedded Animation if (mExportType == NIF_WO_KF) CreateController(maxNode, Interval()); parent->AddChild(DynamicCast<NiAVObject>(node)); return node; }
NiTriBasedGeomRef Exporter::makeMesh(NiNodeRef &parent, Mtl *mtl, FaceGroup &grp, bool exportStrips) { NiTriBasedGeomRef shape; NiTriBasedGeomDataRef data; //if (Exporter::mFixNormals) { // FixNormals(grp.faces, grp.verts, grp.vnorms); //} if (exportStrips) { shape = new NiTriStrips(); data = new NiTriStripsData(grp.faces, !mUseAlternateStripper); } else { shape = new NiTriShape(); data = new NiTriShapeData(grp.faces); } if ( IsFallout3() || IsSkyrim() ) shape->SetFlags( 14 ); data->SetVertices(grp.verts); data->SetNormals(grp.vnorms); data->SetVertexIndices(grp.vidx); data->SetUVSetMap(grp.uvMapping); int nUVs = grp.uvs.size(); if ( IsFallout3() || IsSkyrim() ) nUVs = min(1, nUVs); data->SetUVSetCount(nUVs); for (int i =0;i<nUVs; ++i) { data->SetUVSet(i, grp.uvs[i]); } //if (IsSkyrim() && grp.vcolors.size() == 0) // grp.vcolors.resize(grp.verts.size(), Color4(1.0f,1.0f,1.0f,1.0f)); if (mVertexColors && grp.vcolors.size() > 0) { bool allWhite = true; Color4 white(1.0f, 1.0f, 1.0f, 1.0f); for (int i=0,n=grp.vcolors.size();i<n; ++i) { if (white != grp.vcolors[i]) { allWhite = false; break; } } if (!allWhite) data->SetVertexColors(grp.vcolors); } data->SetConsistencyFlags(CT_STATIC); shape->SetData(data); if (Exporter::mTangentAndBinormalExtraData && (Exporter::mNifVersionInt > VER_4_2_2_0)) { // enable traditional tangents and binormals for non-oblivion meshes if ( !IsOblivion() && (Exporter::mNifVersionInt >= VER_10_0_1_0) ) data->SetTspaceFlag( 0x01 ); shape->UpdateTangentSpace(Exporter::mTangentAndBinormalMethod); } parent->AddChild(DynamicCast<NiAVObject>(shape)); NiAVObjectRef av(DynamicCast<NiAVObject>(shape)); makeMaterial(av, mtl); shape->SetActiveMaterial(0); return shape; }
/*---------------------------------------------------------------------------*/ unsigned int NifConvertUtility::convertShape(string fileNameSrc, string fileNameDst, string fileNameTmpl) { NiNodeRef pRootInput (NULL); NiNodeRef pRootOutput (NULL); NiNodeRef pRootTemplate (NULL); NiTriShapeRef pNiTriShapeTmpl(NULL); vector<NiAVObjectRef> srcChildList; bool fakedRoot (false); // test on existing file names if (fileNameSrc.empty()) return NCU_ERROR_MISSING_FILE_NAME; if (fileNameDst.empty()) return NCU_ERROR_MISSING_FILE_NAME; if (fileNameTmpl.empty()) return NCU_ERROR_MISSING_FILE_NAME; // initialize user messages _userMessages.clear(); logMessage(NCU_MSG_TYPE_INFO, "Source: " + (fileNameSrc.empty() ? "- none -" : fileNameSrc)); logMessage(NCU_MSG_TYPE_INFO, "Template: " + (fileNameTmpl.empty() ? "- none -" : fileNameTmpl)); logMessage(NCU_MSG_TYPE_INFO, "Destination: " + (fileNameDst.empty() ? "- none -" : fileNameDst)); logMessage(NCU_MSG_TYPE_INFO, "Texture: " + (_pathTexture.empty() ? "- none -" : _pathTexture)); // initialize used texture list _usedTextures.clear(); _newTextures.clear(); // read input NIF if ((pRootInput = getRootNodeFromNifFile(fileNameSrc, "source", fakedRoot)) == NULL) { logMessage(NCU_MSG_TYPE_ERROR, "Can't open '" + fileNameSrc + "' as input"); return NCU_ERROR_CANT_OPEN_INPUT; } // get template nif pRootTemplate = DynamicCast<BSFadeNode>(ReadNifTree((const char*) fileNameTmpl.c_str())); if (pRootTemplate == NULL) { logMessage(NCU_MSG_TYPE_ERROR, "Can't open '" + fileNameTmpl + "' as template"); return NCU_ERROR_CANT_OPEN_TEMPLATE; } // get shapes from template // - shape root pNiTriShapeTmpl = DynamicCast<NiTriShape>(pRootTemplate->GetChildren().at(0)); if (pNiTriShapeTmpl == NULL) { logMessage(NCU_MSG_TYPE_INFO, "Template has no NiTriShape."); } // template root is used as root of output pRootOutput = pRootTemplate; // get rid of unwanted subnodes pRootOutput->ClearChildren(); // remove all children pRootOutput->SetCollisionObject(NULL); // unlink collision object // hold extra data and property nodes // copy translation from input node pRootOutput->SetLocalTransform(pRootInput->GetLocalTransform()); // copy name of root node pRootOutput->SetName(pRootInput->GetName()); // get list of children from input node srcChildList = pRootInput->GetChildren(); // unlink children 'cause moved to output pRootInput->ClearChildren(); // iterate over source nodes and convert using template for (vector<NiAVObjectRef>::iterator ppIter = srcChildList.begin(); ppIter != srcChildList.end(); ppIter++) { // NiTriShape if (DynamicCast<NiTriShape>(*ppIter) != NULL) { pRootOutput->AddChild(&(*convertNiTriShape(DynamicCast<NiTriShape>(*ppIter), pNiTriShapeTmpl))); } // RootCollisionNode else if (DynamicCast<RootCollisionNode>(*ppIter) != NULL) { // ignore node } // NiNode (and derived classes?) else if (DynamicCast<NiNode>(*ppIter) != NULL) { pRootOutput->AddChild(&(*convertNiNode(DynamicCast<NiNode>(*ppIter), pNiTriShapeTmpl, pRootOutput))); } } // write missing textures to log - as block for (set<string>::iterator pIter(_newTextures.begin()); pIter != _newTextures.end(); ++pIter) { logMessage(NCU_MSG_TYPE_TEXTURE_MISS, *pIter); } // write modified nif file WriteNifTree((const char*) fileNameDst.c_str(), pRootOutput, NifInfo(VER_20_2_0_7, 12, 83)); return NCU_OK; }
/*---------------------------------------------------------------------------*/ unsigned int NifConvertUtility::convertShape(string fileNameSrc, string fileNameDst, string fileNameTmpl) { cout << "Here3" << endl; NiNodeRef pRootInput (NULL); NiNodeRef pRootOutput (NULL); NiNodeRef pRootTemplate (NULL); NiTriShapeRef pNiTriShapeTmpl(NULL); NiCollisionObjectRef pRootCollObject(NULL); NifInfo nifInfo; vector<NiAVObjectRef> srcChildList; bool fakedRoot (false); cout << "Here4" << endl; // test on existing file names if (fileNameSrc.empty()) return NCU_ERROR_MISSING_FILE_NAME; if (fileNameDst.empty()) return NCU_ERROR_MISSING_FILE_NAME; if (fileNameTmpl.empty()) return NCU_ERROR_MISSING_FILE_NAME; cout << "Here5" << endl; // initialize user messages _userMessages.clear(); logMessage(NCU_MSG_TYPE_INFO, "Source: " + (fileNameSrc.empty() ? "- none -" : fileNameSrc)); logMessage(NCU_MSG_TYPE_INFO, "Template: " + (fileNameTmpl.empty() ? "- none -" : fileNameTmpl)); logMessage(NCU_MSG_TYPE_INFO, "Destination: " + (fileNameDst.empty() ? "- none -" : fileNameDst)); logMessage(NCU_MSG_TYPE_INFO, "Texture: " + (_pathTexture.empty() ? "- none -" : _pathTexture)); cout << "Here6" << endl; // initialize used texture list _usedTextures.clear(); _newTextures.clear(); cout << "Here7" << endl; // read input NIF if ((pRootInput = getRootNodeFromNifFile(fileNameSrc, "source", fakedRoot, &nifInfo)) == NULL) { logMessage(NCU_MSG_TYPE_ERROR, "Can't open '" + fileNameSrc + "' as input"); return NCU_ERROR_CANT_OPEN_INPUT; } cout << "Here8" << endl; // get template nif pRootTemplate = DynamicCast<BSFadeNode>(ReadNifTree((const char*) fileNameTmpl.c_str())); if (pRootTemplate == NULL) { logMessage(NCU_MSG_TYPE_ERROR, "Can't open '" + fileNameTmpl + "' as template"); return NCU_ERROR_CANT_OPEN_TEMPLATE; } cout << "Here9" << endl; // get shapes from template // - shape root pNiTriShapeTmpl = DynamicCast<NiTriShape>(pRootTemplate->GetChildren().at(0)); if (pNiTriShapeTmpl == NULL) { logMessage(NCU_MSG_TYPE_INFO, "Template has no NiTriShape."); } cout << "Here10" << endl; // get data from input node srcChildList = pRootInput->GetChildren(); pRootCollObject = pRootInput->GetCollisionObject(); cout << "Here11" << endl; // template root is used as root of output pRootOutput = pRootTemplate; // move date from input to output pRootInput ->SetCollisionObject(NULL); pRootOutput->SetCollisionObject(pRootCollObject); pRootOutput->SetLocalTransform(pRootInput->GetLocalTransform()); pRootOutput->SetName(pRootInput->GetName()); cout << "Here12" << endl; // get rid of unwanted subnodes pRootOutput->ClearChildren(); pRootInput->ClearChildren(); cout << "Here13" << endl; // move children to output for (auto pIter=srcChildList.begin(), pEnd=srcChildList.end(); pIter != pEnd; ++pIter) { pRootOutput->AddChild(*pIter); } cout << "Here14" << endl; // iterate over source nodes and convert using template root_bsafade = pRootOutput; pRootOutput = convertNiNode(pRootOutput, pNiTriShapeTmpl, pRootOutput); cout << "Here15" << endl; // write missing textures to log - as block for (auto pIter=_newTextures.begin(), pEnd=_newTextures.end(); pIter != pEnd; ++pIter) { logMessage(NCU_MSG_TYPE_TEXTURE_MISS, *pIter); } cout << "Here16" << endl; // set version information stringstream sStream; cout << "Here17" << endl; sStream << nifInfo.version << ';' << nifInfo.userVersion; nifInfo.version = VER_20_2_0_7; nifInfo.userVersion = 12; nifInfo.userVersion2 = 83; nifInfo.creator = "NifConvert"; nifInfo.exportInfo1 = MASTER_PRODUCT_VERSION_STR; nifInfo.exportInfo2 = sStream.str(); cout << "Here18" << endl; // write modified nif file WriteNifTree((const char*) fileNameDst.c_str(), pRootOutput, nifInfo); cout << "Here19" << endl; return NCU_OK; }
NiNodeRef NifConvertUtility::convertNiNode(NiNodeRef pSrcNode, NiTriShapeRef pTmplNode, NiNodeRef pRootNode, NiAlphaPropertyRef pTmplAlphaProp) { NiNodeRef pDstNode (pSrcNode); //pDstNode->SetName(pDstNode->GetName().replace( string node_name_in = pDstNode->GetName(); string node_name_out = ""; for (int i = 0; i < node_name_in.length(); i++) { if (node_name_in[i] != '.' && node_name_in[i] != '_' && node_name_in[i] != ' ') { node_name_out = node_name_out + node_name_in[i]; } } pDstNode->SetName(node_name_out); node_name_in = node_name_out; if (node_name_in.compare("AttachLight") == 0) { Vector3 tr = pDstNode->GetLocalTranslation(); tr.z += 10.0f; pDstNode->SetLocalTranslation(tr); } if (node_name_in.compare("ShadowBox") == 0) { cout << "Removing ShadowBox" << endl; pDstNode->ClearChildren(); } if (toLower(node_name_in).find("fireemit") != -1) { NiExtraDataRef ed = root_bsafade->GetExtraData().front(); NiIntegerExtraDataRef iref = DynamicCast<NiIntegerExtraData>(ed); iref->SetData(147); cout << "Adding TorchFlame Addon" << endl; BSValueNodeRef candle_flame = new BSValueNode(); candle_flame->SetName("AddOnNode"); candle_flame->value = 46; pDstNode->AddChild(DynamicCast<NiAVObject>(candle_flame)); } else if (node_name_in.find("CandleFlame") != -1) { NiExtraDataRef ed = root_bsafade->GetExtraData().front(); NiIntegerExtraDataRef iref = DynamicCast<NiIntegerExtraData>(ed); iref->SetData(147); cout << "Adding CandleFlame Addon" << endl; BSValueNodeRef candle_flame = new BSValueNode(); candle_flame->SetName("AddOnNode"); candle_flame->value = 49; pDstNode->AddChild(DynamicCast<NiAVObject>(candle_flame)); } vector<NiAVObjectRef> srcShapeList(pDstNode->GetChildren()); //if (!pDstNode->GetType().IsSameType(NiNode::TYPE) && !pDstNode->GetType().IsSameType(BSFadeNode::TYPE) && !pDstNode->GetType().IsSameType(NiTriShape::TYPE) && !pDstNode->GetType().IsSameType(NiTriStrips::TYPE)) { } // find NiAlphaProperty and use as template in sub-nodes if (DynamicCast<NiAlphaProperty>(pDstNode->GetPropertyByType(NiAlphaProperty::TYPE)) != NULL) { pTmplAlphaProp = DynamicCast<NiAlphaProperty>(pDstNode->GetPropertyByType(NiAlphaProperty::TYPE)); } // unlink protperties -> not used in new format pDstNode->ClearProperties(); // shift extra data to new version pDstNode->ShiftExtraData(VER_20_2_0_7); // unlink children pDstNode->ClearChildren(); pDstNode->ClearEffects(); pDstNode->ClearControllers(); if (!pDstNode->GetType().IsSameType(BSFadeNode::TYPE)) { pDstNode->ClearExtraData(); } // iterate over source nodes and convert using template for (auto ppIter=srcShapeList.begin(), pEnd=srcShapeList.end(); ppIter != pEnd; ppIter++) { //DynamicCast<NiTriShape>(*ppIter) == NULL && DynamicCast<NiTriStrips>(*ppIter) == NULL ** DynamicCast<NiTriStrips>(*ppIter) != NULL // NiTriShape if (DynamicCast<NiTriShape>(*ppIter) != NULL) { pDstNode->AddChild(&(*convertNiTriShape(DynamicCast<NiTriShape>(*ppIter), pTmplNode, pTmplAlphaProp))); } // NiTriStrips else if (DynamicCast<NiTriStrips>(*ppIter) != NULL) { pDstNode->AddChild(&(*convertNiTriStrips(DynamicCast<NiTriStrips>(*ppIter), pTmplNode, pTmplAlphaProp))); } // RootCollisionNode else if ((DynamicCast<RootCollisionNode>(*ppIter) != NULL) && _cleanTreeCollision) { // ignore node } // NiNode (and derived classes?) else if (DynamicCast<NiNode>(*ppIter) != NULL) { NiNode* node_hashmi = DynamicCast<NiNode>(*ppIter); if (node_hashmi->GetType().IsSameType(NiNode::TYPE) || node_hashmi->GetType().IsSameType(BSFadeNode::TYPE) || node_hashmi->GetType().IsSameType(BSValueNode::TYPE)) { pDstNode->AddChild(&(*convertNiNode(DynamicCast<NiNode>(*ppIter), pTmplNode, pRootNode, pTmplAlphaProp))); } } } // remove collision object (newer version) if (_cleanTreeCollision) { pDstNode->SetCollisionObject(NULL); } else if (DynamicCast<bhkCollisionObject>(pDstNode->GetCollisionObject()) != NULL) { bhkRigidBodyRef pBody(DynamicCast<bhkRigidBody>((DynamicCast<bhkCollisionObject>(pDstNode->GetCollisionObject()))->GetBody())); if (pBody != NULL) { parseCollisionTree(pBody->GetShape()); } } return pDstNode; }
/*---------------------------------------------------------------------------*/ NiNodeRef NifPrepareUtility::parse4Armor(NiNodeRef pNode, BSLightingShaderPropertyRef pShaderTmpl) { vector<NiAVObjectRef> childList(pNode->GetChildren()); // unlink children pNode->ClearChildren(); // iterate over children for (auto pIter(childList.begin()), pEnd(childList.end()); pIter != pEnd; pIter++) { // NiTriShape => remodel BSLightingShaderProperty if (DynamicCast<NiTriShape>(*pIter) != NULL) { NiTriShapeRef pShape (DynamicCast<NiTriShape>(*pIter)); BSDismemberSkinInstanceRef pSkin (DynamicCast<BSDismemberSkinInstance>(pShape->GetSkinInstance())); vector<NiPropertyRef> propList(pShape->GetProperties()); // part of skin data? => modify skin code if (pSkin != NULL) { vector<BodyPartList> bPartList(pSkin->GetPartitions()); for (auto pIter(bPartList.begin()), pEnd(bPartList.end()); pIter != pEnd; pIter++) { if (_bodyPartMap.count(pIter->bodyPart) > 0) { pIter->bodyPart = (BSDismemberBodyPartType) _bodyPartMap[pIter->bodyPart]; } } // for (auto pIter(bPartList.begin()), pEnd(bPartList.end()); pIter != pEnd; pIter++) // set modified parts pSkin->SetPartitions(bPartList); } // if (pSkin != NULL) // remove all properties pShape->ClearProperties(); // create new BSLightingShaderProperty if template given if (pShaderTmpl != NULL) { // check properties for (auto pIterProp(propList.begin()), pEnd(propList.end()); pIterProp != pEnd; pIterProp++) { // convert BSShaderPPLightingProperty to BSLightingShaderProperty if (DynamicCast<BSShaderPPLightingProperty>(*pIterProp) != NULL) { BSShaderPPLightingProperty* pPProp(DynamicCast<BSShaderPPLightingProperty>(*pIterProp)); BSLightingShaderProperty* pLProp(new BSLightingShaderProperty()); // move texture set pLProp->SetTextureSet(pPProp->GetTextureSet()); pPProp->SetTextureSet(NULL); pLProp->SetShaderFlags1 (pShaderTmpl->GetShaderFlags1()); pLProp->SetShaderFlags2 (pShaderTmpl->GetShaderFlags2()); pLProp->SetEmissiveMultiple (pShaderTmpl->GetEmissiveMultiple()); pLProp->SetEmissiveColor (pShaderTmpl->GetEmissiveColor()); pLProp->SetLightingEffect1 (pShaderTmpl->GetLightingEffect1()); pLProp->SetLightingEffect2 (pShaderTmpl->GetLightingEffect2()); pLProp->SetEnvironmentMapScale(pShaderTmpl->GetEnvironmentMapScale()); pLProp->SetSkyrimShaderType (pShaderTmpl->GetSkyrimShaderType()); pLProp->SetSpecularColor (pShaderTmpl->GetSpecularColor()); pLProp->SetSpecularStrength (pShaderTmpl->GetSpecularStrength()); pLProp->SetTextureClampMode (pShaderTmpl->GetTextureClampMode()); pLProp->SetUnknownFloat2 (pShaderTmpl->GetUnknownFloat2()); pLProp->SetGlossiness (pShaderTmpl->GetGlossiness()); // add property to shape pShape->SetBSProperty(0, pLProp); } } // for (auto pIterProp(propList.begin()), pEnd(propList.end()); pIterProp != pEnd; pIterProp++) } // if (pShaderTmpl != NULL) // add shape to node pNode->AddChild(*pIter); } // NiNode (and derived classes?) => iterate subnodes else if (DynamicCast<NiNode>(*pIter) != NULL) { pNode->AddChild(&(*parse4Armor(DynamicCast<NiNode>(*pIter), pShaderTmpl))); } } // for (auto pIter(childList.begin()), pEnd(childList.end()); pIter != pEnd; pIter++) return pNode; }