/// <summary>
        /// Call each time PC size changes
        /// </summary>
        /// <param name="initColor"></param>
        void InitPointCloud(Color initColor)
        {
            var positions = new HelixToolkit.Wpf.SharpDX.Core.Vector3Collection();
            var colors    = new HelixToolkit.Wpf.SharpDX.Core.Color4Collection();
            var indices   = new HelixToolkit.Wpf.SharpDX.Core.IntCollection();

            for (int y = 0; y < Size.Height; y++)
            {
                for (int x = 0; x < Size.Width; x++)
                {
                    indices.Add(positions.Count);
                    float mp = 0.01f;
                    positions.Add(new Vector3(mp * x, mp * y, 0.0f));
                    colors.Add(initColor);
                }
            }
            context.Send((o) =>
            {
                PointCloud.Positions = positions;
                PointCloud.Colors    = colors;
                PointCloud.Indices   = indices;
            }, null);
        }
        /// <summary>
        /// Call on each frame
        /// </summary>
        public void UpdatePC()
        {
            var lastUpdate = DateTime.Now;

            a = (lastUpdate - phase).TotalMilliseconds / 5000.0;

            HelixToolkit.Wpf.SharpDX.Core.Vector3Collection positions;
            if (fastUpdate)
            {
                positions = PointCloud.Positions;
            }
            else
            {
                positions = new HelixToolkit.Wpf.SharpDX.Core.Vector3Collection(PointCount);
            }
            var   colors = new HelixToolkit.Wpf.SharpDX.Core.Color4Collection(PointCount);
            float f = 1915;  // px, focal length (fx')
            float B = 0.25f; // m, baseline B = Tx / (-fx')
            int   w = Size.Width, h = Size.Height;

            for (int y = 0, i = 0; y < h; y++)
            {
                for (int x = 0; x < w; x++, i++)
                {
                    {
                        int   px = x * 3 + y * w * 3;
                        float yy = 0.01f * y, xx = 0.01f * x;
                        var   color = Color4Extensions.FromArgb((int)(255 * Math.Sin(yy + a)), (int)(255 * Math.Cos(xx + a)), 0);
                        int   pxd   = x * 3 + y * w * 3;
                        short disp  = (short)(10 * Math.Sin(yy + a) * Math.Cos(xx + a));
                        //short disp = (short)(100 +  10 * Math.Sin(yy + a) * Math.Cos(xx + a));
                        float Z = f * B / (disp);
                        //Z = 200;
                        float u = w / 2 - x;
                        float v = h / 2 - y;
                        float X = u * Z / f;
                        float Y = v * Z / f;
                        if (fastUpdate)
                        {
                            positions[i] = (new Vector3(X, Y, Z));
                        }
                        else
                        {
                            positions.Add(new Vector3(X, Y, Z));
                        }
                        colors.Add(color);
                    }
                }
            }
            context.Send((o) =>
            {
                PointCloud.Positions = positions;
                PointCloud.Colors    = colors;

                int d = 10;
                this.Camera.Position      = new Point3D(Math.Cos(a) * d, 3, Math.Sin(a) * d);
                this.Camera.LookDirection = new Vector3D(-this.Camera.Position.X, -this.Camera.Position.Y, -this.Camera.Position.Z);
            }, null);

            var currentTime = DateTime.Now;
            var duration    = currentTime - lastUpdate;

            FPS        = 1000.0 / duration.TotalMilliseconds;
            lastUpdate = currentTime;
        }