# Visualization Library

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

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

- Main Page
- 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.com                                               */
    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
    00109     vl::ref<vl::Geometry> portal_geom = new vl::Geometry;
    00110     vl::ref<vl::ArrayFloat3> vert_array = new vl::ArrayFloat3;
    00111     portal_geom->setVertexArray(vert_array.get());
    00112     portal_geom->setColor(portal_color);
    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     portal_geom->drawCalls()->push_back( new vl::DrawArrays(vl::PT_LINE_LOOP, 0, (int)vert_array->size()) );
    00118     portal_geom->drawCalls()->push_back( new vl::DrawArrays(vl::PT_LINE_LOOP, 0, (int)vert_array->size()) );
    00119     portal_geom->drawCalls()->push_back( new vl::DrawArrays(vl::PT_POLYGON,   0, (int)vert_array->size()) );
    00120     mTempActors.push_back( new vl::Actor(portal_geom.get(), portal_fx.get(), NULL) );
    00121     mPortalActorMap[portal] = mTempActors.back();
    00122   }
    00123 }
    00124 //-----------------------------------------------------------------------------
    00125 void SceneManagerPortals::extractActors(ActorCollection& list)
    00126 {
    00127   for(unsigned i=0; i<mSectors.size(); ++i)
    00128     for(int j=0; j<mSectors[i]->actors()->size(); ++j)
    00129       list.push_back( mSectors[i]->actors()->at(j) );
    00130 }
    00131 //-----------------------------------------------------------------------------
    00132 void SceneManagerPortals::extractVisibleActors(ActorCollection& list, const Camera* camera)
    00133 {
    00134   if (cullingEnabled())
    00135   {
    00136     Sector* start = computeStartingSector(camera);
    00137     if (!start)
    00138       extractActors(list);
    00139     else
    00140     {
    00141       ++mVisitTick;
    00142       mTempActors.clear();
    00143       mPortalActorMap.clear();
    00144       mFrustumStack.clear();
    00145
    00146       mFrustumStack.push_back(camera->frustum());
    00147       start->executeCallbacks(camera,this,NULL);
    00148       visitSector(NULL, start, camera->inverseViewMatrix().getT(), camera);
    00149
    00150       // avoid reporting duplicates
    00151       std::sort(mTempActors.begin(), mTempActors.end());
    00152       std::vector< ref<Actor> >::iterator new_end = std::unique(mTempActors.begin(), mTempActors.end());
    00153       for(std::vector< ref<Actor> >::iterator it = mTempActors.begin(); it != new_end; ++it)
    00154         list.push_back(it->get());
    00155     }
    00156   }
    00157   else
    00158     extractActors(list);
    00159 }
    00160 //-----------------------------------------------------------------------------
    00161 void SceneManagerPortals::visitSector(Sector* prev, Sector* sector, const vec3& eye, const Camera* camera)
    00162 {
    00163   // this sector is visible so we add the visible objects
    00164   for(int j=0; j<sector->actors()->size(); ++j)
    00165   {
    00166     if (isEnabled(sector->actors()->at(j)))
    00167     {
    00168       sector->actors()->at(j)->computeBounds();
    00169       bool visible = true;
    00170       for(unsigned i=0; visible && i<mFrustumStack.size(); ++i)
    00171         visible = visible & !mFrustumStack[i].cull( sector->actors()->at(j)->boundingBox() );
    00172       if( visible )
    00173         mTempActors.push_back( sector->actors()->at(j) );
    00174     }
    00175   }
    00176   // check the visible portals
    00177   for(unsigned j=0; j<sector->portals().size(); ++j)
    00178   {
    00179     if(showPortals())
    00180       renderPortal(sector->portals()[j].get());
    00181
    00182     // open/closed portals.
    00183     if(!sector->portals()[j]->isOpen())
    00184       continue;
    00185
    00186     if (sector->portals()[j]->mVisitTick == mVisitTick)
    00187       continue;
    00188     else
    00189       sector->portals()[j]->mVisitTick = mVisitTick;
    00190
    00191     Sector* target_sec = sector->portals()[j]->targetSector();
    00192     VL_CHECK(target_sec != sector)
    00193     if ( target_sec != prev )
    00194     {
    00195       bool visible = true;
    00196       for(unsigned i=0; visible && i<mFrustumStack.size(); ++i)
    00197         visible = visible & !mFrustumStack[i].cull( sector->portals()[j]->geometry() );
    00198
    00199       if (visible)
    00200       {
    00201         // make visiting_portal_frustum
    00202         Frustum portal_frustum;
    00203         portal_frustum.planes().resize(sector->portals()[j]->geometry().size());
    00204         bool flip = dot((fvec3)eye - sector->portals()[j]->geometry()[0], sector->portals()[j]->normal()) < 0;
    00205         for(unsigned i=0; i<sector->portals()[j]->geometry().size(); ++i)
    00206         {
    00207           int i2 = (i+1) % sector->portals()[j]->geometry().size();
    00208           vec3 v1 = (vec3)sector->portals()[j]->geometry()[i]  - eye;
    00209           vec3 v2 = (vec3)sector->portals()[j]->geometry()[i2] - eye;
    00210           vec3 n = cross(v1,v2);
    00211           n.normalize();
    00212           if (flip)
    00213             n = -n;
    00214           portal_frustum.setPlane(i, Plane(dot(n,eye),n));
    00215         }
    00216
    00217         mFrustumStack.push_back(portal_frustum);
    00218         sector->executeCallbacks(camera,this,sector->portals()[j].get());
    00219         visitSector(sector, sector->portals()[j]->targetSector(), eye, camera);
    00220         mFrustumStack.pop_back();
    00221       }
    00222     }
    00223   }
    00224 }
    00225 //-----------------------------------------------------------------------------
    00226 void SceneManagerPortals::computePortalNormals()
    00227 {
    00228   for(unsigned i=0; i<mSectors.size(); ++i)
    00229     for(unsigned j=0; j<mSectors[i]->portals().size(); ++j)
    00230       mSectors[i]->portals()[j]->computeNormal();
    00231 }
    00232 //-----------------------------------------------------------------------------
    00233 Sector* SceneManagerPortals::computeStartingSector(const Camera* camera)
    00234 {
    00235   vec3 eye = camera->inverseViewMatrix().getT();
    00236   for(unsigned i=0; i<mSectors.size(); ++i)
    00237   {
    00238     for(unsigned j=0; j<mSectors[i]->volumes().size(); ++j)
    00239     {
    00240       if (sectors()[i]->volumes()[j].isInside(eye))
    00241         return sectors()[i].get();
    00242     }
    00243   }
    00244   return externalSector();
    00245 }
    00246 //-----------------------------------------------------------------------------

Visualization Library v2011.05.1142 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 26 2011 22:51:25.
Permission is granted to use this page to write and publish articles regarding Visualization Library.