/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCanvas3D module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** 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.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
**   * Redistributions of source code must retain the above copyright
**     notice, this list of conditions and the following disclaimer.
**   * Redistributions in binary form must reproduce the above copyright
**     notice, this list of conditions and the following disclaimer in
**     the documentation and/or other materials provided with the
**     distribution.
**   * Neither the name of The Qt Company Ltd nor the names of its
**     contributors may be used to endorse or promote products derived
**     from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/

/*!
    \example threejs/oneqt
    \since QtCanvas3D 1.0
    \title One Qt Example
    \ingroup qtcanvas3d-examples
    \brief Demonstrates combining Qt Quick and three.js rendering.

    One Qt example demonstrates how to implement a simple QML 3D control that combines the use
    of \c{three.js} library-based Canvas3D rendering with Qt Quick 2D elements. The example shows
    a view with various benefits of using Qt with related images picked from
    \l {http://qt.io} {http://qt.io}. The images are displayed on the side of a spinning 3D cube
    that spins to show the correct image when the tabs at the top of the application are selected.
    You can also use swipe gestures to spin the cube to navigate between the tabs. The 3D cube
    control has been implemented as a simple QML type that internaly uses \c{three.js} library and
    \l{Qt Canvas 3D}.

    \image oneqt-example.png

    \section1 Main QML File

    In \l{threejs/oneqt/oneqt.qml}{oneqt.qml}, we build the 2D content as normal in QML.
    Then we add a custom \c {ImageCube} type into the scene behind the text elements.
    This custom type, implemented using \c{three.js} library, handles the painting of the 3D
    cube.

    \snippet threejs/oneqt/oneqt.qml 0
    \dots

    \note The \c {ImageCube} 3D UI component can be created and anchored just like any other
    QML type.

    \section1 The Custom 3D QML Control

    The \l{threejs/oneqt/ImageCube.qml}{ImageCube.qml} takes six images that it loads
    and places to the sides of the cube. In addition, the type has a state that defines which of
    these images are visible and a \c {backgroundColor} property that is used when painting the 3D
    cube. The \c {angleOffset} property can be used to adjust the cube's direction when displaying
    the selected image. In this example the cube component sits on the right edge of the screen so
    we twist it slightly to the left so that it appears to be facing the rest of the content.
    This angle is also used by the 3D light so that the light always illuminates the selected face
    of the cube.

    \snippet threejs/oneqt/ImageCube.qml 0
    \dots

    The custom type defines six states, one for each side of the cube along with the x-, y-, and
    z-rotations, that must be set to show the face of the cube corresponding to the state.

    \snippet threejs/oneqt/ImageCube.qml 1
    \dots

    We use \c {RotationAnimation} to animate the transition between angles. It enables us to get
    smooth transitions between different cube orientations and to always rotate the cube along the
    shortest possible angle distance.

    \snippet threejs/oneqt/ImageCube.qml 2
    \dots

    We call the JavaScript code that uses \c{three.js} to do the rendering of the cube, calling
    it on the \c{initializeGL}, \c{paintGL}, and \c{resizeGL} signals.

    \snippet threejs/oneqt/ImageCube.qml 3

    \section1 The JavaScript Code

    The JavaScript side of the implementation,
    \l{threejs/oneqt/imagecube.js}{imagecube.js},
    is done using a version of \c{three.js} that is ported for \l{Qt Canvas 3D}:
    \l{https://github.com/tronlec/three.js}{three.js}.

    In \l{threejs/oneqt/imagecube.js}{imagecube.js}, we start by creating the camera and
    the scene that contains all the rest of the \c{three.js} objects.

    \snippet threejs/oneqt/imagecube.js 0
    \dots

    Then we start the asynchronous loading of the textures and create a material array for the sides
    of the cube (note that the cube needs 12 materials as each side consists of two triangles).

    \snippet threejs/oneqt/imagecube.js 1
    \dots

    We then create the needed geometry as \c {BoxGeometry} binding the created materials to the
    faces of the cube. We then create a \c {MeshFaceMaterial} from the array of materials.

    \snippet threejs/oneqt/imagecube.js 2

    Finally we create the cube mesh from the geometry and material, position it, and add it
    to the 3D scene.

    \snippet threejs/oneqt/imagecube.js 3

    Next we create and add some lights to the scene. \c{AmbientLight} defines the surrounding light
    amount and the directional light is positioned so that it highlights the face of the cube that
    is currently selected.

    \snippet threejs/oneqt/imagecube.js 6

    Final step in the initialization phase is to create the \c {Canvas3D} renderer and set the
    initial size and clear color (color of the background) to the renderer.

    \snippet threejs/oneqt/imagecube.js 4

    When we need to render the scene in response to the \c{paintGL} signal from Canvas3D, we just
    copy the current rotation values from the QML side to the cube mesh in the \c{paintGL()} method.

    \snippet threejs/oneqt/imagecube.js 5

    For more information on how to use \c {three.js} the documentation is available here:
    \l{http://threejs.org/docs/}{three.js/docs}
*/
