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 //}