/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt3D documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:FDL$
** 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 Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Free Documentation License Usage
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file.  Please review the following information to ensure
** the GNU Free Documentation License version 1.3 requirements
** will be met: http://www.gnu.org/copyleft/fdl.html.
** $QT_END_LICENSE$
**
****************************************************************************/

/*!
    \ingroup qt3d
    \ingroup qt3d::scene
    \since 4.8
    \title Declarative Scenegraph Creation
    \page qt3d-declarative-scenegraph.html
    \keyword Declarative Scenegraph Scene QML Quick
    \brief Basics of scene construction in Qt 3D (QML)

    \l{Qt 3D} implements a scene-graph to make rendering more efficient in terms of
    both computation and space requirements.  Loosely defined, a scene-graph is
    a tree-like structure which is used to represent a graphical scene logically.

    The variant of a scene-graph at the core of Qt 3D's rendering is based on the
    QGLSceneNode class and breaks the contents of the scene down into nodes.

    \section1 Scene Nodes

    Nodes can represent several logical constructs used in rendering.  A single
    node may include one or more of the following:

    \section2 Geometry

    Geometry describes the physical structure of an object in 3D space.  It does
    this in terms of "vertices" which are joined together to form a triangle mesh.

    While many simple 3D objects can be represented by a single scene-node, complex
    objects such as those found in third party asset interchange formats (.obj,
    .3ds, etc) are comprised of multiple geometries stored across a multitude of
    scene-nodes.  This allows for sub-sections of geometry to be animated, rendered
    with different materials and effects, and deconstructed as necessary.

    \section2 Materials/Effects

    Materials and effects describe how the surfaces of the geometry are rendered
    when the scene is drawn.  They may describe simple parameters used to describe
    the object, such as color, texture images, alpha-blending, and other options.

    Alternatively the material may be described by a specific set of shader
    programmes in the GL shader-language which perform a custom implementation of
    rendering.

    Scene nodes can represent one or more materials which are then referenced when
    drawing the geometry of this nodes, or its child nodes.

    \section2 Transformations

    Transformations in the scene-graph describe rotations around the x,y, or z axes,
    as well as scaling, translation, or other custom transformations in 3D space.

    A transformation node contains one or more transformations which are automatically
    applied to the current node, as well as all of its child nodes.

    \section2 Additional Parameters

    Nodes can also contain additional parameters describing debug information, and
    other miscellaneous functions such as whether the node should be rendered, whether
    blending is enabled, and so on.

    Nodes can also represent picking information which is used for selecting 3D items
    with the mouse.

    \section1 Scene Graphs in C++

    When writing a C++ application the user can create one or more QGLSceneNode based
    scene-graphs which can then be rendered each frame by calling the QGLSceneNode::draw()
    function.

    Scene graphs can be constructed manually by the user one node at a time, or by using
    the QGLBuilder to assemble geometries.  The Qt 3D model loader plug-ins also
    create individual scene-graphs which can then be used separately, or inserted into
    an existing scene-graph.

    Model-loader scene-graphs represent all of the geometries, transformations, materials,
    and other elements, which are described in the model interchange file.  These nodes can
    be manipulated at the code-level at any time to modify or adjust the model as needed.

    When the scenegraph is created, Qt 3D optimises the drawing order of the scenegraph
    somewhat so that all materials of the same type are drawn first, and so on.  These
    optimisations reduce the amount of context switching required by OpenGL when drawing,
    and can substantially improve performance in complicated scenes.

    \section1 QML 3D Scene Graphs in Qt 3D for Qt 4.x

    While C++ allows users to manually construct and manipulate scene-graphs, Qt 3D's
    extension into QtQuick does not currently allow the same degree of flexibility.

    Qt 3D for Qt4.x generally used a single small scene-graph for each Item3D.  These would
    only used shared geometry information if multiple Item3D instances referenced a single
    Mesh instance.  While sufficient for simple 3D use cases, this method is inherently
    inefficient for drawing large/complex scenes.  Without a single scenegraph we cannot
    optimise the entire 3D scene.

    Likewise in this implementation we have only a very limited ability to manipulate the
    content of a model file/meh instance.  In Qt4.x users are able to specify that an
    Item3D contains a specific sub-node of a mesh's scenegraph.  This removes the instance
    from the tree in the graph which owns it, thereby changing the structure of the
    originating model.

    This limits our ability to implement specific use-cases.

    These problems are addressed in Qt5.

    \section1 QML 3D Scene Graphs in Qt 3D for Qt 5

    In Qt5 the QML implementation of Qt 3D substantially improves this situation.  Instead
    of creating individual scene-graphs for each Mesh/Item3D, the user now creates a single
    holistic scenegraph for each viewport.  Addition of Item3D elements to a scene creates a
    hierarchy of scene-graph branches which are then optimised and drawn in a single call for
    the viewport.

    Components of a mesh can now be accessed with specific QQuickMesh functions which are
    exposed to QML.

    The sections below describe the various scenarios in which a user may wish to use sub-components
    of a model's scenegraph.


    \section2 Scenario 1: Simple Single-Model Rendering

    This displays the model "as is" with no changes or alterations.

    \code
    Mesh {
            id: model
            source: "bike.3ds"
    }

    Item3D {
            mesh: model
    }
    \endcode

    The output for this, as well as the scenegraphs it produces, can be seen below:

    \image scenegraph_scenario1.png

    \section2 Scenario 2: Use a Sub-tree of the Model

    This displays a sub-section of the model - in this case the wheel.

    \code
    Mesh {
            id: model
            source: "bike.3ds"
    }

    Item3D {
            //Get just the subtree starting at wheel1
            mesh:  Mesh {scene: model.get(bike.body.wheel1)}
    }
    \endcode

    The output for this, as well as the scenegraphs it produces, can be seen below:

    \image scenegraph_scenario2.png

    \section2 Scenario 3: Use an Intermediate Set of Model Nodes

    This displays an intermediate (sub)section of the graph but excludes specific nodes/
    subtrees.

    \code
    Mesh {
            id: model
            source: "bike.3ds"

    }

    Item3D {
            //get the model but exclude the sub-branch beginning at wheel1.
            mesh: Mesh {model: model.except(bike.body.wheel1)}
    }
    \endcode

    The output for this, as well as the scenegraphs it produces, can be seen below:

    \image scenegraph_scenario3.png

    \section2 Scenario 4: Transform the Model, and a Sub-tree of the Model, Independently

    This displays the original model in one Item3D and a sub-tree of the model in another.
    The second item applies a transform to the item, which leaves the original model unchanged.


    \code
    Mesh {
            id: model
            source: "bike.3ds"
    }

    Item3D {
            mesh: model
    }

    Item3D {
            mesh: Mesh{scene: model.get(bike.body.wheel1)}
            x: -5
            z: 5
    }
    \endcode

    The output for this, as well as the scenegraphs it produces, can be seen below:

    \image scenegraph_scenario4.png

    \section2 Scenario 5: Use a Model, and a set materials on a Sub-tree of the Model, Independently

    This displays the original model in one Item3D and a sub-tree of the model in another.
    The second item applies an effect to the item, which leaves the original model unchanged.


    \code
    Mesh {
            id: model
            source: "bike.3ds"
    }

    Item3D {
            mesh: model
    }

    Item3D {
            mesh: Mesh{scene: model.get(bike.body.wheel1)}
            effect: Effect {color: #00FF00}
    }
    \endcode

    The output for this, as well as the scenegraphs it produces, can be seen below:

    \image scenegraph_scenario5.png

    \section2 Scenario 6: Set Model materials, and use a Sub-tree of the Model, Independently

    This displays an intermediate (sub)section of the graph to which an effect has been
    applied but excludes specific nodes subtrees.  In a second Item3D it displays a sub-node/
    tree which is not affected by the effect on the first item.

    \code
    Mesh {
            id: model
            source: "car.3ds"
    }

    Item3D {
            mesh: Mesh{scene: model.except(bike.body.wheel1)}
            effect: Effect {color: #FF0000}
    }

    Item3D {
            mesh: model.get(bike.body.wheel1)
    }
    \endcode

    The output for this, as well as the scenegraphs it produces, can be seen below:

    \image scenegraph_scenario6.png

    \section2 Scenario 7: Display Model Section, and Transform a Sub-tree of the Model, Independently

    This displays an intermediate (sub)section of the graph but excludes specific nodes/
    subtrees.  In a second Item3D it displays a transformed sub-node/tree which does not affect the
    first item.

    \code
    Mesh {
            id: model
            source: "car.3ds"
    }

    Item3D {
            mesh: Mesh{scene: model.except(bike.body.wheel1)}
    }

    Item3D {
            mesh: Mesh{scene: model.get(bike.body.wheel1)}
            y: -2
    }
    \endcode

    The output for this, as well as the scenegraphs it produces, can be seen below:

    \image scenegraph_scenario7.png

    \section2 Scenario 8: Use Unconnected Sub-nodes of a Tree

    This displays disparate subtrees of the model as a single item.

    \code
    Mesh {
            id: model
            source: "car.3ds"
    }

    Item3D {
            mesh: Mesh{scene: model.get([car.body.wheel1, car.body.wheel2])}
    }
    \endcode

    The output for this, as well as the scenegraphs it produces, can be seen below:

    \image scenegraph_scenario8.png
*/
