159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/* 259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Copyright (c) 2009-2010 jMonkeyEngine 359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * All rights reserved. 459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Redistribution and use in source and binary forms, with or without 659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * modification, are permitted provided that the following conditions are 759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * met: 859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Redistributions of source code must retain the above copyright 1059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * notice, this list of conditions and the following disclaimer. 1159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 1259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Redistributions in binary form must reproduce the above copyright 1359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * notice, this list of conditions and the following disclaimer in the 1459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * documentation and/or other materials provided with the distribution. 1559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 1659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Neither the name of 'jMonkeyEngine' nor the names of its contributors 1759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * may be used to endorse or promote products derived from this software 1859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * without specific prior written permission. 1959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 2059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 2259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 2359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 2459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 2559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 2659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 2759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 2859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 2959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 3059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 3259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapackage com.jme3.collision.bih; 3359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 3459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.bounding.BoundingBox; 3559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.bounding.BoundingSphere; 3659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.bounding.BoundingVolume; 3759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.collision.Collidable; 3859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.collision.CollisionResults; 3959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.collision.UnsupportedCollisionException; 4059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.export.InputCapsule; 4159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.export.JmeExporter; 4259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.export.JmeImporter; 4359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.export.OutputCapsule; 4459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.FastMath; 4559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.Matrix4f; 4659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.Ray; 4759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.Vector3f; 4859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.CollisionData; 4959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.Mesh; 5059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.Mesh.Mode; 5159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.VertexBuffer.Type; 5259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.mesh.IndexBuffer; 5359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.mesh.VirtualIndexBuffer; 5459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.mesh.WrappedIndexBuffer; 5559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.util.TempVars; 5659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.io.IOException; 5759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport static java.lang.Math.max; 5859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.nio.FloatBuffer; 5959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 6059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapublic class BIHTree implements CollisionData { 6159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 6259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int MAX_TREE_DEPTH = 100; 6359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int MAX_TRIS_PER_NODE = 21; 6459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private Mesh mesh; 6559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private BIHNode root; 6659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private int maxTrisPerNode; 6759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private int numTris; 6859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private float[] pointData; 6959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private int[] triIndices; 7059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 7159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private transient CollisionResults boundResults = new CollisionResults(); 7259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private transient float[] bihSwapTmp; 7359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 7459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private static final TriangleAxisComparator[] comparators = new TriangleAxisComparator[] 7559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta { 7659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta new TriangleAxisComparator(0), 7759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta new TriangleAxisComparator(1), 7859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta new TriangleAxisComparator(2) 7959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta }; 8059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 8159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private void initTriList(FloatBuffer vb, IndexBuffer ib) { 8259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta pointData = new float[numTris * 3 * 3]; 8359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int p = 0; 8459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int i = 0; i < numTris * 3; i += 3) { 8559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int vert = ib.get(i) * 3; 8659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta pointData[p++] = vb.get(vert++); 8759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta pointData[p++] = vb.get(vert++); 8859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta pointData[p++] = vb.get(vert); 8959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 9059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vert = ib.get(i + 1) * 3; 9159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta pointData[p++] = vb.get(vert++); 9259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta pointData[p++] = vb.get(vert++); 9359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta pointData[p++] = vb.get(vert); 9459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 9559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vert = ib.get(i + 2) * 3; 9659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta pointData[p++] = vb.get(vert++); 9759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta pointData[p++] = vb.get(vert++); 9859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta pointData[p++] = vb.get(vert); 9959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 10059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 10159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta triIndices = new int[numTris]; 10259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int i = 0; i < numTris; i++) { 10359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta triIndices[i] = i; 10459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 10559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 10659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 10759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public BIHTree(Mesh mesh, int maxTrisPerNode) { 10859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.mesh = mesh; 10959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.maxTrisPerNode = maxTrisPerNode; 11059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 11159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (maxTrisPerNode < 1 || mesh == null) { 11259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta throw new IllegalArgumentException(); 11359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 11459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 11559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta bihSwapTmp = new float[9]; 11659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 11759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta FloatBuffer vb = (FloatBuffer) mesh.getBuffer(Type.Position).getData(); 11859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta IndexBuffer ib = mesh.getIndexBuffer(); 11959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (ib == null) { 12059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta ib = new VirtualIndexBuffer(mesh.getVertexCount(), mesh.getMode()); 12159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else if (mesh.getMode() != Mode.Triangles) { 12259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta ib = new WrappedIndexBuffer(mesh); 12359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 12459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 12559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta numTris = ib.size() / 3; 12659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta initTriList(vb, ib); 12759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 12859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 12959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public BIHTree(Mesh mesh) { 13059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this(mesh, MAX_TRIS_PER_NODE); 13159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 13259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 13359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public BIHTree() { 13459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 13559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 13659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void construct() { 13759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta BoundingBox sceneBbox = createBox(0, numTris - 1); 13859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta root = createNode(0, numTris - 1, sceneBbox, 0); 13959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 14059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 14159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private BoundingBox createBox(int l, int r) { 14259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta TempVars vars = TempVars.get(); 14359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 14459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f min = vars.vect1.set(new Vector3f(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY)); 14559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f max = vars.vect2.set(new Vector3f(Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY)); 14659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 14759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f v1 = vars.vect3, 14859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta v2 = vars.vect4, 14959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta v3 = vars.vect5; 15059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 15159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int i = l; i <= r; i++) { 15259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta getTriangle(i, v1, v2, v3); 15359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta BoundingBox.checkMinMax(min, max, v1); 15459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta BoundingBox.checkMinMax(min, max, v2); 15559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta BoundingBox.checkMinMax(min, max, v3); 15659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 15759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 15859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta BoundingBox bbox = new BoundingBox(min, max); 15959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vars.release(); 16059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return bbox; 16159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 16259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 16359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int getTriangleIndex(int triIndex) { 16459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return triIndices[triIndex]; 16559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 16659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 16759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private int sortTriangles(int l, int r, float split, int axis) { 16859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int pivot = l; 16959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int j = r; 17059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 17159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta TempVars vars = TempVars.get(); 17259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 17359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f v1 = vars.vect1, 17459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta v2 = vars.vect2, 17559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta v3 = vars.vect3; 17659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 17759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta while (pivot <= j) { 17859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta getTriangle(pivot, v1, v2, v3); 17959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta v1.addLocal(v2).addLocal(v3).multLocal(FastMath.ONE_THIRD); 18059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (v1.get(axis) > split) { 18159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta swapTriangles(pivot, j); 18259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta --j; 18359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 18459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta ++pivot; 18559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 18659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 18759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 18859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vars.release(); 18959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta pivot = (pivot == l && j < pivot) ? j : pivot; 19059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return pivot; 19159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 19259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 19359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private void setMinMax(BoundingBox bbox, boolean doMin, int axis, float value) { 19459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f min = bbox.getMin(null); 19559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f max = bbox.getMax(null); 19659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 19759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (doMin) { 19859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta min.set(axis, value); 19959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 20059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta max.set(axis, value); 20159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 20259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 20359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta bbox.setMinMax(min, max); 20459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 20559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 20659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private float getMinMax(BoundingBox bbox, boolean doMin, int axis) { 20759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (doMin) { 20859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return bbox.getMin(null).get(axis); 20959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 21059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return bbox.getMax(null).get(axis); 21159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 21259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 21359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 21459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// private BIHNode createNode2(int l, int r, BoundingBox nodeBbox, int depth){ 21559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// if ((r - l) < maxTrisPerNode || depth > 100) 21659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// return createLeaf(l, r); 21759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// 21859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// BoundingBox currentBox = createBox(l, r); 21959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// int axis = depth % 3; 22059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// float split = currentBox.getCenter().get(axis); 22159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// 22259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// TriangleAxisComparator comparator = comparators[axis]; 22359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// Arrays.sort(tris, l, r, comparator); 22459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// int splitIndex = -1; 22559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// 22659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// float leftPlane, rightPlane = Float.POSITIVE_INFINITY; 22759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// leftPlane = tris[l].getExtreme(axis, false); 22859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// for (int i = l; i <= r; i++){ 22959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// BIHTriangle tri = tris[i]; 23059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// if (splitIndex == -1){ 23159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// float v = tri.getCenter().get(axis); 23259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// if (v > split){ 23359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// if (i == 0){ 23459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// // no left plane 23559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// splitIndex = -2; 23659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// }else{ 23759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// splitIndex = i; 23859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// // first triangle assigned to right 23959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// rightPlane = tri.getExtreme(axis, true); 24059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// } 24159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// }else{ 24259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// // triangle assigned to left 24359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// float ex = tri.getExtreme(axis, false); 24459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// if (ex > leftPlane) 24559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// leftPlane = ex; 24659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// } 24759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// }else{ 24859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// float ex = tri.getExtreme(axis, true); 24959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// if (ex < rightPlane) 25059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// rightPlane = ex; 25159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// } 25259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// } 25359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// 25459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// if (splitIndex < 0){ 25559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// splitIndex = (r - l) / 2; 25659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// 25759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// leftPlane = Float.NEGATIVE_INFINITY; 25859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// rightPlane = Float.POSITIVE_INFINITY; 25959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// 26059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// for (int i = l; i < splitIndex; i++){ 26159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// float ex = tris[i].getExtreme(axis, false); 26259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// if (ex > leftPlane){ 26359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// leftPlane = ex; 26459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// } 26559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// } 26659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// for (int i = splitIndex; i <= r; i++){ 26759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// float ex = tris[i].getExtreme(axis, true); 26859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// if (ex < rightPlane){ 26959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// rightPlane = ex; 27059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// } 27159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// } 27259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// } 27359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// 27459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// BIHNode node = new BIHNode(axis); 27559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// node.leftPlane = leftPlane; 27659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// node.rightPlane = rightPlane; 27759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// 27859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// node.leftIndex = l; 27959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// node.rightIndex = r; 28059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// 28159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// BoundingBox leftBbox = new BoundingBox(currentBox); 28259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// setMinMax(leftBbox, false, axis, split); 28359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// node.left = createNode2(l, splitIndex-1, leftBbox, depth+1); 28459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// 28559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// BoundingBox rightBbox = new BoundingBox(currentBox); 28659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// setMinMax(rightBbox, true, axis, split); 28759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// node.right = createNode2(splitIndex, r, rightBbox, depth+1); 28859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// 28959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// return node; 29059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// } 29159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private BIHNode createNode(int l, int r, BoundingBox nodeBbox, int depth) { 29259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if ((r - l) < maxTrisPerNode || depth > MAX_TREE_DEPTH) { 29359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return new BIHNode(l, r); 29459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 29559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 29659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta BoundingBox currentBox = createBox(l, r); 29759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 29859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f exteriorExt = nodeBbox.getExtent(null); 29959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f interiorExt = currentBox.getExtent(null); 30059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta exteriorExt.subtractLocal(interiorExt); 30159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 30259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int axis = 0; 30359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (exteriorExt.x > exteriorExt.y) { 30459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (exteriorExt.x > exteriorExt.z) { 30559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta axis = 0; 30659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 30759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta axis = 2; 30859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 30959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 31059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (exteriorExt.y > exteriorExt.z) { 31159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta axis = 1; 31259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 31359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta axis = 2; 31459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 31559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 31659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (exteriorExt.equals(Vector3f.ZERO)) { 31759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta axis = 0; 31859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 31959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 32059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// Arrays.sort(tris, l, r, comparators[axis]); 32159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float split = currentBox.getCenter().get(axis); 32259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int pivot = sortTriangles(l, r, split, axis); 32359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (pivot == l || pivot == r) { 32459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta pivot = (r + l) / 2; 32559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 32659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 32759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //If one of the partitions is empty, continue with recursion: same level but different bbox 32859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (pivot < l) { 32959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //Only right 33059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta BoundingBox rbbox = new BoundingBox(currentBox); 33159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta setMinMax(rbbox, true, axis, split); 33259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return createNode(l, r, rbbox, depth + 1); 33359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else if (pivot > r) { 33459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //Only left 33559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta BoundingBox lbbox = new BoundingBox(currentBox); 33659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta setMinMax(lbbox, false, axis, split); 33759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return createNode(l, r, lbbox, depth + 1); 33859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 33959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //Build the node 34059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta BIHNode node = new BIHNode(axis); 34159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 34259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //Left child 34359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta BoundingBox lbbox = new BoundingBox(currentBox); 34459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta setMinMax(lbbox, false, axis, split); 34559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 34659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //The left node right border is the plane most right 34759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta node.setLeftPlane(getMinMax(createBox(l, max(l, pivot - 1)), false, axis)); 34859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta node.setLeftChild(createNode(l, max(l, pivot - 1), lbbox, depth + 1)); //Recursive call 34959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 35059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //Right Child 35159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta BoundingBox rbbox = new BoundingBox(currentBox); 35259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta setMinMax(rbbox, true, axis, split); 35359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //The right node left border is the plane most left 35459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta node.setRightPlane(getMinMax(createBox(pivot, r), true, axis)); 35559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta node.setRightChild(createNode(pivot, r, rbbox, depth + 1)); //Recursive call 35659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 35759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return node; 35859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 35959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 36059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 36159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void getTriangle(int index, Vector3f v1, Vector3f v2, Vector3f v3) { 36259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int pointIndex = index * 9; 36359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 36459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta v1.x = pointData[pointIndex++]; 36559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta v1.y = pointData[pointIndex++]; 36659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta v1.z = pointData[pointIndex++]; 36759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 36859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta v2.x = pointData[pointIndex++]; 36959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta v2.y = pointData[pointIndex++]; 37059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta v2.z = pointData[pointIndex++]; 37159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 37259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta v3.x = pointData[pointIndex++]; 37359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta v3.y = pointData[pointIndex++]; 37459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta v3.z = pointData[pointIndex++]; 37559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 37659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 37759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void swapTriangles(int index1, int index2) { 37859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int p1 = index1 * 9; 37959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int p2 = index2 * 9; 38059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 38159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // store p1 in tmp 38259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta System.arraycopy(pointData, p1, bihSwapTmp, 0, 9); 38359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 38459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // copy p2 to p1 38559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta System.arraycopy(pointData, p2, pointData, p1, 9); 38659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 38759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // copy tmp to p2 38859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta System.arraycopy(bihSwapTmp, 0, pointData, p2, 9); 38959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 39059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // swap indices 39159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int tmp2 = triIndices[index1]; 39259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta triIndices[index1] = triIndices[index2]; 39359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta triIndices[index2] = tmp2; 39459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 39559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 39659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private int collideWithRay(Ray r, 39759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Matrix4f worldMatrix, 39859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta BoundingVolume worldBound, 39959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta CollisionResults results) { 40059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 40159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta boundResults.clear(); 40259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta worldBound.collideWith(r, boundResults); 40359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (boundResults.size() > 0) { 40459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float tMin = boundResults.getClosestCollision().getDistance(); 40559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float tMax = boundResults.getFarthestCollision().getDistance(); 40659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 40759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (tMax <= 0) { 40859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta tMax = Float.POSITIVE_INFINITY; 40959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else if (tMin == tMax) { 41059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta tMin = 0; 41159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 41259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 41359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (tMin <= 0) { 41459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta tMin = 0; 41559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 41659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 41759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (r.getLimit() < Float.POSITIVE_INFINITY) { 41859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta tMax = Math.min(tMax, r.getLimit()); 41959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (tMin > tMax){ 42059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return 0; 42159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 42259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 42359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 42459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// return root.intersectBrute(r, worldMatrix, this, tMin, tMax, results); 42559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return root.intersectWhere(r, worldMatrix, this, tMin, tMax, results); 42659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 42759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return 0; 42859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 42959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 43059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private int collideWithBoundingVolume(BoundingVolume bv, 43159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Matrix4f worldMatrix, 43259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta CollisionResults results) { 43359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta BoundingBox bbox; 43459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (bv instanceof BoundingSphere) { 43559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta BoundingSphere sphere = (BoundingSphere) bv; 43659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta bbox = new BoundingBox(bv.getCenter().clone(), sphere.getRadius(), 43759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta sphere.getRadius(), 43859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta sphere.getRadius()); 43959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else if (bv instanceof BoundingBox) { 44059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta bbox = new BoundingBox((BoundingBox) bv); 44159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 44259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta throw new UnsupportedCollisionException(); 44359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 44459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 44559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta bbox.transform(worldMatrix.invert(), bbox); 44659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return root.intersectWhere(bv, bbox, worldMatrix, this, results); 44759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 44859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 44959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public int collideWith(Collidable other, 45059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Matrix4f worldMatrix, 45159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta BoundingVolume worldBound, 45259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta CollisionResults results) { 45359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 45459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (other instanceof Ray) { 45559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Ray ray = (Ray) other; 45659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return collideWithRay(ray, worldMatrix, worldBound, results); 45759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else if (other instanceof BoundingVolume) { 45859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta BoundingVolume bv = (BoundingVolume) other; 45959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return collideWithBoundingVolume(bv, worldMatrix, results); 46059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 46159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta throw new UnsupportedCollisionException(); 46259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 46359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 46459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 46559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void write(JmeExporter ex) throws IOException { 46659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta OutputCapsule oc = ex.getCapsule(this); 46759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta oc.write(mesh, "mesh", null); 46859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta oc.write(root, "root", null); 46959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta oc.write(maxTrisPerNode, "tris_per_node", 0); 47059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta oc.write(pointData, "points", null); 47159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta oc.write(triIndices, "indices", null); 47259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 47359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 47459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void read(JmeImporter im) throws IOException { 47559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta InputCapsule ic = im.getCapsule(this); 47659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta mesh = (Mesh) ic.readSavable("mesh", null); 47759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta root = (BIHNode) ic.readSavable("root", null); 47859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta maxTrisPerNode = ic.readInt("tris_per_node", 0); 47959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta pointData = ic.readFloatArray("points", null); 48059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta triIndices = ic.readIntArray("indices", null); 48159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 48259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta} 483