Equalizer  1.4.1
sliceClipping.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 "sliceClipping.h"
00030 
00031 
00032 namespace eVolve
00033 {
00034 
00035     const int SliceClipper::nSequence[8][8] = {
00036         {7,3,5,6,1,2,4,0},
00037         {6,2,4,7,0,3,5,1},
00038         {5,1,4,7,0,3,6,2},
00039         {4,0,5,6,1,2,7,3},
00040         {3,1,2,7,0,5,6,4},
00041         {2,0,3,6,1,4,7,5},
00042         {1,0,3,5,2,4,7,6},
00043         {0,1,2,4,3,5,6,7},
00044     };
00045 
00046     const float SliceClipper::sequence[64] = {
00047         0, 1, 4, 2, 3, 5, 6, 7,
00048         1, 0, 3, 5, 4, 2, 7, 6,
00049         2, 0, 6, 3, 1, 4, 7, 5,
00050         3, 1, 2, 7, 5, 0, 6, 4,
00051         4, 0, 5, 6, 2, 1, 7, 3,
00052         5, 1, 7, 4, 0, 3, 6, 2,
00053         6, 2, 4, 7, 3, 0, 5, 1,
00054         7, 3, 6, 5, 1, 2, 4, 0 };
00055 
00056     const float SliceClipper::v1[24] = {
00057         0, 1, 4, 4,
00058         1, 0, 1, 4,
00059         0, 2, 5, 5,
00060         2, 0, 2, 5,
00061         0, 3, 6, 6, 
00062         3, 0, 3, 6 };
00063 
00064     const float SliceClipper::v2[24] = {
00065         1, 4, 7, 7,
00066         5, 1, 4, 7,
00067         2, 5, 7, 7,
00068         6, 2, 5, 7,
00069         3, 6, 7, 7,
00070         4, 3, 6, 7 };
00071 
00072 
00073 void SliceClipper::updatePerFrameInfo
00074 (
00075     const eq::Matrix4d&   modelviewM,
00076     const eq::Matrix3d&   modelviewITM,
00077     const double            newSliceDistance,
00078     const eq::Range&        range
00079 )
00080 {
00081     double zRs = -1+2.*range.start;
00082     double zRe = -1+2.*range.end;
00083 
00084     //rendering parallelepipid's verteces
00085     eq::Vector4d vertices[8];
00086     vertices[0] = eq::Vector4d(-1.0,-1.0,zRs, 1.0);
00087     vertices[1] = eq::Vector4d( 1.0,-1.0,zRs, 1.0);
00088     vertices[2] = eq::Vector4d(-1.0, 1.0,zRs, 1.0);
00089     vertices[3] = eq::Vector4d( 1.0, 1.0,zRs, 1.0);
00090 
00091     vertices[4] = eq::Vector4d(-1.0,-1.0,zRe, 1.0);
00092     vertices[5] = eq::Vector4d( 1.0,-1.0,zRe, 1.0);
00093     vertices[6] = eq::Vector4d(-1.0, 1.0,zRe, 1.0);
00094     vertices[7] = eq::Vector4d( 1.0, 1.0,zRe, 1.0);
00095 
00096     for( int i=0; i<8; i++ )
00097         for( int j=0; j<3; j++)
00098             shaderVertices[ i*3+j ] = float( vertices[i][j] );
00099 
00100 
00101     this->viewVec = eq::Vector4d( -modelviewM.array[ 2],
00102                                   -modelviewM.array[ 6],
00103                                   -modelviewM.array[10],
00104                                   0.0                 );
00105 
00106     viewVecf = eq::Vector3f( float( viewVec.x( )), float( viewVec.y( )),
00107                              float( viewVec.z( )));
00108 
00109     sliceDistance = newSliceDistance;
00110 
00111     frontIndex = 0;
00112     float maxDist = float( viewVec.dot( vertices[0] ));
00113     for( int i = 1; i < 8; i++ )
00114     {
00115         const float dist = float( viewVec.dot( vertices[i] ));
00116         if ( dist > maxDist)
00117         {
00118             maxDist = dist;
00119             frontIndex = i;
00120         }
00121     }
00122 
00123     planeStart  = viewVec.dot( vertices[nSequence[frontIndex][0]] );
00124     double dS   = ceil( planeStart/sliceDistance );
00125     planeStart  = dS * sliceDistance;
00126 }
00127 
00128 
00129 eq::Vector3f SliceClipper::getPosition
00130 (
00131     const int vertexNum,
00132     const int sliceNum
00133 ) const
00134 {
00135     const float dPlaneDist = float( planeStart + sliceNum * sliceDistance );
00136     float3  Position     = float3( 0.0, 0.0, 0.0 );
00137 
00138     for( int e = 0; e < 4; e++ )
00139     {
00140         int vidx1 = 3*static_cast<int>( sequence[ 
00141                         static_cast<int>(frontIndex * 8 + v1[vertexNum*4+e])]);
00142         int vidx2 = 3*static_cast<int>( sequence[
00143                         static_cast<int>(frontIndex * 8 + v2[vertexNum*4+e])]);
00144 
00145         float3 vecV1( shaderVertices[vidx1  ],
00146                       shaderVertices[vidx1+1],
00147                       shaderVertices[vidx1+2] );
00148 
00149         float3 vecV2( shaderVertices[vidx2  ],
00150                       shaderVertices[vidx2+1],
00151                       shaderVertices[vidx2+2] );
00152 
00153         float3 vecStart = vecV1;
00154         float3 vecDir   = vecV2-vecV1;
00155 
00156         float denom = vecDir.dot( viewVecf );
00157         float lambda = (denom != 0.0f) ?
00158                        (dPlaneDist - vecStart.dot(viewVecf))/denom : -1.0f;
00159 
00160         if(( lambda >= 0.0f ) && ( lambda <= 1.0f ))
00161         {
00162             Position = vecStart + vecDir * lambda;
00163             break;
00164         }
00165     }
00166     return Position;
00167 }
00168 
00169 
00170 }
00171 
Generated on Mon Nov 26 2012 14:41:49 for Equalizer 1.4.1 by  doxygen 1.7.6.1