Warum wird die diffuse Karte nicht auf mein MeshView angewendet?
Proble
Ich möchte eine diffuse Karte auf eine MeshView anwenden. Wenn ich ein Material mit der diffusen Karte auf das MeshView anwende, ist es nicht sichtbar. Das gleiche Material, das auf eine Box angewendet wurde, ist jedoch sichtbar.
Frag
Was muss ich tun, um eine diffuse Karte auf eine MeshView anzuwenden?
Cod
Der Code generiert ein Bild mit zufälligem Rauschen. Das Bild wird als diffuse Karte in einem PhongMaterial verwendet. Das Bild wird angezeigt, darüber die Box mit dem angewendeten Material und darüber die MeshView (eine Pyramide) mit dem angewendeten Material. Das Material ist auf der Pyramide nicht sichtbar. Sie können die Maus zum Drehen ziehen.
import java.util.Random;
import javafx.application.Application;
import javafx.geometry.Point3D;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.Scene;
import javafx.scene.SceneAntialiasing;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.image.PixelWriter;
import javafx.scene.image.WritableImage;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Box;
import javafx.scene.shape.DrawMode;
import javafx.scene.shape.MeshView;
import javafx.scene.shape.TriangleMesh;
import javafx.scene.transform.Rotate;
import javafx.stage.Stage;
public class Test extends Application {
private double mousePosX, mousePosY;
private double mouseOldX, mouseOldY;
private final Rotate rotateX = new Rotate(20, Rotate.X_AXIS);
private final Rotate rotateY = new Rotate(-45, Rotate.Y_AXIS);
@Override
public void start(Stage primaryStage) {
// cube
Group group = new Group();
// size of the cube
double size = 400;
group.getTransforms().addAll(rotateX, rotateY);
Image diffuseMap = createImage( size);
// show noise image
ImageView iv = new ImageView( diffuseMap);
iv.setTranslateX(-0.5*size);
iv.setTranslateY(-0.20*size);
iv.setRotate(90);
iv.setRotationAxis(new Point3D(1,0,0));
group.getChildren().add( iv);
// create material out of the noise image
PhongMaterial material = new PhongMaterial();
material.setDiffuseMap(diffuseMap);
// create box with noise diffuse map
Box box = new Box( 100,100,100);
box.setMaterial(material);
group.getChildren().add( box);
// create pyramid with diffuse map
float h = 150; // Height
float s = 150; // Side
TriangleMesh pyramidMesh = new TriangleMesh();
pyramidMesh.getTexCoords().addAll(1,1,1,0,0,1,0,0);
pyramidMesh.getPoints().addAll(
0, 0, 0, // Point 0 - Top
0, h, -s/2, // Point 1 - Front
-s/2, h, 0, // Point 2 - Left
s/2, h, 0, // Point 3 - Back
0, h, s/2 // Point 4 - Right
);
pyramidMesh.getFaces().addAll(
0,0, 2,0, 1,0, // Front left face
0,0, 1,0, 3,0, // Front right face
0,0, 3,0, 4,0, // Back right face
0,0, 4,0, 2,0, // Back left face
4,0, 1,0, 2,0, // Bottom rear face
4,0, 3,0, 1,0 // Bottom front face
);
MeshView pyramid = new MeshView(pyramidMesh);
pyramid.setDrawMode(DrawMode.FILL);
pyramid.setTranslateY(-250);
// apply material
// TODO: why is the diffuse map not displayed?
pyramid.setMaterial(material);
group.getChildren().add(pyramid);
// scene
StackPane root = new StackPane();
root.getChildren().add(group);
Scene scene = new Scene(root, 1600, 900, true, SceneAntialiasing.BALANCED);
scene.setCamera(new PerspectiveCamera());
// interaction listeners
scene.setOnMousePressed(me -> {
mouseOldX = me.getSceneX();
mouseOldY = me.getSceneY();
});
scene.setOnMouseDragged(me -> {
mousePosX = me.getSceneX();
mousePosY = me.getSceneY();
rotateX.setAngle(rotateX.getAngle()-(mousePosY - mouseOldY));
rotateY.setAngle(rotateY.getAngle()+(mousePosX - mouseOldX));
mouseOldX = mousePosX;
mouseOldY = mousePosY;
});
primaryStage.setResizable(false);
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* Create image with random noise
*/
public Image createImage( double size) {
Random rnd = new Random();
int width = (int) size;
int height = (int) size;
WritableImage wr = new WritableImage(width, height);
PixelWriter pw = wr.getPixelWriter();
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
Color color = Color.rgb(rnd.nextInt( 256), rnd.nextInt( 256), rnd.nextInt( 256));
pw.setColor(x, y, color);
}
}
return wr;
}
public static void main(String[] args) {
launch(args);
}
}
Bildschirmfot
Vielen Dank für die Hilfe!