Definition at line 517 of file ps_mesh.cpp.
Static Public Member Functions | |
template<class T> void | drawMeshs (T posIt, CPSConstraintMesh &m, uint size, uint32 srcStep, bool opaque) |
template<class T, class U> void | drawPrerotatedMeshs (T posIt, U indexIt, CPSConstraintMesh &m, uint size, uint32 srcStep, bool opaque, TAnimationTime ellapsedTime) |
|
get a vb in which to write. It has the same format than the input mesh, but can also have a color flag added unmorphed case constant case Definition at line 521 of file ps_mesh.cpp. References NL3D::CPSColoredParticle::_ColorScheme, NL3D::CPSConstraintMesh::_GlobalAnimDate, NL3D::CPSConstraintMesh::_MeshDisplayShare, NL3D::CPSConstraintMesh::_Meshes, NL3D::CPSConstraintMesh::_MorphScheme, NL3D::CPSConstraintMesh::_MorphValue, NL3D::CPSLocatedBindable::_Owner, NL3D::CPSSizedParticle::_ParticleSize, NL3D::CPSRotated3DPlaneParticle::_PlaneBasis, NL3D::CPSRotated3DPlaneParticle::_PlaneBasisScheme, NL3D::CPSSizedParticle::_SizeScheme, NL3D::IDriver::activeVertexBuffer(), CHECK_VERTEX_BUFFER, NL3D::CPSConstraintMesh::computeColors(), NL3D::ConstraintMeshBufSize, NL3D::CPSConstraintMesh::doRenderPasses(), NL3D::CPSLocatedBindable::getDriver(), NL3D::CVertexBuffer::getNormalOff(), NL3D::CVertexBuffer::getNumVertices(), NL3D::CParticleSystemProcess::getOwner(), NL3D::CParticleSystem::getSystemDate(), NL3D::CMesh::getVertexBuffer(), NL3D::CVertexBuffer::getVertexCoordPointer(), NL3D::CVertexBuffer::getVertexFormat(), NL3D::CVertexBuffer::getVertexSize(), NLMISC::CMatrix::identity(), NL3D::CPSAttribMaker< CPlaneBasis >::make(), NL3D::CPSAttribMaker< float >::make(), min, NL3D::CPSConstraintMesh::CMeshDisplay::RdrPasses, NLMISC::CMatrix::scale(), NLMISC::CMatrix::setRot(), NL3D::CPSLocatedBindable::setupDriverModelMatrix(), NL3D::CPSConstraintMesh::setupRenderPasses(), sint, size, uint, uint32, uint8, NL3D::CPSConstraintMesh::CMeshDisplay::VB, NL3D::CPlaneBasis::X, and NL3D::CPlaneBasis::Y.
00522 { 00523 CMesh &mesh = * NLMISC::safe_cast<CMesh *>((IShape *) m._Meshes[0]); 00524 const CVertexBuffer &modelVb = mesh.getVertexBuffer(); 00525 00526 // size for model vertices 00527 const uint inVSize = modelVb.getVertexSize(); // vertex size 00528 00529 // driver setup 00530 IDriver *driver = m.getDriver(); 00531 m.setupDriverModelMatrix(); 00532 00533 // buffer to compute sizes 00534 float sizes[ConstraintMeshBufSize]; 00535 00536 float *ptCurrSize; 00537 uint ptCurrSizeIncrement = m._SizeScheme ? 1 : 0; 00538 00539 T endPosIt; 00540 uint leftToDo = size, toProcess; 00541 00543 CPSConstraintMesh::CMeshDisplay &md= m._MeshDisplayShare.getMeshDisplay(m._Meshes[0], modelVb.getVertexFormat() 00544 | (m._ColorScheme ? CVertexBuffer::PrimaryColorFlag : 0)); 00545 00546 m.setupRenderPasses((float) m._Owner->getOwner()->getSystemDate() - m._GlobalAnimDate, md.RdrPasses, opaque); 00547 00548 CVertexBuffer &outVb = md.VB; 00549 const uint outVSize = outVb.getVertexSize(); 00550 00551 driver->activeVertexBuffer(outVb); 00552 00553 // we don't have precomputed mesh there ... so each mesh must be transformed, which is the worst case 00554 CPlaneBasis planeBasis[ConstraintMeshBufSize]; 00555 CPlaneBasis *ptBasis; 00556 uint ptBasisIncrement = m._PlaneBasisScheme ? 1 : 0; 00557 00558 const uint nbVerticesInSource = modelVb.getNumVertices(); 00559 00560 sint inNormalOff=0; 00561 sint outNormalOff=0; 00562 if (modelVb.getVertexFormat() & CVertexBuffer::NormalFlag) 00563 { 00564 inNormalOff = modelVb.getNormalOff(); 00565 outNormalOff = outVb.getNormalOff(); 00566 } 00567 00568 do 00569 { 00570 uint8 *outVertex = (uint8 *) outVb.getVertexCoordPointer(); 00571 00572 toProcess = std::min(leftToDo, ConstraintMeshBufSize); 00573 00574 if (m._SizeScheme) 00575 { 00576 ptCurrSize = (float *) (m._SizeScheme->make(m._Owner, size -leftToDo, &sizes[0], sizeof(float), toProcess, true, srcStep)); 00577 } 00578 else 00579 { 00580 ptCurrSize = &m._ParticleSize; 00581 } 00582 00583 if (m._PlaneBasisScheme) 00584 { 00585 ptBasis = (CPlaneBasis *) (m._PlaneBasisScheme->make(m._Owner, size -leftToDo, &planeBasis[0], sizeof(CPlaneBasis), toProcess, true, srcStep)); 00586 } 00587 else 00588 { 00589 ptBasis = &m._PlaneBasis; 00590 } 00591 00592 00593 endPosIt = posIt + toProcess; 00594 // transfo matrix & scaled transfo matrix; 00595 CMatrix M, sM; 00596 00597 00598 if (m._Meshes.size() == 1) 00599 { 00601 do 00602 { 00603 00604 uint8 *inVertex = (uint8 *) modelVb.getVertexCoordPointer(); 00605 uint k = nbVerticesInSource; 00606 00607 // do we need a normal ? 00608 if (modelVb.getVertexFormat() & CVertexBuffer::NormalFlag) 00609 { 00610 M.identity(); 00611 M.setRot(ptBasis->X, ptBasis->Y, ptBasis->X ^ ptBasis->Y); 00612 sM = M; 00613 sM.scale(*ptCurrSize); 00614 00615 // offset of normals in the prerotated mesh 00616 do 00617 { 00618 CHECK_VERTEX_BUFFER(modelVb, inVertex); 00619 CHECK_VERTEX_BUFFER(outVb, outVertex); 00620 CHECK_VERTEX_BUFFER(modelVb, inVertex + inNormalOff); 00621 CHECK_VERTEX_BUFFER(outVb, outVertex + outNormalOff); 00622 00623 // translate and resize the vertex (relatively to the mesh origin) 00624 *(CVector *) outVertex = *posIt + sM * *(CVector *) inVertex; 00625 // copy the normal 00626 *(CVector *) (outVertex + outNormalOff) = M * *(CVector *) (inVertex + inNormalOff); 00627 00628 00629 inVertex += inVSize; 00630 outVertex += outVSize; 00631 } 00632 while (--k); 00633 } 00634 else 00635 { 00636 // no normal to transform 00637 sM.identity(); 00638 sM.setRot(ptBasis->X, ptBasis->Y, ptBasis->X ^ ptBasis->Y); 00639 sM.scale(*ptCurrSize); 00640 00641 do 00642 { 00643 CHECK_VERTEX_BUFFER(modelVb, inVertex); 00644 CHECK_VERTEX_BUFFER(outVb, outVertex); 00645 00646 // translate and resize the vertex (relatively to the mesh origin) 00647 *(CVector *) outVertex = *posIt + sM * *(CVector *) inVertex; 00648 00649 inVertex += inVSize; 00650 outVertex += outVSize; 00651 } 00652 while (--k); 00653 } 00654 00655 00656 ++posIt; 00657 ptCurrSize += ptCurrSizeIncrement; 00658 ptBasis += ptBasisIncrement; 00659 } 00660 while (posIt != endPosIt); 00661 } 00662 else 00663 { 00664 // morphed case 00665 00666 // first, compute the morph value for each mesh 00667 float morphValues[ConstraintMeshBufSize]; 00668 float *currMorphValue; 00669 uint morphValueIncr; 00670 00671 if (m._MorphScheme) // variable case 00672 { 00673 currMorphValue = (float *) m._MorphScheme->make(m._Owner, size - leftToDo, &morphValues[0], sizeof(float), toProcess, true, srcStep); 00674 morphValueIncr = 1; 00675 } 00676 else 00677 { 00678 currMorphValue = &m._MorphValue; 00679 morphValueIncr = 0; 00680 } 00681 00682 do 00683 { 00684 const uint numShapes = m._Meshes.size(); 00685 const uint8 *m0, *m1; 00686 float lambda; 00687 float opLambda; 00688 const CVertexBuffer *inVB0, *inVB1; 00689 if (*currMorphValue >= numShapes - 1) 00690 { 00691 lambda = 0.f; 00692 opLambda = 1.f; 00693 inVB0 = inVB1 = &(m._Meshes[numShapes - 1]->getVertexBuffer()); 00694 } 00695 else if (*currMorphValue <= 0) 00696 { 00697 lambda = 0.f; 00698 opLambda = 1.f; 00699 inVB0 = inVB1 = &(m._Meshes[0]->getVertexBuffer()); 00700 } 00701 else 00702 { 00703 uint iMeshIndex = (uint) *currMorphValue; 00704 lambda = *currMorphValue - iMeshIndex; 00705 opLambda = 1.f - lambda; 00706 inVB0 = &(m._Meshes[iMeshIndex]->getVertexBuffer()); 00707 inVB1 = &(m._Meshes[iMeshIndex + 1]->getVertexBuffer()); 00708 } 00709 00710 m0 = (uint8 *) inVB0->getVertexCoordPointer(); 00711 m1 = (uint8 *) inVB1->getVertexCoordPointer(); 00712 00713 00714 uint k = nbVerticesInSource; 00715 // do we need a normal ? 00716 if (modelVb.getVertexFormat() & CVertexBuffer::NormalFlag) 00717 { 00718 M.identity(); 00719 M.setRot(ptBasis->X, ptBasis->Y, ptBasis->X ^ ptBasis->Y); 00720 sM = M; 00721 sM.scale(*ptCurrSize); 00722 00723 // offset of normals in the prerotated mesh 00724 do 00725 { 00726 CHECK_VERTEX_BUFFER((*inVB0), m0); 00727 CHECK_VERTEX_BUFFER((*inVB1), m1); 00728 CHECK_VERTEX_BUFFER((*inVB0), m0 + inNormalOff); 00729 CHECK_VERTEX_BUFFER((*inVB1), m1 + inNormalOff); 00730 CHECK_VERTEX_BUFFER(outVb, outVertex); 00731 CHECK_VERTEX_BUFFER(outVb, outVertex + outNormalOff); 00732 00733 // morph, and transform the vertex 00734 *(CVector *) outVertex = *posIt + sM * (opLambda * *(CVector *) m0 + lambda * *(CVector *) m1); 00735 // morph, and transform the normal 00736 *(CVector *) (outVertex + outNormalOff) = M * (opLambda * *(CVector *) (m0 + inNormalOff) 00737 + lambda * *(CVector *) (m1 + inNormalOff)).normed(); 00738 00739 00740 m0 += inVSize; 00741 m1 += inVSize; 00742 outVertex += outVSize; 00743 } 00744 while (--k); 00745 } 00746 else 00747 { 00748 // no normal to transform 00749 sM.identity(); 00750 sM.setRot(ptBasis->X, ptBasis->Y, ptBasis->X ^ ptBasis->Y); 00751 sM.scale(*ptCurrSize); 00752 00753 do 00754 { 00755 CHECK_VERTEX_BUFFER((*inVB0), m0); 00756 CHECK_VERTEX_BUFFER((*inVB1), m1); 00757 CHECK_VERTEX_BUFFER(outVb, outVertex); 00758 // morph, and transform the vertex 00759 *(CVector *) outVertex = *posIt + sM * (opLambda * *(CVector *) m0 + opLambda * *(CVector *) m1); 00760 00761 m0 += inVSize; 00762 m1 += inVSize; 00763 outVertex += outVSize; 00764 } 00765 while (--k); 00766 } 00767 00768 00769 ++posIt; 00770 ptCurrSize += ptCurrSizeIncrement; 00771 ptBasis += ptBasisIncrement; 00772 currMorphValue += morphValueIncr; 00773 } 00774 while (posIt != endPosIt); 00775 } 00776 00777 // compute colors if needed 00778 if (m._ColorScheme) 00779 { 00780 m.computeColors(outVb, modelVb, size - leftToDo, toProcess, srcStep); 00781 } 00782 00783 // render meshs 00784 m.doRenderPasses(driver, toProcess, md.RdrPasses, opaque); 00785 leftToDo -= toProcess; 00786 00787 } 00788 while (leftToDo); 00789 } |
|
precompute rotation in a VB from the src mesh get a mesh display struct on this shape, with eventually a primary color added. copy datas for several mesh render the result Definition at line 793 of file ps_mesh.cpp. References NL3D::CPSColoredParticle::_ColorScheme, NL3D::CPSConstraintMesh::_GlobalAnimDate, NL3D::CPSConstraintMesh::_MeshDisplayShare, NL3D::CPSConstraintMesh::_Meshes, NL3D::CPSLocatedBindable::_Owner, NL3D::CPSSizedParticle::_ParticleSize, NL3D::CPSSizedParticle::_SizeScheme, NL3D::IDriver::activeVertexBuffer(), CHECK_VERTEX_BUFFER, NL3D::CPSConstraintMesh::computeColors(), NL3D::ConstraintMeshBufSize, NL3D::CPSConstraintMesh::doRenderPasses(), NL3D::CPSLocatedBindable::getDriver(), NL3D::CVertexBuffer::getNormalOff(), NL3D::CVertexBuffer::getNumVertices(), NL3D::CParticleSystemProcess::getOwner(), NL3D::CParticleSystem::getSystemDate(), NL3D::CMesh::getVertexBuffer(), NL3D::CVertexBuffer::getVertexCoordPointer(), NL3D::CVertexBuffer::getVertexFormat(), NL3D::CVertexBuffer::getVertexSize(), NL3D::CPSAttribMaker< float >::make(), NL3D::CPSConstraintMesh::makePrerotatedVb(), min, nlassert, PARTICLES_CHECK_MEM, NL3D::CPSConstraintMesh::CMeshDisplay::RdrPasses, NL3D::CPSLocatedBindable::setupDriverModelMatrix(), NL3D::CPSConstraintMesh::setupRenderPasses(), size, NL3D::TAnimationTime, uint, uint32, uint8, and NL3D::CPSConstraintMesh::CMeshDisplay::VB.
00800 { 00801 // get the vb from the original mesh 00802 CMesh &mesh = *m._Meshes[0]; 00803 const CVertexBuffer &modelVb = mesh.getVertexBuffer(); 00804 00806 CVertexBuffer &prerotVb = m.makePrerotatedVb(modelVb, ellapsedTime); 00807 00808 // driver setup 00809 IDriver *driver = m.getDriver(); 00810 m.setupDriverModelMatrix(); 00811 00812 // renderPasses setup 00813 nlassert(m._Owner); 00814 00815 // storage for sizes of meshs 00816 float sizes[ConstraintMeshBufSize]; 00817 00818 // point the size for the current mesh 00819 float *ptCurrSize; 00820 uint ptCurrSizeIncrement = m._SizeScheme ? 1 : 0; 00821 00822 T endPosIt; 00823 uint leftToDo = size, toProcess; 00824 const uint nbVerticesInSource = modelVb.getNumVertices(); 00825 00826 00827 00828 // size of a complete prerotated model 00829 const uint prerotatedModelSize = prerotVb.getVertexSize() * modelVb.getNumVertices(); 00830 00832 CPSConstraintMesh::CMeshDisplay &md = m._MeshDisplayShare.getMeshDisplay(m._Meshes[0], modelVb.getVertexFormat() 00833 | (m._ColorScheme ? CVertexBuffer::PrimaryColorFlag : 0)); 00834 00835 00836 m.setupRenderPasses((float) m._Owner->getOwner()->getSystemDate() - m._GlobalAnimDate, md.RdrPasses, opaque); 00837 00838 CVertexBuffer &outVb = md.VB; 00839 00840 driver->activeVertexBuffer(outVb); 00841 00842 00843 // size of vertices in prerotated model 00844 const uint inVSize = prerotVb.getVertexSize(); 00845 00846 // size ofr vertices in dest vb 00847 const uint outVSize = outVb.getVertexSize(); 00848 00849 // offset of normals in vertices of the prerotated model, and source model 00850 uint normalOff=0; 00851 uint pNormalOff=0; 00852 if (prerotVb.getVertexFormat() & CVertexBuffer::NormalFlag) 00853 { 00854 normalOff = outVb.getNormalOff(); 00855 pNormalOff = prerotVb.getNormalOff(); 00856 } 00857 00858 do 00859 { 00860 toProcess = std::min(leftToDo, ConstraintMeshBufSize); 00861 00862 if (m._SizeScheme) 00863 { 00864 // compute size 00865 ptCurrSize = (float *) (m._SizeScheme->make(m._Owner, size - leftToDo, &sizes[0], sizeof(float), toProcess, true, srcStep)); 00866 } 00867 else 00868 { 00869 // pointer on constant size 00870 ptCurrSize = &m._ParticleSize; 00871 } 00872 00873 endPosIt = posIt + toProcess; 00874 uint8 *outVertex = (uint8 *) outVb.getVertexCoordPointer(); 00876 do 00877 { 00878 uint8 *inVertex = (uint8 *) prerotVb.getVertexCoordPointer() + prerotatedModelSize * *indexIt; // prerotated vertex 00879 uint k = nbVerticesInSource; 00880 00881 if (prerotVb.getVertexFormat() & CVertexBuffer::NormalFlag) // has it a normal ? 00882 { 00883 do 00884 { 00885 CHECK_VERTEX_BUFFER(outVb, outVertex); 00886 CHECK_VERTEX_BUFFER(prerotVb, inVertex); 00887 CHECK_VERTEX_BUFFER(outVb, outVertex + normalOff); 00888 CHECK_VERTEX_BUFFER(prerotVb, inVertex + pNormalOff); 00889 00890 00891 // translate and resize the vertex (relatively to the mesh origin) 00892 *(CVector *) outVertex = *posIt + *ptCurrSize * *(CVector *) inVertex; 00893 // copy the normal 00894 *(CVector *) (outVertex + normalOff ) = *(CVector *) (inVertex + pNormalOff); 00895 inVertex += inVSize; 00896 outVertex += outVSize; 00897 } 00898 while (--k); 00899 } 00900 else 00901 { 00902 do 00903 { 00904 // translate and resize the vertex (relatively to the mesh origin) 00905 CHECK_VERTEX_BUFFER(outVb, outVertex); 00906 CHECK_VERTEX_BUFFER(prerotVb, inVertex); 00907 *(CVector *) outVertex = *posIt + *ptCurrSize * *(CVector *) inVertex; 00908 inVertex += inVSize; 00909 outVertex += outVSize; 00910 } 00911 while (--k); 00912 } 00913 00914 ++indexIt; 00915 ++posIt; 00916 ptCurrSize += ptCurrSizeIncrement; 00917 } 00918 while (posIt != endPosIt); 00919 00920 // compute colors if needed 00921 if (m._ColorScheme) 00922 { 00923 m.computeColors(outVb, modelVb, size - leftToDo, toProcess, srcStep); 00924 } 00925 00926 00928 m.doRenderPasses(driver, toProcess, md.RdrPasses, opaque); 00929 leftToDo -= toProcess; 00930 00931 } 00932 while (leftToDo); 00933 PARTICLES_CHECK_MEM 00934 } |