отсечение MeshView scalafx/javafx

У меня есть следующий тестовый код, где я пытаюсь обрезать MeshView кругом. Я также попытался поместить meshView в группу, а затем обрезать ее, но в результате получился черный круг.

Есть ли способ обрезать MeshView, желательно, не помещая его в группу?

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
  )

person workingdog    schedule 21.07.2015    source источник


Ответы (1)


Отсечение на самом деле работает отлично поверх MeshView, обернутого вокруг Group.

Если вы проверите JavaDoc для setClip():

Существует известное ограничение смешивания клипа с 3D-преобразованием. Отсечение — это, по сути, операция с 2D-изображением. Результат клипа, установленного на узле группы с трехмерно преобразованными дочерними элементами, приведет к тому, что его дочерние элементы будут отображаться по порядку без применения Z-буферизации между этими дочерними элементами.

В результате этого:

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

у вас будет 2D изображение, и вроде Material не применяется. Однако вы можете проверить наличие сетки, установив это:

meshView.setDrawMode(DrawMode.LINE);

Итак, в вашем случае регулировка размеров:

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

даст это:

клип

В конце концов, отсечение не имеет смысла с 3D-фигурами. Для этого вы можете использовать только 2D-форму, чтобы получить желаемый результат.

Если вы хотите 3D-отсечение, взгляните на операции CSG. Проверьте этот вопрос для решения на основе JavaFX.

person José Pereda    schedule 21.07.2015
comment
Я посмотрю на операции CSG. Если я правильно понял ваш ответ, вы говорите, что это невозможно. - person workingdog; 22.07.2015
comment
3D-отсечение будет булевой операцией CSG, так что это можно сделать... Я не сказал, что это невозможно. В вопросе я упоминаю, что у вас есть образец логических операций между трехмерными фигурами с использованием JCSG и FXyz. - person José Pereda; 22.07.2015
comment
Я все еще смотрю на логические операции CSG, я уже использовал FXyz и не знал о CSG. Обе библиотеки хороши. Так как clip() на сетке не работает без разрушения Материала, я придумал обходной путь для отсечения с помощью Shape.subtract. Это почти работает, но есть проблема. Как последовательно получить внешние граничные точки сетки. Я не понимаю общей последовательности точек в сложной сетке, такой как ткань, и поэтому не могу разработать формулу, чтобы выбрать только точки, которые мне нужны для создания многоугольника. gist.github.com/anonymous/49977e526a501905d1fb - person workingdog; 24.07.2015