▼マスコットカプセル メモ▼
マスコットカプセル
マスコットカプセル
マスコットカプセルは、エイチアイが開発した「3Dポリゴンエンジン」です。3Dモデルのキャラクターをパソコンや携帯電話上でリアルタイムに動作させることができます。特に携帯電話用の3Dエンジンとしては、ドコモ・au・ソフトバンク・WILLCOMといった全キャリアで採用されています。は2004年8月現在、ver.1からver.4までの4つのバージョンが存在します。

ver.1 ver.2 ver.3 ver.4
ソフトバンク 50Kアプリ 100Kアプリ 256Kアプリ 256Kアプリ Ver.2/3G
ドコモ なし DoJa2.0 DoJa3.0 DoJa4.0
au なし なし Java Phase 3/BREW なし
WILLCOM なし なし W-ZERO3 なし
海外端末 なし なし なし M3G


テクスチャ
ver.1 ver.2 ver.3 ver.4
ファイル形式 256色BMP 256色BMP 256色BMP PNG-8
サイズ 128x128固定 128x128以下 256x256以下 端末依存?
枚数 1枚のみ 1枚のみ 16枚のみ 端末依存?
環境マッピング ×
タイリング × × ×
歪み補正 × × ×


ポリゴン

ver.1 ver.2 ver.3 ver.4
半透明 × 有段階 有段階 無段階
動的ポリゴン × ×
色ポリゴン × ×
プリミティブ × ×


光源
ver.1 ver.2 ver.3 ver.4
種類 × 環境光
平行光源
環境光
平行光源
環境光
平行光源
点光源
スポットライト
× 1個所のみ 1個所のみ 複数個所
× 白色光のみ 白色光のみ どんな色でも可


レンダリング
ver.1 ver.2 ver.3 ver.4
隠面消去 Zソート Zソート Zソート Zバッファ
投影法 平行投影 平行投影 平行投影
透視投影
平行投影
透視投影
シェーディング フラットシェーディング? グローシェーディング
トゥーンシェーディング
グローシェーディング
トゥーンシェーディング
グローシェーディング
トゥーンシェーディング
フォグ × × ×


用語



プレスリリース 

3Dデータの作成
マスコットカプセルの3Dデータ
2Dグラフィックスを表示するのにbmpなどの画像ファイルが必要なように、3Dグラフィックスを表示するのには3Dデータが必要です。マスコットカプセルで使用する3Dデータには次の3種類があります。 モデルデータとアクションデータは、マスコットカプセル専用のファイル形式です。市販の「3DCG作成ソフト」で作成した3Dデータを、コンバータやプラグインで変換して作ります。



3DCG作成ソフト
マスコットカプセル用のモデルデータやアクションデータを出力するためのプラグインが提供されている3DCG作成ソフトは次の6つです。
マスコットカプセル ver.2/ver.3 マスコットカプセル ver.4
3ds Max 5.0/5.1/6.0/7.0/8.0 5.0/5.1/6.0/7.0
Maya 5.0/6.0/6.5/7.0 5.0/6.0/6.5/7.0
LightWave 7.5以降 7.5以降
SoftImage|3D 3.9.22/4.0 なし
SoftImage|XSI 4.2/5.1 4.2
Blender 2.41 なし
メタセコイア なし 2.4以降


MascotCapsule Toolkit
3DCG作成ソフトの3Dデータをマスコットカプセル専用のファイル形式に変換するためのツール郡です。
マスコットカプセルのサイトから無償でダウンロードできます。
メタセコイアのプラグインはぐったりネットからダウンロードできます。 プラグインのインストール方法は3DCG作成ごとに異なります。マニュアルの指示に従って設定してください。その他のツールは解凍して好きなディレクトリに置くだけでOKです。



モデルデータとアクションデータの作成
モデルデータとアクションデータの作成の流れは次の通りです。プラグインでbacファイル・traファイルという中間データを出力し、ツールでポリゴン属性を編集したあと、コンバータでmbacファイルとmtraファイルに変換します。


3DCG作成ツール
まずはじめに3DCG作成ソフトを使って、3Dモデルデータとアクションデータを作ります。
  

マスコットカプセル専用のファイル形式に正しく変換するには、 などのマスコットカプセルの制限に注意する必要があります。詳しくはプラグインのマニュアルを参照して下さい。

プラグイン
モデルデータとアクションデータができたら、プラグインを使って3Dモデルデータを「bacファイル」に、アクションデータを「traファイル」に出力します。「Animation Master」では、モデル画面でメニューの「プラグイン→エクスポート→BAC VX.0」を選択すると「bacファイル」を、アクション画面でメニューの「プラグイン→エクスポート→TRA VX.0」を選択すると「traファイル」を出力します。「bacファイル」と「tarファイル」のバージョンはマスコットカプセルのバージョンと一致しないので注意してください。

bacバージョン traバージョン データ形式
マスコットカプセル ver.2 ver.5 ver.3 バイナリ
マスコットカプセル ver.3 ver.6 ver.4 テキスト(PVEx.exe使用不可)


PAC.exe
「PAC.exe」はポリゴンに透過、照光、反射などの属性を設定するためのツールです。 PAC.exeをダブルクリックするとウィンドウが開きます。そこに「bacファイル」をドラッグ&ドロップすると、モデルデータの展開図が表示されます。ポリゴンを選択後、メニューの「表示→ポリゴン属性」で「ポリゴン属性変更ウィンドウ」を開いて、そこで属性を設定します。


PVEx.exe
「PVEx.exe」はbacファイルとtraファイルが正しいデータかどうかを確認するためのビューアです。PVEx.exeを起動するとウィンドウが開きます。そこに「bacファイル」と「traファイル」とテクスチャとして使う「bmpファイル」をドラッグ&ドロップすると、モデルが表示されます。緑の三角ボタンを押すとアクションが再生されます。

モデルに穴があいている時は、ポリゴンの面の向きが逆の可能性が高いです。3DCG作成ソフトで法線(ポリゴンの面に対して垂直なベクトルで、ポリゴンの面の向きを表す線)を表示して確認してみてください。

Micro3DConv_DoCoMo.exe
「Micro3DConv_DoCoMo.exe」はbacファイルとtraファイルを「mbacファイル」と「mtraファイル」に変換するためのコンバーターです。Micro3DConv.exeを起動すると<<Micro3DConv.exe.bmp>>のようなウィンドウが開きます。「BAC file」にbacファイルを、「TRA file(s)」にtraファイルを、「Output directory」に出力先ディレクトリを指定します。「MTRA」の「One file」をチェックすれば、複数のtarファイルをひとつのmtarファイルに変換することもできます。準備できたらConvertボタンを押します。成功すれば、「mbacファイル」と「mtraファイル」が生成されます。


PVMicro.exe
「PVMicro.exe」はmbacファイルとmtraファイルが正しいデータかどうかを確認するためのビューアです。PVMicro.exeを起動するとウィンドウが開きます。そこに「mbacファイル」と「mtraファイル」とテクスチャとして使う「bmpファイル」をドラッグ&ドロップすると、モデルが表示されます。緑の三角ボタンを押すとアクションが再生されます。



iアプリの開発環境を整える
開発ツールの準備
3Dデータを表示するiアプリを作るには、次の4つの開発ツールが必要です。どれも無償で入手できます。

Java 2 SDK, Standard Edition Version 1.3(JDK1.3以降)
パソコン上で動くJavaアプリを作るための開発キットです。サン・マイクロシステムズのサイトで入手できます。次に説明するiαppli Development Kitを実行するのに必要なので、それより先にインストールします。インストーラの指示に従ってインストールしてください。

iαppli Development Kit for DoJa 3.5
iアプリを作るための開発キットです。NTTドコモのサイトで入手できます。ボタン1つでビルド(コンパイル+検証+JAR作成)やエミュレータでの実行ができます。インストーラの指示に従ってインストールしてください。Microsoft Windows 98 Second Edition/2000で動作します。

同サイトから開発に役立つドキュメントが入手できるので、いっしょにダウンロードしてください。
CLDC API Documentation, V1.0, Japanese
CLDCのAPIリファレンスはNTTドコモのサイトで入手できるドキュメントの中には含まれないので、サン・マイクロシステムズのサイトから入手してください。

micro3d_v3_32.dll
エミュレータで3Dポリゴンを表示するためのDLLです。マスコットカプセルのサイトで入手できます。iαppli Development Kitをインストールしたディレクトリのbinディレクトリ(C:\iDKDoJa3.5\bin)にコピーして下さい。これがないと、3Dポリゴンを表示するアプリをエミュレータで実行した時、例外が発生します。


平行投影でモデルを表示する
平行投影でモデルを表示するプログラムを作ります。方向キーでモデルを回転させることができます。平行投影は、モデルと投影面を結ぶ線がそれぞれ平行となる投影法です。モデルのサイズは視点の距離に左右されません。


今回のプログラムは、次の2つのクラスで構成されています。

Graphics3DExクラス
Graphics3DExクラスは、プログラムの本体となるクラスです。
Graphics3DEx.java
import com.nttdocomo.ui.*;



//3Dデータを表示する(本体)

public class Graphics3DEx extends IApplication {



    //アプリの開始

    public void start() {

        Graphics3DCanvas c=new Graphics3DCanvas();

        Display.setCurrent(c);

        c.exe();

    }

}


Graphics3DCanvasクラス
Graphics3DCanvasクラスは、キャンバスとなるクラスです。
Graphics3DCanvas.java
import com.nttdocomo.opt.ui.j3d.*;
import com.nttdocomo.ui.*;
import javax.microedition.io.*;
import java.io.*;

//平行投影でモデルを表示する(キャンバス)
class Graphics3DCanvas extends Canvas {
    //モデル
    Figure      figure; //モデル
    ActionTable action; //アクション
    Texture     texture;//テクスチャ
    int         frame;  //フレーム

    //回転
    int         rotX   =2048;             //X軸回転
    int         rotY   =0;                //Y軸回転
    AffineTrans transX =new AffineTrans();//X軸変換
    AffineTrans transY =new AffineTrans();//Y軸変換
    AffineTrans trans  =new AffineTrans();//視点座標

    //描画フラグ
    boolean drawable=false;

    //処理
    void exe() {
        int key;
        try {
            //モデルデータの読み込み
            figure=new Figure(
                Connector.openInputStream("resource:///pig.mbac"));

            //アクションデータの読み込み
            action=new ActionTable(
                Connector.openInputStream("resource:///pig.mtra"));

            //テクスチャデータの読み込み
            texture=new Texture(
                Connector.openInputStream("resource:///pig.bmp"),
                false);
            figure.setTexture(texture);

            //描画フラグ
            drawable=true;
        } catch (Exception e) {
        }

        while (true) {
            //キー操作
            key=getKeypadState();
            if (((1<<Display.KEY_UP)&key)!=0) {
               rotX+=256;
                if (rotX>4096) rotX-=4096;
            }
            if (((1<<Display.KEY_DOWN)&key)!=0) {
                rotX-=256;
                if (rotX<0) rotX+=4096;
            }
            if (((1<<Display.KEY_LEFT)&key)!=0) {
                rotY+=256;
                if (rotY>4096) rotY-=4096;
            }
            if (((1<<Display.KEY_RIGHT)&key)!=0) {
                rotY-=256;
                if (rotY<0) rotY+=4096;
            }

            //フレームの加算
            frame+=40960;
            if (frame>=action.getMaxFrame(0)) {
                frame-=action.getMaxFrame(0);
            }

            //再描画
            repaint();

            //スリープ
            try {
                Thread.sleep(100);
            } catch (Exception e) {
            }
        }
    }

    //描画
    public void paint(Graphics g) {
        if (!drawable) return;

        //Graphics3Dインタフェース
        Graphics3D g3=(Graphics3D)g;

        //光源の指定
        g3.setAmbientLight(4096/2);                      //環境光
        g3.setDirectionLight(new Vector3D(1,1,0),4096/2);//平行光源
        g3.enableLight(true);                            //光源処理ON

        //表示位置の指定
        g3.setScreenCenter(120,120);//表示位置

        //大きさの指定
        g3.setScreenScale(2048,2048);//大きさ

        //回転角度の指定
        transX.setRotateX(rotX); //X軸変換
        transY.setRotateY(rotY); //Y軸変換
        trans.mul(transX,transY);//視点座標
        g3.setViewTrans(trans);

        //ポーズの指定
        figure.setPosture(action,0,frame);

        //モデルの描画
        g.lock();
        g.setColor(g.getColorOfName(g.WHITE));//背景色指定
        g.fillRect(0,0,240,240);              //背景描画
        g3.drawFigure(figure);                //モデル描画
        g.unlock(true);
    }
}


モデルデータの読み込み
モデルデータはFigureクラスで読み込みます。

Figureクラスには2種類のコンストラクタがあります。
Figure(byte[] data)
data:モデルデータ
Figure(InputStream is)
is:モデルデータの入力ストリーム

今回のプログラムは"pig.mbac"を読み込みます。
Graphics3DCanvas.javaの一部
figure=new Figure(
    Connector.openInputStream("resource:///pig.mbac"));

Figureクラスには、モデルの外見状態を指定するsetPattern()メソッドとsetNumPattern()メソッドがありますが、複数の外見状態を持つ3Dデータの作り方は公開されてないようです(見逃してるだけかも)。


アクションデータの読み込み
アクションデータはActionTableクラスで読み込みます。ActionTableクラスには2種類のコンストラクタがあります。
ActionTable(byte[] data)
data:アクションデータ
ActionTable(InputStream is)
is:アクションデータの入力ストリーム

今回のプログラムは"pig.mtra"を読み込みます。
Graphics3DCanvas.javaの一部
action=new ActionTable(
    Connector.openInputStream("resource:///pig.mtra"));


テクスチャデータの読み込み
テクスチャデータはTextureクラスで読み込みます。

Textureクラスには2種類のコンストラクタがあります。
Texture(byte[] data, boolean forEnv)
data:テクスチャデータ
forEnv:環境マッピングのために使うかどうか
Texture(java.io.InputStream is, boolean forEnv)
is:テクスチャデータの入力ストリーム
forEnv:環境マッピングのために使うかどうか
「環境マッピング」とは、鏡面反射による背景の映り込みを擬似的に再現するものです。

今回のプログラムは"pig.bmp"を読み込み、環境マッピングではなく通常のテクスチャとして使用します。
Graphics3DCanvas.javaの一部
texture=new Texture(
    Connector.openInputStream("resource:///pig.bmp"),
    false);
figure.setTexture(texture);

Textureクラスには、トゥーンシェーディングのためのsetNormalShader()メソッドとsetToonShader()メソッドがありますが、どちらもDoJa-2.0との互換のため残されているもので、通常使いません。


Graphics3Dインタフェース
スクリーンの設定やモデルの描画を行うには、Graphics3Dインタフェースのメソッドを使います。GraphicsクラスのオブジェクトをGraphics3D形式にキャストしてください。
Graphics3D g3=(Graphics3D)g;


光源の設定
3Dグラフィックスでは物体は光をあててできる陰によって立体的に見せます。光源の種類には「環境光」と「平行光源」があります。

「環境光」は、光源からの光が何度となく反射を繰り返して、方向を特定できない光のことです。どの位置でも一定に明るくします。
void setAmbientLight(int intensity)
intensity:光の強さ(0〜4096)

「平行光源」は、空間中のあらゆる場所に同一方向から照らされる光の光源です。光の当たっている場所を明るくします。
void setDirectionLight(Vector3D direction,int intensity)
direction:方向
intensity:光の強さ(0〜4096)

光源処理の設定をレンダリングに反映させるかどうかを指定するには、enableLight()メソッドを使います。
void enableLight(boolean on)
on:ON・OFF

今回のプログラムは次のように指定します。
Graphics3DCanvas.javaの一部
g3.setAmbientLight(3072);
g3.setDirectionLight(new Vector3D(1,1,0),2048);
g3.enableLight(true);


表示位置の指定
モデルの表示位置を指定するにはsetScreenCenter()メソッドを使います。
void setScreenCenter(int cx,int cy)
cx:表示位置のX座標
cy:表示位置のY座標

今回のプログラムは、モデルの表示位置に(120,120)を指定します。
Graphics3DCanvas.javaの一部
g3.setScreenCenter(120,120);//表示位置


大きさの指定
平行投影を指定するには、次の2つの方法があります。、 これによって、モデル表示の大きさが決まります。

スクリーンのスケールで指定するには、setScreenScale()メソッドを使います。初期状態では(4096,4096)が指定されています。
void setScreenScale(int sx,int sy)
sx:X方向の大きさ(デフォルトは4096)
sy:Y方向の大きさ(デフォルトは4096)

投影面の幅と高さで指定するには、setScreenView()メソッドを使います。幅と高さを大きくすると、レンダリングの対象となる領域が広がるため、結果としてモデルはより小さくレンダリングされることになります。
void setScreenView(int width,int height)
width:投影面の幅
height:投影面の高さ

今回のプログラムはスクリーンのスケールで指定する方法で大きさに(2048,2048)を指定します。
Graphics3DCanvas.javaの一部
g3.setScreenScale(2048,2048);//大きさ


回転角度の指定
モデルの回転角度を指定するには、Graphics3DインタフェースのsetViewTrans()メソッドを使います。
void setViewTrans(AffineTrans at)
at:視点座標への変換行列

変換行列とは、図形や視点座標がどの程度回転しているかを保持します。X軸中心に回転するにはsetRotateX()メソッド、Y軸中心に回転するにはsetRotateY()メソッド、Z軸中心に回転するにはsetRotateZ()メソッドを使います。引数には4096分円単位で角度を指定します。
void setRotateX(int a)
a:角度(4096分円単位)
void setRotateY(int a)
a:角度(4096分円単位)
void setRotateZ(int a)
a:角度(4096分円単位)

これらのメソッドは、現在の角度からどの程度回転させるかでなく、初期状態からどの程度回転させるかを指定します。そのため、X軸とY軸を同時に回転するには、X軸回転のAffineTrans型変数とY軸回転のAffineTrans型変数を作り、それを掛け算したAffineTrans型変数を作る必要があります。掛け算はmul()メソッドで行います。
Graphics3DCanvas.javaの一部
transX.setRotateX(rotX);
transY.setRotateY(rotY);
trans.mul(transX,transY);
g3.setViewTrans(trans);


ポーズの指定
モデルにどのアクションの何フレーム目のポーズをとらるかを指定するには、FigureクラスのsetPosture()メソッドを使います。
void setPosture(ActionTable action,int index,int frame)
action:アクションデータ
index:アクションインデックス
frame:フレーム(65536分フレーム単位)

アクションインデックスは、mtraファイルに複数のアクションが含まれている時、どのアクションを使うかを指定するためのものです。アクションがひとつの時は0のみです。フレーム番号を増やしながら描画することにより、モデルのアニメーションを表示することができます。アクションの最大フレーム数は、ActionTableクラスのgetMaxFrame()メソッドで取得できます。
int getMaxFrame(int index)
index:アクションインデックス
戻り値:最大フレーム数(65536分フレーム単位)

今回のプログラムは1フレーム間隔(つまり指定するのは1*65536=65536)で加算しています。
Graphics3DCanvas.javaの一部
frame+=65536;
if (frame>=action.getMaxFrame(0)) {
    frame-=action.getMaxFrame(0);
};
Graphics3DCanvas.javaの一部
figure.setPosture(action,0,frame);


モデルの描画
モデルを描画するには、drawFigure()メソッドを使います。
void drawFigure(Figure figure)
figure:モデルデータ

今回のプログラムの描画処理は次のようになります。
Graphics3DCanvas.javaの一部
g.lock();
g.setColor(g.getColorOfName(g.WHITE));//背景色指定
g.fillRect(0,0,240,240);              //背景描画
g3.drawFigure(figure);                //モデル描画
g.unlock(true);
透視投影でモデルを表示する
透視投影でモデルを表示するプログラムを作ります。左右キーでカメラの向きの変更を、上下キーでカメラの前進と後進を行うことができます。透視投影は、視点から遠くのものは小さく、近くのものは大きく表示することにより遠近感を出す投影法です。モデルのサイズは視点からの距離に左右されます。視点から近すぎる、遠すぎる、視線とは反対方向にあるモデルは描画されません。描画される空間の視点から最も近い面をニアクリップ面、最も遠い面をファークリップ面といいます。


今回のプログラムは、次の2つのクラスで構成されています。

PerspectiveExクラス
PerspectiveExクラスは、プログラムの本体となるクラスです。
PerspectiveEx.java
import com.nttdocomo.ui.*;

//透視投影でモデルを表示する(本体)
public class PerspectiveEx extends IApplication {

    //アプリの開始
    public void start() {
        PerspectiveCanvas c=new PerspectiveCanvas();
        Display.setCurrent(c);
        c.exe();
    }
}


PerspectiveCanvasクラス
PerspectiveCanvasクラスは、キャンバスとなるクラスです。
PerspectiveCanvas.java
import com.nttdocomo.opt.ui.j3d.*;
import com.nttdocomo.ui.*;
import javax.microedition.io.*;
import java.io.*;
import com.nttdocomo.opt.ui.j3d.Math;

//透視投影でモデルを表示する(キャンバス)
class PerspectiveCanvas extends Canvas {
    //モデル
    Figure      figure; //モデル
    ActionTable action; //アクション
    Texture     texture;//テクスチャ
    int         frame;  //フレーム

    //視野座標
    int lookX  =0;   //X座標
    int lookZ  =256; //Z座標
    int lookDir=3072;//方向
    AffineTrans trans=new AffineTrans();//視野座標

    //描画フラグ
    boolean drawable=false;

    //処理
    void exe() {
        int key;
        try {

            //モデルデータの読み込み
            figure=new Figure(
                Connector.openInputStream("resource:///pig.mbac"));

            //アクションデータの読み込み
            action=new ActionTable(
                Connector.openInputStream("resource:///pig.mtra"));

            //テクスチャデータの読み込み
            texture=new Texture(
                Connector.openInputStream("resource:///pig.bmp"),
                false);
            figure.setTexture(texture);

            //描画フラグ
            drawable=true;
        } catch (Exception e) {
        }

        while (true) {
            //キー操作
            key=getKeypadState();
            if (((1<<Display.KEY_UP)&key)!=0) {
                lookX+=Math.cos(lookDir)/100;
                lookZ+=Math.sin(lookDir)/100;
            }
            if (((1<<Display.KEY_DOWN)&key)!=0) {
                lookX-=Math.cos(lookDir)/100;
                lookZ-=Math.sin(lookDir)/100;
            }
            if (((1<<Display.KEY_LEFT)&key)!=0) {
                lookDir-=113;
                if (lookDir<0) lookDir+=4096;
            }
            if (((1<<Display.KEY_RIGHT)&key)!=0) {
                lookDir+=113;
                if (lookDir>4096) lookDir-=4096;
            }

            //フレームの加算
            frame+=40960;
            if (frame>=action.getMaxFrame(0)) {
                frame-=action.getMaxFrame(0);
            }

            //再描画
            repaint();

            //スリープ
            try {
                Thread.sleep(100);
            } catch (Exception e) {
            }
        }
    }

    //描画
    public void paint(Graphics g) {
        if (!drawable) return;

        //Graphics3Dインタフェース
        Graphics3D g3=(Graphics3D)g;

        //光源の指定
        g3.setAmbientLight(4096/2);                      //環境光
        g3.setDirectionLight(new Vector3D(1,1,0),4096/2);//平行光源
        g3.enableLight(true);                            //光源処理ON

        //表示位置の指定
        g3.setScreenCenter(120,120);//表示位置

        //視野の広さの指定
        g3.setPerspective(10,4086,1024);

        //視野座標の指定
        trans.lookAt(
            new Vector3D(lookX,0,lookZ), //視点
            new Vector3D(
                lookX+Math.cos(lookDir),0,
                lookZ+Math.sin(lookDir)),//参照点
            new Vector3D(0,4096,0));     //UPべクトル
        g3.setViewTrans(trans);

        //ポーズの指定
        figure.setPosture(action,0,frame);

        //モデルの描画
        g.lock();
        g.setColor(g.getColorOfName(g.WHITE));//背景色指定
        g.fillRect(0,0,240,240);              //背景描画
        g3.drawFigure(figure);                //モデル描画
        g.unlock(true);
    }
}


視野の広さの指定
透視投影を指定するには、次の2つの方法があります。、 これによって、視野の広さが決まります。

視野角で指定するには、setPerspective()メソッドを使います。
void setPerspective(int zNear,int zFar,int angle)
zNear:カメラからニアクリップ面までの距離
zFar:カメラからファークリップ面までの距離
angle:視野角(4096分周円表現で1〜2047、すなわち0度〜180度)

投影面の幅と高さで指定するには、setPerspective()メソッドを使います。
void setPerspective(int zNear,int zFar,int width,int height)
zNear:カメラからニアクリップ面までの距離
zFar:カメラからファークリップ面までの距離
width:ニアクリップ面における投影面の幅
height:ニアクリップ面における投影面の高さ

今回は、視野角で指定する方法でニアクリップ面に10、ファークリップ面に4086、視野角に90度(1024)を指定するので、次のようになります。
PerspectiveCanvas.javaの一部
g3.setPerspective(10,4086,1024);


視野座標の指定
視点から参照点を見る時の視野座標を生成するには、lookAt()メソッドを使います。
void lookAt(Vector3D position,Vector3D look,Vector3D up)
position:視点への位置ベクトル
look:参照点への位置ベクトル
up:Upベクトル
視線方向とUpベクトルが垂直でない時は、視線方向と垂直になるようにUpベクトルが修正された上で、変換行列が生成されます。

今回は、視点(lookX,0,lookZ)、参照点(lookX+Math.cos(lookDir),0,lookZ+Math.sin(lookDir))、Upべクトル(0,4096,0)を指定するので、次のようになります。
PerspectiveEx.javaの一部
trans.lookAt(
    new Vector3D(lookX,0,lookZ), //視点
    new Vector3D(
        lookX+Math.cos(lookDir),0,
        lookZ+Math.sin(lookDir)),//参照点
    new Vector3D(0,4096,0));     //UPべクトル
g3.setViewTrans(trans);


数値演算ユーティリティ
数値演算ユーティリティ
com.nttdocomo.opt.ui.j3d.Mathクラスは数値計算のためのユーティリティクラスです。平方根と三角関数の計算を行うことができます。com.nttdocomo.uiパッケージにも同じ名前のクラスがあるので、衝突しないようにしください。



平方根
平方根とは、同じ数をかけたらその数になる、その元の数のことです。2x2は4なので4の平方根(√4)は2、4x4は16なので16の平方根(√16)は4となります。

平方根を計算するにはsqrt()メソッドを使います。
static int sqrt(int x)
x:整数値
戻り値:平方根の近似値

4の平方根と16の平方根を計算するプログラムは以下の通りです。
MathEx.javaの一部
g.drawString("sqrt(4) ="+Math.sqrt(3),0,13);
g.drawString("sqrt(16)="+Math.sqrt(9),0,13*2);



三角関数
三角関数とは、直角三角形の時に成り立つ、角度から位置を求める方法のことです。sin(サイン、正弦)とcos(コサイン、余弦)は、直角三角形の辺長の割合のことで、点Aの座標は(Rcosθ,Rsinθ)となります。


余弦(cos、コサイン)
static int cos(int a)
a:角度を4096分円単位で指定
戻り値:余弦の近似値
角度は4096分円単位で指定します。0度の時は0、360度の時は4096となります。戻り値は指定された角度の余弦の4096倍の値となります。

0度(0)、45度(4096/8)、90度(4096/4)の余弦を計算するプログラムは以下の通りです。
MathEx.javaの一部
g.drawString("cos(0) ="+Math.cos(0), 0,13*4);
g.drawString("cos(4096/8)="+Math.cos(4096/8),0,13*5);
g.drawString("cos(4096/4)="+Math.cos(4096/4),0,13*6);


正弦(sin、サイン)
static int cos(int a)
a:角度を4096分円単位で指定
戻り値:余弦の近似値
角度は4096分円単位で指定します。0度の時は0、360度の時は4096となります。戻り値は指定された角度の余弦の4096倍の値となります。

0度(0)、45度(4096/8)、90度(4096/4)の正余弦を計算するプログラムは以下の通りです。
MathEx.javaの一部
g.drawString("sin(0) ="+Math.sin(0), 0,13*8);
g.drawString("sin(4096/8)="+Math.sin(4096/8),0,13*9);
g.drawString("sin(4096/4)="+Math.sin(4096/4),0,13*10);


逆正接(atan、アークタンジェント)
static int atan2(int a,int b)
a:intに格納された固定小数点値
b:intに格納された固定小数点値
戻り値:逆正接
aとbに指定された値から、a/bの逆正接を計算します。ただし、このメソッドはN504i・N504iS・N2051では使えません。



サンプルプログラム
MathEx.java
import com.nttdocomo.ui.*;

//数値演算ユーティリティ(本体)
public class MathEx extends IApplication {

    //アプリの開始
    public void start() {
        Display.setCurrent(new MathCanvas());
    }
}


MathCanvas.java
import com.nttdocomo.opt.ui.j3d.Math;
import com.nttdocomo.ui.Canvas;
import com.nttdocomo.ui.Graphics;

//数値演算ユーティリティ(キャンバス)
class MathCanvas extends Canvas {
    //描画
    public void paint(Graphics g) {
        //平方根
        g.drawString("sqrt(4) ="+Math.sqrt(3),0,13);
        g.drawString("sqrt(16)="+Math.sqrt(9),0,13*2);

        //余弦
        g.drawString("cos(0)     ="+Math.cos(0),     0,13*4);
        g.drawString("cos(4096/8)="+Math.cos(4096/8),0,13*5);
        g.drawString("cos(4096/4)="+Math.cos(4096/4),0,13*6);

        //正弦
        g.drawString("sin(0)     ="+Math.sin(0),     0,13*8);
        g.drawString("sin(4096/8)="+Math.sin(4096/8),0,13*9);
        g.drawString("sin(4096/4)="+Math.sin(4096/4),0,13*10);
    }
}

ベクトル
ベクトル
ベクトルとは向きと長さを表す数のことです。高レベル3Dグラフィックスでは、3次元の固定小数点数ベクトルを使います。ベクトルの値はVector3Dクラスで保持し、このベクトル各成分は1.0を4096にマッピングする固定小数点数として扱われます。Vector3Dクラスは1x3の行列で、それを操作するためのメソッド郡を持っています。
[ x,y,z
]

指定する値 意味
0 0.0
2048 0.5
4096 1.0


正規化
正規化(単位ベクトル化)します。 単位ベクトルの長さは4096です。
void normalize()


内積
dot()メソッド
内積を計算します。内積は2つのベクトルからその角度を取得する時に使います。
int dot(Vector3D v)
v:ベクトル
戻り値:内積の値

int dot(Vector3D v1,Vector3D v2)
v1:ベクトル
v2:ベクトル
戻り値:内積の値


外積
cross()メソッド
外積を計算します。外積は2つのベクトルから、直交するベクトルを取得する時に使います。
int cross(Vector3D v)
v:ベクトル
戻り値:外積の値

int dot(Vector3D u,Vector3D v)
u:ベクトル
v:ベクトル
戻り値:外積の値



アフィン変換


アフィン変換
アフィン変換とは、モデルを回転・拡大縮小・平行移動などを行う変換のことです。アフィン変換によってどのような回転を行うかはAffineTransクラスで保持します(拡大縮小・平行移動などは保持しません)。高レベル3Dグラフィックスでは、拡大縮小にGraphics3D.setScreenScale()メソッド、平行移動にGraphics3D.setScreenCenter()メソッドを使うため、AffineTransクラスで保持するのはモデルがどの程度回転しているかのみです。AffineTransクラスは3x4の行列で、それを操作するためのメソッド郡を持っています。
[ a00,a01,a02,a03
a10,a11,a12,a13
a20,a21,a22,a23
]


要素の指定
setElement()メソッド
行列の1つ、または全ての要素を指定します。
void setElement(int row,int column,int value)
row:行
column:列
value:値

void setElement(int a00,int a01,int a02,int a03,int a10,int a11,int a12,int a13,int a20,int a21,int a22,int a23)
a00:1行1列の要素
a01:1行2列の要素
a02:1行3列の要素
a03:1行4列の要素
a10:2行1列の要素
a11:2行2列の要素
a12:2行3列の要素
a13:2行4列の要素
a20:3行1列の要素
a21:3行2列の要素
a22:3行3列の要素
a23:3行4列の要素

setColumn()メソッド
行列の1列の要素を指定します。
void setColumn(int column,int x,int y,int z)
column:列
x:1行の要素
y:2行の要素
z:3行の要素

setRow()メソッド
行列の1行の要素を指定します。
void setRow(int row,int x,int y,int z,int w)
row:行
x:第1列の要素
y:第2列の要素
z:第3列の要素
w:第4列の要素

setIdentity()メソッド
恒等変換を行います。setElement(4096,0,0,0,0,4096,0,0,0,0,4096,0)を呼び出したのと同じ結果になります。
void setIndentity()


回転
setRotateX()メソッド
X軸中心の回転させます。
void setRotateX(int a)
a:角度を4096分円単位で指定

setRotateY()メソッド
Y軸中心の回転させます。
void setRotateY(int a)
a:角度を4096分円単位で指定

setRotateZ()メソッド
Z軸中心の回転させます。
void setRotateZ(int a)
a:角度を4096分円単位で指定

setRotateV()メソッド
任意のベクトルの軸中心の回転させます。
void setRotateV(Vector3D v,int a)
v:回転の中心となるベクトル
a:角度を4096分円単位で指定


その他
mul()メソッド
変換行列の積を計算します。
void mul(AffineTrans t)
t:乗数となる変換行列

void mul(AffineTrans t1,AffineTrans t2)
t1:被乗数となる変換行列
t2:乗数となる変換行列

transform()メソッド
点の座標を表すベクトルを、この変換行列で変換して、 結果を別のベクトルに格納します。
void transform(Vector3D v,Vector3D result)
v:点の座標を表すベクトル
result:変換結果を格納するベクトル

lookAt()メソッド
視点から参照点を見る時の視野座標を生成することができます。レースゲームで車の後斜め上にカメラを設置したい時などに便利です。視線方向とUpベクトルが垂直でない時は、視線方向と垂直になるようにUpベクトルが修正された上で、 変換行列が設定されます。
void lookAt(Vector3D position,Vector3D look,Vector3D up)
position:視点への位置ベクトル
look:参照点への位置ベクトル
up:Upベクトル





−戻る−