Open Dynamics Engine
|
00001 /************************************************************************* 00002 * * 00003 * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * 00004 * All rights reserved. Email: russ@q12.org Web: www.q12.org * 00005 * * 00006 * This library is free software; you can redistribute it and/or * 00007 * modify it under the terms of EITHER: * 00008 * (1) The GNU Lesser General Public License as published by the Free * 00009 * Software Foundation; either version 2.1 of the License, or (at * 00010 * your option) any later version. The text of the GNU Lesser * 00011 * General Public License is included with this library in the * 00012 * file LICENSE.TXT. * 00013 * (2) The BSD-style license that is included with this library in * 00014 * the file LICENSE-BSD.TXT. * 00015 * * 00016 * This library is distributed in the hope that it will be useful, * 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * 00019 * LICENSE.TXT and LICENSE-BSD.TXT for more details. * 00020 * * 00021 *************************************************************************/ 00022 00023 /* 00024 00025 internal data structures and functions for collision detection. 00026 00027 */ 00028 00029 #ifndef _ODE_COLLISION_KERNEL_H_ 00030 #define _ODE_COLLISION_KERNEL_H_ 00031 00032 #include <ode/common.h> 00033 #include <ode/contact.h> 00034 #include <ode/collision.h> 00035 #include "objects.h" 00036 #include "odetls.h" 00037 00038 //**************************************************************************** 00039 // constants and macros 00040 00041 // mask for the number-of-contacts field in the dCollide() flags parameter 00042 #define NUMC_MASK (0xffff) 00043 00044 #define IS_SPACE(geom) \ 00045 ((geom)->type >= dFirstSpaceClass && (geom)->type <= dLastSpaceClass) 00046 00047 //**************************************************************************** 00048 // geometry object base class 00049 00050 00051 // geom flags. 00052 // 00053 // GEOM_DIRTY means that the space data structures for this geom are 00054 // potentially not up to date. NOTE THAT all space parents of a dirty geom 00055 // are themselves dirty. this is an invariant that must be enforced. 00056 // 00057 // GEOM_AABB_BAD means that the cached AABB for this geom is not up to date. 00058 // note that GEOM_DIRTY does not imply GEOM_AABB_BAD, as the geom might 00059 // recalculate its own AABB but does not know how to update the space data 00060 // structures for the space it is in. but GEOM_AABB_BAD implies GEOM_DIRTY. 00061 // the valid combinations are: 00062 // 0 00063 // GEOM_DIRTY 00064 // GEOM_DIRTY|GEOM_AABB_BAD 00065 // GEOM_DIRTY|GEOM_AABB_BAD|GEOM_POSR_BAD 00066 00067 enum { 00068 GEOM_DIRTY = 1, // geom is 'dirty', i.e. position unknown 00069 GEOM_POSR_BAD = 2, // geom's final posr is not valid 00070 GEOM_AABB_BAD = 4, // geom's AABB is not valid 00071 GEOM_PLACEABLE = 8, // geom is placeable 00072 GEOM_ENABLED = 16, // geom is enabled 00073 GEOM_ZERO_SIZED = 32, // geom is zero sized 00074 00075 GEOM_ENABLE_TEST_MASK = GEOM_ENABLED | GEOM_ZERO_SIZED, 00076 GEOM_ENABLE_TEST_VALUE = GEOM_ENABLED, 00077 00078 // Ray specific 00079 RAY_FIRSTCONTACT = 0x10000, 00080 RAY_BACKFACECULL = 0x20000, 00081 RAY_CLOSEST_HIT = 0x40000 00082 }; 00083 00084 enum dxContactMergeOptions { 00085 DONT_MERGE_CONTACTS, 00086 MERGE_CONTACT_NORMALS, 00087 MERGE_CONTACTS_FULLY, 00088 }; 00089 00090 00091 // geometry object base class. pos and R will either point to a separately 00092 // allocated buffer (if body is 0 - pos points to the dxPosR object) or to 00093 // the pos and R of the body (if body nonzero). 00094 // a dGeomID is a pointer to this object. 00095 00096 struct dxGeom : public dBase { 00097 int type; // geom type number, set by subclass constructor 00098 int gflags; // flags used by geom and space 00099 void *data; // user-defined data pointer 00100 dBodyID body; // dynamics body associated with this object (if any) 00101 dxGeom *body_next; // next geom in body's linked list of associated geoms 00102 dxPosR *final_posr; // final position of the geom in world coordinates 00103 dxPosR *offset_posr; // offset from body in local coordinates 00104 00105 // information used by spaces 00106 dxGeom *next; // next geom in linked list of geoms 00107 dxGeom **tome; // linked list backpointer 00108 dxSpace *parent_space;// the space this geom is contained in, 0 if none 00109 dReal aabb[6]; // cached AABB for this space 00110 unsigned long category_bits,collide_bits; 00111 00112 dxGeom (dSpaceID _space, int is_placeable); 00113 virtual ~dxGeom(); 00114 00115 // Set or clear GEOM_ZERO_SIZED flag 00116 void updateZeroSizedFlag(bool is_zero_sized) { gflags = is_zero_sized ? (gflags | GEOM_ZERO_SIZED) : (gflags & ~GEOM_ZERO_SIZED); } 00117 // Get parent space TLS kind 00118 unsigned getParentSpaceTLSKind() const; 00119 00120 // calculate our new final position from our offset and body 00121 void computePosr(); 00122 00123 // recalculate our new final position if needed 00124 void recomputePosr() 00125 { 00126 if (gflags & GEOM_POSR_BAD) { 00127 computePosr(); 00128 gflags &= ~GEOM_POSR_BAD; 00129 } 00130 } 00131 00132 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 00133 virtual bool controlGeometry(int controlClass, int controlCode, void *dataValue, int *dataSize); 00134 00135 virtual void computeAABB()=0; 00136 // compute the AABB for this object and put it in aabb. this function 00137 // always performs a fresh computation, it does not inspect the 00138 // GEOM_AABB_BAD flag. 00139 00140 virtual int AABBTest (dxGeom *o, dReal aabb[6]); 00141 // test whether the given AABB object intersects with this object, return 00142 // 1=yes, 0=no. this is used as an early-exit test in the space collision 00143 // functions. the default implementation returns 1, which is the correct 00144 // behavior if no more detailed implementation can be provided. 00145 00146 // utility functions 00147 00148 // compute the AABB only if it is not current. this function manipulates 00149 // the GEOM_AABB_BAD flag. 00150 00151 void recomputeAABB() { 00152 if (gflags & GEOM_AABB_BAD) { 00153 // our aabb functions assume final_posr is up to date 00154 recomputePosr(); 00155 computeAABB(); 00156 gflags &= ~GEOM_AABB_BAD; 00157 } 00158 } 00159 00160 // add and remove this geom from a linked list maintained by a space. 00161 00162 void spaceAdd (dxGeom **first_ptr) { 00163 next = *first_ptr; 00164 tome = first_ptr; 00165 if (*first_ptr) (*first_ptr)->tome = &next; 00166 *first_ptr = this; 00167 } 00168 void spaceRemove() { 00169 if (next) next->tome = tome; 00170 *tome = next; 00171 } 00172 00173 // add and remove this geom from a linked list maintained by a body. 00174 00175 void bodyAdd (dxBody *b) { 00176 body = b; 00177 body_next = b->geom; 00178 b->geom = this; 00179 } 00180 void bodyRemove(); 00181 }; 00182 00183 //**************************************************************************** 00184 // the base space class 00185 // 00186 // the contained geoms are divided into two kinds: clean and dirty. 00187 // the clean geoms have not moved since they were put in the list, 00188 // and their AABBs are valid. the dirty geoms have changed position, and 00189 // their AABBs are may not be valid. the two types are distinguished by the 00190 // GEOM_DIRTY flag. all dirty geoms come *before* all clean geoms in the list. 00191 00192 #if dTLS_ENABLED 00193 #define dSPACE_TLS_KIND_INIT_VALUE OTK__DEFAULT 00194 #define dSPACE_TLS_KIND_MANUAL_VALUE OTK_MANUALCLEANUP 00195 #else 00196 #define dSPACE_TLS_KIND_INIT_VALUE 0 00197 #define dSPACE_TLS_KIND_MANUAL_VALUE 0 00198 #endif 00199 00200 struct dxSpace : public dxGeom { 00201 int count; // number of geoms in this space 00202 dxGeom *first; // first geom in list 00203 int cleanup; // cleanup mode, 1=destroy geoms on exit 00204 int sublevel; // space sublevel (used in dSpaceCollide2). NOT TRACKED AUTOMATICALLY!!! 00205 unsigned tls_kind; // space TLS kind to be used for global caches retrieval 00206 00207 // cached state for getGeom() 00208 int current_index; // only valid if current_geom != 0 00209 dxGeom *current_geom; // if 0 then there is no information 00210 00211 // locking stuff. the space is locked when it is currently traversing its 00212 // internal data structures, e.g. in collide() and collide2(). operations 00213 // that modify the contents of the space are not permitted when the space 00214 // is locked. 00215 int lock_count; 00216 00217 dxSpace (dSpaceID _space); 00218 ~dxSpace(); 00219 00220 void computeAABB(); 00221 00222 void setCleanup (int mode) { cleanup = (mode != 0); } 00223 int getCleanup() const { return cleanup; } 00224 void setSublevel(int value) { sublevel = value; } 00225 int getSublevel() const { return sublevel; } 00226 void setManulCleanup(int value) { tls_kind = (value ? dSPACE_TLS_KIND_MANUAL_VALUE : dSPACE_TLS_KIND_INIT_VALUE); } 00227 int getManualCleanup() const { return (tls_kind == dSPACE_TLS_KIND_MANUAL_VALUE) ? 1 : 0; } 00228 int query (dxGeom *geom) const { dAASSERT(geom); return (geom->parent_space == this); } 00229 int getNumGeoms() const { return count; } 00230 00231 virtual dxGeom *getGeom (int i); 00232 00233 virtual void add (dxGeom *); 00234 virtual void remove (dxGeom *); 00235 virtual void dirty (dxGeom *); 00236 00237 virtual void cleanGeoms()=0; 00238 // turn all dirty geoms into clean geoms by computing their AABBs and any 00239 // other space data structures that are required. this should clear the 00240 // GEOM_DIRTY and GEOM_AABB_BAD flags of all geoms. 00241 00242 virtual void collide (void *data, dNearCallback *callback)=0; 00243 virtual void collide2 (void *data, dxGeom *geom, dNearCallback *callback)=0; 00244 }; 00245 00246 00247 //**************************************************************************** 00248 // Initialization and finalization functions 00249 00250 void dInitColliders(); 00251 void dFinitColliders(); 00252 00253 void dClearPosrCache(void); 00254 void dFinitUserClasses(); 00255 00256 00257 #endif