# Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics

[Home] [Tutorials] [All Classes] [Grouped Classes]

- Main Page
- Related Pages
- Namespaces
- Classes
- Files

- File List
- File Members

# D:/VL/BuildSystem/VL_DISTRO/Visualization_Library_SDK/src/vlVolume/RaycastVolume.cpp

Go to the documentation of this file.

    00001 /**************************************************************************************/
    00002 /*                                                                                    */
    00003 /*  Visualization Library                                                             */
    00004 /*  http://www.visualizationlibrary.org                                               */
    00005 /*                                                                                    */
    00006 /*  Copyright (c) 2005-2010, Michele Bosi                                             */
    00007 /*  All rights reserved.                                                              */
    00008 /*                                                                                    */
    00009 /*  Redistribution and use in source and binary forms, with or without modification,  */
    00010 /*  are permitted provided that the following conditions are met:                     */
    00011 /*                                                                                    */
    00012 /*  - Redistributions of source code must retain the above copyright notice, this     */
    00013 /*  list of conditions and the following disclaimer.                                  */
    00014 /*                                                                                    */
    00015 /*  - Redistributions in binary form must reproduce the above copyright notice, this  */
    00016 /*  list of conditions and the following disclaimer in the documentation and/or       */
    00017 /*  other materials provided with the distribution.                                   */
    00018 /*                                                                                    */
    00019 /*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
    00020 /*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
    00021 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
    00022 /*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
    00023 /*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
    00024 /*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
    00025 /*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
    00026 /*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
    00027 /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
    00028 /*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
    00029 /*                                                                                    */
    00030 /**************************************************************************************/
    00031
    00032 #include <vlVolume/RaycastVolume.hpp>
    00033 #include <vlGraphics/GLSL.hpp>
    00034 #include <vlGraphics/Light.hpp>
    00035 #include <vlGraphics/Camera.hpp>
    00036
    00037 using namespace vl;
    00038
    00065 RaycastVolume::RaycastVolume()
    00066 {
    00067   VL_DEBUG_SET_OBJECT_NAME()
    00068   // box geometry
    00069   mGeometry = new Geometry;
    00070
    00071   // install vertex coords array
    00072   mVertCoord = new ArrayFloat3;
    00073   mVertCoord->resize( 8 );
    00074   mGeometry->setVertexArray( mVertCoord.get() );
    00075
    00076   // install texture coords array
    00077   mTexCoord = new ArrayFloat3;
    00078   mTexCoord->resize( 8 );
    00079   mGeometry->setTexCoordArray( 0, mTexCoord.get() );
    00080
    00081   // install index array
    00082   ref<DrawElementsUInt> de = new DrawElementsUInt( PT_QUADS );
    00083   mGeometry->drawCalls()->push_back( de.get() );
    00084   unsigned int de_indices[] =
    00085   {
    00086     0,1,2,3, 1,5,6,2, 5,4,7,6, 4,0,3,7, 3,2,6,7, 4,5,1,0
    00087   };
    00088   de->indexBuffer()->resize( 4*6 );
    00089   memcpy( de->indexBuffer()->ptr(), de_indices, sizeof( de_indices ) );
    00090
    00091   // generate default texture coordinates
    00092   fvec3 texc[] =
    00093   {
    00094     fvec3( 0,0,0 ), fvec3( 1,0,0 ), fvec3( 1,1,0 ), fvec3( 0,1,0 ),
    00095     fvec3( 0,0,1 ), fvec3( 1,0,1 ), fvec3( 1,1,1 ), fvec3( 0,1,1 )
    00096   };
    00097   memcpy( mTexCoord->ptr(), texc, sizeof( texc ) );
    00098
    00099   // default box dimensions and geometry
    00100   setBox( AABB( vec3( 0,0,0 ), vec3( 1,1,1 ) ) );
    00101 }
    00102 //-----------------------------------------------------------------------------
    00111 void RaycastVolume::updateUniforms( vl::Actor*actor, vl::real, const vl::Camera* camera, vl::Renderable*, const vl::Shader* shader )
    00112 {
    00113   const GLSLProgram* glsl = shader->getGLSLProgram();
    00114   VL_CHECK( glsl );
    00115
    00116   // used later
    00117   fmat4 inv_mat;
    00118   if (actor->transform())
    00119     inv_mat = ( fmat4 )actor->transform()->worldMatrix().getInverse();
    00120
    00121   if ( glsl->getUniformLocation( "light_position" ) != -1 && glsl->getUniformLocation( "light_enable" ) != -1 )
    00122   {
    00123     // computes up to 4 light positions ( in object space ) and enables
    00124
    00125     int light_enable[4] = { 0,0,0,0 };
    00126     fvec3 light_position[4];
    00127     bool has_lights = false;
    00128
    00129     for( int i=0; i<4; ++i )
    00130     {
    00131       const vl::Light* light = shader->getLight( i );
    00132       light_enable[i] = light != NULL;
    00133       if ( light )
    00134       {
    00135         has_lights = true;
    00136         // light position following transform
    00137         if ( light->boundTransform() )
    00138           light_position[i] = ( fmat4 )light->boundTransform()->worldMatrix() * light->position().xyz();
    00139         // light position following camera
    00140         else
    00141           light_position[i] = ( ( fmat4 )camera->modelingMatrix() * light->position() ).xyz();
    00142
    00143         // light position in object space
    00144         if ( actor->transform() )
    00145           light_position[i] = inv_mat * light_position[i];
    00146       }
    00147     }
    00148
    00149     actor->gocUniform( "light_position" )->setUniform( 4, light_position );
    00150     actor->gocUniform( "light_enable" )->setUniform1i( 4, light_enable );
    00151   }
    00152
    00153   if ( glsl->getUniformLocation( "eye_position" ) != -1 )
    00154   {
    00155     // pass the eye position in object space
    00156
    00157     // eye postion
    00158     fvec3 eye = ( fvec3 )camera->modelingMatrix().getT();
    00159     // world to object space
    00160     if ( actor->transform() )
    00161       eye = inv_mat * eye;
    00162     actor->gocUniform( "eye_position" )->setUniform( eye );
    00163   }
    00164
    00165   if ( glsl->getUniformLocation( "eye_look" ) != -1 )
    00166   {
    00167     // pass the eye look direction in object space
    00168
    00169     // eye postion
    00170     fvec3 look = -( fvec3 )camera->modelingMatrix().getZ();
    00171     // world to object space
    00172     if ( actor->transform() )
    00173     {
    00174       // look = inv_mat * look;
    00175       look = ( fmat4 )actor->transform()->worldMatrix().getInverse().getTransposed() * look;
    00176     }
    00177     actor->gocUniform( "eye_look" )->setUniform( look );
    00178   }
    00179 }
    00180 //-----------------------------------------------------------------------------
    00181 void RaycastVolume::bindActor( Actor* actor )
    00182 {
    00183   actor->actorEventCallbacks()->erase( this );
    00184   actor->actorEventCallbacks()->push_back( this );
    00185   actor->setLod( 0, mGeometry.get() );
    00186 }
    00187 //-----------------------------------------------------------------------------
    00188 void RaycastVolume::onActorRenderStarted( Actor* actor, real clock, const Camera* camera, Renderable* rend, const Shader* shader, int pass )
    00189 {
    00190   if ( pass>0 )
    00191     return;
    00192
    00193   // setup uniform variables
    00194
    00195   if ( shader->getGLSLProgram() )
    00196     updateUniforms( actor, clock, camera, rend, shader );
    00197 }
    00198 //-----------------------------------------------------------------------------
    00199 void RaycastVolume::generateTextureCoordinates( const ivec3& size )
    00200 {
    00201   if ( !size.x() || !size.y() || !size.z() )
    00202   {
    00203     Log::error( "RaycastVolume::generateTextureCoordinates(): failed! The size passed does not represent a 3D image.\n" );
    00204     return;
    00205   }
    00206
    00207   float dx = 0.5f/size.x();
    00208   float dy = 0.5f/size.y();
    00209   float dz = 0.5f/size.z();
    00210
    00211   float x0 = 0.0f + dx;
    00212   float x1 = 1.0f - dx;
    00213   float y0 = 0.0f + dy;
    00214   float y1 = 1.0f - dy;
    00215   float z0 = 0.0f + dz;
    00216   float z1 = 1.0f - dz;
    00217
    00218   fvec3 texc[] =
    00219   {
    00220     fvec3( x0,y0,z1 ), fvec3( x1,y0,z1 ), fvec3( x1,y1,z1 ), fvec3( x0,y1,z1 ), // mic fixme: i don't remember why we need z1 here and z0 below...
    00221     fvec3( x0,y0,z0 ), fvec3( x1,y0,z0 ), fvec3( x1,y1,z0 ), fvec3( x0,y1,z0 ),
    00222   };
    00223   memcpy( mTexCoord->ptr(), texc, sizeof( texc ) );
    00224 }
    00225 //-----------------------------------------------------------------------------
    00226 void RaycastVolume::generateTextureCoordinates(const ivec3& img_size, const ivec3& min_corner, const ivec3& max_corner)
    00227 {
    00228     if (!img_size.x() || !img_size.y() || !img_size.z())
    00229     {
    00230         Log::error("RaycastVolume::setDisplayRegion(): failed! The size passed does not represent a 3D image.\n");
    00231         return;
    00232     }
    00233
    00234     float dx = 0.5f/img_size.x();
    00235     float dy = 0.5f/img_size.y();
    00236     float dz = 0.5f/img_size.z();
    00237
    00238     float x0 = min_corner.x()/(float)img_size.x() + dx;
    00239     float x1 = max_corner.x()/(float)img_size.x() - dx;
    00240     float y0 = min_corner.y()/(float)img_size.y() + dy;
    00241     float y1 = max_corner.y()/(float)img_size.y() - dy;
    00242     float z0 = min_corner.z()/(float)img_size.z() + dz;
    00243     float z1 = max_corner.z()/(float)img_size.z() - dz;
    00244
    00245     fvec3 texc[] =
    00246     {
    00247       fvec3( x0,y0,z1 ), fvec3( x1,y0,z1 ), fvec3( x1,y1,z1 ), fvec3( x0,y1,z1 ),
    00248       fvec3( x0,y0,z0 ), fvec3( x1,y0,z0 ), fvec3( x1,y1,z0 ), fvec3( x0,y1,z0 ),
    00249     };
    00250     memcpy( mTexCoord->ptr(), texc, sizeof(texc) );
    00251 }
    00252 //-----------------------------------------------------------------------------
    00253 void RaycastVolume::setBox( const AABB& box )
    00254 {
    00255   mBox = box;
    00256   // generate the box geometry
    00257   float x0 = box.minCorner().x();
    00258   float y0 = box.minCorner().y();
    00259   float z0 = box.minCorner().z();
    00260   float x1 = box.maxCorner().x();
    00261   float y1 = box.maxCorner().y();
    00262   float z1 = box.maxCorner().z();
    00263   fvec3 box_verts[] =
    00264   {
    00265     fvec3( x0,y0,z1 ), fvec3( x1,y0,z1 ), fvec3( x1,y1,z1 ), fvec3( x0,y1,z1 ),
    00266     fvec3( x0,y0,z0 ), fvec3( x1,y0,z0 ), fvec3( x1,y1,z0 ), fvec3( x0,y1,z0 ),
    00267   };
    00268   memcpy( mVertCoord->ptr(), box_verts, sizeof( box_verts ) );
    00269   mGeometry->setBoundsDirty( true );
    00270 }
    00271 //-----------------------------------------------------------------------------

Visualization Library v2011.09.1162 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu Jan 26 2012 00:43:46.
Permission is granted to use this page to write and publish articles regarding Visualization Library.