1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
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/>.
17 #ifndef NL_PARTICLE_WORKSPACE_H
18 #define NL_PARTICLE_WORKSPACE_H
20 #include "nel/misc/smart_ptr.h"
21 #include "nel/misc/stream.h"
22 #include "nel/3d/skeleton_model.h"
24 #include "ps_initial_pos.h"
28 class CParticleSystem
;
29 class CParticleSystemModel
;
42 /** A workspace containing several fxs
43 * \author Nicolas Vizerie
44 * \author Nevrax France
47 class CParticleWorkspace
50 // A node in the workspace
51 // Contains a particle system and its relative path
52 class CNode
: public NLMISC::CRefCount
55 void init(CParticleWorkspace
*ws
);
56 void setRelativePath(const std::string
&relativePath
);
57 const std::string
&getRelativePath() const { return _RelativePath
; }
58 std::string
getFullPath() const;
59 std::string
getFilename() const { return NLMISC::CFile::getFilename(_RelativePath
); }
60 // Serial node information into workspace stream. This does not save the particle system shape, only a reference to its file
61 void serial(NLMISC::IStream
&f
);
62 // Save the particle system target file
64 // Save particle system with an arbitrary filename
65 void savePSAs(const std::string
&fullPath
);
66 // put back in the unloaded state
68 /** Load the particle system target file
69 * \return true if loading succeed (false means that loading was ok, but this is not a particle system). Other cases throw an exception.
72 // create an empty particle system
74 // helper flag to know if a ps has been modified
75 bool isModified() const { return _Modified
; }
76 void setModified(bool modified
);
77 NL3D::CParticleSystem
*getPSPointer() const { return _PS
; }
78 NL3D::CParticleSystemModel
*getPSModel() const { return _PSM
; }
79 // See if this node ps has been loaded
80 bool isLoaded() const { return _PS
!= NULL
; }
81 // Get the workspace in which this node is inserted
82 CParticleWorkspace
*getWorkspace() const { return _WS
; }
83 // Memorize current position of object in the system. Useful to play the system because instances can be created / deleted
85 // Restore state previously memorize. Is usually called when the user stops a particle system
87 // Test if state is currenlty memorized
88 bool isStateMemorized() const;
89 // For edition : If the state of the system has been memorized, keep it on par with the system when it is modified
90 void removeLocated(NL3D::CPSLocated
*loc
);
91 // For edition : If the state of the system has been memorized, keep it on par with the system when it is modified
92 void removeLocatedBindable(NL3D::CPSLocatedBindable
*lb
);
93 // Returns the skeleton to which the ps is currently sticked
94 NL3D::CSkeletonModel
*getParentSkel() const { return _ParentSkel
; }
95 const std::string
&getParentSkelName() const { return _ParentSkelName
; }
96 const std::string
&getParentBoneName() const { return _ParentBoneName
; }
98 std::string
getTriggerAnim() { return _TriggerAnim
; }
99 void setTriggerAnim(const std::string
&anim
);
100 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
101 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
103 std::string _TriggerAnim
;
104 NL3D::CParticleSystem
*_PS
;
105 NL3D::CParticleSystemModel
*_PSM
;
106 NL3D::CShapeBank
*_ShapeBank
; // Keep a shape bank per node because we want the whole path to identify the ps, not just its filename
107 // (shape bank keeps the filename only)
108 std::string _RelativePath
; // relative path from which the ps was inserted
109 // relative path is also a unique identifier for this ps in the workspace
110 CPSInitialPos _InitialPos
; // initial pos of system. Allow to restore the initial instances of the system when doing start / stop
112 CParticleWorkspace
*_WS
;
113 NLMISC::CRefPtr
<NL3D::CSkeletonModel
> _ParentSkel
;
114 bool _ResetAutoCount
;
116 std::string _ParentSkelName
;
117 std::string _ParentBoneName
;
119 void setup(NL3D::CParticleSystemModel
&psm
);
121 bool getResetAutoCountFlag() const { return _ResetAutoCount
; }
122 void setResetAutoCountFlag(bool reset
) { _ResetAutoCount
= reset
; }
123 // stick to a skeleton
124 void stickPSToSkeleton(NL3D::CSkeletonModel
*skel
,
126 const std::string
&parentSkelName
, // for callback after loading
127 const std::string
&parentBoneName
129 void unstickPSFromSkeleton();
131 friend class CParticleWorkspace
;
138 // callback to know when a workspace node has been modified
139 struct IModificationCallback
141 virtual void workspaceModifiedFlagChanged(CParticleWorkspace
&pw
) = 0;
142 virtual void nodeModifiedFlagChanged(CNode
&node
) = 0;
143 virtual void nodeSkelParentChanged(CNode
&node
) = 0; // called when fx has been linked / unlinked from a skeleton parent
148 virtual bool less(const CNode
&lhs
, const CNode
&rhs
) const = 0;
151 CParticleWorkspace();
153 ~CParticleWorkspace();
155 // Init the workspace for the given object viewer
156 // must be called prior to other methods
157 void init(CObjectViewer
*ov
,
158 const std::string
&filename
,
159 NL3D::CFontManager
*fontManager
,
160 NL3D::CFontGenerator
*fontGenerator
162 // Set a new name for the workspace (not its filename)
163 void setName(const std::string
&name
);
164 std::string
getName() const { return _Name
; }
165 // Get the object viewer instance
166 CObjectViewer
*getObjectViewer() const { return _OV
; }
167 // Get the path in which workpsace is located with a trailing slash
168 std::string
getPath() const;
169 std::string
getFilename() const { return _Filename
; }
170 // Get Number of nodes in the workspace
171 uint
getNumNode() const { return (uint
)_Nodes
.size(); }
172 /** Get a node in workspace
173 * Can keep pointer safely as long as the node is not deleted
175 CNode
*getNode(uint index
) const { return _Nodes
[index
]; }
176 // Get a node from a pointer on a particle system
177 CNode
*getNodeFromPS(NL3D::CParticleSystem
*ps
) const;
178 /** Test if the workspace already contains a node with the given filename name
179 * NB : 2 node with the same name re not allowed, even if their path is different
181 bool containsFile(std::string filename
) const;
183 /** Add a node in the workspace. Will succeed only if fx filename does not already exist in the workspace.
184 * The node is in the 'unloaded' state, so caller must load it afterward.
185 * NB : no lookup is done, full path must be provided.
187 * \return pointer to new node, or NULL if already inserted
189 CNode
*addNode(const std::string
&filenameWithFullPath
);
190 // remove a node by its index
191 void removeNode(uint index
);
192 // remove a node by its pointer
193 void removeNode(CNode
*ptr
);
194 // Get index of a node from its pointer, or -1 if not found
195 sint
getIndexFromNode(CNode
*node
) const;
196 /** Save the workspace structure. The target file is the one given when this object was created
197 * NB : ps shape are not saved, only the structure is. To save the shapes, call CNode::save()
200 /** Load the workspace structure. The target file is the one given when this object was created
201 * All nodes are in the 'unloaded" state, so it is to the caller to load them by calling load() on their node
204 // Test whether the structure of the workspace has been modified (does not test if ps inside the workspace have been modified)
205 bool isModified() const { return _Modified
; }
206 // Test whether the content of the workspace has ben modified
207 bool isContentModified() const;
208 void touch() { setModifiedFlag(true); }
209 void clearModifiedFlag() { setModifiedFlag(false); }
210 // set a callback to know when a node is modified
211 void setModificationCallback(IModificationCallback
*cb
) { _ModificationCallback
= cb
; }
212 IModificationCallback
*getModificationCallback() const { return _ModificationCallback
; }
213 // Sort the workspace. The node pointer remains valid and unchanged
214 void sort(ISort
&predicate
);
215 // get font manager / font generator
216 NL3D::CFontGenerator
*getFontGenerator() const { return _FontGenerator
; }
217 NL3D::CFontManager
*getFontManager() const { return _FontManager
; }
218 // restick all objects, useful after loading
219 void restickAllObjects(CObjectViewer
*ov
);
221 typedef std::vector
<NLMISC::CSmartPtr
<CNode
> > TNodeVect
;
222 TNodeVect _Nodes
; // use smart ptr to avoir prb wih resize
223 std::string _Filename
; // path + name of workspace
226 NL3D::CFontManager
*_FontManager
;
227 NL3D::CFontGenerator
*_FontGenerator
;
228 IModificationCallback
*_ModificationCallback
;
229 std::string _Name
; // workspace user name
232 void serial(NLMISC::IStream
&f
);
233 // set the 'modified flag' and call the callback
234 void setModifiedFlag(bool modified
);
236 void nodeModified(CNode
&node
);