1 #ifndef GIM_BOX_SET_H_INCLUDED 2 #define GIM_BOX_SET_H_INCLUDED 92 virtual bool is_trimesh() = 0;
93 virtual GUINT get_primitive_count() = 0;
94 virtual void get_primitive_box(
GUINT prim_index,
GIM_AABB& primbox) = 0;
95 virtual void get_primitive_triangle(
GUINT prim_index,
GIM_TRIANGLE& triangle) = 0;
123 return (!m_left && !m_right);
135 GUINT _sort_and_calc_splitting_index(
155 m_node_array.
clear();
168 return m_node_array[nodeindex].is_leaf_node();
173 return m_node_array[nodeindex].
m_data;
178 bound = m_node_array[nodeindex].m_bound;
183 m_node_array[nodeindex].m_bound = bound;
188 return m_node_array[nodeindex].m_left;
193 return m_node_array[nodeindex].m_right;
198 return m_node_array[nodeindex].m_escapeIndex;
210 template <
typename _GIM_PRIMITIVE_MANAGER_PROTOTYPE,
typename _GIM_BOX_TREE_PROTOTYPE>
221 GUINT nodecount = getNodeCount();
224 if (isLeafNode(nodecount))
227 m_primitive_manager.get_primitive_box(getNodeData(nodecount), leafbox);
228 setNodeBound(nodecount, leafbox);
233 GUINT childindex = getLeftNodeIndex(nodecount);
235 getNodeBound(childindex, bound);
237 childindex = getRightNodeIndex(nodecount);
239 getNodeBound(childindex, bound2);
242 setNodeBound(nodecount, bound);
255 getNodeBound(0, totalbox);
261 m_primitive_manager = primitive_manager;
266 return m_primitive_manager;
271 return m_primitive_manager;
288 primitive_boxes.
resize(m_primitive_manager.get_primitive_count(),
false);
290 for (
GUINT i = 0; i < primitive_boxes.
size(); i++)
292 m_primitive_manager.get_primitive_box(i, primitive_boxes[i].m_bound);
293 primitive_boxes[i].
m_data = i;
296 m_box_tree.build_tree(primitive_boxes);
303 GUINT numNodes = getNodeCount();
305 while (curIndex < numNodes)
308 getNodeBound(curIndex, bound);
313 bool isleafnode = isLeafNode(curIndex);
315 if (isleafnode && aabbOverlap)
317 collided_results.
push_back(getNodeData(curIndex));
320 if (aabbOverlap || isleafnode)
328 curIndex += getScapeNodeIndex(curIndex);
331 if (collided_results.
size() > 0)
return true;
341 return boxQuery(transbox, collided_results);
350 GUINT numNodes = getNodeCount();
352 while (curIndex < numNodes)
355 getNodeBound(curIndex, bound);
359 bool aabbOverlap = bound.
collide_ray(ray_origin, ray_dir);
360 bool isleafnode = isLeafNode(curIndex);
362 if (isleafnode && aabbOverlap)
364 collided_results.
push_back(getNodeData(curIndex));
367 if (aabbOverlap || isleafnode)
375 curIndex += getScapeNodeIndex(curIndex);
378 if (collided_results.
size() > 0)
return true;
391 return m_primitive_manager.is_trimesh();
397 return m_box_tree.getNodeCount();
403 return m_box_tree.isLeafNode(nodeindex);
408 return m_box_tree.getNodeData(nodeindex);
413 m_box_tree.getNodeBound(nodeindex, bound);
418 m_box_tree.setNodeBound(nodeindex, bound);
423 return m_box_tree.getLeftNodeIndex(nodeindex);
428 return m_box_tree.getRightNodeIndex(nodeindex);
433 return m_box_tree.getScapeNodeIndex(nodeindex);
438 m_primitive_manager.get_primitive_triangle(getNodeData(nodeindex), triangle);
446 template <
typename _GIM_PRIMITIVE_MANAGER_PROTOTYPE>
453 template <
typename BOX_SET_CLASS0,
typename BOX_SET_CLASS1>
487 if (node0_has_triangle)
return;
488 m_boxset0->getNodeTriangle(node0, m_tri0);
495 node0_has_triangle =
true;
500 if (node1_has_triangle)
return;
501 m_boxset1->getNodeTriangle(node1, m_tri1);
508 node1_has_triangle =
true;
513 if (node0 == current_node0)
return;
514 m_boxset0->getNodeBound(node0, m_box0);
515 node0_is_leaf = m_boxset0->isLeafNode(node0);
516 node0_has_triangle =
false;
517 current_node0 = node0;
522 if (node1 == current_node1)
return;
523 m_boxset1->getNodeBound(node1, m_box1);
524 node1_is_leaf = m_boxset1->isLeafNode(node1);
525 node1_has_triangle =
false;
526 current_node1 = node1;
531 retrieve_node0_info(node0);
532 retrieve_node1_info(node1);
534 if (!result)
return false;
536 if (t0_is_trimesh && node0_is_leaf)
539 retrieve_node0_triangle(node0);
548 if (!result)
return false;
551 else if (t1_is_trimesh && node1_is_leaf)
554 retrieve_node1_triangle(node1);
563 if (!result)
return false;
578 while (stack_collisions.
size())
584 if (node_collision(node0, node1))
590 m_collision_pairs->
push_pair(m_boxset0->getNodeData(node0), m_boxset1->getNodeData(node1));
595 stack_collisions.
push_pair(node0, m_boxset1->getLeftNodeIndex(node1));
598 stack_collisions.
push_pair(node0, m_boxset1->getRightNodeIndex(node1));
606 stack_collisions.
push_pair(m_boxset0->getLeftNodeIndex(node0), node1);
608 stack_collisions.
push_pair(m_boxset0->getRightNodeIndex(node0), node1);
612 GUINT left0 = m_boxset0->getLeftNodeIndex(node0);
613 GUINT right0 = m_boxset0->getRightNodeIndex(node0);
614 GUINT left1 = m_boxset1->getLeftNodeIndex(node1);
615 GUINT right1 = m_boxset1->getRightNodeIndex(node1);
617 stack_collisions.
push_pair(left0, left1);
619 stack_collisions.
push_pair(left0, right1);
621 stack_collisions.
push_pair(right0, left1);
623 stack_collisions.
push_pair(right0, right1);
634 BOX_SET_CLASS1* boxset2,
const btTransform& trans2,
635 gim_pair_set& collision_pairs,
bool complete_primitive_tests =
true)
637 m_collision_pairs = &collision_pairs;
643 trans_cache_0to1 = trans2.
inverse();
644 trans_cache_0to1 *= trans1;
646 if (complete_primitive_tests)
648 t0_is_trimesh = boxset1->getPrimitiveManager().is_trimesh();
649 t1_is_trimesh = boxset2->getPrimitiveManager().is_trimesh();
653 t0_is_trimesh =
false;
654 t1_is_trimesh =
false;
657 find_collision_pairs();
661 #endif // GIM_BOXPRUNING_H_INCLUDED void find_collision(BOX_SET_CLASS0 *boxset1, const btTransform &trans1, BOX_SET_CLASS1 *boxset2, const btTransform &trans2, gim_pair_set &collision_pairs, bool complete_primitive_tests=true)
_GIM_PRIMITIVE_MANAGER_PROTOTYPE m_primitive_manager
GUINT m_data
primitive index if apply
BOX_SET_CLASS0 * m_boxset0
GUINT m_right
Right subtree.
bool boxQuery(const GIM_AABB &box, gim_array< GUINT > &collided_results) const
returns the indices of the primitives in the m_primitive_manager
void getNodeBound(GUINT nodeindex, GIM_AABB &bound) const
void push_pair(GUINT index1, GUINT index2)
GUINT getNodeData(GUINT nodeindex) const
bool node_collision(GUINT node0, GUINT node1)
BOX_SET_CLASS1 * m_boxset1
GUINT m_left
Left subtree.
GIM_BOX_TREE_TEMPLATE_SET()
GIM_PAIR(GUINT index1, GUINT index2)
#define G_UINT_INFINITY
A very very high value.
GUINT getScapeNodeIndex(GUINT nodeindex) const
GIM_BOX_SET collision methods.
void buildSet()
this rebuild the entire set
bool rayQuery(const btVector3 &ray_dir, const btVector3 &ray_origin, gim_array< GUINT > &collided_results) const
returns the indices of the primitives in the m_primitive_manager
#define SIMD_FORCE_INLINE
GUINT getRightNodeIndex(GUINT nodeindex) const
const _GIM_PRIMITIVE_MANAGER_PROTOTYPE & getPrimitiveManager() const
void getNodeBound(GUINT nodeindex, GIM_AABB &bound) const
GUINT getNodeCount() const
node count
void resize(GUINT size, bool call_constructor=true, const T &fillData=T())
void setPrimitiveManager(const _GIM_PRIMITIVE_MANAGER_PROTOTYPE &primitive_manager)
virtual ~GIM_PRIMITIVE_MANAGER_PROTOTYPE()
void retrieve_node0_triangle(GUINT node0)
_GIM_PRIMITIVE_MANAGER_PROTOTYPE & getPrimitiveManager()
bool collide_ray(const btVector3 &vorigin, const btVector3 &vdir)
Finds the Ray intersection parameter.
GUINT getNodeCount() const
node count
void find_collision_pairs()
GUINT getLeftNodeIndex(GUINT nodeindex) const
bool has_collision(const GIM_AABB &other) const
GUINT m_escapeIndex
Scape index for traversing.
_GIM_BOX_TREE_PROTOTYPE m_box_tree
void getNodeTriangle(GUINT nodeindex, GIM_TRIANGLE &triangle) const
Class for colliding triangles.
void update()
node manager prototype functions
void get_plane(btVector4 &plane) const
GUINT getRightNodeIndex(GUINT nodeindex) const
void retrieve_node1_info(GUINT node1)
Very simple array container with fast access and simd memory.
void setNodeBound(GUINT nodeindex, const GIM_AABB &bound)
bool is_leaf_node() const
bool isTrimesh() const
tells if this set is a trimesh
Basic Box tree structure.
GIM_BOX_BOX_TRANSFORM_CACHE trans_cache_1to0
btVector3 can be used to represent 3D points and vectors.
GUINT getNodeData(GUINT nodeindex) const
void push_pair_inv(GUINT index1, GUINT index2)
bool overlapping_trans_cache(const GIM_AABB &box, const GIM_BOX_BOX_TRANSFORM_CACHE &transcache, bool fulltest)
transcache is the transformation cache from box to this AABB
GUINT getScapeNodeIndex(GUINT nodeindex) const
void retrieve_node0_info(GUINT node0)
bool boxQueryTrans(const GIM_AABB &box, const btTransform &transform, gim_array< GUINT > &collided_results) const
returns the indices of the primitives in the m_primitive_manager
gim_pair_set * m_collision_pairs
GIM_PAIR(const GIM_PAIR &p)
void appy_transform(const btTransform &trans)
Apply a transform to an AABB.
bool isLeafNode(GUINT nodeindex) const
tells if the node is a leaf
GUINT getLeftNodeIndex(GUINT nodeindex) const
void retrieve_node1_triangle(GUINT node1)
void setNodeBound(GUINT nodeindex, const GIM_AABB &bound)
Generic Box Tree Template.
bool isLeafNode(GUINT nodeindex) const
tells if the node is a leaf
gim_array< GIM_BOX_TREE_NODE > m_node_array
Prototype Base class for primitive classification.
bool hasHierarchy() const
tells if this set has hierarcht
bool collide_triangle_exact(const btVector3 &p1, const btVector3 &p2, const btVector3 &p3, const btVector4 &triangle_plane)
test for a triangle, with edges
Node Structure for trees.
bool reserve(GUINT size)
public operations
void push_back(const T &obj)
btTransform trans_cache_0to1
void increment_margin(btScalar margin)
void merge(const GIM_AABB &box)
Merges a Box.
GIM_AABB getGlobalBox() const