Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics
[Home] [Tutorials] [All Classes] [Grouped Classes]

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

Visualization Library 2011.09.1160 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 2 2013 13:40:40.
Permission is granted to use this page to write and publish articles regarding Visualization Library.