形状へのテクスチャーの貼り方を指定できる
TextureTransform ノードについて。
テクスチャーの座標は左下が原点 ( 0.0, 0.0 )、右上が ( 1.0, 1.0 ) の2次元ベクトルで表されます。
テクスチャー画像 map.gif
( 0.0, 1.0 ) |
|
( 1.0, 1.0 ) |
|
 |
|
( 0.0, 0.0 ) |
|
( 1.0, 0.0 ) |
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
}
Box ノードに貼られたテクスチャー対して
TextureTransform ノードで
translation 0.25 0.25 を指定してみました。
本来の貼られ方と比べて、左下に( 0.25, 0.25 ) の分だけ移動して貼られています。
Transform ノードで
translation 0.25 0.25 0 を指定すると、右上に形状が移動するのですが、それとは逆方向であることに注意してください。
テクスチャーの中央を中心に45度 ( 0.7854 ) 傾けて貼ってみました。
テクスチャーの中央 ( 0.5, 0.5 ) を指定するには、
TextureTransform ノードで
center -0.5 -0.5 を指定しなくてはいけません。
本来の座標から符号が反転します。
( バージョン 3.1 以下の Cortona VRML Clientならば左のイメージとは異なり、テクスチャーは上下左右に反復されて貼られます。)
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 を組んでみました。
このファイルはプロトタイプの定義だけなので、実行しても何も表示されません。
このプロトタイプは
SFVec3f の補完ノードである
PositionInterpolator の x,y だけを利用しています。
VRML2.0 の仕様により
Script ノードで
exposedField を定義出来ない為に、
TextureCoordinate ノードを仮の
MFVec2f keyValue の置き場として使っています。
スクリプトは
MFVec2f から
MFVec3f へと
SFVec3f から
SFVec2f への型変換に使われています。
ちなみに
Cortona は
Position2Interpolator ノードが、
Cortona VRML Client 5.0 以上と blaxxun Contact 5.0 以上 は
PositionInterpolator2D ノードが独自に機能追加されているため、これらを利用すればこのプロトタイプは必要ありません。
X3D においては
PositionInterpolator2D ノードは標準の
仕様として備わっています。
translation (貼付位置)のアニメーションです。
rotation (貼付回転角度)のアニメーションです。
このフィールドは
SFFloat 型のため、
ScalarInterpolator ノードを使っています。
( バージョン 3.1 以下の Cortona VRML Clientならば左のイメージとは異なり、テクスチャーは上下左右に反復されて貼られます。)
scale (貼付拡大縮小率)のアニメーションです。
rotation (貼付回転角度)のアニメーションと共に、
center (中心位置)の移動アニメーションも行っています。
( バージョン 3.1 以下の Cortona VRML Clientならば左のイメージとは異なり、テクスチャーは上下左右に反復されて貼られます。)
ビューアの周りを表示する地図
ウォークスルーの際に、ビューアの周りだけを拡大した地図を表示してみましょう。
画面右上の正方形内にビューアを中心に真上から見た付近の地図が表示されます。
ビューアが仮想空間内を移動すると、それに合わせて地図の表示部分も移動します。
地図と地面のテクスチャーは同一の画像ファイルを使用しています。
( バージョン 3.1 以下の Cortona VRML Clientならば、右上の地図テクスチャーは上下左右に反復されて貼られます。)
DEF Sc Script {
eventIn SFVec3f set_position
field SFNode MapTT USE Map-TT
field SFFloat groundSize 100
field SFFloat mapSize 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 フィールドで指定していますが、
この値を変えてもスクリプトに変更を加える必要はありません。
ビューアの向きに従って地図を回す
前の作例ではビューアの向きに関わらず地図は傾きませんでした。
次はビューアの向きが地図表示の真上になるように地図を傾けてみましょう。
画面右上の正方形内にビューアを中心に真上から見た付近の地図が表示されます。
ビューアが仮想空間内を移動すると、それに合わせて地図の表示部分も移動します。
さらにビューアの向きが変わると、それに応じてビューアの目線の先が真上になるように地図が回転します。
( バージョン 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
field SFFloat mapSize 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 軸を中心とした回転を抽出する処理が必要ですが、この関数ではそれを省いています。
この為、この作例は視線を水平から上下に傾けると地図の傾きが変化してしまう不具合が残っています。
先の例から地図表示を丸く変えてみました。 地図のテクスチャーを
Cylinder (円筒)ノードの上底面に貼っています。
また、
set_rotation 関数に改良を加えて、視線の上下移動が地図表示に影響しないようにしています。
( バージョン 3.1 以下の Cortona VRML Clientならば、右上の地図テクスチャーは上下左右に反復されて貼られます。
GLView4.4 及び blaxxun Contact 5 の場合、ブラウザーの不具合により正しく地図のテクスチャーが貼られません。 BS Contact VRML 6 以上の場合は問題ありません。)
このページのトップ |
前へ
テクスチャー |
次へ
テクスチャーの生成