mirror of
https://github.com/leozide/leocad
synced 2025-01-13 08:01:38 +01:00
Detect train track connections and pick an open one when inserting.
This commit is contained in:
parent
f80b5c95e1
commit
a08ad3f81b
7 changed files with 117 additions and 25 deletions
|
@ -1316,10 +1316,15 @@ void lcModel::GetScene(lcScene* Scene, const lcCamera* ViewCamera, bool AllowHig
|
|||
if (mPieceInfo)
|
||||
mPieceInfo->AddRenderMesh(*Scene);
|
||||
|
||||
lcPiece* FocusPiece = nullptr;
|
||||
|
||||
for (const std::unique_ptr<lcPiece>& Piece : mPieces)
|
||||
{
|
||||
if (Piece->IsVisible(mCurrentStep))
|
||||
{
|
||||
if (Piece->IsFocused())
|
||||
FocusPiece = Piece.get();
|
||||
|
||||
const lcStep StepShow = Piece->GetStepShow();
|
||||
Piece->AddMainModelRenderMeshes(Scene, AllowHighlight && StepShow == mCurrentStep, AllowFade && StepShow < mCurrentStep);
|
||||
}
|
||||
|
@ -1327,6 +1332,9 @@ void lcModel::GetScene(lcScene* Scene, const lcCamera* ViewCamera, bool AllowHig
|
|||
|
||||
if (Scene->GetDrawInterface() && !Scene->GetActiveSubmodelInstance())
|
||||
{
|
||||
if (FocusPiece)
|
||||
UpdateTrainTrackConnections(FocusPiece);
|
||||
|
||||
for (const std::unique_ptr<lcCamera>& Camera : mCameras)
|
||||
if (Camera.get() != ViewCamera && Camera->IsVisible())
|
||||
Scene->AddInterfaceObject(Camera.get());
|
||||
|
@ -2356,6 +2364,32 @@ void lcModel::InsertPiece(lcPiece* Piece, size_t Index)
|
|||
mPieces.insert(mPieces.begin() + Index, std::unique_ptr<lcPiece>(Piece));
|
||||
}
|
||||
|
||||
void lcModel::UpdateTrainTrackConnections(lcPiece* FocusPiece) const
|
||||
{
|
||||
if (!FocusPiece || !FocusPiece->IsFocused())
|
||||
return;
|
||||
|
||||
const lcTrainTrackInfo* TrainTrackInfo = FocusPiece->mPieceInfo->GetTrainTrackInfo();
|
||||
|
||||
if (!TrainTrackInfo)
|
||||
return;
|
||||
|
||||
const int ConnectionCount = static_cast<int>(TrainTrackInfo->GetConnections().size());
|
||||
std::vector<bool> Connections(ConnectionCount, false);
|
||||
|
||||
for (const std::unique_ptr<lcPiece>& Piece : mPieces)
|
||||
{
|
||||
if (Piece.get() == FocusPiece || !Piece->mPieceInfo->GetTrainTrackInfo())
|
||||
continue;
|
||||
|
||||
for (int ConnectionIndex = 0; ConnectionIndex < ConnectionCount; ConnectionIndex++)
|
||||
if (!Connections[ConnectionIndex] && lcTrainTrackInfo::ArePiecesConnected(FocusPiece, ConnectionIndex, Piece.get()))
|
||||
Connections[ConnectionIndex] = true;
|
||||
}
|
||||
|
||||
FocusPiece->SetTrainTrackConnections(std::move(Connections));
|
||||
}
|
||||
|
||||
void lcModel::DeleteAllCameras()
|
||||
{
|
||||
if (mCameras.empty())
|
||||
|
@ -3782,11 +3816,13 @@ void lcModel::ClearSelectionAndSetFocus(lcObject* Object, quint32 Section, bool
|
|||
|
||||
if (Object->IsPiece())
|
||||
{
|
||||
SelectGroup(((lcPiece*)Object)->GetTopGroup(), true);
|
||||
lcPiece* Piece = dynamic_cast<lcPiece*>(Object);
|
||||
|
||||
SelectGroup(Piece->GetTopGroup(), true);
|
||||
|
||||
if (EnableSelectionMode)
|
||||
{
|
||||
std::vector<lcObject*> Pieces = GetSelectionModePieces((lcPiece*)Object);
|
||||
std::vector<lcObject*> Pieces = GetSelectionModePieces(Piece);
|
||||
AddToSelection(Pieces, false, false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -390,6 +390,8 @@ protected:
|
|||
void AddPiece(lcPiece* Piece);
|
||||
void InsertPiece(lcPiece* Piece, size_t Index);
|
||||
|
||||
void UpdateTrainTrackConnections(lcPiece* FocusPiece) const;
|
||||
|
||||
lcPOVRayOptions mPOVRayOptions;
|
||||
lcModelProperties mProperties;
|
||||
Project* const mProject;
|
||||
|
|
|
@ -111,6 +111,29 @@ std::pair<PieceInfo*, lcMatrix44> lcTrainTrackInfo::GetPieceInsertTransform(lcPi
|
|||
return { Info, Transform };
|
||||
}
|
||||
|
||||
bool lcTrainTrackInfo::ArePiecesConnected(const lcPiece* Piece1, int ConnectionIndex1, const lcPiece* Piece2)
|
||||
{
|
||||
const lcTrainTrackInfo* TrainTrackInfo1 = Piece1->mPieceInfo->GetTrainTrackInfo();
|
||||
const lcTrainTrackInfo* TrainTrackInfo2 = Piece2->mPieceInfo->GetTrainTrackInfo();
|
||||
|
||||
lcMatrix44 Transform1 = lcMul(TrainTrackInfo1->GetConnections()[ConnectionIndex1].Transform, Piece1->mModelWorld);
|
||||
|
||||
for (const lcTrainTrackConnection& Connection2 : TrainTrackInfo2->GetConnections())
|
||||
{
|
||||
lcMatrix44 Transform2 = lcMul(Connection2.Transform, Piece2->mModelWorld);
|
||||
|
||||
if (lcLengthSquared(Transform1.GetTranslation() - Transform2.GetTranslation()) > 0.1f)
|
||||
continue;
|
||||
|
||||
float Dot = lcDot3(Transform1[0], Transform2[0]);
|
||||
|
||||
if (Dot < -0.99f && Dot > -1.01f)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::optional<lcMatrix44> lcTrainTrackInfo::GetPieceInsertTransform(lcPiece* CurrentPiece, PieceInfo* Info)
|
||||
{
|
||||
if (!CurrentPiece || !Info)
|
||||
|
@ -126,7 +149,9 @@ std::optional<lcMatrix44> lcTrainTrackInfo::GetPieceInsertTransform(lcPiece* Cur
|
|||
|
||||
if (FocusSection == LC_PIECE_SECTION_POSITION || FocusSection == LC_PIECE_SECTION_INVALID)
|
||||
{
|
||||
// todo: search model for open connection
|
||||
for (ConnectionIndex = 0; ConnectionIndex < CurrentTrackInfo->GetConnections().size(); ConnectionIndex++)
|
||||
if (CurrentPiece->IsTrainTrackConnectionVisible(ConnectionIndex))
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -134,11 +159,11 @@ std::optional<lcMatrix44> lcTrainTrackInfo::GetPieceInsertTransform(lcPiece* Cur
|
|||
return std::nullopt;
|
||||
|
||||
ConnectionIndex = FocusSection - LC_PIECE_SECTION_TRAIN_TRACK_CONNECTION_FIRST;
|
||||
|
||||
if (ConnectionIndex >= CurrentTrackInfo->GetConnections().size())
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
if (ConnectionIndex >= CurrentTrackInfo->GetConnections().size())
|
||||
return std::nullopt;
|
||||
|
||||
lcTrainTrackInfo* NewTrackInfo = Info->GetTrainTrackInfo();
|
||||
|
||||
if (!NewTrackInfo || NewTrackInfo->mConnections.empty())
|
||||
|
|
|
@ -27,6 +27,7 @@ public:
|
|||
|
||||
std::pair<PieceInfo*, lcMatrix44> GetPieceInsertTransform(lcPiece* Piece, quint32 ConnectionIndex, lcTrainTrackType TrainTrackType) const;
|
||||
static std::optional<lcMatrix44> GetPieceInsertTransform(lcPiece* CurrentPiece, PieceInfo* Info);
|
||||
static bool ArePiecesConnected(const lcPiece* Piece1, int ConnectionIndex1, const lcPiece* Piece2);
|
||||
|
||||
void AddConnection(const lcTrainTrackConnection& TrainTrackConnection)
|
||||
{
|
||||
|
|
|
@ -371,26 +371,32 @@ void lcViewManipulator::DrawSelectMove(lcTrackButton TrackButton, lcTrackTool Tr
|
|||
void lcViewManipulator::DrawTrainTrack(lcPiece* Piece, lcContext* Context, float OverlayScale)
|
||||
{
|
||||
const lcTrainTrackInfo* TrainTrackInfo = Piece->mPieceInfo->GetTrainTrackInfo();
|
||||
const std::vector<lcTrainTrackConnection>& Connections = TrainTrackInfo->GetConnections();
|
||||
|
||||
for (const lcTrainTrackConnection& TrainTrackConnection : TrainTrackInfo->GetConnections())
|
||||
for (quint32 ConnectionIndex = 0; ConnectionIndex < Connections.size(); ConnectionIndex++)
|
||||
{
|
||||
if (!Piece->IsTrainTrackConnectionVisible(ConnectionIndex))
|
||||
continue;
|
||||
|
||||
const lcMatrix44& Transform = Connections[ConnectionIndex].Transform;
|
||||
|
||||
lcVector3 Verts[static_cast<int>(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++] = Transform.GetTranslation() / OverlayScale;
|
||||
Verts[NumVerts++] = (Transform.GetTranslation() + lcVector3(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++] = Transform.GetTranslation() / OverlayScale;
|
||||
Verts[NumVerts++] = (Transform.GetTranslation() + lcMul31(lcVector3(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++] = Transform.GetTranslation() / OverlayScale;
|
||||
Verts[NumVerts++] = (Transform.GetTranslation() + lcMul31(lcVector3(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++] = Transform.GetTranslation() / OverlayScale;
|
||||
Verts[NumVerts++] = (Transform.GetTranslation() + lcMul31(lcVector3(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;
|
||||
Verts[NumVerts++] = Transform.GetTranslation() / OverlayScale;
|
||||
Verts[NumVerts++] = (Transform.GetTranslation() + lcMul31(lcVector3(Transform[0]), lcMatrix44RotationZ(LC_DTOR * -30)) * 100) / OverlayScale;
|
||||
|
||||
Context->SetColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
|
@ -956,17 +962,22 @@ std::pair<lcTrackTool, quint32> lcViewManipulator::UpdateSelectMove()
|
|||
|
||||
if (TrainTrackInfo)
|
||||
{
|
||||
for (quint32 Section = 0; Section < TrainTrackInfo->GetConnections().size(); Section++)
|
||||
const std::vector<lcTrainTrackConnection>& Connections = TrainTrackInfo->GetConnections();
|
||||
|
||||
for (quint32 ConnectionIndex = 0; ConnectionIndex < Connections.size(); ConnectionIndex++)
|
||||
{
|
||||
const lcTrainTrackConnection& TrainTrackConnection = TrainTrackInfo->GetConnections()[Section];
|
||||
if (!Piece->IsTrainTrackConnectionVisible(ConnectionIndex))
|
||||
continue;
|
||||
|
||||
const lcMatrix44& Transform = Connections[ConnectionIndex].Transform;
|
||||
lcVector3 Verts[static_cast<int>(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;
|
||||
Verts[NumVerts++] = (Transform.GetTranslation() + lcVector3(Transform[0]) * 100) / 1;
|
||||
Verts[NumVerts++] = (Transform.GetTranslation() + lcMul31(lcVector3(Transform[0]), lcMatrix44RotationZ(LC_DTOR * 60)) * 100) / 1;
|
||||
Verts[NumVerts++] = (Transform.GetTranslation() + lcMul31(lcVector3(Transform[0]), lcMatrix44RotationZ(LC_DTOR * -60)) * 100) / 1;
|
||||
Verts[NumVerts++] = (Transform.GetTranslation() + lcMul31(lcVector3(Transform[0]), lcMatrix44RotationZ(LC_DTOR * 30)) * 100) / 1;
|
||||
Verts[NumVerts++] = (Transform.GetTranslation() + lcMul31(lcVector3(Transform[0]), lcMatrix44RotationZ(LC_DTOR * -30)) * 100) / 1;
|
||||
|
||||
for (int VertexIndex = 0; VertexIndex < NumVerts; VertexIndex++)
|
||||
{
|
||||
|
@ -981,7 +992,7 @@ std::pair<lcTrackTool, quint32> lcViewManipulator::UpdateSelectMove()
|
|||
|
||||
NewTrackTool = lcTrackTool::Insert;
|
||||
ClosestIntersectionDistance = IntersectionDistance;
|
||||
NewTrackSection = Section | (VertexIndex << 8);
|
||||
NewTrackSection = ConnectionIndex | (VertexIndex << 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -520,6 +520,9 @@ void lcPiece::RayTest(lcObjectRayTest& ObjectRayTest) const
|
|||
|
||||
for (quint32 ConnectionIndex = 0; ConnectionIndex < Connections.size(); ConnectionIndex++)
|
||||
{
|
||||
if (mTrainTrackConnections[ConnectionIndex])
|
||||
continue;
|
||||
|
||||
const lcMatrix44 InverseTransform = lcMatrix44AffineInverse(Connections[ConnectionIndex].Transform);
|
||||
const lcVector3 PointStart = lcMul31(Start, InverseTransform);
|
||||
const lcVector3 PointEnd = lcMul31(End, InverseTransform);
|
||||
|
@ -728,6 +731,9 @@ void lcPiece::DrawTrainTrackInterface(lcContext* Context, const lcMatrix44& Worl
|
|||
|
||||
for (quint32 ConnectionIndex = 0; ConnectionIndex < Connections.size(); ConnectionIndex++)
|
||||
{
|
||||
if (mTrainTrackConnections[ConnectionIndex])
|
||||
continue;
|
||||
|
||||
Context->SetWorldMatrix(lcMul(Connections[ConnectionIndex].Transform, WorldMatrix));
|
||||
|
||||
Context->SetVertexBufferPointer(Verts);
|
||||
|
|
|
@ -150,6 +150,16 @@ public:
|
|||
UpdateMesh();
|
||||
}
|
||||
|
||||
bool IsTrainTrackConnectionVisible(int ConnectionIndex) const
|
||||
{
|
||||
return !mTrainTrackConnections[ConnectionIndex];
|
||||
}
|
||||
|
||||
void SetTrainTrackConnections(std::vector<bool>&& Connections)
|
||||
{
|
||||
mTrainTrackConnections = std::move(Connections);
|
||||
}
|
||||
|
||||
const QString& GetID() const
|
||||
{
|
||||
return mID;
|
||||
|
@ -367,5 +377,6 @@ protected:
|
|||
bool mSelected = false;
|
||||
quint32 mFocusedSection = LC_PIECE_SECTION_INVALID;
|
||||
std::vector<lcPieceControlPoint> mControlPoints;
|
||||
std::vector<bool> mTrainTrackConnections;
|
||||
lcMesh* mMesh = nullptr;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue