use of javafx.scene.shape.TriangleMesh in project FXyzLib by Birdasaur.
the class IcosahedronMesh method createSphere.
private TriangleMesh createSphere(int level, float diameter) {
TriangleMesh m0 = null;
if (level > 0) {
m0 = createSphere(level - 1, diameter);
}
// read vertices from level-1
if (level == 0) {
points0 = baseVertices;
numVertices = baseVertices.length / 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());
// read textures from level -1
if (level == 0) {
texCoord0 = baseTexCoords;
numTexCoords = baseTexCoords.length / 2;
} else if (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());
// read faces from level -1
if (level == 0) {
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) {
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(Math.PI * diameter);
areaMesh.setHeight(Math.PI * diameter);
rectMesh.setWidth((int) Math.sqrt(texCoord0.length));
rectMesh.setHeight(texCoord0.length / ((int) Math.sqrt(texCoord0.length)));
}
return createMesh();
}
use of javafx.scene.shape.TriangleMesh in project FXyzLib by Birdasaur.
the class TrapezoidMesh method createTrapezoid.
private TriangleMesh createTrapezoid(double smallSize, double bigSize, double high, double depth) {
TriangleMesh m = new TriangleMesh();
float s = ((float) smallSize);
float b = ((float) bigSize);
float h = ((float) high);
float d = ((float) depth);
// create Points
m.getPoints().addAll(// A = 0
-s / 2, // A = 0
-h / 2, // A = 0
d / 2, // B = 1
s / 2, // B = 1
-h / 2, // B = 1
d / 2, // C = 2
-b / 2, // C = 2
h / 2, // C = 2
d / 2, // D = 3
b / 2, // D = 3
h / 2, // D = 3
d / 2, // E = 4
-s / 2, // E = 4
-h / 2, // E = 4
-d / 2, // F = 5
s / 2, // F = 5
-h / 2, // F = 5
-d / 2, // G = 6
-b / 2, // G = 6
h / 2, // G = 6
-d / 2, // H = 7
b / 2, // H = 7
h / 2, // H = 7
-d / 2);
m.getTexCoords().addAll(0, 0);
m.getFaces().addAll(// A-B-D
0, // A-B-D
0, // A-B-D
1, // A-B-D
0, // A-B-D
3, // A-B-D
0, // A-D-C
0, // A-D-C
0, // A-D-C
3, // A-D-C
0, // A-D-C
2, // A-D-C
0, // A-C-G
0, // A-C-G
0, // A-C-G
2, // A-C-G
0, // A-C-G
6, // A-C-G
0, // A-G-E
0, // A-G-E
0, // A-G-E
6, // A-G-E
0, // A-G-E
4, // A-G-E
0, // A-E-B
0, // A-E-B
0, // A-E-B
4, // A-E-B
0, // A-E-B
1, // A-E-B
0, // B-E-F
1, // B-E-F
0, // B-E-F
4, // B-E-F
0, // B-E-F
5, // B-E-F
0, // B-F-H
1, // B-F-H
0, // B-F-H
5, // B-F-H
0, // B-F-H
7, // B-F-H
0, // B-H-D
1, // B-H-D
0, // B-H-D
7, // B-H-D
0, // B-H-D
3, // B-H-D
0, // D-H-G
3, // D-H-G
0, // D-H-G
7, // D-H-G
0, // D-H-G
6, // D-H-G
0, // D-G-C
3, // D-G-C
0, // D-G-C
6, // D-G-C
0, // D-G-C
2, // D-G-C
0, // G-H-F
6, // G-H-F
0, // G-H-F
7, // G-H-F
0, // G-H-F
5, // G-H-F
0, // G-F-E
6, // G-F-E
0, // G-F-E
5, // G-F-E
0, // G-F-E
4, // G-F-E
0);
return m;
}
use of javafx.scene.shape.TriangleMesh in project FXyzLib by Birdasaur.
the class Text3DTest 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(800);
camera.setTranslateZ(-3000);
// cameraTransform.ry.setAngle(-25.0);
cameraTransform.rx.setAngle(10.0);
// add a Point Light for better viewing of the grid coordinate system
// PointLight light1 = new PointLight(Color.WHITE);
cameraTransform.getChildren().add(new AmbientLight());
scene.setCamera(camera);
Group group = new Group(cameraTransform);
Text3DMesh letters = new Text3DMesh("3DMesh", "Gadugi Bold", 400, true, 120, 0, 1);
// letters.setDrawMode(DrawMode.LINE);
// NONE
// letters.setTextureModeNone(Color.ROYALBLUE);
// IMAGE
// letters.setTextureModeImage(getClass().getResource("res/steel-background1.jpg").toExternalForm());
// letters.setTextureModeImage(getClass().getResource("res/marvel1.jpg").toExternalForm());
// DENSITY
letters.setTextureModeVertices3D(1530, p -> p.magnitude());
// letters.setTextureModeVertices3D(1530,p->Math.sin(p.y/50)*Math.cos(p.x/40)*p.z);
// FACES
// letters.setTextureModeFaces(Palette.ColorPalette.HSB,16);
group.getChildren().add(letters);
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 - Text3D");
primaryStage.setScene(scene);
primaryStage.show();
// Letter transformations
IntStream.range(0, letters.getChildren().size()).forEach(i -> {
double y = (((double) i) / ((double) letters.getChildren().size()) * 3d * Math.PI);
((TexturedMesh) (letters.getChildren().get(i))).getTranslate().setY(100d * Math.sin(y));
// ((TexturedMesh)(letters.getChildren().get(i))).getRotateZ().setAngle(Math.cos(y)*180d/Math.PI);
// ((TexturedMesh)(letters.getChildren().get(i))).getRotateX().setAngle(Math.cos(y)*180d/Math.PI);
});
// Letter animations
final Timeline rotateEffect1 = new Timeline();
rotateEffect1.setCycleCount(Timeline.INDEFINITE);
TexturedMesh t0 = letters.getMeshFromLetter("M");
final KeyValue kv1 = new KeyValue(t0.getRotateY().angleProperty(), 360);
final KeyFrame kf1 = new KeyFrame(Duration.millis(3000), kv1);
rotateEffect1.getKeyFrames().addAll(kf1);
rotateEffect1.play();
final Timeline rotateEffect2 = new Timeline();
TexturedMesh t1 = letters.getMeshFromLetter("3");
final KeyValue kv2 = new KeyValue(t1.getRotateX().angleProperty(), 360);
final KeyFrame kf2 = new KeyFrame(Duration.millis(2000), kv2);
rotateEffect2.getKeyFrames().addAll(kf2);
rotateEffect2.play();
//
final Timeline rotateEffect3 = new Timeline();
rotateEffect3.setCycleCount(Timeline.INDEFINITE);
TexturedMesh t5 = letters.getMeshFromLetter("h");
final KeyValue kv1x = new KeyValue(t5.getScale().xProperty(), 1.2, Interpolator.EASE_BOTH);
final KeyValue kv1y = new KeyValue(t5.getScale().yProperty(), 1.2, Interpolator.EASE_BOTH);
final KeyValue kv1z = new KeyValue(t5.getScale().zProperty(), 1.2, Interpolator.EASE_BOTH);
final KeyFrame kfs1 = new KeyFrame(Duration.millis(500), kv1x, kv1y, kv1z);
final KeyValue kv2x = new KeyValue(t5.getScale().xProperty(), 0.3, Interpolator.EASE_BOTH);
final KeyValue kv2y = new KeyValue(t5.getScale().yProperty(), 0.3, Interpolator.EASE_BOTH);
final KeyValue kv2z = new KeyValue(t5.getScale().zProperty(), 0.3, Interpolator.EASE_BOTH);
final KeyFrame kfs2 = new KeyFrame(Duration.millis(2000), kv2x, kv2y, kv2z);
final KeyValue kv3x = new KeyValue(t5.getScale().xProperty(), 1, Interpolator.EASE_BOTH);
final KeyValue kv3y = new KeyValue(t5.getScale().yProperty(), 1, Interpolator.EASE_BOTH);
final KeyValue kv3z = new KeyValue(t5.getScale().zProperty(), 1, Interpolator.EASE_BOTH);
final KeyFrame kfs3 = new KeyFrame(Duration.millis(3000), kv3x, kv3y, kv3z);
rotateEffect3.getKeyFrames().addAll(kfs1, kfs2, kfs3);
rotateEffect3.play();
lastEffect = System.nanoTime();
AtomicInteger count = new AtomicInteger(1);
AnimationTimer timerEffect = new AnimationTimer() {
@Override
public void handle(long now) {
if (now > lastEffect + 1_000_000_000l) {
System.out.println("*** " + count.get());
letters.setFont(Font.getFontNames().get(count.get() % Font.getFontNames().size()));
if (count.get() % 10 < 2) {
letters.setTextureModeNone(Color.hsb(count.get() % 360, 1, 1));
} else if (count.get() % 10 < 4) {
letters.setTextureModeImage(getClass().getResource("res/steel-background1.jpg").toExternalForm());
} else if (count.get() % 10 < 8) {
letters.setTextureModeVertices3D(1530, p -> (double) (p.y / (20 + count.get() % 20)) * (p.x / (10 + count.get() % 10)));
} else {
letters.setTextureModeFaces(1530);
}
if (count.get() % 20 > 15) {
letters.setDrawMode(DrawMode.LINE);
} else {
letters.setDrawMode(DrawMode.FILL);
}
letters.getChildren().forEach(m -> ((TexturedMesh) m).setDensity(p -> p.magnitude() * Math.cos(p.y / 100d * (count.get() % 5))));
count.getAndIncrement();
lastEffect = now;
}
}
};
// timerEffect.start();
OBJWriter writer = new OBJWriter((TriangleMesh) ((TexturedMesh) (letters.getChildren().get(0))).getMesh(), "letter");
writer.setTextureColors(6);
// writer.setTexturePattern();
// writer.setTextureImage(getClass().getResource("res/LaminateSteel.jpg").toExternalForm());
writer.exportMesh();
}
use of javafx.scene.shape.TriangleMesh in project FXyzLib by Birdasaur.
the class MeshUtils method mesh2CSG.
public static CSG mesh2CSG(Mesh mesh) throws IOException {
List<Polygon> polygons = new ArrayList<>();
List<Vector3d> vertices = new ArrayList<>();
if (mesh instanceof TriangleMesh) {
// Get faces
ObservableFaceArray faces = ((TriangleMesh) mesh).getFaces();
int[] f = new int[faces.size()];
faces.toArray(f);
// Get vertices
ObservableFloatArray points = ((TriangleMesh) mesh).getPoints();
float[] p = new float[points.size()];
points.toArray(p);
// convert faces to polygons
for (int i = 0; i < faces.size() / 6; i++) {
int i0 = f[6 * i], i1 = f[6 * i + 2], i2 = f[6 * i + 4];
vertices.add(new Vector3d(p[3 * i0], p[3 * i0 + 1], p[3 * i0 + 2]));
vertices.add(new Vector3d(p[3 * i1], p[3 * i1 + 1], p[3 * i1 + 2]));
vertices.add(new Vector3d(p[3 * i2], p[3 * i2 + 1], p[3 * i2 + 2]));
polygons.add(Polygon.fromPoints(vertices));
vertices = new ArrayList<>();
}
}
return CSG.fromPolygons(new PropertyStorage(), polygons);
}
use of javafx.scene.shape.TriangleMesh in project FXyzLib by Birdasaur.
the class MeshUtils method mesh2STL.
public static void mesh2STL(String fileName, Mesh mesh) throws IOException {
if (!(mesh instanceof TriangleMesh)) {
return;
}
// Get faces
ObservableFaceArray faces = ((TriangleMesh) mesh).getFaces();
int[] f = new int[faces.size()];
faces.toArray(f);
// Get vertices
ObservableFloatArray points = ((TriangleMesh) mesh).getPoints();
float[] p = new float[points.size()];
points.toArray(p);
StringBuilder sb = new StringBuilder();
sb.append("solid meshFX\n");
// convert faces to polygons
for (int i = 0; i < faces.size() / 6; i++) {
int i0 = f[6 * i], i1 = f[6 * i + 2], i2 = f[6 * i + 4];
Point3D pA = new Point3D(p[3 * i0], p[3 * i0 + 1], p[3 * i0 + 2]);
Point3D pB = new Point3D(p[3 * i1], p[3 * i1 + 1], p[3 * i1 + 2]);
Point3D pC = new Point3D(p[3 * i2], p[3 * i2 + 1], p[3 * i2 + 2]);
Point3D pN = pB.subtract(pA).crossProduct(pC.subtract(pA)).normalize();
sb.append(" facet normal ").append(pN.getX()).append(" ").append(pN.getY()).append(" ").append(pN.getZ()).append("\n");
sb.append(" outer loop\n");
sb.append(" vertex ").append(pA.getX()).append(" ").append(pA.getY()).append(" ").append(pA.getZ()).append("\n");
sb.append(" vertex ").append(pB.getX()).append(" ").append(pB.getY()).append(" ").append(pB.getZ()).append("\n");
sb.append(" vertex ").append(pC.getX()).append(" ").append(pC.getY()).append(" ").append(pC.getZ()).append("\n");
sb.append(" endloop\n");
sb.append(" endfacet\n");
}
sb.append("endsolid meshFX\n");
// write file
try (BufferedWriter writer = Files.newBufferedWriter(Paths.get(fileName), Charset.forName("UTF-8"), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)) {
writer.write(sb.toString());
}
}
Aggregations