Search in sources :

Example 21 with Point2D

use of javafx.geometry.Point2D in project FXyzLib by Birdasaur.

the class OBJWriter method exportMesh.

public void exportMesh() {
    File objFile = new File(fileName + ".obj");
    try {
        writer = new BufferedWriter(new FileWriter(objFile));
        writer.write("# Material" + newline);
        writer.write("mtllib " + fileName + ".mtl" + newline);
        points0 = new float[mesh.getPoints().size()];
        mesh.getPoints().toArray(points0);
        List<Point3D> points1 = IntStream.range(0, points0.length / 3).mapToObj(i -> new Point3D(points0[3 * i], points0[3 * i + 1], points0[3 * i + 2])).collect(Collectors.toList());
        writer.write("# Vertices (" + points1.size() + ")" + newline);
        points1.forEach(p -> {
            try {
                writer.write("v " + p.x + " " + p.y + " " + p.z + "" + newline);
            } catch (IOException ex) {
                System.out.println("Error writting vertex " + ex);
            }
        });
        writer.write("# End Vertices" + newline);
        writer.write(newline);
        texCoord0 = new float[mesh.getTexCoords().size()];
        mesh.getTexCoords().toArray(texCoord0);
        List<Point2D> texCoord1 = IntStream.range(0, texCoord0.length / 2).mapToObj(i -> new Point2D(texCoord0[2 * i], texCoord0[2 * i + 1])).collect(Collectors.toList());
        writer.write("# Textures Coordinates (" + texCoord1.size() + ")" + newline);
        texCoord1.forEach(t -> {
            try {
                writer.write("vt " + ((float) t.getX()) + " " + ((float) (1d - t.getY())) + "" + newline);
            } catch (IOException ex) {
                System.out.println("Error writting texture coordinate " + ex);
            }
        });
        writer.write("# End Texture Coordinates " + newline);
        writer.write(newline);
        faces0 = new int[mesh.getFaces().size()];
        mesh.getFaces().toArray(faces0);
        List<Integer[]> faces1 = IntStream.range(0, faces0.length / 6).mapToObj(i -> new Integer[] { faces0[6 * i], faces0[6 * i + 1], faces0[6 * i + 2], faces0[6 * i + 3], faces0[6 * i + 4], faces0[6 * i + 5] }).collect(Collectors.toList());
        writer.write("# Faces (" + faces1.size() + ")" + newline);
        writer.write("# Material" + newline);
        writer.write("usemtl " + fileName + "" + newline);
        sm0 = new int[mesh.getFaces().size()];
        mesh.getFaceSmoothingGroups().toArray(sm0);
        if (sm0[0] > 0) {
            writer.write("s " + sm0[0] + "" + newline);
        }
        AtomicInteger count = new AtomicInteger();
        faces1.forEach(f -> {
            try {
                writer.write("f " + (f[0] + 1) + "/" + (f[1] + 1) + " " + (f[2] + 1) + "/" + (f[3] + 1) + " " + (f[4] + 1) + "/" + (f[5] + 1) + "" + newline);
                if (sm0[count.getAndIncrement()] != sm0[count.get()]) {
                    writer.write("s " + (sm0[count.get()] > 0 ? sm0[count.get()] : "off") + "" + newline);
                }
            } catch (IOException ex) {
                System.out.println("Error writting face " + ex);
            }
        });
        writer.write("# End Faces " + newline);
        writer.write(newline);
    } catch (IOException io) {
        System.out.println("Error creating writer obj " + io);
    } finally {
        try {
            if (writer != null) {
                writer.close();
            }
        } catch (Exception e) {
        }
    }
    File mtlFile = new File(fileName + ".mtl");
    try {
        writer = new BufferedWriter(new FileWriter(mtlFile));
        writer.write("# Material " + fileName + "" + newline);
        writer.write("newmtl " + fileName + "" + newline);
        // Illumination [0-10]
        writer.write("illum 4" + newline);
        // diffuse color black
        writer.write("Kd " + diffuseColor + "" + newline);
        // ambient color
        writer.write("Ka 0.10 0.10 0.10" + newline);
        // Transmission filter
        writer.write("Tf 1.00 1.00 1.00" + newline);
        if (diffuseMap != null) {
            writer.write("map_Kd " + diffuseMap + "" + newline);
        }
        // optical density
        writer.write("Ni 1.00" + newline);
        // specular reflectivity
        writer.write("Ks 1.00 1.00 1.00" + newline);
        // specular exponent
        writer.write("Ns 32.00" + newline);
    } catch (IOException io) {
        System.out.println("Error creating writer mtl " + io);
    } finally {
        try {
            if (writer != null) {
                writer.close();
            }
        } catch (Exception e) {
        }
    }
}
Also used : IntStream(java.util.stream.IntStream) Color(javafx.scene.paint.Color) TextureType(org.fxyz.shapes.primitives.helper.TriangleMeshHelper.TextureType) BufferedWriter(java.io.BufferedWriter) FileWriter(java.io.FileWriter) IOException(java.io.IOException) Collectors(java.util.stream.Collectors) File(java.io.File) TriangleMesh(javafx.scene.shape.TriangleMesh) List(java.util.List) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) SwingFXUtils(javafx.embed.swing.SwingFXUtils) ImageIO(javax.imageio.ImageIO) ColorPalette(org.fxyz.utils.Palette.ColorPalette) Point2D(javafx.geometry.Point2D) Image(javafx.scene.image.Image) Point3D(org.fxyz.geometry.Point3D) FileWriter(java.io.FileWriter) IOException(java.io.IOException) IOException(java.io.IOException) BufferedWriter(java.io.BufferedWriter) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Point2D(javafx.geometry.Point2D) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Point3D(org.fxyz.geometry.Point3D) File(java.io.File)

Example 22 with Point2D

use of javafx.geometry.Point2D in project FXyzLib by Birdasaur.

the class FrustumMesh method createFrustum.

private TriangleMesh createFrustum(float majorRadius, float minorRadius, float height, int level) {
    TriangleMesh m0 = null;
    if (level > 0) {
        m0 = createFrustum(majorRadius, minorRadius, height, level - 1);
    }
    if (level == 0) {
        a = new Affine();
        int div = DEFAULT_DIVISIONS > 3 ? DEFAULT_DIVISIONS : 3;
        if (getSectionType() != TriangleMeshHelper.SectionType.CIRCLE) {
            div = getSectionType().getSides() * ((int) (div / getSectionType().getSides()) + 1);
        }
        if (getAxisOrigin() != null && getAxisEnd() != null) {
            Point3D dir = getAxisEnd().substract(getAxisOrigin()).crossProduct(new Point3D(0, -1, 0));
            double angle = Math.acos(getAxisEnd().substract(getAxisOrigin()).normalize().dotProduct(new Point3D(0, -1, 0)));
            a = a.createConcatenation(new Translate(getAxisOrigin().x, getAxisOrigin().y - height / 2d, getAxisOrigin().z)).createConcatenation(new Rotate(-Math.toDegrees(angle), 0d, height / 2d, 0d, new javafx.geometry.Point3D(dir.x, -dir.y, dir.z)));
        }
        int nPoints = 2 * div + 2;
        float rBase = majorRadius;
        float rTop = minorRadius;
        float h = height;
        final float[] baseVertices = new float[nPoints * 3];
        // base at y=h/2
        for (int i = 0; i < div; i++) {
            double ang = i * 2d * Math.PI / div;
            double pol = polygonalSection(ang);
            Point3D ta = transform(rBase * pol * Math.cos(ang), h / 2, rBase * pol * Math.sin(ang));
            baseVertices[3 * i] = ta.x;
            baseVertices[3 * i + 1] = ta.y;
            baseVertices[3 * i + 2] = ta.z;
        }
        // top at y=-h/2
        for (int i = div; i < 2 * div; i++) {
            double ang = i * 2d * Math.PI / div;
            double pol = polygonalSection(ang);
            Point3D ta = transform(rTop * pol * Math.cos(ang), -h / 2, rTop * pol * Math.sin(ang));
            baseVertices[3 * i] = ta.x;
            baseVertices[3 * i + 1] = ta.y;
            baseVertices[3 * i + 2] = ta.z;
        }
        Point3D ta = transform(0, h / 2, 0);
        baseVertices[6 * div] = ta.x;
        baseVertices[6 * div + 1] = ta.y;
        baseVertices[6 * div + 2] = ta.z;
        ta = transform(0, -h / 2, 0);
        baseVertices[6 * div + 3] = ta.x;
        baseVertices[6 * div + 4] = ta.y;
        baseVertices[6 * div + 5] = ta.z;
        int nTextCoords = div * 4 + 6;
        float rectBase = (float) polygonalSize(rBase);
        float rectTop = (float) polygonalSize(rTop);
        float L = (float) (rBase + 2d * Math.PI * rBase);
        float H = 2f * (rBase + rTop) + h;
        final float[] baseTexCoords = new float[nTextCoords * 2];
        // u right ,v up
        for (int i = 0; i <= div; i++) {
            baseTexCoords[2 * i] = (float) (rBase + i * rectBase / div) / L;
            baseTexCoords[2 * i + 1] = (float) (2f * rTop + h) / H;
        }
        for (int i = 0; i <= div; i++) {
            baseTexCoords[2 * div + 2 * i + 2] = (float) (rBase + i * rectTop / div) / L;
            baseTexCoords[2 * div + 2 * i + 3] = (float) (2f * rTop) / H;
        }
        for (int i = 0; i <= div; i++) {
            double ang = i * 2d * Math.PI / div;
            double pol = polygonalSection(ang);
            baseTexCoords[4 * div + 2 * i + 4] = (float) (rBase + rBase * pol * Math.sin(ang)) / L;
            baseTexCoords[4 * div + 2 * i + 5] = (float) (2f * rTop + rBase + h - rBase * pol * Math.cos(ang)) / H;
        }
        for (int i = 0; i <= div; i++) {
            double ang = i * 2d * Math.PI / div;
            double pol = polygonalSection(ang);
            baseTexCoords[6 * div + 2 * i + 6] = (float) (rBase + rTop * pol * Math.sin(ang)) / L;
            baseTexCoords[6 * div + 2 * i + 7] = (float) (rTop + rTop * pol * Math.cos(ang)) / H;
        }
        baseTexCoords[8 * div + 8] = rBase / L;
        baseTexCoords[8 * div + 9] = (2f * rTop + rBase + h) / H;
        baseTexCoords[8 * div + 10] = rBase / L;
        baseTexCoords[8 * div + 11] = rTop / H;
        int nFaces = div * 4;
        final int[] baseTexture = new int[nFaces * 3];
        final int[] baseFaces = new int[nFaces * 3];
        for (int i = 0; i < div; i++) {
            int p1 = i + 1;
            int p2 = i + div;
            int p3 = i + div + 1;
            baseFaces[6 * i] = i;
            baseFaces[6 * i + 1] = p1 == div ? 0 : p1;
            baseFaces[6 * i + 2] = p2;
            baseFaces[6 * i + 3] = p3 % div == 0 ? p3 - div : p3;
            baseFaces[6 * i + 4] = p2;
            baseFaces[6 * i + 5] = p1 == div ? 0 : p1;
            baseTexture[6 * i] = i;
            baseTexture[6 * i + 1] = p1;
            baseTexture[6 * i + 2] = p2 + 1;
            baseTexture[6 * i + 3] = p3 + 1;
            baseTexture[6 * i + 4] = p2 + 1;
            baseTexture[6 * i + 5] = p1;
        }
        for (int i = 0; i < div; i++) {
            int p1 = div * 2;
            int p2 = i + 1;
            baseFaces[6 * div + 3 * i] = i;
            baseFaces[6 * div + 3 * i + 1] = p1;
            baseFaces[6 * div + 3 * i + 2] = p2 == div ? 0 : p2;
            baseTexture[6 * div + 3 * i] = (div + 1) * 2 + i;
            baseTexture[6 * div + 3 * i + 1] = (div + 1) * 4;
            baseTexture[6 * div + 3 * i + 2] = (div + 1) * 2 + i + 1;
        }
        for (int i = 0; i < div; i++) {
            int p1 = div * 2 + 1;
            int p2 = i + 1 + div;
            baseFaces[9 * div + 3 * i] = i + div;
            baseFaces[9 * div + 3 * i + 1] = p2 % div == 0 ? p2 - div : p2;
            baseFaces[9 * div + 3 * i + 2] = p1;
            baseTexture[9 * div + 3 * i] = (div + 1) * 3 + i;
            baseTexture[9 * div + 3 * i + 1] = (div + 1) * 3 + i + 1;
            baseTexture[9 * div + 3 * i + 2] = (div + 1) * 4 + 1;
        }
        points0 = baseVertices;
        numVertices = baseVertices.length / 3;
        texCoord0 = baseTexCoords;
        numTexCoords = baseTexCoords.length / 2;
        faces0 = IntStream.range(0, baseFaces.length / 3).mapToObj(i -> IntStream.of(baseFaces[3 * i], baseTexture[3 * i], baseFaces[3 * i + 1], baseTexture[3 * i + 1], baseFaces[3 * i + 2], baseTexture[3 * i + 2])).flatMapToInt(i -> i).toArray();
        numFaces = baseFaces.length / 3;
    } else if (m0 != null) {
        points0 = new float[numVertices * m0.getPointElementSize()];
        m0.getPoints().toArray(points0);
    }
    final float h = height;
    List<Point3D> points1 = IntStream.range(0, numVertices).mapToObj(i -> {
        Point3D p = new Point3D(points0[3 * i], points0[3 * i + 1], points0[3 * i + 2]);
        p.f = (h / 2 - unTransform(p).y) / h;
        return p;
    }).collect(Collectors.toList());
    if (level > 0 && m0 != null) {
        texCoord0 = new float[numTexCoords * m0.getTexCoordElementSize()];
        m0.getTexCoords().toArray(texCoord0);
    }
    texCoord1 = IntStream.range(0, numTexCoords).mapToObj(i -> new Point2D(texCoord0[2 * i], texCoord0[2 * i + 1])).collect(Collectors.toList());
    if (level > 0 && m0 != null) {
        faces0 = new int[numFaces * m0.getFaceElementSize()];
        m0.getFaces().toArray(faces0);
    }
    List<Face3> faces1 = IntStream.range(0, numFaces).mapToObj(i -> new Face3(faces0[6 * i], faces0[6 * i + 2], faces0[6 * i + 4])).collect(Collectors.toList());
    index.set(points1.size());
    map.clear();
    listVertices.clear();
    listFaces.clear();
    listVertices.addAll(points1);
    faces1.forEach(face -> {
        int v1 = face.p0;
        int v2 = face.p1;
        int v3 = face.p2;
        if (level > 0) {
            int a = getMiddle(v1, points1.get(v1), v2, points1.get(v2));
            int b = getMiddle(v2, points1.get(v2), v3, points1.get(v3));
            int c = getMiddle(v3, points1.get(v3), v1, points1.get(v1));
            listFaces.add(new Face3(v1, a, c));
            listFaces.add(new Face3(v2, b, a));
            listFaces.add(new Face3(v3, c, b));
            listFaces.add(new Face3(a, b, c));
        } else {
            listFaces.add(new Face3(v1, v2, v3));
        }
    });
    map.clear();
    numVertices = listVertices.size();
    numFaces = listFaces.size();
    List<Face3> textures1;
    if (level == 0) {
        textures1 = IntStream.range(0, faces0.length / 6).mapToObj(i -> new Face3(faces0[6 * i + 1], faces0[6 * i + 3], faces0[6 * i + 5])).collect(Collectors.toList());
    } else {
        textures1 = listTextures.stream().map(t -> t).collect(Collectors.toList());
    }
    index.set(texCoord1.size());
    listTextures.clear();
    AtomicInteger kk = new AtomicInteger();
    textures1.forEach(face -> {
        int v1 = face.p0;
        int v2 = face.p1;
        int v3 = face.p2;
        if (level > 0) {
            int a = getMiddle(v1, texCoord1.get(v1), v2, texCoord1.get(v2));
            int b = getMiddle(v2, texCoord1.get(v2), v3, texCoord1.get(v3));
            int c = getMiddle(v3, texCoord1.get(v3), v1, texCoord1.get(v1));
            listTextures.add(new Face3(v1, a, c));
            listTextures.add(new Face3(v2, b, a));
            listTextures.add(new Face3(v3, c, b));
            listTextures.add(new Face3(a, b, c));
        } else {
            listTextures.add(new Face3(v1, v2, v3));
        }
    });
    map.clear();
    texCoord0 = texCoord1.stream().flatMapToDouble(p -> DoubleStream.of(p.getX(), p.getY())).collect(() -> new FloatCollector(texCoord1.size() * 2), FloatCollector::add, FloatCollector::join).toArray();
    numTexCoords = texCoord0.length / 2;
    textureCoords = texCoord0;
    if (level == getLevel()) {
        areaMesh.setWidth(majorRadius + 2f * Math.PI * majorRadius);
        areaMesh.setHeight(height + 2f * (minorRadius + majorRadius));
        smoothingGroups = IntStream.range(0, listFaces.size()).map(i -> {
            if (getSectionType() != TriangleMeshHelper.SectionType.CIRCLE) {
                return 0;
            }
            if (i < listFaces.size() / 2) {
                return 1;
            } else if (i < 3 * listFaces.size() / 4) {
                return 2;
            }
            return 4;
        }).toArray();
    }
    return createMesh();
}
Also used : IntStream(java.util.stream.IntStream) Affine(javafx.scene.transform.Affine) Rotate(javafx.scene.transform.Rotate) HashMap(java.util.HashMap) DoubleProperty(javafx.beans.property.DoubleProperty) IntegerProperty(javafx.beans.property.IntegerProperty) CullFace(javafx.scene.shape.CullFace) TriangleMesh(javafx.scene.shape.TriangleMesh) NonInvertibleTransformException(javafx.scene.transform.NonInvertibleTransformException) SectionType(org.fxyz.shapes.primitives.helper.TriangleMeshHelper.SectionType) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) SimpleIntegerProperty(javafx.beans.property.SimpleIntegerProperty) Point2D(javafx.geometry.Point2D) Transform(javafx.scene.transform.Transform) TriangleMeshHelper(org.fxyz.shapes.primitives.helper.TriangleMeshHelper) ObjectProperty(javafx.beans.property.ObjectProperty) FloatCollector(org.fxyz.utils.FloatCollector) Translate(javafx.scene.transform.Translate) DrawMode(javafx.scene.shape.DrawMode) Collectors(java.util.stream.Collectors) DoubleStream(java.util.stream.DoubleStream) List(java.util.List) SimpleObjectProperty(javafx.beans.property.SimpleObjectProperty) DepthTest(javafx.scene.DepthTest) Face3(org.fxyz.geometry.Face3) SimpleDoubleProperty(javafx.beans.property.SimpleDoubleProperty) Point3D(org.fxyz.geometry.Point3D) TriangleMesh(javafx.scene.shape.TriangleMesh) Rotate(javafx.scene.transform.Rotate) FloatCollector(org.fxyz.utils.FloatCollector) Affine(javafx.scene.transform.Affine) Point2D(javafx.geometry.Point2D) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Point3D(org.fxyz.geometry.Point3D) Translate(javafx.scene.transform.Translate) Face3(org.fxyz.geometry.Face3)

Example 23 with Point2D

use of javafx.geometry.Point2D in project FXyzLib by Birdasaur.

the class CuboidMesh method createCube.

private TriangleMesh createCube(float width, float height, float depth, int level) {
    TriangleMesh m0 = null;
    if (level > 0) {
        m0 = createCube(width, height, depth, level - 1);
    }
    if (level == 0) {
        a = new Affine();
        float L = 2f * width + 2f * depth;
        float H = height + 2f * depth;
        float hw = width / 2f, hh = height / 2f, hd = depth / 2f;
        if (center.get() != null) {
            a = a.createConcatenation(new Translate(center.get().x, center.get().y, center.get().z));
        //                hw+=center.get().x;
        //                hh+=center.get().y;
        //                hd+=center.get().z;
        }
        final float[] baseVertices = new float[] { hw, hh, hd, hw, hh, -hd, hw, -hh, hd, hw, -hh, -hd, -hw, hh, hd, -hw, hh, -hd, -hw, -hh, hd, -hw, -hh, -hd };
        final float[] baseTexCoords = new float[] { depth / L, 0f, (depth + width) / L, 0f, 0f, depth / H, depth / L, depth / H, (depth + width) / L, depth / H, (2f * depth + width) / L, depth / H, 1f, depth / H, 0f, (depth + height) / H, depth / L, (depth + height) / H, (depth + width) / L, (depth + height) / H, (2f * depth + width) / L, (depth + height) / H, 1f, (depth + height) / H, depth / L, 1f, (depth + width) / L, 1f };
        final int[] baseTexture = new int[] { 8, 3, 7, 3, 2, 7, 9, 10, 4, 4, 10, 5, 8, 12, 9, 9, 12, 13, 3, 4, 0, 0, 4, 1, 8, 9, 3, 3, 9, 4, 11, 6, 10, 10, 6, 5 };
        final List<Integer> baseFaces = Arrays.asList(0, 2, 1, 2, 3, 1, 4, 5, 6, 6, 5, 7, 0, 1, 4, 4, 1, 5, 2, 6, 3, 3, 6, 7, 0, 4, 2, 2, 4, 6, 1, 3, 5, 5, 3, 7);
        for (int i = 0; i < baseVertices.length / 3; i++) {
            Point3D ta = transform(baseVertices[3 * i], baseVertices[3 * i + 1], baseVertices[3 * i + 2]);
            baseVertices[3 * i] = ta.x;
            baseVertices[3 * i + 1] = ta.y;
            baseVertices[3 * i + 2] = ta.z;
        }
        points0 = baseVertices;
        numVertices = baseVertices.length / 3;
        texCoord0 = baseTexCoords;
        numTexCoords = baseTexCoords.length / 2;
        faces0 = IntStream.range(0, baseFaces.size() / 3).mapToObj(i -> IntStream.of(baseFaces.get(3 * i), baseTexture[3 * i], baseFaces.get(3 * i + 1), baseTexture[3 * i + 1], baseFaces.get(3 * i + 2), baseTexture[3 * i + 2])).flatMapToInt(i -> i).toArray();
        numFaces = baseFaces.size() / 3;
    } else if (m0 != null) {
        points0 = new float[numVertices * m0.getPointElementSize()];
        m0.getPoints().toArray(points0);
    }
    List<Point3D> points1 = IntStream.range(0, numVertices).mapToObj(i -> new Point3D(points0[3 * i], points0[3 * i + 1], points0[3 * i + 2])).collect(Collectors.toList());
    if (level > 0 && m0 != null) {
        texCoord0 = new float[numTexCoords * m0.getTexCoordElementSize()];
        m0.getTexCoords().toArray(texCoord0);
    }
    texCoord1 = IntStream.range(0, numTexCoords).mapToObj(i -> new Point2D(texCoord0[2 * i], texCoord0[2 * i + 1])).collect(Collectors.toList());
    if (level > 0 && m0 != null) {
        faces0 = new int[numFaces * m0.getFaceElementSize()];
        m0.getFaces().toArray(faces0);
    }
    List<Face3> faces1 = IntStream.range(0, numFaces).mapToObj(i -> new Face3(faces0[6 * i], faces0[6 * i + 2], faces0[6 * i + 4])).collect(Collectors.toList());
    index.set(points1.size());
    map.clear();
    listVertices.clear();
    listFaces.clear();
    listVertices.addAll(points1);
    faces1.forEach(face -> {
        int v1 = face.p0;
        int v2 = face.p1;
        int v3 = face.p2;
        if (level > 0) {
            int a = getMiddle(v1, points1.get(v1), v2, points1.get(v2));
            int b = getMiddle(v2, points1.get(v2), v3, points1.get(v3));
            int c = getMiddle(v3, points1.get(v3), v1, points1.get(v1));
            listFaces.add(new Face3(v1, a, c));
            listFaces.add(new Face3(v2, b, a));
            listFaces.add(new Face3(v3, c, b));
            listFaces.add(new Face3(a, b, c));
        } else {
            listFaces.add(new Face3(v1, v2, v3));
        }
    });
    map.clear();
    numVertices = listVertices.size();
    numFaces = listFaces.size();
    List<Face3> textures1;
    if (level == 0) {
        textures1 = IntStream.range(0, faces0.length / 6).mapToObj(i -> new Face3(faces0[6 * i + 1], faces0[6 * i + 3], faces0[6 * i + 5])).collect(Collectors.toList());
    } else {
        textures1 = listTextures.stream().map(t -> t).collect(Collectors.toList());
    }
    index.set(texCoord1.size());
    listTextures.clear();
    textures1.forEach(face -> {
        int v1 = face.p0;
        int v2 = face.p1;
        int v3 = face.p2;
        if (level > 0) {
            int a = getMiddle(v1, texCoord1.get(v1), v2, texCoord1.get(v2));
            int b = getMiddle(v2, texCoord1.get(v2), v3, texCoord1.get(v3));
            int c = getMiddle(v3, texCoord1.get(v3), v1, texCoord1.get(v1));
            listTextures.add(new Face3(v1, a, c));
            listTextures.add(new Face3(v2, b, a));
            listTextures.add(new Face3(v3, c, b));
            listTextures.add(new Face3(a, b, c));
        } else {
            listTextures.add(new Face3(v1, v2, v3));
        }
    });
    map.clear();
    texCoord0 = texCoord1.stream().flatMapToDouble(p -> DoubleStream.of(p.getX(), p.getY())).collect(() -> new FloatCollector(texCoord1.size() * 2), FloatCollector::add, FloatCollector::join).toArray();
    numTexCoords = texCoord0.length / 2;
    textureCoords = texCoord0;
    if (level == getLevel()) {
        areaMesh.setWidth(2f * width + 2f * depth);
        areaMesh.setHeight(height + 2f * depth);
        // 1<<j -> bitset, 00100. Otherwise: 000111 will mean they are shared
        smoothingGroups = IntStream.range(0, listFaces.size()).map(i -> 1 << (i / (listFaces.size() / 6))).toArray();
    // smoothing groups based on 3DViewer -> same result
    //            float[] normals=new float[]{1,0,0,-1,0,0,0,1,0,0,-1,0,0,0,1,0,0,-1};
    //            int[] newFaces = IntStream.range(0, listFaces.size())
    //                        .mapToObj(i->IntStream.of((int)listFaces.get(i).x, (int)listFaces.get(i).x, 
    //                                (int)listFaces.get(i).y, (int)listFaces.get(i).y, 
    //                                (int)listFaces.get(i).z, (int)listFaces.get(i).z))
    //                        .flatMapToInt(i->i).toArray();
    //            int[] newFaceNormals = IntStream.range(0,listFaces.size()).mapToObj(i->{
    //                int j=(i/(listFaces.size()/6));
    //                return IntStream.of(j,j,j);
    //            }).flatMapToInt(i->i).toArray();
    //            smoothingGroups=SmoothingGroups.calcSmoothGroups(new TriangleMesh(), newFaces, newFaceNormals, normals);
    }
    return createMesh();
}
Also used : IntStream(java.util.stream.IntStream) Arrays(java.util.Arrays) Affine(javafx.scene.transform.Affine) HashMap(java.util.HashMap) DoubleProperty(javafx.beans.property.DoubleProperty) IntegerProperty(javafx.beans.property.IntegerProperty) CullFace(javafx.scene.shape.CullFace) TriangleMesh(javafx.scene.shape.TriangleMesh) NonInvertibleTransformException(javafx.scene.transform.NonInvertibleTransformException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) SimpleIntegerProperty(javafx.beans.property.SimpleIntegerProperty) Point2D(javafx.geometry.Point2D) Transform(javafx.scene.transform.Transform) ObjectProperty(javafx.beans.property.ObjectProperty) FloatCollector(org.fxyz.utils.FloatCollector) Translate(javafx.scene.transform.Translate) DrawMode(javafx.scene.shape.DrawMode) Collectors(java.util.stream.Collectors) DoubleStream(java.util.stream.DoubleStream) List(java.util.List) SimpleObjectProperty(javafx.beans.property.SimpleObjectProperty) DepthTest(javafx.scene.DepthTest) Face3(org.fxyz.geometry.Face3) SimpleDoubleProperty(javafx.beans.property.SimpleDoubleProperty) Point3D(org.fxyz.geometry.Point3D) TriangleMesh(javafx.scene.shape.TriangleMesh) FloatCollector(org.fxyz.utils.FloatCollector) Affine(javafx.scene.transform.Affine) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Point2D(javafx.geometry.Point2D) Point3D(org.fxyz.geometry.Point3D) Translate(javafx.scene.transform.Translate) Face3(org.fxyz.geometry.Face3)

Example 24 with Point2D

use of javafx.geometry.Point2D in project FXyzLib by Birdasaur.

the class TriangulatedMesh method createMesh.

private TriangleMesh createMesh(int level) {
    TriangleMesh m0 = null;
    if (level > 0) {
        m0 = createMesh(level - 1);
    }
    if (level == 0) {
        //check for duplicates or too close
        List<Integer> duplicates = IntStream.range(0, pointsExterior.size()).boxed().filter(i -> pointsExterior.get(i).substract(pointsExterior.get(i == pointsExterior.size() - 1 ? 0 : i + 1)).magnitude() < 100 * EPSILON).map(i -> i).collect(Collectors.toList());
        duplicates.stream().sorted(Collections.reverseOrder()).forEach(i -> pointsExterior.remove(i.intValue()));
        List<PolygonPoint> list = pointsExterior.stream().map(p -> new PolygonPoint(p.x, p.y)).collect(Collectors.toList());
        Polygon poly = new Polygon(list);
        if (bounds.get() != null) {
            maxX = bounds.get().getMaxX();
            minX = bounds.get().getMinX();
            maxY = bounds.get().getMaxY();
            minY = bounds.get().getMinY();
        } else {
            maxX = pointsExterior.stream().mapToDouble(p -> p.x).max().getAsDouble();
            maxY = pointsExterior.stream().mapToDouble(p -> p.y).max().getAsDouble();
            minX = pointsExterior.stream().mapToDouble(p -> p.x).min().getAsDouble();
            minY = pointsExterior.stream().mapToDouble(p -> p.y).min().getAsDouble();
        }
        double rad = getHoleRadius();
        if (pointsHoles != null) {
            steinerPoints = 0;
            numHoles = pointsHoles.size();
            // holes
            pointsHoles.forEach(pHole -> {
                List<PolygonPoint> hole = pHole.stream().distinct().map(p -> new PolygonPoint(p.x, p.y)).collect(Collectors.toList());
                holePoints.add(hole.size());
                Polygon polyIn = new Polygon(hole);
                poly.addHole(polyIn);
                holes.add(hole);
            });
        } else if (rad > 0d) {
            steinerPoints = 0;
            numHoles = 1;
            int num = 200;
            holePoints.add(num);
            // circular hole                
            List<PolygonPoint> hole = IntStream.range(0, num).mapToObj(i -> new PolygonPoint((maxX + minX) / 2d + rad * Math.cos((num - i) * 2d * Math.PI / num), (maxY + minY) / 2d + rad * Math.sin((num - i) * 2d * Math.PI / num))).collect(Collectors.toList());
            Polygon polyIn = new Polygon(hole);
            poly.addHole(polyIn);
            holes.add(hole);
        } else {
            double radSteiner = Math.sqrt(Math.pow(maxX - minX, 2) + Math.pow(maxY - minY, 2)) / 8d;
            // steiner points
            steiner = IntStream.range(0, steinerPoints).mapToObj(i -> new PolygonPoint((maxX + minX) / 2d + radSteiner * Math.cos(i * 2d * Math.PI / steinerPoints), (maxY + minY) / 2d + radSteiner * Math.sin(i * 2d * Math.PI / steinerPoints))).collect(Collectors.toList());
            poly.addSteinerPoints(steiner);
        }
        PolygonSet ps = new PolygonSet(poly);
        Poly2Tri.triangulate(ps);
        Polygon polRes = ps.getPolygons().get(0);
        List<DelaunayTriangle> tri = polRes.getTriangles();
        points1 = polRes.getPoints();
        extPoints = points1.size();
        if (pointsHoles != null || rad > 0d) {
            holes.forEach(hole -> hole.forEach(points1::add));
        } else {
            steiner.forEach(points1::add);
        }
        int totalHolePoints = holePoints.stream().reduce(0, Integer::sum);
        int numPoints = extPoints + steinerPoints + totalHolePoints;
        FloatCollector pointsBottom = points1.stream().flatMapToDouble(p -> DoubleStream.of(p.getX(), p.getY(), 0d)).collect(() -> new FloatCollector(points1.size() * 3), FloatCollector::add, FloatCollector::join);
        FloatCollector pointsTop = points1.stream().flatMapToDouble(p -> DoubleStream.of(p.getX(), p.getY(), height.get())).collect(() -> new FloatCollector(points1.size() * 3), FloatCollector::add, FloatCollector::join);
        pointsBottom.join(pointsTop);
        points0 = pointsBottom.toArray();
        numVertices = points0.length / 3;
        FloatCollector texBottom = points1.stream().flatMapToDouble(p -> DoubleStream.of((p.getX() - minX) / (maxX - minX), (p.getY() - minY) / (maxY - minY))).collect(() -> new FloatCollector(points1.size() * 2), FloatCollector::add, FloatCollector::join);
        FloatCollector texTop = points1.stream().flatMapToDouble(p -> DoubleStream.of((p.getX() - minX) / (maxX - minX), (p.getY() - minY) / (maxY - minY))).collect(() -> new FloatCollector(points1.size() * 2), FloatCollector::add, FloatCollector::join);
        texBottom.join(texTop);
        texCoord0 = texBottom.toArray();
        numTexCoords = texCoord0.length / 2;
        texCoord1 = IntStream.range(0, numTexCoords).mapToObj(i -> new Point2D(texCoord0[2 * i], texCoord0[2 * i + 1])).collect(Collectors.toList());
        List<int[]> listIndices = tri.stream().map((DelaunayTriangle t) -> {
            int[] pIndex = new int[3];
            for (int j = 0; j < 3; j++) {
                final TriangulationPoint dt = t.points[j];
                int[] toArray = IntStream.range(0, points1.size()).filter(i -> points1.get(i).equals(dt)).toArray();
                if (toArray.length > 0) {
                    pIndex[j] = toArray[0];
                } else {
                    System.out.println("Error " + points1);
                }
            }
            return pIndex;
        }).collect(Collectors.toList());
        // faces
        // base
        IntStream streamBottom = listIndices.stream().map(i -> IntStream.of(i[0], i[0], i[2], i[2], i[1], i[1])).flatMapToInt(i -> i);
        // top
        IntStream streamTop = listIndices.stream().map(i -> IntStream.of(numPoints + i[0], numPoints + i[0], numPoints + i[1], numPoints + i[1], numPoints + i[2], numPoints + i[2])).flatMapToInt(i -> i);
        // vertical, exterior
        IntStream streamExtWalls = IntStream.range(0, extPoints - 1).mapToObj(i -> IntStream.of(i, i, i + 1, i + 1, i + 1 + numPoints, i + 1 + numPoints, i, i, i + 1 + numPoints, i + 1 + numPoints, i + numPoints, i + numPoints)).flatMapToInt(i -> i);
        // vertical, exterior, close polygon
        IntStream streamExtWallsClose = IntStream.of(extPoints - 1, extPoints - 1, 0, 0, 0 + numPoints, 0 + numPoints, extPoints - 1, extPoints - 1, 0 + numPoints, 0 + numPoints, numPoints + extPoints - 1, numPoints + extPoints - 1);
        if (totalHolePoints > 0) {
            // vertical, interior
            // holes
            int acuHolePoints0 = extPoints + steinerPoints, acuHolePoints1;
            IntStream streamIntWalls = IntStream.empty();
            for (List<PolygonPoint> hole : holes) {
                acuHolePoints1 = acuHolePoints0 + hole.size() - 1;
                IntStream streamIntWallsHole = IntStream.range(acuHolePoints0, acuHolePoints1).mapToObj(i -> IntStream.of(i, i, i + 1 + numPoints, i + 1 + numPoints, i + 1, i + 1, i, i, i + numPoints, i + numPoints, i + 1 + numPoints, i + 1 + numPoints)).flatMapToInt(i -> i);
                streamIntWalls = IntStream.concat(streamIntWalls, streamIntWallsHole);
                acuHolePoints0 = acuHolePoints1 + 1;
            }
            // vertical, interior, close holes
            // holes
            acuHolePoints0 = extPoints + steinerPoints;
            IntStream streamIntWallsClose = IntStream.empty();
            for (List<PolygonPoint> hole : holes) {
                acuHolePoints1 = acuHolePoints0 + hole.size() - 1;
                IntStream streamIntWallsCloseHole = IntStream.of(acuHolePoints1, acuHolePoints1, numPoints + acuHolePoints0, numPoints + acuHolePoints0, acuHolePoints0, acuHolePoints0, acuHolePoints1, acuHolePoints1, numPoints + acuHolePoints1, numPoints + acuHolePoints1, numPoints + acuHolePoints0, numPoints + acuHolePoints0);
                streamIntWallsClose = IntStream.concat(streamIntWallsClose, streamIntWallsCloseHole);
                acuHolePoints0 = acuHolePoints1 + 1;
            }
            faces0 = IntStream.concat(streamBottom, IntStream.concat(streamTop, IntStream.concat(streamExtWalls, IntStream.concat(streamExtWallsClose, IntStream.concat(streamIntWalls, streamIntWallsClose))))).toArray();
        } else {
            faces0 = IntStream.concat(streamBottom, IntStream.concat(streamTop, IntStream.concat(streamExtWalls, streamExtWallsClose))).toArray();
        }
        numFaces = faces0.length / 6;
    } else if (m0 != null) {
        points0 = new float[numVertices * m0.getPointElementSize()];
        m0.getPoints().toArray(points0);
        texCoord0 = new float[numTexCoords * m0.getTexCoordElementSize()];
        m0.getTexCoords().toArray(texCoord0);
        faces0 = new int[numFaces * m0.getFaceElementSize()];
        m0.getFaces().toArray(faces0);
    }
    List<Point3D> points1 = IntStream.range(0, numVertices).mapToObj(i -> new Point3D(points0[3 * i], points0[3 * i + 1], points0[3 * i + 2])).collect(Collectors.toList());
    texCoord1 = IntStream.range(0, numTexCoords).mapToObj(i -> new Point2D(texCoord0[2 * i], texCoord0[2 * i + 1])).collect(Collectors.toList());
    List<Face3> faces1 = IntStream.range(0, numFaces).mapToObj(i -> new Face3(faces0[6 * i], faces0[6 * i + 2], faces0[6 * i + 4])).collect(Collectors.toList());
    index.set(points1.size());
    map.clear();
    listFaces.clear();
    listVertices.clear();
    listVertices.addAll(points1);
    faces1.forEach(face -> {
        int v1 = face.p0;
        int v2 = face.p1;
        int v3 = face.p2;
        if (level > 0) {
            int a = getMiddle(v1, points1.get(v1), v2, points1.get(v2));
            int b = getMiddle(v2, points1.get(v2), v3, points1.get(v3));
            int c = getMiddle(v3, points1.get(v3), v1, points1.get(v1));
            listFaces.add(new Face3(v1, a, c));
            listFaces.add(new Face3(v2, b, a));
            listFaces.add(new Face3(v3, c, b));
            listFaces.add(new Face3(a, b, c));
        } else {
            listFaces.add(new Face3(v1, v2, v3));
        }
    });
    map.clear();
    numVertices = listVertices.size();
    numFaces = listFaces.size();
    List<Face3> textures1 = IntStream.range(0, faces0.length / 6).mapToObj(i -> new Face3(faces0[6 * i + 1], faces0[6 * i + 3], faces0[6 * i + 5])).collect(Collectors.toList());
    index.set(texCoord1.size());
    listTextures.clear();
    textures1.forEach(face -> {
        int v1 = face.p0;
        int v2 = face.p1;
        int v3 = face.p2;
        if (level > 0) {
            int a = getMiddle(v1, texCoord1.get(v1), v2, texCoord1.get(v2));
            int b = getMiddle(v2, texCoord1.get(v2), v3, texCoord1.get(v3));
            int c = getMiddle(v3, texCoord1.get(v3), v1, texCoord1.get(v1));
            listTextures.add(new Face3(v1, a, c));
            listTextures.add(new Face3(v2, b, a));
            listTextures.add(new Face3(v3, c, b));
            listTextures.add(new Face3(a, b, c));
        } else {
            listTextures.add(new Face3(v1, v2, v3));
        }
    });
    map.clear();
    texCoord0 = texCoord1.stream().flatMapToDouble(p -> DoubleStream.of(p.getX(), p.getY())).collect(() -> new FloatCollector(texCoord1.size() * 2), FloatCollector::add, FloatCollector::join).toArray();
    numTexCoords = texCoord0.length / 2;
    textureCoords = texCoord0;
    if (level == getLevel()) {
        areaMesh.setWidth(maxX - minX);
        areaMesh.setHeight(maxY - minY);
        rectMesh.setWidth((int) Math.sqrt(texCoord0.length));
        rectMesh.setHeight(texCoord0.length / ((int) Math.sqrt(texCoord0.length)));
        smoothingGroups = getSmoothingGroups(listVertices, listFaces);
    }
    return createMesh();
}
Also used : IntStream(java.util.stream.IntStream) HashMap(java.util.HashMap) DoubleProperty(javafx.beans.property.DoubleProperty) IntegerProperty(javafx.beans.property.IntegerProperty) CullFace(javafx.scene.shape.CullFace) TriangleMesh(javafx.scene.shape.TriangleMesh) ArrayList(java.util.ArrayList) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) DelaunayTriangle(org.poly2tri.triangulation.delaunay.DelaunayTriangle) SimpleIntegerProperty(javafx.beans.property.SimpleIntegerProperty) Polygon(org.poly2tri.polygon.Polygon) Point2D(javafx.geometry.Point2D) ObjectProperty(javafx.beans.property.ObjectProperty) FloatCollector(org.fxyz.utils.FloatCollector) PolygonSet(org.poly2tri.polygon.PolygonSet) DrawMode(javafx.scene.shape.DrawMode) Collectors(java.util.stream.Collectors) DoubleStream(java.util.stream.DoubleStream) Poly2Tri(org.poly2tri.Poly2Tri) List(java.util.List) SimpleObjectProperty(javafx.beans.property.SimpleObjectProperty) DepthTest(javafx.scene.DepthTest) Face3(org.fxyz.geometry.Face3) SimpleDoubleProperty(javafx.beans.property.SimpleDoubleProperty) TriangulationPoint(org.poly2tri.triangulation.TriangulationPoint) Collections(java.util.Collections) PolygonPoint(org.poly2tri.polygon.PolygonPoint) Point3D(org.fxyz.geometry.Point3D) Bounds(javafx.geometry.Bounds) TriangulationPoint(org.poly2tri.triangulation.TriangulationPoint) TriangleMesh(javafx.scene.shape.TriangleMesh) FloatCollector(org.fxyz.utils.FloatCollector) DelaunayTriangle(org.poly2tri.triangulation.delaunay.DelaunayTriangle) PolygonPoint(org.poly2tri.polygon.PolygonPoint) PolygonSet(org.poly2tri.polygon.PolygonSet) TriangulationPoint(org.poly2tri.triangulation.TriangulationPoint) PolygonPoint(org.poly2tri.polygon.PolygonPoint) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Point2D(javafx.geometry.Point2D) Point3D(org.fxyz.geometry.Point3D) ArrayList(java.util.ArrayList) List(java.util.List) Polygon(org.poly2tri.polygon.Polygon) IntStream(java.util.stream.IntStream) Face3(org.fxyz.geometry.Face3)

Example 25 with Point2D

use of javafx.geometry.Point2D in project FXyzLib by Birdasaur.

the class CameraController method getMouseDelta.

private Point2D getMouseDelta(MouseEvent event) {
    Point2D res = new Point2D(event.getSceneX() - previousX, event.getSceneY() - previousY);
    previousX = event.getSceneX();
    previousY = event.getSceneY();
    return res;
}
Also used : Point2D(javafx.geometry.Point2D)

Aggregations

Point2D (javafx.geometry.Point2D)29 Point3D (org.fxyz.geometry.Point3D)8 List (java.util.List)7 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)7 Collectors (java.util.stream.Collectors)7 IntStream (java.util.stream.IntStream)7 TriangleMesh (javafx.scene.shape.TriangleMesh)7 Face3 (org.fxyz.geometry.Face3)7 HashMap (java.util.HashMap)6 DoubleStream (java.util.stream.DoubleStream)6 IntegerProperty (javafx.beans.property.IntegerProperty)6 ObjectProperty (javafx.beans.property.ObjectProperty)6 SimpleIntegerProperty (javafx.beans.property.SimpleIntegerProperty)6 SimpleObjectProperty (javafx.beans.property.SimpleObjectProperty)6 DepthTest (javafx.scene.DepthTest)6 CullFace (javafx.scene.shape.CullFace)6 DrawMode (javafx.scene.shape.DrawMode)6 FloatCollector (org.fxyz.utils.FloatCollector)6 DoubleProperty (javafx.beans.property.DoubleProperty)5 SimpleDoubleProperty (javafx.beans.property.SimpleDoubleProperty)5