Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/ode/ode-0.9/OPCODE/OPC_Model.cpp @ 216

Last change on this file since 216 was 216, checked in by mathiask, 16 years ago

[Physik] add ode-0.9

File size: 8.4 KB
Line 
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}
Note: See TracBrowser for help on using the repository browser.