CrystalSpace

Public API Reference

csplugincommon/rendermanager/standardsorter.h
Go to the documentation of this file.
00001 /*
00002     Copyright (C) 2007-2008 by Marten Svanfeldt
00003 
00004     This library is free software; you can redistribute it and/or
00005     modify it under the terms of the GNU Library General Public
00006     License as published by the Free Software Foundation; either
00007     version 2 of the License, or (at your option) any later version.
00008 
00009     This library is distributed in the hope that it will be useful,
00010     but WITHOUT ANY WARRANTY; without even the implied warranty of
00011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012     Library General Public License for more details.
00013 
00014     You should have received a copy of the GNU Library General Public
00015     License along with this library; if not, write to the Free
00016     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00017 */
00018 
00019 #ifndef __CS_CSPLUGINCOMMON_RENDERMANAGER_STANDARDSOTER_H__
00020 #define __CS_CSPLUGINCOMMON_RENDERMANAGER_STANDARDSOTER_H__
00021 
00026 #include "csplugincommon/rendermanager/operations.h"
00027 
00028 #include "ivideo/rendermesh.h"
00029 #include "csgeom/vector3.h"
00030 
00031 namespace CS
00032 {
00033 namespace RenderManager
00034 {
00035 
00054   template<typename Tree>
00055   class StandardMeshSorter    
00056   {
00057   public:
00058     StandardMeshSorter (iEngine* engine)
00059       : engine (engine), cameraOrigin (0,0,0)
00060     {
00061       // Build table of sorting options
00062       renderPriorityCount = engine->GetRenderPriorityCount ();
00063       sortingTypeTable = new int[renderPriorityCount];
00064       
00065       for (uint i = 0; i < renderPriorityCount; ++i)
00066       {       
00067         sortingTypeTable[i] = -1;
00068       }      
00069     }
00070 
00071     ~StandardMeshSorter ()
00072     {
00073       delete[] sortingTypeTable;
00074     }
00075 
00077     void SetupCameraLocation (const csVector3& vec)
00078     {
00079       cameraOrigin = vec;
00080     }
00081 
00085     void operator()(typename Tree::MeshNode* meshNode)
00086     {
00087       // Get the render priority for node
00088       CS::Graphics::RenderPriority renderPrio (meshNode->priority);
00089       
00090       int sorting = GetSorting (renderPrio);
00091       meshNode->sorting = sorting;
00092       switch (sorting)
00093       {
00094       case CS_RENDPRI_SORT_NONE:
00095         {
00096           NormalSorter sorter;
00097           meshNode->meshes.SortStable (sorter); // Use a stable sort to keep some b2f
00098         }
00099         break;
00100       case CS_RENDPRI_SORT_BACK2FRONT:
00101         {
00102           // B2F: we want to render meshes with the larger distance first.
00103           DistanceSorter sorter (cameraOrigin, -1);
00104           meshNode->meshes.Sort (sorter);
00105         }
00106         break;
00107       case CS_RENDPRI_SORT_FRONT2BACK:
00108         {
00109           // F2B: we want to render meshes with the smaller distance first.
00110           DistanceSorter sorter (cameraOrigin, 1);
00111           meshNode->meshes.Sort (sorter);
00112         }
00113         break;
00114       default:
00115         CS_ASSERT_MSG("Invalid sorting mode!", 0);
00116       }
00117     }
00118     
00119 
00120   private:
00121 
00125     class NormalSorter
00126     {
00127     public:
00128       bool operator() (typename Tree::MeshNode::SingleMesh const& m1,
00129         typename Tree::MeshNode::SingleMesh const& m2)
00130       {
00131         const csRenderMesh* rm1 = m1.renderMesh;
00132         const csRenderMesh* rm2 = m2.renderMesh;
00133 
00134         if(rm1->material < rm2->material)
00135           return true;
00136 
00137         if((rm1->material == rm2->material) &&
00138           (rm1->geometryInstance < rm2->geometryInstance))
00139           return true;
00140 
00141         return false;
00142       }
00143 
00144     };
00145 
00152     class DistanceSorter : NormalSorter
00153     {
00154     public:
00155       DistanceSorter (const csVector3& cameraOrigin, const float scaleFactor)
00156         : cameraOrigin (cameraOrigin), scaleFactor (scaleFactor)
00157       {}
00158 
00159       bool operator() (typename Tree::MeshNode::SingleMesh const& m1,
00160         typename Tree::MeshNode::SingleMesh const& m2)
00161       {
00162         const csRenderMesh* rm1 = m1.renderMesh;
00163         const csRenderMesh* rm2 = m2.renderMesh;
00164 
00165         const float distSqRm1 = scaleFactor*(rm1->worldspace_origin - cameraOrigin).SquaredNorm ();
00166         const float distSqRm2 = scaleFactor*(rm2->worldspace_origin - cameraOrigin).SquaredNorm ();
00167 
00168         if (distSqRm1 < distSqRm2)
00169           return true;
00170 
00171         if (distSqRm2 < distSqRm1)
00172           return false;
00173 
00174         return NormalSorter::operator () (m1, m2);
00175       }
00176 
00177 
00178     private:
00179       const csVector3& cameraOrigin;
00180       const float scaleFactor;
00181     };
00182   
00183     csRenderPrioritySorting GetSorting (CS::Graphics::RenderPriority renderPrio)
00184     {
00185       CS_ASSERT(renderPrio.IsValid() && renderPrio < renderPriorityCount);
00186 
00187       if (sortingTypeTable[renderPrio] < 0)
00188       {
00189         sortingTypeTable[renderPrio] = engine->GetRenderPrioritySorting (renderPrio);
00190       }
00191 
00192       return (csRenderPrioritySorting)sortingTypeTable[renderPrio];
00193     }
00194 
00195     uint renderPriorityCount;
00196     int* sortingTypeTable;
00197     iEngine* engine;
00198     csVector3 cameraOrigin;
00199   };
00200   
00202   template<typename RenderTree>  
00203   struct OperationTraits<StandardMeshSorter<RenderTree> >
00204   {
00205     typedef OperationUnordered Ordering;
00206   };
00207 
00208 }
00209 }
00210 
00211 #endif

Generated for Crystal Space 2.0 by doxygen 1.7.6.1