2 * OPCODE - Optimized Collision Detection
3 * http://www.codercorner.com/Opcode.htm
5 * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com
7 This software is provided 'as-is', without any express or implied warranty.
8 In no event will the authors be held liable for any damages arising from the use of this software.
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it freely,
11 subject to the following restrictions:
13 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.
14 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
15 3. This notice may not be removed or altered from any source distribution.
18 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
20 * Contains code for OPCODE models.
22 * \author Pierre Terdiman
23 * \date March, 20, 2001
25 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
27 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
29 * The main collision wrapper, for all trees. Supported trees are:
30 * - Normal trees (2*N-1 nodes, full size)
31 * - No-leaf trees (N-1 nodes, full size)
32 * - Quantized trees (2*N-1 nodes, half size)
33 * - Quantized no-leaf trees (N-1 nodes, half size)
37 * 1) Create a static mesh interface using callbacks or pointers. (see OPC_MeshInterface.cpp).
38 * Keep it around in your app, since a pointer to this interface is saved internally and
39 * used until you release the collision structures.
41 * 2) Build a Model using a creation structure:
50 * OPCC.Quantized = ...;
51 * OPCC.KeepOriginal = ...;
52 * bool Status = Sample.Build(OPCC);
55 * 3) Create a tree collider and set it up:
58 * AABBTreeCollider TC;
59 * TC.SetFirstContact(...);
60 * TC.SetFullBoxBoxTest(...);
61 * TC.SetFullPrimBoxTest(...);
62 * TC.SetTemporalCoherence(...);
65 * 4) Perform a collision query
69 * static BVTCache ColCache;
70 * ColCache.Model0 = &Model0;
71 * ColCache.Model1 = &Model1;
74 * bool IsOk = TC.Collide(ColCache, World0, World1);
76 * // Get collision status => if true, objects overlap
77 * BOOL Status = TC.GetContactStatus();
79 * // Number of colliding pairs and list of pairs
80 * udword NbPairs = TC.GetNbPairs();
81 * const Pair* p = TC.GetPairs()
87 * Model0.GetUsedBytes() = number of bytes used for this collision tree
88 * TC.GetNbBVBVTests() = number of BV-BV overlap tests performed during last query
89 * TC.GetNbPrimPrimTests() = number of Triangle-Triangle overlap tests performed during last query
90 * TC.GetNbBVPrimTests() = number of Triangle-BV overlap tests performed during last query
94 * \author Pierre Terdiman
96 * \date March, 20, 2001
98 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
100 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
101 // Precompiled Header
104 using namespace Opcode;
106 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
110 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
113 #ifdef __MESHMERIZER_H__ // Collision hulls only supported within ICE !
115 #endif // __MESHMERIZER_H__
118 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
122 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
128 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
130 * Releases the model.
132 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
133 void Model::Release()
136 #ifdef __MESHMERIZER_H__ // Collision hulls only supported within ICE !
138 #endif // __MESHMERIZER_H__
141 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
143 * Builds a collision model.
144 * \param create [in] model creation structure
145 * \return true if success
147 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
148 bool Model::Build(const OPCODECREATE& create)
151 if(!create.mIMesh || !create.mIMesh->IsValid()) return false;
153 // For this model, we only support complete trees
154 if(create.mSettings.mLimit!=1) return SetIceError("OPCODE WARNING: supports complete trees only! Use mLimit = 1.\n", null);
156 // Look for degenerate faces.
157 udword NbDegenerate = create.mIMesh->CheckTopology();
158 if(NbDegenerate) Log("OPCODE WARNING: found %d degenerate faces in model! Collision might report wrong results!\n", NbDegenerate);
159 // We continue nonetheless....
161 Release(); // Make sure previous tree has been discarded [Opcode 1.3, thanks Adam]
163 // 1-1) Setup mesh interface automatically [Opcode 1.3]
164 SetMeshInterface(create.mIMesh);
166 // Special case for 1-triangle meshes [Opcode 1.3]
167 udword NbTris = create.mIMesh->GetNbTriangles();
170 // We don't need to actually create a tree here, since we'll only have a single triangle to deal with anyway.
171 // It's a waste to use a "model" for this but at least it will work.
172 mModelCode |= OPC_SINGLE_NODE;
176 // 2) Build a generic AABB Tree.
177 mSource = new AABBTree;
180 // 2-1) Setup a builder. Our primitives here are triangles from input mesh,
181 // so we use an AABBTreeOfTrianglesBuilder.....
183 AABBTreeOfTrianglesBuilder TB;
184 TB.mIMesh = create.mIMesh;
185 TB.mSettings = create.mSettings;
186 TB.mNbPrimitives = NbTris;
187 if(!mSource->Build(&TB)) return false;
190 // 3) Create an optimized tree according to user-settings
191 if(!CreateTree(create.mNoLeaf, create.mQuantized)) return false;
193 // 3-2) Create optimized tree
194 if(!mTree->Build(mSource)) return false;
196 // 3-3) Delete generic tree if needed
197 if(!create.mKeepOriginal) DELETESINGLE(mSource);
199 #ifdef __MESHMERIZER_H__
201 if(create.mCollisionHull)
204 mHull = new CollisionHull;
207 CONVEXHULLCREATE CHC;
208 // ### doesn't work with strides
209 CHC.NbVerts = create.mIMesh->GetNbVertices();
210 CHC.Vertices = create.mIMesh->GetVerts();
211 CHC.UnifyNormals = true;
212 CHC.ReduceVertices = true;
213 CHC.WordFaces = false;
216 #endif // __MESHMERIZER_H__
221 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
223 * Gets the number of bytes used by the tree.
224 * \return amount of bytes used
226 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
227 udword Model::GetUsedBytes() const
230 return mTree->GetUsedBytes();