1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #ifndef CL_TIMED_FX_MANAGER_H
20 #define CL_TIMED_FX_MANAGER_H
22 #include "nel/misc/vector.h"
23 #include "nel/misc/noise_value.h"
24 #include "game_share/season.h"
25 #include "time_client.h"
26 #include "fx_manager.h"
32 class UParticleSystemInstance
;
36 /** A fx that must be spawn at a given season and hour
37 * \author Nicolas Vizerie
38 * \author Nevrax France
44 NLMISC::CVector SpawnPosition
;
46 NLMISC::CVector Scale
;
47 const CSeasonFXSheet
*FXSheet
;
49 bool FromIG
; // true if the fx comes from an ig, or false if it was generated dynamically
52 CTimedFX() : SpawnPosition(0.f
, 0.f
, 0.f
), FXSheet(NULL
)
58 NLMISC::CMatrix
getInstanceMatrix() const;
61 typedef std::vector
<CTimedFX
> TTimedFXGroup
;
63 /** Manager to spawn fxs at a given season and hour.
64 * \author Nicolas Vizerie
65 * \author Nevrax France
74 CClientDate Date
; // the date at which the FX must be added / removed
76 CManagedFX
*FX
; // managed FX
77 bool operator < (const CTimeStampedFX
&rhs
) const
79 if (Date
== rhs
.Date
) return FX
< rhs
.FX
;
80 else return Date
< rhs
.Date
;
81 } // we want to deal with early dates sooner
82 bool operator == (const CTimeStampedFX
&rhs
) const { return Date
== rhs
.Date
&& FX
== rhs
.FX
; }
83 CTimeStampedFX() : FX(NULL
) {}
85 typedef std::set
<CTimeStampedFX
> TTimeStampedFXPtrSet
;
86 struct CManagedFXGroup
;
87 struct CCandidateFXListHead
;
88 /** A managed FX. Unless it is flagged as 'always intanciated', or is in a group that is shutting down,
89 * such a fx can only be in one set : _FXToAdd if it is not currently instanciated (or is shutting down), and _FXToRemove if it is instanciated and is not being shut down.
90 * and will be removed in the future.
92 class CManagedFX
: public CTimedFX
95 enum TState
{ Unknown
= 0, Permanent
, InAddList
, InRemoveList
};
97 CManagedFXGroup
*OwnerGroup
;
99 NL3D::UParticleSystemInstance Instance
; // Pointer to the actual FX. NULL if failed to instanciate or if not instanciated
101 TTimeStampedFXPtrSet::iterator SetHandle
; // if the fx is in a list (see its state), then it is an iterator into that list (for removal)
103 CManagedFX
**_PrevCandidateFX
; // if the fx has asked to be instanciated, it is inserted in a list of candidate fxs. points the previous "Next" pointer
104 // even if the fx is currently instanciated, it remains in that list (those are the potnetially instanciated fxs)
105 CManagedFX
*_NextCandidateFX
; // next candidate FX
107 CManagedFX
**_PrevInstanciatedFX
; // link into instanciated fx list, prev (is also a candidate)
108 CManagedFX
*_NextInstanciatedFX
; // link into instanciated fx list, next
123 _PrevCandidateFX
= NULL
;
124 _NextCandidateFX
= NULL
;
126 _PrevInstanciatedFX
= NULL
;
127 _NextInstanciatedFX
= NULL
;
129 // compute start hour of that fx for the given day
130 void computeStartHour(sint32 cycle
, CClientDate
&resultDate
, float cycleLength
, float dayLength
, const NLMISC::CNoiseValue
&nv
) const;
131 // compute end hour of that fx for the given day
132 void computeEndHour(sint32 cycle
, CClientDate
&resultDate
, float cycleLength
, float dayLength
, const NLMISC::CNoiseValue
&nv
) const;
133 // unlink from list of candidate fxs
134 void unlinkFromCandidateFXList();
135 // unlink from list of instanciated fx. NB : this doesn't remove the model!
136 void unlinkFromInstanciatedFXList();
139 void shutDown(NL3D::UScene
*scene
, CFXManager
&fxManager
);
141 void computeHour(sint32 cycle
, float bias
, CClientDate
&resultDate
, float cycleLength
, float dayLength
, const NLMISC::CNoiseValue
&nv
, float minHour
, float maxHour
) const;
143 // A group of managed fx. We never resize these vectors after creation so we can keep pointers in them.
144 typedef std::vector
<CManagedFX
> TManagedFXGroup
;
145 struct CManagedFXGroup
147 TManagedFXGroup Group
;
149 EGSPD::CSeason::TSeason Season
;
152 // a list of group of managed fxs.
153 typedef std::list
<CManagedFXGroup
> TManagedFXGroupList
;
157 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
158 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
159 //\name USER INTERFACE
161 // mode of display for debug
162 enum TDebugDisplayMode
{ NoText
= 0, PSName
, SpawnDate
, DebugModeCount
};
163 // handle to add/remove a group of managed fxs (see add() / remove())
164 typedef TManagedFXGroupList::iterator TFXGroupHandle
;
167 /** Init the manager. Must be called before first use
168 * \param scene The scene from which instances are created
169 * \param startDate Date of init
170 * \param dayLength Length of a day, in hours
171 * \param noiseFrequency Frequency of noise used to compute pseudo random spwaning dates of fxs (depends on their spawn position and on the date)
172 * \param maxNumberOfFXInstance Max number of fx instances that are allowed to be instanciated at a given time. Nearest fx are instanciated first
173 * \param sortDistanceInterval precision with which fx are sorted in distance. For example, with 1meter precision, fx at 0.2 & 0.5 from the user are considered
174 * to be at the same distance
175 * \param maxDist Max dist at which fxs are sorted. For efficiency, it is important to keep maxDist / sortDistanceInterval
177 void init(NL3D::UScene
*scene
,
178 const CClientDate
&startDate
,
180 float noiseFrequency
,
181 uint maxNumberOfFXInstances
,
182 float sortDistanceInterval
,
185 // Reset all manager content
187 /** Register a set of fxs to be managed.
188 * A handle is returned to remove it later.
190 TFXGroupHandle
add(const std::vector
<CTimedFX
> &fxs
, EGSPD::CSeason::TSeason season
);
191 /** Remove a FX group that has previously been added
192 * All FX instances are deleted.
194 void remove(TFXGroupHandle handle
);
195 /** Delayed removal of a fx group that has previously been added.
196 * All FXs are shutdown by removing their emitters.
197 * This is useful to switch from one season to another.
199 void shutDown(TFXGroupHandle handle
);
200 // Update the manager state to match the new date. This add / removes FX as necessary
201 void update(const CClientDate
&date
, EGSPD::CSeason::TSeason currSeason
, const NLMISC::CVector
&camPos
);
202 // Set a new date, but do not update current fx. The new hour will be taken in account during the next call to 'add'
203 void setDate(const CClientDate
&date
);
204 // get the current date
205 const CClientDate
&getDate() const { return _CurrDate
; }
206 // Access to the unique instance of this class
207 static CTimedFXManager
&getInstance();
209 void dumpFXToAdd() const;
210 void dumpFXToRemove() const;
211 void dumpFXInfo() const;
212 // debug bbox and dates of FXs to remove and to add.
213 void displayFXBoxes(TDebugDisplayMode displayMode
) const;
214 // set max number of fx to be instanciated at a time
215 void setMaxNumFXInstances(uint maxNumInstaces
);
217 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
218 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
220 // Set of fx to be instanciated in the future. It is managed as a priority queue (sorted by date of instanciation).
221 TTimeStampedFXPtrSet _FXToAdd
;
222 // Set of fx to remove in the future, and that are currently instanciated (and are not shutting done). It is managed as a priority queue (sorted by date of removal).
223 TTimeStampedFXPtrSet _FXToRemove
;
224 // List of the groups of FXs that are currenlty managed.
225 TManagedFXGroupList _FXGroups
;
226 // The scene from which to add / remove instances
227 NL3D::UScene
*_Scene
;
228 // Current date of the manager
229 CClientDate _CurrDate
;
230 // List of group that are shutting down (that is, shutDown(TFXGroupHandle handle) was called on that group)
231 std::list
<TFXGroupHandle
> _ShuttingDownGroups
;
232 // Length of a day, in hours
234 // Noise function used to compute start/end date of fxs
235 NLMISC::CNoiseValue _Noise
;
239 //\name DISTANCE SORTING
241 // FX to be displayed can be limited in number -> the nearest fx are instanciated in priority
242 // To achieve this, we keep a list of candidate fx for each interval of distance (thus achieving linear approximate sorting)
244 typedef std::vector
<CManagedFX
*> TCandidateFXListSortedByDist
;
245 TCandidateFXListSortedByDist _CandidateFXListSortedByDist
; // roughly sorted list of candidate fx. Should be rebuilt completely when players moves (done in linear time)
246 TCandidateFXListSortedByDist _CandidateFXListSortedByDistTmp
; // already allocated vect for fast resorting of list when player moves
248 // NB : this vector nevers grows
249 bool _CandidateFXListTouched
; // the list of candidate has been modified, so the manager should see which fxs should be instanciated, and which fxs should be removed
250 float _SortDistance
; // length of each distance interval, in meters
251 uint _MaxNumberOfFXInstances
; // max number of instances that can be 'alive' at a time
254 // Linked list of currently instanciated FXs (nearest candidates)
255 CManagedFX
*_InstanciatedFXs
;
256 NLMISC::CVector _LastCamPos
;
258 // fx manager to deals with shutting down fxs
259 CFXManager _FXManager
;
265 void checkIntegrity();
266 // setup user params for a fx
267 void setupUserParams(CManagedFX
&fi
, uint cycle
);
268 // insert a fx in list of candidate for instanciation (also unlink from a previous list)
269 void linkCandidateFX(TCandidateFXListSortedByDist
&targetList
, float dist
, CManagedFX
*fx
);
270 // link a fx into a list of instances (also unlink from a previous list)
271 void linkInstanciatedFX(CManagedFX
*&listHead
, CManagedFX
*fx
);
272 // update list of instanciated fxs (create / removes fxs as necessary)
273 void updateInstanciatedFXList();
274 // re-sort list of candidate fx by distance (this is necessary when player moves)
275 void updateCandidateFXListSorting();
277 // convert a cycle and an hour to a date
278 static void cycleToDate(sint32 cycle
, float hour
, float cycleLength
, float dayLength
, CClientDate
&result
);
279 // give the matching cycle for a date
280 static sint32
dateToCycle(const CClientDate
&date
, float cycleLength
, float dayLength
);