ode/src/collision_transform.cpp
changeset 0 2f259fa3e83a
equal deleted inserted replaced
-1:000000000000 0:2f259fa3e83a
       
     1 /*************************************************************************
       
     2  *                                                                       *
       
     3  * Open Dynamics Engine, Copyright (C) 2001,2002 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 geom transform
       
    26 
       
    27 */
       
    28 
       
    29 #include <ode/collision.h>
       
    30 #include <ode/matrix.h>
       
    31 #include <ode/rotation.h>
       
    32 #include <ode/odemath.h>
       
    33 #include "collision_transform.h"
       
    34 #include "collision_util.h"
       
    35 
       
    36 //****************************************************************************
       
    37 // dxGeomTransform class
       
    38 
       
    39 struct dxGeomTransform : public dxGeom {
       
    40   dxGeom *obj;		// object that is being transformed
       
    41   int cleanup;		// 1 to destroy obj when destroyed
       
    42   int infomode;		// 1 to put Tx geom in dContactGeom g1
       
    43 
       
    44   // cached final object transform (body tx + relative tx). this is set by
       
    45   // computeAABB(), and it is valid while the AABB is valid.
       
    46   dxPosR transform_posr;
       
    47 
       
    48   dxGeomTransform (dSpaceID space);
       
    49   ~dxGeomTransform();
       
    50   void computeAABB();
       
    51   void computeFinalTx();
       
    52 };
       
    53 
       
    54 
       
    55 dxGeomTransform::dxGeomTransform (dSpaceID space) : dxGeom (space,1)
       
    56 {
       
    57   type = dGeomTransformClass;
       
    58   obj = 0;
       
    59   cleanup = 0;
       
    60   infomode = 0;
       
    61   dSetZero (transform_posr.pos,4);
       
    62   dRSetIdentity (transform_posr.R);
       
    63 }
       
    64 
       
    65 
       
    66 dxGeomTransform::~dxGeomTransform()
       
    67 {
       
    68   if (obj && cleanup) delete obj;
       
    69 }
       
    70 
       
    71 
       
    72 void dxGeomTransform::computeAABB()
       
    73 {
       
    74   if (!obj) {
       
    75     dSetZero (aabb,6);
       
    76     return;
       
    77   }
       
    78 
       
    79   // backup the relative pos and R pointers of the encapsulated geom object
       
    80   dxPosR* posr_bak = obj->final_posr;
       
    81 
       
    82   // compute temporary pos and R for the encapsulated geom object
       
    83   computeFinalTx();
       
    84   obj->final_posr = &transform_posr;
       
    85 
       
    86   // compute the AABB
       
    87   obj->computeAABB();
       
    88   memcpy (aabb,obj->aabb,6*sizeof(dReal));
       
    89 
       
    90   // restore the pos and R
       
    91   obj->final_posr = posr_bak;
       
    92 }
       
    93 
       
    94 
       
    95 // utility function for dCollideTransform() : compute final pos and R
       
    96 // for the encapsulated geom object
       
    97 
       
    98 void dxGeomTransform::computeFinalTx()
       
    99 {
       
   100   dMULTIPLY0_331 (transform_posr.pos,final_posr->R,obj->final_posr->pos);
       
   101   transform_posr.pos[0] += final_posr->pos[0];
       
   102   transform_posr.pos[1] += final_posr->pos[1];
       
   103   transform_posr.pos[2] += final_posr->pos[2];
       
   104   dMULTIPLY0_333 (transform_posr.R,final_posr->R,obj->final_posr->R);
       
   105 }
       
   106 
       
   107 //****************************************************************************
       
   108 // collider function:
       
   109 // this collides a transformed geom with another geom. the other geom can
       
   110 // also be a transformed geom, but this case is not handled specially.
       
   111 
       
   112 int dCollideTransform (dxGeom *o1, dxGeom *o2, int flags,
       
   113 		       dContactGeom *contact, int skip)
       
   114 {
       
   115 
       
   116 
       
   117   dxGeomTransform *tr = (dxGeomTransform*) o1;
       
   118   if (!tr->obj) return 0;
       
   119 
       
   120 
       
   121   // backup the relative pos and R pointers of the encapsulated geom object,
       
   122   // and the body pointer
       
   123   dxPosR *posr_bak = tr->obj->final_posr;
       
   124   dxBody *bodybak = tr->obj->body;
       
   125 
       
   126   // compute temporary pos and R for the encapsulated geom object.
       
   127   // note that final_pos and final_R are valid if no GEOM_AABB_BAD flag,
       
   128   // because computeFinalTx() will have already been called in
       
   129   // dxGeomTransform::computeAABB()
       
   130 
       
   131   if (tr->gflags & GEOM_AABB_BAD) tr->computeFinalTx();
       
   132   tr->obj->final_posr = &tr->transform_posr;
       
   133   tr->obj->body = o1->body;
       
   134 
       
   135   // do the collision
       
   136   int n = dCollide (tr->obj,o2,flags,contact,skip);
       
   137 
       
   138   // if required, adjust the 'g1' values in the generated contacts so that
       
   139   // thay indicated the GeomTransform object instead of the encapsulated
       
   140   // object.
       
   141   if (tr->infomode) {
       
   142     for (int i=0; i<n; i++) {
       
   143       dContactGeom *c = CONTACT(contact,skip*i);
       
   144       c->g1 = o1;
       
   145     }
       
   146   }
       
   147 
       
   148   // restore the pos, R and body
       
   149   tr->obj->final_posr = posr_bak;
       
   150   tr->obj->body = bodybak;
       
   151   return n;
       
   152 }
       
   153 
       
   154 //****************************************************************************
       
   155 // public API
       
   156 
       
   157 EXPORT_C dGeomID dCreateGeomTransform (dSpaceID space)
       
   158 {
       
   159   return new dxGeomTransform (space);
       
   160 }
       
   161 
       
   162 
       
   163 EXPORT_C void dGeomTransformSetGeom (dGeomID g, dGeomID obj)
       
   164 {
       
   165 
       
   166   dxGeomTransform *tr = (dxGeomTransform*) g;
       
   167   if (tr->obj && tr->cleanup) delete tr->obj;
       
   168   tr->obj = obj;
       
   169 }
       
   170 
       
   171 
       
   172 EXPORT_C dGeomID dGeomTransformGetGeom (dGeomID g)
       
   173 {
       
   174 
       
   175   dxGeomTransform *tr = (dxGeomTransform*) g;
       
   176   return tr->obj;
       
   177 }
       
   178 
       
   179 
       
   180 EXPORT_C void dGeomTransformSetCleanup (dGeomID g, int mode)
       
   181 {
       
   182 
       
   183   dxGeomTransform *tr = (dxGeomTransform*) g;
       
   184   tr->cleanup = mode;
       
   185 }
       
   186 
       
   187 
       
   188 EXPORT_C int dGeomTransformGetCleanup (dGeomID g)
       
   189 {
       
   190 
       
   191   dxGeomTransform *tr = (dxGeomTransform*) g;
       
   192   return tr->cleanup;
       
   193 }
       
   194 
       
   195 
       
   196 EXPORT_C void dGeomTransformSetInfo (dGeomID g, int mode)
       
   197 {
       
   198 
       
   199   dxGeomTransform *tr = (dxGeomTransform*) g;
       
   200   tr->infomode = mode;
       
   201 }
       
   202 
       
   203 
       
   204 EXPORT_C int dGeomTransformGetInfo (dGeomID g)
       
   205 {
       
   206 
       
   207   dxGeomTransform *tr = (dxGeomTransform*) g;
       
   208   return tr->infomode;
       
   209 }