You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
265 lines
11 KiB
265 lines
11 KiB
12 years ago
|
/*
|
||
|
* 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<Statement> 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<Shader.ShaderSource> 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<InputMappingBlock> 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<OutputMappingBlock> 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<MaterialDef> key = new AssetKey<MaterialDef>(assetManager.getRelativeAssetPath(matDefFile.getPath()));
|
||
|
obj.getLookupContents().remove(materialDef);
|
||
|
matToRemove = material;
|
||
|
|
||
|
List<Statement> l = new ArrayList<Statement>();
|
||
|
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);
|
||
|
|
||
|
}
|
||
|
}
|