bevy_pancam
bevy_pancam copied to clipboard
add config options to allow global coord clamping
- allows one to set a minimum and maximum x and y to act as boundaries for the camera projection
- works for both dragging and zooming
Fixes: #11
Hello! I've been getting into bevy recently, and I found your camera super helpful. Thank you for open sourcing it! I did find, however, that I wanted to be able to restrict the camera's view window so that I didn't drag or zoom the window beyond the borders of a specific grid. I did some local tinkering and I got it working pretty much as I envisioned. If the change looks good to you, I thought it'd be a nice first contribution to the bevy community to merge this support upstream :)
Video of the implemented behavior: https://user-images.githubusercontent.com/8944532/189548695-7bd62198-eea7-4fa0-a576-6d1f01b02a2b.mp4
Hey, and thanks for the contribution! It's a difficult task with lots of literal edge cases :)
Overall, it looks like the implementation makes sense, but like you say, it's kind of hard to wrap your head around the equation as it stands, and it adds quite a lot of complexity to otherwise straightforward code. If possible I'd like us to try and make it more readable.
Thanks for the comments, they all seem reasonable, and I absolutely agree my initial pass could use a fair bit of clean up! I mostly just wanted to get a first POC up to show that the behavior is technically achievable without adding new funcs/systems. I'll take a swing at cleaning it up after work tonight
@johanhelsing Apologies, wasn't able to dedicate enough heads-down time dig into the zooming math until the weekend. I'm still not sure I can explain how it works exhaustively, but I've tried to clean up the math to make it more readable (your suggestions were incredibly helpful in doing so!).
I moved the max allowable zoom scale logic to two new functions, max_scale_within_x_bounds
and max_scale_within_y_bounds
, mostly so that I could add commentary explaining what was going on without it bloating the original function. I'm happy to remove the long function comment if it feels redundant, but I found it personally helpful to write out a number of examples of how the projection, window, and boundary dimensions would interact with one another. Kind of an "if you turn these knobs, this is what will happen" set.
I renamed all the global/pixel stuff to remove the misleading elements. I think I made a lot of bad assumptions when first trying to understand how cameras work in bevy. I'm definitely not to full understanding yet, but I think I'm starting to grok the basic components a bit better.
I also moved the example to the examples folder, I hadn't even known you could execute examples via cargo run --example
, cargo is pretty cool! I appreciate your patience and helpful suggestions, I feel like I'm learning a lot about how to write Rust and Bevy 😄 If you wouldn't mind taking a look at the updated code, I'm of course happy to make any others changes that jump out.
Thank you for the PR @johanhelsing , I think that really provided the remaining refinement needed on the scaling functions! I just put up another commit to add some unit tests for the scale functions and hopefully make the clamped_border
comments more useful. I think I'm starting to feel pretty good about merging this (assuming it passes CI), but as always am happy to address anything you think might be remaining
Sorry for being slow to get back, it can be hard to find time for side projects when balancing work and home life. But wow, I feel like you cracked the final piece of this with the simplification of the math. Nicely done! I merged your PR to my fork, and am going to see if I can get some unit tests in place. I'm still wrapping my head a bit around Rust unit testing, but I think it's a good opportunity to learn it while also making sure some of my assumptions are correct
No worries. I've also been juggling a lot lately.
I'm happy it turned out to be really simple and readable in the end :) Thanks again!