@@ -48,8 +48,8 @@ float& flightInitialFov = state::globalContext.flightInitialFov;
4848// Default values
4949const int defaultWindowWidth = 1280 ;
5050const int defaultWindowHeight = 720 ;
51- const float defaultNearClipRatio = 1e-2 ;
52- const float defaultFarClipRatio = 1e2 ;
51+ const float defaultNearClipRatio = 0 . 005f ;
52+ const float defaultFarClipRatio = 20 .f ;
5353const float defaultFov = 45 .;
5454const float minFov = 5 .; // for UI
5555const float maxFov = 160 .; // for UI
@@ -274,9 +274,11 @@ void processTranslate(glm::vec2 delta) {
274274 glm::vec3 worldspaceT =
275275 glm::transpose (glm::mat3 (viewMat)) * glm::vec3 (-movementScale * delta.x , -movementScale * delta.y , 0.0 );
276276 glm::vec3 newCenter = oldCenter + worldspaceT;
277- setViewCenter (newCenter, false );
277+ setViewCenterRaw (newCenter);
278278 }
279279
280+ projectCenterToBeValidForView ();
281+
280282 requestRedraw ();
281283 immediatelyEndFlight ();
282284}
@@ -288,7 +290,7 @@ void processClipPlaneShift(float amount) {
288290 requestRedraw ();
289291}
290292
291- void processZoom (float amount, bool relativeToCenter ) {
293+ void processZoom (float amount) {
292294 if (amount == 0.0 ) return ;
293295 if (getNavigateStyle () == NavigateStyle::None || getNavigateStyle () == NavigateStyle::FirstPerson) {
294296 return ;
@@ -381,7 +383,7 @@ void processSetCenter(glm::vec2 screenCoords) {
381383 PickResult pickResult = pickAtScreenCoords (screenCoords);
382384
383385 if (pickResult.isHit ) {
384- setViewCenter (pickResult.position , true );
386+ setViewCenterAndLookAt (pickResult.position , true );
385387 }
386388}
387389
@@ -424,6 +426,36 @@ float computeRelativeMotionScale() {
424426 }
425427}
426428
429+ void projectCenterToBeValidForView () {
430+ // If necessary, move the view center to be one that is compatible with the current view matrix and navigation style.
431+
432+ switch (style) {
433+ case NavigateStyle::Turntable: {
434+
435+ // Center must lie exactly along the camera look direction
436+
437+ glm::vec3 camPos = getCameraWorldPosition ();
438+ glm::vec3 camLookDir, camUpDir, camRightDir;
439+ getCameraFrame (camLookDir, camUpDir, camRightDir);
440+ glm::vec3 sceneUpDir = getUpVec ();
441+ glm::vec3 vecToCenter = viewCenter - camPos;
442+ float distToCenter = glm::length (vecToCenter);
443+ glm::vec3 newCenter = camPos + camLookDir * distToCenter;
444+
445+ setViewCenterRaw (newCenter);
446+
447+ break ;
448+ }
449+ case NavigateStyle::Planar:
450+ case NavigateStyle::Free:
451+ case NavigateStyle::Arcball:
452+ case NavigateStyle::None:
453+ case NavigateStyle::FirstPerson:
454+ // No constraints
455+ break ;
456+ }
457+ }
458+
427459glm::mat4 computeHomeView () {
428460
429461 glm::vec3 target = view::viewCenter;
@@ -558,7 +590,7 @@ void updateViewAndChangeFrontDir(FrontDir newFrontDir, bool flyTo) {
558590 }
559591}
560592
561- void updateViewAndChangeCenter (glm::vec3 newCenter, bool flyTo) {
593+ void setViewCenterAndLookAt (glm::vec3 newCenter, bool flyTo) {
562594
563595 view::viewCenter = newCenter;
564596
@@ -594,7 +626,12 @@ void updateViewAndChangeCenter(glm::vec3 newCenter, bool flyTo) {
594626 }
595627}
596628
597- void setViewCenter (glm::vec3 newCenter, bool flyTo) { updateViewAndChangeCenter (newCenter, flyTo); }
629+ void setViewCenterAndProject (glm::vec3 newCenter) {
630+ view::viewCenter = newCenter;
631+ projectCenterToBeValidForView ();
632+ }
633+
634+ void setViewCenterRaw (glm::vec3 newCenter) { view::viewCenter = newCenter; }
598635
599636glm::vec3 getViewCenter () { return view::viewCenter; }
600637
@@ -621,10 +658,12 @@ void lookAt(glm::vec3 cameraLocation, glm::vec3 target, glm::vec3 upDir, bool fl
621658 // just continue after; our view handling will take care of the NaN and set it to the default view
622659 }
623660
661+
624662 if (flyTo) {
625663 startFlightTo (targetView, fov);
626664 } else {
627665 viewMat = targetView;
666+ projectCenterToBeValidForView ();
628667 requestRedraw ();
629668 }
630669}
@@ -646,6 +685,7 @@ void setViewToCamera(const CameraParameters& p) {
646685 fov = p.getFoVVerticalDegrees ();
647686 // aspectRatio = p.focalLengths.x / p.focalLengths.y; // TODO should be
648687 // flipped?
688+ projectCenterToBeValidForView ();
649689}
650690
651691CameraParameters getCameraParametersForCurrentView () {
@@ -656,7 +696,11 @@ CameraParameters getCameraParametersForCurrentView() {
656696 CameraExtrinsics::fromMatrix (viewMat));
657697}
658698
659- void setCameraViewMatrix (glm::mat4 mat) { viewMat = mat; }
699+ void setCameraViewMatrix (glm::mat4 mat) {
700+ viewMat = mat;
701+ projectCenterToBeValidForView ();
702+ requestRedraw ();
703+ }
660704
661705glm::mat4 getCameraViewMatrix () { return viewMat; }
662706
@@ -778,7 +822,14 @@ glm::vec3 bufferCoordsToWorldRay(glm::vec2 bufferCoords) {
778822std::tuple<float , float > computeClipPlanes () {
779823 float s = computeRelativeMotionScale ();
780824 float absFarClip = farClip * s;
781- float absNearClip = nearClip * s;
825+
826+ // it's tempting to compute both near and far clip planes from the scale,
827+ // but computing the near clip plane this way gives flickering very quickly when zooming in on surface details
828+ // float absNearClip = nearClip * s;
829+
830+ // instead, always use the length scale for the near clip plane
831+ float absNearClip = nearClip * state::lengthScale;
832+
782833 return std::make_tuple (absNearClip, absFarClip);
783834}
784835
@@ -1000,10 +1051,10 @@ void setViewFromJson(std::string jsonData, bool flyTo) {
10001051 newCenter.x = centerData[0 ];
10011052 newCenter.y = centerData[1 ];
10021053 newCenter.z = centerData[2 ];
1003- setViewCenter (newCenter, flyTo );
1054+ setViewCenterRaw (newCenter);
10041055 }
10051056 }
1006-
1057+
10071058 // NOTE: it's important that we do this after the mode/dir settings, as this
10081059 // lets us do our flight
10091060 bool viewChanged = false ;
@@ -1027,7 +1078,7 @@ void setViewFromJson(std::string jsonData, bool flyTo) {
10271078 if (flyTo) {
10281079 startFlightTo (newViewMat, fov);
10291080 } else {
1030- viewMat = newViewMat;
1081+ setCameraViewMatrix ( newViewMat) ;
10311082 fov = newFov;
10321083 requestRedraw ();
10331084 }
0 commit comments