8#include <QtCore/qurl.h>
9#include <QtCore/qbytearrayalgorithms.h>
10#include <QtGui/QQuaternion>
12#include <QtQuick3DAssetImport/private/qssgassetimporterfactory_p.h>
13#include <QtQuick3DAssetImport/private/qssgassetimporter_p.h>
14#include <QtQuick3DAssetUtils/private/qssgscenedesc_p.h>
15#include <QtQuick3DAssetUtils/private/qssgsceneedit_p.h>
18#include <assimp/Importer.hpp>
19#include <assimp/scene.h>
20#include <assimp/Logger.hpp>
21#include <assimp/DefaultLogger.hpp>
22#include <assimp/postprocess.h>
23#include <assimp/material.h>
24#include <assimp/GltfMaterial.h>
25#include <assimp/importerdesc.h>
33#define AI_GLTF_FILTER_NEAREST 0x2600
34#define AI_GLTF_FILTER_LINEAR 0x2601
35#define AI_GLTF_FILTER_NEAREST_MIPMAP_NEAREST 0x2700
36#define AI_GLTF_FILTER_LINEAR_MIPMAP_NEAREST 0x2701
37#define AI_GLTF_FILTER_NEAREST_MIPMAP_LINEAR 0x2702
38#define AI_GLTF_FILTER_LINEAR_MIPMAP_LINEAR 0x2703
69[[nodiscard]]
static inline bool isEqual(
const aiUVTransform &
a,
const aiUVTransform &
b)
71 return (
a.mTranslation ==
b.mTranslation &&
a.mScaling ==
b.mScaling &&
a.mRotation ==
b.mRotation);
77 aiTextureMapping
mapping = aiTextureMapping::aiTextureMapping_UV;
86 return (
a.mapping ==
b.mapping)
87 && (std::memcmp(
a.modes,
b.modes,
sizeof(
a.modes)) == 0)
88 && (
a.minFilter ==
b.minFilter)
89 && (
a.magFilter ==
b.magFilter)
90 && (
a.uvIndex ==
b.uvIndex)
103 static_assert(std::is_same_v<
decltype(
key.info.transform), aiUVTransform>,
"Unexpected type");
115 return (
a.name ==
b.name) && (
a.info ==
b.info);
163 aiMatrix4x4 *transformCorrection)
170 aiMatrix4x4 transformMatrix;
171 if (transformCorrection)
172 transformMatrix =
source.mTransformation * *transformCorrection;
174 transformMatrix =
source.mTransformation;
178 aiQuaternion rotation;
179 aiVector3D translation;
180 transformMatrix.Decompose(scaling, rotation, translation);
193 const QQuaternion rot(rotation.w, rotation.x, rotation.y, rotation.z);
217 if (texInfo.
mapping == aiTextureMapping_UV) {
227 static const auto asQtTilingMode = [](aiTextureMapMode
mode) {
229 case aiTextureMapMode_Wrap:
231 case aiTextureMapMode_Clamp:
233 case aiTextureMapMode_Mirror:
249 if (applyUvTransform) {
262 const float rcos = std::cos(rotation);
263 const float rsin = std::sin(rotation);
264 posU -= 0.5f *
transform.mScaling.x * (-rcos + rsin + 1.0f);
265 posV -= (0.5f *
transform.mScaling.y * (rcos + rsin - 1.0f) + 1.0f -
transform.mScaling.y);
285 bool generateMipMaps = forceMipMapGeneration;
315 if (generateMipMaps) {
323 if (
target.name.isNull()) {
324 aiString materialName =
source.GetName();
328 const auto createTextureNode = [&sceneInfo, &
target](
const aiMaterial &material, aiTextureType textureType,
unsigned int index) {
329 const auto &srcScene = sceneInfo.
scene;
331 aiString texturePath;
334 if (material.GetTexture(textureType,
index, &texturePath, &texInfo.
mapping, &texInfo.
uvIndex,
nullptr,
nullptr, texInfo.
modes) == aiReturn_SUCCESS) {
335 if (texturePath.length > 0) {
337 if (material.Get(AI_MATKEY_UVTRANSFORM(textureType,
index),
transform) == aiReturn_SUCCESS)
340 material.Get(AI_MATKEY_UVWSRC(textureType,
index), texInfo.
uvIndex);
341 material.Get(AI_MATKEY_GLTF_MAPPINGFILTER_MIN(textureType,
index), texInfo.
minFilter);
342 material.Get(AI_MATKEY_GLTF_MAPPINGFILTER_MAG(textureType,
index), texInfo.
magFilter);
349 if (
it != textureMap.
cend()) {
360 auto aEmbeddedTex = srcScene.GetEmbeddedTextureAndIndex(texturePath.C_Str());
361 const auto &embeddedTexId = aEmbeddedTex.second;
362 if (embeddedTexId > -1) {
365 textureData = embeddedTextures[embeddedTexId];
377 const quint8 flags = isCompressed ?
quint8(QSSGSceneDesc::TextureData::Flags::Compressed) : 0;
380 embeddedTextures[embeddedTexId] = textureData;
389 relativePath.replace(
"\\",
"/");
402 if (
type == QSSGSceneDesc::Material::RuntimeType::PrincipledMaterial) {
404 aiColor4D baseColorFactor;
405 result =
source.Get(AI_MATKEY_BASE_COLOR, baseColorFactor);
406 if (
result == aiReturn_SUCCESS) {
411 aiColor3D diffuseColor;
412 result =
source.Get(AI_MATKEY_COLOR_DIFFUSE, diffuseColor);
413 if (
result == aiReturn_SUCCESS)
418 if (
auto baseColorTexture = createTextureNode(
source, AI_MATKEY_BASE_COLOR_TEXTURE)) {
421 }
else if (
auto diffuseMapTexture = createTextureNode(
source, aiTextureType_DIFFUSE, 0)) {
426 if (
auto metalicRoughnessTexture = createTextureNode(
source, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE)) {
434 ai_real metallicFactor;
435 result =
source.Get(AI_MATKEY_METALLIC_FACTOR, metallicFactor);
436 if (
result == aiReturn_SUCCESS)
441 ai_real roughnessFactor;
442 result =
source.Get(AI_MATKEY_ROUGHNESS_FACTOR, roughnessFactor);
443 if (
result == aiReturn_SUCCESS)
447 if (
auto normalTexture = createTextureNode(
source, aiTextureType_NORMALS, 0)) {
451 result =
source.Get(AI_MATKEY_GLTF_TEXTURE_SCALE(aiTextureType_NORMALS, 0), normalScale);
452 if (
result == aiReturn_SUCCESS)
458 if (
auto occlusionTexture = createTextureNode(
source, aiTextureType_LIGHTMAP, 0)) {
462 ai_real occlusionAmount;
463 result =
source.Get(AI_MATKEY_GLTF_TEXTURE_STRENGTH(aiTextureType_LIGHTMAP, 0), occlusionAmount);
464 if (
result == aiReturn_SUCCESS)
469 if (
auto emissiveTexture = createTextureNode(
source, aiTextureType_EMISSIVE, 0))
473 aiColor3D emissiveColorFactor;
474 result =
source.Get(AI_MATKEY_COLOR_EMISSIVE, emissiveColorFactor);
475 if (
result == aiReturn_SUCCESS)
482 if (
result == aiReturn_SUCCESS && isDoubleSided)
488 result =
source.Get(AI_MATKEY_GLTF_ALPHAMODE, alphaMode);
489 if (
result == aiReturn_SUCCESS) {
505 result =
source.Get(AI_MATKEY_GLTF_ALPHACUTOFF, alphaCutoff);
506 if (
result == aiReturn_SUCCESS)
511 int shadingModel = 0;
512 result =
source.Get(AI_MATKEY_SHADING_MODEL, shadingModel);
513 if (
result == aiReturn_SUCCESS && shadingModel == aiShadingMode_Unlit)
522 ai_real clearcoatFactor = 0.0f;
523 result =
source.Get(AI_MATKEY_CLEARCOAT_FACTOR, clearcoatFactor);
524 if (
result == aiReturn_SUCCESS)
527 &QQuick3DPrincipledMaterial::setClearcoatAmount,
528 float(clearcoatFactor));
533 ai_real clearcoatRoughnessFactor = 0.0f;
534 result =
source.Get(AI_MATKEY_CLEARCOAT_ROUGHNESS_FACTOR, clearcoatRoughnessFactor);
535 if (
result == aiReturn_SUCCESS)
537 "clearcoatRoughnessAmount",
538 &QQuick3DPrincipledMaterial::setClearcoatRoughnessAmount,
539 float(clearcoatRoughnessFactor));
543 if (
auto clearcoatTexture = createTextureNode(
source, AI_MATKEY_CLEARCOAT_TEXTURE))
547 if (
auto clearcoatRoughnessTexture = createTextureNode(
source, AI_MATKEY_CLEARCOAT_ROUGHNESS_TEXTURE))
549 "clearcoatRoughnessMap",
550 &QQuick3DPrincipledMaterial::setClearcoatRoughnessMap,
551 clearcoatRoughnessTexture);
554 if (
auto clearcoatNormalTexture = createTextureNode(
source, AI_MATKEY_CLEARCOAT_NORMAL_TEXTURE))
562 ai_real transmissionFactor = 0.0f;
563 result =
source.Get(AI_MATKEY_TRANSMISSION_FACTOR, transmissionFactor);
564 if (
result == aiReturn_SUCCESS)
566 "transmissionFactor",
567 &QQuick3DPrincipledMaterial::setTransmissionFactor,
568 float(transmissionFactor));
573 if (
auto transmissionImage = createTextureNode(
source, AI_MATKEY_TRANSMISSION_TEXTURE))
576 &QQuick3DPrincipledMaterial::setTransmissionMap,
586 ai_real thicknessFactor = 0.0f;
587 result =
source.Get(AI_MATKEY_VOLUME_THICKNESS_FACTOR, thicknessFactor);
588 if (
result == aiReturn_SUCCESS)
594 if (
auto thicknessImage = createTextureNode(
source, AI_MATKEY_VOLUME_THICKNESS_TEXTURE))
600 ai_real attenuationDistance = 0.0f;
601 result =
source.Get(AI_MATKEY_VOLUME_ATTENUATION_DISTANCE, attenuationDistance);
602 if (
result == aiReturn_SUCCESS)
604 "attenuationDistance",
605 &QQuick3DPrincipledMaterial::setAttenuationDistance,
606 float(attenuationDistance));
611 aiColor3D attenuationColor;
612 result =
source.Get(AI_MATKEY_VOLUME_ATTENUATION_COLOR, attenuationColor);
613 if (
result == aiReturn_SUCCESS)
616 &QQuick3DPrincipledMaterial::setAttenuationColor,
626 if (
result == aiReturn_SUCCESS)
629 &QQuick3DPrincipledMaterial::setIndexOfRefraction,
633 }
else if (
type == QSSGSceneDesc::Material::RuntimeType::DefaultMaterial) {
634 int shadingModel = 0;
636 result = material->Get(AI_MATKEY_SHADING_MODEL, shadingModel);
638 if (
result == aiReturn_SUCCESS && (shadingModel == aiShadingMode_NoShading))
641 if (
auto diffuseMapTexture = createTextureNode(
source, aiTextureType_DIFFUSE, 0)) {
646 aiColor3D diffuseColor;
647 result = material->Get(AI_MATKEY_COLOR_DIFFUSE, diffuseColor);
648 if (
result == aiReturn_SUCCESS)
652 if (
auto emissiveTexture = createTextureNode(
source, aiTextureType_EMISSIVE, 0))
656 if (
auto specularTexture = createTextureNode(
source, aiTextureType_SPECULAR, 0))
661 result = material->Get(AI_MATKEY_OPACITY, opacity);
662 if (
result == aiReturn_SUCCESS)
666 if (
auto opacityTexture = createTextureNode(
source, aiTextureType_OPACITY, 0))
670 if (
auto bumpTexture = createTextureNode(
source, aiTextureType_HEIGHT, 0)) {
674 result = material->Get(AI_MATKEY_BUMPSCALING, bumpAmount);
675 if (
result == aiReturn_SUCCESS)
680 if (
auto normalTexture = createTextureNode(
source, aiTextureType_NORMALS, 0))
682 }
else if (
type == QSSGSceneDesc::Material::RuntimeType::SpecularGlossyMaterial) {
684 aiColor4D albedoFactor;
685 result =
source.Get(AI_MATKEY_COLOR_DIFFUSE, albedoFactor);
686 if (
result == aiReturn_SUCCESS)
690 if (
auto albedoTexture = createTextureNode(
source, aiTextureType_DIFFUSE, 0)) {
695 if (
auto specularGlossinessTexture = createTextureNode(
source, aiTextureType_SPECULAR, 0)) {
702 aiColor4D specularColorFactor;
703 result =
source.Get(AI_MATKEY_COLOR_SPECULAR, specularColorFactor);
704 if (
result == aiReturn_SUCCESS)
709 ai_real glossinessFactor;
710 result =
source.Get(AI_MATKEY_GLOSSINESS_FACTOR, glossinessFactor);
711 if (
result == aiReturn_SUCCESS)
715 if (
auto normalTexture = createTextureNode(
source, aiTextureType_NORMALS, 0)) {
719 result =
source.Get(AI_MATKEY_GLTF_TEXTURE_SCALE(aiTextureType_NORMALS, 0), normalScale);
720 if (
result == aiReturn_SUCCESS)
726 if (
auto occlusionTexture = createTextureNode(
source, aiTextureType_LIGHTMAP, 0)) {
730 ai_real occlusionAmount;
731 result =
source.Get(AI_MATKEY_GLTF_TEXTURE_STRENGTH(aiTextureType_LIGHTMAP, 0), occlusionAmount);
732 if (
result == aiReturn_SUCCESS)
737 if (
auto emissiveTexture = createTextureNode(
source, aiTextureType_EMISSIVE, 0))
741 aiColor3D emissiveColorFactor;
742 result =
source.Get(AI_MATKEY_COLOR_EMISSIVE, emissiveColorFactor);
743 if (
result == aiReturn_SUCCESS)
750 if (
result == aiReturn_SUCCESS && isDoubleSided)
756 result =
source.Get(AI_MATKEY_GLTF_ALPHAMODE, alphaMode);
757 if (
result == aiReturn_SUCCESS) {
773 result =
source.Get(AI_MATKEY_GLTF_ALPHACUTOFF, alphaCutoff);
774 if (
result == aiReturn_SUCCESS)
779 int shadingModel = 0;
780 result =
source.Get(AI_MATKEY_SHADING_MODEL, shadingModel);
781 if (
result == aiReturn_SUCCESS && shadingModel == aiShadingMode_Unlit)
790 ai_real clearcoatFactor = 0.0f;
791 result =
source.Get(AI_MATKEY_CLEARCOAT_FACTOR, clearcoatFactor);
792 if (
result == aiReturn_SUCCESS)
796 float(clearcoatFactor));
801 ai_real clearcoatRoughnessFactor = 0.0f;
802 result =
source.Get(AI_MATKEY_CLEARCOAT_ROUGHNESS_FACTOR, clearcoatRoughnessFactor);
803 if (
result == aiReturn_SUCCESS)
805 "clearcoatRoughnessAmount",
807 float(clearcoatRoughnessFactor));
811 if (
auto clearcoatTexture = createTextureNode(
source, AI_MATKEY_CLEARCOAT_TEXTURE))
815 if (
auto clearcoatRoughnessTexture = createTextureNode(
source, AI_MATKEY_CLEARCOAT_ROUGHNESS_TEXTURE))
817 "clearcoatRoughnessMap",
819 clearcoatRoughnessTexture);
822 if (
auto clearcoatNormalTexture = createTextureNode(
source, AI_MATKEY_CLEARCOAT_NORMAL_TEXTURE))
830 ai_real transmissionFactor = 0.0f;
831 result =
source.Get(AI_MATKEY_TRANSMISSION_FACTOR, transmissionFactor);
832 if (
result == aiReturn_SUCCESS)
834 "transmissionFactor",
836 float(transmissionFactor));
841 if (
auto transmissionImage = createTextureNode(
source, AI_MATKEY_TRANSMISSION_TEXTURE))
854 ai_real thicknessFactor = 0.0f;
855 result =
source.Get(AI_MATKEY_VOLUME_THICKNESS_FACTOR, thicknessFactor);
856 if (
result == aiReturn_SUCCESS)
862 if (
auto thicknessImage = createTextureNode(
source, AI_MATKEY_VOLUME_THICKNESS_TEXTURE))
868 ai_real attenuationDistance = 0.0f;
869 result =
source.Get(AI_MATKEY_VOLUME_ATTENUATION_DISTANCE, attenuationDistance);
870 if (
result == aiReturn_SUCCESS)
872 "attenuationDistance",
874 float(attenuationDistance));
879 aiColor3D attenuationColor;
880 result =
source.Get(AI_MATKEY_VOLUME_ATTENUATION_COLOR, attenuationColor);
881 if (
result == aiReturn_SUCCESS)
896 target.runtimeType = (
source.mHorizontalFOV == 0.0f) ? Node::RuntimeType::OrthographicCamera
897 : Node::RuntimeType::PerspectiveCamera;
901 aiMatrix4x4 correctionMatrix;
902 bool needsCorrection =
false;
903 aiVector3D upQuick3D = aiVector3D(0, 1, 0);
904 if (
source.mLookAt != aiVector3D(0, 0, -1)) {
905 aiMatrix4x4 lookAtCorrection;
906 aiMatrix4x4::FromToMatrix(aiVector3D(0, 0, -1),
source.mLookAt, lookAtCorrection);
907 correctionMatrix *= lookAtCorrection;
908 needsCorrection =
true;
909 upQuick3D *= lookAtCorrection;
911 if (
source.mUp != upQuick3D) {
912 aiMatrix4x4 upCorrection;
913 aiMatrix4x4::FromToMatrix(upQuick3D,
source.mUp, upCorrection);
914 correctionMatrix = upCorrection * correctionMatrix;
915 needsCorrection =
true;
921 if (
target.runtimeType == Node::RuntimeType::PerspectiveCamera) {
929 if (
target.runtimeType == Node::RuntimeType::PerspectiveCamera) {
940 const float width =
source.mOrthographicWidth * 2.0f;
961 aiMatrix4x4 correctionMatrix;
962 bool needsCorrection =
false;
963 if (
source.mDirection != aiVector3D(0, 0, 0)) {
964 if (
source.mDirection != aiVector3D(0, 0, -1)) {
965 aiMatrix4x4::FromToMatrix(aiVector3D(0, 0, -1),
source.mDirection, correctionMatrix);
966 needsCorrection =
true;
971 static const auto asQtLightType = [](aiLightSourceType
type) {
973 case aiLightSource_AMBIENT:
975 case aiLightSource_DIRECTIONAL:
976 return QSSGSceneDesc::Light::RuntimeType::DirectionalLight;
977 case aiLightSource_POINT:
978 return QSSGSceneDesc::Light::RuntimeType::PointLight;
979 case aiLightSource_SPOT:
980 return QSSGSceneDesc::Light::RuntimeType::SpotLight;
982 return QSSGSceneDesc::Light::RuntimeType::PointLight;
1000 if (
source.mType == aiLightSource_AMBIENT) {
1006 source.mColorAmbient.g / brightness,
1007 source.mColorAmbient.b / brightness);
1013 source.mColorDiffuse.g / brightness,
1014 source.mColorDiffuse.b / brightness);
1020 const bool isSpot = (
source.mType == aiLightSource_SPOT);
1021 if (
source.mType == aiLightSource_POINT || isSpot) {
1062 const quint32 numMorphTargets =
qMin(8U, mesh.mNumAnimMeshes);
1064 for (
uint i = 0;
i < numMorphTargets; ++
i) {
1065 const auto &animMesh = mesh.mAnimMeshes[
i];
1066 QQuick3DMorphTarget::MorphTargetAttributes mTarget;
1067 if (animMesh->HasPositions())
1069 if (animMesh->HasNormals())
1071 if (animMesh->HasTangentsAndBitangents()) {
1082 if (
source.mNumMeshes == 0)
1085 auto &targetScene =
target.scene;
1086 const auto &srcScene = sceneInfo.
scene;
1090 auto &meshStorage = targetScene->meshStorage;
1092 auto &meshMap = sceneInfo.
meshMap;
1093 auto &skinMap = sceneInfo.
skinMap;
1101 const auto ensureMaterial = [&](
qsizetype materialIndex) {
1103 auto &material = materialMap[materialIndex];
1105 auto targetMat = material.second;
1106 if (targetMat ==
nullptr) {
1107 const aiMaterial *sourceMat = material.
first;
1109 auto currentMaterialType = QSSGSceneDesc::Material::RuntimeType::PrincipledMaterial;
1110 ai_real glossinessFactor;
1111 aiReturn
result = sourceMat->Get(AI_MATKEY_GLOSSINESS_FACTOR, glossinessFactor);
1112 if (
result == aiReturn_SUCCESS)
1113 currentMaterialType = QSSGSceneDesc::Material::RuntimeType::SpecularGlossyMaterial;
1118 material.second = targetMat;
1121 Q_ASSERT(targetMat !=
nullptr && material.second !=
nullptr);
1123 Q_ASSERT(srcScene.mMaterials[materialIndex] == material.first);
1139 const auto combineMeshes = [&](
const aiNode &
source, aiMesh **sceneMeshes) {
1141 const aiMesh &mesh = *sceneMeshes[
source.mMeshes[
i]];
1142 ensureMaterial(mesh.mMaterialIndex);
1143 if (skinIdx == -1 && mesh.HasBones())
1144 skinIdx = mesh2skin[
source.mMeshes[
i]];
1149 const auto createMeshNode = [&](
const aiString &
name) {
1157 meshStorage.push_back(std::move(meshData));
1159 const auto idx = meshStorage.size() - 1;
1166 const bool isMultiMesh = (
source.mNumMeshes > 1);
1169 combineMeshes(
source, srcScene.mMeshes);
1171 meshNode = createMeshNode(
source.mName);
1175 auto &mesh = meshMap[*
source.mMeshes];
1176 meshNode = mesh.second;
1177 if (meshNode ==
nullptr) {
1178 meshes = {mesh.
first};
1179 if (mesh.first->HasBones())
1180 skinIdx = mesh2skin[*
source.mMeshes];
1181 mesh.second = meshNode = createMeshNode(mesh.first->mName);
1184 ensureMaterial(mesh.first->mMaterialIndex);
1185 Q_ASSERT(meshNode !=
nullptr && mesh.second !=
nullptr);
1191 if (skinIdx != -1) {
1192 auto &skin = skinMap[skinIdx];
1207 const aiNode &srcNode,
1212 const auto &srcScene = sceneInfo.
scene;
1213 switch (nodeInfo.
type) {
1214 case QSSGSceneDesc::Node::Type::Camera:
1216 const auto &srcType = *srcScene.mCameras[nodeInfo.
index];
1224 case QSSGSceneDesc::Node::Type::Light:
1226 const auto &srcType = *srcScene.mLights[nodeInfo.
index];
1228 auto targetType =
new QSSGSceneDesc::Light(QSSGSceneDesc::Node::RuntimeType::DirectionalLight);
1234 case QSSGSceneDesc::Node::Type::Model:
1242 case QSSGSceneDesc::Node::Type::Joint:
1251 case QSSGSceneDesc::Node::Type::Transform:
1253 node =
new QSSGSceneDesc::Node(QSSGSceneDesc::Node::Type::Transform, QSSGSceneDesc::Node::RuntimeType::Node);
1269 if (
source.mNumMeshes != 0) {
1271 using It =
decltype(
source.mNumMeshes);
1274 const auto &srcScene = sceneInfo.
scene;
1275 const aiMesh &mesh = *srcScene.mMeshes[
source.mMeshes[
i]];
1276 if (mesh.mNumAnimMeshes && mesh.mAnimMeshes) {
1287 const auto morphProp = morphProps.
at(
i);
1295 if (!animationNodes.
isEmpty()) {
1297 const auto aNodeIt = animationNodes.
find(morphTargetName.
toUtf8());
1298 if (aNodeIt != animationNodes.
end() && aNodeIt.
value() ==
nullptr)
1299 *aNodeIt = morphNode;
1307 NodeInfo nodeInfo{ 0, QSSGSceneDesc::Node::Type::Transform };
1319 if (!animationNodes.
isEmpty()) {
1320 const auto &nodeName =
source.mName;
1322 if (aNodeIt != animationNodes.
end() && aNodeIt.
value() ==
nullptr)
1327 using It =
decltype (
source.mNumChildren);
1354 value =
it->toObject().value(
"value");
1358 return value.toBool();
1368 value =
it->toObject().value(
"value");
1373 return value.toDouble();
1376#define demonPostProcessPresets ( \
1377 aiProcess_CalcTangentSpace | \
1378 aiProcess_GenSmoothNormals | \
1379 aiProcess_JoinIdenticalVertices | \
1380 aiProcess_ImproveCacheLocality | \
1381 aiProcess_RemoveRedundantMaterials | \
1382 aiProcess_SplitLargeMeshes | \
1383 aiProcess_Triangulate | \
1384 aiProcess_GenUVCoords | \
1385 aiProcess_SortByPType | \
1386 aiProcess_FindDegenerates | \
1387 aiProcess_FindInvalidData | \
1391 aiPostProcessSteps postProcessSteps = aiPostProcessSteps(aiProcess_Triangulate | aiProcess_SortByPType);;
1399 options =
it->toObject();
1402 return postProcessSteps;
1407 postProcessSteps = aiPostProcessSteps(postProcessSteps | aiProcess_CalcTangentSpace);
1410 postProcessSteps = aiPostProcessSteps(postProcessSteps | aiProcess_JoinIdenticalVertices);
1413 postProcessSteps = aiPostProcessSteps(postProcessSteps | aiProcess_GenNormals);
1416 postProcessSteps = aiPostProcessSteps(postProcessSteps | aiProcess_GenSmoothNormals);
1419 postProcessSteps = aiPostProcessSteps(postProcessSteps | aiProcess_SplitLargeMeshes);
1422 postProcessSteps = aiPostProcessSteps(postProcessSteps | aiProcess_PreTransformVertices);
1425 postProcessSteps = aiPostProcessSteps(postProcessSteps | aiProcess_ImproveCacheLocality);
1428 postProcessSteps = aiPostProcessSteps(postProcessSteps | aiProcess_RemoveRedundantMaterials);
1431 postProcessSteps = aiPostProcessSteps(postProcessSteps | aiProcess_FixInfacingNormals);
1434 postProcessSteps = aiPostProcessSteps(postProcessSteps | aiProcess_FindDegenerates);
1437 postProcessSteps = aiPostProcessSteps(postProcessSteps | aiProcess_FindInvalidData);
1440 postProcessSteps = aiPostProcessSteps(postProcessSteps | aiProcess_TransformUVCoords);
1443 postProcessSteps = aiPostProcessSteps(postProcessSteps | aiProcess_FindInstances);
1446 postProcessSteps = aiPostProcessSteps(postProcessSteps | aiProcess_OptimizeMeshes);
1449 postProcessSteps = aiPostProcessSteps(postProcessSteps | aiProcess_OptimizeGraph);
1452 postProcessSteps = aiPostProcessSteps(postProcessSteps | aiProcess_DropNormals);
1454 aiComponent removeComponents = aiComponent(0);
1457 removeComponents = aiComponent(removeComponents | aiComponent_NORMALS);
1460 removeComponents = aiComponent(removeComponents | aiComponent_TANGENTS_AND_BITANGENTS);
1463 removeComponents = aiComponent(removeComponents | aiComponent_COLORS);
1466 removeComponents = aiComponent(removeComponents | aiComponent_TEXCOORDS);
1469 removeComponents = aiComponent(removeComponents | aiComponent_BONEWEIGHTS);
1472 removeComponents = aiComponent(removeComponents | aiComponent_ANIMATIONS);
1475 removeComponents = aiComponent(removeComponents | aiComponent_TEXTURES);
1477 if (removeComponents != aiComponent(0)) {
1478 postProcessSteps = aiPostProcessSteps(postProcessSteps | aiProcess_RemoveComponent);
1479 importer->SetPropertyInteger(AI_CONFIG_PP_RVC_FLAGS, removeComponents);
1483 importer->SetPropertyBool(AI_CONFIG_IMPORT_FBX_PRESERVE_PIVOTS, preservePivots);
1485 return postProcessSteps;
1497 options =
it->toObject();
1500 return sceneOptions;
1522 if (recalculateLODNormals) {
1532 return sceneOptions;
1544 if (!sourceFile.exists())
1546 targetScene.
sourceDir = sourceFile.path();
1548 std::unique_ptr<Assimp::Importer> importer(
new Assimp::Importer());
1551 aiPostProcessSteps postProcessSteps;
1558 importer->SetPropertyInteger(AI_CONFIG_PP_SBP_REMOVE, aiPrimitiveType_POINT | aiPrimitiveType_LINE);
1559 importer->SetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_USE_COLLADA_NAMES, 1);
1561 auto sourceScene = importer->ReadFile(filePath.toStdString(), postProcessSteps);
1570 targetScene.
id = sourceFile.canonicalFilePath();
1573 using It =
decltype(sourceScene->mNumMeshes);
1577 const auto &srcRootNode = *sourceScene->mRootNode;
1583 if (sourceScene->HasLights()) {
1584 for (It
i = 0,
end = sourceScene->mNumLights;
i !=
end; ++
i) {
1585 const auto &
type = *sourceScene->mLights[
i];
1586 if (
auto node = srcRootNode.FindNode(
type.mName))
1587 nodeMap[node] = {
i, NodeInfo::Type::Light };
1591 if (sourceScene->HasCameras()) {
1592 for (It
i = 0,
end = sourceScene->mNumCameras;
i !=
end; ++
i) {
1593 const auto &srcCam = *sourceScene->mCameras[
i];
1594 if (
auto node = srcRootNode.FindNode(srcCam.mName))
1595 nodeMap[node] = {
i, NodeInfo::Type::Camera };
1599 if (sourceScene->HasAnimations()) {
1600 for (It
i = 0,
end = sourceScene->mNumAnimations;
i !=
end; ++
i) {
1601 const auto &srcAnim = *sourceScene->mAnimations[
i];
1602 const auto channelCount = srcAnim.mNumChannels;
1603 for (It cIdx = 0; cIdx != channelCount; ++cIdx) {
1604 const auto &srcChannel = srcAnim.mChannels[cIdx];
1605 const auto &nodeName = srcChannel->mNodeName;
1606 if (nodeName.length > 0) {
1613 const auto morphChannelCount = srcAnim.mNumMorphMeshChannels;
1614 for (It cIdx = 0; cIdx != morphChannelCount; ++cIdx) {
1615 const auto &srcChannel = srcAnim.mMorphMeshChannels[cIdx];
1616 const auto &nodeName = srcChannel->mName;
1617 if (nodeName.length > 0) {
1618 const auto morphKeys = srcChannel->mKeys;
1619 const auto numMorphTargets =
qMin(morphKeys[0].mNumValuesAndWeights, 8U);
1621 for (It
j = 0;
j < numMorphTargets; ++
j) {
1622 QString morphTargetName(nodeName.C_Str());
1624 animatingNodes.
insert(morphTargetName.
toUtf8(),
nullptr);
1633 const auto materialCount = sourceScene->mNumMaterials;
1635 materials.
reserve(materialCount);
1637 const auto meshCount = sourceScene->mNumMeshes;
1643 const auto embeddedTextureCount = sourceScene->mNumTextures;
1648 for (It
i = 0;
i != materialCount; ++
i)
1649 materials.
push_back({sourceScene->mMaterials[i], nullptr});
1651 for (It
i = 0;
i != meshCount; ++
i) {
1652 meshes.
push_back({sourceScene->mMeshes[
i],
nullptr});
1653 if (sourceScene->mMeshes[
i]->HasBones()) {
1655 const auto boneCount = sourceScene->mMeshes[
i]->mNumBones;
1656 auto bones = sourceScene->mMeshes[
i]->mBones;
1662 for (It
j = 0;
j != boneCount; ++
j) {
1663 const auto &nodeName = bones[
j]->mName;
1664 if (nodeName.length > 0) {
1675 for (It
i = 0;
i != embeddedTextureCount; ++
i)
1680 if (!targetScene.
root) {
1681 auto root =
new QSSGSceneDesc::Node(QSSGSceneDesc::Node::Type::Transform, QSSGSceneDesc::Node::RuntimeType::Node);
1688 const auto extension = sourceFile.suffix().toLower();
1690 SceneInfo sceneInfo { *sourceScene, materials, meshes, embeddedTextures,
1691 textureMap, skins, mesh2skin, sourceFile.dir(),
opt };
1694 const auto gscale =
opt.globalScaleValue;
1699 if (sourceScene->mRootNode)
1700 processNode(sceneInfo, *sourceScene->mRootNode, *targetScene.
root, nodeMap, animatingNodes);
1702 for (It
i = 0, endI = skins.
size();
i != endI; ++
i) {
1703 const auto &skin = skins[
i];
1711 joints.
reserve(skin.mNumBones);
1712 for (It
j = 0, endJ = skin.mNumBones;
j != endJ; ++
j) {
1713 const auto &bone = *skin.mBones[
j];
1714 const auto &nodeName = bone.mName;
1715 if (nodeName.length > 0) {
1718 const auto &osMat = bone.mOffsetMatrix;
1719 auto pose =
QMatrix4x4(osMat[0][0], osMat[0][1], osMat[0][2], osMat[0][3],
1720 osMat[1][0], osMat[1][1], osMat[1][2], osMat[1][3],
1721 osMat[2][0], osMat[2][1], osMat[2][2], osMat[2][3],
1722 osMat[3][0], osMat[3][1], osMat[3][2], osMat[3][3]);
1730 static const auto fuzzyComparePos = [](
const aiVectorKey *
pos,
const aiVectorKey *prev){
1738 static const auto fuzzyCompareRot = [](
const aiQuatKey *rot,
const aiQuatKey *prev){
1750 auto &channels = targetAnimation.
channels;
1752 : 1000.0 / srcAnim.mTicksPerSecond;
1756 for (It
i = 0,
end = srcAnim.mNumChannels;
i !=
end; ++
i) {
1757 const auto &srcChannel = *srcAnim.mChannels[
i];
1759 const auto &nodeName = srcChannel.mNodeName;
1760 if (nodeName.length > 0) {
1761 const auto aNodeEnd = animatingNodes.
cend();
1763 if (aNodeIt != aNodeEnd && aNodeIt.value() !=
nullptr) {
1764 auto targetNode = aNodeIt.
value();
1767 const auto currentPropertyValue = [targetNode](
const char *propertyName) ->
QVariant {
1768 for (
auto *
p : targetNode->properties) {
1769 if (!
qstrcmp(propertyName,
p->name))
1776 const auto posKeyEnd = srcChannel.mNumPositionKeys;
1778 targetChannel.
targetProperty = Animation::Channel::TargetProperty::Position;
1779 targetChannel.
target = targetNode;
1780 const aiVectorKey *prevPos =
nullptr;
1781 for (It posKeyIdx = 0; posKeyIdx != posKeyEnd; ++posKeyIdx) {
1782 const auto &posKey = srcChannel.mPositionKeys[posKeyIdx];
1783 if (fuzzyComparePos(&posKey, prevPos))
1789 const auto isUnchanged = [&targetChannel, currentPropertyValue]() {
1792 auto currentPos = currentPropertyValue(
"position").value<
QVector3D>();
1796 if (!isUnchanged()) {
1798 float endTime = float(srcChannel.mPositionKeys[posKeyEnd - 1].mTime) * freq;
1799 if (targetAnimation.
length < endTime)
1800 targetAnimation.
length = endTime;
1809 const auto rotKeyEnd = srcChannel.mNumRotationKeys;
1811 targetChannel.
targetProperty = Animation::Channel::TargetProperty::Rotation;
1812 targetChannel.
target = targetNode;
1813 const aiQuatKey *prevRot =
nullptr;
1814 for (It rotKeyIdx = 0; rotKeyIdx != rotKeyEnd; ++rotKeyIdx) {
1815 const auto &rotKey = srcChannel.mRotationKeys[rotKeyIdx];
1816 if (fuzzyCompareRot(&rotKey, prevRot))
1822 const auto isUnchanged = [&targetChannel, currentPropertyValue]() {
1825 auto currentVal = currentPropertyValue(
"rotation");
1830 if (!isUnchanged()) {
1832 float endTime = float(srcChannel.mRotationKeys[rotKeyEnd - 1].mTime) * freq;
1833 if (targetAnimation.
length < endTime)
1834 targetAnimation.
length = endTime;
1843 const auto scaleKeyEnd = srcChannel.mNumScalingKeys;
1845 targetChannel.
targetProperty = Animation::Channel::TargetProperty::Scale;
1846 targetChannel.
target = targetNode;
1847 const aiVectorKey *prevScale =
nullptr;
1848 for (It scaleKeyIdx = 0; scaleKeyIdx != scaleKeyEnd; ++scaleKeyIdx) {
1849 const auto &scaleKey = srcChannel.mScalingKeys[scaleKeyIdx];
1850 if (fuzzyComparePos(&scaleKey, prevScale))
1853 prevScale = &scaleKey;
1856 const auto isUnchanged = [&targetChannel, currentPropertyValue]() {
1859 auto currentVal = currentPropertyValue(
"scale");
1865 if (!isUnchanged()) {
1867 float endTime = float(srcChannel.mScalingKeys[scaleKeyEnd - 1].mTime) * freq;
1868 if (targetAnimation.
length < endTime)
1869 targetAnimation.
length = endTime;
1880 for (It
i = 0,
end = srcAnim.mNumMorphMeshChannels;
i !=
end; ++
i) {
1881 const auto &srcMorphChannel = *srcAnim.mMorphMeshChannels[
i];
1882 const QString nodeName(srcMorphChannel.mName.C_Str());
1883 const auto *morphKeys = srcMorphChannel.mKeys;
1884 const auto numMorphTargets =
qMin(morphKeys[0].mNumValuesAndWeights, 8U);
1885 for (It targetId = 0; targetId != numMorphTargets; ++targetId) {
1887 const auto aNodeEnd = animatingNodes.
cend();
1888 const auto aNodeIt = animatingNodes.
constFind(morphTargetName.
toUtf8());
1889 if (aNodeIt != aNodeEnd && aNodeIt.value() !=
nullptr) {
1890 auto targetNode = aNodeIt.
value();
1891 const auto weightKeyEnd = srcMorphChannel.mNumKeys;
1893 targetChannel.
targetProperty = Animation::Channel::TargetProperty::Weight;
1894 targetChannel.
target = targetNode;
1895 for (It wId = 0; wId != weightKeyEnd; ++wId) {
1896 const auto &weightKey = srcMorphChannel.mKeys[wId];
1902 float endTime = float(srcMorphChannel.mKeys[weightKeyEnd - 1].mTime) * freq;
1903 if (targetAnimation.
length < endTime)
1904 targetAnimation.
length = endTime;
1916 if (sourceScene->HasAnimations()) {
1917 const auto animationCount = sourceScene->mNumAnimations;
1919 for (It
i = 0,
end = animationCount;
i !=
end; ++
i) {
1920 const auto &srcAnim = *sourceScene->mAnimations[
i];
1921 createAnimation(targetScene, srcAnim, animatingNodes);
1963 QFile targetFile(targetFileName);
1965 errorString +=
QString(
"Could not write to file: ") + targetFileName;
1970 generatedFiles->append(targetFileName);
#define AI_GLTF_FILTER_NEAREST_MIPMAP_NEAREST
QPair< MorphAttributes, float > MorphProperty
static Q_REQUIRED_RESULT QColor aiColorToQColor(const aiColor3D &color)
#define AI_GLTF_FILTER_NEAREST
#define AI_GLTF_FILTER_NEAREST_MIPMAP_LINEAR
static QSSGSceneDesc::Animation::KeyPosition toAnimationKey(const aiVectorKey &key, qreal freq)
static void processNode(const SceneInfo &sceneInfo, const aiNode &source, QSSGSceneDesc::Node &parent, const NodeMap &nodeMap, AnimationNodeMap &animationNodes)
static qreal getRealOption(const QString &optionName, const QJsonObject &options)
#define AI_GLTF_FILTER_LINEAR_MIPMAP_LINEAR
static QByteArray fromAiString(const aiString &string)
static void setModelProperties(QSSGSceneDesc::Model &target, const aiNode &source, const SceneInfo &sceneInfo)
static void setLightProperties(QSSGSceneDesc::Light &target, const aiLight &source, const aiNode &sourceNode, const SceneInfo &sceneInfo)
static void setMaterialProperties(QSSGSceneDesc::Material &target, const aiMaterial &source, const SceneInfo &sceneInfo, QSSGSceneDesc::Material::RuntimeType type)
static QVector< MorphProperty > getMorphTargetProperties(const aiMesh &mesh)
bool operator==(const TextureInfo &a, const TextureInfo &b)
static bool isEqual(const aiUVTransform &a, const aiUVTransform &b)
QQuick3DMorphTarget::MorphTargetAttributes MorphAttributes
#define AI_GLTF_FILTER_LINEAR
static aiPostProcessSteps processOptions(const QJsonObject &optionsObject, std::unique_ptr< Assimp::Importer > &importer)
static void setNodeProperties(QSSGSceneDesc::Node &target, const aiNode &source, const SceneInfo &sceneInfo, aiMatrix4x4 *transformCorrection)
static QString importImp(const QUrl &url, const QJsonObject &options, QSSGSceneDesc::Scene &targetScene)
static void setTextureProperties(QSSGSceneDesc::Texture &target, const TextureInfo &texInfo, const SceneInfo &sceneInfo)
size_t qHash(const TextureEntry &key, size_t seed)
static QSSGSceneDesc::Node * createSceneNode(const NodeInfo &nodeInfo, const aiNode &srcNode, QSSGSceneDesc::Node &parent, const SceneInfo &sceneInfo)
#define demonPostProcessPresets
static SceneInfo::Options processSceneOptions(const QJsonObject &optionsObject)
static void setCameraProperties(QSSGSceneDesc::Camera &target, const aiCamera &source, const aiNode &sourceNode, const SceneInfo &sceneInfo)
static bool checkBooleanOption(const QString &optionName, const QJsonObject &options)
#define AI_GLTF_FILTER_LINEAR_MIPMAP_NEAREST
QString import(const QString &sourceFile, const QDir &savePath, const QJsonObject &options, QStringList *generatedFiles) override
qsizetype length() const noexcept
Same as size().
The QColor class provides colors based on RGB, HSV or CMYK values.
static QColor fromRgbF(float r, float g, float b, float a=1.0)
Static convenience function that returns a QColor constructed from the RGB color values,...
static QChar separator()
Returns the native directory separator: "/" under Unix and "\\" under Windows.
QString absolutePath() const
Returns the absolute path (a path that starts with "/" or with a drive specification),...
QString absoluteFilePath(const QString &fileName) const
Returns the absolute path name of a file in the directory.
\inmodule QtCore \reentrant
QString completeBaseName() const
Returns the complete base name of the file without the path.
bool exists() const
Returns true if the file exists; otherwise returns false.
bool open(OpenMode flags) override
Opens the file using OpenMode mode, returning true if successful; otherwise false.
const T & value() const noexcept
Returns the current item's value.
T & value() const noexcept
Returns a modifiable reference to the current item's value.
const_iterator constFind(const Key &key) const noexcept
const_iterator constEnd() const noexcept
Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item after the ...
iterator find(const Key &key)
Returns an iterator pointing to the item with the key in the hash.
bool contains(const Key &key) const noexcept
Returns true if the hash contains an item with the key; otherwise returns false.
T value(const Key &key) const noexcept
iterator end() noexcept
Returns an \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item after the last ...
const_iterator cend() const noexcept
bool isEmpty() const noexcept
Returns true if the hash contains no items; otherwise returns false.
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
\inmodule QtCore\reentrant
const_iterator constFind(const QString &key) const
Returns a const iterator pointing to the item with key key in the map.
const_iterator constEnd() const
Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item after the ...
bool isEmpty() const
Returns true if the object is empty.
\inmodule QtCore\reentrant
qsizetype size() const noexcept
bool isEmpty() const noexcept
void push_back(parameter_type t)
const_reference at(qsizetype i) const noexcept
T value(qsizetype i) const
qsizetype count() const noexcept
void reserve(qsizetype size)
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
The QQuaternion class represents a quaternion consisting of a vector and scalar.
void setBrightness(float brightness)
void setColor(const QColor &color)
void setAmbientColor(const QColor &ambientColor)
void setLighting(QQuick3DDefaultMaterial::Lighting lighting)
void setBumpMap(QQuick3DTexture *bumpMap)
void setEmissiveMap(QQuick3DTexture *emissiveMap)
void setBumpAmount(float bumpAmount)
void setOpacityMap(QQuick3DTexture *opacityMap)
void setNormalMap(QQuick3DTexture *normalMap)
void setOpacity(float opacity)
void setDiffuseMap(QQuick3DTexture *diffuseMap)
void setSpecularMap(QQuick3DTexture *specularMap)
void setDiffuseColor(QColor diffuseColor)
void setIndex(qint32 index)
void setCullMode(QQuick3DMaterial::CullMode cullMode)
QQmlListProperty< QQuick3DMaterial > materials
\qmlproperty List<QtQuick3D::Material> Model::materials
QQmlListProperty< QQuick3DMorphTarget > morphTargets
\qmlproperty List<QtQuick3D::MorphTarget> Model::morphTargets
void setSource(const QUrl &source)
void setAttributes(QQuick3DMorphTarget::MorphTargetAttributes attributes)
void setWeight(float castsShadows)
void setRotation(const QQuaternion &rotation)
void setScale(const QVector3D &scale)
void setPosition(const QVector3D &position)
void setClipFar(float clipFar)
void setClipNear(float clipNear)
void setVerticalMagnification(float horizontalMagnification)
void setHorizontalMagnification(float horizontalMagnification)
void setClipFar(float clipFar)
void setFieldOfViewOrientation(QQuick3DPerspectiveCamera::FieldOfViewOrientation fieldOfViewOrientation)
void setFieldOfView(float fieldOfView)
void setClipNear(float clipNear)
void setConstantFade(float constantFade)
void setQuadraticFade(float quadraticFade)
void setLinearFade(float linearFade)
void setOcclusionMap(QQuick3DTexture *occlusionMap)
void setLighting(QQuick3DPrincipledMaterial::Lighting lighting)
void setBaseColorMap(QQuick3DTexture *baseColorMap)
void setMetalnessMap(QQuick3DTexture *metalnessMap)
void setNormalStrength(float normalStrength)
void setMetalnessChannel(QQuick3DMaterial::TextureChannelMapping channel)
void setEmissiveMap(QQuick3DTexture *emissiveMap)
void setRoughnessChannel(QQuick3DMaterial::TextureChannelMapping channel)
void setAlphaMode(QQuick3DPrincipledMaterial::AlphaMode alphaMode)
void setOcclusionChannel(QQuick3DMaterial::TextureChannelMapping channel)
void setAlphaCutoff(float alphaCutoff)
void setRoughnessMap(QQuick3DTexture *roughnessMap)
void setNormalMap(QQuick3DTexture *normalMap)
void setEmissiveFactor(QVector3D emissiveFactor)
void setRoughness(float roughness)
void setOcclusionAmount(float occlusionAmount)
void setOpacityChannel(QQuick3DMaterial::TextureChannelMapping channel)
void setBaseColor(QColor baseColor)
void setMetalness(float metalnessAmount)
void setInverseBindPoses(const QList< QMatrix4x4 > &poses)
QQmlListProperty< QQuick3DNode > joints
\qmlproperty List<QtQuick3D::Node> Skin::joints
void setEmissiveFactor(const QVector3D &emissiveFactor)
void setAlphaMode(QQuick3DSpecularGlossyMaterial::AlphaMode alphaMode)
void setClearcoatMap(QQuick3DTexture *newClearcoatMap)
void setOcclusionMap(QQuick3DTexture *occlusionMap)
void setClearcoatAmount(float newClearcoatAmount)
void setSpecularColor(const QColor &specular)
void setNormalMap(QQuick3DTexture *normalMap)
void setAlbedoColor(const QColor &albedo)
void setGlossiness(float glossiness)
void setOpacityChannel(QQuick3DMaterial::TextureChannelMapping channel)
void setGlossinessMap(QQuick3DTexture *glossinessMap)
void setTransmissionMap(QQuick3DTexture *newTransmissionMap)
void setEmissiveMap(QQuick3DTexture *emissiveMap)
void setAlphaCutoff(float alphaCutoff)
void setThicknessMap(QQuick3DTexture *newThicknessMap)
void setThicknessFactor(float newThicknessFactor)
void setNormalStrength(float normalStrength)
void setOcclusionChannel(QQuick3DMaterial::TextureChannelMapping channel)
void setAttenuationColor(const QColor &newAttenuationColor)
void setClearcoatRoughnessMap(QQuick3DTexture *newClearcoatRoughnessMap)
void setOcclusionAmount(float occlusionAmount)
void setGlossinessChannel(QQuick3DMaterial::TextureChannelMapping channel)
void setAlbedoMap(QQuick3DTexture *albedoMap)
void setTransmissionFactor(float newTransmissionFactor)
void setSpecularMap(QQuick3DTexture *specularMap)
void setAttenuationDistance(float newAttenuationDistance)
void setClearcoatRoughnessAmount(float newClearcoatRoughnessAmount)
void setLighting(QQuick3DSpecularGlossyMaterial::Lighting lighting)
void setClearcoatNormalMap(QQuick3DTexture *newClearcoatNormalMap)
void setConstantFade(float constantFade)
void setInnerConeAngle(float innerConeAngle)
void setConeAngle(float coneAngle)
void setLinearFade(float linearFade)
void setQuadraticFade(float quadraticFade)
void setPivotV(float pivotV)
void setScaleV(float scaleV)
void setHorizontalTiling(QQuick3DTexture::TilingMode tilingModeHorizontal)
void setRotationUV(float rotationUV)
void setTextureData(QQuick3DTextureData *textureData)
void setMipFilter(QQuick3DTexture::Filter mipFilter)
void setVerticalTiling(QQuick3DTexture::TilingMode tilingModeVertical)
void setGenerateMipmaps(bool generateMipmaps)
void setIndexUV(int indexUV)
void setPositionU(float positionU)
void setPositionV(float positionV)
void setSource(const QUrl &source)
void setMagFilter(QQuick3DTexture::Filter magFilter)
void setMappingMode(QQuick3DTexture::MappingMode mappingMode)
void setMinFilter(QQuick3DTexture::Filter minFilter)
void setScaleU(float scaleU)
const_iterator cend() const noexcept
const_iterator constFind(const T &value) const
\macro QT_RESTRICTED_CAST_FROM_ASCII
static QString fromLocal8Bit(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QString first(qsizetype n) const
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QByteArray toUtf8() const &
static QUrl fromLocalFile(const QString &localfile)
Returns a QUrl representation of localFile, interpreted as a local file.
QString scheme() const
Returns the scheme of the URL.
QString toLocalFile() const
Returns the path of this URL formatted as a local file path.
QString path(ComponentFormattingOptions options=FullyDecoded) const
Returns the path of the URL.
constexpr size_type size() const noexcept
void push_back(const T &t)
void reserve(qsizetype sz)
static auto fromValue(T &&value) noexcept(std::is_nothrow_copy_constructible_v< T > &&Private::CanUseInternalSpace< T >) -> std::enable_if_t< std::conjunction_v< std::is_copy_constructible< T >, std::is_destructible< T > >, QVariant >
The QVector3D class represents a vector or vertex in 3D space.
constexpr float x() const noexcept
Returns the x coordinate of this point.
The QVector4D class represents a vector or vertex in 4D space.
constexpr float x() const noexcept
Returns the x coordinate of this point.
object setProperty("down", true)
qDeleteAll(list.begin(), list.end())
QSet< QString >::iterator it
QSSGMesh::Mesh generateMeshData(const aiScene &scene, const MeshList &meshes, bool useFloatJointIndices, bool generateLevelsOfDetail, float normalMergeAngle, float normalSplitAngle, QString &errorString)
void applyEdit(QSSGSceneDesc::Scene *scene, const QJsonObject &changes)
static void writeQml(const QSSGSceneDesc::Node &transform, OutputContext &output)
QString qmlComponentName(const QString &name)
static void setProperty(QSSGSceneDesc::Node &node, const char *name, Setter setter, T &&value)
Q_QUICK3DASSETUTILS_EXPORT void addNode(Node &parent, Node &node)
Combined button and popup list for selecting options.
#define QByteArrayLiteral(str)
Q_CORE_EXPORT int qstrcmp(const char *str1, const char *str2)
#define Q_REQUIRED_RESULT
std::pair< T1, T2 > QPair
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
bool qFuzzyIsNull(qfloat16 f) noexcept
size_t qHashBits(const void *p, size_t size, size_t seed) noexcept
constexpr float qRadiansToDegrees(float radians)
constexpr const T & qMin(const T &a, const T &b)
constexpr const T & qBound(const T &min, const T &val, const T &max)
constexpr const T & qMax(const T &a, const T &b)
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
GLint GLsizei GLsizei height
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLuint GLenum GLsizei length
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLint GLsizei GLsizei GLenum format
GLsizei GLsizei GLchar * source
GLuint GLenum GLenum transform
GLsizei const GLchar *const * path
GLenum GLenum GLenum GLenum mapping
GLenum GLenum GLenum GLenum GLenum scale
constexpr decltype(auto) qMakePair(T1 &&value1, T2 &&value2) noexcept(noexcept(std::make_pair(std::forward< T1 >(value1), std::forward< T2 >(value2))))
static Q_CONSTINIT QBasicAtomicInteger< unsigned > seed
QLatin1StringView QLatin1String
#define QStringLiteral(str)
#define Q_DECLARE_TYPEINFO(TYPE, FLAGS)
QT_BEGIN_NAMESPACE typedef uchar * output
QUrl url("example.com")
[constructor-url-reference]
TargetProperty targetProperty
bool forceMipMapGeneration
bool designStudioWorkarounds
int lightmapBaseResolution
bool useFloatJointIndices
float lodNormalSplitAngle
float lodNormalMergeAngle
QSSGSceneDesc::Skin * node
EmbeddedTextureMap & embeddedTextureMap
MaterialMap & materialMap
aiTextureMapMode modes[3]
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent