ps_particle_basic.h

Go to the documentation of this file.
00001 
00005 /* Copyright, 2001 Nevrax Ltd.
00006  *
00007  * This file is part of NEVRAX NEL.
00008  * NEVRAX NEL is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2, or (at your option)
00011  * any later version.
00012 
00013  * NEVRAX NEL is distributed in the hope that it will be useful, but
00014  * WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00016  * General Public License for more details.
00017 
00018  * You should have received a copy of the GNU General Public License
00019  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00020  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00021  * MA 02111-1307, USA.
00022  */
00023 
00024 #ifndef NL_PS_PARTICLE_BASIC_H
00025 #define NL_PS_PARTICLE_BASIC_H
00026 
00027 #include "nel/misc/types_nl.h"
00028 #include "nel/misc/vector_2f.h"
00029 #include "nel/misc/stream.h"
00030 #include "nel/3d/ps_located.h"
00031 #include "nel/3d/ps_plane_basis.h"
00032 #include "nel/3d/material.h"
00033 #include "nel/3d/ps_attrib_maker.h"
00034 
00035 namespace NL3D
00036 {
00037 
00038 
00040 // class forward declarations //
00042 
00043 class CTextureGrouped;
00044 
00053 class CPSParticle : public CPSLocatedBindable
00054 {
00055 public:
00056 
00058     CPSParticle();
00059 
00061     uint32 getType(void) const { return PSParticle; }
00062 
00064     virtual uint32 getPriority(void) const { return 1000; }
00065 
00067     virtual bool hasParticles(void) const { nlassert(_Owner); return _Owner->getSize() != 0; }
00068 
00072     virtual void step(TPSProcessPass pass)
00073     {
00074         if (
00075             (pass == PSBlendRender && hasTransparentFaces())
00076             || (pass == PSSolidRender && hasOpaqueFaces())
00077             )
00078         {
00079             draw(pass == PSSolidRender);
00080         }
00081         else
00082         if (pass == PSToolRender) // edition mode only
00083         {
00084             showTool();
00085         }
00086     }
00087 
00089     virtual bool hasTransparentFaces(void)  = 0;
00090 
00092     virtual bool hasOpaqueFaces(void)  = 0;
00093 
00096     virtual bool hasLightableFaces() = 0;
00097 
00101     bool usesGlobalColorLighting() { return _UsesGlobalColorLighting; }
00102     // active / deactive global color lighting
00103     void enableGlobalColorLighting(bool enabled) { _UsesGlobalColorLighting = enabled; }
00104     // is global color lighting supported ?
00105     virtual bool supportGlobalColorLighting() const = 0;
00106 
00108     virtual void draw(bool opaque) {}
00109 
00111     virtual void showTool();
00112 
00114     virtual uint32 getNumWantedTris() const = 0;
00115 
00117     virtual void serial(NLMISC::IStream &f) throw(NLMISC::EStream)
00118     {
00121         sint ver = f.serialVersion(3);
00122         CPSLocatedBindable::serial(f);
00123         if (ver >= 3)
00124         {
00125             f.serial(_UsesGlobalColorLighting);
00126         }
00127         if (ver >= 2)
00128         {
00129             f.serial(_DisableAutoLOD);
00130         }
00131     }
00132 
00133 
00135     void    disableAutoLOD(bool disable = true) { _DisableAutoLOD = disable; }
00136 
00138     bool    isAutoLODDisabled() const { return _DisableAutoLOD; }
00139 
00140     // Change z-bias of material. this must be redefined for all renderable particles
00141     virtual void            setZBias(float value) = 0;
00142     virtual float           getZBias() const = 0;
00143 
00144 protected:
00145 
00150     /*
00151     void notifyOwnerMaxNumFacesChanged(void) const
00152     {
00153         if (_Owner)
00154         {
00155             _Owner->notifyMaxNumFacesChanged();
00156         }
00157     }*/
00158 
00161     virtual void newElement(const CPSEmitterInfo &info) = 0;
00162 
00167     virtual void deleteElement(uint32 index) = 0;
00168 
00172     virtual void resize(uint32 size) = 0;
00173 
00174 
00179      void computeSrcStep(uint32 &step, uint &numToProcess);
00180 
00181 private:
00183      bool   _DisableAutoLOD;
00184      bool   _UsesGlobalColorLighting;
00185 };
00186 
00189 
00191 class CPSColoredParticle
00192 {
00193     public:
00194 
00199         void setColorScheme(CPSAttribMaker<CRGBA> *col);
00200 
00202         CPSAttribMaker<CRGBA> *getColorScheme(void) { return _ColorScheme; }
00203 
00205         const CPSAttribMaker<CRGBA> *getColorScheme(void) const { return _ColorScheme; }
00206 
00208         void setColor(NLMISC::CRGBA col);
00209 
00211         NLMISC::CRGBA getColor(void) const { return _Color; }
00212 
00214         CPSColoredParticle();
00215 
00217         virtual ~CPSColoredParticle();
00218 
00220         void serialColorScheme(NLMISC::IStream &f) throw(NLMISC::EStream);
00221 
00222     protected:
00223 
00225         virtual CPSLocated *getColorOwner(void) = 0;
00226         CRGBA _Color;
00227 
00228         CPSAttribMaker<CRGBA> *_ColorScheme;
00229 
00231         virtual void updateMatAndVbForColor(void) = 0;
00232 
00233         void newColorElement(const CPSEmitterInfo &info)
00234         {
00235             if (_ColorScheme && _ColorScheme->hasMemory()) _ColorScheme->newElement(info);
00236         }
00237         void deleteColorElement(uint32 index)
00238         {
00239             if (_ColorScheme && _ColorScheme->hasMemory()) _ColorScheme->deleteElement(index);
00240         }
00241         void resizeColor(uint32 size)
00242         {
00243             nlassert(size < (1 << 16));
00244             if (_ColorScheme && _ColorScheme->hasMemory()) _ColorScheme->resize(size, getColorOwner()->getSize());
00245         }
00246 };
00247 
00250 
00252 class CPSSizedParticle
00253 {
00254     public:
00255 
00260         void setSizeScheme(CPSAttribMaker<float> *size);
00261 
00262 
00263 
00265         CPSAttribMaker<float> *getSizeScheme(void) { return _SizeScheme; }
00266 
00268         const CPSAttribMaker<float> *getSizeScheme(void) const { return _SizeScheme; }
00269 
00271         void setSize(float size);
00272 
00274         float getSize(void) const { return _ParticleSize; }
00275 
00277         CPSSizedParticle();
00278 
00280         virtual ~CPSSizedParticle();
00281 
00283         void serialSizeScheme(NLMISC::IStream &f) throw(NLMISC::EStream);
00284 
00285     protected:
00286 
00288         virtual CPSLocated *getSizeOwner(void) = 0;
00289         float _ParticleSize;
00290         CPSAttribMaker<float> *_SizeScheme;
00291         void newSizeElement(const CPSEmitterInfo &info)
00292         {
00293             if (_SizeScheme && _SizeScheme->hasMemory()) _SizeScheme->newElement(info);
00294         }
00295         void deleteSizeElement(uint32 index)
00296         {
00297             if (_SizeScheme && _SizeScheme->hasMemory()) _SizeScheme->deleteElement(index);
00298         }
00299         void resizeSize(uint32 size)
00300         {
00301             nlassert(size < (1 << 16));
00302             if (_SizeScheme && _SizeScheme->hasMemory()) _SizeScheme->resize(size, getSizeOwner()->getSize());
00303         }
00304 };
00305 
00306 
00309 
00311 class CPSRotated2DParticle
00312 {
00313     public:
00314 
00320         void setAngle2DScheme(CPSAttribMaker<float> *scheme);
00321 
00323         CPSAttribMaker<float> *getAngle2DScheme(void) { return _Angle2DScheme; }
00324 
00326         const CPSAttribMaker<float> *getAngle2DScheme(void) const { return _Angle2DScheme; }
00327 
00328 
00333         void setAngle2D(float angle);
00334 
00336         float getAngle2D(void) const { return _Angle2D; }
00337 
00339         CPSRotated2DParticle();
00340 
00342         virtual ~CPSRotated2DParticle();
00343 
00345         void serialAngle2DScheme(NLMISC::IStream &f) throw(NLMISC::EStream);
00346 
00347 
00348 
00354         static inline const float *getRotTable(void)
00355         {
00356             nlassert(_InitializedRotTab); // must have called initRotTable at the start of the apply
00357             return _RotTable;
00358         }
00359 
00361         static void initRotTable(void);
00362 
00363     protected:
00365         virtual CPSLocated *getAngle2DOwner(void) = 0;
00366 
00367         float _Angle2D;
00368         CPSAttribMaker<float> *_Angle2DScheme;
00369         static float _RotTable[4 * 256];
00370 
00371         //#ifdef NL_DEBUG
00373             static bool _InitializedRotTab;
00374         //#endif
00375 
00376         void newAngle2DElement(const CPSEmitterInfo &info)
00377         {
00378             if (_Angle2DScheme && _Angle2DScheme->hasMemory()) _Angle2DScheme->newElement(info);
00379         }
00380         void deleteAngle2DElement(uint32 index)
00381         {
00382             if (_Angle2DScheme && _Angle2DScheme->hasMemory()) _Angle2DScheme->deleteElement(index);
00383         }
00384         void resizeAngle2D(uint32 size)
00385         {
00386             nlassert(size < (1 << 16));
00387             if (_Angle2DScheme && _Angle2DScheme->hasMemory()) _Angle2DScheme->resize(size, getAngle2DOwner()->getSize());
00388         }
00389 };
00390 
00391 
00394 
00396 struct CPSTexturedParticleNoAnim
00397 {
00398         virtual ~CPSTexturedParticleNoAnim() {}
00400         virtual void                        setTexture(CSmartPtr<ITexture> tex) = 0;
00402         virtual ITexture                    *getTexture(void) = 0;
00403         virtual const ITexture              *getTexture(void) const = 0;
00404 };
00405 
00408 
00412 class CPSTexturedParticle
00413 {
00414     public:
00415 
00422         void setTextureIndexScheme(CPSAttribMaker<sint32> *animOrder);
00423 
00425         CPSAttribMaker<sint32> *getTextureIndexScheme(void) { return _TextureIndexScheme; }
00426 
00428         const CPSAttribMaker<sint32> *getTextureIndexScheme(void) const { return _TextureIndexScheme; }
00429 
00431         void setTextureIndex(sint32 index);
00432 
00434         sint32 getTextureIndex(void) const { return _TextureIndex; }
00435 
00437         virtual void setTextureGroup(NLMISC::CSmartPtr<CTextureGrouped> texGroup);
00438 
00440         CTextureGrouped *getTextureGroup(void) {  return _TexGroup; }
00441 
00443         const CTextureGrouped *getTextureGroup(void) const { return _TexGroup; }
00444 
00449         virtual void setTexture(CSmartPtr<ITexture> tex);
00450 
00452         ITexture *getTexture(void) { return _Tex; }
00453         // get the texture (const version)
00454         const ITexture *getTexture(void) const { return _Tex; }
00455 
00457         CPSTexturedParticle();
00458 
00460         virtual ~CPSTexturedParticle();
00461 
00463         void serialTextureScheme(NLMISC::IStream &f) throw(NLMISC::EStream);
00464 
00465         void            enumTexs(std::vector<NLMISC::CSmartPtr<ITexture> > &dest);
00466 
00467 
00468     protected:
00470         virtual CPSLocated *getTextureIndexOwner(void) = 0;
00471 
00472         // a single texture
00473         CSmartPtr<ITexture> _Tex;
00474 
00475         // a grouped texture
00476         CSmartPtr<CTextureGrouped> _TexGroup;
00477 
00478         CPSAttribMaker<sint32> *_TextureIndexScheme;
00479 
00480         // a texture index. Most of the time, a scheme of index will be used instead of that
00481         sint32 _TextureIndex;
00482 
00484         virtual void updateMatAndVbForTexture(void) = 0;
00485 
00486         void newTextureIndexElement(const CPSEmitterInfo &info)
00487         {
00488             if (_TextureIndexScheme && _TextureIndexScheme->hasMemory()) _TextureIndexScheme->newElement(info);
00489         }
00490         void deleteTextureIndexElement(uint32 index)
00491         {
00492             if (_TextureIndexScheme && _TextureIndexScheme->hasMemory()) _TextureIndexScheme->deleteElement(index);
00493         }
00494         void resizeTextureIndex(uint32 size)
00495         {
00496             nlassert(size < (1 << 16));
00497             if (_TextureIndexScheme && _TextureIndexScheme->hasMemory()) _TextureIndexScheme->resize(size, getTextureIndexOwner()->getSize() );
00498         }
00499 };
00500 
00503 
00509 class CPSMultiTexturedParticle
00510 {
00511 public:
00513     CPSMultiTexturedParticle();
00514     virtual ~CPSMultiTexturedParticle() {}
00515 
00517     enum TOperator { Add = 0, Modulate, Decal, EnvBumpMap, Last = 0xff };
00518 
00520     void                        enableMultiTexture(bool enabled = true);
00521     bool                        isMultiTextureEnabled() const   { return (_MultiTexState & (uint8) MultiTextureEnabled) != 0; }
00522 
00524     void                        setTexture2(ITexture *tex);
00525 
00527     const ITexture              *getTexture2() const { return _Texture2; }
00528     ITexture                    *getTexture2() { return _Texture2; }
00529 
00533     void                        setMainTexOp(TOperator op);
00534 
00535     TOperator                   getMainTexOp() const       { return _MainOp; }
00536 
00537     // Enable the use of an alternate texture for multitexturing. When disabled, this discard the textures that may have been set.
00538     void                        enableAlternateTex(bool enabled = true);
00539     bool                        isAlternateTexEnabled() const { return (_MultiTexState & (uint8) AlternateTextureEnabled) != 0; }
00540 
00542     // Convert the texture to / from a bumpmap if needed. (so you just provide its heightmap)
00543     void                        setTexture2Alternate(ITexture *tex);
00544 
00546     const ITexture              *getTexture2Alternate() const { return _AlternateTexture2; }
00547     ITexture                    *getTexture2Alternate() { return _AlternateTexture2; }
00548 
00550     void                        setAlternateTexOp(TOperator op);
00551 
00552     TOperator                   getAlternateTexOp() const
00553     {
00554         return _AlternateOp;
00555     }
00556 
00560     void                        setScrollSpeed(uint stage, const NLMISC::CVector2f &sp)
00561     {
00562         nlassert(stage < 2);
00563         _TexScroll[stage] = sp;
00564     }
00565     const NLMISC::CVector2f     &getScrollSpeed(uint stage) const
00566     {
00567         nlassert(stage < 2);
00568         return _TexScroll[stage];
00569     }
00570 
00574     void                        setAlternateScrollSpeed(uint stage, const NLMISC::CVector2f &sp)
00575     {
00576         nlassert(stage < 2);
00577         _TexScrollAlternate[stage] = sp;
00578     }
00579     const NLMISC::CVector2f     &getAlternateScrollSpeed(uint stage) const
00580     {
00581         nlassert(stage < 2);
00582         return _TexScrollAlternate[stage];
00583     }
00584 
00586     void serialMultiTex(NLMISC::IStream &f) throw(NLMISC::EStream);
00587 
00593     void setupMaterial(ITexture *primary, IDriver *drv, CMaterial &mat, CVertexBuffer &vb);
00594 
00598     static void forceBasicCaps(bool force = true) { _ForceBasicCaps =  force; }
00599 
00601     static  bool areBasicCapsForced() { return _ForceBasicCaps; }
00602 
00604     void    setUseLocalDate(bool use);
00605     bool    getUseLocalDate() { return (_MultiTexState & ScrollUseLocalDate) != 0; }
00606 
00608     void    setUseLocalDateAlt(bool use);
00609     bool    getUseLocalDateAlt() { return (_MultiTexState & ScrollUseLocalDateAlternate) != 0; }
00610 
00612     void    setBumpFactor(float bumpFactor) { _BumpFactor = bumpFactor; touch(); }
00613     float   getBumpFactor() const { return _BumpFactor; }
00614 
00615     void            enumTexs(std::vector<NLMISC::CSmartPtr<ITexture> > &dest, IDriver &drv);
00616 
00617 
00618 protected:
00619     void                        setupMultiTexEnv(TOperator op, ITexture *tex1, ITexture *tex2, CMaterial &mat, IDriver &drv);
00620     TOperator                   _MainOp, _AlternateOp;
00621     NLMISC::CSmartPtr<ITexture> _Texture2;
00622     NLMISC::CSmartPtr<ITexture> _AlternateTexture2;
00623 
00625     NLMISC::CVector2f _TexScroll[2];
00627     NLMISC::CVector2f _TexScrollAlternate[2];
00628 
00629     enum TMultiTexState {  TouchFlag = 0x01, MultiTextureEnabled = 0x02, AlternateTextureEnabled = 0x04, AlternateTextureUsed = 0x08, EnvBumpMapUsed = 0x10, BasicCapsForced = 0x20,
00630                             ScrollUseLocalDate = 0x40, ScrollUseLocalDateAlternate = 0x80
00631                         };
00632     uint8   _MultiTexState;
00633 
00635     bool    isAlternateTextureUsed(IDriver &driver) const;
00636     bool    isEnvBumpMapUsed() const { return (_MultiTexState & EnvBumpMapUsed) != 0; }
00637 
00638 
00639     // update wrap mode for all textures
00640     virtual void updateTexWrapMode(IDriver &drv) = 0;
00641     void touch()        { _MultiTexState |= (uint8) TouchFlag; }
00642     void unTouch()      { _MultiTexState &= ~ (uint8) TouchFlag; }
00643     bool isTouched()    const { return (_MultiTexState & TouchFlag) != 0; }
00644     bool areBasicCapsForcedLocal() const { return (_MultiTexState & BasicCapsForced) != 0; }
00645     void forceBasicCapsLocal(bool force)
00646     {
00647         if (force) _MultiTexState |= BasicCapsForced;
00648         else _MultiTexState &= ~BasicCapsForced;
00649     }
00650     float       _BumpFactor;
00651     static bool _ForceBasicCaps;
00652 };
00653 
00654 
00657 
00661 class CPSRotated3DPlaneParticle
00662 {
00663     public:
00664 
00669         void setPlaneBasisScheme(CPSAttribMaker<CPlaneBasis> *basisMaker);
00670 
00675 
00676         CPSAttribMaker<CPlaneBasis> *getPlaneBasisScheme(void) { return _PlaneBasisScheme; }
00677 
00679         const CPSAttribMaker<CPlaneBasis> *getPlaneBasisScheme(void) const { return _PlaneBasisScheme; }
00680 
00681         void setPlaneBasis(const CPlaneBasis &basis);
00682 
00684         CPlaneBasis getPlaneBasis(void) const { return _PlaneBasis; }
00685 
00687         CPSRotated3DPlaneParticle();
00688 
00690         virtual ~CPSRotated3DPlaneParticle();
00691 
00693         void serialPlaneBasisScheme(NLMISC::IStream &f) throw(NLMISC::EStream);
00694 
00695     protected:
00697 
00699         virtual CPSLocated *getPlaneBasisOwner(void) = 0;
00700 
00701         CPSAttribMaker<CPlaneBasis> *_PlaneBasisScheme;
00702 
00703         CPlaneBasis _PlaneBasis; // constant basis..
00704 
00705         void newPlaneBasisElement(const CPSEmitterInfo &info)
00706         {
00707             if (_PlaneBasisScheme && _PlaneBasisScheme->hasMemory()) _PlaneBasisScheme->newElement(info);
00708         }
00709         void deletePlaneBasisElement(uint32 index)
00710         {
00711             if (_PlaneBasisScheme && _PlaneBasisScheme->hasMemory()) _PlaneBasisScheme->deleteElement(index);
00712         }
00713         void resizePlaneBasis(uint32 size)
00714         {
00715             nlassert(size < (1 << 16));
00716             if (_PlaneBasisScheme && _PlaneBasisScheme->hasMemory()) _PlaneBasisScheme->resize(size, getPlaneBasisOwner()->getSize());
00717         }
00718 };
00719 
00722 
00727 struct CPSHintParticleRotateTheSame
00728 {
00729     virtual ~CPSHintParticleRotateTheSame() {}
00730 
00740     virtual void hintRotateTheSame(uint32 nbConfiguration
00741                             , float minAngularVelocity = NLMISC::Pi
00742                             , float maxAngularVelocity = NLMISC::Pi
00743                           ) = 0;
00744 
00749     virtual void disableHintRotateTheSame(void) = 0;
00750 
00751 
00756     virtual uint32 checkHintRotateTheSame(float &minAngularVelocity, float &maxAngularVelocity) const = 0;
00757 };
00758 
00761 
00763 struct CPSTailParticle
00764 {
00765     virtual ~CPSTailParticle() {}
00766 
00770     virtual void setColorFading(bool onOff = true) = 0;
00771 
00773     virtual bool getColorFading(void) const = 0;
00774 
00775 
00777     virtual void setTailNbSeg(uint32 nbSeg) = 0;
00778 
00779     // get the number of segments in the tail
00780     virtual uint32 getTailNbSeg(void) const = 0;
00781 
00782 
00783 };
00784 
00787 
00789 struct CPSShapeParticle
00790 {
00791     virtual ~CPSShapeParticle() {}
00792 
00794     virtual void setShape(const std::string &shape) = 0;
00795 
00797     virtual std::string getShape(void) const = 0;
00798 };
00799 
00802 
00806 class CPSMaterial
00807 {
00808 public:
00810     CPSMaterial();
00811 
00813     enum TBlendingMode { add, modulate, alphaBlend, alphaTest };
00814 
00816     void serialMaterial(NLMISC::IStream &f) throw(NLMISC::EStream);
00817 
00819     void setBlendingMode(CPSMaterial::TBlendingMode mode);
00820 
00822     CPSMaterial::TBlendingMode getBlendingMode(void) const;
00823 
00824 
00829     void forceModulateConstantColor(bool force, const NLMISC::CRGBA &col = NLMISC::CRGBA::White);
00830 
00837     void forceTexturedMaterialStages(uint numStages);
00838 
00839     // enable / disable z-test (default is enabled)
00840     void enableZTest(bool enabled);
00841     // test if z test is enabled
00842     bool isZTestEnabled() const;
00843 
00844     // set z-bias
00845     void setZBias(float value) { _Mat.setZBias(value); }
00846     float getZBias() const { return _Mat.getZBias(); }
00847 
00848 
00849 
00850 protected:
00851     CMaterial _Mat;
00852 };
00853 
00854 
00855 //==========================================================================
00857 inline void SetupModulatedStage(CMaterial &m, uint stage, CMaterial::TTexSource src1, CMaterial::TTexSource src2)
00858 {
00859     m.texEnvOpRGB(stage, CMaterial::Modulate);
00860     m.texEnvOpAlpha(stage, CMaterial::Modulate);
00861     m.texEnvArg0RGB(stage, src1, CMaterial::SrcColor);
00862     m.texEnvArg1RGB(stage, src2, CMaterial::SrcColor);
00863     m.texEnvArg0Alpha(stage, src1, CMaterial::SrcAlpha);
00864     m.texEnvArg1Alpha(stage, src2, CMaterial::SrcAlpha);
00865 }
00866 
00867 
00868 
00869 
00870 } // NL3D
00871 
00872 
00873 #endif // NL_PS_PARTICLE_BASIC_H
00874 
00875 /* End of ps_particle_basic.h */

Generated on Thu Jan 7 08:26:20 2010 for NeL by  doxygen 1.6.1