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_glextensions.h"
#include "lc_synth.h" #include "lc_synth.h"
#include "lc_traintrack.h" #include "lc_traintrack.h"
#include "lc_traintrack.h"
#include "project.h" #include "project.h"
#include "lc_profile.h" #include "lc_profile.h"
#include "lc_meshloader.h" #include "lc_meshloader.h"
@ -1807,6 +1808,17 @@ void lcPiecesLibrary::GetParts(std::vector<PieceInfo*>& Parts) const
Parts.emplace_back(PartIt.second); 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*> lcPiecesLibrary::GetPartsFromSet(const std::vector<std::string>& PartIds) const
{ {
std::vector<PieceInfo*> Parts; std::vector<PieceInfo*> Parts;

View file

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

View file

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

View file

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

View file

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

View file

@ -233,6 +233,28 @@ void lcPartSelectionListModel::SetCurrentModelCategory()
SetFilter(mFilter); 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) void lcPartSelectionListModel::SetFilter(const QString& Filter)
{ {
mFilter = Filter.toLatin1(); mFilter = Filter.toLatin1();
@ -511,12 +533,8 @@ void lcPartSelectionListModel::SetShowPartNames(bool Show)
} }
lcPartSelectionListView::lcPartSelectionListView(QWidget* Parent, lcPartSelectionWidget* PartSelectionWidget) lcPartSelectionListView::lcPartSelectionListView(QWidget* Parent, lcPartSelectionWidget* PartSelectionWidget)
: QListView(Parent) : QListView(Parent), mPartSelectionWidget(PartSelectionWidget)
{ {
mPartSelectionWidget = PartSelectionWidget;
mCategoryType = lcPartCategoryType::AllParts;
mCategoryIndex = 0;
setUniformItemSizes(true); setUniformItemSizes(true);
setResizeMode(QListView::Adjust); setResizeMode(QListView::Adjust);
setWordWrap(false); setWordWrap(false);
@ -535,6 +553,9 @@ lcPartSelectionListView::lcPartSelectionListView(QWidget* Parent, lcPartSelectio
void lcPartSelectionListView::CustomContextMenuRequested(QPoint Pos) void lcPartSelectionListView::CustomContextMenuRequested(QPoint Pos)
{ {
if (!mPartSelectionWidget)
return;
QMenu* Menu = new QMenu(this); QMenu* Menu = new QMenu(this);
QModelIndex Index = indexAt(Pos); QModelIndex Index = indexAt(Pos);
@ -584,6 +605,7 @@ void lcPartSelectionListView::SetCategory(lcPartCategoryType Type, int Index)
case lcPartCategoryType::Category: case lcPartCategoryType::Category:
mListModel->SetCategory(Index); mListModel->SetCategory(Index);
break; break;
case lcPartCategoryType::Custom:
case lcPartCategoryType::Count: case lcPartCategoryType::Count:
break; break;
} }
@ -591,6 +613,15 @@ void lcPartSelectionListView::SetCategory(lcPartCategoryType Type, int Index)
setCurrentIndex(mListModel->index(0, 0)); 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) void lcPartSelectionListView::SetCurrentPart(PieceInfo* Info)
{ {
QModelIndex Index = mListModel->GetPieceInfoIndex(Info); QModelIndex Index = mListModel->GetPieceInfoIndex(Info);

View file

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

View file

@ -25,25 +25,11 @@ class lcTrainTrackInfo
public: public:
lcTrainTrackInfo() = default; 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> GetPieceInsertTransform(lcPiece* CurrentPiece, PieceInfo* Info);
static std::optional<lcMatrix44> GetConnectionTransform(lcPiece* CurrentPiece, quint32 CurrentConnectionIndex, PieceInfo* Info, quint32 NewConnectionIndex); 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 std::optional<lcMatrix44> CalculateTransformToConnection(const lcMatrix44& ConnectionTransform, PieceInfo* Info, quint32 ConnectionIndex);
static int GetPieceConnectionIndex(const lcPiece* Piece1, int ConnectionIndex1, const lcPiece* Piece2); 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) void AddConnection(const lcTrainTrackConnection& TrainTrackConnection)
{ {
mConnections.emplace_back(TrainTrackConnection); mConnections.emplace_back(TrainTrackConnection);

View file

@ -17,6 +17,7 @@
#include "lc_viewsphere.h" #include "lc_viewsphere.h"
#include "lc_findreplacewidget.h" #include "lc_findreplacewidget.h"
#include "lc_library.h" #include "lc_library.h"
#include "lc_partselectionwidget.h"
lcFindReplaceParams lcView::mFindReplaceParams; lcFindReplaceParams lcView::mFindReplaceParams;
QPointer<lcFindReplaceWidget> lcView::mFindWidget; QPointer<lcFindReplaceWidget> lcView::mFindWidget;
@ -304,6 +305,45 @@ lcMatrix44 lcView::GetTileProjectionMatrix(int CurrentRow, int CurrentColumn, in
return lcMatrix44Frustum(Left, Right, Bottom, Top, Near, Far); 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 void lcView::ShowContextMenu() const
{ {
if (mViewType != lcViewType::View) if (mViewType != lcViewType::View)
@ -421,39 +461,14 @@ lcVector3 lcView::GetMoveDirection(const lcVector3& Direction) const
void lcView::UpdatePiecePreview() void lcView::UpdatePiecePreview()
{ {
lcModel* ActiveModel = GetActiveModel(); PieceInfo* PreviewInfo = gMainWindow->GetCurrentPieceInfo();
lcObject* Focus = ActiveModel->GetFocusObject();
PieceInfo* PreviewInfo = nullptr;
lcMatrix44 PreviewTransform;
if (Focus && Focus->IsPiece()) if (PreviewInfo)
{ {
lcPiece* Piece = (lcPiece*)Focus; mPiecePreviewTransform = GetPieceInsertTransform(false, PreviewInfo);
const lcTrainTrackInfo* TrainTrackInfo = Piece->mPieceInfo->GetTrainTrackInfo(); if (GetActiveModel() != mModel)
mPiecePreviewTransform = lcMul(mPiecePreviewTransform, mActiveSubmodelTransform);
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();
if (PreviewInfo)
{
mPiecePreviewTransform = GetPieceInsertTransform(false, PreviewInfo);
if (GetActiveModel() != mModel)
mPiecePreviewTransform = lcMul(mPiecePreviewTransform, mActiveSubmodelTransform);
}
} }
if (PreviewInfo != mPiecePreviewInfo) if (PreviewInfo != mPiecePreviewInfo)
@ -1927,8 +1942,9 @@ lcCursor lcView::GetCursor() const
lcCursor::Rotate, // lcTrackTool::RotateZ lcCursor::Rotate, // lcTrackTool::RotateZ
lcCursor::Rotate, // lcTrackTool::RotateXY lcCursor::Rotate, // lcTrackTool::RotateXY
lcCursor::Rotate, // lcTrackTool::RotateXYZ lcCursor::Rotate, // lcTrackTool::RotateXYZ
lcCursor::Rotate, // lcTrackTool::RotateTrainTrackRight lcCursor::Select, // lcTrackTool::RotateTrainTrackRight
lcCursor::Rotate, // lcTrackTool::RotateTrainTrackLeft lcCursor::Select, // lcTrackTool::RotateTrainTrackLeft
lcCursor::Select, // lcTrackTool::InsertTrainTrack
lcCursor::Move, // lcTrackTool::ScalePlus lcCursor::Move, // lcTrackTool::ScalePlus
lcCursor::Move, // lcTrackTool::ScaleMinus lcCursor::Move, // lcTrackTool::ScaleMinus
lcCursor::Delete, // lcTrackTool::Eraser lcCursor::Delete, // lcTrackTool::Eraser
@ -2040,6 +2056,7 @@ lcTool lcView::GetCurrentTool() const
lcTool::Rotate, // lcTrackTool::RotateXYZ lcTool::Rotate, // lcTrackTool::RotateXYZ
lcTool::Rotate, // lcTrackTool::RotateTrainTrackRight lcTool::Rotate, // lcTrackTool::RotateTrainTrackRight
lcTool::Rotate, // lcTrackTool::RotateTrainTrackLeft lcTool::Rotate, // lcTrackTool::RotateTrainTrackLeft
lcTool::Insert, // lcTrackTool::InsertTrainTrack
lcTool::Move, // lcTrackTool::ScalePlus lcTool::Move, // lcTrackTool::ScalePlus
lcTool::Move, // lcTrackTool::ScaleMinus lcTool::Move, // lcTrackTool::ScaleMinus
lcTool::Eraser, // lcTrackTool::Eraser lcTool::Eraser, // lcTrackTool::Eraser
@ -2579,6 +2596,15 @@ void lcView::OnButtonDown(lcTrackButton TrackButton)
} }
break; break;
case lcTrackTool::InsertTrainTrack:
{
ShowTrainTrackPopup();
mToolClicked = true;
UpdateTrackTool();
}
break;
case lcTrackTool::ScalePlus: case lcTrackTool::ScalePlus:
case lcTrackTool::ScaleMinus: case lcTrackTool::ScaleMinus:
if (ActiveModel->AnyPiecesSelected()) if (ActiveModel->AnyPiecesSelected())
@ -3024,6 +3050,7 @@ void lcView::OnMouseMove()
case lcTrackTool::RotateTrainTrackRight: case lcTrackTool::RotateTrainTrackRight:
case lcTrackTool::RotateTrainTrackLeft: case lcTrackTool::RotateTrainTrackLeft:
case lcTrackTool::InsertTrainTrack:
case lcTrackTool::Eraser: case lcTrackTool::Eraser:
case lcTrackTool::Paint: case lcTrackTool::Paint:
case lcTrackTool::ColorPicker: case lcTrackTool::ColorPicker:

View file

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

View file

@ -21,7 +21,7 @@ lcViewManipulator::lcViewManipulator(lcView* View)
void lcViewManipulator::CreateResources(lcContext* Context) void lcViewManipulator::CreateResources(lcContext* Context)
{ {
float Verts[(51 + 138 + 10 + 74) * 3]; float Verts[(51 + 138 + 10 + 74 + 28) * 3];
float* CurVert = Verts; float* CurVert = Verts;
const float OverlayMovePlaneSize = 0.5f; const float OverlayMovePlaneSize = 0.5f;
@ -146,6 +146,7 @@ void lcViewManipulator::CreateResources(lcContext* Context)
const float OverlayTrainTrackEnd = 0.5f; const float OverlayTrainTrackEnd = 0.5f;
const float OverlayTrainTrackCenter = 0.2f; const float OverlayTrainTrackCenter = 0.2f;
const float OverlayTrainTrackDistance = 0.5f; const float OverlayTrainTrackDistance = 0.5f;
const float OverlayTrainTrackInsert = 0.3f;
// Train Track Rotate Right // Train Track Rotate Right
*CurVert++ = OverlayTrainTrackStart; *CurVert++ = OverlayTrainTrackEnd + OverlayTrainTrackDistance - OverlayArrowCapRadius; *CurVert++ = 0.0f; *CurVert++ = OverlayTrainTrackStart; *CurVert++ = OverlayTrainTrackEnd + OverlayTrainTrackDistance - OverlayArrowCapRadius; *CurVert++ = 0.0f;
@ -194,7 +195,38 @@ void lcViewManipulator::CreateResources(lcContext* Context)
*CurVert = *(CurVert - 111); CurVert++; *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 // 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, 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 // 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, 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, 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); mRotateMoveVertexBuffer = Context->CreateVertexBuffer(sizeof(Verts), Verts);
@ -432,18 +467,15 @@ void lcViewManipulator::DrawSelectMove(lcTrackButton TrackButton, lcTrackTool Tr
} }
else if (Piece->mPieceInfo->GetTrainTrackInfo()) else if (Piece->mPieceInfo->GetTrainTrackInfo())
{ {
DrawTrainTrack(Piece, Context, OverlayScale, TrackTool); DrawTrainTrack(Piece, Context, TrackTool);
} }
} }
Context->EnableDepthTest(true); 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) if (Piece->GetFocusSection() >= LC_PIECE_SECTION_TRAIN_TRACK_CONNECTION_FIRST)
{ {
const lcPreferences& Preferences = lcGetPreferences(); const lcPreferences& Preferences = lcGetPreferences();
@ -454,6 +486,7 @@ void lcViewManipulator::DrawTrainTrack(lcPiece* Piece, lcContext* Context, float
if (TrackTool == lcTrackTool::RotateTrainTrackRight) if (TrackTool == lcTrackTool::RotateTrainTrackRight)
{ {
Context->DrawIndexedPrimitives(GL_TRIANGLES, 96, GL_UNSIGNED_SHORT, (108 + 360 + 12 + 96) * 2); 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->SetColor(0.8f, 0.8f, 0.0f, 1.0f);
Context->DrawIndexedPrimitives(GL_TRIANGLES, 96, GL_UNSIGNED_SHORT, (108 + 360 + 12) * 2); 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) else if (TrackTool == lcTrackTool::RotateTrainTrackLeft)
{ {
Context->DrawIndexedPrimitives(GL_TRIANGLES, 96, GL_UNSIGNED_SHORT, (108 + 360 + 12) * 2); 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->SetColor(0.8f, 0.8f, 0.0f, 1.0f);
Context->DrawIndexedPrimitives(GL_TRIANGLES, 96, GL_UNSIGNED_SHORT, (108 + 360 + 12 + 96) * 2); 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); Context->DrawIndexedPrimitives(GL_TRIANGLES, 192, GL_UNSIGNED_SHORT, (108 + 360 + 12) * 2);
Context->SetColor(0.8f, 0.8f, 0.0f, 1.0f);
Context->DrawIndexedPrimitives(GL_TRIANGLES, 72, GL_UNSIGNED_SHORT, (108 + 360 + 12 + 192) * 2);
} }
} else
for (quint32 ConnectionIndex = 0; ConnectionIndex < Connections.size(); ConnectionIndex++)
{
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; Context->DrawIndexedPrimitives(GL_TRIANGLES, 192 + 72, GL_UNSIGNED_SHORT, (108 + 360 + 12) * 2);
if (FocusIndex != ConnectionIndex)
continue;
Start = lcVector3(0.0f, 0.0f, 0.0f);
Direction = lcVector3(100.0f, 0.0f, 0.0f);
} }
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::RotateTrainTrackRight:
case lcTrackTool::RotateTrainTrackLeft: case lcTrackTool::RotateTrainTrackLeft:
case lcTrackTool::InsertTrainTrack:
return true; return true;
case lcTrackTool::ScalePlus: case lcTrackTool::ScalePlus:
@ -907,11 +902,13 @@ std::pair<lcTrackTool, quint32> lcViewManipulator::UpdateSelectMove()
const float OverlayMovePlaneSize = 0.5f * OverlayScale; const float OverlayMovePlaneSize = 0.5f * OverlayScale;
const float OverlayMoveArrowSize = 1.5f * OverlayScale; const float OverlayMoveArrowSize = 1.5f * OverlayScale;
const float OverlayMoveArrowCapRadius = 0.1f * OverlayScale; const float OverlayMoveArrowCapRadius = 0.1f * OverlayScale;
const float OverlayArrowBodyRadius = 0.05f * OverlayScale;
const float OverlayRotateArrowStart = 1.0f * OverlayScale; const float OverlayRotateArrowStart = 1.0f * OverlayScale;
const float OverlayRotateArrowEnd = 1.5f * OverlayScale; const float OverlayRotateArrowEnd = 1.5f * OverlayScale;
const float OverlayTrainTrackStart = 0.0f * OverlayScale; const float OverlayTrainTrackStart = 0.0f * OverlayScale;
const float OverlayTrainTrackEnd = 0.5f * OverlayScale; const float OverlayTrainTrackEnd = 0.5f * OverlayScale;
const float OverlayTrainTrackDistance = 0.5f * OverlayScale; const float OverlayTrainTrackDistance = 0.5f * OverlayScale;
const float OverlayTrainTrackInsert = 0.3f * OverlayScale;
const float OverlayScaleRadius = 0.125f; const float OverlayScaleRadius = 0.125f;
lcTool CurrentTool = gMainWindow->GetTool(); lcTool CurrentTool = gMainWindow->GetTool();
@ -1113,43 +1110,14 @@ std::pair<lcTrackTool, quint32> lcViewManipulator::UpdateSelectMove()
ClosestIntersectionDistance = IntersectionDistance; ClosestIntersectionDistance = IntersectionDistance;
NewTrackSection = Piece->GetFocusSection() - LC_PIECE_SECTION_TRAIN_TRACK_CONNECTION_FIRST; NewTrackSection = Piece->GetFocusSection() - LC_PIECE_SECTION_TRAIN_TRACK_CONNECTION_FIRST;
} }
}
}
ActiveModel->UpdateTrainTrackConnections(Piece); if (Proj1 > -OverlayTrainTrackInsert + OverlayTrainTrackEnd - OverlayArrowBodyRadius && Proj1 < OverlayTrainTrackInsert + OverlayTrainTrackEnd - OverlayArrowBodyRadius && Proj2 > -OverlayTrainTrackInsert && Proj2 < OverlayTrainTrackInsert)
const std::vector<lcTrainTrackConnection>& Connections = TrainTrackInfo->GetConnections();
for (quint32 ConnectionIndex = 0; ConnectionIndex < Connections.size(); ConnectionIndex++)
{
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) NewTrackTool = lcTrackTool::InsertTrainTrack;
continue;
NewTrackTool = lcTrackTool::Insert;
ClosestIntersectionDistance = IntersectionDistance; 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); static void DestroyResources(lcContext* Context);
protected: 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); static bool IsTrackToolAllowed(lcTrackTool TrackTool, quint32 AllowedTransforms);