VRML
1 VRMLだけで動きを出す。
1-1 簡単なVRMLプログラム
1-2 さらに発展したプログラム
1-3 3次元世界に動きをつける。
1-4 実践プログラム
1-3 3次元世界に動きをつける

 前のページでは、3次元の球を表示し、自分で視点を変えたり、回転することができました。しかし物体そのものが動かなければ何の意味もありません。
 この章では、Javaを1行も書かなくても、複雑なアニメーションを行うシーンを書くための十分な知識が得られ、VRML2.0のメカニズムに対する十分な基礎知識がこの章では身につくことができます。
 では、その動きをつけるためにはどうしたらよいのか?それには3つの方法があります。

  • APIによるもの

  •  シーンを変更するためのプロシージャやメソッドがプログラマに提供されています。

  • 言語によるもの

  •  VRML1.0を普通のプログラミング言語に発展させ、他から独立した3次元プログラミングの専用言語にしたもの

  • イベントによるもの

  •  外部の言語とシーンとの間で、イベントのやりとりを行うもの。

実行モデルの詳細

 物体を動的なものにするためには、”実行モデル”を通して、シーン上のものを変化させる、ということである。
 では、VRML2.0に対するフィールドはさまざまありまして、その例を紹介したいと思います。

 次のクラスに分類されるのはeventInフィールドです。eventInフィールドでは、イベントを受け取り、自らの値をイベントの値を書きかえるようなフィールドのことを指し示す。
 最後のクラスは、eventInとeventOutを組み合わせたもので、exposedFieldフィールドといいます。exposedFieldとは、イベントにより値を設定するとともに、その値をイベントとして出すようなフィールドのことを指し示す。exposedFieldは2つのフィールドの組み合わせに対する略記法で、イベントの送信者かつ受信者として動作します。

  1. Transformノード

  2.  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
    }

  3. PositionInterPolatorノード

  4.  インターポレーターとは、アニメーションを簡単に実現してくれるノードです。このノードに範囲を指定する数値を与えると、

    PositionInterpolator  {
    evrntIn SSFloat set_fraction  
    exposedField MMFloat key [ ]
    exposedField MFvec3f keyValue [ ]
    eventOut SFVec3f value_changed  
    }

  5. TimeSenserノード

  6.  タイムセンサノードとは、連続的なシミュレーション、周期的な運動、そして、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
    }

  7. TouchSecsorノード

  8.  ユーザーによるイベントで、アニメーションをマウスクリックで始めることが可能になります。もしこれがないと、アニメーションを止めることができません。

    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ノードを加えると、図では次のように表せる。

Interporator

 この例では、インターポレータのフィールド名value_changedのフィールドクラスがeventOutになっており、Transformノードへ出力する。さらに、Timesensorノードを用いると、次のようになる。

Time Senser

 タイムセンサノードのフィールド名、fraction_changedのフィールドクラスがeventOutで、それをインターポレータのset_fractionがフィールドクラスがeventInにデータを渡している。この例を次の実践プログラムのページにいってみましょう。