I dont know how many of you have come across this technique before. I
remember finding an OpenGL demo that did this kind of NPR (NonPhotorealistic
Rendering) outlines.
The concept is rather simple, create clones of objects, turn that clones into
a wire frame setting the color and the line widths and switch their culling
so that they are drawn backface.
but any way, look at the attached pictures, the code for doing this is like
this...
public void outline(float width, Node node){
if(node instanceof Shape3D){
Shape3D shape = (Shape3D)node;
Appearance app = shape.getAppearance();
PolygonAttributes polyAtt = new
PolygonAttributes(PolygonAttributes.POLYGON_LINE,PolygonAttributes.CULL_FRONT,
0.0f);
app.setPolygonAttributes(polyAtt);
LineAttributes lineAtt = new
LineAttributes(width,LineAttributes.PATTERN_SOLID,false);
app.setLineAttributes(lineAtt);
app.setTexture(null);
app.setMaterial(null);
ColoringAttributes colorAtt = new
ColoringAttributes(0.0f,0.0f,0.0f,ColoringAttributes.FASTEST);
app.setColoringAttributes(colorAtt);
shape.setAppearance(app);
}else if(node instanceof Morph){
Morph shape = (Morph)node;
Appearance app = shape.getAppearance();
PolygonAttributes polyAtt = new
PolygonAttributes(PolygonAttributes.POLYGON_LINE,PolygonAttributes.CULL_FRONT,
0.0f);
app.setPolygonAttributes(polyAtt);
LineAttributes lineAtt = new
LineAttributes(width,LineAttributes.PATTERN_SOLID,false);
app.setLineAttributes(lineAtt);
app.setTexture(null);
app.setMaterial(null);
ColoringAttributes colorAtt = new
ColoringAttributes(0.0f,0.0f,0.0f,ColoringAttributes.FASTEST);
app.setColoringAttributes(colorAtt);
shape.setAppearance(app);
}else if(node instanceof Group){
Group group = (Group)node;
int numChildren = group.numChildren();
for(int i=0;i<numChildren;i++){
outline(width, group.getChild(i));
}
}
}
To use this function you would need to clone the geometry you wish to create
an outline for...
Node clone = bg.cloneTree(true);
outline(8.0f, clone);
bg.addChild(clone);
The "true" in "cloneTree" is critical because this will force it to duplicate
appearances, if you dont do this then the object will look like a wireframe
instead. The 8.0f is the line width for the outline, typically though you
would have to think of it in half, because half the line will be obscured by
the object.
There may be additional things that can be done to this, like instead of
cloning the entire scene, it would probably be better to clone only shape3ds
and morphs, and attach them to the parent branch groups. And maybe even
better instead of out right cloning shape3ds and morphs, to actual convert
their geometry over manually and leave out any texture data (save some
memory). I should also probably add color as another parameter to the
function because black may not be the only color.
Right now I have it running in my utility program I created a while back for
creating morphs to export as j3f files.
Maybe someone could officially slap it up on www.j3d.org, so it does not get
lost in this archive.
Have fun,
Leyland Needham
OUTLINE.ZIP