diff --git a/include/icameraview.h b/include/icameraview.h index aed52f2d45..23deed5435 100644 --- a/include/icameraview.h +++ b/include/icameraview.h @@ -17,6 +17,9 @@ class ICameraView : virtual ~ICameraView() {} + // Sets the device width and height, updates the projection + virtual void setDeviceDimensions(int width, int height) = 0; + // Move the camera's origin virtual const Vector3& getCameraOrigin() const = 0; virtual void setCameraOrigin(const Vector3& newOrigin) = 0; @@ -33,6 +36,10 @@ class ICameraView : virtual const Matrix4& getModelView() const = 0; virtual const Matrix4& getProjection() const = 0; + + // Cubic clipping + virtual float getFarClipPlaneDistance() const = 0; + virtual void setFarClipPlaneDistance(float distance) = 0; }; class IFreeMoveView : diff --git a/radiant/camera/CamWnd.cpp b/radiant/camera/CamWnd.cpp index 1c931a4d76..71508d8156 100644 --- a/radiant/camera/CamWnd.cpp +++ b/radiant/camera/CamWnd.cpp @@ -59,6 +59,11 @@ namespace const unsigned int MOVE_PITCHUP = 1 << 8; const unsigned int MOVE_PITCHDOWN = 1 << 9; const unsigned int MOVE_ALL = MOVE_FORWARD | MOVE_BACK | MOVE_ROTRIGHT | MOVE_ROTLEFT | MOVE_STRAFERIGHT | MOVE_STRAFELEFT | MOVE_UP | MOVE_DOWN | MOVE_PITCHUP | MOVE_PITCHDOWN; + + inline float calculateFarPlaneDistance(int cubicScale) + { + return pow(2.0, (cubicScale + 7) / 2.0); + } } inline Vector2 windowvector_for_widget_centre(wxutil::GLWidget& widget) @@ -89,6 +94,8 @@ CamWnd::CamWnd(wxWindow* parent) : Bind(wxEVT_TIMER, &CamWnd::onFrame, this, _timer.GetId()); Bind(wxEVT_TIMER, &CamWnd::onFreeMoveTimer, this, _freeMoveTimer.GetId()); + updateFarClipPlane(); + constructGUIComponents(); // Connect the mouse button events @@ -281,6 +288,11 @@ int CamWnd::getDeviceHeight() const return _camera.getDeviceHeight(); } +void CamWnd::setDeviceDimensions(int width, int height) +{ + _camera.setDeviceDimensions(width, height); +} + void CamWnd::startRenderTime() { if (_timer.IsRunning()) @@ -598,9 +610,7 @@ void CamWnd::Cam_Draw() if (_camera.getDeviceWidth() != glSize.GetWidth() || _camera.getDeviceHeight() != glSize.GetHeight()) { - _camera.setDeviceWidth(glSize.GetWidth()); - _camera.setDeviceHeight(glSize.GetHeight()); - _camera.updateProjection(); + _camera.setDeviceDimensions(glSize.GetWidth(), glSize.GetHeight()); } int height = _camera.getDeviceHeight(); @@ -974,28 +984,42 @@ void CamWnd::onFarClipPlaneInClick(wxCommandEvent& ev) void CamWnd::farClipPlaneOut() { - getCameraSettings()->setCubicScale( getCameraSettings()->cubicScale() + 1 ); + auto newCubicScale = getCameraSettings()->cubicScale() + 1; + getCameraSettings()->setCubicScale(newCubicScale); - _camera.updateProjection(); + _camera.setFarClipPlaneDistance(calculateFarPlaneDistance(newCubicScale)); update(); } void CamWnd::farClipPlaneIn() { - getCameraSettings()->setCubicScale( getCameraSettings()->cubicScale() - 1 ); + auto newCubicScale = getCameraSettings()->cubicScale() - 1; + getCameraSettings()->setCubicScale(newCubicScale); - _camera.updateProjection(); + _camera.setFarClipPlaneDistance(calculateFarPlaneDistance(newCubicScale)); update(); } +void CamWnd::updateFarClipPlane() +{ + _camera.setFarClipPlaneDistance(calculateFarPlaneDistance(getCameraSettings()->cubicScale())); +} + +float CamWnd::getFarClipPlaneDistance() const +{ + return _camera.getFarClipPlaneDistance(); +} + +void CamWnd::setFarClipPlaneDistance(float distance) +{ + _camera.setFarClipPlaneDistance(distance); +} + void CamWnd::onGLResize(wxSizeEvent& ev) { - getCamera().setDeviceWidth(ev.GetSize().GetWidth()); - getCamera().setDeviceHeight(ev.GetSize().GetHeight()); - getCamera().updateProjection(); + getCamera().setDeviceDimensions(ev.GetSize().GetWidth(), ev.GetSize().GetHeight()); queueDraw(); - ev.Skip(); } diff --git a/radiant/camera/CamWnd.h b/radiant/camera/CamWnd.h index be720a1059..2aa910ab5f 100644 --- a/radiant/camera/CamWnd.h +++ b/radiant/camera/CamWnd.h @@ -107,6 +107,9 @@ class CamWnd : void queueDraw() override; void forceRedraw() override; + // Note: this only updates the GL viewport size, it doesn't resize the GL widget itself + void setDeviceDimensions(int width, int height); + void update(); // The callback when the scene gets changed @@ -152,6 +155,9 @@ class CamWnd : // Increases/decreases the far clip plane distance void farClipPlaneIn(); void farClipPlaneOut(); + void updateFarClipPlane(); + float getFarClipPlaneDistance() const override; + void setFarClipPlaneDistance(float distance) override; void startRenderTime(); void stopRenderTime(); diff --git a/radiant/camera/Camera.cpp b/radiant/camera/Camera.cpp index d99d474660..44fbe264bb 100644 --- a/radiant/camera/Camera.cpp +++ b/radiant/camera/Camera.cpp @@ -53,6 +53,7 @@ Camera::Camera(render::View& view, const Callback& queueDraw, const Callback& fo _queueDraw(queueDraw), _forceRedraw(forceRedraw), _fieldOfView(75.0f), + _farClipPlane(32768), _width(0), _height(0), _projection(Matrix4::getIdentity()), @@ -162,14 +163,11 @@ int Camera::getDeviceHeight() const return _height; } -void Camera::setDeviceWidth(int width) +void Camera::setDeviceDimensions(int width, int height) { _width = width; -} - -void Camera::setDeviceHeight(int height) -{ _height = height; + updateProjection(); } SelectionTestPtr Camera::createSelectionTestForPoint(const Vector2& point) @@ -214,19 +212,20 @@ void Camera::moveUpdateAxes() { _right[1] = -_forward[0]; } -bool Camera::farClipEnabled() const +float Camera::getFarClipPlaneDistance() const { - return getCameraSettings()->farClipEnabled(); + return _farClipPlane; } -float Camera::getFarClipPlane() const +void Camera::setFarClipPlaneDistance(float distance) { - return (farClipEnabled()) ? pow(2.0, (getCameraSettings()->cubicScale() + 7) / 2.0) : 32768.0f; + _farClipPlane = distance; + updateProjection(); } void Camera::updateProjection() { - float farClip = getFarClipPlane(); + auto farClip = getFarClipPlaneDistance(); _projection = projection_for_camera(farClip / 4096.0f, farClip, _fieldOfView, _width, _height); _view.Construct(_projection, _modelview, _width, _height); diff --git a/radiant/camera/Camera.h b/radiant/camera/Camera.h index 36562d26a3..99d399586b 100644 --- a/radiant/camera/Camera.h +++ b/radiant/camera/Camera.h @@ -25,6 +25,7 @@ class Camera : Callback _forceRedraw; float _fieldOfView; + float _farClipPlane; int _width; int _height; @@ -43,12 +44,9 @@ class Camera : void updateVectors(); void updateModelview(); - void updateProjection(); - - float getFarClipPlane() const; - // Returns true if cubic clipping is "on" - bool farClipEnabled() const; + float getFarClipPlaneDistance() const override; + void setFarClipPlaneDistance(float distance) override; void freemoveUpdateAxes(); void moveUpdateAxes(); @@ -67,9 +65,8 @@ class Camera : const Matrix4& getProjection() const override; int getDeviceWidth() const override; - void setDeviceWidth(int width); int getDeviceHeight() const override; - void setDeviceHeight(int height); + void setDeviceDimensions(int width, int height) override; SelectionTestPtr createSelectionTestForPoint(const Vector2& point) override; const VolumeTest& getVolumeTest() const override; @@ -87,6 +84,9 @@ class Camera : void moveUpDiscrete(double units); void moveBackDiscrete(double units); void moveForwardDiscrete(double units); + +private: + void updateProjection(); }; } // namespace diff --git a/radiant/camera/CameraSettings.cpp b/radiant/camera/CameraSettings.cpp index e0b2e156c9..94ba39910e 100644 --- a/radiant/camera/CameraSettings.cpp +++ b/radiant/camera/CameraSettings.cpp @@ -157,7 +157,7 @@ void CameraSettings::keyChanged() // Reconnect the new handlers cam->addHandlersMove(); - cam->getCamera().updateProjection(); + cam->updateFarClipPlane(); if (freeMovedWasEnabled) {