public QueryRangeJob(KnnContainer container, float3 queryPosition, float range, NativeList <int> result) { m_result = result; m_range = range; m_queryPosition = queryPosition; m_container = container; }
public QueryRangeBatchJob(KnnContainer container, NativeArray <float3> queryPositions, float range, NativeArray <RangeQueryResult> results) { m_container = container; m_queryPositions = queryPositions; m_range = range; Results = results; }
public QueryRangesBatchJob(KnnContainer container, NativeArray <float3> queryPositions, float searchSearchRadius, NativeArray <RangeQueryResult> results) { m_container = container; m_queryPositions = queryPositions; m_SearchRadius = searchSearchRadius; Results = results; }
public QueryMultiRangesBatchJob(KnnContainer container, NativeArray <float3> queryPositions, NativeArray <float> ranges, NativeArray <RangeQueryResult> results) { m_container = container; m_queryPositions = queryPositions; m_queryRadii = ranges; Results = results; }
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 }
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(); }
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; }
public QueryKNearestJob(KnnContainer container, float3 queryPosition, NativeSlice <int> result) { m_result = result; m_queryPosition = queryPosition; m_container = container; }
public KnnRebuildJob(KnnContainer container) { m_container = container; }
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(); }