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