2010-10-22 03:34:26 +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 PARTICLE_NODE_H
|
|
|
|
|
#define PARTICLE_NODE_H
|
|
|
|
|
|
|
|
|
|
// STL includes
|
|
|
|
|
#include <string>
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
|
|
// NeL includes
|
|
|
|
|
#include "nel/misc/smart_ptr.h"
|
|
|
|
|
#include "nel/misc/stream.h"
|
|
|
|
|
#include <nel/misc/path.h>
|
|
|
|
|
#include "nel/3d/skeleton_model.h"
|
|
|
|
|
|
|
|
|
|
// Projects includes
|
|
|
|
|
#include "ps_initial_pos.h"
|
|
|
|
|
|
|
|
|
|
|
2010-11-26 11:54:06 +00:00
|
|
|
|
namespace NL3D
|
|
|
|
|
{
|
|
|
|
|
class CParticleSystem;
|
|
|
|
|
class CParticleSystemModel;
|
|
|
|
|
class CShapeBank;
|
2010-10-22 03:34:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
2010-11-26 11:54:06 +00:00
|
|
|
|
namespace NLQT
|
|
|
|
|
{
|
|
|
|
|
|
2010-10-22 03:34:26 +00:00
|
|
|
|
class CParticleWorkspace;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@class CWorkspaceNode
|
|
|
|
|
@author Nicolas Vizerie
|
|
|
|
|
@author Nevrax France
|
|
|
|
|
@date 2004
|
|
|
|
|
@brief A node in the workspace particles system editor.
|
|
|
|
|
@details Contains NeL system of particles and allows them to perform the following operations:
|
|
|
|
|
- Creating a new empty particle system (createEmptyPS()).
|
|
|
|
|
- Loading and saving the existing system of particles.
|
|
|
|
|
- Linking / unlinking of the system of particles to any bone of the skeleton model.
|
|
|
|
|
- Operations with the name and directory location of the particles system file.
|
2010-11-26 11:54:06 +00:00
|
|
|
|
- Has a flag indicating if the particles system changed or not (intended for the editor)
|
2010-10-22 03:34:26 +00:00
|
|
|
|
*/
|
|
|
|
|
class CWorkspaceNode : public NLMISC::CRefCount
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
void init(CParticleWorkspace *ws);
|
2010-11-26 11:54:06 +00:00
|
|
|
|
|
2010-10-22 03:34:26 +00:00
|
|
|
|
void setRelativePath(const std::string &relativePath);
|
2010-11-26 11:54:06 +00:00
|
|
|
|
|
|
|
|
|
const std::string &getRelativePath() const
|
|
|
|
|
{
|
|
|
|
|
return _RelativePath;
|
|
|
|
|
}
|
|
|
|
|
|
2010-10-22 03:34:26 +00:00
|
|
|
|
std::string getFullPath() const;
|
2010-11-26 11:54:06 +00:00
|
|
|
|
|
|
|
|
|
std::string getFilename() const
|
|
|
|
|
{
|
|
|
|
|
return NLMISC::CFile::getFilename(_RelativePath);
|
|
|
|
|
}
|
|
|
|
|
|
2010-10-22 03:34:26 +00:00
|
|
|
|
/// Serial node information into workspace stream. This does not save the particle system shape, only a reference to its file
|
|
|
|
|
void serial(NLMISC::IStream &f);
|
2010-11-26 11:54:06 +00:00
|
|
|
|
|
2010-10-22 03:34:26 +00:00
|
|
|
|
/// Save the particle system target file
|
|
|
|
|
void savePS() throw(NLMISC::EStream);
|
2010-11-26 11:54:06 +00:00
|
|
|
|
|
2010-10-22 03:34:26 +00:00
|
|
|
|
/// Save particle system with an arbitrary filename
|
|
|
|
|
void savePSAs(const std::string &fullPath) throw(NLMISC::EStream);
|
2010-11-26 11:54:06 +00:00
|
|
|
|
|
2010-10-22 03:34:26 +00:00
|
|
|
|
/// put back in the unloaded state
|
|
|
|
|
void unload();
|
2010-11-26 11:54:06 +00:00
|
|
|
|
|
2010-10-22 03:34:26 +00:00
|
|
|
|
/// 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);
|
2010-11-26 11:54:06 +00:00
|
|
|
|
|
2010-10-22 03:34:26 +00:00
|
|
|
|
/// Create an empty particle system
|
|
|
|
|
void createEmptyPS();
|
2010-11-26 11:54:06 +00:00
|
|
|
|
|
2010-10-22 03:34:26 +00:00
|
|
|
|
/// Helper flag to know if a ps has been modified
|
|
|
|
|
/// @{
|
2010-11-26 11:54:06 +00:00
|
|
|
|
bool isModified() const
|
|
|
|
|
{
|
|
|
|
|
return _Modified;
|
|
|
|
|
}
|
2010-10-22 03:34:26 +00:00
|
|
|
|
void setModified(bool modified);
|
|
|
|
|
/// @}
|
2010-11-26 11:54:06 +00:00
|
|
|
|
NL3D::CParticleSystem *getPSPointer() const
|
|
|
|
|
{
|
|
|
|
|
return _PS;
|
|
|
|
|
}
|
|
|
|
|
NL3D::CParticleSystemModel *getPSModel() const
|
|
|
|
|
{
|
|
|
|
|
return _PSM;
|
|
|
|
|
}
|
|
|
|
|
|
2010-10-22 03:34:26 +00:00
|
|
|
|
/// See if this node ps has been loaded
|
2010-11-26 11:54:06 +00:00
|
|
|
|
bool isLoaded() const
|
|
|
|
|
{
|
|
|
|
|
return _PS != NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2010-10-22 03:34:26 +00:00
|
|
|
|
/// Get the workspace in which this node is inserted
|
2010-11-26 11:54:06 +00:00
|
|
|
|
CParticleWorkspace *getWorkspace() const
|
|
|
|
|
{
|
|
|
|
|
return _WS;
|
|
|
|
|
}
|
|
|
|
|
|
2010-10-22 03:34:26 +00:00
|
|
|
|
/// Memorize current position of object in the system. Useful to play the system because instances can be created / deleted
|
|
|
|
|
void memorizeState();
|
2010-11-26 11:54:06 +00:00
|
|
|
|
|
2010-10-22 03:34:26 +00:00
|
|
|
|
/// Restore state previously memorize. Is usually called when the user stops a particle system
|
|
|
|
|
void restoreState();
|
2010-11-26 11:54:06 +00:00
|
|
|
|
|
2010-10-22 03:34:26 +00:00
|
|
|
|
/// Test if state is currenlty memorized
|
|
|
|
|
bool isStateMemorized() const;
|
2010-11-26 11:54:06 +00:00
|
|
|
|
|
2010-10-22 03:34:26 +00:00
|
|
|
|
/// 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);
|
2010-11-26 11:54:06 +00:00
|
|
|
|
|
|
|
|
|
/// For edition : If the state of the system has been memorized, keep it on par with the system when it is modified
|
2010-10-22 03:34:26 +00:00
|
|
|
|
void removeLocatedBindable(NL3D::CPSLocatedBindable *lb);
|
2010-11-26 11:54:06 +00:00
|
|
|
|
|
2010-10-22 03:34:26 +00:00
|
|
|
|
/// Returns the skeleton to which the ps is currently sticked
|
2010-11-26 11:54:06 +00:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2010-10-22 03:34:26 +00:00
|
|
|
|
void setTriggerAnim(const std::string &anim);
|
2010-11-26 11:54:06 +00:00
|
|
|
|
|
2010-10-22 03:34:26 +00:00
|
|
|
|
private:
|
2010-12-04 12:03:31 +00:00
|
|
|
|
std::string _TriggerAnim;
|
|
|
|
|
NL3D::CParticleSystem *_PS;
|
|
|
|
|
NL3D::CParticleSystemModel *_PSM;
|
2010-11-26 11:54:06 +00:00
|
|
|
|
|
2010-10-22 03:34:26 +00:00
|
|
|
|
// 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)
|
2010-12-04 12:03:31 +00:00
|
|
|
|
NL3D::CShapeBank *_ShapeBank;
|
2010-11-26 11:54:06 +00:00
|
|
|
|
|
2010-10-22 03:34:26 +00:00
|
|
|
|
// Relative path from which the ps was inserted
|
|
|
|
|
// relative path is also a unique identifier for this ps in the workspace
|
2010-12-04 12:03:31 +00:00
|
|
|
|
std::string _RelativePath;
|
2010-11-26 11:54:06 +00:00
|
|
|
|
|
2010-10-22 03:34:26 +00:00
|
|
|
|
// initial pos of system. Allow to restore the initial instances of the system when doing start / stop
|
2010-12-04 12:03:31 +00:00
|
|
|
|
CPSInitialPos _InitialPos;
|
|
|
|
|
bool _Modified;
|
|
|
|
|
CParticleWorkspace *_WS;
|
2010-10-22 03:34:26 +00:00
|
|
|
|
NLMISC::CRefPtr<NL3D::CSkeletonModel> _ParentSkel;
|
2010-12-04 12:03:31 +00:00
|
|
|
|
bool _ResetAutoCount;
|
2010-10-22 03:34:26 +00:00
|
|
|
|
//
|
2010-12-04 12:03:31 +00:00
|
|
|
|
std::string _ParentSkelName;
|
|
|
|
|
std::string _ParentBoneName;
|
2010-10-22 03:34:26 +00:00
|
|
|
|
private:
|
|
|
|
|
void setup(NL3D::CParticleSystemModel &psm);
|
|
|
|
|
public:
|
2010-11-26 11:54:06 +00:00
|
|
|
|
bool getResetAutoCountFlag() const
|
|
|
|
|
{
|
|
|
|
|
return _ResetAutoCount;
|
|
|
|
|
}
|
|
|
|
|
void setResetAutoCountFlag(bool reset)
|
|
|
|
|
{
|
|
|
|
|
_ResetAutoCount = reset;
|
|
|
|
|
}
|
|
|
|
|
|
2010-10-22 03:34:26 +00:00
|
|
|
|
/// Stick to a skeleton
|
|
|
|
|
void stickPSToSkeleton(NL3D::CSkeletonModel *skel,
|
|
|
|
|
uint bone,
|
|
|
|
|
const std::string &parentSkelName, // for callback after loading
|
2010-11-26 11:54:06 +00:00
|
|
|
|
const std::string &parentBoneName
|
2010-10-22 03:34:26 +00:00
|
|
|
|
);
|
|
|
|
|
void unstickPSFromSkeleton();
|
|
|
|
|
private:
|
|
|
|
|
friend class CParticleWorkspace;
|
|
|
|
|
// Ctor
|
|
|
|
|
CWorkspaceNode();
|
|
|
|
|
public:
|
|
|
|
|
// DTor
|
|
|
|
|
~CWorkspaceNode();
|
|
|
|
|
}; /* class CWorkspaceNode */
|
|
|
|
|
|
|
|
|
|
typedef std::vector<NLMISC::CRefPtr<CWorkspaceNode> > TNodeVect;
|
|
|
|
|
typedef TNodeVect::iterator TPWNodeItr;
|
|
|
|
|
|
2010-11-26 11:54:06 +00:00
|
|
|
|
/**
|
2010-10-22 03:34:26 +00:00
|
|
|
|
@class CParticleWorkspace
|
|
|
|
|
@author Nicolas Vizerie
|
|
|
|
|
@author Nevrax France
|
|
|
|
|
@date 2004
|
|
|
|
|
@brief A container containing all the loaded particle system.
|
|
|
|
|
@details Allows you to load \ save in xml file list of systems of particles (the path to each file as well)
|
|
|
|
|
and additional parameters (skeleton model, and to which bone it is attached)
|
2010-11-26 11:54:06 +00:00
|
|
|
|
There is a feedback mechanism showed changes are being made with the container,with a particle system or connection to the skeleton.
|
2010-10-22 03:34:26 +00:00
|
|
|
|
*/
|
|
|
|
|
class CParticleWorkspace
|
|
|
|
|
{
|
2010-11-26 11:54:06 +00:00
|
|
|
|
public:
|
2010-10-22 03:34:26 +00:00
|
|
|
|
/// callback to know when a workspace node has been modified
|
|
|
|
|
struct IModificationCallback
|
|
|
|
|
{
|
|
|
|
|
virtual void workspaceModifiedFlagChanged(CParticleWorkspace &pw) = 0;
|
|
|
|
|
virtual void nodeModifiedFlagChanged(CWorkspaceNode &node) = 0;
|
|
|
|
|
virtual void nodeSkelParentChanged(CWorkspaceNode &node) = 0; // called when fx has been linked / unlinked from a skeleton parent
|
|
|
|
|
};
|
|
|
|
|
/// Сonstructor
|
|
|
|
|
CParticleWorkspace();
|
|
|
|
|
/// Destructor
|
|
|
|
|
~CParticleWorkspace();
|
|
|
|
|
|
|
|
|
|
/// Init the workspace for the given object viewer
|
2010-11-26 11:54:06 +00:00
|
|
|
|
/// must be called prior to other methods
|
2010-10-22 03:34:26 +00:00
|
|
|
|
void init(const std::string &filename);
|
2010-11-26 11:54:06 +00:00
|
|
|
|
|
2010-10-22 03:34:26 +00:00
|
|
|
|
/// Set a new name for the workspace (not its filename)
|
|
|
|
|
void setName(const std::string &name);
|
2010-11-26 11:54:06 +00:00
|
|
|
|
|
2010-10-22 03:34:26 +00:00
|
|
|
|
/// Set a new file name for the workspace
|
|
|
|
|
void setFileName(const std::string &fileName);
|
2010-11-26 11:54:06 +00:00
|
|
|
|
|
|
|
|
|
std::string getName() const
|
|
|
|
|
{
|
|
|
|
|
return _Name;
|
|
|
|
|
}
|
|
|
|
|
|
2010-10-22 03:34:26 +00:00
|
|
|
|
/// Get the path in which workpsace is located with a trailing slash
|
|
|
|
|
std::string getPath() const;
|
|
|
|
|
std::string getFilename() const;
|
|
|
|
|
|
|
|
|
|
/// Get Number of nodes in the workspace
|
2010-11-26 11:54:06 +00:00
|
|
|
|
uint getNumNode() const
|
|
|
|
|
{
|
|
|
|
|
return (uint)_Nodes.size();
|
|
|
|
|
}
|
|
|
|
|
|
2010-10-22 03:34:26 +00:00
|
|
|
|
/// Get a node in workspace
|
|
|
|
|
/// Can keep pointer safely as long as the node is not deleted
|
2010-11-26 11:54:06 +00:00
|
|
|
|
CWorkspaceNode *getNode(uint index) const
|
|
|
|
|
{
|
|
|
|
|
return _Nodes[index];
|
|
|
|
|
}
|
|
|
|
|
|
2010-10-22 03:34:26 +00:00
|
|
|
|
/// Get a node from a pointer on a particle system
|
|
|
|
|
CWorkspaceNode *getNodeFromPS(NL3D::CParticleSystem *ps) const;
|
2010-11-26 11:54:06 +00:00
|
|
|
|
|
2010-10-22 03:34:26 +00:00
|
|
|
|
/// 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.
|
2010-11-26 11:54:06 +00:00
|
|
|
|
/// 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
|
2010-10-22 03:34:26 +00:00
|
|
|
|
CWorkspaceNode *addNode(const std::string &filenameWithFullPath) throw( NLMISC::Exception);
|
2010-11-26 11:54:06 +00:00
|
|
|
|
|
2010-10-22 03:34:26 +00:00
|
|
|
|
/// Remove a node by it's index
|
|
|
|
|
void removeNode(uint index);
|
2010-11-26 11:54:06 +00:00
|
|
|
|
|
2010-10-22 03:34:26 +00:00
|
|
|
|
/// Remove a node by it's pointer
|
|
|
|
|
void removeNode(CWorkspaceNode *ptr);
|
2010-11-26 11:54:06 +00:00
|
|
|
|
|
2010-10-22 03:34:26 +00:00
|
|
|
|
/// Get index of a node from its pointer, or -1 if not found
|
|
|
|
|
sint getIndexFromNode(CWorkspaceNode *node) const;
|
2010-11-26 11:54:06 +00:00
|
|
|
|
|
|
|
|
|
/// Save the workspace structure. The target file is the one given when this object was created
|
2010-10-22 03:34:26 +00:00
|
|
|
|
/// NB : ps shape are not saved, only the structure is. To save the shapes, call CNode::save()
|
|
|
|
|
void save() throw(NLMISC::EStream);
|
2010-11-26 11:54:06 +00:00
|
|
|
|
|
2010-10-22 03:34:26 +00:00
|
|
|
|
/// 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);
|
2010-11-26 11:54:06 +00:00
|
|
|
|
|
2010-11-12 13:26:38 +00:00
|
|
|
|
/// Test whether the structure of the workspace has been modified (does not test if ps inside the workspace have been modified)
|
2010-11-26 11:54:06 +00:00
|
|
|
|
bool isModified() const
|
|
|
|
|
{
|
|
|
|
|
return _Modified;
|
|
|
|
|
}
|
|
|
|
|
|
2010-11-12 13:26:38 +00:00
|
|
|
|
/// Test whether the content of the workspace has ben modified
|
2010-10-22 03:34:26 +00:00
|
|
|
|
bool isContentModified() const;
|
2010-11-26 11:54:06 +00:00
|
|
|
|
void touch()
|
|
|
|
|
{
|
|
|
|
|
setModifiedFlag(true);
|
|
|
|
|
}
|
|
|
|
|
void clearModifiedFlag()
|
|
|
|
|
{
|
|
|
|
|
setModifiedFlag(false);
|
|
|
|
|
}
|
|
|
|
|
|
2010-10-22 03:34:26 +00:00
|
|
|
|
/// Set a callback to know when a node is modified
|
2010-11-26 11:54:06 +00:00
|
|
|
|
void setModificationCallback(IModificationCallback *cb)
|
|
|
|
|
{
|
|
|
|
|
_ModificationCallback = cb;
|
|
|
|
|
}
|
|
|
|
|
IModificationCallback *getModificationCallback() const
|
|
|
|
|
{
|
|
|
|
|
return _ModificationCallback;
|
|
|
|
|
}
|
|
|
|
|
|
2010-10-22 03:34:26 +00:00
|
|
|
|
/// Restick all objects, useful after loading
|
|
|
|
|
void restickAllObjects();
|
|
|
|
|
|
2010-11-26 11:54:06 +00:00
|
|
|
|
TNodeVect& getNodeList()
|
|
|
|
|
{
|
|
|
|
|
return _Nodes;
|
|
|
|
|
}
|
2010-10-22 03:34:26 +00:00
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
// use smart ptr to avoir prb wih resize
|
2010-12-04 12:03:31 +00:00
|
|
|
|
TNodeVect _Nodes;
|
2010-10-22 03:34:26 +00:00
|
|
|
|
// path + name of workspace
|
2010-12-04 12:03:31 +00:00
|
|
|
|
std::string _Filename;
|
|
|
|
|
bool _Modified;
|
|
|
|
|
IModificationCallback *_ModificationCallback;
|
2010-10-22 03:34:26 +00:00
|
|
|
|
// workspace user name
|
2010-12-04 12:03:31 +00:00
|
|
|
|
std::string _Name;
|
2010-11-26 11:54:06 +00:00
|
|
|
|
|
2010-10-22 03:34:26 +00:00
|
|
|
|
/// serial the object
|
2010-11-26 11:54:06 +00:00
|
|
|
|
void serial(NLMISC::IStream &f) throw(NLMISC::EStream);
|
|
|
|
|
|
2010-10-22 03:34:26 +00:00
|
|
|
|
/// set the 'modified flag' and call the callback
|
|
|
|
|
void setModifiedFlag(bool modified);
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
void nodeModified(CWorkspaceNode &node);
|
|
|
|
|
}; /* class CParticleWorkspace */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} /* namespace NLQT */
|
|
|
|
|
|
|
|
|
|
#endif // PARTICLE_NODE_H
|