00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
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 ,
00056 uint32 srcStep ,
00057 bool forceClampEntry
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;
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;
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
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
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
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
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
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 }