ps_attrib_maker_helper.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_ATTRIB_MAKER_HELPER_H
00025 #define NL_PS_ATTRIB_MAKER_HELPER_H
00026 
00027 #include "nel/3d/ps_attrib_maker.h"
00028 
00029 #include "nel/misc/fast_floor.h" // inline assembly for fast float<->int conversions
00030 #include "nel/3d/ps_attrib_maker_iterators.h" // some iterators we use
00031 
00032 namespace NL3D
00033 {
00034 
00035 
00036 
00037 
00038 
00039 
00049 template <typename T, class F> class CPSAttribMakerT : public CPSAttribMaker<T>
00050 {
00051     public:
00053         F _F;
00054 
00056         virtual T get(CPSLocated *loc, uint32 index);
00057         virtual T get(const CPSEmitterInfo &info);
00058 
00059         virtual T get(float input)
00060         {
00061             NLMISC::OptFastFloorBegin();
00062             nlassert(input >= 0.f && input <= 1.f);
00063             T tmp=  _F(input);
00064             NLMISC::OptFastFloorEnd();
00065             return tmp;
00066         }
00067 
00071         /*  virtual void *make(CPSLocated *loc,
00072                              uint32 startIndex,
00073                              void *tab, uint32 stride,
00074                              uint32 numAttrib,
00075                              bool allowNoCopy = false,
00076                              uint32 srcStep = (1 << 16)
00077                                              ) const;*/
00078 
00082          /* virtual void make4(CPSLocated *loc,
00083                              uint32 startIndex,
00084                              void *tab,
00085                              uint32 stride,
00086                              uint32 numAttrib,
00087                              uint32 srcStep = (1 << 16)
00088                             ) const;*/
00089 
00093         /* virtual void makeN(CPSLocated *loc,
00094                             uint32 startIndex,
00095                             void *tab,
00096                             uint32 stride,
00097                             uint32 numAttrib,
00098                             uint32 nbReplicate,
00099                             uint32 srcStep = (1 << 16)
00100                         ) const;*/
00101 
00102 
00104         virtual void serial(NLMISC::IStream &f) throw(NLMISC::EStream)
00105         {
00106             sint ver = f.serialVersion(2);
00107             CPSAttribMaker<T>::serial(f);
00108             f.serial(_F);
00109             switch (ver)
00110             {
00111                 case 1:
00112                 {
00113                     CPSInputType it;
00114                     f.serialEnum(it.InputType);
00115                     _InputType = it;
00116                 }
00117                 break;
00118                 case 2:
00119                     f.serial(_InputType);
00120                 break;
00121             }
00122             f.serial(_Clamp);
00123         }
00124 
00128         CPSAttribMakerT(float nbCycles) :  CPSAttribMaker<T>(nbCycles), _Clamp(false)
00129         {}
00130 
00132           virtual ~CPSAttribMakerT() {}
00133 
00134 
00138         virtual bool hasCustomInput(void) { return true; }
00139 
00140 
00143         virtual void setInput(const CPSInputType &input) { _InputType = input; }
00144 
00145 
00149         virtual CPSInputType getInput(void) const { return _InputType; }
00150 
00151 
00154         bool isClampingSupported(void) const { return true; }
00155 
00156 
00160         virtual void setClamping(bool enable = true) { _Clamp = enable; };
00161 
00162 
00166         virtual bool getClamping(void) const  { return _Clamp; };
00167 
00168 
00170           typedef T value_type;
00171 
00173           typedef F functor_type;
00174 
00175     private:
00176 
00177         // type of the input
00178         CPSInputType _InputType;
00179 
00180         // clamping on/ off
00181         bool _Clamp;
00182 
00183 
00184 
00190          template <typename It> void makeByIterator(It it,
00191                                                      void *tab,
00192                                                      uint32 stride,
00193                                                      uint32 numAttrib,
00194                                                      bool canOverlapOne,
00195                                                      bool forceClampEntry
00196                                                      ) const
00197          {
00198             uint8 *pt = (uint8 *) tab;
00199 
00200 
00201             if (this->_NbCycles > 1 || canOverlapOne || forceClampEntry)
00202             {
00203                 // the value could cycle, so we need to clamp it to 0.0f 1.0f
00204 
00205                 if (!_Clamp && !forceClampEntry)
00206                 {
00207                     if (this->_NbCycles == 1)
00208                     {
00209                         while (numAttrib --)
00210                         {
00211                             *(T *)pt = _F(NLMISC::OptFastFractionnalPart(it.get()));
00212                             pt += stride;
00213                             it.advance();
00214                         }
00215                     }
00216                     else
00217                     {
00218                         while (numAttrib --)
00219                         {
00220                             const float time =  this->_NbCycles * (it.get());
00221                             *(T *)pt = _F(NLMISC::OptFastFractionnalPart(time));
00222                             pt += stride;
00223                             it.advance();
00224                         }
00225                     }
00226                 }
00227                 else
00228                 {
00229                     // clamping is on
00230                     float value;
00231                     if (this->_NbCycles == 1)
00232                     {
00233                         while (numAttrib --)
00234                         {
00235                             value = it.get();
00236                             if (value > MaxInputValue)
00237                             {
00238                                 value = MaxInputValue;
00239                             }
00240                             *(T *)pt = _F(value);
00241                             pt += stride;
00242                             it.advance();
00243                         }
00244                     }
00245                     else
00246                     {
00247                         while (numAttrib --)
00248                         {
00249                             float value =  this->_NbCycles * (it.get());
00250                             if (value > MaxInputValue)
00251                             {
00252                                 value = MaxInputValue;
00253                             }
00254                             *(T *)pt = _F(value);
00255                             pt += stride;
00256                             it.advance();
00257                         }
00258                     }
00259                 }
00260             }
00261             else
00262             {
00263                 // the fastest case : it match the particle's life perfectly
00264 
00265                 if (this->_NbCycles == 1)
00266                 {
00267                     while (numAttrib --)
00268                     {
00269                         *(T *)pt = _F(it.get());
00270                         pt += stride;
00271                         it.advance();
00272                     }
00273                 }
00274                 else
00275                 {
00276                     // the particle won't cover the whole pattern during his life
00277                     while (numAttrib --)
00278                     {
00279                         *(T *)pt = _F(this->_NbCycles  * (it.get()));
00280                         pt += stride;
00281                         it.advance();
00282                     }
00283                 }
00284             }
00285         }
00286 
00291          template <typename It> void make4ByIterator(It it,
00292                                                      void *tab,
00293                                                      uint32 stride,
00294                                                      uint32 numAttrib,
00295                                                      bool canOverlapOne) const
00296          {
00297 
00298 
00299             uint8 *pt = (uint8 *) tab;
00300 
00301 
00302             // first precompute the various strides (stride * 2, 3 and 4)
00303             // const uint32 stride2 = stride << 1, stride3 = stride + stride2, stride4 = stride2 << 1;
00304 
00305             const uint32 stride2 = stride << 1;
00306 
00307             if (this->_NbCycles > 1 || canOverlapOne)
00308             {
00309 
00310                 if (!_Clamp)
00311                 {
00312                     if (this->_NbCycles == 1)
00313                     {
00314                         while (numAttrib --)
00315                         {
00316                             // fill 4 attrib with the same value at once
00317                             //*(T *)pt = *(T *)(pt + stride) = *(T *)(pt + stride2)  = *(T *)(pt + stride3) = _F(OptFastFractionnalPart(it.get()));
00318                             *(T *) pt = _F(NLMISC::OptFastFractionnalPart(it.get()));
00319                             *(T *) (pt + stride) = *(T *) pt;
00320                             pt += stride;
00321                             *(T *) (pt + stride) = *(T *) pt;
00322                             pt += stride;
00323                             *(T *) (pt + stride) = *(T *) pt;
00324                             pt += stride2;
00325                             it.advance();
00326                         }
00327                     }
00328                     else
00329                     {
00330                         while (numAttrib --)
00331                         {
00332                             const float time =  this->_NbCycles * (it.get());
00333                             // fill 4 attrib with the same value at once
00334                             //*(T *)pt = *(T *)(pt + stride) = *(T *)(pt + stride2)  = *(T *)(pt + stride3) = _F(OptFastFractionnalPart(time));
00335                             *(T *) pt = _F(NLMISC::OptFastFractionnalPart(time));
00336                             *(T *) (pt + stride) = *(T *) pt;
00337                             pt += stride;
00338                             *(T *) (pt + stride) = *(T *) pt;
00339                             pt += stride;
00340                             *(T *) (pt + stride) = *(T *) pt;
00341                             pt += stride2;
00342 
00343                             it.advance();
00344                         }
00345                     }
00346                 }
00347                 else
00348                 {
00349                     float value;
00350 
00351                     if (this->_NbCycles == 1)
00352                     {
00353                         while (numAttrib --)
00354                         {
00355                             value = it.get();
00356                             if (value > MaxInputValue)
00357                             {
00358                                 value = MaxInputValue;
00359                             }
00360                             // fill 4 attrib with the same value at once
00361                             //*(T *)pt = *(T *)(pt + stride) = *(T *)(pt + stride2)  = *(T *)(pt + stride3) = _F(value);
00362                             *(T *) pt = _F(value);
00363                             *(T *) (pt + stride) = *(T *) pt;
00364                             pt += stride;
00365                             *(T *) (pt + stride) = *(T *) pt;
00366                             pt += stride;
00367                             *(T *) (pt + stride) = *(T *) pt;
00368                             pt += stride2;
00369 
00370                             it.advance();
00371                         }
00372                     }
00373                     else
00374                     {
00375                         while (numAttrib --)
00376                         {
00377                             value =   this->_NbCycles * (it.get());
00378                             if (value > MaxInputValue)
00379                             {
00380                                 value = MaxInputValue;
00381                             }
00382                             // fill 4 attrib with the same value at once
00383                             //*(T *)pt = *(T *)(pt + stride) = *(T *)(pt + stride2)  = *(T *)(pt + stride3) = _F(value);
00384                             *(T *) pt = _F(value);
00385                             *(T *) (pt + stride) = *(T *) pt;
00386                             pt += stride;
00387                             *(T *) (pt + stride) = *(T *) pt;
00388                             pt += stride;
00389                             *(T *) (pt + stride) = *(T *) pt;
00390                             pt += stride2;
00391                             //pt += stride4; // advance of 4
00392                             it.advance();
00393                         }
00394                     }
00395                 }
00396             }
00397             else
00398             {
00399                 // the fastest case : it match the particle's life perfectly
00400 
00401                 if (this->_NbCycles == 1)
00402                 {
00403                     while (numAttrib --)
00404                     {
00405                         // fill 4 attrib with the same value at once
00406                         //*(T *)pt = *(T *)(pt + stride) = *(T *)(pt + stride2)  = *(T *)(pt + stride3) = _F(it.get());
00407                         *(T *) pt = _F(it.get());
00408                         *(T *) (pt + stride) = *(T *) pt;
00409                         pt += stride;
00410                         *(T *) (pt + stride) = *(T *) pt;
00411                         pt += stride;
00412                         *(T *) (pt + stride) = *(T *) pt;
00413                         pt += stride2;
00414 
00415                         //pt += stride4; // advance of 4
00416                         it.advance();
00417                     }
00418                 }
00419                 else
00420                 {
00421                     // the particle won't cover the whole pattern during his life
00422 
00423                     while (numAttrib --)
00424                     {
00425                         // fill 4 attrib with the same value at once
00426                         *(T *) pt = _F(this->_NbCycles * it.get());
00427                         *(T *) (pt + stride) = *(T *) pt;
00428                         pt += stride;
00429                         *(T *) (pt + stride) = *(T *) pt;
00430                         pt += stride;
00431                         *(T *) (pt + stride) = *(T *) pt;
00432                         pt += stride2;
00433                         //*(T *)pt = *(T *)(pt + stride) = *(T *)(pt + stride2)  = *(T *)(pt + stride3) = _F(_NbCycles * it.get());
00434                         //pt += stride4; // advance of 4
00435                         it.advance();
00436                     }
00437                 }
00438             }
00439          }
00440 
00441 
00446          template <typename It> void makeNByIterator(It it, void *tab, uint32 stride, uint32 numAttrib
00447                                                   , uint32 nbReplicate, bool canOverlapOne) const
00448          {
00449 
00450                 nlassert(nbReplicate > 1);
00451 
00452                 uint8 *pt = (uint8 *) tab;
00453 
00454                 // loop counter
00455                 uint k;
00456 
00457 
00458                 if (this->_NbCycles > 1 || canOverlapOne)
00459                 {
00460 
00461                     if (!_Clamp)
00462                     {
00463                         if (this->_NbCycles == 1)
00464                         {
00465                             while (numAttrib --)
00466                             {
00467                                 // fill 4 attrib with the same value at once
00468                                 *(T *)pt = _F(NLMISC::OptFastFractionnalPart(it.get()));
00469                                 k = nbReplicate - 1;
00470                                 do
00471                                 {
00472                                     *(T *) (pt + stride) = *(T *) pt;
00473                                     pt += stride;
00474                                 }
00475                                 while (--k);
00476                                 pt += stride;
00477                                 it.advance();
00478                             }
00479                         }
00480                         else
00481                         {
00482                             while (numAttrib --)
00483                             {
00484                                 const float time =  this->_NbCycles * (it.get());
00485                                 // fill 4 attrib with the same value at once
00486                                 *(T *)pt = _F(NLMISC::OptFastFractionnalPart(time));
00487                                 k = nbReplicate - 1;
00488                                 do
00489                                 {
00490                                     *(T *) (pt + stride) = *(T *) pt;
00491                                     pt += stride;
00492                                 }
00493                                 while (--k);
00494                                 pt += stride;
00495                                 it.advance();
00496                             }
00497                         }
00498                     }
00499                     else
00500                     {
00501                         float value;
00502                         // clamping is on
00503                         if (this->_NbCycles == 1)
00504                         {
00505                             while (numAttrib --)
00506                             {
00507                                 // fill 4 attrib with the same value at once
00508                                 value = it.get();
00509                                 if (value > MaxInputValue)
00510                                 {
00511                                     value = MaxInputValue;
00512                                 }
00513                                 *(T *)pt = _F(value);
00514                                 k = nbReplicate - 1;
00515                                 do
00516                                 {
00517                                     *(T *) (pt + stride) = *(T *) pt;
00518                                     pt += stride;
00519                                 }
00520                                 while (--k);
00521                                 pt += stride;
00522                                 it.advance();
00523                             }
00524                         }
00525                         else
00526                         {
00527                             while (numAttrib --)
00528                             {
00529                                 value =  this->_NbCycles * (it.get());
00530                                 if (value > MaxInputValue)
00531                                 {
00532                                     value = MaxInputValue;
00533                                 }
00534                                 // fill 4 attrib with the same value at once
00535                                 *(T *)pt = _F(value);
00536                                 k = nbReplicate - 1;
00537                                 do
00538                                 {
00539                                     *(T *) (pt + stride) = *(T *) pt;
00540                                     pt += stride;
00541                                 }
00542                                 while (--k);
00543                                 pt += stride;
00544                                 it.advance();
00545                             }
00546                         }
00547                     }
00548                 }
00549                 else
00550                 {
00551                     // the fastest case : it match the particle's life perfectly
00552 
00553                     if (this->_NbCycles == 1)
00554                     {
00555                         while (numAttrib --)
00556                         {
00557                             // fill 4 attrib with the same value at once
00558                             *(T *)pt = _F(it.get());
00559                             k = nbReplicate - 1;
00560                             do
00561                             {
00562                                 *(T *) (pt + stride) = *(T *) pt;
00563                                 pt += stride;
00564                             }
00565                             while (--k);
00566                             pt += stride;
00567                             it.advance();
00568                         }
00569                     }
00570                     else
00571                     {
00572                         // the particle won't cover the whole pattern during his life
00573 
00574                         while (numAttrib --)
00575                         {
00576                             // fill 4 attrib with the same value at once
00577                             *(T *)pt =  _F(this->_NbCycles * it.get());
00578                             k = nbReplicate - 1;
00579                             do
00580                             {
00581                                 *(T *) (pt + stride) = *(T *) pt;
00582                                 pt += stride;
00583                             }
00584                             while (--k);
00585                             pt += stride;
00586                             it.advance();
00587                         }
00588                     }
00589                 }
00590             }
00591 
00592 
00593 
00594             /* template <typename T, class F> */
00595             void /*CPSAttribMakerT<T, F>::*/ *make(CPSLocated *loc,
00596                                               uint32 startIndex,
00597                                               void *tab,
00598                                               uint32 stride,
00599                                               uint32 numAttrib,
00600                                               bool /* allowNoCopy */ /* = false */,
00601                                               uint32 srcStep /*= (1 << 16)*/,
00602                                               bool  forceClampEntry /*= false*/
00603                                              ) const
00604             {
00605 
00606                 NLMISC::OptFastFloorBegin();
00607                 nlassert(loc);
00608 
00609                 if (srcStep == (1 << 16))
00610                 {
00611                     switch (_InputType.InputType)
00612                     {
00613                         case CPSInputType::attrDate:
00614                         {
00615                             CPSBaseIterator<TIteratorFloatStep1>
00616                                 it(TIteratorFloatStep1(loc->getTime().begin(), startIndex));
00617                             makeByIterator(it, tab, stride, numAttrib, loc->getLastForever(), forceClampEntry);
00618                         }
00619                         break;
00620                         case CPSInputType::attrInverseMass:
00621                         {
00622                             CPSBaseIterator<TIteratorFloatStep1>
00623                                 it(TIteratorFloatStep1(loc->getInvMass().begin() , startIndex));
00624                             makeByIterator(it, tab, stride, numAttrib, true, forceClampEntry);
00625                         }
00626                         break;
00627                         case CPSInputType::attrSpeed:
00628                         {
00629                             CVectNormIterator<TIteratorVectStep1>
00630                                 it(TIteratorVectStep1(loc->getSpeed().begin(), startIndex));
00631                             makeByIterator(it, tab, stride, numAttrib, true, forceClampEntry);
00632                         }
00633                         break;
00634 
00635                         case CPSInputType::attrPosition:
00636                         {
00637                             CVectNormIterator<TIteratorVectStep1>
00638                                 it( TIteratorVectStep1(loc->getPos().begin(), startIndex) );
00639                             makeByIterator(it, tab, stride, numAttrib, true, forceClampEntry);
00640                         }
00641                         break;
00642                         case CPSInputType::attrUniformRandom:
00643                         {
00644                             CRandomIterator it;
00645                             makeByIterator(it, tab, stride, numAttrib, true, forceClampEntry);
00646                         }
00647                         break;
00648                         case CPSInputType::attrUserParam:
00649                         {
00650                             CDecalIterator it;
00651                             it.Value = loc->getUserParam(_InputType.UserParamNum);
00652                             makeByIterator(it, tab, stride, numAttrib, false, forceClampEntry);
00653                         }
00654                         break;
00655                         case CPSInputType::attrLOD:
00656                         {
00657 
00658                             CFDot3AddIterator<TIteratorVectStep1>
00659                                 it(TIteratorVectStep1(loc->getPos().begin(), startIndex));
00660                             loc->getLODVect(it.V, it.Offset, loc->getMatrixMode());
00661                             makeByIterator(it, tab, stride, numAttrib, false, forceClampEntry);
00662                         }
00663                         break;
00664                         case CPSInputType::attrSquareLOD:
00665                         {
00666 
00667                             CFSquareDot3AddIterator<TIteratorVectStep1>
00668                                 it(TIteratorVectStep1(loc->getPos().begin(), startIndex));
00669                             loc->getLODVect(it.V, it.Offset, loc->getMatrixMode());
00670                             makeByIterator(it, tab, stride, numAttrib, false, forceClampEntry);
00671                         }
00672                         break;
00673                         case CPSInputType::attrClampedLOD:
00674                         {
00675 
00676                             CFClampDot3AddIterator<TIteratorVectStep1>
00677                                 it(TIteratorVectStep1(loc->getPos().begin(), startIndex));
00678                             loc->getLODVect(it.V, it.Offset, loc->getMatrixMode());
00679                             makeByIterator(it, tab, stride, numAttrib, false, forceClampEntry);
00680                         }
00681                         break;
00682                         case CPSInputType::attrClampedSquareLOD:
00683                         {
00684 
00685                             CFClampSquareDot3AddIterator<TIteratorVectStep1>
00686                                 it(TIteratorVectStep1(loc->getPos().begin(), startIndex));
00687                             loc->getLODVect(it.V, it.Offset, loc->getMatrixMode());
00688                             makeByIterator(it, tab, stride, numAttrib, false, forceClampEntry);
00689                         }
00690                         break;
00691                     }
00692 
00693                     NLMISC::OptFastFloorEnd();
00694                     // we must alway copy the data there ...
00695                     return tab;
00696                 }
00697                 else // fixed point steps
00698                 {
00699                     switch (_InputType.InputType)
00700                     {
00701                         case CPSInputType::attrDate:
00702                         {
00703                             CPSBaseIterator<TIteratorFloatStep1616>
00704                                 it(TIteratorFloatStep1616(loc->getTime().begin(), startIndex, srcStep));
00705                             makeByIterator(it, tab, stride, numAttrib, loc->getLastForever(), forceClampEntry);
00706                         }
00707                         break;
00708                         case CPSInputType::attrInverseMass:
00709                         {
00710                             CPSBaseIterator<TIteratorFloatStep1616>
00711                                 it( TIteratorFloatStep1616(loc->getInvMass().begin(), startIndex, srcStep));
00712                             makeByIterator(it, tab, stride, numAttrib, true, forceClampEntry);
00713                         }
00714                         break;
00715                         case CPSInputType::attrSpeed:
00716                         {
00717                             CVectNormIterator<TIteratorVectStep1616>
00718                                 it( TIteratorVectStep1616(loc->getSpeed().begin(), startIndex, srcStep) );
00719                             makeByIterator(it, tab, stride, numAttrib, true, forceClampEntry);
00720                         }
00721                         break;
00722 
00723                         case CPSInputType::attrPosition:
00724                         {
00725                             CVectNormIterator<TIteratorVectStep1616>
00726                                 it( TIteratorVectStep1616(loc->getPos().begin(), startIndex, srcStep) );
00727                             makeByIterator(it, tab, stride, numAttrib, true, forceClampEntry);
00728                         }
00729                         break;
00730                         case CPSInputType::attrUniformRandom:
00731                         {
00732                             CRandomIterator it;
00733                             makeByIterator(it, tab, stride, numAttrib, true, forceClampEntry);
00734                         }
00735                         break;
00736                         case CPSInputType::attrUserParam:
00737                         {
00738                             CDecalIterator it;
00739                             it.Value = loc->getUserParam(_InputType.UserParamNum);
00740                             makeByIterator(it, tab, stride, numAttrib, false, forceClampEntry);
00741                         }
00742                         break;
00743                         case CPSInputType::attrLOD:
00744                         {
00745 
00746                             CFDot3AddIterator<TIteratorVectStep1616>
00747                                 it( TIteratorVectStep1616(loc->getPos().begin(), startIndex, srcStep) );
00748                             loc->getLODVect(it.V, it.Offset, loc->getMatrixMode());
00749                             makeByIterator(it, tab, stride, numAttrib, false, forceClampEntry);
00750                         }
00751                         break;
00752                         case CPSInputType::attrSquareLOD:
00753                         {
00754 
00755                             CFSquareDot3AddIterator<TIteratorVectStep1616>
00756                                 it( TIteratorVectStep1616(loc->getPos().begin(), startIndex, srcStep) );
00757                             loc->getLODVect(it.V, it.Offset, loc->getMatrixMode());
00758                             makeByIterator(it, tab, stride, numAttrib, false, forceClampEntry);
00759                         }
00760                         break;
00761                         case CPSInputType::attrClampedLOD:
00762                         {
00763 
00764                             CFClampDot3AddIterator<TIteratorVectStep1616>
00765                                 it( TIteratorVectStep1616(loc->getPos().begin(), startIndex, srcStep) );
00766                             loc->getLODVect(it.V, it.Offset, loc->getMatrixMode());
00767                             makeByIterator(it, tab, stride, numAttrib, false, forceClampEntry);
00768                         }
00769                         break;
00770                         case CPSInputType::attrClampedSquareLOD:
00771                         {
00772 
00773                             CFClampSquareDot3AddIterator<TIteratorVectStep1616>
00774                                 it( TIteratorVectStep1616(loc->getPos().begin(), startIndex, srcStep) );
00775                             loc->getLODVect(it.V, it.Offset, loc->getMatrixMode());
00776                             makeByIterator(it, tab, stride, numAttrib, false, forceClampEntry);
00777                         }
00778                         break;
00779                     }
00780 
00781                     NLMISC::OptFastFloorEnd();
00782                     // we must alway copy the data there ...
00783                     return tab;
00784                 }
00785             }
00786 
00787 
00788 
00789             /* template <typename T, class F> */
00790             void /*CPSAttribMakerT<T, F>::*/make4(CPSLocated *loc,
00791                                                uint32 startIndex,
00792                                                void *tab,
00793                                                uint32 stride,
00794                                                uint32 numAttrib,
00795                                                uint32 srcStep /*= (1 << 16)*/
00796                                               ) const
00797             {
00798                 NLMISC::OptFastFloorBegin();
00799                 nlassert(loc);
00800 
00801                 if (srcStep == (1 << 16))
00802                 {
00803                     switch (_InputType.InputType)
00804                     {
00805                         case CPSInputType::attrDate:
00806                         {
00807                             CPSBaseIterator<TIteratorFloatStep1>
00808                                 it(TIteratorFloatStep1( loc->getTime().begin(), startIndex) );
00809                             make4ByIterator(it, tab, stride, numAttrib, loc->getLastForever());
00810                         }
00811                         break;
00812                         case CPSInputType::attrInverseMass:
00813                         {
00814                             CPSBaseIterator<TIteratorFloatStep1>
00815                                 it( TIteratorFloatStep1(loc->getInvMass().begin(), startIndex) );
00816                             make4ByIterator(it, tab, stride, numAttrib, true);
00817                         }
00818                         break;
00819                         case CPSInputType::attrSpeed:
00820                         {
00821                             CVectNormIterator<TIteratorVectStep1>
00822                                 it( TIteratorVectStep1(loc->getSpeed().begin(), startIndex) );
00823                             make4ByIterator(it, tab, stride, numAttrib, true);
00824                         }
00825                         break;
00826 
00827                         case CPSInputType::attrPosition:
00828                         {
00829                             CVectNormIterator<TIteratorVectStep1>
00830                                 it( TIteratorVectStep1(loc->getPos().begin() , startIndex) );
00831                             make4ByIterator(it, tab, stride, numAttrib, true);
00832                         }
00833                         break;
00834                         case CPSInputType::attrUniformRandom:
00835                         {
00836                             CRandomIterator it;
00837                             make4ByIterator(it, tab, stride, numAttrib, true);
00838                         }
00839                         break;
00840                         case CPSInputType::attrUserParam:
00841                         {
00842                             CDecalIterator it;
00843                             it.Value = loc->getUserParam(_InputType.UserParamNum);
00844                             make4ByIterator(it, tab, stride, numAttrib, false);
00845                         }
00846                         break;
00847                         case CPSInputType::attrLOD:
00848                         {
00849 
00850                             CFDot3AddIterator<TIteratorVectStep1>
00851                                 it(TIteratorVectStep1(loc->getPos().begin(), startIndex) );
00852                             loc->getLODVect(it.V, it.Offset, loc->getMatrixMode());
00853                             make4ByIterator(it, tab, stride, numAttrib, false);
00854                         }
00855                         break;
00856                         case CPSInputType::attrSquareLOD:
00857                         {
00858 
00859                             CFSquareDot3AddIterator<TIteratorVectStep1>
00860                                 it(TIteratorVectStep1(loc->getPos().begin(), startIndex));
00861                             loc->getLODVect(it.V, it.Offset, loc->getMatrixMode());
00862                             make4ByIterator(it, tab, stride, numAttrib, false);
00863                         }
00864                         break;
00865                         case CPSInputType::attrClampedLOD:
00866                         {
00867 
00868                             CFClampDot3AddIterator<TIteratorVectStep1>
00869                                 it(TIteratorVectStep1(loc->getPos().begin(), startIndex));
00870                             loc->getLODVect(it.V, it.Offset, loc->getMatrixMode());
00871                             make4ByIterator(it, tab, stride, numAttrib, false);
00872                         }
00873                         break;
00874                         case CPSInputType::attrClampedSquareLOD:
00875                         {
00876 
00877                             CFClampSquareDot3AddIterator<TIteratorVectStep1>
00878                                 it(TIteratorVectStep1(loc->getPos().begin(), startIndex));
00879                             loc->getLODVect(it.V, it.Offset, loc->getMatrixMode());
00880                             make4ByIterator(it, tab, stride, numAttrib, false);
00881                         }
00882                         break;
00883                     }
00884 
00885                     NLMISC::OptFastFloorEnd();
00886                 }
00887                 else // fixed point steps
00888                 {
00889                     switch (_InputType.InputType)
00890                     {
00891                         case CPSInputType::attrDate:
00892                         {
00893                             CPSBaseIterator<TIteratorFloatStep1616>
00894                                 it(TIteratorFloatStep1616(loc->getTime().begin(), startIndex, srcStep));
00895                             make4ByIterator(it, tab, stride, numAttrib, loc->getLastForever());
00896                         }
00897                         break;
00898                         case CPSInputType::attrInverseMass:
00899                         {
00900                             CPSBaseIterator<TIteratorFloatStep1616>
00901                                 it( TIteratorFloatStep1616(loc->getInvMass().begin() , startIndex, srcStep));
00902                             make4ByIterator(it, tab, stride, numAttrib, true);
00903                         }
00904                         break;
00905                         case CPSInputType::attrSpeed:
00906                         {
00907                             CVectNormIterator<TIteratorVectStep1616>
00908                                 it( TIteratorVectStep1616(loc->getSpeed().begin(), startIndex, srcStep) );
00909                             make4ByIterator(it, tab, stride, numAttrib, true);
00910                         }
00911                         break;
00912 
00913                         case CPSInputType::attrPosition:
00914                         {
00915                             CVectNormIterator<TIteratorVectStep1616>
00916                                 it( TIteratorVectStep1616(loc->getPos().begin() , startIndex, srcStep) );
00917                             make4ByIterator(it, tab, stride, numAttrib, true);
00918                         }
00919                         break;
00920                         case CPSInputType::attrUniformRandom:
00921                         {
00922                             CRandomIterator it;
00923                             make4ByIterator(it, tab, stride, numAttrib, true);
00924                         }
00925                         break;
00926                         case CPSInputType::attrUserParam:
00927                         {
00928                             CDecalIterator it;
00929                             it.Value = loc->getUserParam(_InputType.UserParamNum);
00930                             make4ByIterator(it, tab, stride, numAttrib, false);
00931                         }
00932                         break;
00933                         case CPSInputType::attrLOD:
00934                         {
00935 
00936                             CFDot3AddIterator<TIteratorVectStep1616>
00937                                 it( TIteratorVectStep1616(loc->getPos().begin(), startIndex, srcStep) );
00938                             loc->getLODVect(it.V, it.Offset, loc->getMatrixMode());
00939                             make4ByIterator(it, tab, stride, numAttrib, false);
00940                         }
00941                         break;
00942                         case CPSInputType::attrSquareLOD:
00943                         {
00944 
00945                             CFSquareDot3AddIterator<TIteratorVectStep1616>
00946                                 it( TIteratorVectStep1616(loc->getPos().begin(), startIndex, srcStep) );
00947                             loc->getLODVect(it.V, it.Offset, loc->getMatrixMode());
00948                             make4ByIterator(it, tab, stride, numAttrib, false);
00949                         }
00950                         break;
00951                         case CPSInputType::attrClampedLOD:
00952                         {
00953 
00954                             CFClampDot3AddIterator<TIteratorVectStep1616>
00955                                 it( TIteratorVectStep1616(loc->getPos().begin(), startIndex, srcStep) );
00956                             loc->getLODVect(it.V, it.Offset, loc->getMatrixMode());
00957                             make4ByIterator(it, tab, stride, numAttrib, false);
00958                         }
00959                         break;
00960                         case CPSInputType::attrClampedSquareLOD:
00961                         {
00962 
00963                             CFClampSquareDot3AddIterator<TIteratorVectStep1616>
00964                                 it( TIteratorVectStep1616(loc->getPos().begin(), startIndex, srcStep) );
00965                             loc->getLODVect(it.V, it.Offset, loc->getMatrixMode());
00966                             make4ByIterator(it, tab, stride, numAttrib, false);
00967                         }
00968                         break;
00969                     }
00970 
00971                     NLMISC::OptFastFloorEnd();
00972 
00973                 }
00974             }
00975 
00976 
00977             /* template <typename T, class F> */
00978             virtual void /*CPSAttribMakerT<T, F>::*/makeN(CPSLocated *loc,
00979                                         uint32 startIndex,
00980                                         void *tab,
00981                                         uint32 stride,
00982                                         uint32 numAttrib,
00983                                         uint32 nbReplicate,
00984                                         uint32 srcStep /* = (1 << 16)*/
00985                                     ) const
00986             {
00987                 NLMISC::OptFastFloorBegin();
00988                 nlassert(loc);
00989                 if (srcStep == (1 << 16))
00990                 {
00991                     switch (_InputType.InputType)
00992                     {
00993                         case CPSInputType::attrDate:
00994                         {
00995                             CPSBaseIterator<TIteratorFloatStep1>
00996                                 it(TIteratorFloatStep1(loc->getTime().begin(), startIndex) );
00997                             makeNByIterator(it, tab, stride, numAttrib, nbReplicate, loc->getLastForever());
00998                         }
00999                         break;
01000                         case CPSInputType::attrInverseMass:
01001                         {
01002                             CPSBaseIterator<TIteratorFloatStep1>
01003                                 it( TIteratorFloatStep1(loc->getInvMass().begin() , startIndex) );
01004                             makeNByIterator(it, tab, stride, numAttrib, nbReplicate, true);
01005                         }
01006                         break;
01007                         case CPSInputType::attrSpeed:
01008                         {
01009                             CVectNormIterator<TIteratorVectStep1>
01010                                 it( TIteratorVectStep1(loc->getSpeed().begin(), startIndex) );
01011                             makeNByIterator(it, tab, stride, numAttrib, nbReplicate, true);
01012                         }
01013                         break;
01014 
01015                         case CPSInputType::attrPosition:
01016                         {
01017                             CVectNormIterator<TIteratorVectStep1>
01018                                 it( TIteratorVectStep1( loc->getPos().begin() , startIndex ) );
01019                             makeNByIterator(it, tab, stride, numAttrib, nbReplicate, true);
01020                         }
01021                         break;
01022                         case CPSInputType::attrUniformRandom:
01023                         {
01024                             CRandomIterator it;
01025                             makeNByIterator(it, tab, stride, numAttrib, nbReplicate, true);
01026                         }
01027                         break;
01028                         case CPSInputType::attrUserParam:
01029                         {
01030                             CDecalIterator it;
01031                             it.Value = loc->getUserParam(_InputType.UserParamNum);
01032                             makeNByIterator(it, tab, stride, numAttrib, nbReplicate, false);
01033                         }
01034                         break;
01035                         case CPSInputType::attrLOD:
01036                         {
01037 
01038                             CFDot3AddIterator<TIteratorVectStep1>
01039                                 it( TIteratorVectStep1(loc->getPos().begin(), startIndex) );
01040                             loc->getLODVect(it.V, it.Offset, loc->getMatrixMode());
01041                             makeNByIterator(it, tab, stride, numAttrib, nbReplicate, false);
01042                         }
01043                         break;
01044                         case CPSInputType::attrSquareLOD:
01045                         {
01046 
01047                             CFSquareDot3AddIterator<TIteratorVectStep1>
01048                                 it(TIteratorVectStep1(loc->getPos().begin(), startIndex));
01049                             loc->getLODVect(it.V, it.Offset, loc->getMatrixMode());
01050                             makeNByIterator(it, tab, stride, numAttrib, nbReplicate, false);
01051                         }
01052                         break;
01053                         case CPSInputType::attrClampedLOD:
01054                         {
01055 
01056                             CFClampDot3AddIterator<TIteratorVectStep1>
01057                                 it(TIteratorVectStep1(loc->getPos().begin(), startIndex));
01058                             loc->getLODVect(it.V, it.Offset, loc->getMatrixMode());
01059                             makeNByIterator(it, tab, stride, numAttrib, nbReplicate, false);
01060                         }
01061                         break;
01062                         case CPSInputType::attrClampedSquareLOD:
01063                         {
01064 
01065                             CFClampSquareDot3AddIterator<TIteratorVectStep1>
01066                                 it(TIteratorVectStep1(loc->getPos().begin(), startIndex));
01067                             loc->getLODVect(it.V, it.Offset, loc->getMatrixMode());
01068                             makeNByIterator(it, tab, stride, numAttrib, nbReplicate, false);
01069                         }
01070                         break;
01071                     }
01072 
01073                     NLMISC::OptFastFloorEnd();
01074                 }
01075                 else // fixed point steps
01076                 {
01077                     switch (_InputType.InputType)
01078                     {
01079                         case CPSInputType::attrDate:
01080                         {
01081                             CPSBaseIterator<TIteratorFloatStep1616>
01082                                 it(TIteratorFloatStep1616(loc->getTime().begin(), startIndex, srcStep));
01083                             makeNByIterator(it, tab, stride, numAttrib, nbReplicate, loc->getLastForever());
01084                         }
01085                         break;
01086                         case CPSInputType::attrInverseMass:
01087                         {
01088                             CPSBaseIterator<TIteratorFloatStep1616>
01089                                 it( TIteratorFloatStep1616(loc->getInvMass().begin() , startIndex, srcStep) );
01090                             makeNByIterator(it, tab, stride, numAttrib, nbReplicate, true);
01091                         }
01092                         break;
01093                         case CPSInputType::attrSpeed:
01094                         {
01095                             CVectNormIterator<TIteratorVectStep1616>
01096                                 it( TIteratorVectStep1616(loc->getSpeed().begin(), startIndex, srcStep) );
01097                             makeNByIterator(it, tab, stride, numAttrib, nbReplicate, true);
01098                         }
01099                         break;
01100 
01101                         case CPSInputType::attrPosition:
01102                         {
01103                             CVectNormIterator<TIteratorVectStep1616>
01104                                 it( TIteratorVectStep1616(loc->getPos().begin(), startIndex, srcStep) );
01105                             makeNByIterator(it, tab, stride, numAttrib, nbReplicate, true);
01106                         }
01107                         break;
01108                         case CPSInputType::attrUniformRandom:
01109                         {
01110                             CRandomIterator it;
01111                             makeNByIterator(it, tab, stride, numAttrib, nbReplicate, true);
01112                         }
01113                         break;
01114                         case CPSInputType::attrUserParam:
01115                         {
01116                             CDecalIterator it;
01117                             it.Value = loc->getUserParam(_InputType.UserParamNum);
01118                             makeNByIterator(it, tab, stride, numAttrib, nbReplicate, false);
01119                         }
01120                         break;
01121                         case CPSInputType::attrLOD:
01122                         {
01123 
01124                             CFDot3AddIterator<TIteratorVectStep1616>
01125                                 it( TIteratorVectStep1616(loc->getPos().begin(), startIndex, srcStep) );
01126                             loc->getLODVect(it.V, it.Offset, loc->getMatrixMode());
01127                             makeNByIterator(it, tab, stride, numAttrib, nbReplicate, false);
01128                         }
01129                         break;
01130                         case CPSInputType::attrSquareLOD:
01131                         {
01132 
01133                             CFSquareDot3AddIterator<TIteratorVectStep1616>
01134                                 it( TIteratorVectStep1616(loc->getPos().begin(), startIndex, srcStep) );
01135                             loc->getLODVect(it.V, it.Offset, loc->getMatrixMode());
01136                             makeNByIterator(it, tab, stride, numAttrib, nbReplicate, false);
01137                         }
01138                         break;
01139                         case CPSInputType::attrClampedLOD:
01140                         {
01141 
01142                             CFClampDot3AddIterator<TIteratorVectStep1616>
01143                                 it( TIteratorVectStep1616( loc->getPos().begin(), startIndex, srcStep) );
01144                             loc->getLODVect(it.V, it.Offset, loc->getMatrixMode());
01145                             makeNByIterator(it, tab, stride, numAttrib, nbReplicate, false);
01146                         }
01147                         break;
01148                         case CPSInputType::attrClampedSquareLOD:
01149                         {
01150 
01151                             CFClampSquareDot3AddIterator<TIteratorVectStep1616>
01152                                 it( TIteratorVectStep1616( loc->getPos().begin(), startIndex,  srcStep) );
01153                             loc->getLODVect(it.V, it.Offset, loc->getMatrixMode());
01154                             makeNByIterator(it, tab, stride, numAttrib, nbReplicate, false);
01155                         }
01156                         break;
01157                     }
01158 
01159                     NLMISC::OptFastFloorEnd();
01160                 }
01161             }
01162             // Compute a single value from the input assuming that NLMISC::OptFastFloorBegin() has been called
01163             virtual T getInternal(float input)
01164             {
01165                 input *= this->_NbCycles;
01166                 if (_Clamp)
01167                 {
01168                     if (input >= MaxInputValue) return _F(1.f);
01169                     return _F(input);
01170                 }
01171                 else
01172                 {
01173                     return (input == MaxInputValue) ? _F(MaxInputValue) :  _F(NLMISC::OptFastFractionnalPart(input));
01174                 }
01175             }
01176 };
01177 
01178 
01179 
01181 // implementation of CPSAttribMakerT methods //
01183 template <typename T, class F>
01184 T  CPSAttribMakerT<T, F>::get(CPSLocated *loc, uint32 index)
01185 {
01186     NLMISC::OptFastFloorBegin();
01187     T result;
01188     nlassert(loc);
01189     switch (_InputType.InputType)
01190     {
01191         case CPSInputType::attrDate:
01192             result = getInternal(loc->getTime()[index]);
01193         break;
01194         case CPSInputType::attrInverseMass:
01195             result=  getInternal(loc->getInvMass()[index]);
01196         break;
01197         case CPSInputType::attrSpeed:
01198             result = getInternal(loc->getSpeed()[index].norm());
01199         break;
01200         case CPSInputType::attrPosition:
01201             result = getInternal(loc->getPos()[index].norm());
01202         break;
01203         case CPSInputType::attrUniformRandom:
01204         {
01205             result =  _F(float(rand() * (1 / double(RAND_MAX))));
01206         }
01207         break;
01208         case CPSInputType::attrUserParam:
01209         {
01210             result = getInternal(loc->getUserParam(_InputType.UserParamNum));
01211         }
01212         break;
01213         case CPSInputType::attrLOD:
01214         {
01215             static NLMISC::CVector lodVect;
01216             float lodOffset;
01217             loc->getLODVect(lodVect, lodOffset, loc->getMatrixMode());
01218             float r = fabsf(loc->getPos()[index] * lodVect + lodOffset);
01219             r = this->_NbCycles * r > MaxInputValue ? MaxInputValue : r;
01220             if (_Clamp)
01221             {
01222                 result = _F(r > MaxInputValue ? MaxInputValue : r);
01223             }
01224             else result = (r == MaxInputValue) ? _F(MaxInputValue) : _F(NLMISC::OptFastFractionnalPart(r));
01225         }
01226         break;
01227         case CPSInputType::attrSquareLOD:
01228         {
01229             static NLMISC::CVector lodVect;
01230             float lodOffset;
01231             loc->getLODVect(lodVect, lodOffset, loc->getMatrixMode());
01232             float r = loc->getPos()[index] * lodVect + lodOffset;
01233             r = this->_NbCycles * (r > MaxInputValue ? MaxInputValue : r * r);
01234 
01235             if (_Clamp)
01236             {
01237                 result = _F(r > MaxInputValue ? MaxInputValue : r);
01238             }
01239             else result = (r == MaxInputValue) ? _F(MaxInputValue) : _F(NLMISC::OptFastFractionnalPart(r));
01240         }
01241         break;
01242         case CPSInputType::attrClampedLOD:
01243         {
01244             static NLMISC::CVector lodVect;
01245             float lodOffset;
01246             loc->getLODVect(lodVect, lodOffset, loc->getMatrixMode());
01247 
01248             float r = loc->getPos()[index] * lodVect + lodOffset;
01249             if (r < 0)
01250             {
01251                 result = _F(MaxInputValue);
01252                 break;
01253             }
01254             r = this->_NbCycles * (r > MaxInputValue ? MaxInputValue : r);
01255             if (_Clamp)
01256             {
01257                 result = _F(r > MaxInputValue ? MaxInputValue : r);
01258             }
01259             else result = (r == MaxInputValue) ? _F(MaxInputValue) : _F(NLMISC::OptFastFractionnalPart(r));
01260         }
01261         break;
01262         case CPSInputType::attrClampedSquareLOD:
01263         {
01264             static NLMISC::CVector lodVect;
01265             float lodOffset;
01266             loc->getLODVect(lodVect, lodOffset, loc->getMatrixMode());
01267 
01268             float r = loc->getPos()[index] * lodVect + lodOffset;
01269             if (r < 0)
01270             {
01271                 result = _F(MaxInputValue);
01272                 break;
01273             }
01274             r = this->_NbCycles * (r > MaxInputValue ? MaxInputValue : r * r);
01275             if (_Clamp)
01276             {
01277                 result = _F(r > MaxInputValue ? MaxInputValue : r);
01278             }
01279             else result = (r == MaxInputValue) ? _F(MaxInputValue) : _F(NLMISC::OptFastFractionnalPart(r));
01280         }
01281         break;
01282         default:
01283             result = T();
01284         break;
01285     }
01286 
01287     NLMISC::OptFastFloorEnd();
01288     return result;
01289 }
01290 
01291 template <typename T, class F>
01292 T  CPSAttribMakerT<T, F>::get(const CPSEmitterInfo &infos)
01293 {
01294     NLMISC::OptFastFloorBegin();
01295     T result;
01296     switch (_InputType.InputType)
01297     {
01298         case CPSInputType::attrDate:
01299         {
01300             result = getInternal(infos.Life);
01301         }
01302         break;
01303         case CPSInputType::attrInverseMass:
01304         {
01305             result = getInternal(infos.InvMass);
01306         }
01307         break;
01308         case CPSInputType::attrSpeed:
01309         {
01310             result = getInternal(infos.Speed.norm());
01311         }
01312         break;
01313         case CPSInputType::attrPosition:
01314         {
01315             result = getInternal(infos.Pos.norm());
01316         }
01317         break;
01318         case CPSInputType::attrUniformRandom:
01319         {
01320             result =  _F(float(rand() * (1 / double(RAND_MAX))));
01321         }
01322         break;
01323         case CPSInputType::attrUserParam:
01324         {
01325             result = getInternal(infos.Loc->getUserParam(_InputType.UserParamNum));
01326         }
01327         break;
01328         case CPSInputType::attrLOD:
01329         {
01330             static NLMISC::CVector lodVect;
01331             float lodOffset;
01332             infos.Loc->getLODVect(lodVect, lodOffset, infos.Loc->getMatrixMode());
01333             float r = fabsf(infos.Pos * lodVect + lodOffset);
01334             r = this->_NbCycles * r > MaxInputValue ? MaxInputValue : r;
01335             if (_Clamp)
01336             {
01337                 result = _F(r > MaxInputValue ? MaxInputValue : r);
01338             }
01339             else result = (r == MaxInputValue) ? _F(MaxInputValue) : _F(NLMISC::OptFastFractionnalPart(r));
01340         }
01341         break;
01342         case CPSInputType::attrSquareLOD:
01343         {
01344             static NLMISC::CVector lodVect;
01345             float lodOffset;
01346             infos.Loc->getLODVect(lodVect, lodOffset, infos.Loc->getMatrixMode());
01347             float r = infos.Pos * lodVect + lodOffset;
01348             r = this->_NbCycles * (r > MaxInputValue ? MaxInputValue : r * r);
01349 
01350             if (_Clamp)
01351             {
01352                 result = _F(r > MaxInputValue ? MaxInputValue : r);
01353             }
01354             else result = (r == MaxInputValue) ? _F(MaxInputValue) : _F(NLMISC::OptFastFractionnalPart(r));
01355         }
01356         break;
01357         case CPSInputType::attrClampedLOD:
01358         {
01359             static NLMISC::CVector lodVect;
01360             float lodOffset;
01361             infos.Loc->getLODVect(lodVect, lodOffset, infos.Loc->getMatrixMode());
01362             float r = infos.Pos * lodVect + lodOffset;
01363             if (r < 0)
01364             {
01365                 result = _F(MaxInputValue);
01366                 break;
01367             }
01368             r = this->_NbCycles * (r > MaxInputValue ? MaxInputValue : r);
01369             if (_Clamp)
01370             {
01371                 result = _F(r > MaxInputValue ? MaxInputValue : r);
01372             }
01373             else result = (r == MaxInputValue) ? _F(MaxInputValue) : _F(NLMISC::OptFastFractionnalPart(r));
01374         }
01375         break;
01376         case CPSInputType::attrClampedSquareLOD:
01377         {
01378             static NLMISC::CVector lodVect;
01379             float lodOffset;
01380             infos.Loc->getLODVect(lodVect, lodOffset, infos.Loc->getMatrixMode());
01381 
01382             float r = infos.Pos * lodVect + lodOffset;
01383             if (r < 0)
01384             {
01385                 result = _F(MaxInputValue);
01386                 break;
01387             }
01388             r = this->_NbCycles * (r > MaxInputValue ? MaxInputValue : r * r);
01389             if (_Clamp)
01390             {
01391                 result = _F(r > MaxInputValue ? MaxInputValue : r);
01392             }
01393             else result = (r == MaxInputValue) ? _F(MaxInputValue) : _F(NLMISC::OptFastFractionnalPart(r));
01394         }
01395         break;
01396         default:
01397             result = T();
01398         break;
01399     }
01400     NLMISC::OptFastFloorEnd();
01401     return result;
01402 }
01403 
01412 template <typename T> class CPSAttribMakerMemoryBase : public CPSAttribMaker<T>
01413 {
01414 public:
01415 
01417     CPSAttribMakerMemoryBase() : CPSAttribMaker<T>(1.f), _Scheme(NULL)
01418     {
01419         this->_HasMemory = true;
01420     }
01421 
01440     virtual void setDefaultValue(T defaultValue) { _DefaultValue = defaultValue;}
01441 
01443     virtual T getDefaultValue(void) const { return _DefaultValue; }
01444 
01445 
01446 
01450     void setScheme(CPSAttribMaker<T> *scheme)
01451     {
01452         nlassert(scheme);
01453         if (_Scheme) delete _Scheme;
01454         _Scheme = scheme;
01455         if (_Scheme->hasMemory())
01456         {
01457             _Scheme->resize(_T.getMaxSize(), _T.getSize());
01458         }
01459     }
01460 
01462     CPSAttribMaker<T> *getScheme(void) { return _Scheme; }
01464     const CPSAttribMaker<T> *getScheme(void) const { return _Scheme; }
01465 
01466 
01467     // copy ctor
01468     CPSAttribMakerMemoryBase(const CPSAttribMakerMemoryBase &src) : CPSAttribMaker<T>(src) // parent copy ctor
01469     {
01470         nlassert(src._Scheme);
01471         std::auto_ptr<CPSAttribMaker<T> > s(NLMISC::safe_cast<CPSAttribMaker<T> *>(src._Scheme->clone()));
01472         this->_T = src._T;
01473         this->_DefaultValue = src._DefaultValue;
01474         this->_Scheme = s.release();
01475     }
01477     ~CPSAttribMakerMemoryBase()
01478     {
01479         if (_Scheme)
01480         {
01481             delete _Scheme;
01482         }
01483     }
01484 
01486     virtual T get(CPSLocated * /* loc */, uint32 index)
01487     {
01488         if (index < _T.getSize()) return _T[index];
01489         else return _DefaultValue;
01490     }
01491     virtual T get(const CPSEmitterInfo &/* infos */) {  return _DefaultValue; }
01492 
01494     virtual void *make(CPSLocated * /* loc */,
01495                        uint32 startIndex,
01496                        void *output,
01497                        uint32 stride,
01498                        uint32 numAttrib,
01499                        bool allowNoCopy = false,
01500                        uint32 srcStep = (1 << 16),
01501                        bool /* forceClampEntry */ = false
01502                       ) const
01503     {
01504         if (!numAttrib) return output;
01505         void *tab = output;
01506         if (!allowNoCopy || srcStep != (1 << 16) || sizeof(T) != stride)
01507         {
01508             // we just copy what we have memorized
01509             if (srcStep == (1 << 16))
01510             {
01511                 typename CPSAttrib<T>::const_iterator it = _T.begin() + startIndex, endIt = _T.begin() + startIndex + numAttrib;
01512                 do
01513                 {
01514                     *(T *) tab = *it;
01515                     ++it;
01516                     tab = (uint8 *) tab + stride;
01517                 }
01518                 while (it != endIt);
01519             }
01520             else // no constant step
01521             {
01522                 uint32 fpIndex = startIndex * srcStep;
01523                 typename CPSAttrib<T>::const_iterator startIt = _T.begin();
01524                 while (numAttrib --)
01525                 {
01526                     *(T *) tab = *(startIt + (fpIndex >> 16));
01527                     tab = (uint8 *) tab + stride;
01528                     fpIndex += srcStep;
01529                 }
01530             }
01531             return output;
01532         }
01533         else
01534         {
01535             // the caller will read data directly in the vector ...
01536             return (void *) &(*(_T.begin() + startIndex));
01537         }
01538     }
01539 
01541     virtual void make4(CPSLocated * /* loc */,
01542                        uint32 startIndex,
01543                        void *tab,
01544                        uint32 stride,
01545                        uint32 numAttrib,
01546                        uint32 srcStep = (1 << 16)
01547                        ) const
01548     {
01549         // we just copy what we have memorized
01550         if (srcStep == (1 << 16))
01551         {
01552             typename CPSAttrib<T>::const_iterator it = _T.begin() + startIndex, endIt = _T.begin() + startIndex + numAttrib;
01553             while (it != endIt)
01554             {
01555                 *(T *) tab = *it;
01556                 tab = (uint8 *) tab + stride;
01557                 *(T *) tab = *it;
01558                 tab = (uint8 *) tab + stride;
01559                 *(T *) tab = *it;
01560                 tab = (uint8 *) tab + stride;
01561                 *(T *) tab = *it;
01562                 tab = (uint8 *) tab + stride;
01563                 ++it;
01564             }
01565         }
01566         else
01567         {
01568             uint32 fpIndex = startIndex * srcStep;
01569             typename CPSAttrib<T>::const_iterator startIt = _T.begin();
01570             while (numAttrib --)
01571             {
01572                 *(T *) tab = *(startIt + (fpIndex >> 16));
01573                 *(T *) ((uint8 *) tab + stride) = *(T *) tab;
01574                 tab = (uint8 *) tab + stride;
01575                 *(T *) ((uint8 *) tab + stride) = *(T *) tab;
01576                 tab = (uint8 *) tab + stride;
01577                 *(T *) ((uint8 *) tab + stride) = *(T *) tab;
01578 
01579                 tab = (uint8 *) tab + stride + stride;
01580                 fpIndex += srcStep;
01581             }
01582         }
01583     }
01584 
01586     virtual void makeN(CPSLocated * /* loc */,
01587                        uint32 startIndex,
01588                        void *tab,
01589                        uint32 stride,
01590                        uint32 numAttrib,
01591                        uint32 nbReplicate,
01592                        uint32 srcStep = (1 << 16)
01593                       ) const
01594     {
01595         // we just copy what we have memorized
01596         uint k;
01597         typename CPSAttrib<T>::const_iterator it = _T.begin() + startIndex, endIt = _T.begin() + startIndex + numAttrib;
01598         if (srcStep == (1 << 16))
01599         {
01600             while (it != endIt)
01601             {
01602 
01603                 for (k = 0; k < nbReplicate; ++k)
01604                 {
01605                     *(T *) tab = *it;
01606                     tab = (uint8 *) tab + stride;
01607                 }
01608                 ++it;
01609             }
01610         }
01611         else
01612         {
01613             uint32 fpIndex = startIndex * srcStep;
01614             typename CPSAttrib<T>::const_iterator startIt = _T.begin();
01615 
01616             while (numAttrib --)
01617             {
01618                 *(T *) tab = *(startIt + (fpIndex >> 16));
01619                 for (k = 1; k < nbReplicate; ++k)
01620                 {
01621                     *(T *) ((uint8 *) tab + stride) = *(T *) tab;
01622                     tab = (uint8 *) tab + stride;
01623                 }
01624                 tab = (uint8 *) tab + stride;
01625                 fpIndex += srcStep;
01626             }
01627 
01628         }
01629     }
01630 
01632     virtual void serial(NLMISC::IStream &f) throw(NLMISC::EStream)
01633     {
01634 
01635         f.serialVersion(1);
01636         CPSAttribMaker<T>::serial(f);
01637         if (f.isReading())
01638         {
01639             if (_Scheme) delete _Scheme;
01640         }
01641         f.serialPolyPtr(_Scheme);
01642         f.serial(_T);
01643         f.serial(_DefaultValue);
01644     }
01645 
01647     virtual void deleteElement(uint32 index)
01648     {
01649         nlassert(_Scheme); // you should have called setScheme !
01650         _T.remove(index);
01651         if (_Scheme->hasMemory())
01652         {
01653             _Scheme->deleteElement(index);
01654         }
01655     }
01657     virtual void newElement(const CPSEmitterInfo &info)
01658     {
01659         nlassert(_Scheme); // you should have called setScheme !
01660 
01661         // we should create the contained scheme before this one if it has memory...
01662         if (_Scheme->hasMemory())
01663         {
01664             _Scheme->newElement(info);
01665         }
01666 
01667         if (info.Loc)
01668         {
01669             _T.insert(_Scheme->get(info));
01670         }
01671         else
01672         {
01677             _T.insert(_DefaultValue);
01678         }
01679     }
01680     virtual void resize(uint32 capacity, uint32 nbPresentElements)
01681     {
01682         nlassert(capacity < (1 << 16));
01683         _T.resize(capacity);
01684         if (nbPresentElements > _T.getSize())
01685         {
01686             while (_T.getSize() != nbPresentElements)
01687             {
01688                 _T.insert(_DefaultValue);
01689             }
01690         }
01691         else if (nbPresentElements < _T.getSize())
01692         {
01693             while (_T.getSize() != nbPresentElements)
01694             {
01695                 _T.remove(_T.getSize() - 1);
01696             }
01697         }
01698 
01699 
01700         if (_Scheme && _Scheme->hasMemory())
01701         {
01702             _Scheme->resize(capacity,   nbPresentElements);
01703         }
01704 
01705     }
01706     virtual bool hasCustomInput() { return false; }
01707 
01708 protected:
01709     // the attribute we memorize
01710     CPSAttrib<T> _T;
01711 
01712     // the default value for generation (when no emitter can be used)
01713     T _DefaultValue;
01714 
01719     CPSAttribMaker<T> *_Scheme;
01720 };
01721 
01722 
01725 template <typename T> class CPSAttribMakerMemory : public CPSAttribMakerMemoryBase<T>
01726 {
01727 public:
01728     // default ctor
01729     CPSAttribMakerMemory() : CPSAttribMakerMemoryBase<T>() {}
01730     CPSAttribMakerMemory(const CPSAttribMakerMemory &other) : CPSAttribMakerMemoryBase<T>(other) {}
01731 };
01732 
01739 template <>
01740 class CPSAttribMakerMemory<uint32> : public  CPSAttribMakerMemoryBase<uint32>
01741 {
01742 public:
01743     // default ctor
01744     CPSAttribMakerMemory() : CPSAttribMakerMemoryBase<uint32>() {}
01745     // copy ctor
01746     CPSAttribMakerMemory(const CPSAttribMakerMemory<uint32> &other) : CPSAttribMakerMemoryBase<uint32>(other)
01747     {
01748         _MinValue = other._MinValue;
01749         _MaxValue = other._MaxValue;
01750     }
01751     // serial. Should update min / max when reading
01752     virtual void serial(NLMISC::IStream &f) throw(NLMISC::EStream);
01753     virtual uint32 getMinValue(void) const { return _MinValue; }
01754     virtual uint32 getMaxValue(void) const { return _MaxValue; }
01755     virtual void newElement(const CPSEmitterInfo &info);
01756 private:
01757     uint32 _MinValue;
01758     uint32 _MaxValue;
01759 };
01762 template <>
01763 class CPSAttribMakerMemory<sint32> : public  CPSAttribMakerMemoryBase<sint32>
01764 {
01765 public:
01766     // default ctor
01767     CPSAttribMakerMemory() : CPSAttribMakerMemoryBase<sint32>() {}
01768     // copy ctor
01769     CPSAttribMakerMemory(const CPSAttribMakerMemory<sint32> &other) : CPSAttribMakerMemoryBase<sint32>(other)
01770     {
01771         _MinValue = other._MinValue;
01772         _MaxValue = other._MaxValue;
01773     }
01774     // serial. Should update min / max when reading
01775     virtual void serial(NLMISC::IStream &f) throw(NLMISC::EStream);
01776     virtual sint32 getMinValue(void) const { return _MinValue; }
01777     virtual sint32 getMaxValue(void) const { return _MaxValue; }
01778     virtual void newElement(const CPSEmitterInfo &info);
01779 private:
01780     sint32 _MinValue;
01781     sint32 _MaxValue;
01782 };
01785 template <>
01786 class CPSAttribMakerMemory<float> : public  CPSAttribMakerMemoryBase<float>
01787 {
01788 public:
01789     // default ctor
01790     CPSAttribMakerMemory() : CPSAttribMakerMemoryBase<float>() {}
01791     // copy ctor
01792     CPSAttribMakerMemory(const CPSAttribMakerMemory<float> &other) : CPSAttribMakerMemoryBase<float>(other)
01793     {
01794         _MinValue = other._MinValue;
01795         _MaxValue = other._MaxValue;
01796     }
01797     // serial. Should update min / max when reading
01798     virtual void serial(NLMISC::IStream &f) throw(NLMISC::EStream);
01799     virtual float getMinValue(void) const { return _MinValue; }
01800     virtual float getMaxValue(void) const { return _MaxValue; }
01801     virtual void newElement(const CPSEmitterInfo &info);
01802 private:
01803     float _MinValue;
01804     float _MaxValue;
01805 };
01806 
01807 
01808 
01809 
01810 
01811 } // NL3D
01812 
01813 
01814 #endif // NL_PS_ATTRIB_MAKER_HELPER_H
01815 
01816 /* End of ps_attrib_maker_helper.h */

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