clipping of MeshView scalafx/javafx

折月煮酒 提交于 2019-12-11 11:14:30

问题


I have the following test code, where I try to clip a MeshView with a circle. I also tried putting the meshView into a group then clipping that, but this result in a black circle.

Is there a way to clip a MeshView, preferably without putting it into a group?

import scalafx.application.JFXApp
import scalafx.application.JFXApp.PrimaryStage
import scalafx.scene.image.Image
import scalafx.scene.paint.{Color, PhongMaterial}
import scalafx.scene.shape.{TriangleMesh, Circle, MeshView}
import scalafx.scene.{Group, PerspectiveCamera, Scene, SceneAntialiasing}

object Test4 extends JFXApp {
  stage = new PrimaryStage {
    scene = new Scene(500, 500, true, SceneAntialiasing.Balanced) {
      fill = Color.LightGray
      val clipCircle = Circle(150.0)
      val meshView = new MeshView(new RectangleMesh(500,500)) {
        // takes a while to load
        material = new PhongMaterial(Color.White, new Image("https://peach.blender.org/wp-content/uploads/bbb-splash.png"), null, null, null)
      }
    //  val meshGroup = new Group(meshView)
      meshView.setClip(clipCircle)
      root = new Group {children = meshView; translateX = 250.0; translateY = 250.0; translateZ = 560.0}
      camera = new PerspectiveCamera(false)
    }
  }
}

class RectangleMesh(Width: Float, Height: Float) extends TriangleMesh {
  points = Array(
    -Width / 2, Height / 2, 0,
    -Width / 2, -Height / 2, 0,
    Width / 2, Height / 2, 0,
    Width / 2, -Height / 2, 0
  )
  texCoords = Array(
    1, 1,
    1, 0,
    0, 1,
    0, 0
  )
  faces = Array(
    2, 2, 1, 1, 0, 0,
    2, 2, 3, 3, 1, 1
  )

回答1:


The clippling actually works fine over the MeshView wrapped around a Group.

If you check JavaDoc for setClip():

There is a known limitation of mixing Clip with a 3D Transform. Clipping is essentially a 2D image operation. The result of a Clip set on a Group node with 3D transformed children will cause its children to be rendered in order without Z-buffering applied between those children.

As a result of this:

Group meshGroup = new Group(meshView);
meshGroup.setClip(clipCircle);

you will have a 2D image, and it seems Material is not applied. However you can check there's a mesh, by seting this:

meshView.setDrawMode(DrawMode.LINE);

So in your case, adjusting dimensions:

@Override
public void start(Stage primaryStage) {
    Circle clipCircle = new Circle(220.0);
    MeshView meshView = new MeshView(new RectangleMesh(400,400));
    meshView.setDrawMode(DrawMode.LINE);
    Group meshGroup = new Group(meshView);
    meshGroup.setClip(clipCircle);
    PerspectiveCamera camera = new PerspectiveCamera(false);

    StackPane root = new StackPane();
    final Circle circle = new Circle(220.0);
    circle.setFill(Color.TRANSPARENT);
    circle.setStroke(Color.RED);
    root.getChildren().addAll(meshGroup, circle);

    Scene scene = new Scene(root, 500, 500, true, SceneAntialiasing.BALANCED);
    scene.setCamera(camera);

    primaryStage.setTitle("Hello World!");
    primaryStage.setScene(scene);
    primaryStage.show();
}

will give this:

In the end, clipping doesn't make sense with 3D shapes. For that you can use just 2D shape to get the result you want.

If you want 3D clipping have a look at CSG operations. Check this question for a JavaFX based solution.



来源:https://stackoverflow.com/questions/31530110/clipping-of-meshview-scalafx-javafx

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!