12#include <QtQuick3DRuntimeRender/private/qssgrendergraphobject_p.h>
13#include <QtQuick3DRuntimeRender/private/qssgrendercustommaterial_p.h>
14#include <QtQuick3DRuntimeRender/private/qssgrenderdefaultmaterial_p.h>
15#include <QtQuick3DRuntimeRender/private/qssgrendermodel_p.h>
17#include <QtQuick3DUtils/private/qssgutils_p.h>
19#include <QtQml/QQmlFile>
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
119
120
121
122
123
124
125
126
129
130
131
132
133
136
137
138
139
140
142QQuick3DModel::QQuick3DModel(QQuick3DNode *parent)
143 : QQuick3DNode(*(
new QQuick3DNodePrivate(QQuick3DNodePrivate::Type::Model)), parent) {}
145QQuick3DModel::~QQuick3DModel()
147 disconnect(m_geometryConnection);
149 auto matList = materials();
150 qmlClearMaterials(&matList);
151 auto morphList = morphTargets();
152 qmlClearMorphTargets(&morphList);
156
157
158
159
160
161
162
163
164
165
166
167
168
169
171QUrl QQuick3DModel::source()
const
177
178
179
180
181
182
183
184
185
188QQmlListProperty<QQuick3DMaterial> QQuick3DModel::materials()
190 return QQmlListProperty<QQuick3DMaterial>(
this,
192 QQuick3DModel::qmlAppendMaterial,
193 QQuick3DModel::qmlMaterialsCount,
194 QQuick3DModel::qmlMaterialAt,
195 QQuick3DModel::qmlClearMaterials);
199
200
201
202
203
204
205
206
207
209QQmlListProperty<QQuick3DMorphTarget> QQuick3DModel::morphTargets()
211 return QQmlListProperty<QQuick3DMorphTarget>(
this,
213 QQuick3DModel::qmlAppendMorphTarget,
214 QQuick3DModel::qmlMorphTargetsCount,
215 QQuick3DModel::qmlMorphTargetAt,
216 QQuick3DModel::qmlClearMorphTargets);
220
221
222
223
224
225
226
228QQuick3DInstancing *QQuick3DModel::instancing()
const
234
235
236
237
238
239
240
241
242QQuick3DNode *QQuick3DModel::instanceRoot()
const
244 return m_instanceRoot;
251QString QQuick3DModel::translateMeshSource(
const QUrl &source, QObject *contextObject)
254 if (source.hasFragment()) {
256 bool isNumber =
false;
257 source.fragment().toInt(&isNumber);
258 fragment = QStringLiteral(
"#") + source.fragment();
264 const QQmlContext *context = qmlContext(contextObject);
265 const auto resolvedUrl = context ? context->resolvedUrl(source) : source;
266 const auto qmlSource = QQmlFile::urlToLocalFileOrQrc(resolvedUrl);
267 return (qmlSource.isEmpty() ? source.path() : qmlSource) + fragment;
270void QQuick3DModel::markAllDirty()
272 m_dirtyAttributes = 0xffffffff;
273 QQuick3DNode::markAllDirty();
277
278
279
280
281
282
283
284
286bool QQuick3DModel::castsShadows()
const
288 return m_castsShadows;
292
293
294
295
296
297
298
299
300
301
302
304bool QQuick3DModel::receivesShadows()
const
306 return m_receivesShadows;
310
311
312
313
314
315
316
317bool QQuick3DModel::pickable()
const
323
324
325
326
327
328
329QQuick3DGeometry *QQuick3DModel::geometry()
const
335
336
337
338
339
340
341
342
343
344
345
346
347QQuick3DSkeleton *QQuick3DModel::skeleton()
const
353
354
355
356
357
358
359
360
361
362
363
364
365
366QQuick3DSkin *QQuick3DModel::skin()
const
373
374
375
376
377
378
379
380
381
382
383
384
385QList<QMatrix4x4> QQuick3DModel::inverseBindPoses()
const
387 return m_inverseBindPoses;
391
392
393
394
395
396
397
398
399QQuick3DBounds3 QQuick3DModel::bounds()
const
405
406
407
408
409
410
411
412float QQuick3DModel::depthBias()
const
418
419
420
421
422
423
425bool QQuick3DModel::receivesReflections()
const
427 return m_receivesReflections;
431
432
433
434
435
436
437bool QQuick3DModel::castsReflections()
const
439 return m_castsReflections;
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
469bool QQuick3DModel::isUsedInBakedLighting()
const
471 return m_usedInBakedLighting;
475
476
477
478
479int QQuick3DModel::lightmapBaseResolution()
const
481 return m_lightmapBaseResolution;
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
512QQuick3DBakedLightmap *QQuick3DModel::bakedLightmap()
const
514 return m_bakedLightmap;
518
519
520
521
522
523float QQuick3DModel::instancingLodMin()
const
525 return m_instancingLodMin;
529
530
531
532
533
534float QQuick3DModel::instancingLodMax()
const
536 return m_instancingLodMax;
539void QQuick3DModel::setSource(
const QUrl &source)
541 if (m_source == source)
545 emit sourceChanged();
546 markDirty(SourceDirty);
547 if (QQuick3DObjectPrivate::get(
this)->sceneManager)
548 QQuick3DObjectPrivate::get(
this)->sceneManager->dirtyBoundingBoxList.append(
this);
551void QQuick3DModel::setCastsShadows(
bool castsShadows)
553 if (m_castsShadows == castsShadows)
556 m_castsShadows = castsShadows;
557 emit castsShadowsChanged();
558 markDirty(ShadowsDirty);
561void QQuick3DModel::setReceivesShadows(
bool receivesShadows)
563 if (m_receivesShadows == receivesShadows)
566 m_receivesShadows = receivesShadows;
567 emit receivesShadowsChanged();
568 markDirty(ShadowsDirty);
571void QQuick3DModel::setPickable(
bool isPickable)
573 if (m_pickable == isPickable)
576 m_pickable = isPickable;
577 emit pickableChanged();
578 markDirty(PickingDirty);
581void QQuick3DModel::setGeometry(QQuick3DGeometry *geometry)
583 if (geometry == m_geometry)
587 QQuick3DObjectPrivate::attachWatcher(
this, &QQuick3DModel::setGeometry, geometry, m_geometry);
590 QObject::disconnect(m_geometryConnection);
591 m_geometry = geometry;
595 = QObject::connect(m_geometry, &QQuick3DGeometry::geometryNodeDirty,
this, [
this]() {
596 markDirty(GeometryDirty);
599 emit geometryChanged();
600 markDirty(GeometryDirty);
603void QQuick3DModel::setSkeleton(QQuick3DSkeleton *skeleton)
605 if (skeleton == m_skeleton)
609 QQuick3DObjectPrivate::attachWatcher(
this, &QQuick3DModel::setSkeleton, skeleton, m_skeleton);
611 m_skeleton = skeleton;
613 emit skeletonChanged();
614 markDirty(SkeletonDirty);
617void QQuick3DModel::setSkin(QQuick3DSkin *skin)
623 QQuick3DObjectPrivate::attachWatcher(
this, &QQuick3DModel::setSkin, skin, m_skin);
627 markDirty(SkinDirty);
630void QQuick3DModel::setInverseBindPoses(
const QList<QMatrix4x4> &poses)
632 if (m_inverseBindPoses == poses)
635 m_inverseBindPoses = poses;
636 emit inverseBindPosesChanged();
637 markDirty(PoseDirty);
641void QQuick3DModel::setBounds(
const QVector3D &min,
const QVector3D &max)
643 if (!qFuzzyCompare(m_bounds.maximum(), max)
644 || !qFuzzyCompare(m_bounds.minimum(), min)) {
645 m_bounds.bounds = QSSGBounds3 { min, max };
646 emit boundsChanged();
650void QQuick3DModel::setInstancing(QQuick3DInstancing *instancing)
652 if (m_instancing == instancing)
656 QQuick3DObjectPrivate::attachWatcher(
this, &QQuick3DModel::setInstancing, instancing, m_instancing);
658 QObject::disconnect(m_instancingConnection);
659 m_instancing = instancing;
661 m_instancingConnection = QObject::connect
662 (m_instancing, &QQuick3DInstancing::instanceNodeDirty,
663 this, [
this]{ markDirty(InstancesDirty);});
665 markDirty(InstancesDirty);
666 emit instancingChanged();
669void QQuick3DModel::setInstanceRoot(QQuick3DNode *instanceRoot)
671 if (m_instanceRoot == instanceRoot)
674 QQuick3DObjectPrivate::attachWatcher(
this, &QQuick3DModel::setInstanceRoot, instanceRoot, m_instanceRoot);
676 m_instanceRoot = instanceRoot;
677 markDirty(InstanceRootDirty);
678 emit instanceRootChanged();
681void QQuick3DModel::setDepthBias(
float bias)
683 if (qFuzzyCompare(bias, m_depthBias))
687 markDirty(PropertyDirty);
688 emit depthBiasChanged();
691void QQuick3DModel::setReceivesReflections(
bool receivesReflections)
693 if (m_receivesReflections == receivesReflections)
696 m_receivesReflections = receivesReflections;
697 emit receivesReflectionsChanged();
698 markDirty(ReflectionDirty);
701void QQuick3DModel::setCastsReflections(
bool castsReflections)
703 if (m_castsReflections == castsReflections)
705 m_castsReflections = castsReflections;
706 emit castsReflectionsChanged();
707 markDirty(ReflectionDirty);
710void QQuick3DModel::setUsedInBakedLighting(
bool enable)
712 if (m_usedInBakedLighting == enable)
715 m_usedInBakedLighting = enable;
716 emit usedInBakedLightingChanged();
717 markDirty(PropertyDirty);
720void QQuick3DModel::setLightmapBaseResolution(
int resolution)
722 resolution = qMax(128, resolution);
723 if (m_lightmapBaseResolution == resolution)
726 qWarning() <<
"Model::lightmapBaseResolution is deprecated and will have no effect.";
728 m_lightmapBaseResolution = resolution;
729 emit lightmapBaseResolutionChanged();
730 markDirty(PropertyDirty);
733void QQuick3DModel::setBakedLightmap(QQuick3DBakedLightmap *bakedLightmap)
735 if (m_bakedLightmap == bakedLightmap)
739 m_bakedLightmap->disconnect(m_bakedLightmapSignalConnection);
741 m_bakedLightmap = bakedLightmap;
743 m_bakedLightmapSignalConnection = QObject::connect(m_bakedLightmap, &QQuick3DBakedLightmap::changed,
this,
744 [
this] { markDirty(PropertyDirty); });
746 QObject::connect(m_bakedLightmap, &QObject::destroyed,
this,
749 m_bakedLightmap =
nullptr;
750 markDirty(PropertyDirty);
753 emit bakedLightmapChanged();
754 markDirty(PropertyDirty);
757void QQuick3DModel::itemChange(ItemChange change,
const ItemChangeData &value)
759 if (change == QQuick3DObject::ItemSceneChange)
760 updateSceneManager(value.sceneManager);
763QSSGRenderGraphObject *QQuick3DModel::updateSpatialNode(QSSGRenderGraphObject *node)
767 node =
new QSSGRenderModel();
770 QQuick3DNode::updateSpatialNode(node);
771 int dirtyAttribute = 0;
773 auto modelNode =
static_cast<QSSGRenderModel *>(node);
774 if (m_dirtyAttributes & SourceDirty) {
775 const QString path = translateMeshSource(m_source,
this);
776 const QString lightmapKey = m_bakedLightmap ? m_bakedLightmap->key() : QString();
777 modelNode->meshPath = QSSGRenderPath(path, lightmapKey);
779 if (m_dirtyAttributes & PickingDirty)
780 modelNode->setState(QSSGRenderModel::LocalState::Pickable, m_pickable);
782 if (m_dirtyAttributes & ShadowsDirty) {
783 modelNode->castsShadows = m_castsShadows;
784 modelNode->receivesShadows = m_receivesShadows;
787 if (m_dirtyAttributes & MaterialsDirty) {
788 if (!m_materials.isEmpty()) {
789 if (modelNode->materials.isEmpty()) {
791 for (
const Material &material : m_materials) {
792 QSSGRenderGraphObject *graphObject = QQuick3DObjectPrivate::get(material.material)->spatialNode;
794 modelNode->materials.append(graphObject);
796 dirtyAttribute |= MaterialsDirty;
800 if (modelNode->materials.size() != m_materials.size())
801 modelNode->materials.resize(m_materials.size());
802 for (
int i = 0; i < m_materials.size(); ++i) {
803 QSSGRenderGraphObject *graphObject = QQuick3DObjectPrivate::get(m_materials[i].material)->spatialNode;
804 if (modelNode->materials[i] != graphObject)
805 modelNode->materials[i] = graphObject;
810 modelNode->materials.clear();
814 if (m_dirtyAttributes & MorphTargetsDirty) {
815 if (!m_morphTargets.isEmpty()) {
816 const int numMorphTarget = m_morphTargets.size();
817 if (modelNode->morphTargets.isEmpty()) {
819 for (
const auto morphTarget : std::as_const(m_morphTargets)) {
820 QSSGRenderGraphObject *graphObject = QQuick3DObjectPrivate::get(morphTarget)->spatialNode;
822 modelNode->morphTargets.append(graphObject);
824 dirtyAttribute |= MorphTargetsDirty;
826 modelNode->morphWeights.resize(numMorphTarget);
827 modelNode->morphAttributes.resize(numMorphTarget);
830 if (modelNode->morphTargets.size() != numMorphTarget) {
831 modelNode->morphTargets.resize(numMorphTarget);
832 modelNode->morphWeights.resize(numMorphTarget);
833 modelNode->morphAttributes.resize(numMorphTarget);
835 for (
int i = 0; i < numMorphTarget; ++i)
836 modelNode->morphTargets[i] = QQuick3DObjectPrivate::get(m_morphTargets.at(i))->spatialNode;
840 modelNode->morphTargets.clear();
844 if (m_dirtyAttributes & quint32(InstancesDirty | InstanceRootDirty)) {
847 QSSGRenderNode *instanceRootNode =
nullptr;
848 if (m_instanceRoot) {
849 if (m_instanceRoot ==
this)
850 instanceRootNode = modelNode;
852 instanceRootNode =
static_cast<QSSGRenderNode *>(QQuick3DObjectPrivate::get(m_instanceRoot)->spatialNode);
854 if (instanceRootNode != modelNode->instanceRoot) {
855 modelNode->instanceRoot = instanceRootNode;
856 modelNode->markDirty(QSSGRenderNode::DirtyFlag::TransformDirty);
860 modelNode->instanceTable =
static_cast<QSSGRenderInstanceTable *>(QQuick3DObjectPrivate::get(m_instancing)->spatialNode);
862 modelNode->instanceTable =
nullptr;
866 if (m_dirtyAttributes & GeometryDirty) {
868 modelNode->geometry =
static_cast<QSSGRenderGeometry *>(QQuick3DObjectPrivate::get(m_geometry)->spatialNode);
869 setBounds(m_geometry->boundsMin(), m_geometry->boundsMax());
871 modelNode->geometry =
nullptr;
872 setBounds(QVector3D(), QVector3D());
876 if (m_dirtyAttributes & SkeletonDirty) {
878 modelNode->skeleton =
static_cast<QSSGRenderSkeleton *>(QQuick3DObjectPrivate::get(m_skeleton)->spatialNode);
879 if (modelNode->skeleton)
880 modelNode->skeleton->skinningDirty =
true;
882 modelNode->skeleton =
nullptr;
886 if (m_dirtyAttributes & SkinDirty) {
888 modelNode->skin =
static_cast<QSSGRenderSkin *>(QQuick3DObjectPrivate::get(m_skin)->spatialNode);
890 modelNode->skin =
nullptr;
893 if (m_dirtyAttributes & LodDirty) {
894 modelNode->instancingLodMin = m_instancingLodMin;
895 modelNode->instancingLodMax = m_instancingLodMax;
898 if (m_dirtyAttributes & PoseDirty) {
899 modelNode->inverseBindPoses = m_inverseBindPoses.toVector();
900 if (modelNode->skeleton)
901 modelNode->skeleton->skinningDirty =
true;
904 if (m_dirtyAttributes & PropertyDirty) {
905 modelNode->m_depthBiasSq = QSSGRenderModel::signedSquared(m_depthBias);
906 modelNode->usedInBakedLighting = m_usedInBakedLighting;
907 modelNode->texelsPerUnit = m_texelsPerUnit;
908 if (m_bakedLightmap && m_bakedLightmap->isEnabled()) {
909 modelNode->lightmapKey = m_bakedLightmap->key();
911 modelNode->lightmapKey.clear();
914 const QString path = translateMeshSource(m_source,
this);
915 modelNode->meshPath = QSSGRenderPath(path, modelNode->lightmapKey);
916 modelNode->levelOfDetailBias = m_levelOfDetailBias;
917 modelNode->motionVectorEnabled = m_motionVectorEnabled;
918 modelNode->motionVectorScale = m_motionVectorScale;
921 if (m_dirtyAttributes & ReflectionDirty) {
922 modelNode->receivesReflections = m_receivesReflections;
923 modelNode->castsReflections = m_castsReflections;
926 m_dirtyAttributes = dirtyAttribute;
931void QQuick3DModel::markDirty(QQuick3DModel::QSSGModelDirtyType type)
933 if (InstanceRootDirty & quint32(type))
934 QQuick3DObjectPrivate::get(
this)->dirty(QQuick3DObjectPrivate::InstanceRootChanged);
936 if (!(m_dirtyAttributes & quint32(type))) {
937 m_dirtyAttributes |= quint32(type);
942void QQuick3DModel::updateSceneManager(QQuick3DSceneManager *sceneManager)
945 sceneManager->dirtyBoundingBoxList.append(
this);
946 QQuick3DObjectPrivate::refSceneManager(m_skeleton, *sceneManager);
947 QQuick3DObjectPrivate::refSceneManager(m_skin, *sceneManager);
948 QQuick3DObjectPrivate::refSceneManager(m_geometry, *sceneManager);
949 QQuick3DObjectPrivate::refSceneManager(m_instancing, *sceneManager);
950 for (Material &mat : m_materials) {
951 if (!mat.material->parentItem() && !QQuick3DObjectPrivate::get(mat.material)->sceneManager) {
953 QQuick3DObjectPrivate::refSceneManager(mat.material, *sceneManager);
959 QQuick3DObjectPrivate::derefSceneManager(m_skeleton);
960 QQuick3DObjectPrivate::derefSceneManager(m_skin);
961 QQuick3DObjectPrivate::derefSceneManager(m_geometry);
962 QQuick3DObjectPrivate::derefSceneManager(m_instancing);
963 for (Material &mat : m_materials) {
965 QQuick3DObjectPrivate::derefSceneManager(mat.material);
972void QQuick3DModel::onMaterialDestroyed(QObject *object)
975 for (
int i = 0; i < m_materials.size(); ++i) {
976 if (m_materials[i].material == object) {
977 m_materials.removeAt(i--);
982 markDirty(QQuick3DModel::MaterialsDirty);
985void QQuick3DModel::qmlAppendMaterial(QQmlListProperty<QQuick3DMaterial> *list, QQuick3DMaterial *material)
987 if (material ==
nullptr)
989 QQuick3DModel *self =
static_cast<QQuick3DModel *>(list->object);
990 self->m_materials.push_back({ material,
false });
991 self->markDirty(QQuick3DModel::MaterialsDirty);
993 if (material->parentItem() ==
nullptr) {
996 QQuick3DObject *parentItem = qobject_cast<QQuick3DObject *>(material->parent());
998 material->setParentItem(parentItem);
1000 const auto &sceneManager = QQuick3DObjectPrivate::get(self)->sceneManager;
1002 QQuick3DObjectPrivate::get(material)->refSceneManager(*sceneManager);
1008 self->m_materials.last().refed =
true;
1015 connect(material, &QQuick3DMaterial::destroyed, self, &QQuick3DModel::onMaterialDestroyed);
1018QQuick3DMaterial *QQuick3DModel::qmlMaterialAt(QQmlListProperty<QQuick3DMaterial> *list, qsizetype index)
1020 QQuick3DModel *self =
static_cast<QQuick3DModel *>(list->object);
1021 return self->m_materials.at(index).material;
1024qsizetype QQuick3DModel::qmlMaterialsCount(QQmlListProperty<QQuick3DMaterial> *list)
1026 QQuick3DModel *self =
static_cast<QQuick3DModel *>(list->object);
1027 return self->m_materials.size();
1030void QQuick3DModel::qmlClearMaterials(QQmlListProperty<QQuick3DMaterial> *list)
1032 QQuick3DModel *self =
static_cast<QQuick3DModel *>(list->object);
1033 for (Material &mat : self->m_materials) {
1034 if (mat.material->parentItem() ==
nullptr) {
1036 QQuick3DObjectPrivate::get(mat.material)->derefSceneManager();
1040 disconnect(mat.material, &QQuick3DMaterial::destroyed, self, &QQuick3DModel::onMaterialDestroyed);
1042 self->m_materials.clear();
1043 self->markDirty(QQuick3DModel::MaterialsDirty);
1046void QQuick3DModel::onMorphTargetDestroyed(QObject *object)
1049 for (
int i = 0; i < m_morphTargets.size(); ++i) {
1050 if (m_morphTargets.at(i) == object) {
1051 m_morphTargets.removeAt(i--);
1056 markDirty(QQuick3DModel::MorphTargetsDirty);
1060void QQuick3DModel::qmlAppendMorphTarget(QQmlListProperty<QQuick3DMorphTarget> *list, QQuick3DMorphTarget *morphTarget)
1062 if (morphTarget ==
nullptr)
1064 QQuick3DModel *self =
static_cast<QQuick3DModel *>(list->object);
1065 self->m_morphTargets.push_back(morphTarget);
1067 self->markDirty(QQuick3DModel::MorphTargetsDirty);
1069 if (morphTarget->parentItem() ==
nullptr) {
1072 QQuick3DObject *parentItem = qobject_cast<QQuick3DObject *>(morphTarget->parent());
1074 morphTarget->setParentItem(parentItem);
1076 const auto &scenManager = QQuick3DObjectPrivate::get(self)->sceneManager;
1078 QQuick3DObjectPrivate::get(morphTarget)->refSceneManager(*scenManager);
1084 connect(morphTarget, &QQuick3DMorphTarget::destroyed, self, &QQuick3DModel::onMorphTargetDestroyed);
1087QQuick3DMorphTarget *QQuick3DModel::qmlMorphTargetAt(QQmlListProperty<QQuick3DMorphTarget> *list, qsizetype index)
1089 QQuick3DModel *self =
static_cast<QQuick3DModel *>(list->object);
1090 if (index >= self->m_morphTargets.size()) {
1091 qWarning(
"The index exceeds the range of valid morph targets.");
1094 return self->m_morphTargets.at(index);
1097qsizetype QQuick3DModel::qmlMorphTargetsCount(QQmlListProperty<QQuick3DMorphTarget> *list)
1099 QQuick3DModel *self =
static_cast<QQuick3DModel *>(list->object);
1100 return self->m_morphTargets.size();
1103void QQuick3DModel::qmlClearMorphTargets(QQmlListProperty<QQuick3DMorphTarget> *list)
1105 QQuick3DModel *self =
static_cast<QQuick3DModel *>(list->object);
1106 for (
const auto &morph : std::as_const(self->m_morphTargets)) {
1107 if (morph->parentItem() ==
nullptr)
1108 QQuick3DObjectPrivate::get(morph)->derefSceneManager();
1109 disconnect(morph, &QQuick3DMorphTarget::destroyed, self, &QQuick3DModel::onMorphTargetDestroyed);
1111 self->m_morphTargets.clear();
1112 self->markDirty(QQuick3DModel::MorphTargetsDirty);
1115void QQuick3DModel::setInstancingLodMin(
float minDistance)
1117 if (qFuzzyCompare(m_instancingLodMin, minDistance))
1119 m_instancingLodMin = minDistance;
1120 emit instancingLodMinChanged();
1121 markDirty(LodDirty);
1124void QQuick3DModel::setInstancingLodMax(
float maxDistance)
1126 if (qFuzzyCompare(m_instancingLodMax, maxDistance))
1128 m_instancingLodMax = maxDistance;
1129 emit instancingLodMaxChanged();
1130 markDirty(LodDirty);
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1157float QQuick3DModel::levelOfDetailBias()
const
1159 return m_levelOfDetailBias;
1162void QQuick3DModel::setLevelOfDetailBias(
float newLevelOfDetailBias)
1164 if (qFuzzyCompare(m_levelOfDetailBias, newLevelOfDetailBias))
1166 m_levelOfDetailBias = newLevelOfDetailBias;
1167 emit levelOfDetailBiasChanged();
1168 markDirty(QQuick3DModel::PropertyDirty);
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1183float QQuick3DModel::texelsPerUnit()
const
1185 return m_texelsPerUnit;
1188void QQuick3DModel::setTexelsPerUnit(
float newTexelsPerUnit)
1190 if (qFuzzyCompare(m_texelsPerUnit, newTexelsPerUnit))
1192 m_texelsPerUnit = newTexelsPerUnit;
1193 emit texelsPerUnitChanged();
1194 markDirty(PropertyDirty);
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1215bool QQuick3DModel::motionVectorEnabled()
const
1217 return m_motionVectorEnabled;
1220void QQuick3DModel::setMotionVectorEnabled(
bool newMotionVectorEnabled)
1222 if (m_motionVectorEnabled == newMotionVectorEnabled)
1224 m_motionVectorEnabled = newMotionVectorEnabled;
1225 emit motionVectorEnabledChanged();
1226 markDirty(QQuick3DModel::PropertyDirty);
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1246float QQuick3DModel::motionVectorScale()
const
1248 return m_motionVectorScale;
1251void QQuick3DModel::setMotionVectorScale(
float newMotionVectorScale)
1253 if (qFuzzyCompare(m_motionVectorScale, newMotionVectorScale))
1255 m_motionVectorScale = newMotionVectorScale;
1256 emit motionVectorScaleChanged();
1257 markDirty(QQuick3DModel::PropertyDirty);
Combined button and popup list for selecting options.