/* PlanJ.java 0.0 10/13/01 * This is a program that will be used to illustrate opportunities and * problems doing physics with the Java 3D API. * * It is built using Sun Microsystem's tutorial example * HelloJava3Dc.java, the Copyright notice of which is * reproduced below. * * modifications Copyright Fred Klingener 2001 * may be reproduced, modified, or used for any non-commercial purpose * * Same as PlanAClock except * 10-13-2001 wakeupOnElapsedFrames(0) * Thread.sleep(dt) in processStimulus() of SimClock inner class * */ /* * @(#)HelloJava3Dc.java 1.1 00/09/22 13:55 * * Copyright (c) 1996-2000 Sun Microsystems, Inc. All Rights Reserved. * * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use, * modify and redistribute this software in source and binary code form, * provided that i) this copyright notice and license appear on all copies of * the software; and ii) Licensee does not utilize the software in a manner * which is disparaging to Sun. * * 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. SUN AND ITS LICENSORS 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. */ import java.applet.Applet; import java.awt.BorderLayout; import java.awt.Frame; import java.awt.event.*; import java.awt.GraphicsConfiguration; import java.util.Enumeration; // 09-17-01 import com.sun.j3d.utils.applet.MainFrame; import com.sun.j3d.utils.geometry.ColorCube; import com.sun.j3d.utils.universe.*; import javax.media.j3d.*; import javax.vecmath.*; // PlanJ renders a single, rotating cube. public class PlanJ extends Applet { String ProgramName = "PlanJ.java 10-15-2001"; /* SimpleU * | * objRoot (BG) * | * SimClock (RotationInterpolator with clock that advances only * | when renderer is running) * objSpin (TG) * | * ColorCube (Shape) */ public BranchGroup createSceneGraph() {// Create the root of the branch graph BranchGroup objRoot = new BranchGroup(); // Create the transform group node and initialize it to the // identity. Add it to the root of the subgraph. TransformGroup objSpin = new TransformGroup(); objSpin.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); objRoot.addChild(objSpin); // 09-17-01 add SimClock Behavior Alpha rotationAlpha = new Alpha(-1, 4000); BSFClock SimClock = new BSFClock(10, 200, objSpin, rotationAlpha); BoundingSphere ClockBounds = new BoundingSphere(); SimClock.setSchedulingBounds(ClockBounds); objRoot.addChild(SimClock); // Create a simple shape leaf node, add it to the scene graph. // ColorCube is a Convenience Utility class objSpin.addChild(new ColorCube(0.4)); return objRoot; } // Constructor public PlanJ() { setLayout(new BorderLayout()); GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration(); Canvas3D canvas3D = new Canvas3D(config); canvas3D.setSize(256, 256); add("Center", canvas3D); // SimpleUniverse is a Convenience Utility class SimpleUniverse simpleU = new SimpleUniverse(canvas3D); // This will move the ViewPlatform back a bit so the // objects in the scene can be viewed. simpleU.getViewingPlatform().setNominalViewingTransform(); BranchGroup scene = createSceneGraph(); simpleU.addBranchGraph(scene); } // The following allows this to be run as an application // as well as an applet public static void main(String[] args) { Frame frame = new MainFrame(new PlanJ(), 256, 256); } /* * Java classes for doing simulations of physical processes * on the Java3D scene graph. * * (C) 2000, 2001 Fred Klingener * klingener@BrockEng.com * www.VMech.com * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA, * or you may read or obtain a copy at http://www.gnu.org/copyleft/gpl.html */ /** Simulation clock for controlling physical process simulations on * the Java 3D scene graph. */ public class BSFClock extends Behavior implements Runnable {// 1. alarm WakeupCriterion yawn; // 2. clock long SimTime; // clock reading int dt; // time step // 3. set model Alpha SimAlpha; TransformGroup targetTG; private Transform3D t3d; // 4. maintain and report frame rate final static boolean debug = true; int FrameCount; int FrameBlock; long BlockStartTime; double AvgDelay; private java.text.NumberFormat Double1; // 5. set frame delay Thread OneShot; int joincounter; int timeshim = 0; /** Constructor */ public BSFClock(int ts, // time step int fb, // number of frames in averaging block TransformGroup tg, // target TG for the Interpolator Alpha ra) // roataion Alpha { dt = ts; FrameBlock = fb; targetTG = tg; SimAlpha = ra; t3d = new Transform3D(); /******* BSF *******************************/ yawn = new WakeupOnElapsedFrames(0); /**********************************************/ Double1 = java.text.NumberFormat.getInstance(); Double1.setMaximumFractionDigits(1); Double1.setMinimumFractionDigits(1); } /*******BSF ********************************/ /** run method * * */ public void run() { int s = dt - timeshim; try { Thread.sleep(s>0?s:0); } catch(InterruptedException e) {} } /**********************************************/ /** initialize */ public void initialize() {// 1. alarm wakeupOn(yawn); // 2. clock SimTime = 0; // 3. set model SimAlpha.setStartTime(0); targetTG.setTransform(t3d); // 4. maintain and report frame rate FrameCount = 0; joincounter = 0; BlockStartTime = System.currentTimeMillis(); if (debug) { java.text.DateFormat DayTime = java.text.DateFormat.getDateTimeInstance( java.text.DateFormat.SHORT, java.text.DateFormat.SHORT); System.out.println(""); System.out.println("Program: "+ProgramName); System.out.println("Run "+DayTime.format(new java.util.Date())); System.out.println("OS Arch.: "+System.getProperty("os.arch")); System.out.println("OS: "+System.getProperty("os.name")+ " Version: "+System.getProperty("os.version")); System.out.println("Averaging block = "+FrameBlock+" Frames"); System.out.println("timeshim = "+timeshim+" (ms)"); System.out.println("---------------------------------"); System.out.print("\tjoin()\tFrame\t\tLag\n"); System.out.print(" dt\tFrames\tDelay\tLag\tGraphic\n"); System.out.print("(ms)\t %\t(ms)\t %\t'*' = 1ms\n"); System.out.print("------\t------\t------\t------\t------\n"); } // 5. set frame delay // OneShot = new Thread(this); } /** processStimulus */ public void processStimulus(Enumeration e) {// 1. alarm wakeupOn(yawn); // 2. clock SimTime +=dt; // 3. set model t3d.rotY(Math.PI*2.0*SimAlpha.value(SimTime)); targetTG.setTransform(t3d); // 4. maintain and report frame rate if (++FrameCount >= FrameBlock) { long Now = System.currentTimeMillis(); long ET = Now - BlockStartTime; AvgDelay = (double)ET/(double)FrameBlock; BlockStartTime = Now; FrameCount = 0; if (debug) { System.out.print(+dt+"\t"+ 100.0f*(float)joincounter/(float)FrameBlock+ "\t"+Double1.format(AvgDelay)+"\t"+ Double1.format(100.0*(AvgDelay - dt)/(double)dt)+"\t"); String s = ""; for (int i=0; i<(int)AvgDelay-dt; i++) { s += "*"; } System.out.print(s+"\n"); dt += 1; joincounter = 0; } } // 5. then wait for OneShot to time out if (OneShot != null) { if (debug) { if (OneShot.isAlive()) joincounter++; } try { OneShot.join(); } catch(InterruptedException je) {} } // and then restart it OneShot = new Thread(this); OneShot.start(); } } }