忍者ブログ

軽Lab

 Javaを中心とした、プログラミング関係のナレッジベース

Home > > JavaFX 3D テクスチャのアニメーション

JavaFX 3D テクスチャのアニメーション

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

Home > > JavaFX 3D テクスチャのアニメーション

- ランダム記事 -
- PR -

コメント

ただいまコメントを受けつけておりません。

Home > JavaFX入門 > JavaFX 3D テクスチャのアニメーション

JavaFX 3D テクスチャのアニメーション

今回はテクスチャのアニメーションの実装方法についてみていく。テクスチャのアニメーションもメッシュ・アニメーションと同様、meshに対してテクスチャを定期的に設定しなおすことで実現できる。なお、JavaFXにおけるアニメーションの基礎は『JavaFX アニメーション』を参照のこと。

■ テクスチャ・アニメーションのサンプル

 以下にテクスチャ・アニメーションを行うサンプルコードを示す。サンプルでは、0.5行毎にテクスチャ画像を入れ替える。

◇ サンプルコード
package application_fx;

import java.io.File;

import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.LightBase;
import javafx.scene.Node;
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.CullFace;
import javafx.scene.shape.MeshView;
import javafx.scene.shape.TriangleMesh;
import javafx.stage.Stage;

public class TestTriangleMeshTexture extends Application {


    public static void main(String[] args)
    {
        launch( args );
    }
    
    @Override
    public void start(Stage primaryStage) throws Exception
    {
        // シーングラフの構成
        Group   root        = new Group();
        
        // モデルデータの取り込み
        root.getChildren().add( createTriangleMesh() );
        
        // シーンの作成
        // 3Dシーンの奥行きを表現するため、Zバッファを有効にする
        Scene   scene       = new Scene( root , 1000 , 750 , true );
        scene.setFill( Color.web( "9FCC7F" ) );
        
        // カメラ設定
        PerspectiveCamera   camera  = new PerspectiveCamera( true );
        camera.setFarClip( 300 );
        camera.setTranslateZ( -50 );
        scene.setCamera( camera );
        
        // 光源設定
        LightBase   light       = new PointLight();
        light.setTranslateZ( -50 );
        root.getChildren().add( light );
        
        // ウィンドウ表示
        primaryStage.setScene( scene );
        primaryStage.show();
    }
    
    /**
     * トライアングル・メッシュを作成
     * 
     * 【メッシュ】
     * p0┏━┓p3
     *   ┃\┃
     * p1┗━┛p2
     * 
     * 【テクスチャ】
     * t0┏━┓t3
     *   ┃ ┃
     * t1┗━┛t2
     * 
     * @return
     */
    public Node createTriangleMesh()
    {
        // メッシュビューを作成
        MeshView        meshView    = new MeshView();

        // メッシュを作成
        TriangleMesh    mesh        = new TriangleMesh();
        float[]         points      = { -2      ,-2     ,0      ,   // p0
                                        -2      ,2      ,0      ,   // p1
                                        2       ,2      ,0      ,   // p2
                                        2       ,-2     ,0      };  // p3
        float[]         texCoords   = { 0 , 0 ,     // t0
                                        0 , 1 ,     // t1
                                        1 , 1 ,     // t2
                                        1 , 0 };    // t3
        int[]           faces       = { 0 , 0 , 1 , 1 , 2 , 2,
                                        2 , 2 , 3 , 3 , 0 , 0 };
        mesh.getPoints().addAll( points );
        mesh.getTexCoords().addAll( texCoords );
        mesh.getFaces().addAll( faces );
        
        // マテリアルを作成
        PhongMaterial   material    = new PhongMaterial();
        
        // メッシュを登録
        meshView.setMesh( mesh );
        meshView.setMaterial( material );
        meshView.setCullFace(CullFace.NONE);

        // テキスチャアニメーション開始
        new TextureAnimation( meshView ).start();
        
        return meshView;
    }
    
    /**
     *  アニメーションタイマー・クラス
     */
    private class TextureAnimation extends AnimationTimer
    {
        // アニメーション対象ノード
        private MeshView    meshView    = null;
        private Image[]     images      = null;
         
        // アニメーション間隔(nano sec)
        private long        duration    = 500 * 1000000L;   // 500ミリ秒
        private long        startTime   = 0;
        private long        beforeCount = -1;
         
        public TextureAnimation( MeshView meshView )
        {
            // 内部変数の初期化
            this.meshView           = meshView;
            
            // アニメーション画像の読込
            images      = new Image[2];
            images[0]   = new Image( new File( "img/chara_anime_01.gif" ).toURI().toString() );
            images[1]   = new Image( new File( "img/chara_anime_02.gif" ).toURI().toString() );
        }
         
        @Override
        public void handle( long now )
        {
            // アニメーションの開始時間を取得
            if( startTime == 0 ){ startTime = now; }
            
            // アニメーションカウントを計算
            // カウントが進んでいない場合は、処理を終了
            Long    count   = ( now - startTime ) / duration;
            if( beforeCount != count ){ beforeCount = count; }
                                  else{ return; }
            
            // 画像番号を計算
            int     index   = 0;
            if( count % 2 == 1 ){ index = 0; }
                            else{ index = 1; }
            
            // マテリアルの再設定
            PhongMaterial   material    = (PhongMaterial) meshView.getMaterial();
            material.setDiffuseMap( images[ index ] );
            meshView.setMaterial( material );
             
        }
 
         
    }
}

◇ リソース

(chara_anime_01.gif)
 (chara_anime_02.gif)


◇ 実行結果


◇ 解説

  1. アニメーションはAnimationTimerクラスを継承したTextureAnimationクラスにより行う(104行目、112行目~159行目)。
  2. 一定間隔で呼ばれるhandle関数内でアニメーションカウントを計算し(138行目~144行目)、アニメーションカウントが偶数/奇数でテクスチャ画像を切り替えている(147行目~154行目)。


■ 参照

  1. JavaDoc - クラスTriangleMesh
  2. JavaDoc - インタフェースObservableFloatArray

改訂履歴
・2015年10月29日 改訂。『メッシュ・アニメーション』を別記事として分離
Home > JavaFX入門 > JavaFX 3D テクスチャのアニメーション

- ランダム記事 -
- PR -

コメント

プロフィール

管理者:
 連絡はContactよりお願いします。

PR