diff --git a/common/camera.cpp b/common/camera.cpp index 182c760e..6d823f38 100644 --- a/common/camera.cpp +++ b/common/camera.cpp @@ -770,7 +770,7 @@ void lcCamera::ZoomExtents(float AspectRatio, const lcVector3& Center, const lcV lcVector3 Position(mPosition + Center - mTargetPosition); lcMatrix44 ProjectionMatrix = lcMatrix44Perspective(m_fovy, AspectRatio, m_zNear, m_zFar); - mPosition = lcZoomExtents(Position, mWorldView, ProjectionMatrix, Points, NumPoints); + std::tie(mPosition, std::ignore) = lcZoomExtents(Position, mWorldView, ProjectionMatrix, Points, NumPoints); mTargetPosition = Center; } @@ -816,7 +816,7 @@ void lcCamera::ZoomRegion(float AspectRatio, const lcVector3& Position, const lc lcMatrix44 WorldView = lcMatrix44LookAt(Position, TargetPosition, mUpVector); lcMatrix44 ProjectionMatrix = lcMatrix44Perspective(m_fovy, AspectRatio, m_zNear, m_zFar); - mPosition = lcZoomExtents(Position, WorldView, ProjectionMatrix, Corners, 2); + std::tie(mPosition, std::ignore) = lcZoomExtents(Position, WorldView, ProjectionMatrix, Corners, 2); mTargetPosition = TargetPosition; } diff --git a/common/lc_math.h b/common/lc_math.h index e2db2960..38f00671 100644 --- a/common/lc_math.h +++ b/common/lc_math.h @@ -1517,36 +1517,46 @@ inline void lcGetFrustumPlanes(const lcMatrix44& WorldView, const lcMatrix44& Pr } } -inline lcVector3 lcZoomExtents(const lcVector3& Position, const lcMatrix44& WorldView, const lcMatrix44& Projection, const lcVector3* Points, int NumPoints) +inline std::tuple lcZoomExtents(const lcVector3& Position, const lcMatrix44& WorldView, const lcMatrix44& Projection, const lcVector3* Points, int NumPoints) { if (!NumPoints) - return Position; + return std::make_tuple(Position, 2500.0f); lcVector4 Planes[6]; lcGetFrustumPlanes(WorldView, Projection, Planes); lcVector3 Front(WorldView[0][2], WorldView[1][2], WorldView[2][2]); - // Calculate the position that is as close as possible to the model and has all pieces visible. float SmallestDistance = FLT_MAX; - for (int p = 0; p < 4; p++) + for (int PlaneIdx = 0; PlaneIdx < 4; PlaneIdx++) { - lcVector3 Plane(Planes[p][0], Planes[p][1], Planes[p][2]); + lcVector3 Plane(Planes[PlaneIdx][0], Planes[PlaneIdx][1], Planes[PlaneIdx][2]); float ep = lcDot(Position, Plane); float fp = lcDot(Front, Plane); - for (int j = 0; j < NumPoints; j++) + for (int PointIdx = 0; PointIdx < NumPoints; PointIdx++) { - // Intersect the camera line with the plane that contains this point, NewEye = Eye + u * (Target - Eye) - float u = (ep - lcDot(Points[j], Plane)) / fp; + float u = (ep - lcDot(Points[PointIdx], Plane)) / fp; if (u < SmallestDistance) SmallestDistance = u; } } - return Position - (Front * SmallestDistance); + lcVector3 NewPosition = Position - (Front * SmallestDistance); + + float FarDistance = 2500.0f; + + for (int PointIdx = 0; PointIdx < NumPoints; PointIdx++) + { + float Distance = lcDot(Points[PointIdx], Front); + + if (Distance > FarDistance) + FarDistance = Distance; + } + + return std::make_tuple(NewPosition, FarDistance + lcDot(NewPosition, Front)); } inline void lcClosestPointsBetweenLines(const lcVector3& Line1a, const lcVector3& Line1b, const lcVector3& Line2a, const lcVector3& Line2b, lcVector3* Intersection1, lcVector3* Intersection2) diff --git a/common/lc_partselectionwidget.cpp b/common/lc_partselectionwidget.cpp index 4bd545da..bf6661e3 100644 --- a/common/lc_partselectionwidget.cpp +++ b/common/lc_partselectionwidget.cpp @@ -329,11 +329,7 @@ void lcPartSelectionListModel::DrawPreview(int InfoIndex) float Aspect = (float)Width / (float)Height; Context->SetViewport(0, 0, Width, Height); - lcMatrix44 ProjectionMatrix = lcMatrix44Perspective(20.0f, Aspect, 1.0f, 12500.0f); - lcMatrix44 ViewMatrix; - Context->SetDefaultState(); - Context->SetProjectionMatrix(ProjectionMatrix); lcPiecesLibrary* Library = lcGetPiecesLibrary(); PieceInfo* Info = mParts[InfoIndex].first; @@ -341,8 +337,11 @@ void lcPartSelectionListModel::DrawPreview(int InfoIndex) glClearColor(1.0f, 1.0f, 1.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - lcVector3 CameraPosition(-100.0f, -100.0f, 75.0f); - Info->ZoomExtents(ProjectionMatrix, ViewMatrix, CameraPosition); + lcMatrix44 ProjectionMatrix, ViewMatrix; + + Info->ZoomExtents(20.0f, Aspect, ProjectionMatrix, ViewMatrix); + + Context->SetProjectionMatrix(ProjectionMatrix); lcScene Scene; Scene.Begin(ViewMatrix); diff --git a/common/minifig.cpp b/common/minifig.cpp index 187fd807..336c4ca1 100644 --- a/common/minifig.cpp +++ b/common/minifig.cpp @@ -254,11 +254,10 @@ void MinifigWizard::OnDraw() Eye += Center; lcMatrix44 ModelView = lcMatrix44LookAt(Eye, Center, lcVector3(0, 0, 1)); - Eye = lcZoomExtents(Eye, ModelView, Projection, Points, 8); + std::tie(Eye, std::ignore) = lcZoomExtents(Eye, ModelView, Projection, Points, 8); ViewMatrix = lcMatrix44LookAt(Eye, Center, lcVector3(0, 0, 1)); - // Update the new camera distance. lcVector3 d = Eye - Center; mDistance = d.Length(); } diff --git a/common/pieceinf.cpp b/common/pieceinf.cpp index 8d0ca77f..24bd99ef 100644 --- a/common/pieceinf.cpp +++ b/common/pieceinf.cpp @@ -276,31 +276,20 @@ bool PieceInfo::BoxTest(const lcMatrix44& WorldMatrix, const lcVector4 WorldPlan return false; } -// Zoom extents for the preview window and print catalog -void PieceInfo::ZoomExtents(const lcMatrix44& ProjectionMatrix, lcMatrix44& ViewMatrix, float* EyePos) const +void PieceInfo::ZoomExtents(float FoV, float AspectRatio, lcMatrix44& ProjectionMatrix, lcMatrix44& ViewMatrix) const { lcVector3 Points[8]; lcGetBoxCorners(mBoundingBox, Points); lcVector3 Center = (mBoundingBox.Min + mBoundingBox.Max) / 2.0f; - lcVector3 Position; - - if (EyePos) - Position = lcVector3(EyePos[0], EyePos[1], EyePos[2]); - else - Position = lcVector3(-250.0f, -250.0f, 75.0f); - Position += Center; + lcVector3 Position = Center + lcVector3(100.0f, -100.0f, 75.0f); + ProjectionMatrix = lcMatrix44Perspective(FoV, AspectRatio, 1.0f, 12500.0f); lcMatrix44 ModelView = lcMatrix44LookAt(Position, Center, lcVector3(0, 0, 1)); - Position = lcZoomExtents(Position, ModelView, ProjectionMatrix, Points, 8); + float FarDistance; + std::tie(Position, FarDistance) = lcZoomExtents(Position, ModelView, ProjectionMatrix, Points, 8); ViewMatrix = lcMatrix44LookAt(Position, Center, lcVector3(0, 0, 1)); - - if (EyePos) - { - EyePos[0] = Position[0]; - EyePos[1] = Position[1]; - EyePos[2] = Position[2]; - } + ProjectionMatrix = lcMatrix44Perspective(FoV, AspectRatio, 1.0f, FarDistance); } void PieceInfo::AddRenderMesh(lcScene& Scene) diff --git a/common/pieceinf.h b/common/pieceinf.h index e6f3cc52..33d5d51d 100644 --- a/common/pieceinf.h +++ b/common/pieceinf.h @@ -129,7 +129,7 @@ public: return (m_strDescription[0] == '~'); } - void ZoomExtents(const lcMatrix44& ProjectionMatrix, lcMatrix44& ViewMatrix, float* EyePos = nullptr) const; + void ZoomExtents(float FoV, float AspectRatio, lcMatrix44& ProjectionMatrix, lcMatrix44& ViewMatrix) const; void AddRenderMesh(lcScene& Scene); void AddRenderMeshes(lcScene& Scene, const lcMatrix44& WorldMatrix, int ColorIndex, bool Focused, bool Selected, bool Highlight) const; diff --git a/common/project.cpp b/common/project.cpp index cf19a179..679797e3 100644 --- a/common/project.cpp +++ b/common/project.cpp @@ -1866,17 +1866,15 @@ void Project::ExportHTML(const lcHTMLExportOptions& Options) return; } - float aspect = (float)Width / (float)Height; + float AspectRatio = (float)Width / (float)Height; Context->SetViewport(0, 0, Width, Height); lcPartsList PartsList; Model->GetPartsList(gDefaultColor, true, PartsList); - lcMatrix44 ProjectionMatrix = lcMatrix44Perspective(30.0f, aspect, 1.0f, 2500.0f); - lcMatrix44 ViewMatrix; + lcMatrix44 ProjectionMatrix, ViewMatrix; Context->SetDefaultState(); - Context->SetProjectionMatrix(ProjectionMatrix); for (const auto& PartIt : PartsList) { @@ -1885,8 +1883,9 @@ void Project::ExportHTML(const lcHTMLExportOptions& Options) glClearColor(1.0f, 1.0f, 1.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - lcVector3 CameraPosition(-100.0f, -100.0f, 75.0f); - Info->ZoomExtents(ProjectionMatrix, ViewMatrix, CameraPosition); + Info->ZoomExtents(30.0f, AspectRatio, ProjectionMatrix, ViewMatrix); + + Context->SetProjectionMatrix(ProjectionMatrix); lcScene Scene; Scene.Begin(ViewMatrix);