Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
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
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);
00098 }
00099 break;
00100 case CS_RENDPRI_SORT_BACK2FRONT:
00101 {
00102
00103 DistanceSorter sorter (cameraOrigin, -1);
00104 meshNode->meshes.Sort (sorter);
00105 }
00106 break;
00107 case CS_RENDPRI_SORT_FRONT2BACK:
00108 {
00109
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