public override void OnRender()
        {
            DrawString("Keys: a: automate, c: create, d: destroy, m: move");
            DrawString("Blue: overlap\nGreen: ray actor\nRed: ray actor & overlap");
            Color c;

            for (var i = 0; i < ActorCount; ++i)
            {
                var actor = _actors[i];
                if (actor.ProxyId == BroadPhase.NullProxy)
                {
                    continue;
                }

                c = Color.FromArgb(230, 230, 230);
                if (actor == _rayActor && actor.Overlap)
                {
                    c = Color.FromArgb(230, 153, 153);
                }
                else if (actor == _rayActor)
                {
                    c = Color.FromArgb(153, 230, 153);
                }
                else if (actor.Overlap)
                {
                    c = Color.FromArgb(153, 153, 230);
                }

                DrawAABB(actor.AABB, c);
            }

            c = Color.FromArgb(178, 178, 178);
            DrawAABB(_queryAABB, c);

            Drawer.DrawSegment(_rayCastInput.P1, _rayCastInput.P2, c);

            var c1 = Color.FromArgb(51, 230, 51);
            var c2 = Color.FromArgb(230, 51, 51);

            Drawer.DrawPoint(_rayCastInput.P1, 6.0f, c1);
            Drawer.DrawPoint(_rayCastInput.P2, 6.0f, c2);

            if (_rayActor != null)
            {
                var cr = Color.FromArgb(51, 51, 230);
                var p  = _rayCastInput.P1 + _rayActor.Fraction * (_rayCastInput.P2 - _rayCastInput.P1);
                Drawer.DrawPoint(p, 6.0f, cr);
            }

            {
                var height = _tree.GetHeight();
                DrawString($"dynamic tree height = {height}");
            }
        }
        /// <inheritdoc />
        protected override void PreStep()
        {
            if (Input.GetKeyDown(KeyCode.A))
            {
                _automated = !_automated;
            }

            if (Input.GetKeyDown(KeyCode.C))
            {
                CreateProxy();
            }

            if (Input.GetKeyDown(KeyCode.D))
            {
                DestroyProxy();
            }

            if (Input.GetKeyDown(KeyCode.M))
            {
                MoveProxy();
            }

            _rayActor = null;
            for (var i = 0; i < ActorCount; ++i)
            {
                _actors[i].Fraction = 1.0f;
                _actors[i].Overlap  = false;
            }

            if (_automated)
            {
                var actionCount = Math.Max(1, ActorCount >> 2);

                for (var i = 0; i < actionCount; ++i)
                {
                    Action();
                }
            }

            Query();
            RayCast();
            Color c;

            for (var i = 0; i < ActorCount; ++i)
            {
                var actor = _actors[i];
                if (actor.ProxyId == BroadPhase.NullProxy)
                {
                    continue;
                }

                c = Color.FromArgb(230, 230, 230);
                if (actor == _rayActor && actor.Overlap)
                {
                    c = Color.FromArgb(230, 153, 153);
                }
                else if (actor == _rayActor)
                {
                    c = Color.FromArgb(153, 230, 153);
                }
                else if (actor.Overlap)
                {
                    c = Color.FromArgb(153, 153, 230);
                }

                DrawAABB(actor.AABB, c);
            }

            c = Color.FromArgb(178, 178, 178);
            DrawAABB(_queryAABB, c);

            Drawer.DrawSegment(_rayCastInput.P1, _rayCastInput.P2, c);

            var c1 = Color.FromArgb(51, 230, 51);
            var c2 = Color.FromArgb(230, 51, 51);

            Drawer.DrawPoint(_rayCastInput.P1, 6.0f, c1);
            Drawer.DrawPoint(_rayCastInput.P2, 6.0f, c2);

            if (_rayActor != null)
            {
                var cr = Color.FromArgb(51, 51, 230);
                var p  = _rayCastInput.P1 + _rayActor.Fraction * (_rayCastInput.P2 - _rayCastInput.P1);
                Drawer.DrawPoint(p, 6.0f, cr);
            }

            {
                var height = _tree.GetHeight();
                DrawString($"dynamic tree height = {height}");
            }

            ++_stepCount;
        }