/* Mykeynavbeh.java * Originally based on code from BackgroundApp.java *   @(#)BackgroundApp.java 1.1 00/09/22 14:03 * * portions 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.awt.*;
import javax.media.j3d.*;import javax.vecmath.*;
import com.sun.j3d.utils.universe.SimpleUniverse;import com.sun.j3d.utils.universe.PlatformGeometry;import com.sun.j3d.utils.behaviors.keyboard.*;
import com.sun.j3d.loaders.Scene;
import java.awt.event.KeyListener;import java.awt.event.KeyEvent;
import javax.media.j3d.WakeupOnCollisionEntry;import javax.media.j3d.WakeupOnCollisionExit;
import java.util.*;
import com.sun.j3d.loaders.objectfile.ObjectFile;import java.io.*;
import java.awt.event.*;import com.sun.j3d.utils.geometry.*;
//import com.sun.j3d.utils.image.TextureLoader;
import javax.sound.sampled.DataLine;import javax.sound.sampled.AudioInputStream;import javax.sound.sampled.AudioSystem;import javax.sound.sampled.Clip;import javax.sound.sampled.LineUnavailableException;import javax.sound.sampled.UnsupportedAudioFileException;
import javax.sound.sampled.FloatControl;
import java.net.*;
public class Mykeynavbeh extends Frame implements KeyListener {
private SimpleUniverse universe = null; private Canvas3D canvas = null; private TransformGroup viewtrans = null; private TransformGroup viewtrans_2 = null;
private TransformGroup tg = null; private Transform3D t3d = null; private Transform3D t3dstep = new Transform3D();
private Matrix4d matrix = new Matrix4d();
private boolean firstTime = true;
private Switch selector = new Switch(Switch.CHILD_MASK); private BitSet flag_i = new BitSet(4);
private int count = 0;
private TransformGroup tg_ab = null; private Transform3D t3d_ab = null;
private BoundingSphere bounds;
private CollisionDetectorGroup cdGroup = null; private boolean inCollision = false; private int angle = 0;
private static final Point3d USERPOSN = new Point3d(-0.105, 2.4, 7.1);
private Clip clip = null;
public Mykeynavbeh() { setLayout(new BorderLayout()); GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration();
canvas = new Canvas3D(config); add("Center", canvas); universe = new SimpleUniverse(canvas);
canvas.addKeyListener(this);
BranchGroup scene = createSceneGraph(); universe.getViewingPlatform().setNominalViewingTransform();
universe.getViewer().getView().setBackClipDistance(100.0); universe.addBranchGraph(scene);
viewtrans_2 = universe.getViewingPlatform().getViewPlatformTransform();
Transform3D t3d_vt = new Transform3D(); viewtrans_2.getTransform(t3d_vt);
// args are: viewer posn, where looking, up direction t3d_vt.lookAt(USERPOSN, new Point3d(-0.1, 0, 0), new Vector3d(0, 1, 0)); t3d_vt.invert();
viewtrans_2.setTransform(t3d_vt); }
private BranchGroup createSceneGraph() { BranchGroup objRoot = new BranchGroup();
bounds = new BoundingSphere(new Point3d(), 10000.0);
viewtrans = universe.getViewingPlatform().getViewPlatformTransform();
KeyNavigatorBehavior keyNavBeh = new KeyNavigatorBehavior(viewtrans); keyNavBeh.setSchedulingBounds(bounds); PlatformGeometry platformGeom = new PlatformGeometry(); platformGeom.addChild(keyNavBeh); universe.getViewingPlatform().setPlatformGeometry(platformGeom);
Background background = new Background(); background.setColor(1.0f, 1.0f, 0.9f); background.setApplicationBounds(bounds); objRoot.addChild(background);
objRoot.addChild(createFerrisWheel()); objRoot.addChild(createArchitecturePack()); objRoot.addChild(createGround()); objRoot.addChild(createLeoAirBag());
return objRoot; }
private BranchGroup createLeoAirBag() {
BranchGroup objRoot = new BranchGroup(); TransformGroup tg = new TransformGroup(); Transform3D t3d = new Transform3D();
t3d.setTranslation(new Vector3d(-2.4, -2.46, -9.9)); t3d.setRotation(new AxisAngle4f(0.0f, 1.0f, 0.0f, -0.6f)); t3d.setScale(0.21); tg.setTransform(t3d);
tg.addChild(createLeo()); tg.addChild(createAirBag());
objRoot.addChild(tg); objRoot.addChild(createLight(-0.3f, 0.3f, 0.0f)); objRoot.addChild(createLight(0.3f, 0.2f, 0.0f)); objRoot.compile();
return objRoot;
}
private BranchGroup createFerrisWheel() {
BranchGroup objRoot = new BranchGroup(); TransformGroup tg = new TransformGroup(); Transform3D t3d = new Transform3D(); tg.setCollidable(false);
t3d.setTranslation(new Vector3d(-0.7, -4.2, -15.3)); t3d.setRotation(new AxisAngle4f(0.0f, 1.0f, 0.0f, -0.6f)); t3d.setScale(4.5); tg.setTransform(t3d);
TransformGroup tg_2 = new TransformGroup(); Transform3D t3d_2 = new Transform3D();
t3d_2.setTranslation(new Vector3d(0.0, 0.0, 0.0)); t3d_2.setScale(1.4); tg_2.setTransform(t3d_2);
TransformGroup tg_3 = new TransformGroup(); Transform3D t3d_3 = new Transform3D();
t3d_3.setTranslation(new Vector3d(-0.15, -1.05, 0.104)); t3d_3.setRotation(new AxisAngle4f(0.0f, 1.0f, 0.0f, -1.57f)); t3d_3.setScale(0.13); tg_3.setTransform(t3d_3);
tg.addChild(createWheel()); tg_2.addChild(createObjLoad("model/support_clr_l.obj")); tg_3.addChild(createObjLoad("model/ramp.obj"));
tg_2.addChild(tg_3); tg.addChild(tg_2);
objRoot.addChild(tg);
objRoot.compile();
return objRoot;
}
private BranchGroup createWheel() {
BranchGroup objRoot = new BranchGroup(); TransformGroup tg = new TransformGroup(); Transform3D t3d = new Transform3D(); // tg.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
t3d.setScale(2.0); tg.setTransform(t3d);
TransformGroup tg_rot = new TransformGroup(); tg_rot.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
tg_rot.addChild(createGondolas()); tg_rot.addChild(createObjLoad("model/wheel_clr.obj"));
Transform3D axis = new Transform3D(); axis.setRotation(new AxisAngle4f(1.0f, 0.0f, 0.0f, 1.57f));
Alpha alpha = new Alpha(1, 80000);
RotationInterpolator rotator = new RotationInterpolator(alpha, tg_rot, axis, 0.0f, (float) -Math.PI * 2.0f);
BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0); rotator.setSchedulingBounds(bounds);
tg.addChild(rotator); tg.addChild(tg_rot);
objRoot.addChild(tg); objRoot.compile();
return objRoot;
}
private BranchGroup createGondolas() {
BranchGroup objRoot = new BranchGroup();
TransformGroup tg = new TransformGroup(); Transform3D t3d = new Transform3D(); // tg.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); t3d.setScale(0.6); tg.setTransform(t3d);
TransformGroup tg_3 = new TransformGroup(); Transform3D t3d_3 = new Transform3D(); t3d_3.setTranslation(new Vector3d(0.0, -0.05, 0.0)); t3d_3.setScale(0.026); tg_3.setTransform(t3d_3);
SharedGroup shared = new SharedGroup(); TransformGroup tg_link = null; Transform3D t3d_link = new Transform3D(); TransformGroup tg_2 = null;
double r = 1.0; for (int i = 13; i < 31; i++) { t3d_link.setTranslation( new Vector3d(r * Math.cos((Math.PI / 9) * i), r * Math.sin((Math.PI / 9) * i), 0.0f));
tg_link = new TransformGroup(t3d_link); tg_link.addChild(new Link(shared)); tg.addChild(tg_link);
TransformGroup tg_rot = new TransformGroup(); // tg_link.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
tg_2 = new TransformGroup();
tg_rot.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); tg_rot.addChild(tg_2); tg_2.addChild(createObjLoad("model/gondola_clr.obj"));
tg_link.addChild(tg_rot);
if (firstTime) { tg_2.addChild(tg_3); tg_3.addChild(createPonta_Pom()); firstTime = false; }
Transform3D axis = new Transform3D(); axis.setRotation(new AxisAngle4f(1.0f, 0.0f, 0.0f, 1.57f));
Alpha alpha = new Alpha(1, 80000);
RotationInterpolator rotator2 = new RotationInterpolator(alpha, tg_rot, axis, 0.0f, (float) Math.PI * 2.0f);
BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0); rotator2.setSchedulingBounds(bounds); tg_2.addChild(rotator2);
}
objRoot.addChild(tg);
// objRoot.addChild(createLight(-0.3f, 0.2f, 0.0f)); // objRoot.addChild(createLight(0.3f, 0.2f, 0.0f));
objRoot.compile();
return objRoot;
}
private BranchGroup createPonta_Pom() {
BranchGroup objRoot = new BranchGroup();
TransformGroup tg = new TransformGroup(); Transform3D t3d = new Transform3D(); t3d.setScale(0.8); tg.setTransform(t3d);
TransformGroup tg_pt = new TransformGroup(); Transform3D t3d_pt = new Transform3D(); // tg_pt.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
TransformGroup tg_p = new TransformGroup(); Transform3D t3d_p = new Transform3D(); // tg_p.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
t3d_pt.setTranslation(new Vector3d(-0.6, -2.0, -0.8)); t3d_pt.setRotation(new AxisAngle4f(0.0f, 1.0f, 0.0f, -0.6f)); tg_pt.setTransform(t3d_pt);
t3d_p.setTranslation(new Vector3d(0.6, -2.0, -0.8)); t3d_p.setRotation(new AxisAngle4f(0.0f, 1.0f, 0.0f, 0.6f)); tg_p.setTransform(t3d_p);
tg_pt.addChild(createObjLoad("model/Sitting_Pomeranian.obj")); tg_p.addChild(createObjLoad("model/Sitting_Pomeranian.obj"));
tg.addChild(tg_pt); tg.addChild(tg_p); objRoot.addChild(tg); objRoot.compile();
return objRoot;
}
private BranchGroup createArchitecturePack() {
BranchGroup objRoot = new BranchGroup(); TransformGroup tg = new TransformGroup(); Transform3D t3d = new Transform3D(); tg.setCollidable(false);
tg.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
t3d.setTranslation(new Vector3d(-2.8, -10.9, -20.9)); t3d.setRotation(new AxisAngle4f(0.0f, 1.0f, 0.0f, -1.2f)); t3d.setScale(8.8); tg.setTransform(t3d);
tg.addChild(createObjLoad("model/Architecture_pack_001_fw_fl_rem.obj"));
objRoot.addChild(tg); objRoot.addChild(createLight(-1.0f, -1.0f, -1.0f)); objRoot.addChild(createLight(1.0f, 1.0f, 1.0f));
objRoot.compile();
return objRoot;
}
private BranchGroup createGround() {
BranchGroup objRoot = new BranchGroup();
TransformGroup tg = new TransformGroup(); Transform3D t3d = new Transform3D(); tg.setCollidable(false);
t3d.setTranslation(new Vector3d(0.0, -11.9, -0.0)); t3d.setScale(200.0); tg.setTransform(t3d);
tg.addChild(createObjLoad("model/ground.obj"));
objRoot.addChild(tg);
objRoot.compile();
return objRoot;
}
private BranchGroup createLeo() {
BranchGroup objRoot = new BranchGroup();
tg = new TransformGroup(); t3d = new Transform3D(); tg.setCollidable(false);
tg.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
t3d.setTranslation(new Vector3d(-50.0, -40.9, -25.0)); t3d.setRotation(new AxisAngle4f(0.0f, 1.0f, 0.0f, 1.57f)); t3d.setScale(0.8);
tg.setTransform(t3d);
tg.addChild(createLeo2()); // objRoot.addChild(createAmbientLight());
Appearance ap_yel = createAppearance(new Color3f(1.0f, 1.0f, 0.0f)); Sphere yball = new Sphere(0.6f, ap_yel);
int mode = TransparencyAttributes.NICEST; TransparencyAttributes transAttr_y = new TransparencyAttributes(mode, 1.0f); transAttr_y.setCapability(TransparencyAttributes.ALLOW_VALUE_WRITE); ap_yel.setTransparencyAttributes(transAttr_y);
TransformGroup tg_y = new TransformGroup(); Transform3D t3d_y = new Transform3D(); t3d_y.setTranslation(new Vector3d(0.0, 2.1, 1.2)); t3d_y.setScale(0.00001); tg_y.setTransform(t3d_y);
tg_y.addChild(yball); tg.addChild(tg_y);
CollisionDetectorGroup cdGroup = new CollisionDetectorGroup(tg_y); cdGroup.setSchedulingBounds(bounds); tg_y.addChild(cdGroup);
objRoot.addChild(tg); objRoot.compile();
return objRoot;
}
private BranchGroup createLeo2() {
BranchGroup objRoot = new BranchGroup();
selector.setCapability(Switch.ALLOW_SWITCH_WRITE);
flag_i.clear(); flag_i.set(1); selector.setChildMask(flag_i);
selector.addChild(createObjLoad("model/Pomeranian_tilt_2_legs_bend_smooth2.obj")); selector.addChild(createObjLoad("model/Pomeranian_tilt_-2_legs_bend_smooth2.obj")); selector.addChild(createObjLoad("model/Leo_pushing_air_bag.obj", 0.5, 0.48)); selector.addChild(createObjLoad("model/Leo_pushing_air_bag_mirror.obj", 0.5, 0.48));
objRoot.addChild(selector);
objRoot.compile();
return objRoot;
}
private BranchGroup createAirBag() {
BranchGroup objRoot = new BranchGroup(); tg_ab = new TransformGroup(); t3d_ab = new Transform3D();
tg_ab.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
t3d_ab.setTranslation(new Vector3d(-45.0, -40.0, -25.0)); t3d_ab.setScale(1.2);
tg_ab.setTransform(t3d_ab);
tg_ab.addChild(createObjLoad("model/air_bag_with_indentations.obj"));
objRoot.addChild(tg_ab); objRoot.addChild(createLight(-1.0f, -1.0f, -1.0f)); objRoot.addChild(createLight(1.0f, 1.0f, 1.0f)); objRoot.compile();
return objRoot;
}
private BranchGroup createObjLoad(String filename) {
BranchGroup objRoot = new BranchGroup();
TransformGroup tg = new TransformGroup(); Transform3D t3d = new Transform3D(); t3d.setScale(0.5); tg.setTransform(t3d);
ObjectFile loader = new ObjectFile(); Scene s = null;
File file = new java.io.File(filename);
try { s = loader.load(file.toURI().toURL()); } catch (Exception e) { System.err.println(e); System.exit(1); }
tg.addChild(s.getSceneGroup());
objRoot.addChild(tg);
objRoot.compile();
return objRoot;
}
private BranchGroup createObjLoad(String filename, double y, double scale) {
BranchGroup objRoot = new BranchGroup();
TransformGroup tg = new TransformGroup(); Transform3D t3d = new Transform3D(); t3d.setTranslation(new Vector3d(0.0, y, 0.0)); t3d.setScale(scale); tg.setTransform(t3d);
ObjectFile loader = new ObjectFile(); Scene s = null;
File file = new java.io.File(filename);
try { s = loader.load(file.toURI().toURL()); } catch (Exception e) { System.err.println(e); System.exit(1); }
tg.addChild(s.getSceneGroup());
objRoot.addChild(tg);
objRoot.compile();
return objRoot;
}
/* * private Light createAmbientLight() { AmbientLight light = new * AmbientLight(new Color3f(0.35f, 0.35f, 0.35f)); *Â * light.setInfluencingBounds(new BoundingSphere(new Point3d(), 100.0)); *Â * return light; } */ public void getSound(String fname, double vol) {
try { URL url = this.getClass().getClassLoader().getResource(fname); AudioInputStream audioIn = AudioSystem.getAudioInputStream(url); clip = AudioSystem.getClip(); clip.open(audioIn); FloatControl control = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN); controlByLinearScalar(control, vol); clip.start(); } catch (UnsupportedAudioFileException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (LineUnavailableException e) { e.printStackTrace(); } }
private void controlByLinearScalar(FloatControl control, double linearScalar) { control.setValue((float) Math.log10(linearScalar) * 20); }
private Appearance createAppearance(Color3f col) { Appearance ap = new Appearance(); Material ma = new Material(); ma.setDiffuseColor(col); ap.setMaterial(ma); return ap; }
private Light createLight(float x, float y, float z) { DirectionalLight light = new DirectionalLight(true, new Color3f(1.0f, 1.0f, 1.0f), new Vector3f(x, y, z));
light.setInfluencingBounds(new BoundingSphere(new Point3d(), 10000.0));
return light; }
public static void main(String args[]) {
Mykeynavbeh window = new Mykeynavbeh();
window.setSize(800, 600);
window.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } });
window.setVisible(true); }
public void keyTyped(KeyEvent e) { char key = e.getKeyChar(); // System.out.println("inCollision: "+inCollision);
if (key == 't') { System.out.println("inCollision_t_key: " + inCollision);
flag_i.clear(); flag_i.set(count % 2); selector.setChildMask(flag_i);
t3dstep.set(new Vector3d(0.0, 0.0, 0.1)); tg.getTransform(t3d); t3d.mul(t3dstep); tg.setTransform(t3d);
count++; }
if (key == 'b') { System.out.println("inCollision_b_key: " + inCollision);
flag_i.clear(); flag_i.set(count % 2); selector.setChildMask(flag_i);
t3dstep.set(new Vector3d(0.0, 0.0, -0.4)); tg.getTransform(t3d); t3d.mul(t3dstep); tg.setTransform(t3d);
count++;
}
if (key == 's') {
angle++;
flag_i.clear(); flag_i.set(count % 2); selector.setChildMask(flag_i);
t3dstep.rotY(Math.PI / 4); tg.getTransform(t3d); t3d.get(matrix); t3d.setTranslation(new Vector3d(0.0, 0.0, 0.0)); t3d.mul(t3dstep); t3d.setTranslation(new Vector3d(matrix.m03, matrix.m13, matrix.m23)); tg.setTransform(t3d);
count++;
}
if (key == 'f') {
angle--; System.out.println("angle: " + angle); System.out.println("angle % 8: " + angle % 8);
flag_i.clear(); flag_i.set(count % 2); selector.setChildMask(flag_i);
t3dstep.rotY(-Math.PI / 4); tg.getTransform(t3d); t3d.get(matrix); t3d.setTranslation(new Vector3d(0.0, 0.0, 0.0)); t3d.mul(t3dstep); t3d.setTranslation(new Vector3d(matrix.m03, matrix.m13, matrix.m23)); tg.setTransform(t3d);
count++;
}
if (key == 'x') { flag_i.clear(); flag_i.set(1); selector.setChildMask(flag_i); }
if ((key == 'm') && (clip == null)) { getSound("sound/Gondola High_st.wav", 0.5); }
if ((key == 'p') && (clip != null)) { clip.stop(); clip = null; }
}
public void keyReleased(KeyEvent e) { char key = e.getKeyChar();
if ((Math.abs(angle % 8) == 4) || (angle % 8 == 0)) { if ((key == 'w') || (key == 'r')) { flag_i.clear(); flag_i.set((count % 2) + 2); System.out.println("((count % 2)+2)): " + ((count % 2) + 2)); selector.setChildMask(flag_i); } } }
public void keyPressed(KeyEvent e) { char key = e.getKeyChar(); System.out.println("inCollision_keyPressed: " + inCollision);
if ((key == 'd') && (inCollision == false)) { System.out.println("inCollision_d_key: " + inCollision);
flag_i.clear(); flag_i.set(count % 2); selector.setChildMask(flag_i);
t3dstep.set(new Vector3d(0.0, 0.0, 0.3)); tg.getTransform(t3d); t3d.mul(t3dstep); tg.setTransform(t3d);
count++; }
if (angle % 8 == 0) { if ((key == 'w') && (inCollision == true)) { System.out.println("w key"); flag_i.clear(); flag_i.set((count % 2) + 2); System.out.println("((count % 2)+2)): " + ((count % 2) + 2)); selector.setChildMask(flag_i);
t3dstep.set(new Vector3d(0.0, 0.0, 0.39)); tg.getTransform(t3d); t3d.mul(t3dstep); tg.setTransform(t3d);
t3dstep.set(new Vector3d(0.26, 0.0, 0.0)); tg_ab.getTransform(t3d_ab); t3d_ab.mul(t3dstep); tg_ab.setTransform(t3d_ab);
count++;
} }
if (Math.abs(angle % 8) == 4) { if ((key == 'r') && (inCollision == true)) { System.out.println("r key"); flag_i.clear(); flag_i.set((count % 2) + 2); System.out.println("((count % 2)+2)): " + ((count % 2) + 2)); selector.setChildMask(flag_i);
t3dstep.set(new Vector3d(0.0, 0.0, 0.39)); tg.getTransform(t3d); t3d.mul(t3dstep); tg.setTransform(t3d);
t3dstep.set(new Vector3d(-0.26, 0.0, 0.0)); tg_ab.getTransform(t3d_ab); t3d_ab.mul(t3dstep); tg_ab.setTransform(t3d_ab);
count++;
} } }
class CollisionDetectorGroup extends Behavior { // private boolean inCollision = false; private Group group;
private WakeupOnCollisionEntry wEnter; private WakeupOnCollisionExit wExit;
public CollisionDetectorGroup(Group cdGroup) { group = cdGroup; inCollision = false;
}
public void initialize() { wEnter = new WakeupOnCollisionEntry(group); wExit = new WakeupOnCollisionExit(group); wakeupOn(wEnter); }
public void processStimulus(Enumeration criteria) {
inCollision = !inCollision; if (inCollision) {
wakeupOn(wExit); } else { wakeupOn(wEnter); } } }
}