带有鼠标事件的轮廓 Shape3d javafx

Gio*_*ras 2 java 3d javafx javafx-3d

许多 3d 程序使用轮廓来提示用户选择 3d 对象。

有没有办法模仿 javafx 中的这种行为?

Gio*_*ras 6

带有比例缩放 3D 对象且正面被剔除的轮廓

javafx 中的 culledfaces

在这种做法下。PickResult当鼠标在节点上输入时, 3d 对象会使用节点的类类型进行实例化Group,该对象具有与所选对象相同的大小和相同的平移(在本例中只是 x 轴),但略有缩放(1.1)。因此,3d 对象更大,并且位于同一位置,但不与下面的 shape3d 重叠,因为任何朝向相机的面部都会被Culface.FRONT枚举剔除Shape3d.setCullFace()。最后,当鼠标退出 pickresult 节点时,3d 对象将从组的子对象中删除,从而允许下一次迭代。这是一个单类功能性 javafx 应用程序,您可以尝试一下

应用程序.java

public class App extends Application {

    private Shape3D outLine;

    @Override
    public void start(Stage stage) {
        Shape3D sphere = new Sphere(0.45);
        PhongMaterial sMaterial = new PhongMaterial(Color.CORAL);
        sphere.setMaterial(sMaterial);
        sphere.setTranslateX(-1.1);
        Shape3D box = new Box(0.9, 0.9, 0.9);
        box.setTranslateX(1.1);
        box.setMaterial(new PhongMaterial(Color.PALEGREEN));
        Shape3D cylinder = new Cylinder(0.45, 0.8);
        cylinder.setMaterial(new PhongMaterial(Color.PALEVIOLETRED));
        PerspectiveCamera camera = new PerspectiveCamera(true);
        camera.setTranslateZ(-5.5);

        Group group3d = new Group(camera, box, sphere, cylinder);

        Scene scene = new Scene(group3d, 640, 480, true, SceneAntialiasing.BALANCED);
        group3d.setOnMouseExited((t) -> {
            group3d.getChildren().remove(outLine);
        });
        group3d.setOnMouseEntered((t) -> {

            PickResult pickResult = t.getPickResult();
            Node intersectedNode = pickResult.getIntersectedNode();

            if (intersectedNode instanceof Sphere) {

                outLine = new Sphere(((Sphere) intersectedNode).getRadius());
                outLine.setTranslateX(intersectedNode.getTranslateX());
                group3d.getChildren().add(outLine);

                outLine.setCullFace(CullFace.FRONT);
                outLine.setScaleX(1.1);
                outLine.setScaleY(1.1);
                outLine.setScaleZ(1.1);

            }
            if (intersectedNode instanceof Cylinder) {
                Cylinder c = (Cylinder) intersectedNode;
                outLine = new Cylinder(c.getRadius(), c.getHeight(), c.getDivisions());
                outLine.setTranslateX(c.getTranslateX());
                group3d.getChildren().add(outLine);

                outLine.setCullFace(CullFace.FRONT);
                outLine.setScaleX(1.1);
                outLine.setScaleY(1.1);
                outLine.setScaleZ(1.1);

            }
            if (intersectedNode instanceof Box) {
                Box b = (Box) intersectedNode;
                outLine = new Box(b.getWidth(), b.getHeight(), b.getDepth());
                outLine.setTranslateX(b.getTranslateX());
                group3d.getChildren().add(outLine);

                outLine.setCullFace(CullFace.FRONT);
                outLine.setScaleX(1.1);
                outLine.setScaleY(1.1);
                outLine.setScaleZ(1.1);

            }
        });
        scene.setCamera(camera);
        scene.setFill(Color.AQUA);
        stage.setScene(scene);
        stage.setTitle("outline javafx");
        stage.show();
    }

    public static void main(String[] args) {
        launch();
    }
}
Run Code Online (Sandbox Code Playgroud)

注意 Shape3d 对象从其中心开始缩放。如果使用自定义 MeshView 对象实现此方法,则这些网格也需要在其中心缩放