# Home    # nevrax.com   
Nevrax
Nevrax.org
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
Docs
 
Documentation  
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  

ps_particle_basic.h

Go to the documentation of this file.
00001 
00007 /* Copyright, 2001 Nevrax Ltd.
00008  *
00009  * This file is part of NEVRAX NEL.
00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2, or (at your option)
00013  * any later version.
00014 
00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00018  * General Public License for more details.
00019 
00020  * You should have received a copy of the GNU General Public License
00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00023  * MA 02111-1307, USA.
00024  */
00025 
00026 #ifndef NL_PS_PARTICLE_BASIC_H
00027 #define NL_PS_PARTICLE_BASIC_H
00028 
00029 #include "nel/misc/types_nl.h"
00030 #include "nel/misc/vector_2f.h"
00031 #include "3d/ps_located.h"
00032 #include "3d/ps_plane_basis.h"
00033 #include "3d/material.h"
00034 #include "3d/ps_attrib_maker.h"
00035 
00036 namespace NL3D 
00037 {
00038 
00039 
00041 // class forward declarations //
00043 
00044 class CTextureGrouped;
00045 
00054 class CPSParticle : public CPSLocatedBindable
00055 {
00056 public:
00057 
00059         CPSParticle();
00060 
00062         uint32 getType(void) const { return PSParticle; }
00063 
00065         virtual uint32 getPriority(void) const { return 1000; }
00066 
00068         virtual bool hasParticles(void) const { nlassert(_Owner); return _Owner->getSize() != 0; }
00069         
00073         virtual void step(TPSProcessPass pass, TAnimationTime ellapsedTime, TAnimationTime realEt)
00074         {
00075                 if (
00076                         (pass == PSBlendRender && hasTransparentFaces())
00077                         || (pass == PSSolidRender && hasOpaqueFaces())
00078                         )
00079                 {
00080                         draw(pass == PSSolidRender);
00081                 }
00082                 else 
00083                 if (pass == PSToolRender) // edition mode only
00084                 {                       
00085                         showTool();
00086                 }
00087         }
00088 
00090         virtual bool hasTransparentFaces(void)  = 0;
00091 
00093         virtual bool hasOpaqueFaces(void)  = 0;
00094 
00096         virtual void draw(bool opaque) {}
00097 
00099         virtual void showTool();
00100 
00102         virtual uint32 getMaxNumFaces(void) const = 0;
00103         
00105         virtual void serial(NLMISC::IStream &f) throw(NLMISC::EStream)
00106         {               
00108                 sint ver = f.serialVersion(2);
00109                 CPSLocatedBindable::serial(f);
00110                 if (ver >= 2)
00111                 {
00112                         f.serial(_DisableAutoLOD);
00113                 }               
00114         }
00115 
00116 
00118         void    disableAutoLOD(bool disable = true) { _DisableAutoLOD = disable; }
00119 
00121         bool    isAutoLODDisabled() const { return _DisableAutoLOD; }   
00122 
00123 protected:
00124 
00129         void notifyOwnerMaxNumFacesChanged(void) const
00130         {
00131                 if (_Owner)
00132                 {
00133                         _Owner->notifyMaxNumFacesChanged();
00134                 }
00135         }
00136 
00139         virtual void newElement(CPSLocated *emitterLocated, uint32 emitterIndex) = 0;
00140         
00145         virtual void deleteElement(uint32 index) = 0;
00146 
00150         virtual void resize(uint32 size) = 0;
00151 
00152 
00157          void computeSrcStep(uint32 &step, uint &numToProcess);
00158 
00159 private:
00161          bool   _DisableAutoLOD;
00162 };
00163 
00166 
00168 class CPSColoredParticle
00169 {
00170         public:
00171 
00176                 void setColorScheme(CPSAttribMaker<CRGBA> *col);
00177 
00179                 CPSAttribMaker<CRGBA> *getColorScheme(void) { return _ColorScheme; }
00180 
00182                 const CPSAttribMaker<CRGBA> *getColorScheme(void) const { return _ColorScheme; }
00183 
00185                 void setColor(NLMISC::CRGBA col);
00186 
00188                 NLMISC::CRGBA getColor(void) const { return _Color; }
00189 
00191                 CPSColoredParticle();
00192 
00194                 virtual ~CPSColoredParticle();
00195 
00197                 void serialColorScheme(NLMISC::IStream &f) throw(NLMISC::EStream);              
00198 
00199         protected:              
00200 
00202                 virtual CPSLocated *getColorOwner(void) = 0;            
00203                 CRGBA _Color;
00204                 
00205                 CPSAttribMaker<CRGBA> *_ColorScheme;                                            
00206 
00208                 virtual void updateMatAndVbForColor(void) = 0;
00209 
00210                 void newColorElement(CPSLocated *emitterLocated, uint32 emitterIndex)
00211                 {
00212                         if (_ColorScheme && _ColorScheme->hasMemory()) _ColorScheme->newElement(emitterLocated, emitterIndex);
00213                 }       
00214                 void deleteColorElement(uint32 index)
00215                 {
00216                         if (_ColorScheme && _ColorScheme->hasMemory()) _ColorScheme->deleteElement(index);
00217                 }
00218                 void resizeColor(uint32 size)
00219                 {
00220                         nlassert(size < (1 << 16));
00221                         if (_ColorScheme && _ColorScheme->hasMemory()) _ColorScheme->resize(size, getColorOwner()->getSize());
00222                 }
00223 };
00224 
00227 
00229 class CPSSizedParticle
00230 {
00231         public:
00232 
00237                 void setSizeScheme(CPSAttribMaker<float> *size);
00238 
00239 
00240 
00242                 CPSAttribMaker<float> *getSizeScheme(void) { return _SizeScheme; }
00243 
00245                 const CPSAttribMaker<float> *getSizeScheme(void) const { return _SizeScheme; }
00246 
00248                 void setSize(float size);
00249 
00251                 float getSize(void) const { return _ParticleSize; }
00252 
00254                 CPSSizedParticle();
00255 
00257                 virtual ~CPSSizedParticle();
00258 
00260                 void serialSizeScheme(NLMISC::IStream &f) throw(NLMISC::EStream);
00261 
00262         protected:      
00263                 
00265                 virtual CPSLocated *getSizeOwner(void) = 0;             
00266                 float _ParticleSize;
00267                 CPSAttribMaker<float> *_SizeScheme;
00268                 void newSizeElement(CPSLocated *emitterLocated, uint32 emitterIndex)
00269                 {
00270                         if (_SizeScheme && _SizeScheme->hasMemory()) _SizeScheme->newElement(emitterLocated, emitterIndex);
00271                 }       
00272                 void deleteSizeElement(uint32 index)
00273                 {
00274                         if (_SizeScheme && _SizeScheme->hasMemory()) _SizeScheme->deleteElement(index);
00275                 }
00276                 void resizeSize(uint32 size)
00277                 {
00278                         nlassert(size < (1 << 16));
00279                         if (_SizeScheme && _SizeScheme->hasMemory()) _SizeScheme->resize(size, getSizeOwner()->getSize());
00280                 }
00281 };
00282 
00283 
00286 
00288 class CPSRotated2DParticle
00289 {
00290         public:
00291 
00297                 void setAngle2DScheme(CPSAttribMaker<float> *scheme);
00298 
00300                 CPSAttribMaker<float> *getAngle2DScheme(void) { return _Angle2DScheme; }
00301 
00303                 const CPSAttribMaker<float> *getAngle2DScheme(void) const { return _Angle2DScheme; }
00304 
00305 
00310                 void setAngle2D(float angle);
00311 
00313                 float getAngle2D(void) const { return _Angle2D; }
00314 
00316                 CPSRotated2DParticle();
00317 
00319                 virtual ~CPSRotated2DParticle();
00320 
00322                 void serialAngle2DScheme(NLMISC::IStream &f) throw(NLMISC::EStream);
00323 
00324 
00325 
00331                 static inline const float *getRotTable(void)
00332                 {
00333                         nlassert(_InitializedRotTab); // must have called initRotTable at the start of the apply
00334                         return _RotTable;
00335                 }
00336 
00338                 static void initRotTable(void);
00339 
00340         protected:      
00342                 virtual CPSLocated *getAngle2DOwner(void) = 0;
00343                                 
00344                 float _Angle2D;
00345                 CPSAttribMaker<float> *_Angle2DScheme;
00346                 static float _RotTable[4 * 256];
00347 
00348                 //#ifdef NL_DEBUG
00350                         static bool _InitializedRotTab;
00351                 //#endif
00352 
00353                 void newAngle2DElement(CPSLocated *emitterLocated, uint32 emitterIndex)
00354                 {
00355                         if (_Angle2DScheme && _Angle2DScheme->hasMemory()) _Angle2DScheme->newElement(emitterLocated, emitterIndex);
00356                 }       
00357                 void deleteAngle2DElement(uint32 index)
00358                 {
00359                         if (_Angle2DScheme && _Angle2DScheme->hasMemory()) _Angle2DScheme->deleteElement(index);
00360                 }
00361                 void resizeAngle2D(uint32 size)
00362                 {
00363                         nlassert(size < (1 << 16));
00364                         if (_Angle2DScheme && _Angle2DScheme->hasMemory()) _Angle2DScheme->resize(size, getAngle2DOwner()->getSize());
00365                 }
00366 };
00367 
00368 
00371 
00373 struct CPSTexturedParticleNoAnim
00374 {
00376                 virtual void                                            setTexture(CSmartPtr<ITexture> tex) = 0;
00378                 virtual ITexture                                        *getTexture(void) = 0;
00379                 virtual const ITexture                          *getTexture(void) const = 0;
00380 };
00381 
00384 
00388 class CPSTexturedParticle
00389 {
00390         public:
00391 
00398                 void setTextureIndexScheme(CPSAttribMaker<sint32> *animOrder);
00399 
00401                 CPSAttribMaker<sint32> *getTextureIndexScheme(void) { return _TextureIndexScheme; }
00402 
00404                 const CPSAttribMaker<sint32> *getTextureIndexScheme(void) const { return _TextureIndexScheme; }
00405 
00407                 void setTextureIndex(sint32 index);
00408 
00410                 sint32 getTextureIndex(void) const { return _TextureIndex; }            
00411 
00413                 void setTextureGroup(NLMISC::CSmartPtr<CTextureGrouped> texGroup);
00414 
00416                 CTextureGrouped *getTextureGroup(void) {  return _TexGroup; }
00417 
00419                 const CTextureGrouped *getTextureGroup(void) const { return _TexGroup; }
00420 
00425                 void setTexture(CSmartPtr<ITexture> tex);
00426 
00428                 ITexture *getTexture(void) { return _Tex; }
00429                 // get the texture (const version)
00430                 const ITexture *getTexture(void) const { return _Tex; }
00431 
00433                 CPSTexturedParticle();
00434 
00436                 virtual ~CPSTexturedParticle();
00437 
00439                 void serialTextureScheme(NLMISC::IStream &f) throw(NLMISC::EStream);            
00440                 
00441         protected:                      
00443                 virtual CPSLocated *getTextureIndexOwner(void) = 0;
00444                 
00445                 // a single texture
00446                 CSmartPtr<ITexture> _Tex;
00447 
00448                 // a grouped texture
00449                 CSmartPtr<CTextureGrouped> _TexGroup;           
00450                 
00451                 CPSAttribMaker<sint32> *_TextureIndexScheme;
00452 
00453                 // a texture index. Most of the time, a scheme of index will be used instead of that
00454                 sint32 _TextureIndex;
00455 
00457                 virtual void updateMatAndVbForTexture(void) = 0;
00458 
00459                 void newTextureIndexElement(CPSLocated *emitterLocated, uint32 emitterIndex)
00460                 {
00461                         if (_TextureIndexScheme && _TextureIndexScheme->hasMemory()) _TextureIndexScheme->newElement(emitterLocated, emitterIndex);
00462                 }       
00463                 void deleteTextureIndexElement(uint32 index)
00464                 {
00465                         if (_TextureIndexScheme && _TextureIndexScheme->hasMemory()) _TextureIndexScheme->deleteElement(index);
00466                 }
00467                 void resizeTextureIndex(uint32 size)
00468                 {
00469                         nlassert(size < (1 << 16));
00470                         if (_TextureIndexScheme && _TextureIndexScheme->hasMemory()) _TextureIndexScheme->resize(size, getTextureIndexOwner()->getSize() );
00471                 }
00472 };
00473 
00476 
00482 class CPSMultiTexturedParticle
00483 {
00484 public:
00486         CPSMultiTexturedParticle();
00487 
00489         enum TOperator { Add = 0, Modulate, Decal, EnvBumpMap, Last = 0xff };
00490 
00492         void                                            enableMultiTexture(bool enabled = true);
00493         bool                                            isMultiTextureEnabled() const   { return (_MultiTexState & (uint8) MultiTextureEnabled) != 0; }
00494 
00496         void                                            setTexture2(ITexture *tex);     
00497 
00499         const ITexture                          *getTexture2() const { return _Texture2; }
00500         ITexture                                        *getTexture2() { return _Texture2; }
00501 
00505         void                                            setMainTexOp(TOperator op);     
00506 
00507         TOperator                                       getMainTexOp() const       { return _MainOp; }
00508 
00509         // Enable the use of an alternate texture for multitexturing. When disabled, this discard the textures that may have been set.
00510         void                                            enableAlternateTex(bool enabled = true);
00511         bool                                            isAlternateTexEnabled() const { return (_MultiTexState & (uint8) AlternateTextureEnabled) != 0; }
00512         
00514         // Convert the texture to / from a bumpmap if needed. (so you just provide its heightmap)
00515         void                                            setTexture2Alternate(ITexture *tex);
00516 
00518         const ITexture                          *getTexture2Alternate() const { return _AlternateTexture2; }
00519         ITexture                                        *getTexture2Alternate() { return _AlternateTexture2; }
00520 
00522         void                                            setAlternateTexOp(TOperator op); 
00523         
00524         TOperator                                       getAlternateTexOp() const           
00525         {               
00526                 return _AlternateOp; 
00527         }
00528 
00532         void                                            setScrollSpeed(uint stage, const NLMISC::CVector2f &sp) 
00533         {
00534                 nlassert(stage < 2);
00535                 _TexScroll[stage] = sp;         
00536         }
00537         const NLMISC::CVector2f         &getScrollSpeed(uint stage) const
00538         {
00539                 nlassert(stage < 2);
00540                 return _TexScroll[stage];
00541         }
00542 
00546         void                                            setAlternateScrollSpeed(uint stage, const NLMISC::CVector2f &sp) 
00547         {
00548                 nlassert(stage < 2);
00549                 _TexScrollAlternate[stage] = sp;
00550         }
00551         const NLMISC::CVector2f         &getAlternateScrollSpeed(uint stage) const
00552         {
00553                 nlassert(stage < 2);
00554                 return _TexScrollAlternate[stage];
00555         }
00556 
00558         void serialMultiTex(NLMISC::IStream &f) throw(NLMISC::EStream); 
00559 
00564         void setupMaterial(ITexture *primary, IDriver *drv, CMaterial &mat);
00565 
00569         static void forceBasicCaps(bool force = true) { _ForceBasicCaps =  force; }
00570 
00572         static  bool areBasicCapsForced() { return _ForceBasicCaps; }
00573 
00575         void    setUseLocalDate(bool use);
00576         bool    getUseLocalDate() { return (_MultiTexState & ScrollUseLocalDate) != 0; }
00577 
00579         void    setUseLocalDateAlt(bool use);
00580         bool    getUseLocalDateAlt() { return (_MultiTexState & ScrollUseLocalDateAlternate) != 0; }
00581 
00583         void    setBumpFactor(float bumpFactor) { _BumpFactor = bumpFactor; touch(); }
00584         float   getBumpFactor() const { return _BumpFactor; }
00585 
00586 protected:      
00587         void                                            setupMultiTexEnv(TOperator op, ITexture *tex1, ITexture *tex2, CMaterial &mat); 
00588         TOperator                                       _MainOp, _AlternateOp;
00589         NLMISC::CSmartPtr<ITexture> _Texture2;
00590         NLMISC::CSmartPtr<ITexture> _AlternateTexture2; 
00591 
00593         NLMISC::CVector2f _TexScroll[2];
00595         NLMISC::CVector2f _TexScrollAlternate[2];
00596         
00597         enum TMultiTexState {  TouchFlag = 0x01, MultiTextureEnabled = 0x02, AlternateTextureEnabled = 0x04, AlternateTextureUsed = 0x08, EnvBumpMapUsed = 0x10, BasicCapsForced = 0x20,
00598                                                         ScrollUseLocalDate = 0x40, ScrollUseLocalDateAlternate = 0x80
00599                                                 };
00600         uint8   _MultiTexState;
00601 
00603         bool    isAlternateTextureUsed() const { return (_MultiTexState & AlternateTextureUsed) != 0; }
00604         bool    isEnvBumpMapUsed() const { return (_MultiTexState & EnvBumpMapUsed) != 0; }
00605 
00606         void touch()            { _MultiTexState |= (uint8) TouchFlag; }
00607         void unTouch()          { _MultiTexState &= ~ (uint8) TouchFlag; }
00608         bool isTouched()        { return (_MultiTexState & TouchFlag) != 0; }   
00609         bool areBasicCapsForcedLocal() const { return (_MultiTexState & BasicCapsForced) != 0; }
00610         void forceBasicCapsLocal(bool force) 
00611         { 
00612                 if (force) _MultiTexState |= BasicCapsForced;
00613                 else _MultiTexState &= ~BasicCapsForced;
00614         }
00615         float           _BumpFactor;
00616         static bool _ForceBasicCaps;    
00617 };
00618  
00619 
00622 
00626 class CPSRotated3DPlaneParticle
00627 {
00628         public:
00629 
00634                 void setPlaneBasisScheme(CPSAttribMaker<CPlaneBasis> *basisMaker);
00635 
00640 
00641                 CPSAttribMaker<CPlaneBasis> *getPlaneBasisScheme(void) { return _PlaneBasisScheme; }
00642 
00644                 const CPSAttribMaker<CPlaneBasis> *getPlaneBasisScheme(void) const { return _PlaneBasisScheme; }
00645 
00646                 void setPlaneBasis(const CPlaneBasis &basis);
00647 
00649                 CPlaneBasis getPlaneBasis(void) const { return _PlaneBasis; }
00650 
00652                 CPSRotated3DPlaneParticle();
00653 
00655                 virtual ~CPSRotated3DPlaneParticle();
00656 
00658                 void serialPlaneBasisScheme(NLMISC::IStream &f) throw(NLMISC::EStream);
00659 
00660         protected:              
00662 
00664                 virtual CPSLocated *getPlaneBasisOwner(void) = 0;               
00665                 
00666                 CPSAttribMaker<CPlaneBasis> *_PlaneBasisScheme;
00667                 
00668                 CPlaneBasis _PlaneBasis; // constant basis..
00669 
00670                 void newPlaneBasisElement(CPSLocated *emitterLocated, uint32 emitterIndex)
00671                 {
00672                         if (_PlaneBasisScheme && _PlaneBasisScheme->hasMemory()) _PlaneBasisScheme->newElement(emitterLocated, emitterIndex);
00673                 }       
00674                 void deletePlaneBasisElement(uint32 index)
00675                 {
00676                         if (_PlaneBasisScheme && _PlaneBasisScheme->hasMemory()) _PlaneBasisScheme->deleteElement(index);
00677                 }
00678                 void resizePlaneBasis(uint32 size)
00679                 {
00680                         nlassert(size < (1 << 16));
00681                         if (_PlaneBasisScheme && _PlaneBasisScheme->hasMemory()) _PlaneBasisScheme->resize(size, getPlaneBasisOwner()->getSize());
00682                 }
00683 };
00684 
00687 
00692 struct CPSHintParticleRotateTheSame
00693 {
00703         virtual void hintRotateTheSame(uint32 nbConfiguration
00704                                                         , float minAngularVelocity = NLMISC::Pi
00705                                                         , float maxAngularVelocity = NLMISC::Pi
00706                                                   ) = 0;
00707 
00712         virtual void disableHintRotateTheSame(void) = 0;
00713         
00714 
00719         virtual uint32 checkHintRotateTheSame(float &minAngularVelocity, float &maxAngularVelocity) const = 0;
00720 };
00721 
00724 
00726 struct CPSTailParticle
00727 {
00731         virtual void setColorFading(bool onOff = true) = 0;
00732 
00734         virtual bool getColorFading(void) const = 0;
00735                 
00736                 
00738         virtual void setTailNbSeg(uint32 nbSeg) = 0;
00739 
00740         // get the number of segments in the tail
00741         virtual uint32 getTailNbSeg(void) const = 0;
00742 
00743         
00748         virtual void setSystemBasis(bool yes) = 0;
00749                 
00751         virtual bool isInSystemBasis(void) const = 0;
00752 };
00753 
00756 
00758 struct CPSShapeParticle
00759 {
00761         virtual void setShape(const std::string &shape) = 0;
00762 
00764         virtual std::string getShape(void) const = 0;
00765 };
00766 
00769 
00773 class CPSMaterial
00774 {
00775 public:
00777         CPSMaterial();
00778 
00780         enum TBlendingMode { add, modulate, alphaBlend, alphaTest };    
00781 
00783         void serialMaterial(NLMISC::IStream &f) throw(NLMISC::EStream); 
00784 
00786         void setBlendingMode(CPSMaterial::TBlendingMode mode);
00787 
00789         CPSMaterial::TBlendingMode getBlendingMode(void) const; 
00790 
00791 
00796         void forceModulateConstantColor(bool force, const NLMISC::CRGBA &col = NLMISC::CRGBA::White);
00797 
00804         void forceTexturedMaterialStages(uint numStages);
00805 
00806         
00807 protected:
00808         CMaterial _Mat;         
00809 };
00810 
00811 
00812 //==========================================================================    
00814 inline void SetupModulatedStage(CMaterial &m, uint stage, CMaterial::TTexSource src1, CMaterial::TTexSource src2)
00815 {
00816         m.texEnvOpRGB(stage, CMaterial::Modulate);
00817         m.texEnvOpAlpha(stage, CMaterial::Modulate);
00818         m.texEnvArg0RGB(stage, src1, CMaterial::SrcColor);
00819         m.texEnvArg1RGB(stage, src2, CMaterial::SrcColor);
00820         m.texEnvArg0Alpha(stage, src1, CMaterial::SrcAlpha);
00821         m.texEnvArg1Alpha(stage, src2, CMaterial::SrcAlpha);
00822 }
00823 
00824 
00825 
00826 
00827 } // NL3D
00828 
00829 
00830 #endif // NL_PS_PARTICLE_BASIC_H
00831 
00832 /* End of ps_particle_basic.h */