summaryrefslogtreecommitdiffstats
path: root/tests/auto/animation
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/animation')
-rw-r--r--tests/auto/animation/animation.pro7
-rw-r--r--tests/auto/animation/animationutils/animationutils.qrc1
-rw-r--r--tests/auto/animation/animationutils/clip5.json1401
-rw-r--r--tests/auto/animation/animationutils/tst_animationutils.cpp864
-rw-r--r--tests/auto/animation/blendedclipanimator/tst_blendedclipanimator.cpp7
-rw-r--r--tests/auto/animation/channelmapping/tst_channelmapping.cpp34
-rw-r--r--tests/auto/animation/clipanimator/tst_clipanimator.cpp19
-rw-r--r--tests/auto/animation/clock/clock.pro12
-rw-r--r--tests/auto/animation/clock/tst_clock.cpp111
-rw-r--r--tests/auto/animation/findrunningclipanimatorsjob/tst_findrunningclipanimatorsjob.cpp1
-rw-r--r--tests/auto/animation/qcallbackmapping/qcallbackmapping.pro12
-rw-r--r--tests/auto/animation/qcallbackmapping/tst_qcallbackmapping.cpp223
-rw-r--r--tests/auto/animation/qchannelmapping/tst_qchannelmapping.cpp7
-rw-r--r--tests/auto/animation/qclipanimator/tst_qclipanimator.cpp57
-rw-r--r--tests/auto/animation/qclock/qclock.pro12
-rw-r--r--tests/auto/animation/qclock/tst_qclock.cpp165
-rw-r--r--tests/auto/animation/qskeletonmapping/qskeletonmapping.pro12
-rw-r--r--tests/auto/animation/qskeletonmapping/tst_qskeletonmapping.cpp175
-rw-r--r--tests/auto/animation/skeleton/skeleton.pro12
-rw-r--r--tests/auto/animation/skeleton/tst_skeleton.cpp146
20 files changed, 2927 insertions, 351 deletions
diff --git a/tests/auto/animation/animation.pro b/tests/auto/animation/animation.pro
index 421ecfdd5..1226f9498 100644
--- a/tests/auto/animation/animation.pro
+++ b/tests/auto/animation/animation.pro
@@ -13,7 +13,10 @@ SUBDIRS += \
qkeyframeanimation \
qmorphinganimation \
qmorphtarget \
- qvertexblendanimation
+ qvertexblendanimation \
+ qclock \
+ qskeletonmapping \
+ qcallbackmapping
qtConfig(private_tests) {
SUBDIRS += \
@@ -35,5 +38,7 @@ qtConfig(private_tests) {
clipblendvalue \
animationutils \
qabstractanimation \
+ clock \
+ skeleton \
findrunningclipanimatorsjob
}
diff --git a/tests/auto/animation/animationutils/animationutils.qrc b/tests/auto/animation/animationutils/animationutils.qrc
index ddaeab7f1..0b499ed76 100644
--- a/tests/auto/animation/animationutils/animationutils.qrc
+++ b/tests/auto/animation/animationutils/animationutils.qrc
@@ -4,5 +4,6 @@
<file>clip2.json</file>
<file>clip3.json</file>
<file>clip4.json</file>
+ <file>clip5.json</file>
</qresource>
</RCC>
diff --git a/tests/auto/animation/animationutils/clip5.json b/tests/auto/animation/animationutils/clip5.json
new file mode 100644
index 000000000..50a848f03
--- /dev/null
+++ b/tests/auto/animation/animationutils/clip5.json
@@ -0,0 +1,1401 @@
+{
+ "animations": [
+ {
+ "animationName": "SkeletonAction",
+ "channels": [
+ {
+ "channelComponents": [
+ {
+ "channelComponentName": "Rotation W",
+ "keyFrames": [
+ {
+ "coords": [
+ 0.0,
+ 1.0
+ ],
+ "leftHandle": [
+ -0.9597616195678711,
+ 1.0
+ ],
+ "rightHandle": [
+ 0.9597616195678711,
+ 1.0
+ ]
+ },
+ {
+ "coords": [
+ 2.4583333333333335,
+ -4.371138828673793e-08
+ ],
+ "leftHandle": [
+ 1.4985717137654622,
+ -4.371138828673793e-08
+ ],
+ "rightHandle": [
+ 3.4180949529012046,
+ -4.371138828673793e-08
+ ]
+ }
+ ]
+ },
+ {
+ "channelComponentName": "Rotation X",
+ "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": "Rotation Z",
+ "keyFrames": [
+ {
+ "coords": [
+ 0.0,
+ -0.0
+ ],
+ "leftHandle": [
+ -0.9597616195678711,
+ -0.0
+ ],
+ "rightHandle": [
+ 0.9597616195678711,
+ -0.0
+ ]
+ },
+ {
+ "coords": [
+ 2.4583333333333335,
+ -1.0
+ ],
+ "leftHandle": [
+ 1.4985717137654622,
+ -1.0
+ ],
+ "rightHandle": [
+ 3.4180949529012046,
+ -1.0
+ ]
+ }
+ ]
+ },
+ {
+ "channelComponentName": "Rotation 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
+ ]
+ }
+ ]
+ }
+ ],
+ "channelName": "Rotation",
+ "jointIndex": 0
+ },
+ {
+ "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 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
+ ]
+ }
+ ]
+ },
+ {
+ "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
+ ]
+ }
+ ]
+ }
+ ],
+ "channelName": "Location",
+ "jointIndex": 0
+ },
+ {
+ "channelComponents": [
+ {
+ "channelComponentName": "Scale 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": "Scale 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": "Scale 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": "Scale",
+ "jointIndex": 0
+ },
+ {
+ "channelComponents": [
+ {
+ "channelComponentName": "Rotation W",
+ "keyFrames": [
+ {
+ "coords": [
+ 0.0,
+ 1.0
+ ],
+ "leftHandle": [
+ -0.9597616195678711,
+ 1.0
+ ],
+ "rightHandle": [
+ 0.9597616195678711,
+ 1.0
+ ]
+ },
+ {
+ "coords": [
+ 2.4583333333333335,
+ -4.371138828673793e-08
+ ],
+ "leftHandle": [
+ 1.4985717137654622,
+ -4.371138828673793e-08
+ ],
+ "rightHandle": [
+ 3.4180949529012046,
+ -4.371138828673793e-08
+ ]
+ }
+ ]
+ },
+ {
+ "channelComponentName": "Rotation X",
+ "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": "Rotation Z",
+ "keyFrames": [
+ {
+ "coords": [
+ 0.0,
+ -0.0
+ ],
+ "leftHandle": [
+ -0.9597616195678711,
+ -0.0
+ ],
+ "rightHandle": [
+ 0.9597616195678711,
+ -0.0
+ ]
+ },
+ {
+ "coords": [
+ 2.4583333333333335,
+ -1.0
+ ],
+ "leftHandle": [
+ 1.4985717137654622,
+ -1.0
+ ],
+ "rightHandle": [
+ 3.4180949529012046,
+ -1.0
+ ]
+ }
+ ]
+ },
+ {
+ "channelComponentName": "Rotation 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
+ ]
+ }
+ ]
+ }
+ ],
+ "channelName": "Rotation",
+ "jointIndex": 1
+ },
+ {
+ "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 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
+ ]
+ }
+ ]
+ },
+ {
+ "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
+ ]
+ }
+ ]
+ }
+ ],
+ "channelName": "Location",
+ "jointIndex": 1
+ },
+ {
+ "channelComponents": [
+ {
+ "channelComponentName": "Scale 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": "Scale 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": "Scale 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": "Scale",
+ "jointIndex": 1
+ },
+ {
+ "channelComponents": [
+ {
+ "channelComponentName": "Rotation W",
+ "keyFrames": [
+ {
+ "coords": [
+ 0.0,
+ 1.0
+ ],
+ "leftHandle": [
+ -0.9597616195678711,
+ 1.0
+ ],
+ "rightHandle": [
+ 0.9597616195678711,
+ 1.0
+ ]
+ },
+ {
+ "coords": [
+ 2.4583333333333335,
+ -4.371138828673793e-08
+ ],
+ "leftHandle": [
+ 1.4985717137654622,
+ -4.371138828673793e-08
+ ],
+ "rightHandle": [
+ 3.4180949529012046,
+ -4.371138828673793e-08
+ ]
+ }
+ ]
+ },
+ {
+ "channelComponentName": "Rotation X",
+ "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": "Rotation Z",
+ "keyFrames": [
+ {
+ "coords": [
+ 0.0,
+ -0.0
+ ],
+ "leftHandle": [
+ -0.9597616195678711,
+ -0.0
+ ],
+ "rightHandle": [
+ 0.9597616195678711,
+ -0.0
+ ]
+ },
+ {
+ "coords": [
+ 2.4583333333333335,
+ -1.0
+ ],
+ "leftHandle": [
+ 1.4985717137654622,
+ -1.0
+ ],
+ "rightHandle": [
+ 3.4180949529012046,
+ -1.0
+ ]
+ }
+ ]
+ },
+ {
+ "channelComponentName": "Rotation 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
+ ]
+ }
+ ]
+ }
+ ],
+ "channelName": "Rotation",
+ "jointIndex": 2
+ },
+ {
+ "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 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
+ ]
+ }
+ ]
+ },
+ {
+ "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
+ ]
+ }
+ ]
+ }
+ ],
+ "channelName": "Location",
+ "jointIndex": 2
+ },
+ {
+ "channelComponents": [
+ {
+ "channelComponentName": "Scale 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": "Scale 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": "Scale 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": "Scale",
+ "jointIndex": 2
+ },
+ {
+ "channelComponents": [
+ {
+ "channelComponentName": "Rotation W",
+ "keyFrames": [
+ {
+ "coords": [
+ 0.0,
+ 1.0
+ ],
+ "leftHandle": [
+ -0.9597616195678711,
+ 1.0
+ ],
+ "rightHandle": [
+ 0.9597616195678711,
+ 1.0
+ ]
+ },
+ {
+ "coords": [
+ 2.4583333333333335,
+ -4.371138828673793e-08
+ ],
+ "leftHandle": [
+ 1.4985717137654622,
+ -4.371138828673793e-08
+ ],
+ "rightHandle": [
+ 3.4180949529012046,
+ -4.371138828673793e-08
+ ]
+ }
+ ]
+ },
+ {
+ "channelComponentName": "Rotation X",
+ "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": "Rotation Z",
+ "keyFrames": [
+ {
+ "coords": [
+ 0.0,
+ -0.0
+ ],
+ "leftHandle": [
+ -0.9597616195678711,
+ -0.0
+ ],
+ "rightHandle": [
+ 0.9597616195678711,
+ -0.0
+ ]
+ },
+ {
+ "coords": [
+ 2.4583333333333335,
+ -1.0
+ ],
+ "leftHandle": [
+ 1.4985717137654622,
+ -1.0
+ ],
+ "rightHandle": [
+ 3.4180949529012046,
+ -1.0
+ ]
+ }
+ ]
+ },
+ {
+ "channelComponentName": "Rotation 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
+ ]
+ }
+ ]
+ }
+ ],
+ "channelName": "Rotation",
+ "jointIndex": 3
+ },
+ {
+ "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 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
+ ]
+ }
+ ]
+ },
+ {
+ "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
+ ]
+ }
+ ]
+ }
+ ],
+ "channelName": "Location",
+ "jointIndex": 3
+ },
+ {
+ "channelComponents": [
+ {
+ "channelComponentName": "Scale 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": "Scale 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": "Scale 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": "Scale",
+ "jointIndex": 3
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/auto/animation/animationutils/tst_animationutils.cpp b/tests/auto/animation/animationutils/tst_animationutils.cpp
index 36e954a85..5ec8c7d60 100644
--- a/tests/auto/animation/animationutils/tst_animationutils.cpp
+++ b/tests/auto/animation/animationutils/tst_animationutils.cpp
@@ -30,6 +30,7 @@
#include <Qt3DAnimation/private/animationclip_p.h>
#include <Qt3DAnimation/private/animationutils_p.h>
#include <Qt3DAnimation/private/blendedclipanimator_p.h>
+#include <Qt3DAnimation/private/clock_p.h>
#include <Qt3DAnimation/private/channelmapper_p.h>
#include <Qt3DAnimation/private/channelmapping_p.h>
#include <Qt3DAnimation/private/clipblendvalue_p.h>
@@ -51,6 +52,7 @@ using namespace Qt3DAnimation::Animation;
Q_DECLARE_METATYPE(Qt3DAnimation::Animation::Handler*)
Q_DECLARE_METATYPE(QVector<ChannelMapping *>)
+Q_DECLARE_METATYPE(Clock *)
Q_DECLARE_METATYPE(ChannelMapper *)
Q_DECLARE_METATYPE(AnimationClip *)
Q_DECLARE_METATYPE(QVector<MappingData>)
@@ -61,6 +63,7 @@ Q_DECLARE_METATYPE(ClipEvaluationData)
Q_DECLARE_METATYPE(ClipAnimator *)
Q_DECLARE_METATYPE(BlendedClipAnimator *)
Q_DECLARE_METATYPE(QVector<ChannelNameAndType>)
+Q_DECLARE_METATYPE(QVector<AnimationCallbackAndValue>)
namespace {
@@ -122,6 +125,12 @@ bool fuzzyCompare(float x1, float x2)
}
}
+class DummyCallback : public Qt3DAnimation::QAnimationCallback
+{
+public:
+ void valueChanged(const QVariant &) override { }
+};
+
} // anonymous
@@ -140,11 +149,25 @@ 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);
channelMapping->setChannelName(channelName);
channelMapping->setType(type);
+ channelMapping->setMappingType(ChannelMapping::ChannelMappingType);
+ return channelMapping;
+ }
+
+ ChannelMapping *createChannelMapping(Handler *handler,
+ const Qt3DCore::QNodeId skeletonId)
+ {
+ 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;
}
@@ -238,9 +261,19 @@ public:
return node;
}
+ Skeleton *createSkeleton(Handler *handler, int jointCount)
+ {
+ auto skeletonId = Qt3DCore::QNodeId::createId();
+ Skeleton *skeleton = handler->skeletonManager()->getOrCreateResource(skeletonId);
+ setPeerId(skeleton, skeletonId);
+ skeleton->setJointCount(jointCount);
+ return skeleton;
+ }
+
private Q_SLOTS:
void checkBuildPropertyMappings_data()
{
+ QTest::addColumn<Handler *>("handler");
QTest::addColumn<QVector<ChannelMapping *>>("channelMappings");
QTest::addColumn<QVector<ChannelNameAndType>>("channelNamesAndTypes");
QTest::addColumn<QVector<ComponentIndices>>("channelComponentIndices");
@@ -248,12 +281,14 @@ private Q_SLOTS:
// 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 };
@@ -289,6 +324,7 @@ private Q_SLOTS:
QVector<MappingData> expectedResults = { expectedMapping };
QTest::newRow("single mapping")
+ << handler
<< channelMappings
<< channelNamesAndTypes
<< channelComponentIndices
@@ -297,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,
@@ -399,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
@@ -409,6 +518,7 @@ private Q_SLOTS:
void checkBuildPropertyMappings()
{
// GIVEN
+ QFETCH(Handler *, handler);
QFETCH(QVector<ChannelMapping *>, channelMappings);
QFETCH(QVector<ChannelNameAndType>, channelNamesAndTypes);
QFETCH(QVector<ComponentIndices>, channelComponentIndices);
@@ -426,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());
@@ -433,338 +544,142 @@ private Q_SLOTS:
QCOMPARE(actualMapping.channelIndices[j], expectedMapping.channelIndices[j]);
}
}
+
+ // Cleanup
+ delete handler;
}
- void checkLocalTimeFromGlobalTime_data()
+ void checkLocalTimeFromElapsedTime_data()
{
- QTest::addColumn<double>("globalTime");
- QTest::addColumn<double>("globalStartTime");
+ QTest::addColumn<double>("elapsedTime");
+ QTest::addColumn<double>("currentTime");
QTest::addColumn<double>("playbackRate");
QTest::addColumn<double>("duration");
QTest::addColumn<int>("loopCount");
+ QTest::addColumn<int>("currentLoop");
QTest::addColumn<double>("expectedLocalTime");
QTest::addColumn<int>("expectedCurrentLoop");
- double globalTime;
- double globalStartTime;
+ double elapsedTime;
+ double currentTime;
double playbackRate;
double duration;
int loopCount;
+ int currentLoop;
double expectedLocalTime;
int expectedCurrentLoop;
- globalTime = 0.0;
- globalStartTime = 0.0;
+ elapsedTime = 0.0;
+ currentTime = 0.0;
playbackRate = 1.0;
duration = 1.0;
loopCount = 1;
+ currentLoop = 0;
expectedLocalTime = 0.0;
expectedCurrentLoop = 0;
- QTest::newRow("simple, t_global = 0")
- << globalTime << globalStartTime << playbackRate << duration << loopCount
+ QTest::newRow("simple, t_current = 0, t_elapsed = 0, loop_current = 0")
+ << elapsedTime << currentTime << playbackRate << duration << loopCount << currentLoop
<< expectedLocalTime << expectedCurrentLoop;
- globalTime = 0.5;
- globalStartTime = 0.0;
+ elapsedTime = 0.5;
+ currentTime = 0.0;
playbackRate = 1.0;
duration = 1.0;
loopCount = 1;
+ currentLoop = 0;
expectedLocalTime = 0.5;
expectedCurrentLoop = 0;
- QTest::newRow("simple, t_global = 0.5")
- << globalTime << globalStartTime << playbackRate << duration << loopCount
+ QTest::newRow("simple, t_current = 0, t_elapsed = 0.5, loop_current = 0")
+ << elapsedTime << currentTime << playbackRate << duration << loopCount << currentLoop
<< expectedLocalTime << expectedCurrentLoop;
- globalTime = 1.0;
- globalStartTime = 0.0;
+ elapsedTime = 1.5;
+ currentTime = 0.0;
playbackRate = 1.0;
duration = 1.0;
loopCount = 1;
+ currentLoop = 0;
expectedLocalTime = 1.0;
expectedCurrentLoop = 0;
- QTest::newRow("simple, t_global = 1.0")
- << globalTime << globalStartTime << playbackRate << duration << loopCount
- << expectedLocalTime << expectedCurrentLoop;
-
- globalTime = -0.5;
- globalStartTime = 0.0;
- playbackRate = 1.0;
- duration = 1.0;
- loopCount = 1;
- expectedLocalTime = 0.0;
- expectedCurrentLoop = 0;
- QTest::newRow("simple, t_global = -0.5")
- << globalTime << globalStartTime << playbackRate << duration << loopCount
+ QTest::newRow("simple, t_current = 0, t_elapsed = 1.5, loop_current = 0")
+ << elapsedTime << currentTime << playbackRate << duration << loopCount << currentLoop
<< expectedLocalTime << expectedCurrentLoop;
- globalTime = 1.5;
- globalStartTime = 0.0;
+ elapsedTime = 0.5;
+ currentTime = 0.6;
playbackRate = 1.0;
duration = 1.0;
loopCount = 1;
+ currentLoop = 0;
expectedLocalTime = 1.0;
expectedCurrentLoop = 0;
- QTest::newRow("simple, t_global = 1.5")
- << globalTime << globalStartTime << playbackRate << duration << loopCount
+ QTest::newRow("simple, t_current = 0.5, t_elapsed = 0.6, loop_current = 0")
+ << elapsedTime << currentTime << playbackRate << duration << loopCount << currentLoop
<< expectedLocalTime << expectedCurrentLoop;
- globalTime = 0.5;
- globalStartTime = 0.0;
+ elapsedTime = 0.5;
+ currentTime = 0.6;
playbackRate = 1.0;
duration = 1.0;
loopCount = 2;
- expectedLocalTime = 0.5;
- expectedCurrentLoop = 0;
- QTest::newRow("simple, loopCount = 2, t_global = 0.5")
- << globalTime << globalStartTime << playbackRate << duration << loopCount
- << expectedLocalTime << expectedCurrentLoop;
-
- globalTime = 1.5;
- globalStartTime = 0.0;
- playbackRate = 1.0;
- duration = 1.0;
- loopCount = 2;
- expectedLocalTime = 0.5;
+ currentLoop = 0;
+ expectedLocalTime = 0.1;
expectedCurrentLoop = 1;
- QTest::newRow("simple, loopCount = 2, t_global = 1.5")
- << globalTime << globalStartTime << playbackRate << duration << loopCount
+ QTest::newRow("simple, t_current = 0.5, t_elapsed = 0.6, loop_current = 0, loop_count = 2")
+ << elapsedTime << currentTime << playbackRate << duration << loopCount << currentLoop
<< expectedLocalTime << expectedCurrentLoop;
- globalTime = 3.5;
- globalStartTime = 0.0;
+ elapsedTime = 0.5;
+ currentTime = 0.6;
playbackRate = 1.0;
- duration = 2.0;
- loopCount = 2;
- expectedLocalTime = 1.5;
- expectedCurrentLoop = 1;
- QTest::newRow("duration = 2, loopCount = 2, t_global = 3.5")
- << globalTime << globalStartTime << playbackRate << duration << loopCount
- << expectedLocalTime << expectedCurrentLoop;
-
- globalTime = 4.5;
- globalStartTime = 0.0;
- playbackRate = 1.0;
- duration = 2.0;
+ duration = 1.0;
loopCount = 2;
- expectedLocalTime = 2.0;
- expectedCurrentLoop = 1;
- QTest::newRow("duration = 2, loopCount = 2, t_global = 4.5")
- << globalTime << globalStartTime << playbackRate << duration << loopCount
+ currentLoop = 1;
+ expectedLocalTime = 1.0;
+ expectedCurrentLoop = 1; // We clamp at end of final loop
+ QTest::newRow("simple, t_current = 0.5, t_elapsed = 0.6, loop_current = 1, loop_count = 2")
+ << elapsedTime << currentTime << playbackRate << duration << loopCount << currentLoop
<< expectedLocalTime << expectedCurrentLoop;
- globalTime = 1.5;
- globalStartTime = 0.0;
- playbackRate = 1.0;
+ elapsedTime = 0.5;
+ currentTime = 0.6;
+ playbackRate = 0.1;
duration = 1.0;
- loopCount = -1;
- expectedLocalTime = 0.5;
+ loopCount = 2;
+ currentLoop = 1;
+ expectedLocalTime = 0.65;
expectedCurrentLoop = 1;
- QTest::newRow("simple, loopCount = inf, t_global = 1.5")
- << globalTime << globalStartTime << playbackRate << duration << loopCount
- << expectedLocalTime << expectedCurrentLoop;
-
- globalTime = 10.2;
- globalStartTime = 0.0;
- playbackRate = 1.0;
- duration = 1.0;
- loopCount = -1;
- expectedLocalTime = 0.2;
- expectedCurrentLoop = 10;
- QTest::newRow("simple, loopCount = inf, t_global = 10.2")
- << globalTime << globalStartTime << playbackRate << duration << loopCount
+ QTest::newRow("simple, t_current = 0.5, t_elapsed = 0.6, loop_current = 1, loop_count = 2")
+ << elapsedTime << currentTime << playbackRate << duration << loopCount << currentLoop
<< expectedLocalTime << expectedCurrentLoop;
}
- void checkLocalTimeFromGlobalTime()
+ void checkLocalTimeFromElapsedTime()
{
// GIVEN
- QFETCH(double, globalTime);
- QFETCH(double, globalStartTime);
+ QFETCH(double, elapsedTime);
+ QFETCH(double, currentTime);
QFETCH(double, playbackRate);
QFETCH(double, duration);
QFETCH(int, loopCount);
+ QFETCH(int, currentLoop);
QFETCH(double, expectedLocalTime);
QFETCH(int, expectedCurrentLoop);
// WHEN
- int actualCurrentLoop = 0;
- double actualLocalTime = localTimeFromGlobalTime(globalTime,
- globalStartTime,
- playbackRate,
- duration,
- loopCount,
- actualCurrentLoop);
+ int actualCurrentLoop = currentLoop;
+ double actualLocalTime = localTimeFromElapsedTime(currentTime,
+ elapsedTime,
+ playbackRate,
+ duration,
+ loopCount,
+ actualCurrentLoop);
// THEN
QCOMPARE(actualCurrentLoop, expectedCurrentLoop);
QCOMPARE(actualLocalTime, expectedLocalTime);
}
- void checkPhaseFromGlobalTime_data()
- {
- QTest::addColumn<double>("globalTime");
- QTest::addColumn<double>("globalStartTime");
- QTest::addColumn<double>("playbackRate");
- QTest::addColumn<double>("duration");
- QTest::addColumn<int>("loopCount");
- QTest::addColumn<double>("expectedPhase");
- QTest::addColumn<int>("expectedCurrentLoop");
-
- double globalTime;
- double globalStartTime;
- double playbackRate;
- double duration;
- int loopCount;
- double expectedPhase;
- int expectedCurrentLoop;
-
- globalTime = 0.0;
- globalStartTime = 0.0;
- playbackRate = 1.0;
- duration = 1.0;
- loopCount = 1;
- expectedPhase = 0.0;
- expectedCurrentLoop = 0;
- QTest::newRow("simple, t_global = 0")
- << globalTime << globalStartTime << playbackRate << duration << loopCount
- << expectedPhase << expectedCurrentLoop;
-
- globalTime = 0.5;
- globalStartTime = 0.0;
- playbackRate = 1.0;
- duration = 1.0;
- loopCount = 1;
- expectedPhase = 0.5;
- expectedCurrentLoop = 0;
- QTest::newRow("simple, t_global = 0.5")
- << globalTime << globalStartTime << playbackRate << duration << loopCount
- << expectedPhase << expectedCurrentLoop;
-
- globalTime = 1.0;
- globalStartTime = 0.0;
- playbackRate = 1.0;
- duration = 1.0;
- loopCount = 1;
- expectedPhase = 1.0;
- expectedCurrentLoop = 0;
- QTest::newRow("simple, t_global = 1.0")
- << globalTime << globalStartTime << playbackRate << duration << loopCount
- << expectedPhase << expectedCurrentLoop;
-
- globalTime = -0.5;
- globalStartTime = 0.0;
- playbackRate = 1.0;
- duration = 1.0;
- loopCount = 1;
- expectedPhase = 0.0;
- expectedCurrentLoop = 0;
- QTest::newRow("simple, t_global = -0.5")
- << globalTime << globalStartTime << playbackRate << duration << loopCount
- << expectedPhase << expectedCurrentLoop;
-
- globalTime = 1.5;
- globalStartTime = 0.0;
- playbackRate = 1.0;
- duration = 1.0;
- loopCount = 1;
- expectedPhase = 1.0;
- expectedCurrentLoop = 0;
- QTest::newRow("simple, t_global = 1.5")
- << globalTime << globalStartTime << playbackRate << duration << loopCount
- << expectedPhase << expectedCurrentLoop;
-
- globalTime = 0.5;
- globalStartTime = 0.0;
- playbackRate = 1.0;
- duration = 1.0;
- loopCount = 2;
- expectedPhase = 0.5;
- expectedCurrentLoop = 0;
- QTest::newRow("simple, loopCount = 2, t_global = 0.5")
- << globalTime << globalStartTime << playbackRate << duration << loopCount
- << expectedPhase << expectedCurrentLoop;
-
- globalTime = 1.5;
- globalStartTime = 0.0;
- playbackRate = 1.0;
- duration = 1.0;
- loopCount = 2;
- expectedPhase = 0.5;
- expectedCurrentLoop = 1;
- QTest::newRow("simple, loopCount = 2, t_global = 1.5")
- << globalTime << globalStartTime << playbackRate << duration << loopCount
- << expectedPhase << expectedCurrentLoop;
-
- globalTime = 3.5;
- globalStartTime = 0.0;
- playbackRate = 1.0;
- duration = 2.0;
- loopCount = 2;
- expectedPhase = 0.75;
- expectedCurrentLoop = 1;
- QTest::newRow("duration = 2, loopCount = 2, t_global = 3.5")
- << globalTime << globalStartTime << playbackRate << duration << loopCount
- << expectedPhase << expectedCurrentLoop;
-
- globalTime = 4.5;
- globalStartTime = 0.0;
- playbackRate = 1.0;
- duration = 2.0;
- loopCount = 2;
- expectedPhase = 1.0;
- expectedCurrentLoop = 1;
- QTest::newRow("duration = 2, loopCount = 2, t_global = 4.5")
- << globalTime << globalStartTime << playbackRate << duration << loopCount
- << expectedPhase << expectedCurrentLoop;
-
- globalTime = 1.5;
- globalStartTime = 0.0;
- playbackRate = 1.0;
- duration = 1.0;
- loopCount = -1;
- expectedPhase = 0.5;
- expectedCurrentLoop = 1;
- QTest::newRow("simple, loopCount = inf, t_global = 1.5")
- << globalTime << globalStartTime << playbackRate << duration << loopCount
- << expectedPhase << expectedCurrentLoop;
-
- globalTime = 10.2;
- globalStartTime = 0.0;
- playbackRate = 1.0;
- duration = 1.0;
- loopCount = -1;
- expectedPhase = 0.2;
- expectedCurrentLoop = 10;
- QTest::newRow("simple, loopCount = inf, t_global = 10.2")
- << globalTime << globalStartTime << playbackRate << duration << loopCount
- << expectedPhase << expectedCurrentLoop;
- }
-
- void checkPhaseFromGlobalTime()
- {
- // GIVEN
- QFETCH(double, globalTime);
- QFETCH(double, globalStartTime);
- QFETCH(double, playbackRate);
- QFETCH(double, duration);
- QFETCH(int, loopCount);
- QFETCH(double, expectedPhase);
- QFETCH(int, expectedCurrentLoop);
-
- // WHEN
- int actualCurrentLoop = 0;
- double actualPhase = phaseFromGlobalTime(globalTime,
- globalStartTime,
- playbackRate,
- duration,
- loopCount,
- actualCurrentLoop);
-
- // THEN
- QCOMPARE(actualCurrentLoop, expectedCurrentLoop);
- QCOMPARE(actualPhase, expectedPhase);
- }
-
void checkPreparePropertyChanges_data()
{
QTest::addColumn<Qt3DCore::QNodeId>("animatorId");
@@ -1034,6 +949,117 @@ private Q_SLOTS:
}
}
+ void checkPrepareCallbacks_data()
+ {
+ QTest::addColumn<QVector<MappingData>>("mappingData");
+ QTest::addColumn<QVector<float>>("channelResults");
+ QTest::addColumn<QVector<AnimationCallbackAndValue> >("expectedValues");
+
+ QVector<MappingData> mappingData;
+ QVector<float> channelResults;
+ QVector<AnimationCallbackAndValue> expectedValues;
+
+ // vec3
+ {
+ DummyCallback callback; // safe since the object is never used, just the address
+ MappingData mapping;
+ mapping.targetId = Qt3DCore::QNodeId::createId();
+ mapping.propertyName = "translation";
+ mapping.type = static_cast<int>(QVariant::Vector3D);
+ mapping.channelIndices = QVector<int>() << 0 << 1 << 2;
+ mapping.callback = &callback;
+ mapping.callbackFlags = 0;
+ mappingData.push_back(mapping);
+ channelResults = QVector<float>() << 1.0f << 2.0f << 3.0f;
+
+ AnimationCallbackAndValue cbv;
+ cbv.callback = mapping.callback;
+ cbv.flags = mapping.callbackFlags;
+ cbv.value = QVariant::fromValue<QVector3D>(QVector3D(1.0f, 2.0f, 3.0f));
+ expectedValues.push_back(cbv);
+
+ QTest::newRow("vec3 translation, no flags") << mappingData << channelResults << expectedValues;
+
+ mappingData.clear();
+ channelResults.clear();
+ expectedValues.clear();
+ }
+
+ // double
+ {
+ DummyCallback callback;
+ MappingData mapping;
+ mapping.targetId = Qt3DCore::QNodeId::createId();
+ mapping.propertyName = "something";
+ mapping.type = static_cast<int>(QVariant::Double);
+ mapping.channelIndices = QVector<int>() << 0;
+ mapping.callback = &callback;
+ mapping.callbackFlags = 0;
+ mappingData.push_back(mapping);
+ channelResults = QVector<float>() << 1.0f;
+
+ AnimationCallbackAndValue cbv;
+ cbv.callback = mapping.callback;
+ cbv.flags = mapping.callbackFlags;
+ cbv.value = QVariant(double(1.0));
+ expectedValues.push_back(cbv);
+
+ QTest::newRow("double, no flags") << mappingData << channelResults << expectedValues;
+
+ mappingData.clear();
+ channelResults.clear();
+ expectedValues.clear();
+ }
+
+ // float, set a flag
+ {
+ DummyCallback callback;
+ MappingData mapping;
+ mapping.targetId = Qt3DCore::QNodeId::createId();
+ mapping.propertyName = "opacity";
+ mapping.type = static_cast<int>(QMetaType::Float);
+ mapping.channelIndices = QVector<int>() << 0;
+ mapping.callback = &callback;
+ mapping.callbackFlags = Qt3DAnimation::QAnimationCallback::OnThreadPool;
+ mappingData.push_back(mapping);
+ channelResults = QVector<float>() << 0.5f;
+
+ AnimationCallbackAndValue cbv;
+ cbv.callback = mapping.callback;
+ cbv.flags = mapping.callbackFlags;
+ cbv.value = QVariant(float(0.5f));
+ expectedValues.push_back(cbv);
+
+ QTest::newRow("float, OnThreadPool") << mappingData << channelResults << expectedValues;
+
+ mappingData.clear();
+ channelResults.clear();
+ expectedValues.clear();
+ }
+ }
+
+ void checkPrepareCallbacks()
+ {
+ // GIVEN
+ QFETCH(QVector<MappingData>, mappingData);
+ QFETCH(QVector<float>, channelResults);
+ QFETCH(QVector<AnimationCallbackAndValue>, expectedValues);
+
+ // WHEN
+ QVector<AnimationCallbackAndValue> callbacks = prepareCallbacks(mappingData, channelResults);
+
+ // THEN
+ QCOMPARE(callbacks.size(), expectedValues.size());
+ for (int i = 0; i < callbacks.size(); ++i) {
+ auto expected = expectedValues[i];
+ auto actual = callbacks[i];
+
+ QCOMPARE(actual.callback, expected.callback);
+ QCOMPARE(actual.flags, expected.flags);
+ QCOMPARE(actual.value, expected.value);
+ }
+ }
+
void checkEvaluateClipAtLocalTime_data()
{
QTest::addColumn<Handler *>("handler");
@@ -1284,6 +1310,31 @@ private Q_SLOTS:
QVector<char> suffixes;
QVector<int> expectedResults;
+ // already sorted vec3, no component names, with and without offset
+ {
+ channel = Channel();
+ channel.name = QLatin1String("Location");
+ channel.channelComponents.resize(3);
+ // leave 'name' empty
+
+ dataType = static_cast<int>(QVariant::Vector3D);
+ offset = 0;
+ // suffixes expected to be ignored
+ expectedResults = (QVector<int>() << 0 << 1 << 2);
+
+ QTest::newRow("vec3 location, pre-sorted, no component names, offset = 0")
+ << channel << dataType << offset << suffixes << expectedResults;
+
+ expectedResults.clear();
+
+ offset = 4;
+ expectedResults = (QVector<int>() << 4 << 5 << 6);
+ QTest::newRow("vec3 location, pre-sorted, no component names, offset = 4")
+ << channel << dataType << offset << suffixes << expectedResults;
+
+ expectedResults.clear();
+ }
+
// vec3 with and without offset
{
channel = Channel();
@@ -1622,6 +1673,7 @@ private Q_SLOTS:
AnimationClip *clip;
AnimatorEvaluationData animatorData;
ClipEvaluationData clipData;
+ auto* clock = new Clock;
{
handler = new Handler();
@@ -1629,11 +1681,13 @@ private Q_SLOTS:
const qint64 globalStartTimeNS = 0;
const int loops = 1;
auto animator = createClipAnimator(handler, globalStartTimeNS, loops);
- const qint64 globalTimeNS = 0;
- animatorData = evaluationDataForAnimator(animator, globalTimeNS); // Tested elsewhere
+ animator->setCurrentLoop(0);
+ clipData.currentLoop = animator->currentLoop();
+ const qint64 elapsedTimeNS = 0;
+ animatorData = evaluationDataForAnimator(animator, clock, elapsedTimeNS); // Tested elsewhere
- clipData.localTime = localTimeFromGlobalTime(animatorData.globalTime,
- animatorData.startTime,
+ clipData.localTime = localTimeFromElapsedTime(animatorData.currentTime,
+ animatorData.elapsedTime,
animatorData.playbackRate,
clip->duration(),
animatorData.loopCount,
@@ -1650,18 +1704,20 @@ private Q_SLOTS:
const qint64 globalStartTimeNS = 0;
const int loops = 1;
auto animator = createClipAnimator(handler, globalStartTimeNS, loops);
- const qint64 globalTimeNS = (clip->duration() + 1.0) * 1.0e9; // +1 to ensure beyond end of clip
- animatorData = evaluationDataForAnimator(animator, globalTimeNS); // Tested elsewhere
+ animator->setCurrentLoop(0);
+ clipData.currentLoop = animator->currentLoop();
+ const qint64 elapsedTimeNS = (clip->duration()+1)*1e09; // +1 to ensure beyond end
+ animatorData = evaluationDataForAnimator(animator, nullptr, elapsedTimeNS); // Tested elsewhere
- clipData.localTime = localTimeFromGlobalTime(animatorData.globalTime,
- animatorData.startTime,
+ clipData.localTime = localTimeFromElapsedTime(animatorData.currentTime,
+ animatorData.elapsedTime,
animatorData.playbackRate,
clip->duration(),
animatorData.loopCount,
clipData.currentLoop); // Tested elsewhere
clipData.isFinalFrame = true;
- QTest::newRow("clip1.json, globalTime = duration")
+ QTest::newRow("clip1.json, elapsedTime = duration + 1")
<< handler << clip << animatorData << clipData;
}
@@ -1671,18 +1727,43 @@ private Q_SLOTS:
const qint64 globalStartTimeNS = 0;
const int loops = 0; // Infinite loops
auto animator = createClipAnimator(handler, globalStartTimeNS, loops);
- const qint64 globalTimeNS = 2.0 * clip->duration() * 1.0e9;
- animatorData = evaluationDataForAnimator(animator, globalTimeNS); // Tested elsewhere
+ animator->setCurrentLoop(0);
+ clipData.currentLoop = animator->currentLoop();
+ const qint64 elapsedTimeNS = 2.0 * clip->duration() * 1.0e9;
+ animatorData = evaluationDataForAnimator(animator, clock, elapsedTimeNS); // Tested elsewhere
- clipData.localTime = localTimeFromGlobalTime(animatorData.globalTime,
- animatorData.startTime,
+ clipData.localTime = localTimeFromElapsedTime(animatorData.currentTime,
+ animatorData.elapsedTime,
animatorData.playbackRate,
clip->duration(),
animatorData.loopCount,
clipData.currentLoop); // Tested elsewhere
clipData.isFinalFrame = false;
- QTest::newRow("clip1.json, globalTime = 2 * duration, loops = infinite")
+ QTest::newRow("clip1.json, elapsedTime = 2 * duration, loops = infinite")
+ << handler << clip << animatorData << clipData;
+ }
+
+ {
+ handler = new Handler();
+ clip = createAnimationClipLoader(handler, QUrl("qrc:/clip1.json"));
+ const qint64 globalStartTimeNS = 0;
+ const int loops = 2;
+ auto animator = createClipAnimator(handler, globalStartTimeNS, loops);
+ animator->setCurrentLoop(0);
+ clipData.currentLoop = animator->currentLoop();
+ const qint64 elapsedTimeNS = (2.0 * clip->duration() + 1.0) * 1.0e9; // +1 to ensure beyond end of clip
+ animatorData = evaluationDataForAnimator(animator, nullptr, elapsedTimeNS); // Tested elsewhere
+
+ clipData.localTime = localTimeFromElapsedTime(animatorData.currentTime,
+ animatorData.elapsedTime,
+ animatorData.playbackRate,
+ clip->duration(),
+ animatorData.loopCount,
+ clipData.currentLoop); // Tested elsewhere
+ clipData.isFinalFrame = true;
+
+ QTest::newRow("clip1.json, elapsedTime = 2 * duration + 1, loops = 2")
<< handler << clip << animatorData << clipData;
}
@@ -1692,18 +1773,20 @@ private Q_SLOTS:
const qint64 globalStartTimeNS = 0;
const int loops = 2;
auto animator = createClipAnimator(handler, globalStartTimeNS, loops);
- const qint64 globalTimeNS = (2.0 * clip->duration() + 1.0) * 1.0e9; // +1 to ensure beyond end of clip
- animatorData = evaluationDataForAnimator(animator, globalTimeNS); // Tested elsewhere
+ animator->setCurrentLoop(1);
+ clipData.currentLoop = animator->currentLoop();
+ const qint64 elapsedTimeNS = (clip->duration() + 1.0) * 1.0e9; // +1 to ensure beyond end of clip
+ animatorData = evaluationDataForAnimator(animator, nullptr, elapsedTimeNS); // Tested elsewhere
- clipData.localTime = localTimeFromGlobalTime(animatorData.globalTime,
- animatorData.startTime,
+ clipData.localTime = localTimeFromElapsedTime(animatorData.currentTime,
+ animatorData.elapsedTime,
animatorData.playbackRate,
clip->duration(),
animatorData.loopCount,
clipData.currentLoop); // Tested elsewhere
clipData.isFinalFrame = true;
- QTest::newRow("clip1.json, globalTime = 2 * duration + 1, loops = 2")
+ QTest::newRow("clip1.json, elapsedTime = duration + 1, loops = 2, current_loop = 1")
<< handler << clip << animatorData << clipData;
}
}
@@ -1732,12 +1815,12 @@ private Q_SLOTS:
{
QTest::addColumn<Handler *>("handler");
QTest::addColumn<ClipAnimator *>("animator");
- QTest::addColumn<qint64>("globalTimeNS");
+ QTest::addColumn<qint64>("elapsedTime");
QTest::addColumn<AnimatorEvaluationData>("expectedAnimatorData");
Handler *handler;
ClipAnimator *animator;
- qint64 globalTimeNS;
+ qint64 elapsedTimeNS;
AnimatorEvaluationData expectedAnimatorData;
{
@@ -1745,15 +1828,14 @@ private Q_SLOTS:
const qint64 globalStartTimeNS = 0;
const int loops = 1;
animator = createClipAnimator(handler, globalStartTimeNS, loops);
- globalTimeNS = 0;
+ elapsedTimeNS = 0;
expectedAnimatorData.loopCount = loops;
expectedAnimatorData.playbackRate = 1.0; // hard-wired for now
- expectedAnimatorData.startTime = 0.0;
- expectedAnimatorData.globalTime = 0.0;
+ expectedAnimatorData.elapsedTime = 0.0;
- QTest::newRow("globalStartTime = 0, globalTime = 0, loops = 1")
- << handler << animator << globalTimeNS << expectedAnimatorData;
+ QTest::newRow("globalStartTime = 0, elapsedTime = 0, loops = 1")
+ << handler << animator << elapsedTimeNS << expectedAnimatorData;
}
{
@@ -1761,15 +1843,14 @@ private Q_SLOTS:
const qint64 globalStartTimeNS = 0;
const int loops = 5;
animator = createClipAnimator(handler, globalStartTimeNS, loops);
- globalTimeNS = 0;
+ elapsedTimeNS = 0;
expectedAnimatorData.loopCount = loops;
expectedAnimatorData.playbackRate = 1.0; // hard-wired for now
- expectedAnimatorData.startTime = 0.0;
- expectedAnimatorData.globalTime = 0.0;
+ expectedAnimatorData.elapsedTime = 0.0;
- QTest::newRow("globalStartTime = 0, globalTime = 0, loops = 5")
- << handler << animator << globalTimeNS << expectedAnimatorData;
+ QTest::newRow("globalStartTime = 0, elapsedTime = 0, loops = 5")
+ << handler << animator << elapsedTimeNS << expectedAnimatorData;
}
{
@@ -1777,15 +1858,14 @@ private Q_SLOTS:
const qint64 globalStartTimeNS = 0;
const int loops = 1;
animator = createClipAnimator(handler, globalStartTimeNS, loops);
- globalTimeNS = 5000000000;
+ elapsedTimeNS = 5000000000;
expectedAnimatorData.loopCount = loops;
expectedAnimatorData.playbackRate = 1.0; // hard-wired for now
- expectedAnimatorData.startTime = 0.0;
- expectedAnimatorData.globalTime = 5.0;
+ expectedAnimatorData.elapsedTime = 5.0;
- QTest::newRow("globalStartTime = 0, globalTime = 5, loops = 1")
- << handler << animator << globalTimeNS << expectedAnimatorData;
+ QTest::newRow("globalStartTime = 0, elapsedTime = 5, loops = 1")
+ << handler << animator << elapsedTimeNS << expectedAnimatorData;
}
{
@@ -1793,15 +1873,14 @@ private Q_SLOTS:
const qint64 globalStartTimeNS = 3000000000;
const int loops = 1;
animator = createClipAnimator(handler, globalStartTimeNS, loops);
- globalTimeNS = 5000000000;
+ elapsedTimeNS = 2000000000;
expectedAnimatorData.loopCount = loops;
expectedAnimatorData.playbackRate = 1.0; // hard-wired for now
- expectedAnimatorData.startTime = 3.0;
- expectedAnimatorData.globalTime = 5.0;
+ expectedAnimatorData.elapsedTime = 2.0;
- QTest::newRow("globalStartTime = 3, globalTime = 5, loops = 1")
- << handler << animator << globalTimeNS << expectedAnimatorData;
+ QTest::newRow("globalStartTime = 3, elapsedTime = 2, loops = 1")
+ << handler << animator << elapsedTimeNS << expectedAnimatorData;
}
}
@@ -1810,17 +1889,16 @@ private Q_SLOTS:
// GIVEN
QFETCH(Handler *, handler);
QFETCH(ClipAnimator *, animator);
- QFETCH(qint64, globalTimeNS);
+ QFETCH(qint64, elapsedTime);
QFETCH(AnimatorEvaluationData, expectedAnimatorData);
// WHEN
- AnimatorEvaluationData actualAnimatorData = evaluationDataForAnimator(animator, globalTimeNS);
+ AnimatorEvaluationData actualAnimatorData = evaluationDataForAnimator(animator, nullptr, elapsedTime);
// THEN
QCOMPARE(actualAnimatorData.loopCount, expectedAnimatorData.loopCount);
QVERIFY(fuzzyCompare(actualAnimatorData.playbackRate, expectedAnimatorData.playbackRate) == true);
- QVERIFY(fuzzyCompare(actualAnimatorData.startTime, expectedAnimatorData.startTime) == true);
- QVERIFY(fuzzyCompare(actualAnimatorData.globalTime, expectedAnimatorData.globalTime) == true);
+ QVERIFY(fuzzyCompare(actualAnimatorData.elapsedTime, expectedAnimatorData.elapsedTime) == true);
// Cleanup
delete handler;
@@ -2304,6 +2382,27 @@ private Q_SLOTS:
QTest::addRow("Multiple channels with repeats") << handler << channelMapper << expectedResults;
}
+
+ {
+ auto handler = new Handler();
+ const int jointCount = 10;
+ auto skeleton = createSkeleton(handler, jointCount);
+ auto channelMapping = createChannelMapping(handler, skeleton->peerId());
+ QVector<ChannelMapping *> channelMappings;
+ channelMappings.push_back(channelMapping);
+
+ auto channelMapper = createChannelMapper(handler,
+ QVector<Qt3DCore::QNodeId>() << channelMapping->peerId());
+
+ QVector<ChannelNameAndType> expectedResults;
+ for (int i = 0; i < jointCount; ++i) {
+ expectedResults.push_back({ QLatin1String("Location"), static_cast<int>(QVariant::Vector3D), i });
+ expectedResults.push_back({ QLatin1String("Rotation"), static_cast<int>(QVariant::Quaternion), i });
+ expectedResults.push_back({ QLatin1String("Scale"), static_cast<int>(QVariant::Vector3D), i });
+ }
+
+ QTest::addRow("Skeleton, 10 joints") << handler << channelMapper << expectedResults;
+ }
}
void checkBuildRequiredChannelsAndTypes()
@@ -2369,6 +2468,35 @@ private Q_SLOTS:
QTest::newRow("vec3 location, quaterion rotation, pbr metal-rough") << allChannels << expectedResults;
}
+
+ {
+ QVector<ChannelNameAndType> allChannels;
+ const int jointCount = 4;
+ for (int i = 0; i < jointCount; ++i) {
+ allChannels.push_back({ QLatin1String("Location"), static_cast<int>(QVariant::Vector3D), i });
+ allChannels.push_back({ QLatin1String("Rotation"), static_cast<int>(QVariant::Quaternion), i });
+ allChannels.push_back({ QLatin1String("Scale"), static_cast<int>(QVariant::Vector3D), i });
+ }
+
+ QVector<ComponentIndices> expectedResults;
+ expectedResults.push_back({ 0, 1, 2 });
+ expectedResults.push_back({ 3, 4, 5, 6 });
+ expectedResults.push_back({ 7, 8, 9 });
+
+ expectedResults.push_back({ 10, 11, 12 });
+ expectedResults.push_back({ 13, 14, 15, 16 });
+ expectedResults.push_back({ 17, 18, 19 });
+
+ expectedResults.push_back({ 20, 21, 22 });
+ expectedResults.push_back({ 23, 24, 25, 26 });
+ expectedResults.push_back({ 27, 28, 29 });
+
+ expectedResults.push_back({ 30, 31, 32 });
+ expectedResults.push_back({ 33, 34, 35, 36 });
+ expectedResults.push_back({ 37, 38, 39 });
+
+ QTest::newRow("skeleton, 4 joints") << allChannels << expectedResults;
+ }
}
void checkAssignChannelComponentIndices()
@@ -2517,6 +2645,54 @@ private Q_SLOTS:
QTest::newRow("location, rotation, albedo (missing), metal-rough")
<< targetChannels << targetIndices << clip << expectedResults;
}
+
+ {
+ QVector<ChannelNameAndType> targetChannels;
+ const int jointCount = 4;
+ for (int i = 0; i < jointCount; ++i) {
+ targetChannels.push_back({ QLatin1String("Location"), static_cast<int>(QVariant::Vector3D), i });
+ targetChannels.push_back({ QLatin1String("Rotation"), static_cast<int>(QVariant::Quaternion), i });
+ targetChannels.push_back({ QLatin1String("Scale"), static_cast<int>(QVariant::Vector3D), i });
+ }
+
+ QVector<ComponentIndices> targetIndices;
+ targetIndices.push_back({ 0, 1, 2 });
+ targetIndices.push_back({ 3, 4, 5, 6 });
+ targetIndices.push_back({ 7, 8, 9 });
+
+ targetIndices.push_back({ 10, 11, 12 });
+ targetIndices.push_back({ 13, 14, 15, 16 });
+ targetIndices.push_back({ 17, 18, 19 });
+
+ targetIndices.push_back({ 20, 21, 22 });
+ targetIndices.push_back({ 23, 24, 25, 26 });
+ targetIndices.push_back({ 27, 28, 29 });
+
+ targetIndices.push_back({ 30, 31, 32 });
+ targetIndices.push_back({ 33, 34, 35, 36 });
+ targetIndices.push_back({ 37, 38, 39 });
+
+ auto *clip = new AnimationClip();
+ clip->setDataType(AnimationClip::File);
+ clip->setSource(QUrl("qrc:/clip5.json"));
+ clip->loadAnimation();
+
+ 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, 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, 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, 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")
+ << targetChannels << targetIndices << clip << expectedResults;
+ }
}
void checkGenerateClipFormatIndices()
diff --git a/tests/auto/animation/blendedclipanimator/tst_blendedclipanimator.cpp b/tests/auto/animation/blendedclipanimator/tst_blendedclipanimator.cpp
index 3265de167..c0e1581f9 100644
--- a/tests/auto/animation/blendedclipanimator/tst_blendedclipanimator.cpp
+++ b/tests/auto/animation/blendedclipanimator/tst_blendedclipanimator.cpp
@@ -63,7 +63,8 @@ private Q_SLOTS:
QCOMPARE(backendBlendedClipAnimator.blendTreeRootId(), Qt3DCore::QNodeId());
QCOMPARE(backendBlendedClipAnimator.mapperId(), Qt3DCore::QNodeId());
QCOMPARE(backendBlendedClipAnimator.isRunning(), false);
- QCOMPARE(backendBlendedClipAnimator.startTime(), 0);
+ QCOMPARE(backendBlendedClipAnimator.lastLocalTime(), 0.0);
+ QCOMPARE(backendBlendedClipAnimator.nsSincePreviousFrame(0), 0);
QCOMPARE(backendBlendedClipAnimator.currentLoop(), 0);
QCOMPARE(backendBlendedClipAnimator.loops(), 1);
@@ -82,6 +83,7 @@ private Q_SLOTS:
backendBlendedClipAnimator.setMapperId(Qt3DCore::QNodeId::createId());
backendBlendedClipAnimator.setRunning(true);
backendBlendedClipAnimator.setStartTime(28);
+ backendBlendedClipAnimator.setLastLocalTime(0.28);
backendBlendedClipAnimator.cleanup();
// THEN
@@ -89,7 +91,8 @@ private Q_SLOTS:
QCOMPARE(backendBlendedClipAnimator.blendTreeRootId(), Qt3DCore::QNodeId());
QCOMPARE(backendBlendedClipAnimator.mapperId(), Qt3DCore::QNodeId());
QCOMPARE(backendBlendedClipAnimator.isRunning(), false);
- QCOMPARE(backendBlendedClipAnimator.startTime(), 0);
+ QCOMPARE(backendBlendedClipAnimator.lastLocalTime(), 0.0);
+ QCOMPARE(backendBlendedClipAnimator.nsSincePreviousFrame(0), 0);
QCOMPARE(backendBlendedClipAnimator.currentLoop(), 0);
QCOMPARE(backendBlendedClipAnimator.loops(), 1);
}
diff --git a/tests/auto/animation/channelmapping/tst_channelmapping.cpp b/tests/auto/animation/channelmapping/tst_channelmapping.cpp
index 478406336..a947d4a2d 100644
--- a/tests/auto/animation/channelmapping/tst_channelmapping.cpp
+++ b/tests/auto/animation/channelmapping/tst_channelmapping.cpp
@@ -31,8 +31,10 @@
#include <Qt3DAnimation/private/handler_p.h>
#include <Qt3DAnimation/private/channelmapping_p.h>
#include <Qt3DAnimation/qchannelmapping.h>
+#include <Qt3DAnimation/qskeletonmapping.h>
#include <Qt3DAnimation/private/qchannelmapping_p.h>
#include <Qt3DCore/qentity.h>
+#include <Qt3DCore/qskeleton.h>
#include <Qt3DCore/private/qnode_p.h>
#include <Qt3DCore/private/qscene_p.h>
#include <Qt3DCore/qpropertyupdatedchange.h>
@@ -66,6 +68,23 @@ private Q_SLOTS:
QCOMPARE(backendMapping.channelName(), mapping.channelName());
QCOMPARE(backendMapping.targetId(), mapping.target()->id());
QCOMPARE(backendMapping.property(), mapping.property());
+ QCOMPARE(backendMapping.mappingType(), Qt3DAnimation::Animation::ChannelMapping::ChannelMappingType);
+
+ // GIVEN
+ Qt3DAnimation::Animation::ChannelMapping backendSkeletonMapping;
+ backendSkeletonMapping.setHandler(&handler);
+ Qt3DAnimation::QSkeletonMapping skeletonMapping;
+ auto skeleton = new Qt3DCore::QSkeleton;
+ skeletonMapping.setSkeleton(skeleton);
+
+ // WHEN
+ simulateInitialization(&skeletonMapping, &backendSkeletonMapping);
+
+ // THEN
+ QCOMPARE(backendSkeletonMapping.peerId(), skeletonMapping.id());
+ QCOMPARE(backendSkeletonMapping.isEnabled(), skeletonMapping.isEnabled());
+ QCOMPARE(backendSkeletonMapping.skeletonId(), skeletonMapping.skeleton()->id());
+ QCOMPARE(backendSkeletonMapping.mappingType(), Qt3DAnimation::Animation::ChannelMapping::SkeletonMappingType);
}
void checkInitialAndCleanedUpState()
@@ -81,6 +100,8 @@ private Q_SLOTS:
QCOMPARE(backendMapping.channelName(), QString());
QCOMPARE(backendMapping.targetId(), Qt3DCore::QNodeId());
QCOMPARE(backendMapping.property(), QString());
+ QCOMPARE(backendMapping.skeletonId(), Qt3DCore::QNodeId());
+ QCOMPARE(backendMapping.mappingType(), Qt3DAnimation::Animation::ChannelMapping::ChannelMappingType);
// GIVEN
Qt3DAnimation::QChannelMapping mapping;
@@ -91,6 +112,7 @@ private Q_SLOTS:
// WHEN
simulateInitialization(&mapping, &backendMapping);
+ backendMapping.setSkeletonId(Qt3DCore::QNodeId::createId());
backendMapping.cleanup();
// THEN
@@ -98,6 +120,8 @@ private Q_SLOTS:
QCOMPARE(backendMapping.channelName(), QString());
QCOMPARE(backendMapping.targetId(), Qt3DCore::QNodeId());
QCOMPARE(backendMapping.property(), QString());
+ QCOMPARE(backendMapping.skeletonId(), Qt3DCore::QNodeId());
+ QCOMPARE(backendMapping.mappingType(), Qt3DAnimation::Animation::ChannelMapping::ChannelMappingType);
}
void checkPropertyChanges()
@@ -146,6 +170,16 @@ private Q_SLOTS:
// THEN
QCOMPARE(backendMapping.property(), property);
+
+ // WHEN
+ const auto skeletonId = Qt3DCore::QNodeId::createId();
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
+ updateChange->setPropertyName("skeleton");
+ updateChange->setValue(QVariant::fromValue(skeletonId));
+ backendMapping.sceneChangeEvent(updateChange);
+
+ // THEN
+ QCOMPARE(backendMapping.skeletonId(), skeletonId);
}
};
diff --git a/tests/auto/animation/clipanimator/tst_clipanimator.cpp b/tests/auto/animation/clipanimator/tst_clipanimator.cpp
index e837a2a82..168cba050 100644
--- a/tests/auto/animation/clipanimator/tst_clipanimator.cpp
+++ b/tests/auto/animation/clipanimator/tst_clipanimator.cpp
@@ -30,6 +30,7 @@
#include <Qt3DAnimation/private/clipanimator_p.h>
#include <Qt3DAnimation/qanimationcliploader.h>
#include <Qt3DAnimation/qclipanimator.h>
+#include <Qt3DAnimation/qclock.h>
#include <Qt3DCore/private/qnode_p.h>
#include <Qt3DCore/private/qscene_p.h>
#include <Qt3DCore/qpropertyupdatedchange.h>
@@ -50,8 +51,10 @@ private Q_SLOTS:
backendAnimator.setHandler(&handler);
Qt3DAnimation::QClipAnimator animator;
auto clip = new Qt3DAnimation::QAnimationClipLoader();
+ auto clock = new Qt3DAnimation::QClock();
animator.setClip(clip);
+ animator.setClock(clock);
animator.setLoopCount(10);
// WHEN
@@ -61,6 +64,7 @@ private Q_SLOTS:
QCOMPARE(backendAnimator.peerId(), animator.id());
QCOMPARE(backendAnimator.isEnabled(), animator.isEnabled());
QCOMPARE(backendAnimator.clipId(), clip->id());
+ QCOMPARE(backendAnimator.clockId(), clock->id());
QCOMPARE(backendAnimator.isRunning(), animator.isRunning());
QCOMPARE(backendAnimator.loops(), animator.loopCount());
}
@@ -76,23 +80,28 @@ private Q_SLOTS:
QVERIFY(backendAnimator.peerId().isNull());
QCOMPARE(backendAnimator.isEnabled(), false);
QCOMPARE(backendAnimator.clipId(), Qt3DCore::QNodeId());
+ QCOMPARE(backendAnimator.clockId(), Qt3DCore::QNodeId());
QCOMPARE(backendAnimator.isRunning(), false);
QCOMPARE(backendAnimator.loops(), 1);
// GIVEN
Qt3DAnimation::QClipAnimator animator;
auto clip = new Qt3DAnimation::QAnimationClipLoader();
+ auto clock = new Qt3DAnimation::QClock();
animator.setClip(clip);
+ animator.setClock(clock);
animator.setRunning(true);
animator.setLoopCount(25);
// WHEN
simulateInitialization(&animator, &backendAnimator);
backendAnimator.setClipId(Qt3DCore::QNodeId::createId());
+ backendAnimator.setClockId(Qt3DCore::QNodeId::createId());
backendAnimator.cleanup();
// THEN
QCOMPARE(backendAnimator.clipId(), Qt3DCore::QNodeId());
+ QCOMPARE(backendAnimator.clockId(), Qt3DCore::QNodeId());
QCOMPARE(backendAnimator.isEnabled(), false);
QCOMPARE(backendAnimator.isRunning(), false);
QCOMPARE(backendAnimator.loops(), 1);
@@ -126,6 +135,16 @@ private Q_SLOTS:
QCOMPARE(backendAnimator.clipId(), newClip->id());
// WHEN
+ auto clock = new Qt3DAnimation::QClock();
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
+ updateChange->setPropertyName("clock");
+ updateChange->setValue(QVariant::fromValue(clock->id()));
+ backendAnimator.sceneChangeEvent(updateChange);
+
+ // THEN
+ QCOMPARE(backendAnimator.clockId(), clock->id());
+
+ // WHEN
updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setPropertyName("running");
updateChange->setValue(true);
diff --git a/tests/auto/animation/clock/clock.pro b/tests/auto/animation/clock/clock.pro
new file mode 100644
index 000000000..26b7a4b21
--- /dev/null
+++ b/tests/auto/animation/clock/clock.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+
+TARGET = tst_clock
+
+QT += core-private 3dcore 3dcore-private 3danimation 3danimation-private testlib
+
+CONFIG += testcase
+
+SOURCES += \
+ tst_clock.cpp
+
+include(../../core/common/common.pri)
diff --git a/tests/auto/animation/clock/tst_clock.cpp b/tests/auto/animation/clock/tst_clock.cpp
new file mode 100644
index 000000000..a81adfe7b
--- /dev/null
+++ b/tests/auto/animation/clock/tst_clock.cpp
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** 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/qclock.h>
+#include <Qt3DAnimation/private/clock_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>
+
+class tst_Clock: public Qt3DCore::QBackendNodeTester
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void checkPeerPropertyMirroring()
+ {
+ // GIVEN
+ Qt3DAnimation::Animation::Clock backendClock;
+ Qt3DAnimation::QClock clock;
+
+ clock.setPlaybackRate(10.5);
+
+ // WHEN
+ simulateInitialization(&clock, &backendClock);
+
+ // THEN
+ QCOMPARE(backendClock.playbackRate(), clock.playbackRate());
+ }
+
+ void checkInitialAndCleanedUpState()
+ {
+ // GIVEN
+ Qt3DAnimation::Animation::Clock backendClock;
+
+ // THEN
+ QCOMPARE(backendClock.playbackRate(), 1.0);
+
+ // GIVEN
+ Qt3DAnimation::QClock clock;
+ clock.setPlaybackRate(10.5);
+
+ // WHEN
+ simulateInitialization(&clock, &backendClock);
+ backendClock.cleanup();
+
+ // THEN
+ QCOMPARE(backendClock.playbackRate(), 1.0);
+ }
+
+ void checkSceneChangeEvents()
+ {
+ // GIVEN
+ Qt3DAnimation::Animation::Clock backendClock;
+
+ {
+ // WHEN
+ const bool newValue = false;
+ const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
+ change->setPropertyName("enabled");
+ change->setValue(newValue);
+ backendClock.sceneChangeEvent(change);
+
+ // THEN
+ QCOMPARE(backendClock.isEnabled(), newValue);
+ }
+ {
+ // WHEN
+ const double newPlaybackRateValue = 2.0;
+ const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
+ change->setPropertyName("playbackRate");
+ change->setValue(newPlaybackRateValue);
+ backendClock.sceneChangeEvent(change);
+
+ // THEN
+ QCOMPARE(backendClock.playbackRate(), newPlaybackRateValue);
+ }
+ }
+};
+
+QTEST_APPLESS_MAIN(tst_Clock)
+
+#include "tst_clock.moc"
diff --git a/tests/auto/animation/findrunningclipanimatorsjob/tst_findrunningclipanimatorsjob.cpp b/tests/auto/animation/findrunningclipanimatorsjob/tst_findrunningclipanimatorsjob.cpp
index 79d18b7cf..ce37ffc76 100644
--- a/tests/auto/animation/findrunningclipanimatorsjob/tst_findrunningclipanimatorsjob.cpp
+++ b/tests/auto/animation/findrunningclipanimatorsjob/tst_findrunningclipanimatorsjob.cpp
@@ -72,6 +72,7 @@ public:
channelMapping->setPropertyName(propertyName);
channelMapping->setChannelName(channelName);
channelMapping->setType(type);
+ channelMapping->setMappingType(ChannelMapping::ChannelMappingType);
return channelMapping;
}
diff --git a/tests/auto/animation/qcallbackmapping/qcallbackmapping.pro b/tests/auto/animation/qcallbackmapping/qcallbackmapping.pro
new file mode 100644
index 000000000..2ec002878
--- /dev/null
+++ b/tests/auto/animation/qcallbackmapping/qcallbackmapping.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+
+TARGET = tst_qcallbackmapping
+
+QT += 3dcore 3dcore-private 3danimation 3danimation-private testlib
+
+CONFIG += testcase
+
+SOURCES += \
+ tst_qcallbackmapping.cpp
+
+include(../../core/common/common.pri)
diff --git a/tests/auto/animation/qcallbackmapping/tst_qcallbackmapping.cpp b/tests/auto/animation/qcallbackmapping/tst_qcallbackmapping.cpp
new file mode 100644
index 000000000..6a1c8da8c
--- /dev/null
+++ b/tests/auto/animation/qcallbackmapping/tst_qcallbackmapping.cpp
@@ -0,0 +1,223 @@
+/****************************************************************************
+**
+** 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/qcallbackmapping.h>
+#include <Qt3DAnimation/private/qcallbackmapping_p.h>
+#include <Qt3DAnimation/private/qchannelmappingcreatedchange_p.h>
+#include <Qt3DCore/qpropertyupdatedchange.h>
+#include <Qt3DCore/qentity.h>
+#include <Qt3DCore/qnodecreatedchange.h>
+#include <Qt3DCore/private/qnodecreatedchangegenerator_p.h>
+#include <QObject>
+#include <QSignalSpy>
+#include <testpostmanarbiter.h>
+
+class DummyCallback : public Qt3DAnimation::QAnimationCallback
+{
+public:
+ void valueChanged(const QVariant &) override { }
+};
+
+class tst_QCallbackMapping : public QObject
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void checkDefaultConstruction()
+ {
+ // GIVEN
+ Qt3DAnimation::QCallbackMapping mapping;
+
+ // THEN
+ QCOMPARE(mapping.channelName(), QString());
+ QCOMPARE(mapping.callback(), static_cast<Qt3DAnimation::QAnimationCallback *>(nullptr));
+ }
+
+ void checkPropertyChanges()
+ {
+ // GIVEN
+ Qt3DAnimation::QCallbackMapping mapping;
+
+ {
+ // WHEN
+ QSignalSpy spy(&mapping, SIGNAL(channelNameChanged(QString)));
+ const QString newValue(QStringLiteral("Rotation"));
+ mapping.setChannelName(newValue);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(mapping.channelName(), newValue);
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ mapping.setChannelName(newValue);
+
+ // THEN
+ QCOMPARE(mapping.channelName(), newValue);
+ QCOMPARE(spy.count(), 0);
+ }
+
+ {
+ // WHEN
+ auto newValue = new DummyCallback();
+ mapping.setCallback(QVariant::Quaternion, newValue);
+
+ // THEN - no signals for callback
+ QCOMPARE(mapping.callback(), newValue);
+ }
+ }
+
+ void checkCreationData()
+ {
+ // GIVEN
+ Qt3DAnimation::QCallbackMapping mapping;
+ auto callback = new DummyCallback();
+
+ mapping.setChannelName(QStringLiteral("Location"));
+ mapping.setCallback(QVariant::Vector3D, callback);
+
+ // WHEN
+ QVector<Qt3DCore::QNodeCreatedChangeBasePtr> creationChanges;
+
+ {
+ Qt3DCore::QNodeCreatedChangeGenerator creationChangeGenerator(&mapping);
+ creationChanges = creationChangeGenerator.creationChanges();
+ }
+
+ // THEN
+ {
+ QCOMPARE(creationChanges.size(), 1);
+
+ const auto creationChangeData = qSharedPointerCast<Qt3DAnimation::QChannelMappingCreatedChange<Qt3DAnimation::QCallbackMappingData>>(creationChanges.first());
+ const Qt3DAnimation::QCallbackMappingData data = creationChangeData->data;
+
+ QCOMPARE(mapping.id(), creationChangeData->subjectId());
+ QCOMPARE(mapping.isEnabled(), true);
+ QCOMPARE(mapping.isEnabled(), creationChangeData->isNodeEnabled());
+ QCOMPARE(mapping.metaObject(), creationChangeData->metaObject());
+ QCOMPARE(creationChangeData->type(), Qt3DAnimation::QChannelMappingCreatedChangeBase::CallbackMapping);
+ QCOMPARE(mapping.channelName(), data.channelName);
+ QCOMPARE(mapping.callback(), data.callback);
+ QCOMPARE(QVariant::Vector3D, data.type);
+ }
+
+ // WHEN
+ mapping.setEnabled(false);
+
+ {
+ Qt3DCore::QNodeCreatedChangeGenerator creationChangeGenerator(&mapping);
+ creationChanges = creationChangeGenerator.creationChanges();
+ }
+
+ // THEN
+ {
+ QCOMPARE(creationChanges.size(), 1);
+
+ const auto creationChangeData = qSharedPointerCast<Qt3DAnimation::QChannelMappingCreatedChange<Qt3DAnimation::QCallbackMappingData>>(creationChanges.first());
+ const Qt3DAnimation::QCallbackMappingData data = creationChangeData->data;
+
+ QCOMPARE(mapping.id(), creationChangeData->subjectId());
+ QCOMPARE(mapping.isEnabled(), false);
+ QCOMPARE(mapping.isEnabled(), creationChangeData->isNodeEnabled());
+ QCOMPARE(mapping.metaObject(), creationChangeData->metaObject());
+ QCOMPARE(creationChangeData->type(), Qt3DAnimation::QChannelMappingCreatedChangeBase::CallbackMapping);
+ QCOMPARE(mapping.channelName(), data.channelName);
+ QCOMPARE(mapping.callback(), data.callback);
+ QCOMPARE(QVariant::Vector3D, data.type);
+ }
+ }
+
+ void checkPropertyUpdateChanges()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ Qt3DAnimation::QCallbackMapping mapping;
+ arbiter.setArbiterOnNode(&mapping);
+
+ {
+ // WHEN
+ mapping.setChannelName(QStringLiteral("Scale"));
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "channelName");
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+ QCOMPARE(change->value().toString(), mapping.channelName());
+
+ arbiter.events.clear();
+
+ // WHEN
+ mapping.setChannelName(QStringLiteral("Scale"));
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+
+ {
+ // WHEN
+ auto callback = new DummyCallback();
+ mapping.setCallback(QVariant::Vector3D, callback, Qt3DAnimation::QAnimationCallback::OnThreadPool);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 3);
+ auto change = arbiter.events.at(0).staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "type");
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+ QCOMPARE(change->value().toInt(), QVariant::Vector3D);
+
+ change = arbiter.events.at(1).staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "callback");
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+ QCOMPARE(reinterpret_cast<DummyCallback *>(change->value().value<void *>()), callback);
+
+ change = arbiter.events.at(2).staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "callbackFlags");
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+ QCOMPARE(change->value().toInt(), static_cast<int>(Qt3DAnimation::QAnimationCallback::OnThreadPool));
+
+ arbiter.events.clear();
+
+ // WHEN
+ mapping.setCallback(QVariant::Vector3D, callback, Qt3DAnimation::QAnimationCallback::OnThreadPool);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+ }
+};
+
+QTEST_MAIN(tst_QCallbackMapping)
+
+#include "tst_qcallbackmapping.moc"
diff --git a/tests/auto/animation/qchannelmapping/tst_qchannelmapping.cpp b/tests/auto/animation/qchannelmapping/tst_qchannelmapping.cpp
index 9d356de4c..cab5fda6f 100644
--- a/tests/auto/animation/qchannelmapping/tst_qchannelmapping.cpp
+++ b/tests/auto/animation/qchannelmapping/tst_qchannelmapping.cpp
@@ -29,6 +29,7 @@
#include <QtTest/QTest>
#include <Qt3DAnimation/qchannelmapping.h>
#include <Qt3DAnimation/private/qchannelmapping_p.h>
+#include <Qt3DAnimation/private/qchannelmappingcreatedchange_p.h>
#include <Qt3DCore/qpropertyupdatedchange.h>
#include <Qt3DCore/qentity.h>
#include <Qt3DCore/qnodecreatedchange.h>
@@ -142,13 +143,14 @@ private Q_SLOTS:
{
QCOMPARE(creationChanges.size(), 2); // 1 for mapping, 1 for target
- const auto creationChangeData = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<Qt3DAnimation::QChannelMappingData>>(creationChanges.first());
+ const auto creationChangeData = qSharedPointerCast<Qt3DAnimation::QChannelMappingCreatedChange<Qt3DAnimation::QChannelMappingData>>(creationChanges.first());
const Qt3DAnimation::QChannelMappingData data = creationChangeData->data;
QCOMPARE(mapping.id(), creationChangeData->subjectId());
QCOMPARE(mapping.isEnabled(), true);
QCOMPARE(mapping.isEnabled(), creationChangeData->isNodeEnabled());
QCOMPARE(mapping.metaObject(), creationChangeData->metaObject());
+ QCOMPARE(creationChangeData->type(), Qt3DAnimation::QChannelMappingCreatedChangeBase::ChannelMapping);
QCOMPARE(mapping.channelName(), data.channelName);
QCOMPARE(mapping.target()->id(), data.targetId);
QCOMPARE(mapping.property(), data.property);
@@ -166,13 +168,14 @@ private Q_SLOTS:
{
QCOMPARE(creationChanges.size(), 2); // 1 for mapping, 1 for target
- const auto creationChangeData = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<Qt3DAnimation::QChannelMappingData>>(creationChanges.first());
+ const auto creationChangeData = qSharedPointerCast<Qt3DAnimation::QChannelMappingCreatedChange<Qt3DAnimation::QChannelMappingData>>(creationChanges.first());
const Qt3DAnimation::QChannelMappingData data = creationChangeData->data;
QCOMPARE(mapping.id(), creationChangeData->subjectId());
QCOMPARE(mapping.isEnabled(), false);
QCOMPARE(mapping.isEnabled(), creationChangeData->isNodeEnabled());
QCOMPARE(mapping.metaObject(), creationChangeData->metaObject());
+ QCOMPARE(creationChangeData->type(), Qt3DAnimation::QChannelMappingCreatedChangeBase::ChannelMapping);
QCOMPARE(mapping.channelName(), data.channelName);
QCOMPARE(mapping.target()->id(), data.targetId);
QCOMPARE(mapping.property(), data.property);
diff --git a/tests/auto/animation/qclipanimator/tst_qclipanimator.cpp b/tests/auto/animation/qclipanimator/tst_qclipanimator.cpp
index 1ed4b8f13..6a46b7008 100644
--- a/tests/auto/animation/qclipanimator/tst_qclipanimator.cpp
+++ b/tests/auto/animation/qclipanimator/tst_qclipanimator.cpp
@@ -30,6 +30,7 @@
#include <QtTest/QTest>
#include <Qt3DAnimation/qanimationcliploader.h>
#include <Qt3DAnimation/qchannelmapper.h>
+#include <Qt3DAnimation/qclock.h>
#include <Qt3DAnimation/qclipanimator.h>
#include <Qt3DAnimation/private/qanimationclip_p.h>
#include <Qt3DAnimation/private/qclipanimator_p.h>
@@ -49,6 +50,7 @@ private Q_SLOTS:
{
qRegisterMetaType<Qt3DAnimation::QAbstractAnimationClip*>();
qRegisterMetaType<Qt3DAnimation::QChannelMapper*>();
+ qRegisterMetaType<Qt3DAnimation::QClock*>();
}
void checkDefaultConstruction()
@@ -59,6 +61,7 @@ private Q_SLOTS:
// THEN
QCOMPARE(animator.clip(), static_cast<Qt3DAnimation::QAbstractAnimationClip *>(nullptr));
QCOMPARE(animator.channelMapper(), static_cast<Qt3DAnimation::QChannelMapper *>(nullptr));
+ QCOMPARE(animator.clock(), static_cast<Qt3DAnimation::QClock*>(nullptr));
QCOMPARE(animator.loopCount(), 1);
}
@@ -111,6 +114,27 @@ private Q_SLOTS:
{
// WHEN
+ QSignalSpy spy(&animator, SIGNAL(clockChanged(Qt3DAnimation::QClock *)));
+ auto clock = new Qt3DAnimation::QClock();
+ animator.setClock(clock);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(animator.clock(), clock);
+ QCOMPARE(clock->parent(), &animator);
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ animator.setClock(clock);
+
+ // THEN
+ QCOMPARE(animator.clock(), clock);
+ QCOMPARE(spy.count(), 0);
+ }
+
+ {
+ // WHEN
QSignalSpy spy(&animator, SIGNAL(loopCountChanged(int)));
const int newValue = 5;
animator.setLoopCount(newValue);
@@ -138,6 +162,8 @@ private Q_SLOTS:
animator.setClip(clip);
auto mapper = new Qt3DAnimation::QChannelMapper();
animator.setChannelMapper(mapper);
+ auto clock = new Qt3DAnimation::QClock();
+ animator.setClock(clock);
// WHEN
QVector<Qt3DCore::QNodeCreatedChangeBasePtr> creationChanges;
@@ -148,7 +174,7 @@ private Q_SLOTS:
// THEN
{
- QCOMPARE(creationChanges.size(), 3);
+ QCOMPARE(creationChanges.size(), 4);
const auto creationChangeData = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<Qt3DAnimation::QClipAnimatorData>>(creationChanges.first());
const Qt3DAnimation::QClipAnimatorData data = creationChangeData->data;
@@ -159,6 +185,7 @@ private Q_SLOTS:
QCOMPARE(animator.metaObject(), creationChangeData->metaObject());
QCOMPARE(animator.clip()->id(), data.clipId);
QCOMPARE(animator.channelMapper()->id(), data.mapperId);
+ QCOMPARE(animator.clock()->id(), data.clockId);
QCOMPARE(animator.loopCount(), data.loops);
}
@@ -171,7 +198,7 @@ private Q_SLOTS:
// THEN
{
- QCOMPARE(creationChanges.size(), 3);
+ QCOMPARE(creationChanges.size(), 4);
const auto creationChangeData = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<Qt3DAnimation::QClipAnimatorData>>(creationChanges.first());
@@ -240,6 +267,32 @@ private Q_SLOTS:
QCOMPARE(arbiter.events.size(), 0);
}
+ // GIVEN
+ auto clock = new Qt3DAnimation::QClock;
+ {
+ // WHEN
+ animator.setClock(clock);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "clock");
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+ QCOMPARE(change->value().value<Qt3DCore::QNodeId>(), clock->id());
+
+ arbiter.events.clear();
+ }
+
+ {
+ // WHEN
+ animator.setClock(clock);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+
{
// WHEN
animator.setLoopCount(10);
diff --git a/tests/auto/animation/qclock/qclock.pro b/tests/auto/animation/qclock/qclock.pro
new file mode 100644
index 000000000..2b1194860
--- /dev/null
+++ b/tests/auto/animation/qclock/qclock.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+
+TARGET = tst_qclock
+
+QT += 3dcore 3dcore-private 3danimation 3danimation-private testlib
+
+CONFIG += testcase
+
+SOURCES += \
+ tst_qclock.cpp
+
+include(../../core/common/common.pri)
diff --git a/tests/auto/animation/qclock/tst_qclock.cpp b/tests/auto/animation/qclock/tst_qclock.cpp
new file mode 100644
index 000000000..34c70da7b
--- /dev/null
+++ b/tests/auto/animation/qclock/tst_qclock.cpp
@@ -0,0 +1,165 @@
+/****************************************************************************
+**
+** 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/qclock.h>
+#include <Qt3DAnimation/private/qclock_p.h>
+#include <Qt3DCore/qpropertyupdatedchange.h>
+#include <Qt3DCore/qnodecreatedchange.h>
+#include <Qt3DCore/private/qnodecreatedchangegenerator_p.h>
+#include <QObject>
+#include <QSignalSpy>
+#include <testpostmanarbiter.h>
+
+class tst_QClock : public QObject
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void initTestCase()
+ {
+ qRegisterMetaType<Qt3DAnimation::QClock*>();
+ }
+
+ void checkDefaultConstruction()
+ {
+ // GIVEN
+ Qt3DAnimation::QClock clock;
+
+ // THEN
+ QCOMPARE(clock.playbackRate(), 1.0);
+ }
+
+ void checkPropertyChanges()
+ {
+ // GIVEN
+ Qt3DAnimation::QClock clock;
+
+ // WHEN
+ QSignalSpy spy(&clock, SIGNAL(playbackRateChanged(double)));
+ const double newValue = 5.5;
+ clock.setPlaybackRate(newValue);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(clock.playbackRate(), newValue);
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ clock.setPlaybackRate(newValue);
+
+ // THEN
+ QCOMPARE(clock.playbackRate(), newValue);
+ QCOMPARE(spy.count(), 0);
+ }
+
+ void checkCreationData()
+ {
+ // GIVEN
+ Qt3DAnimation::QClock clock;
+ clock.setPlaybackRate(10.f);
+
+ // WHEN
+ QVector<Qt3DCore::QNodeCreatedChangeBasePtr> creationChanges;
+ {
+ Qt3DCore::QNodeCreatedChangeGenerator creationChangeGenerator(&clock);
+ creationChanges = creationChangeGenerator.creationChanges();
+ }
+
+ // THEN
+ {
+ QCOMPARE(creationChanges.size(), 1);
+
+ const auto creationChangeData = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<Qt3DAnimation::QClockData>>(creationChanges.first());
+ const Qt3DAnimation::QClockData data = creationChangeData->data;
+
+ QCOMPARE(clock.id(), creationChangeData->subjectId());
+ QCOMPARE(clock.isEnabled(), true);
+ QCOMPARE(clock.isEnabled(), creationChangeData->isNodeEnabled());
+ QCOMPARE(clock.metaObject(), creationChangeData->metaObject());
+ QCOMPARE(clock.playbackRate(), data.playbackRate);
+ }
+
+ // WHEN
+ clock.setEnabled(false);
+ {
+ Qt3DCore::QNodeCreatedChangeGenerator creationChangeGenerator(&clock);
+ creationChanges = creationChangeGenerator.creationChanges();
+ }
+
+ // THEN
+ {
+ QCOMPARE(creationChanges.size(), 1);
+
+ const auto creationChangeData = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<Qt3DAnimation::QClockData>>(creationChanges.first());
+
+ QCOMPARE(clock.id(), creationChangeData->subjectId());
+ QCOMPARE(clock.isEnabled(), false);
+ QCOMPARE(clock.isEnabled(), creationChangeData->isNodeEnabled());
+ QCOMPARE(clock.metaObject(), creationChangeData->metaObject());
+ }
+ }
+
+ void checkPropertyUpdate()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ Qt3DAnimation::QClock clock;
+ arbiter.setArbiterOnNode(&clock);
+
+ {
+ // WHEN
+ clock.setPlaybackRate(10.5);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "playbackRate");
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+ QCOMPARE(change->value().value<double>(), clock.playbackRate());
+
+ arbiter.events.clear();
+ }
+
+ {
+ // WHEN
+ clock.setPlaybackRate(10.5f);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+ }
+};
+
+QTEST_MAIN(tst_QClock)
+
+#include "tst_qclock.moc"
diff --git a/tests/auto/animation/qskeletonmapping/qskeletonmapping.pro b/tests/auto/animation/qskeletonmapping/qskeletonmapping.pro
new file mode 100644
index 000000000..c00252557
--- /dev/null
+++ b/tests/auto/animation/qskeletonmapping/qskeletonmapping.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+
+TARGET = tst_qskeletonmapping
+
+QT += 3dcore 3dcore-private 3danimation 3danimation-private testlib
+
+CONFIG += testcase
+
+SOURCES += \
+ tst_qskeletonmapping.cpp
+
+include(../../core/common/common.pri)
diff --git a/tests/auto/animation/qskeletonmapping/tst_qskeletonmapping.cpp b/tests/auto/animation/qskeletonmapping/tst_qskeletonmapping.cpp
new file mode 100644
index 000000000..452292e9e
--- /dev/null
+++ b/tests/auto/animation/qskeletonmapping/tst_qskeletonmapping.cpp
@@ -0,0 +1,175 @@
+/****************************************************************************
+**
+** 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/qskeletonmapping.h>
+#include <Qt3DAnimation/private/qskeletonmapping_p.h>
+#include <Qt3DCore/qskeleton.h>
+#include <Qt3DCore/qpropertyupdatedchange.h>
+#include <Qt3DCore/qentity.h>
+#include <Qt3DCore/qnodecreatedchange.h>
+#include <Qt3DCore/private/qnodecreatedchangegenerator_p.h>
+#include <QObject>
+#include <QSignalSpy>
+#include <testpostmanarbiter.h>
+
+class tst_QSkeletonMapping : public QObject
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void initTestCase()
+ {
+ qRegisterMetaType<Qt3DCore::QAbstractSkeleton*>();
+ }
+
+ void checkDefaultConstruction()
+ {
+ // GIVEN
+ Qt3DAnimation::QSkeletonMapping mapping;
+
+ // THEN
+ QCOMPARE(mapping.skeleton(), static_cast<Qt3DCore::QAbstractSkeleton *>(nullptr));
+ }
+
+ void checkPropertyChanges()
+ {
+ // GIVEN
+ Qt3DAnimation::QSkeletonMapping mapping;
+
+ {
+ // WHEN
+ QSignalSpy spy(&mapping, SIGNAL(skeletonChanged(Qt3DCore::QAbstractSkeleton*)));
+ auto newValue = new Qt3DCore::QSkeleton();
+ mapping.setSkeleton(newValue);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(mapping.skeleton(), newValue);
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ mapping.setSkeleton(newValue);
+
+ // THEN
+ QCOMPARE(mapping.skeleton(), newValue);
+ QCOMPARE(spy.count(), 0);
+ }
+ }
+
+ void checkCreationData()
+ {
+ // GIVEN
+ Qt3DAnimation::QSkeletonMapping mapping;
+ auto target = new Qt3DCore::QSkeleton;
+
+ mapping.setSkeleton(target);
+
+ // WHEN
+ QVector<Qt3DCore::QNodeCreatedChangeBasePtr> creationChanges;
+
+ {
+ Qt3DCore::QNodeCreatedChangeGenerator creationChangeGenerator(&mapping);
+ creationChanges = creationChangeGenerator.creationChanges();
+ }
+
+ // THEN
+ {
+ QCOMPARE(creationChanges.size(), 2); // 1 for mapping, 1 for skeleton
+
+ const auto creationChangeData = qSharedPointerCast<Qt3DAnimation::QChannelMappingCreatedChange<Qt3DAnimation::QSkeletonMappingData>>(creationChanges.first());
+ const Qt3DAnimation::QSkeletonMappingData data = creationChangeData->data;
+
+ QCOMPARE(mapping.id(), creationChangeData->subjectId());
+ QCOMPARE(mapping.isEnabled(), true);
+ QCOMPARE(mapping.isEnabled(), creationChangeData->isNodeEnabled());
+ QCOMPARE(mapping.metaObject(), creationChangeData->metaObject());
+ QCOMPARE(creationChangeData->type(), Qt3DAnimation::QChannelMappingCreatedChangeBase::SkeletonMapping);
+ QCOMPARE(mapping.skeleton()->id(), data.skeletonId);
+ }
+
+ // WHEN
+ mapping.setEnabled(false);
+
+ {
+ Qt3DCore::QNodeCreatedChangeGenerator creationChangeGenerator(&mapping);
+ creationChanges = creationChangeGenerator.creationChanges();
+ }
+
+ // THEN
+ {
+ QCOMPARE(creationChanges.size(), 2); // 1 for mapping, 1 for skeleton
+
+ const auto creationChangeData = qSharedPointerCast<Qt3DAnimation::QChannelMappingCreatedChange<Qt3DAnimation::QSkeletonMappingData>>(creationChanges.first());
+ const Qt3DAnimation::QSkeletonMappingData data = creationChangeData->data;
+
+ QCOMPARE(mapping.id(), creationChangeData->subjectId());
+ QCOMPARE(mapping.isEnabled(), false);
+ QCOMPARE(mapping.isEnabled(), creationChangeData->isNodeEnabled());
+ QCOMPARE(mapping.metaObject(), creationChangeData->metaObject());
+ QCOMPARE(creationChangeData->type(), Qt3DAnimation::QChannelMappingCreatedChangeBase::SkeletonMapping);
+ QCOMPARE(mapping.skeleton()->id(), data.skeletonId);
+ }
+ }
+
+ void checkPropertyUpdateChanges()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ Qt3DAnimation::QSkeletonMapping mapping;
+ arbiter.setArbiterOnNode(&mapping);
+
+ {
+ // WHEN
+ auto target = new Qt3DCore::QSkeleton();
+ mapping.setSkeleton(target);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "skeleton");
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+ QCOMPARE(change->value().value<Qt3DCore::QNodeId>(), mapping.skeleton()->id());
+
+ arbiter.events.clear();
+
+ // WHEN
+ mapping.setSkeleton(target);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+ }
+};
+
+QTEST_MAIN(tst_QSkeletonMapping)
+
+#include "tst_qskeletonmapping.moc"
diff --git a/tests/auto/animation/skeleton/skeleton.pro b/tests/auto/animation/skeleton/skeleton.pro
new file mode 100644
index 000000000..b36278bdf
--- /dev/null
+++ b/tests/auto/animation/skeleton/skeleton.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+
+TARGET = tst_skeleton
+
+QT += core-private 3dcore 3dcore-private 3danimation 3danimation-private testlib
+
+CONFIG += testcase
+
+SOURCES += \
+ tst_skeleton.cpp
+
+include(../../core/common/common.pri)
diff --git a/tests/auto/animation/skeleton/tst_skeleton.cpp b/tests/auto/animation/skeleton/tst_skeleton.cpp
new file mode 100644
index 000000000..9e3cfef6d
--- /dev/null
+++ b/tests/auto/animation/skeleton/tst_skeleton.cpp
@@ -0,0 +1,146 @@
+/****************************************************************************
+**
+** 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 <Qt3DCore/qjoint.h>
+#include <Qt3DCore/qskeleton.h>
+#include <Qt3DAnimation/private/skeleton_p.h>
+#include <Qt3DAnimation/private/handler_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 Qt3DCore;
+using namespace Qt3DAnimation;
+using namespace Qt3DAnimation::Animation;
+
+class tst_Skeleton : public QBackendNodeTester
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void checkPeerPropertyMirroring()
+ {
+ // GIVEN
+ Handler handler;
+ Skeleton backendSkeleton;
+ backendSkeleton.setHandler(&handler);
+ QSkeleton skeleton;
+ auto rootJoint = new QJoint();
+ rootJoint->setName(QLatin1String("rootJoint"));
+ auto childJoint = new QJoint();
+ childJoint->setName(QLatin1String("childJoint"));
+ rootJoint->addChildJoint(childJoint);
+ skeleton.setRootJoint(rootJoint);
+
+ // WHEN
+ simulateInitialization(&skeleton, &backendSkeleton);
+
+ // THEN - nothing mirrored from frontend
+ QCOMPARE(backendSkeleton.peerId(), skeleton.id());
+ QCOMPARE(backendSkeleton.isEnabled(), skeleton.isEnabled());
+ QCOMPARE(backendSkeleton.jointNames().size(), 0);
+ QCOMPARE(backendSkeleton.jointLocalPoses().size(), 0);
+ }
+
+ void checkInitialAndCleanedUpState()
+ {
+ // GIVEN
+ Handler handler;
+ Skeleton backendSkeleton;
+ backendSkeleton.setHandler(&handler);
+
+ // THEN
+ QVERIFY(backendSkeleton.peerId().isNull());
+ QCOMPARE(backendSkeleton.isEnabled(), false);
+ QCOMPARE(backendSkeleton.jointNames().size(), 0);
+ QCOMPARE(backendSkeleton.jointLocalPoses().size(), 0);
+
+ // GIVEN
+ const QVector<QString> names = (QVector<QString>()
+ << QLatin1String("root")
+ << QLatin1String("child1")
+ << QLatin1String("child2"));
+ const QVector<Sqt> localPoses = (QVector<Sqt>() << Sqt() << Sqt() << Sqt());
+
+ // WHEN
+ backendSkeleton.setJointNames(names);
+ backendSkeleton.setJointLocalPoses(localPoses);
+ backendSkeleton.cleanup();
+
+ // THEN
+ QCOMPARE(backendSkeleton.isEnabled(), false);
+ QCOMPARE(backendSkeleton.jointNames().size(), 0);
+ QCOMPARE(backendSkeleton.jointLocalPoses().size(), 0);
+ }
+
+ void checkPropertyChanges()
+ {
+ // GIVEN
+ Handler handler;
+ Skeleton backendSkeleton;
+ backendSkeleton.setHandler(&handler);
+ QPropertyUpdatedChangePtr updateChange;
+
+ // WHEN
+ updateChange = QPropertyUpdatedChangePtr::create(QNodeId());
+ updateChange->setPropertyName("enabled");
+ updateChange->setValue(true);
+ backendSkeleton.sceneChangeEvent(updateChange);
+
+ // THEN
+ QCOMPARE(backendSkeleton.isEnabled(), true);
+
+ // GIVEN
+ const QVector<QString> names = (QVector<QString>()
+ << QLatin1String("root")
+ << QLatin1String("child1")
+ << QLatin1String("child2"));
+ const QVector<Sqt> localPoses = (QVector<Sqt>() << Sqt() << Sqt() << Sqt());
+
+ // WHEN
+ JointNamesAndLocalPoses namesAndPoses;
+ namesAndPoses.names = names;
+ namesAndPoses.localPoses = localPoses;
+
+ updateChange = QPropertyUpdatedChangePtr::create(QNodeId());
+ updateChange->setPropertyName("jointNamesAndLocalPoses");
+ updateChange->setValue(QVariant::fromValue(namesAndPoses));
+ backendSkeleton.sceneChangeEvent(updateChange);
+
+ // THEN
+ QCOMPARE(backendSkeleton.jointNames(), names);
+ QCOMPARE(backendSkeleton.jointLocalPoses(), localPoses);
+ }
+};
+
+QTEST_APPLESS_MAIN(tst_Skeleton)
+
+#include "tst_skeleton.moc"