| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 
 | void ParticleSystem::computeParticles(Map *pMap)
{
    int widthCell = 32;
    int heightCell = 32;
 
    int nbCellWidth = pMap->WIDTH * 32 / widthCell + 1;
    int nbCellHeight = pMap->HEIGHT * 32 / heightCell + 1;
 
     std::vector<int> grid[nbCellHeight][nbCellWidth];
 
    for(int i = 0; i<mParticles.size(); i++){
 
        int x = mParticles[i]->mPositionY/heightCell;
        int y = mParticles[i]->mPositionX/widthCell;
 
        grid[x][y].push_back(i);
 
    }
 
    // trouver les particules voisines
    for(int i = 0; i<nbCellHeight; i++)
        for(int j = 0; j<nbCellWidth; j++)
        {
            while(!grid[i][j].empty()){
                int particule = grid[i][j].back(); // remove particle par la fin pour O(1)
                grid[i][j].pop_back();
 
                for(int x = -1; x<=1; x++){
                    for(int y = -1; y<=1; y++){
                        int a = i + x;
                        int b = j + y;
 
                        if(a < 0 || a >=nbCellHeight || b < 0 || b >= nbCellWidth)
                            continue;
 
                        for(int z = 0; z<grid[a][b].size(); z++)
                        {
                            int voisin = grid[a][b][z];
 
                            float dx = mParticles[voisin]->mPositionX - mParticles[particule]->mPositionX;
                            float dy = mParticles[voisin]->mPositionY - mParticles[particule]->mPositionY;
                            float distance2 = dx * dx + dy * dy;
                            if(distance2 < mParticleWidth * mParticleWidth){
                                float distance = sqrt(distance2);
                                float weight = (1.0f-distance/mParticleWidth);
                                ParticleContact contact(particule, voisin, distance, weight);
                                mParticleContacts.push_back(contact);
 
                            }
                        }
                    }
                }
                mParticles[particule]->mDensity=0.0f;
                mParticles[particule]->mPressure=0.0f;
                mParticles[particule]->mVelocityY -= GRAVITY;
            }
        }
 
    // compute density
    for(int i = 0; i<mParticleContacts.size(); i++){
 
        int p1 = mParticleContacts[i].mParticule1;
        int p2 = mParticleContacts[i].mParticule2;
 
        mParticles[p1]->mDensity += mParticleContacts[i].mWeight;
        mParticles[p2]->mDensity += mParticleContacts[i].mWeight;
 
    }
 
    while(!mParticleContacts.empty()){
 
        ParticleContact contact = mParticleContacts.back();
        mParticleContacts.pop_back();
 
        int p1 = contact.mParticule1;
        int p2 = contact.mParticule2;
 
        //compute pressure
        mParticles[p1]->mPressure = std::max(0.0f, n * (mParticles[p1]->mDensity - w0));
        mParticles[p2]->mPressure = std::max(0.0f, n * (mParticles[p2]->mDensity - w0));
 
        //compute force
        float nX = (mParticles[p2]->mPositionX - mParticles[p1]->mPositionX)/contact.mDistance;
        float nY = (mParticles[p2]->mPositionY - mParticles[p1]->mPositionY)/contact.mDistance;
 
        mParticles[p1]->mVelocityX += TIME_STEP * a * (mParticles[p1]->mPressure + mParticles[p2]->mPressure)
                                        * contact.mWeight * nX;
        mParticles[p1]->mVelocityY += TIME_STEP * a * (mParticles[p1]->mPressure + mParticles[p2]->mPressure)
                                        * contact.mWeight * nY;
 
        mParticles[p2]->mVelocityX += TIME_STEP * a * (mParticles[p1]->mPressure + mParticles[p2]->mPressure)
                                        * contact.mWeight * -nX;
        mParticles[p2]->mVelocityY += TIME_STEP * a * (mParticles[p1]->mPressure + mParticles[p2]->mPressure)
                                        * contact.mWeight * -nY;
 
        mParticles[p1]->mVelocityX += TIME_STEP * VISCOSITY * (mParticles[p2]->mVelocityX - mParticles[p1]->mVelocityX);
        mParticles[p1]->mVelocityY += TIME_STEP * VISCOSITY * (mParticles[p2]->mVelocityY - mParticles[p1]->mVelocityY);
 
        mParticles[p2]->mVelocityX += TIME_STEP * VISCOSITY * (mParticles[p1]->mVelocityX - mParticles[p2]->mVelocityX);
        mParticles[p2]->mVelocityY += TIME_STEP * VISCOSITY * (mParticles[p1]->mVelocityY - mParticles[p2]->mVelocityY);
 
    }
 
    // update position
    for (int i = 0; i < mParticles.size(); ++i) {
        mParticles[i]->updatePosition(pMap ,TIME_STEP);
    }
} | 
Partager