Search in sources :

Example 6 with Matrix4d

use of javax.vecmath.Matrix4d in project chordatlas by twak.

the class GreebleCGA method cga.

protected double cga(Loop<Point2d> rect, Matrix4d to3d, WallTag wallTag, MeshBuilder normalWall, MeshBuilder ground, Cache<float[], MeshBuilder> mbs, List<DRectangle> occlusions) {
    double[] bounds = Loopz.minMax2d(rect);
    GreebleGrid gg = new GreebleGrid(tweed, new MMeshBuilderCache());
    DRectangle all = new DRectangle(bounds[0], bounds[2], bounds[1] - bounds[0], bounds[3] - bounds[2]);
    // for (DRectangle d : occlusions)
    // mbs.get( new float[] {1,1,0,1} ).add( d, to3d );
    float[] windowColor = new float[] { 0.8f, .8f, 0.8f, 1 }, glassColor = new float[] { 0.3f, 0.3f, 1, 1 }, mouldingColor = new float[] { 0.7f, .7f, 0.7f, 1 };
    double groundFloorHeight = 0;
    List<DRectangle> floors = all.splitY(r -> splitFloors(r, 3, 2.5, 2));
    for (int f = 0; f < floors.size(); f++) {
        boolean isGround = f == 0 && wallTag.isGroundFloor;
        DRectangle floor = floors.get(f);
        MeshBuilder wall = isGround ? ground : normalWall;
        List<DRectangle> edges = floor.splitX(r -> split3(r, 1, 1));
        if (isGround)
            groundFloorHeight = floor.height;
        if (edges.size() != 3) {
            wall.add(floor, to3d);
        } else {
            wall.add(edges.get(0), to3d);
            wall.add(edges.get(edges.size() - 1), to3d);
            DRectangle cen = edges.get(1);
            if (cen.height < 1.8)
                wall.add(cen, to3d);
            else {
                if (f == 0 && wallTag.isGroundFloor) {
                    List<DRectangle> groundPanel = cen.splitX(r -> split1(r, 0.9));
                    if (groundPanel.get(0).width < 0.7)
                        wall.add(groundPanel.get(0), to3d);
                    else if (wallTag.makeDoor) {
                        List<DRectangle> doorHeight = groundPanel.get(0).splitY(r -> split1(r, 2.2));
                        if (visible(doorHeight.get(0), occlusions))
                            greebleGrid.createDoor(doorHeight.get(0), to3d, wall, mbs.get(windowColor), wallTag.doorDepth);
                        else
                            wall.add(doorHeight.get(0), to3d);
                        if (doorHeight.size() > 1)
                            wall.add(doorHeight.get(1), to3d);
                        if (groundPanel.size() > 1) {
                            List<DRectangle> gWindowPanelH = groundPanel.get(1).splitX(r -> split3(r, 0.5, 0.0));
                            if (gWindowPanelH.size() > 2) {
                                wall.add(gWindowPanelH.get(0), to3d);
                                wall.add(gWindowPanelH.get(2), to3d);
                                List<DRectangle> gWindowPanelV = gWindowPanelH.get(1).splitY(r -> split3(r, 0.5, 0.5));
                                if (gWindowPanelV.size() > 2) {
                                    wall.add(gWindowPanelV.get(0), to3d);
                                    wall.add(gWindowPanelV.get(2), to3d);
                                    if (visible(gWindowPanelV.get(1), occlusions))
                                        greebleGrid.createWindow(gWindowPanelV.get(1), to3d, wall, mbs.get(windowColor), mbs.get(glassColor), wallTag.windowDepth, -1, -1, -1, 0.6, 0.9);
                                    else
                                        wall.add(gWindowPanelV.get(1), to3d);
                                } else
                                    for (DRectangle d : gWindowPanelV) wall.add(d, to3d);
                            } else
                                for (DRectangle d : gWindowPanelH) wall.add(d, to3d);
                        }
                    } else
                        windowStrip(to3d, wallTag, mbs.get(windowColor), mbs.get(glassColor), wall, cen, false, occlusions, greebleGrid);
                } else {
                    windowStrip(to3d, wallTag, mbs.get(windowColor), mbs.get(glassColor), wall, cen, f > 0 && f < floors.size() - 1 && wallTag.makeBalcony, occlusions, greebleGrid);
                    if (f == 1 && wallTag.isGroundFloor)
                        greebleGrid.moulding(to3d, new DRectangle(floor.x, floor.y, floor.width, 0.5), mbs.get(mouldingColor));
                }
            }
        }
    }
    return groundFloorHeight;
}
Also used : Loop(org.twak.utils.collections.Loop) Loopz(org.twak.utils.collections.Loopz) Point2d(javax.vecmath.Point2d) List(java.util.List) Cache(org.twak.utils.Cache) Matrix4d(javax.vecmath.Matrix4d) DRectangle(org.twak.utils.geom.DRectangle) RectDir(org.twak.utils.geom.DRectangle.RectDir) MeshBuilder(org.twak.siteplan.jme.MeshBuilder) Tweed(org.twak.tweed.Tweed) ArrayList(java.util.ArrayList) DRectangle(org.twak.utils.geom.DRectangle) MeshBuilder(org.twak.siteplan.jme.MeshBuilder) List(java.util.List) ArrayList(java.util.ArrayList)

Example 7 with Matrix4d

use of javax.vecmath.Matrix4d in project chordatlas by twak.

the class AlignTool method doAlign.

private void doAlign() {
    if (alignMarkers[0] == null || alignMarkers[1] == null || otherMarkers[0] == null || otherMarkers[1] == null) {
        JOptionPane.showMessageDialog(null, "click meshes to create align markers");
        return;
    }
    Matrix4d toOrigin = buildFrame(alignMarkers);
    toOrigin.invert();
    Matrix4d o = buildFrame(otherMarkers);
    toOrigin.mul(o, toOrigin);
    toOrigin.m13 += vOffset;
    Transform t = new Transform();
    t.fromTransformMatrix(Jme3z.toJme(toOrigin));
    toAlign.moveTo(t);
// System.out.println ( "bounds "+ toAlign.gNode.getWorldBound() );
}
Also used : Matrix4d(javax.vecmath.Matrix4d) Transform(com.jme3.math.Transform)

Example 8 with Matrix4d

use of javax.vecmath.Matrix4d in project chordatlas by twak.

the class MiniTransform method convertToMini.

public static void convertToMini(Iterable<File> bigObj, File outfile, Matrix4d transform) {
    outfile.mkdirs();
    // .iterator().next() );
    ObjDump src = new ObjDump(bigObj);
    src.centerVerts();
    src.transform(transform);
    long count = src.material2Face.entrySet().stream().mapToInt(x -> x.getValue().size()).sum();
    double[] bounds = src.orderVert.stream().collect(new InaxPoint3dCollector());
    long targetCount = 5000;
    double volume = (bounds[1] - bounds[0]) * (bounds[3] - bounds[2]) * (bounds[5] - bounds[4]);
    double edgeLength = Math.pow(volume / (count / targetCount), 0.3333);
    int xc = (int) Math.ceil((bounds[1] - bounds[0]) / edgeLength), yc = (int) Math.ceil((bounds[3] - bounds[2]) / edgeLength), zc = (int) Math.ceil((bounds[5] - bounds[4]) / edgeLength);
    Set<Face>[][][] faces = new Set[xc][yc][zc];
    for (Entry<Material, List<Face>> e : src.material2Face.entrySet()) for (Face f : e.getValue()) {
        Tuple3d vt = src.orderVert.get(f.vtIndexes.get(0));
        int ix = (int) ((vt.x - bounds[0]) / edgeLength);
        int iy = (int) ((vt.y - bounds[2]) / edgeLength);
        int iz = (int) ((vt.z - bounds[4]) / edgeLength);
        if (faces[ix][iy][iz] == null)
            faces[ix][iy][iz] = new HashSet();
        faces[ix][iy][iz].add(f);
    }
    int dir = 0;
    MiniTransform mt = new MiniTransform();
    for (int x = 0; x < xc; x++) for (int y = 0; y < yc; y++) for (int z = 0; z < zc; z++) {
        Set<Face> miniF = faces[x][y][z];
        if (miniF == null)
            continue;
        Matrix4d trans = new Matrix4d();
        trans.setIdentity();
        trans.setScale(edgeLength / 255);
        trans.setTranslation(new Vector3d(x * edgeLength + bounds[0], y * edgeLength + bounds[2], z * edgeLength + bounds[4]));
        Matrix4d pack = new Matrix4d(trans);
        pack.invert();
        ObjDump mini = new ObjDump();
        miniF.stream().forEach(f -> mini.addFaceFrom(f, src));
        mini.transform(pack);
        mini.dump(new File(new File(outfile, "" + dir), OBJ));
        mt.index.put(dir, trans);
        dir++;
    }
    try {
        new XStream().toXML(mt, new FileWriter(new File(outfile, INDEX)));
    } catch (IOException e1) {
        e1.printStackTrace();
    }
    System.out.println("wrote " + count + " faces to " + dir + " meshes");
}
Also used : XStream(com.thoughtworks.xstream.XStream) InaxPoint3dCollector(org.twak.utils.streams.InaxPoint3dCollector) FileWriter(java.io.FileWriter) Matrix4d(javax.vecmath.Matrix4d) Face(org.twak.utils.geom.ObjDump.Face) Auto(org.twak.utils.ui.auto.Auto) Set(java.util.Set) IOException(java.io.IOException) HashMap(java.util.HashMap) Vector3d(javax.vecmath.Vector3d) Matrix4f(com.jme3.math.Matrix4f) File(java.io.File) Tuple3d(javax.vecmath.Tuple3d) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) List(java.util.List) Map(java.util.Map) Entry(java.util.Map.Entry) ObjDump(org.twak.utils.geom.ObjDump) Material(org.twak.utils.geom.ObjDump.Material) Set(java.util.Set) HashSet(java.util.HashSet) XStream(com.thoughtworks.xstream.XStream) FileWriter(java.io.FileWriter) Material(org.twak.utils.geom.ObjDump.Material) IOException(java.io.IOException) Matrix4d(javax.vecmath.Matrix4d) Vector3d(javax.vecmath.Vector3d) ObjDump(org.twak.utils.geom.ObjDump) Tuple3d(javax.vecmath.Tuple3d) ArrayList(java.util.ArrayList) List(java.util.List) InaxPoint3dCollector(org.twak.utils.streams.InaxPoint3dCollector) Face(org.twak.utils.geom.ObjDump.Face) File(java.io.File) HashSet(java.util.HashSet)

Example 9 with Matrix4d

use of javax.vecmath.Matrix4d in project chordatlas by twak.

the class ReadTrace method processLine.

private void processLine(String line) throws Throwable {
    set(glDrawElementsRE, line, TRI_COUNT);
    Matcher m = glVertexAttrib.matcher(line);
    if (m.matches()) {
        if (m.group(1).equals("BYTE")) {
            iVals[VERTEX_BUFFER] = boundBuffer.get(ARRAY_BUFFER);
            iVals[VERTEX_BUFFER_OFFSET] = m.group(3).equals("NULL") ? 0 : Integer.parseUnsignedInt(m.group(3).substring(2), 16);
            iVals[VERTEX_BUFFER_STRIDE] = Integer.parseInt(m.group(2));
        }
        if (m.group(1).equals("SHORT")) {
            iVals[UV_BUFFER] = boundBuffer.get(ARRAY_BUFFER);
            iVals[UV_BUFFER_OFFSET] = m.group(3).equals("NULL") ? 0 : Integer.parseInt(m.group(3).substring(2), 16);
            iVals[UV_BUFFER_STRIDE] = Integer.parseInt(m.group(2));
        }
    }
    m = magic8Pattern.matcher(line);
    if (m.matches())
        for (int i = 1; i < 9; i++) magic8[i - 1] = Double.parseDouble(m.group(i));
    m = viewMatrixPattern.matcher(line);
    if (m.matches()) {
        for (int xi = 0; xi < 4; xi++) for (int yi = 0; yi < 4; yi++) viewMatrix.setElement(xi, yi, Double.parseDouble(m.group(xi + yi * 4 + 1)));
        if (matrixForAntiWibble == null) {
            matrixForAntiWibble = new Matrix4d(viewMatrix);
            try {
                matrixForAntiWibble.invert();
            } catch (Throwable th) {
                matrixForAntiWibble = null;
            }
        }
        if (matrixForAntiWibble != null)
            viewMatrix.mul(matrixForAntiWibble, viewMatrix);
    }
    m = uvParams.matcher(line);
    if (m.matches())
        for (int i = 0; i < 4; i++) fVals[UV_PARAM_X + i] = Float.parseFloat(m.group(1 + i));
}
Also used : Matrix4d(javax.vecmath.Matrix4d) Matcher(java.util.regex.Matcher)

Example 10 with Matrix4d

use of javax.vecmath.Matrix4d 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)

Aggregations

Matrix4d (javax.vecmath.Matrix4d)18 Vector3d (javax.vecmath.Vector3d)8 File (java.io.File)6 ArrayList (java.util.ArrayList)6 HashMap (java.util.HashMap)6 Point3d (javax.vecmath.Point3d)6 Map (java.util.Map)5 Point2d (javax.vecmath.Point2d)5 IOException (java.io.IOException)4 ObjDump (org.twak.utils.geom.ObjDump)4 Transform (com.jme3.math.Transform)3 XStream (com.thoughtworks.xstream.XStream)3 FileOutputStream (java.io.FileOutputStream)3 List (java.util.List)3 Tuple3d (javax.vecmath.Tuple3d)3 Loop (org.twak.utils.collections.Loop)3 LinearForm3D (org.twak.utils.geom.LinearForm3D)3 Face (org.twak.utils.geom.ObjDump.Face)3 ModelKey (com.jme3.asset.ModelKey)2 Material (com.jme3.material.Material)2