diff options
Diffstat (limited to 'src/Authoring/QT3DSIMP/Qt3DSImportSGTranslation/Qt3DSImportColladaSGTranslation.cpp')
-rw-r--r-- | src/Authoring/QT3DSIMP/Qt3DSImportSGTranslation/Qt3DSImportColladaSGTranslation.cpp | 111 |
1 files changed, 81 insertions, 30 deletions
diff --git a/src/Authoring/QT3DSIMP/Qt3DSImportSGTranslation/Qt3DSImportColladaSGTranslation.cpp b/src/Authoring/QT3DSIMP/Qt3DSImportSGTranslation/Qt3DSImportColladaSGTranslation.cpp index 2bf58a85..0cadee7b 100644 --- a/src/Authoring/QT3DSIMP/Qt3DSImportSGTranslation/Qt3DSImportColladaSGTranslation.cpp +++ b/src/Authoring/QT3DSIMP/Qt3DSImportSGTranslation/Qt3DSImportColladaSGTranslation.cpp @@ -40,8 +40,7 @@ #include "Qt3DSImportTranslationCommon.h" #include "Qt3DSImportSceneGraphTranslation.h" #include "Qt3DSImportTranslation.h" -#include "Dialogs.h" -#include "StudioApp.h" +#include "Rotation3.h" #include <QtCore/qbytearray.h> #include <QtCore/qfileinfo.h> @@ -74,7 +73,7 @@ public: public: bool LoadDocument(const std::string &inFilePath); - void ProcessScene(); + bool ProcessScene(); void ProcessLibraryAnimations(); protected: @@ -88,7 +87,8 @@ protected: void ProcessGeometry(const domGeometry *inGeometry, TFaceIndicies &ioIndicies); void ProcessTriangle(const domTrianglesRef inTrianglesRef, TFaceIndicies &ioFaceIndicies, bool &outHasNormals, bool &outHasTexCoords, bool &outHasTexCoords2, - bool &outHasTexTangents, bool &outHasTexBinormals, bool &outHasColors); + bool &outHasTexTangents, bool &outHasTexBinormals, bool &outHasColors, + const char *meshName); void GenerateMeshTangents(const domTrianglesRef inTrianglesRef, const SSourceArrayInfo &inVertexArrayInfo, const SSourceArrayInfo &inNormalArrayInfo, @@ -129,6 +129,7 @@ protected: void TrackObjectIndex(const daeElement *inElement, long inIndex); void GetIndicesFromElement(const daeElement *inElement, TLongsList &outIndicies); bool ApplyAnimation(const daeElement *inContainerElement); + int CheckLightType(const domLight *light); protected: std::function<void(const char *)> PushGroup; @@ -174,6 +175,7 @@ protected: ISceneGraphTranslation *m_Translator; const char *m_DAEFilename; TElementToIndicesMap m_ElementToIndicies; + EAuthoringToolType m_authoringTool; }; void FindTexturesViaNewParam(daeElement *inElementPtr, ColladaDOMWalker::TURIList &outTexturePaths) @@ -361,10 +363,13 @@ bool ColladaDOMWalker::LoadDocument(const std::string &inFilePath) * This begins by looking at the active visual_scene node and starting import * from that node. */ -void ColladaDOMWalker::ProcessScene() +bool ColladaDOMWalker::ProcessScene() { if (m_ColladaRoot != nullptr) { const domCOLLADA::domSceneRef theScene = m_ColladaRoot->getScene(); + if (!theScene) + return false; + // Retrieve the active visual_scene const domInstanceWithExtraRef theInstanceVisualScene = theScene->getInstance_visual_scene(); const xsAnyURI &theVisualSceneURI = theInstanceVisualScene->getUrl(); @@ -411,6 +416,8 @@ void ColladaDOMWalker::ProcessScene() // Disable wrapping the visual scene in it's own group, since m_TopMostParent exists // PopGroup( ); } + + return true; } void ColladaDOMWalker::SetFColladaAuthoringTool(const char *inName) @@ -466,6 +473,9 @@ void ColladaDOMWalker::SetFColladaAuthoringTool(const char *inName) } else if (theAuthoringToolLowerCase.find("opencollada") != std::string::npos && theAuthoringToolLowerCase.find("3ds max") != std::string::npos) { theAuthoringToolType = EAuthoringToolType_FCollada_Max; + } else if (theAuthoringToolLowerCase.find("opencollada") != std::string::npos) { + // Assume Maya if no 3ds max was found + theAuthoringToolType = EAuthoringToolType_OpenCollada_Maya; } long theAuthoringToolVersion = 0; @@ -473,6 +483,7 @@ void ColladaDOMWalker::SetFColladaAuthoringTool(const char *inName) || theAuthoringToolType == EAuthoringToolType_FCollada_Maya) theAuthoringToolVersion = GetFColladaVersion(theAuthoringToolLowerCase); + m_authoringTool = theAuthoringToolType; SetAuthoringTool(theAuthoringToolType, theAuthoringToolVersion); } @@ -516,9 +527,9 @@ void ColladaDOMWalker::ProcessNode(const domNodeRef inNode) { switch (inNode->getType()) { case NODETYPE_NODE: { - const domInstance_geometry_Array &theInstanceGeometryArray = - inNode->getInstance_geometry_array(); - long theGeometryCount = (long)theInstanceGeometryArray.getCount(); + const domInstance_geometry_Array &theInstanceGeometryArray + = inNode->getInstance_geometry_array(); + size_t theGeometryCount = theInstanceGeometryArray.getCount(); bool thePushModelFlag = false; bool lightFlag = false; bool cameraFlag = false; @@ -542,9 +553,9 @@ void ColladaDOMWalker::ProcessNode(const domNodeRef inNode) PushGroup(GetNameOrIDOrSid(inNode)); ProcessTransform(inNode); - for (long theIndex = 0; theIndex < theGeometryCount; ++theIndex) { + for (size_t theIndex = 0; theIndex < theGeometryCount; ++theIndex) { const domInstance_geometryRef theInstanceGeometryRef = - theInstanceGeometryArray[theIndex]; + theInstanceGeometryArray[theIndex]; PushModel(GetNameOrIDOrSid(theInstanceGeometryRef)); ProcessInstanceGeometry(inNode, theInstanceGeometryRef); PopModel(); @@ -569,20 +580,30 @@ void ColladaDOMWalker::ProcessNode(const domNodeRef inNode) double clipstart = 0; double clipend = 0; bool ortho = false; + double aspectRatio = 0; if (technique->getPerspective()) { fov = technique->getPerspective()->getXfov() != nullptr ? technique->getPerspective()->getXfov()->getValue() : technique->getPerspective()->getYfov()->getValue(); clipstart = technique->getPerspective()->getZnear()->getValue(); clipend = technique->getPerspective()->getZfar()->getValue(); + aspectRatio = technique->getPerspective()->getAspect_ratio()->getValue(); } else if (technique->getOrthographic()) { fov = technique->getOrthographic()->getXmag() != nullptr ? technique->getOrthographic()->getXmag()->getValue() : technique->getOrthographic()->getYmag()->getValue(); clipstart = technique->getOrthographic()->getZnear()->getValue(); clipend = technique->getOrthographic()->getZfar()->getValue(); + aspectRatio = technique->getOrthographic()->getAspect_ratio()->getValue(); ortho = true; } + if (m_authoringTool == EAuthoringToolType_OpenCollada_Maya) { + // Calculate horizontal fov from vertical fov: + // hfov = 2 * tan-1(w/h * tan(vfov / 2)) + fov = Q3DStudio::QT3DS_RADIANS_TO_DEGREES * 2 + * std::atan(aspectRatio * std::tan(Q3DStudio::QT3DS_DEGREES_TO_RADIANS + * fov / 2.)); + } SetCameraProperties(clipstart, clipend, ortho, fov); } else if (lights.getCount()) { // Light @@ -600,6 +621,11 @@ void ColladaDOMWalker::ProcessNode(const domNodeRef inNode) double linearFade = 0; double quadFade = 0; if (technique->getPoint()) { + // Blender exports Area light as Point type, so we need to check if we are + // dealing with Blender, and dig the actual light type from inside extra + // elements + type = CheckLightType(light); + type = (type == -1) ? 0 : type; domLight::domTechnique_common::domPointRef point = technique->getPoint(); color = point->getColor()->getValue(); linearFade = point->getLinear_attenuation()->getValue() * 1000; @@ -610,7 +636,11 @@ void ColladaDOMWalker::ProcessNode(const domNodeRef inNode) = technique->getDirectional(); color = directional->getColor()->getValue(); } else if (technique->getAmbient()) { - type = 4; + // Blender exports Hemi light as Ambient type, so we need to check if we are + // dealing with Blender, and dig the actual light type from inside extra + // elements + type = CheckLightType(light); + type = (type == -1) ? 4 : type; domLight::domTechnique_common::domAmbientRef ambient = technique->getAmbient(); color = ambient->getColor()->getValue(); } else { @@ -621,11 +651,12 @@ void ColladaDOMWalker::ProcessNode(const domNodeRef inNode) color = spot->getColor()->getValue(); linearFade = spot->getLinear_attenuation()->getValue() * 1000; quadFade = spot->getQuadratic_attenuation()->getValue() * 1000; + LogWarning(ESceneGraphWarningCode_UnsupportedLight, GetNameOrIDOrSid(inNode)); } // Collada does not seem to have info about casting shadows or light intensity. // We'll use the defaults (intensity 100, no shadows) - SetLightProperties(type, - SFloat4(color.get(0), color.get(1), color.get(2), color.get(3)), + SetLightProperties(type, SFloat4(float(color.get(0)), float(color.get(1)), + float(color.get(2)), 1.0f), 100, linearFade, quadFade, false); } } @@ -653,6 +684,29 @@ void ColladaDOMWalker::ProcessNode(const domNodeRef inNode) } } +int ColladaDOMWalker::CheckLightType(const domLight *light) +{ + // In case of Blender, dig the actual light type from inside extra techniques + const domExtra_Array &lightExtraArray = light->getExtra_array(); + size_t extrasCount = lightExtraArray.getCount(); + for (size_t i = 0; i < extrasCount; ++i) { + domExtraRef lightExtra = lightExtraArray[i]; + const domTechnique_Array &lightExtraTechniqueArray + = lightExtra->getTechnique_array(); + size_t techniqueCount = lightExtraTechniqueArray.getCount(); + for (size_t j = 0; j < techniqueCount; ++j) { + domTechniqueRef lightExtraTechnique = lightExtraTechniqueArray[i]; + const char *profile = lightExtraTechnique->getProfile(); + if (::strcmp(profile, "blender") == 0) { + if (daeElement *theElement = lightExtraTechnique->getChild("type")) + return GetIntFromElementChar(theElement); + break; + } + } + } + return -1; // Not found +} + //============================================================================== /** * Processes transform elements on a <node>. @@ -775,7 +829,15 @@ void ColladaDOMWalker::ProcessGeometry(const domGeometry *inGeometry, TFaceIndic long theTriangleArrayCount = (long)theTriangles.getCount(); for (long theIndex = 0; theIndex < theTriangleArrayCount; ++theIndex) { ProcessTriangle(theTriangles[theIndex], ioFaceIndicies, theHasNormals, theHasTexCoords, - theHasTexCoords2, theHasTexTangents, theHasTexBinormals, theHasColors); + theHasTexCoords2, theHasTexTangents, theHasTexBinormals, theHasColors, + GetNameOrIDOrSid(inGeometry)); + } + + // Pop up warning message if model contains non-triangles geometry + if (theMesh->getPolylist_array().getCount() || theMesh->getPolygons_array().getCount() + || theMesh->getLines_array().getCount() || theMesh->getLinestrips_array().getCount() + || theMesh->getTrifans_array().getCount() || theMesh->getTristrips_array().getCount()) { + LogWarning(ESceneGraphWarningCode_OnlySupportTriangles, GetNameOrIDOrSid(inGeometry)); } // Prepare arrays for population @@ -832,13 +894,6 @@ void ColladaDOMWalker::ProcessGeometry(const domGeometry *inGeometry, TFaceIndic m_Translator->SetGeometry(theVertices, theNormals, theTexCoords, theTexCoords2, theTexTangents, theTexBinormals, theWeights, theBoneIndex, theColors, theEntireFaceIndiciesList); - - // Pop up warning message if model contains non-triangles geometry - if (theMesh->getPolylist_array().getCount() || theMesh->getPolygons_array().getCount() - || theMesh->getLines_array().getCount() || theMesh->getLinestrips_array().getCount() - || theMesh->getTrifans_array().getCount() || theMesh->getTristrips_array().getCount()) { - LogWarning(ESceneGraphWarningCode_OnlySupportTriangles, GetNameOrIDOrSid(inGeometry)); - } } //============================================================================== @@ -849,7 +904,7 @@ void ColladaDOMWalker::ProcessTriangle(const domTrianglesRef inTrianglesRef, TFaceIndicies &ioFaceIndicies, bool &outHasNormals, bool &outHasTexCoords, bool &outHasTexCoords2, bool &outHasTexTangents, bool &outHasTexBinormals, - bool &outHasColors) + bool &outHasColors, const char *meshName) { SSourceArrayInfo theVertexArrayInfo; SSourceArrayInfo theNormalArrayInfo; @@ -1014,13 +1069,10 @@ void ColladaDOMWalker::ProcessTriangle(const domTrianglesRef inTrianglesRef, // Set the face indicies used by this particular material const xsNCName theMaterialName = inTrianglesRef->getMaterial(); // TODO: Handle the material settings for this face - if (theMaterialName != nullptr) { + if (theMaterialName != nullptr) ioFaceIndicies.second.push_back(std::make_pair(theMaterialName, theMaterialFaceIndicies)); - } else { - g_StudioApp.GetDialogs()->DisplayKnownErrorDialog( - QObject::tr("The mesh files could not be created.\n" - "Materials are missing from the imported model.")); - } + else + LogWarning(ESceneGraphWarningCode_MissingMaterial, meshName); } /** @@ -1769,8 +1821,7 @@ bool CImportTranslation::ParseColladaFile(const std::string &fileName, Import &i ColladaDOMWalker theDOMWalker(&transHelper); if (theDOMWalker.LoadDocument(fileName)) { theDOMWalker.ProcessLibraryAnimations(); - theDOMWalker.ProcessScene(); - return true; + return theDOMWalker.ProcessScene(); } return false; } |