#VRML V2.0 utf8
Viewpoint {}
NavigationInfo {
type "EXAMINE"
}
# 箱
Group {
children [
Shape {
appearance Appearance {
texture DEF PT PixelTexture {}
material Material {
diffuseColor 1 1 1
}
}
geometry Box {
size 5 5 5
}
}
DEF ThS TouchSensor {}
]
}
# 線描画スクリプト
DEF Sc Script {
eventIn SFVec2f set_hitTexCoord
eventIn SFBool penUpDowned
eventOut SFImage image
field SFInt32 dt 128 # テクスチャの1辺のピクセル数
field MFInt32 ary [] # テクスチャーの色情報が納められている配列
field SFVec2f hitPoint 0 0 # ポインタが触れているテクスチャー座標
field SFVec2f penDownPoint 0 0 # ドラッグ開始位置を示すテクスチャー座標
field SFInt32 penColor 0xFFFF00 # 線の色
field SFInt32 bgColor 0x0000FF # 背景の色
url "javascript:
// SFVec2fオブジェクトで示されたテクスチャー座標に penColor を適応させる関数。
function pset(v) {
var tv = v.multiply ( dt );
var s = Math.floor( tv.x );
var t = Math.floor( tv.y );
s = Math.max ( 0, Math.min( dt - 1, s ));
t = Math.max ( 0, Math.min( dt - 1, t ));
ary[ s + t * dt ] = penColor;
}
// SFVec2fオブジェクトで示された2点 v0 と v1 との間に線を描くための関数。
// テクスチャーの縦横のピクセル数は同じである必要がある。
function lineset(v0,v1) {
// v0 から v1 へのベクトルを v01 とする。
var v01 = v1.subtract( v0 );
// v0 と v1 との距離を v01len とする。
var v01len = v01.length();
if ( v01len == 0 ) {
// v0 と v1 との距離が 0 なら、v0 の位置に点を描く。
pset( v0 );
}
else {
// v0 と v1 との距離が 0 ではないなら、v0 から v1 まで1ピクセル間隔で点を描く。
// v01 と同じ向きで、長さが1ピクセル分のベクトルを dv とする。
var dv = v01.normalize().divide( dt );
// v0 のコピーである v2 を新規生成する。
var v2 = new SFVec2f ( v0.x, v0.y );
// v0 と v1 との距離をdvの長さで割ることにより、描く点の個数 n を求める。
var n = v01len / dv.length();
// v2 の場所に点を描き、v2 をdv(1ピクセルの距離)だけ移動させる。
// それを n 回繰り返すことにより、v0 と v1 とを繋ぐ線を描く。
for ( var i = 0; i <= n; i++ ) {
pset ( v2 );
v2 = v2.add ( dv );
}
}
}
function initialize () {
var px = dt * dt;
// テクスチャー全体を bgColor で塗りつぶして、ary を初期化する。
for ( var i = 0; i < px; i++ ) ary[i] = bgColor;
image = new SFImage ( dt, dt, 3, ary );
}
function set_hitTexCoord (v) {
// キャンバス上のポインタが触れている座標を hitPoint にセットする。
hitPoint = v;
}
function penUpDowned (active) {
if (active) {
// キャンバス上でポインタのボタンが押されたら、ポインタの座標を線分の始点とする。
penDownPoint = hitPoint;
}
else {
// キャンバス上でポインタのボタンが離されたら、始点からポインタの座標までの線分を描く。
lineset( penDownPoint, hitPoint );
image = new SFImage ( dt, dt, 3, ary );
}
}
"
}
ROUTE Sc.image TO PT.image
ROUTE ThS.hitTexCoord_changed TO Sc.set_hitTexCoord
ROUTE ThS.isActive TO Sc.penUpDowned