blob: dd49713349280879f3c67b530ffe4653c8b15f1c [file] [log] [blame]
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Quick 3D.
**
** $QT_BEGIN_LICENSE:GPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 or (at your option) any later version
** approved by the KDE Free Qt Foundation. The licenses are as published by
** the Free Software Foundation and appearing in the file LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef UIPPRESENTATION_H
#define UIPPRESENTATION_H
#include <QString>
#include <QVector>
#include <QSet>
#include <QHash>
#include <QVector2D>
#include <QVector3D>
#include <QMatrix4x4>
#include <QColor>
#include <QXmlStreamAttributes>
#include <functional>
QT_BEGIN_NAMESPACE
namespace Q3DS {
enum PropertyType { // value format
Unknown = 0,
StringList, // String
FloatRange, // Float
LongRange, // Long
Float, // Float
Long, // Long
Float2, // Float2
Vector, // Float3
Scale, // Float3
Rotation, // Float3
Color, // Float4
Boolean, // Bool
Slide, // String
Font, // String
FontSize, // Float
String, // String
MultiLineString, // String
ObjectRef, // ObjectRef
Image, // String
Mesh, // String
Import, // String
Texture, // String
Image2D, // String
Buffer, // String
Guid, // Long4
StringListOrInt, // StringOrInt
Renderable, // String
PathBuffer, // String
Enum, // depends on name; data model only
Matrix4x4 // Matrix4x4
};
bool convertToPropertyType(const QStringRef &value, Q3DS::PropertyType *type, int *componentCount, const char *desc = nullptr, QXmlStreamReader *reader = nullptr);
bool convertToFloat(const QStringRef &value, float *v, const char *desc = nullptr, QXmlStreamReader *reader = nullptr);
bool convertToInt(const QStringRef &value, int *v, const char *desc = nullptr, QXmlStreamReader *reader = nullptr);
bool convertToInt32(const QStringRef &value, qint32 *v, const char *desc = nullptr, QXmlStreamReader *reader = nullptr);
bool convertToBool(const QStringRef &value, bool *v, const char *desc = nullptr, QXmlStreamReader *reader = nullptr);
bool convertToVector2D(const QStringRef &value, QVector2D *v, const char *desc = nullptr, QXmlStreamReader *reader = nullptr);
bool convertToVector3D(const QStringRef &value, QVector3D *v, const char *desc = nullptr, QXmlStreamReader *reader = nullptr);
bool convertToVector4D(const QStringRef &value, QVector4D *v, const char *desc = nullptr, QXmlStreamReader *reader = nullptr);
bool convertToMatrix4x4(const QStringRef &value, QMatrix4x4 *v, const char *desc = nullptr, QXmlStreamReader *reader = nullptr);
int animatablePropertyTypeToMetaType(Q3DS::PropertyType type);
QVariant convertToVariant(const QString &value, Q3DS::PropertyType type);
QString convertFromVariant(const QVariant &value);
} // namespace Q3DS
class PropertyChange
{
public:
PropertyChange() = default;
// When the new value is already set via a member or static setter.
// Used by animations and any external call to a member setter.
PropertyChange(const QString &name_)
: m_name(name_)
{ }
// Value included.
// Used by slides (on-enter property changes) and data input.
// High frequency usage should be avoided.
PropertyChange(const QString &name_, const QString &value_)
: m_name(name_), m_value(value_), m_hasValue(true)
{ }
static PropertyChange fromVariant(const QString &name, const QVariant &value);
// name() and value() must be source compatible with QXmlStreamAttribute
QStringRef name() const { return QStringRef(&m_name); }
QStringRef value() const { Q_ASSERT(m_hasValue); return QStringRef(&m_value); }
QString nameStr() const { return m_name; }
QString valueStr() const { Q_ASSERT(m_hasValue); return m_value; }
// A setter can return an invalid change when the new value is the same as
// before. Such changes are ignored by the changelist.
bool isValid() const { return !m_name.isEmpty(); }
// A change without value can only be used with notifyPropertyChanges, not
// with applyPropertyChanges.
bool hasValue() const { return m_hasValue; }
private:
QString m_name;
QString m_value;
bool m_hasValue = false;
};
Q_DECLARE_TYPEINFO(PropertyChange, Q_MOVABLE_TYPE);
class PropertyChangeList
{
public:
typedef const PropertyChange *const_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
PropertyChangeList() { }
#ifdef Q_COMPILER_INITIALIZER_LISTS
PropertyChangeList(std::initializer_list<PropertyChange> args);
#endif
const_iterator begin() const Q_DECL_NOTHROW { return m_changes.begin(); }
const_iterator cbegin() const Q_DECL_NOTHROW { return begin(); }
const_iterator end() const Q_DECL_NOTHROW { return m_changes.end(); }
const_iterator cend() const Q_DECL_NOTHROW { return end(); }
const_reverse_iterator rbegin() const Q_DECL_NOTHROW { return const_reverse_iterator(end()); }
const_reverse_iterator crbegin() const Q_DECL_NOTHROW { return rbegin(); }
const_reverse_iterator rend() const Q_DECL_NOTHROW { return const_reverse_iterator(begin()); }
const_reverse_iterator crend() const Q_DECL_NOTHROW { return rend(); }
bool isEmpty() const { return m_changes.isEmpty(); }
int count() const { return m_changes.count(); }
void clear() { m_changes.clear(); m_keys.clear(); }
void append(const PropertyChange &change);
QSet<QString> keys() const { return m_keys; }
typedef PropertyChange value_type;
private:
QVector<PropertyChange> m_changes;
QSet<QString> m_keys;
};
class GraphObject
{
public:
enum Type {
Asset = 0,
// direct subtypes
Scene,
Slide,
Image,
DefaultMaterial,
ReferencedMaterial,
CustomMaterial,
Effect,
Behavior,
// node subtypes
Layer = 100,
Camera,
Light,
Model,
Group,
Text,
Component,
Alias
};
static constexpr Type AnyObject = Type::Asset;
static constexpr Type FirstNodeType = Type::Layer;
enum PropSetFlag {
PropSetDefaults = 0x01,
PropSetOnMaster = 0x02
};
Q_DECLARE_FLAGS(PropSetFlags, PropSetFlag)
enum State {
Enabled,
Disabled
};
GraphObject(Type type);
virtual ~GraphObject();
// hmm where have I seen this before...
Type type() const { return m_type; }
QString typeName () const;
GraphObject *parent() const { return m_parent; }
GraphObject *firstChild() const { return m_firstChild; }
GraphObject *lastChild() const { return m_lastChild; }
GraphObject *nextSibling() const { return m_nextSibling; }
GraphObject *previousSibling() const { return m_previousSibling; }
int childCount() const;
GraphObject *childAtIndex(int idx) const;
void removeChildNode(GraphObject *node);
void removeAllChildNodes();
void prependChildNode(GraphObject *node);
void appendChildNode(GraphObject *node);
void insertChildNodeBefore(GraphObject *node, GraphObject *before);
void insertChildNodeAfter(GraphObject *node, GraphObject *after);
void reparentChildNodesTo(GraphObject *newParent);
virtual void setProperties(const QXmlStreamAttributes &attrs, PropSetFlags flags);
virtual void applyPropertyChanges(const PropertyChangeList &changeList);
bool isNode() const { return m_type >= FirstNodeType; }
float startTime() { return m_startTime * 0.001f; }
float endTime() { return m_endTime * 0.001f; }
State state() const { return m_state; }
QString qmlId();
virtual void writeQmlHeader(QTextStream &output, int tabLevel) = 0;
virtual void writeQmlProperties(QTextStream &output, int tabLevel, bool isInRootLevel = false) = 0;
virtual void writeQmlProperties(const PropertyChangeList &changeList, QTextStream &output, int tabLevel) = 0;
virtual void writeQmlFooter(QTextStream &output, int tabLevel);
void destroyGraph();
QByteArray m_id;
QString m_name;
qint32 m_startTime = 0;
qint32 m_endTime = 10000;
private:
Q_DISABLE_COPY(GraphObject)
template<typename V> void setProps(const V &attrs, PropSetFlags flags);
struct ObjectExtraMetaData
{
struct Data {
QVector<QByteArray> propertyNames;
QVector<QVariant> propertyValues;
};
QScopedPointer<Data> data;
} metaData;
ObjectExtraMetaData *extraMetaData() { return &metaData; }
const ObjectExtraMetaData *extraMetaData() const { return &metaData; }
GraphObject *m_parent = nullptr;
GraphObject *m_firstChild = nullptr;
GraphObject *m_lastChild = nullptr;
GraphObject *m_nextSibling = nullptr;
GraphObject *m_previousSibling = nullptr;
Type m_type = AnyObject;
State m_state = Enabled;
friend class UipPresentation;
};
class Scene : public GraphObject
{
public:
Scene();
~Scene() override;
void setProperties(const QXmlStreamAttributes &attrs, PropSetFlags flags) override;
bool m_useClearColor = true;
QColor m_clearColor = Qt::black;
// GraphObject interface
public:
void writeQmlHeader(QTextStream &output, int tabLevel) override;
void writeQmlProperties(QTextStream &output, int tabLevel, bool isInRootLevel = false) override;
void writeQmlProperties(const PropertyChangeList &changeList, QTextStream &output, int tabLevel) override;
void writeQmlFooter(QTextStream &output, int tabLevel) override;
};
class AnimationTrack
{
public:
enum AnimationType {
NoAnimation = 0,
Linear,
EaseInOut,
Bezier
};
struct KeyFrame {
KeyFrame() = default;
KeyFrame(float time_, float value_)
: time(time_), value(value_)
{ }
float time = 0; // seconds
float value = 0;
union {
float easeIn;
float c2time;
};
union {
float easeOut;
float c2value;
};
float c1time;
float c1value;
};
using KeyFrameList = QVector<KeyFrame>;
AnimationTrack() = default;
AnimationTrack(AnimationType type_, GraphObject *target_, const QString &property_)
: m_type(type_), m_target(target_), m_property(property_)
{ }
AnimationType m_type = NoAnimation;
GraphObject *m_target = nullptr;
QString m_property;
bool m_dynamic = false;
KeyFrameList m_keyFrames;
};
Q_DECLARE_TYPEINFO(AnimationTrack::KeyFrame, Q_MOVABLE_TYPE);
Q_DECLARE_TYPEINFO(AnimationTrack, Q_MOVABLE_TYPE);
inline bool operator==(const AnimationTrack::KeyFrame &a, const AnimationTrack::KeyFrame &b)
{
return a.time == b.time;
}
inline bool operator!=(const AnimationTrack::KeyFrame &a, const AnimationTrack::KeyFrame &b)
{
return !(a == b);
}
inline bool operator==(const AnimationTrack &a, const AnimationTrack &b)
{
return a.m_target == b.m_target && a.m_property == b.m_property;
}
inline bool operator!=(const AnimationTrack &a, const AnimationTrack &b)
{
return !(a == b);
}
class Slide : public GraphObject
{
public:
enum PlayMode {
StopAtEnd = 0,
Looping,
PingPong,
Ping,
PlayThroughTo
};
enum InitialPlayState {
Play = 0,
Pause
};
enum PlayThrough {
Next,
Previous,
Value
};
using PropertyChanges = QHash<GraphObject *, PropertyChangeList *>;
using AnimationTrackList = QVector<AnimationTrack>;
Slide();
~Slide() override;
void setProperties(const QXmlStreamAttributes &attrs, PropSetFlags flags) override;
void applyPropertyChanges(const PropertyChangeList &changeList) override;
const QSet<GraphObject *> &objects() const { return m_objects; } // NB does not include objects from master
void addObject(GraphObject *obj);
void removeObject(GraphObject *obj);
const PropertyChanges &propertyChanges() const { return m_propChanges; }
void addPropertyChanges(GraphObject *target, PropertyChangeList *changeList); // changeList ownership transferred
void removePropertyChanges(GraphObject *target);
PropertyChangeList *takePropertyChanges(GraphObject *target);
const AnimationTrackList &animations() const { return m_anims; }
void addAnimation(const AnimationTrack &track);
void removeAnimation(const AnimationTrack &track);
template<typename V> void setProps(const V &attrs, PropSetFlags flags);
PlayMode m_playMode = StopAtEnd;
InitialPlayState m_initialPlayState = Play;
PlayThrough m_playThrough = Next;
QVariant m_playThroughValue;
QSet<GraphObject *> m_objects;
PropertyChanges m_propChanges;
AnimationTrackList m_anims;
// GraphObject interface
public:
void writeQmlHeader(QTextStream &output, int tabLevel) override;
void writeQmlProperties(QTextStream &output, int tabLevel, bool isInRootLevel = false) override;
void writeQmlProperties(const PropertyChangeList &changeList, QTextStream &output, int tabLevel) override;
void writeQmlFooter(QTextStream &output, int tabLevel) override;
};
class Image : public GraphObject
{
public:
enum MappingMode {
UVMapping = 0,
EnvironmentalMapping,
LightProbe,
IBLOverride
};
enum TilingMode {
Tiled = 0,
Mirrored,
NoTiling
};
enum ImagePropertyChanges {
SourceChanges = 1 << 0
};
Image();
void setProperties(const QXmlStreamAttributes &attrs, PropSetFlags flags) override;
void applyPropertyChanges(const PropertyChangeList &changeList) override;
bool isDefaultScaleAndRotation();
template<typename V> void setProps(const V &attrs, PropSetFlags flags);
QString m_sourcePath;
float m_scaleU = 1;
float m_scaleV = 1;
MappingMode m_mappingMode = UVMapping;
TilingMode m_tilingHoriz = NoTiling;
TilingMode m_tilingVert = NoTiling;
float m_rotationUV = 0;
float m_positionU = 0;
float m_positionV = 0;
float m_pivotU = 0;
float m_pivotV = 0;
QString m_subPresentation;
// GraphObject interface
public:
void writeQmlHeader(QTextStream &output, int tabLevel) override;
void writeQmlProperties(QTextStream &output, int tabLevel, bool isInRootLevel = false) override;
void writeQmlProperties(const PropertyChangeList &changeList, QTextStream &output, int tabLevel) override;
};
class Node : public GraphObject
{
public:
enum NodeFlag {
Active = 0x01, // eyeball
IgnoresParentTransform = 0x02
};
Q_DECLARE_FLAGS(Flags, NodeFlag)
enum RotationOrder {
XYZ = 0,
YZX,
ZXY,
XZY,
YXZ,
ZYX,
XYZr,
YZXr,
ZXYr,
XZYr,
YXZr,
ZYXr
};
enum Orientation {
LeftHanded = 0,
RightHanded
};
enum NodePropertyChanges {
TransformChanges = 1 << 0,
OpacityChanges = 1 << 1,
EyeballChanges = 1 << 2
};
static const int FIRST_FREE_PROPERTY_CHANGE_BIT = 3;
Node(Type type);
void setProperties(const QXmlStreamAttributes &attrs, PropSetFlags flags) override;
void applyPropertyChanges(const PropertyChangeList &changeList) override;
Flags m_flags = Active;
QVector3D m_rotation;
QVector3D m_position;
QVector3D m_scale = QVector3D(1, 1, 1);
QVector3D m_pivot;
float m_localOpacity = 100.0f;
qint32 m_skeletonId = -1;
RotationOrder m_rotationOrder = YXZ;
Orientation m_orientation = LeftHanded;
template<typename V> void setProps(const V &attrs, PropSetFlags flags);
// GraphObject interface
public:
void writeQmlHeader(QTextStream &output, int tabLevel) override;
void writeQmlProperties(QTextStream &output, int tabLevel, bool isInRootLevel = false) override;
void writeQmlProperties(const PropertyChangeList &changeList, QTextStream &output, int tabLevel) override;
};
class LayerNode : public Node
{
public:
enum Flag {
DisableDepthTest = 0x01,
DisableDepthPrePass = 0x02,
TemporalAA = 0x04,
FastIBL = 0x08,
// non-uip
ExplicitSize = 0x1000
};
Q_DECLARE_FLAGS(Flags, Flag)
enum ProgressiveAA {
NoPAA = 0,
PAA2x,
PAA4x,
PAA8x
};
enum MultisampleAA {
NoMSAA = 0,
MSAA2x,
MSAA4x,
SSAA
};
enum LayerBackground {
Transparent = 0,
SolidColor,
Unspecified
};
enum BlendType {
Normal = 0,
Screen,
Multiply,
Add,
Subtract,
Overlay,
ColorBurn,
ColorDodge
};
enum HorizontalFields {
LeftWidth = 0,
LeftRight,
WidthRight
};
enum VerticalFields {
TopHeight = 0,
TopBottom,
HeightBottom
};
enum Units {
Percent = 0,
Pixels
};
enum LayerPropertyChanges {
AoOrShadowChanges = 1 << Node::FIRST_FREE_PROPERTY_CHANGE_BIT,
LayerContentSubTreeChanges = 1 << (Node::FIRST_FREE_PROPERTY_CHANGE_BIT + 1),
LayerContentSubTreeLightsChange = 1 << (Node::FIRST_FREE_PROPERTY_CHANGE_BIT + 2),
SourcePathChanges = 1 << (Node::FIRST_FREE_PROPERTY_CHANGE_BIT + 3)
};
LayerNode();
void setProperties(const QXmlStreamAttributes &attrs, PropSetFlags flags) override;
void applyPropertyChanges(const PropertyChangeList &changeList) override;
template<typename V> void setProps(const V &attrs, PropSetFlags flags);
QSize m_explicitSize;
Flags m_layerFlags = FastIBL;
ProgressiveAA m_progressiveAA = NoPAA;
MultisampleAA m_multisampleAA = NoMSAA;
LayerBackground m_layerBackground = Transparent;
QColor m_backgroundColor;
BlendType m_blendType = Normal;
HorizontalFields m_horizontalFields = LeftWidth;
float m_left = 0;
Units m_leftUnits = Percent;
float m_width = 100;
Units m_widthUnits = Percent;
float m_right = 0;
Units m_rightUnits = Percent;
VerticalFields m_verticalFields = TopHeight;
float m_top = 0;
Units m_topUnits = Percent;
float m_height = 100;
Units m_heightUnits = Percent;
float m_bottom = 0;
Units m_bottomUnits = Percent;
QString m_sourcePath;
float m_aoStrength = 0;
float m_aoDistance = 5;
float m_aoSoftness = 50;
float m_aoBias = 0;
qint32 m_aoSampleRate = 2;
bool m_aoDither = false;
QString m_lightProbe_unresolved;
float m_probeBright = 100;
float m_probeHorizon = -1;
float m_probeFov = 180;
// GraphObject interface
public:
void writeQmlHeader(QTextStream &output, int tabLevel) override;
void writeQmlProperties(QTextStream &output, int tabLevel, bool isInRootLevel = false) override;
void writeQmlProperties(const PropertyChangeList &changeList, QTextStream &output, int tabLevel) override;
};
class CameraNode : public Node
{
public:
#if 0 // TODO: QTBUG-81016
enum ScaleMode {
SameSize = 0,
Fit,
FitHorizontal,
FitVertical
};
enum ScaleAnchor {
Center = 0,
N,
NE,
E,
SE,
S,
SW,
W,
NW
};
#endif
CameraNode();
void setProperties(const QXmlStreamAttributes &attrs, PropSetFlags flags) override;
void applyPropertyChanges(const PropertyChangeList &changeList) override;
template<typename V> void setProps(const V &attrs, PropSetFlags flags);
bool m_orthographic = false;
float m_fov = 60;
bool m_fovHorizontal = false;
float m_clipNear = 10;
float m_clipFar = 5000;
bool m_frustumCulling = false;
#if 0 // TODO: QTBUG-81016
ScaleMode m_scaleMode = Fit;
ScaleAnchor m_scaleAnchor = Center;
#endif
float m_zoom = 1.0;
// GraphObject interface
public:
void writeQmlHeader(QTextStream &output, int tabLevel) override;
void writeQmlProperties(QTextStream &output, int tabLevel, bool isInRootLevel = false) override;
void writeQmlProperties(const PropertyChangeList &changeList, QTextStream &output, int tabLevel) override;
};
class LightNode : public Node
{
public:
enum LightType {
Directional = 0,
Point,
Area
};
LightNode();
void setProperties(const QXmlStreamAttributes &attrs, PropSetFlags flags) override;
void applyPropertyChanges(const PropertyChangeList &changeList) override;
template<typename V> void setProps(const V &attrs, PropSetFlags flags);
QString m_scope_unresolved;
GraphObject *m_scope = nullptr;
LightType m_lightType = Directional;
QColor m_lightDiffuse = Qt::white;
QColor m_lightSpecular = Qt::white;
QColor m_lightAmbient = Qt::black;
float m_brightness = 100;
float m_constantFade = 1;
float m_linearFade = 0;
float m_expFade = 0;
float m_areaWidth = 100;
float m_areaHeight = 100;
bool m_castShadow = false;
float m_shadowFactor = 10;
float m_shadowFilter = 35;
qint32 m_shadowMapRes = 9;
float m_shadowBias = 0;
float m_shadowMapFar = 5000;
float m_shadowMapFov = 90;
// GraphObject interface
public:
void writeQmlHeader(QTextStream &output, int tabLevel) override;
void writeQmlProperties(QTextStream &output, int tabLevel, bool isInRootLevel = false) override;
void writeQmlProperties(const PropertyChangeList &changeList, QTextStream &output, int tabLevel) override;
};
class ModelNode : public Node
{
public:
enum Tessellation {
None = 0,
Linear,
Phong,
NPatch
};
enum ModelPropertyChanges {
MeshChanges = 1 << Node::FIRST_FREE_PROPERTY_CHANGE_BIT
};
ModelNode();
~ModelNode() override;
void setProperties(const QXmlStreamAttributes &attrs, PropSetFlags flags) override;
void applyPropertyChanges(const PropertyChangeList &changeList) override;
template<typename V> void setProps(const V &attrs, PropSetFlags flags);
QString m_mesh_unresolved;
Tessellation m_tessellation = None;
float m_edgeTess = 4;
float m_innerTess = 4;
// GraphObject interface
public:
void writeQmlHeader(QTextStream &output, int tabLevel) override;
void writeQmlProperties(QTextStream &output, int tabLevel, bool isInRootLevel = false) override;
void writeQmlProperties(const PropertyChangeList &changeList, QTextStream &output, int tabLevel) override;
};
class GroupNode : public Node
{
public:
GroupNode();
void setProperties(const QXmlStreamAttributes &attrs, PropSetFlags flags) override;
void applyPropertyChanges(const PropertyChangeList &changeList) override;
template<typename V> void setProps(const V &attrs, PropSetFlags flags);
// GraphObject interface
public:
void writeQmlHeader(QTextStream &output, int tabLevel) override;
void writeQmlProperties(QTextStream &output, int tabLevel, bool isInRootLevel = false) override;
void writeQmlProperties(const PropertyChangeList &changeList, QTextStream &output, int tabLevel) override;
};
class ComponentNode : public Node
{
public:
ComponentNode();
~ComponentNode() override;
void setProperties(const QXmlStreamAttributes &attrs, PropSetFlags flags) override;
void applyPropertyChanges(const PropertyChangeList &changeList) override;
template<typename V> void setProps(const V &attrs, PropSetFlags flags);
class Slide *m_masterSlide = nullptr;
class Slide *m_currentSlide = nullptr;
// GraphObject interface
public:
void writeQmlHeader(QTextStream &output, int tabLevel) override;
void writeQmlProperties(QTextStream &output, int tabLevel, bool isInRootLevel = false) override;
void writeQmlProperties(const PropertyChangeList &changeList, QTextStream &output, int tabLevel) override;
};
class TextNode : public Node
{
public:
enum HorizontalAlignment {
Left = 0,
Center,
Right
};
enum VerticalAlignment {
Top = 0,
Middle,
Bottom
};
enum WordWrap {
Clip = 0,
WrapWord,
WrapAnywhere
};
enum Elide {
ElideNone = 0,
ElideLeft,
ElideMiddle,
ElideRight
};
enum TextPropertyChanges {
TextureImageDepChanges = 1 << Node::FIRST_FREE_PROPERTY_CHANGE_BIT
};
TextNode();
void setProperties(const QXmlStreamAttributes &attrs, PropSetFlags flags) override;
void applyPropertyChanges(const PropertyChangeList &changeList) override;
template<typename V> void setProps(const V &attrs, PropSetFlags flags);
QString m_text = QStringLiteral("Text");
QColor m_color = Qt::white;
QString m_font = QStringLiteral("TitilliumWeb-Regular");
float m_size = 36;
HorizontalAlignment m_horizAlign = Center;
VerticalAlignment m_vertAlign = Middle;
float m_leading = 0;
float m_tracking = 0;
bool m_shadow = false;
float m_shadowStrength = 80;
float m_shadowOffsetX = 0;
float m_shadowOffsetY = 0;
float m_shadowOffset = 10; // To be removed in 2.x (when UIP version is next updated)
HorizontalAlignment m_shadowHorzAlign = Right; // To be removed in 2.x (when UIP version is next updated)
VerticalAlignment m_shadowVertAlign = Bottom; // To be removed in 2.x (when UIP version is next updated)
QVector2D m_boundingBox;
WordWrap m_wordWrap = WrapWord;
Elide m_elide = ElideNone;
// GraphObject interface
public:
void writeQmlHeader(QTextStream &output, int tabLevel) override;
void writeQmlProperties(QTextStream &output, int tabLevel, bool isInRootLevel = false) override;
void writeQmlProperties(const PropertyChangeList &changeList, QTextStream &output, int tabLevel) override;
void writeQmlFooter(QTextStream &output, int tabLevel) override;
};
class DefaultMaterial : public GraphObject
{
public:
enum ShaderLighting {
PixelShaderLighting = 0,
NoShaderLighting
};
enum BlendMode {
Normal = 0,
Screen,
Multiply,
Overlay,
ColorBurn,
ColorDodge
};
enum SpecularModel {
DefaultSpecularModel = 0,
KGGX,
KWard
};
enum DefaultMaterialPropertyChanges {
BlendModeChanges = 1 << 0
};
DefaultMaterial();
void setProperties(const QXmlStreamAttributes &attrs, PropSetFlags flags) override;
void applyPropertyChanges(const PropertyChangeList &changeList) override;
template<typename V> void setProps(const V &attrs, PropSetFlags flags);
// GraphObject interface
public:
void writeQmlHeader(QTextStream &output, int tabLevel) override;
void writeQmlProperties(QTextStream &output, int tabLevel, bool isInRootLevel = false) override;
void writeQmlProperties(const PropertyChangeList &changeList, QTextStream &output, int tabLevel) override;
ShaderLighting m_shaderLighting = PixelShaderLighting;
BlendMode m_blendMode = Normal;
bool m_vertexColors = false;
QColor m_diffuse = Qt::white;
QString m_diffuseMap_unresolved;
QString m_specularReflection_unresolved;
QColor m_specularTint = Qt::white;
float m_specularAmount = 0;
QString m_specularMap_unresolved;
SpecularModel m_specularModel = DefaultSpecularModel;
float m_specularRoughness = 0;
QString m_roughnessMap_unresolved;
float m_fresnelPower = 0;
float m_ior = 0.2f;
QString m_bumpMap_unresolved;
QString m_normalMap_unresolved;
float m_bumpAmount = 0.5f;
QString m_displacementMap_unresolved;
float m_displaceAmount = 20;
float m_opacity = 100;
QString m_opacityMap_unresolved;
QColor m_emissiveColor = Qt::white;
float m_emissiveFactor = 0;
QString m_emissiveMap_unresolved;
QString m_translucencyMap_unresolved;
float m_translucentFalloff = 1;
float m_diffuseLightWrap = 0;
// lightmaps
QString m_lightmapIndirectMap_unresolved;
QString m_lightmapRadiosityMap_unresolved;
QString m_lightmapShadowMap_unresolved;
// IBL override
QString m_lightProbe_unresolved;
};
class ReferencedMaterial : public GraphObject
{
public:
enum ReferencedMaterialPropertyChanges {
ReferenceChanges = 1 << 0
};
ReferencedMaterial();
void setProperties(const QXmlStreamAttributes &attrs, PropSetFlags flags) override;
void applyPropertyChanges(const PropertyChangeList &changeList) override;
template<typename V> void setProps(const V &attrs, PropSetFlags flags);
// GraphObject interface
public:
void writeQmlHeader(QTextStream &output, int tabLevel) override;
void writeQmlProperties(QTextStream &output, int tabLevel, bool isInRootLevel = false) override;
void writeQmlProperties(const PropertyChangeList &changeList, QTextStream &output, int tabLevel) override;
QString m_referencedMaterial_unresolved;
GraphObject *m_referencedMaterial = nullptr;
// lightmap overrides
QString m_lightmapIndirectMap_unresolved;
QString m_lightmapRadiosityMap_unresolved;
QString m_lightmapShadowMap_unresolved;
// IBL override
QString m_lightProbe_unresolved;
};
class CustomMaterialInstance : public GraphObject
{
public:
enum CustomMaterialPropertyChanges {
SourceChanges = 1 << 0
};
CustomMaterialInstance();
void setProperties(const QXmlStreamAttributes &attrs, PropSetFlags flags) override;
void applyPropertyChanges(const PropertyChangeList &changeList) override;
template<typename V> void setProps(const V &attrs, PropSetFlags flags);
// GraphObject interface
public:
void writeQmlHeader(QTextStream &output, int tabLevel) override;
void writeQmlProperties(QTextStream &output, int tabLevel, bool isInRootLevel = false) override;
void writeQmlProperties(const PropertyChangeList &changeList, QTextStream &output, int tabLevel) override;
QString m_material_unresolved;
bool m_materialIsResolved = false;
QVariantMap m_materialPropertyVals;
PropertyChangeList m_pendingCustomProperties;
// lightmaps
QString m_lightmapIndirectMap_unresolved;
QString m_lightmapRadiosityMap_unresolved;
QString m_lightmapShadowMap_unresolved;
// IBL override
QString m_lightProbe_unresolved;
};
class EffectInstance : public GraphObject
{
public:
enum EffectInstancePropertyChanges {
EyeBallChanges = 1 << 0,
SourceChanges = 1 << 1
};
EffectInstance();
void setProperties(const QXmlStreamAttributes &attrs, PropSetFlags flags) override;
void applyPropertyChanges(const PropertyChangeList &changeList) override;
template<typename V> void setProps(const V &attrs, PropSetFlags flags);
// GraphObject interface
public:
void writeQmlHeader(QTextStream &output, int tabLevel) override;
void writeQmlProperties(QTextStream &output, int tabLevel, bool isInRootLevel = false) override;
void writeQmlProperties(const PropertyChangeList &changeList, QTextStream &output, int tabLevel) override;
void writeQmlFooter(QTextStream &output, int tabLevel) override;
QString m_effect_unresolved;
bool m_effectIsResolved = false;
bool m_eyeballEnabled = true;
PropertyChangeList m_pendingCustomProperties;
};
class BehaviorInstance : public GraphObject
{
public:
enum BehaviorInstancePropertyChanges {
EyeBallChanges = 1 << 0
};
BehaviorInstance();
void setProperties(const QXmlStreamAttributes &attrs, PropSetFlags flags) override;
void applyPropertyChanges(const PropertyChangeList &changeList) override;
template<typename V> void setProps(const V &attrs, PropSetFlags flags);
// GraphObject interface
public:
void writeQmlHeader(QTextStream &output, int tabLevel) override;
void writeQmlProperties(QTextStream &output, int tabLevel, bool isInRootLevel = false) override;
void writeQmlProperties(const PropertyChangeList &changeList, QTextStream &output, int tabLevel) override;
void writeQmlFooter(QTextStream &output, int tabLevel) override;
QString m_behavior_unresolved;
bool m_behaviorIsResolved = false;
bool m_eyeballEnabled = true;
PropertyChangeList m_pendingCustomProperties;
QVariantMap m_behaviorPropertyVals;
};
class AliasNode : public Node
{
public:
AliasNode();
void setProperties(const QXmlStreamAttributes &attrs, PropSetFlags flags) override;
void applyPropertyChanges(const PropertyChangeList &changeList) override;
template<typename V> void setProps(const V &attrs, PropSetFlags flags);
// GraphObject interface
public:
void writeQmlHeader(QTextStream &output, int tabLevel) override;
void writeQmlProperties(QTextStream &output, int tabLevel, bool isInRootLevel = false) override;
void writeQmlProperties(const PropertyChangeList &changeList, QTextStream &output, int tabLevel) override;
QString m_referencedNode_unresolved;
GraphObject *m_referencedNode = nullptr;
};
struct UipPresentationData;
class UipPresentation
{
public:
UipPresentation();
~UipPresentation();
void reset();
enum Rotation {
NoRotation = 0,
Clockwise90,
Clockwise180,
Clockwise270
};
QString sourceFile() const;
void setSourceFile(const QString &s);
QString assetFileName(const QString &xmlFileNameRef, int *part) const;
QString name() const;
void setName(const QString &s);
QString author() const;
QString company() const;
int presentationWidth() const;
int presentationHeight() const;
Rotation presentationRotation() const;
bool maintainAspectRatio() const;
void setAuthor(const QString &author);
void setCompany(const QString &company);
void setPresentationWidth(int w);
void setPresentationHeight(int h);
void setPresentationRotation(Rotation r);
void setMaintainAspectRatio(bool maintain);
Scene *scene() const;
Slide *masterSlide() const;
void setScene(Scene *p);
void setMasterSlide(Slide *p);
bool registerObject(const QByteArray &id, GraphObject *p); // covers both the scene and slide graphs
void unregisterObject(const QByteArray &id);
template <typename T = GraphObject>
const T *object(const QByteArray &id) const { return static_cast<const T *>(getObject(id)); }
template <typename T = GraphObject>
T *object(const QByteArray &id) { return static_cast<T *>(getObject(id)); }
template <typename T = GraphObject>
const T *objectByName(const QString &name) const { return static_cast<const T *>(getObjectByName(name)); }
template <typename T = GraphObject>
T *objectByName(const QString &name) { return static_cast<T *>(getObjectByName(name)); }
void registerImageBuffer(const QString &sourcePath, bool hasTransparency);
typedef QHash<QString, bool> ImageBufferMap;
const ImageBufferMap &imageBuffer() const;
void applyPropertyChanges(const Slide::PropertyChanges &changeList) const;
void applySlidePropertyChanges(Slide *slide) const;
template<typename T> T *newObject(const QByteArray &id)
{
T *obj = new T;
return registerObject(id, obj) ? obj : nullptr; // also sets obj->id
}
GraphObject *newObject(const char *type, const QByteArray &id);
GraphObject *getObject(const QByteArray &id) const;
GraphObject *getObjectByName(const QString &name) const;
QScopedPointer<UipPresentationData> d;
QHash<QString, bool> m_imageTransparencyHash;
friend class UipParser;
};
struct UipPresentationData
{
QString sourceFile;
QString name;
QString author;
QString company;
int presentationWidth = 0;
int presentationHeight = 0;
UipPresentation::Rotation presentationRotation = UipPresentation::NoRotation;
bool maintainAspectRatio = false;
qint64 loadTime = 0;
qint64 meshesLoadTime = 0;
Scene *scene = nullptr;
Slide *masterSlide = nullptr;
QHash<QByteArray, GraphObject *> objects; // node ptrs managed by scene, not owned
// Note: the key here is the sourcePath before it's resolved!
QHash<QString, bool /* hasTransparency */> imageBuffers;
};
QT_END_NAMESPACE
#endif // UIPPRESENTATION_H