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();
}
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();
}
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();
}
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();
}
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();
}
Aggregations