Added rotate train track gizmo.
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-17 19:20:38 -08:00
parent 5e0df56351
commit 4f2782b407
10 changed files with 207 additions and 171 deletions

View file

@ -2941,7 +2941,7 @@ void lcMainWindow::HandleCommand(lcCommandId CommandId)
case LC_PIECE_TRAIN_TRACK_ROTATE:
if (ActiveModel)
ActiveModel->RotateFocusedTrainTrack();
ActiveModel->RotateFocusedTrainTrack(1);
break;
case LC_PIECE_MOVE_PLUSX:

View file

@ -2429,7 +2429,7 @@ void lcModel::FocusPreviousTrainTrack()
UpdateAllViews();
}
void lcModel::RotateFocusedTrainTrack()
void lcModel::RotateFocusedTrainTrack(int Direction)
{
const lcObject* Focus = GetFocusObject();
@ -2472,7 +2472,7 @@ void lcModel::RotateFocusedTrainTrack()
}
lcMatrix44 ConnectionTransform = lcMul(TrainTrackInfo->GetConnections()[RotateConnectionIndex].Transform, FocusPiece->mModelWorld);
int NewConnectionIndex = (RotateConnectionIndex + 1) % TrainTrackInfo->GetConnections().size();
int NewConnectionIndex = (RotateConnectionIndex + Direction + static_cast<int>(TrainTrackInfo->GetConnections().size())) % TrainTrackInfo->GetConnections().size();
Transform = lcTrainTrackInfo::CalculateTransformToConnection(ConnectionTransform, FocusPiece->mPieceInfo, NewConnectionIndex);
@ -4525,54 +4525,6 @@ void lcModel::UpdateRotateTool(const lcVector3& Angles, bool AlternateButtonDrag
UpdateAllViews();
}
void lcModel::RotateTrainTrackToolClicked(quint32 ConnectionIndex)
{
const lcObject* Focus = GetFocusObject();
if (!Focus || !Focus->IsPiece())
return;
lcPiece* FocusPiece = (lcPiece*)Focus;
const lcTrainTrackInfo* TrainTrackInfo = FocusPiece->mPieceInfo->GetTrainTrackInfo();
if (!TrainTrackInfo)
return;
lcPiece* ConnectedPiece = nullptr;
int ConnectedPieceConnectionIndex = -1;
for (const std::unique_ptr<lcPiece>& Piece : mPieces)
{
if (Piece.get() == FocusPiece || !Piece->mPieceInfo->GetTrainTrackInfo())
continue;
ConnectedPieceConnectionIndex = lcTrainTrackInfo::GetPieceConnectionIndex(FocusPiece, ConnectionIndex, Piece.get());
if (ConnectedPieceConnectionIndex != -1)
{
ConnectedPiece = Piece.get();
break;
}
}
if (!ConnectedPiece)
return;
quint32 NewConnectionIndex = (ConnectionIndex + 1) % TrainTrackInfo->GetConnections().size();
std::optional<lcMatrix44> Transform = lcTrainTrackInfo::GetConnectionTransform(ConnectedPiece, ConnectedPieceConnectionIndex, FocusPiece->mPieceInfo, NewConnectionIndex);
if (!Transform)
return;
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::UpdateScaleTool(const float Scale)
{
ScaleSelectedPieces(Scale, true, false);

View file

@ -218,7 +218,7 @@ public:
void RemoveFocusedControlPoint();
void FocusNextTrainTrack();
void FocusPreviousTrainTrack();
void RotateFocusedTrainTrack();
void RotateFocusedTrainTrack(int Direction);
void ShowSelectedPiecesEarlier();
void ShowSelectedPiecesLater();
void SetPieceSteps(const std::vector<std::pair<lcPiece*, lcStep>>& PieceSteps);
@ -339,7 +339,6 @@ public:
void UpdateCameraTool(const lcVector3& Position);
void UpdateMoveTool(const lcVector3& Distance, bool AllowRelative, bool AlternateButtonDrag);
void UpdateRotateTool(const lcVector3& Angles, bool AlternateButtonDrag);
void RotateTrainTrackToolClicked(quint32 ConnectionIndex);
void UpdateScaleTool(const float Scale);
void EraserToolClicked(lcObject* Object);
void PaintToolClicked(lcObject* Object);

View file

@ -9,9 +9,6 @@
// auto replace cross when going over a straight section
// redo gizmo
// add cross to gizmo
// new rotate connection gizmo
// rotate around connections shortcut
// shortcuts for changing active connection
// move config to json
// add other track types
// set focus connection after adding

View file

@ -1927,7 +1927,8 @@ lcCursor lcView::GetCursor() const
lcCursor::Rotate, // lcTrackTool::RotateZ
lcCursor::Rotate, // lcTrackTool::RotateXY
lcCursor::Rotate, // lcTrackTool::RotateXYZ
lcCursor::Rotate, // lcTrackTool::RotateTrainTrack
lcCursor::Rotate, // lcTrackTool::RotateTrainTrackRight
lcCursor::Rotate, // lcTrackTool::RotateTrainTrackLeft
lcCursor::Move, // lcTrackTool::ScalePlus
lcCursor::Move, // lcTrackTool::ScaleMinus
lcCursor::Delete, // lcTrackTool::Eraser
@ -2037,7 +2038,8 @@ lcTool lcView::GetCurrentTool() const
lcTool::Rotate, // lcTrackTool::RotateZ
lcTool::Rotate, // lcTrackTool::RotateXY
lcTool::Rotate, // lcTrackTool::RotateXYZ
lcTool::Rotate, // lcTrackTool::RotateTrainTrack
lcTool::Rotate, // lcTrackTool::RotateTrainTrackRight
lcTool::Rotate, // lcTrackTool::RotateTrainTrackLeft
lcTool::Move, // lcTrackTool::ScalePlus
lcTool::Move, // lcTrackTool::ScaleMinus
lcTool::Eraser, // lcTrackTool::Eraser
@ -2567,18 +2569,16 @@ void lcView::OnButtonDown(lcTrackButton TrackButton)
StartTracking(TrackButton);
break;
case lcTrackTool::RotateTrainTrack:
case lcTrackTool::RotateTrainTrackRight:
case lcTrackTool::RotateTrainTrackLeft:
{
auto [ConnectionIndex, TrainTrackType] = lcTrainTrackInfo::DecodeTrackToolSection(mTrackToolSection);
ActiveModel->RotateTrainTrackToolClicked(ConnectionIndex);
ActiveModel->RotateFocusedTrainTrack(mTrackTool == lcTrackTool::RotateTrainTrackRight ? 1 : -1);
mToolClicked = true;
UpdateTrackTool();
}
break;
case lcTrackTool::ScalePlus:
case lcTrackTool::ScaleMinus:
if (ActiveModel->AnyPiecesSelected())
@ -2653,9 +2653,20 @@ void lcView::OnLeftButtonDoubleClick()
return;
}
lcObjectSection ObjectSection = FindObjectUnderPointer(false, false);
lcModel* ActiveModel = GetActiveModel();
if (mTrackTool == lcTrackTool::RotateTrainTrackRight || mTrackTool == lcTrackTool::RotateTrainTrackLeft)
{
ActiveModel->RotateFocusedTrainTrack(mTrackTool == lcTrackTool::RotateTrainTrackRight ? 1 : -1);
mToolClicked = true;
UpdateTrackTool();
return;
}
lcObjectSection ObjectSection = FindObjectUnderPointer(false, false);
if (mMouseModifiers & Qt::ControlModifier)
ActiveModel->FocusOrDeselectObject(ObjectSection);
else if (mMouseModifiers & Qt::ShiftModifier)
@ -3011,7 +3022,8 @@ void lcView::OnMouseMove()
}
break;
case lcTrackTool::RotateTrainTrack:
case lcTrackTool::RotateTrainTrackRight:
case lcTrackTool::RotateTrainTrackLeft:
case lcTrackTool::Eraser:
case lcTrackTool::Paint:
case lcTrackTool::ColorPicker:

View file

@ -70,7 +70,8 @@ enum class lcTrackTool
RotateZ,
RotateXY,
RotateXYZ,
RotateTrainTrack,
RotateTrainTrackRight,
RotateTrainTrackLeft,
ScalePlus,
ScaleMinus,
Eraser,

View file

@ -21,36 +21,36 @@ lcViewManipulator::lcViewManipulator(lcView* View)
void lcViewManipulator::CreateResources(lcContext* Context)
{
float Verts[(51 + 138 + 10) * 3];
float Verts[(51 + 138 + 10 + 74) * 3];
float* CurVert = Verts;
const float OverlayMovePlaneSize = 0.5f;
const float OverlayMoveArrowSize = 1.5f;
const float OverlayMoveArrowCapSize = 0.9f;
const float OverlayMoveArrowCapRadius = 0.1f;
const float OverlayArrowCapRadius = 0.1f;
const float OverlayMoveArrowBodySize = 1.2f;
const float OverlayMoveArrowBodyRadius = 0.05f;
const float OverlayArrowBodyRadius = 0.05f;
const float OverlayRotateArrowStart = 1.0f;
const float OverlayRotateArrowEnd = 1.5f;
const float OverlayRotateArrowCenter = 1.2f;
*CurVert++ = OverlayMoveArrowSize; *CurVert++ = 0.0f; *CurVert++ = 0.0f;
for (int EdgeIdx = 0; EdgeIdx < 8; EdgeIdx++)
for (int EdgeIndex = 0; EdgeIndex < 8; EdgeIndex++)
{
*CurVert++ = OverlayMoveArrowCapSize;
*CurVert++ = cosf(LC_2PI * EdgeIdx / 8) * OverlayMoveArrowCapRadius;
*CurVert++ = sinf(LC_2PI * EdgeIdx / 8) * OverlayMoveArrowCapRadius;
*CurVert++ = cosf(LC_2PI * EdgeIndex / 8) * OverlayArrowCapRadius;
*CurVert++ = sinf(LC_2PI * EdgeIndex / 8) * OverlayArrowCapRadius;
}
*CurVert++ = 0.0f; *CurVert++ = -OverlayMoveArrowBodyRadius; *CurVert++ = 0.0f;
*CurVert++ = 0.0f; *CurVert++ = OverlayMoveArrowBodyRadius; *CurVert++ = 0.0f;
*CurVert++ = 0.0f; *CurVert++ = 0.0f; *CurVert++ = -OverlayMoveArrowBodyRadius;
*CurVert++ = 0.0f; *CurVert++ = 0.0f; *CurVert++ = OverlayMoveArrowBodyRadius;
*CurVert++ = OverlayMoveArrowBodySize; *CurVert++ = -OverlayMoveArrowBodyRadius; *CurVert++ = 0.0f;
*CurVert++ = OverlayMoveArrowBodySize; *CurVert++ = OverlayMoveArrowBodyRadius; *CurVert++ = 0.0f;
*CurVert++ = OverlayMoveArrowBodySize; *CurVert++ = 0.0f; *CurVert++ = -OverlayMoveArrowBodyRadius;
*CurVert++ = OverlayMoveArrowBodySize; *CurVert++ = 0.0f; *CurVert++ = OverlayMoveArrowBodyRadius;
*CurVert++ = 0.0f; *CurVert++ = -OverlayArrowBodyRadius; *CurVert++ = 0.0f;
*CurVert++ = 0.0f; *CurVert++ = OverlayArrowBodyRadius; *CurVert++ = 0.0f;
*CurVert++ = 0.0f; *CurVert++ = 0.0f; *CurVert++ = -OverlayArrowBodyRadius;
*CurVert++ = 0.0f; *CurVert++ = 0.0f; *CurVert++ = OverlayArrowBodyRadius;
*CurVert++ = OverlayMoveArrowBodySize; *CurVert++ = -OverlayArrowBodyRadius; *CurVert++ = 0.0f;
*CurVert++ = OverlayMoveArrowBodySize; *CurVert++ = OverlayArrowBodyRadius; *CurVert++ = 0.0f;
*CurVert++ = OverlayMoveArrowBodySize; *CurVert++ = 0.0f; *CurVert++ = -OverlayArrowBodyRadius;
*CurVert++ = OverlayMoveArrowBodySize; *CurVert++ = 0.0f; *CurVert++ = OverlayArrowBodyRadius;
for (int VertIdx = 0; VertIdx < 17; VertIdx++)
{
@ -66,30 +66,31 @@ void lcViewManipulator::CreateResources(lcContext* Context)
*CurVert = *(CurVert - 104); CurVert++;
}
*CurVert++ = 0.0f; *CurVert++ = OverlayRotateArrowEnd - OverlayMoveArrowCapRadius; *CurVert++ = OverlayRotateArrowStart;
// Rotate X
*CurVert++ = 0.0f; *CurVert++ = OverlayRotateArrowEnd - OverlayArrowCapRadius; *CurVert++ = OverlayRotateArrowStart;
for (int EdgeIdx = 0; EdgeIdx < 8; EdgeIdx++)
for (int EdgeIndex = 0; EdgeIndex < 8; EdgeIndex++)
{
*CurVert++ = cosf(LC_2PI * EdgeIdx / 8) * OverlayMoveArrowCapRadius;
*CurVert++ = sinf(LC_2PI * EdgeIdx / 8) * OverlayMoveArrowCapRadius + OverlayRotateArrowEnd - OverlayMoveArrowCapRadius;
*CurVert++ = cosf(LC_2PI * EdgeIndex / 8) * OverlayArrowCapRadius;
*CurVert++ = sinf(LC_2PI * EdgeIndex / 8) * OverlayArrowCapRadius + OverlayRotateArrowEnd - OverlayArrowCapRadius;
*CurVert++ = OverlayRotateArrowCenter;
}
*CurVert++ = 0.0f; *CurVert++ = OverlayRotateArrowStart; *CurVert++ = OverlayRotateArrowEnd - OverlayMoveArrowCapRadius;
*CurVert++ = 0.0f; *CurVert++ = OverlayRotateArrowStart; *CurVert++ = OverlayRotateArrowEnd - OverlayArrowCapRadius;
for (int EdgeIdx = 0; EdgeIdx < 8; EdgeIdx++)
for (int EdgeIndex = 0; EdgeIndex < 8; EdgeIndex++)
{
*CurVert++ = cosf(LC_2PI * EdgeIdx / 8) * OverlayMoveArrowCapRadius;
*CurVert++ = cosf(LC_2PI * EdgeIndex / 8) * OverlayArrowCapRadius;
*CurVert++ = OverlayRotateArrowCenter;
*CurVert++ = sinf(LC_2PI * EdgeIdx / 8) * OverlayMoveArrowCapRadius + OverlayRotateArrowEnd - OverlayMoveArrowCapRadius;
*CurVert++ = sinf(LC_2PI * EdgeIndex / 8) * OverlayArrowCapRadius + OverlayRotateArrowEnd - OverlayArrowCapRadius;
}
for (int EdgeIdx = 0; EdgeIdx < 7; EdgeIdx++)
for (int EdgeIndex = 0; EdgeIndex < 7; EdgeIndex++)
{
const float Radius1 = OverlayRotateArrowEnd - OverlayMoveArrowCapRadius - OverlayRotateArrowCenter - OverlayMoveArrowBodyRadius;
const float Radius2 = OverlayRotateArrowEnd - OverlayMoveArrowCapRadius - OverlayRotateArrowCenter + OverlayMoveArrowBodyRadius;
float x = cosf(LC_2PI / 4 * EdgeIdx / 6);
float y = sinf(LC_2PI / 4 * EdgeIdx / 6);
const float Radius1 = OverlayRotateArrowEnd - OverlayArrowCapRadius - OverlayRotateArrowCenter - OverlayArrowBodyRadius;
const float Radius2 = OverlayRotateArrowEnd - OverlayArrowCapRadius - OverlayRotateArrowCenter + OverlayArrowBodyRadius;
float x = cosf(LC_2PI / 4 * EdgeIndex / 6);
float y = sinf(LC_2PI / 4 * EdgeIndex / 6);
*CurVert++ = 0.0f;
*CurVert++ = OverlayRotateArrowCenter + x * Radius1;
@ -99,20 +100,21 @@ void lcViewManipulator::CreateResources(lcContext* Context)
*CurVert++ = OverlayRotateArrowCenter + y * Radius2;
}
for (int EdgeIdx = 0; EdgeIdx < 7; EdgeIdx++)
for (int EdgeIndex = 0; EdgeIndex < 7; EdgeIndex++)
{
const float Radius = OverlayRotateArrowEnd - OverlayMoveArrowCapRadius - OverlayRotateArrowCenter;
float x = cosf(LC_2PI / 4 * EdgeIdx / 6);
float y = sinf(LC_2PI / 4 * EdgeIdx / 6);
const float Radius = OverlayRotateArrowEnd - OverlayArrowCapRadius - OverlayRotateArrowCenter;
float x = cosf(LC_2PI / 4 * EdgeIndex / 6);
float y = sinf(LC_2PI / 4 * EdgeIndex / 6);
*CurVert++ = -OverlayMoveArrowBodyRadius;
*CurVert++ = -OverlayArrowBodyRadius;
*CurVert++ = OverlayRotateArrowCenter + x * Radius;
*CurVert++ = OverlayRotateArrowCenter + y * Radius;
*CurVert++ = OverlayMoveArrowBodyRadius;
*CurVert++ = OverlayArrowBodyRadius;
*CurVert++ = OverlayRotateArrowCenter + x * Radius;
*CurVert++ = OverlayRotateArrowCenter + y * Radius;
}
// Rotate Y
for (int VertIdx = 0; VertIdx < 46; VertIdx++)
{
*CurVert = *(CurVert - 137); CurVert++;
@ -120,6 +122,7 @@ void lcViewManipulator::CreateResources(lcContext* Context)
*CurVert = *(CurVert - 138); CurVert++;
}
// Rotate Z
for (int VertIdx = 0; VertIdx < 46; VertIdx++)
{
*CurVert = *(CurVert - 274); CurVert++;
@ -127,6 +130,7 @@ void lcViewManipulator::CreateResources(lcContext* Context)
*CurVert = *(CurVert - 278); CurVert++;
}
// Move Planes
*CurVert++ = 0.0f; *CurVert++ = 0.0f; *CurVert++ = 0.0f;
*CurVert++ = 0.0f; *CurVert++ = OverlayMovePlaneSize; *CurVert++ = 0.0f;
*CurVert++ = 0.0f; *CurVert++ = OverlayMovePlaneSize; *CurVert++ = OverlayMovePlaneSize;
@ -138,27 +142,94 @@ void lcViewManipulator::CreateResources(lcContext* Context)
*CurVert++ = OverlayMovePlaneSize; *CurVert++ = OverlayMovePlaneSize; *CurVert++ = 0.0f;
*CurVert++ = OverlayMovePlaneSize; *CurVert++ = 0.0f; *CurVert++ = 0.0f;
const GLushort Indices[108 + 360 + 12] =
const float OverlayTrainTrackStart = 0.0f;
const float OverlayTrainTrackEnd = 0.5f;
const float OverlayTrainTrackCenter = 0.2f;
const float OverlayTrainTrackDistance = 0.5f;
// Train Track Rotate Right
*CurVert++ = OverlayTrainTrackStart; *CurVert++ = OverlayTrainTrackEnd + OverlayTrainTrackDistance - OverlayArrowCapRadius; *CurVert++ = 0.0f;
for (int EdgeIndex = 0; EdgeIndex < 8; EdgeIndex++)
{
*CurVert++ = OverlayTrainTrackCenter;
*CurVert++ = sinf(LC_2PI * EdgeIndex / 8) * OverlayArrowCapRadius + OverlayTrainTrackEnd + OverlayTrainTrackDistance - OverlayArrowCapRadius;
*CurVert++ = cosf(LC_2PI * EdgeIndex / 8) * OverlayArrowCapRadius;
}
for (int EdgeIndex = 0; EdgeIndex < 7; EdgeIndex++)
{
const float Radius1 = OverlayTrainTrackEnd - OverlayArrowCapRadius - OverlayTrainTrackCenter - OverlayArrowBodyRadius;
const float Radius2 = OverlayTrainTrackEnd - OverlayArrowCapRadius - OverlayTrainTrackCenter + OverlayArrowBodyRadius;
float x = cosf(LC_2PI / 4 * EdgeIndex / 6);
float y = sinf(LC_2PI / 4 * EdgeIndex / 6);
*CurVert++ = OverlayTrainTrackCenter + y * Radius1;
*CurVert++ = OverlayTrainTrackCenter + OverlayTrainTrackDistance + x * Radius1;
*CurVert++ = 0.0f;
*CurVert++ = OverlayTrainTrackCenter + y * Radius2;
*CurVert++ = OverlayTrainTrackCenter + OverlayTrainTrackDistance + x * Radius2;
*CurVert++ = 0.0f;
}
for (int EdgeIndex = 0; EdgeIndex < 7; EdgeIndex++)
{
const float Radius = OverlayTrainTrackEnd - OverlayArrowCapRadius - OverlayTrainTrackCenter;
float x = cosf(LC_2PI / 4 * EdgeIndex / 6);
float y = sinf(LC_2PI / 4 * EdgeIndex / 6);
*CurVert++ = OverlayTrainTrackCenter + y * Radius;
*CurVert++ = OverlayTrainTrackCenter + OverlayTrainTrackDistance + x * Radius;
*CurVert++ = -OverlayArrowBodyRadius;
*CurVert++ = OverlayTrainTrackCenter + y * Radius;
*CurVert++ = OverlayTrainTrackCenter + OverlayTrainTrackDistance + x * Radius;
*CurVert++ = OverlayArrowBodyRadius;
}
// Train Track Rotate Left
for (int VertIdx = 0; VertIdx < 37; VertIdx++)
{
*CurVert = *(CurVert - 111); CurVert++;
*CurVert = -*(CurVert - 111); CurVert++;
*CurVert = *(CurVert - 111); CurVert++;
}
const GLushort Indices[108 + 360 + 12 + 192] =
{
// 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,
9, 10, 14, 14, 13, 9, 11, 12, 15, 15, 16, 12,
// Move Y
17, 18, 19, 17, 19, 20, 17, 20, 21, 17, 21, 22, 17, 22, 23, 17, 23, 24, 17, 24, 25, 17, 25, 18,
26, 27, 31, 31, 30, 26, 28, 29, 32, 32, 33, 29,
// Move Z
34, 35, 36, 34, 36, 37, 34, 37, 38, 34, 38, 39, 34, 39, 40, 34, 40, 41, 34, 41, 42, 34, 42, 35,
43, 44, 48, 48, 47, 43, 45, 46, 49, 49, 50, 46,
// Rotate X
51, 52, 53, 51, 53, 54, 51, 54, 55, 51, 55, 56, 51, 56, 57, 51, 57, 58, 51, 58, 59, 51, 59, 52,
60, 61, 62, 60, 62, 63, 60, 63, 64, 60, 64, 65, 60, 65, 66, 60, 66, 67, 60, 67, 68, 60, 68, 61,
69, 70, 71, 71, 72, 70, 71, 72, 73, 73, 74, 72, 73, 74, 75, 75, 76, 74, 75, 76, 77, 77, 78, 76, 77, 78, 79, 79, 80, 78, 79, 80, 81, 81, 82, 80,
83, 84, 85, 85, 86, 84, 85, 86, 87, 87, 88, 86, 87, 88, 89, 89, 90, 88, 89, 90, 91, 91, 92, 90, 91, 92, 93, 93, 94, 92, 93, 94, 95, 95, 96, 94,
// Rotate Y
97, 98, 99, 97, 99, 100, 97, 100, 101, 97, 101, 102, 97, 102, 103, 97, 103, 104, 97, 104, 105, 97, 105, 98,
106, 107, 108, 106, 108, 109, 106, 109, 110, 106, 110, 111, 106, 111, 112, 106, 112, 113, 106, 113, 114, 106, 114, 107,
115, 116, 117, 117, 118, 116, 117, 118, 119, 119, 120, 118, 119, 120, 121, 121, 122, 120, 121, 122, 123, 123, 124, 122, 123, 124, 125, 125, 126, 124, 125, 126, 127, 127, 128, 126,
129, 130, 131, 131, 132, 130, 131, 132, 133, 133, 134, 132, 133, 134, 135, 135, 136, 134, 135, 136, 137, 137, 138, 136, 137, 138, 139, 139, 140, 138, 139, 140, 141, 141, 142, 140,
// Rotate Z
143, 144, 145, 143, 145, 146, 143, 146, 147, 143, 147, 148, 143, 148, 149, 143, 149, 150, 143, 150, 151, 143, 151, 144,
152, 153, 154, 152, 154, 155, 152, 155, 156, 152, 156, 157, 152, 157, 158, 152, 158, 159, 152, 159, 160, 152, 160, 153,
161, 162, 163, 163, 164, 162, 163, 164, 165, 165, 166, 164, 165, 166, 167, 167, 168, 166, 167, 168, 169, 169, 170, 168, 169, 170, 171, 171, 172, 170, 171, 172, 173, 173, 174, 172,
175, 176, 177, 177, 178, 176, 177, 178, 179, 179, 180, 178, 179, 180, 181, 181, 182, 180, 181, 182, 183, 183, 184, 182, 183, 184, 185, 185, 186, 184, 185, 186, 187, 187, 188, 186,
189, 190, 191, 192, 189, 193, 194, 195, 189, 196, 197, 198
// Move Planes
189, 190, 191, 192, 189, 193, 194, 195, 189, 196, 197, 198,
// Train Track Rotate Right
199, 200, 201, 199, 201, 202, 199, 202, 203, 199, 203, 204, 199, 204, 205, 199, 205, 206, 199, 206, 207, 199, 207, 200,
208, 209, 210, 210, 211, 209, 210, 211, 212, 212, 213, 211, 212, 213, 214, 214, 215, 213, 214, 215, 216, 216, 217, 215, 216, 217, 218, 218, 219, 217, 218, 219, 220, 220, 221, 219,
222, 223, 224, 224, 225, 223, 224, 225, 226, 226, 227, 225, 226, 227, 228, 228, 229, 227, 228, 229, 230, 230, 231, 229, 230, 231, 232, 232, 233, 231, 232, 233, 234, 234, 235, 233,
// 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
};
mRotateMoveVertexBuffer = Context->CreateVertexBuffer(sizeof(Verts), Verts);
@ -361,18 +432,45 @@ void lcViewManipulator::DrawSelectMove(lcTrackButton TrackButton, lcTrackTool Tr
}
else if (Piece->mPieceInfo->GetTrainTrackInfo())
{
DrawTrainTrack(Piece, Context, OverlayScale);
DrawTrainTrack(Piece, Context, OverlayScale, TrackTool);
}
}
Context->EnableDepthTest(true);
}
void lcViewManipulator::DrawTrainTrack(lcPiece* Piece, lcContext* Context, float OverlayScale)
void lcViewManipulator::DrawTrainTrack(lcPiece* Piece, lcContext* Context, float OverlayScale, 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();
const lcVector4 ControlPointColor = lcVector4FromColor(Preferences.mControlPointColor);
Context->SetColor(ControlPointColor);
if (TrackTool == lcTrackTool::RotateTrainTrackRight)
{
Context->DrawIndexedPrimitives(GL_TRIANGLES, 96, GL_UNSIGNED_SHORT, (108 + 360 + 12 + 96) * 2);
Context->SetColor(0.8f, 0.8f, 0.0f, 1.0f);
Context->DrawIndexedPrimitives(GL_TRIANGLES, 96, GL_UNSIGNED_SHORT, (108 + 360 + 12) * 2);
}
else if (TrackTool == lcTrackTool::RotateTrainTrackLeft)
{
Context->DrawIndexedPrimitives(GL_TRIANGLES, 96, GL_UNSIGNED_SHORT, (108 + 360 + 12) * 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
{
Context->DrawIndexedPrimitives(GL_TRIANGLES, 192, GL_UNSIGNED_SHORT, (108 + 360 + 12) * 2);
}
}
for (quint32 ConnectionIndex = 0; ConnectionIndex < Connections.size(); ConnectionIndex++)
{
if (Piece->IsTrainTrackConnected(ConnectionIndex))
@ -775,7 +873,8 @@ bool lcViewManipulator::IsTrackToolAllowed(lcTrackTool TrackTool, quint32 Allowe
case lcTrackTool::RotateXYZ:
return (AllowedTransforms & (LC_OBJECT_TRANSFORM_ROTATE_X | LC_OBJECT_TRANSFORM_ROTATE_Y | LC_OBJECT_TRANSFORM_ROTATE_Z)) == (LC_OBJECT_TRANSFORM_ROTATE_X | LC_OBJECT_TRANSFORM_ROTATE_Y | LC_OBJECT_TRANSFORM_ROTATE_Z);
case lcTrackTool::RotateTrainTrack:
case lcTrackTool::RotateTrainTrackRight:
case lcTrackTool::RotateTrainTrackLeft:
return true;
case lcTrackTool::ScalePlus:
@ -810,6 +909,9 @@ std::pair<lcTrackTool, quint32> lcViewManipulator::UpdateSelectMove()
const float OverlayMoveArrowCapRadius = 0.1f * 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 OverlayScaleRadius = 0.125f;
lcTool CurrentTool = gMainWindow->GetTool();
@ -978,6 +1080,42 @@ std::pair<lcTrackTool, quint32> lcViewManipulator::UpdateSelectMove()
if (TrainTrackInfo)
{
if (Piece->GetFocusSection() >= LC_PIECE_SECTION_TRAIN_TRACK_CONNECTION_FIRST && CurrentTool == lcTool::Select)
{
for (int AxisIndex = 2; AxisIndex < 3; AxisIndex++)
{
lcVector4 Plane(PlaneNormals[AxisIndex], -lcDot(PlaneNormals[AxisIndex], OverlayCenter));
lcVector3 Intersection;
if (!lcLineSegmentPlaneIntersection(&Intersection, Start, End, Plane))
continue;
float IntersectionDistance = lcLengthSquared(Intersection - Start);
if (IntersectionDistance > ClosestIntersectionDistance)
continue;
lcVector3 Dir(Intersection - OverlayCenter);
float Proj1 = lcDot(Dir, PlaneNormals[(AxisIndex + 1) % 3]);
float Proj2 = lcDot(Dir, PlaneNormals[(AxisIndex + 2) % 3]);
if (Proj1 > OverlayTrainTrackStart && Proj1 < OverlayTrainTrackEnd && Proj2 > OverlayTrainTrackDistance + OverlayTrainTrackStart && Proj2 < OverlayTrainTrackDistance + OverlayTrainTrackEnd)
{
NewTrackTool = lcTrackTool::RotateTrainTrackRight;
ClosestIntersectionDistance = IntersectionDistance;
NewTrackSection = Piece->GetFocusSection() - LC_PIECE_SECTION_TRAIN_TRACK_CONNECTION_FIRST;
}
if (Proj1 > OverlayTrainTrackStart && Proj1 < OverlayTrainTrackEnd && -Proj2 > OverlayTrainTrackDistance + OverlayTrainTrackStart && -Proj2 < OverlayTrainTrackDistance + OverlayTrainTrackEnd)
{
NewTrackTool = lcTrackTool::RotateTrainTrackLeft;
ClosestIntersectionDistance = IntersectionDistance;
NewTrackSection = Piece->GetFocusSection() - LC_PIECE_SECTION_TRAIN_TRACK_CONNECTION_FIRST;
}
}
}
ActiveModel->UpdateTrainTrackConnections(Piece);
const std::vector<lcTrainTrackConnection>& Connections = TrainTrackInfo->GetConnections();
@ -1014,23 +1152,6 @@ std::pair<lcTrackTool, quint32> lcViewManipulator::UpdateSelectMove()
}
}
}
lcObjectRayTest ObjectRayTest;
ObjectRayTest.PiecesOnly = true;
ObjectRayTest.IgnoreSelected = false;
ObjectRayTest.ViewCamera = mView->GetCamera();
ObjectRayTest.Start = StartEnd[0];
ObjectRayTest.End = StartEnd[1];
Piece->RayTestConnectedTrainTracks(ObjectRayTest);
if (ObjectRayTest.Distance < ClosestIntersectionDistance && ObjectRayTest.ObjectSection.Section >= LC_PIECE_SECTION_TRAIN_TRACK_CONNECTION_FIRST)
{
NewTrackTool = lcTrackTool::RotateTrainTrack;
ClosestIntersectionDistance = ObjectRayTest.Distance;
NewTrackSection = ObjectRayTest.ObjectSection.Section - 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);
void DrawTrainTrack(lcPiece* Piece, lcContext* Context, float OverlayScale, lcTrackTool TrackTool);
static bool IsTrackToolAllowed(lcTrackTool TrackTool, quint32 AllowedTransforms);

View file

@ -463,41 +463,6 @@ void lcPiece::RemoveTime(lcStep Start, lcStep Time)
mRotation.RemoveTime(Start, Time);
}
void lcPiece::RayTestConnectedTrainTracks(lcObjectRayTest& ObjectRayTest) const
{
const lcMatrix44 InverseWorldMatrix = lcMatrix44AffineInverse(mModelWorld);
const lcVector3 Start = lcMul31(ObjectRayTest.Start, InverseWorldMatrix);
const lcVector3 End = lcMul31(ObjectRayTest.End, InverseWorldMatrix);
if (mPieceInfo->GetTrainTrackInfo() && AreTrainTrackConnectionsVisible())
{
const lcVector3 Min(-LC_PIECE_CONTROL_POINT_SIZE, -LC_PIECE_CONTROL_POINT_SIZE, -LC_PIECE_CONTROL_POINT_SIZE);
const lcVector3 Max(LC_PIECE_CONTROL_POINT_SIZE, LC_PIECE_CONTROL_POINT_SIZE, LC_PIECE_CONTROL_POINT_SIZE);
const std::vector<lcTrainTrackConnection>& Connections = mPieceInfo->GetTrainTrackInfo()->GetConnections();
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);
float Distance;
lcVector3 Plane;
if (lcBoundingBoxRayIntersectDistance(Min, Max, PointStart, PointEnd, &Distance, nullptr, &Plane))
{
ObjectRayTest.ObjectSection.Object = const_cast<lcPiece*>(this);
ObjectRayTest.ObjectSection.Section = LC_PIECE_SECTION_TRAIN_TRACK_CONNECTION_FIRST + ConnectionIndex;
ObjectRayTest.Distance = Distance;
ObjectRayTest.PieceInfoRayTest.Plane = Plane;
}
}
}
}
void lcPiece::RayTest(lcObjectRayTest& ObjectRayTest) const
{
const lcMatrix44 InverseWorldMatrix = lcMatrix44AffineInverse(mModelWorld);
@ -555,9 +520,6 @@ 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);
@ -772,17 +734,10 @@ void lcPiece::DrawTrainTrackInterface(lcContext* Context, const lcMatrix44& Worl
Context->SetVertexFormatPosition(3);
Context->SetIndexBufferPointer(Indices);
if (mTrainTrackConnections[ConnectionIndex])
{
Context->SetColor(lcVector4(1.0f, 0.0f, 0.0f, 1.0f));
}
else
{
if (IsFocused(LC_PIECE_SECTION_TRAIN_TRACK_CONNECTION_FIRST + ConnectionIndex))
Context->SetColor(ConnectionFocusedColor);
else
Context->SetColor(ConnectionColor);
}
Context->DrawIndexedPrimitives(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 0);
}

View file

@ -107,7 +107,6 @@ public:
}
void RayTest(lcObjectRayTest& ObjectRayTest) const override;
void RayTestConnectedTrainTracks(lcObjectRayTest& ObjectRayTest) const;
void BoxTest(lcObjectBoxTest& ObjectBoxTest) const override;
void DrawInterface(lcContext* Context, const lcScene& Scene) const override;
QVariant GetPropertyValue(lcObjectPropertyId PropertyId) const override;