Пример #1
0
        } // 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);
        }
Пример #2
0
        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);
        }
Пример #3
0
        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();
            }
        }