Open Dynamics Engine
collision_kernel.h
1 /*************************************************************************
2  * *
3  * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. *
4  * All rights reserved. Email: russ@q12.org Web: www.q12.org *
5  * *
6  * This library is free software; you can redistribute it and/or *
7  * modify it under the terms of EITHER: *
8  * (1) The GNU Lesser General Public License as published by the Free *
9  * Software Foundation; either version 2.1 of the License, or (at *
10  * your option) any later version. The text of the GNU Lesser *
11  * General Public License is included with this library in the *
12  * file LICENSE.TXT. *
13  * (2) The BSD-style license that is included with this library in *
14  * the file LICENSE-BSD.TXT. *
15  * *
16  * This library is distributed in the hope that it will be useful, *
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
19  * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
20  * *
21  *************************************************************************/
22 
23 /*
24 
25 internal data structures and functions for collision detection.
26 
27 */
28 
29 #ifndef _ODE_COLLISION_KERNEL_H_
30 #define _ODE_COLLISION_KERNEL_H_
31 
32 #include <ode/common.h>
33 #include <ode/contact.h>
34 #include <ode/collision.h>
35 #include "objects.h"
36 #include "odetls.h"
37 
38 //****************************************************************************
39 // constants and macros
40 
41 // mask for the number-of-contacts field in the dCollide() flags parameter
42 #define NUMC_MASK (0xffff)
43 
44 #define IS_SPACE(geom) \
45  ((geom)->type >= dFirstSpaceClass && (geom)->type <= dLastSpaceClass)
46 
47 //****************************************************************************
48 // geometry object base class
49 
50 
51 // geom flags.
52 //
53 // GEOM_DIRTY means that the space data structures for this geom are
54 // potentially not up to date. NOTE THAT all space parents of a dirty geom
55 // are themselves dirty. this is an invariant that must be enforced.
56 //
57 // GEOM_AABB_BAD means that the cached AABB for this geom is not up to date.
58 // note that GEOM_DIRTY does not imply GEOM_AABB_BAD, as the geom might
59 // recalculate its own AABB but does not know how to update the space data
60 // structures for the space it is in. but GEOM_AABB_BAD implies GEOM_DIRTY.
61 // the valid combinations are:
62 // 0
63 // GEOM_DIRTY
64 // GEOM_DIRTY|GEOM_AABB_BAD
65 // GEOM_DIRTY|GEOM_AABB_BAD|GEOM_POSR_BAD
66 
67 enum {
68  GEOM_DIRTY = 1, // geom is 'dirty', i.e. position unknown
69  GEOM_POSR_BAD = 2, // geom's final posr is not valid
70  GEOM_AABB_BAD = 4, // geom's AABB is not valid
71  GEOM_PLACEABLE = 8, // geom is placeable
72  GEOM_ENABLED = 16, // geom is enabled
73  GEOM_ZERO_SIZED = 32, // geom is zero sized
74 
75  GEOM_ENABLE_TEST_MASK = GEOM_ENABLED | GEOM_ZERO_SIZED,
76  GEOM_ENABLE_TEST_VALUE = GEOM_ENABLED,
77 
78  // Ray specific
79  RAY_FIRSTCONTACT = 0x10000,
80  RAY_BACKFACECULL = 0x20000,
81  RAY_CLOSEST_HIT = 0x40000
82 };
83 
84 enum dxContactMergeOptions {
85  DONT_MERGE_CONTACTS,
86  MERGE_CONTACT_NORMALS,
87  MERGE_CONTACTS_FULLY
88 };
89 
90 
91 // geometry object base class. pos and R will either point to a separately
92 // allocated buffer (if body is 0 - pos points to the dxPosR object) or to
93 // the pos and R of the body (if body nonzero).
94 // a dGeomID is a pointer to this object.
95 
96 struct dxGeom : public dBase {
97  int type; // geom type number, set by subclass constructor
98  int gflags; // flags used by geom and space
99  void *data; // user-defined data pointer
100  dBodyID body; // dynamics body associated with this object (if any)
101  dxGeom *body_next; // next geom in body's linked list of associated geoms
102  dxPosR *final_posr; // final position of the geom in world coordinates
103  dxPosR *offset_posr; // offset from body in local coordinates
104 
105  // information used by spaces
106  dxGeom *next; // next geom in linked list of geoms
107  dxGeom **tome; // linked list backpointer
108  dxGeom *next_ex; // next geom in extra linked list of geoms (for higher level structures)
109  dxGeom **tome_ex; // extra linked list backpointer (for higher level structures)
110  dxSpace *parent_space;// the space this geom is contained in, 0 if none
111  dReal aabb[6]; // cached AABB for this space
112  unsigned long category_bits,collide_bits;
113 
114  dxGeom (dSpaceID _space, int is_placeable);
115  virtual ~dxGeom();
116 
117  // Set or clear GEOM_ZERO_SIZED flag
118  void updateZeroSizedFlag(bool is_zero_sized) { gflags = is_zero_sized ? (gflags | GEOM_ZERO_SIZED) : (gflags & ~GEOM_ZERO_SIZED); }
119  // Get parent space TLS kind
120  unsigned getParentSpaceTLSKind() const;
121 
122  // calculate our new final position from our offset and body
123  void computePosr();
124 
125  // recalculate our new final position if needed
126  void recomputePosr()
127  {
128  if (gflags & GEOM_POSR_BAD) {
129  computePosr();
130  gflags &= ~GEOM_POSR_BAD;
131  }
132  }
133 
134  bool checkControlValueSizeValidity(void *dataValue, int *dataSize, int iRequiresSize) { return (*dataSize == iRequiresSize && dataValue != 0) ? true : !(*dataSize = iRequiresSize); } // Here it is the intent to return true for 0 required size in any case
135  virtual bool controlGeometry(int controlClass, int controlCode, void *dataValue, int *dataSize);
136 
137  virtual void computeAABB()=0;
138  // compute the AABB for this object and put it in aabb. this function
139  // always performs a fresh computation, it does not inspect the
140  // GEOM_AABB_BAD flag.
141 
142  virtual int AABBTest (dxGeom *o, dReal aabb[6]);
143  // test whether the given AABB object intersects with this object, return
144  // 1=yes, 0=no. this is used as an early-exit test in the space collision
145  // functions. the default implementation returns 1, which is the correct
146  // behavior if no more detailed implementation can be provided.
147 
148  // utility functions
149 
150  // compute the AABB only if it is not current. this function manipulates
151  // the GEOM_AABB_BAD flag.
152 
153  void recomputeAABB() {
154  if (gflags & GEOM_AABB_BAD) {
155  // our aabb functions assume final_posr is up to date
156  recomputePosr();
157  computeAABB();
158  gflags &= ~GEOM_AABB_BAD;
159  }
160  }
161 
162  // add and remove this geom from a linked list maintained by a space.
163 
164  void spaceAdd (dxGeom **first_ptr) {
165  next = *first_ptr;
166  tome = first_ptr;
167  if (*first_ptr) (*first_ptr)->tome = &next;
168  *first_ptr = this;
169  }
170  void spaceRemove() {
171  if (next) next->tome = tome;
172  *tome = next;
173  }
174 
175  // add and remove this geom from a linked list maintained by a body.
176 
177  void bodyAdd (dxBody *b) {
178  body = b;
179  body_next = b->geom;
180  b->geom = this;
181  }
182  void bodyRemove();
183 };
184 
185 //****************************************************************************
186 // the base space class
187 //
188 // the contained geoms are divided into two kinds: clean and dirty.
189 // the clean geoms have not moved since they were put in the list,
190 // and their AABBs are valid. the dirty geoms have changed position, and
191 // their AABBs are may not be valid. the two types are distinguished by the
192 // GEOM_DIRTY flag. all dirty geoms come *before* all clean geoms in the list.
193 
194 #if dTLS_ENABLED
195 #define dSPACE_TLS_KIND_INIT_VALUE OTK__DEFAULT
196 #define dSPACE_TLS_KIND_MANUAL_VALUE OTK_MANUALCLEANUP
197 #else
198 #define dSPACE_TLS_KIND_INIT_VALUE 0
199 #define dSPACE_TLS_KIND_MANUAL_VALUE 0
200 #endif
201 
202 struct dxSpace : public dxGeom {
203  int count; // number of geoms in this space
204  dxGeom *first; // first geom in list
205  int cleanup; // cleanup mode, 1=destroy geoms on exit
206  int sublevel; // space sublevel (used in dSpaceCollide2). NOT TRACKED AUTOMATICALLY!!!
207  unsigned tls_kind; // space TLS kind to be used for global caches retrieval
208 
209  // cached state for getGeom()
210  int current_index; // only valid if current_geom != 0
211  dxGeom *current_geom; // if 0 then there is no information
212 
213  // locking stuff. the space is locked when it is currently traversing its
214  // internal data structures, e.g. in collide() and collide2(). operations
215  // that modify the contents of the space are not permitted when the space
216  // is locked.
217  int lock_count;
218 
219  dxSpace (dSpaceID _space);
220  ~dxSpace();
221 
222  void computeAABB();
223 
224  void setCleanup (int mode) { cleanup = (mode != 0); }
225  int getCleanup() const { return cleanup; }
226  void setSublevel(int value) { sublevel = value; }
227  int getSublevel() const { return sublevel; }
228  void setManulCleanup(int value) { tls_kind = (value ? dSPACE_TLS_KIND_MANUAL_VALUE : dSPACE_TLS_KIND_INIT_VALUE); }
229  int getManualCleanup() const { return (tls_kind == dSPACE_TLS_KIND_MANUAL_VALUE) ? 1 : 0; }
230  int query (dxGeom *geom) const { dAASSERT(geom); return (geom->parent_space == this); }
231  int getNumGeoms() const { return count; }
232 
233  virtual dxGeom *getGeom (int i);
234 
235  virtual void add (dxGeom *);
236  virtual void remove (dxGeom *);
237  virtual void dirty (dxGeom *);
238 
239  virtual void cleanGeoms()=0;
240  // turn all dirty geoms into clean geoms by computing their AABBs and any
241  // other space data structures that are required. this should clear the
242  // GEOM_DIRTY and GEOM_AABB_BAD flags of all geoms.
243 
244  virtual void collide (void *data, dNearCallback *callback)=0;
245  virtual void collide2 (void *data, dxGeom *geom, dNearCallback *callback)=0;
246 };
247 
248 
249 //****************************************************************************
250 // Initialization and finalization functions
251 
252 void dInitColliders();
253 void dFinitColliders();
254 
255 void dClearPosrCache(void);
256 void dFinitUserClasses();
257 
258 
259 #endif
Definition: ode/src/objects.h:57
Definition: ode/src/objects.h:131
void dNearCallback(void *data, dGeomID o1, dGeomID o2)
User callback for geom-geom collision testing.
Definition: collision_space.h:49
Definition: ode/src/objects.h:126
Definition: collision_kernel.h:96
Definition: collision_kernel.h:202