10#include <QtQuick3DRuntimeRender/private/qssgrendergraphobject_p.h>
11#include <QtQuick3DRuntimeRender/private/qssgrendercustommaterial_p.h>
12#include <QtQuick3DRuntimeRender/private/qssgrenderdefaultmaterial_p.h>
13#include <QtQuick3DRuntimeRender/private/qssgrendermodel_p.h>
15#include <QtQuick3DUtils/private/qssgutils_p.h>
17#include <QtQml/QQmlFile>
22
23
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
117
118
119
120
121
122
123
124
127
128
129
130
131
134
135
136
137
138
140QQuick3DModel::QQuick3DModel(QQuick3DNode *parent)
141 : QQuick3DNode(*(
new QQuick3DNodePrivate(QQuick3DNodePrivate::Type::Model)), parent) {}
143QQuick3DModel::~QQuick3DModel()
145 disconnect(m_geometryConnection);
147 auto matList = materials();
148 qmlClearMaterials(&matList);
149 auto morphList = morphTargets();
150 qmlClearMorphTargets(&morphList);
154
155
156
157
158
159
160
161
162
163
164
165
166
167
169QUrl QQuick3DModel::source()
const
175
176
177
178
179
180
181
182
183
186QQmlListProperty<QQuick3DMaterial> QQuick3DModel::materials()
188 return QQmlListProperty<QQuick3DMaterial>(
this,
190 QQuick3DModel::qmlAppendMaterial,
191 QQuick3DModel::qmlMaterialsCount,
192 QQuick3DModel::qmlMaterialAt,
193 QQuick3DModel::qmlClearMaterials);
197
198
199
200
201
202
203
204
205
207QQmlListProperty<QQuick3DMorphTarget> QQuick3DModel::morphTargets()
209 return QQmlListProperty<QQuick3DMorphTarget>(
this,
211 QQuick3DModel::qmlAppendMorphTarget,
212 QQuick3DModel::qmlMorphTargetsCount,
213 QQuick3DModel::qmlMorphTargetAt,
214 QQuick3DModel::qmlClearMorphTargets);
218
219
220
221
222
223
224
226QQuick3DInstancing *QQuick3DModel::instancing()
const
232
233
234
235
236
237
238
239
240QQuick3DNode *QQuick3DModel::instanceRoot()
const
242 return m_instanceRoot;
249QString QQuick3DModel::translateMeshSource(
const QUrl &source, QObject *contextObject)
252 if (source.hasFragment()) {
254 bool isNumber =
false;
255 source.fragment().toInt(&isNumber);
256 fragment = QStringLiteral(
"#") + source.fragment();
262 const QQmlContext *context = qmlContext(contextObject);
263 const auto resolvedUrl = context ? context->resolvedUrl(source) : source;
264 const auto qmlSource = QQmlFile::urlToLocalFileOrQrc(resolvedUrl);
265 return (qmlSource.isEmpty() ? source.path() : qmlSource) + fragment;
268void QQuick3DModel::markAllDirty()
270 m_dirtyAttributes = 0xffffffff;
271 QQuick3DNode::markAllDirty();
275
276
277
278
279
280
281
282
284bool QQuick3DModel::castsShadows()
const
286 return m_castsShadows;
290
291
292
293
294
295
296
297
298
299
300
302bool QQuick3DModel::receivesShadows()
const
304 return m_receivesShadows;
308
309
310
311
312
313
314
315bool QQuick3DModel::pickable()
const
321
322
323
324
325
326
327QQuick3DGeometry *QQuick3DModel::geometry()
const
333
334
335
336
337
338
339
340
341
342
343
344
345QQuick3DSkeleton *QQuick3DModel::skeleton()
const
351
352
353
354
355
356
357
358
359
360
361
362
363
364QQuick3DSkin *QQuick3DModel::skin()
const
371
372
373
374
375
376
377
378
379
380
381
382
383QList<QMatrix4x4> QQuick3DModel::inverseBindPoses()
const
385 return m_inverseBindPoses;
389
390
391
392
393
394
395
396
397QQuick3DBounds3 QQuick3DModel::bounds()
const
403
404
405
406
407
408
409
410float QQuick3DModel::depthBias()
const
416
417
418
419
420
421
423bool QQuick3DModel::receivesReflections()
const
425 return m_receivesReflections;
429
430
431
432
433
434
435bool QQuick3DModel::castsReflections()
const
437 return m_castsReflections;
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
467bool QQuick3DModel::isUsedInBakedLighting()
const
469 return m_usedInBakedLighting;
473
474
475
476
477int QQuick3DModel::lightmapBaseResolution()
const
479 return m_lightmapBaseResolution;
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
510QQuick3DBakedLightmap *QQuick3DModel::bakedLightmap()
const
512 return m_bakedLightmap;
516
517
518
519
520
521float QQuick3DModel::instancingLodMin()
const
523 return m_instancingLodMin;
527
528
529
530
531
532float QQuick3DModel::instancingLodMax()
const
534 return m_instancingLodMax;
537void QQuick3DModel::setSource(
const QUrl &source)
539 if (m_source == source)
543 emit sourceChanged();
544 markDirty(SourceDirty);
545 if (QQuick3DObjectPrivate::get(
this)->sceneManager)
546 QQuick3DObjectPrivate::get(
this)->sceneManager->dirtyBoundingBoxList.append(
this);
549void QQuick3DModel::setCastsShadows(
bool castsShadows)
551 if (m_castsShadows == castsShadows)
554 m_castsShadows = castsShadows;
555 emit castsShadowsChanged();
556 markDirty(ShadowsDirty);
559void QQuick3DModel::setReceivesShadows(
bool receivesShadows)
561 if (m_receivesShadows == receivesShadows)
564 m_receivesShadows = receivesShadows;
565 emit receivesShadowsChanged();
566 markDirty(ShadowsDirty);
569void QQuick3DModel::setPickable(
bool isPickable)
571 if (m_pickable == isPickable)
574 m_pickable = isPickable;
575 emit pickableChanged();
576 markDirty(PickingDirty);
579void QQuick3DModel::setGeometry(QQuick3DGeometry *geometry)
581 if (geometry == m_geometry)
585 QQuick3DObjectPrivate::attachWatcher(
this, &QQuick3DModel::setGeometry, geometry, m_geometry);
588 QObject::disconnect(m_geometryConnection);
589 m_geometry = geometry;
593 = QObject::connect(m_geometry, &QQuick3DGeometry::geometryNodeDirty,
this, [
this]() {
594 markDirty(GeometryDirty);
597 emit geometryChanged();
598 markDirty(GeometryDirty);
601void QQuick3DModel::setSkeleton(QQuick3DSkeleton *skeleton)
603 if (skeleton == m_skeleton)
607 QQuick3DObjectPrivate::attachWatcher(
this, &QQuick3DModel::setSkeleton, skeleton, m_skeleton);
609 m_skeleton = skeleton;
611 emit skeletonChanged();
612 markDirty(SkeletonDirty);
615void QQuick3DModel::setSkin(QQuick3DSkin *skin)
621 QQuick3DObjectPrivate::attachWatcher(
this, &QQuick3DModel::setSkin, skin, m_skin);
625 markDirty(SkinDirty);
628void QQuick3DModel::setInverseBindPoses(
const QList<QMatrix4x4> &poses)
630 if (m_inverseBindPoses == poses)
633 m_inverseBindPoses = poses;
634 emit inverseBindPosesChanged();
635 markDirty(PoseDirty);
639void QQuick3DModel::setBounds(
const QVector3D &min,
const QVector3D &max)
641 if (!qFuzzyCompare(m_bounds.maximum(), max)
642 || !qFuzzyCompare(m_bounds.minimum(), min)) {
643 m_bounds.bounds = QSSGBounds3 { min, max };
644 emit boundsChanged();
648void QQuick3DModel::setInstancing(QQuick3DInstancing *instancing)
650 if (m_instancing == instancing)
654 QQuick3DObjectPrivate::attachWatcher(
this, &QQuick3DModel::setInstancing, instancing, m_instancing);
656 QObject::disconnect(m_instancingConnection);
657 m_instancing = instancing;
659 m_instancingConnection = QObject::connect
660 (m_instancing, &QQuick3DInstancing::instanceNodeDirty,
661 this, [
this]{ markDirty(InstancesDirty);});
663 markDirty(InstancesDirty);
664 emit instancingChanged();
667void QQuick3DModel::setInstanceRoot(QQuick3DNode *instanceRoot)
669 if (m_instanceRoot == instanceRoot)
672 QQuick3DObjectPrivate::attachWatcher(
this, &QQuick3DModel::setInstanceRoot, instanceRoot, m_instanceRoot);
674 m_instanceRoot = instanceRoot;
675 markDirty(InstanceRootDirty);
676 emit instanceRootChanged();
679void QQuick3DModel::setDepthBias(
float bias)
681 if (qFuzzyCompare(bias, m_depthBias))
685 markDirty(PropertyDirty);
686 emit depthBiasChanged();
689void QQuick3DModel::setReceivesReflections(
bool receivesReflections)
691 if (m_receivesReflections == receivesReflections)
694 m_receivesReflections = receivesReflections;
695 emit receivesReflectionsChanged();
696 markDirty(ReflectionDirty);
699void QQuick3DModel::setCastsReflections(
bool castsReflections)
701 if (m_castsReflections == castsReflections)
703 m_castsReflections = castsReflections;
704 emit castsReflectionsChanged();
705 markDirty(ReflectionDirty);
708void QQuick3DModel::setUsedInBakedLighting(
bool enable)
710 if (m_usedInBakedLighting == enable)
713 m_usedInBakedLighting = enable;
714 emit usedInBakedLightingChanged();
715 markDirty(PropertyDirty);
718void QQuick3DModel::setLightmapBaseResolution(
int resolution)
720 resolution = qMax(128, resolution);
721 if (m_lightmapBaseResolution == resolution)
724 qWarning() <<
"Model::lightmapBaseResolution is deprecated and will have no effect.";
726 m_lightmapBaseResolution = resolution;
727 emit lightmapBaseResolutionChanged();
728 markDirty(PropertyDirty);
731void QQuick3DModel::setBakedLightmap(QQuick3DBakedLightmap *bakedLightmap)
733 if (m_bakedLightmap == bakedLightmap)
737 m_bakedLightmap->disconnect(m_bakedLightmapSignalConnection);
739 m_bakedLightmap = bakedLightmap;
741 m_bakedLightmapSignalConnection = QObject::connect(m_bakedLightmap, &QQuick3DBakedLightmap::changed,
this,
742 [
this] { markDirty(PropertyDirty); });
744 QObject::connect(m_bakedLightmap, &QObject::destroyed,
this,
747 m_bakedLightmap =
nullptr;
748 markDirty(PropertyDirty);
751 emit bakedLightmapChanged();
752 markDirty(PropertyDirty);
755void QQuick3DModel::itemChange(ItemChange change,
const ItemChangeData &value)
757 if (change == QQuick3DObject::ItemSceneChange)
758 updateSceneManager(value.sceneManager);
761QSSGRenderGraphObject *QQuick3DModel::updateSpatialNode(QSSGRenderGraphObject *node)
765 node =
new QSSGRenderModel();
768 QQuick3DNode::updateSpatialNode(node);
769 int dirtyAttribute = 0;
771 auto modelNode =
static_cast<QSSGRenderModel *>(node);
772 if (m_dirtyAttributes & SourceDirty) {
773 const QString path = translateMeshSource(m_source,
this);
774 const QString lightmapKey = m_bakedLightmap ? m_bakedLightmap->key() : QString();
775 modelNode->meshPath = QSSGRenderPath(path, lightmapKey);
777 if (m_dirtyAttributes & PickingDirty)
778 modelNode->setState(QSSGRenderModel::LocalState::Pickable, m_pickable);
780 if (m_dirtyAttributes & ShadowsDirty) {
781 modelNode->castsShadows = m_castsShadows;
782 modelNode->receivesShadows = m_receivesShadows;
785 if (m_dirtyAttributes & MaterialsDirty) {
786 if (!m_materials.isEmpty()) {
787 if (modelNode->materials.isEmpty()) {
789 for (
const Material &material : m_materials) {
790 QSSGRenderGraphObject *graphObject = QQuick3DObjectPrivate::get(material.material)->spatialNode;
792 modelNode->materials.append(graphObject);
794 dirtyAttribute |= MaterialsDirty;
798 if (modelNode->materials.size() != m_materials.size())
799 modelNode->materials.resize(m_materials.size());
800 for (
int i = 0; i < m_materials.size(); ++i) {
801 QSSGRenderGraphObject *graphObject = QQuick3DObjectPrivate::get(m_materials[i].material)->spatialNode;
802 if (modelNode->materials[i] != graphObject)
803 modelNode->materials[i] = graphObject;
808 modelNode->materials.clear();
812 if (m_dirtyAttributes & MorphTargetsDirty) {
813 if (!m_morphTargets.isEmpty()) {
814 const int numMorphTarget = m_morphTargets.size();
815 if (modelNode->morphTargets.isEmpty()) {
817 for (
const auto morphTarget : std::as_const(m_morphTargets)) {
818 QSSGRenderGraphObject *graphObject = QQuick3DObjectPrivate::get(morphTarget)->spatialNode;
820 modelNode->morphTargets.append(graphObject);
822 dirtyAttribute |= MorphTargetsDirty;
824 modelNode->morphWeights.resize(numMorphTarget);
825 modelNode->morphAttributes.resize(numMorphTarget);
828 if (modelNode->morphTargets.size() != numMorphTarget) {
829 modelNode->morphTargets.resize(numMorphTarget);
830 modelNode->morphWeights.resize(numMorphTarget);
831 modelNode->morphAttributes.resize(numMorphTarget);
833 for (
int i = 0; i < numMorphTarget; ++i)
834 modelNode->morphTargets[i] = QQuick3DObjectPrivate::get(m_morphTargets.at(i))->spatialNode;
838 modelNode->morphTargets.clear();
842 if (m_dirtyAttributes & quint32(InstancesDirty | InstanceRootDirty)) {
845 QSSGRenderNode *instanceRootNode =
nullptr;
846 if (m_instanceRoot) {
847 if (m_instanceRoot ==
this)
848 instanceRootNode = modelNode;
850 instanceRootNode =
static_cast<QSSGRenderNode *>(QQuick3DObjectPrivate::get(m_instanceRoot)->spatialNode);
852 if (instanceRootNode != modelNode->instanceRoot) {
853 modelNode->instanceRoot = instanceRootNode;
854 modelNode->markDirty(QSSGRenderNode::DirtyFlag::TransformDirty);
858 modelNode->instanceTable =
static_cast<QSSGRenderInstanceTable *>(QQuick3DObjectPrivate::get(m_instancing)->spatialNode);
860 modelNode->instanceTable =
nullptr;
864 if (m_dirtyAttributes & GeometryDirty) {
866 modelNode->geometry =
static_cast<QSSGRenderGeometry *>(QQuick3DObjectPrivate::get(m_geometry)->spatialNode);
867 setBounds(m_geometry->boundsMin(), m_geometry->boundsMax());
869 modelNode->geometry =
nullptr;
870 setBounds(QVector3D(), QVector3D());
874 if (m_dirtyAttributes & SkeletonDirty) {
876 modelNode->skeleton =
static_cast<QSSGRenderSkeleton *>(QQuick3DObjectPrivate::get(m_skeleton)->spatialNode);
877 if (modelNode->skeleton)
878 modelNode->skeleton->skinningDirty =
true;
880 modelNode->skeleton =
nullptr;
884 if (m_dirtyAttributes & SkinDirty) {
886 modelNode->skin =
static_cast<QSSGRenderSkin *>(QQuick3DObjectPrivate::get(m_skin)->spatialNode);
888 modelNode->skin =
nullptr;
891 if (m_dirtyAttributes & LodDirty) {
892 modelNode->instancingLodMin = m_instancingLodMin;
893 modelNode->instancingLodMax = m_instancingLodMax;
896 if (m_dirtyAttributes & PoseDirty) {
897 modelNode->inverseBindPoses = m_inverseBindPoses.toVector();
898 if (modelNode->skeleton)
899 modelNode->skeleton->skinningDirty =
true;
902 if (m_dirtyAttributes & PropertyDirty) {
903 modelNode->m_depthBiasSq = QSSGRenderModel::signedSquared(m_depthBias);
904 modelNode->usedInBakedLighting = m_usedInBakedLighting;
905 modelNode->texelsPerUnit = m_texelsPerUnit;
906 if (m_bakedLightmap && m_bakedLightmap->isEnabled()) {
907 modelNode->lightmapKey = m_bakedLightmap->key();
909 modelNode->lightmapKey.clear();
912 const QString path = translateMeshSource(m_source,
this);
913 modelNode->meshPath = QSSGRenderPath(path, modelNode->lightmapKey);
914 modelNode->levelOfDetailBias = m_levelOfDetailBias;
917 if (m_dirtyAttributes & ReflectionDirty) {
918 modelNode->receivesReflections = m_receivesReflections;
919 modelNode->castsReflections = m_castsReflections;
922 m_dirtyAttributes = dirtyAttribute;
927void QQuick3DModel::markDirty(QQuick3DModel::QSSGModelDirtyType type)
929 if (InstanceRootDirty & quint32(type))
930 QQuick3DObjectPrivate::get(
this)->dirty(QQuick3DObjectPrivate::InstanceRootChanged);
932 if (!(m_dirtyAttributes & quint32(type))) {
933 m_dirtyAttributes |= quint32(type);
938void QQuick3DModel::updateSceneManager(QQuick3DSceneManager *sceneManager)
941 sceneManager->dirtyBoundingBoxList.append(
this);
942 QQuick3DObjectPrivate::refSceneManager(m_skeleton, *sceneManager);
943 QQuick3DObjectPrivate::refSceneManager(m_skin, *sceneManager);
944 QQuick3DObjectPrivate::refSceneManager(m_geometry, *sceneManager);
945 QQuick3DObjectPrivate::refSceneManager(m_instancing, *sceneManager);
946 for (Material &mat : m_materials) {
947 if (!mat.material->parentItem() && !QQuick3DObjectPrivate::get(mat.material)->sceneManager) {
949 QQuick3DObjectPrivate::refSceneManager(mat.material, *sceneManager);
955 QQuick3DObjectPrivate::derefSceneManager(m_skeleton);
956 QQuick3DObjectPrivate::derefSceneManager(m_skin);
957 QQuick3DObjectPrivate::derefSceneManager(m_geometry);
958 QQuick3DObjectPrivate::derefSceneManager(m_instancing);
959 for (Material &mat : m_materials) {
961 QQuick3DObjectPrivate::derefSceneManager(mat.material);
968void QQuick3DModel::onMaterialDestroyed(QObject *object)
971 for (
int i = 0; i < m_materials.size(); ++i) {
972 if (m_materials[i].material == object) {
973 m_materials.removeAt(i--);
978 markDirty(QQuick3DModel::MaterialsDirty);
981void QQuick3DModel::qmlAppendMaterial(QQmlListProperty<QQuick3DMaterial> *list, QQuick3DMaterial *material)
983 if (material ==
nullptr)
985 QQuick3DModel *self =
static_cast<QQuick3DModel *>(list->object);
986 self->m_materials.push_back({ material,
false });
987 self->markDirty(QQuick3DModel::MaterialsDirty);
989 if (material->parentItem() ==
nullptr) {
992 QQuick3DObject *parentItem = qobject_cast<QQuick3DObject *>(material->parent());
994 material->setParentItem(parentItem);
996 const auto &sceneManager = QQuick3DObjectPrivate::get(self)->sceneManager;
998 QQuick3DObjectPrivate::get(material)->refSceneManager(*sceneManager);
1004 self->m_materials.last().refed =
true;
1011 connect(material, &QQuick3DMaterial::destroyed, self, &QQuick3DModel::onMaterialDestroyed);
1014QQuick3DMaterial *QQuick3DModel::qmlMaterialAt(QQmlListProperty<QQuick3DMaterial> *list, qsizetype index)
1016 QQuick3DModel *self =
static_cast<QQuick3DModel *>(list->object);
1017 return self->m_materials.at(index).material;
1020qsizetype QQuick3DModel::qmlMaterialsCount(QQmlListProperty<QQuick3DMaterial> *list)
1022 QQuick3DModel *self =
static_cast<QQuick3DModel *>(list->object);
1023 return self->m_materials.size();
1026void QQuick3DModel::qmlClearMaterials(QQmlListProperty<QQuick3DMaterial> *list)
1028 QQuick3DModel *self =
static_cast<QQuick3DModel *>(list->object);
1029 for (Material &mat : self->m_materials) {
1030 if (mat.material->parentItem() ==
nullptr) {
1032 QQuick3DObjectPrivate::get(mat.material)->derefSceneManager();
1036 disconnect(mat.material, &QQuick3DMaterial::destroyed, self, &QQuick3DModel::onMaterialDestroyed);
1038 self->m_materials.clear();
1039 self->markDirty(QQuick3DModel::MaterialsDirty);
1042void QQuick3DModel::onMorphTargetDestroyed(QObject *object)
1045 for (
int i = 0; i < m_morphTargets.size(); ++i) {
1046 if (m_morphTargets.at(i) == object) {
1047 m_morphTargets.removeAt(i--);
1052 markDirty(QQuick3DModel::MorphTargetsDirty);
1053 m_numMorphAttribs = 0;
1057void QQuick3DModel::qmlAppendMorphTarget(QQmlListProperty<QQuick3DMorphTarget> *list, QQuick3DMorphTarget *morphTarget)
1059 if (morphTarget ==
nullptr)
1061 QQuick3DModel *self =
static_cast<QQuick3DModel *>(list->object);
1062 if (self->m_numMorphAttribs >= 8) {
1063 qWarning(
"The number of morph attributes exceeds 8. This morph target will be ignored.");
1066 self->m_morphTargets.push_back(morphTarget);
1067 self->m_numMorphAttribs += morphTarget->numAttribs();
1068 if (self->m_numMorphAttribs > 8)
1069 qWarning(
"The number of morph attributes exceeds 8. This morph target will be supported partially.");
1071 self->markDirty(QQuick3DModel::MorphTargetsDirty);
1073 if (morphTarget->parentItem() ==
nullptr) {
1076 QQuick3DObject *parentItem = qobject_cast<QQuick3DObject *>(morphTarget->parent());
1078 morphTarget->setParentItem(parentItem);
1080 const auto &scenManager = QQuick3DObjectPrivate::get(self)->sceneManager;
1082 QQuick3DObjectPrivate::get(morphTarget)->refSceneManager(*scenManager);
1088 connect(morphTarget, &QQuick3DMorphTarget::destroyed, self, &QQuick3DModel::onMorphTargetDestroyed);
1091QQuick3DMorphTarget *QQuick3DModel::qmlMorphTargetAt(QQmlListProperty<QQuick3DMorphTarget> *list, qsizetype index)
1093 QQuick3DModel *self =
static_cast<QQuick3DModel *>(list->object);
1094 if (index >= self->m_morphTargets.size()) {
1095 qWarning(
"The index exceeds the range of valid morph targets.");
1098 return self->m_morphTargets.at(index);
1101qsizetype QQuick3DModel::qmlMorphTargetsCount(QQmlListProperty<QQuick3DMorphTarget> *list)
1103 QQuick3DModel *self =
static_cast<QQuick3DModel *>(list->object);
1104 return self->m_morphTargets.size();
1107void QQuick3DModel::qmlClearMorphTargets(QQmlListProperty<QQuick3DMorphTarget> *list)
1109 QQuick3DModel *self =
static_cast<QQuick3DModel *>(list->object);
1110 for (
const auto &morph : std::as_const(self->m_morphTargets)) {
1111 if (morph->parentItem() ==
nullptr)
1112 QQuick3DObjectPrivate::get(morph)->derefSceneManager();
1113 disconnect(morph, &QQuick3DMorphTarget::destroyed, self, &QQuick3DModel::onMorphTargetDestroyed);
1115 self->m_morphTargets.clear();
1116 self->m_numMorphAttribs = 0;
1117 self->markDirty(QQuick3DModel::MorphTargetsDirty);
1120void QQuick3DModel::setInstancingLodMin(
float minDistance)
1122 if (qFuzzyCompare(m_instancingLodMin, minDistance))
1124 m_instancingLodMin = minDistance;
1125 emit instancingLodMinChanged();
1126 markDirty(LodDirty);
1129void QQuick3DModel::setInstancingLodMax(
float maxDistance)
1131 if (qFuzzyCompare(m_instancingLodMax, maxDistance))
1133 m_instancingLodMax = maxDistance;
1134 emit instancingLodMaxChanged();
1135 markDirty(LodDirty);
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1162float QQuick3DModel::levelOfDetailBias()
const
1164 return m_levelOfDetailBias;
1167void QQuick3DModel::setLevelOfDetailBias(
float newLevelOfDetailBias)
1169 if (qFuzzyCompare(m_levelOfDetailBias, newLevelOfDetailBias))
1171 m_levelOfDetailBias = newLevelOfDetailBias;
1172 emit levelOfDetailBiasChanged();
1173 markDirty(QQuick3DModel::PropertyDirty);
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1188float QQuick3DModel::texelsPerUnit()
const
1190 return m_texelsPerUnit;
1193void QQuick3DModel::setTexelsPerUnit(
float newTexelsPerUnit)
1195 if (qFuzzyCompare(m_texelsPerUnit, newTexelsPerUnit))
1197 m_texelsPerUnit = newTexelsPerUnit;
1198 emit texelsPerUnitChanged();
1199 markDirty(PropertyDirty);