From b30ffd1b59e4c23cb71cec6dc233b6286307266c Mon Sep 17 00:00:00 2001 From: Leonardo Zide Date: Thu, 29 Mar 2018 10:20:36 -0700 Subject: [PATCH] Initial implementation of in place submodel editing. --- common/lc_colors.cpp | 1 + common/lc_colors.h | 1 + common/lc_commands.cpp | 7 + common/lc_commands.h | 1 + common/lc_context.cpp | 5 +- common/lc_context.h | 2 +- common/lc_mainwindow.cpp | 10 +- common/lc_mesh.h | 1 + common/lc_model.cpp | 49 +++++-- common/lc_model.h | 5 +- common/lc_partselectionwidget.cpp | 2 +- common/lc_scene.cpp | 12 +- common/minifig.cpp | 2 +- common/piece.cpp | 19 ++- common/piece.h | 4 +- common/pieceinf.cpp | 16 ++- common/pieceinf.h | 3 +- common/project.cpp | 4 +- common/view.cpp | 222 ++++++++++++++++++++---------- common/view.h | 19 ++- 20 files changed, 271 insertions(+), 114 deletions(-) diff --git a/common/lc_colors.cpp b/common/lc_colors.cpp index dbb84883..44059b2b 100644 --- a/common/lc_colors.cpp +++ b/common/lc_colors.cpp @@ -13,6 +13,7 @@ lcVector4 gInterfaceColors[LC_NUM_INTERFACECOLORS] = // todo: make the colors co { lcVector4(0.898f, 0.298f, 0.400f, 1.000f), // LC_COLOR_SELECTED lcVector4(0.400f, 0.298f, 0.898f, 1.000f), // LC_COLOR_FOCUSED + lcVector4(0.800f, 0.800f, 0.800f, 1.000f), // LC_COLOR_DISABLED lcVector4(0.500f, 0.800f, 0.500f, 1.000f), // LC_COLOR_CAMERA lcVector4(0.500f, 0.800f, 0.500f, 1.000f), // LC_COLOR_LIGHT lcVector4(0.500f, 0.800f, 0.500f, 0.500f), // LC_COLOR_CONTROL_POINT diff --git a/common/lc_colors.h b/common/lc_colors.h index 7d7325c4..9900abd7 100644 --- a/common/lc_colors.h +++ b/common/lc_colors.h @@ -34,6 +34,7 @@ enum lcInterfaceColor { LC_COLOR_SELECTED, LC_COLOR_FOCUSED, + LC_COLOR_DISABLED, LC_COLOR_CAMERA, LC_COLOR_LIGHT, LC_COLOR_CONTROL_POINT, diff --git a/common/lc_commands.cpp b/common/lc_commands.cpp index 253c8fec..8dfffecc 100644 --- a/common/lc_commands.cpp +++ b/common/lc_commands.cpp @@ -1200,6 +1200,13 @@ lcCommand gCommands[LC_NUM_COMMANDS] = QT_TRANSLATE_NOOP("Status", "Insert the contents of the selected model references into the current model"), QT_TRANSLATE_NOOP("Shortcut", "") }, + // LC_PIECE_EDIT_SELECTED_SUBMODEL + { + QT_TRANSLATE_NOOP("Action", "Piece.EditSelectedSubmodel"), + QT_TRANSLATE_NOOP("Menu", "Edit Selected Submodel"), + QT_TRANSLATE_NOOP("Status", "Edit the currently selected submodel"), + QT_TRANSLATE_NOOP("Shortcut", "") + }, // LC_PIECE_GROUP { QT_TRANSLATE_NOOP("Action", "Piece.Group"), diff --git a/common/lc_commands.h b/common/lc_commands.h index 993772ad..44183e82 100644 --- a/common/lc_commands.h +++ b/common/lc_commands.h @@ -185,6 +185,7 @@ enum lcCommandId LC_PIECE_VIEW_SELECTED_MODEL, LC_PIECE_MOVE_SELECTION_TO_MODEL, LC_PIECE_INLINE_SELECTED_MODELS, + LC_PIECE_EDIT_SELECTED_SUBMODEL, LC_PIECE_GROUP, LC_PIECE_UNGROUP, LC_PIECE_GROUP_ADD, diff --git a/common/lc_context.cpp b/common/lc_context.cpp index 8fb57bf1..d0ae2c45 100644 --- a/common/lc_context.cpp +++ b/common/lc_context.cpp @@ -540,9 +540,10 @@ void lcContext::SetColorIndex(int ColorIndex) SetColor(gColorList[ColorIndex].Value); } -void lcContext::SetColorIndexTinted(int ColorIndex, lcInterfaceColor InterfaceColor) +void lcContext::SetColorIndexTinted(int ColorIndex, lcInterfaceColor InterfaceColor, float Weight) { - SetColor((gColorList[ColorIndex].Value + gInterfaceColors[InterfaceColor]) * 0.5f); + lcVector3 Color(gColorList[ColorIndex].Value * Weight + gInterfaceColors[InterfaceColor] * (1.0f - Weight)); + SetColor(lcVector4(Color, gColorList[ColorIndex].Value.w)); } void lcContext::SetEdgeColorIndex(int ColorIndex) diff --git a/common/lc_context.h b/common/lc_context.h index 7aa2a1ba..ffc57e78 100644 --- a/common/lc_context.h +++ b/common/lc_context.h @@ -150,7 +150,7 @@ public: void SetColor(float Red, float Green, float Blue, float Alpha); void SetColorIndex(int ColorIndex); - void SetColorIndexTinted(int ColorIndex, lcInterfaceColor InterfaceColor); + void SetColorIndexTinted(int ColorIndex, lcInterfaceColor InterfaceColor, float Weight); void SetEdgeColorIndex(int ColorIndex); void SetInterfaceColor(lcInterfaceColor InterfaceColor); diff --git a/common/lc_mainwindow.cpp b/common/lc_mainwindow.cpp index 88f379fa..676639d9 100644 --- a/common/lc_mainwindow.cpp +++ b/common/lc_mainwindow.cpp @@ -50,7 +50,7 @@ void lcModelTabWidget::Clear() ResetLayout(); mModel = nullptr; for (View* View : mViews) - View->mModel = nullptr; + View->Clear(); mViews.RemoveAll(); mActiveView = nullptr; lcQGLWidget* Widget = (lcQGLWidget*)layout()->itemAt(0)->widget(); @@ -518,6 +518,7 @@ void lcMainWindow::CreateMenus() PieceMenu->addAction(mActions[LC_PIECE_VIEW_SELECTED_MODEL]); PieceMenu->addAction(mActions[LC_PIECE_INLINE_SELECTED_MODELS]); PieceMenu->addAction(mActions[LC_PIECE_MOVE_SELECTION_TO_MODEL]); + PieceMenu->addAction(mActions[LC_PIECE_EDIT_SELECTED_SUBMODEL]); PieceMenu->addSeparator(); PieceMenu->addAction(mActions[LC_PIECE_GROUP]); PieceMenu->addAction(mActions[LC_PIECE_UNGROUP]); @@ -1436,7 +1437,7 @@ void lcMainWindow::ResetCameras() void lcMainWindow::AddView(View* View) { - lcModelTabWidget* TabWidget = GetTabWidgetForModel(View->mModel); + lcModelTabWidget* TabWidget = GetTabWidgetForModel(View->GetModel()); if (!TabWidget) return; @@ -1794,6 +1795,7 @@ void lcMainWindow::UpdateSelectedObjects(bool SelectionChanged) mActions[LC_PIECE_VIEW_SELECTED_MODEL]->setEnabled(Flags & LC_SEL_MODEL_SELECTED); mActions[LC_PIECE_MOVE_SELECTION_TO_MODEL]->setEnabled(Flags & LC_SEL_PIECE); mActions[LC_PIECE_INLINE_SELECTED_MODELS]->setEnabled(Flags & LC_SEL_MODEL_SELECTED); + mActions[LC_PIECE_EDIT_SELECTED_SUBMODEL]->setEnabled(Flags & LC_SEL_MODEL_SELECTED); mActions[LC_PIECE_GROUP]->setEnabled(Flags & LC_SEL_CAN_GROUP); mActions[LC_PIECE_UNGROUP]->setEnabled(Flags & LC_SEL_GROUPED); mActions[LC_PIECE_GROUP_ADD]->setEnabled((Flags & (LC_SEL_GROUPED | LC_SEL_FOCUS_GROUPED)) == LC_SEL_GROUPED); @@ -2617,6 +2619,10 @@ void lcMainWindow::HandleCommand(lcCommandId CommandId) lcGetActiveModel()->InlineSelectedModels(); break; + case LC_PIECE_EDIT_SELECTED_SUBMODEL: + GetActiveView()->SetSelectedSubmodelActive(); + break; + case LC_PIECE_GROUP: lcGetActiveModel()->GroupSelection(); break; diff --git a/common/lc_mesh.h b/common/lc_mesh.h index ca1f4b61..3b313677 100644 --- a/common/lc_mesh.h +++ b/common/lc_mesh.h @@ -101,6 +101,7 @@ enum lcRenderMeshState LC_RENDERMESH_NONE, LC_RENDERMESH_SELECTED, LC_RENDERMESH_FOCUSED, + LC_RENDERMESH_DISABLED, LC_RENDERMESH_HIGHLIGHT }; diff --git a/common/lc_model.cpp b/common/lc_model.cpp index f583f01d..bb9bcd0b 100644 --- a/common/lc_model.cpp +++ b/common/lc_model.cpp @@ -175,6 +175,33 @@ lcModel::~lcModel() DeleteHistory(); } +bool lcModel::GetPieceWorldMatrix(lcPiece* Piece, lcMatrix44& ParentWorldMatrix) const +{ + for (lcPiece* ModelPiece : mPieces) + { + if (ModelPiece == Piece) + { + ParentWorldMatrix = lcMul(ModelPiece->mModelWorld, ParentWorldMatrix); + return true; + } + + PieceInfo* Info = ModelPiece->mPieceInfo; + + if (Info->IsModel()) + { + lcMatrix44 WorldMatrix = lcMul(ModelPiece->mModelWorld, ParentWorldMatrix); + + if (Info->GetPieceWorldMatrix(Piece, WorldMatrix)) + { + ParentWorldMatrix = WorldMatrix; + return true; + } + } + } + + return false; +} + bool lcModel::IncludesModel(const lcModel* Model) const { if (Model == this) @@ -1224,21 +1251,17 @@ void lcModel::DuplicateSelectedPieces() SaveCheckpoint(tr("Duplicating Pieces")); } -void lcModel::GetScene(lcScene& Scene, lcCamera* ViewCamera, bool DrawInterface, bool Highlight) const +void lcModel::GetScene(lcScene& Scene, lcCamera* ViewCamera, bool DrawInterface, bool Highlight, lcPiece* ActiveSubmodelInstance) const { Scene.Begin(ViewCamera->mWorldView); mPieceInfo->AddRenderMesh(Scene); - for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++) - { - lcPiece* Piece = mPieces[PieceIdx]; - + for (lcPiece* Piece : mPieces) if (Piece->IsVisible(mCurrentStep)) - Piece->AddRenderMeshes(Scene, DrawInterface, Highlight && Piece->GetStepShow() == mCurrentStep); - } + Piece->AddRenderMeshes(Scene, DrawInterface, Highlight && Piece->GetStepShow() == mCurrentStep, ActiveSubmodelInstance); - if (DrawInterface) + if (DrawInterface && !ActiveSubmodelInstance) { for (int CameraIdx = 0; CameraIdx < mCameras.GetSize(); CameraIdx++) { @@ -1260,15 +1283,11 @@ void lcModel::GetScene(lcScene& Scene, lcCamera* ViewCamera, bool DrawInterface, Scene.End(); } -void lcModel::SubModelAddRenderMeshes(lcScene& Scene, const lcMatrix44& WorldMatrix, int DefaultColorIndex, bool Focused, bool Selected) const +void lcModel::SubModelAddRenderMeshes(lcScene& Scene, const lcMatrix44& WorldMatrix, int DefaultColorIndex, bool Focused, bool Selected, bool Disabled, lcPiece* ActiveSubmodelInstance) const { - for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++) - { - lcPiece* Piece = mPieces[PieceIdx]; - + for (lcPiece* Piece : mPieces) if (Piece->GetStepHide() == LC_STEP_MAX) - Piece->SubModelAddRenderMeshes(Scene, WorldMatrix, DefaultColorIndex, Focused, Selected); - } + Piece->SubModelAddRenderMeshes(Scene, WorldMatrix, DefaultColorIndex, Focused, Selected, Disabled, ActiveSubmodelInstance); } void lcModel::DrawBackground(lcGLWidget* Widget) diff --git a/common/lc_model.h b/common/lc_model.h index 7b6bb9ab..405cd970 100644 --- a/common/lc_model.h +++ b/common/lc_model.h @@ -108,6 +108,7 @@ public: return mSavedHistory != mUndoHistory[0]; } + bool GetPieceWorldMatrix(lcPiece* Piece, lcMatrix44& ParentWorldMatrix) const; bool IncludesModel(const lcModel* Model) const; void CreatePieceInfo(Project* Project); void UpdatePieceInfo(lcArray& UpdatedModels); @@ -231,8 +232,8 @@ public: void Paste(); void DuplicateSelectedPieces(); - void GetScene(lcScene& Scene, lcCamera* ViewCamera, bool DrawInterface, bool Highlight) const; - void SubModelAddRenderMeshes(lcScene& Scene, const lcMatrix44& WorldMatrix, int DefaultColorIndex, bool Focused, bool Selected) const; + void GetScene(lcScene& Scene, lcCamera* ViewCamera, bool DrawInterface, bool Highlight, lcPiece* ActiveSubmodelInstance) const; + void SubModelAddRenderMeshes(lcScene& Scene, const lcMatrix44& WorldMatrix, int DefaultColorIndex, bool Focused, bool Selected, bool Disabled, lcPiece* ActiveSubmodelInstance) const; void DrawBackground(lcGLWidget* Widget); void SaveStepImages(const QString& BaseName, bool AddStepSuffix, bool Zoom, bool Highlight, int Width, int Height, lcStep Start, lcStep End); diff --git a/common/lc_partselectionwidget.cpp b/common/lc_partselectionwidget.cpp index dc686105..7ea7ab8b 100644 --- a/common/lc_partselectionwidget.cpp +++ b/common/lc_partselectionwidget.cpp @@ -370,7 +370,7 @@ void lcPartSelectionListModel::DrawPreview(int InfoIndex) lcScene Scene; Scene.Begin(ViewMatrix); - Info->AddRenderMeshes(Scene, lcMatrix44Identity(), mColorIndex, false, false, false); + Info->AddRenderMeshes(Scene, lcMatrix44Identity(), mColorIndex, false, false, false, false, nullptr); Scene.End(); diff --git a/common/lc_scene.cpp b/common/lc_scene.cpp index 9f99975c..98fb6e01 100644 --- a/common/lc_scene.cpp +++ b/common/lc_scene.cpp @@ -100,11 +100,15 @@ void lcScene::DrawRenderMeshes(lcContext* Context, int PrimitiveTypes, bool Enab break; case LC_RENDERMESH_SELECTED: - Context->SetColorIndexTinted(ColorIndex, LC_COLOR_SELECTED); + Context->SetColorIndexTinted(ColorIndex, LC_COLOR_SELECTED, 0.5f); break; case LC_RENDERMESH_FOCUSED: - Context->SetColorIndexTinted(ColorIndex, LC_COLOR_FOCUSED); + Context->SetColorIndexTinted(ColorIndex, LC_COLOR_FOCUSED, 0.5f); + break; + + case LC_RENDERMESH_DISABLED: + Context->SetColorIndexTinted(ColorIndex, LC_COLOR_DISABLED, 0.25f); break; } } @@ -130,6 +134,10 @@ void lcScene::DrawRenderMeshes(lcContext* Context, int PrimitiveTypes, bool Enab case LC_RENDERMESH_HIGHLIGHT: Context->SetInterfaceColor(LC_COLOR_HIGHLIGHT); break; + + case LC_RENDERMESH_DISABLED: + Context->SetInterfaceColor(LC_COLOR_DISABLED); + break; } } else if (Section->PrimitiveType == LC_MESH_CONDITIONAL_LINES) diff --git a/common/minifig.cpp b/common/minifig.cpp index 489be851..fc2c8ef5 100644 --- a/common/minifig.cpp +++ b/common/minifig.cpp @@ -350,7 +350,7 @@ void MinifigWizard::OnDraw() for (int PieceIdx = 0; PieceIdx < LC_MFW_NUMITEMS; PieceIdx++) if (mMinifig.Parts[PieceIdx]) - mMinifig.Parts[PieceIdx]->AddRenderMeshes(Scene, mMinifig.Matrices[PieceIdx], mMinifig.Colors[PieceIdx], false, false, false); + mMinifig.Parts[PieceIdx]->AddRenderMeshes(Scene, mMinifig.Matrices[PieceIdx], mMinifig.Colors[PieceIdx], false, false, false, false, nullptr); Scene.End(); diff --git a/common/piece.cpp b/common/piece.cpp index 603b5655..fd82c2b9 100644 --- a/common/piece.cpp +++ b/common/piece.cpp @@ -646,31 +646,36 @@ void lcPiece::RemoveKeyFrames() ChangeKey(mRotationKeys, lcMatrix33(mModelWorld), 1, true); } -void lcPiece::AddRenderMeshes(lcScene& Scene, bool DrawInterface, bool Highlight) const +void lcPiece::AddRenderMeshes(lcScene& Scene, bool DrawInterface, bool Highlight, lcPiece* ActiveSubmodelInstance) const { - bool Focused, Selected; + bool Focused, Selected, Disabled; if (DrawInterface) { Focused = IsFocused(); Selected = IsSelected(); + Disabled = ActiveSubmodelInstance && (ActiveSubmodelInstance != this); } else { Focused = false; Selected = false; + Disabled = false; } + if (ActiveSubmodelInstance == this) + ActiveSubmodelInstance = nullptr; + if (!mMesh) - mPieceInfo->AddRenderMeshes(Scene, mModelWorld, mColorIndex, Focused, Selected, Highlight); + mPieceInfo->AddRenderMeshes(Scene, mModelWorld, mColorIndex, Focused, Selected, Disabled, Highlight, ActiveSubmodelInstance); else - Scene.AddMesh(mMesh, mModelWorld, mColorIndex, Focused ? LC_RENDERMESH_FOCUSED : (Selected ? LC_RENDERMESH_SELECTED : LC_RENDERMESH_NONE), mPieceInfo->mFlags); + Scene.AddMesh(mMesh, mModelWorld, mColorIndex, Disabled ? LC_RENDERMESH_DISABLED : (Focused ? LC_RENDERMESH_FOCUSED : (Selected ? LC_RENDERMESH_SELECTED : LC_RENDERMESH_NONE)), mPieceInfo->mFlags); if (Selected) Scene.AddInterfaceObject(this); } -void lcPiece::SubModelAddRenderMeshes(lcScene& Scene, const lcMatrix44& WorldMatrix, int DefaultColorIndex, bool Focused, bool Selected) const +void lcPiece::SubModelAddRenderMeshes(lcScene& Scene, const lcMatrix44& WorldMatrix, int DefaultColorIndex, bool Focused, bool Selected, bool Disabled, lcPiece* ActiveSubmodelInstance) const { int ColorIndex = mColorIndex; @@ -678,9 +683,9 @@ void lcPiece::SubModelAddRenderMeshes(lcScene& Scene, const lcMatrix44& WorldMat ColorIndex = DefaultColorIndex; if (!mMesh) - mPieceInfo->AddRenderMeshes(Scene, lcMul(mModelWorld, WorldMatrix), ColorIndex, Focused, Selected, false); + mPieceInfo->AddRenderMeshes(Scene, lcMul(mModelWorld, WorldMatrix), ColorIndex, Focused, Selected, Disabled, false, ActiveSubmodelInstance); else - Scene.AddMesh(mMesh, lcMul(mModelWorld, WorldMatrix), ColorIndex, Focused ? LC_RENDERMESH_FOCUSED : (Selected ? LC_RENDERMESH_SELECTED : LC_RENDERMESH_NONE), mPieceInfo->mFlags); + Scene.AddMesh(mMesh, lcMul(mModelWorld, WorldMatrix), ColorIndex, Disabled ? LC_RENDERMESH_DISABLED : (Focused ? LC_RENDERMESH_FOCUSED : (Selected ? LC_RENDERMESH_SELECTED : LC_RENDERMESH_NONE)), mPieceInfo->mFlags); } void lcPiece::MoveSelected(lcStep Step, bool AddKey, const lcVector3& Distance) diff --git a/common/piece.h b/common/piece.h index ebed6727..5eddadfd 100644 --- a/common/piece.h +++ b/common/piece.h @@ -346,8 +346,8 @@ public: virtual void DrawInterface(lcContext* Context) const override; virtual void RemoveKeyFrames() override; - void AddRenderMeshes(lcScene& Scene, bool DrawInterface, bool Highlight) const; - void SubModelAddRenderMeshes(lcScene& Scene, const lcMatrix44& WorldMatrix, int DefaultColorIndex, bool Focused, bool Selected) const; + void AddRenderMeshes(lcScene& Scene, bool DrawInterface, bool Highlight, lcPiece* ActiveSubmodelInstance) const; + void SubModelAddRenderMeshes(lcScene& Scene, const lcMatrix44& WorldMatrix, int DefaultColorIndex, bool Focused, bool Selected, bool Disabled, lcPiece* ActiveSubmodelInstance) const; void InsertTime(lcStep Start, lcStep Time); void RemoveTime(lcStep Start, lcStep Time); diff --git a/common/pieceinf.cpp b/common/pieceinf.cpp index 74813b82..d28e1f3d 100644 --- a/common/pieceinf.cpp +++ b/common/pieceinf.cpp @@ -104,6 +104,14 @@ void PieceInfo::CreateProject(Project* Project, const char* PieceName) m_strDescription[sizeof(m_strDescription) - 1] = 0; } +bool PieceInfo::GetPieceWorldMatrix(lcPiece* Piece, lcMatrix44& WorldMatrix) const +{ + if (mFlags & LC_PIECE_MODEL) + return mModel->GetPieceWorldMatrix(Piece, WorldMatrix); + + return false; +} + bool PieceInfo::IncludesModel(const lcModel* Model) const { if (mFlags & LC_PIECE_MODEL) @@ -298,18 +306,18 @@ void PieceInfo::AddRenderMesh(lcScene& Scene) Scene.AddMesh(mMesh, lcMatrix44Identity(), gDefaultColor, LC_RENDERMESH_NONE, mFlags); } -void PieceInfo::AddRenderMeshes(lcScene& Scene, const lcMatrix44& WorldMatrix, int ColorIndex, bool Focused, bool Selected, bool Highlight) const +void PieceInfo::AddRenderMeshes(lcScene& Scene, const lcMatrix44& WorldMatrix, int ColorIndex, bool Focused, bool Selected, bool Disabled, bool Highlight, lcPiece* ActiveSubmodelInstance) const { if ((mMesh) || (mFlags & LC_PIECE_PLACEHOLDER)) - Scene.AddMesh((mFlags & LC_PIECE_PLACEHOLDER) ? gPlaceholderMesh : mMesh, WorldMatrix, ColorIndex, Focused ? LC_RENDERMESH_FOCUSED : (Selected ? LC_RENDERMESH_SELECTED : (Highlight ? LC_RENDERMESH_HIGHLIGHT : LC_RENDERMESH_NONE)), mFlags); + Scene.AddMesh((mFlags & LC_PIECE_PLACEHOLDER) ? gPlaceholderMesh : mMesh, WorldMatrix, ColorIndex, Disabled ? LC_RENDERMESH_DISABLED : (Focused ? LC_RENDERMESH_FOCUSED : (Selected ? LC_RENDERMESH_SELECTED : (Highlight ? LC_RENDERMESH_HIGHLIGHT : LC_RENDERMESH_NONE))), mFlags); if (mFlags & LC_PIECE_MODEL) - mModel->SubModelAddRenderMeshes(Scene, WorldMatrix, ColorIndex, Focused, Selected); + mModel->SubModelAddRenderMeshes(Scene, WorldMatrix, ColorIndex, Focused, Selected, Disabled, ActiveSubmodelInstance); else if (mFlags & LC_PIECE_PROJECT) { lcModel* Model = mProject->GetMainModel(); if (Model) - Model->SubModelAddRenderMeshes(Scene, WorldMatrix, ColorIndex, Focused, Selected); + Model->SubModelAddRenderMeshes(Scene, WorldMatrix, ColorIndex, Focused, Selected, Disabled, ActiveSubmodelInstance); } } diff --git a/common/pieceinf.h b/common/pieceinf.h index d184fd27..14c38b45 100644 --- a/common/pieceinf.h +++ b/common/pieceinf.h @@ -136,13 +136,14 @@ public: 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; + void AddRenderMeshes(lcScene& Scene, const lcMatrix44& WorldMatrix, int ColorIndex, bool Focused, bool Selected, bool Disabled, bool Highlight, lcPiece* ActiveSubmodelInstance) const; void CreatePlaceholder(const char* Name); void SetPlaceholder(); void SetModel(lcModel* Model, bool UpdateMesh, Project* CurrentProject, bool SearchProjectFolder); void CreateProject(Project* Project, const char* PieceName); + bool GetPieceWorldMatrix(lcPiece* Piece, lcMatrix44& WorldMatrix) const; bool IncludesModel(const lcModel* Model) const; bool MinIntersectDist(const lcVector3& Start, const lcVector3& End, float& MinDistance) const; bool BoxTest(const lcMatrix44& WorldMatrix, const lcVector4 Planes[6]) const; diff --git a/common/project.cpp b/common/project.cpp index e5832f1f..88c9229c 100644 --- a/common/project.cpp +++ b/common/project.cpp @@ -1554,7 +1554,7 @@ QImage Project::CreatePartsListImage(lcModel* Model, lcStep Step) lcScene Scene; Scene.Begin(ViewMatrix); - Image.Info->AddRenderMeshes(Scene, lcMatrix44Identity(), Image.ColorIndex, false, false, false); + Image.Info->AddRenderMeshes(Scene, lcMatrix44Identity(), Image.ColorIndex, false, false, false, false, nullptr); Scene.End(); @@ -1942,7 +1942,7 @@ void Project::ExportHTML(const lcHTMLExportOptions& Options) lcScene Scene; Scene.Begin(ViewMatrix); - Info->AddRenderMeshes(Scene, lcMatrix44Identity(), Options.PartImagesColor, false, false, false); + Info->AddRenderMeshes(Scene, lcMatrix44Identity(), Options.PartImagesColor, false, false, false, false, nullptr); Scene.End(); diff --git a/common/view.cpp b/common/view.cpp index 1565ab72..489b763f 100644 --- a/common/view.cpp +++ b/common/view.cpp @@ -15,6 +15,7 @@ lcIndexBuffer View::mRotateMoveIndexBuffer; View::View(lcModel* Model) { mModel = Model; + mActiveSubmodelInstance = nullptr; mCamera = nullptr; mHighlight = false; memset(mGridSettings, 0, sizeof(mGridSettings)); @@ -42,6 +43,41 @@ View::~View() delete mCamera; } +lcModel* View::GetActiveModel() const +{ + return !mActiveSubmodelInstance ? mModel : mActiveSubmodelInstance->mPieceInfo->GetModel(); +} + +void View::SetSelectedSubmodelActive() +{ + if (mActiveSubmodelInstance) + { + lcModel* Model = mActiveSubmodelInstance->mPieceInfo->GetModel(); + Model->SetActive(false); + Model->ClearSelection(true); + mActiveSubmodelInstance = nullptr; + } + + lcModel* ActiveModel = GetActiveModel(); + lcObject* Object = ActiveModel->GetFocusObject(); + + if (Object && Object->IsPiece()) + { + lcPiece* Piece = (lcPiece*)Object; + + if (Piece->mPieceInfo->IsModel()) + { + ActiveModel->ClearSelection(false); + mActiveSubmodelMatrix = lcMatrix44Identity(); + mModel->GetPieceWorldMatrix(Piece, mActiveSubmodelMatrix); + mActiveSubmodelInstance = Piece; + lcModel* Model = mActiveSubmodelInstance->mPieceInfo->GetModel(); + Model->SetActive(true); + Model->ClearSelection(true); + } + } +} + void View::CreateResources(lcContext* Context) { gGridTexture = new lcTexture; @@ -428,6 +464,7 @@ void View::ShowContextMenu() const Popup->addSeparator(); + Popup->addAction(Actions[LC_PIECE_EDIT_SELECTED_SUBMODEL]); Popup->addAction(Actions[LC_PIECE_VIEW_SELECTED_MODEL]); Popup->addAction(Actions[LC_PIECE_INLINE_SELECTED_MODELS]); Popup->addAction(Actions[LC_PIECE_MOVE_SELECTION_TO_MODEL]); @@ -501,15 +538,16 @@ lcVector3 View::GetMoveDirection(const lcVector3& Direction) const lcMatrix44 View::GetPieceInsertPosition(bool IgnoreSelected, PieceInfo* Info) const { lcPiece* HitPiece = (lcPiece*)FindObjectUnderPointer(true, IgnoreSelected).Object; + lcModel* ActiveModel = GetActiveModel(); if (HitPiece) { lcVector3 Position(0, 0, HitPiece->GetBoundingBox().Max.z - Info->GetBoundingBox().Min.z); if (gMainWindow->GetRelativeTransform()) - Position = lcMul31(mModel->SnapPosition(Position), HitPiece->mModelWorld); + Position = lcMul31(ActiveModel->SnapPosition(Position), HitPiece->mModelWorld); else - Position = mModel->SnapPosition(lcMul31(Position, HitPiece->mModelWorld)); + Position = ActiveModel->SnapPosition(lcMul31(Position, HitPiece->mModelWorld)); lcMatrix44 WorldMatrix = HitPiece->mModelWorld; WorldMatrix.SetTranslation(Position); @@ -525,7 +563,7 @@ lcMatrix44 View::GetPieceInsertPosition(bool IgnoreSelected, PieceInfo* Info) co const lcBoundingBox& BoundingBox = Info->GetBoundingBox(); if (lcLineSegmentPlaneIntersection(&Intersection, ClickPoints[0], ClickPoints[1], lcVector4(0, 0, 1, BoundingBox.Min.z))) { - Intersection = mModel->SnapPosition(Intersection); + Intersection = ActiveModel->SnapPosition(Intersection); return lcMatrix44Translation(Intersection); } @@ -567,7 +605,17 @@ lcObjectSection View::FindObjectUnderPointer(bool PiecesOnly, bool IgnoreSelecte ObjectRayTest.ObjectSection.Object = nullptr; ObjectRayTest.ObjectSection.Section = 0;; - mModel->RayTest(ObjectRayTest); + lcModel* ActiveModel = GetActiveModel(); + + if (ActiveModel != mModel) + { + lcMatrix44 InverseMatrix = lcMatrix44AffineInverse(mActiveSubmodelMatrix); + + ObjectRayTest.Start = lcMul31(ObjectRayTest.Start, InverseMatrix); + ObjectRayTest.End = lcMul31(ObjectRayTest.End, InverseMatrix); + } + + ActiveModel->RayTest(ObjectRayTest); return ObjectRayTest.ObjectSection; } @@ -627,7 +675,8 @@ lcArray View::FindObjectsInBox(float x1, float y1, float x2, float y2 ObjectBoxTest.Planes[4] = lcVector4(PlaneNormals[4], -lcDot(PlaneNormals[4], Corners[0])); ObjectBoxTest.Planes[5] = lcVector4(PlaneNormals[5], -lcDot(PlaneNormals[5], Corners[5])); - mModel->BoxTest(ObjectBoxTest); + lcModel* ActiveModel = GetActiveModel(); + ActiveModel->BoxTest(ObjectBoxTest); return ObjectBoxTest.Objects; } @@ -666,14 +715,14 @@ void View::OnDraw() bool DrawInterface = mWidget != nullptr; - mModel->GetScene(mScene, mCamera, DrawInterface, mHighlight); + mModel->GetScene(mScene, mCamera, DrawInterface, mHighlight, mActiveSubmodelInstance); if (DrawInterface && mTrackTool == LC_TRACKTOOL_INSERT) { PieceInfo* Info = gMainWindow->GetCurrentPieceInfo(); if (Info) - Info->AddRenderMeshes(mScene, GetPieceInsertPosition(false, gMainWindow->GetCurrentPieceInfo()), gMainWindow->mColorIndex, true, true, false); + Info->AddRenderMeshes(mScene, GetPieceInsertPosition(false, gMainWindow->GetCurrentPieceInfo()), gMainWindow->mColorIndex, true, true, false, false, nullptr); } int TotalTileRows = 1; @@ -771,12 +820,13 @@ void View::OnDraw() DrawAxes(); lcTool Tool = gMainWindow->GetTool(); + lcModel* ActiveModel = GetActiveModel(); - if ((Tool == LC_TOOL_SELECT || Tool == LC_TOOL_MOVE) && mTrackButton == LC_TRACKBUTTON_NONE && mModel->AnyObjectsSelected()) + if ((Tool == LC_TOOL_SELECT || Tool == LC_TOOL_MOVE) && mTrackButton == LC_TRACKBUTTON_NONE && ActiveModel->AnyObjectsSelected()) DrawSelectMoveOverlay(); else if (GetCurrentTool() == LC_TOOL_MOVE && mTrackButton != LC_TRACKBUTTON_NONE) DrawSelectMoveOverlay(); - else if ((Tool == LC_TOOL_ROTATE || (Tool == LC_TOOL_SELECT && mTrackButton != LC_TRACKBUTTON_NONE && mTrackTool >= LC_TRACKTOOL_ROTATE_X && mTrackTool <= LC_TRACKTOOL_ROTATE_XYZ)) && mModel->AnyPiecesSelected()) + else if ((Tool == LC_TOOL_ROTATE || (Tool == LC_TOOL_SELECT && mTrackButton != LC_TRACKBUTTON_NONE && mTrackTool >= LC_TRACKTOOL_ROTATE_X && mTrackTool <= LC_TRACKTOOL_ROTATE_XYZ)) && ActiveModel->AnyPiecesSelected()) DrawRotateOverlay(); else if ((mTrackTool == LC_TRACKTOOL_SELECT || mTrackTool == LC_TRACKTOOL_ZOOM_REGION) && mTrackButton == LC_TRACKBUTTON_LEFT) DrawSelectZoomRegionOverlay(); @@ -799,11 +849,15 @@ void View::DrawSelectMoveOverlay() lcVector3 OverlayCenter; lcMatrix33 RelativeRotation; - mModel->GetMoveRotateTransform(OverlayCenter, RelativeRotation); - bool AnyPiecesSelected = mModel->AnyPiecesSelected(); + lcModel* ActiveModel = GetActiveModel(); + ActiveModel->GetMoveRotateTransform(OverlayCenter, RelativeRotation); + bool AnyPiecesSelected = ActiveModel->AnyPiecesSelected(); lcMatrix44 WorldMatrix = lcMatrix44(RelativeRotation, OverlayCenter); + if (ActiveModel != mModel) + WorldMatrix = lcMul(WorldMatrix, mActiveSubmodelMatrix); + const float OverlayScale = GetOverlayScale(); WorldMatrix = lcMul(lcMatrix44Scale(lcVector3(OverlayScale, OverlayScale, OverlayScale)), WorldMatrix); @@ -813,7 +867,7 @@ void View::DrawSelectMoveOverlay() mContext->SetVertexBuffer(mRotateMoveVertexBuffer); mContext->SetVertexFormatPosition(3); - lcObject* Focus = mModel->GetFocusObject(); + lcObject* Focus = ActiveModel->GetFocusObject(); quint32 AllowedTransforms = Focus ? Focus->GetAllowedTransforms() : LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Y | LC_OBJECT_TRANSFORM_MOVE_Z | LC_OBJECT_TRANSFORM_ROTATE_X | LC_OBJECT_TRANSFORM_ROTATE_Y | LC_OBJECT_TRANSFORM_ROTATE_Z; if (mTrackButton == LC_TRACKBUTTON_NONE || (mTrackTool >= LC_TRACKTOOL_MOVE_X && mTrackTool <= LC_TRACKTOOL_MOVE_XYZ)) @@ -989,8 +1043,9 @@ void View::DrawRotateOverlay() lcVector3 OverlayCenter; lcMatrix33 RelativeRotation; - mModel->GetMoveRotateTransform(OverlayCenter, RelativeRotation); - lcVector3 MouseToolDistance = mModel->SnapRotation(mModel->GetMouseToolDistance()); + lcModel* ActiveModel = GetActiveModel(); + ActiveModel->GetMoveRotateTransform(OverlayCenter, RelativeRotation); + lcVector3 MouseToolDistance = ActiveModel->SnapRotation(ActiveModel->GetMouseToolDistance()); bool HasAngle = false; // Draw a disc showing the rotation amount. @@ -1783,7 +1838,8 @@ float View::GetOverlayScale() const { lcVector3 OverlayCenter; lcMatrix33 RelativeRotation; - mModel->GetMoveRotateTransform(OverlayCenter, RelativeRotation); + lcModel* ActiveModel = GetActiveModel(); + ActiveModel->GetMoveRotateTransform(OverlayCenter, RelativeRotation); lcVector3 ScreenPos = ProjectPoint(OverlayCenter); ScreenPos[0] += 10.0f; @@ -1803,17 +1859,19 @@ void View::EndDrag(bool Accept) { if (Accept) { + lcModel* ActiveModel = GetActiveModel(); + switch (mDragState) { case lcDragState::NONE: break; case lcDragState::PIECE: - mModel->InsertPieceToolClicked(GetPieceInsertPosition(false, gMainWindow->GetCurrentPieceInfo())); + ActiveModel->InsertPieceToolClicked(GetPieceInsertPosition(false, gMainWindow->GetCurrentPieceInfo())); break; case lcDragState::COLOR: - mModel->PaintToolClicked(FindObjectUnderPointer(true, false).Object); + ActiveModel->PaintToolClicked(FindObjectUnderPointer(true, false).Object); break; } } @@ -1832,22 +1890,32 @@ void View::SetProjection(bool Ortho) gMainWindow->UpdatePerspective(); } else - mModel->SetCameraOrthographic(mCamera, Ortho); + { + lcModel* ActiveModel = GetActiveModel(); + if (ActiveModel) + ActiveModel->SetCameraOrthographic(mCamera, Ortho); + } } void View::LookAt() { - mModel->LookAt(mCamera); + lcModel* ActiveModel = GetActiveModel(); + if (ActiveModel) + ActiveModel->LookAt(mCamera); } void View::ZoomExtents() { - mModel->ZoomExtents(mCamera, (float)mWidth / (float)mHeight); + lcModel* ActiveModel = GetActiveModel(); + if (ActiveModel) + ActiveModel->ZoomExtents(mCamera, (float)mWidth / (float)mHeight); } void View::MoveCamera(const lcVector3& Direction) { - mModel->MoveCamera(mCamera, Direction); + lcModel* ActiveModel = GetActiveModel(); + if (ActiveModel) + ActiveModel->MoveCamera(mCamera, Direction); } void View::UpdateTrackTool() @@ -1858,6 +1926,7 @@ void View::UpdateTrackTool() int y = mInputState.y; bool Redraw = false; mTrackToolFromOverlay = false; + lcModel* ActiveModel = GetActiveModel(); switch (CurrentTool) { @@ -1893,7 +1962,7 @@ void View::UpdateTrackTool() lcVector3 OverlayCenter; lcMatrix33 RelativeRotation; - if (!mModel->GetMoveRotateTransform(OverlayCenter, RelativeRotation)) + if (!ActiveModel->GetMoveRotateTransform(OverlayCenter, RelativeRotation)) break; lcVector3 PlaneNormals[3] = @@ -1912,7 +1981,7 @@ void View::UpdateTrackTool() const lcVector3& End = StartEnd[1]; float ClosestIntersectionDistance = FLT_MAX; - lcObject* Focus = mModel->GetFocusObject(); + lcObject* Focus = ActiveModel->GetFocusObject(); int ControlPointIndex = -1; if (Focus && Focus->IsPiece()) { @@ -1954,7 +2023,7 @@ void View::UpdateTrackTool() } } - if (CurrentTool == LC_TOOL_SELECT && Proj1 > OverlayRotateArrowStart && Proj1 < OverlayRotateArrowEnd && Proj2 > OverlayRotateArrowStart && Proj2 < OverlayRotateArrowEnd && mModel->AnyPiecesSelected()) + if (CurrentTool == LC_TOOL_SELECT && Proj1 > OverlayRotateArrowStart && Proj1 < OverlayRotateArrowEnd && Proj2 > OverlayRotateArrowStart && Proj2 < OverlayRotateArrowEnd && ActiveModel->AnyPiecesSelected()) { lcTrackTool PlaneModes[] = { LC_TRACKTOOL_ROTATE_X, LC_TRACKTOOL_ROTATE_Y, LC_TRACKTOOL_ROTATE_Z }; @@ -2064,7 +2133,7 @@ void View::UpdateTrackTool() lcVector3 OverlayCenter; lcMatrix33 RelativeRotation; - if (!mModel->GetMoveRotateTransform(OverlayCenter, RelativeRotation)) + if (!ActiveModel->GetMoveRotateTransform(OverlayCenter, RelativeRotation)) break; // Calculate the distance from the mouse pointer to the center of the sphere. @@ -2369,6 +2438,7 @@ void View::StartTracking(lcTrackButton TrackButton) mMouseDownX = mInputState.x; mMouseDownY = mInputState.y; lcTool Tool = GetCurrentTool(); + lcModel* ActiveModel = GetActiveModel(); switch (Tool) { @@ -2385,7 +2455,7 @@ void View::StartTracking(lcTrackButton TrackButton) }; UnprojectPoints(PositionTarget, 2); - mModel->BeginSpotLightTool(PositionTarget[0], PositionTarget[1]); + ActiveModel->BeginSpotLightTool(PositionTarget[0], PositionTarget[1]); } break; @@ -2398,7 +2468,7 @@ void View::StartTracking(lcTrackButton TrackButton) }; UnprojectPoints(PositionTarget, 2); - mModel->BeginCameraTool(PositionTarget[0], PositionTarget[1]); + ActiveModel->BeginCameraTool(PositionTarget[0], PositionTarget[1]); } break; @@ -2407,7 +2477,7 @@ void View::StartTracking(lcTrackButton TrackButton) case LC_TOOL_MOVE: case LC_TOOL_ROTATE: - mModel->BeginMouseTool(); + ActiveModel->BeginMouseTool(); break; case LC_TOOL_ERASER: @@ -2418,7 +2488,7 @@ void View::StartTracking(lcTrackButton TrackButton) case LC_TOOL_PAN: case LC_TOOL_ROTATE_VIEW: case LC_TOOL_ROLL: - mModel->BeginMouseTool(); + ActiveModel->BeginMouseTool(); break; case LC_TOOL_ZOOM_REGION: @@ -2437,6 +2507,7 @@ void View::StopTracking(bool Accept) return; lcTool Tool = GetCurrentTool(); + lcModel* ActiveModel = GetActiveModel(); switch (Tool) { @@ -2446,7 +2517,7 @@ void View::StopTracking(bool Accept) case LC_TOOL_SPOTLIGHT: case LC_TOOL_CAMERA: - mModel->EndMouseTool(Tool, Accept); + ActiveModel->EndMouseTool(Tool, Accept); break; case LC_TOOL_SELECT: @@ -2455,17 +2526,17 @@ void View::StopTracking(bool Accept) lcArray Objects = FindObjectsInBox(mMouseDownX, mMouseDownY, mInputState.x, mInputState.y); if (mInputState.Modifiers & Qt::ControlModifier) - mModel->AddToSelection(Objects, true, true); + ActiveModel->AddToSelection(Objects, true, true); else if (mInputState.Modifiers & Qt::ShiftModifier) - mModel->RemoveFromSelection(Objects); + ActiveModel->RemoveFromSelection(Objects); else - mModel->SetSelectionAndFocus(Objects, nullptr, 0, true); + ActiveModel->SetSelectionAndFocus(Objects, nullptr, 0, true); } break; case LC_TOOL_MOVE: case LC_TOOL_ROTATE: - mModel->EndMouseTool(Tool, Accept); + ActiveModel->EndMouseTool(Tool, Accept); break; case LC_TOOL_ERASER: @@ -2476,7 +2547,7 @@ void View::StopTracking(bool Accept) case LC_TOOL_PAN: case LC_TOOL_ROTATE_VIEW: case LC_TOOL_ROLL: - mModel->EndMouseTool(Tool, Accept); + ActiveModel->EndMouseTool(Tool, Accept); break; case LC_TOOL_ZOOM_REGION: @@ -2496,7 +2567,7 @@ void View::StopTracking(bool Accept) UnprojectPoints(Points, 5); - lcVector3 Center = mModel->GetSelectionOrModelCenter(); + lcVector3 Center = ActiveModel->GetSelectionOrModelCenter(); lcVector3 PlaneNormal(mCamera->mPosition - mCamera->mTargetPosition); lcVector4 Plane(PlaneNormal, -lcDot(PlaneNormal, Center)); @@ -2505,7 +2576,7 @@ void View::StopTracking(bool Accept) if (lcLineSegmentPlaneIntersection(&Target, Points[0], Points[1], Plane) && lcLineSegmentPlaneIntersection(&Corners[0], Points[2], Points[3], Plane) && lcLineSegmentPlaneIntersection(&Corners[1], Points[3], Points[4], Plane)) { float AspectRatio = (float)mWidth / (float)mHeight; - mModel->ZoomRegionToolClicked(mCamera, AspectRatio, Points[0], Target, Corners); + ActiveModel->ZoomRegionToolClicked(mCamera, AspectRatio, Points[0], Target, Corners); } } break; @@ -2524,11 +2595,17 @@ void View::CancelTrackingOrClearSelection() if (mTrackButton != LC_TRACKBUTTON_NONE) StopTracking(false); else - mModel->ClearSelection(true); + { + lcModel* ActiveModel = GetActiveModel(); + if (ActiveModel) + ActiveModel->ClearSelection(true); + } } void View::OnButtonDown(lcTrackButton TrackButton) { + lcModel* ActiveModel = GetActiveModel(); + switch (mTrackTool) { case LC_TRACKTOOL_NONE: @@ -2541,7 +2618,7 @@ void View::OnButtonDown(lcTrackButton TrackButton) if (!CurPiece) break; - mModel->InsertPieceToolClicked(GetPieceInsertPosition(false, gMainWindow->GetCurrentPieceInfo())); + ActiveModel->InsertPieceToolClicked(GetPieceInsertPosition(false, gMainWindow->GetCurrentPieceInfo())); if ((mInputState.Modifiers & Qt::ControlModifier) == 0) gMainWindow->SetTool(LC_TOOL_SELECT); @@ -2552,7 +2629,7 @@ void View::OnButtonDown(lcTrackButton TrackButton) case LC_TRACKTOOL_POINTLIGHT: { - mModel->PointLightToolClicked(UnprojectPoint(lcVector3((float)mInputState.x, (float)mInputState.y, 0.9f))); + ActiveModel->PointLightToolClicked(UnprojectPoint(lcVector3((float)mInputState.x, (float)mInputState.y, 0.9f))); if ((mInputState.Modifiers & Qt::ControlModifier) == 0) gMainWindow->SetTool(LC_TOOL_SELECT); @@ -2571,11 +2648,11 @@ void View::OnButtonDown(lcTrackButton TrackButton) lcObjectSection ObjectSection = FindObjectUnderPointer(false, false); if (mInputState.Modifiers & Qt::ControlModifier) - mModel->FocusOrDeselectObject(ObjectSection); + ActiveModel->FocusOrDeselectObject(ObjectSection); else if (mInputState.Modifiers & Qt::ShiftModifier) - mModel->RemoveFromSelection(ObjectSection); + ActiveModel->RemoveFromSelection(ObjectSection); else - mModel->ClearSelectionAndSetFocus(ObjectSection, true); + ActiveModel->ClearSelectionAndSetFocus(ObjectSection, true); StartTracking(TrackButton); } @@ -2588,7 +2665,7 @@ void View::OnButtonDown(lcTrackButton TrackButton) case LC_TRACKTOOL_MOVE_XZ: case LC_TRACKTOOL_MOVE_YZ: case LC_TRACKTOOL_MOVE_XYZ: - if (mModel->AnyObjectsSelected()) + if (ActiveModel->AnyObjectsSelected()) StartTracking(TrackButton); break; @@ -2597,22 +2674,22 @@ void View::OnButtonDown(lcTrackButton TrackButton) case LC_TRACKTOOL_ROTATE_Z: case LC_TRACKTOOL_ROTATE_XY: case LC_TRACKTOOL_ROTATE_XYZ: - if (mModel->AnyPiecesSelected()) + if (ActiveModel->AnyPiecesSelected()) StartTracking(TrackButton); break; case LC_TRACKTOOL_SCALE_PLUS: case LC_TRACKTOOL_SCALE_MINUS: - if (mModel->AnyPiecesSelected()) + if (ActiveModel->AnyPiecesSelected()) StartTracking(TrackButton); break; case LC_TRACKTOOL_ERASER: - mModel->EraserToolClicked(FindObjectUnderPointer(false, false).Object); + ActiveModel->EraserToolClicked(FindObjectUnderPointer(false, false).Object); break; case LC_TRACKTOOL_PAINT: - mModel->PaintToolClicked(FindObjectUnderPointer(true, false).Object); + ActiveModel->PaintToolClicked(FindObjectUnderPointer(true, false).Object); break; case LC_TRACKTOOL_ZOOM: @@ -2658,13 +2735,14 @@ void View::OnLeftButtonDoubleClick() gMainWindow->SetActiveView(this); lcObjectSection ObjectSection = FindObjectUnderPointer(false, false); + lcModel* ActiveModel = GetActiveModel(); if (mInputState.Modifiers & Qt::ControlModifier) - mModel->FocusOrDeselectObject(ObjectSection); + ActiveModel->FocusOrDeselectObject(ObjectSection); else if (mInputState.Modifiers & Qt::ShiftModifier) - mModel->RemoveFromSelection(ObjectSection); + ActiveModel->RemoveFromSelection(ObjectSection); else - mModel->ClearSelectionAndSetFocus(ObjectSection, true); + ActiveModel->ClearSelectionAndSetFocus(ObjectSection, true); } void View::OnMiddleButtonDown() @@ -2737,7 +2815,9 @@ void View::OnForwardButtonUp() void View::OnMouseMove() { - if (!mModel) + lcModel* ActiveModel = GetActiveModel(); + + if (!ActiveModel) return; if (mTrackButton == LC_TRACKBUTTON_NONE) @@ -2761,11 +2841,11 @@ void View::OnMouseMove() break; case LC_TRACKTOOL_SPOTLIGHT: - mModel->UpdateSpotLightTool(UnprojectPoint(lcVector3((float)mInputState.x, (float)mInputState.y, 0.9f))); + ActiveModel->UpdateSpotLightTool(UnprojectPoint(lcVector3((float)mInputState.x, (float)mInputState.y, 0.9f))); break; case LC_TRACKTOOL_CAMERA: - mModel->UpdateCameraTool(UnprojectPoint(lcVector3((float)mInputState.x, (float)mInputState.y, 0.9f))); + ActiveModel->UpdateCameraTool(UnprojectPoint(lcVector3((float)mInputState.x, (float)mInputState.y, 0.9f))); break; case LC_TRACKTOOL_SELECT: @@ -2799,7 +2879,7 @@ void View::OnMouseMove() lcVector3 Center; lcMatrix33 RelativeRotation; - mModel->GetMoveRotateTransform(Center, RelativeRotation); + ActiveModel->GetMoveRotateTransform(Center, RelativeRotation); if (mTrackTool == LC_TRACKTOOL_MOVE_X || mTrackTool == LC_TRACKTOOL_MOVE_Y || mTrackTool == LC_TRACKTOOL_MOVE_Z) { @@ -2821,7 +2901,7 @@ void View::OnMouseMove() lcVector3 Distance = Intersection - MoveStart; Distance = lcMul(Distance, lcMatrix33AffineInverse(RelativeRotation)); - mModel->UpdateMoveTool(Distance, mTrackButton != LC_TRACKBUTTON_LEFT); + ActiveModel->UpdateMoveTool(Distance, mTrackButton != LC_TRACKBUTTON_LEFT); } else if (mTrackTool == LC_TRACKTOOL_MOVE_XY || mTrackTool == LC_TRACKTOOL_MOVE_XZ || mTrackTool == LC_TRACKTOOL_MOVE_YZ) { @@ -2846,7 +2926,7 @@ void View::OnMouseMove() { lcVector3 Distance = Intersection - MoveStart; Distance = lcMul(Distance, lcMatrix33AffineInverse(RelativeRotation)); - mModel->UpdateMoveTool(Distance, mTrackButton != LC_TRACKBUTTON_LEFT); + ActiveModel->UpdateMoveTool(Distance, mTrackButton != LC_TRACKBUTTON_LEFT); } } } @@ -2854,7 +2934,7 @@ void View::OnMouseMove() { lcMatrix44 NewPosition = GetPieceInsertPosition(true, mMouseDownPiece); lcVector3 Distance = NewPosition.GetTranslation() - mMouseDownPosition; - mModel->UpdateMoveTool(Distance, mTrackButton != LC_TRACKBUTTON_LEFT); + ActiveModel->UpdateMoveTool(Distance, mTrackButton != LC_TRACKBUTTON_LEFT); } else if (mTrackTool == LC_TRACKTOOL_SCALE_PLUS || mTrackTool == LC_TRACKTOOL_SCALE_MINUS) { @@ -2869,7 +2949,7 @@ void View::OnMouseMove() lcVector3 Intersection; lcClosestPointsBetweenLines(Center, Center + Direction, CurrentStart, CurrentEnd, &Intersection, nullptr); - lcObject* Focus = mModel->GetFocusObject(); + lcObject* Focus = ActiveModel->GetFocusObject(); if (Focus && Focus->IsPiece()) { lcPiece* Piece = (lcPiece*)Focus; @@ -2890,7 +2970,7 @@ void View::OnMouseMove() float Scale = lcClamp(Distance, 0.1f, ScaleMax); - mModel->UpdateScaleTool(Scale); + ActiveModel->UpdateScaleTool(Scale); } } } @@ -2907,7 +2987,7 @@ void View::OnMouseMove() if (lcLineSegmentPlaneIntersection(&MoveStart, MouseDownStart, MouseDownEnd, Plane)) { lcVector3 Distance = Intersection - MoveStart; - mModel->UpdateMoveTool(Distance, mTrackButton != LC_TRACKBUTTON_LEFT); + ActiveModel->UpdateMoveTool(Distance, mTrackButton != LC_TRACKBUTTON_LEFT); } } } @@ -2965,7 +3045,7 @@ void View::OnMouseMove() MoveX *= 36.0f * (float)(mInputState.x - mMouseDownX) * MouseSensitivity; MoveY *= 36.0f * (float)(mInputState.y - mMouseDownY) * MouseSensitivity; - mModel->UpdateRotateTool(MoveX + MoveY, mTrackButton != LC_TRACKBUTTON_LEFT); + ActiveModel->UpdateRotateTool(MoveX + MoveY, mTrackButton != LC_TRACKBUTTON_LEFT); } break; @@ -2977,7 +3057,7 @@ void View::OnMouseMove() lcVector3 MoveX = 36.0f * (float)(mInputState.x - mMouseDownX) * MouseSensitivity * ScreenX; lcVector3 MoveY = 36.0f * (float)(mInputState.y - mMouseDownY) * MouseSensitivity * ScreenY; - mModel->UpdateRotateTool(MoveX + MoveY, mTrackButton != LC_TRACKBUTTON_LEFT); + ActiveModel->UpdateRotateTool(MoveX + MoveY, mTrackButton != LC_TRACKBUTTON_LEFT); } break; @@ -2985,7 +3065,7 @@ void View::OnMouseMove() { lcVector3 ScreenZ = lcNormalize(mCamera->mTargetPosition - mCamera->mPosition); - mModel->UpdateRotateTool(36.0f * (float)(mInputState.y - mMouseDownY) * MouseSensitivity * ScreenZ, mTrackButton != LC_TRACKBUTTON_LEFT); + ActiveModel->UpdateRotateTool(36.0f * (float)(mInputState.y - mMouseDownY) * MouseSensitivity * ScreenZ, mTrackButton != LC_TRACKBUTTON_LEFT); } break; @@ -2994,7 +3074,7 @@ void View::OnMouseMove() break; case LC_TRACKTOOL_ZOOM: - mModel->UpdateZoomTool(mCamera, 2.0f * MouseSensitivity * (mInputState.y - mMouseDownY)); + ActiveModel->UpdateZoomTool(mCamera, 2.0f * MouseSensitivity * (mInputState.y - mMouseDownY)); break; case LC_TRACKTOOL_PAN: @@ -3013,7 +3093,7 @@ void View::OnMouseMove() const lcVector3& CurrentEnd = Points[1]; const lcVector3& MouseDownStart = Points[2]; const lcVector3& MouseDownEnd = Points[3]; - lcVector3 Center = mModel->GetSelectionOrModelCenter(); + lcVector3 Center = ActiveModel->GetSelectionOrModelCenter(); lcVector3 PlaneNormal(mCamera->mPosition - mCamera->mTargetPosition); lcVector4 Plane(PlaneNormal, -lcDot(PlaneNormal, Center)); @@ -3028,24 +3108,24 @@ void View::OnMouseMove() break; } - mModel->UpdatePanTool(mCamera, MoveStart - Intersection); + ActiveModel->UpdatePanTool(mCamera, MoveStart - Intersection); } break; case LC_TRACKTOOL_ORBIT_X: - mModel->UpdateOrbitTool(mCamera, 0.1f * MouseSensitivity * (mInputState.x - mMouseDownX), 0.0f); + ActiveModel->UpdateOrbitTool(mCamera, 0.1f * MouseSensitivity * (mInputState.x - mMouseDownX), 0.0f); break; case LC_TRACKTOOL_ORBIT_Y: - mModel->UpdateOrbitTool(mCamera, 0.0f, 0.1f * MouseSensitivity * (mInputState.y - mMouseDownY)); + ActiveModel->UpdateOrbitTool(mCamera, 0.0f, 0.1f * MouseSensitivity * (mInputState.y - mMouseDownY)); break; case LC_TRACKTOOL_ORBIT_XY: - mModel->UpdateOrbitTool(mCamera, 0.1f * MouseSensitivity * (mInputState.x - mMouseDownX), 0.1f * MouseSensitivity * (mInputState.y - mMouseDownY)); + ActiveModel->UpdateOrbitTool(mCamera, 0.1f * MouseSensitivity * (mInputState.x - mMouseDownX), 0.1f * MouseSensitivity * (mInputState.y - mMouseDownY)); break; case LC_TRACKTOOL_ROLL: - mModel->UpdateRollTool(mCamera, 2.0f * MouseSensitivity * (mInputState.x - mMouseDownX) * LC_DTOR); + ActiveModel->UpdateRollTool(mCamera, 2.0f * MouseSensitivity * (mInputState.x - mMouseDownX) * LC_DTOR); break; case LC_TRACKTOOL_ZOOM_REGION: diff --git a/common/view.h b/common/view.h index 1dab034e..7a20decc 100644 --- a/common/view.h +++ b/common/view.h @@ -58,6 +58,20 @@ public: View(lcModel* Model); virtual ~View(); + void Clear() + { + mModel = nullptr; + mActiveSubmodelInstance = nullptr; + } + + lcModel* GetModel() const + { + return mModel; + } + + lcModel* GetActiveModel() const; + void SetSelectedSubmodelActive(); + void SetHighlight(bool Highlight) { mHighlight = Highlight; @@ -107,7 +121,6 @@ public: lcObjectSection FindObjectUnderPointer(bool PiecesOnly, bool IgnoreSelected) const; lcArray FindObjectsInBox(float x1, float y1, float x2, float y2) const; - lcModel* mModel; lcCamera* mCamera; lcVector3 ProjectPoint(const lcVector3& Point) const @@ -157,6 +170,10 @@ protected: void OnButtonDown(lcTrackButton TrackButton); lcMatrix44 GetTileProjectionMatrix(int CurrentRow, int CurrentColumn, int CurrentTileWidth, int CurrentTileHeight) const; + lcModel* mModel; + lcPiece* mActiveSubmodelInstance; + lcMatrix44 mActiveSubmodelMatrix; + lcScene mScene; lcDragState mDragState; lcTrackButton mTrackButton;