From 354041e8d61571b25c6eeb672537a013d3e0fa60 Mon Sep 17 00:00:00 2001 From: Jesse Morgan Date: Fri, 11 Feb 2011 18:53:32 +0000 Subject: Broke the grabbing code but added Alden's collision code. Not sure if its working yet since my Mac doesn't like it. --- src/alden/CollisionDetectorDemo.java | 237 +++++++++++++++++++++++++++++++++++ 1 file changed, 237 insertions(+) create mode 100644 src/alden/CollisionDetectorDemo.java (limited to 'src/alden/CollisionDetectorDemo.java') diff --git a/src/alden/CollisionDetectorDemo.java b/src/alden/CollisionDetectorDemo.java new file mode 100644 index 0000000..b2268a4 --- /dev/null +++ b/src/alden/CollisionDetectorDemo.java @@ -0,0 +1,237 @@ +package alden; +import com.sun.j3d.utils.geometry.*; +import com.sun.j3d.utils.geometry.Box; +import com.sun.j3d.utils.picking.*; +import com.sun.j3d.utils.picking.behaviors.*; +import com.sun.j3d.utils.universe.*; +import java.awt.*; +import java.awt.event.*; +import java.util.*; +import java.util.List; +import javax.media.j3d.*; +import javax.swing.*; +import javax.swing.Timer; +import javax.vecmath.*; + +@SuppressWarnings("restriction") +public class CollisionDetectorDemo { + private JFrame appFrame; + private Canvas3D canvas3D; + private BranchGroup scene; + private BoundingLeaf originLeaf; + // Bounding box defining the periphery of the virtual world. + private BoundingBox virtualWorldBounds; + // Data needed for adjusting the camera position. + private TransformGroup cameraTG; + private double cameraXRotation, cameraYRotation, cameraDistance; + private MouseEvent lastDragEvent; + // A list of all the objects in the world + private List objects; + // A list of all the visual collision points + private List collisionPoints; + // Number of state updates per second + private final int UPDATE_RATE = 30; + + public static void main(String[] args) { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + new CollisionDetectorDemo().createAndShowGUI(); + } + }); + } + + private CollisionDetectorDemo() { + final double UNIT = 1f; + virtualWorldBounds = new BoundingBox(new Point3d(-UNIT/2, -UNIT/2, -UNIT/2), new Point3d(UNIT/2, UNIT/2, UNIT/2)); + cameraDistance = 3 * UNIT; + objects = new ArrayList(); + collisionPoints = new ArrayList(); + } + + private void createAndShowGUI() { + GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration(); + canvas3D = new Canvas3D(config); + SimpleUniverse universe = new SimpleUniverse(canvas3D); + cameraTG = universe.getViewingPlatform().getViewPlatformTransform(); + updateCamera(); + universe.getViewer().getView().setSceneAntialiasingEnable(true); + + scene = new BranchGroup(); + scene.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND); + scene.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE); + originLeaf = new BoundingLeaf(new BoundingSphere()); + scene.addChild(originLeaf); + scene.addChild(createVirtualWorldBoundsShape()); + addObjects(); + scene.compile(); + universe.addBranchGraph(scene); + + appFrame = new JFrame("Collision Detector Demo"); + appFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + appFrame.add(canvas3D); + appFrame.pack(); + if (Toolkit.getDefaultToolkit().isFrameStateSupported(JFrame.MAXIMIZED_BOTH)) + appFrame.setExtendedState(appFrame.getExtendedState() | JFrame.MAXIMIZED_BOTH); + + canvas3D.addMouseMotionListener(new MouseMotionAdapter() { + public void mouseDragged(MouseEvent e) { + if ((e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) == 0) + return; + if (lastDragEvent != null) { + cameraXRotation += Math.toRadians(e.getY() - lastDragEvent.getY()) / 3; + if (cameraXRotation > Math.PI / 2) + cameraXRotation = Math.PI / 2; + else if (cameraXRotation < -Math.PI / 2) + cameraXRotation = -Math.PI / 2; + cameraYRotation += Math.toRadians(e.getX() - lastDragEvent.getX()) / 3; + updateCamera(); + } + lastDragEvent = e; + } + public void mouseMoved(MouseEvent e) { + lastDragEvent = null; + }}); + canvas3D.addMouseWheelListener(new MouseWheelListener() { + public void mouseWheelMoved(MouseWheelEvent e) { + if (e.getWheelRotation() > 0) + cameraDistance *= 1.05; + else if (e.getWheelRotation() < 0) + cameraDistance *= 0.95; + updateCamera(); + } + }); + new Timer(1000 / UPDATE_RATE, new ActionListener() { + public void actionPerformed(ActionEvent e) { + canvas3D.stopRenderer(); + tick(); + canvas3D.startRenderer(); + } + }).start(); + + appFrame.setVisible(true); + } + + private Node createVirtualWorldBoundsShape() { + Point3d lower = new Point3d(); + Point3d upper = new Point3d(); + virtualWorldBounds.getLower(lower); + virtualWorldBounds.getUpper(upper); + + double coordinates[] = {lower.x, lower.y, lower.z, upper.x, lower.y, lower.z, + upper.x, lower.y, upper.z, lower.x, lower.y, upper.z, + lower.x, upper.y, lower.z, upper.x, upper.y, lower.z, + upper.x, upper.y, upper.z, lower.x, upper.y, upper.z}; + int coordinateIndices[] = {0, 1, 1, 2, 2, 3, 3, 0, + 4, 5, 5, 6, 6, 7, 7, 4, + 0, 4, 1, 5, 2, 6, 3, 7}; + + IndexedLineArray geometry = new IndexedLineArray(coordinates.length / 3, IndexedLineArray.COORDINATES, coordinateIndices.length); + geometry.setCoordinates(0, coordinates); + geometry.setCoordinateIndices(0, coordinateIndices); + + return new Shape3D(geometry); + } + + private void addObjects() { + BranchGroup pickables = new BranchGroup(); + pickables.addChild(new PickTranslateBehavior(pickables, canvas3D, virtualWorldBounds, PickTool.GEOMETRY)); + pickables.addChild(new PickZoomBehavior(pickables, canvas3D, virtualWorldBounds, PickTool.GEOMETRY)); + scene.addChild(pickables); + + Appearance appearance = new Appearance(); + appearance.setTransparencyAttributes(new TransparencyAttributes(TransparencyAttributes.NICEST, 0.2f)); + appearance.setColoringAttributes(new ColoringAttributes(1, 0.7f, 0.7f, ColoringAttributes.FASTEST)); + Primitive prim = new com.sun.j3d.utils.geometry.Sphere(0.2f, 0, 15, appearance); + objects.add(new GenericCollidableObject(prim, new Vector3f(0, 0, 0.3f), originLeaf)); + + appearance = new Appearance(); + appearance.setTransparencyAttributes(new TransparencyAttributes(TransparencyAttributes.NICEST, 0.2f)); + appearance.setColoringAttributes(new ColoringAttributes(0.7f, 1, 0.7f, ColoringAttributes.FASTEST)); + prim = new Box(0.2f, 0.15f, 0.1f, 0, appearance); + objects.add(new GenericCollidableObject(prim, new Vector3f(0.3f, 0, 0), originLeaf)); + + appearance = new Appearance(); + appearance.setTransparencyAttributes(new TransparencyAttributes(TransparencyAttributes.NICEST, 0.2f)); + appearance.setColoringAttributes(new ColoringAttributes(0.7f, 0.7f, 1, ColoringAttributes.FASTEST)); + prim = new Cylinder(0.2f, 0.4f, 0, 15, 1, appearance); + objects.add(new GenericCollidableObject(prim, new Vector3f(0, 0, -0.3f), originLeaf)); + + appearance = new Appearance(); + appearance.setTransparencyAttributes(new TransparencyAttributes(TransparencyAttributes.NICEST, 0.2f)); + appearance.setColoringAttributes(new ColoringAttributes(1, 1, 0.7f, ColoringAttributes.FASTEST)); + prim = new com.sun.j3d.utils.geometry.Cone(0.15f, 0.3f, 0, 15, 1, appearance); + objects.add(new GenericCollidableObject(prim, new Vector3f(-0.3f, 0, 0), originLeaf)); + + for (CollidableObject object : objects) + pickables.addChild(object.getGroup()); + } + + private void tick() { + for (BranchGroup BG : collisionPoints) + BG.detach(); + collisionPoints.clear(); + + for (int i = 0; i < objects.size() - 1; i++) + for (int j = i + 1; j < objects.size(); j++) { + ArrayList collisions = CollisionDetector.calculateCollisions(objects.get(i), objects.get(j)); + Appearance appearance = new Appearance(); + ColoringAttributes cAttr = new ColoringAttributes(new Color3f(1, 0, 0), ColoringAttributes.FASTEST); + appearance.setColoringAttributes(cAttr); + for (CollisionInfo ci : collisions) { + Transform3D tmp = new Transform3D(); + tmp.setTranslation(ci.contactPoint); + TransformGroup TG = new TransformGroup(tmp); + TG.addChild(new com.sun.j3d.utils.geometry.Sphere(0.002f, 0, 8, appearance)); + BranchGroup BG = new BranchGroup(); + BG.setCapability(BranchGroup.ALLOW_DETACH); + BG.addChild(TG); + collisionPoints.add(BG); + scene.addChild(BG); + } + } + } + + private void updateCamera() { + Transform3D camera3D = new Transform3D(); + camera3D.setTranslation(new Vector3f(0f, 0f, -(float)cameraDistance)); + Transform3D tmp = new Transform3D(); + tmp.rotX(cameraXRotation); + camera3D.mul(tmp); + tmp.rotY(cameraYRotation); + camera3D.mul(tmp); + camera3D.invert(); + cameraTG.setTransform(camera3D); + } + + private static class CollisionUpdateBehavior extends Behavior { + private GenericCollidableObject gco; + private TransformGroup TG; + + public CollisionUpdateBehavior(GenericCollidableObject gco, TransformGroup TG, BoundingLeaf boundingLeaf) { + this.gco = gco; + this.TG = TG; + setSchedulingBoundingLeaf(boundingLeaf); + } + + public void initialize() { + wakeupOn(new WakeupOnTransformChange(TG)); + } + + public void processStimulus(Enumeration e) { + gco.clearCaches(); + wakeupOn(new WakeupOnTransformChange(TG)); + } + } + + private static class GenericCollidableObject extends CollidableObject { + public GenericCollidableObject(Node shapeNode, Vector3f position, BoundingLeaf boundingLeaf) { + setShape(shapeNode); + this.position.set(position); + TG.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + TG.setCapability(TransformGroup.ENABLE_PICK_REPORTING); + TG.addChild(CollisionDetector.createShape(CollisionDetector.triangularize(shapeNode))); + BG.addChild(new CollisionUpdateBehavior(this, TG, boundingLeaf)); + updateTransformGroup(); + } + } +} -- cgit v1.2.3