Paint Board using SFImage
From H3D.org
This example demonstrates the use of SFImage in ECMAScript SpiderMonkey implementation to implement a paintable board using the haptic device. Unlike other examples which use X3D, we use VRML (X3DV) in this example.
The example draws inspiration from the PaintableTexture example.
You can download the sourcecode of the example here
The example
The idea is simple. We hold an SFImage variable that contains the pixel texture of the board, and upon touching of the haptic device with the board, we catch the contact point, translate to board's position and change the color of the board through SFImage.
SFImage contains an array of the following: [<width> <height> <type> <pixel_array>..], by changing the individual of the MFInt32 pixel array, you can change the texture of the object. The length of the pixel_array is width*height. Essentially, the entire length of SFImage.array is 3+width*height
Function below describe how to initialize the variable:
function initialize() {
colors = new MFInt32();
width = 0.3; height = 0.2;
tex_width = 30; tex_height = 20;
G.size = SFVec2f(width, height);
for (i = 0; i < tex_width * tex_height; i++) {
colors[i] = 0xff0000;
}
sfimage = SFImage(tex_width, tex_height, 3, colors);
PT.set_image = sfimage;
}
The function below describes the process of catching the point and convert to board
function pointHit(val) {
point = val[0];
x = point.x; y = point.y;
// calculate the grid-position on the board
idw = parseInt(((x + width/2)/width) * tex_width);
idh = parseInt(((y + height/2)/height) * tex_height);
if (idw == tex_width) idw--;
if (idh == tex_height) idh--;
id = idh * tex_width + idw;
sfimage.array[3+id] = 0x00ff00;
PT.set_image = sfimage; // to reattach the SFImage object to the texture
}
Lastly, do a route from the contactPoint of geometry object to the function implemented:
ROUTE G.contactPoint TO JS.pointHit
Full sourcecode
# PaintBoard.x3dv
#X3D V3.0 utf8
PROFILE Immersive
Transform {
translation 0 0 0
rotation 1 0 0 0.5
children [
Shape {
appearance Appearance {
material DEF MAT Material {
diffuseColor 0 0 1
}
surface FrictionalSurface { }
texture DEF PT PixelTexture {
repeatS TRUE
repeatT TRUE
}
}
geometry DEF G Rectangle2D {
}
}
]
}
DEF JS Script {
field SFNode PT USE PT
field SFNode G USE G
inputOnly MFVec3f pointHit
url ["ecmascript:
function initialize() {
colors = new MFInt32();
width = 0.3; height = 0.2;
tex_width = 30; tex_height = 20;
G.size = SFVec2f(width, height);
for (i = 0; i < tex_width * tex_height; i++) {
colors[i] = 0xff0000;
}
sfimage = SFImage(tex_width, tex_height, 3, colors);
PT.set_image = sfimage;
}
function pointHit(val) {
point = val[0];
x = point.x; y = point.y;
idw = parseInt(((x + width/2)/width) * tex_width);
idh = parseInt(((y + height/2)/height) * tex_height);
if (idw == tex_width) idw--;
if (idh == tex_height) idh--;
id = idh * tex_width + idw;
sfimage.array[3+id] = 0x00ff00;
PT.set_image = sfimage;
}
"]
}
ROUTE G.contactPoint TO JS.pointHit

