1 /* 2 * Copyright (c) 2009-2012 jMonkeyEngine 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: 8 * 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * * Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 package com.jme3.bounding; 34 35 import com.jme3.collision.Collidable; 36 import com.jme3.export.JmeExporter; 37 import com.jme3.export.JmeImporter; 38 import com.jme3.export.Savable; 39 import com.jme3.math.*; 40 import java.io.IOException; 41 import java.nio.FloatBuffer; 42 43 /** 44 * <code>BoundingVolume</code> defines an interface for dealing with 45 * containment of a collection of points. 46 * 47 * @author Mark Powell 48 * @version $Id: BoundingVolume.java,v 1.24 2007/09/21 15:45:32 nca Exp $ 49 */ 50 public abstract class BoundingVolume implements Savable, Cloneable, Collidable { 51 52 /** 53 * The type of bounding volume being used. 54 */ 55 public enum Type { 56 /** 57 * {@link BoundingSphere} 58 */ 59 Sphere, 60 61 /** 62 * {@link BoundingBox}. 63 */ 64 AABB, 65 66 /** 67 * {@link com.jme3.bounding.OrientedBoundingBox} 68 */ 69 OBB, 70 71 /** 72 * Currently unsupported by jME3. 73 */ 74 Capsule; 75 } 76 77 protected int checkPlane = 0; 78 protected Vector3f center = new Vector3f(); 79 80 public BoundingVolume() { 81 } 82 83 public BoundingVolume(Vector3f center) { 84 this.center.set(center); 85 } 86 87 /** 88 * Grabs the checkplane we should check first. 89 * 90 */ 91 public int getCheckPlane() { 92 return checkPlane; 93 } 94 95 /** 96 * Sets the index of the plane that should be first checked during rendering. 97 * 98 * @param value 99 */ 100 public final void setCheckPlane(int value) { 101 checkPlane = value; 102 } 103 104 /** 105 * getType returns the type of bounding volume this is. 106 */ 107 public abstract Type getType(); 108 109 /** 110 * 111 * <code>transform</code> alters the location of the bounding volume by a 112 * rotation, translation and a scalar. 113 * 114 * @param trans 115 * the transform to affect the bound. 116 * @return the new bounding volume. 117 */ 118 public final BoundingVolume transform(Transform trans) { 119 return transform(trans, null); 120 } 121 122 /** 123 * 124 * <code>transform</code> alters the location of the bounding volume by a 125 * rotation, translation and a scalar. 126 * 127 * @param trans 128 * the transform to affect the bound. 129 * @param store 130 * sphere to store result in 131 * @return the new bounding volume. 132 */ 133 public abstract BoundingVolume transform(Transform trans, BoundingVolume store); 134 135 public abstract BoundingVolume transform(Matrix4f trans, BoundingVolume store); 136 137 /** 138 * 139 * <code>whichSide</code> returns the side on which the bounding volume 140 * lies on a plane. Possible values are POSITIVE_SIDE, NEGATIVE_SIDE, and 141 * NO_SIDE. 142 * 143 * @param plane 144 * the plane to check against this bounding volume. 145 * @return the side on which this bounding volume lies. 146 */ 147 public abstract Plane.Side whichSide(Plane plane); 148 149 /** 150 * 151 * <code>computeFromPoints</code> generates a bounding volume that 152 * encompasses a collection of points. 153 * 154 * @param points 155 * the points to contain. 156 */ 157 public abstract void computeFromPoints(FloatBuffer points); 158 159 /** 160 * <code>merge</code> combines two bounding volumes into a single bounding 161 * volume that contains both this bounding volume and the parameter volume. 162 * 163 * @param volume 164 * the volume to combine. 165 * @return the new merged bounding volume. 166 */ 167 public abstract BoundingVolume merge(BoundingVolume volume); 168 169 /** 170 * <code>mergeLocal</code> combines two bounding volumes into a single 171 * bounding volume that contains both this bounding volume and the parameter 172 * volume. The result is stored locally. 173 * 174 * @param volume 175 * the volume to combine. 176 * @return this 177 */ 178 public abstract BoundingVolume mergeLocal(BoundingVolume volume); 179 180 /** 181 * <code>clone</code> creates a new BoundingVolume object containing the 182 * same data as this one. 183 * 184 * @param store 185 * where to store the cloned information. if null or wrong class, 186 * a new store is created. 187 * @return the new BoundingVolume 188 */ 189 public abstract BoundingVolume clone(BoundingVolume store); 190 191 public final Vector3f getCenter() { 192 return center; 193 } 194 195 public final Vector3f getCenter(Vector3f store) { 196 store.set(center); 197 return store; 198 } 199 200 public final void setCenter(Vector3f newCenter) { 201 center.set(newCenter); 202 } 203 204 /** 205 * Find the distance from the center of this Bounding Volume to the given 206 * point. 207 * 208 * @param point 209 * The point to get the distance to 210 * @return distance 211 */ 212 public final float distanceTo(Vector3f point) { 213 return center.distance(point); 214 } 215 216 /** 217 * Find the squared distance from the center of this Bounding Volume to the 218 * given point. 219 * 220 * @param point 221 * The point to get the distance to 222 * @return distance 223 */ 224 public final float distanceSquaredTo(Vector3f point) { 225 return center.distanceSquared(point); 226 } 227 228 /** 229 * Find the distance from the nearest edge of this Bounding Volume to the given 230 * point. 231 * 232 * @param point 233 * The point to get the distance to 234 * @return distance 235 */ 236 public abstract float distanceToEdge(Vector3f point); 237 238 /** 239 * determines if this bounding volume and a second given volume are 240 * intersecting. Intersecting being: one volume contains another, one volume 241 * overlaps another or one volume touches another. 242 * 243 * @param bv 244 * the second volume to test against. 245 * @return true if this volume intersects the given volume. 246 */ 247 public abstract boolean intersects(BoundingVolume bv); 248 249 /** 250 * determines if a ray intersects this bounding volume. 251 * 252 * @param ray 253 * the ray to test. 254 * @return true if this volume is intersected by a given ray. 255 */ 256 public abstract boolean intersects(Ray ray); 257 258 259 /** 260 * determines if this bounding volume and a given bounding sphere are 261 * intersecting. 262 * 263 * @param bs 264 * the bounding sphere to test against. 265 * @return true if this volume intersects the given bounding sphere. 266 */ 267 public abstract boolean intersectsSphere(BoundingSphere bs); 268 269 /** 270 * determines if this bounding volume and a given bounding box are 271 * intersecting. 272 * 273 * @param bb 274 * the bounding box to test against. 275 * @return true if this volume intersects the given bounding box. 276 */ 277 public abstract boolean intersectsBoundingBox(BoundingBox bb); 278 279 /** 280 * determines if this bounding volume and a given bounding box are 281 * intersecting. 282 * 283 * @param bb 284 * the bounding box to test against. 285 * @return true if this volume intersects the given bounding box. 286 */ 287 // public abstract boolean intersectsOrientedBoundingBox(OrientedBoundingBox bb); 288 /** 289 * 290 * determines if a given point is contained within this bounding volume. 291 * If the point is on the edge of the bounding volume, this method will 292 * return false. Use intersects(Vector3f) to check for edge intersection. 293 * 294 * @param point 295 * the point to check 296 * @return true if the point lies within this bounding volume. 297 */ 298 public abstract boolean contains(Vector3f point); 299 300 /** 301 * Determines if a given point intersects (touches or is inside) this bounding volume. 302 * @param point the point to check 303 * @return true if the point lies within this bounding volume. 304 */ 305 public abstract boolean intersects(Vector3f point); 306 307 public abstract float getVolume(); 308 309 @Override 310 public BoundingVolume clone() { 311 try{ 312 BoundingVolume clone = (BoundingVolume) super.clone(); 313 clone.center = center.clone(); 314 return clone; 315 }catch (CloneNotSupportedException ex){ 316 throw new AssertionError(); 317 } 318 } 319 320 public void write(JmeExporter e) throws IOException { 321 e.getCapsule(this).write(center, "center", Vector3f.ZERO); 322 } 323 324 public void read(JmeImporter e) throws IOException { 325 center = (Vector3f) e.getCapsule(this).readSavable("center", Vector3f.ZERO.clone()); 326 } 327 328 } 329 330