Browse Source

NormalViewState appstate and hook up for SceneViewer

rickard 2 years ago
parent
commit
2309588cf2

+ 9 - 0
jme3-core/src/com/jme3/gde/core/scene/SceneApplication.java

@@ -36,6 +36,7 @@ import com.jme3.gde.core.assets.AssetData;
 import com.jme3.gde.core.assets.AssetDataObject;
 import com.jme3.gde.core.assets.AssetDataObject;
 import com.jme3.gde.core.scene.controller.AbstractCameraController;
 import com.jme3.gde.core.scene.controller.AbstractCameraController;
 import com.jme3.gde.core.scene.processors.WireProcessor;
 import com.jme3.gde.core.scene.processors.WireProcessor;
+import com.jme3.gde.core.scene.state.NormalViewState;
 import com.jme3.gde.core.sceneexplorer.nodes.NodeUtility;
 import com.jme3.gde.core.sceneexplorer.nodes.NodeUtility;
 import com.jme3.gde.core.sceneviewer.SceneViewerTopComponent;
 import com.jme3.gde.core.sceneviewer.SceneViewerTopComponent;
 import com.jme3.gde.core.undoredo.SceneUndoRedoManager;
 import com.jme3.gde.core.undoredo.SceneUndoRedoManager;
@@ -769,4 +770,12 @@ public class SceneApplication extends LegacyApplication implements LookupProvide
     public boolean isAwt() {
     public boolean isAwt() {
         return java.awt.EventQueue.isDispatchThread();
         return java.awt.EventQueue.isDispatchThread();
     }
     }
+
+    public void enableNormalView(boolean selected) {
+        if(selected) {
+            stateManager.attach(new NormalViewState());
+        } else if(stateManager.getState(NormalViewState.class) != null) {
+            stateManager.detach(stateManager.getState(NormalViewState.class));
+        }
+    }
 }
 }

+ 64 - 0
jme3-core/src/com/jme3/gde/core/scene/state/NormalViewState.java

@@ -0,0 +1,64 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.jme3.gde.core.scene.state;
+
+import com.jme3.app.Application;
+import com.jme3.app.state.BaseAppState;
+import com.jme3.gde.core.scene.SceneApplication;
+import com.jme3.material.Material;
+import com.jme3.scene.Geometry;
+import com.jme3.scene.Node;
+import com.jme3.scene.Spatial;
+import com.jme3.util.TangentBinormalGenerator;
+import java.util.ArrayList;
+import java.util.List;
+import jme3tools.optimize.GeometryBatchFactory;
+
+/**
+ * Generates a set of geometries for debugging normals. Does not support moving
+ * or animated meshes. Implementation ref:
+ * https://hub.jmonkeyengine.org/t/debug-graphics-show-normals-as-lines/35058/3
+ *
+ * @author rickard
+ */
+public class NormalViewState extends BaseAppState {
+
+    private final Node debugNode = new Node("Normals debug");
+
+    @Override
+    protected void initialize(Application arg0) {
+    }
+
+    @Override
+    protected void cleanup(Application arg0) {
+    }
+
+    @Override
+    protected void onEnable() {
+        final SceneApplication app = (SceneApplication) getApplication();
+        final List<Geometry> geometries = new ArrayList<>();
+        GeometryBatchFactory.gatherGeoms(app.getRootNode(), geometries);
+        final Material debugMat = app.getAssetManager().loadMaterial("Common/Materials/VertexColor.j3m");
+
+        for (Geometry geometry : geometries) {
+            Geometry debug = new Geometry("Debug normals",
+                    TangentBinormalGenerator.genNormalLines(geometry.getMesh(),
+                            0.2f));
+            debug.setMaterial(debugMat);
+            debug.setCullHint(Spatial.CullHint.Never);
+            debug.setLocalTransform(geometry.getWorldTransform());
+            debugNode.attachChild(debug);
+        }
+        app.getRootNode().attachChild(debugNode);
+    }
+
+    @Override
+    protected void onDisable() {
+        debugNode.removeFromParent();
+        debugNode.detachAllChildren();
+    }
+
+}

+ 22 - 0
jme3-core/src/com/jme3/gde/core/sceneviewer/SceneViewerTopComponent.form

@@ -140,6 +140,28 @@
             <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="enablePBRSkyActionPerformed"/>
             <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="enablePBRSkyActionPerformed"/>
           </Events>
           </Events>
         </Component>
         </Component>
+        <Component class="javax.swing.JToggleButton" name="enableNormalView">
+          <Properties>
+            <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
+              <Connection code="IconList.chimpMad" type="code"/>
+            </Property>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="com/jme3/gde/core/sceneviewer/Bundle.properties" key="SceneViewerTopComponent.enableNormalView.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+            <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="com/jme3/gde/core/sceneviewer/Bundle.properties" key="SceneViewerTopComponent.enableNormalView.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+            <Property name="focusable" type="boolean" value="false"/>
+            <Property name="horizontalTextPosition" type="int" value="0"/>
+            <Property name="selectedIcon" type="javax.swing.Icon" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
+              <Connection code="IconList.chimpMad" type="code"/>
+            </Property>
+            <Property name="verticalTextPosition" type="int" value="3"/>
+          </Properties>
+          <Events>
+            <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="enableNormalViewActionPerformed"/>
+          </Events>
+        </Component>
         <Container class="javax.swing.JPanel" name="jPanel1">
         <Container class="javax.swing.JPanel" name="jPanel1">
 
 
           <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/>
           <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/>

+ 20 - 0
jme3-core/src/com/jme3/gde/core/sceneviewer/SceneViewerTopComponent.java

@@ -171,6 +171,7 @@ public final class SceneViewerTopComponent extends TopComponent {
         enableWireframe = new javax.swing.JToggleButton();
         enableWireframe = new javax.swing.JToggleButton();
         enablePBREnv = new javax.swing.JToggleButton();
         enablePBREnv = new javax.swing.JToggleButton();
         enablePBRSky = new javax.swing.JToggleButton();
         enablePBRSky = new javax.swing.JToggleButton();
+        enableNormalView = new javax.swing.JToggleButton();
         jPanel1 = new javax.swing.JPanel();
         jPanel1 = new javax.swing.JPanel();
         enableStats = new javax.swing.JToggleButton();
         enableStats = new javax.swing.JToggleButton();
         oGLPanel = new javax.swing.JPanel();
         oGLPanel = new javax.swing.JPanel();
@@ -249,6 +250,20 @@ public final class SceneViewerTopComponent extends TopComponent {
             }
             }
         });
         });
         jToolBar1.add(enablePBRSky);
         jToolBar1.add(enablePBRSky);
+
+        enableNormalView.setIcon(IconList.chimpMad);
+        org.openide.awt.Mnemonics.setLocalizedText(enableNormalView, org.openide.util.NbBundle.getMessage(SceneViewerTopComponent.class, "SceneViewerTopComponent.enableNormalView.text")); // NOI18N
+        enableNormalView.setToolTipText(org.openide.util.NbBundle.getMessage(SceneViewerTopComponent.class, "SceneViewerTopComponent.enableNormalView.toolTipText")); // NOI18N
+        enableNormalView.setFocusable(false);
+        enableNormalView.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
+        enableNormalView.setSelectedIcon(IconList.chimpMad);
+        enableNormalView.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
+        enableNormalView.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                enableNormalViewActionPerformed(evt);
+            }
+        });
+        jToolBar1.add(enableNormalView);
         jToolBar1.add(jPanel1);
         jToolBar1.add(jPanel1);
 
 
         enableStats.setIcon(IconList.info);
         enableStats.setIcon(IconList.info);
@@ -295,8 +310,13 @@ public final class SceneViewerTopComponent extends TopComponent {
         app.enablePBRSkybox(enablePBRSky.isSelected());
         app.enablePBRSkybox(enablePBRSky.isSelected());
     }//GEN-LAST:event_enablePBRSkyActionPerformed
     }//GEN-LAST:event_enablePBRSkyActionPerformed
 
 
+    private void enableNormalViewActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_enableNormalViewActionPerformed
+        app.enableNormalView(enableNormalView.isSelected());
+    }//GEN-LAST:event_enableNormalViewActionPerformed
+
     // Variables declaration - do not modify//GEN-BEGIN:variables
     // Variables declaration - do not modify//GEN-BEGIN:variables
     private javax.swing.JToggleButton enableCamLight;
     private javax.swing.JToggleButton enableCamLight;
+    private javax.swing.JToggleButton enableNormalView;
     private javax.swing.JToggleButton enablePBREnv;
     private javax.swing.JToggleButton enablePBREnv;
     private javax.swing.JToggleButton enablePBRSky;
     private javax.swing.JToggleButton enablePBRSky;
     private javax.swing.JToggleButton enableStats;
     private javax.swing.JToggleButton enableStats;