1 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3 * OPCODE - Optimized Collision Detection
4 * Copyright (C) 2001 Pierre Terdiman
5 * Homepage: http://www.codercorner.com/Opcode.htm
7 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11 * Contains code for OPCODE models.
13 * \author Pierre Terdiman
14 * \date March, 20, 2001
16 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
18 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
20 * The main collision wrapper, for all trees. Supported trees are:
21 * - Normal trees (2*N-1 nodes, full size)
22 * - No-leaf trees (N-1 nodes, full size)
23 * - Quantized trees (2*N-1 nodes, half size)
24 * - Quantized no-leaf trees (N-1 nodes, half size)
28 * 1) Create a static mesh interface using callbacks or pointers. (see OPC_MeshInterface.cpp).
29 * Keep it around in your app, since a pointer to this interface is saved internally and
30 * used until you release the collision structures.
32 * 2) Build a Model using a creation structure:
41 * OPCC.Quantized = ...;
42 * OPCC.KeepOriginal = ...;
43 * bool Status = Sample.Build(OPCC);
46 * 3) Create a tree collider and set it up:
49 * AABBTreeCollider TC;
50 * TC.SetFirstContact(...);
51 * TC.SetFullBoxBoxTest(...);
52 * TC.SetFullPrimBoxTest(...);
53 * TC.SetTemporalCoherence(...);
56 * 4) Perform a collision query
60 * static BVTCache ColCache;
61 * ColCache.Model0 = &Model0;
62 * ColCache.Model1 = &Model1;
65 * bool IsOk = TC.Collide(ColCache, World0, World1);
67 * // Get collision status => if true, objects overlap
68 * BOOL Status = TC.GetContactStatus();
70 * // Number of colliding pairs and list of pairs
71 * udword NbPairs = TC.GetNbPairs();
72 * const Pair* p = TC.GetPairs()
78 * Model0.GetUsedBytes() = number of bytes used for this collision tree
79 * TC.GetNbBVBVTests() = number of BV-BV overlap tests performed during last query
80 * TC.GetNbPrimPrimTests() = number of Triangle-Triangle overlap tests performed during last query
81 * TC.GetNbBVPrimTests() = number of Triangle-BV overlap tests performed during last query
85 * \author Pierre Terdiman
87 * \date March, 20, 2001
89 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
91 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
95 using namespace Opcode
;
97 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
101 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
104 #ifdef __MESHMERIZER_H__ // Collision hulls only supported within ICE !
106 #endif // __MESHMERIZER_H__
109 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
113 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
119 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
121 * Releases the model.
123 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
124 void Model::Release()
127 #ifdef __MESHMERIZER_H__ // Collision hulls only supported within ICE !
129 #endif // __MESHMERIZER_H__
132 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
134 * Builds a collision model.
135 * \param create [in] model creation structure
136 * \return true if success
138 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
139 bool Model::Build(const OPCODECREATE
& create
)
142 if(!create
.mIMesh
|| !create
.mIMesh
->IsValid()) return false;
144 // For this model, we only support complete trees
145 if(create
.mSettings
.mLimit
!=1) return SetIceError("OPCODE WARNING: supports complete trees only! Use mLimit = 1.\n", null
);
147 // Look for degenerate faces.
148 //udword NbDegenerate = create.mIMesh->CheckTopology();
149 //if(NbDegenerate) Log("OPCODE WARNING: found %d degenerate faces in model! Collision might report wrong results!\n", NbDegenerate);
150 // We continue nonetheless....
152 Release(); // Make sure previous tree has been discarded [Opcode 1.3, thanks Adam]
154 // 1-1) Setup mesh interface automatically [Opcode 1.3]
155 SetMeshInterface(create
.mIMesh
);
157 // Special case for 1-triangle meshes [Opcode 1.3]
158 udword NbTris
= create
.mIMesh
->GetNbTriangles();
161 // We don't need to actually create a tree here, since we'll only have a single triangle to deal with anyway.
162 // It's a waste to use a "model" for this but at least it will work.
163 mModelCode
|= OPC_SINGLE_NODE
;
167 // 2) Build a generic AABB Tree.
168 mSource
= new AABBTree
;
171 // 2-1) Setup a builder. Our primitives here are triangles from input mesh,
172 // so we use an AABBTreeOfTrianglesBuilder.....
174 AABBTreeOfTrianglesBuilder TB
;
175 TB
.mIMesh
= create
.mIMesh
;
176 TB
.mSettings
= create
.mSettings
;
177 TB
.mNbPrimitives
= NbTris
;
178 if(!mSource
->Build(&TB
)) return false;
181 // 3) Create an optimized tree according to user-settings
182 if(!CreateTree(create
.mNoLeaf
, create
.mQuantized
)) return false;
184 // 3-2) Create optimized tree
185 if(!mTree
->Build(mSource
)) return false;
187 // 3-3) Delete generic tree if needed
188 if(!create
.mKeepOriginal
) DELETESINGLE(mSource
);
190 #ifdef __MESHMERIZER_H__
192 if(create
.mCollisionHull
)
195 mHull
= new CollisionHull
;
198 CONVEXHULLCREATE CHC
;
199 // ### doesn't work with strides
200 CHC
.NbVerts
= create
.mIMesh
->GetNbVertices();
201 CHC
.Vertices
= create
.mIMesh
->GetVerts();
202 CHC
.UnifyNormals
= true;
203 CHC
.ReduceVertices
= true;
204 CHC
.WordFaces
= false;
207 #endif // __MESHMERIZER_H__
212 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
214 * Gets the number of bytes used by the tree.
215 * \return amount of bytes used
217 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
218 udword
Model::GetUsedBytes() const
221 return mTree
->GetUsedBytes();