summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2015-04-17 20:15:28 +0200
committerPaul Lemire <paul.lemire@kdab.com>2015-05-10 12:25:36 +0000
commitd63464ce4c758b544d35c0fea09f6c1d260a0cb5 (patch)
treec9f78c120302c81c0e01e13b8d6dc28e014eccf5
parent90ba9328495574f8fbd745fb9825bf02e8c2f28d (diff)
AssimpParser: create most appropriate texture material
Also fixed material loading issue (was using wrong material index) Note: the flag aiProcess_FlipUVs was required to have textures displayed correctly. Change-Id: I3f5b436fad20d6bf50c8e5ddca56f78948b44fec Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
-rw-r--r--src/plugins/sceneparsers/assimp/assimpparser.cpp133
-rw-r--r--src/plugins/sceneparsers/assimp/assimpparser_p.h1
2 files changed, 95 insertions, 39 deletions
diff --git a/src/plugins/sceneparsers/assimp/assimpparser.cpp b/src/plugins/sceneparsers/assimp/assimpparser.cpp
index 9673deceb..e0b1713cd 100644
--- a/src/plugins/sceneparsers/assimp/assimpparser.cpp
+++ b/src/plugins/sceneparsers/assimp/assimpparser.cpp
@@ -43,11 +43,14 @@
#include <Qt3DCore/qcameralens.h>
#include <private/qabstractmesh_p.h>
#include <Qt3DRenderer/qparameter.h>
+#include <Qt3DRenderer/qeffect.h>
#include <Qt3DRenderer/qmesh.h>
#include <Qt3DRenderer/qmaterial.h>
#include <Qt3DRenderer/qbuffer.h>
#include <Qt3DRenderer/qattribute.h>
#include <Qt3DRenderer/qtexture.h>
+#include <Qt3DRenderer/qdiffusemapmaterial.h>
+#include <Qt3DRenderer/qdiffusespecularmapmaterial.h>
#include <Qt3DRenderer/qphongmaterial.h>
#include <QFileInfo>
#include <QColor>
@@ -111,8 +114,73 @@ const QString TANGENT_ATTRIBUTE_NAME = QMeshData::defaultTangentAttributeName();
const QString TEXTCOORD_ATTRIBUTE_NAME = QMeshData::defaultTextureCoordinateAttributeName();
const QString COLOR_ATTRIBUTE_NAME = QMeshData::defaultColorAttributeName();
+/*!
+ * Returns a QMatrix4x4 from \a matrix;
+ */
+QMatrix4x4 aiMatrix4x4ToQMatrix4x4(const aiMatrix4x4 &matrix) Q_DECL_NOEXCEPT
+{
+ return QMatrix4x4(matrix.a1, matrix.a2, matrix.a3, matrix.a4,
+ matrix.b1, matrix.b2, matrix.b3, matrix.b4,
+ matrix.c1, matrix.c2, matrix.c3, matrix.c4,
+ matrix.d1, matrix.d2, matrix.d3, matrix.d4);
+}
+
+QMaterial *createBestApproachingMaterial(const aiMaterial *assimpMaterial) Q_DECL_NOEXCEPT
+{
+ aiString path; // unused but necessary
+ const bool hasDiffuseTexture = (assimpMaterial->GetTexture(aiTextureType_DIFFUSE, 0, &path) == AI_SUCCESS);
+ const bool hasSpecularTexture = (assimpMaterial->GetTexture(aiTextureType_SPECULAR, 0, &path) == AI_SUCCESS);
+
+ if (hasDiffuseTexture && hasSpecularTexture)
+ return new QDiffuseSpecularMapMaterial();
+ if (hasDiffuseTexture)
+ return new QDiffuseMapMaterial();
+ return new QPhongMaterial();
+}
+
+QString texturePath(aiString path)
+{
+ QString p = QString::fromUtf8(path.data);
+ if (p.startsWith('/'))
+ p.remove(0, 1);
+ return p;
+}
+
+/*!
+ * Returns the Qt3D::QParameter with named \a name if contained by the material
+ * \a material. If the material doesn't contain the named parameter, a new
+ * Qt3D::QParameter is created and inserted into the material.
+ */
+QParameter *findNamedParameter(const QString &name, QMaterial *material)
+{
+ // Does the material contain the parameter ?
+ foreach (QParameter *p , material->parameters())
+ if (p->name() == name)
+ return p;
+
+ // Does the material's effect contain the parameter ?
+ if (material->effect()) {
+ const QEffect *e = material->effect();
+ foreach (QParameter *p, e->parameters())
+ if (p->name() == name)
+ return p;
+ }
+
+ // Create and add parameter to material
+ QParameter *p = new QParameter(material);
+ p->setName(name);
+ material->addParameter(p);
+ return p;
}
+void setParameterValue(const QString &name, QMaterial *material, const QVariant &value)
+{
+ QParameter *p = findNamedParameter(name, material);
+ p->setValue(value);
+}
+
+} // anonymous
+
QStringList AssimpParser::assimpSupportedFormatsList = AssimpParser::assimpSupportedFormats();
/*!
@@ -260,17 +328,6 @@ bool AssimpParser::isAssimpPath(const QString &path)
}
/*!
- * Returns a QMatrix4x4 from \a matrix;
- */
-QMatrix4x4 AssimpParser::aiMatrix4x4ToQMatrix4x4(const aiMatrix4x4 &matrix)
-{
- return QMatrix4x4(matrix.a1, matrix.a2, matrix.a3, matrix.a4,
- matrix.b1, matrix.b2, matrix.b3, matrix.b4,
- matrix.c1, matrix.c2, matrix.c3, matrix.c4,
- matrix.d1, matrix.d2, matrix.d3, matrix.d4);
-}
-
-/*!
* Sets the \a source used by the parser to load the asset file.
* If the file is valid, this will trigger parsing of the file.
*/
@@ -351,8 +408,9 @@ QEntity *AssimpParser::node(aiNode *node)
uint meshIdx = node->mMeshes[i];
AssimpMesh * mesh = m_scene->m_meshes[meshIdx];
// mesh material
- if (m_scene->m_materials.contains(meshIdx))
- entityNode->addComponent(m_scene->m_materials[meshIdx]);
+ uint materialIndex = m_scene->m_aiScene->mMeshes[meshIdx]->mMaterialIndex;
+ if (m_scene->m_materials.contains(materialIndex))
+ entityNode->addComponent(m_scene->m_materials[materialIndex]);
// mesh
entityNode->addComponent(mesh);
}
@@ -368,7 +426,7 @@ QEntity *AssimpParser::node(aiNode *node)
}
// Add Transformations
- QMatrix4x4 qTransformMatrix = AssimpParser::aiMatrix4x4ToQMatrix4x4(node->mTransformation);
+ const QMatrix4x4 qTransformMatrix = aiMatrix4x4ToQMatrix4x4(node->mTransformation);
QTransform *transform = new QTransform(new QMatrixTransform(qTransformMatrix));
entityNode->addComponent(transform);
@@ -403,7 +461,8 @@ void AssimpParser::readSceneFile(const QString &path)
aiProcess_SortByPType|
aiProcess_Triangulate|
aiProcess_JoinIdenticalVertices|
- aiProcess_GenSmoothNormals);
+ aiProcess_GenSmoothNormals|
+ aiProcess_FlipUVs);
if (m_scene->m_aiScene == Q_NULLPTR) {
qCWarning(AssimpParserLog) << "Assimp scene import failed";
return ;
@@ -453,8 +512,9 @@ void AssimpParser::parse()
*/
void AssimpParser::loadMaterial(uint materialIndex)
{
- QMaterial *material = new QPhongMaterial();
+ // Generates default material based on what the assimp material contains
aiMaterial *assimpMaterial = m_scene->m_aiScene->mMaterials[materialIndex];
+ QMaterial *material = createBestApproachingMaterial(assimpMaterial);
// Material Name
copyMaterialName(material, assimpMaterial);
copyMaterialColorProperties(material, assimpMaterial);
@@ -464,9 +524,7 @@ void AssimpParser::loadMaterial(uint materialIndex)
// Add textures to materials dict
copyMaterialTextures(material, assimpMaterial);
- // TO DO : Set Material Effect and Technique
-
- m_scene->m_materials[materialIndex] = material;
+ m_scene->m_materials.insert(materialIndex, material);
}
/*!
@@ -709,17 +767,17 @@ void AssimpParser::copyMaterialColorProperties(QMaterial *material, aiMaterial *
{
aiColor3D color;
if (assimpMaterial->Get(AI_MATKEY_COLOR_DIFFUSE, color) == aiReturn_SUCCESS)
- material->addParameter(new QParameter(ASSIMP_MATERIAL_DIFFUSE_COLOR, QColor::fromRgbF(color.r, color.g, color.b)));
+ setParameterValue(ASSIMP_MATERIAL_DIFFUSE_COLOR, material, QColor::fromRgbF(color.r, color.g, color.b));
if (assimpMaterial->Get(AI_MATKEY_COLOR_SPECULAR, color) == aiReturn_SUCCESS)
- material->addParameter(new QParameter(ASSIMP_MATERIAL_SPECULAR_COLOR, QColor::fromRgbF(color.r, color.g, color.b)));
+ setParameterValue(ASSIMP_MATERIAL_SPECULAR_COLOR, material, QColor::fromRgbF(color.r, color.g, color.b));
if (assimpMaterial->Get(AI_MATKEY_COLOR_AMBIENT, color) == aiReturn_SUCCESS)
- material->addParameter(new QParameter(ASSIMP_MATERIAL_AMBIENT_COLOR, QColor::fromRgbF(color.r, color.g, color.b)));
+ setParameterValue(ASSIMP_MATERIAL_AMBIENT_COLOR, material, QColor::fromRgbF(color.r, color.g, color.b));
if (assimpMaterial->Get(AI_MATKEY_COLOR_EMISSIVE, color) == aiReturn_SUCCESS)
- material->addParameter(new QParameter(ASSIMP_MATERIAL_EMISSIVE_COLOR, QColor::fromRgbF(color.r, color.g, color.b)));
+ setParameterValue(ASSIMP_MATERIAL_EMISSIVE_COLOR, material, QColor::fromRgbF(color.r, color.g, color.b));
if (assimpMaterial->Get(AI_MATKEY_COLOR_TRANSPARENT, color) == aiReturn_SUCCESS)
- material->addParameter(new QParameter(ASSIMP_MATERIAL_TRANSPARENT_COLOR, QColor::fromRgbF(color.r, color.g, color.b)));
+ setParameterValue(ASSIMP_MATERIAL_TRANSPARENT_COLOR, material, QColor::fromRgbF(color.r, color.g, color.b));
if (assimpMaterial->Get(AI_MATKEY_COLOR_REFLECTIVE, color) == aiReturn_SUCCESS)
- material->addParameter(new QParameter(ASSIMP_MATERIAL_REFLECTIVE_COLOR, QColor::fromRgbF(color.r, color.g, color.b)));
+ setParameterValue(ASSIMP_MATERIAL_REFLECTIVE_COLOR, material, QColor::fromRgbF(color.r, color.g, color.b));
}
/*!
@@ -729,9 +787,9 @@ void AssimpParser::copyMaterialBoolProperties(QMaterial *material, aiMaterial *a
{
int value;
if (assimpMaterial->Get(AI_MATKEY_TWOSIDED, value) == aiReturn_SUCCESS)
- material->addParameter(new QParameter(ASSIMP_MATERIAL_IS_TWOSIDED, (value == 0) ? false : true));
+ setParameterValue(ASSIMP_MATERIAL_IS_TWOSIDED, material, (value == 0) ? false : true);
if (assimpMaterial->Get(AI_MATKEY_ENABLE_WIREFRAME, value) == aiReturn_SUCCESS)
- material->addParameter(new QParameter(ASSIMP_MATERIAL_IS_WIREFRAME, (value == 0) ? false : true));
+ setParameterValue(ASSIMP_MATERIAL_IS_WIREFRAME, material, (value == 0) ? false : true);
}
void AssimpParser::copyMaterialShadingModel(QMaterial *material, aiMaterial *assimpMaterial)
@@ -767,8 +825,7 @@ void AssimpParser::copyMaterialTextures(QMaterial *material, aiMaterial *assimpM
aiTextureType_OPACITY,
aiTextureType_REFLECTION,
aiTextureType_SHININESS,
- aiTextureType_SPECULAR,
- /*aiTextureType_UNKNOWN*/};
+ aiTextureType_SPECULAR};
if (m_scene->m_textureToParameterName.isEmpty()) {
m_scene->m_textureToParameterName.insert(aiTextureType_AMBIENT, ASSIMP_MATERIAL_AMBIENT_TEXTURE);
@@ -787,18 +844,18 @@ void AssimpParser::copyMaterialTextures(QMaterial *material, aiMaterial *assimpM
for (unsigned int i = 0; i < sizeof(textureType)/sizeof(textureType[0]); i++) {
aiString path;
if (assimpMaterial->GetTexture(textureType[i], 0, &path) == AI_SUCCESS) {
- QString fullPath = m_sceneDir.absoluteFilePath(QString::fromUtf8(path.data));
+ QString fullPath = m_sceneDir.absoluteFilePath(texturePath(path));
// Load texture if not already loaded
if (!m_scene->m_materialTextures.contains(fullPath)) {
QAbstractTextureProvider *tex = new QTexture2D();
QTextureImage *texImage = new QTextureImage();
- texImage->setSource(fullPath);
+ texImage->setSource(QUrl::fromLocalFile(fullPath));
tex->addTextureImage(texImage);
m_scene->m_materialTextures.insert(fullPath, tex);
qCDebug(AssimpParserLog) << Q_FUNC_INFO << " Loaded Texture " << fullPath;
}
- material->addParameter(new QParameter(m_scene->m_textureToParameterName[textureType[i]],
- m_scene->m_materialTextures[fullPath]));
+ setParameterValue(m_scene->m_textureToParameterName[textureType[i]],
+ material, QVariant::fromValue(m_scene->m_materialTextures[fullPath]));
}
}
}
@@ -810,15 +867,15 @@ void AssimpParser::copyMaterialFloatProperties(QMaterial *material, aiMaterial *
{
float value = 0;
if (assimpMaterial->Get(AI_MATKEY_OPACITY, value) == aiReturn_SUCCESS)
- material->addParameter(new QParameter(ASSIMP_MATERIAL_OPACITY, value));
+ setParameterValue(ASSIMP_MATERIAL_OPACITY, material, value);
if (assimpMaterial->Get(AI_MATKEY_SHININESS, value) == aiReturn_SUCCESS)
- material->addParameter(new QParameter(ASSIMP_MATERIAL_SHININESS, value));
+ setParameterValue(ASSIMP_MATERIAL_SHININESS, material, value);
if (assimpMaterial->Get(AI_MATKEY_SHININESS_STRENGTH, value) == aiReturn_SUCCESS)
- material->addParameter(new QParameter(ASSIMP_MATERIAL_SHININESS_STRENGTH, value));
+ setParameterValue(ASSIMP_MATERIAL_SHININESS_STRENGTH, material, value);
if (assimpMaterial->Get(AI_MATKEY_REFRACTI, value) == aiReturn_SUCCESS)
- material->addParameter(new QParameter(ASSIMP_MATERIAL_REFRACTI, value));
+ setParameterValue(ASSIMP_MATERIAL_REFRACTI, material, value);
if (assimpMaterial->Get(AI_MATKEY_REFLECTIVITY, value) == aiReturn_SUCCESS)
- material->addParameter(new QParameter(ASSIMP_MATERIAL_REFLECTIVITY, value));
+ setParameterValue(ASSIMP_MATERIAL_REFLECTIVITY, material, value);
}
AssimpMesh::AssimpMesh(QNode *parent)
diff --git a/src/plugins/sceneparsers/assimp/assimpparser_p.h b/src/plugins/sceneparsers/assimp/assimpparser_p.h
index d24472522..b0267d472 100644
--- a/src/plugins/sceneparsers/assimp/assimpparser_p.h
+++ b/src/plugins/sceneparsers/assimp/assimpparser_p.h
@@ -85,7 +85,6 @@ public:
private:
static bool isAssimpPath(const QString &path);
static QStringList assimpSupportedFormats();
- static QMatrix4x4 aiMatrix4x4ToQMatrix4x4(const aiMatrix4x4 &matrix);
QEntity *node(aiNode *node);