Commit b35c1ba0 authored by Human Gamer's avatar Human Gamer

Highly Experimental OBJ3DIF Converter

parent f3e6b5e1
Pipeline #1789610 skipped
......@@ -16,6 +16,7 @@ import org.xml.sax.SAXException;
import com.dddviewr.collada.Collada;
import com.matt.difinspector.io.ReverseDataInputStream;
import com.matt.difinspector.io.ReverseDataOutputStream;
import com.matt.difinspector.models.OBJModel;
public class InteriorResource
{
......@@ -474,6 +475,35 @@ public class InteriorResource
return false;
}
public boolean readOBJ(File file)
{
if (!file.exists())
{
System.err.println("File '" + file.toString() + "' does not exist!");
return false;
}
try
{
OBJModel model = new OBJModel(file);
Interior interior = new Interior();
if (interior.processOBJ(model))
{
this.detailLevels.add(interior);
} else
{
return false;
}
return true;
} catch (IOException e)
{
e.printStackTrace();
}
return false;
}
public List<Interior> getDetailLevels()
{
return this.detailLevels;
......
......@@ -94,6 +94,16 @@ public class DifInspector
});
fileMenu.add(openMenu);
JMenuItem openOBJMenu = new JMenuItem("Import OBJ");
openOBJMenu.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e)
{
DifInspector.this.importOBJ();
}
});
fileMenu.add(openOBJMenu);
JMenuItem openColladaMenu = new JMenuItem("Open Collada");
openColladaMenu.addActionListener(new ActionListener() {
@Override
......@@ -381,6 +391,57 @@ public class DifInspector
Settings.saveConfig();
}
public void importOBJ()
{
JFileChooser chooser = new JFileChooser();
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
chooser.setFileFilter(new FileNameExtensionFilter("Object Model Files (.obj)", "obj"));
if (!Settings.getLastOpenDir().isEmpty())
chooser.setCurrentDirectory(new File(Settings.getLastOpenDir()));
int option = chooser.showOpenDialog(this.frame);
if (option != JFileChooser.APPROVE_OPTION)
return;
File file = chooser.getSelectedFile();
if (file != null && file.exists())
{
this.interior = new InteriorResource();
if (this.interior.readOBJ(file))
{
this.render.setInterior(this.interior);
this.surfaceEditor.setInterior(this.interior);
this.pointEditor.setInterior(this.interior);
this.planeEditor.setInterior(this.interior);
this.settings.refresh();
this.selector.refresh();
this.infoTab.update();
this.detailLevelsTab.update();
if (this.interior.getSubObjects().size() > 0)
this.subObjectsTab.update();
this.tabbedPane.setVisible(true);
this.tabbedPane.removeAll();
this.tabbedPane.addTab("General", this.infoTab);
if (this.interior.getDetailLevels().size() > 0)
this.tabbedPane.addTab("Detail Levels", this.detailLevelsTab);
if (this.interior.getSubObjects().size() > 0)
this.tabbedPane.addTab("Sub Objects", this.subObjectsTab);
} else
{
JOptionPane.showMessageDialog(this.frame, "Failed to load interior!");
}
}
String dir = chooser.getCurrentDirectory().toString();
Settings.setLastOpenDir(dir);
Settings.saveConfig();
}
public void openCollada()
{
JFileChooser chooser = new JFileChooser();
......
package com.matt.difinspector.main;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JTextField;
import com.matt.difinspector.structures.Point2I;
public class Point2IField extends JComponent
{
private static final long serialVersionUID = 4432082004476176516L;
private JLabel label;
private JTextField xField;
private JTextField yField;
private class PointActionListener implements KeyListener
{
@Override
public void keyTyped(KeyEvent e)
{
ActionEvent event = new ActionEvent(Point2IField.this, ActionEvent.ACTION_PERFORMED, "Changed");
//PointField.this.dispatchEvent();
ActionListener[] listeners = Point2IField.this.listenerList.getListeners(ActionListener.class);
for (int i = 0; i < listeners.length; i++)
{
listeners[i].actionPerformed(event);
}
}
@Override
public void keyPressed(KeyEvent e){}
@Override
public void keyReleased(KeyEvent e){}
}
public Point2IField(String label, Point2I point)
{
this.setLayout(new FlowLayout());
this.setPreferredSize(new Dimension(175, 25));
this.label = new JLabel(label);
this.xField = new JTextField("" + point.getX(), 3);
this.xField.addKeyListener(new PointActionListener());
this.yField = new JTextField("" + point.getY(), 3);
this.yField.addKeyListener(new PointActionListener());
this.add(this.label);
this.add(this.xField);
this.add(this.yField);
}
public Point2IField(Point2I point)
{
this("", point);
}
public Point2IField(String label)
{
this(label, new Point2I());
}
public Point2IField()
{
this("");
}
public void setPoint(Point2I point)
{
this.xField.setText("" + point.getX());
this.yField.setText("" + point.getY());
}
public Point2I getPoint()
{
int x;
int y;
try {
x = Integer.parseInt(this.xField.getText());
} catch (NumberFormatException e)
{
x = 0;
}
try {
y = Integer.parseInt(this.yField.getText());
} catch (NumberFormatException e)
{
y = 0;
}
return new Point2I(x, y);
}
public void addActionListener(ActionListener l) {
this.listenerList.add(ActionListener.class, l);
}
}
......@@ -17,6 +17,7 @@ import com.matt.difinspector.interior.InteriorResource;
import com.matt.difinspector.materials.TexData;
import com.matt.difinspector.structures.PlaneF;
import com.matt.difinspector.structures.Point2F;
import com.matt.difinspector.structures.Point2I;
import com.matt.difinspector.structures.Point3F;
import com.matt.difinspector.structures.Surface;
import com.matt.difinspector.structures.TexGenPlanes;
......@@ -49,16 +50,29 @@ public class SurfaceEditor extends JFrame
private int surfaceId;
private JCheckBox surfaceFlipped;
private Point2IField mapOffset;
private Point2IField mapSize;
private JPanel mapPanel;
public SurfaceEditor()
{
this.setTitle("Surface Editor");
this.setSize(200, 240);
this.setSize(200, 320);
this.setResizable(false);
this.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
this.panel = new JPanel();
this.texturePanel = new JPanel();
this.mapOffset = new Point2IField("Map Offset");
this.mapSize = new Point2IField("Map Size");
this.mapPanel = new JPanel();
this.mapPanel.setPreferredSize(new Dimension(200, 75));
this.mapPanel.add(this.mapOffset);
this.mapPanel.add(this.mapSize);
// this.surfaceSelection = new JComboBox<String>();
// this.surfaceSelection.setPreferredSize(new Dimension(290, 25));
......@@ -119,6 +133,7 @@ public class SurfaceEditor extends JFrame
this.setLayout(new FlowLayout());
this.add(this.panel);
this.add(this.texturePanel);
this.add(this.mapPanel);
this.add(this.surfaceFlipped);
this.add(this.applyButton);
......@@ -170,6 +185,9 @@ public class SurfaceEditor extends JFrame
/*
* } catch (NumberFormatException e) { e.printStackTrace(); } }
*/
this.mapOffset.setPoint(new Point2I(surface.getMapOffsetX(), surface.getMapOffsetY()));
this.mapSize.setPoint(new Point2I(surface.getMapSizeX(), surface.getMapSizeY()));
}
/*
......@@ -229,6 +247,14 @@ public class SurfaceEditor extends JFrame
surface.flip();
}
Point2I offset = this.mapOffset.getPoint();
surface.setMapOffsetX(offset.getX());
surface.setMapOffsetY(offset.getY());
Point2I size = this.mapSize.getPoint();
surface.setMapSizeX(size.getX());
surface.setMapSizeY(size.getY());
/*
* } catch (NumberFormatException e) { e.printStackTrace(); } }
*/
......
package com.matt.difinspector.models;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import com.matt.difinspector.structures.Point2F;
import com.matt.difinspector.structures.Point3F;
public class OBJModel
{
protected File file;
protected List<Point3F> positions;
protected List<Point2F> texCoords;
protected List<Point3F> normals;
protected List<OBJIndex> indices;
protected boolean hasTexCoords;
protected boolean hasNormals;
public OBJModel(File file) throws IOException
{
this.file = file;
this.positions = new ArrayList<Point3F>();
this.texCoords = new ArrayList<Point2F>();
this.normals = new ArrayList<Point3F>();
this.indices = new ArrayList<OBJIndex>();
this.hasTexCoords = false;
this.hasNormals = false;
BufferedReader meshReader = new BufferedReader(new FileReader(file));
String line;
while((line = meshReader.readLine()) != null)
{
String[] tokens = line.split(" ");
if (tokens.length == 0 || tokens[0].equals("#"))
continue;
else if (tokens[0].equals("v"))
{
this.positions.add(new Point3F(Float.valueOf(tokens[1]), Float.valueOf(tokens[2]), Float.valueOf(tokens[3])));
} else if (tokens[0].equals("vt"))
{
float token1;
float token2;
if (tokens[1].equalsIgnoreCase("nan") || tokens[1].isEmpty())
token1 = Float.NaN;
else
token1 = Float.valueOf(tokens[1]);
if (tokens[2].equalsIgnoreCase("nan") || tokens[1].isEmpty())
token2 = Float.NaN;
else
token2 = Float.valueOf(tokens[2]);
this.texCoords.add(new Point2F(token1, 1.0f - token2));
} else if (tokens[0].equals("vn"))
{
this.normals.add(new Point3F(Float.valueOf(tokens[1]), Float.valueOf(tokens[2]), Float.valueOf(tokens[3])));
} else if (tokens[0].equals("f"))
{
for (int i = 0; i < tokens.length - 3; i++)
{
this.indices.add(parseOBJIndex(tokens[1]));
this.indices.add(parseOBJIndex(tokens[2 + i]));
this.indices.add(parseOBJIndex(tokens[3 + i]));
}
}
}
meshReader.close();
}
private OBJIndex parseOBJIndex(String token)
{
String[] values = token.split("/");
OBJIndex result = new OBJIndex();
result.setVertexIndex(Integer.parseInt(values[0]) - 1);
if (values.length > 1)
{
if (!values[1].isEmpty())
{
this.hasTexCoords = true;
result.setTexCoordIndex(Integer.parseInt(values[1]) - 1);
}
if (values.length > 2)
{
this.hasNormals = true;
result.setNormalIndex(Integer.parseInt(values[2]) - 1);
}
}
return result;
}
public static class OBJIndex
{
protected int vertexIndex;
protected int texCoordIndex;
protected int normalIndex;
public OBJIndex()
{
}
public int getVertexIndex()
{
return vertexIndex;
}
public void setVertexIndex(int vertexIndex)
{
this.vertexIndex = vertexIndex;
}
public int getTexCoordIndex()
{
return texCoordIndex;
}
public void setTexCoordIndex(int texCoordIndex)
{
this.texCoordIndex = texCoordIndex;
}
public int getNormalIndex()
{
return normalIndex;
}
public void setNormalIndex(int normalIndex)
{
this.normalIndex = normalIndex;
}
}
public List<Point3F> getPositions()
{
return positions;
}
public void setPositions(List<Point3F> positions)
{
this.positions = positions;
}
public List<Point2F> getTexCoords()
{
return texCoords;
}
public void setTexCoords(List<Point2F> texCoords)
{
this.texCoords = texCoords;
}
public List<Point3F> getNormals()
{
return normals;
}
public void setNormals(List<Point3F> normals)
{
this.normals = normals;
}
public List<OBJIndex> getIndices()
{
return indices;
}
public void setIndices(List<OBJIndex> indices)
{
this.indices = indices;
}
public boolean hasTexCoords()
{
return hasTexCoords;
}
public void setHasTexCoords(boolean hasTexCoords)
{
this.hasTexCoords = hasTexCoords;
}
public boolean hasNormals()
{
return hasNormals;
}
public void setHasNormals(boolean hasNormals)
{
this.hasNormals = hasNormals;
}
}
/*package com.matt.difinspector.models;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import com.matt.difinspector.structures.Point2F;
import com.matt.difinspector.structures.Point3F;
import com.matt.difinspector.structures.Point3I;
public class OBJModel
{
protected File file;
protected String materialFile;
protected List<Point3F> vertices;
protected List<Point2F> vertexTextures;
protected List<OBJMesh> meshes;
public OBJModel(File file) throws IOException
{
this.file = file;
this.vertices = new ArrayList<Point3F>();
this.vertexTextures = new ArrayList<Point2F>();
this.meshes = new ArrayList<OBJMesh>();
this.readOBJ();
}
private void readOBJ() throws IOException
{
FileInputStream fis = new FileInputStream(this.file);
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
String line;
String group = null;
String usemtl = null;
OBJMesh currentMesh = new OBJMesh("obj");
this.meshes.add(currentMesh);
while ((line = br.readLine()) != null)
{
// Remove Extra White Space
line = line.trim();
// Comments
if (line.startsWith("#"))
continue;
line = line.replace(" ", " ");
String[] ln = line.split(" ");
if (ln.length <= 0)
continue;
if (ln[0].equals("mtllib") && ln.length >= 2)
{
this.materialFile = ln[1];
}
if(ln[0].equals("v") && ln.length >= 4)
{
float x = Float.parseFloat(ln[1]);
float y = Float.parseFloat(ln[2]);
float z = Float.parseFloat(ln[3]);
Point3F v = new Point3F(x, y, z);
this.vertices.add(v);
}
if(ln[0].equals("vt") && ln.length >= 3)
{
float x;
if(ln[1].equalsIgnoreCase("nan"))
x = Float.NaN;
else
x = Float.parseFloat(ln[1]);
float y;
if(ln[2].equalsIgnoreCase("nan"))
y = Float.NaN;
else
y = Float.parseFloat(ln[2]);
Point2F uv = new Point2F(x, y);
this.vertexTextures.add(uv);
}
if(ln[0].equals("s") && ln.length >= 1)
{
System.out.println("Smoothing Group: " + ln[1]);
}
if(ln[0].equals("g") && ln.length >= 2)
{
group = ln[1];
if (currentMesh.faces.size() > 0)
{
currentMesh = new OBJMesh(group);
this.meshes.add(currentMesh);
}
}
if (ln[0].equals("usemtl") && ln.length >= 2)
{
usemtl = ln[1];
//System.out.println(usemtl);
}
if (ln[0].equals("f") && ln.length >= 3)
{
String[] xx = ln[1].split("/");
String[] yy = ln[2].split("/");
String[] zz = ln[3].split("/");
int xIndex = Integer.parseInt(xx[0]);
int yIndex = Integer.parseInt(yy[0]);
int zIndex = Integer.parseInt(zz[0]);
int textureXIndex = 0;
int textureYIndex = 0;
int textureZIndex = 0;
if (xx.length > 1)
textureXIndex = Integer.parseInt(xx[1]);
if (yy.length > 1)
textureYIndex = Integer.parseInt(yy[1]);
if (zz.length > 1)
textureZIndex = Integer.parseInt(zz[1]);
Point3I vertIndex = new Point3I(xIndex, yIndex, zIndex);
Point3I textureIndex = new Point3I(textureXIndex, textureYIndex, textureZIndex);
OBJFace index = new OBJFace(vertIndex, textureIndex, usemtl);
currentMesh.addFace(index);
}
}
br.close();
}
public static class OBJMesh
{
protected List<OBJFace> faces;
protected String name;
public OBJMesh(String name)
{
this.name = name;
this.faces = new ArrayList<OBJFace>();
}
public void addFace(OBJFace face)
{
this.faces.add(face);
}
public List<OBJFace> getFaces()
{
return this.faces;
}
}
public static class OBJFace
{
protected Point3I vertexIndex;
protected Point3I textureIndex;
protected String material;
public OBJFace(Point3I vertexIndex, Point3I textureIndex, String material)
{
this.vertexIndex = vertexIndex;
this.textureIndex = textureIndex;
this.material = material;
}
public Point3I getVertexIndex()
{
return vertexIndex;
}
public void setVertexIndex(Point3I vertexIndex)
{
this.vertexIndex = vertexIndex;
}
public Point3I getTextureIndex()
{
return textureIndex;
}
public void setTextureIndex(Point3I textureIndex)
{
this.textureIndex = textureIndex;
}
public String getMaterial()