/* * Java port of Bullet (c) 2008 Martin Dvorak * * This source file is part of GIMPACT Library. * * For the latest info, see http://gimpact.sourceforge.net/ * * Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371. * email: projectileman@yahoo.com * * This software is provided 'as-is', without any express or implied warranty. * In no event will the authors be held liable for any damages arising from * the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. */ package com.bulletphysics.extras.gimpact; import com.bulletphysics.extras.gimpact.BoxCollision.AABB; import com.bulletphysics.linearmath.VectorUtil; import cz.advel.stack.Stack; import javax.vecmath.Vector3f; /** * * @author jezek2 */ class BvhTree { protected int num_nodes = 0; protected BvhTreeNodeArray node_array = new BvhTreeNodeArray(); protected int _calc_splitting_axis(BvhDataArray primitive_boxes, int startIndex, int endIndex) { Vector3f means = Stack.alloc(Vector3f.class); means.set(0f, 0f, 0f); Vector3f variance = Stack.alloc(Vector3f.class); variance.set(0f, 0f, 0f); int numIndices = endIndex - startIndex; Vector3f center = Stack.alloc(Vector3f.class); Vector3f diff2 = Stack.alloc(Vector3f.class); Vector3f tmp1 = Stack.alloc(Vector3f.class); Vector3f tmp2 = Stack.alloc(Vector3f.class); for (int i=startIndex; i splitValue) { // swap primitive_boxes.swap(i, splitIndex); //swapLeafNodes(i,splitIndex); splitIndex++; } } // if the splitIndex causes unbalanced trees, fix this by using the center in between startIndex and endIndex // otherwise the tree-building might fail due to stack-overflows in certain cases. // unbalanced1 is unsafe: it can cause stack overflows //bool unbalanced1 = ((splitIndex==startIndex) || (splitIndex == (endIndex-1))); // unbalanced2 should work too: always use center (perfect balanced trees) //bool unbalanced2 = true; // this should be safe too: int rangeBalancedIndices = numIndices / 3; boolean unbalanced = ((splitIndex <= (startIndex + rangeBalancedIndices)) || (splitIndex >= (endIndex - 1 - rangeBalancedIndices))); if (unbalanced) { splitIndex = startIndex + (numIndices >> 1); } boolean unbal = (splitIndex == startIndex) || (splitIndex == (endIndex)); assert (!unbal); return splitIndex; } protected void _build_sub_tree(BvhDataArray primitive_boxes, int startIndex, int endIndex) { int curIndex = num_nodes; num_nodes++; assert ((endIndex - startIndex) > 0); if ((endIndex - startIndex) == 1) { // We have a leaf node //setNodeBound(curIndex,primitive_boxes[startIndex].m_bound); //m_node_array[curIndex].setDataIndex(primitive_boxes[startIndex].m_data); node_array.set(curIndex, primitive_boxes, startIndex); return; } // calculate Best Splitting Axis and where to split it. Sort the incoming 'leafNodes' array within range 'startIndex/endIndex'. // split axis int splitIndex = _calc_splitting_axis(primitive_boxes, startIndex, endIndex); splitIndex = _sort_and_calc_splitting_index(primitive_boxes, startIndex, endIndex, splitIndex); //calc this node bounding box AABB node_bound = Stack.alloc(AABB.class); AABB tmpAABB = Stack.alloc(AABB.class); node_bound.invalidate(); for (int i=startIndex; i