Definition at line 62 of file ps_face_look_at.cpp.
Static Public Member Functions | |
| template<class T> void | computeOrientationVectors (T speedIt, const CVector &I, const CVector &K, CLookAtAlign *dest, uint size) |
| template<class T> void | drawLookAt (T it, T speedIt, CPSFaceLookAt &la, uint size, uint32 srcStep) |
| template<class T> void | drawLookAtAlignOnMotion (T it, T speedIt, CPSFaceLookAt &la, uint size, uint32 srcStep) |
|
||||||||||||||||||||||||||||
|
compute orientation vectors depending on speed Definition at line 68 of file ps_face_look_at.cpp. References NL3D::CLookAtAlign::I, NL3D::CLookAtAlign::K, nlassert, NLMISC::CVector::normed(), size, and uint. Referenced by drawLookAtAlignOnMotion().
00069 {
00070 nlassert(size > 0);
00071 const CLookAtAlign *endDest = dest + size;
00072 do
00073 {
00074 // tmp unoptimized slow version
00075 CVector normedSpeed = (*speedIt).normed();
00076 float iProj = normedSpeed * I;
00077 float kProj = normedSpeed * K;
00078 dest->I = iProj * I + kProj * K;
00079 dest->K = (- kProj * I + iProj * K).normed();
00080 ++ speedIt;
00081 ++ dest;
00082 }
00083 while(dest != endDest);
00084 }
|
|
||||||||||||||||||||||||||||
|
render look at, but dont align on motion Definition at line 379 of file ps_face_look_at.cpp. References NL3D::CPSRotated2DParticle::_Angle2D, NL3D::CPSRotated2DParticle::_Angle2DScheme, NL3D::CPSFaceLookAt::_IndependantSizes, NL3D::CPSMaterial::_Mat, NL3D::CPSFaceLookAt::_MotionBlurCoeff, NL3D::CPSLocatedBindable::_Owner, NL3D::CPSSizedParticle::_ParticleSize, NL3D::CPSFaceLookAt::_SecondSize, NL3D::CPSSizedParticle::_SizeScheme, NL3D::CPSFaceLookAt::_Threshold, NL3D::IDriver::activeVertexBuffer(), CHECK_VERTEX_BUFFER, NL3D::CPSLocatedBindable::computeI(), NL3D::CPSLocatedBindable::computeJ(), NL3D::CPSLocatedBindable::computeK(), NL3D::CPSLocatedBindable::getDriver(), NL3D::CPSLocated::getLocalToWorldMatrix(), NL3D::CPSQuad::getNeededVB(), NL3D::CPSSizedParticle::getSize(), NL3D::CPSSizedParticle::getSizeScheme(), NL3D::CVertexBuffer::getVertexCoordPointer(), NL3D::CVertexBuffer::getVertexSize(), NL3D::CPSLocatedBindable::getViewMat(), NL3D::CPSLocated::incrementNbDrawnParticles(), NL3D::CPSAttribMaker< float >::make(), nlassert, NLMISC::CVector::norm(), NLMISC::OptFastFloor(), NLMISC::OptFastFloorBegin(), NLMISC::OptFastFloorEnd(), PARTICLES_CHECK_MEM, NL3D::IDriver::renderOrientedQuads(), NL3D::IDriver::renderQuads(), NL3D::CPSLocatedBindable::setupDriverModelMatrix(), sint32, size, stride, uint, uint32, uint8, NL3D::CPSQuad::updateMatBeforeRendering(), NL3D::CPSQuad::updateVbColNUVForRender(), NLMISC::CVector::x, NLMISC::CVector::y, and NLMISC::CVector::z.
00380 {
00381 //uint64 startTick = NLMISC::CTime::getPerformanceTime();
00382 PARTICLES_CHECK_MEM;
00383 nlassert(la._Owner);
00384 IDriver *driver = la.getDriver();
00385
00386 la.updateMatBeforeRendering(driver);
00387
00388 CVertexBuffer &vb = la.getNeededVB();
00389 la._Owner->incrementNbDrawnParticles(size); // for benchmark purpose
00390 la.setupDriverModelMatrix();
00391 driver->activeVertexBuffer(vb);
00392 const CVector I = la.computeI();
00393 const CVector J = la.computeJ();
00394 const CVector K = la.computeK();
00395 const float *rotTable = CPSRotated2DParticle::getRotTable();
00396 // for each the particle can be constantly rotated or have an independant rotation for each particle
00397 // number of face left, and number of face to process at once
00398 uint32 leftToDo = size, toProcess;
00399 float pSizes[CPSQuad::quadBufSize]; // the sizes to use
00400 float pSecondSizes[CPSQuad::quadBufSize]; // the second sizes to use
00401 float *currentSize;
00402 uint32 currentSizeStep = la._SizeScheme ? 1 : 0;
00403 // point the vector part in the current vertex
00404 uint8 *ptPos;
00405 // strides to go from one vertex to another one
00406 const uint32 stride = vb.getVertexSize(), stride2 = stride << 1, stride3 = stride + stride2, stride4 = stride << 2;
00407 //PSLookAtRenderTime += NLMISC::CTime::getPerformanceTime() - startTick;
00408 if (!la._Angle2DScheme)
00409 {
00410 // constant rotation case
00411 do
00412 {
00413 // restart at the beginning of the vertex buffer
00414 ptPos = (uint8 *) vb.getVertexCoordPointer();
00415 toProcess = leftToDo <= CPSQuad::quadBufSize ? leftToDo : CPSQuad::quadBufSize;
00416
00417 if (la._SizeScheme)
00418 {
00419 currentSize = (float *) la._SizeScheme->make(la._Owner, size- leftToDo, pSizes, sizeof(float), toProcess, true, srcStep);
00420 }
00421 else
00422 {
00423 currentSize = &la._ParticleSize;
00424 }
00425
00426 la.updateVbColNUVForRender(vb, size - leftToDo, toProcess, srcStep);
00427 T endIt = it + toProcess;
00428 if (la._MotionBlurCoeff == 0.f)
00429 {
00430 if (!la._IndependantSizes)
00431 {
00432 const uint32 tabIndex = (((uint32) la._Angle2D) & 0xff) << 2;
00433 const CVector v1 = rotTable[tabIndex] * I + rotTable[tabIndex + 1] * K;
00434 const CVector v2 = rotTable[tabIndex + 2] * I + rotTable[tabIndex + 3] * K;
00435 if (currentSizeStep)
00436 {
00437 while (it != endIt)
00438 {
00439 CHECK_VERTEX_BUFFER(vb, ptPos);
00440 ((CVector *) ptPos)->x = (*it).x + *currentSize * v1.x;
00441 ((CVector *) ptPos)->y = (*it).y + *currentSize * v1.y;
00442 ((CVector *) ptPos)->z = (*it).z + *currentSize * v1.z;
00443 ptPos += stride;
00444
00445 CHECK_VERTEX_BUFFER(vb, ptPos);
00446 ((CVector *) ptPos)->x = (*it).x + *currentSize * v2.x;
00447 ((CVector *) ptPos)->y = (*it).y + *currentSize * v2.y;
00448 ((CVector *) ptPos)->z = (*it).z + *currentSize * v2.z;
00449 ptPos += stride;
00450
00451 CHECK_VERTEX_BUFFER(vb, ptPos);
00452 ((CVector *) ptPos)->x = (*it).x - *currentSize * v1.x;
00453 ((CVector *) ptPos)->y = (*it).y - *currentSize * v1.y;
00454 ((CVector *) ptPos)->z = (*it).z - *currentSize * v1.z;
00455 ptPos += stride;
00456
00457 CHECK_VERTEX_BUFFER(vb, ptPos);
00458 ((CVector *) ptPos)->x = (*it).x - *currentSize * v2.x;
00459 ((CVector *) ptPos)->y = (*it).y - *currentSize * v2.y;
00460 ((CVector *) ptPos)->z = (*it).z - *currentSize * v2.z;
00461 ptPos += stride;
00462
00463 ++it;
00464 currentSize += currentSizeStep;
00465 }
00466 }
00467 else
00468 {
00469 // constant size
00470 const CVector myV1 = *currentSize * v1;
00471 const CVector myV2 = *currentSize * v2;
00472
00473 while (it != endIt)
00474 {
00475 CHECK_VERTEX_BUFFER(vb, ptPos);
00476 ((CVector *) ptPos)->x = (*it).x + myV1.x;
00477 ((CVector *) ptPos)->y = (*it).y + myV1.y;
00478 ((CVector *) ptPos)->z = (*it).z + myV1.z;
00479 ptPos += stride;
00480
00481 CHECK_VERTEX_BUFFER(vb, ptPos);
00482 ((CVector *) ptPos)->x = (*it).x + myV2.x;
00483 ((CVector *) ptPos)->y = (*it).y + myV2.y;
00484 ((CVector *) ptPos)->z = (*it).z + myV2.z;
00485 ptPos += stride;
00486
00487 CHECK_VERTEX_BUFFER(vb, ptPos);
00488 ((CVector *) ptPos)->x = (*it).x - myV1.x;
00489 ((CVector *) ptPos)->y = (*it).y - myV1.y;
00490 ((CVector *) ptPos)->z = (*it).z - myV1.z;
00491 ptPos += stride;
00492
00493 CHECK_VERTEX_BUFFER(vb, ptPos);
00494 ((CVector *) ptPos)->x = (*it).x - myV2.x;
00495 ((CVector *) ptPos)->y = (*it).y - myV2.y;
00496 ((CVector *) ptPos)->z = (*it).z - myV2.z;
00497 ptPos += stride;
00498 ++it;
00499 }
00500 }
00501 }
00502 else // independant sizes
00503 {
00504 const CVector v1 = CPSUtil::getCos((sint32) la._Angle2D) * I + CPSUtil::getSin((sint32) la._Angle2D) * K;
00505 const CVector v2 = - CPSUtil::getSin((sint32) la._Angle2D) * I + CPSUtil::getCos((sint32) la._Angle2D) * K;
00506
00507 float *currentSize2;
00508 float secondSize;
00509 uint32 currentSizeStep2;
00510 if (la._SecondSize.getSizeScheme())
00511 {
00512 currentSize2 = (float *) la._SecondSize.getSizeScheme()->make(la._Owner, size- leftToDo, pSecondSizes, sizeof(float), toProcess, true, srcStep);
00513 currentSizeStep2 = 1;
00514 }
00515 else
00516 {
00517 secondSize = la._SecondSize.getSize();
00518 currentSize2 = &secondSize;
00519 currentSizeStep2 = 0;
00520 }
00521
00522
00523 while (it != endIt)
00524 {
00525 CHECK_VERTEX_BUFFER(vb, ptPos);
00526 ((CVector *) ptPos)->x = (*it).x - *currentSize * v1.x + *currentSize2 * v2.x;
00527 ((CVector *) ptPos)->y = (*it).y - *currentSize * v1.y + *currentSize2 * v2.y;
00528 ((CVector *) ptPos)->z = (*it).z - *currentSize * v1.z + *currentSize2 * v2.z;
00529 ptPos += stride;
00530
00531 CHECK_VERTEX_BUFFER(vb, ptPos);
00532 ((CVector *) ptPos)->x = (*it).x + *currentSize * v1.x + *currentSize2 * v2.x;
00533 ((CVector *) ptPos)->y = (*it).y + *currentSize * v1.y + *currentSize2 * v2.y;
00534 ((CVector *) ptPos)->z = (*it).z + *currentSize * v1.z + *currentSize2 * v2.z;
00535 ptPos += stride;
00536
00537 CHECK_VERTEX_BUFFER(vb, ptPos);
00538 ((CVector *) ptPos)->x = (*it).x + *currentSize * v1.x - *currentSize2 * v2.x;
00539 ((CVector *) ptPos)->y = (*it).y + *currentSize * v1.y - *currentSize2 * v2.y;
00540 ((CVector *) ptPos)->z = (*it).z + *currentSize * v1.z - *currentSize2 * v2.z;
00541 ptPos += stride;
00542
00543 CHECK_VERTEX_BUFFER(vb, ptPos);
00544 ((CVector *) ptPos)->x = (*it).x - *currentSize * v1.x - *currentSize2 * v2.x;
00545 ((CVector *) ptPos)->y = (*it).y - *currentSize * v1.y - *currentSize2 * v2.y;
00546 ((CVector *) ptPos)->z = (*it).z - *currentSize * v1.z - *currentSize2 * v2.z;
00547 ptPos += stride;
00548 ++it;
00549 currentSize += currentSizeStep;
00550 currentSize2 += currentSizeStep2;
00551 }
00552 }
00553 //tmp
00554 //uint64 startTick = NLMISC::CTime::getPerformanceTime();
00555 driver->renderQuads(la._Mat, 0, toProcess);
00556 //PSLookAtRenderTime += NLMISC::CTime::getPerformanceTime() - startTick;
00557 }
00558 else
00559 {
00560 // perform motion, blur, we need an iterator on speed
00561 // independant sizes and rotation not supported for now with motion blur
00562 const CVector v1 = I + K;
00563 const CVector v2 = K - I;
00564 CVector startV, endV, mbv1, mbv1n, mbv12, mbv2;
00565 // norme of the v1 vect
00566 float n;
00567 const float epsilon = 10E-5f;
00568 const float normEpsilon = 10E-6f;
00569
00570 CMatrix tMat = la.getViewMat() * la._Owner->getLocalToWorldMatrix();
00571
00572 while (it != endIt)
00573 {
00574 // project the speed in the projection plane
00575 // this give us the v1 vect
00576 startV = tMat * *it ;
00577 endV = tMat * (*it + *speedIt);
00578 if (startV.y > epsilon || endV.y > epsilon)
00579 {
00580 if (startV.y < epsilon)
00581 {
00582 if (fabsf(endV.y - startV.y) > normEpsilon)
00583 {
00584 startV = endV + (endV.y - epsilon) / (endV.y - startV.y) * (startV - endV);
00585 }
00586 startV.y = epsilon;
00587 }
00588 else if (endV.y < epsilon)
00589 {
00590 if (fabsf(endV.y - startV.y) > normEpsilon)
00591 {
00592 endV = startV + (startV.y - epsilon) / (startV.y - endV.y) * (endV - startV);
00593 }
00594 endV.y = epsilon;
00595 }
00596
00597 mbv1 = (startV.x / startV.y - endV.x / endV.y) * I
00598 + (startV.z / startV.y - endV.z / endV.y) * K ;
00599
00600 n = mbv1.norm();
00601 if (n > la._Threshold)
00602 {
00603 mbv1 *= la._Threshold / n;
00604 n = la._Threshold;
00605 }
00606 if (n > normEpsilon)
00607 {
00608 mbv1n = mbv1 / n;
00609 mbv2 = *currentSize * (J ^ mbv1n);
00610 mbv12 = -*currentSize * mbv1n;
00611 mbv1 *= *currentSize * (1 + la._MotionBlurCoeff * n * n) / n;
00612
00613 *(CVector *) ptPos = *it - mbv2;
00614 *(CVector *) (ptPos + stride) = *it + mbv1;
00615 *(CVector *) (ptPos + stride2) = *it + mbv2;
00616 *(CVector *) (ptPos + stride3) = *it + mbv12;
00617
00618
00619 CHECK_VERTEX_BUFFER(vb, ptPos);
00620 ((CVector *) ptPos)->x = (*it).x - mbv2.x;
00621 ((CVector *) ptPos)->y = (*it).y - mbv2.y;
00622 ((CVector *) ptPos)->z = (*it).z - mbv2.z;
00623
00624 CHECK_VERTEX_BUFFER(vb, ptPos + stride);
00625 ((CVector *) (ptPos + stride))->x = (*it).x + mbv1.x;
00626 ((CVector *) (ptPos + stride))->y = (*it).y + mbv1.y;
00627 ((CVector *) (ptPos + stride))->z = (*it).z + mbv1.z;
00628
00629 CHECK_VERTEX_BUFFER(vb, ptPos + stride2);
00630 ((CVector *) (ptPos + stride2))->x = (*it).x + mbv2.x;
00631 ((CVector *) (ptPos + stride2))->y = (*it).y + mbv2.y;
00632 ((CVector *) (ptPos + stride2))->z = (*it).z + mbv2.z;
00633
00634
00635 CHECK_VERTEX_BUFFER(vb, ptPos + stride3);
00636 ((CVector *) (ptPos + stride3))->x = (*it).x + mbv12.x;
00637 ((CVector *) (ptPos + stride3))->y = (*it).y + mbv12.y;
00638 ((CVector *) (ptPos + stride3))->z = (*it).z + mbv12.z;
00639
00640 }
00641 else // speed too small, we must avoid imprecision
00642 {
00643 CHECK_VERTEX_BUFFER(vb, ptPos);
00644 ((CVector *) ptPos)->x = (*it).x - *currentSize * v2.x;
00645 ((CVector *) ptPos)->y = (*it).y - *currentSize * v2.y;
00646 ((CVector *) ptPos)->z = (*it).z - *currentSize * v2.z;
00647
00648 CHECK_VERTEX_BUFFER(vb, ptPos + stride);
00649 ((CVector *) (ptPos + stride))->x = (*it).x + *currentSize * v1.x;
00650 ((CVector *) (ptPos + stride))->y = (*it).y + *currentSize * v1.y;
00651 ((CVector *) (ptPos + stride))->z = (*it).z + *currentSize * v1.z;
00652
00653 CHECK_VERTEX_BUFFER(vb, ptPos + stride2);
00654 ((CVector *) (ptPos + stride2))->x = (*it).x + *currentSize * v2.x;
00655 ((CVector *) (ptPos + stride2))->y = (*it).y + *currentSize * v2.y;
00656 ((CVector *) (ptPos + stride2))->z = (*it).z + *currentSize * v2.z;
00657
00658
00659 CHECK_VERTEX_BUFFER(vb, ptPos + stride3);
00660 ((CVector *) (ptPos + stride3))->x = (*it).x - *currentSize * v1.x;
00661 ((CVector *) (ptPos + stride3))->y = (*it).y - *currentSize * v1.y;
00662 ((CVector *) (ptPos + stride3))->z = (*it).z - *currentSize * v1.z;
00663 }
00664 }
00665 else
00666 {
00667
00668 CHECK_VERTEX_BUFFER(vb, ptPos);
00669 ((CVector *) ptPos)->x = (*it).x - *currentSize * v2.x;
00670 ((CVector *) ptPos)->y = (*it).y - *currentSize * v2.y;
00671 ((CVector *) ptPos)->z = (*it).z - *currentSize * v2.z;
00672
00673 CHECK_VERTEX_BUFFER(vb, ptPos + stride);
00674 ((CVector *) (ptPos + stride))->x = (*it).x + *currentSize * v1.x;
00675 ((CVector *) (ptPos + stride))->y = (*it).y + *currentSize * v1.y;
00676 ((CVector *) (ptPos + stride))->z = (*it).z + *currentSize * v1.z;
00677
00678 CHECK_VERTEX_BUFFER(vb, ptPos + stride2);
00679 ((CVector *) (ptPos + stride2))->x = (*it).x + *currentSize * v2.x;
00680 ((CVector *) (ptPos + stride2))->y = (*it).y + *currentSize * v2.y;
00681 ((CVector *) (ptPos + stride2))->z = (*it).z + *currentSize * v2.z;
00682
00683
00684 CHECK_VERTEX_BUFFER(vb, ptPos + stride3);
00685 ((CVector *) (ptPos + stride3))->x = (*it).x - *currentSize * v1.x;
00686 ((CVector *) (ptPos + stride3))->y = (*it).y - *currentSize * v1.y;
00687 ((CVector *) (ptPos + stride3))->z = (*it).z - *currentSize * v1.z;
00688 }
00689
00690 ptPos += stride4;
00691 ++it;
00692 ++speedIt;
00693 currentSize += currentSizeStep;
00694 }
00695 //uint64 startTick = NLMISC::CTime::getPerformanceTime();
00696 driver->renderOrientedQuads(la._Mat, 0, toProcess);
00697 //PSLookAtRenderTime += NLMISC::CTime::getPerformanceTime() - startTick;
00698 }
00699 leftToDo -= toProcess;
00700 }
00701 while (leftToDo);
00702 }
00703 else
00704 {
00705 float pAngles[CPSQuad::quadBufSize]; // the angles to use
00706 float *currentAngle;
00707 do
00708 {
00709 // restart at the beginning of the vertex buffer
00710 ptPos = (uint8 *) vb.getVertexCoordPointer();
00711 toProcess = leftToDo <= CPSQuad::quadBufSize ? leftToDo : CPSQuad::quadBufSize;
00712 if (la._SizeScheme)
00713 {
00714 currentSize = (float *) la._SizeScheme->make(la._Owner, size - leftToDo, pSizes, sizeof(float), toProcess, true, srcStep);
00715 }
00716 else
00717 {
00718 currentSize = &la._ParticleSize;
00719 }
00720 currentAngle = (float *) la._Angle2DScheme->make(la._Owner, size - leftToDo, pAngles, sizeof(float), toProcess, true, srcStep);
00721 la.updateVbColNUVForRender(vb, size - leftToDo, toProcess, srcStep);
00722 T endIt = it + toProcess;
00723 CVector v1, v2;
00724 NLMISC::OptFastFloorBegin();
00725 if (!la._IndependantSizes)
00726 {
00727 while (it != endIt)
00728 {
00729 const uint32 tabIndex = ((NLMISC::OptFastFloor(*currentAngle)) & 0xff) << 2;
00730 // lets avoid some ctor calls
00731 v1.x = *currentSize * (rotTable[tabIndex] * I.x + rotTable[tabIndex + 1] * K.x);
00732 v1.y = *currentSize * (rotTable[tabIndex] * I.y + rotTable[tabIndex + 1] * K.y);
00733 v1.z = *currentSize * (rotTable[tabIndex] * I.z + rotTable[tabIndex + 1] * K.z);
00734
00735 v2.x = *currentSize * (rotTable[tabIndex + 2] * I.x + rotTable[tabIndex + 3] * K.x);
00736 v2.y = *currentSize * (rotTable[tabIndex + 2] * I.y + rotTable[tabIndex + 3] * K.y);
00737 v2.z = *currentSize * (rotTable[tabIndex + 2] * I.z + rotTable[tabIndex + 3] * K.z);
00738
00739 CHECK_VERTEX_BUFFER(vb, ptPos);
00740 CHECK_VERTEX_BUFFER(vb, ptPos + stride);
00741 CHECK_VERTEX_BUFFER(vb, ptPos + stride2);
00742 CHECK_VERTEX_BUFFER(vb, ptPos + stride3);
00743
00744 ((CVector *) ptPos)->x = (*it).x + v1.x;
00745 ((CVector *) ptPos)->y = (*it).y + v1.y;
00746 ((CVector *) ptPos)->z = (*it).z + v1.z;
00747 ptPos += stride;
00748
00749 ((CVector *) ptPos)->x = (*it).x + v2.x;
00750 ((CVector *) ptPos)->y = (*it).y + v2.y;
00751 ((CVector *) ptPos)->z = (*it).z + v2.z;
00752 ptPos += stride;
00753
00754 ((CVector *) ptPos)->x = (*it).x - v1.x;
00755 ((CVector *) ptPos)->y = (*it).y - v1.y;
00756 ((CVector *) ptPos)->z = (*it).z - v1.z;
00757 ptPos += stride;
00758
00759 ((CVector *) ptPos)->x = (*it).x - v2.x;
00760 ((CVector *) ptPos)->y = (*it).y - v2.y;
00761 ((CVector *) ptPos)->z = (*it).z - v2.z;
00762 ptPos += stride;
00763
00764 ++it;
00765 currentSize += currentSizeStep;
00766 ++currentAngle;
00767 }
00768 }
00769 else // independant size, and non-constant rotation
00770 {
00771
00772 float *currentSize2;
00773 float secondSize;
00774 uint32 currentSizeStep2;
00775 if (la._SecondSize.getSizeScheme())
00776 {
00777 currentSize2 = (float *) la._SecondSize.getSizeScheme()->make(la._Owner, size- leftToDo, pSecondSizes, sizeof(float), toProcess, true, srcStep);
00778 currentSizeStep2 = 1;
00779 }
00780 else
00781 {
00782 secondSize = la._SecondSize.getSize();
00783 currentSize2 = &secondSize;
00784 currentSizeStep2 = 0;
00785 }
00786
00787 float cosAngle, sinAngle;
00788 while (it != endIt)
00789 {
00790 cosAngle = CPSUtil::getCos((sint32) *currentAngle);
00791 sinAngle = CPSUtil::getSin((sint32) *currentAngle);
00792 v1 = cosAngle * I + sinAngle * K;
00793 v2 = - sinAngle * I + cosAngle * K;
00794
00795 CHECK_VERTEX_BUFFER(vb, ptPos);
00796 ((CVector *) ptPos)->x = (*it).x - *currentSize * v1.x + *currentSize2 * v2.x;
00797 ((CVector *) ptPos)->y = (*it).y - *currentSize * v1.y + *currentSize2 * v2.y;
00798 ((CVector *) ptPos)->z = (*it).z - *currentSize * v1.z + *currentSize2 * v2.z;
00799 ptPos += stride;
00800
00801 CHECK_VERTEX_BUFFER(vb, ptPos);
00802 ((CVector *) ptPos)->x = (*it).x + *currentSize * v1.x + *currentSize2 * v2.x;
00803 ((CVector *) ptPos)->y = (*it).y + *currentSize * v1.y + *currentSize2 * v2.y;
00804 ((CVector *) ptPos)->z = (*it).z + *currentSize * v1.z + *currentSize2 * v2.z;
00805 ptPos += stride;
00806
00807 CHECK_VERTEX_BUFFER(vb, ptPos);
00808 ((CVector *) ptPos)->x = (*it).x + *currentSize * v1.x - *currentSize2 * v2.x;
00809 ((CVector *) ptPos)->y = (*it).y + *currentSize * v1.y - *currentSize2 * v2.y;
00810 ((CVector *) ptPos)->z = (*it).z + *currentSize * v1.z - *currentSize2 * v2.z;
00811 ptPos += stride;
00812
00813 CHECK_VERTEX_BUFFER(vb, ptPos);
00814 ((CVector *) ptPos)->x = (*it).x - *currentSize * v1.x - *currentSize2 * v2.x;
00815 ((CVector *) ptPos)->y = (*it).y - *currentSize * v1.y - *currentSize2 * v2.y;
00816 ((CVector *) ptPos)->z = (*it).z - *currentSize * v1.z - *currentSize2 * v2.z;
00817 ptPos += stride;
00818 ++it;
00819 ++currentAngle;
00820 currentSize += currentSizeStep;
00821 currentSize2 += currentSizeStep2;
00822 }
00823 }
00824 NLMISC::OptFastFloorEnd();
00825 //tmp
00826 // uint64 startTick = NLMISC::CTime::getPerformanceTime();
00827 driver->renderQuads(la._Mat, 0, toProcess);
00828 //PSLookAtRenderTime += NLMISC::CTime::getPerformanceTime() - startTick;*/
00829 leftToDo -= toProcess;
00830 }
00831 while (leftToDo);
00832 }
00833 PARTICLES_CHECK_MEM;
00834 }
|
|
||||||||||||||||||||||||||||
|
Draw look at and align them on motion Definition at line 89 of file ps_face_look_at.cpp. References NL3D::CPSRotated2DParticle::_Angle2D, NL3D::CPSRotated2DParticle::_Angle2DScheme, NL3D::CPSFaceLookAt::_IndependantSizes, NL3D::CPSMaterial::_Mat, NL3D::CPSLocatedBindable::_Owner, NL3D::CPSSizedParticle::_ParticleSize, NL3D::CPSFaceLookAt::_SecondSize, NL3D::CPSSizedParticle::_SizeScheme, NL3D::IDriver::activeVertexBuffer(), CHECK_VERTEX_BUFFER, NL3D::CPSLocatedBindable::computeI(), NL3D::CPSLocatedBindable::computeK(), computeOrientationVectors(), NL3D::CPSLocatedBindable::getDriver(), NL3D::CPSQuad::getNeededVB(), NL3D::CPSSizedParticle::getSize(), NL3D::CPSSizedParticle::getSizeScheme(), NL3D::CVertexBuffer::getVertexCoordPointer(), NL3D::CVertexBuffer::getVertexSize(), NL3D::CLookAtAlign::I, NL3D::CPSLocated::incrementNbDrawnParticles(), NL3D::CLookAtAlign::K, NL3D::CPSAttribMaker< float >::make(), nlassert, NLMISC::OptFastFloor(), NLMISC::OptFastFloorBegin(), NLMISC::OptFastFloorEnd(), PARTICLES_CHECK_MEM, NL3D::IDriver::renderQuads(), NL3D::CPSLocatedBindable::setupDriverModelMatrix(), sint32, size, stride, uint, uint32, uint8, NL3D::CPSQuad::updateMatBeforeRendering(), NL3D::CPSQuad::updateVbColNUVForRender(), NLMISC::CVector::x, NLMISC::CVector::y, and NLMISC::CVector::z.
00090 {
00091 PARTICLES_CHECK_MEM;
00092 nlassert(la._Owner);
00093 IDriver *driver = la.getDriver();
00094
00095 la.updateMatBeforeRendering(driver);
00096
00097 CVertexBuffer &vb = la.getNeededVB();
00098 la._Owner->incrementNbDrawnParticles(size); // for benchmark purpose
00099 la.setupDriverModelMatrix();
00100 driver->activeVertexBuffer(vb);
00101 const CVector I = la.computeI();
00102 const CVector K = la.computeK();
00103 const float *rotTable = CPSRotated2DParticle::getRotTable();
00104 // for each the particle can be constantly rotated or have an independant rotation for each particle
00105 // number of face left, and number of face to process at once
00106 uint32 leftToDo = size, toProcess;
00107 float pSizes[CPSQuad::quadBufSize]; // the sizes to use
00108 float pSecondSizes[CPSQuad::quadBufSize]; // the second sizes to use
00109 uint8 laAlignRaw[sizeof(CLookAtAlign) * CPSQuad::quadBufSize]; // orientation computed from motion for each particle
00110 CLookAtAlign *laAlign = (CLookAtAlign *) laAlignRaw; // cast to avoid unilined ctor calls
00111 float *currentSize;
00112 uint32 currentSizeStep = la._SizeScheme ? 1 : 0;
00113 // point the vector part in the current vertex
00114 uint8 *ptPos;
00115 // strides to go from one vertex to another one
00116 const uint32 stride = vb.getVertexSize(), stride2 = stride << 1, stride3 = stride + stride2, stride4 = stride << 2;
00117 if (!la._Angle2DScheme)
00118 {
00119 // constant rotation case
00120 do
00121 {
00122 // restart at the beginning of the vertex buffer
00123 ptPos = (uint8 *) vb.getVertexCoordPointer();
00124 toProcess = leftToDo <= CPSQuad::quadBufSize ? leftToDo : CPSQuad::quadBufSize;
00125
00126 if (la._SizeScheme)
00127 {
00128 currentSize = (float *) la._SizeScheme->make(la._Owner, size- leftToDo, pSizes, sizeof(float), toProcess, true, srcStep);
00129 }
00130 else
00131 {
00132 currentSize = &la._ParticleSize;
00133 }
00134 computeOrientationVectors(speedIt, I, K, laAlign, toProcess);
00135 speedIt = speedIt + toProcess;
00136 const CLookAtAlign *currAlign = laAlign;
00137
00138 la.updateVbColNUVForRender(vb, size - leftToDo, toProcess, srcStep);
00139 T endIt = it + toProcess;
00140 if (!la._IndependantSizes)
00141 {
00142 const uint32 tabIndex = (((uint32) la._Angle2D) & 0xff) << 2;
00143 CVector v1;
00144 CVector v2;
00145 // TODO : optimize if necessary
00146 while (it != endIt)
00147 {
00148 v1 = rotTable[tabIndex] * currAlign->I + rotTable[tabIndex + 1] * currAlign->K;
00149 v2 = rotTable[tabIndex + 2] * currAlign->I + rotTable[tabIndex + 3] * currAlign->K;
00150 CHECK_VERTEX_BUFFER(vb, ptPos);
00151 ((CVector *) ptPos)->x = (*it).x + *currentSize * v1.x;
00152 ((CVector *) ptPos)->y = (*it).y + *currentSize * v1.y;
00153 ((CVector *) ptPos)->z = (*it).z + *currentSize * v1.z;
00154 ptPos += stride;
00155
00156 CHECK_VERTEX_BUFFER(vb, ptPos);
00157 ((CVector *) ptPos)->x = (*it).x + *currentSize * v2.x;
00158 ((CVector *) ptPos)->y = (*it).y + *currentSize * v2.y;
00159 ((CVector *) ptPos)->z = (*it).z + *currentSize * v2.z;
00160 ptPos += stride;
00161
00162 CHECK_VERTEX_BUFFER(vb, ptPos);
00163 ((CVector *) ptPos)->x = (*it).x - *currentSize * v1.x;
00164 ((CVector *) ptPos)->y = (*it).y - *currentSize * v1.y;
00165 ((CVector *) ptPos)->z = (*it).z - *currentSize * v1.z;
00166 ptPos += stride;
00167
00168 CHECK_VERTEX_BUFFER(vb, ptPos);
00169 ((CVector *) ptPos)->x = (*it).x - *currentSize * v2.x;
00170 ((CVector *) ptPos)->y = (*it).y - *currentSize * v2.y;
00171 ((CVector *) ptPos)->z = (*it).z - *currentSize * v2.z;
00172 ptPos += stride;
00173
00174 ++it;
00175 ++currAlign;
00176 currentSize += currentSizeStep;
00177 }
00178 }
00179 else // independant sizes
00180 {
00181 float *currentSize2;
00182 float secondSize;
00183 uint32 currentSizeStep2;
00184 if (la._SecondSize.getSizeScheme())
00185 {
00186 currentSize2 = (float *) la._SecondSize.getSizeScheme()->make(la._Owner, size- leftToDo, pSecondSizes, sizeof(float), toProcess, true, srcStep);
00187 currentSizeStep2 = 1;
00188 }
00189 else
00190 {
00191 secondSize = la._SecondSize.getSize();
00192 currentSize2 = &secondSize;
00193 currentSizeStep2 = 0;
00194 }
00195 CVector v1;
00196 CVector v2;
00197 // TODO : optimize if necessary
00198 while (it != endIt)
00199 {
00200 v1 = CPSUtil::getCos((sint32) la._Angle2D) * currAlign->I + CPSUtil::getSin((sint32) la._Angle2D) * currAlign->K;
00201 v2 = - CPSUtil::getSin((sint32) la._Angle2D) * currAlign->I + CPSUtil::getCos((sint32) la._Angle2D) * currAlign->K;
00202 CHECK_VERTEX_BUFFER(vb, ptPos);
00203 ((CVector *) ptPos)->x = (*it).x - *currentSize * v1.x + *currentSize2 * v2.x;
00204 ((CVector *) ptPos)->y = (*it).y - *currentSize * v1.y + *currentSize2 * v2.y;
00205 ((CVector *) ptPos)->z = (*it).z - *currentSize * v1.z + *currentSize2 * v2.z;
00206 ptPos += stride;
00207
00208 CHECK_VERTEX_BUFFER(vb, ptPos);
00209 ((CVector *) ptPos)->x = (*it).x + *currentSize * v1.x + *currentSize2 * v2.x;
00210 ((CVector *) ptPos)->y = (*it).y + *currentSize * v1.y + *currentSize2 * v2.y;
00211 ((CVector *) ptPos)->z = (*it).z + *currentSize * v1.z + *currentSize2 * v2.z;
00212 ptPos += stride;
00213
00214 CHECK_VERTEX_BUFFER(vb, ptPos);
00215 ((CVector *) ptPos)->x = (*it).x + *currentSize * v1.x - *currentSize2 * v2.x;
00216 ((CVector *) ptPos)->y = (*it).y + *currentSize * v1.y - *currentSize2 * v2.y;
00217 ((CVector *) ptPos)->z = (*it).z + *currentSize * v1.z - *currentSize2 * v2.z;
00218 ptPos += stride;
00219
00220 CHECK_VERTEX_BUFFER(vb, ptPos);
00221 ((CVector *) ptPos)->x = (*it).x - *currentSize * v1.x - *currentSize2 * v2.x;
00222 ((CVector *) ptPos)->y = (*it).y - *currentSize * v1.y - *currentSize2 * v2.y;
00223 ((CVector *) ptPos)->z = (*it).z - *currentSize * v1.z - *currentSize2 * v2.z;
00224 ptPos += stride;
00225 ++it;
00226 ++currAlign;
00227 currentSize += currentSizeStep;
00228 currentSize2 += currentSizeStep2;
00229 }
00230 }
00231 // uint64 startTick = NLMISC::CTime::getPerformanceTime();
00232 driver->renderQuads(la._Mat, 0, toProcess);
00233 // PSLookAtRenderTime += NLMISC::CTime::getPerformanceTime() - startTick;
00234 leftToDo -= toProcess;
00235 }
00236 while (leftToDo);
00237 }
00238 else
00239 {
00240 float pAngles[CPSQuad::quadBufSize]; // the angles to use
00241 float *currentAngle;
00242 do
00243 {
00244 // restart at the beginning of the vertex buffer
00245 ptPos = (uint8 *) vb.getVertexCoordPointer();
00246 toProcess = leftToDo <= CPSQuad::quadBufSize ? leftToDo : CPSQuad::quadBufSize;
00247 if (la._SizeScheme)
00248 {
00249 currentSize = (float *) la._SizeScheme->make(la._Owner, size - leftToDo, pSizes, sizeof(float), toProcess, true, srcStep);
00250 }
00251 else
00252 {
00253 currentSize = &la._ParticleSize;
00254 }
00255 computeOrientationVectors(speedIt, I, K, laAlign, toProcess);
00256 speedIt = speedIt + toProcess;
00257 const CLookAtAlign *currAlign = laAlign;
00258 currentAngle = (float *) la._Angle2DScheme->make(la._Owner, size - leftToDo, pAngles, sizeof(float), toProcess, true, srcStep);
00259 la.updateVbColNUVForRender(vb, size - leftToDo, toProcess, srcStep);
00260 T endIt = it + toProcess;
00261 CVector v1, v2;
00262 NLMISC::OptFastFloorBegin();
00263 if (!la._IndependantSizes)
00264 {
00265 while (it != endIt)
00266 {
00267 const uint32 tabIndex = ((NLMISC::OptFastFloor(*currentAngle)) & 0xff) << 2;
00268 // lets avoid some ctor calls
00269 v1.x = *currentSize * (rotTable[tabIndex] * currAlign->I.x + rotTable[tabIndex + 1] * currAlign->K.x);
00270 v1.y = *currentSize * (rotTable[tabIndex] * currAlign->I.y + rotTable[tabIndex + 1] * currAlign->K.y);
00271 v1.z = *currentSize * (rotTable[tabIndex] * currAlign->I.z + rotTable[tabIndex + 1] * currAlign->K.z);
00272
00273 v2.x = *currentSize * (rotTable[tabIndex + 2] * currAlign->I.x + rotTable[tabIndex + 3] * currAlign->K.x);
00274 v2.y = *currentSize * (rotTable[tabIndex + 2] * currAlign->I.y + rotTable[tabIndex + 3] * currAlign->K.y);
00275 v2.z = *currentSize * (rotTable[tabIndex + 2] * currAlign->I.z + rotTable[tabIndex + 3] * currAlign->K.z);
00276
00277 CHECK_VERTEX_BUFFER(vb, ptPos);
00278 CHECK_VERTEX_BUFFER(vb, ptPos + stride);
00279 CHECK_VERTEX_BUFFER(vb, ptPos + stride2);
00280 CHECK_VERTEX_BUFFER(vb, ptPos + stride3);
00281
00282 ((CVector *) ptPos)->x = (*it).x + v1.x;
00283 ((CVector *) ptPos)->y = (*it).y + v1.y;
00284 ((CVector *) ptPos)->z = (*it).z + v1.z;
00285 ptPos += stride;
00286
00287 ((CVector *) ptPos)->x = (*it).x + v2.x;
00288 ((CVector *) ptPos)->y = (*it).y + v2.y;
00289 ((CVector *) ptPos)->z = (*it).z + v2.z;
00290 ptPos += stride;
00291
00292 ((CVector *) ptPos)->x = (*it).x - v1.x;
00293 ((CVector *) ptPos)->y = (*it).y - v1.y;
00294 ((CVector *) ptPos)->z = (*it).z - v1.z;
00295 ptPos += stride;
00296
00297 ((CVector *) ptPos)->x = (*it).x - v2.x;
00298 ((CVector *) ptPos)->y = (*it).y - v2.y;
00299 ((CVector *) ptPos)->z = (*it).z - v2.z;
00300 ptPos += stride;
00301
00302 ++it;
00303 ++ currAlign;
00304 currentSize += currentSizeStep;
00305 ++currentAngle;
00306 }
00307 }
00308 else // independant size, and non-constant rotation
00309 {
00310
00311 float *currentSize2;
00312 float secondSize;
00313 uint32 currentSizeStep2;
00314 if (la._SecondSize.getSizeScheme())
00315 {
00316 currentSize2 = (float *) la._SecondSize.getSizeScheme()->make(la._Owner, size- leftToDo, pSecondSizes, sizeof(float), toProcess, true, srcStep);
00317 currentSizeStep2 = 1;
00318 }
00319 else
00320 {
00321 secondSize = la._SecondSize.getSize();
00322 currentSize2 = &secondSize;
00323 currentSizeStep2 = 0;
00324 }
00325
00326 float cosAngle, sinAngle;
00327 while (it != endIt)
00328 {
00329 cosAngle = CPSUtil::getCos((sint32) *currentAngle);
00330 sinAngle = CPSUtil::getSin((sint32) *currentAngle);
00331 v1 = cosAngle * currAlign->I + sinAngle * currAlign->K;
00332 v2 = - sinAngle * currAlign->I + cosAngle * currAlign->K;
00333
00334 CHECK_VERTEX_BUFFER(vb, ptPos);
00335 ((CVector *) ptPos)->x = (*it).x - *currentSize * v1.x + *currentSize2 * v2.x;
00336 ((CVector *) ptPos)->y = (*it).y - *currentSize * v1.y + *currentSize2 * v2.y;
00337 ((CVector *) ptPos)->z = (*it).z - *currentSize * v1.z + *currentSize2 * v2.z;
00338 ptPos += stride;
00339
00340 CHECK_VERTEX_BUFFER(vb, ptPos);
00341 ((CVector *) ptPos)->x = (*it).x + *currentSize * v1.x + *currentSize2 * v2.x;
00342 ((CVector *) ptPos)->y = (*it).y + *currentSize * v1.y + *currentSize2 * v2.y;
00343 ((CVector *) ptPos)->z = (*it).z + *currentSize * v1.z + *currentSize2 * v2.z;
00344 ptPos += stride;
00345
00346 CHECK_VERTEX_BUFFER(vb, ptPos);
00347 ((CVector *) ptPos)->x = (*it).x + *currentSize * v1.x - *currentSize2 * v2.x;
00348 ((CVector *) ptPos)->y = (*it).y + *currentSize * v1.y - *currentSize2 * v2.y;
00349 ((CVector *) ptPos)->z = (*it).z + *currentSize * v1.z - *currentSize2 * v2.z;
00350 ptPos += stride;
00351
00352 CHECK_VERTEX_BUFFER(vb, ptPos);
00353 ((CVector *) ptPos)->x = (*it).x - *currentSize * v1.x - *currentSize2 * v2.x;
00354 ((CVector *) ptPos)->y = (*it).y - *currentSize * v1.y - *currentSize2 * v2.y;
00355 ((CVector *) ptPos)->z = (*it).z - *currentSize * v1.z - *currentSize2 * v2.z;
00356 ptPos += stride;
00357 ++it;
00358 ++currentAngle;
00359 ++ currAlign;
00360 currentSize += currentSizeStep;
00361 currentSize2 += currentSizeStep2;
00362 }
00363 }
00364 NLMISC::OptFastFloorEnd();
00365 //tmp
00366 // uint64 startTick = NLMISC::CTime::getPerformanceTime();
00367 driver->renderQuads(la._Mat, 0, toProcess);
00368 // PSLookAtRenderTime += NLMISC::CTime::getPerformanceTime() - startTick;
00369 leftToDo -= toProcess;
00370 }
00371 while (leftToDo);
00372 }
00373 PARTICLES_CHECK_MEM;
00374 }
|
1.3.6