Problema con l'aggiunta di più mesh triangolari a una scena in javafx


Spero che qualcuno possa aiutarmi con questo problema.

Sto usando javafx e triangle mesh per costruire un oggetto simile a una sfera da triangoli (come un pallone da calcio). Le diverse tessere della forma si distinguono per colore ma voglio aggiungere linee tra le tessere. Come in questo calcio:

Le linee 2D fornite di javafx portano prestazioni terribili nello spazio 3D. Quindi ho trovato il FXyzLib che fornisce un PolyLine3D . Questo è in realtà solo un'altra maglia triangolare che crea una linea in uno spazio 3D.

Con questo posso creare linee 3D. Ma se voglio aggiungerli alla mia maglia triangolare originale, tutto il resto diventa nero. È anche il contrario. Ho sperimentato l'esempio fornito della Libreria trovata qui . Crea una linea 3D di fantasia ma quando ho provato ad aggiungere una semplice sfera di colore rosso alla scena la sfera era solo nera come questa:

questo.

Non sono esperto in questo e nuovo a javafx e non è riuscito a trovare il problema nel codice di PolyLine3D . Non dovrebbe essere un problema aggiungere mesh triangolari mutliple a una scena. Ci sono alcuni effetti di luce o fotocamera di cui non sono a conoscenza?

EDIT: ho risolto il problema. La luce ambientale utilizzata in Polyline3D ha causato il problema. Se aggiungi luce per gli altri oggetti dovrebbe andare bene.

Author: Erdbeer0815, 2018-09-28

1 answers

Mentre non c'è nulla di sbagliato nell'aggiungere più mesh triangolari a una scena, c'è un approccio più semplice quando si desidera creare una mesh come una dall'immagine del calcio, in modo da avere l'effetto di evidenziare alcuni bordi ma non tutti i triangoli dalla mesh.

Può essere fatto con un PolygonMesh che prende qualsiasi poligono chiuso valido come faccia.

Questa implementazione esiste già, nel progetto 3DViewer, che è open source e può essere trovata qui . C'è un controllo PolygonMeshView che può rendere un PolygonMesh.

Nota che se usi queste due classi solo nel tuo progetto, dovrai saltare la mesh di suddivisione per ora.

Questo risposta utilizza già una maglia quadrilatero per un rendering di una scatola senza i bordi diagonali di una maglia triangolo.

Sotto il cofano, la mesh poligonale utilizza una mesh triangolare e converte internamente i poligoni forniti in triangoli.

Troncato Maglia di icosaedro

Quindi possiamo fare qualcosa di simile per generare la mesh di un icosaedro troncato, che è il nome della figura geometrica che possiamo usare per generare un modello di calcio semplificato.

Ha 12 facce pentagonali regolari, 20 facce esagonali regolari e 60 vertici.

Abbiamo bisogno delle coordinate 3D di quei vertici, delle coordinate 2D delle trame e degli indici di vertici e trame per ciascuno dei 32 faccia.

Ho usato la sandbox online gratuita WolframCloud risorsa per recuperare quei valori.

Ad esempio, è possibile eseguire:

Flatten[PolyhedronData["TruncatedIcosahedron","VertexCoordinates"]//N]

Per ottenere l'elenco delle coordinate dei vertici:

Out[1]= {-0.16246,-2.11803,1.27598,-0.16246,2.11803,...}

E, è possibile ottenere le facce:

PolyhedronData["TruncatedIcosahedron","FaceIndices"]
Out[2]= {{53,11,24,23,9},{51,39,40,52,30},...}

Infine, sono necessarie le coordinate e gli indici delle texture, che possono essere recuperati attraverso la rete dell'icosaedro :

PolyhedronData["TruncatedIcosahedron","Net"]
PolyhedronData["TruncatedIcosahedron","NetCoordinates"]

In questo caso, si ottengono le coordinate 2D delle 32 facce. Dato che vogliamo avere la stessa texture per tutti i pentagoni e lo stesso per tutti gli esagoni, ho domato alcune manipolazioni di quelle coordinate per creare questa immagine di texture:

Con solo 9 vertici e le loro coordinate (nel sistema di coordinate JavaFX).

Questo metodo contiene le informazioni necessarie per creare la mesh:

private PolygonMesh getTruncatedIcosahedron() {
    float[] points = new float[]{
        -0.16246f,-2.11803f,1.27598f,       -0.16246f,2.11803f,1.27598f, 
        0.16246f,-2.11803f,-1.27598f,       0.16246f,2.11803f,-1.27598f,
        -0.262866f,-0.809017f,-2.32744f,    -0.262866f,-2.42705f,-0.425325f,
        -0.262866f,0.809017f,-2.32744f,     -0.262866f,2.42705f,-0.425325f,
        0.262866f,-0.809017f,2.32744f,      0.262866f,-2.42705f,0.425325f, 
        0.262866f,0.809017f,2.32744f,       0.262866f,2.42705f,0.425325f,
        0.688191f,-0.5f,-2.32744f,          0.688191f,0.5f,-2.32744f,
        1.21392f,-2.11803f,0.425325f,       1.21392f,2.11803f,0.425325f,
        -2.06457f,-0.5f,1.27598f,           -2.06457f,0.5f,1.27598f,
        -1.37638f,-1.f,1.80171f,            -1.37638f,1.f,1.80171f,
        -1.37638f,-1.61803f,-1.27598f,      -1.37638f,1.61803f,-1.27598f,
        -0.688191f,-0.5f,2.32744f,          -0.688191f,0.5f,2.32744f,
        1.37638f,-1.f,-1.80171f,            1.37638f,1.f,-1.80171f,
        1.37638f,-1.61803f,1.27598f,        1.37638f,1.61803f,1.27598f,
        -1.7013f,0.f,-1.80171f,             1.7013f,0.f,1.80171f,
        -1.21392f,-2.11803f,-0.425325f,     -1.21392f,2.11803f,-0.425325f,
        -1.96417f,-0.809017f,-1.27598f,     -1.96417f,0.809017f,-1.27598f,
        2.06457f,-0.5f,-1.27598f,           2.06457f,0.5f,-1.27598f,
        2.22703f,-1.f,-0.425325f,           2.22703f,1.f,-0.425325f,
        2.38949f,-0.5f,0.425325f,           2.38949f,0.5f,0.425325f,
        -1.11352f,-1.80902f,1.27598f,       -1.11352f,1.80902f,1.27598f,
        1.11352f,-1.80902f,-1.27598f,       1.11352f,1.80902f,-1.27598f,
        -2.38949f,-0.5f,-0.425325f,         -2.38949f,0.5f,-0.425325f,
        -1.63925f,-1.80902f,0.425325f,      -1.63925f,1.80902f,0.425325f,
        1.63925f,-1.80902f,-0.425325f,      1.63925f,1.80902f,-0.425325f,
        1.96417f,-0.809017f,1.27598f,       1.96417f,0.809017f,1.27598f,
        0.850651f,0.f,2.32744f,             -2.22703f,-1.f,0.425325f,
        -2.22703f,1.f,0.425325f,            -0.850651f,0.f,-2.32744f,
        -0.525731f,-1.61803f,-1.80171f,     -0.525731f,1.61803f,-1.80171f,
        0.525731f,-1.61803f,1.80171f,       0.525731f,1.61803f,1.80171f};

    float[] texCoords = new float[]{0.904508f,0.820298f, 0.75f,0.529535f, 0.25f,0.529535f, 0.0954915f,0.820298f, 0.5f,1f, 
                                    1f,0.264767f, 0.75f,0f, 0.25f,0f, 0f,0.264767f};

    int faces[][] = new int[][]{{52,0,10,1,23,2,22,3,8,4},
                        {50,0,38,1,39,2,51,3,29,4},
                        {59,0,27,1,15,2,11,3,1,4},
                        {19,0,41,1,47,2,54,3,17,4},
                        {18,0,16,1,53,2,46,3,40,4},
                        {0,0,9,1,14,2,26,3,58,4},
                        {35,0,25,1,43,2,49,3,37,4},
                        {3,0,57,1,21,2,31,3,7,4},
                        {33,0,28,1,32,2,44,3,45,4},
                        {20,0,56,1,2,2,5,3,30,4},
                        {36,0,48,1,42,2,24,3,34,4},
                        {12,0,4,1,55,2,6,3,13,4},
                        {8,1,58,5,26,6,50,7,29,8,52,2},
                        {52,1,29,5,51,6,27,7,59,8,10,2},
                        {10,1,59,5,1,6,41,7,19,8,23,2},
                        {23,1,19,5,17,6,16,7,18,8,22,2},
                        {22,1,18,5,40,6,0,7,58,8,8,2},
                        {12,1,24,5,42,6,2,7,56,8,4,2},
                        {4,1,56,5,20,6,32,7,28,8,55,2},
                        {55,1,28,5,33,6,21,7,57,8,6,2},
                        {6,1,57,5,3,6,43,7,25,8,13,2},
                        {13,1,25,5,35,6,34,7,24,8,12,2},
                        {39,1,37,5,49,6,15,7,27,8,51,2},
                        {15,1,49,5,43,6,3,7,7,8,11,2},
                        {11,1,7,5,31,6,47,7,41,8,1,2},
                        {47,1,31,5,21,6,33,7,45,8,54,2},
                        {54,1,45,5,44,6,53,7,16,8,17,2},
                        {53,1,44,5,32,6,20,7,30,8,46,2},
                        {46,1,30,5,5,6,9,7,0,8,40,2},
                        {9,1,5,5,2,6,42,7,48,8,14,2},
                        {14,1,48,5,36,6,38,7,50,8,26,2},
                        {38,1,36,5,34,6,35,7,37,8,39,2}};

    int[] smooth = new int[] {
        1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 
        11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 
        21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 
        31, 32
    };

    PolygonMesh mesh = new PolygonMesh(points, texCoords, faces);
    mesh.getFaceSmoothingGroups().addAll(smooth);
    return mesh;
}

Ora puoi aggiungerlo facilmente a una scena:

private double mouseOldX, mouseOldY = 0;
private final Rotate rotateX = new Rotate(0, Rotate.X_AXIS);
private final Rotate rotateY = new Rotate(0, Rotate.Y_AXIS);

@Override
public void start(Stage primaryStage) {

    PolygonMeshView meshView = new PolygonMeshView(getTruncatedIcosahedron());

    final PhongMaterial phongMaterial = new PhongMaterial();
    meshView.setDrawMode(DrawMode.LINE);
    meshView.setMaterial(phongMaterial);
    final Group group = new Group(meshView);
    group.getTransforms().add(new Scale(50, 50, 50));
    Scene scene = new Scene(group, 500, 300, true, SceneAntialiasing.BALANCED);
    scene.setOnMousePressed(event -> {
        mouseOldX = event.getSceneX();
        mouseOldY = event.getSceneY();
    });

    scene.setOnMouseDragged(event -> {
        rotateX.setAngle(rotateX.getAngle() - (event.getSceneY() - mouseOldY));
        rotateY.setAngle(rotateY.getAngle() + (event.getSceneX() - mouseOldX));
        mouseOldX = event.getSceneX();
        mouseOldY = event.getSceneY();
    });

    PerspectiveCamera camera = new PerspectiveCamera(false);
    camera.setNearClip(0.1);
    camera.setFarClip(1000.0);
    camera.getTransforms().addAll(rotateX, rotateY, new Translate(-250, -150, 0));
    scene.setCamera(camera);

    primaryStage.setTitle("JavaFX 3D - Truncated Icosahedron");
    primaryStage.setScene(scene);
    primaryStage.show();
}

Vi darà il wireframe:

wireframe

E se aggiungi l'immagine della texture, otterrai il tuo calcio:

phongMaterial.setDiffuseMap(new Image(getClass().getResourceAsStream("net3.png")));
meshView.setDrawMode(DrawMode.FILL);       

football

Ora tocca a te manipolare a tuo piacimento queste informazioni e modificare questa mesh in quella che stai cercando.

 2
Author: José Pereda, 2018-09-29 13:03:49