Skip to content

Commit

Permalink
Added train track gizmo.
Browse files Browse the repository at this point in the history
  • Loading branch information
leozide committed Nov 3, 2024
1 parent bf3f1d5 commit ed29dad
Show file tree
Hide file tree
Showing 12 changed files with 349 additions and 40 deletions.
3 changes: 3 additions & 0 deletions common/lc_library.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "lc_context.h"
#include "lc_glextensions.h"
#include "lc_synth.h"
#include "lc_traintrack.h"
#include "project.h"
#include "lc_profile.h"
#include "lc_meshloader.h"
Expand Down Expand Up @@ -277,6 +278,7 @@ bool lcPiecesLibrary::Load(const QString& LibraryPath, bool ShowProgress)
UpdateStudStyleSource();
lcLoadDefaultCategories();
lcSynthInit();
lcTrainTrackInit(this);

return true;
}
Expand Down Expand Up @@ -1870,6 +1872,7 @@ bool lcPiecesLibrary::LoadBuiltinPieces()
lcLoadDefaultColors(lcStudStyle::Plain);
lcLoadDefaultCategories(true);
lcSynthInit();
lcTrainTrackInit(this);

return true;
}
4 changes: 2 additions & 2 deletions common/lc_model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4233,9 +4233,9 @@ void lcModel::EndMouseTool(lcTool Tool, bool Accept)
}
}

void lcModel::InsertPieceToolClicked(const lcMatrix44& WorldMatrix)
void lcModel::InsertPieceToolClicked(PieceInfo* Info, const lcMatrix44& WorldMatrix)
{
lcPiece* Piece = new lcPiece(gMainWindow->GetCurrentPieceInfo());
lcPiece* Piece = new lcPiece(Info);
Piece->Initialize(WorldMatrix, mCurrentStep);
Piece->SetColorIndex(gMainWindow->mColorIndex);
Piece->UpdatePosition(mCurrentStep);
Expand Down
2 changes: 1 addition & 1 deletion common/lc_model.h
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ class lcModel

void BeginMouseTool();
void EndMouseTool(lcTool Tool, bool Accept);
void InsertPieceToolClicked(const lcMatrix44& WorldMatrix);
void InsertPieceToolClicked(PieceInfo* Info, const lcMatrix44& WorldMatrix);
void InsertLightToolClicked(const lcVector3& Position, lcLightType LightType);
void BeginCameraTool(const lcVector3& Position, const lcVector3& Target);
void UpdateCameraTool(const lcVector3& Position);
Expand Down
113 changes: 113 additions & 0 deletions common/lc_traintrack.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
#include "lc_global.h"
#include "lc_traintrack.h"
#include "lc_library.h"
#include "pieceinf.h"
#include "piece.h"
#include "lc_application.h"

// todo:
// add cross 32087.dat and auto replace when going over a straight section
// draw icon on thumbnails
// detect existing connections
// new gizmo mesh
// move config to json
// add other track types

std::pair<PieceInfo*, lcMatrix44> lcTrainTrackInfo::GetPieceInsertPosition(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 };
}

void lcTrainTrackInit(lcPiecesLibrary* Library)
{
PieceInfo* Info = Library->FindPiece("74746.dat", nullptr, false, false);

if (Info)
{
lcTrainTrackInfo* TrainTrackInfo = new lcTrainTrackInfo();

TrainTrackInfo->AddConnection({lcMatrix44Translation(lcVector3(160.0f, 0.0f, 0.0f))});
TrainTrackInfo->AddConnection({lcMatrix44(lcMatrix33RotationZ(LC_PI), lcVector3(-160.0f, 0.0f, 0.0f))});

Info->SetTrainTrackInfo(TrainTrackInfo);
}

Info = Library->FindPiece("74747.dat", nullptr, false, false);

if (Info)
{
lcTrainTrackInfo* TrainTrackInfo = new lcTrainTrackInfo();

const float CurveX = sinf(LC_DTOR * 11.25f) * 800.0f;
const float CurveY = (cosf(LC_DTOR * 11.25f) * 800.0f) - 800.0f;

TrainTrackInfo->AddConnection({lcMatrix44(lcMatrix33RotationZ(-11.25f * LC_DTOR), lcVector3(CurveX, CurveY, 0.0f))});
TrainTrackInfo->AddConnection({lcMatrix44(lcMatrix33RotationZ(-168.75f * LC_DTOR), lcVector3(-CurveX, CurveY, 0.0f))});

Info->SetTrainTrackInfo(TrainTrackInfo);
}

const float BranchX = 320.0f + 320.0f + (-(sinf(LC_DTOR * 22.5f) * 800.0f));
const float BranchY = 320.0f + ((cosf(LC_DTOR * 22.5f) * 800.0f) - 800.0f);

Info = Library->FindPiece("2861c04.dat", nullptr, false, false);

if (Info)
{
lcTrainTrackInfo* TrainTrackInfo = new lcTrainTrackInfo();

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);
}

Info = Library->FindPiece("2859c04.dat", nullptr, false, false);

if (Info)
{
lcTrainTrackInfo* TrainTrackInfo = new lcTrainTrackInfo();

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);
}
}
44 changes: 44 additions & 0 deletions common/lc_traintrack.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#pragma once

#include "lc_math.h"

class lcPiece;
class lcPiecesLibrary;

struct lcTrainTrackConnection
{
lcMatrix44 Transform;
};

enum class lcTrainTrackType
{
Straight,
Left,
Right,
BranchLeft,
BranchRight,
Count
};

class lcTrainTrackInfo
{
public:
lcTrainTrackInfo() = default;

std::pair<PieceInfo*, lcMatrix44> GetPieceInsertPosition(lcPiece* Piece, quint32 ConnectionIndex, lcTrainTrackType TrainTrackType) const;

void AddConnection(const lcTrainTrackConnection& TrainTrackConnection)
{
mConnections.emplace_back(TrainTrackConnection);
}

const std::vector<lcTrainTrackConnection>& GetConnections() const
{
return mConnections;
}

protected:
std::vector<lcTrainTrackConnection> mConnections;
};

void lcTrainTrackInit(lcPiecesLibrary* Library);
94 changes: 73 additions & 21 deletions common/lc_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@
#include "piece.h"
#include "pieceinf.h"
#include "lc_synth.h"
#include "lc_traintrack.h"
#include "lc_scene.h"
#include "lc_context.h"
#include "lc_viewmanipulator.h"
#include "lc_viewsphere.h"
#include "lc_findreplacewidget.h"
#include "lc_library.h"

lcFindReplaceParams lcView::mFindReplaceParams;
QPointer<lcFindReplaceWidget> lcView::mFindWidget;
Expand Down Expand Up @@ -48,6 +50,13 @@ lcView::lcView(lcViewType ViewType, lcModel* Model)

lcView::~lcView()
{
if (mPiecePreviewInfo)
{
lcPiecesLibrary* Library = lcGetPiecesLibrary();
Library->ReleasePieceInfo(mPiecePreviewInfo);
mPiecePreviewInfo = nullptr;
}

mContext->DestroyVertexBuffer(mGridBuffer);

if (gMainWindow && mViewType == lcViewType::View)
Expand Down Expand Up @@ -410,6 +419,55 @@ lcVector3 lcView::GetMoveDirection(const lcVector3& Direction) const
return axis;
}

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)
{
quint32 ConnectionIndex = mTrackToolSection & 0xff;
lcTrainTrackType TrainTrackType = static_cast<lcTrainTrackType>((mTrackToolSection >> 8) & 0xff);

std::tie(PreviewInfo, mPiecePreviewTransform) = TrainTrackInfo->GetPieceInsertPosition(Piece, ConnectionIndex, TrainTrackType);
}
}

if (!PreviewInfo)
{
PreviewInfo = gMainWindow->GetCurrentPieceInfo();

if (PreviewInfo)
{
mPiecePreviewTransform = GetPieceInsertPosition(false, PreviewInfo);

if (GetActiveModel() != mModel)
mPiecePreviewTransform = lcMul(mPiecePreviewTransform, mActiveSubmodelTransform);
}
}

if (PreviewInfo != mPiecePreviewInfo)
{
lcPiecesLibrary* Library = lcGetPiecesLibrary();

if (mPiecePreviewInfo)
Library->ReleasePieceInfo(mPiecePreviewInfo);

mPiecePreviewInfo = PreviewInfo;

if (mPiecePreviewInfo)
Library->LoadPieceInfo(mPiecePreviewInfo, true, true);
}
}

lcMatrix44 lcView::GetPieceInsertPosition(bool IgnoreSelected, PieceInfo* Info) const
{
lcModel* ActiveModel = GetActiveModel();
Expand Down Expand Up @@ -812,16 +870,11 @@ void lcView::OnDraw()

if (DrawInterface && mTrackTool == lcTrackTool::Insert)
{
PieceInfo* Info = gMainWindow->GetCurrentPieceInfo();
UpdatePiecePreview();

if (Info)
if (mPiecePreviewInfo)
{
lcMatrix44 WorldMatrix = GetPieceInsertPosition(false, Info);

if (GetActiveModel() != mModel)
WorldMatrix = lcMul(WorldMatrix, mActiveSubmodelTransform);

Info->AddRenderMeshes(mScene.get(), WorldMatrix, gMainWindow->mColorIndex, lcRenderMeshState::Focused, false);
mPiecePreviewInfo->AddRenderMeshes(mScene.get(), mPiecePreviewTransform, gMainWindow->mColorIndex, lcRenderMeshState::Focused, false);
}
}

Expand Down Expand Up @@ -1389,18 +1442,14 @@ void lcView::DrawGrid()

if (mTrackTool == lcTrackTool::Insert)
{
PieceInfo* CurPiece = gMainWindow->GetCurrentPieceInfo();

if (CurPiece)
if (mPiecePreviewInfo)
{
lcVector3 Points[8];
lcGetBoxCorners(CurPiece->GetBoundingBox(), Points);

lcMatrix44 WorldMatrix = GetPieceInsertPosition(false, CurPiece);
lcGetBoxCorners(mPiecePreviewInfo->GetBoundingBox(), Points);

for (int i = 0; i < 8; i++)
{
lcVector3 Point = lcMul31(Points[i], WorldMatrix);
lcVector3 Point = lcMul31(Points[i], mPiecePreviewTransform);

Min = lcMin(Point, Min);
Max = lcMax(Point, Max);
Expand Down Expand Up @@ -1654,8 +1703,9 @@ void lcView::EndDrag(bool Accept)
case lcDragState::Piece:
{
PieceInfo* Info = gMainWindow->GetCurrentPieceInfo();

if (Info)
ActiveModel->InsertPieceToolClicked(GetPieceInsertPosition(false, Info));
ActiveModel->InsertPieceToolClicked(Info, GetPieceInsertPosition(false, Info));
} break;

case lcDragState::Color:
Expand Down Expand Up @@ -2012,6 +2062,7 @@ void lcView::UpdateTrackTool()

lcTool CurrentTool = gMainWindow->GetTool();
lcTrackTool NewTrackTool = mTrackTool;
quint32 NewTrackSection = ~0U;
int x = mMouseX;
int y = mMouseY;
bool Redraw = false;
Expand Down Expand Up @@ -2048,9 +2099,10 @@ void lcView::UpdateTrackTool()
case lcTool::Move:
{
mMouseDownPiece = nullptr;
NewTrackTool = mViewManipulator->UpdateSelectMove();
std::tie(NewTrackTool, NewTrackSection) = mViewManipulator->UpdateSelectMove();
mTrackToolFromOverlay = NewTrackTool != lcTrackTool::MoveXYZ && NewTrackTool != lcTrackTool::Select;
Redraw = NewTrackTool != mTrackTool;
Redraw = NewTrackTool != mTrackTool || NewTrackSection != mTrackToolSection;
mTrackToolSection = NewTrackSection;

if (CurrentTool == lcTool::Select && NewTrackTool == lcTrackTool::Select && mMouseModifiers == Qt::NoModifier)
{
Expand Down Expand Up @@ -2433,12 +2485,12 @@ void lcView::OnButtonDown(lcTrackButton TrackButton)

case lcTrackTool::Insert:
{
PieceInfo* CurPiece = gMainWindow->GetCurrentPieceInfo();
UpdatePiecePreview();

if (!CurPiece)
if (!mPiecePreviewInfo)
break;

ActiveModel->InsertPieceToolClicked(GetPieceInsertPosition(false, gMainWindow->GetCurrentPieceInfo()));
ActiveModel->InsertPieceToolClicked(mPiecePreviewInfo, mPiecePreviewTransform);

if ((mMouseModifiers & Qt::ControlModifier) == 0)
gMainWindow->SetTool(lcTool::Select);
Expand Down
Loading

0 comments on commit ed29dad

Please sign in to comment.