メッシュアニメーションの作成方法
メッシュ(MeshView)を使ったアニメーションのサンプルプログラムです。
実行するとこんなアニメーションが表示されます。
アニメーションの作成方法
3Dノードを表示する方法はこちら
MeshViewを作る方法はこちら
JavaFX アニメーション作る方法はこちら
をまずご覧になってください。
こちらでアニメーションを表示する方法を書きましたが、
これはBOX形状を回転させるもので、ノードの形状を変えるものではありませんでした。
今回のサンプルプログラムでは、メッシュを構成する点の座標を入れ替えることで形状を変化させています。
アニメーションの作成手順
メッシュの作成
XY平面上に平らな四角形のメッシュを作ります。構成点は20×20個。
//メッシュを置く
FlatMesh fm = new FlatMesh( 5 , 5 , 20 , 20 , .01 );
MeshView meshView = new MeshView();
mesh = fm.getTriangleMesh();
meshView.setMesh( mesh );
meshView.setDrawMode( DrawMode.FILL);
PhongMaterial material = new PhongMaterial();
Image img = new Image("file:d:/work/java/test.png");
material.setDiffuseMap( img );
meshView.setMaterial(material);
meshView.setCullFace(CullFace.NONE);
group.getChildren().add( meshView );
構成点の取りおき
メッシュを構成する点の座標を別途保管しておきます。
//メッシュを構成する点を取得
points = fm.getPoints();
点座標の変更
アニメーションClassのhandleメソッドの中で、点の座標を書き換えます。
今回はZ座標を三角関数を使って変更しています。
座標配列は、こちら
で書いてるように、x,y,z3つの数値で1つの点を表わします。したがって、差し替える数値も3つ飛ばしになります。
int i=2;
for(int x=0;x<20;x++){
for(int y=0;y<20;y++){
double l = Math.sqrt((50.-x*5.)*(50.-x*5.)+(50.-y*5.)*(50.-y*5.));
float z = (float)Math.sin( l/5.+no )*2f;
points[i]=z ; i=i+3;
}
}
メッシュに差し替えた座標を入れる
最後に書き換えた座標配列をメッシュ(TriangleMesh)に入れれば、JavaFX楽天 が形状の変更されたメッシュを表示してくれます。
mesh.getPoints().setAll( points );
メッシュアニメーションのサンプルプログラム
コード全体は下記のようになります。
package tomojavalib.fx;
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.geometry.*;
import javafx.scene.*;
import javafx.scene.image.Image;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.*;
import javafx.scene.transform.*;
import javafx.stage.Stage;
/**単純な
Java
楽天 FXプログラム
*アニメーション
* */
public class MeshAnimation extends Application {
float[] points = null;
TriangleMesh mesh = null;
public static void main(String[] args) {
Application.launch(args);
}
@Override
public void start(Stage stage) throws Exception {
Scene scene = make3dScene();
stage.setScene(scene);
//タイトルの表示
stage.setTitle("アニメーション試験");
stage.show();
//アニメーションを始める
new Animation().start();
}
private Scene make3dScene(){
Group group = new Group();
//メッシュを置く
FlatMesh fm = new FlatMesh( 5 , 5 , 20 , 20 , .01 );
MeshView meshView = new MeshView();
mesh = fm.getTriangleMesh();
meshView.setMesh( mesh );
meshView.setDrawMode( DrawMode.FILL);
PhongMaterial material = new PhongMaterial();
Image img = new Image("file:d:/work/java/test.png");
material.setDiffuseMap( img );
meshView.setMaterial(material);
meshView.setCullFace(CullFace.NONE);
group.getChildren().add( meshView );
//メッシュを構成する点を取得
points = fm.getPoints();
// カメラを置く
PerspectiveCamera camera = new PerspectiveCamera( true );
Translate cameratranslate = new Translate(50,50,-250);
Rotate camerarotateX = new Rotate( 30 , new Point3D( 1 , 0 , 0 ) );
Rotate camerarotateY = new Rotate( 30 , new Point3D( 0 , 1 , 0 ) );
camera.getTransforms().add( camerarotateX );
camera.getTransforms().add( camerarotateY );
camera.getTransforms().add( cameratranslate );
camera.setFarClip( 1000. );
camera.setFieldOfView( 30. );
group.getChildren().add( camera );
//点光源を置く
LightBase light = new PointLight();
light.setTranslateX( 30.0 );
light.setTranslateY( -30.0 );
light.setTranslateZ( -30.0 );
group.getChildren().add( light );
//Sceneの設定
Scene s3d = new Scene(group, 320, 240);
s3d.setFill(Color.ALICEBLUE);
s3d.setCamera( camera );
return s3d;
}
private class Animation extends AnimationTimer {
// アニメーション間隔の設定
long kankaku = 100 * 1000000L; //500ミリ秒
long stime = 0;
long foreno = -1;
@Override
public void handle(long now) {
if( stime == 0 ){ stime = now; }
//所定時間経過の確認
Long no = (Long)(( now - stime ) / kankaku );
if( foreno != no ){ foreno = no; } else { return; }
System.out.println(no);
int i=2;
for(int x=0;x<20;x++){
for(int y=0;y<20;y++){
double l = Math.sqrt((50.-x*5.)*(50.-x*5.)+(50.-y*5.)*(50.-y*5.));
float z = (float)Math.sin( l/5.+no )*2f;
points[i]=z ; i=i+3;
}
}
mesh.getPoints().setAll( points );
}
}
}
最終更新日: 2017-03-14 11:25:50