Replaced train track gizmo with a popup list.
Some checks failed
LeoCAD CI / build-ubuntu (push) Has been cancelled
LeoCAD CI / build-macos (push) Has been cancelled

This commit is contained in:
Leonardo Zide 2024-12-18 16:41:03 -08:00
parent 4f2782b407
commit b9dc71d60e
13 changed files with 181 additions and 188 deletions

View file

@ -12,6 +12,7 @@
#include "lc_glextensions.h"
#include "lc_synth.h"
#include "lc_traintrack.h"
#include "lc_traintrack.h"
#include "project.h"
#include "lc_profile.h"
#include "lc_meshloader.h"
@ -1807,6 +1808,17 @@ void lcPiecesLibrary::GetParts(std::vector<PieceInfo*>& Parts) const
Parts.emplace_back(PartIt.second);
}
std::vector<PieceInfo*> lcPiecesLibrary::GetTrainTrackParts(const lcTrainTrackInfo* TrainTrackInfo) const
{
std::vector<PieceInfo*> Parts;
for (const auto& [Name, Info] : mPieces)
if (Info->GetTrainTrackInfo())
Parts.emplace_back(Info);
return Parts;
}
std::vector<PieceInfo*> lcPiecesLibrary::GetPartsFromSet(const std::vector<std::string>& PartIds) const
{
std::vector<PieceInfo*> Parts;

View file

@ -5,6 +5,7 @@
#include "lc_meshloader.h"
class PieceInfo;
class lcTrainTrackInfo;
class lcZipFile;
class lcLibraryMeshData;
class lcThumbnailManager;
@ -155,6 +156,7 @@ public:
void GetCategoryEntries(int CategoryIndex, bool GroupPieces, std::vector<PieceInfo*>& SinglePieces, std::vector<PieceInfo*>& GroupedPieces);
void GetCategoryEntries(const char* CategoryKeywords, bool GroupPieces, std::vector<PieceInfo*>& SinglePieces, std::vector<PieceInfo*>& GroupedPieces);
void GetParts(std::vector<PieceInfo*>& Parts) const;
std::vector<PieceInfo*> GetTrainTrackParts(const lcTrainTrackInfo* TrainTrackInfo) const;
std::vector<PieceInfo*> GetPartsFromSet(const std::vector<std::string>& PartIds) const;
std::string GetPartId(const PieceInfo* Info) const;

View file

@ -2891,7 +2891,7 @@ void lcMainWindow::HandleCommand(lcCommandId CommandId)
case LC_PIECE_INSERT:
if (ActiveModel)
ActiveModel->AddPiece();
ActiveModel->AddPiece(static_cast<PieceInfo*>(nullptr));
break;
case LC_PIECE_DELETE:

View file

@ -2281,9 +2281,10 @@ lcMatrix33 lcModel::GetRelativeRotation() const
return lcMatrix33Identity();
}
void lcModel::AddPiece()
void lcModel::AddPiece(PieceInfo* PieceInfo)
{
PieceInfo* PieceInfo = gMainWindow->GetCurrentPieceInfo();
if (!PieceInfo)
PieceInfo = gMainWindow->GetCurrentPieceInfo();
if (!PieceInfo)
return;

View file

@ -209,7 +209,7 @@ public:
void InsertStep(lcStep Step);
void RemoveStep(lcStep Step);
void AddPiece();
void AddPiece(PieceInfo* Info);
void DeleteAllCameras();
void DeleteSelectedObjects();
void ResetSelectedPiecesPivotPoint();

View file

@ -233,6 +233,28 @@ void lcPartSelectionListModel::SetCurrentModelCategory()
SetFilter(mFilter);
}
void lcPartSelectionListModel::SetCustomParts(const std::vector<PieceInfo*>& Parts)
{
beginResetModel();
ReleaseThumbnails();
mParts.clear();
for (PieceInfo* Part : Parts)
mParts.emplace_back().Info = Part;
auto lcPartSortFunc = [](const lcPartSelectionListModelEntry& a, const lcPartSelectionListModelEntry& b)
{
return strcmp(a.Info->m_strDescription, b.Info->m_strDescription) < 0;
};
std::sort(mParts.begin(), mParts.end(), lcPartSortFunc);
endResetModel();
SetFilter(mFilter);
}
void lcPartSelectionListModel::SetFilter(const QString& Filter)
{
mFilter = Filter.toLatin1();
@ -511,12 +533,8 @@ void lcPartSelectionListModel::SetShowPartNames(bool Show)
}
lcPartSelectionListView::lcPartSelectionListView(QWidget* Parent, lcPartSelectionWidget* PartSelectionWidget)
: QListView(Parent)
: QListView(Parent), mPartSelectionWidget(PartSelectionWidget)
{
mPartSelectionWidget = PartSelectionWidget;
mCategoryType = lcPartCategoryType::AllParts;
mCategoryIndex = 0;
setUniformItemSizes(true);
setResizeMode(QListView::Adjust);
setWordWrap(false);
@ -535,6 +553,9 @@ lcPartSelectionListView::lcPartSelectionListView(QWidget* Parent, lcPartSelectio
void lcPartSelectionListView::CustomContextMenuRequested(QPoint Pos)
{
if (!mPartSelectionWidget)
return;
QMenu* Menu = new QMenu(this);
QModelIndex Index = indexAt(Pos);
@ -584,6 +605,7 @@ void lcPartSelectionListView::SetCategory(lcPartCategoryType Type, int Index)
case lcPartCategoryType::Category:
mListModel->SetCategory(Index);
break;
case lcPartCategoryType::Custom:
case lcPartCategoryType::Count:
break;
}
@ -591,6 +613,15 @@ void lcPartSelectionListView::SetCategory(lcPartCategoryType Type, int Index)
setCurrentIndex(mListModel->index(0, 0));
}
void lcPartSelectionListView::SetCustomParts(const std::vector<PieceInfo*>& Parts)
{
mCategoryType = lcPartCategoryType::Custom;
mListModel->SetCustomParts(Parts);
setCurrentIndex(mListModel->index(0, 0));
}
void lcPartSelectionListView::SetCurrentPart(PieceInfo* Info)
{
QModelIndex Index = mListModel->GetPieceInfoIndex(Info);

View file

@ -13,6 +13,7 @@ enum class lcPartCategoryType
Submodels,
Palette,
Category,
Custom,
Count
};
@ -148,6 +149,7 @@ public:
void SetModelsCategory();
void SetPaletteCategory(int SetIndex);
void SetCurrentModelCategory();
void SetCustomParts(const std::vector<PieceInfo*>& Parts);
void SetFilter(const QString& Filter);
void RequestThumbnail(int PartIndex);
void SetShowDecoratedParts(bool Show);
@ -191,6 +193,7 @@ public:
void startDrag(Qt::DropActions SupportedActions) override;
void SetCategory(lcPartCategoryType Type, int Index);
void SetCustomParts(const std::vector<PieceInfo*>& Parts);
void SetCurrentPart(PieceInfo* Info);
PieceInfo* GetCurrentPart() const
@ -239,11 +242,11 @@ protected:
void SetIconSize(int Size);
void SetPartFilterType(lcPartFilterType Option);
lcPartSelectionListModel* mListModel;
lcPartSelectionWidget* mPartSelectionWidget;
PieceInfo* mContextInfo;
lcPartCategoryType mCategoryType;
int mCategoryIndex;
lcPartSelectionListModel* mListModel = nullptr;
lcPartSelectionWidget* mPartSelectionWidget = nullptr;
PieceInfo* mContextInfo = nullptr;
lcPartCategoryType mCategoryType = lcPartCategoryType::AllParts;
int mCategoryIndex = 0;
};
class lcPartSelectionWidget : public QWidget

View file

@ -86,46 +86,6 @@ void lcTrainTrackInit(lcPiecesLibrary* Library)
}
}
std::pair<PieceInfo*, lcMatrix44> lcTrainTrackInfo::GetPieceInsertTransform(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<int>(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 };
}
int lcTrainTrackInfo::GetPieceConnectionIndex(const lcPiece* Piece1, int ConnectionIndex1, const lcPiece* Piece2)
{
const lcTrainTrackInfo* TrainTrackInfo1 = Piece1->mPieceInfo->GetTrainTrackInfo();

View file

@ -25,25 +25,11 @@ class lcTrainTrackInfo
public:
lcTrainTrackInfo() = default;
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);
static quint32 EncodeTrackToolSection(quint32 ConnectionIndex, lcTrainTrackType TrainTrackType)
{
return ConnectionIndex | (static_cast<quint32>(TrainTrackType) << 8);
}
static std::pair<quint32, lcTrainTrackType> DecodeTrackToolSection(quint32 TrackToolSection)
{
quint32 ConnectionIndex = TrackToolSection & 0xff;
lcTrainTrackType TrainTrackType = static_cast<lcTrainTrackType>((TrackToolSection >> 8) & 0xff);
return { ConnectionIndex, TrainTrackType };
}
void AddConnection(const lcTrainTrackConnection& TrainTrackConnection)
{
mConnections.emplace_back(TrainTrackConnection);

View file

@ -17,6 +17,7 @@
#include "lc_viewsphere.h"
#include "lc_findreplacewidget.h"
#include "lc_library.h"
#include "lc_partselectionwidget.h"
lcFindReplaceParams lcView::mFindReplaceParams;
QPointer<lcFindReplaceWidget> lcView::mFindWidget;
@ -304,6 +305,45 @@ lcMatrix44 lcView::GetTileProjectionMatrix(int CurrentRow, int CurrentColumn, in
return lcMatrix44Frustum(Left, Right, Bottom, Top, Near, Far);
}
void lcView::ShowTrainTrackPopup()
{
if (mViewType != lcViewType::View)
return;
lcModel* ActiveModel = GetActiveModel();
lcObject* Focus = ActiveModel->GetFocusObject();
if (!Focus || !Focus->IsPiece())
return;
lcPiece* Piece = (lcPiece*)Focus;
const lcTrainTrackInfo* TrainTrackInfo = Piece->mPieceInfo->GetTrainTrackInfo();
if (!TrainTrackInfo)
return;
QMenu* Menu = new QMenu(mWidget);
QWidgetAction* Action = new QWidgetAction(Menu);
lcPartSelectionListView* ListView = new lcPartSelectionListView(mWidget, nullptr);
Action->setDefaultWidget(ListView);
Menu->addAction(Action);
std::vector<PieceInfo*> Parts = lcGetPiecesLibrary()->GetTrainTrackParts(TrainTrackInfo);
ListView->SetCustomParts(Parts);
connect(ListView, &QListView::doubleClicked, [Menu, ListView, ActiveModel]()
{
ActiveModel->AddPiece(ListView->GetCurrentPart());
Menu->close();
});
Menu->exec(QCursor::pos());
delete Menu;
}
void lcView::ShowContextMenu() const
{
if (mViewType != lcViewType::View)
@ -421,31 +461,7 @@ lcVector3 lcView::GetMoveDirection(const lcVector3& Direction) const
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)
{
auto [ConnectionIndex, TrainTrackType] = lcTrainTrackInfo::DecodeTrackToolSection(mTrackToolSection);
std::tie(PreviewInfo, mPiecePreviewTransform) = TrainTrackInfo->GetPieceInsertTransform(Piece, ConnectionIndex, TrainTrackType);
if (GetActiveModel() != mModel)
mPiecePreviewTransform = lcMul(mPiecePreviewTransform, mActiveSubmodelTransform);
}
}
if (!PreviewInfo)
{
PreviewInfo = gMainWindow->GetCurrentPieceInfo();
PieceInfo* PreviewInfo = gMainWindow->GetCurrentPieceInfo();
if (PreviewInfo)
{
@ -454,7 +470,6 @@ void lcView::UpdatePiecePreview()
if (GetActiveModel() != mModel)
mPiecePreviewTransform = lcMul(mPiecePreviewTransform, mActiveSubmodelTransform);
}
}
if (PreviewInfo != mPiecePreviewInfo)
{
@ -1927,8 +1942,9 @@ lcCursor lcView::GetCursor() const
lcCursor::Rotate, // lcTrackTool::RotateZ
lcCursor::Rotate, // lcTrackTool::RotateXY
lcCursor::Rotate, // lcTrackTool::RotateXYZ
lcCursor::Rotate, // lcTrackTool::RotateTrainTrackRight
lcCursor::Rotate, // lcTrackTool::RotateTrainTrackLeft
lcCursor::Select, // lcTrackTool::RotateTrainTrackRight
lcCursor::Select, // lcTrackTool::RotateTrainTrackLeft
lcCursor::Select, // lcTrackTool::InsertTrainTrack
lcCursor::Move, // lcTrackTool::ScalePlus
lcCursor::Move, // lcTrackTool::ScaleMinus
lcCursor::Delete, // lcTrackTool::Eraser
@ -2040,6 +2056,7 @@ lcTool lcView::GetCurrentTool() const
lcTool::Rotate, // lcTrackTool::RotateXYZ
lcTool::Rotate, // lcTrackTool::RotateTrainTrackRight
lcTool::Rotate, // lcTrackTool::RotateTrainTrackLeft
lcTool::Insert, // lcTrackTool::InsertTrainTrack
lcTool::Move, // lcTrackTool::ScalePlus
lcTool::Move, // lcTrackTool::ScaleMinus
lcTool::Eraser, // lcTrackTool::Eraser
@ -2579,6 +2596,15 @@ void lcView::OnButtonDown(lcTrackButton TrackButton)
}
break;
case lcTrackTool::InsertTrainTrack:
{
ShowTrainTrackPopup();
mToolClicked = true;
UpdateTrackTool();
}
break;
case lcTrackTool::ScalePlus:
case lcTrackTool::ScaleMinus:
if (ActiveModel->AnyPiecesSelected())
@ -3024,6 +3050,7 @@ void lcView::OnMouseMove()
case lcTrackTool::RotateTrainTrackRight:
case lcTrackTool::RotateTrainTrackLeft:
case lcTrackTool::InsertTrainTrack:
case lcTrackTool::Eraser:
case lcTrackTool::Paint:
case lcTrackTool::ColorPicker:

View file

@ -72,6 +72,7 @@ enum class lcTrackTool
RotateXYZ,
RotateTrainTrackRight,
RotateTrainTrackLeft,
InsertTrainTrack,
ScalePlus,
ScaleMinus,
Eraser,
@ -310,6 +311,8 @@ protected:
void StartPan(int x, int y);
void UpdatePan(int x, int y);
void ShowTrainTrackPopup();
lcViewWidget* mWidget = nullptr;
int mWidth = 1;
int mHeight = 1;

View file

@ -21,7 +21,7 @@ lcViewManipulator::lcViewManipulator(lcView* View)
void lcViewManipulator::CreateResources(lcContext* Context)
{
float Verts[(51 + 138 + 10 + 74) * 3];
float Verts[(51 + 138 + 10 + 74 + 28) * 3];
float* CurVert = Verts;
const float OverlayMovePlaneSize = 0.5f;
@ -146,6 +146,7 @@ void lcViewManipulator::CreateResources(lcContext* Context)
const float OverlayTrainTrackEnd = 0.5f;
const float OverlayTrainTrackCenter = 0.2f;
const float OverlayTrainTrackDistance = 0.5f;
const float OverlayTrainTrackInsert = 0.3f;
// Train Track Rotate Right
*CurVert++ = OverlayTrainTrackStart; *CurVert++ = OverlayTrainTrackEnd + OverlayTrainTrackDistance - OverlayArrowCapRadius; *CurVert++ = 0.0f;
@ -194,7 +195,38 @@ void lcViewManipulator::CreateResources(lcContext* Context)
*CurVert = *(CurVert - 111); CurVert++;
}
const GLushort Indices[108 + 360 + 12 + 192] =
// Train Track Insert
for (int EdgeIndex = 0; EdgeIndex < 7; EdgeIndex++)
{
const float Radius = OverlayArrowBodyRadius;
float x = cosf(LC_2PI * EdgeIndex / 6);
float y = sinf(LC_2PI * EdgeIndex / 6);
*CurVert++ = x * Radius + OverlayTrainTrackEnd - OverlayArrowBodyRadius;
*CurVert++ = OverlayTrainTrackInsert;
*CurVert++ = y * Radius;
*CurVert++ = x * Radius + OverlayTrainTrackEnd - OverlayArrowBodyRadius;
*CurVert++ = -OverlayTrainTrackInsert;
*CurVert++ = y * Radius;
}
for (int EdgeIndex = 0; EdgeIndex < 7; EdgeIndex++)
{
const float Radius = OverlayArrowBodyRadius;
float x = cosf(LC_2PI * EdgeIndex / 6);
float y = sinf(LC_2PI * EdgeIndex / 6);
*CurVert++ = OverlayTrainTrackInsert + OverlayTrainTrackEnd - OverlayArrowBodyRadius;
*CurVert++ = x * Radius;
*CurVert++ = y * Radius;
*CurVert++ = -OverlayTrainTrackInsert + OverlayTrainTrackEnd - OverlayArrowBodyRadius;
*CurVert++ = x * Radius;
*CurVert++ = y * Radius;
}
const GLushort Indices[108 + 360 + 12 + 192 + 72] =
{
// Move X
0, 1, 2, 0, 2, 3, 0, 3, 4, 0, 4, 5, 0, 5, 6, 0, 6, 7, 0, 7, 8, 0, 8, 1,
@ -229,7 +261,10 @@ void lcViewManipulator::CreateResources(lcContext* Context)
// Train Track Rotate Left
236, 237, 238, 236, 238, 239, 236, 239, 240, 236, 240, 241, 236, 241, 242, 236, 242, 243, 236, 243, 244, 236, 244, 237,
245, 246, 247, 247, 248, 246, 247, 248, 249, 249, 250, 248, 249, 250, 251, 251, 252, 250, 251, 252, 253, 253, 254, 252, 253, 254, 255, 255, 256, 254, 255, 256, 257, 257, 258, 256,
259, 260, 261, 261, 262, 260, 261, 262, 263, 263, 264, 262, 263, 264, 265, 265, 266, 264, 265, 266, 267, 267, 268, 266, 267, 268, 269, 269, 270, 268, 269, 270, 271, 271, 272, 270
259, 260, 261, 261, 262, 260, 261, 262, 263, 263, 264, 262, 263, 264, 265, 265, 266, 264, 265, 266, 267, 267, 268, 266, 267, 268, 269, 269, 270, 268, 269, 270, 271, 271, 272, 270,
// Train Track Insert
273, 274, 275, 275, 276, 274, 275, 276, 277, 277, 278, 276, 277, 278, 279, 279, 280, 278, 279, 280, 281, 281, 282, 280, 281, 282, 283, 283, 284, 282, 283, 284, 285, 285, 286, 284,
287, 288, 289, 289, 290, 288, 289, 290, 291, 291, 292, 290, 291, 292, 293, 293, 294, 292, 293, 294, 295, 295, 296, 294, 295, 296, 297, 297, 298, 296, 297, 298, 299, 299, 300, 298
};
mRotateMoveVertexBuffer = Context->CreateVertexBuffer(sizeof(Verts), Verts);
@ -432,18 +467,15 @@ void lcViewManipulator::DrawSelectMove(lcTrackButton TrackButton, lcTrackTool Tr
}
else if (Piece->mPieceInfo->GetTrainTrackInfo())
{
DrawTrainTrack(Piece, Context, OverlayScale, TrackTool);
DrawTrainTrack(Piece, Context, TrackTool);
}
}
Context->EnableDepthTest(true);
}
void lcViewManipulator::DrawTrainTrack(lcPiece* Piece, lcContext* Context, float OverlayScale, lcTrackTool TrackTool)
void lcViewManipulator::DrawTrainTrack(lcPiece* Piece, lcContext* Context, lcTrackTool TrackTool)
{
const lcTrainTrackInfo* TrainTrackInfo = Piece->mPieceInfo->GetTrainTrackInfo();
const std::vector<lcTrainTrackConnection>& Connections = TrainTrackInfo->GetConnections();
if (Piece->GetFocusSection() >= LC_PIECE_SECTION_TRAIN_TRACK_CONNECTION_FIRST)
{
const lcPreferences& Preferences = lcGetPreferences();
@ -454,6 +486,7 @@ void lcViewManipulator::DrawTrainTrack(lcPiece* Piece, lcContext* Context, float
if (TrackTool == lcTrackTool::RotateTrainTrackRight)
{
Context->DrawIndexedPrimitives(GL_TRIANGLES, 96, GL_UNSIGNED_SHORT, (108 + 360 + 12 + 96) * 2);
Context->DrawIndexedPrimitives(GL_TRIANGLES, 72, GL_UNSIGNED_SHORT, (108 + 360 + 12 + 192) * 2);
Context->SetColor(0.8f, 0.8f, 0.0f, 1.0f);
Context->DrawIndexedPrimitives(GL_TRIANGLES, 96, GL_UNSIGNED_SHORT, (108 + 360 + 12) * 2);
@ -461,61 +494,22 @@ void lcViewManipulator::DrawTrainTrack(lcPiece* Piece, lcContext* Context, float
else if (TrackTool == lcTrackTool::RotateTrainTrackLeft)
{
Context->DrawIndexedPrimitives(GL_TRIANGLES, 96, GL_UNSIGNED_SHORT, (108 + 360 + 12) * 2);
Context->DrawIndexedPrimitives(GL_TRIANGLES, 72, GL_UNSIGNED_SHORT, (108 + 360 + 12 + 192) * 2);
Context->SetColor(0.8f, 0.8f, 0.0f, 1.0f);
Context->DrawIndexedPrimitives(GL_TRIANGLES, 96, GL_UNSIGNED_SHORT, (108 + 360 + 12 + 96) * 2);
}
else
else if (TrackTool == lcTrackTool::InsertTrainTrack)
{
Context->DrawIndexedPrimitives(GL_TRIANGLES, 192, GL_UNSIGNED_SHORT, (108 + 360 + 12) * 2);
}
}
for (quint32 ConnectionIndex = 0; ConnectionIndex < Connections.size(); ConnectionIndex++)
Context->SetColor(0.8f, 0.8f, 0.0f, 1.0f);
Context->DrawIndexedPrimitives(GL_TRIANGLES, 72, GL_UNSIGNED_SHORT, (108 + 360 + 12 + 192) * 2);
}
else
{
if (Piece->IsTrainTrackConnected(ConnectionIndex))
continue;
const lcMatrix44& Transform = Connections[ConnectionIndex].Transform;
lcVector3 Start = Transform.GetTranslation();
lcVector3 Direction = lcVector3(Transform[0]) * 100;
if (Piece->GetFocusSection() >= LC_PIECE_SECTION_TRAIN_TRACK_CONNECTION_FIRST)
{
quint32 FocusIndex = Piece->GetFocusSection() - LC_PIECE_SECTION_TRAIN_TRACK_CONNECTION_FIRST;
if (FocusIndex != ConnectionIndex)
continue;
Start = lcVector3(0.0f, 0.0f, 0.0f);
Direction = lcVector3(100.0f, 0.0f, 0.0f);
Context->DrawIndexedPrimitives(GL_TRIANGLES, 192 + 72, GL_UNSIGNED_SHORT, (108 + 360 + 12) * 2);
}
lcVector3 Verts[static_cast<int>(lcTrainTrackType::Count) * 2];
int NumVerts = 0;
Verts[NumVerts++] = Start / OverlayScale;
Verts[NumVerts++] = (Start + Direction) / OverlayScale;
Verts[NumVerts++] = Verts[0];
Verts[NumVerts++] = (Start + lcMul31(Direction, lcMatrix44RotationZ(LC_DTOR * 60))) / OverlayScale;
Verts[NumVerts++] = Verts[0];
Verts[NumVerts++] = (Start + lcMul31(Direction, lcMatrix44RotationZ(LC_DTOR * -60))) / OverlayScale;
Verts[NumVerts++] = Verts[0];
Verts[NumVerts++] = (Start + lcMul31(Direction, lcMatrix44RotationZ(LC_DTOR * 30))) / OverlayScale;
Verts[NumVerts++] = Verts[0];
Verts[NumVerts++] = (Start + lcMul31(Direction, lcMatrix44RotationZ(LC_DTOR * -30))) / 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);
}
}
@ -875,6 +869,7 @@ bool lcViewManipulator::IsTrackToolAllowed(lcTrackTool TrackTool, quint32 Allowe
case lcTrackTool::RotateTrainTrackRight:
case lcTrackTool::RotateTrainTrackLeft:
case lcTrackTool::InsertTrainTrack:
return true;
case lcTrackTool::ScalePlus:
@ -907,11 +902,13 @@ std::pair<lcTrackTool, quint32> lcViewManipulator::UpdateSelectMove()
const float OverlayMovePlaneSize = 0.5f * OverlayScale;
const float OverlayMoveArrowSize = 1.5f * OverlayScale;
const float OverlayMoveArrowCapRadius = 0.1f * OverlayScale;
const float OverlayArrowBodyRadius = 0.05f * OverlayScale;
const float OverlayRotateArrowStart = 1.0f * OverlayScale;
const float OverlayRotateArrowEnd = 1.5f * OverlayScale;
const float OverlayTrainTrackStart = 0.0f * OverlayScale;
const float OverlayTrainTrackEnd = 0.5f * OverlayScale;
const float OverlayTrainTrackDistance = 0.5f * OverlayScale;
const float OverlayTrainTrackInsert = 0.3f * OverlayScale;
const float OverlayScaleRadius = 0.125f;
lcTool CurrentTool = gMainWindow->GetTool();
@ -1113,43 +1110,14 @@ std::pair<lcTrackTool, quint32> lcViewManipulator::UpdateSelectMove()
ClosestIntersectionDistance = IntersectionDistance;
NewTrackSection = Piece->GetFocusSection() - LC_PIECE_SECTION_TRAIN_TRACK_CONNECTION_FIRST;
}
}
}
ActiveModel->UpdateTrainTrackConnections(Piece);
const std::vector<lcTrainTrackConnection>& Connections = TrainTrackInfo->GetConnections();
for (quint32 ConnectionIndex = 0; ConnectionIndex < Connections.size(); ConnectionIndex++)
if (Proj1 > -OverlayTrainTrackInsert + OverlayTrainTrackEnd - OverlayArrowBodyRadius && Proj1 < OverlayTrainTrackInsert + OverlayTrainTrackEnd - OverlayArrowBodyRadius && Proj2 > -OverlayTrainTrackInsert && Proj2 < OverlayTrainTrackInsert)
{
if (Piece->IsTrainTrackConnected(ConnectionIndex))
continue;
const lcMatrix44& Transform = Connections[ConnectionIndex].Transform;
lcVector3 Verts[static_cast<int>(lcTrainTrackType::Count)];
int NumVerts = 0;
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++)
{
Verts[VertexIndex] = lcMul31(Verts[VertexIndex], WorldMatrix);
float IntersectionDistance = lcRayPointDistance(Verts[VertexIndex], Start, End);
if (IntersectionDistance < 40)
{
if (IntersectionDistance > ClosestIntersectionDistance)
continue;
NewTrackTool = lcTrackTool::Insert;
NewTrackTool = lcTrackTool::InsertTrainTrack;
ClosestIntersectionDistance = IntersectionDistance;
NewTrackSection = lcTrainTrackInfo::EncodeTrackToolSection(ConnectionIndex, static_cast<lcTrainTrackType>(VertexIndex));
NewTrackSection = Piece->GetFocusSection() - LC_PIECE_SECTION_TRAIN_TRACK_CONNECTION_FIRST;
}
}
}
}

View file

@ -17,7 +17,7 @@ public:
static void DestroyResources(lcContext* Context);
protected:
void DrawTrainTrack(lcPiece* Piece, lcContext* Context, float OverlayScale, lcTrackTool TrackTool);
void DrawTrainTrack(lcPiece* Piece, lcContext* Context, lcTrackTool TrackTool);
static bool IsTrackToolAllowed(lcTrackTool TrackTool, quint32 AllowedTransforms);