Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

physics/ODECollisionCuller.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002   Copyright (C)2003 David Jung <opensim@pobox.com>
00003 
00004   This program/file is free software; you can redistribute it and/or modify
00005   it under the terms of the GNU General Public License as published by
00006   the Free Software Foundation; either version 2 of the License, or
00007   (at your option) any later version.
00008   
00009   This program is distributed in the hope that it will be useful,
00010   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012   GNU General Public License for more details. (http://www.gnu.org)
00013   
00014   You should have received a copy of the GNU General Public License
00015   along with this program; if not, write to the Free Software
00016   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017   
00018   $Id: ODECollisionCuller.cpp 1066 2004-02-27 19:55:32Z jungd $
00019   $Revision: 1.4 $
00020   $Date: 2004-02-27 14:55:32 -0500 (Fri, 27 Feb 2004) $
00021   $Author: jungd $
00022  
00023 ****************************************************************************/
00024 
00025 #include <physics/ODECollisionCuller>
00026 
00027 #include <physics/ODECollidableGroup>
00028 
00029 #include <physics/ODECollidableBody>
00030 //!!!
00031 #include <physics/VisualDebugUtil> 
00032 
00033 using physics::ODECollisionCuller;
00034 
00035 using physics::Collider;
00036 using physics::Collidable;
00037 using physics::CollidableBody;
00038 using physics::ODECollidableBody;
00039 using physics::CollidableGroup;
00040 using physics::ODECollidableGroup;
00041 
00042 
00043 ref<CollidableGroup> ODECollisionCuller::createCollidableGroup() const
00044 {
00045   return ref<ODECollidableGroup>(NewObj ODECollidableGroup());
00046 }
00047 
00048 
00049 void ODECollisionCuller::nearCallback(void *data, dGeomID o1, dGeomID o2)
00050 {
00051   (static_cast<ODECollisionCuller*>(data))->callback(o1,o2);
00052 }
00053 
00054 
00055 void ODECollisionCuller::callback(dGeomID o1, dGeomID o2)
00056 {
00057   if (dGeomIsSpace(o1)) {
00058     
00059     ref<const ODECollidableGroup> group1( (const ODECollidableGroup*)dGeomGetData(o1) );
00060     
00061     if (dGeomIsSpace(o2)) {
00062       ref<const ODECollidableGroup> group2( (const ODECollidableGroup*)dGeomGetData(o2) );
00063       collide(group1, group2);
00064     }
00065     else {
00066       ref<const ODECollidableBody> body2( (const ODECollidableBody*)dGeomGetData(o2) );
00067       collide(group1, body2);
00068     }
00069     
00070   }
00071   else {
00072     
00073     ref<const ODECollidableBody> body1( (const ODECollidableBody*)dGeomGetData(o1) );
00074     
00075     if (dGeomIsSpace(o2)) {
00076       ref<const ODECollidableGroup> group2( (const ODECollidableGroup*)dGeomGetData(o2) );
00077       collide(body1, group2);
00078     }
00079     else {
00080       ref<const ODECollidableBody> body2( (const ODECollidableBody*)dGeomGetData(o2) );
00081       collide(body1,body2);
00082     }
00083     
00084   }
00085   
00086 }  
00087   
00088 
00089 
00090 void ODECollisionCuller::collide(ref<const Collidable> collidable)
00091 {
00092   if (!isCollisionEnabled()) return;
00093 
00094   if (!instanceof(*collidable, const CollidableGroup))
00095     return; // can't collide one Collidable with anything - do nothing
00096 
00097   Assert(instanceof(*collidable, const ODECollidableGroup));
00098   ref<const ODECollidableGroup> group(narrow_ref<const ODECollidableGroup>(collidable));
00099   if (!group->isChildIntercollisionEnabled()) return;
00100 Collider::collide(collidable);
00101   //!!!dSpaceCollide(group->getSpaceID(), this, nearCallback);
00102 }
00103 
00104 
00105 
00106 void ODECollisionCuller::collide(ref<const Collidable> collidable1, ref<const Collidable> collidable2)
00107 {
00108   if (!isCollisionEnabled()) return;
00109 
00110   if (collidable1->getUserClass() != 0)
00111     if (collidable1->getUserClass() == collidable2->getUserClass())
00112       return; // same user class (not 0) => cull
00113   
00114 //!!!
00115 
00116 if (instanceof(*collidable1, const ODECollidableBody)) {
00117   VisualDebugUtil::setConfiguration(  collidable1->getName()+" Sensor", narrow_ref<const ODECollidableBody>(collidable1)->getConfiguration());
00118   //Debugcln(Tmp,"set " << collidable1->getName());
00119 }
00120 if (instanceof(*collidable2, const ODECollidableBody)) {
00121   VisualDebugUtil::setConfiguration(  collidable2->getName()+" Sensor", narrow_ref<const ODECollidableBody>(collidable2)->getConfiguration());
00122   //Debugcln(Tmp,"set " << collidable2->getName());
00123 }
00124 //!!!  
00125   
00126   
00127   if (instanceof(*collidable1, const ODECollidableBody) && instanceof(*collidable2, const ODECollidableBody)) {
00128     if (!isCollisionEnabled(collidable1, collidable2)) return; // cull
00129     notifyListeners(collidable1, collidable2); // both bodies
00130     return;
00131   }
00132     
00133   if (instanceof(*collidable1, const ODECollidableGroup) && instanceof(*collidable2, const ODECollidableGroup)) {
00134     // both groups
00135     
00136     ref<const ODECollidableGroup> group1(narrow_ref<const ODECollidableGroup>(collidable1));
00137     ref<const ODECollidableGroup> group2(narrow_ref<const ODECollidableGroup>(collidable2));
00138  
00139     if (isCollisionEnabled(collidable1, collidable2)) 
00140       dSpaceCollide2((dGeomID)group1->getSpaceID(), (dGeomID)group2->getSpaceID(), this, nearCallback);
00141  
00142     // collide each the elements of the groups among themselves
00143     if (group1->isChildIntercollisionEnabled())
00144       dSpaceCollide(group1->getSpaceID(), this, nearCallback);
00145     
00146     if (group2->isChildIntercollisionEnabled())
00147       dSpaceCollide(group2->getSpaceID(), this, nearCallback);
00148     
00149   }
00150   else {
00151 
00152     // one of each, make the group the first one
00153     if (instanceof(*collidable1, const ODECollidableBody))
00154       base::swap(collidable1, collidable2);
00155     
00156     // now collidable1 is group & collidable2 is a body
00157     // Collide each group element with the body
00158     Assert(instanceof(*collidable1, const ODECollidableGroup));
00159     Assert(instanceof(*collidable2, const ODECollidableBody));
00160     
00161     ref<const ODECollidableGroup> group(narrow_ref<const ODECollidableGroup>(collidable1));
00162     ref<const ODECollidableBody>  body(narrow_ref<const ODECollidableBody>(collidable2));
00163 
00164     // collide each element of the group with the body
00165     if (isCollisionEnabled(collidable1, collidable2)) 
00166       dSpaceCollide2((dGeomID)group->getSpaceID(), body->getGeomID(), this, nearCallback);
00167     
00168     // and collide the group elements among themselves
00169     if (group->isChildIntercollisionEnabled())
00170       dSpaceCollide(group->getSpaceID(), this, nearCallback);
00171     
00172   }
00173 
00174 }

Generated on Thu Jul 29 15:56:25 2004 for OpenSim by doxygen 1.3.6