001: /*
002: * $Header: /cvs/j3dfly/J3dFly/src/org/jdesktop/j3dfly/utils/vpbehaviors/VPVehicleCollision.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: import org.jdesktop.j3dfly.utils.vpbehaviors.vehicles.SimpleVehicle;
027:
028: /**
029: * @author Paul Byrne
030: * @version 1.3 01/18/02
031: */
032: public class VPVehicleCollision extends VPDefaultCollision {
033:
034: private Point3d rayStart = new Point3d(0, 1000, 0);
035: private static final Vector3d rayVec = new Vector3d(0, -1, 0);
036: private Vector3f pos = new Vector3f();
037: private float height = 0.3f;
038:
039: private SimpleVehicle vehicle;
040:
041: private Transform3D yawT = new Transform3D();
042: private Transform3D pitchT = new Transform3D();
043: private Transform3D rollT = new Transform3D();
044: private Transform3D velocityT = new Transform3D();
045: private Transform3D destination = new Transform3D();
046:
047: /** Creates new VPDriveCollision */
048: public VPVehicleCollision(int mode) {
049: super (mode);
050: }
051:
052: /** Creates new VPDriveCollision */
053: public VPVehicleCollision() {
054: super ();
055: }
056:
057: /**
058: * Set the Vehcile
059: */
060: public void setVehicle(SimpleVehicle vehicle) {
061: this .vehicle = vehicle;
062: }
063:
064: /**
065: * Set the height the viewer will be placed above the floor
066: */
067: public void setHeight(float height) {
068: this .height = height;
069: }
070:
071: /**
072: * Get the height the viewer is from the floor
073: */
074: public float getHeight() {
075: return height;
076: }
077:
078: /**
079: * Check for collision when casting the swept bounds from currentLocation to
080: * nextLocation. The orientation of the swept bounds is set to the orientation at
081: * nextLocation.
082: *
083: * Also force the view to be the specified height above the floor.
084: *
085: * This implementation only processes the first ray in each direction. It
086: * also requires that a ray exists in each direction.
087: *
088: * @param currentLocation The current location of the view
089: * @param nextLocation Will contain the next non collision location of the view on return
090: * @param velocity The current velocity vector for the view
091: * @param roll The change in roll for this frame
092: * @param pitch The change in pitch for this frame
093: * @param yaw The change in yaw for this frame
094: */
095: public SweptVolumeCollision getCollisions(
096: Transform3D currentLocation, Transform3D nextLocation,
097: Vector3f velocity, float roll, float pitch, float yaw) {
098:
099: boolean collision = false;
100: SweptVolumeCollision ret = new SweptVolumeCollision();
101:
102: yawT.setIdentity();
103: pitchT.setIdentity();
104: rollT.setIdentity();
105: velocityT.setIdentity();
106: destination.setIdentity();
107:
108: yawT.rotY(yaw);
109: pitchT.rotX(pitch);
110: rollT.rotZ(roll);
111:
112: velocityT.set(velocity);
113: velocityT.mul(yawT);
114: velocityT.mul(pitchT);
115: velocityT.mul(rollT);
116:
117: destination.set(currentLocation);
118:
119: destination.mul(yawT);
120: destination.mul(pitchT);
121: destination.mul(rollT);
122: destination.mul(velocityT);
123:
124: // Find the floor
125: destination.get(pos);
126: rayStart.x = pos.x;
127: rayStart.z = pos.z;
128: rayStart.y = 100000;
129:
130: pickTool.setShapeRay(rayStart, rayVec);
131: PickResult floor = pickTool.pickClosest();
132: if (floor != null) {
133: pos.y = (float) floor.getIntersection(0)
134: .getPointCoordinates().y
135: + height;
136: destination.setTranslation(pos);
137: }
138:
139: collision |= checkZDirection(currentLocation, destination,
140: velocity, ret);
141: collision |= checkXDirection(currentLocation, destination,
142: velocity, ret);
143: collision |= checkYDirection(currentLocation, destination,
144: velocity, ret);
145:
146: // In many cases the checkYDirection call can be omitted. However it is
147: // included in this general class to check for collision above the
148: // view position.
149:
150: // If the volume is in collision return the original transform, ie
151: // don't move.
152: // An alternative approach would be to calculate the 'best' move from
153: // the current location, ie move as far as possible without causing
154: // collision.
155: if (collision) {
156: nextLocation.set(currentLocation);
157: return null;
158: } else {
159: nextLocation.set(destination);
160: vehicle.vehicleMoved(pickTool, destination);
161: return ret;
162: }
163: }
164: }
|