From ed29dad76a59f41b8ab0f666642027e1c51772af Mon Sep 17 00:00:00 2001 From: Leonardo Zide Date: Sat, 2 Nov 2024 19:34:22 -0700 Subject: [PATCH] Added train track gizmo. --- common/lc_library.cpp | 3 + common/lc_model.cpp | 4 +- common/lc_model.h | 2 +- common/lc_traintrack.cpp | 113 ++++++++++++++++++++++++++++++++++ common/lc_traintrack.h | 44 +++++++++++++ common/lc_view.cpp | 94 +++++++++++++++++++++------- common/lc_view.h | 5 ++ common/lc_viewmanipulator.cpp | 86 +++++++++++++++++++++++++- common/lc_viewmanipulator.h | 4 +- common/pieceinf.cpp | 8 +-- common/pieceinf.h | 24 ++++++-- leocad.pro | 2 + 12 files changed, 349 insertions(+), 40 deletions(-) create mode 100644 common/lc_traintrack.cpp create mode 100644 common/lc_traintrack.h diff --git a/common/lc_library.cpp b/common/lc_library.cpp index 96e977dc..9d0bfe04 100644 --- a/common/lc_library.cpp +++ b/common/lc_library.cpp @@ -11,6 +11,7 @@ #include "lc_context.h" #include "lc_glextensions.h" #include "lc_synth.h" +#include "lc_traintrack.h" #include "project.h" #include "lc_profile.h" #include "lc_meshloader.h" @@ -277,6 +278,7 @@ bool lcPiecesLibrary::Load(const QString& LibraryPath, bool ShowProgress) UpdateStudStyleSource(); lcLoadDefaultCategories(); lcSynthInit(); + lcTrainTrackInit(this); return true; } @@ -1870,6 +1872,7 @@ bool lcPiecesLibrary::LoadBuiltinPieces() lcLoadDefaultColors(lcStudStyle::Plain); lcLoadDefaultCategories(true); lcSynthInit(); + lcTrainTrackInit(this); return true; } diff --git a/common/lc_model.cpp b/common/lc_model.cpp index f65f247e..a6314915 100644 --- a/common/lc_model.cpp +++ b/common/lc_model.cpp @@ -4233,9 +4233,9 @@ void lcModel::EndMouseTool(lcTool Tool, bool Accept) } } -void lcModel::InsertPieceToolClicked(const lcMatrix44& WorldMatrix) +void lcModel::InsertPieceToolClicked(PieceInfo* Info, const lcMatrix44& WorldMatrix) { - lcPiece* Piece = new lcPiece(gMainWindow->GetCurrentPieceInfo()); + lcPiece* Piece = new lcPiece(Info); Piece->Initialize(WorldMatrix, mCurrentStep); Piece->SetColorIndex(gMainWindow->mColorIndex); Piece->UpdatePosition(mCurrentStep); diff --git a/common/lc_model.h b/common/lc_model.h index fed286d5..ca52a8de 100644 --- a/common/lc_model.h +++ b/common/lc_model.h @@ -328,7 +328,7 @@ public: void BeginMouseTool(); void EndMouseTool(lcTool Tool, bool Accept); - void InsertPieceToolClicked(const lcMatrix44& WorldMatrix); + void InsertPieceToolClicked(PieceInfo* Info, const lcMatrix44& WorldMatrix); void InsertLightToolClicked(const lcVector3& Position, lcLightType LightType); void BeginCameraTool(const lcVector3& Position, const lcVector3& Target); void UpdateCameraTool(const lcVector3& Position); diff --git a/common/lc_traintrack.cpp b/common/lc_traintrack.cpp new file mode 100644 index 00000000..6a7246dc --- /dev/null +++ b/common/lc_traintrack.cpp @@ -0,0 +1,113 @@ +#include "lc_global.h" +#include "lc_traintrack.h" +#include "lc_library.h" +#include "pieceinf.h" +#include "piece.h" +#include "lc_application.h" + +// todo: +// add cross 32087.dat and auto replace when going over a straight section +// draw icon on thumbnails +// detect existing connections +// new gizmo mesh +// move config to json +// add other track types + +std::pair lcTrainTrackInfo::GetPieceInsertPosition(lcPiece* Piece, quint32 ConnectionIndex, lcTrainTrackType TrainTrackType) const +{ + if (ConnectionIndex >= mConnections.size()) + return { nullptr, lcMatrix44Identity() }; + + const char* PieceNames[] = + { + "74746.dat", + "74747.dat", + "74747.dat", + "2861c04.dat", + "2859c04.dat" + }; + + PieceInfo* Info = lcGetPiecesLibrary()->FindPiece(PieceNames[static_cast(TrainTrackType)], nullptr, false, false); + + if (!Info) + return { nullptr, lcMatrix44Identity() }; + + lcTrainTrackInfo* TrainTrackInfo = Info->GetTrainTrackInfo(); + + if (!TrainTrackInfo || TrainTrackInfo->mConnections.empty()) + return { nullptr, lcMatrix44Identity() }; + + lcMatrix44 Transform; + + if (TrainTrackType != lcTrainTrackType::Left) + Transform = TrainTrackInfo->mConnections[0].Transform; + else + { + Transform = lcMatrix44AffineInverse(TrainTrackInfo->mConnections[0].Transform); + Transform = lcMul(Transform, lcMatrix44RotationZ(LC_PI)); + } + + Transform = lcMul(Transform, mConnections[ConnectionIndex].Transform); + Transform = lcMul(Transform, Piece->mModelWorld); + + return { Info, Transform }; +} + +void lcTrainTrackInit(lcPiecesLibrary* Library) +{ + PieceInfo* Info = Library->FindPiece("74746.dat", nullptr, false, false); + + if (Info) + { + lcTrainTrackInfo* TrainTrackInfo = new lcTrainTrackInfo(); + + TrainTrackInfo->AddConnection({lcMatrix44Translation(lcVector3(160.0f, 0.0f, 0.0f))}); + TrainTrackInfo->AddConnection({lcMatrix44(lcMatrix33RotationZ(LC_PI), lcVector3(-160.0f, 0.0f, 0.0f))}); + + Info->SetTrainTrackInfo(TrainTrackInfo); + } + + Info = Library->FindPiece("74747.dat", nullptr, false, false); + + if (Info) + { + lcTrainTrackInfo* TrainTrackInfo = new lcTrainTrackInfo(); + + const float CurveX = sinf(LC_DTOR * 11.25f) * 800.0f; + const float CurveY = (cosf(LC_DTOR * 11.25f) * 800.0f) - 800.0f; + + TrainTrackInfo->AddConnection({lcMatrix44(lcMatrix33RotationZ(-11.25f * LC_DTOR), lcVector3(CurveX, CurveY, 0.0f))}); + TrainTrackInfo->AddConnection({lcMatrix44(lcMatrix33RotationZ(-168.75f * LC_DTOR), lcVector3(-CurveX, CurveY, 0.0f))}); + + Info->SetTrainTrackInfo(TrainTrackInfo); + } + + const float BranchX = 320.0f + 320.0f + (-(sinf(LC_DTOR * 22.5f) * 800.0f)); + const float BranchY = 320.0f + ((cosf(LC_DTOR * 22.5f) * 800.0f) - 800.0f); + + Info = Library->FindPiece("2861c04.dat", nullptr, false, false); + + if (Info) + { + lcTrainTrackInfo* TrainTrackInfo = new lcTrainTrackInfo(); + + TrainTrackInfo->AddConnection({lcMatrix44Translation(lcVector3(320.0f, 0.0f, 0.0f))}); + TrainTrackInfo->AddConnection({lcMatrix44(lcMatrix33RotationZ(22.5f * LC_DTOR), lcVector3(BranchX, BranchY, 0.0f))}); + TrainTrackInfo->AddConnection({lcMatrix44(lcMatrix33RotationZ(LC_PI), lcVector3(-320.0f, 0.0f, 0.0f))}); + + Info->SetTrainTrackInfo(TrainTrackInfo); + } + + Info = Library->FindPiece("2859c04.dat", nullptr, false, false); + + if (Info) + { + lcTrainTrackInfo* TrainTrackInfo = new lcTrainTrackInfo(); + + TrainTrackInfo->AddConnection({lcMatrix44Translation(lcVector3(320.0f, 0.0f, 0.0f))}); + TrainTrackInfo->AddConnection({lcMatrix44(lcMatrix33RotationZ(-22.5f * LC_DTOR), lcVector3(BranchX, -BranchY, 0.0f))}); + TrainTrackInfo->AddConnection({lcMatrix44(lcMatrix33RotationZ(LC_PI), lcVector3(-320.0f, 0.0f, 0.0f))}); + + Info->SetTrainTrackInfo(TrainTrackInfo); + } +} diff --git a/common/lc_traintrack.h b/common/lc_traintrack.h new file mode 100644 index 00000000..7a12d86d --- /dev/null +++ b/common/lc_traintrack.h @@ -0,0 +1,44 @@ +#pragma once + +#include "lc_math.h" + +class lcPiece; +class lcPiecesLibrary; + +struct lcTrainTrackConnection +{ + lcMatrix44 Transform; +}; + +enum class lcTrainTrackType +{ + Straight, + Left, + Right, + BranchLeft, + BranchRight, + Count +}; + +class lcTrainTrackInfo +{ +public: + lcTrainTrackInfo() = default; + + std::pair GetPieceInsertPosition(lcPiece* Piece, quint32 ConnectionIndex, lcTrainTrackType TrainTrackType) const; + + void AddConnection(const lcTrainTrackConnection& TrainTrackConnection) + { + mConnections.emplace_back(TrainTrackConnection); + } + + const std::vector& GetConnections() const + { + return mConnections; + } + +protected: + std::vector mConnections; +}; + +void lcTrainTrackInit(lcPiecesLibrary* Library); diff --git a/common/lc_view.cpp b/common/lc_view.cpp index 375d5ad5..189b2df9 100644 --- a/common/lc_view.cpp +++ b/common/lc_view.cpp @@ -10,11 +10,13 @@ #include "piece.h" #include "pieceinf.h" #include "lc_synth.h" +#include "lc_traintrack.h" #include "lc_scene.h" #include "lc_context.h" #include "lc_viewmanipulator.h" #include "lc_viewsphere.h" #include "lc_findreplacewidget.h" +#include "lc_library.h" lcFindReplaceParams lcView::mFindReplaceParams; QPointer lcView::mFindWidget; @@ -48,6 +50,13 @@ lcView::lcView(lcViewType ViewType, lcModel* Model) lcView::~lcView() { + if (mPiecePreviewInfo) + { + lcPiecesLibrary* Library = lcGetPiecesLibrary(); + Library->ReleasePieceInfo(mPiecePreviewInfo); + mPiecePreviewInfo = nullptr; + } + mContext->DestroyVertexBuffer(mGridBuffer); if (gMainWindow && mViewType == lcViewType::View) @@ -410,6 +419,55 @@ lcVector3 lcView::GetMoveDirection(const lcVector3& Direction) const return axis; } +void lcView::UpdatePiecePreview() +{ + lcModel* ActiveModel = GetActiveModel(); + lcObject* Focus = ActiveModel->GetFocusObject(); + PieceInfo* PreviewInfo = nullptr; + lcMatrix44 PreviewTransform; + + if (Focus && Focus->IsPiece()) + { + lcPiece* Piece = (lcPiece*)Focus; + + const lcTrainTrackInfo* TrainTrackInfo = Piece->mPieceInfo->GetTrainTrackInfo(); + + if (TrainTrackInfo) + { + quint32 ConnectionIndex = mTrackToolSection & 0xff; + lcTrainTrackType TrainTrackType = static_cast((mTrackToolSection >> 8) & 0xff); + + std::tie(PreviewInfo, mPiecePreviewTransform) = TrainTrackInfo->GetPieceInsertPosition(Piece, ConnectionIndex, TrainTrackType); + } + } + + if (!PreviewInfo) + { + PreviewInfo = gMainWindow->GetCurrentPieceInfo(); + + if (PreviewInfo) + { + mPiecePreviewTransform = GetPieceInsertPosition(false, PreviewInfo); + + if (GetActiveModel() != mModel) + mPiecePreviewTransform = lcMul(mPiecePreviewTransform, mActiveSubmodelTransform); + } + } + + if (PreviewInfo != mPiecePreviewInfo) + { + lcPiecesLibrary* Library = lcGetPiecesLibrary(); + + if (mPiecePreviewInfo) + Library->ReleasePieceInfo(mPiecePreviewInfo); + + mPiecePreviewInfo = PreviewInfo; + + if (mPiecePreviewInfo) + Library->LoadPieceInfo(mPiecePreviewInfo, true, true); + } +} + lcMatrix44 lcView::GetPieceInsertPosition(bool IgnoreSelected, PieceInfo* Info) const { lcModel* ActiveModel = GetActiveModel(); @@ -812,16 +870,11 @@ void lcView::OnDraw() if (DrawInterface && mTrackTool == lcTrackTool::Insert) { - PieceInfo* Info = gMainWindow->GetCurrentPieceInfo(); + UpdatePiecePreview(); - if (Info) + if (mPiecePreviewInfo) { - lcMatrix44 WorldMatrix = GetPieceInsertPosition(false, Info); - - if (GetActiveModel() != mModel) - WorldMatrix = lcMul(WorldMatrix, mActiveSubmodelTransform); - - Info->AddRenderMeshes(mScene.get(), WorldMatrix, gMainWindow->mColorIndex, lcRenderMeshState::Focused, false); + mPiecePreviewInfo->AddRenderMeshes(mScene.get(), mPiecePreviewTransform, gMainWindow->mColorIndex, lcRenderMeshState::Focused, false); } } @@ -1389,18 +1442,14 @@ void lcView::DrawGrid() if (mTrackTool == lcTrackTool::Insert) { - PieceInfo* CurPiece = gMainWindow->GetCurrentPieceInfo(); - - if (CurPiece) + if (mPiecePreviewInfo) { lcVector3 Points[8]; - lcGetBoxCorners(CurPiece->GetBoundingBox(), Points); - - lcMatrix44 WorldMatrix = GetPieceInsertPosition(false, CurPiece); + lcGetBoxCorners(mPiecePreviewInfo->GetBoundingBox(), Points); for (int i = 0; i < 8; i++) { - lcVector3 Point = lcMul31(Points[i], WorldMatrix); + lcVector3 Point = lcMul31(Points[i], mPiecePreviewTransform); Min = lcMin(Point, Min); Max = lcMax(Point, Max); @@ -1654,8 +1703,9 @@ void lcView::EndDrag(bool Accept) case lcDragState::Piece: { PieceInfo* Info = gMainWindow->GetCurrentPieceInfo(); + if (Info) - ActiveModel->InsertPieceToolClicked(GetPieceInsertPosition(false, Info)); + ActiveModel->InsertPieceToolClicked(Info, GetPieceInsertPosition(false, Info)); } break; case lcDragState::Color: @@ -2012,6 +2062,7 @@ void lcView::UpdateTrackTool() lcTool CurrentTool = gMainWindow->GetTool(); lcTrackTool NewTrackTool = mTrackTool; + quint32 NewTrackSection = ~0U; int x = mMouseX; int y = mMouseY; bool Redraw = false; @@ -2048,9 +2099,10 @@ void lcView::UpdateTrackTool() case lcTool::Move: { mMouseDownPiece = nullptr; - NewTrackTool = mViewManipulator->UpdateSelectMove(); + std::tie(NewTrackTool, NewTrackSection) = mViewManipulator->UpdateSelectMove(); mTrackToolFromOverlay = NewTrackTool != lcTrackTool::MoveXYZ && NewTrackTool != lcTrackTool::Select; - Redraw = NewTrackTool != mTrackTool; + Redraw = NewTrackTool != mTrackTool || NewTrackSection != mTrackToolSection; + mTrackToolSection = NewTrackSection; if (CurrentTool == lcTool::Select && NewTrackTool == lcTrackTool::Select && mMouseModifiers == Qt::NoModifier) { @@ -2433,12 +2485,12 @@ void lcView::OnButtonDown(lcTrackButton TrackButton) case lcTrackTool::Insert: { - PieceInfo* CurPiece = gMainWindow->GetCurrentPieceInfo(); + UpdatePiecePreview(); - if (!CurPiece) + if (!mPiecePreviewInfo) break; - ActiveModel->InsertPieceToolClicked(GetPieceInsertPosition(false, gMainWindow->GetCurrentPieceInfo())); + ActiveModel->InsertPieceToolClicked(mPiecePreviewInfo, mPiecePreviewTransform); if ((mMouseModifiers & Qt::ControlModifier) == 0) gMainWindow->SetTool(lcTool::Select); diff --git a/common/lc_view.h b/common/lc_view.h index ee8073d1..6463e096 100644 --- a/common/lc_view.h +++ b/common/lc_view.h @@ -259,6 +259,7 @@ public: float GetOverlayScale() const; lcVector3 GetMoveDirection(const lcVector3& Direction) const; + void UpdatePiecePreview(); lcMatrix44 GetPieceInsertPosition(bool IgnoreSelected, PieceInfo* Info) const; lcVector3 GetCameraLightInsertPosition() const; void GetRayUnderPointer(lcVector3& Start, lcVector3& End) const; @@ -327,6 +328,7 @@ protected: lcDragState mDragState; bool mTrackToolFromOverlay; + quint32 mTrackToolSection = ~0U; lcVector3 mMouseDownPosition; PieceInfo* mMouseDownPiece; int mPanX = 0; @@ -347,6 +349,9 @@ protected: lcCamera* mCamera = nullptr; + PieceInfo* mPiecePreviewInfo = nullptr; + lcMatrix44 mPiecePreviewTransform; + lcVertexBuffer mGridBuffer; int mGridSettings[7]; diff --git a/common/lc_viewmanipulator.cpp b/common/lc_viewmanipulator.cpp index 1d7bcaa0..b646c8b6 100644 --- a/common/lc_viewmanipulator.cpp +++ b/common/lc_viewmanipulator.cpp @@ -7,6 +7,7 @@ #include "camera.h" #include "pieceinf.h" #include "lc_synth.h" +#include "lc_traintrack.h" #include "lc_mainwindow.h" #include "texfont.h" @@ -358,11 +359,49 @@ void lcViewManipulator::DrawSelectMove(lcTrackButton TrackButton, lcTrackTool Tr Context->DrawPrimitives(GL_TRIANGLE_STRIP, 2, 18); Context->DrawPrimitives(GL_TRIANGLE_STRIP, 20, 18); } + else if (Piece->mPieceInfo->GetTrainTrackInfo()) + { + DrawTrainTrack(Piece, Context, OverlayScale); + } } Context->EnableDepthTest(true); } +void lcViewManipulator::DrawTrainTrack(lcPiece* Piece, lcContext* Context, float OverlayScale) +{ + const lcTrainTrackInfo* TrainTrackInfo = Piece->mPieceInfo->GetTrainTrackInfo(); + + for (const lcTrainTrackConnection& TrainTrackConnection : TrainTrackInfo->GetConnections()) + { + lcVector3 Verts[static_cast(lcTrainTrackType::Count) * 2]; + int NumVerts = 0; + + Verts[NumVerts++] = TrainTrackConnection.Transform.GetTranslation() / OverlayScale; + Verts[NumVerts++] = (TrainTrackConnection.Transform.GetTranslation() + lcVector3(TrainTrackConnection.Transform[0]) * 100) / OverlayScale; + + Verts[NumVerts++] = TrainTrackConnection.Transform.GetTranslation() / OverlayScale; + Verts[NumVerts++] = (TrainTrackConnection.Transform.GetTranslation() + lcMul31(lcVector3(TrainTrackConnection.Transform[0]), lcMatrix44RotationZ(LC_DTOR * 60)) * 100) / OverlayScale; + + Verts[NumVerts++] = TrainTrackConnection.Transform.GetTranslation() / OverlayScale; + Verts[NumVerts++] = (TrainTrackConnection.Transform.GetTranslation() + lcMul31(lcVector3(TrainTrackConnection.Transform[0]), lcMatrix44RotationZ(LC_DTOR * -60)) * 100) / OverlayScale; + + Verts[NumVerts++] = TrainTrackConnection.Transform.GetTranslation() / OverlayScale; + Verts[NumVerts++] = (TrainTrackConnection.Transform.GetTranslation() + lcMul31(lcVector3(TrainTrackConnection.Transform[0]), lcMatrix44RotationZ(LC_DTOR * 30)) * 100) / OverlayScale; + + Verts[NumVerts++] = TrainTrackConnection.Transform.GetTranslation() / OverlayScale; + Verts[NumVerts++] = (TrainTrackConnection.Transform.GetTranslation() + lcMul31(lcVector3(TrainTrackConnection.Transform[0]), lcMatrix44RotationZ(LC_DTOR * -30)) * 100) / OverlayScale; + + Context->SetColor(1.0f, 1.0f, 1.0f, 1.0f); + + Context->SetVertexBufferPointer(Verts); + Context->ClearIndexBuffer(); + Context->SetVertexFormatPosition(3); + + Context->DrawPrimitives(GL_LINES, 0, NumVerts); + } +} + void lcViewManipulator::DrawRotate(lcTrackButton TrackButton, lcTrackTool TrackTool) { const lcCamera* Camera = mView->GetCamera(); @@ -740,7 +779,7 @@ bool lcViewManipulator::IsTrackToolAllowed(lcTrackTool TrackTool, quint32 Allowe return false; } -lcTrackTool lcViewManipulator::UpdateSelectMove() +std::pair lcViewManipulator::UpdateSelectMove() { lcModel* ActiveModel = mView->GetActiveModel(); const float OverlayScale = mView->GetOverlayScale(); @@ -753,12 +792,13 @@ lcTrackTool lcViewManipulator::UpdateSelectMove() lcTool CurrentTool = gMainWindow->GetTool(); lcTrackTool NewTrackTool = (CurrentTool == lcTool::Move) ? lcTrackTool::MoveXYZ : lcTrackTool::Select; + quint32 NewTrackSection = ~0U; lcVector3 OverlayCenter; lcMatrix33 RelativeRotation; if (!ActiveModel->GetMoveRotateTransform(OverlayCenter, RelativeRotation)) - return NewTrackTool; + return { NewTrackTool, NewTrackSection }; lcMatrix44 WorldMatrix = lcMatrix44(RelativeRotation, OverlayCenter); @@ -786,6 +826,7 @@ lcTrackTool lcViewManipulator::UpdateSelectMove() lcObject* Focus = ActiveModel->GetFocusObject(); int ControlPointIndex = -1; + if (Focus && Focus->IsPiece()) { lcPiece* Piece = (lcPiece*)Focus; @@ -908,7 +949,46 @@ lcTrackTool lcViewManipulator::UpdateSelectMove() } } - return NewTrackTool; + if (Focus && Focus->IsPiece()) + { + const lcPiece* Piece = (lcPiece*)Focus; + const lcTrainTrackInfo* TrainTrackInfo = Piece->mPieceInfo->GetTrainTrackInfo(); + + if (TrainTrackInfo) + { + for (quint32 Section = 0; Section < TrainTrackInfo->GetConnections().size(); Section++) + { + const lcTrainTrackConnection& TrainTrackConnection = TrainTrackInfo->GetConnections()[Section]; + lcVector3 Verts[static_cast(lcTrainTrackType::Count)]; + int NumVerts = 0; + + Verts[NumVerts++] = (TrainTrackConnection.Transform.GetTranslation() + lcVector3(TrainTrackConnection.Transform[0]) * 100) / 1; + Verts[NumVerts++] = (TrainTrackConnection.Transform.GetTranslation() + lcMul31(lcVector3(TrainTrackConnection.Transform[0]), lcMatrix44RotationZ(LC_DTOR * 60)) * 100) / 1; + Verts[NumVerts++] = (TrainTrackConnection.Transform.GetTranslation() + lcMul31(lcVector3(TrainTrackConnection.Transform[0]), lcMatrix44RotationZ(LC_DTOR * -60)) * 100) / 1; + Verts[NumVerts++] = (TrainTrackConnection.Transform.GetTranslation() + lcMul31(lcVector3(TrainTrackConnection.Transform[0]), lcMatrix44RotationZ(LC_DTOR * 30)) * 100) / 1; + Verts[NumVerts++] = (TrainTrackConnection.Transform.GetTranslation() + lcMul31(lcVector3(TrainTrackConnection.Transform[0]), lcMatrix44RotationZ(LC_DTOR * -30)) * 100) / 1; + + for (int VertexIndex = 0; VertexIndex < NumVerts; VertexIndex++) + { + Verts[VertexIndex] = lcMul31(Verts[VertexIndex], WorldMatrix); + + float IntersectionDistance = lcRayPointDistance(Verts[VertexIndex], Start, End); + + if (IntersectionDistance < 40) + { + if (IntersectionDistance > ClosestIntersectionDistance) + continue; + + NewTrackTool = lcTrackTool::Insert; + ClosestIntersectionDistance = IntersectionDistance; + NewTrackSection = Section | (VertexIndex << 8); + } + } + } + } + } + + return { NewTrackTool, NewTrackSection }; } lcTrackTool lcViewManipulator::UpdateRotate() diff --git a/common/lc_viewmanipulator.h b/common/lc_viewmanipulator.h index 2363f180..28c8f84a 100644 --- a/common/lc_viewmanipulator.h +++ b/common/lc_viewmanipulator.h @@ -10,13 +10,15 @@ public: void DrawSelectMove(lcTrackButton TrackButton, lcTrackTool TrackTool); void DrawRotate(lcTrackButton TrackButton, lcTrackTool TrackTool); - lcTrackTool UpdateSelectMove(); + std::pair UpdateSelectMove(); lcTrackTool UpdateRotate(); static void CreateResources(lcContext* Context); static void DestroyResources(lcContext* Context); protected: + void DrawTrainTrack(lcPiece* Piece, lcContext* Context, float OverlayScale); + static bool IsTrackToolAllowed(lcTrackTool TrackTool, quint32 AllowedTransforms); lcView* mView = nullptr; diff --git a/common/pieceinf.cpp b/common/pieceinf.cpp index d3b95329..7fdf5213 100644 --- a/common/pieceinf.cpp +++ b/common/pieceinf.cpp @@ -11,6 +11,7 @@ #include "project.h" #include "lc_scene.h" #include "lc_synth.h" +#include "lc_traintrack.h" #include "lc_file.h" #include @@ -21,12 +22,6 @@ PieceInfo::PieceInfo() mFolderType = -1; mFolderIndex = -1; mState = lcPieceInfoState::Unloaded; - mRefCount = 0; - mType = lcPieceInfoType::Part; - mMesh = nullptr; - mModel = nullptr; - mProject = nullptr; - mSynthInfo = nullptr; mFileName[0] = 0; m_strDescription[0] = 0; } @@ -34,6 +29,7 @@ PieceInfo::PieceInfo() PieceInfo::~PieceInfo() { delete mSynthInfo; + delete mTrainTrackInfo; if (mState == lcPieceInfoState::Loaded) Unload(); diff --git a/common/pieceinf.h b/common/pieceinf.h index 917b36b8..f3478a5f 100644 --- a/common/pieceinf.h +++ b/common/pieceinf.h @@ -29,6 +29,7 @@ struct lcModelPartsEntry }; class lcSynthInfo; +class lcTrainTrackInfo; enum class lcZipFileType; class PieceInfo @@ -63,6 +64,16 @@ public: mSynthInfo = SynthInfo; } + lcTrainTrackInfo* GetTrainTrackInfo() const + { + return mTrainTrackInfo; + } + + void SetTrainTrackInfo(lcTrainTrackInfo* TrainTrackInfo) + { + mTrainTrackInfo = TrainTrackInfo; + } + lcMesh* GetMesh() const { return mMesh; @@ -192,12 +203,13 @@ public: protected: void ReleaseMesh(); - int mRefCount; - lcPieceInfoType mType; - lcModel* mModel; - Project* mProject; - lcMesh* mMesh; + int mRefCount = 0; + lcPieceInfoType mType = lcPieceInfoType::Part; + lcModel* mModel = nullptr; + Project* mProject = nullptr; + lcMesh* mMesh = nullptr; lcBoundingBox mBoundingBox; - lcSynthInfo* mSynthInfo; + lcSynthInfo* mSynthInfo = nullptr; + lcTrainTrackInfo* mTrainTrackInfo = nullptr; }; diff --git a/leocad.pro b/leocad.pro index 6aac24a6..9d14dab8 100644 --- a/leocad.pro +++ b/leocad.pro @@ -219,6 +219,7 @@ SOURCES += \ common/lc_texture.cpp \ common/lc_thumbnailmanager.cpp \ common/lc_timelinewidget.cpp \ + common/lc_traintrack.cpp \ common/lc_view.cpp \ common/lc_viewmanipulator.cpp \ common/lc_viewsphere.cpp \ @@ -292,6 +293,7 @@ HEADERS += \ common/lc_texture.h \ common/lc_thumbnailmanager.h \ common/lc_timelinewidget.h \ + common/lc_traintrack.h \ common/lc_view.h \ common/lc_viewmanipulator.h \ common/lc_viewsphere.h \