VRML with JavaScript Tutorial

戻る はじめに

サンプル集

形状の切り替えと選択

VRML - ソース / X3D - ソース
クリックするごとに3種類の形状が切り替わります。
changeShape 関数の2行目にある Sw.choice.lengthSwitch ノードの choice フィールドにある子ノードの数(このサンプルの場合 3 )です。  この関数が実行される度に Sw.whichChoice は 1 づつ加算されますが、子ノード数との剰余が代入されます。  よって、Sw.whichChoice が子ノード数と同じになると 0 になります。
VRML - ソース / X3D - ソース
下に並んだ形状をクリックすると、その形状が大きく表示されます。
下に並んだ形状の一つ一つに TouchSensor ノードが仕掛けられていますが、共通の関数で処理しています。  まず、初期化時にこれらのセンサーからスクリプトへの ROUTE を設置し、どの形状がクリックされても choiceSp 関数を実行するように仕掛けます。  choiceSp 関数では各 TouchSensor ノードの isOver フィールドを調べてどの形状がクリックされたかを判断しています。

参考:Browser オブジェクト

ドラッグセンサーのリセット

VRML - ソース / X3D - ソース
画面中央の猫の正方形パネルをドラッグすると、上下左右に移動できます。  画面下の赤い球をクリックするとパネルが中央に戻ります。
しかし、さらにドラッグしようとすると、パネルは中央に戻る前の位置に戻ってしまいます。  これはパネルそのものの位置を中央に戻しただけで、PlaneSensor ノードは以前の状態を維持したままだからです。


以下の ROUTE を最後に1行追加してみました。
ROUTE Sc.resetPosition TO Cat-PlS.offset
VRML - ソース / X3D - ソース
赤い球をクリックした際にパネルを中央に戻しただけでなく、PlaneSensor ノードの offset フィールドもパネルと同じ位置にセットしています。  これで赤い球をクリックした後も正常にパネルをドラッグできます。

SphereSensorCylinderSensor といった PlaneSensor 以外のドラッグセンサーも同じ要領でセット・リセットできます。  これは SphereSensor ノードを使った場合です。
VRML - ソース / X3D - ソース
猫の写真が貼られた円柱を上下左右にドラッグすると、それを傾けることができます。  下の赤い球をクリックすると元の角度に戻り、青い球をクリックすると、斜め上からみた角度になります。

クリックで開閉するドア

VRML - ソース / X3D - ソース
木の家のドアをクリックすると、その度に開閉します。

ブラウザー情報

VRML - ソース / X3D - ソース
Browser オブジェクトから得られる各種情報をテキスト表示します。
cortona は大量のテキストの書き換えが苦手なため、Cosmo Contact と比べて動作が重くなります。

ステータスバーへのメッセージ表示

VRML - ソース
表示されている English もしくは Japanese にカーソルを乗せると、Webブラウザーのステータスバーに英語もしくは日本語のメッセージが表示されます。  Webブラウザーのステータスバーを表示する設定でお試しください。

このソースのコードは Shift-JIS で記述されています。  Text ノードで VRML 画面内に日本語を表示させるには UTF-8 コードでソースを記述する必要がありますが、 ステータスバーに日本語を表示できなくなるので注意してください。

以下は Windows 98 SE でのステータスバー表示の結果です。
Internet Explorer 5.01 / 6.0 SP1 / Netscape 4.6 / 4.78 では英語、日本語ともに表示します。
Netscape 7.1 など Mozilla 系では英語は正しく表示されますが、日本語は表示されません。
Opera 7.23 では英語は正しく表示されますが、日本語は全て文字化して表示されます。

X3D - ソース
X3Dの場合、Windows 98 SE + Internet Explorer 6.0 SP1 + BS Contact VRML/X3D 6.2 では英語は正しく表示されますが、日本語は文字化けします。  これはソースを UTF-8 で記述した場合も同じ結果になります。

参考:Browser オブジェクト

任意のフレームへのVRML表示

VRML / X3D
表示されている形状をクリックすると、左右対称位置にあるフレームに新たなVRMLをロードします。
フレームが以下のように定義されている場合、Browser.loadURL( filename, 'target=vrml0' ); ならば左側、'target=vrml1' ならば右側にロードします。

<frameset rows="30%,*">
	<frame src="doc.htm" name="document">
	<frameset cols="50%,*">
		<frame src="frame_0.wrl" name="vrml0">
		<frame src="frame_1.wrl" name="vrml1">
	</frameset>
</frameset>
参考:Browser オブジェクト

磁石のように動く円柱

VRML - ソース / X3D - ソース
3色の円柱が表示されますが、このうち青色の円柱だけをドラッグして動かすことができます。  緑色の円柱は青色に付いてまわりますが、赤色の円柱は他の2色の円柱が近づくと避けるように動きます。

点A と点B がベクトルで表される場合、点A から点B へ向かう向かうベクトル V は、B から A の引き算で表されます。
V = B.subtract(A);

点A と点B との距離は V.length() で求めることができます。
V の長さを任意の長さ n にする場合は、V を正規化して n 倍します。
V1 = V.normalize().multiply(n);

点Aから点Bへの延長線上にあり、点Aから n だけ離れた点B1 は、点A に V1 を足して求めます。
B1 = V1.add(A);
参考:SFVec3f オブジェクト

触れた場所の法線ベクトルを示す

VRML - ソース / X3D - ソース
表示された壺の表面をマウスカーソルでなぞると、カーソルの場所の法線ベクトルを示すように矢印が表示されます。

TouchSensorhitPoint_changed フィールドの値に従って、カーソル位置に矢印を動かしています。  矢印を法線と同じ方向に回転させるのは、hitNormal_changed フィールドの値を使っています。  hitNormal_changed は法線ベクトル ( SFVec3f ) であり、回転値 ( SFRotation )ではありません。  矢印は初期状態では真上 ( 0, 1, 0 ) を向いています。  この初期方向 ( initDirection ) から法線ベクトル ( normal ) への回転を表す値を得るために、スクリプトを使っています。
rotation = new SFRotation ( initDirection, normal );
参考:SFRotation オブジェクト

方角を示すコンパス

VRML - ソース / X3D - ソース
ビューアが向きを変えても一定の方角を示すコンパスです。

このスクリプトはビューアの向きを逆回転させているだけです。  ビューアが右に90度向けば、針は左に90度回転します。
compassRotation = viewerOrientation.inverse();
ビューアの位置と向きに関わらずコンパスは目の前に固定表示しています。  ちなみに、もしこのスクリプトが機能していないならば、針は動かず常にビューアの進行方向を向いています。

参考:SFRotation オブジェクト

表情が変わり、首を振る雪だるま

VRML - ソース / X3D - ソース
雪だるまの首にカーソルを乗せると驚いた表情に変わり、その首をドラッグすると首の向きが変わります。
# スクリプト
DEF Sc Script {
eventIn SFBool change_Face
eventOut SFInt32 whichChoice
eventIn SFVec3f translation_Head
eventOut SFRotation rotation_Head
field SFBool isCortona FALSE
url "javascript:
function initialize () {
isCortona = (Browser.getName() == 'Cortona VRML Client');
}
function change_Face (val) {
whichChoice = val;
}
function translation_Head (val) {
var ry = new SFRotation (0, 1, 0, val.x);
var rx = new SFRotation (1, 0, 0, -val.y);
rotation_Head = isCortona ? ry.multiply(rx) : rx.multiply(ry);
}
"
}
表情変化
首に仕掛けた TouchSensor ノードの isOver の値をスクリプトの change_Face にイベントしています。  isOverSFBool であり、whichChoiceSFInt32 ですが、 SFInt32 型で定義された変数に bool値を代入すると自動的に整数への型変換が行われます。  change_Face 関数は、首にカーソルを乗せる ( isOver = TRUE ) と whichChoice に 1 が、 首からカーソルが離れる ( isOver = FALSE ) と whichChoice に 0 が代入されます。
首振り
VRML には上下左右の平面ドラッグ操作を回転値( SFRotation ) に変換する SphereSensor ノードがあります。  しかしこのノードはドラッグ範囲を限定できない為、このノードを首振り動作に使用すると首は際限なく回ってしまいます。
そこで、ドラッグ範囲を限定できる PlaneSensor ノードの値をスクリプトで回転値に変換しています。  PlaneSensor ノードの translation_changedSFVec3f であり、ドラッグによる上下左右の移動量です。  translation_Head 関数は、この移動量の x 成分を y 軸を中心とした回転値、y 成分を x 軸を中心とした回転値に変換し、その両者を multiply メソッドで掛け合わせています。

SFRotation オブジェクトの multiply メソッド ( 回転値と回転値の掛け算 ) は「掛ける側」と「掛けられる側」が入れ替わると異なる結果が導かれます。  そして、このメソッドはVRMLブラウザーにより「掛ける側」と「掛けられる側」の関係が入れ替わっています。
まず、initialize 関数で実行しているVRMLブラウザーが Cortona であるかどうかを調べて、 translation_Head 関数の最後で Cortona の場合とそれ以外のブラウザーの場合とで異なる計算をしています。

このページのトップ | 前へ コンソールへの出力 | 次へ アニメーション