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

physics/SimpleCollisionCuller.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: SimpleCollisionCuller.cpp 1031 2004-02-11 20:46:36Z jungd $
00019   $Revision: 1.3 $
00020   $Date: 2004-02-11 15:46:36 -0500 (Wed, 11 Feb 2004) $
00021   $Author: jungd $
00022  
00023 ****************************************************************************/
00024 
00025 #include <physics/SimpleCollisionCuller>
00026 
00027 using physics::SimpleCollisionCuller;
00028 
00029 using physics::Collider;
00030 using physics::Collidable;
00031 using physics::CollidableBody;
00032 using physics::CollidableGroup;
00033 
00034 
00035 void SimpleCollisionCuller::collide(ref<const Collidable> collidable1, ref<const Collidable> collidable2)
00036 {
00037   if (!isCollisionEnabled()) return;
00038   
00039   Assert(collidable1);
00040   Assert(collidable2);
00041   
00042   if (instanceof(*collidable1, const CollidableBody) && instanceof(*collidable2, const CollidableBody)) {
00043     if (!isCollisionEnabled(collidable1, collidable2)) return; // cull
00044     notifyListeners(collidable1, collidable2); // both bodies
00045     return;
00046   }
00047     
00048   if (instanceof(*collidable1, const CollidableGroup) && instanceof(*collidable2, const CollidableGroup)) {
00049     // both groups
00050     
00051     ref<const CollidableGroup> group1(narrow_ref<const CollidableGroup>(collidable1));
00052     ref<const CollidableGroup> group2(narrow_ref<const CollidableGroup>(collidable2));
00053  
00054     // collide each element of the second group with the whole first group
00055     if (isCollisionEnabled(collidable1, collidable2)) {
00056       CollidableGroup::const_iterator_const c = group2->const_begin();
00057       CollidableGroup::const_iterator_const end = group2->const_end();
00058       while (c != end) {
00059         collide(group1, *c); 
00060         ++c;
00061       }
00062     }
00063    
00064     // collide each the elements of the groups among themselves
00065     if (group1->isChildIntercollisionEnabled())
00066       collide(group1);
00067     
00068     if (group2->isChildIntercollisionEnabled())
00069       collide(group2);
00070     
00071   }
00072   else {
00073     // one of each, make the group the first one
00074     if (instanceof(*collidable1, const CollidableBody))
00075       base::swap(collidable1, collidable2);
00076     
00077     // now collidable1 is group & collidable2 is a body
00078     // Collide each group element with the body
00079     Assert(instanceof(*collidable1, const CollidableGroup));
00080     Assert(instanceof(*collidable2, const CollidableBody));
00081     
00082     ref<const CollidableGroup> group(narrow_ref<const CollidableGroup>(collidable1));
00083     ref<const CollidableBody>  body(narrow_ref<const CollidableBody>(collidable2));
00084 
00085     // collide each element of the group with the body
00086     if (isCollisionEnabled(collidable1, collidable2)) {
00087       CollidableGroup::const_iterator_const c = group->const_begin();
00088       CollidableGroup::const_iterator_const end = group->const_end();
00089       while (c != end) {
00090         collide(*c, body); 
00091         ++c;
00092       }
00093     }
00094 
00095     if (group->isChildIntercollisionEnabled())
00096       collide(group); // and collide the group elements among themselves
00097     
00098   }
00099 
00100 }

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