2010-05-06 00:08:41 +00:00
|
|
|
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
|
|
|
// Copyright (C) 2010 Winch Gate Property Limited
|
|
|
|
//
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU Affero General Public License as
|
|
|
|
// published by the Free Software Foundation, either version 3 of the
|
|
|
|
// License, or (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU Affero General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU Affero General Public License
|
|
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
#ifndef NL_PARTICLE_WORKSPACE_H
|
|
|
|
#define NL_PARTICLE_WORKSPACE_H
|
|
|
|
|
|
|
|
#include "nel/misc/smart_ptr.h"
|
|
|
|
#include "nel/misc/stream.h"
|
|
|
|
#include "nel/3d/skeleton_model.h"
|
|
|
|
//
|
|
|
|
#include "ps_initial_pos.h"
|
|
|
|
|
|
|
|
namespace NL3D
|
|
|
|
{
|
|
|
|
class CParticleSystem;
|
|
|
|
class CParticleSystemModel;
|
|
|
|
class CshapeBank;
|
|
|
|
class CFontManager;
|
|
|
|
class CFontGenerator;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
class CObjectViewer;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** A workspace containing several fxs
|
|
|
|
* \author Nicolas Vizerie
|
|
|
|
* \author Nevrax France
|
|
|
|
* \date 2004
|
|
|
|
*/
|
|
|
|
class CParticleWorkspace
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
// A node in the workspace
|
|
|
|
// Contains a particle system and its relative path
|
|
|
|
class CNode : public NLMISC::CRefCount
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
void init(CParticleWorkspace *ws);
|
|
|
|
void setRelativePath(const std::string &relativePath);
|
|
|
|
const std::string &getRelativePath() const { return _RelativePath; }
|
|
|
|
std::string getFullPath() const;
|
|
|
|
std::string getFilename() const { return NLMISC::CFile::getFilename(_RelativePath); }
|
2010-06-13 14:58:11 +00:00
|
|
|
// Serial node information into workspace stream. This does not save the particle system shape, only a reference to its file
|
2010-05-06 00:08:41 +00:00
|
|
|
void serial(NLMISC::IStream &f);
|
|
|
|
// Save the particle system target file
|
|
|
|
void savePS() throw(NLMISC::EStream);
|
|
|
|
// Save particle system with an arbitrary filename
|
|
|
|
void savePSAs(const std::string &fullPath) throw(NLMISC::EStream);
|
|
|
|
// put back in the unloaded state
|
|
|
|
void unload();
|
|
|
|
/** Load the particle system target file
|
|
|
|
* \return true if loading succeed (false means that loading was ok, but this is not a particle system). Other cases throw an exception.
|
|
|
|
*/
|
|
|
|
bool loadPS() throw(NLMISC::EStream);
|
|
|
|
// create an empty particle system
|
|
|
|
void createEmptyPS();
|
|
|
|
// helper flag to know if a ps has been modified
|
|
|
|
bool isModified() const { return _Modified; }
|
|
|
|
void setModified(bool modified);
|
|
|
|
NL3D::CParticleSystem *getPSPointer() const { return _PS; }
|
|
|
|
NL3D::CParticleSystemModel *getPSModel() const { return _PSM; }
|
|
|
|
// See if this node ps has been loaded
|
|
|
|
bool isLoaded() const { return _PS != NULL; }
|
|
|
|
// Get the workspace in which this node is inserted
|
|
|
|
CParticleWorkspace *getWorkspace() const { return _WS; }
|
|
|
|
// Memorize current position of object in the system. Useful to play the system because instances can be created / deleted
|
|
|
|
void memorizeState();
|
|
|
|
// Restore state previously memorize. Is usually called when the user stops a particle system
|
|
|
|
void restoreState();
|
|
|
|
// Test if state is currenlty memorized
|
|
|
|
bool isStateMemorized() const;
|
|
|
|
// For edition : If the state of the system has been memorized, keep it on par with the system when it is modified
|
|
|
|
void removeLocated(NL3D::CPSLocated *loc);
|
|
|
|
// For edition : If the state of the system has been memorized, keep it on par with the system when it is modified
|
|
|
|
void removeLocatedBindable(NL3D::CPSLocatedBindable *lb);
|
|
|
|
// Returns the skeleton to which the ps is currently sticked
|
|
|
|
NL3D::CSkeletonModel *getParentSkel() const { return _ParentSkel; }
|
|
|
|
const std::string &getParentSkelName() const { return _ParentSkelName; }
|
|
|
|
const std::string &getParentBoneName() const { return _ParentBoneName; }
|
|
|
|
//
|
|
|
|
std::string getTriggerAnim() { return _TriggerAnim; }
|
|
|
|
void setTriggerAnim(const std::string &anim);
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
private:
|
|
|
|
std::string _TriggerAnim;
|
|
|
|
NL3D::CParticleSystem *_PS;
|
|
|
|
NL3D::CParticleSystemModel *_PSM;
|
|
|
|
NL3D::CShapeBank *_ShapeBank; // Keep a shape bank per node because we want the whole path to identify the ps, not just its filename
|
|
|
|
// (shape bank keeps the filename only)
|
|
|
|
std::string _RelativePath; // relative path from which the ps was inserted
|
|
|
|
// relative path is also a unique identifier for this ps in the workspace
|
|
|
|
CPSInitialPos _InitialPos; // initial pos of system. Allow to restore the initial instances of the system when doing start / stop
|
|
|
|
bool _Modified;
|
|
|
|
CParticleWorkspace *_WS;
|
|
|
|
NLMISC::CRefPtr<NL3D::CSkeletonModel> _ParentSkel;
|
|
|
|
bool _ResetAutoCount;
|
|
|
|
//
|
|
|
|
std::string _ParentSkelName;
|
|
|
|
std::string _ParentBoneName;
|
|
|
|
private:
|
|
|
|
void setup(NL3D::CParticleSystemModel &psm);
|
|
|
|
public:
|
|
|
|
bool getResetAutoCountFlag() const { return _ResetAutoCount; }
|
|
|
|
void setResetAutoCountFlag(bool reset) { _ResetAutoCount = reset; }
|
|
|
|
// stick to a skeleton
|
|
|
|
void stickPSToSkeleton(NL3D::CSkeletonModel *skel,
|
|
|
|
uint bone,
|
|
|
|
const std::string &parentSkelName, // for callback after loading
|
|
|
|
const std::string &parentBoneName
|
|
|
|
);
|
|
|
|
void unstickPSFromSkeleton();
|
|
|
|
private:
|
|
|
|
friend class CParticleWorkspace;
|
|
|
|
// Ctor
|
|
|
|
CNode();
|
|
|
|
public:
|
|
|
|
// DTor
|
|
|
|
~CNode();
|
|
|
|
};
|
|
|
|
// callback to know when a workspace node has been modified
|
|
|
|
struct IModificationCallback
|
|
|
|
{
|
|
|
|
virtual void workspaceModifiedFlagChanged(CParticleWorkspace &pw) = 0;
|
|
|
|
virtual void nodeModifiedFlagChanged(CNode &node) = 0;
|
|
|
|
virtual void nodeSkelParentChanged(CNode &node) = 0; // called when fx has been linked / unlinked from a skeleton parent
|
|
|
|
};
|
|
|
|
// sorting predicate
|
|
|
|
struct ISort
|
|
|
|
{
|
|
|
|
virtual bool less(const CNode &lhs, const CNode &rhs) const = 0;
|
|
|
|
};
|
|
|
|
// ctor
|
|
|
|
CParticleWorkspace();
|
|
|
|
// dtor
|
|
|
|
~CParticleWorkspace();
|
|
|
|
|
|
|
|
// Init the workspace for the given object viewer
|
|
|
|
// must be called prior to other methods
|
|
|
|
void init(CObjectViewer *ov,
|
|
|
|
const std::string &filename,
|
|
|
|
NL3D::CFontManager *fontManager,
|
|
|
|
NL3D::CFontGenerator *fontGenerator
|
|
|
|
);
|
|
|
|
// Set a new name for the workspace (not its filename)
|
|
|
|
void setName(const std::string &name);
|
|
|
|
std::string getName() const { return _Name; }
|
|
|
|
// Get the object viewer instance
|
|
|
|
CObjectViewer *getObjectViewer() const { return _OV; }
|
|
|
|
// Get the path in which workpsace is located with a trailing slash
|
|
|
|
std::string getPath() const;
|
|
|
|
std::string getFilename() const { return _Filename; }
|
|
|
|
// Get Number of nodes in the workspace
|
2010-06-21 07:39:58 +00:00
|
|
|
uint getNumNode() const { return (uint)_Nodes.size(); }
|
2010-05-06 00:08:41 +00:00
|
|
|
/** Get a node in workspace
|
|
|
|
* Can keep pointer safely as long as the node is not deleted
|
|
|
|
*/
|
|
|
|
CNode *getNode(uint index) const { return _Nodes[index]; }
|
|
|
|
// Get a node from a pointer on a particle system
|
|
|
|
CNode *getNodeFromPS(NL3D::CParticleSystem *ps) const;
|
|
|
|
/** Test if the workspace already contains a node with the given filename name
|
|
|
|
* NB : 2 node with the same name re not allowed, even if their path is different
|
|
|
|
*/
|
|
|
|
bool containsFile(std::string filename) const;
|
|
|
|
|
|
|
|
/** Add a node in the workspace. Will succeed only if fx filename does not already exist in the workspace.
|
|
|
|
* The node is in the 'unloaded' state, so caller must load it afterward.
|
|
|
|
* NB : no lookup is done, full path must be provided.
|
|
|
|
*
|
|
|
|
* \return pointer to new node, or NULL if already inserted
|
|
|
|
*/
|
|
|
|
CNode *addNode(const std::string &filenameWithFullPath) throw( NLMISC::Exception);
|
|
|
|
// remove a node by its index
|
|
|
|
void removeNode(uint index);
|
|
|
|
// remove a node by its pointer
|
|
|
|
void removeNode(CNode *ptr);
|
|
|
|
// Get index of a node from its pointer, or -1 if not found
|
|
|
|
sint getIndexFromNode(CNode *node) const;
|
|
|
|
/** Save the workspace structure. The target file is the one given when this object was created
|
|
|
|
* NB : ps shape are not saved, only the structure is. To save the shapes, call CNode::save()
|
|
|
|
*/
|
|
|
|
void save() throw(NLMISC::EStream);
|
|
|
|
/** Load the workspace structure. The target file is the one given when this object was created
|
|
|
|
* All nodes are in the 'unloaded" state, so it is to the caller to load them by calling load() on their node
|
|
|
|
*/
|
|
|
|
void load() throw(NLMISC::EStream);
|
|
|
|
// Test wether the structure of the workspace has been modified (does not test if ps inside the workspace have been modified)
|
|
|
|
bool isModified() const { return _Modified; }
|
|
|
|
// Test wether the content of the workspace has ben modified
|
|
|
|
bool isContentModified() const;
|
|
|
|
void touch() { setModifiedFlag(true); }
|
|
|
|
void clearModifiedFlag() { setModifiedFlag(false); }
|
|
|
|
// set a callback to know when a node is modified
|
|
|
|
void setModificationCallback(IModificationCallback *cb) { _ModificationCallback = cb; }
|
|
|
|
IModificationCallback *getModificationCallback() const { return _ModificationCallback; }
|
|
|
|
// Sort the workspace. The node pointer remains valid and unchanged
|
|
|
|
void sort(ISort &predicate);
|
|
|
|
// get font manager / font generator
|
|
|
|
NL3D::CFontGenerator *getFontGenerator() const { return _FontGenerator; }
|
|
|
|
NL3D::CFontManager *getFontManager() const { return _FontManager; }
|
|
|
|
// restick all objects, useful after loading
|
|
|
|
void restickAllObjects(CObjectViewer *ov);
|
|
|
|
private:
|
|
|
|
typedef std::vector<NLMISC::CSmartPtr<CNode> > TNodeVect;
|
|
|
|
TNodeVect _Nodes; // use smart ptr to avoir prb wih resize
|
|
|
|
std::string _Filename; // path + name of workspace
|
|
|
|
CObjectViewer *_OV;
|
|
|
|
bool _Modified; //
|
|
|
|
NL3D::CFontManager *_FontManager;
|
|
|
|
NL3D::CFontGenerator *_FontGenerator;
|
|
|
|
IModificationCallback *_ModificationCallback;
|
|
|
|
std::string _Name; // workspace user name
|
|
|
|
private:
|
|
|
|
// serial the object
|
|
|
|
void serial(NLMISC::IStream &f) throw(NLMISC::EStream);
|
|
|
|
// set the 'modified flag' and call the callback
|
|
|
|
void setModifiedFlag(bool modified);
|
|
|
|
public:
|
|
|
|
void nodeModified(CNode &node);
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#endif
|