Bicameral Engine
GPU-resident engine for a magic-research open-world game
Loading...
Searching...
No Matches
debug_camera.h
Go to the documentation of this file.
1// debug_camera.h — デバッグ表示のカメラ(格子の周りを回るカメラ)と、画面の点からの光線・断面のセルの拾い方(T-0015)。
2//
3// データの流れ: 入力(render/debug_view_controller)→ OrbitCamera の状態を変える → Basis() が描画の定数へ
4// (render/probe_view.hlsl が同じ式で画素ごとの光線を作る)。クリックは RayThroughPixel → PickSliceCell でセルにして、つつきのコマンドへ。
5// カメラは View の状態(D-107)。世界には入らない。浮動小数点を使ってよい(描画側。04 §4 の検査の外)。
6// 座標: 世界 = セルの番号の空間(格子は [0, 1 辺)³)。回る軸は −y(既定の向きで画面の右 = +x・上 = −y・奥 = +z。
7// 今までの z = 32 の面の見え方と同じ)。
8#pragma once
9
10#include <cstdint>
11#include <optional>
12
13namespace bicameral::render {
14
15 struct Vector3 {
16 constexpr Vector3() = default;
17 constexpr Vector3(float xValue, float yValue, float zValue) : x(xValue), y(yValue), z(zValue) {}
18
19 float x = 0.0f;
20 float y = 0.0f;
21 float z = 0.0f;
22
23 [[nodiscard]] float operator[](uint32_t axis) const { return axis == 0 ? x : axis == 1 ? y : z; }
24 };
25
26 [[nodiscard]] Vector3 operator+(Vector3 left, Vector3 right);
27 [[nodiscard]] Vector3 operator-(Vector3 left, Vector3 right);
28 [[nodiscard]] Vector3 operator*(Vector3 vector, float scale);
29
30 struct CameraRay {
32 Vector3 direction; // 長さは 1 とは限らない
33 };
34
35 // 描画に渡すカメラ(probe_view.hlsl と同じ意味)。画面の点 (u, v) ∈ [−1, 1]²(v は上が +)の光線は
36 // 透視: 始点 = position、向き = forward + u × right + v × up
37 // 平行: 始点 = position + u × right + v × up、向き = forward
38 struct CameraBasis {
41 Vector3 right; // 画面の半分の幅の分(透視は向きの傾き、平行は世界の長さ)
42 Vector3 up; // 画面の半分の高さの分
43 bool orthographic = false;
44 };
45
47 float yawDegrees = 35.0f; // −y の軸の周りの向き(0 で +z を向く)
48 float pitchDegrees = 25.0f; // 上下(正で上から見下ろす)
49 float distance = 150.0f; // 注視点からの距離(セル)
50 Vector3 target{32.0f, 32.0f, 32.0f};
51 bool orthographic = false;
52 };
53
55 public:
56 static constexpr float VERTICAL_FIELD_OF_VIEW_DEGREES = 45.0f;
57 // 注視点からの距離の幅(セル)。覗き窓の一番細かい段(1 セルの 1/512)まで寄れるように小さく(T-0096)
58 static constexpr float MIN_DISTANCE = 0.001f;
59 static constexpr float MAX_DISTANCE = 2000.0f;
60
61 explicit OrbitCamera(const OrbitCameraState& initial = {}) : m_initial(initial), m_state(initial) {}
62
63 void Orbit(float deltaXPixels, float deltaYPixels); // 回る(右ドラッグ)
64 void Pan(float deltaXPixels, float deltaYPixels, uint32_t viewportHeight); // 平行移動(中ドラッグ)
65 void Zoom(int32_t wheelSteps); // 寄る(奥へ回すと近づく)
66 void Focus(Vector3 target, float distance); // 注視点と距離を決める(向きはそのまま。覗き窓で潜る)
67 void ToggleProjection() { m_state.orthographic = !m_state.orthographic; }
68 void Reset() { m_state = m_initial; }
69
70 [[nodiscard]] const OrbitCameraState& State() const { return m_state; }
71 [[nodiscard]] CameraBasis Basis(uint32_t width, uint32_t height) const;
72
73 private:
76 };
77
78 // 画素 (pixelX, pixelY)(左上が 0。画素の中心は +0.5)を通る光線
79 [[nodiscard]] CameraRay RayThroughPixel(const CameraBasis& basis, float pixelX, float pixelY, uint32_t width,
80 uint32_t height);
81
83 uint32_t x = 0;
84 uint32_t y = 0;
85 uint32_t z = 0;
86
87 bool operator==(const CellCoordinate&) const = default;
88 };
89
90 // 断面(軸 axis = 0/1/2 の座標が plane のセルの面。面の真ん中 plane + 0.5 で交わりを取る)のうち、光線が当たるセル。
91 // 面と平行・カメラの後ろ・格子の外なら無し
92 [[nodiscard]] std::optional<CellCoordinate> PickSliceCell(const CameraRay& ray, uint32_t axis, uint32_t plane,
93 uint32_t gridSize);
94
95 // 断面の上の (u, v) のセル(u, v は軸 axis 以外の 2 つの軸を x → y → z の順に)
96 [[nodiscard]] CellCoordinate CellOnSlice(uint32_t axis, uint32_t plane, uint32_t u, uint32_t v);
97
98} // namespace bicameral::render
CameraBasis Basis(uint32_t width, uint32_t height) const
static constexpr float VERTICAL_FIELD_OF_VIEW_DEGREES
void Focus(Vector3 target, float distance)
const OrbitCameraState & State() const
void Pan(float deltaXPixels, float deltaYPixels, uint32_t viewportHeight)
static constexpr float MAX_DISTANCE
static constexpr float MIN_DISTANCE
void Orbit(float deltaXPixels, float deltaYPixels)
void Zoom(int32_t wheelSteps)
OrbitCamera(const OrbitCameraState &initial={})
Vector3 operator+(Vector3 left, Vector3 right)
CellCoordinate CellOnSlice(uint32_t axis, uint32_t plane, uint32_t u, uint32_t v)
Vector3 operator-(Vector3 left, Vector3 right)
Vector3 operator*(Vector3 vector, float scale)
CameraRay RayThroughPixel(const CameraBasis &basis, float pixelX, float pixelY, uint32_t width, uint32_t height)
std::optional< CellCoordinate > PickSliceCell(const CameraRay &ray, uint32_t axis, uint32_t plane, uint32_t gridSize)
bool operator==(const CellCoordinate &) const =default
constexpr Vector3(float xValue, float yValue, float zValue)
constexpr Vector3()=default
float operator[](uint32_t axis) const