00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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
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)
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);
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
00350
00351
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
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
00446 CSmartPtr<ITexture> _Tex;
00447
00448
00449 CSmartPtr<CTextureGrouped> _TexGroup;
00450
00451 CPSAttribMaker<sint32> *_TextureIndexScheme;
00452
00453
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
00510 void enableAlternateTex(bool enabled = true);
00511 bool isAlternateTexEnabled() const { return (_MultiTexState & (uint8) AlternateTextureEnabled) != 0; }
00512
00514
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;
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
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
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 }
00828
00829
00830 #endif // NL_PS_PARTICLE_BASIC_H
00831
00832