aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/ode-0.9/OPCODE/OPC_Model.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/ode-0.9/OPCODE/OPC_Model.cpp')
-rw-r--r--libraries/ode-0.9/OPCODE/OPC_Model.cpp222
1 files changed, 222 insertions, 0 deletions
diff --git a/libraries/ode-0.9/OPCODE/OPC_Model.cpp b/libraries/ode-0.9/OPCODE/OPC_Model.cpp
new file mode 100644
index 0000000..8b71fb1
--- /dev/null
+++ b/libraries/ode-0.9/OPCODE/OPC_Model.cpp
@@ -0,0 +1,222 @@
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 OPCODE models.
12 * \file OPC_Model.cpp
13 * \author Pierre Terdiman
14 * \date March, 20, 2001
15 */
16///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
17
18///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
19/**
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)
25 *
26 * Usage:
27 *
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.
31 *
32 * 2) Build a Model using a creation structure:
33 *
34 * \code
35 * Model Sample;
36 *
37 * OPCODECREATE OPCC;
38 * OPCC.IMesh = ...;
39 * OPCC.Rules = ...;
40 * OPCC.NoLeaf = ...;
41 * OPCC.Quantized = ...;
42 * OPCC.KeepOriginal = ...;
43 * bool Status = Sample.Build(OPCC);
44 * \endcode
45 *
46 * 3) Create a tree collider and set it up:
47 *
48 * \code
49 * AABBTreeCollider TC;
50 * TC.SetFirstContact(...);
51 * TC.SetFullBoxBoxTest(...);
52 * TC.SetFullPrimBoxTest(...);
53 * TC.SetTemporalCoherence(...);
54 * \endcode
55 *
56 * 4) Perform a collision query
57 *
58 * \code
59 * // Setup cache
60 * static BVTCache ColCache;
61 * ColCache.Model0 = &Model0;
62 * ColCache.Model1 = &Model1;
63 *
64 * // Collision query
65 * bool IsOk = TC.Collide(ColCache, World0, World1);
66 *
67 * // Get collision status => if true, objects overlap
68 * BOOL Status = TC.GetContactStatus();
69 *
70 * // Number of colliding pairs and list of pairs
71 * udword NbPairs = TC.GetNbPairs();
72 * const Pair* p = TC.GetPairs()
73 * \endcode
74 *
75 * 5) Stats
76 *
77 * \code
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
82 * \endcode
83 *
84 * \class Model
85 * \author Pierre Terdiman
86 * \version 1.3
87 * \date March, 20, 2001
88*/
89///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
90
91///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
92// Precompiled Header
93#include "Stdafx.h"
94
95using namespace Opcode;
96
97///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
98/**
99 * Constructor.
100 */
101///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
102Model::Model()
103{
104#ifdef __MESHMERIZER_H__ // Collision hulls only supported within ICE !
105 mHull = null;
106#endif // __MESHMERIZER_H__
107}
108
109///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
110/**
111 * Destructor.
112 */
113///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
114Model::~Model()
115{
116 Release();
117}
118
119///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
120/**
121 * Releases the model.
122 */
123///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
124void Model::Release()
125{
126 ReleaseBase();
127#ifdef __MESHMERIZER_H__ // Collision hulls only supported within ICE !
128 DELETESINGLE(mHull);
129#endif // __MESHMERIZER_H__
130}
131
132///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
133/**
134 * Builds a collision model.
135 * \param create [in] model creation structure
136 * \return true if success
137 */
138///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
139bool Model::Build(const OPCODECREATE& create)
140{
141 // 1) Checkings
142 if(!create.mIMesh || !create.mIMesh->IsValid()) return false;
143
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);
146
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....
151
152 Release(); // Make sure previous tree has been discarded [Opcode 1.3, thanks Adam]
153
154 // 1-1) Setup mesh interface automatically [Opcode 1.3]
155 SetMeshInterface(create.mIMesh);
156
157 // Special case for 1-triangle meshes [Opcode 1.3]
158 udword NbTris = create.mIMesh->GetNbTriangles();
159 if(NbTris==1)
160 {
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;
164 return true;
165 }
166
167 // 2) Build a generic AABB Tree.
168 mSource = new AABBTree;
169 CHECKALLOC(mSource);
170
171 // 2-1) Setup a builder. Our primitives here are triangles from input mesh,
172 // so we use an AABBTreeOfTrianglesBuilder.....
173 {
174 AABBTreeOfTrianglesBuilder TB;
175 TB.mIMesh = create.mIMesh;
176 TB.mSettings = create.mSettings;
177 TB.mNbPrimitives = NbTris;
178 if(!mSource->Build(&TB)) return false;
179 }
180
181 // 3) Create an optimized tree according to user-settings
182 if(!CreateTree(create.mNoLeaf, create.mQuantized)) return false;
183
184 // 3-2) Create optimized tree
185 if(!mTree->Build(mSource)) return false;
186
187 // 3-3) Delete generic tree if needed
188 if(!create.mKeepOriginal) DELETESINGLE(mSource);
189
190#ifdef __MESHMERIZER_H__
191 // 4) Convex hull
192 if(create.mCollisionHull)
193 {
194 // Create hull
195 mHull = new CollisionHull;
196 CHECKALLOC(mHull);
197
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;
205 mHull->Compute(CHC);
206 }
207#endif // __MESHMERIZER_H__
208
209 return true;
210}
211
212///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
213/**
214 * Gets the number of bytes used by the tree.
215 * \return amount of bytes used
216 */
217///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
218udword Model::GetUsedBytes() const
219{
220 if(!mTree) return 0;
221 return mTree->GetUsedBytes();
222}