CX's Hatena Blog

はてなブログを使ってみるテスト

JavaFX 3D で地球を回してみるテスト

帰ってきた「○○ で地球を回してみる」シリーズ。

今回は、Java 8 に含まれる予定の GUI ライブラリ JavaFX 3D を使ってみたいと思います。

今回日程 シリーズ構成言語
1日目OpenGL で地球を回してみるテスト C/C++
2日目DirectX で地球を回してみるテスト C/C++
3日目Java 3D で地球を回してみるテスト Java
4日目WebGL で地球を回してみるテスト JavaScript
5日目Three.js で地球を回してみるテスト JavaScript
6日目Babylon.js で地球を回してみるテストJavaScript
7日目gl.enchant.js で地球を回してみるテストJavaScript
8日目PhiloGL で地球を回してみるテストJavaScript
9日目CubicVR.js で地球を回してみるテストJavaScript
最終日Away3D で地球を回してみるテストJavaScript
追加+1Flash 版 Away3D で地球を回してみるテストActionScript
追加+2WPF で地球を回してみるテストC# + XAML
追加+3JavaFX 3D で地球を回してみるテストJava

f:id:cx20:20140217001112p:plain

0. 事前準備

以下のコンパイラとライブラリを用意します。

JDK 8.0 の正式版は、2014年3月にリリース予定となっていますが、Early Access 版がダウンロードできるので、それを使ってみたいと思います。

JavaFXJDK 8.0 に含まれる為、別途ダウンロードする必要はありません。

以下は、JDK 8.0 のインストール時の画面イメージです。

f:id:cx20:20140217001106p:plain

f:id:cx20:20140217001107p:plain

f:id:cx20:20140217001108p:plain

f:id:cx20:20140217001109p:plain

f:id:cx20:20140217001110p:plain

f:id:cx20:20140217001111p:plain

1. ソースを作成する

import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.scene.AmbientLight;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.PointLight;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Sphere;
import javafx.scene.transform.Rotate;
import javafx.scene.transform.Translate;
import javafx.stage.Stage;

public class Earth extends Application {

    private final Image earthImage = new Image(getClass().getResourceAsStream("earth.jpg"));

    private long previousHandledTime = Long.MAX_VALUE;
    private double azimuth;
    private AnimationTimer timer;

    private static final double AZIMUTH_SPEED_PER_100MILLIS = 1.0;
    private static final double ORBITAL_RADIUS = 300d;

    private final Rotate cameraRotateX = new Rotate(0d, Rotate.X_AXIS);
    private final Rotate cameraRotateY = new Rotate(0d, Rotate.Y_AXIS);
    private final Rotate cameraRotateZ = new Rotate(0d, Rotate.Z_AXIS);
    private final Translate cameraTranslate = new Translate(0d, 0d, -300d);

    @Override
    public void start(final Stage stage) {
        final Group root = new Group();

        // 球体の定義
        final Sphere earth = new Sphere(100d);
        root.getChildren().add(earth);

        // 材質の定義
        final PhongMaterial material = new PhongMaterial();
        material.setDiffuseMap(earthImage);
        earth.setMaterial(material);

        // カメラの定義
        final PerspectiveCamera camera = new PerspectiveCamera(true);
        camera.setFieldOfView(45d);
        camera.setFarClip(1000d);
        camera.getTransforms().addAll(cameraTranslate, cameraRotateX, cameraRotateY, cameraRotateZ);

        // 環境光の定義
        final AmbientLight ambientLight = new AmbientLight(Color.rgb(255, 255, 255, 1.0));
        root.getChildren().add(ambientLight);

        final Scene scene = new Scene(root, 450, 450, Color.BLACK);
        scene.setCamera(camera);

        stage.setScene(scene);
        stage.setTitle("Hello, JavaFX 3D World!");
        stage.show();

        timer = new AnimationTimer() {
            @Override
            public void handle(long now) {
                update(now);
            }
        };
        timer.start();
    }

    private void update(long now) {
        if (previousHandledTime + 33_000_000 > now) return;
        previousHandledTime = now;
        azimuth += AZIMUTH_SPEED_PER_100MILLIS;

        cameraTranslate.setX(Math.sin(Math.toRadians(azimuth)) * ORBITAL_RADIUS);
        cameraTranslate.setZ(-1 * Math.cos(Math.toRadians(azimuth)) * ORBITAL_RADIUS);
        cameraRotateY.setAngle(-1 * azimuth);
    }

    public static void main(final String... args) {
        launch(args);
    }
}

上記、コードは、

JavaFX 3Dを理解する

http://www.torutk.com/projects/swe/wiki/JavaFX_3D%E3%82%92%E7%90%86%E8%A7%A3%E3%81%99%E3%82%8B

のものを、一部、修正したものになります。

2. コンパイルする

コマンドプロンプトより以下のコマンドを実行します。

javac Earth.java

エラーが出なければ、とりあえず、コンパイル完了です。

3. 出力先フォルダにテクスチャファイルをコピーする

テクスチャに使用する画像ファイルは、「earth.jpg」としてください。

f:id:cx20:20140120002054p:plain

4. 実行する

コマンドプロンプトより以下のコマンドを実行します。

javaw Earth

f:id:cx20:20140217001112p:plain

地球が回れば、成功です。ただ、ちょっとテクスチャの縮尺が変なので、改善の余地はありそうです・・・

参考

JavaFX 3Dを理解する

http://www.torutk.com/projects/swe/wiki/JavaFX_3D%E3%82%92%E7%90%86%E8%A7%A3%E3%81%99%E3%82%8B