예제 #1
0
        public void Execute(int i)
        {
            int simplexStart = simplexCounts.GetSimplexStartAndSize(i, out int simplexSize);

            var bounds = new BurstAabb(float.MaxValue, float.MinValue);

            for (int j = 0; j < simplexSize; ++j)
            {
                int p = simplices[simplexStart + j];

                // Find this particle's stick distance:
                int   m             = particleMaterialIndices[p];
                float stickDistance = m >= 0 ? collisionMaterials[m].stickDistance : 0;

                // Expand simplex bounds, using both the particle's original position and its velocity:
                bounds.EncapsulateParticle(positions[p], positions[p] + velocities[p] * continuousCollisionDetection * dt,
                                           math.max(radii[p].x + stickDistance, fluidRadii[p] * 0.5f) + collisionMargin);
            }

            simplexBounds[i] = bounds;
        }
            public void Execute(int i)
            {
                var cell = particleGrid.usedCells[i];

                BurstAabb cellBounds = new BurstAabb(float.MaxValue, float.MinValue);

                // here we calculate cell bounds that enclose both the predicted position and the original position of all its particles,
                // for accurate continuous collision detection.
                for (int p = 0; p < cell.Length; ++p)
                {
                    int pIndex = cell[p];

                    // get collision material stick distance:
                    float stickDistance = 0;
                    int   materialIndex = particleMaterialIndices[pIndex];
                    if (materialIndex >= 0)
                    {
                        stickDistance = collisionMaterials[materialIndex].stickDistance;
                    }

                    cellBounds.EncapsulateParticle(positions[pIndex],
                                                   positions[pIndex] + velocities[pIndex] * deltaTime,
                                                   radii[pIndex].x + stickDistance);
                }

                // transform the cell bounds to world space:
                cellBounds.Transform(solverToWorld);

                // get all colliders overlapped by the cell bounds, in all grid levels:
                NativeList <int> candidates = new NativeList <int>(Allocator.Temp);

                for (int l = 0; l < gridLevels.Length; ++l)
                {
                    GetCandidatesForBoundsAtLevel(candidates, cellBounds, gridLevels[l], is2D);
                }

                if (candidates.Length > 0)
                {
                    // make sure each candidate collider only shows up once in the array:
                    NativeArray <int> uniqueCandidates = candidates.AsArray();
                    uniqueCandidates.Sort();
                    int uniqueCount = uniqueCandidates.Unique();

                    // iterate over candidate colliders, generating contacts for each one
                    for (int c = 0; c < uniqueCount; ++c)
                    {
                        int colliderIndex                     = uniqueCandidates[c];
                        BurstColliderShape   shape            = shapes[colliderIndex];
                        BurstAabb            colliderBounds   = bounds[colliderIndex];
                        BurstAffineTransform colliderToSolver = worldToSolver * transforms[colliderIndex];

                        // transform collider bounds to solver space:
                        colliderBounds.Transform(worldToSolver);

                        // iterate over all particles in the cell:
                        for (int p = 0; p < cell.Length; ++p)
                        {
                            int particleIndex = cell[p];

                            // skip this pair if particle and collider have the same phase:
                            if (shape.phase == (phases[particleIndex] & (int)Oni.ParticleFlags.GroupMask))
                            {
                                continue;
                            }

                            // get collision material stick distance:
                            float stickDistance = 0;
                            int   materialIndex = particleMaterialIndices[particleIndex];
                            if (materialIndex >= 0)
                            {
                                stickDistance = collisionMaterials[materialIndex].stickDistance;
                            }

                            // inflate collider bounds by particle's bounds:
                            BurstAabb inflatedColliderBounds = colliderBounds;
                            inflatedColliderBounds.Expand(radii[particleIndex].x * 1.2f + stickDistance);

                            float4 invDir = math.rcp(velocities[particleIndex] * deltaTime);

                            // We check particle trajectory ray vs inflated collider aabb
                            // instead of checking particle vs collider aabbs directly, as this reduces
                            // the amount of contacts generated for fast moving particles.
                            if (inflatedColliderBounds.IntersectsRay(positions[particleIndex], invDir, shape.is2D != 0))
                            {
                                // generate contacts for the collider:
                                GenerateContacts(shape.type,
                                                 particleIndex, colliderIndex,
                                                 positions[particleIndex], orientations[particleIndex], velocities[particleIndex], radii[particleIndex],
                                                 colliderToSolver, shape, contactsQueue, deltaTime);
                            }
                        }
                    }
                }
            }