~choreonoid/choreonoid/debian

« back to all changes in this revision

Viewing changes to src/Collision/Opcode/OPC_OptimizedTree.h

  • Committer: Thomas Moulard
  • Date: 2012-10-23 12:43:24 UTC
  • Revision ID: git-v1:351cf736ad49bc7a9a7b9767dee760a013517a5d
Tags: upstream/1.1.0
ImportedĀ UpstreamĀ versionĀ 1.1.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
2
/*
 
3
 *      OPCODE - Optimized Collision Detection
 
4
 *      Copyright (C) 2001 Pierre Terdiman
 
5
 *      Homepage: http://www.codercorner.com/Opcode.htm
 
6
 */
 
7
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
8
 
 
9
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
10
/**
 
11
 *      Contains code for optimized trees.
 
12
 *      \file           OPC_OptimizedTree.h
 
13
 *      \author         Pierre Terdiman
 
14
 *      \date           March, 20, 2001
 
15
 */
 
16
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
17
 
 
18
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
19
// Include Guard
 
20
#ifndef __OPC_OPTIMIZEDTREE_H__
 
21
#define __OPC_OPTIMIZEDTREE_H__
 
22
 
 
23
#ifdef __x86_64
 
24
#define EXWORD uqword
 
25
#else
 
26
#define EXWORD udword
 
27
#endif
 
28
 
 
29
        //! Common interface for a node of an implicit tree
 
30
        #define IMPLEMENT_IMPLICIT_NODE(base_class, volume)                                                                                                             \
 
31
                public:                                                                                                                                                                                         \
 
32
                /* Constructor / Destructor */                                                                                                                                          \
 
33
                inline_                                                         base_class() : mData(0) {}                                                                              \
 
34
                inline_                                                         ~base_class()                   {}                                                                              \
 
35
                /* Leaf test */                                                                                                                                                                         \
 
36
                inline_                 BOOL                            IsLeaf()                const   { return mData&1;                                       }       \
 
37
                /* Data access */                                                                                                                                                                       \
 
38
                inline_                 const base_class*       GetPos()                const   { return (base_class*)mData;            }       \
 
39
                inline_                 const base_class*       GetNeg()                const   { return ((base_class*)mData)+1;        }       \
 
40
                /* Modified by S-cubed, Inc. */                                                                                                                                         \
 
41
                inline_                 const base_class*       GetB()                  const   { return                                mB;             }       \
 
42
                inline_                 udword                          GetPrimitive()  const   { return (mData>>1);                            }       \
 
43
                /* Stats */                                                                                                                                                                                     \
 
44
                inline_                 udword                          GetNodeSize()   const   { return SIZEOFOBJECT;                          }       \
 
45
                                                                                                                                                                                                                        \
 
46
                                                volume                          mAABB;                                                                                                                  \
 
47
                                                EXWORD                          mData;                                                                                                                  \
 
48
                /* Modified by S-cubed, Inc. */                                                                                                                                         \
 
49
                                                base_class*                     mB;                                                                                                                             
 
50
 
 
51
        //! Common interface for a node of a no-leaf tree
 
52
        #define IMPLEMENT_NOLEAF_NODE(base_class, volume)                                                                                                               \
 
53
                public:                                                                                                                                                                                         \
 
54
                /* Constructor / Destructor */                                                                                                                                          \
 
55
                inline_                                                         base_class() : mPosData(0), mNegData(0) {}                                              \
 
56
                inline_                                                         ~base_class()                                                   {}                                              \
 
57
                /* Leaf tests */                                                                                                                                                                        \
 
58
                inline_                 BOOL                            HasPosLeaf()            const   { return mPosData&1;                    }       \
 
59
                inline_                 BOOL                            HasNegLeaf()            const   { return mNegData&1;                    }       \
 
60
                /* Data access */                                                                                                                                                                       \
 
61
                inline_                 const base_class*       GetPos()                        const   { return (base_class*)mPosData; }       \
 
62
                inline_                 const base_class*       GetNeg()                        const   { return (base_class*)mNegData; }       \
 
63
                /* Modified by S-cubed, Inc. */                                                                                                                                         \
 
64
                inline_                 const base_class*       GetB()                          const   { return                                mB;             }       \
 
65
                inline_                 udword                          GetPosPrimitive()       const   { return (mPosData>>1);                 }       \
 
66
                inline_                 udword                          GetNegPrimitive()       const   { return (mNegData>>1);                 }       \
 
67
                /* Stats */                                                                                                                                                                                     \
 
68
                inline_                 udword                          GetNodeSize()           const   { return SIZEOFOBJECT;                  }       \
 
69
                                                                                                                                                                                                                        \
 
70
                                                volume                          mAABB;                                                                                                                  \
 
71
                                                EXWORD                          mPosData;                                                                                                               \
 
72
                                                EXWORD                          mNegData;                                                                                                               \
 
73
                /* Modified by S-cubed, Inc. */                                                                                                                                         \
 
74
                                                base_class*                     mB;                                                                                                                             
 
75
 
 
76
        class OPCODE_API AABBCollisionNode
 
77
        {
 
78
                IMPLEMENT_IMPLICIT_NODE(AABBCollisionNode, CollisionAABB)
 
79
 
 
80
                inline_                 float                           GetVolume()             const   { return mAABB.mExtents.x * mAABB.mExtents.y * mAABB.mExtents.z;        }
 
81
                inline_                 float                           GetSize()               const   { return mAABB.mExtents.SquareMagnitude();      }
 
82
                inline_                 udword                          GetRadius()             const
 
83
                                                                                        {
 
84
                                                                                                udword* Bits = (udword*)&mAABB.mExtents.x;
 
85
                                                                                                udword Max = Bits[0];
 
86
                                                                                                if(Bits[1]>Max) Max = Bits[1];
 
87
                                                                                                if(Bits[2]>Max) Max = Bits[2];
 
88
                                                                                                return Max;
 
89
                                                                                        }
 
90
 
 
91
                // NB: using the square-magnitude or the true volume of the box, seems to yield better results
 
92
                // (assuming UNC-like informed traversal methods). I borrowed this idea from PQP. The usual "size"
 
93
                // otherwise, is the largest box extent. In SOLID that extent is computed on-the-fly each time it's
 
94
                // needed (the best approach IMHO). In RAPID the rotation matrix is permuted so that Extent[0] is
 
95
                // always the greatest, which saves looking for it at runtime. On the other hand, it yields matrices
 
96
                // whose determinant is not 1, i.e. you can't encode them anymore as unit quaternions. Not a very
 
97
                // good strategy.
 
98
        };
 
99
 
 
100
        class OPCODE_API AABBQuantizedNode
 
101
        {
 
102
                IMPLEMENT_IMPLICIT_NODE(AABBQuantizedNode, QuantizedAABB)
 
103
 
 
104
                inline_                 uword                           GetSize()               const
 
105
                                                                                        {
 
106
                                                                                                const uword* Bits = mAABB.mExtents;
 
107
                                                                                                uword Max = Bits[0];
 
108
                                                                                                if(Bits[1]>Max) Max = Bits[1];
 
109
                                                                                                if(Bits[2]>Max) Max = Bits[2];
 
110
                                                                                                return Max;
 
111
                                                                                        }
 
112
                // NB: for quantized nodes I don't feel like computing a square-magnitude with integers all
 
113
                // over the place.......!
 
114
        };
 
115
 
 
116
        class OPCODE_API AABBNoLeafNode
 
117
        {
 
118
                IMPLEMENT_NOLEAF_NODE(AABBNoLeafNode, CollisionAABB)
 
119
        };
 
120
 
 
121
        class OPCODE_API AABBQuantizedNoLeafNode
 
122
        {
 
123
                IMPLEMENT_NOLEAF_NODE(AABBQuantizedNoLeafNode, QuantizedAABB)
 
124
        };
 
125
 
 
126
        //! Common interface for a collision tree
 
127
        #define IMPLEMENT_COLLISION_TREE(base_class, node)                                                                                                                              \
 
128
                public:                                                                                                                                                                                                         \
 
129
                /* Constructor / Destructor */                                                                                                                                                          \
 
130
                                                                                                        base_class();                                                                                                   \
 
131
                virtual                                                                         ~base_class();                                                                                                  \
 
132
                /* Builds from a standard tree */                                                                                                                                                       \
 
133
                override(AABBOptimizedTree)     bool                    Build(AABBTree* tree);                                                                                  \
 
134
                /* Refits the tree */                                                                                                                                                                           \
 
135
                override(AABBOptimizedTree)     bool                    Refit(const MeshInterface* mesh_interface);                                             \
 
136
                /* Walks the tree */                                                                                                                                                                            \
 
137
                override(AABBOptimizedTree)     bool                    Walk(GenericWalkingCallback callback, void* user_data) const;   \
 
138
                /* Data access */                                                                                                                                                                                       \
 
139
                inline_                                         const node*             GetNodes()              const   { return mNodes;                                        }       \
 
140
                /* Stats */                                                                                                                                                                                                     \
 
141
                override(AABBOptimizedTree)     udword                  GetUsedBytes()  const   { return mNbNodes*sizeof(node);         }       \
 
142
                private:                                                                                                                                                                                                        \
 
143
                                                                        node*                   mNodes;
 
144
 
 
145
        typedef         bool                            (*GenericWalkingCallback)       (const void* current, void* user_data);
 
146
 
 
147
        class OPCODE_API AABBOptimizedTree
 
148
        {
 
149
                public:
 
150
                // Constructor / Destructor
 
151
                                                                                        AABBOptimizedTree() :
 
152
                                                                                                mNbNodes        (0)
 
153
                                                                                                                                                                                        {}
 
154
                virtual                                                         ~AABBOptimizedTree()                                                    {}
 
155
 
 
156
                ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
157
                /**
 
158
                 *      Builds the collision tree from a generic AABB tree.
 
159
                 *      \param          tree                    [in] generic AABB tree
 
160
                 *      \return         true if success
 
161
                 */
 
162
                ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
163
                virtual                 bool                            Build(AABBTree* tree)                                                                                   = 0;
 
164
 
 
165
                ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
166
                /**
 
167
                 *      Refits the collision tree after vertices have been modified.
 
168
                 *      \param          mesh_interface  [in] mesh interface for current model
 
169
                 *      \return         true if success
 
170
                 */
 
171
                ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
172
                virtual                 bool                            Refit(const MeshInterface* mesh_interface)                                              = 0;
 
173
 
 
174
                ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
175
                /**
 
176
                 *      Walks the tree and call the user back for each node.
 
177
                 *      \param          callback        [in] walking callback
 
178
                 *      \param          user_data       [in] callback's user data
 
179
                 *      \return         true if success
 
180
                 */
 
181
                ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
182
                virtual                 bool                            Walk(GenericWalkingCallback callback, void* user_data) const    = 0;
 
183
 
 
184
                // Data access
 
185
                virtual                 udword                          GetUsedBytes()          const                                                                           = 0;
 
186
                inline_                 udword                          GetNbNodes()            const                                           { return mNbNodes;      }
 
187
 
 
188
                protected:
 
189
                                                udword                          mNbNodes;
 
190
        };
 
191
 
 
192
        class OPCODE_API AABBCollisionTree : public AABBOptimizedTree
 
193
        {
 
194
                IMPLEMENT_COLLISION_TREE(AABBCollisionTree, AABBCollisionNode)
 
195
        };
 
196
 
 
197
        class OPCODE_API AABBNoLeafTree : public AABBOptimizedTree
 
198
        {
 
199
                IMPLEMENT_COLLISION_TREE(AABBNoLeafTree, AABBNoLeafNode)
 
200
        };
 
201
 
 
202
        class OPCODE_API AABBQuantizedTree : public AABBOptimizedTree
 
203
        {
 
204
                IMPLEMENT_COLLISION_TREE(AABBQuantizedTree, AABBQuantizedNode)
 
205
 
 
206
                public:
 
207
                                                Point                           mCenterCoeff;
 
208
                                                Point                           mExtentsCoeff;
 
209
        };
 
210
 
 
211
        class OPCODE_API AABBQuantizedNoLeafTree : public AABBOptimizedTree
 
212
        {
 
213
                IMPLEMENT_COLLISION_TREE(AABBQuantizedNoLeafTree, AABBQuantizedNoLeafNode)
 
214
 
 
215
                public:
 
216
                                                Point                           mCenterCoeff;
 
217
                                                Point                           mExtentsCoeff;
 
218
        };
 
219
 
 
220
#endif // __OPC_OPTIMIZEDTREE_H__