VRML with JavaScript Tutorial

戻る はじめに / テクスチャー

貼り方の指定

形状へのテクスチャーの貼り方を指定できる TextureTransform ノードについて。

テクスチャー座標変換

テクスチャーの座標は左下が原点 ( 0.0, 0.0 )、右上が ( 1.0, 1.0 ) の2次元ベクトルで表されます。

テクスチャー画像 map.gif
( 0.0, 1.0 ) ( 1.0, 1.0 )
texture image
( 0.0, 0.0 ) ( 1.0, 0.0 )

texture coord
VRML - ソース / X3D - ソース
Box (箱)、Cylinder (円筒)、Cone (円錐)、Sphere (球) を表す形状ノードに対して基本的にどの様にテクスチャーが貼られるかを確かめることが出来ます。
ポインタで形状を触れると、その部分のテクスチャー座標 ( x, y ) が表示されます。  また、形状をクリックすると、箱 → 円筒 → 円錐 → 球 → 箱 の繰り返しで形状を切り替えることができます。
( Cortona VRML Client 3.1 ならば、Cone (円錐)の側面のテクスチャー座標が得られない不具合があります。)



基本的なテクスチャーの貼り方から座標変換を指定するためのノードが TextureTransform です。
TextureTransform {
exposedField SFVec2f center 0.0 0.0# 回転と拡大縮小の中心座標
exposedField SFFloat rotation 0.0# 回転角度
exposedField SFVec2f scale 1.0 1.0# 拡大縮小率
exposedField SFVec2f translation 0.0 0.0# 平行移動量
}
texture translation
VRML - ソース / X3D - ソース
Box ノードに貼られたテクスチャー対して TextureTransform ノードで translation 0.25 0.25 を指定してみました。
本来の貼られ方と比べて、左下に( 0.25, 0.25 ) の分だけ移動して貼られています。  Transform ノードで translation 0.25 0.25 0 を指定すると、右上に形状が移動するのですが、それとは逆方向であることに注意してください。

texture rotation
VRML - ソース / X3D - ソース
テクスチャーの中央を中心に45度 ( 0.7854 ) 傾けて貼ってみました。
テクスチャーの中央 ( 0.5, 0.5 ) を指定するには、TextureTransform ノードで center -0.5 -0.5 を指定しなくてはいけません。  本来の座標から符号が反転します。
( バージョン 3.1 以下の Cortona VRML Clientならば左のイメージとは異なり、テクスチャーは上下左右に反復されて貼られます。)

texture scale
VRML - ソース / X3D - ソース
TextureTransform ノードで scale 0.5 2 を指定してみました。
原点 ( 0.0, 0.0 ) を中心に、x 方向の大きさが 2 倍に拡大され、 y 方向の大きさは半分に縮小されています。  テクスチャーはその大きさが指定した値の逆数に従って拡大縮小されて貼られます。


TextureTransform ノードにおいて複数のフィールドが指定された場合、 center を中心に scale による拡大縮小と rotation による回転が行われてから translation による平行移動が行われます。

アニメーション

テクスチャー座標のキーフレーム法によるアニメーションを行ってみます。
TextureTransform ノードのフィールドは rotation を除き、 SFVec2f 型です。  VRML2.0 の仕様に SFVec2f を補完できる Interpolator タイプのノードはありません。  そこで、プロトタイプ PositionInterpolator2D を組んでみました。
VRML - ソース
このファイルはプロトタイプの定義だけなので、実行しても何も表示されません。
このプロトタイプは SFVec3f の補完ノードである PositionInterpolator の x,y だけを利用しています。  VRML2.0 の仕様により Script ノードで exposedField を定義出来ない為に、 TextureCoordinate ノードを仮の MFVec2f keyValue の置き場として使っています。  スクリプトは MFVec2f からMFVec3f へと SFVec3f からSFVec2f への型変換に使われています。

ちなみに CortonaPosition2Interpolator ノードが、 Cortona VRML Client 5.0 以上と blaxxun Contact 5.0 以上 は PositionInterpolator2D ノードが独自に機能追加されているため、これらを利用すればこのプロトタイプは必要ありません。

X3D においては PositionInterpolator2D ノードは標準の仕様として備わっています。

texture translation animation
VRML - ソース / X3D - ソース
translation (貼付位置)のアニメーションです。

texture rotation animation
VRML - ソース / X3D - ソース
rotation (貼付回転角度)のアニメーションです。
このフィールドは SFFloat 型のため、ScalarInterpolator ノードを使っています。
( バージョン 3.1 以下の Cortona VRML Clientならば左のイメージとは異なり、テクスチャーは上下左右に反復されて貼られます。)

texture scale animation
VRML - ソース / X3D - ソース
scale (貼付拡大縮小率)のアニメーションです。

texture center animation
VRML - ソース / X3D - ソース
rotation (貼付回転角度)のアニメーションと共に、center (中心位置)の移動アニメーションも行っています。
( バージョン 3.1 以下の Cortona VRML Clientならば左のイメージとは異なり、テクスチャーは上下左右に反復されて貼られます。)

ある部分を拡大表示

ビューアの周りを表示する地図

ウォークスルーの際に、ビューアの周りだけを拡大した地図を表示してみましょう。

map scope
VRML - ソース / X3D - ソース
画面右上の正方形内にビューアを中心に真上から見た付近の地図が表示されます。  ビューアが仮想空間内を移動すると、それに合わせて地図の表示部分も移動します。  地図と地面のテクスチャーは同一の画像ファイルを使用しています。
( バージョン 3.1 以下の Cortona VRML Clientならば、右上の地図テクスチャーは上下左右に反復されて貼られます。)
DEF Sc Script {
eventIn SFVec3f set_position

field SFNode MapTT USE Map-TT

field SFFloat groundSize 100 # 地面の1辺の長さ
field SFFloat mapSize 1 # 地図の1辺の長さ

field SFFloat rate 0.01
field SFVec2f offset -0.5 -0.5

directOutput TRUE
url "javascript:

function initialize () {

rate = mapSize / groundSize;

}

function set_position (vec) {

var c = new SFVec2f ( -vec.x, vec.z );
c = c.multiply( rate ).add( offset );
MapTT.center = c;

MapTT.translation[0] = -0.5 - c.x;
MapTT.translation[1] = -0.5 - c.y;

}

"
}
ProximitySensor ノードの position_changed フィールドから出力されるビューアの現在位置を元に、 スクリプトの set_position 関数で地図テクスチャーの拡大の中心を求めています。  地面の中央の座標が ( 0.0, 0.0, 0.0 ) であるのに対し、地図テクスチャーの中央の座標が ( 0.5, 0.5 ) であることと、地面と地図の1辺の長さが異なることに注意してテクスチャー拡大の中心を求めています。

また、地図表示の中央がビューア位置を示しますが、「テクスチャー拡大の中心」は「表示の中央」とは異なるので表示位置を補正移動しています。  例えばビューアが地図全体でいう左下 ( 0.0, 0.0 ) にいる場合、MapTT.center は 0.0 0.0 となりますが、これはあくまで左下を中心にテクスチャーを拡大することを意味します。  拡大の中心が表示の中央と同じになるのは center -0.5 -0.5 の場合のみです。

地図の拡大率は TextureTransform ノードの scale フィールドで指定していますが、 この値を変えてもスクリプトに変更を加える必要はありません。

ビューアの向きに従って地図を回す

前の作例ではビューアの向きに関わらず地図は傾きませんでした。  次はビューアの向きが地図表示の真上になるように地図を傾けてみましょう。

map scope
VRML - ソース / X3D - ソース
画面右上の正方形内にビューアを中心に真上から見た付近の地図が表示されます。  ビューアが仮想空間内を移動すると、それに合わせて地図の表示部分も移動します。  さらにビューアの向きが変わると、それに応じてビューアの目線の先が真上になるように地図が回転します。
( バージョン 3.1 以下の Cortona VRML Clientならば、右上の地図テクスチャーは上下左右に反復されて貼られます。)
DEF Sc Script {
eventIn SFVec3f set_position
eventIn SFRotation set_rotation

field SFNode MapTT USE Map-TT

field SFFloat groundSize 100 # 地面の1辺の長さ
field SFFloat mapSize 1 # 地図の1辺の長さ

field SFFloat rate 0.01
field SFVec2f offset -0.5 -0.5

directOutput TRUE
url "javascript:

function initialize () {

rate = mapSize / groundSize;

}

function set_position (vec) {

var c = new SFVec2f ( -vec.x, vec.z );
c = c.multiply( rate ).add( offset );
MapTT.center = c;

MapTT.translation[0] = -0.5 - c.x;
MapTT.translation[1] = -0.5 - c.y;

}

function set_rotation (rot) {

var r = rot.angle;
if ( rot.y < 0 ) r = 2 * Math.PI - r;

MapTT.rotation = r;

}

"
}
このスクリプトは先の作例に set_rotation 関数を加えただけです。  これは ProximitySensor ノードの orientation_changed フィールドから出力されるビューアの向きが変化するごとに実行されます。  この関数の引数 rot はビューアの向きを示す SFRotation オブジェクトです。  この作例の地面は全て水平であるため、このオブジェクトの回転軸は殆どの場合において ( 0, 1, 0 ) もしくは ( 0, -1, 0 ) で表される y 軸を中心とした回転です。  本来ならば rot から y 軸を中心とした回転を抽出する処理が必要ですが、この関数ではそれを省いています。  この為、この作例は視線を水平から上下に傾けると地図の傾きが変化してしまう不具合が残っています。

map scope
VRML - ソース / X3D - ソース
先の例から地図表示を丸く変えてみました。 地図のテクスチャーを Cylinder (円筒)ノードの上底面に貼っています。
また、set_rotation 関数に改良を加えて、視線の上下移動が地図表示に影響しないようにしています。
( バージョン 3.1 以下の Cortona VRML Clientならば、右上の地図テクスチャーは上下左右に反復されて貼られます。  GLView4.4 及び blaxxun Contact 5 の場合、ブラウザーの不具合により正しく地図のテクスチャーが貼られません。 BS Contact VRML 6 以上の場合は問題ありません。)

このページのトップ | 前へ テクスチャー | 次へ テクスチャーの生成