khanat-opennel-code/code/nel/tools/3d/object_viewer_qt/src/particle_node.h
2010-12-04 14:03:31 +02:00

363 lines
10 KiB
Objective-C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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"
namespace NL3D
{
class CParticleSystem;
class CParticleSystemModel;
class CShapeBank;
}
namespace NLQT
{
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.
- Has a flag indicating if the particles system changed or not (intended for the editor)
*/
class CWorkspaceNode : 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);
}
/// 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);
/// 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;
// 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)
NL3D::CShapeBank *_ShapeBank;
// Relative path from which the ps was inserted
// relative path is also a unique identifier for this ps in the workspace
std::string _RelativePath;
// initial pos of system. Allow to restore the initial instances of the system when doing start / stop
CPSInitialPos _InitialPos;
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
CWorkspaceNode();
public:
// DTor
~CWorkspaceNode();
}; /* class CWorkspaceNode */
typedef std::vector<NLMISC::CRefPtr<CWorkspaceNode> > TNodeVect;
typedef TNodeVect::iterator TPWNodeItr;
/**
@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)
There is a feedback mechanism showed changes are being made with the container,with a particle system or connection to the skeleton.
*/
class CParticleWorkspace
{
public:
/// 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
/// must be called prior to other methods
void init(const std::string &filename);
/// Set a new name for the workspace (not its filename)
void setName(const std::string &name);
/// Set a new file name for the workspace
void setFileName(const std::string &fileName);
std::string getName() const
{
return _Name;
}
/// 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
uint getNumNode() const
{
return (uint)_Nodes.size();
}
/// Get a node in workspace
/// Can keep pointer safely as long as the node is not deleted
CWorkspaceNode *getNode(uint index) const
{
return _Nodes[index];
}
/// Get a node from a pointer on a particle system
CWorkspaceNode *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
CWorkspaceNode *addNode(const std::string &filenameWithFullPath) throw( NLMISC::Exception);
/// Remove a node by it's index
void removeNode(uint index);
/// Remove a node by it's pointer
void removeNode(CWorkspaceNode *ptr);
/// Get index of a node from its pointer, or -1 if not found
sint getIndexFromNode(CWorkspaceNode *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 whether 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 whether 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;
}
/// Restick all objects, useful after loading
void restickAllObjects();
TNodeVect& getNodeList()
{
return _Nodes;
}
private:
// use smart ptr to avoir prb wih resize
TNodeVect _Nodes;
// path + name of workspace
std::string _Filename;
bool _Modified;
IModificationCallback *_ModificationCallback;
// workspace user name
std::string _Name;
/// 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(CWorkspaceNode &node);
}; /* class CParticleWorkspace */
} /* namespace NLQT */
#endif // PARTICLE_NODE_H