diff --git a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/SceneComposerTopComponent.form b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/SceneComposerTopComponent.form
index 97a943001..9bf5530f8 100644
--- a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/SceneComposerTopComponent.form
+++ b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/SceneComposerTopComponent.form
@@ -33,7 +33,7 @@
-
+
@@ -169,11 +169,13 @@
-
+
+
+
@@ -407,12 +409,12 @@
-
+
-
+
@@ -445,9 +447,9 @@
-
+
-
+
@@ -466,7 +468,7 @@
-
+
diff --git a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/SceneComposerTopComponent.java b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/SceneComposerTopComponent.java
index ee926dbcb..e8c8b9140 100644
--- a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/SceneComposerTopComponent.java
+++ b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/SceneComposerTopComponent.java
@@ -19,6 +19,7 @@ import com.jme3.gde.core.sceneexplorer.nodes.JmeSpatial;
import com.jme3.gde.core.sceneexplorer.nodes.NodeUtility;
import com.jme3.gde.core.sceneviewer.SceneViewerTopComponent;
import com.jme3.gde.scenecomposer.tools.MoveTool;
+import com.jme3.gde.scenecomposer.tools.RotateTool;
import com.jme3.gde.scenecomposer.tools.ScaleTool;
import com.jme3.gde.scenecomposer.tools.SelectTool;
import com.jme3.math.Vector3f;
@@ -194,10 +195,14 @@ public final class SceneComposerTopComponent extends TopComponent implements Sce
rotateButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/jme3/gde/scenecomposer/icon_arrow_rotate_clockwise.png"))); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(rotateButton, org.openide.util.NbBundle.getMessage(SceneComposerTopComponent.class, "SceneComposerTopComponent.rotateButton.text")); // NOI18N
rotateButton.setToolTipText(org.openide.util.NbBundle.getMessage(SceneComposerTopComponent.class, "SceneComposerTopComponent.rotateButton.toolTipText")); // NOI18N
- rotateButton.setEnabled(false);
rotateButton.setFocusable(false);
rotateButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
rotateButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
+ rotateButton.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ rotateButtonActionPerformed(evt);
+ }
+ });
jToolBar1.add(rotateButton);
spatialModButtonGroup.add(scaleButton);
@@ -309,7 +314,7 @@ public final class SceneComposerTopComponent extends TopComponent implements Sce
jToolBar1.add(camToCursorSelectionButton);
jToolBar1.add(jSeparator1);
- jLabel6.setFont(new java.awt.Font("Lucida Grande", 0, 10)); // NOI18N
+ jLabel6.setFont(new java.awt.Font("Lucida Grande", 0, 10));
org.openide.awt.Mnemonics.setLocalizedText(jLabel6, org.openide.util.NbBundle.getMessage(SceneComposerTopComponent.class, "SceneComposerTopComponent.jLabel6.text")); // NOI18N
jToolBar1.add(jLabel6);
@@ -345,11 +350,11 @@ public final class SceneComposerTopComponent extends TopComponent implements Sce
jPanel3.setLayout(jPanel3Layout);
jPanel3Layout.setHorizontalGroup(
jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGap(0, 131, Short.MAX_VALUE)
+ .addGap(0, 272, Short.MAX_VALUE)
);
jPanel3Layout.setVerticalGroup(
jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGap(0, 21, Short.MAX_VALUE)
+ .addGap(0, 23, Short.MAX_VALUE)
);
jToolBar1.add(jPanel3);
@@ -429,8 +434,8 @@ public final class SceneComposerTopComponent extends TopComponent implements Sce
.addGap(10, 10, 10)
.addComponent(jLabel5)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(emitButton, javax.swing.GroupLayout.DEFAULT_SIZE, 267, Short.MAX_VALUE))
- .addComponent(jSeparator6, javax.swing.GroupLayout.DEFAULT_SIZE, 337, Short.MAX_VALUE))
+ .addComponent(emitButton, javax.swing.GroupLayout.DEFAULT_SIZE, 302, Short.MAX_VALUE))
+ .addComponent(jSeparator6, javax.swing.GroupLayout.DEFAULT_SIZE, 357, Short.MAX_VALUE))
.addContainerGap())
);
jPanel4Layout.setVerticalGroup(
@@ -445,7 +450,7 @@ public final class SceneComposerTopComponent extends TopComponent implements Sce
.addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel5)
.addComponent(emitButton))
- .addContainerGap(39, Short.MAX_VALUE))
+ .addContainerGap(40, Short.MAX_VALUE))
);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
@@ -456,7 +461,7 @@ public final class SceneComposerTopComponent extends TopComponent implements Sce
.addComponent(jPanel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(sceneInfoPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
- .addComponent(jToolBar1, javax.swing.GroupLayout.DEFAULT_SIZE, 766, Short.MAX_VALUE)
+ .addComponent(jToolBar1, javax.swing.GroupLayout.DEFAULT_SIZE, 772, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@@ -561,6 +566,12 @@ private void scaleButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-F
private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton3ActionPerformed
SceneApplication.getApplication().setPhysicsEnabled(false);
}//GEN-LAST:event_jButton3ActionPerformed
+
+ private void rotateButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rotateButtonActionPerformed
+ RotateTool tool = new RotateTool();
+ toolController.showEditTool(tool);
+ }//GEN-LAST:event_rotateButtonActionPerformed
+
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton camToCursorSelectionButton;
private javax.swing.JButton createPhysicsMeshButton;
diff --git a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/RotateTool.java b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/RotateTool.java
new file mode 100644
index 000000000..d3c81901a
--- /dev/null
+++ b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/RotateTool.java
@@ -0,0 +1,162 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.jme3.gde.scenecomposer.tools;
+
+import com.jme3.asset.AssetManager;
+import com.jme3.gde.core.sceneexplorer.nodes.JmeNode;
+import com.jme3.gde.core.undoredo.AbstractUndoableSceneEdit;
+import com.jme3.gde.scenecomposer.SceneComposerToolController;
+import com.jme3.gde.scenecomposer.SceneEditTool;
+import com.jme3.math.Quaternion;
+import com.jme3.math.Vector2f;
+import com.jme3.math.Vector3f;
+import com.jme3.scene.Node;
+import com.jme3.scene.Spatial;
+import org.openide.loaders.DataObject;
+
+/**
+ *
+ * @author kbender
+ */
+public class RotateTool extends SceneEditTool {
+
+ private Vector3f pickedPlane;
+ private Vector2f lastScreenCoord;
+ private Quaternion startRotate;
+ private Quaternion lastRotate;
+ private boolean wasDragging = false;
+
+ public RotateTool() {
+ axisPickType = AxisMarkerPickType.axisAndPlane;
+ setOverrideCameraControl(true);
+ }
+
+ @Override
+ public void activate(AssetManager manager, Node toolNode, Node onTopToolNode, Spatial selectedSpatial, SceneComposerToolController toolController) {
+ super.activate(manager, toolNode, onTopToolNode, selectedSpatial, toolController);
+ displayPlanes();
+ }
+
+ @Override
+ public void actionPrimary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject dataObject) {
+ if (!pressed) {
+ setDefaultAxisMarkerColors();
+ pickedPlane = null; // mouse released, reset selection
+ lastScreenCoord = null;
+ if (wasDragging) {
+ actionPerformed(new ScaleUndo(toolController.getSelectedSpatial(), startRotate, lastRotate));
+ wasDragging = false;
+ }
+ }
+ }
+
+ @Override
+ public void actionSecondary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject dataObject) {
+
+ }
+
+ @Override
+ public void mouseMoved(Vector2f screenCoord) {
+ if (pickedPlane == null) {
+ highlightAxisMarker(camera, screenCoord, axisPickType);
+ }
+ else {
+ pickedPlane = null;
+ }
+ }
+
+ @Override
+ public void draggedPrimary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject currentDataObject) {
+
+ if (!pressed) {
+ setDefaultAxisMarkerColors();
+ pickedPlane = null; // mouse released, reset selection
+ lastScreenCoord = null;
+
+ if (wasDragging) {
+ actionPerformed(new ScaleUndo(toolController.getSelectedSpatial(), startRotate, lastRotate));
+ wasDragging = false;
+ }
+ return;
+ }
+
+ if (toolController.getSelectedSpatial() == null)
+ {
+ return;
+ }
+
+ if (pickedPlane == null)
+ {
+ pickedPlane = pickAxisMarker(camera, screenCoord, axisPickType);
+ if (pickedPlane == null)
+ {
+ return;
+ }
+ startRotate = toolController.getSelectedSpatial().getLocalRotation().clone();
+ }
+
+ if (lastScreenCoord == null) {
+ lastScreenCoord = screenCoord;
+ } else {
+ Quaternion rotate = new Quaternion();
+ float diff;
+ if(pickedPlane.equals(QUAD_XY))
+ {
+ diff = -(screenCoord.x-lastScreenCoord.x);
+ diff *= 0.03f;
+ rotate = rotate.fromAngleAxis(diff, Vector3f.UNIT_Z);
+ }
+ else if(pickedPlane.equals(QUAD_YZ))
+ {
+ diff = -(screenCoord.y-lastScreenCoord.y);
+ diff *= 0.03f;
+ rotate = rotate.fromAngleAxis(diff, Vector3f.UNIT_X);
+ }
+ else if(pickedPlane.equals(QUAD_XZ))
+ {
+ diff = screenCoord.x-lastScreenCoord.x;
+ diff *= 0.03f;
+ rotate = rotate.fromAngleAxis(diff, Vector3f.UNIT_Y);
+ }
+
+ lastScreenCoord = screenCoord;
+ Quaternion rotation = toolController.getSelectedSpatial().getLocalRotation().mult(rotate);
+ lastRotate = rotation;
+ toolController.getSelectedSpatial().setLocalRotation(rotation);
+ updateToolsTransformation();
+ }
+
+ wasDragging = true;
+ }
+
+ @Override
+ public void draggedSecondary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject currentDataObject) {
+
+ }
+
+ private class ScaleUndo extends AbstractUndoableSceneEdit {
+
+ private Spatial spatial;
+ private Quaternion before,after;
+
+ ScaleUndo(Spatial spatial, Quaternion before, Quaternion after) {
+ this.spatial = spatial;
+ this.before = before;
+ this.after = after;
+ }
+
+ @Override
+ public void sceneUndo() {
+ spatial.setLocalRotation(before);
+ toolController.selectedSpatialTransformed();
+ }
+
+ @Override
+ public void sceneRedo() {
+ spatial.setLocalRotation(after);
+ toolController.selectedSpatialTransformed();
+ }
+ }
+}