/* * @(#)Deform.java 1.0 99/02/14 23:00:00 * * Copyright (c) 1999. All Rights Reserved. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. WE SHALL NOT BE * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * This software is not designed or intended for use in on-line control of * aircraft, air traffic, aircraft navigation or aircraft communications; or in * the design, construction, operation or maintenance of any nuclear * facility. Licensee represents and warrants that it will not use or * redistribute the Software for such purposes. * * @Author: Kovalan Muniandy */ import java.applet.Applet; import java.awt.*; import java.awt.event.*; import com.sun.j3d.utils.geometry.ColorCube; import com.sun.j3d.utils.applet.MainFrame; import com.sun.j3d.utils.universe.*; import com.sun.j3d.utils.behaviors.mouse.MouseRotate; import com.sun.j3d.utils.behaviors.mouse.MouseZoom; import com.sun.j3d.utils.behaviors.mouse.MouseTranslate; import com.sun.j3d.utils.geometry.GeometryInfo; import com.sun.j3d.utils.geometry.NormalGenerator; import com.sun.j3d.utils.geometry.Stripifier; import com.sun.j3d.utils.geometry.Triangulator; import javax.media.j3d.*; import javax.vecmath.*; import java.net.URL; import java.net.MalformedURLException; import java.io.*; import java.awt.image.BufferedImage; import com.sun.j3d.loaders.vrml97.VrmlLoader; import com.sun.j3d.loaders.vrml97.VrmlScene; import com.sun.j3d.utils.image.TextureLoader; import com.sun.image.codec.jpeg.*; import ncsa.j3d.ui.record.RecordableCanvas3D; import kovey.book99.util.J3dFinder; import kovey.book99.util.FFD; import kovey.book99.util.Tracer; public class Deform extends Applet implements ActionListener, Runnable { public static void main(String[] args) { new MainFrame(new Deform(), 512, 256); } String location; RecordableCanvas3D canvas; SimpleUniverse universe; TransformGroup vpTransGroup; VrmlLoader loader; View view; Panel panel; Label label; BranchGroup sceneRoot; TransformGroup examineGroup; BranchGroup sceneGroup; BoundingSphere sceneBounds; DirectionalLight headLight; AmbientLight ambLight; TextField textField; Cursor waitCursor; Cursor handCursor; VrmlScene scene = null; java.util.Vector shapes = new java.util.Vector(); Thread animator; Transform3D objectXf; FFD ffd = new FFD(); Shape3D bird; Point3d birdPts[]; GeometryArray birdGeom; Deform() { Point3d min = new Point3d( -0.522394, -0.748210, -0.423777 ); Point3d max = new Point3d( 0.928951, 0.748210, 0.928951 ); Point3d x0 = new Point3d( max.x, min.y, max.z ); Vector3d s = new Vector3d( -(max.x-min.x), 0, 0 ); Vector3d t = new Vector3d( 0, (max.y-min.y), 0 ); Vector3d u = new Vector3d( 0, 0, -(max.z-min.z) ); final int l=6, m=6, n=6; ffd.getLattice().set( x0, s, t, u, l, m, n ); setLayout(new BorderLayout()); canvas = new RecordableCanvas3D( null ); canvas.captureInPostRender( false ); canvas.setFilePrefix( "f" ); add( "Center", canvas ); waitCursor = new Cursor(Cursor.WAIT_CURSOR); handCursor = new Cursor(Cursor.HAND_CURSOR); universe = new SimpleUniverse(canvas); ViewingPlatform viewingPlatform = universe.getViewingPlatform(); vpTransGroup = viewingPlatform.getViewPlatformTransform(); Viewer viewer = universe.getViewer(); view = viewer.getView(); setupScene(); loadVRML( "./bird.wrl" ); getReady(); } public void actionPerformed(ActionEvent ae) { } class AnimatorFactory extends Behavior { Runnable parent; public AnimatorFactory( Runnable theParent ) { parent = theParent; } public void initialize() { wakeupOn( new WakeupOnElapsedFrames(0) ); } public void processStimulus( java.util.Enumeration criteria ) { if ( null == animator ) { // First scene is being shown. Get ready to animate. animator = new Thread( parent ); animator.start(); } } } void setupScene() { sceneRoot = new BranchGroup(); BoundingSphere backBounds = new BoundingSphere(new Point3d(), Double.MAX_VALUE); TextureLoader bgTexture = new TextureLoader("./castle.jpg", this); Background bg = new Background( bgTexture.getImage() ); bg.setApplicationBounds( backBounds ); sceneRoot.addChild( bg ); examineGroup = new TransformGroup(); examineGroup.setCapability(TransformGroup.ALLOW_CHILDREN_EXTEND); examineGroup.setCapability(TransformGroup.ALLOW_CHILDREN_READ); examineGroup.setCapability(TransformGroup.ALLOW_CHILDREN_WRITE); examineGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); examineGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); sceneRoot.addChild(examineGroup); BoundingSphere behaviorBounds = new BoundingSphere(new Point3d(), Double.MAX_VALUE); MouseRotate mr = new MouseRotate(); mr.setTransformGroup(examineGroup); mr.setSchedulingBounds(behaviorBounds); sceneRoot.addChild(mr); MouseTranslate mt = new MouseTranslate(); mt.setTransformGroup(examineGroup); mt.setSchedulingBounds(behaviorBounds); sceneRoot.addChild(mt); MouseZoom mz = new MouseZoom(); mz.setTransformGroup(examineGroup); mz.setSchedulingBounds(behaviorBounds); sceneRoot.addChild(mz); AnimatorFactory animationStarter = new AnimatorFactory( this ); animationStarter.setSchedulingBounds(behaviorBounds); sceneRoot.addChild( animationStarter ); BoundingSphere lightBounds = new BoundingSphere(new Point3d(), Double.MAX_VALUE); ambLight = new AmbientLight(true, new Color3f(1.0f, 1.0f, 1.0f)); ambLight.setInfluencingBounds(lightBounds); ambLight.setCapability(Light.ALLOW_STATE_WRITE); sceneRoot.addChild(ambLight); headLight = new DirectionalLight(); headLight.setCapability(Light.ALLOW_STATE_WRITE); headLight.setInfluencingBounds(lightBounds); sceneRoot.addChild(headLight); universe.addBranchGraph(sceneRoot); } void loadVRML(String location) { if ( null == loader ) loader = new VrmlLoader(); canvas.setCursor(waitCursor); if (sceneGroup != null) sceneGroup.detach(); try { URL loadUrl = new URL(location); try { // load the scene scene = (VrmlScene)loader.load( loadUrl ); } catch (Exception e) { System.out.println("Exception loading URL:" + e); } } catch (MalformedURLException badUrl) { // location may be a path name try { // load the scene scene = (VrmlScene)loader.load(location); } catch (Exception e) { System.out.println("Exception loading file from path:" + e); } } if (scene != null) { // get the scene group sceneGroup = scene.getSceneGroup(); sceneGroup.setCapability(BranchGroup.ALLOW_DETACH); sceneGroup.setCapability(BranchGroup.ALLOW_BOUNDS_READ); // Get the bird's geometry java.util.Vector shapes = new java.util.Vector(); J3dFinder.getShapes( sceneGroup, shapes ); bird = (Shape3D)shapes.get(0); bird.setCapability( Shape3D.ALLOW_GEOMETRY_READ ); Geometry tempGeom = bird.getGeometry(); if ( tempGeom instanceof GeometryArray ) { birdGeom = (GeometryArray)tempGeom; birdGeom.setCapability( GeometryArray.ALLOW_COORDINATE_READ ); birdGeom.setCapability( GeometryArray.ALLOW_COORDINATE_WRITE ); birdGeom.setCapability( GeometryArray.ALLOW_COUNT_READ ); birdPts = new Point3d[birdGeom.getVertexCount()]; for ( int j=0; j < birdPts.length; j++ ) birdPts[j] = new Point3d(); birdGeom.getCoordinates( 0, birdPts ); } else System.out.println( "Bird isn't contained in GeometryArray!" ); // add the scene group to the scene examineGroup.addChild(sceneGroup); // now that the scene group is "live" we can inquire the bounds sceneBounds = (BoundingSphere)sceneGroup.getBounds(); } canvas.setCursor(handCursor); } void getReady() { // view.setSceneAntialiasingEnable( true ); Transform3D xf = new Transform3D(); Transform3D eyeXf = new Transform3D(); view.setFrontClipDistance( view.getFrontClipDistance() - 0.095 ); // pull the eye back far enough to see the whole object Point3d center = new Point3d(); sceneBounds.getCenter(center); double radius = sceneBounds.getRadius(); Vector3d temp = new Vector3d(center); xf.set(temp); double eyeDist = 0.4*radius / Math.tan(view.getFieldOfView() / 2.0); // view.setBackClipDistance( eyeDist ); temp.x = 0.0; temp.y = 0.0; temp.z = eyeDist; eyeXf.set(temp); xf.mul(eyeXf); vpTransGroup.setTransform(xf); // set the view transform objectXf = new Transform3D(); objectXf.setIdentity(); Vector3d move = new Vector3d( -3.58, -0.5, -24.8 ); objectXf.set( move ); xf.rotX( (-65.0/180.0) * Math.PI ); objectXf.mul( xf ); xf.rotZ( (-45.0/180.0) * Math.PI ); objectXf.mul( xf ); examineGroup.setTransform( objectXf ); } public void run() { final int MAX_MOVE=60; final int INCREMENT=6; final int ARRAY_SIZE=MAX_MOVE/INCREMENT; Point3d up[][] = new Point3d[ARRAY_SIZE][]; Point3d down[][] = new Point3d[ARRAY_SIZE][]; // Flap the wings by pulling the grid points of the FFD. // Right wing: (2, 6, 0) +60z (up) +60y -60z (down) // Left wing: (2, 0, 0) +60z (up) -60y -60z (down) Point3d pt; System.out.print( "Deforming points for flip up" ); // Flip up int j=1; for ( int i=0; i < ARRAY_SIZE; i++ ) { System.out.print( "." ); pt = ffd.getLattice().getGridPt( 2, 6, 0 ); pt.z = j; ffd.getLattice().setGridPt( 2, 6, 0, pt ); pt = ffd.getLattice().getGridPt( 2, 0, 0 ); pt.z = j; ffd.getLattice().setGridPt( 2, 0, 0, pt ); up[i] = ffd.deform( birdPts ); j += INCREMENT; } System.out.print( "\nDeforming points for flip down" ); // Flip down j=1; for ( int i=0; i < ARRAY_SIZE; i++ ) { System.out.print( "." ); pt = ffd.getLattice().getGridPt( 2, 6, 0 ); pt.y = j; pt.z = -j; ffd.getLattice().setGridPt( 2, 6, 0, pt ); pt = ffd.getLattice().getGridPt( 2, 0, 0 ); pt.y = -j; pt.z = -j; ffd.getLattice().setGridPt( 2, 0, 0, pt ); down[i] = ffd.deform( birdPts ); j += INCREMENT; } System.out.println( "\nAnimating.... " ); // Animate Transform3D xf = new Transform3D(); Vector3d translate = new Vector3d( 0.0, 0.0, 0.0 ); canvas.startRecording(); while ( translate.z <= 25.5 ) { for ( int i=0; i < ARRAY_SIZE; i++ ) { birdGeom.setCoordinates( 0, up[i] ); moveBird( translate, xf ); canvas.rendezvous(); } for ( int i=(ARRAY_SIZE-1); i >= 0; i-- ) { birdGeom.setCoordinates( 0, up[i] ); moveBird( translate, xf ); canvas.rendezvous(); } birdGeom.setCoordinates( 0, birdPts ); for ( int i=0; i < ARRAY_SIZE; i++ ) { birdGeom.setCoordinates( 0, down[i] ); moveBird( translate, xf ); canvas.rendezvous(); } for ( int i=(ARRAY_SIZE-1); i >= 0; i-- ) { birdGeom.setCoordinates( 0, down[i] ); moveBird( translate, xf ); canvas.rendezvous(); } birdGeom.setCoordinates( 0, birdPts ); } } private void moveBird( Vector3d translate, Transform3D xf ) { translate.x += 0.02; translate.z += 0.1; xf.setIdentity(); xf.setTranslation( translate ); xf.mul( objectXf ); examineGroup.setTransform( xf ); } }