/* * Copyright (c) 2006, John T. Reese Redistribution and use in source * and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of John T. Reese nor the names of his * contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY JOHN T. REESE AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JOHN T. * REESE AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ import jtr.*; import jtr.mesh.*; import vrml.*; import vrml.field.*; import vrml.node.*; /* * * to use from VRML: * * the VRML file should be of this form: * * # any applicable grouping node * Transform { * children [ * # Use a touch sensor to active the subdivision. * DEF SENSOR TouchSensor {} * Shape { * # Whatever you want it to look like: color and so * # forth. * appearance Appearance {...} * * # The mesh itself. Name (with DEF) for future * # reference in the Script node. * geometry DEF IFS IndexedFaceSet { * # point is a vector of vertices * coord Coordinate { point [...] } * # coordIndex represents the faces * coordIndex [...] * } * } * * # the Script node * DEF SC Script { * # important -- allows script to affect scene graph * directOutput TRUE * * # point to the compiled Java code * url "http://www.ugcs.caltech.edu/~jtr/tide/mesh-div.class" * * # used to link TouchSensor to script * eventIn SFBool isActive * * # points to mesh previously defined * field SFNode ifs USE IFS * * # because the VRML Java interface blows goats, you must * # duplicate all of the data from coordIndex, verbatim, * # here. There is no other way for the Script to * # acquire this information. * field MFInt32 coordIndex [...] * } * * # Connect touch sensor to script, allowing script to * # subdivide when mouse button is pressed over shape. * ROUTE SENSOR.isActive TO SC.isActive * ] * } * * There is some flexibility possible. mesh-div subdivides when the * isActive eventIn is triggered... any normal VRML method of * generating a VRML eventIn will work as well as the TouchSensor * method. The code could easily be tweaked to activate in another * way, but an SFBool eventIn seems natural. * * The duplication of the coordIndex annoys me, but is currently * unavoidable. Hopefully coordIndex will become an exposedField in * some future version of VRML. * * * */ public class MeshDiv extends Script { VRMLDivide v; Browser br; float[][] point; int[] coordIndex; public void initialize() { try { Node ifs= (Node) ((SFNode) getField("ifs")).getValue(); Node co= (Node) ((SFNode) ifs.getExposedField("coord")).getValue(); MFVec3f mv= (MFVec3f) co.getExposedField("point"); MFInt32 mi= (MFInt32) getField("coordIndex"); point= new float[mv.getSize()][3]; coordIndex= new int[mi.getSize()]; mv.getValue(point); mi.getValue(coordIndex); br= ifs.getBrowser(); v= new VRMLDivide(ifs, mi); } catch (Throwable e) { System.out.println("*** error during construction"); e.printStackTrace(System.out); System.out.println("*** thump"); } } public void processEvent(Event e) { try { if (e.getName().equals("isActive") && ((ConstSFBool) e.getValue()).getValue()) { String[] s= new String[4]; System.out.println("Preparing " + (s.length - 1) + " levels"); s[0]= v.Emit(coordIndex, point); s[1]= v.CatClark(1); s[2]= v.CatClark(2); s[3]= v.CatClark(3); //s[3]= v.CatClark(4); System.out.println("Done."); BaseNode[] bn= br.createVrmlFromString(MakeNewWorld(s)); br.replaceWorld(bn); } } catch (Throwable ex) { System.out.println("*** yawn"); ex.printStackTrace(System.out); System.out.println("*** thump"); } } private String MakeNewWorld(String[] meshes) { String s; s= "Transform {\n" + "children [\n" + //"DEF RED Appearance {\n" + //"material Material { diffuseColor 1 0 0 }\n" + //"}\n" + "DEF TS TouchSensor {}\n" + "DirectionalLight {\n" + " color 0.05 0.05 0.6\n" + " direction 0.1 0.1 0.0\n" + "}\n" + "DirectionalLight {\n" + " color 0.6 0.05 0.05\n" + " direction 0.1 -0.1 0.0\n" + "}\n" + "DEF SW Switch {\n" + "choice [\n"; for (int i= 0; i < meshes.length; i++) s += "Shape { appearance Appearance {\n" + "material Material {diffuseColor .4 .4 .4 \n" + "specularColor 1 1 1\n" + "shininess 1.0\n" + "}\n" + "}\n" + "geometry " + meshes[i] + "}\n"; s += "]\n" + "whichChoice 0\n" + "}\n" + "DEF BUTTSWITCH Script {\n" + "directOutput TRUE\n" + "field SFNode swit USE SW\n" + "eventIn SFBool butt1\n" + "url \"javascript:\n" + "function butt1(value,timestamp) {\n" + "if (value) {\n" + "swit.set_whichChoice= " + "(swit.whichChoice + 1) %" + meshes.length + ";\n" + "}\n" + "}\"\n" + "}\n" + "]\n" + "ROUTE TS.isActive TO BUTTSWITCH.butt1\n" + "}\n"; return s; } }