use of javax.vecmath.Vector4d in project chordatlas by twak.
the class ReadTrace method postProcessFrames.
private void postProcessFrames() throws Throwable {
ObjDump out = new ObjDump();
// start with data most likely to be loaded
Collections.reverse(frames);
double[] tmp = new double[4];
for (Frame f : frames) {
// filter out large tiles
CountThings<Double> lengths = new CountThings<>();
for (FrameGeometry fg : f) {
for (int i = 0; i < 3; i++) {
fg.viewMatrix.getColumn(i, tmp);
lengths.count((double) Math.round(new Vector4d(tmp).length() * 20) / 20);
}
}
// we assume the most popular tile size is the smallest (and that they've loaded)
double targetLength = lengths.getMax().first();
double t = 0.01 / targetLength;
Matrix4d scale = new Matrix4d(t, 0, 0, 0, 0, t, 0, 0, 0, 0, t, 0, 0, 0, 0, t);
Iterator<FrameGeometry> fig = f.iterator();
fig: while (fig.hasNext()) {
FrameGeometry fg = fig.next();
for (int i = 0; i < 3; i++) {
fg.viewMatrix.getColumn(i, tmp);
if (new Vector4d(tmp).lengthSquared() > (targetLength * targetLength * 1.01)) {
// remove non-smallest tile size
fig.remove();
continue fig;
}
}
fg.viewMatrix.mul(scale);
// y-up!
swapRows(fg.viewMatrix, 0, 1);
swapRows(fg.viewMatrix, 0, 2);
fg.viewMatrix.m33 = 1;
}
}
Matrix4d frameTransform = new Matrix4d();
frameTransform.setIdentity();
Map<String, Matrix4d> knownVerts = new HashMap<>();
Iterator<Frame> fit = frames.iterator();
while (fit.hasNext()) if (fit.next().size() < 50) {
System.out.println("warning: removing small frame");
fit.remove();
}
fit = frames.iterator();
while (fit.hasNext()) {
Frame f = fit.next();
Set<Matrix4d> mats = new HashSet<>();
for (FrameGeometry fg : f) {
if (knownVerts.containsKey(fg.loc)) {
Matrix4d toFrame = new Matrix4d(fg.viewMatrix);
toFrame.invert();
toFrame.mul(knownVerts.get(fg.loc));
mats.add(toFrame);
// frameTransform = new Matrix4d( fg.viewMatrix );
// frameTransform.invert();
// frameTransform.mul( knownVerts.get( fg.loc ) );
//
// break;
// frameTransform = toFrame;
}
}
if (!mats.isEmpty())
frameTransform = average(mats);
if (frameTransform != null) {
// apply found transform to all within same frame
Iterator<FrameGeometry> fig = f.iterator();
while (fig.hasNext()) {
FrameGeometry fg = fig.next();
if (knownVerts.containsKey(fg.loc)) {
fig.remove();
} else {
fg.viewMatrix.mul(frameTransform);
knownVerts.put(fg.loc, fg.viewMatrix);
}
}
} else {
System.out.println("failed to find origin for frame");
fit.remove();
}
frameTransform = null;
}
int count = 0, c2 = 0;
MiniTransform miniTransform = new MiniTransform();
for (Frame f : frames) {
// write out the frames into a single file
System.out.println("post-processing " + count++ + "/" + frames.size());
for (FrameGeometry fg : f) {
File miniFrameFolder = null;
File outFolder = folder;
Matrix4d meshTransform = fg.viewMatrix;
if (miniMesh != null) {
// if we're writing out in the miniMesh format
out = new ObjDump();
miniFrameFolder = new File(miniMesh, c2 + "");
miniFrameFolder.mkdirs();
miniTransform.index.put(c2, fg.viewMatrix);
outFolder = miniFrameFolder;
meshTransform = new Matrix4d();
meshTransform.setIdentity();
}
int[] ind = BitTwiddle.byteToUShort(getBytes(fg.ind));
if (ind == null) {
System.out.println("*** missing index buffer " + fg.ind);
continue;
}
byte[] vtLocBytes = getBytes(fg.loc);
if (vtLocBytes == null)
continue;
int[][] vtLoc = BitTwiddle.byteToUByte(vtLocBytes, 4, (int) fg.iVals[VERTEX_BUFFER_OFFSET], (int) fg.iVals[VERTEX_BUFFER_STRIDE]);
byte[] uvBytes = Files.readAllBytes(new File(folder, fg.uvs).toPath());
int[][] uvLoc = BitTwiddle.byteToUShort(uvBytes, 2, (int) fg.iVals[UV_BUFFER_OFFSET], (int) fg.iVals[UV_BUFFER_STRIDE]);
out.setCurrentTexture("" + c2++, 512, 512);
Tex tex = fg.tex;
File texFile = null;
if (tex != null && (texFile = new File(folder, tex.filename)).exists()) {
File mat = DTX1.toPNG(Files.readAllBytes(texFile.toPath()), outFolder, tex.width, tex.height);
out.setCurrentTexture(mat.getName(), tex.width, tex.height);
} else {
out.setCurrentTexture("missing_" + c2, 1, 1);
System.err.println("missing texture!" + c2);
}
for (int i = 2; i < fg.iVals[TRI_COUNT]; i++) {
// GL_TRIANGLES
int a = ind[i], b = ind[i - (i % 2 == 0 ? 2 : 1)], c = ind[i - (i % 2 == 0 ? 1 : 2)];
if (a != b && b != c && c != a && // google viewer magically hides some verts
isMagic8Visible(fg.magic8, vtLoc[a][3]) && isMagic8Visible(fg.magic8, vtLoc[b][3]) && isMagic8Visible(fg.magic8, vtLoc[c][3]) && // removes the tabs from the edges and centers of tiles (much easier before transform)
!isTab(vtLoc[a], vtLoc[b], vtLoc[c])) {
float[][] pos = new float[][] { locTrans(vtLoc[a], meshTransform), locTrans(vtLoc[b], meshTransform), locTrans(vtLoc[c], meshTransform) };
out.addFace(pos, new float[][] { uvMunge(uvLoc[a][0], uvLoc[a][1], tex, fg.fVals), uvMunge(uvLoc[b][0], uvLoc[b][1], tex, fg.fVals), uvMunge(uvLoc[c][0], uvLoc[c][1], tex, fg.fVals) }, findNormals(pos));
}
}
if (miniMesh != null) {
// out.writeMtlFile = false;
out.dump(new File(miniFrameFolder, "model.obj"));
}
}
}
if (miniMesh == null)
out.dump(new File(folder, "model.obj"));
else {
File f = new File(miniMesh, "index.xml");
f.getParentFile().mkdirs();
new XStream().toXML(miniTransform, new FileOutputStream(f));
}
}
use of javax.vecmath.Vector4d in project chordatlas by twak.
the class ReadTrace method locTrans.
private float[] locTrans(int[] fs, Matrix4d viewMatrix) {
Vector4d loc = new Vector4d(Math.floor((fs[0]) + 0.5), Math.floor((fs[1]) + 0.5), Math.floor((fs[2]) + 0.5), 1);
viewMatrix.transform(loc);
return new float[] { (float) loc.x, (float) loc.y, (float) loc.z };
}
Aggregations