00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00021
00022
00023 #ifndef H_SPK_GROUP
00024 #define H_SPK_GROUP
00025
00026 #include "Core/SPK_DEF.h"
00027 #include "Core/SPK_Registerable.h"
00028 #include "Core/SPK_Transformable.h"
00029 #include "Core/SPK_Vector3D.h"
00030 #include "Core/SPK_Pool.h"
00031 #include "Core/SPK_Particle.h"
00032
00033
00034 namespace SPK
00035 {
00036 class Renderer;
00037 class Emitter;
00038 class Modifier;
00039 class Zone;
00040 class Model;
00041 class Buffer;
00042 class BufferCreator;
00043
00053 class SPK_PREFIX Group : public Registerable, public Transformable
00054 {
00055 friend class Renderer;
00056 friend class Particle;
00057 friend void swapParticles(Particle& a,Particle& b);
00058
00059 SPK_IMPLEMENT_REGISTERABLE(Group)
00060
00061 public :
00062
00064
00066
00080 Group(Model* model = NULL,size_t capacity = Pool<Particle>::DEFAULT_CAPACITY);
00081
00086 Group(const Group& group);
00087
00095 static Group* create(Model* model = NULL,size_t capacity = Pool<Particle>::DEFAULT_CAPACITY);
00096
00098
00100
00102 ~Group();
00103
00105
00107
00116 void setModel(Model* model);
00117
00128 void setRenderer(Renderer* renderer);
00129
00146 void setFriction(float friction);
00147
00159 void setGravity(const Vector3D& gravity);
00160
00176 void setCustomUpdate(bool (*fupdate)(Particle&,float));
00177
00188 void setCustomBirth(void (*fbirth)(Particle&));
00189
00200 void setCustomDeath(void (*fdeath)(Particle&));
00201
00214 void enableSorting(bool sort);
00215
00229 void enableDistanceComputation(bool distanceComputation);
00230
00243 void enableAABBComputing(bool AABB);
00244
00256 static void enableBuffersManagement(bool manage);
00257
00259
00261
00269 const Pool<Particle>& getParticles() const;
00270
00280 Particle& getParticle(size_t index);
00281
00291 const Particle& getParticle(size_t index) const;
00292
00297 size_t getNbParticles() const;
00298
00303 const std::vector<Emitter*>& getEmitters() const;
00304
00310 Emitter* getEmitter(size_t index) const;
00311
00316 size_t getNbEmitters() const;
00317
00322 const std::vector<Modifier*>& getModifiers() const;
00323
00329 Modifier* getModifier(size_t index) const;
00330
00335 size_t getNbModifiers() const;
00336
00341 Model* getModel() const;
00342
00347 Renderer* getRenderer() const;
00348
00356 float getFriction() const;
00357
00365 const Vector3D& getGravity() const;
00366
00374 bool isSortingEnabled() const;
00375
00381 bool isDistanceComputationEnabled() const;
00382
00390 bool isAABBComputingEnabled() const;
00391
00399 const Vector3D& getAABBMin() const;
00400
00408 const Vector3D& getAABBMax() const;
00409
00421 const void* getParamAddress(ModelParam param) const;
00422
00431 const void* getPositionAddress() const;
00432
00441 size_t getParamStride() const;
00442
00451 size_t getPositionStride() const;
00452
00461 static bool isBuffersManagementEnabled();
00462
00464
00466
00491 void addParticles(unsigned int nb,const Vector3D& position,const Vector3D& velocity);
00492
00503 void addParticles(unsigned int nb,const Zone* zone,Emitter* emitter,bool full = true);
00504
00515 void addParticles(unsigned int nb,const Zone* zone,const Vector3D& velocity,bool full = true);
00516
00526 void addParticles(unsigned int nb,const Vector3D& position,Emitter* emitter);
00527
00536 void addParticles(unsigned int nb,Emitter* emitter);
00537
00548 void addParticles(const Zone* zone,Emitter* emitter,float deltaTime,bool full = true);
00549
00559 void addParticles(const Vector3D& position,Emitter* emitter,float deltaTime);
00560
00569 void addParticles(Emitter* emitter,float deltaTime);
00570
00589 float addParticles(const Vector3D& start,const Vector3D& end,Emitter* emitter,float step,float offset = 0.0f);
00590
00603 float addParticles(const Vector3D& start,const Vector3D& end,const Vector3D& velocity,float step,float offset = 0.0f);
00604
00612 void removeParticle(size_t index);
00613
00621 void addEmitter(Emitter* emitter);
00622
00627 void removeEmitter(Emitter* emitter);
00628
00633 void addModifier(Modifier* modifier);
00634
00639 void removeModifier(Modifier* modifier);
00640
00659 bool update(float deltaTime);
00660
00666 void render();
00667
00674 void empty();
00675
00682 void flushAddedParticles();
00683
00695 void sortParticles();
00696
00706 void computeDistances();
00707
00717 void computeAABB();
00718
00728 void reallocate(size_t capacity);
00729
00750 Buffer* createBuffer(const std::string& ID,const BufferCreator& creator,unsigned int flag = 0,bool swapData = true) const;
00751
00761 void destroyBuffer(const std::string& ID) const;
00762
00767 void destroyAllBuffers() const;
00768
00782 Buffer* getBuffer(const std::string& ID,unsigned int flag) const;
00783
00793 Buffer* getBuffer(const std::string& ID) const;
00794
00795 virtual Registerable* findByName(const std::string& name);
00796
00797 protected :
00798
00799 virtual void registerChildren(bool registerAll);
00800 virtual void copyChildren(const Registerable& object,bool createBase);
00801 virtual void destroyChildren(bool keepChildren);
00802
00803 virtual void propagateUpdateTransform();
00804
00805 private :
00806
00807 struct CreationData
00808 {
00809 unsigned int nb;
00810 Vector3D position;
00811 Vector3D velocity;
00812 const Zone* zone;
00813 Emitter* emitter;
00814 bool full;
00815 };
00816
00817 struct EmitterData
00818 {
00819 Emitter* emitter;
00820 unsigned int nbParticles;
00821 };
00822
00823
00824 static bool bufferManagement;
00825 static Model& getDefaultModel();
00826
00827
00828 Model* model;
00829 Renderer* renderer;
00830 std::vector<Emitter*> emitters;
00831 std::vector<Modifier*> modifiers;
00832
00833 mutable std::vector<EmitterData> activeEmitters;
00834 mutable std::vector<Modifier*> activeModifiers;
00835
00836
00837 float friction;
00838 Vector3D gravity;
00839
00840
00841 Pool<Particle> pool;
00842 Particle::ParticleData* particleData;
00843 float* particleCurrentParams;
00844 float* particleExtendedParams;
00845
00846
00847 bool sortingEnabled;
00848 bool distanceComputationEnabled;
00849
00850
00851 std::deque<CreationData> creationBuffer;
00852 unsigned int nbBufferedParticles;
00853
00854
00855 bool (*fupdate)(Particle&,float);
00856 void (*fbirth)(Particle&);
00857 void (*fdeath)(Particle&);
00858
00859
00860 bool boundingBoxEnabled;
00861 Vector3D AABBMin;
00862 Vector3D AABBMax;
00863
00864
00865 mutable std::map<std::string,Buffer*> additionalBuffers;
00866 mutable std::set<Buffer*> swappableBuffers;
00867
00868 void pushParticle(std::vector<EmitterData>::iterator& emitterIt,unsigned int& nbManualBorn);
00869 void launchParticle(Particle& p,std::vector<EmitterData>::iterator& emitterIt,unsigned int& nbManualBorn);
00870
00871 void addParticles(unsigned int nb,const Vector3D& position,const Vector3D& velocity,const Zone* zone,Emitter* emitter,bool full = false);
00872
00873 void popNextManualAdding(unsigned int& nbManualBorn);
00874
00875 void updateAABB(const Particle& particle);
00876
00877 void sortParticles(int start,int end);
00878 };
00879
00880
00881 inline Group* Group::create(Model* model,size_t capacity)
00882 {
00883 Group* obj = new Group(model,capacity);
00884 registerObject(obj);
00885 return obj;
00886 }
00887
00888 inline void Group::setFriction(float friction)
00889 {
00890 this->friction = friction;
00891 }
00892
00893 inline void Group::setGravity(const Vector3D& gravity)
00894 {
00895 this->gravity = gravity;
00896 }
00897
00898 inline void Group::setCustomUpdate(bool (*fupdate)(Particle&,float))
00899 {
00900 this->fupdate = fupdate;
00901 }
00902
00903 inline void Group::setCustomBirth(void (*fbirth)(Particle&))
00904 {
00905 this->fbirth = fbirth;
00906 }
00907
00908 inline void Group::setCustomDeath(void (*fdeath)(Particle&))
00909 {
00910 this->fdeath = fdeath;
00911 }
00912
00913 inline void Group::enableSorting(bool sort)
00914 {
00915 sortingEnabled = sort;
00916 distanceComputationEnabled = sort;
00917 }
00918
00919 inline void Group::enableDistanceComputation(bool distanceComputation)
00920 {
00921 distanceComputationEnabled = distanceComputation;
00922 if (!distanceComputation) enableSorting(false);
00923 }
00924
00925 inline void Group::enableAABBComputing(bool AABB)
00926 {
00927 boundingBoxEnabled = AABB;
00928 }
00929
00930 inline const Pool<Particle>& Group::getParticles() const
00931 {
00932 return pool;
00933 }
00934
00935 inline Particle& Group::getParticle(size_t index)
00936 {
00937 return pool[index];
00938 }
00939
00940 inline const Particle& Group::getParticle(size_t index) const
00941 {
00942 return pool[index];
00943 }
00944
00945 inline size_t Group::getNbParticles() const
00946 {
00947 return pool.getNbActive();
00948 }
00949
00950 inline const std::vector<Emitter*>& Group::getEmitters() const
00951 {
00952 return emitters;
00953 }
00954
00955 inline Emitter* Group::getEmitter(size_t index) const
00956 {
00957 return emitters[index];
00958 }
00959
00960 inline size_t Group::getNbEmitters() const
00961 {
00962 return emitters.size();
00963 }
00964
00965 inline const std::vector<Modifier*>& Group::getModifiers() const
00966 {
00967 return modifiers;
00968 }
00969
00970 inline Modifier* Group::getModifier(size_t index) const
00971 {
00972 return modifiers[index];
00973 }
00974
00975 inline size_t Group::getNbModifiers() const
00976 {
00977 return modifiers.size();
00978 }
00979
00980 inline Model* Group::getModel() const
00981 {
00982 return model;
00983 }
00984
00985 inline Renderer* Group::getRenderer() const
00986 {
00987 return renderer;
00988 }
00989
00990 inline float Group::getFriction() const
00991 {
00992 return friction;
00993 }
00994
00995 inline const Vector3D& Group::getGravity() const
00996 {
00997 return gravity;
00998 }
00999
01000 inline bool Group::isSortingEnabled() const
01001 {
01002 return sortingEnabled;
01003 }
01004
01005 inline bool Group::isDistanceComputationEnabled() const
01006 {
01007 return distanceComputationEnabled;
01008 }
01009
01010 inline bool Group::isAABBComputingEnabled() const
01011 {
01012 return boundingBoxEnabled;
01013 }
01014
01015 inline const Vector3D& Group::getAABBMin() const
01016 {
01017 return AABBMin;
01018 }
01019
01020 inline const Vector3D& Group::getAABBMax() const
01021 {
01022 return AABBMax;
01023 }
01024
01025 inline void Group::addParticles(unsigned int nb,const Vector3D& position,const Vector3D& velocity)
01026 {
01027 addParticles(nb,position,velocity,NULL,NULL);
01028 }
01029
01030 inline void Group::addParticles(unsigned int nb,const Zone* zone,Emitter* emitter,bool full)
01031 {
01032 addParticles(nb,Vector3D(),Vector3D(),zone,emitter,full);
01033 }
01034
01035 inline void Group::addParticles(unsigned int nb,const Zone* zone,const Vector3D& velocity,bool full)
01036 {
01037 addParticles(nb,Vector3D(),velocity,zone,NULL,full);
01038 }
01039
01040 inline void Group::addParticles(unsigned int nb,const Vector3D& position,Emitter* emitter)
01041 {
01042 addParticles(nb,position,Vector3D(),NULL,emitter);
01043 }
01044
01045 inline void Group::removeParticle(size_t index)
01046 {
01047 pool.makeInactive(index);
01048 }
01049
01050 inline const void* Group::getPositionAddress() const
01051 {
01052 return &(particleData[0].position);
01053 }
01054
01055 inline size_t Group::getPositionStride() const
01056 {
01057 return sizeof(Particle::ParticleData);
01058 }
01059 }
01060
01061 #endif