|
@@ -1,785 +1,784 @@
|
|
|
-/******************************************************************************
|
|
|
- * Spine Runtimes Software License
|
|
|
- * Version 2.3
|
|
|
- *
|
|
|
- * Copyright (c) 2013-2015, Esoteric Software
|
|
|
- * All rights reserved.
|
|
|
- *
|
|
|
- * You are granted a perpetual, non-exclusive, non-sublicensable and
|
|
|
- * non-transferable license to use, install, execute and perform the Spine
|
|
|
- * Runtimes Software (the "Software") and derivative works solely for personal
|
|
|
- * or internal use. Without the written permission of Esoteric Software (see
|
|
|
- * Section 2 of the Spine Software License Agreement), you may not (a) modify,
|
|
|
- * translate, adapt or otherwise create derivative works, improvements of the
|
|
|
- * Software or develop new applications using the Software or (b) remove,
|
|
|
- * delete, alter or obscure any trademarks or any copyright, trademark, patent
|
|
|
- * or other intellectual property or proprietary rights notices on or in the
|
|
|
- * Software, including any copy thereof. Redistributions in binary or source
|
|
|
- * form must include this license and terms.
|
|
|
- *
|
|
|
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
|
|
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
|
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
|
|
- * EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
|
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
|
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
|
|
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
|
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
|
|
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
|
|
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
+/******************************************************************************
|
|
|
+ * Spine Runtimes Software License v2.5
|
|
|
+ *
|
|
|
+ * Copyright (c) 2013-2016, Esoteric Software
|
|
|
+ * All rights reserved.
|
|
|
+ *
|
|
|
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
|
|
|
+ * non-transferable license to use, install, execute, and perform the Spine
|
|
|
+ * Runtimes software and derivative works solely for personal or internal
|
|
|
+ * use. Without the written permission of Esoteric Software (see Section 2 of
|
|
|
+ * the Spine Software License Agreement), you may not (a) modify, translate,
|
|
|
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
|
|
|
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
|
|
|
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
|
|
|
+ * or other intellectual property or proprietary rights notices on or in the
|
|
|
+ * Software, including any copy thereof. Redistributions in binary or source
|
|
|
+ * form must include this license and terms.
|
|
|
+ *
|
|
|
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
|
|
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
|
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
|
|
+ * EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
|
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
|
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
|
|
|
+ * USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
|
|
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
|
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
+ * POSSIBILITY OF SUCH DAMAGE.
|
|
|
*****************************************************************************/
|
|
|
|
|
|
-package com.esotericsoftware.spine;
|
|
|
-
|
|
|
-import com.badlogic.gdx.Files.FileType;
|
|
|
-import com.badlogic.gdx.backends.lwjgl.LwjglFileHandle;
|
|
|
-import com.badlogic.gdx.math.MathUtils;
|
|
|
-import com.badlogic.gdx.utils.Array;
|
|
|
-import com.esotericsoftware.spine.AnimationState.AnimationStateListener;
|
|
|
-import com.esotericsoftware.spine.AnimationState.TrackEntry;
|
|
|
-import com.esotericsoftware.spine.attachments.AttachmentLoader;
|
|
|
-import com.esotericsoftware.spine.attachments.BoundingBoxAttachment;
|
|
|
-import com.esotericsoftware.spine.attachments.MeshAttachment;
|
|
|
-import com.esotericsoftware.spine.attachments.PathAttachment;
|
|
|
-import com.esotericsoftware.spine.attachments.RegionAttachment;
|
|
|
-
|
|
|
-public class AnimationStateTests {
|
|
|
- final SkeletonJson json = new SkeletonJson(new AttachmentLoader() {
|
|
|
- public RegionAttachment newRegionAttachment (Skin skin, String name, String path) {
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
- public MeshAttachment newMeshAttachment (Skin skin, String name, String path) {
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
- public BoundingBoxAttachment newBoundingBoxAttachment (Skin skin, String name) {
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
- public PathAttachment newPathAttachment (Skin skin, String name) {
|
|
|
- return null;
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- final AnimationStateListener stateListener = new AnimationStateListener() {
|
|
|
- public void start (TrackEntry entry) {
|
|
|
- add(actual("start", entry));
|
|
|
- }
|
|
|
-
|
|
|
- public void interrupt (TrackEntry entry) {
|
|
|
- add(actual("interrupt", entry));
|
|
|
- }
|
|
|
-
|
|
|
- public void end (TrackEntry entry) {
|
|
|
- add(actual("end", entry));
|
|
|
- }
|
|
|
-
|
|
|
- public void dispose (TrackEntry entry) {
|
|
|
- add(actual("dispose", entry));
|
|
|
- }
|
|
|
-
|
|
|
- public void complete (TrackEntry entry) {
|
|
|
- add(actual("complete", entry));
|
|
|
- }
|
|
|
-
|
|
|
- public void event (TrackEntry entry, Event event) {
|
|
|
- add(actual("event " + event.getString(), entry));
|
|
|
- }
|
|
|
-
|
|
|
- private void add (Result result) {
|
|
|
- String message = result.toString();
|
|
|
- if (actual.size >= expected.size) {
|
|
|
- message += "FAIL: <none>";
|
|
|
- fail = true;
|
|
|
- } else if (!expected.get(actual.size).equals(result)) {
|
|
|
- message += "FAIL: " + expected.get(actual.size);
|
|
|
- fail = true;
|
|
|
- } else
|
|
|
- message += "PASS";
|
|
|
- log(message);
|
|
|
- actual.add(result);
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- final SkeletonData skeletonData;
|
|
|
- final Array<Result> actual = new Array();
|
|
|
- final Array<Result> expected = new Array();
|
|
|
-
|
|
|
- AnimationStateData stateData;
|
|
|
- AnimationState state;
|
|
|
- float time = 0;
|
|
|
- boolean fail;
|
|
|
- int test;
|
|
|
-
|
|
|
- AnimationStateTests () {
|
|
|
- skeletonData = json.readSkeletonData(new LwjglFileHandle("test/test.json", FileType.Internal));
|
|
|
-
|
|
|
- TrackEntry entry;
|
|
|
-
|
|
|
- setup("0.1 time step", // 1
|
|
|
- expect(0, "start", 0, 0), //
|
|
|
- expect(0, "event 0", 0, 0), //
|
|
|
- expect(0, "event 14", 0.5f, 0.5f), //
|
|
|
- expect(0, "event 30", 1, 1), //
|
|
|
- expect(0, "complete", 1, 1), //
|
|
|
- expect(0, "end", 1, 1.1f), //
|
|
|
- expect(0, "dispose", 1, 1.1f) //
|
|
|
- );
|
|
|
- state.setAnimation(0, "events1", false);
|
|
|
- run(0.1f, 1000, null);
|
|
|
-
|
|
|
- setup("1/60 time step, dispose queued", // 2
|
|
|
- expect(0, "start", 0, 0), //
|
|
|
- expect(0, "interrupt", 0, 0), //
|
|
|
- expect(0, "end", 0, 0), //
|
|
|
- expect(0, "dispose", 0, 0), //
|
|
|
- expect(1, "dispose", 0, 0), //
|
|
|
- expect(0, "dispose", 0, 0), //
|
|
|
- expect(1, "dispose", 0, 0), //
|
|
|
-
|
|
|
- // First 2 set/addAnimation calls are done.
|
|
|
-
|
|
|
- expect(0, "start", 0, 0), //
|
|
|
- expect(0, "event 0", 0, 0), //
|
|
|
- expect(0, "event 14", 0.467f, 0.467f), //
|
|
|
- expect(0, "event 30", 1, 1), //
|
|
|
- expect(0, "complete", 1, 1), //
|
|
|
- expect(0, "end", 1, 1.017f), //
|
|
|
- expect(0, "dispose", 1, 1.017f) //
|
|
|
- );
|
|
|
- state.setAnimation(0, "events1", false);
|
|
|
- state.addAnimation(0, "events2", false, 0);
|
|
|
- state.addAnimation(0, "events1", false, 0);
|
|
|
- state.addAnimation(0, "events2", false, 0);
|
|
|
- state.setAnimation(0, "events1", false);
|
|
|
- run(1 / 60f, 1000, null);
|
|
|
-
|
|
|
- setup("30 time step", // 3
|
|
|
- expect(0, "start", 0, 0), //
|
|
|
- expect(0, "event 0", 0, 0), //
|
|
|
- expect(0, "event 14", 30, 30), //
|
|
|
- expect(0, "event 30", 30, 30), //
|
|
|
- expect(0, "complete", 30, 30), //
|
|
|
- expect(0, "end", 30, 60), //
|
|
|
- expect(0, "dispose", 30, 60) //
|
|
|
- );
|
|
|
- state.setAnimation(0, "events1", false);
|
|
|
- run(30, 1000, null);
|
|
|
-
|
|
|
- setup("1 time step", // 4
|
|
|
- expect(0, "start", 0, 0), //
|
|
|
- expect(0, "event 0", 0, 0), //
|
|
|
- expect(0, "event 14", 1, 1), //
|
|
|
- expect(0, "event 30", 1, 1), //
|
|
|
- expect(0, "complete", 1, 1), //
|
|
|
- expect(0, "end", 1, 2), //
|
|
|
- expect(0, "dispose", 1, 2) //
|
|
|
- );
|
|
|
- state.setAnimation(0, "events1", false);
|
|
|
- run(1, 1.01f, null);
|
|
|
-
|
|
|
- setup("interrupt", // 5
|
|
|
- expect(0, "start", 0, 0), //
|
|
|
- expect(0, "event 0", 0, 0), //
|
|
|
- expect(0, "event 14", 0.5f, 0.5f), //
|
|
|
- expect(0, "event 30", 1, 1), //
|
|
|
- expect(0, "complete", 1, 1), //
|
|
|
- expect(0, "interrupt", 1.1f, 1.1f), //
|
|
|
-
|
|
|
- expect(1, "start", 0.1f, 1.1f), //
|
|
|
- expect(1, "event 0", 0.1f, 1.1f), //
|
|
|
-
|
|
|
- expect(0, "end", 1.1f, 1.2f), //
|
|
|
- expect(0, "dispose", 1.1f, 1.2f), //
|
|
|
-
|
|
|
- expect(1, "event 14", 0.5f, 1.5f), //
|
|
|
- expect(1, "event 30", 1, 2), //
|
|
|
- expect(1, "complete", 1, 2), //
|
|
|
- expect(1, "interrupt", 1.1f, 2.1f), //
|
|
|
-
|
|
|
- expect(0, "start", 0.1f, 2.1f), //
|
|
|
- expect(0, "event 0", 0.1f, 2.1f), //
|
|
|
-
|
|
|
- expect(1, "end", 1.1f, 2.2f), //
|
|
|
- expect(1, "dispose", 1.1f, 2.2f), //
|
|
|
-
|
|
|
- expect(0, "event 14", 0.5f, 2.5f), //
|
|
|
- expect(0, "event 30", 1, 3), //
|
|
|
- expect(0, "complete", 1, 3), //
|
|
|
- expect(0, "end", 1, 3.1f), //
|
|
|
- expect(0, "dispose", 1, 3.1f) //
|
|
|
- );
|
|
|
- state.setAnimation(0, "events1", false);
|
|
|
- state.addAnimation(0, "events2", false, 0);
|
|
|
- state.addAnimation(0, "events1", false, 0);
|
|
|
- run(0.1f, 4f, null);
|
|
|
-
|
|
|
- setup("interrupt with delay", // 6
|
|
|
- expect(0, "start", 0, 0), //
|
|
|
- expect(0, "event 0", 0, 0), //
|
|
|
- expect(0, "event 14", 0.5f, 0.5f), //
|
|
|
- expect(0, "interrupt", 0.6f, 0.6f), //
|
|
|
-
|
|
|
- expect(1, "start", 0.1f, 0.6f), //
|
|
|
- expect(1, "event 0", 0.1f, 0.6f), //
|
|
|
-
|
|
|
- expect(0, "end", 0.6f, 0.7f), //
|
|
|
- expect(0, "dispose", 0.6f, 0.7f), //
|
|
|
-
|
|
|
- expect(1, "event 14", 0.5f, 1.0f), //
|
|
|
- expect(1, "event 30", 1, 1.5f), //
|
|
|
- expect(1, "complete", 1, 1.5f), //
|
|
|
- expect(1, "end", 1, 1.6f), //
|
|
|
- expect(1, "dispose", 1, 1.6f) //
|
|
|
- );
|
|
|
- state.setAnimation(0, "events1", false);
|
|
|
- state.addAnimation(0, "events2", false, 0.5f);
|
|
|
- run(0.1f, 1000, null);
|
|
|
-
|
|
|
- setup("interrupt with delay and mix time", // 7
|
|
|
- expect(0, "start", 0, 0), //
|
|
|
- expect(0, "event 0", 0, 0), //
|
|
|
- expect(0, "event 14", 0.5f, 0.5f), //
|
|
|
- expect(0, "interrupt", 1, 1), //
|
|
|
-
|
|
|
- expect(1, "start", 0.1f, 1), //
|
|
|
-
|
|
|
- expect(0, "complete", 1, 1), //
|
|
|
-
|
|
|
- expect(1, "event 0", 0.1f, 1), //
|
|
|
- expect(1, "event 14", 0.5f, 1.4f), //
|
|
|
-
|
|
|
- expect(0, "end", 1.6f, 1.7f), //
|
|
|
- expect(0, "dispose", 1.6f, 1.7f), //
|
|
|
-
|
|
|
- expect(1, "event 30", 1, 1.9f), //
|
|
|
- expect(1, "complete", 1, 1.9f), //
|
|
|
- expect(1, "end", 1, 2), //
|
|
|
- expect(1, "dispose", 1, 2) //
|
|
|
- );
|
|
|
- stateData.setMix("events1", "events2", 0.7f);
|
|
|
- state.setAnimation(0, "events1", true);
|
|
|
- state.addAnimation(0, "events2", false, 0.9f);
|
|
|
- run(0.1f, 1000, null);
|
|
|
-
|
|
|
- setup("animation 0 events do not fire during mix", // 8
|
|
|
- expect(0, "start", 0, 0), //
|
|
|
- expect(0, "event 0", 0, 0), //
|
|
|
- expect(0, "interrupt", 0.5f, 0.5f), //
|
|
|
-
|
|
|
- expect(1, "start", 0.1f, 0.5f), //
|
|
|
- expect(1, "event 0", 0.1f, 0.5f), //
|
|
|
- expect(1, "event 14", 0.5f, 0.9f), //
|
|
|
-
|
|
|
- expect(0, "complete", 1, 1), //
|
|
|
- expect(0, "end", 1.1f, 1.2f), //
|
|
|
- expect(0, "dispose", 1.1f, 1.2f), //
|
|
|
-
|
|
|
- expect(1, "event 30", 1, 1.4f), //
|
|
|
- expect(1, "complete", 1, 1.4f), //
|
|
|
- expect(1, "end", 1, 1.5f), //
|
|
|
- expect(1, "dispose", 1, 1.5f) //
|
|
|
- );
|
|
|
- stateData.setDefaultMix(0.7f);
|
|
|
- state.setAnimation(0, "events1", false);
|
|
|
- state.addAnimation(0, "events2", false, 0.4f);
|
|
|
- run(0.1f, 1000, null);
|
|
|
-
|
|
|
- setup("event threshold, some animation 0 events fire during mix", // 9
|
|
|
- expect(0, "start", 0, 0), //
|
|
|
- expect(0, "event 0", 0, 0), //
|
|
|
- expect(0, "interrupt", 0.5f, 0.5f), //
|
|
|
-
|
|
|
- expect(1, "start", 0.1f, 0.5f), //
|
|
|
-
|
|
|
- expect(0, "event 14", 0.5f, 0.5f), //
|
|
|
-
|
|
|
- expect(1, "event 0", 0.1f, 0.5f), //
|
|
|
- expect(1, "event 14", 0.5f, 0.9f), //
|
|
|
-
|
|
|
- expect(0, "complete", 1, 1), //
|
|
|
- expect(0, "end", 1.1f, 1.2f), //
|
|
|
- expect(0, "dispose", 1.1f, 1.2f), //
|
|
|
-
|
|
|
- expect(1, "event 30", 1, 1.4f), //
|
|
|
- expect(1, "complete", 1, 1.4f), //
|
|
|
- expect(1, "end", 1, 1.5f), //
|
|
|
- expect(1, "dispose", 1, 1.5f) //
|
|
|
- );
|
|
|
- stateData.setMix("events1", "events2", 0.7f);
|
|
|
- state.setAnimation(0, "events1", false).setEventThreshold(0.5f);
|
|
|
- state.addAnimation(0, "events2", false, 0.4f);
|
|
|
- run(0.1f, 1000, null);
|
|
|
-
|
|
|
- setup("event threshold, all animation 0 events fire during mix", // 10
|
|
|
- expect(0, "start", 0, 0), //
|
|
|
- expect(0, "event 0", 0, 0), //
|
|
|
- expect(0, "event 14", 0.5f, 0.5f), //
|
|
|
- expect(0, "interrupt", 0.9f, 0.9f), //
|
|
|
-
|
|
|
- expect(1, "start", 0.1f, 0.9f), //
|
|
|
- expect(1, "event 0", 0.1f, 0.9f), //
|
|
|
-
|
|
|
- expect(0, "event 30", 1, 1), //
|
|
|
- expect(0, "complete", 1, 1), //
|
|
|
- expect(0, "event 0", 1, 1), //
|
|
|
-
|
|
|
- expect(1, "event 14", 0.5f, 1.3f), //
|
|
|
-
|
|
|
- expect(0, "end", 1.5f, 1.6f), //
|
|
|
- expect(0, "dispose", 1.5f, 1.6f), //
|
|
|
-
|
|
|
- expect(1, "event 30", 1, 1.8f), //
|
|
|
- expect(1, "complete", 1, 1.8f), //
|
|
|
- expect(1, "end", 1, 1.9f), //
|
|
|
- expect(1, "dispose", 1, 1.9f) //
|
|
|
- );
|
|
|
- state.setAnimation(0, "events1", true).setEventThreshold(1);
|
|
|
- state.addAnimation(0, "events2", false, 0.8f).setMixDuration(0.7f);
|
|
|
- run(0.1f, 1000, null);
|
|
|
-
|
|
|
- setup("looping", // 11
|
|
|
- expect(0, "start", 0, 0), //
|
|
|
- expect(0, "event 0", 0, 0), //
|
|
|
- expect(0, "event 14", 0.5f, 0.5f), //
|
|
|
- expect(0, "event 30", 1, 1), //
|
|
|
- expect(0, "complete", 1, 1), //
|
|
|
- expect(0, "event 0", 1, 1), //
|
|
|
- expect(0, "event 14", 1.5f, 1.5f), //
|
|
|
- expect(0, "event 30", 2, 2), //
|
|
|
- expect(0, "complete", 2, 2), //
|
|
|
- expect(0, "event 0", 2, 2), //
|
|
|
- expect(0, "event 14", 2.5f, 2.5f), //
|
|
|
- expect(0, "event 30", 3, 3), //
|
|
|
- expect(0, "complete", 3, 3), //
|
|
|
- expect(0, "event 0", 3, 3), //
|
|
|
- expect(0, "event 14", 3.5f, 3.5f), //
|
|
|
- expect(0, "event 30", 4, 4), //
|
|
|
- expect(0, "complete", 4, 4), //
|
|
|
- expect(0, "event 0", 4, 4) //
|
|
|
- );
|
|
|
- state.setAnimation(0, "events1", true);
|
|
|
- run(0.1f, 4, null);
|
|
|
-
|
|
|
- setup("not looping, track end past animation 0 duration", // 12
|
|
|
- expect(0, "start", 0, 0), //
|
|
|
- expect(0, "event 0", 0, 0), //
|
|
|
- expect(0, "event 14", 0.5f, 0.5f), //
|
|
|
- expect(0, "event 30", 1, 1), //
|
|
|
- expect(0, "complete", 1, 1), //
|
|
|
- expect(0, "interrupt", 2.1f, 2.1f), //
|
|
|
-
|
|
|
- expect(1, "start", 0.1f, 2.1f), //
|
|
|
- expect(1, "event 0", 0.1f, 2.1f), //
|
|
|
-
|
|
|
- expect(0, "end", 2.1f, 2.2f), //
|
|
|
- expect(0, "dispose", 2.1f, 2.2f), //
|
|
|
-
|
|
|
- expect(1, "event 14", 0.5f, 2.5f), //
|
|
|
- expect(1, "event 30", 1, 3), //
|
|
|
- expect(1, "complete", 1, 3), //
|
|
|
- expect(1, "end", 1, 3.1f), //
|
|
|
- expect(1, "dispose", 1, 3.1f) //
|
|
|
- );
|
|
|
- state.setAnimation(0, "events1", false);
|
|
|
- state.addAnimation(0, "events2", false, 2);
|
|
|
- run(0.1f, 4f, null);
|
|
|
-
|
|
|
- setup("interrupt animation after first loop complete", // 13
|
|
|
- expect(0, "start", 0, 0), //
|
|
|
- expect(0, "event 0", 0, 0), //
|
|
|
- expect(0, "event 14", 0.5f, 0.5f), //
|
|
|
- expect(0, "event 30", 1, 1), //
|
|
|
- expect(0, "complete", 1, 1), //
|
|
|
- expect(0, "event 0", 1, 1), //
|
|
|
- expect(0, "event 14", 1.5f, 1.5f), //
|
|
|
- expect(0, "event 30", 2, 2), //
|
|
|
- expect(0, "complete", 2, 2), //
|
|
|
- expect(0, "event 0", 2, 2), //
|
|
|
- expect(0, "interrupt", 2.1f, 2.1f), //
|
|
|
-
|
|
|
- expect(1, "start", 0.1f, 2.1f), //
|
|
|
- expect(1, "event 0", 0.1f, 2.1f), //
|
|
|
-
|
|
|
- expect(0, "end", 2.1f, 2.2f), //
|
|
|
- expect(0, "dispose", 2.1f, 2.2f), //
|
|
|
-
|
|
|
- expect(1, "event 14", 0.5f, 2.5f), //
|
|
|
- expect(1, "event 30", 1, 3), //
|
|
|
- expect(1, "complete", 1, 3), //
|
|
|
- expect(1, "end", 1, 3.1f), //
|
|
|
- expect(1, "dispose", 1, 3.1f) //
|
|
|
- );
|
|
|
- state.setAnimation(0, "events1", true);
|
|
|
- run(0.1f, 6, new TestListener() {
|
|
|
- public void frame (float time) {
|
|
|
- if (MathUtils.isEqual(time, 1.4f)) state.addAnimation(0, "events2", false, 0);
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- setup("add animation on empty track", // 14
|
|
|
- expect(0, "start", 0, 0), //
|
|
|
- expect(0, "event 0", 0, 0), //
|
|
|
- expect(0, "event 14", 0.5f, 0.5f), //
|
|
|
- expect(0, "event 30", 1, 1), //
|
|
|
- expect(0, "complete", 1, 1), //
|
|
|
- expect(0, "end", 1, 1.1f), //
|
|
|
- expect(0, "dispose", 1, 1.1f) //
|
|
|
- );
|
|
|
- state.addAnimation(0, "events1", false, 0);
|
|
|
- run(0.1f, 1.9f, null);
|
|
|
-
|
|
|
- setup("end time beyond non-looping animation duration", // 15
|
|
|
- expect(0, "start", 0, 0), //
|
|
|
- expect(0, "event 0", 0, 0), //
|
|
|
- expect(0, "event 14", 0.5f, 0.5f), //
|
|
|
- expect(0, "event 30", 1, 1), //
|
|
|
- expect(0, "complete", 1, 1), //
|
|
|
- expect(0, "end", 9f, 9.1f), //
|
|
|
- expect(0, "dispose", 9f, 9.1f) //
|
|
|
- );
|
|
|
- state.setAnimation(0, "events1", false).setTrackEnd(9);
|
|
|
- run(0.1f, 10, null);
|
|
|
-
|
|
|
- setup("looping with animation start", // 16
|
|
|
- expect(0, "start", 0, 0), //
|
|
|
- expect(0, "event 30", 0.4f, 0.4f), //
|
|
|
- expect(0, "complete", 0.4f, 0.4f), //
|
|
|
- expect(0, "event 30", 0.8f, 0.8f), //
|
|
|
- expect(0, "complete", 0.8f, 0.8f), //
|
|
|
- expect(0, "event 30", 1.2f, 1.2f), //
|
|
|
- expect(0, "complete", 1.2f, 1.2f) //
|
|
|
- );
|
|
|
- entry = state.setAnimation(0, "events1", true);
|
|
|
- entry.setAnimationLast(0.6f);
|
|
|
- entry.setAnimationStart(0.6f);
|
|
|
- run(0.1f, 1.4f, null);
|
|
|
-
|
|
|
- setup("looping with animation start and end", // 17
|
|
|
- expect(0, "start", 0, 0), //
|
|
|
- expect(0, "event 14", 0.3f, 0.3f), //
|
|
|
- expect(0, "complete", 0.6f, 0.6f), //
|
|
|
- expect(0, "event 14", 0.9f, 0.9f), //
|
|
|
- expect(0, "complete", 1.2f, 1.2f), //
|
|
|
- expect(0, "event 14", 1.5f, 1.5f) //
|
|
|
- );
|
|
|
- entry = state.setAnimation(0, "events1", true);
|
|
|
- entry.setAnimationStart(0.2f);
|
|
|
- entry.setAnimationLast(0.2f);
|
|
|
- entry.setAnimationEnd(0.8f);
|
|
|
- run(0.1f, 1.8f, null);
|
|
|
-
|
|
|
- setup("non-looping with animation start and end", // 18
|
|
|
- expect(0, "start", 0, 0), //
|
|
|
- expect(0, "event 14", 0.3f, 0.3f), //
|
|
|
- expect(0, "complete", 0.6f, 0.6f), //
|
|
|
- expect(0, "end", 1, 1.1f), //
|
|
|
- expect(0, "dispose", 1, 1.1f) //
|
|
|
- );
|
|
|
- entry = state.setAnimation(0, "events1", false);
|
|
|
- entry.setAnimationStart(0.2f);
|
|
|
- entry.setAnimationLast(0.2f);
|
|
|
- entry.setAnimationEnd(0.8f);
|
|
|
- run(0.1f, 1.8f, null);
|
|
|
-
|
|
|
- setup("mix out looping with animation start and end", // 19
|
|
|
- expect(0, "start", 0, 0), //
|
|
|
- expect(0, "event 14", 0.3f, 0.3f), //
|
|
|
- expect(0, "complete", 0.6f, 0.6f), //
|
|
|
- expect(0, "interrupt", 0.8f, 0.8f), //
|
|
|
-
|
|
|
- expect(1, "start", 0.1f, 0.8f), //
|
|
|
- expect(1, "event 0", 0.1f, 0.8f), //
|
|
|
-
|
|
|
- expect(0, "event 14", 0.9f, 0.9f), //
|
|
|
- expect(0, "complete", 1.2f, 1.2f), //
|
|
|
-
|
|
|
- expect(1, "event 14", 0.5f, 1.2f), //
|
|
|
-
|
|
|
- expect(0, "end", 1.4f, 1.5f), //
|
|
|
- expect(0, "dispose", 1.4f, 1.5f), //
|
|
|
-
|
|
|
- expect(1, "event 30", 1, 1.7f), //
|
|
|
- expect(1, "complete", 1, 1.7f), //
|
|
|
- expect(1, "end", 1, 1.8f), //
|
|
|
- expect(1, "dispose", 1, 1.8f) //
|
|
|
- );
|
|
|
- entry = state.setAnimation(0, "events1", true);
|
|
|
- entry.setAnimationStart(0.2f);
|
|
|
- entry.setAnimationLast(0.2f);
|
|
|
- entry.setAnimationEnd(0.8f);
|
|
|
- entry.setEventThreshold(1);
|
|
|
- state.addAnimation(0, "events2", false, 0.7f).setMixDuration(0.7f);
|
|
|
- run(0.1f, 20, null);
|
|
|
-
|
|
|
- setup("setAnimation with track entry mix", // 20
|
|
|
- expect(0, "start", 0, 0), //
|
|
|
- expect(0, "event 0", 0, 0), //
|
|
|
- expect(0, "event 14", 0.5f, 0.5f), //
|
|
|
- expect(0, "event 30", 1, 1), //
|
|
|
- expect(0, "complete", 1, 1), //
|
|
|
- expect(0, "event 0", 1, 1), //
|
|
|
- expect(0, "interrupt", 1, 1), //
|
|
|
-
|
|
|
- expect(1, "start", 0, 1), //
|
|
|
-
|
|
|
- expect(1, "event 0", 0.1f, 1.1f), //
|
|
|
- expect(1, "event 14", 0.5f, 1.5f), //
|
|
|
-
|
|
|
- expect(0, "end", 1.7f, 1.8f), //
|
|
|
- expect(0, "dispose", 1.7f, 1.8f), //
|
|
|
-
|
|
|
- expect(1, "event 30", 1, 2), //
|
|
|
- expect(1, "complete", 1, 2), //
|
|
|
- expect(1, "end", 1, 2.1f), //
|
|
|
- expect(1, "dispose", 1, 2.1f) //
|
|
|
- );
|
|
|
- state.setAnimation(0, "events1", true);
|
|
|
- run(0.1f, 1000, new TestListener() {
|
|
|
- public void frame (float time) {
|
|
|
- if (MathUtils.isEqual(time, 1f)) state.setAnimation(0, "events2", false).setMixDuration(0.7f);
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- setup("setAnimation twice", // 21
|
|
|
- expect(0, "start", 0, 0), //
|
|
|
- expect(0, "interrupt", 0, 0), //
|
|
|
- expect(0, "end", 0, 0), //
|
|
|
- expect(0, "dispose", 0, 0), //
|
|
|
-
|
|
|
- expect(1, "start", 0, 0), //
|
|
|
- expect(1, "event 0", 0, 0), //
|
|
|
- expect(1, "event 14", 0.5f, 0.5f), //
|
|
|
-
|
|
|
- // First 2 setAnimation calls are done.
|
|
|
-
|
|
|
- expect(1, "interrupt", 0.8f, 0.8f), //
|
|
|
-
|
|
|
- expect(0, "start", 0, 0.8f), //
|
|
|
- expect(0, "interrupt", 0, 0.8f), //
|
|
|
- expect(0, "end", 0, 0.8f), //
|
|
|
- expect(0, "dispose", 0, 0.8f), //
|
|
|
-
|
|
|
- expect(1, "start", 0, 0.8f), //
|
|
|
- expect(1, "event 0", 0.1f, 0.9f), //
|
|
|
- expect(1, "event 14", 0.5f, 1.3f), //
|
|
|
- expect(1, "event 30", 1, 1.8f), //
|
|
|
- expect(1, "complete", 1, 1.8f), //
|
|
|
- expect(1, "end", 1, 1.9f), //
|
|
|
- expect(1, "dispose", 1, 1.9f) //
|
|
|
- );
|
|
|
- state.setAnimation(0, "events1", false); // First should be ignored.
|
|
|
- state.setAnimation(0, "events2", false);
|
|
|
- run(0.1f, 1000, new TestListener() {
|
|
|
- public void frame (float time) {
|
|
|
- if (MathUtils.isEqual(time, 0.8f)) {
|
|
|
- state.setAnimation(0, "events1", false); // First should be ignored.
|
|
|
- state.setAnimation(0, "events2", false);
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- setup("addAnimation with delay on empty track", // 22
|
|
|
- expect(0, "start", 0, 0), //
|
|
|
- expect(0, "event 0", 0, 5), //
|
|
|
- expect(0, "event 14", 0.5f, 5.5f), //
|
|
|
- expect(0, "event 30", 1, 6), //
|
|
|
- expect(0, "complete", 1, 6), //
|
|
|
- expect(0, "end", 1, 6.1f), //
|
|
|
- expect(0, "dispose", 1, 6.1f) //
|
|
|
- );
|
|
|
- state.addAnimation(0, "events1", false, 5);
|
|
|
- run(0.1f, 10, null);
|
|
|
-
|
|
|
- setup("setAnimation during AnimationStateListener"); // 23
|
|
|
- state.addListener(new AnimationStateListener() {
|
|
|
- public void start (TrackEntry entry) {
|
|
|
- if (entry.getAnimation().getName().equals("events1")) state.setAnimation(1, "events2", false);
|
|
|
- }
|
|
|
-
|
|
|
- public void interrupt (TrackEntry entry) {
|
|
|
- state.addAnimation(3, "events2", false, 0);
|
|
|
- }
|
|
|
-
|
|
|
- public void end (TrackEntry entry) {
|
|
|
- if (entry.getAnimation().getName().equals("events1")) state.setAnimation(0, "events2", false);
|
|
|
- }
|
|
|
-
|
|
|
- public void dispose (TrackEntry entry) {
|
|
|
- if (entry.getAnimation().getName().equals("events1")) state.setAnimation(1, "events2", false);
|
|
|
- }
|
|
|
-
|
|
|
- public void complete (TrackEntry entry) {
|
|
|
- if (entry.getAnimation().getName().equals("events1")) state.setAnimation(1, "events2", false);
|
|
|
- }
|
|
|
-
|
|
|
- public void event (TrackEntry entry, Event event) {
|
|
|
- if (entry.getTrackIndex() != 2) state.setAnimation(2, "events2", false);
|
|
|
- }
|
|
|
- });
|
|
|
- state.addAnimation(0, "events1", false, 0);
|
|
|
- state.addAnimation(0, "events2", false, 0);
|
|
|
- state.setAnimation(1, "events2", false);
|
|
|
- run(0.1f, 10, null);
|
|
|
-
|
|
|
- setup("clearTrack", // 24
|
|
|
- expect(0, "start", 0, 0), //
|
|
|
- expect(0, "event 0", 0, 0), //
|
|
|
- expect(0, "event 14", 0.5f, 0.5f), //
|
|
|
- expect(0, "end", 0.7f, 0.7f), //
|
|
|
- expect(0, "dispose", 0.7f, 0.7f) //
|
|
|
- );
|
|
|
- state.addAnimation(0, "events1", false, 0);
|
|
|
- run(0.1f, 10, new TestListener() {
|
|
|
- public void frame (float time) {
|
|
|
- if (MathUtils.isEqual(time, 0.7f)) state.clearTrack(0);
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- setup("setEmptyAnimation", // 25
|
|
|
- expect(0, "start", 0, 0), //
|
|
|
- expect(0, "event 0", 0, 0), //
|
|
|
- expect(0, "event 14", 0.5f, 0.5f), //
|
|
|
- expect(0, "interrupt", 0.7f, 0.7f), //
|
|
|
-
|
|
|
- expect(-1, "start", 0, 0.7f), //
|
|
|
- expect(-1, "complete", 0.1f, 0.8f), //
|
|
|
-
|
|
|
- expect(0, "end", 0.8f, 0.9f), //
|
|
|
- expect(0, "dispose", 0.8f, 0.9f), //
|
|
|
-
|
|
|
- expect(-1, "end", 0.1f, 0.9f), //
|
|
|
- expect(-1, "dispose", 0.1f, 0.9f) //
|
|
|
- );
|
|
|
- state.addAnimation(0, "events1", false, 0);
|
|
|
- run(0.1f, 10, new TestListener() {
|
|
|
- public void frame (float time) {
|
|
|
- if (MathUtils.isEqual(time, 0.7f)) state.setEmptyAnimation(0, 0);
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- System.out.println("AnimationState tests passed.");
|
|
|
- }
|
|
|
-
|
|
|
- void setup (String description, Result... expectedArray) {
|
|
|
- test++;
|
|
|
- expected.addAll(expectedArray);
|
|
|
- stateData = new AnimationStateData(skeletonData);
|
|
|
- state = new AnimationState(stateData);
|
|
|
- time = 0;
|
|
|
- fail = false;
|
|
|
- log(test + ": " + description);
|
|
|
- if (expectedArray.length > 0) {
|
|
|
- state.addListener(stateListener);
|
|
|
- log(String.format("%-3s%-12s%-7s%-7s%-7s", "#", "EVENT", "TRACK", "TOTAL", "RESULT"));
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- void run (float incr, float endTime, TestListener listener) {
|
|
|
- Skeleton skeleton = new Skeleton(skeletonData);
|
|
|
- state.apply(skeleton);
|
|
|
- while (time < endTime) {
|
|
|
- time += incr;
|
|
|
- skeleton.update(incr);
|
|
|
- state.update(incr);
|
|
|
-
|
|
|
- // Reduce float discrepancies for tests.
|
|
|
- for (TrackEntry entry : state.getTracks()) {
|
|
|
- if (entry == null) continue;
|
|
|
- entry.trackTime = round(entry.trackTime, 6);
|
|
|
- entry.delay = round(entry.delay, 3);
|
|
|
- if (entry.mixingFrom != null) entry.mixingFrom.trackTime = round(entry.mixingFrom.trackTime, 6);
|
|
|
- }
|
|
|
-
|
|
|
- state.apply(skeleton);
|
|
|
-
|
|
|
- // Apply multiple times to ensure no side effects.
|
|
|
- if (expected.size > 0) state.removeListener(stateListener);
|
|
|
- state.apply(skeleton);
|
|
|
- state.apply(skeleton);
|
|
|
- if (expected.size > 0) state.addListener(stateListener);
|
|
|
-
|
|
|
- if (listener != null) listener.frame(time);
|
|
|
- }
|
|
|
- // Expecting more than actual is a failure.
|
|
|
- for (int i = actual.size, n = expected.size; i < n; i++) {
|
|
|
- log(String.format("%-29s", "<none>") + "FAIL: " + expected.get(i));
|
|
|
- fail = true;
|
|
|
- }
|
|
|
- actual.clear();
|
|
|
- expected.clear();
|
|
|
- log("");
|
|
|
- if (fail) {
|
|
|
- log("TEST " + test + " FAILED!");
|
|
|
- System.exit(0);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- Result expect (int animationIndex, String name, float trackTime, float totalTime) {
|
|
|
- Result result = new Result();
|
|
|
- result.name = name;
|
|
|
- result.animationIndex = animationIndex;
|
|
|
- result.trackTime = trackTime;
|
|
|
- result.totalTime = totalTime;
|
|
|
- return result;
|
|
|
- }
|
|
|
-
|
|
|
- Result actual (String name, TrackEntry entry) {
|
|
|
- Result result = new Result();
|
|
|
- result.name = name;
|
|
|
- result.animationIndex = skeletonData.getAnimations().indexOf(entry.animation, true);
|
|
|
- result.trackTime = Math.round(entry.trackTime * 1000) / 1000f;
|
|
|
- result.totalTime = Math.round(time * 1000) / 1000f;
|
|
|
- return result;
|
|
|
- }
|
|
|
-
|
|
|
- void log (String message) {
|
|
|
- System.out.println(message);
|
|
|
- }
|
|
|
-
|
|
|
- class Result {
|
|
|
- String name;
|
|
|
- int animationIndex;
|
|
|
- float trackTime, totalTime;
|
|
|
-
|
|
|
- public int hashCode () {
|
|
|
- int result = 31 + animationIndex;
|
|
|
- result = 31 * result + name.hashCode();
|
|
|
- result = 31 * result + Float.floatToIntBits(totalTime);
|
|
|
- result = 31 * result + Float.floatToIntBits(trackTime);
|
|
|
- return result;
|
|
|
- }
|
|
|
-
|
|
|
- public boolean equals (Object obj) {
|
|
|
- Result other = (Result)obj;
|
|
|
- if (animationIndex != other.animationIndex) return false;
|
|
|
- if (!name.equals(other.name)) return false;
|
|
|
- if (!MathUtils.isEqual(totalTime, other.totalTime)) return false;
|
|
|
- if (!MathUtils.isEqual(trackTime, other.trackTime)) return false;
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- public String toString () {
|
|
|
- return String.format("%-3s%-12s%-7s%-7s", "" + animationIndex, name, roundTime(trackTime), roundTime(totalTime));
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- static float round (float value, int decimals) {
|
|
|
- float shift = (float)Math.pow(10, decimals);
|
|
|
- return Math.round(value * shift) / shift;
|
|
|
- }
|
|
|
-
|
|
|
- static String roundTime (float value) {
|
|
|
- String text = Float.toString(round(value, 3));
|
|
|
- return text.endsWith(".0") ? text.substring(0, text.length() - 2) : text;
|
|
|
- }
|
|
|
-
|
|
|
- static interface TestListener {
|
|
|
- void frame (float time);
|
|
|
- }
|
|
|
-
|
|
|
- static public void main (String[] args) throws Exception {
|
|
|
- new AnimationStateTests();
|
|
|
- }
|
|
|
+package com.esotericsoftware.spine;
|
|
|
+
|
|
|
+import com.badlogic.gdx.Files.FileType;
|
|
|
+import com.badlogic.gdx.backends.lwjgl.LwjglFileHandle;
|
|
|
+import com.badlogic.gdx.math.MathUtils;
|
|
|
+import com.badlogic.gdx.utils.Array;
|
|
|
+import com.esotericsoftware.spine.AnimationState.AnimationStateListener;
|
|
|
+import com.esotericsoftware.spine.AnimationState.TrackEntry;
|
|
|
+import com.esotericsoftware.spine.attachments.AttachmentLoader;
|
|
|
+import com.esotericsoftware.spine.attachments.BoundingBoxAttachment;
|
|
|
+import com.esotericsoftware.spine.attachments.MeshAttachment;
|
|
|
+import com.esotericsoftware.spine.attachments.PathAttachment;
|
|
|
+import com.esotericsoftware.spine.attachments.RegionAttachment;
|
|
|
+
|
|
|
+public class AnimationStateTests {
|
|
|
+ final SkeletonJson json = new SkeletonJson(new AttachmentLoader() {
|
|
|
+ public RegionAttachment newRegionAttachment (Skin skin, String name, String path) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ public MeshAttachment newMeshAttachment (Skin skin, String name, String path) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ public BoundingBoxAttachment newBoundingBoxAttachment (Skin skin, String name) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ public PathAttachment newPathAttachment (Skin skin, String name) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ final AnimationStateListener stateListener = new AnimationStateListener() {
|
|
|
+ public void start (TrackEntry entry) {
|
|
|
+ add(actual("start", entry));
|
|
|
+ }
|
|
|
+
|
|
|
+ public void interrupt (TrackEntry entry) {
|
|
|
+ add(actual("interrupt", entry));
|
|
|
+ }
|
|
|
+
|
|
|
+ public void end (TrackEntry entry) {
|
|
|
+ add(actual("end", entry));
|
|
|
+ }
|
|
|
+
|
|
|
+ public void dispose (TrackEntry entry) {
|
|
|
+ add(actual("dispose", entry));
|
|
|
+ }
|
|
|
+
|
|
|
+ public void complete (TrackEntry entry) {
|
|
|
+ add(actual("complete", entry));
|
|
|
+ }
|
|
|
+
|
|
|
+ public void event (TrackEntry entry, Event event) {
|
|
|
+ add(actual("event " + event.getString(), entry));
|
|
|
+ }
|
|
|
+
|
|
|
+ private void add (Result result) {
|
|
|
+ String message = result.toString();
|
|
|
+ if (actual.size >= expected.size) {
|
|
|
+ message += "FAIL: <none>";
|
|
|
+ fail = true;
|
|
|
+ } else if (!expected.get(actual.size).equals(result)) {
|
|
|
+ message += "FAIL: " + expected.get(actual.size);
|
|
|
+ fail = true;
|
|
|
+ } else
|
|
|
+ message += "PASS";
|
|
|
+ log(message);
|
|
|
+ actual.add(result);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ final SkeletonData skeletonData;
|
|
|
+ final Array<Result> actual = new Array();
|
|
|
+ final Array<Result> expected = new Array();
|
|
|
+
|
|
|
+ AnimationStateData stateData;
|
|
|
+ AnimationState state;
|
|
|
+ float time = 0;
|
|
|
+ boolean fail;
|
|
|
+ int test;
|
|
|
+
|
|
|
+ AnimationStateTests () {
|
|
|
+ skeletonData = json.readSkeletonData(new LwjglFileHandle("test/test.json", FileType.Internal));
|
|
|
+
|
|
|
+ TrackEntry entry;
|
|
|
+
|
|
|
+ setup("0.1 time step", // 1
|
|
|
+ expect(0, "start", 0, 0), //
|
|
|
+ expect(0, "event 0", 0, 0), //
|
|
|
+ expect(0, "event 14", 0.5f, 0.5f), //
|
|
|
+ expect(0, "event 30", 1, 1), //
|
|
|
+ expect(0, "complete", 1, 1), //
|
|
|
+ expect(0, "end", 1, 1.1f), //
|
|
|
+ expect(0, "dispose", 1, 1.1f) //
|
|
|
+ );
|
|
|
+ state.setAnimation(0, "events1", false);
|
|
|
+ run(0.1f, 1000, null);
|
|
|
+
|
|
|
+ setup("1/60 time step, dispose queued", // 2
|
|
|
+ expect(0, "start", 0, 0), //
|
|
|
+ expect(0, "interrupt", 0, 0), //
|
|
|
+ expect(0, "end", 0, 0), //
|
|
|
+ expect(0, "dispose", 0, 0), //
|
|
|
+ expect(1, "dispose", 0, 0), //
|
|
|
+ expect(0, "dispose", 0, 0), //
|
|
|
+ expect(1, "dispose", 0, 0), //
|
|
|
+
|
|
|
+ // First 2 set/addAnimation calls are done.
|
|
|
+
|
|
|
+ expect(0, "start", 0, 0), //
|
|
|
+ expect(0, "event 0", 0, 0), //
|
|
|
+ expect(0, "event 14", 0.467f, 0.467f), //
|
|
|
+ expect(0, "event 30", 1, 1), //
|
|
|
+ expect(0, "complete", 1, 1), //
|
|
|
+ expect(0, "end", 1, 1.017f), //
|
|
|
+ expect(0, "dispose", 1, 1.017f) //
|
|
|
+ );
|
|
|
+ state.setAnimation(0, "events1", false);
|
|
|
+ state.addAnimation(0, "events2", false, 0);
|
|
|
+ state.addAnimation(0, "events1", false, 0);
|
|
|
+ state.addAnimation(0, "events2", false, 0);
|
|
|
+ state.setAnimation(0, "events1", false);
|
|
|
+ run(1 / 60f, 1000, null);
|
|
|
+
|
|
|
+ setup("30 time step", // 3
|
|
|
+ expect(0, "start", 0, 0), //
|
|
|
+ expect(0, "event 0", 0, 0), //
|
|
|
+ expect(0, "event 14", 30, 30), //
|
|
|
+ expect(0, "event 30", 30, 30), //
|
|
|
+ expect(0, "complete", 30, 30), //
|
|
|
+ expect(0, "end", 30, 60), //
|
|
|
+ expect(0, "dispose", 30, 60) //
|
|
|
+ );
|
|
|
+ state.setAnimation(0, "events1", false);
|
|
|
+ run(30, 1000, null);
|
|
|
+
|
|
|
+ setup("1 time step", // 4
|
|
|
+ expect(0, "start", 0, 0), //
|
|
|
+ expect(0, "event 0", 0, 0), //
|
|
|
+ expect(0, "event 14", 1, 1), //
|
|
|
+ expect(0, "event 30", 1, 1), //
|
|
|
+ expect(0, "complete", 1, 1), //
|
|
|
+ expect(0, "end", 1, 2), //
|
|
|
+ expect(0, "dispose", 1, 2) //
|
|
|
+ );
|
|
|
+ state.setAnimation(0, "events1", false);
|
|
|
+ run(1, 1.01f, null);
|
|
|
+
|
|
|
+ setup("interrupt", // 5
|
|
|
+ expect(0, "start", 0, 0), //
|
|
|
+ expect(0, "event 0", 0, 0), //
|
|
|
+ expect(0, "event 14", 0.5f, 0.5f), //
|
|
|
+ expect(0, "event 30", 1, 1), //
|
|
|
+ expect(0, "complete", 1, 1), //
|
|
|
+ expect(0, "interrupt", 1.1f, 1.1f), //
|
|
|
+
|
|
|
+ expect(1, "start", 0.1f, 1.1f), //
|
|
|
+ expect(1, "event 0", 0.1f, 1.1f), //
|
|
|
+
|
|
|
+ expect(0, "end", 1.1f, 1.2f), //
|
|
|
+ expect(0, "dispose", 1.1f, 1.2f), //
|
|
|
+
|
|
|
+ expect(1, "event 14", 0.5f, 1.5f), //
|
|
|
+ expect(1, "event 30", 1, 2), //
|
|
|
+ expect(1, "complete", 1, 2), //
|
|
|
+ expect(1, "interrupt", 1.1f, 2.1f), //
|
|
|
+
|
|
|
+ expect(0, "start", 0.1f, 2.1f), //
|
|
|
+ expect(0, "event 0", 0.1f, 2.1f), //
|
|
|
+
|
|
|
+ expect(1, "end", 1.1f, 2.2f), //
|
|
|
+ expect(1, "dispose", 1.1f, 2.2f), //
|
|
|
+
|
|
|
+ expect(0, "event 14", 0.5f, 2.5f), //
|
|
|
+ expect(0, "event 30", 1, 3), //
|
|
|
+ expect(0, "complete", 1, 3), //
|
|
|
+ expect(0, "end", 1, 3.1f), //
|
|
|
+ expect(0, "dispose", 1, 3.1f) //
|
|
|
+ );
|
|
|
+ state.setAnimation(0, "events1", false);
|
|
|
+ state.addAnimation(0, "events2", false, 0);
|
|
|
+ state.addAnimation(0, "events1", false, 0);
|
|
|
+ run(0.1f, 4f, null);
|
|
|
+
|
|
|
+ setup("interrupt with delay", // 6
|
|
|
+ expect(0, "start", 0, 0), //
|
|
|
+ expect(0, "event 0", 0, 0), //
|
|
|
+ expect(0, "event 14", 0.5f, 0.5f), //
|
|
|
+ expect(0, "interrupt", 0.6f, 0.6f), //
|
|
|
+
|
|
|
+ expect(1, "start", 0.1f, 0.6f), //
|
|
|
+ expect(1, "event 0", 0.1f, 0.6f), //
|
|
|
+
|
|
|
+ expect(0, "end", 0.6f, 0.7f), //
|
|
|
+ expect(0, "dispose", 0.6f, 0.7f), //
|
|
|
+
|
|
|
+ expect(1, "event 14", 0.5f, 1.0f), //
|
|
|
+ expect(1, "event 30", 1, 1.5f), //
|
|
|
+ expect(1, "complete", 1, 1.5f), //
|
|
|
+ expect(1, "end", 1, 1.6f), //
|
|
|
+ expect(1, "dispose", 1, 1.6f) //
|
|
|
+ );
|
|
|
+ state.setAnimation(0, "events1", false);
|
|
|
+ state.addAnimation(0, "events2", false, 0.5f);
|
|
|
+ run(0.1f, 1000, null);
|
|
|
+
|
|
|
+ setup("interrupt with delay and mix time", // 7
|
|
|
+ expect(0, "start", 0, 0), //
|
|
|
+ expect(0, "event 0", 0, 0), //
|
|
|
+ expect(0, "event 14", 0.5f, 0.5f), //
|
|
|
+ expect(0, "interrupt", 1, 1), //
|
|
|
+
|
|
|
+ expect(1, "start", 0.1f, 1), //
|
|
|
+
|
|
|
+ expect(0, "complete", 1, 1), //
|
|
|
+
|
|
|
+ expect(1, "event 0", 0.1f, 1), //
|
|
|
+ expect(1, "event 14", 0.5f, 1.4f), //
|
|
|
+
|
|
|
+ expect(0, "end", 1.6f, 1.7f), //
|
|
|
+ expect(0, "dispose", 1.6f, 1.7f), //
|
|
|
+
|
|
|
+ expect(1, "event 30", 1, 1.9f), //
|
|
|
+ expect(1, "complete", 1, 1.9f), //
|
|
|
+ expect(1, "end", 1, 2), //
|
|
|
+ expect(1, "dispose", 1, 2) //
|
|
|
+ );
|
|
|
+ stateData.setMix("events1", "events2", 0.7f);
|
|
|
+ state.setAnimation(0, "events1", true);
|
|
|
+ state.addAnimation(0, "events2", false, 0.9f);
|
|
|
+ run(0.1f, 1000, null);
|
|
|
+
|
|
|
+ setup("animation 0 events do not fire during mix", // 8
|
|
|
+ expect(0, "start", 0, 0), //
|
|
|
+ expect(0, "event 0", 0, 0), //
|
|
|
+ expect(0, "interrupt", 0.5f, 0.5f), //
|
|
|
+
|
|
|
+ expect(1, "start", 0.1f, 0.5f), //
|
|
|
+ expect(1, "event 0", 0.1f, 0.5f), //
|
|
|
+ expect(1, "event 14", 0.5f, 0.9f), //
|
|
|
+
|
|
|
+ expect(0, "complete", 1, 1), //
|
|
|
+ expect(0, "end", 1.1f, 1.2f), //
|
|
|
+ expect(0, "dispose", 1.1f, 1.2f), //
|
|
|
+
|
|
|
+ expect(1, "event 30", 1, 1.4f), //
|
|
|
+ expect(1, "complete", 1, 1.4f), //
|
|
|
+ expect(1, "end", 1, 1.5f), //
|
|
|
+ expect(1, "dispose", 1, 1.5f) //
|
|
|
+ );
|
|
|
+ stateData.setDefaultMix(0.7f);
|
|
|
+ state.setAnimation(0, "events1", false);
|
|
|
+ state.addAnimation(0, "events2", false, 0.4f);
|
|
|
+ run(0.1f, 1000, null);
|
|
|
+
|
|
|
+ setup("event threshold, some animation 0 events fire during mix", // 9
|
|
|
+ expect(0, "start", 0, 0), //
|
|
|
+ expect(0, "event 0", 0, 0), //
|
|
|
+ expect(0, "interrupt", 0.5f, 0.5f), //
|
|
|
+
|
|
|
+ expect(1, "start", 0.1f, 0.5f), //
|
|
|
+
|
|
|
+ expect(0, "event 14", 0.5f, 0.5f), //
|
|
|
+
|
|
|
+ expect(1, "event 0", 0.1f, 0.5f), //
|
|
|
+ expect(1, "event 14", 0.5f, 0.9f), //
|
|
|
+
|
|
|
+ expect(0, "complete", 1, 1), //
|
|
|
+ expect(0, "end", 1.1f, 1.2f), //
|
|
|
+ expect(0, "dispose", 1.1f, 1.2f), //
|
|
|
+
|
|
|
+ expect(1, "event 30", 1, 1.4f), //
|
|
|
+ expect(1, "complete", 1, 1.4f), //
|
|
|
+ expect(1, "end", 1, 1.5f), //
|
|
|
+ expect(1, "dispose", 1, 1.5f) //
|
|
|
+ );
|
|
|
+ stateData.setMix("events1", "events2", 0.7f);
|
|
|
+ state.setAnimation(0, "events1", false).setEventThreshold(0.5f);
|
|
|
+ state.addAnimation(0, "events2", false, 0.4f);
|
|
|
+ run(0.1f, 1000, null);
|
|
|
+
|
|
|
+ setup("event threshold, all animation 0 events fire during mix", // 10
|
|
|
+ expect(0, "start", 0, 0), //
|
|
|
+ expect(0, "event 0", 0, 0), //
|
|
|
+ expect(0, "event 14", 0.5f, 0.5f), //
|
|
|
+ expect(0, "interrupt", 0.9f, 0.9f), //
|
|
|
+
|
|
|
+ expect(1, "start", 0.1f, 0.9f), //
|
|
|
+ expect(1, "event 0", 0.1f, 0.9f), //
|
|
|
+
|
|
|
+ expect(0, "event 30", 1, 1), //
|
|
|
+ expect(0, "complete", 1, 1), //
|
|
|
+ expect(0, "event 0", 1, 1), //
|
|
|
+
|
|
|
+ expect(1, "event 14", 0.5f, 1.3f), //
|
|
|
+
|
|
|
+ expect(0, "end", 1.5f, 1.6f), //
|
|
|
+ expect(0, "dispose", 1.5f, 1.6f), //
|
|
|
+
|
|
|
+ expect(1, "event 30", 1, 1.8f), //
|
|
|
+ expect(1, "complete", 1, 1.8f), //
|
|
|
+ expect(1, "end", 1, 1.9f), //
|
|
|
+ expect(1, "dispose", 1, 1.9f) //
|
|
|
+ );
|
|
|
+ state.setAnimation(0, "events1", true).setEventThreshold(1);
|
|
|
+ state.addAnimation(0, "events2", false, 0.8f).setMixDuration(0.7f);
|
|
|
+ run(0.1f, 1000, null);
|
|
|
+
|
|
|
+ setup("looping", // 11
|
|
|
+ expect(0, "start", 0, 0), //
|
|
|
+ expect(0, "event 0", 0, 0), //
|
|
|
+ expect(0, "event 14", 0.5f, 0.5f), //
|
|
|
+ expect(0, "event 30", 1, 1), //
|
|
|
+ expect(0, "complete", 1, 1), //
|
|
|
+ expect(0, "event 0", 1, 1), //
|
|
|
+ expect(0, "event 14", 1.5f, 1.5f), //
|
|
|
+ expect(0, "event 30", 2, 2), //
|
|
|
+ expect(0, "complete", 2, 2), //
|
|
|
+ expect(0, "event 0", 2, 2), //
|
|
|
+ expect(0, "event 14", 2.5f, 2.5f), //
|
|
|
+ expect(0, "event 30", 3, 3), //
|
|
|
+ expect(0, "complete", 3, 3), //
|
|
|
+ expect(0, "event 0", 3, 3), //
|
|
|
+ expect(0, "event 14", 3.5f, 3.5f), //
|
|
|
+ expect(0, "event 30", 4, 4), //
|
|
|
+ expect(0, "complete", 4, 4), //
|
|
|
+ expect(0, "event 0", 4, 4) //
|
|
|
+ );
|
|
|
+ state.setAnimation(0, "events1", true);
|
|
|
+ run(0.1f, 4, null);
|
|
|
+
|
|
|
+ setup("not looping, track end past animation 0 duration", // 12
|
|
|
+ expect(0, "start", 0, 0), //
|
|
|
+ expect(0, "event 0", 0, 0), //
|
|
|
+ expect(0, "event 14", 0.5f, 0.5f), //
|
|
|
+ expect(0, "event 30", 1, 1), //
|
|
|
+ expect(0, "complete", 1, 1), //
|
|
|
+ expect(0, "interrupt", 2.1f, 2.1f), //
|
|
|
+
|
|
|
+ expect(1, "start", 0.1f, 2.1f), //
|
|
|
+ expect(1, "event 0", 0.1f, 2.1f), //
|
|
|
+
|
|
|
+ expect(0, "end", 2.1f, 2.2f), //
|
|
|
+ expect(0, "dispose", 2.1f, 2.2f), //
|
|
|
+
|
|
|
+ expect(1, "event 14", 0.5f, 2.5f), //
|
|
|
+ expect(1, "event 30", 1, 3), //
|
|
|
+ expect(1, "complete", 1, 3), //
|
|
|
+ expect(1, "end", 1, 3.1f), //
|
|
|
+ expect(1, "dispose", 1, 3.1f) //
|
|
|
+ );
|
|
|
+ state.setAnimation(0, "events1", false);
|
|
|
+ state.addAnimation(0, "events2", false, 2);
|
|
|
+ run(0.1f, 4f, null);
|
|
|
+
|
|
|
+ setup("interrupt animation after first loop complete", // 13
|
|
|
+ expect(0, "start", 0, 0), //
|
|
|
+ expect(0, "event 0", 0, 0), //
|
|
|
+ expect(0, "event 14", 0.5f, 0.5f), //
|
|
|
+ expect(0, "event 30", 1, 1), //
|
|
|
+ expect(0, "complete", 1, 1), //
|
|
|
+ expect(0, "event 0", 1, 1), //
|
|
|
+ expect(0, "event 14", 1.5f, 1.5f), //
|
|
|
+ expect(0, "event 30", 2, 2), //
|
|
|
+ expect(0, "complete", 2, 2), //
|
|
|
+ expect(0, "event 0", 2, 2), //
|
|
|
+ expect(0, "interrupt", 2.1f, 2.1f), //
|
|
|
+
|
|
|
+ expect(1, "start", 0.1f, 2.1f), //
|
|
|
+ expect(1, "event 0", 0.1f, 2.1f), //
|
|
|
+
|
|
|
+ expect(0, "end", 2.1f, 2.2f), //
|
|
|
+ expect(0, "dispose", 2.1f, 2.2f), //
|
|
|
+
|
|
|
+ expect(1, "event 14", 0.5f, 2.5f), //
|
|
|
+ expect(1, "event 30", 1, 3), //
|
|
|
+ expect(1, "complete", 1, 3), //
|
|
|
+ expect(1, "end", 1, 3.1f), //
|
|
|
+ expect(1, "dispose", 1, 3.1f) //
|
|
|
+ );
|
|
|
+ state.setAnimation(0, "events1", true);
|
|
|
+ run(0.1f, 6, new TestListener() {
|
|
|
+ public void frame (float time) {
|
|
|
+ if (MathUtils.isEqual(time, 1.4f)) state.addAnimation(0, "events2", false, 0);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ setup("add animation on empty track", // 14
|
|
|
+ expect(0, "start", 0, 0), //
|
|
|
+ expect(0, "event 0", 0, 0), //
|
|
|
+ expect(0, "event 14", 0.5f, 0.5f), //
|
|
|
+ expect(0, "event 30", 1, 1), //
|
|
|
+ expect(0, "complete", 1, 1), //
|
|
|
+ expect(0, "end", 1, 1.1f), //
|
|
|
+ expect(0, "dispose", 1, 1.1f) //
|
|
|
+ );
|
|
|
+ state.addAnimation(0, "events1", false, 0);
|
|
|
+ run(0.1f, 1.9f, null);
|
|
|
+
|
|
|
+ setup("end time beyond non-looping animation duration", // 15
|
|
|
+ expect(0, "start", 0, 0), //
|
|
|
+ expect(0, "event 0", 0, 0), //
|
|
|
+ expect(0, "event 14", 0.5f, 0.5f), //
|
|
|
+ expect(0, "event 30", 1, 1), //
|
|
|
+ expect(0, "complete", 1, 1), //
|
|
|
+ expect(0, "end", 9f, 9.1f), //
|
|
|
+ expect(0, "dispose", 9f, 9.1f) //
|
|
|
+ );
|
|
|
+ state.setAnimation(0, "events1", false).setTrackEnd(9);
|
|
|
+ run(0.1f, 10, null);
|
|
|
+
|
|
|
+ setup("looping with animation start", // 16
|
|
|
+ expect(0, "start", 0, 0), //
|
|
|
+ expect(0, "event 30", 0.4f, 0.4f), //
|
|
|
+ expect(0, "complete", 0.4f, 0.4f), //
|
|
|
+ expect(0, "event 30", 0.8f, 0.8f), //
|
|
|
+ expect(0, "complete", 0.8f, 0.8f), //
|
|
|
+ expect(0, "event 30", 1.2f, 1.2f), //
|
|
|
+ expect(0, "complete", 1.2f, 1.2f) //
|
|
|
+ );
|
|
|
+ entry = state.setAnimation(0, "events1", true);
|
|
|
+ entry.setAnimationLast(0.6f);
|
|
|
+ entry.setAnimationStart(0.6f);
|
|
|
+ run(0.1f, 1.4f, null);
|
|
|
+
|
|
|
+ setup("looping with animation start and end", // 17
|
|
|
+ expect(0, "start", 0, 0), //
|
|
|
+ expect(0, "event 14", 0.3f, 0.3f), //
|
|
|
+ expect(0, "complete", 0.6f, 0.6f), //
|
|
|
+ expect(0, "event 14", 0.9f, 0.9f), //
|
|
|
+ expect(0, "complete", 1.2f, 1.2f), //
|
|
|
+ expect(0, "event 14", 1.5f, 1.5f) //
|
|
|
+ );
|
|
|
+ entry = state.setAnimation(0, "events1", true);
|
|
|
+ entry.setAnimationStart(0.2f);
|
|
|
+ entry.setAnimationLast(0.2f);
|
|
|
+ entry.setAnimationEnd(0.8f);
|
|
|
+ run(0.1f, 1.8f, null);
|
|
|
+
|
|
|
+ setup("non-looping with animation start and end", // 18
|
|
|
+ expect(0, "start", 0, 0), //
|
|
|
+ expect(0, "event 14", 0.3f, 0.3f), //
|
|
|
+ expect(0, "complete", 0.6f, 0.6f), //
|
|
|
+ expect(0, "end", 1, 1.1f), //
|
|
|
+ expect(0, "dispose", 1, 1.1f) //
|
|
|
+ );
|
|
|
+ entry = state.setAnimation(0, "events1", false);
|
|
|
+ entry.setAnimationStart(0.2f);
|
|
|
+ entry.setAnimationLast(0.2f);
|
|
|
+ entry.setAnimationEnd(0.8f);
|
|
|
+ run(0.1f, 1.8f, null);
|
|
|
+
|
|
|
+ setup("mix out looping with animation start and end", // 19
|
|
|
+ expect(0, "start", 0, 0), //
|
|
|
+ expect(0, "event 14", 0.3f, 0.3f), //
|
|
|
+ expect(0, "complete", 0.6f, 0.6f), //
|
|
|
+ expect(0, "interrupt", 0.8f, 0.8f), //
|
|
|
+
|
|
|
+ expect(1, "start", 0.1f, 0.8f), //
|
|
|
+ expect(1, "event 0", 0.1f, 0.8f), //
|
|
|
+
|
|
|
+ expect(0, "event 14", 0.9f, 0.9f), //
|
|
|
+ expect(0, "complete", 1.2f, 1.2f), //
|
|
|
+
|
|
|
+ expect(1, "event 14", 0.5f, 1.2f), //
|
|
|
+
|
|
|
+ expect(0, "end", 1.4f, 1.5f), //
|
|
|
+ expect(0, "dispose", 1.4f, 1.5f), //
|
|
|
+
|
|
|
+ expect(1, "event 30", 1, 1.7f), //
|
|
|
+ expect(1, "complete", 1, 1.7f), //
|
|
|
+ expect(1, "end", 1, 1.8f), //
|
|
|
+ expect(1, "dispose", 1, 1.8f) //
|
|
|
+ );
|
|
|
+ entry = state.setAnimation(0, "events1", true);
|
|
|
+ entry.setAnimationStart(0.2f);
|
|
|
+ entry.setAnimationLast(0.2f);
|
|
|
+ entry.setAnimationEnd(0.8f);
|
|
|
+ entry.setEventThreshold(1);
|
|
|
+ state.addAnimation(0, "events2", false, 0.7f).setMixDuration(0.7f);
|
|
|
+ run(0.1f, 20, null);
|
|
|
+
|
|
|
+ setup("setAnimation with track entry mix", // 20
|
|
|
+ expect(0, "start", 0, 0), //
|
|
|
+ expect(0, "event 0", 0, 0), //
|
|
|
+ expect(0, "event 14", 0.5f, 0.5f), //
|
|
|
+ expect(0, "event 30", 1, 1), //
|
|
|
+ expect(0, "complete", 1, 1), //
|
|
|
+ expect(0, "event 0", 1, 1), //
|
|
|
+ expect(0, "interrupt", 1, 1), //
|
|
|
+
|
|
|
+ expect(1, "start", 0, 1), //
|
|
|
+
|
|
|
+ expect(1, "event 0", 0.1f, 1.1f), //
|
|
|
+ expect(1, "event 14", 0.5f, 1.5f), //
|
|
|
+
|
|
|
+ expect(0, "end", 1.7f, 1.8f), //
|
|
|
+ expect(0, "dispose", 1.7f, 1.8f), //
|
|
|
+
|
|
|
+ expect(1, "event 30", 1, 2), //
|
|
|
+ expect(1, "complete", 1, 2), //
|
|
|
+ expect(1, "end", 1, 2.1f), //
|
|
|
+ expect(1, "dispose", 1, 2.1f) //
|
|
|
+ );
|
|
|
+ state.setAnimation(0, "events1", true);
|
|
|
+ run(0.1f, 1000, new TestListener() {
|
|
|
+ public void frame (float time) {
|
|
|
+ if (MathUtils.isEqual(time, 1f)) state.setAnimation(0, "events2", false).setMixDuration(0.7f);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ setup("setAnimation twice", // 21
|
|
|
+ expect(0, "start", 0, 0), //
|
|
|
+ expect(0, "interrupt", 0, 0), //
|
|
|
+ expect(0, "end", 0, 0), //
|
|
|
+ expect(0, "dispose", 0, 0), //
|
|
|
+
|
|
|
+ expect(1, "start", 0, 0), //
|
|
|
+ expect(1, "event 0", 0, 0), //
|
|
|
+ expect(1, "event 14", 0.5f, 0.5f), //
|
|
|
+
|
|
|
+ // First 2 setAnimation calls are done.
|
|
|
+
|
|
|
+ expect(1, "interrupt", 0.8f, 0.8f), //
|
|
|
+
|
|
|
+ expect(0, "start", 0, 0.8f), //
|
|
|
+ expect(0, "interrupt", 0, 0.8f), //
|
|
|
+ expect(0, "end", 0, 0.8f), //
|
|
|
+ expect(0, "dispose", 0, 0.8f), //
|
|
|
+
|
|
|
+ expect(1, "start", 0, 0.8f), //
|
|
|
+ expect(1, "event 0", 0.1f, 0.9f), //
|
|
|
+ expect(1, "event 14", 0.5f, 1.3f), //
|
|
|
+ expect(1, "event 30", 1, 1.8f), //
|
|
|
+ expect(1, "complete", 1, 1.8f), //
|
|
|
+ expect(1, "end", 1, 1.9f), //
|
|
|
+ expect(1, "dispose", 1, 1.9f) //
|
|
|
+ );
|
|
|
+ state.setAnimation(0, "events1", false); // First should be ignored.
|
|
|
+ state.setAnimation(0, "events2", false);
|
|
|
+ run(0.1f, 1000, new TestListener() {
|
|
|
+ public void frame (float time) {
|
|
|
+ if (MathUtils.isEqual(time, 0.8f)) {
|
|
|
+ state.setAnimation(0, "events1", false); // First should be ignored.
|
|
|
+ state.setAnimation(0, "events2", false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ setup("addAnimation with delay on empty track", // 22
|
|
|
+ expect(0, "start", 0, 0), //
|
|
|
+ expect(0, "event 0", 0, 5), //
|
|
|
+ expect(0, "event 14", 0.5f, 5.5f), //
|
|
|
+ expect(0, "event 30", 1, 6), //
|
|
|
+ expect(0, "complete", 1, 6), //
|
|
|
+ expect(0, "end", 1, 6.1f), //
|
|
|
+ expect(0, "dispose", 1, 6.1f) //
|
|
|
+ );
|
|
|
+ state.addAnimation(0, "events1", false, 5);
|
|
|
+ run(0.1f, 10, null);
|
|
|
+
|
|
|
+ setup("setAnimation during AnimationStateListener"); // 23
|
|
|
+ state.addListener(new AnimationStateListener() {
|
|
|
+ public void start (TrackEntry entry) {
|
|
|
+ if (entry.getAnimation().getName().equals("events1")) state.setAnimation(1, "events2", false);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void interrupt (TrackEntry entry) {
|
|
|
+ state.addAnimation(3, "events2", false, 0);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void end (TrackEntry entry) {
|
|
|
+ if (entry.getAnimation().getName().equals("events1")) state.setAnimation(0, "events2", false);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void dispose (TrackEntry entry) {
|
|
|
+ if (entry.getAnimation().getName().equals("events1")) state.setAnimation(1, "events2", false);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void complete (TrackEntry entry) {
|
|
|
+ if (entry.getAnimation().getName().equals("events1")) state.setAnimation(1, "events2", false);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void event (TrackEntry entry, Event event) {
|
|
|
+ if (entry.getTrackIndex() != 2) state.setAnimation(2, "events2", false);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ state.addAnimation(0, "events1", false, 0);
|
|
|
+ state.addAnimation(0, "events2", false, 0);
|
|
|
+ state.setAnimation(1, "events2", false);
|
|
|
+ run(0.1f, 10, null);
|
|
|
+
|
|
|
+ setup("clearTrack", // 24
|
|
|
+ expect(0, "start", 0, 0), //
|
|
|
+ expect(0, "event 0", 0, 0), //
|
|
|
+ expect(0, "event 14", 0.5f, 0.5f), //
|
|
|
+ expect(0, "end", 0.7f, 0.7f), //
|
|
|
+ expect(0, "dispose", 0.7f, 0.7f) //
|
|
|
+ );
|
|
|
+ state.addAnimation(0, "events1", false, 0);
|
|
|
+ run(0.1f, 10, new TestListener() {
|
|
|
+ public void frame (float time) {
|
|
|
+ if (MathUtils.isEqual(time, 0.7f)) state.clearTrack(0);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ setup("setEmptyAnimation", // 25
|
|
|
+ expect(0, "start", 0, 0), //
|
|
|
+ expect(0, "event 0", 0, 0), //
|
|
|
+ expect(0, "event 14", 0.5f, 0.5f), //
|
|
|
+ expect(0, "interrupt", 0.7f, 0.7f), //
|
|
|
+
|
|
|
+ expect(-1, "start", 0, 0.7f), //
|
|
|
+ expect(-1, "complete", 0.1f, 0.8f), //
|
|
|
+
|
|
|
+ expect(0, "end", 0.8f, 0.9f), //
|
|
|
+ expect(0, "dispose", 0.8f, 0.9f), //
|
|
|
+
|
|
|
+ expect(-1, "end", 0.1f, 0.9f), //
|
|
|
+ expect(-1, "dispose", 0.1f, 0.9f) //
|
|
|
+ );
|
|
|
+ state.addAnimation(0, "events1", false, 0);
|
|
|
+ run(0.1f, 10, new TestListener() {
|
|
|
+ public void frame (float time) {
|
|
|
+ if (MathUtils.isEqual(time, 0.7f)) state.setEmptyAnimation(0, 0);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ System.out.println("AnimationState tests passed.");
|
|
|
+ }
|
|
|
+
|
|
|
+ void setup (String description, Result... expectedArray) {
|
|
|
+ test++;
|
|
|
+ expected.addAll(expectedArray);
|
|
|
+ stateData = new AnimationStateData(skeletonData);
|
|
|
+ state = new AnimationState(stateData);
|
|
|
+ time = 0;
|
|
|
+ fail = false;
|
|
|
+ log(test + ": " + description);
|
|
|
+ if (expectedArray.length > 0) {
|
|
|
+ state.addListener(stateListener);
|
|
|
+ log(String.format("%-3s%-12s%-7s%-7s%-7s", "#", "EVENT", "TRACK", "TOTAL", "RESULT"));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ void run (float incr, float endTime, TestListener listener) {
|
|
|
+ Skeleton skeleton = new Skeleton(skeletonData);
|
|
|
+ state.apply(skeleton);
|
|
|
+ while (time < endTime) {
|
|
|
+ time += incr;
|
|
|
+ skeleton.update(incr);
|
|
|
+ state.update(incr);
|
|
|
+
|
|
|
+ // Reduce float discrepancies for tests.
|
|
|
+ for (TrackEntry entry : state.getTracks()) {
|
|
|
+ if (entry == null) continue;
|
|
|
+ entry.trackTime = round(entry.trackTime, 6);
|
|
|
+ entry.delay = round(entry.delay, 3);
|
|
|
+ if (entry.mixingFrom != null) entry.mixingFrom.trackTime = round(entry.mixingFrom.trackTime, 6);
|
|
|
+ }
|
|
|
+
|
|
|
+ state.apply(skeleton);
|
|
|
+
|
|
|
+ // Apply multiple times to ensure no side effects.
|
|
|
+ if (expected.size > 0) state.removeListener(stateListener);
|
|
|
+ state.apply(skeleton);
|
|
|
+ state.apply(skeleton);
|
|
|
+ if (expected.size > 0) state.addListener(stateListener);
|
|
|
+
|
|
|
+ if (listener != null) listener.frame(time);
|
|
|
+ }
|
|
|
+ // Expecting more than actual is a failure.
|
|
|
+ for (int i = actual.size, n = expected.size; i < n; i++) {
|
|
|
+ log(String.format("%-29s", "<none>") + "FAIL: " + expected.get(i));
|
|
|
+ fail = true;
|
|
|
+ }
|
|
|
+ actual.clear();
|
|
|
+ expected.clear();
|
|
|
+ log("");
|
|
|
+ if (fail) {
|
|
|
+ log("TEST " + test + " FAILED!");
|
|
|
+ System.exit(0);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Result expect (int animationIndex, String name, float trackTime, float totalTime) {
|
|
|
+ Result result = new Result();
|
|
|
+ result.name = name;
|
|
|
+ result.animationIndex = animationIndex;
|
|
|
+ result.trackTime = trackTime;
|
|
|
+ result.totalTime = totalTime;
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ Result actual (String name, TrackEntry entry) {
|
|
|
+ Result result = new Result();
|
|
|
+ result.name = name;
|
|
|
+ result.animationIndex = skeletonData.getAnimations().indexOf(entry.animation, true);
|
|
|
+ result.trackTime = Math.round(entry.trackTime * 1000) / 1000f;
|
|
|
+ result.totalTime = Math.round(time * 1000) / 1000f;
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ void log (String message) {
|
|
|
+ System.out.println(message);
|
|
|
+ }
|
|
|
+
|
|
|
+ class Result {
|
|
|
+ String name;
|
|
|
+ int animationIndex;
|
|
|
+ float trackTime, totalTime;
|
|
|
+
|
|
|
+ public int hashCode () {
|
|
|
+ int result = 31 + animationIndex;
|
|
|
+ result = 31 * result + name.hashCode();
|
|
|
+ result = 31 * result + Float.floatToIntBits(totalTime);
|
|
|
+ result = 31 * result + Float.floatToIntBits(trackTime);
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ public boolean equals (Object obj) {
|
|
|
+ Result other = (Result)obj;
|
|
|
+ if (animationIndex != other.animationIndex) return false;
|
|
|
+ if (!name.equals(other.name)) return false;
|
|
|
+ if (!MathUtils.isEqual(totalTime, other.totalTime)) return false;
|
|
|
+ if (!MathUtils.isEqual(trackTime, other.trackTime)) return false;
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ public String toString () {
|
|
|
+ return String.format("%-3s%-12s%-7s%-7s", "" + animationIndex, name, roundTime(trackTime), roundTime(totalTime));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ static float round (float value, int decimals) {
|
|
|
+ float shift = (float)Math.pow(10, decimals);
|
|
|
+ return Math.round(value * shift) / shift;
|
|
|
+ }
|
|
|
+
|
|
|
+ static String roundTime (float value) {
|
|
|
+ String text = Float.toString(round(value, 3));
|
|
|
+ return text.endsWith(".0") ? text.substring(0, text.length() - 2) : text;
|
|
|
+ }
|
|
|
+
|
|
|
+ static interface TestListener {
|
|
|
+ void frame (float time);
|
|
|
+ }
|
|
|
+
|
|
|
+ static public void main (String[] args) throws Exception {
|
|
|
+ new AnimationStateTests();
|
|
|
+ }
|
|
|
}
|