Example #1
0
 public QueryRangeJob(KnnContainer container, float3 queryPosition, float range, NativeList <int> result)
 {
     m_result        = result;
     m_range         = range;
     m_queryPosition = queryPosition;
     m_container     = container;
 }
Example #2
0
 public QueryRangeBatchJob(KnnContainer container, NativeArray <float3> queryPositions, float range, NativeArray <RangeQueryResult> results)
 {
     m_container      = container;
     m_queryPositions = queryPositions;
     m_range          = range;
     Results          = results;
 }
Example #3
0
        public QueryRangesBatchJob(KnnContainer container, NativeArray <float3> queryPositions, float searchSearchRadius, NativeArray <RangeQueryResult> results)
        {
            m_container      = container;
            m_queryPositions = queryPositions;
            m_SearchRadius   = searchSearchRadius;

            Results = results;
        }
Example #4
0
        public QueryMultiRangesBatchJob(KnnContainer container, NativeArray <float3> queryPositions, NativeArray <float> ranges, NativeArray <RangeQueryResult> results)
        {
            m_container      = container;
            m_queryPositions = queryPositions;
            m_queryRadii     = ranges;

            Results = results;
        }
Example #5
0
    void Start()
    {
        m_system = GetComponent <ParticleSystem>();

        m_system.Emit(ParticleCount);
        m_points = new NativeArray <float3>(ParticleCount, Allocator.Persistent);

        // Create a container that accelerates querying for neighbours
        m_container = new KnnContainer(m_points, false, Allocator.Persistent);         // Skip building for now. We rebuild every frame
    }
Example #6
0
        private void InitBlobData(int numBlobs, ParticleSystem blobParticleSystemOutput)
        {
            NUM_BLOBS_Display = numBlobs;
            var main = BlobParticleSystemOutput.main;

            main.maxParticles = numBlobs;
            BlobParticleSystemOutput.Emit(numBlobs);
            //Blob enabling

            //create scratch data
            _blobVelocities      = new NativeArray <float2>(numBlobs, Allocator.Persistent);
            _blobPositions       = new NativeArray <float2>(numBlobs, Allocator.Persistent);
            _blobAccelerations   = new NativeArray <float2>(numBlobs, Allocator.Persistent);
            _blobRadii           = new NativeArray <float>(numBlobs, Allocator.Persistent);
            _blobTeamIDs         = new NativeArray <int>(numBlobs, Allocator.Persistent);
            _blobGroupIDs        = new NativeArray <int>(numBlobs, Allocator.Persistent);
            _numGroups           = new NativeArray <int>(1, Allocator.Persistent);
            _floodQueue          = new NativeQueue <int>(Allocator.Persistent);
            _blobColors          = new NativeArray <Color>(numBlobs, Allocator.Persistent);
            _blobPositionsV3     = new NativeArray <float3>(numBlobs, Allocator.Persistent);
            _overallGooBounds    = new NativeArray <Bounds>(1, Allocator.Persistent);
            _overallGooBounds[0] = OverallGooBounds;

            //copy init values into scratch data
            for (int index = 0; index < numBlobs; index++)
            {
                Vector3 randomPos = Random.insideUnitCircle * PetriDishRadius;

                float angleFraction = (Mathf.Atan2(randomPos.x, randomPos.y) + Mathf.PI) / (Mathf.PI * 2.0f);//flipped x and y is intentional so that 2player gets horizontal split
                //Vector3 randomVel = Random.insideUnitCircle;
                _blobTeamIDs[index]       = Mathf.FloorToInt(angleFraction * (float)NumTeams);
                _blobGroupIDs[index]      = -1;
                _blobPositions[index]     = new float2(randomPos.x, randomPos.y);
                _blobVelocities[index]    = float2.zero;
                _blobAccelerations[index] = float2.zero;
                _blobColors[index]        = Color.magenta;
                _blobPositionsV3[index]   = new float3(randomPos.x, randomPos.y, _blobTeamIDs[index]);
                _blobRadii[index]         = GooPhysics.MaxSpringDistance;
            }


            //output things


            main = BlobParticleSystemOutput.main;
            main.maxParticles = numBlobs;


            _knnContainer = new KnnContainer(_blobPositionsV3, false, Allocator.Persistent);



            InitJobData();
        }
Example #7
0
        public QueryKNearestBatchJob(KnnContainer container, NativeArray <float3> queryPositions, NativeSlice <int> results)
        {
            m_container      = container;
            m_queryPositions = queryPositions;
            m_results        = results;

                #if ENABLE_UNITY_COLLECTIONS_CHECKS
            if (queryPositions.Length == 0 || results.Length % queryPositions.Length != 0)
            {
                Debug.LogError("Make sure your results array is a multiple in length of your querypositions array!");
            }
                #endif

            m_k = results.Length / queryPositions.Length;
        }
Example #8
0
 public QueryKNearestJob(KnnContainer container, float3 queryPosition, NativeSlice <int> result)
 {
     m_result        = result;
     m_queryPosition = queryPosition;
     m_container     = container;
 }
Example #9
0
 public KnnRebuildJob(KnnContainer container)
 {
     m_container = container;
 }
Example #10
0
    public static void Demo()
    {
        Profiler.BeginSample("Test Query");

        // First let's create a random point cloud
        var points = new NativeArray <float3>(100000, Allocator.Persistent);
        var rand   = new Random(123456);

        for (int i = 0; i < points.Length; ++i)
        {
            points[i] = rand.NextFloat3();
        }

        // Number of neighbours we want to query
        const int kNeighbours   = 10;
        float3    queryPosition = float3.zero;

        Profiler.BeginSample("Build");
        // Create a container that accelerates querying for neighbours.
        // The 2nd argument indicates whether we want to build the tree straight away or not
        // Let's hold off on building it a little bit
        var knnContainer = new KnnContainer(points, false, Allocator.TempJob);

        Profiler.EndSample();

        // Whenever your point cloud changes, you can make a job to rebuild the container:
        var rebuildJob = new KnnRebuildJob(knnContainer);

        rebuildJob.Schedule().Complete();

        // Most basic usage:
        // Get 10 nearest neighbours as indices into our points array!
        // This is NOT burst accelerated yet! Unity need to implement compiling delegates with Burst
        var result = new NativeArray <int>(kNeighbours, Allocator.TempJob);

        knnContainer.QueryKNearest(queryPosition, result);

        // The result array at this point contains indices into the points array with the nearest neighbours!

        Profiler.BeginSample("Simple Query");
        // Get a job to do the query.
        var queryJob = new QueryKNearestJob(knnContainer, queryPosition, result);

        // And just run immediately on the main thread for now. This uses Burst!
        queryJob.Schedule().Complete();
        Profiler.EndSample();

        // Or maybe we want to query neighbours for multiple points.
        const int queryPoints = 100000;

        // Keep an array of neighbour indices of all points
        var results = new NativeArray <int>(queryPoints * kNeighbours, Allocator.TempJob);

        // Query at a few random points
        var queryPositions = new NativeArray <float3>(queryPoints, Allocator.TempJob);

        for (int i = 0; i < queryPoints; ++i)
        {
            queryPositions[i] = rand.NextFloat3() * 0.1f;
        }

        Profiler.BeginSample("Batch Query");
        // Fire up job to get results for all points
        var batchQueryJob = new QueryKNearestBatchJob(knnContainer, queryPositions, results);

        // And just run immediately now. This will run on multiple threads!
        batchQueryJob.ScheduleBatch(queryPositions.Length, queryPositions.Length / 32).Complete();
        Profiler.EndSample();

        // Or maybe we're interested in a range around eacht query point
        var queryRangeResult = new NativeList <int>(Allocator.TempJob);
        var rangeQueryJob    = new QueryRangeJob(knnContainer, queryPosition, 2.0f, queryRangeResult);

        // Store a list of particles in range
        var rangeResults = new NativeArray <RangeQueryResult>(queryPoints, Allocator.TempJob);

        // And just run immediately on the main thread for now. This uses Burst!
        rangeQueryJob.Schedule().Complete();

        // Unfortunately, for batch range queries we do need to decide upfront the maximum nr. of neighbours we allow
        // This is due to limitation on allocations within a job.
        for (int i = 0; i < rangeResults.Length; ++i)
        {
            rangeResults[i] = new RangeQueryResult(128, Allocator.TempJob);
        }

        Profiler.BeginSample("Batch Range Query");
        // Fire up job to get results for all points
        var batchRange = new QueryRangeBatchJob(knnContainer, queryPositions, 2.0f, rangeResults);

        // And just run immediately now. This will run on multiple threads!
        batchRange.Schedule(queryPositions.Length, queryPositions.Length / 32).Complete();
        Profiler.EndSample();

        // Now the results array contains all the neighbours!
        queryRangeResult.Dispose();
        foreach (var r in rangeResults)
        {
            r.Dispose();
        }
        rangeResults.Dispose();
        knnContainer.Dispose();
        queryPositions.Dispose();
        results.Dispose();
        points.Dispose();
        result.Dispose();
        Profiler.EndSample();
    }