▼Androidメモ▼
3Dモデルのアニメーション


OpenGL ES 1.0で3Dモデルのアニメーションを行うプログラムを作成する。
ドロイドくんが手足をふりながら回転。
HelloGL10_22.png

3Dモデルファイル
以下の4つのファイルをプロジェクトのassetsに配置。
ライブラリ
3Dモデルの読み込みで利用した独自ライブラリを追加。

ソースコード
GL10ModelEx2.java
package net.npaka.gl10modelex2;
import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;

//3Dモデルのアニメーション
public class GL10ModelEx2 extends Activity {
private GLSurfaceView glView;

//アクティビティ生成時に呼ばれる
@Override
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);

//GLサーフェイスビューの生成
glView=new GLSurfaceView(this);
glView.setRenderer(new GLRenderer(this));
setContentView(glView);
}

//アクティビティレジューム時に呼ばれる
@Override
public void onResume() {
super.onResume();
glView.onResume();
}

//アクティビティポーズ時に呼ばれる
@Override
public void onPause() {
super.onPause();
glView.onPause();
}
}

GLRenderer.java
package net.npaka.gl10modelex2;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.opengles.GL11;
import net.npaka.gles.Figure;
import net.npaka.gles.GLES;
import net.npaka.gles.ObjLoader;
import net.npaka.gles.Object3D;
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.opengl.GLU;

//レンダラー
public class GLRenderer implements
GLSurfaceView.Renderer {
//システム
private float aspect;//アスペクト比
private int tick; //時間経過

//モデル
private Object3D model=new Object3D();
private Object3D handL=new Object3D();
private Object3D handR=new Object3D();
private Object3D legL =new Object3D();
private Object3D legR =new Object3D();

//コンストラクタ
public GLRenderer(Context context) {
GLES.context=context;
}

//サーフェイス生成時に呼ばれる
@Override
public void onSurfaceCreated(GL10 gl10,EGLConfig eglConfig) {
GLES.gl=(GL11)gl10;

//デプステストの有効化
gl10.glEnable(GL10.GL_DEPTH_TEST);

//光源の有効化
gl10.glEnable(GL10.GL_LIGHTING);
gl10.glEnable(GL10.GL_LIGHT0);

//光源色の指定
gl10.glLightfv(GL10.GL_LIGHT0,GL10.GL_AMBIENT,
new float[]{0.2f,0.2f,0.2f,1.0f},0);
gl10.glLightfv(GL10.GL_LIGHT0,GL10.GL_DIFFUSE,
new float[]{0.7f,0.7f,0.7f,1.0f},0);
gl10.glLightfv(GL10.GL_LIGHT0,GL10.GL_SPECULAR,
new float[]{0.9f,0.9f,0.9f,1.0f},0);

//モデルの読み込み
try {
//手
Figure handFigure=ObjLoader.load("droid_hand.obj");
handL.figure=handFigure;
handL.position.set(-0.65f,1.24f,0.0f);
handR.figure=handFigure;
handR.position.set( 0.65f,1.24f,0.0f);

//足
Figure legFigure=ObjLoader.load("droid_leg.obj");
legL.figure=legFigure;
legL.position.set(-0.2f,0.5f,0.0f);
legR.figure=legFigure;
legR.position.set( 0.2f,0.5f,0.0f);

//体
model.figure=ObjLoader.load("droid_body.obj");
model.childs.add(handL);
model.childs.add(handR);
model.childs.add(legL);
model.childs.add(legR);
} catch (Exception e) {
android.util.Log.e("debug",e.toString());
for (StackTraceElement ste:e.getStackTrace()) {
android.util.Log.e("debug"," "+ste);
}
}
}

//画面サイズ変更時に呼ばれる
@Override
public void onSurfaceChanged(GL10 gl10,int w,int h) {
//ビューポート変換
gl10.glViewport(0,0,w,h);
aspect=(float)w/(float)h;
}

//毎フレーム描画時に呼ばれる
@Override
public void onDrawFrame(GL10 gl10) {
//画面のクリア
gl10.glClearColor(1.0f,1.0f,1.0f,1.0f);
gl10.glClear(GL10.GL_COLOR_BUFFER_BIT|
GL10.GL_DEPTH_BUFFER_BIT);

//射影変換
gl10.glMatrixMode(GL10.GL_PROJECTION);
gl10.glLoadIdentity();
GLU.gluPerspective(gl10,
45.0f, //Y方向の画角
aspect, //アスペクト比
0.01f, //ニアクリップ
100.0f);//ファークリップ

//光源位置の指定
gl10.glMatrixMode(GL10.GL_MODELVIEW);
gl10.glLoadIdentity();
gl10.glLightfv(GL10.GL_LIGHT0,GL10.GL_POSITION,
new float[]{5.0f,5.0f,5.0f,0.0f},0);

//ビュー変換
GLU.gluLookAt(gl10,
0,0.8f,5.0f, //カメラの視点
0,0.8f,0.0f, //カメラの焦点
0.0f,1.0f,0.0f);//カメラの上方向

//モデル変換
gl10.glRotatef(tick++,0,1,0);

//左手・右足
int rotate=tick%180;
rotate=(rotate<90)?rotate-45:180-45-rotate;
handL.rotate.x=rotate;
legR.rotate.x=rotate;

//右手・左足
rotate=(tick+90)%180;
rotate=(rotate<90)?rotate-45:180-45-rotate;
handR.rotate.x=rotate;
legL.rotate.x=rotate;

//モデルの描画
model.draw();
}
}



−戻る−