VRML with JavaScript Tutorial

戻る はじめに / ノードの生成

文字列からノード生成

VRML のコードが記述された文字列から新たなノードを生成してみましょう。  例えば生成されたノードを Group ノードや Transform ノードの children フィールドにイベント出力することにより、 それまで何も無かった空間に任意の形状を好きな場所に好きなだけ追加することができます。

形状の追加

cone children フィールドが空の Group ノードに、シェーディングが施されていない真っ白な円錐を追加します。
Browser オブジェクトの createVrmlFromString メソッドを使う方法と SFNode オブジェクトを新規生成する方法の2つがあります。 
VRML - ソース / X3D - ソース
これは Browser オブジェクトの createVrmlFromString メソッドを使った場合です。  このメソッドは MFNode オブジェクトを帰り値として生成します。
DEF Sc Script {
eventOut MFNode children
url "javascript:

function initialize() {

var coneStr = 'Shape { geometry Cone {} }';

children = Browser.createVrmlFromString ( coneStr );

}

"
}


VRML - ソース / X3D - ソース
これは SFNode オブジェクトを新規生成した場合です。  children フィールドなど MFNode 型変数への代入は、children[0] などの様に要素番号を指定して代入するようにしてください。
DEF Sc Script {
eventOut MFNode children
url "javascript:

function initialize() {

var coneStr = 'Shape { geometry Cone {} }';

children[0] = new SFNode ( coneStr );

}

"
}

フィールドへのアクセス

redcone 今度は円錐を赤く塗ってみましょう。
VRML - ソース / X3D - ソース

DEF Sc Script {
eventOut MFNode children
field SFColor red 1 0 0
url "javascript:

function initialize() {

var coneStr = 'Shape { geometry Cone {} }';
var apprStr = 'Appearance { material Material {} }';

var cone = new SFNode ( coneStr );
var appr = new SFNode ( apprStr );

appr.material.diffuseColor = red;
cone.appearance = appr;

children[0] = cone;

}

"
}
最後の children[0] には以下の内容が代入されます。
Shape {
appearance Appearance {
material Material {
diffuseColor 1 0 0
}
}
geometry Cone {}
}
例えば変数 nSFNode オブジェクトが入っている場合、n.fieldName で、そのノードのフィールドにアクセスできます。
参照:SFNode オブジェクト

ノードを生成するための文字列にフィールドも記述すると、生成される際にそのフィールド値が適応されます。 (記載されていないフィールドは初期値が適応されます。) 

a = new SFNode ( 'Appearance { material Material {} }' );
b = new SFNode ( 'Appearance {}' );


この場合、変数 a には子ノードに Material ノードを含めた Appearance ノードが代入されます。  a.material.diffuseColor など、Material ノードのフィールドの読み書きが可能です。  変数 b には Appearance ノードしか代入されない為、 子ノードのフィールドの読み書きを行うことはできません。

b.material = new SFNode ( 'Material {}' );

と、後から子ノードを追加すれば、変数 b は変数 a と同様に Material ノードのフィールドの読み書きが可能になります。


twocone 次は高さの異なる2つの円錐を左右に並べてみました。
VRML - ソース / X3D - ソース

DEF Sc Script {
eventOut MFNode children
field SFColor red 1 0 0
field SFVec3f left -2 0 0
field SFVec3f right 2 0 0
url "javascript:

function initialize() {

var coneStr = 'Shape { geometry Cone { ';
var apprStr = 'Appearance { material Material {} }';
var trnsStr = 'Transform {}';

var coneL = new SFNode ( coneStr + 'height 3 }}' );
var coneR = new SFNode ( coneStr + '}}' );
var appr = new SFNode ( apprStr );

appr.material.diffuseColor = red;
coneL.appearance = appr;
coneR.appearance = appr;

var trnsLt = new SFNode ( trnsStr );
var trnsRt = new SFNode ( trnsStr );
trnsLt.translation = left;
trnsRt.translation = right;
trnsLt.children[0] = coneL;
trnsRt.children[0] = coneR;

children[0] = trnsLt;
children[1] = trnsRt;

}

"
}
右の円錐は前の作例と同じ高さですが、左の円錐は右と比べて高くなっています。

円錐の高さを Cone ノードの height フィールドで指定しますが、 このフィールドは exposedField ではない普通の field であり、VRML2.0 の仕様上では読み書きはできません。  その為、ノード生成前の文字列でフィールド値を指定しています。

それでは Cone ノードを生成した後に height フィールドを書き換えたらどうなるのか試してみました。
VRML - ソース / X3D - ソース
var coneStr = 'Shape { geometry Cone {} }';
var coneL = new SFNode ( coneStr );
coneL.geometry.height = 3;


Cosmo の場合、エラーが発生し実行されません。
Cortona の場合、エラーは出ませんが、左右の円錐は同じ高さで表示されます。
Contact の場合、エラー無く前の例と同じ様に左の円錐が右よりも高く表示されます。

この様にVRMLブラウザーにより異なる結果となるので注意してください。



このページのトップ | 前へ ノードの生成 | 次へ ノードのコピー