リビジョン 59e525ef
| learn/java/javafx/Hello3d/Hello3d.java | ||
|---|---|---|
|
import javafx.stage.Stage;
|
||
|
|
||
|
public class Hello3d extends Application {
|
||
|
private static final double FAR_ORBITAL_RADIUS = 240d;
|
||
|
private static final double NEAR_ORBITAL_RADIUS = 160d;
|
||
|
|
||
|
private final Image earthImage = new Image(getClass().getResourceAsStream("physical-free-world-map-b1.jpg"));
|
||
|
private final Image earthImage = new Image(getClass().getResourceAsStream("earth_1000x500.png"));
|
||
|
|
||
|
private long previousHandledTime = Long.MAX_VALUE;
|
||
|
private double azimuth;
|
||
|
private double range = FAR_ORBITAL_RADIUS;
|
||
|
private AnimationTimer timer;
|
||
|
|
||
|
private static final double AZIMUTH_SPEED_PER_100MILLIS = 1.0;
|
||
|
private static final double ORBITAL_RADIUS = 240d;
|
||
|
|
||
|
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, -200d);
|
||
|
private final Translate cameraTranslate = new Translate(0d, -30d, -1 * FAR_ORBITAL_RADIUS);
|
||
|
|
||
|
@Override
|
||
|
public void start(final Stage stage) {
|
||
| ... | ... | |
|
|
||
|
// 点光源の定義
|
||
|
final PointLight pointLight = new PointLight(Color.WHITE);
|
||
|
pointLight.setTranslateX(-60d);
|
||
|
pointLight.setTranslateX(-80d);
|
||
|
pointLight.setTranslateY(0d);
|
||
|
pointLight.setTranslateZ(240d);
|
||
|
pointLight.setTranslateZ(220d);
|
||
|
root.getChildren().add(pointLight);
|
||
|
|
||
|
// 環境光の定義
|
||
|
final AmbientLight ambientLight = new AmbientLight(Color.rgb(80, 80, 80, 0.5));
|
||
|
final AmbientLight ambientLight = new AmbientLight(Color.rgb(100, 100, 100, 0.7));
|
||
|
root.getChildren().add(ambientLight);
|
||
|
|
||
|
final Scene scene = new Scene(root, 800, 600, Color.BLACK);
|
||
| ... | ... | |
|
update(now);
|
||
|
}
|
||
|
};
|
||
|
timer.start();
|
||
|
|
||
|
root.setOnMousePressed(ev -> timer.start());
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* カメラ位置を更新する。
|
||
|
* カメラは Y=0 の平面(X-Z平面)で原点を中心に 定数 ORBITAL_RADIUS を半径とした
|
||
|
* 円軌道を移動する。
|
||
|
*
|
||
|
* カメラは、Y=0 の平面(X-Z平面)で原点を中心にした円軌道を移動する。
|
||
|
*
|
||
|
* - フェーズ1
|
||
|
* 経度0度から140度EまでFAR_ORBITAL_RADIUS を半径とした円軌道を移動する。
|
||
|
* - フェーズ2
|
||
|
* 経度140度Eで、半径をFAR_ORBITAL_RADIUSからNEAR_ORBITAL_RADIUSに移動する。
|
||
|
* - フェーズ3
|
||
|
* 経度140度Eから122度WまでFAR_ORBITAL_RADIUS を半径とした円軌道を移動する。
|
||
|
*
|
||
|
* また、カメラの角度は常に球体を向くように円軌道の移動に合わせて設定する。
|
||
|
*/
|
||
|
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);
|
||
|
// フェーズ1
|
||
|
if (azimuth < 140d) {
|
||
|
azimuth += 1;
|
||
|
cameraTranslate.setX(Math.sin(Math.toRadians(azimuth)) * FAR_ORBITAL_RADIUS);
|
||
|
cameraTranslate.setZ(-1 * Math.cos(Math.toRadians(azimuth)) * FAR_ORBITAL_RADIUS);
|
||
|
cameraRotateY.setAngle(-1 * azimuth);
|
||
|
return;
|
||
|
}
|
||
|
// フェーズ2
|
||
|
if (range > NEAR_ORBITAL_RADIUS) {
|
||
|
range -= 0.5d;
|
||
|
cameraTranslate.setX(Math.sin(Math.toRadians(azimuth)) * range);
|
||
|
cameraTranslate.setZ(-1 * Math.cos(Math.toRadians(azimuth)) * range);
|
||
|
return;
|
||
|
}
|
||
|
// フェーズ3
|
||
|
if (azimuth < 238d) {
|
||
|
azimuth += 0.5;
|
||
|
cameraTranslate.setX(Math.sin(Math.toRadians(azimuth)) * NEAR_ORBITAL_RADIUS);
|
||
|
cameraTranslate.setZ(-1 * Math.cos(Math.toRadians(azimuth)) * NEAR_ORBITAL_RADIUS);
|
||
|
cameraRotateY.setAngle(-1 * azimuth);
|
||
|
return;
|
||
|
}
|
||
|
timer.stop();
|
||
|
}
|
||
|
|
||
|
public static void main(final String... args) {
|
||
JavaOne 2013 サンフランシスコ報告会のLTでデモするバージョン
東京へズームしサンフランシスコまで移動する
サンフランシスコに丸印をつけた