123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372 |
- #ifndef GIM_QUANTIZED_SET_H_INCLUDED
- #define GIM_QUANTIZED_SET_H_INCLUDED
- /*! \file btGImpactQuantizedBvh.h
- \author Francisco Leon Najera
- */
- /*
- 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.
- */
- #include "btGImpactBvh.h"
- #include "btQuantization.h"
- ///btQuantizedBvhNode is a compressed aabb node, 16 bytes.
- ///Node can be used for leafnode or internal node. Leafnodes can point to 32-bit triangle index (non-negative range).
- ATTRIBUTE_ALIGNED16 (struct) BT_QUANTIZED_BVH_NODE
- {
- //12 bytes
- unsigned short int m_quantizedAabbMin[3];
- unsigned short int m_quantizedAabbMax[3];
- //4 bytes
- int m_escapeIndexOrDataIndex;
- BT_QUANTIZED_BVH_NODE()
- {
- m_escapeIndexOrDataIndex = 0;
- }
- SIMD_FORCE_INLINE bool isLeafNode() const
- {
- //skipindex is negative (internal node), triangleindex >=0 (leafnode)
- return (m_escapeIndexOrDataIndex>=0);
- }
- SIMD_FORCE_INLINE int getEscapeIndex() const
- {
- //btAssert(m_escapeIndexOrDataIndex < 0);
- return -m_escapeIndexOrDataIndex;
- }
- SIMD_FORCE_INLINE void setEscapeIndex(int index)
- {
- m_escapeIndexOrDataIndex = -index;
- }
- SIMD_FORCE_INLINE int getDataIndex() const
- {
- //btAssert(m_escapeIndexOrDataIndex >= 0);
- return m_escapeIndexOrDataIndex;
- }
- SIMD_FORCE_INLINE void setDataIndex(int index)
- {
- m_escapeIndexOrDataIndex = index;
- }
- SIMD_FORCE_INLINE bool testQuantizedBoxOverlapp(
- unsigned short * quantizedMin,unsigned short * quantizedMax) const
- {
- if(m_quantizedAabbMin[0] > quantizedMax[0] ||
- m_quantizedAabbMax[0] < quantizedMin[0] ||
- m_quantizedAabbMin[1] > quantizedMax[1] ||
- m_quantizedAabbMax[1] < quantizedMin[1] ||
- m_quantizedAabbMin[2] > quantizedMax[2] ||
- m_quantizedAabbMax[2] < quantizedMin[2])
- {
- return false;
- }
- return true;
- }
- };
- class GIM_QUANTIZED_BVH_NODE_ARRAY:public btAlignedObjectArray<BT_QUANTIZED_BVH_NODE>
- {
- };
- //! Basic Box tree structure
- class btQuantizedBvhTree
- {
- protected:
- int m_num_nodes;
- GIM_QUANTIZED_BVH_NODE_ARRAY m_node_array;
- btAABB m_global_bound;
- btVector3 m_bvhQuantization;
- protected:
- void calc_quantization(GIM_BVH_DATA_ARRAY & primitive_boxes, btScalar boundMargin = btScalar(1.0) );
- int _sort_and_calc_splitting_index(
- GIM_BVH_DATA_ARRAY & primitive_boxes,
- int startIndex, int endIndex, int splitAxis);
- int _calc_splitting_axis(GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex);
- void _build_sub_tree(GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex);
- public:
- btQuantizedBvhTree()
- {
- m_num_nodes = 0;
- }
- //! prototype functions for box tree management
- //!@{
- void build_tree(GIM_BVH_DATA_ARRAY & primitive_boxes);
- SIMD_FORCE_INLINE void quantizePoint(
- unsigned short * quantizedpoint, const btVector3 & point) const
- {
- bt_quantize_clamp(quantizedpoint,point,m_global_bound.m_min,m_global_bound.m_max,m_bvhQuantization);
- }
- SIMD_FORCE_INLINE bool testQuantizedBoxOverlapp(
- int node_index,
- unsigned short * quantizedMin,unsigned short * quantizedMax) const
- {
- return m_node_array[node_index].testQuantizedBoxOverlapp(quantizedMin,quantizedMax);
- }
- SIMD_FORCE_INLINE void clearNodes()
- {
- m_node_array.clear();
- m_num_nodes = 0;
- }
- //! node count
- SIMD_FORCE_INLINE int getNodeCount() const
- {
- return m_num_nodes;
- }
- //! tells if the node is a leaf
- SIMD_FORCE_INLINE bool isLeafNode(int nodeindex) const
- {
- return m_node_array[nodeindex].isLeafNode();
- }
- SIMD_FORCE_INLINE int getNodeData(int nodeindex) const
- {
- return m_node_array[nodeindex].getDataIndex();
- }
- SIMD_FORCE_INLINE void getNodeBound(int nodeindex, btAABB & bound) const
- {
- bound.m_min = bt_unquantize(
- m_node_array[nodeindex].m_quantizedAabbMin,
- m_global_bound.m_min,m_bvhQuantization);
- bound.m_max = bt_unquantize(
- m_node_array[nodeindex].m_quantizedAabbMax,
- m_global_bound.m_min,m_bvhQuantization);
- }
- SIMD_FORCE_INLINE void setNodeBound(int nodeindex, const btAABB & bound)
- {
- bt_quantize_clamp( m_node_array[nodeindex].m_quantizedAabbMin,
- bound.m_min,
- m_global_bound.m_min,
- m_global_bound.m_max,
- m_bvhQuantization);
- bt_quantize_clamp( m_node_array[nodeindex].m_quantizedAabbMax,
- bound.m_max,
- m_global_bound.m_min,
- m_global_bound.m_max,
- m_bvhQuantization);
- }
- SIMD_FORCE_INLINE int getLeftNode(int nodeindex) const
- {
- return nodeindex+1;
- }
- SIMD_FORCE_INLINE int getRightNode(int nodeindex) const
- {
- if(m_node_array[nodeindex+1].isLeafNode()) return nodeindex+2;
- return nodeindex+1 + m_node_array[nodeindex+1].getEscapeIndex();
- }
- SIMD_FORCE_INLINE int getEscapeNodeIndex(int nodeindex) const
- {
- return m_node_array[nodeindex].getEscapeIndex();
- }
- SIMD_FORCE_INLINE const BT_QUANTIZED_BVH_NODE * get_node_pointer(int index = 0) const
- {
- return &m_node_array[index];
- }
- //!@}
- };
- //! Structure for containing Boxes
- /*!
- This class offers an structure for managing a box tree of primitives.
- Requires a Primitive prototype (like btPrimitiveManagerBase )
- */
- class btGImpactQuantizedBvh
- {
- protected:
- btQuantizedBvhTree m_box_tree;
- btPrimitiveManagerBase * m_primitive_manager;
- protected:
- //stackless refit
- void refit();
- public:
- //! this constructor doesn't build the tree. you must call buildSet
- btGImpactQuantizedBvh()
- {
- m_primitive_manager = NULL;
- }
- //! this constructor doesn't build the tree. you must call buildSet
- btGImpactQuantizedBvh(btPrimitiveManagerBase * primitive_manager)
- {
- m_primitive_manager = primitive_manager;
- }
- SIMD_FORCE_INLINE btAABB getGlobalBox() const
- {
- btAABB totalbox;
- getNodeBound(0, totalbox);
- return totalbox;
- }
- SIMD_FORCE_INLINE void setPrimitiveManager(btPrimitiveManagerBase * primitive_manager)
- {
- m_primitive_manager = primitive_manager;
- }
- SIMD_FORCE_INLINE btPrimitiveManagerBase * getPrimitiveManager() const
- {
- return m_primitive_manager;
- }
- //! node manager prototype functions
- ///@{
- //! this attemps to refit the box set.
- SIMD_FORCE_INLINE void update()
- {
- refit();
- }
- //! this rebuild the entire set
- void buildSet();
- //! returns the indices of the primitives in the m_primitive_manager
- bool boxQuery(const btAABB & box, btAlignedObjectArray<int> & collided_results) const;
- //! returns the indices of the primitives in the m_primitive_manager
- SIMD_FORCE_INLINE bool boxQueryTrans(const btAABB & box,
- const btTransform & transform, btAlignedObjectArray<int> & collided_results) const
- {
- btAABB transbox=box;
- transbox.appy_transform(transform);
- return boxQuery(transbox,collided_results);
- }
- //! returns the indices of the primitives in the m_primitive_manager
- bool rayQuery(
- const btVector3 & ray_dir,const btVector3 & ray_origin ,
- btAlignedObjectArray<int> & collided_results) const;
- //! tells if this set has hierarcht
- SIMD_FORCE_INLINE bool hasHierarchy() const
- {
- return true;
- }
- //! tells if this set is a trimesh
- SIMD_FORCE_INLINE bool isTrimesh() const
- {
- return m_primitive_manager->is_trimesh();
- }
- //! node count
- SIMD_FORCE_INLINE int getNodeCount() const
- {
- return m_box_tree.getNodeCount();
- }
- //! tells if the node is a leaf
- SIMD_FORCE_INLINE bool isLeafNode(int nodeindex) const
- {
- return m_box_tree.isLeafNode(nodeindex);
- }
- SIMD_FORCE_INLINE int getNodeData(int nodeindex) const
- {
- return m_box_tree.getNodeData(nodeindex);
- }
- SIMD_FORCE_INLINE void getNodeBound(int nodeindex, btAABB & bound) const
- {
- m_box_tree.getNodeBound(nodeindex, bound);
- }
- SIMD_FORCE_INLINE void setNodeBound(int nodeindex, const btAABB & bound)
- {
- m_box_tree.setNodeBound(nodeindex, bound);
- }
- SIMD_FORCE_INLINE int getLeftNode(int nodeindex) const
- {
- return m_box_tree.getLeftNode(nodeindex);
- }
- SIMD_FORCE_INLINE int getRightNode(int nodeindex) const
- {
- return m_box_tree.getRightNode(nodeindex);
- }
- SIMD_FORCE_INLINE int getEscapeNodeIndex(int nodeindex) const
- {
- return m_box_tree.getEscapeNodeIndex(nodeindex);
- }
- SIMD_FORCE_INLINE void getNodeTriangle(int nodeindex,btPrimitiveTriangle & triangle) const
- {
- m_primitive_manager->get_primitive_triangle(getNodeData(nodeindex),triangle);
- }
- SIMD_FORCE_INLINE const BT_QUANTIZED_BVH_NODE * get_node_pointer(int index = 0) const
- {
- return m_box_tree.get_node_pointer(index);
- }
- #ifdef TRI_COLLISION_PROFILING
- static float getAverageTreeCollisionTime();
- #endif //TRI_COLLISION_PROFILING
- static void find_collision(const btGImpactQuantizedBvh * boxset1, const btTransform & trans1,
- const btGImpactQuantizedBvh * boxset2, const btTransform & trans2,
- btPairSet & collision_pairs);
- };
- #endif // GIM_BOXPRUNING_H_INCLUDED
|