00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef _3D_LIGHT_SOURCE_MANAGER_H
00028 #define _3D_LIGHT_SOURCE_MANAGER_H
00029
00032
00033 #include <PVLE/Export.h>
00034 #include <PVLE/Util/Util.h>
00035 #include <PVLE/Util/Callback.h>
00036 #include <PVLE/Util/Singleton.h>
00037 #include <osg/LightSource>
00038 #include <osg/observer_ptr>
00039 #include <boost/operators.hpp>
00040 #include <vector>
00041
00042
00043 class LightSourceManager;
00044
00048 class LightSourceUserCallback : public Util::Callback<LightSourceUserCallback> {
00049 public:
00053 virtual bool onSourceTaken(LightSourceManager * pLightSourceManager, osg::Referenced * pUserObject, UINT lightNumber) {
00054 if (_nestedCallback.valid()) return _nestedCallback->onSourceTaken(pLightSourceManager, pUserObject, lightNumber);
00055 else return false;
00056 }
00057
00060 virtual bool onSourceAvailable(LightSourceManager * pLightSourceManager, osg::Referenced * pUserObject, UINT lightNumber) =0;
00061
00064 virtual void onUserDropped(LightSourceManager * pLightSourceManager, osg::Referenced * pUserObject) =0;
00065 };
00066
00067
00068
00076 class PVLE_EXPORT LightSourceManager {
00077 public:
00078 typedef float Priority;
00079 static const UINT MAX_LIGHT = 8;
00080
00081 LightSourceManager(UINT _firstManagedLight = 0, UINT _lastManagedLight = MAX_LIGHT) : firstManagedLight(_firstManagedLight), lastManagedLight(_lastManagedLight) {
00082
00083 }
00084
00092 UINT request(osg::Referenced * pNewUser, Priority priority, LightSourceUserCallback * pUserCB = NULL, bool enqueue = false);
00093
00096
00097
00100 void remove(osg::Referenced * pUserObject);
00101
00103 void clear();
00104
00105 const LightSourceUserCallback * getUserCallback(const osg::Referenced * pUserObject) const { return getUser(pUserObject)->pUserCB.get(); }
00106 LightSourceUserCallback * getUserCallback(osg::Referenced * pUserObject) { return getUser(pUserObject)->pUserCB.get(); }
00107 void setUserCallback(osg::Referenced * pUserObject, LightSourceUserCallback * pUserCB) { getUser(pUserObject)->pUserCB = pUserCB; }
00108
00111 void updatePriority(osg::Referenced * pUserObject, Priority newPriority) { getUser(pUserObject)->priority = newPriority; }
00112
00115 void checkForAvailableLights();
00116
00117 void setManagedLights(UINT _firstManagedLight, UINT _lastManagedLight);
00118
00119 protected:
00120 UINT firstManagedLight;
00121 UINT lastManagedLight;
00122
00124 class User : public boost::totally_ordered<User> {
00125 public:
00126 User() : priority(0) {}
00127
00128
00129 osg::observer_ptr<osg::Referenced> pUserObject;
00130 Priority priority;
00131 osg::ref_ptr<LightSourceUserCallback> pUserCB;
00132
00134 bool check() { if (pUserObject.valid()) return true; pUserCB = NULL; return false; }
00135 void reset() { pUserObject = NULL; pUserCB = NULL; }
00136
00137 inline bool operator<(const User & u) const { return priority < u.priority; }
00138 inline bool operator==(const User & u) const { return priority == u.priority; }
00139 User & operator=(const User & u) {
00140 pUserObject = u.pUserObject;
00141 priority = u.priority;
00142 pUserCB = u.pUserCB;
00143 return *this;
00144 }
00145 };
00146
00147 User users[MAX_LIGHT];
00148
00150 User * getUser(const osg::Referenced * pUserObject);
00152 const User * getUser(const osg::Referenced * pUserObject) const;
00153
00155 void lightAvailable(UINT lightNumber);
00156 void lightAvailable(UINT lightNumber, std::vector<User>::iterator & itBestCandidate);
00157
00158 inline void lightAvailable(User * pEmptyUser) {
00159 int pos = pEmptyUser - users;
00160 ASSERT(pos>=0 && pos<MAX_LIGHT);
00161 lightAvailable(static_cast<UINT>(MAX_LIGHT));
00162 }
00163
00164
00166
00168 void cleanQueue();
00169
00170 void doEnqueue(osg::Referenced * pNewUser, Priority priority, LightSourceUserCallback * pUserCB);
00171 inline void doEnqueue(User * pUserObject) { doEnqueue(pUserObject->pUserObject.get(), pUserObject->priority, pUserObject->pUserCB.get()); }
00172
00173 void unManage(UINT i, bool canEnqueue);
00174 std::vector<User>::iterator getBestEnqueuedCandidate();
00175
00176 std::vector<User> usersQueue;
00177 };
00178
00179
00180
00181 #endif // _3D_LIGHT_SOURCE_MANAGER_H