Esempio n. 1
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;
                }
            }
        }
Esempio n. 2
0
        }     // OnSceneGUI

        private void Bake(FlowMap _inst)
        {
            int _tw = Mathf.NextPowerOfTwo((int)_inst.resolution.x);
            int _th = Mathf.NextPowerOfTwo((int)_inst.resolution.y);

            Vector2 _delta = new Vector2(_inst.size.x / _tw, _inst.size.y / _th);

            List <FlowPath.Sample> _samples = _inst.GatherSamples(_delta * _inst.minimumDistance);

            if (_samples.Count == 0)
            {
                return;
            }

            FlowPath.Sample[,] _outputs = new FlowPath.Sample[_tw, _th];
            InterpolateSamples(_inst, _samples, _delta, _outputs);

            Texture2D _tex = EncodeToTexture(_inst, _outputs);

            SaveTexture(_inst, _tex);
        } // Bake
Esempio 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);
        }