Browse Source

Add camera fov slider to SceneComposer window

rickard 2 years ago
parent
commit
fc27ec199d

+ 8 - 3
jme3-scenecomposer/src/com/jme3/gde/scenecomposer/Bundle.properties

@@ -14,8 +14,6 @@ SceneComposerTopComponent.jLabel1.text=
 SceneComposerTopComponent.jLabel2.text=
 SceneComposerTopComponent.jLabel2.text=
 SceneComposerTopComponent.sceneInfoLabel3.text=jLabel3
 SceneComposerTopComponent.sceneInfoLabel3.text=jLabel3
 SceneComposerTopComponent.scenInfoLabel4.text=jLabel3
 SceneComposerTopComponent.scenInfoLabel4.text=jLabel3
-SceneComposerTopComponent.sceneInfoLabel1.text=..
-SceneComposerTopComponent.sceneInfoLabel2.text=..
 SceneComposerTopComponent.moveToCursorButton.toolTipText=move selected item to cursor
 SceneComposerTopComponent.moveToCursorButton.toolTipText=move selected item to cursor
 SceneComposerTopComponent.moveToCursorButton.text=
 SceneComposerTopComponent.moveToCursorButton.text=
 SceneComposerTopComponent.showSelectionToggleButton.toolTipText=display selection
 SceneComposerTopComponent.showSelectionToggleButton.toolTipText=display selection
@@ -46,7 +44,6 @@ SceneComposerTopComponent.selectButton.toolTipText=Select
 SceneComposerTopComponent.moveButton.toolTipText=Move
 SceneComposerTopComponent.moveButton.toolTipText=Move
 SceneComposerTopComponent.rotateButton.toolTipText=Rotate
 SceneComposerTopComponent.rotateButton.toolTipText=Rotate
 SceneComposerTopComponent.scaleButton.toolTipText=Scale
 SceneComposerTopComponent.scaleButton.toolTipText=Scale
-SceneComposerTopComponent.sceneInfoPanel.border.title=no scene loaded
 SceneComposerTopComponent.jLabel5.text=Effects :
 SceneComposerTopComponent.jLabel5.text=Effects :
 SceneComposerTopComponent.emitButton.toolTipText=Emit all particles of all particle emitters from the selected Node
 SceneComposerTopComponent.emitButton.toolTipText=Emit all particles of all particle emitters from the selected Node
 SceneComposerTopComponent.emitButton.text=Emit All
 SceneComposerTopComponent.emitButton.text=Emit All
@@ -73,3 +70,11 @@ SceneComposerTopComponent.jLabel11.text=(NaN, NaN, NaN)
 SceneComposerTopComponent.jLabel12.text=(NaN, NaN, NaN)
 SceneComposerTopComponent.jLabel12.text=(NaN, NaN, NaN)
 SceneComposerTopComponent.cursorPositionLabel.text=(NaN, NaN, NaN)
 SceneComposerTopComponent.cursorPositionLabel.text=(NaN, NaN, NaN)
 SceneComposerTopComponent.cursorPositionHeader.text=Cursor Position:
 SceneComposerTopComponent.cursorPositionHeader.text=Cursor Position:
+SceneComposerTopComponent.cameraPanel.AccessibleContext.accessibleName=Camera
+SceneComposerTopComponent.cameraPanel.border.title=Camera
+SceneComposerTopComponent.sceneInfoPanel.border.title=No scene loaded
+SceneComposerTopComponent.sceneInfoPanel.AccessibleContext.accessibleName=No scene loaded
+SceneComposerTopComponent.jLabel13.text=Field of View
+SceneComposerTopComponent.sceneInfoLabel.text_1=..
+SceneComposerTopComponent.sceneInfoLabel1.text=..
+SceneComposerTopComponent.jSlider1.toolTipText=

+ 128 - 44
jme3-scenecomposer/src/com/jme3/gde/scenecomposer/SceneComposerTopComponent.form

@@ -26,7 +26,10 @@
           <Group type="102" alignment="0" attributes="0">
           <Group type="102" alignment="0" attributes="0">
               <Component id="jPanel4" min="-2" max="-2" attributes="0"/>
               <Component id="jPanel4" min="-2" max="-2" attributes="0"/>
               <EmptySpace max="-2" attributes="0"/>
               <EmptySpace max="-2" attributes="0"/>
-              <Component id="sceneInfoPanel" max="32767" attributes="0"/>
+              <Component id="sceneInfoPanel" min="-2" max="-2" attributes="0"/>
+              <EmptySpace max="-2" attributes="0"/>
+              <Component id="cameraPanel" min="-2" max="-2" attributes="0"/>
+              <EmptySpace max="32767" attributes="0"/>
           </Group>
           </Group>
           <Component id="jToolBar1" alignment="0" max="32767" attributes="0"/>
           <Component id="jToolBar1" alignment="0" max="32767" attributes="0"/>
       </Group>
       </Group>
@@ -37,46 +40,34 @@
               <Component id="jToolBar1" min="-2" pref="25" max="-2" attributes="0"/>
               <Component id="jToolBar1" min="-2" pref="25" max="-2" attributes="0"/>
               <EmptySpace max="-2" attributes="0"/>
               <EmptySpace max="-2" attributes="0"/>
               <Group type="103" groupAlignment="0" attributes="0">
               <Group type="103" groupAlignment="0" attributes="0">
-                  <Component id="sceneInfoPanel" max="32767" attributes="0"/>
+                  <Component id="cameraPanel" max="32767" attributes="0"/>
                   <Component id="jPanel4" alignment="0" max="32767" attributes="0"/>
                   <Component id="jPanel4" alignment="0" max="32767" attributes="0"/>
+                  <Component id="sceneInfoPanel" alignment="1" max="32767" attributes="0"/>
               </Group>
               </Group>
           </Group>
           </Group>
       </Group>
       </Group>
     </DimensionLayout>
     </DimensionLayout>
   </Layout>
   </Layout>
   <SubComponents>
   <SubComponents>
-    <Container class="javax.swing.JPanel" name="sceneInfoPanel">
+    <Container class="javax.swing.JPanel" name="cameraPanel">
       <Properties>
       <Properties>
         <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
         <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
           <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
           <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
             <TitledBorder title="no scene loaded">
             <TitledBorder title="no scene loaded">
-              <ResourceString PropertyName="titleX" bundle="com/jme3/gde/scenecomposer/Bundle.properties" key="SceneComposerTopComponent.sceneInfoPanel.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+              <ResourceString PropertyName="titleX" bundle="com/jme3/gde/scenecomposer/Bundle.properties" key="SceneComposerTopComponent.cameraPanel.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
             </TitledBorder>
             </TitledBorder>
           </Border>
           </Border>
         </Property>
         </Property>
       </Properties>
       </Properties>
+      <AccessibilityProperties>
+        <Property name="AccessibleContext.accessibleName" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="com/jme3/gde/scenecomposer/Bundle.properties" key="SceneComposerTopComponent.cameraPanel.AccessibleContext.accessibleName" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </AccessibilityProperties>
 
 
       <Layout>
       <Layout>
         <DimensionLayout dim="0">
         <DimensionLayout dim="0">
           <Group type="103" groupAlignment="0" attributes="0">
           <Group type="103" groupAlignment="0" attributes="0">
-              <Component id="sceneInfoLabel1" alignment="0" max="32767" attributes="0"/>
-              <Component id="sceneInfoLabel2" alignment="0" max="32767" attributes="0"/>
-              <Group type="102" alignment="0" attributes="0">
-                  <Group type="103" groupAlignment="0" attributes="0">
-                      <Component id="jLabel7" alignment="0" min="-2" max="-2" attributes="0"/>
-                      <Component id="jLabel8" alignment="0" min="-2" max="-2" attributes="0"/>
-                  </Group>
-                  <EmptySpace type="unrelated" max="-2" attributes="0"/>
-                  <Group type="103" groupAlignment="0" attributes="0">
-                      <Component id="jSlider1" max="32767" attributes="0"/>
-                      <Component id="jSlider2" max="32767" attributes="0"/>
-                  </Group>
-                  <EmptySpace max="-2" attributes="0"/>
-                  <Group type="103" groupAlignment="0" max="-2" attributes="0">
-                      <Component id="jSpinner2" max="32767" attributes="0"/>
-                      <Component id="jSpinner1" min="-2" pref="80" max="-2" attributes="0"/>
-                  </Group>
-              </Group>
               <Group type="102" attributes="0">
               <Group type="102" attributes="0">
                   <Group type="103" groupAlignment="0" attributes="0">
                   <Group type="103" groupAlignment="0" attributes="0">
                       <Component id="jLabel9" alignment="0" min="-2" max="-2" attributes="0"/>
                       <Component id="jLabel9" alignment="0" min="-2" max="-2" attributes="0"/>
@@ -89,17 +80,46 @@
                       <Component id="jLabel12" alignment="0" min="-2" max="-2" attributes="0"/>
                       <Component id="jLabel12" alignment="0" min="-2" max="-2" attributes="0"/>
                       <Component id="jLabel11" alignment="0" min="-2" max="-2" attributes="0"/>
                       <Component id="jLabel11" alignment="0" min="-2" max="-2" attributes="0"/>
                   </Group>
                   </Group>
-                  <EmptySpace max="32767" attributes="0"/>
+                  <EmptySpace pref="134" max="32767" attributes="0"/>
+              </Group>
+              <Group type="102" alignment="0" attributes="0">
+                  <Group type="103" groupAlignment="0" attributes="0">
+                      <Component id="jLabel7" alignment="0" min="-2" max="-2" attributes="0"/>
+                      <Component id="jLabel8" alignment="0" min="-2" max="-2" attributes="0"/>
+                      <Component id="jLabel13" alignment="0" min="-2" max="-2" attributes="0"/>
+                  </Group>
+                  <EmptySpace type="unrelated" max="-2" attributes="0"/>
+                  <Group type="103" groupAlignment="0" attributes="0">
+                      <Group type="102" alignment="0" attributes="0">
+                          <Component id="fovSlider" max="32767" attributes="0"/>
+                          <EmptySpace max="-2" attributes="0"/>
+                          <Component id="fovSpinner" min="-2" pref="80" max="-2" attributes="0"/>
+                      </Group>
+                      <Group type="102" alignment="0" attributes="0">
+                          <Group type="103" groupAlignment="0" attributes="0">
+                              <Component id="jSlider1" max="32767" attributes="0"/>
+                              <Component id="jSlider2" max="32767" attributes="0"/>
+                          </Group>
+                          <EmptySpace max="-2" attributes="0"/>
+                          <Group type="103" groupAlignment="0" max="-2" attributes="0">
+                              <Component id="jSpinner2" max="32767" attributes="0"/>
+                              <Component id="jSpinner1" min="-2" pref="80" max="-2" attributes="0"/>
+                          </Group>
+                      </Group>
+                  </Group>
               </Group>
               </Group>
           </Group>
           </Group>
         </DimensionLayout>
         </DimensionLayout>
         <DimensionLayout dim="1">
         <DimensionLayout dim="1">
           <Group type="103" groupAlignment="0" attributes="0">
           <Group type="103" groupAlignment="0" attributes="0">
               <Group type="102" alignment="0" attributes="0">
               <Group type="102" alignment="0" attributes="0">
-                  <Component id="sceneInfoLabel1" min="-2" max="-2" attributes="0"/>
+                  <EmptySpace min="-2" pref="30" max="-2" attributes="0"/>
+                  <Group type="103" groupAlignment="1" attributes="0">
+                      <Component id="fovSlider" alignment="1" min="-2" max="-2" attributes="0"/>
+                      <Component id="jLabel13" alignment="1" min="-2" max="-2" attributes="0"/>
+                      <Component id="fovSpinner" alignment="1" min="-2" max="-2" attributes="0"/>
+                  </Group>
                   <EmptySpace max="-2" attributes="0"/>
                   <EmptySpace max="-2" attributes="0"/>
-                  <Component id="sceneInfoLabel2" min="-2" max="-2" attributes="0"/>
-                  <EmptySpace min="-2" pref="5" max="-2" attributes="0"/>
                   <Group type="103" groupAlignment="1" attributes="0">
                   <Group type="103" groupAlignment="1" attributes="0">
                       <Component id="jSlider1" min="-2" max="-2" attributes="0"/>
                       <Component id="jSlider1" min="-2" max="-2" attributes="0"/>
                       <Component id="jLabel7" min="-2" max="-2" attributes="0"/>
                       <Component id="jLabel7" min="-2" max="-2" attributes="0"/>
@@ -136,24 +156,13 @@
         </DimensionLayout>
         </DimensionLayout>
       </Layout>
       </Layout>
       <SubComponents>
       <SubComponents>
-        <Component class="javax.swing.JLabel" name="sceneInfoLabel1">
-          <Properties>
-            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
-              <ResourceString bundle="com/jme3/gde/scenecomposer/Bundle.properties" key="SceneComposerTopComponent.sceneInfoLabel1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
-            </Property>
-          </Properties>
-        </Component>
-        <Component class="javax.swing.JLabel" name="sceneInfoLabel2">
-          <Properties>
-            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
-              <ResourceString bundle="com/jme3/gde/scenecomposer/Bundle.properties" key="SceneComposerTopComponent.sceneInfoLabel2.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
-            </Property>
-          </Properties>
-        </Component>
         <Component class="javax.swing.JSlider" name="jSlider1">
         <Component class="javax.swing.JSlider" name="jSlider1">
           <Properties>
           <Properties>
             <Property name="maximum" type="int" value="2000"/>
             <Property name="maximum" type="int" value="2000"/>
             <Property name="minimum" type="int" value="100"/>
             <Property name="minimum" type="int" value="100"/>
+            <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="com/jme3/gde/scenecomposer/Bundle.properties" key="SceneComposerTopComponent.jSlider1.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
             <Property name="value" type="int" value="1000"/>
             <Property name="value" type="int" value="1000"/>
           </Properties>
           </Properties>
           <Events>
           <Events>
@@ -246,11 +255,37 @@
             </Property>
             </Property>
           </Properties>
           </Properties>
         </Component>
         </Component>
+        <Component class="javax.swing.JLabel" name="jLabel13">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="com/jme3/gde/scenecomposer/Bundle.properties" key="SceneComposerTopComponent.jLabel13.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JSlider" name="fovSlider">
+          <Properties>
+            <Property name="maximum" type="int" value="360"/>
+            <Property name="minimum" type="int" value="1"/>
+            <Property name="value" type="int" value="45"/>
+          </Properties>
+          <Events>
+            <EventHandler event="stateChanged" listener="javax.swing.event.ChangeListener" parameters="javax.swing.event.ChangeEvent" handler="fovSliderStateChanged"/>
+          </Events>
+        </Component>
+        <Component class="javax.swing.JSpinner" name="fovSpinner">
+          <Properties>
+            <Property name="model" type="javax.swing.SpinnerModel" editor="org.netbeans.modules.form.editors2.SpinnerModelEditor">
+              <SpinnerModel initial="45" numberType="java.lang.Integer" stepSize="1" type="number"/>
+            </Property>
+          </Properties>
+          <Events>
+            <EventHandler event="stateChanged" listener="javax.swing.event.ChangeListener" parameters="javax.swing.event.ChangeEvent" handler="fovSpinnerStateChanged"/>
+          </Events>
+        </Component>
       </SubComponents>
       </SubComponents>
     </Container>
     </Container>
     <Container class="javax.swing.JToolBar" name="jToolBar1">
     <Container class="javax.swing.JToolBar" name="jToolBar1">
       <Properties>
       <Properties>
-        <Property name="floatable" type="boolean" value="false"/>
         <Property name="rollover" type="boolean" value="true"/>
         <Property name="rollover" type="boolean" value="true"/>
       </Properties>
       </Properties>
 
 
@@ -598,7 +633,7 @@
           <Layout>
           <Layout>
             <DimensionLayout dim="0">
             <DimensionLayout dim="0">
               <Group type="103" groupAlignment="0" attributes="0">
               <Group type="103" groupAlignment="0" attributes="0">
-                  <EmptySpace min="0" pref="133" max="32767" attributes="0"/>
+                  <EmptySpace min="0" pref="571" max="32767" attributes="0"/>
               </Group>
               </Group>
             </DimensionLayout>
             </DimensionLayout>
             <DimensionLayout dim="1">
             <DimensionLayout dim="1">
@@ -683,7 +718,6 @@
       <SubComponents>
       <SubComponents>
         <Container class="javax.swing.JToolBar" name="jToolBar2">
         <Container class="javax.swing.JToolBar" name="jToolBar2">
           <Properties>
           <Properties>
-            <Property name="floatable" type="boolean" value="false"/>
             <Property name="rollover" type="boolean" value="true"/>
             <Property name="rollover" type="boolean" value="true"/>
           </Properties>
           </Properties>
 
 
@@ -727,7 +761,6 @@
         </Container>
         </Container>
         <Container class="javax.swing.JToolBar" name="jToolBar3">
         <Container class="javax.swing.JToolBar" name="jToolBar3">
           <Properties>
           <Properties>
-            <Property name="floatable" type="boolean" value="false"/>
             <Property name="rollover" type="boolean" value="true"/>
             <Property name="rollover" type="boolean" value="true"/>
           </Properties>
           </Properties>
 
 
@@ -837,5 +870,56 @@
         </Component>
         </Component>
       </SubComponents>
       </SubComponents>
     </Container>
     </Container>
+    <Container class="javax.swing.JPanel" name="sceneInfoPanel">
+      <Properties>
+        <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
+          <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
+            <TitledBorder title="no scene loaded">
+              <ResourceString PropertyName="titleX" bundle="com/jme3/gde/scenecomposer/Bundle.properties" key="SceneComposerTopComponent.sceneInfoPanel.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </TitledBorder>
+          </Border>
+        </Property>
+      </Properties>
+      <AccessibilityProperties>
+        <Property name="AccessibleContext.accessibleName" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="com/jme3/gde/scenecomposer/Bundle.properties" key="SceneComposerTopComponent.sceneInfoPanel.AccessibleContext.accessibleName" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </AccessibilityProperties>
+
+      <Layout>
+        <DimensionLayout dim="0">
+          <Group type="103" groupAlignment="0" attributes="0">
+              <Component id="sceneInfoLabel" alignment="0" pref="391" max="32767" attributes="0"/>
+              <Component id="sceneInfoLabel1" alignment="0" max="32767" attributes="0"/>
+          </Group>
+        </DimensionLayout>
+        <DimensionLayout dim="1">
+          <Group type="103" groupAlignment="0" attributes="0">
+              <Group type="102" alignment="0" attributes="0">
+                  <Component id="sceneInfoLabel" min="-2" max="-2" attributes="0"/>
+                  <EmptySpace max="-2" attributes="0"/>
+                  <Component id="sceneInfoLabel1" min="-2" max="-2" attributes="0"/>
+                  <EmptySpace max="32767" attributes="0"/>
+              </Group>
+          </Group>
+        </DimensionLayout>
+      </Layout>
+      <SubComponents>
+        <Component class="javax.swing.JLabel" name="sceneInfoLabel">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="com/jme3/gde/scenecomposer/Bundle.properties" key="SceneComposerTopComponent.sceneInfoLabel.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JLabel" name="sceneInfoLabel1">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="com/jme3/gde/scenecomposer/Bundle.properties" key="SceneComposerTopComponent.sceneInfoLabel1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+        </Component>
+      </SubComponents>
+    </Container>
   </SubComponents>
   </SubComponents>
 </Form>
 </Form>

+ 144 - 63
jme3-scenecomposer/src/com/jme3/gde/scenecomposer/SceneComposerTopComponent.java

@@ -102,9 +102,7 @@ public final class SceneComposerTopComponent extends TopComponent implements
     private void initComponents() {
     private void initComponents() {
 
 
         spatialModButtonGroup = new ButtonGroup();
         spatialModButtonGroup = new ButtonGroup();
-        sceneInfoPanel = new javax.swing.JPanel();
-        sceneInfoLabel1 = new javax.swing.JLabel();
-        sceneInfoLabel2 = new javax.swing.JLabel();
+        cameraPanel = new javax.swing.JPanel();
         jSlider1 = new javax.swing.JSlider();
         jSlider1 = new javax.swing.JSlider();
         jSlider2 = new javax.swing.JSlider();
         jSlider2 = new javax.swing.JSlider();
         jSpinner1 = new javax.swing.JSpinner();
         jSpinner1 = new javax.swing.JSpinner();
@@ -117,6 +115,9 @@ public final class SceneComposerTopComponent extends TopComponent implements
         jLabel12 = new javax.swing.JLabel();
         jLabel12 = new javax.swing.JLabel();
         cursorPositionHeader = new javax.swing.JLabel();
         cursorPositionHeader = new javax.swing.JLabel();
         cursorPositionLabel = new javax.swing.JLabel();
         cursorPositionLabel = new javax.swing.JLabel();
+        jLabel13 = new javax.swing.JLabel();
+        fovSlider = new javax.swing.JSlider();
+        fovSpinner = new javax.swing.JSpinner();
         jToolBar1 = new javax.swing.JToolBar();
         jToolBar1 = new javax.swing.JToolBar();
         transformationTypeComboBox = new javax.swing.JComboBox<>();
         transformationTypeComboBox = new javax.swing.JComboBox<>();
         jSeparator9 = new javax.swing.JToolBar.Separator();
         jSeparator9 = new javax.swing.JToolBar.Separator();
@@ -162,15 +163,15 @@ public final class SceneComposerTopComponent extends TopComponent implements
         jLabel6 = new javax.swing.JLabel();
         jLabel6 = new javax.swing.JLabel();
         jButton2 = new javax.swing.JButton();
         jButton2 = new javax.swing.JButton();
         jButton3 = new javax.swing.JButton();
         jButton3 = new javax.swing.JButton();
+        sceneInfoPanel = new javax.swing.JPanel();
+        sceneInfoLabel = new javax.swing.JLabel();
+        sceneInfoLabel1 = new javax.swing.JLabel();
 
 
-        sceneInfoPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(SceneComposerTopComponent.class, "SceneComposerTopComponent.sceneInfoPanel.border.title"))); // NOI18N
-
-        org.openide.awt.Mnemonics.setLocalizedText(sceneInfoLabel1, org.openide.util.NbBundle.getMessage(SceneComposerTopComponent.class, "SceneComposerTopComponent.sceneInfoLabel1.text")); // NOI18N
-
-        org.openide.awt.Mnemonics.setLocalizedText(sceneInfoLabel2, org.openide.util.NbBundle.getMessage(SceneComposerTopComponent.class, "SceneComposerTopComponent.sceneInfoLabel2.text")); // NOI18N
+        cameraPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(SceneComposerTopComponent.class, "SceneComposerTopComponent.cameraPanel.border.title"))); // NOI18N
 
 
         jSlider1.setMaximum(2000);
         jSlider1.setMaximum(2000);
         jSlider1.setMinimum(100);
         jSlider1.setMinimum(100);
+        jSlider1.setToolTipText(org.openide.util.NbBundle.getMessage(SceneComposerTopComponent.class, "SceneComposerTopComponent.jSlider1.toolTipText")); // NOI18N
         jSlider1.setValue(1000);
         jSlider1.setValue(1000);
         jSlider1.addChangeListener(new javax.swing.event.ChangeListener() {
         jSlider1.addChangeListener(new javax.swing.event.ChangeListener() {
             public void stateChanged(javax.swing.event.ChangeEvent evt) {
             public void stateChanged(javax.swing.event.ChangeEvent evt) {
@@ -217,70 +218,94 @@ public final class SceneComposerTopComponent extends TopComponent implements
 
 
         org.openide.awt.Mnemonics.setLocalizedText(cursorPositionLabel, org.openide.util.NbBundle.getMessage(SceneComposerTopComponent.class, "SceneComposerTopComponent.cursorPositionLabel.text")); // NOI18N
         org.openide.awt.Mnemonics.setLocalizedText(cursorPositionLabel, org.openide.util.NbBundle.getMessage(SceneComposerTopComponent.class, "SceneComposerTopComponent.cursorPositionLabel.text")); // NOI18N
 
 
-        javax.swing.GroupLayout sceneInfoPanelLayout = new javax.swing.GroupLayout(sceneInfoPanel);
-        sceneInfoPanel.setLayout(sceneInfoPanelLayout);
-        sceneInfoPanelLayout.setHorizontalGroup(
-            sceneInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-            .addComponent(sceneInfoLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-            .addComponent(sceneInfoLabel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-            .addGroup(sceneInfoPanelLayout.createSequentialGroup()
-                .addGroup(sceneInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-                    .addComponent(jLabel7)
-                    .addComponent(jLabel8))
-                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
-                .addGroup(sceneInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-                    .addComponent(jSlider1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-                    .addComponent(jSlider2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
-                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
-                .addGroup(sceneInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
-                    .addComponent(jSpinner2)
-                    .addComponent(jSpinner1, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)))
-            .addGroup(sceneInfoPanelLayout.createSequentialGroup()
-                .addGroup(sceneInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+        org.openide.awt.Mnemonics.setLocalizedText(jLabel13, org.openide.util.NbBundle.getMessage(SceneComposerTopComponent.class, "SceneComposerTopComponent.jLabel13.text")); // NOI18N
+
+        fovSlider.setMaximum(360);
+        fovSlider.setMinimum(1);
+        fovSlider.setValue(45);
+        fovSlider.addChangeListener(new javax.swing.event.ChangeListener() {
+            public void stateChanged(javax.swing.event.ChangeEvent evt) {
+                fovSliderStateChanged(evt);
+            }
+        });
+
+        fovSpinner.setModel(new javax.swing.SpinnerNumberModel(45, null, null, 1));
+        fovSpinner.addChangeListener(new javax.swing.event.ChangeListener() {
+            public void stateChanged(javax.swing.event.ChangeEvent evt) {
+                fovSpinnerStateChanged(evt);
+            }
+        });
+
+        javax.swing.GroupLayout cameraPanelLayout = new javax.swing.GroupLayout(cameraPanel);
+        cameraPanel.setLayout(cameraPanelLayout);
+        cameraPanelLayout.setHorizontalGroup(
+            cameraPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(cameraPanelLayout.createSequentialGroup()
+                .addGroup(cameraPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                     .addComponent(jLabel9)
                     .addComponent(jLabel9)
                     .addComponent(jLabel10)
                     .addComponent(jLabel10)
                     .addComponent(cursorPositionHeader))
                     .addComponent(cursorPositionHeader))
                 .addGap(34, 34, 34)
                 .addGap(34, 34, 34)
-                .addGroup(sceneInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                .addGroup(cameraPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                     .addComponent(cursorPositionLabel)
                     .addComponent(cursorPositionLabel)
                     .addComponent(jLabel12)
                     .addComponent(jLabel12)
                     .addComponent(jLabel11))
                     .addComponent(jLabel11))
-                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+                .addContainerGap(134, Short.MAX_VALUE))
+            .addGroup(cameraPanelLayout.createSequentialGroup()
+                .addGroup(cameraPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addComponent(jLabel7)
+                    .addComponent(jLabel8)
+                    .addComponent(jLabel13))
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                .addGroup(cameraPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addGroup(cameraPanelLayout.createSequentialGroup()
+                        .addComponent(fovSlider, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                        .addComponent(fovSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE))
+                    .addGroup(cameraPanelLayout.createSequentialGroup()
+                        .addGroup(cameraPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                            .addComponent(jSlider1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                            .addComponent(jSlider2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                        .addGroup(cameraPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+                            .addComponent(jSpinner2)
+                            .addComponent(jSpinner1, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)))))
         );
         );
-        sceneInfoPanelLayout.setVerticalGroup(
-            sceneInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-            .addGroup(sceneInfoPanelLayout.createSequentialGroup()
-                .addComponent(sceneInfoLabel1)
+        cameraPanelLayout.setVerticalGroup(
+            cameraPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(cameraPanelLayout.createSequentialGroup()
+                .addGap(30, 30, 30)
+                .addGroup(cameraPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+                    .addComponent(fovSlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+                    .addComponent(jLabel13)
+                    .addComponent(fovSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
-                .addComponent(sceneInfoLabel2)
-                .addGap(5, 5, 5)
-                .addGroup(sceneInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+                .addGroup(cameraPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                     .addComponent(jSlider1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                     .addComponent(jSlider1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                     .addComponent(jLabel7)
                     .addComponent(jLabel7)
                     .addComponent(jSpinner1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                     .addComponent(jSpinner1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
-                .addGroup(sceneInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+                .addGroup(cameraPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                     .addComponent(jSpinner2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                     .addComponent(jSpinner2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
-                    .addGroup(sceneInfoPanelLayout.createSequentialGroup()
-                        .addGroup(sceneInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+                    .addGroup(cameraPanelLayout.createSequentialGroup()
+                        .addGroup(cameraPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                             .addComponent(jSlider2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                             .addComponent(jSlider2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                             .addComponent(jLabel8))
                             .addComponent(jLabel8))
                         .addGap(1, 1, 1)))
                         .addGap(1, 1, 1)))
                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
-                .addGroup(sceneInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                .addGroup(cameraPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                     .addComponent(jLabel9)
                     .addComponent(jLabel9)
                     .addComponent(jLabel11))
                     .addComponent(jLabel11))
                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-                .addGroup(sceneInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                .addGroup(cameraPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                     .addComponent(jLabel10)
                     .addComponent(jLabel10)
                     .addComponent(jLabel12))
                     .addComponent(jLabel12))
                 .addGap(8, 8, 8)
                 .addGap(8, 8, 8)
-                .addGroup(sceneInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                .addGroup(cameraPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                     .addComponent(cursorPositionHeader)
                     .addComponent(cursorPositionHeader)
                     .addComponent(cursorPositionLabel)))
                     .addComponent(cursorPositionLabel)))
         );
         );
 
 
-        jToolBar1.setFloatable(false);
         jToolBar1.setRollover(true);
         jToolBar1.setRollover(true);
 
 
         transformationTypeComboBox.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Local", "Global", "Camera" }));
         transformationTypeComboBox.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Local", "Global", "Camera" }));
@@ -502,7 +527,7 @@ public final class SceneComposerTopComponent extends TopComponent implements
         jPanel3.setLayout(jPanel3Layout);
         jPanel3.setLayout(jPanel3Layout);
         jPanel3Layout.setHorizontalGroup(
         jPanel3Layout.setHorizontalGroup(
             jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
             jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-            .addGap(0, 133, Short.MAX_VALUE)
+            .addGap(0, 571, Short.MAX_VALUE)
         );
         );
         jPanel3Layout.setVerticalGroup(
         jPanel3Layout.setVerticalGroup(
             jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
             jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@@ -513,7 +538,6 @@ public final class SceneComposerTopComponent extends TopComponent implements
 
 
         jPanel4.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(SceneComposerTopComponent.class, "SceneComposerTopComponent.jPanel4.border.title"))); // NOI18N
         jPanel4.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(SceneComposerTopComponent.class, "SceneComposerTopComponent.jPanel4.border.title"))); // NOI18N
 
 
-        jToolBar2.setFloatable(false);
         jToolBar2.setRollover(true);
         jToolBar2.setRollover(true);
 
 
         org.openide.awt.Mnemonics.setLocalizedText(createPhysicsMeshButton, org.openide.util.NbBundle.getMessage(SceneComposerTopComponent.class, "SceneComposerTopComponent.createPhysicsMeshButton.text")); // NOI18N
         org.openide.awt.Mnemonics.setLocalizedText(createPhysicsMeshButton, org.openide.util.NbBundle.getMessage(SceneComposerTopComponent.class, "SceneComposerTopComponent.createPhysicsMeshButton.text")); // NOI18N
@@ -534,7 +558,6 @@ public final class SceneComposerTopComponent extends TopComponent implements
         org.openide.awt.Mnemonics.setLocalizedText(jLabel4, org.openide.util.NbBundle.getMessage(SceneComposerTopComponent.class, "SceneComposerTopComponent.jLabel4.text")); // NOI18N
         org.openide.awt.Mnemonics.setLocalizedText(jLabel4, org.openide.util.NbBundle.getMessage(SceneComposerTopComponent.class, "SceneComposerTopComponent.jLabel4.text")); // NOI18N
         jToolBar2.add(jLabel4);
         jToolBar2.add(jLabel4);
 
 
-        jToolBar3.setFloatable(false);
         jToolBar3.setRollover(true);
         jToolBar3.setRollover(true);
 
 
         org.openide.awt.Mnemonics.setLocalizedText(jButton1, org.openide.util.NbBundle.getMessage(SceneComposerTopComponent.class, "SceneComposerTopComponent.jButton1.text")); // NOI18N
         org.openide.awt.Mnemonics.setLocalizedText(jButton1, org.openide.util.NbBundle.getMessage(SceneComposerTopComponent.class, "SceneComposerTopComponent.jButton1.text")); // NOI18N
@@ -640,6 +663,28 @@ public final class SceneComposerTopComponent extends TopComponent implements
                 .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                 .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
         );
         );
 
 
+        sceneInfoPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(SceneComposerTopComponent.class, "SceneComposerTopComponent.sceneInfoPanel.border.title"))); // NOI18N
+
+        org.openide.awt.Mnemonics.setLocalizedText(sceneInfoLabel, org.openide.util.NbBundle.getMessage(SceneComposerTopComponent.class, "SceneComposerTopComponent.sceneInfoLabel.text_1")); // NOI18N
+
+        org.openide.awt.Mnemonics.setLocalizedText(sceneInfoLabel1, org.openide.util.NbBundle.getMessage(SceneComposerTopComponent.class, "SceneComposerTopComponent.sceneInfoLabel1.text")); // NOI18N
+
+        javax.swing.GroupLayout sceneInfoPanelLayout = new javax.swing.GroupLayout(sceneInfoPanel);
+        sceneInfoPanel.setLayout(sceneInfoPanelLayout);
+        sceneInfoPanelLayout.setHorizontalGroup(
+            sceneInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addComponent(sceneInfoLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 391, Short.MAX_VALUE)
+            .addComponent(sceneInfoLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+        );
+        sceneInfoPanelLayout.setVerticalGroup(
+            sceneInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(sceneInfoPanelLayout.createSequentialGroup()
+                .addComponent(sceneInfoLabel)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                .addComponent(sceneInfoLabel1)
+                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+        );
+
         javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
         javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
         this.setLayout(layout);
         this.setLayout(layout);
         layout.setHorizontalGroup(
         layout.setHorizontalGroup(
@@ -647,7 +692,10 @@ public final class SceneComposerTopComponent extends TopComponent implements
             .addGroup(layout.createSequentialGroup()
             .addGroup(layout.createSequentialGroup()
                 .addComponent(jPanel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                 .addComponent(jPanel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
-                .addComponent(sceneInfoPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+                .addComponent(sceneInfoPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                .addComponent(cameraPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
             .addComponent(jToolBar1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
             .addComponent(jToolBar1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
         );
         );
         layout.setVerticalGroup(
         layout.setVerticalGroup(
@@ -656,9 +704,13 @@ public final class SceneComposerTopComponent extends TopComponent implements
                 .addComponent(jToolBar1, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
                 .addComponent(jToolBar1, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-                    .addComponent(sceneInfoPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-                    .addComponent(jPanel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
+                    .addComponent(cameraPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                    .addComponent(jPanel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                    .addComponent(sceneInfoPanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
         );
         );
+
+        cameraPanel.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(SceneComposerTopComponent.class, "SceneComposerTopComponent.cameraPanel.AccessibleContext.accessibleName")); // NOI18N
+        sceneInfoPanel.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(SceneComposerTopComponent.class, "SceneComposerTopComponent.sceneInfoPanel.AccessibleContext.accessibleName")); // NOI18N
     }// </editor-fold>//GEN-END:initComponents
     }// </editor-fold>//GEN-END:initComponents
 
 
     private void showSelectionToggleButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_showSelectionToggleButtonActionPerformed
     private void showSelectionToggleButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_showSelectionToggleButtonActionPerformed
@@ -804,7 +856,7 @@ private void jToggleSelectGeomActionPerformed(java.awt.event.ActionEvent evt) {/
         // This is called, when the spinner of the near plane has been changed.
         // This is called, when the spinner of the near plane has been changed.
         float near = ((float)jSlider1.getValue() / 1000f);
         float near = ((float)jSlider1.getValue() / 1000f);
         float spin = (Float)jSpinner1.getValue();
         float spin = (Float)jSpinner1.getValue();
-        
+        float fov = (Float) fovSpinner.getValue();
         // Prevent an endless loop of state changes and don't change the slider when the spinner
         // Prevent an endless loop of state changes and don't change the slider when the spinner
         // has gone out of range, since this would lead to the slider's StateChanged overwriting the spinner again.
         // has gone out of range, since this would lead to the slider's StateChanged overwriting the spinner again.
         // but we want the spinner to be a free-form field
         // but we want the spinner to be a free-form field
@@ -814,31 +866,59 @@ private void jToggleSelectGeomActionPerformed(java.awt.event.ActionEvent evt) {/
         }
         }
         
         
         final Camera cam = SceneApplication.getApplication().getCamera();
         final Camera cam = SceneApplication.getApplication().getCamera();
-        cam.setFrustumPerspective(45f, (float)cam.getWidth() / cam.getHeight(), spin, cam.getFrustumFar());
+        cam.setFrustumPerspective(fov, (float)cam.getWidth() / cam.getHeight(), spin, cam.getFrustumFar());
     }//GEN-LAST:event_jSpinner1StateChanged
     }//GEN-LAST:event_jSpinner1StateChanged
 
 
     private void jSpinner2StateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_jSpinner2StateChanged
     private void jSpinner2StateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_jSpinner2StateChanged
         // Prevent an endless loop of state changes and don't change the slider when the spinner
         // Prevent an endless loop of state changes and don't change the slider when the spinner
         // has gone out of range, since this would lead to the slider's StateChanged overwriting the spinner again.
         // has gone out of range, since this would lead to the slider's StateChanged overwriting the spinner again.
         // but we want the spinner to be a free-form field
         // but we want the spinner to be a free-form field
-        
+        float fov = (int) fovSpinner.getValue();
         float spin = (Float)jSpinner2.getValue();
         float spin = (Float)jSpinner2.getValue();
         if (spin <= 3000f && spin >= 5f && !FastMath.approximateEquals(spin, (float)jSlider2.getValue())) {
         if (spin <= 3000f && spin >= 5f && !FastMath.approximateEquals(spin, (float)jSlider2.getValue())) {
             jSlider2.setValue((int)spin);
             jSlider2.setValue((int)spin);
         }
         }
         
         
         final Camera cam = SceneApplication.getApplication().getCamera();
         final Camera cam = SceneApplication.getApplication().getCamera();
-        cam.setFrustumPerspective(45f, (float)cam.getWidth() / cam.getHeight(), cam.getFrustumNear(), spin);
+        cam.setFrustumPerspective(fov, (float)cam.getWidth() / cam.getHeight(), cam.getFrustumNear(), spin);
     }//GEN-LAST:event_jSpinner2StateChanged
     }//GEN-LAST:event_jSpinner2StateChanged
 
 
+    private void fovSliderStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_fovSliderStateChanged
+        int fov = (int) fovSlider.getValue();
+        
+        // Prevent an endless loop of state changes
+        if ((int) fovSpinner.getValue() != fov) {
+            fovSpinner.setValue((int) fov);
+        }
+    }//GEN-LAST:event_fovSliderStateChanged
+
+    private void fovSpinnerStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_fovSpinnerStateChanged
+        // This is called, when the spinner of the near plane has been changed.
+        int fov = (int) fovSpinner.getValue();
+        
+        // Prevent an endless loop of state changes and don't change the slider when the spinner
+        // has gone out of range, since this would lead to the slider's StateChanged overwriting the spinner again.
+        // but we want the spinner to be a free-form field
+        
+        if (fov <= 360 && fov >= 1 && fovSlider.getValue() != fov) {
+            fovSlider.setValue((int) fovSpinner.getValue());
+        }
+        
+        final Camera cam = SceneApplication.getApplication().getCamera();
+        cam.setFrustumPerspective(fov, (float)cam.getWidth() / cam.getHeight(), cam.getFrustumNear(), cam.getFrustumFar());
+    }//GEN-LAST:event_fovSpinnerStateChanged
+
     // Variables declaration - do not modify//GEN-BEGIN:variables
     // Variables declaration - do not modify//GEN-BEGIN:variables
     private javax.swing.JButton camToCursorSelectionButton;
     private javax.swing.JButton camToCursorSelectionButton;
+    private javax.swing.JPanel cameraPanel;
     private javax.swing.JButton createPhysicsMeshButton;
     private javax.swing.JButton createPhysicsMeshButton;
     private javax.swing.JLabel cursorPositionHeader;
     private javax.swing.JLabel cursorPositionHeader;
     private javax.swing.JLabel cursorPositionLabel;
     private javax.swing.JLabel cursorPositionLabel;
     private javax.swing.JButton cursorToSelectionButton;
     private javax.swing.JButton cursorToSelectionButton;
     private javax.swing.JButton emitButton;
     private javax.swing.JButton emitButton;
     private javax.swing.JCheckBox fixedCheckBox;
     private javax.swing.JCheckBox fixedCheckBox;
+    private javax.swing.JSlider fovSlider;
+    private javax.swing.JSpinner fovSpinner;
     private javax.swing.JSpinner heightSpinner;
     private javax.swing.JSpinner heightSpinner;
     private javax.swing.JButton jButton1;
     private javax.swing.JButton jButton1;
     private javax.swing.JButton jButton2;
     private javax.swing.JButton jButton2;
@@ -848,6 +928,7 @@ private void jToggleSelectGeomActionPerformed(java.awt.event.ActionEvent evt) {/
     private javax.swing.JLabel jLabel10;
     private javax.swing.JLabel jLabel10;
     private javax.swing.JLabel jLabel11;
     private javax.swing.JLabel jLabel11;
     private javax.swing.JLabel jLabel12;
     private javax.swing.JLabel jLabel12;
+    private javax.swing.JLabel jLabel13;
     private javax.swing.JLabel jLabel2;
     private javax.swing.JLabel jLabel2;
     private javax.swing.JLabel jLabel3;
     private javax.swing.JLabel jLabel3;
     private javax.swing.JLabel jLabel4;
     private javax.swing.JLabel jLabel4;
@@ -885,8 +966,8 @@ private void jToggleSelectGeomActionPerformed(java.awt.event.ActionEvent evt) {/
     private javax.swing.JButton resetCursorButton;
     private javax.swing.JButton resetCursorButton;
     private javax.swing.JToggleButton rotateButton;
     private javax.swing.JToggleButton rotateButton;
     private javax.swing.JToggleButton scaleButton;
     private javax.swing.JToggleButton scaleButton;
+    private javax.swing.JLabel sceneInfoLabel;
     private javax.swing.JLabel sceneInfoLabel1;
     private javax.swing.JLabel sceneInfoLabel1;
-    private javax.swing.JLabel sceneInfoLabel2;
     private javax.swing.JPanel sceneInfoPanel;
     private javax.swing.JPanel sceneInfoPanel;
     private javax.swing.JToggleButton selectButton;
     private javax.swing.JToggleButton selectButton;
     private javax.swing.JToggleButton showGridToggleButton;
     private javax.swing.JToggleButton showGridToggleButton;
@@ -1052,10 +1133,10 @@ private void jToggleSelectGeomActionPerformed(java.awt.event.ActionEvent evt) {/
             result.removeLookupListener(inst);
             result.removeLookupListener(inst);
             showSelectionToggleButton.setSelected(true);
             showSelectionToggleButton.setSelected(true);
             showGridToggleButton.setSelected(true);
             showGridToggleButton.setSelected(true);
-            sceneInfoLabel1.setText("");
-            sceneInfoLabel2.setText("");
-            sceneInfoLabel1.setToolTipText("");
-            sceneInfoLabel2.setToolTipText("");
+            sceneInfoLabel.setText("");
+            sceneInfoLabel.setText("");
+            sceneInfoLabel.setToolTipText("");
+            sceneInfoLabel.setToolTipText("");
             close();
             close();
         } else {
         } else {
             result.addLookupListener(this);
             result.addLookupListener(this);
@@ -1063,10 +1144,10 @@ private void jToggleSelectGeomActionPerformed(java.awt.event.ActionEvent evt) {/
             showGridToggleButton.setSelected(true);
             showGridToggleButton.setSelected(true);
             //TODO: threading
             //TODO: threading
             if (file != null) {
             if (file != null) {
-                sceneInfoLabel1.setText("Name: " + file.getNameExt());
-                sceneInfoLabel2.setText("Size: " + file.getSize() / 1024 + " kB");
-                sceneInfoLabel1.setToolTipText("Name: " + file.getNameExt());
-                sceneInfoLabel2.setToolTipText("Size: " + file.getSize() / 1024 + " kB");
+                sceneInfoLabel.setText("Name: " + file.getNameExt());
+                sceneInfoLabel.setText("Size: " + file.getSize() / 1024 + " kB");
+                sceneInfoLabel.setToolTipText("Name: " + file.getNameExt());
+                sceneInfoLabel.setToolTipText("Size: " + file.getSize() / 1024 + " kB");
             }
             }
             open();
             open();
             requestActive();
             requestActive();