} // Bake private KdTree CreateKdTree(List <FlowPath.Sample> _samples) { KdTree.Entry[] _kdEnt = new KdTree.Entry[_samples.Count]; for (int _it = 0; _it < _samples.Count; ++_it) { _kdEnt[_it] = new KdTree.Entry(_samples[_it].position, _it); } KdTree _kdTree = new KdTree(); _kdTree.build(_kdEnt); return(_kdTree); }
public List <FlowPath.Sample> GatherSamples(Vector2 _sampleSize) { var _flowPaths = GetComponentsInChildren <FlowPath>(); var _rawSamples = new List <FlowPath.Sample>(); foreach (var _flow in _flowPaths) { if (null == _flow || !_flow) { continue; } (_flow as FlowPath).GatherSamples(_rawSamples, _sampleSize); } KdTree.Entry[] _kdEnt = new KdTree.Entry[_rawSamples.Count]; for (int _it = 0; _it < _rawSamples.Count; ++_it) { _kdEnt[_it] = new KdTree.Entry(_rawSamples[_it].position, _it); } KdTree _kdTree = new KdTree(); _kdTree.build(_kdEnt); KdTree.RQueue _rqueue = new KdTree.RQueue(); var _processed = new System.Collections.Generic.HashSet <int>(); float _range = Mathf.Min(_sampleSize.x, _sampleSize.y); var _filteredSamples = new List <FlowPath.Sample>(); for (int _it = 0; _it < _rawSamples.Count; ++_it) { if (_processed.Contains(_it)) { continue; } int[] _neighbours = _kdTree.rquery(_rqueue, _rawSamples[_it].position, _range); if (_neighbours.Length == 1) { _filteredSamples.Add(_rawSamples[_it]); _processed.Add(_it); } else { Vector3 _pos = Vector3.zero; Vector3 _dir = Vector3.zero; foreach (int _id in _neighbours) { _pos += _rawSamples[_id].position; _dir += _rawSamples[_id].direction; _processed.Add(_id); } FlowPath.Sample _samp = new FlowPath.Sample(); _samp.position = _pos * (1.0f / _neighbours.Length); _samp.direction = _dir * (1.0f / _neighbours.Length); _filteredSamples.Add(_samp); } } return(_filteredSamples); }
public void PlaceProbes() { if (probeObject != null) { probeObject.transform.position = Vector3.zero; UnityEngine.AI.NavMeshTriangulation navMesh = UnityEngine.AI.NavMesh.CalculateTriangulation(); Vector3[] _pos = navMesh.vertices; // construct kd tree KdTree _kd = new KdTree(); KdTree.Entry[] _kdents = new KdTree.Entry[_pos.Length]; for (int i = 0; i < _kdents.Length; ++i) { _kdents[i] = new KdTree.Entry(_pos[i], i); } _kd.build(_kdents); List <ProbeGenPoint> probeGen = new List <ProbeGenPoint>(); foreach (Vector3 _pt in _pos) { probeGen.Add(new ProbeGenPoint(_pt, false)); } List <Vector3> mergedProbes = new List <Vector3>(); var _watch = new System.Diagnostics.Stopwatch(); _watch.Start(); var _queue = new KdTree.RQueue(); for (int i = 0; i < probeGen.Count; ++i) { ProbeGenPoint _pro = probeGen[i]; if (_pro.used) { continue; } float _mergedCnt = 1.0f; Vector3 _mergedPos = _pro.pos; var _neighbor = _kd.rquery(_queue, _pro.pos, mergeDistance); for (int n = 0; n < _neighbor.Length; ++n) { if (_neighbor[n] == i) { continue; } ProbeGenPoint _subject = probeGen[_neighbor[n]]; _subject.used = true; } if (_mergedCnt > 1.0f) { _mergedPos *= 1.0f / _mergedCnt; } for (int l = 0; l < layers; ++l) { mergedProbes.Add(_mergedPos + Vector3.up * (layerHeight * l)); } _pro.used = true; } _watch.Stop(); Log.I("merging completed in {0} ms", _watch.ElapsedMilliseconds); probeObject.probePositions = mergedProbes.ToArray(); } }