# Home    # nevrax.com   
Nevrax
Nevrax.org
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
Docs
 
Documentation  
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  

ps_attrib_maker_helper.h

Go to the documentation of this file.
00001 
00007 /* Copyright, 2001 Nevrax Ltd.
00008  *
00009  * This file is part of NEVRAX NEL.
00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2, or (at your option)
00013  * any later version.
00014 
00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00018  * General Public License for more details.
00019 
00020  * You should have received a copy of the GNU General Public License
00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00023  * MA 02111-1307, USA.
00024  */
00025 
00026 #ifndef NL_PS_ATTRIB_MAKER_HELPER_H
00027 #define NL_PS_ATTRIB_MAKER_HELPER_H
00028 
00029 #include "3d/ps_attrib_maker.h"
00030 
00031 #include "fast_floor.h" // inline assembly for fast float<->int conversions
00032 #include "ps_attrib_maker_iterators.h" // some iterators we use 
00033 
00034 namespace NL3D 
00035 {
00036 
00037 
00038 
00039 
00040 
00041 
00051 template <typename T, class F> class CPSAttribMakerT : public CPSAttribMaker<T>
00052 {
00053         public:
00055                 F _F;   
00056 
00058                 virtual T get(CPSLocated *loc, uint32 index);
00059 
00060                 virtual T get(float input)
00061                 {
00062                         OptFastFloorBegin();
00063                         nlassert(input >= 0.f && input <= 1.f);
00064                         return _F(input);
00065                         OptFastFloorEnd();
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)
00129                                                                                   , _Clamp(false)
00130                 {}
00131 
00133                   virtual ~CPSAttribMakerT() {}
00134 
00135 
00139                 virtual bool hasCustomInput(void) { return true; } 
00140                 
00141 
00144                 virtual void setInput(const CPSInputType &input) { _InputType = input; }
00145 
00146 
00150                 virtual CPSInputType getInput(void) const { return _InputType; }
00151 
00152 
00155                 bool isClampingSupported(void) const { return true; }
00156 
00157 
00161                 virtual void setClamping(bool enable = true) { _Clamp = enable; };
00162 
00163 
00167                 virtual bool getClamping(void) const  { return _Clamp; };
00168 
00169 
00171                   typedef T value_type;
00172 
00174                   typedef F functor_type;
00175 
00176         private:                
00177 
00178                 // type of the input
00179                 CPSInputType _InputType;
00180 
00181                 // clamping on/ off
00182                 bool _Clamp;
00183 
00184                 
00185 
00191                  template <typename It> void makeByIterator(It it,
00192                                                                                                          void *tab,
00193                                                                                                          uint32 stride,
00194                                                                                                          uint32 numAttrib,
00195                                                                                                          bool canOverlapOne
00196                                                                                                          ) const
00197                  {                                              
00198                         uint8 *pt = (uint8 *) tab;
00199 
00200                         
00201                         if (_NbCycles > 1 || canOverlapOne)
00202                         {
00203                                 // the value could cycle, so we need to clamp it to 0.0f 1.0f
00204 
00205                                 if (!_Clamp)
00206                                 {
00207                                         if (_NbCycles == 1)
00208                                         {
00209                                                 while (numAttrib --)
00210                                                 {       
00211                                                         *(T *)pt = _F(OptFastFractionnalPart(it.get())); 
00212                                                         pt += stride;
00213                                                         it.advance();
00214                                                 }
00215                                         }
00216                                         else
00217                                         {
00218                                                 while (numAttrib --)
00219                                                 {
00220                                                         const float time =  _NbCycles * (it.get());
00221                                                         *(T *)pt = _F(OptFastFractionnalPart(time)); 
00222                                                         pt += stride;
00223                                                         it.advance();
00224                                                 }       
00225                                         }
00226                                 }
00227                                 else
00228                                 {
00229                                         // clamping is on
00230 
00231                                         float value;
00232 
00233                                         if (_NbCycles == 1)
00234                                         {
00235                                                 while (numAttrib --)
00236                                                 {       
00237                                                         value = (it.get());
00238                                                         if (value > MaxInputValue)
00239                                                         {
00240                                                                 value = MaxInputValue;
00241                                                         }
00242                                                         *(T *)pt = _F(value); 
00243                                                         pt += stride;
00244                                                         it.advance();
00245                                                 }
00246                                         }
00247                                         else
00248                                         {
00249                                                 while (numAttrib --)
00250                                                 {
00251                                                         float value =  _NbCycles * (it.get());
00252                                                         if (value > MaxInputValue)
00253                                                         {
00254                                                                 value = MaxInputValue;
00255                                                         }                                                                                                               
00256                                                         *(T *)pt = _F(value); 
00257                                                         pt += stride;
00258                                                         it.advance();
00259                                                 }       
00260                                         }
00261                                 }
00262                         }
00263                         else
00264                         {
00265                                 // the fastest case : it match the particle's life perfeclty
00266 
00267                                 if (_NbCycles == 1)
00268                                 {
00269                                         while (numAttrib --)
00270                                         {
00271                                                 *(T *)pt = _F(it.get()); 
00272                                                 pt += stride;
00273                                                 it.advance();
00274                                         }
00275                                 }
00276                                 else
00277                                 {
00278                                         // the particle won't cover the whole pattern durin his life
00279                                         while (numAttrib --)
00280                                         {
00281                                                 *(T *)pt = _F(_NbCycles  * (it.get())); 
00282                                                 pt += stride;
00283                                                 it.advance();
00284                                         }
00285                                 }
00286                         }                                               
00287                 }
00288 
00293                  template <typename It> void make4ByIterator(It it,
00294                                                                                                          void *tab,
00295                                                                                                          uint32 stride,
00296                                                                                                      uint32 numAttrib,
00297                                                                                                          bool canOverlapOne) const
00298                  {
00299                         
00300 
00301                         uint8 *pt = (uint8 *) tab;
00302 
00303 
00304                         // first precompute the various strides (stride * 2, 3 and 4)
00305                         // const uint32 stride2 = stride << 1, stride3 = stride + stride2, stride4 = stride2 << 1;
00306 
00307                         const uint32 stride2 = stride << 1;
00308 
00309                         if (_NbCycles > 1 || canOverlapOne)
00310                         {
00311                                 
00312                                 if (!_Clamp)
00313                                 {
00314                                         if (_NbCycles == 1)
00315                                         {                       
00316                                                 while (numAttrib --)
00317                                                 {               
00318                                                         // fill 4 attrib with the same value at once 
00319                                                         //*(T *)pt = *(T *)(pt + stride) = *(T *)(pt + stride2)  = *(T *)(pt + stride3) = _F(OptFastFractionnalPart(it.get()));         
00320                                                         *(T *) pt = _F(OptFastFractionnalPart(it.get()));
00321                                                         *(T *) (pt + stride) = *(T *) pt;
00322                                                         pt += stride;
00323                                                         *(T *) (pt + stride) = *(T *) pt;
00324                                                         pt += stride;
00325                                                         *(T *) (pt + stride) = *(T *) pt;
00326                                                         pt += stride2;                                                  
00327                                                         it.advance();
00328                                                 }
00329                                         }
00330                                         else
00331                                         {                       
00332                                                 while (numAttrib --)
00333                                                 {               
00334                                                         const float time =  _NbCycles * (it.get());
00335                                                         // fill 4 attrib with the same value at once 
00336                                                         //*(T *)pt = *(T *)(pt + stride) = *(T *)(pt + stride2)  = *(T *)(pt + stride3) = _F(OptFastFractionnalPart(time));             
00337                                                         *(T *) pt =     _F(OptFastFractionnalPart(time));
00338                                                         *(T *) (pt + stride) = *(T *) pt;
00339                                                         pt += stride;
00340                                                         *(T *) (pt + stride) = *(T *) pt;
00341                                                         pt += stride;
00342                                                         *(T *) (pt + stride) = *(T *) pt;
00343                                                         pt += stride2;                                                  
00344                                                 
00345                                                         it.advance();
00346                                                 }
00347                                         }
00348                                 }
00349                                 else
00350                                 {
00351                                         float value;
00352 
00353                                         if (_NbCycles == 1)
00354                                         {                       
00355                                                 while (numAttrib --)
00356                                                 {               
00357                                                         value = it.get();
00358                                                         if (value > MaxInputValue)
00359                                                         {
00360                                                                 value = MaxInputValue;
00361                                                         }
00362                                                         // fill 4 attrib with the same value at once 
00363                                                         //*(T *)pt = *(T *)(pt + stride) = *(T *)(pt + stride2)  = *(T *)(pt + stride3) = _F(value);            
00364                                                         *(T *) pt =     _F(value);
00365                                                         *(T *) (pt + stride) = *(T *) pt;
00366                                                         pt += stride;
00367                                                         *(T *) (pt + stride) = *(T *) pt;
00368                                                         pt += stride;
00369                                                         *(T *) (pt + stride) = *(T *) pt;
00370                                                         pt += stride2;                                                  
00371                                                 
00372                                                         it.advance();
00373                                                 }
00374                                         }
00375                                         else
00376                                         {                       
00377                                                 while (numAttrib --)
00378                                                 {               
00379                                                         value =   _NbCycles * (it.get());
00380                                                         if (value > MaxInputValue)
00381                                                         {
00382                                                                 value = MaxInputValue;
00383                                                         }
00384                                                         // fill 4 attrib with the same value at once 
00385                                                         //*(T *)pt = *(T *)(pt + stride) = *(T *)(pt + stride2)  = *(T *)(pt + stride3) = _F(value);            
00386                                                         *(T *) pt =     _F(value);
00387                                                         *(T *) (pt + stride) = *(T *) pt;
00388                                                         pt += stride;
00389                                                         *(T *) (pt + stride) = *(T *) pt;
00390                                                         pt += stride;
00391                                                         *(T *) (pt + stride) = *(T *) pt;
00392                                                         pt += stride2;                                                  
00393                                                         //pt += stride4; // advance of 4 
00394                                                         it.advance();
00395                                                 }
00396                                         }                                       
00397                                 }
00398                         }
00399                         else
00400                         {
00401                                 // the fastest case : it match the particle's life perfeclty
00402 
00403                                 if (_NbCycles == 1)
00404                                 {
00405                                         while (numAttrib --)
00406                                         {               
00407                                                 // fill 4 attrib with the same value at once 
00408                                                 //*(T *)pt = *(T *)(pt + stride) = *(T *)(pt + stride2)  = *(T *)(pt + stride3) = _F(it.get());         
00409                                                 *(T *) pt =     _F(it.get());
00410                                                 *(T *) (pt + stride) = *(T *) pt;
00411                                                 pt += stride;
00412                                                 *(T *) (pt + stride) = *(T *) pt;
00413                                                 pt += stride;
00414                                                 *(T *) (pt + stride) = *(T *) pt;
00415                                                 pt += stride2;                                                  
00416 
00417                                                 //pt += stride4; // advance of 4 
00418                                                 it.advance();
00419                                         }
00420                                 }
00421                                 else
00422                                 {
00423                                         // the particle won't cover the whole pattern durin his life
00424 
00425                                         while (numAttrib --)
00426                                         {               
00427                                                 // fill 4 attrib with the same value at once 
00428                                                 *(T *) pt =     _F(_NbCycles * it.get());
00429                                                 *(T *) (pt + stride) = *(T *) pt;
00430                                                 pt += stride;
00431                                                 *(T *) (pt + stride) = *(T *) pt;
00432                                                 pt += stride;
00433                                                 *(T *) (pt + stride) = *(T *) pt;
00434                                                 pt += stride2;  
00435                                                 //*(T *)pt = *(T *)(pt + stride) = *(T *)(pt + stride2)  = *(T *)(pt + stride3) = _F(_NbCycles * it.get());             
00436                                                 //pt += stride4; // advance of 4 
00437                                                 it.advance();
00438                                         }
00439                                 }
00440                         }       
00441                  }
00442 
00443 
00448                  template <typename It> void makeNByIterator(It it, void *tab, uint32 stride, uint32 numAttrib
00449                                                                                                   , uint32 nbReplicate, bool canOverlapOne) const
00450                  {
00451                                 
00452                                 nlassert(nbReplicate > 1);                              
00453 
00454                                 uint8 *pt = (uint8 *) tab;
00455 
00456                                 // loop counter
00457                                 uint k;
00458 
00459 
00460                                 if (_NbCycles > 1 || canOverlapOne)
00461                                 {
00462                                         
00463                                         if (!_Clamp)
00464                                         {
00465                                                 if (_NbCycles == 1)
00466                                                 {                       
00467                                                         while (numAttrib --)
00468                                                         {               
00469                                                                 // fill 4 attrib with the same value at once 
00470                                                                 *(T *)pt = _F(OptFastFractionnalPart(it.get()));                                                
00471                                                                 k = nbReplicate - 1;
00472                                                                 do 
00473                                                                 {
00474                                                                         *(T *) (pt + stride) = *(T *) pt;
00475                                                                         pt += stride;
00476                                                                 }
00477                                                                 while (--k);
00478                                                                 pt += stride;
00479                                                                 it.advance();
00480                                                         }
00481                                                 }
00482                                                 else
00483                                                 {                       
00484                                                         while (numAttrib --)
00485                                                         {               
00486                                                                 const float time =  _NbCycles * (it.get());
00487                                                                 // fill 4 attrib with the same value at once 
00488                                                                 *(T *)pt = _F(OptFastFractionnalPart(time));                                    
00489                                                                 k = nbReplicate - 1;
00490                                                                 do 
00491                                                                 {
00492                                                                         *(T *) (pt + stride) = *(T *) pt;
00493                                                                         pt += stride;
00494                                                                 }
00495                                                                 while (--k);
00496                                                                 pt += stride;
00497                                                                 it.advance();
00498                                                         }
00499                                                 }
00500                                         }
00501                                         else
00502                                         {
00503                                                 float value;
00504                                                 // clamping is on
00505                                                 if (_NbCycles == 1)
00506                                                 {                       
00507                                                         while (numAttrib --)
00508                                                         {               
00509                                                                 // fill 4 attrib with the same value at once 
00510                                                                 value = it.get();
00511                                                                 if (value > MaxInputValue)
00512                                                                 {
00513                                                                         value = MaxInputValue;
00514                                                                 }
00515                                                                 *(T *)pt = _F(value);                                           
00516                                                                 k = nbReplicate - 1;
00517                                                                 do 
00518                                                                 {
00519                                                                         *(T *) (pt + stride) = *(T *) pt;
00520                                                                         pt += stride;
00521                                                                 }
00522                                                                 while (--k);
00523                                                                 pt += stride;
00524                                                                 it.advance();
00525                                                         }
00526                                                 }
00527                                                 else
00528                                                 {                       
00529                                                         while (numAttrib --)
00530                                                         {               
00531                                                                 value =  _NbCycles * (it.get());
00532                                                                 if (value > MaxInputValue)
00533                                                                 {
00534                                                                         value = MaxInputValue;
00535                                                                 }
00536                                                                 // fill 4 attrib with the same value at once 
00537                                                                 *(T *)pt = _F(value);                                   
00538                                                                 k = nbReplicate - 1;
00539                                                                 do 
00540                                                                 {
00541                                                                         *(T *) (pt + stride) = *(T *) pt;
00542                                                                         pt += stride;
00543                                                                 }
00544                                                                 while (--k);
00545                                                                 pt += stride;
00546                                                                 it.advance();
00547                                                         }
00548                                                 }
00549                                         }
00550                                 }
00551                                 else
00552                                 {
00553                                         // the fastest case : it match the particle's life perfeclty
00554 
00555                                         if (_NbCycles == 1)
00556                                         {
00557                                                 while (numAttrib --)
00558                                                 {               
00559                                                         // fill 4 attrib with the same value at once 
00560                                                         *(T *)pt = _F(it.get());                                                
00561                                                         k = nbReplicate - 1;
00562                                                         do 
00563                                                         {
00564                                                                 *(T *) (pt + stride) = *(T *) pt;
00565                                                                 pt += stride;
00566                                                         }
00567                                                         while (--k);
00568                                                         pt += stride;
00569                                                         it.advance();
00570                                                 }
00571                                         }
00572                                         else
00573                                         {
00574                                                 // the particle won't cover the whole pattern durin his life
00575 
00576                                                 while (numAttrib --)
00577                                                 {               
00578                                                         // fill 4 attrib with the same value at once 
00579                                                         *(T *)pt =  _F(_NbCycles * it.get());                                   
00580                                                         k = nbReplicate - 1;
00581                                                         do 
00582                                                         {
00583                                                                 *(T *) (pt + stride) = *(T *) pt;
00584                                                                 pt += stride;
00585                                                         }
00586                                                         while (--k);
00587                                                         pt += stride;
00588                                                         it.advance();
00589                                                 }
00590                                         }
00591                                 }       
00592                         }
00593 
00594         
00595                         /* template <typename T, class F> */
00596                         void /*CPSAttribMakerT<T, F>::*/ *make(CPSLocated *loc,
00597                                                                                           uint32 startIndex,
00598                                                                                           void *tab,
00599                                                                                           uint32 stride,
00600                                                                                           uint32 numAttrib,
00601                                                                                           bool allowNoCopy /* = false */,
00602                                                                                           uint32 srcStep /*= (1 << 16)*/
00603                                                                                          ) const
00604                         {
00605 
00606                                 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());
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);
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);
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);
00640                                                 }
00641                                                 break;
00642                                                 case CPSInputType::attrUniformRandom:   
00643                                                 {
00644                                                         CRandomIterator it;
00645                                                         makeByIterator(it, tab, stride, numAttrib, true);
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);
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->isInSystemBasis());                       
00661                                                         makeByIterator(it, tab, stride, numAttrib, false);
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->isInSystemBasis());                       
00670                                                         makeByIterator(it, tab, stride, numAttrib, false);
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->isInSystemBasis());                       
00679                                                         makeByIterator(it, tab, stride, numAttrib, false);
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->isInSystemBasis());                       
00688                                                         makeByIterator(it, tab, stride, numAttrib, false);
00689                                                 }
00690                                                 break;
00691                                         }
00692 
00693                                         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());
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);
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);
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);
00728                                                 }
00729                                                 break;
00730                                                 case CPSInputType::attrUniformRandom:   
00731                                                 {
00732                                                         CRandomIterator it;
00733                                                         makeByIterator(it, tab, stride, numAttrib, true);
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);
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->isInSystemBasis());                       
00749                                                         makeByIterator(it, tab, stride, numAttrib, false);
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->isInSystemBasis());                       
00758                                                         makeByIterator(it, tab, stride, numAttrib, false);
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->isInSystemBasis());                       
00767                                                         makeByIterator(it, tab, stride, numAttrib, false);
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->isInSystemBasis());                       
00776                                                         makeByIterator(it, tab, stride, numAttrib, false);
00777                                                 }
00778                                                 break;
00779                                         }
00780 
00781                                         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                                 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->isInSystemBasis());                       
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->isInSystemBasis());                       
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->isInSystemBasis());                       
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->isInSystemBasis());                       
00880                                                         make4ByIterator(it, tab, stride, numAttrib, false);
00881                                                 }
00882                                                 break;
00883                                         }
00884 
00885                                         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->isInSystemBasis());                       
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->isInSystemBasis());                       
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->isInSystemBasis());                       
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->isInSystemBasis());                       
00966                                                         make4ByIterator(it, tab, stride, numAttrib, false);
00967                                                 }
00968                                                 break;
00969                                         }
00970 
00971                                         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                                 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->isInSystemBasis());                       
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->isInSystemBasis());                       
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->isInSystemBasis());                       
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->isInSystemBasis());                       
01068                                                         makeNByIterator(it, tab, stride, numAttrib, nbReplicate, false);
01069                                                 }
01070                                                 break;
01071                                         }
01072 
01073                                         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->isInSystemBasis());                       
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->isInSystemBasis());                       
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->isInSystemBasis());                       
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->isInSystemBasis());                       
01154                                                         makeNByIterator(it, tab, stride, numAttrib, nbReplicate, false);
01155                                                 }
01156                                                 break;
01157                                         }
01158 
01159                                         OptFastFloorEnd();                              
01160                                 }       
01161                         }
01162 
01163 
01164 };
01165 
01167 // implementation of CPSAttribMakerT methods //
01169 
01170 
01171 template <typename T, class F> 
01172 T  CPSAttribMakerT<T, F>::get(CPSLocated *loc, uint32 index)
01173 {       
01174         OptFastFloorBegin();
01175         T result;
01176         nlassert(loc);
01177         switch (_InputType.InputType)
01178         {
01179                 case CPSInputType::attrDate:    
01180                 {
01181                         float v = _NbCycles * loc->getTime()[index];
01182                         if (_Clamp)
01183                         {
01184                                 if (v > MaxInputValue) v = MaxInputValue;
01185                         }
01186 
01187                         result = _F(OptFastFractionnalPart(v));
01188                 }
01189                 break;
01190                 case CPSInputType::attrInverseMass:     
01191                 {
01192                         float v = _NbCycles * loc->getInvMass()[index];
01193                         if (_Clamp)
01194                         {
01195                                 if (v > MaxInputValue) v = MaxInputValue;
01196                         }
01197                         result =  _F(OptFastFractionnalPart(v));
01198                 }
01199                 break;          
01200                 case CPSInputType::attrSpeed:   
01201                 {
01202                         float v = _NbCycles * loc->getSpeed()[index].norm();
01203                         if (_Clamp)
01204                         {
01205                                 if (v > MaxInputValue) v = MaxInputValue;
01206                         }
01207                         result = _F(OptFastFractionnalPart(v));
01208                 }
01209                 break;
01210 
01211                 case CPSInputType::attrPosition:        
01212                 {
01213                         float v = _NbCycles * loc->getPos()[index].norm();
01214                         if (_Clamp)
01215                         {
01216                                 if (v > MaxInputValue) v = MaxInputValue;
01217                         }
01218                         result = _F(OptFastFractionnalPart(v));
01219                 }
01220                 break;
01221                 case CPSInputType::attrUniformRandom:   
01222                 {
01223                         result =  _F(float(rand() * (1 / double(RAND_MAX))));
01224                 }
01225                 break;
01226                 case CPSInputType::attrUserParam:
01227                 {                       
01228                         float v = _NbCycles * loc->getUserParam(_InputType.UserParamNum); 
01229                         if (_Clamp)
01230                         {
01231                                 if (v > MaxInputValue) v = MaxInputValue;
01232                         }
01233                         result = _F(v);
01234                 }
01235                 break;
01236                 case CPSInputType::attrLOD:
01237                 {       
01238                         static NLMISC::CVector lodVect;
01239                         float lodOffset;                        
01240                         loc->getLODVect(lodVect, lodOffset, loc->isInSystemBasis());                                            
01241                         float r = fabsf(loc->getPos()[index] * lodVect + lodOffset);
01242                         r = _NbCycles * r > MaxInputValue ? MaxInputValue : r;                  
01243                         if (_Clamp)
01244                         {
01245                                 result = _F(r > MaxInputValue ? MaxInputValue : r);
01246                         }
01247                         else result = _F(r - uint32(r));                                                
01248                 }
01249                 break;
01250                 case CPSInputType::attrSquareLOD:
01251                 {       
01252                         static NLMISC::CVector lodVect;
01253                         float lodOffset;                        
01254                         loc->getLODVect(lodVect, lodOffset, loc->isInSystemBasis());                                            
01255                         float r = loc->getPos()[index] * lodVect + lodOffset;
01256                         r = _NbCycles * (r > MaxInputValue ? MaxInputValue : r * r);
01257 
01258                         if (_Clamp)
01259                         {
01260                                 result = _F(r > MaxInputValue ? MaxInputValue : r);
01261                         }
01262                         else result = _F(r - uint32(r));                                                
01263                 }
01264                 break;
01265                 case CPSInputType::attrClampedLOD:
01266                 {       
01267                         static NLMISC::CVector lodVect;
01268                         float lodOffset;                        
01269                         loc->getLODVect(lodVect, lodOffset, loc->isInSystemBasis());                                            
01270 
01271                         float r = loc->getPos()[index] * lodVect + lodOffset;
01272                         if (r < 0) 
01273                         {
01274                                 result = _F(MaxInputValue);
01275                                 break;
01276                         }
01277                         r = _NbCycles * (r > MaxInputValue ? MaxInputValue : r);                                                                        
01278                         if (_Clamp)
01279                         {
01280                                 result = _F(r > MaxInputValue ? MaxInputValue : r);
01281                         }
01282                         else result = _F(r - uint32(r));                                                
01283                 }
01284                 break;
01285                 case CPSInputType::attrClampedSquareLOD:
01286                 {       
01287                         static NLMISC::CVector lodVect;
01288                         float lodOffset;                        
01289                         loc->getLODVect(lodVect, lodOffset, loc->isInSystemBasis());                                            
01290 
01291                         float r = loc->getPos()[index] * lodVect + lodOffset;
01292                         if (r < 0) 
01293                         {
01294                                 result = _F(MaxInputValue);
01295                                 break; 
01296                         }
01297                         r = _NbCycles * (r > MaxInputValue ? MaxInputValue : r * r);                                                                    
01298                         if (_Clamp)
01299                         {
01300                                 result = _F(r > MaxInputValue ? MaxInputValue : r);
01301                         }
01302                         else result = _F(r - uint32(r));                                                
01303                 }
01304                 break;  
01305                 default:
01306                         result = T();
01307                 break;          
01308         }
01309 
01310         OptFastFloorEnd();
01311         return result;
01312         
01313 }
01314 
01315 
01324 template <typename T> class CPSAttribMakerMemory : public CPSAttribMaker<T>
01325 {
01326 public: 
01327 
01330         CPSAttribMakerMemory() : CPSAttribMaker<T>(1.f), _Scheme(NULL)
01331         {
01332                 _HasMemory = true;
01333         }
01334 
01353     void setDefaultValue(T defaultValue) { _DefaultValue = defaultValue;}
01354 
01356         T getDefaultValue(void) const { return _DefaultValue; }
01357 
01358 
01359 
01363         void setScheme(CPSAttribMaker<T> *scheme)
01364         {
01365                 nlassert(scheme);
01366                 if (_Scheme) delete _Scheme;
01367                 _Scheme = scheme;
01368                 if (_Scheme->hasMemory())
01369                 {
01370                         _Scheme->resize(_T.getMaxSize(), _T.getSize());
01371                 }
01372         }
01373 
01375         CPSAttribMaker<T> *getScheme(void) { return _Scheme; }
01377         const CPSAttribMaker<T> *getScheme(void) const { return _Scheme; }
01378 
01379 
01380         // copy ctor
01381         CPSAttribMakerMemory(const CPSAttribMakerMemory &src) : CPSAttribMaker<T>(src) // parent copy ctor
01382         {
01383                 nlassert(src._Scheme);
01384                 std::auto_ptr<CPSAttribMaker<T> > s(NLMISC::safe_cast<CPSAttribMaker<T> *>(src._Scheme->clone()));
01385                 this->_T = src._T;
01386                 this->_DefaultValue = src._DefaultValue;
01387                 this->_Scheme = s.release();
01388         }
01390         ~CPSAttribMakerMemory()
01391         {
01392                 if (_Scheme)
01393                 {
01394                         delete _Scheme;
01395                 }
01396         }
01397 
01399         virtual T get(CPSLocated *loc, uint32 index) 
01400         { 
01401                 if (index < _T.getSize()) return _T[index];
01402                 else return _DefaultValue;
01403         }
01404 
01406         virtual void *make(CPSLocated *loc,
01407                                            uint32 startIndex,
01408                                            void *output,
01409                                            uint32 stride,
01410                                            uint32 numAttrib,
01411                                            bool allowNoCopy = false,
01412                                            uint32 srcStep = (1 << 16)
01413                                           ) const
01414         {
01415                 if (!numAttrib) return output;
01416                 void *tab = output;
01417                 if (!allowNoCopy || srcStep != (1 << 16) || sizeof(T) != stride)
01418                 {
01419                         // we just copy what we have memorized
01420                         if (srcStep == (1 << 16))
01421                         {
01422                                 CPSAttrib<T>::const_iterator it = _T.begin() + startIndex, endIt = _T.begin() + startIndex + numAttrib;
01423                                 do
01424                                 {
01425                                         *(T *) tab = *it;
01426                                         ++it;
01427                                         tab = (uint8 *) tab + stride;
01428                                 }
01429                                 while (it != endIt);
01430                         }
01431                         else // no constant step
01432                         {
01433                                 uint32 fpIndex = startIndex * srcStep;
01434                                 CPSAttrib<T>::const_iterator startIt = _T.begin();
01435                                 while (numAttrib --)
01436                                 {
01437                                         *(T *) tab = *(startIt + (fpIndex >> 16));                                      
01438                                         tab = (uint8 *) tab + stride;
01439                                         fpIndex += srcStep;
01440                                 }                               
01441                         }
01442                         return output;
01443                 }
01444                 else
01445                 {
01446                         // the caller will read data directly in the vector ...
01447                         return (void *) &(*(_T.begin() + startIndex));
01448                 }
01449         }       
01450 
01452         virtual void make4(CPSLocated *loc,
01453                                            uint32 startIndex,
01454                                            void *tab,
01455                                            uint32 stride,
01456                                            uint32 numAttrib,
01457                                            uint32 srcStep = (1 << 16)
01458                                            ) const
01459         {
01460                 // we just copy what we have memorized
01461                 if (srcStep == (1 << 16))
01462                 {
01463                         CPSAttrib<T>::const_iterator it = _T.begin() + startIndex, endIt = _T.begin() + startIndex + numAttrib;
01464                         while (it != endIt)
01465                         {
01466                                 *(T *) tab = *it;
01467                                 tab = (uint8 *) tab + stride;
01468                                 *(T *) tab = *it;
01469                                 tab = (uint8 *) tab + stride;
01470                                 *(T *) tab = *it;
01471                                 tab = (uint8 *) tab + stride;
01472                                 *(T *) tab = *it;
01473                                 tab = (uint8 *) tab + stride;
01474                                 ++it;                   
01475                         }
01476                 }
01477                 else
01478                 {
01479                         uint32 fpIndex = startIndex * srcStep;
01480                         CPSAttrib<T>::const_iterator startIt = _T.begin();
01481                         while (numAttrib --)
01482                         {
01483                                 *(T *) tab = *(startIt + (fpIndex >> 16));                                      
01484                                 *(T *) ((uint8 *) tab + stride) = *(T *) tab;
01485                                 tab = (uint8 *) tab + stride;
01486                                 *(T *) ((uint8 *) tab + stride) = *(T *) tab;
01487                                 tab = (uint8 *) tab + stride;
01488                                 *(T *) ((uint8 *) tab + stride) = *(T *) tab;
01489 
01490                                 tab = (uint8 *) tab + stride + stride;
01491                                 fpIndex += srcStep;
01492                         }       
01493                 }
01494         }
01495 
01497         virtual void makeN(CPSLocated *loc,
01498                                            uint32 startIndex,
01499                                            void *tab,
01500                                            uint32 stride,
01501                                            uint32 numAttrib,
01502                                            uint32 nbReplicate,
01503                                            uint32 srcStep = (1 << 16)
01504                                           ) const
01505         {
01506                 // we just copy what we have memorized
01507                 uint k;
01508                 CPSAttrib<T>::const_iterator it = _T.begin() + startIndex, endIt = _T.begin() + startIndex + numAttrib;
01509                 if (srcStep == (1 << 16))
01510                 {
01511                         while (it != endIt)
01512                         {
01513                         
01514                                 for (k = 0; k < nbReplicate; ++k)
01515                                 {
01516                                         *(T *) tab = *it;
01517                                         tab = (uint8 *) tab + stride;
01518                                 }                       
01519                                 ++it;
01520                         }
01521                 }
01522                 else
01523                 {
01524                         uint32 fpIndex = startIndex * srcStep;
01525                         CPSAttrib<T>::const_iterator startIt = _T.begin();      
01526 
01527                         while (numAttrib --)
01528                         {               
01529                                 *(T *) tab = *(startIt + (fpIndex >> 16));
01530                                 for (k = 1; k < nbReplicate; ++k)
01531                                 {
01532                                         *(T *) ((uint8 *) tab + stride) = *(T *) tab;
01533                                         tab = (uint8 *) tab + stride;
01534                                 }
01535                                 tab = (uint8 *) tab + stride;
01536                                 fpIndex += srcStep;
01537                         }
01538 
01539                 }               
01540         }
01541 
01543         virtual void serial(NLMISC::IStream &f) throw(NLMISC::EStream)
01544         {
01545                 
01546                 f.serialVersion(1);
01547                 CPSAttribMaker<T>::serial(f);
01548                 if (f.isReading())
01549                 {
01550                         if (_Scheme) delete _Scheme;
01551                 }
01552                 f.serialPolyPtr(_Scheme);
01553                 f.serial(_T);
01554                 f.serial(_DefaultValue);
01555         }
01556         
01558         virtual void deleteElement(uint32 index) 
01559         { 
01560                 nlassert(_Scheme); // you should have called setScheme !
01561                 _T.remove(index); 
01562                 if (_Scheme->hasMemory())
01563                 {
01564                         _Scheme->deleteElement(index);
01565                 }
01566         }
01568         virtual void newElement(CPSLocated *emitterLocated, uint32 emitterIndex) 
01569         { 
01570                 nlassert(_Scheme); // you should have called setScheme !
01571 
01572                 // we should create the contained scheme before this one if it has memory...
01573                 if (_Scheme->hasMemory())
01574                 {
01575                         _Scheme->newElement(emitterLocated, emitterIndex);
01576                 }
01577 
01578                 if (emitterLocated)
01579                 {
01580                         _T.insert(_Scheme->get(emitterLocated, emitterIndex));
01581                 }
01582                 else
01583                 {                       
01588                         _T.insert(_DefaultValue);
01589                 }               
01590         }
01591         virtual void resize(uint32 capacity, uint32 nbPresentElements)
01592         {
01593                 nlassert(capacity < (1 << 16));
01594                 _T.resize(capacity);
01595                 if (nbPresentElements > _T.getSize())
01596                 {
01597                         while (_T.getSize() != nbPresentElements)
01598                         {
01599                                 _T.insert(_DefaultValue);
01600                         }
01601                 }
01602                 else if (nbPresentElements < _T.getSize())
01603                 {
01604                         while (_T.getSize() != nbPresentElements)
01605                         {
01606                                 _T.remove(_T.getSize() - 1);
01607                         }
01608                 }
01609 
01610 
01611                 if (_Scheme && _Scheme->hasMemory())
01612                 {
01613                         _Scheme->resize(capacity,   nbPresentElements);
01614                 }
01615 
01616         }       
01617 
01618 
01619 protected:
01620         // the attribute we memorize
01621         CPSAttrib<T> _T;
01622 
01623         // the default value for generation (when no emitter can be used)
01624         T _DefaultValue;
01625 
01630         CPSAttribMaker<T> *_Scheme;
01631 
01632 };
01633 
01634 
01635 
01636 } // NL3D
01637 
01638 
01639 #endif // NL_PS_ATTRIB_MAKER_HELPER_H
01640 
01641 /* End of ps_attrib_maker_helper.h */