summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2017-10-05 20:34:44 +0200
committerLiang Qi <liang.qi@qt.io>2017-10-05 20:47:59 +0200
commit8e67fb1f148b2f3c795d230faad7aee20389878a (patch)
tree34358c0ee9ab4816d20d58d84bdab20093b1d423
parentba5bc93b95d28a28a72e60281f765a6f031129a5 (diff)
parentd4fb24c0871320667640f100b743f34f702db6cf (diff)
Merge remote-tracking branch 'origin/5.10' into dev
Conflicts: src/animation/backend/channelmapper_p.h Change-Id: I4e0f59c6648925ba45d30ccc2405524a9e901a0e
-rw-r--r--examples/qt3d/advancedcustommaterial/shaders/es2/water.frag24
-rw-r--r--examples/qt3d/advancedcustommaterial/shaders/es2/water.vert25
-rw-r--r--examples/qt3d/advancedcustommaterial/shaders/gl3/water.frag23
-rw-r--r--examples/qt3d/advancedcustommaterial/shaders/gl3/water.vert25
-rw-r--r--examples/qt3d/phong-cubes/CubeEntity.qml81
-rw-r--r--examples/qt3d/phong-cubes/main.cpp63
-rw-r--r--examples/qt3d/phong-cubes/main.qml152
-rw-r--r--examples/qt3d/phong-cubes/phong-cubes.pro18
-rw-r--r--examples/qt3d/phong-cubes/phong-cubes.qrc6
-rw-r--r--examples/qt3d/qt3d.pro3
-rw-r--r--src/animation/backend/animationutils.cpp237
-rw-r--r--src/animation/backend/animationutils_p.h19
-rw-r--r--src/animation/backend/channelmapper.cpp20
-rw-r--r--src/animation/backend/channelmapper_p.h12
-rw-r--r--src/animation/backend/channelmapping.cpp6
-rw-r--r--src/animation/backend/channelmapping_p.h1
-rw-r--r--src/animation/backend/clipanimator.cpp1
-rw-r--r--src/animation/backend/clipanimator_p.h4
-rw-r--r--src/animation/backend/clipblendvalue_p.h2
-rw-r--r--src/animation/backend/evaluateclipanimatorjob.cpp11
-rw-r--r--src/animation/backend/findrunningclipanimatorsjob.cpp41
-rw-r--r--src/animation/backend/findrunningclipanimatorsjob_p.h10
-rw-r--r--src/animation/backend/skeleton.cpp9
-rw-r--r--src/animation/backend/skeleton_p.h17
-rw-r--r--src/animation/frontend/qanimationaspect.cpp1
-rw-r--r--src/animation/frontend/qblendedclipanimator.cpp2
-rw-r--r--src/core/transforms/sqt_p.h1
-rw-r--r--src/extras/3dtext/qextrudedtextgeometry.cpp4
-rw-r--r--src/extras/defaults/defaults.pri3
-rw-r--r--src/extras/defaults/qabstractcameracontroller.cpp436
-rw-r--r--src/extras/defaults/qabstractcameracontroller.h126
-rw-r--r--src/extras/defaults/qabstractcameracontroller_p.h141
-rw-r--r--src/extras/defaults/qdiffusemapmaterial.cpp4
-rw-r--r--src/extras/defaults/qdiffusespecularmapmaterial.cpp4
-rw-r--r--src/extras/defaults/qfirstpersoncameracontroller.cpp305
-rw-r--r--src/extras/defaults/qfirstpersoncameracontroller.h39
-rw-r--r--src/extras/defaults/qfirstpersoncameracontroller_p.h152
-rw-r--r--src/extras/defaults/qmetalroughmaterial.cpp30
-rw-r--r--src/extras/defaults/qmetalroughmaterial.h4
-rw-r--r--src/extras/defaults/qmetalroughmaterial_p.h3
-rw-r--r--src/extras/defaults/qnormaldiffusemapalphamaterial.cpp8
-rw-r--r--src/extras/defaults/qnormaldiffusemapmaterial.cpp4
-rw-r--r--src/extras/defaults/qnormaldiffusespecularmapmaterial.cpp4
-rw-r--r--src/extras/defaults/qorbitcameracontroller.cpp348
-rw-r--r--src/extras/defaults/qorbitcameracontroller.h28
-rw-r--r--src/extras/defaults/qorbitcameracontroller_p.h75
-rw-r--r--src/extras/defaults/qphongalphamaterial.cpp32
-rw-r--r--src/extras/defaults/qphongalphamaterial_p.h2
-rw-r--r--src/extras/defaults/qphongmaterial.cpp5
-rw-r--r--src/extras/extras.qrc17
-rw-r--r--src/extras/geometries/qconegeometry.cpp4
-rw-r--r--src/extras/geometries/qcuboidgeometry.cpp4
-rw-r--r--src/extras/geometries/qcylindergeometry.cpp4
-rw-r--r--src/extras/geometries/qplanegeometry.cpp4
-rw-r--r--src/extras/geometries/qspheregeometry.cpp4
-rw-r--r--src/extras/geometries/qtorusgeometry.cpp4
-rw-r--r--src/extras/shaders/es2/coordinatesystems.inc87
-rw-r--r--src/extras/shaders/es2/default.vert80
-rw-r--r--src/extras/shaders/es2/diffusemap.frag15
-rw-r--r--src/extras/shaders/es2/diffusemap.vert22
-rw-r--r--src/extras/shaders/es2/diffusespecularmap.frag15
-rw-r--r--src/extras/shaders/es2/light.inc.frag185
-rw-r--r--src/extras/shaders/es2/light.inc.frag100205
-rw-r--r--src/extras/shaders/es2/normaldiffusemap.frag23
-rw-r--r--src/extras/shaders/es2/normaldiffusemap.vert38
-rw-r--r--src/extras/shaders/es2/normaldiffusemapalpha.frag32
-rw-r--r--src/extras/shaders/es2/normaldiffusespecularmap.frag21
-rw-r--r--src/extras/shaders/es2/pervertexcolor.frag11
-rw-r--r--src/extras/shaders/es2/pervertexcolor.vert4
-rw-r--r--src/extras/shaders/es2/phong.frag13
-rw-r--r--src/extras/shaders/es2/phong.inc.frag128
-rw-r--r--src/extras/shaders/es2/phong.inc.frag100142
-rw-r--r--src/extras/shaders/es2/phong.vert17
-rw-r--r--src/extras/shaders/es2/phongalpha.frag22
-rw-r--r--src/extras/shaders/gl3/default.vert (renamed from src/extras/shaders/gl3/metalrough.vert)13
-rw-r--r--src/extras/shaders/gl3/diffusemap.frag15
-rw-r--r--src/extras/shaders/gl3/diffusemap.vert24
-rw-r--r--src/extras/shaders/gl3/diffusespecularmap.frag15
-rw-r--r--src/extras/shaders/gl3/light.inc.frag197
-rw-r--r--src/extras/shaders/gl3/normaldiffusemap.frag23
-rw-r--r--src/extras/shaders/gl3/normaldiffusemap.vert47
-rw-r--r--src/extras/shaders/gl3/normaldiffusemapalpha.frag34
-rw-r--r--src/extras/shaders/gl3/normaldiffusespecularmap.frag24
-rw-r--r--src/extras/shaders/gl3/pervertexcolor.frag11
-rw-r--r--src/extras/shaders/gl3/pervertexcolor.vert4
-rw-r--r--src/extras/shaders/gl3/phong.frag13
-rw-r--r--src/extras/shaders/gl3/phong.inc.frag138
-rw-r--r--src/extras/shaders/gl3/phong.vert19
-rw-r--r--src/extras/shaders/gl3/phongalpha.frag24
-rw-r--r--src/extras/text/distancefieldtextrenderer.cpp4
-rw-r--r--src/plugins/geometryloaders/default/objgeometryloader.cpp2
-rw-r--r--src/plugins/sceneparsers/assimp/assimpimporter.cpp6
-rw-r--r--src/plugins/sceneparsers/gltf/gltfimporter.cpp34
-rw-r--r--src/plugins/sceneparsers/gltfexport/gltfexporter.cpp41
-rw-r--r--src/quick3d/quick3drender/items/quick3dbuffer.cpp2
-rw-r--r--src/render/backend/renderer.cpp6
-rw-r--r--src/render/backend/renderview.cpp3
-rw-r--r--src/render/backend/renderview_p.h1
-rw-r--r--src/render/frontend/qitemmodelbuffer.cpp2
-rw-r--r--src/render/frontend/qrendersettings.cpp5
-rw-r--r--src/render/geometry/buffer.cpp6
-rw-r--r--src/render/geometry/buffer_p.h2
-rw-r--r--src/render/geometry/qbuffer.cpp17
-rw-r--r--src/render/geometry/qbuffer.h7
-rw-r--r--src/render/geometry/qbuffer_p.h1
-rw-r--r--src/render/geometry/skeleton.cpp7
-rw-r--r--src/render/graphicshelpers/graphicscontext.cpp45
-rw-r--r--src/render/graphicshelpers/graphicscontext_p.h6
-rw-r--r--src/render/materialsystem/prototypes/default.json45
-rw-r--r--src/render/texture/gltexture.cpp1
-rw-r--r--tests/auto/animation/animation.pro3
-rw-r--r--tests/auto/animation/animationutils/tst_animationutils.cpp279
-rw-r--r--tests/auto/animation/channelmapper/tst_channelmapper.cpp36
-rw-r--r--tests/auto/animation/clipblendvalue/tst_clipblendvalue.cpp6
-rw-r--r--tests/auto/animation/findrunningclipanimatorsjob/clip1.json114
-rw-r--r--tests/auto/animation/findrunningclipanimatorsjob/findrunningclipanimatorsjob.pro15
-rw-r--r--tests/auto/animation/findrunningclipanimatorsjob/findrunningclipanimatorsjob.qrc5
-rw-r--r--tests/auto/animation/findrunningclipanimatorsjob/tst_findrunningclipanimatorsjob.cpp204
-rw-r--r--tests/auto/render/buffer/tst_buffer.cpp25
-rw-r--r--tests/auto/render/meshfunctors/tst_meshfunctors.cpp44
-rw-r--r--tests/auto/render/qbuffer/tst_qbuffer.cpp1
-rw-r--r--tests/manual/skinned-mesh/DefaultSceneEntity.qml4
-rw-r--r--tests/manual/skinned-mesh/SkinnedEntity.qml1
-rw-r--r--tests/manual/skinned-mesh/SkinnedPbrEffect.qml3
-rw-r--r--tests/manual/skinned-mesh/jump.json4571
-rw-r--r--tests/manual/skinned-mesh/main.cpp2
-rw-r--r--tests/manual/skinned-mesh/main.qml143
-rw-r--r--tests/manual/skinned-mesh/skinned-mesh.pro2
-rw-r--r--tests/manual/skinned-mesh/skinned-mesh.qrc1
129 files changed, 7694 insertions, 2281 deletions
diff --git a/examples/qt3d/advancedcustommaterial/shaders/es2/water.frag b/examples/qt3d/advancedcustommaterial/shaders/es2/water.frag
index ea54a87f1..f471504fa 100644
--- a/examples/qt3d/advancedcustommaterial/shaders/es2/water.frag
+++ b/examples/qt3d/advancedcustommaterial/shaders/es2/water.frag
@@ -1,6 +1,8 @@
#define FP highp
varying FP vec3 worldPosition;
+varying FP vec3 worldNormal;
+varying FP vec4 worldTangent;
varying FP vec2 texCoord;
varying FP vec2 waveTexCoord;
varying FP vec2 movtexCoord;
@@ -9,7 +11,6 @@ varying FP vec2 skyTexCoord;
varying FP vec3 vpos;
-varying FP mat3 tangentMatrix;
varying FP vec3 color;
uniform FP sampler2D diffuseTexture;
@@ -23,13 +24,13 @@ uniform FP float offsetx;
uniform FP float offsety;
uniform FP float specularity;
uniform FP float waveStrenght;
-uniform FP vec3 ka;
-uniform FP vec3 specularColor;
+uniform FP vec4 ka;
uniform FP float shininess;
uniform FP float normalAmount;
uniform FP vec3 eyePosition;
-#pragma include light.inc.frag
+#pragma include phong.inc.frag
+#pragma include coordinatesystems.inc
void main()
{
@@ -50,21 +51,24 @@ void main()
// 2 Animated Layers of specularTexture mixed with the newCoord
FP vec4 specularTextureColor = texture2D( specularTexture, multexCoord+newCoord) + (texture2D( specularTexture, movtexCoord+newCoord ));
// 2 Animated Layers of normalTexture mixed with the newCoord
- FP vec3 normal = normalAmount * texture2D( normalTexture, movtexCoord+newCoord ).rgb - vec3( 1.0 )+(normalAmount * texture2D( normalTexture, multexCoord+newCoord ).rgb - vec3( 1.0 ));
+ FP vec3 tNormal = normalAmount * texture2D( normalTexture, movtexCoord+newCoord ).rgb - vec3( 1.0 )+(normalAmount * texture2D( normalTexture, multexCoord+newCoord ).rgb - vec3( 1.0 ));
// Animated skyTexture layer
FP vec4 skycolor = texture2D(skyTexture, skyTexCoord);
skycolor = skycolor * 0.4;
//Animated foamTexture layer
FP vec4 foamTextureColor = texture2D(foamTexture, texCoord);
- // Calculate the lighting model, keeping the specular component separate
- FP vec3 diffuseColor, specularColor;
- adsModelNormalMapped(worldPosition, normal, eyePosition, shininess, tangentMatrix, diffuseColor, specularColor);
+ FP mat3 tangentMatrix = calcWorldSpaceToTangentSpaceMatrix(worldNormal, worldTangent);
+ FP mat3 invertTangentMatrix = transpose(tangentMatrix);
- // Combine final fragment color
- FP vec4 outputColor = vec4(((skycolor.rgb + ka + diffuseTextureColor.rgb * (diffuseColor))+(specularColor * specularTextureColor.a*specularity)), vpos.y );
+ FP vec3 wNormal = normalize(invertTangentMatrix * tNormal);
+ FP vec3 worldView = normalize(eyePosition - worldPosition);
+ FP vec4 diffuse = vec4(diffuseTextureColor.rgb, vpos.y);
+ FP vec4 specular = vec4(specularTextureColor.a*specularity);
+ FP vec4 outputColor = phongFunction(ka, diffuse, specular, shininess, worldPosition, worldView, wNormal);
+ outputColor += vec4(skycolor.rgb, vpos.y);
outputColor += (foamTextureColor.rgba*vpos.y);
gl_FragColor = vec4(outputColor.rgb,1.0);
diff --git a/examples/qt3d/advancedcustommaterial/shaders/es2/water.vert b/examples/qt3d/advancedcustommaterial/shaders/es2/water.vert
index 1a7d46a46..76dd3f8c0 100644
--- a/examples/qt3d/advancedcustommaterial/shaders/es2/water.vert
+++ b/examples/qt3d/advancedcustommaterial/shaders/es2/water.vert
@@ -6,12 +6,13 @@ attribute FP vec2 vertexTexCoord;
attribute FP vec4 vertexTangent;
varying FP vec3 worldPosition;
+varying FP vec3 worldNormal;
+varying FP vec4 worldTangent;
varying FP vec2 texCoord;
varying FP vec2 movtexCoord;
varying FP vec2 multexCoord;
varying FP vec2 waveTexCoord;
varying FP vec2 skyTexCoord;
-varying FP mat3 tangentMatrix;
varying FP vec3 vpos;
uniform FP mat4 modelMatrix;
@@ -42,25 +43,9 @@ void main()
// Transform position, normal, and tangent to world coords
worldPosition = vec3(modelMatrix * vec4(vertexPosition, 1.0));
- FP vec3 normal = normalize(modelNormalMatrix * vertexNormal);
- FP vec3 tangent = normalize(vec3(modelMatrix * vec4(vertexTangent.xyz, 0.0)));
-
- // Make the tangent truly orthogonal to the normal by using Gram-Schmidt.
- // This allows to build the tangentMatrix below by simply transposing the
- // tangent -> world space matrix (which would now be orthogonal)
- tangent = normalize(tangent - dot(tangent, normal) * normal);
-
- // Calculate binormal vector. No "real" need to renormalize it,
- // as built by crossing two normal vectors.
- // To orient the binormal correctly, use the fourth coordinate of the tangent,
- // which is +1 for a right hand system, and -1 for a left hand system.
- FP vec3 binormal = cross(normal, tangent) * vertexTangent.w;
-
- // Construct matrix to transform from eye coords to tangent space
- tangentMatrix = mat3(
- tangent.x, binormal.x, normal.x,
- tangent.y, binormal.y, normal.y,
- tangent.z, binormal.z, normal.z);
+ worldNormal = normalize(modelNormalMatrix * vertexNormal);
+ worldTangent.xyz = normalize(vec3(modelMatrix * vec4(vertexTangent.xyz, 0.0)));
+ worldTangent.w = vertexTangent.w;
// Calculate animated vertex positions
diff --git a/examples/qt3d/advancedcustommaterial/shaders/gl3/water.frag b/examples/qt3d/advancedcustommaterial/shaders/gl3/water.frag
index 9657cc63a..6e9722314 100644
--- a/examples/qt3d/advancedcustommaterial/shaders/gl3/water.frag
+++ b/examples/qt3d/advancedcustommaterial/shaders/gl3/water.frag
@@ -1,6 +1,8 @@
#version 150 core
in vec3 worldPosition;
+in vec3 worldNormal;
+in vec4 worldTangent;
in vec2 texCoord;
in vec2 waveTexCoord;
in vec2 movtexCoord;
@@ -9,7 +11,6 @@ in vec2 skyTexCoord;
in vec3 vpos;
-in mat3 tangentMatrix;
in vec3 color;
uniform sampler2D diffuseTexture;
@@ -23,7 +24,7 @@ uniform float offsetx;
uniform float offsety;
uniform float specularity;
uniform float waveStrenght;
-uniform vec3 ka;
+uniform vec4 ka;
uniform vec3 specularColor;
uniform float shininess;
uniform float normalAmount;
@@ -31,7 +32,8 @@ uniform vec3 eyePosition;
out vec4 fragColor;
-#pragma include light.inc.frag
+#pragma include phong.inc.frag
+#pragma include coordinatesystems.inc
void main()
{
@@ -52,21 +54,24 @@ void main()
// 2 Animated Layers of specularTexture mixed with the newCoord
vec4 specularTextureColor = texture( specularTexture, multexCoord+newCoord) + (texture( specularTexture, movtexCoord+newCoord ));
// 2 Animated Layers of normalTexture mixed with the newCoord
- vec3 normal = normalAmount * texture( normalTexture, movtexCoord+newCoord ).rgb - vec3( 1.0 )+(normalAmount * texture( normalTexture, multexCoord+newCoord ).rgb - vec3( 1.0 ));
+ vec3 tNormal = normalAmount * texture( normalTexture, movtexCoord+newCoord ).rgb - vec3( 1.0 )+(normalAmount * texture( normalTexture, multexCoord+newCoord ).rgb - vec3( 1.0 ));
// Animated skyTexture layer
vec4 skycolor = texture(skyTexture, skyTexCoord);
skycolor = skycolor * 0.4;
//Animated foamTexture layer
vec4 foamTextureColor = texture(foamTexture, texCoord);
- // Calculate the lighting model, keeping the specular component separate
- vec3 diffuseColor, specularColor;
- adsModelNormalMapped(worldPosition, normal, eyePosition, shininess, tangentMatrix, diffuseColor, specularColor);
+ mat3 tangentMatrix = calcWorldSpaceToTangentSpaceMatrix(worldNormal, worldTangent);
+ mat3 invertTangentMatrix = transpose(tangentMatrix);
- // Combine final fragment color
- vec4 outputColor = vec4(((skycolor.rgb + ka + diffuseTextureColor.rgb * (diffuseColor))+(specularColor * specularTextureColor.a*specularity)), vpos.y );
+ vec3 wNormal = normalize(invertTangentMatrix * tNormal);
+ vec3 worldView = normalize(eyePosition - worldPosition);
+ vec4 diffuse = vec4(diffuseTextureColor.rgb, vpos.y);
+ vec4 specular = vec4(specularTextureColor.a*specularity);
+ vec4 outputColor = phongFunction(ka, diffuse, specular, shininess, worldPosition, worldView, wNormal);
+ outputColor += vec4(skycolor.rgb, vpos.y);
outputColor += (foamTextureColor.rgba*vpos.y);
fragColor = vec4(outputColor.rgb,1.0);
diff --git a/examples/qt3d/advancedcustommaterial/shaders/gl3/water.vert b/examples/qt3d/advancedcustommaterial/shaders/gl3/water.vert
index a4ddcf62b..3af37e9a5 100644
--- a/examples/qt3d/advancedcustommaterial/shaders/gl3/water.vert
+++ b/examples/qt3d/advancedcustommaterial/shaders/gl3/water.vert
@@ -6,12 +6,13 @@ in vec2 vertexTexCoord;
in vec4 vertexTangent;
out vec3 worldPosition;
+out vec3 worldNormal;
+out vec4 worldTangent;
out vec2 texCoord;
out vec2 movtexCoord;
out vec2 multexCoord;
out vec2 waveTexCoord;
out vec2 skyTexCoord;
-out mat3 tangentMatrix;
out vec3 vpos;
uniform mat4 modelMatrix;
@@ -42,25 +43,9 @@ void main()
// Transform position, normal, and tangent to world coords
worldPosition = vec3(modelMatrix * vec4(vertexPosition, 1.0));
- vec3 normal = normalize(modelNormalMatrix * vertexNormal);
- vec3 tangent = normalize(vec3(modelMatrix * vec4(vertexTangent.xyz, 0.0)));
-
- // Make the tangent truly orthogonal to the normal by using Gram-Schmidt.
- // This allows to build the tangentMatrix below by simply transposing the
- // tangent -> world space matrix (which would now be orthogonal)
- tangent = normalize(tangent - dot(tangent, normal) * normal);
-
- // Calculate binormal vector. No "real" need to renormalize it,
- // as built by crossing two normal vectors.
- // To orient the binormal correctly, use the fourth coordinate of the tangent,
- // which is +1 for a right hand system, and -1 for a left hand system.
- vec3 binormal = cross(normal, tangent) * vertexTangent.w;
-
- // Construct matrix to transform from eye coords to tangent space
- tangentMatrix = mat3(
- tangent.x, binormal.x, normal.x,
- tangent.y, binormal.y, normal.y,
- tangent.z, binormal.z, normal.z);
+ worldNormal = normalize(modelNormalMatrix * vertexNormal);
+ worldTangent.xyz = normalize(vec3(modelMatrix * vec4(vertexTangent.xyz, 0.0)));
+ worldTangent.w = vertexTangent.w;
// Calculate animated vertex positions
diff --git a/examples/qt3d/phong-cubes/CubeEntity.qml b/examples/qt3d/phong-cubes/CubeEntity.qml
new file mode 100644
index 000000000..558f53327
--- /dev/null
+++ b/examples/qt3d/phong-cubes/CubeEntity.qml
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D 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$
+**
+****************************************************************************/
+
+import QtQuick 2.0 as Quick
+import Qt3D.Core 2.0
+import Qt3D.Render 2.0
+import Qt3D.Extras 2.0
+
+Entity {
+ id: root
+ property vector3d position: Qt.vector3d()
+ property Material material
+
+ components: [mesh, material, transform]
+
+ CuboidMesh {
+ id: mesh
+ xExtent: 0.5
+ yExtent: xExtent
+ zExtent: xExtent
+ }
+
+ Transform {
+ id: transform
+ translation: root.position
+ rotationZ: 45
+
+ Quick.NumberAnimation on rotationY {
+ from: 0; to: 360
+ loops: Quick.Animation.Infinite
+ duration: 5000
+ }
+ }
+}
diff --git a/examples/qt3d/phong-cubes/main.cpp b/examples/qt3d/phong-cubes/main.cpp
new file mode 100644
index 000000000..dba6e0bff
--- /dev/null
+++ b/examples/qt3d/phong-cubes/main.cpp
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D 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$
+**
+****************************************************************************/
+
+#include <Qt3DQuickExtras/qt3dquickwindow.h>
+#include <QGuiApplication>
+
+int main(int argc, char* argv[])
+{
+ QGuiApplication app(argc, argv);
+ Qt3DExtras::Quick::Qt3DQuickWindow view;
+
+ view.setSource(QUrl("qrc:/main.qml"));
+ view.show();
+
+ return app.exec();
+}
diff --git a/examples/qt3d/phong-cubes/main.qml b/examples/qt3d/phong-cubes/main.qml
new file mode 100644
index 000000000..0e067fdad
--- /dev/null
+++ b/examples/qt3d/phong-cubes/main.qml
@@ -0,0 +1,152 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D 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$
+**
+****************************************************************************/
+
+import Qt3D.Core 2.0
+import Qt3D.Render 2.0
+import Qt3D.Input 2.0
+import Qt3D.Extras 2.0
+
+Entity {
+ components: [
+ RenderSettings {
+ activeFrameGraph: ForwardRenderer {
+ clearColor: "white"
+ camera: mainCamera
+ }
+ },
+ InputSettings { }
+ ]
+
+ Camera {
+ id: mainCamera
+ position: Qt.vector3d(0.0, 0.0, 7.0)
+ upVector: Qt.vector3d(0.0, 1.0, 0.0)
+ viewCenter: Qt.vector3d(0.0, 0.0, 0.0)
+ }
+
+ FirstPersonCameraController {
+ camera: mainCamera
+ }
+
+ Entity {
+ components: [
+ PointLight {},
+ Transform { translation: mainCamera.position }
+ ]
+ }
+
+ CubeEntity {
+ position: Qt.vector3d(-1, 1, 0)
+ material: PhongMaterial {}
+ }
+
+ CubeEntity {
+ position: Qt.vector3d(0, 1, 0)
+ material: DiffuseMapMaterial {
+ diffuse: TextureLoader { source: "qrc:/assets/textures/pattern_09/diffuse.webp" }
+ }
+ }
+
+ CubeEntity {
+ position: Qt.vector3d(1, 1, 0)
+ material: DiffuseSpecularMapMaterial {
+ diffuse: TextureLoader { source: "qrc:/assets/textures/pattern_09/diffuse.webp" }
+ specular: TextureLoader { source: "qrc:/assets/textures/pattern_09/specular.webp" }
+ }
+ }
+
+ CubeEntity {
+ position: Qt.vector3d(-1, 0, 0)
+ material: PhongAlphaMaterial {}
+ }
+
+ CubeEntity {
+ position: Qt.vector3d(0, 0, 0)
+ material: NormalDiffuseMapMaterial {
+ normal: TextureLoader { source: "qrc:/assets/textures/pattern_09/normal.webp" }
+ diffuse: TextureLoader { source: "qrc:/assets/textures/pattern_09/diffuse.webp" }
+ }
+ }
+
+ CubeEntity {
+ position: Qt.vector3d(1, 0, 0)
+ material: NormalDiffuseMapAlphaMaterial {
+ normal: TextureLoader { source: "qrc:/assets/textures/pattern_09/normal.webp" }
+ diffuse: TextureLoader { source: "qrc:/assets/textures/pattern_09/diffuse.webp" }
+ }
+ }
+
+ CubeEntity {
+ position: Qt.vector3d(-1, -1, 0)
+ material: NormalDiffuseSpecularMapMaterial {
+ normal: TextureLoader { source: "qrc:/assets/textures/pattern_09/normal.webp" }
+ diffuse: TextureLoader { source: "qrc:/assets/textures/pattern_09/diffuse.webp" }
+ specular: TextureLoader { source: "qrc:/assets/textures/pattern_09/specular.webp" }
+ }
+ }
+
+ CubeEntity {
+ position: Qt.vector3d(0, -1, 0)
+ material: NormalDiffuseSpecularMapMaterial {
+ normal: TextureLoader { source: "qrc:/assets/textures/pattern_09/normal.webp" }
+ diffuse: TextureLoader { source: "qrc:/assets/textures/pattern_09/diffuse.webp" }
+ specular: TextureLoader { source: "qrc:/assets/textures/pattern_09/specular.webp" }
+ }
+ }
+
+ CubeEntity {
+ position: Qt.vector3d(1, -1, 0)
+ material: NormalDiffuseSpecularMapMaterial {
+ normal: TextureLoader { source: "qrc:/assets/textures/pattern_09/normal.webp" }
+ diffuse: TextureLoader { source: "qrc:/assets/textures/pattern_09/diffuse.webp" }
+ specular: TextureLoader { source: "qrc:/assets/textures/pattern_09/specular.webp" }
+ }
+ }
+}
diff --git a/examples/qt3d/phong-cubes/phong-cubes.pro b/examples/qt3d/phong-cubes/phong-cubes.pro
new file mode 100644
index 000000000..e099b336d
--- /dev/null
+++ b/examples/qt3d/phong-cubes/phong-cubes.pro
@@ -0,0 +1,18 @@
+!include( ../examples.pri ) {
+ error( "Couldn't find the examples.pri file!" )
+}
+
+SOURCE += main.cpp
+
+QT += qml quick 3dcore 3drender 3dinput 3dquick 3dquickextras
+
+OTHER_FILES += \
+ main.qml \
+ CubeEntity.qml
+
+SOURCES += \
+ main.cpp
+
+RESOURCES += \
+ phong-cubes.qrc \
+ ../exampleresources/textures.qrc
diff --git a/examples/qt3d/phong-cubes/phong-cubes.qrc b/examples/qt3d/phong-cubes/phong-cubes.qrc
new file mode 100644
index 000000000..84cec1121
--- /dev/null
+++ b/examples/qt3d/phong-cubes/phong-cubes.qrc
@@ -0,0 +1,6 @@
+<RCC>
+ <qresource prefix="/">
+ <file>main.qml</file>
+ <file>CubeEntity.qml</file>
+ </qresource>
+</RCC>
diff --git a/examples/qt3d/qt3d.pro b/examples/qt3d/qt3d.pro
index 7ac55bfd2..74049b129 100644
--- a/examples/qt3d/qt3d.pro
+++ b/examples/qt3d/qt3d.pro
@@ -20,7 +20,8 @@ SUBDIRS += \
qardboard \
advancedcustommaterial \
simplecustommaterial \
- scene2d
+ scene2d \
+ phong-cubes
qtHaveModule(multimedia): SUBDIRS += audio-visualizer-qml
diff --git a/src/animation/backend/animationutils.cpp b/src/animation/backend/animationutils.cpp
index f421a8025..d05d96f38 100644
--- a/src/animation/backend/animationutils.cpp
+++ b/src/animation/backend/animationutils.cpp
@@ -48,6 +48,7 @@
#include <QtGui/qquaternion.h>
#include <QtGui/qcolor.h>
#include <QtCore/qvariant.h>
+#include <QtCore/qvarlengtharray.h>
#include <Qt3DAnimation/private/animationlogging_p.h>
#include <numeric>
@@ -292,13 +293,45 @@ QVector<Qt3DCore::QSceneChangePtr> preparePropertyChanges(Qt3DCore::QNodeId anim
bool finalFrame)
{
QVector<Qt3DCore::QSceneChangePtr> changes;
+ QVarLengthArray<Skeleton *, 4> dirtySkeletons;
+
// Iterate over the mappings
for (const MappingData &mappingData : mappingDataVec) {
if (!mappingData.propertyName)
continue;
+
// Build the new value from the channel/fcurve evaluation results
const QVariant v = buildPropertyValue(mappingData, channelResults);
- if (v.isValid()) {
+ if (!v.isValid())
+ continue;
+
+ // TODO: Avoid wrapping joint transform components up in a variant, just
+ // to immediately unwrap them again. Refactor buildPropertyValue() to call
+ // helper functions that we can call directly here for joints.
+ if (mappingData.skeleton && mappingData.jointIndex != -1) {
+ // Remember that this skeleton is dirty. We will ask each dirty skeleton
+ // to send its set of local poses to observers below.
+ if (!dirtySkeletons.contains(mappingData.skeleton))
+ dirtySkeletons.push_back(mappingData.skeleton);
+
+ switch (mappingData.jointTransformComponent) {
+ case MappingData::Scale:
+ mappingData.skeleton->setJointScale(mappingData.jointIndex, v.value<QVector3D>());
+ break;
+
+ case MappingData::Rotation:
+ mappingData.skeleton->setJointRotation(mappingData.jointIndex, v.value<QQuaternion>());
+ break;
+
+ case MappingData::Translation:
+ mappingData.skeleton->setJointTranslation(mappingData.jointIndex, v.value<QVector3D>());
+ break;
+
+ default:
+ Q_UNREACHABLE();
+ break;
+ }
+ } else {
// Construct a property update change, set target, property and delivery options
auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(mappingData.targetId);
e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll);
@@ -311,6 +344,8 @@ QVector<Qt3DCore::QSceneChangePtr> preparePropertyChanges(Qt3DCore::QNodeId anim
}
}
+ for (const auto skeleton : dirtySkeletons)
+ skeleton->sendLocalPoses();
// If it's the final frame, notify the frontend that we've stopped
if (finalFrame) {
@@ -342,96 +377,118 @@ QVector<AnimationCallbackAndValue> prepareCallbacks(const QVector<MappingData> &
return callbacks;
}
-//TODO: Remove this and use new implementation below for both the unblended
-// and blended animation cases.
-QVector<MappingData> buildPropertyMappings(Handler *handler,
- const AnimationClip *clip,
- const ChannelMapper *mapper)
+// TODO: Optimize this even more by combining the work done here with the functions:
+// buildRequiredChannelsAndTypes() and assignChannelComponentIndices(). We are
+// currently repeating the iteration over mappings and extracting/generating
+// channel names, types and joint indices.
+QVector<MappingData> buildPropertyMappings(const QVector<ChannelMapping*> &channelMappings,
+ const QVector<ChannelNameAndType> &channelNamesAndTypes,
+ const QVector<ComponentIndices> &channelComponentIndices)
{
- QVector<MappingData> mappingDataVec;
- ChannelMappingManager *mappingManager = handler->channelMappingManager();
- const QVector<Channel> &channels = clip->channels();
-
- // Iterate over the mappings in the mapper object
- const auto mappingIds = mapper->mappingIds();
- for (const Qt3DCore::QNodeId mappingId : mappingIds) {
- // Get the mapping object
- ChannelMapping *mapping = mappingManager->lookupResource(mappingId);
- Q_ASSERT(mapping);
+ // Accumulate the required number of mappings
+ int maxMappingDatas = 0;
+ for (const auto mapping : channelMappings) {
+ switch (mapping->mappingType()) {
+ case ChannelMapping::ChannelMappingType:
+ case ChannelMapping::CallbackMappingType:
+ ++maxMappingDatas;
+ break;
- // Populate the data we need, easy stuff first
- MappingData mappingData;
- mappingData.targetId = mapping->targetId();
- mappingData.propertyName = mapping->propertyName();
- mappingData.type = mapping->type();
- mappingData.callback = mapping->callback();
- mappingData.callbackFlags = mapping->callbackFlags();
-
- if (mappingData.type == static_cast<int>(QVariant::Invalid)) {
- qWarning() << "Unknown type for node id =" << mappingData.targetId
- << "and property =" << mapping->property()
- << "and callback =" << mapping->callback();
- continue;
+ case ChannelMapping::SkeletonMappingType: {
+ Skeleton *skeleton = mapping->skeleton();
+ maxMappingDatas += 3 * skeleton->jointCount(); // S, R, T
+ break;
}
+ }
+ }
+ QVector<MappingData> mappingDataVec;
+ mappingDataVec.reserve(maxMappingDatas);
- // Now the tricky part. Mapping the channel indices onto the property type.
- // Try to find a ChannelGroup with matching name
- const QString channelName = mapping->channelName();
- int channelGroupIndex = 0;
- bool foundMatch = false;
- for (const Channel &channel : channels) {
- if (channel.name == channelName) {
- foundMatch = true;
- const int channelBaseIndex = clip->channelComponentBaseIndex(channelGroupIndex);
-
- // Within this group, match channel names with index ordering
- mappingData.channelIndices = channelComponentsToIndices(channel, mappingData.type, channelBaseIndex);
+ // Iterate over the mappings
+ for (const auto mapping : channelMappings) {
+ switch (mapping->mappingType()) {
+ case ChannelMapping::ChannelMappingType:
+ case ChannelMapping::CallbackMappingType: {
+ // Populate the data we need, easy stuff first
+ MappingData mappingData;
+ mappingData.targetId = mapping->targetId();
+ mappingData.propertyName = mapping->propertyName();
+ mappingData.type = mapping->type();
+ mappingData.callback = mapping->callback();
+ mappingData.callbackFlags = mapping->callbackFlags();
+
+ if (mappingData.type == static_cast<int>(QVariant::Invalid)) {
+ qWarning() << "Unknown type for node id =" << mappingData.targetId
+ << "and property =" << mapping->property()
+ << "and callback =" << mapping->callback();
+ continue;
+ }
- // Store the mapping data
+ // Try to find matching channel name and type
+ const ChannelNameAndType nameAndType = { mapping->channelName(), mapping->type() };
+ const int index = channelNamesAndTypes.indexOf(nameAndType);
+ if (index != -1) {
+ // We got one!
+ mappingData.channelIndices = channelComponentIndices[index];
mappingDataVec.push_back(mappingData);
-
- if (foundMatch)
- break;
}
-
- ++channelGroupIndex;
+ break;
}
- }
- return mappingDataVec;
-}
+ case ChannelMapping::SkeletonMappingType: {
+ const QVector<ChannelNameAndType> jointProperties
+ = { { QLatin1String("Location"), static_cast<int>(QVariant::Vector3D) },
+ { QLatin1String("Rotation"), static_cast<int>(QVariant::Quaternion) },
+ { QLatin1String("Scale"), static_cast<int>(QVariant::Vector3D) } };
+ const QHash<QString, const char *> channelNameToPropertyName
+ = { { QLatin1String("Location"), "translation" },
+ { QLatin1String("Rotation"), "rotation" },
+ { QLatin1String("Scale"), "scale" } };
+ Skeleton *skeleton = mapping->skeleton();
+ const int jointCount = skeleton->jointCount();
+ for (int jointIndex = 0; jointIndex < jointCount; ++jointIndex) {
+ // Populate the data we need, easy stuff first
+ MappingData mappingData;
+ mappingData.targetId = mapping->skeletonId();
+ mappingData.skeleton = mapping->skeleton();
-QVector<MappingData> buildPropertyMappings(const QVector<ChannelMapping*> &channelMappings,
- const QVector<ChannelNameAndType> &channelNamesAndTypes,
- const QVector<ComponentIndices> &channelComponentIndices)
-{
- QVector<MappingData> mappingDataVec;
- mappingDataVec.reserve(channelMappings.size());
+ const int propertyCount = jointProperties.size();
+ for (int propertyIndex = 0; propertyIndex < propertyCount; ++propertyIndex) {
+ // Get the name, type and index
+ ChannelNameAndType nameAndType = jointProperties[propertyIndex];
+ nameAndType.jointIndex = jointIndex;
- // Iterate over the mappings
- for (const auto mapping : channelMappings) {
- // Populate the data we need, easy stuff first
- MappingData mappingData;
- mappingData.targetId = mapping->targetId();
- mappingData.propertyName = mapping->propertyName();
- mappingData.type = mapping->type();
- mappingData.callback = mapping->callback();
- mappingData.callbackFlags = mapping->callbackFlags();
-
- if (mappingData.type == static_cast<int>(QVariant::Invalid)) {
- qWarning() << "Unknown type for node id =" << mappingData.targetId
- << "and property =" << mapping->property()
- << "and callback =" << mapping->callback();
- continue;
+ // Try to find matching channel name and type
+ const int index = channelNamesAndTypes.indexOf(nameAndType);
+
+ // Do we have any animation data for this channel? If not, don't bother
+ // adding a mapping for it.
+ if (channelComponentIndices[index].isEmpty())
+ continue;
+
+ if (index != -1) {
+ // We got one!
+ mappingData.propertyName = channelNameToPropertyName[nameAndType.name];
+ mappingData.type = nameAndType.type;
+ mappingData.channelIndices = channelComponentIndices[index];
+ mappingData.jointIndex = jointIndex;
+
+ // Convert property name for joint transform components to
+ // an enumerated type so we can avoid the string comparisons
+ // when sending the change events after evaluation.
+ if (qstrcmp(mappingData.propertyName, "scale") == 0)
+ mappingData.jointTransformComponent = MappingData::Scale;
+ else if (qstrcmp(mappingData.propertyName, "rotation") == 0)
+ mappingData.jointTransformComponent = MappingData::Rotation;
+ else if (qstrcmp(mappingData.propertyName, "translation") == 0)
+ mappingData.jointTransformComponent = MappingData::Translation;
+
+ mappingDataVec.push_back(mappingData);
+ }
+ }
+ }
+ break;
}
-
- // Try to find matching channel name and type
- const ChannelNameAndType nameAndType = { mapping->channelName(), mapping->type() };
- const int index = channelNamesAndTypes.indexOf(nameAndType);
- if (index != -1) {
- // We got one!
- mappingData.channelIndices = channelComponentIndices[index];
- mappingDataVec.push_back(mappingData);
}
}
@@ -539,6 +596,10 @@ QVector<Qt3DCore::QNodeId> gatherValueNodesToEvaluate(Handler *handler,
ClipBlendNodeVisitor::VisitOnlyDependencies);
auto func = [&clipIds, nodeManager] (ClipBlendNode *blendNode) {
+ // Check if this is a value node itself
+ if (blendNode->blendType() == ClipBlendNode::ValueType)
+ clipIds.append(blendNode->peerId());
+
const auto dependencyIds = blendNode->currentDependencyIds();
for (const auto dependencyId : dependencyIds) {
// Look up the blend node and if it's a value type (clip),
@@ -558,19 +619,18 @@ QVector<Qt3DCore::QNodeId> gatherValueNodesToEvaluate(Handler *handler,
}
ComponentIndices generateClipFormatIndices(const QVector<ChannelNameAndType> &targetChannels,
- const QVector<ComponentIndices> &targetIndices,
+ QVector<ComponentIndices> &targetIndices,
const AnimationClip *clip)
{
Q_ASSERT(targetChannels.size() == targetIndices.size());
// Reserve enough storage for all the format indices
int indexCount = 0;
- for (const auto targetIndexVec : qAsConst(targetIndices))
+ for (const auto &targetIndexVec : qAsConst(targetIndices))
indexCount += targetIndexVec.size();
ComponentIndices format;
format.resize(indexCount);
-
// Iterate through the target channels
const int channelCount = targetChannels.size();
auto formatIt = format.begin();
@@ -579,23 +639,24 @@ ComponentIndices generateClipFormatIndices(const QVector<ChannelNameAndType> &ta
const ChannelNameAndType &targetChannel = targetChannels[i];
const int clipChannelIndex = clip->channelIndex(targetChannel.name,
targetChannel.jointIndex);
-
- // TODO: Ensure channel in the clip has enough components to map to the type.
- // Requires some improvements to the clip data structure first.
- // TODO: I don't think we need the targetIndices, only the number of components
- // for each target channel. Check once blend tree is complete.
const int componentCount = targetIndices[i].size();
if (clipChannelIndex != -1) {
// Found a matching channel in the clip. Get the base channel
// component index and populate the format indices for this channel.
const int baseIndex = clip->channelComponentBaseIndex(clipChannelIndex);
- std::iota(formatIt, formatIt + componentCount, baseIndex);
+
+ // Within this group, match channel names with index ordering
+ const auto channelIndices = channelComponentsToIndices(clip->channels()[clipChannelIndex],
+ targetChannel.type,
+ baseIndex);
+ std::copy(channelIndices.begin(), channelIndices.end(), formatIt);
} else {
// No such channel in this clip. We'll use default values when
// mapping from the clip to the formatted clip results.
std::fill(formatIt, formatIt + componentCount, -1);
+ targetIndices[i].clear();
}
formatIt += componentCount;
diff --git a/src/animation/backend/animationutils_p.h b/src/animation/backend/animationutils_p.h
index 7fcd9ead5..4bd3ee64b 100644
--- a/src/animation/backend/animationutils_p.h
+++ b/src/animation/backend/animationutils_p.h
@@ -71,9 +71,19 @@ typedef QVector<int> ComponentIndices;
struct MappingData
{
+ enum JointTransformComponent {
+ NoTransformComponent = 0,
+ Scale,
+ Rotation,
+ Translation
+ };
+
Qt3DCore::QNodeId targetId;
+ Skeleton *skeleton = nullptr;
+ int jointIndex = -1;
+ JointTransformComponent jointTransformComponent = NoTransformComponent;
const char *propertyName;
- QAnimationCallback *callback;
+ QAnimationCallback *callback = nullptr;
QAnimationCallback::Flags callbackFlags;
int type;
ComponentIndices channelIndices;
@@ -190,11 +200,6 @@ QVector<AnimationCallbackAndValue> prepareCallbacks(const QVector<MappingData> &
const QVector<float> &channelResults);
Q_AUTOTEST_EXPORT
-QVector<MappingData> buildPropertyMappings(Handler *handler,
- const AnimationClip *clip,
- const ChannelMapper *mapper);
-
-Q_AUTOTEST_EXPORT
QVector<MappingData> buildPropertyMappings(const QVector<ChannelMapping *> &channelMappings,
const QVector<ChannelNameAndType> &channelNamesAndTypes,
const QVector<ComponentIndices> &channelComponentIndices);
@@ -222,7 +227,7 @@ QVector<Qt3DCore::QNodeId> gatherValueNodesToEvaluate(Handler *handler,
Q_AUTOTEST_EXPORT
ComponentIndices generateClipFormatIndices(const QVector<ChannelNameAndType> &targetChannels,
- const QVector<ComponentIndices> &targetIndices,
+ QVector<ComponentIndices> &targetIndices,
const AnimationClip *clip);
Q_AUTOTEST_EXPORT
diff --git a/src/animation/backend/channelmapper.cpp b/src/animation/backend/channelmapper.cpp
index 0e5555096..48a1335fa 100644
--- a/src/animation/backend/channelmapper.cpp
+++ b/src/animation/backend/channelmapper.cpp
@@ -38,6 +38,7 @@
#include <Qt3DAnimation/qchannelmapper.h>
#include <Qt3DAnimation/private/qchannelmapper_p.h>
#include <Qt3DAnimation/private/animationlogging_p.h>
+#include <Qt3DAnimation/private/managers_p.h>
#include <Qt3DCore/qpropertyupdatedchange.h>
#include <Qt3DCore/qpropertynodeaddedchange.h>
#include <Qt3DCore/qpropertynoderemovedchange.h>
@@ -50,6 +51,7 @@ namespace Animation {
ChannelMapper::ChannelMapper()
: BackendNode(ReadOnly)
, m_mappingIds()
+ , m_isDirty(true)
{
}
@@ -58,12 +60,15 @@ void ChannelMapper::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr
const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QChannelMapperData>>(change);
const auto &data = typedChange->data;
m_mappingIds = data.mappingIds;
+ m_isDirty = true;
}
void ChannelMapper::cleanup()
{
setEnabled(false);
m_mappingIds.clear();
+ m_mappings.clear();
+ m_isDirty = true;
}
void ChannelMapper::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
@@ -74,6 +79,7 @@ void ChannelMapper::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
if (change->propertyName() == QByteArrayLiteral("mappings")) {
m_mappingIds.push_back(change->addedNodeId());
setDirty(Handler::ChannelMappingsDirty);
+ m_isDirty = true;
}
break;
}
@@ -83,6 +89,7 @@ void ChannelMapper::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
if (change->propertyName() == QByteArrayLiteral("mappings")) {
m_mappingIds.removeOne(change->removedNodeId());
setDirty(Handler::ChannelMappingsDirty);
+ m_isDirty = true;
}
break;
}
@@ -93,6 +100,19 @@ void ChannelMapper::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
QBackendNode::sceneChangeEvent(e);
}
+void ChannelMapper::updateMappings() const
+{
+ m_mappings.clear();
+ m_mappings.reserve(m_mappingIds.size());
+ const auto mappingManager = m_handler->channelMappingManager();
+ for (const auto &mappingId : m_mappingIds) {
+ const auto mapping = mappingManager->lookupResource(mappingId);
+ Q_ASSERT(mapping);
+ m_mappings.push_back(mapping);
+ }
+ m_isDirty = false;
+}
+
} // namespace Animation
} // namespace Qt3DAnimation
diff --git a/src/animation/backend/channelmapper_p.h b/src/animation/backend/channelmapper_p.h
index cb1a13928..fd99c8dbd 100644
--- a/src/animation/backend/channelmapper_p.h
+++ b/src/animation/backend/channelmapper_p.h
@@ -74,10 +74,22 @@ public:
void setMappingIds(const QVector<Qt3DCore::QNodeId> &mappingIds) { m_mappingIds = mappingIds; }
QVector<Qt3DCore::QNodeId> mappingIds() const { return m_mappingIds; }
+ QVector<ChannelMapping*> mappings() const
+ {
+ if (m_isDirty)
+ updateMappings();
+ return m_mappings;
+ }
+
private:
void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
+ void updateMappings() const;
QVector<Qt3DCore::QNodeId> m_mappingIds;
+
+ // Cached data
+ mutable QVector<ChannelMapping*> m_mappings;
+ mutable bool m_isDirty;
};
} // namespace Animation
diff --git a/src/animation/backend/channelmapping.cpp b/src/animation/backend/channelmapping.cpp
index 417c10a1a..4c263edba 100644
--- a/src/animation/backend/channelmapping.cpp
+++ b/src/animation/backend/channelmapping.cpp
@@ -40,6 +40,7 @@
#include <Qt3DAnimation/private/qskeletonmapping_p.h>
#include <Qt3DAnimation/private/animationlogging_p.h>
#include <Qt3DAnimation/private/qchannelmappingcreatedchange_p.h>
+#include <Qt3DAnimation/private/managers_p.h>
#include <Qt3DCore/qpropertyupdatedchange.h>
QT_BEGIN_NAMESPACE
@@ -137,6 +138,11 @@ void ChannelMapping::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
QBackendNode::sceneChangeEvent(e);
}
+Skeleton *ChannelMapping::skeleton() const
+{
+ return m_handler->skeletonManager()->lookupResource(m_skeletonId);
+}
+
} // namespace Animation
} // namespace Qt3DAnimation
diff --git a/src/animation/backend/channelmapping_p.h b/src/animation/backend/channelmapping_p.h
index 92c1d1c28..82de5c7b4 100644
--- a/src/animation/backend/channelmapping_p.h
+++ b/src/animation/backend/channelmapping_p.h
@@ -101,6 +101,7 @@ public:
void setSkeletonId(Qt3DCore::QNodeId skeletonId) { m_skeletonId = skeletonId; }
Qt3DCore::QNodeId skeletonId() const { return m_skeletonId; }
+ Skeleton *skeleton() const;
void setMappingType(MappingType mappingType) { m_mappingType = mappingType; }
MappingType mappingType() const { return m_mappingType; }
diff --git a/src/animation/backend/clipanimator.cpp b/src/animation/backend/clipanimator.cpp
index 2f4dca63f..568e2dbb0 100644
--- a/src/animation/backend/clipanimator.cpp
+++ b/src/animation/backend/clipanimator.cpp
@@ -114,6 +114,7 @@ void ClipAnimator::cleanup()
m_clockId = Qt3DCore::QNodeId();
m_running = false;
m_loops = 1;
+ m_formatIndices.clear();
}
void ClipAnimator::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
diff --git a/src/animation/backend/clipanimator_p.h b/src/animation/backend/clipanimator_p.h
index 0f975093c..ca05afdd3 100644
--- a/src/animation/backend/clipanimator_p.h
+++ b/src/animation/backend/clipanimator_p.h
@@ -97,6 +97,9 @@ public:
void animationClipMarkedDirty() { setDirty(Handler::ClipAnimatorDirty); }
+ void setFormatIndices(const ComponentIndices &formatIndices) { m_formatIndices = formatIndices; }
+ ComponentIndices formatIndices() const { return m_formatIndices; }
+
private:
void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
@@ -111,6 +114,7 @@ private:
QVector<MappingData> m_mappingData;
int m_currentLoop;
+ ComponentIndices m_formatIndices;
};
} // namespace Animation
diff --git a/src/animation/backend/clipblendvalue_p.h b/src/animation/backend/clipblendvalue_p.h
index f1bdfed3f..f0ae65589 100644
--- a/src/animation/backend/clipblendvalue_p.h
+++ b/src/animation/backend/clipblendvalue_p.h
@@ -73,7 +73,7 @@ public:
inline QVector<Qt3DCore::QNodeId> currentDependencyIds() const override
{
- return { m_clipId };
+ return {};
}
double duration() const override;
diff --git a/src/animation/backend/evaluateclipanimatorjob.cpp b/src/animation/backend/evaluateclipanimatorjob.cpp
index 6dab51d63..d9600c375 100644
--- a/src/animation/backend/evaluateclipanimatorjob.cpp
+++ b/src/animation/backend/evaluateclipanimatorjob.cpp
@@ -70,7 +70,11 @@ void EvaluateClipAnimatorJob::run()
// Prepare for evaluation (convert global time to local time ....)
const AnimatorEvaluationData animatorEvaluationData = evaluationDataForAnimator(clipAnimator, clock, globalTime);
const ClipEvaluationData preEvaluationDataForClip = evaluationDataForClip(clip, animatorEvaluationData);
- const ClipResults channelResults = evaluateClipAtLocalTime(clip, preEvaluationDataForClip.localTime);
+ const ClipResults rawClipResults = evaluateClipAtLocalTime(clip, preEvaluationDataForClip.localTime);
+
+ // Reformat the clip results into the layout used by this animator/blend tree
+ ComponentIndices format = clipAnimator->formatIndices();
+ ClipResults formattedClipResults = formatClipResults(rawClipResults, format);
if (preEvaluationDataForClip.isFinalFrame)
clipAnimator->setRunning(false);
@@ -80,14 +84,15 @@ void EvaluateClipAnimatorJob::run()
// Prepare property changes (if finalFrame it also prepares the change for the running property for the frontend)
const QVector<Qt3DCore::QSceneChangePtr> changes = preparePropertyChanges(clipAnimator->peerId(),
clipAnimator->mappingData(),
- channelResults,
+ formattedClipResults,
preEvaluationDataForClip.isFinalFrame);
// Send the property changes
clipAnimator->sendPropertyChanges(changes);
// Trigger callbacks either on this thread or by notifying the gui thread.
- const QVector<AnimationCallbackAndValue> callbacks = prepareCallbacks(clipAnimator->mappingData(), channelResults);
+ const QVector<AnimationCallbackAndValue> callbacks = prepareCallbacks(clipAnimator->mappingData(),
+ formattedClipResults);
clipAnimator->sendCallbacks(callbacks);
}
diff --git a/src/animation/backend/findrunningclipanimatorsjob.cpp b/src/animation/backend/findrunningclipanimatorsjob.cpp
index a8349eb91..16b84359e 100644
--- a/src/animation/backend/findrunningclipanimatorsjob.cpp
+++ b/src/animation/backend/findrunningclipanimatorsjob.cpp
@@ -62,24 +62,39 @@ void FindRunningClipAnimatorsJob::run()
Q_ASSERT(m_handler);
ClipAnimatorManager *clipAnimatorManager = m_handler->clipAnimatorManager();
- for (const auto clipAnimatorHandle : qAsConst(m_clipAnimatorHandles)) {
+ for (const auto &clipAnimatorHandle : qAsConst(m_clipAnimatorHandles)) {
ClipAnimator *clipAnimator = clipAnimatorManager->data(clipAnimatorHandle);
Q_ASSERT(clipAnimator);
const bool canRun = clipAnimator->canRun();
m_handler->setClipAnimatorRunning(clipAnimatorHandle, canRun);
- // The clip animator needs to know how to map fcurve values through to
- // properties on QNodes. Now we know this animator can run, build the mapping
- // table.
- // TODO: Should be possible to parallelise this with the fcurve evaluation as
- // sending the property change events doesn't happen until after evaluation
- if (canRun) {
- const AnimationClip *clip = m_handler->animationClipLoaderManager()->lookupResource(clipAnimator->clipId());
- const ChannelMapper *mapper = m_handler->channelMapperManager()->lookupResource(clipAnimator->mapperId());
- Q_ASSERT(clip && mapper);
- const QVector<MappingData> mappingData = buildPropertyMappings(m_handler, clip, mapper);
- clipAnimator->setMappingData(mappingData);
- }
+ if (!canRun)
+ continue;
+
+ // The clip animator needs to know how to map fcurve values through to properties on QNodes.
+ // Now we know this animator can run, build the mapping table. Even though this could be
+ // done a little simpler in the non-blended case, we follow the same code path as the
+ // blended clip animator for consistency and ease of maintenance.
+ const ChannelMapper *mapper = m_handler->channelMapperManager()->lookupResource(clipAnimator->mapperId());
+ Q_ASSERT(mapper);
+ const QVector<ChannelMapping *> channelMappings = mapper->mappings();
+
+ const QVector<ChannelNameAndType> channelNamesAndTypes
+ = buildRequiredChannelsAndTypes(m_handler, mapper);
+ QVector<ComponentIndices> channelComponentIndices
+ = assignChannelComponentIndices(channelNamesAndTypes);
+
+ const AnimationClip *clip = m_handler->animationClipLoaderManager()->lookupResource(clipAnimator->clipId());
+ Q_ASSERT(clip);
+ const ComponentIndices formatIndices = generateClipFormatIndices(channelNamesAndTypes,
+ channelComponentIndices,
+ clip);
+ clipAnimator->setFormatIndices(formatIndices);
+
+ const QVector<MappingData> mappingData = buildPropertyMappings(channelMappings,
+ channelNamesAndTypes,
+ channelComponentIndices);
+ clipAnimator->setMappingData(mappingData);
}
qCDebug(Jobs) << "Running clip animators =" << m_handler->runningClipAnimators();
diff --git a/src/animation/backend/findrunningclipanimatorsjob_p.h b/src/animation/backend/findrunningclipanimatorsjob_p.h
index 6c81ee914..f0e30e80c 100644
--- a/src/animation/backend/findrunningclipanimatorsjob_p.h
+++ b/src/animation/backend/findrunningclipanimatorsjob_p.h
@@ -52,6 +52,10 @@
#include <Qt3DAnimation/private/handle_types_p.h>
#include <QtCore/qvector.h>
+#if defined(QT_BUILD_INTERNAL)
+class tst_FindRunningClipAnimatorsJob;
+#endif
+
QT_BEGIN_NAMESPACE
namespace Qt3DAnimation {
@@ -59,7 +63,7 @@ namespace Animation {
class Handler;
-class FindRunningClipAnimatorsJob : public Qt3DCore::QAspectJob
+class Q_AUTOTEST_EXPORT FindRunningClipAnimatorsJob : public Qt3DCore::QAspectJob
{
public:
FindRunningClipAnimatorsJob();
@@ -75,6 +79,10 @@ protected:
private:
QVector<HClipAnimator> m_clipAnimatorHandles;
Handler *m_handler;
+
+#if defined(QT_BUILD_INTERNAL)
+ friend class ::tst_FindRunningClipAnimatorsJob;
+#endif
};
} // namespace Animation
diff --git a/src/animation/backend/skeleton.cpp b/src/animation/backend/skeleton.cpp
index a920e2473..dcfaf55e7 100644
--- a/src/animation/backend/skeleton.cpp
+++ b/src/animation/backend/skeleton.cpp
@@ -96,6 +96,15 @@ void Skeleton::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
BackendNode::sceneChangeEvent(e);
}
+void Skeleton::sendLocalPoses()
+{
+ auto e = QPropertyUpdatedChangePtr::create(peerId());
+ e->setDeliveryFlags(Qt3DCore::QSceneChange::BackendNodes);
+ e->setPropertyName("localPoses");
+ e->setValue(QVariant::fromValue(m_jointLocalPoses));
+ notifyObservers(e);
+}
+
} // namespace Animation
} // namespace Qt3DAnimation
diff --git a/src/animation/backend/skeleton_p.h b/src/animation/backend/skeleton_p.h
index 19da98261..e26e276d9 100644
--- a/src/animation/backend/skeleton_p.h
+++ b/src/animation/backend/skeleton_p.h
@@ -66,6 +66,23 @@ public:
int jointCount() const { return m_jointLocalPoses.size(); }
+ void setJointScale(int jointIndex, const QVector3D &scale)
+ {
+ m_jointLocalPoses[jointIndex].scale = scale;
+ }
+
+ void setJointRotation(int jointIndex, const QQuaternion &rotation)
+ {
+ m_jointLocalPoses[jointIndex].rotation = rotation;
+ }
+
+ void setJointTranslation(int jointIndex, const QVector3D &translation)
+ {
+ m_jointLocalPoses[jointIndex].translation = translation;
+ }
+
+ void sendLocalPoses();
+
#if defined(QT_BUILD_INTERNAL)
void setJointCount(int jointCount)
{
diff --git a/src/animation/frontend/qanimationaspect.cpp b/src/animation/frontend/qanimationaspect.cpp
index 14a0c4f8c..9b23a7b1d 100644
--- a/src/animation/frontend/qanimationaspect.cpp
+++ b/src/animation/frontend/qanimationaspect.cpp
@@ -95,6 +95,7 @@ QAnimationAspect::QAnimationAspect(QAnimationAspectPrivate &dd, QObject *parent)
Q_D(QAnimationAspect);
qRegisterMetaType<Qt3DAnimation::QAnimationClipLoader*>();
qRegisterMetaType<Qt3DAnimation::QChannelMapper*>();
+ qRegisterMetaType<QVector<Qt3DCore::Sqt>>();
registerBackendType<QAbstractAnimationClip>(
QSharedPointer<Animation::NodeFunctor<Animation::AnimationClip, Animation::AnimationClipLoaderManager>>::create(d->m_handler.data(),
diff --git a/src/animation/frontend/qblendedclipanimator.cpp b/src/animation/frontend/qblendedclipanimator.cpp
index 93cc27f50..785c810d3 100644
--- a/src/animation/frontend/qblendedclipanimator.cpp
+++ b/src/animation/frontend/qblendedclipanimator.cpp
@@ -40,6 +40,7 @@
#include "qblendedclipanimator_p.h"
#include <Qt3DAnimation/qabstractclipblendnode.h>
#include <Qt3DAnimation/qchannelmapper.h>
+#include <Qt3DAnimation/qclock.h>
QT_BEGIN_NAMESPACE
@@ -312,6 +313,7 @@ Qt3DCore::QNodeCreatedChangeBasePtr QBlendedClipAnimator::createNodeCreationChan
Q_D(const QBlendedClipAnimator);
data.blendTreeRootId = Qt3DCore::qIdForNode(d->m_blendTreeRoot);
data.mapperId = Qt3DCore::qIdForNode(d->m_mapper);
+ data.clockId = Qt3DCore::qIdForNode(d->m_clock);
data.running = d->m_running;
data.loops = d->m_loops;
return creationChange;
diff --git a/src/core/transforms/sqt_p.h b/src/core/transforms/sqt_p.h
index 262e3a645..5fdefccc8 100644
--- a/src/core/transforms/sqt_p.h
+++ b/src/core/transforms/sqt_p.h
@@ -101,6 +101,7 @@ struct JointNamesAndLocalPoses
QT_END_NAMESPACE
+Q_DECLARE_METATYPE(QVector<Qt3DCore::Sqt>)
Q_DECLARE_METATYPE(Qt3DCore::JointNamesAndLocalPoses)
#endif // QT3DCORE_SQT_P_H
diff --git a/src/extras/3dtext/qextrudedtextgeometry.cpp b/src/extras/3dtext/qextrudedtextgeometry.cpp
index c4c4ba77f..4a81ae44a 100644
--- a/src/extras/3dtext/qextrudedtextgeometry.cpp
+++ b/src/extras/3dtext/qextrudedtextgeometry.cpp
@@ -166,8 +166,8 @@ void QExtrudedTextGeometryPrivate::init()
m_positionAttribute = new Qt3DRender::QAttribute(q);
m_normalAttribute = new Qt3DRender::QAttribute(q);
m_indexAttribute = new Qt3DRender::QAttribute(q);
- m_vertexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, q);
- m_indexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::IndexBuffer, q);
+ m_vertexBuffer = new Qt3DRender::QBuffer(q);
+ m_indexBuffer = new Qt3DRender::QBuffer(q);
const quint32 elementSize = 3 + 3;
const quint32 stride = elementSize * sizeof(float);
diff --git a/src/extras/defaults/defaults.pri b/src/extras/defaults/defaults.pri
index d3fd122ae..2575de1a3 100644
--- a/src/extras/defaults/defaults.pri
+++ b/src/extras/defaults/defaults.pri
@@ -25,6 +25,8 @@ HEADERS += \
$$PWD/qphongalphamaterial_p.h \
$$PWD/qt3dwindow.h \
$$PWD/qt3dwindow_p.h \
+ $$PWD/qabstractcameracontroller.h \
+ $$PWD/qabstractcameracontroller_p.h \
$$PWD/qfirstpersoncameracontroller.h \
$$PWD/qfirstpersoncameracontroller_p.h \
$$PWD/qorbitcameracontroller.h \
@@ -58,6 +60,7 @@ SOURCES += \
$$PWD/qgoochmaterial.cpp \
$$PWD/qphongalphamaterial.cpp \
$$PWD/qt3dwindow.cpp \
+ $$PWD/qabstractcameracontroller.cpp \
$$PWD/qfirstpersoncameracontroller.cpp \
$$PWD/qorbitcameracontroller.cpp \
$$PWD/qabstractspritesheet.cpp \
diff --git a/src/extras/defaults/qabstractcameracontroller.cpp b/src/extras/defaults/qabstractcameracontroller.cpp
new file mode 100644
index 000000000..8bf57f5fa
--- /dev/null
+++ b/src/extras/defaults/qabstractcameracontroller.cpp
@@ -0,0 +1,436 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qabstractcameracontroller.h"
+#include "qabstractcameracontroller_p.h"
+
+#include <Qt3DRender/QCamera>
+#include <Qt3DInput/QAxis>
+#include <Qt3DInput/QAnalogAxisInput>
+#include <Qt3DInput/QButtonAxisInput>
+#include <Qt3DInput/QAction>
+#include <Qt3DInput/QActionInput>
+#include <Qt3DInput/QLogicalDevice>
+#include <Qt3DInput/QKeyboardDevice>
+#include <Qt3DInput/QMouseDevice>
+#include <Qt3DInput/QMouseEvent>
+#include <Qt3DLogic/QFrameAction>
+#include <QtCore/QtGlobal>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+
+QAbstractCameraControllerPrivate::QAbstractCameraControllerPrivate()
+ : Qt3DCore::QEntityPrivate()
+ , m_camera(nullptr)
+ , m_leftMouseButtonAction(new Qt3DInput::QAction())
+ , m_middleMouseButtonAction(new Qt3DInput::QAction())
+ , m_rightMouseButtonAction(new Qt3DInput::QAction())
+ , m_altButtonAction(new Qt3DInput::QAction())
+ , m_shiftButtonAction(new Qt3DInput::QAction())
+ , m_rxAxis(new Qt3DInput::QAxis())
+ , m_ryAxis(new Qt3DInput::QAxis())
+ , m_txAxis(new Qt3DInput::QAxis())
+ , m_tyAxis(new Qt3DInput::QAxis())
+ , m_tzAxis(new Qt3DInput::QAxis())
+ , m_leftMouseButtonInput(new Qt3DInput::QActionInput())
+ , m_middleMouseButtonInput(new Qt3DInput::QActionInput())
+ , m_rightMouseButtonInput(new Qt3DInput::QActionInput())
+ , m_altButtonInput(new Qt3DInput::QActionInput())
+ , m_shiftButtonInput(new Qt3DInput::QActionInput())
+ , m_mouseRxInput(new Qt3DInput::QAnalogAxisInput())
+ , m_mouseRyInput(new Qt3DInput::QAnalogAxisInput())
+ , m_mouseTzXInput(new Qt3DInput::QAnalogAxisInput())
+ , m_mouseTzYInput(new Qt3DInput::QAnalogAxisInput())
+ , m_keyboardTxPosInput(new Qt3DInput::QButtonAxisInput())
+ , m_keyboardTyPosInput(new Qt3DInput::QButtonAxisInput())
+ , m_keyboardTzPosInput(new Qt3DInput::QButtonAxisInput())
+ , m_keyboardTxNegInput(new Qt3DInput::QButtonAxisInput())
+ , m_keyboardTyNegInput(new Qt3DInput::QButtonAxisInput())
+ , m_keyboardTzNegInput(new Qt3DInput::QButtonAxisInput())
+ , m_keyboardDevice(new Qt3DInput::QKeyboardDevice())
+ , m_mouseDevice(new Qt3DInput::QMouseDevice())
+ , m_logicalDevice(new Qt3DInput::QLogicalDevice())
+ , m_frameAction(new Qt3DLogic::QFrameAction())
+ , m_linearSpeed(10.0f)
+ , m_lookSpeed(180.0f)
+ , m_acceleration(-1.0f)
+ , m_deceleration(-1.0f)
+ , m_sceneUp(0.0f, 1.0f, 0.0f)
+{}
+
+void QAbstractCameraControllerPrivate::init()
+{
+ //// Actions
+
+ // Left Mouse Button Action
+ m_leftMouseButtonInput->setButtons(QVector<int>() << Qt::LeftButton);
+ m_leftMouseButtonInput->setSourceDevice(m_mouseDevice);
+ m_leftMouseButtonAction->addInput(m_leftMouseButtonInput);
+
+ // Middle Mouse Button Action
+ m_middleMouseButtonInput->setButtons(QVector<int>() << Qt::MiddleButton);
+ m_middleMouseButtonInput->setSourceDevice(m_mouseDevice);
+ m_middleMouseButtonAction->addInput(m_middleMouseButtonInput);
+
+ // Right Mouse Button Action
+ m_rightMouseButtonInput->setButtons(QVector<int>() << Qt::RightButton);
+ m_rightMouseButtonInput->setSourceDevice(m_mouseDevice);
+ m_rightMouseButtonAction->addInput(m_rightMouseButtonInput);
+
+ // Alt Button Action
+ m_altButtonInput->setButtons(QVector<int>() << Qt::Key_Alt);
+ m_altButtonInput->setSourceDevice(m_keyboardDevice);
+ m_altButtonAction->addInput(m_altButtonInput);
+
+ // Shift Button Action
+ m_shiftButtonInput->setButtons(QVector<int>() << Qt::Key_Shift);
+ m_shiftButtonInput->setSourceDevice(m_keyboardDevice);
+ m_shiftButtonAction->addInput(m_shiftButtonInput);
+
+ //// Axes
+
+ // Mouse X
+ m_mouseRxInput->setAxis(Qt3DInput::QMouseDevice::X);
+ m_mouseRxInput->setSourceDevice(m_mouseDevice);
+ m_rxAxis->addInput(m_mouseRxInput);
+
+ // Mouse Y
+ m_mouseRyInput->setAxis(Qt3DInput::QMouseDevice::Y);
+ m_mouseRyInput->setSourceDevice(m_mouseDevice);
+ m_ryAxis->addInput(m_mouseRyInput);
+
+ // Mouse Wheel X
+ m_mouseTzXInput->setAxis(Qt3DInput::QMouseDevice::WheelX);
+ m_mouseTzXInput->setSourceDevice(m_mouseDevice);
+ m_tzAxis->addInput(m_mouseTzXInput);
+
+ // Mouse Wheel Y
+ m_mouseTzYInput->setAxis(Qt3DInput::QMouseDevice::WheelY);
+ m_mouseTzYInput->setSourceDevice(m_mouseDevice);
+ m_tzAxis->addInput(m_mouseTzYInput);
+
+ // Keyboard Pos Tx
+ m_keyboardTxPosInput->setButtons(QVector<int>() << Qt::Key_Right);
+ m_keyboardTxPosInput->setScale(1.0f);
+ m_keyboardTxPosInput->setSourceDevice(m_keyboardDevice);
+ m_txAxis->addInput(m_keyboardTxPosInput);
+
+ // Keyboard Pos Tz
+ m_keyboardTzPosInput->setButtons(QVector<int>() << Qt::Key_PageUp);
+ m_keyboardTzPosInput->setScale(1.0f);
+ m_keyboardTzPosInput->setSourceDevice(m_keyboardDevice);
+ m_tzAxis->addInput(m_keyboardTzPosInput);
+
+ // Keyboard Pos Ty
+ m_keyboardTyPosInput->setButtons(QVector<int>() << Qt::Key_Up);
+ m_keyboardTyPosInput->setScale(1.0f);
+ m_keyboardTyPosInput->setSourceDevice(m_keyboardDevice);
+ m_tyAxis->addInput(m_keyboardTyPosInput);
+
+ // Keyboard Neg Tx
+ m_keyboardTxNegInput->setButtons(QVector<int>() << Qt::Key_Left);
+ m_keyboardTxNegInput->setScale(-1.0f);
+ m_keyboardTxNegInput->setSourceDevice(m_keyboardDevice);
+ m_txAxis->addInput(m_keyboardTxNegInput);
+
+ // Keyboard Neg Tz
+ m_keyboardTzNegInput->setButtons(QVector<int>() << Qt::Key_PageDown);
+ m_keyboardTzNegInput->setScale(-1.0f);
+ m_keyboardTzNegInput->setSourceDevice(m_keyboardDevice);
+ m_tzAxis->addInput(m_keyboardTzNegInput);
+
+ // Keyboard Neg Ty
+ m_keyboardTyNegInput->setButtons(QVector<int>() << Qt::Key_Down);
+ m_keyboardTyNegInput->setScale(-1.0f);
+ m_keyboardTyNegInput->setSourceDevice(m_keyboardDevice);
+ m_tyAxis->addInput(m_keyboardTyNegInput);
+
+ //// Logical Device
+
+ m_logicalDevice->addAction(m_leftMouseButtonAction);
+ m_logicalDevice->addAction(m_middleMouseButtonAction);
+ m_logicalDevice->addAction(m_rightMouseButtonAction);
+ m_logicalDevice->addAction(m_altButtonAction);
+ m_logicalDevice->addAction(m_shiftButtonAction);
+ m_logicalDevice->addAxis(m_rxAxis);
+ m_logicalDevice->addAxis(m_ryAxis);
+ m_logicalDevice->addAxis(m_txAxis);
+ m_logicalDevice->addAxis(m_tyAxis);
+ m_logicalDevice->addAxis(m_tzAxis);
+
+ applyInputAccelerations();
+
+ Q_Q(QAbstractCameraController);
+ //// FrameAction
+
+ // Disable the logical device when the entity is disabled
+ QObject::connect(q, &Qt3DCore::QEntity::enabledChanged,
+ m_logicalDevice, &Qt3DInput::QLogicalDevice::setEnabled);
+
+ q->addComponent(m_frameAction);
+ q->addComponent(m_logicalDevice);
+}
+
+void QAbstractCameraControllerPrivate::applyInputAccelerations()
+{
+ const auto inputs = {
+ m_keyboardTxPosInput,
+ m_keyboardTyPosInput,
+ m_keyboardTzPosInput,
+ m_keyboardTxNegInput,
+ m_keyboardTyNegInput,
+ m_keyboardTzNegInput
+ };
+
+ for (auto input : inputs) {
+ input->setAcceleration(m_acceleration);
+ input->setDeceleration(m_deceleration);
+ }
+}
+
+/*!
+ \class QAbstractCameraController
+
+ \brief The QAbstractCameraController class provides basic
+ functionality for camera controllers.
+
+ \inmodule Qt3DExtras
+ \since 5.10
+
+ QAbstractCameraController sets up and handles input from keyboard,
+ mouse, and other devices. QAbstractCameraController is an abstract
+ class and cannot itself be instantiated. It provides a standard
+ interface for camera controllers.
+
+ Derived classes need only implement the frameActionTriggered()
+ method to move the camera.
+*/
+
+/*!
+ \fn void QAbstractCameraController::moveCamera(const InputState &state, float dt) = 0
+
+ This method is called whenever a frame action is triggered. Derived
+ classes must override this method to implement the camera movement
+ specific to the controller.
+
+ In the base class this is a pure virtual function.
+*/
+
+QAbstractCameraController::QAbstractCameraController(Qt3DCore::QNode *parent)
+ : QAbstractCameraController(*new QAbstractCameraControllerPrivate, parent)
+{
+}
+
+/*! \internal
+ */
+QAbstractCameraController::QAbstractCameraController(QAbstractCameraControllerPrivate &dd, Qt3DCore::QNode *parent)
+ : Qt3DCore::QEntity(dd, parent)
+{
+ Q_D(QAbstractCameraController);
+ d->init();
+
+ QObject::connect(d->m_frameAction, &Qt3DLogic::QFrameAction::triggered,
+ this, [=] (float dt) {
+ InputState state;
+
+ state.rxAxisValue = d->m_rxAxis->value();
+ state.ryAxisValue = d->m_ryAxis->value();
+ state.txAxisValue = d->m_txAxis->value();
+ state.tyAxisValue = d->m_tyAxis->value();
+ state.tzAxisValue = d->m_tzAxis->value();
+
+ state.leftMouseButtonActive = d->m_leftMouseButtonAction->isActive();
+ state.middleMouseButtonActive = d->m_middleMouseButtonAction->isActive();
+ state.rightMouseButtonActive = d->m_rightMouseButtonAction->isActive();
+
+ state.altKeyActive = d->m_altButtonAction->isActive();
+ state.shiftKeyActive = d->m_shiftButtonAction->isActive();
+
+ moveCamera(state, dt);
+ });
+}
+
+QAbstractCameraController::~QAbstractCameraController()
+{
+}
+
+/*!
+ \property QAbstractCameraController::camera
+
+ Holds the currently controlled camera.
+*/
+Qt3DRender::QCamera *QAbstractCameraController::camera() const
+{
+ Q_D(const QAbstractCameraController);
+ return d->m_camera;
+}
+
+/*!
+ \property QAbstractCameraController::linearSpeed
+
+ Holds the current linear speed of the camera controller. Linear speed determines the
+ movement speed of the camera.
+
+ The default is 10.0.
+*/
+float QAbstractCameraController::linearSpeed() const
+{
+ Q_D(const QAbstractCameraController);
+ return d->m_linearSpeed;
+}
+
+/*!
+ \property QAbstractCameraController::lookSpeed
+
+ Holds the current look speed of the camera controller. The look speed determines the turn rate
+ of the camera pan and tilt.
+
+ The default is 180.0.
+*/
+float QAbstractCameraController::lookSpeed() const
+{
+ Q_D(const QAbstractCameraController);
+ return d->m_lookSpeed;
+}
+
+/*!
+ \property QAbstractCameraController::acceleration
+
+ Holds the current acceleration of the camera controller.
+*/
+float QAbstractCameraController::acceleration() const
+{
+ Q_D(const QAbstractCameraController);
+ return d->m_acceleration;
+}
+
+/*!
+ \property QAbstractCameraController::deceleration
+
+ Holds the current deceleration of the camera controller.
+*/
+float QAbstractCameraController::deceleration() const
+{
+ Q_D(const QAbstractCameraController);
+ return d->m_deceleration;
+}
+
+void QAbstractCameraController::setCamera(Qt3DRender::QCamera *camera)
+{
+ Q_D(QAbstractCameraController);
+ if (d->m_camera != camera) {
+
+ if (d->m_camera)
+ d->unregisterDestructionHelper(d->m_camera);
+
+ if (camera && !camera->parent())
+ camera->setParent(this);
+
+ d->m_camera = camera;
+
+ // Ensures proper bookkeeping
+ if (d->m_camera)
+ d->registerDestructionHelper(d->m_camera, &QAbstractCameraController::setCamera, d->m_camera);
+
+ emit cameraChanged();
+ }
+}
+
+void QAbstractCameraController::setLinearSpeed(float linearSpeed)
+{
+ Q_D(QAbstractCameraController);
+ if (d->m_linearSpeed != linearSpeed) {
+ d->m_linearSpeed = linearSpeed;
+ emit linearSpeedChanged();
+ }
+}
+
+void QAbstractCameraController::setLookSpeed(float lookSpeed)
+{
+ Q_D(QAbstractCameraController);
+ if (d->m_lookSpeed != lookSpeed) {
+ d->m_lookSpeed = lookSpeed;
+ emit lookSpeedChanged();
+ }
+}
+
+void QAbstractCameraController::setAcceleration(float acceleration)
+{
+ Q_D(QAbstractCameraController);
+ if (d->m_acceleration != acceleration) {
+ d->m_acceleration = acceleration;
+ d->applyInputAccelerations();
+ emit accelerationChanged(acceleration);
+ }
+}
+
+void QAbstractCameraController::setDeceleration(float deceleration)
+{
+ Q_D(QAbstractCameraController);
+ if (d->m_deceleration != deceleration) {
+ d->m_deceleration = deceleration;
+ d->applyInputAccelerations();
+ emit decelerationChanged(deceleration);
+ }
+}
+
+/*!
+ Provides access to the keyboard device.
+*/
+
+Qt3DInput::QKeyboardDevice *QAbstractCameraController::keyboardDevice() const
+{
+ Q_D(const QAbstractCameraController);
+ return d->m_keyboardDevice;
+}
+
+/*!
+ Provides access to the mouse device.
+*/
+
+Qt3DInput::QMouseDevice *QAbstractCameraController::mouseDevice() const
+{
+ Q_D(const QAbstractCameraController);
+ return d->m_mouseDevice;
+}
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
+
+#include "moc_qabstractcameracontroller.cpp"
diff --git a/src/extras/defaults/qabstractcameracontroller.h b/src/extras/defaults/qabstractcameracontroller.h
new file mode 100644
index 000000000..f13079f5f
--- /dev/null
+++ b/src/extras/defaults/qabstractcameracontroller.h
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_QABSTRACTCAMERACONTROLLER_H
+#define QT3DEXTRAS_QABSTRACTCAMERACONTROLLER_H
+
+#include <Qt3DCore/QEntity>
+#include <Qt3DExtras/qt3dextras_global.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DInput {
+class QKeyboardDevice;
+class QMouseDevice;
+}
+
+namespace Qt3DRender {
+class QCamera;
+}
+
+namespace Qt3DExtras {
+
+class QAbstractCameraControllerPrivate;
+
+class QT3DEXTRASSHARED_EXPORT QAbstractCameraController : public Qt3DCore::QEntity
+{
+ Q_OBJECT
+ Q_PROPERTY(Qt3DRender::QCamera *camera READ camera WRITE setCamera NOTIFY cameraChanged)
+ Q_PROPERTY(float linearSpeed READ linearSpeed WRITE setLinearSpeed NOTIFY linearSpeedChanged)
+ Q_PROPERTY(float lookSpeed READ lookSpeed WRITE setLookSpeed NOTIFY lookSpeedChanged)
+ Q_PROPERTY(float acceleration READ acceleration WRITE setAcceleration NOTIFY accelerationChanged)
+ Q_PROPERTY(float deceleration READ deceleration WRITE setDeceleration NOTIFY decelerationChanged)
+
+public:
+ ~QAbstractCameraController();
+
+ Qt3DRender::QCamera *camera() const;
+ float linearSpeed() const;
+ float lookSpeed() const;
+
+ float acceleration() const;
+ float deceleration() const;
+
+ void setCamera(Qt3DRender::QCamera *camera);
+ void setLinearSpeed(float linearSpeed);
+ void setLookSpeed(float lookSpeed);
+
+ void setAcceleration(float acceleration);
+ void setDeceleration(float deceleration);
+
+Q_SIGNALS:
+ void cameraChanged();
+ void linearSpeedChanged();
+ void lookSpeedChanged();
+
+ void accelerationChanged(float acceleration);
+ void decelerationChanged(float deceleration);
+
+protected:
+ explicit QAbstractCameraController(Qt3DCore::QNode *parent = nullptr);
+ QAbstractCameraController(QAbstractCameraControllerPrivate &dd, Qt3DCore::QNode *parent = nullptr);
+
+ Qt3DInput::QKeyboardDevice *keyboardDevice() const;
+ Qt3DInput::QMouseDevice *mouseDevice() const;
+
+ struct InputState
+ {
+ float rxAxisValue;
+ float ryAxisValue;
+ float txAxisValue;
+ float tyAxisValue;
+ float tzAxisValue;
+
+ bool leftMouseButtonActive;
+ bool middleMouseButtonActive;
+ bool rightMouseButtonActive;
+
+ bool altKeyActive;
+ bool shiftKeyActive;
+ };
+
+private:
+ virtual void moveCamera(const InputState &state, float dt) = 0;
+
+private:
+ Q_DECLARE_PRIVATE(QAbstractCameraController)
+};
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QABSTRACTCAMERACONTROLLER_H
diff --git a/src/extras/defaults/qabstractcameracontroller_p.h b/src/extras/defaults/qabstractcameracontroller_p.h
new file mode 100644
index 000000000..00424a55b
--- /dev/null
+++ b/src/extras/defaults/qabstractcameracontroller_p.h
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_QABSTRACTCAMERACONTROLLER_P_H
+#define QT3DEXTRAS_QABSTRACTCAMERACONTROLLER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <Qt3DExtras/qabstractcameracontroller.h>
+#include <QtGui/QVector3D>
+
+#include <Qt3DCore/private/qentity_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+class QCamera;
+}
+
+namespace Qt3DLogic {
+class QFrameAction;
+}
+
+namespace Qt3DInput {
+class QKeyboardDevice;
+class QMouseDevice;
+class QLogicalDevice;
+class QAction;
+class QActionInput;
+class QAxis;
+class QAnalogAxisInput;
+class QButtonAxisInput;
+class QAxisActionHandler;
+}
+
+namespace Qt3DExtras {
+
+class QAbstractCameraControllerPrivate : public Qt3DCore::QEntityPrivate
+{
+public:
+ QAbstractCameraControllerPrivate();
+
+ void init();
+ void applyInputAccelerations();
+
+ Qt3DRender::QCamera *m_camera;
+
+ Qt3DInput::QAction *m_leftMouseButtonAction;
+ Qt3DInput::QAction *m_middleMouseButtonAction;
+ Qt3DInput::QAction *m_rightMouseButtonAction;
+ Qt3DInput::QAction *m_altButtonAction;
+ Qt3DInput::QAction *m_shiftButtonAction;
+
+ Qt3DInput::QAxis *m_rxAxis;
+ Qt3DInput::QAxis *m_ryAxis;
+ Qt3DInput::QAxis *m_txAxis;
+ Qt3DInput::QAxis *m_tyAxis;
+ Qt3DInput::QAxis *m_tzAxis;
+
+ Qt3DInput::QActionInput *m_leftMouseButtonInput;
+ Qt3DInput::QActionInput *m_middleMouseButtonInput;
+ Qt3DInput::QActionInput *m_rightMouseButtonInput;
+ Qt3DInput::QActionInput *m_altButtonInput;
+ Qt3DInput::QActionInput *m_shiftButtonInput;
+
+ Qt3DInput::QAnalogAxisInput *m_mouseRxInput;
+ Qt3DInput::QAnalogAxisInput *m_mouseRyInput;
+ Qt3DInput::QAnalogAxisInput *m_mouseTzXInput;
+ Qt3DInput::QAnalogAxisInput *m_mouseTzYInput;
+ Qt3DInput::QButtonAxisInput *m_keyboardTxPosInput;
+ Qt3DInput::QButtonAxisInput *m_keyboardTyPosInput;
+ Qt3DInput::QButtonAxisInput *m_keyboardTzPosInput;
+ Qt3DInput::QButtonAxisInput *m_keyboardTxNegInput;
+ Qt3DInput::QButtonAxisInput *m_keyboardTyNegInput;
+ Qt3DInput::QButtonAxisInput *m_keyboardTzNegInput;
+
+ Qt3DInput::QKeyboardDevice *m_keyboardDevice;
+ Qt3DInput::QMouseDevice *m_mouseDevice;
+
+ Qt3DInput::QLogicalDevice *m_logicalDevice;
+
+ Qt3DLogic::QFrameAction *m_frameAction;
+
+ float m_linearSpeed;
+ float m_lookSpeed;
+
+ float m_acceleration;
+ float m_deceleration;
+
+ QVector3D m_sceneUp;
+
+ Q_DECLARE_PUBLIC(QAbstractCameraController)
+};
+
+} // namespace Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QABSTRACTCAMERACONTROLLER_P_H
diff --git a/src/extras/defaults/qdiffusemapmaterial.cpp b/src/extras/defaults/qdiffusemapmaterial.cpp
index a6da98a2e..930fbbd1f 100644
--- a/src/extras/defaults/qdiffusemapmaterial.cpp
+++ b/src/extras/defaults/qdiffusemapmaterial.cpp
@@ -98,9 +98,9 @@ void QDiffuseMapMaterialPrivate::init()
connect(m_textureScaleParameter, &Qt3DRender::QParameter::valueChanged,
this, &QDiffuseMapMaterialPrivate::handleTextureScaleChanged);
- m_diffuseMapGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/diffusemap.vert"))));
+ m_diffuseMapGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/default.vert"))));
m_diffuseMapGL3Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/diffusemap.frag"))));
- m_diffuseMapGL2ES2Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/diffusemap.vert"))));
+ m_diffuseMapGL2ES2Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/default.vert"))));
m_diffuseMapGL2ES2Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/diffusemap.frag"))));
m_diffuseMapGL3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
diff --git a/src/extras/defaults/qdiffusespecularmapmaterial.cpp b/src/extras/defaults/qdiffusespecularmapmaterial.cpp
index 615ee6305..2e98bc8e7 100644
--- a/src/extras/defaults/qdiffusespecularmapmaterial.cpp
+++ b/src/extras/defaults/qdiffusespecularmapmaterial.cpp
@@ -105,9 +105,9 @@ void QDiffuseSpecularMapMaterialPrivate::init()
connect(m_textureScaleParameter, &Qt3DRender::QParameter::valueChanged,
this, &QDiffuseSpecularMapMaterialPrivate::handleTextureScaleChanged);
- m_diffuseSpecularMapGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/diffusemap.vert"))));
+ m_diffuseSpecularMapGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/default.vert"))));
m_diffuseSpecularMapGL3Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/diffusespecularmap.frag"))));
- m_diffuseSpecularMapGL2ES2Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/diffusemap.vert"))));
+ m_diffuseSpecularMapGL2ES2Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/default.vert"))));
m_diffuseSpecularMapGL2ES2Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/diffusespecularmap.frag"))));
m_diffuseSpecularMapGL3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
diff --git a/src/extras/defaults/qfirstpersoncameracontroller.cpp b/src/extras/defaults/qfirstpersoncameracontroller.cpp
index 5321bfcf2..2ad997d05 100644
--- a/src/extras/defaults/qfirstpersoncameracontroller.cpp
+++ b/src/extras/defaults/qfirstpersoncameracontroller.cpp
@@ -35,188 +35,13 @@
****************************************************************************/
#include "qfirstpersoncameracontroller.h"
-#include "qfirstpersoncameracontroller_p.h"
-#include <Qt3DInput/QAction>
-#include <Qt3DInput/QActionInput>
-#include <Qt3DInput/QAnalogAxisInput>
-#include <Qt3DInput/QAxis>
-#include <Qt3DInput/QButtonAxisInput>
-#include <Qt3DLogic/QFrameAction>
-#include <Qt3DInput/QKeyboardDevice>
-#include <Qt3DInput/QLogicalDevice>
-#include <Qt3DInput/QMouseDevice>
-#include <Qt3DInput/QMouseEvent>
#include <Qt3DRender/QCamera>
QT_BEGIN_NAMESPACE
namespace Qt3DExtras {
-QFirstPersonCameraControllerPrivate::QFirstPersonCameraControllerPrivate()
- : Qt3DCore::QEntityPrivate()
- , m_camera(nullptr)
- , m_leftMouseButtonAction(new Qt3DInput::QAction())
- , m_fineMotionAction(new Qt3DInput::QAction())
- , m_rxAxis(new Qt3DInput::QAxis())
- , m_ryAxis(new Qt3DInput::QAxis())
- , m_txAxis(new Qt3DInput::QAxis())
- , m_tyAxis(new Qt3DInput::QAxis())
- , m_tzAxis(new Qt3DInput::QAxis())
- , m_leftMouseButtonInput(new Qt3DInput::QActionInput())
- , m_fineMotionKeyInput(new Qt3DInput::QActionInput())
- , m_mouseRxInput(new Qt3DInput::QAnalogAxisInput())
- , m_mouseRyInput(new Qt3DInput::QAnalogAxisInput())
- , m_mouseTzXInput(new Qt3DInput::QAnalogAxisInput())
- , m_mouseTzYInput(new Qt3DInput::QAnalogAxisInput())
- , m_keyboardTxPosInput(new Qt3DInput::QButtonAxisInput())
- , m_keyboardTyPosInput(new Qt3DInput::QButtonAxisInput())
- , m_keyboardTzPosInput(new Qt3DInput::QButtonAxisInput())
- , m_keyboardTxNegInput(new Qt3DInput::QButtonAxisInput())
- , m_keyboardTyNegInput(new Qt3DInput::QButtonAxisInput())
- , m_keyboardTzNegInput(new Qt3DInput::QButtonAxisInput())
- , m_keyboardDevice(new Qt3DInput::QKeyboardDevice())
- , m_mouseDevice(new Qt3DInput::QMouseDevice())
- , m_logicalDevice(new Qt3DInput::QLogicalDevice())
- , m_frameAction(new Qt3DLogic::QFrameAction())
- , m_linearSpeed(10.0f)
- , m_lookSpeed(180.0f)
- , m_acceleration(-1.0f)
- , m_deceleration(-1.0f)
- , m_firstPersonUp(QVector3D(0.0f, 1.0f, 0.0f))
-{}
-
-void QFirstPersonCameraControllerPrivate::init()
-{
- //// Actions
-
- // Left Mouse Button Action
- m_leftMouseButtonInput->setButtons(QVector<int>() << Qt::LeftButton);
- m_leftMouseButtonInput->setSourceDevice(m_mouseDevice);
- m_leftMouseButtonAction->addInput(m_leftMouseButtonInput);
-
- // Fine Motion Action
- m_fineMotionKeyInput->setButtons(QVector<int>() << Qt::Key_Shift);
- m_fineMotionKeyInput->setSourceDevice(m_keyboardDevice);
- m_fineMotionAction->addInput(m_fineMotionKeyInput);
-
- //// Axes
-
- // Mouse X
- m_mouseRxInput->setAxis(Qt3DInput::QMouseDevice::X);
- m_mouseRxInput->setSourceDevice(m_mouseDevice);
- m_rxAxis->addInput(m_mouseRxInput);
-
- // Mouse Y
- m_mouseRyInput->setAxis(Qt3DInput::QMouseDevice::Y);
- m_mouseRyInput->setSourceDevice(m_mouseDevice);
- m_ryAxis->addInput(m_mouseRyInput);
-
- // Mouse Wheel X
- m_mouseTzXInput->setAxis(Qt3DInput::QMouseDevice::WheelX);
- m_mouseTzXInput->setSourceDevice(m_mouseDevice);
- m_tzAxis->addInput(m_mouseTzXInput);
-
- // Mouse Wheel Y
- m_mouseTzYInput->setAxis(Qt3DInput::QMouseDevice::WheelY);
- m_mouseTzYInput->setSourceDevice(m_mouseDevice);
- m_tzAxis->addInput(m_mouseTzYInput);
-
- // Keyboard Pos Tx
- m_keyboardTxPosInput->setButtons(QVector<int>() << Qt::Key_Right);
- m_keyboardTxPosInput->setScale(1.0f);
- m_keyboardTxPosInput->setSourceDevice(m_keyboardDevice);
- m_txAxis->addInput(m_keyboardTxPosInput);
-
- // Keyboard Pos Ty
- m_keyboardTyPosInput->setButtons(QVector<int>() << Qt::Key_PageUp);
- m_keyboardTyPosInput->setScale(1.0f);
- m_keyboardTyPosInput->setSourceDevice(m_keyboardDevice);
- m_tyAxis->addInput(m_keyboardTyPosInput);
-
- // Keyboard Pos Tz
- m_keyboardTzPosInput->setButtons(QVector<int>() << Qt::Key_Up);
- m_keyboardTzPosInput->setScale(1.0f);
- m_keyboardTzPosInput->setSourceDevice(m_keyboardDevice);
- m_tzAxis->addInput(m_keyboardTzPosInput);
-
- // Keyboard Neg Tx
- m_keyboardTxNegInput->setButtons(QVector<int>() << Qt::Key_Left);
- m_keyboardTxNegInput->setScale(-1.0f);
- m_keyboardTxNegInput->setSourceDevice(m_keyboardDevice);
- m_txAxis->addInput(m_keyboardTxNegInput);
-
- // Keyboard Neg Ty
- m_keyboardTyNegInput->setButtons(QVector<int>() << Qt::Key_PageDown);
- m_keyboardTyNegInput->setScale(-1.0f);
- m_keyboardTyNegInput->setSourceDevice(m_keyboardDevice);
- m_tyAxis->addInput(m_keyboardTyNegInput);
-
- // Keyboard Neg Tz
- m_keyboardTzNegInput->setButtons(QVector<int>() << Qt::Key_Down);
- m_keyboardTzNegInput->setScale(-1.0f);
- m_keyboardTzNegInput->setSourceDevice(m_keyboardDevice);
- m_tzAxis->addInput(m_keyboardTzNegInput);
-
- //// Logical Device
-
- m_logicalDevice->addAction(m_fineMotionAction);
- m_logicalDevice->addAction(m_leftMouseButtonAction);
- m_logicalDevice->addAxis(m_rxAxis);
- m_logicalDevice->addAxis(m_ryAxis);
- m_logicalDevice->addAxis(m_txAxis);
- m_logicalDevice->addAxis(m_tyAxis);
- m_logicalDevice->addAxis(m_tzAxis);
-
- applyAccelerations();
-
- Q_Q(QFirstPersonCameraController);
- //// FrameAction
-
- QObject::connect(m_frameAction, SIGNAL(triggered(float)),
- q, SLOT(_q_onTriggered(float)));
-
- // Disable the logical device when the entity is disabled
- QObject::connect(q, &Qt3DCore::QEntity::enabledChanged,
- m_logicalDevice, &Qt3DInput::QLogicalDevice::setEnabled);
-
- q->addComponent(m_frameAction);
- q->addComponent(m_logicalDevice);
-}
-
-void QFirstPersonCameraControllerPrivate::applyAccelerations()
-{
- const auto inputs = {
- m_keyboardTxPosInput,
- m_keyboardTyPosInput,
- m_keyboardTzPosInput,
- m_keyboardTxNegInput,
- m_keyboardTyNegInput,
- m_keyboardTzNegInput
- };
-
- for (auto input : inputs) {
- input->setAcceleration(m_acceleration);
- input->setDeceleration(m_deceleration);
- }
-}
-
-void QFirstPersonCameraControllerPrivate::_q_onTriggered(float dt)
-{
- if (m_camera != nullptr) {
- m_camera->translate(QVector3D(m_txAxis->value() * m_linearSpeed,
- m_tyAxis->value() * m_linearSpeed,
- m_tzAxis->value() * m_linearSpeed) * dt);
- if (m_leftMouseButtonAction->isActive()) {
- float lookSpeed = m_lookSpeed;
- if (m_fineMotionAction->isActive())
- lookSpeed *= 0.2f;
- m_camera->pan(m_rxAxis->value() * lookSpeed * dt, m_firstPersonUp);
- m_camera->tilt(m_ryAxis->value() * lookSpeed * dt);
- }
- }
-}
-
/*!
\class Qt3DExtras::QFirstPersonCameraController
\brief The QFirstPersonCameraController class allows controlling the scene camera
@@ -251,129 +76,35 @@ void QFirstPersonCameraControllerPrivate::_q_onTriggered(float dt)
*/
QFirstPersonCameraController::QFirstPersonCameraController(Qt3DCore::QNode *parent)
- : Qt3DCore::QEntity(*new QFirstPersonCameraControllerPrivate, parent)
+ : QAbstractCameraController(parent)
{
- Q_D(QFirstPersonCameraController);
- d->init();
}
QFirstPersonCameraController::~QFirstPersonCameraController()
{
}
-/*!
- \property QFirstPersonCameraController::camera
-
- Holds the currently controlled camera.
-*/
-Qt3DRender::QCamera *QFirstPersonCameraController::camera() const
-{
- Q_D(const QFirstPersonCameraController);
- return d->m_camera;
-}
-
-/*!
- \property QFirstPersonCameraController::linearSpeed
- Holds the current linear speed of the camera controller. Linear speed determines the
- movement speed of the camera.
-*/
-float QFirstPersonCameraController::linearSpeed() const
+void QFirstPersonCameraController::moveCamera(const QAbstractCameraController::InputState &state, float dt)
{
- Q_D(const QFirstPersonCameraController);
- return d->m_linearSpeed;
-}
-
-/*!
- \property QFirstPersonCameraController::lookSpeed
-
- Holds the current look speed of the camera controller. The look speed determines the turn rate
- of the camera pan and tilt.
-*/
-float QFirstPersonCameraController::lookSpeed() const
-{
- Q_D(const QFirstPersonCameraController);
- return d->m_lookSpeed;
-}
-
-/*!
- \property QFirstPersonCameraController::acceleration
-
- Holds the current acceleration of the camera controller.
-*/
-float QFirstPersonCameraController::acceleration() const
-{
- Q_D(const QFirstPersonCameraController);
- return d->m_acceleration;
-}
-
-/*!
- \property QFirstPersonCameraController::deceleration
-
- Holds the current deceleration of the camera controller.
-*/
-float QFirstPersonCameraController::deceleration() const
-{
- Q_D(const QFirstPersonCameraController);
- return d->m_deceleration;
-}
-
-void QFirstPersonCameraController::setCamera(Qt3DRender::QCamera *camera)
-{
- Q_D(QFirstPersonCameraController);
- if (d->m_camera != camera) {
-
- if (d->m_camera)
- d->unregisterDestructionHelper(d->m_camera);
-
- if (camera && !camera->parent())
- camera->setParent(this);
-
- d->m_camera = camera;
-
- // Ensures proper bookkeeping
- if (d->m_camera)
- d->registerDestructionHelper(d->m_camera, &QFirstPersonCameraController::setCamera, d->m_camera);
-
- emit cameraChanged();
- }
-}
-
-void QFirstPersonCameraController::setLinearSpeed(float linearSpeed)
-{
- Q_D(QFirstPersonCameraController);
- if (d->m_linearSpeed != linearSpeed) {
- d->m_linearSpeed = linearSpeed;
- emit linearSpeedChanged();
- }
-}
-
-void QFirstPersonCameraController::setLookSpeed(float lookSpeed)
-{
- Q_D(QFirstPersonCameraController);
- if (d->m_lookSpeed != lookSpeed) {
- d->m_lookSpeed = lookSpeed;
- emit lookSpeedChanged();
- }
-}
+ Qt3DRender::QCamera *theCamera = camera();
+
+ if (theCamera == nullptr)
+ return;
+
+ theCamera->translate(QVector3D(state.txAxisValue * linearSpeed(),
+ state.tyAxisValue * linearSpeed(),
+ state.tzAxisValue * linearSpeed()) * dt);
+ if (state.leftMouseButtonActive) {
+ float theLookSpeed = lookSpeed();
+ if (state.shiftKeyActive) {
+ theLookSpeed *= 0.2f;
+ }
-void QFirstPersonCameraController::setAcceleration(float acceleration)
-{
- Q_D(QFirstPersonCameraController);
- if (d->m_acceleration != acceleration) {
- d->m_acceleration = acceleration;
- d->applyAccelerations();
- emit accelerationChanged(acceleration);
- }
-}
+ const QVector3D upVector(0.0f, 1.0f, 0.0f);
-void QFirstPersonCameraController::setDeceleration(float deceleration)
-{
- Q_D(QFirstPersonCameraController);
- if (d->m_deceleration != deceleration) {
- d->m_deceleration = deceleration;
- d->applyAccelerations();
- emit decelerationChanged(deceleration);
+ theCamera->pan(state.rxAxisValue * theLookSpeed * dt, upVector);
+ theCamera->tilt(state.ryAxisValue * theLookSpeed * dt);
}
}
diff --git a/src/extras/defaults/qfirstpersoncameracontroller.h b/src/extras/defaults/qfirstpersoncameracontroller.h
index 3f7a6acc4..60edf7cb8 100644
--- a/src/extras/defaults/qfirstpersoncameracontroller.h
+++ b/src/extras/defaults/qfirstpersoncameracontroller.h
@@ -37,53 +37,22 @@
#ifndef QT3DEXTRAS_QFIRSTPERSONCAMERACONTROLLER_H
#define QT3DEXTRAS_QFIRSTPERSONCAMERACONTROLLER_H
-#include <Qt3DExtras/qt3dextras_global.h>
-#include <Qt3DCore/QEntity>
+#include <Qt3DExtras/qabstractcameracontroller.h>
QT_BEGIN_NAMESPACE
-namespace Qt3DRender {
-class QCamera;
-}
-
namespace Qt3DExtras {
-class QFirstPersonCameraControllerPrivate;
-
-class QT3DEXTRASSHARED_EXPORT QFirstPersonCameraController : public Qt3DCore::QEntity
+class QT3DEXTRASSHARED_EXPORT QFirstPersonCameraController : public QAbstractCameraController
{
Q_OBJECT
- Q_PROPERTY(Qt3DRender::QCamera *camera READ camera WRITE setCamera NOTIFY cameraChanged)
- Q_PROPERTY(float linearSpeed READ linearSpeed WRITE setLinearSpeed NOTIFY linearSpeedChanged)
- Q_PROPERTY(float lookSpeed READ lookSpeed WRITE setLookSpeed NOTIFY lookSpeedChanged)
- Q_PROPERTY(float acceleration READ acceleration WRITE setAcceleration NOTIFY accelerationChanged)
- Q_PROPERTY(float deceleration READ deceleration WRITE setDeceleration NOTIFY decelerationChanged)
+
public:
explicit QFirstPersonCameraController(Qt3DCore::QNode *parent = nullptr);
~QFirstPersonCameraController();
- Qt3DRender::QCamera *camera() const;
- float linearSpeed() const;
- float lookSpeed() const;
- float acceleration() const;
- float deceleration() const;
-
- void setCamera(Qt3DRender::QCamera *camera);
- void setLinearSpeed(float linearSpeed);
- void setLookSpeed(float lookSpeed);
- void setAcceleration(float acceleration);
- void setDeceleration(float deceleration);
-
-Q_SIGNALS:
- void cameraChanged();
- void linearSpeedChanged();
- void lookSpeedChanged();
- void accelerationChanged(float acceleration);
- void decelerationChanged(float deceleration);
-
private:
- Q_DECLARE_PRIVATE(QFirstPersonCameraController)
- Q_PRIVATE_SLOT(d_func(), void _q_onTriggered(float))
+ void moveCamera(const QAbstractCameraController::InputState &state, float dt) override;
};
} // Qt3DExtras
diff --git a/src/extras/defaults/qfirstpersoncameracontroller_p.h b/src/extras/defaults/qfirstpersoncameracontroller_p.h
deleted file mode 100644
index 48a7c7998..000000000
--- a/src/extras/defaults/qfirstpersoncameracontroller_p.h
+++ /dev/null
@@ -1,152 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB).
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt3D 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$
-**
-****************************************************************************/
-
-#ifndef QT3DEXTRAS_QFIRSTPERSONCAMERACONTROLLER_P_H
-#define QT3DEXTRAS_QFIRSTPERSONCAMERACONTROLLER_P_H
-
-#include <Qt3DExtras/qfirstpersoncameracontroller.h>
-#include <QtGui/QVector3D>
-
-#include <Qt3DCore/private/qentity_p.h>
-
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-QT_BEGIN_NAMESPACE
-
-namespace Qt3DRender {
-class QCamera;
-}
-
-namespace Qt3DLogic {
-class QFrameAction;
-}
-
-namespace Qt3DInput {
-
-class QKeyboardDevice;
-class QMouseDevice;
-class QLogicalDevice;
-class QAction;
-class QActionInput;
-class QAxis;
-class QAnalogAxisInput;
-class QButtonAxisInput;
-class QAxisActionHandler;
-
-}
-
-namespace Qt3DExtras {
-
-class QFirstPersonCameraControllerPrivate : public Qt3DCore::QEntityPrivate
-{
-public:
- QFirstPersonCameraControllerPrivate();
-
- void init();
- void applyAccelerations();
-
- Qt3DRender::QCamera *m_camera;
-
- Qt3DInput::QAction *m_leftMouseButtonAction;
- Qt3DInput::QAction *m_fineMotionAction;
-
- Qt3DInput::QAxis *m_rxAxis;
- Qt3DInput::QAxis *m_ryAxis;
- Qt3DInput::QAxis *m_txAxis;
- Qt3DInput::QAxis *m_tyAxis;
- Qt3DInput::QAxis *m_tzAxis;
-
- Qt3DInput::QActionInput *m_leftMouseButtonInput;
- Qt3DInput::QActionInput *m_fineMotionKeyInput;
-
- Qt3DInput::QAnalogAxisInput *m_mouseRxInput;
- Qt3DInput::QAnalogAxisInput *m_mouseRyInput;
- Qt3DInput::QAnalogAxisInput *m_mouseTzXInput;
- Qt3DInput::QAnalogAxisInput *m_mouseTzYInput;
- Qt3DInput::QButtonAxisInput *m_keyboardTxPosInput;
- Qt3DInput::QButtonAxisInput *m_keyboardTyPosInput;
- Qt3DInput::QButtonAxisInput *m_keyboardTzPosInput;
- Qt3DInput::QButtonAxisInput *m_keyboardTxNegInput;
- Qt3DInput::QButtonAxisInput *m_keyboardTyNegInput;
- Qt3DInput::QButtonAxisInput *m_keyboardTzNegInput;
-
- Qt3DInput::QKeyboardDevice *m_keyboardDevice;
- Qt3DInput::QMouseDevice *m_mouseDevice;
-
- Qt3DInput::QLogicalDevice *m_logicalDevice;
-
- Qt3DLogic::QFrameAction *m_frameAction;
-
- float m_linearSpeed;
- float m_lookSpeed;
- float m_acceleration;
- float m_deceleration;
- QVector3D m_firstPersonUp;
-
- void _q_onTriggered(float);
-
- Q_DECLARE_PUBLIC(QFirstPersonCameraController)
-};
-
-} // Qt3DInput
-
-QT_END_NAMESPACE
-
-#endif // QT3DINPUT_QFIRSTPERSONCAMERACONTROLLER_P_H
diff --git a/src/extras/defaults/qmetalroughmaterial.cpp b/src/extras/defaults/qmetalroughmaterial.cpp
index c3d59d9de..ac6117101 100644
--- a/src/extras/defaults/qmetalroughmaterial.cpp
+++ b/src/extras/defaults/qmetalroughmaterial.cpp
@@ -71,6 +71,7 @@ QMetalRoughMaterialPrivate::QMetalRoughMaterialPrivate()
, m_roughnessMapParameter(new QParameter(QStringLiteral("roughnessMap"), QVariant()))
, m_ambientOcclusionMapParameter(new QParameter(QStringLiteral("ambientOcclusionMap"), QVariant()))
, m_normalMapParameter(new QParameter(QStringLiteral("normalMap"), QVariant()))
+ , m_textureScaleParameter(new QParameter(QStringLiteral("texCoordScale"), 1.0f))
, m_environmentIrradianceParameter(new QParameter(QStringLiteral("envLight.irradiance"), m_environmentIrradianceTexture))
, m_environmentSpecularParameter(new QParameter(QStringLiteral("envLight.specular"), m_environmentSpecularTexture))
, m_metalRoughEffect(new QEffect())
@@ -107,8 +108,10 @@ void QMetalRoughMaterialPrivate::init()
q, &QMetalRoughMaterial::roughnessChanged);
QObject::connect(m_normalMapParameter, &Qt3DRender::QParameter::valueChanged,
q, &QMetalRoughMaterial::roughnessChanged);
+ connect(m_textureScaleParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QMetalRoughMaterialPrivate::handleTextureScaleChanged);
- m_metalRoughGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/metalrough.vert"))));
+ m_metalRoughGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/default.vert"))));
m_metalRoughGL3ShaderBuilder->setParent(q);
m_metalRoughGL3ShaderBuilder->setShaderProgram(m_metalRoughGL3Shader);
@@ -136,6 +139,7 @@ void QMetalRoughMaterialPrivate::init()
m_metalRoughEffect->addParameter(m_baseColorParameter);
m_metalRoughEffect->addParameter(m_metalnessParameter);
m_metalRoughEffect->addParameter(m_roughnessParameter);
+ m_metalRoughEffect->addParameter(m_textureScaleParameter);
// Note that even though those parameters are not exposed in the API,
// they need to be kept around for now due to a bug in some drivers/GPUs
@@ -149,6 +153,12 @@ void QMetalRoughMaterialPrivate::init()
q->setEffect(m_metalRoughEffect);
}
+void QMetalRoughMaterialPrivate::handleTextureScaleChanged(const QVariant &var)
+{
+ Q_Q(QMetalRoughMaterial);
+ emit q->textureScaleChanged(var.toFloat());
+}
+
/*!
\class Qt3DExtras::QMetalRoughMaterial
\brief The QMetalRoughMaterial provides a default implementation of PBR
@@ -249,6 +259,18 @@ QVariant QMetalRoughMaterial::normal() const
return d->m_normalMapParameter->value();
}
+/*!
+ \property QMetalRoughMaterial::textureScale
+
+ Holds the current texture scale. It is applied as a multiplier to texture
+ coordinates at render time. Defaults to 1.0.
+*/
+float QMetalRoughMaterial::textureScale() const
+{
+ Q_D(const QMetalRoughMaterial);
+ return d->m_textureScaleParameter->value().toFloat();
+}
+
void QMetalRoughMaterial::setBaseColor(const QVariant &baseColor)
{
Q_D(QMetalRoughMaterial);
@@ -348,6 +370,12 @@ void QMetalRoughMaterial::setNormal(const QVariant &normal)
d->m_metalRoughGL3ShaderBuilder->setEnabledLayers(layers);
}
+void QMetalRoughMaterial::setTextureScale(float textureScale)
+{
+ Q_D(QMetalRoughMaterial);
+ d->m_textureScaleParameter->setValue(textureScale);
+}
+
} // namespace Qt3DExtras
QT_END_NAMESPACE
diff --git a/src/extras/defaults/qmetalroughmaterial.h b/src/extras/defaults/qmetalroughmaterial.h
index 6da00ec08..400437338 100644
--- a/src/extras/defaults/qmetalroughmaterial.h
+++ b/src/extras/defaults/qmetalroughmaterial.h
@@ -62,6 +62,7 @@ class QT3DEXTRASSHARED_EXPORT QMetalRoughMaterial : public Qt3DRender::QMaterial
Q_PROPERTY(QVariant roughness READ roughness WRITE setRoughness NOTIFY roughnessChanged)
Q_PROPERTY(QVariant ambientOcclusion READ ambientOcclusion WRITE setAmbientOcclusion NOTIFY ambientOcclusionChanged REVISION 10)
Q_PROPERTY(QVariant normal READ normal WRITE setNormal NOTIFY normalChanged REVISION 10)
+ Q_PROPERTY(float textureScale READ textureScale WRITE setTextureScale NOTIFY textureScaleChanged REVISION 10)
public:
explicit QMetalRoughMaterial(Qt3DCore::QNode *parent = nullptr);
@@ -72,6 +73,7 @@ public:
QVariant roughness() const;
QVariant ambientOcclusion() const;
QVariant normal() const;
+ float textureScale() const;
public Q_SLOTS:
void setBaseColor(const QVariant &baseColor);
@@ -79,6 +81,7 @@ public Q_SLOTS:
void setRoughness(const QVariant &roughness);
void setAmbientOcclusion(const QVariant &ambientOcclusion);
void setNormal(const QVariant &normal);
+ void setTextureScale(float textureScale);
Q_SIGNALS:
void baseColorChanged(const QVariant &baseColor);
@@ -86,6 +89,7 @@ Q_SIGNALS:
void roughnessChanged(const QVariant &roughness);
void ambientOcclusionChanged(const QVariant &ambientOcclusion);
void normalChanged(const QVariant &normal);
+ void textureScaleChanged(float textureScale);
protected:
explicit QMetalRoughMaterial(QMetalRoughMaterialPrivate &dd, Qt3DCore::QNode *parent = nullptr);
diff --git a/src/extras/defaults/qmetalroughmaterial_p.h b/src/extras/defaults/qmetalroughmaterial_p.h
index 8d6cbfcad..838474490 100644
--- a/src/extras/defaults/qmetalroughmaterial_p.h
+++ b/src/extras/defaults/qmetalroughmaterial_p.h
@@ -79,6 +79,8 @@ public:
void init();
+ void handleTextureScaleChanged(const QVariant &var);
+
Qt3DRender::QAbstractTexture *m_environmentIrradianceTexture;
Qt3DRender::QAbstractTexture *m_environmentSpecularTexture;
Qt3DRender::QParameter *m_baseColorParameter;
@@ -89,6 +91,7 @@ public:
Qt3DRender::QParameter *m_roughnessMapParameter;
Qt3DRender::QParameter *m_ambientOcclusionMapParameter;
Qt3DRender::QParameter *m_normalMapParameter;
+ Qt3DRender::QParameter *m_textureScaleParameter;
Qt3DRender::QParameter *m_environmentIrradianceParameter;
Qt3DRender::QParameter *m_environmentSpecularParameter;
Qt3DRender::QEffect *m_metalRoughEffect;
diff --git a/src/extras/defaults/qnormaldiffusemapalphamaterial.cpp b/src/extras/defaults/qnormaldiffusemapalphamaterial.cpp
index eb6398341..dd8288683 100644
--- a/src/extras/defaults/qnormaldiffusemapalphamaterial.cpp
+++ b/src/extras/defaults/qnormaldiffusemapalphamaterial.cpp
@@ -82,10 +82,10 @@ void QNormalDiffuseMapAlphaMaterialPrivate::init()
connect(m_textureScaleParameter, &Qt3DRender::QParameter::valueChanged,
this, &QNormalDiffuseMapMaterialPrivate::handleTextureScaleChanged);
- m_normalDiffuseGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/normaldiffusemap.vert"))));
- m_normalDiffuseGL3Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/normaldiffusemapalpha.frag"))));
- m_normalDiffuseGL2ES2Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/normaldiffusemap.vert"))));
- m_normalDiffuseGL2ES2Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/normaldiffusemapalpha.frag"))));
+ m_normalDiffuseGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/default.vert"))));
+ m_normalDiffuseGL3Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/normaldiffusemap.frag"))));
+ m_normalDiffuseGL2ES2Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/default.vert"))));
+ m_normalDiffuseGL2ES2Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/normaldiffusemap.frag"))));
m_normalDiffuseGL3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
m_normalDiffuseGL3Technique->graphicsApiFilter()->setMajorVersion(3);
diff --git a/src/extras/defaults/qnormaldiffusemapmaterial.cpp b/src/extras/defaults/qnormaldiffusemapmaterial.cpp
index 35cea095a..ec3bd0a22 100644
--- a/src/extras/defaults/qnormaldiffusemapmaterial.cpp
+++ b/src/extras/defaults/qnormaldiffusemapmaterial.cpp
@@ -107,9 +107,9 @@ void QNormalDiffuseMapMaterialPrivate::init()
connect(m_textureScaleParameter, &Qt3DRender::QParameter::valueChanged,
this, &QNormalDiffuseMapMaterialPrivate::handleTextureScaleChanged);
- m_normalDiffuseGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/normaldiffusemap.vert"))));
+ m_normalDiffuseGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/default.vert"))));
m_normalDiffuseGL3Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/normaldiffusemap.frag"))));
- m_normalDiffuseGL2ES2Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/normaldiffusemap.vert"))));
+ m_normalDiffuseGL2ES2Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/default.vert"))));
m_normalDiffuseGL2ES2Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/normaldiffusemap.frag"))));
m_normalDiffuseGL3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
diff --git a/src/extras/defaults/qnormaldiffusespecularmapmaterial.cpp b/src/extras/defaults/qnormaldiffusespecularmapmaterial.cpp
index c6f8ced9c..eaa1491a0 100644
--- a/src/extras/defaults/qnormaldiffusespecularmapmaterial.cpp
+++ b/src/extras/defaults/qnormaldiffusespecularmapmaterial.cpp
@@ -115,9 +115,9 @@ void QNormalDiffuseSpecularMapMaterialPrivate::init()
connect(m_textureScaleParameter, &Qt3DRender::QParameter::valueChanged,
this, &QNormalDiffuseSpecularMapMaterialPrivate::handleTextureScaleChanged);
- m_normalDiffuseSpecularGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/normaldiffusemap.vert"))));
+ m_normalDiffuseSpecularGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/default.vert"))));
m_normalDiffuseSpecularGL3Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/normaldiffusespecularmap.frag"))));
- m_normalDiffuseSpecularGL2ES2Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/normaldiffusemap.vert"))));
+ m_normalDiffuseSpecularGL2ES2Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/default.vert"))));
m_normalDiffuseSpecularGL2ES2Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/normaldiffusespecularmap.frag"))));
m_normalDiffuseSpecularGL3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
diff --git a/src/extras/defaults/qorbitcameracontroller.cpp b/src/extras/defaults/qorbitcameracontroller.cpp
index 565a75ea1..03e9a290b 100644
--- a/src/extras/defaults/qorbitcameracontroller.cpp
+++ b/src/extras/defaults/qorbitcameracontroller.cpp
@@ -38,22 +38,15 @@
#include "qorbitcameracontroller_p.h"
#include <Qt3DRender/QCamera>
-#include <Qt3DInput/QAxis>
-#include <Qt3DInput/QAnalogAxisInput>
-#include <Qt3DInput/QButtonAxisInput>
-#include <Qt3DInput/QAction>
-#include <Qt3DInput/QActionInput>
-#include <Qt3DInput/QLogicalDevice>
-#include <Qt3DInput/QKeyboardDevice>
-#include <Qt3DInput/QMouseDevice>
-#include <Qt3DInput/QMouseEvent>
-#include <Qt3DLogic/QFrameAction>
-#include <QtCore/QtGlobal>
QT_BEGIN_NAMESPACE
namespace Qt3DExtras {
+QOrbitCameraControllerPrivate::QOrbitCameraControllerPrivate()
+ : m_zoomInLimit(2.0f)
+{}
+
/*!
\class Qt3DExtras::QOrbitCameraController
\brief The QOrbitCameraController class allows controlling the scene camera along orbital path.
@@ -99,251 +92,20 @@ namespace Qt3DExtras {
\endtable
*/
-QOrbitCameraControllerPrivate::QOrbitCameraControllerPrivate()
- : Qt3DCore::QEntityPrivate()
- , m_camera(nullptr)
- , m_leftMouseButtonAction(new Qt3DInput::QAction())
- , m_rightMouseButtonAction(new Qt3DInput::QAction())
- , m_altButtonAction(new Qt3DInput::QAction())
- , m_shiftButtonAction(new Qt3DInput::QAction())
- , m_rxAxis(new Qt3DInput::QAxis())
- , m_ryAxis(new Qt3DInput::QAxis())
- , m_txAxis(new Qt3DInput::QAxis())
- , m_tyAxis(new Qt3DInput::QAxis())
- , m_tzAxis(new Qt3DInput::QAxis())
- , m_leftMouseButtonInput(new Qt3DInput::QActionInput())
- , m_rightMouseButtonInput(new Qt3DInput::QActionInput())
- , m_altButtonInput(new Qt3DInput::QActionInput())
- , m_shiftButtonInput(new Qt3DInput::QActionInput())
- , m_mouseRxInput(new Qt3DInput::QAnalogAxisInput())
- , m_mouseRyInput(new Qt3DInput::QAnalogAxisInput())
- , m_mouseTzXInput(new Qt3DInput::QAnalogAxisInput())
- , m_mouseTzYInput(new Qt3DInput::QAnalogAxisInput())
- , m_keyboardTxPosInput(new Qt3DInput::QButtonAxisInput())
- , m_keyboardTyPosInput(new Qt3DInput::QButtonAxisInput())
- , m_keyboardTzPosInput(new Qt3DInput::QButtonAxisInput())
- , m_keyboardTxNegInput(new Qt3DInput::QButtonAxisInput())
- , m_keyboardTyNegInput(new Qt3DInput::QButtonAxisInput())
- , m_keyboardTzNegInput(new Qt3DInput::QButtonAxisInput())
- , m_keyboardDevice(new Qt3DInput::QKeyboardDevice())
- , m_mouseDevice(new Qt3DInput::QMouseDevice())
- , m_logicalDevice(new Qt3DInput::QLogicalDevice())
- , m_frameAction(new Qt3DLogic::QFrameAction())
- , m_linearSpeed(10.0f)
- , m_lookSpeed(180.0f)
- , m_zoomInLimit(2.0f)
- , m_cameraUp(QVector3D(0.0f, 1.0f, 0.0f))
-{}
-
-void QOrbitCameraControllerPrivate::init()
-{
- //// Actions
-
- // Left Mouse Button Action
- m_leftMouseButtonInput->setButtons(QVector<int>() << Qt::LeftButton);
- m_leftMouseButtonInput->setSourceDevice(m_mouseDevice);
- m_leftMouseButtonAction->addInput(m_leftMouseButtonInput);
-
- // Right Mouse Button Action
- m_rightMouseButtonInput->setButtons(QVector<int>() << Qt::RightButton);
- m_rightMouseButtonInput->setSourceDevice(m_mouseDevice);
- m_rightMouseButtonAction->addInput(m_rightMouseButtonInput);
-
- // Alt Button Action
- m_altButtonInput->setButtons(QVector<int>() << Qt::Key_Alt);
- m_altButtonInput->setSourceDevice(m_keyboardDevice);
- m_altButtonAction->addInput(m_altButtonInput);
-
- // Shift Button Action
- m_shiftButtonInput->setButtons(QVector<int>() << Qt::Key_Shift);
- m_shiftButtonInput->setSourceDevice(m_keyboardDevice);
- m_shiftButtonAction->addInput(m_shiftButtonInput);
-
- //// Axes
-
- // Mouse X
- m_mouseRxInput->setAxis(Qt3DInput::QMouseDevice::X);
- m_mouseRxInput->setSourceDevice(m_mouseDevice);
- m_rxAxis->addInput(m_mouseRxInput);
-
- // Mouse Y
- m_mouseRyInput->setAxis(Qt3DInput::QMouseDevice::Y);
- m_mouseRyInput->setSourceDevice(m_mouseDevice);
- m_ryAxis->addInput(m_mouseRyInput);
-
- // Mouse Wheel X
- m_mouseTzXInput->setAxis(Qt3DInput::QMouseDevice::WheelX);
- m_mouseTzXInput->setSourceDevice(m_mouseDevice);
- m_tzAxis->addInput(m_mouseTzXInput);
-
- // Mouse Wheel Y
- m_mouseTzYInput->setAxis(Qt3DInput::QMouseDevice::WheelY);
- m_mouseTzYInput->setSourceDevice(m_mouseDevice);
- m_tzAxis->addInput(m_mouseTzYInput);
-
- // Keyboard Pos Tx
- m_keyboardTxPosInput->setButtons(QVector<int>() << Qt::Key_Right);
- m_keyboardTxPosInput->setScale(1.0f);
- m_keyboardTxPosInput->setSourceDevice(m_keyboardDevice);
- m_txAxis->addInput(m_keyboardTxPosInput);
-
- // Keyboard Pos Tz
- m_keyboardTzPosInput->setButtons(QVector<int>() << Qt::Key_PageUp);
- m_keyboardTzPosInput->setScale(1.0f);
- m_keyboardTzPosInput->setSourceDevice(m_keyboardDevice);
- m_tzAxis->addInput(m_keyboardTzPosInput);
-
- // Keyboard Pos Ty
- m_keyboardTyPosInput->setButtons(QVector<int>() << Qt::Key_Up);
- m_keyboardTyPosInput->setScale(1.0f);
- m_keyboardTyPosInput->setSourceDevice(m_keyboardDevice);
- m_tyAxis->addInput(m_keyboardTyPosInput);
-
- // Keyboard Neg Tx
- m_keyboardTxNegInput->setButtons(QVector<int>() << Qt::Key_Left);
- m_keyboardTxNegInput->setScale(-1.0f);
- m_keyboardTxNegInput->setSourceDevice(m_keyboardDevice);
- m_txAxis->addInput(m_keyboardTxNegInput);
-
- // Keyboard Neg Tz
- m_keyboardTzNegInput->setButtons(QVector<int>() << Qt::Key_PageDown);
- m_keyboardTzNegInput->setScale(-1.0f);
- m_keyboardTzNegInput->setSourceDevice(m_keyboardDevice);
- m_tzAxis->addInput(m_keyboardTzNegInput);
-
- // Keyboard Neg Ty
- m_keyboardTyNegInput->setButtons(QVector<int>() << Qt::Key_Down);
- m_keyboardTyNegInput->setScale(-1.0f);
- m_keyboardTyNegInput->setSourceDevice(m_keyboardDevice);
- m_tyAxis->addInput(m_keyboardTyNegInput);
-
- //// Logical Device
-
- m_logicalDevice->addAction(m_leftMouseButtonAction);
- m_logicalDevice->addAction(m_rightMouseButtonAction);
- m_logicalDevice->addAction(m_altButtonAction);
- m_logicalDevice->addAction(m_shiftButtonAction);
- m_logicalDevice->addAxis(m_rxAxis);
- m_logicalDevice->addAxis(m_ryAxis);
- m_logicalDevice->addAxis(m_txAxis);
- m_logicalDevice->addAxis(m_tyAxis);
- m_logicalDevice->addAxis(m_tzAxis);
-
- Q_Q(QOrbitCameraController);
- //// FrameAction
-
- QObject::connect(m_frameAction, SIGNAL(triggered(float)),
- q, SLOT(_q_onTriggered(float)));
-
- // Disable the logical device when the entity is disabled
- QObject::connect(q, &Qt3DCore::QEntity::enabledChanged,
- m_logicalDevice, &Qt3DInput::QLogicalDevice::setEnabled);
-
- q->addComponent(m_frameAction);
- q->addComponent(m_logicalDevice);
-}
-
-float clampInputs(float input1, float input2)
-{
- float axisValue = input1 + input2;
- return (axisValue < -1) ? -1 : (axisValue > 1) ? 1 : axisValue;
-}
-
-float zoomDistance(QVector3D firstPoint, QVector3D secondPoint)
-{
- return (secondPoint - firstPoint).lengthSquared();
-}
-
-void QOrbitCameraControllerPrivate::_q_onTriggered(float dt)
-{
- if (m_camera != nullptr) {
- // Mouse input
- if (m_leftMouseButtonAction->isActive()) {
- if (m_rightMouseButtonAction->isActive()) {
- if ( zoomDistance(m_camera->position(), m_camera->viewCenter()) > m_zoomInLimit * m_zoomInLimit) {
- // Dolly up to limit
- m_camera->translate(QVector3D(0, 0, m_ryAxis->value()), m_camera->DontTranslateViewCenter);
- } else {
- m_camera->translate(QVector3D(0, 0, -0.5), m_camera->DontTranslateViewCenter);
- }
- } else {
- // Translate
- m_camera->translate(QVector3D(clampInputs(m_rxAxis->value(), m_txAxis->value()) * m_linearSpeed,
- clampInputs(m_ryAxis->value(), m_tyAxis->value()) * m_linearSpeed,
- 0) * dt);
- }
- return;
- }
- else if (m_rightMouseButtonAction->isActive()) {
- // Orbit
- m_camera->panAboutViewCenter((m_rxAxis->value() * m_lookSpeed) * dt, m_cameraUp);
- m_camera->tiltAboutViewCenter((m_ryAxis->value() * m_lookSpeed) * dt);
- }
- // Keyboard Input
- if (m_altButtonAction->isActive()) {
- // Orbit
- m_camera->panAboutViewCenter((m_txAxis->value() * m_lookSpeed) * dt, m_cameraUp);
- m_camera->tiltAboutViewCenter((m_tyAxis->value() * m_lookSpeed) * dt);
- } else if (m_shiftButtonAction->isActive()) {
- if (zoomDistance(m_camera->position(), m_camera->viewCenter()) > m_zoomInLimit * m_zoomInLimit) {
- // Dolly
- m_camera->translate(QVector3D(0, 0, m_tyAxis->value()), m_camera->DontTranslateViewCenter);
- } else {
- m_camera->translate(QVector3D(0, 0, -0.5), m_camera->DontTranslateViewCenter);
- }
- } else {
- // Translate
- m_camera->translate(QVector3D(clampInputs(m_leftMouseButtonAction->isActive() ? m_rxAxis->value() : 0, m_txAxis->value()) * m_linearSpeed,
- clampInputs(m_leftMouseButtonAction->isActive() ? m_ryAxis->value() : 0, m_tyAxis->value()) * m_linearSpeed,
- m_tzAxis->value() * m_linearSpeed) * dt);
- }
- }
-}
-
QOrbitCameraController::QOrbitCameraController(Qt3DCore::QNode *parent)
- : Qt3DCore::QEntity(*new QOrbitCameraControllerPrivate, parent)
+ : QOrbitCameraController(*new QOrbitCameraControllerPrivate, parent)
{
- Q_D(QOrbitCameraController);
- d->init();
}
-QOrbitCameraController::~QOrbitCameraController()
+/*! \internal
+ */
+QOrbitCameraController::QOrbitCameraController(QOrbitCameraControllerPrivate &dd, Qt3DCore::QNode *parent)
+ : QAbstractCameraController(dd, parent)
{
}
-/*!
- \property QOrbitCameraController::camera
-
- Holds the currently controlled camera.
-*/
-Qt3DRender::QCamera *QOrbitCameraController::camera() const
-{
- Q_D(const QOrbitCameraController);
- return d->m_camera;
-}
-
-/*!
- \property QOrbitCameraController::linearSpeed
-
- Holds the current linear speed of the camera controller. Linear speed determines the
- movement speed of the camera.
-*/
-float QOrbitCameraController::linearSpeed() const
-{
- Q_D(const QOrbitCameraController);
- return d->m_linearSpeed;
-}
-
-/*!
- \property QOrbitCameraController::lookSpeed
-
- Holds the current look speed of the camera controller. The look speed determines the turn rate
- of the camera pan and tilt.
-*/
-float QOrbitCameraController::lookSpeed() const
+QOrbitCameraController::~QOrbitCameraController()
{
- Q_D(const QOrbitCameraController);
- return d->m_lookSpeed;
}
/*!
@@ -358,51 +120,77 @@ float QOrbitCameraController::zoomInLimit() const
return d->m_zoomInLimit;
}
-void QOrbitCameraController::setCamera(Qt3DRender::QCamera *camera)
+void QOrbitCameraController::setZoomInLimit(float zoomInLimit)
{
Q_D(QOrbitCameraController);
- if (d->m_camera != camera) {
-
- if (d->m_camera)
- d->unregisterDestructionHelper(d->m_camera);
-
- if (camera && !camera->parent())
- camera->setParent(this);
-
- d->m_camera = camera;
-
- // Ensures proper bookkeeping
- if (d->m_camera)
- d->registerDestructionHelper(d->m_camera, &QOrbitCameraController::setCamera, d->m_camera);
-
- emit cameraChanged();
+ if (d->m_zoomInLimit != zoomInLimit) {
+ d->m_zoomInLimit = zoomInLimit;
+ emit zoomInLimitChanged();
}
}
-void QOrbitCameraController::setLinearSpeed(float linearSpeed)
+inline float clampInputs(float input1, float input2)
{
- Q_D(QOrbitCameraController);
- if (d->m_linearSpeed != linearSpeed) {
- d->m_linearSpeed = linearSpeed;
- emit linearSpeedChanged();
- }
+ float axisValue = input1 + input2;
+ return (axisValue < -1) ? -1 : (axisValue > 1) ? 1 : axisValue;
}
-void QOrbitCameraController::setLookSpeed(float lookSpeed)
+inline float zoomDistance(QVector3D firstPoint, QVector3D secondPoint)
{
- Q_D(QOrbitCameraController);
- if (d->m_lookSpeed != lookSpeed) {
- d->m_lookSpeed = lookSpeed;
- emit lookSpeedChanged();
- }
+ return (secondPoint - firstPoint).lengthSquared();
}
-void QOrbitCameraController::setZoomInLimit(float zoomInLimit)
+void QOrbitCameraController::moveCamera(const QAbstractCameraController::InputState &state, float dt)
{
Q_D(QOrbitCameraController);
- if (d->m_zoomInLimit != zoomInLimit) {
- d->m_zoomInLimit = zoomInLimit;
- emit zoomInLimitChanged();
+
+ Qt3DRender::QCamera *theCamera = camera();
+
+ if (theCamera == nullptr)
+ return;
+
+ const QVector3D upVector(0.0f, 1.0f, 0.0f);
+
+ // Mouse input
+ if (state.leftMouseButtonActive) {
+ if (state.rightMouseButtonActive) {
+ if ( zoomDistance(camera()->position(), theCamera->viewCenter()) > d->m_zoomInLimit * d->m_zoomInLimit) {
+ // Dolly up to limit
+ theCamera->translate(QVector3D(0, 0, state.ryAxisValue), theCamera->DontTranslateViewCenter);
+ } else {
+ theCamera->translate(QVector3D(0, 0, -0.5), theCamera->DontTranslateViewCenter);
+ }
+ } else {
+ // Translate
+ theCamera->translate(QVector3D(clampInputs(state.rxAxisValue, state.txAxisValue) * linearSpeed(),
+ clampInputs(state.ryAxisValue, state.tyAxisValue) * linearSpeed(),
+ 0) * dt);
+ }
+ return;
+ }
+ else if (state.rightMouseButtonActive) {
+ // Orbit
+ theCamera->panAboutViewCenter((state.rxAxisValue * lookSpeed()) * dt, upVector);
+ theCamera->tiltAboutViewCenter((state.ryAxisValue * lookSpeed()) * dt);
+ }
+
+ // Keyboard Input
+ if (state.altKeyActive) {
+ // Orbit
+ theCamera->panAboutViewCenter((state.txAxisValue * lookSpeed()) * dt, upVector);
+ theCamera->tiltAboutViewCenter((state.tyAxisValue * lookSpeed()) * dt);
+ } else if (state.shiftKeyActive) {
+ if (zoomDistance(camera()->position(), theCamera->viewCenter()) > d->m_zoomInLimit * d->m_zoomInLimit) {
+ // Dolly
+ theCamera->translate(QVector3D(0, 0, state.tyAxisValue), theCamera->DontTranslateViewCenter);
+ } else {
+ theCamera->translate(QVector3D(0, 0, -0.5), theCamera->DontTranslateViewCenter);
+ }
+ } else {
+ // Translate
+ theCamera->translate(QVector3D(clampInputs(state.leftMouseButtonActive ? state.rxAxisValue : 0, state.txAxisValue) * linearSpeed(),
+ clampInputs(state.leftMouseButtonActive ? state.ryAxisValue : 0, state.tyAxisValue) * linearSpeed(),
+ state.tzAxisValue * linearSpeed()) * dt);
}
}
diff --git a/src/extras/defaults/qorbitcameracontroller.h b/src/extras/defaults/qorbitcameracontroller.h
index 7cb8b3eb7..684bfddf1 100644
--- a/src/extras/defaults/qorbitcameracontroller.h
+++ b/src/extras/defaults/qorbitcameracontroller.h
@@ -37,50 +37,38 @@
#ifndef QT3DEXTRAS_QORBITCAMERACONTROLLER_H
#define QT3DEXTRAS_QORBITCAMERACONTROLLER_H
-#include <Qt3DCore/QEntity>
-#include <Qt3DExtras/qt3dextras_global.h>
+#include <Qt3DExtras/qabstractcameracontroller.h>
QT_BEGIN_NAMESPACE
-namespace Qt3DRender {
-class QCamera;
-}
-
namespace Qt3DExtras {
class QOrbitCameraControllerPrivate;
-class QT3DEXTRASSHARED_EXPORT QOrbitCameraController : public Qt3DCore::QEntity
+class QT3DEXTRASSHARED_EXPORT QOrbitCameraController : public QAbstractCameraController
{
Q_OBJECT
- Q_PROPERTY(Qt3DRender::QCamera *camera READ camera WRITE setCamera NOTIFY cameraChanged)
- Q_PROPERTY(float linearSpeed READ linearSpeed WRITE setLinearSpeed NOTIFY linearSpeedChanged)
- Q_PROPERTY(float lookSpeed READ lookSpeed WRITE setLookSpeed NOTIFY lookSpeedChanged)
Q_PROPERTY(float zoomInLimit READ zoomInLimit WRITE setZoomInLimit NOTIFY zoomInLimitChanged)
public:
explicit QOrbitCameraController(Qt3DCore::QNode *parent = nullptr);
~QOrbitCameraController();
- Qt3DRender::QCamera *camera() const;
- float linearSpeed() const;
- float lookSpeed() const;
float zoomInLimit() const;
- void setCamera(Qt3DRender::QCamera *camera);
- void setLinearSpeed(float linearSpeed);
- void setLookSpeed(float lookSpeed);
void setZoomInLimit(float zoomInLimit);
Q_SIGNALS:
- void cameraChanged();
- void linearSpeedChanged();
- void lookSpeedChanged();
void zoomInLimitChanged();
+protected:
+ QOrbitCameraController(QOrbitCameraControllerPrivate &dd, Qt3DCore::QNode *parent = nullptr);
+
+private:
+ void moveCamera(const QAbstractCameraController::InputState &state, float dt) override;
+
private:
Q_DECLARE_PRIVATE(QOrbitCameraController)
- Q_PRIVATE_SLOT(d_func(), void _q_onTriggered(float))
};
} // Qt3DExtras
diff --git a/src/extras/defaults/qorbitcameracontroller_p.h b/src/extras/defaults/qorbitcameracontroller_p.h
index 8105d4375..1e4e3d4d2 100644
--- a/src/extras/defaults/qorbitcameracontroller_p.h
+++ b/src/extras/defaults/qorbitcameracontroller_p.h
@@ -48,88 +48,25 @@
// We mean it.
//
-#include <Qt3DExtras/qorbitcameracontroller.h>
-#include <QtGui/QVector3D>
-
-#include <Qt3DCore/private/qentity_p.h>
+#include <Qt3DExtras/private/qabstractcameracontroller_p.h>
QT_BEGIN_NAMESPACE
-namespace Qt3DRender {
-class QCamera;
-}
-
-namespace Qt3DLogic {
-class QFrameAction;
-}
-
-namespace Qt3DInput {
-
-class QKeyboardDevice;
-class QMouseDevice;
-class QLogicalDevice;
-class QAction;
-class QActionInput;
-class QAxis;
-class QAnalogAxisInput;
-class QButtonAxisInput;
-class QAxisActionHandler;
-
-}
-
namespace Qt3DExtras {
-class QOrbitCameraControllerPrivate : public Qt3DCore::QEntityPrivate
+class QOrbitCameraControllerPrivate : public QAbstractCameraControllerPrivate
{
+ Q_DECLARE_PUBLIC(QOrbitCameraController)
+
public:
QOrbitCameraControllerPrivate();
void init();
- Qt3DRender::QCamera *m_camera;
-
- Qt3DInput::QAction *m_leftMouseButtonAction;
- Qt3DInput::QAction *m_rightMouseButtonAction;
- Qt3DInput::QAction *m_altButtonAction;
- Qt3DInput::QAction *m_shiftButtonAction;
-
- Qt3DInput::QAxis *m_rxAxis;
- Qt3DInput::QAxis *m_ryAxis;
- Qt3DInput::QAxis *m_txAxis;
- Qt3DInput::QAxis *m_tyAxis;
- Qt3DInput::QAxis *m_tzAxis;
-
- Qt3DInput::QActionInput *m_leftMouseButtonInput;
- Qt3DInput::QActionInput *m_rightMouseButtonInput;
- Qt3DInput::QActionInput *m_altButtonInput;
- Qt3DInput::QActionInput *m_shiftButtonInput;
-
- Qt3DInput::QAnalogAxisInput *m_mouseRxInput;
- Qt3DInput::QAnalogAxisInput *m_mouseRyInput;
- Qt3DInput::QAnalogAxisInput *m_mouseTzXInput;
- Qt3DInput::QAnalogAxisInput *m_mouseTzYInput;
- Qt3DInput::QButtonAxisInput *m_keyboardTxPosInput;
- Qt3DInput::QButtonAxisInput *m_keyboardTyPosInput;
- Qt3DInput::QButtonAxisInput *m_keyboardTzPosInput;
- Qt3DInput::QButtonAxisInput *m_keyboardTxNegInput;
- Qt3DInput::QButtonAxisInput *m_keyboardTyNegInput;
- Qt3DInput::QButtonAxisInput *m_keyboardTzNegInput;
-
- Qt3DInput::QKeyboardDevice *m_keyboardDevice;
- Qt3DInput::QMouseDevice *m_mouseDevice;
-
- Qt3DInput::QLogicalDevice *m_logicalDevice;
-
- Qt3DLogic::QFrameAction *m_frameAction;
-
- float m_linearSpeed;
- float m_lookSpeed;
float m_zoomInLimit;
- QVector3D m_cameraUp;
- void _q_onTriggered(float);
-
- Q_DECLARE_PUBLIC(QOrbitCameraController)
+private:
+ QOrbitCameraController *q_ptr;
};
} // namespace Qt3DExtras
diff --git a/src/extras/defaults/qphongalphamaterial.cpp b/src/extras/defaults/qphongalphamaterial.cpp
index d7f054d71..fd8c52525 100644
--- a/src/extras/defaults/qphongalphamaterial.cpp
+++ b/src/extras/defaults/qphongalphamaterial.cpp
@@ -65,10 +65,9 @@ QPhongAlphaMaterialPrivate::QPhongAlphaMaterialPrivate()
: QMaterialPrivate()
, m_phongEffect(new QEffect())
, m_ambientParameter(new QParameter(QStringLiteral("ka"), QColor::fromRgbF(0.05f, 0.05f, 0.05f, 1.0f)))
- , m_diffuseParameter(new QParameter(QStringLiteral("kd"), QColor::fromRgbF(0.7f, 0.7f, 0.7f, 1.0f)))
+ , m_diffuseParameter(new QParameter(QStringLiteral("kd"), QColor::fromRgbF(0.7f, 0.7f, 0.7f, 0.5f)))
, m_specularParameter(new QParameter(QStringLiteral("ks"), QColor::fromRgbF(0.01f, 0.01f, 0.01f, 1.0f)))
, m_shininessParameter(new QParameter(QStringLiteral("shininess"), 150.0f))
- , m_alphaParameter(new QParameter(QStringLiteral("alpha"), 0.5f))
, m_phongAlphaGL3Technique(new QTechnique())
, m_phongAlphaGL2Technique(new QTechnique())
, m_phongAlphaES2Technique(new QTechnique())
@@ -95,13 +94,11 @@ void QPhongAlphaMaterialPrivate::init()
this, &QPhongAlphaMaterialPrivate::handleSpecularChanged);
connect(m_shininessParameter, &Qt3DRender::QParameter::valueChanged,
this, &QPhongAlphaMaterialPrivate::handleShininessChanged);
- connect(m_alphaParameter, &Qt3DRender::QParameter::valueChanged,
- this, &QPhongAlphaMaterialPrivate::handleAlphaChanged);
- m_phongAlphaGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/phong.vert"))));
- m_phongAlphaGL3Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/phongalpha.frag"))));
- m_phongAlphaGL2ES2Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/phong.vert"))));
- m_phongAlphaGL2ES2Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/phongalpha.frag"))));
+ m_phongAlphaGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/default.vert"))));
+ m_phongAlphaGL3Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/phong.frag"))));
+ m_phongAlphaGL2ES2Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/default.vert"))));
+ m_phongAlphaGL2ES2Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/phong.frag"))));
m_phongAlphaGL3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
m_phongAlphaGL3Technique->graphicsApiFilter()->setMajorVersion(3);
@@ -159,7 +156,6 @@ void QPhongAlphaMaterialPrivate::init()
m_phongEffect->addParameter(m_diffuseParameter);
m_phongEffect->addParameter(m_specularParameter);
m_phongEffect->addParameter(m_shininessParameter);
- m_phongEffect->addParameter(m_alphaParameter);
q->setEffect(m_phongEffect);
}
@@ -174,6 +170,7 @@ void QPhongAlphaMaterialPrivate::handleDiffuseChanged(const QVariant &var)
{
Q_Q(QPhongAlphaMaterial);
emit q->diffuseChanged(var.value<QColor>());
+ emit q->alphaChanged(var.value<QColor>().alphaF());
}
void QPhongAlphaMaterialPrivate::handleSpecularChanged(const QVariant &var)
@@ -188,12 +185,6 @@ void QPhongAlphaMaterialPrivate::handleShininessChanged(const QVariant &var)
emit q->shininessChanged(var.toFloat());
}
-void QPhongAlphaMaterialPrivate::handleAlphaChanged(const QVariant &var)
-{
- Q_Q(QPhongAlphaMaterial);
- emit q->alphaChanged(var.toFloat());
-}
-
/*!
\class Qt3DExtras::QPhongAlphaMaterial
@@ -301,7 +292,7 @@ float QPhongAlphaMaterial::shininess() const
float QPhongAlphaMaterial::alpha() const
{
Q_D(const QPhongAlphaMaterial);
- return d->m_alphaParameter->value().toFloat();
+ return d->m_diffuseParameter->value().value<QColor>().alphaF();
}
/*!
@@ -378,7 +369,10 @@ void QPhongAlphaMaterial::setAmbient(const QColor &ambient)
void QPhongAlphaMaterial::setDiffuse(const QColor &diffuse)
{
Q_D(QPhongAlphaMaterial);
- d->m_diffuseParameter->setValue(diffuse);
+ QColor currentDiffuse = d->m_diffuseParameter->value().value<QColor>();
+ QColor newDiffuse = diffuse;
+ newDiffuse.setAlphaF(currentDiffuse.alphaF());
+ d->m_diffuseParameter->setValue(newDiffuse);
}
void QPhongAlphaMaterial::setSpecular(const QColor &specular)
@@ -396,7 +390,9 @@ void QPhongAlphaMaterial::setShininess(float shininess)
void QPhongAlphaMaterial::setAlpha(float alpha)
{
Q_D(QPhongAlphaMaterial);
- d->m_alphaParameter->setValue(alpha);
+ QColor diffuse = d->m_diffuseParameter->value().value<QColor>();
+ diffuse.setAlphaF(alpha);
+ d->m_diffuseParameter->setValue(diffuse);
}
void QPhongAlphaMaterial::setSourceRgbArg(QBlendEquationArguments::Blending sourceRgbArg)
diff --git a/src/extras/defaults/qphongalphamaterial_p.h b/src/extras/defaults/qphongalphamaterial_p.h
index 623eca0ea..84e2eead3 100644
--- a/src/extras/defaults/qphongalphamaterial_p.h
+++ b/src/extras/defaults/qphongalphamaterial_p.h
@@ -84,14 +84,12 @@ public:
void handleDiffuseChanged(const QVariant &var);
void handleSpecularChanged(const QVariant &var);
void handleShininessChanged(const QVariant &var);
- void handleAlphaChanged(const QVariant &var);
Qt3DRender::QEffect *m_phongEffect;
Qt3DRender::QParameter *m_ambientParameter;
Qt3DRender::QParameter *m_diffuseParameter;
Qt3DRender::QParameter *m_specularParameter;
Qt3DRender::QParameter *m_shininessParameter;
- Qt3DRender::QParameter *m_alphaParameter;
Qt3DRender::QTechnique *m_phongAlphaGL3Technique;
Qt3DRender::QTechnique *m_phongAlphaGL2Technique;
Qt3DRender::QTechnique *m_phongAlphaES2Technique;
diff --git a/src/extras/defaults/qphongmaterial.cpp b/src/extras/defaults/qphongmaterial.cpp
index 449eb7351..25dbf3c85 100644
--- a/src/extras/defaults/qphongmaterial.cpp
+++ b/src/extras/defaults/qphongmaterial.cpp
@@ -89,10 +89,9 @@ void QPhongMaterialPrivate::init()
connect(m_shininessParameter, &Qt3DRender::QParameter::valueChanged,
this, &QPhongMaterialPrivate::handleShininessChanged);
-
- m_phongGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/phong.vert"))));
+ m_phongGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/default.vert"))));
m_phongGL3Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/phong.frag"))));
- m_phongGL2ES2Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/phong.vert"))));
+ m_phongGL2ES2Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/default.vert"))));
m_phongGL2ES2Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/phong.frag"))));
m_phongGL3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
diff --git a/src/extras/extras.qrc b/src/extras/extras.qrc
index ce959af93..f3619fdb7 100644
--- a/src/extras/extras.qrc
+++ b/src/extras/extras.qrc
@@ -4,26 +4,24 @@
<file>shaders/gl3/light.inc.frag</file>
<file>shaders/es2/light.inc.frag</file>
<file>shaders/es2/light.inc.frag100</file>
+ <file>shaders/gl3/phong.inc.frag</file>
+ <file>shaders/es2/phong.inc.frag</file>
+ <file>shaders/es2/phong.inc.frag100</file>
<file>shaders/gl3/metalrough.inc.frag</file>
<file>shaders/gl3/coordinatesystems.inc</file>
- <file>shaders/gl3/phong.vert</file>
+ <file>shaders/es2/coordinatesystems.inc</file>
<file>shaders/gl3/phong.frag</file>
- <file>shaders/es2/phong.vert</file>
<file>shaders/es2/phong.frag</file>
<file>shaders/gl3/normaldiffusespecularmap.frag</file>
- <file>shaders/gl3/diffusemap.vert</file>
<file>shaders/gl3/diffusemap.frag</file>
<file>shaders/es2/normaldiffusespecularmap.frag</file>
- <file>shaders/es2/diffusemap.vert</file>
<file>shaders/es2/diffusemap.frag</file>
- <file>shaders/es2/normaldiffusemap.vert</file>
<file>shaders/es2/normaldiffusemap.frag</file>
- <file>shaders/es2/normaldiffusemapalpha.frag</file>
<file>shaders/gl3/normaldiffusemap.frag</file>
- <file>shaders/gl3/normaldiffusemap.vert</file>
- <file>shaders/gl3/normaldiffusemapalpha.frag</file>
<file>shaders/es2/diffusespecularmap.frag</file>
<file>shaders/gl3/diffusespecularmap.frag</file>
+ <file>shaders/gl3/default.vert</file>
+ <file>shaders/es2/default.vert</file>
<file>shaders/gl3/pervertexcolor.frag</file>
<file>shaders/gl3/pervertexcolor.vert</file>
<file>shaders/es2/pervertexcolor.frag</file>
@@ -36,13 +34,10 @@
<file>shaders/gl3/gooch.frag</file>
<file>shaders/es2/gooch.frag</file>
<file>shaders/es2/gooch.vert</file>
- <file>shaders/gl3/phongalpha.frag</file>
- <file>shaders/es2/phongalpha.frag</file>
<file>shaders/gl3/unlittexture.vert</file>
<file>shaders/gl3/unlittexture.frag</file>
<file>shaders/es2/unlittexture.frag</file>
<file>shaders/es2/unlittexture.vert</file>
- <file>shaders/gl3/metalrough.vert</file>
<file>shaders/gl3/distancefieldtext.vert</file>
<file>shaders/gl3/distancefieldtext.frag</file>
<file>shaders/es2/distancefieldtext.frag</file>
diff --git a/src/extras/geometries/qconegeometry.cpp b/src/extras/geometries/qconegeometry.cpp
index d1a6917f5..a80e2a78a 100644
--- a/src/extras/geometries/qconegeometry.cpp
+++ b/src/extras/geometries/qconegeometry.cpp
@@ -368,8 +368,8 @@ void QConeGeometryPrivate::init()
m_normalAttribute = new QAttribute(q);
m_texCoordAttribute = new QAttribute(q);
m_indexAttribute = new QAttribute(q);
- m_vertexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, q);
- m_indexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::IndexBuffer, q);
+ m_vertexBuffer = new Qt3DRender::QBuffer(q);
+ m_indexBuffer = new Qt3DRender::QBuffer(q);
// vec3 pos, vec2 tex, vec3 normal
const quint32 elementSize = 3 + 2 + 3;
diff --git a/src/extras/geometries/qcuboidgeometry.cpp b/src/extras/geometries/qcuboidgeometry.cpp
index a8899989c..9e6747c1e 100644
--- a/src/extras/geometries/qcuboidgeometry.cpp
+++ b/src/extras/geometries/qcuboidgeometry.cpp
@@ -497,8 +497,8 @@ void QCuboidGeometryPrivate::init()
m_texCoordAttribute = new Qt3DRender::QAttribute(q);
m_tangentAttribute = new Qt3DRender::QAttribute(q);
m_indexAttribute = new Qt3DRender::QAttribute(q);
- m_vertexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, q);
- m_indexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::IndexBuffer, q);
+ m_vertexBuffer = new Qt3DRender::QBuffer(q);
+ m_indexBuffer = new Qt3DRender::QBuffer(q);
// vec3 pos vec2 tex vec3 normal vec4 tangent
const quint32 stride = (3 + 2 + 3 + 4) * sizeof(float);
diff --git a/src/extras/geometries/qcylindergeometry.cpp b/src/extras/geometries/qcylindergeometry.cpp
index a6eb01d41..c86b76d24 100644
--- a/src/extras/geometries/qcylindergeometry.cpp
+++ b/src/extras/geometries/qcylindergeometry.cpp
@@ -299,8 +299,8 @@ void QCylinderGeometryPrivate::init()
m_normalAttribute = new QAttribute(q);
m_texCoordAttribute = new QAttribute(q);
m_indexAttribute = new QAttribute(q);
- m_vertexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, q);
- m_indexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::IndexBuffer, q);
+ m_vertexBuffer = new Qt3DRender::QBuffer(q);
+ m_indexBuffer = new Qt3DRender::QBuffer(q);
// vec3 pos, vec2 tex, vec3 normal
const quint32 elementSize = 3 + 2 + 3;
diff --git a/src/extras/geometries/qplanegeometry.cpp b/src/extras/geometries/qplanegeometry.cpp
index c6318e199..225726342 100644
--- a/src/extras/geometries/qplanegeometry.cpp
+++ b/src/extras/geometries/qplanegeometry.cpp
@@ -509,8 +509,8 @@ void QPlaneGeometryPrivate::init()
m_texCoordAttribute = new QAttribute(q);
m_tangentAttribute = new QAttribute(q);
m_indexAttribute = new QAttribute(q);
- m_vertexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, q);
- m_indexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::IndexBuffer, q);
+ m_vertexBuffer = new Qt3DRender::QBuffer(q);
+ m_indexBuffer = new Qt3DRender::QBuffer(q);
const int nVerts = m_meshResolution.width() * m_meshResolution.height();
const int stride = (3 + 2 + 3 + 4) * sizeof(float);
diff --git a/src/extras/geometries/qspheregeometry.cpp b/src/extras/geometries/qspheregeometry.cpp
index 92844335c..1a3b50553 100644
--- a/src/extras/geometries/qspheregeometry.cpp
+++ b/src/extras/geometries/qspheregeometry.cpp
@@ -254,8 +254,8 @@ void QSphereGeometryPrivate::init()
m_texCoordAttribute = new QAttribute(q);
m_tangentAttribute = new QAttribute(q);
m_indexAttribute = new QAttribute(q);
- m_vertexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, q);
- m_indexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::IndexBuffer, q);
+ m_vertexBuffer = new Qt3DRender::QBuffer(q);
+ m_indexBuffer = new Qt3DRender::QBuffer(q);
// vec3 pos, vec2 tex, vec3 normal, vec4 tangent
const quint32 elementSize = 3 + 2 + 3 + 4;
diff --git a/src/extras/geometries/qtorusgeometry.cpp b/src/extras/geometries/qtorusgeometry.cpp
index ef14ee50d..726b81c62 100644
--- a/src/extras/geometries/qtorusgeometry.cpp
+++ b/src/extras/geometries/qtorusgeometry.cpp
@@ -243,8 +243,8 @@ void QTorusGeometryPrivate::init()
m_texCoordAttribute = new QAttribute(q);
m_tangentAttribute = new QAttribute(q);
m_indexAttribute = new QAttribute(q);
- m_vertexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, q);
- m_indexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::IndexBuffer, q);
+ m_vertexBuffer = new Qt3DRender::QBuffer(q);
+ m_indexBuffer = new Qt3DRender::QBuffer(q);
// vec3 pos, vec2 tex, vec3 normal, vec4 tangent
const quint32 elementSize = 3 + 2 + 3 + 4;
const quint32 stride = elementSize * sizeof(float);
diff --git a/src/extras/shaders/es2/coordinatesystems.inc b/src/extras/shaders/es2/coordinatesystems.inc
new file mode 100644
index 000000000..5f6ee40f5
--- /dev/null
+++ b/src/extras/shaders/es2/coordinatesystems.inc
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D 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$
+**
+****************************************************************************/
+
+#define FP highp
+
+FP mat3 transpose(const in FP mat3 inputMatrix)
+{
+ FP vec3 i0 = inputMatrix[0];
+ FP vec3 i1 = inputMatrix[1];
+ FP vec3 i2 = inputMatrix[2];
+
+ FP mat3 outputMatrix = mat3(
+ vec3(i0.x, i1.x, i2.x),
+ vec3(i0.y, i1.y, i2.y),
+ vec3(i0.z, i1.z, i2.z)
+ );
+
+ return outputMatrix;
+}
+
+FP mat3 calcWorldSpaceToTangentSpaceMatrix(const in FP vec3 wNormal, const in FP vec4 wTangent)
+{
+ // Make the tangent truly orthogonal to the normal by using Gram-Schmidt.
+ // This allows to build the tangentMatrix below by simply transposing the
+ // tangent -> eyespace matrix (which would now be orthogonal)
+ FP vec3 wFixedTangent = normalize(wTangent.xyz - dot(wTangent.xyz, wNormal) * wNormal);
+
+ // Calculate binormal vector. No "real" need to renormalize it,
+ // as built by crossing two normal vectors.
+ // To orient the binormal correctly, use the fourth coordinate of the tangent,
+ // which is +1 for a right hand system, and -1 for a left hand system.
+ FP vec3 wBinormal = cross(wNormal, wFixedTangent.xyz) * wTangent.w;
+
+ // Construct matrix to transform from world space to tangent space
+ // This is the transpose of the tangentToWorld transformation matrix
+ FP mat3 tangentToWorldMatrix = mat3(wFixedTangent, wBinormal, wNormal);
+ FP mat3 worldToTangentMatrix = transpose(tangentToWorldMatrix);
+ return worldToTangentMatrix;
+}
+
diff --git a/src/extras/shaders/es2/default.vert b/src/extras/shaders/es2/default.vert
new file mode 100644
index 000000000..810f658bc
--- /dev/null
+++ b/src/extras/shaders/es2/default.vert
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D 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$
+**
+****************************************************************************/
+
+attribute vec3 vertexPosition;
+attribute vec3 vertexNormal;
+attribute vec4 vertexTangent;
+attribute vec2 vertexTexCoord;
+
+varying vec3 worldPosition;
+varying vec3 worldNormal;
+varying vec4 worldTangent;
+varying vec2 texCoord;
+
+uniform mat4 modelMatrix;
+uniform mat3 modelNormalMatrix;
+uniform mat4 modelViewProjection;
+
+uniform float texCoordScale;
+
+void main()
+{
+ // Pass through texture coordinates
+ texCoord = vertexTexCoord * texCoordScale;
+
+ // Transform position, normal, and tangent to world coords
+ worldPosition = vec3(modelMatrix * vec4(vertexPosition, 1.0));
+ worldNormal = normalize(modelNormalMatrix * vertexNormal);
+ worldTangent.xyz = normalize(vec3(modelMatrix * vec4(vertexTangent.xyz, 0.0)));
+ worldTangent.w = vertexTangent.w;
+
+ // Calculate vertex position in clip coordinates
+ gl_Position = modelViewProjection * vec4(vertexPosition, 1.0);
+}
diff --git a/src/extras/shaders/es2/diffusemap.frag b/src/extras/shaders/es2/diffusemap.frag
index 7d06d8e2c..6ac9bd5a3 100644
--- a/src/extras/shaders/es2/diffusemap.frag
+++ b/src/extras/shaders/es2/diffusemap.frag
@@ -1,7 +1,7 @@
#define FP highp
-uniform FP vec3 ka; // Ambient reflectivity
-uniform FP vec3 ks; // Specular reflectivity
+uniform FP vec4 ka; // Ambient reflectivity
+uniform FP vec4 ks; // Specular reflectivity
uniform FP float shininess; // Specular shininess factor
uniform FP vec3 eyePosition;
@@ -12,14 +12,11 @@ varying FP vec3 worldPosition;
varying FP vec3 worldNormal;
varying FP vec2 texCoord;
-#pragma include light.inc.frag
+#pragma include phong.inc.frag
void main()
{
- FP vec3 diffuseTextureColor = texture2D( diffuseTexture, texCoord ).rgb;
-
- FP vec3 diffuseColor, specularColor;
- adsModel(worldPosition, worldNormal, eyePosition, shininess, diffuseColor, specularColor);
-
- gl_FragColor = vec4( diffuseTextureColor * ( ka + diffuseColor ) + ks * specularColor, 1.0 );
+ FP vec4 diffuseTextureColor = texture2D( diffuseTexture, texCoord );
+ FP vec3 worldView = normalize(eyePosition - worldPosition);
+ gl_FragColor = phongFunction(ka, diffuseTextureColor, ks, shininess, worldPosition, worldView, worldNormal);
}
diff --git a/src/extras/shaders/es2/diffusemap.vert b/src/extras/shaders/es2/diffusemap.vert
deleted file mode 100644
index 13798279e..000000000
--- a/src/extras/shaders/es2/diffusemap.vert
+++ /dev/null
@@ -1,22 +0,0 @@
-attribute vec3 vertexPosition;
-attribute vec3 vertexNormal;
-attribute vec2 vertexTexCoord;
-
-varying vec3 worldPosition;
-varying vec3 worldNormal;
-varying vec2 texCoord;
-
-uniform mat4 modelMatrix;
-uniform mat3 modelNormalMatrix;
-uniform mat4 mvp;
-
-uniform float texCoordScale;
-
-void main()
-{
- texCoord = vertexTexCoord * texCoordScale;
- worldNormal = normalize( modelNormalMatrix * vertexNormal );
- worldPosition = vec3( modelMatrix * vec4( vertexPosition, 1.0 ) );
-
- gl_Position = mvp * vec4( vertexPosition, 1.0 );
-}
diff --git a/src/extras/shaders/es2/diffusespecularmap.frag b/src/extras/shaders/es2/diffusespecularmap.frag
index 4d776772c..99183aaf4 100644
--- a/src/extras/shaders/es2/diffusespecularmap.frag
+++ b/src/extras/shaders/es2/diffusespecularmap.frag
@@ -1,7 +1,7 @@
#define FP highp
// TODO: Replace with a struct
-uniform FP vec3 ka; // Ambient reflectivity
+uniform FP vec4 ka; // Ambient reflectivity
uniform FP float shininess; // Specular shininess factor
uniform FP vec3 eyePosition;
@@ -13,15 +13,12 @@ varying FP vec3 worldPosition;
varying FP vec3 worldNormal;
varying FP vec2 texCoord;
-#pragma include light.inc.frag
+#pragma include phong.inc.frag
void main()
{
- FP vec3 diffuseTextureColor = texture2D( diffuseTexture, texCoord ).rgb;
- FP vec3 specularTextureColor = texture2D( specularTexture, texCoord ).rgb;
-
- FP vec3 diffuseColor, specularColor;
- adsModel(worldPosition, worldNormal, eyePosition, shininess, diffuseColor, specularColor);
-
- gl_FragColor = vec4( diffuseTextureColor * ( ka + diffuseColor ) + specularTextureColor * specularColor, 1.0 );
+ FP vec4 diffuseTextureColor = texture2D( diffuseTexture, texCoord );
+ FP vec4 specularTextureColor = texture2D( specularTexture, texCoord );
+ FP vec3 worldView = normalize(eyePosition - worldPosition);
+ gl_FragColor = phongFunction(ka, diffuseTextureColor, specularTextureColor, shininess, worldPosition, worldView, worldNormal);
}
diff --git a/src/extras/shaders/es2/light.inc.frag b/src/extras/shaders/es2/light.inc.frag
index 57a30036f..167ff306e 100644
--- a/src/extras/shaders/es2/light.inc.frag
+++ b/src/extras/shaders/es2/light.inc.frag
@@ -1,3 +1,5 @@
+#define FP highp
+
const int MAX_LIGHTS = 8;
const int TYPE_POINT = 0;
const int TYPE_DIRECTIONAL = 1;
@@ -13,186 +15,3 @@ struct Light {
};
uniform Light lights[MAX_LIGHTS];
uniform int lightCount;
-
-void adsModelNormalMapped(const in FP vec3 vpos, const in FP vec3 vnormal, const in FP vec3 eye, const in FP float shininess,
- const in FP mat3 tangentMatrix,
- out FP vec3 diffuseColor, out FP vec3 specularColor)
-{
- diffuseColor = vec3(0.0);
- specularColor = vec3(0.0);
-
- FP vec3 snormal = normalize( vec3( tangentMatrix[0][2], tangentMatrix[1][2], tangentMatrix[2][2] ) );
-
- FP vec3 n = normalize( vnormal );
-
- FP vec3 s, ts;
- Light light;
- for (int i = 0; i < MAX_LIGHTS; ++i) {
- if (i >= lightCount) // Make brcm happy with the for loop
- break;
- if (i == 0)
- light = lights[0];
- else if (i == 1)
- light = lights[1];
- else if (i == 2)
- light = lights[2];
- else if (i == 3)
- light = lights[3];
- else if (i == 4)
- light = lights[4];
- else if (i == 5)
- light = lights[5];
- else if (i == 6)
- light = lights[6];
- else if (i == 7)
- light = lights[7];
-
- FP float att = 1.0;
- if ( light.type != TYPE_DIRECTIONAL ) {
- s = light.position - vpos;
- if ( dot(snormal, s) < 0.0 )
- att = 0.0;
- else {
- ts = normalize( tangentMatrix * s );
- if (length( light.attenuation ) != 0.0) {
- FP float dist = length(s);
- att = 1.0 / (light.attenuation.x + light.attenuation.y * dist + light.attenuation.z * dist * dist);
- }
- s = normalize( s );
- if ( light.type == TYPE_SPOT ) {
- if ( degrees(acos(dot(-s, normalize(light.direction))) ) > light.cutOffAngle)
- att = 0.0;
- }
- }
- } else {
- if ( dot(snormal, -light.direction) > 0.0 )
- s = normalize( tangentMatrix * -light.direction );
- else
- att = 0.0;
- }
-
- FP float diffuse = max( dot( ts, n ), 0.0 );
-
- FP float specular = 0.0;
- if (diffuse > 0.0 && shininess > 0.0 && att > 0.0) {
- FP vec3 r = reflect( -ts, n );
- FP vec3 v = normalize( tangentMatrix * ( eye - vpos ) );
- FP float normFactor = ( shininess + 2.0 ) / 2.0;
- specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess );
- }
-
- diffuseColor += att * light.intensity * diffuse * light.color;
- specularColor += att * light.intensity * specular * light.color;
- }
-}
-
-void adsModel(const in FP vec3 vpos, const in FP vec3 vnormal, const in FP vec3 eye, const in FP float shininess,
- out FP vec3 diffuseColor, out FP vec3 specularColor)
-{
- diffuseColor = vec3(0.0);
- specularColor = vec3(0.0);
-
- FP vec3 n = normalize( vnormal );
-
- FP vec3 s;
- Light light;
- for (int i = 0; i < MAX_LIGHTS; ++i) {
- if (i >= lightCount) // Make brcm happy with the for loop
- break;
- if (i == 0)
- light = lights[0];
- else if (i == 1)
- light = lights[1];
- else if (i == 2)
- light = lights[2];
- else if (i == 3)
- light = lights[3];
- else if (i == 4)
- light = lights[4];
- else if (i == 5)
- light = lights[5];
- else if (i == 6)
- light = lights[6];
- else if (i == 7)
- light = lights[7];
-
- FP float att = 1.0;
- if ( light.type != TYPE_DIRECTIONAL ) {
- s = light.position - vpos;
- if (length( light.attenuation ) != 0.0) {
- FP float dist = length(s);
- att = 1.0 / (light.attenuation.x + light.attenuation.y * dist + light.attenuation.z * dist * dist);
- }
- s = normalize( s );
- if ( light.type == TYPE_SPOT ) {
- if ( degrees(acos(dot(-s, normalize(light.direction))) ) > light.cutOffAngle)
- att = 0.0;
- }
- } else {
- s = normalize( -light.direction );
- }
-
- FP float diffuse = max( dot( s, n ), 0.0 );
-
- FP float specular = 0.0;
- if (diffuse > 0.0 && shininess > 0.0 && att > 0.0) {
- FP vec3 r = reflect( -s, n );
- FP vec3 v = normalize( eye - vpos );
- FP float normFactor = ( shininess + 2.0 ) / 2.0;
- specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess );
- }
-
- diffuseColor += att * light.intensity * diffuse * light.color;
- specularColor += att * light.intensity * specular * light.color;
- }
-}
-
-void adModel(const in FP vec3 vpos, const in FP vec3 vnormal, out FP vec3 diffuseColor)
-{
- diffuseColor = vec3(0.0);
-
- FP vec3 n = normalize( vnormal );
-
- FP vec3 s;
- Light light;
- for (int i = 0; i < MAX_LIGHTS; ++i) {
- if (i >= lightCount) // Make brcm happy with the for loop
- break;
- if (i == 0)
- light = lights[0];
- else if (i == 1)
- light = lights[1];
- else if (i == 2)
- light = lights[2];
- else if (i == 3)
- light = lights[3];
- else if (i == 4)
- light = lights[4];
- else if (i == 5)
- light = lights[5];
- else if (i == 6)
- light = lights[6];
- else if (i == 7)
- light = lights[7];
-
- FP float att = 1.0;
- if ( light.type != TYPE_DIRECTIONAL ) {
- s = light.position - vpos;
- if (length( light.attenuation ) != 0.0) {
- FP float dist = length(s);
- att = 1.0 / (light.attenuation.x + light.attenuation.y * dist + light.attenuation.z * dist * dist);
- }
- s = normalize( s );
- if ( light.type == TYPE_SPOT ) {
- if ( degrees(acos(dot(-s, normalize(light.direction))) ) > light.cutOffAngle)
- att = 0.0;
- }
- } else {
- s = normalize( -light.direction );
- }
-
- FP float diffuse = max( dot( s, n ), 0.0 );
-
- diffuseColor += att * light.intensity * diffuse * light.color;
- }
-}
diff --git a/src/extras/shaders/es2/light.inc.frag100 b/src/extras/shaders/es2/light.inc.frag100
index b4988ad82..8680ee423 100644
--- a/src/extras/shaders/es2/light.inc.frag100
+++ b/src/extras/shaders/es2/light.inc.frag100
@@ -1,3 +1,5 @@
+#define FP highp
+
const int MAX_LIGHTS = 2; // RPi: cannot use more than two as we run out of uniforms
const int TYPE_POINT = 0;
const int TYPE_DIRECTIONAL = 1;
@@ -13,206 +15,3 @@ struct Light {
};
uniform Light lights[MAX_LIGHTS];
uniform int lightCount;
-
-void adsModelNormalMapped(const in FP vec3 vpos, const in FP vec3 vnormal, const in FP vec3 eye, const in FP float shininess,
- const in FP mat3 tangentMatrix,
- out FP vec3 diffuseColor, out FP vec3 specularColor)
-{
- diffuseColor = vec3(0.0);
- specularColor = vec3(0.0);
-
- FP vec3 n = normalize( vnormal );
-
- // 0
- if (lightCount < 1)
- return;
- FP vec3 s;
- FP float att = 1.0;
- if ( lights[0].type != TYPE_DIRECTIONAL ) {
- s = tangentMatrix * ( lights[0].position - vpos );
- if (length( lights[0].attenuation ) != 0.0) {
- FP float dist = length(s);
- att = 1.0 / (lights[0].attenuation.x + lights[0].attenuation.y * dist + lights[0].attenuation.z * dist * dist);
- }
- s = normalize( s );
- if ( lights[0].type == TYPE_SPOT ) {
- if ( degrees(acos(dot(-s, normalize(lights[0].direction))) ) > lights[0].cutOffAngle)
- att = 0.0;
- }
- } else {
- s = normalize( tangentMatrix * -lights[0].direction );
- }
-
- FP float diffuse = max( dot( s, n ), 0.0 );
-
- FP float specular = 0.0;
- if (diffuse > 0.0 && shininess > 0.0 && att > 0.0) {
- FP vec3 r = reflect( -s, n );
- FP vec3 v = normalize( tangentMatrix * ( eye - vpos ) );
- FP float normFactor = ( shininess + 2.0 ) / 2.0;
- specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess );
- }
-
- diffuseColor += att * lights[0].intensity * diffuse * lights[0].color;
- specularColor += att * specular;
-
- // 1
- if (lightCount < 2)
- return;
- att = 1.0;
- if ( lights[1].type != TYPE_DIRECTIONAL ) {
- s = tangentMatrix * ( lights[1].position - vpos );
- if (length( lights[1].attenuation ) != 0.0) {
- FP float dist = length(s);
- att = 1.0 / (lights[1].attenuation.x + lights[1].attenuation.y * dist + lights[1].attenuation.z * dist * dist);
- }
- s = normalize( s );
- if ( lights[1].type == TYPE_SPOT ) {
- if ( degrees(acos(dot(-s, normalize(lights[1].direction))) ) > lights[1].cutOffAngle)
- att = 0.0;
- }
- } else {
- s = normalize( tangentMatrix * -lights[1].direction );
- }
-
- diffuse = max( dot( s, n ), 0.0 );
-
- specular = 0.0;
- if (diffuse > 0.0 && shininess > 0.0 && att > 0.0) {
- FP vec3 r = reflect( -s, n );
- FP vec3 v = normalize( tangentMatrix * ( eye - vpos ) );
- FP float normFactor = ( shininess + 2.0 ) / 2.0;
- specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess );
- }
-
- diffuseColor += att * lights[1].intensity * diffuse * lights[1].color;
- specularColor += att * specular;
-}
-
-void adsModel(const in FP vec3 vpos, const in FP vec3 vnormal, const in FP vec3 eye, const in FP float shininess,
- out FP vec3 diffuseColor, out FP vec3 specularColor)
-{
- diffuseColor = vec3(0.0);
- specularColor = vec3(0.0);
-
- FP vec3 n = normalize( vnormal );
-
- // 0
- if (lightCount < 1)
- return;
- FP vec3 s;
- FP float att = 1.0;
- if ( lights[0].type != TYPE_DIRECTIONAL ) {
- s = lights[0].position - vpos;
- if (length( lights[0].attenuation ) != 0.0) {
- FP float dist = length(s);
- att = 1.0 / (lights[0].attenuation.x + lights[0].attenuation.y * dist + lights[0].attenuation.z * dist * dist);
- }
- s = normalize( s );
- if ( lights[0].type == TYPE_SPOT ) {
- if ( degrees(acos(dot(-s, normalize(lights[0].direction))) ) > lights[0].cutOffAngle)
- att = 0.0;
- }
- } else {
- s = normalize( -lights[0].direction );
- }
-
- FP float diffuse = max( dot( s, n ), 0.0 );
-
- FP float specular = 0.0;
- if (diffuse > 0.0 && shininess > 0.0 && att > 0.0) {
- FP vec3 r = reflect( -s, n );
- FP vec3 v = normalize( eye - vpos );
- FP float normFactor = ( shininess + 2.0 ) / 2.0;
- specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess );
- }
-
- diffuseColor += att * lights[0].intensity * diffuse * lights[0].color;
- specularColor += att * specular;
-
- // 1
- if (lightCount < 2)
- return;
- att = 1.0;
- if ( lights[1].type != TYPE_DIRECTIONAL ) {
- s = lights[1].position - vpos;
- if (length( lights[1].attenuation ) != 0.0) {
- FP float dist = length(s);
- att = 1.0 / (lights[1].attenuation.x + lights[1].attenuation.y * dist + lights[1].attenuation.z * dist * dist);
- }
- s = normalize( s );
- if ( lights[1].type == TYPE_SPOT ) {
- if ( degrees(acos(dot(-s, normalize(lights[1].direction))) ) > lights[1].cutOffAngle)
- att = 0.0;
- }
- } else {
- s = normalize( -lights[1].direction );
- }
-
- diffuse = max( dot( s, n ), 0.0 );
-
- specular = 0.0;
- if (diffuse > 0.0 && shininess > 0.0 && att > 0.0) {
- FP vec3 r = reflect( -s, n );
- FP vec3 v = normalize( eye - vpos );
- FP float normFactor = ( shininess + 2.0 ) / 2.0;
- specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess );
- }
-
- diffuseColor += att * lights[1].intensity * diffuse * lights[1].color;
- specularColor += att * specular;
-}
-
-void adModel(const in FP vec3 vpos, const in FP vec3 vnormal, out FP vec3 diffuseColor)
-{
- diffuseColor = vec3(0.0);
-
- FP vec3 n = normalize( vnormal );
-
- // 0
- if (lightCount < 1)
- return;
- FP vec3 s;
- FP float att = 1.0;
- if ( lights[0].type != TYPE_DIRECTIONAL ) {
- s = lights[0].position - vpos;
- if (length( lights[0].attenuation ) != 0.0) {
- FP float dist = length(s);
- att = 1.0 / (lights[0].attenuation.x + lights[0].attenuation.y * dist + lights[0].attenuation.z * dist * dist);
- }
- s = normalize( s );
- if ( lights[0].type == TYPE_SPOT ) {
- if ( degrees(acos(dot(-s, normalize(lights[0].direction))) ) > lights[0].cutOffAngle)
- att = 0.0;
- }
- } else {
- s = normalize( -lights[0].direction );
- }
-
- FP float diffuse = max( dot( s, n ), 0.0 );
-
- diffuseColor += att * lights[0].intensity * diffuse * lights[0].color;
-
- // 1
- if (lightCount < 2)
- return;
- att = 1.0;
- if ( lights[1].type != TYPE_DIRECTIONAL ) {
- s = lights[1].position - vpos;
- if (length( lights[1].attenuation ) != 0.0) {
- FP float dist = length(s);
- att = 1.0 / (lights[1].attenuation.x + lights[1].attenuation.y * dist + lights[1].attenuation.z * dist * dist);
- }
- s = normalize( s );
- if ( lights[1].type == TYPE_SPOT ) {
- if ( degrees(acos(dot(-s, normalize(lights[1].direction))) ) > lights[1].cutOffAngle)
- att = 0.0;
- }
- } else {
- s = normalize( -lights[1].direction );
- }
-
- diffuse = max( dot( s, n ), 0.0 );
-
- diffuseColor += att * lights[1].intensity * diffuse * lights[1].color;
-}
diff --git a/src/extras/shaders/es2/normaldiffusemap.frag b/src/extras/shaders/es2/normaldiffusemap.frag
index c69aa8b81..0bf4c5630 100644
--- a/src/extras/shaders/es2/normaldiffusemap.frag
+++ b/src/extras/shaders/es2/normaldiffusemap.frag
@@ -1,31 +1,34 @@
#define FP highp
varying FP vec3 worldPosition;
+varying FP vec3 worldNormal;
+varying FP vec4 worldTangent;
varying FP vec2 texCoord;
-varying FP mat3 tangentMatrix;
uniform sampler2D diffuseTexture;
uniform sampler2D normalTexture;
// TODO: Replace with a struct
-uniform FP vec3 ka; // Ambient reflectivity
-uniform FP vec3 ks; // Specular reflectivity
+uniform FP vec4 ka; // Ambient reflectivity
+uniform FP vec4 ks; // Specular reflectivity
uniform FP float shininess; // Specular shininess factor
uniform FP vec3 eyePosition;
-#pragma include light.inc.frag
+#pragma include phong.inc.frag
+#pragma include coordinatesystems.inc
void main()
{
// Sample the textures at the interpolated texCoords
FP vec4 diffuseTextureColor = texture2D( diffuseTexture, texCoord );
- FP vec3 normal = 2.0 * texture2D( normalTexture, texCoord ).rgb - vec3( 1.0 );
+ FP vec3 tNormal = 2.0 * texture2D( normalTexture, texCoord ).rgb - vec3( 1.0 );
- // Calculate the lighting model, keeping the specular component separate
- FP vec3 diffuseColor, specularColor;
- adsModelNormalMapped(worldPosition, normal, eyePosition, shininess, tangentMatrix, diffuseColor, specularColor);
+ FP mat3 tangentMatrix = calcWorldSpaceToTangentSpaceMatrix(worldNormal, worldTangent);
+ FP mat3 invertTangentMatrix = transpose(tangentMatrix);
- // Combine spec with ambient+diffuse for final fragment color
- gl_FragColor = vec4( ka + diffuseTextureColor.rgb * diffuseColor + ks * specularColor, 1.0 );
+ FP vec3 wNormal = normalize(invertTangentMatrix * tNormal);
+ FP vec3 worldView = normalize(eyePosition - worldPosition);
+
+ gl_FragColor = phongFunction(ka, diffuseTextureColor, ks, shininess, worldPosition, worldView, wNormal);
}
diff --git a/src/extras/shaders/es2/normaldiffusemap.vert b/src/extras/shaders/es2/normaldiffusemap.vert
deleted file mode 100644
index ecc689f69..000000000
--- a/src/extras/shaders/es2/normaldiffusemap.vert
+++ /dev/null
@@ -1,38 +0,0 @@
-attribute vec3 vertexPosition;
-attribute vec3 vertexNormal;
-attribute vec2 vertexTexCoord;
-attribute vec4 vertexTangent;
-
-varying vec3 worldPosition;
-varying vec2 texCoord;
-varying mat3 tangentMatrix;
-
-uniform mat4 modelMatrix;
-uniform mat3 modelNormalMatrix;
-uniform mat4 projectionMatrix;
-uniform mat4 mvp;
-
-uniform float texCoordScale;
-
-void main()
-{
- // Pass through texture coordinates
- texCoord = vertexTexCoord * texCoordScale;
-
- // Transform position, normal, and tangent to world coords
- vec3 normal = normalize( modelNormalMatrix * vertexNormal );
- vec3 tangent = normalize( modelNormalMatrix * vertexTangent.xyz );
- worldPosition = vec3( modelMatrix * vec4( vertexPosition, 1.0 ) );
-
- // Calculate binormal vector
- vec3 binormal = normalize( cross( normal, tangent ) );
-
- // Construct matrix to transform from eye coords to tangent space
- tangentMatrix = mat3 (
- tangent.x, binormal.x, normal.x,
- tangent.y, binormal.y, normal.y,
- tangent.z, binormal.z, normal.z );
-
- // Calculate vertex position in clip coordinates
- gl_Position = mvp * vec4( vertexPosition, 1.0 );
-}
diff --git a/src/extras/shaders/es2/normaldiffusemapalpha.frag b/src/extras/shaders/es2/normaldiffusemapalpha.frag
deleted file mode 100644
index 98acbf01d..000000000
--- a/src/extras/shaders/es2/normaldiffusemapalpha.frag
+++ /dev/null
@@ -1,32 +0,0 @@
-#define FP highp
-
-varying FP vec3 worldPosition;
-varying FP vec2 texCoord;
-varying FP mat3 tangentMatrix;
-
-uniform sampler2D diffuseTexture;
-uniform sampler2D normalTexture;
-
-// TODO: Replace with a struct
-uniform FP vec3 ka; // Ambient reflectivity
-uniform FP vec3 ks; // Specular reflectivity
-uniform FP float shininess; // Specular shininess factor
-
-uniform FP vec3 eyePosition;
-
-#pragma include light.inc.frag
-
-void main()
-{
- // Sample the textures at the interpolated texCoords
- FP vec4 diffuseTextureColor = texture2D( diffuseTexture, texCoord );
- FP vec3 normal = 2.0 * texture2D( normalTexture, texCoord ).rgb - vec3( 1.0 );
-
- // Calculate the lighting model, keeping the specular component separate
- FP vec3 diffuseColor, specularColor;
- adsModelNormalMapped(worldPosition, normal, eyePosition, shininess, tangentMatrix, diffuseColor, specularColor);
-
- // Combine spec with ambient+diffuse for final fragment color
- // Use the alpha from the diffuse texture (for alpha to coverage)
- gl_FragColor = vec4( ka + diffuseTextureColor.rgb * diffuseColor + ks * specularColor, diffuseTextureColor.a );
-}
diff --git a/src/extras/shaders/es2/normaldiffusespecularmap.frag b/src/extras/shaders/es2/normaldiffusespecularmap.frag
index b30c1bd5f..0541c8902 100644
--- a/src/extras/shaders/es2/normaldiffusespecularmap.frag
+++ b/src/extras/shaders/es2/normaldiffusespecularmap.frag
@@ -1,32 +1,35 @@
#define FP highp
varying FP vec3 worldPosition;
+varying FP vec3 worldNormal;
+varying FP vec4 worldTangent;
varying FP vec2 texCoord;
-varying FP mat3 tangentMatrix;
uniform sampler2D diffuseTexture;
uniform sampler2D specularTexture;
uniform sampler2D normalTexture;
// TODO: Replace with a struct
-uniform FP vec3 ka; // Ambient reflectivity
+uniform FP vec4 ka; // Ambient reflectivity
uniform FP float shininess; // Specular shininess factor
uniform FP vec3 eyePosition;
-#pragma include light.inc.frag
+#pragma include phong.inc.frag
+#pragma include coordinatesystems.inc
void main()
{
// Sample the textures at the interpolated texCoords
FP vec4 diffuseTextureColor = texture2D( diffuseTexture, texCoord );
FP vec4 specularTextureColor = texture2D( specularTexture, texCoord );
- FP vec3 normal = 2.0 * texture2D( normalTexture, texCoord ).rgb - vec3( 1.0 );
+ FP vec3 tNormal = 2.0 * texture2D( normalTexture, texCoord ).rgb - vec3( 1.0 );
- // Calculate the lighting model, keeping the specular component separate
- FP vec3 diffuseColor, specularColor;
- adsModelNormalMapped(worldPosition, normal, eyePosition, shininess, tangentMatrix, diffuseColor, specularColor);
+ FP mat3 tangentMatrix = calcWorldSpaceToTangentSpaceMatrix(worldNormal, worldTangent);
+ FP mat3 invertTangentMatrix = transpose(tangentMatrix);
- // Combine spec with ambient+diffuse for final fragment color
- gl_FragColor = vec4( ka + diffuseTextureColor.rgb * diffuseColor + specularTextureColor.rgb * specularColor, 1.0 );
+ FP vec3 wNormal = normalize(invertTangentMatrix * tNormal);
+ FP vec3 worldView = normalize(eyePosition - worldPosition);
+
+ gl_FragColor = phongFunction(ka, diffuseTextureColor, specularTextureColor, shininess, worldPosition, worldView, wNormal);
}
diff --git a/src/extras/shaders/es2/pervertexcolor.frag b/src/extras/shaders/es2/pervertexcolor.frag
index ab429d942..a2f0e8bf2 100644
--- a/src/extras/shaders/es2/pervertexcolor.frag
+++ b/src/extras/shaders/es2/pervertexcolor.frag
@@ -2,13 +2,14 @@
varying FP vec3 worldPosition;
varying FP vec3 worldNormal;
-varying FP vec3 color;
+varying FP vec4 color;
-#pragma include light.inc.frag
+uniform FP vec3 eyePosition;
+
+#pragma include phong.inc.frag
void main()
{
- FP vec3 diffuseColor;
- adModel(worldPosition, worldNormal, diffuseColor);
- gl_FragColor = vec4( color + color * diffuseColor, 1.0 );
+ FP vec3 worldView = normalize(eyePosition - worldPosition);
+ gl_FragColor = phongFunction(color, color, vec4(0.0), 0.0, worldPosition, worldView, worldNormal);
}
diff --git a/src/extras/shaders/es2/pervertexcolor.vert b/src/extras/shaders/es2/pervertexcolor.vert
index 7fc3e649f..bfa2e615a 100644
--- a/src/extras/shaders/es2/pervertexcolor.vert
+++ b/src/extras/shaders/es2/pervertexcolor.vert
@@ -1,10 +1,10 @@
attribute vec3 vertexPosition;
attribute vec3 vertexNormal;
-attribute vec3 vertexColor;
+attribute vec4 vertexColor;
varying vec3 worldPosition;
varying vec3 worldNormal;
-varying vec3 color;
+varying vec4 color;
uniform mat4 modelMatrix;
uniform mat3 modelNormalMatrix;
diff --git a/src/extras/shaders/es2/phong.frag b/src/extras/shaders/es2/phong.frag
index c00f89db0..6b8ab7111 100644
--- a/src/extras/shaders/es2/phong.frag
+++ b/src/extras/shaders/es2/phong.frag
@@ -1,8 +1,8 @@
#define FP highp
-uniform FP vec3 ka; // Ambient reflectivity
-uniform FP vec3 kd; // Diffuse reflectivity
-uniform FP vec3 ks; // Specular reflectivity
+uniform FP vec4 ka; // Ambient reflectivity
+uniform FP vec4 kd; // Diffuse reflectivity
+uniform FP vec4 ks; // Specular reflectivity
uniform FP float shininess; // Specular shininess factor
uniform FP vec3 eyePosition;
@@ -10,11 +10,10 @@ uniform FP vec3 eyePosition;
varying FP vec3 worldPosition;
varying FP vec3 worldNormal;
-#pragma include light.inc.frag
+#pragma include phong.inc.frag
void main()
{
- FP vec3 diffuseColor, specularColor;
- adsModel(worldPosition, worldNormal, eyePosition, shininess, diffuseColor, specularColor);
- gl_FragColor = vec4( ka + kd * diffuseColor + ks * specularColor, 1.0 );
+ FP vec3 worldView = normalize(eyePosition - worldPosition);
+ gl_FragColor = phongFunction(ka, kd, ks, shininess, worldPosition, worldView, worldNormal);
}
diff --git a/src/extras/shaders/es2/phong.inc.frag b/src/extras/shaders/es2/phong.inc.frag
new file mode 100644
index 000000000..9d17b68b5
--- /dev/null
+++ b/src/extras/shaders/es2/phong.inc.frag
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D 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$
+**
+****************************************************************************/
+
+#pragma include light.inc.frag
+
+void adsModel(const in FP vec3 vpos, const in FP vec3 vnormal, const in FP vec3 vview, const in FP float shininess,
+ out FP vec3 diffuseColor, out FP vec3 specularColor)
+{
+ diffuseColor = vec3(0.0);
+ specularColor = vec3(0.0);
+
+ FP vec3 n = normalize( vnormal );
+
+ FP vec3 s;
+ Light light;
+ for (int i = 0; i < lightCount; ++i) {
+ if (i == 0)
+ light = lights[0];
+ else if (i == 1)
+ light = lights[1];
+ else if (i == 2)
+ light = lights[2];
+ else if (i == 3)
+ light = lights[3];
+ else if (i == 4)
+ light = lights[4];
+ else if (i == 5)
+ light = lights[5];
+ else if (i == 6)
+ light = lights[6];
+ else if (i == 7)
+ light = lights[7];
+
+ FP float att = 1.0;
+ if ( light.type != TYPE_DIRECTIONAL ) {
+ s = light.position - vpos;
+ if (length( light.attenuation ) != 0.0) {
+ FP float dist = length(s);
+ att = 1.0 / (light.attenuation.x + light.attenuation.y * dist + light.attenuation.z * dist * dist);
+ }
+ s = normalize( s );
+ if ( light.type == TYPE_SPOT ) {
+ if ( degrees(acos(dot(-s, normalize(light.direction))) ) > light.cutOffAngle)
+ att = 0.0;
+ }
+ } else {
+ s = normalize( -light.direction );
+ }
+
+ FP float diffuse = max( dot( s, n ), 0.0 );
+
+ FP float specular = 0.0;
+ if (diffuse > 0.0 && shininess > 0.0 && att > 0.0) {
+ FP vec3 r = reflect( -s, n );
+ FP float normFactor = ( shininess + 2.0 ) / 2.0;
+ specular = normFactor * pow( max( dot( r, vview ), 0.0 ), shininess );
+ }
+
+ diffuseColor += att * light.intensity * diffuse * light.color;
+ specularColor += att * light.intensity * specular * light.color;
+ }
+}
+
+FP vec4 phongFunction(const in FP vec4 ambient,
+ const in FP vec4 diffuse,
+ const in FP vec4 specular,
+ const in FP float shininess,
+ const in FP vec3 worldPosition,
+ const in FP vec3 worldView,
+ const in FP vec3 worldNormal)
+{
+ // Calculate the lighting model, keeping the specular component separate
+ FP vec3 diffuseColor, specularColor;
+ adsModel(worldPosition, worldNormal, worldView, shininess, diffuseColor, specularColor);
+
+ // Combine spec with ambient+diffuse for final fragment color
+ FP vec3 color = (ambient.rgb + diffuseColor) * diffuse.rgb
+ + specularColor * specular.rgb;
+
+ return vec4(color, diffuse.a);
+}
diff --git a/src/extras/shaders/es2/phong.inc.frag100 b/src/extras/shaders/es2/phong.inc.frag100
new file mode 100644
index 000000000..507d8eaf5
--- /dev/null
+++ b/src/extras/shaders/es2/phong.inc.frag100
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D 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$
+**
+****************************************************************************/
+
+#pragma include light.inc.frag
+
+void adsModel(const in FP vec3 vpos, const in FP vec3 vnormal, const in FP vec3 vview, const in FP float shininess,
+ out FP vec3 diffuseColor, out FP vec3 specularColor)
+{
+ diffuseColor = vec3(0.0);
+ specularColor = vec3(0.0);
+
+ FP vec3 n = normalize( vnormal );
+
+ // 0
+ if (lightCount < 1)
+ return;
+ FP vec3 s;
+ FP float att = 1.0;
+ if ( lights[0].type != TYPE_DIRECTIONAL ) {
+ s = lights[0].position - vpos;
+ if (length( lights[0].attenuation ) != 0.0) {
+ FP float dist = length(s);
+ att = 1.0 / (lights[0].attenuation.x + lights[0].attenuation.y * dist + lights[0].attenuation.z * dist * dist);
+ }
+ s = normalize( s );
+ if ( lights[0].type == TYPE_SPOT ) {
+ if ( degrees(acos(dot(-s, normalize(lights[0].direction))) ) > lights[0].cutOffAngle)
+ att = 0.0;
+ }
+ } else {
+ s = normalize( -lights[0].direction );
+ }
+
+ FP float diffuse = max( dot( s, n ), 0.0 );
+
+ FP float specular = 0.0;
+ if (diffuse > 0.0 && shininess > 0.0 && att > 0.0) {
+ FP vec3 r = reflect( -s, n );
+ FP float normFactor = ( shininess + 2.0 ) / 2.0;
+ specular = normFactor * pow( max( dot( r, vview ), 0.0 ), shininess );
+ }
+
+ diffuseColor += att * lights[0].intensity * diffuse * lights[0].color;
+ specularColor += att * specular;
+
+ // 1
+ if (lightCount < 2)
+ return;
+ att = 1.0;
+ if ( lights[1].type != TYPE_DIRECTIONAL ) {
+ s = lights[1].position - vpos;
+ if (length( lights[1].attenuation ) != 0.0) {
+ FP float dist = length(s);
+ att = 1.0 / (lights[1].attenuation.x + lights[1].attenuation.y * dist + lights[1].attenuation.z * dist * dist);
+ }
+ s = normalize( s );
+ if ( lights[1].type == TYPE_SPOT ) {
+ if ( degrees(acos(dot(-s, normalize(lights[1].direction))) ) > lights[1].cutOffAngle)
+ att = 0.0;
+ }
+ } else {
+ s = normalize( -lights[1].direction );
+ }
+
+ diffuse = max( dot( s, n ), 0.0 );
+
+ specular = 0.0;
+ if (diffuse > 0.0 && shininess > 0.0 && att > 0.0) {
+ FP vec3 r = reflect( -s, n );
+ FP float normFactor = ( shininess + 2.0 ) / 2.0;
+ specular = normFactor * pow( max( dot( r, vview ), 0.0 ), shininess );
+ }
+
+ diffuseColor += att * lights[1].intensity * diffuse * lights[1].color;
+ specularColor += att * specular;
+}
+
+FP vec4 phongFunction(const in FP vec4 ambient,
+ const in FP vec4 diffuse,
+ const in FP vec4 specular,
+ const in FP float shininess,
+ const in FP vec3 worldPosition,
+ const in FP vec3 worldView,
+ const in FP vec3 worldNormal)
+{
+ // Calculate the lighting model, keeping the specular component separate
+ FP vec3 diffuseColor, specularColor;
+ adsModel(worldPosition, worldNormal, worldView, shininess, diffuseColor, specularColor);
+
+ // Combine spec with ambient+diffuse for final fragment color
+ FP vec3 color = (ambient.rgb + diffuseColor) * diffuse.rgb
+ + specularColor * specular.rgb;
+
+ return vec4(color, diffuse.a);
+}
diff --git a/src/extras/shaders/es2/phong.vert b/src/extras/shaders/es2/phong.vert
deleted file mode 100644
index 2b4c51b14..000000000
--- a/src/extras/shaders/es2/phong.vert
+++ /dev/null
@@ -1,17 +0,0 @@
-attribute vec3 vertexPosition;
-attribute vec3 vertexNormal;
-
-varying vec3 worldPosition;
-varying vec3 worldNormal;
-
-uniform mat4 modelMatrix;
-uniform mat3 modelNormalMatrix;
-uniform mat4 modelViewProjection;
-
-void main()
-{
- worldNormal = normalize( modelNormalMatrix * vertexNormal );
- worldPosition = vec3( modelMatrix * vec4( vertexPosition, 1.0 ) );
-
- gl_Position = modelViewProjection * vec4( vertexPosition, 1.0 );
-}
diff --git a/src/extras/shaders/es2/phongalpha.frag b/src/extras/shaders/es2/phongalpha.frag
deleted file mode 100644
index c5ec43049..000000000
--- a/src/extras/shaders/es2/phongalpha.frag
+++ /dev/null
@@ -1,22 +0,0 @@
-#define FP highp
-
-// TODO: Replace with a struct
-uniform FP vec3 ka; // Ambient reflectivity
-uniform FP vec3 kd; // Diffuse reflectivity
-uniform FP vec3 ks; // Specular reflectivity
-uniform FP float shininess; // Specular shininess factor
-uniform FP float alpha;
-
-uniform FP vec3 eyePosition;
-
-varying FP vec3 worldPosition;
-varying FP vec3 worldNormal;
-
-#pragma include light.inc.frag
-
-void main()
-{
- FP vec3 diffuseColor, specularColor;
- adsModel(worldPosition, worldNormal, eyePosition, shininess, diffuseColor, specularColor);
- gl_FragColor = vec4( ka + kd * diffuseColor + ks * specularColor, alpha );
-}
diff --git a/src/extras/shaders/gl3/metalrough.vert b/src/extras/shaders/gl3/default.vert
index 6d3a60ef6..f97cd099d 100644
--- a/src/extras/shaders/gl3/metalrough.vert
+++ b/src/extras/shaders/gl3/default.vert
@@ -48,7 +48,7 @@
**
****************************************************************************/
-#version 150
+#version 150 core
in vec3 vertexPosition;
in vec3 vertexNormal;
@@ -62,12 +62,14 @@ out vec2 texCoord;
uniform mat4 modelMatrix;
uniform mat3 modelNormalMatrix;
-uniform mat4 mvp;
+uniform mat4 modelViewProjection;
+
+uniform float texCoordScale;
void main()
{
- // Pass the texture coordinates through
- texCoord = vertexTexCoord;
+ // Pass through scaled texture coordinates
+ texCoord = vertexTexCoord * texCoordScale;
// Transform position, normal, and tangent to world space
worldPosition = vec3(modelMatrix * vec4(vertexPosition, 1.0));
@@ -75,5 +77,6 @@ void main()
worldTangent.xyz = normalize(vec3(modelMatrix * vec4(vertexTangent.xyz, 0.0)));
worldTangent.w = vertexTangent.w;
- gl_Position = mvp * vec4(vertexPosition, 1.0);
+ // Calculate vertex position in clip coordinates
+ gl_Position = modelViewProjection * vec4(vertexPosition, 1.0);
}
diff --git a/src/extras/shaders/gl3/diffusemap.frag b/src/extras/shaders/gl3/diffusemap.frag
index 7810fdb68..34fef5a43 100644
--- a/src/extras/shaders/gl3/diffusemap.frag
+++ b/src/extras/shaders/gl3/diffusemap.frag
@@ -1,7 +1,7 @@
#version 150 core
-uniform vec3 ka; // Ambient reflectivity
-uniform vec3 ks; // Specular reflectivity
+uniform vec4 ka; // Ambient reflectivity
+uniform vec4 ks; // Specular reflectivity
uniform float shininess; // Specular shininess factor
uniform vec3 eyePosition;
@@ -14,14 +14,11 @@ in vec2 texCoord;
out vec4 fragColor;
-#pragma include light.inc.frag
+#pragma include phong.inc.frag
void main()
{
- vec3 diffuseTextureColor = texture( diffuseTexture, texCoord ).rgb;
-
- vec3 diffuseColor, specularColor;
- adsModel(worldPosition, worldNormal, eyePosition, shininess, diffuseColor, specularColor);
-
- fragColor = vec4( diffuseTextureColor * ( ka + diffuseColor ) + ks * specularColor, 1.0 );
+ vec4 diffuseTextureColor = texture( diffuseTexture, texCoord );
+ vec3 worldView = normalize(eyePosition - worldPosition);
+ fragColor = phongFunction(ka, diffuseTextureColor, ks, shininess, worldPosition, worldView, worldNormal);
}
diff --git a/src/extras/shaders/gl3/diffusemap.vert b/src/extras/shaders/gl3/diffusemap.vert
deleted file mode 100644
index 439be6e99..000000000
--- a/src/extras/shaders/gl3/diffusemap.vert
+++ /dev/null
@@ -1,24 +0,0 @@
-#version 150 core
-
-in vec3 vertexPosition;
-in vec3 vertexNormal;
-in vec2 vertexTexCoord;
-
-out vec3 worldPosition;
-out vec3 worldNormal;
-out vec2 texCoord;
-
-uniform mat4 modelMatrix;
-uniform mat3 modelNormalMatrix;
-uniform mat4 mvp;
-
-uniform float texCoordScale;
-
-void main()
-{
- texCoord = vertexTexCoord * texCoordScale;
- worldNormal = normalize( modelNormalMatrix * vertexNormal );
- worldPosition = vec3( modelMatrix * vec4( vertexPosition, 1.0 ) );
-
- gl_Position = mvp * vec4( vertexPosition, 1.0 );
-}
diff --git a/src/extras/shaders/gl3/diffusespecularmap.frag b/src/extras/shaders/gl3/diffusespecularmap.frag
index fb809393a..8673a5121 100644
--- a/src/extras/shaders/gl3/diffusespecularmap.frag
+++ b/src/extras/shaders/gl3/diffusespecularmap.frag
@@ -1,7 +1,7 @@
#version 150 core
// TODO: Replace with a struct
-uniform vec3 ka; // Ambient reflectivity
+uniform vec4 ka; // Ambient reflectivity
uniform float shininess; // Specular shininess factor
uniform vec3 eyePosition;
@@ -15,15 +15,12 @@ in vec2 texCoord;
out vec4 fragColor;
-#pragma include light.inc.frag
+#pragma include phong.inc.frag
void main()
{
- vec3 diffuseTextureColor = texture( diffuseTexture, texCoord ).rgb;
- vec3 specularTextureColor = texture( specularTexture, texCoord ).rgb;
-
- vec3 diffuseColor, specularColor;
- adsModel(worldPosition, worldNormal, eyePosition, shininess, diffuseColor, specularColor);
-
- fragColor = vec4( diffuseTextureColor * ( ka + diffuseColor ) + specularTextureColor * specularColor, 1.0 );
+ vec4 diffuseTextureColor = texture( diffuseTexture, texCoord );
+ vec4 specularTextureColor = texture( specularTexture, texCoord );
+ vec3 worldView = normalize(eyePosition - worldPosition);
+ fragColor = phongFunction(ka, diffuseTextureColor, specularTextureColor, shininess, worldPosition, worldView, worldNormal);
}
diff --git a/src/extras/shaders/gl3/light.inc.frag b/src/extras/shaders/gl3/light.inc.frag
index ce5c581cf..0b642638f 100644
--- a/src/extras/shaders/gl3/light.inc.frag
+++ b/src/extras/shaders/gl3/light.inc.frag
@@ -23,200 +23,3 @@ struct EnvironmentLight {
};
uniform EnvironmentLight envLight;
uniform int envLightCount = 0;
-
-void adsModelNormalMapped(const in vec3 worldPos,
- const in vec3 tsNormal,
- const in vec3 worldEye,
- const in float shininess,
- const in mat3 tangentMatrix,
- out vec3 diffuseColor,
- out vec3 specularColor)
-{
- diffuseColor = vec3(0.0);
- specularColor = vec3(0.0);
-
- // We perform all work in tangent space, so we convert quantities from world space
- vec3 tsPos = tangentMatrix * worldPos;
- vec3 n = normalize(tsNormal);
- vec3 v = normalize(tangentMatrix * (worldEye - worldPos));
- vec3 s = vec3(0.0);
-
- for (int i = 0; i < lightCount; ++i) {
- float att = 1.0;
- float sDotN = 0.0;
-
- if (lights[i].type != TYPE_DIRECTIONAL) {
- // Point and Spot lights
-
- // Transform the light position from world to tangent space
- vec3 tsLightPos = tangentMatrix * lights[i].position;
- vec3 sUnnormalized = tsLightPos - tsPos;
- s = normalize(sUnnormalized); // Light direction in tangent space
-
- // Calculate the attenuation factor
- sDotN = dot(s, n);
- if (sDotN > 0.0) {
- if (lights[i].constantAttenuation != 0.0
- || lights[i].linearAttenuation != 0.0
- || lights[i].quadraticAttenuation != 0.0) {
- float dist = length(sUnnormalized);
- att = 1.0 / (lights[i].constantAttenuation +
- lights[i].linearAttenuation * dist +
- lights[i].quadraticAttenuation * dist * dist);
- }
-
- // The light direction is in world space, convert to tangent space
- if (lights[i].type == TYPE_SPOT) {
- // Check if fragment is inside or outside of the spot light cone
- vec3 tsLightDirection = tangentMatrix * lights[i].direction;
- if (degrees(acos(dot(-s, tsLightDirection))) > lights[i].cutOffAngle)
- sDotN = 0.0;
- }
- }
- } else {
- // Directional lights
- // The light direction is in world space, convert to tangent space
- s = normalize(tangentMatrix * -lights[i].direction);
- sDotN = dot(s, n);
- }
-
- // Calculate the diffuse factor
- float diffuse = max(sDotN, 0.0);
-
- // Calculate the specular factor
- float specular = 0.0;
- if (diffuse > 0.0 && shininess > 0.0) {
- float normFactor = (shininess + 2.0) / 2.0;
- vec3 r = reflect(-s, n); // Reflection direction in tangent space
- specular = normFactor * pow(max(dot(r, v), 0.0), shininess);
- }
-
- // Accumulate the diffuse and specular contributions
- diffuseColor += att * lights[i].intensity * diffuse * lights[i].color;
- specularColor += att * lights[i].intensity * specular * lights[i].color;
- }
-}
-
-void adsModel(const in vec3 worldPos,
- const in vec3 worldNormal,
- const in vec3 worldEye,
- const in float shininess,
- out vec3 diffuseColor,
- out vec3 specularColor)
-{
- diffuseColor = vec3(0.0);
- specularColor = vec3(0.0);
-
- // We perform all work in world space
- vec3 n = normalize(worldNormal);
- vec3 v = normalize(worldEye - worldPos);
- vec3 s = vec3(0.0);
-
- for (int i = 0; i < lightCount; ++i) {
- float att = 1.0;
- float sDotN = 0.0;
-
- if (lights[i].type != TYPE_DIRECTIONAL) {
- // Point and Spot lights
-
- // Light position is already in world space
- vec3 sUnnormalized = lights[i].position - worldPos;
- s = normalize(sUnnormalized); // Light direction
-
- // Calculate the attenuation factor
- sDotN = dot(s, n);
- if (sDotN > 0.0) {
- if (lights[i].constantAttenuation != 0.0
- || lights[i].linearAttenuation != 0.0
- || lights[i].quadraticAttenuation != 0.0) {
- float dist = length(sUnnormalized);
- att = 1.0 / (lights[i].constantAttenuation +
- lights[i].linearAttenuation * dist +
- lights[i].quadraticAttenuation * dist * dist);
- }
-
- // The light direction is in world space already
- if (lights[i].type == TYPE_SPOT) {
- // Check if fragment is inside or outside of the spot light cone
- if (degrees(acos(dot(-s, lights[i].direction))) > lights[i].cutOffAngle)
- sDotN = 0.0;
- }
- }
- } else {
- // Directional lights
- // The light direction is in world space already
- s = normalize(-lights[i].direction);
- sDotN = dot(s, n);
- }
-
- // Calculate the diffuse factor
- float diffuse = max(sDotN, 0.0);
-
- // Calculate the specular factor
- float specular = 0.0;
- if (diffuse > 0.0 && shininess > 0.0) {
- float normFactor = (shininess + 2.0) / 2.0;
- vec3 r = reflect(-s, n); // Reflection direction in world space
- specular = normFactor * pow(max(dot(r, v), 0.0), shininess);
- }
-
- // Accumulate the diffuse and specular contributions
- diffuseColor += att * lights[i].intensity * diffuse * lights[i].color;
- specularColor += att * lights[i].intensity * specular * lights[i].color;
- }
-}
-
-void adModel(const in vec3 worldPos,
- const in vec3 worldNormal,
- out vec3 diffuseColor)
-{
- diffuseColor = vec3(0.0);
-
- // We perform all work in world space
- vec3 n = normalize(worldNormal);
- vec3 s = vec3(0.0);
-
- for (int i = 0; i < lightCount; ++i) {
- float att = 1.0;
- float sDotN = 0.0;
-
- if (lights[i].type != TYPE_DIRECTIONAL) {
- // Point and Spot lights
-
- // Light position is already in world space
- vec3 sUnnormalized = lights[i].position - worldPos;
- s = normalize(sUnnormalized); // Light direction
-
- // Calculate the attenuation factor
- sDotN = dot(s, n);
- if (sDotN > 0.0) {
- if (lights[i].constantAttenuation != 0.0
- || lights[i].linearAttenuation != 0.0
- || lights[i].quadraticAttenuation != 0.0) {
- float dist = length(sUnnormalized);
- att = 1.0 / (lights[i].constantAttenuation +
- lights[i].linearAttenuation * dist +
- lights[i].quadraticAttenuation * dist * dist);
- }
-
- // The light direction is in world space already
- if (lights[i].type == TYPE_SPOT) {
- // Check if fragment is inside or outside of the spot light cone
- if (degrees(acos(dot(-s, lights[i].direction))) > lights[i].cutOffAngle)
- sDotN = 0.0;
- }
- }
- } else {
- // Directional lights
- // The light direction is in world space already
- s = normalize(-lights[i].direction);
- sDotN = dot(s, n);
- }
-
- // Calculate the diffuse factor
- float diffuse = max(sDotN, 0.0);
-
- // Accumulate the diffuse contributions
- diffuseColor += att * lights[i].intensity * diffuse * lights[i].color;
- }
-}
diff --git a/src/extras/shaders/gl3/normaldiffusemap.frag b/src/extras/shaders/gl3/normaldiffusemap.frag
index a99a7ed73..bac776738 100644
--- a/src/extras/shaders/gl3/normaldiffusemap.frag
+++ b/src/extras/shaders/gl3/normaldiffusemap.frag
@@ -1,33 +1,36 @@
#version 150 core
in vec3 worldPosition;
+in vec3 worldNormal;
+in vec4 worldTangent;
in vec2 texCoord;
-in mat3 tangentMatrix;
uniform sampler2D diffuseTexture;
uniform sampler2D normalTexture;
// TODO: Replace with a struct
-uniform vec3 ka; // Ambient reflectivity
-uniform vec3 ks; // Specular reflectivity
+uniform vec4 ka; // Ambient reflectivity
+uniform vec4 ks; // Specular reflectivity
uniform float shininess; // Specular shininess factor
uniform vec3 eyePosition;
out vec4 fragColor;
-#pragma include light.inc.frag
+#pragma include phong.inc.frag
+#pragma include coordinatesystems.inc
void main()
{
// Sample the textures at the interpolated texCoords
vec4 diffuseTextureColor = texture( diffuseTexture, texCoord );
- vec3 normal = 2.0 * texture( normalTexture, texCoord ).rgb - vec3( 1.0 );
+ vec3 tNormal = 2.0 * texture( normalTexture, texCoord ).rgb - vec3( 1.0 );
- // Calculate the lighting model, keeping the specular component separate
- vec3 diffuseColor, specularColor;
- adsModelNormalMapped(worldPosition, normal, eyePosition, shininess, tangentMatrix, diffuseColor, specularColor);
+ mat3 tangentMatrix = calcWorldSpaceToTangentSpaceMatrix(worldNormal, worldTangent);
+ mat3 invertTangentMatrix = transpose(tangentMatrix);
- // Combine spec with ambient+diffuse for final fragment color
- fragColor = vec4( ka + diffuseTextureColor.rgb * diffuseColor + ks * specularColor, 1.0 );
+ vec3 wNormal = normalize(invertTangentMatrix * tNormal);
+
+ vec3 worldView = normalize(eyePosition - worldPosition);
+ fragColor = phongFunction(ka, diffuseTextureColor, ks, shininess, worldPosition, worldView, wNormal);
}
diff --git a/src/extras/shaders/gl3/normaldiffusemap.vert b/src/extras/shaders/gl3/normaldiffusemap.vert
deleted file mode 100644
index 8da443e8d..000000000
--- a/src/extras/shaders/gl3/normaldiffusemap.vert
+++ /dev/null
@@ -1,47 +0,0 @@
-#version 150 core
-
-in vec3 vertexPosition;
-in vec3 vertexNormal;
-in vec2 vertexTexCoord;
-in vec4 vertexTangent;
-
-out vec3 worldPosition;
-out vec2 texCoord;
-out mat3 tangentMatrix;
-
-uniform mat4 modelMatrix;
-uniform mat3 modelNormalMatrix;
-uniform mat4 mvp;
-
-uniform float texCoordScale;
-
-void main()
-{
- // Pass through scaled texture coordinates
- texCoord = vertexTexCoord * texCoordScale;
-
- // Transform position, normal, and tangent to world coords
- worldPosition = vec3(modelMatrix * vec4(vertexPosition, 1.0));
- vec3 normal = normalize(modelNormalMatrix * vertexNormal);
- vec3 tangent = normalize(vec3(modelMatrix * vec4(vertexTangent.xyz, 0.0)));
-
- // Make the tangent truly orthogonal to the normal by using Gram-Schmidt.
- // This allows to build the tangentMatrix below by simply transposing the
- // tangent -> world space matrix (which would now be orthogonal)
- tangent = normalize(tangent - dot(tangent, normal) * normal);
-
- // Calculate binormal vector. No "real" need to renormalize it,
- // as built by crossing two normal vectors.
- // To orient the binormal correctly, use the fourth coordinate of the tangent,
- // which is +1 for a right hand system, and -1 for a left hand system.
- vec3 binormal = cross(normal, tangent) * vertexTangent.w;
-
- // Construct matrix to transform from eye coords to tangent space
- tangentMatrix = mat3(
- tangent.x, binormal.x, normal.x,
- tangent.y, binormal.y, normal.y,
- tangent.z, binormal.z, normal.z);
-
- // Calculate vertex position in clip coordinates
- gl_Position = mvp * vec4(vertexPosition, 1.0);
-}
diff --git a/src/extras/shaders/gl3/normaldiffusemapalpha.frag b/src/extras/shaders/gl3/normaldiffusemapalpha.frag
deleted file mode 100644
index ce5cf0e90..000000000
--- a/src/extras/shaders/gl3/normaldiffusemapalpha.frag
+++ /dev/null
@@ -1,34 +0,0 @@
-#version 150 core
-
-in vec3 worldPosition;
-in vec2 texCoord;
-in mat3 tangentMatrix;
-
-uniform sampler2D diffuseTexture;
-uniform sampler2D normalTexture;
-
-// TODO: Replace with a struct
-uniform vec3 ka; // Ambient reflectivity
-uniform vec3 ks; // Specular reflectivity
-uniform float shininess; // Specular shininess factor
-
-uniform vec3 eyePosition;
-
-out vec4 fragColor;
-
-#pragma include light.inc.frag
-
-void main()
-{
- // Sample the textures at the interpolated texCoords
- vec4 diffuseTextureColor = texture( diffuseTexture, texCoord );
- vec3 normal = 2.0 * texture( normalTexture, texCoord ).rgb - vec3( 1.0 );
-
- // Calculate the lighting model, keeping the specular component separate
- vec3 diffuseColor, specularColor;
- adsModelNormalMapped(worldPosition, normal, eyePosition, shininess, tangentMatrix, diffuseColor, specularColor);
-
- // Combine spec with ambient+diffuse for final fragment color
- // Use the alpha from the diffuse texture (for alpha to coverage)
- fragColor = vec4( ka + diffuseTextureColor.rgb * diffuseColor + ks * specularColor, diffuseTextureColor.a );
-}
diff --git a/src/extras/shaders/gl3/normaldiffusespecularmap.frag b/src/extras/shaders/gl3/normaldiffusespecularmap.frag
index b60cfe84c..d96b9e747 100644
--- a/src/extras/shaders/gl3/normaldiffusespecularmap.frag
+++ b/src/extras/shaders/gl3/normaldiffusespecularmap.frag
@@ -1,8 +1,9 @@
#version 150 core
in vec3 worldPosition;
+in vec3 worldNormal;
+in vec4 worldTangent;
in vec2 texCoord;
-in mat3 tangentMatrix;
out vec4 fragColor;
@@ -10,26 +11,25 @@ uniform sampler2D diffuseTexture;
uniform sampler2D specularTexture;
uniform sampler2D normalTexture;
-uniform vec3 ka; // Ambient reflectivity
+uniform vec4 ka; // Ambient reflectivity
uniform float shininess; // Specular shininess factor
uniform vec3 eyePosition;
-#pragma include light.inc.frag
+#pragma include phong.inc.frag
+#pragma include coordinatesystems.inc
void main()
{
// Sample the textures at the interpolated texCoords
vec4 diffuseTextureColor = texture( diffuseTexture, texCoord );
vec4 specularTextureColor = texture( specularTexture, texCoord );
- vec3 normal = 2.0 * texture( normalTexture, texCoord ).rgb - vec3( 1.0 );
+ vec3 tNormal = 2.0 * texture( normalTexture, texCoord ).rgb - vec3( 1.0 );
- // Calculate the lighting model, keeping the specular component separate
- vec3 diffuseColor, specularColor;
- adsModelNormalMapped(worldPosition, normal, eyePosition,
- shininess, tangentMatrix,
- diffuseColor, specularColor);
+ mat3 tangentMatrix = calcWorldSpaceToTangentSpaceMatrix(worldNormal, worldTangent);
+ mat3 invertTangentMatrix = transpose(tangentMatrix);
- // Combine spec with ambient+diffuse for final fragment color
- fragColor = vec4((ka + diffuseColor) * diffuseTextureColor.rgb
- + specularColor * specularTextureColor.rgb, 1.0);
+ vec3 wNormal = normalize(invertTangentMatrix * tNormal);
+
+ vec3 worldView = normalize(eyePosition - worldPosition);
+ fragColor = phongFunction(ka, diffuseTextureColor, specularTextureColor, shininess, worldPosition, worldView, wNormal);
}
diff --git a/src/extras/shaders/gl3/pervertexcolor.frag b/src/extras/shaders/gl3/pervertexcolor.frag
index b5ed5a33d..40fc066d6 100644
--- a/src/extras/shaders/gl3/pervertexcolor.frag
+++ b/src/extras/shaders/gl3/pervertexcolor.frag
@@ -2,15 +2,16 @@
in vec3 worldPosition;
in vec3 worldNormal;
-in vec3 color;
+in vec4 color;
out vec4 fragColor;
-#pragma include light.inc.frag
+uniform vec3 eyePosition;
+
+#pragma include phong.inc.frag
void main()
{
- vec3 diffuseColor;
- adModel(worldPosition, worldNormal, diffuseColor);
- fragColor = vec4( color + color * diffuseColor, 1.0 );
+ vec3 worldView = normalize(eyePosition - worldPosition);
+ fragColor = phongFunction(color, color, vec4(0.0), 0.0, worldPosition, worldView, worldNormal);
}
diff --git a/src/extras/shaders/gl3/pervertexcolor.vert b/src/extras/shaders/gl3/pervertexcolor.vert
index 87713a520..1d721e945 100644
--- a/src/extras/shaders/gl3/pervertexcolor.vert
+++ b/src/extras/shaders/gl3/pervertexcolor.vert
@@ -2,11 +2,11 @@
in vec3 vertexPosition;
in vec3 vertexNormal;
-in vec3 vertexColor;
+in vec4 vertexColor;
out vec3 worldPosition;
out vec3 worldNormal;
-out vec3 color;
+out vec4 color;
uniform mat4 modelMatrix;
uniform mat3 modelNormalMatrix;
diff --git a/src/extras/shaders/gl3/phong.frag b/src/extras/shaders/gl3/phong.frag
index a4d7e0969..3652672b5 100644
--- a/src/extras/shaders/gl3/phong.frag
+++ b/src/extras/shaders/gl3/phong.frag
@@ -1,8 +1,8 @@
#version 150 core
-uniform vec3 ka; // Ambient reflectivity
-uniform vec3 kd; // Diffuse reflectivity
-uniform vec3 ks; // Specular reflectivity
+uniform vec4 ka; // Ambient reflectivity
+uniform vec4 kd; // Diffuse reflectivity
+uniform vec4 ks; // Specular reflectivity
uniform float shininess; // Specular shininess factor
uniform vec3 eyePosition;
@@ -12,11 +12,10 @@ in vec3 worldNormal;
out vec4 fragColor;
-#pragma include light.inc.frag
+#pragma include phong.inc.frag
void main()
{
- vec3 diffuseColor, specularColor;
- adsModel(worldPosition, worldNormal, eyePosition, shininess, diffuseColor, specularColor);
- fragColor = vec4( ka + kd * diffuseColor + ks * specularColor, 1.0 );
+ vec3 worldView = normalize(eyePosition - worldPosition);
+ fragColor = phongFunction(ka, kd, ks, shininess, worldPosition, worldView, worldNormal);
}
diff --git a/src/extras/shaders/gl3/phong.inc.frag b/src/extras/shaders/gl3/phong.inc.frag
new file mode 100644
index 000000000..47a6ecd4a
--- /dev/null
+++ b/src/extras/shaders/gl3/phong.inc.frag
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D 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$
+**
+****************************************************************************/
+
+#pragma include light.inc.frag
+
+void adsModel(const in vec3 worldPos,
+ const in vec3 worldNormal,
+ const in vec3 worldView,
+ const in float shininess,
+ out vec3 diffuseColor,
+ out vec3 specularColor)
+{
+ diffuseColor = vec3(0.0);
+ specularColor = vec3(0.0);
+
+ // We perform all work in world space
+ vec3 n = normalize(worldNormal);
+ vec3 s = vec3(0.0);
+
+ for (int i = 0; i < lightCount; ++i) {
+ float att = 1.0;
+ float sDotN = 0.0;
+
+ if (lights[i].type != TYPE_DIRECTIONAL) {
+ // Point and Spot lights
+
+ // Light position is already in world space
+ vec3 sUnnormalized = lights[i].position - worldPos;
+ s = normalize(sUnnormalized); // Light direction
+
+ // Calculate the attenuation factor
+ sDotN = dot(s, n);
+ if (sDotN > 0.0) {
+ if (lights[i].constantAttenuation != 0.0
+ || lights[i].linearAttenuation != 0.0
+ || lights[i].quadraticAttenuation != 0.0) {
+ float dist = length(sUnnormalized);
+ att = 1.0 / (lights[i].constantAttenuation +
+ lights[i].linearAttenuation * dist +
+ lights[i].quadraticAttenuation * dist * dist);
+ }
+
+ // The light direction is in world space already
+ if (lights[i].type == TYPE_SPOT) {
+ // Check if fragment is inside or outside of the spot light cone
+ if (degrees(acos(dot(-s, lights[i].direction))) > lights[i].cutOffAngle)
+ sDotN = 0.0;
+ }
+ }
+ } else {
+ // Directional lights
+ // The light direction is in world space already
+ s = normalize(-lights[i].direction);
+ sDotN = dot(s, n);
+ }
+
+ // Calculate the diffuse factor
+ float diffuse = max(sDotN, 0.0);
+
+ // Calculate the specular factor
+ float specular = 0.0;
+ if (diffuse > 0.0 && shininess > 0.0) {
+ float normFactor = (shininess + 2.0) / 2.0;
+ vec3 r = reflect(-s, n); // Reflection direction in world space
+ specular = normFactor * pow(max(dot(r, worldView), 0.0), shininess);
+ }
+
+ // Accumulate the diffuse and specular contributions
+ diffuseColor += att * lights[i].intensity * diffuse * lights[i].color;
+ specularColor += att * lights[i].intensity * specular * lights[i].color;
+ }
+}
+
+vec4 phongFunction(const in vec4 ambient,
+ const in vec4 diffuse,
+ const in vec4 specular,
+ const in float shininess,
+ const in vec3 worldPosition,
+ const in vec3 worldView,
+ const in vec3 worldNormal)
+{
+ // Calculate the lighting model, keeping the specular component separate
+ vec3 diffuseColor, specularColor;
+ adsModel(worldPosition, worldNormal, worldView, shininess, diffuseColor, specularColor);
+
+ // Combine spec with ambient+diffuse for final fragment color
+ vec3 color = (ambient.rgb + diffuseColor) * diffuse.rgb
+ + specularColor * specular.rgb;
+
+ return vec4(color, diffuse.a);
+}
diff --git a/src/extras/shaders/gl3/phong.vert b/src/extras/shaders/gl3/phong.vert
deleted file mode 100644
index cdb3c70e9..000000000
--- a/src/extras/shaders/gl3/phong.vert
+++ /dev/null
@@ -1,19 +0,0 @@
-#version 150 core
-
-in vec3 vertexPosition;
-in vec3 vertexNormal;
-
-out vec3 worldPosition;
-out vec3 worldNormal;
-
-uniform mat4 modelMatrix;
-uniform mat3 modelNormalMatrix;
-uniform mat4 modelViewProjection;
-
-void main()
-{
- worldNormal = normalize( modelNormalMatrix * vertexNormal );
- worldPosition = vec3( modelMatrix * vec4( vertexPosition, 1.0 ) );
-
- gl_Position = modelViewProjection * vec4( vertexPosition, 1.0 );
-}
diff --git a/src/extras/shaders/gl3/phongalpha.frag b/src/extras/shaders/gl3/phongalpha.frag
deleted file mode 100644
index cb019e9aa..000000000
--- a/src/extras/shaders/gl3/phongalpha.frag
+++ /dev/null
@@ -1,24 +0,0 @@
-#version 150 core
-
-// TODO: Replace with a struct
-uniform vec3 ka; // Ambient reflectivity
-uniform vec3 kd; // Diffuse reflectivity
-uniform vec3 ks; // Specular reflectivity
-uniform float shininess; // Specular shininess factor
-uniform float alpha;
-
-uniform vec3 eyePosition;
-
-in vec3 worldPosition;
-in vec3 worldNormal;
-
-out vec4 fragColor;
-
-#pragma include light.inc.frag
-
-void main()
-{
- vec3 diffuseColor, specularColor;
- adsModel(worldPosition, worldNormal, eyePosition, shininess, diffuseColor, specularColor);
- fragColor = vec4( ka + kd * diffuseColor + ks * specularColor, alpha );
-}
diff --git a/src/extras/text/distancefieldtextrenderer.cpp b/src/extras/text/distancefieldtextrenderer.cpp
index 9f390e8da..4cf9c0b4a 100644
--- a/src/extras/text/distancefieldtextrenderer.cpp
+++ b/src/extras/text/distancefieldtextrenderer.cpp
@@ -80,8 +80,8 @@ void DistanceFieldTextRendererPrivate::init()
m_geometry = new Qt3DRender::QGeometry(m_renderer);
m_renderer->setGeometry(m_geometry);
- m_vertexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, m_geometry);
- m_indexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::IndexBuffer, m_geometry);
+ m_vertexBuffer = new Qt3DRender::QBuffer(m_geometry);
+ m_indexBuffer = new Qt3DRender::QBuffer(m_geometry);
m_positionAttr = new Qt3DRender::QAttribute(m_geometry);
m_positionAttr->setName(Qt3DRender::QAttribute::defaultPositionAttributeName());
diff --git a/src/plugins/geometryloaders/default/objgeometryloader.cpp b/src/plugins/geometryloaders/default/objgeometryloader.cpp
index b1fb1f931..7184e2f69 100644
--- a/src/plugins/geometryloaders/default/objgeometryloader.cpp
+++ b/src/plugins/geometryloaders/default/objgeometryloader.cpp
@@ -144,7 +144,7 @@ bool ObjGeometryLoader::doLoad(QIODevice *ioDev, const QString &subMesh)
++normalsOffset;
}
}
- } else if (!skipping && qstrncmp(tokens.charPtrAt(0), "f ", 2) == 0) {
+ } else if (!skipping && tokens.size() >= 4 && qstrncmp(tokens.charPtrAt(0), "f ", 2) == 0) {
// Process face
++faceCount;
diff --git a/src/plugins/sceneparsers/assimp/assimpimporter.cpp b/src/plugins/sceneparsers/assimp/assimpimporter.cpp
index a1558b7e2..3a06c7807 100644
--- a/src/plugins/sceneparsers/assimp/assimpimporter.cpp
+++ b/src/plugins/sceneparsers/assimp/assimpimporter.cpp
@@ -403,8 +403,8 @@ void AssimpImporter::setSource(const QUrl &source)
}
/*!
- * Sets the \a source used by the parser to load the asset file.
- * If the file is valid, this will trigger parsing of the file.
+ * Sets the \a basePath used by the parser to load the asset file.
+ * If the file specified in \a data is valid, this will trigger parsing of the file.
*/
void AssimpImporter::setData(const QByteArray &data, const QString &basePath)
{
@@ -412,7 +412,7 @@ void AssimpImporter::setData(const QByteArray &data, const QString &basePath)
}
/*!
- * Returns \c true if the extension of \a source is supported by
+ * Returns \c true if the extension in QStringList \a extensions is supported by
* the assimp parser.
*/
bool AssimpImporter::areFileTypesSupported(const QStringList &extensions) const
diff --git a/src/plugins/sceneparsers/gltf/gltfimporter.cpp b/src/plugins/sceneparsers/gltf/gltfimporter.cpp
index a94a4f307..4419bd708 100644
--- a/src/plugins/sceneparsers/gltf/gltfimporter.cpp
+++ b/src/plugins/sceneparsers/gltf/gltfimporter.cpp
@@ -268,11 +268,23 @@ GLTFImporter::~GLTFImporter()
}
+/*!
+ \class Qt3DRender::GLTFImporter
+ \inmodule Qt3DRender
+ \brief Handles importing of gltf files
+*/
+/*!
+ Set the base \a path for importing scenes.
+*/
void GLTFImporter::setBasePath(const QString& path)
{
m_basePath = path;
}
+/*!
+ Set a \a json document as the file used for importing a scene.
+ Returns true if the operation is successful.
+*/
bool GLTFImporter::setJSON(const QJsonDocument &json )
{
if ( !json.isObject() ) {
@@ -286,7 +298,8 @@ bool GLTFImporter::setJSON(const QJsonDocument &json )
}
/*!
- * Sets the \a path used by the parser to load the scene file.
+ * Sets the path based on parameter \a source. The path is
+ * used by the parser to load the scene file.
* If the file is valid, parsing is automatically triggered.
*/
void GLTFImporter::setSource(const QUrl &source)
@@ -314,8 +327,9 @@ void GLTFImporter::setSource(const QUrl &source)
}
/*!
- * Sets the \a path used by the parser to load the scene file.
- * If the file is valid, parsing is automatically triggered.
+ * Sets the \a basePath used by the parser to load the scene file.
+ * If the file derived from \a data is valid, parsing is automatically
+ * triggered.
*/
void GLTFImporter::setData(const QByteArray& data, const QString &basePath)
{
@@ -332,7 +346,7 @@ void GLTFImporter::setData(const QByteArray& data, const QString &basePath)
}
/*!
- * Returns true if the extensions are supported by the
+ * Returns true if the \a extensions are supported by the
* GLTF parser.
*/
bool GLTFImporter::areFileTypesSupported(const QStringList &extensions) const
@@ -340,6 +354,9 @@ bool GLTFImporter::areFileTypesSupported(const QStringList &extensions) const
return GLTFImporter::isGLTFSupported(extensions);
}
+/*!
+ Imports the node specified in \a id from the GLTF file.
+*/
Qt3DCore::QEntity* GLTFImporter::node(const QString &id)
{
QJsonObject nodes = m_json.object().value(KEY_NODES).toObject();
@@ -507,6 +524,9 @@ Qt3DCore::QEntity* GLTFImporter::node(const QString &id)
return result;
}
+/*!
+ Imports the scene specified in parameter \a id.
+*/
Qt3DCore::QEntity* GLTFImporter::scene(const QString &id)
{
parse();
@@ -1656,6 +1676,9 @@ void GLTFImporter::processJSONRenderPass(const QString &id, const QJsonObject &j
m_renderPasses[id] = pass;
}
+/*!
+ Loads raw data from the GLTF file into the buffer.
+*/
void GLTFImporter::loadBufferData()
{
for (auto &bufferData : m_bufferDatas) {
@@ -1665,6 +1688,9 @@ void GLTFImporter::loadBufferData()
}
}
+/*!
+ Removes all data from the buffer.
+*/
void GLTFImporter::unloadBufferData()
{
for (const auto &bufferData : qAsConst(m_bufferDatas)) {
diff --git a/src/plugins/sceneparsers/gltfexport/gltfexporter.cpp b/src/plugins/sceneparsers/gltfexport/gltfexporter.cpp
index 7921fce64..ba100e095 100644
--- a/src/plugins/sceneparsers/gltfexport/gltfexporter.cpp
+++ b/src/plugins/sceneparsers/gltfexport/gltfexporter.cpp
@@ -266,6 +266,13 @@ GLTFExporter::~GLTFExporter()
{
}
+/*!
+ \class Qt3DRender::GLTFExporter
+ \inmodule Qt3DRender
+ \brief Manages the export of a 3D scene to the GLTF format.
+
+ Handles the export of a 3D scene to the GLTF format.
+*/
// sceneRoot : The root entity that contains the exported scene. If the sceneRoot doesn't have
// any exportable components, it is not exported itself. This is because importing a
// scene creates an empty top level entity to hold the scene.
@@ -278,6 +285,23 @@ GLTFExporter::~GLTFExporter()
// "binaryJson" (bool): Generates a binary JSON file, which is more efficient to parse.
// "compactJson" (bool): Removes unnecessary whitespace from the generated JSON file.
// Ignored if "binaryJson" option is true.
+
+/*!
+ Exports the scene to the GLTF format
+
+ \a sceneRoot is the root entity that will be exported.
+ If the sceneRoot does not have any exportable components, it is not exported itself.
+
+ \a outDir is the directory in which the scene export is created.
+
+ \a exportName is the name of the directory created in \c outDir that will hold
+ the exported scene.
+
+ \a options contain the export options.
+
+ Returns true if the export was carried out successfully.
+*/
+
bool GLTFExporter::exportScene(QEntity *sceneRoot, const QString &outDir,
const QString &exportName, const QVariantHash &options)
{
@@ -643,18 +667,23 @@ void GLTFExporter::parseMaterials()
for (auto param : parameters) {
if (param->value().type() == QVariant::Color) {
QColor color = param->value().value<QColor>();
- if (param->name() == MATERIAL_AMBIENT_COLOR)
+ if (param->name() == MATERIAL_AMBIENT_COLOR) {
matInfo.colors.insert(QStringLiteral("ambient"), color);
- else if (param->name() == MATERIAL_DIFFUSE_COLOR)
+ } else if (param->name() == MATERIAL_DIFFUSE_COLOR) {
+ if (matInfo.type == MaterialInfo::TypePhongAlpha) {
+ matInfo.values.insert(QStringLiteral("transparency"), float(color.alphaF()));
+ color.setAlphaF(1.0f);
+ }
matInfo.colors.insert(QStringLiteral("diffuse"), color);
- else if (param->name() == MATERIAL_SPECULAR_COLOR)
+ } else if (param->name() == MATERIAL_SPECULAR_COLOR) {
matInfo.colors.insert(QStringLiteral("specular"), color);
- else if (param->name() == MATERIAL_COOL_COLOR) // Custom Qt3D gooch
+ } else if (param->name() == MATERIAL_COOL_COLOR) { // Custom Qt3D gooch
matInfo.colors.insert(QStringLiteral("cool"), color);
- else if (param->name() == MATERIAL_WARM_COLOR) // Custom Qt3D gooch
+ } else if (param->name() == MATERIAL_WARM_COLOR) { // Custom Qt3D gooch
matInfo.colors.insert(QStringLiteral("warm"), color);
- else
+ } else {
matInfo.colors.insert(param->name(), color);
+ }
} else if (param->value().canConvert<QAbstractTexture *>()) {
const QString urlString = textureVariantToUrl(param->value());
if (param->name() == MATERIAL_DIFFUSE_TEXTURE)
diff --git a/src/quick3d/quick3drender/items/quick3dbuffer.cpp b/src/quick3d/quick3drender/items/quick3dbuffer.cpp
index 362e60328..9ff349118 100644
--- a/src/quick3d/quick3drender/items/quick3dbuffer.cpp
+++ b/src/quick3d/quick3drender/items/quick3dbuffer.cpp
@@ -61,7 +61,7 @@ const int jsValueTypeId = qMetaTypeId<QJSValue>();
}
Quick3DBuffer::Quick3DBuffer(Qt3DCore::QNode *parent)
- : Qt3DRender::QBuffer(QBuffer::VertexBuffer, parent)
+ : Qt3DRender::QBuffer(parent)
, m_engine(nullptr)
, m_v4engine(nullptr)
{
diff --git a/src/render/backend/renderer.cpp b/src/render/backend/renderer.cpp
index da4ad0ae0..1ba178a3a 100644
--- a/src/render/backend/renderer.cpp
+++ b/src/render/backend/renderer.cpp
@@ -64,6 +64,7 @@
#include <Qt3DRender/private/renderqueue_p.h>
#include <Qt3DRender/private/shader_p.h>
#include <Qt3DRender/private/buffer_p.h>
+#include <Qt3DRender/private/glbuffer_p.h>
#include <Qt3DRender/private/renderstateset_p.h>
#include <Qt3DRender/private/technique_p.h>
#include <Qt3DRender/private/renderthread_p.h>
@@ -1078,8 +1079,9 @@ void Renderer::updateGLResources()
for (HBuffer handle: dirtyBufferHandles) {
Buffer *buffer = m_nodesManager->bufferManager()->data(handle);
// Forces creation if it doesn't exit
+ // Also note the binding point doesn't really matter here, we just upload data
if (!m_graphicsContext->hasGLBufferForBuffer(buffer))
- m_graphicsContext->glBufferForRenderBuffer(buffer);
+ m_graphicsContext->glBufferForRenderBuffer(buffer, GLBuffer::ArrayBuffer);
// Update the glBuffer data
m_graphicsContext->updateBuffer(buffer);
buffer->unsetDirty();
@@ -1604,7 +1606,7 @@ void Renderer::performDraw(RenderCommand *command)
}
// Get GLBuffer from Buffer;
- GLBuffer *indirectDrawGLBuffer = m_graphicsContext->glBufferForRenderBuffer(indirectDrawBuffer);
+ GLBuffer *indirectDrawGLBuffer = m_graphicsContext->glBufferForRenderBuffer(indirectDrawBuffer, GLBuffer::DrawIndirectBuffer);
if (Q_UNLIKELY(indirectDrawGLBuffer == nullptr)) {
qWarning() << "Invalid Indirect Draw Buffer - failed to retrieve GLBuffer";
return;
diff --git a/src/render/backend/renderview.cpp b/src/render/backend/renderview.cpp
index 962480f2f..07311824e 100644
--- a/src/render/backend/renderview.cpp
+++ b/src/render/backend/renderview.cpp
@@ -129,6 +129,7 @@ RenderView::StandardUniformsNameToTypeHash RenderView::initializeStandardUniform
setters.insert(StringToInt::lookupId(QLatin1String("modelViewNormal")), ModelViewNormalMatrix);
setters.insert(StringToInt::lookupId(QLatin1String("viewportMatrix")), ViewportMatrix);
setters.insert(StringToInt::lookupId(QLatin1String("inverseViewportMatrix")), InverseViewportMatrix);
+ setters.insert(StringToInt::lookupId(QLatin1String("aspectRatio")), AspectRatio);
setters.insert(StringToInt::lookupId(QLatin1String("exposure")), Exposure);
setters.insert(StringToInt::lookupId(QLatin1String("gamma")), Gamma);
setters.insert(StringToInt::lookupId(QLatin1String("time")), Time);
@@ -200,6 +201,8 @@ UniformValue RenderView::standardUniformValue(RenderView::StandardUniform standa
viewportMatrix.viewport(resolveViewport(m_viewport, m_surfaceSize));
return UniformValue(viewportMatrix.inverted());
}
+ case AspectRatio:
+ return float(m_surfaceSize.width()) / float(m_surfaceSize.height());
case Exposure:
return UniformValue(m_data.m_renderCameraLens ? m_data.m_renderCameraLens->exposure() : 0.0f);
case Gamma:
diff --git a/src/render/backend/renderview_p.h b/src/render/backend/renderview_p.h
index bc68e2a63..8c733fc3a 100644
--- a/src/render/backend/renderview_p.h
+++ b/src/render/backend/renderview_p.h
@@ -342,6 +342,7 @@ private:
ModelViewNormalMatrix,
ViewportMatrix,
InverseViewportMatrix,
+ AspectRatio,
Time,
Exposure,
Gamma,
diff --git a/src/render/frontend/qitemmodelbuffer.cpp b/src/render/frontend/qitemmodelbuffer.cpp
index 3941ac2fd..82215204a 100644
--- a/src/render/frontend/qitemmodelbuffer.cpp
+++ b/src/render/frontend/qitemmodelbuffer.cpp
@@ -223,7 +223,7 @@ QBuffer *QItemModelBuffer::buffer()
m_attributes.clear();
m_itemStride = 0;
- m_buffer = new QBuffer(QBuffer::VertexBuffer);
+ m_buffer = new QBuffer;
// assume model will change
m_buffer->setUsage(QBuffer::DynamicDraw);
diff --git a/src/render/frontend/qrendersettings.cpp b/src/render/frontend/qrendersettings.cpp
index 4212897ab..23f88eb10 100644
--- a/src/render/frontend/qrendersettings.cpp
+++ b/src/render/frontend/qrendersettings.cpp
@@ -217,8 +217,11 @@ void QRenderSettings::setActiveFrameGraph(QFrameGraphNode *activeFrameGraph)
if (d->m_activeFrameGraph && activeFrameGraph) {
Qt3DRender::QRenderSurfaceSelector *oldSurfaceSelector = Qt3DRender::QRenderSurfaceSelectorPrivate::find(d->m_activeFrameGraph);
Qt3DRender::QRenderSurfaceSelector *newSurfaceSelector = Qt3DRender::QRenderSurfaceSelectorPrivate::find(activeFrameGraph);
- if (oldSurfaceSelector && newSurfaceSelector && oldSurfaceSelector->surface())
+ if (oldSurfaceSelector && newSurfaceSelector && oldSurfaceSelector->surface()) {
+ newSurfaceSelector->setExternalRenderTargetSize(oldSurfaceSelector->externalRenderTargetSize());
+ newSurfaceSelector->setSurfacePixelRatio(oldSurfaceSelector->surfacePixelRatio());
newSurfaceSelector->setSurface(oldSurfaceSelector->surface());
+ }
}
if (d->m_activeFrameGraph)
diff --git a/src/render/geometry/buffer.cpp b/src/render/geometry/buffer.cpp
index 666b5006d..3658ef335 100644
--- a/src/render/geometry/buffer.cpp
+++ b/src/render/geometry/buffer.cpp
@@ -51,7 +51,6 @@ namespace Render {
Buffer::Buffer()
: BackendNode(QBackendNode::ReadWrite)
- , m_type(QBuffer::VertexBuffer)
, m_usage(QBuffer::StaticDraw)
, m_bufferDirty(false)
, m_syncData(false)
@@ -68,7 +67,6 @@ Buffer::~Buffer()
void Buffer::cleanup()
{
- m_type = QBuffer::VertexBuffer;
m_usage = QBuffer::StaticDraw;
m_data.clear();
m_bufferUpdates.clear();
@@ -120,7 +118,6 @@ void Buffer::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &chang
const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QBufferData>>(change);
const auto &data = typedChange->data;
m_data = data.data;
- m_type = data.type;
m_usage = data.usage;
m_syncData = data.syncData;
m_access = data.access;
@@ -164,9 +161,6 @@ void Buffer::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
Qt3DRender::QBufferUpdate updateData = propertyChange->value().value<Qt3DRender::QBufferUpdate>();
m_bufferUpdates.push_back(updateData);
m_bufferDirty = true;
- } else if (propertyName == QByteArrayLiteral("type")) {
- m_type = static_cast<QBuffer::BufferType>(propertyChange->value().value<int>());
- m_bufferDirty = true;
} else if (propertyName == QByteArrayLiteral("usage")) {
m_usage = static_cast<QBuffer::UsageType>(propertyChange->value().value<int>());
m_bufferDirty = true;
diff --git a/src/render/geometry/buffer_p.h b/src/render/geometry/buffer_p.h
index 690d1eab6..9a171599d 100644
--- a/src/render/geometry/buffer_p.h
+++ b/src/render/geometry/buffer_p.h
@@ -78,7 +78,6 @@ public:
void setManager(BufferManager *manager);
void executeFunctor();
void updateDataFromGPUToCPU(QByteArray data);
- inline QBuffer::BufferType type() const { return m_type; }
inline QBuffer::UsageType usage() const { return m_usage; }
inline QByteArray data() const { return m_data; }
inline QVector<Qt3DRender::QBufferUpdate> &pendingBufferUpdates() { return m_bufferUpdates; }
@@ -92,7 +91,6 @@ private:
void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
void forceDataUpload();
- QBuffer::BufferType m_type;
QBuffer::UsageType m_usage;
QByteArray m_data;
QVector<Qt3DRender::QBufferUpdate> m_bufferUpdates;
diff --git a/src/render/geometry/qbuffer.cpp b/src/render/geometry/qbuffer.cpp
index 3d524d60f..fe065929d 100644
--- a/src/render/geometry/qbuffer.cpp
+++ b/src/render/geometry/qbuffer.cpp
@@ -77,6 +77,8 @@ QBufferPrivate::QBufferPrivate()
* \qmlproperty QBuffer::BufferType Buffer::type
*
* Holds the buffer type.
+ *
+ * \deprecated
*/
/*!
@@ -220,6 +222,8 @@ QBufferPrivate::QBufferPrivate()
* GL_SHADER_STORAGE_BUFFER
* \value DrawIndirectBuffer
* GL_DRAW_INDIRECT_BUFFER
+ *
+ * \deprecated
*/
/*!
@@ -253,7 +257,17 @@ QBufferPrivate::QBufferPrivate()
*/
/*!
+ * Constructs a new QBuffer with \a parent.
+ */
+QBuffer::QBuffer(QNode *parent)
+ : QNode(*new QBufferPrivate(), parent)
+{
+}
+
+/*!
* Constructs a new QBuffer of buffer type \a ty with \a parent.
+ *
+ * \deprecated
*/
QBuffer::QBuffer(QBuffer::BufferType ty, QNode *parent)
: QNode(*new QBufferPrivate(), parent)
@@ -360,6 +374,8 @@ void QBuffer::setUsage(QBuffer::UsageType usage)
* \property QBuffer::type
*
* Holds the buffer type.
+ *
+ * \deprecated
*/
QBuffer::BufferType QBuffer::type() const
{
@@ -448,7 +464,6 @@ Qt3DCore::QNodeCreatedChangeBasePtr QBuffer::createNodeCreationChange() const
auto &data = creationChange->data;
Q_D(const QBuffer);
data.data = d->m_data;
- data.type = d->m_type;
data.usage = d->m_usage;
data.functor = d->m_functor;
data.syncData = d->m_syncData;
diff --git a/src/render/geometry/qbuffer.h b/src/render/geometry/qbuffer.h
index 1aa4bcc06..09fe54e10 100644
--- a/src/render/geometry/qbuffer.h
+++ b/src/render/geometry/qbuffer.h
@@ -95,11 +95,12 @@ public:
};
Q_ENUM(AccessType) // LCOV_EXCL_LINE
- explicit QBuffer(BufferType ty = QBuffer::VertexBuffer, Qt3DCore::QNode *parent = nullptr);
+ explicit QBuffer(Qt3DCore::QNode *parent = nullptr);
+ QT_DEPRECATED explicit QBuffer(BufferType ty, Qt3DCore::QNode *parent = nullptr);
~QBuffer();
UsageType usage() const;
- BufferType type() const;
+ QT_DEPRECATED BufferType type() const;
bool isSyncData() const;
AccessType accessType() const;
@@ -112,7 +113,7 @@ public:
Q_INVOKABLE void updateData(int offset, const QByteArray &bytes);
public Q_SLOTS:
- void setType(BufferType type);
+ QT_DEPRECATED void setType(BufferType type);
void setUsage(UsageType usage);
void setSyncData(bool syncData);
void setAccessType(AccessType access);
diff --git a/src/render/geometry/qbuffer_p.h b/src/render/geometry/qbuffer_p.h
index a722675ab..a342518e0 100644
--- a/src/render/geometry/qbuffer_p.h
+++ b/src/render/geometry/qbuffer_p.h
@@ -80,7 +80,6 @@ public:
struct QBufferData
{
QByteArray data;
- QBuffer::BufferType type;
QBuffer::UsageType usage;
QBufferDataGeneratorPtr functor;
bool syncData;
diff --git a/src/render/geometry/skeleton.cpp b/src/render/geometry/skeleton.cpp
index 485069e2a..075936f37 100644
--- a/src/render/geometry/skeleton.cpp
+++ b/src/render/geometry/skeleton.cpp
@@ -118,7 +118,12 @@ void Skeleton::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
switch (e->type()) {
case Qt3DCore::PropertyUpdated: {
const auto change = qSharedPointerCast<QPropertyUpdatedChange>(e);
- if (change->propertyName() == QByteArrayLiteral("source")) {
+ if (change->propertyName() == QByteArrayLiteral("localPoses")) {
+ // When the animation aspect sends us a new set of local poses, all we
+ // need to do is copy them into place. The existing jobs will then update
+ // the skinning matrix palette.
+ m_skeletonData.localPoses = change->value().value<QVector<Qt3DCore::Sqt>>();
+ } else if (change->propertyName() == QByteArrayLiteral("source")) {
Q_ASSERT(m_dataType == File);
const auto source = change->value().toUrl();
if (source != m_source) {
diff --git a/src/render/graphicshelpers/graphicscontext.cpp b/src/render/graphicshelpers/graphicscontext.cpp
index 11132c5ed..814429504 100644
--- a/src/render/graphicshelpers/graphicscontext.cpp
+++ b/src/render/graphicshelpers/graphicscontext.cpp
@@ -120,22 +120,14 @@ static void logOpenGLDebugMessage(const QOpenGLDebugMessage &debugMessage)
namespace {
-GLBuffer::Type bufferTypeToGLBufferType(QBuffer::BufferType type)
+GLBuffer::Type attributeTypeToGLBufferType(QAttribute::AttributeType type)
{
switch (type) {
- case QBuffer::VertexBuffer:
+ case QAttribute::VertexAttribute:
return GLBuffer::ArrayBuffer;
- case QBuffer::IndexBuffer:
+ case QAttribute::IndexAttribute:
return GLBuffer::IndexBuffer;
- case QBuffer::PixelPackBuffer:
- return GLBuffer::PixelPackBuffer;
- case QBuffer::PixelUnpackBuffer:
- return GLBuffer::PixelUnpackBuffer;
- case QBuffer::UniformBuffer:
- return GLBuffer::UniformBuffer;
- case QBuffer::ShaderStorageBuffer:
- return GLBuffer::ShaderStorageBuffer;
- case QBuffer::DrawIndirectBuffer:
+ case QAttribute::DrawIndirectAttribute:
return GLBuffer::DrawIndirectBuffer;
default:
Q_UNREACHABLE();
@@ -1220,7 +1212,7 @@ void GraphicsContext::setParameters(ShaderParameterPack &parameterPack)
int ssboIndex = 0;
for (const BlockToSSBO b : blockToSSBOs) {
Buffer *cpuBuffer = m_renderer->nodeManagers()->bufferManager()->lookupResource(b.m_bufferID);
- GLBuffer *ssbo = glBufferForRenderBuffer(cpuBuffer);
+ GLBuffer *ssbo = glBufferForRenderBuffer(cpuBuffer, GLBuffer::ShaderStorageBuffer);
bindShaderStorageBlock(shader->programId(), b.m_blockIndex, ssboIndex);
// Needed to avoid conflict where the buffer would already
// be bound as a VertexArray
@@ -1240,7 +1232,7 @@ void GraphicsContext::setParameters(ShaderParameterPack &parameterPack)
int uboIndex = 0;
for (const BlockToUBO &b : blockToUBOs) {
Buffer *cpuBuffer = m_renderer->nodeManagers()->bufferManager()->lookupResource(b.m_bufferID);
- GLBuffer *ubo = glBufferForRenderBuffer(cpuBuffer);
+ GLBuffer *ubo = glBufferForRenderBuffer(cpuBuffer, GLBuffer::UniformBuffer);
bindUniformBlock(shader->programId(), b.m_blockIndex, uboIndex);
// Needed to avoid conflict where the buffer would already
// be bound as a VertexArray
@@ -1287,7 +1279,7 @@ void GraphicsContext::enableAttribute(const VAOVertexAttribute &attr)
// Bind buffer within the current VAO
GLBuffer *buf = m_renderer->nodeManagers()->glBufferManager()->data(attr.bufferHandle);
Q_ASSERT(buf);
- bindGLBuffer(buf, attr.bufferType);
+ bindGLBuffer(buf, attr.attributeType);
// Don't use QOpenGLShaderProgram::setAttributeBuffer() because of QTBUG-43199.
// Use the introspection data and set the attribute explicitly
@@ -1437,7 +1429,7 @@ void GraphicsContext::specifyAttribute(const Attribute *attribute,
const GLint attributeDataType = glDataTypeFromAttributeDataType(attribute->vertexBaseType());
const HGLBuffer glBufferHandle = m_renderer->nodeManagers()->glBufferManager()->lookupHandle(buffer->peerId());
Q_ASSERT(!glBufferHandle.isNull());
- const GLBuffer::Type bufferType = bufferTypeToGLBufferType(buffer->type());
+ const GLBuffer::Type attributeType = attributeTypeToGLBufferType(attribute->attributeType());
int typeSize = 0;
int attrCount = 0;
@@ -1457,7 +1449,7 @@ void GraphicsContext::specifyAttribute(const Attribute *attribute,
for (int i = 0; i < attrCount; i++) {
VAOVertexAttribute attr;
attr.bufferHandle = glBufferHandle;
- attr.bufferType = bufferType;
+ attr.attributeType = attributeType;
attr.location = location + i;
attr.dataType = attributeDataType;
attr.byteOffset = attribute->byteOffset() + (i * attrCount * typeSize);
@@ -1476,9 +1468,7 @@ void GraphicsContext::specifyAttribute(const Attribute *attribute,
void GraphicsContext::specifyIndices(Buffer *buffer)
{
- Q_ASSERT(buffer->type() == QBuffer::IndexBuffer);
-
- GLBuffer *buf = glBufferForRenderBuffer(buffer);
+ GLBuffer *buf = glBufferForRenderBuffer(buffer, GLBuffer::IndexBuffer);
if (!bindGLBuffer(buf, GLBuffer::IndexBuffer))
qCWarning(Backend) << Q_FUNC_INFO << "binding index buffer failed";
@@ -1585,14 +1575,14 @@ void GraphicsContext::memoryBarrier(QMemoryBarrier::Operations barriers)
m_glHelper->memoryBarrier(barriers);
}
-GLBuffer *GraphicsContext::glBufferForRenderBuffer(Buffer *buf)
+GLBuffer *GraphicsContext::glBufferForRenderBuffer(Buffer *buf, GLBuffer::Type type)
{
if (!m_renderBufferHash.contains(buf->peerId()))
- m_renderBufferHash.insert(buf->peerId(), createGLBufferFor(buf));
+ m_renderBufferHash.insert(buf->peerId(), createGLBufferFor(buf, type));
return m_renderer->nodeManagers()->glBufferManager()->data(m_renderBufferHash.value(buf->peerId()));
}
-HGLBuffer GraphicsContext::createGLBufferFor(Buffer *buffer)
+HGLBuffer GraphicsContext::createGLBufferFor(Buffer *buffer, GLBuffer::Type type)
{
GLBuffer *b = m_renderer->nodeManagers()->glBufferManager()->getOrCreateResource(buffer->peerId());
// b.setUsagePattern(static_cast<QOpenGLBuffer::UsagePattern>(buffer->usage()));
@@ -1600,7 +1590,7 @@ HGLBuffer GraphicsContext::createGLBufferFor(Buffer *buffer)
if (!b->create(this))
qCWarning(Render::Io) << Q_FUNC_INFO << "buffer creation failed";
- if (!bindGLBuffer(b, bufferTypeToGLBufferType(buffer->type())))
+ if (!bindGLBuffer(b, type))
qCWarning(Render::Io) << Q_FUNC_INFO << "buffer binding failed";
return m_renderer->nodeManagers()->glBufferManager()->lookupHandle(buffer->peerId());
@@ -1621,7 +1611,7 @@ bool GraphicsContext::bindGLBuffer(GLBuffer *buffer, GLBuffer::Type type)
void GraphicsContext::uploadDataToGLBuffer(Buffer *buffer, GLBuffer *b, bool releaseBuffer)
{
- if (!bindGLBuffer(b, bufferTypeToGLBufferType(buffer->type())))
+ if (!bindGLBuffer(b, GLBuffer::ArrayBuffer)) // We're uploading, the type doesn't matter here
qCWarning(Render::Io) << Q_FUNC_INFO << "buffer bind failed";
// If the buffer is dirty (hence being called here)
// there are two possible cases
@@ -1663,15 +1653,14 @@ void GraphicsContext::uploadDataToGLBuffer(Buffer *buffer, GLBuffer *b, bool rel
if (releaseBuffer) {
b->release(this);
- if (bufferTypeToGLBufferType(buffer->type()) == GLBuffer::ArrayBuffer)
- m_boundArrayBuffer = nullptr;
+ m_boundArrayBuffer = nullptr;
}
qCDebug(Render::Io) << "uploaded buffer size=" << buffer->data().size();
}
QByteArray GraphicsContext::downloadDataFromGLBuffer(Buffer *buffer, GLBuffer *b)
{
- if (!bindGLBuffer(b, bufferTypeToGLBufferType(buffer->type())))
+ if (!bindGLBuffer(b, GLBuffer::ArrayBuffer)) // We're downloading, the type doesn't matter here
qCWarning(Render::Io) << Q_FUNC_INFO << "buffer bind failed";
QByteArray data = b->download(this, buffer->data().size());
diff --git a/src/render/graphicshelpers/graphicscontext_p.h b/src/render/graphicshelpers/graphicscontext_p.h
index 21ec90c58..1b9438a6f 100644
--- a/src/render/graphicshelpers/graphicscontext_p.h
+++ b/src/render/graphicshelpers/graphicscontext_p.h
@@ -188,7 +188,7 @@ public:
* @param buf
* @return
*/
- GLBuffer *glBufferForRenderBuffer(Buffer *buf);
+ GLBuffer *glBufferForRenderBuffer(Buffer *buf, GLBuffer::Type type);
/**
* @brief activateTexture - make a texture active on a hardware unit
@@ -270,7 +270,7 @@ private:
void bindFrameBufferAttachmentHelper(GLuint fboId, const AttachmentPack &attachments);
void activateDrawBuffers(const AttachmentPack &attachments);
- HGLBuffer createGLBufferFor(Buffer *buffer);
+ HGLBuffer createGLBufferFor(Buffer *buffer, GLBuffer::Type type);
void uploadDataToGLBuffer(Buffer *buffer, GLBuffer *b, bool releaseBuffer = false);
QByteArray downloadDataFromGLBuffer(Buffer *buffer, GLBuffer *b);
bool bindGLBuffer(GLBuffer *buffer, GLBuffer::Type type);
@@ -331,7 +331,7 @@ private:
struct VAOVertexAttribute
{
HGLBuffer bufferHandle;
- GLBuffer::Type bufferType;
+ GLBuffer::Type attributeType;
int location;
GLint dataType;
uint byteOffset;
diff --git a/src/render/materialsystem/prototypes/default.json b/src/render/materialsystem/prototypes/default.json
index 429c435f4..9f16b0f53 100644
--- a/src/render/materialsystem/prototypes/default.json
+++ b/src/render/materialsystem/prototypes/default.json
@@ -107,7 +107,7 @@
"major": 2,
"minor": 0
},
- "substitution": "gl_fragColor = $fragColor;"
+ "substitution": "gl_FragColor = $fragColor;"
},
{
"format": {
@@ -377,6 +377,15 @@
"rules": [
{
"format": {
+ "api": "OpenGLES",
+ "major": 2,
+ "minor": 0
+ },
+ "substitution": "highp mat3 $matrix = calcWorldSpaceToTangentSpaceMatrix($worldNormal, $worldTangent);",
+ "headerSnippets": [ "#pragma include :/shaders/es2/coordinatesystems.inc" ]
+ },
+ {
+ "format": {
"api": "OpenGLCoreProfile",
"major": 3,
"minor": 0
@@ -386,6 +395,40 @@
}
]
},
+ "phongFunction": {
+ "inputs": [
+ "ambient",
+ "diffuse",
+ "specular",
+ "shininess",
+ "worldPosition",
+ "worldView",
+ "worldNormal"
+ ],
+ "outputs": [
+ "outputColor"
+ ],
+ "rules": [
+ {
+ "format": {
+ "api": "OpenGLES",
+ "major": 2,
+ "minor": 0
+ },
+ "substitution": "highp vec4 $outputColor = phongFunction($ambient, $diffuse, $specular, $shininess, $worldPosition, $worldView, $worldNormal);",
+ "headerSnippets": [ "#pragma include :/shaders/es2/phong.inc.frag" ]
+ },
+ {
+ "format": {
+ "api": "OpenGLCoreProfile",
+ "major": 3,
+ "minor": 0
+ },
+ "substitution": "vec4 $outputColor = phongFunction($ambient, $diffuse, $specular, $shininess, $worldPosition, $worldView, $worldNormal);",
+ "headerSnippets": [ "#pragma include :/shaders/gl3/phong.inc.frag" ]
+ }
+ ]
+ },
"metalRoughFunction": {
"inputs": [
"baseColor",
diff --git a/src/render/texture/gltexture.cpp b/src/render/texture/gltexture.cpp
index 2a35a6f7e..11cc1544f 100644
--- a/src/render/texture/gltexture.cpp
+++ b/src/render/texture/gltexture.cpp
@@ -208,6 +208,7 @@ QOpenGLTexture* GLTexture::getOrCreateGLTexture()
// need to (re-)upload texture data?
if (needUpload && !texturedDataInvalid) {
uploadGLTextureData();
+ setDirtyFlag(TextureData, false);
}
// need to set texture parameters?
diff --git a/tests/auto/animation/animation.pro b/tests/auto/animation/animation.pro
index eff1a4779..c97b07923 100644
--- a/tests/auto/animation/animation.pro
+++ b/tests/auto/animation/animation.pro
@@ -38,5 +38,6 @@ qtConfig(private_tests) {
animationutils \
qabstractanimation \
clock \
- skeleton
+ skeleton \
+ findrunningclipanimatorsjob
}
diff --git a/tests/auto/animation/animationutils/tst_animationutils.cpp b/tests/auto/animation/animationutils/tst_animationutils.cpp
index c75ae8e6a..1e55a29b5 100644
--- a/tests/auto/animation/animationutils/tst_animationutils.cpp
+++ b/tests/auto/animation/animationutils/tst_animationutils.cpp
@@ -149,6 +149,7 @@ public:
auto channelMappingId = Qt3DCore::QNodeId::createId();
ChannelMapping *channelMapping = handler->channelMappingManager()->getOrCreateResource(channelMappingId);
setPeerId(channelMapping, channelMappingId);
+ channelMapping->setHandler(handler);
channelMapping->setTargetId(targetId);
channelMapping->setProperty(property);
channelMapping->setPropertyName(propertyName);
@@ -164,6 +165,7 @@ public:
auto channelMappingId = Qt3DCore::QNodeId::createId();
ChannelMapping *channelMapping = handler->channelMappingManager()->getOrCreateResource(channelMappingId);
setPeerId(channelMapping, channelMappingId);
+ channelMapping->setHandler(handler);
channelMapping->setSkeletonId(skeletonId);
channelMapping->setMappingType(ChannelMapping::SkeletonMappingType);
return channelMapping;
@@ -273,88 +275,20 @@ private Q_SLOTS:
{
QTest::addColumn<Handler *>("handler");
QTest::addColumn<QVector<ChannelMapping *>>("channelMappings");
- QTest::addColumn<ChannelMapper *>("channelMapper");
- QTest::addColumn<AnimationClip *>("clip");
- QTest::addColumn<QVector<MappingData>>("expectedMappingData");
-
- auto handler = new Handler;
- auto channelMapping = createChannelMapping(handler,
- QLatin1String("Location"),
- Qt3DCore::QNodeId::createId(),
- QLatin1String("translation"),
- "translation",
- static_cast<int>(QVariant::Vector3D));
- QVector<ChannelMapping *> channelMappings;
- channelMappings.push_back(channelMapping);
-
- // ... a channel mapper...
- auto channelMapper = createChannelMapper(handler, QVector<Qt3DCore::QNodeId>() << channelMapping->peerId());
-
- // ...and an animation clip
- auto clip = createAnimationClipLoader(handler, QUrl("qrc:/clip1.json"));
-
- QVector<MappingData> mappingData;
- MappingData mapping;
- mapping.targetId = channelMapping->targetId();
- mapping.propertyName = channelMapping->propertyName(); // Location
- mapping.type = channelMapping->type();
- mapping.channelIndices = QVector<int>() << 0 << 1 << 2; // Location X, Y, Z
- mappingData.push_back(mapping);
-
- QTest::newRow("clip1.json") << handler
- << channelMappings
- << channelMapper
- << clip
- << mappingData;
- }
-
- void checkBuildPropertyMappings()
- {
- // GIVEN
- QFETCH(Handler *, handler);
- QFETCH(QVector<ChannelMapping *>, channelMappings);
- QFETCH(ChannelMapper *, channelMapper);
- QFETCH(AnimationClip *, clip);
- QFETCH(QVector<MappingData>, expectedMappingData);
-
- // WHEN
- // Build the mapping data for the above configuration
- QVector<MappingData> mappingData = buildPropertyMappings(handler, clip, channelMapper);
-
- // THEN
- QCOMPARE(mappingData.size(), expectedMappingData.size());
- for (int i = 0; i < mappingData.size(); ++i) {
- const auto mapping = mappingData[i];
- const auto expectedMapping = expectedMappingData[i];
-
- QCOMPARE(mapping.targetId, expectedMapping.targetId);
- QCOMPARE(mapping.propertyName, expectedMapping.propertyName);
- QCOMPARE(mapping.type, expectedMapping.type);
- QCOMPARE(mapping.channelIndices.size(), expectedMapping.channelIndices.size());
- for (int j = 0; j < mapping.channelIndices.size(); ++j) {
- QCOMPARE(mapping.channelIndices[j], expectedMapping.channelIndices[j]);
- }
- }
-
- // Cleanup
- delete handler;
- }
-
- void checkBuildPropertyMappings2_data()
- {
- QTest::addColumn<QVector<ChannelMapping *>>("channelMappings");
QTest::addColumn<QVector<ChannelNameAndType>>("channelNamesAndTypes");
QTest::addColumn<QVector<ComponentIndices>>("channelComponentIndices");
QTest::addColumn<QVector<MappingData>>("expectedResults");
// Single ChannelMapping
{
- auto channelMapping = new ChannelMapping();
- channelMapping->setChannelName("Location");
- channelMapping->setTargetId(Qt3DCore::QNodeId::createId());
- channelMapping->setProperty(QLatin1String("translation"));
- channelMapping->setPropertyName("translation");
- channelMapping->setType(static_cast<int>(QVariant::Vector3D));
+ Handler *handler = new Handler();
+
+ auto channelMapping = createChannelMapping(handler,
+ QLatin1String("Location"),
+ Qt3DCore::QNodeId::createId(),
+ QLatin1String("translation"),
+ "translation",
+ static_cast<int>(QVariant::Vector3D));
QVector<ChannelMapping *> channelMappings = { channelMapping };
@@ -390,6 +324,7 @@ private Q_SLOTS:
QVector<MappingData> expectedResults = { expectedMapping };
QTest::newRow("single mapping")
+ << handler
<< channelMappings
<< channelNamesAndTypes
<< channelComponentIndices
@@ -398,40 +333,42 @@ private Q_SLOTS:
// Multiple ChannelMappings
{
- auto locationMapping = new ChannelMapping();
- locationMapping->setChannelName("Location");
- locationMapping->setTargetId(Qt3DCore::QNodeId::createId());
- locationMapping->setProperty(QLatin1String("translation"));
- locationMapping->setPropertyName("translation");
- locationMapping->setType(static_cast<int>(QVariant::Vector3D));
-
- auto metalnessMapping = new ChannelMapping();
- metalnessMapping->setChannelName("Metalness");
- metalnessMapping->setTargetId(Qt3DCore::QNodeId::createId());
- metalnessMapping->setProperty(QLatin1String("metalness"));
- metalnessMapping->setPropertyName("metalness");
- metalnessMapping->setType(static_cast<int>(QVariant::Double));
-
- auto baseColorMapping = new ChannelMapping();
- baseColorMapping->setChannelName("BaseColor");
- baseColorMapping->setTargetId(Qt3DCore::QNodeId::createId());
- baseColorMapping->setProperty(QLatin1String("baseColor"));
- baseColorMapping->setPropertyName("baseColor");
- baseColorMapping->setType(static_cast<int>(QVariant::Vector3D));
-
- auto roughnessMapping = new ChannelMapping();
- roughnessMapping->setChannelName("Roughness");
- roughnessMapping->setTargetId(Qt3DCore::QNodeId::createId());
- roughnessMapping->setProperty(QLatin1String("roughness"));
- roughnessMapping->setPropertyName("roughness");
- roughnessMapping->setType(static_cast<int>(QVariant::Double));
-
- auto rotationMapping = new ChannelMapping();
- rotationMapping->setChannelName("Rotation");
- rotationMapping->setTargetId(Qt3DCore::QNodeId::createId());
- rotationMapping->setProperty(QLatin1String("rotation"));
- rotationMapping->setPropertyName("rotation");
- rotationMapping->setType(static_cast<int>(QVariant::Quaternion));
+ Handler *handler = new Handler();
+
+ auto locationMapping = createChannelMapping(handler,
+ QLatin1String("Location"),
+ Qt3DCore::QNodeId::createId(),
+ QLatin1String("translation"),
+ "translation",
+ static_cast<int>(QVariant::Vector3D));
+
+ auto metalnessMapping = createChannelMapping(handler,
+ QLatin1String("Metalness"),
+ Qt3DCore::QNodeId::createId(),
+ QLatin1String("metalness"),
+ "metalness",
+ static_cast<int>(QVariant::Double));
+
+ auto baseColorMapping = createChannelMapping(handler,
+ QLatin1String("BaseColor"),
+ Qt3DCore::QNodeId::createId(),
+ QLatin1String("baseColor"),
+ "baseColor",
+ static_cast<int>(QVariant::Vector3D));
+
+ auto roughnessMapping = createChannelMapping(handler,
+ QLatin1String("Roughness"),
+ Qt3DCore::QNodeId::createId(),
+ QLatin1String("roughness"),
+ "roughness",
+ static_cast<int>(QVariant::Double));
+
+ auto rotationMapping = createChannelMapping(handler,
+ QLatin1String("Rotation"),
+ Qt3DCore::QNodeId::createId(),
+ QLatin1String("rotation"),
+ "rotation",
+ static_cast<int>(QVariant::Quaternion));
QVector<ChannelMapping *> channelMappings
= { locationMapping, metalnessMapping,
@@ -500,6 +437,77 @@ private Q_SLOTS:
expectedRotationMapping };
QTest::newRow("multiple mappings")
+ << handler
+ << channelMappings
+ << channelNamesAndTypes
+ << channelComponentIndices
+ << expectedResults;
+ }
+
+ // Single skeleton mapping
+ {
+ Handler *handler = new Handler();
+ const int jointCount = 4;
+ auto skeleton = createSkeleton(handler, jointCount);
+ auto channelMapping = createChannelMapping(handler, skeleton->peerId());
+
+ QVector<ChannelMapping *> channelMappings = { channelMapping };
+
+ // Create a few channels in the format description
+ QVector<ChannelNameAndType> channelNamesAndTypes;
+ for (int i = 0; i < jointCount; ++i) {
+ channelNamesAndTypes.push_back({ QLatin1String("Location"), static_cast<int>(QVariant::Vector3D), i });
+ channelNamesAndTypes.push_back({ QLatin1String("Rotation"), static_cast<int>(QVariant::Quaternion), i });
+ channelNamesAndTypes.push_back({ QLatin1String("Scale"), static_cast<int>(QVariant::Vector3D), i });
+ }
+
+ // And the matching indices
+ QVector<ComponentIndices> channelComponentIndices;
+ channelComponentIndices.push_back({ 0, 1, 2 });
+ channelComponentIndices.push_back({ 3, 4, 5, 6 });
+ channelComponentIndices.push_back({ 7, 8, 9 });
+
+ channelComponentIndices.push_back({ 10, 11, 12 });
+ channelComponentIndices.push_back({ 13, 14, 15, 16 });
+ channelComponentIndices.push_back({ 17, 18, 19 });
+
+ channelComponentIndices.push_back({ 20, 21, 22 });
+ channelComponentIndices.push_back({ 23, 24, 25, 26 });
+ channelComponentIndices.push_back({ 27, 28, 29 });
+
+ channelComponentIndices.push_back({ 30, 31, 32 });
+ channelComponentIndices.push_back({ 33, 34, 35, 36 });
+ channelComponentIndices.push_back({ 37, 38, 39 });
+
+ QVector<MappingData> expectedResults;
+ int componentIndicesIndex = 0;
+ for (int i = 0; i < jointCount; ++i) {
+ MappingData locationMapping;
+ locationMapping.targetId = channelMapping->skeletonId();
+ locationMapping.propertyName = "translation";
+ locationMapping.type = static_cast<int>(QVariant::Vector3D);
+ locationMapping.channelIndices = channelComponentIndices[componentIndicesIndex++];
+ locationMapping.jointIndex = i;
+
+ MappingData rotationMapping;
+ rotationMapping.targetId = channelMapping->skeletonId();
+ rotationMapping.propertyName = "rotation";
+ rotationMapping.type = static_cast<int>(QVariant::Quaternion);
+ rotationMapping.channelIndices = channelComponentIndices[componentIndicesIndex++];
+ rotationMapping.jointIndex = i;
+
+ MappingData scaleMapping;
+ scaleMapping.targetId = channelMapping->skeletonId();
+ scaleMapping.propertyName = "scale";
+ scaleMapping.type = static_cast<int>(QVariant::Vector3D);
+ scaleMapping.channelIndices = channelComponentIndices[componentIndicesIndex++];
+ scaleMapping.jointIndex = i;
+
+ expectedResults << locationMapping << rotationMapping << scaleMapping;
+ }
+
+ QTest::newRow("single skeleton mapping")
+ << handler
<< channelMappings
<< channelNamesAndTypes
<< channelComponentIndices
@@ -507,9 +515,10 @@ private Q_SLOTS:
}
}
- void checkBuildPropertyMappings2()
+ void checkBuildPropertyMappings()
{
// GIVEN
+ QFETCH(Handler *, handler);
QFETCH(QVector<ChannelMapping *>, channelMappings);
QFETCH(QVector<ChannelNameAndType>, channelNamesAndTypes);
QFETCH(QVector<ComponentIndices>, channelComponentIndices);
@@ -527,6 +536,7 @@ private Q_SLOTS:
const auto expectedMapping = expectedResults[i];
QCOMPARE(actualMapping.targetId, expectedMapping.targetId);
+ QCOMPARE(actualMapping.jointIndex, expectedMapping.jointIndex);
QCOMPARE(actualMapping.propertyName, expectedMapping.propertyName);
QCOMPARE(actualMapping.type, expectedMapping.type);
QCOMPARE(actualMapping.channelIndices.size(), expectedMapping.channelIndices.size());
@@ -534,6 +544,9 @@ private Q_SLOTS:
QCOMPARE(actualMapping.channelIndices[j], expectedMapping.channelIndices[j]);
}
}
+
+ // Cleanup
+ delete handler;
}
void checkLocalTimeFromGlobalTime_data()
@@ -2088,6 +2101,18 @@ private Q_SLOTS:
QTest::newRow("simple lerp") << handler << lerp->peerId() << expectedIds;
}
+
+ {
+ Handler *handler = new Handler;
+
+ const auto value1 = createClipBlendValue(handler);
+ const auto clip1Id = Qt3DCore::QNodeId::createId();
+ value1->setClipId(clip1Id);
+
+ QVector<Qt3DCore::QNodeId> expectedIds = { value1->peerId() };
+
+ QTest::newRow("value only") << handler << value1->peerId() << expectedIds;
+ }
}
void checkGatherValueNodesToEvaluate()
@@ -2694,8 +2719,8 @@ private Q_SLOTS:
clip->setSource(QUrl("qrc:/clip3.json"));
clip->loadAnimation();
- ComponentIndices expectedResults = { 0, 1, 2, 3, // Rotation
- 4, 5, 6, // Location
+ ComponentIndices expectedResults = { 0, 1, 3, 2, // Rotation (y/z swapped in clip3.json)
+ 4, 6, 5, // Location (y/z swapped in clip3.json)
7, 8, 9, // Base Color
10, // Metalness
11 }; // Roughness
@@ -2724,8 +2749,8 @@ private Q_SLOTS:
clip->setSource(QUrl("qrc:/clip3.json"));
clip->loadAnimation();
- ComponentIndices expectedResults = { 4, 5, 6, // Location
- 0, 1, 2, 3, // Rotation
+ ComponentIndices expectedResults = { 4, 6, 5, // Location (y/z swapped in clip3.json)
+ 0, 1, 3, 2, // Rotation (y/z swapped in clip3.json)
7, 8, 9, // Base Color
10, // Metalness
11 }; // Roughness
@@ -2754,8 +2779,8 @@ private Q_SLOTS:
clip->setSource(QUrl("qrc:/clip3.json"));
clip->loadAnimation();
- ComponentIndices expectedResults = { 0, 1, 2, 3, // Rotation
- 4, 5, 6, // Location
+ ComponentIndices expectedResults = { 0, 1, 3, 2, // Rotation (y/z swapped in clip3.json)
+ 4, 6, 5, // Location (y/z swapped in clip3.json)
-1, -1, -1, // Albedo (missing from clip)
10, // Metalness
11 }; // Roughness
@@ -2784,8 +2809,8 @@ private Q_SLOTS:
clip->setSource(QUrl("qrc:/clip3.json"));
clip->loadAnimation();
- ComponentIndices expectedResults = { 4, 5, 6, // Location
- 0, 1, 2, 3, // Rotation
+ ComponentIndices expectedResults = { 4, 6, 5, // Location (y/z swapped in clip3.json)
+ 0, 1, 3, 2, // Rotation (y/z swapped in clip3.json)
-1, -1, -1, // Albedo (missing from clip)
10, // Metalness
11 }; // Roughness
@@ -2825,17 +2850,17 @@ private Q_SLOTS:
clip->setSource(QUrl("qrc:/clip5.json"));
clip->loadAnimation();
- ComponentIndices expectedResults = { 4, 5, 6, // Location, joint 0
- 0, 1, 2, 3, // Rotation, joint 0
+ ComponentIndices expectedResults = { 4, 6, 5, // Location, joint 0 (y/z swapped in clip5.json)
+ 0, 1, 3, 2, // Rotation, joint 0 (y/z swapped in clip5.json)
7, 8, 9, // Scale, joint 0
- 14, 15, 16, // Location, joint 1
- 10, 11, 12, 13, // Rotation, joint 1
+ 14, 16, 15, // Location, joint 1 (y/z swapped in clip5.json)
+ 10, 11, 13, 12, // Rotation, joint 1 (y/z swapped in clip5.json)
17, 18, 19, // Scale, joint 1
- 24, 25, 26, // Location, joint 2
- 20, 21, 22, 23, // Rotation, joint 2
+ 24, 26, 25, // Location, joint 2 (y/z swapped in clip5.json)
+ 20, 21, 23, 22, // Rotation, joint 2 (y/z swapped in clip5.json)
27, 28, 29, // Scale, joint 2
- 34, 35, 36, // Location, joint 3
- 30, 31, 32, 33, // Rotation, joint 3
+ 34, 36, 35, // Location, joint 3 (y/z swapped in clip5.json)
+ 30, 31, 33, 32, // Rotation, joint 3 (y/z swapped in clip5.json)
37, 38, 39 }; // Scale, joint 3
QTest::newRow("skeleton (SQT), 4 joints")
diff --git a/tests/auto/animation/channelmapper/tst_channelmapper.cpp b/tests/auto/animation/channelmapper/tst_channelmapper.cpp
index 4dcb52aef..446e1a0c5 100644
--- a/tests/auto/animation/channelmapper/tst_channelmapper.cpp
+++ b/tests/auto/animation/channelmapper/tst_channelmapper.cpp
@@ -30,6 +30,8 @@
#include <qbackendnodetester.h>
#include <Qt3DAnimation/private/handler_p.h>
#include <Qt3DAnimation/private/channelmapper_p.h>
+#include <Qt3DAnimation/private/channelmapping_p.h>
+#include <Qt3DAnimation/private/managers_p.h>
#include <Qt3DAnimation/qchannelmapper.h>
#include <Qt3DAnimation/qchannelmapping.h>
#include <Qt3DAnimation/private/qchannelmapper_p.h>
@@ -116,13 +118,40 @@ private Q_SLOTS:
// WHEN
Qt3DAnimation::QChannelMapping mapping;
const Qt3DCore::QNodeId mappingId = mapping.id();
- const auto nodeAddedChange = Qt3DCore::QPropertyNodeAddedChangePtr::create(Qt3DCore::QNodeId(), &mapping);
+ Qt3DAnimation::Animation::ChannelMapping *backendMapping
+ = handler.channelMappingManager()->getOrCreateResource(mappingId);
+ backendMapping->setHandler(&handler);
+ simulateInitialization(&mapping, backendMapping);
+
+ auto nodeAddedChange = Qt3DCore::QPropertyNodeAddedChangePtr::create(Qt3DCore::QNodeId(), &mapping);
nodeAddedChange->setPropertyName("mappings");
backendMapper.sceneChangeEvent(nodeAddedChange);
// THEN
QCOMPARE(backendMapper.mappingIds().size(), 1);
QCOMPARE(backendMapper.mappingIds().first(), mappingId);
+ QCOMPARE(backendMapper.mappings().size(), 1);
+ QCOMPARE(backendMapper.mappings().first(), backendMapping);
+
+ // WHEN
+ Qt3DAnimation::QChannelMapping mapping2;
+ const Qt3DCore::QNodeId mappingId2 = mapping2.id();
+ Qt3DAnimation::Animation::ChannelMapping *backendMapping2
+ = handler.channelMappingManager()->getOrCreateResource(mappingId2);
+ backendMapping2->setHandler(&handler);
+ simulateInitialization(&mapping2, backendMapping2);
+
+ nodeAddedChange = Qt3DCore::QPropertyNodeAddedChangePtr::create(Qt3DCore::QNodeId(), &mapping2);
+ nodeAddedChange->setPropertyName("mappings");
+ backendMapper.sceneChangeEvent(nodeAddedChange);
+
+ // THEN
+ QCOMPARE(backendMapper.mappingIds().size(), 2);
+ QCOMPARE(backendMapper.mappingIds().first(), mappingId);
+ QCOMPARE(backendMapper.mappingIds().last(), mappingId2);
+ QCOMPARE(backendMapper.mappings().size(), 2);
+ QCOMPARE(backendMapper.mappings().first(), backendMapping);
+ QCOMPARE(backendMapper.mappings().last(), backendMapping2);
// WHEN
const auto nodeRemovedChange = Qt3DCore::QPropertyNodeRemovedChangePtr::create(Qt3DCore::QNodeId(), &mapping);
@@ -130,7 +159,10 @@ private Q_SLOTS:
backendMapper.sceneChangeEvent(nodeRemovedChange);
// THEN
- QCOMPARE(backendMapper.mappingIds().size(), 0);
+ QCOMPARE(backendMapper.mappingIds().size(), 1);
+ QCOMPARE(backendMapper.mappingIds().first(), mappingId2);
+ QCOMPARE(backendMapper.mappings().size(), 1);
+ QCOMPARE(backendMapper.mappings().first(), backendMapping2);
}
};
diff --git a/tests/auto/animation/clipblendvalue/tst_clipblendvalue.cpp b/tests/auto/animation/clipblendvalue/tst_clipblendvalue.cpp
index 6fe2846b8..fcbc167ca 100644
--- a/tests/auto/animation/clipblendvalue/tst_clipblendvalue.cpp
+++ b/tests/auto/animation/clipblendvalue/tst_clipblendvalue.cpp
@@ -137,8 +137,7 @@ private Q_SLOTS:
QVector<Qt3DCore::QNodeId> actualIds = clipNode.currentDependencyIds();
// THEN
- QCOMPARE(actualIds.size(), 1);
- QCOMPARE(actualIds[0], clipId);
+ QCOMPARE(actualIds.size(), 0);
// WHEN
auto anotherClipId = Qt3DCore::QNodeId::createId();
@@ -146,8 +145,7 @@ private Q_SLOTS:
actualIds = clipNode.currentDependencyIds();
// THEN
- QCOMPARE(actualIds.size(), 1);
- QCOMPARE(actualIds[0], anotherClipId);
+ QCOMPARE(actualIds.size(), 0);
}
void checkDuration()
diff --git a/tests/auto/animation/findrunningclipanimatorsjob/clip1.json b/tests/auto/animation/findrunningclipanimatorsjob/clip1.json
new file mode 100644
index 000000000..a2ad365a8
--- /dev/null
+++ b/tests/auto/animation/findrunningclipanimatorsjob/clip1.json
@@ -0,0 +1,114 @@
+{
+ "animations": [
+ {
+ "animationName": "CubeAction",
+ "channels": [
+ {
+ "channelComponents": [
+ {
+ "channelComponentName": "Location X",
+ "keyFrames": [
+ {
+ "coords": [
+ 0.0,
+ 0.0
+ ],
+ "leftHandle": [
+ -0.9597616195678711,
+ 0.0
+ ],
+ "rightHandle": [
+ 0.9597616195678711,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 2.4583333333333335,
+ 5.0
+ ],
+ "leftHandle": [
+ 1.4985717137654622,
+ 5.0
+ ],
+ "rightHandle": [
+ 3.4180949529012046,
+ 5.0
+ ]
+ }
+ ]
+ },
+ {
+ "channelComponentName": "Location Y",
+ "keyFrames": [
+ {
+ "coords": [
+ 0.0,
+ 0.0
+ ],
+ "leftHandle": [
+ -0.9597616195678711,
+ 0.0
+ ],
+ "rightHandle": [
+ 0.9597616195678711,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 2.4583333333333335,
+ 0.0
+ ],
+ "leftHandle": [
+ 1.4985717137654622,
+ 0.0
+ ],
+ "rightHandle": [
+ 3.4180949529012046,
+ 0.0
+ ]
+ }
+ ]
+ },
+ {
+ "channelComponentName": "Location Z",
+ "keyFrames": [
+ {
+ "coords": [
+ 0.0,
+ 0.0
+ ],
+ "leftHandle": [
+ -0.9597616195678711,
+ 0.0
+ ],
+ "rightHandle": [
+ 0.9597616195678711,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 2.4583333333333335,
+ 0.0
+ ],
+ "leftHandle": [
+ 1.4985717137654622,
+ 0.0
+ ],
+ "rightHandle": [
+ 3.4180949529012046,
+ 0.0
+ ]
+ }
+ ]
+ }
+ ],
+ "channelName": "Location"
+ }
+ ]
+ }
+ ]
+}
+
diff --git a/tests/auto/animation/findrunningclipanimatorsjob/findrunningclipanimatorsjob.pro b/tests/auto/animation/findrunningclipanimatorsjob/findrunningclipanimatorsjob.pro
new file mode 100644
index 000000000..f81b95dcd
--- /dev/null
+++ b/tests/auto/animation/findrunningclipanimatorsjob/findrunningclipanimatorsjob.pro
@@ -0,0 +1,15 @@
+TEMPLATE = app
+
+TARGET = tst_findrunningclipanimatorsjob
+
+QT += core-private 3dcore 3dcore-private 3danimation 3danimation-private testlib
+
+CONFIG += testcase
+
+SOURCES += \
+ tst_findrunningclipanimatorsjob.cpp
+
+include(../../core/common/common.pri)
+
+RESOURCES += \
+ findrunningclipanimatorsjob.qrc
diff --git a/tests/auto/animation/findrunningclipanimatorsjob/findrunningclipanimatorsjob.qrc b/tests/auto/animation/findrunningclipanimatorsjob/findrunningclipanimatorsjob.qrc
new file mode 100644
index 000000000..72234ec64
--- /dev/null
+++ b/tests/auto/animation/findrunningclipanimatorsjob/findrunningclipanimatorsjob.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/">
+ <file>clip1.json</file>
+ </qresource>
+</RCC>
diff --git a/tests/auto/animation/findrunningclipanimatorsjob/tst_findrunningclipanimatorsjob.cpp b/tests/auto/animation/findrunningclipanimatorsjob/tst_findrunningclipanimatorsjob.cpp
new file mode 100644
index 000000000..79d18b7cf
--- /dev/null
+++ b/tests/auto/animation/findrunningclipanimatorsjob/tst_findrunningclipanimatorsjob.cpp
@@ -0,0 +1,204 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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$
+**
+****************************************************************************/
+
+#include <QtTest/QTest>
+#include <Qt3DAnimation/qanimationcliploader.h>
+#include <Qt3DAnimation/qclipanimator.h>
+#include <Qt3DAnimation/qchannelmapper.h>
+#include <Qt3DAnimation/qchannelmapping.h>
+#include <Qt3DAnimation/private/clipanimator_p.h>
+#include <Qt3DAnimation/private/channelmapper_p.h>
+#include <Qt3DAnimation/private/channelmapping_p.h>
+#include <Qt3DAnimation/private/findrunningclipanimatorsjob_p.h>
+#include <Qt3DAnimation/private/handler_p.h>
+#include <Qt3DAnimation/private/managers_p.h>
+#include <Qt3DCore/private/qnode_p.h>
+#include <Qt3DCore/private/qscene_p.h>
+#include <Qt3DCore/qpropertyupdatedchange.h>
+#include <Qt3DCore/private/qbackendnode_p.h>
+#include <qbackendnodetester.h>
+#include <testpostmanarbiter.h>
+
+using namespace Qt3DAnimation::Animation;
+
+Q_DECLARE_METATYPE(Qt3DAnimation::Animation::Handler*)
+Q_DECLARE_METATYPE(QVector<Qt3DAnimation::Animation::HClipAnimator>)
+
+typedef QHash<ClipAnimator*, QVector<Qt3DAnimation::Animation::MappingData>> MappingDataResults;
+Q_DECLARE_METATYPE(MappingDataResults)
+
+class tst_FindRunningClipAnimatorsJob: public Qt3DCore::QBackendNodeTester
+{
+ Q_OBJECT
+public:
+ ChannelMapping *createChannelMapping(Handler *handler,
+ const QString &channelName,
+ const Qt3DCore::QNodeId targetId,
+ const QString &property,
+ const char *propertyName,
+ int type)
+ {
+ auto channelMappingId = Qt3DCore::QNodeId::createId();
+ ChannelMapping *channelMapping = handler->channelMappingManager()->getOrCreateResource(channelMappingId);
+ setPeerId(channelMapping, channelMappingId);
+ channelMapping->setHandler(handler);
+ channelMapping->setTargetId(targetId);
+ channelMapping->setProperty(property);
+ channelMapping->setPropertyName(propertyName);
+ channelMapping->setChannelName(channelName);
+ channelMapping->setType(type);
+ return channelMapping;
+ }
+
+ ChannelMapper *createChannelMapper(Handler *handler,
+ const QVector<Qt3DCore::QNodeId> &mappingIds)
+ {
+ auto channelMapperId = Qt3DCore::QNodeId::createId();
+ ChannelMapper *channelMapper = handler->channelMapperManager()->getOrCreateResource(channelMapperId);
+ setPeerId(channelMapper, channelMapperId);
+ channelMapper->setHandler(handler);
+ channelMapper->setMappingIds(mappingIds);
+ return channelMapper;
+ }
+
+ AnimationClip *createAnimationClipLoader(Handler *handler,
+ const QUrl &source)
+ {
+ auto clipId = Qt3DCore::QNodeId::createId();
+ AnimationClip *clip = handler->animationClipLoaderManager()->getOrCreateResource(clipId);
+ setPeerId(clip, clipId);
+ clip->setHandler(handler);
+ clip->setDataType(AnimationClip::File);
+ clip->setSource(source);
+ clip->loadAnimation();
+ return clip;
+ }
+
+ ClipAnimator *createClipAnimator(Handler *handler,
+ qint64 globalStartTimeNS,
+ int loops)
+ {
+ auto animatorId = Qt3DCore::QNodeId::createId();
+ ClipAnimator *animator = handler->clipAnimatorManager()->getOrCreateResource(animatorId);
+ setPeerId(animator, animatorId);
+ animator->setHandler(handler);
+ animator->setStartTime(globalStartTimeNS);
+ animator->setLoops(loops);
+ return animator;
+ }
+
+private Q_SLOTS:
+ void checkJob_data()
+ {
+ QTest::addColumn<Handler *>("handler");
+ QTest::addColumn<QVector<HClipAnimator>>("dirtyClipAnimators");
+ QTest::addColumn<MappingDataResults>("expectedResults");
+
+ Handler *handler;
+ AnimationClip *clip;
+ ClipAnimator *animator;
+ QVector<HClipAnimator> dirtyClipAnimators;
+ ChannelMapper *channelMapper;
+ MappingDataResults expectedResults;
+
+ {
+ handler = new Handler();
+ clip = createAnimationClipLoader(handler, QUrl("qrc:/clip1.json"));
+
+ const qint64 globalStartTimeNS = 0;
+ const int loops = 1;
+ animator = createClipAnimator(handler, globalStartTimeNS, loops);
+ animator->setClipId(clip->peerId());
+ dirtyClipAnimators = (QVector<HClipAnimator>()
+ << handler->clipAnimatorManager()->getOrAcquireHandle(animator->peerId()));
+
+ auto channelMapping = createChannelMapping(handler,
+ QLatin1String("Location"),
+ Qt3DCore::QNodeId::createId(),
+ QLatin1String("translation"),
+ "translation",
+ static_cast<int>(QVariant::Vector3D));
+ QVector<ChannelMapping *> channelMappings;
+ channelMappings.push_back(channelMapping);
+
+ channelMapper = createChannelMapper(handler, QVector<Qt3DCore::QNodeId>() << channelMapping->peerId());
+ animator->setMapperId(channelMapper->peerId());
+ animator->setRunning(true); // Has to be marked as running for the job to process it
+
+ const ComponentIndices locationIndices = { 0, 1, 2 };
+ MappingData expectedMapping;
+ expectedMapping.targetId = channelMapping->targetId();
+ expectedMapping.propertyName = channelMapping->propertyName();
+ expectedMapping.type = channelMapping->type();
+ expectedMapping.channelIndices = locationIndices;
+ expectedResults.insert(animator, QVector<MappingData>() << expectedMapping);
+
+ QTest::newRow("single mapping")
+ << handler
+ << dirtyClipAnimators
+ << expectedResults;
+ }
+ }
+
+ void checkJob()
+ {
+ // GIVEN
+ QFETCH(Handler *, handler);
+ QFETCH(QVector<HClipAnimator>, dirtyClipAnimators);
+ QFETCH(MappingDataResults, expectedResults);
+ FindRunningClipAnimatorsJob job;
+
+ // WHEN
+ job.setHandler(handler);
+ job.setDirtyClipAnimators(dirtyClipAnimators);
+ job.run();
+
+ // THEN - check the resulting MappingData on the animator matches the expected results
+ for (const auto &dirtyClipAnimator : dirtyClipAnimators) {
+ const auto animator = handler->clipAnimatorManager()->data(dirtyClipAnimator);
+ const QVector<MappingData> actualMappingData = animator->mappingData();
+ const QVector<MappingData> expectedMappingData = expectedResults[animator];
+
+ QCOMPARE(expectedMappingData.size(), actualMappingData.size());
+ for (int i = 0; i < actualMappingData.size(); ++i) {
+ QCOMPARE(expectedMappingData[i].targetId, actualMappingData[i].targetId);
+ QCOMPARE(expectedMappingData[i].type, actualMappingData[i].type);
+ QVERIFY(qstrcmp(expectedMappingData[i].propertyName, actualMappingData[i].propertyName) == 0);
+ QCOMPARE(expectedMappingData[i].channelIndices.size(), actualMappingData[i].channelIndices.size());
+
+ for (int j = 0; j < actualMappingData[i].channelIndices.size(); ++j) {
+ QCOMPARE(expectedMappingData[i].channelIndices[j], actualMappingData[i].channelIndices[j]);
+ }
+ }
+ }
+ }
+};
+
+QTEST_APPLESS_MAIN(tst_FindRunningClipAnimatorsJob)
+
+#include "tst_findrunningclipanimatorsjob.moc"
diff --git a/tests/auto/render/buffer/tst_buffer.cpp b/tests/auto/render/buffer/tst_buffer.cpp
index 84990f4ab..a23e46c65 100644
--- a/tests/auto/render/buffer/tst_buffer.cpp
+++ b/tests/auto/render/buffer/tst_buffer.cpp
@@ -87,7 +87,6 @@ private Q_SLOTS:
// THEN
QCOMPARE(renderBuffer.peerId(), buffer.id());
QCOMPARE(renderBuffer.isDirty(), true);
- QCOMPARE(renderBuffer.type(), buffer.type());
QCOMPARE(renderBuffer.usage(), buffer.usage());
QCOMPARE(renderBuffer.data(), buffer.data());
QCOMPARE(renderBuffer.dataGenerator(), buffer.dataGenerator());
@@ -105,7 +104,6 @@ private Q_SLOTS:
// THEN
QCOMPARE(renderBuffer.isDirty(), false);
- QCOMPARE(renderBuffer.type(), Qt3DRender::QBuffer::VertexBuffer);
QCOMPARE(renderBuffer.usage(), Qt3DRender::QBuffer::StaticDraw);
QVERIFY(renderBuffer.data().isEmpty());
QVERIFY(renderBuffer.peerId().isNull());
@@ -113,7 +111,7 @@ private Q_SLOTS:
QVERIFY(renderBuffer.pendingBufferUpdates().empty());
// GIVEN
- Qt3DRender::QBuffer buffer(Qt3DRender::QBuffer::IndexBuffer);
+ Qt3DRender::QBuffer buffer;
buffer.setUsage(Qt3DRender::QBuffer::DynamicCopy);
buffer.setData(QByteArrayLiteral("C7"));
buffer.setDataGenerator(Qt3DRender::QBufferDataGeneratorPtr(new TestFunctor(73)));
@@ -132,7 +130,6 @@ private Q_SLOTS:
renderBuffer.sceneChangeEvent(updateChange);
// THEN
- QCOMPARE(renderBuffer.type(), Qt3DRender::QBuffer::IndexBuffer);
QCOMPARE(renderBuffer.usage(), Qt3DRender::QBuffer::DynamicCopy);
QCOMPARE(renderBuffer.isDirty(), true);
QCOMPARE(renderBuffer.data(), QByteArrayLiteral("C7"));
@@ -144,7 +141,6 @@ private Q_SLOTS:
// THEN
QCOMPARE(renderBuffer.isDirty(), false);
- QCOMPARE(renderBuffer.type(), Qt3DRender::QBuffer::VertexBuffer);
QCOMPARE(renderBuffer.usage(), Qt3DRender::QBuffer::StaticDraw);
QVERIFY(renderBuffer.data().isEmpty());
QVERIFY(renderBuffer.dataGenerator().isNull());
@@ -159,7 +155,6 @@ private Q_SLOTS:
renderBuffer.setRenderer(&renderer);
// THEN
- QVERIFY(renderBuffer.type() != Qt3DRender::QBuffer::IndexBuffer);
QVERIFY(renderBuffer.data().isEmpty());
QVERIFY(renderBuffer.usage() != Qt3DRender::QBuffer::DynamicRead);
QVERIFY(!renderBuffer.isDirty());
@@ -168,24 +163,6 @@ private Q_SLOTS:
// WHEN
Qt3DCore::QPropertyUpdatedChangePtr updateChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
- updateChange->setValue(static_cast<int>(Qt3DRender::QBuffer::IndexBuffer));
- updateChange->setPropertyName("type");
- renderBuffer.sceneChangeEvent(updateChange);
-
-
- // THEN
- QCOMPARE(renderBuffer.type(), Qt3DRender::QBuffer::IndexBuffer);
- QVERIFY(renderer.dirtyBits() != 0);
- QVERIFY(renderBuffer.isDirty());
-
- QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::BuffersDirty);
- renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
-
- renderBuffer.unsetDirty();
- QVERIFY(!renderBuffer.isDirty());
-
- // WHEN
- updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setValue(static_cast<int>(Qt3DRender::QBuffer::DynamicRead));
updateChange->setPropertyName("usage");
renderBuffer.sceneChangeEvent(updateChange);
diff --git a/tests/auto/render/meshfunctors/tst_meshfunctors.cpp b/tests/auto/render/meshfunctors/tst_meshfunctors.cpp
index c0e871d62..1904169fb 100644
--- a/tests/auto/render/meshfunctors/tst_meshfunctors.cpp
+++ b/tests/auto/render/meshfunctors/tst_meshfunctors.cpp
@@ -27,8 +27,12 @@
****************************************************************************/
#include <QtTest/QtTest>
+#include <Qt3DCore/qcomponent.h>
#include <Qt3DRender/qgeometryfactory.h>
#include <Qt3DRender/qgeometry.h>
+#include <Qt3DRender/qmesh.h>
+#include <Qt3DRender/private/qmesh_p.h>
+#include <Qt3DCore/qaspectengine.h>
class MeshFunctorA : public Qt3DRender::QGeometryFactory
{
@@ -117,8 +121,46 @@ private Q_SLOTS:
QVERIFY(*functorB == *functorB);
QVERIFY(*functorASub == *functorASub);
}
+
+ void checkMeshFunctorEquality()
+ {
+ // GIVEN
+ Qt3DCore::QAspectEngine engine;
+ auto meshA = new Qt3DRender::QMesh();
+ meshA->setSource(QUrl::fromLocalFile(QLatin1String("/foo")));
+ meshA->setMeshName(QLatin1String("bar"));
+
+ auto meshB = new Qt3DRender::QMesh();
+ meshB->setSource(QUrl::fromLocalFile(QLatin1String("/foo")));
+ meshB->setMeshName(QLatin1String("baz"));
+
+ auto meshC = new Qt3DRender::QMesh();
+ meshC->setSource(QUrl::fromLocalFile(QLatin1String("/baz")));
+ meshC->setMeshName(QLatin1String("bar"));
+
+ auto meshD = new Qt3DRender::QMesh();
+ meshD->setSource(QUrl::fromLocalFile(QLatin1String("/foo")));
+ meshD->setMeshName(QLatin1String("bar"));
+
+ const Qt3DRender::MeshLoaderFunctor functorA(meshA, &engine);
+ const Qt3DRender::MeshLoaderFunctor functorB(meshB, &engine);
+ const Qt3DRender::MeshLoaderFunctor functorC(meshC, &engine);
+ const Qt3DRender::MeshLoaderFunctor functorD(meshD, &engine);
+
+ // WHEN
+ const bool selfEquality = (functorA == functorA);
+ const bool sameSource = (functorA == functorB);
+ const bool sameMeshName = (functorA == functorC);
+ const bool perfectMatch = (functorA == functorD);
+
+ // THEN
+ QCOMPARE(selfEquality, true);
+ QCOMPARE(sameSource, false);
+ QCOMPARE(sameMeshName, false);
+ QCOMPARE(perfectMatch, true);
+ }
};
-QTEST_APPLESS_MAIN(tst_MeshFunctors)
+QTEST_MAIN(tst_MeshFunctors)
#include "tst_meshfunctors.moc"
diff --git a/tests/auto/render/qbuffer/tst_qbuffer.cpp b/tests/auto/render/qbuffer/tst_qbuffer.cpp
index 5408c0474..c0d96d10b 100644
--- a/tests/auto/render/qbuffer/tst_qbuffer.cpp
+++ b/tests/auto/render/qbuffer/tst_qbuffer.cpp
@@ -112,7 +112,6 @@ private Q_SLOTS:
QCOMPARE(buffer->metaObject(), creationChangeData->metaObject());
QCOMPARE(buffer->data(), cloneData.data);
QCOMPARE(buffer->usage(), cloneData.usage);
- QCOMPARE(buffer->type(), cloneData.type);
QCOMPARE(buffer->dataGenerator(), cloneData.functor);
QCOMPARE(buffer->isSyncData(), cloneData.syncData);
if (buffer->dataGenerator()) {
diff --git a/tests/manual/skinned-mesh/DefaultSceneEntity.qml b/tests/manual/skinned-mesh/DefaultSceneEntity.qml
index 26760fa51..e3465a8bb 100644
--- a/tests/manual/skinned-mesh/DefaultSceneEntity.qml
+++ b/tests/manual/skinned-mesh/DefaultSceneEntity.qml
@@ -68,8 +68,8 @@ Entity {
Camera {
id: mainCamera
- position: Qt.vector3d(0, 0.8, 2)
- viewCenter: Qt.vector3d(0, 0.8, 0)
+ position: Qt.vector3d(2.5, 0.8, 5)
+ viewCenter: Qt.vector3d(2.5, 0.8, 0)
fieldOfView: 60
}
diff --git a/tests/manual/skinned-mesh/SkinnedEntity.qml b/tests/manual/skinned-mesh/SkinnedEntity.qml
index 47f2bae7b..f1c3ee0c2 100644
--- a/tests/manual/skinned-mesh/SkinnedEntity.qml
+++ b/tests/manual/skinned-mesh/SkinnedEntity.qml
@@ -12,6 +12,7 @@ Entity {
property alias transform: transform
property color baseColor: "red"
property alias rootJoint: skeleton.rootJoint
+ property alias skeleton: skeleton
components: [
Transform {
diff --git a/tests/manual/skinned-mesh/SkinnedPbrEffect.qml b/tests/manual/skinned-mesh/SkinnedPbrEffect.qml
index 79e4f7757..c1c383a74 100644
--- a/tests/manual/skinned-mesh/SkinnedPbrEffect.qml
+++ b/tests/manual/skinned-mesh/SkinnedPbrEffect.qml
@@ -30,7 +30,8 @@ Effect {
ShaderProgramBuilder {
shaderProgram: prog
- fragmentShaderGraph: "qrc:/shaders/graphs/metalroughuniform.frag.json"
+ fragmentShaderGraph: "qrc:/shaders/graphs/metalrough.frag.json"
+ enabledLayers: ["baseColor", "metalness", "roughness", "ambientOcclusion", "normal"]
}
}
}
diff --git a/tests/manual/skinned-mesh/jump.json b/tests/manual/skinned-mesh/jump.json
new file mode 100644
index 000000000..7d7447a40
--- /dev/null
+++ b/tests/manual/skinned-mesh/jump.json
@@ -0,0 +1,4571 @@
+{
+ "animations": [
+ {
+ "animationName": "Jump",
+ "channels": [
+ {
+ "channelComponents": [
+ {
+ "channelComponentName": "Location X",
+ "keyFrames": [
+ {
+ "coords": [
+ 0.0,
+ 0.0
+ ],
+ "leftHandle": [
+ -0.3090757727622986,
+ 0.0
+ ],
+ "rightHandle": [
+ 0.3090757528940837,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 0.7916666666666666,
+ 0.0
+ ],
+ "leftHandle": [
+ 0.482590913772583,
+ 0.0
+ ],
+ "rightHandle": [
+ 0.9543381532033285,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 1.2083333333333333,
+ -0.5
+ ],
+ "leftHandle": [
+ 1.0456618467966716,
+ -0.5
+ ],
+ "rightHandle": [
+ 1.2896690368652344,
+ -0.5
+ ]
+ },
+ {
+ "coords": [
+ 1.4166666666666667,
+ -0.5
+ ],
+ "leftHandle": [
+ 1.3353309631347656,
+ -0.5
+ ],
+ "rightHandle": [
+ 1.5305366516113281,
+ -0.5
+ ]
+ },
+ {
+ "coords": [
+ 1.7083333333333333,
+ 2.5
+ ],
+ "leftHandle": [
+ 1.5944633483886719,
+ 1.4873701333999634
+ ],
+ "rightHandle": [
+ 1.838470458984375,
+ 3.6572914123535156
+ ]
+ },
+ {
+ "coords": [
+ 2.0416666666666665,
+ 5.0
+ ],
+ "leftHandle": [
+ 1.911529541015625,
+ 5.0
+ ],
+ "rightHandle": [
+ 2.5296810468037925,
+ 5.0
+ ]
+ },
+ {
+ "coords": [
+ 3.2916666666666665,
+ 5.0
+ ],
+ "leftHandle": [
+ 2.8036524454752603,
+ 5.0
+ ],
+ "rightHandle": [
+ 3.405536651611328,
+ 5.0
+ ]
+ },
+ {
+ "coords": [
+ 3.5833333333333335,
+ 5.0
+ ],
+ "leftHandle": [
+ 3.469463348388672,
+ 5.0
+ ],
+ "rightHandle": [
+ 3.6972033182779946,
+ 5.0
+ ]
+ },
+ {
+ "coords": [
+ 3.875,
+ 5.0
+ ],
+ "leftHandle": [
+ 3.7611300150553384,
+ 5.0
+ ],
+ "rightHandle": [
+ 3.9888699849446616,
+ 5.0
+ ]
+ },
+ {
+ "coords": [
+ 4.166666666666667,
+ 5.0
+ ],
+ "leftHandle": [
+ 4.052796681722005,
+ 5.0
+ ],
+ "rightHandle": [
+ 4.248002370198567,
+ 5.0
+ ]
+ },
+ {
+ "coords": [
+ 4.375,
+ 5.0
+ ],
+ "leftHandle": [
+ 4.293664296468099,
+ 5.0
+ ],
+ "rightHandle": [
+ 4.456335703531901,
+ 5.0
+ ]
+ },
+ {
+ "coords": [
+ 4.583333333333333,
+ 5.0
+ ],
+ "leftHandle": [
+ 4.501997629801433,
+ 5.0
+ ],
+ "rightHandle": [
+ 4.664669036865234,
+ 5.0
+ ]
+ },
+ {
+ "coords": [
+ 4.791666666666667,
+ 5.0
+ ],
+ "leftHandle": [
+ 4.710330963134766,
+ 5.0
+ ],
+ "rightHandle": [
+ 4.873002370198567,
+ 5.0
+ ]
+ },
+ {
+ "coords": [
+ 5.0,
+ 5.0
+ ],
+ "leftHandle": [
+ 4.918664296468099,
+ 5.0
+ ],
+ "rightHandle": [
+ 5.081335703531901,
+ 5.0
+ ]
+ },
+ {
+ "coords": [
+ 5.208333333333333,
+ 5.0
+ ],
+ "leftHandle": [
+ 5.126997629801433,
+ 5.0
+ ],
+ "rightHandle": [
+ 5.598744710286458,
+ 5.0
+ ]
+ },
+ {
+ "coords": [
+ 6.208333333333333,
+ 5.0
+ ],
+ "leftHandle": [
+ 5.817921956380208,
+ 5.0
+ ],
+ "rightHandle": [
+ 6.371004740397136,
+ 5.0
+ ]
+ },
+ {
+ "coords": [
+ 6.625,
+ 5.5
+ ],
+ "leftHandle": [
+ 6.462328592936198,
+ 5.5
+ ],
+ "rightHandle": [
+ 6.706335703531901,
+ 5.5
+ ]
+ },
+ {
+ "coords": [
+ 6.833333333333333,
+ 5.5
+ ],
+ "leftHandle": [
+ 6.751997629801433,
+ 5.5
+ ],
+ "rightHandle": [
+ 6.947203318277995,
+ 5.5
+ ]
+ },
+ {
+ "coords": [
+ 7.125,
+ 2.5
+ ],
+ "leftHandle": [
+ 7.011130015055339,
+ 3.512629985809326
+ ],
+ "rightHandle": [
+ 7.255137125651042,
+ 1.342708706855774
+ ]
+ },
+ {
+ "coords": [
+ 7.458333333333333,
+ 0.0
+ ],
+ "leftHandle": [
+ 7.328196207682292,
+ 0.0
+ ],
+ "rightHandle": [
+ 7.946347554524739,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 8.708333333333334,
+ 0.0
+ ],
+ "leftHandle": [
+ 8.220319112141928,
+ 0.0
+ ],
+ "rightHandle": [
+ 8.822203318277994,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 9.0,
+ 0.0
+ ],
+ "leftHandle": [
+ 8.886130015055338,
+ 0.0
+ ],
+ "rightHandle": [
+ 9.113869984944662,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 9.291666666666666,
+ 0.0
+ ],
+ "leftHandle": [
+ 9.177796681722006,
+ 0.0
+ ],
+ "rightHandle": [
+ 9.405536651611328,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 9.583333333333334,
+ 0.0
+ ],
+ "leftHandle": [
+ 9.469463348388672,
+ 0.0
+ ],
+ "rightHandle": [
+ 9.664669036865234,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 9.791666666666666,
+ 0.0
+ ],
+ "leftHandle": [
+ 9.710330963134766,
+ 0.0
+ ],
+ "rightHandle": [
+ 9.873002370198568,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 10.0,
+ 0.0
+ ],
+ "leftHandle": [
+ 9.9186642964681,
+ 0.0
+ ],
+ "rightHandle": [
+ 10.0813357035319,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 10.208333333333334,
+ 0.0
+ ],
+ "leftHandle": [
+ 10.126997629801432,
+ 0.0
+ ],
+ "rightHandle": [
+ 10.289669036865234,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 10.416666666666666,
+ 0.0
+ ],
+ "leftHandle": [
+ 10.335330963134766,
+ 0.0
+ ],
+ "rightHandle": [
+ 10.498002370198568,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 10.625,
+ 0.0
+ ],
+ "leftHandle": [
+ 10.5436642964681,
+ 0.0
+ ],
+ "rightHandle": [
+ 10.7063357035319,
+ 0.0
+ ]
+ }
+ ]
+ },
+ {
+ "channelComponentName": "Location Z",
+ "keyFrames": [
+ {
+ "coords": [
+ 0.0,
+ 0.0
+ ],
+ "leftHandle": [
+ -0.3090757727622986,
+ 0.0
+ ],
+ "rightHandle": [
+ 0.3090757528940837,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 0.7916666666666666,
+ 0.0
+ ],
+ "leftHandle": [
+ 0.482590913772583,
+ 0.0
+ ],
+ "rightHandle": [
+ 0.9543381532033285,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 1.2083333333333333,
+ 0.0
+ ],
+ "leftHandle": [
+ 1.0456618467966716,
+ 0.0
+ ],
+ "rightHandle": [
+ 1.2896690368652344,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 1.4166666666666667,
+ 0.0
+ ],
+ "leftHandle": [
+ 1.3353309631347656,
+ 0.0
+ ],
+ "rightHandle": [
+ 1.5305366516113281,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 1.7083333333333333,
+ 0.0
+ ],
+ "leftHandle": [
+ 1.5944633483886719,
+ 0.0
+ ],
+ "rightHandle": [
+ 1.838470458984375,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 2.0416666666666665,
+ 0.0
+ ],
+ "leftHandle": [
+ 1.911529541015625,
+ 0.0
+ ],
+ "rightHandle": [
+ 2.5296810468037925,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 3.2916666666666665,
+ 0.0
+ ],
+ "leftHandle": [
+ 2.8036524454752603,
+ 0.0
+ ],
+ "rightHandle": [
+ 3.405536651611328,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 3.5833333333333335,
+ 0.0
+ ],
+ "leftHandle": [
+ 3.469463348388672,
+ 0.0
+ ],
+ "rightHandle": [
+ 3.6972033182779946,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 3.875,
+ 0.0
+ ],
+ "leftHandle": [
+ 3.7611300150553384,
+ 0.0
+ ],
+ "rightHandle": [
+ 3.9888699849446616,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 4.166666666666667,
+ 0.0
+ ],
+ "leftHandle": [
+ 4.052796681722005,
+ 0.0
+ ],
+ "rightHandle": [
+ 4.248002370198567,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 4.375,
+ 0.0
+ ],
+ "leftHandle": [
+ 4.293664296468099,
+ 0.0
+ ],
+ "rightHandle": [
+ 4.456335703531901,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 4.583333333333333,
+ 0.0
+ ],
+ "leftHandle": [
+ 4.501997629801433,
+ 0.0
+ ],
+ "rightHandle": [
+ 4.664669036865234,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 4.791666666666667,
+ 0.0
+ ],
+ "leftHandle": [
+ 4.710330963134766,
+ 0.0
+ ],
+ "rightHandle": [
+ 4.873002370198567,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 5.0,
+ 0.0
+ ],
+ "leftHandle": [
+ 4.918664296468099,
+ 0.0
+ ],
+ "rightHandle": [
+ 5.081335703531901,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 5.208333333333333,
+ 0.0
+ ],
+ "leftHandle": [
+ 5.126997629801433,
+ 0.0
+ ],
+ "rightHandle": [
+ 5.598744710286458,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 6.208333333333333,
+ 0.0
+ ],
+ "leftHandle": [
+ 5.817921956380208,
+ 0.0
+ ],
+ "rightHandle": [
+ 6.371004740397136,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 6.625,
+ 0.0
+ ],
+ "leftHandle": [
+ 6.462328592936198,
+ 0.0
+ ],
+ "rightHandle": [
+ 6.706335703531901,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 6.833333333333333,
+ 0.0
+ ],
+ "leftHandle": [
+ 6.751997629801433,
+ 0.0
+ ],
+ "rightHandle": [
+ 6.947203318277995,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 7.125,
+ 0.0
+ ],
+ "leftHandle": [
+ 7.011130015055339,
+ 0.0
+ ],
+ "rightHandle": [
+ 7.255137125651042,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 7.458333333333333,
+ 0.0
+ ],
+ "leftHandle": [
+ 7.328196207682292,
+ 0.0
+ ],
+ "rightHandle": [
+ 7.946347554524739,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 8.708333333333334,
+ 0.0
+ ],
+ "leftHandle": [
+ 8.220319112141928,
+ 0.0
+ ],
+ "rightHandle": [
+ 8.822203318277994,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 9.0,
+ 0.0
+ ],
+ "leftHandle": [
+ 8.886130015055338,
+ 0.0
+ ],
+ "rightHandle": [
+ 9.113869984944662,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 9.291666666666666,
+ 0.0
+ ],
+ "leftHandle": [
+ 9.177796681722006,
+ 0.0
+ ],
+ "rightHandle": [
+ 9.405536651611328,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 9.583333333333334,
+ 0.0
+ ],
+ "leftHandle": [
+ 9.469463348388672,
+ 0.0
+ ],
+ "rightHandle": [
+ 9.664669036865234,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 9.791666666666666,
+ 0.0
+ ],
+ "leftHandle": [
+ 9.710330963134766,
+ 0.0
+ ],
+ "rightHandle": [
+ 9.873002370198568,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 10.0,
+ 0.0
+ ],
+ "leftHandle": [
+ 9.9186642964681,
+ 0.0
+ ],
+ "rightHandle": [
+ 10.0813357035319,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 10.208333333333334,
+ 0.0
+ ],
+ "leftHandle": [
+ 10.126997629801432,
+ 0.0
+ ],
+ "rightHandle": [
+ 10.289669036865234,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 10.416666666666666,
+ 0.0
+ ],
+ "leftHandle": [
+ 10.335330963134766,
+ 0.0
+ ],
+ "rightHandle": [
+ 10.498002370198568,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 10.625,
+ 0.0
+ ],
+ "leftHandle": [
+ 10.5436642964681,
+ 0.0
+ ],
+ "rightHandle": [
+ 10.7063357035319,
+ 0.0
+ ]
+ }
+ ]
+ },
+ {
+ "channelComponentName": "Location Y",
+ "keyFrames": [
+ {
+ "coords": [
+ 0.0,
+ 0.0
+ ],
+ "leftHandle": [
+ -0.3090757727622986,
+ 0.0
+ ],
+ "rightHandle": [
+ 0.3090757528940837,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 0.7916666666666666,
+ 0.0
+ ],
+ "leftHandle": [
+ 0.482590913772583,
+ 0.0
+ ],
+ "rightHandle": [
+ 0.9543381532033285,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 1.2083333333333333,
+ 0.0
+ ],
+ "leftHandle": [
+ 1.0456618467966716,
+ 0.0
+ ],
+ "rightHandle": [
+ 1.2896690368652344,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 1.4166666666666667,
+ 0.0
+ ],
+ "leftHandle": [
+ 1.3353309631347656,
+ 0.0
+ ],
+ "rightHandle": [
+ 1.5305366516113281,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 1.7083333333333333,
+ 2.0
+ ],
+ "leftHandle": [
+ 1.5944633483886719,
+ 2.0
+ ],
+ "rightHandle": [
+ 1.838470458984375,
+ 2.0
+ ]
+ },
+ {
+ "coords": [
+ 2.0416666666666665,
+ 0.0
+ ],
+ "leftHandle": [
+ 1.911529541015625,
+ 0.0
+ ],
+ "rightHandle": [
+ 2.5296810468037925,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 3.2916666666666665,
+ 0.0
+ ],
+ "leftHandle": [
+ 2.8036524454752603,
+ 0.0
+ ],
+ "rightHandle": [
+ 3.405536651611328,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 3.5833333333333335,
+ 0.0
+ ],
+ "leftHandle": [
+ 3.469463348388672,
+ 0.0
+ ],
+ "rightHandle": [
+ 3.6972033182779946,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 3.875,
+ 0.5
+ ],
+ "leftHandle": [
+ 3.7611300150553384,
+ 0.5
+ ],
+ "rightHandle": [
+ 3.9888699849446616,
+ 0.5
+ ]
+ },
+ {
+ "coords": [
+ 4.166666666666667,
+ 0.0
+ ],
+ "leftHandle": [
+ 4.052796681722005,
+ 0.0
+ ],
+ "rightHandle": [
+ 4.248002370198567,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 4.375,
+ 0.0
+ ],
+ "leftHandle": [
+ 4.293664296468099,
+ 0.0
+ ],
+ "rightHandle": [
+ 4.456335703531901,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 4.583333333333333,
+ 0.0
+ ],
+ "leftHandle": [
+ 4.501997629801433,
+ 0.0
+ ],
+ "rightHandle": [
+ 4.664669036865234,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 4.791666666666667,
+ 0.0
+ ],
+ "leftHandle": [
+ 4.710330963134766,
+ 0.0
+ ],
+ "rightHandle": [
+ 4.873002370198567,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 5.0,
+ 0.30000001192092896
+ ],
+ "leftHandle": [
+ 4.918664296468099,
+ 0.30000001192092896
+ ],
+ "rightHandle": [
+ 5.081335703531901,
+ 0.30000001192092896
+ ]
+ },
+ {
+ "coords": [
+ 5.208333333333333,
+ 0.0
+ ],
+ "leftHandle": [
+ 5.126997629801433,
+ 0.0
+ ],
+ "rightHandle": [
+ 5.598744710286458,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 6.208333333333333,
+ 0.0
+ ],
+ "leftHandle": [
+ 5.817921956380208,
+ 0.0
+ ],
+ "rightHandle": [
+ 6.371004740397136,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 6.625,
+ 0.0
+ ],
+ "leftHandle": [
+ 6.462328592936198,
+ 0.0
+ ],
+ "rightHandle": [
+ 6.706335703531901,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 6.833333333333333,
+ 0.0
+ ],
+ "leftHandle": [
+ 6.751997629801433,
+ 0.0
+ ],
+ "rightHandle": [
+ 6.947203318277995,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 7.125,
+ 2.0
+ ],
+ "leftHandle": [
+ 7.011130015055339,
+ 2.0
+ ],
+ "rightHandle": [
+ 7.255137125651042,
+ 2.0
+ ]
+ },
+ {
+ "coords": [
+ 7.458333333333333,
+ 0.0
+ ],
+ "leftHandle": [
+ 7.328196207682292,
+ 0.0
+ ],
+ "rightHandle": [
+ 7.946347554524739,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 8.708333333333334,
+ 0.0
+ ],
+ "leftHandle": [
+ 8.220319112141928,
+ 0.0
+ ],
+ "rightHandle": [
+ 8.822203318277994,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 9.0,
+ 0.0
+ ],
+ "leftHandle": [
+ 8.886130015055338,
+ 0.0
+ ],
+ "rightHandle": [
+ 9.113869984944662,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 9.291666666666666,
+ 0.5
+ ],
+ "leftHandle": [
+ 9.177796681722006,
+ 0.5
+ ],
+ "rightHandle": [
+ 9.405536651611328,
+ 0.5
+ ]
+ },
+ {
+ "coords": [
+ 9.583333333333334,
+ 0.0
+ ],
+ "leftHandle": [
+ 9.469463348388672,
+ 0.0
+ ],
+ "rightHandle": [
+ 9.664669036865234,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 9.791666666666666,
+ 0.0
+ ],
+ "leftHandle": [
+ 9.710330963134766,
+ 0.0
+ ],
+ "rightHandle": [
+ 9.873002370198568,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 10.0,
+ 0.0
+ ],
+ "leftHandle": [
+ 9.9186642964681,
+ 0.0
+ ],
+ "rightHandle": [
+ 10.0813357035319,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 10.208333333333334,
+ 0.0
+ ],
+ "leftHandle": [
+ 10.126997629801432,
+ 0.0
+ ],
+ "rightHandle": [
+ 10.289669036865234,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 10.416666666666666,
+ 0.30000001192092896
+ ],
+ "leftHandle": [
+ 10.335330963134766,
+ 0.30000001192092896
+ ],
+ "rightHandle": [
+ 10.498002370198568,
+ 0.30000001192092896
+ ]
+ },
+ {
+ "coords": [
+ 10.625,
+ 0.0
+ ],
+ "leftHandle": [
+ 10.5436642964681,
+ 0.0
+ ],
+ "rightHandle": [
+ 10.7063357035319,
+ 0.0
+ ]
+ }
+ ]
+ }
+ ],
+ "channelName": "Location",
+ "jointIndex": 0
+ },
+ {
+ "channelComponents": [
+ {
+ "channelComponentName": "Scale X",
+ "keyFrames": [
+ {
+ "coords": [
+ 0.0,
+ 1.000070333480835
+ ],
+ "leftHandle": [
+ -0.3090757926305135,
+ 1.000070333480835
+ ],
+ "rightHandle": [
+ 0.3090757528940837,
+ 1.000070333480835
+ ]
+ },
+ {
+ "coords": [
+ 0.7916666666666666,
+ 1.000070333480835
+ ],
+ "leftHandle": [
+ 0.482590913772583,
+ 1.000070333480835
+ ],
+ "rightHandle": [
+ 0.9543381532033285,
+ 1.000070333480835
+ ]
+ },
+ {
+ "coords": [
+ 1.2083333333333333,
+ 1.2000703811645508
+ ],
+ "leftHandle": [
+ 1.0456618467966716,
+ 1.2000703811645508
+ ],
+ "rightHandle": [
+ 1.6150120099385579,
+ 1.2000703811645508
+ ]
+ },
+ {
+ "coords": [
+ 1.4166666666666667,
+ 1.2000703811645508
+ ],
+ "leftHandle": [
+ 1.0099881490071614,
+ 1.2000703811645508
+ ],
+ "rightHandle": [
+ 1.5305366516113281,
+ 1.2000703811645508
+ ]
+ },
+ {
+ "coords": [
+ 1.7083333333333333,
+ 0.8000703454017639
+ ],
+ "leftHandle": [
+ 1.5944633483886719,
+ 0.8000703454017639
+ ],
+ "rightHandle": [
+ 1.838470458984375,
+ 0.8000703454017639
+ ]
+ },
+ {
+ "coords": [
+ 2.0416666666666665,
+ 1.2000703811645508
+ ],
+ "leftHandle": [
+ 1.9603309631347656,
+ 1.0536658763885498
+ ],
+ "rightHandle": [
+ 2.057933807373047,
+ 1.229351282119751
+ ]
+ },
+ {
+ "coords": [
+ 2.0833333333333335,
+ 1.3000702857971191
+ ],
+ "leftHandle": [
+ 2.0386231740315757,
+ 1.3000702857971191
+ ],
+ "rightHandle": [
+ 2.1339289347330728,
+ 1.3000702857971191
+ ]
+ },
+ {
+ "coords": [
+ 2.2083333333333335,
+ 0.9400703310966492
+ ],
+ "leftHandle": [
+ 2.1606807708740234,
+ 0.9400703310966492
+ ],
+ "rightHandle": [
+ 2.255985895792643,
+ 0.9400703310966492
+ ]
+ },
+ {
+ "coords": [
+ 2.3333333333333335,
+ 1.000070333480835
+ ],
+ "leftHandle": [
+ 2.2827377319335938,
+ 1.000070333480835
+ ],
+ "rightHandle": [
+ 2.3780434926350913,
+ 1.000070333480835
+ ]
+ },
+ {
+ "coords": [
+ 3.2916666666666665,
+ 1.000070333480835
+ ],
+ "leftHandle": [
+ 2.917522430419922,
+ 1.000070333480835
+ ],
+ "rightHandle": [
+ 3.405536651611328,
+ 1.000070333480835
+ ]
+ },
+ {
+ "coords": [
+ 3.5833333333333335,
+ 1.2000703811645508
+ ],
+ "leftHandle": [
+ 3.469463348388672,
+ 1.2000703811645508
+ ],
+ "rightHandle": [
+ 3.6972033182779946,
+ 1.2000703811645508
+ ]
+ },
+ {
+ "coords": [
+ 3.875,
+ 0.8000703454017639
+ ],
+ "leftHandle": [
+ 3.7611300150553384,
+ 0.8000703454017639
+ ],
+ "rightHandle": [
+ 3.9888699849446616,
+ 0.8000703454017639
+ ]
+ },
+ {
+ "coords": [
+ 4.166666666666667,
+ 1.2000703811645508
+ ],
+ "leftHandle": [
+ 4.052796681722005,
+ 1.2000703811645508
+ ],
+ "rightHandle": [
+ 4.248002370198567,
+ 1.2000703811645508
+ ]
+ },
+ {
+ "coords": [
+ 4.375,
+ 1.2000703811645508
+ ],
+ "leftHandle": [
+ 4.293664296468099,
+ 1.2000703811645508
+ ],
+ "rightHandle": [
+ 4.456335703531901,
+ 1.2000703811645508
+ ]
+ },
+ {
+ "coords": [
+ 4.583333333333333,
+ 1.2000703811645508
+ ],
+ "leftHandle": [
+ 4.501997629801433,
+ 1.2000703811645508
+ ],
+ "rightHandle": [
+ 4.664669036865234,
+ 1.2000703811645508
+ ]
+ },
+ {
+ "coords": [
+ 4.791666666666667,
+ 1.1000703573226929
+ ],
+ "leftHandle": [
+ 4.710330963134766,
+ 1.1508238315582275
+ ],
+ "rightHandle": [
+ 4.873002370198567,
+ 1.0493168830871582
+ ]
+ },
+ {
+ "coords": [
+ 5.0,
+ 0.9400703310966492
+ ],
+ "leftHandle": [
+ 4.918664296468099,
+ 0.9400703310966492
+ ],
+ "rightHandle": [
+ 5.081335703531901,
+ 0.9400703310966492
+ ]
+ },
+ {
+ "coords": [
+ 5.208333333333333,
+ 1.1000703573226929
+ ],
+ "leftHandle": [
+ 5.126997629801433,
+ 1.1000703573226929
+ ],
+ "rightHandle": [
+ 5.2734018961588545,
+ 1.1000703573226929
+ ]
+ },
+ {
+ "coords": [
+ 5.375,
+ 1.000070333480835
+ ],
+ "leftHandle": [
+ 5.3099314371744795,
+ 1.000070333480835
+ ],
+ "rightHandle": [
+ 5.7003428141276045,
+ 1.000070333480835
+ ]
+ },
+ {
+ "coords": [
+ 6.208333333333333,
+ 1.000070333480835
+ ],
+ "leftHandle": [
+ 5.8829905192057295,
+ 1.000070333480835
+ ],
+ "rightHandle": [
+ 6.371004740397136,
+ 1.000070333480835
+ ]
+ },
+ {
+ "coords": [
+ 6.625,
+ 1.2000703811645508
+ ],
+ "leftHandle": [
+ 6.462328592936198,
+ 1.2000703811645508
+ ],
+ "rightHandle": [
+ 7.031678517659505,
+ 1.2000703811645508
+ ]
+ },
+ {
+ "coords": [
+ 6.833333333333333,
+ 1.2000703811645508
+ ],
+ "leftHandle": [
+ 6.426654815673828,
+ 1.2000703811645508
+ ],
+ "rightHandle": [
+ 6.947203318277995,
+ 1.2000703811645508
+ ]
+ },
+ {
+ "coords": [
+ 7.125,
+ 0.8000703454017639
+ ],
+ "leftHandle": [
+ 7.011130015055339,
+ 0.8000703454017639
+ ],
+ "rightHandle": [
+ 7.255137125651042,
+ 0.8000703454017639
+ ]
+ },
+ {
+ "coords": [
+ 7.458333333333333,
+ 1.2000703811645508
+ ],
+ "leftHandle": [
+ 7.376997629801433,
+ 1.0536658763885498
+ ],
+ "rightHandle": [
+ 7.474600474039714,
+ 1.229351282119751
+ ]
+ },
+ {
+ "coords": [
+ 7.5,
+ 1.3000702857971191
+ ],
+ "leftHandle": [
+ 7.455289204915364,
+ 1.3000702857971191
+ ],
+ "rightHandle": [
+ 7.550595601399739,
+ 1.3000702857971191
+ ]
+ },
+ {
+ "coords": [
+ 7.625,
+ 0.9400703310966492
+ ],
+ "leftHandle": [
+ 7.5773468017578125,
+ 0.9400703310966492
+ ],
+ "rightHandle": [
+ 7.6726531982421875,
+ 0.9400703310966492
+ ]
+ },
+ {
+ "coords": [
+ 7.75,
+ 1.000070333480835
+ ],
+ "leftHandle": [
+ 7.699404398600261,
+ 1.000070333480835
+ ],
+ "rightHandle": [
+ 7.794710795084636,
+ 1.000070333480835
+ ]
+ },
+ {
+ "coords": [
+ 8.708333333333334,
+ 1.000070333480835
+ ],
+ "leftHandle": [
+ 8.334189097086588,
+ 1.000070333480835
+ ],
+ "rightHandle": [
+ 8.822203318277994,
+ 1.000070333480835
+ ]
+ },
+ {
+ "coords": [
+ 9.0,
+ 1.2000703811645508
+ ],
+ "leftHandle": [
+ 8.886130015055338,
+ 1.2000703811645508
+ ],
+ "rightHandle": [
+ 9.113869984944662,
+ 1.2000703811645508
+ ]
+ },
+ {
+ "coords": [
+ 9.291666666666666,
+ 0.8000703454017639
+ ],
+ "leftHandle": [
+ 9.177796681722006,
+ 0.8000703454017639
+ ],
+ "rightHandle": [
+ 9.405536651611328,
+ 0.8000703454017639
+ ]
+ },
+ {
+ "coords": [
+ 9.583333333333334,
+ 1.2000703811645508
+ ],
+ "leftHandle": [
+ 9.469462076822916,
+ 1.2000703811645508
+ ],
+ "rightHandle": [
+ 9.664667765299479,
+ 1.2000703811645508
+ ]
+ },
+ {
+ "coords": [
+ 9.791666666666666,
+ 1.000070333480835
+ ],
+ "leftHandle": [
+ 9.710332234700521,
+ 1.000070333480835
+ ],
+ "rightHandle": [
+ 9.873001098632812,
+ 1.000070333480835
+ ]
+ },
+ {
+ "coords": [
+ 10.0,
+ 1.000070333480835
+ ],
+ "leftHandle": [
+ 9.918665568033854,
+ 1.000070333480835
+ ],
+ "rightHandle": [
+ 10.081334431966146,
+ 1.000070333480835
+ ]
+ },
+ {
+ "coords": [
+ 10.208333333333334,
+ 1.1000703573226929
+ ],
+ "leftHandle": [
+ 10.126998901367188,
+ 1.1000703573226929
+ ],
+ "rightHandle": [
+ 10.289667765299479,
+ 1.1000703573226929
+ ]
+ },
+ {
+ "coords": [
+ 10.416666666666666,
+ 0.9400703310966492
+ ],
+ "leftHandle": [
+ 10.335332234700521,
+ 0.9400703310966492
+ ],
+ "rightHandle": [
+ 10.498001098632812,
+ 0.9400703310966492
+ ]
+ },
+ {
+ "coords": [
+ 10.625,
+ 1.1000703573226929
+ ],
+ "leftHandle": [
+ 10.543665568033854,
+ 1.1000703573226929
+ ],
+ "rightHandle": [
+ 10.690068562825521,
+ 1.1000703573226929
+ ]
+ },
+ {
+ "coords": [
+ 10.791666666666666,
+ 1.000070333480835
+ ],
+ "leftHandle": [
+ 10.726598103841146,
+ 1.000070333480835
+ ],
+ "rightHandle": [
+ 10.856735229492188,
+ 1.000070333480835
+ ]
+ }
+ ]
+ },
+ {
+ "channelComponentName": "Scale Z",
+ "keyFrames": [
+ {
+ "coords": [
+ 0.0,
+ 1.000070333480835
+ ],
+ "leftHandle": [
+ -0.3090757926305135,
+ 1.000070333480835
+ ],
+ "rightHandle": [
+ 0.3090757528940837,
+ 1.000070333480835
+ ]
+ },
+ {
+ "coords": [
+ 0.7916666666666666,
+ 1.000070333480835
+ ],
+ "leftHandle": [
+ 0.482590913772583,
+ 1.000070333480835
+ ],
+ "rightHandle": [
+ 0.9543381532033285,
+ 1.000070333480835
+ ]
+ },
+ {
+ "coords": [
+ 1.2083333333333333,
+ 1.2000703811645508
+ ],
+ "leftHandle": [
+ 1.0456618467966716,
+ 1.2000703811645508
+ ],
+ "rightHandle": [
+ 1.6150120099385579,
+ 1.2000703811645508
+ ]
+ },
+ {
+ "coords": [
+ 1.4166666666666667,
+ 1.2000703811645508
+ ],
+ "leftHandle": [
+ 1.0099881490071614,
+ 1.2000703811645508
+ ],
+ "rightHandle": [
+ 1.5305366516113281,
+ 1.2000703811645508
+ ]
+ },
+ {
+ "coords": [
+ 1.7083333333333333,
+ 0.8000703454017639
+ ],
+ "leftHandle": [
+ 1.5944633483886719,
+ 0.8000703454017639
+ ],
+ "rightHandle": [
+ 1.838470458984375,
+ 0.8000703454017639
+ ]
+ },
+ {
+ "coords": [
+ 2.0416666666666665,
+ 1.2000703811645508
+ ],
+ "leftHandle": [
+ 1.9603309631347656,
+ 1.0536658763885498
+ ],
+ "rightHandle": [
+ 2.057933807373047,
+ 1.229351282119751
+ ]
+ },
+ {
+ "coords": [
+ 2.0833333333333335,
+ 1.3000702857971191
+ ],
+ "leftHandle": [
+ 2.0386231740315757,
+ 1.3000702857971191
+ ],
+ "rightHandle": [
+ 2.1339289347330728,
+ 1.3000702857971191
+ ]
+ },
+ {
+ "coords": [
+ 2.2083333333333335,
+ 0.9400703310966492
+ ],
+ "leftHandle": [
+ 2.1606807708740234,
+ 0.9400703310966492
+ ],
+ "rightHandle": [
+ 2.255985895792643,
+ 0.9400703310966492
+ ]
+ },
+ {
+ "coords": [
+ 2.3333333333333335,
+ 1.000070333480835
+ ],
+ "leftHandle": [
+ 2.2827377319335938,
+ 1.000070333480835
+ ],
+ "rightHandle": [
+ 2.3780434926350913,
+ 1.000070333480835
+ ]
+ },
+ {
+ "coords": [
+ 3.2916666666666665,
+ 1.000070333480835
+ ],
+ "leftHandle": [
+ 2.917522430419922,
+ 1.000070333480835
+ ],
+ "rightHandle": [
+ 3.405536651611328,
+ 1.000070333480835
+ ]
+ },
+ {
+ "coords": [
+ 3.5833333333333335,
+ 1.2000703811645508
+ ],
+ "leftHandle": [
+ 3.469463348388672,
+ 1.2000703811645508
+ ],
+ "rightHandle": [
+ 3.6972033182779946,
+ 1.2000703811645508
+ ]
+ },
+ {
+ "coords": [
+ 3.875,
+ 0.8000703454017639
+ ],
+ "leftHandle": [
+ 3.7611300150553384,
+ 0.8000703454017639
+ ],
+ "rightHandle": [
+ 3.9888699849446616,
+ 0.8000703454017639
+ ]
+ },
+ {
+ "coords": [
+ 4.166666666666667,
+ 1.2000703811645508
+ ],
+ "leftHandle": [
+ 4.052796681722005,
+ 1.2000703811645508
+ ],
+ "rightHandle": [
+ 4.248002370198567,
+ 1.2000703811645508
+ ]
+ },
+ {
+ "coords": [
+ 4.375,
+ 1.2000703811645508
+ ],
+ "leftHandle": [
+ 4.293664296468099,
+ 1.2000703811645508
+ ],
+ "rightHandle": [
+ 4.456335703531901,
+ 1.2000703811645508
+ ]
+ },
+ {
+ "coords": [
+ 4.583333333333333,
+ 1.2000703811645508
+ ],
+ "leftHandle": [
+ 4.501997629801433,
+ 1.2000703811645508
+ ],
+ "rightHandle": [
+ 4.664669036865234,
+ 1.2000703811645508
+ ]
+ },
+ {
+ "coords": [
+ 4.791666666666667,
+ 1.1000703573226929
+ ],
+ "leftHandle": [
+ 4.710330963134766,
+ 1.1508238315582275
+ ],
+ "rightHandle": [
+ 4.873002370198567,
+ 1.0493168830871582
+ ]
+ },
+ {
+ "coords": [
+ 5.0,
+ 0.9400703310966492
+ ],
+ "leftHandle": [
+ 4.918664296468099,
+ 0.9400703310966492
+ ],
+ "rightHandle": [
+ 5.081335703531901,
+ 0.9400703310966492
+ ]
+ },
+ {
+ "coords": [
+ 5.208333333333333,
+ 1.1000703573226929
+ ],
+ "leftHandle": [
+ 5.126997629801433,
+ 1.1000703573226929
+ ],
+ "rightHandle": [
+ 5.2734018961588545,
+ 1.1000703573226929
+ ]
+ },
+ {
+ "coords": [
+ 5.375,
+ 1.000070333480835
+ ],
+ "leftHandle": [
+ 5.3099314371744795,
+ 1.000070333480835
+ ],
+ "rightHandle": [
+ 5.7003428141276045,
+ 1.000070333480835
+ ]
+ },
+ {
+ "coords": [
+ 6.208333333333333,
+ 1.000070333480835
+ ],
+ "leftHandle": [
+ 5.8829905192057295,
+ 1.000070333480835
+ ],
+ "rightHandle": [
+ 6.371004740397136,
+ 1.000070333480835
+ ]
+ },
+ {
+ "coords": [
+ 6.625,
+ 1.2000703811645508
+ ],
+ "leftHandle": [
+ 6.462328592936198,
+ 1.2000703811645508
+ ],
+ "rightHandle": [
+ 7.031678517659505,
+ 1.2000703811645508
+ ]
+ },
+ {
+ "coords": [
+ 6.833333333333333,
+ 1.2000703811645508
+ ],
+ "leftHandle": [
+ 6.426654815673828,
+ 1.2000703811645508
+ ],
+ "rightHandle": [
+ 6.947203318277995,
+ 1.2000703811645508
+ ]
+ },
+ {
+ "coords": [
+ 7.125,
+ 0.8000703454017639
+ ],
+ "leftHandle": [
+ 7.011130015055339,
+ 0.8000703454017639
+ ],
+ "rightHandle": [
+ 7.255137125651042,
+ 0.8000703454017639
+ ]
+ },
+ {
+ "coords": [
+ 7.458333333333333,
+ 1.2000703811645508
+ ],
+ "leftHandle": [
+ 7.376997629801433,
+ 1.0536658763885498
+ ],
+ "rightHandle": [
+ 7.474600474039714,
+ 1.229351282119751
+ ]
+ },
+ {
+ "coords": [
+ 7.5,
+ 1.3000702857971191
+ ],
+ "leftHandle": [
+ 7.455289204915364,
+ 1.3000702857971191
+ ],
+ "rightHandle": [
+ 7.550595601399739,
+ 1.3000702857971191
+ ]
+ },
+ {
+ "coords": [
+ 7.625,
+ 0.9400703310966492
+ ],
+ "leftHandle": [
+ 7.5773468017578125,
+ 0.9400703310966492
+ ],
+ "rightHandle": [
+ 7.6726531982421875,
+ 0.9400703310966492
+ ]
+ },
+ {
+ "coords": [
+ 7.75,
+ 1.000070333480835
+ ],
+ "leftHandle": [
+ 7.699404398600261,
+ 1.000070333480835
+ ],
+ "rightHandle": [
+ 7.794710795084636,
+ 1.000070333480835
+ ]
+ },
+ {
+ "coords": [
+ 8.708333333333334,
+ 1.000070333480835
+ ],
+ "leftHandle": [
+ 8.334189097086588,
+ 1.000070333480835
+ ],
+ "rightHandle": [
+ 8.822203318277994,
+ 1.000070333480835
+ ]
+ },
+ {
+ "coords": [
+ 9.0,
+ 1.2000703811645508
+ ],
+ "leftHandle": [
+ 8.886130015055338,
+ 1.2000703811645508
+ ],
+ "rightHandle": [
+ 9.113869984944662,
+ 1.2000703811645508
+ ]
+ },
+ {
+ "coords": [
+ 9.291666666666666,
+ 0.8000703454017639
+ ],
+ "leftHandle": [
+ 9.177796681722006,
+ 0.8000703454017639
+ ],
+ "rightHandle": [
+ 9.405536651611328,
+ 0.8000703454017639
+ ]
+ },
+ {
+ "coords": [
+ 9.583333333333334,
+ 1.2000703811645508
+ ],
+ "leftHandle": [
+ 9.469462076822916,
+ 1.2000703811645508
+ ],
+ "rightHandle": [
+ 9.664667765299479,
+ 1.2000703811645508
+ ]
+ },
+ {
+ "coords": [
+ 9.791666666666666,
+ 1.2000703811645508
+ ],
+ "leftHandle": [
+ 9.710332234700521,
+ 1.2000703811645508
+ ],
+ "rightHandle": [
+ 9.873001098632812,
+ 1.2000703811645508
+ ]
+ },
+ {
+ "coords": [
+ 10.0,
+ 1.2000703811645508
+ ],
+ "leftHandle": [
+ 9.918665568033854,
+ 1.2000703811645508
+ ],
+ "rightHandle": [
+ 10.081334431966146,
+ 1.2000703811645508
+ ]
+ },
+ {
+ "coords": [
+ 10.208333333333334,
+ 1.1000703573226929
+ ],
+ "leftHandle": [
+ 10.126998901367188,
+ 1.1508238315582275
+ ],
+ "rightHandle": [
+ 10.289667765299479,
+ 1.0493168830871582
+ ]
+ },
+ {
+ "coords": [
+ 10.416666666666666,
+ 0.9400703310966492
+ ],
+ "leftHandle": [
+ 10.335332234700521,
+ 0.9400703310966492
+ ],
+ "rightHandle": [
+ 10.498001098632812,
+ 0.9400703310966492
+ ]
+ },
+ {
+ "coords": [
+ 10.625,
+ 1.1000703573226929
+ ],
+ "leftHandle": [
+ 10.543665568033854,
+ 1.1000703573226929
+ ],
+ "rightHandle": [
+ 10.690068562825521,
+ 1.1000703573226929
+ ]
+ },
+ {
+ "coords": [
+ 10.791666666666666,
+ 1.000070333480835
+ ],
+ "leftHandle": [
+ 10.726598103841146,
+ 1.000070333480835
+ ],
+ "rightHandle": [
+ 10.856735229492188,
+ 1.000070333480835
+ ]
+ }
+ ]
+ },
+ {
+ "channelComponentName": "Scale Y",
+ "keyFrames": [
+ {
+ "coords": [
+ 0.0,
+ 1.0
+ ],
+ "leftHandle": [
+ -0.30907583236694336,
+ 1.0
+ ],
+ "rightHandle": [
+ 0.3090757528940837,
+ 1.0
+ ]
+ },
+ {
+ "coords": [
+ 0.7916666666666666,
+ 1.0
+ ],
+ "leftHandle": [
+ 0.44092432657877606,
+ 1.0
+ ],
+ "rightHandle": [
+ 0.9126714070638021,
+ 1.0
+ ]
+ },
+ {
+ "coords": [
+ 1.2083333333333333,
+ 0.6000000238418579
+ ],
+ "leftHandle": [
+ 1.0039952596028645,
+ 0.6000000238418579
+ ],
+ "rightHandle": [
+ 1.5733451843261719,
+ 0.6000000238418579
+ ]
+ },
+ {
+ "coords": [
+ 1.4166666666666667,
+ 0.6000000238418579
+ ],
+ "leftHandle": [
+ 1.0099881490071614,
+ 0.6000000238418579
+ ],
+ "rightHandle": [
+ 1.5305366516113281,
+ 0.6000000238418579
+ ]
+ },
+ {
+ "coords": [
+ 1.7083333333333333,
+ 1.2000000476837158
+ ],
+ "leftHandle": [
+ 1.5527966817220051,
+ 1.2000000476837158
+ ],
+ "rightHandle": [
+ 1.7968037923177083,
+ 1.2000000476837158
+ ]
+ },
+ {
+ "coords": [
+ 2.0416666666666665,
+ 0.550000011920929
+ ],
+ "leftHandle": [
+ 1.996956507364909,
+ 0.550000011920929
+ ],
+ "rightHandle": [
+ 2.0922622680664062,
+ 0.550000011920929
+ ]
+ },
+ {
+ "coords": [
+ 2.2083333333333335,
+ 1.0499999523162842
+ ],
+ "leftHandle": [
+ 2.119014104207357,
+ 1.0499999523162842
+ ],
+ "rightHandle": [
+ 2.2143192291259766,
+ 1.0499999523162842
+ ]
+ },
+ {
+ "coords": [
+ 2.3333333333333335,
+ 1.0
+ ],
+ "leftHandle": [
+ 2.2827377319335938,
+ 1.0
+ ],
+ "rightHandle": [
+ 2.3780434926350913,
+ 1.0
+ ]
+ },
+ {
+ "coords": [
+ 3.2916666666666665,
+ 1.0
+ ],
+ "leftHandle": [
+ 2.8758557637532554,
+ 1.0
+ ],
+ "rightHandle": [
+ 3.3638699849446616,
+ 1.0
+ ]
+ },
+ {
+ "coords": [
+ 3.5833333333333335,
+ 0.6000000238418579
+ ],
+ "leftHandle": [
+ 3.469463348388672,
+ 0.6000000238418579
+ ],
+ "rightHandle": [
+ 3.6972033182779946,
+ 0.6000000238418579
+ ]
+ },
+ {
+ "coords": [
+ 3.875,
+ 1.100000023841858
+ ],
+ "leftHandle": [
+ 3.719463348388672,
+ 1.100000023841858
+ ],
+ "rightHandle": [
+ 3.9472033182779946,
+ 1.100000023841858
+ ]
+ },
+ {
+ "coords": [
+ 4.125,
+ 0.800000011920929
+ ],
+ "leftHandle": [
+ 4.011130015055339,
+ 0.800000011920929
+ ],
+ "rightHandle": [
+ 4.206335703531901,
+ 0.800000011920929
+ ]
+ },
+ {
+ "coords": [
+ 4.375,
+ 1.0
+ ],
+ "leftHandle": [
+ 4.251997629801433,
+ 1.0
+ ],
+ "rightHandle": [
+ 4.414669036865234,
+ 1.0
+ ]
+ },
+ {
+ "coords": [
+ 4.583333333333333,
+ 1.0
+ ],
+ "leftHandle": [
+ 4.501997629801433,
+ 1.0
+ ],
+ "rightHandle": [
+ 4.664669036865234,
+ 1.0
+ ]
+ },
+ {
+ "coords": [
+ 4.791666666666667,
+ 0.8999999761581421
+ ],
+ "leftHandle": [
+ 4.668664296468099,
+ 0.8999999761581421
+ ],
+ "rightHandle": [
+ 4.831335703531901,
+ 0.8999999761581421
+ ]
+ },
+ {
+ "coords": [
+ 5.0,
+ 1.0499999523162842
+ ],
+ "leftHandle": [
+ 4.918664296468099,
+ 1.0499999523162842
+ ],
+ "rightHandle": [
+ 5.081335703531901,
+ 1.0499999523162842
+ ]
+ },
+ {
+ "coords": [
+ 5.208333333333333,
+ 0.8999999761581421
+ ],
+ "leftHandle": [
+ 5.085330963134766,
+ 0.8999999761581421
+ ],
+ "rightHandle": [
+ 5.2317352294921875,
+ 0.8999999761581421
+ ]
+ },
+ {
+ "coords": [
+ 5.375,
+ 1.0
+ ],
+ "leftHandle": [
+ 5.2682647705078125,
+ 1.0
+ ],
+ "rightHandle": [
+ 5.6586761474609375,
+ 1.0
+ ]
+ },
+ {
+ "coords": [
+ 6.208333333333333,
+ 1.0
+ ],
+ "leftHandle": [
+ 5.8413238525390625,
+ 1.0
+ ],
+ "rightHandle": [
+ 6.329338073730469,
+ 1.0
+ ]
+ },
+ {
+ "coords": [
+ 6.625,
+ 0.6000000238418579
+ ],
+ "leftHandle": [
+ 6.420661926269531,
+ 0.6000000238418579
+ ],
+ "rightHandle": [
+ 6.990011850992839,
+ 0.6000000238418579
+ ]
+ },
+ {
+ "coords": [
+ 6.791666666666667,
+ 0.6000000238418579
+ ],
+ "leftHandle": [
+ 6.384988149007161,
+ 0.6000000238418579
+ ],
+ "rightHandle": [
+ 6.905536651611328,
+ 0.6000000238418579
+ ]
+ },
+ {
+ "coords": [
+ 7.125,
+ 1.2000000476837158
+ ],
+ "leftHandle": [
+ 6.969463348388672,
+ 1.2000000476837158
+ ],
+ "rightHandle": [
+ 7.213470458984375,
+ 1.2000000476837158
+ ]
+ },
+ {
+ "coords": [
+ 7.458333333333333,
+ 0.800000011920929
+ ],
+ "leftHandle": [
+ 7.3353322347005205,
+ 1.0928102731704712
+ ],
+ "rightHandle": [
+ 7.4631195068359375,
+ 0.7886062860488892
+ ]
+ },
+ {
+ "coords": [
+ 7.458333333333333,
+ 0.550000011920929
+ ],
+ "leftHandle": [
+ 7.413622538248698,
+ 0.550000011920929
+ ],
+ "rightHandle": [
+ 7.508928934733073,
+ 0.550000011920929
+ ]
+ },
+ {
+ "coords": [
+ 7.625,
+ 1.0499999523162842
+ ],
+ "leftHandle": [
+ 7.5356801350911455,
+ 1.0499999523162842
+ ],
+ "rightHandle": [
+ 7.6309865315755205,
+ 1.0499999523162842
+ ]
+ },
+ {
+ "coords": [
+ 7.75,
+ 1.0
+ ],
+ "leftHandle": [
+ 7.699404398600261,
+ 1.0
+ ],
+ "rightHandle": [
+ 7.794710795084636,
+ 1.0
+ ]
+ },
+ {
+ "coords": [
+ 8.708333333333334,
+ 1.0
+ ],
+ "leftHandle": [
+ 8.292522430419922,
+ 1.0
+ ],
+ "rightHandle": [
+ 8.780536651611328,
+ 1.0
+ ]
+ },
+ {
+ "coords": [
+ 8.958333333333334,
+ 0.6000000238418579
+ ],
+ "leftHandle": [
+ 8.844463348388672,
+ 0.6000000238418579
+ ],
+ "rightHandle": [
+ 9.07220458984375,
+ 0.6000000238418579
+ ]
+ },
+ {
+ "coords": [
+ 9.291666666666666,
+ 1.100000023841858
+ ],
+ "leftHandle": [
+ 9.136128743489584,
+ 1.100000023841858
+ ],
+ "rightHandle": [
+ 9.363871256510416,
+ 1.100000023841858
+ ]
+ },
+ {
+ "coords": [
+ 9.541666666666666,
+ 0.800000011920929
+ ],
+ "leftHandle": [
+ 9.42779541015625,
+ 0.800000011920929
+ ],
+ "rightHandle": [
+ 9.623001098632812,
+ 0.800000011920929
+ ]
+ },
+ {
+ "coords": [
+ 9.791666666666666,
+ 1.0
+ ],
+ "leftHandle": [
+ 9.668665568033854,
+ 1.0
+ ],
+ "rightHandle": [
+ 9.831334431966146,
+ 1.0
+ ]
+ },
+ {
+ "coords": [
+ 10.0,
+ 1.0
+ ],
+ "leftHandle": [
+ 9.918665568033854,
+ 1.0
+ ],
+ "rightHandle": [
+ 10.081334431966146,
+ 1.0
+ ]
+ },
+ {
+ "coords": [
+ 10.208333333333334,
+ 0.8999999761581421
+ ],
+ "leftHandle": [
+ 10.085332234700521,
+ 0.8999999761581421
+ ],
+ "rightHandle": [
+ 10.248001098632812,
+ 0.8999999761581421
+ ]
+ },
+ {
+ "coords": [
+ 10.416666666666666,
+ 1.0499999523162842
+ ],
+ "leftHandle": [
+ 10.335332234700521,
+ 1.0499999523162842
+ ],
+ "rightHandle": [
+ 10.498001098632812,
+ 1.0499999523162842
+ ]
+ },
+ {
+ "coords": [
+ 10.625,
+ 0.8999999761581421
+ ],
+ "leftHandle": [
+ 10.501998901367188,
+ 0.8999999761581421
+ ],
+ "rightHandle": [
+ 10.648401896158854,
+ 0.8999999761581421
+ ]
+ },
+ {
+ "coords": [
+ 10.791666666666666,
+ 1.0
+ ],
+ "leftHandle": [
+ 10.684931437174479,
+ 1.0
+ ],
+ "rightHandle": [
+ 10.815068562825521,
+ 1.0
+ ]
+ }
+ ]
+ }
+ ],
+ "channelName": "Scale",
+ "jointIndex": 0
+ },
+ {
+ "channelComponents": [
+ {
+ "channelComponentName": "Rotation W",
+ "keyFrames": [
+ {
+ "coords": [
+ 0.0,
+ 1.0
+ ],
+ "leftHandle": [
+ -0.3090757727622986,
+ 1.0
+ ],
+ "rightHandle": [
+ 0.3090757528940837,
+ 1.0
+ ]
+ },
+ {
+ "coords": [
+ 0.7916666666666666,
+ 1.0
+ ],
+ "leftHandle": [
+ 0.482590913772583,
+ 1.0
+ ],
+ "rightHandle": [
+ 0.9543381532033285,
+ 1.0
+ ]
+ },
+ {
+ "coords": [
+ 1.2083333333333333,
+ 1.0
+ ],
+ "leftHandle": [
+ 1.0456618467966716,
+ 1.0
+ ],
+ "rightHandle": [
+ 1.2896690368652344,
+ 1.0
+ ]
+ },
+ {
+ "coords": [
+ 1.4166666666666667,
+ 1.0
+ ],
+ "leftHandle": [
+ 1.3353309631347656,
+ 1.0
+ ],
+ "rightHandle": [
+ 1.4817352294921875,
+ 1.0
+ ]
+ },
+ {
+ "coords": [
+ 1.5833333333333333,
+ 0.9848077893257141
+ ],
+ "leftHandle": [
+ 1.5182647705078125,
+ 0.9848077893257141
+ ],
+ "rightHandle": [
+ 1.6809361775716145,
+ 0.9848077893257141
+ ]
+ },
+ {
+ "coords": [
+ 1.8333333333333333,
+ 0.9961948394775391
+ ],
+ "leftHandle": [
+ 1.735730489095052,
+ 0.9930806159973145
+ ],
+ "rightHandle": [
+ 1.9146690368652344,
+ 0.9987900257110596
+ ]
+ },
+ {
+ "coords": [
+ 2.0416666666666665,
+ 1.000000238418579
+ ],
+ "leftHandle": [
+ 1.9603309631347656,
+ 1.000000238418579
+ ],
+ "rightHandle": [
+ 2.448345343271891,
+ 1.000000238418579
+ ]
+ },
+ {
+ "coords": [
+ 3.2916666666666665,
+ 1.000000238418579
+ ],
+ "leftHandle": [
+ 2.8036524454752603,
+ 1.000000238418579
+ ],
+ "rightHandle": [
+ 3.405536651611328,
+ 1.000000238418579
+ ]
+ },
+ {
+ "coords": [
+ 3.5833333333333335,
+ 1.000000238418579
+ ],
+ "leftHandle": [
+ 3.469463348388672,
+ 1.000000238418579
+ ],
+ "rightHandle": [
+ 3.6972033182779946,
+ 1.000000238418579
+ ]
+ },
+ {
+ "coords": [
+ 3.875,
+ 0.8191520571708679
+ ],
+ "leftHandle": [
+ 3.7611300150553384,
+ 0.9475935697555542
+ ],
+ "rightHandle": [
+ 3.9888699849446616,
+ 0.6907105445861816
+ ]
+ },
+ {
+ "coords": [
+ 4.166666666666667,
+ 0.3420201539993286
+ ],
+ "leftHandle": [
+ 4.052796681722005,
+ 0.3420201539993286
+ ],
+ "rightHandle": [
+ 4.248002370198567,
+ 0.3420201539993286
+ ]
+ },
+ {
+ "coords": [
+ 4.375,
+ 0.3420201539993286
+ ],
+ "leftHandle": [
+ 4.293664296468099,
+ 0.3420201539993286
+ ],
+ "rightHandle": [
+ 4.456335703531901,
+ 0.3420201539993286
+ ]
+ },
+ {
+ "coords": [
+ 4.583333333333333,
+ 0.3420201539993286
+ ],
+ "leftHandle": [
+ 4.501997629801433,
+ 0.3420201539993286
+ ],
+ "rightHandle": [
+ 4.664669036865234,
+ 0.3420201539993286
+ ]
+ },
+ {
+ "coords": [
+ 4.791666666666667,
+ 0.3420201539993286
+ ],
+ "leftHandle": [
+ 4.710330963134766,
+ 0.3420201539993286
+ ],
+ "rightHandle": [
+ 4.873002370198567,
+ 0.3420201539993286
+ ]
+ },
+ {
+ "coords": [
+ 5.0,
+ 0.17364823818206787
+ ],
+ "leftHandle": [
+ 4.918664296468099,
+ 0.24041254818439484
+ ],
+ "rightHandle": [
+ 5.081335703531901,
+ 0.1068839281797409
+ ]
+ },
+ {
+ "coords": [
+ 5.208333333333333,
+ -5.960464477539063e-08
+ ],
+ "leftHandle": [
+ 5.126997629801433,
+ -5.960464477539063e-08
+ ],
+ "rightHandle": [
+ 5.598744710286458,
+ -5.960464477539063e-08
+ ]
+ },
+ {
+ "coords": [
+ 6.208333333333333,
+ 0.0
+ ],
+ "leftHandle": [
+ 5.817921956380208,
+ -5.960464477539063e-08
+ ],
+ "rightHandle": [
+ 6.371004740397136,
+ 2.4835268064293814e-08
+ ]
+ },
+ {
+ "coords": [
+ 6.625,
+ 2.384185791015625e-07
+ ],
+ "leftHandle": [
+ 6.462328592936198,
+ 2.384185791015625e-07
+ ],
+ "rightHandle": [
+ 7.031678517659505,
+ 2.384185791015625e-07
+ ]
+ },
+ {
+ "coords": [
+ 6.833333333333333,
+ 2.384185791015625e-07
+ ],
+ "leftHandle": [
+ 6.5079905192057295,
+ 2.384185791015625e-07
+ ],
+ "rightHandle": [
+ 6.8984018961588545,
+ 2.384185791015625e-07
+ ]
+ },
+ {
+ "coords": [
+ 7.0,
+ 1.9185245037078857e-07
+ ],
+ "leftHandle": [
+ 6.9349314371744795,
+ 1.9185245037078857e-07
+ ],
+ "rightHandle": [
+ 7.097602844238281,
+ 1.9185245037078857e-07
+ ]
+ },
+ {
+ "coords": [
+ 7.25,
+ -4.353933036327362e-08
+ ],
+ "leftHandle": [
+ 7.152397155761719,
+ 0.003114179940894246
+ ],
+ "rightHandle": [
+ 7.331335703531901,
+ -0.0025952300056815147
+ ]
+ },
+ {
+ "coords": [
+ 7.458333333333333,
+ 0.0
+ ],
+ "leftHandle": [
+ 7.376997629801433,
+ 0.0
+ ],
+ "rightHandle": [
+ 7.865011850992839,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 8.708333333333334,
+ 0.0
+ ],
+ "leftHandle": [
+ 8.220319112141928,
+ 0.0
+ ],
+ "rightHandle": [
+ 8.82220458984375,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 9.0,
+ 0.0
+ ],
+ "leftHandle": [
+ 8.886128743489584,
+ 0.0
+ ],
+ "rightHandle": [
+ 9.113871256510416,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 9.291666666666666,
+ 0.5735764503479004
+ ],
+ "leftHandle": [
+ 9.178207397460938,
+ 0.3380364775657654
+ ],
+ "rightHandle": [
+ 9.428712209065756,
+ 0.8580812215805054
+ ]
+ },
+ {
+ "coords": [
+ 9.583333333333334,
+ 0.9396926164627075
+ ],
+ "leftHandle": [
+ 9.469462076822916,
+ 0.9396926164627075
+ ],
+ "rightHandle": [
+ 9.664667765299479,
+ 0.9396926164627075
+ ]
+ },
+ {
+ "coords": [
+ 9.791666666666666,
+ 0.9396926164627075
+ ],
+ "leftHandle": [
+ 9.710332234700521,
+ 0.9396926164627075
+ ],
+ "rightHandle": [
+ 9.873001098632812,
+ 0.9396926164627075
+ ]
+ },
+ {
+ "coords": [
+ 10.0,
+ 0.9396926164627075
+ ],
+ "leftHandle": [
+ 9.918665568033854,
+ 0.9396926164627075
+ ],
+ "rightHandle": [
+ 10.081334431966146,
+ 0.9396926164627075
+ ]
+ },
+ {
+ "coords": [
+ 10.208333333333334,
+ 0.9396926164627075
+ ],
+ "leftHandle": [
+ 10.126998901367188,
+ 0.9396926164627075
+ ],
+ "rightHandle": [
+ 10.289667765299479,
+ 0.9396926164627075
+ ]
+ },
+ {
+ "coords": [
+ 10.416666666666666,
+ 0.9848077297210693
+ ],
+ "leftHandle": [
+ 10.335332234700521,
+ 0.9627091884613037
+ ],
+ "rightHandle": [
+ 10.498001098632812,
+ 1.006906270980835
+ ]
+ },
+ {
+ "coords": [
+ 10.625,
+ 1.0
+ ],
+ "leftHandle": [
+ 10.543665568033854,
+ 1.0
+ ],
+ "rightHandle": [
+ 10.706334431966146,
+ 1.0
+ ]
+ }
+ ]
+ },
+ {
+ "channelComponentName": "Rotation X",
+ "keyFrames": [
+ {
+ "coords": [
+ 0.0,
+ 0.0
+ ],
+ "leftHandle": [
+ -0.3090757727622986,
+ 0.0
+ ],
+ "rightHandle": [
+ 0.3090757528940837,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 0.7916666666666666,
+ 0.0
+ ],
+ "leftHandle": [
+ 0.482590913772583,
+ 0.0
+ ],
+ "rightHandle": [
+ 0.9543381532033285,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 1.2083333333333333,
+ 0.0
+ ],
+ "leftHandle": [
+ 1.0456618467966716,
+ 0.0
+ ],
+ "rightHandle": [
+ 1.2896690368652344,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 1.4166666666666667,
+ 0.0
+ ],
+ "leftHandle": [
+ 1.3353309631347656,
+ 0.0
+ ],
+ "rightHandle": [
+ 1.4817352294921875,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 1.5833333333333333,
+ 0.0
+ ],
+ "leftHandle": [
+ 1.5182647705078125,
+ 0.0
+ ],
+ "rightHandle": [
+ 1.6809361775716145,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 1.8333333333333333,
+ 0.0
+ ],
+ "leftHandle": [
+ 1.735730489095052,
+ 0.0
+ ],
+ "rightHandle": [
+ 1.9146690368652344,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 2.0416666666666665,
+ 0.0
+ ],
+ "leftHandle": [
+ 1.9603309631347656,
+ 0.0
+ ],
+ "rightHandle": [
+ 2.448345343271891,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 3.2916666666666665,
+ 0.0
+ ],
+ "leftHandle": [
+ 2.8036524454752603,
+ 0.0
+ ],
+ "rightHandle": [
+ 3.405536651611328,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 3.5833333333333335,
+ 0.0
+ ],
+ "leftHandle": [
+ 3.469463348388672,
+ 0.0
+ ],
+ "rightHandle": [
+ 3.6972033182779946,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 3.875,
+ 4.2734766836360905e-09
+ ],
+ "leftHandle": [
+ 3.7611300150553384,
+ 2.906791696233313e-09
+ ],
+ "rightHandle": [
+ 3.9888699849446616,
+ 5.640161671038868e-09
+ ]
+ },
+ {
+ "coords": [
+ 4.166666666666667,
+ 7.001254243022004e-09
+ ],
+ "leftHandle": [
+ 4.052796681722005,
+ 7.001254243022004e-09
+ ],
+ "rightHandle": [
+ 4.248002370198567,
+ 7.001254243022004e-09
+ ]
+ },
+ {
+ "coords": [
+ 4.375,
+ 7.001254243022004e-09
+ ],
+ "leftHandle": [
+ 4.293664296468099,
+ 7.001254243022004e-09
+ ],
+ "rightHandle": [
+ 4.456335703531901,
+ 7.001254243022004e-09
+ ]
+ },
+ {
+ "coords": [
+ 4.583333333333333,
+ 7.001254243022004e-09
+ ],
+ "leftHandle": [
+ 4.501997629801433,
+ 7.001254243022004e-09
+ ],
+ "rightHandle": [
+ 4.664669036865234,
+ 7.001254243022004e-09
+ ]
+ },
+ {
+ "coords": [
+ 4.791666666666667,
+ 7.001254243022004e-09
+ ],
+ "leftHandle": [
+ 4.710330963134766,
+ 7.001254243022004e-09
+ ],
+ "rightHandle": [
+ 4.873002370198567,
+ 7.001254243022004e-09
+ ]
+ },
+ {
+ "coords": [
+ 5.0,
+ 7.337388030492775e-09
+ ],
+ "leftHandle": [
+ 4.918664296468099,
+ 7.249677302922919e-09
+ ],
+ "rightHandle": [
+ 5.081335703531901,
+ 7.4250987580626315e-09
+ ]
+ },
+ {
+ "coords": [
+ 5.208333333333333,
+ 7.450578376477779e-09
+ ],
+ "leftHandle": [
+ 5.126997629801433,
+ 7.450578376477779e-09
+ ],
+ "rightHandle": [
+ 5.598744710286458,
+ 7.450578376477779e-09
+ ]
+ },
+ {
+ "coords": [
+ 6.208333333333333,
+ 0.0
+ ],
+ "leftHandle": [
+ 5.817921956380208,
+ 0.0
+ ],
+ "rightHandle": [
+ 6.371004740397136,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 6.625,
+ 0.0
+ ],
+ "leftHandle": [
+ 6.462328592936198,
+ 0.0
+ ],
+ "rightHandle": [
+ 6.706335703531901,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 6.833333333333333,
+ 0.0
+ ],
+ "leftHandle": [
+ 6.751997629801433,
+ 0.0
+ ],
+ "rightHandle": [
+ 6.8984018961588545,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 7.0,
+ -0.1736481785774231
+ ],
+ "leftHandle": [
+ 6.9349314371744795,
+ -0.1736481785774231
+ ],
+ "rightHandle": [
+ 7.097602844238281,
+ -0.1736481785774231
+ ]
+ },
+ {
+ "coords": [
+ 7.25,
+ 0.08715573698282242
+ ],
+ "leftHandle": [
+ 7.152397155761719,
+ 0.08715573698282242
+ ],
+ "rightHandle": [
+ 7.331335703531901,
+ 0.08715573698282242
+ ]
+ },
+ {
+ "coords": [
+ 7.458333333333333,
+ 0.0
+ ],
+ "leftHandle": [
+ 7.376997629801433,
+ 0.0
+ ],
+ "rightHandle": [
+ 7.865011850992839,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 8.708333333333334,
+ 0.0
+ ],
+ "leftHandle": [
+ 8.220319112141928,
+ 0.0
+ ],
+ "rightHandle": [
+ 8.822203318277994,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 9.0,
+ 0.0
+ ],
+ "leftHandle": [
+ 8.886130015055338,
+ 0.0
+ ],
+ "rightHandle": [
+ 9.113869984944662,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 9.291666666666666,
+ -2.410053712154081e-09
+ ],
+ "leftHandle": [
+ 9.177796681722006,
+ -1.8343819796484695e-09
+ ],
+ "rightHandle": [
+ 9.405536651611328,
+ -2.9857254446596926e-09
+ ]
+ },
+ {
+ "coords": [
+ 9.583333333333334,
+ -2.9857254446596926e-09
+ ],
+ "leftHandle": [
+ 9.469463348388672,
+ -2.9857254446596926e-09
+ ],
+ "rightHandle": [
+ 9.664669036865234,
+ -2.9857254446596926e-09
+ ]
+ },
+ {
+ "coords": [
+ 9.791666666666666,
+ -2.9857254446596926e-09
+ ],
+ "leftHandle": [
+ 9.710330963134766,
+ -2.9857254446596926e-09
+ ],
+ "rightHandle": [
+ 9.873002370198568,
+ -2.9857254446596926e-09
+ ]
+ },
+ {
+ "coords": [
+ 10.0,
+ -2.9857254446596926e-09
+ ],
+ "leftHandle": [
+ 9.9186642964681,
+ -2.9857254446596926e-09
+ ],
+ "rightHandle": [
+ 10.0813357035319,
+ -2.9857254446596926e-09
+ ]
+ },
+ {
+ "coords": [
+ 10.208333333333334,
+ -2.9857254446596926e-09
+ ],
+ "leftHandle": [
+ 10.126997629801432,
+ -2.9857254446596926e-09
+ ],
+ "rightHandle": [
+ 10.289669036865234,
+ -2.9857254446596926e-09
+ ]
+ },
+ {
+ "coords": [
+ 10.416666666666666,
+ -1.5745631465335919e-09
+ ],
+ "leftHandle": [
+ 10.335330963134766,
+ -2.2619428552417276e-09
+ ],
+ "rightHandle": [
+ 10.498002370198568,
+ -8.871833823143049e-10
+ ]
+ },
+ {
+ "coords": [
+ 10.625,
+ 5.355835774878415e-10
+ ],
+ "leftHandle": [
+ 10.5436642964681,
+ 5.355835774878415e-10
+ ],
+ "rightHandle": [
+ 10.7063357035319,
+ 5.355835774878415e-10
+ ]
+ }
+ ]
+ },
+ {
+ "channelComponentName": "Rotation Z",
+ "keyFrames": [
+ {
+ "coords": [
+ 0.0,
+ -0.0
+ ],
+ "leftHandle": [
+ -0.3090757727622986,
+ -0.0
+ ],
+ "rightHandle": [
+ 0.3090757528940837,
+ -0.0
+ ]
+ },
+ {
+ "coords": [
+ 0.7916666666666666,
+ -0.0
+ ],
+ "leftHandle": [
+ 0.482590913772583,
+ -0.0
+ ],
+ "rightHandle": [
+ 0.9543381532033285,
+ -0.0
+ ]
+ },
+ {
+ "coords": [
+ 1.2083333333333333,
+ -0.0
+ ],
+ "leftHandle": [
+ 1.0456618467966716,
+ -0.0
+ ],
+ "rightHandle": [
+ 1.2896690368652344,
+ -0.0
+ ]
+ },
+ {
+ "coords": [
+ 1.4166666666666667,
+ -0.0
+ ],
+ "leftHandle": [
+ 1.3353309631347656,
+ -0.0
+ ],
+ "rightHandle": [
+ 1.4817352294921875,
+ -0.0
+ ]
+ },
+ {
+ "coords": [
+ 1.5833333333333333,
+ -0.1736481785774231
+ ],
+ "leftHandle": [
+ 1.5182647705078125,
+ -0.1736481785774231
+ ],
+ "rightHandle": [
+ 1.6809361775716145,
+ -0.1736481785774231
+ ]
+ },
+ {
+ "coords": [
+ 1.8333333333333333,
+ 0.08715575933456421
+ ],
+ "leftHandle": [
+ 1.735730489095052,
+ 0.08715575933456421
+ ],
+ "rightHandle": [
+ 1.9146690368652344,
+ 0.08715575933456421
+ ]
+ },
+ {
+ "coords": [
+ 2.0416666666666665,
+ 7.450580596923828e-09
+ ],
+ "leftHandle": [
+ 1.9603309631347656,
+ 7.450580596923828e-09
+ ],
+ "rightHandle": [
+ 2.448345343271891,
+ 7.450580596923828e-09
+ ]
+ },
+ {
+ "coords": [
+ 3.2916666666666665,
+ 7.450580596923828e-09
+ ],
+ "leftHandle": [
+ 2.8036524454752603,
+ 7.450580596923828e-09
+ ],
+ "rightHandle": [
+ 3.405536651611328,
+ 7.450580596923828e-09
+ ]
+ },
+ {
+ "coords": [
+ 3.5833333333333335,
+ 7.450580596923828e-09
+ ],
+ "leftHandle": [
+ 3.469463348388672,
+ 7.450580596923828e-09
+ ],
+ "rightHandle": [
+ 3.6972033182779946,
+ 7.450580596923828e-09
+ ]
+ },
+ {
+ "coords": [
+ 3.875,
+ 6.1031566467306675e-09
+ ],
+ "leftHandle": [
+ 3.7611300150553384,
+ 7.060120044144469e-09
+ ],
+ "rightHandle": [
+ 3.9888699849446616,
+ 5.146193249316866e-09
+ ]
+ },
+ {
+ "coords": [
+ 4.166666666666667,
+ 2.5482482790550876e-09
+ ],
+ "leftHandle": [
+ 4.052796681722005,
+ 2.5482482790550876e-09
+ ],
+ "rightHandle": [
+ 4.248002370198567,
+ 2.5482482790550876e-09
+ ]
+ },
+ {
+ "coords": [
+ 4.375,
+ 2.5482482790550876e-09
+ ],
+ "leftHandle": [
+ 4.293664296468099,
+ 2.5482482790550876e-09
+ ],
+ "rightHandle": [
+ 4.456335703531901,
+ 2.5482482790550876e-09
+ ]
+ },
+ {
+ "coords": [
+ 4.583333333333333,
+ 2.5482482790550876e-09
+ ],
+ "leftHandle": [
+ 4.501997629801433,
+ 2.5482482790550876e-09
+ ],
+ "rightHandle": [
+ 4.664669036865234,
+ 2.5482482790550876e-09
+ ]
+ },
+ {
+ "coords": [
+ 4.791666666666667,
+ 2.5482482790550876e-09
+ ],
+ "leftHandle": [
+ 4.710330963134766,
+ 2.5482482790550876e-09
+ ],
+ "rightHandle": [
+ 4.873002370198567,
+ 2.5482482790550876e-09
+ ]
+ },
+ {
+ "coords": [
+ 5.0,
+ 1.2937797500001125e-09
+ ],
+ "leftHandle": [
+ 4.918664296468099,
+ 1.7912125116481548e-09
+ ],
+ "rightHandle": [
+ 5.081335703531901,
+ 7.96346932840919e-10
+ ]
+ },
+ {
+ "coords": [
+ 5.208333333333333,
+ -4.440892098500626e-16
+ ],
+ "leftHandle": [
+ 5.126997629801433,
+ -4.440892098500626e-16
+ ],
+ "rightHandle": [
+ 5.598744710286458,
+ -4.440892098500626e-16
+ ]
+ },
+ {
+ "coords": [
+ 6.208333333333333,
+ -0.0
+ ],
+ "leftHandle": [
+ 5.817921956380208,
+ -0.0
+ ],
+ "rightHandle": [
+ 6.371004740397136,
+ -0.0
+ ]
+ },
+ {
+ "coords": [
+ 6.625,
+ -0.0
+ ],
+ "leftHandle": [
+ 6.462328592936198,
+ -0.0
+ ],
+ "rightHandle": [
+ 6.706335703531901,
+ -0.0
+ ]
+ },
+ {
+ "coords": [
+ 6.833333333333333,
+ -0.0
+ ],
+ "leftHandle": [
+ 6.751997629801433,
+ -0.0
+ ],
+ "rightHandle": [
+ 6.8984018961588545,
+ -0.0
+ ]
+ },
+ {
+ "coords": [
+ 7.0,
+ 2.9802322387695312e-08
+ ],
+ "leftHandle": [
+ 6.9349314371744795,
+ 2.9802322387695312e-08
+ ],
+ "rightHandle": [
+ 7.097602844238281,
+ 2.9802322387695312e-08
+ ]
+ },
+ {
+ "coords": [
+ 7.25,
+ -7.450580596923828e-09
+ ],
+ "leftHandle": [
+ 7.152397155761719,
+ -7.450580596923828e-09
+ ],
+ "rightHandle": [
+ 7.331335703531901,
+ -7.450580596923828e-09
+ ]
+ },
+ {
+ "coords": [
+ 7.458333333333333,
+ 7.450580596923828e-09
+ ],
+ "leftHandle": [
+ 7.376997629801433,
+ 7.450580596923828e-09
+ ],
+ "rightHandle": [
+ 7.865011850992839,
+ 7.450580596923828e-09
+ ]
+ },
+ {
+ "coords": [
+ 8.708333333333334,
+ 7.450580596923828e-09
+ ],
+ "leftHandle": [
+ 8.220319112141928,
+ 7.450580596923828e-09
+ ],
+ "rightHandle": [
+ 8.822203318277994,
+ 7.450580596923828e-09
+ ]
+ },
+ {
+ "coords": [
+ 9.0,
+ 7.450580596923828e-09
+ ],
+ "leftHandle": [
+ 8.886130015055338,
+ 7.450580596923828e-09
+ ],
+ "rightHandle": [
+ 9.113869984944662,
+ 7.450580596923828e-09
+ ]
+ },
+ {
+ "coords": [
+ 9.291666666666666,
+ 1.0482139600753726e-08
+ ],
+ "leftHandle": [
+ 9.177796681722006,
+ 8.819545094240766e-09
+ ],
+ "rightHandle": [
+ 9.405536651611328,
+ 1.2144734107266686e-08
+ ]
+ },
+ {
+ "coords": [
+ 9.583333333333334,
+ 1.5967721367360355e-08
+ ],
+ "leftHandle": [
+ 9.469463348388672,
+ 1.5967721367360355e-08
+ ],
+ "rightHandle": [
+ 9.664669036865234,
+ 1.5967721367360355e-08
+ ]
+ },
+ {
+ "coords": [
+ 9.791666666666666,
+ 1.5967721367360355e-08
+ ],
+ "leftHandle": [
+ 9.710330963134766,
+ 1.5967721367360355e-08
+ ],
+ "rightHandle": [
+ 9.873002370198568,
+ 1.5967721367360355e-08
+ ]
+ },
+ {
+ "coords": [
+ 10.0,
+ 1.5967721367360355e-08
+ ],
+ "leftHandle": [
+ 9.9186642964681,
+ 1.5967721367360355e-08
+ ],
+ "rightHandle": [
+ 10.0813357035319,
+ 1.5967721367360355e-08
+ ]
+ },
+ {
+ "coords": [
+ 10.208333333333334,
+ 1.5967721367360355e-08
+ ],
+ "leftHandle": [
+ 10.126997629801432,
+ 1.5967721367360355e-08
+ ],
+ "rightHandle": [
+ 10.289669036865234,
+ 1.5967721367360355e-08
+ ]
+ },
+ {
+ "coords": [
+ 10.416666666666666,
+ 1.7476175173669617e-08
+ ],
+ "leftHandle": [
+ 10.335330963134766,
+ 1.7084600401062744e-08
+ ],
+ "rightHandle": [
+ 10.498002370198568,
+ 1.786774994627649e-08
+ ]
+ },
+ {
+ "coords": [
+ 10.625,
+ 1.7973679433680445e-08
+ ],
+ "leftHandle": [
+ 10.5436642964681,
+ 1.7973679433680445e-08
+ ],
+ "rightHandle": [
+ 10.7063357035319,
+ 1.7973679433680445e-08
+ ]
+ }
+ ]
+ },
+ {
+ "channelComponentName": "Rotation Y",
+ "keyFrames": [
+ {
+ "coords": [
+ 0.0,
+ 0.0
+ ],
+ "leftHandle": [
+ -0.3090757727622986,
+ 0.0
+ ],
+ "rightHandle": [
+ 0.3090757528940837,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 0.7916666666666666,
+ 0.0
+ ],
+ "leftHandle": [
+ 0.482590913772583,
+ 0.0
+ ],
+ "rightHandle": [
+ 0.9543381532033285,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 1.2083333333333333,
+ 0.0
+ ],
+ "leftHandle": [
+ 1.0456618467966716,
+ 0.0
+ ],
+ "rightHandle": [
+ 1.2896690368652344,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 1.4166666666666667,
+ 0.0
+ ],
+ "leftHandle": [
+ 1.3353309631347656,
+ 0.0
+ ],
+ "rightHandle": [
+ 1.4817352294921875,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 1.5833333333333333,
+ 0.0
+ ],
+ "leftHandle": [
+ 1.5182647705078125,
+ 0.0
+ ],
+ "rightHandle": [
+ 1.6809361775716145,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 1.8333333333333333,
+ 0.0
+ ],
+ "leftHandle": [
+ 1.735730489095052,
+ 0.0
+ ],
+ "rightHandle": [
+ 1.9146690368652344,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 2.0416666666666665,
+ 0.0
+ ],
+ "leftHandle": [
+ 1.9603309631347656,
+ 0.0
+ ],
+ "rightHandle": [
+ 2.448345343271891,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 3.2916666666666665,
+ 0.0
+ ],
+ "leftHandle": [
+ 2.8036524454752603,
+ 0.0
+ ],
+ "rightHandle": [
+ 3.405536651611328,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 3.5833333333333335,
+ 0.0
+ ],
+ "leftHandle": [
+ 3.469463348388672,
+ 0.0
+ ],
+ "rightHandle": [
+ 3.6972033182779946,
+ 0.0
+ ]
+ },
+ {
+ "coords": [
+ 3.875,
+ 0.5735764503479004
+ ],
+ "leftHandle": [
+ 3.7611300150553384,
+ 0.3901430368423462
+ ],
+ "rightHandle": [
+ 3.9888699849446616,
+ 0.7570098638534546
+ ]
+ },
+ {
+ "coords": [
+ 4.166666666666667,
+ 0.9396926164627075
+ ],
+ "leftHandle": [
+ 4.052796681722005,
+ 0.9396926164627075
+ ],
+ "rightHandle": [
+ 4.248002370198567,
+ 0.9396926164627075
+ ]
+ },
+ {
+ "coords": [
+ 4.375,
+ 0.9396926164627075
+ ],
+ "leftHandle": [
+ 4.293664296468099,
+ 0.9396926164627075
+ ],
+ "rightHandle": [
+ 4.456335703531901,
+ 0.9396926164627075
+ ]
+ },
+ {
+ "coords": [
+ 4.583333333333333,
+ 0.9396926164627075
+ ],
+ "leftHandle": [
+ 4.501997629801433,
+ 0.9396926164627075
+ ],
+ "rightHandle": [
+ 4.664669036865234,
+ 0.9396926164627075
+ ]
+ },
+ {
+ "coords": [
+ 4.791666666666667,
+ 0.9396926164627075
+ ],
+ "leftHandle": [
+ 4.710330963134766,
+ 0.9396926164627075
+ ],
+ "rightHandle": [
+ 4.873002370198567,
+ 0.9396926164627075
+ ]
+ },
+ {
+ "coords": [
+ 5.0,
+ 0.9848077297210693
+ ],
+ "leftHandle": [
+ 4.918664296468099,
+ 0.9730353951454163
+ ],
+ "rightHandle": [
+ 5.081335703531901,
+ 0.9965800642967224
+ ]
+ },
+ {
+ "coords": [
+ 5.208333333333333,
+ 1.0
+ ],
+ "leftHandle": [
+ 5.126997629801433,
+ 1.0
+ ],
+ "rightHandle": [
+ 5.598744710286458,
+ 1.0
+ ]
+ },
+ {
+ "coords": [
+ 6.208333333333333,
+ 1.0
+ ],
+ "leftHandle": [
+ 5.817921956380208,
+ 1.0
+ ],
+ "rightHandle": [
+ 6.371004740397136,
+ 1.0
+ ]
+ },
+ {
+ "coords": [
+ 6.625,
+ 1.000000238418579
+ ],
+ "leftHandle": [
+ 6.462328592936198,
+ 1.000000238418579
+ ],
+ "rightHandle": [
+ 7.031678517659505,
+ 1.000000238418579
+ ]
+ },
+ {
+ "coords": [
+ 6.833333333333333,
+ 1.000000238418579
+ ],
+ "leftHandle": [
+ 6.5079905192057295,
+ 1.000000238418579
+ ],
+ "rightHandle": [
+ 6.8984018961588545,
+ 1.000000238418579
+ ]
+ },
+ {
+ "coords": [
+ 7.0,
+ 1.0
+ ],
+ "leftHandle": [
+ 6.9349314371744795,
+ 1.0
+ ],
+ "rightHandle": [
+ 7.097605387369792,
+ 1.0
+ ]
+ },
+ {
+ "coords": [
+ 7.25,
+ 1.0
+ ],
+ "leftHandle": [
+ 7.152397155761719,
+ 1.0
+ ],
+ "rightHandle": [
+ 7.331335703531901,
+ 1.0
+ ]
+ },
+ {
+ "coords": [
+ 7.458333333333333,
+ 1.000000238418579
+ ],
+ "leftHandle": [
+ 7.376997629801433,
+ 1.000000238418579
+ ],
+ "rightHandle": [
+ 7.865011850992839,
+ 1.000000238418579
+ ]
+ },
+ {
+ "coords": [
+ 8.708333333333334,
+ 1.000000238418579
+ ],
+ "leftHandle": [
+ 8.220319112141928,
+ 1.000000238418579
+ ],
+ "rightHandle": [
+ 8.82220458984375,
+ 1.000000238418579
+ ]
+ },
+ {
+ "coords": [
+ 9.0,
+ 1.000000238418579
+ ],
+ "leftHandle": [
+ 8.886128743489584,
+ 1.000000238418579
+ ],
+ "rightHandle": [
+ 9.113871256510416,
+ 1.000000238418579
+ ]
+ },
+ {
+ "coords": [
+ 9.291666666666666,
+ 0.8191520571708679
+ ],
+ "leftHandle": [
+ 9.17779541015625,
+ 0.932508647441864
+ ],
+ "rightHandle": [
+ 9.405537923177084,
+ 0.7057954668998718
+ ]
+ },
+ {
+ "coords": [
+ 9.583333333333334,
+ 0.3420201241970062
+ ],
+ "leftHandle": [
+ 9.469462076822916,
+ 0.3420201241970062
+ ],
+ "rightHandle": [
+ 9.664667765299479,
+ 0.3420201241970062
+ ]
+ },
+ {
+ "coords": [
+ 9.791666666666666,
+ 0.3420201241970062
+ ],
+ "leftHandle": [
+ 9.710332234700521,
+ 0.3420201241970062
+ ],
+ "rightHandle": [
+ 9.873001098632812,
+ 0.3420201241970062
+ ]
+ },
+ {
+ "coords": [
+ 10.0,
+ 0.3420201241970062
+ ],
+ "leftHandle": [
+ 9.918665568033854,
+ 0.3420201241970062
+ ],
+ "rightHandle": [
+ 10.081334431966146,
+ 0.3420201241970062
+ ]
+ },
+ {
+ "coords": [
+ 10.208333333333334,
+ 0.3420201241970062
+ ],
+ "leftHandle": [
+ 10.126998901367188,
+ 0.3420201241970062
+ ],
+ "rightHandle": [
+ 10.289667765299479,
+ 0.3420201241970062
+ ]
+ },
+ {
+ "coords": [
+ 10.416666666666666,
+ 0.1736481785774231
+ ],
+ "leftHandle": [
+ 10.335413614908854,
+ 0.2643083930015564
+ ],
+ "rightHandle": [
+ 10.498001098632812,
+ 0.08289717137813568
+ ]
+ },
+ {
+ "coords": [
+ 10.625,
+ 0.0
+ ],
+ "leftHandle": [
+ 10.543665568033854,
+ 0.0
+ ],
+ "rightHandle": [
+ 10.706334431966146,
+ 0.0
+ ]
+ }
+ ]
+ }
+ ],
+ "channelName": "Rotation",
+ "jointIndex": 0
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/manual/skinned-mesh/main.cpp b/tests/manual/skinned-mesh/main.cpp
index dba6e0bff..8e2ebcbfb 100644
--- a/tests/manual/skinned-mesh/main.cpp
+++ b/tests/manual/skinned-mesh/main.cpp
@@ -49,12 +49,14 @@
****************************************************************************/
#include <Qt3DQuickExtras/qt3dquickwindow.h>
+#include <Qt3DAnimation/QAnimationAspect>
#include <QGuiApplication>
int main(int argc, char* argv[])
{
QGuiApplication app(argc, argv);
Qt3DExtras::Quick::Qt3DQuickWindow view;
+ view.registerAspect(new Qt3DAnimation::QAnimationAspect());
view.setSource(QUrl("qrc:/main.qml"));
view.show();
diff --git a/tests/manual/skinned-mesh/main.qml b/tests/manual/skinned-mesh/main.qml
index 6e8adbf50..174d54f83 100644
--- a/tests/manual/skinned-mesh/main.qml
+++ b/tests/manual/skinned-mesh/main.qml
@@ -51,6 +51,7 @@
import Qt3D.Core 2.10
import Qt3D.Render 2.10
import Qt3D.Input 2.0
+import Qt3D.Animation 2.10
import Qt3D.Extras 2.10
import QtQuick 2.9
@@ -61,10 +62,150 @@ DefaultSceneEntity {
id: skinnedPbrEffect
}
+ Timer {
+ interval: 2000
+ running: true
+ repeat: false
+ onTriggered: {
+ animator1.running = true
+ animator2.running = true
+ animator3.running = true
+ animator4.running = true
+ animator5.running = true
+ }
+ }
+
+ SkinnedEntity {
+ id: riggedFigure1
+ effect: skinnedPbrEffect
+ source: "qrc:/assets/gltf/2.0/RiggedFigure/RiggedFigure.gltf"
+ baseColor: "red"
+
+ components: [
+// ClipAnimator {
+// loops: 3
+// clip: AnimationClipLoader { source: "qrc:/jump.json" }
+// channelMapper: ChannelMapper {
+// mappings: [
+// SkeletonChannelMapping { target: riggedFigure.skeleton }
+// ]
+// }
+// }
+ BlendedClipAnimator {
+ id: animator1
+ loops: 5
+ blendTree: ClipBlendValue {
+ clip: AnimationClipLoader { source: "qrc:/jump.json" }
+ }
+ channelMapper: ChannelMapper {
+ mappings: [
+ SkeletonMapping { skeleton: riggedFigure1.skeleton }
+ ]
+ }
+
+ onRunningChanged: console.log("running = " + running)
+ }
+ ]
+ }
+
SkinnedEntity {
- id: riggedFigure
+ id: riggedFigure2
effect: skinnedPbrEffect
source: "qrc:/assets/gltf/2.0/RiggedFigure/RiggedFigure.gltf"
+ baseColor: "purple"
+ transform.translation: Qt.vector3d(0.0, 0.0, -1.0);
+
+ components: [
+ BlendedClipAnimator {
+ id: animator2
+ loops: 5
+ blendTree: ClipBlendValue {
+ clip: AnimationClipLoader { source: "qrc:/jump.json" }
+ }
+ channelMapper: ChannelMapper {
+ mappings: [
+ SkeletonMapping { skeleton: riggedFigure2.skeleton }
+ ]
+ }
+
+ onRunningChanged: console.log("running = " + running)
+ }
+ ]
+ }
+
+ SkinnedEntity {
+ id: riggedFigure3
+ effect: skinnedPbrEffect
+ source: "qrc:/assets/gltf/2.0/RiggedFigure/RiggedFigure.gltf"
+ baseColor: "blue"
+ transform.translation: Qt.vector3d(0.0, 0.0, -2.0);
+
+ components: [
+ BlendedClipAnimator {
+ id: animator3
+ loops: 5
+ blendTree: ClipBlendValue {
+ clip: AnimationClipLoader { source: "qrc:/jump.json" }
+ }
+ channelMapper: ChannelMapper {
+ mappings: [
+ SkeletonMapping { skeleton: riggedFigure3.skeleton }
+ ]
+ }
+
+ onRunningChanged: console.log("running = " + running)
+ }
+ ]
+ }
+
+ SkinnedEntity {
+ id: riggedFigure4
+ effect: skinnedPbrEffect
+ source: "qrc:/assets/gltf/2.0/RiggedFigure/RiggedFigure.gltf"
+ baseColor: "green"
+ transform.translation: Qt.vector3d(0.0, 0.0, -3.0);
+
+ components: [
+ BlendedClipAnimator {
+ id: animator4
+ loops: 5
+ blendTree: ClipBlendValue {
+ clip: AnimationClipLoader { source: "qrc:/jump.json" }
+ }
+ channelMapper: ChannelMapper {
+ mappings: [
+ SkeletonMapping { skeleton: riggedFigure4.skeleton }
+ ]
+ }
+
+ onRunningChanged: console.log("running = " + running)
+ }
+ ]
+ }
+
+ SkinnedEntity {
+ id: riggedFigure5
+ effect: skinnedPbrEffect
+ source: "qrc:/assets/gltf/2.0/RiggedFigure/RiggedFigure.gltf"
+ baseColor: "orange"
+ transform.translation: Qt.vector3d(0.0, 0.0, -4.0);
+
+ components: [
+ BlendedClipAnimator {
+ id: animator5
+ loops: 5
+ blendTree: ClipBlendValue {
+ clip: AnimationClipLoader { source: "qrc:/jump.json" }
+ }
+ channelMapper: ChannelMapper {
+ mappings: [
+ SkeletonMapping { skeleton: riggedFigure5.skeleton }
+ ]
+ }
+
+ onRunningChanged: console.log("running = " + running)
+ }
+ ]
}
SkinnedEntity {
diff --git a/tests/manual/skinned-mesh/skinned-mesh.pro b/tests/manual/skinned-mesh/skinned-mesh.pro
index dc5fd3730..380b1bb35 100644
--- a/tests/manual/skinned-mesh/skinned-mesh.pro
+++ b/tests/manual/skinned-mesh/skinned-mesh.pro
@@ -2,7 +2,7 @@
error( "Couldn't find the manual.pri file!" )
}
-QT += 3dcore 3drender 3dinput 3dquick qml quick 3dquickextras
+QT += 3dcore 3drender 3dinput 3dquick qml quick 3dquickextras 3danimation
SOURCES += \
main.cpp
diff --git a/tests/manual/skinned-mesh/skinned-mesh.qrc b/tests/manual/skinned-mesh/skinned-mesh.qrc
index e062e6be4..f34f93f37 100644
--- a/tests/manual/skinned-mesh/skinned-mesh.qrc
+++ b/tests/manual/skinned-mesh/skinned-mesh.qrc
@@ -5,5 +5,6 @@
<file>skinnedPbr.vert</file>
<file>SkinnedEntity.qml</file>
<file>SkinnedPbrEffect.qml</file>
+ <file>jump.json</file>
</qresource>
</RCC>