00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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"
00032 #include "ps_attrib_maker_iterators.h"
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
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)
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
00179 CPSInputType _InputType;
00180
00181
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
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
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
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
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
00305
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
00319
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
00336
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
00363
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
00385
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
00394 it.advance();
00395 }
00396 }
00397 }
00398 }
00399 else
00400 {
00401
00402
00403 if (_NbCycles == 1)
00404 {
00405 while (numAttrib --)
00406 {
00407
00408
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
00418 it.advance();
00419 }
00420 }
00421 else
00422 {
00423
00424
00425 while (numAttrib --)
00426 {
00427
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
00436
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
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
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
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
00505 if (_NbCycles == 1)
00506 {
00507 while (numAttrib --)
00508 {
00509
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
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
00554
00555 if (_NbCycles == 1)
00556 {
00557 while (numAttrib --)
00558 {
00559
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
00575
00576 while (numAttrib --)
00577 {
00578
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
00596 void *make(CPSLocated *loc,
00597 uint32 startIndex,
00598 void *tab,
00599 uint32 stride,
00600 uint32 numAttrib,
00601 bool allowNoCopy ,
00602 uint32 srcStep
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
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());
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
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 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
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
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 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
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
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
01381 CPSAttribMakerMemory(const CPSAttribMakerMemory &src) : CPSAttribMaker<T>(src)
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
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
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
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
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
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);
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);
01571
01572
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
01621 CPSAttrib<T> _T;
01622
01623
01624 T _DefaultValue;
01625
01630 CPSAttribMaker<T> *_Scheme;
01631
01632 };
01633
01634
01635
01636 }
01637
01638
01639 #endif // NL_PS_ATTRIB_MAKER_HELPER_H
01640
01641