private Node terrainNode;
private Node rootNode;
private AssetDataObject currentFileObject;
+ private TerrainEditorTopComponent topComponent;
// texture settings
public static final String DEFAULT_TERRAIN_TEXTURE = "com/jme3/gde/terraineditor/dirt.jpg";
public static final float DEFAULT_TEXTURE_SCALE = 16.0625f;
public static final int NUM_ALPHA_TEXTURES = 3;
- private final int BASE_TEXTURE_COUNT = NUM_ALPHA_TEXTURES; // add any others here, like a global specular map
- protected final int MAX_TEXTURE_LAYERS = 7-BASE_TEXTURE_COUNT; // 16 max, minus the ones we are reserving
-
+ protected final int MAX_DIFFUSE = 12;
+ protected final int MAX_TEXTURES = 16-NUM_ALPHA_TEXTURES; // 16 max (diffuse and normal), minus the ones we are reserving
+
protected SaveCookie terrainSaveCookie = new SaveCookie() {
rootNode = this.jmeRootNode.getLookup().lookup(Node.class);
this.currentFileObject = currentFileObject;
this.currentFileObject.setSaveCookie(terrainSaveCookie);
+ this.topComponent = topComponent;
}
public void setToolController(TerrainToolController toolController) {
return tex;
}
- /**
- * Get the diffuse texture at the specified layer.
- * Run this on the GL thread!
- */
- private Texture doGetAlphaTextureFromDiffuse(Terrain terrain, int diffuseLayer) {
- int alphaIdx = diffuseLayer/4; // 4 = rgba = 4 textures
-
- return doGetAlphaTexture(terrain, alphaIdx);
- /* Terrain terrain = (Terrain) getTerrain(null);
- MatParam matParam = null;
- //TODO: add when supported
-// if (alphaIdx == 0)
- matParam = terrain.getMaterial().getParam("AlphaMap");
-// else
-// matParam = terrain.getMaterial().getParam("AlphaMap_"+alphaIdx);
-
- if (matParam == null || matParam.getValue() == null) {
- return null;
- }
- Texture tex = (Texture) matParam.getValue();
- return tex;
- */
- }
-
/**
* Set the diffuse texture at the specified layer.
Texture tex = manager.loadAsset(new TextureKey(alphaBlendFileName, false));
if (i == 0)
mat.setTexture("AlphaMap", tex);
- /*else if (i == 1) // add these in when they are supported
+ else if (i == 1) // add these in when they are supported
mat.setTexture("AlphaMap_1", tex);
else if (i == 2)
- mat.setTexture("AlphaMap_2", tex);*/
+ mat.setTexture("AlphaMap_2", tex);
}
// give the first layer default texture
return false;
}
+ /**
+ * Enable/disable the add and remove texture buttons based
+ * on how many textures are currently being used.
+ */
+ protected void enableTextureButtons() {
+ final int numAvailable = MAX_TEXTURES-doGetNumUsedTextures();
+ final boolean add = doGetNumDiffuseTextures() < MAX_DIFFUSE && numAvailable > 0;
+ final boolean remove = doGetNumDiffuseTextures() > 1;
+
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ topComponent.enableAddTextureButton(add);
+ topComponent.enableRemoveTextureButton(remove);
+ topComponent.updateTextureCountLabel(numAvailable);
+ topComponent.setAddNormalTextureEnabled(numAvailable>0);
+ }
+ });
+ }
+
+ /**
+ * How many diffuse textures are being used.
+ * Blocking call on GL thread
+ */
+ protected int getNumDiffuseTextures() {
+ try {
+ Integer count =
+ SceneApplication.getApplication().enqueue(new Callable<Integer>() {
+ public Integer call() throws Exception {
+ return doGetNumDiffuseTextures();
+ }
+ }).get();
+ return count;
+ } catch (InterruptedException ex) {
+ Exceptions.printStackTrace(ex);
+ } catch (ExecutionException ex) {
+ Exceptions.printStackTrace(ex);
+ }
+ return -1;
+ }
+
+ private int doGetNumDiffuseTextures() {
+ Terrain terrain = (Terrain) getTerrain(null);
+ if (terrain == null)
+ return 0;
+ int count = 0;
+
+ for (int i=0; i<MAX_TEXTURES; i++) {
+ Texture tex = doGetDiffuseTexture(i);
+ if (tex != null)
+ count++;
+ }
+ return count;
+ }
+
/**
* How many textures are currently being used.
* Blocking call on GL thread
int count = 0;
- for (int i=0; i<MAX_TEXTURE_LAYERS; i++) {
+ for (int i=0; i<MAX_TEXTURES; i++) {
Texture tex = doGetDiffuseTexture(i);
if (tex != null)
count++;
TerrainToolController toolController;
TerrainEditorController editorController;
private SceneRequest currentRequest;
- private int currentTextureCount;
private boolean alreadyChoosing = false; // used for texture table selection
private CreateTerrainWizardAction terrainWizard;
private SkyboxWizardAction skyboxWizard;
private JmeSpatial selectedSpat;
private TerrainNodeListener terrainDeletedNodeListener;
-
+ private boolean availableNormalTextures;
private HelpCtx ctx = new HelpCtx("sdk.terrain_editor");
return;
int index = getTableModel().getRowCount(); // get the last row
addNewTextureLayer(index);
- if (currentTextureCount >= editorController.MAX_TEXTURE_LAYERS)
- addTextureButton.setEnabled(false);
- if (currentTextureCount > 0)
- removeTextureButton.setEnabled(true);
- remainingTexturesLabel.setText(""+(editorController.MAX_TEXTURE_LAYERS-currentTextureCount));
+ editorController.enableTextureButtons();
}//GEN-LAST:event_addTextureButtonActionPerformed
+ protected void enableAddTextureButton(boolean enabled) {
+ addTextureButton.setEnabled(enabled);
+ }
+
+ protected void enableRemoveTextureButton(boolean enabled) {
+ removeTextureButton.setEnabled(enabled);
+ }
+
+ protected void updateTextureCountLabel(int count) {
+ remainingTexturesLabel.setText(""+count);
+ }
+
+ protected void setAddNormalTextureEnabled(boolean enabled) {
+ availableNormalTextures = enabled;
+ }
+
private void removeTextureButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_removeTextureButtonActionPerformed
if (editorController == null || editorController.getTerrain(null) == null)
return;
return;
int index = getTableModel().getRowCount() - 1; // get the last row
removeTextureLayer(index);
- if (currentTextureCount == 0)
- removeTextureButton.setEnabled(false);
- if (currentTextureCount < editorController.MAX_TEXTURE_LAYERS)
- addTextureButton.setEnabled(true);
- remainingTexturesLabel.setText(""+(editorController.MAX_TEXTURE_LAYERS-currentTextureCount));
+ editorController.enableTextureButtons();
}//GEN-LAST:event_removeTextureButtonActionPerformed
private void eraseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_eraseButtonActionPerformed
addSaveNode(selectedSpat);
- // editorController.getAlphaSaveDataObject(this);
-
editorController.setNeedsSave(true);
- currentTextureCount = editorController.getNumUsedTextures();
- remainingTexturesLabel.setText(""+(editorController.MAX_TEXTURE_LAYERS-currentTextureCount));
+ editorController.enableTextureButtons();
reinitTextureTable(); // update the UI
addSaveNode(jmeNode);
- SceneUndoRedoManager m = Lookup.getDefault().lookup(SceneUndoRedoManager.class);//TODO remove this line
+ //SceneUndoRedoManager m = Lookup.getDefault().lookup(SceneUndoRedoManager.class);//TODO remove this line
Logger.getLogger(TerrainEditorTopComponent.class.getName()).finer("Terrain openScene "+file.getName());
SceneApplication.getApplication().requestScene(request);
terrainDeletedNodeListener = new TerrainNodeListener();
+ editorController.enableTextureButtons();
}
// run on GL thread
else
toolController.setSelectedTextureIndex(-1);
- currentTextureCount = editorController.getNumUsedTextures();
- remainingTexturesLabel.setText(""+(editorController.MAX_TEXTURE_LAYERS-currentTextureCount));
+ editorController.enableTextureButtons();
triPlanarCheckBox.setSelected(editorController.isTriPlanarEnabled());
}
removeRow(0);
// fill the table with the proper data
- for (int i=0; i<editorController.MAX_TEXTURE_LAYERS; i++) {
+ for (int i=0; i<editorController.MAX_TEXTURES; i++) {
if (!editorController.hasTextureAt(i))
continue;
// and add it to the actual material
setTexture(newIndex, (String)null);
setTextureScale(newIndex, scale);
- currentTextureCount = editorController.getNumUsedTextures();
+ editorController.enableTextureButtons();
}
protected void setTexture(final int index, final Texture texture) {
protected void setNormal(final int index, final String texturePath) {
setValueAt(index, index, 2);
editorController.setNormalMap(index, texturePath);
- currentTextureCount = editorController.getNumUsedTextures();
+ editorController.enableTextureButtons();
}
protected void setNormal(final int index, final Texture texture) {
setValueAt(index, index, 2);
editorController.setNormalMap(index, texture);
- currentTextureCount = editorController.getNumUsedTextures();
+ editorController.enableTextureButtons();
}
protected void setTextureScale(int index, float scale) {
protected void removeTexture(final int index) {
removeRow(index);
editorController.removeTextureLayer(index);
- currentTextureCount = editorController.getNumUsedTextures();
+ editorController.enableTextureButtons();
}
}
try {
Texture selectedTex = getTextureFromModel(row); // delegates to sub class
+ if (selectedTex == null && !availableNormalTextures) // bail if we are at our texture limit
+ return;
TexturePropertyEditor editor = new TexturePropertyEditor(selectedTex);
Component view = editor.getCustomEditor();
view.setVisible(true);
}
}
- private Component getTopComponent() {
- return this;
- }
-
/**
* A file filter to only show images
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-*** GENERATED FROM project.xml - DO NOT EDIT ***
-*** EDIT ../build.xml INSTEAD ***
--->
-<project name="jme-gde-impl" basedir=".." xmlns:sproject="http://www.netbeans.org/ns/nb-module-suite-project/1">
- <fail message="Please build using Ant 1.7.1 or higher.">
- <condition>
- <not>
- <antversion atleast="1.7.1"/>
- </not>
- </condition>
- </fail>
- <property file="nbproject/private/platform-private.properties"/>
- <property file="nbproject/platform.properties"/>
- <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-suite-project/1">
- <attribute name="name"/>
- <attribute name="value"/>
- <sequential>
- <property name="@{name}" value="${@{value}}"/>
- </sequential>
- </macrodef>
- <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-suite-project/1">
- <attribute name="property"/>
- <attribute name="value"/>
- <sequential>
- <property name="@{property}" value="@{value}"/>
- </sequential>
- </macrodef>
- <property file="${user.properties.file}"/>
- <sproject:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir"/>
- <sproject:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir"/>
- <sproject:evalprops property="cluster.path.evaluated" value="${cluster.path}"/>
- <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
- <condition>
- <not>
- <contains string="${cluster.path.evaluated}" substring="platform"/>
- </not>
- </condition>
- </fail>
- <fail message="Cannot find NetBeans build harness. ${line.separator}Check that nbplatform.${nbplatform.active}.netbeans.dest.dir and nbplatform.${nbplatform.active}.harness.dir are defined. ${line.separator}On a developer machine these are normally defined in ${user.properties.file}=${netbeans.user}/build.properties ${line.separator}but for automated builds you should pass these properties to Ant explicitly.">
- <condition>
- <not>
- <available type="dir" file="${harness.dir}"/>
- </not>
- </condition>
- </fail>
- <import file="${harness.dir}/suite.xml"/>
-</project>
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--\r
+*** GENERATED FROM project.xml - DO NOT EDIT ***\r
+*** EDIT ../build.xml INSTEAD ***\r
+-->\r
+<project name="jme-gde-impl" basedir=".." xmlns:sproject="http://www.netbeans.org/ns/nb-module-suite-project/1">\r
+ <fail message="Please build using Ant 1.7.1 or higher.">\r
+ <condition>\r
+ <not>\r
+ <antversion atleast="1.7.1"/>\r
+ </not>\r
+ </condition>\r
+ </fail>\r
+ <property file="nbproject/private/platform-private.properties"/>\r
+ <property file="nbproject/platform.properties"/>\r
+ <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-suite-project/1">\r
+ <attribute name="name"/>\r
+ <attribute name="value"/>\r
+ <sequential>\r
+ <property name="@{name}" value="${@{value}}"/>\r
+ </sequential>\r
+ </macrodef>\r
+ <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-suite-project/1">\r
+ <attribute name="property"/>\r
+ <attribute name="value"/>\r
+ <sequential>\r
+ <property name="@{property}" value="@{value}"/>\r
+ </sequential>\r
+ </macrodef>\r
+ <property file="${user.properties.file}"/>\r
+ <sproject:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir"/>\r
+ <sproject:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir"/>\r
+ <sproject:evalprops property="cluster.path.evaluated" value="${cluster.path}"/>\r
+ <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">\r
+ <condition>\r
+ <not>\r
+ <contains string="${cluster.path.evaluated}" substring="platform"/>\r
+ </not>\r
+ </condition>\r
+ </fail>\r
+ <fail message="Cannot find NetBeans build harness. ${line.separator}Check that nbplatform.${nbplatform.active}.netbeans.dest.dir and nbplatform.${nbplatform.active}.harness.dir are defined. ${line.separator}On a developer machine these are normally defined in ${user.properties.file}=${netbeans.user}/build.properties ${line.separator}but for automated builds you should pass these properties to Ant explicitly.">\r
+ <condition>\r
+ <not>\r
+ <available type="dir" file="${harness.dir}"/>\r
+ </not>\r
+ </condition>\r
+ </fail>\r
+ <import file="${harness.dir}/suite.xml"/>\r
+</project>\r
-build.xml.data.CRC32=cbef27ca
-build.xml.script.CRC32=7efad5da
-build.xml.stylesheet.CRC32=531c622b@1.31.1.7
-# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
-# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
-nbproject/build-impl.xml.data.CRC32=cbef27ca
-nbproject/build-impl.xml.script.CRC32=ce1d717c
-nbproject/build-impl.xml.stylesheet.CRC32=183e6ef3@1.42.1
+build.xml.data.CRC32=cbef27ca\r
+build.xml.script.CRC32=7efad5da\r
+build.xml.stylesheet.CRC32=531c622b@1.31.1.7\r
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\r
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\r
+nbproject/build-impl.xml.data.CRC32=cbef27ca\r
+nbproject/build-impl.xml.script.CRC32=ce1d717c\r
+nbproject/build-impl.xml.stylesheet.CRC32=183e6ef3@1.42.2\r
-cluster.path=\
- ${nbplatform.active.dir}/extra:\
- ${nbplatform.active.dir}/harness:\
- ${nbplatform.active.dir}/ide:\
- ${nbplatform.active.dir}/java:\
- ${nbplatform.active.dir}/platform
-disabled.modules=\
- org.netbeans.libs.bugtracking,\
- org.netbeans.libs.bugzilla,\
- org.netbeans.libs.jsr223,\
- org.netbeans.libs.smack,\
- org.netbeans.libs.springframework,\
- org.netbeans.libs.swingx,\
- org.netbeans.modules.apisupport.apidocs,\
- org.netbeans.modules.bugtracking,\
- org.netbeans.modules.bugtracking.bridge,\
- org.netbeans.modules.bugzilla,\
- org.netbeans.modules.db,\
- org.netbeans.modules.db.core,\
- org.netbeans.modules.db.dataview,\
- org.netbeans.modules.db.drivers,\
- org.netbeans.modules.db.kit,\
- org.netbeans.modules.db.metadata.model,\
- org.netbeans.modules.db.mysql,\
- org.netbeans.modules.db.sql.editor,\
- org.netbeans.modules.db.sql.visualeditor,\
- org.netbeans.modules.dbapi,\
- org.netbeans.modules.dbschema,\
- org.netbeans.modules.derby,\
- org.netbeans.modules.form,\
- org.netbeans.modules.form.j2ee,\
- org.netbeans.modules.form.kit,\
- org.netbeans.modules.glassfish.common,\
- org.netbeans.modules.hibernate,\
- org.netbeans.modules.hibernatelib,\
- org.netbeans.modules.hudson,\
- org.netbeans.modules.hudson.ant,\
- org.netbeans.modules.hudson.maven,\
- org.netbeans.modules.hudson.mercurial,\
- org.netbeans.modules.hudson.subversion,\
- org.netbeans.modules.i18n.form,\
- org.netbeans.modules.j2ee.core.utilities,\
- org.netbeans.modules.j2ee.jpa.refactoring,\
- org.netbeans.modules.j2ee.jpa.verification,\
- org.netbeans.modules.j2ee.persistence,\
- org.netbeans.modules.j2ee.persistence.kit,\
- org.netbeans.modules.j2ee.toplinklib,\
- org.netbeans.modules.jellytools,\
- org.netbeans.modules.jellytools.ide,\
- org.netbeans.modules.jellytools.java,\
- org.netbeans.modules.jellytools.platform,\
- org.netbeans.modules.jemmy,\
- org.netbeans.modules.languages,\
- org.netbeans.modules.maven,\
- org.netbeans.modules.maven.embedder,\
- org.netbeans.modules.maven.grammar,\
- org.netbeans.modules.maven.graph,\
- org.netbeans.modules.maven.hints,\
- org.netbeans.modules.maven.indexer,\
- org.netbeans.modules.maven.junit,\
- org.netbeans.modules.maven.kit,\
- org.netbeans.modules.maven.model,\
- org.netbeans.modules.maven.osgi,\
- org.netbeans.modules.maven.persistence,\
- org.netbeans.modules.maven.repository,\
- org.netbeans.modules.maven.search,\
- org.netbeans.modules.maven.spring,\
- org.netbeans.modules.server,\
- org.netbeans.modules.spellchecker,\
- org.netbeans.modules.spellchecker.bindings.htmlxml,\
- org.netbeans.modules.spellchecker.bindings.properties,\
- org.netbeans.modules.spellchecker.dictionary_en,\
- org.netbeans.modules.spellchecker.kit,\
- org.netbeans.modules.spring.beans,\
- org.netbeans.modules.swing.validation,\
- org.netbeans.modules.swingapp,\
- org.netbeans.modules.websvc.saas.codegen.java,\
- org.netbeans.modules.xml.wsdl.model,\
- org.openide.compat,\
- org.openide.options,\
- org.openide.util.enumerations
-nbjdk.active=default
-nbplatform.active=default
+cluster.path=\\r
+ ${nbplatform.active.dir}/extra:\\r
+ ${nbplatform.active.dir}/harness:\\r
+ ${nbplatform.active.dir}/ide:\\r
+ ${nbplatform.active.dir}/java:\\r
+ ${nbplatform.active.dir}/platform\r
+disabled.modules=\\r
+ org.netbeans.libs.bugtracking,\\r
+ org.netbeans.libs.bugzilla,\\r
+ org.netbeans.libs.jsr223,\\r
+ org.netbeans.libs.smack,\\r
+ org.netbeans.libs.springframework,\\r
+ org.netbeans.libs.swingx,\\r
+ org.netbeans.modules.apisupport.apidocs,\\r
+ org.netbeans.modules.bugtracking,\\r
+ org.netbeans.modules.bugtracking.bridge,\\r
+ org.netbeans.modules.bugzilla,\\r
+ org.netbeans.modules.db,\\r
+ org.netbeans.modules.db.core,\\r
+ org.netbeans.modules.db.dataview,\\r
+ org.netbeans.modules.db.drivers,\\r
+ org.netbeans.modules.db.kit,\\r
+ org.netbeans.modules.db.metadata.model,\\r
+ org.netbeans.modules.db.mysql,\\r
+ org.netbeans.modules.db.sql.editor,\\r
+ org.netbeans.modules.db.sql.visualeditor,\\r
+ org.netbeans.modules.dbapi,\\r
+ org.netbeans.modules.dbschema,\\r
+ org.netbeans.modules.derby,\\r
+ org.netbeans.modules.form,\\r
+ org.netbeans.modules.form.j2ee,\\r
+ org.netbeans.modules.form.kit,\\r
+ org.netbeans.modules.glassfish.common,\\r
+ org.netbeans.modules.hibernate,\\r
+ org.netbeans.modules.hibernatelib,\\r
+ org.netbeans.modules.hudson,\\r
+ org.netbeans.modules.hudson.ant,\\r
+ org.netbeans.modules.hudson.maven,\\r
+ org.netbeans.modules.hudson.mercurial,\\r
+ org.netbeans.modules.hudson.subversion,\\r
+ org.netbeans.modules.i18n.form,\\r
+ org.netbeans.modules.j2ee.core.utilities,\\r
+ org.netbeans.modules.j2ee.jpa.refactoring,\\r
+ org.netbeans.modules.j2ee.jpa.verification,\\r
+ org.netbeans.modules.j2ee.persistence,\\r
+ org.netbeans.modules.j2ee.persistence.kit,\\r
+ org.netbeans.modules.j2ee.toplinklib,\\r
+ org.netbeans.modules.jellytools,\\r
+ org.netbeans.modules.jellytools.ide,\\r
+ org.netbeans.modules.jellytools.java,\\r
+ org.netbeans.modules.jellytools.platform,\\r
+ org.netbeans.modules.jemmy,\\r
+ org.netbeans.modules.languages,\\r
+ org.netbeans.modules.maven.grammar,\\r
+ org.netbeans.modules.maven.graph,\\r
+ org.netbeans.modules.maven.hints,\\r
+ org.netbeans.modules.maven.junit,\\r
+ org.netbeans.modules.maven.kit,\\r
+ org.netbeans.modules.maven.osgi,\\r
+ org.netbeans.modules.maven.persistence,\\r
+ org.netbeans.modules.maven.repository,\\r
+ org.netbeans.modules.maven.search,\\r
+ org.netbeans.modules.maven.spring,\\r
+ org.netbeans.modules.server,\\r
+ org.netbeans.modules.spellchecker,\\r
+ org.netbeans.modules.spellchecker.bindings.htmlxml,\\r
+ org.netbeans.modules.spellchecker.bindings.properties,\\r
+ org.netbeans.modules.spellchecker.dictionary_en,\\r
+ org.netbeans.modules.spellchecker.kit,\\r
+ org.netbeans.modules.spring.beans,\\r
+ org.netbeans.modules.swingapp,\\r
+ org.netbeans.modules.websvc.saas.codegen.java,\\r
+ org.netbeans.modules.xml.wsdl.model,\\r
+ org.openide.compat,\\r
+ org.openide.options,\\r
+ org.openide.util.enumerations\r
+nbjdk.active=default\r
+nbplatform.active=default\r