Equalizer
1.4.1
|
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 pSsub.normalize(); 00083 dotVals.push_back( norm.dot( pSsub )); 00084 //check if any slices need to be rendered in reverse order 00085 size_t minPos = std::numeric_limits< size_t >::max(); 00086 for( size_t i=0; i<dotVals.size()-1; i++ ) 00087 if( dotVals[i] > 0 && dotVals[i+1] > 0 ) 00088 minPos = static_cast< int >( i ); 00089 00090 const size_t nFrames = frames.size(); 00091 minPos++; 00092 if( minPos < frames.size()-1 ) 00093 { 00094 eq::Frames framesTmp = frames; 00095 00096 // copy slices that should be rendered first 00097 memcpy( &frames[ nFrames-minPos-1 ], &framesTmp[0], 00098 (minPos+1)*sizeof( eq::Frame* ) ); 00099 00100 // copy slices that should be rendered last, in reverse order 00101 for( size_t i=0; i<nFrames-minPos-1; i++ ) 00102 frames[ i ] = framesTmp[ nFrames-i-1 ]; 00103 } 00104 } 00105 00106 } 00107