Siv3D / OpenSiv3D

C++20 framework for creative coding 🎮🎨🎹 / Cross-platform support (Windows, macOS, Linux, and the Web)
https://siv3d.github.io/
MIT License
1k stars 138 forks source link

Cursor::Delta() が (Cursor::Pos() - Cursor::PreviousPos()) と一致しない #1119

Open Raclamusi opened 10 months ago

Raclamusi commented 10 months ago

Cursor::Delta() のコメントに

Cursor::Pos() - Cursor::PreviousPos() と同値です。

とありますが、この2つの式の値が一致しないことがあります。

この問題は、Transformer2D でマウスカーソルの座標系を拡大したときに発生します。

次のコードを実行してマウスカーソルを動かしてみると、Cursor::Pos() - Cursor::PreviousPos() はカーソル座標の整数部が変化するフレームで一瞬大きさを持つのに対し、Cursor::Delta() は(ゆっくり動かしていると)ずっと Point{ 0, 0 } のままです。

# include <Siv3D.hpp> // Siv3D v0.6.12

void Main()
{
    constexpr double Scale = 100;

    while (System::Update())
    {
        const Transformer2D transformer{ Mat3x2::Scale(Scale), TransformCursor::Yes };

        ClearPrint();
        Print << Cursor::Delta();
        Print << (Cursor::Pos() - Cursor::PreviousPos());

        for (int32 x = 0; x < (Scene::Width() / Scale + 1); ++x)
        {
            for (int32 y = 0; y < (Scene::Height() / Scale + 1); ++y)
            {
                if ((x + y) % 2 == 0)
                {
                    Rect{ x, y, 1 }.draw(ColorF{ 0.3, 0.9, 0.6 });
                }
            }
        }
    }
}

この問題の原因としては、Cursor::Delta() の実装が Cursor::Pos() - Cursor::PreviousPos() ではなく Cursor::DeltaF().asPoint() のような実装になっていることが考えられます。 実際に、すべてのプラットフォームの Cursor の実装で、Vec2 で求めたマウスカーソルの移動量を Point に変換しているようなコードが見られました。 以下の permalink はその1つです。

https://github.com/Siv3D/OpenSiv3D/blob/df93738dcc2a5e1089b3586bf8028fa13e063c6e/Siv3D/src/Siv3D-Platform/WindowsDesktop/Siv3D/Cursor/CCursor.cpp?ts=4#L241