示例#1
0
    private void InitSPH()
    {
        kernelComputeDensityPressure = shader.FindKernel("ComputeDensityPressure");

        uint numThreadsX;

        shader.GetKernelThreadGroupSizes(kernelComputeDensityPressure, out numThreadsX, out _, out _);
        groupSize = Mathf.CeilToInt((float)particleCount / (float)numThreadsX);
        int amount = (int)numThreadsX * groupSize;

        particlesArray = new SPHParticle[amount];
        float size   = particleRadius * 1.1f;
        float center = rowSize * 0.5f;

        for (int i = 0; i < amount; i++)
        {
            Vector3 pos = new Vector3();
            pos.x = (i % rowSize) + Random.Range(-0.1f, 0.1f) - center;
            pos.y = 2 + (float)((i / rowSize) / rowSize) * 1.1f;
            pos.z = ((i / rowSize) % rowSize) + Random.Range(-0.1f, 0.1f) - center;
            pos  *= particleRadius;

            particlesArray[i] = new SPHParticle(pos);
        }
    }
示例#2
0
    private void Init()
    {
        particles = new KdTree <SPHParticle>();
        for (int i = 0; i < amount; i++)
        {
            Vector3 pos = new Vector3(
                (i % rowSize) + UnityEngine.Random.Range(-0.1f, 0.1f),
                2 + ((i / (float)rowSize) / rowSize) * 1.1f,
                ((i / rowSize) % rowSize) + UnityEngine.Random.Range(-0.1f, 0.1f)
                );

            GameObject  go       = Instantiate(sphParticle, pos, Quaternion.identity) as GameObject;
            SPHParticle particle = go.GetComponent <SPHParticle>();
            go.transform.localScale = parameters[parameterID].particleRadius * Vector3.one;
            particle.parameterID    = parameterID;
            particles.Add(particle);
        }
    }
示例#3
0
    protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
        if (cameraTransform == null)
        {
            cameraTransform = GameObject.Find("Main Camera").transform;
        }

        EntityManager.GetAllUniqueSharedComponentData(uniqueTypes);

        ComponentDataArray <SPHCollider> colliders = SPHColliderGroup.GetComponentDataArray <SPHCollider>();
        int colliderCount = colliders.Length;

        for (int typeIndex = 1; typeIndex < uniqueTypes.Count; typeIndex++)
        {
            // Get the current chunk setting
            SPHParticle settings = uniqueTypes[typeIndex];
            SPHCharacterGroup.SetFilter(settings);

            // Cache the data
            ComponentDataArray <Position>    positions  = SPHCharacterGroup.GetComponentDataArray <Position>();
            ComponentDataArray <SPHVelocity> velocities = SPHCharacterGroup.GetComponentDataArray <SPHVelocity>();

            int cacheIndex    = typeIndex - 1;
            int particleCount = positions.Length;

            NativeMultiHashMap <int, int> hashMap = new NativeMultiHashMap <int, int>(particleCount, Allocator.TempJob);

            NativeArray <Position>    particlesPosition = new NativeArray <Position>(particleCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
            NativeArray <SPHVelocity> particlesVelocity = new NativeArray <SPHVelocity>(particleCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
            NativeArray <float3>      particlesForces   = new NativeArray <float3>(particleCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
            NativeArray <float>       particlesPressure = new NativeArray <float>(particleCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
            NativeArray <float>       particlesDensity  = new NativeArray <float>(particleCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
            NativeArray <int>         particleIndices   = new NativeArray <int>(particleCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);

            NativeArray <int>         cellOffsetTableNative = new NativeArray <int>(cellOffsetTable, Allocator.TempJob);
            NativeArray <SPHCollider> copyColliders         = new NativeArray <SPHCollider>(colliderCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);



            // Add new or dispose previous particle chunks
            PreviousParticle nextParticles = new PreviousParticle
            {
                hashMap           = hashMap,
                particlesPosition = particlesPosition,
                particlesVelocity = particlesVelocity,
                particlesForces   = particlesForces,
                particlesPressure = particlesPressure,
                particlesDensity  = particlesDensity,
                particleIndices   = particleIndices,
                cellOffsetTable   = cellOffsetTableNative,
                copyColliders     = copyColliders
            };

            if (cacheIndex > previousParticles.Count - 1)
            {
                previousParticles.Add(nextParticles);
            }
            else
            {
                previousParticles[cacheIndex].hashMap.Dispose();
                previousParticles[cacheIndex].particlesPosition.Dispose();
                previousParticles[cacheIndex].particlesVelocity.Dispose();
                previousParticles[cacheIndex].particlesForces.Dispose();
                previousParticles[cacheIndex].particlesPressure.Dispose();
                previousParticles[cacheIndex].particlesDensity.Dispose();
                previousParticles[cacheIndex].particleIndices.Dispose();
                previousParticles[cacheIndex].cellOffsetTable.Dispose();
                previousParticles[cacheIndex].copyColliders.Dispose();
            }
            previousParticles[cacheIndex] = nextParticles;



            // Copy the component data to native arrays
            CopyComponentData <Position> particlesPositionJob = new CopyComponentData <Position> {
                Source = positions, Results = particlesPosition
            };
            JobHandle particlesPositionJobHandle = particlesPositionJob.Schedule(particleCount, 64, inputDeps);

            CopyComponentData <SPHVelocity> particlesVelocityJob = new CopyComponentData <SPHVelocity> {
                Source = velocities, Results = particlesVelocity
            };
            JobHandle particlesVelocityJobHandle = particlesVelocityJob.Schedule(particleCount, 64, inputDeps);

            CopyComponentData <SPHCollider> copyCollidersJob = new CopyComponentData <SPHCollider> {
                Source = colliders, Results = copyColliders
            };
            JobHandle copyCollidersJobHandle = copyCollidersJob.Schedule(colliderCount, 64, inputDeps);

            MemsetNativeArray <float> particlesPressureJob = new MemsetNativeArray <float> {
                Source = particlesPressure, Value = 0.0f
            };
            JobHandle particlesPressureJobHandle = particlesPressureJob.Schedule(particleCount, 64, inputDeps);

            MemsetNativeArray <float> particlesDensityJob = new MemsetNativeArray <float> {
                Source = particlesDensity, Value = 0.0f
            };
            JobHandle particlesDensityJobHandle = particlesDensityJob.Schedule(particleCount, 64, inputDeps);

            MemsetNativeArray <int> particleIndicesJob = new MemsetNativeArray <int> {
                Source = particleIndices, Value = 0
            };
            JobHandle particleIndicesJobHandle = particleIndicesJob.Schedule(particleCount, 64, inputDeps);

            MemsetNativeArray <float3> particlesForcesJob = new MemsetNativeArray <float3> {
                Source = particlesForces, Value = new float3(0, 0, 0)
            };
            JobHandle particlesForcesJobHandle = particlesForcesJob.Schedule(particleCount, 64, inputDeps);



            // Put positions into a hashMap
            HashPositions hashPositionsJob = new HashPositions
            {
                positions  = particlesPosition,
                hashMap    = hashMap.ToConcurrent(),
                cellRadius = settings.radius
            };
            JobHandle hashPositionsJobHandle = hashPositionsJob.Schedule(particleCount, 64, particlesPositionJobHandle);

            JobHandle mergedPositionIndicesJobHandle = JobHandle.CombineDependencies(hashPositionsJobHandle, particleIndicesJobHandle);

            MergeParticles mergeParticlesJob = new MergeParticles
            {
                particleIndices = particleIndices
            };
            JobHandle mergeParticlesJobHandle = mergeParticlesJob.Schedule(hashMap, 64, mergedPositionIndicesJobHandle);

            JobHandle mergedMergedParticlesDensityPressure = JobHandle.CombineDependencies(mergeParticlesJobHandle, particlesPressureJobHandle, particlesDensityJobHandle);

            // Compute density pressure
            ComputeDensityPressure computeDensityPressureJob = new ComputeDensityPressure
            {
                particlesPosition = particlesPosition,
                densities         = particlesDensity,
                pressures         = particlesPressure,
                hashMap           = hashMap,
                cellOffsetTable   = cellOffsetTableNative,
                settings          = settings
            };
            JobHandle computeDensityPressureJobHandle = computeDensityPressureJob.Schedule(particleCount, 64, mergedMergedParticlesDensityPressure);

            JobHandle mergeComputeDensityPressureVelocityForces = JobHandle.CombineDependencies(computeDensityPressureJobHandle, particlesForcesJobHandle, particlesVelocityJobHandle);

            // Compute forces
            ComputeForces computeForcesJob = new ComputeForces
            {
                particlesPosition = particlesPosition,
                particlesVelocity = particlesVelocity,
                particlesForces   = particlesForces,
                particlesPressure = particlesPressure,
                particlesDensity  = particlesDensity,
                cellOffsetTable   = cellOffsetTableNative,
                hashMap           = hashMap,
                settings          = settings
            };
            JobHandle computeForcesJobHandle = computeForcesJob.Schedule(particleCount, 64, mergeComputeDensityPressureVelocityForces);

            // Integrate
            Integrate integrateJob = new Integrate
            {
                particlesPosition = particlesPosition,
                particlesVelocity = particlesVelocity,
                particlesDensity  = particlesDensity,
                particlesForces   = particlesForces
            };
            JobHandle integrateJobHandle = integrateJob.Schedule(particleCount, 64, computeForcesJobHandle);

            JobHandle mergedIntegrateCollider = JobHandle.CombineDependencies(integrateJobHandle, copyCollidersJobHandle);

            // Compute Colliders
            ComputeColliders computeCollidersJob = new ComputeColliders
            {
                particlesPosition = particlesPosition,
                particlesVelocity = particlesVelocity,
                copyColliders     = copyColliders,
                settings          = settings
            };
            JobHandle computeCollidersJobHandle = computeCollidersJob.Schedule(particleCount, 64, mergedIntegrateCollider);

            // Apply positions
            ApplyPositions applyPositionsJob = new ApplyPositions
            {
                particlesPosition = particlesPosition,
                particlesVelocity = particlesVelocity,
                positions         = positions,
                velocities        = velocities
            };
            JobHandle applyPositionsJobHandle = applyPositionsJob.Schedule(particleCount, 64, computeCollidersJobHandle);

            inputDeps = applyPositionsJobHandle;
        }

        // Done
        uniqueTypes.Clear();
        return(inputDeps);
    }