Search in sources :

Example 1 with Vector4d

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));
    }
}
Also used : HashMap(java.util.HashMap) Vector4d(javax.vecmath.Vector4d) ObjDump(org.twak.utils.geom.ObjDump) CountThings(org.twak.utils.collections.CountThings) HashSet(java.util.HashSet) XStream(com.thoughtworks.xstream.XStream) Matrix4d(javax.vecmath.Matrix4d) FileOutputStream(java.io.FileOutputStream) File(java.io.File)

Example 2 with Vector4d

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 };
}
Also used : Vector4d(javax.vecmath.Vector4d)

Aggregations

Vector4d (javax.vecmath.Vector4d)2 XStream (com.thoughtworks.xstream.XStream)1 File (java.io.File)1 FileOutputStream (java.io.FileOutputStream)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 Matrix4d (javax.vecmath.Matrix4d)1 CountThings (org.twak.utils.collections.CountThings)1 ObjDump (org.twak.utils.geom.ObjDump)1