00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #include <stdlib.h>
00044 #include <stdio.h>
00045
00046 #include <OSGConfig.h>
00047 #include <OSGAction.h>
00048 #include <OSGDrawAction.h>
00049 #include <OSGRenderAction.h>
00050 #include <OSGMaterial.h>
00051 #include <OSGGeoPropPtrs.h>
00052 #include <OSGCamera.h>
00053
00054 #include "OSGParticles.h"
00055
00056 #include <algorithm>
00057
00058 OSG_USING_NAMESPACE
00059
00060
00061
00062
00063
00071
00072
00073
00074
00075 void Particles::initMethod (void)
00076 {
00077 DrawAction::registerEnterDefault( getClassType(),
00078 osgTypedMethodFunctor2BaseCPtrRef<Action::ResultE,
00079 ParticlesPtr ,
00080 CNodePtr ,
00081 Action *>
00082 (&MaterialDrawable::drawActionHandler));
00083
00084 RenderAction::registerEnterDefault( getClassType(),
00085 osgTypedMethodFunctor2BaseCPtrRef<Action::ResultE,
00086 ParticlesPtr ,
00087 CNodePtr ,
00088 Action *>
00089 (&MaterialDrawable::renderActionHandler));
00090 }
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100 Particles::Particles(void) :
00101 Inherited()
00102 {
00103 }
00104
00105 Particles::Particles(const Particles &source) :
00106 Inherited(source)
00107 {
00108 }
00109
00110 Particles::~Particles(void)
00111 {
00112 ParticlesPtr thisP(*this);
00113
00114 if(_sfPositions.getValue() != NullFC)
00115 {
00116 beginEditCP(_sfPositions.getValue(), Attachment::ParentsFieldMask);
00117 {
00118 _sfPositions.getValue()->subParent(thisP);
00119 }
00120 endEditCP(_sfPositions.getValue(), Attachment::ParentsFieldMask);
00121
00122 subRefCP(_sfPositions.getValue());
00123 }
00124
00125 if(_sfSecPositions.getValue() != NullFC)
00126 {
00127 beginEditCP(_sfSecPositions.getValue(), Attachment::ParentsFieldMask);
00128 {
00129 _sfSecPositions.getValue()->subParent(thisP);
00130 }
00131 endEditCP(_sfSecPositions.getValue(), Attachment::ParentsFieldMask);
00132
00133 subRefCP(_sfSecPositions.getValue());
00134 }
00135
00136 if(_sfColors.getValue() != NullFC)
00137 {
00138 beginEditCP(_sfColors.getValue(), Attachment::ParentsFieldMask);
00139 {
00140 _sfColors.getValue()->subParent(thisP);
00141 }
00142 endEditCP(_sfColors.getValue(), Attachment::ParentsFieldMask);
00143
00144 subRefCP(_sfColors.getValue());
00145 }
00146
00147 if(_sfNormals.getValue() != NullFC)
00148 {
00149 beginEditCP(_sfNormals.getValue(), Attachment::ParentsFieldMask);
00150 {
00151 _sfNormals.getValue()->subParent(thisP);
00152 }
00153 endEditCP(_sfNormals.getValue(), Attachment::ParentsFieldMask);
00154
00155 subRefCP(_sfNormals.getValue());
00156 }
00157
00158 subRefCP(_sfMaterial.getValue());
00159 }
00160
00161
00162
00163 void Particles::changed(BitVector whichField, UInt32 origin)
00164 {
00165 if(whichField & PositionsFieldMask)
00166 {
00167 for(UInt32 i = 0; i < _parents.size(); i++)
00168 {
00169 _parents[i]->invalidateVolume();
00170 }
00171 getBsp().destroy();
00172
00173 if(origin & ChangedOrigin::Abstract)
00174 {
00175 if(origin & ChangedOrigin::AbstrCheckValid)
00176 {
00177 ParticlesPtr thisP(*this);
00178
00179 if(_sfPositions.getValue() != NullFC &&
00180 _sfPositions.getValue()->findParent(thisP) == -1 )
00181 {
00182 GeoPositionsPtr pPos = _sfPositions.getValue();
00183
00184 _sfPositions.setValue(NullFC);
00185
00186 setPositions(pPos);
00187 }
00188 }
00189 else if(origin & ChangedOrigin::AbstrIncRefCount)
00190 {
00191 addRefCP(_sfPositions.getValue());
00192 }
00193 else
00194 {
00195 GeoPositionsPtr pPos = _sfPositions.getValue();
00196
00197 _sfPositions.setValue(NullFC);
00198
00199 setPositions(pPos);
00200 }
00201 }
00202 }
00203
00204 if(whichField & SecPositionsFieldMask)
00205 {
00206 if(origin & ChangedOrigin::Abstract)
00207 {
00208 if(origin & ChangedOrigin::AbstrCheckValid)
00209 {
00210 ParticlesPtr thisP(*this);
00211
00212 if(_sfSecPositions.getValue() != NullFC &&
00213 _sfSecPositions.getValue()->findParent(thisP) == -1 )
00214 {
00215 GeoPositionsPtr pPos = _sfSecPositions.getValue();
00216
00217 _sfSecPositions.setValue(NullFC);
00218
00219 setSecPositions(pPos);
00220 }
00221 }
00222 else if(origin & ChangedOrigin::AbstrIncRefCount)
00223 {
00224 addRefCP(_sfSecPositions.getValue());
00225 }
00226 else
00227 {
00228 GeoPositionsPtr pPos = _sfSecPositions.getValue();
00229
00230 _sfSecPositions.setValue(NullFC);
00231
00232 setSecPositions(pPos);
00233 }
00234 }
00235 }
00236
00237 if(whichField & ColorsFieldMask)
00238 {
00239 if(origin & ChangedOrigin::Abstract)
00240 {
00241 if(origin & ChangedOrigin::AbstrCheckValid)
00242 {
00243 ParticlesPtr thisP(*this);
00244
00245 if(_sfColors.getValue() != NullFC &&
00246 _sfColors.getValue()->findParent(thisP) == -1 )
00247 {
00248 GeoColorsPtr pCol = _sfColors.getValue();
00249
00250 _sfColors.setValue(NullFC);
00251
00252 setColors(pCol);
00253 }
00254 }
00255 else if(origin & ChangedOrigin::AbstrIncRefCount)
00256 {
00257 addRefCP(_sfColors.getValue());
00258 }
00259 else
00260 {
00261 GeoColorsPtr pCol = _sfColors.getValue();
00262
00263 _sfColors.setValue(NullFC);
00264
00265 setColors(pCol);
00266 }
00267 }
00268 }
00269
00270 if(whichField & NormalsFieldMask)
00271 {
00272 if(origin & ChangedOrigin::Abstract)
00273 {
00274 if(origin & ChangedOrigin::AbstrCheckValid)
00275 {
00276 ParticlesPtr thisP(*this);
00277
00278 if(_sfNormals.getValue() != NullFC &&
00279 _sfNormals.getValue()->findParent(thisP) == -1 )
00280 {
00281 GeoNormalsPtr pNorm = _sfNormals.getValue();
00282
00283 _sfNormals.setValue(NullFC);
00284
00285 setNormals(pNorm);
00286 }
00287 }
00288 else if(origin & ChangedOrigin::AbstrIncRefCount)
00289 {
00290 addRefCP(_sfNormals.getValue());
00291 }
00292 else
00293 {
00294 GeoNormalsPtr pNorm = _sfNormals.getValue();
00295
00296 _sfNormals.setValue(NullFC);
00297
00298 setNormals(pNorm);
00299 }
00300 }
00301 }
00302
00303 if(whichField & MaterialFieldMask)
00304 {
00305 if(origin & ChangedOrigin::Abstract)
00306 {
00307 if(origin & ChangedOrigin::AbstrIncRefCount)
00308 {
00309 addRefCP(_sfMaterial.getValue());
00310 }
00311 else
00312 {
00313 MaterialPtr pMat = _sfMaterial.getValue();
00314
00315 _sfMaterial.setValue(NullFC);
00316
00317 setMaterial(pMat);
00318 }
00319 }
00320 }
00321
00322 Inherited::changed(whichField, origin);
00323 }
00324
00325
00326
00327 void Particles::dump( UInt32 ,
00328 const BitVector ) const
00329 {
00330 SLOG << "Dump Particles NI" << std::endl;
00331 }
00332
00333
00334 void Particles::adjustVolume( Volume & volume )
00335 {
00336 GeoPositionsPtr pos = getPositions();
00337
00338 if ( pos == NullFC )
00339 return;
00340
00341 volume.setValid();
00342 volume.setEmpty();
00343
00344 MFVec3f *sizes = getMFSizes();
00345
00346 if(sizes->size() == pos->size())
00347 {
00348 Vec3f p;
00349 Real32 s;
00350
00351 for(UInt32 i = 0; i < pos->size(); i++)
00352 {
00353 pos->getValue(p, i);
00354
00355 s=(*sizes)[i][0]*Sqrt2;
00356
00357 p[0]+=s/2;
00358 p[1]+=s/2;
00359 p[2]+=s/2;
00360 volume.extendBy(p);
00361 p[0]-=s;
00362 volume.extendBy(p);
00363 p[1]-=s;
00364 volume.extendBy(p);
00365 p[0]+=s;
00366 volume.extendBy(p);
00367 p[2]-=s;
00368 volume.extendBy(p);
00369 p[0]-=s;
00370 volume.extendBy(p);
00371 p[1]+=s;
00372 volume.extendBy(p);
00373 p[0]+=s;
00374 volume.extendBy(p);
00375 }
00376
00377 }
00378 else if(sizes->size() == 1)
00379 {
00380 Vec3f p;
00381 Real32 s,s2;
00382
00383 s=(*sizes)[0][0]*Sqrt2;
00384 s2=s/2;
00385
00386 for(UInt32 i = 0; i < pos->size(); i++)
00387 {
00388 pos->getValue(p, i);
00389
00390 p[0]+=s2;
00391 p[1]+=s2;
00392 p[2]+=s2;
00393 volume.extendBy(p);
00394 p[0]-=s;
00395 volume.extendBy(p);
00396 p[1]-=s;
00397 volume.extendBy(p);
00398 p[0]+=s;
00399 volume.extendBy(p);
00400 p[2]-=s;
00401 volume.extendBy(p);
00402 p[0]-=s;
00403 volume.extendBy(p);
00404 p[1]+=s;
00405 volume.extendBy(p);
00406 p[0]+=s;
00407 volume.extendBy(p);
00408 }
00409
00410 }
00411 else
00412 {
00413 Vec3f p;
00414
00415 for(UInt32 i = 0; i < pos->getSize(); i++)
00416 {
00417 pos->getValue(p, i);
00418
00419 volume.extendBy(p);
00420 }
00421 }
00422 }
00423
00424 #if !defined(OSG_DO_DOC) || OSG_DOC_LEVEL > 1 // remove from user docu
00425
00426
00427
00441 class ParticleTraits
00442 {
00443 };
00444
00447 struct ColTraitBase : public ParticleTraits
00448 {
00449 typedef void (OSG_APIENTRY *pumpFunc)( GLubyte * data );
00450 static const int formatBase;
00451 enum { numFormats = GL_DOUBLE - GL_BYTE + 1 };
00452
00453 static char *formatNames[];
00454
00455 static pumpFunc ColorFuncs[numFormats][4];
00456 };
00457
00460 const int ColTraitBase::formatBase = GL_BYTE;
00461
00464 char *ColTraitBase::formatNames[] =
00465 { "GL_BYTE", "GL_UNSIGNED_BYTE", "GL_SHORT", "GL_UNSIGNED_SHORT",
00466 "GL_INT", "GL_UNSIGNED_INT", "GL_FLOAT", "GL_2_BYTES",
00467 "GL_3_BYTES", "GL_4_BYTES", "GL_DOUBLE"
00468 };
00469
00472 ColTraitBase::pumpFunc
00473 ColTraitBase::ColorFuncs[ColTraitBase::numFormats][4] = {
00474 { NULL, NULL,
00475 (pumpFunc)glColor3bv, (pumpFunc)glColor4bv },
00476 { NULL, NULL,
00477 (pumpFunc)glColor3ubv,(pumpFunc)glColor4ubv },
00478 { NULL, NULL,
00479 (pumpFunc)glColor3sv, (pumpFunc)glColor4sv },
00480 { NULL, NULL,
00481 (pumpFunc)glColor3usv,(pumpFunc)glColor4usv },
00482 { NULL, NULL,
00483 (pumpFunc)glColor3iv, (pumpFunc)glColor4iv },
00484 { NULL, NULL,
00485 (pumpFunc)glColor3uiv,(pumpFunc)glColor4uiv },
00486 { NULL, NULL,
00487 (pumpFunc)glColor3fv, (pumpFunc)glColor4fv },
00488 { NULL, NULL, NULL, NULL },
00489 { NULL, NULL, NULL, NULL },
00490 { NULL, NULL, NULL, NULL },
00491 { NULL, NULL,
00492 (pumpFunc)glColor3dv, (pumpFunc)glColor4dv },
00493 };
00494
00495 struct ColTraitNone : public ColTraitBase
00496 {
00497 typedef UInt8 dataType;
00498
00499 static inline void init(Particles *, DrawActionBase *, dataType &)
00500 {
00501 }
00502
00503 static inline bool particle(dataType &, UInt32)
00504 {
00505 return false;
00506 }
00507
00508 static inline void vertex(dataType &, UInt32, UInt32)
00509 {
00510 }
00511 };
00512
00513 struct ColTraitSingle : public ColTraitBase
00514 {
00515 typedef UInt8 dataType;
00516
00517 static inline void init(Particles *part, DrawActionBase *, dataType &)
00518 {
00519 GeoColorsPtr col = part->getColors();
00520
00521 if(col != NullFC)
00522 {
00523 pumpFunc col_func;
00524
00525 col_func = ColorFuncs[ col->getFormat() - formatBase ]
00526 [ col->getDimension() - 1 ];
00527
00528 if(col_func == NULL)
00529 {
00530 SWARNING << "Particles " << part << "have illegal "
00531 << "colors: " << col->getDimension()
00532 << "D " << formatNames[col->getFormat() - formatBase]
00533 << "!" << std::endl;
00534 return;
00535 }
00536 else
00537 {
00538 col_func((GLubyte*) col->getData());
00539 }
00540 }
00541 }
00542
00543 static inline bool particle(dataType &, UInt32)
00544 {
00545 return false;
00546 }
00547
00548 static inline void vertex(dataType &, UInt32, UInt32)
00549 {
00550 }
00551 };
00552
00553 struct ColTraitParticle : public ColTraitBase
00554 {
00555 typedef struct
00556 {
00557 UInt8 *data;
00558 UInt32 stride;
00559 pumpFunc func;
00560 }
00561 dataType;
00562
00563 static inline void init(Particles *part, DrawActionBase *, dataType &data)
00564 {
00565 GeoColorsPtr col = part->getColors();
00566
00567 data.data = col->getData();
00568 if((data.stride = col->getStride()) == 0)
00569 data.stride = col->getFormatSize() * col->getDimension();
00570
00571 data.func = ColorFuncs[ col->getFormat() - formatBase ]
00572 [ col->getDimension() - 1 ];
00573
00574 if(data.func == NULL)
00575 {
00576 SWARNING << "Particles " << part << "have illegal "
00577 << "colors: " << col->getDimension()
00578 << "D " << formatNames[ col->getFormat() - formatBase ]
00579 << "!" << std::endl;
00580 return;
00581 }
00582 }
00583
00584 static inline bool particle(dataType &data, UInt32 particle)
00585 {
00586 data.func((GLubyte*)(data.data + particle * data.stride));
00587 return false;
00588 }
00589
00590 static inline void vertex(dataType &, UInt32, UInt32)
00591 {
00592 }
00593 };
00594
00595 struct ColTraitGeneric : public ColTraitBase
00596 {
00597 typedef struct
00598 {
00599 UInt8 *data;
00600 UInt32 stride;
00601 pumpFunc func;
00602 bool perParticle;
00603 }
00604 dataType;
00605
00606 static inline void init(Particles *part, DrawActionBase *, dataType &data)
00607 {
00608 GeoColorsPtr col = part->getColors();
00609
00610 data.perParticle = false;
00611
00612 if(col != NullFC)
00613 {
00614 data.data = col->getData();
00615 if((data.stride = col->getStride()) == 0)
00616 data.stride = col->getFormatSize() * col->getDimension();
00617
00618 data.func = ColorFuncs[ col->getFormat() - formatBase ]
00619 [ col->getDimension() - 1 ];
00620
00621 if(data.func == NULL)
00622 {
00623 SWARNING << "Particles " << part << "have illegal "
00624 << "colors: " << col->getDimension()
00625 << "D " << formatNames[ col->getFormat() - formatBase ]
00626 << "!" << std::endl;
00627 return;
00628 }
00629
00630 if(col->getSize() == 1)
00631 {
00632 data.func((GLubyte*) col->getData());
00633 }
00634 else if(col->getSize() == part->getPositions()->getSize())
00635 {
00636 data.perParticle = true;
00637 }
00638 }
00639 }
00640
00641 static inline bool particle(dataType &data, UInt32 particle)
00642 {
00643 if(data.perParticle == true)
00644 data.func((GLubyte*)(data.data + particle * data.stride));
00645 return false;
00646 }
00647
00648 static inline void vertex(dataType &, UInt32, UInt32)
00649 {
00650 }
00651 };
00652
00655 struct PosTraitGeneric : public ParticleTraits
00656 {
00657 typedef struct
00658 {
00659 GeoPositionsPtr pos;
00660 Pnt3f p;
00661 }
00662 dataType;
00663
00664 static inline void init(Particles *, DrawActionBase *, dataType &data,
00665 GeoPositionsPtr &pos)
00666 {
00667 data.pos = pos;
00668 }
00669
00670 static inline bool particle(dataType &data, UInt32 particle)
00671 {
00672 data.pos->getValue(data.p, particle);
00673
00674 return false;
00675 }
00676
00677 static inline Pnt3f &position(dataType &data)
00678 {
00679 return data.p;
00680 }
00681
00682 static inline void vertex(dataType &data, UInt32 , Vec4f &dir,
00683 Real32 s)
00684 {
00685 glVertex3f( data.p[0] + dir[0] * s,
00686 data.p[1] + dir[1] * s,
00687 data.p[2] + dir[2] * s);
00688 }
00689
00690 static inline void vertex(dataType &data)
00691 {
00692 glVertex3fv( (GLfloat*) data.p.getValues() );
00693 }
00694 };
00695
00696 struct PosTrait3f : public ParticleTraits
00697 {
00698 typedef struct
00699 {
00700 MFPnt3f *pos;
00701 Pnt3f *p;
00702 }
00703 dataType;
00704
00705 static inline void init(Particles *, DrawActionBase *, dataType &data,
00706 GeoPositionsPtr &pos)
00707 {
00708 GeoPositions3fPtr pos3f = GeoPositions3fPtr::dcast(pos);
00709
00710 data.pos = pos3f->getFieldPtr();
00711 }
00712
00713 static inline bool particle(dataType &data, UInt32 particle)
00714 {
00715 data.p = & (*(data.pos))[particle];
00716 return false;
00717 }
00718
00719 static inline Pnt3f &position(dataType &data)
00720 {
00721 return *data.p;
00722 }
00723
00724 static inline void vertex(dataType &data, UInt32 , Vec4f &dir, Real32 s)
00725 {
00726 glVertex3f( (*data.p)[0] + dir[0] * s,
00727 (*data.p)[1] + dir[1] * s,
00728 (*data.p)[2] + dir[2] * s);
00729 }
00730
00731 static inline void vertex(dataType &data)
00732 {
00733 glVertex3fv( (GLfloat*) (*data.p).getValues() );
00734 }
00735 };
00736
00739 struct SizeTraitGeneric : public ParticleTraits
00740 {
00741 typedef struct
00742 {
00743 MFVec3f *sizes;
00744 Vec3f s;
00745 bool perParticle;
00746 }
00747 dataType;
00748
00749 static inline void init(Particles *part, DrawActionBase *, dataType &data)
00750 {
00751 data.sizes = part->getMFSizes();
00752
00753 if(data.sizes != NULL)
00754 {
00755 if(data.sizes->size() == 1)
00756 {
00757 data.s = (*(data.sizes))[0];
00758 data.perParticle = false;
00759 }
00760 else if(data.sizes->size() == part->getPositions()->size())
00761 {
00762 data.perParticle = true;
00763 }
00764 else
00765 {
00766 data.s.setValues(1,1,1);
00767 data.perParticle = false;
00768 }
00769 }
00770 else
00771 {
00772 data.s.setValues(1,1,1);
00773 data.perParticle = false;
00774 }
00775 }
00776
00777 static inline bool particle(dataType &, UInt32)
00778 {
00779 return false;
00780 }
00781
00782 static inline Vec3f &size(dataType &data, UInt32 particle)
00783 {
00784 if(data.perParticle)
00785 return (*(data.sizes))[particle];
00786 return data.s;
00787 }
00788 };
00789
00790 struct SizeTraitSingle : public ParticleTraits
00791 {
00792 typedef struct
00793 {
00794 Vec3f s;
00795 }
00796 dataType;
00797
00798 static inline void init(Particles *part, DrawActionBase *, dataType &data)
00799 {
00800 data.s = part->getSizes()[0];
00801 }
00802
00803 static inline bool particle(dataType &, UInt32)
00804 {
00805 return false;
00806 }
00807
00808 static inline Vec3f &size(dataType &data, UInt32)
00809 {
00810 return data.s;
00811 }
00812 };
00813
00814 struct SizeTraitParticle : public ParticleTraits
00815 {
00816 typedef struct
00817 {
00818 MFVec3f *sizes;
00819 Vec3f s;
00820 }
00821 dataType;
00822
00823 static inline void init(Particles *part, DrawActionBase *, dataType &data)
00824 {
00825 data.sizes = part->getMFSizes();
00826 }
00827
00828 static inline bool particle(dataType &, UInt32)
00829 {
00830 return false;
00831 }
00832
00833 static inline Vec3f &size(dataType &data, UInt32 particle)
00834 {
00835 return (*(data.sizes))[particle];
00836 }
00837 };
00838
00839 struct SizeTraitNone : public ParticleTraits
00840 {
00841 typedef UInt8 dataType;
00842
00843 static inline void init(Particles *, DrawActionBase *, dataType &)
00844 {
00845 }
00846
00847 static inline bool particle(dataType &, UInt32)
00848 {
00849 return false;
00850 }
00851
00852 static inline Vec3f &size(dataType &, UInt32 )
00853 {
00854 static Vec3f s(1,1,1);
00855 return s;
00856 }
00857 };
00858
00861 struct TexTraitGeneric : public ParticleTraits
00862 {
00863 typedef struct
00864 {
00865 MFReal32 *texzs;
00866 Real32 z;
00867 bool perParticle;
00868 }
00869 dataType;
00870
00871 static inline void init(Particles *part, DrawActionBase *, dataType &data)
00872 {
00873 data.texzs = part->getMFTextureZs();
00874
00875 data.perParticle = false;
00876
00877 if(data.texzs != NULL)
00878 {
00879 if(data.texzs->size() == 1)
00880 {
00881 data.z = (*(data.texzs))[0];
00882 }
00883 else if(data.texzs->size() == part->getPositions()->size())
00884 {
00885 data.perParticle = true;
00886 }
00887 else
00888 {
00889 data.z = 0;
00890 }
00891 }
00892 else
00893 {
00894 data.z = 0;
00895 }
00896 }
00897
00898 static inline bool particle(dataType &data, UInt32 particle)
00899 {
00900 if(data.perParticle)
00901 {
00902 data.z = (*(data.texzs))[particle];
00903 }
00904 return false;
00905 }
00906
00907 static inline void vertex(dataType &data)
00908 {
00909 glTexCoord1f(data.z);
00910 }
00911
00912 static inline void vertex(dataType &data, UInt32 , Real32 u,
00913 Real32 v)
00914 {
00915 glTexCoord3f(u, v, data.z);
00916 }
00917 };
00918
00919 struct TexTraitParticle : public ParticleTraits
00920 {
00921 typedef struct
00922 {
00923 MFReal32 *texzs;
00924 Real32 z;
00925 }
00926 dataType;
00927
00928 static inline void init(Particles *part, DrawActionBase *, dataType &data)
00929 {
00930 data.texzs = part->getMFTextureZs();
00931 }
00932
00933 static inline bool particle(dataType &data, UInt32 particle)
00934 {
00935 data.z = (*(data.texzs))[particle];
00936 return false;
00937 }
00938
00939 static inline void vertex(dataType &data)
00940 {
00941 glTexCoord1f(data.z);
00942 }
00943
00944 static inline void vertex(dataType &data, UInt32 , Real32 u,
00945 Real32 v)
00946 {
00947 glTexCoord3f(u, v, data.z);
00948 }
00949 };
00950
00951 struct TexTraitSingle : public ParticleTraits
00952 {
00953 typedef struct
00954 {
00955 Real32 z;
00956 }
00957 dataType;
00958
00959 static inline void init(Particles *part, DrawActionBase *, dataType &data)
00960 {
00961 data.z = (*(part->getMFTextureZs()))[0];
00962 }
00963
00964 static inline bool particle(dataType &, UInt32)
00965 {
00966 return false;
00967 }
00968
00969 static inline void vertex(dataType &data)
00970 {
00971 glTexCoord1f(data.z);
00972 }
00973
00974 static inline void vertex(dataType &data, UInt32 , Real32 u,
00975 Real32 v)
00976 {
00977 glTexCoord3f(u, v, data.z);
00978 }
00979 };
00980
00981 struct TexTraitNone : public ParticleTraits
00982 {
00983 typedef UInt8 dataType;
00984
00985 static inline void init(Particles *, DrawActionBase *, dataType &)
00986 {
00987 }
00988
00989 static inline bool particle(dataType &, UInt32)
00990 {
00991 return false;
00992 }
00993
00994 static inline void vertex(dataType &, UInt32 )
00995 {
00996 glTexCoord1f(0);
00997 }
00998
00999 static inline void vertex(dataType &, UInt32, Real32 u, Real32 v)
01000 {
01001 glTexCoord2f(u, v);
01002 }
01003 };
01004
01005
01008 struct NormalTraitGeneric : public ParticleTraits
01009 {
01010 typedef struct
01011 {
01012 GeoNormalsPtr norms;
01013 Vec3f n;
01014 bool perParticle;
01015 }
01016 dataType;
01017
01018 static inline void init(Particles *part, DrawActionBase *, dataType &data)
01019 {
01020 data.norms = part->getNormals();
01021
01022 data.perParticle = false;
01023
01024 if(data.norms != NullFC)
01025 {
01026 if(data.norms->size() == 1)
01027 {
01028 data.n = data.norms->getValue(0);
01029 }
01030 else if(data.norms->getSize() == part->getPositions()->getSize())
01031 {
01032 data.perParticle = true;
01033 }
01034 else
01035 {
01036 data.n.setValues(0,1,0);
01037 }
01038 }
01039 else
01040 {
01041 data.n.setValues(0,1,0);
01042 }
01043 }
01044
01045 static inline bool particle(dataType &data, UInt32 particle)
01046 {
01047 if(data.perParticle)
01048 data.norms->getValue(data.n, particle);
01049
01050 return false;
01051 }
01052
01053 static inline Vec3f &normal(dataType &data)
01054 {
01055 return data.n;
01056 }
01057
01058 static inline void normal(dataType &data, UInt32 )
01059 {
01060 glNormal3fv( (GLfloat*) data.n.getValues() );
01061 }
01062 };
01063
01064 struct NormalTraitGeneric3f : public ParticleTraits
01065 {
01066 typedef struct
01067 {
01068 MFVec3f *norms;
01069 Vec3f *n;
01070 bool perParticle;
01071 Vec3f const_n;