bool FArchiveXML::LoadGeometryInstance(FCDObject* object, xmlNode* instanceNode) { if (!FArchiveXML::LoadEntityInstance(object, instanceNode)) return false; bool status = true; FCDGeometryInstance* geometryInstance = (FCDGeometryInstance*)object; // Look for the <bind_material> element. The others are discarded for now. xmlNode* bindMaterialNode = FindChildByType(instanceNode, DAE_BINDMATERIAL_ELEMENT); if (bindMaterialNode != NULL) { for (xmlNode* child = bindMaterialNode->children; child != NULL; child = child->next) { if (child->type != XML_ELEMENT_NODE) continue; if (IsEquivalent(child->name, DAE_PARAMETER_ELEMENT)) { FCDEffectParameter* parameter = geometryInstance->AddEffectParameter(FArchiveXML::GetEffectParameterType(child)); parameter->SetAnimator(); status &= FArchiveXML::LoadSwitch(parameter, ¶meter->GetObjectType(), child); } } // Retrieve the list of the <technique_common><instance_material> elements. xmlNode* techniqueNode = FindChildByType(bindMaterialNode, DAE_TECHNIQUE_COMMON_ELEMENT); xmlNodeList materialNodes; FindChildrenByType(techniqueNode, DAE_INSTANCE_MATERIAL_ELEMENT, materialNodes); for (xmlNodeList::iterator itM = materialNodes.begin(); itM != materialNodes.end(); ++itM) { FCDMaterialInstance* material = geometryInstance->AddMaterialInstance(); status &= (FArchiveXML::LoadMaterialInstance(material, *itM)); } } else { // Blinding attempt to use the material semantic from the polygons as a material id. FCDGeometry* geometry = (FCDGeometry*) geometryInstance->GetEntity(); if (geometry != NULL && geometry->HasType(FCDGeometry::GetClassType()) && geometry->IsMesh()) { FCDGeometryMesh* mesh = geometry->GetMesh(); size_t polyCount = mesh->GetPolygonsCount(); for (size_t i = 0; i < polyCount; ++i) { FCDGeometryPolygons* polys = mesh->GetPolygons(i); const fstring& semantic = polys->GetMaterialSemantic(); fm::string semanticUTF8 = TO_STRING(semantic); semanticUTF8 = FCDObjectWithId::CleanId(semanticUTF8.c_str()); FCDMaterial* material = geometry->GetDocument()->FindMaterial(semanticUTF8); if (material != NULL) { geometryInstance->AddMaterialInstance(material, polys); } } } } geometryInstance->SetDirtyFlag(); return status; }
void CModelConverter::SaveDAEScene(class FCDSceneNode* pNode, CConversionSceneNode* pScene) { pNode->SetName(convert_to_fstring(pScene->GetName())); FCDTMatrix* pTransform = (FCDTMatrix*)pNode->AddTransform(FCDTransform::MATRIX); pTransform->SetTransform(FMMatrix44(pScene->m_mTransformations)); for (size_t i = 0; i < pScene->GetNumMeshInstances(); i++) { CConversionMeshInstance* pMeshInstance = pScene->GetMeshInstance(i); FCDEntityInstance* pInstance = pNode->AddInstance(FCDEntity::GEOMETRY); FCDGeometryInstance* pGeometryInstance = dynamic_cast<FCDGeometryInstance*>(pInstance); FCDGeometryLibrary* pGeoLib = pNode->GetDocument()->GetGeometryLibrary(); pGeometryInstance->SetEntity(pGeoLib->GetEntity(pMeshInstance->m_iMesh)); // Relies on both libraries having the same indexes. FCDMaterialLibrary* pMatLib = pNode->GetDocument()->GetMaterialLibrary(); tmap<size_t, CConversionMaterialMap>::iterator j; for (j = pMeshInstance->m_aiMaterialsMap.begin(); j != pMeshInstance->m_aiMaterialsMap.end(); j++) { CConversionMaterialMap* pMap = &j->second; pGeometryInstance->AddMaterialInstance(pMatLib->GetEntity(pMap->m_iMaterial), convert_to_fstring(pMeshInstance->GetMesh()->GetMaterialStub(pMap->m_iStub)->GetName())); } } size_t iChildren = pScene->GetNumChildren(); for (size_t i = 0; i < iChildren; ++i) SaveDAEScene(pNode->AddChildNode(), pScene->GetChild(i)); }
FCDEntityInstance* FCDGeometryInstance::Clone(FCDEntityInstance* _clone) const { FCDGeometryInstance* clone = NULL; if (_clone == NULL) clone = new FCDGeometryInstance(const_cast<FCDocument*>(GetDocument()), const_cast<FCDSceneNode*>(GetParent()), GetEntityType()); else if (!_clone->HasType(FCDGeometryInstance::GetClassType())) return Parent::Clone(_clone); else clone = (FCDGeometryInstance*) _clone; Parent::Clone(clone); size_t parameterCount = parameters.size(); for (size_t p = 0; p < parameterCount; ++p) { FCDEffectParameter* clonedParameter = clone->AddEffectParameter(parameters[p]->GetType()); parameters[p]->Clone(clonedParameter); } // Clone the material instances. for (const FCDMaterialInstance** it = materials.begin(); it != materials.end(); ++it) { FCDMaterialInstance* materialInstance = clone->AddMaterialInstance(); (*it)->Clone(materialInstance); } return clone; }