RaycastSensor.cpp

Go to the documentation of this file.
00001 /*************************************************************************
00002 *                                                                       *
00003 * Open Physics Abstraction Layer                                        *
00004 * Copyright (C) 2004-2005                                               *
00005 * Alan Fischer  alan.fischer@gmail.com                                  *
00006 * Andres Reinot  andres@reinot.com                                      *
00007 * Tyler Streeter  tylerstreeter@gmail.com                               *
00008 * All rights reserved.                                                  *
00009 * Web: opal.sourceforge.net                                             *
00010 *                                                                       *
00011 * This library is free software; you can redistribute it and/or         *
00012 * modify it under the terms of EITHER:                                  *
00013 *   (1) The GNU Lesser General Public License as published by the Free  *
00014 *       Software Foundation; either version 2.1 of the License, or (at  *
00015 *       your option) any later version. The text of the GNU Lesser      *
00016 *       General Public License is included with this library in the     *
00017 *       file license-LGPL.txt.                                          *
00018 *   (2) The BSD-style license that is included with this library in     *
00019 *       the file license-BSD.txt.                                       *
00020 *                                                                       *
00021 * This library is distributed in the hope that it will be useful,       *
00022 * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00023 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
00024 * license-LGPL.txt and license-BSD.txt for more details.                *
00025 *                                                                       *
00026 *************************************************************************/
00027 
00028 // project headers
00029 #include "RaycastSensor.h"
00030 #include "Simulator.h"
00031 
00032 // system headers
00033 #include <algorithm>
00034 
00035 using namespace std;
00036 
00037 namespace opal
00038 {
00039     RaycastSensor::RaycastSensor( Simulator* s )
00040     {
00041         // "mData" is initialized in its own constructor.
00042         mSim = s;
00043     }
00044 
00045     RaycastSensor::~RaycastSensor()
00046     {}
00047 
00048     void RaycastSensor::init( const RaycastSensorData& data )
00049     {
00050         Sensor::init();
00051         mData = data;
00052     }
00053 
00054     const RaycastSensorData& RaycastSensor::getData() const
00055     {
00056         return mData;
00057     }
00058 
00059     const RaycastResult & RaycastSensor::fireRay()
00060     {
00061         return fireRay( mData.ray.getLength() );
00062     }
00063 
00064     const vector<RaycastResult> & RaycastSensor::firePiercingRay()
00065     {
00066         return firePiercingRay( mData.ray.getLength() );
00067     }
00068 
00069     const RaycastResult & RaycastSensor::fireRay( real length )
00070     {
00071         static RaycastResult junkResult;
00072 
00073         if ( mData.enabled )
00074         {
00075             Rayr ray = mData.ray;
00076 
00077             // If the Sensor is attached to a Solid, we need to transform
00078             // the ray relative to that Solid's transform.
00079             if ( mData.solid )
00080             {
00081                 ray = mData.solid->getTransform() * mData.transform * ray;
00082             }
00083                         else
00084                         {
00085                                 // If the Sensor is not attached to a Solid, just use the 
00086                                 // Sensor's transform as a global transform on the ray.
00087                                 ray = mData.transform * ray;
00088                         }
00089 
00090             // If this is attached to a Solid, the Simulator raycast function
00091             // will automatically ignore intersections between the ray and
00092             // that Solid.
00093 
00094             vector<RaycastResult> & results = mSim->internal_fireRay(
00095                                 ray, length, mData.solid, mData.contactGroup );
00096 
00097             if ( results.size() == 0 )
00098                 return junkResult;
00099 
00100             size_t closest = 0;
00101             for ( size_t i = 1; i < results.size(); ++i )
00102             {
00103                 if ( results[ i ].distance < results[ closest ].distance )
00104                     closest = i;
00105             }
00106 
00107             return results[ closest ];
00108         }
00109         else
00110         {
00111             return junkResult;
00112         }
00113     }
00114 
00115     const vector<RaycastResult> & RaycastSensor::firePiercingRay( real length )
00116     {
00117         static vector<RaycastResult> empty;
00118 
00119         if ( mData.enabled )
00120         {
00121             // the original ray shouldn't change
00122             Rayr ray = mData.ray;
00123 
00124             // If the Sensor is attached to a Solid, we need to transform
00125             // the ray relative to that Solid's transform.
00126             if ( mData.solid )
00127             {
00128                                 ray = mData.solid->getTransform() * mData.transform * ray;
00129             }
00130                         else
00131                         {
00132                                 // If the Sensor is not attached to a Solid, just use the 
00133                                 // Sensor's transform as a global transform on the ray.
00134                                 ray = mData.transform * ray;
00135                         }
00136 
00137             // If this is attached to a Solid, the Simulator raycast function
00138             // will automatically ignore intersections between the ray and
00139             // that Solid.
00140 
00141             vector<RaycastResult> & results = mSim->internal_fireRay(
00142                                 ray, length, mData.solid, mData.contactGroup );
00143             sort( results.begin(), results.end() );
00144 
00145             return results;
00146         }
00147         else
00148         {
00149             return empty;
00150         }
00151     }
00152 
00153     void RaycastSensor::setEnabled( bool e )
00154     {
00155         //if (!mInitCalled)
00156         //{
00157         //      return;
00158         //}
00159 
00160         mData.enabled = e;
00161     }
00162 
00163     bool RaycastSensor::isEnabled() const
00164     {
00165         return mData.enabled;
00166     }
00167 
00168     void RaycastSensor::setRay( const Rayr& r )
00169     {
00170         mData.ray = r;
00171     }
00172 
00173     const Rayr& RaycastSensor::getRay() const
00174     {
00175         return mData.ray;
00176     }
00177 
00178     SensorType RaycastSensor::getType() const
00179     {
00180         return mData.getType();
00181     }
00182 
00183     void RaycastSensor::setTransform( const Matrix44r& t )
00184     {
00185         mData.transform = t;
00186     }
00187 
00188     const Matrix44r& RaycastSensor::getTransform() const
00189     {
00190         return mData.transform;
00191     }
00192 
00193     void RaycastSensor::setName( const std::string& name )
00194     {
00195         mData.name = name;
00196     }
00197 
00198     const std::string& RaycastSensor::getName() const
00199     {
00200         return mData.name;
00201     }
00202 
00203     void RaycastSensor::internal_update()
00204     {
00205         if ( mData.enabled && mData.solid )
00206         {
00207             // Do nothing.
00208         }
00209     }
00210 
00211     bool RaycastSensor::internal_dependsOnSolid( Solid* s )
00212     {
00213         if ( s == mData.solid )
00214         {
00215             return true;
00216         }
00217         else
00218         {
00219             return false;
00220         }
00221     }
00222 
00223     bool operator<( const RaycastResult & l, const RaycastResult & r )
00224     {
00225         return l.distance < r.distance;
00226     }
00227 }

Generated on Tue May 16 17:49:52 2006 for OPAL by  doxygen 1.4.6-NO