/* 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();
}
}
}