1 /**************************************************************************** 2 ** 3 ** Copyright (C) 2019 The Qt Company Ltd. 4 ** Contact: https://www.qt.io/licensing/ 5 ** 6 ** This file is part of Qt Quick 3D. 7 ** 8 ** $QT_BEGIN_LICENSE:GPL$ 9 ** Commercial License Usage 10 ** Licensees holding valid commercial Qt licenses may use this file in 11 ** accordance with the commercial license agreement provided with the 12 ** Software or, alternatively, in accordance with the terms contained in 13 ** a written agreement between you and The Qt Company. For licensing terms 14 ** and conditions see https://www.qt.io/terms-conditions. For further 15 ** information use the contact form at https://www.qt.io/contact-us. 16 ** 17 ** GNU General Public License Usage 18 ** Alternatively, this file may be used under the terms of the GNU 19 ** General Public License version 3 or (at your option) any later version 20 ** approved by the KDE Free Qt Foundation. The licenses are as published by 21 ** the Free Software Foundation and appearing in the file LICENSE.GPL3 22 ** included in the packaging of this file. Please review the following 23 ** information to ensure the GNU General Public License requirements will 24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html. 25 ** 26 ** $QT_END_LICENSE$ 27 ** 28 ****************************************************************************/ 29 30 #ifndef UIPPRESENTATION_H 31 #define UIPPRESENTATION_H 32 33 #include <QString> 34 #include <QVector> 35 #include <QSet> 36 #include <QHash> 37 #include <QVector2D> 38 #include <QVector3D> 39 #include <QMatrix4x4> 40 #include <QColor> 41 #include <QXmlStreamAttributes> 42 43 #include <functional> 44 45 QT_BEGIN_NAMESPACE 46 47 namespace Q3DS { 48 49 enum PropertyType { // value format 50 Unknown = 0, 51 StringList, // String 52 FloatRange, // Float 53 LongRange, // Long 54 Float, // Float 55 Long, // Long 56 Float2, // Float2 57 Vector, // Float3 58 Scale, // Float3 59 Rotation, // Float3 60 Color, // Float4 61 Boolean, // Bool 62 Slide, // String 63 Font, // String 64 FontSize, // Float 65 String, // String 66 MultiLineString, // String 67 ObjectRef, // ObjectRef 68 Image, // String 69 Mesh, // String 70 Import, // String 71 Texture, // String 72 Image2D, // String 73 Buffer, // String 74 Guid, // Long4 75 StringListOrInt, // StringOrInt 76 Renderable, // String 77 PathBuffer, // String 78 Enum, // depends on name; data model only 79 Matrix4x4 // Matrix4x4 80 }; 81 82 bool convertToPropertyType(const QStringRef &value, Q3DS::PropertyType *type, int *componentCount, const char *desc = nullptr, QXmlStreamReader *reader = nullptr); 83 bool convertToFloat(const QStringRef &value, float *v, const char *desc = nullptr, QXmlStreamReader *reader = nullptr); 84 bool convertToInt(const QStringRef &value, int *v, const char *desc = nullptr, QXmlStreamReader *reader = nullptr); 85 bool convertToInt32(const QStringRef &value, qint32 *v, const char *desc = nullptr, QXmlStreamReader *reader = nullptr); 86 bool convertToBool(const QStringRef &value, bool *v, const char *desc = nullptr, QXmlStreamReader *reader = nullptr); 87 bool convertToVector2D(const QStringRef &value, QVector2D *v, const char *desc = nullptr, QXmlStreamReader *reader = nullptr); 88 bool convertToVector3D(const QStringRef &value, QVector3D *v, const char *desc = nullptr, QXmlStreamReader *reader = nullptr); 89 bool convertToVector4D(const QStringRef &value, QVector4D *v, const char *desc = nullptr, QXmlStreamReader *reader = nullptr); 90 bool convertToMatrix4x4(const QStringRef &value, QMatrix4x4 *v, const char *desc = nullptr, QXmlStreamReader *reader = nullptr); 91 int animatablePropertyTypeToMetaType(Q3DS::PropertyType type); 92 QVariant convertToVariant(const QString &value, Q3DS::PropertyType type); 93 QString convertFromVariant(const QVariant &value); 94 95 } // namespace Q3DS 96 97 class PropertyChange 98 { 99 public: 100 PropertyChange() = default; 101 102 // When the new value is already set via a member or static setter. 103 // Used by animations and any external call to a member setter. PropertyChange(const QString & name_)104 PropertyChange(const QString &name_) 105 : m_name(name_) 106 { } 107 108 // Value included. 109 // Used by slides (on-enter property changes) and data input. 110 // High frequency usage should be avoided. PropertyChange(const QString & name_,const QString & value_)111 PropertyChange(const QString &name_, const QString &value_) 112 : m_name(name_), m_value(value_), m_hasValue(true) 113 { } 114 115 static PropertyChange fromVariant(const QString &name, const QVariant &value); 116 117 // name() and value() must be source compatible with QXmlStreamAttribute name()118 QStringRef name() const { return QStringRef(&m_name); } value()119 QStringRef value() const { Q_ASSERT(m_hasValue); return QStringRef(&m_value); } 120 nameStr()121 QString nameStr() const { return m_name; } valueStr()122 QString valueStr() const { Q_ASSERT(m_hasValue); return m_value; } 123 124 // A setter can return an invalid change when the new value is the same as 125 // before. Such changes are ignored by the changelist. isValid()126 bool isValid() const { return !m_name.isEmpty(); } 127 128 // A change without value can only be used with notifyPropertyChanges, not 129 // with applyPropertyChanges. hasValue()130 bool hasValue() const { return m_hasValue; } 131 132 private: 133 QString m_name; 134 QString m_value; 135 bool m_hasValue = false; 136 }; 137 138 Q_DECLARE_TYPEINFO(PropertyChange, Q_MOVABLE_TYPE); 139 140 class PropertyChangeList 141 { 142 public: 143 typedef const PropertyChange *const_iterator; 144 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 145 PropertyChangeList()146 PropertyChangeList() { } 147 #ifdef Q_COMPILER_INITIALIZER_LISTS 148 PropertyChangeList(std::initializer_list<PropertyChange> args); 149 #endif 150 begin()151 const_iterator begin() const Q_DECL_NOTHROW { return m_changes.begin(); } cbegin()152 const_iterator cbegin() const Q_DECL_NOTHROW { return begin(); } end()153 const_iterator end() const Q_DECL_NOTHROW { return m_changes.end(); } cend()154 const_iterator cend() const Q_DECL_NOTHROW { return end(); } rbegin()155 const_reverse_iterator rbegin() const Q_DECL_NOTHROW { return const_reverse_iterator(end()); } crbegin()156 const_reverse_iterator crbegin() const Q_DECL_NOTHROW { return rbegin(); } rend()157 const_reverse_iterator rend() const Q_DECL_NOTHROW { return const_reverse_iterator(begin()); } crend()158 const_reverse_iterator crend() const Q_DECL_NOTHROW { return rend(); } 159 isEmpty()160 bool isEmpty() const { return m_changes.isEmpty(); } count()161 int count() const { return m_changes.count(); } clear()162 void clear() { m_changes.clear(); m_keys.clear(); } 163 void append(const PropertyChange &change); keys()164 QSet<QString> keys() const { return m_keys; } 165 166 typedef PropertyChange value_type; 167 168 private: 169 QVector<PropertyChange> m_changes; 170 QSet<QString> m_keys; 171 }; 172 173 class GraphObject 174 { 175 public: 176 enum Type { 177 Asset = 0, 178 // direct subtypes 179 Scene, 180 Slide, 181 Image, 182 DefaultMaterial, 183 ReferencedMaterial, 184 CustomMaterial, 185 Effect, 186 Behavior, 187 // node subtypes 188 Layer = 100, 189 Camera, 190 Light, 191 Model, 192 Group, 193 Text, 194 Component, 195 Alias 196 }; 197 198 static constexpr Type AnyObject = Type::Asset; 199 static constexpr Type FirstNodeType = Type::Layer; 200 201 enum PropSetFlag { 202 PropSetDefaults = 0x01, 203 PropSetOnMaster = 0x02 204 }; 205 Q_DECLARE_FLAGS(PropSetFlags, PropSetFlag) 206 207 enum State { 208 Enabled, 209 Disabled 210 }; 211 212 GraphObject(Type type); 213 virtual ~GraphObject(); 214 215 // hmm where have I seen this before... type()216 Type type() const { return m_type; } 217 QString typeName () const; 218 parent()219 GraphObject *parent() const { return m_parent; } firstChild()220 GraphObject *firstChild() const { return m_firstChild; } lastChild()221 GraphObject *lastChild() const { return m_lastChild; } nextSibling()222 GraphObject *nextSibling() const { return m_nextSibling; } previousSibling()223 GraphObject *previousSibling() const { return m_previousSibling; } 224 int childCount() const; 225 GraphObject *childAtIndex(int idx) const; 226 void removeChildNode(GraphObject *node); 227 void removeAllChildNodes(); 228 void prependChildNode(GraphObject *node); 229 void appendChildNode(GraphObject *node); 230 void insertChildNodeBefore(GraphObject *node, GraphObject *before); 231 void insertChildNodeAfter(GraphObject *node, GraphObject *after); 232 void reparentChildNodesTo(GraphObject *newParent); 233 234 virtual void setProperties(const QXmlStreamAttributes &attrs, PropSetFlags flags); 235 virtual void applyPropertyChanges(const PropertyChangeList &changeList); 236 isNode()237 bool isNode() const { return m_type >= FirstNodeType; } startTime()238 float startTime() { return m_startTime * 0.001f; } endTime()239 float endTime() { return m_endTime * 0.001f; } state()240 State state() const { return m_state; } 241 242 QString qmlId(); 243 virtual void writeQmlHeader(QTextStream &output, int tabLevel) = 0; 244 virtual void writeQmlProperties(QTextStream &output, int tabLevel, bool isInRootLevel = false) = 0; 245 virtual void writeQmlProperties(const PropertyChangeList &changeList, QTextStream &output, int tabLevel) = 0; 246 virtual void writeQmlFooter(QTextStream &output, int tabLevel); 247 248 void destroyGraph(); 249 250 QByteArray m_id; 251 QString m_name; 252 qint32 m_startTime = 0; 253 qint32 m_endTime = 10000; 254 255 private: 256 Q_DISABLE_COPY(GraphObject) 257 template<typename V> void setProps(const V &attrs, PropSetFlags flags); 258 259 struct ObjectExtraMetaData 260 { 261 struct Data { 262 QVector<QByteArray> propertyNames; 263 QVector<QVariant> propertyValues; 264 }; 265 QScopedPointer<Data> data; 266 } metaData; 267 extraMetaData()268 ObjectExtraMetaData *extraMetaData() { return &metaData; } extraMetaData()269 const ObjectExtraMetaData *extraMetaData() const { return &metaData; } 270 271 GraphObject *m_parent = nullptr; 272 GraphObject *m_firstChild = nullptr; 273 GraphObject *m_lastChild = nullptr; 274 GraphObject *m_nextSibling = nullptr; 275 GraphObject *m_previousSibling = nullptr; 276 Type m_type = AnyObject; 277 State m_state = Enabled; 278 279 friend class UipPresentation; 280 }; 281 282 class Scene : public GraphObject 283 { 284 public: 285 Scene(); 286 ~Scene() override; 287 288 void setProperties(const QXmlStreamAttributes &attrs, PropSetFlags flags) override; 289 290 bool m_useClearColor = true; 291 QColor m_clearColor = Qt::black; 292 293 // GraphObject interface 294 public: 295 void writeQmlHeader(QTextStream &output, int tabLevel) override; 296 void writeQmlProperties(QTextStream &output, int tabLevel, bool isInRootLevel = false) override; 297 void writeQmlProperties(const PropertyChangeList &changeList, QTextStream &output, int tabLevel) override; 298 void writeQmlFooter(QTextStream &output, int tabLevel) override; 299 }; 300 301 class AnimationTrack 302 { 303 public: 304 enum AnimationType { 305 NoAnimation = 0, 306 Linear, 307 EaseInOut, 308 Bezier 309 }; 310 311 struct KeyFrame { 312 KeyFrame() = default; KeyFrameKeyFrame313 KeyFrame(float time_, float value_) 314 : time(time_), value(value_) 315 { } 316 317 float time = 0; // seconds 318 float value = 0; 319 union { 320 float easeIn; 321 float c2time; 322 }; 323 union { 324 float easeOut; 325 float c2value; 326 }; 327 float c1time; 328 float c1value; 329 }; 330 using KeyFrameList = QVector<KeyFrame>; 331 332 AnimationTrack() = default; AnimationTrack(AnimationType type_,GraphObject * target_,const QString & property_)333 AnimationTrack(AnimationType type_, GraphObject *target_, const QString &property_) 334 : m_type(type_), m_target(target_), m_property(property_) 335 { } 336 337 AnimationType m_type = NoAnimation; 338 GraphObject *m_target = nullptr; 339 QString m_property; 340 bool m_dynamic = false; 341 KeyFrameList m_keyFrames; 342 }; 343 344 Q_DECLARE_TYPEINFO(AnimationTrack::KeyFrame, Q_MOVABLE_TYPE); 345 Q_DECLARE_TYPEINFO(AnimationTrack, Q_MOVABLE_TYPE); 346 347 inline bool operator==(const AnimationTrack::KeyFrame &a, const AnimationTrack::KeyFrame &b) 348 { 349 return a.time == b.time; 350 } 351 352 inline bool operator!=(const AnimationTrack::KeyFrame &a, const AnimationTrack::KeyFrame &b) 353 { 354 return !(a == b); 355 } 356 357 inline bool operator==(const AnimationTrack &a, const AnimationTrack &b) 358 { 359 return a.m_target == b.m_target && a.m_property == b.m_property; 360 } 361 362 inline bool operator!=(const AnimationTrack &a, const AnimationTrack &b) 363 { 364 return !(a == b); 365 } 366 367 class Slide : public GraphObject 368 { 369 public: 370 enum PlayMode { 371 StopAtEnd = 0, 372 Looping, 373 PingPong, 374 Ping, 375 PlayThroughTo 376 }; 377 378 enum InitialPlayState { 379 Play = 0, 380 Pause 381 }; 382 383 enum PlayThrough { 384 Next, 385 Previous, 386 Value 387 }; 388 389 using PropertyChanges = QHash<GraphObject *, PropertyChangeList *>; 390 using AnimationTrackList = QVector<AnimationTrack>; 391 392 Slide(); 393 ~Slide() override; 394 395 void setProperties(const QXmlStreamAttributes &attrs, PropSetFlags flags) override; 396 void applyPropertyChanges(const PropertyChangeList &changeList) override; 397 objects()398 const QSet<GraphObject *> &objects() const { return m_objects; } // NB does not include objects from master 399 void addObject(GraphObject *obj); 400 void removeObject(GraphObject *obj); 401 propertyChanges()402 const PropertyChanges &propertyChanges() const { return m_propChanges; } 403 void addPropertyChanges(GraphObject *target, PropertyChangeList *changeList); // changeList ownership transferred 404 void removePropertyChanges(GraphObject *target); 405 PropertyChangeList *takePropertyChanges(GraphObject *target); 406 animations()407 const AnimationTrackList &animations() const { return m_anims; } 408 void addAnimation(const AnimationTrack &track); 409 void removeAnimation(const AnimationTrack &track); 410 411 template<typename V> void setProps(const V &attrs, PropSetFlags flags); 412 413 PlayMode m_playMode = StopAtEnd; 414 InitialPlayState m_initialPlayState = Play; 415 PlayThrough m_playThrough = Next; 416 QVariant m_playThroughValue; 417 QSet<GraphObject *> m_objects; 418 PropertyChanges m_propChanges; 419 AnimationTrackList m_anims; 420 421 // GraphObject interface 422 public: 423 void writeQmlHeader(QTextStream &output, int tabLevel) override; 424 void writeQmlProperties(QTextStream &output, int tabLevel, bool isInRootLevel = false) override; 425 void writeQmlProperties(const PropertyChangeList &changeList, QTextStream &output, int tabLevel) override; 426 void writeQmlFooter(QTextStream &output, int tabLevel) override; 427 }; 428 429 class Image : public GraphObject 430 { 431 public: 432 enum MappingMode { 433 UVMapping = 0, 434 EnvironmentalMapping, 435 LightProbe, 436 IBLOverride 437 }; 438 439 enum TilingMode { 440 Tiled = 0, 441 Mirrored, 442 NoTiling 443 }; 444 445 enum ImagePropertyChanges { 446 SourceChanges = 1 << 0 447 }; 448 449 Image(); 450 451 void setProperties(const QXmlStreamAttributes &attrs, PropSetFlags flags) override; 452 void applyPropertyChanges(const PropertyChangeList &changeList) override; 453 454 bool isDefaultScaleAndRotation(); 455 456 template<typename V> void setProps(const V &attrs, PropSetFlags flags); 457 458 QString m_sourcePath; 459 float m_scaleU = 1; 460 float m_scaleV = 1; 461 MappingMode m_mappingMode = UVMapping; 462 TilingMode m_tilingHoriz = NoTiling; 463 TilingMode m_tilingVert = NoTiling; 464 float m_rotationUV = 0; 465 float m_positionU = 0; 466 float m_positionV = 0; 467 float m_pivotU = 0; 468 float m_pivotV = 0; 469 QString m_subPresentation; 470 471 // GraphObject interface 472 public: 473 void writeQmlHeader(QTextStream &output, int tabLevel) override; 474 void writeQmlProperties(QTextStream &output, int tabLevel, bool isInRootLevel = false) override; 475 void writeQmlProperties(const PropertyChangeList &changeList, QTextStream &output, int tabLevel) override; 476 }; 477 478 class Node : public GraphObject 479 { 480 public: 481 enum NodeFlag { 482 Active = 0x01, // eyeball 483 IgnoresParentTransform = 0x02 484 }; 485 Q_DECLARE_FLAGS(Flags, NodeFlag) 486 487 enum RotationOrder { 488 XYZ = 0, 489 YZX, 490 ZXY, 491 XZY, 492 YXZ, 493 ZYX, 494 XYZr, 495 YZXr, 496 ZXYr, 497 XZYr, 498 YXZr, 499 ZYXr 500 }; 501 502 enum Orientation { 503 LeftHanded = 0, 504 RightHanded 505 }; 506 507 enum NodePropertyChanges { 508 TransformChanges = 1 << 0, 509 OpacityChanges = 1 << 1, 510 EyeballChanges = 1 << 2 511 }; 512 static const int FIRST_FREE_PROPERTY_CHANGE_BIT = 3; 513 514 Node(Type type); 515 516 void setProperties(const QXmlStreamAttributes &attrs, PropSetFlags flags) override; 517 void applyPropertyChanges(const PropertyChangeList &changeList) override; 518 519 Flags m_flags = Active; 520 QVector3D m_rotation; 521 QVector3D m_position; 522 QVector3D m_scale = QVector3D(1, 1, 1); 523 QVector3D m_pivot; 524 float m_localOpacity = 100.0f; 525 qint32 m_skeletonId = -1; 526 RotationOrder m_rotationOrder = YXZ; 527 Orientation m_orientation = LeftHanded; 528 529 template<typename V> void setProps(const V &attrs, PropSetFlags flags); 530 531 // GraphObject interface 532 public: 533 void writeQmlHeader(QTextStream &output, int tabLevel) override; 534 void writeQmlProperties(QTextStream &output, int tabLevel, bool isInRootLevel = false) override; 535 void writeQmlProperties(const PropertyChangeList &changeList, QTextStream &output, int tabLevel) override; 536 }; 537 538 class LayerNode : public Node 539 { 540 public: 541 enum Flag { 542 DisableDepthTest = 0x01, 543 DisableDepthPrePass = 0x02, 544 TemporalAA = 0x04, 545 FastIBL = 0x08, 546 547 // non-uip 548 ExplicitSize = 0x1000 549 }; 550 Q_DECLARE_FLAGS(Flags, Flag) 551 552 enum ProgressiveAA { 553 NoPAA = 0, 554 PAA2x, 555 PAA4x, 556 PAA8x 557 }; 558 559 enum MultisampleAA { 560 NoMSAA = 0, 561 MSAA2x, 562 MSAA4x, 563 SSAA 564 }; 565 566 enum LayerBackground { 567 Transparent = 0, 568 SolidColor, 569 Unspecified 570 }; 571 572 enum BlendType { 573 Normal = 0, 574 Screen, 575 Multiply, 576 Add, 577 Subtract, 578 Overlay, 579 ColorBurn, 580 ColorDodge 581 }; 582 583 enum HorizontalFields { 584 LeftWidth = 0, 585 LeftRight, 586 WidthRight 587 }; 588 589 enum VerticalFields { 590 TopHeight = 0, 591 TopBottom, 592 HeightBottom 593 }; 594 595 enum Units { 596 Percent = 0, 597 Pixels 598 }; 599 600 enum LayerPropertyChanges { 601 AoOrShadowChanges = 1 << Node::FIRST_FREE_PROPERTY_CHANGE_BIT, 602 LayerContentSubTreeChanges = 1 << (Node::FIRST_FREE_PROPERTY_CHANGE_BIT + 1), 603 LayerContentSubTreeLightsChange = 1 << (Node::FIRST_FREE_PROPERTY_CHANGE_BIT + 2), 604 SourcePathChanges = 1 << (Node::FIRST_FREE_PROPERTY_CHANGE_BIT + 3) 605 }; 606 607 LayerNode(); 608 609 void setProperties(const QXmlStreamAttributes &attrs, PropSetFlags flags) override; 610 void applyPropertyChanges(const PropertyChangeList &changeList) override; 611 612 template<typename V> void setProps(const V &attrs, PropSetFlags flags); 613 614 void outputAAModeAndQuality(QTextStream &output, int tabLevel, const QString &propertyName); 615 616 QSize m_explicitSize; 617 618 Flags m_layerFlags = FastIBL; 619 ProgressiveAA m_progressiveAA = NoPAA; 620 MultisampleAA m_multisampleAA = NoMSAA; 621 bool m_antialiasingSet = false; 622 LayerBackground m_layerBackground = Transparent; 623 QColor m_backgroundColor = Qt::black; 624 BlendType m_blendType = Normal; 625 626 HorizontalFields m_horizontalFields = LeftWidth; 627 float m_left = 0; 628 Units m_leftUnits = Percent; 629 float m_width = 100; 630 Units m_widthUnits = Percent; 631 float m_right = 0; 632 Units m_rightUnits = Percent; 633 VerticalFields m_verticalFields = TopHeight; 634 float m_top = 0; 635 Units m_topUnits = Percent; 636 float m_height = 100; 637 Units m_heightUnits = Percent; 638 float m_bottom = 0; 639 Units m_bottomUnits = Percent; 640 641 QString m_sourcePath; 642 643 float m_aoStrength = 0; 644 float m_aoDistance = 5; 645 float m_aoSoftness = 50; 646 float m_aoBias = 0; 647 qint32 m_aoSampleRate = 2; 648 bool m_aoDither = false; 649 650 QString m_lightProbe_unresolved; 651 float m_probeBright = 100; 652 float m_probeHorizon = -1; 653 float m_probeFov = 180; 654 655 // GraphObject interface 656 public: 657 void writeQmlHeader(QTextStream &output, int tabLevel) override; 658 void writeQmlProperties(QTextStream &output, int tabLevel, bool isInRootLevel = false) override; 659 void writeQmlProperties(const PropertyChangeList &changeList, QTextStream &output, int tabLevel) override; 660 }; 661 662 class CameraNode : public Node 663 { 664 665 public: 666 CameraNode(); 667 668 void setProperties(const QXmlStreamAttributes &attrs, PropSetFlags flags) override; 669 void applyPropertyChanges(const PropertyChangeList &changeList) override; 670 671 template<typename V> void setProps(const V &attrs, PropSetFlags flags); 672 673 bool m_orthographic = false; 674 float m_fov = 60; 675 bool m_fovHorizontal = false; 676 float m_clipNear = 10; 677 float m_clipFar = 5000; 678 bool m_frustumCulling = false; 679 float m_zoom = 1.0; 680 681 // GraphObject interface 682 public: 683 void writeQmlHeader(QTextStream &output, int tabLevel) override; 684 void writeQmlProperties(QTextStream &output, int tabLevel, bool isInRootLevel = false) override; 685 void writeQmlProperties(const PropertyChangeList &changeList, QTextStream &output, int tabLevel) override; 686 }; 687 688 class LightNode : public Node 689 { 690 public: 691 enum LightType { 692 Directional = 0, 693 Point, 694 Area 695 }; 696 697 LightNode(); 698 699 void setProperties(const QXmlStreamAttributes &attrs, PropSetFlags flags) override; 700 void applyPropertyChanges(const PropertyChangeList &changeList) override; 701 702 template<typename V> void setProps(const V &attrs, PropSetFlags flags); 703 704 QString m_scope_unresolved; 705 GraphObject *m_scope = nullptr; 706 LightType m_lightType = Directional; 707 QColor m_lightDiffuse = Qt::white; 708 QColor m_lightSpecular = Qt::white; 709 QColor m_lightAmbient = Qt::black; 710 float m_brightness = 100; 711 float m_constantFade = 1; 712 float m_linearFade = 0; 713 float m_expFade = 0; 714 float m_areaWidth = 100; 715 float m_areaHeight = 100; 716 bool m_castShadow = false; 717 float m_shadowFactor = 10; 718 float m_shadowFilter = 35; 719 qint32 m_shadowMapRes = 9; 720 float m_shadowBias = 0; 721 float m_shadowMapFar = 5000; 722 float m_shadowMapFov = 90; 723 724 // GraphObject interface 725 public: 726 void writeQmlHeader(QTextStream &output, int tabLevel) override; 727 void writeQmlProperties(QTextStream &output, int tabLevel, bool isInRootLevel = false) override; 728 void writeQmlProperties(const PropertyChangeList &changeList, QTextStream &output, int tabLevel) override; 729 }; 730 731 class ModelNode : public Node 732 { 733 public: 734 enum Tessellation { 735 None = 0, 736 Linear, 737 Phong, 738 NPatch 739 }; 740 741 enum ModelPropertyChanges { 742 MeshChanges = 1 << Node::FIRST_FREE_PROPERTY_CHANGE_BIT 743 }; 744 745 ModelNode(); 746 ~ModelNode() override; 747 748 void setProperties(const QXmlStreamAttributes &attrs, PropSetFlags flags) override; 749 void applyPropertyChanges(const PropertyChangeList &changeList) override; 750 751 template<typename V> void setProps(const V &attrs, PropSetFlags flags); 752 753 QString m_mesh_unresolved; 754 Tessellation m_tessellation = None; 755 float m_edgeTess = 4; 756 float m_innerTess = 4; 757 758 // GraphObject interface 759 public: 760 void writeQmlHeader(QTextStream &output, int tabLevel) override; 761 void writeQmlProperties(QTextStream &output, int tabLevel, bool isInRootLevel = false) override; 762 void writeQmlProperties(const PropertyChangeList &changeList, QTextStream &output, int tabLevel) override; 763 }; 764 765 class GroupNode : public Node 766 { 767 public: 768 GroupNode(); 769 770 void setProperties(const QXmlStreamAttributes &attrs, PropSetFlags flags) override; 771 void applyPropertyChanges(const PropertyChangeList &changeList) override; 772 773 template<typename V> void setProps(const V &attrs, PropSetFlags flags); 774 775 // GraphObject interface 776 public: 777 void writeQmlHeader(QTextStream &output, int tabLevel) override; 778 void writeQmlProperties(QTextStream &output, int tabLevel, bool isInRootLevel = false) override; 779 void writeQmlProperties(const PropertyChangeList &changeList, QTextStream &output, int tabLevel) override; 780 }; 781 782 783 784 class ComponentNode : public Node 785 { 786 787 public: 788 ComponentNode(); 789 ~ComponentNode() override; 790 791 void setProperties(const QXmlStreamAttributes &attrs, PropSetFlags flags) override; 792 void applyPropertyChanges(const PropertyChangeList &changeList) override; 793 794 template<typename V> void setProps(const V &attrs, PropSetFlags flags); 795 796 class Slide *m_masterSlide = nullptr; 797 class Slide *m_currentSlide = nullptr; 798 799 800 // GraphObject interface 801 public: 802 void writeQmlHeader(QTextStream &output, int tabLevel) override; 803 void writeQmlProperties(QTextStream &output, int tabLevel, bool isInRootLevel = false) override; 804 void writeQmlProperties(const PropertyChangeList &changeList, QTextStream &output, int tabLevel) override; 805 }; 806 807 class TextNode : public Node 808 { 809 810 public: 811 enum HorizontalAlignment { 812 Left = 0, 813 Center, 814 Right 815 }; 816 817 enum VerticalAlignment { 818 Top = 0, 819 Middle, 820 Bottom 821 }; 822 823 enum WordWrap { 824 Clip = 0, 825 WrapWord, 826 WrapAnywhere 827 }; 828 829 enum Elide { 830 ElideNone = 0, 831 ElideLeft, 832 ElideMiddle, 833 ElideRight 834 }; 835 836 enum TextPropertyChanges { 837 TextureImageDepChanges = 1 << Node::FIRST_FREE_PROPERTY_CHANGE_BIT 838 }; 839 840 TextNode(); 841 842 void setProperties(const QXmlStreamAttributes &attrs, PropSetFlags flags) override; 843 void applyPropertyChanges(const PropertyChangeList &changeList) override; 844 845 template<typename V> void setProps(const V &attrs, PropSetFlags flags); 846 847 QString m_text = QStringLiteral("Text"); 848 QColor m_color = Qt::white; 849 QString m_font = QStringLiteral("TitilliumWeb-Regular"); 850 float m_size = 36; 851 HorizontalAlignment m_horizAlign = Center; 852 VerticalAlignment m_vertAlign = Middle; 853 float m_leading = 0; 854 float m_tracking = 0; 855 bool m_shadow = false; 856 float m_shadowStrength = 80; 857 float m_shadowOffsetX = 0; 858 float m_shadowOffsetY = 0; 859 float m_shadowOffset = 10; // To be removed in 2.x (when UIP version is next updated) 860 HorizontalAlignment m_shadowHorzAlign = Right; // To be removed in 2.x (when UIP version is next updated) 861 VerticalAlignment m_shadowVertAlign = Bottom; // To be removed in 2.x (when UIP version is next updated) 862 QVector2D m_boundingBox; 863 WordWrap m_wordWrap = WrapWord; 864 Elide m_elide = ElideNone; 865 866 // GraphObject interface 867 public: 868 void writeQmlHeader(QTextStream &output, int tabLevel) override; 869 void writeQmlProperties(QTextStream &output, int tabLevel, bool isInRootLevel = false) override; 870 void writeQmlProperties(const PropertyChangeList &changeList, QTextStream &output, int tabLevel) override; 871 }; 872 873 class DefaultMaterial : public GraphObject 874 { 875 public: 876 enum ShaderLighting { 877 PixelShaderLighting = 0, 878 NoShaderLighting 879 }; 880 881 enum BlendMode { 882 Normal = 0, 883 Screen, 884 Multiply, 885 Overlay, 886 ColorBurn, 887 ColorDodge 888 }; 889 890 enum SpecularModel { 891 DefaultSpecularModel = 0, 892 KGGX, 893 KWard 894 }; 895 896 enum DefaultMaterialPropertyChanges { 897 BlendModeChanges = 1 << 0 898 }; 899 900 DefaultMaterial(); 901 902 void setProperties(const QXmlStreamAttributes &attrs, PropSetFlags flags) override; 903 void applyPropertyChanges(const PropertyChangeList &changeList) override; 904 905 template<typename V> void setProps(const V &attrs, PropSetFlags flags); 906 907 // GraphObject interface 908 public: 909 void writeQmlHeader(QTextStream &output, int tabLevel) override; 910 void writeQmlProperties(QTextStream &output, int tabLevel, bool isInRootLevel = false) override; 911 void writeQmlProperties(const PropertyChangeList &changeList, QTextStream &output, int tabLevel) override; 912 913 ShaderLighting m_shaderLighting = PixelShaderLighting; 914 BlendMode m_blendMode = Normal; 915 bool m_vertexColors = false; 916 QColor m_diffuse = Qt::white; 917 QString m_diffuseMap_unresolved; 918 QString m_specularReflection_unresolved; 919 QColor m_specularTint = Qt::white; 920 float m_specularAmount = 0; 921 QString m_specularMap_unresolved; 922 SpecularModel m_specularModel = DefaultSpecularModel; 923 float m_specularRoughness = 0; 924 QString m_roughnessMap_unresolved; 925 float m_fresnelPower = 0; 926 float m_ior = 0.2f; 927 QString m_bumpMap_unresolved; 928 QString m_normalMap_unresolved; 929 float m_bumpAmount = 0.5f; 930 QString m_displacementMap_unresolved; 931 float m_displaceAmount = 20; 932 float m_opacity = 100; 933 QString m_opacityMap_unresolved; 934 QColor m_emissiveColor = Qt::white; 935 float m_emissiveFactor = 0; 936 QString m_emissiveMap_unresolved; 937 QString m_translucencyMap_unresolved; 938 float m_translucentFalloff = 1; 939 float m_diffuseLightWrap = 0; 940 // lightmaps 941 QString m_lightmapIndirectMap_unresolved; 942 QString m_lightmapRadiosityMap_unresolved; 943 QString m_lightmapShadowMap_unresolved; 944 // IBL override 945 QString m_lightProbe_unresolved; 946 }; 947 948 class ReferencedMaterial : public GraphObject 949 { 950 public: 951 enum ReferencedMaterialPropertyChanges { 952 ReferenceChanges = 1 << 0 953 }; 954 955 ReferencedMaterial(); 956 957 void setProperties(const QXmlStreamAttributes &attrs, PropSetFlags flags) override; 958 void applyPropertyChanges(const PropertyChangeList &changeList) override; 959 960 template<typename V> void setProps(const V &attrs, PropSetFlags flags); 961 962 // GraphObject interface 963 public: 964 void writeQmlHeader(QTextStream &output, int tabLevel) override; 965 void writeQmlProperties(QTextStream &output, int tabLevel, bool isInRootLevel = false) override; 966 void writeQmlProperties(const PropertyChangeList &changeList, QTextStream &output, int tabLevel) override; 967 968 QString m_referencedMaterial_unresolved; 969 GraphObject *m_referencedMaterial = nullptr; 970 // lightmap overrides 971 QString m_lightmapIndirectMap_unresolved; 972 QString m_lightmapRadiosityMap_unresolved; 973 QString m_lightmapShadowMap_unresolved; 974 // IBL override 975 QString m_lightProbe_unresolved; 976 }; 977 978 class CustomMaterialInstance : public GraphObject 979 { 980 public: 981 enum CustomMaterialPropertyChanges { 982 SourceChanges = 1 << 0 983 }; 984 985 CustomMaterialInstance(); 986 987 void setProperties(const QXmlStreamAttributes &attrs, PropSetFlags flags) override; 988 void applyPropertyChanges(const PropertyChangeList &changeList) override; 989 990 template<typename V> void setProps(const V &attrs, PropSetFlags flags); 991 992 // GraphObject interface 993 public: 994 void writeQmlHeader(QTextStream &output, int tabLevel) override; 995 void writeQmlProperties(QTextStream &output, int tabLevel, bool isInRootLevel = false) override; 996 void writeQmlProperties(const PropertyChangeList &changeList, QTextStream &output, int tabLevel) override; 997 998 QString m_material_unresolved; 999 bool m_materialIsResolved = false; 1000 QVariantMap m_materialPropertyVals; 1001 PropertyChangeList m_pendingCustomProperties; 1002 // lightmaps 1003 QString m_lightmapIndirectMap_unresolved; 1004 QString m_lightmapRadiosityMap_unresolved; 1005 QString m_lightmapShadowMap_unresolved; 1006 // IBL override 1007 QString m_lightProbe_unresolved; 1008 }; 1009 1010 class EffectInstance : public GraphObject 1011 { 1012 public: 1013 enum EffectInstancePropertyChanges { 1014 EyeBallChanges = 1 << 0, 1015 SourceChanges = 1 << 1 1016 }; 1017 1018 EffectInstance(); 1019 1020 void setProperties(const QXmlStreamAttributes &attrs, PropSetFlags flags) override; 1021 void applyPropertyChanges(const PropertyChangeList &changeList) override; 1022 1023 template<typename V> void setProps(const V &attrs, PropSetFlags flags); 1024 1025 // GraphObject interface 1026 public: 1027 void writeQmlHeader(QTextStream &output, int tabLevel) override; 1028 void writeQmlProperties(QTextStream &output, int tabLevel, bool isInRootLevel = false) override; 1029 void writeQmlProperties(const PropertyChangeList &changeList, QTextStream &output, int tabLevel) override; 1030 void writeQmlFooter(QTextStream &output, int tabLevel) override; 1031 1032 QString m_effect_unresolved; 1033 bool m_effectIsResolved = false; 1034 bool m_eyeballEnabled = true; 1035 PropertyChangeList m_pendingCustomProperties; 1036 }; 1037 1038 class BehaviorInstance : public GraphObject 1039 { 1040 public: 1041 enum BehaviorInstancePropertyChanges { 1042 EyeBallChanges = 1 << 0 1043 }; 1044 1045 BehaviorInstance(); 1046 1047 void setProperties(const QXmlStreamAttributes &attrs, PropSetFlags flags) override; 1048 void applyPropertyChanges(const PropertyChangeList &changeList) override; 1049 1050 template<typename V> void setProps(const V &attrs, PropSetFlags flags); 1051 1052 // GraphObject interface 1053 public: 1054 void writeQmlHeader(QTextStream &output, int tabLevel) override; 1055 void writeQmlProperties(QTextStream &output, int tabLevel, bool isInRootLevel = false) override; 1056 void writeQmlProperties(const PropertyChangeList &changeList, QTextStream &output, int tabLevel) override; 1057 void writeQmlFooter(QTextStream &output, int tabLevel) override; 1058 1059 QString m_behavior_unresolved; 1060 bool m_behaviorIsResolved = false; 1061 bool m_eyeballEnabled = true; 1062 PropertyChangeList m_pendingCustomProperties; 1063 QVariantMap m_behaviorPropertyVals; 1064 }; 1065 1066 class AliasNode : public Node 1067 { 1068 public: 1069 AliasNode(); 1070 1071 void setProperties(const QXmlStreamAttributes &attrs, PropSetFlags flags) override; 1072 void applyPropertyChanges(const PropertyChangeList &changeList) override; 1073 1074 template<typename V> void setProps(const V &attrs, PropSetFlags flags); 1075 // GraphObject interface 1076 public: 1077 void writeQmlHeader(QTextStream &output, int tabLevel) override; 1078 void writeQmlProperties(QTextStream &output, int tabLevel, bool isInRootLevel = false) override; 1079 void writeQmlProperties(const PropertyChangeList &changeList, QTextStream &output, int tabLevel) override; 1080 1081 QString m_referencedNode_unresolved; 1082 GraphObject *m_referencedNode = nullptr; 1083 1084 }; 1085 1086 struct UipPresentationData; 1087 class UipPresentation 1088 { 1089 public: 1090 UipPresentation(); 1091 ~UipPresentation(); 1092 void reset(); 1093 1094 enum Rotation { 1095 NoRotation = 0, 1096 Clockwise90, 1097 Clockwise180, 1098 Clockwise270 1099 }; 1100 1101 QString sourceFile() const; 1102 void setSourceFile(const QString &s); 1103 QString assetFileName(const QString &xmlFileNameRef, int *part) const; 1104 1105 QString name() const; 1106 void setName(const QString &s); 1107 1108 QString author() const; 1109 QString company() const; 1110 int presentationWidth() const; 1111 int presentationHeight() const; 1112 Rotation presentationRotation() const; 1113 bool maintainAspectRatio() const; 1114 1115 void setAuthor(const QString &author); 1116 void setCompany(const QString &company); 1117 void setPresentationWidth(int w); 1118 void setPresentationHeight(int h); 1119 void setPresentationRotation(Rotation r); 1120 void setMaintainAspectRatio(bool maintain); 1121 1122 Scene *scene() const; 1123 Slide *masterSlide() const; 1124 1125 void setScene(Scene *p); 1126 void setMasterSlide(Slide *p); 1127 1128 bool registerObject(const QByteArray &id, GraphObject *p); // covers both the scene and slide graphs 1129 void unregisterObject(const QByteArray &id); 1130 1131 template <typename T = GraphObject> object(const QByteArray & id)1132 const T *object(const QByteArray &id) const { return static_cast<const T *>(getObject(id)); } 1133 template <typename T = GraphObject> object(const QByteArray & id)1134 T *object(const QByteArray &id) { return static_cast<T *>(getObject(id)); } 1135 1136 template <typename T = GraphObject> objectByName(const QString & name)1137 const T *objectByName(const QString &name) const { return static_cast<const T *>(getObjectByName(name)); } 1138 template <typename T = GraphObject> objectByName(const QString & name)1139 T *objectByName(const QString &name) { return static_cast<T *>(getObjectByName(name)); } 1140 1141 void registerImageBuffer(const QString &sourcePath, bool hasTransparency); 1142 1143 typedef QHash<QString, bool> ImageBufferMap; 1144 const ImageBufferMap &imageBuffer() const; 1145 1146 void applyPropertyChanges(const Slide::PropertyChanges &changeList) const; 1147 void applySlidePropertyChanges(Slide *slide) const; 1148 newObject(const QByteArray & id)1149 template<typename T> T *newObject(const QByteArray &id) 1150 { 1151 T *obj = new T; 1152 return registerObject(id, obj) ? obj : nullptr; // also sets obj->id 1153 } 1154 1155 GraphObject *newObject(const char *type, const QByteArray &id); 1156 1157 GraphObject *getObject(const QByteArray &id) const; 1158 GraphObject *getObjectByName(const QString &name) const; 1159 1160 QScopedPointer<UipPresentationData> d; 1161 QHash<QString, bool> m_imageTransparencyHash; 1162 friend class UipParser; 1163 }; 1164 1165 struct UipPresentationData 1166 { 1167 QString sourceFile; 1168 QString name; 1169 QString author; 1170 QString company; 1171 int presentationWidth = 0; 1172 int presentationHeight = 0; 1173 UipPresentation::Rotation presentationRotation = UipPresentation::NoRotation; 1174 bool maintainAspectRatio = false; 1175 qint64 loadTime = 0; 1176 qint64 meshesLoadTime = 0; 1177 1178 Scene *scene = nullptr; 1179 Slide *masterSlide = nullptr; 1180 QHash<QByteArray, GraphObject *> objects; // node ptrs managed by scene, not owned 1181 1182 // Note: the key here is the sourcePath before it's resolved! 1183 QHash<QString, bool /* hasTransparency */> imageBuffers; 1184 }; 1185 1186 QT_END_NAMESPACE 1187 1188 #endif // UIPPRESENTATION_H 1189