1-3 3次元世界に動きをつける
前のページでは、3次元の球を表示し、自分で視点を変えたり、回転することができました。しかし物体そのものが動かなければ何の意味もありません。
この章では、Javaを1行も書かなくても、複雑なアニメーションを行うシーンを書くための十分な知識が得られ、VRML2.0のメカニズムに対する十分な基礎知識がこの章では身につくことができます。
では、その動きをつけるためにはどうしたらよいのか?それには3つの方法があります。
- APIによるもの
シーンを変更するためのプロシージャやメソッドがプログラマに提供されています。
- 言語によるもの
VRML1.0を普通のプログラミング言語に発展させ、他から独立した3次元プログラミングの専用言語にしたもの
- イベントによるもの
外部の言語とシーンとの間で、イベントのやりとりを行うもの。
実行モデルの詳細
物体を動的なものにするためには、”実行モデル”を通して、シーン上のものを変化させる、ということである。
では、VRML2.0に対するフィールドはさまざまありまして、その例を紹介したいと思います。
次のクラスに分類されるのはeventInフィールドです。eventInフィールドでは、イベントを受け取り、自らの値をイベントの値を書きかえるようなフィールドのことを指し示す。
最後のクラスは、eventInとeventOutを組み合わせたもので、exposedFieldフィールドといいます。exposedFieldとは、イベントにより値を設定するとともに、その値をイベントとして出すようなフィールドのことを指し示す。exposedFieldは2つのフィールドの組み合わせに対する略記法で、イベントの送信者かつ受信者として動作します。
- Transformノード
VRML2.0からもらったTransformノードは次のようになっています。
Transform { |
 | eventIn | MFNode | addChildren | |
eventIn | MFNode | removeChildren |
exposedField | MFNode | children | [ ] |
exposedField | SFRotation | rotation | 0 0 1 0 |
exposedField | SFVec3f | scale | 1 1 1 |
exposedField | SFRotation | scaleOrientation | 0 0 1 0 |
exposedField | SFVec3f | center | 0 0 0 |
exposedField | SFVec3f | translation | 0 0 0 |
field | SFVec3f | bboxCenter | 0 0 0 |
field | SFVec3F | bboxSize | -1 -1 -1 |
} |
- PositionInterPolatorノード
インターポレーターとは、アニメーションを簡単に実現してくれるノードです。このノードに範囲を指定する数値を与えると、
PositionInterpolator { |
 | evrntIn | SSFloat | set_fraction | |
exposedField | MMFloat | key | [ ] |
exposedField | MFvec3f | keyValue | [ ] |
eventOut | SFVec3f | value_changed | |
} |
- TimeSenserノード
タイムセンサノードとは、連続的なシミュレーション、周期的な運動、そして、1回だけ鳴るアラームなど、いろいろな目的に使うことが可能である。
TimeSensor { |
 | exposedField | SFTime | cycleInterval | 1 |
exposedField | SFBool | enabled | TRUE |
exposedField | SFBool | Loop | TRUE |
exposedField | SFTime | startTime | 0 |
exposedField | SFTime | stopTime | 0 |
eventOut | SFTime | cycleTime | |
eventOut | SFFloat | fraction_changed |
eventOut | SFBool | isActive |
eventOut | SFTime | time |
} |
- TouchSecsorノード
ユーザーによるイベントで、アニメーションをマウスクリックで始めることが可能になります。もしこれがないと、アニメーションを止めることができません。
TouchSensor { |
 | exposedField | SFBool | enabled | TRUE |
eventOut | SFVec3f | hitNormal_changed | |
eventOut | SFVec3f | hitPoint_changed |
eventOut | SFVec2f | hitTexCoord_changed |
eventOut | SFBool | isActive |
eventOut | SFBool | isOver |
eventOut | SFTime | touchTime |
} |
左側からそれぞれ、フィールドのクラス。その隣がフィールドの型、次がフィールド名、一番右側がそのフィールドの持つデフォルト値です。
基本的には左から1番目と2番目の部分は省略してもよいし、一番右側の部分は定数といい、省略することもでき、その時定数となる。
フィールドの型
フィールドには属性を指定することができます。ノードの最も一般的な型は、1つの値(プレフィックスはSF)のものと、複数のパラメータ値(プレフィックスはMF)のものとあります。MFフィールドは特に大括弧[ ]内に値を入れなければなりません。
フィールド型とそれを受け取る引数を表にして表しています。
フィールド型 |
受け取る引数 |
SFNode/MFNode |
VRMLのノード |
SFBool |
TRUEあるいはFALSE |
SFColor/MFColor |
赤、緑、青に相当する0.0〜1.0までの3つの浮動小数点値 |
SFFloat/MFFloat |
単精度浮動小数点値 |
SFImage |
Pixelイメージマップの記述 |
SFInt32/MFInt32 |
32ビット整数 |
SFRotaion/MFRotation |
4つの値:最初の3つは回転ベクトル、最後の値は回転量(単位はラジアン) |
SFString/MFString |
文字列(utf8) |
SFTime/MFTime |
1970年1月からの経過秒数(倍精度浮動小数点) |
SFVec2f/MFVec2f |
SFFloatの2次元ベクトル |
SFVec3f/MFVec3f |
SFFlortの3次元ベクトル |
VRMLのノード
VRML2.0のノードは、2つの基本的な種類に分けられます。グラフィカルなものと、非グラフィカルなものです。グラフィカルノードでは、BoxやSphereのような幾何学図形のようなものがあります。属性ノードにはAppearance, Materialのようなものがあり、親ノードにはShapeやTransformがあります。これらのノードは、シーンを組み立てるノードです。VRML2.0のグラフィカルノードを、以下のようにまとめておきます。
グループノード |
幾何図形ノード |
属性ノード |
Shape |
Box |
Appearance |
Anchor |
Cone |
Color |
Billboard |
Cylinder |
Coordinate |
Collision |
ElevationGrid |
FontStyle |
Group |
Extrusion |
ImageTexture |
Translation |
IndexedFaceSet |
Material |
Inline |
IndexedLineSet |
MovieTexture |
LOD |
PointSet |
Normal |
Switch |
Sphere |
PixelTexture |
|
Text |
TextureCoordinate |
|
|
TextureTransform |
ルーティング
ここまでは、実行モデルの基礎で、フィールドがイベントの送信、受信、またはその両方のどれであるかを宣言する方法についての説明でありました。
ここから、ノード間でのイベントのやりとりをどうすればいいのか?その結び付けを行うのか、ルートになります。
ルートを使うことで、あるイベントの送信者と受信者になるフィールドを指定し、ノード間をつなげることができる。記述方式は、
ROUTE node.”デフォルト値” to node.”デフォルト値”
となり、最初のほうは送信側、後は受信側になっています。
ルーティングを使うことで、Transformノードに動きをつけるために、Interporatorノードを加えると、図では次のように表せる。
この例では、インターポレータのフィールド名value_changedのフィールドクラスがeventOutになっており、Transformノードへ出力する。さらに、Timesensorノードを用いると、次のようになる。
タイムセンサノードのフィールド名、fraction_changedのフィールドクラスがeventOutで、それをインターポレータのset_fractionがフィールドクラスがeventInにデータを渡している。この例を次の実践プログラムのページにいってみましょう。
|