6

JavaFX と Java は初めてです。立方体または多面体の表面にシーンを作成する方法を知りたいですか? 任意の 3D 形状の表面でビデオを再生したいと思います。どうすればこれを行うことができますか?

4

3 に答える 3

8

組み込みの JavaFX MediaPlayer を使用し、メディア上のビューの定期的なスナップショットを取得して、3D シェイプ (この場合はボックス) にマップされたテクスチャ イメージにするサンプルを次に示します。ボックスの側面が遠近感で見えるように、Y 軸を中心とした回転アニメーションが追加されます。

3Dビデオ

import javafx.animation.*;
import javafx.application.*;
import javafx.geometry.Rectangle2D;
import javafx.scene.*;
import javafx.scene.image.WritableImage;
import javafx.scene.media.*;
import javafx.scene.paint.*;
import javafx.scene.shape.*;
import javafx.scene.transform.Rotate;
import javafx.stage.Stage;
import javafx.util.Duration;

// Display a rotating 3D box with a video projected onto its surface.
public class ThreeDMedia extends Application {

    private static final String MEDIA_URL =
            "http://download.oracle.com/otndocs/products/javafx/oow2010-2.flv";

    private static final int SCENE_W = 640;
    private static final int SCENE_H = 400;

    private static final double MEDIA_W = 540 * 2/3;
    private static final double MEDIA_H = 209 * 2/3;

    private static final Color INDIA_INK = Color.rgb(35, 39, 50);

    @Override
    public void start(Stage stage) {
        // create a 3D box shape on which to project the video.
        Box box = new Box(MEDIA_W, MEDIA_H, MEDIA_W);
        box.setTranslateX(SCENE_W / 2);
        box.setTranslateY(SCENE_H / 2);

        // create a media player for the video which loops the video forever.
        MediaPlayer player = new MediaPlayer(new Media(MEDIA_URL));
        player.setCycleCount(MediaPlayer.INDEFINITE);

        // create a media view for the video, sized to our specifications.
        MediaView mediaView = new MediaView(player);
        mediaView.setPreserveRatio(false);
        mediaView.setFitWidth(MEDIA_W);
        mediaView.setFitHeight(MEDIA_H);

        // project the video on to the 3D box.
        showMediaOnShape3D(box, mediaView);

        // rotate the box.
        rotateAroundYAxis(box);

        // create a point light source a fair way away so lighting is reasonably even.
        PointLight pointLight = new PointLight(
                Color.WHITE
        );
        pointLight.setTranslateX(SCENE_W / 2);
        pointLight.setTranslateY(SCENE_H / 2);
        pointLight.setTranslateZ(-SCENE_W * 5);

        // add a bit of ambient light to make the lighting more natural.
        AmbientLight ambientLight = new AmbientLight(
                Color.rgb(15, 15, 15)
        );

        // place the shape and associated lights in a group.
        Group group = new Group(
                box,
                pointLight,
                ambientLight
        );

        // create a 3D scene with a default perspective camera.
        Scene scene = new Scene(
                group,
                SCENE_W, SCENE_H, true, SceneAntialiasing.BALANCED
        );
        scene.setFill(INDIA_INK);
        PerspectiveCamera camera = new PerspectiveCamera();
        scene.setCamera(camera);

        stage.setScene(scene);
        stage.setResizable(false);

        // start playing the media, showing the scene once the media is ready to play.
        player.setOnReady(stage::show);
        player.setOnError(Platform::exit);
        player.play();
    }

       // Project video on to 3D shape.
    private void showMediaOnShape3D(Shape3D shape3D, final MediaView mediaView) {
        PhongMaterial material = new PhongMaterial();
        shape3D.setMaterial(material);

        Scene mediaScene = new Scene(
                new Group(mediaView),
                MEDIA_W, MEDIA_H
        );
        SnapshotParameters snapshotParameters = new SnapshotParameters();
        snapshotParameters.setViewport(
                new Rectangle2D(
                        0, 0, MEDIA_W, MEDIA_H
                )
        );
        WritableImage textureImage = mediaView.snapshot(
                snapshotParameters,
                null
        );
        material.setDiffuseMap(textureImage);

        AnimationTimer timer = new AnimationTimer() {
            @Override
            public void handle(long now) {
                mediaView.snapshot(
                        snapshotParameters,
                        textureImage
                );
            }
        };
        timer.start();
    }

    // Rotates a shape around the y axis indefinitely.
    private void rotateAroundYAxis(Shape3D shape3D) {
        RotateTransition rotateY = new RotateTransition(
                Duration.seconds(10),
                shape3D
        );

        rotateY.setAxis(Rotate.Y_AXIS);
        rotateY.setFromAngle(360);
        rotateY.setToAngle(0);
        rotateY.setCycleCount(RotateTransition.INDEFINITE);
        rotateY.setInterpolator(Interpolator.LINEAR);

        rotateY.play();
    }

    public static void main(String[] args) {
        launch(args);
    }
}
于 2015-04-08T00:14:32.403 に答える
4

jewelsea と José のよりエレガントなソリューションに加えて、MediaView を 3D 空間に手動で配置することもできます (例: 立方体の 6 つの面)。

public class VideoCubeDemo extends Application {

    Random rnd = new Random();

    // size of the cube
    double size = 320;

    @Override
    public void start(Stage primaryStage) throws MalformedURLException {

        // create media views
        List<String> videoFiles = new ArrayList<>();

        videoFiles.add( getClass().getResource("funny_cats_compilation_2012.mp4").toExternalForm());
        videoFiles.add( getClass().getResource("funny_cats_compilation_2012.mp4").toExternalForm());
        videoFiles.add( getClass().getResource("funny_cats_compilation_2012.mp4").toExternalForm());
        videoFiles.add( getClass().getResource("funny_cats_compilation_2012.mp4").toExternalForm());
        videoFiles.add( getClass().getResource("funny_cats_compilation_2012.mp4").toExternalForm());
        videoFiles.add( getClass().getResource("funny_cats_compilation_2012.mp4").toExternalForm());

        // create faces for the cube
        // original cube face code from http://www.javafxapps.in/tutorial/Creating-3D-Cube-in-javafx.html
        MediaView r;
        int videoIndex;

        Group cube = new Group();

        List<MediaView> cubeFaces = new ArrayList<>();

        // back face
        videoIndex = 0;
        r = createMediaView(videoFiles.get( videoIndex));
        r.setTranslateX(-0.5 * size);
        r.setTranslateY(-0.5 * size);
        r.setTranslateZ(0.5 * size);

        cubeFaces.add( r);

        // bottom face
        videoIndex = 1;
        r = createMediaView(videoFiles.get( videoIndex));
        r.setTranslateX(-0.5 * size);
        r.setTranslateY(0);
        r.setRotationAxis(Rotate.X_AXIS);
        r.setRotate(90);

        cubeFaces.add( r);

        // right face
        videoIndex = 2;
        r = createMediaView(videoFiles.get( videoIndex));
        r.setTranslateX(-1 * size);
        r.setTranslateY(-0.5 * size);
        r.setRotationAxis(Rotate.Y_AXIS);
        r.setRotate(90);

        cubeFaces.add( r);

        // left face
        videoIndex = 3;
        r = createMediaView(videoFiles.get( videoIndex));
        r.setTranslateX(0);
        r.setTranslateY(-0.5 * size);
        r.setRotationAxis(Rotate.Y_AXIS);
        r.setRotate(90);

        cubeFaces.add( r);

        // top face
        videoIndex = 4;
        r = createMediaView(videoFiles.get( videoIndex));
        r.setTranslateX(-0.5 * size);
        r.setTranslateY(-1 * size);
        r.setRotationAxis(Rotate.X_AXIS);
        r.setRotate(90);

        cubeFaces.add( r);

        // front face
        videoIndex = 5;
        r = createMediaView(videoFiles.get( videoIndex));
        r.setTranslateX(-0.5 * size);
        r.setTranslateY(-0.5 * size);
        r.setTranslateZ(-0.5 * size);

        cubeFaces.add( r);

        // create cube with all faces
        cube.getChildren().addAll( cubeFaces);

        // initial cube rotation
        cube.getTransforms().addAll(new Rotate(45, Rotate.X_AXIS), new Rotate(45, Rotate.Y_AXIS));

        // animate cube
        Point3D rotateAxis = new Point3D(1,1,1); // rotate around X, Y and Z
        Timeline animation = new Timeline();
        animation.getKeyFrames().addAll(
                new KeyFrame(Duration.ZERO, new KeyValue(cube.rotationAxisProperty(), rotateAxis), new KeyValue(cube.rotateProperty(), 0d)),
                new KeyFrame(Duration.seconds(5), new KeyValue(cube.rotationAxisProperty(), rotateAxis), new KeyValue(cube.rotateProperty(), 360d))
                );
        animation.setCycleCount(Animation.INDEFINITE);

        // add objects to scene
        StackPane root = new StackPane();
        root.getChildren().add(cube);

        Scene scene = new Scene(root, 1600, 900, true, SceneAntialiasing.BALANCED);
        scene.setFill(Color.BLACK);
        scene.setCamera(new PerspectiveCamera());

        primaryStage.setResizable(true);
        primaryStage.setScene(scene);
        primaryStage.show();

        // play videos and animation
        for( MediaView mediaPlayer: cubeFaces) {
            mediaPlayer.getMediaPlayer().play();
        }
        animation.play();

    }

    private MediaView createMediaView( String path) {

        Media media = new Media( path);
        MediaPlayer mediaPlayer = new MediaPlayer( media);
        mediaPlayer.setVolume(0.8);
        mediaPlayer.setCycleCount(MediaPlayer.INDEFINITE);

        MediaView mediaView = new MediaView( mediaPlayer);
        mediaView.setFitHeight(size);
        mediaView.setFitWidth(size);
        mediaView.setPreserveRatio( false);

        return mediaView;
    }

    public static void main(String[] args) {
        launch(args);
    }
}

ここに画像の説明を入力

于 2015-04-08T07:38:59.660 に答える