diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/Bundle.properties b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/Bundle.properties new file mode 100644 index 000000000..f2c93b3d3 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/Bundle.properties @@ -0,0 +1,4 @@ +MatParamTopComponent.jScrollPane2.TabConstraints.tabTitle=Parameters +MatParamTopComponent.jScrollPane3.TabConstraints.tabTitle=Render states +MatParamTopComponent.jScrollPane3.TabConstraints.tabToolTip=Material parameters +MatParamTopComponent.jScrollPane2.TabConstraints.tabToolTip=Additional render states diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/EditableMatDefFile.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/EditableMatDefFile.java new file mode 100644 index 000000000..f3325bfc8 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/EditableMatDefFile.java @@ -0,0 +1,264 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition; + +import com.jme3.asset.AssetKey; +import com.jme3.asset.MaterialKey; +import com.jme3.gde.core.assets.ProjectAssetManager; +import com.jme3.gde.core.scene.SceneApplication; +import com.jme3.gde.materialdefinition.fileStructure.MatDefBlock; +import com.jme3.gde.materialdefinition.fileStructure.ShaderNodeBlock; +import com.jme3.gde.materialdefinition.fileStructure.TechniqueBlock; +import com.jme3.gde.materialdefinition.fileStructure.UberStatement; +import com.jme3.gde.materialdefinition.fileStructure.leaves.InputMappingBlock; +import com.jme3.gde.materialdefinition.fileStructure.leaves.LeafStatement; +import com.jme3.gde.materialdefinition.fileStructure.leaves.OutputMappingBlock; +import com.jme3.gde.materialdefinition.navigator.node.MatDefNode; +import com.jme3.material.MatParam; +import com.jme3.material.Material; +import com.jme3.material.MaterialDef; +import com.jme3.material.plugins.J3MLoader; +import com.jme3.shader.Glsl100ShaderGenerator; +import com.jme3.shader.Glsl150ShaderGenerator; +import com.jme3.shader.Shader; +import com.jme3.shader.ShaderGenerator; +import com.jme3.util.blockparser.BlockLanguageParser; +import com.jme3.util.blockparser.Statement; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.text.BadLocationException; +import javax.swing.text.SimpleAttributeSet; +import javax.swing.text.StyledDocument; +import org.openide.cookies.EditorCookie; +import org.openide.explorer.ExplorerManager; +import org.openide.filesystems.FileLock; +import org.openide.filesystems.FileObject; +import org.openide.nodes.Node; +import org.openide.text.NbDocument; +import org.openide.util.Exceptions; +import org.openide.util.Lookup; +import org.openide.util.WeakListeners; + +/** + * + * @author Nehon + */ +public class EditableMatDefFile { + + private FileObject matDefFile; + private MatDefDataObject obj; + private Material material; + private MatDefBlock matDefStructure; + private TechniqueBlock currentTechnique; + private MaterialDef materialDef; + private ProjectAssetManager assetManager; +// MatParamTopComponent matParamComponent; + private ShaderGenerator glsl100; + private ShaderGenerator glsl150; + private String selectedTechnique = "Default"; + private final static String GLSL100 = "GLSL100"; + private final static String GLSL150 = "GLSL150"; + private Lookup lookup; + + public EditableMatDefFile(Lookup lookup) { + obj = lookup.lookup(MatDefDataObject.class); + + this.matDefFile = obj.getPrimaryFile(); + this.assetManager = lookup.lookup(ProjectAssetManager.class); + this.glsl100 = new Glsl100ShaderGenerator(assetManager); + this.glsl150 = new Glsl150ShaderGenerator(assetManager); + this.lookup = lookup; + + materialDef = null; + matDefStructure = null; + FileLock lock = null; + + try { + lock = matDefFile.lock(); + List sta = BlockLanguageParser.parse(obj.getPrimaryFile().getInputStream()); + matDefStructure = new MatDefBlock(sta.get(0)); + // System.err.println(block.toString()); + materialDef = (MaterialDef) assetManager.loadAsset(assetManager.getRelativeAssetPath(matDefFile.getPath())); + lock.releaseLock(); + } catch (Exception ex) { + Exceptions.printStackTrace(ex); + } finally { + if (lock != null) { + lock.releaseLock(); + } + } + if (materialDef != null) { + currentTechnique = matDefStructure.getTechniques().get(0); + registerListener(matDefStructure); + obj.getLookupContents().add(matDefStructure); + updateLookupWithMaterialData(obj); + } + + } + + private void registerListener(Statement sta) { + if (sta instanceof UberStatement) { + ((UberStatement) sta).addPropertyChangeListener(WeakListeners.propertyChange(changeListener, ((UberStatement) sta))); + } else if (sta instanceof LeafStatement) { + ((LeafStatement) sta).addPropertyChangeListener(WeakListeners.propertyChange(changeListener, ((LeafStatement) sta))); + } + if (sta.getContents() != null) { + for (Statement statement : sta.getContents()) { + registerListener(statement); + } + } + } + + public void buildOverview(ExplorerManager mgr) { + if (materialDef != null) { + mgr.setRootContext(new MatDefNode(lookup)); + + } else { + mgr.setRootContext(Node.EMPTY); + } + } + + public String getShaderCode(String version, Shader.ShaderType type) { + try { + material.selectTechnique("Default", SceneApplication.getApplication().getRenderManager()); + Shader s = null; + if (version.equals(GLSL100)) { + s = glsl100.generateShader(material.getActiveTechnique()); + } else { + s = glsl150.generateShader(material.getActiveTechnique()); + } + for (Iterator it = s.getSources().iterator(); it.hasNext();) { + Shader.ShaderSource source = it.next(); + if (source.getType() == type) { + return source.getSource(); + } + } + return ""; + } catch (Exception e) { + Exceptions.printStackTrace(e); + return "error generating shader " + e.getMessage(); + } + } + +// public MatParamTopComponent getMatParamComponent() { +// return matParamComponent; +// } +// +// public void setMatParamComponent(MatParamTopComponent matParamComponent) { +// this.matParamComponent = matParamComponent; +// } + public TechniqueBlock getCurrentTechnique() { + return currentTechnique; + } + + public MatDefBlock getMatDefStructure() { + return matDefStructure; + } + private MatStructChangeListener changeListener = new MatStructChangeListener(); + J3MLoader loader = new J3MLoader(); + + private void updateLookupWithMaterialData(MatDefDataObject obj) { + obj.getLookupContents().add(materialDef); + material = new Material(materialDef); + + try { + material.selectTechnique("Default", SceneApplication.getApplication().getRenderManager()); + if (matToRemove != null) { + for (MatParam matParam : matToRemove.getParams()) { + material.setParam(matParam.getName(), matParam.getVarType(), matParam.getValue()); + } + obj.getLookupContents().remove(matToRemove); + matToRemove = null; + } + obj.getLookupContents().add(material); + } catch (Exception e) { + Logger.getLogger(EditableMatDefFile.class.getName()).log(Level.WARNING, "Error making material {0}", e.getMessage()); + material = matToRemove; + } + } + + private class MatStructChangeListener implements PropertyChangeListener { + + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getSource() instanceof ShaderNodeBlock && evt.getPropertyName().equals("name")) { + String oldValue = (String) evt.getOldValue(); + String newValue = (String) evt.getNewValue(); + for (ShaderNodeBlock shaderNodeBlock : currentTechnique.getShaderNodes()) { + List lin = shaderNodeBlock.getInputs(); + if (lin != null) { + for (InputMappingBlock inputMappingBlock : shaderNodeBlock.getInputs()) { + if (inputMappingBlock.getLeftNameSpace().equals(oldValue)) { + inputMappingBlock.setLeftNameSpace(newValue); + } + if (inputMappingBlock.getRightNameSpace().equals(oldValue)) { + inputMappingBlock.setRightNameSpace(newValue); + } + } + } + List l = shaderNodeBlock.getOutputs(); + if (l != null) { + for (OutputMappingBlock outputMappingBlock : l) { + if (outputMappingBlock.getRightNameSpace().equals(oldValue)) { + outputMappingBlock.setRightNameSpace(newValue); + } + } + } + } + } + if (evt.getPropertyName().equals(MatDefBlock.ADD_MAT_PARAM) + || evt.getPropertyName().equals(TechniqueBlock.ADD_SHADER_NODE) + || evt.getPropertyName().equals(ShaderNodeBlock.ADD_MAPPING)) { + registerListener((Statement) evt.getNewValue()); + } + applyChange(); + } + } + Material matToRemove; + + private void applyChange() { + + try { + EditorCookie ec = (EditorCookie) lookup.lookup(EditorCookie.class); + final StyledDocument doc = ec.getDocument(); + final BadLocationException[] exc = new BadLocationException[]{null}; + NbDocument.runAtomicAsUser(ec.getDocument(), new Runnable() { + public void run() { + try { + doc.remove(0, doc.getLength()); + doc.insertString(doc.getLength(), + matDefStructure.toString(), + SimpleAttributeSet.EMPTY); + } catch (BadLocationException e) { + exc[0] = e; + } + } + }); + } catch (BadLocationException ex) { + Exceptions.printStackTrace(ex); + } + AssetKey key = new AssetKey(assetManager.getRelativeAssetPath(matDefFile.getPath())); + obj.getLookupContents().remove(materialDef); + matToRemove = material; + + List l = new ArrayList(); + l.add(matDefStructure); + try { + materialDef = loader.loadMaterialDef(l, assetManager, key); + } catch (IOException ex) { + Logger.getLogger(EditableMatDefFile.class.getName()).log(Level.SEVERE, ex.getMessage()); + } + updateLookupWithMaterialData(obj); + AssetKey matDefKey = new AssetKey(assetManager.getRelativeAssetPath(assetManager.getRelativeAssetPath(matDefFile.getPath()))); + assetManager.deleteFromCache(matDefKey); + + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/MatDef.j3md b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/MatDef.j3md new file mode 100644 index 000000000..a58ac63d8 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/MatDef.j3md @@ -0,0 +1,34 @@ +MaterialDef Simple { + MaterialParameters { + Color Color + } + Technique { + WorldParameters { + WorldViewProjectionMatrix + } + VertexShaderNodes { + ShaderNode CommonVert { + Definition : CommonVert : Common/MatDefs/ShaderNodes/Common/CommonVert.j3sn + InputMappings { + worldViewProjectionMatrix = WorldParam.WorldViewProjectionMatrix + modelPosition = Global.position.xyz + } + OutputMappings { + Global.position = projPosition + } + } + } + FragmentShaderNodes { + ShaderNode ColorMult { + Definition : ColorMult : Common/MatDefs/ShaderNodes/Basic/ColorMult.j3sn + InputMappings { + color1 = MatParam.Color + color2 = Global.color + } + OutputMappings { + Global.color = outColor + } + } + } + } +} \ No newline at end of file diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/MatDefDataObject.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/MatDefDataObject.java new file mode 100644 index 000000000..0e4fae611 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/MatDefDataObject.java @@ -0,0 +1,309 @@ +/* + * Copyright (c) 2009-2010 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.jme3.gde.materialdefinition; + +import com.jme3.gde.core.assets.ProjectAssetManager; +import com.jme3.gde.materialdefinition.navigator.MatDefNavigatorPanel; +import java.io.IOException; +import org.netbeans.api.project.Project; +import org.netbeans.api.project.ProjectManager; +import org.netbeans.core.spi.multiview.MultiViewElement; +import org.netbeans.core.spi.multiview.text.MultiViewEditorElement; +import org.openide.awt.ActionID; +import org.openide.awt.ActionReference; +import org.openide.awt.ActionReferences; +import org.openide.cookies.SaveCookie; +import org.openide.filesystems.FileChangeAdapter; +import org.openide.filesystems.FileChangeListener; +import org.openide.filesystems.FileEvent; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.MIMEResolver; +import org.openide.loaders.DataFolder; +import org.openide.loaders.DataObject; +import org.openide.loaders.DataObjectExistsException; +import org.openide.loaders.MultiDataObject; +import org.openide.loaders.MultiFileLoader; +import org.openide.util.Lookup; +import org.openide.util.NbBundle.Messages; +import org.openide.util.lookup.AbstractLookup; +import org.openide.util.lookup.InstanceContent; +import org.openide.util.lookup.ProxyLookup; +import org.openide.windows.TopComponent; + +@Messages({ + "LBL_MatDef_LOADER=JME Material definition" +}) +@MIMEResolver.ExtensionRegistration( + displayName = "#LBL_MatDef_LOADER", +mimeType = "text/jme-materialdefinition", +extension = {"j3md", "J3MD"}) +@DataObject.Registration( + mimeType = "text/jme-materialdefinition", +iconBase = "com/jme3/gde/materialdefinition/icons/matdef.png", +displayName = "#LBL_MatDef_LOADER", +position = 300) +@ActionReferences({ + @ActionReference( + path = "Loaders/text/jme-materialdefinition/Actions", + id = + @ActionID(category = "System", id = "org.openide.actions.OpenAction"), + position = 100, + separatorAfter = 200), + @ActionReference( + path = "Loaders/text/jme-materialdefinition/Actions", + id = + @ActionID(category = "Edit", id = "org.openide.actions.CutAction"), + position = 300), + @ActionReference( + path = "Loaders/text/jme-materialdefinition/Actions", + id = + @ActionID(category = "Edit", id = "org.openide.actions.CopyAction"), + position = 400, + separatorAfter = 500), + @ActionReference( + path = "Loaders/text/jme-materialdefinition/Actions", + id = + @ActionID(category = "Edit", id = "org.openide.actions.DeleteAction"), + position = 600), + @ActionReference( + path = "Loaders/text/jme-materialdefinition/Actions", + id = + @ActionID(category = "System", id = "org.openide.actions.RenameAction"), + position = 700, + separatorAfter = 800), + @ActionReference( + path = "Loaders/text/jme-materialdefinition/Actions", + id = + @ActionID(category = "System", id = "org.openide.actions.SaveAsTemplateAction"), + position = 900, + separatorAfter = 1000), + @ActionReference( + path = "Loaders/text/jme-materialdefinition/Actions", + id = + @ActionID(category = "System", id = "org.openide.actions.FileSystemAction"), + position = 1100, + separatorAfter = 1200), + @ActionReference( + path = "Loaders/text/jme-materialdefinition/Actions", + id = + @ActionID(category = "System", id = "org.openide.actions.ToolsAction"), + position = 1300), + @ActionReference( + path = "Loaders/text/jme-materialdefinition/Actions", + id = + @ActionID(category = "System", id = "org.openide.actions.PropertiesAction"), + position = 1400) +}) +public class MatDefDataObject extends MultiDataObject { + + protected final Lookup lookup; + protected final InstanceContent lookupContents = new InstanceContent(); + protected AbstractLookup contentLookup; + private EditableMatDefFile file = null; + private boolean loaded = false; + + public MatDefDataObject(FileObject pf, MultiFileLoader loader) throws DataObjectExistsException, IOException { + super(pf, loader); + registerEditor("text/jme-materialdefinition", true); + contentLookup = new AbstractLookup(lookupContents); + lookupContents.add(this); + lookup = new ProxyLookup(getCookieSet().getLookup(), contentLookup); + findAssetManager(); + final MatDefMetaData metaData = new MatDefMetaData(this); + lookupContents.add(metaData); + pf.addFileChangeListener(new FileChangeAdapter(){ + + @Override + public void fileChanged(FileEvent fe) { + super.fileChanged(fe); + metaData.save(); + } + + }); + + } + + private void findAssetManager() { + FileObject primaryFile = getPrimaryFile(); + ProjectManager pm = ProjectManager.getDefault(); + while (primaryFile != null) { + if (primaryFile.isFolder() && pm.isProject(primaryFile)) { + try { + Project project = ProjectManager.getDefault().findProject(primaryFile); + if (project != null) { + getLookupContents().add(project); + ProjectAssetManager mgr = project.getLookup().lookup(ProjectAssetManager.class); + if (mgr != null) { + getLookupContents().add(mgr); + return; + } + } + } catch (IOException ex) { + } catch (IllegalArgumentException ex) { + } + } + primaryFile = primaryFile.getParent(); + } +// getLookupContents().add(new ProjectAssetManager(file.getParent())); + } + + @Override + protected int associateLookup() { + return 1; + } + + @Override + public Lookup getLookup() { + return lookup; + } + + @MultiViewElement.Registration( + displayName = "#LBL_MatDef_EDITOR", + iconBase = "com/jme3/gde/materialdefinition/icons/matdef.png", + mimeType = "text/jme-materialdefinition", + persistenceType = TopComponent.PERSISTENCE_ONLY_OPENED, + preferredID = "MatDef", + position = 1000) + @Messages("LBL_MatDef_EDITOR=Text") + public static MultiViewEditorElement createEditor(Lookup lkp) { + final MatDefDataObject obj = lkp.lookup(MatDefDataObject.class); + obj.loaded = true; + MatDefNavigatorPanel nav = obj.getLookup().lookup(MatDefNavigatorPanel.class); + if (nav != null) { + nav.updateData(obj); + } + MultiViewEditorElement ed = new MultiViewEditorElement(lkp) { + @Override + public void componentClosed() { + super.componentClosed(); + obj.unload(); + } + }; + + + return ed; + } + + @Override + protected void handleDelete() throws IOException { + MatDefMetaData metaData = lookup.lookup(MatDefMetaData.class); + metaData.cleanup(); + super.handleDelete(); + } + + @Override + protected FileObject handleRename(String name) throws IOException { + MatDefMetaData metaData = lookup.lookup(MatDefMetaData.class); + metaData.rename(null, name); + return super.handleRename(name); + } + + @Override + protected FileObject handleMove(DataFolder df) throws IOException { + MatDefMetaData metaData = lookup.lookup(MatDefMetaData.class); + metaData.rename(df, null); + return super.handleMove(df); + } + + @Override + protected DataObject handleCopy(DataFolder df) throws IOException { + MatDefMetaData metaData = lookup.lookup(MatDefMetaData.class); + metaData.duplicate(df, null); + return super.handleCopy(df); + } + + @Override + protected DataObject handleCopyRename(DataFolder df, String name, String ext) throws IOException { + MatDefMetaData metaData = lookup.lookup(MatDefMetaData.class); + metaData.duplicate(df, name); + return super.handleCopyRename(df, name, ext); + } + + + + + + public EditableMatDefFile getEditableFile() { + if (file == null) { + file = new EditableMatDefFile(getLookup()); + } + + return file; + } + + public boolean isLoaded() { + return loaded; + } + + public void unload() { + if (loaded) { + loaded = false; + getLookup().lookup(MatDefNavigatorPanel.class).updateData(null); + } + } + + public InstanceContent getLookupContents() { + return lookupContents; + } +// @Override +// public synchronized void saveAsset() throws IOException { +// +//// ProgressHandle progressHandle = ProgressHandleFactory.createHandle("Saving File.."); +//// progressHandle.start(); +// // BinaryExporter exp = BinaryExporter.getInstance(); +// FileLock lock = null; +// OutputStream out = null; +// try { +// PrintWriter to = new PrintWriter(getPrimaryFile().getOutputStream(lock)); +// try { +// to.print(getEditableFile().getMatDefStructure().toString()); +// +// } finally { +// to.close(); +// } +// } finally { +// if (lock != null) { +// lock.releaseLock(); +// } +// if (out != null) { +// out.close(); +// } +// } +// // progressHandle.finish(); +// StatusDisplayer.getDefault().setStatusText(getPrimaryFile().getNameExt() + " saved."); +// setModified(false); +// +//// getPrimaryFile(). +//// getOutputStream().write(getEditableFile().getMatDefStructure().toString().getBytes()); +// +// } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/MatDefMetaData.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/MatDefMetaData.java new file mode 100644 index 000000000..5193186b2 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/MatDefMetaData.java @@ -0,0 +1,398 @@ +/* + * Copyright (c) 2009-2010 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.jme3.gde.materialdefinition; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.io.BufferedOutputStream; +import java.io.BufferedInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Date; +import java.util.Iterator; +import java.util.List; +import java.util.Properties; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.netbeans.api.project.Project; +import org.openide.filesystems.FileLock; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileUtil; +import org.openide.loaders.DataFolder; +import org.openide.util.Exceptions; +import org.openide.util.Mutex; +import org.openide.util.Mutex.Action; + +/** + * Global object to access actual jME3 data within an AssetDataObject, available + * through the Lookup of any AssetDataObject. AssetDataObjects that wish to use + * + * @author normenhansen + */ +@SuppressWarnings("unchecked") +public class MatDefMetaData { + + private static final Logger logger = Logger.getLogger(MatDefMetaData.class.getName()); + private final List listeners = new ArrayList(); + private final Mutex propsMutex = new Mutex(); + private final Properties props = new Properties(); + private static final Properties defaultProps = new Properties(); + + static { + defaultProps.put("Default/position", "0,120"); + defaultProps.put("Default/MatParam.Color", "438,351"); + defaultProps.put("Default/Default/ColorMult", "605,372"); + defaultProps.put("Default/WorldParam.WorldViewProjectionMatrix", "33,241"); + defaultProps.put("Default/color", "0,478"); + defaultProps.put("Default/Default/CommonVert", "211,212"); + } + private MatDefDataObject file; + private String extension = "jmpdata"; + private Date lastLoaded; + private FileObject folder; + private FileObject root; + +// private XMLFileSystem fs; + public MatDefMetaData(MatDefDataObject file) { + try { + this.file = file; + getFolder(); + FileObject primaryFile = file.getPrimaryFile(); + + if (primaryFile != null) { + extension = primaryFile.getExt() + "data"; + } + + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + } + } + + public MatDefMetaData(MatDefDataObject file, String extension) { + this.file = file; + this.extension = extension; + } + + public synchronized String getProperty(final String key) { + readProperties(); + return propsMutex.readAccess(new Action() { + public String run() { + String prop = props.getProperty(key); + if (prop == null) { + return defaultProps.getProperty(key); + } + return prop; + } + }); + } + + public synchronized String getProperty(final String key, final String defaultValue) { + readProperties(); + return propsMutex.readAccess(new Action() { + public String run() { + String prop = props.getProperty(key); + if (prop == null) { + return defaultProps.getProperty(key); + } + return prop; + } + }); + } + + public synchronized String setProperty(final String key, final String value) { + readProperties(); + String ret = propsMutex.writeAccess(new Action() { + public String run() { + String ret = (String) props.setProperty(key, value); + return ret; + } + }); + // writeProperties(); + notifyListeners(key, ret, value); + return ret; + } + + private void readProperties() { + propsMutex.writeAccess(new Runnable() { + public void run() { + try { + FileObject pFile = file.getPrimaryFile(); + FileObject storageFolder = getFolder(); + if (storageFolder == null) { + return; + } + final FileObject myFile = storageFolder.getFileObject(getFileFullName(pFile)); //fs.findResource(fs.getRoot().getPath()+"/"+ file.getPrimaryFile().getName() + "." + extension);// + + if (myFile == null) { + return; + } + final Date lastMod = myFile.lastModified(); + if (!lastMod.equals(lastLoaded)) { + props.clear(); + lastLoaded = lastMod; + InputStream in = null; + try { + in = new BufferedInputStream(myFile.getInputStream()); + try { + props.load(in); + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + } + } catch (FileNotFoundException ex) { + Exceptions.printStackTrace(ex); + } finally { + try { + in.close(); + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + } + } + logger.log(Level.FINE, "Read AssetData properties for {0}", file); + } + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + } + } + }); + } + + public void cleanup() { + propsMutex.writeAccess(new Runnable() { + public void run() { + OutputStream out = null; + FileLock lock = null; + try { + FileObject pFile = file.getPrimaryFile(); + FileObject storageFolder = getFolder(); + if (storageFolder == null) { + return; + } + + FileObject myFile = storageFolder.getFileObject(getFileFullName(pFile));//FileUtil.findBrother(pFile, extension);//fs.findResource(fs.getRoot().getPath()+"/"+ pFile.getName() + "." + extension);// + if (myFile == null) { + return; + } + lock = myFile.lock(); + myFile.delete(lock); + } catch (IOException e) { + Exceptions.printStackTrace(e); + } finally { + if (out != null) { + try { + out.close(); + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + } + } + if (lock != null) { + lock.releaseLock(); + } + } + } + }); + + } + + public void rename(final DataFolder df, final String name) { + propsMutex.writeAccess(new Runnable() { + public void run() { + OutputStream out = null; + FileLock lock = null; + try { + FileObject pFile = file.getPrimaryFile(); + FileObject storageFolder = getFolder(); + if (storageFolder == null) { + return; + } + + FileObject myFile = storageFolder.getFileObject(getFileFullName(pFile));//FileUtil.findBrother(pFile, extension);//fs.findResource(fs.getRoot().getPath()+"/"+ pFile.getName() + "." + extension);// + if (myFile == null) { + return; + } + lock = myFile.lock(); + if (df == null) { + myFile.rename(lock, getFileFullName(pFile).replaceAll(file.getName() + "." + extension, name + "." + extension), ""); + } else { + myFile.rename(lock, FileUtil.getRelativePath(root, df.getPrimaryFile()).replaceAll("/", ".") + "." + pFile.getName(), extension); + } + } catch (IOException e) { + Exceptions.printStackTrace(e); + } finally { + if (out != null) { + try { + out.close(); + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + } + } + if (lock != null) { + lock.releaseLock(); + } + } + } + }); + + } + + public void duplicate(final DataFolder df, final String name) { + propsMutex.writeAccess(new Runnable() { + public void run() { + OutputStream out = null; + FileLock lock = null; + try { + FileObject pFile = file.getPrimaryFile(); + FileObject storageFolder = getFolder(); + if (storageFolder == null) { + return; + } + String newName = name; + if (newName == null) { + newName = file.getName(); + } + String path = FileUtil.getRelativePath(root, df.getPrimaryFile()).replaceAll("/", ".") + "." + newName; + FileObject myFile = storageFolder.getFileObject(getFileFullName(pFile)); + if (myFile == null) { + return; + } + + myFile.copy(storageFolder, path, extension); + + } catch (IOException e) { + Exceptions.printStackTrace(e); + } finally { + if (out != null) { + try { + out.close(); + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + } + } + if (lock != null) { + lock.releaseLock(); + } + } + } + }); + + } + + public void save(){ + writeProperties(); + } + + private void writeProperties() { + //writeAccess because we write lastMod date, not because we write to the file + //the mutex protects the properties object, not the file + propsMutex.writeAccess(new Runnable() { + public void run() { + OutputStream out = null; + FileLock lock = null; + try { + FileObject pFile = file.getPrimaryFile(); + FileObject storageFolder = getFolder(); + if (storageFolder == null) { + return; + } + + FileObject myFile = storageFolder.getFileObject(getFileFullName(pFile));//FileUtil.findBrother(pFile, extension);//fs.findResource(fs.getRoot().getPath()+"/"+ pFile.getName() + "." + extension);// + if (myFile == null) { + myFile = FileUtil.createData(storageFolder, getFileFullName(pFile)); + } + lock = myFile.lock(); + out = new BufferedOutputStream(myFile.getOutputStream(lock)); + props.store(out, ""); + out.flush(); + lastLoaded = myFile.lastModified(); + logger.log(Level.FINE, "Written AssetData properties for {0}", file); + } catch (IOException e) { + Exceptions.printStackTrace(e); + } finally { + if (out != null) { + try { + out.close(); + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + } + } + if (lock != null) { + lock.releaseLock(); + } + } + } + }); + } + + private String getFileFullName(FileObject pFile) { + return FileUtil.getRelativePath(root, pFile).replaceAll("/", ".").replaceAll("j3md", extension); + } + + protected void notifyListeners(String property, String before, String after) { + synchronized (listeners) { + for (Iterator it = listeners.iterator(); it.hasNext();) { + PropertyChangeListener propertyChangeListener = it.next(); + propertyChangeListener.propertyChange(new PropertyChangeEvent(this, property, before, after)); + } + } + } + + public void addPropertyChangeListener(PropertyChangeListener listener) { + synchronized (listeners) { + listeners.add(listener); + } + } + + public void removePropertyChangeListener(PropertyChangeListener listener) { + synchronized (listeners) { + listeners.remove(listener); + } + } + + private FileObject getFolder() throws IOException { + if (folder == null) { + Project p = file.getLookup().lookup(Project.class); + if (p != null) { + root = p.getProjectDirectory(); + + FileObject jmedataFolder = root.getFileObject("/nbproject/jme3Data"); + if (jmedataFolder == null) { + jmedataFolder = root.getFileObject("/nbproject"); + jmedataFolder = jmedataFolder.createFolder("jme3Data"); + } + return jmedataFolder; + } + } + return folder; + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/dialog/AddAttributeDialog.form b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/dialog/AddAttributeDialog.form new file mode 100644 index 000000000..f5bb8c5de --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/dialog/AddAttributeDialog.form @@ -0,0 +1,135 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/dialog/AddAttributeDialog.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/dialog/AddAttributeDialog.java new file mode 100644 index 000000000..3e815e0f2 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/dialog/AddAttributeDialog.java @@ -0,0 +1,196 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.dialog; + +import com.jme3.gde.materialdefinition.editor.Diagram; +import com.jme3.scene.VertexBuffer; +import com.jme3.shader.UniformBinding; +import java.awt.Point; +import javax.swing.DefaultComboBoxModel; + +/** + * + * @author Nehon + */ +public class AddAttributeDialog extends javax.swing.JDialog { + + private Diagram diagram; + private Point clickPosition; + + /** + * Creates new form AddMaterialParameter + */ + public AddAttributeDialog(java.awt.Frame parent, boolean modal, Diagram diagram, Point clickPosition) { + super(parent, modal); + initComponents(); + DefaultComboBoxModel model = new DefaultComboBoxModel(); + + for (VertexBuffer.Type attr : VertexBuffer.Type.values()) { + model.addElement("in" + attr.name()); + } + this.diagram = diagram; + this.clickPosition = clickPosition; + nameField.setModel(model); + updateType(); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + jButton1 = new javax.swing.JButton(); + jButton2 = new javax.swing.JButton(); + jLabel1 = new javax.swing.JLabel(); + nameField = new javax.swing.JComboBox(); + jLabel2 = new javax.swing.JLabel(); + typeField = new javax.swing.JTextField(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setTitle(org.openide.util.NbBundle.getMessage(AddAttributeDialog.class, "AddAttributeDialog.title")); // NOI18N + setModal(true); + + org.openide.awt.Mnemonics.setLocalizedText(jButton1, org.openide.util.NbBundle.getMessage(AddAttributeDialog.class, "AddAttributeDialog.jButton1.text")); // NOI18N + jButton1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton1ActionPerformed(evt); + } + }); + + org.openide.awt.Mnemonics.setLocalizedText(jButton2, org.openide.util.NbBundle.getMessage(AddAttributeDialog.class, "AddAttributeDialog.jButton2.text")); // NOI18N + jButton2.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton2ActionPerformed(evt); + } + }); + + jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING); + org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(AddAttributeDialog.class, "AddAttributeDialog.jLabel1.text")); // NOI18N + + nameField.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" })); + nameField.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + nameFieldActionPerformed(evt); + } + }); + + org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(AddAttributeDialog.class, "AddAttributeDialog.jLabel2.text")); // NOI18N + + typeField.setText(org.openide.util.NbBundle.getMessage(AddAttributeDialog.class, "AddAttributeDialog.typeField.text")); // NOI18N + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addComponent(jButton2) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jButton1)) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jLabel2) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 123, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(nameField, 0, 253, Short.MAX_VALUE) + .addComponent(typeField)))) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1) + .addComponent(nameField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel2) + .addComponent(typeField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jButton1) + .addComponent(jButton2)) + .addContainerGap()) + ); + + pack(); + }// //GEN-END:initComponents + + private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed + setVisible(false); + }//GEN-LAST:event_jButton2ActionPerformed + + private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed + diagram.addAttribute((String) nameField.getSelectedItem(), typeField.getText(), clickPosition); + setVisible(false); + }//GEN-LAST:event_jButton1ActionPerformed + + private void nameFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_nameFieldActionPerformed + updateType(); + } + + private void updateType() { + VertexBuffer.Type attr = VertexBuffer.Type.valueOf(((String) nameField.getSelectedItem()).replaceFirst("in", "")); + switch (attr) { + + case BoneWeight: + + case BindPoseNormal: + case Binormal: + + case Normal: + typeField.setText("vec3"); + break; + + case Size: + typeField.setText("float"); + break; + + case Position: + case BindPosePosition: + case BindPoseTangent: + case Tangent: + case Color: + typeField.setText("vec4"); + break; + case InterleavedData: + typeField.setText("int"); + break; + case Index: + typeField.setText("uint"); + break; + case BoneIndex: + typeField.setText("uvec4"); + break; + + case TexCoord: + case TexCoord2: + case TexCoord3: + case TexCoord4: + case TexCoord5: + case TexCoord6: + case TexCoord7: + case TexCoord8: + typeField.setText("vec2"); + break; + } + }//GEN-LAST:event_nameFieldActionPerformed + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jButton1; + private javax.swing.JButton jButton2; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JComboBox nameField; + private javax.swing.JTextField typeField; + // End of variables declaration//GEN-END:variables +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/dialog/AddMaterialParameterDialog.form b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/dialog/AddMaterialParameterDialog.form new file mode 100644 index 000000000..4fecca682 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/dialog/AddMaterialParameterDialog.form @@ -0,0 +1,135 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/dialog/AddMaterialParameterDialog.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/dialog/AddMaterialParameterDialog.java new file mode 100644 index 000000000..d185aca53 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/dialog/AddMaterialParameterDialog.java @@ -0,0 +1,161 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.dialog; + +import com.jme3.gde.materialdefinition.editor.Diagram; +import com.jme3.shader.VarType; +import java.awt.Point; +import java.awt.event.KeyEvent; +import javax.swing.DefaultComboBoxModel; + +/** + * + * @author Nehon + */ +public class AddMaterialParameterDialog extends javax.swing.JDialog { + + private Diagram diagram; + private Point clickPosition; + + /** + * Creates new form AddMaterialParameter + */ + public AddMaterialParameterDialog(java.awt.Frame parent, boolean modal, Diagram diagram, Point clickPosition) { + super(parent, modal); + initComponents(); + DefaultComboBoxModel model = new DefaultComboBoxModel(); + model.addElement("Color"); + for (VarType varType : VarType.values()) { + + model.addElement(varType.name()); + } + this.diagram = diagram; + this.clickPosition = clickPosition; + typeField.setModel(model); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + jButton1 = new javax.swing.JButton(); + jButton2 = new javax.swing.JButton(); + jLabel1 = new javax.swing.JLabel(); + typeField = new javax.swing.JComboBox(); + jLabel3 = new javax.swing.JLabel(); + nameField = new javax.swing.JTextField(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setTitle(org.openide.util.NbBundle.getMessage(AddMaterialParameterDialog.class, "AddMaterialParameterDialog.title")); // NOI18N + setModal(true); + + org.openide.awt.Mnemonics.setLocalizedText(jButton1, org.openide.util.NbBundle.getMessage(AddMaterialParameterDialog.class, "AddMaterialParameterDialog.jButton1.text")); // NOI18N + jButton1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton1ActionPerformed(evt); + } + }); + + org.openide.awt.Mnemonics.setLocalizedText(jButton2, org.openide.util.NbBundle.getMessage(AddMaterialParameterDialog.class, "AddMaterialParameterDialog.jButton2.text")); // NOI18N + jButton2.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton2ActionPerformed(evt); + } + }); + + jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING); + org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(AddMaterialParameterDialog.class, "AddMaterialParameterDialog.jLabel1.text")); // NOI18N + + typeField.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" })); + + org.openide.awt.Mnemonics.setLocalizedText(jLabel3, org.openide.util.NbBundle.getMessage(AddMaterialParameterDialog.class, "AddMaterialParameterDialog.jLabel3.text")); // NOI18N + + nameField.setText(org.openide.util.NbBundle.getMessage(AddMaterialParameterDialog.class, "AddMaterialParameterDialog.nameField.text")); // NOI18N + nameField.addKeyListener(new java.awt.event.KeyAdapter() { + public void keyPressed(java.awt.event.KeyEvent evt) { + nameFieldKeyPressed(evt); + } + }); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addComponent(jButton2) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jButton1)) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jLabel3) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 123, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(typeField, 0, 253, Short.MAX_VALUE) + .addComponent(nameField)))) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1) + .addComponent(typeField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel3) + .addComponent(nameField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 23, Short.MAX_VALUE) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jButton1) + .addComponent(jButton2)) + .addContainerGap()) + ); + + pack(); + }// //GEN-END:initComponents + + private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed + setVisible(false); + }//GEN-LAST:event_jButton2ActionPerformed + + private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed + okPressed(); + }//GEN-LAST:event_jButton1ActionPerformed + + private void nameFieldKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_nameFieldKeyPressed + if (evt.getKeyCode() == KeyEvent.VK_ENTER) { + okPressed(); + } + }//GEN-LAST:event_nameFieldKeyPressed + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jButton1; + private javax.swing.JButton jButton2; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel3; + private javax.swing.JTextField nameField; + private javax.swing.JComboBox typeField; + // End of variables declaration//GEN-END:variables + + private void okPressed() { + String name = nameField.getText(); + if (name.length() > 1) { + name = name.substring(0, 1).toUpperCase() + name.substring(1); + } else { + name = name.toUpperCase(); + } + diagram.addMatParam((String) typeField.getSelectedItem(), name, clickPosition); + setVisible(false); + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/dialog/AddNodeDialog.form b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/dialog/AddNodeDialog.form new file mode 100644 index 000000000..4cbf6d625 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/dialog/AddNodeDialog.form @@ -0,0 +1,167 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/dialog/AddNodeDialog.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/dialog/AddNodeDialog.java new file mode 100644 index 000000000..cb9602553 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/dialog/AddNodeDialog.java @@ -0,0 +1,254 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.dialog; + +import com.jme3.asset.ShaderNodeDefinitionKey; +import com.jme3.gde.core.assets.ProjectAssetManager; +import com.jme3.gde.core.util.TreeUtil; +import com.jme3.gde.materialdefinition.editor.Diagram; +import com.jme3.gde.materialdefinition.editor.NodePanel; +import com.jme3.gde.materialdefinition.fileStructure.ShaderNodeBlock; +import com.jme3.gde.materialdefinition.icons.Icons; +import com.jme3.gde.materialdefinition.utils.DocFormatter; +import com.jme3.shader.Shader; +import com.jme3.shader.ShaderNodeDefinition; +import java.awt.Point; +import java.awt.event.KeyEvent; +import java.util.ArrayList; +import java.util.List; +import javax.swing.JScrollPane; +import javax.swing.JTextPane; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.TreeNode; +import javax.swing.tree.TreeSelectionModel; + +/** + * + * @author m327836 + */ +public class AddNodeDialog extends javax.swing.JDialog { + + private List defList = new ArrayList(); + private Diagram diagram; + private Point clickPosition; + private String path; + + /** + * Creates new form NewJDialog + */ + public AddNodeDialog(java.awt.Frame parent, boolean modal, ProjectAssetManager mgr, Diagram diagram, Point clickPosition) { + super(parent, modal); + this.diagram = diagram; + initComponents(); + loadDefs(mgr); + fillList(mgr); + this.clickPosition = clickPosition; + + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + jPanel2 = new javax.swing.JPanel(); + jButton1 = new javax.swing.JButton(); + jButton2 = new javax.swing.JButton(); + jSplitPane1 = new javax.swing.JSplitPane(); + jPanel1 = new javax.swing.JPanel(); + jScrollPane3 = new javax.swing.JScrollPane(); + jTree1 = new javax.swing.JTree(); + shaderNodesList = new javax.swing.JPanel(); + jTabbedPane1 = new javax.swing.JTabbedPane(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setTitle("Add a Shader Node"); + setModal(true); + + jButton1.setText("ok"); + jButton1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton1ActionPerformed(evt); + } + }); + + jButton2.setMnemonic(KeyEvent.VK_ESCAPE); + jButton2.setText("cancel"); + jButton2.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton2ActionPerformed(evt); + } + }); + + javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); + jPanel2.setLayout(jPanel2Layout); + jPanel2Layout.setHorizontalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jButton2) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jButton1) + .addContainerGap()) + ); + jPanel2Layout.setVerticalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jButton1) + .addComponent(jButton2)) + ); + + jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Shader node definitions")); + + jScrollPane3.setViewportView(jTree1); + + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); + jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 236, Short.MAX_VALUE) + ); + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 468, Short.MAX_VALUE) + ); + + jSplitPane1.setLeftComponent(jPanel1); + + shaderNodesList.setBorder(javax.swing.BorderFactory.createTitledBorder("Shader node definition")); + + javax.swing.GroupLayout shaderNodesListLayout = new javax.swing.GroupLayout(shaderNodesList); + shaderNodesList.setLayout(shaderNodesListLayout); + shaderNodesListLayout.setHorizontalGroup( + shaderNodesListLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jTabbedPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 339, Short.MAX_VALUE) + ); + shaderNodesListLayout.setVerticalGroup( + shaderNodesListLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jTabbedPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 468, Short.MAX_VALUE) + ); + + jSplitPane1.setRightComponent(shaderNodesList); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jSplitPane1, javax.swing.GroupLayout.Alignment.LEADING) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jSplitPane1) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + ); + + pack(); + }// //GEN-END:initComponents + + private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed + setVisible(false); + }//GEN-LAST:event_jButton2ActionPerformed + + private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed + setVisible(false); + diagram.addNodesFromDefs(defList, path, clickPosition); + }//GEN-LAST:event_jButton1ActionPerformed + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jButton1; + private javax.swing.JButton jButton2; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JScrollPane jScrollPane3; + private javax.swing.JSplitPane jSplitPane1; + private javax.swing.JTabbedPane jTabbedPane1; + private javax.swing.JTree jTree1; + private javax.swing.JPanel shaderNodesList; + // End of variables declaration//GEN-END:variables + + private void loadDefs(ProjectAssetManager mgr) { +// defList.addAll(); +// defList.addAll(mgr.getDependenciesShaderNodeDefs()); +// List inputs = new ArrayList(); +// inputs.add(new ShaderNodeVariable("vec2", "texCoord1")); +// inputs.add(new ShaderNodeVariable("vec2", "texCoord2")); +// List outputs = new ArrayList(); +// outputs.add(new ShaderNodeVariable("vec2", "texCoord1")); +// outputs.add(new ShaderNodeVariable("vec2", "texCoord2")); +// ShaderNodeDefinition fogdef = new ShaderNodeDefinition("FogFactor", Shader.ShaderType.Vertex, "", ""); +// fogdef.setInputs(inputs); +// fogdef.setOutputs(outputs); +// fogdef.setDocumentation( +// " This Node is responsible for adding a fog contribution to a color according to a fogColor and a fogFactor.\n" +// + " This node should be used with a FogFactor node that will be responsible to compute the fogFactor in the vertex shader.\n" +// + " Inputs : \n" +// + " color : the color on which the fog contribution will be added.\n" +// + " fogFactor : the previously computed fog factor \n" +// + " fogColor : the fog color\n" +// + " Outputs : \n" +// + " outColor : the color with fog contribution (usually assigned to Global.color) "); +// +// defList.add(fogdef); + } + + private void createDoc(ShaderNodeDefinition def) { + JTextPane doc = new JTextPane(); + doc.setEditable(false); + doc.setBackground(new java.awt.Color(240, 240, 240)); + doc.setMaximumSize(new java.awt.Dimension(300, 300)); + doc.setMinimumSize(new java.awt.Dimension(300, 300)); + doc.setPreferredSize(new java.awt.Dimension(300, 300)); + JScrollPane defPanel = new JScrollPane(); + defPanel.setViewportView(doc); + + jTabbedPane1.addTab(def.getName(), def.getType() == Shader.ShaderType.Vertex ? Icons.vert : Icons.frag, defPanel); + doc.setText(""); + DocFormatter.addDoc(def, doc.getStyledDocument()); + doc.setCaretPosition(0); + } + + private void fillList(final ProjectAssetManager mgr) { + List l = new ArrayList(); + l.addAll(mgr.getProjectShaderNodeDefs()); + l.addAll(mgr.getDependenciesShaderNodeDefs()); + String[] leaves = l.toArray(new String[l.size()]); + TreeUtil.createTree(jTree1, leaves); + TreeUtil.expandTree(jTree1, (TreeNode) jTree1.getModel().getRoot(), 10); + jTree1.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); + jTree1.addTreeSelectionListener(new TreeSelectionListener() { + public void valueChanged(TreeSelectionEvent e) { + + DefaultMutableTreeNode node = (DefaultMutableTreeNode) jTree1.getLastSelectedPathComponent(); + + if (node == null) { + return; + } + + + if (node.isLeaf()) { + jTabbedPane1.removeAll(); + path = TreeUtil.getPath(node.getUserObjectPath()); + path = path.substring(0, path.lastIndexOf("/")); + ShaderNodeDefinitionKey k = new ShaderNodeDefinitionKey(path); + k.setLoadDocumentation(true); + defList = (List) mgr.loadAsset(k); + + for (ShaderNodeDefinition def : defList) { + createDoc(def); + } + + } + } + }); + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/dialog/AddWorldParameterDialog.form b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/dialog/AddWorldParameterDialog.form new file mode 100644 index 000000000..573c88aa4 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/dialog/AddWorldParameterDialog.form @@ -0,0 +1,107 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/dialog/AddWorldParameterDialog.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/dialog/AddWorldParameterDialog.java new file mode 100644 index 000000000..fa2a5f60c --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/dialog/AddWorldParameterDialog.java @@ -0,0 +1,122 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.dialog; + +import com.jme3.gde.materialdefinition.editor.Diagram; +import com.jme3.shader.UniformBinding; +import java.awt.Point; +import javax.swing.DefaultComboBoxModel; + +/** + * + * @author Nehon + */ +public class AddWorldParameterDialog extends javax.swing.JDialog { + + private Diagram diagram; + private Point clickPosition; + + /** + * Creates new form AddMaterialParameter + */ + public AddWorldParameterDialog(java.awt.Frame parent, boolean modal, Diagram diagram, Point clickPosition) { + super(parent, modal); + initComponents(); + DefaultComboBoxModel model = new DefaultComboBoxModel(); + + for (UniformBinding binding : UniformBinding.values()) { + model.addElement(binding); + } + this.diagram = diagram; + this.clickPosition = clickPosition; + nameField.setModel(model); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + jButton1 = new javax.swing.JButton(); + jButton2 = new javax.swing.JButton(); + jLabel1 = new javax.swing.JLabel(); + nameField = new javax.swing.JComboBox(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setTitle(org.openide.util.NbBundle.getMessage(AddWorldParameterDialog.class, "AddWorldParameterDialog.title")); // NOI18N + setModal(true); + + org.openide.awt.Mnemonics.setLocalizedText(jButton1, org.openide.util.NbBundle.getMessage(AddWorldParameterDialog.class, "AddWorldParameterDialog.jButton1.text")); // NOI18N + jButton1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton1ActionPerformed(evt); + } + }); + + org.openide.awt.Mnemonics.setLocalizedText(jButton2, org.openide.util.NbBundle.getMessage(AddWorldParameterDialog.class, "AddWorldParameterDialog.jButton2.text")); // NOI18N + jButton2.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton2ActionPerformed(evt); + } + }); + + jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING); + org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(AddWorldParameterDialog.class, "AddWorldParameterDialog.jLabel1.text")); // NOI18N + + nameField.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" })); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addComponent(jButton2) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jButton1)) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 123, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(nameField, 0, 253, Short.MAX_VALUE))) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1) + .addComponent(nameField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jButton1) + .addComponent(jButton2)) + .addContainerGap()) + ); + + pack(); + }// //GEN-END:initComponents + + private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed + setVisible(false); + }//GEN-LAST:event_jButton2ActionPerformed + + private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed + diagram.addWorldParam((UniformBinding) nameField.getSelectedItem(), clickPosition); + setVisible(false); + }//GEN-LAST:event_jButton1ActionPerformed + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jButton1; + private javax.swing.JButton jButton2; + private javax.swing.JLabel jLabel1; + private javax.swing.JComboBox nameField; + // End of variables declaration//GEN-END:variables +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/dialog/Bundle.properties b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/dialog/Bundle.properties new file mode 100644 index 000000000..706982093 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/dialog/Bundle.properties @@ -0,0 +1,17 @@ + +AddMaterialParameterDialog.nameField.text= +AddMaterialParameterDialog.jLabel3.text=Parameter Name +AddMaterialParameterDialog.jLabel1.text=Parameter Type +AddMaterialParameterDialog.title=Add Material Parameter +AddMaterialParameterDialog.jButton1.text=Ok +AddMaterialParameterDialog.jButton2.text=Cancel +AddWorldParameterDialog.title=Add Material Parameter +AddWorldParameterDialog.jButton1.text=Ok +AddWorldParameterDialog.jButton2.text=Cancel +AddWorldParameterDialog.jLabel1.text=Parameter Name +AddAttributeDialog.jButton2.text=Cancel +AddAttributeDialog.jLabel1.text=Attribute +AddAttributeDialog.title=Add Material Parameter +AddAttributeDialog.jButton1.text=Ok +AddAttributeDialog.jLabel2.text=GLSL Type +AddAttributeDialog.typeField.text= diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/Connection.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/Connection.java new file mode 100644 index 000000000..0503aa909 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/Connection.java @@ -0,0 +1,539 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.editor; + +import com.jme3.gde.materialdefinition.fileStructure.leaves.MappingBlock; +import com.jme3.gde.materialdefinition.utils.MaterialUtils; +import java.awt.Color; +import java.awt.Component; +import java.awt.Graphics; +import java.awt.Point; +import java.awt.event.ComponentEvent; +import java.awt.event.ComponentListener; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseWheelEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; +import javax.swing.event.MenuDragMouseEvent; +import javax.swing.event.MouseInputListener; + +/** + * + * @author Nehon + */ +public class Connection extends JPanel implements ComponentListener, MouseInputListener, KeyListener, Selectable, PropertyChangeListener { + + protected Dot start; + protected Dot end; + private Point[] points = new Point[6]; + private int pointsSize = 6; + private Corner[] corners = new Corner[6]; + private String key = ""; + protected MappingBlock mapping; + + private MouseEvent convertEvent(MouseEvent e) { + MouseEvent me = null; + //workaround for swing utilities removing mouse button when converting events. + if (e instanceof MouseWheelEvent || e instanceof MenuDragMouseEvent) { + SwingUtilities.convertMouseEvent(this, e, getDiagram()); + } else { + Point p = SwingUtilities.convertPoint(this, new Point(e.getX(), + e.getY()), + getDiagram()); + + me = new MouseEvent(getDiagram(), + e.getID(), + e.getWhen(), + e.getModifiers() + | e.getModifiersEx(), + p.x, p.y, + e.getXOnScreen(), + e.getYOnScreen(), + e.getClickCount(), + e.isPopupTrigger(), + e.getButton()); + } + return me; + } + + private enum Corner { + + RightBottom, + BottomRight, + BottomLeft, + LeftBottom, + RightTop, + TopRight, + LeftTop, + TopLeft, + Top, + Bottom, + None,} + + public Connection(Dot start, Dot end) { + + + if (start.getParamType() == Dot.ParamType.Output + || (start.getParamType() == Dot.ParamType.Both && end.getParamType() != Dot.ParamType.Output) + || (end.getParamType() == Dot.ParamType.Both && start.getParamType() != Dot.ParamType.Input)) { + this.start = start; + this.end = end; + } else { + this.start = end; + this.end = start; + } + + for (int i = 0; i < 6; i++) { + points[i] = new Point(); + } + resize(this.start, this.end); + addMouseMotionListener(this); + addMouseListener(this); + addKeyListener(this); + setFocusable(true); + setOpaque(false); + + } + + private void translate(Point p, Point store) { + store.x = p.x - getLocation().x - 1; + store.y = p.y - getLocation().y - 1; + } + private Point p1 = new Point(); + private Point p2 = new Point(); + private Point tp1 = new Point(); + private Point bp1 = new Point(); + private Point tp2 = new Point(); + private Point bp2 = new Point(); + + @Override + protected void paintBorder(Graphics g) { +// super.paintBorder(g); +// +// g.setColor(Color.GRAY); +// g.drawLine(0, 0, getWidth(), 0); +// g.drawLine(getWidth(), 0, getWidth(), getHeight() - 1); +// g.drawLine(getWidth(), getHeight() - 1, 0, getHeight() - 1); +// g.drawLine(0, getHeight() - 1, 0, 0); + } + + public String getKey() { + return key; + } + + protected void makeKey(MappingBlock mapping, String techName) { + this.mapping = mapping; + key = MaterialUtils.makeKey(mapping, techName); + } + + private void adjustCorners(Corner corner, Point tp, Point bp) { + switch (corner) { + case LeftTop: + case TopLeft: + tp.x -= 1; + bp.x += 1; + tp.y += 1; + bp.y -= 1; + break; + case RightBottom: + case BottomRight: + tp.x += 1; + bp.x -= 1; + tp.y -= 1; + bp.y += 1; + break; + case RightTop: + case TopRight: + tp.x -= 1; + bp.x += 1; + tp.y -= 1; + bp.y += 1; + break; + case LeftBottom: + case BottomLeft: + tp.x += 1; + bp.x -= 1; + tp.y += 1; + bp.y -= 1; + break; + case None: + tp.y -= 1; + bp.y += 1; + break; + case Top: + tp.x -= 1; + bp.x += 1; + break; + case Bottom: + tp.x += 1; + bp.x -= 1; + break; + } + } + + @Override + protected void paintComponent(Graphics g) { + if (paintDebug) { + for (int i = 0; i < pointsSize - 1; i++) { + translate(points[i], p1); + p1.x -= MARGIN; + p1.y -= MARGIN; + translate(points[i + 1], p2); + p2.x += MARGIN; + p2.y += MARGIN; + g.setColor(Color.GRAY); + g.drawLine(p1.x, p1.y, p2.x, p1.y); + g.drawLine(p2.x, p1.y, p2.x, p2.y); + g.drawLine(p2.x, p2.y, p1.x, p2.y); + g.drawLine(p1.x, p2.y, p1.x, p1.y); + + + } + + paintDebug = false; + } + + for (int i = 0; i < pointsSize - 1; i++) { + + g.setColor(Color.YELLOW); + translate(points[i], p1); + translate(points[i + 1], p2); + g.drawLine(p1.x, p1.y, p2.x, p2.y); + + + if (getDiagram().selectedItem == this) { + g.setColor(Color.CYAN); + } else { + g.setColor(Color.GRAY); + } + tp1.setLocation(p1); + bp1.setLocation(p1); + tp2.setLocation(p2); + bp2.setLocation(p2); + adjustCorners(corners[i], tp1, bp1); + adjustCorners(corners[i + 1], tp2, bp2); + g.drawLine(tp1.x, tp1.y, tp2.x, tp2.y); + g.drawLine(bp1.x, bp1.y, bp2.x, bp2.y); + + } + + } + public final static int MARGIN = 10; + + private int getOffset() { + return 5 * start.getIndex(); + } + + private int getHMiddle() { + int st = start.getNode().getLocation().y + start.getNode().getHeight(); + int diff = end.getNode().getLocation().y - st; + return st + diff / 2 + getOffset(); + + } + + private int getVMiddleStart() { + Point startLocation = start.getStartLocation(); + Point endLocation = end.getEndLocation(); + return startLocation.x + Math.max(MARGIN, (endLocation.x - startLocation.x) / 2) + getOffset(); + } + + private int getVMiddleStartClampedRight() { + Point startLocation = start.getStartLocation(); + Point endLocation = end.getEndLocation(); + int right = end.getNode().getLocation().x + end.getNode().getWidth() + MARGIN; + int loc = startLocation.x + Math.max(MARGIN, (endLocation.x - startLocation.x) / 2); + return Math.max(loc, right) + getOffset(); + } + + private int getVMiddleEnd() { + Point startLocation = start.getStartLocation(); + Point endLocation = end.getEndLocation(); + return endLocation.x - Math.max(0, Math.max(MARGIN, (endLocation.x - startLocation.x) / 2) + getOffset()); + + } + + private int getVMiddleEndClampedLeft() { + Point startLocation = start.getStartLocation(); + Point endLocation = end.getEndLocation(); + int left = start.getNode().getLocation().x - MARGIN;//+ end.getNode().getWidth() + MARGIN; + int loc = endLocation.x - Math.max(0, Math.max(MARGIN, (endLocation.x - startLocation.x) / 2)); + return Math.min(loc, left) + getOffset(); + + } + + private int getHBottom() { + int endBottom = end.getNode().getLocation().y + end.getNode().getHeight() + MARGIN; + int startBottom = start.getNode().getLocation().y + start.getNode().getHeight() + MARGIN; + return Math.max(endBottom, startBottom) + getOffset(); + + } + + public final void resize(Dot start, Dot end) { + Point startLocation = start.getStartLocation(); + Point endLocation = end.getEndLocation(); + + if (start.getParamType() == Dot.ParamType.Both) { + startLocation.x = endLocation.x - MARGIN * 2; + pointsSize = 3; + points[0].setLocation(startLocation); + points[1].x = startLocation.x; + points[1].y = endLocation.y; + points[2].setLocation(endLocation); + if (startLocation.y <= endLocation.y) { + corners[0] = Corner.Bottom; + corners[1] = Corner.BottomRight; + corners[2] = Corner.None; + } else { + corners[0] = Corner.Top; + corners[1] = Corner.TopRight; + corners[2] = Corner.None; + } + } else if (end.getParamType() == Dot.ParamType.Both) { + endLocation.x = startLocation.x + MARGIN * 2; + pointsSize = 3; + points[0].setLocation(startLocation); + points[1].x = endLocation.x; + points[1].y = startLocation.y; + points[2].setLocation(endLocation); + if (startLocation.y <= endLocation.y) { + corners[0] = Corner.None; + corners[1] = Corner.RightBottom; + corners[2] = Corner.Bottom; + } else { + corners[0] = Corner.None; + corners[1] = Corner.RightTop; + corners[2] = Corner.Top; + } + } else if (startLocation.x + MARGIN <= endLocation.x - MARGIN) { + pointsSize = 4; + points[0].setLocation(startLocation); + points[1].x = getVMiddleStart(); + points[1].y = startLocation.y; + points[2].x = getVMiddleStart(); + points[2].y = endLocation.y; + corners[0] = Corner.None; + corners[3] = Corner.None; + points[3].setLocation(endLocation); + if (startLocation.y <= endLocation.y) { + corners[1] = Corner.RightBottom; + corners[2] = Corner.BottomRight; + } else { + corners[1] = Corner.RightTop; + corners[2] = Corner.TopRight; + } + + } else { + pointsSize = 6; + points[0].setLocation(startLocation); + points[5].setLocation(endLocation); + points[1].x = getVMiddleStart(); + points[1].y = startLocation.y; + + points[4].x = getVMiddleEnd(); + points[4].y = endLocation.y; + corners[0] = Corner.None; + corners[5] = Corner.None; + if ((start.getNode().getLocation().y + start.getNode().getHeight() + MARGIN + > end.getNode().getLocation().y - MARGIN) + && (end.getNode().getLocation().y + end.getNode().getHeight() + MARGIN + > start.getNode().getLocation().y - MARGIN)) { + + if (startLocation.y + MARGIN <= endLocation.y - MARGIN) { + points[1].x = getVMiddleStartClampedRight(); + points[2].x = getVMiddleStartClampedRight(); + } else { + points[1].x = getVMiddleStart(); + points[2].x = getVMiddleStart(); + } + points[2].y = getHBottom(); + + if (startLocation.y + MARGIN > endLocation.y - MARGIN) { + points[3].x = getVMiddleEndClampedLeft(); + points[4].x = getVMiddleEndClampedLeft(); + + } else { + points[3].x = getVMiddleEnd(); + points[4].x = getVMiddleEnd(); + } + + points[3].y = getHBottom(); + + corners[1] = Corner.RightBottom; + corners[2] = Corner.BottomLeft; + corners[3] = Corner.LeftTop; + corners[4] = Corner.TopRight; + + } else { + + points[2].x = getVMiddleStart(); + points[2].y = getHMiddle(); + + points[3].x = getVMiddleEnd(); + points[3].y = getHMiddle(); + + + if (startLocation.y <= endLocation.y) { + corners[1] = Corner.RightBottom; + corners[2] = Corner.BottomLeft; + corners[3] = Corner.LeftBottom; + corners[4] = Corner.BottomRight; + } else { + corners[1] = Corner.RightTop; + corners[2] = Corner.TopLeft; + corners[3] = Corner.LeftTop; + corners[4] = Corner.TopRight; + } + } + } + updateBounds(); + } + + private void updateBounds() { + int minX = Integer.MAX_VALUE, minY = Integer.MAX_VALUE, maxX = Integer.MIN_VALUE, maxY = Integer.MIN_VALUE; + for (int i = 0; i < pointsSize; i++) { + if (points[i].x < minX) { + minX = points[i].x; + } + if (points[i].y < minY) { + minY = points[i].y; + } + + if (points[i].x > maxX) { + maxX = points[i].x; + } + if (points[i].y > maxY) { + maxY = points[i].y; + } + } + maxX += MARGIN; + maxY += MARGIN; + minX -= MARGIN; + minY -= MARGIN; + + setLocation(minX, minY); + setSize(maxX - minX, maxY - minY); + } + + private Diagram getDiagram() { + return (Diagram) start.getDiagram(); + } + + @Override + public void mouseDragged(MouseEvent e) { + dispatchEventToDiagram(e); + } + + private void dispatchEventToDiagram(MouseEvent e) { + MouseEvent me = null; + me = convertEvent(e); + getDiagram().dispatchEvent(me); + } + + @Override + public void mouseMoved(MouseEvent e) { + dispatchEventToDiagram(e); + } + private boolean paintDebug = false; + + private void debug() { + paintDebug = true; + repaint(); + } + + @Override + public void mouseClicked(MouseEvent e) { + dispatchEventToDiagram(e); + } + + @Override + public void mousePressed(MouseEvent e) { + dispatchEventToDiagram(e); + } + + @Override + public void mouseReleased(MouseEvent e) { + dispatchEventToDiagram(e); + } + + public void select(MouseEvent e) { + boolean selected = false; + requestFocusInWindow(true); + for (int i = 0; i < pointsSize - 1; i++) { + translate(points[i], p1); + translate(points[i + 1], p2); + if (p1.x > p2.x || p1.y > p2.y) { + tp1.setLocation(p1); + p1.setLocation(p2); + p2.setLocation(tp1); + } + + p1.x -= MARGIN / 2; + p1.y -= MARGIN / 2; + + p2.x += MARGIN / 2; + p2.y += MARGIN / 2; + + + if (e.getX() >= p1.x && e.getX() <= p2.x + && e.getY() >= p1.y && e.getY() <= p2.y) { + selected = true; + } + } + + if (selected) { + getDiagram().select(this); + e.consume(); + } + } + + @Override + public void mouseEntered(MouseEvent e) { + } + + @Override + public void mouseExited(MouseEvent e) { + } + + @Override + public void keyTyped(KeyEvent e) { + } + + @Override + public void keyPressed(KeyEvent e) { + + if (e.getKeyCode() == KeyEvent.VK_DELETE) { + Diagram diag = getDiagram(); + if (diag.selectedItem == this) { + diag.removeSelectedConnection(); + } + } + } + + @Override + public void keyReleased(KeyEvent e) { + } + + public void componentResized(ComponentEvent e) { + } + + public void componentMoved(ComponentEvent e) { + resize(start, end); + } + + public void componentShown(ComponentEvent e) { + } + + public void componentHidden(ComponentEvent e) { + } + + public void propertyChange(PropertyChangeEvent evt) { + MappingBlock mapping = (MappingBlock) evt.getSource(); + key = MaterialUtils.makeKey(mapping, getDiagram().getCurrentTechniqueName()); + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/Diagram.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/Diagram.java new file mode 100644 index 000000000..09e113489 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/Diagram.java @@ -0,0 +1,531 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.editor; + +import com.jme3.gde.core.assets.ProjectAssetManager; +import com.jme3.gde.materialdefinition.dialog.AddAttributeDialog; +import com.jme3.gde.materialdefinition.dialog.AddMaterialParameterDialog; +import com.jme3.gde.materialdefinition.dialog.AddNodeDialog; +import com.jme3.gde.materialdefinition.dialog.AddWorldParameterDialog; +import com.jme3.gde.materialdefinition.fileStructure.ShaderNodeBlock; +import com.jme3.gde.materialdefinition.icons.Icons; +import com.jme3.material.Material; +import com.jme3.shader.Shader; +import com.jme3.shader.ShaderNodeDefinition; +import com.jme3.shader.ShaderNodeVariable; +import com.jme3.shader.UniformBinding; +import com.jme3.shader.VarType; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.Point; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ComponentEvent; +import java.awt.event.ComponentListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.JMenuItem; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JPopupMenu; +import javax.swing.JSeparator; +import javax.swing.SwingUtilities; +import javax.swing.border.Border; +import javax.swing.border.TitledBorder; + +/** + * + * @author Nehon + */ +public class Diagram extends JPanel implements MouseListener, MouseMotionListener, ComponentListener { + + protected Dot draggedFrom; + protected Dot draggedTo; + protected Selectable selectedItem; + protected List connections = new ArrayList(); + protected List nodes = new ArrayList(); + protected List outBuses = new ArrayList(); + private MyMenu contextMenu = new MyMenu("Add"); + private MatDefEditorlElement parent; + private String currentTechniqueName; + + public Diagram() { + + addMouseListener(this); + addMouseMotionListener(this); + createPopupMenu(); + } + + @Override + public void mouseClicked(MouseEvent e) { + } + + @Override + public void mousePressed(MouseEvent e) { + + for (OutBusPanel outBusPanel : outBuses) { + Point p = SwingUtilities.convertPoint(this, e.getX(), e.getY(), outBusPanel); + if (outBusPanel.contains(p)) { + MouseEvent me = SwingUtilities.convertMouseEvent(this, e, outBusPanel); + outBusPanel.dispatchEvent(me); + if (me.isConsumed()) { + return; + } + } + } + + for (Connection connection : connections) { + MouseEvent me = SwingUtilities.convertMouseEvent(this, e, connection); + connection.select(me); + if (me.isConsumed()) { + return; + } + } + + selectedItem = null; + repaint(); + } + + public void refreshPreviews(Material mat) { + for (OutBusPanel outBusPanel : outBuses) { + outBusPanel.updatePreview(mat); + } + } + Point clickLoc = new Point(0, 0); + + @Override + public void mouseReleased(MouseEvent e) { + if (draggedFrom != null && draggedFrom.getNode() instanceof OutBusPanel) { + MouseEvent me = SwingUtilities.convertMouseEvent(this, e, draggedFrom.getNode()); + draggedFrom.getNode().dispatchEvent(me); + if (me.isConsumed()) { + return; + } + } + if (e.getButton() != MouseEvent.BUTTON3) { + dispatchToOutBuses(e); + } else { + contextMenu.show(this, e.getX(), e.getY()); + clickLoc.setLocation(e.getX(), e.getY()); + } + + } + + public MatDefEditorlElement getEditorParent() { + return parent; + } + + public void addConnection(Connection conn) { + connections.add(conn); + add(conn); + for (OutBusPanel bus : outBuses) { + setComponentZOrder(bus, getComponentCount() - 1); + } + repaint(); + } + + public void notifyMappingCreation(Connection conn) { + parent.makeMapping(conn); + } + + public void addNode(NodePanel node) { + add(node); + node.setTechName(currentTechniqueName); + node.setDiagram(this); + nodes.add(node); + setComponentZOrder(node, 0); + node.addComponentListener(this); + } + + public void addOutBus(OutBusPanel bus) { + outBuses.add(bus); + bus.setDiagram(this); + add(bus); + setComponentZOrder(bus, getComponentCount() - 1); + addComponentListener(bus); + bus.componentResized(new ComponentEvent(this, ActionEvent.ACTION_PERFORMED)); + bus.revalidate(); + } + + @Override + public void mouseEntered(MouseEvent e) { + } + + @Override + public void mouseExited(MouseEvent e) { + } + + protected void removeSelectedConnection() { + if (selectedItem instanceof Connection) { + Connection selectedConnection = (Connection) selectedItem; + removeConnection(selectedConnection); + selectedItem = null; + parent.notifyRemoveConnection(selectedConnection); + } + } + + public void addNodesFromDefs(List defList, String path, Point clickPosition) { + int i = 0; + for (ShaderNodeDefinition def : defList) { + ShaderNodeBlock sn = new ShaderNodeBlock(def, path); + NodePanel np = new NodePanel(sn, def); + addNode(np); + np.setLocation(clickPosition.x + i * 150, clickPosition.y); + sn.setSpatialOrder(np.getLocation().x); + i++; + np.revalidate(); + getEditorParent().notifyAddNode(sn, def); + } + repaint(); + } + + public void addMatParam(String type, String name, Point point) { + String fixedType = type; + if (type.equals("Color")) { + fixedType = "Vector4"; + } + ShaderNodeVariable param = new ShaderNodeVariable(VarType.valueOf(fixedType).getGlslType(), name); + NodePanel np = new NodePanel(param, NodePanel.NodeType.MatParam); + addNode(np); + np.setLocation(point.x, point.y); + np.revalidate(); + repaint(); + getEditorParent().notifyAddMapParam(type, name); + } + + public void addWorldParam(UniformBinding binding, Point point) { + + ShaderNodeVariable param = new ShaderNodeVariable(binding.getGlslType(), binding.name()); + NodePanel np = new NodePanel(param, NodePanel.NodeType.WorldParam); + addNode(np); + np.setLocation(point.x, point.y); + np.revalidate(); + repaint(); + getEditorParent().notifyAddWorldParam(binding.name()); + } + + public void addAttribute(String name, String type, Point point) { + ShaderNodeVariable param = new ShaderNodeVariable(type, "Attr", name); + NodePanel np = new NodePanel(param, NodePanel.NodeType.Attribute); + addNode(np); + np.setLocation(point.x, point.y); + np.revalidate(); + repaint(); + } + + protected void removeSelectedNode() { + if (selectedItem instanceof NodePanel) { + int result = JOptionPane.showConfirmDialog(null, "Delete this node and all its mappings?", "Delete Shader Node", JOptionPane.OK_CANCEL_OPTION); + if (result == JOptionPane.OK_OPTION) { + NodePanel selectedNode = (NodePanel) selectedItem; + nodes.remove(selectedNode); + for (Iterator it = connections.iterator(); it.hasNext();) { + Connection conn = it.next(); + if (conn.start.getNode() == selectedNode || conn.end.getNode() == selectedNode) { + it.remove(); + conn.end.disconnect(); + conn.start.disconnect(); + remove(conn); + } + } + + remove(selectedNode); + selectedItem = null; + repaint(); + parent.notifyRemoveNode(selectedNode); + } + } + } + + @Override + public void mouseDragged(MouseEvent e) { + if (draggedFrom == null) { + if (selectedItem instanceof OutBusPanel) { + OutBusPanel bus = (OutBusPanel) selectedItem; + MouseEvent me = SwingUtilities.convertMouseEvent(this, e, bus); + bus.dispatchEvent(me); + } + } + } + + protected void draggingDot(MouseEvent e) { + for (OutBusPanel outBusPanel : outBuses) { + Point p = SwingUtilities.convertPoint(this, e.getX(), e.getY(), outBusPanel); + if (outBusPanel.contains(p)) { + MouseEvent me = SwingUtilities.convertMouseEvent(this, e, outBusPanel); + outBusPanel.draggingDot(me); + if (me.isConsumed()) { + return; + } + } + } + } + + public Connection connect(Dot start, Dot end) { + Connection conn = new Connection(start, end); + start.connect(conn); + end.connect(conn); + + + addConnection(conn); + + return conn; + } + + public NodePanel getNodePanel(String key) { + for (NodePanel nodePanel : nodes) { + if (nodePanel.getKey().equals(key)) { + return nodePanel; + } + } + return null; + } + + public OutBusPanel getOutBusPanel(String key) { + for (OutBusPanel out : outBuses) { + if (out.getKey().equals(key)) { + return out; + } + } + return null; + } + + /** + * selection from the editor. Select the item and notify the topComponent + * + * @param selectable + */ + public void select(Selectable selectable) { + parent.selectionChanged(doSelect(selectable)); + } + + /** + * do select the item and repaint the diagram + * + * @param selectable + * @return + */ + private Selectable doSelect(Selectable selectable) { + this.selectedItem = selectable; + if (selectable instanceof Component) { + ((Component) selectable).requestFocusInWindow(); + } + repaint(); + return selectable; + } + + /** + * find the item with the given key and select it without notifying the + * topComponent + * + * @param key + * @return + */ + public Selectable select(String key) { + + for (NodePanel nodePanel : nodes) { + if (nodePanel.getKey().equals(key)) { + return doSelect(nodePanel); + } + } + + for (Connection connection : connections) { + if (connection.getKey().equals(key)) { + return doSelect(connection); + } + } + + for (OutBusPanel outBusPanel : outBuses) { + if (outBusPanel.getKey().equals(key)) { + return doSelect(outBusPanel); + } + } + return doSelect(null); + } + + @Override + public void mouseMoved(MouseEvent e) { + dispatchToOutBuses(e); + } + + private JMenuItem createMenuItem(String text, Icon icon) { + JMenuItem item = new JMenuItem(text, icon); + item.setFont(new Font("Tahoma", 1, 10)); // NOI18N + return item; + } + + private void createPopupMenu() { + contextMenu.setFont(new Font("Tahoma", 1, 10)); // NOI18N + contextMenu.setOpaque(true); + Border titleUnderline = BorderFactory.createMatteBorder(1, 0, 0, 0, Color.BLACK); + TitledBorder labelBorder = BorderFactory.createTitledBorder( + titleUnderline, contextMenu.getLabel(), + TitledBorder.LEADING, TitledBorder.ABOVE_TOP, contextMenu.getFont(), Color.BLACK); + + contextMenu.setBorder(BorderFactory.createLineBorder(Color.BLACK)); + contextMenu.setBorder(BorderFactory.createCompoundBorder(contextMenu.getBorder(), + labelBorder)); + + + JMenuItem nodeItem = createMenuItem("Node", Icons.node); + nodeItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + AddNodeDialog d = new AddNodeDialog(null, true, parent.obj.getLookup().lookup(ProjectAssetManager.class), Diagram.this, clickLoc); + d.setLocationRelativeTo(null); + d.setVisible(true); + } + }); + + contextMenu.add(nodeItem); + contextMenu.add(createSeparator()); + JMenuItem matParamItem = createMenuItem("Material Parameter", Icons.mat); + matParamItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + AddMaterialParameterDialog d = new AddMaterialParameterDialog(null, true, Diagram.this, clickLoc); + d.setLocationRelativeTo(null); + d.setVisible(true); + } + }); + contextMenu.add(matParamItem); + JMenuItem worldParamItem = createMenuItem("World Parameter", Icons.world); + worldParamItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + AddWorldParameterDialog d = new AddWorldParameterDialog(null, true, Diagram.this, clickLoc); + d.setLocationRelativeTo(null); + d.setVisible(true); + } + }); + contextMenu.add(worldParamItem); + JMenuItem attributeItem = createMenuItem("Attribute", Icons.attrib); + attributeItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + AddAttributeDialog d = new AddAttributeDialog(null, true, Diagram.this, clickLoc); + d.setLocationRelativeTo(null); + d.setVisible(true); + } + }); + contextMenu.add(attributeItem); + contextMenu.add(createSeparator()); + JMenuItem outputItem = createMenuItem("Output color", Icons.output); + contextMenu.add(outputItem); + outputItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + OutBusPanel p2 = new OutBusPanel("color" + (outBuses.size() - 1), Shader.ShaderType.Fragment); + p2.setBounds(0, 350 + 50 * (outBuses.size() - 1), p2.getWidth(), p2.getHeight()); + + addOutBus(p2); + + } + }); + } + + private JSeparator createSeparator() { + JSeparator jsep = new JSeparator(JSeparator.HORIZONTAL); + jsep.setBackground(Color.BLACK); + return jsep; + } + + private void dispatchToOutBuses(MouseEvent e) { + for (OutBusPanel outBusPanel : outBuses) { + Point p = SwingUtilities.convertPoint(this, e.getX(), e.getY(), outBusPanel); + if (outBusPanel.contains(p)) { + MouseEvent me = SwingUtilities.convertMouseEvent(this, e, outBusPanel); + outBusPanel.dispatchEvent(me); + if (me.isConsumed()) { + return; + } + } + } + } + + private void removeConnection(Connection selectedConnection) { + connections.remove(selectedConnection); + selectedConnection.end.disconnect(); + selectedConnection.start.disconnect(); + remove(selectedConnection); + } + + private class MyMenu extends JPopupMenu { + + public MyMenu(String label) { + super(label); + } + + @Override + protected void paintComponent(Graphics g) { + //Color c1 = new Color(100, 100, 100, 255); + Color bg = new Color(175, 175, 175); + g.setColor(bg); + g.fillRect(0, 0, getWidth(), getHeight()); + } + } + + public void fixSize() { + int maxWidth = minWidth; + int maxHeight = minHeight; + + for (NodePanel nodePanel : nodes) { + int w = nodePanel.getLocation().x + nodePanel.getWidth() + 150; + if (w > maxWidth) { + maxWidth = w; + } + int h = nodePanel.getLocation().y + nodePanel.getHeight(); + if (h > maxHeight) { + maxHeight = h; + } + } + for (OutBusPanel outBusPanel : outBuses) { + int h = outBusPanel.getLocation().y + outBusPanel.getHeight(); + if (h > maxHeight) { + maxHeight = h; + } + } + setPreferredSize(new Dimension(maxWidth, maxHeight)); + revalidate(); + } + int minWidth = 0; + int minHeight = 0; + + public void componentResized(ComponentEvent e) { + minWidth = e.getComponent().getWidth() - 2; + minHeight = e.getComponent().getHeight() - 2; + fixSize(); + } + + public void componentMoved(ComponentEvent e) { + } + + public void componentShown(ComponentEvent e) { + } + + public void componentHidden(ComponentEvent e) { + } + + public void setParent(MatDefEditorlElement parent) { + this.parent = parent; + } + + public void setCurrentTechniqueName(String currentTechniqueName) { + this.currentTechniqueName = currentTechniqueName; + } + + public String getCurrentTechniqueName() { + return currentTechniqueName; + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/Dot.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/Dot.java new file mode 100644 index 000000000..651d8b2f5 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/Dot.java @@ -0,0 +1,262 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.editor; + +import com.jme3.gde.materialdefinition.icons.Icons; +import com.jme3.shader.ShaderUtils; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Point; +import java.awt.event.MouseEvent; +import javax.swing.ImageIcon; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; +import javax.swing.event.MouseInputListener; + +/** + * + * @author Nehon + */ +public class Dot extends JPanel implements MouseInputListener { + + public static boolean pressed = false; + protected ImageIcon img; + protected ImageIcon prevImg; + private String type; + private ParamType paramType; + private String text = ""; + private DraggablePanel node; + private int index = 1; + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public enum ParamType { + + Input, + Output, + Both + } + + public Dot() { + super(); + setMaximumSize(new Dimension(10, 10)); + setMinimumSize(new Dimension(10, 10)); + setPreferredSize(new Dimension(10, 10)); + setSize(10, 10); + addMouseMotionListener(this); + addMouseListener(this); + } + + @Override + protected void paintComponent(Graphics g) { + if (img == null) { + + img = Icons.imgGrey; + } + g.drawImage(img.getImage(), 0, 0, this); + } + + @Override + public void mouseClicked(MouseEvent e) { + } + + @Override + public void mousePressed(MouseEvent e) { + prevImg = img; + img = Icons.imgOrange; + Diagram diag = getDiagram(); + diag.draggedFrom = this; + repaint(); + e.consume(); + } + + @Override + public void repaint() { + if (getNode() != null) { + getDiagram().repaint(); + } else { + super.repaint(); + } + } + + public Diagram getDiagram() { + return node.getDiagram(); + } + + public DraggablePanel getNode() { + return node; + } + + public void setNode(DraggablePanel node) { + this.node = node; + } + + @Override + public void mouseReleased(MouseEvent e) { + Diagram diag = getDiagram(); + if (diag.draggedFrom == this && diag.draggedTo != null) { + if (this.canConnect(diag.draggedTo)) { + diag.notifyMappingCreation(diag.connect(this, diag.draggedTo)); + + } else { + diag.draggedTo.reset(); + this.reset(); + } + diag.draggedFrom = null; + diag.draggedTo = null; + } else { + reset(); + diag.draggedFrom = null; + } + e.consume(); + } + + public void reset() { + img = prevImg; + repaint(); + } + + public void disconnect() { + img = Icons.imgGrey; + repaint(); + } + + @Override + public void mouseEntered(MouseEvent e) { + Diagram diag = getDiagram(); + if (diag.draggedFrom != null && diag.draggedFrom != this) { + prevImg = img; + canConnect(diag.draggedFrom); + diag.draggedTo = this; + diag.draggedFrom.canConnect(this); + } + + } + + public boolean canConnect(Dot pair) { + if (pair == null) { + img = Icons.imgOrange; + repaint(); + return false; + } + + + + if (matches(pair.getType(), type) && (pair.getParamType() != paramType + || pair.getParamType() == ParamType.Both + || paramType == ParamType.Both) + || ShaderUtils.isSwizzlable(pair.getType()) && ShaderUtils.isSwizzlable(type)) { + img = Icons.imgGreen; + repaint(); + return true; + } + + + img = Icons.imgRed; + repaint(); + return false; + } + + private boolean matches(String type1, String type2) { + String[] s1 = type1.split("\\|"); + String[] s2 = type2.split("\\|"); + for (String string : s1) { + for (String string1 : s2) { + if (string.equals(string1)) { + return true; + } + } + } + return false; + + } + + protected void connect(Connection connection) { + img = Icons.imgGreen; + getNode().addComponentListener(connection); + repaint(); + } + + @Override + public void mouseExited(MouseEvent e) { + Diagram diag = getDiagram(); + if (diag.draggedFrom != null) { + diag.draggedFrom.canConnect(null); + if (diag.draggedFrom != this) { + reset(); + } + if (diag.draggedTo == this) { + diag.draggedTo = null; + } + } + } + + public Point getStartLocation() { + Point p = getLocation(); + Component parent = getParent(); + while (parent != getNode()) { + p.x += parent.getLocation().x; + p.y += parent.getLocation().y; + parent = parent.getParent(); + } + p.x += 10 + getNode().getLocation().x; + p.y += 5 + getNode().getLocation().y; + return p; + } + + public Point getEndLocation() { + Point p = getLocation(); + Component parent = getParent(); + while (parent != getNode()) { + p.x += parent.getLocation().x; + p.y += parent.getLocation().y; + parent = parent.getParent(); + } + p.x += getNode().getLocation().x + 2; + p.y += 5 + getNode().getLocation().y; + return p; + } + + @Override + public void mouseDragged(MouseEvent e) { + MouseEvent me = SwingUtilities.convertMouseEvent(this, e, getDiagram()); + getDiagram().draggingDot(me); + } + + @Override + public void mouseMoved(MouseEvent e) { + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public ParamType getParamType() { + return paramType; + } + + public void setParamType(ParamType paramType) { + this.paramType = paramType; + } + + public int getIndex() { + return index; + } + + public void setIndex(int index) { + this.index = index; + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/DraggablePanel.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/DraggablePanel.java new file mode 100644 index 000000000..73568963b --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/DraggablePanel.java @@ -0,0 +1,82 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.editor; + +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; +import javax.swing.JPanel; + +/** + * + * @author m327836 + */ +public class DraggablePanel extends JPanel implements MouseListener, MouseMotionListener { + + protected int svdx, svdy, svdex, svdey; + private boolean vertical = false; + protected Diagram diagram; + + + public DraggablePanel(boolean vertical) { + this(); + this.vertical = vertical; + } + + public DraggablePanel() { + addMouseListener(this); + addMouseMotionListener(this); + } + + @Override + public void mouseClicked(MouseEvent e) { + } + + @Override + public void mousePressed(MouseEvent e) { + svdx = getLocation().x; + if (!vertical) { + svdex = e.getXOnScreen(); + } + svdy = getLocation().y; + svdey = e.getYOnScreen(); + e.consume(); + } + + @Override + public void mouseReleased(MouseEvent e) { + } + + @Override + public void mouseEntered(MouseEvent e) { + } + + @Override + public void mouseExited(MouseEvent e) { + } + + @Override + public void mouseMoved(MouseEvent e) { + } + + @Override + public void mouseDragged(MouseEvent e) { + int xoffset = 0; + if (!vertical) { + xoffset = e.getLocationOnScreen().x - svdex; + } + int yoffset = e.getLocationOnScreen().y - svdey; + setLocation(Math.max(0, svdx + xoffset), Math.max(0,svdy + yoffset)); + e.consume(); + } + + public Diagram getDiagram() { + return diagram; + } + + public void setDiagram(Diagram diagram) { + this.diagram = diagram; + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/InOut.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/InOut.java new file mode 100644 index 000000000..90caa385e --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/InOut.java @@ -0,0 +1,25 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.editor; + +import com.jme3.gde.materialdefinition.fileStructure.leaves.InputMappingBlock; +import com.jme3.gde.materialdefinition.fileStructure.leaves.OutputMappingBlock; + +/** + * + * @author Nehon + */ +public interface InOut { + + public String getName(); + + public void addInputMapping(InputMappingBlock block); + + public void removeInputMapping(InputMappingBlock block); + + public void addOutputMapping(OutputMappingBlock block); + + public void removeOutputMapping(OutputMappingBlock block); +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/MatDefEditorlElement.form b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/MatDefEditorlElement.form new file mode 100644 index 000000000..9c82d4931 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/MatDefEditorlElement.form @@ -0,0 +1,56 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/MatDefEditorlElement.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/MatDefEditorlElement.java new file mode 100644 index 000000000..bdef62cb2 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/MatDefEditorlElement.java @@ -0,0 +1,566 @@ +/* + * Copyright (c) 2009-2010 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.jme3.gde.materialdefinition.editor; + +import com.jme3.gde.core.assets.ProjectAssetManager; +import com.jme3.gde.materialdefinition.EditableMatDefFile; +import com.jme3.gde.materialdefinition.MatDefDataObject; +import com.jme3.gde.materialdefinition.MatDefMetaData; +import com.jme3.gde.materialdefinition.fileStructure.MatDefBlock; +import com.jme3.gde.materialdefinition.fileStructure.ShaderNodeBlock; +import com.jme3.gde.materialdefinition.fileStructure.TechniqueBlock; +import com.jme3.gde.materialdefinition.fileStructure.leaves.InputMappingBlock; +import com.jme3.gde.materialdefinition.fileStructure.leaves.MappingBlock; +import com.jme3.gde.materialdefinition.fileStructure.leaves.MatParamBlock; +import com.jme3.gde.materialdefinition.fileStructure.leaves.OutputMappingBlock; +import com.jme3.gde.materialdefinition.fileStructure.leaves.WorldParamBlock; +import com.jme3.gde.materialdefinition.navigator.MatDefNavigatorPanel; +import com.jme3.gde.materialdefinition.utils.MaterialUtils; +import com.jme3.material.Material; +import com.jme3.shader.Shader; +import com.jme3.shader.ShaderNodeDefinition; +import com.jme3.shader.ShaderNodeVariable; +import com.jme3.shader.ShaderUtils; +import java.awt.Dimension; +import java.awt.Point; +import java.beans.PropertyVetoException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import javax.swing.Action; +import javax.swing.JComponent; +import javax.swing.JPanel; +import javax.swing.JToolBar; +import org.netbeans.core.spi.multiview.CloseOperationState; +import org.netbeans.core.spi.multiview.MultiViewElement; +import org.netbeans.core.spi.multiview.MultiViewElementCallback; +import org.openide.awt.UndoRedo; +import org.openide.nodes.Children; +import org.openide.nodes.Node; +import org.openide.util.Exceptions; +import org.openide.util.Lookup; +import org.openide.util.LookupEvent; +import org.openide.util.LookupListener; +import org.openide.util.NbBundle.Messages; +import org.openide.util.lookup.InstanceContent; +import org.openide.windows.TopComponent; + +@MultiViewElement.Registration( + displayName = "#LBL_MatDef_EDITOR", +iconBase = "com/jme3/gde/materialdefinition/icons/matdef.png", +mimeType = "text/jme-materialdefinition", +persistenceType = TopComponent.PERSISTENCE_ONLY_OPENED, +preferredID = "MatDefVisual", +position = 2000) +@Messages("LBL_MatDef_EDITOR=Editor") +public final class MatDefEditorlElement extends JPanel implements MultiViewElement { + + protected MatDefDataObject obj; + private JToolBar toolbar = new JToolBar(); + private transient MultiViewElementCallback callback; + InstanceContent content; + Selectable prevNode; + MatDefMetaData metaData; + + public MatDefEditorlElement(Lookup lkp) { + obj = lkp.lookup(MatDefDataObject.class); + metaData = lkp.lookup(MatDefMetaData.class); + assert obj != null; + EditableMatDefFile file = obj.getEditableFile(); + initComponents(); + diagram1.setParent(this); + + Material mat = lkp.lookup(Material.class); + + ProjectAssetManager manager = obj.getLookup().lookup(ProjectAssetManager.class); + final MatDefBlock matDef = obj.getLookup().lookup(MatDefBlock.class); + TechniqueBlock technique = getTechnique(matDef); + + diagram1.setCurrentTechniqueName(technique.getName()); + + List vertexGlobals = new ArrayList(); + List fragmentGlobals = new ArrayList(); + List attributes = new ArrayList(); + List uniforms = new ArrayList(); + initData(technique, manager, vertexGlobals, fragmentGlobals, attributes, matDef, uniforms); + + int i = 0; + for (ShaderNodeBlock sn : technique.getShaderNodes()) { + ShaderNodeDefinition def = MaterialUtils.loadShaderNodeDefinition(sn, manager); + NodePanel np = new NodePanel(sn, def); + diagram1.addNode(np); + Point position = getPositionFromMetaData(np.getKey(), 150 * i + 20, 190); + np.setLocation(position); + sn.setSpatialOrder(np.getLocation().x); + i++; + } + // TechniqueDef tech = def.getDefaultTechniques().get(0); + for (ShaderNodeVariable shaderNodeVariable : vertexGlobals) { + OutBusPanel out = new OutBusPanel(shaderNodeVariable.getName(), Shader.ShaderType.Vertex); + diagram1.addOutBus(out); + Point position = getPositionFromMetaData(out.getKey(), 0, 125); + out.setLocation(position); + } + + i = 2; + for (ShaderNodeVariable var : fragmentGlobals) { + OutBusPanel out2 = new OutBusPanel(var.getName(), Shader.ShaderType.Fragment); + diagram1.addOutBus(out2); + Point position = getPositionFromMetaData(out2.getKey(), 0, 150 * i + 190); + out2.setLocation(position); + i++; + } + i = 0; + for (ShaderNodeVariable shaderNodeVariable : attributes) { + NodePanel np = diagram1.getNodePanel(shaderNodeVariable.getNameSpace() + "." + shaderNodeVariable.getName()); + if (np == null) { + np = new NodePanel(shaderNodeVariable, NodePanel.NodeType.Attribute); + diagram1.addNode(np); + Point position = getPositionFromMetaData(np.getKey(), 150 * i + 20, 5); + np.setLocation(position); + i++; + } + } + i = 0; + for (ShaderNodeVariable shaderNodeVariable : uniforms) { + NodePanel np = diagram1.getNodePanel(shaderNodeVariable.getNameSpace() + "." + shaderNodeVariable.getName()); + if (np == null) { + np = new NodePanel(shaderNodeVariable, shaderNodeVariable.getNameSpace().equals("MatParam") ? NodePanel.NodeType.MatParam : NodePanel.NodeType.WorldParam); + diagram1.addNode(np); + Point position = getPositionFromMetaData(np.getKey(), 150 * i + 20, 65); + np.setLocation(position); + + i++; + } + } + + for (ShaderNodeBlock sn : technique.getShaderNodes()) { + //NodePanel np = diagram1.getNodePanel(sn.getName()); + List ins = sn.getInputs(); + if (ins != null) { + for (InputMappingBlock mapping : ins) { + makeConnection(mapping); + if (!mapping.getRightNameSpace().equals("Global") + && !mapping.getRightNameSpace().equals("MatParam") + && !mapping.getRightNameSpace().equals("Attribute") + && !mapping.getRightNameSpace().equals("WorldParam")) { + sn.addInputNode(mapping.getRightNameSpace()); + } else if (mapping.getRightNameSpace().equals("Global")) { + sn.setGlobalInput(true); + } + } + } + List outs = sn.getOutputs(); + if (outs != null) { + for (OutputMappingBlock mapping : outs) { + makeConnection(mapping); + if (mapping.getLeftNameSpace().equals("Global")) { + sn.setGlobalOutput(true); + } + } + } + + } + + diagram1.setPreferredSize(new Dimension(jScrollPane1.getWidth() - 2, jScrollPane1.getHeight() - 2)); + diagram1.revalidate(); + jScrollPane1.addComponentListener(diagram1); + + + diagram1.refreshPreviews(mat); + final Lookup.Result resMat = obj.getLookup().lookupResult(Material.class); + resMat.addLookupListener(new LookupListener() { + public void resultChanged(LookupEvent ev) { + Collection col = (Collection) resMat.allInstances(); + if (!col.isEmpty()) { + Material material = col.iterator().next(); + diagram1.refreshPreviews(material); + } + } + }); + + + final MatDefNavigatorPanel nav = obj.getLookup().lookup(MatDefNavigatorPanel.class); + if (nav != null) { + + Lookup.Result res = nav.getLookup().lookupResult(Selectable.class); + res.addLookupListener(new LookupListener() { + public void resultChanged(LookupEvent ev) { + Selectable selected = nav.getLookup().lookup(Selectable.class); + if (selected != null && (prevNode == null || !(selected.getKey().equals(prevNode.getKey())))) { + prevNode = diagram1.select(selected.getKey()); + } + + } + }); + } + + + + } + + @Override + public String getName() { + return "MatDefVisualElement"; + } + + protected void selectionChanged(Selectable selectable) { + MatDefNavigatorPanel nav = obj.getLookup().lookup(MatDefNavigatorPanel.class); + try { + Node n = findNode(nav.getExplorerManager().getRootContext(), selectable.getKey()); + if (n == null) { + n = nav.getExplorerManager().getRootContext(); + } + prevNode = selectable; + nav.getExplorerManager().setSelectedNodes(new Node[]{n}); + //FIXME this is hackish, each time it's used it spits a warning in the log. + //without this line selecting a node in the editor select it in + //the navigator explorer but does not displays its property sheet. + //the warning says to manipulate the MultiViewElement lookup, but it just voids the tree view + callback.getTopComponent().setActivatedNodes(new Node[]{n}); + + } catch (PropertyVetoException ex) { + Exceptions.printStackTrace(ex); + } + } + + private Node findNode(Node root, String key) { + if (root instanceof Selectable) { + Selectable s = (Selectable) root; + if (s.getKey().equals(key)) { + return root; + } else if (root.getChildren() != Children.LEAF) { + Node n; + for (Node node : root.getChildren().getNodes()) { + n = findNode(node, key); + if (n != null) { + return n; + } + } + } + } + + return null; + + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + jScrollPane1 = new javax.swing.JScrollPane(); + diagram1 = new com.jme3.gde.materialdefinition.editor.Diagram(); + + diagram1.setBackground(new java.awt.Color(153, 153, 153)); + + javax.swing.GroupLayout diagram1Layout = new javax.swing.GroupLayout(diagram1); + diagram1.setLayout(diagram1Layout); + diagram1Layout.setHorizontalGroup( + diagram1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 398, Short.MAX_VALUE) + ); + diagram1Layout.setVerticalGroup( + diagram1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 298, Short.MAX_VALUE) + ); + + jScrollPane1.setViewportView(diagram1); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPane1) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPane1) + ); + }// //GEN-END:initComponents + // Variables declaration - do not modify//GEN-BEGIN:variables + private com.jme3.gde.materialdefinition.editor.Diagram diagram1; + private javax.swing.JScrollPane jScrollPane1; + // End of variables declaration//GEN-END:variables + + @Override + public JComponent getVisualRepresentation() { + return this; + } + + @Override + public JComponent getToolbarRepresentation() { + return toolbar; + } + + @Override + public Action[] getActions() { + return new Action[0]; + } + + @Override + public Lookup getLookup() { + return obj.getLookup(); + } + + @Override + public void componentOpened() { + } + + @Override + public void componentClosed() { + } + + @Override + public void componentShowing() { + } + + @Override + public void componentHidden() { + } + + @Override + public void componentActivated() { + } + + @Override + public void componentDeactivated() { + } + + @Override + public UndoRedo getUndoRedo() { + return UndoRedo.NONE; + } + + @Override + public void setMultiViewCallback(MultiViewElementCallback callback) { + this.callback = callback; + } + + @Override + public CloseOperationState canCloseElement() { + return CloseOperationState.STATE_OK; + } + + protected void makeMapping(Connection conn) { + InOut startNode = (InOut) conn.start.getNode(); + InOut endNode = (InOut) conn.end.getNode(); + String leftVarName = conn.end.getText(); + String rightVarName = conn.start.getText(); + String leftVarSwizzle = null; + String rightVarSwizzle = null; + + int endCard = ShaderUtils.getCardinality(conn.end.getType(), ""); + int startCard = ShaderUtils.getCardinality(conn.start.getType(), ""); + String swizzle = "xyzw"; + if (startCard > endCard) { + rightVarSwizzle = swizzle.substring(0, endCard); + } else if (endCard > startCard) { + leftVarSwizzle = swizzle.substring(0, startCard); + } + + if (endNode instanceof OutBusPanel) { + OutputMappingBlock mapping = new OutputMappingBlock(leftVarName, rightVarName, leftVarSwizzle, rightVarSwizzle, endNode.getName(), startNode.getName(), null); + startNode.addOutputMapping(mapping); + conn.makeKey(mapping, diagram1.getCurrentTechniqueName()); + } else { + InputMappingBlock mapping = new InputMappingBlock(leftVarName, rightVarName, leftVarSwizzle, rightVarSwizzle, endNode.getName(), startNode.getName(), null); + endNode.addInputMapping(mapping); + conn.makeKey(mapping, diagram1.getCurrentTechniqueName()); + } + } + + protected void notifyRemoveConnection(Connection conn) { + InOut startNode = (InOut) conn.start.getNode(); + InOut endNode = (InOut) conn.end.getNode(); + if (endNode instanceof OutBusPanel) { + startNode.removeOutputMapping((OutputMappingBlock) conn.mapping); + } else { + endNode.removeInputMapping((InputMappingBlock) conn.mapping); + } + } + + public void notifyAddNode(ShaderNodeBlock node, ShaderNodeDefinition def) { + MatDefBlock matDef = obj.getLookup().lookup(MatDefBlock.class); + TechniqueBlock technique = getTechnique(matDef); + if (def.getType() == Shader.ShaderType.Vertex) { + technique.addVertexShaderNode(node); + } else if (def.getType() == Shader.ShaderType.Fragment) { + technique.addFragmentShaderNode(node); + } + } + + public void notifyAddMapParam(String type, String name) { + MatDefBlock matDef = obj.getLookup().lookup(MatDefBlock.class); + //FIXME add a way to set fixed pipeline function and default value + MatParamBlock param = new MatParamBlock(type, name, null, null); + matDef.addMatParam(param); + } + + public void notifyAddWorldParam(String name) { + MatDefBlock matDef = obj.getLookup().lookup(MatDefBlock.class); + //FIXME add a way to set fixed pipeline function and default value + WorldParamBlock param = new WorldParamBlock(name); + getTechnique(matDef).addWorldParam(param); + } + + public void notifyRemoveNode(NodePanel node) { + MatDefBlock matDef = obj.getLookup().lookup(MatDefBlock.class); + if (node.getType() == NodePanel.NodeType.Fragment || node.getType() == NodePanel.NodeType.Vertex) { + TechniqueBlock technique = getTechnique(matDef); + for (ShaderNodeBlock shaderNodeBlock : technique.getShaderNodes()) { + if (shaderNodeBlock.getName().equals(node.getName())) { + technique.removeShaderNode(shaderNodeBlock); + } + } + } else if (node.getType() == NodePanel.NodeType.MatParam) { + matDef.removeMatParam(new MatParamBlock("", node.getKey().replaceAll("MatParam.", ""), "", "")); + } else if (node.getType() == NodePanel.NodeType.WorldParam) { + getTechnique(matDef).removeWorldParam(new WorldParamBlock(node.getKey().replaceAll("WorldParam.", ""))); + } else if (node.getType() == NodePanel.NodeType.Attribute) { + getTechnique(matDef).cleanupMappings("Attr", node.getKey().replaceAll("Attr.", "")); + } + } + + private Dot findConnectPoint(String nameSpace, String name, boolean isInput) { + + if (nameSpace.equals("MatParam") + || nameSpace.equals("WorldParam") + || nameSpace.equals("Attr")) { + NodePanel np = diagram1.getNodePanel(nameSpace + "." + name); + return isInput ? np.getInputConnectPoint(name) : np.getOutputConnectPoint(name); + } else if (nameSpace.equals("Global")) { + OutBusPanel outBus = diagram1.getOutBusPanel(name); + return outBus.getConnectPoint(); + } else { + NodePanel np = diagram1.getNodePanel(diagram1.getCurrentTechniqueName() + "/" + nameSpace); + return isInput ? np.getInputConnectPoint(name) : np.getOutputConnectPoint(name); + } + } + + private void makeConnection(MappingBlock mapping) { + + Dot leftDot = findConnectPoint(mapping.getLeftNameSpace(), mapping.getLeftVar(), true); + Dot rightDot = findConnectPoint(mapping.getRightNameSpace(), mapping.getRightVar(), false); + Connection conn = diagram1.connect(leftDot, rightDot); + mapping.addPropertyChangeListener(conn); + conn.makeKey(mapping, diagram1.getCurrentTechniqueName()); + } + + private void initData(TechniqueBlock technique, ProjectAssetManager manager, List vertexGlobals, List fragmentGlobals, List attributes, MatDefBlock matDef, List uniforms) { + for (ShaderNodeBlock sn : technique.getShaderNodes()) { + ShaderNodeDefinition def = MaterialUtils.loadShaderNodeDefinition(sn, manager); + List in = sn.getInputs(); + if (in != null) { + for (InputMappingBlock map : in) { + ShaderNodeVariable var = new ShaderNodeVariable("", map.getRightNameSpace(), map.getRightVar()); + if (var.getNameSpace().equals("Global")) { + var.setType("vec4"); + if (def.getType() == Shader.ShaderType.Vertex) { + if (!MaterialUtils.contains(vertexGlobals, var)) { + vertexGlobals.add(var); + } + } else { + if (!MaterialUtils.contains(fragmentGlobals, var)) { + fragmentGlobals.add(var); + } + } + } else if (var.getNameSpace().equals("Attr")) { + ShaderNodeVariable left = MaterialUtils.getVar(def.getInputs(), map.getLeftVar()); + var.setType(MaterialUtils.guessType(map, left)); + attributes.add(var); + } + } + } + List out = sn.getOutputs(); + if (out != null) { + for (OutputMappingBlock map : out) { + ShaderNodeVariable var = new ShaderNodeVariable("", map.getLeftNameSpace(), map.getLeftVar()); + if (var.getNameSpace().equals("Global")) { + var.setType("vec4"); + if (def.getType() == Shader.ShaderType.Vertex) { + if (!MaterialUtils.contains(vertexGlobals, var)) { + vertexGlobals.add(var); + } + } else { + if (!MaterialUtils.contains(fragmentGlobals, var)) { + fragmentGlobals.add(var); + } + } + } + } + } + + } + + + for (WorldParamBlock worldParamBlock : technique.getWorldParams()) { + ShaderNodeVariable var = new ShaderNodeVariable("", "WorldParam", worldParamBlock.getName()); + var.setType(MaterialUtils.getWorldParamType(var.getName())); + uniforms.add(var); + } + + for (MatParamBlock matParamBlock : matDef.getMatParams()) { + ShaderNodeVariable var = new ShaderNodeVariable("", "MatParam", matParamBlock.getName()); + var.setType(MaterialUtils.getMatParamType(matParamBlock)); + uniforms.add(var); + } + + } + + private TechniqueBlock getTechnique(MatDefBlock matDef) { + TechniqueBlock technique = matDef.getTechniques().get(0); + + return technique; + } + + protected Point getPositionFromMetaData(String key, int defaultx, int defaulty) throws NumberFormatException { + Point position = new Point(); + String pos = metaData.getProperty(diagram1.getCurrentTechniqueName() + "/" + key, defaultx + "," + defaulty); + + if (pos != null) { + String[] s = pos.split(","); + position.x = Integer.parseInt(s[0]); + position.y = Integer.parseInt(s[1]); + } + return position; + } + + protected void savePositionToMetaData(String key, int x, int y) throws NumberFormatException { + + metaData.setProperty(diagram1.getCurrentTechniqueName() + "/" + key, x + "," + y); + + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/MatPanel.form b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/MatPanel.form new file mode 100644 index 000000000..58e9d4739 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/MatPanel.form @@ -0,0 +1,277 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/MatPanel.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/MatPanel.java new file mode 100644 index 000000000..b578d5ee0 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/MatPanel.java @@ -0,0 +1,379 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.editor; + +import com.jme3.gde.core.assets.ProjectAssetManager; +import com.jme3.gde.materials.MaterialPreviewRenderer; +import com.jme3.material.Material; +import java.awt.Component; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ComponentEvent; +import java.awt.event.ComponentListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import javax.swing.SwingUtilities; +import javax.swing.Timer; + +/** + * + * @author Nehon + */ +public class MatPanel extends javax.swing.JPanel implements MouseListener,ComponentListener { + + + private MaterialPreviewRenderer renderer; + private Material mat; + /** + * Creates new form PreviewPanel + */ + public MatPanel() { + initComponents(); + setBounds(0, 0, 120, 120); + toolBar.setVisible(false); + addMouseListener(this); + renderer = new MaterialPreviewRenderer(previewLabel); + } + + public void cleanup(){ + renderer.cleanUp(); + cleanup(); + } + + public void showMaterial(Material mat) { + this.mat = mat; + renderer.showMaterial(mat); + } + + + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + toolBar = new javax.swing.JPanel(); + sphereButton = new javax.swing.JButton(); + boxButton = new javax.swing.JButton(); + reloadButton = new javax.swing.JButton(); + quadButton = new javax.swing.JButton(); + expandButton = new javax.swing.JButton(); + previewLabel = new javax.swing.JLabel(); + + setOpaque(false); + setLayout(null); + + toolBar.setOpaque(false); + + sphereButton.setBackground(new java.awt.Color(153, 153, 153)); + sphereButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/jme3/gde/materialdefinition/icons/Sphere.png"))); // NOI18N + sphereButton.setToolTipText("Sphere"); + sphereButton.setBorder(null); + sphereButton.setBorderPainted(false); + sphereButton.setContentAreaFilled(false); + sphereButton.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); + sphereButton.setFocusable(false); + sphereButton.setIconTextGap(0); + sphereButton.setMaximumSize(new java.awt.Dimension(24, 24)); + sphereButton.setMinimumSize(new java.awt.Dimension(24, 24)); + sphereButton.setPreferredSize(new java.awt.Dimension(24, 24)); + sphereButton.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseEntered(java.awt.event.MouseEvent evt) { + sphereButtonMouseEntered(evt); + } + public void mouseExited(java.awt.event.MouseEvent evt) { + sphereButtonMouseExited(evt); + } + }); + sphereButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + sphereButtonActionPerformed(evt); + } + }); + + boxButton.setBackground(new java.awt.Color(153, 153, 153)); + boxButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/jme3/gde/materialdefinition/icons/cube.png"))); // NOI18N + boxButton.setToolTipText("Cube"); + boxButton.setBorder(null); + boxButton.setBorderPainted(false); + boxButton.setContentAreaFilled(false); + boxButton.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); + boxButton.setFocusable(false); + boxButton.setIconTextGap(0); + boxButton.setMaximumSize(new java.awt.Dimension(24, 24)); + boxButton.setMinimumSize(new java.awt.Dimension(24, 24)); + boxButton.setPreferredSize(new java.awt.Dimension(24, 24)); + boxButton.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseEntered(java.awt.event.MouseEvent evt) { + boxButtonMouseEntered(evt); + } + public void mouseExited(java.awt.event.MouseEvent evt) { + boxButtonMouseExited(evt); + } + }); + boxButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + boxButtonActionPerformed(evt); + } + }); + + reloadButton.setBackground(new java.awt.Color(153, 153, 153)); + reloadButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/jme3/gde/materialdefinition/icons/reload.png"))); // NOI18N + reloadButton.setToolTipText("Refresh"); + reloadButton.setBorder(null); + reloadButton.setBorderPainted(false); + reloadButton.setContentAreaFilled(false); + reloadButton.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); + reloadButton.setFocusable(false); + reloadButton.setIconTextGap(0); + reloadButton.setMaximumSize(new java.awt.Dimension(24, 24)); + reloadButton.setMinimumSize(new java.awt.Dimension(24, 24)); + reloadButton.setPreferredSize(new java.awt.Dimension(24, 24)); + reloadButton.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseEntered(java.awt.event.MouseEvent evt) { + reloadButtonMouseEntered(evt); + } + public void mouseExited(java.awt.event.MouseEvent evt) { + reloadButtonMouseExited(evt); + } + }); + reloadButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + reloadButtonActionPerformed(evt); + } + }); + + quadButton.setBackground(new java.awt.Color(153, 153, 153)); + quadButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/jme3/gde/materialdefinition/icons/Quad.png"))); // NOI18N + quadButton.setToolTipText("Quad"); + quadButton.setBorder(null); + quadButton.setBorderPainted(false); + quadButton.setContentAreaFilled(false); + quadButton.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); + quadButton.setFocusable(false); + quadButton.setIconTextGap(0); + quadButton.setMaximumSize(new java.awt.Dimension(24, 24)); + quadButton.setMinimumSize(new java.awt.Dimension(24, 24)); + quadButton.setPreferredSize(new java.awt.Dimension(24, 24)); + quadButton.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseEntered(java.awt.event.MouseEvent evt) { + quadButtonMouseEntered(evt); + } + public void mouseExited(java.awt.event.MouseEvent evt) { + quadButtonMouseExited(evt); + } + }); + quadButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + quadButtonActionPerformed(evt); + } + }); + + expandButton.setBackground(new java.awt.Color(153, 153, 153)); + expandButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/jme3/gde/materialdefinition/icons/expend.png"))); // NOI18N + expandButton.setToolTipText("Expand"); + expandButton.setBorder(null); + expandButton.setBorderPainted(false); + expandButton.setContentAreaFilled(false); + expandButton.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); + expandButton.setFocusable(false); + expandButton.setIconTextGap(0); + expandButton.setMaximumSize(new java.awt.Dimension(24, 24)); + expandButton.setMinimumSize(new java.awt.Dimension(24, 24)); + expandButton.setPreferredSize(new java.awt.Dimension(24, 24)); + expandButton.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseEntered(java.awt.event.MouseEvent evt) { + expandButtonMouseEntered(evt); + } + public void mouseExited(java.awt.event.MouseEvent evt) { + expandButtonMouseExited(evt); + } + }); + expandButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + expandButtonActionPerformed(evt); + } + }); + + javax.swing.GroupLayout toolBarLayout = new javax.swing.GroupLayout(toolBar); + toolBar.setLayout(toolBarLayout); + toolBarLayout.setHorizontalGroup( + toolBarLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(toolBarLayout.createSequentialGroup() + .addGroup(toolBarLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(sphereButton, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(boxButton, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(quadButton, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap(104, Short.MAX_VALUE)) + .addGroup(toolBarLayout.createSequentialGroup() + .addComponent(expandButton, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(reloadButton, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE)) + ); + toolBarLayout.setVerticalGroup( + toolBarLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(toolBarLayout.createSequentialGroup() + .addGroup(toolBarLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(expandButton, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(reloadButton, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 39, Short.MAX_VALUE) + .addComponent(sphereButton, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(boxButton, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(quadButton, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(5, 5, 5)) + ); + + add(toolBar); + toolBar.setBounds(0, 0, 120, 120); + + previewLabel.setBackground(new java.awt.Color(100, 100, 100)); + previewLabel.setForeground(new java.awt.Color(100, 100, 100)); + previewLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + previewLabel.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + previewLabel.setIconTextGap(0); + previewLabel.setMaximumSize(new java.awt.Dimension(100, 100)); + previewLabel.setMinimumSize(new java.awt.Dimension(100, 100)); + previewLabel.setOpaque(true); + previewLabel.setPreferredSize(new java.awt.Dimension(100, 100)); + add(previewLabel); + previewLabel.setBounds(20, 20, 100, 100); + }// //GEN-END:initComponents + + private void expandButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_expandButtonActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_expandButtonActionPerformed + + private void expandButtonMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_expandButtonMouseEntered + mouseEntered(SwingUtilities.convertMouseEvent(expandButton, evt, this)); + }//GEN-LAST:event_expandButtonMouseEntered + + private void expandButtonMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_expandButtonMouseExited + mouseExited(SwingUtilities.convertMouseEvent(expandButton, evt, this)); + }//GEN-LAST:event_expandButtonMouseExited + + private void sphereButtonMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_sphereButtonMouseEntered + mouseEntered(SwingUtilities.convertMouseEvent(sphereButton, evt, this)); + }//GEN-LAST:event_sphereButtonMouseEntered + + private void sphereButtonMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_sphereButtonMouseExited + mouseExited(SwingUtilities.convertMouseEvent(sphereButton, evt, this)); + }//GEN-LAST:event_sphereButtonMouseExited + + private void sphereButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_sphereButtonActionPerformed + renderer.switchDisplay(MaterialPreviewRenderer.DisplayType.Sphere); + refresh(); + }//GEN-LAST:event_sphereButtonActionPerformed + + private void boxButtonMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_boxButtonMouseEntered + mouseEntered(SwingUtilities.convertMouseEvent(boxButton, evt, this)); + }//GEN-LAST:event_boxButtonMouseEntered + + private void boxButtonMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_boxButtonMouseExited + mouseExited(SwingUtilities.convertMouseEvent(boxButton, evt, this)); + }//GEN-LAST:event_boxButtonMouseExited + + private void boxButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_boxButtonActionPerformed + renderer.switchDisplay(MaterialPreviewRenderer.DisplayType.Box); + refresh(); + }//GEN-LAST:event_boxButtonActionPerformed + + private void reloadButtonMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_reloadButtonMouseEntered + mouseEntered(SwingUtilities.convertMouseEvent(reloadButton, evt, this)); + }//GEN-LAST:event_reloadButtonMouseEntered + + private void reloadButtonMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_reloadButtonMouseExited + mouseExited(SwingUtilities.convertMouseEvent(reloadButton, evt, this)); + }//GEN-LAST:event_reloadButtonMouseExited + + private void reloadButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_reloadButtonActionPerformed + refresh(); + }//GEN-LAST:event_reloadButtonActionPerformed + + private void quadButtonMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_quadButtonMouseEntered + mouseEntered(SwingUtilities.convertMouseEvent(quadButton, evt, this)); + }//GEN-LAST:event_quadButtonMouseEntered + + private void quadButtonMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_quadButtonMouseExited + mouseExited(SwingUtilities.convertMouseEvent(quadButton, evt, this)); + }//GEN-LAST:event_quadButtonMouseExited + + private void quadButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_quadButtonActionPerformed + renderer.switchDisplay(MaterialPreviewRenderer.DisplayType.Quad); + refresh(); + }//GEN-LAST:event_quadButtonActionPerformed + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton boxButton; + private javax.swing.JButton expandButton; + private javax.swing.JLabel previewLabel; + private javax.swing.JButton quadButton; + private javax.swing.JButton reloadButton; + private javax.swing.JButton sphereButton; + private javax.swing.JPanel toolBar; + // End of variables declaration//GEN-END:variables + + @Override + public void mouseClicked(MouseEvent e) { + } + + @Override + public void mousePressed(MouseEvent e) { + } + + @Override + public void mouseReleased(MouseEvent e) { + } + + @Override + public void mouseEntered(MouseEvent e) { + toolBar.setVisible(true); + t.stop(); + } + Timer t = new Timer(500, new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + toolBar.setVisible(false); + } + }); + + @Override + public void mouseExited(MouseEvent e) { + t.restart(); + } + + @Override + public void componentResized(ComponentEvent e) { + update(e.getComponent()); + } + + @Override + public void componentMoved(ComponentEvent e) { + update(e.getComponent()); + } + + @Override + public void componentShown(ComponentEvent e) { + update(e.getComponent()); + } + + @Override + public void componentHidden(ComponentEvent e) { + } + + protected void update(Component c) { + setLocation(c.getLocation().x + c.getWidth() - 150, c.getLocation().y + 10 - 120); + } + + private void refresh() { + if(mat!=null){ + renderer.showMaterial(mat); + } + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/NodePanel.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/NodePanel.java new file mode 100644 index 000000000..58e2a7b2d --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/NodePanel.java @@ -0,0 +1,460 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.editor; + +import com.jme3.gde.materialdefinition.fileStructure.ShaderNodeBlock; +import com.jme3.gde.materialdefinition.fileStructure.leaves.InputMappingBlock; +import com.jme3.gde.materialdefinition.fileStructure.leaves.OutputMappingBlock; +import com.jme3.gde.materialdefinition.icons.Icons; +import com.jme3.shader.Shader; +import com.jme3.shader.ShaderNodeDefinition; +import com.jme3.shader.ShaderNodeVariable; +import java.awt.Color; +import java.awt.Font; +import java.awt.GradientPaint; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RadialGradientPaint; +import java.awt.RenderingHints; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.ArrayList; +import java.util.List; +import javax.swing.GroupLayout; +import javax.swing.ImageIcon; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.LayoutStyle; +import javax.swing.SwingConstants; +import javax.swing.SwingUtilities; +import org.openide.util.WeakListeners; + +/** + * + * @author Nehon + */ +public class NodePanel extends DraggablePanel implements Selectable, PropertyChangeListener, InOut, KeyListener { + + List inputLabels = new ArrayList(); + List outputLabels = new ArrayList(); + List inputDots = new ArrayList(); + List outputDots = new ArrayList(); + private NodeType type = NodeType.Vertex; + private JPanel content; + private JLabel header; + private Color color; + private String name; + private String techName; + +// private List listeners = Collections.synchronizedList(new LinkedList()); +// +// public void addPropertyChangeListener(PropertyChangeListener pcl) { +// listeners.add(pcl); +// } +// +// public void removePropertyChangeListener(PropertyChangeListener pcl) { +// listeners.remove(pcl); +// } +// +// protected void fire(String propertyName, Object old, Object nue) { +// //Passing 0 below on purpose, so you only synchronize for one atomic call: +// PropertyChangeListener[] pcls = (PropertyChangeListener[]) listeners.toArray(new PropertyChangeListener[0]); +// for (int i = 0; i < pcls.length; i++) { +// pcls[i].propertyChange(new PropertyChangeEvent(this, propertyName, old, nue)); +// } +// } + public enum NodeType { + + Vertex(new Color(220, 220, 70)),//yellow + Fragment(new Color(114, 200, 255)),//bleue + Attribute(Color.WHITE), + MatParam(new Color(70, 220, 70)),//green + WorldParam(new Color(220, 70, 70)); //red + private Color color; + + private NodeType() { + } + + private NodeType(Color color) { + this.color = color; + } + + public Color getColor() { + return color; + } + } + + /** + * Creates new form NodePanel + */ + public NodePanel(ShaderNodeBlock node, ShaderNodeDefinition def) { + super(); + if (def.getType() == Shader.ShaderType.Vertex) { + type = NodePanel.NodeType.Vertex; + } else { + type = NodePanel.NodeType.Fragment; + } + init(def.getInputs(), def.getOutputs()); + + node.addPropertyChangeListener(WeakListeners.propertyChange(this, node)); + this.addPropertyChangeListener(WeakListeners.propertyChange(node, this)); + refresh(node); + addKeyListener(this); + } + + /** + * Creates new form NodePanel + */ + public NodePanel(ShaderNodeVariable singleOut, NodePanel.NodeType type) { + super(); + List outputs = new ArrayList(); + outputs.add(singleOut); + this.type = type; + init(new ArrayList(), outputs); + addKeyListener(this); + } + + public final void refresh(ShaderNodeBlock node) { + name = node.getName(); + header.setText(node.getName()); + header.setToolTipText(node.getName()); + + } + + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("name")) { + refresh((ShaderNodeBlock) evt.getSource()); + } + } + + private void init(List inputs, List outputs) { + + setBounds(0, 0, 120, 30 + inputs.size() * 20 + outputs.size() * 20); + + for (ShaderNodeVariable input : inputs) { + + JLabel label = createLabel(input.getType(), input.getName(), Dot.ParamType.Input); + Dot dot = createDot(input.getType(), Dot.ParamType.Input, input.getName()); + inputLabels.add(label); + inputDots.add(dot); + } + int index = 0; + for (ShaderNodeVariable output : outputs) { + String outName = output.getName(); + JLabel label = createLabel(output.getType(), outName, Dot.ParamType.Output); + Dot dot = createDot(output.getType(), Dot.ParamType.Output, outName); + dot.setIndex(index++); + outputLabels.add(label); + outputDots.add(dot); + } + + initComponents(); + updateType(); + setOpaque(false); + + } + + public void setTitle(String s) { + header.setText(s); + header.setToolTipText(s); + } + + public Dot getInputConnectPoint(String varName) { + return getConnectPoint(inputLabels, varName, inputDots); + } + + public Dot getOutputConnectPoint(String varName) { + return getConnectPoint(outputLabels, varName, outputDots); + } + + private Dot getConnectPoint(List list, String varName, List listDot) { + if (varName.startsWith("m_") || varName.startsWith("g_")) { + varName = varName.substring(2); + } + for (int i = 0; i < list.size(); i++) { + if (list.get(i).getText().equals(varName)) { + return listDot.get(i); + } + } + return null; + } + + @Override + protected void paintComponent(Graphics g1) { + Graphics2D g = (Graphics2D) g1; + Color boderColor = Color.BLACK; + if (diagram.selectedItem == this) { + boderColor = Color.WHITE; + } + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, // Anti-alias! + RenderingHints.VALUE_ANTIALIAS_ON); + Color[] colors = {new Color(0, 0, 0, 0.7f), new Color(0, 0, 0, 0.15f)}; + if (diagram.selectedItem == this) { + colors = new Color[]{new Color(0.6f, 0.6f, 1.0f, 0.9f), new Color(0.6f, 0.6f, 1.0f, 0.5f)}; + } + float[] factors = {0f, 1f}; + g.setPaint(new RadialGradientPaint(getWidth() / 2, getHeight() / 2, getWidth() / 2, factors, colors)); + g.fillRoundRect(8, 3, getWidth() - 10, getHeight() - 6, 15, 15); + g.setColor(new Color(170, 170, 170)); + g.fillRoundRect(5, 1, getWidth() - 9, getHeight() - 6, 15, 15); + g.setColor(boderColor); + + g.drawRoundRect(4, 0, getWidth() - 9, getHeight() - 6, 15, 15); + g.setColor(new Color(170, 170, 170)); + g.fillRect(4, 1, 10, 10); + g.setColor(boderColor); + g.drawLine(4, 0, 14, 0); + g.drawLine(4, 0, 4, 10); + g.setColor(Color.BLACK); + g.drawLine(5, 15, getWidth() - 6, 15); + g.setColor(new Color(190, 190, 190)); + g.drawLine(5, 16, getWidth() - 6, 16); + + Color c1 = new Color(color.getRed(), color.getGreen(), color.getBlue(), 150); + Color c2 = new Color(color.getRed(), color.getGreen(), color.getBlue(), 0); + g.setPaint(new GradientPaint(0, 15, c1, getWidth(), 15, c2)); + g.fillRect(5, 1, getWidth() - 10, 14); + + } + + public String getKey() { + switch (type) { + case Attribute: + return "Attr." + outputLabels.get(0).getText(); + case WorldParam: + return "WorldParam." + outputLabels.get(0).getText(); + case MatParam: + return "MatParam." + outputLabels.get(0).getText(); + default: + return techName + "/" + name; + } + } + + @Override + public String getName() { + return name; + } + + @Override + public void mousePressed(MouseEvent e) { + super.mousePressed(e); + diagram.select(this); + } + + public NodeType getType() { + return type; + } + + @Override + public void mouseReleased(MouseEvent e) { + diagram.fixSize(); + if (svdx != getLocation().x) { + firePropertyChange(ShaderNodeBlock.POSITION, svdx, getLocation().x); + getDiagram().getEditorParent().savePositionToMetaData(getKey(), getLocation().x, getLocation().y); + } + } + + public final void updateType() { + + switch (type) { + case Vertex: + header.setIcon(Icons.vert); + break; + case Fragment: + header.setIcon(Icons.frag); + break; + case Attribute: + header.setIcon(Icons.attrib); + header.setText("Attribute"); + header.setToolTipText("Attribute"); + name = "Attr"; + break; + case WorldParam: + header.setIcon(Icons.world); + header.setText("WorldParam"); + header.setToolTipText("WorldParam"); + name = "WorldParam"; + break; + case MatParam: + header.setIcon(Icons.mat); + header.setText("MatParam"); + header.setToolTipText("MatParam"); + name = "MatParam"; + break; + } + color = type.getColor(); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // + private void initComponents() { + + + + ImageIcon icon = Icons.vert; + if (type == NodeType.Fragment) { + icon = Icons.frag; + } + header = new JLabel(icon); + header.addMouseListener(labelMouseMotionListener); + header.addMouseMotionListener(labelMouseMotionListener); + header.setHorizontalAlignment(SwingConstants.LEFT); + header.setFont(new Font("Tahoma", Font.BOLD, 11)); + content = new JPanel(); + content.setOpaque(false); + GroupLayout contentLayout = new GroupLayout(content); + content.setLayout(contentLayout); + + + + int txtLength = 100; + + GroupLayout.ParallelGroup grpHoriz = contentLayout.createParallelGroup(GroupLayout.Alignment.LEADING); + + for (int i = 0; i < outputDots.size(); i++) { + grpHoriz.addGroup(GroupLayout.Alignment.TRAILING, contentLayout.createSequentialGroup() + .addGap(0, 0, Short.MAX_VALUE) + .addComponent(outputLabels.get(i), GroupLayout.PREFERRED_SIZE, txtLength, GroupLayout.PREFERRED_SIZE) + .addGap(2, 2, 2) + .addComponent(outputDots.get(i), GroupLayout.PREFERRED_SIZE, 10, GroupLayout.PREFERRED_SIZE)); + } + for (int i = 0; i < inputDots.size(); i++) { + grpHoriz.addGroup(GroupLayout.Alignment.LEADING, contentLayout.createSequentialGroup() + .addComponent(inputDots.get(i), GroupLayout.PREFERRED_SIZE, 10, GroupLayout.PREFERRED_SIZE) + .addGap(2, 2, 2) + .addComponent(inputLabels.get(i), GroupLayout.PREFERRED_SIZE, txtLength, GroupLayout.PREFERRED_SIZE)); + } + + contentLayout.setHorizontalGroup(grpHoriz); + + GroupLayout.ParallelGroup grpVert = contentLayout.createParallelGroup(GroupLayout.Alignment.LEADING); + + GroupLayout.SequentialGroup grp = contentLayout.createSequentialGroup(); + for (int i = 0; i < inputDots.size(); i++) { + grp.addGroup(contentLayout.createParallelGroup(GroupLayout.Alignment.CENTER) + .addComponent(inputDots.get(i), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(inputLabels.get(i))).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED); + } + for (int i = 0; i < outputDots.size(); i++) { + grp.addGroup(contentLayout.createParallelGroup(GroupLayout.Alignment.CENTER) + .addComponent(outputDots.get(i), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(outputLabels.get(i))).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED); + } + + + grpVert.addGroup(GroupLayout.Alignment.TRAILING, grp); + + contentLayout.setVerticalGroup(grpVert); + + GroupLayout layout = new GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(GroupLayout.Alignment.LEADING, layout.createSequentialGroup() + .addGap(6, 6, 6) + .addComponent(header, 100, 100, 100)) + .addGroup(GroupLayout.Alignment.LEADING, layout.createSequentialGroup() + .addGap(6, 6, 6)) + .addComponent(content, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)); + layout.setVerticalGroup( + layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(header, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addGap(10, 10, 10) + .addComponent(content, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addGap(10, 10, 10)); + } + + public JLabel createLabel(String glslType, String txt, Dot.ParamType type) { + JLabel label = new JLabel(txt); + label.setToolTipText(glslType + " " + txt); + label.setOpaque(false); + //label.setPreferredSize(new Dimension(50, 15)); + label.setHorizontalAlignment(type == Dot.ParamType.Output ? SwingConstants.RIGHT : SwingConstants.LEFT); + label.setFont(new Font("Tahoma", 0, 10)); + label.addMouseListener(labelMouseMotionListener); + label.addMouseMotionListener(labelMouseMotionListener); + // label.setBorder(BorderFactory.createLineBorder(Color.BLACK)); + return label; + } + + public Dot createDot(String type, Dot.ParamType paramType, String paramName) { + Dot dot1 = new Dot(); + dot1.setNode(this); + dot1.setText(paramName); + dot1.setParamType(paramType); + dot1.setType(type); + return dot1; + } + + public void keyTyped(KeyEvent e) { + } + + @Override + public void keyPressed(KeyEvent e) { + + if (e.getKeyCode() == KeyEvent.VK_DELETE) { + Diagram diag = getDiagram(); + if (diag.selectedItem == this) { + diag.removeSelectedNode(); + } + } + } + + public void keyReleased(KeyEvent e) { + } + // used to pass press and drag events to the NodePanel when they occur on the label + private LabelMouseMotionListener labelMouseMotionListener = new LabelMouseMotionListener(); + + private class LabelMouseMotionListener extends MouseAdapter { + + @Override + public void mousePressed(MouseEvent e) { + MouseEvent me = SwingUtilities.convertMouseEvent(e.getComponent(), e, NodePanel.this); + NodePanel.this.dispatchEvent(me); + } + + @Override + public void mouseDragged(MouseEvent e) { + MouseEvent me = SwingUtilities.convertMouseEvent(e.getComponent(), e, NodePanel.this); + NodePanel.this.dispatchEvent(me); + } + + @Override + public void mouseReleased(MouseEvent e) { + MouseEvent me = SwingUtilities.convertMouseEvent(e.getComponent(), e, NodePanel.this); + NodePanel.this.dispatchEvent(me); + } + } + + public void setTechName(String techName) { + this.techName = techName; + } + + public void addInputMapping(InputMappingBlock block) { + firePropertyChange(ShaderNodeBlock.INPUT, null, block); + } + + public void removeInputMapping(InputMappingBlock block) { + firePropertyChange(ShaderNodeBlock.INPUT, block, null); + } + + public void addOutputMapping(OutputMappingBlock block) { + firePropertyChange(ShaderNodeBlock.OUTPUT, null, block); + } + + public void removeOutputMapping(OutputMappingBlock block) { + firePropertyChange(ShaderNodeBlock.OUTPUT, block, null); + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/OutBusPanel.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/OutBusPanel.java new file mode 100644 index 000000000..2070f0d10 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/OutBusPanel.java @@ -0,0 +1,283 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.editor; + +import com.jme3.gde.materialdefinition.fileStructure.leaves.InputMappingBlock; +import com.jme3.gde.materialdefinition.fileStructure.leaves.OutputMappingBlock; +import com.jme3.material.Material; +import com.jme3.shader.Shader; +import java.awt.Color; +import java.awt.GradientPaint; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.LinearGradientPaint; +import java.awt.Point; +import java.awt.Polygon; +import java.awt.RenderingHints; +import java.awt.event.ComponentEvent; +import java.awt.event.ComponentListener; +import java.awt.event.MouseEvent; +import javax.swing.GroupLayout; +import javax.swing.JLabel; +import javax.swing.SwingUtilities; + +/** + * + * @author m327836 + */ +public class OutBusPanel extends DraggablePanel implements ComponentListener, Selectable, InOut { + + private Color color = new Color(220, 220, 70); + private String name = ""; + private InnerPanel panel; + private MatPanel preview; + private Shader.ShaderType type; + + public OutBusPanel(String name, Shader.ShaderType type) { + this(name); + this.type = type; + if (type == Shader.ShaderType.Fragment) { + this.color = new Color(114, 200, 255); + } + } + + private OutBusPanel(String name) { + super(true); + setBounds(0, 0, 300, 50); + JLabel title = new JLabel(); + this.name = name; + title.setFont(new java.awt.Font("Impact", 1, 15)); // NOI18N + title.setForeground(new java.awt.Color(153, 153, 153)); + title.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + title.setText(name); + setOpaque(false); + panel = new InnerPanel(); + + javax.swing.GroupLayout outBusPanel1Layout = new javax.swing.GroupLayout(this); + this.setLayout(outBusPanel1Layout); + outBusPanel1Layout.setHorizontalGroup( + outBusPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, outBusPanel1Layout.createSequentialGroup() + .addContainerGap(70, 70) + .addComponent(panel, 20, 200, Short.MAX_VALUE) + .addComponent(title, GroupLayout.PREFERRED_SIZE, 70, GroupLayout.PREFERRED_SIZE) + .addGap(30, 30, 30))); + outBusPanel1Layout.setVerticalGroup( + outBusPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(outBusPanel1Layout.createSequentialGroup() + .addContainerGap() + .addComponent(title, javax.swing.GroupLayout.DEFAULT_SIZE, 28, Short.MAX_VALUE) + .addContainerGap()) + .addGroup(outBusPanel1Layout.createSequentialGroup() + .addContainerGap(20, 20) + .addComponent(panel, 10, 10, 10) + .addContainerGap())); + + preview = new MatPanel(); + addComponentListener(preview); + + } + + @Override + public void setDiagram(Diagram diagram) { + super.setDiagram(diagram); + // preview.setBounds(350,300,128,100); + diagram.add(preview); + preview.update(this); + } + + @Override + protected void paintComponent(Graphics g1) { + Graphics2D g = (Graphics2D) g1; + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, // Anti-alias! + RenderingHints.VALUE_ANTIALIAS_ON); + + int width = getWidth(); + int[] xs = {38, width - 30, width - 30, width, width - 30, width - 30, 38, 38}; + int[] ys = {10, 10, 0, getHeight() / 2, getHeight(), getHeight() - 10, getHeight() - 10, 10}; + + Polygon p = new Polygon(xs, ys, 8); + + if (diagram.selectedItem == this) { + int[] xs2 = {0, width - 30, width - 30, width, width - 32, width - 32, 0, 0}; + int[] ys2 = {10, 10, 0, getHeight() / 2 + 2, getHeight(), getHeight() - 8, getHeight() - 8, 10}; + + Polygon p2 = new Polygon(xs2, ys2, 8); + g.setPaint(new GradientPaint(0, 0, new Color(0.6f, 0.6f, 1.0f, 0.9f), 0, getHeight(), new Color(0.6f, 0.6f, 1.0f, 0.5f))); + g.fillPolygon(p2); + } + + Color c1 = new Color(100, 100, 100, 255); + Color c2 = new Color(100, 100, 100, 100); + g.setPaint(new GradientPaint(0, 0, c1, width, 0, c2)); + g.fillPolygon(p); + g.fillRect(0, 10, 3, getHeight() - 20); + g.fillRect(5, 10, 6, getHeight() - 20); + g.fillRect(13, 10, 9, getHeight() - 20); + g.fillRect(24, 10, 12, getHeight() - 20); + + + } + + @Override + public void componentResized(ComponentEvent e) { + setSize(e.getComponent().getWidth(), 50); + } + + @Override + public void componentMoved(ComponentEvent e) { + } + + @Override + public void componentShown(ComponentEvent e) { + } + + @Override + public void componentHidden(ComponentEvent e) { + } + + @Override + public void mousePressed(MouseEvent e) { + if (dispatchToInnerPanel(e)) { + return; + } + super.mousePressed(e); + diagram.select(this); + } + + @Override + public void mouseDragged(MouseEvent e) { + if (panel.dragging == false) { + super.mouseDragged(e); + } + } + + protected void draggingDot(MouseEvent e) { + Point p = SwingUtilities.convertPoint(this, e.getX(), e.getY(), panel); + if (panel.contains(p)) { + MouseEvent me = SwingUtilities.convertMouseEvent(this, e, panel); + panel.mouseEntered(me); + } else { + MouseEvent me = SwingUtilities.convertMouseEvent(this, e, panel); + panel.mouseExited(me); + } + } + + public Dot getConnectPoint() { + return panel; + } + + public void updatePreview(Material mat) { + if (type == Shader.ShaderType.Fragment) { + preview.showMaterial(mat); + } else { + Material vmat = mat.clone(); + vmat.getAdditionalRenderState().setWireframe(true); + preview.showMaterial(vmat); + } + } + + @Override + public String getName() { + return "Global"; + } + + @Override + public void mouseReleased(MouseEvent e) { + diagram.fixSize(); + MouseEvent me = SwingUtilities.convertMouseEvent(this, e, panel); + panel.mouseReleased(me); + getDiagram().getEditorParent().savePositionToMetaData(getKey(), 0, getLocation().y); + + } + + public String getKey() { + return name; + } + + private boolean dispatchToInnerPanel(MouseEvent e) { + Point p = SwingUtilities.convertPoint(this, e.getX(), e.getY(), panel); + if (panel.contains(p)) { + MouseEvent me = SwingUtilities.convertMouseEvent(this, e, panel); + panel.dispatchEvent(me); + if (me.isConsumed()) { + return true; + } + } + return false; + } + + public void addInputMapping(InputMappingBlock block) { + } + + public void removeInputMapping(InputMappingBlock block) { + } + + public void addOutputMapping(OutputMappingBlock block) { + } + + public void removeOutputMapping(OutputMappingBlock block) { + } + + class InnerPanel extends Dot { + + boolean over = false; + boolean dragging = false; + + public InnerPanel() { + setOpaque(false); + setNode(OutBusPanel.this); + setParamType(Dot.ParamType.Both); + setType("vec4"); + setText(name); + } + + @Override + protected void paintComponent(Graphics g1) { + Graphics2D g = (Graphics2D) g1; + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, // Anti-alias! + RenderingHints.VALUE_ANTIALIAS_ON); + + Color c1 = new Color(color.getRed(), color.getGreen(), color.getBlue(), 255); + Color c2 = new Color(color.getRed(), color.getGreen(), color.getBlue(), 0); + g.setPaint(new LinearGradientPaint(0, 0, 0, getHeight(), new float[]{0, 0.5f, 1}, new Color[]{c2, c1, c2})); + g.fillRoundRect(1, 1, getWidth() - 1, getHeight() - 1, 10, 10); + + } + + @Override + public void mousePressed(MouseEvent e) { + super.mousePressed(e); + dragging = true; + } + + @Override + public void mouseDragged(MouseEvent e) { + e.consume(); + } + + @Override + public void mouseReleased(MouseEvent e) { + super.mouseReleased(e); + dragging = false; + } + + @Override + public void mouseEntered(MouseEvent e) { + if (!over) { + super.mouseEntered(e); + over = true; + } + } + + @Override + public void mouseExited(MouseEvent e) { + if (over) { + super.mouseExited(e); + over = false; + } + } + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/Selectable.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/Selectable.java new file mode 100644 index 000000000..201e30d81 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/Selectable.java @@ -0,0 +1,16 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.editor; + +/** + * + * @author m327836 + */ +public interface Selectable { + + public String getKey(); + + +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/FragmentShaderNodesBlock.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/FragmentShaderNodesBlock.java new file mode 100644 index 000000000..32f2a3e13 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/FragmentShaderNodesBlock.java @@ -0,0 +1,22 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.fileStructure; + +import com.jme3.util.blockparser.Statement; + +/** + * + * @author Nehon + */ +public class FragmentShaderNodesBlock extends ShaderNodesBlock { + + public FragmentShaderNodesBlock(int lineNumber, String line) { + super(lineNumber, line); + } + + public FragmentShaderNodesBlock(Statement sta) { + super(sta); + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/InputMappingsBlock.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/InputMappingsBlock.java new file mode 100644 index 000000000..3d5155d51 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/InputMappingsBlock.java @@ -0,0 +1,42 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.fileStructure; + +import com.jme3.gde.materialdefinition.fileStructure.*; +import com.jme3.gde.materialdefinition.fileStructure.leaves.InputMappingBlock; +import com.jme3.gde.materialdefinition.fileStructure.leaves.MatParamBlock; +import com.jme3.gde.materialdefinition.fileStructure.leaves.OutputMappingBlock; +import com.jme3.util.blockparser.Statement; +import java.util.List; + +/** + * + * @author Nehon + */ +public class InputMappingsBlock extends UberStatement { + + protected InputMappingsBlock(int lineNumber, String line) { + super(lineNumber, line); + } + + public InputMappingsBlock(Statement sta, String nodeName) { + this(sta.getLineNumber(), sta.getLine()); + for (Statement statement : sta.getContents()) { + addStatement(new InputMappingBlock(statement, nodeName)); + } + } + + public List getMappings() { + return getBlocks(InputMappingBlock.class); + } + + public void addMapping(InputMappingBlock mapping) { + addStatement(mapping); + } + + public void removeMapping(InputMappingBlock mapping) { + contents.remove(mapping); + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/MatDefBlock.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/MatDefBlock.java new file mode 100644 index 000000000..203181951 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/MatDefBlock.java @@ -0,0 +1,94 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.fileStructure; + +import com.jme3.gde.materialdefinition.fileStructure.leaves.MatParamBlock; +import com.jme3.gde.materialdefinition.fileStructure.leaves.UnsupportedStatement; +import com.jme3.util.blockparser.Statement; +import java.util.List; + +/** + * + * @author Nehon + */ +public class MatDefBlock extends UberStatement { + + public static final String ADD_MAT_PARAM = "addMatParam"; + public static final String REMOVE_MAT_PARAM = "removeMatParam"; + protected String name; + + protected MatDefBlock(int lineNumber, String line) { + super(lineNumber, line); + } + + public MatDefBlock(Statement sta) { + this(sta.getLineNumber(), sta.getLine()); + for (Statement statement : sta.getContents()) { + if (statement.getLine().trim().startsWith("MaterialParameters")) { + addStatement(new MaterialParametersBlock(statement)); + } else if (statement.getLine().trim().startsWith("Technique")) { + addStatement(new TechniqueBlock(statement)); + } else { + addStatement(new UnsupportedStatement(statement)); + } + } + String[] s = line.split("\\s"); + name = s[1]; + } + + public String getName() { + return name; + } + + public void setName(String name) { + String oldName = this.name; + this.name = name; + line = "MaterialDef " + name; + fire("name", oldName, name); + } + + protected MaterialParametersBlock getMaterialParameters() { + return getBlock(MaterialParametersBlock.class); + } + + public List getMatParams() { + return getMaterialParameters().getMatParams(); + } + + public void addMatParam(MatParamBlock matParam) { + MaterialParametersBlock mpBlock = getMaterialParameters(); + if (mpBlock == null) { + mpBlock = new MaterialParametersBlock(0, "MaterialParameters"); + addStatement(0, mpBlock); + } + mpBlock.addMatParam(matParam); + fire(ADD_MAT_PARAM, null, matParam); + } + + public void removeMatParam(MatParamBlock matParam) { + MaterialParametersBlock mpBlock = getMaterialParameters(); + if (mpBlock == null) { + return; + } + mpBlock.removeMatParam(matParam); + + for (TechniqueBlock techniqueBlock : getTechniques()) { + VertexShaderNodesBlock vblock = techniqueBlock.getBlock(VertexShaderNodesBlock.class); + FragmentShaderNodesBlock fblock = techniqueBlock.getBlock(FragmentShaderNodesBlock.class); + techniqueBlock.cleanMappings(vblock, "MatParam", matParam.getName()); + techniqueBlock.cleanMappings(fblock, "MatParam", matParam.getName()); + } + fire(REMOVE_MAT_PARAM, null, matParam); + } + + public List getTechniques() { + return getBlocks(TechniqueBlock.class); + } + + public void addTechnique(TechniqueBlock techniqueBlock) { + addStatement(techniqueBlock); + fire("technique", null, techniqueBlock); + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/MaterialParametersBlock.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/MaterialParametersBlock.java new file mode 100644 index 000000000..c5764c6ae --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/MaterialParametersBlock.java @@ -0,0 +1,40 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.fileStructure; + +import com.jme3.gde.materialdefinition.fileStructure.leaves.MatParamBlock; +import com.jme3.util.blockparser.Statement; +import java.util.ArrayList; +import java.util.List; + +/** + * + * @author Nehon + */ +public class MaterialParametersBlock extends UberStatement { + + protected MaterialParametersBlock(int lineNumber, String line) { + super(lineNumber, line); + } + + public MaterialParametersBlock(Statement sta) { + this(sta.getLineNumber(), sta.getLine()); + for (Statement statement : sta.getContents()) { + addStatement(new MatParamBlock(statement)); + } + } + + public List getMatParams() { + return getBlocks(MatParamBlock.class); + } + + public void addMatParam(MatParamBlock matParam){ + addStatement(matParam); + } + + public void removeMatParam(MatParamBlock matParam){ + contents.remove(matParam); + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/OutputMappingsBlock.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/OutputMappingsBlock.java new file mode 100644 index 000000000..2d92bdd0f --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/OutputMappingsBlock.java @@ -0,0 +1,39 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.fileStructure; + +import com.jme3.gde.materialdefinition.fileStructure.leaves.OutputMappingBlock; +import com.jme3.util.blockparser.Statement; +import java.util.List; + +/** + * + * @author Nehon + */ +public class OutputMappingsBlock extends UberStatement { + + protected OutputMappingsBlock(int lineNumber, String line) { + super(lineNumber, line); + } + + public OutputMappingsBlock(Statement sta, String nodeName) { + this(sta.getLineNumber(), sta.getLine()); + for (Statement statement : sta.getContents()) { + addStatement(new OutputMappingBlock(statement, nodeName)); + } + } + + public List getMappings() { + return getBlocks(OutputMappingBlock.class); + } + + public void addMapping(OutputMappingBlock mapping) { + addStatement(mapping); + } + + public void removeMapping(OutputMappingBlock mapping) { + contents.remove(mapping); + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/ShaderNodeBlock.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/ShaderNodeBlock.java new file mode 100644 index 000000000..c17f336a6 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/ShaderNodeBlock.java @@ -0,0 +1,250 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.fileStructure; + +import com.jme3.gde.materialdefinition.fileStructure.leaves.ConditionBlock; +import com.jme3.gde.materialdefinition.fileStructure.leaves.DefinitionBlock; +import com.jme3.gde.materialdefinition.fileStructure.leaves.InputMappingBlock; +import com.jme3.gde.materialdefinition.fileStructure.leaves.OutputMappingBlock; +import com.jme3.shader.ShaderNodeDefinition; +import com.jme3.util.blockparser.Statement; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.ArrayList; +import java.util.List; + +/** + * + * @author Nehon + */ +public class ShaderNodeBlock extends UberStatement implements Comparable, PropertyChangeListener { + + public final static String POSITION = "position"; + public final static String INPUT = "input"; + public final static String OUTPUT = "output"; + public static final String ADD_MAPPING = "addMapping"; + public static final String REMOVE_MAPPING = "removeMapping"; + protected String name; + //built up data for fast sorting + protected int spatialOrder; + protected List inputNodes = new ArrayList(); + protected boolean globalInput = false; + protected boolean globalOutput = false; + + protected ShaderNodeBlock(int lineNumber, String line) { + super(lineNumber, line); + } + + public ShaderNodeBlock(Statement sta) { + this(sta.getLineNumber(), sta.getLine()); + String[] s = line.split("\\s"); + name = s[1]; + for (Statement statement : sta.getContents()) { + if (statement.getLine().trim().startsWith("Definition")) { + addStatement(new DefinitionBlock(statement)); + } else if (statement.getLine().trim().startsWith("Condition")) { + addStatement(new ConditionBlock(statement)); + } else if (statement.getLine().trim().startsWith("InputMapping")) { + addStatement(new InputMappingsBlock(statement, name)); + } else if (statement.getLine().trim().startsWith("OutputMapping")) { + addStatement(new OutputMappingsBlock(statement, name)); + } else { + addStatement(statement); + } + } + + } + + public ShaderNodeBlock(ShaderNodeDefinition def, String path) { + super(0, "ShaderNode " + def.getName()); + name = def.getName(); + DefinitionBlock b = new DefinitionBlock(name, path); + addStatement(0, b); + } + + public String getName() { + return name; + } + + public void setName(String name) { + String oldName = this.name; + this.name = name; + line = "ShaderNode " + name; + fire("name", oldName, name); + } + + public void setSpatialOrder(int spatialOrder) { + this.spatialOrder = spatialOrder; + } + + public void addInputNode(String name) { + if (!inputNodes.contains(name)) { + inputNodes.add(name); + } + } + + public void setGlobalInput(boolean globalInput) { + this.globalInput = globalInput; + } + + public void setGlobalOutput(boolean globalOutput) { + this.globalOutput = globalOutput; + } + + public DefinitionBlock getDefinition() { + return getBlock(DefinitionBlock.class); + } + + public void setDefinition(String name, String path) { + DefinitionBlock b = getDefinition(); + + if (b == null) { + b = new DefinitionBlock(name, path); + addStatement(0, b); + } else { + b.setName(name); + b.setPath(path); + } + fire("definition", null, b); + } + + public String getCondition() { + ConditionBlock b = getBlock(ConditionBlock.class); + if (b == null) { + return null; + } + return b.getCondition(); + } + + public void setCondition(String condition) { + ConditionBlock b = getBlock(ConditionBlock.class); + String prevCond = null; + if (condition.trim().length() == 0 || condition.equals("")) { + condition = null; + } + if (b == null) { + if (condition == null) { + return; + } + b = new ConditionBlock(condition); + addStatement(b); + } else { + if (condition == null) { + contents.remove(b); + } + prevCond = b.getCondition(); + b.setCondition(condition); + } + fire("condition", prevCond, condition); + } + + public List getInputs() { + InputMappingsBlock b = getBlock(InputMappingsBlock.class); + if (b == null) { + return null; + } + return b.getMappings(); + } + + public List getOutputs() { + OutputMappingsBlock b = getBlock(OutputMappingsBlock.class); + if (b == null) { + return null; + } + return b.getMappings(); + } + + public void addInputMapping(InputMappingBlock mapping) { + InputMappingsBlock b = getBlock(InputMappingsBlock.class); + if (b == null) { + b = new InputMappingsBlock(0, "InputMappings"); + addStatement(b); + } + b.addMapping(mapping); + fire(ADD_MAPPING, null, mapping); + } + + public void addOutputMapping(OutputMappingBlock mapping) { + OutputMappingsBlock b = getBlock(OutputMappingsBlock.class); + if (b == null) { + b = new OutputMappingsBlock(0, "OutputMappings"); + addStatement(b); + } + b.addMapping(mapping); + fire(ADD_MAPPING, null, mapping); + } + + public void removeInputMapping(InputMappingBlock mapping) { + InputMappingsBlock b = getBlock(InputMappingsBlock.class); + if (b != null) { + b.removeMapping(mapping); + } + fire(REMOVE_MAPPING, mapping, null); + } + + public void removeOutputMapping(OutputMappingBlock mapping) { + OutputMappingsBlock b = getBlock(OutputMappingsBlock.class); + if (b != null) { + b.removeMapping(mapping); + } + fire(REMOVE_MAPPING, mapping, null); + } + + public int compareTo(ShaderNodeBlock o) { + if (inputNodes.contains(o.getName())) { + return 1; + } + if (o.inputNodes.contains(name)) { + return -1; + } + if ((globalInput && o.globalOutput) || (o.globalInput && globalOutput)) { + return (int) Math.signum(spatialOrder - o.spatialOrder); + } + return 0; + } + + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals(POSITION)) { + spatialOrder = (Integer) evt.getNewValue(); + fire("order", null, null); + } else if (evt.getPropertyName().equals(INPUT)) { + InputMappingBlock mapping = (InputMappingBlock) evt.getNewValue(); + if (mapping != null) { + if (mapping.getRightNameSpace().equals("Global")) { + globalInput = true; + } else { + inputNodes.add(mapping.getRightNameSpace()); + } + addInputMapping(mapping); + } else { + InputMappingBlock oldMapping = (InputMappingBlock) evt.getOldValue(); + if (oldMapping.getRightNameSpace().equals("Global")) { + globalInput = false; + } else { + inputNodes.remove(oldMapping.getRightNameSpace()); + } + removeInputMapping(oldMapping); + } + fire("order", null, null); + + } else if (evt.getPropertyName().equals(OUTPUT)) { + OutputMappingBlock mapping = (OutputMappingBlock) evt.getNewValue(); + if (mapping != null) { + if (mapping.getLeftNameSpace().equals("Global")) { + globalOutput = true; + } + addOutputMapping(mapping); + } else { + OutputMappingBlock oldMapping = (OutputMappingBlock) evt.getOldValue(); + + if (oldMapping.getLeftNameSpace().equals("Global")) { + globalOutput = false; + } + removeOutputMapping(oldMapping); + } + fire("order", null, null); + } + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/ShaderNodesBlock.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/ShaderNodesBlock.java new file mode 100644 index 000000000..66372a90d --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/ShaderNodesBlock.java @@ -0,0 +1,59 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.fileStructure; + +import com.jme3.util.blockparser.Statement; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.Collections; +import java.util.List; +import org.openide.util.WeakListeners; + +/** + * + * @author Nehon + */ +public class ShaderNodesBlock extends UberStatement implements PropertyChangeListener { + + protected ShaderNodesBlock(int lineNumber, String line) { + super(lineNumber, line); + } + + public ShaderNodesBlock(Statement sta) { + this(sta.getLineNumber(), sta.getLine()); + for (Statement statement : sta.getContents()) { + ShaderNodeBlock b = new ShaderNodeBlock(statement); + b.addPropertyChangeListener(WeakListeners.propertyChange(this, b)); + addStatement(b); + } + } + + public List getShaderNodes() { + return getBlocks(ShaderNodeBlock.class); + } + + public void addShaderNode(ShaderNodeBlock shaderNodeBlock) { + addStatement(shaderNodeBlock); + shaderNodeBlock.addPropertyChangeListener(WeakListeners.propertyChange(this, shaderNodeBlock)); + } + + public boolean removeShaderNode(ShaderNodeBlock shaderNodeBlock) { + return contents.remove(shaderNodeBlock); + } + + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("order")) { + sort(); + } + } + + public void sort() { + List list = getShaderNodes(); + Collections.sort(list); + contents.clear(); + contents.addAll(list); + fire("reorder", null, null); + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/TechniqueBlock.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/TechniqueBlock.java new file mode 100644 index 000000000..27a52c0ce --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/TechniqueBlock.java @@ -0,0 +1,239 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.fileStructure; + +import com.jme3.gde.materialdefinition.fileStructure.leaves.FragmentShaderFileBlock; +import com.jme3.gde.materialdefinition.fileStructure.leaves.InputMappingBlock; +import com.jme3.gde.materialdefinition.fileStructure.leaves.LightModeBlock; +import com.jme3.gde.materialdefinition.fileStructure.leaves.MatParamBlock; +import com.jme3.gde.materialdefinition.fileStructure.leaves.ShaderFileBlock; +import com.jme3.gde.materialdefinition.fileStructure.leaves.UnsupportedStatement; +import com.jme3.gde.materialdefinition.fileStructure.leaves.VertexShaderFileBlock; +import com.jme3.gde.materialdefinition.fileStructure.leaves.WorldParamBlock; +import com.jme3.util.blockparser.Statement; +import java.beans.PropertyChangeListener; +import java.util.ArrayList; +import java.util.List; +import org.openide.util.WeakListeners; + +/** + * + * @author Nehon + */ +public class TechniqueBlock extends UberStatement { + + public static final String ADD_SHADER_NODE = "addShaderNode"; + public static final String REMOVE_SHADER_NODE = "removeShaderNode"; + public static final String ADD_WORLD_PARAM = "addWorldParam"; + public static final String REMOVE_WORLD_PARAM = "removeWorldParam"; + protected String name; + + protected TechniqueBlock(int lineNumber, String line) { + super(lineNumber, line); + } + + public TechniqueBlock(Statement sta) { + this(sta.getLineNumber(), sta.getLine()); + for (Statement statement : sta.getContents()) { + if (statement.getLine().trim().startsWith("WorldParameters")) { + addStatement(new WorldParametersBlock(statement)); + } else if (statement.getLine().trim().startsWith("LightMode")) { + addStatement(new LightModeBlock(statement)); + } else if (statement.getLine().trim().startsWith("VertexShader ")) { + addStatement(new VertexShaderFileBlock(statement)); + } else if (statement.getLine().trim().startsWith("FragmentShader ")) { + addStatement(new FragmentShaderFileBlock(statement)); + } else if (statement.getLine().trim().startsWith("VertexShaderNodes")) { + addStatement(new VertexShaderNodesBlock(statement)); + } else if (statement.getLine().trim().startsWith("FragmentShaderNodes")) { + addStatement(new FragmentShaderNodesBlock(statement)); + } else { + addStatement(new UnsupportedStatement(statement)); + } + } + String[] s = line.split("\\s"); + if (s.length == 1) { + name = "Default"; + } else { + name = s[1]; + } + } + + public String getName() { + return name; + } + + public void setName(String name) { + String oldName = this.name; + this.name = name; + line = "Technique " + (name.equals("Default") ? "" : name); + fire("name", oldName, name); + } + + public String getLightMode() { + LightModeBlock l = getBlock(LightModeBlock.class); + if (l == null) { + return null; + } + return l.getLightMode(); + } + + public void setLightMode(String lightMode) { + String oldLightMode = null; + LightModeBlock l = getBlock(LightModeBlock.class); + if (l == null) { + l = new LightModeBlock(lightMode); + addStatement(0, l); + } else { + oldLightMode = l.getLightMode(); + l.setLightMode(lightMode); + } + fire("lightMode", oldLightMode, lightMode); + } + + protected WorldParametersBlock getWorldParameters() { + return getBlock(WorldParametersBlock.class); + } + + public List getWorldParams() { + return getWorldParameters().getWorldParams(); + } + + public void addWorldParam(WorldParamBlock block) { + WorldParametersBlock wpBlock = getBlock(WorldParametersBlock.class); + if (wpBlock == null) { + wpBlock = new WorldParametersBlock(0, "WorldParameters"); + addStatement(0, wpBlock); + } + wpBlock.addWorldParam(block); + fire(ADD_WORLD_PARAM, null, block); + } + + public void addVertexShaderNode(ShaderNodeBlock block) { + VertexShaderNodesBlock vblock = getBlock(VertexShaderNodesBlock.class); + + if (vblock == null) { + vblock = new VertexShaderNodesBlock(0, "VertexShaderNodes "); + addStatement(0, vblock); + } + vblock.addShaderNode(block); + fire(ADD_SHADER_NODE, null, block); + } + + public void addFragmentShaderNode(ShaderNodeBlock block) { + FragmentShaderNodesBlock fblock = getBlock(FragmentShaderNodesBlock.class); + + if (fblock == null) { + fblock = new FragmentShaderNodesBlock(0, "FragmentShaderNodes "); + addStatement(0, fblock); + } + fblock.addShaderNode(block); + fire(ADD_SHADER_NODE, null, block); + } + + public void removeShaderNode(ShaderNodeBlock block) { + VertexShaderNodesBlock vblock = getBlock(VertexShaderNodesBlock.class); + FragmentShaderNodesBlock fblock = getBlock(FragmentShaderNodesBlock.class); + boolean removed = false; + String eventToFire = null; + if (vblock != null) { + removed = vblock.removeShaderNode(block); + eventToFire = REMOVE_SHADER_NODE; + } + if (fblock != null) { + if (!removed) { + removed = fblock.removeShaderNode(block); + eventToFire = REMOVE_SHADER_NODE; + } + } + + if (removed) { + cleanMappings(vblock, block); + cleanMappings(fblock, block); + } + + if (eventToFire != null) { + fire(eventToFire, block, null); + } + } + + public void removeWorldParam(WorldParamBlock worldParam) { + WorldParametersBlock wpBlock = getWorldParameters(); + if (wpBlock == null) { + return; + } + wpBlock.removeWorldParam(worldParam); + + VertexShaderNodesBlock vblock = getBlock(VertexShaderNodesBlock.class); + FragmentShaderNodesBlock fblock = getBlock(FragmentShaderNodesBlock.class); + cleanMappings(vblock, "WorldParam", worldParam.getName()); + cleanMappings(fblock, "WorldParam", worldParam.getName()); + + fire(REMOVE_WORLD_PARAM, null, worldParam); + } + + public List getShaderNodes() { + List list = new ArrayList(); + list.addAll(getBlock(VertexShaderNodesBlock.class).getShaderNodes()); + list.addAll(getBlock(FragmentShaderNodesBlock.class).getShaderNodes()); + return list; + } + + public ShaderFileBlock getVertexShader() { + return getBlock(VertexShaderFileBlock.class); + } + + public ShaderFileBlock getFragmentShader() { + return getBlock(FragmentShaderFileBlock.class); + } + + @Override + public void addPropertyChangeListener(PropertyChangeListener pcl) { + super.addPropertyChangeListener(pcl); + VertexShaderNodesBlock vblock = getBlock(VertexShaderNodesBlock.class); + if (vblock != null) { + vblock.addPropertyChangeListener(WeakListeners.propertyChange(pcl, vblock)); + } + FragmentShaderNodesBlock fblock = getBlock(FragmentShaderNodesBlock.class); + if (fblock != null) { + fblock.addPropertyChangeListener(WeakListeners.propertyChange(pcl, fblock)); + } + } + + private void cleanMappings(ShaderNodesBlock vblock, ShaderNodeBlock block) { + if (vblock != null) { + for (ShaderNodeBlock shaderNodeBlock : vblock.getShaderNodes()) { + List lInput = shaderNodeBlock.getInputs(); + if (lInput != null) { + for (InputMappingBlock inputMappingBlock : lInput) { + if (inputMappingBlock.getRightNameSpace().equals(block.getName())) { + shaderNodeBlock.removeInputMapping(inputMappingBlock); + } + } + } + } + } + } + + protected void cleanMappings(ShaderNodesBlock vblock, String nameSpace, String name) { + if (vblock != null) { + for (ShaderNodeBlock shaderNodeBlock : vblock.getShaderNodes()) { + List lInput = shaderNodeBlock.getInputs(); + if (lInput != null) { + for (InputMappingBlock inputMappingBlock : lInput) { + if (inputMappingBlock.getRightNameSpace().equals(nameSpace) && inputMappingBlock.getRightVar().equals(name)) { + shaderNodeBlock.removeInputMapping(inputMappingBlock); + } + } + } + } + } + } + + public void cleanupMappings(String nameSpace, String name) { + cleanMappings(getBlock(VertexShaderNodesBlock.class), nameSpace, name); + cleanMappings(getBlock(FragmentShaderNodesBlock.class), nameSpace, name); + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/UberStatement.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/UberStatement.java new file mode 100644 index 000000000..a86231da1 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/UberStatement.java @@ -0,0 +1,61 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.fileStructure; + +import com.jme3.util.blockparser.Statement; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + +/** + * + * @author Nehon + */ +public class UberStatement extends Statement { + + private List listeners = Collections.synchronizedList(new LinkedList()); + + public void addPropertyChangeListener(PropertyChangeListener pcl) { + listeners.add(pcl); + } + + public void removePropertyChangeListener(PropertyChangeListener pcl) { + listeners.remove(pcl); + } + + protected void fire(String propertyName, Object old, Object nue) { + //Passing 0 below on purpose, so you only synchronize for one atomic call: + PropertyChangeListener[] pcls = (PropertyChangeListener[]) listeners.toArray(new PropertyChangeListener[0]); + for (int i = 0; i < pcls.length; i++) { + pcls[i].propertyChange(new PropertyChangeEvent(this, propertyName, old, nue)); + } + } + + public UberStatement(int lineNumber, String line) { + super(lineNumber, line); + } + + protected T getBlock(Class blockType) { + for (Statement statement : contents) { + if (statement.getClass().isAssignableFrom(blockType)) { + return (T) statement; + } + } + return null; + } + + protected List getBlocks(Class blockType) { + List blocks = new ArrayList(); + for (Statement statement : contents) { + if (statement.getClass().isAssignableFrom(blockType)) { + blocks.add((T) statement); + } + } + return blocks; + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/VertexShaderNodesBlock.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/VertexShaderNodesBlock.java new file mode 100644 index 000000000..3a725ba8b --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/VertexShaderNodesBlock.java @@ -0,0 +1,23 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.fileStructure; + +import com.jme3.util.blockparser.Statement; + +/** + * + * @author Nehon + */ +public class VertexShaderNodesBlock extends ShaderNodesBlock { + + public VertexShaderNodesBlock(int lineNumber, String line) { + super(lineNumber, line); + } + + public VertexShaderNodesBlock(Statement sta) { + super(sta); + } +} + \ No newline at end of file diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/WorldParametersBlock.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/WorldParametersBlock.java new file mode 100644 index 000000000..2b0860971 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/WorldParametersBlock.java @@ -0,0 +1,39 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.fileStructure; + +import com.jme3.gde.materialdefinition.fileStructure.leaves.WorldParamBlock; +import com.jme3.util.blockparser.Statement; +import java.util.List; + +/** + * + * @author Nehon + */ +public class WorldParametersBlock extends UberStatement { + + protected WorldParametersBlock(int lineNumber, String line) { + super(lineNumber, line); + } + + public WorldParametersBlock(Statement sta) { + this(sta.getLineNumber(), sta.getLine()); + for (Statement statement : sta.getContents()) { + addStatement(new WorldParamBlock(statement)); + } + } + + public List getWorldParams() { + return getBlocks(WorldParamBlock.class); + } + + public void addWorldParam(WorldParamBlock block) { + contents.add(block); + } + + public void removeWorldParam(WorldParamBlock block) { + contents.remove(block); + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/leaves/ConditionBlock.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/leaves/ConditionBlock.java new file mode 100644 index 000000000..60a040deb --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/leaves/ConditionBlock.java @@ -0,0 +1,57 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.fileStructure.leaves; + +import com.jme3.util.blockparser.Statement; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * + * @author Nehon + */ +public class ConditionBlock extends LeafStatement { + + protected String condition; + + protected ConditionBlock(int lineNumber, String line) { + super(lineNumber, line); + } + + public ConditionBlock(Statement sta) { + this(sta.getLineNumber(), sta.getLine()); + parse(sta); + updateLine(); + } + + public ConditionBlock(String condition) { + super(0, ""); + this.condition = condition; + updateLine(); + } + + private void updateLine() { + this.line = "Condition : " + condition; + } + + public String getCondition() { + return condition; + } + + public void setCondition(String condition) { + this.condition = condition; + updateLine(); + } + + private void parse(Statement sta) { + try { + String[] split = sta.getLine().split(":"); + condition = split[1].trim(); + + } catch (ArrayIndexOutOfBoundsException e) { + Logger.getLogger(ConditionBlock.class.getName()).log(Level.WARNING, "Parsing error line " + sta.getLineNumber() + " : " + sta.getLine()); + } + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/leaves/DefinitionBlock.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/leaves/DefinitionBlock.java new file mode 100644 index 000000000..626808a33 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/leaves/DefinitionBlock.java @@ -0,0 +1,72 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.fileStructure.leaves; + +import com.jme3.util.blockparser.Statement; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * + * @author Nehon + */ +public class DefinitionBlock extends LeafStatement { + + protected String name; + protected String path; + + protected DefinitionBlock(int lineNumber, String line) { + super(lineNumber, line); + } + + public DefinitionBlock(Statement sta) { + this(sta.getLineNumber(), sta.getLine()); + parse(sta); + updateLine(); + } + + public DefinitionBlock(String name, String path) { + super(0, ""); + this.name = name; + this.path = path; + updateLine(); + } + + private void updateLine() { + this.line = "Definition : " + name + (path == null ? "" : " : " + path); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + updateLine(); + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + updateLine(); + } + + private void parse(Statement sta) { + try { + String[] split = sta.getLine().split(":"); + if (split.length > 2) { + path = split[2].trim(); + } + name = split[1].trim(); + + + } catch (ArrayIndexOutOfBoundsException e) { + Logger.getLogger(DefinitionBlock.class.getName()).log(Level.WARNING, "Parsing error line " + sta.getLineNumber() + " : " + sta.getLine()); + } + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/leaves/FragmentShaderFileBlock.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/leaves/FragmentShaderFileBlock.java new file mode 100644 index 000000000..418b0fb81 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/leaves/FragmentShaderFileBlock.java @@ -0,0 +1,32 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.fileStructure.leaves; + +import com.jme3.util.blockparser.Statement; + +/** + * + * @author Nehon + */ +public class FragmentShaderFileBlock extends ShaderFileBlock { + + public FragmentShaderFileBlock(int lineNumber, String line) { + super(lineNumber, line); + } + + public FragmentShaderFileBlock(Statement sta) { + super(sta); + } + + public FragmentShaderFileBlock(String language, String path, int lineNumber, String line) { + super(language, path, lineNumber, line); + } + + @Override + protected void updateLine() { + super.updateLine(); + line = "Fragment" + line; + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/leaves/InputmappingBlock.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/leaves/InputmappingBlock.java new file mode 100644 index 000000000..ce46e86ee --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/leaves/InputmappingBlock.java @@ -0,0 +1,69 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.fileStructure.leaves; + +import com.jme3.util.blockparser.Statement; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * + * @author Nehon + */ +public class InputMappingBlock extends MappingBlock { + + protected InputMappingBlock(int lineNumber, String line) { + super(lineNumber, line); + } + + public InputMappingBlock(Statement sta, String name) { + this(sta.getLineNumber(), sta.getLine()); + parse(sta); + leftNameSpace = name; + updateLine(); + } + + public InputMappingBlock(String leftVar, String rightVar, String leftVarSwizzle, String rightVarSwizzle, String leftNameSpace,String rightNameSpace, String condition) { + super(0, ""); + this.leftVar = leftVar; + this.rightVar = rightVar; + this.leftVarSwizzle = leftVarSwizzle; + this.leftNameSpace = leftNameSpace; + this.rightVarSwizzle = rightVarSwizzle; + this.rightNameSpace = rightNameSpace; + this.condition = condition; + updateLine(); + } + + @Override + protected final void updateLine() { + this.line = leftVar + (leftVarSwizzle == null ? "" : "." + leftVarSwizzle) + " = " + rightNameSpace + "." + rightVar + (rightVarSwizzle == null ? "" : "." + rightVarSwizzle) + (condition != null ? " : " + condition : ""); + } + + private void parse(Statement sta) { + try { + String[] split = sta.getLine().split(":"); + if (split.length > 1) { + condition = split[1].trim(); + } + String mapping = split[0].trim(); + String[] s = mapping.split("="); + String[] left = s[0].split("\\."); + leftVar = left[0].trim(); + if (left.length > 1) { + leftVarSwizzle = left[1].trim(); + } + String[] right = s[1].split("\\."); + rightNameSpace = right[0].trim(); + rightVar = right[1].trim(); + if (right.length > 2) { + rightVarSwizzle = right[2].trim(); + } + + } catch (ArrayIndexOutOfBoundsException e) { + Logger.getLogger(InputMappingBlock.class.getName()).log(Level.WARNING, "Parsing error line " + sta.getLineNumber() + " : " + sta.getLine()); + } + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/leaves/LeafStatement.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/leaves/LeafStatement.java new file mode 100644 index 000000000..3fb98fb2b --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/leaves/LeafStatement.java @@ -0,0 +1,42 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.fileStructure.leaves; + +import com.jme3.util.blockparser.Statement; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + +/** + * + * @author Nehon + */ +public class LeafStatement extends Statement { + + private List listeners = Collections.synchronizedList(new LinkedList()); + + public void addPropertyChangeListener(PropertyChangeListener pcl) { + listeners.add(pcl); + } + + public void removePropertyChangeListener(PropertyChangeListener pcl) { + listeners.remove(pcl); + } + + protected void fire(String propertyName, Object old, Object nue) { + //Passing 0 below on purpose, so you only synchronize for one atomic call: + PropertyChangeListener[] pcls = (PropertyChangeListener[]) listeners.toArray(new PropertyChangeListener[0]); + for (int i = 0; i < pcls.length; i++) { + pcls[i].propertyChange(new PropertyChangeEvent(this, propertyName, old, nue)); + } + } + + public LeafStatement(int lineNumber, String line) { + super(lineNumber, line); + contents = null; + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/leaves/LightModeBlock.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/leaves/LightModeBlock.java new file mode 100644 index 000000000..6fd356aa0 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/leaves/LightModeBlock.java @@ -0,0 +1,62 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.fileStructure.leaves; + +import com.jme3.material.TechniqueDef; +import com.jme3.util.blockparser.Statement; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * + * @author Nehon + */ +public class LightModeBlock extends LeafStatement { + + protected String lightMode; + + protected LightModeBlock(int lineNumber, String line) { + super(lineNumber, line); + } + + public LightModeBlock(Statement sta) { + this(sta.getLineNumber(), sta.getLine()); + parse(sta); + updateLine(); + } + + public LightModeBlock(String lightMode) { + super(0, ""); + this.lightMode = lightMode; + updateLine(); + } + + private void updateLine() { + this.line = "LightMode " + lightMode; + } + + public String getLightMode() { + return lightMode; + } + + public void setLightMode(String lightMode) { + this.lightMode = lightMode; + updateLine(); + } + + private void parse(Statement sta) { + try { + String[] split = sta.getLine().split("\\s"); + lightMode = split[1].trim(); + + TechniqueDef.LightMode.valueOf(lightMode); + + } catch (ArrayIndexOutOfBoundsException e) { + Logger.getLogger(LightModeBlock.class.getName()).log(Level.WARNING, "Parsing error line " + sta.getLineNumber() + " : " + sta.getLine()); + } catch (IllegalArgumentException ex){ + Logger.getLogger(LightModeBlock.class.getName()).log(Level.WARNING, "Invalid light mode : " + sta.getLineNumber() + " : " + sta.getLine()); + } + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/leaves/MappingBlock.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/leaves/MappingBlock.java new file mode 100644 index 000000000..134559a6c --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/leaves/MappingBlock.java @@ -0,0 +1,112 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.fileStructure.leaves; + +/** + * + * @author Nehon + */ +public abstract class MappingBlock extends LeafStatement { + + protected String leftVar; + protected String rightVar; + protected String leftVarSwizzle; + protected String rightVarSwizzle; + protected String leftNameSpace; + protected String rightNameSpace; + protected String condition; + + public MappingBlock(int lineNumber, String line) { + super(lineNumber, line); + } + + protected abstract void updateLine(); + + public String getCondition() { + return condition; + } + + public void setCondition(String condition) { + String old = this.condition; + if (condition.trim().length() == 0 || condition.equals("")) { + condition = null; + } + this.condition = condition; + updateLine(); + fire("condition", old, condition); + } + + public String getLeftVar() { + return leftVar; + } + + public void setLeftVar(String leftVar) { + this.leftVar = leftVar; + updateLine(); + } + + public String getRightVar() { + return rightVar; + } + + public void setRightVar(String rightVar) { + this.rightVar = rightVar; + updateLine(); + } + + public String getRightNameSpace() { + return rightNameSpace; + } + + public void setRightNameSpace(String rightnameSpace) { + String old = this.rightNameSpace; + this.rightNameSpace = rightnameSpace; + updateLine(); + fire("rightNameSpace", old, rightnameSpace); + } + + public String getLeftVarSwizzle() { + return leftVarSwizzle; + } + + public void setLeftVarSwizzle(String leftVarSwizzle) { + String old = this.leftVarSwizzle; + if (leftVarSwizzle.trim().length() == 0) { + leftVarSwizzle = null; + } + this.leftVarSwizzle = leftVarSwizzle; + updateLine(); + fire("leftVarSwizzle", old, leftVarSwizzle); + } + + public String getRightVarSwizzle() { + return rightVarSwizzle; + } + + public void setRightVarSwizzle(String rightVarSwizzle) { + String old = this.rightVarSwizzle; + this.rightVarSwizzle = rightVarSwizzle; + if (rightVarSwizzle.trim().length() == 0) { + rightVarSwizzle = null; + } + this.rightVarSwizzle = rightVarSwizzle; + updateLine(); + fire("rightVarSwizzle", old, rightVarSwizzle); + } + + public String getLeftNameSpace() { + return leftNameSpace; + } + + public void setLeftNameSpace(String leftNameSpace) { + String old = this.leftNameSpace; + this.leftNameSpace = leftNameSpace; + updateLine(); + fire("leftNameSpace", old, leftNameSpace); + } + + + +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/leaves/MatParamBlock.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/leaves/MatParamBlock.java new file mode 100644 index 000000000..7b1d03a6f --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/leaves/MatParamBlock.java @@ -0,0 +1,128 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.fileStructure.leaves; + +import com.jme3.util.blockparser.Statement; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * + * @author Nehon + */ +public class MatParamBlock extends LeafStatement { + + protected String type; + protected String name; + protected String fixedFuncBinding; + protected String defaultValue; + + protected MatParamBlock(int lineNumber, String line) { + super(lineNumber, line); + } + + public MatParamBlock(Statement sta) { + this(sta.getLineNumber(), sta.getLine()); + parse(sta); + updateLine(); + } + + public MatParamBlock(String type, String name, String fixedPipelineBinding, String defaultValue) { + super(0, ""); + this.type = type; + this.name = name; + this.fixedFuncBinding = fixedPipelineBinding; + this.defaultValue = defaultValue; + updateLine(); + } + + private void updateLine() { + this.line = type + " " + name + (fixedFuncBinding != null ? " (" + fixedFuncBinding + ") " : "") + (defaultValue != null ? " : " + defaultValue : ""); + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + updateLine(); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + updateLine(); + } + + public String getFixedPipelineBinding() { + return fixedFuncBinding; + } + + public void setFixedPipelineBinding(String fixedPipelineBinding) { + this.fixedFuncBinding = fixedPipelineBinding; + updateLine(); + } + + public String getDefaultValue() { + return defaultValue; + } + + public void setDefaultValue(String defaultValue) { + this.defaultValue = defaultValue; + updateLine(); + } + + @Override + public boolean equals(Object obj) { + if(!(obj instanceof MatParamBlock)){ + return false; + } + return ((MatParamBlock)obj).getName().equals(name); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 89 * hash + (this.name != null ? this.name.hashCode() : 0); + return hash; + } + + private void parse(Statement sta) { + try { + String[] split = sta.getLine().split(":"); + String statement = split[0].trim(); + + // Parse default val + if (split.length > 1) { + + defaultValue = split[1].trim(); + } + + // Parse ffbinding + int startParen = statement.indexOf("("); + if (startParen != -1) { + // get content inside parentheses + int endParen = statement.indexOf(")", startParen); + fixedFuncBinding = statement.substring(startParen + 1, endParen).trim(); + statement = statement.substring(0, startParen); + } + + // Parse type + name + split = statement.split("\\p{javaWhitespace}+"); + + type = split[0]; + name = split[1]; + + + } catch (Exception e) { + e.printStackTrace(); + Logger.getLogger(MatParamBlock.class.getName()).log(Level.WARNING, "Parsing error line " + sta.getLineNumber() + " : " + sta.getLine()); + } + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/leaves/OutputMappingBlock.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/leaves/OutputMappingBlock.java new file mode 100644 index 000000000..0717b2848 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/leaves/OutputMappingBlock.java @@ -0,0 +1,73 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.fileStructure.leaves; + +import com.jme3.util.blockparser.Statement; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * + * @author Nehon + */ +public class OutputMappingBlock extends MappingBlock { + + protected OutputMappingBlock(int lineNumber, String line) { + super(lineNumber, line); + } + + public OutputMappingBlock(Statement sta, String name) { + this(sta.getLineNumber(), sta.getLine()); + parse(sta); + rightNameSpace = name; + updateLine(); + } + + public OutputMappingBlock(String leftVar, String rightVar, String leftVarSwizzle, String rightVarSwizzle, String leftNameSpace, String rightNameSpace, String condition) { + super(0, ""); + this.leftVar = leftVar; + this.rightVar = rightVar; + this.leftVarSwizzle = leftVarSwizzle; + this.rightVarSwizzle = rightVarSwizzle; + this.leftNameSpace = leftNameSpace; + this.rightNameSpace = rightNameSpace; + this.condition = condition; + updateLine(); + } + + @Override + protected final void updateLine() { + this.line = leftNameSpace + "." + leftVar + (leftVarSwizzle == null ? "" : "." + leftVarSwizzle) + " = " + rightVar + (rightVarSwizzle == null ? "" : "." + rightVarSwizzle) + (condition != null ? " : " + condition : ""); + } + + private void parse(Statement sta) { + try { + String[] split = sta.getLine().split(":"); + if (split.length > 1) { + condition = split[1].trim(); + } + String mapping = split[0].trim(); + String[] s = mapping.split("="); + + String[] left = s[0].split("\\."); + leftNameSpace = left[0].trim(); + leftVar = left[1].trim(); + if (left.length > 2) { + leftVarSwizzle = left[2].trim(); + } + + String[] right = s[1].split("\\."); + + rightVar = right[0].trim(); + if (right.length > 1) { + rightVarSwizzle = right[1].trim(); + } + + + } catch (ArrayIndexOutOfBoundsException e) { + Logger.getLogger(OutputMappingBlock.class.getName()).log(Level.WARNING, "Parsing error line {0} : {1}", new Object[]{sta.getLineNumber(), sta.getLine()}); + } + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/leaves/ShaderFileBlock.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/leaves/ShaderFileBlock.java new file mode 100644 index 000000000..47ef2cf56 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/leaves/ShaderFileBlock.java @@ -0,0 +1,53 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.fileStructure.leaves; + +import com.jme3.util.blockparser.Statement; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * + * @author Nehon + */ +public class ShaderFileBlock extends LeafStatement { + + protected String language; + protected String path; + + protected ShaderFileBlock(int lineNumber, String line) { + super(lineNumber, line); + } + + public ShaderFileBlock(Statement sta) { + this(sta.getLineNumber(), sta.getLine()); + parse(sta); + updateLine(); + } + + public ShaderFileBlock(String language, String path, int lineNumber, String line) { + super(lineNumber, line); + this.language = language; + this.path = path; + updateLine(); + } + + protected void updateLine() { + this.line = "Shader " + language + ": " + path; + } + + private void parse(Statement sta) { + try { + String[] split = sta.getLine().split("\\s"); + language = split[1].trim(); + path = split[2].trim(); + + } catch (ArrayIndexOutOfBoundsException e) { + Logger.getLogger(ShaderFileBlock.class.getName()).log(Level.WARNING, "Parsing error line " + sta.getLineNumber() + " : " + sta.getLine()); + } catch (IllegalArgumentException ex) { + Logger.getLogger(ShaderFileBlock.class.getName()).log(Level.WARNING, "Invalid light mode : " + sta.getLineNumber() + " : " + sta.getLine()); + } + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/leaves/UnsupportedStatement.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/leaves/UnsupportedStatement.java new file mode 100644 index 000000000..8203d759e --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/leaves/UnsupportedStatement.java @@ -0,0 +1,22 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.fileStructure.leaves; + +import com.jme3.util.blockparser.Statement; + +/** + * + * @author Nehon + */ +public class UnsupportedStatement extends Statement { + + public UnsupportedStatement(int lineNumber, String line) { + super(lineNumber, line); + } + + public UnsupportedStatement(Statement sta) { + super(sta.getLineNumber(), sta.getLine()); + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/leaves/VertexShaderFileBlock.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/leaves/VertexShaderFileBlock.java new file mode 100644 index 000000000..fe30e15e3 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/leaves/VertexShaderFileBlock.java @@ -0,0 +1,32 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.fileStructure.leaves; + +import com.jme3.util.blockparser.Statement; + +/** + * + * @author Nehon + */ +public class VertexShaderFileBlock extends ShaderFileBlock { + + public VertexShaderFileBlock(int lineNumber, String line) { + super(lineNumber, line); + } + + public VertexShaderFileBlock(Statement sta) { + super(sta); + } + + public VertexShaderFileBlock(String language, String path, int lineNumber, String line) { + super(language, path, lineNumber, line); + } + + @Override + protected void updateLine() { + super.updateLine(); + line = "Vertex" + line; + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/leaves/WorldParamBlock.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/leaves/WorldParamBlock.java new file mode 100644 index 000000000..162ef5377 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/leaves/WorldParamBlock.java @@ -0,0 +1,64 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.fileStructure.leaves; + +import com.jme3.util.blockparser.Statement; + +/** + * + * @author Nehon + */ +public class WorldParamBlock extends LeafStatement { + + protected String name; + + protected WorldParamBlock(int lineNumber, String line) { + super(lineNumber, line); + } + + public WorldParamBlock(Statement sta) { + this(sta.getLineNumber(), sta.getLine()); + parse(sta); + updateLine(); + } + + public WorldParamBlock(String name) { + super(0, ""); + this.name = name; + updateLine(); + } + + private void updateLine() { + this.line = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + updateLine(); + } + + private void parse(Statement sta) { + name = sta.getLine().trim(); + } + + @Override + public boolean equals(Object obj) { + if(!(obj instanceof WorldParamBlock)){ + return false; + } + return ((WorldParamBlock)obj).getName().equals(name); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 89 * hash + (this.name != null ? this.name.hashCode() : 0); + return hash; + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/Icons.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/Icons.java new file mode 100644 index 000000000..7e746346e --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/Icons.java @@ -0,0 +1,30 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.icons; + +import javax.swing.ImageIcon; + +/** + * + * @author Nehon + */ +public class Icons { + + public final static ImageIcon node = new ImageIcon(Icons.class.getResource("node.png")); + public final static ImageIcon output = new ImageIcon(Icons.class.getResource("output.png")); + public final static ImageIcon world = new ImageIcon(Icons.class.getResource("earth.png")); + public final static ImageIcon attrib = new ImageIcon(Icons.class.getResource("attrib.png")); + public final static ImageIcon mat = new ImageIcon(Icons.class.getResource("mat.png")); + public final static ImageIcon vert = new ImageIcon(Icons.class.getResource("vert.png")); + public final static ImageIcon frag = new ImageIcon(Icons.class.getResource("fragment.png")); + public final static ImageIcon imgGrey = new ImageIcon(Icons.class.getResource("dot.png")); + public final static ImageIcon imgGreen = new ImageIcon(Icons.class.getResource("dotGreen.png")); + public final static ImageIcon imgOrange = new ImageIcon(Icons.class.getResource("dotOrange.png")); + public final static ImageIcon imgRed = new ImageIcon(Icons.class.getResource("dotRed.png")); + public final static ImageIcon matDef = new ImageIcon(Icons.class.getResource("matdef.png")); + public final static ImageIcon tech = new ImageIcon(Icons.class.getResource("tech.png")); + public final static ImageIcon in = new ImageIcon(Icons.class.getResource("in.png")); + public final static ImageIcon out = new ImageIcon(Icons.class.getResource("out.png")); +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/Quad.png b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/Quad.png new file mode 100644 index 000000000..46b379332 Binary files /dev/null and b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/Quad.png differ diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/Sphere.png b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/Sphere.png new file mode 100644 index 000000000..c65989777 Binary files /dev/null and b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/Sphere.png differ diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/attrib.png b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/attrib.png new file mode 100644 index 000000000..fb1401bfb Binary files /dev/null and b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/attrib.png differ diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/busOutput.png b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/busOutput.png new file mode 100644 index 000000000..9ba936acc Binary files /dev/null and b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/busOutput.png differ diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/cube.png b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/cube.png new file mode 100644 index 000000000..6974118bb Binary files /dev/null and b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/cube.png differ diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/cube.psd b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/cube.psd new file mode 100644 index 000000000..c688bc524 Binary files /dev/null and b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/cube.psd differ diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/dot.png b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/dot.png new file mode 100644 index 000000000..59605f195 Binary files /dev/null and b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/dot.png differ diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/dotGreen.png b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/dotGreen.png new file mode 100644 index 000000000..196cfa58b Binary files /dev/null and b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/dotGreen.png differ diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/dotOrange.png b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/dotOrange.png new file mode 100644 index 000000000..ea4c06eba Binary files /dev/null and b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/dotOrange.png differ diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/dotRed.png b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/dotRed.png new file mode 100644 index 000000000..d20eac024 Binary files /dev/null and b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/dotRed.png differ diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/earth.png b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/earth.png new file mode 100644 index 000000000..94bac07c6 Binary files /dev/null and b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/earth.png differ diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/earth_1.png b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/earth_1.png new file mode 100644 index 000000000..94bac07c6 Binary files /dev/null and b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/earth_1.png differ diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/expend.png b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/expend.png new file mode 100644 index 000000000..dbe2d477e Binary files /dev/null and b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/expend.png differ diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/flip.png b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/flip.png new file mode 100644 index 000000000..4c3d2d546 Binary files /dev/null and b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/flip.png differ diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/fragment.png b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/fragment.png new file mode 100644 index 000000000..3c9d72649 Binary files /dev/null and b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/fragment.png differ diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/in.png b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/in.png new file mode 100644 index 000000000..dd2eb7a13 Binary files /dev/null and b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/in.png differ diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/inputOutput.psd b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/inputOutput.psd new file mode 100644 index 000000000..d2ad69dc7 Binary files /dev/null and b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/inputOutput.psd differ diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/mat.png b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/mat.png new file mode 100644 index 000000000..3c3028a8d Binary files /dev/null and b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/mat.png differ diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/matdef.png b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/matdef.png new file mode 100644 index 000000000..6f31cb85a Binary files /dev/null and b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/matdef.png differ diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/node.png b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/node.png new file mode 100644 index 000000000..66f4ae5bb Binary files /dev/null and b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/node.png differ diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/node.psd b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/node.psd new file mode 100644 index 000000000..f7570bcb7 Binary files /dev/null and b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/node.psd differ diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/ouptut.psd b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/ouptut.psd new file mode 100644 index 000000000..c208c6175 Binary files /dev/null and b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/ouptut.psd differ diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/out.png b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/out.png new file mode 100644 index 000000000..a34e4cb5a Binary files /dev/null and b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/out.png differ diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/output.png b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/output.png new file mode 100644 index 000000000..04af138a8 Binary files /dev/null and b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/output.png differ diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/pirates.wmv b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/pirates.wmv new file mode 100644 index 000000000..5a30b7daf Binary files /dev/null and b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/pirates.wmv differ diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/previewIcons.psd b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/previewIcons.psd new file mode 100644 index 000000000..cb9255e1c Binary files /dev/null and b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/previewIcons.psd differ diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/reload.png b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/reload.png new file mode 100644 index 000000000..795dede32 Binary files /dev/null and b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/reload.png differ diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/repeat.png b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/repeat.png new file mode 100644 index 000000000..e963f747b Binary files /dev/null and b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/repeat.png differ diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/tech.png b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/tech.png new file mode 100644 index 000000000..3d5aa729f Binary files /dev/null and b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/tech.png differ diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/vert.png b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/vert.png new file mode 100644 index 000000000..ac66ef6f6 Binary files /dev/null and b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/icons/vert.png differ diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/navigator/MatDefNavigatorPanel.form b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/navigator/MatDefNavigatorPanel.form new file mode 100644 index 000000000..8ad7761c0 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/navigator/MatDefNavigatorPanel.form @@ -0,0 +1,37 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/navigator/MatDefNavigatorPanel.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/navigator/MatDefNavigatorPanel.java new file mode 100644 index 000000000..035513798 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/navigator/MatDefNavigatorPanel.java @@ -0,0 +1,182 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.navigator; + +import com.jme3.gde.materialdefinition.MatDefDataObject; +import java.util.Collection; +import javax.swing.JComponent; +import javax.swing.JPanel; +import org.netbeans.spi.navigator.NavigatorPanel; +import org.openide.explorer.ExplorerManager; +import org.openide.explorer.ExplorerUtils; +import org.openide.explorer.view.BeanTreeView; +import org.openide.nodes.Node; +import org.openide.util.Lookup; +import org.openide.util.LookupEvent; +import org.openide.util.LookupListener; + +/** + * + * @author Nehon + */ +@NavigatorPanel.Registration(mimeType = "text/jme-materialdefinition", displayName = "Material Def") +public class MatDefNavigatorPanel extends JPanel implements NavigatorPanel, ExplorerManager.Provider { + + /** + * template for finding data in given context. + */ + private static final Lookup.Template MY_DATA = new Lookup.Template(MatDefDataObject.class); + + /** + * current context to work on + */ + private Lookup.Result curContext; + private Lookup lookup; + /** + * listener to context changes + */ + private LookupListener contextL; + private final ExplorerManager mgr = new ExplorerManager(); + + /** + * Creates new form MatDefNavigatorPanel + */ + public MatDefNavigatorPanel() { + initComponents(); + lookup = ExplorerUtils.createLookup(mgr, getActionMap()); + + } + + public String getDisplayHint() { + return "Material definition outline view"; + } + + @Override + public String getDisplayName() { + return "Bla"; + } + + public JComponent getComponent() { + return this; + } + + public void panelActivated(Lookup context) { + // lookup context and listen to result to get notified about context changes + curContext = context.lookup(MY_DATA); + //lookup = context; + curContext.addLookupListener(getContextListener()); + // get actual data and recompute content + Collection data = curContext.allInstances(); + setNewContent(data); + + // ExplorerUtils.activateActions(mgr, true); + + } + + public void panelDeactivated() { + Collection data = curContext.allInstances(); + if (!data.isEmpty()) { + MatDefDataObject obj = (MatDefDataObject) data.iterator().next(); + obj.getLookupContents().remove(this); + } + curContext.removeLookupListener(getContextListener()); + curContext = null; + mgr.setRootContext(Node.EMPTY); + //ExplorerUtils.activateActions(mgr, false); + } + + public Lookup getLookup() { + // go with default activated Node strategy + return lookup; + } + + /** + * *********** non - public part *********** + */ + private void setNewContent(Collection newData) { + if (!newData.isEmpty()) { + MatDefDataObject data = (MatDefDataObject) newData.iterator().next(); + data.getLookupContents().add(this); + if (data.isLoaded()) { + updateData(data); + } else { + mgr.setRootContext(Node.EMPTY); + } + } + } + + /** + * Accessor for listener to context + */ + private LookupListener getContextListener() { + if (contextL == null) { + contextL = new ContextListener(); + } + return contextL; + } + + public ExplorerManager getExplorerManager() { + return mgr; + } + + public void updateData(MatDefDataObject data) { + if (data != null) { + data.getEditableFile().buildOverview(mgr); + } else { + mgr.setRootContext(Node.EMPTY); + } + } + + /** + * Listens to changes of context and triggers proper action + */ + private class ContextListener implements LookupListener { + + public void resultChanged(LookupEvent ev) { + Collection data = ((Lookup.Result) ev.getSource()).allInstances(); + setNewContent(data); + } + } // end of ContextListener + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + jScrollPane1 = new BeanTreeView(); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE) + ); + }// //GEN-END:initComponents + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JScrollPane jScrollPane1; + // End of variables declaration//GEN-END:variables + + /** + * Gets default instance. Do not use directly: reserved for *.settings files + * only, i.e. deserialization routines; otherwise you could get a + * non-deserialized instance. To obtain the singleton instance, use + * {@link #findInstance}. + */ + public static synchronized MatDefNavigatorPanel getDefault() { + if (instance == null) { + instance = new MatDefNavigatorPanel(); + } + return instance; + } + private static MatDefNavigatorPanel instance; +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/navigator/node/AbstractMatDefNode.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/navigator/node/AbstractMatDefNode.java new file mode 100644 index 000000000..05a34852e --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/navigator/node/AbstractMatDefNode.java @@ -0,0 +1,66 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.navigator.node; + +import com.jme3.gde.materialdefinition.fileStructure.MatDefBlock; +import com.jme3.gde.materialdefinition.fileStructure.leaves.MatParamBlock; +import com.jme3.gde.materialdefinition.navigator.node.properties.MatParamProperty; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.List; +import javax.swing.Action; +import org.openide.nodes.AbstractNode; +import org.openide.nodes.Children; +import org.openide.nodes.Sheet; +import org.openide.util.Lookup; + +/** + * + * @author Nehon + */ +public class AbstractMatDefNode extends AbstractNode { + + protected Lookup lookup; + + public AbstractMatDefNode(Children children, Lookup lookup) { + super(children, lookup); + this.lookup = lookup; + MatDefBlock block = lookup.lookup(MatDefBlock.class); + block.addPropertyChangeListener(new PropertyChangeListener() { + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals(MatDefBlock.ADD_MAT_PARAM) || evt.getPropertyName().equals(MatDefBlock.REMOVE_MAT_PARAM)) { + setSheet(createSheet()); + firePropertySetsChange(null, null); + } + } + }); + + } + + + @Override + public Action[] getActions(boolean popup) { + return new Action[]{}; + } + + @Override + protected Sheet createSheet() { + Sheet sheet = super.createSheet(); + MatDefBlock def = lookup.lookup(MatDefBlock.class); + List params = def.getMatParams(); + + Sheet.Set set = new Sheet.Set(); + set.setName("MaterialParameters"); + set.setDisplayName("Material Parameters"); + for (MatParamBlock matParamBlock : params) { + set.put(MatParamProperty.makeProperty(matParamBlock, lookup)); + } + + sheet.put(set); + + return sheet; + + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/navigator/node/MappingNode.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/navigator/node/MappingNode.java new file mode 100644 index 000000000..9778d5aea --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/navigator/node/MappingNode.java @@ -0,0 +1,112 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.navigator.node; + +import com.jme3.gde.materialdefinition.MatDefDataObject; +import com.jme3.gde.materialdefinition.editor.Selectable; +import com.jme3.gde.materialdefinition.fileStructure.leaves.InputMappingBlock; +import com.jme3.gde.materialdefinition.fileStructure.leaves.MappingBlock; +import com.jme3.gde.materialdefinition.icons.Icons; +import com.jme3.gde.materialdefinition.navigator.node.properties.DefaultProperty; +import com.jme3.gde.materialdefinition.utils.MaterialUtils; +import java.awt.Image; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import org.openide.nodes.Children; +import org.openide.nodes.Sheet; +import org.openide.util.Exceptions; +import org.openide.util.Lookup; +import org.openide.util.WeakListeners; + +/** + * + * @author Nehon + */ +public class MappingNode extends AbstractMatDefNode implements Selectable, PropertyChangeListener { + + MappingBlock mapping; + String key; + + public MappingNode(final MappingBlock mapping) { + this(null, mapping); + } + + public MappingNode(Lookup lookup, final MappingBlock mapping) { + super(Children.LEAF, lookup); + this.mapping = mapping; + setName(makeName(mapping)); + key = makeKey(); + } + + private String makeName(MappingBlock mapping) { +// ShaderNodeVariable left = mapping.getLeftVar(); +// ShaderNodeVariable right = mapping.getRightVariable(); +// String rightName = right.getName().replaceAll("g_", "").replaceAll("m_", ""); +// String leftName = left.getName().replaceAll("g_", "").replaceAll("m_", ""); +// String leftSwizzle = mapping.getLeftSwizzling().length() > 0 ? "." + mapping.getLeftSwizzling() : ""; +// String rightSwizzle = mapping.getRightSwizzling().length() > 0 ? "." + mapping.getRightSwizzling() : ""; +// if (isInput()) { +// return leftName + leftSwizzle + " = " + right.getNameSpace() + "." + rightName + rightSwizzle; +// } + return mapping.toString();//right.getNameSpace() + "." + leftName + leftSwizzle + " = " + rightName + rightSwizzle; + } + + private boolean isInput() { + return (mapping instanceof InputMappingBlock); + } + + @Override + public Image getIcon(int type) { + if (isInput()) { + return Icons.in.getImage(); + } + return Icons.out.getImage(); + } + + @Override + protected Sheet createSheet() { + Sheet sheet = super.createSheet(); + Sheet.Set set = new Sheet.Set(); + set.setName(mapping.getLeftVar() + " <- " + mapping.getRightVar()); + set.setDisplayName(mapping.getLeftVar() + " <- " + mapping.getRightVar()); + + + try { + set.put(new DefaultProperty(mapping, String.class, "Condition", "getCondition", "setCondition")); + + set.put(new DefaultProperty(mapping, String.class, "Left name space", "getLeftNameSpace", "setLeftNameSpace", true)); + set.put(new DefaultProperty(mapping, String.class, "Left variable", "getLeftVar", "setLeftVar", true)); + set.put(new DefaultProperty(mapping, String.class, "Left swizzle", "getLeftVarSwizzle", "setLeftVarSwizzle")); + + set.put(new DefaultProperty(mapping, String.class, "Right name space", "getRightNameSpace", "setRightNameSpace", true)); + set.put(new DefaultProperty(mapping, String.class, "Right variable", "getRightVar", "setRightVar", true)); + set.put(new DefaultProperty(mapping, String.class, "Right swizzle", "getRightVarSwizzle", "setRightVarSwizzle")); + + + } catch (NoSuchMethodException ex) { + Exceptions.printStackTrace(ex); + } + + mapping.addPropertyChangeListener(WeakListeners.propertyChange(this, mapping)); + + + sheet.put(set); + + return sheet; + } + + private String makeKey() { + return MaterialUtils.makeKey(mapping, lookup.lookup(MatDefDataObject.class).getEditableFile().getCurrentTechnique().getName()); + } + + public String getKey() { + return key; + } + + public void propertyChange(PropertyChangeEvent evt) { + setName(makeName(mapping)); + key = makeKey(); + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/navigator/node/MatDefNode.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/navigator/node/MatDefNode.java new file mode 100644 index 000000000..6a0bf9168 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/navigator/node/MatDefNode.java @@ -0,0 +1,103 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.navigator.node; + +import com.jme3.gde.materialdefinition.editor.Selectable; +import com.jme3.gde.materialdefinition.fileStructure.MatDefBlock; +import com.jme3.gde.materialdefinition.fileStructure.TechniqueBlock; +import com.jme3.gde.materialdefinition.icons.Icons; +import com.jme3.gde.materialdefinition.navigator.node.properties.DefaultProperty; +import java.awt.Image; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.List; +import javax.swing.Action; +import org.openide.actions.RenameAction; +import org.openide.nodes.ChildFactory; +import org.openide.nodes.Children; +import org.openide.nodes.Node; +import org.openide.nodes.Sheet; +import org.openide.util.Exceptions; +import org.openide.util.Lookup; +import org.openide.util.WeakListeners; +import org.openide.util.actions.SystemAction; + +/** + * + * @author Nehon + */ +public class MatDefNode extends AbstractMatDefNode implements Selectable, PropertyChangeListener { + + + public MatDefNode(final Lookup lookup) { + super(Children.create(new ChildFactory() { + @Override + protected boolean createKeys(List list) { + list.addAll(lookup.lookup(MatDefBlock.class).getTechniques()); + return true; + } + + @Override + protected Node createNodeForKey(TechniqueBlock key) { + return new TechniqueNode(lookup, key); + } + }, true),lookup); + + setName(lookup.lookup(MatDefBlock.class).getName()); + + } + + + + @Override + protected Sheet createSheet() { + Sheet sheet = super.createSheet(); + MatDefBlock def = lookup.lookup(MatDefBlock.class); + + Sheet.Set set = new Sheet.Set(); + set.setName(def.getName() + "MaterialDefinition"); + set.setDisplayName(def.getName() + " Material Definition"); + set.setShortDescription(def.getName() + " Material Definition"); + try { + DefaultProperty prop = new DefaultProperty(def, String.class, "Name", "getName", "setName"); + set.put(prop); + + } catch (NoSuchMethodException ex) { + Exceptions.printStackTrace(ex); + } + + def.addPropertyChangeListener(WeakListeners.propertyChange(this, def)); + +// for (MatParam matParam : def.getMaterialParams()) { +// set.put(MatParamProperty.makeProperty(matParam, lookup)); +// } + sheet.put(set); + + return sheet; + + } + + @Override + public Image getIcon(int type) { + return Icons.matDef.getImage(); + } + + @Override + public Image getOpenedIcon(int type) { + return Icons.matDef.getImage(); + } + + public String getKey() { + return getName(); + } + + public void propertyChange(PropertyChangeEvent evt) { + if(evt.getPropertyName().equals("name")){ + setName((String)evt.getNewValue()); + setDisplayName((String)evt.getNewValue()); + } + + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/navigator/node/ShaderNodeNode.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/navigator/node/ShaderNodeNode.java new file mode 100644 index 000000000..f7133bc8c --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/navigator/node/ShaderNodeNode.java @@ -0,0 +1,177 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.navigator.node; + +import com.jme3.gde.core.assets.ProjectAssetManager; +import com.jme3.gde.materialdefinition.MatDefDataObject; +import com.jme3.gde.materialdefinition.editor.Selectable; +import com.jme3.gde.materialdefinition.fileStructure.ShaderNodeBlock; +import com.jme3.gde.materialdefinition.fileStructure.leaves.MappingBlock; +import com.jme3.gde.materialdefinition.icons.Icons; +import com.jme3.gde.materialdefinition.navigator.node.properties.DefaultProperty; +import com.jme3.gde.materialdefinition.utils.MaterialUtils; +import com.jme3.shader.Shader; +import com.jme3.shader.ShaderNodeDefinition; +import java.awt.Image; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.ArrayList; +import java.util.List; +import org.openide.nodes.Children; +import org.openide.nodes.Node; +import org.openide.nodes.Sheet; +import org.openide.util.Exceptions; +import org.openide.util.Lookup; +import org.openide.util.WeakListeners; + +/** + * + * @author Nehon + */ +public class ShaderNodeNode extends AbstractMatDefNode implements Selectable, PropertyChangeListener { + + ShaderNodeBlock shaderNode; + ShaderNodeDefinition def; + String key = ""; + + + public ShaderNodeNode(final Lookup lookup, final ShaderNodeBlock shaderNode) { +// super(Children.create(new ChildFactory() { +// @Override +// protected boolean createKeys(List list) { +// list.addAll(shaderNode.getInputs()); +// List out = shaderNode.getOutputs(); +// if (out != null) { +// list.addAll(shaderNode.getOutputs()); +// } +// +// return true; +// } +// +// @Override +// protected Node createNodeForKey(MappingBlock key) { +// return new MappingNode(lookup, key); +// } +// }, true), lookup); + super(new MappingNodeChildren(lookup, shaderNode), lookup); + this.shaderNode = shaderNode; + setName(shaderNode.getName()); + key = makeKey(); + ProjectAssetManager manager = lookup.lookup(ProjectAssetManager.class); + def = MaterialUtils.loadShaderNodeDefinition(shaderNode, manager); + + } + + @Override + public Image getIcon(int type) { + return getImageIcon(); + } + + @Override + protected Sheet createSheet() { + + Sheet sheet = super.createSheet(); + Sheet.Set set = new Sheet.Set(); + set.setName(shaderNode.getName() + "ShaderNode"); + set.setDisplayName(shaderNode.getName() + " ShaderNode"); + set.setShortDescription(def.getDocumentation()); + try { + set.put(new DefaultProperty(shaderNode, String.class, "Name", "getName", "setName")); + set.put(new DefaultProperty(shaderNode, String.class, "Condition", "getCondition", "setCondition")); + + } catch (NoSuchMethodException ex) { + Exceptions.printStackTrace(ex); + } + + shaderNode.addPropertyChangeListener(WeakListeners.propertyChange(this, shaderNode)); + + + sheet.put(set); + + return sheet; + + + } + + @Override + public String getShortDescription() { + return def.getDocumentation(); + } + + @Override + public Image getOpenedIcon(int type) { + return getImageIcon(); + } + + private Image getImageIcon() { + if (def.getType() == Shader.ShaderType.Vertex) { + return Icons.vert.getImage(); + } else { + return Icons.frag.getImage(); + } + } + + private String makeKey() { + String defName = lookup.lookup(MatDefDataObject.class).getEditableFile().getCurrentTechnique().getName(); + return defName + "/" + getName(); + } + + public String getKey() { + return key; + } + + public ShaderNodeDefinition getShaderNodeDefinition() { + return def; + } + + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("name")) { + setName((String) evt.getNewValue()); + setDisplayName((String) evt.getNewValue()); + key = makeKey(); + } else if (evt.getPropertyName().equals(ShaderNodeBlock.ADD_MAPPING) + || evt.getPropertyName().equals(ShaderNodeBlock.REMOVE_MAPPING)) { + ((MappingNodeChildren) getChildren()).reload(); + } + } + + public static class MappingNodeChildren extends Children.Keys { + + Lookup lookup; + ShaderNodeBlock node; + + public MappingNodeChildren(Lookup lookup, ShaderNodeBlock node) { + this.lookup = lookup; + this.node = node; + } + + @Override + protected void addNotify() { + super.addNotify(); + setKeys(createKeys()); + } + + public void reload() { + setKeys(createKeys()); + } + + public List createKeys() { + List l = new ArrayList(); + if (node.getInputs() != null) { + l.addAll(node.getInputs()); + } + if (node.getOutputs() != null) { + l.addAll(node.getOutputs()); + } + + return l; + } + + @Override + protected Node[] createNodes(MappingBlock key) { + return new Node[]{new MappingNode(lookup, key)}; + } + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/navigator/node/TechniqueNode.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/navigator/node/TechniqueNode.java new file mode 100644 index 000000000..ebb5e199b --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/navigator/node/TechniqueNode.java @@ -0,0 +1,118 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.navigator.node; + +import com.jme3.gde.materialdefinition.editor.Selectable; +import com.jme3.gde.materialdefinition.fileStructure.ShaderNodeBlock; +import com.jme3.gde.materialdefinition.fileStructure.TechniqueBlock; +import com.jme3.gde.materialdefinition.icons.Icons; +import com.jme3.gde.materialdefinition.navigator.node.properties.DefaultProperty; +import java.awt.Image; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.ArrayList; +import java.util.List; +import org.openide.nodes.Children; +import org.openide.nodes.Node; +import org.openide.nodes.Sheet; +import org.openide.util.Exceptions; +import org.openide.util.Lookup; +import org.openide.util.WeakListeners; + +/** + * + * @author Nehon + */ +public class TechniqueNode extends AbstractMatDefNode implements Selectable, PropertyChangeListener { + + TechniqueBlock def; + + public TechniqueNode(final Lookup lookup, final TechniqueBlock def) { + super(new ShaderNodeChildren(lookup, def), lookup); + this.def = def; + def.addPropertyChangeListener(WeakListeners.propertyChange(this, def)); + setName(def.getName()); + } + + @Override + protected Sheet createSheet() { + Sheet sheet = super.createSheet(); + Sheet.Set set = Sheet.createPropertiesSet(); + set.setName("Technique"); + try { + DefaultProperty prop = new DefaultProperty(def, String.class, "Name", "getName", "setName"); + set.put(prop); + } catch (NoSuchMethodException ex) { + Exceptions.printStackTrace(ex); + } + + sheet.put(set); + + + + return sheet; + + } + + @Override + public Image getIcon(int type) { + return Icons.tech.getImage(); + } + + @Override + public Image getOpenedIcon(int type) { + return Icons.tech.getImage(); + } + + public String getKey() { + return getName(); + } + + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("name")) { + setName((String) evt.getNewValue()); + setDisplayName((String) evt.getNewValue()); + } + if (evt.getPropertyName().equals("reorder") + || evt.getPropertyName().equals(TechniqueBlock.ADD_SHADER_NODE) + || evt.getPropertyName().equals(TechniqueBlock.REMOVE_SHADER_NODE)) { + ((ShaderNodeChildren) getChildren()).reload(); + } + } + + public static class ShaderNodeChildren extends Children.Keys { + + Lookup lookup; + TechniqueBlock def; + + public ShaderNodeChildren(Lookup lookup, TechniqueBlock def) { + this.lookup = lookup; + this.def = def; + } + + @Override + protected void addNotify() { + super.addNotify(); + setKeys(createKeys()); + } + + public void reload() { + setKeys(createKeys()); + } + + public List createKeys() { + List l = new ArrayList(); + if (def.getVertexShader() == null) { + l.addAll(def.getShaderNodes()); + } + return l; + } + + @Override + protected Node[] createNodes(ShaderNodeBlock key) { + return new Node[]{new ShaderNodeNode(lookup, key)}; + } + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/navigator/node/properties/DefaultProperty.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/navigator/node/properties/DefaultProperty.java new file mode 100644 index 000000000..487f3f80e --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/navigator/node/properties/DefaultProperty.java @@ -0,0 +1,32 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.navigator.node.properties; + +import org.openide.nodes.PropertySupport; + +/** + * + * @author Nehon + */ +public class DefaultProperty extends PropertySupport.Reflection { + + private boolean readOnly = false; + + public DefaultProperty(Object instance, Class valueType, String displayName, String getter, String setter) throws NoSuchMethodException { + super(instance, valueType, getter, setter); + setName(displayName); + setDisplayName(displayName); + } + + public DefaultProperty(Object instance, Class valueType, String displayName, String getter, String setter, boolean readOnly) throws NoSuchMethodException { + this(instance, valueType, displayName, getter, setter); + this.readOnly = readOnly; + } + + @Override + public boolean canWrite() { + return !readOnly; + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/navigator/node/properties/MatParamProperty.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/navigator/node/properties/MatParamProperty.java new file mode 100644 index 000000000..8b09e7b3f --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/navigator/node/properties/MatParamProperty.java @@ -0,0 +1,208 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.navigator.node.properties; + +import com.jme3.gde.core.assets.ProjectAssetManager; +import com.jme3.gde.core.properties.ColorRGBAPropertyEditor; +import com.jme3.gde.core.properties.Matrix3fPropertyEditor; +import com.jme3.gde.core.properties.QuaternionPropertyEditor; +import com.jme3.gde.core.properties.TexturePropertyEditor; +import com.jme3.gde.core.properties.Vector2fPropertyEditor; +import com.jme3.gde.core.properties.Vector3fPropertyEditor; +import com.jme3.gde.materialdefinition.MatDefDataObject; +import com.jme3.gde.materialdefinition.fileStructure.leaves.MatParamBlock; +import com.jme3.material.MatParam; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Matrix3f; +import com.jme3.math.Matrix4f; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector2f; +import com.jme3.math.Vector3f; +import com.jme3.math.Vector4f; +import com.jme3.shader.VarType; +import com.jme3.texture.Texture; +import java.beans.PropertyChangeListener; +import java.beans.PropertyEditor; +import java.lang.reflect.InvocationTargetException; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.openide.nodes.Node; +import org.openide.util.Lookup; + +/** + * + * @author Nehon + */ +public class MatParamProperty extends Node.Property { + + private Lookup lookup; + private String type; + private Class valueType; + + public MatParamProperty(String name, String type, Class valueType, Lookup lookup) { + super(valueType); + this.valueType = valueType; + setName(name); + this.type = type; + this.lookup = lookup; + setDisplayName(name); + } + + @Override + public boolean canRead() { + return true; + } + + + + @Override + public T getValue() throws IllegalAccessException, InvocationTargetException { + MatParam param = lookup.lookup(Material.class).getParam(getName()); + if (param != null) { + return (T) param.getValue(); + } + return null; + } + + @Override + public boolean canWrite() { + return true; + } + + @Override + public void setValue(T val) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { + Object v = val; + if (valueType == Vector3f.class) { + float[] f = getFloatArrayValue((String) val, 3); + v = new Vector3f(f[0], f[1], f[2]); + } else if (valueType == Quaternion.class) { + float[] f = getFloatArrayValue((String) val, 4); + v = new Quaternion(f[0], f[1], f[2], f[3]); + } else if (valueType == Vector4f.class) { + float[] f = getFloatArrayValue((String) val, 4); + v = new Vector4f(f[0], f[1], f[2], f[3]); + } else if (valueType == Vector2f.class) { + float[] f = getFloatArrayValue((String) val, 2); + v = new Vector2f(f[0], f[1]); + } + VarType vType = MatParamProperty.getVarType(type); + + Material m = lookup.lookup(Material.class); + m.setParam(getName(), vType, v); + MatDefDataObject obj = lookup.lookup(MatDefDataObject.class); + obj.getLookupContents().remove(m); + obj.getLookupContents().add(m); + + } + + + + public float[] getFloatArrayValue(String value, int capacity) { + float[] ret = new float[capacity]; + String[] vals = extractValues(value); + try { + for (int i = 0; i < vals.length; i++) { + ret[i] = Float.parseFloat(vals[i]); + } + } catch (NumberFormatException e) { + Logger.getLogger(VectorTextField.class.getName()).log(Level.WARNING, "Invalid format"); + } + return ret; + } + + private String[] extractValues(String value) { + String text = value.replaceAll("[\\[\\]]", ""); + String[] values = text.split(","); + return values; + } + + public String getStringFromFloatArray(float[] vals) { + String t = "["; + for (float f : vals) { + t += f + ","; + } + t = t.substring(0, t.length() - 1) + "]"; + return t; + } + + @Override + public PropertyEditor getPropertyEditor() { + if (valueType == Vector3f.class) { + return new Vector3fPropertyEditor(); + } else if (valueType == Quaternion.class) { + return new QuaternionPropertyEditor(); + } else if (valueType == Matrix3f.class) { + return new Matrix3fPropertyEditor(); + } else if (valueType == ColorRGBA.class) { + return new ColorRGBAPropertyEditor(); + } else if (valueType == Vector2f.class) { + return new Vector2fPropertyEditor(); + } else if (valueType == Texture.class) { + return new TexturePropertyEditor(lookup.lookup(ProjectAssetManager.class)); + } + + + return super.getPropertyEditor(); + } + + public static MatParamProperty makeProperty(MatParamBlock param, Lookup lookup) { + + VarType vType = MatParamProperty.getVarType(param.getType()); + switch (vType) { + case Boolean: + return new MatParamProperty(param.getName(), param.getType(), Boolean.class, lookup); + case Float: + return new MatParamProperty(param.getName(), param.getType(), Float.class, lookup); + case FloatArray: + return new MatParamProperty(param.getName(), param.getType(), Object.class, lookup); + case Int: + return new MatParamProperty(param.getName(), param.getType(), Integer.class, lookup); + case Matrix3: + return new MatParamProperty(param.getName(), param.getType(), Matrix3f.class, lookup); + case Matrix3Array: + return new MatParamProperty(param.getName(), param.getType(), Object.class, lookup); + case Matrix4: + return new MatParamProperty(param.getName(), param.getType(), Matrix4f.class, lookup); + case Matrix4Array: + return new MatParamProperty(param.getName(), param.getType(), Object.class, lookup); + case Texture2D: + case Texture3D: + case TextureArray: + case TextureBuffer: + case TextureCubeMap: + return new MatParamProperty(param.getName(), param.getType(), Texture.class, lookup); + case Vector2: + return new MatParamProperty(param.getName(), param.getType(), Vector2f.class, lookup); + case Vector2Array: + return new MatParamProperty(param.getName(), param.getType(), Object.class, lookup); + case Vector3: + return new MatParamProperty(param.getName(), param.getType(), Vector3f.class, lookup); + case Vector3Array: + return new MatParamProperty(param.getName(), param.getType(), Object.class, lookup); + case Vector4: + if (param.getType().equals("Color")) { + return new MatParamProperty(param.getName(), param.getType(), ColorRGBA.class, lookup); + } + return new MatParamProperty(param.getName(), param.getType(), Vector4f.class, lookup); + case Vector4Array: + return new MatParamProperty(param.getName(), param.getType(), Object.class, lookup); + default: + return null; + } + } + + private static VarType getVarType(String type) { + VarType vType = null; + if (type.equals("Color")) { + vType = VarType.Vector4; + } else { + vType = VarType.valueOf(type); + } + return vType; + } + + +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/navigator/node/properties/VectorInplaceEditor.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/navigator/node/properties/VectorInplaceEditor.java new file mode 100644 index 000000000..c62dc7b35 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/navigator/node/properties/VectorInplaceEditor.java @@ -0,0 +1,94 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.navigator.node.properties; + +import com.jme3.math.Vector2f; +import java.awt.Component; +import java.awt.event.ActionListener; +import java.beans.PropertyEditor; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.JComponent; +import javax.swing.KeyStroke; +import org.openide.explorer.propertysheet.InplaceEditor; +import org.openide.explorer.propertysheet.PropertyEnv; +import org.openide.explorer.propertysheet.PropertyModel; + +/** + * + * @author Nehon + */ +public class VectorInplaceEditor implements InplaceEditor { + + private VectorTextField field; + private PropertyEditor editor = null; + private PropertyModel model; + private PropertyEnv env; + + public VectorInplaceEditor(int capacity) { + field = new VectorTextField(capacity); + } + + public void connect(PropertyEditor pe, PropertyEnv env) { + editor = pe; + this.env = env; + reset(); + } + + public JComponent getComponent() { + return field; + } + + public void clear() { + editor = null; + model = null; + } + + public Object getValue() { + return field.getText(); + } + + public void setValue(Object o) { + field.setText((String) o); + } + + public boolean supportsTextEntry() { + return true; + } + + public void reset() { + if (editor.getValue() != null) { + field.setText((String) editor.getValue()); + } + } + + public void addActionListener(ActionListener al) { + field.addActionListener(al); + } + + public void removeActionListener(ActionListener al) { + field.removeActionListener(al); + } + + public KeyStroke[] getKeyStrokes() { + return new KeyStroke[0]; + } + + public PropertyEditor getPropertyEditor() { + return editor; + } + + public PropertyModel getPropertyModel() { + return model; + } + + public void setPropertyModel(PropertyModel pm) { + model = pm; + } + + public boolean isKnownComponent(Component cmpnt) { + return cmpnt == field || field.isAncestorOf(cmpnt); + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/navigator/node/properties/VectorPropertyEditor.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/navigator/node/properties/VectorPropertyEditor.java new file mode 100644 index 000000000..036dd2771 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/navigator/node/properties/VectorPropertyEditor.java @@ -0,0 +1,47 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.navigator.node.properties; + +import java.beans.PropertyEditorSupport; +import org.openide.explorer.propertysheet.ExPropertyEditor; +import org.openide.explorer.propertysheet.InplaceEditor; +import org.openide.explorer.propertysheet.PropertyEnv; + +/** + * + * @author Nehon + */ +public class VectorPropertyEditor extends PropertyEditorSupport implements ExPropertyEditor, InplaceEditor.Factory { + + private PropertyEnv env; + private VectorInplaceEditor editor; + + public VectorPropertyEditor(int capacity) { + editor = new VectorInplaceEditor(capacity); + } + + public void attachEnv(PropertyEnv env) { + this.env = env; + env.registerInplaceEditorFactory(this); + } + + public InplaceEditor getInplaceEditor() { + return editor; + } + + @Override + public String getAsText() { + return (String) editor.getValue(); + } + + + + @Override + public void setAsText(String text) throws IllegalArgumentException { + editor.setValue(text); + } + + +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/navigator/node/properties/VectorTextField.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/navigator/node/properties/VectorTextField.java new file mode 100644 index 000000000..9b14e3303 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/navigator/node/properties/VectorTextField.java @@ -0,0 +1,170 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.navigator.node.properties; + +import java.awt.KeyboardFocusManager; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.JTextField; + +/** + * + * @author Nehon + */ +public class VectorTextField extends JTextField implements KeyListener, MouseListener, FocusListener { + + private int index = 0; + private int capacity = 4; + private boolean pressed = false; + private String backup; + + public VectorTextField(int capacity) { + setFocusTraversalKeysEnabled(false); + addKeyListener(this); + addFocusListener(this); + addMouseListener(this); + setFocusTraversalKeysEnabled(false); + this.capacity = capacity; + backup = "["; + for (int i = 0; i < capacity; i++) { + backup += "0"; + if (i != capacity - 1) { + backup += ","; + } + } + backup += "]"; + } + + @Override + public void keyTyped(KeyEvent e) { + } + + @Override + public void keyPressed(KeyEvent e) { + // + if (e.getKeyCode() == KeyEvent.VK_TAB) { + if (checkValidity()) { + backup = getText(); + if (e.getModifiersEx() == KeyEvent.SHIFT_DOWN_MASK) { + index = index - 1; + + } else { + index = index + 1; + } + if (index == capacity) { + KeyboardFocusManager.getCurrentKeyboardFocusManager().focusNextComponent(); + return; + } + if (index == -1) { + KeyboardFocusManager.getCurrentKeyboardFocusManager().focusPreviousComponent(); + return; + } + + } else { + setText(backup); + Logger.getLogger(VectorTextField.class.getName()).log(Level.WARNING, "Invalid format"); + } + findSelection(0); + } + } + + private boolean checkValidity() { + String[] values = extractValues(); + return values.length == capacity; + + } + + @Override + public void keyReleased(KeyEvent e) { + } + + @Override + public void mouseClicked(MouseEvent e) { + } + + @Override + public void mousePressed(MouseEvent e) { + init(); + pressed = true; + } + + @Override + public void mouseReleased(MouseEvent e) { + init(); + index = findSelection(getCaretPosition()); + pressed = false; + } + + @Override + public void mouseEntered(MouseEvent e) { + } + + @Override + public void mouseExited(MouseEvent e) { + } + + @Override + public void focusGained(FocusEvent e) { + if (!pressed) { + init(); + findSelection(0); + } + } + + @Override + public void focusLost(FocusEvent e) { + } + + private void init() { + index = 0; + if (getText().trim().equals("")) { + setText(backup); + setCaretPosition(1); + } + + } + + + + public void clear() { + setText(""); + } + + private int findSelection(int caretPosition) { + String[] values = extractValues(); + int start = 0;// = 1; + int end = 0;// = values[0].length() + start; + if (caretPosition == getText().length()) { + caretPosition--; + } + int i; + if (caretPosition != 0) { + for (i = 0; caretPosition > end; i++) { + start = end + 1; + end = values[i].length() + start; + } + i--; + } else { + for (i = 0; i <= index; i++) { + start = end + 1; + end = values[i].length() + start; + } + } + select(start, end); + return i; + } + + private String[] extractValues() { + String text = getText().replaceAll("[\\[\\]]", ""); + String[] values = text.split(","); + return values; + } +} \ No newline at end of file diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materials/JMEMaterialDefinitionDataObject.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/package-info.java similarity index 68% rename from sdk/jme3-materialeditor/src/com/jme3/gde/materials/JMEMaterialDefinitionDataObject.java rename to sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/package-info.java index f8f91779c..a140d606c 100644 --- a/sdk/jme3-materialeditor/src/com/jme3/gde/materials/JMEMaterialDefinitionDataObject.java +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/package-info.java @@ -29,23 +29,7 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package com.jme3.gde.materials; +@TemplateRegistration(folder = "Material", content = "MatDef.j3md",displayName="Material Definition Template") +package com.jme3.gde.materialdefinition; -import java.io.IOException; -import org.openide.filesystems.FileObject; -import org.openide.loaders.DataObjectExistsException; -import org.openide.loaders.MultiDataObject; -import org.openide.loaders.MultiFileLoader; -import org.openide.nodes.CookieSet; -import org.openide.nodes.Node; -import org.openide.text.DataEditorSupport; - -public class JMEMaterialDefinitionDataObject extends MultiDataObject { - - public JMEMaterialDefinitionDataObject(FileObject pf, MultiFileLoader loader) throws DataObjectExistsException, IOException { - super(pf, loader); - CookieSet cookies = getCookieSet(); - cookies.add((Node.Cookie) DataEditorSupport.create(this, getPrimaryEntry(), cookies)); - } - -} +import org.netbeans.api.templates.TemplateRegistration; diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/shadervisual/Bundle.properties b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/shadervisual/Bundle.properties new file mode 100644 index 000000000..f8bbe8ebc --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/shadervisual/Bundle.properties @@ -0,0 +1,4 @@ +ShaderVisualToolBar.jLabel1.text=Version : +ShaderVisualToolBar.vertButton.toolTipText=Vertex Shader +ShaderVisualToolBar.fragButton.actionCommand= +ShaderVisualToolBar.fragButton.toolTipText=Fragment Shader diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/shadervisual/MatDefShaderElement.form b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/shadervisual/MatDefShaderElement.form new file mode 100644 index 000000000..7f7c2e864 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/shadervisual/MatDefShaderElement.form @@ -0,0 +1,44 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/shadervisual/MatDefShaderElement.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/shadervisual/MatDefShaderElement.java new file mode 100644 index 000000000..a2bbeb408 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/shadervisual/MatDefShaderElement.java @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2009-2010 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.jme3.gde.materialdefinition.shadervisual; + +import com.jme3.gde.core.assets.ProjectAssetManager; +import com.jme3.gde.materialdefinition.EditableMatDefFile; +import com.jme3.gde.materialdefinition.MatDefDataObject; +import javax.swing.Action; +import javax.swing.JComponent; +import javax.swing.JPanel; +import org.netbeans.core.spi.multiview.CloseOperationState; +import org.netbeans.core.spi.multiview.MultiViewElement; +import org.netbeans.core.spi.multiview.MultiViewElementCallback; +import org.openide.awt.UndoRedo; +import org.openide.util.Lookup; +import org.openide.util.NbBundle.Messages; +import org.openide.windows.TopComponent; + +@MultiViewElement.Registration( + displayName = "#LBL_MatDef_SHADER", +iconBase = "com/jme3/gde/materialdefinition/icons/matdef.png", +mimeType = "text/jme-materialdefinition", +persistenceType = TopComponent.PERSISTENCE_ONLY_OPENED, +preferredID = "MatDefVisual", +position = 3000) +@Messages("LBL_MatDef_SHADER=Shader") +public final class MatDefShaderElement extends JPanel implements MultiViewElement { + + private MatDefDataObject obj; + private ShaderVisualToolBar toolbar = new ShaderVisualToolBar(); + private transient MultiViewElementCallback callback; + + public MatDefShaderElement(Lookup lkp) { + obj = lkp.lookup(MatDefDataObject.class); + assert obj != null; + initComponents(); + toolbar.setParent(this); + refresh(); + } + + public final void refresh() { + jEditorPane1.setText(obj.getEditableFile().getShaderCode(toolbar.getVersion(), toolbar.getType())); + } + + @Override + public String getName() { + return "MatDefVisualElement"; + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + jScrollPane1 = new javax.swing.JScrollPane(); + jEditorPane1 = new javax.swing.JEditorPane(); + + jEditorPane1.setEditable(false); + jEditorPane1.setFont(new java.awt.Font("Monospaced", 0, 13)); // NOI18N + jScrollPane1.setViewportView(jEditorPane1); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPane1) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE) + ); + }// //GEN-END:initComponents + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JEditorPane jEditorPane1; + private javax.swing.JScrollPane jScrollPane1; + // End of variables declaration//GEN-END:variables + + @Override + public JComponent getVisualRepresentation() { + return this; + } + + @Override + public JComponent getToolbarRepresentation() { + return toolbar; + } + + @Override + public Action[] getActions() { + return new Action[0]; + } + + @Override + public Lookup getLookup() { + return obj.getLookup(); + } + + @Override + public void componentOpened() { + } + + @Override + public void componentClosed() { + } + + @Override + public void componentShowing() { + } + + @Override + public void componentHidden() { + } + + @Override + public void componentActivated() { + refresh(); + } + + @Override + public void componentDeactivated() { + } + + @Override + public UndoRedo getUndoRedo() { + return UndoRedo.NONE; + } + + @Override + public void setMultiViewCallback(MultiViewElementCallback callback) { + this.callback = callback; + } + + @Override + public CloseOperationState canCloseElement() { + return CloseOperationState.STATE_OK; + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/shadervisual/ShaderVisualToolBar.form b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/shadervisual/ShaderVisualToolBar.form new file mode 100644 index 000000000..61262e237 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/shadervisual/ShaderVisualToolBar.form @@ -0,0 +1,105 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/shadervisual/ShaderVisualToolBar.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/shadervisual/ShaderVisualToolBar.java new file mode 100644 index 000000000..0e25b0e85 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/shadervisual/ShaderVisualToolBar.java @@ -0,0 +1,128 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.shadervisual; + +import com.jme3.gde.materialdefinition.icons.Icons; +import com.jme3.shader.Shader; + +/** + * + * @author Nehon + */ +public class ShaderVisualToolBar extends javax.swing.JPanel { + + private MatDefShaderElement parent; + + /** + * Creates new form ShaderVisualToolBar + */ + public ShaderVisualToolBar() { + initComponents(); + } + + public void setParent(MatDefShaderElement parent) { + this.parent = parent; + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + btnGroup = new javax.swing.ButtonGroup(); + jLabel1 = new javax.swing.JLabel(); + versionList = new javax.swing.JComboBox(); + vertButton = new javax.swing.JToggleButton(); + fragButton = new javax.swing.JToggleButton(); + + org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(ShaderVisualToolBar.class, "ShaderVisualToolBar.jLabel1.text")); // NOI18N + + versionList.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "GLSL100", "GLSL150" })); + versionList.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + versionListActionPerformed(evt); + } + }); + + btnGroup.add(vertButton); + vertButton.setIcon(Icons.vert); + vertButton.setSelected(true); + vertButton.setToolTipText(org.openide.util.NbBundle.getMessage(ShaderVisualToolBar.class, "ShaderVisualToolBar.vertButton.toolTipText")); // NOI18N + vertButton.setIconTextGap(0); + vertButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + vertButtonActionPerformed(evt); + } + }); + + btnGroup.add(fragButton); + fragButton.setIcon(Icons.frag); + fragButton.setToolTipText(org.openide.util.NbBundle.getMessage(ShaderVisualToolBar.class, "ShaderVisualToolBar.fragButton.toolTipText")); // NOI18N + fragButton.setActionCommand(org.openide.util.NbBundle.getMessage(ShaderVisualToolBar.class, "ShaderVisualToolBar.fragButton.actionCommand")); // NOI18N + fragButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + fragButtonActionPerformed(evt); + } + }); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(vertButton, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(fragButton, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(10, 10, 10) + .addComponent(jLabel1) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(versionList, javax.swing.GroupLayout.PREFERRED_SIZE, 131, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(154, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(fragButton, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1) + .addComponent(versionList, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(vertButton, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)) + ); + }// //GEN-END:initComponents + + private void vertButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_vertButtonActionPerformed + parent.refresh(); + }//GEN-LAST:event_vertButtonActionPerformed + + private void fragButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fragButtonActionPerformed + parent.refresh(); + }//GEN-LAST:event_fragButtonActionPerformed + + private void versionListActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_versionListActionPerformed + parent.refresh(); + }//GEN-LAST:event_versionListActionPerformed + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.ButtonGroup btnGroup; + private javax.swing.JToggleButton fragButton; + private javax.swing.JLabel jLabel1; + private javax.swing.JComboBox versionList; + private javax.swing.JToggleButton vertButton; + // End of variables declaration//GEN-END:variables + + public String getVersion() { + return versionList.getSelectedItem().toString(); + } + + public Shader.ShaderType getType() { + if (btnGroup.isSelected(vertButton.getModel())) { + return Shader.ShaderType.Vertex; + } else { + return Shader.ShaderType.Fragment; + } + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/utils/DocFormatter.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/utils/DocFormatter.java new file mode 100644 index 000000000..aaa66fde3 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/utils/DocFormatter.java @@ -0,0 +1,97 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.utils; + +import com.jme3.gde.materialdefinition.dialog.AddNodeDialog; +import com.jme3.gde.materialdefinition.icons.Icons; +import com.jme3.shader.ShaderNodeDefinition; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.text.BadLocationException; +import javax.swing.text.Style; +import javax.swing.text.StyleConstants; +import javax.swing.text.StyleContext; +import javax.swing.text.StyledDocument; + +/** + * + * @author m327836 + */ +public class DocFormatter { + + private static DocFormatter instance; + private Style regStyle = StyleContext.getDefaultStyleContext(). + getStyle(StyleContext.DEFAULT_STYLE); + + private DocFormatter() { + } + + public static DocFormatter getInstance() { + if (instance == null) { + instance = new DocFormatter(); + } + return instance; + } + + private void makeStyles(StyledDocument doc) { + Style s1 = doc.addStyle("regular", regStyle); + StyleConstants.setFontFamily(s1, "SansSerif"); + Style s2 = doc.addStyle("bold", s1); + StyleConstants.setBold(s2, true); + Style icon = doc.addStyle("input", s1); + StyleConstants.setAlignment(icon, StyleConstants.ALIGN_CENTER); + StyleConstants.setSpaceAbove(icon, 8); + StyleConstants.setIcon(icon, Icons.in); + Style icon2 = doc.addStyle("output", s1); + StyleConstants.setAlignment(icon2, StyleConstants.ALIGN_CENTER); + StyleConstants.setSpaceAbove(icon2, 8); + StyleConstants.setIcon(icon2, Icons.out); + + + } + + public static void addDoc(ShaderNodeDefinition def, StyledDocument doc) { + + if (doc.getStyle("regular") == null) { + getInstance().makeStyles(doc); + } + + try { + String[] lines = def.getDocumentation().split("\\n"); + doc.insertString(doc.getLength(), "Shader type : " + def.getType().toString() + "\n", doc.getStyle("regular")); + + for (int i = 0; i < def.getShadersLanguage().size(); i++) { + doc.insertString(doc.getLength(), "Shader : " + def.getShadersLanguage().get(i) + " " + def.getShadersPath().get(i) + "\n", doc.getStyle("regular")); + } +// doc.insertString(doc.getLength(), "\n", doc.getStyle("regular")); + + for (String string : lines) { + String l = string.trim() + "\n"; + if (l.startsWith("@input")) { + l = l.substring(6).trim(); + int spaceIdx = l.indexOf(' '); + doc.insertString(doc.getLength(), "\n", doc.getStyle("regular")); + doc.insertString(doc.getLength(), " ", doc.getStyle("input")); + doc.insertString(doc.getLength(), l.substring(0, spaceIdx), doc.getStyle("bold")); + doc.insertString(doc.getLength(), l.substring(spaceIdx), doc.getStyle("regular")); + + } else if (l.startsWith("@output")) { + l = l.substring(7).trim(); + int spaceIdx = l.indexOf(' '); + doc.insertString(doc.getLength(), "\n", doc.getStyle("regular")); + doc.insertString(doc.getLength(), " ", doc.getStyle("output")); + doc.insertString(doc.getLength(), l.substring(0, spaceIdx), doc.getStyle("bold")); + doc.insertString(doc.getLength(), l.substring(spaceIdx), doc.getStyle("regular")); + + } else { + doc.insertString(doc.getLength(), l, doc.getStyle("regular")); + } + + } + } catch (BadLocationException ex) { + Logger.getLogger(AddNodeDialog.class.getName()).log(Level.SEVERE, null, ex); + } + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/utils/MaterialUtils.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/utils/MaterialUtils.java new file mode 100644 index 000000000..36fb9f35f --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/utils/MaterialUtils.java @@ -0,0 +1,132 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.materialdefinition.utils; + +import com.jme3.asset.ShaderNodeDefinitionKey; +import com.jme3.gde.core.assets.ProjectAssetManager; +import com.jme3.gde.materialdefinition.fileStructure.ShaderNodeBlock; +import com.jme3.gde.materialdefinition.fileStructure.leaves.InputMappingBlock; +import com.jme3.gde.materialdefinition.fileStructure.leaves.MappingBlock; +import com.jme3.gde.materialdefinition.fileStructure.leaves.MatParamBlock; +import com.jme3.gde.materialdefinition.fileStructure.leaves.WorldParamBlock; +import com.jme3.shader.ShaderNodeDefinition; +import com.jme3.shader.ShaderNodeVariable; +import com.jme3.shader.ShaderUtils; +import com.jme3.shader.UniformBinding; +import com.jme3.shader.VarType; +import java.util.List; + +/** + * + * @author Nehon + */ +public class MaterialUtils { + + public static String makeKey(MappingBlock mapping, String techName) { + + String rightName = mapping.getRightVar(); + String leftName = mapping.getLeftVar(); + String leftSwizzle = mapping.getLeftVarSwizzle() != null ? "." + mapping.getLeftVarSwizzle() : ""; + String rightSwizzle = mapping.getRightVarSwizzle() != null ? "." + mapping.getRightVarSwizzle() : ""; + return techName + "/" + mapping.getLeftNameSpace() + "." + leftName + leftSwizzle + "=" + mapping.getRightNameSpace() + "." + rightName + rightSwizzle; + } + + /** + * trims a line and removes comments + * + * @param line + * @return + */ + public static String trimLine(String line) { + int idx = line.indexOf("//"); + if (idx != -1) { + line = line.substring(0, idx); + } + return line.trim(); + } + + /** + * trims a line and removes everything behind colon + * + * @param line + * @return + */ + public static String trimName(String line) { + line = trimLine(line); + int idx = line.indexOf("("); + if (idx == -1) { + idx = line.indexOf(":"); + } + if (idx != -1) { + line = line.substring(0, idx); + } + return line.trim(); + } + + public static ShaderNodeDefinition loadShaderNodeDefinition(ShaderNodeBlock shaderNode, ProjectAssetManager manager) { + return loadShaderNodeDefinition(shaderNode.getDefinition().getPath(), shaderNode.getDefinition().getName(), manager); + } + + public static ShaderNodeDefinition loadShaderNodeDefinition(String path, String name, ProjectAssetManager manager) { + ShaderNodeDefinitionKey k = new ShaderNodeDefinitionKey(path); + k.setLoadDocumentation(true); + List defs = (List) manager.loadAsset(k); + for (ShaderNodeDefinition shaderNodeDefinition : defs) { + if (shaderNodeDefinition.getName().equals(name)) { + return shaderNodeDefinition; + } + } + return null; + } + + /** + * updates the type of the right variable of a mapping from the type of the + * left variable + * + * @param mapping the mapping to consider + */ + public static String guessType(InputMappingBlock mapping, ShaderNodeVariable left) { + String type = left.getType(); + int card = ShaderUtils.getCardinality(type, mapping.getRightVarSwizzle() == null ? "" : mapping.getRightVarSwizzle()); + if (card > 0) { + if (card == 1) { + type = "float"; + } else { + type = "vec" + card; + } + } + return type; + } + + public static ShaderNodeVariable getVar(List ins, String name) { + for (ShaderNodeVariable shaderNodeVariable : ins) { + if (shaderNodeVariable.getName().equals(name)) { + return shaderNodeVariable; + } + } + return null; + } + + public static String getMatParamType(MatParamBlock param) { + String type = param.getType(); + if (type.equals("Color")) { + type = "Vector4"; + } + return VarType.valueOf(type).getGlslType(); + } + + public static String getWorldParamType(String name) { + return UniformBinding.valueOf(name).getGlslType(); + } + + public static boolean contains(List vars, ShaderNodeVariable var) { + for (ShaderNodeVariable shaderNodeVariable : vars) { + if (shaderNodeVariable.getName().equals(var.getName()) && shaderNodeVariable.getNameSpace().equals(var.getNameSpace())) { + return true; + } + } + return false; + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materials/EditableMaterialFile.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materials/EditableMaterialFile.java index cfbf2b9d3..72d082a41 100644 --- a/sdk/jme3-materialeditor/src/com/jme3/gde/materials/EditableMaterialFile.java +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materials/EditableMaterialFile.java @@ -7,6 +7,7 @@ package com.jme3.gde.materials; import com.jme3.asset.TextureKey; import com.jme3.gde.core.assets.ProjectAssetManager; import com.jme3.gde.core.util.Beans; +import com.jme3.gde.materialdefinition.utils.MaterialUtils; import com.jme3.gde.materials.wizards.StoreTextureWizardWizardAction; import com.jme3.material.MatParam; import com.jme3.material.MatParamTexture; @@ -90,7 +91,7 @@ public class EditableMaterialFile { //scan material text for (String line : material.asLines()) { //trim line incl comments - line = trimLine(line); + line = MaterialUtils.trimLine(line); //find and load matdef file if (line.startsWith("Material ") || line.startsWith("Material\t") && level == 0) { parseMaterialProperties(line); @@ -223,7 +224,7 @@ public class EditableMaterialFile { if (matDef != null && matDef.isValid()) { try { for (String defLine : matDef.asLines()) { - defLine = trimLine(defLine.trim()); + defLine = MaterialUtils.trimLine(defLine.trim()); if (defLine.startsWith("MaterialParameters ") || defLine.startsWith("MaterialParameters\t") || defLine.startsWith("MaterialParameters{") && level == 1) { params = true; } @@ -241,7 +242,7 @@ public class EditableMaterialFile { for (int i = 0; i < variableTypes.length; i++) { String string = variableTypes[i]; if (defLine.startsWith(string)) { - String name = trimName(defLine.replaceFirst(string, "")); + String name = MaterialUtils.trimName(defLine.replaceFirst(string, "")); matDefEntries.add(name); MaterialProperty prop = materialParameters.get(name); if (prop == null) { @@ -288,7 +289,7 @@ public class EditableMaterialFile { //goes through the lines of the material file and replaces the values it finds for (String line : matLines) { String newLine = line; - line = trimLine(line); + line = MaterialUtils.trimLine(line); //write material header if (line.startsWith("Material ") || line.startsWith("Material\t") && level == 0) { String suffix = ""; @@ -426,37 +427,7 @@ public class EditableMaterialFile { out.close(); } - /** - * trims a line and removes comments - * - * @param line - * @return - */ - private String trimLine(String line) { - int idx = line.indexOf("//"); - if (idx != -1) { - line = line.substring(0, idx); - } - return line.trim(); - } - - /** - * trims a line and removes everything behind colon - * - * @param line - * @return - */ - private String trimName(String line) { - line = trimLine(line); - int idx = line.indexOf("("); - if (idx == -1) { - idx = line.indexOf(":"); - } - if (idx != -1) { - line = line.substring(0, idx); - } - return line.trim(); - } + public Map getParameterMap() { return materialParameters; diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materials/JMEMaterialDefinitionResolver.xml b/sdk/jme3-materialeditor/src/com/jme3/gde/materials/JMEMaterialDefinitionResolver.xml deleted file mode 100644 index 5ae719e8d..000000000 --- a/sdk/jme3-materialeditor/src/com/jme3/gde/materials/JMEMaterialDefinitionResolver.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materials/MaterialDefinition.j3md b/sdk/jme3-materialeditor/src/com/jme3/gde/materials/MaterialDefinition.j3md deleted file mode 100644 index 9a58e1e76..000000000 --- a/sdk/jme3-materialeditor/src/com/jme3/gde/materials/MaterialDefinition.j3md +++ /dev/null @@ -1,16 +0,0 @@ -MaterialDef My MaterialDef { - - MaterialParameters { - Vector4 Color - } - - Technique { - VertexShader GLSL100: Common/MatDefs/Misc/SolidColor.vert - FragmentShader GLSL100: Common/MatDefs/Misc/SolidColor.frag - - WorldParameters { - WorldViewProjectionMatrix - } - } - -} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materials/jme-logo.png b/sdk/jme3-materialeditor/src/com/jme3/gde/materials/jme-logo.png index f67785a6e..8b1fbdf91 100644 Binary files a/sdk/jme3-materialeditor/src/com/jme3/gde/materials/jme-logo.png and b/sdk/jme3-materialeditor/src/com/jme3/gde/materials/jme-logo.png differ diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materials/layer.xml b/sdk/jme3-materialeditor/src/com/jme3/gde/materials/layer.xml index b52fae921..119b6ce11 100644 --- a/sdk/jme3-materialeditor/src/com/jme3/gde/materials/layer.xml +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materials/layer.xml @@ -79,75 +79,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -158,10 +90,7 @@ - - - - + @@ -172,11 +101,7 @@ - - - - - +