Search in sources :

Example 1 with Point3D

use of org.fxyz.geometry.Point3D in project FXyzLib by Birdasaur.

the class TriangleMeshHelper method updateFacesWithIntersections.

/*
    Based on Fast, Minimum Storage Ray/Triangle Intersection
    Tomas Möller & Ben Trumbore
    http://www.graphics.cornell.edu/pubs/1997/MT97.pdf

    * origin and direction of a ray, in local coordinates of the shape, 
      to avoid transformation all the triangles to scene coordinates
      
    * This sets the texture of every face: 0 without intersection, 1 intersected
    */
public int[] updateFacesWithIntersections(Point3D origin, Point3D direction, List<Point3D> points, List<Face3> faces) {
    return faces.parallelStream().map(f -> {
        Point3D a = points.get(f.p0);
        Point3D b = points.get(f.p1);
        Point3D c = points.get(f.p2);
        Point3D edge1 = b.substract(a);
        Point3D edge2 = c.substract(a);
        Point3D pvec = direction.crossProduct(edge2);
        float det = edge1.dotProduct(pvec);
        int t0 = 0;
        if (det <= -EPS || det >= EPS) {
            float inv_det = 1f / det;
            Point3D tvec = origin.substract(a);
            float u = tvec.dotProduct(pvec) * inv_det;
            if (u >= 0f && u <= 1f) {
                Point3D qvec = tvec.crossProduct(edge1);
                float v = direction.dotProduct(qvec) * inv_det;
                if (v >= 0 && u + v <= 1f) {
                    // float t = c.dotProduct(qvec)*inv_det;
                    t0 = 6;
                // System.out.println("t: "+t+", u: "+u+", v: "+v+" (a: "+a+", b: "+b+", c: "+c+")");
                }
            }
        }
        return f.getFace(t0);
    }).flatMapToInt(i -> i).toArray();
}
Also used : IntStream(java.util.stream.IntStream) Color(javafx.scene.paint.Color) FloatCollector(org.fxyz.utils.FloatCollector) Palette(org.fxyz.utils.Palette) CarbonPatterns(org.fxyz.utils.Patterns.CarbonPatterns) Material(javafx.scene.paint.Material) Function(java.util.function.Function) Collectors(java.util.stream.Collectors) List(java.util.List) NormalMap(org.fxyz.utils.NormalMap) PhongMaterial(javafx.scene.paint.PhongMaterial) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Face3(org.fxyz.geometry.Face3) ColorPalette(org.fxyz.utils.Palette.ColorPalette) Patterns(org.fxyz.utils.Patterns) Image(javafx.scene.image.Image) Point3D(org.fxyz.geometry.Point3D) Point3D(org.fxyz.geometry.Point3D)

Example 2 with Point3D

use of org.fxyz.geometry.Point3D in project FXyzLib by Birdasaur.

the class TriangleMeshHelper method getMeshArea.

/*
    utils
    */
public double getMeshArea(List<Point3D> points, List<Face3> faces) {
    return faces.parallelStream().mapToDouble(f -> {
        Point3D a = points.get(f.p0);
        Point3D b = points.get(f.p1);
        Point3D c = points.get(f.p2);
        return b.substract(a).crossProduct((c.substract(a))).magnitude() / 2.0;
    }).reduce(Double::sum).getAsDouble();
}
Also used : Point3D(org.fxyz.geometry.Point3D)

Example 3 with Point3D

use of org.fxyz.geometry.Point3D in project FXyzLib by Birdasaur.

the class CSVScatter3DTest method start.

@Override
public void start(Stage primaryStage) throws Exception {
    Group sceneRoot = new Group();
    Scene scene = new Scene(sceneRoot, sceneWidth, sceneHeight, true, SceneAntialiasing.BALANCED);
    scene.setFill(Color.BLACK);
    camera = new PerspectiveCamera(true);
    // setup camera transform for rotational support
    cameraTransform.setTranslate(0, 0, 0);
    cameraTransform.getChildren().add(camera);
    camera.setNearClip(0.1);
    camera.setFarClip(10000.0);
    camera.setTranslateX(0);
    camera.setTranslateZ(-1000);
    cameraTransform.ry.setAngle(-25.0);
    cameraTransform.rx.setAngle(-10.0);
    // add a Point Light for better viewing of the grid coordinate system
    PointLight light = new PointLight(Color.WHITE);
    cameraTransform.getChildren().add(new AmbientLight());
    light.setTranslateX(camera.getTranslateX());
    light.setTranslateY(camera.getTranslateY());
    light.setTranslateZ(camera.getTranslateZ());
    scene.setCamera(camera);
    long time = System.currentTimeMillis();
    Group group = new Group(cameraTransform);
    List<Point3D> data = new ArrayList<>();
    // // create some data
    // IntStream.range(0,100000)
    // .forEach(i->data.add(new Point3D((float)(30*Math.sin(50*i)),
    // (float)(Math.sin(i)*(100+30*Math.cos(100*i))),
    // (float)(Math.cos(i)*(100+30*Math.cos(200*i))),
    // i))); // <-- f
    // // and write to csv file
    // Path out = Paths.get("output.txt");
    // Files.write(out,data.stream().map(p3d->p3d.toCSV()).collect(Collectors.toList()),Charset.defaultCharset());
    // read from csv file
    Path out = getCSVFile(0);
    if (out != null) {
        Files.lines(out).map(s -> s.split(";")).forEach(s -> data.add(new Point3D(Float.parseFloat(s[0]), Float.parseFloat(s[1]), Float.parseFloat(s[2]), Float.parseFloat(s[3]))));
    }
    ScatterMesh scatter = new ScatterMesh(data, true, 1, 0);
    // DENSITY
    // texture is given by p.f value, don't change this!
    scatter.setTextureModeVertices3D(1530, p -> p.f);
    group.getChildren().add(scatter);
    sceneRoot.getChildren().addAll(group);
    // First person shooter keyboard movement
    scene.setOnKeyPressed(event -> {
        double change = 10.0;
        // Add shift modifier to simulate "Running Speed"
        if (event.isShiftDown()) {
            change = 50.0;
        }
        // What key did the user press?
        KeyCode keycode = event.getCode();
        // Step 2c: Add Zoom controls
        if (keycode == KeyCode.W) {
            camera.setTranslateZ(camera.getTranslateZ() + change);
        }
        if (keycode == KeyCode.S) {
            camera.setTranslateZ(camera.getTranslateZ() - change);
        }
        // Step 2d:  Add Strafe controls
        if (keycode == KeyCode.A) {
            camera.setTranslateX(camera.getTranslateX() - change);
        }
        if (keycode == KeyCode.D) {
            camera.setTranslateX(camera.getTranslateX() + change);
        }
    });
    scene.setOnMousePressed((MouseEvent me) -> {
        mousePosX = me.getSceneX();
        mousePosY = me.getSceneY();
        mouseOldX = me.getSceneX();
        mouseOldY = me.getSceneY();
    });
    scene.setOnMouseDragged((MouseEvent me) -> {
        mouseOldX = mousePosX;
        mouseOldY = mousePosY;
        mousePosX = me.getSceneX();
        mousePosY = me.getSceneY();
        mouseDeltaX = (mousePosX - mouseOldX);
        mouseDeltaY = (mousePosY - mouseOldY);
        double modifier = 10.0;
        double modifierFactor = 0.1;
        if (me.isControlDown()) {
            modifier = 0.1;
        }
        if (me.isShiftDown()) {
            modifier = 50.0;
        }
        if (me.isPrimaryButtonDown()) {
            // +
            cameraTransform.ry.setAngle(((cameraTransform.ry.getAngle() + mouseDeltaX * modifierFactor * modifier * 2.0) % 360 + 540) % 360 - 180);
            // -
            cameraTransform.rx.setAngle(((cameraTransform.rx.getAngle() - mouseDeltaY * modifierFactor * modifier * 2.0) % 360 + 540) % 360 - 180);
        } else if (me.isSecondaryButtonDown()) {
            double z = camera.getTranslateZ();
            double newZ = z + mouseDeltaX * modifierFactor * modifier;
            camera.setTranslateZ(newZ);
        } else if (me.isMiddleButtonDown()) {
            // -
            cameraTransform.t.setX(cameraTransform.t.getX() + mouseDeltaX * modifierFactor * modifier * 0.3);
            // -
            cameraTransform.t.setY(cameraTransform.t.getY() + mouseDeltaY * modifierFactor * modifier * 0.3);
        }
    });
    primaryStage.setTitle("F(X)yz - ScatterMesh Test");
    primaryStage.setScene(scene);
    primaryStage.show();
    final boolean constantVertices = true;
    lastEffect = System.nanoTime();
    AtomicInteger count = new AtomicInteger(0);
    List<List<Number>> fullData = new ArrayList<>();
    if (constantVertices) {
        // if possible we can cache all the data
        Stream.of(0, 1, 2, 3, 4, 3, 2, 1).forEach(i -> {
            Path out2 = getCSVFile(i);
            if (out2 != null) {
                try {
                    List<Number> data2 = new ArrayList<>();
                    Files.lines(out2).map(s -> s.split(";")).forEach(s -> {
                        float f = Float.parseFloat(s[3]);
                        // 4 vertices tetrahedra
                        data2.add(f);
                        data2.add(f);
                        data2.add(f);
                        data2.add(f);
                    });
                    fullData.add(data2);
                } catch (IOException ex) {
                }
            }
        });
    }
    AnimationTimer timerEffect = new AnimationTimer() {

        @Override
        public void handle(long now) {
            if (now > lastEffect + 50_000_000l) {
                try {
                    // long t=System.currentTimeMillis();
                    if (constantVertices && fullData != null) {
                        // Vertices coordinates are always the same: mesh is tha same, we only
                        // need to update F on each element
                        scatter.setFunctionData(fullData.get(count.get() % 8));
                    // System.out.println("t "+(System.currentTimeMillis()-t));
                    } else {
                        // vertices coordinates may change in time, we need to create them all over again reading the files:
                        Path out2 = getCSVFile((int) (Stream.of(0, 1, 2, 3, 4, 3, 2, 1).toArray()[count.get() % 8]));
                        if (out2 != null) {
                            List<Point3D> data2 = new ArrayList<>();
                            Files.lines(out2).map(s -> s.split(";")).forEach(s -> data2.add(new Point3D(Float.parseFloat(s[0]), Float.parseFloat(s[1]), Float.parseFloat(s[2]), Float.parseFloat(s[3]))));
                            scatter.setScatterData(data2);
                            scatter.setTextureModeVertices1D(1530, p -> p);
                        }
                    // System.out.println("t "+(System.currentTimeMillis()-t));
                    }
                } catch (IOException ex) {
                }
                count.getAndIncrement();
                lastEffect = now;
            }
        }
    };
    timerEffect.start();
}
Also used : Path(java.nio.file.Path) Scene(javafx.scene.Scene) ScatterMesh(org.fxyz.shapes.primitives.ScatterMesh) Palette(org.fxyz.utils.Palette) URISyntaxException(java.net.URISyntaxException) MouseEvent(javafx.scene.input.MouseEvent) PointLight(javafx.scene.PointLight) ArrayList(java.util.ArrayList) Application(javafx.application.Application) PerspectiveCamera(javafx.scene.PerspectiveCamera) CameraTransformer(org.fxyz.cameras.CameraTransformer) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Path(java.nio.file.Path) KeyCode(javafx.scene.input.KeyCode) Color(javafx.scene.paint.Color) Files(java.nio.file.Files) IOException(java.io.IOException) Group(javafx.scene.Group) AnimationTimer(javafx.animation.AnimationTimer) List(java.util.List) Stream(java.util.stream.Stream) Stage(javafx.stage.Stage) Paths(java.nio.file.Paths) SceneAntialiasing(javafx.scene.SceneAntialiasing) Point3D(org.fxyz.geometry.Point3D) AmbientLight(javafx.scene.AmbientLight) Group(javafx.scene.Group) MouseEvent(javafx.scene.input.MouseEvent) AnimationTimer(javafx.animation.AnimationTimer) ArrayList(java.util.ArrayList) PerspectiveCamera(javafx.scene.PerspectiveCamera) IOException(java.io.IOException) Scene(javafx.scene.Scene) ScatterMesh(org.fxyz.shapes.primitives.ScatterMesh) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Point3D(org.fxyz.geometry.Point3D) KeyCode(javafx.scene.input.KeyCode) ArrayList(java.util.ArrayList) List(java.util.List) PointLight(javafx.scene.PointLight) AmbientLight(javafx.scene.AmbientLight)

Example 4 with Point3D

use of org.fxyz.geometry.Point3D in project FXyzLib by Birdasaur.

the class SurfacePlotMesh method createPlotMesh.

private TriangleMesh createPlotMesh(Function<Point2D, Number> function2D, double rangeX, double rangeY, int divisionsX, int divisionsY, double scale) {
    listVertices.clear();
    listTextures.clear();
    listFaces.clear();
    int numDivX = divisionsX + 1;
    float pointY;
    areaMesh.setWidth(rangeX);
    areaMesh.setHeight(rangeY);
    // Create points
    for (int y = 0; y <= divisionsY; y++) {
        float dy = (float) (-rangeY / 2d + ((float) y / (float) divisionsY) * rangeY);
        for (int x = 0; x <= divisionsX; x++) {
            float dx = (float) (-rangeX / 2d + ((float) x / (float) divisionsX) * rangeX);
            pointY = (float) scale * function2D.apply(new Point2D(dx, dy)).floatValue();
            listVertices.add(new Point3D(dx, pointY, dy));
        }
    }
    // Create texture coordinates
    createTexCoords(divisionsX, divisionsY);
    // Create textures indices
    for (int y = 0; y < divisionsY; y++) {
        for (int x = 0; x < divisionsX; x++) {
            int p00 = y * numDivX + x;
            int p01 = p00 + 1;
            int p10 = p00 + numDivX;
            int p11 = p10 + 1;
            listTextures.add(new Face3(p00, p10, p11));
            listTextures.add(new Face3(p11, p01, p00));
        }
    }
    // Create faces indices
    for (int y = 0; y < divisionsY; y++) {
        for (int x = 0; x < divisionsX; x++) {
            int p00 = y * numDivX + x;
            int p01 = p00 + 1;
            int p10 = p00 + numDivX;
            int p11 = p10 + 1;
            listFaces.add(new Face3(p00, p10, p11));
            listFaces.add(new Face3(p11, p01, p00));
        }
    }
    return createMesh();
}
Also used : Point2D(javafx.geometry.Point2D) Point3D(org.fxyz.geometry.Point3D) Face3(org.fxyz.geometry.Face3)

Example 5 with Point3D

use of org.fxyz.geometry.Point3D in project FXyzLib by Birdasaur.

the class TexturedMesh method createMesh.

protected TriangleMesh createMesh(MeshHelper mh) {
    float[] points0 = mh.getPoints();
    float[] f = mh.getF();
    listVertices.clear();
    listVertices.addAll(IntStream.range(0, points0.length / 3).mapToObj(i -> new Point3D(points0[3 * i], points0[3 * i + 1], points0[3 * i + 2], f[i])).collect(Collectors.toList()));
    textureCoords = mh.getTexCoords();
    int[] faces0 = mh.getFaces();
    listFaces.clear();
    listFaces.addAll(IntStream.range(0, faces0.length / 6).mapToObj(i -> new Face3(faces0[6 * i + 0], faces0[6 * i + 2], faces0[6 * i + 4])).collect(Collectors.toList()));
    listTextures.clear();
    // listTextures.addAll(listFaces);
    listTextures.addAll(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()));
    smoothingGroups = mh.getFaceSmoothingGroups();
    return createMesh();
}
Also used : Point3D(org.fxyz.geometry.Point3D) Face3(org.fxyz.geometry.Face3)

Aggregations

Point3D (org.fxyz.geometry.Point3D)48 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)16 List (java.util.List)12 Face3 (org.fxyz.geometry.Face3)12 Collectors (java.util.stream.Collectors)10 IntStream (java.util.stream.IntStream)10 Group (javafx.scene.Group)10 Translate (javafx.scene.transform.Translate)10 ArrayList (java.util.ArrayList)9 Point2D (javafx.geometry.Point2D)9 PerspectiveCamera (javafx.scene.PerspectiveCamera)9 Scene (javafx.scene.Scene)9 KeyCode (javafx.scene.input.KeyCode)9 TriangleMesh (javafx.scene.shape.TriangleMesh)9 Rotate (javafx.scene.transform.Rotate)9 PointLight (javafx.scene.PointLight)8 MouseEvent (javafx.scene.input.MouseEvent)8 DoubleProperty (javafx.beans.property.DoubleProperty)7 IntegerProperty (javafx.beans.property.IntegerProperty)7 SimpleDoubleProperty (javafx.beans.property.SimpleDoubleProperty)7