Commit 50b42e45 by Matthieu Parizeau

Added UV Import support for OBJ Models (WIP).

Materials Tab now displays (why was it commented out?). Moved scale options into main class for an easier override later.
parent 18a124ec
File added
<?xml version="1.0" encoding="UTF-8"?>
<launch4jConfig>
<dontWrapJar>false</dontWrapJar>
<headerType>gui</headerType>
<jar>E:\Data\Documents\difinspector.jar</jar>
<outfile>E:\Data\Documents\difinspector.exe</outfile>
<errTitle></errTitle>
<cmdLine></cmdLine>
<chdir>.</chdir>
<priority>normal</priority>
<downloadUrl>http://java.com/download</downloadUrl>
<supportUrl></supportUrl>
<stayAlive>false</stayAlive>
<restartOnCrash>false</restartOnCrash>
<manifest></manifest>
<icon>E:\Repositories\dif-inspector\icon.ico</icon>
<classPath>
<mainClass>com.matt.difinspector.main.DifInspector</mainClass>
<cp>lib/slick-util.jar</cp>
<cp>lib/lwjgl/jinput.jar</cp>
<cp>lib/lwjgl/lwjgl.jar</cp>
<cp>lib/lwjgl/lwjgl_util.jar</cp>
</classPath>
<jre>
<path></path>
<bundledJre64Bit>false</bundledJre64Bit>
<bundledJreAsFallback>false</bundledJreAsFallback>
<minVersion>1.8.0</minVersion>
<maxVersion></maxVersion>
<jdkPreference>preferJre</jdkPreference>
<runtimeBits>64/32</runtimeBits>
</jre>
</launch4jConfig>
\ No newline at end of file
......@@ -486,7 +486,7 @@ public class InteriorResource
return false;
}
public boolean readOBJ(File file)
public boolean readOBJ(File file, float scale)
{
if (!file.exists())
{
......@@ -501,7 +501,7 @@ public class InteriorResource
inspector.displayProgress("Importing OBJ File", 0);
System.out.println("Importing OBJ File");
OBJModel model = new OBJModel(file);
OBJModel model = new OBJModel(file, scale);
System.out.println("Converting To Interior");
InteriorBuilder ib = new InteriorBuilder("tile_advanced");
......
......@@ -70,7 +70,7 @@ public class DetailLevelsTab extends JPanel
public void addPanels()
{
//this.panels.put("Materials", new MaterialsPanel());
this.panels.put("Materials", new MaterialsPanel());
this.panels.put("Edges", new EdgesPanel());
this.panels.put("Surfaces", new SurfacesPanel());
this.panels.put("Points", new PointsPanel());
......
......@@ -68,6 +68,8 @@ public class DifInspector
private Selector selector;
private ProgressDialog progressDialog;
private float objScale = 0.01f;
public DifInspector()
{
......@@ -478,7 +480,7 @@ public class DifInspector
public void run()
{
DifInspector.this.interior = new InteriorResource();
if (DifInspector.this.interior.readOBJ(file))
if (DifInspector.this.interior.readOBJ(file, objScale))
{
DifInspector.this.processInterior();
} else
......@@ -854,7 +856,7 @@ public class DifInspector
public void run()
{
InteriorResource res = new InteriorResource();
if (res.readOBJ(file))
if (res.readOBJ(file, objScale))
{
String p = file.toString();
p = p.replace(".obj", ".dif");
......
......@@ -188,6 +188,50 @@ public class MatrixF
this.m[x][y] = value;
}
public void swapRows(int row1, int row2)
{
float p1x = this.m[row1][0];
float p1y = this.m[row1][1];
float p1z = this.m[row1][2];
float p1w = this.m[row1][3];
float p2x = this.m[row2][0];
float p2y = this.m[row2][1];
float p2z = this.m[row2][2];
float p2w = this.m[row2][3];
this.m[row1][0] = p2x;
this.m[row1][1] = p2y;
this.m[row1][2] = p2z;
this.m[row1][3] = p2w;
this.m[row2][0] = p1x;
this.m[row2][1] = p1y;
this.m[row2][2] = p1z;
this.m[row2][3] = p1w;
}
public void addRow(int destRow, int srcRow, float factor)
{
this.m[destRow][0] += this.m[srcRow][0] * factor;
this.m[destRow][1] += this.m[srcRow][1] * factor;
this.m[destRow][2] += this.m[srcRow][2] * factor;
this.m[destRow][3] += this.m[srcRow][3] * factor;
}
public void scaleRow(int row, float scale)
{
this.m[row][0] *= scale;
this.m[row][1] *= scale;
this.m[row][2] *= scale;
this.m[row][3] *= scale;
}
public MatrixF copy()
{
return new MatrixF(m.clone());
}
/*@Override
public String toString()
{
......
......@@ -123,7 +123,7 @@ public class InteriorBuilder
for (int i = 0; i < texCoords.sizeIndices(); i ++)
{
if (i >= texCoords.sizeIndices())
if (i + 2 >= texCoords.sizeIndices())
{
System.out.println("Extra UV?");
int dif = i - texCoords.sizeIndices();
......@@ -131,17 +131,19 @@ public class InteriorBuilder
texGenEQs.add(lastTexGen);
break;
}
/*Point2F uv0 = texCoords.getObject(i+0);
Point2F uv0 = texCoords.getObject(i+0);
Point2F uv1 = texCoords.getObject(i+1);
Point2F uv2 = texCoords.getObject(i+2);
Point3F point0 = vertices.getObject(i+0);
Point3F point1 = vertices.getObject(i+1);
Point3F point2 = vertices.getObject(i+2);*/
Point3F point2 = vertices.getObject(i+2);
Point3F normal = normals.getObject(i);
String texture = mesh.getTextures()[textureIndices[i]];
Point2F offset = new Point2F(0, 0);
// old uv stuff
/*Point2F offset = new Point2F(0, 0);
Point2F scale = new Point2F(0.25f, 0.25f);
float rotation = 0;
if (texture.equalsIgnoreCase("edge_white") || texture.equalsIgnoreCase("edge_white_mbm"))
......@@ -152,12 +154,14 @@ public class InteriorBuilder
rotation = 45;
if (texture.equalsIgnoreCase("beam"))
rotation = 90;
//offset = new Point2F(2, 0);
TexData texData = new TexData(normal, offset, rotation, scale);
ImageData imageData = images.get(texture);
TexGenPlanes texGenPlanes = new TexGenPlanes();
if (imageData != null)
texGenPlanes = Util.getTexGen(texData, imageData);
//offset = new Point2F(2, 0);*/
//TexData texData = new TexData(normal, offset, rotation, scale);
//ImageData imageData = images.get(texture);
//TexGenPlanes texGenPlanes = new TexGenPlanes();
//if (imageData != null)
TexGenPlanes texGenPlanes = Util.getTexGen(point0, point1, point2, uv0, uv1, uv2);
//texGenPlanes = Util.getTexGen(texData, imageData);
//TexGenPlanes texGenPlanes = Util.getTexGen(point0, point1, point2, uv0, uv1, uv2); //new TexGenPlanes(normal, point, uv);
lastTexGen = texGenPlanes;
texGenEQs.add(texGenPlanes);
......
......@@ -21,7 +21,7 @@ public class OBJModel
protected boolean hasTexCoords;
protected boolean hasNormals;
public OBJModel(File file) throws IOException
public OBJModel(File file, float scale) throws IOException
{
this.file = file;
this.positions = new ArrayList<Point3F>();
......@@ -39,7 +39,7 @@ public class OBJModel
while((line = meshReader.readLine()) != null)
{
String[] tokens = line.split(" ");
String[] tokens = line.trim().split(" +");
//System.out.println(Util.getArrayString(tokens));
if (tokens.length == 0 || tokens[0].equals("#"))
......@@ -100,8 +100,9 @@ public class OBJModel
{
Point3F pos = this.positions.get(i);
pos = pos.mul(scale);
//pos = pos.mul(0.01f); // Blender + 100 scale
pos = pos.mul(0.001f); // Sketchup
//pos = pos.mul(0.001f); // Sketchup
//pos = pos.rotate(new Point3F(0, 1, 0), (float)Math.toRadians(90));
pos = pos.rotate(new Point3F(0, 0, 1), (float)Math.toRadians(180));
......
......@@ -11,6 +11,7 @@ import org.lwjgl.BufferUtils;
import com.matt.difinspector.materials.TexData;
import com.matt.difinspector.materials.TorqueMaterial;
import com.matt.difinspector.math.MatrixF;
import com.matt.difinspector.math.PlaneF;
import com.matt.difinspector.math.Point2F;
import com.matt.difinspector.math.Point3F;
......@@ -563,7 +564,7 @@ public final class Util
return new TexData(normal, offset, rotate, scale);
}
public static Point3F solveSystem(float a, float b, float c, float d, float e, float f, float g, float h, float i, float j, float k, float l)
/*public static Point3F solveSystem(float a, float b, float c, float d, float e, float f, float g, float h, float i, float j, float k, float l)
{
float zTop = (l - (i * d / a)) - (((j - (i * b / a)) * (h - (e * d / a))) / (f - (e * b / a)));
float zBot = (((j - (i * b / a )) * ((e * c / a) - g)) / (f - (e * b / a))) + (k - (i * c / a));
......@@ -573,12 +574,248 @@ public final class Util
float x = (d - (b * y) - (c * z)) / a;
return new Point3F(x, y, z);
}*/
public static boolean closeEnough(float p0, float p1, float distance)
{
return Math.abs(p0 - p1) < distance;
}
public static boolean closeEnough(float p0, float p1)
{
return closeEnough(p0, p1, 0.0001f);
}
public static Point3F solveMatrix(MatrixF pointMatrix)
{
MatrixF m = pointMatrix.copy();
//Clean up stuff that is almost zero
if (closeEnough(m.get(0, 0), 0.0f)) m.set(0, 0, 0.0f);
if (closeEnough(m.get(1, 0), 0.0f)) m.set(1, 0, 0.0f);
if (closeEnough(m.get(2, 0), 0.0f)) m.set(2, 0, 0.0f);
if (closeEnough(m.get(0, 1), 0.0f)) m.set(0, 1, 0.0f);
if (closeEnough(m.get(1, 1), 0.0f)) m.set(1, 1, 0.0f);
if (closeEnough(m.get(2, 1), 0.0f)) m.set(2, 1, 0.0f);
if (closeEnough(m.get(0, 2), 0.0f)) m.set(0, 2, 0.0f);
if (closeEnough(m.get(1, 2), 0.0f)) m.set(1, 2, 0.0f);
if (closeEnough(m.get(2, 2), 0.0f)) m.set(2, 2, 0.0f);
if (closeEnough(m.get(0, 3), 0.0f)) m.set(0, 3, 0.0f);
if (closeEnough(m.get(1, 3), 0.0f)) m.set(1, 3, 0.0f);
if (closeEnough(m.get(2, 3), 0.0f)) m.set(2, 3, 0.0f);
//For checking at the end
MatrixF test = m.copy();
/*
We have three simultaneous equations:
ax + by + cz = uv0
dx + ey + fz = uv1
gx + hy + iz = uv2
We can arrange them in a matrix like this:
[ a b c ] ( x ) ( uv0 )
[ d e f ] x ( y ) = ( uv1 )
[ g h i ] ( z ) ( uv2 )
And then if we can get the matrix into reduced echelon form we can solve
for (x y z) with no trouble.
*/
//Swap around rows so that we can get something non-zero for [0][0]
if (closeEnough(m.get(0, 0), 0.0f))
{
if (closeEnough(m.get(1, 0), 0.0f))
{
m.swapRows(0, 2);
} else {
m.swapRows(0, 1);
}
}
//If all three have zero for [0][0] then we're fine here
if (!closeEnough(m.get(0, 0), 0.0f))
{
/*
Reduce second and third rows so the first column is zero
To get
[ a b c ]
[ 0 d e ]
[ 0 f g ]
*/
if (!closeEnough(m.get(1, 0), 0.0f))
{
m.addRow(1, 0, -m.get(1, 0) / m.get(0, 0));
}
if (!closeEnough(m.get(2, 0), 0.0f))
{
m.addRow(2, 0, -m.get(2, 0) / m.get(0, 0));
}
}
//If mat[1][1] is zero we should swap rows 1 and 2 so we can reduce the other row
if (closeEnough(m.get(1, 1), 0.0f))
{
m.swapRows(1, 2);
}
//If mat[1][1] is zero then both [1][1] and [2][1] are zero and we can continue
if (!closeEnough(m.get(1, 1), 0.0f))
{
/*
Reverse third row so the second column is zero
To get
[ a b c ]
[ 0 d e ]
[ 0 0 f ]
*/
if (!closeEnough(m.get(2, 1), 0.0f))
{
m.addRow(2, 1, -m.get(2, 1) / m.get(1, 1));
}
}
/*
Scale each of the rows so the first component is one
To get
[ 1 a b ]
[ 0 1 c ]
[ 0 0 1 ]
*/
if (!closeEnough(m.get(0, 0), 0.0f, 0.00001f))
{
m.scaleRow(0, 1.0f / m.get(0, 0));
}
if (!closeEnough(m.get(1, 1), 0.0f, 0.00001f))
{
m.scaleRow(1, 1.0f / m.get(1, 1));
}
if (!closeEnough(m.get(2, 2), 0.0f, 0.00001f))
{
m.scaleRow(2, 1.0f / m.get(2, 2));
}
/*
At this point the matrix is
[ 1 a b ] ( x ) ( uv0' )
[ 0 1 c ] x ( y ) = ( uv1' )
[ 0 0 1 ] ( z ) ( uv2' )
where
x + ay + bz = uv0
y + cz = uv1
z = uv2
therefore
z = uv2'
y = uv1' - cz
x = uv0' - ay - bz
*/
//Convenience
float[] xvec = m.getM()[0];
float[] yvec = m.getM()[1];
float[] zvec = m.getM()[2];
//These are easy now
float z = zvec[3];
float y = yvec[3] - z * yvec[2];
float x = xvec[3] - y * xvec[1] - z * xvec[2];
//Check our work
if (!closeEnough(x * test.get(0, 0) + y * test.get(0, 1) + z * test.get(0, 2), test.get(0, 3)))
{
System.err.println("Invalid X: (" + x + ", " + y + ", " + z + ")");
}
if (!closeEnough(x * test.get(1, 0) + y * test.get(1, 1) + z * test.get(1, 2), test.get(1, 3)))
{
System.err.println("Invalid Y: (" + x + ", " + y + ", " + z + ")");
}
if (!closeEnough(x * test.get(2, 0) + y * test.get(2, 1) + z * test.get(2, 2), test.get(2, 3)))
{
System.err.println("Invalid Z: (" + x + ", " + y + ", " + z + ") :: " + (x * test.get(2, 0) + y * test.get(2, 1) + z * test.get(2, 2)) + " :: " + test.get(2, 3));
}
//And there we go
return new Point3F(x, y, z);
}
// Thanks to HiGuy
public static TexGenPlanes getTexGen(Point3F point0, Point3F point1, Point3F point2, Point2F uv0, Point2F uv1, Point2F uv2)
{
TexGenPlanes planes = new TexGenPlanes();
//Construct these matrices for the solver to figure out
MatrixF xTexMat = new MatrixF(new float[][] {
new float[] {
point0.getX(), point0.getY(), point0.getZ(), uv0.getX()
},
new float[] {
point1.getX(), point1.getY(), point1.getZ(), uv1.getX()
},
new float[] {
point2.getX(), point2.getY(), point2.getZ(), uv2.getX()
},
new float[] {
0.0f, 0.0f, 0.0f, 0.0f
}
});
MatrixF yTexMat = new MatrixF(new float[][] {
new float[] {
point0.getX(), point0.getY(), point0.getZ(), uv0.getY()
},
new float[] {
point1.getX(), point1.getY(), point1.getZ(), uv1.getY()
},
new float[] {
point2.getX(), point2.getY(), point2.getZ(), uv2.getY()
},
new float[] {
0.0f, 0.0f, 0.0f, 0.0f
}
});
//Solving is rather simple
Point3F xsolve = solveMatrix(xTexMat);
Point3F ysolve = solveMatrix(yTexMat);
//Rigorous checking because I don't like being wrong
/*if (!closeEnough(xsolve.getX() * point0.getX() + xsolve.getY() * point0.getY() + xsolve.getZ() * point0.getZ(), uv0.getX(), 0.001f)) {
solveMatrix(xTexMat);
}
if (!closeEnough(xsolve.getX() * point1.getX() + xsolve.getY() * point1.getY() + xsolve.getZ() * point1.getZ(), uv1.getX(), 0.001f)) {
solveMatrix(xTexMat);
}
if (!closeEnough(xsolve.getX() * point2.getX() + xsolve.getY() * point2.getY() + xsolve.getZ() * point2.getZ(), uv2.getX(), 0.001f)) {
solveMatrix(xTexMat);
}
if (!closeEnough(xsolve.getX() * point0.getX() + xsolve.getY() * point0.getY() + xsolve.getZ() * point0.getZ(), uv0.getY(), 0.001f)) {
solveMatrix(yTexMat);
}
if (!closeEnough(xsolve.getX() * point1.getX() + xsolve.getY() * point1.getY() + xsolve.getZ() * point1.getZ(), uv1.getY(), 0.001f)) {
solveMatrix(yTexMat);
}
if (!closeEnough(xsolve.getX() * point2.getX() + xsolve.getY() * point2.getY() + xsolve.getZ() * point2.getZ(), uv2.getY(), 0.001f)) {
solveMatrix(yTexMat);
}*/
//And there we go
planes.getPlaneX().setX(xsolve.getX());
planes.getPlaneX().setY(xsolve.getY());
planes.getPlaneX().setZ(xsolve.getZ());
planes.getPlaneY().setX(ysolve.getX());
planes.getPlaneY().setY(ysolve.getY());
planes.getPlaneY().setZ(ysolve.getZ());
return planes;
}
/*public static TexGenPlanes getTexGen(Point3F point0, Point3F point1, Point3F point2, Point2F uv0, Point2F uv1, Point2F uv2)
{
TexGenPlanes planes = new TexGenPlanes();
float min = uv0.getX();
if (uv0.getY() < min) min = uv0.getY();
if (uv1.getX() < min) min = uv1.getX();
......@@ -608,7 +845,7 @@ public final class Util
planes.getPlaneY().setZ(ysolve.getZ());
return planes;
}
}*/
public static int[][] generateMipmapData(int level, int width, int[][] data)
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment