protected void splitMesh( final Mesh mesh, final int sectionStart, final int sectionEnd, final boolean doSort) { _mesh = makeRef(mesh); // Split range in half final int rangeSize = sectionEnd - sectionStart; final int halfRange = rangeSize / 2; // odd number will give +1 to right. // left half: // if half size == 1, create as regular CollisionTree if (halfRange == 1) { // compute section final int section = sectionStart; // create the left child _left = new CollisionTree(_type); _left._primitiveIndices = new int[mesh.getMeshData().getPrimitiveCount(section)]; for (int i = 0; i < _left._primitiveIndices.length; i++) { _left._primitiveIndices[i] = i; } _left._mesh = _mesh; _left.createTree(section, 0, _left._primitiveIndices.length, doSort); } else { // otherwise, make an empty collision tree and call split with new range _left = new CollisionTree(_type); _left.splitMesh(mesh, sectionStart, sectionStart + halfRange, doSort); } // right half: // if rangeSize - half size == 1, create as regular CollisionTree if (rangeSize - halfRange == 1) { // compute section final int section = sectionStart + 1; // create the left child _right = new CollisionTree(_type); _right._primitiveIndices = new int[mesh.getMeshData().getPrimitiveCount(section)]; for (int i = 0; i < _right._primitiveIndices.length; i++) { _right._primitiveIndices[i] = i; } _right._mesh = _mesh; _right.createTree(section, 0, _right._primitiveIndices.length, doSort); } else { // otherwise, make an empty collision tree and call split with new range _right = new CollisionTree(_type); _right.splitMesh(mesh, sectionStart + halfRange, sectionEnd, doSort); } // Ok, now since we technically have no primitives, we need our bounds to be the merging of our // children bounds // instead: _bounds = _left._bounds.clone(_bounds); _bounds.mergeLocal(_right._bounds); _worldBounds = _bounds.clone(_worldBounds); }
/** * Creates a Collision Tree by recursively creating children nodes, splitting the primitives this * node is responsible for in half until the desired primitive count is reached. * * @param start The start index of the primitivesArray, inclusive. * @param end The end index of the primitivesArray, exclusive. * @param doSort True if the primitives should be sorted at each level, false otherwise. */ public void createTree(final int section, final int start, final int end, final boolean doSort) { _section = section; _start = start; _end = end; if (_primitiveIndices == null) { return; } createBounds(); // the bounds at this level should contain all the primitives this level is responsible for. _bounds.computeFromPrimitives( getMesh().getMeshData(), _section, _primitiveIndices, _start, _end); // check to see if we are a leaf, if the number of primitives we reference is less than or equal // to the maximum // defined by the CollisionTreeManager we are done. if (_end - _start + 1 <= CollisionTreeManager.getInstance().getMaxPrimitivesPerLeaf()) { return; } // if doSort is set we need to attempt to optimize the referenced primitives. optimizing the // sorting of the // primitives will help group them spatially in the left/right children better. if (doSort) { sortPrimitives(); } // create the left child if (_left == null) { _left = new CollisionTree(_type); } _left._primitiveIndices = _primitiveIndices; _left._mesh = _mesh; _left.createTree(_section, _start, (_start + _end) / 2, doSort); // create the right child if (_right == null) { _right = new CollisionTree(_type); } _right._primitiveIndices = _primitiveIndices; _right._mesh = _mesh; _right.createTree(_section, (_start + _end) / 2, _end, doSort); }