Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DebugCamera3D がコンストラクタで指定した注視点と異なる位置を注視するバグ #1255

Open
Raclamusi opened this issue Aug 12, 2024 · 3 comments

Comments

@Raclamusi
Copy link
Member

DebugCamera3D がコンストラクタの引数 focusPosition で指定した注視点と異なる位置を注視します。

下のスクリーンショットは BasicCamera3DDebugCamera3D にそれぞれ赤い球を注目するようコンストラクタで指定したときの結果です。
BasicCamera3D の場合は赤い球が中心にあるのに対し、 DebugCamera3D の場合は赤い球が中心から外れています。

再現コード
# include <Siv3D.hpp>

void Main()
{
	Window::Resize(1280, 720);

	const ColorF backgroundColor = ColorF{ 0.4, 0.6, 0.8 }.removeSRGBCurve();
	const Texture uvChecker{ U"example/texture/uv.png", TextureDesc::MippedSRGB };
	const MSRenderTexture renderTexture{ Scene::Size(), TextureFormat::R8G8B8A8_Unorm_SRGB, HasDepth::Yes };

	// 同じパラメータを与えているが結果が異なる
	BasicCamera3D basicCamera{ renderTexture.size(), 30_deg, Vec3{ 10, 24, -32 }, Vec3{ 0, 2, 0 } };
	DebugCamera3D debugCamera{ renderTexture.size(), 30_deg, Vec3{ 10, 24, -32 }, Vec3{ 0, 2, 0 } };

	size_t index = 0;
	const Array<String> options{ U"BasicCamera3D", U"DebugCamera3D" };

	while (System::Update())
	{
		if (index == 0)
		{
			Graphics3D::SetCameraTransform(basicCamera);
		}
		else
		{
			debugCamera.update(2.0);
			Graphics3D::SetCameraTransform(debugCamera);
		}

		{
			const ScopedRenderTarget3D target{ renderTexture.clear(backgroundColor) };

			Plane{ 64 }.draw(uvChecker);

			Sphere{ 0, 2, 0, 2 }.draw(ColorF{ 1.0, 0.0, 0.0 }.removeSRGBCurve());
		}

		{
			Graphics3D::Flush();
			renderTexture.resolve();
			Shader::LinearToScreen(renderTexture);
		}

		{
			Line{ 630, 360, 650, 360 }.draw(2);
			Line{ 640, 350, 640, 370 }.draw(2);

			SimpleGUI::RadioButtons(index, options, Vec2{ 20, 20 });
		}
	}
}
BasicCamera3D の場合 DebugCamera3D の場合

原因の考察と解決策

原因は DebugCamera3D::m_focusY の初期化にあると考えられます。

double m_focusY = (BasicCamera3D::m_focusPosition - BasicCamera3D::m_eyePosition).normalized().y;

DebugCamera3D の注視点は、カメラ位置を中心とする半径 1 の y 方向に無限に伸びる伸びる円筒上に正規化されます。
カメラ位置から注視点へのベクトルを正規化したベクトルを使って m_focusY を初期化していますが、このベクトルの y 成分が 0 でないとき、その指す位置は円筒上になく、その y 成分で m_focusY を初期化したとき本来指すべき位置より y 座標の絶対値が小さくなります。

つまり、カメラ位置から注視点へのベクトルを円筒上に来るように正規化し、 m_focusY を初期化することでこの問題は解決できます。
例えば、 m_focusY の初期化を次のように変更します。

double m_focusY = [this]
	{
		const auto focusVector = (BasicCamera3D::m_focusPosition - BasicCamera3D::m_eyePosition);
		return (focusVector.y / std::hypot(focusVector.x, focusVector.z));
	}();
@Raclamusi Raclamusi changed the title DebugCamera3D がコンストラクタで指定した注視点と異なる位置を注視する DebugCamera3D がコンストラクタで指定した注視点と異なる位置を注視するバグ Sep 25, 2024
@Raclamusi
Copy link
Member Author

DebugCamera3D::setView() にも同様のバグがありました。

@Reputeless
Copy link
Member

コメントありがとうございます!
なぜかこの Issue の存在が記憶から抜け落ちてました(多分忙しかった時期だったため)。
対応が必要なので、提案を試してみます。よさそうだと判断した場合 PR 受け付けます。

@Reputeless
Copy link
Member

問題を確認しました。修正方法も妥当だと思います。PR 受け付けます!

@Reputeless Reputeless moved this from Investigating to ToDo in v0.6 Roadmap Nov 17, 2024
Raclamusi added a commit to Raclamusi/OpenSiv3D that referenced this issue Nov 17, 2024
@Reputeless Reputeless moved this from ToDo to Done in v0.6 Roadmap Nov 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Development

No branches or pull requests

2 participants