void ClothImpl<SwCloth>::setVirtualParticles(Range<const uint32_t[4]> indices, Range<const PxVec3> weights) { mCloth.mNumVirtualParticles = 0; // shuffle indices to form independent SIMD sets uint16_t numParticles = uint16_t(mCloth.mCurParticles.size()); TripletScheduler scheduler(indices); scheduler.simd(numParticles, 4); // convert indices to byte offset Vec4us dummy(numParticles, uint16_t(numParticles+1), uint16_t(numParticles+2), 0); Vector<uint32_t>::Type::ConstIterator sIt = scheduler.mSetSizes.begin(); Vector<uint32_t>::Type::ConstIterator sEnd = scheduler.mSetSizes.end(); TripletScheduler::ConstTripletIter tIt = scheduler.mTriplets.begin(), tLast; mCloth.mVirtualParticleIndices.resize(0); mCloth.mVirtualParticleIndices.reserve(indices.size() + 3 * uint32_t(sEnd - sIt)); for(; sIt != sEnd; ++sIt) { uint32_t setSize = *sIt; for(tLast = tIt + setSize; tIt != tLast; ++tIt, ++mCloth.mNumVirtualParticles) mCloth.mVirtualParticleIndices.pushBack(Vec4us(*tIt)); mCloth.mVirtualParticleIndices.resize( (mCloth.mVirtualParticleIndices.size() + 3) & ~3, dummy); } Vector<Vec4us>::Type(mCloth.mVirtualParticleIndices.begin(), mCloth.mVirtualParticleIndices.end()).swap(mCloth.mVirtualParticleIndices); // precompute 1/dot(w,w) Vec4fAlignedVector().swap(mCloth.mVirtualParticleWeights); mCloth.mVirtualParticleWeights.reserve(weights.size()); for(; !weights.empty(); weights.popFront()) { PxVec3 w = reinterpret_cast<const PxVec3&>(weights.front()); PxReal scale = 1 / w.magnitudeSquared(); mCloth.mVirtualParticleWeights.pushBack(PxVec4(w.x, w.y, w.z, scale)); } mCloth.notifyChanged(); }
void ClothImpl<SwCloth>::clearParticleAccelerations() { Vec4fAlignedVector().swap(mCloth.mParticleAccelerations); mCloth.wakeUp(); }