00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
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)
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
00103 void enableGlobalColorLighting(bool enabled) { _UsesGlobalColorLighting = enabled; }
00104
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
00141 virtual void setZBias(float value) = 0;
00142 virtual float getZBias() const = 0;
00143
00144 protected:
00145
00150
00151
00152
00153
00154
00155
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);
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
00373 static bool _InitializedRotTab;
00374
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
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
00473 CSmartPtr<ITexture> _Tex;
00474
00475
00476 CSmartPtr<CTextureGrouped> _TexGroup;
00477
00478 CPSAttribMaker<sint32> *_TextureIndexScheme;
00479
00480
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
00538 void enableAlternateTex(bool enabled = true);
00539 bool isAlternateTexEnabled() const { return (_MultiTexState & (uint8) AlternateTextureEnabled) != 0; }
00540
00542
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
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;
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
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
00840 void enableZTest(bool enabled);
00841
00842 bool isZTestEnabled() const;
00843
00844
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 }
00871
00872
00873 #endif // NL_PS_PARTICLE_BASIC_H
00874
00875