diff --git a/jme3-core/src/main/java/com/jme3/anim/AnimComposer.java b/jme3-core/src/main/java/com/jme3/anim/AnimComposer.java index f9fd84edbf..f2ba8f8d8f 100644 --- a/jme3-core/src/main/java/com/jme3/anim/AnimComposer.java +++ b/jme3-core/src/main/java/com/jme3/anim/AnimComposer.java @@ -52,6 +52,7 @@ * @author Nehon */ public class AnimComposer extends AbstractControl { + /** * The name of the default layer. */ @@ -121,7 +122,7 @@ public void removeAnimClip(AnimClip anim) { * @return The action corresponding to the given name. */ public Action setCurrentAction(String name) { - return setCurrentAction(name, DEFAULT_LAYER); + return setCurrentAction(name, DEFAULT_LAYER, true); } /** @@ -144,9 +145,9 @@ public Action setCurrentAction(String actionName, String layerName) { * @return The action corresponding to the given name. */ public Action setCurrentAction(String actionName, String layerName, boolean loop) { - AnimLayer l = getLayer(layerName); + AnimLayer layer = getLayer(layerName); Action currentAction = action(actionName); - l.setCurrentAction(actionName, currentAction, loop); + layer.setCurrentAction(actionName, currentAction, loop); return currentAction; } @@ -239,7 +240,8 @@ public void setTime(String layerName, double time) { /** * * @param name The name of the action to return. - * @return The action registered with specified name. It will make a new action if there isn't any. + * @return The action registered with specified name. It will make a new + * action if there isn't any. * @see #makeAction(java.lang.String) */ public Action action(String name) { @@ -254,7 +256,8 @@ public Action action(String name) { /** * * @param name The name of the action to return. - * @return The action registered with specified name or null if nothing is registered. + * @return The action registered with specified name or null if nothing is + * registered. */ public Action getAction(String name) { return actions.get(name); @@ -331,8 +334,8 @@ public AnimLayer removeLayer(String name) { } /** - * Creates an action that will interpolate over an entire sequence - * of tweens in order. + * Creates an action that will interpolate over an entire sequence of tweens + * in order. * * @param name a name for the new Action * @param tweens the desired sequence of tweens @@ -374,8 +377,9 @@ public void reset() { } /** - * Returns an unmodifiable collection of all available animations. When an attempt - * is made to modify the collection, an UnsupportedOperationException is thrown. + * Returns an unmodifiable collection of all available animations. When an + * attempt is made to modify the collection, an + * UnsupportedOperationException is thrown. * * @return the unmodifiable collection of animations */ @@ -526,7 +530,9 @@ public void cloneFields(Cloner cloner, Object original) { for (String key : layers.keySet()) { newLayers.put(key, cloner.clone(layers.get(key))); } - + if (!newLayers.containsKey(DEFAULT_LAYER)) { + newLayers.put(DEFAULT_LAYER, new AnimLayer(DEFAULT_LAYER, null)); + } layers = newLayers; } @@ -546,6 +552,9 @@ public void read(JmeImporter im) throws IOException { animClipMap = (Map) ic.readStringSavableMap("animClipMap", new HashMap()); globalSpeed = ic.readFloat("globalSpeed", 1f); layers = (Map) ic.readStringSavableMap("layers", new HashMap()); + if (!layers.containsKey(DEFAULT_LAYER)) { + layers.put(DEFAULT_LAYER, new AnimLayer(DEFAULT_LAYER, null)); + } } /** diff --git a/jme3-core/src/test/java/com/jme3/anim/AnimComposerTest.java b/jme3-core/src/test/java/com/jme3/anim/AnimComposerTest.java index 4cc5eb9080..4813747695 100644 --- a/jme3-core/src/test/java/com/jme3/anim/AnimComposerTest.java +++ b/jme3-core/src/test/java/com/jme3/anim/AnimComposerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2019 jMonkeyEngine + * Copyright (c) 2009-2024 jMonkeyEngine * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -32,6 +32,7 @@ package com.jme3.anim; import com.jme3.anim.tween.action.Action; +import com.jme3.util.clone.Cloner; import java.util.Set; import java.util.TreeSet; import org.junit.Assert; @@ -57,34 +58,34 @@ public void testGetAnimClipsNames() { Assert.assertNotNull(composer.getAnimClipsNames()); Assert.assertEquals(0, composer.getAnimClipsNames().size()); } - + @Test public void testMakeLayer() { AnimComposer composer = new AnimComposer(); - + final String layerName = "TestLayer"; composer.makeLayer(layerName, null); - + final Set layers = new TreeSet<>(); layers.add("Default"); layers.add(layerName); - + Assert.assertNotNull(composer.getLayer(layerName)); Assert.assertEquals(layers, composer.getLayerNames()); } - + @Test public void testMakeAction() { AnimComposer composer = new AnimComposer(); - + final String animName = "TestClip"; - + final AnimClip anim = new AnimClip(animName); composer.addAnimClip(anim); - + final Action action = composer.makeAction(animName); - + Assert.assertNotNull(action); } @@ -102,4 +103,26 @@ public void testGetAnimClipsNamesIsNotModifiable() { composer.getAnimClipsNames().add("test"); } + @Test + public void testHasDefaultLayer() { + AnimComposer composer = new AnimComposer(); + + AnimLayer defaultLayer = composer.getLayer("Default"); + Assert.assertNotNull(defaultLayer); + } + + @Test + /** + * https://github.com/jMonkeyEngine/jmonkeyengine/issues/2341 + * + */ + public void testMissingDefaultLayerIssue2341() { + AnimComposer composer = new AnimComposer(); + composer.removeLayer(AnimComposer.DEFAULT_LAYER); + + AnimComposer clone = (AnimComposer) composer.jmeClone(); + clone.cloneFields(new Cloner(), composer); + Assert.assertNotNull(clone.getLayer(AnimComposer.DEFAULT_LAYER)); + } + }