mirror of
https://github.com/Nexoniarz/Fry3DX.git
synced 2026-11-03 04:24:26 +00:00
Getting round: the wheel closes in on what's under the mouse (an object, the ground; the sky: on that way), the whole camera with it, so far from everything it no longer creeps at a spot in the air; arrow keys move along the ground, Page Up / Down up and down (a flat view: closer, further), Shift faster; fry_hold and fry_wheel to try them; crash dumps and a.out out of the repository and ignored
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
9a7ed67d80
commit
de749dba11
13 changed files with 54 additions and 4 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -4,3 +4,7 @@ build/
|
||||||
__pycache__/
|
__pycache__/
|
||||||
*.fry~
|
*.fry~
|
||||||
dist/
|
dist/
|
||||||
|
|
||||||
|
# crash dumps and stray test programs
|
||||||
|
core.[0-9]*
|
||||||
|
a.out
|
||||||
|
|
|
||||||
|
|
@ -102,6 +102,8 @@ Five tabs along the top: **Model**, **Paint**, **Layout**, **Render**, **Print**
|
||||||
- **Layout tab**: move, turn and size the flat frames of the surface yourself; the paint follows.
|
- **Layout tab**: move, turn and size the flat frames of the surface yourself; the paint follows.
|
||||||
|
|
||||||
**Seeing it**
|
**Seeing it**
|
||||||
|
- **Getting round**: right drag orbits, middle drag pans, the wheel goes towards what's under the
|
||||||
|
mouse; the **arrow keys** move you along the ground (Page Up / Down: up and down, Shift: faster).
|
||||||
- **Solid** view for modelling, **Rendered** with a real sky, sun and soft shadows (Z). Wireframe
|
- **Solid** view for modelling, **Rendered** with a real sky, sun and soft shadows (Z). Wireframe
|
||||||
(Shift+Z), X-ray (Alt+Z). The Render tab: the sun, sky, ground, brightness, shadows, glow;
|
(Shift+Z), X-ray (Alt+Z). The Render tab: the sun, sky, ground, brightness, shadows, glow;
|
||||||
F12 saves a picture of just the view.
|
F12 saves a picture of just the view.
|
||||||
|
|
|
||||||
0
a.out
0
a.out
BIN
core.35446
BIN
core.35446
Binary file not shown.
BIN
core.35463
BIN
core.35463
Binary file not shown.
BIN
core.35933
BIN
core.35933
Binary file not shown.
BIN
core.35947
BIN
core.35947
Binary file not shown.
BIN
core.36411
BIN
core.36411
Binary file not shown.
BIN
core.36564
BIN
core.36564
Binary file not shown.
18
src/app.cpp
18
src/app.cpp
|
|
@ -262,6 +262,21 @@ auto App::init() -> void {
|
||||||
if (a.size() < 3) return self->say("fry_bench orbit|smooth|angle|round frames");
|
if (a.size() < 3) return self->say("fry_bench orbit|smooth|angle|round frames");
|
||||||
self->bench_ = {a[1], std::max(1, std::stoi(a[2])), {}};
|
self->bench_ = {a[1], std::max(1, std::stoi(a[2])), {}};
|
||||||
}, "Fry3DX: fry_bench orbit|smooth|angle|round frames: time that many frames while the camera turns or the picked object's setting is dragged");
|
}, "Fry3DX: fry_bench orbit|smooth|angle|round frames: time that many frames while the camera turns or the picked object's setting is dragged");
|
||||||
|
static keel::Cmd hold("fry_hold", [](const keel::Args& a) { // a key held down for some frames, as if pressed (for trying keys out)
|
||||||
|
if (a.size() < 3) return self->say("fry_hold key frames (UpArrow, PageUp, LeftShift...)");
|
||||||
|
for (int k = ImGuiKey_NamedKey_BEGIN; k < ImGuiKey_NamedKey_END; ++k)
|
||||||
|
if (a[1] == ImGui::GetKeyName(ImGuiKey(k))) {
|
||||||
|
ImGui::GetIO().AddKeyEvent(ImGuiKey(k), true);
|
||||||
|
return self->holding_.push_back({ImGuiKey(k), std::stoi(a[2])});
|
||||||
|
}
|
||||||
|
self->say("fry_hold: no key called " + a[1]);
|
||||||
|
}, "Fry3DX: fry_hold key frames: hold a key down (UpArrow, PageUp...)");
|
||||||
|
static keel::Cmd wheel("fry_wheel", [](const keel::Args& a) { // the wheel turned at x y (0..1 of the view)
|
||||||
|
if (a.size() < 4) return;
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
io.AddMousePosEvent(self->viewMin_.x + (self->viewMax_.x - self->viewMin_.x) * std::stof(a[1]), self->viewMin_.y + (self->viewMax_.y - self->viewMin_.y) * std::stof(a[2]));
|
||||||
|
io.AddMouseWheelEvent(0, std::stof(a[3]));
|
||||||
|
}, "Fry3DX: fry_wheel x y notches: the mouse wheel at that point of the view");
|
||||||
static keel::Cmd capture("fry_capture", [](const keel::Args& a) { if (a.size() > 1) self->savePicture(a[1]); }, "Fry3DX: save a picture of the view");
|
static keel::Cmd capture("fry_capture", [](const keel::Args& a) { if (a.size() > 1) self->savePicture(a[1]); }, "Fry3DX: save a picture of the view");
|
||||||
static keel::Cmd layout("fry_layout", [](const keel::Args& a) {
|
static keel::Cmd layout("fry_layout", [](const keel::Args& a) {
|
||||||
Object* o = self->find(self->active_);
|
Object* o = self->find(self->active_);
|
||||||
|
|
@ -460,6 +475,9 @@ auto App::onEscape() -> void {
|
||||||
|
|
||||||
// (fry_bench) Each frame: the change being timed.
|
// (fry_bench) Each frame: the change being timed.
|
||||||
auto App::benchStep() -> void {
|
auto App::benchStep() -> void {
|
||||||
|
for (auto& [k, left] : holding_)
|
||||||
|
if (--left <= 0) ImGui::GetIO().AddKeyEvent(k, false);
|
||||||
|
std::erase_if(holding_, [](const auto& h) { return h.second <= 0; });
|
||||||
if (bench_.left <= 0) return;
|
if (bench_.left <= 0) return;
|
||||||
const int i = int(bench_.ms.size());
|
const int i = int(bench_.ms.size());
|
||||||
Object* o = find(active_);
|
Object* o = find(active_);
|
||||||
|
|
|
||||||
|
|
@ -1463,6 +1463,7 @@ private:
|
||||||
int left = 0;
|
int left = 0;
|
||||||
std::vector<double> ms;
|
std::vector<double> ms;
|
||||||
} bench_;
|
} bench_;
|
||||||
|
std::vector<std::pair<ImGuiKey, int>> holding_; // (fry_hold: keys held down for that many more frames)
|
||||||
void benchStep();
|
void benchStep();
|
||||||
void benchEnd(std::chrono::steady_clock::time_point began);
|
void benchEnd(std::chrono::steady_clock::time_point began);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -446,7 +446,8 @@ auto App::helpWindow() -> void {
|
||||||
rows("Finding things", {{"F3 or Ctrl+Space", "Search for any command by name and run it"}, {"Space (held)", "The tools round the mouse: point at one, let go"},
|
rows("Finding things", {{"F3 or Ctrl+Space", "Search for any command by name and run it"}, {"Space (held)", "The tools round the mouse: point at one, let go"},
|
||||||
{"Shift+Space (held)", "The views round the mouse"}});
|
{"Shift+Space (held)", "The views round the mouse"}});
|
||||||
myKeysTable();
|
myKeysTable();
|
||||||
rows("Looking around", {{"Right drag", "Orbit round what you look at"}, {"Middle drag / Shift+Right drag", "Pan"}, {"Wheel", "Zoom (towards the mouse)"},
|
rows("Looking around", {{"Right drag", "Orbit round what you look at"}, {"Middle drag / Shift+Right drag", "Pan"}, {"Wheel", "Zoom (towards what's under the mouse)"},
|
||||||
|
{"Arrow keys", "Move round (Page Up / Down: up and down; Shift: faster)"},
|
||||||
{"Orbit / Pan / Zoom buttons", "Drag them (touchpads)"}, {"F", "Frame the selection"}, {"Home", "Frame everything"},
|
{"Orbit / Pan / Zoom buttons", "Drag them (touchpads)"}, {"F", "Frame the selection"}, {"Home", "Frame everything"},
|
||||||
{"Numpad 1 / 3 / 7", "Front / side / top (Shift: the opposite)"}, {"Numpad 5", "Flat view / 3D"},
|
{"Numpad 1 / 3 / 7", "Front / side / top (Shift: the opposite)"}, {"Numpad 5", "Flat view / 3D"},
|
||||||
{"Z / Shift+Z", "Solid or Rendered / Wireframe"}, {"Alt+Z", "X-ray: see and pick through"}});
|
{"Z / Shift+Z", "Solid or Rendered / Wireframe"}, {"Alt+Z", "X-ray: see and pick through"}});
|
||||||
|
|
|
||||||
|
|
@ -194,11 +194,35 @@ auto App::updateCamera(ImGuiIO& io) -> void {
|
||||||
findSoft();
|
findSoft();
|
||||||
message_ = std::format("Soft selection reaches {:.3f} m (wheel)", softReach_), messageAt_ = now();
|
message_ = std::format("Soft selection reaches {:.3f} m (wheel)", softReach_), messageAt_ = now();
|
||||||
} else if (inView && io.MouseWheel != 0) {
|
} else if (inView && io.MouseWheel != 0) {
|
||||||
// Towards what's under the mouse: the target slides that way a little.
|
// Towards what's under the mouse: an object, else the ground, else the plane the target's
|
||||||
|
// on. The whole camera closes in on that point (it stays under the mouse), so far from
|
||||||
|
// everything you still get somewhere instead of creeping at a spot in the air.
|
||||||
const float k = std::pow(0.85f, io.MouseWheel);
|
const float k = std::pow(0.85f, io.MouseWheel);
|
||||||
const Ray ray = mouseRay(io.MousePos);
|
const Ray ray = mouseRay(io.MousePos);
|
||||||
if (auto p = hitPlane(ray, target_, -viewDir())) target_ += (*p - target_) * (1.0f - k);
|
std::optional<glm::vec3> at;
|
||||||
dist_ = std::clamp(dist_ * k, 0.01f, 5000.0f);
|
if (const Hit h = pickObject(ray); h.object) at = ray.origin + ray.dir * h.t;
|
||||||
|
else if (auto g = hitPlane(ray, glm::vec3(0.0f), glm::vec3(0, 0, 1)); g && glm::distance(*g, eye_) < dist_ * 40.0f) at = g;
|
||||||
|
if (!at && k < 1.0f) target_ += ray.dir * dist_ * (1.0f - k); // (nothing there: the sky; on that way)
|
||||||
|
else {
|
||||||
|
if (!at) at = hitPlane(ray, target_, -viewDir());
|
||||||
|
const float to = std::clamp(dist_ * k, 0.01f, 5000.0f);
|
||||||
|
if (at) target_ = *at + (target_ - *at) * (to / dist_);
|
||||||
|
dist_ = to;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Arrow keys: forward, back and sideways along the ground (in a flat view: the way they
|
||||||
|
// point on the screen), Page Up / Down: up and down; Shift: faster. As fast as the view is big.
|
||||||
|
if (!io.WantTextInput && !search_.open && !ImGui::IsAnyItemActive() && !io.KeyCtrl && !io.KeyAlt) {
|
||||||
|
const float x = float(ImGui::IsKeyDown(ImGuiKey_RightArrow)) - float(ImGui::IsKeyDown(ImGuiKey_LeftArrow));
|
||||||
|
const float y = float(ImGui::IsKeyDown(ImGuiKey_UpArrow)) - float(ImGui::IsKeyDown(ImGuiKey_DownArrow));
|
||||||
|
const float z = float(ImGui::IsKeyDown(ImGuiKey_PageUp)) - float(ImGui::IsKeyDown(ImGuiKey_PageDown));
|
||||||
|
if (x != 0 || y != 0 || z != 0) {
|
||||||
|
const glm::vec3 f = viewDir(), right = glm::normalize(glm::cross(f, std::abs(f.z) > 0.99f ? glm::vec3(std::cos(glm::radians(yaw_)), std::sin(glm::radians(yaw_)), 0) : glm::vec3(0, 0, 1)));
|
||||||
|
const glm::vec3 ahead = view_ == View::Perspective ? glm::normalize(glm::cross(glm::vec3(0, 0, 1), right)) : glm::cross(right, f);
|
||||||
|
const float dt = std::min(io.DeltaTime, 0.1f), speed = dist_ * (io.KeyShift ? 2.5f : 0.8f) * dt;
|
||||||
|
target_ += (right * x + ahead * y + (view_ == View::Perspective ? glm::vec3(0, 0, z) : glm::vec3(0.0f))) * speed;
|
||||||
|
if (view_ != View::Perspective && z != 0) dist_ = std::clamp(dist_ * std::pow(io.KeyShift ? 0.1f : 0.4f, z * dt), 0.01f, 5000.0f); // (flat: closer or further)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
settleView();
|
settleView();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue