mirror of
https://github.com/leozide/leocad
synced 2024-12-24 21:58:12 +01:00
Added track rotation and focus shortcuts.
This commit is contained in:
parent
fee870d33d
commit
ff23653709
8 changed files with 207 additions and 8 deletions
|
@ -1278,6 +1278,27 @@ const lcCommand gCommands[] =
|
|||
QT_TRANSLATE_NOOP("Status", "Remove the selected control point"),
|
||||
""
|
||||
},
|
||||
// LC_PIECE_TRAIN_TRACK_FOCUS_NEXT
|
||||
{
|
||||
QT_TRANSLATE_NOOP("Action", "Piece.TrainTrack.FocusNext"),
|
||||
QT_TRANSLATE_NOOP("Menu", "Focus Next Connection"),
|
||||
QT_TRANSLATE_NOOP("Status", "Focus the next connection of the currently selected track"),
|
||||
""
|
||||
},
|
||||
// LC_PIECE_TRAIN_TRACK_FOCUS_PREVIOUS
|
||||
{
|
||||
QT_TRANSLATE_NOOP("Action", "Piece.TrainTrack.FocusPrevious"),
|
||||
QT_TRANSLATE_NOOP("Menu", "Focus Previous Connection"),
|
||||
QT_TRANSLATE_NOOP("Status", "Focus the previous connection of the currently selected track"),
|
||||
""
|
||||
},
|
||||
// LC_PIECE_TRAIN_TRACK_ROTATE
|
||||
{
|
||||
QT_TRANSLATE_NOOP("Action", "Piece.TrainTrack.Rotate"),
|
||||
QT_TRANSLATE_NOOP("Menu", "Rotate Train Track"),
|
||||
QT_TRANSLATE_NOOP("Status", "Rotate the focused train track arount its last connection"),
|
||||
""
|
||||
},
|
||||
// LC_PIECE_MOVE_PLUSX
|
||||
{
|
||||
QT_TRANSLATE_NOOP("Action", "Piece.Move.PlusX"),
|
||||
|
|
|
@ -198,6 +198,9 @@ enum lcCommandId
|
|||
LC_PIECE_REMOVE_KEY_FRAMES,
|
||||
LC_PIECE_CONTROL_POINT_INSERT,
|
||||
LC_PIECE_CONTROL_POINT_REMOVE,
|
||||
LC_PIECE_TRAIN_TRACK_FOCUS_NEXT,
|
||||
LC_PIECE_TRAIN_TRACK_FOCUS_PREVIOUS,
|
||||
LC_PIECE_TRAIN_TRACK_ROTATE,
|
||||
LC_PIECE_MOVE_PLUSX,
|
||||
LC_PIECE_MOVE_MINUSX,
|
||||
LC_PIECE_MOVE_PLUSY,
|
||||
|
|
|
@ -2005,6 +2005,9 @@ void lcMainWindow::UpdateSelectedObjects(bool SelectionChanged)
|
|||
mActions[LC_PIECE_ARRAY]->setEnabled(Flags & LC_SEL_PIECE);
|
||||
mActions[LC_PIECE_CONTROL_POINT_INSERT]->setEnabled(Flags & LC_SEL_CAN_ADD_CONTROL_POINT);
|
||||
mActions[LC_PIECE_CONTROL_POINT_REMOVE]->setEnabled(Flags & LC_SEL_CAN_REMOVE_CONTROL_POINT);
|
||||
mActions[LC_PIECE_TRAIN_TRACK_FOCUS_NEXT]->setEnabled(Flags & LC_SEL_TRAIN_TRACK_VISIBLE);
|
||||
mActions[LC_PIECE_TRAIN_TRACK_FOCUS_PREVIOUS]->setEnabled(Flags & LC_SEL_TRAIN_TRACK_VISIBLE);
|
||||
mActions[LC_PIECE_TRAIN_TRACK_ROTATE]->setEnabled(Flags & LC_SEL_TRAIN_TRACK_VISIBLE);
|
||||
mActions[LC_PIECE_HIDE_SELECTED]->setEnabled(Flags & LC_SEL_VISIBLE_SELECTED);
|
||||
mActions[LC_PIECE_HIDE_UNSELECTED]->setEnabled(Flags & LC_SEL_UNSELECTED);
|
||||
mActions[LC_PIECE_UNHIDE_SELECTED]->setEnabled(Flags & LC_SEL_HIDDEN_SELECTED);
|
||||
|
@ -2926,6 +2929,21 @@ void lcMainWindow::HandleCommand(lcCommandId CommandId)
|
|||
ActiveModel->RemoveFocusedControlPoint();
|
||||
break;
|
||||
|
||||
case LC_PIECE_TRAIN_TRACK_FOCUS_NEXT:
|
||||
if (ActiveModel)
|
||||
ActiveModel->FocusNextTrainTrack();
|
||||
break;
|
||||
|
||||
case LC_PIECE_TRAIN_TRACK_FOCUS_PREVIOUS:
|
||||
if (ActiveModel)
|
||||
ActiveModel->FocusPreviousTrainTrack();
|
||||
break;
|
||||
|
||||
case LC_PIECE_TRAIN_TRACK_ROTATE:
|
||||
if (ActiveModel)
|
||||
ActiveModel->RotateFocusedTrainTrack();
|
||||
break;
|
||||
|
||||
case LC_PIECE_MOVE_PLUSX:
|
||||
if (ActiveModel)
|
||||
ActiveModel->MoveSelectedObjects(ActiveView->GetMoveDirection(lcVector3(lcMax(GetMoveXYSnap(), 0.1f), 0.0f, 0.0f)), true, false, true, true, true);
|
||||
|
|
|
@ -2371,6 +2371,126 @@ void lcModel::InsertPiece(lcPiece* Piece, size_t Index)
|
|||
mPieces.insert(mPieces.begin() + Index, std::unique_ptr<lcPiece>(Piece));
|
||||
}
|
||||
|
||||
void lcModel::FocusNextTrainTrack()
|
||||
{
|
||||
const lcObject* Focus = GetFocusObject();
|
||||
|
||||
if (!Focus || !Focus->IsPiece())
|
||||
return;
|
||||
|
||||
lcPiece* FocusPiece = (lcPiece*)Focus;
|
||||
const lcTrainTrackInfo* TrainTrackInfo = FocusPiece->mPieceInfo->GetTrainTrackInfo();
|
||||
|
||||
if (!TrainTrackInfo)
|
||||
return;
|
||||
|
||||
quint32 FocusSection = FocusPiece->GetFocusSection();
|
||||
std::optional<lcMatrix44> Transform;
|
||||
int ConnectionIndex = 0;
|
||||
|
||||
if (FocusSection != LC_PIECE_SECTION_INVALID && FocusSection != LC_PIECE_SECTION_POSITION)
|
||||
{
|
||||
ConnectionIndex = FocusSection - LC_PIECE_SECTION_TRAIN_TRACK_CONNECTION_FIRST;
|
||||
ConnectionIndex = (ConnectionIndex + 1) % TrainTrackInfo->GetConnections().size();
|
||||
}
|
||||
|
||||
FocusPiece->SetFocused(LC_PIECE_SECTION_TRAIN_TRACK_CONNECTION_FIRST + ConnectionIndex, true);
|
||||
|
||||
gMainWindow->UpdateSelectedObjects(true);
|
||||
UpdateAllViews();
|
||||
}
|
||||
|
||||
void lcModel::FocusPreviousTrainTrack()
|
||||
{
|
||||
const lcObject* Focus = GetFocusObject();
|
||||
|
||||
if (!Focus || !Focus->IsPiece())
|
||||
return;
|
||||
|
||||
lcPiece* FocusPiece = (lcPiece*)Focus;
|
||||
const lcTrainTrackInfo* TrainTrackInfo = FocusPiece->mPieceInfo->GetTrainTrackInfo();
|
||||
|
||||
if (!TrainTrackInfo)
|
||||
return;
|
||||
|
||||
quint32 FocusSection = FocusPiece->GetFocusSection();
|
||||
std::optional<lcMatrix44> Transform;
|
||||
int ConnectionIndex = 0;
|
||||
|
||||
if (FocusSection != LC_PIECE_SECTION_INVALID && FocusSection != LC_PIECE_SECTION_POSITION)
|
||||
{
|
||||
ConnectionIndex = FocusSection - LC_PIECE_SECTION_TRAIN_TRACK_CONNECTION_FIRST;
|
||||
ConnectionIndex = (ConnectionIndex + static_cast<int>(TrainTrackInfo->GetConnections().size()) - 1) % TrainTrackInfo->GetConnections().size();
|
||||
}
|
||||
|
||||
FocusPiece->SetFocused(LC_PIECE_SECTION_TRAIN_TRACK_CONNECTION_FIRST + ConnectionIndex, true);
|
||||
|
||||
gMainWindow->UpdateSelectedObjects(true);
|
||||
UpdateAllViews();
|
||||
}
|
||||
|
||||
void lcModel::RotateFocusedTrainTrack()
|
||||
{
|
||||
const lcObject* Focus = GetFocusObject();
|
||||
|
||||
if (!Focus || !Focus->IsPiece())
|
||||
return;
|
||||
|
||||
lcPiece* FocusPiece = (lcPiece*)Focus;
|
||||
const lcTrainTrackInfo* TrainTrackInfo = FocusPiece->mPieceInfo->GetTrainTrackInfo();
|
||||
|
||||
if (!TrainTrackInfo)
|
||||
return;
|
||||
|
||||
quint32 FocusSection = FocusPiece->GetFocusSection();
|
||||
std::optional<lcMatrix44> Transform;
|
||||
int FirstConnectionIndex = 0, RotateConnectionIndex = 0, TracksConnected = 0;
|
||||
|
||||
for (int ConnectionIndex = 0; ConnectionIndex < static_cast<int>(TrainTrackInfo->GetConnections().size()); ConnectionIndex++)
|
||||
{
|
||||
if (FocusPiece->IsTrainTrackConnected(ConnectionIndex))
|
||||
{
|
||||
if (!TracksConnected)
|
||||
FirstConnectionIndex = ConnectionIndex;
|
||||
|
||||
TracksConnected++;
|
||||
}
|
||||
}
|
||||
|
||||
if (FocusSection != LC_PIECE_SECTION_INVALID && FocusSection != LC_PIECE_SECTION_POSITION)
|
||||
{
|
||||
RotateConnectionIndex = FocusSection - LC_PIECE_SECTION_TRAIN_TRACK_CONNECTION_FIRST;
|
||||
}
|
||||
else
|
||||
{
|
||||
RotateConnectionIndex = FirstConnectionIndex;
|
||||
|
||||
if (TracksConnected > 1)
|
||||
{
|
||||
// todo: find most recent connection
|
||||
}
|
||||
}
|
||||
|
||||
lcMatrix44 ConnectionTransform = lcMul(TrainTrackInfo->GetConnections()[RotateConnectionIndex].Transform, FocusPiece->mModelWorld);
|
||||
int NewConnectionIndex = (RotateConnectionIndex + 1) % TrainTrackInfo->GetConnections().size();
|
||||
|
||||
Transform = lcTrainTrackInfo::CalculateTransformToConnection(ConnectionTransform, FocusPiece->mPieceInfo, NewConnectionIndex);
|
||||
|
||||
if (!Transform)
|
||||
return;
|
||||
|
||||
if ((FocusSection != LC_PIECE_SECTION_INVALID && FocusSection != LC_PIECE_SECTION_POSITION) || !TracksConnected)
|
||||
FocusPiece->SetFocused(LC_PIECE_SECTION_TRAIN_TRACK_CONNECTION_FIRST + NewConnectionIndex, true);
|
||||
|
||||
FocusPiece->SetPosition(Transform.value().GetTranslation(), mCurrentStep, gMainWindow->GetAddKeys());
|
||||
FocusPiece->SetRotation(lcMatrix33(Transform.value()), mCurrentStep, gMainWindow->GetAddKeys());
|
||||
FocusPiece->UpdatePosition(mCurrentStep);
|
||||
|
||||
gMainWindow->UpdateSelectedObjects(true);
|
||||
UpdateAllViews();
|
||||
SaveCheckpoint(tr("Rotating"));
|
||||
}
|
||||
|
||||
void lcModel::UpdateTrainTrackConnections(lcPiece* FocusPiece) const
|
||||
{
|
||||
if (!FocusPiece || !FocusPiece->IsFocused())
|
||||
|
@ -3645,6 +3765,9 @@ void lcModel::GetSelectionInformation(int* Flags, std::vector<lcObject*>& Select
|
|||
|
||||
*Flags |= LC_SEL_PIECE | LC_SEL_SELECTED;
|
||||
|
||||
if (Piece->AreTrainTrackConnectionsVisible())
|
||||
*Flags |= LC_SEL_TRAIN_TRACK_VISIBLE;
|
||||
|
||||
if (Piece->CanAddControlPoint())
|
||||
*Flags |= LC_SEL_CAN_ADD_CONTROL_POINT;
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ enum class lcObjectPropertyId;
|
|||
#define LC_SEL_MODEL_SELECTED 0x1000 // At least one model reference is selected
|
||||
#define LC_SEL_CAN_ADD_CONTROL_POINT 0x2000 // Can add control points to focused piece
|
||||
#define LC_SEL_CAN_REMOVE_CONTROL_POINT 0x4000 // Can remove control points from focused piece
|
||||
#define LC_SEL_TRAIN_TRACK_VISIBLE 0x8000 // Focused piece has train track connections
|
||||
|
||||
enum class lcSelectionMode
|
||||
{
|
||||
|
@ -215,6 +216,9 @@ public:
|
|||
void RemoveSelectedPiecesKeyFrames();
|
||||
void InsertControlPoint();
|
||||
void RemoveFocusedControlPoint();
|
||||
void FocusNextTrainTrack();
|
||||
void FocusPreviousTrainTrack();
|
||||
void RotateFocusedTrainTrack();
|
||||
void ShowSelectedPiecesEarlier();
|
||||
void ShowSelectedPiecesLater();
|
||||
void SetPieceSteps(const std::vector<std::pair<lcPiece*, lcStep>>& PieceSteps);
|
||||
|
|
|
@ -55,9 +55,9 @@ void lcTrainTrackInit(lcPiecesLibrary* Library)
|
|||
{
|
||||
lcTrainTrackInfo* TrainTrackInfo = new lcTrainTrackInfo();
|
||||
|
||||
TrainTrackInfo->AddConnection({lcMatrix44(lcMatrix33RotationZ(LC_PI), lcVector3(-320.0f, 0.0f, 0.0f))});
|
||||
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);
|
||||
}
|
||||
|
@ -68,9 +68,9 @@ void lcTrainTrackInit(lcPiecesLibrary* Library)
|
|||
{
|
||||
lcTrainTrackInfo* TrainTrackInfo = new lcTrainTrackInfo();
|
||||
|
||||
TrainTrackInfo->AddConnection({lcMatrix44(lcMatrix33RotationZ(LC_PI), lcVector3(-320.0f, 0.0f, 0.0f))});
|
||||
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);
|
||||
}
|
||||
|
@ -170,6 +170,9 @@ std::optional<lcMatrix44> lcTrainTrackInfo::GetPieceInsertTransform(lcPiece* Cur
|
|||
for (ConnectionIndex = 0; ConnectionIndex < CurrentTrackInfo->GetConnections().size(); ConnectionIndex++)
|
||||
if (!CurrentPiece->IsTrainTrackConnected(ConnectionIndex))
|
||||
break;
|
||||
|
||||
if (ConnectionIndex == CurrentTrackInfo->GetConnections().size())
|
||||
return std::nullopt;
|
||||
}
|
||||
else if (FocusSection != LC_PIECE_SECTION_INVALID)
|
||||
{
|
||||
|
@ -179,7 +182,7 @@ std::optional<lcMatrix44> lcTrainTrackInfo::GetPieceInsertTransform(lcPiece* Cur
|
|||
ConnectionIndex = FocusSection - LC_PIECE_SECTION_TRAIN_TRACK_CONNECTION_FIRST;
|
||||
}
|
||||
|
||||
return GetConnectionTransform(CurrentPiece, ConnectionIndex, Info, 0);
|
||||
return GetConnectionTransform(CurrentPiece, ConnectionIndex, Info, ConnectionIndex ? 0 : 1);
|
||||
}
|
||||
|
||||
std::optional<lcMatrix44> lcTrainTrackInfo::GetConnectionTransform(lcPiece* CurrentPiece, quint32 CurrentConnectionIndex, PieceInfo* Info, quint32 NewConnectionIndex)
|
||||
|
@ -215,3 +218,28 @@ std::optional<lcMatrix44> lcTrainTrackInfo::GetConnectionTransform(lcPiece* Curr
|
|||
|
||||
return Transform;
|
||||
}
|
||||
|
||||
std::optional<lcMatrix44> lcTrainTrackInfo::CalculateTransformToConnection(const lcMatrix44& ConnectionTransform, PieceInfo* Info, quint32 ConnectionIndex)
|
||||
{
|
||||
lcTrainTrackInfo* TrackInfo = Info->GetTrainTrackInfo();
|
||||
|
||||
if (!TrackInfo || ConnectionIndex >= TrackInfo->mConnections.size())
|
||||
return std::nullopt;
|
||||
|
||||
lcMatrix44 Transform;
|
||||
|
||||
// if (TrainTrackType != lcTrainTrackType::Left)
|
||||
// Transform = NewTrackInfo->mConnections[NewConnectionIndex].Transform;
|
||||
// else
|
||||
// {
|
||||
Transform = lcMatrix44AffineInverse(TrackInfo->mConnections[ConnectionIndex].Transform);
|
||||
// Transform = lcMul(Transform, lcMatrix44RotationZ(LC_PI));
|
||||
// }
|
||||
|
||||
Transform = lcMul(Transform, ConnectionTransform);
|
||||
|
||||
// Transform = lcMul(Transform, CurrentTrackInfo->GetConnections()[CurrentConnectionIndex].Transform);
|
||||
// Transform = lcMul(Transform, CurrentPiece->mModelWorld);
|
||||
|
||||
return Transform;
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ public:
|
|||
std::pair<PieceInfo*, lcMatrix44> GetPieceInsertTransform(lcPiece* Piece, quint32 ConnectionIndex, lcTrainTrackType TrainTrackType) const;
|
||||
static std::optional<lcMatrix44> GetPieceInsertTransform(lcPiece* CurrentPiece, PieceInfo* Info);
|
||||
static std::optional<lcMatrix44> GetConnectionTransform(lcPiece* CurrentPiece, quint32 CurrentConnectionIndex, PieceInfo* Info, quint32 NewConnectionIndex);
|
||||
static std::optional<lcMatrix44> CalculateTransformToConnection(const lcMatrix44& ConnectionTransform, PieceInfo* Info, quint32 ConnectionIndex);
|
||||
static int GetPieceConnectionIndex(const lcPiece* Piece1, int ConnectionIndex1, const lcPiece* Piece2);
|
||||
|
||||
void AddConnection(const lcTrainTrackConnection& TrainTrackConnection)
|
||||
|
|
|
@ -171,6 +171,12 @@ public:
|
|||
QString GetName() const override;
|
||||
bool IsVisible(lcStep Step) const;
|
||||
bool IsVisibleInSubModel() const;
|
||||
|
||||
bool AreTrainTrackConnectionsVisible() const
|
||||
{
|
||||
return IsFocused();
|
||||
}
|
||||
|
||||
void GetModelParts(const lcMatrix44& WorldMatrix, int DefaultColorIndex, std::vector<lcModelPartsEntry>& ModelParts) const;
|
||||
void Initialize(const lcMatrix44& WorldMatrix, lcStep Step);
|
||||
const lcBoundingBox& GetBoundingBox() const;
|
||||
|
@ -352,11 +358,6 @@ protected:
|
|||
|
||||
void DrawSynthInterface(lcContext* Context, const lcMatrix44& WorldMatrix) const;
|
||||
|
||||
bool AreTrainTrackConnectionsVisible() const
|
||||
{
|
||||
return IsFocused();
|
||||
}
|
||||
|
||||
void DrawTrainTrackInterface(lcContext* Context, const lcMatrix44& WorldMatrix) const;
|
||||
|
||||
lcObjectProperty<lcVector3> mPosition = lcObjectProperty<lcVector3>(lcVector3(0.0f, 0.0f, 0.0f));
|
||||
|
|
Loading…
Reference in a new issue