Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "gim_box_set.h"
00033
00034
00035 GUINT GIM_BOX_TREE::_calc_splitting_axis(
00036 gim_array<GIM_AABB_DATA> & primitive_boxes, GUINT startIndex, GUINT endIndex)
00037 {
00038 GUINT i;
00039
00040 btVector3 means(btScalar(0.),btScalar(0.),btScalar(0.));
00041 btVector3 variance(btScalar(0.),btScalar(0.),btScalar(0.));
00042 GUINT numIndices = endIndex-startIndex;
00043
00044 for (i=startIndex;i<endIndex;i++)
00045 {
00046 btVector3 center = btScalar(0.5)*(primitive_boxes[i].m_bound.m_max +
00047 primitive_boxes[i].m_bound.m_min);
00048 means+=center;
00049 }
00050 means *= (btScalar(1.)/(btScalar)numIndices);
00051
00052 for (i=startIndex;i<endIndex;i++)
00053 {
00054 btVector3 center = btScalar(0.5)*(primitive_boxes[i].m_bound.m_max +
00055 primitive_boxes[i].m_bound.m_min);
00056 btVector3 diff2 = center-means;
00057 diff2 = diff2 * diff2;
00058 variance += diff2;
00059 }
00060 variance *= (btScalar(1.)/ ((btScalar)numIndices-1) );
00061
00062 return variance.maxAxis();
00063 }
00064
00065
00066 GUINT GIM_BOX_TREE::_sort_and_calc_splitting_index(
00067 gim_array<GIM_AABB_DATA> & primitive_boxes, GUINT startIndex,
00068 GUINT endIndex, GUINT splitAxis)
00069 {
00070 GUINT i;
00071 GUINT splitIndex =startIndex;
00072 GUINT numIndices = endIndex - startIndex;
00073
00074
00075 btScalar splitValue = 0.0f;
00076 for (i=startIndex;i<endIndex;i++)
00077 {
00078 splitValue+= 0.5f*(primitive_boxes[i].m_bound.m_max[splitAxis] +
00079 primitive_boxes[i].m_bound.m_min[splitAxis]);
00080 }
00081 splitValue /= (btScalar)numIndices;
00082
00083
00084 for (i=startIndex;i<endIndex;i++)
00085 {
00086 btScalar center = 0.5f*(primitive_boxes[i].m_bound.m_max[splitAxis] +
00087 primitive_boxes[i].m_bound.m_min[splitAxis]);
00088 if (center > splitValue)
00089 {
00090
00091 primitive_boxes.swap(i,splitIndex);
00092 splitIndex++;
00093 }
00094 }
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 GUINT rangeBalancedIndices = numIndices/3;
00106 bool unbalanced = ((splitIndex<=(startIndex+rangeBalancedIndices)) || (splitIndex >=(endIndex-1-rangeBalancedIndices)));
00107
00108 if (unbalanced)
00109 {
00110 splitIndex = startIndex+ (numIndices>>1);
00111 }
00112
00113 btAssert(!((splitIndex==startIndex) || (splitIndex == (endIndex))));
00114
00115 return splitIndex;
00116 }
00117
00118
00119 void GIM_BOX_TREE::_build_sub_tree(gim_array<GIM_AABB_DATA> & primitive_boxes, GUINT startIndex, GUINT endIndex)
00120 {
00121 GUINT current_index = m_num_nodes++;
00122
00123 btAssert((endIndex-startIndex)>0);
00124
00125 if((endIndex-startIndex) == 1)
00126 {
00127 m_node_array[current_index].m_left = 0;
00128 m_node_array[current_index].m_right = 0;
00129 m_node_array[current_index].m_escapeIndex = 0;
00130
00131 m_node_array[current_index].m_bound = primitive_boxes[startIndex].m_bound;
00132 m_node_array[current_index].m_data = primitive_boxes[startIndex].m_data;
00133 return;
00134 }
00135
00136
00137
00138 GUINT splitIndex;
00139
00140
00141 m_node_array[current_index].m_bound.invalidate();
00142 for (splitIndex=startIndex;splitIndex<endIndex;splitIndex++)
00143 {
00144 m_node_array[current_index].m_bound.merge(primitive_boxes[splitIndex].m_bound);
00145 }
00146
00147
00148
00149
00150 splitIndex = _calc_splitting_axis(primitive_boxes,startIndex,endIndex);
00151
00152 splitIndex = _sort_and_calc_splitting_index(
00153 primitive_boxes,startIndex,endIndex,splitIndex);
00154
00155
00156 m_node_array[current_index].m_left = m_num_nodes;
00157
00158 _build_sub_tree(primitive_boxes, startIndex, splitIndex );
00159
00160
00161 m_node_array[current_index].m_right = m_num_nodes;
00162
00163
00164 _build_sub_tree(primitive_boxes, splitIndex ,endIndex);
00165
00166
00167 m_node_array[current_index].m_escapeIndex = m_num_nodes - current_index;
00168 }
00169
00171 void GIM_BOX_TREE::build_tree(
00172 gim_array<GIM_AABB_DATA> & primitive_boxes)
00173 {
00174
00175 m_num_nodes = 0;
00176
00177 m_node_array.resize(primitive_boxes.size()*2);
00178
00179 _build_sub_tree(primitive_boxes, 0, primitive_boxes.size());
00180 }
00181
00182