00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "std3d.h"
00027
00028 #include "3d/ps_face_look_at.h"
00029 #include "3d/ps_macro.h"
00030 #include "3d/driver.h"
00031 #include "3d/fast_floor.h"
00032 #include "3d/ps_iterator.h"
00033
00034
00035 namespace NL3D
00036 {
00037
00038
00039
00041
00043
00044
00050 class CPSFaceLookAtHelper
00051 {
00052 public:
00053 template <class T>
00054 static void drawLookAt(T it, T speedIt, CPSFaceLookAt &la, uint size, uint32 srcStep)
00055 {
00056 PARTICLES_CHECK_MEM;
00057 nlassert(la._Owner);
00058 IDriver *driver = la.getDriver();
00059
00060 la.updateMatBeforeRendering(driver);
00061
00062 CVertexBuffer &vb = la.getNeededVB();
00063 la._Owner->incrementNbDrawnParticles(size);
00064 la.setupDriverModelMatrix();
00065 driver->activeVertexBuffer(vb);
00066 const CVector I = la.computeI();
00067 const CVector J = la.computeJ();
00068 const CVector K = la.computeK();
00069 const float *rotTable = CPSRotated2DParticle::getRotTable();
00070
00071
00072 uint32 leftToDo = size, toProcess;
00073 float pSizes[CPSQuad::quadBufSize];
00074 float pSecondSizes[CPSQuad::quadBufSize];
00075 float *currentSize;
00076 uint32 currentSizeStep = la._SizeScheme ? 1 : 0;
00077
00078 uint8 *ptPos;
00079
00080 const uint32 stride = vb.getVertexSize(), stride2 = stride << 1, stride3 = stride + stride2, stride4 = stride << 2;
00081 if (!la._Angle2DScheme)
00082 {
00083
00084 do
00085 {
00086
00087 ptPos = (uint8 *) vb.getVertexCoordPointer();
00088 toProcess = leftToDo <= CPSQuad::quadBufSize ? leftToDo : CPSQuad::quadBufSize;
00089
00090 if (la._SizeScheme)
00091 {
00092 currentSize = (float *) la._SizeScheme->make(la._Owner, size- leftToDo, pSizes, sizeof(float), toProcess, true, srcStep);
00093 }
00094 else
00095 {
00096 currentSize = &la._ParticleSize;
00097 }
00098
00099 la.updateVbColNUVForRender(vb, size - leftToDo, toProcess, srcStep);
00100 T endIt = it + toProcess;
00101 if (la._MotionBlurCoeff == 0.f)
00102 {
00103 if (!la._IndependantSizes)
00104 {
00105 const uint32 tabIndex = (((uint32) la._Angle2D) & 0xff) << 2;
00106 const CVector v1 = rotTable[tabIndex] * I + rotTable[tabIndex + 1] * K;
00107 const CVector v2 = rotTable[tabIndex + 2] * I + rotTable[tabIndex + 3] * K;
00108 if (currentSizeStep)
00109 {
00110 while (it != endIt)
00111 {
00112 CHECK_VERTEX_BUFFER(vb, ptPos);
00113 ((CVector *) ptPos)->x = (*it).x + *currentSize * v1.x;
00114 ((CVector *) ptPos)->y = (*it).y + *currentSize * v1.y;
00115 ((CVector *) ptPos)->z = (*it).z + *currentSize * v1.z;
00116 ptPos += stride;
00117
00118 CHECK_VERTEX_BUFFER(vb, ptPos);
00119 ((CVector *) ptPos)->x = (*it).x + *currentSize * v2.x;
00120 ((CVector *) ptPos)->y = (*it).y + *currentSize * v2.y;
00121 ((CVector *) ptPos)->z = (*it).z + *currentSize * v2.z;
00122 ptPos += stride;
00123
00124 CHECK_VERTEX_BUFFER(vb, ptPos);
00125 ((CVector *) ptPos)->x = (*it).x - *currentSize * v1.x;
00126 ((CVector *) ptPos)->y = (*it).y - *currentSize * v1.y;
00127 ((CVector *) ptPos)->z = (*it).z - *currentSize * v1.z;
00128 ptPos += stride;
00129
00130 CHECK_VERTEX_BUFFER(vb, ptPos);
00131 ((CVector *) ptPos)->x = (*it).x - *currentSize * v2.x;
00132 ((CVector *) ptPos)->y = (*it).y - *currentSize * v2.y;
00133 ((CVector *) ptPos)->z = (*it).z - *currentSize * v2.z;
00134 ptPos += stride;
00135
00136 ++it;
00137 currentSize += currentSizeStep;
00138 }
00139 }
00140 else
00141 {
00142
00143 const CVector myV1 = *currentSize * v1;
00144 const CVector myV2 = *currentSize * v2;
00145
00146 while (it != endIt)
00147 {
00148 CHECK_VERTEX_BUFFER(vb, ptPos);
00149 ((CVector *) ptPos)->x = (*it).x + myV1.x;
00150 ((CVector *) ptPos)->y = (*it).y + myV1.y;
00151 ((CVector *) ptPos)->z = (*it).z + myV1.z;
00152 ptPos += stride;
00153
00154 CHECK_VERTEX_BUFFER(vb, ptPos);
00155 ((CVector *) ptPos)->x = (*it).x + myV2.x;
00156 ((CVector *) ptPos)->y = (*it).y + myV2.y;
00157 ((CVector *) ptPos)->z = (*it).z + myV2.z;
00158 ptPos += stride;
00159
00160 CHECK_VERTEX_BUFFER(vb, ptPos);
00161 ((CVector *) ptPos)->x = (*it).x - myV1.x;
00162 ((CVector *) ptPos)->y = (*it).y - myV1.y;
00163 ((CVector *) ptPos)->z = (*it).z - myV1.z;
00164 ptPos += stride;
00165
00166 CHECK_VERTEX_BUFFER(vb, ptPos);
00167 ((CVector *) ptPos)->x = (*it).x - myV2.x;
00168 ((CVector *) ptPos)->y = (*it).y - myV2.y;
00169 ((CVector *) ptPos)->z = (*it).z - myV2.z;
00170 ptPos += stride;
00171 ++it;
00172 }
00173 }
00174 }
00175 else
00176 {
00177 const CVector v1 = CPSUtil::getCos((sint32) la._Angle2D) * I + CPSUtil::getSin((sint32) la._Angle2D) * K;
00178 const CVector v2 = - CPSUtil::getSin((sint32) la._Angle2D) * I + CPSUtil::getCos((sint32) la._Angle2D) * K;
00179
00180 float *currentSize2;
00181 float secondSize;
00182 uint32 currentSizeStep2;
00183 if (la._SecondSize.getSizeScheme())
00184 {
00185 currentSize2 = (float *) la._SecondSize.getSizeScheme()->make(la._Owner, size- leftToDo, pSecondSizes, sizeof(float), toProcess, true, srcStep);
00186 currentSizeStep2 = 1;
00187 }
00188 else
00189 {
00190 secondSize = la._SecondSize.getSize();
00191 currentSize2 = &secondSize;
00192 currentSizeStep2 = 0;
00193 }
00194
00195
00196 while (it != endIt)
00197 {
00198 CHECK_VERTEX_BUFFER(vb, ptPos);
00199 ((CVector *) ptPos)->x = (*it).x - *currentSize * v1.x + *currentSize2 * v2.x;
00200 ((CVector *) ptPos)->y = (*it).y - *currentSize * v1.y + *currentSize2 * v2.y;
00201 ((CVector *) ptPos)->z = (*it).z - *currentSize * v1.z + *currentSize2 * v2.z;
00202 ptPos += stride;
00203
00204 CHECK_VERTEX_BUFFER(vb, ptPos);
00205 ((CVector *) ptPos)->x = (*it).x + *currentSize * v1.x + *currentSize2 * v2.x;
00206 ((CVector *) ptPos)->y = (*it).y + *currentSize * v1.y + *currentSize2 * v2.y;
00207 ((CVector *) ptPos)->z = (*it).z + *currentSize * v1.z + *currentSize2 * v2.z;
00208 ptPos += stride;
00209
00210 CHECK_VERTEX_BUFFER(vb, ptPos);
00211 ((CVector *) ptPos)->x = (*it).x + *currentSize * v1.x - *currentSize2 * v2.x;
00212 ((CVector *) ptPos)->y = (*it).y + *currentSize * v1.y - *currentSize2 * v2.y;
00213 ((CVector *) ptPos)->z = (*it).z + *currentSize * v1.z - *currentSize2 * v2.z;
00214 ptPos += stride;
00215
00216 CHECK_VERTEX_BUFFER(vb, ptPos);
00217 ((CVector *) ptPos)->x = (*it).x - *currentSize * v1.x - *currentSize2 * v2.x;
00218 ((CVector *) ptPos)->y = (*it).y - *currentSize * v1.y - *currentSize2 * v2.y;
00219 ((CVector *) ptPos)->z = (*it).z - *currentSize * v1.z - *currentSize2 * v2.z;
00220 ptPos += stride;
00221 ++it;
00222 currentSize += currentSizeStep;
00223 currentSize2 += currentSizeStep2;
00224 }
00225 }
00226 }
00227 else
00228 {
00229
00230
00231 const CVector v1 = I + K;
00232 const CVector v2 = K - I;
00233 CVector startV, endV, mbv1, mbv1n, mbv12, mbv2;
00234
00235 float n;
00236 const float epsilon = 10E-5f;
00237 const float normEpsilon = 10E-6f;
00238
00239 CMatrix tMat = la._Owner->isInSystemBasis() ? la.getViewMat() * la.getSysMat()
00240 : la.getViewMat();
00241
00242 while (it != endIt)
00243 {
00244
00245
00246 startV = tMat * *it ;
00247 endV = tMat * (*it + *speedIt);
00248 if (startV.y > epsilon || endV.y > epsilon)
00249 {
00250 if (startV.y < epsilon)
00251 {
00252 if (fabsf(endV.y - startV.y) > normEpsilon)
00253 {
00254 startV = endV + (endV.y - epsilon) / (endV.y - startV.y) * (startV - endV);
00255 }
00256 startV.y = epsilon;
00257 }
00258 else if (endV.y < epsilon)
00259 {
00260 if (fabsf(endV.y - startV.y) > normEpsilon)
00261 {
00262 endV = startV + (startV.y - epsilon) / (startV.y - endV.y) * (endV - startV);
00263 }
00264 endV.y = epsilon;
00265 }
00266
00267 mbv1 = (startV.x / startV.y - endV.x / endV.y) * I
00268 + (startV.z / startV.y - endV.z / endV.y) * K ;
00269
00270 n = mbv1.norm();
00271 if (n > la._Threshold)
00272 {
00273 mbv1 *= la._Threshold / n;
00274 n = la._Threshold;
00275 }
00276 if (n > normEpsilon)
00277 {
00278 mbv1n = mbv1 / n;
00279 mbv2 = *currentSize * (J ^ mbv1n);
00280 mbv12 = -*currentSize * mbv1n;
00281 mbv1 *= *currentSize * (1 + la._MotionBlurCoeff * n * n) / n;
00282
00283 *(CVector *) ptPos = *it - mbv2;
00284 *(CVector *) (ptPos + stride) = *it + mbv1;
00285 *(CVector *) (ptPos + stride2) = *it + mbv2;
00286 *(CVector *) (ptPos + stride3) = *it + mbv12;
00287
00288
00289 CHECK_VERTEX_BUFFER(vb, ptPos);
00290 ((CVector *) ptPos)->x = (*it).x - mbv2.x;
00291 ((CVector *) ptPos)->y = (*it).y - mbv2.y;
00292 ((CVector *) ptPos)->z = (*it).z - mbv2.z;
00293
00294 CHECK_VERTEX_BUFFER(vb, ptPos + stride);
00295 ((CVector *) (ptPos + stride))->x = (*it).x + mbv1.x;
00296 ((CVector *) (ptPos + stride))->y = (*it).y + mbv1.y;
00297 ((CVector *) (ptPos + stride))->z = (*it).z + mbv1.z;
00298
00299 CHECK_VERTEX_BUFFER(vb, ptPos + stride2);
00300 ((CVector *) (ptPos + stride2))->x = (*it).x + mbv2.x;
00301 ((CVector *) (ptPos + stride2))->y = (*it).y + mbv2.y;
00302 ((CVector *) (ptPos + stride2))->z = (*it).z + mbv2.z;
00303
00304
00305 CHECK_VERTEX_BUFFER(vb, ptPos + stride3);
00306 ((CVector *) (ptPos + stride3))->x = (*it).x + mbv12.x;
00307 ((CVector *) (ptPos + stride3))->y = (*it).y + mbv12.y;
00308 ((CVector *) (ptPos + stride3))->z = (*it).z + mbv12.z;
00309
00310 }
00311 else
00312 {
00313 CHECK_VERTEX_BUFFER(vb, ptPos);
00314 ((CVector *) ptPos)->x = (*it).x - *currentSize * v2.x;
00315 ((CVector *) ptPos)->y = (*it).y - *currentSize * v2.y;
00316 ((CVector *) ptPos)->z = (*it).z - *currentSize * v2.z;
00317
00318 CHECK_VERTEX_BUFFER(vb, ptPos + stride);
00319 ((CVector *) (ptPos + stride))->x = (*it).x + *currentSize * v1.x;
00320 ((CVector *) (ptPos + stride))->y = (*it).y + *currentSize * v1.y;
00321 ((CVector *) (ptPos + stride))->z = (*it).z + *currentSize * v1.z;
00322
00323 CHECK_VERTEX_BUFFER(vb, ptPos + stride2);
00324 ((CVector *) (ptPos + stride2))->x = (*it).x + *currentSize * v2.x;
00325 ((CVector *) (ptPos + stride2))->y = (*it).y + *currentSize * v2.y;
00326 ((CVector *) (ptPos + stride2))->z = (*it).z + *currentSize * v2.z;
00327
00328
00329 CHECK_VERTEX_BUFFER(vb, ptPos + stride3);
00330 ((CVector *) (ptPos + stride3))->x = (*it).x - *currentSize * v1.x;
00331 ((CVector *) (ptPos + stride3))->y = (*it).y - *currentSize * v1.y;
00332 ((CVector *) (ptPos + stride3))->z = (*it).z - *currentSize * v1.z;
00333 }
00334 }
00335 else
00336 {
00337
00338 CHECK_VERTEX_BUFFER(vb, ptPos);
00339 ((CVector *) ptPos)->x = (*it).x - *currentSize * v2.x;
00340 ((CVector *) ptPos)->y = (*it).y - *currentSize * v2.y;
00341 ((CVector *) ptPos)->z = (*it).z - *currentSize * v2.z;
00342
00343 CHECK_VERTEX_BUFFER(vb, ptPos + stride);
00344 ((CVector *) (ptPos + stride))->x = (*it).x + *currentSize * v1.x;
00345 ((CVector *) (ptPos + stride))->y = (*it).y + *currentSize * v1.y;
00346 ((CVector *) (ptPos + stride))->z = (*it).z + *currentSize * v1.z;
00347
00348 CHECK_VERTEX_BUFFER(vb, ptPos + stride2);
00349 ((CVector *) (ptPos + stride2))->x = (*it).x + *currentSize * v2.x;
00350 ((CVector *) (ptPos + stride2))->y = (*it).y + *currentSize * v2.y;
00351 ((CVector *) (ptPos + stride2))->z = (*it).z + *currentSize * v2.z;
00352
00353
00354 CHECK_VERTEX_BUFFER(vb, ptPos + stride3);
00355 ((CVector *) (ptPos + stride3))->x = (*it).x - *currentSize * v1.x;
00356 ((CVector *) (ptPos + stride3))->y = (*it).y - *currentSize * v1.y;
00357 ((CVector *) (ptPos + stride3))->z = (*it).z - *currentSize * v1.z;
00358 }
00359
00360 ptPos += stride4;
00361 ++it;
00362 ++speedIt;
00363 currentSize += currentSizeStep;
00364 }
00365
00366 }
00367 driver->renderQuads(la._Mat, 0, toProcess);
00368 leftToDo -= toProcess;
00369 }
00370 while (leftToDo);
00371 }
00372 else
00373 {
00374 float pAngles[CPSQuad::quadBufSize];
00375 float *currentAngle;
00376 do
00377 {
00378
00379 ptPos = (uint8 *) vb.getVertexCoordPointer();
00380 toProcess = leftToDo <= CPSQuad::quadBufSize ? leftToDo : CPSQuad::quadBufSize;
00381 if (la._SizeScheme)
00382 {
00383 currentSize = (float *) la._SizeScheme->make(la._Owner, size - leftToDo, pSizes, sizeof(float), toProcess, true, srcStep);
00384 }
00385 else
00386 {
00387 currentSize = &la._ParticleSize;
00388 }
00389 currentAngle = (float *) la._Angle2DScheme->make(la._Owner, size - leftToDo, pAngles, sizeof(float), toProcess, true, srcStep);
00390 la.updateVbColNUVForRender(vb, size - leftToDo, toProcess, srcStep);
00391 T endIt = it + toProcess;
00392 CVector v1, v2;
00393 OptFastFloorBegin();
00394 if (!la._IndependantSizes)
00395 {
00396 while (it != endIt)
00397 {
00398 const uint32 tabIndex = ((OptFastFloor(*currentAngle)) & 0xff) << 2;
00399
00400 v1.x = *currentSize * (rotTable[tabIndex] * I.x + rotTable[tabIndex + 1] * K.x);
00401 v1.y = *currentSize * (rotTable[tabIndex] * I.y + rotTable[tabIndex + 1] * K.y);
00402 v1.z = *currentSize * (rotTable[tabIndex] * I.z + rotTable[tabIndex + 1] * K.z);
00403
00404 v2.x = *currentSize * (rotTable[tabIndex + 2] * I.x + rotTable[tabIndex + 3] * K.x);
00405 v2.y = *currentSize * (rotTable[tabIndex + 2] * I.y + rotTable[tabIndex + 3] * K.y);
00406 v2.z = *currentSize * (rotTable[tabIndex + 2] * I.z + rotTable[tabIndex + 3] * K.z);
00407
00408 CHECK_VERTEX_BUFFER(vb, ptPos);
00409 CHECK_VERTEX_BUFFER(vb, ptPos + stride);
00410 CHECK_VERTEX_BUFFER(vb, ptPos + stride2);
00411 CHECK_VERTEX_BUFFER(vb, ptPos + stride3);
00412
00413 ((CVector *) ptPos)->x = (*it).x + v1.x;
00414 ((CVector *) ptPos)->y = (*it).y + v1.y;
00415 ((CVector *) ptPos)->z = (*it).z + v1.z;
00416 ptPos += stride;
00417
00418 ((CVector *) ptPos)->x = (*it).x + v2.x;
00419 ((CVector *) ptPos)->y = (*it).y + v2.y;
00420 ((CVector *) ptPos)->z = (*it).z + v2.z;
00421 ptPos += stride;
00422
00423 ((CVector *) ptPos)->x = (*it).x - v1.x;
00424 ((CVector *) ptPos)->y = (*it).y - v1.y;
00425 ((CVector *) ptPos)->z = (*it).z - v1.z;
00426 ptPos += stride;
00427
00428 ((CVector *) ptPos)->x = (*it).x - v2.x;
00429 ((CVector *) ptPos)->y = (*it).y - v2.y;
00430 ((CVector *) ptPos)->z = (*it).z - v2.z;
00431 ptPos += stride;
00432
00433 ++it;
00434 currentSize += currentSizeStep;
00435 ++currentAngle;
00436 }
00437 }
00438 else
00439 {
00440
00441 float *currentSize2;
00442 float secondSize;
00443 uint32 currentSizeStep2;
00444 if (la._SecondSize.getSizeScheme())
00445 {
00446 currentSize2 = (float *) la._SecondSize.getSizeScheme()->make(la._Owner, size- leftToDo, pSecondSizes, sizeof(float), toProcess, true, srcStep);
00447 currentSizeStep2 = 1;
00448 }
00449 else
00450 {
00451 secondSize = la._SecondSize.getSize();
00452 currentSize2 = &secondSize;
00453 currentSizeStep2 = 0;
00454 }
00455
00456 float cosAngle, sinAngle;
00457 while (it != endIt)
00458 {
00459 cosAngle = CPSUtil::getCos((sint32) *currentAngle);
00460 sinAngle = CPSUtil::getSin((sint32) *currentAngle);
00461 v1 = cosAngle * I + sinAngle * K;
00462 v2 = - sinAngle * I + cosAngle * K;
00463
00464 CHECK_VERTEX_BUFFER(vb, ptPos);
00465 ((CVector *) ptPos)->x = (*it).x - *currentSize * v1.x + *currentSize2 * v2.x;
00466 ((CVector *) ptPos)->y = (*it).y - *currentSize * v1.y + *currentSize2 * v2.y;
00467 ((CVector *) ptPos)->z = (*it).z - *currentSize * v1.z + *currentSize2 * v2.z;
00468 ptPos += stride;
00469
00470 CHECK_VERTEX_BUFFER(vb, ptPos);
00471 ((CVector *) ptPos)->x = (*it).x + *currentSize * v1.x + *currentSize2 * v2.x;
00472 ((CVector *) ptPos)->y = (*it).y + *currentSize * v1.y + *currentSize2 * v2.y;
00473 ((CVector *) ptPos)->z = (*it).z + *currentSize * v1.z + *currentSize2 * v2.z;
00474 ptPos += stride;
00475
00476 CHECK_VERTEX_BUFFER(vb, ptPos);
00477 ((CVector *) ptPos)->x = (*it).x + *currentSize * v1.x - *currentSize2 * v2.x;
00478 ((CVector *) ptPos)->y = (*it).y + *currentSize * v1.y - *currentSize2 * v2.y;
00479 ((CVector *) ptPos)->z = (*it).z + *currentSize * v1.z - *currentSize2 * v2.z;
00480 ptPos += stride;
00481
00482 CHECK_VERTEX_BUFFER(vb, ptPos);
00483 ((CVector *) ptPos)->x = (*it).x - *currentSize * v1.x - *currentSize2 * v2.x;
00484 ((CVector *) ptPos)->y = (*it).y - *currentSize * v1.y - *currentSize2 * v2.y;
00485 ((CVector *) ptPos)->z = (*it).z - *currentSize * v1.z - *currentSize2 * v2.z;
00486 ptPos += stride;
00487 ++it;
00488 ++currentAngle;
00489 currentSize += currentSizeStep;
00490 currentSize2 += currentSizeStep2;
00491 }
00492 }
00493 OptFastFloorEnd();
00494 driver->renderQuads(la._Mat, 0, toProcess);
00495 leftToDo -= toProcess;
00496 }
00497 while (leftToDo);
00498 }
00499 PARTICLES_CHECK_MEM;
00500 }
00501 };
00502
00504 void CPSFaceLookAt::draw(bool opaque)
00505 {
00506 PARTICLES_CHECK_MEM;
00507 if (!_Owner->getSize()) return;
00508
00509 uint32 step;
00510 uint numToProcess;
00511 computeSrcStep(step, numToProcess);
00512 if (!numToProcess) return;
00513
00514
00515 if (step == (1 << 16))
00516 {
00517 CPSFaceLookAtHelper::drawLookAt(_Owner->getPos().begin(),
00518 _Owner->getSpeed().begin(),
00519 *this,
00520 numToProcess,
00521 step
00522 );
00523 }
00524 else
00525 {
00526 CPSFaceLookAtHelper::drawLookAt(TIteratorVectStep1616(_Owner->getPos().begin(), 0, step),
00527 TIteratorVectStep1616(_Owner->getSpeed().begin(), 0, step),
00528 *this,
00529 numToProcess,
00530 step
00531 );
00532 }
00533
00534 PARTICLES_CHECK_MEM;
00535 }
00536
00538 CPSFaceLookAt::CPSFaceLookAt(CSmartPtr<ITexture> tex) : CPSQuad(tex), _MotionBlurCoeff(0.f)
00539 , _Threshold(0.5f), _IndependantSizes(false)
00540 {
00541 _SecondSize.Owner = this;
00542 _Name = std::string("LookAt");
00543 }
00544
00546 void CPSFaceLookAt::newElement(CPSLocated *emitterLocated, uint32 emitterIndex)
00547 {
00548 CPSQuad::newElement(emitterLocated, emitterIndex);
00549 newAngle2DElement(emitterLocated, emitterIndex);
00550 }
00551
00553 void CPSFaceLookAt::deleteElement(uint32 index)
00554 {
00555 CPSQuad::deleteElement(index);
00556 deleteAngle2DElement(index);
00557 }
00558
00560 void CPSFaceLookAt::resize(uint32 capacity)
00561 {
00562 nlassert(capacity < (1 << 16));
00563 CPSQuad::resize(capacity);
00564 resizeAngle2D(capacity);
00565 }
00566
00567
00569 void CPSFaceLookAt::serial(NLMISC::IStream &f) throw(NLMISC::EStream)
00570 {
00571 sint ver = f.serialVersion(2);
00572 CPSQuad::serial(f);
00573 CPSRotated2DParticle::serialAngle2DScheme(f);
00574 f.serial(_MotionBlurCoeff);
00575 if (_MotionBlurCoeff != 0)
00576 {
00577 f.serial(_Threshold);
00578 }
00579 if (ver > 1)
00580 {
00581 f.serial(_IndependantSizes);
00582 if (_IndependantSizes)
00583 {
00584 _SecondSize.serialSizeScheme(f);
00585 }
00586 }
00587 if (f.isReading())
00588 {
00589 init();
00590 }
00591 }
00592
00593 }