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, &parameter->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;
}
示例#2
0
void CModelConverter::ReadDAESceneTree(FCDSceneNode* pNode, CConversionSceneNode* pScene)
{
	size_t iTransforms = pNode->GetTransformCount();

	Matrix4x4 mTransformations;

	for (size_t t = 0; t < iTransforms; t++)
	{
		FCDTransform* pTransform = pNode->GetTransform(t);
		FMMatrix44 m = pTransform->ToMatrix();
		mTransformations *= Matrix4x4(m);
	}

	pScene->SetTransformations(mTransformations);

	size_t iInstances = pNode->GetInstanceCount();

	for (size_t i = 0; i < iInstances; i++)
	{
		FCDEntityInstance* pInstance = pNode->GetInstance(i);

		switch (pInstance->GetType())
		{
		case FCDEntityInstance::GEOMETRY:
		{
			FCDGeometryInstance* pGeometryInstance = dynamic_cast<FCDGeometryInstance*>(pInstance);
			FCDEntity* pEntity = pGeometryInstance->GetEntity();
			size_t iMesh = pScene->m_pScene->FindMesh(convert_from_fstring(pEntity->GetName()));
			size_t iMeshInstance = pScene->AddMeshInstance(iMesh);

			size_t iMaterialInstances = pGeometryInstance->GetMaterialInstanceCount();
			for (size_t m = 0; m < iMaterialInstances; m++)
			{
				FCDMaterialInstance* pMaterialInstance = pGeometryInstance->GetMaterialInstance(m);
				FCDMaterial* pMaterial = pMaterialInstance->GetMaterial();
				tstring sMaterial = pMaterial?convert_from_fstring(pMaterialInstance->GetMaterial()->GetName()):"";
				tstring sMaterialStub = convert_from_fstring(pMaterialInstance->GetSemantic());

				size_t iMaterial = pScene->m_pScene->FindMaterial(sMaterial);
				size_t iMaterialStub = pScene->m_pScene->GetMesh(iMesh)->FindMaterialStub(sMaterialStub);

				pScene->GetMeshInstance(iMeshInstance)->AddMappedMaterial(iMaterialStub, iMaterial);
			}
		}
		}
	}

	size_t iChildren = pNode->GetChildrenCount();
	for (size_t j = 0; j < iChildren; j++)
	{
		FCDSceneNode* pChildNode = pNode->GetChild(j);
		size_t iNode = pScene->AddChild(convert_from_fstring(pChildNode->GetName()));
		ReadDAESceneTree(pChildNode, pScene->GetChild(iNode));
	}
}