001: /*
002: * $Header: /cvs/j3dfly/J3dFly/src/org/jdesktop/j3dfly/utils/vpbehaviors/VPDriveCollision.java,v 1.1 2005/04/20 21:05:15 paulby Exp $
003: *
004: * Sun Public License Notice
005: *
006: * The contents of this file are subject to the Sun Public License Version
007: * 1.0 (the "License"). You may not use this file except in compliance with
008: * the License. A copy of the License is available at http://www.sun.com/
009: *
010: * The Original Code is Java 3D(tm) Fly Through.
011: * The Initial Developer of the Original Code is Paul Byrne.
012: * Portions created by Paul Byrne are Copyright (C) 2002.
013: * All Rights Reserved.
014: *
015: * Contributor(s): Paul Byrne.
016: *
017: **/
018: package org.jdesktop.j3dfly.utils.vpbehaviors;
019:
020: import javax.media.j3d.Transform3D;
021: import javax.vecmath.Vector3f;
022: import javax.vecmath.Vector3d;
023: import javax.vecmath.Point3d;
024: import com.sun.j3d.utils.picking.PickResult;
025:
026: /**
027: * A collision implementation that places the view a set distance above
028: * the 'floor' and then applies collision detection.
029: *
030: * The floor is determined as the first geometry that intersects the ray
031: * (0,large +ve, 0) -> ( 0, -1, 0 )
032: *
033: * @author Paul Byrne
034: * @version 1.4 01/18/02
035: */
036: public class VPDriveCollision extends VPDefaultCollision {
037:
038: private Point3d rayStart = new Point3d(0, 1000, 0);
039: private static final Vector3d rayVec = new Vector3d(0, -1, 0);
040: private Vector3f pos = new Vector3f();
041: private float height = 1.2f;
042:
043: /** Creates new VPDriveCollision */
044: public VPDriveCollision(int mode) {
045: super (mode);
046: }
047:
048: /** Creates new VPDriveCollision */
049: public VPDriveCollision() {
050: super ();
051: }
052:
053: /**
054: * Set the height the viewer will be placed above the floor
055: */
056: public void setHeight(float height) {
057: this .height = height;
058: }
059:
060: /**
061: * Get the height the viewer is from the floor
062: */
063: public float getHeight() {
064: return height;
065: }
066:
067: /**
068: * Check for collision when casting the swept bounds from currentLocation to
069: * nextLocation. The orientation of the swept bounds is set to the orientation at
070: * nextLocation.
071: *
072: * Also force the view to be the specified height above the floor.
073: *
074: * This implementation only processes the first ray in each direction. It
075: * also requires that a ray exists in each direction.
076: *
077: * @param currentLocation The current location of the view
078: * @param nextLocation Will contain the next non collision location of the view on return
079: * @param velocity The current velocity vector for the view
080: * @param roll The change in roll for this frame
081: * @param pitch The change in pitch for this frame
082: * @param yaw The change in yaw for this frame
083: */
084: public SweptVolumeCollision getCollisions(
085: Transform3D currentLocation, Transform3D nextLocation,
086: Vector3f velocity, float roll, float pitch, float yaw) {
087:
088: boolean collision = false;
089: SweptVolumeCollision ret = new SweptVolumeCollision();
090:
091: Transform3D yawT = new Transform3D();
092: Transform3D pitchT = new Transform3D();
093: Transform3D rollT = new Transform3D();
094: Transform3D velocityT = new Transform3D();
095: Transform3D destination = new Transform3D();
096:
097: yawT.rotY(yaw);
098: pitchT.rotX(pitch);
099: rollT.rotZ(roll);
100:
101: velocityT.set(velocity);
102: velocityT.mul(yawT);
103: velocityT.mul(pitchT);
104: velocityT.mul(rollT);
105:
106: destination.set(currentLocation);
107:
108: destination.mul(yawT);
109: destination.mul(pitchT);
110: destination.mul(rollT);
111: destination.mul(velocityT);
112:
113: // Find the floor
114: destination.get(pos);
115: rayStart.x = pos.x;
116: rayStart.z = pos.z;
117: rayStart.y = 100000;
118:
119: pickTool.setShapeRay(rayStart, rayVec);
120: PickResult floor = pickTool.pickClosest();
121: if (floor != null) {
122: pos.y = (float) floor.getIntersection(0)
123: .getPointCoordinates().y
124: + height;
125: destination.setTranslation(pos);
126: }
127:
128: collision |= checkZDirection(currentLocation, destination,
129: velocity, ret);
130: collision |= checkXDirection(currentLocation, destination,
131: velocity, ret);
132: collision |= checkYDirection(currentLocation, destination,
133: velocity, ret);
134:
135: // In many cases the checkYDirection call can be omitted. However it is
136: // included in this general class to check for collision above the
137: // view position.
138:
139: // If the volume is in collision return the original transform, ie
140: // don't move.
141: // An alternative approach would be to calculate the 'best' move from
142: // the current location, ie move as far as possible without causing
143: // collision.
144: if (collision) {
145: nextLocation.set(currentLocation);
146: return null;
147: } else {
148: nextLocation.set(destination);
149: return ret;
150: }
151: }
152: }
|