ps_plane_basis_maker.cpp

Go to the documentation of this file.
00001 
00005 /* Copyright, 2001 Nevrax Ltd.
00006  *
00007  * This file is part of NEVRAX NEL.
00008  * NEVRAX NEL is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2, or (at your option)
00011  * any later version.
00012 
00013  * NEVRAX NEL is distributed in the hope that it will be useful, but
00014  * WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00016  * General Public License for more details.
00017 
00018  * You should have received a copy of the GNU General Public License
00019  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00020  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00021  * MA 02111-1307, USA.
00022  */
00023 
00024 #include "std3d.h"
00025 
00026 
00027 #include "nel/3d/ps_plane_basis_maker.h"
00028 #include "nel/3d/ps_register_plane_basis_attribs.h"
00029 
00030 namespace NL3D
00031 {
00032 
00033 
00034 CPlaneBasis CPSPlaneBasisGradient::DefaultPlaneBasisTab[] = { CPlaneBasis(NLMISC::CVector::I), CPlaneBasis(NLMISC::CVector::J) };
00035 
00037 // CPSPlaneBasisFollowSpeed implementation //
00039 
00041 CPlaneBasis CPSPlaneBasisFollowSpeed::get(CPSLocated *loc, uint32 index)
00042 {
00043    return (CPlaneBasis(loc->getSpeed()[index]));
00044 }
00045 CPlaneBasis CPSPlaneBasisFollowSpeed::get(const CPSEmitterInfo &infos)
00046 {
00047     return (CPlaneBasis(infos.Speed));
00048 }
00049 
00051 void *CPSPlaneBasisFollowSpeed::make(CPSLocated *loc,
00052                                      uint32 startIndex,
00053                                      void *tab, uint32 stride,
00054                                      uint32 numAttrib,
00055                                      bool enableNoCopy /* = false*/,
00056                                      uint32 srcStep /*= (1 << 16)*/,
00057                                      bool forceClampEntry /* = false */
00058                                     ) const
00059 {
00060     nlassert(numAttrib);
00061     if (srcStep == (1 << 16))
00062     {
00063         TPSAttribVector::const_iterator speedIt = loc->getSpeed().begin() + startIndex
00064                                         , endSpeedIt = loc->getSpeed().begin() + startIndex + numAttrib;
00065         uint8 *ptDat  = (uint8 *) tab;
00066         switch(_ProjectionPlane)
00067         {
00068             case NoProjection:
00069                 do
00070                 {
00071                     *(CPlaneBasis *) ptDat = CPlaneBasis(*speedIt);
00072                     ++ speedIt;
00073                     ptDat += stride;
00074                 }
00075                 while (speedIt != endSpeedIt);
00076             break;
00077             case XY:
00078                 do
00079                 {
00080                     float norm = sqrtf(speedIt->x * speedIt->x + speedIt->y * speedIt->y);
00081                     float invNorm = (norm != 0.f) ? 1.f / norm : 0.f;
00082                     CPlaneBasis &pb = *(CPlaneBasis *) ptDat;
00083                     pb.X.set(invNorm * speedIt->x, invNorm * speedIt->y, 0.f);
00084                     pb.Y.set(- pb.X.y, pb.X.x, 0.f);
00085                     ++ speedIt;
00086                     ptDat += stride;
00087                 }
00088                 while (speedIt != endSpeedIt);
00089             break;
00090             case XZ:
00091                 do
00092                 {
00093                     float norm = sqrtf(speedIt->x * speedIt->x + speedIt->z * speedIt->z);
00094                     float invNorm = (norm != 0.f) ? 1.f / norm : 0.f;
00095                     CPlaneBasis &pb = *(CPlaneBasis *) ptDat;
00096                     pb.X.set(invNorm * speedIt->x, 0.f, invNorm * speedIt->z);
00097                     pb.Y.set(- pb.X.z, 0.f, pb.X.x);
00098                     ++ speedIt;
00099                     ptDat += stride;
00100                 }
00101                 while (speedIt != endSpeedIt);
00102             break;
00103             case YZ:
00104                 do
00105                 {
00106                     float norm = sqrtf(speedIt->y * speedIt->y + speedIt->z * speedIt->z);
00107                     float invNorm = (norm != 0.f) ? 1.f / norm : 0.f;
00108                     CPlaneBasis &pb = *(CPlaneBasis *) ptDat;
00109                     pb.X.set(0.f, invNorm * speedIt->y, invNorm * speedIt->z);
00110                     pb.Y.set(0.f, - pb.X.z, pb.X.y);
00111                     ++ speedIt;
00112                     ptDat += stride;
00113                 }
00114                 while (speedIt != endSpeedIt);
00115             break;
00116             default:
00117                 nlstop; // unknow projection mode
00118             break;
00119         }
00120         return tab;
00121     }
00122     else
00123     {
00124         uint32 fpIndex = startIndex * srcStep;
00125         const TPSAttribVector::const_iterator speedIt = loc->getSpeed().begin();
00126         uint8 *ptDat  = (uint8 *) tab;
00127         switch(_ProjectionPlane)
00128         {
00129             case NoProjection:
00130                 while (numAttrib --)
00131                 {
00132                     *(CPlaneBasis *) ptDat = CPlaneBasis(*(speedIt + (fpIndex >> 16)));
00133                     ptDat += stride;
00134                     fpIndex += srcStep;
00135                 }
00136             break;
00137             case XY:
00138                 while (numAttrib --)
00139                 {
00140                     const CVector *speedVect = &(*(speedIt + (fpIndex >> 16)));
00141                     float norm = sqrtf(speedVect->x * speedVect->x + speedVect->y * speedVect->y);
00142                     float invNorm = (norm != 0.f) ? 1.f / norm : 0.f;
00143                     CPlaneBasis &pb = *(CPlaneBasis *) ptDat;
00144                     pb.X.set(invNorm * speedVect->x, invNorm * speedVect->y, 0.f);
00145                     pb.Y.set(- pb.X.y, pb.X.x, 0.f);
00146                     ptDat += stride;
00147                     fpIndex += srcStep;
00148                 }
00149             break;
00150             case XZ:
00151                 while (numAttrib --)
00152                 {
00153                     const CVector *speedVect = &(*(speedIt + (fpIndex >> 16)));
00154                     float norm = sqrtf(speedVect->x * speedVect->x + speedVect->z * speedVect->z);
00155                     float invNorm = (norm != 0.f) ? 1.f / norm : 0.f;
00156                     CPlaneBasis &pb = *(CPlaneBasis *) ptDat;
00157                     pb.X.set(invNorm * speedVect->x, 0.f, invNorm * speedVect->z);
00158                     pb.Y.set(- pb.X.z, 0.f, pb.X.x);
00159                     ptDat += stride;
00160                     fpIndex += srcStep;
00161                 }
00162             break;
00163             case YZ:
00164                 while (numAttrib --)
00165                 {
00166                     const CVector *speedVect = &(*(speedIt + (fpIndex >> 16)));
00167                     float norm = sqrtf(speedVect->y * speedVect->y + speedVect->z * speedVect->z);
00168                     float invNorm = (norm != 0.f) ? 1.f / norm : 0.f;
00169                     CPlaneBasis &pb = *(CPlaneBasis *) ptDat;
00170                     pb.X.set(0.f, invNorm * speedVect->y, invNorm * speedVect->z);
00171                     pb.Y.set(0.f, - pb.X.z, pb.X.y);
00172                     ptDat += stride;
00173                     fpIndex += srcStep;
00174                 }
00175             break;
00176             default:
00177                 nlstop; // unknow projection mode
00178             break;
00179         }
00180         return tab;
00181     }
00182 }
00183 
00185 void CPSPlaneBasisFollowSpeed::make4(CPSLocated *loc,
00186                                      uint32 startIndex,
00187                                      void *tab,
00188                                      uint32 stride,
00189                                      uint32 numAttrib,
00190                                      uint32 srcStep /*= (1 << 16)*/
00191                                     ) const
00192 {
00193     nlassert(numAttrib);
00194     if (srcStep == (1 << 16))
00195     {
00196         TPSAttribVector::const_iterator speedIt = loc->getSpeed().begin() + startIndex
00197                                         , endSpeedIt = loc->getSpeed().begin() + startIndex + numAttrib;
00198         uint8 *ptDat  = (uint8 *) tab;
00199         do
00200         {
00201             *(CPlaneBasis *) ptDat = CPlaneBasis(*speedIt);
00202             *(CPlaneBasis *) (ptDat + stride) = *(CPlaneBasis *) ptDat;
00203             ptDat += stride;
00204             *(CPlaneBasis *) (ptDat + stride) = *(CPlaneBasis *) ptDat;
00205             ptDat += stride;
00206             *(CPlaneBasis *) (ptDat + stride) = *(CPlaneBasis *) ptDat;
00207             ptDat += stride << 1;
00208             ++ speedIt;
00209         }
00210         while (speedIt != endSpeedIt);
00211     }
00212     else
00213     {
00214         uint32 fpIndex = startIndex * srcStep;
00215         const TPSAttribVector::const_iterator speedIt = loc->getSpeed().begin();
00216         uint8 *ptDat  = (uint8 *) tab;
00217         while (numAttrib --)
00218         {
00219             *(CPlaneBasis *) ptDat = CPlaneBasis(*(speedIt + (fpIndex >> 16)));
00220             *(CPlaneBasis *) (ptDat + stride) = *(CPlaneBasis *) ptDat;
00221             ptDat += stride;
00222             *(CPlaneBasis *) (ptDat + stride) = *(CPlaneBasis *) ptDat;
00223             ptDat += stride;
00224             *(CPlaneBasis *) (ptDat + stride) = *(CPlaneBasis *) ptDat;
00225             ptDat += stride << 1;
00226             fpIndex += srcStep;
00227         }
00228     }
00229 }
00230 
00232 void CPSPlaneBasisFollowSpeed::makeN(CPSLocated *loc,
00233                                      uint32 startIndex,
00234                                      void *tab,
00235                                      uint32 stride,
00236                                      uint32 numAttrib,
00237                                      uint32 nbReplicate,
00238                                      uint32 srcStep /*= (1 << 16) */
00239                                     ) const
00240 {
00241     nlassert(numAttrib);
00242     if (srcStep == (1 << 16))
00243     {
00244         nlassert(nbReplicate > 1);
00245         TPSAttribVector::const_iterator speedIt = loc->getSpeed().begin() + startIndex
00246                                         , endSpeedIt = loc->getSpeed().begin() + startIndex + numAttrib;
00247         uint8 *ptDat  = (uint8 *) tab;
00248         uint k;
00249         do
00250         {
00251             *(CPlaneBasis *) ptDat = CPlaneBasis(*speedIt);
00252 
00253             k = nbReplicate - 1;
00254 
00255             do
00256             {
00257                 *(CPlaneBasis *) (ptDat + stride) = *(CPlaneBasis *) ptDat;
00258                 ptDat += stride;
00259             }
00260             while (--k);
00261             ptDat += stride;
00262 
00263             ++ speedIt;
00264         }
00265         while (speedIt != endSpeedIt);
00266     }
00267     else
00268     {
00269         uint32 fpIndex = startIndex * srcStep;
00270         nlassert(nbReplicate > 1);
00271         const TPSAttribVector::const_iterator speedIt = loc->getSpeed().begin();
00272         uint8 *ptDat  = (uint8 *) tab;
00273         uint k;
00274         while (numAttrib --)
00275         {
00276             *(CPlaneBasis *) ptDat = CPlaneBasis(*(speedIt + (fpIndex >> 16)));
00277 
00278             k = nbReplicate - 1;
00279 
00280             do
00281             {
00282                 *(CPlaneBasis *) (ptDat + stride) = *(CPlaneBasis *) ptDat;
00283                 ptDat += stride;
00284             }
00285             while (--k);
00286             ptDat += stride;
00287 
00288             fpIndex += srcStep;
00289         }
00290     }
00291 }
00292 
00293 
00295 // CSpinnerFunctor implementation          //
00297 
00298 
00300 CSpinnerFunctor::CSpinnerFunctor() : _NbSamples(0), _Axis(NLMISC::CVector::K)
00301 {
00302 }
00303 
00305 void CSpinnerFunctor::setAxis(const NLMISC::CVector &axis)
00306 {
00307     _Axis = axis;
00308     updateSamples();
00309 }
00310 
00312 void CSpinnerFunctor::setNumSamples(uint32 nbSamples)
00313 {
00314     nlassert(nbSamples > 0);
00315     _NbSamples = nbSamples;
00316     updateSamples();
00317 }
00318 
00320 uint32 CSpinnerFunctor::getNumSamples(void) const
00321 {
00322     return _NbSamples;
00323 }
00324 
00326 void CSpinnerFunctor::serial(NLMISC::IStream &f) throw(NLMISC::EStream)
00327 {
00328     f.serialVersion(1);
00329     f.serial(_Axis, _NbSamples);
00330     if (f.isReading()) updateSamples();
00331 }
00332 
00334 void CSpinnerFunctor::updateSamples(void)
00335 {
00336     if (_NbSamples == 0) return;
00337     // compute step between each angle
00338     const float angInc = (float) (2.f * NLMISC::Pi / _NbSamples);
00339     _PBTab.resize(_NbSamples + 1);
00340     NLMISC::CMatrix mat;
00341     CPSUtil::buildSchmidtBasis(_Axis, mat);
00342     NLMISC::CVector I = mat.getI();
00343     NLMISC::CVector J = mat.getJ();
00344     // compute basis for rotation
00345     for (uint32 k = 0; k < _NbSamples; ++k)
00346     {
00347         float ca = cosf(k * angInc);
00348         float sa = sinf(k * angInc);
00349         _PBTab[k].X.set(ca * I.x + sa * J.x,
00350                         ca * I.y + sa * J.y,
00351                         ca * I.z + sa * J.z);
00352 
00353         _PBTab[k].Y.set(- sa * I.x + ca * J.x,
00354                         - sa * I.y + ca * J.y,
00355                         - sa * I.z + ca * J.z);
00356     }
00357 }
00358 
00360 void PSRegisterPlaneBasisAttribs()
00361 {
00362     NLMISC_REGISTER_CLASS(CPSPlaneBasisBlender);
00363     NLMISC_REGISTER_CLASS(CPSPlaneBasisGradient);
00364     NLMISC_REGISTER_CLASS(CPSPlaneBasisMemory);
00365     NLMISC_REGISTER_CLASS(CPSPlaneBasisBinOp);
00366     NLMISC_REGISTER_CLASS(CPSPlaneBasisFollowSpeed);
00367     NLMISC_REGISTER_CLASS(CPSBasisSpinner);
00368 }
00369 
00370 } // NL3D

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