Equalizer  1.2.1
framesOrderer.cpp
00001 
00002 /* Copyright (c) 2007       Maxim Makhinya
00003  *
00004  * Redistribution and use in source and binary forms, with or without
00005  * modification, are permitted provided that the following conditions are met:
00006  *
00007  * - Redistributions of source code must retain the above copyright notice, this
00008  *   list of conditions and the following disclaimer.
00009  * - Redistributions in binary form must reproduce the above copyright notice,
00010  *   this list of conditions and the following disclaimer in the documentation
00011  *   and/or other materials provided with the distribution.
00012  * - Neither the name of Eyescale Software GmbH nor the names of its
00013  *   contributors may be used to endorse or promote products derived from this
00014  *   software without specific prior written permission.
00015  *
00016  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00017  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00018  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00019  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00020  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00021  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00022  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00023  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00024  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00025  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00026  * POSSIBILITY OF SUCH DAMAGE.
00027  */
00028 
00029 #include "framesOrderer.h"
00030 
00031 namespace eVolve
00032 {
00033 
00034 static bool cmpRangesDec(const eq::Frame* frame1, const eq::Frame* frame2)
00035 {
00036     return frame1->getRange().start < frame2->getRange().start;
00037 }
00038 
00039 
00040 static bool cmpRangesInc(const eq::Frame* frame1, const eq::Frame* frame2)
00041 {
00042     return frame1->getRange().start > frame2->getRange().start;
00043 }
00044 
00045 
00046 void orderFrames( eq::Frames& frames, const eq::Matrix4d& modelviewM,
00047                   const eq::Matrix3d& modelviewITM,
00048                   const eq::Matrix4f& rotation, const bool orthographic )
00049 {
00050     if( orthographic )
00051     {
00052         const bool orientation = rotation.array[10] < 0;
00053         sort( frames.begin(), frames.end(),
00054               orientation ? cmpRangesInc : cmpRangesDec );
00055         return;
00056     }
00057     // else perspective projection
00058 
00059     eq::Vector3d norm = modelviewITM * eq::Vector3d( 0.0, 0.0, 1.0 );
00060     norm.normalize();
00061 
00062     sort( frames.begin(), frames.end(), cmpRangesInc );
00063 
00064     // cos of angle between normal and vectors from center
00065     std::vector<double> dotVals;
00066 
00067     // of projection to the middle of slices' boundaries
00068     for( eq::Frames::const_iterator i = frames.begin();
00069          i != frames.end(); ++i )
00070     {
00071         const eq::Frame* frame = *i;
00072         const double     px    = -1.0 + frame->getRange().end*2.0;
00073 
00074         const eq::Vector4d pS = modelviewM * eq::Vector4d( 0.0, 0.0, px , 1.0 );
00075         eq::Vector3d pSsub( pS[ 0 ], pS[ 1 ], pS[ 2 ] );
00076         pSsub.normalize();
00077         dotVals.push_back( norm.dot( pSsub ));
00078     }
00079 
00080     const eq::Vector4d pS = modelviewM * eq::Vector4d( 0.0, 0.0,-1.0, 1.0 );
00081     eq::Vector3d pSsub( pS[ 0 ], pS[ 1 ], pS[ 2 ] );
00082     dotVals.push_back( norm.dot( pSsub.normalize() ) );
00083     //check if any slices need to be rendered in reverse order
00084     size_t minPos = std::numeric_limits< size_t >::max();
00085     for( size_t i=0; i<dotVals.size()-1; i++ )
00086         if( dotVals[i] > 0 && dotVals[i+1] > 0 )
00087             minPos = static_cast< int >( i );
00088 
00089     const size_t nFrames = frames.size();
00090     minPos++;
00091     if( minPos < frames.size()-1 )
00092     {
00093         eq::Frames framesTmp = frames;
00094 
00095         // copy slices that should be rendered first
00096         memcpy( &frames[ nFrames-minPos-1 ], &framesTmp[0],
00097                 (minPos+1)*sizeof( eq::Frame* ) );
00098  
00099          // copy slices that should be rendered last, in reverse order
00100         for( size_t i=0; i<nFrames-minPos-1; i++ )
00101             frames[ i ] = framesTmp[ nFrames-i-1 ];
00102     }
00103 }
00104 
00105 }
00106 
Generated on Fri Jun 8 2012 15:44:30 for Equalizer 1.2.1 by  doxygen 1.8.0