summaryrefslogtreecommitdiffstats
path: root/src/Authoring/QT3DSIMP/Qt3DSImportSGTranslation/Qt3DSImportColladaSGTranslation.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Authoring/QT3DSIMP/Qt3DSImportSGTranslation/Qt3DSImportColladaSGTranslation.cpp')
-rw-r--r--src/Authoring/QT3DSIMP/Qt3DSImportSGTranslation/Qt3DSImportColladaSGTranslation.cpp111
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;
}