////////////////////////////////////////////////////////////////////////////////// // SPARK particle engine // // Copyright (C) 2008-2009 - Julien Fryer - julienfryer@gmail.com // // // // This software is provided 'as-is', without any express or implied // // warranty. In no event will the authors be held liable for any damages // // arising from the use of this software. // // // // Permission is granted to anyone to use this software for any purpose, // // including commercial applications, and to alter it and redistribute it // // freely, subject to the following restrictions: // // // // 1. The origin of this software must not be misrepresented; you must not // // claim that you wrote the original software. If you use this software // // in a product, an acknowledgment in the product documentation would be // // appreciated but is not required. // // 2. Altered source versions must be plainly marked as such, and must not be // // misrepresented as being the original software. // // 3. This notice may not be removed or altered from any source distribution. // ////////////////////////////////////////////////////////////////////////////////// #ifndef H_SPK_MODIFIERGROUP #define H_SPK_MODIFIERGROUP #include "Core/SPK_Modifier.h" #include "Core/SPK_Particle.h" #include "Core/SPK_Zone.h" namespace SPK { /** * @class ModifierGroup * @brief A Group of Modifiers * * This modifier can be used in 2 ways : * * By default a ModifierGroup is used as a partition group. the user can change it by calling useGlobalGroup(bool,bool) or usePartitionGroup(bool). * * @since 1.02.00 */ class SPK_PREFIX ModifierGroup : public Modifier { SPK_IMPLEMENT_REGISTERABLE(ModifierGroup) public : ///////////////// // Constructor // ///////////////// /** * @brief Constructor of ModifierGroup * @param zone : the Zone of this ModifierGroup * @param trigger : the trigger of the ModifierGroup */ ModifierGroup(Zone* zone = NULL,ModifierTrigger trigger = INSIDE_ZONE); /** * @brief Creates and registers a new ModifierGroup * @param zone : the Zone of this ModifierGroup * @param trigger : the trigger of the ModifierGroup * @return A new registered ModifierGroup * @since 1.04.00 */ static inline ModifierGroup* create(Zone* zone = NULL,ModifierTrigger trigger = INSIDE_ZONE); ///////////// // Setters // ///////////// /** * @brief Uses this ModifierGroup as a global group * * A global group allows to use only one trigger for many modifiers. It works as follow : * Note that if a child Modifier needs intersection or normal computation (the Modifier Obstacle for instance), the variables have to be set. * * @param useIntersection : true to enable intersection computation in this ModifierGroup * @param useNormal : true to enable normal computation in this ModifierGroup */ inline void useGlobalGroup(bool useIntersection = false,bool useNormal = false); /** * @brief Uses this ModifierGroup as a partition group * * A partition group allows to partition the space in order to have faster tests. It works as follow : * * @param handleWrongSide : true to enable intersection computation in this ModifierGroup */ inline void usePartitionGroup(bool handleWrongSide = false); ///////////// // Getters // ///////////// /** * @brief Gets the number of modifiers in this ModifierGroup * @return the number of modifiers in this ModifierGroup */ inline size_t getNb() const; /** * @brief Gets the vector containing all the children modifiers * @return the vector containing all the children modifiers */ inline const std::vector& getModifiers() const; /** * @brief Tells whether this ModifierGroup is a global group * * For more information about global groups, see useGlobalGroup(bool,bool). * * @return true if this ModifierGroup is a global group, false if not */ inline bool isGlobalGroup() const; /** * @brief Tells whether this ModifierGroup is a partition group * * For more information about partition groups, see usePartitionGroup(bool). * * @return true if this ModifierGroup is a partition group, false if not */ inline bool isPartitionGroup() const; /** * @brief Tells whether this partition group handles wrong side * * If this ModifierGroup is a global group, the return value is not used.
* For more information about partition groups, see usePartitionGroup(bool).
*
* Note that the wrong side can only be used with the following triggers : * * @return true if this ModifierGroup handles wrong size, false if not */ inline bool handlesWrongSide() const; /** * @brief Tells whether this global group computes the intersection * * If this ModifierGroup is a partition group, the return value is not used.
* For more information about global groups, see useGlobalGroup(bool,bool).
*
* Note that the intersection can only be used with the following triggers : * * @return true if this ModifierGroup computes the intersection, false if not */ inline bool usesIntersection() const; /** * @brief Tells whether this global group computes the normal * * If this ModifierGroup is a partition group, the return value is not used.
* For more information about global groups, see useGlobalGroup(bool,bool).
*
* Note that the normal can only be used with the following triggers : * * @return true if this ModifierGroup computes the normal, false if not */ inline bool usesNormal() const; /////////////// // Interface // /////////////// /** * @brief Adds a Modifier to this ModifierGroup * @param modifier : the Modifier to add to this ModifierGroup */ void addModifier(Modifier* modifier); /** * @brief Removes a Modifier from this ModifierGroup * @param modifier : the Modifier to remove from this ModifierGroup * @return true if the Modifier has been found and removed, false if not */ bool removeModifier(const Modifier* modifier); /** * @brief Removes all Modifier children from this ModifierGroup */ inline void clear(); virtual void createBuffers(const Group& group); virtual void destroyBuffers(const Group& group); virtual Registerable* findByName(const std::string& name); protected : virtual void registerChildren(bool registerAll); virtual void copyChildren(const ModifierGroup& modifier,bool createBase); virtual void destroyChildren(bool keepChildren); virtual bool checkBuffers(const Group& group); private : std::vector modifiers; bool globalZone; bool handleWrongSide; virtual void modify(Particle& particle,float deltaTime) const; virtual void modifyWrongSide(Particle& particle,bool inside) const; }; inline ModifierGroup* ModifierGroup::create(Zone* zone,ModifierTrigger trigger) { ModifierGroup* obj = new ModifierGroup(zone,trigger); registerObject(obj); return obj; } inline void ModifierGroup::useGlobalGroup(bool useIntersection,bool useNormal) { globalZone = true; needsIntersection = useIntersection; needsNormal = useNormal; } inline void ModifierGroup::usePartitionGroup(bool handleWrongSide) { globalZone = false; this->handleWrongSide = handleWrongSide; } inline size_t ModifierGroup::getNb() const { return modifiers.size(); } inline const std::vector& ModifierGroup::getModifiers() const { return modifiers; } inline bool ModifierGroup::isGlobalGroup() const { return globalZone; } inline bool ModifierGroup::isPartitionGroup() const { return !globalZone; } inline bool ModifierGroup::handlesWrongSide() const { return handleWrongSide; } inline bool ModifierGroup::usesIntersection() const { return needsIntersection; } inline bool ModifierGroup::usesNormal() const { return needsNormal; } } #endif