JavaFX と Java は初めてです。立方体または多面体の表面にシーンを作成する方法を知りたいですか? 任意の 3D 形状の表面でビデオを再生したいと思います。どうすればこれを行うことができますか?
2461 次
3 に答える
8
組み込みの JavaFX MediaPlayer を使用し、メディア上のビューの定期的なスナップショットを取得して、3D シェイプ (この場合はボックス) にマップされたテクスチャ イメージにするサンプルを次に示します。ボックスの側面が遠近感で見えるように、Y 軸を中心とした回転アニメーションが追加されます。
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 に答える