# 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_bin_op_inline.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 
00027 #ifndef NL_PS_ATTRIB_MAKER_BIN_OP_H
00028         #error Do not include this file! include ps_attrib_maker_bin_op_inline instead!
00029 #endif
00030 
00031 #ifndef NL_PS_ATTRIB_MAKER_BIN_OP_INLINE_H
00032 #define NL_PS_ATTRIB_MAKER_BIN_OP_INLINE_H
00033 
00034 
00035 
00036 namespace NL3D {
00037 
00038 
00044 template <class T>
00045 inline T PSBinOpModulate(T arg1, T arg2) { return arg1 * arg2; }
00046 template <class T>
00047 inline T PSBinOpAdd(T arg1, T arg2) { return arg1 + arg2; }
00048 template <class T>
00049 inline T PSBinOpSubtract(T arg1, T arg2) { return arg1 - arg2; }
00050 
00051 template <>
00052 inline CPlaneBasis PSBinOpModulate(CPlaneBasis p1, CPlaneBasis p2)
00053 {
00054         // we compute p1 * p2
00055         NLMISC::CVector z = p1.X ^ p1.Y;
00056         CPlaneBasis r;
00057         r.X.x = p2.X.x * p1.X.x + p2.X.y * p1.Y.x + p2.X.z * z.x;
00058         r.X.y = p2.X.x * p1.X.y + p2.X.y * p1.Y.y + p2.X.z * z.y;
00059         r.X.z = p2.X.x * p1.X.z + p2.X.y * p1.Y.z + p2.X.z * z.z;
00060 
00061         r.Y.x = p2.Y.x * p1.X.x + p2.Y.y * p1.Y.x + p2.Y.z * z.x;
00062         r.Y.y = p2.Y.x * p1.X.y + p2.Y.y * p1.Y.y + p2.Y.z * z.y;
00063         r.Y.z = p2.Y.x * p1.X.z + p2.Y.y * p1.Y.z + p2.Y.z * z.z;
00064 
00065         return r;
00066 
00067 }
00068 template <>
00069 inline CPlaneBasis PSBinOpAdd(CPlaneBasis p1, CPlaneBasis p2)
00070 {
00071         nlassert(0); // not allowed for now
00072         return CPlaneBasis(NLMISC::CVector::Null);
00073 }
00074 template <>
00075 inline CPlaneBasis PSBinOpSubtract(CPlaneBasis p1, CPlaneBasis p2)
00076 {
00077         nlassert(0); // not allowed for now
00078         return CPlaneBasis(NLMISC::CVector::Null);
00079 }
00080 
00081 
00082 
00083  
00084 template <>
00085 inline NLMISC::CRGBA PSBinOpModulate(NLMISC::CRGBA t1, NLMISC::CRGBA t2)
00086 {
00087         NLMISC::CRGBA result;
00088         result.modulateFromColor(t1, t2);
00089         return result;
00090 }
00091 template <>
00092 inline NLMISC::CRGBA PSBinOpAdd(NLMISC::CRGBA t1, NLMISC::CRGBA t2)
00093 {
00094         NLMISC::CRGBA r;
00095         uint S = t1.R + t2.R; if (S > 255) S = 255; r.R = (uint8) S;
00096         S = t1.G + t2.G; if (S > 255) S = 255; r.G = (uint8) S;
00097         S = t1.B + t2.B; if (S > 255) S = 255; r.B = (uint8) S;
00098         return r;
00099 }
00100 template <>
00101 inline NLMISC::CRGBA PSBinOpSubtract(NLMISC::CRGBA t1, NLMISC::CRGBA t2)
00102 {
00103         NLMISC::CRGBA r;
00104         sint S = t1.R - t2.R; if (S < 0) S = 0; r.R = (uint8) S;
00105         S = t1.G - t2.G; if (S < 0) S = 0; r.G = (uint8) S;
00106         S = t1.B - t2.B; if (S < 0) S = 0; r.B = (uint8) S;
00107         return r;
00108 }
00109 
00110 
00112 // CPSAttribMakerBinOp implementation //
00114 
00115 
00116 
00117 //=================================================================================================================
00119 template <class T>
00120 CPSAttribMakerBinOp<T>::CPSAttribMakerBinOp(const CPSAttribMakerBinOp &other) : CPSAttribMaker<T>(other) // parent copy ctor
00121 {       
00122         std::auto_ptr<CPSAttribMaker<T> > a0(NLMISC::safe_cast<CPSAttribMaker<T> *>(other._Arg[0]->clone()))
00123                                                                         , a1(NLMISC::safe_cast<CPSAttribMaker<T> *>(other._Arg[1]->clone()));   
00124         this->_Op =             other._Op;
00125         this->_Size =   other._Size;
00126         this->_MaxSize =  other._MaxSize;
00127         this->_Arg[0] = a0.release();
00128         this->_Arg[1] = a1.release();   
00129 }
00130 
00131 //=================================================================================================================
00132 template <class T>
00133 CPSAttribMakerBinOp<T>::CPSAttribMakerBinOp() : _Op(CPSBinOp::selectArg1), _Size(0), _MaxSize(0)
00134 {
00135         _Arg[0] = _Arg[1] = NULL;
00136         _HasMemory  = true; 
00137 }
00138 
00139 //=================================================================================================================
00140 template <class T>
00141 void CPSAttribMakerBinOp<T>::clean(void) 
00142 {
00143         delete _Arg[0];
00144         delete _Arg[1];
00145 }
00146 
00147 //=================================================================================================================
00148 template <class T>
00149 CPSAttribMakerBinOp<T>::~CPSAttribMakerBinOp() 
00150 {
00151         clean();
00152 }
00153 
00154 //=================================================================================================================
00156 bool CPSAttribMakerBinOp<CPlaneBasis>::supportOp(CPSBinOp::BinOp op) 
00157 { 
00158         return  (op == CPSBinOp::selectArg1 || op == CPSBinOp::selectArg2 || op == CPSBinOp::modulate);
00159 }
00160 
00161 
00162 //=================================================================================================================
00163 template <class T>
00164 T               CPSAttribMakerBinOp<T>::get                       (CPSLocated *loc, uint32 index)
00165 {
00166         switch (_Op)
00167         {
00168                 case CPSBinOp::selectArg1:
00169                         return _Arg[0]->get(loc, index);
00170                 break;
00171                 case CPSBinOp::selectArg2:
00172                         return _Arg[1]->get(loc, index);
00173                 break;
00174                 case CPSBinOp::modulate:
00175                         return PSBinOpModulate(_Arg[0]->get(loc, index), _Arg[1]->get(loc, index));
00176                 break;
00177                 case CPSBinOp::add:
00178                         return PSBinOpAdd(_Arg[0]->get(loc, index), _Arg[1]->get(loc, index));
00179                 break;
00180                 case CPSBinOp::subtract:
00181                         return PSBinOpSubtract(_Arg[0]->get(loc, index), _Arg[1]->get(loc, index));
00182                 break;
00183                 default: break;
00184         }
00185 
00186         nlstop;
00187         return T();
00188 }
00189 
00190 // for private use
00191 void MakePrivate(uint8 * dest, const NLMISC::CRGBA *src1, const NLMISC::CRGBA *src2, uint32 stride, uint32 numAttrib, CPSBinOp::BinOp op);
00192 // for private use
00193 template <class T>
00194 void MakePrivate(uint8 * dest, const T *src1, const T *src2, uint32 stride, uint32 numAttrib, CPSBinOp::BinOp op)
00195 {
00196         uint8 *destEnd = dest + (stride * numAttrib);
00197 
00198         switch (op)
00199         {
00200                 case CPSBinOp::modulate:
00201                 {
00202                         while (dest != destEnd)
00203                         {
00204                                 * (T *) dest = PSBinOpModulate(*src1 ++, *src2 ++);
00205                                 dest += stride;
00206                         }
00207                 }
00208                 break;
00209                 case CPSBinOp::add:
00210                 {
00211                         while (dest != destEnd)
00212                         {
00213                                 * (T *) dest = PSBinOpAdd(*src1 ++, *src2 ++);
00214                                 dest += stride;
00215                         }
00216                 }
00217                 break;
00218                 case CPSBinOp::subtract:
00219                 while (dest != destEnd)
00220                 {
00221                         * (T *) dest = PSBinOpSubtract(*src1 ++, *src2 ++);
00222                         dest += stride;
00223                 }
00224                 break;
00225                 default: break;
00226         }
00227 }
00228 
00229 
00230 //=================================================================================================================
00231 template <class T>
00232 inline void   *CPSAttribMakerBinOp<T>::makePrivate(T *buf1,
00233                                                                                                    T *buf2,
00234                                                                                                    CPSLocated *loc,
00235                                                                                                    uint32 startIndex,
00236                                                                                                    void *tab,
00237                                                                                                    uint32 stride,
00238                                                                                                    uint32 numAttrib,
00239                                                                                                    bool allowNoCopy /* = false */,
00240                                                                                                    uint32 srcStep /* = (1 << 16)*/
00241                                                                                                   ) const
00242 {
00243         uint8 *dest = (uint8 *) tab;
00244         uint leftToDo = numAttrib, toProcess;
00245         nlassert(_Arg[0] && _Arg[1]);   
00246         switch (_Op)
00247         {
00248                 case CPSBinOp::selectArg1:
00249                         return _Arg[0]->make(loc, startIndex, tab, stride, numAttrib, allowNoCopy, srcStep);
00250                         break;
00251                 case CPSBinOp::selectArg2:
00252                         return _Arg[1]->make(loc, startIndex, tab, stride, numAttrib, allowNoCopy, srcStep);
00253                         break;          
00254                 default: break;
00255         }
00256 
00257 
00258 
00259         while (leftToDo)
00260         {
00261                 toProcess = leftToDo > PSBinOpBufSize ? PSBinOpBufSize : leftToDo;
00262                 T *src1 = (T *) _Arg[0]->make(loc, startIndex + (numAttrib - leftToDo), &buf1[0], sizeof(T), toProcess, true, srcStep);
00263                 T *src2 = (T *) _Arg[1]->make(loc, startIndex + (numAttrib - leftToDo), &buf2[0], sizeof(T), toProcess, true, srcStep);
00264                 MakePrivate(dest, src1, src2, stride, toProcess, _Op);          
00265                 leftToDo -= toProcess;
00266         }
00267 
00268         return tab;
00269 }
00270 
00271 //=================================================================================================================
00272 template <class T>
00273 void   *CPSAttribMakerBinOp<T>::make      (CPSLocated *loc,
00274                                                                                    uint32 startIndex,
00275                                                                                    void *tab,
00276                                                                                    uint32 stride,
00277                                                                                    uint32 numAttrib,
00278                                                                                    bool allowNoCopy /* = false */,
00279                                                                                    uint32 srcStep /* = (1 << 16)*/
00280                                                                                   ) const
00281 {
00286         uint8 tab1[PSBinOpBufSize * sizeof(T)];
00287         uint8 tab2[PSBinOpBufSize * sizeof(T)];
00288         return makePrivate((T *) &tab1[0], (T *) &tab2[0], loc, startIndex, tab, stride, numAttrib, allowNoCopy, srcStep);
00289 }
00290 
00291 
00292 // for private use
00293 void Make4Private(uint8 * dest, const NLMISC::CRGBA *src1, const NLMISC::CRGBA *src2, uint32 stride, uint32 numAttrib, CPSBinOp::BinOp op);
00294 
00295 // for private use
00296 template <class T>
00297 void Make4Private(uint8 * dest, const T *src1, const T *src2, uint32 stride, uint32 numAttrib, CPSBinOp::BinOp op)
00298 {
00299         const uint stride2 = stride << 1, stride3 = stride + stride2, stride4 = stride2 << 1; 
00300         uint8 *destEnd = dest + ((stride<<2) * numAttrib);
00301         switch (op)
00302         {
00303                 case CPSBinOp::modulate:
00304                 {
00305                         while (dest != destEnd)
00306                         {
00307                                 // compute one value, and duplicate if 4 times
00308                                 * (T *) dest = PSBinOpModulate(*src1 ++, *src2 ++);
00309                                 * (T *) (dest + stride) = * (T *) dest;
00310                                 * (T *) (dest + stride2) = * (T *) dest;
00311                                 * (T *) (dest + stride3) = * (T *) dest;
00312                                 dest += stride4;
00313                         }
00314                 }
00315                 break;
00316                 case CPSBinOp::add:
00317                 {
00318                         while (dest != destEnd)
00319                         {
00320                                 // compute one value, and duplicate if 4 times
00321                                 * (T *) dest = PSBinOpAdd(*src1 ++, *src2 ++);
00322                                 * (T *) (dest + stride) = * (T *) dest;
00323                                 * (T *) (dest + stride2) = * (T *) dest;
00324                                 * (T *) (dest + stride3) = * (T *) dest;
00325                                 dest += stride4;
00326                         }
00327                 }
00328                 break;
00329                 case CPSBinOp::subtract:
00330                         while (dest != destEnd)
00331                         {
00332                                 // compute one value, and duplicate if 4 times
00333                                 * (T *) dest = PSBinOpSubtract(*src1 ++, *src2 ++);
00334                                 * (T *) (dest + stride) = * (T *) dest;
00335                                 * (T *) (dest + stride2) = * (T *) dest;
00336                                 * (T *) (dest + stride3) = * (T *) dest;
00337                                 dest += stride4;
00338                         }
00339                 break;
00340                 default: break;
00341         }
00342 }
00343 
00344 //=================================================================================================================
00345 template <class T>
00346 inline void    CPSAttribMakerBinOp<T>::make4Private(T *buf1,
00347                                                                                                     T *buf2,
00348                                                                                                         CPSLocated *loc,
00349                                                                                                         uint32 startIndex,
00350                                                                                                         void *tab,
00351                                                                                                         uint32 stride,
00352                                                                                                         uint32 numAttrib,
00353                                                                                                         uint32 srcStep /* = (1 << 16)*/
00354                                                                                                    ) const
00355 {       
00356         uint8 *dest = (uint8 *) tab;
00357         uint leftToDo = numAttrib, toProcess;
00358         nlassert(_Arg[0] && _Arg[1]);   
00359         switch (_Op)
00360         {
00361                 case CPSBinOp::selectArg1:
00362                         _Arg[0]->make4(loc, startIndex, tab, stride, numAttrib, srcStep);
00363                         return;
00364                         break;
00365                 case CPSBinOp::selectArg2:
00366                         _Arg[1]->make4(loc, startIndex, tab, stride, numAttrib, srcStep);
00367                         return;
00368                         break;          
00369                 default: break;
00370         }
00371 
00372         while (leftToDo)
00373         {
00374                 toProcess = leftToDo > PSBinOpBufSize ? PSBinOpBufSize : leftToDo;
00375                 T *src1 = (T *) _Arg[0]->make(loc, startIndex + (numAttrib - leftToDo), &buf1[0], sizeof(T), toProcess, true, srcStep);
00376                 T *src2 = (T *) _Arg[1]->make(loc, startIndex + (numAttrib - leftToDo), &buf2[0], sizeof(T), toProcess, true, srcStep);
00377                 
00378                 Make4Private(dest, src1, src2, stride, toProcess, _Op);
00379                 leftToDo -= toProcess;
00380         }
00381 }
00382 
00383 
00384 //=================================================================================================================
00385 template <class T>
00386 void    CPSAttribMakerBinOp<T>::make4     (CPSLocated *loc,
00387                                                                                    uint32 startIndex,
00388                                                                                    void *tab,
00389                                                                                    uint32 stride,
00390                                                                                    uint32 numAttrib,
00391                                                                                    uint32  srcStep /*= (1 << 16) */                                                                                
00392                                                                                   ) const
00393 
00394 {
00399         uint8 tab1[PSBinOpBufSize * sizeof(T)];
00400         uint8 tab2[PSBinOpBufSize * sizeof(T)];
00401         make4Private((T *) &tab1[0], (T *) &tab2[0], loc, startIndex, tab, stride, numAttrib, srcStep);
00402 }
00403 
00404 
00405 // for private use
00406 void MakeNPrivate(uint8 * dest, const NLMISC::CRGBA *src1, const NLMISC::CRGBA *src2, uint32 stride, uint32 numAttrib, CPSBinOp::BinOp op, uint nbReplicate);
00407 
00408 // for private use
00409 template <class T>
00410 void MakeNPrivate(uint8 * dest,
00411                                   const T *src1,
00412                                   const T *src2,
00413                                   uint32 stride,
00414                                   uint32 numAttrib,
00415                                   CPSBinOp::BinOp op,
00416                                   uint nbReplicate,
00417                                   uint32 srcStep = (1 << 16)
00418                                  )
00419 {
00420         uint k;
00421         uint8 *destEnd = dest + ((stride * nbReplicate) * numAttrib);
00422         switch (op)
00423         {
00424                 case CPSBinOp::modulate:
00425                 {
00426                         while (dest != destEnd)
00427                         {
00428                                 * (T *) dest = PSBinOpModulate(*src1 ++, *src2 ++);                                     
00429                                 k = (nbReplicate - 1);
00430                                 do
00431                                 {
00432                                         * (T *) (dest + stride) = *(T *) dest;
00433                                         dest += stride;
00434                                 }
00435                                 while (--k);
00436                                 dest += stride;
00437                         }
00438                 }
00439                 break;
00440                 case CPSBinOp::add:
00441                 {
00442                         while (dest != destEnd)
00443                         {                                       
00444                                 * (T *) dest = PSBinOpAdd(*src1 ++, *src2 ++);                                  
00445                                 k = (nbReplicate - 1);
00446                                 do
00447                                 {
00448                                         * (T *) (dest + stride) = *(T *) dest;
00449                                         dest += stride;
00450                                 }
00451                                 while (--k);
00452                                 dest += stride;
00453                         }
00454                 }
00455                 break;
00456                 case CPSBinOp::subtract:
00457                         while (dest != destEnd)
00458                         {
00459                                 * (T *) dest = PSBinOpSubtract(*src1 ++, *src2 ++);                                     
00460                                 k = (nbReplicate - 1);
00461                                 do
00462                                 {
00463                                         * (T *) (dest + stride) = *(T *) dest;
00464                                         dest += stride;
00465                                 }
00466                                 while (--k);
00467                                 dest += stride;
00468                         }
00469                 break;
00470                 default: break;
00471         }
00472 }
00473 
00474 //=================================================================================================================
00475 template <class T>
00476 inline void     CPSAttribMakerBinOp<T>::makeNPrivate(T *buf1,
00477                                                                                                  T *buf2,
00478                                                                                                  CPSLocated *loc,
00479                                                                                                  uint32 startIndex,
00480                                                                                                  void *tab,
00481                                                                                                  uint32 stride,
00482                                                                                                  uint32 numAttrib,
00483                                                                                                  uint32 nbReplicate,
00484                                                                                                  uint32 srcStep /*= (1 << 16)*/                                                                                          
00485                                                                                                 ) const
00486 {               
00487         uint8 *dest = (uint8 *) tab;
00488         uint leftToDo = numAttrib, toProcess;
00489         nlassert(_Arg[0] && _Arg[1]);   
00490         switch (_Op)
00491         {
00492                 case CPSBinOp::selectArg1:
00493                         _Arg[0]->makeN(loc, startIndex, tab, stride, numAttrib, nbReplicate, srcStep);
00494                         return;
00495                         break;
00496                 case CPSBinOp::selectArg2:
00497                         _Arg[1]->makeN(loc, startIndex, tab, stride, numAttrib, nbReplicate, srcStep);
00498                         return;
00499                         break;          
00500                 default: break;
00501         }
00502         
00503         while (leftToDo)
00504         {
00505                 toProcess = leftToDo > PSBinOpBufSize ? PSBinOpBufSize : leftToDo;
00506                 T *src1 = (T *) _Arg[0]->make(loc, startIndex + (numAttrib - leftToDo), &buf1[0], sizeof(T), toProcess, true, srcStep);
00507                 T *src2 = (T *) _Arg[1]->make(loc, startIndex + (numAttrib - leftToDo), &buf2[0], sizeof(T), toProcess, true, srcStep);
00508                 
00509                 MakeNPrivate(dest, src1, src2, stride, toProcess, _Op, nbReplicate);
00510                 leftToDo -= toProcess;
00511         }
00512 }
00513 
00514 //=================================================================================================================
00515 template <class T>
00516 void    CPSAttribMakerBinOp<T>::makeN(CPSLocated *loc,
00517                                                                           uint32 startIndex,
00518                                                                           void *tab,
00519                                                                           uint32 stride,
00520                                                                           uint32 numAttrib,
00521                                                                           uint32 nbReplicate,
00522                                                                           uint32 /* srcStep = (1 << 16)*/
00523                                                                          ) const
00524 
00525 {
00530         uint8 tab1[PSBinOpBufSize * sizeof(T)];
00531         uint8 tab2[PSBinOpBufSize * sizeof(T)];
00532         makeNPrivate((T *) &tab1[0], (T *) &tab2[0], loc, startIndex, tab, stride, numAttrib, nbReplicate);
00533 }
00534 
00535 //=================================================================================================================
00536 template <class T>
00537 void    CPSAttribMakerBinOp<T>::serial            (NLMISC::IStream &f) throw(NLMISC::EStream)
00538 {
00539         if (f.isReading())
00540         {
00541                 clean();
00542         }
00543         f.serialVersion(1);
00544         f.serialEnum(_Op);
00545         f.serialPolyPtr(_Arg[0]);
00546         f.serialPolyPtr(_Arg[1]);
00547         f.serial(_Size, _MaxSize);
00548         
00549 }
00550 
00551 //=================================================================================================================
00552 template <class T>
00553 void    CPSAttribMakerBinOp<T>::deleteElement (uint32 index)
00554 {
00555         if (_Arg[0]->hasMemory())       _Arg[0]->deleteElement(index);
00556         if (_Arg[1]->hasMemory())       _Arg[1]->deleteElement(index);
00557         nlassert(_Size != 0);
00558         --_Size;
00559 }
00560 
00561 //=================================================================================================================
00562 template <class T>
00563 void    CPSAttribMakerBinOp<T>::newElement        (CPSLocated *emitterLocated, uint32 emitterIndex)
00564 {
00565         if (_Arg[0]->hasMemory())       _Arg[0]->newElement(emitterLocated, emitterIndex);
00566         if (_Arg[1]->hasMemory())       _Arg[1]->newElement(emitterLocated, emitterIndex);
00567         if (_Size != _MaxSize)
00568         {
00569                 ++_Size;
00570         }
00571 }
00572 
00573 //=================================================================================================================
00574 template <class T>
00575 void    CPSAttribMakerBinOp<T>::resize            (uint32 capacity, uint32 nbPresentElements)
00576 {
00577         nlassert(capacity < (1 << 16));
00578         _MaxSize = capacity;
00579         _Size = nbPresentElements;
00580         if (_Arg[0]->hasMemory())       _Arg[0]->resize(capacity, nbPresentElements);
00581         if (_Arg[1]->hasMemory())       _Arg[1]->resize(capacity, nbPresentElements);
00582 }
00583 
00584 
00585 } // NL3D
00586 
00587 
00588 #endif // NL_PS_ATTRIB_MAKER_BIN_OP_INLINE_H
00589 
00590 /* End of ps_attrib_maker_bin_op.h */