/** * intersect checks for collisions between this collision tree and a provided Ray. Any collisions * are stored in a provided list as primitive index values. The ray is assumed to have a * normalized direction for accurate calculations. * * @param ray the ray to test for intersections. * @param store a list to fill with the index values of the primitive hit. if null, a new List is * created. * @return the list. */ public List<PrimitiveKey> intersect(final Ray3 ray, final List<PrimitiveKey> store) { List<PrimitiveKey> result = store; if (result == null) { result = new ArrayList<PrimitiveKey>(); } // if our ray doesn't hit the bounds, then it must not hit a primitive. if (!_worldBounds.intersects(ray)) { return result; } // This is not a leaf node, therefore, check each child (left/right) for intersection with the // ray. if (_left != null) { _left._worldBounds = _left._bounds.transform(getMesh().getWorldTransform(), _left._worldBounds); _left.intersect(ray, result); } if (_right != null) { _right._worldBounds = _right._bounds.transform(getMesh().getWorldTransform(), _right._worldBounds); _right.intersect(ray, result); } else if (_left == null) { // This is a leaf node. We can therefore check each primitive this node contains. If an // intersection occurs, // place it in the list. final MeshData data = getMesh().getMeshData(); final ReadOnlyTransform transform = getMesh().getWorldTransform(); Vector3[] points = null; for (int i = _start; i < _end; i++) { points = data.getPrimitiveVertices(_primitiveIndices[i], _section, points); for (int t = 0; t < points.length; t++) { transform.applyForward(points[t]); } if (ray.intersects(points, null)) { result.add(new PrimitiveKey(_primitiveIndices[i], _section)); } } } return result; }
/** * Determines if this Collision Tree intersects the given CollisionTree. If a collision occurs, * true is returned, otherwise false is returned. If the provided collisionTree is invalid, false * is returned. All collisions that occur are stored in lists as an integer index into the mesh's * triangle buffer. where aList is the primitives for this mesh and bList is the primitives for * the test tree. * * @param collisionTree The Tree to test. * @param aList a list to contain the colliding primitives of this mesh. * @param bList a list to contain the colliding primitives of the testing mesh. * @return True if they intersect, false otherwise. */ public boolean intersect( final CollisionTree collisionTree, final List<PrimitiveKey> aList, final List<PrimitiveKey> bList) { if (collisionTree == null) { return false; } collisionTree._worldBounds = collisionTree._bounds.transform( collisionTree.getMesh().getWorldTransform(), collisionTree._worldBounds); // our two collision bounds do not intersect, therefore, our primitives // must not intersect. Return false. if (!intersectsBounding(collisionTree._worldBounds)) { return false; } // if our node is not a leaf send the children (both left and right) to // the test tree. if (_left != null) { // This is not a leaf boolean test = collisionTree.intersect(_left, bList, aList); test = collisionTree.intersect(_right, bList, aList) || test; return test; } // This node is a leaf, but the testing tree node is not. Therefore, // continue processing the testing tree until we find its leaves. if (collisionTree._left != null) { boolean test = intersect(collisionTree._left, aList, bList); test = intersect(collisionTree._right, aList, bList) || test; return test; } // both this node and the testing node are leaves. Therefore, we can // switch to checking the contained primitives with each other. Any // that are found to intersect are placed in the appropriate list. final ReadOnlyTransform transformA = getMesh().getWorldTransform(); final ReadOnlyTransform transformB = collisionTree.getMesh().getWorldTransform(); final MeshData dataA = getMesh().getMeshData(); final MeshData dataB = collisionTree.getMesh().getMeshData(); Vector3[] storeA = null; Vector3[] storeB = null; boolean test = false; for (int i = _start; i < _end; i++) { storeA = dataA.getPrimitiveVertices(_primitiveIndices[i], _section, storeA); // to world space for (int t = 0; t < storeA.length; t++) { transformA.applyForward(storeA[t]); } for (int j = collisionTree._start; j < collisionTree._end; j++) { storeB = dataB.getPrimitiveVertices( collisionTree._primitiveIndices[j], collisionTree._section, storeB); // to world space for (int t = 0; t < storeB.length; t++) { transformB.applyForward(storeB[t]); } if (Intersection.intersection(storeA, storeB)) { test = true; aList.add(new PrimitiveKey(_primitiveIndices[i], _section)); bList.add(new PrimitiveKey(collisionTree._primitiveIndices[j], collisionTree._section)); } } } return test; }
/** * Determines if this Collision Tree intersects the given CollisionTree. If a collision occurs, * true is returned, otherwise false is returned. If the provided collisionTree is invalid, false * is returned. * * @param collisionTree The Tree to test. * @return True if they intersect, false otherwise. */ public boolean intersect(final CollisionTree collisionTree) { if (collisionTree == null) { return false; } collisionTree._worldBounds = collisionTree._bounds.transform( collisionTree.getMesh().getWorldTransform(), collisionTree._worldBounds); // our two collision bounds do not intersect, therefore, our primitives // must not intersect. Return false. if (!intersectsBounding(collisionTree._worldBounds)) { return false; } // check children if (_left != null) { // This is not a leaf if (collisionTree.intersect(_left)) { return true; } if (collisionTree.intersect(_right)) { return true; } return false; } // This is a leaf if (collisionTree._left != null) { // but collision isn't if (intersect(collisionTree._left)) { return true; } if (intersect(collisionTree._right)) { return true; } return false; } // both are leaves final ReadOnlyTransform transformA = getMesh().getWorldTransform(); final ReadOnlyTransform transformB = collisionTree.getMesh().getWorldTransform(); final MeshData dataA = getMesh().getMeshData(); final MeshData dataB = collisionTree.getMesh().getMeshData(); Vector3[] storeA = null; Vector3[] storeB = null; // for every primitive to compare, put them into world space and check for intersections for (int i = _start; i < _end; i++) { storeA = dataA.getPrimitiveVertices(_primitiveIndices[i], _section, storeA); // to world space for (int t = 0; t < storeA.length; t++) { transformA.applyForward(storeA[t]); } for (int j = collisionTree._start; j < collisionTree._end; j++) { storeB = dataB.getPrimitiveVertices( collisionTree._primitiveIndices[j], collisionTree._section, storeB); // to world space for (int t = 0; t < storeB.length; t++) { transformB.applyForward(storeB[t]); } if (Intersection.intersection(storeA, storeB)) { return true; } } } return false; }