# 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/vlGraphics/SceneManagerPortals.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 <vlGraphics/SceneManagerPortals.hpp>
    00033 #include <vlGraphics/Geometry.hpp>
    00034 #include <vlCore/Say.hpp>
    00035 #include <vlGraphics/Camera.hpp>
    00036
    00037 using namespace vl;
    00038
    00039 //-----------------------------------------------------------------------------
    00040 // Portal
    00041 //-----------------------------------------------------------------------------
    00042 bool Portal::computeNormal()
    00043 {
    00044   mNormal = 0;
    00045   if (geometry().size() < 3)
    00046   {
    00047     vl::Log::error("Portal::computeNormal() error, no portal geometry defined.\n");
    00048     return false;
    00049   }
    00050   if (!mTargetSector)
    00051   {
    00052     vl::Log::error("Portal::computeNormal() error, no sector bound to this portal.\n");
    00053     return false;
    00054   }
    00055
    00056   fvec3 v0 = geometry()[0];
    00057   fvec3 v1 = geometry()[1] - v0;
    00058   fvec3 v2 = geometry()[2] - v0;
    00059   mNormal = cross(v1,v2);
    00060
    00061   return true;
    00062 }
    00063 //-----------------------------------------------------------------------------
    00064 // Sector
    00065 //-----------------------------------------------------------------------------
    00066 AABB Sector::computeBoundingBox()
    00067 {
    00068   AABB aabb;
    00069   for(int i=0; i<actors()->size(); ++i)
    00070   {
    00071     actors()->at(i)->computeBounds();
    00072     aabb += actors()->at(i)->boundingBox();
    00073   }
    00074   return aabb;
    00075 }
    00076 //-----------------------------------------------------------------------------
    00077 void Sector::executeCallbacks(const Camera*cam,SceneManagerPortals* psm, Portal*p)
    00078 {
    00079   for(unsigned i=0; i<callbacks().size(); ++i)
    00080     callbacks()[i]->operator()(cam,psm,this,p);
    00081 }
    00082 //-----------------------------------------------------------------------------
    00083 // SceneManagerPortals
    00084 //-----------------------------------------------------------------------------
    00085 void SceneManagerPortals::initialize()
    00086 {
    00087   computePortalNormals();
    00088   for(unsigned i=0; i<mSectors.size(); ++i)
    00089   {
    00090     if (mSectors[i]->volumes().empty())
    00091       vl::Log::error( vl::Say("Sector #%n does not have any volume!\n") << i );
    00092     for(unsigned j=0; j<mSectors[i]->portals().size(); ++j)
    00093       if (!mSectors[i]->portals()[j]->targetSector())
    00094         vl::Log::error( vl::Say("In Sector #%n Portal #%n does not have any target sector!\n") << i << j);
    00095   }
    00096 }
    00097 //-----------------------------------------------------------------------------
    00098 void SceneManagerPortals::renderPortal(Portal* portal)
    00099 {
    00100   if (mPortalActorMap.find(portal) == mPortalActorMap.end())
    00101   {
    00102     const fvec4 portal_color = fvec4(1,0,0,0.25f);
    00103     vl::ref<vl::Effect> portal_fx = new vl::Effect;
    00104     /*portal_fx->shader()->enable(vl::EN_DEPTH_TEST);
    00105     portal_fx->shader()->gocDepthFunc()->set(vl::FU_LEQUAL);*/
    00106     portal_fx->shader()->enable(vl::EN_BLEND);
    00107     portal_fx->shader()->gocLineWidth()->set(2.0f);
    00108     portal_fx->shader()->gocColor()->setValue(portal_color);
    00109
    00110     vl::ref<vl::Geometry> portal_geom = new vl::Geometry;
    00111     vl::ref<vl::ArrayFloat3> vert_array = new vl::ArrayFloat3;
    00112     portal_geom->setVertexArray(vert_array.get());
    00113     vert_array->resize(portal->geometry().size());
    00114     for(unsigned int i=0; i<portal->geometry().size(); ++i)
    00115       vert_array->at(i) = portal->geometry()[i];
    00116     portal_geom->drawCalls()->push_back( new vl::DrawArrays(vl::PT_LINE_LOOP, 0, (int)vert_array->size()) );
    00117 #if defined(VL_OPENGL)
    00118     portal_geom->drawCalls()->push_back( new vl::DrawArrays(vl::PT_POLYGON,   0, (int)vert_array->size()) );
    00119 #endif
    00120     mPortalActorMap[portal] = new vl::Actor(portal_geom.get(), portal_fx.get(), NULL);
    00121   }
    00122 }
    00123 //-----------------------------------------------------------------------------
    00124 void SceneManagerPortals::extractActors(ActorCollection& list)
    00125 {
    00126   for(unsigned i=0; i<mSectors.size(); ++i)
    00127     for(int j=0; j<mSectors[i]->actors()->size(); ++j)
    00128       list.push_back( mSectors[i]->actors()->at(j) );
    00129 }
    00130 //-----------------------------------------------------------------------------
    00131 void SceneManagerPortals::extractVisibleActors(ActorCollection& list, const Camera* camera)
    00132 {
    00133   if (cullingEnabled())
    00134   {
    00135     Sector* start = computeStartingSector(camera);
    00136     if (!start)
    00137       extractActors(list);
    00138     else
    00139     {
    00140       ++mVisitTick;
    00141       mTempActors.clear();
    00142       mFrustumStack.clear();
    00143
    00144       mFrustumStack.push_back(camera->frustum());
    00145       start->executeCallbacks(camera,this,NULL);
    00146       visitSector(NULL, start, camera->modelingMatrix().getT(), camera);
    00147
    00148       // insert portal actors
    00149       if (showPortals())
    00150       {
    00151         for(std::map<Portal*, ref<Actor> >::const_iterator it = mPortalActorMap.begin(); it != mPortalActorMap.end(); ++it)
    00152           mTempActors.push_back(it->second);
    00153       }
    00154
    00155       // mic fixme: isn't quicker to use sets instead of sort()+unique()?
    00156       // avoid reporting duplicates
    00157       std::sort(mTempActors.begin(), mTempActors.end());
    00158       std::vector< ref<Actor> >::iterator new_end = std::unique(mTempActors.begin(), mTempActors.end());
    00159       for(std::vector< ref<Actor> >::iterator it = mTempActors.begin(); it != new_end; ++it)
    00160         list.push_back(it->get());
    00161     }
    00162   }
    00163   else
    00164     extractActors(list);
    00165 }
    00166 //-----------------------------------------------------------------------------
    00167 void SceneManagerPortals::visitSector(Sector* prev, Sector* sector, const vec3& eye, const Camera* camera)
    00168 {
    00169   // this sector is visible so we add the visible objects
    00170   for(int j=0; j<sector->actors()->size(); ++j)
    00171   {
    00172     if (isEnabled(sector->actors()->at(j)))
    00173     {
    00174       sector->actors()->at(j)->computeBounds();
    00175       bool visible = true;
    00176       for(unsigned i=0; visible && i<mFrustumStack.size(); ++i)
    00177         visible = visible & !mFrustumStack[i].cull( sector->actors()->at(j)->boundingBox() );
    00178       if( visible )
    00179         mTempActors.push_back( sector->actors()->at(j) );
    00180     }
    00181   }
    00182   // check the visible portals
    00183   for(unsigned j=0; j<sector->portals().size(); ++j)
    00184   {
    00185     if(showPortals())
    00186       renderPortal(sector->portals()[j].get());
    00187
    00188     // open/closed portals.
    00189     if(!sector->portals()[j]->isOpen())
    00190       continue;
    00191
    00192     if (sector->portals()[j]->mVisitTick == mVisitTick)
    00193       continue;
    00194     else
    00195       sector->portals()[j]->mVisitTick = mVisitTick;
    00196
    00197     Sector* target_sec = sector->portals()[j]->targetSector();
    00198     VL_CHECK(target_sec != sector)
    00199     if ( target_sec != prev )
    00200     {
    00201       bool visible = true;
    00202       for(unsigned i=0; visible && i<mFrustumStack.size(); ++i)
    00203         visible = visible & !mFrustumStack[i].cull( sector->portals()[j]->geometry() );
    00204
    00205       if (visible)
    00206       {
    00207         // make visiting_portal_frustum
    00208         Frustum portal_frustum;
    00209         portal_frustum.planes().resize(sector->portals()[j]->geometry().size());
    00210         bool flip = dot((fvec3)eye - sector->portals()[j]->geometry()[0], sector->portals()[j]->normal()) < 0;
    00211         for(unsigned i=0; i<sector->portals()[j]->geometry().size(); ++i)
    00212         {
    00213           int i2 = (i+1) % sector->portals()[j]->geometry().size();
    00214           vec3 v1 = (vec3)sector->portals()[j]->geometry()[i]  - eye;
    00215           vec3 v2 = (vec3)sector->portals()[j]->geometry()[i2] - eye;
    00216           vec3 n = cross(v1,v2);
    00217           n.normalize();
    00218           if (flip)
    00219             n = -n;
    00220           portal_frustum.setPlane(i, Plane(dot(n,eye),n));
    00221         }
    00222
    00223         mFrustumStack.push_back(portal_frustum);
    00224         sector->executeCallbacks(camera,this,sector->portals()[j].get());
    00225         visitSector(sector, sector->portals()[j]->targetSector(), eye, camera);
    00226         mFrustumStack.pop_back();
    00227       }
    00228     }
    00229   }
    00230 }
    00231 //-----------------------------------------------------------------------------
    00232 void SceneManagerPortals::computePortalNormals()
    00233 {
    00234   for(unsigned i=0; i<mSectors.size(); ++i)
    00235     for(unsigned j=0; j<mSectors[i]->portals().size(); ++j)
    00236       mSectors[i]->portals()[j]->computeNormal();
    00237 }
    00238 //-----------------------------------------------------------------------------
    00239 Sector* SceneManagerPortals::computeStartingSector(const Camera* camera)
    00240 {
    00241   vec3 eye = camera->modelingMatrix().getT();
    00242   for(unsigned i=0; i<mSectors.size(); ++i)
    00243   {
    00244     for(unsigned j=0; j<mSectors[i]->volumes().size(); ++j)
    00245     {
    00246       if (sectors()[i]->volumes()[j].isInside(eye))
    00247         return sectors()[i].get();
    00248     }
    00249   }
    00250   return externalSector();
    00251 }
    00252 //-----------------------------------------------------------------------------

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