VRML のコードが記述された文字列から新たなノードを生成してみましょう。
例えば生成されたノードを
Group ノードや
Transform ノードの
children フィールドにイベント出力することにより、
それまで何も無かった空間に任意の形状を好きな場所に好きなだけ追加することができます。
children フィールドが空の
Group ノードに、シェーディングが施されていない真っ白な円錐を追加します。
Browser オブジェクトの createVrmlFromString メソッドを使う方法と
SFNode オブジェクトを新規生成する方法の2つがあります。
これは
Browser オブジェクトの createVrmlFromString メソッドを使った場合です。
このメソッドは
MFNode オブジェクトを帰り値として生成します。
DEF Sc Script {
eventOut MFNode children
url "javascript:
function initialize() {
var coneStr = 'Shape { geometry Cone {} }';
children = Browser.createVrmlFromString ( coneStr );
}
"
}
これは
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 );
}
"
}

今度は円錐を赤く塗ってみましょう。
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 {}
}
例えば変数
n
に
SFNode オブジェクトが入っている場合、
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 ノードのフィールドの読み書きが可能になります。

次は高さの異なる2つの円錐を左右に並べてみました。
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 フィールドを書き換えたらどうなるのか試してみました。
var coneStr = 'Shape { geometry Cone {} }';
var coneL = new SFNode ( coneStr );
coneL.geometry.height = 3;
Cosmo の場合、エラーが発生し実行されません。
Cortona の場合、エラーは出ませんが、左右の円錐は同じ高さで表示されます。
Contact の場合、エラー無く前の例と同じ様に左の円錐が右よりも高く表示されます。
この様にVRMLブラウザーにより異なる結果となるので注意してください。