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 } |