Ejemplo n.º 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);
        }
Ejemplo n.º 2
0
        private void InterpolateSamples(FlowMap _inst, List <FlowPath.Sample> _samples, Vector2 _delta, FlowPath.Sample[,] _outputs)
        {
            var _transform = _inst.transform;
            var _offset    = _inst.size * -0.5f + _delta * 0.5f;

            int _w = _outputs.GetUpperBound(0) + 1;
            int _h = _outputs.GetUpperBound(1) + 1;

            KdTree _kdTree = CreateKdTree(_samples);

            KdTree.KQueue _kqueue = new KdTree.KQueue(3);

            for (int _y = 0; _y < _h; ++_y)
            {
                for (int _x = 0; _x < _w; ++_x)
                {
                    Vector2 _pos      = _offset + Vector2.Scale(_delta, new Vector2(_x, _y));
                    Vector3 _worldPos = _transform.TransformPoint(new Vector3(_pos.x, 0, _pos.y));

                    FlowPath.Sample _outSamp = new FlowPath.Sample()
                    {
                        position  = _worldPos,
                        direction = Vector3.zero,
                    };

                    int[] _knn = _kdTree.knearest(_kqueue, _worldPos, 3);
                    if (_knn.Length == 3)
                    {
                        var     _sampA = _samples[_knn[0]];
                        var     _sampB = _samples[_knn[1]];
                        var     _sampC = _samples[_knn[2]];
                        Vector3 _weights;
                        Vector3 _dir = _sampA.direction;

                        if (Geometry.GetBarycentricCoords(out _weights, _sampA.position, _sampB.position, _sampC.position, _worldPos))
                        {
                            _dir = (_sampA.direction * _weights.x) + (_sampB.direction * _weights.y) + (_sampC.direction * _weights.z);
                        }

                        _outSamp.direction = _dir;
                    }

                    _outputs[_x, _y] = _outSamp;
                }
            }
        }
Ejemplo n.º 3
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);
        }
Ejemplo n.º 4
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();
            }
        }