From c5c06ca10a61f9aad1bde1a21c0b0c0c8637b0cf Mon Sep 17 00:00:00 2001 From: "rem..om" Date: Sun, 7 Oct 2012 08:34:09 +0000 Subject: [PATCH] SDK : One can now set the animation parameters (loopMode and speed) when playing an animation in the SDK git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9848 75d07b2b-3a1a-0410-a2c5-0572b91ccdca --- .../sceneexplorer/nodes/JmeAnimation.java | 184 +++++++++++++---- .../nodes/actions/Bundle.properties | 7 + .../nodes/actions/ChannelDialog.form | 160 +++++++++++++++ .../nodes/actions/ChannelDialog.java | 185 ++++++++++++++++++ 4 files changed, 501 insertions(+), 35 deletions(-) create mode 100644 sdk/jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/actions/ChannelDialog.form create mode 100644 sdk/jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/actions/ChannelDialog.java diff --git a/sdk/jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/JmeAnimation.java b/sdk/jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/JmeAnimation.java index 603465f5b..535f7091f 100644 --- a/sdk/jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/JmeAnimation.java +++ b/sdk/jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/JmeAnimation.java @@ -31,9 +31,14 @@ */ package com.jme3.gde.core.sceneexplorer.nodes; +import com.jme3.animation.AnimChannel; import com.jme3.animation.AnimControl; +import com.jme3.animation.AnimEventListener; import com.jme3.animation.Animation; +import com.jme3.animation.LoopMode; +import com.jme3.gde.core.properties.AnimationProperty; import com.jme3.gde.core.scene.SceneApplication; +import com.jme3.gde.core.sceneexplorer.nodes.actions.ChannelDialog; import com.jme3.gde.core.sceneexplorer.nodes.actions.impl.tracks.AudioTrackWizardAction; import com.jme3.gde.core.sceneexplorer.nodes.actions.impl.tracks.EffectTrackWizardAction; import java.awt.Image; @@ -56,17 +61,20 @@ import org.openide.util.ImageUtilities; */ @org.openide.util.lookup.ServiceProvider(service = SceneExplorerNode.class) public class JmeAnimation extends AbstractSceneExplorerNode { - + private Animation animation; private static final String ICON = "com/jme3/gde/core/sceneexplorer/nodes/icons/anim.png"; private static final String ICON_PLAY = "com/jme3/gde/core/sceneexplorer/nodes/icons/animPlay.png"; private Image icon; private JmeAnimControl jmeControl; private boolean playing = false; - + private LoopMode animLoopMode = LoopMode.Loop; + private float animSpeed = 1.0f; + private AnimChannel channel = null; + public JmeAnimation() { } - + public JmeAnimation(JmeAnimControl control, Animation animation, JmeTrackChildren children, DataObject dataObject) { super(children); this.dataObject = dataObject; @@ -79,44 +87,44 @@ public class JmeAnimation extends AbstractSceneExplorerNode { children.setAnimation(this); children.setAnimControl(jmeControl); icon = ImageUtilities.loadImage(ICON); - + } - + @Override public Image getIcon(int type) { return icon; } - + @Override public Image getOpenedIcon(int type) { - + return icon; - + } - + public void toggleIcon(boolean enabled) { if (!playing) { icon = ImageUtilities.loadImage(ICON); - + } else { icon = ImageUtilities.loadImage(ICON_PLAY); - + } fireIconChange(); } - + @Override public Action getPreferredAction() { return Actions.alwaysEnabled(new PlayAction(), "Play", "", false); - + } - + private void play() { playing = !playing; toggleIcon(playing); jmeControl.setAnim(this); } - + @Override protected Sheet createSheet() { //TODO: multithreading.. @@ -128,36 +136,37 @@ public class JmeAnimation extends AbstractSceneExplorerNode { return sheet; } - // set.put(new AnimationProperty(animControl)); + set.put(new AnimationProperty(jmeControl.getLookup().lookup(AnimControl.class))); sheet.put(set); return sheet; - + } - + public void setChanged() { fireSave(true); } - + @Override public Action[] getActions(boolean context) { - + return new Action[]{Actions.alwaysEnabled(new PlayAction(), playing ? "Stop" : "Play", "", false), + Actions.alwaysEnabled(new PlayBackParamsAction(), "Playback parameters", "", false), Actions.alwaysEnabled(new EffectTrackWizardAction(jmeControl.getLookup().lookup(AnimControl.class).getSpatial(), this), "Add Effect Track", "", false), Actions.alwaysEnabled(new AudioTrackWizardAction(jmeControl.getLookup().lookup(AnimControl.class).getSpatial(), this), "Add Audio Track", "", false) }; } - + @Override public boolean canDestroy() { return false; } - + public void stop() { playing = false; - toggleIcon(playing); + toggleIcon(playing); } - + @Override public void destroy() throws IOException { // super.destroy(); @@ -177,61 +186,166 @@ public class JmeAnimation extends AbstractSceneExplorerNode { // Exceptions.printStackTrace(ex); // } } - + @Override public void refresh(boolean immediate) { super.refresh(immediate); ((JmeTrackChildren) getChildren()).refreshChildren(false); } - + public Class getExplorerObjectClass() { return Animation.class; } - + @Override public Class getExplorerNodeClass() { return JmeAnimation.class; } - + @Override public Node[] createNodes(Object key, DataObject key2, boolean cookie) { JmeTrackChildren children = new JmeTrackChildren(this, jmeControl); JmeAnimation jsc = new JmeAnimation(jmeControl, (Animation) key, children, key2); return new Node[]{jsc}; } - + class PlayAction implements ActionListener { - + public void actionPerformed(ActionEvent e) { final AnimControl control = jmeControl.getLookup().lookup(AnimControl.class); if (control == null) { return; } + try { SceneApplication.getApplication().enqueue(new Callable() { - public Void call() throws Exception { if (playing) { control.clearChannels(); + channel = null; jmeControl.setAnim(null); return null; } control.clearChannels(); - control.createChannel().setAnim(animation.getName()); - play(); - + channel = control.createChannel(); + channel.setAnim(animation.getName()); + innerSetLoopMode(); + channel.setSpeed(animSpeed); + java.awt.EventQueue.invokeLater(new Runnable() { + public void run() { + play(); + } + }); return null; + } }).get(); } catch (InterruptedException ex) { Exceptions.printStackTrace(ex); + return; } catch (ExecutionException ex) { Exceptions.printStackTrace(ex); + return; } - + } } + + private void innerSetLoopMode() { + final AnimControl control = jmeControl.getLookup().lookup(AnimControl.class); + channel.setLoopMode(animLoopMode); + if (animLoopMode == LoopMode.DontLoop) { + control.addListener(new AnimEventListener() { + public void onAnimCycleDone(AnimControl ac, AnimChannel ac1, String animName) { + if (animName.equals(animation.getName())) { + if (playing) { + control.clearChannels(); + channel = null; + jmeControl.setAnim(null); + java.awt.EventQueue.invokeLater(new Runnable() { + public void run() { + stop(); + } + }); + } + + ac.removeListener(this); + } + } + + public void onAnimChange(AnimControl ac, AnimChannel ac1, String animName) { +// if (animation.getName().equals(ac1.getAnimationName())) { +// java.awt.EventQueue.invokeLater(new Runnable() { // +// public void run() { +// stop(); +// } +// }); +// } + } + }); + } + } + + class PlayBackParamsAction implements ActionListener { + + ChannelDialog dialog = new ChannelDialog(null, false, JmeAnimation.this); + + public void actionPerformed(ActionEvent e) { + dialog.setLocationRelativeTo(null); + dialog.setVisible(true); + + } + } + + public LoopMode getAnimLoopMode() { + return animLoopMode; + } + + public void setAnimLoopMode(LoopMode loopMode) { + this.animLoopMode = loopMode; + + try { + SceneApplication.getApplication().enqueue(new Callable() { + public Void call() throws Exception { + if (channel != null) { + innerSetLoopMode(); + } + + return null; + } + }).get(); + } catch (InterruptedException ex) { + Exceptions.printStackTrace(ex); + } catch (ExecutionException ex) { + Exceptions.printStackTrace(ex); + } + + + } + + public float getAnimSpeed() { + return animSpeed; + } + + public void setAnimSpeed(float speed) { + this.animSpeed = speed; + try { + SceneApplication.getApplication().enqueue(new Callable() { + public Void call() throws Exception { + if (channel != null) { + channel.setSpeed(animSpeed); + } + return null; + } + }).get(); + } catch (InterruptedException ex) { + Exceptions.printStackTrace(ex); + } catch (ExecutionException ex) { + Exceptions.printStackTrace(ex); + } + + } // class AddTrackAction implements ActionListener { // // public void actionPerformed(ActionEvent e) { diff --git a/sdk/jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/actions/Bundle.properties b/sdk/jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/actions/Bundle.properties index a7bfa7f19..02a4b8e79 100644 --- a/sdk/jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/actions/Bundle.properties +++ b/sdk/jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/actions/Bundle.properties @@ -14,3 +14,10 @@ ParticleInfluencerPicker.jPanel1.border.title=Chose a UserData type ParticleInfluencerPicker.jButton2.text=Cancel ParticleInfluencerPicker.jButton1.text=Ok ParticleInfluencerPicker.jTextField1.text= +ChannelDialog.jPanel1.border.title=Animation properties +ChannelDialog.jLabel1.text=Loop mode +ChannelDialog.jLabel2.text=Speed +ChannelDialog.jTextField1.text=jTextField1 +ChannelDialog.jButton1.text=Ok +ChannelDialog.jButton2.text=Cancel +ChannelDialog.jButton2.actionCommand=Cancel diff --git a/sdk/jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/actions/ChannelDialog.form b/sdk/jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/actions/ChannelDialog.form new file mode 100644 index 000000000..7c9e5b3e0 --- /dev/null +++ b/sdk/jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/actions/ChannelDialog.form @@ -0,0 +1,160 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/sdk/jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/actions/ChannelDialog.java b/sdk/jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/actions/ChannelDialog.java new file mode 100644 index 000000000..69ee05379 --- /dev/null +++ b/sdk/jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/actions/ChannelDialog.java @@ -0,0 +1,185 @@ + /* + * Copyright (c) 2009-2012 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.jme3.gde.core.sceneexplorer.nodes.actions; + +import com.jme3.animation.LoopMode; +import com.jme3.gde.core.sceneexplorer.nodes.JmeAnimation; + +/** + * + * @author Nehon + */ + + +public class ChannelDialog extends javax.swing.JDialog { + + JmeAnimation jmeAnim; + + /** + * Creates new form ChannelDialog + */ + public ChannelDialog(java.awt.Frame parent, boolean modal, JmeAnimation jmeAnim) { + super(parent, modal); + this.jmeAnim = jmeAnim; + initComponents(); + jTextField1.setText(jmeAnim.getAnimSpeed()+""); + jComboBox1.setSelectedItem(jmeAnim.getAnimLoopMode().toString()); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + jPanel1 = new javax.swing.JPanel(); + jLabel1 = new javax.swing.JLabel(); + jLabel2 = new javax.swing.JLabel(); + jComboBox1 = new javax.swing.JComboBox(); + jTextField1 = new javax.swing.JTextField(); + jButton1 = new javax.swing.JButton(); + jButton2 = new javax.swing.JButton(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + + jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(ChannelDialog.class, "ChannelDialog.jPanel1.border.title"))); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(ChannelDialog.class, "ChannelDialog.jLabel1.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(ChannelDialog.class, "ChannelDialog.jLabel2.text")); // NOI18N + + jComboBox1.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Loop", "DontLoop", "Cycle" })); + + jTextField1.setText(org.openide.util.NbBundle.getMessage(ChannelDialog.class, "ChannelDialog.jTextField1.text")); // NOI18N + + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); + jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGap(66, 66, 66) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jLabel2) + .addComponent(jLabel1)) + .addGap(18, 18, 18) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jComboBox1, 0, 142, Short.MAX_VALUE) + .addComponent(jTextField1)) + .addContainerGap()) + ); + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1) + .addComponent(jComboBox1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(18, 18, 18) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel2) + .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(0, 16, Short.MAX_VALUE)) + ); + + org.openide.awt.Mnemonics.setLocalizedText(jButton1, org.openide.util.NbBundle.getMessage(ChannelDialog.class, "ChannelDialog.jButton1.text")); // NOI18N + jButton1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton1ActionPerformed(evt); + } + }); + + org.openide.awt.Mnemonics.setLocalizedText(jButton2, org.openide.util.NbBundle.getMessage(ChannelDialog.class, "ChannelDialog.jButton2.text")); // NOI18N + jButton2.setActionCommand(org.openide.util.NbBundle.getMessage(ChannelDialog.class, "ChannelDialog.jButton2.actionCommand")); // NOI18N + jButton2.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton2ActionPerformed(evt); + } + }); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addComponent(jButton2) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jButton1))) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jButton1) + .addComponent(jButton2)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + + pack(); + }// //GEN-END:initComponents + + private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed + jmeAnim.setAnimLoopMode(LoopMode.valueOf(jComboBox1.getSelectedItem().toString())); + float speed = 1.0f; + try{ + speed = Float.parseFloat(jTextField1.getText()); + }catch(NumberFormatException e){ + //wrong format, just setting the speed to 1.0 + } + jmeAnim.setAnimSpeed(speed); + setVisible(false); + }//GEN-LAST:event_jButton1ActionPerformed + + private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed + setVisible(false); + }//GEN-LAST:event_jButton2ActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jButton1; + private javax.swing.JButton jButton2; + private javax.swing.JComboBox jComboBox1; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JPanel jPanel1; + private javax.swing.JTextField jTextField1; + // End of variables declaration//GEN-END:variables +}