ode/inc/collision_kernel.h
changeset 0 2f259fa3e83a
equal deleted inserted replaced
-1:000000000000 0:2f259fa3e83a
       
     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 "object.h"
       
    36 
       
    37 //****************************************************************************
       
    38 // constants and macros
       
    39 
       
    40 // mask for the number-of-contacts field in the dCollide() flags parameter
       
    41 #define NUMC_MASK (0xffff)
       
    42 
       
    43 #define IS_SPACE(geom) \
       
    44   ((geom)->type >= dFirstSpaceClass && (geom)->type <= dLastSpaceClass)
       
    45 
       
    46 //****************************************************************************
       
    47 // geometry object base class
       
    48 
       
    49 
       
    50 // geom flags.
       
    51 //
       
    52 // GEOM_DIRTY means that the space data structures for this geom are
       
    53 // potentially not up to date. NOTE THAT all space parents of a dirty geom
       
    54 // are themselves dirty. this is an invariant that must be enforced.
       
    55 //
       
    56 // GEOM_AABB_BAD means that the cached AABB for this geom is not up to date.
       
    57 // note that GEOM_DIRTY does not imply GEOM_AABB_BAD, as the geom might
       
    58 // recalculate its own AABB but does not know how to update the space data
       
    59 // structures for the space it is in. but GEOM_AABB_BAD implies GEOM_DIRTY.
       
    60 // the valid combinations are: 
       
    61 //		0
       
    62 //		GEOM_DIRTY
       
    63 //		GEOM_DIRTY|GEOM_AABB_BAD
       
    64 //		GEOM_DIRTY|GEOM_AABB_BAD|GEOM_POSR_BAD
       
    65 
       
    66 enum {
       
    67   GEOM_DIRTY	= 1,	// geom is 'dirty', i.e. position unknown
       
    68   GEOM_POSR_BAD = 2,	// geom's final posr is not valid
       
    69   GEOM_AABB_BAD	= 4,	// geom's AABB is not valid
       
    70   GEOM_PLACEABLE = 8,	// geom is placeable
       
    71   GEOM_ENABLED = 16,		// geom is enabled
       
    72 
       
    73   // Ray specific
       
    74   RAY_FIRSTCONTACT = 0x10000,
       
    75   RAY_BACKFACECULL = 0x20000,
       
    76   RAY_CLOSEST_HIT  = 0x40000
       
    77 };
       
    78 
       
    79 
       
    80 // geometry object base class. pos and R will either point to a separately
       
    81 // allocated buffer (if body is 0 - pos points to the dxPosR object) or to
       
    82 // the pos and R of the body (if body nonzero).
       
    83 // a dGeomID is a pointer to this object.
       
    84 
       
    85 struct dxGeom : public dBase {
       
    86   int type;		// geom type number, set by subclass constructor
       
    87   int gflags;		// flags used by geom and space
       
    88   void *data;		// user-defined data pointer
       
    89   dBodyID body;		// dynamics body associated with this object (if any)
       
    90   dxGeom *body_next;	// next geom in body's linked list of associated geoms
       
    91   dxPosR *final_posr;	// final position of the geom in world coordinates
       
    92   dxPosR *offset_posr;	// offset from body in local coordinates
       
    93 
       
    94   // information used by spaces
       
    95   dxGeom *next;		// next geom in linked list of geoms
       
    96   dxGeom **tome;	// linked list backpointer
       
    97   dxSpace *parent_space;// the space this geom is contained in, 0 if none
       
    98   dReal aabb[6];	// cached AABB for this space
       
    99   unsigned long category_bits,collide_bits;
       
   100 
       
   101   dxGeom (dSpaceID _space, int is_placeable);
       
   102   virtual ~dxGeom();
       
   103 
       
   104 
       
   105   // calculate our new final position from our offset and body
       
   106   void computePosr();
       
   107 
       
   108   // recalculate our new final position if needed
       
   109   void recomputePosr()
       
   110   {
       
   111     if (gflags & GEOM_POSR_BAD) {
       
   112       computePosr();
       
   113       gflags &= ~GEOM_POSR_BAD;
       
   114     }
       
   115   }
       
   116 
       
   117   virtual void computeAABB()=0;
       
   118   // compute the AABB for this object and put it in aabb. this function
       
   119   // always performs a fresh computation, it does not inspect the
       
   120   // GEOM_AABB_BAD flag.
       
   121 
       
   122   virtual int AABBTest (dxGeom *o, dReal aabb[6]);
       
   123   // test whether the given AABB object intersects with this object, return
       
   124   // 1=yes, 0=no. this is used as an early-exit test in the space collision
       
   125   // functions. the default implementation returns 1, which is the correct
       
   126   // behavior if no more detailed implementation can be provided.
       
   127 
       
   128   // utility functions
       
   129 
       
   130   // compute the AABB only if it is not current. this function manipulates
       
   131   // the GEOM_AABB_BAD flag.
       
   132 
       
   133   void recomputeAABB() {
       
   134     if (gflags & GEOM_AABB_BAD) {
       
   135       // our aabb functions assume final_posr is up to date
       
   136       recomputePosr(); 
       
   137       computeAABB();
       
   138       gflags &= ~GEOM_AABB_BAD;
       
   139     }
       
   140   }
       
   141 
       
   142   // add and remove this geom from a linked list maintained by a space.
       
   143 
       
   144   void spaceAdd (dxGeom **first_ptr) {
       
   145     next = *first_ptr;
       
   146     tome = first_ptr;
       
   147     if (*first_ptr) (*first_ptr)->tome = &next;
       
   148     *first_ptr = this;
       
   149   }
       
   150   void spaceRemove() {
       
   151     if (next) next->tome = tome;
       
   152     *tome = next;
       
   153   }
       
   154 
       
   155   // add and remove this geom from a linked list maintained by a body.
       
   156 
       
   157   void bodyAdd (dxBody *b) {
       
   158     body = b;
       
   159     body_next = b->geom;
       
   160     b->geom = this;
       
   161   }
       
   162   void bodyRemove();
       
   163 };
       
   164 
       
   165 //****************************************************************************
       
   166 // the base space class
       
   167 //
       
   168 // the contained geoms are divided into two kinds: clean and dirty.
       
   169 // the clean geoms have not moved since they were put in the list,
       
   170 // and their AABBs are valid. the dirty geoms have changed position, and
       
   171 // their AABBs are may not be valid. the two types are distinguished by the
       
   172 // GEOM_DIRTY flag. all dirty geoms come *before* all clean geoms in the list.
       
   173 
       
   174 struct dxSpace : public dxGeom {
       
   175   int count;			// number of geoms in this space
       
   176   dxGeom *first;		// first geom in list
       
   177   int cleanup;			// cleanup mode, 1=destroy geoms on exit
       
   178 
       
   179   // cached state for getGeom()
       
   180   int current_index;		// only valid if current_geom != 0
       
   181   dxGeom *current_geom;		// if 0 then there is no information
       
   182 
       
   183   // locking stuff. the space is locked when it is currently traversing its
       
   184   // internal data structures, e.g. in collide() and collide2(). operations
       
   185   // that modify the contents of the space are not permitted when the space
       
   186   // is locked.
       
   187   int lock_count;
       
   188 
       
   189   dxSpace (dSpaceID _space);
       
   190   ~dxSpace();
       
   191 
       
   192   void computeAABB();
       
   193 
       
   194   void setCleanup (int mode);
       
   195   int getCleanup();
       
   196   int query (dxGeom *geom);
       
   197   int getNumGeoms();
       
   198   virtual dxGeom *getGeom (int i);
       
   199 
       
   200   virtual void add (dxGeom *);
       
   201   virtual void remove (dxGeom *);
       
   202   virtual void dirty (dxGeom *);
       
   203 
       
   204   virtual void cleanGeoms()=0;
       
   205   // turn all dirty geoms into clean geoms by computing their AABBs and any
       
   206   // other space data structures that are required. this should clear the
       
   207   // GEOM_DIRTY and GEOM_AABB_BAD flags of all geoms.
       
   208 
       
   209   virtual void collide (void *data, dNearCallback *callback)=0;
       
   210   virtual void collide2 (void *data, dxGeom *geom, dNearCallback *callback)=0;
       
   211 };
       
   212 
       
   213 
       
   214 #endif