Browse Source

simplify methods, thanks to capdevon

rickard 8 months ago
parent
commit
b41846ec72

+ 2 - 9
build.gradle

@@ -44,7 +44,6 @@ dependencies {
     corelibs dep("org.jmonkeyengine:jme3-effects:$jmeVersion-$jmeVersionTag", true, true)
     corelibs dep("org.jmonkeyengine:jme3-effects:$jmeVersion-$jmeVersionTag", true, true)
     corelibs dep("com.github.stephengold:Minie:8.2.0", true, true) // replacement for bullet-native
     corelibs dep("com.github.stephengold:Minie:8.2.0", true, true) // replacement for bullet-native
     corelibs dep("com.github.stephengold:Heart:9.1.0", true, true) // requirement for Minie
     corelibs dep("com.github.stephengold:Heart:9.1.0", true, true) // requirement for Minie
-    corelibs dep("com.github.stephengold:Wes:0.8.1", true, true)
     corelibs dep(fileTree("lib"), false, false)
     corelibs dep(fileTree("lib"), false, false)
     corelibs dep("org.jmonkeyengine:jme3-jogg:$jmeVersion-$jmeVersionTag", true, true)
     corelibs dep("org.jmonkeyengine:jme3-jogg:$jmeVersion-$jmeVersionTag", true, true)
 
 
@@ -64,7 +63,7 @@ dependencies {
     optlibs dep("org.jmonkeyengine:jme3-ios:$jmeVersion-$jmeVersionTag", true, true)
     optlibs dep("org.jmonkeyengine:jme3-ios:$jmeVersion-$jmeVersionTag", true, true)
     optlibs dep("org.jmonkeyengine:jme3-android-native:$jmeVersion-$jmeVersionTag", true, true)
     optlibs dep("org.jmonkeyengine:jme3-android-native:$jmeVersion-$jmeVersionTag", true, true)
     optlibs dep("org.jmonkeyengine:jme3-lwjgl3:$jmeVersion-$jmeVersionTag", true, true)
     optlibs dep("org.jmonkeyengine:jme3-lwjgl3:$jmeVersion-$jmeVersionTag", true, true)
-    
+    optlibs dep("com.github.stephengold:Wes:0.8.1", true, true)
     testdatalibs dep("org.jmonkeyengine:jme3-testdata:$jmeVersion-$jmeVersionTag", false, false)
     testdatalibs dep("org.jmonkeyengine:jme3-testdata:$jmeVersion-$jmeVersionTag", false, false)
     examplelibs dep("org.jmonkeyengine:jme3-examples:$jmeVersion-$jmeVersionTag", false, true)
     examplelibs dep("org.jmonkeyengine:jme3-examples:$jmeVersion-$jmeVersionTag", false, true)
 }
 }
@@ -133,13 +132,7 @@ task copyBaseLibs(dependsOn:configurations.corelibs) {
                     into "jme3-core-baselibs/release/modules/ext/"
                     into "jme3-core-baselibs/release/modules/ext/"
                 }
                 }
             } else if( file.name.contains("Heart") && !isSourceOrJavadoc(file.name)) {
             } else if( file.name.contains("Heart") && !isSourceOrJavadoc(file.name)) {
-                // Special handling of Heart, since it doesn't follow the name convention
-                copy {
-                    from file
-                    into "jme3-core-baselibs/release/modules/ext/"
-                }
-            } else if( file.name.contains("Wes") && !isSourceOrJavadoc(file.name)) {
-                // Special handling of Wes, since it doesn't follow the name convention
+                // Special handling of Minie, since it doesn't follow the name convention
                 copy {
                 copy {
                     from file
                     from file
                     into "jme3-core-baselibs/release/modules/ext/"
                     into "jme3-core-baselibs/release/modules/ext/"

+ 83 - 58
jme3-core/src/com/jme3/gde/core/assets/actions/MergeAnimationsAction.java

@@ -42,28 +42,28 @@ import com.jme3.anim.util.HasLocalTransform;
 import com.jme3.gde.core.assets.SpatialAssetDataObject;
 import com.jme3.gde.core.assets.SpatialAssetDataObject;
 import com.jme3.scene.Node;
 import com.jme3.scene.Node;
 import com.jme3.scene.Spatial;
 import com.jme3.scene.Spatial;
-import com.jme3.scene.plugins.bvh.SkeletonMapping;
+import com.jme3.util.SafeArrayList;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.awt.event.ActionListener;
 import java.io.IOException;
 import java.io.IOException;
 import java.util.Collection;
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.Iterator;
 import java.util.List;
 import java.util.List;
-import jme3utilities.MyAnimation;
-import jme3utilities.wes.AnimationEdit;
-import org.bushe.swing.event.Logger;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 import org.openide.DialogDisplayer;
 import org.openide.DialogDisplayer;
 import org.openide.NotifyDescriptor;
 import org.openide.NotifyDescriptor;
 import org.openide.NotifyDescriptor.Confirmation;
 import org.openide.NotifyDescriptor.Confirmation;
 import org.openide.util.Exceptions;
 import org.openide.util.Exceptions;
 
 
 /**
 /**
- * Action for merging one or more spatials' animation to another.
- * Same rig required.
+ * Action for merging one or more spatials' animation to another. Same rig
+ * required.
+ *
  * @author rickard
  * @author rickard
  */
  */
 public class MergeAnimationsAction implements ActionListener {
 public class MergeAnimationsAction implements ActionListener {
-    
+
     private static final String CANCEL = "Cancel";
     private static final String CANCEL = "Cancel";
     private final List<SpatialAssetDataObject> spatials;
     private final List<SpatialAssetDataObject> spatials;
     private final Logger logger;
     private final Logger logger;
@@ -77,84 +77,63 @@ public class MergeAnimationsAction implements ActionListener {
     public void actionPerformed(ActionEvent e) {
     public void actionPerformed(ActionEvent e) {
         if (spatials.size() == 1) {
         if (spatials.size() == 1) {
             DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(
             DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(
-                            "Must select more than one spatial",
-                            NotifyDescriptor.ERROR_MESSAGE));
+                    "Must select more than one spatial",
+                    NotifyDescriptor.ERROR_MESSAGE));
             return;
             return;
         }
         }
-        
+
         final Object selectedSpatial = createSelector().getValue();
         final Object selectedSpatial = createSelector().getValue();
-        
+
         if (selectedSpatial == null || selectedSpatial.equals(CANCEL)) {
         if (selectedSpatial == null || selectedSpatial.equals(CANCEL)) {
-            logger.log(Logger.Level.INFO, "Operation cancelled by user.");
+            logger.log(Level.INFO, "Operation cancelled by user.");
             return;
             return;
         }
         }
-        
+
         final SpatialAssetDataObject targetAsset = findSpatial(selectedSpatial.toString());
         final SpatialAssetDataObject targetAsset = findSpatial(selectedSpatial.toString());
-        
+
         if (targetAsset == null) {
         if (targetAsset == null) {
-            logger.log(Logger.Level.INFO, "Operation failed. No spatial.");
+            logger.log(Level.INFO, "Operation failed. No spatial.");
             return;
             return;
         }
         }
-        
+
         final Spatial targetSpatial = targetAsset.loadAsset();
         final Spatial targetSpatial = targetAsset.loadAsset();
         final AnimComposer targetAnimComposer = findAnimComposer(targetSpatial, null);
         final AnimComposer targetAnimComposer = findAnimComposer(targetSpatial, null);
-        
+
         if (targetAnimComposer == null) {
         if (targetAnimComposer == null) {
             DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(
             DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(
-                            String.format("%s has no AnimComposer.", targetSpatial),
-                            NotifyDescriptor.ERROR_MESSAGE));
+                    String.format("%s has no AnimComposer.", targetSpatial),
+                    NotifyDescriptor.ERROR_MESSAGE));
             return;
             return;
         }
         }
         final Spatial targetAnimComposerSpatial = targetAnimComposer.getSpatial();
         final Spatial targetAnimComposerSpatial = targetAnimComposer.getSpatial();
         for (final Iterator<SpatialAssetDataObject> it = spatials.iterator(); it.hasNext();) {
         for (final Iterator<SpatialAssetDataObject> it = spatials.iterator(); it.hasNext();) {
             final SpatialAssetDataObject spatialAssetDataObject = it.next();
             final SpatialAssetDataObject spatialAssetDataObject = it.next();
-            if(spatialAssetDataObject.getName().equals(selectedSpatial)) {
+            if (spatialAssetDataObject.getName().equals(selectedSpatial)) {
                 continue;
                 continue;
             }
             }
             Spatial sourceSpatial = spatialAssetDataObject.loadAsset();
             Spatial sourceSpatial = spatialAssetDataObject.loadAsset();
             final AnimComposer sourceAnimComposer = findAnimComposer(sourceSpatial, null);
             final AnimComposer sourceAnimComposer = findAnimComposer(sourceSpatial, null);
             if (sourceAnimComposer == null) {
             if (sourceAnimComposer == null) {
                 DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(
                 DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(
-                            String.format("%s has no AnimComposer.", sourceSpatial),
-                            NotifyDescriptor.ERROR_MESSAGE));
+                        String.format("%s has no AnimComposer.", sourceSpatial),
+                        NotifyDescriptor.ERROR_MESSAGE));
                 return;
                 return;
             }
             }
             copyClips(sourceAnimComposer, targetAnimComposer, targetAnimComposerSpatial.getControl(SkinningControl.class).getArmature());
             copyClips(sourceAnimComposer, targetAnimComposer, targetAnimComposerSpatial.getControl(SkinningControl.class).getArmature());
         }
         }
-        logger.log(Logger.Level.INFO, "Merging animations done. Saving.");
+        logger.log(Level.INFO, "Merging animations done. Saving.");
         try {
         try {
             targetAsset.saveAsset();
             targetAsset.saveAsset();
         } catch (IOException ex) {
         } catch (IOException ex) {
             Exceptions.printStackTrace(ex);
             Exceptions.printStackTrace(ex);
         }
         }
     }
     }
-    
-    private static AnimClip retargetClip(
-            AnimClip clip, Armature armature, String clipName) {
-        AnimTrack[] animTracks = clip.getTracks();
-        AnimClip result = new AnimClip(clipName);
-        for (AnimTrack animTrack : animTracks) {
-            if (MyAnimation.isJointTrack(animTrack)) {
-                TransformTrack transformTrack = (TransformTrack) animTrack;
-                HasLocalTransform animTarget = transformTrack.getTarget();
-                Joint animJoint = (Joint) animTarget;
-                String jointName = animJoint.getName();
-                Joint charaJoint = armature.getJoint(jointName);
-                if (charaJoint != null) {
-                    transformTrack.setTarget(charaJoint);
-                    AnimationEdit.addTrack(result, transformTrack);
-                }
-            }
-        }
-        return result;
-    }
 
 
-    
     private void copyClips(final AnimComposer from, final AnimComposer to, Armature toArmature) {
     private void copyClips(final AnimComposer from, final AnimComposer to, Armature toArmature) {
         final Collection<AnimClip> animClips = from.getAnimClips();
         final Collection<AnimClip> animClips = from.getAnimClips();
-        for(AnimClip animClip: animClips) {
+        for (AnimClip animClip : animClips) {
             to.addAnimClip(retargetClip(animClip, toArmature, animClip.getName()));
             to.addAnimClip(retargetClip(animClip, toArmature, animClip.getName()));
-            logger.log(Logger.Level.DEBUG, String.format("Added anim clip %s", animClip.getName()));
+            logger.log(Level.FINE, String.format("Added anim clip %s", animClip.getName()));
         }
         }
     }
     }
 
 
@@ -166,22 +145,22 @@ public class MergeAnimationsAction implements ActionListener {
             spatials[index++] = spatialAssetDataObject.getName();
             spatials[index++] = spatialAssetDataObject.getName();
         }
         }
         spatials[index++] = CANCEL;
         spatials[index++] = CANCEL;
-        final NotifyDescriptor.Confirmation message =
-                new NotifyDescriptor.Confirmation(
+        final NotifyDescriptor.Confirmation message
+                = new NotifyDescriptor.Confirmation(
                         "Select spatial to copy animations to.");
                         "Select spatial to copy animations to.");
         message.setOptions(spatials);
         message.setOptions(spatials);
-        
+
         DialogDisplayer.getDefault().notify(message);
         DialogDisplayer.getDefault().notify(message);
-        
+
         return message;
         return message;
     }
     }
-    
+
     private AnimComposer findAnimComposer(Spatial spatial, AnimComposer animComposer) {
     private AnimComposer findAnimComposer(Spatial spatial, AnimComposer animComposer) {
         if (spatial.getControl(AnimComposer.class) != null) {
         if (spatial.getControl(AnimComposer.class) != null) {
-            animComposer = spatial.getControl(AnimComposer.class);
+            return spatial.getControl(AnimComposer.class);
         }
         }
         if (animComposer == null && spatial instanceof Node node) {
         if (animComposer == null && spatial instanceof Node node) {
-            for (Spatial child: node.getChildren()) {
+            for (Spatial child : node.getChildren()) {
                 animComposer = findAnimComposer(child, animComposer);
                 animComposer = findAnimComposer(child, animComposer);
                 if (animComposer != null) {
                 if (animComposer != null) {
                     return animComposer;
                     return animComposer;
@@ -190,19 +169,65 @@ public class MergeAnimationsAction implements ActionListener {
         }
         }
         return animComposer;
         return animComposer;
     }
     }
-    
+
     private SpatialAssetDataObject findSpatial(String selected) {
     private SpatialAssetDataObject findSpatial(String selected) {
         for (Iterator<SpatialAssetDataObject> it = spatials.iterator(); it.hasNext();) {
         for (Iterator<SpatialAssetDataObject> it = spatials.iterator(); it.hasNext();) {
             final SpatialAssetDataObject spatialAssetDataObject = it.next();
             final SpatialAssetDataObject spatialAssetDataObject = it.next();
-            if(spatialAssetDataObject.getName().equals(selected)) {
+            if (spatialAssetDataObject.getName().equals(selected)) {
                 return spatialAssetDataObject;
                 return spatialAssetDataObject;
             }
             }
         }
         }
         NotifyDescriptor.Message msg = new NotifyDescriptor.Message(
         NotifyDescriptor.Message msg = new NotifyDescriptor.Message(
-            "Main asset to copy to not found. This is likely an issue with the tool itself.",
-            NotifyDescriptor.ERROR_MESSAGE);
+                "Main asset to copy to not found. This is likely an issue with the tool itself.",
+                NotifyDescriptor.ERROR_MESSAGE);
         DialogDisplayer.getDefault().notify(msg);
         DialogDisplayer.getDefault().notify(msg);
         return null;
         return null;
     }
     }
-    
+
+    private AnimClip retargetClip(AnimClip sourceClip, Armature targetArmature, String clipName) {
+
+        // Create a list to hold the new tracks
+        SafeArrayList<AnimTrack> tracks = new SafeArrayList<>(AnimTrack.class);
+
+        // Iterate through each track in the source clip
+        for (AnimTrack animTrack : sourceClip.getTracks()) {
+
+            TransformTrack sourceTrack = (TransformTrack) animTrack;
+            String targetName = getTargetName(sourceTrack.getTarget());
+            if (targetName == null) {
+                logger.log(Level.SEVERE, String.format("Unsupported target for: %s. Skipping.", animTrack));
+                continue;
+            }
+            Joint target = targetArmature.getJoint(targetName);
+
+            if (target != null) {
+                // Clone the source track and set the new target joint
+                TransformTrack newTrack = sourceTrack.jmeClone();
+                newTrack.setTarget(target);
+                tracks.add(newTrack);
+
+            } else {
+                logger.log(Level.WARNING, "Joint not found in the target Armature: {0}", targetName);
+            }
+        }
+
+        // Create a new animation clip with the specified name and set its tracks
+        AnimClip newClip = new AnimClip(clipName);
+        newClip.setTracks(tracks.getArray());
+
+        logger.log(Level.INFO, "Created new AnimClip {0} with {1} tracks out of {2} from the source clip",
+                new Object[]{clipName, tracks.size(), sourceClip.getTracks().length});
+        return newClip;
+    }
+
+    private String getTargetName(final HasLocalTransform target) {
+        if (target instanceof Node node) {
+            return node.getName();
+        }
+        if (target instanceof Joint joint) {
+            return joint.getName();
+        }
+        return null;
+    }
+
 }
 }