feat: Enhance camera orbiting - #1
Conversation
This commit introduces a new orbiting functionality by implementing a polar coordinate system (constrained to the Z-axis). This new method makes the orbit camera a lil more intuitive Key enhancements: - A new `moveCamForAxes` function for smoother, more predictable orbiting. - Improved exception handling with the addition of a `log_exception` function. - Constrained camera pitch to prevent unexpected camera rolls.
|
|
||
| # starting global orbit state (simple polar coordinates) | ||
| # this is the reason why the default camera buttons are conflicting with the orbit | ||
| # when you press them, right now they ain't updating these states, so as you move the joystick, you go back to where these were |
|
If I remember correctly, these except block changes were just to avoid letting bare excepts (mainly to get rid of the IDE warnings). My implementation was to take whatever text the fusion360 handler gave to that error and print on the API shell, centralizing that to the |
nivekmai
left a comment
There was a problem hiding this comment.
Required:
- update yaw/pitch/orbit when orientCam called
Nits:
- move global variable definitions to be like the others (globalize and init in
run) - use pascalCase instead of lower_snake to have consistent variable/method naming
Other than that, it works well! If you wanna address the required and nits I'll merge, otherwise I'll just rewrite using your new maths and my preferred style.
| cam.isSmoothTransition = True | ||
| else: | ||
| cam.viewOrientation = nextOrientation | ||
| setCam(cam) |
There was a problem hiding this comment.
Since you now store separate variables for the camera location instead of updating the existing camera, you need to update the local variables to match the camera when hitting HAT buttons.
| @@ -582,28 +609,6 @@ def constrain(vector: Vector3D) -> Vector3D: | |||
| return vector | |||
There was a problem hiding this comment.
All unused now right? Can delete
There was a problem hiding this comment.
Yes these were replaced by implementations inside the new moveCamForAxes itself
|
|
||
| yaw_angle += rotateXAxis * 0.05 | ||
| pitch_angle += rotateYAxis * 0.05 | ||
|
|
There was a problem hiding this comment.
extract 0.05 to a constant (maybe update ROTATION_AXIS_SCALE since you don't use it anymore?)
There was a problem hiding this comment.
yeah definitely. Also, that needed to be fine-tuned, but I personally found it quite fluid with that scaling factor
| yaw_angle += rotateXAxis * 0.05 | ||
| pitch_angle += rotateYAxis * 0.05 | ||
|
|
||
| MAX_PITCH = radians(89.9) |
There was a problem hiding this comment.
Should be a constant up w/ the others?
There was a problem hiding this comment.
I think that's much closely related to the orbiting context, and that constant is just there to prevent the glitches when trying to loop on the object (over XY plane). In that regard, this constant could even be ditched and replaced with a hardcoded max angle value on the relevant section, maybe with a comment explaining that option (L442)
| # you'll se that the 360 orbit is not smooth | ||
| pitch_angle = max(-MAX_PITCH, min(MAX_PITCH, pitch_angle)) | ||
|
|
||
| orbit_radius *= (1 - zoomAxis * 0.05) |
There was a problem hiding this comment.
Should this use the same ROTATION_AXIS_SCALE constant as L435, L436?
There was a problem hiding this comment.
nop that controls how fast the zoom occurs when a zooming signal is detected [-1,1] * zooming factor (in this case 0.05)
| cx = cos(yaw_angle) * cos(pitch_angle) | ||
| cy = sin(yaw_angle) * cos(pitch_angle) | ||
| cz = sin(pitch_angle) | ||
| orbit_offset = Vector3D.create(cx, cy, cz) | ||
| orbit_offset.normalize() | ||
| orbit_offset.scaleBy(orbit_radius) |
There was a problem hiding this comment.
Would be nice to pull this out to a method (getOrbitOffset)
| if panXAxis != 0: | ||
| pan_h = side_vec.copy() | ||
| pan_h.scaleBy(scalePanAxis(panXAxis) * orbit_radius * PAN_ZOOM_COMPENSATION) | ||
| pan_vec.add(pan_h) | ||
| if panYAxis != 0: | ||
| pan_v = local_up.copy() | ||
| pan_v.scaleBy(scalePanAxis(panYAxis) * orbit_radius * PAN_ZOOM_COMPENSATION) | ||
| pan_vec.add(pan_v) |
There was a problem hiding this comment.
pull duplicated code to a method
...
addScaledPanComponent(pan_vec, panXAxis, side_vec, orbit_radius)
addScaledPanComponent(pan_vec, panYAxis, local_up, orbit_radius)
...
addScaledPanComponent(panVec, axis, inputVec, orbitRadius):
panComponent = inputVec.copy()
panComponent.scaleBy(scalePanAxis(axis) * orbitRadius * PAN_ZOOM_COMPENSATION)
panVec.add(panComponent)
|
I'm having trouble making the new My implementation was to basically reverse engineer the camera position that fusion gives, into polar terms, using atan/asin, and then updating the respective variables (which are now global, initialized inside A brief summary is: inside My controller has got some serious drift, so that isn't helping either |
I'd assume that's why you see it "snap back after a second", probably the drift triggering a move, I find it only snapping back if I start moving joysticks. Maybe try increasing the dead zone to compensate for the drift? |
This commit introduces a new orbiting functionality by implementing a polar coordinate system (constrained to the Z-axis). This new method makes the orbit camera a lil more intuitive
Key enhancements:
moveCamForAxesfunction for smoother, more predictable orbiting.log_exceptionfunction.