Home | History | Annotate | Download | only in bounding
      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