Esempio n. 1
0
        public static void ProjectFluidConstraints(Vector4[] particles, float[] densities, float[] lambdas, int particlesCount, int[] particlesNeighbours, int[] particlesNeighboursCount, int maxNeighboursPerParticle, float restDensity, PBFKernels kernels, Vector4[] deltaPositions)
        {
            for (int idA = 0; idA < particlesCount; idA++)
            {
                Vector3 predPosA = particles[idA];
                float   lambda   = lambdas[idA];
                Vector3 deltaP   = new Vector3();

                for (int nId = 0; nId < particlesNeighboursCount[idA]; nId++)
                {
                    int idB = particlesNeighbours[idA * maxNeighboursPerParticle + nId];

                    Vector3 predPosB = particles[idB];

                    float lambdaSum = lambda + lambdas[idB];
                    float sCorr     = kernels.sCorrCalc(predPosA, predPosB);

                    deltaP += kernels.WSpiky(predPosA, predPosB) * (lambdaSum + sCorr);
                }

                deltaPositions[idA] = deltaP / restDensity;
            }
        }
Esempio n. 2
0
        public static void CalculateLambdas(Vector4[] positions, float[] densities, float[] lambdas, int particlesCount, int[] particlesNeighbours, int[] particlesNeighboursCount, int maxNeighboursPerParticle, float restDensity, float epsilonLambda, PBFKernels kernels)
        {
            for (int idA = 0; idA < particlesCount; idA++)
            {
                Vector3 predPosA = positions[idA];

                float   density      = 0.0f;
                Vector3 gradientI    = new Vector3();
                float   sumGradients = 0.0f;



                for (int nId = 0; nId < particlesNeighboursCount[idA]; nId++)
                {
                    int     idB      = particlesNeighbours[idA * maxNeighboursPerParticle + nId];
                    Vector3 predPosB = positions[idB];

                    //Calculate the lambda value for pressure correction
                    density += kernels.WPoly6(predPosA, predPosB);

                    //Calculate gradient with respect to j
                    Vector3 gradientJ = kernels.WSpiky(predPosA, predPosB) / restDensity;
                    //float3 gradientJ = gradWPoly6(predPosA, predPosB) / REST_DENSITY;


                    //Add magnitude squared to sum
                    //sumGradients += glm::length2(gradientJ);
                    sumGradients += Vector3.Dot(gradientJ, gradientJ);
                    gradientI    += gradientJ;
                }

                //Add the particle i gradient magnitude squared to sum
                sumGradients += Vector3.Dot(gradientI, gradientI);

                float densityConstraint = (density / restDensity) - 1.0f;

                densities[idA] = density;
                lambdas[idA]   = (-1.0f) * densityConstraint / (sumGradients + epsilonLambda);
            }
        }