| 2837 | } |
| 2838 | |
| 2839 | void b2ParticleSystem::SolveBarrier(const b2TimeStep& step) |
| 2840 | { |
| 2841 | // If a particle is passing between paired barrier particles, |
| 2842 | // its velocity will be decelerated to avoid passing. |
| 2843 | for (int32 i = 0; i < m_count; i++) |
| 2844 | { |
| 2845 | uint32 flags = m_flagsBuffer.data[i]; |
| 2846 | static const uint32 k_barrierWallFlags = |
| 2847 | b2_barrierParticle | b2_wallParticle; |
| 2848 | if ((flags & k_barrierWallFlags) == k_barrierWallFlags) |
| 2849 | { |
| 2850 | m_velocityBuffer.data[i].SetZero(); |
| 2851 | } |
| 2852 | } |
| 2853 | float32 tmax = b2_barrierCollisionTime * step.dt; |
| 2854 | for (int32 k = 0; k < m_pairBuffer.GetCount(); k++) |
| 2855 | { |
| 2856 | const b2ParticlePair& pair = m_pairBuffer[k]; |
| 2857 | if (pair.flags & b2_barrierParticle) |
| 2858 | { |
| 2859 | int32 a = pair.indexA; |
| 2860 | int32 b = pair.indexB; |
| 2861 | b2Vec2 pa = m_positionBuffer.data[a]; |
| 2862 | b2Vec2 pb = m_positionBuffer.data[b]; |
| 2863 | b2AABB aabb; |
| 2864 | aabb.lowerBound = b2Min(pa, pb); |
| 2865 | aabb.upperBound = b2Max(pa, pb); |
| 2866 | b2ParticleGroup *aGroup = m_groupBuffer[a]; |
| 2867 | b2ParticleGroup *bGroup = m_groupBuffer[b]; |
| 2868 | b2Vec2 va = GetLinearVelocity(aGroup, a, pa); |
| 2869 | b2Vec2 vb = GetLinearVelocity(bGroup, b, pb); |
| 2870 | b2Vec2 pba = pb - pa; |
| 2871 | b2Vec2 vba = vb - va; |
| 2872 | InsideBoundsEnumerator enumerator = GetInsideBoundsEnumerator(aabb); |
| 2873 | int32 c; |
| 2874 | while ((c = enumerator.GetNext()) >= 0) |
| 2875 | { |
| 2876 | b2Vec2 pc = m_positionBuffer.data[c]; |
| 2877 | b2ParticleGroup *cGroup = m_groupBuffer[c]; |
| 2878 | if (aGroup != cGroup && bGroup != cGroup) |
| 2879 | { |
| 2880 | b2Vec2 vc = GetLinearVelocity(cGroup, c, pc); |
| 2881 | // Solve the equation below: |
| 2882 | // (1-s)*(pa+t*va)+s*(pb+t*vb) = pc+t*vc |
| 2883 | // which expresses that the particle c will pass a line |
| 2884 | // connecting the particles a and b at the time of t. |
| 2885 | // if s is between 0 and 1, c will pass between a and b. |
| 2886 | b2Vec2 pca = pc - pa; |
| 2887 | b2Vec2 vca = vc - va; |
| 2888 | float32 e2 = b2Cross(vba, vca); |
| 2889 | float32 e1 = b2Cross(pba, vca) - b2Cross(pca, vba); |
| 2890 | float32 e0 = b2Cross(pba, pca); |
| 2891 | float32 s, t; |
| 2892 | b2Vec2 qba, qca; |
| 2893 | if (e2 == 0) |
| 2894 | { |
| 2895 | if (e1 == 0) continue; |
| 2896 | t = - e0 / e1; |
nothing calls this directly
no test coverage detected