framesOrderer.cpp

00001 
00002 /* Copyright (c) 2007       Maxim Makhinya
00003  *
00004  * This library is free software; you can redistribute it and/or modify it under
00005  * the terms of the GNU Lesser General Public License version 2.1 as published
00006  * by the Free Software Foundation.
00007  *  
00008  * This library is distributed in the hope that it will be useful, but WITHOUT
00009  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00010  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00011  * details.
00012  * 
00013  * You should have received a copy of the GNU Lesser General Public License
00014  * along with this library; if not, write to the Free Software Foundation, Inc.,
00015  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00016  */
00017 
00018 #include "framesOrderer.h"
00019 
00020 namespace eVolve
00021 {
00022 
00023 static bool cmpRangesDec(const eq::Frame* frame1, const eq::Frame* frame2)
00024 {
00025     return frame1->getRange().start < frame2->getRange().start;
00026 }
00027 
00028 
00029 static bool cmpRangesInc(const eq::Frame* frame1, const eq::Frame* frame2)
00030 {
00031     return frame1->getRange().start > frame2->getRange().start;
00032 }
00033 
00034 
00035 void orderFrames( eq::FrameVector&    frames,
00036                   const eq::Matrix4d& modelviewM,
00037                   const eq::Matrix3d& modelviewITM,
00038                   const eq::Matrix4f& rotation,
00039                   const bool          orthographic )
00040 {
00041     if( orthographic )
00042     {
00043         const bool orientation = rotation.array[10] < 0;
00044         sort( frames.begin(), frames.end(),
00045               orientation ? cmpRangesInc : cmpRangesDec );
00046         return;
00047     }
00048     // else perspective projection
00049 
00050     eq::Vector3d norm = modelviewITM * eq::Vector3d( 0.0, 0.0, 1.0 );
00051     norm.normalize();
00052 
00053     sort( frames.begin(), frames.end(), cmpRangesInc );
00054 
00055     // cos of angle between normal and vectors from center
00056     std::vector<double> dotVals;
00057 
00058     // of projection to the middle of slices' boundaries
00059     for( eq::FrameVector::const_iterator i = frames.begin();
00060          i != frames.end(); ++i )
00061     {
00062         const eq::Frame* frame = *i;
00063         const double     px    = -1.0 + frame->getRange().end*2.0;
00064 
00065         const eq::Vector4d pS = modelviewM * eq::Vector4d( 0.0, 0.0, px , 1.0 );
00066         eq::Vector3d pSsub( pS.get_sub_vector< 3 >( 0 ));
00067         pSsub.normalize();
00068         dotVals.push_back( norm.dot( pSsub ));
00069     }
00070 
00071     const eq::Vector4d pS = modelviewM * eq::Vector4d( 0.0, 0.0,-1.0, 1.0 );
00072     eq::Vector3d pSsub = pS.get_sub_vector< 3 >( 0 ) ;
00073     dotVals.push_back( norm.dot( pSsub.normalize() ) );
00074     //check if any slices need to be rendered in reverse order
00075     size_t minPos = std::numeric_limits< size_t >::max();
00076     for( size_t i=0; i<dotVals.size()-1; i++ )
00077         if( dotVals[i] > 0 && dotVals[i+1] > 0 )
00078             minPos = static_cast< int >( i );
00079 
00080     const uint32_t nFrames = frames.size();
00081     minPos++;
00082     if( minPos < frames.size()-1 )
00083     {
00084         eq::FrameVector framesTmp = frames;
00085 
00086         // copy slices that should be rendered first
00087         memcpy( &frames[ nFrames-minPos-1 ], &framesTmp[0],
00088                 (minPos+1)*sizeof( eq::Frame* ) );
00089  
00090          // copy slices that should be rendered last, in reverse order
00091         for( size_t i=0; i<nFrames-minPos-1; i++ )
00092             frames[ i ] = framesTmp[ nFrames-i-1 ];
00093     }
00094 }
00095 
00096 }
00097 
Generated on Mon Aug 10 18:58:33 2009 for Equalizer 0.9 by  doxygen 1.5.8