From 81053352ac3630d750e667c10fb78b471fdaf185 Mon Sep 17 00:00:00 2001 From: Nehon Date: Mon, 9 May 2016 17:08:22 +0200 Subject: [PATCH] initial and partial implementation of a j3md exporter with test --- .../export/materialdef/J3mdExporter.java | 72 +++++ .../materialdef/J3mdMatDefOutputCapsule.java | 101 +++++++ .../J3mdMatParamOutputCapsule.java | 151 +++++++++++ .../materialdef/J3mdOutputCapsuleAdapter.java | 255 ++++++++++++++++++ .../material/plugin/TestMaterialDefWrite.java | 110 ++++++++ 5 files changed, 689 insertions(+) create mode 100644 jme3-plugins/src/main/java/com/jme3/material/plugin/export/materialdef/J3mdExporter.java create mode 100644 jme3-plugins/src/main/java/com/jme3/material/plugin/export/materialdef/J3mdMatDefOutputCapsule.java create mode 100644 jme3-plugins/src/main/java/com/jme3/material/plugin/export/materialdef/J3mdMatParamOutputCapsule.java create mode 100644 jme3-plugins/src/main/java/com/jme3/material/plugin/export/materialdef/J3mdOutputCapsuleAdapter.java create mode 100644 jme3-plugins/src/test/java/com/jme3/material/plugin/TestMaterialDefWrite.java diff --git a/jme3-plugins/src/main/java/com/jme3/material/plugin/export/materialdef/J3mdExporter.java b/jme3-plugins/src/main/java/com/jme3/material/plugin/export/materialdef/J3mdExporter.java new file mode 100644 index 000000000..25fdd2971 --- /dev/null +++ b/jme3-plugins/src/main/java/com/jme3/material/plugin/export/materialdef/J3mdExporter.java @@ -0,0 +1,72 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.material.plugin.export.materialdef; + +import com.jme3.export.JmeExporter; +import com.jme3.export.OutputCapsule; +import com.jme3.export.Savable; +import com.jme3.material.*; + +import java.io.*; + +/** + * Saves a Material to a j3m file with proper formatting. + * + * usage is : + *
+ *     J3mdExporter exporter = new J3mdExporter();
+ *     exporter.save(material, myFile);
+ *     //or
+ *     exporter.save(material, myOutputStream);
+ * 
+ * + * @author tsr + * @author nehon (documentation and safety check) + */ +public class J3mdExporter implements JmeExporter { + + private final J3mdMatDefOutputCapsule rootCapsule; + + /** + * Create a J3mdExporter + */ + public J3mdExporter() { + rootCapsule = new J3mdMatDefOutputCapsule(this); + } + + @Override + public void save(Savable object, OutputStream f) throws IOException { + + if (!(object instanceof MaterialDef)) { + throw new IllegalArgumentException("J3mdExporter can only save com.jme3.material.MaterialDef class"); + } + + OutputStreamWriter out = new OutputStreamWriter(f); + + rootCapsule.clear(); + object.write(this); + rootCapsule.writeToStream(out); + + out.flush(); + } + + @Override + public void save(Savable object, File f) throws IOException { + try (FileOutputStream fos = new FileOutputStream(f)) { + save(object, fos); + } + } + + @Override + public OutputCapsule getCapsule(Savable object) { + if (object instanceof MaterialDef) { + return rootCapsule; + } + + return rootCapsule.getCapsule(object); + } + +} diff --git a/jme3-plugins/src/main/java/com/jme3/material/plugin/export/materialdef/J3mdMatDefOutputCapsule.java b/jme3-plugins/src/main/java/com/jme3/material/plugin/export/materialdef/J3mdMatDefOutputCapsule.java new file mode 100644 index 000000000..397450a38 --- /dev/null +++ b/jme3-plugins/src/main/java/com/jme3/material/plugin/export/materialdef/J3mdMatDefOutputCapsule.java @@ -0,0 +1,101 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.material.plugin.export.materialdef; + +import com.jme3.export.*; +import com.jme3.material.*; + +import java.io.*; +import java.util.*; + +/** + * @author nehon + */ +public class J3mdMatDefOutputCapsule extends J3mdOutputCapsuleAdapter { + + //private final HashMap outCapsules; + private String name; + private List matParams = new ArrayList(); + boolean textureParam= false; + + + public J3mdMatDefOutputCapsule(J3mdExporter exporter) { + super(exporter); + } + + @Override + public void clear() { + super.clear(); + name = ""; + matParams.clear(); + } + + public OutputCapsule getCapsule(Savable object) { + if(object instanceof MatParam){ + if(object instanceof MatParamTexture && textureParam){ + textureParam = false; + return matParams.get(matParams.size() - 1); + } + if( object instanceof MatParamTexture){ + textureParam = true; + } + J3mdMatParamOutputCapsule matParamCapsule = new J3mdMatParamOutputCapsule(exporter); + matParams.add(matParamCapsule); + return matParamCapsule; + } + + throw new IllegalArgumentException("Unsupported type : " + object.getClass().getName()); + + } + + @Override + public void writeToStream(OutputStreamWriter out) throws IOException { + out.write("MaterialDef " + name + " {\n"); + + out.write(" MaterialParameters {\n"); + for (J3mdOutputCapsuleAdapter matParam : matParams) { + matParam.writeToStream(out); + } + out.write(" }\n\n"); +// +// for (J3mdOutputCapsule c : outCapsules.values()) { +// c.writeToStream(out); +// } + out.write("}\n"); + } + + @Override + public void write(String value, String name, String defVal) throws IOException { + switch (name) { + case "name": + this.name = value; + break; + default: + throw new UnsupportedOperationException(name + " string material parameter not supported yet"); + } + } + + @Override + public void write(Savable object, String name, Savable defVal) throws IOException { + object.write(exporter); + } + + @Override + public void writeStringSavableMap(Map map, String name, Map defVal) throws IOException { + switch (name) { + case "matParams": + for (Savable savable : map.values()) { + savable.write(exporter); + } + break; + case "techniques": + //nothing for now + break; + default: + throw new UnsupportedOperationException(name + " string material parameter not supported yet"); + } + } +} diff --git a/jme3-plugins/src/main/java/com/jme3/material/plugin/export/materialdef/J3mdMatParamOutputCapsule.java b/jme3-plugins/src/main/java/com/jme3/material/plugin/export/materialdef/J3mdMatParamOutputCapsule.java new file mode 100644 index 000000000..37b730bcf --- /dev/null +++ b/jme3-plugins/src/main/java/com/jme3/material/plugin/export/materialdef/J3mdMatParamOutputCapsule.java @@ -0,0 +1,151 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.material.plugin.export.materialdef; + +import com.jme3.export.*; +import com.jme3.math.*; +import com.jme3.texture.image.ColorSpace; + +import java.io.*; +import java.util.*; + +import static com.jme3.shader.VarType.Vector2; +import static com.jme3.shader.VarType.Vector3; +import static com.jme3.shader.VarType.Vector4; + +/** + * @author nehon + */ +public class J3mdMatParamOutputCapsule extends J3mdOutputCapsuleAdapter { + + private String name; + private String varType; + private String value; + private String space; + + + + public J3mdMatParamOutputCapsule(J3mdExporter exporter) { + super(exporter); + } + + @Override + public void clear() { + super.clear(); + name = ""; + varType = ""; + value = ""; + space = ""; + } + + @Override + public void writeToStream(OutputStreamWriter out) throws IOException { + out.write(" "); + out.write(varType); + out.write(" "); + out.write(name); + if(space != null) { + out.write(" "); + out.write(space); + } + if(value != null){ + out.write(" : "); + out.write(value); + } + out.write("\n"); + } + + @Override + public void write(String value, String name, String defVal) throws IOException { + switch (name) { + case "name": + this.name = value; + break; + default: + throw new UnsupportedOperationException(name + " string material parameter not supported yet"); + } + } + + @Override + public void write(Savable object, String name, Savable defVal) throws IOException { + + + if(name.equals("texture")){ + return; + } + + if(name.equals("value_savable")){ + if(object instanceof Vector2f) { + Vector2f v = (Vector2f)object; + this.value = v.getX() + " " + v.getY(); + } else if (object instanceof Vector3f) { + Vector3f v = (Vector3f)object; + this.value = v.getX() + " " + v.getY()+ " " + v.getZ(); + } else if (object instanceof Vector4f ) { + Vector4f v = (Vector4f)object; + this.value = v.getX() + " " + v.getY()+ " " + v.getZ()+ " " + v.getW(); + } else if (object instanceof ColorRGBA) { + ColorRGBA v = (ColorRGBA)object; + this.value = v.getRed() + " " + v.getGreen() + " " + v.getBlue() + " " + v.getAlpha(); + } else { + throw new UnsupportedOperationException(object.getClass() + " Unsupported type"); + } + + } else { + throw new UnsupportedOperationException(name + " string material parameter not supported yet"); + } + } + + + @Override + public void write(Enum value, String name, Enum defVal) throws IOException { + + + switch (name) { + case "varType": + this.varType = value.name(); + break; + case "colorSpace": + space = value == ColorSpace.Linear?"-LINEAR":null; + break; + default: + throw new UnsupportedOperationException(name + " string material parameter not supported yet"); + } + + } + + @Override + public void write(boolean value, String name, boolean defVal) throws IOException { + if(name.equals("value_bool")){ + this.value = Boolean.toString(value); + } else { + throw new UnsupportedOperationException(name + " string material parameter not supported yet"); + } + } + + @Override + public void write(float value, String name, float defVal) throws IOException { + if(name.equals("value_float")){ + this.value = Float.toString(value); + } else { + throw new UnsupportedOperationException(name + " string material parameter not supported yet"); + } + } + + @Override + public void write(int value, String name, int defVal) throws IOException { + if(name.equals("texture_unit")){ + return; + } + if(name.equals("value_int")){ + this.value = Integer.toString(value); + } else { + throw new UnsupportedOperationException(name + " string material parameter not supported yet"); + } + } +} + + diff --git a/jme3-plugins/src/main/java/com/jme3/material/plugin/export/materialdef/J3mdOutputCapsuleAdapter.java b/jme3-plugins/src/main/java/com/jme3/material/plugin/export/materialdef/J3mdOutputCapsuleAdapter.java new file mode 100644 index 000000000..c945e7f12 --- /dev/null +++ b/jme3-plugins/src/main/java/com/jme3/material/plugin/export/materialdef/J3mdOutputCapsuleAdapter.java @@ -0,0 +1,255 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.material.plugin.export.materialdef; + +import com.jme3.asset.TextureKey; +import com.jme3.export.*; +import com.jme3.material.*; +import com.jme3.math.*; +import com.jme3.shader.VarType; +import com.jme3.texture.Texture; +import com.jme3.texture.Texture.WrapMode; +import com.jme3.util.IntMap; + +import java.io.*; +import java.nio.*; +import java.util.*; + +/** + * + * @author tsr + */ +public abstract class J3mdOutputCapsuleAdapter implements OutputCapsule { + + protected final J3mdExporter exporter; + + public J3mdOutputCapsuleAdapter(J3mdExporter exporter) { + this.exporter = exporter; + } + + public void writeToStream(OutputStreamWriter out) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); + } + + protected void writeParameter(OutputStreamWriter out, String name, String value) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void clear() { + + } + + protected void putParameter(String name, String value) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void write(boolean value, String name, boolean defVal) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void writeStringSavableMap(Map map, String name, Map defVal) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); + } + + + @Override + public void write(Enum value, String name, Enum defVal) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void write(float value, String name, float defVal) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void write(float[] value, String name, float[] defVal) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void write(float[][] value, String name, float[][] defVal) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void write(double value, String name, double defVal) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void write(double[] value, String name, double[] defVal) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void write(double[][] value, String name, double[][] defVal) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void write(long value, String name, long defVal) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void write(long[] value, String name, long[] defVal) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void write(long[][] value, String name, long[][] defVal) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void write(short value, String name, short defVal) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void write(short[] value, String name, short[] defVal) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void write(short[][] value, String name, short[][] defVal) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void write(boolean[] value, String name, boolean[] defVal) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void write(boolean[][] value, String name, boolean[][] defVal) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void write(String value, String name, String defVal) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void write(String[] value, String name, String[] defVal) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void write(String[][] value, String name, String[][] defVal) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void write(BitSet value, String name, BitSet defVal) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void write(Savable object, String name, Savable defVal) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void write(Savable[] objects, String name, Savable[] defVal) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void write(Savable[][] objects, String name, Savable[][] defVal) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void writeSavableArrayList(ArrayList array, String name, ArrayList defVal) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void writeSavableArrayListArray(ArrayList[] array, String name, ArrayList[] defVal) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void writeSavableArrayListArray2D(ArrayList[][] array, String name, ArrayList[][] defVal) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void writeFloatBufferArrayList(ArrayList array, String name, ArrayList defVal) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void writeByteBufferArrayList(ArrayList array, String name, ArrayList defVal) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void writeSavableMap(Map map, String name, Map defVal) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void writeIntSavableMap(IntMap map, String name, IntMap defVal) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void write(FloatBuffer value, String name, FloatBuffer defVal) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void write(IntBuffer value, String name, IntBuffer defVal) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void write(ByteBuffer value, String name, ByteBuffer defVal) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void write(ShortBuffer value, String name, ShortBuffer defVal) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void write(byte value, String name, byte defVal) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void write(byte[] value, String name, byte[] defVal) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void write(byte[][] value, String name, byte[][] defVal) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void write(int value, String name, int defVal) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void write(int[] value, String name, int[] defVal) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void write(int[][] value, String name, int[][] defVal) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + +} diff --git a/jme3-plugins/src/test/java/com/jme3/material/plugin/TestMaterialDefWrite.java b/jme3-plugins/src/test/java/com/jme3/material/plugin/TestMaterialDefWrite.java new file mode 100644 index 000000000..e3c9cb22e --- /dev/null +++ b/jme3-plugins/src/test/java/com/jme3/material/plugin/TestMaterialDefWrite.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2009-2016 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.material.plugin; + +import com.jme3.asset.*; +import com.jme3.material.*; +import com.jme3.material.plugin.export.materialdef.J3mdExporter; +import com.jme3.material.plugins.J3MLoader; +import com.jme3.system.JmeSystem; +import org.junit.*; + +import java.io.*; + +import static org.junit.Assert.assertTrue; + +public class TestMaterialDefWrite { + + private AssetManager assetManager; + + @Before + public void init() { + assetManager = JmeSystem.newAssetManager( + TestMaterialDefWrite.class.getResource("/com/jme3/asset/Desktop.cfg")); + + + } + + + @Test + public void testWriteMat() throws Exception { + + Material mat = new Material(assetManager,"Common/MatDefs/Light/Lighting.j3md"); +// +// mat.setBoolean("UseMaterialColors", true); +// mat.setColor("Diffuse", ColorRGBA.White); +// mat.setColor("Ambient", ColorRGBA.DarkGray); +// mat.setFloat("AlphaDiscardThreshold", 0.5f); +// +// mat.setFloat("Shininess", 2.5f); +// +// Texture tex = assetManager.loadTexture("Common/Textures/MissingTexture.png"); +// tex.setMagFilter(Texture.MagFilter.Nearest); +// tex.setMinFilter(Texture.MinFilter.BilinearNoMipMaps); +// tex.setWrap(Texture.WrapAxis.S, Texture.WrapMode.Repeat); +// tex.setWrap(Texture.WrapAxis.T, Texture.WrapMode.MirroredRepeat); +// +// mat.setTexture("DiffuseMap", tex); +// mat.getAdditionalRenderState().setDepthWrite(false); +// mat.getAdditionalRenderState().setDepthTest(false); +// mat.getAdditionalRenderState().setLineWidth(5); +// mat.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha); + + final ByteArrayOutputStream stream = new ByteArrayOutputStream(); + + J3mdExporter exporter = new J3mdExporter(); + try { + exporter.save(mat.getMaterialDef(), stream); + } catch (IOException e) { + e.printStackTrace(); + } + + // System.err.println(stream.toString()); + + J3MLoader loader = new J3MLoader(); + AssetInfo info = new AssetInfo(assetManager, new AssetKey("test")) { + @Override + public InputStream openStream() { + return new ByteArrayInputStream(stream.toByteArray()); + } + }; + MaterialDef matDef = (MaterialDef)loader.load(info); + MaterialDef ref = mat.getMaterialDef(); + + for (MatParam matParam : matDef.getMaterialParams()) { + MatParam refParam = ref.getMaterialParam(matParam.getName()); + assertTrue(refParam != null); + assertTrue(refParam.equals(matParam)); + } + } + +}