2020-10-03 12:02:27 +02:00
|
|
|
#include "QMessageBox"
|
|
|
|
#include "lc_global.h"
|
|
|
|
#include "lc_previewwidget.h"
|
|
|
|
#include "pieceinf.h"
|
|
|
|
#include "piece.h"
|
|
|
|
#include "project.h"
|
|
|
|
#include "lc_model.h"
|
|
|
|
#include "camera.h"
|
|
|
|
#include "texfont.h"
|
|
|
|
#include "lc_library.h"
|
|
|
|
|
|
|
|
#include "lc_qglwidget.h"
|
|
|
|
|
|
|
|
lcPreviewWidget* gPreviewWidget;
|
|
|
|
|
2020-10-07 10:08:58 +02:00
|
|
|
lcPreviewDockWidget::lcPreviewDockWidget(QMainWindow* Parent)
|
|
|
|
: QMainWindow(Parent)
|
2020-10-03 12:02:27 +02:00
|
|
|
{
|
2020-10-07 12:07:32 +02:00
|
|
|
mPreview = new lcPreviewWidget();
|
|
|
|
mViewWidget = new lcQGLWidget(nullptr, mPreview, true/*IsView*/, true/*IsPreview*/);
|
|
|
|
setCentralWidget(mViewWidget);
|
2020-10-03 12:02:27 +02:00
|
|
|
setMinimumSize(200, 200);
|
2020-10-07 12:07:32 +02:00
|
|
|
|
2020-10-07 13:42:43 +02:00
|
|
|
mLockAction = new QAction(QIcon(":/resources/action_preview_unlocked.png"),tr("Lock Preview"), this);
|
|
|
|
mLockAction->setCheckable(true);
|
|
|
|
mLockAction->setChecked(false);
|
|
|
|
mLockAction->setShortcut(tr("Ctrl+L"));
|
|
|
|
connect(mLockAction, SIGNAL(triggered()), this, SLOT(SetPreviewLock()));
|
|
|
|
SetPreviewLock();
|
|
|
|
|
|
|
|
mLabel = new QLabel(QString());
|
|
|
|
|
2020-10-07 12:07:32 +02:00
|
|
|
mToolBar = addToolBar(tr("PreviewDescription"));
|
|
|
|
mToolBar->setObjectName("PreviewDescription");
|
|
|
|
mToolBar->setMovable(false);
|
2020-10-07 13:42:43 +02:00
|
|
|
mToolBar->addAction(mLockAction);
|
|
|
|
mToolBar->addSeparator();
|
2020-10-07 12:07:32 +02:00
|
|
|
mToolBar->addWidget(mLabel);
|
2020-10-03 12:02:27 +02:00
|
|
|
}
|
|
|
|
|
2020-10-07 10:08:58 +02:00
|
|
|
bool lcPreviewDockWidget::SetCurrentPiece(const QString& PartType, int ColorCode)
|
2020-10-03 12:02:27 +02:00
|
|
|
{
|
2020-10-07 13:42:43 +02:00
|
|
|
if (mLockAction->isChecked())
|
|
|
|
return true;
|
|
|
|
|
2020-10-07 12:07:32 +02:00
|
|
|
mLabel->setText(tr("Loading..."));
|
|
|
|
if (mPreview->SetCurrentPiece(PartType, ColorCode))
|
2020-10-07 10:08:58 +02:00
|
|
|
{
|
2020-10-07 12:07:32 +02:00
|
|
|
mLabel->setText(mPreview->GetDescription());
|
2020-10-03 12:02:27 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void lcPreviewDockWidget::ClearPreview()
|
|
|
|
{
|
2020-10-07 16:56:49 +02:00
|
|
|
if (mPreview->GetActiveModel()->GetPieces().GetSize())
|
|
|
|
mPreview->ClearPreview();
|
2020-10-07 12:07:32 +02:00
|
|
|
mLabel->setText(QString());
|
2020-10-03 12:02:27 +02:00
|
|
|
}
|
|
|
|
|
2020-10-07 13:42:43 +02:00
|
|
|
void lcPreviewDockWidget::SetPreviewLock()
|
|
|
|
{
|
|
|
|
bool Locked = mLockAction->isChecked();
|
|
|
|
if (Locked && mPreview->GetActiveModel()->GetPieces().IsEmpty())
|
|
|
|
{
|
|
|
|
mLockAction->setChecked(false);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
QIcon LockIcon(Locked ? ":/resources/action_preview_locked.png" : ":/resources/action_preview_unlocked.png");
|
|
|
|
QString State(Locked ? tr("Unlock") : tr("Lock"));
|
|
|
|
QString StatusTip(tr("%1 the preview display to %2 updates").arg(State).arg(Locked ? "enable" : "disable"));
|
|
|
|
mLockAction->setToolTip(tr("%1 Preview").arg(State));
|
|
|
|
mLockAction->setIcon(LockIcon);
|
|
|
|
mLockAction->setStatusTip(StatusTip);
|
|
|
|
}
|
|
|
|
|
2020-10-03 12:02:27 +02:00
|
|
|
lcPreviewWidget::lcPreviewWidget()
|
2020-10-07 10:08:58 +02:00
|
|
|
: mLoader(new Project(true/*IsPreview*/)),
|
|
|
|
mViewSphere(this/*Preview*/)
|
2020-10-03 12:02:27 +02:00
|
|
|
{
|
2020-10-07 10:08:58 +02:00
|
|
|
mTool = LC_TOOL_SELECT;
|
|
|
|
mTrackTool = LC_TRACKTOOL_NONE;
|
2020-10-03 12:02:27 +02:00
|
|
|
mTrackButton = lcTrackButton::None;
|
|
|
|
|
|
|
|
mLoader->SetActiveModel(0);
|
2020-10-07 10:08:58 +02:00
|
|
|
mModel = mLoader->GetActiveModel();
|
2020-10-03 12:02:27 +02:00
|
|
|
mCamera = nullptr;
|
|
|
|
|
|
|
|
SetDefaultCamera();
|
|
|
|
}
|
|
|
|
|
|
|
|
lcPreviewWidget::~lcPreviewWidget()
|
|
|
|
{
|
|
|
|
if (mCamera && mCamera->IsSimple())
|
|
|
|
delete mCamera;
|
|
|
|
|
2020-10-07 10:08:58 +02:00
|
|
|
delete mLoader;
|
2020-10-07 16:56:49 +02:00
|
|
|
|
|
|
|
gPreviewWidget = nullptr;
|
2020-10-03 12:02:27 +02:00
|
|
|
}
|
|
|
|
|
2020-10-07 10:08:58 +02:00
|
|
|
bool lcPreviewWidget::SetCurrentPiece(const QString& PartType, int ColorCode)
|
2020-10-03 12:02:27 +02:00
|
|
|
{
|
2020-10-07 10:08:58 +02:00
|
|
|
lcPiecesLibrary* Library = lcGetPiecesLibrary();
|
2020-10-03 12:02:27 +02:00
|
|
|
PieceInfo* Info = Library->FindPiece(PartType.toLatin1().constData(), nullptr, false, false);
|
2020-10-07 10:08:58 +02:00
|
|
|
|
|
|
|
if (Info)
|
|
|
|
{
|
2020-10-08 15:17:31 +02:00
|
|
|
lcModel* ActiveModel = GetActiveModel();
|
|
|
|
for (lcPiece* ModelPiece : ActiveModel->GetPieces())
|
|
|
|
{
|
|
|
|
if (Info == ModelPiece->mPieceInfo)
|
|
|
|
{
|
|
|
|
int ModelColorCode = ModelPiece->mColorCode;
|
|
|
|
if (ModelColorCode == ColorCode)
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-07 12:07:32 +02:00
|
|
|
mIsModel = Info->IsModel();
|
2020-10-03 12:02:27 +02:00
|
|
|
mDescription = Info->m_strDescription;
|
|
|
|
|
|
|
|
ActiveModel->SelectAllPieces();
|
|
|
|
ActiveModel->DeleteSelectedObjects();
|
|
|
|
|
|
|
|
Library->LoadPieceInfo(Info, false, true);
|
|
|
|
Library->WaitForLoadQueue();
|
|
|
|
|
2020-10-07 10:08:58 +02:00
|
|
|
lcStep CurrentStep = 1;
|
2020-10-03 12:02:27 +02:00
|
|
|
lcPiece* Piece = new lcPiece(nullptr);
|
|
|
|
|
|
|
|
Piece->SetPieceInfo(Info, PartType, false);
|
2020-10-07 10:08:58 +02:00
|
|
|
Piece->Initialize(lcMatrix44Identity(), CurrentStep);
|
2020-10-03 12:02:27 +02:00
|
|
|
Piece->SetColorCode(ColorCode);
|
|
|
|
|
|
|
|
ActiveModel->SetPreviewPiece(Piece);
|
2020-10-07 10:08:58 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
QString ModelPath = QString("%1/%2").arg(QDir::currentPath()).arg(PartType);
|
2020-10-03 12:02:27 +02:00
|
|
|
|
2020-10-07 10:08:58 +02:00
|
|
|
if (!mLoader->Load(ModelPath))
|
|
|
|
{
|
|
|
|
QMessageBox::warning(nullptr, QMessageBox::tr("Error"), QMessageBox::tr("Failed to load '%1'.").arg(ModelPath));
|
2020-10-03 12:02:27 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
mLoader->SetActiveModel(0);
|
|
|
|
lcGetPiecesLibrary()->RemoveTemporaryPieces();
|
|
|
|
mModel = mLoader->GetActiveModel();
|
|
|
|
if (!mModel->GetProperties().mDescription.isEmpty())
|
|
|
|
mDescription = mModel->GetProperties().mDescription;
|
|
|
|
else
|
|
|
|
mDescription = PartType;
|
2020-10-07 12:07:32 +02:00
|
|
|
mIsModel = true;
|
2020-10-03 12:02:27 +02:00
|
|
|
}
|
2020-10-07 10:08:58 +02:00
|
|
|
|
2020-10-03 12:02:27 +02:00
|
|
|
ZoomExtents();
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void lcPreviewWidget::ClearPreview()
|
|
|
|
{
|
2020-10-12 02:29:32 +02:00
|
|
|
delete mLoader;
|
2020-10-03 12:02:27 +02:00
|
|
|
mLoader = new Project(true/*IsPreview*/);
|
|
|
|
mLoader->SetActiveModel(0);
|
|
|
|
mModel = mLoader->GetActiveModel();
|
|
|
|
lcGetPiecesLibrary()->UnloadUnusedParts();
|
|
|
|
Redraw();
|
|
|
|
}
|
|
|
|
|
|
|
|
void lcPreviewWidget::SetDefaultCamera()
|
|
|
|
{
|
|
|
|
if (!mCamera || !mCamera->IsSimple())
|
|
|
|
mCamera = new lcCamera(true);
|
|
|
|
mCamera->SetViewpoint(LC_VIEWPOINT_HOME);
|
|
|
|
}
|
|
|
|
|
|
|
|
void lcPreviewWidget::SetCamera(lcCamera* Camera) // called by lcModel::DeleteModel()
|
|
|
|
{
|
|
|
|
if (!mCamera || !mCamera->IsSimple())
|
|
|
|
mCamera = new lcCamera(true);
|
|
|
|
|
|
|
|
mCamera->CopyPosition(Camera);
|
|
|
|
}
|
|
|
|
|
|
|
|
lcModel* lcPreviewWidget::GetActiveModel() const
|
|
|
|
{
|
|
|
|
return mModel;
|
|
|
|
}
|
|
|
|
|
|
|
|
void lcPreviewWidget::ZoomExtents()
|
|
|
|
{
|
|
|
|
lcModel* ActiveModel = GetActiveModel();
|
2020-10-07 10:08:58 +02:00
|
|
|
if (ActiveModel)
|
|
|
|
{
|
2020-10-03 12:02:27 +02:00
|
|
|
ActiveModel->ZoomExtents(mCamera, float(mWidth) / float(mHeight));
|
|
|
|
Redraw();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
lcMatrix44 lcPreviewWidget::GetProjectionMatrix() const
|
|
|
|
{
|
|
|
|
float AspectRatio = (float)mWidth / (float)mHeight;
|
|
|
|
|
|
|
|
if (mCamera->IsOrtho())
|
|
|
|
{
|
|
|
|
float OrthoHeight = mCamera->GetOrthoHeight() / 2.0f;
|
|
|
|
float OrthoWidth = OrthoHeight * AspectRatio;
|
|
|
|
|
|
|
|
return lcMatrix44Ortho(-OrthoWidth, OrthoWidth, -OrthoHeight, OrthoHeight, mCamera->m_zNear, mCamera->m_zFar * 4);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return lcMatrix44Perspective(mCamera->m_fovy, AspectRatio, mCamera->m_zNear, mCamera->m_zFar);
|
|
|
|
}
|
|
|
|
|
|
|
|
void lcPreviewWidget::StartOrbitTracking() // called by viewSphere
|
|
|
|
{
|
|
|
|
mTrackTool = LC_TRACKTOOL_ORBIT_XY;
|
|
|
|
|
|
|
|
OnUpdateCursor();
|
|
|
|
|
|
|
|
OnButtonDown(lcTrackButton::Left);
|
|
|
|
}
|
|
|
|
|
|
|
|
void lcPreviewWidget::SetViewpoint(const lcVector3& Position)
|
|
|
|
{
|
|
|
|
if (!mCamera || !mCamera->IsSimple())
|
|
|
|
{
|
|
|
|
lcCamera* OldCamera = mCamera;
|
|
|
|
|
|
|
|
mCamera = new lcCamera(true);
|
|
|
|
|
|
|
|
if (OldCamera)
|
|
|
|
mCamera->CopySettings(OldCamera);
|
|
|
|
}
|
|
|
|
|
|
|
|
mCamera->SetViewpoint(Position);
|
|
|
|
|
|
|
|
Redraw();
|
|
|
|
}
|
|
|
|
|
|
|
|
void lcPreviewWidget::DrawViewport()
|
|
|
|
{
|
|
|
|
mContext->SetWorldMatrix(lcMatrix44Identity());
|
|
|
|
mContext->SetViewMatrix(lcMatrix44Translation(lcVector3(0.375, 0.375, 0.0)));
|
|
|
|
mContext->SetProjectionMatrix(lcMatrix44Ortho(0.0f, mWidth, 0.0f, mHeight, -1.0f, 1.0f));
|
|
|
|
|
|
|
|
mContext->SetDepthWrite(false);
|
|
|
|
glDisable(GL_DEPTH_TEST);
|
|
|
|
|
|
|
|
if (true/*we have an active view*/)
|
|
|
|
{
|
|
|
|
mContext->SetMaterial(lcMaterialType::UnlitColor);
|
|
|
|
mContext->SetColor(lcVector4FromColor(lcGetPreferences().mPreviewActiveColor));
|
|
|
|
float Verts[8] = { 0.0f, 0.0f, mWidth - 1.0f, 0.0f, mWidth - 1.0f, mHeight - 1.0f, 0.0f, mHeight - 1.0f };
|
|
|
|
|
|
|
|
mContext->SetVertexBufferPointer(Verts);
|
|
|
|
mContext->SetVertexFormatPosition(2);
|
|
|
|
mContext->DrawPrimitives(GL_LINE_LOOP, 0, 4);
|
|
|
|
}
|
|
|
|
|
|
|
|
mContext->SetDepthWrite(true);
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
}
|
|
|
|
|
|
|
|
void lcPreviewWidget::DrawAxes()
|
|
|
|
{
|
2020-10-07 10:08:58 +02:00
|
|
|
// glClear(GL_DEPTH_BUFFER_BIT);
|
2020-10-03 12:02:27 +02:00
|
|
|
|
|
|
|
const float Verts[28 * 3] =
|
|
|
|
{
|
|
|
|
0.00f, 0.00f, 0.00f, 20.00f, 0.00f, 0.00f, 12.00f, 3.00f, 0.00f, 12.00f, 2.12f, 2.12f,
|
|
|
|
12.00f, 0.00f, 3.00f, 12.00f, -2.12f, 2.12f, 12.00f, -3.00f, 0.00f, 12.00f, -2.12f, -2.12f,
|
|
|
|
12.00f, 0.00f, -3.00f, 12.00f, 2.12f, -2.12f, 0.00f, 20.00f, 0.00f, 3.00f, 12.00f, 0.00f,
|
|
|
|
2.12f, 12.00f, 2.12f, 0.00f, 12.00f, 3.00f, -2.12f, 12.00f, 2.12f, -3.00f, 12.00f, 0.00f,
|
|
|
|
-2.12f, 12.00f, -2.12f, 0.00f, 12.00f, -3.00f, 2.12f, 12.00f, -2.12f, 0.00f, 0.00f, 20.00f,
|
|
|
|
0.00f, 3.00f, 12.00f, 2.12f, 2.12f, 12.00f, 3.00f, 0.00f, 12.00f, 2.12f, -2.12f, 12.00f,
|
|
|
|
0.00f, -3.00f, 12.00f, -2.12f, -2.12f, 12.00f, -3.00f, 0.00f, 12.00f, -2.12f, 2.12f, 12.00f,
|
|
|
|
};
|
|
|
|
|
|
|
|
const GLushort Indices[78] =
|
|
|
|
{
|
|
|
|
0, 1, 0, 10, 0, 19,
|
|
|
|
1, 2, 3, 1, 3, 4, 1, 4, 5, 1, 5, 6, 1, 6, 7, 1, 7, 8, 1, 8, 9, 1, 9, 2,
|
|
|
|
10, 11, 12, 10, 12, 13, 10, 13, 14, 10, 14, 15, 10, 15, 16, 10, 16, 17, 10, 17, 18, 10, 18, 11,
|
|
|
|
19, 20, 21, 19, 21, 22, 19, 22, 23, 19, 23, 24, 19, 24, 25, 19, 25, 26, 19, 26, 27, 19, 27, 20
|
|
|
|
};
|
|
|
|
|
|
|
|
lcMatrix44 TranslationMatrix = lcMatrix44Translation(lcVector3(30.375f, 30.375f, 0.0f));
|
|
|
|
lcMatrix44 WorldViewMatrix = mCamera->mWorldView;
|
|
|
|
WorldViewMatrix.SetTranslation(lcVector3(0, 0, 0));
|
|
|
|
|
|
|
|
mContext->SetMaterial(lcMaterialType::UnlitColor);
|
|
|
|
mContext->SetWorldMatrix(lcMatrix44Identity());
|
|
|
|
mContext->SetViewMatrix(lcMul(WorldViewMatrix, TranslationMatrix));
|
|
|
|
mContext->SetProjectionMatrix(lcMatrix44Ortho(0, mWidth, 0, mHeight, -50, 50));
|
|
|
|
|
|
|
|
mContext->SetVertexBufferPointer(Verts);
|
|
|
|
mContext->SetVertexFormatPosition(3);
|
|
|
|
mContext->SetIndexBufferPointer(Indices);
|
|
|
|
|
|
|
|
mContext->SetColor(0.0f, 0.0f, 0.0f, 1.0f);
|
|
|
|
mContext->DrawIndexedPrimitives(GL_LINES, 6, GL_UNSIGNED_SHORT, 0);
|
|
|
|
|
|
|
|
mContext->SetColor(0.8f, 0.0f, 0.0f, 1.0f);
|
|
|
|
mContext->DrawIndexedPrimitives(GL_TRIANGLES, 24, GL_UNSIGNED_SHORT, 6 * 2);
|
|
|
|
mContext->SetColor(0.0f, 0.8f, 0.0f, 1.0f);
|
|
|
|
mContext->DrawIndexedPrimitives(GL_TRIANGLES, 24, GL_UNSIGNED_SHORT, (6 + 24) * 2);
|
|
|
|
mContext->SetColor(0.0f, 0.0f, 0.8f, 1.0f);
|
|
|
|
mContext->DrawIndexedPrimitives(GL_TRIANGLES, 24, GL_UNSIGNED_SHORT, (6 + 48) * 2);
|
|
|
|
|
|
|
|
mContext->SetMaterial(lcMaterialType::UnlitTextureModulate);
|
|
|
|
mContext->SetViewMatrix(TranslationMatrix);
|
|
|
|
mContext->BindTexture2D(gTexFont.GetTexture());
|
|
|
|
glEnable(GL_BLEND);
|
|
|
|
|
|
|
|
float TextBuffer[6 * 5 * 3];
|
|
|
|
lcVector3 PosX = lcMul30(lcVector3(25.0f, 0.0f, 0.0f), WorldViewMatrix);
|
|
|
|
gTexFont.GetGlyphTriangles(PosX.x, PosX.y, PosX.z, 'X', TextBuffer);
|
|
|
|
lcVector3 PosY = lcMul30(lcVector3(0.0f, 25.0f, 0.0f), WorldViewMatrix);
|
2020-10-07 12:07:32 +02:00
|
|
|
gTexFont.GetGlyphTriangles(PosY.x, PosY.y, PosY.z, 'Y', TextBuffer + 5 * 6);
|
2020-10-03 12:02:27 +02:00
|
|
|
lcVector3 PosZ = lcMul30(lcVector3(0.0f, 0.0f, 25.0f), WorldViewMatrix);
|
2020-10-07 12:07:32 +02:00
|
|
|
gTexFont.GetGlyphTriangles(PosZ.x, PosZ.y, PosZ.z, 'Z', TextBuffer + 5 * 6 * 2);
|
2020-10-03 12:02:27 +02:00
|
|
|
|
|
|
|
mContext->SetVertexBufferPointer(TextBuffer);
|
|
|
|
mContext->SetVertexFormat(0, 3, 0, 2, 0, false);
|
|
|
|
|
|
|
|
mContext->SetColor(lcVector4FromColor(lcGetPreferences().mAxesColor));
|
|
|
|
mContext->DrawPrimitives(GL_TRIANGLES, 0, 6 * 3);
|
|
|
|
|
|
|
|
glDisable(GL_BLEND);
|
|
|
|
}
|
|
|
|
|
|
|
|
lcTool lcPreviewWidget::GetCurrentTool() const
|
|
|
|
{
|
|
|
|
const lcTool ToolFromTrackTool[] =
|
|
|
|
{
|
|
|
|
LC_TOOL_SELECT, // LC_TRACKTOOL_NONE
|
|
|
|
LC_TOOL_PAN, // LC_TRACKTOOL_PAN
|
|
|
|
LC_TOOL_ROTATE_VIEW, // LC_TRACKTOOL_ORBIT_XY
|
|
|
|
};
|
|
|
|
|
|
|
|
return ToolFromTrackTool[mTrackTool];
|
|
|
|
}
|
|
|
|
|
|
|
|
void lcPreviewWidget::StartTracking(lcTrackButton TrackButton)
|
|
|
|
{
|
|
|
|
mTrackButton = TrackButton;
|
|
|
|
mTrackUpdated = false;
|
|
|
|
mMouseDownX = mInputState.x;
|
|
|
|
mMouseDownY = mInputState.y;
|
|
|
|
lcTool Tool = GetCurrentTool(); // Either LC_TRACKTOOL_NONE (LC_TOOL_SELECT) or LC_TRACKTOOL_ORBIT_XY (LC_TOOL_ROTATE_VIEW)
|
|
|
|
lcModel* ActiveModel = GetActiveModel();
|
|
|
|
|
|
|
|
switch (Tool)
|
|
|
|
{
|
2020-10-07 10:08:58 +02:00
|
|
|
case LC_TOOL_SELECT:
|
|
|
|
break;
|
2020-10-03 12:02:27 +02:00
|
|
|
|
2020-10-07 10:08:58 +02:00
|
|
|
case LC_TOOL_PAN:
|
|
|
|
case LC_TOOL_ROTATE_VIEW:
|
|
|
|
ActiveModel->BeginMouseTool();
|
|
|
|
break;
|
2020-10-03 12:02:27 +02:00
|
|
|
|
2020-10-07 10:08:58 +02:00
|
|
|
case LC_NUM_TOOLS:
|
|
|
|
default:
|
|
|
|
break;
|
2020-10-03 12:02:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
OnUpdateCursor();
|
|
|
|
}
|
|
|
|
|
|
|
|
void lcPreviewWidget::StopTracking(bool Accept)
|
|
|
|
{
|
|
|
|
if (mTrackButton == lcTrackButton::None)
|
|
|
|
return;
|
|
|
|
|
|
|
|
lcTool Tool = GetCurrentTool(); // Either LC_TRACKTOOL_NONE (LC_TOOL_SELECT) or LC_TRACKTOOL_ORBIT_XY (LC_TOOL_ROTATE_VIEW)
|
|
|
|
lcModel* ActiveModel = GetActiveModel();
|
|
|
|
|
|
|
|
switch (Tool)
|
|
|
|
{
|
2020-10-07 10:08:58 +02:00
|
|
|
case LC_TOOL_SELECT:
|
|
|
|
break;
|
2020-10-03 12:02:27 +02:00
|
|
|
|
2020-10-07 10:08:58 +02:00
|
|
|
case LC_TOOL_PAN:
|
|
|
|
case LC_TOOL_ROTATE_VIEW:
|
|
|
|
ActiveModel->EndMouseTool(Tool, Accept);
|
|
|
|
break;
|
2020-10-03 12:02:27 +02:00
|
|
|
|
2020-10-07 10:08:58 +02:00
|
|
|
case LC_NUM_TOOLS:
|
|
|
|
default:
|
|
|
|
break;
|
2020-10-03 12:02:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
mTrackButton = lcTrackButton::None;
|
|
|
|
|
|
|
|
mTrackTool = LC_TRACKTOOL_NONE;
|
|
|
|
|
|
|
|
OnUpdateCursor();
|
|
|
|
}
|
|
|
|
|
|
|
|
void lcPreviewWidget::OnButtonDown(lcTrackButton TrackButton)
|
|
|
|
{
|
|
|
|
switch (mTrackTool)
|
|
|
|
{
|
2020-10-07 10:08:58 +02:00
|
|
|
case LC_TRACKTOOL_NONE:
|
|
|
|
break;
|
2020-10-03 12:02:27 +02:00
|
|
|
|
2020-10-07 10:08:58 +02:00
|
|
|
case LC_TRACKTOOL_PAN:
|
|
|
|
StartTracking(TrackButton);
|
|
|
|
break;
|
2020-10-03 12:02:27 +02:00
|
|
|
|
2020-10-07 10:08:58 +02:00
|
|
|
case LC_TRACKTOOL_ORBIT_XY:
|
|
|
|
StartTracking(TrackButton);
|
|
|
|
break;
|
2020-10-03 12:02:27 +02:00
|
|
|
|
2020-10-07 10:08:58 +02:00
|
|
|
case LC_TRACKTOOL_COUNT:
|
|
|
|
break;
|
2020-10-03 12:02:27 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
lcCursor lcPreviewWidget::GetCursor() const
|
|
|
|
{
|
|
|
|
const lcCursor CursorFromTrackTool[] =
|
|
|
|
{
|
|
|
|
lcCursor::Select, // LC_TRACKTOOL_NONE
|
|
|
|
lcCursor::Pan, // LC_TRACKTOOL_PAN
|
|
|
|
lcCursor::RotateView, // LC_TRACKTOOL_ORBIT_XY
|
|
|
|
};
|
|
|
|
|
|
|
|
static_assert(LC_ARRAY_COUNT(CursorFromTrackTool) == LC_TRACKTOOL_COUNT, "Tracktool array size mismatch.");
|
|
|
|
|
|
|
|
if (mTrackTool >= 0 && mTrackTool < LC_ARRAY_COUNT(CursorFromTrackTool))
|
|
|
|
return CursorFromTrackTool[mTrackTool];
|
|
|
|
|
|
|
|
return lcCursor::Select;
|
|
|
|
}
|
|
|
|
|
|
|
|
void lcPreviewWidget::OnInitialUpdate()
|
|
|
|
{
|
|
|
|
MakeCurrent();
|
|
|
|
|
|
|
|
mContext->SetDefaultState();
|
|
|
|
}
|
|
|
|
|
|
|
|
void lcPreviewWidget::OnDraw()
|
|
|
|
{
|
|
|
|
if (!mModel)
|
|
|
|
return;
|
|
|
|
|
|
|
|
lcPreferences& Preferences = lcGetPreferences();
|
|
|
|
const bool DrawInterface = mWidget != nullptr;
|
|
|
|
|
|
|
|
mScene.SetAllowLOD(Preferences.mAllowLOD && mWidget != nullptr);
|
|
|
|
mScene.SetLODDistance(Preferences.mMeshLODDistance);
|
|
|
|
|
|
|
|
mScene.Begin(mCamera->mWorldView);
|
|
|
|
|
|
|
|
mScene.SetDrawInterface(DrawInterface);
|
|
|
|
|
|
|
|
mModel->GetScene(mScene, mCamera, false /*HighlightNewParts*/, false/*mFadeSteps*/);
|
|
|
|
|
|
|
|
mScene.End();
|
|
|
|
|
|
|
|
mContext->SetDefaultState();
|
|
|
|
|
|
|
|
mContext->SetViewport(0, 0, mWidth, mHeight);
|
|
|
|
|
|
|
|
mModel->DrawBackground(this);
|
|
|
|
|
|
|
|
mContext->SetProjectionMatrix(GetProjectionMatrix());
|
|
|
|
|
|
|
|
mContext->SetLineWidth(Preferences.mLineWidth);
|
|
|
|
|
|
|
|
mScene.Draw(mContext);
|
|
|
|
|
|
|
|
if (DrawInterface)
|
|
|
|
{
|
|
|
|
mContext->SetLineWidth(1.0f);
|
|
|
|
|
|
|
|
if (Preferences.mDrawPreviewAxis)
|
|
|
|
DrawAxes();
|
|
|
|
|
|
|
|
if (Preferences.mDrawPreviewViewSphere)
|
|
|
|
mViewSphere.Draw();
|
|
|
|
DrawViewport();
|
|
|
|
}
|
|
|
|
|
|
|
|
mContext->ClearResources();
|
|
|
|
}
|
|
|
|
|
|
|
|
void lcPreviewWidget::OnUpdateCursor()
|
|
|
|
{
|
|
|
|
SetCursor(GetCursor());
|
|
|
|
}
|
|
|
|
|
|
|
|
void lcPreviewWidget::OnLeftButtonDown()
|
|
|
|
{
|
|
|
|
if (mTrackButton != lcTrackButton::None)
|
|
|
|
{
|
|
|
|
StopTracking(false);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mViewSphere.OnLeftButtonDown())
|
|
|
|
return;
|
|
|
|
|
|
|
|
lcTrackTool OverrideTool = LC_TRACKTOOL_ORBIT_XY;
|
|
|
|
|
|
|
|
if (OverrideTool != LC_TRACKTOOL_NONE)
|
|
|
|
{
|
|
|
|
mTrackTool = OverrideTool;
|
|
|
|
OnUpdateCursor();
|
|
|
|
}
|
|
|
|
|
|
|
|
OnButtonDown(lcTrackButton::Left);
|
|
|
|
}
|
|
|
|
|
|
|
|
void lcPreviewWidget::OnLeftButtonUp()
|
|
|
|
{
|
|
|
|
StopTracking(mTrackButton == lcTrackButton::Left);
|
|
|
|
|
|
|
|
if (mViewSphere.OnLeftButtonUp()) {
|
|
|
|
ZoomExtents();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void lcPreviewWidget::OnMiddleButtonDown()
|
|
|
|
{
|
|
|
|
if (mTrackButton != lcTrackButton::None)
|
|
|
|
{
|
|
|
|
StopTracking(false);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if (QT_VERSION >= QT_VERSION_CHECK(4, 7, 0))
|
|
|
|
lcTrackTool OverrideTool = LC_TRACKTOOL_NONE;
|
|
|
|
|
|
|
|
if (OverrideTool != LC_TRACKTOOL_NONE)
|
|
|
|
{
|
|
|
|
mTrackTool = OverrideTool;
|
|
|
|
OnUpdateCursor();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
OnButtonDown(lcTrackButton::Middle);
|
|
|
|
}
|
|
|
|
|
|
|
|
void lcPreviewWidget::OnMiddleButtonUp()
|
|
|
|
{
|
|
|
|
StopTracking(mTrackButton == lcTrackButton::Middle);
|
|
|
|
}
|
|
|
|
|
|
|
|
void lcPreviewWidget::OnLeftButtonDoubleClick()
|
|
|
|
{
|
|
|
|
ZoomExtents();
|
|
|
|
Redraw();
|
|
|
|
}
|
|
|
|
|
|
|
|
void lcPreviewWidget::OnRightButtonDown()
|
|
|
|
{
|
|
|
|
if (mTrackButton != lcTrackButton::None)
|
|
|
|
{
|
|
|
|
StopTracking(false);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
lcTrackTool OverrideTool = LC_TRACKTOOL_PAN;
|
|
|
|
|
|
|
|
if (OverrideTool != LC_TRACKTOOL_NONE)
|
|
|
|
{
|
|
|
|
mTrackTool = OverrideTool;
|
|
|
|
OnUpdateCursor();
|
|
|
|
}
|
|
|
|
|
|
|
|
OnButtonDown(lcTrackButton::Middle);
|
|
|
|
}
|
|
|
|
|
|
|
|
void lcPreviewWidget::OnRightButtonUp()
|
|
|
|
{
|
|
|
|
if (mTrackButton != lcTrackButton::None)
|
|
|
|
StopTracking(mTrackButton == lcTrackButton::Right);
|
|
|
|
}
|
|
|
|
|
|
|
|
void lcPreviewWidget::OnMouseMove()
|
|
|
|
{
|
|
|
|
lcModel* ActiveModel = GetActiveModel();
|
|
|
|
|
|
|
|
if (!ActiveModel)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (mTrackButton == lcTrackButton::None)
|
|
|
|
{
|
|
|
|
if (mViewSphere.OnMouseMove())
|
|
|
|
{
|
|
|
|
lcTrackTool NewTrackTool = mViewSphere.IsDragging() ? LC_TRACKTOOL_ORBIT_XY : LC_TRACKTOOL_NONE;
|
|
|
|
|
|
|
|
if (NewTrackTool != mTrackTool)
|
|
|
|
{
|
|
|
|
mTrackTool = NewTrackTool;
|
|
|
|
OnUpdateCursor();
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
mTrackUpdated = true;
|
|
|
|
const float MouseSensitivity = 0.5f / (21.0f - lcGetPreferences().mMouseSensitivity);
|
|
|
|
|
|
|
|
switch (mTrackTool)
|
|
|
|
{
|
2020-10-07 10:08:58 +02:00
|
|
|
case LC_TRACKTOOL_NONE:
|
|
|
|
break;
|
2020-10-03 12:02:27 +02:00
|
|
|
|
2020-10-07 10:08:58 +02:00
|
|
|
case LC_TRACKTOOL_PAN:
|
2020-10-03 12:02:27 +02:00
|
|
|
{
|
|
|
|
lcVector3 Points[4] =
|
|
|
|
{
|
|
|
|
lcVector3((float)mInputState.x, (float)mInputState.y, 0.0f),
|
|
|
|
lcVector3((float)mInputState.x, (float)mInputState.y, 1.0f),
|
|
|
|
lcVector3(mMouseDownX, mMouseDownY, 0.0f),
|
|
|
|
lcVector3(mMouseDownX, mMouseDownY, 1.0f)
|
|
|
|
};
|
|
|
|
|
|
|
|
UnprojectPoints(Points, 4);
|
|
|
|
|
|
|
|
const lcVector3& CurrentStart = Points[0];
|
|
|
|
const lcVector3& CurrentEnd = Points[1];
|
|
|
|
const lcVector3& MouseDownStart = Points[2];
|
|
|
|
const lcVector3& MouseDownEnd = Points[3];
|
|
|
|
lcVector3 Center = ActiveModel->GetSelectionOrModelCenter();
|
|
|
|
|
|
|
|
lcVector3 PlaneNormal(mCamera->mPosition - mCamera->mTargetPosition);
|
|
|
|
lcVector4 Plane(PlaneNormal, -lcDot(PlaneNormal, Center));
|
|
|
|
lcVector3 Intersection, MoveStart;
|
|
|
|
|
|
|
|
if (!lcLineSegmentPlaneIntersection(&Intersection, CurrentStart, CurrentEnd, Plane) || !lcLineSegmentPlaneIntersection(&MoveStart, MouseDownStart, MouseDownEnd, Plane))
|
|
|
|
{
|
|
|
|
Center = MouseDownStart + lcNormalize(MouseDownEnd - MouseDownStart) * 10.0f;
|
|
|
|
Plane = lcVector4(PlaneNormal, -lcDot(PlaneNormal, Center));
|
|
|
|
|
|
|
|
if (!lcLineSegmentPlaneIntersection(&Intersection, CurrentStart, CurrentEnd, Plane) || !lcLineSegmentPlaneIntersection(&MoveStart, MouseDownStart, MouseDownEnd, Plane))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
ActiveModel->UpdatePanTool(mCamera, MoveStart - Intersection);
|
|
|
|
Redraw();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2020-10-07 10:08:58 +02:00
|
|
|
case LC_TRACKTOOL_ORBIT_XY:
|
|
|
|
ActiveModel->UpdateOrbitTool(mCamera, 0.1f * MouseSensitivity * (mInputState.x - mMouseDownX), 0.1f * MouseSensitivity * (mInputState.y - mMouseDownY));
|
|
|
|
Redraw();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case LC_TRACKTOOL_COUNT:
|
|
|
|
break;
|
2020-10-03 12:02:27 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void lcPreviewWidget::OnMouseWheel(float Direction)
|
|
|
|
{
|
|
|
|
mModel->Zoom(mCamera, (int)(((mInputState.Modifiers & Qt::ControlModifier) ? 100 : 10) * Direction));
|
|
|
|
Redraw();
|
2020-10-07 12:07:32 +02:00
|
|
|
}
|