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
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");
|
||||
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");
|
||||
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 layout("fry_layout", [](const keel::Args& a) {
|
||||
Object* o = self->find(self->active_);
|
||||
|
|
@ -460,6 +475,9 @@ auto App::onEscape() -> void {
|
|||
|
||||
// (fry_bench) Each frame: the change being timed.
|
||||
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;
|
||||
const int i = int(bench_.ms.size());
|
||||
Object* o = find(active_);
|
||||
|
|
|
|||
|
|
@ -1463,6 +1463,7 @@ private:
|
|||
int left = 0;
|
||||
std::vector<double> ms;
|
||||
} bench_;
|
||||
std::vector<std::pair<ImGuiKey, int>> holding_; // (fry_hold: keys held down for that many more frames)
|
||||
void benchStep();
|
||||
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"},
|
||||
{"Shift+Space (held)", "The views round the mouse"}});
|
||||
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"},
|
||||
{"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"}});
|
||||
|
|
|
|||
|
|
@ -194,11 +194,35 @@ auto App::updateCamera(ImGuiIO& io) -> void {
|
|||
findSoft();
|
||||
message_ = std::format("Soft selection reaches {:.3f} m (wheel)", softReach_), messageAt_ = now();
|
||||
} 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 Ray ray = mouseRay(io.MousePos);
|
||||
if (auto p = hitPlane(ray, target_, -viewDir())) target_ += (*p - target_) * (1.0f - k);
|
||||
dist_ = std::clamp(dist_ * k, 0.01f, 5000.0f);
|
||||
std::optional<glm::vec3> at;
|
||||
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();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue