/* Copyright (C) 2005-2007 Feeling Software Inc. Portions of the code are: Copyright (C) 2005-2007 Sony Computer Entertainment America MIT License: http://www.opensource.org/licenses/mit-license.php */ #include "StdAfx.h" #include "FCDocument/FCDocument.h" #include "FCDocument/FCDCamera.h" #include "FCDocument/FCDExtra.h" #include "FCDocument/FCDGeometry.h" #include "FCDocument/FCDGeometryInstance.h" #include "FCDocument/FCDGeometryMesh.h" #include "FCDocument/FCDGeometrySource.h" #include "FCDocument/FCDGeometrySpline.h" #include "FCDocument/FCDGeometryPolygons.h" #include "FCDocument/FCDLibrary.h" #include "FCDocument/FCDMaterial.h" #include "FCDocument/FCDSceneNode.h" #include "FCDocument/FCDTransform.h" #include "FCDocument/FCDEffect.h" #include "FCDocument/FCDEffectTools.h" #include "FCDocument/FCDEffectStandard.h" #include "FCDocument/FCDEffectParameter.h" #include "FUtils/FUTestBed.h" #include "FCTestExportImport.h" using namespace FCTestExportImport; static fm::string sceneNode1Id, sceneNode2Id, sceneNode3Id; // Test import of a code-generated scene, with library entities. // Does the export, re-import and validates that the information is intact. TESTSUITE_START(FCDExportReimport) TESTSUITE_TEST(0, Export) // Write out a simple document with three visual scenes FCDocument* doc = FCollada::NewTopDocument(); FCDSceneNode* sceneNode1 = doc->AddVisualScene(); sceneNode1->SetName(FC("Scene1")); FCDSceneNode* sceneNode2 = doc->AddVisualScene(); sceneNode2->SetName(FC("Scene2")); FCDSceneNode* sceneNode3 = doc->AddVisualScene(); sceneNode3->SetName(FC("Scene3")); // Fill in the other libraries PassIf(FillLayers(fileOut, doc)); PassIf(FillImageLibrary(fileOut, doc->GetImageLibrary())); PassIf(FillCameraLibrary(fileOut, doc->GetCameraLibrary())); PassIf(FillLightLibrary(fileOut, doc->GetLightLibrary())); PassIf(FillForceFieldLibrary(fileOut, doc->GetForceFieldLibrary())); PassIf(FillEmitterLibrary(fileOut, doc->GetEmitterLibrary())); // must occur after FillForceFieldLibrary; PassIf(FillGeometryLibrary(fileOut, doc->GetGeometryLibrary())); PassIf(FillControllerLibrary(fileOut, doc->GetControllerLibrary())); // must occur after FillGeometryLibrary; PassIf(FillMaterialLibrary(fileOut, doc->GetMaterialLibrary())); // must occur after FillImageLibrary; PassIf(FillVisualScene(fileOut, sceneNode2)); // must occur after lights, cameras, geometries and controllers; PassIf(FillPhysics(fileOut, doc)); // must occur after the visual scene is filled in; PassIf(FillAnimationLibrary(fileOut, doc->GetAnimationLibrary())); // must occur last; // Add a bit of extra data to the FCDocument to verify that this feature works too. FCDEType* type = doc->GetExtra()->AddType("TOTO"); FCDETechnique* technique = type->AddTechnique("TOTO_TECHNIQUE"); technique->AddParameter("AParameter", FC("AValue")); // Write out the document. FCollada::SaveDocument(doc, FC("TestOut.dae")); // Check the dae id that were automatically generated: they should be unique FailIf(sceneNode1->GetDaeId() == sceneNode2->GetDaeId()); FailIf(sceneNode1->GetDaeId() == sceneNode3->GetDaeId()); FailIf(sceneNode2->GetDaeId() == sceneNode3->GetDaeId()); sceneNode1Id = sceneNode1->GetDaeId(); sceneNode2Id = sceneNode2->GetDaeId(); sceneNode3Id = sceneNode3->GetDaeId(); SAFE_RELEASE(doc); TESTSUITE_TEST(1, Reimport) // Import back this document FUErrorSimpleHandler errorHandler; FCDocument* idoc = FCollada::NewTopDocument(); PassIf(FCollada::LoadDocumentFromFile(idoc, FC("TestOut.dae"))); PassIf(idoc != NULL); #ifdef _WIN32 OutputDebugStringA(errorHandler.GetErrorString()); #endif PassIf(errorHandler.IsSuccessful()); // Verify that all the data we pushed is still available // Note that visual scenes may be added by other tests: such as for joints. FCDVisualSceneNodeLibrary* vsl = idoc->GetVisualSceneLibrary(); PassIf(vsl->GetEntityCount() >= 3); // Verify that the visual scene ids are unique. for (size_t i = 0; i < vsl->GetEntityCount(); ++i) { FCDSceneNode* inode = vsl->GetEntity(i); for (size_t j = 0; j < i; ++j) { FCDSceneNode* jnode = vsl->GetEntity(j); FailIf(inode->GetDaeId() == jnode->GetDaeId()); } } // Verify that the three wanted visual scene ids exist and find the one we fill in. bool found1 = false, found3 = false; FCDSceneNode* found2 = NULL; for (size_t i = 0; i < vsl->GetEntityCount(); ++i) { FCDSceneNode* inode = vsl->GetEntity(i); if (inode->GetDaeId() == sceneNode1Id) { FailIf(found1); PassIf(inode->GetName() == FC("Scene1")); found1 = true; } else if (inode->GetDaeId() == sceneNode2Id) { FailIf(found2 != NULL); PassIf(inode->GetName() == FC("Scene2")); found2 = inode; } else if (inode->GetDaeId() == sceneNode3Id) { FailIf(found3); PassIf(inode->GetName() == FC("Scene3")); found3 = true; } } PassIf(found2 != NULL); // Compare all these re-imported library contents PassIf(CheckLayers(fileOut, idoc)); PassIf(CheckVisualScene(fileOut, found2)); PassIf(CheckImageLibrary(fileOut, idoc->GetImageLibrary())); PassIf(CheckCameraLibrary(fileOut, idoc->GetCameraLibrary())); PassIf(CheckEmitterLibrary(fileOut, idoc->GetEmitterLibrary())); PassIf(CheckForceFieldLibrary(fileOut, idoc->GetForceFieldLibrary())); PassIf(CheckLightLibrary(fileOut, idoc->GetLightLibrary())); PassIf(CheckGeometryLibrary(fileOut, idoc->GetGeometryLibrary())); PassIf(CheckControllerLibrary(fileOut, idoc->GetControllerLibrary())); PassIf(CheckMaterialLibrary(fileOut, idoc->GetMaterialLibrary())); PassIf(CheckAnimationLibrary(fileOut, idoc->GetAnimationLibrary())); PassIf(CheckPhysics(fileOut, idoc)); // Check that the document extra data is available and intact. FCDEType* type = idoc->GetExtra()->FindType("TOTO"); FailIf(type == NULL); FCDETechnique* technique = type->FindTechnique("TOTO_TECHNIQUE"); FailIf(technique == NULL); FCDENode* extraNode = technique->FindParameter("AParameter"); PassIf(extraNode != NULL); PassIf(IsEquivalent(extraNode->GetContent(), FC("AValue"))); SAFE_RELEASE(idoc); TESTSUITE_TEST(2, paramImport) // Import this document. FUErrorSimpleHandler errorHandler; FUObjectRef idoc = FCollada::NewTopDocument(); PassIf(FCollada::LoadDocumentFromFile(idoc, FC("TestSphere.dae"))); #ifdef _WIN32 OutputDebugStringA(errorHandler.GetErrorString()); #endif PassIf(errorHandler.IsSuccessful()); // Verify the data. FCDEffectLibrary* effectLibrary = idoc->GetEffectLibrary(); FCDEffect* effect = effectLibrary->GetEntity(0); FCDEffectProfile* profile = effect->GetProfile(0); FCDEffectStandard* effectStandard = (FCDEffectStandard*) profile; // Verify a sample of the regular data. FCDEffectParameterColor4* specular = effectStandard->GetSpecularColorParam(); PassIf(IsEquivalent(specular->GetValue(), FMVector4(0.9f, 0.9f, 0.9f, 1.0f))); FCDEffectParameterFloat* indexOfRefraction = effectStandard->GetIndexOfRefractionParam(); PassIf(IsEquivalent(indexOfRefraction->GetValue(), 1.0f)); // Verify the referenced data one by one... FCDEffectParameterColor4* ambient = effectStandard->GetAmbientColorParam(); PassIf(IsEquivalent("myAmbient", ambient->GetReference())); PassIf(ambient->IsReferencer()); FCDEffectParameterFloat* shininess = effectStandard->GetShininessParam(); PassIf(IsEquivalent("myShininess", shininess->GetReference())); PassIf(shininess->IsReferencer()); FCDEffectParameterColor4* reflective = effectStandard->GetReflectivityColorParam(); PassIf(IsEquivalent("myReflective", reflective->GetReference())); PassIf(reflective->IsReferencer()); // Verify default values PassIf(IsEquivalent(FMVector4::AlphaOne, ambient->GetValue())); PassIf(IsEquivalent(FMVector4::One, reflective->GetValue())); PassIf(IsEquivalent(20.0f, shininess->GetValue())); // Verify the values in the param's list FCDEffectParameterFloat* profileShininess = (FCDEffectParameterFloat*) FCDEffectTools::FindEffectParameterByReference(profile, "myShininess", true); PassIf(IsEquivalent(profileShininess->GetValue(), 10.0f)); PassIf(profileShininess->IsGenerator()); FCDEffectParameterFloat3* profileAmbient = (FCDEffectParameterFloat3*) FCDEffectTools::FindEffectParameterByReference(profile, "myAmbient", true); PassIf(IsEquivalent(profileAmbient->GetValue()->x, 0.59f)); PassIf(IsEquivalent(profileAmbient->GetValue()->y, 0.59f)); PassIf(IsEquivalent(profileAmbient->GetValue()->z, 0.59f)); PassIf(profileAmbient->IsGenerator()); FCDEffectParameterColor4* effectReflectivityRef = (FCDEffectParameterColor4*) FCDEffectTools::FindEffectParameterByReference(effect, "myReflective", true); FCDEffectParameterColor4* effectReflectivitySem = (FCDEffectParameterColor4*) FCDEffectTools::FindEffectParameterBySemantic(effect, "REFLECTIVITY", true); PassIf(effectReflectivityRef == effectReflectivitySem); PassIf(IsEquivalent(effectReflectivityRef->GetValue(), FMVector4(0.5f, 0.25f, 0.125f, 1.0f))); PassIf(effectReflectivityRef->IsGenerator()); // Verify the modifier that's in the material instance parameter's list FCDMaterialLibrary* materialLibrary = idoc->GetMaterialLibrary(); FCDMaterial* material = materialLibrary->GetEntity(0); FCDEffectParameterFloat* materialShininess = (FCDEffectParameterFloat*) FCDEffectTools::FindEffectParameterByReference(material, "myShininess", true); PassIf(IsEquivalent(materialShininess->GetValue(), 0.2f)); PassIf(materialShininess->IsModifier()); // Verify the animator that's in the geometry instance parameter's list FCDVisualSceneNodeLibrary* visualScene = idoc->GetVisualSceneLibrary(); PassIf(IsEquivalent((uint32)1, (uint32)visualScene->GetEntityCount())); FCDSceneNode* sceneNode = visualScene->GetEntity(0); FCDSceneNode* childNode = sceneNode->GetChild(0); FCDEntityInstance* instance = childNode->GetInstance(0); FCDGeometryInstance* geometryInstance = (FCDGeometryInstance*) instance; FCDEffectParameterFloat* instanceShininess = (FCDEffectParameterFloat*) FCDEffectTools::FindEffectParameterBySemantic(geometryInstance, "SHININESS"); PassIf(instanceShininess != NULL); PassIf(IsEquivalent(instanceShininess->GetType(), FCDEffectParameter::FLOAT)); PassIf(instanceShininess == FCDEffectTools::FindEffectParameterByReference(geometryInstance, "myShininessAnimated")); PassIf(instanceShininess->IsAnimator()); //Write it out again. FCollada::SaveDocument(idoc, FC("TestSphereOut.dae")); #ifdef _WIN32 OutputDebugStringA(errorHandler.GetErrorString()); #endif PassIf(errorHandler.IsSuccessful()); SAFE_RELEASE(idoc); FUObjectRef idoc2 = FCollada::NewTopDocument(); PassIf(FCollada::LoadDocumentFromFile(idoc2, FC("TestSphereOut.dae"))); #ifdef _WIN32 OutputDebugStringA(errorHandler.GetErrorString()); #endif PassIf(errorHandler.IsSuccessful()); // Verify the data. FCDEffectLibrary* effectLibrary2 = idoc2->GetEffectLibrary(); FCDEffect* effect2 = effectLibrary2->GetEntity(0); FCDEffectProfile* profile2 = effect2->GetProfile(0); FCDEffectStandard* effectStandard2 = (FCDEffectStandard*) profile2; // Verify a sample of the regular data. FCDEffectParameterColor4* specular2 = effectStandard2->GetSpecularColorParam(); PassIf(IsEquivalent(specular2->GetValue(), FMVector4(0.9f, 0.9f, 0.9f, 1.0f))); FCDEffectParameterFloat* indexOfRefraction2 = effectStandard2->GetIndexOfRefractionParam(); PassIf(IsEquivalent(indexOfRefraction2->GetValue(), 1.0f)); // Verify the referenced data one by one... FCDEffectParameterColor4* ambient2 = effectStandard2->GetAmbientColorParam(); PassIf(IsEquivalent("myAmbient", ambient2->GetReference())); PassIf(ambient2->IsReferencer()); FCDEffectParameterFloat* shininess2 = effectStandard2->GetShininessParam(); PassIf(IsEquivalent("myShininess", shininess2->GetReference())); PassIf(shininess2->IsReferencer()); FCDEffectParameterColor4* reflective2 = effectStandard2->GetReflectivityColorParam(); PassIf(IsEquivalent("myReflective", reflective2->GetReference())); PassIf(reflective2->IsReferencer()); // Verify default values PassIf(IsEquivalent(FMVector4::AlphaOne, ambient2->GetValue())); PassIf(IsEquivalent(FMVector4::One, reflective2->GetValue())); PassIf(IsEquivalent(20.0f, shininess2->GetValue())); // Verify the values in the param's list FCDEffectParameterFloat* profileShininess2 = (FCDEffectParameterFloat*) FCDEffectTools::FindEffectParameterByReference(profile2, "myShininess", true); PassIf(IsEquivalent(profileShininess2->GetValue(), 10.0f)); PassIf(profileShininess2->IsGenerator()); FCDEffectParameterFloat3* profileAmbient2 = (FCDEffectParameterFloat3*) FCDEffectTools::FindEffectParameterByReference(profile2, "myAmbient", true); PassIf(IsEquivalent(profileAmbient2->GetValue()->x, 0.59f)); PassIf(IsEquivalent(profileAmbient2->GetValue()->y, 0.59f)); PassIf(IsEquivalent(profileAmbient2->GetValue()->z, 0.59f)); PassIf(profileAmbient2->IsGenerator()); FCDEffectParameterColor4* effectReflectivityRef2 = (FCDEffectParameterColor4*) FCDEffectTools::FindEffectParameterByReference(effect2, "myReflective", true); FCDEffectParameterColor4* effectReflectivitySem2 = (FCDEffectParameterColor4*) FCDEffectTools::FindEffectParameterBySemantic(effect2, "REFLECTIVITY", true); PassIf(effectReflectivityRef2 == effectReflectivitySem2); PassIf(IsEquivalent(effectReflectivityRef2->GetValue(), FMVector4(0.5f, 0.25f, 0.125f, 1.0f))); PassIf(effectReflectivityRef2->IsGenerator()); // Verify the modifier that's in the material instance parameter's list FCDMaterialLibrary* materialLibrary2 = idoc2->GetMaterialLibrary(); FCDMaterial* material2 = materialLibrary2->GetEntity(0); FCDEffectParameterFloat* materialShininess2 = (FCDEffectParameterFloat*) FCDEffectTools::FindEffectParameterByReference(material2, "myShininess", true); PassIf(IsEquivalent(materialShininess2->GetValue(), 0.2f)); PassIf(materialShininess2->IsModifier()); // Verify the animator that's in the geometry instance parameter's list FCDVisualSceneNodeLibrary* visualScene2 = idoc2->GetVisualSceneLibrary(); PassIf(IsEquivalent((uint32)1, (uint32)visualScene2->GetEntityCount())); FCDSceneNode* sceneNode2 = visualScene2->GetEntity(0); FCDSceneNode* childNode2 = sceneNode2->GetChild(0); FCDEntityInstance* instance2 = childNode2->GetInstance(0); FCDGeometryInstance* geometryInstance2 = (FCDGeometryInstance*) instance2; FCDEffectParameterFloat* instanceShininess2 = (FCDEffectParameterFloat*) FCDEffectTools::FindEffectParameterBySemantic(geometryInstance2, "SHININESS"); PassIf(IsEquivalent(instanceShininess2->GetType(), FCDEffectParameter::FLOAT)); PassIf(instanceShininess2 == FCDEffectTools::FindEffectParameterByReference(geometryInstance2, "myShininessAnimated")); PassIf(instanceShininess2->IsAnimator()); TESTSUITE_END