• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2009-2010 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 /**
36  * NOTE: This class has been commented out as it has too many dependencies.
37  */
38 
39 
40 //
41 //import java.io.IOException;
42 //import java.nio.FloatBuffer;
43 //
44 ////import com.jme.scene.TriMesh;
45 //
46 ///**
47 // * Started Date: Sep 5, 2004 <br>
48 // * <br>
49 // *
50 // * @author Jack Lindamood
51 // * @author Joshua Slack (alterations for .9)
52 // * @version $Id: OrientedBoundingBox.java,v 1.35 2007/09/21 15:45:31 nca Exp $
53 // */
54 //public class OrientedBoundingBox extends BoundingVolume {
55 //
56 //    private static final long serialVersionUID = 1L;
57 //
58 //    static private final Vector3f _compVect3 = new Vector3f();
59 //
60 //    static private final Vector3f _compVect4 = new Vector3f();
61 //
62 //    static private final Vector3f _compVect5 = new Vector3f();
63 //
64 //    static private final Vector3f _compVect6 = new Vector3f();
65 //
66 //    static private final Vector3f _compVect7 = new Vector3f();
67 //
68 //    static private final Vector3f _compVect8 = new Vector3f();
69 //
70 //    static private final Vector3f _compVect9 = new Vector3f();
71 //
72 //    static private final Vector3f _compVect10 = new Vector3f();
73 //
74 //    static private final Vector3f tempVe = new Vector3f();
75 //
76 //    static private final Matrix3f tempMa = new Matrix3f();
77 //
78 //    static private final Quaternion tempQa = new Quaternion();
79 //
80 //    static private final Quaternion tempQb = new Quaternion();
81 //
82 //    private static final float[] fWdU = new float[3];
83 //
84 //    private static final float[] fAWdU = new float[3];
85 //
86 //    private static final float[] fDdU = new float[3];
87 //
88 //    private static final float[] fADdU = new float[3];
89 //
90 //    private static final float[] fAWxDdU = new float[3];
91 //
92 //    private static final float[] tempFa = new float[3];
93 //
94 //    private static final float[] tempFb = new float[3];
95 //
96 //    /** X axis of the Oriented Box. */
97 //    public final Vector3f xAxis = new Vector3f(1, 0, 0);
98 //
99 //    /** Y axis of the Oriented Box. */
100 //    public final Vector3f yAxis = new Vector3f(0, 1, 0);
101 //
102 //    /** Z axis of the Oriented Box. */
103 //    public final Vector3f zAxis = new Vector3f(0, 0, 1);
104 //
105 //    /** Extents of the box along the x,y,z axis. */
106 //    public final Vector3f extent = new Vector3f(0, 0, 0);
107 //
108 //    /** Vector array used to store the array of 8 corners the box has. */
109 //    public final Vector3f[] vectorStore = new Vector3f[8];
110 //
111 //    private final Vector3f tempVk = new Vector3f();
112 //    private final Vector3f tempForword = new Vector3f(0, 0, 1);
113 //    private final Vector3f tempLeft = new Vector3f(1, 0, 0);
114 //    private final Vector3f tempUp = new Vector3f(0, 1, 0);
115 //
116 //    static private final FloatBuffer _mergeBuf = BufferUtils
117 //            .createVector3Buffer(16);
118 //
119 //    /**
120 //     * If true, the box's vectorStore array correctly represents the box's
121 //     * corners.
122 //     */
123 //    public boolean correctCorners = false;
124 //
125 //    public OrientedBoundingBox() {
126 //        for (int x = 0; x < 8; x++)
127 //            vectorStore[x] = new Vector3f();
128 //    }
129 //
130 //    public Type getType() {
131 //        return Type.OBB;
132 //    }
133 //
134 //    public BoundingVolume transform(Quaternion rotate, Vector3f translate,
135 //            Vector3f scale, BoundingVolume store) {
136 //        rotate.toRotationMatrix(tempMa);
137 //        return transform(tempMa, translate, scale, store);
138 //    }
139 //
140 //    public BoundingVolume transform(Matrix3f rotate, Vector3f translate,
141 //            Vector3f scale, BoundingVolume store) {
142 //        if (store == null || store.getType() != Type.OBB) {
143 //            store = new OrientedBoundingBox();
144 //        }
145 //        OrientedBoundingBox toReturn = (OrientedBoundingBox) store;
146 //        toReturn.extent.set(FastMath.abs(extent.x * scale.x),
147 //                FastMath.abs(extent.y * scale.y),
148 //                FastMath.abs(extent.z * scale.z));
149 //        rotate.mult(xAxis, toReturn.xAxis);
150 //        rotate.mult(yAxis, toReturn.yAxis);
151 //        rotate.mult(zAxis, toReturn.zAxis);
152 //        center.mult(scale, toReturn.center);
153 //        rotate.mult(toReturn.center, toReturn.center);
154 //        toReturn.center.addLocal(translate);
155 //        toReturn.correctCorners = false;
156 //        return toReturn;
157 //    }
158 //
159 //    public int whichSide(Plane plane) {
160 //        float fRadius = FastMath.abs(extent.x * (plane.getNormal().dot(xAxis)))
161 //                + FastMath.abs(extent.y * (plane.getNormal().dot(yAxis)))
162 //                + FastMath.abs(extent.z * (plane.getNormal().dot(zAxis)));
163 //        float fDistance = plane.pseudoDistance(center);
164 //        if (fDistance <= -fRadius)
165 //            return Plane.NEGATIVE_SIDE;
166 //        else if (fDistance >= fRadius)
167 //            return Plane.POSITIVE_SIDE;
168 //        else
169 //           return Plane.NO_SIDE;
170 //    }
171 //
172 //    public void computeFromPoints(FloatBuffer points) {
173 //        containAABB(points);
174 //    }
175 //
176 //    /**
177 //     * Calculates an AABB of the given point values for this OBB.
178 //     *
179 //     * @param points
180 //     *            The points this OBB should contain.
181 //     */
182 //    private void containAABB(FloatBuffer points) {
183 //        if (points == null || points.limit() <= 2) { // we need at least a 3
184 //            // float vector
185 //            return;
186 //        }
187 //
188 //        BufferUtils.populateFromBuffer(_compVect1, points, 0);
189 //        float minX = _compVect1.x, minY = _compVect1.y, minZ = _compVect1.z;
190 //        float maxX = _compVect1.x, maxY = _compVect1.y, maxZ = _compVect1.z;
191 //
192 //        for (int i = 1, len = points.limit() / 3; i < len; i++) {
193 //            BufferUtils.populateFromBuffer(_compVect1, points, i);
194 //
195 //            if (_compVect1.x < minX)
196 //                minX = _compVect1.x;
197 //            else if (_compVect1.x > maxX)
198 //                maxX = _compVect1.x;
199 //
200 //            if (_compVect1.y < minY)
201 //                minY = _compVect1.y;
202 //            else if (_compVect1.y > maxY)
203 //                maxY = _compVect1.y;
204 //
205 //            if (_compVect1.z < minZ)
206 //                minZ = _compVect1.z;
207 //            else if (_compVect1.z > maxZ)
208 //                maxZ = _compVect1.z;
209 //        }
210 //
211 //        center.set(minX + maxX, minY + maxY, minZ + maxZ);
212 //        center.multLocal(0.5f);
213 //
214 //        extent.set(maxX - center.x, maxY - center.y, maxZ - center.z);
215 //
216 //        xAxis.set(1, 0, 0);
217 //        yAxis.set(0, 1, 0);
218 //        zAxis.set(0, 0, 1);
219 //
220 //        correctCorners = false;
221 //    }
222 //
223 //    public BoundingVolume merge(BoundingVolume volume) {
224 //        // clone ourselves into a new bounding volume, then merge.
225 //        return clone(new OrientedBoundingBox()).mergeLocal(volume);
226 //    }
227 //
228 //    public BoundingVolume mergeLocal(BoundingVolume volume) {
229 //        if (volume == null)
230 //            return this;
231 //
232 //        switch (volume.getType()) {
233 //
234 //            case OBB: {
235 //                return mergeOBB((OrientedBoundingBox) volume);
236 //            }
237 //
238 //            case AABB: {
239 //                return mergeAABB((BoundingBox) volume);
240 //            }
241 //
242 //            case Sphere: {
243 //                return mergeSphere((BoundingSphere) volume);
244 //            }
245 //
246 //            default:
247 //                return null;
248 //
249 //        }
250 //    }
251 //
252 //    private BoundingVolume mergeSphere(BoundingSphere volume) {
253 //        BoundingSphere mergeSphere = volume;
254 //        if (!correctCorners)
255 //            this.computeCorners();
256 //
257 //        _mergeBuf.rewind();
258 //        for (int i = 0; i < 8; i++) {
259 //            _mergeBuf.put(vectorStore[i].x);
260 //            _mergeBuf.put(vectorStore[i].y);
261 //            _mergeBuf.put(vectorStore[i].z);
262 //        }
263 //        _mergeBuf.put(mergeSphere.center.x + mergeSphere.radius).put(
264 //                mergeSphere.center.y + mergeSphere.radius).put(
265 //                mergeSphere.center.z + mergeSphere.radius);
266 //        _mergeBuf.put(mergeSphere.center.x - mergeSphere.radius).put(
267 //                mergeSphere.center.y + mergeSphere.radius).put(
268 //                mergeSphere.center.z + mergeSphere.radius);
269 //        _mergeBuf.put(mergeSphere.center.x + mergeSphere.radius).put(
270 //                mergeSphere.center.y - mergeSphere.radius).put(
271 //                mergeSphere.center.z + mergeSphere.radius);
272 //        _mergeBuf.put(mergeSphere.center.x + mergeSphere.radius).put(
273 //                mergeSphere.center.y + mergeSphere.radius).put(
274 //                mergeSphere.center.z - mergeSphere.radius);
275 //        _mergeBuf.put(mergeSphere.center.x - mergeSphere.radius).put(
276 //                mergeSphere.center.y - mergeSphere.radius).put(
277 //                mergeSphere.center.z + mergeSphere.radius);
278 //        _mergeBuf.put(mergeSphere.center.x - mergeSphere.radius).put(
279 //                mergeSphere.center.y + mergeSphere.radius).put(
280 //                mergeSphere.center.z - mergeSphere.radius);
281 //        _mergeBuf.put(mergeSphere.center.x + mergeSphere.radius).put(
282 //                mergeSphere.center.y - mergeSphere.radius).put(
283 //                mergeSphere.center.z - mergeSphere.radius);
284 //        _mergeBuf.put(mergeSphere.center.x - mergeSphere.radius).put(
285 //                mergeSphere.center.y - mergeSphere.radius).put(
286 //                mergeSphere.center.z - mergeSphere.radius);
287 //        containAABB(_mergeBuf);
288 //        correctCorners = false;
289 //        return this;
290 //    }
291 //
292 //    private BoundingVolume mergeAABB(BoundingBox volume) {
293 //        BoundingBox mergeBox = volume;
294 //        if (!correctCorners)
295 //            this.computeCorners();
296 //
297 //        _mergeBuf.rewind();
298 //        for (int i = 0; i < 8; i++) {
299 //            _mergeBuf.put(vectorStore[i].x);
300 //            _mergeBuf.put(vectorStore[i].y);
301 //            _mergeBuf.put(vectorStore[i].z);
302 //        }
303 //        _mergeBuf.put(mergeBox.center.x + mergeBox.xExtent).put(
304 //                mergeBox.center.y + mergeBox.yExtent).put(
305 //                mergeBox.center.z + mergeBox.zExtent);
306 //        _mergeBuf.put(mergeBox.center.x - mergeBox.xExtent).put(
307 //                mergeBox.center.y + mergeBox.yExtent).put(
308 //                mergeBox.center.z + mergeBox.zExtent);
309 //        _mergeBuf.put(mergeBox.center.x + mergeBox.xExtent).put(
310 //                mergeBox.center.y - mergeBox.yExtent).put(
311 //                mergeBox.center.z + mergeBox.zExtent);
312 //        _mergeBuf.put(mergeBox.center.x + mergeBox.xExtent).put(
313 //                mergeBox.center.y + mergeBox.yExtent).put(
314 //                mergeBox.center.z - mergeBox.zExtent);
315 //        _mergeBuf.put(mergeBox.center.x - mergeBox.xExtent).put(
316 //                mergeBox.center.y - mergeBox.yExtent).put(
317 //                mergeBox.center.z + mergeBox.zExtent);
318 //        _mergeBuf.put(mergeBox.center.x - mergeBox.xExtent).put(
319 //                mergeBox.center.y + mergeBox.yExtent).put(
320 //                mergeBox.center.z - mergeBox.zExtent);
321 //        _mergeBuf.put(mergeBox.center.x + mergeBox.xExtent).put(
322 //                mergeBox.center.y - mergeBox.yExtent).put(
323 //                mergeBox.center.z - mergeBox.zExtent);
324 //        _mergeBuf.put(mergeBox.center.x - mergeBox.xExtent).put(
325 //                mergeBox.center.y - mergeBox.yExtent).put(
326 //                mergeBox.center.z - mergeBox.zExtent);
327 //        containAABB(_mergeBuf);
328 //        correctCorners = false;
329 //        return this;
330 //    }
331 //
332 //    private BoundingVolume mergeOBB(OrientedBoundingBox volume) {
333 //        // OrientedBoundingBox mergeBox=(OrientedBoundingBox) volume;
334 //        // if (!correctCorners) this.computeCorners();
335 //        // if (!mergeBox.correctCorners) mergeBox.computeCorners();
336 //        // Vector3f[] mergeArray=new Vector3f[16];
337 //        // for (int i=0;i<vectorStore.length;i++){
338 //        // mergeArray[i*2+0]=this .vectorStore[i];
339 //        // mergeArray[i*2+1]=mergeBox.vectorStore[i];
340 //        // }
341 //        // containAABB(mergeArray);
342 //        // correctCorners=false;
343 //        // return this;
344 //        // construct a box that contains the input boxes
345 //        // Box3<Real> kBox;
346 //        OrientedBoundingBox rkBox0 = this;
347 //        OrientedBoundingBox rkBox1 = volume;
348 //
349 //        // The first guess at the box center. This value will be updated later
350 //        // after the input box vertices are projected onto axes determined by an
351 //        // average of box axes.
352 //        Vector3f kBoxCenter = (rkBox0.center.add(rkBox1.center, _compVect7))
353 //                .multLocal(.5f);
354 //
355 //        // A box's axes, when viewed as the columns of a matrix, form a rotation
356 //        // matrix. The input box axes are converted to quaternions. The average
357 //        // quaternion is computed, then normalized to unit length. The result is
358 //        // the slerp of the two input quaternions with t-value of 1/2. The
359 //        // result is converted back to a rotation matrix and its columns are
360 //        // selected as the merged box axes.
361 //        Quaternion kQ0 = tempQa, kQ1 = tempQb;
362 //        kQ0.fromAxes(rkBox0.xAxis, rkBox0.yAxis, rkBox0.zAxis);
363 //        kQ1.fromAxes(rkBox1.xAxis, rkBox1.yAxis, rkBox1.zAxis);
364 //
365 //        if (kQ0.dot(kQ1) < 0.0f)
366 //            kQ1.negate();
367 //
368 //        Quaternion kQ = kQ0.addLocal(kQ1);
369 //        kQ.normalize();
370 //
371 //        Matrix3f kBoxaxis = kQ.toRotationMatrix(tempMa);
372 //        Vector3f newXaxis = kBoxaxis.getColumn(0, _compVect8);
373 //        Vector3f newYaxis = kBoxaxis.getColumn(1, _compVect9);
374 //        Vector3f newZaxis = kBoxaxis.getColumn(2, _compVect10);
375 //
376 //        // Project the input box vertices onto the merged-box axes. Each axis
377 //        // D[i] containing the current center C has a minimum projected value
378 //        // pmin[i] and a maximum projected value pmax[i]. The corresponding end
379 //        // points on the axes are C+pmin[i]*D[i] and C+pmax[i]*D[i]. The point C
380 //        // is not necessarily the midpoint for any of the intervals. The actual
381 //        // box center will be adjusted from C to a point C' that is the midpoint
382 //        // of each interval,
383 //        // C' = C + sum_{i=0}^1 0.5*(pmin[i]+pmax[i])*D[i]
384 //        // The box extents are
385 //        // e[i] = 0.5*(pmax[i]-pmin[i])
386 //
387 //        int i;
388 //        float fDot;
389 //        Vector3f kDiff = _compVect4;
390 //        Vector3f kMin = _compVect5;
391 //        Vector3f kMax = _compVect6;
392 //        kMin.zero();
393 //        kMax.zero();
394 //
395 //        if (!rkBox0.correctCorners)
396 //            rkBox0.computeCorners();
397 //        for (i = 0; i < 8; i++) {
398 //            rkBox0.vectorStore[i].subtract(kBoxCenter, kDiff);
399 //
400 //            fDot = kDiff.dot(newXaxis);
401 //            if (fDot > kMax.x)
402 //                kMax.x = fDot;
403 //            else if (fDot < kMin.x)
404 //                kMin.x = fDot;
405 //
406 //            fDot = kDiff.dot(newYaxis);
407 //            if (fDot > kMax.y)
408 //                kMax.y = fDot;
409 //            else if (fDot < kMin.y)
410 //                kMin.y = fDot;
411 //
412 //            fDot = kDiff.dot(newZaxis);
413 //            if (fDot > kMax.z)
414 //                kMax.z = fDot;
415 //            else if (fDot < kMin.z)
416 //                kMin.z = fDot;
417 //
418 //        }
419 //
420 //        if (!rkBox1.correctCorners)
421 //            rkBox1.computeCorners();
422 //        for (i = 0; i < 8; i++) {
423 //            rkBox1.vectorStore[i].subtract(kBoxCenter, kDiff);
424 //
425 //            fDot = kDiff.dot(newXaxis);
426 //            if (fDot > kMax.x)
427 //                kMax.x = fDot;
428 //            else if (fDot < kMin.x)
429 //                kMin.x = fDot;
430 //
431 //            fDot = kDiff.dot(newYaxis);
432 //            if (fDot > kMax.y)
433 //                kMax.y = fDot;
434 //            else if (fDot < kMin.y)
435 //                kMin.y = fDot;
436 //
437 //            fDot = kDiff.dot(newZaxis);
438 //            if (fDot > kMax.z)
439 //                kMax.z = fDot;
440 //            else if (fDot < kMin.z)
441 //                kMin.z = fDot;
442 //        }
443 //
444 //        this.xAxis.set(newXaxis);
445 //        this.yAxis.set(newYaxis);
446 //        this.zAxis.set(newZaxis);
447 //
448 //        this.extent.x = .5f * (kMax.x - kMin.x);
449 //        kBoxCenter.addLocal(this.xAxis.mult(.5f * (kMax.x + kMin.x), tempVe));
450 //
451 //        this.extent.y = .5f * (kMax.y - kMin.y);
452 //        kBoxCenter.addLocal(this.yAxis.mult(.5f * (kMax.y + kMin.y), tempVe));
453 //
454 //        this.extent.z = .5f * (kMax.z - kMin.z);
455 //        kBoxCenter.addLocal(this.zAxis.mult(.5f * (kMax.z + kMin.z), tempVe));
456 //
457 //        this.center.set(kBoxCenter);
458 //
459 //        this.correctCorners = false;
460 //        return this;
461 //    }
462 //
463 //    public BoundingVolume clone(BoundingVolume store) {
464 //        OrientedBoundingBox toReturn;
465 //        if (store instanceof OrientedBoundingBox) {
466 //            toReturn = (OrientedBoundingBox) store;
467 //        } else {
468 //            toReturn = new OrientedBoundingBox();
469 //        }
470 //        toReturn.extent.set(extent);
471 //        toReturn.xAxis.set(xAxis);
472 //        toReturn.yAxis.set(yAxis);
473 //        toReturn.zAxis.set(zAxis);
474 //        toReturn.center.set(center);
475 //        toReturn.checkPlane = checkPlane;
476 //        for (int x = vectorStore.length; --x >= 0; )
477 //            toReturn.vectorStore[x].set(vectorStore[x]);
478 //        toReturn.correctCorners = this.correctCorners;
479 //        return toReturn;
480 //    }
481 //
482 //    /**
483 //     * Sets the vectorStore information to the 8 corners of the box.
484 //     */
485 //    public void computeCorners() {
486 //        Vector3f akEAxis0 = xAxis.mult(extent.x, _compVect1);
487 //        Vector3f akEAxis1 = yAxis.mult(extent.y, _compVect2);
488 //        Vector3f akEAxis2 = zAxis.mult(extent.z, _compVect3);
489 //
490 //        vectorStore[0].set(center).subtractLocal(akEAxis0).subtractLocal(akEAxis1).subtractLocal(akEAxis2);
491 //        vectorStore[1].set(center).addLocal(akEAxis0).subtractLocal(akEAxis1).subtractLocal(akEAxis2);
492 //        vectorStore[2].set(center).addLocal(akEAxis0).addLocal(akEAxis1).subtractLocal(akEAxis2);
493 //        vectorStore[3].set(center).subtractLocal(akEAxis0).addLocal(akEAxis1).subtractLocal(akEAxis2);
494 //        vectorStore[4].set(center).subtractLocal(akEAxis0).subtractLocal(akEAxis1).addLocal(akEAxis2);
495 //        vectorStore[5].set(center).addLocal(akEAxis0).subtractLocal(akEAxis1).addLocal(akEAxis2);
496 //        vectorStore[6].set(center).addLocal(akEAxis0).addLocal(akEAxis1).addLocal(akEAxis2);
497 //        vectorStore[7].set(center).subtractLocal(akEAxis0).addLocal(akEAxis1).addLocal(akEAxis2);
498 //        correctCorners = true;
499 //    }
500 //
501 ////    public void computeFromTris(int[] indices, TriMesh mesh, int start, int end) {
502 ////        if (end - start <= 0) {
503 ////            return;
504 ////        }
505 ////        Vector3f[] verts = new Vector3f[3];
506 ////        Vector3f min = _compVect1.set(new Vector3f(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY));
507 ////        Vector3f max = _compVect2.set(new Vector3f(Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY));
508 ////        Vector3f point;
509 ////        for (int i = start; i < end; i++) {
510 ////        	mesh.getTriangle(indices[i], verts);
511 ////            point = verts[0];
512 ////            if (point.x < min.x)
513 ////                min.x = point.x;
514 ////            else if (point.x > max.x)
515 ////                max.x = point.x;
516 ////            if (point.y < min.y)
517 ////                min.y = point.y;
518 ////            else if (point.y > max.y)
519 ////                max.y = point.y;
520 ////            if (point.z < min.z)
521 ////                min.z = point.z;
522 ////            else if (point.z > max.z)
523 ////                max.z = point.z;
524 ////
525 ////            point = verts[1];
526 ////            if (point.x < min.x)
527 ////                min.x = point.x;
528 ////            else if (point.x > max.x)
529 ////                max.x = point.x;
530 ////            if (point.y < min.y)
531 ////                min.y = point.y;
532 ////            else if (point.y > max.y)
533 ////                max.y = point.y;
534 ////            if (point.z < min.z)
535 ////                min.z = point.z;
536 ////            else if (point.z > max.z)
537 ////                max.z = point.z;
538 ////
539 ////            point = verts[2];
540 ////            if (point.x < min.x)
541 ////                min.x = point.x;
542 ////            else if (point.x > max.x)
543 ////                max.x = point.x;
544 ////
545 ////            if (point.y < min.y)
546 ////                min.y = point.y;
547 ////            else if (point.y > max.y)
548 ////                max.y = point.y;
549 ////
550 ////            if (point.z < min.z)
551 ////                min.z = point.z;
552 ////            else if (point.z > max.z)
553 ////                max.z = point.z;
554 ////        }
555 ////
556 ////        center.set(min.addLocal(max));
557 ////        center.multLocal(0.5f);
558 ////
559 ////        extent.set(max.x - center.x, max.y - center.y, max.z - center.z);
560 ////
561 ////        xAxis.set(1, 0, 0);
562 ////        yAxis.set(0, 1, 0);
563 ////        zAxis.set(0, 0, 1);
564 ////
565 ////        correctCorners = false;
566 ////    }
567 //
568 //    public void computeFromTris(Triangle[] tris, int start, int end) {
569 //        if (end - start <= 0) {
570 //            return;
571 //        }
572 //
573 //        Vector3f min = _compVect1.set(tris[start].get(0));
574 //        Vector3f max = _compVect2.set(min);
575 //        Vector3f point;
576 //        for (int i = start; i < end; i++) {
577 //
578 //            point = tris[i].get(0);
579 //            if (point.x < min.x)
580 //                min.x = point.x;
581 //            else if (point.x > max.x)
582 //                max.x = point.x;
583 //            if (point.y < min.y)
584 //                min.y = point.y;
585 //            else if (point.y > max.y)
586 //                max.y = point.y;
587 //            if (point.z < min.z)
588 //                min.z = point.z;
589 //            else if (point.z > max.z)
590 //                max.z = point.z;
591 //
592 //            point = tris[i].get(1);
593 //            if (point.x < min.x)
594 //                min.x = point.x;
595 //            else if (point.x > max.x)
596 //                max.x = point.x;
597 //            if (point.y < min.y)
598 //                min.y = point.y;
599 //            else if (point.y > max.y)
600 //                max.y = point.y;
601 //            if (point.z < min.z)
602 //                min.z = point.z;
603 //            else if (point.z > max.z)
604 //                max.z = point.z;
605 //
606 //            point = tris[i].get(2);
607 //            if (point.x < min.x)
608 //                min.x = point.x;
609 //            else if (point.x > max.x)
610 //                max.x = point.x;
611 //
612 //            if (point.y < min.y)
613 //                min.y = point.y;
614 //            else if (point.y > max.y)
615 //                max.y = point.y;
616 //
617 //            if (point.z < min.z)
618 //                min.z = point.z;
619 //            else if (point.z > max.z)
620 //                max.z = point.z;
621 //        }
622 //
623 //        center.set(min.addLocal(max));
624 //        center.multLocal(0.5f);
625 //
626 //        extent.set(max.x - center.x, max.y - center.y, max.z - center.z);
627 //
628 //        xAxis.set(1, 0, 0);
629 //        yAxis.set(0, 1, 0);
630 //        zAxis.set(0, 0, 1);
631 //
632 //        correctCorners = false;
633 //    }
634 //
635 //    public boolean intersection(OrientedBoundingBox box1) {
636 //        // Cutoff for cosine of angles between box axes. This is used to catch
637 //        // the cases when at least one pair of axes are parallel. If this
638 //        // happens,
639 //        // there is no need to test for separation along the Cross(A[i],B[j])
640 //        // directions.
641 //        OrientedBoundingBox box0 = this;
642 //        float cutoff = 0.999999f;
643 //        boolean parallelPairExists = false;
644 //        int i;
645 //
646 //        // convenience variables
647 //        Vector3f akA[] = new Vector3f[] { box0.xAxis, box0.yAxis, box0.zAxis };
648 //        Vector3f[] akB = new Vector3f[] { box1.xAxis, box1.yAxis, box1.zAxis };
649 //        Vector3f afEA = box0.extent;
650 //        Vector3f afEB = box1.extent;
651 //
652 //        // compute difference of box centers, D = C1-C0
653 //        Vector3f kD = box1.center.subtract(box0.center, _compVect1);
654 //
655 //        float[][] aafC = { fWdU, fAWdU, fDdU };
656 //
657 //        float[][] aafAbsC = { fADdU, fAWxDdU, tempFa };
658 //
659 //        float[] afAD = tempFb;
660 //        float fR0, fR1, fR; // interval radii and distance between centers
661 //        float fR01; // = R0 + R1
662 //
663 //        // axis C0+t*A0
664 //        for (i = 0; i < 3; i++) {
665 //            aafC[0][i] = akA[0].dot(akB[i]);
666 //            aafAbsC[0][i] = FastMath.abs(aafC[0][i]);
667 //            if (aafAbsC[0][i] > cutoff) {
668 //                parallelPairExists = true;
669 //            }
670 //        }
671 //        afAD[0] = akA[0].dot(kD);
672 //        fR = FastMath.abs(afAD[0]);
673 //        fR1 = afEB.x * aafAbsC[0][0] + afEB.y * aafAbsC[0][1] + afEB.z
674 //                * aafAbsC[0][2];
675 //        fR01 = afEA.x + fR1;
676 //        if (fR > fR01) {
677 //            return false;
678 //        }
679 //
680 //        // axis C0+t*A1
681 //        for (i = 0; i < 3; i++) {
682 //            aafC[1][i] = akA[1].dot(akB[i]);
683 //            aafAbsC[1][i] = FastMath.abs(aafC[1][i]);
684 //            if (aafAbsC[1][i] > cutoff) {
685 //                parallelPairExists = true;
686 //            }
687 //        }
688 //        afAD[1] = akA[1].dot(kD);
689 //        fR = FastMath.abs(afAD[1]);
690 //        fR1 = afEB.x * aafAbsC[1][0] + afEB.y * aafAbsC[1][1] + afEB.z
691 //                * aafAbsC[1][2];
692 //        fR01 = afEA.y + fR1;
693 //        if (fR > fR01) {
694 //            return false;
695 //        }
696 //
697 //        // axis C0+t*A2
698 //        for (i = 0; i < 3; i++) {
699 //            aafC[2][i] = akA[2].dot(akB[i]);
700 //            aafAbsC[2][i] = FastMath.abs(aafC[2][i]);
701 //            if (aafAbsC[2][i] > cutoff) {
702 //                parallelPairExists = true;
703 //            }
704 //        }
705 //        afAD[2] = akA[2].dot(kD);
706 //        fR = FastMath.abs(afAD[2]);
707 //        fR1 = afEB.x * aafAbsC[2][0] + afEB.y * aafAbsC[2][1] + afEB.z
708 //                * aafAbsC[2][2];
709 //        fR01 = afEA.z + fR1;
710 //        if (fR > fR01) {
711 //            return false;
712 //        }
713 //
714 //        // axis C0+t*B0
715 //        fR = FastMath.abs(akB[0].dot(kD));
716 //        fR0 = afEA.x * aafAbsC[0][0] + afEA.y * aafAbsC[1][0] + afEA.z
717 //                * aafAbsC[2][0];
718 //        fR01 = fR0 + afEB.x;
719 //        if (fR > fR01) {
720 //            return false;
721 //        }
722 //
723 //        // axis C0+t*B1
724 //        fR = FastMath.abs(akB[1].dot(kD));
725 //        fR0 = afEA.x * aafAbsC[0][1] + afEA.y * aafAbsC[1][1] + afEA.z
726 //                * aafAbsC[2][1];
727 //        fR01 = fR0 + afEB.y;
728 //        if (fR > fR01) {
729 //            return false;
730 //        }
731 //
732 //        // axis C0+t*B2
733 //        fR = FastMath.abs(akB[2].dot(kD));
734 //        fR0 = afEA.x * aafAbsC[0][2] + afEA.y * aafAbsC[1][2] + afEA.z
735 //                * aafAbsC[2][2];
736 //        fR01 = fR0 + afEB.z;
737 //        if (fR > fR01) {
738 //            return false;
739 //        }
740 //
741 //        // At least one pair of box axes was parallel, so the separation is
742 //        // effectively in 2D where checking the "edge" normals is sufficient for
743 //        // the separation of the boxes.
744 //        if (parallelPairExists) {
745 //            return true;
746 //        }
747 //
748 //        // axis C0+t*A0xB0
749 //        fR = FastMath.abs(afAD[2] * aafC[1][0] - afAD[1] * aafC[2][0]);
750 //        fR0 = afEA.y * aafAbsC[2][0] + afEA.z * aafAbsC[1][0];
751 //        fR1 = afEB.y * aafAbsC[0][2] + afEB.z * aafAbsC[0][1];
752 //        fR01 = fR0 + fR1;
753 //        if (fR > fR01) {
754 //            return false;
755 //        }
756 //
757 //        // axis C0+t*A0xB1
758 //        fR = FastMath.abs(afAD[2] * aafC[1][1] - afAD[1] * aafC[2][1]);
759 //        fR0 = afEA.y * aafAbsC[2][1] + afEA.z * aafAbsC[1][1];
760 //        fR1 = afEB.x * aafAbsC[0][2] + afEB.z * aafAbsC[0][0];
761 //        fR01 = fR0 + fR1;
762 //        if (fR > fR01) {
763 //            return false;
764 //        }
765 //
766 //        // axis C0+t*A0xB2
767 //        fR = FastMath.abs(afAD[2] * aafC[1][2] - afAD[1] * aafC[2][2]);
768 //        fR0 = afEA.y * aafAbsC[2][2] + afEA.z * aafAbsC[1][2];
769 //        fR1 = afEB.x * aafAbsC[0][1] + afEB.y * aafAbsC[0][0];
770 //        fR01 = fR0 + fR1;
771 //        if (fR > fR01) {
772 //            return false;
773 //        }
774 //
775 //        // axis C0+t*A1xB0
776 //        fR = FastMath.abs(afAD[0] * aafC[2][0] - afAD[2] * aafC[0][0]);
777 //        fR0 = afEA.x * aafAbsC[2][0] + afEA.z * aafAbsC[0][0];
778 //        fR1 = afEB.y * aafAbsC[1][2] + afEB.z * aafAbsC[1][1];
779 //        fR01 = fR0 + fR1;
780 //        if (fR > fR01) {
781 //            return false;
782 //        }
783 //
784 //        // axis C0+t*A1xB1
785 //        fR = FastMath.abs(afAD[0] * aafC[2][1] - afAD[2] * aafC[0][1]);
786 //        fR0 = afEA.x * aafAbsC[2][1] + afEA.z * aafAbsC[0][1];
787 //        fR1 = afEB.x * aafAbsC[1][2] + afEB.z * aafAbsC[1][0];
788 //        fR01 = fR0 + fR1;
789 //        if (fR > fR01) {
790 //            return false;
791 //        }
792 //
793 //        // axis C0+t*A1xB2
794 //        fR = FastMath.abs(afAD[0] * aafC[2][2] - afAD[2] * aafC[0][2]);
795 //        fR0 = afEA.x * aafAbsC[2][2] + afEA.z * aafAbsC[0][2];
796 //        fR1 = afEB.x * aafAbsC[1][1] + afEB.y * aafAbsC[1][0];
797 //        fR01 = fR0 + fR1;
798 //        if (fR > fR01) {
799 //            return false;
800 //        }
801 //
802 //        // axis C0+t*A2xB0
803 //        fR = FastMath.abs(afAD[1] * aafC[0][0] - afAD[0] * aafC[1][0]);
804 //        fR0 = afEA.x * aafAbsC[1][0] + afEA.y * aafAbsC[0][0];
805 //        fR1 = afEB.y * aafAbsC[2][2] + afEB.z * aafAbsC[2][1];
806 //        fR01 = fR0 + fR1;
807 //        if (fR > fR01) {
808 //            return false;
809 //        }
810 //
811 //        // axis C0+t*A2xB1
812 //        fR = FastMath.abs(afAD[1] * aafC[0][1] - afAD[0] * aafC[1][1]);
813 //        fR0 = afEA.x * aafAbsC[1][1] + afEA.y * aafAbsC[0][1];
814 //        fR1 = afEB.x * aafAbsC[2][2] + afEB.z * aafAbsC[2][0];
815 //        fR01 = fR0 + fR1;
816 //        if (fR > fR01) {
817 //            return false;
818 //        }
819 //
820 //        // axis C0+t*A2xB2
821 //        fR = FastMath.abs(afAD[1] * aafC[0][2] - afAD[0] * aafC[1][2]);
822 //        fR0 = afEA.x * aafAbsC[1][2] + afEA.y * aafAbsC[0][2];
823 //        fR1 = afEB.x * aafAbsC[2][1] + afEB.y * aafAbsC[2][0];
824 //        fR01 = fR0 + fR1;
825 //        if (fR > fR01) {
826 //            return false;
827 //        }
828 //
829 //        return true;
830 //    }
831 //
832 //    /*
833 //     * (non-Javadoc)
834 //     *
835 //     * @see com.jme.bounding.BoundingVolume#intersects(com.jme.bounding.BoundingVolume)
836 //     */
837 //    public boolean intersects(BoundingVolume bv) {
838 //        if (bv == null)
839 //            return false;
840 //
841 //        return bv.intersectsOrientedBoundingBox(this);
842 //    }
843 //
844 //    /*
845 //     * (non-Javadoc)
846 //     *
847 //     * @see com.jme.bounding.BoundingVolume#intersectsSphere(com.jme.bounding.BoundingSphere)
848 //     */
849 //    public boolean intersectsSphere(BoundingSphere bs) {
850 //        if (!Vector3f.isValidVector(center) || !Vector3f.isValidVector(bs.center)) return false;
851 //
852 //        _compVect1.set(bs.getCenter()).subtractLocal(center);
853 //        tempMa.fromAxes(xAxis, yAxis, zAxis);
854 //
855 //        tempMa.mult(_compVect1, _compVect2);
856 //
857 //        if (FastMath.abs(_compVect2.x) < bs.getRadius() + extent.x
858 //                && FastMath.abs(_compVect2.y) < bs.getRadius() + extent.y
859 //                && FastMath.abs(_compVect2.z) < bs.getRadius() + extent.z)
860 //            return true;
861 //
862 //        return false;
863 //    }
864 //
865 //    /*
866 //     * (non-Javadoc)
867 //     *
868 //     * @see com.jme.bounding.BoundingVolume#intersectsBoundingBox(com.jme.bounding.BoundingBox)
869 //     */
870 //    public boolean intersectsBoundingBox(BoundingBox bb) {
871 //        if (!Vector3f.isValidVector(center) || !Vector3f.isValidVector(bb.center)) return false;
872 //
873 //        // Cutoff for cosine of angles between box axes. This is used to catch
874 //        // the cases when at least one pair of axes are parallel. If this
875 //        // happens,
876 //        // there is no need to test for separation along the Cross(A[i],B[j])
877 //        // directions.
878 //        float cutoff = 0.999999f;
879 //        boolean parallelPairExists = false;
880 //        int i;
881 //
882 //        // convenience variables
883 //        Vector3f akA[] = new Vector3f[] { xAxis, yAxis, zAxis };
884 //        Vector3f[] akB = new Vector3f[] { tempForword, tempLeft, tempUp };
885 //        Vector3f afEA = extent;
886 //        Vector3f afEB = tempVk.set(bb.xExtent, bb.yExtent, bb.zExtent);
887 //
888 //        // compute difference of box centers, D = C1-C0
889 //        Vector3f kD = bb.getCenter().subtract(center, _compVect1);
890 //
891 //        float[][] aafC = { fWdU, fAWdU, fDdU };
892 //
893 //        float[][] aafAbsC = { fADdU, fAWxDdU, tempFa };
894 //
895 //        float[] afAD = tempFb;
896 //        float fR0, fR1, fR; // interval radii and distance between centers
897 //        float fR01; // = R0 + R1
898 //
899 //        // axis C0+t*A0
900 //        for (i = 0; i < 3; i++) {
901 //            aafC[0][i] = akA[0].dot(akB[i]);
902 //            aafAbsC[0][i] = FastMath.abs(aafC[0][i]);
903 //            if (aafAbsC[0][i] > cutoff) {
904 //                parallelPairExists = true;
905 //            }
906 //        }
907 //        afAD[0] = akA[0].dot(kD);
908 //        fR = FastMath.abs(afAD[0]);
909 //        fR1 = afEB.x * aafAbsC[0][0] + afEB.y * aafAbsC[0][1] + afEB.z
910 //                * aafAbsC[0][2];
911 //        fR01 = afEA.x + fR1;
912 //        if (fR > fR01) {
913 //            return false;
914 //        }
915 //
916 //        // axis C0+t*A1
917 //        for (i = 0; i < 3; i++) {
918 //            aafC[1][i] = akA[1].dot(akB[i]);
919 //            aafAbsC[1][i] = FastMath.abs(aafC[1][i]);
920 //            if (aafAbsC[1][i] > cutoff) {
921 //                parallelPairExists = true;
922 //            }
923 //        }
924 //        afAD[1] = akA[1].dot(kD);
925 //        fR = FastMath.abs(afAD[1]);
926 //        fR1 = afEB.x * aafAbsC[1][0] + afEB.y * aafAbsC[1][1] + afEB.z
927 //                * aafAbsC[1][2];
928 //        fR01 = afEA.y + fR1;
929 //        if (fR > fR01) {
930 //            return false;
931 //        }
932 //
933 //        // axis C0+t*A2
934 //        for (i = 0; i < 3; i++) {
935 //            aafC[2][i] = akA[2].dot(akB[i]);
936 //            aafAbsC[2][i] = FastMath.abs(aafC[2][i]);
937 //            if (aafAbsC[2][i] > cutoff) {
938 //                parallelPairExists = true;
939 //            }
940 //        }
941 //        afAD[2] = akA[2].dot(kD);
942 //        fR = FastMath.abs(afAD[2]);
943 //        fR1 = afEB.x * aafAbsC[2][0] + afEB.y * aafAbsC[2][1] + afEB.z
944 //                * aafAbsC[2][2];
945 //        fR01 = afEA.z + fR1;
946 //        if (fR > fR01) {
947 //            return false;
948 //        }
949 //
950 //        // axis C0+t*B0
951 //        fR = FastMath.abs(akB[0].dot(kD));
952 //        fR0 = afEA.x * aafAbsC[0][0] + afEA.y * aafAbsC[1][0] + afEA.z
953 //                * aafAbsC[2][0];
954 //        fR01 = fR0 + afEB.x;
955 //        if (fR > fR01) {
956 //            return false;
957 //        }
958 //
959 //        // axis C0+t*B1
960 //        fR = FastMath.abs(akB[1].dot(kD));
961 //        fR0 = afEA.x * aafAbsC[0][1] + afEA.y * aafAbsC[1][1] + afEA.z
962 //                * aafAbsC[2][1];
963 //        fR01 = fR0 + afEB.y;
964 //        if (fR > fR01) {
965 //            return false;
966 //        }
967 //
968 //        // axis C0+t*B2
969 //        fR = FastMath.abs(akB[2].dot(kD));
970 //        fR0 = afEA.x * aafAbsC[0][2] + afEA.y * aafAbsC[1][2] + afEA.z
971 //                * aafAbsC[2][2];
972 //        fR01 = fR0 + afEB.z;
973 //        if (fR > fR01) {
974 //            return false;
975 //        }
976 //
977 //        // At least one pair of box axes was parallel, so the separation is
978 //        // effectively in 2D where checking the "edge" normals is sufficient for
979 //        // the separation of the boxes.
980 //        if (parallelPairExists) {
981 //            return true;
982 //        }
983 //
984 //        // axis C0+t*A0xB0
985 //        fR = FastMath.abs(afAD[2] * aafC[1][0] - afAD[1] * aafC[2][0]);
986 //        fR0 = afEA.y * aafAbsC[2][0] + afEA.z * aafAbsC[1][0];
987 //        fR1 = afEB.y * aafAbsC[0][2] + afEB.z * aafAbsC[0][1];
988 //        fR01 = fR0 + fR1;
989 //        if (fR > fR01) {
990 //            return false;
991 //        }
992 //
993 //        // axis C0+t*A0xB1
994 //        fR = FastMath.abs(afAD[2] * aafC[1][1] - afAD[1] * aafC[2][1]);
995 //        fR0 = afEA.y * aafAbsC[2][1] + afEA.z * aafAbsC[1][1];
996 //        fR1 = afEB.x * aafAbsC[0][2] + afEB.z * aafAbsC[0][0];
997 //        fR01 = fR0 + fR1;
998 //        if (fR > fR01) {
999 //            return false;
1000 //        }
1001 //
1002 //        // axis C0+t*A0xB2
1003 //        fR = FastMath.abs(afAD[2] * aafC[1][2] - afAD[1] * aafC[2][2]);
1004 //        fR0 = afEA.y * aafAbsC[2][2] + afEA.z * aafAbsC[1][2];
1005 //        fR1 = afEB.x * aafAbsC[0][1] + afEB.y * aafAbsC[0][0];
1006 //        fR01 = fR0 + fR1;
1007 //        if (fR > fR01) {
1008 //            return false;
1009 //        }
1010 //
1011 //        // axis C0+t*A1xB0
1012 //        fR = FastMath.abs(afAD[0] * aafC[2][0] - afAD[2] * aafC[0][0]);
1013 //        fR0 = afEA.x * aafAbsC[2][0] + afEA.z * aafAbsC[0][0];
1014 //        fR1 = afEB.y * aafAbsC[1][2] + afEB.z * aafAbsC[1][1];
1015 //        fR01 = fR0 + fR1;
1016 //        if (fR > fR01) {
1017 //            return false;
1018 //        }
1019 //
1020 //        // axis C0+t*A1xB1
1021 //        fR = FastMath.abs(afAD[0] * aafC[2][1] - afAD[2] * aafC[0][1]);
1022 //        fR0 = afEA.x * aafAbsC[2][1] + afEA.z * aafAbsC[0][1];
1023 //        fR1 = afEB.x * aafAbsC[1][2] + afEB.z * aafAbsC[1][0];
1024 //        fR01 = fR0 + fR1;
1025 //        if (fR > fR01) {
1026 //            return false;
1027 //        }
1028 //
1029 //        // axis C0+t*A1xB2
1030 //        fR = FastMath.abs(afAD[0] * aafC[2][2] - afAD[2] * aafC[0][2]);
1031 //        fR0 = afEA.x * aafAbsC[2][2] + afEA.z * aafAbsC[0][2];
1032 //        fR1 = afEB.x * aafAbsC[1][1] + afEB.y * aafAbsC[1][0];
1033 //        fR01 = fR0 + fR1;
1034 //        if (fR > fR01) {
1035 //            return false;
1036 //        }
1037 //
1038 //        // axis C0+t*A2xB0
1039 //        fR = FastMath.abs(afAD[1] * aafC[0][0] - afAD[0] * aafC[1][0]);
1040 //        fR0 = afEA.x * aafAbsC[1][0] + afEA.y * aafAbsC[0][0];
1041 //        fR1 = afEB.y * aafAbsC[2][2] + afEB.z * aafAbsC[2][1];
1042 //        fR01 = fR0 + fR1;
1043 //        if (fR > fR01) {
1044 //            return false;
1045 //        }
1046 //
1047 //        // axis C0+t*A2xB1
1048 //        fR = FastMath.abs(afAD[1] * aafC[0][1] - afAD[0] * aafC[1][1]);
1049 //        fR0 = afEA.x * aafAbsC[1][1] + afEA.y * aafAbsC[0][1];
1050 //        fR1 = afEB.x * aafAbsC[2][2] + afEB.z * aafAbsC[2][0];
1051 //        fR01 = fR0 + fR1;
1052 //        if (fR > fR01) {
1053 //            return false;
1054 //        }
1055 //
1056 //        // axis C0+t*A2xB2
1057 //        fR = FastMath.abs(afAD[1] * aafC[0][2] - afAD[0] * aafC[1][2]);
1058 //        fR0 = afEA.x * aafAbsC[1][2] + afEA.y * aafAbsC[0][2];
1059 //        fR1 = afEB.x * aafAbsC[2][1] + afEB.y * aafAbsC[2][0];
1060 //        fR01 = fR0 + fR1;
1061 //        if (fR > fR01) {
1062 //            return false;
1063 //        }
1064 //
1065 //        return true;
1066 //    }
1067 //
1068 //    /*
1069 //     * (non-Javadoc)
1070 //     *
1071 //     * @see com.jme.bounding.BoundingVolume#intersectsOBB2(com.jme.bounding.OBB2)
1072 //     */
1073 //    public boolean intersectsOrientedBoundingBox(OrientedBoundingBox obb) {
1074 //        if (!Vector3f.isValidVector(center) || !Vector3f.isValidVector(obb.center)) return false;
1075 //
1076 //        // Cutoff for cosine of angles between box axes. This is used to catch
1077 //        // the cases when at least one pair of axes are parallel. If this
1078 //        // happens,
1079 //        // there is no need to test for separation along the Cross(A[i],B[j])
1080 //        // directions.
1081 //        float cutoff = 0.999999f;
1082 //        boolean parallelPairExists = false;
1083 //        int i;
1084 //
1085 //        // convenience variables
1086 //        Vector3f akA[] = new Vector3f[] { xAxis, yAxis, zAxis };
1087 //        Vector3f[] akB = new Vector3f[] { obb.xAxis, obb.yAxis, obb.zAxis };
1088 //        Vector3f afEA = extent;
1089 //        Vector3f afEB = obb.extent;
1090 //
1091 //        // compute difference of box centers, D = C1-C0
1092 //        Vector3f kD = obb.center.subtract(center, _compVect1);
1093 //
1094 //        float[][] aafC = { fWdU, fAWdU, fDdU };
1095 //
1096 //        float[][] aafAbsC = { fADdU, fAWxDdU, tempFa };
1097 //
1098 //        float[] afAD = tempFb;
1099 //        float fR0, fR1, fR; // interval radii and distance between centers
1100 //        float fR01; // = R0 + R1
1101 //
1102 //        // axis C0+t*A0
1103 //        for (i = 0; i < 3; i++) {
1104 //            aafC[0][i] = akA[0].dot(akB[i]);
1105 //            aafAbsC[0][i] = FastMath.abs(aafC[0][i]);
1106 //            if (aafAbsC[0][i] > cutoff) {
1107 //                parallelPairExists = true;
1108 //            }
1109 //        }
1110 //        afAD[0] = akA[0].dot(kD);
1111 //        fR = FastMath.abs(afAD[0]);
1112 //        fR1 = afEB.x * aafAbsC[0][0] + afEB.y * aafAbsC[0][1] + afEB.z
1113 //                * aafAbsC[0][2];
1114 //        fR01 = afEA.x + fR1;
1115 //        if (fR > fR01) {
1116 //            return false;
1117 //        }
1118 //
1119 //        // axis C0+t*A1
1120 //        for (i = 0; i < 3; i++) {
1121 //            aafC[1][i] = akA[1].dot(akB[i]);
1122 //            aafAbsC[1][i] = FastMath.abs(aafC[1][i]);
1123 //            if (aafAbsC[1][i] > cutoff) {
1124 //                parallelPairExists = true;
1125 //            }
1126 //        }
1127 //        afAD[1] = akA[1].dot(kD);
1128 //        fR = FastMath.abs(afAD[1]);
1129 //        fR1 = afEB.x * aafAbsC[1][0] + afEB.y * aafAbsC[1][1] + afEB.z
1130 //                * aafAbsC[1][2];
1131 //        fR01 = afEA.y + fR1;
1132 //        if (fR > fR01) {
1133 //            return false;
1134 //        }
1135 //
1136 //        // axis C0+t*A2
1137 //        for (i = 0; i < 3; i++) {
1138 //            aafC[2][i] = akA[2].dot(akB[i]);
1139 //            aafAbsC[2][i] = FastMath.abs(aafC[2][i]);
1140 //            if (aafAbsC[2][i] > cutoff) {
1141 //                parallelPairExists = true;
1142 //            }
1143 //        }
1144 //        afAD[2] = akA[2].dot(kD);
1145 //        fR = FastMath.abs(afAD[2]);
1146 //        fR1 = afEB.x * aafAbsC[2][0] + afEB.y * aafAbsC[2][1] + afEB.z
1147 //                * aafAbsC[2][2];
1148 //        fR01 = afEA.z + fR1;
1149 //        if (fR > fR01) {
1150 //            return false;
1151 //        }
1152 //
1153 //        // axis C0+t*B0
1154 //        fR = FastMath.abs(akB[0].dot(kD));
1155 //        fR0 = afEA.x * aafAbsC[0][0] + afEA.y * aafAbsC[1][0] + afEA.z
1156 //                * aafAbsC[2][0];
1157 //        fR01 = fR0 + afEB.x;
1158 //        if (fR > fR01) {
1159 //            return false;
1160 //        }
1161 //
1162 //        // axis C0+t*B1
1163 //        fR = FastMath.abs(akB[1].dot(kD));
1164 //        fR0 = afEA.x * aafAbsC[0][1] + afEA.y * aafAbsC[1][1] + afEA.z
1165 //                * aafAbsC[2][1];
1166 //        fR01 = fR0 + afEB.y;
1167 //        if (fR > fR01) {
1168 //            return false;
1169 //        }
1170 //
1171 //        // axis C0+t*B2
1172 //        fR = FastMath.abs(akB[2].dot(kD));
1173 //        fR0 = afEA.x * aafAbsC[0][2] + afEA.y * aafAbsC[1][2] + afEA.z
1174 //                * aafAbsC[2][2];
1175 //        fR01 = fR0 + afEB.z;
1176 //        if (fR > fR01) {
1177 //            return false;
1178 //        }
1179 //
1180 //        // At least one pair of box axes was parallel, so the separation is
1181 //        // effectively in 2D where checking the "edge" normals is sufficient for
1182 //        // the separation of the boxes.
1183 //        if (parallelPairExists) {
1184 //            return true;
1185 //        }
1186 //
1187 //        // axis C0+t*A0xB0
1188 //        fR = FastMath.abs(afAD[2] * aafC[1][0] - afAD[1] * aafC[2][0]);
1189 //        fR0 = afEA.y * aafAbsC[2][0] + afEA.z * aafAbsC[1][0];
1190 //        fR1 = afEB.y * aafAbsC[0][2] + afEB.z * aafAbsC[0][1];
1191 //        fR01 = fR0 + fR1;
1192 //        if (fR > fR01) {
1193 //            return false;
1194 //        }
1195 //
1196 //        // axis C0+t*A0xB1
1197 //        fR = FastMath.abs(afAD[2] * aafC[1][1] - afAD[1] * aafC[2][1]);
1198 //        fR0 = afEA.y * aafAbsC[2][1] + afEA.z * aafAbsC[1][1];
1199 //        fR1 = afEB.x * aafAbsC[0][2] + afEB.z * aafAbsC[0][0];
1200 //        fR01 = fR0 + fR1;
1201 //        if (fR > fR01) {
1202 //            return false;
1203 //        }
1204 //
1205 //        // axis C0+t*A0xB2
1206 //        fR = FastMath.abs(afAD[2] * aafC[1][2] - afAD[1] * aafC[2][2]);
1207 //        fR0 = afEA.y * aafAbsC[2][2] + afEA.z * aafAbsC[1][2];
1208 //        fR1 = afEB.x * aafAbsC[0][1] + afEB.y * aafAbsC[0][0];
1209 //        fR01 = fR0 + fR1;
1210 //        if (fR > fR01) {
1211 //            return false;
1212 //        }
1213 //
1214 //        // axis C0+t*A1xB0
1215 //        fR = FastMath.abs(afAD[0] * aafC[2][0] - afAD[2] * aafC[0][0]);
1216 //        fR0 = afEA.x * aafAbsC[2][0] + afEA.z * aafAbsC[0][0];
1217 //        fR1 = afEB.y * aafAbsC[1][2] + afEB.z * aafAbsC[1][1];
1218 //        fR01 = fR0 + fR1;
1219 //        if (fR > fR01) {
1220 //            return false;
1221 //        }
1222 //
1223 //        // axis C0+t*A1xB1
1224 //        fR = FastMath.abs(afAD[0] * aafC[2][1] - afAD[2] * aafC[0][1]);
1225 //        fR0 = afEA.x * aafAbsC[2][1] + afEA.z * aafAbsC[0][1];
1226 //        fR1 = afEB.x * aafAbsC[1][2] + afEB.z * aafAbsC[1][0];
1227 //        fR01 = fR0 + fR1;
1228 //        if (fR > fR01) {
1229 //            return false;
1230 //        }
1231 //
1232 //        // axis C0+t*A1xB2
1233 //        fR = FastMath.abs(afAD[0] * aafC[2][2] - afAD[2] * aafC[0][2]);
1234 //        fR0 = afEA.x * aafAbsC[2][2] + afEA.z * aafAbsC[0][2];
1235 //        fR1 = afEB.x * aafAbsC[1][1] + afEB.y * aafAbsC[1][0];
1236 //        fR01 = fR0 + fR1;
1237 //        if (fR > fR01) {
1238 //            return false;
1239 //        }
1240 //
1241 //        // axis C0+t*A2xB0
1242 //        fR = FastMath.abs(afAD[1] * aafC[0][0] - afAD[0] * aafC[1][0]);
1243 //        fR0 = afEA.x * aafAbsC[1][0] + afEA.y * aafAbsC[0][0];
1244 //        fR1 = afEB.y * aafAbsC[2][2] + afEB.z * aafAbsC[2][1];
1245 //        fR01 = fR0 + fR1;
1246 //        if (fR > fR01) {
1247 //            return false;
1248 //        }
1249 //
1250 //        // axis C0+t*A2xB1
1251 //        fR = FastMath.abs(afAD[1] * aafC[0][1] - afAD[0] * aafC[1][1]);
1252 //        fR0 = afEA.x * aafAbsC[1][1] + afEA.y * aafAbsC[0][1];
1253 //        fR1 = afEB.x * aafAbsC[2][2] + afEB.z * aafAbsC[2][0];
1254 //        fR01 = fR0 + fR1;
1255 //        if (fR > fR01) {
1256 //            return false;
1257 //        }
1258 //
1259 //        // axis C0+t*A2xB2
1260 //        fR = FastMath.abs(afAD[1] * aafC[0][2] - afAD[0] * aafC[1][2]);
1261 //        fR0 = afEA.x * aafAbsC[1][2] + afEA.y * aafAbsC[0][2];
1262 //        fR1 = afEB.x * aafAbsC[2][1] + afEB.y * aafAbsC[2][0];
1263 //        fR01 = fR0 + fR1;
1264 //        if (fR > fR01) {
1265 //            return false;
1266 //        }
1267 //
1268 //        return true;
1269 //    }
1270 //
1271 //    /*
1272 //     * (non-Javadoc)
1273 //     *
1274 //     * @see com.jme.bounding.BoundingVolume#intersects(com.jme.math.Ray)
1275 //     */
1276 //    public boolean intersects(Ray ray) {
1277 //        if (!Vector3f.isValidVector(center)) return false;
1278 //
1279 //        float rhs;
1280 //        Vector3f diff = ray.origin.subtract(getCenter(_compVect2), _compVect1);
1281 //
1282 //        fWdU[0] = ray.getDirection().dot(xAxis);
1283 //        fAWdU[0] = FastMath.abs(fWdU[0]);
1284 //        fDdU[0] = diff.dot(xAxis);
1285 //        fADdU[0] = FastMath.abs(fDdU[0]);
1286 //        if (fADdU[0] > extent.x && fDdU[0] * fWdU[0] >= 0.0) {
1287 //            return false;
1288 //        }
1289 //
1290 //        fWdU[1] = ray.getDirection().dot(yAxis);
1291 //        fAWdU[1] = FastMath.abs(fWdU[1]);
1292 //        fDdU[1] = diff.dot(yAxis);
1293 //        fADdU[1] = FastMath.abs(fDdU[1]);
1294 //        if (fADdU[1] > extent.y && fDdU[1] * fWdU[1] >= 0.0) {
1295 //            return false;
1296 //        }
1297 //
1298 //        fWdU[2] = ray.getDirection().dot(zAxis);
1299 //        fAWdU[2] = FastMath.abs(fWdU[2]);
1300 //        fDdU[2] = diff.dot(zAxis);
1301 //        fADdU[2] = FastMath.abs(fDdU[2]);
1302 //        if (fADdU[2] > extent.z && fDdU[2] * fWdU[2] >= 0.0) {
1303 //            return false;
1304 //        }
1305 //
1306 //        Vector3f wCrossD = ray.getDirection().cross(diff, _compVect2);
1307 //
1308 //        fAWxDdU[0] = FastMath.abs(wCrossD.dot(xAxis));
1309 //        rhs = extent.y * fAWdU[2] + extent.z * fAWdU[1];
1310 //        if (fAWxDdU[0] > rhs) {
1311 //            return false;
1312 //        }
1313 //
1314 //        fAWxDdU[1] = FastMath.abs(wCrossD.dot(yAxis));
1315 //        rhs = extent.x * fAWdU[2] + extent.z * fAWdU[0];
1316 //        if (fAWxDdU[1] > rhs) {
1317 //            return false;
1318 //        }
1319 //
1320 //        fAWxDdU[2] = FastMath.abs(wCrossD.dot(zAxis));
1321 //        rhs = extent.x * fAWdU[1] + extent.y * fAWdU[0];
1322 //        if (fAWxDdU[2] > rhs) {
1323 //            return false;
1324 //
1325 //        }
1326 //
1327 //        return true;
1328 //    }
1329 //
1330 //    /**
1331 //     * @see com.jme.bounding.BoundingVolume#intersectsWhere(com.jme.math.Ray)
1332 //     */
1333 //    public IntersectionRecord intersectsWhere(Ray ray) {
1334 //        Vector3f diff = _compVect1.set(ray.origin).subtractLocal(center);
1335 //        // convert ray to box coordinates
1336 //        Vector3f direction = _compVect2.set(ray.direction.x, ray.direction.y,
1337 //                ray.direction.z);
1338 //        float[] t = { 0f, Float.POSITIVE_INFINITY };
1339 //
1340 //        float saveT0 = t[0], saveT1 = t[1];
1341 //        boolean notEntirelyClipped = clip(+direction.x, -diff.x - extent.x, t)
1342 //                && clip(-direction.x, +diff.x - extent.x, t)
1343 //                && clip(+direction.y, -diff.y - extent.y, t)
1344 //                && clip(-direction.y, +diff.y - extent.y, t)
1345 //                && clip(+direction.z, -diff.z - extent.z, t)
1346 //                && clip(-direction.z, +diff.z - extent.z, t);
1347 //
1348 //        if (notEntirelyClipped && (t[0] != saveT0 || t[1] != saveT1)) {
1349 //            if (t[1] > t[0]) {
1350 //                float[] distances = t;
1351 //                Vector3f[] points = new Vector3f[] {
1352 //                        new Vector3f(ray.direction).multLocal(distances[0]).addLocal(ray.origin),
1353 //                        new Vector3f(ray.direction).multLocal(distances[1]).addLocal(ray.origin)
1354 //                        };
1355 //                IntersectionRecord record = new IntersectionRecord(distances, points);
1356 //                return record;
1357 //            }
1358 //
1359 //            float[] distances = new float[] { t[0] };
1360 //            Vector3f[] points = new Vector3f[] {
1361 //                    new Vector3f(ray.direction).multLocal(distances[0]).addLocal(ray.origin),
1362 //                    };
1363 //            IntersectionRecord record = new IntersectionRecord(distances, points);
1364 //            return record;
1365 //        }
1366 //
1367 //        return new IntersectionRecord();
1368 //
1369 //    }
1370 //
1371 //    /**
1372 //     * <code>clip</code> determines if a line segment intersects the current
1373 //     * test plane.
1374 //     *
1375 //     * @param denom
1376 //     *            the denominator of the line segment.
1377 //     * @param numer
1378 //     *            the numerator of the line segment.
1379 //     * @param t
1380 //     *            test values of the plane.
1381 //     * @return true if the line segment intersects the plane, false otherwise.
1382 //     */
1383 //    private boolean clip(float denom, float numer, float[] t) {
1384 //        // Return value is 'true' if line segment intersects the current test
1385 //        // plane. Otherwise 'false' is returned in which case the line segment
1386 //        // is entirely clipped.
1387 //        if (denom > 0.0f) {
1388 //            if (numer > denom * t[1])
1389 //                return false;
1390 //            if (numer > denom * t[0])
1391 //                t[0] = numer / denom;
1392 //            return true;
1393 //        } else if (denom < 0.0f) {
1394 //            if (numer > denom * t[0])
1395 //                return false;
1396 //            if (numer > denom * t[1])
1397 //                t[1] = numer / denom;
1398 //            return true;
1399 //        } else {
1400 //            return numer <= 0.0;
1401 //        }
1402 //    }
1403 //
1404 //    public void setXAxis(Vector3f axis) {
1405 //        xAxis.set(axis);
1406 //        correctCorners = false;
1407 //    }
1408 //
1409 //    public void setYAxis(Vector3f axis) {
1410 //        yAxis.set(axis);
1411 //        correctCorners = false;
1412 //    }
1413 //
1414 //    public void setZAxis(Vector3f axis) {
1415 //        zAxis.set(axis);
1416 //        correctCorners = false;
1417 //    }
1418 //
1419 //    public void setExtent(Vector3f ext) {
1420 //        extent.set(ext);
1421 //        correctCorners = false;
1422 //    }
1423 //
1424 //    public Vector3f getXAxis() {
1425 //        return xAxis;
1426 //    }
1427 //
1428 //    public Vector3f getYAxis() {
1429 //        return yAxis;
1430 //    }
1431 //
1432 //    public Vector3f getZAxis() {
1433 //        return zAxis;
1434 //    }
1435 //
1436 //    public Vector3f getExtent() {
1437 //        return extent;
1438 //    }
1439 //
1440 //    @Override
1441 //    public boolean contains(Vector3f point) {
1442 //        _compVect1.set(point).subtractLocal(center);
1443 //        float coeff = _compVect1.dot(xAxis);
1444 //        if (FastMath.abs(coeff) > extent.x) return false;
1445 //
1446 //        coeff = _compVect1.dot(yAxis);
1447 //        if (FastMath.abs(coeff) > extent.y) return false;
1448 //
1449 //        coeff = _compVect1.dot(zAxis);
1450 //        if (FastMath.abs(coeff) > extent.z) return false;
1451 //
1452 //        return true;
1453 //    }
1454 //
1455 //    @Override
1456 //    public float distanceToEdge(Vector3f point) {
1457 //        // compute coordinates of point in box coordinate system
1458 //        Vector3f diff = point.subtract(center);
1459 //        Vector3f closest = new Vector3f(diff.dot(xAxis), diff.dot(yAxis), diff
1460 //                .dot(zAxis));
1461 //
1462 //        // project test point onto box
1463 //        float sqrDistance = 0.0f;
1464 //        float delta;
1465 //
1466 //        if (closest.x < -extent.x) {
1467 //            delta = closest.x + extent.x;
1468 //            sqrDistance += delta * delta;
1469 //            closest.x = -extent.x;
1470 //        } else if (closest.x > extent.x) {
1471 //            delta = closest.x - extent.x;
1472 //            sqrDistance += delta * delta;
1473 //            closest.x = extent.x;
1474 //        }
1475 //
1476 //        if (closest.y < -extent.y) {
1477 //            delta = closest.y + extent.y;
1478 //            sqrDistance += delta * delta;
1479 //            closest.y = -extent.y;
1480 //        } else if (closest.y > extent.y) {
1481 //            delta = closest.y - extent.y;
1482 //            sqrDistance += delta * delta;
1483 //            closest.y = extent.y;
1484 //        }
1485 //
1486 //        if (closest.z < -extent.z) {
1487 //            delta = closest.z + extent.z;
1488 //            sqrDistance += delta * delta;
1489 //            closest.z = -extent.z;
1490 //        } else if (closest.z > extent.z) {
1491 //            delta = closest.z - extent.z;
1492 //            sqrDistance += delta * delta;
1493 //            closest.z = extent.z;
1494 //        }
1495 //
1496 //        return FastMath.sqrt(sqrDistance);
1497 //    }
1498 //
1499 //    public void write(JMEExporter e) throws IOException {
1500 //        super.write(e);
1501 //        OutputCapsule capsule = e.getCapsule(this);
1502 //        capsule.write(xAxis, "xAxis", Vector3f.UNIT_X);
1503 //        capsule.write(yAxis, "yAxis", Vector3f.UNIT_Y);
1504 //        capsule.write(zAxis, "zAxis", Vector3f.UNIT_Z);
1505 //        capsule.write(extent, "extent", Vector3f.ZERO);
1506 //    }
1507 //
1508 //    public void read(JMEImporter e) throws IOException {
1509 //        super.read(e);
1510 //        InputCapsule capsule = e.getCapsule(this);
1511 //        xAxis.set((Vector3f) capsule.readSavable("xAxis", Vector3f.UNIT_X.clone()));
1512 //        yAxis.set((Vector3f) capsule.readSavable("yAxis", Vector3f.UNIT_Y.clone()));
1513 //        zAxis.set((Vector3f) capsule.readSavable("zAxis", Vector3f.UNIT_Z.clone()));
1514 //        extent.set((Vector3f) capsule.readSavable("extent", Vector3f.ZERO.clone()));
1515 //        correctCorners = false;
1516 //    }
1517 //
1518 //    @Override
1519 //    public float getVolume() {
1520 //        return (8*extent.x*extent.y*extent.z);
1521 //    }
1522 //}