From 2ca5665235bda59f76af02ead9d976815d4b8bcd Mon Sep 17 00:00:00 2001 From: leo Date: Sun, 5 Oct 2014 05:21:51 +0000 Subject: [PATCH] Moved mouse handling to the model. --- common/lc_application.cpp | 15 +- common/lc_application.h | 6 +- common/lc_basewindow.h | 1 - common/lc_commands.cpp | 56 -- common/lc_commands.h | 8 - common/lc_mainwindow.cpp | 43 ++ common/lc_mainwindow.h | 75 ++- common/lc_model.cpp | 581 +++++++++++++++++ common/lc_model.h | 38 ++ common/lc_profile.cpp | 4 +- common/lc_profile.h | 4 +- common/lc_texture.cpp | 19 + common/lc_texture.h | 3 + common/project.cpp | 1165 +++++----------------------------- common/project.h | 85 +-- common/system.h | 2 - common/view.cpp | 2 +- qt/lc_qmainwindow.cpp | 117 ++-- qt/lc_qmainwindow.h | 2 +- qt/lc_qpreferencesdialog.cpp | 14 +- qt/qtmain.cpp | 4 +- qt/system.cpp | 4 - 22 files changed, 1004 insertions(+), 1244 deletions(-) diff --git a/common/lc_application.cpp b/common/lc_application.cpp index 2e8a945c..785fec15 100644 --- a/common/lc_application.cpp +++ b/common/lc_application.cpp @@ -15,6 +15,8 @@ lcApplication* g_App; void lcPreferences::LoadDefaults() { + mForceGlobalTransforms = lcGetProfileInt(LC_PROFILE_FORCE_GLOBAL_TRANSFORMS); + mFixedAxes = lcGetProfileInt(LC_PROFILE_FIXED_AXES); mMouseSensitivity = lcGetProfileInt(LC_PROFILE_MOUSE_SENSITIVITY); mLightingMode = (lcLightingMode)lcGetProfileInt(LC_PROFILE_LIGHTING_MODE); mDrawAxes = lcGetProfileInt(LC_PROFILE_DRAW_AXES); @@ -29,6 +31,8 @@ void lcPreferences::LoadDefaults() void lcPreferences::SaveDefaults() { + lcSetProfileInt(LC_PROFILE_FORCE_GLOBAL_TRANSFORMS, mForceGlobalTransforms); + lcSetProfileInt(LC_PROFILE_FIXED_AXES, mFixedAxes); lcSetProfileInt(LC_PROFILE_MOUSE_SENSITIVITY, mMouseSensitivity); lcSetProfileInt(LC_PROFILE_LIGHTING_MODE, mLightingMode); lcSetProfileInt(LC_PROFILE_DRAW_AXES, mDrawAxes); @@ -41,6 +45,14 @@ void lcPreferences::SaveDefaults() lcSetProfileInt(LC_PROFILE_GRID_LINE_COLOR, mGridLineColor); } +void lcPreferences::SetForceGlobalTransforms(bool ForceGlobalTransforms) +{ + mForceGlobalTransforms = ForceGlobalTransforms; + lcSetProfileInt(LC_PROFILE_FORCE_GLOBAL_TRANSFORMS, mForceGlobalTransforms); + gMainWindow->UpdateLockSnap(); + gMainWindow->UpdateAllViews(); +} + lcApplication::lcApplication() { mProject = NULL; @@ -408,7 +420,6 @@ void lcApplication::ShowPreferencesDialog() strcpy(Options.LGEOPath, lcGetProfileString(LC_PROFILE_POVRAY_LGEO_PATH)); Options.CheckForUpdates = lcGetProfileInt(LC_PROFILE_CHECK_UPDATES); - Options.Snap = lcGetActiveProject()->m_nSnap; Options.AASamples = CurrentAASamples; Options.Categories = gCategories; @@ -426,7 +437,6 @@ void lcApplication::ShowPreferencesDialog() bool AAChanged = CurrentAASamples != Options.AASamples; mPreferences = Options.Preferences; - lcGetActiveProject()->m_nSnap = Options.Snap; mPreferences.SaveDefaults(); @@ -436,7 +446,6 @@ void lcApplication::ShowPreferencesDialog() lcSetProfileString(LC_PROFILE_POVRAY_PATH, Options.POVRayPath); lcSetProfileString(LC_PROFILE_POVRAY_LGEO_PATH, Options.LGEOPath); lcSetProfileInt(LC_PROFILE_CHECK_UPDATES, Options.CheckForUpdates); - lcSetProfileInt(LC_PROFILE_SNAP, Options.Snap); lcSetProfileInt(LC_PROFILE_ANTIALIASING_SAMPLES, Options.AASamples); if (LibraryChanged && AAChanged) diff --git a/common/lc_application.h b/common/lc_application.h index 734920b8..4aa8d6b4 100644 --- a/common/lc_application.h +++ b/common/lc_application.h @@ -20,6 +20,8 @@ public: void LoadDefaults(); void SaveDefaults(); + void SetForceGlobalTransforms(bool ForceGlobalTransforms); + int mMouseSensitivity; lcLightingMode mLightingMode; bool mDrawAxes; @@ -30,6 +32,8 @@ public: bool mDrawGridLines; int mGridLineSpacing; lcuint32 mGridLineColor; + bool mForceGlobalTransforms; + bool mFixedAxes; }; class lcApplication @@ -72,7 +76,7 @@ inline Project* lcGetActiveProject() return g_App->mProject; } -inline const lcPreferences& lcGetPreferences() +inline lcPreferences& lcGetPreferences() { return g_App->mPreferences; } diff --git a/common/lc_basewindow.h b/common/lc_basewindow.h index 07c5b581..1a161a01 100644 --- a/common/lc_basewindow.h +++ b/common/lc_basewindow.h @@ -132,7 +132,6 @@ struct lcPreferencesDialogOptions char LGEOPath[LC_MAXPATH]; int CheckForUpdates; - lcuint32 Snap; int AASamples; lcArray Categories; diff --git a/common/lc_commands.cpp b/common/lc_commands.cpp index f46df73a..668953bf 100644 --- a/common/lc_commands.cpp +++ b/common/lc_commands.cpp @@ -256,13 +256,6 @@ lcCommand gCommands[LC_NUM_COMMANDS] = QT_TRANSLATE_NOOP("Status", "Prevents movement and rotation along the Z axis"), QT_TRANSLATE_NOOP("Shortcut", "") }, - // LC_EDIT_LOCK_TOGGLE - { - "Edit.Lock.Toggle", - QT_TRANSLATE_NOOP("Menu", "Lock Toggle"), - QT_TRANSLATE_NOOP("Status", "Toggle locked axes"), - QT_TRANSLATE_NOOP("Shortcut", "") - }, // LC_EDIT_LOCK_NONE { "Edit.Lock.None", @@ -277,55 +270,6 @@ lcCommand gCommands[LC_NUM_COMMANDS] = QT_TRANSLATE_NOOP("Status", "Enable relative movement and rotation"), QT_TRANSLATE_NOOP("Shortcut", "") }, - // LC_EDIT_SNAP_X - { - "Edit.Snap.SnapX", - QT_TRANSLATE_NOOP("Menu", "Snap X"), - QT_TRANSLATE_NOOP("Status", "Snap movement along the X axis to fixed intervals"), - QT_TRANSLATE_NOOP("Shortcut", "") - }, - // LC_EDIT_SNAP_Y - { - "Edit.Snap.SnapY", - QT_TRANSLATE_NOOP("Menu", "Snap Y"), - QT_TRANSLATE_NOOP("Status", "Snap movement along the Y axis to fixed intervals"), - QT_TRANSLATE_NOOP("Shortcut", "") - }, - // LC_EDIT_SNAP_Z - { - "Edit.Snap.SnapZ", - QT_TRANSLATE_NOOP("Menu", "Snap Z"), - QT_TRANSLATE_NOOP("Status", "Snap movement along the Z axis to fixed intervals"), - QT_TRANSLATE_NOOP("Shortcut", "") - }, - // LC_EDIT_SNAP_TOGGLE - { - "Edit.Snap.Toggle", - QT_TRANSLATE_NOOP("Menu", "Snap Toggle"), - QT_TRANSLATE_NOOP("Status", "Toggle snap axes"), - QT_TRANSLATE_NOOP("Shortcut", "") - }, - // LC_EDIT_SNAP_NONE - { - "Edit.Snap.None", - QT_TRANSLATE_NOOP("Menu", "Snap None"), - QT_TRANSLATE_NOOP("Status", "Disable snapping along all axes"), - QT_TRANSLATE_NOOP("Shortcut", "") - }, - // LC_EDIT_SNAP_ALL - { - "Edit.Snap.All", - QT_TRANSLATE_NOOP("Menu", "Snap All"), - QT_TRANSLATE_NOOP("Status", "Snap movement along all axes to fixed intervals"), - QT_TRANSLATE_NOOP("Shortcut", "") - }, - // LC_EDIT_SNAP_ANGLE - { - "Edit.SnapAngle.Toggle", - QT_TRANSLATE_NOOP("Menu", "Snap Angle Toggle"), - QT_TRANSLATE_NOOP("Status", "Snap rotations to fixed intervals"), - QT_TRANSLATE_NOOP("Shortcut", "") - }, // LC_EDIT_SNAP_MOVE_XY0 { "Edit.SnapMove.XY0", diff --git a/common/lc_commands.h b/common/lc_commands.h index 2145adb8..ad2762f4 100644 --- a/common/lc_commands.h +++ b/common/lc_commands.h @@ -41,16 +41,8 @@ enum LC_COMMANDS LC_EDIT_LOCK_X, LC_EDIT_LOCK_Y, LC_EDIT_LOCK_Z, - LC_EDIT_LOCK_TOGGLE, LC_EDIT_LOCK_NONE, LC_EDIT_SNAP_RELATIVE, - LC_EDIT_SNAP_X, - LC_EDIT_SNAP_Y, - LC_EDIT_SNAP_Z, - LC_EDIT_SNAP_TOGGLE, - LC_EDIT_SNAP_NONE, - LC_EDIT_SNAP_ALL, - LC_EDIT_SNAP_ANGLE, LC_EDIT_SNAP_MOVE_XY0, LC_EDIT_SNAP_MOVE_XY1, LC_EDIT_SNAP_MOVE_XY2, diff --git a/common/lc_mainwindow.cpp b/common/lc_mainwindow.cpp index 5ef64dd9..9cc28bca 100644 --- a/common/lc_mainwindow.cpp +++ b/common/lc_mainwindow.cpp @@ -13,6 +13,13 @@ lcMainWindow::lcMainWindow() mTransformType = LC_TRANSFORM_RELATIVE_TRANSLATION; mAddKeys = false; + mMoveXYSnapIndex = 4; + mMoveZSnapIndex = 3; + mAngleSnapIndex = 5; + mLockX = false; + mLockY = false; + mLockZ = false; + memset(&mSearchOptions, 0, sizeof(mSearchOptions)); for (int FileIdx = 0; FileIdx < LC_MAX_RECENT_FILES; FileIdx++) @@ -83,6 +90,42 @@ void lcMainWindow::SetColorIndex(int ColorIndex) mPreviewWidget->Redraw(); } +void lcMainWindow::SetMoveXYSnapIndex(int Index) +{ + mMoveXYSnapIndex = Index; + UpdateSnap(); +} + +void lcMainWindow::SetMoveZSnapIndex(int Index) +{ + mMoveZSnapIndex = Index; + UpdateSnap(); +} + +void lcMainWindow::SetAngleSnapIndex(int Index) +{ + mAngleSnapIndex = Index; + UpdateSnap(); +} + +void lcMainWindow::SetLockX(bool LockX) +{ + mLockX = LockX; + UpdateLockSnap(); +} + +void lcMainWindow::SetLockY(bool LockY) +{ + mLockY = LockY; + UpdateLockSnap(); +} + +void lcMainWindow::SetLockZ(bool LockZ) +{ + mLockZ = LockZ; + UpdateLockSnap(); +} + void lcMainWindow::AddRecentFile(const char* FileName) { int FileIdx; diff --git a/common/lc_mainwindow.h b/common/lc_mainwindow.h index 93b2885b..15e99cf4 100644 --- a/common/lc_mainwindow.h +++ b/common/lc_mainwindow.h @@ -41,6 +41,66 @@ public: return mAddKeys; } + int GetMoveXYSnap() const + { + const int SnapXYTable[] = { 0, 1, 5, 8, 10, 20, 40, 60, 80, 160 }; + return SnapXYTable[mMoveXYSnapIndex]; + } + + int GetMoveZSnap() const + { + const int SnapZTable[] = { 0, 1, 5, 8, 10, 20, 24, 48, 96, 192 }; + return SnapZTable[mMoveZSnapIndex]; + } + + int GetAngleSnap() const + { + const int AngleTable[] = { 0, 1, 5, 10, 15, 30, 45, 60, 90, 180 }; + return AngleTable[mAngleSnapIndex]; + } + + int GetMoveXYSnapIndex() const + { + return mMoveXYSnapIndex; + } + + int GetMoveZSnapIndex() const + { + return mMoveZSnapIndex; + } + + int GetAngleSnapIndex() const + { + return mAngleSnapIndex; + } + + const char* GetMoveXYSnapText() const + { + const char* SnapXYText[] = { "0", "1/20S", "1/4S", "1F", "1/2S", "1S", "2S", "3S", "4S", "8S" }; + return SnapXYText[mMoveXYSnapIndex]; + } + + const char* GetMoveZSnapText() const + { + const char* SnapZText[] = { "0", "1/20S", "1/4S", "1F", "1/2S", "1S", "1B", "2B", "4B", "8B" }; + return SnapZText[mMoveZSnapIndex]; + } + + bool GetLockX() const + { + return mLockX; + } + + bool GetLockY() const + { + return mLockY; + } + + bool GetLockZ() const + { + return mLockZ; + } + View* GetActiveView() const { return mActiveView; @@ -59,6 +119,13 @@ public: void SetTool(lcTool Tool); void SetTransformType(lcTransformType TransformType); void SetColorIndex(int ColorIndex); + void SetMoveXYSnapIndex(int Index); + void SetMoveZSnapIndex(int Index); + void SetAngleSnapIndex(int Index); + void SetLockX(bool LockX); + void SetLockY(bool LockY); + void SetLockZ(bool LockZ); + void Close(); void AddRecentFile(const char* FileName); @@ -78,7 +145,7 @@ public: void UpdatePaste(bool Enabled); void UpdateCurrentStep(); void SetAddKeys(bool AddKeys); - void UpdateLockSnap(lcuint32 Snap); + void UpdateLockSnap(); void UpdateSnap(); void UpdateUndoRedo(const QString& UndoText, const QString& RedoText); void UpdateCurrentCamera(int CameraIndex); @@ -104,6 +171,12 @@ protected: bool mAddKeys; lcTool mTool; lcTransformType mTransformType; + int mMoveXYSnapIndex; + int mMoveZSnapIndex; + int mAngleSnapIndex; + bool mLockX; + bool mLockY; + bool mLockZ; }; extern class lcMainWindow* gMainWindow; diff --git a/common/lc_model.cpp b/common/lc_model.cpp index 6dd2dbf2..328794ac 100644 --- a/common/lc_model.cpp +++ b/common/lc_model.cpp @@ -7,6 +7,9 @@ #include "lc_mainwindow.h" #include "lc_profile.h" #include "lc_library.h" +#include "lc_texture.h" +#include "view.h" +#include "preview.h" void lcModelProperties::LoadDefaults() { @@ -139,11 +142,42 @@ void lcModelProperties::ParseLDrawLine(QTextStream& Stream) lcModel::lcModel() { + mBackgroundTexture = NULL; mSavedHistory = NULL; } lcModel::~lcModel() { + DeleteModel(); + DeleteHistory(); +} + +void lcModel::DeleteHistory() +{ + mUndoHistory.DeleteAll(); + mRedoHistory.DeleteAll(); +} + +void lcModel::DeleteModel() +{ + lcReleaseTexture(mBackgroundTexture); + mBackgroundTexture = NULL; + + const lcArray Views = gMainWindow->GetViews(); + + for (int ViewIdx = 0; ViewIdx < Views.GetSize(); ViewIdx++) + { + View* View = Views[ViewIdx]; + lcCamera* Camera = View->mCamera; + + if (!Camera->IsSimple()) + View->SetCamera(Camera, true); + } + + mPieces.DeleteAll(); + mCameras.DeleteAll(); + mLights.DeleteAll(); + mGroups.DeleteAll(); } void lcModel::SaveLDraw(QTextStream& Stream) const @@ -386,11 +420,28 @@ void lcModel::LoadLDraw(QTextStream& Stream) } } + CalculateStep(); + UpdateBackgroundTexture(); + delete Piece; delete Camera; delete Light; } +void lcModel::UpdateBackgroundTexture() +{ + lcReleaseTexture(mBackgroundTexture); + mBackgroundTexture = NULL; + + if (mProperties.mBackgroundType == LC_BACKGROUND_IMAGE) + { + mBackgroundTexture = lcLoadTexture(mProperties.mBackgroundImage, LC_TEXTURE_WRAPU | LC_TEXTURE_WRAPV); + + if (!mBackgroundTexture) + mProperties.mBackgroundType = LC_BACKGROUND_SOLID; + } +} + void lcModel::RayTest(lcObjectRayTest& ObjectRayTest) const { for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++) @@ -456,6 +507,20 @@ void lcModel::SaveCheckpoint(const QString& Description) gMainWindow->UpdateUndoRedo(mUndoHistory.GetSize() > 1 ? mUndoHistory[0]->Description : QString(), !mRedoHistory.IsEmpty() ? mRedoHistory[0]->Description : QString()); } +void lcModel::LoadCheckPoint(lcModelHistoryEntry* CheckPoint) +{ + DeleteModel(); + + QTextStream Stream(CheckPoint->File, QIODevice::ReadOnly); + LoadLDraw(Stream); + + gMainWindow->UpdateFocusObject(GetFocusObject()); + gMainWindow->UpdateCameraMenu(); + UpdateSelection(); + gMainWindow->UpdateCurrentStep(); + gMainWindow->UpdateAllViews(); +} + void lcModel::CalculateStep() { for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++) @@ -513,6 +578,246 @@ lcGroup* lcModel::GetGroup(const char* Name, bool CreateIfMissing) return NULL; } +void lcModel::RemoveEmptyGroups() +{ + bool Removed; + + do + { + Removed = false; + + for (int GroupIdx = 0; GroupIdx < mGroups.GetSize();) + { + lcGroup* Group = mGroups[GroupIdx]; + int Ref = 0; + + for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++) + if (mPieces[PieceIdx]->GetGroup() == Group) + Ref++; + + for (int ParentIdx = 0; ParentIdx < mGroups.GetSize(); ParentIdx++) + if (mGroups[ParentIdx]->mGroup == Group) + Ref++; + + if (Ref > 1) + { + GroupIdx++; + continue; + } + + if (Ref != 0) + { + for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++) + { + lcPiece* Piece = mPieces[PieceIdx]; + + if (Piece->GetGroup() == Group) + { + Piece->SetGroup(Group->mGroup); + break; + } + } + + for (int ParentIdx = 0; ParentIdx < mGroups.GetSize(); ParentIdx++) + { + if (mGroups[ParentIdx]->mGroup == Group) + { + mGroups[ParentIdx]->mGroup = Group->mGroup; + break; + } + } + } + + mGroups.RemoveIndex(GroupIdx); + delete Group; + Removed = true; + } + } + while (Removed); +} + +#include "project.h" +#include "lc_application.h" + +lcMatrix44 lcModel::GetRelativeRotation() const +{ + const lcPreferences& Preferences = lcGetPreferences(); + + if (!Preferences.mForceGlobalTransforms) + { + lcObject* Focus = GetFocusObject(); + + if ((Focus != NULL) && Focus->IsPiece()) + { + lcMatrix44 WorldMatrix = ((lcPiece*)Focus)->mModelWorld; + WorldMatrix.SetTranslation(lcVector3(0.0f, 0.0f, 0.0f)); + return WorldMatrix; + } + } + + return lcMatrix44Identity(); +} + +bool lcModel::MoveSelectedObjects(const lcVector3& PieceDistance, const lcVector3& ObjectDistance) +{ + lcMatrix44 RelativeRotation = GetRelativeRotation(); + bool Moved = false; + + if (PieceDistance.LengthSquared() >= 0.001f) + { + lcVector3 TransformedPieceDistance = lcMul30(PieceDistance, RelativeRotation); + + for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++) + { + lcPiece* Piece = mPieces[PieceIdx]; + + if (Piece->IsSelected()) + { + Piece->Move(mCurrentStep, gMainWindow->GetAddKeys(), TransformedPieceDistance); + Piece->UpdatePosition(mCurrentStep); + Moved = true; + } + } + } + + if (ObjectDistance.LengthSquared() >= 0.001f) + { + lcVector3 TransformedObjectDistance = lcMul30(ObjectDistance, RelativeRotation); + + for (int CameraIdx = 0; CameraIdx < mCameras.GetSize(); CameraIdx++) + { + lcCamera* Camera = mCameras[CameraIdx]; + + if (Camera->IsSelected()) + { + Camera->Move(mCurrentStep, gMainWindow->GetAddKeys(), TransformedObjectDistance); + Camera->UpdatePosition(mCurrentStep); + Moved = true; + } + } + + for (int LightIdx = 0; LightIdx < mLights.GetSize(); LightIdx++) + { + lcLight* Light = mLights[LightIdx]; + + if (Light->IsSelected()) + { + Light->Move(mCurrentStep, gMainWindow->GetAddKeys(), TransformedObjectDistance); + Light->UpdatePosition(mCurrentStep); + Moved = true; + } + } + } + + return Moved; +} + +bool lcModel::RotateSelectedPieces(const lcVector3& Angles) +{ + if (Angles.LengthSquared() < 0.001f) + return false; + + float Bounds[6] = { FLT_MAX, FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX, -FLT_MAX }; + lcPiece* Focus = NULL; + int SelectedCount = 0; + + for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++) + { + lcPiece* Piece = mPieces[PieceIdx]; + + if (Piece->IsSelected()) + { + if (Piece->IsFocused()) + Focus = Piece; + + Piece->CompareBoundingBox(Bounds); + SelectedCount++; + } + } + + lcVector3 Center; + + if (Focus) + Center = Focus->mPosition; + else + Center = lcVector3((Bounds[0] + Bounds[3]) / 2.0f, (Bounds[1] + Bounds[4]) / 2.0f, (Bounds[2] + Bounds[5]) / 2.0f); + + // Create the rotation matrix. + lcVector4 RotationQuaternion(0, 0, 0, 1); + lcVector4 WorldToFocusQuaternion, FocusToWorldQuaternion; + + if (Angles[0] != 0.0f) + { + lcVector4 q = lcQuaternionRotationX(Angles[0] * LC_DTOR); + RotationQuaternion = lcQuaternionMultiply(q, RotationQuaternion); + } + + if (Angles[1] != 0.0f) + { + lcVector4 q = lcQuaternionRotationY(Angles[1] * LC_DTOR); + RotationQuaternion = lcQuaternionMultiply(q, RotationQuaternion); + } + + if (Angles[2] != 0.0f) + { + lcVector4 q = lcQuaternionRotationZ(Angles[2] * LC_DTOR); + RotationQuaternion = lcQuaternionMultiply(q, RotationQuaternion); + } + + const lcPreferences& Preferences = lcGetPreferences(); + if (Preferences.mForceGlobalTransforms) + Focus = NULL; + + if (Focus) + { + const lcVector4& Rotation = Focus->mRotation; + + WorldToFocusQuaternion = lcQuaternionFromAxisAngle(lcVector4(Rotation[0], Rotation[1], Rotation[2], -Rotation[3] * LC_DTOR)); + FocusToWorldQuaternion = lcQuaternionFromAxisAngle(lcVector4(Rotation[0], Rotation[1], Rotation[2], Rotation[3] * LC_DTOR)); + + RotationQuaternion = lcQuaternionMultiply(FocusToWorldQuaternion, RotationQuaternion); + } + + for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++) + { + lcPiece* Piece = mPieces[PieceIdx]; + + if (!Piece->IsSelected()) + continue; + + const lcVector4& Rotation = Piece->mRotation; + lcVector3 Distance = Piece->mPosition - Center; + lcVector4 LocalToWorldQuaternion = lcQuaternionFromAxisAngle(lcVector4(Rotation[0], Rotation[1], Rotation[2], Rotation[3] * LC_DTOR)); + lcVector4 NewRotation, NewLocalToWorldQuaternion; + + if (Focus) + { + lcVector4 LocalToFocusQuaternion = lcQuaternionMultiply(WorldToFocusQuaternion, LocalToWorldQuaternion); + NewLocalToWorldQuaternion = lcQuaternionMultiply(RotationQuaternion, LocalToFocusQuaternion); + + lcVector4 WorldToLocalQuaternion = lcQuaternionFromAxisAngle(lcVector4(Rotation[0], Rotation[1], Rotation[2], -Rotation[3] * LC_DTOR)); + + Distance = lcQuaternionMul(Distance, WorldToLocalQuaternion); + Distance = lcQuaternionMul(Distance, NewLocalToWorldQuaternion); + } + else + { + NewLocalToWorldQuaternion = lcQuaternionMultiply(RotationQuaternion, LocalToWorldQuaternion); + + Distance = lcQuaternionMul(Distance, RotationQuaternion); + } + + NewRotation = lcQuaternionToAxisAngle(NewLocalToWorldQuaternion); + NewRotation[3] *= LC_RTOD; + + Piece->SetPosition(Center + Distance, mCurrentStep, gMainWindow->GetAddKeys()); + Piece->SetRotation(NewRotation, mCurrentStep, gMainWindow->GetAddKeys()); + Piece->UpdatePosition(mCurrentStep); + } + + return true; +} + lcObject* lcModel::GetFocusObject() const { for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++) @@ -542,6 +847,27 @@ lcObject* lcModel::GetFocusObject() const return NULL; } +bool lcModel::GetSelectionCenter(lcVector3& Center) const +{ + float Bounds[6] = { FLT_MAX, FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX, -FLT_MAX }; + bool Selected = false; + + for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++) + { + lcPiece* Piece = mPieces[PieceIdx]; + + if (Piece->IsSelected()) + { + Piece->CompareBoundingBox(Bounds); + Selected = true; + } + } + + Center = lcVector3((Bounds[0] + Bounds[3]) * 0.5f, (Bounds[1] + Bounds[4]) * 0.5f, (Bounds[2] + Bounds[5]) * 0.5f); + + return Selected; +} + void lcModel::UpdateSelection() const { int Flags = 0; @@ -800,3 +1126,258 @@ void lcModel::FindPiece(bool FindFirst, bool SearchForward) ClearSelectionAndSetFocus(Focus, LC_PIECE_SECTION_POSITION); } + +void lcModel::BeginMouseTool() +{ + mMouseToolDistance = lcVector3(0.0f, 0.0f, 0.0f); +} + +void lcModel::EndMouseTool(lcTool Tool, bool Accept) +{ + if (!Accept) + { + LoadCheckPoint(mUndoHistory[0]); + return; + } + + switch (Tool) + { + case LC_TOOL_INSERT: + case LC_TOOL_LIGHT: + break; + + case LC_TOOL_SPOTLIGHT: + SaveCheckpoint(tr("New SpotLight")); + break; + + case LC_TOOL_CAMERA: + gMainWindow->UpdateCameraMenu(); + SaveCheckpoint(tr("New Camera")); + break; + + case LC_TOOL_SELECT: + break; + + case LC_TOOL_MOVE: + SaveCheckpoint(tr("Move")); + break; + + case LC_TOOL_ROTATE: + SaveCheckpoint(tr("Rotate")); + break; + + case LC_TOOL_ERASER: + case LC_TOOL_PAINT: + break; + + case LC_TOOL_ZOOM: + if (!gMainWindow->GetActiveView()->mCamera->IsSimple()) + SaveCheckpoint(tr("Zoom")); + break; + + case LC_TOOL_PAN: + if (!gMainWindow->GetActiveView()->mCamera->IsSimple()) + SaveCheckpoint(tr("Pan")); + break; + + case LC_TOOL_ROTATE_VIEW: + if (!gMainWindow->GetActiveView()->mCamera->IsSimple()) + SaveCheckpoint(tr("Orbit")); + break; + + case LC_TOOL_ROLL: + if (!gMainWindow->GetActiveView()->mCamera->IsSimple()) + SaveCheckpoint(tr("Roll")); + break; + + case LC_TOOL_ZOOM_REGION: + break; + } +} + +void lcModel::InsertPieceToolClicked(const lcVector3& Position, const lcVector4& Rotation) +{ + lcPiece* Piece = new lcPiece(gMainWindow->mPreviewWidget->GetCurrentPiece()); + Piece->Initialize(Position, Rotation, mCurrentStep); + Piece->SetColorIndex(gMainWindow->mColorIndex); + Piece->UpdatePosition(mCurrentStep); + Piece->CreateName(mPieces); + mPieces.Add(Piece); + + ClearSelectionAndSetFocus(Piece, LC_PIECE_SECTION_POSITION); + + SaveCheckpoint(tr("Insert")); +} + +void lcModel::PointLightToolClicked(const lcVector3& Position) +{ + lcLight* Light = new lcLight(Position[0], Position[1], Position[2]); + Light->CreateName(mLights); + mLights.Add(Light); + + ClearSelectionAndSetFocus(Light, LC_LIGHT_SECTION_POSITION); + SaveCheckpoint(tr("New Light")); +} + +void lcModel::BeginSpotLightTool(const lcVector3& Position, const lcVector3& Target) +{ + lcLight* Light = new lcLight(Position[0], Position[1], Position[2], Target[0], Target[1], Target[2]); + mLights.Add(Light); + + ClearSelectionAndSetFocus(Light, LC_LIGHT_SECTION_TARGET); +} + +void lcModel::UpdateSpotLightTool(const lcVector3& Target) +{ + lcLight* Light = mLights[mLights.GetSize() - 1]; + + Light->Move(1, false, Target); + Light->UpdatePosition(1); + + gMainWindow->UpdateFocusObject(Light); + gMainWindow->UpdateAllViews(); +} + +void lcModel::BeginCameraTool(const lcVector3& Position, const lcVector3& Target) +{ + lcCamera* Camera = new lcCamera(Position[0], Position[1], Position[2], Target[0], Target[1], Target[2]); + Camera->CreateName(mCameras); + mCameras.Add(Camera); + + ClearSelectionAndSetFocus(Camera, LC_CAMERA_SECTION_TARGET); +} + +void lcModel::UpdateCameraTool(const lcVector3& Target) +{ + lcCamera* Camera = mCameras[mCameras.GetSize() - 1]; + + Camera->Move(1, false, Target); + Camera->UpdatePosition(1); + + gMainWindow->UpdateFocusObject(Camera); + gMainWindow->UpdateAllViews(); +} + +void lcModel::UpdateMoveTool(const lcVector3& Distance) +{ + lcVector3 PieceDistance = lcGetActiveProject()->LockVector(lcGetActiveProject()->SnapVector(Distance) - lcGetActiveProject()->SnapVector(mMouseToolDistance)); + lcVector3 ObjectDistance = Distance - mMouseToolDistance; + + MoveSelectedObjects(PieceDistance, ObjectDistance); + mMouseToolDistance = Distance; + + gMainWindow->UpdateFocusObject(GetFocusObject()); + gMainWindow->UpdateAllViews(); +} + +void lcModel::UpdateRotateTool(const lcVector3& Angles) +{ + lcVector3 Delta = lcGetActiveProject()->LockVector(lcGetActiveProject()->SnapRotation(Angles) - lcGetActiveProject()->SnapRotation(mMouseToolDistance)); + RotateSelectedPieces(Delta); + mMouseToolDistance = Angles; + + gMainWindow->UpdateFocusObject(GetFocusObject()); + gMainWindow->UpdateAllViews(); +} + +void lcModel::EraserToolClicked(lcObject* Object) +{ + if (!Object) + return; + + switch (Object->GetType()) + { + case LC_OBJECT_PIECE: + mPieces.Remove((lcPiece*)Object); + RemoveEmptyGroups(); + break; + + case LC_OBJECT_CAMERA: + { + const lcArray Views = gMainWindow->GetViews(); + for (int ViewIdx = 0; ViewIdx < Views.GetSize(); ViewIdx++) + { + View* View = Views[ViewIdx]; + lcCamera* Camera = View->mCamera; + + if (Camera == Object) + View->SetCamera(Camera, true); + } + + mCameras.Remove((lcCamera*)Object); + + gMainWindow->UpdateCameraMenu(); + } + break; + + case LC_OBJECT_LIGHT: + mLights.Remove((lcLight*)Object); + break; + } + + delete Object; + gMainWindow->UpdateFocusObject(GetFocusObject()); + UpdateSelection(); + gMainWindow->UpdateAllViews(); + SaveCheckpoint(tr("Deleting")); +} + +void lcModel::PaintToolClicked(lcObject* Object) +{ + if (!Object || Object->GetType() != LC_OBJECT_PIECE) + return; + + lcPiece* Piece = (lcPiece*)Object; + + if (Piece->mColorIndex != gMainWindow->mColorIndex) + { + Piece->SetColorIndex(gMainWindow->mColorIndex); + + SaveCheckpoint(tr("Painting")); + gMainWindow->UpdateFocusObject(GetFocusObject()); + gMainWindow->UpdateAllViews(); + } +} + +void lcModel::UpdateZoomTool(lcCamera* Camera, float Mouse) +{ + Camera->Zoom(Mouse - mMouseToolDistance.x, mCurrentStep, gMainWindow->GetAddKeys()); + mMouseToolDistance.x = Mouse; + gMainWindow->UpdateAllViews(); +} + +void lcModel::UpdatePanTool(lcCamera* Camera, float MouseX, float MouseY) +{ + Camera->Pan(MouseX - mMouseToolDistance.x, MouseY - mMouseToolDistance.y, mCurrentStep, gMainWindow->GetAddKeys()); + mMouseToolDistance.x = MouseX; + mMouseToolDistance.y = MouseY; + gMainWindow->UpdateAllViews(); +} + +void lcModel::UpdateOrbitTool(lcCamera* Camera, float MouseX, float MouseY) +{ + lcVector3 Center; + GetSelectionCenter(Center); + Camera->Orbit(MouseX - mMouseToolDistance.x, MouseY - mMouseToolDistance.y, Center, mCurrentStep, gMainWindow->GetAddKeys()); + mMouseToolDistance.x = MouseX; + mMouseToolDistance.y = MouseY; + gMainWindow->UpdateAllViews(); +} + +void lcModel::UpdateRollTool(lcCamera* Camera, float Mouse) +{ + Camera->Roll(Mouse - mMouseToolDistance.x, mCurrentStep, gMainWindow->GetAddKeys()); + mMouseToolDistance.x = Mouse; + gMainWindow->UpdateAllViews(); +} + +void lcModel::ZoomRegionToolClicked(lcCamera* Camera, const lcVector3* Points, float RatioX, float RatioY) +{ + Camera->ZoomRegion(Points, RatioX, RatioY, mCurrentStep, gMainWindow->GetAddKeys()); + + gMainWindow->UpdateFocusObject(GetFocusObject()); + gMainWindow->UpdateAllViews(); + + if (!Camera->IsSimple()) + SaveCheckpoint(tr("Zoom")); +} diff --git a/common/lc_model.h b/common/lc_model.h index 4307b2d3..7c35c0af 100644 --- a/common/lc_model.h +++ b/common/lc_model.h @@ -147,6 +147,7 @@ public: void BoxTest(lcObjectBoxTest& ObjectBoxTest) const; lcObject* GetFocusObject() const; + bool GetSelectionCenter(lcVector3& Center) const; void FocusOrDeselectObject(const lcObjectSection& ObjectSection); void ClearSelectionAndSetFocus(lcObject* Object, lcuint32 Section); void ClearSelectionAndSetFocus(const lcObjectSection& ObjectSection); @@ -155,9 +156,43 @@ public: void FindPiece(bool FindFirst, bool SearchForward); + lcMatrix44 GetRelativeRotation() const; + + const lcVector3& GetMouseToolDistance() const + { + return mMouseToolDistance; + } + + void BeginMouseTool(); + void EndMouseTool(lcTool Tool, bool Accept); + void InsertPieceToolClicked(const lcVector3& Position, const lcVector4& Rotation); + void PointLightToolClicked(const lcVector3& Position); + void BeginSpotLightTool(const lcVector3& Position, const lcVector3& Target); + void UpdateSpotLightTool(const lcVector3& Target); + void BeginCameraTool(const lcVector3& Position, const lcVector3& Target); + void UpdateCameraTool(const lcVector3& Target); + void UpdateMoveTool(const lcVector3& Distance); + void UpdateRotateTool(const lcVector3& Angles); + void EraserToolClicked(lcObject* Object); + void PaintToolClicked(lcObject* Object); + void UpdateZoomTool(lcCamera* Camera, float Mouse); + void UpdatePanTool(lcCamera* Camera, float MouseX, float MouseY); + void UpdateOrbitTool(lcCamera* Camera, float MouseX, float MouseY); + void UpdateRollTool(lcCamera* Camera, float Mouse); + void ZoomRegionToolClicked(lcCamera* Camera, const lcVector3* Points, float RatioX, float RatioY); + protected: + void DeleteModel(); + void DeleteHistory(); void SaveCheckpoint(const QString& Description); + void LoadCheckPoint(lcModelHistoryEntry* CheckPoint); + + void RemoveEmptyGroups(); + bool MoveSelectedObjects(const lcVector3& PieceDistance, const lcVector3& ObjectDistance); + bool RotateSelectedPieces(const lcVector3& Angles); void CalculateStep(); + void UpdateBackgroundTexture(); + void UpdateSelection() const; void SelectGroup(lcGroup* TopGroup, bool Select); void ClearSelection(bool UpdateInterface); @@ -166,6 +201,7 @@ protected: lcStep mCurrentStep; lcVector3 mMouseToolDistance; + lcTexture* mBackgroundTexture; lcArray mPieces; lcArray mCameras; @@ -175,6 +211,8 @@ protected: lcModelHistoryEntry* mSavedHistory; lcArray mUndoHistory; lcArray mRedoHistory; + + Q_DECLARE_TR_FUNCTIONS(lcModel) }; #endif // _LC_MODEL_H_ diff --git a/common/lc_profile.cpp b/common/lc_profile.cpp index c9cdfb64..0967895a 100644 --- a/common/lc_profile.cpp +++ b/common/lc_profile.cpp @@ -46,8 +46,8 @@ lcProfileEntry::lcProfileEntry(const char* Section, const char* Key) lcProfileEntry gProfileEntries[LC_NUM_PROFILE_KEYS] = { - lcProfileEntry("Settings", "Snap", LC_DRAW_SNAP_A | LC_DRAW_SNAP_XYZ), // LC_PROFILE_SNAP - lcProfileEntry("Settings", "AngleSnap", 30), // LC_PROFILE_ANGLE_SNAP + lcProfileEntry("Settings", "ForceGlobalTransforms", false), // LC_PROFILE_FORCE_GLOBAL_TRANSFORMS + lcProfileEntry("Settings", "FixedAxes", false), // LC_PROFILE_FIXED_AXES lcProfileEntry("Settings", "LineWidth", 1.0f), // LC_PROFILE_LINE_WIDTH lcProfileEntry("Settings", "LightingMode", LC_LIGHTING_FLAT), // LC_PROFILE_LIGHTING_MODE lcProfileEntry("Settings", "DrawAxes", 0), // LC_PROFILE_DRAW_AXES diff --git a/common/lc_profile.h b/common/lc_profile.h index 0558d994..b9e384ce 100644 --- a/common/lc_profile.h +++ b/common/lc_profile.h @@ -4,8 +4,8 @@ enum LC_PROFILE_KEY { // Settings. - LC_PROFILE_SNAP, - LC_PROFILE_ANGLE_SNAP, + LC_PROFILE_FORCE_GLOBAL_TRANSFORMS, + LC_PROFILE_FIXED_AXES, LC_PROFILE_LINE_WIDTH, LC_PROFILE_LIGHTING_MODE, LC_PROFILE_DRAW_AXES, diff --git a/common/lc_texture.cpp b/common/lc_texture.cpp index ff9c5ab6..e910baaa 100644 --- a/common/lc_texture.cpp +++ b/common/lc_texture.cpp @@ -8,6 +8,25 @@ lcTexture* gGridTexture; +lcTexture* lcLoadTexture(const QString& FileName, int Flags) +{ + lcTexture* Texture = new lcTexture(); + + if (!Texture->Load(FileName.toLatin1().constData(), Flags)) // todo: qstring + { + delete Texture; + Texture = NULL; + } + + return Texture; +} + +void lcReleaseTexture(lcTexture* Texture) +{ + if (Texture && Texture->Release() == 0) + delete Texture; +} + lcTexture::lcTexture() { mTexture = 0; diff --git a/common/lc_texture.h b/common/lc_texture.h index 9cfe07e7..4c48427a 100644 --- a/common/lc_texture.h +++ b/common/lc_texture.h @@ -64,6 +64,9 @@ protected: int mRefCount; }; +lcTexture* lcLoadTexture(const QString& FileName, int Flags); +void lcReleaseTexture(lcTexture* Texture); + extern lcTexture* gGridTexture; #endif // _LC_TEXTURE_H_ diff --git a/common/project.cpp b/common/project.cpp index bc294268..e0462f3c 100644 --- a/common/project.cpp +++ b/common/project.cpp @@ -30,14 +30,10 @@ Project::Project() { - m_pBackground = new lcTexture(); } Project::~Project() { - DeleteContents(false); - - delete m_pBackground; } void Project::UpdateInterface() @@ -51,7 +47,7 @@ void Project::UpdateInterface() gMainWindow->UpdateFocusObject(GetFocusObject()); gMainWindow->SetTransformType(gMainWindow->GetTransformType()); - gMainWindow->UpdateLockSnap(m_nSnap); + gMainWindow->UpdateLockSnap(); gMainWindow->UpdateSnap(); gMainWindow->UpdateCameraMenu(); gMainWindow->UpdatePerspective(); @@ -67,76 +63,26 @@ void Project::SetTitle(const char* Title) gMainWindow->UpdateTitle(m_strTitle, IsModified()); } -void Project::DeleteContents(bool bUndo) +void Project::LoadDefaults() { mProperties.LoadDefaults(); - if (!bUndo) - { - mUndoHistory.DeleteAll(); - mRedoHistory.DeleteAll(); - - m_pBackground->Unload(); - } - - mPieces.DeleteAll(); - - if (!bUndo) - { - const lcArray Views = gMainWindow->GetViews(); - for (int ViewIdx = 0; ViewIdx < Views.GetSize(); ViewIdx++) - { - View* view = Views[ViewIdx]; - - if (!view->mCamera->IsSimple()) - view->SetDefaultCamera(); - } - } - - mCameras.DeleteAll(); - mLights.DeleteAll(); - mGroups.DeleteAll(); -} - -// Only call after DeleteContents() -void Project::LoadDefaults(bool cameras) -{ - int i; - - mProperties.LoadDefaults(); - - // Default values gMainWindow->SetColorIndex(lcGetColorIndex(4)); gMainWindow->SetTool(LC_TOOL_SELECT); gMainWindow->SetAddKeys(false); gMainWindow->UpdateUndoRedo(NULL, NULL); - m_nAngleSnap = (unsigned short)lcGetProfileInt(LC_PROFILE_ANGLE_SNAP); - m_nSnap = lcGetProfileInt(LC_PROFILE_SNAP); - gMainWindow->UpdateLockSnap(m_nSnap); - m_nMoveSnap = 0x0304; + gMainWindow->UpdateLockSnap(); gMainWindow->UpdateSnap(); mCurrentStep = 1; gMainWindow->UpdateCurrentStep(); - strcpy(m_strHeader, ""); - strcpy(m_strFooter, "Page &P"); - const lcArray Views = gMainWindow->GetViews(); - for (i = 0; i < Views.GetSize (); i++) - { - Views[i]->MakeCurrent(); - RenderInitialize(); - } + const lcArray& Views = gMainWindow->GetViews(); + for (int i = 0; i < Views.GetSize(); i++) + if (!Views[i]->mCamera->IsSimple()) + Views[i]->SetDefaultCamera(); - if (cameras) - { - for (i = 0; i < Views.GetSize(); i++) - if (!Views[i]->mCamera->IsSimple()) - Views[i]->SetDefaultCamera(); + gMainWindow->UpdateCameraMenu(); - gMainWindow->UpdateCameraMenu(); - } - - SystemPieceComboAdd(NULL); UpdateSelection(); gMainWindow->UpdateFocusObject(NULL); } @@ -187,16 +133,9 @@ bool Project::FileLoad(lcFile* file, bool bUndo, bool bMerge) file->Seek(32, SEEK_CUR); else { - lcuint32 u; - float f; - file->ReadS32(&i, 1); m_nAngleSnap = i; - file->ReadU32(&u, 1); //m_nSnap - file->ReadFloats(&f, 1); //m_fLineWidth - file->ReadU32(&u, 1); //m_nDetail - file->ReadS32(&i, 1); //m_nCurGroup = i; - file->ReadS32(&i, 1); //m_nCurColor = i; - file->ReadS32(&i, 1); //action = i; - file->ReadS32(&i, 1); mCurrentStep = i; + file->Seek(28, SEEK_CUR); + file->ReadS32(&i, 1); + mCurrentStep = i; } if (fv > 0.8f) @@ -227,8 +166,6 @@ bool Project::FileLoad(lcFile* file, bool bUndo, bool bMerge) pPiece->CreateName(mPieces); mPieces.Add(pPiece); - if (!bUndo) - SystemPieceComboAdd(pPiece->mPieceInfo->m_strDescription); } else { @@ -257,7 +194,6 @@ bool Project::FileLoad(lcFile* file, bool bUndo, bool bMerge) mPieces.Add(pPiece); // pPiece->SetGroup((lcGroup*)group); - SystemPieceComboAdd(pInfo->m_strDescription); } } @@ -453,15 +389,15 @@ bool Project::FileLoad(lcFile* file, bool bUndo, bool bMerge) mProperties.mBackgroundImage = Background; } else - file->Seek (sh, SEEK_CUR); + file->Seek(sh, SEEK_CUR); } if (fv >= 0.8f) { file->ReadBuffer(&ch, 1); - file->ReadBuffer(m_strHeader, ch); + file->Seek(ch, SEEK_CUR); file->ReadBuffer(&ch, 1); - file->ReadBuffer(m_strFooter, ch); + file->Seek(ch, SEEK_CUR); } if (fv > 0.9f) @@ -490,13 +426,7 @@ bool Project::FileLoad(lcFile* file, bool bUndo, bool bMerge) } } - const lcArray Views = gMainWindow->GetViews(); - for (i = 0; i < Views.GetSize (); i++) - { - Views[i]->MakeCurrent(); - RenderInitialize(); - } - + UpdateBackgroundTexture(); CalculateStep(); if (!bUndo) @@ -507,6 +437,7 @@ bool Project::FileLoad(lcFile* file, bool bUndo, bool bMerge) if (!bMerge) { + const lcArray& Views = gMainWindow->GetViews(); for (int ViewIdx = 0; ViewIdx < Views.GetSize(); ViewIdx++) { View* view = Views[ViewIdx]; @@ -519,7 +450,7 @@ bool Project::FileLoad(lcFile* file, bool bUndo, bool bMerge) ZoomExtents(0, Views.GetSize()); } - gMainWindow->UpdateLockSnap(m_nSnap); + gMainWindow->UpdateLockSnap(); gMainWindow->UpdateSnap(); gMainWindow->UpdateCameraMenu(); UpdateSelection(); @@ -688,7 +619,6 @@ void Project::FileReadLDraw(lcFile* file, const lcMatrix44& CurrentTransform, in pPiece->SetColorCode(ColorCode); pPiece->CreateName(mPieces); mPieces.Add(pPiece); - SystemPieceComboAdd(pInfo->m_strDescription); (*nOk)++; } } @@ -746,7 +676,6 @@ void Project::FileReadLDraw(lcFile* file, const lcMatrix44& CurrentTransform, in pPiece->SetColorCode(ColorCode); pPiece->CreateName(mPieces); mPieces.Add(pPiece); - SystemPieceComboAdd(Info->m_strDescription); (*nOk)++; } } @@ -866,9 +795,12 @@ bool Project::SaveModified() bool Project::OnNewDocument() { - DeleteContents(false); - memset(m_strPathName, 0, sizeof(m_strPathName)); // no path name yet - LoadDefaults(true); + memset(m_strPathName, 0, sizeof(m_strPathName)); + + DeleteModel(); + DeleteHistory(); + LoadDefaults(); + CheckPoint(""); mSavedHistory = mUndoHistory[0]; SetTitle("Untitled"); @@ -919,9 +851,9 @@ bool Project::OnOpenDocument(const char* lpszPathName) else if (strcmp(ext, "mpd") == 0) mpdfile = true; - // Delete the current project. - DeleteContents(false); - LoadDefaults(datfile || mpdfile); + DeleteModel(); + DeleteHistory(); + LoadDefaults(); if (file.GetLength() != 0) { @@ -966,7 +898,6 @@ bool Project::OnOpenDocument(const char* lpszPathName) gMainWindow->UpdateCurrentStep(); gMainWindow->UpdateFocusObject(GetFocusObject()); UpdateSelection(); - CalculateStep(); ZoomExtents(0, gMainWindow->GetViews().GetSize()); gMainWindow->UpdateAllViews(); @@ -1023,40 +954,6 @@ void Project::CheckPoint(const char* Description) SaveCheckpoint(Description); } -void Project::LoadCheckPoint(lcModelHistoryEntry* CheckPoint) -{ - DeleteContents(true); - - QTextStream Stream(CheckPoint->File, QIODevice::ReadOnly); - LoadLDraw(Stream); - - const lcArray Views = gMainWindow->GetViews(); - for (int i = 0; i < Views.GetSize (); i++) - { - Views[i]->MakeCurrent(); - RenderInitialize(); - } - - CalculateStep(); - - gMainWindow->UpdateFocusObject(GetFocusObject()); - - for (int ViewIdx = 0; ViewIdx < Views.GetSize(); ViewIdx++) - { - View* view = Views[ViewIdx]; - - if (!view->mCamera->IsSimple()) - view->SetDefaultCamera(); - } - - gMainWindow->UpdateLockSnap(m_nSnap); - gMainWindow->UpdateSnap(); - gMainWindow->UpdateCameraMenu(); - UpdateSelection(); - gMainWindow->UpdateCurrentStep(); - gMainWindow->UpdateAllViews(); -} - // Only this function should be called. void Project::Render(View* View, bool ToMemory) { @@ -1127,14 +1024,14 @@ void Project::RenderBackground(View* View) glEnable(GL_TEXTURE_2D); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - glBindTexture(GL_TEXTURE_2D, m_pBackground->mTexture); + glBindTexture(GL_TEXTURE_2D, mBackgroundTexture->mTexture); float TileWidth = 1.0f, TileHeight = 1.0f; if (mProperties.mBackgroundImageTile) { - TileWidth = ViewWidth / m_pBackground->mWidth; - TileHeight = ViewHeight / m_pBackground->mHeight; + TileWidth = ViewWidth / mBackgroundTexture->mWidth; + TileHeight = ViewHeight / mBackgroundTexture->mHeight; } float Verts[] = @@ -1365,16 +1262,6 @@ void Project::RenderSceneObjects(View* view) Context->SetLineWidth(Preferences.mLineWidth); // context remove } -void Project::RenderInitialize() -{ - if (mProperties.mBackgroundType == LC_BACKGROUND_IMAGE) - if (!m_pBackground->Load(mProperties.mBackgroundImage.toLatin1().constData(), LC_TEXTURE_WRAPU | LC_TEXTURE_WRAPV)) // todo: qstring - { - mProperties.mBackgroundType = LC_BACKGROUND_SOLID; -// AfxMessageBox ("Could not load background"); - } -} - bool Project::GetPiecesBoundingBox(View* view, float BoundingBox[6]) { if (mPieces.IsEmpty() && view->mTrackTool != LC_TRACKTOOL_INSERT) @@ -3179,12 +3066,7 @@ void Project::HandleCommand(LC_COMMANDS id) mProperties = Options.Properties; - const lcArray Views = gMainWindow->GetViews(); - for (int i = 0; i < Views.GetSize (); i++) - { - Views[i]->MakeCurrent(); - RenderInitialize(); - } + UpdateBackgroundTexture(); CheckPoint("Properties"); } break; @@ -3617,7 +3499,6 @@ void Project::HandleCommand(LC_COMMANDS id) pPiece->CreateName(mPieces); mPieces.Add(pPiece); ClearSelectionAndSetFocus(pPiece, LC_PIECE_SECTION_POSITION); - SystemPieceComboAdd(m_pCurPiece->m_strDescription); CheckPoint("Inserting"); } break; @@ -3651,24 +3532,18 @@ void Project::HandleCommand(LC_COMMANDS id) if (Rotate) { - if (m_nSnap & LC_DRAW_SNAP_A) - axis[0] = axis[1] = axis[2] = m_nAngleSnap; - else - axis[0] = axis[1] = axis[2] = 1; + axis[0] = axis[1] = axis[2] = lcMax(gMainWindow->GetAngleSnap(), 1); } else { - float xy, z; - GetSnapDistance(&xy, &z); + axis[0] = axis[1] = gMainWindow->GetMoveXYSnap(); + axis[2] = gMainWindow->GetMoveZSnap(); - axis[0] = axis[1] = xy; - axis[2] = z; - - if ((m_nSnap & LC_DRAW_SNAP_X) == 0)// || bControl) + if (!axis[0])// || bControl) axis[0] = 0.01f; - if ((m_nSnap & LC_DRAW_SNAP_Y) == 0)// || bControl) + if (!axis[1])// || bControl) axis[1] = 0.01f; - if ((m_nSnap & LC_DRAW_SNAP_Z) == 0)// || bControl) + if (!axis[2])// || bControl) axis[2] = 0.01f; } @@ -3685,7 +3560,7 @@ void Project::HandleCommand(LC_COMMANDS id) else if (id == LC_PIECE_MOVE_MINUSZ || id == LC_PIECE_ROTATE_MINUSZ) axis = lcVector3(0, 0, -axis[2]); - if ((m_nSnap & LC_DRAW_MOVEAXIS) == 0) + if (!lcGetPreferences().mFixedAxes) { // TODO: rewrite this @@ -3728,15 +3603,9 @@ void Project::HandleCommand(LC_COMMANDS id) } if (Rotate) - { - lcVector3 tmp; - RotateSelectedObjects(axis, tmp, true, true); - } + RotateSelectedPieces(axis); else - { - lcVector3 tmp; - MoveSelectedObjects(axis, tmp, false, true); - } + MoveSelectedObjects(axis, axis); gMainWindow->UpdateAllViews(); CheckPoint(Rotate ? "Rotating" : "Moving"); @@ -3769,8 +3638,6 @@ void Project::HandleCommand(LC_COMMANDS id) mPieces.Add(pPiece); pPiece->SetSelected(true); pPiece->UpdatePosition(mCurrentStep); - - SystemPieceComboAdd(Minifig.Parts[i]->m_strDescription); } int Max = 0; @@ -4515,165 +4382,68 @@ void Project::HandleCommand(LC_COMMANDS id) gMainWindow->SetAddKeys(!gMainWindow->GetAddKeys()); break; - case LC_EDIT_SNAP_RELATIVE: - if (m_nSnap & LC_DRAW_GLOBAL_SNAP) - m_nSnap &= ~LC_DRAW_GLOBAL_SNAP; - else - m_nSnap |= LC_DRAW_GLOBAL_SNAP; - gMainWindow->UpdateLockSnap(m_nSnap); - gMainWindow->UpdateAllViews(); - break; - - case LC_EDIT_SNAP_X: - if (m_nSnap & LC_DRAW_SNAP_X) - m_nSnap &= ~LC_DRAW_SNAP_X; - else - m_nSnap |= LC_DRAW_SNAP_X; - gMainWindow->UpdateLockSnap(m_nSnap); - break; - - case LC_EDIT_SNAP_Y: - if (m_nSnap & LC_DRAW_SNAP_Y) - m_nSnap &= ~LC_DRAW_SNAP_Y; - else - m_nSnap |= LC_DRAW_SNAP_Y; - gMainWindow->UpdateLockSnap(m_nSnap); - break; - - case LC_EDIT_SNAP_Z: - if (m_nSnap & LC_DRAW_SNAP_Z) - m_nSnap &= ~LC_DRAW_SNAP_Z; - else - m_nSnap |= LC_DRAW_SNAP_Z; - gMainWindow->UpdateLockSnap(m_nSnap); - break; - - case LC_EDIT_SNAP_ALL: - m_nSnap |= LC_DRAW_SNAP_XYZ; - gMainWindow->UpdateLockSnap(m_nSnap); - break; - - case LC_EDIT_SNAP_NONE: - m_nSnap &= ~LC_DRAW_SNAP_XYZ; - gMainWindow->UpdateLockSnap(m_nSnap); - break; - - case LC_EDIT_SNAP_TOGGLE: - if ((m_nSnap & LC_DRAW_SNAP_XYZ) == LC_DRAW_SNAP_XYZ) - m_nSnap &= ~LC_DRAW_SNAP_XYZ; - else - m_nSnap |= LC_DRAW_SNAP_XYZ; - gMainWindow->UpdateLockSnap(m_nSnap); - break; - - case LC_EDIT_LOCK_X: - if (m_nSnap & LC_DRAW_LOCK_X) - m_nSnap &= ~LC_DRAW_LOCK_X; - else - m_nSnap |= LC_DRAW_LOCK_X; - gMainWindow->UpdateLockSnap(m_nSnap); - break; - - case LC_EDIT_LOCK_Y: - if (m_nSnap & LC_DRAW_LOCK_Y) - m_nSnap &= ~LC_DRAW_LOCK_Y; - else - m_nSnap |= LC_DRAW_LOCK_Y; - gMainWindow->UpdateLockSnap(m_nSnap); - break; - - case LC_EDIT_LOCK_Z: - if (m_nSnap & LC_DRAW_LOCK_Z) - m_nSnap &= ~LC_DRAW_LOCK_Z; - else - m_nSnap |= LC_DRAW_LOCK_Z; - gMainWindow->UpdateLockSnap(m_nSnap); - break; - - case LC_EDIT_LOCK_NONE: - m_nSnap &= ~LC_DRAW_LOCK_XYZ; - gMainWindow->UpdateLockSnap(m_nSnap); - break; - - case LC_EDIT_LOCK_TOGGLE: - if ((m_nSnap & LC_DRAW_LOCK_XYZ) == LC_DRAW_LOCK_XYZ) - m_nSnap &= ~LC_DRAW_LOCK_XYZ; - else - m_nSnap |= LC_DRAW_LOCK_XYZ; - gMainWindow->UpdateLockSnap(m_nSnap); - break; - - case LC_EDIT_SNAP_MOVE_XY0: - case LC_EDIT_SNAP_MOVE_XY1: - case LC_EDIT_SNAP_MOVE_XY2: - case LC_EDIT_SNAP_MOVE_XY3: - case LC_EDIT_SNAP_MOVE_XY4: - case LC_EDIT_SNAP_MOVE_XY5: - case LC_EDIT_SNAP_MOVE_XY6: - case LC_EDIT_SNAP_MOVE_XY7: - case LC_EDIT_SNAP_MOVE_XY8: - case LC_EDIT_SNAP_MOVE_XY9: + case LC_EDIT_SNAP_RELATIVE: { - m_nMoveSnap = (id - LC_EDIT_SNAP_MOVE_XY0) | (m_nMoveSnap & ~0xff); - if (id != LC_EDIT_SNAP_MOVE_XY0) - m_nSnap |= LC_DRAW_SNAP_X | LC_DRAW_SNAP_Y; - else - m_nSnap &= ~(LC_DRAW_SNAP_X | LC_DRAW_SNAP_Y); - gMainWindow->UpdateSnap(); + lcPreferences& Preferences = lcGetPreferences(); + Preferences.SetForceGlobalTransforms(!Preferences.mForceGlobalTransforms); } break; - case LC_EDIT_SNAP_MOVE_Z0: - case LC_EDIT_SNAP_MOVE_Z1: - case LC_EDIT_SNAP_MOVE_Z2: - case LC_EDIT_SNAP_MOVE_Z3: - case LC_EDIT_SNAP_MOVE_Z4: - case LC_EDIT_SNAP_MOVE_Z5: - case LC_EDIT_SNAP_MOVE_Z6: - case LC_EDIT_SNAP_MOVE_Z7: - case LC_EDIT_SNAP_MOVE_Z8: - case LC_EDIT_SNAP_MOVE_Z9: - { - m_nMoveSnap = (((id - LC_EDIT_SNAP_MOVE_Z0) << 8) | (m_nMoveSnap & ~0xff00)); - if (id != LC_EDIT_SNAP_MOVE_Z0) - m_nSnap |= LC_DRAW_SNAP_Z; - else - m_nSnap &= ~LC_DRAW_SNAP_Z; - gMainWindow->UpdateSnap(); - } break; + case LC_EDIT_LOCK_X: + gMainWindow->SetLockX(!gMainWindow->GetLockX()); + break; - case LC_EDIT_SNAP_ANGLE: - if (m_nSnap & LC_DRAW_SNAP_A) - m_nSnap &= ~LC_DRAW_SNAP_A; - else - { - m_nSnap |= LC_DRAW_SNAP_A; - m_nAngleSnap = lcMax(1, m_nAngleSnap); - } - gMainWindow->UpdateSnap(); - break; + case LC_EDIT_LOCK_Y: + gMainWindow->SetLockY(!gMainWindow->GetLockY()); + break; - case LC_EDIT_SNAP_ANGLE0: - case LC_EDIT_SNAP_ANGLE1: - case LC_EDIT_SNAP_ANGLE2: - case LC_EDIT_SNAP_ANGLE3: - case LC_EDIT_SNAP_ANGLE4: - case LC_EDIT_SNAP_ANGLE5: - case LC_EDIT_SNAP_ANGLE6: - case LC_EDIT_SNAP_ANGLE7: - case LC_EDIT_SNAP_ANGLE8: - case LC_EDIT_SNAP_ANGLE9: - { - const int Angles[] = { 0, 1, 5, 10, 15, 30, 45, 60, 90, 180 }; + case LC_EDIT_LOCK_Z: + gMainWindow->SetLockZ(!gMainWindow->GetLockZ()); + break; - if (id == LC_EDIT_SNAP_ANGLE0) - m_nSnap &= ~LC_DRAW_SNAP_A; - else - { - m_nSnap |= LC_DRAW_SNAP_A; - m_nAngleSnap = Angles[id - LC_EDIT_SNAP_ANGLE0]; - } - gMainWindow->UpdateSnap(); - } break; + case LC_EDIT_LOCK_NONE: + gMainWindow->SetLockX(false); + gMainWindow->SetLockY(false); + gMainWindow->SetLockZ(false); + break; + + case LC_EDIT_SNAP_MOVE_XY0: + case LC_EDIT_SNAP_MOVE_XY1: + case LC_EDIT_SNAP_MOVE_XY2: + case LC_EDIT_SNAP_MOVE_XY3: + case LC_EDIT_SNAP_MOVE_XY4: + case LC_EDIT_SNAP_MOVE_XY5: + case LC_EDIT_SNAP_MOVE_XY6: + case LC_EDIT_SNAP_MOVE_XY7: + case LC_EDIT_SNAP_MOVE_XY8: + case LC_EDIT_SNAP_MOVE_XY9: + gMainWindow->SetMoveXYSnapIndex(id - LC_EDIT_SNAP_MOVE_XY0); + break; + + case LC_EDIT_SNAP_MOVE_Z0: + case LC_EDIT_SNAP_MOVE_Z1: + case LC_EDIT_SNAP_MOVE_Z2: + case LC_EDIT_SNAP_MOVE_Z3: + case LC_EDIT_SNAP_MOVE_Z4: + case LC_EDIT_SNAP_MOVE_Z5: + case LC_EDIT_SNAP_MOVE_Z6: + case LC_EDIT_SNAP_MOVE_Z7: + case LC_EDIT_SNAP_MOVE_Z8: + case LC_EDIT_SNAP_MOVE_Z9: + gMainWindow->SetMoveZSnapIndex(id - LC_EDIT_SNAP_MOVE_Z0); + break; + + case LC_EDIT_SNAP_ANGLE0: + case LC_EDIT_SNAP_ANGLE1: + case LC_EDIT_SNAP_ANGLE2: + case LC_EDIT_SNAP_ANGLE3: + case LC_EDIT_SNAP_ANGLE4: + case LC_EDIT_SNAP_ANGLE5: + case LC_EDIT_SNAP_ANGLE6: + case LC_EDIT_SNAP_ANGLE7: + case LC_EDIT_SNAP_ANGLE8: + case LC_EDIT_SNAP_ANGLE9: + gMainWindow->SetAngleSnapIndex(id - LC_EDIT_SNAP_ANGLE0); + break; case LC_EDIT_TRANSFORM: TransformSelectedObjects(gMainWindow->GetTransformType(), gMainWindow->GetTransformAmount()); @@ -4756,65 +4526,6 @@ void Project::HandleCommand(LC_COMMANDS id) } } -// Remove unused groups -void Project::RemoveEmptyGroups() -{ - bool Removed; - - do - { - Removed = false; - - for (int GroupIdx = 0; GroupIdx < mGroups.GetSize();) - { - lcGroup* Group = mGroups[GroupIdx]; - int Ref = 0; - - for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++) - if (mPieces[PieceIdx]->GetGroup() == Group) - Ref++; - - for (int ParentIdx = 0; ParentIdx < mGroups.GetSize(); ParentIdx++) - if (mGroups[ParentIdx]->mGroup == Group) - Ref++; - - if (Ref > 1) - { - GroupIdx++; - continue; - } - - if (Ref != 0) - { - for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++) - { - lcPiece* Piece = mPieces[PieceIdx]; - - if (Piece->GetGroup() == Group) - { - Piece->SetGroup(Group->mGroup); - break; - } - } - - for (int ParentIdx = 0; ParentIdx < mGroups.GetSize(); ParentIdx++) - { - if (mGroups[ParentIdx]->mGroup == Group) - { - mGroups[ParentIdx]->mGroup = Group->mGroup; - break; - } - } - } - - mGroups.RemoveIndex(GroupIdx); - delete Group; - Removed = true; - } - } - while (Removed); -} - lcGroup* Project::AddGroup(lcGroup* Parent) { lcGroup* NewGroup = new lcGroup(); @@ -4839,27 +4550,6 @@ lcGroup* Project::AddGroup(lcGroup* Parent) return NewGroup; } -bool Project::GetSelectionCenter(lcVector3& Center) const -{ - float bs[6] = { 10000, 10000, 10000, -10000, -10000, -10000 }; - bool Selected = false; - - for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++) - { - lcPiece* Piece = mPieces[PieceIdx]; - - if (Piece->IsSelected()) - { - Piece->CompareBoundingBox(bs); - Selected = true; - } - } - - Center = lcVector3((bs[0] + bs[3]) * 0.5f, (bs[1] + bs[4]) * 0.5f, (bs[2] + bs[5]) * 0.5f); - - return Selected; -} - lcVector3 Project::GetFocusOrSelectionCenter() const { lcVector3 Center; @@ -4912,7 +4602,7 @@ bool Project::AnyObjectsSelected(bool PiecesOnly) const void Project::GetPieceInsertPosition(lcPiece* OffsetPiece, lcVector3& Position, lcVector4& Rotation) { lcVector3 Dist(0, 0, OffsetPiece->mPieceInfo->m_fDimensions[2] - m_pCurPiece->m_fDimensions[5]); - SnapVector(Dist); + Dist = SnapVector(Dist); Position = lcMul31(Dist, OffsetPiece->mModelWorld); Rotation = OffsetPiece->mRotation; @@ -4937,7 +4627,7 @@ void Project::GetPieceInsertPosition(View* view, lcVector3& Position, lcVector4& lcVector3 Intersection; if (lcLinePlaneIntersection(&Intersection, ClickPoints[0], ClickPoints[1], lcVector4(0, 0, 1, m_pCurPiece->m_fDimensions[5]))) { - SnapVector(Intersection); + Intersection = SnapVector(Intersection); Position = Intersection; Rotation = lcVector4(0, 0, 1, 0); return; @@ -4948,390 +4638,101 @@ void Project::GetPieceInsertPosition(View* view, lcVector3& Position, lcVector4& Rotation = lcVector4(0, 0, 1, 0); } -void Project::GetSnapIndex(int* SnapXY, int* SnapZ, int* SnapAngle) const +lcVector3 Project::LockVector(const lcVector3& Vector) const { - if (SnapXY) - *SnapXY = (m_nMoveSnap & 0xff); + lcVector3 NewVector(Vector); - if (SnapZ) - *SnapZ = ((m_nMoveSnap >> 8) & 0xff); + if (gMainWindow->GetLockX()) + NewVector[0] = 0; - if (SnapAngle) + if (gMainWindow->GetLockY()) + NewVector[1] = 0; + + if (gMainWindow->GetLockZ()) + NewVector[2] = 0; + + return NewVector; +} + +lcVector3 Project::SnapVector(const lcVector3& Distance) const +{ + lcVector3 NewDistance(Distance); + + if (gMainWindow->GetMoveXYSnap()) { - if (m_nSnap & LC_DRAW_SNAP_A) + float SnapXY = (float)gMainWindow->GetMoveXYSnap(); + int i = (int)(NewDistance[0] / SnapXY); + float Leftover = NewDistance[0] - (SnapXY * i); + + if (Leftover > SnapXY / 2) { - int Angles[] = { 0, 1, 5, 10, 15, 30, 45, 60, 90, 180 }; - *SnapAngle = -1; - - for (unsigned int i = 0; i < sizeof(Angles)/sizeof(Angles[0]); i++) - { - if (m_nAngleSnap == Angles[i]) - { - *SnapAngle = i; - break; - } - } - } - else - *SnapAngle = 0; - } -} - -void Project::GetSnapDistance(float* SnapXY, float* SnapZ) const -{ - const float SnapXYTable[] = { 0.01f, 1.0f, 5.0f, 8.0f, 10.0f, 20.0f, 40.0f, 60.0f, 80.0f, 160.0f }; - const float SnapZTable[] = { 0.01f, 1.0f, 5.0f, 8.0f, 10.0f, 20.0f, 24.0f, 48.0f, 96.0f, 192.0f }; - - int SXY, SZ; - GetSnapIndex(&SXY, &SZ, NULL); - - SXY = lcMin(SXY, 9); - SZ = lcMin(SZ, 9); - - *SnapXY = SnapXYTable[SXY]; - *SnapZ = SnapZTable[SZ]; -} - -void Project::GetSnapText(char* SnapXY, char* SnapZ, char* SnapAngle) const -{ - const char* SnapXYText[] = { "0", "1/20S", "1/4S", "1F", "1/2S", "1S", "2S", "3S", "4S", "8S" }; - const char* SnapZText[] = { "0", "1/20S", "1/4S", "1F", "1/2S", "1S", "1B", "2B", "4B", "8B" }; - const char* SnapAngleText[] = { "0", "1", "5", "10", "15", "30", "45", "60", "90", "180" }; - - int SXY, SZ, SA; - GetSnapIndex(&SXY, &SZ, &SA); - - SXY = lcMin(SXY, 9); - SZ = lcMin(SZ, 9); - - strcpy(SnapXY, SnapXYText[SXY]); - strcpy(SnapZ, SnapZText[SZ]); - strcpy(SnapAngle, SnapAngleText[SA]); -} - -void Project::SnapVector(lcVector3& Delta, lcVector3& Leftover) const -{ - float SnapXY, SnapZ; - GetSnapDistance(&SnapXY, &SnapZ); - - if (m_nSnap & LC_DRAW_SNAP_X) - { - int i = (int)(Delta[0] / SnapXY); - Leftover[0] = Delta[0] - (SnapXY * i); - - if (Leftover[0] > SnapXY / 2) - { - Leftover[0] -= SnapXY; + Leftover -= SnapXY; i++; } - else if (Leftover[0] < -SnapXY / 2) + else if (Leftover < -SnapXY / 2) { - Leftover[0] += SnapXY; + Leftover += SnapXY; i--; } - Delta[0] = SnapXY * i; - } + NewDistance[0] = SnapXY * i; - if (m_nSnap & LC_DRAW_SNAP_Y) - { - int i = (int)(Delta[1] / SnapXY); - Leftover[1] = Delta[1] - (SnapXY * i); + i = (int)(NewDistance[1] / SnapXY); + Leftover = NewDistance[1] - (SnapXY * i); - if (Leftover[1] > SnapXY / 2) + if (Leftover > SnapXY / 2) { - Leftover[1] -= SnapXY; + Leftover -= SnapXY; i++; } - else if (Leftover[1] < -SnapXY / 2) + else if (Leftover < -SnapXY / 2) { - Leftover[1] += SnapXY; + Leftover += SnapXY; i--; } - Delta[1] = SnapXY * i; + NewDistance[1] = SnapXY * i; } - if (m_nSnap & LC_DRAW_SNAP_Z) + if (gMainWindow->GetMoveZSnap()) { - int i = (int)(Delta[2] / SnapZ); - Leftover[2] = Delta[2] - (SnapZ * i); + float SnapZ = (float)gMainWindow->GetMoveZSnap(); + int i = (int)(NewDistance[2] / SnapZ); + float Leftover = NewDistance[2] - (SnapZ * i); - if (Leftover[2] > SnapZ / 2) + if (Leftover > SnapZ / 2) { - Leftover[2] -= SnapZ; + Leftover -= SnapZ; i++; } - else if (Leftover[2] < -SnapZ / 2) + else if (Leftover < -SnapZ / 2) { - Leftover[2] += SnapZ; + Leftover += SnapZ; i--; } - Delta[2] = SnapZ * i; + NewDistance[2] = SnapZ * i; } + + return NewDistance; } -void Project::SnapRotationVector(lcVector3& Delta, lcVector3& Leftover) const +lcVector3 Project::SnapRotation(const lcVector3& Angles) const { - if (m_nSnap & LC_DRAW_SNAP_A) + int AngleSnap = gMainWindow->GetAngleSnap(); + lcVector3 NewAngles(Angles); + + if (AngleSnap) { int Snap[3]; for (int i = 0; i < 3; i++) - { - Snap[i] = (int)(Delta[i] / (float)m_nAngleSnap); - } + Snap[i] = (int)(Angles[i] / (float)AngleSnap); - lcVector3 NewDelta((float)(m_nAngleSnap * Snap[0]), (float)(m_nAngleSnap * Snap[1]), (float)(m_nAngleSnap * Snap[2])); - Leftover = Delta - NewDelta; - Delta = NewDelta; - } -} - -lcMatrix44 Project::GetRelativeRotation() const -{ - if ((m_nSnap & LC_DRAW_GLOBAL_SNAP) == 0) - { - lcObject* Focus = GetFocusObject(); - - if ((Focus != NULL) && Focus->IsPiece()) - { - lcMatrix44 WorldMatrix = ((lcPiece*)Focus)->mModelWorld; - WorldMatrix.SetTranslation(lcVector3(0.0f, 0.0f, 0.0f)); - return WorldMatrix; - } + NewAngles = lcVector3((float)(AngleSnap * Snap[0]), (float)(AngleSnap * Snap[1]), (float)(AngleSnap * Snap[2])); } - return lcMatrix44Identity(); -} - -bool Project::MoveSelectedObjects(lcVector3& Move, lcVector3& Remainder, bool Snap, bool Lock) -{ - // Don't move along locked directions. - if (Lock) - { - if (m_nSnap & LC_DRAW_LOCK_X) - Move[0] = 0; - - if (m_nSnap & LC_DRAW_LOCK_Y) - Move[1] = 0; - - if (m_nSnap & LC_DRAW_LOCK_Z) - Move[2] = 0; - } - - // Snap. - if (Snap) - { - SnapVector(Move, Remainder); - - if (Move.LengthSquared() < 0.001f) - return false; - } - - lcVector3 TransformedMove = lcMul30(Move, GetRelativeRotation()); - - for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++) - { - lcPiece* Piece = mPieces[PieceIdx]; - - if (Piece->IsSelected()) - { - Piece->Move(mCurrentStep, gMainWindow->GetAddKeys(), TransformedMove); - Piece->UpdatePosition(mCurrentStep); - } - } - - for (int CameraIdx = 0; CameraIdx < mCameras.GetSize(); CameraIdx++) - { - lcCamera* Camera = mCameras[CameraIdx]; - - if (Camera->IsSelected()) - { - Camera->Move(mCurrentStep, gMainWindow->GetAddKeys(), TransformedMove); - Camera->UpdatePosition(mCurrentStep); - } - } - - for (int LightIdx = 0; LightIdx < mLights.GetSize(); LightIdx++) - { - lcLight* Light = mLights[LightIdx]; - - if (Light->IsSelected()) - { - Light->Move(mCurrentStep, gMainWindow->GetAddKeys(), TransformedMove); - Light->UpdatePosition(mCurrentStep); - } - } - - return true; -} - -bool Project::RotateSelectedObjects(lcVector3& Delta, lcVector3& Remainder, bool Snap, bool Lock) -{ - // Don't move along locked directions. - if (Lock) - { - if (m_nSnap & LC_DRAW_LOCK_X) - Delta[0] = 0; - - if (m_nSnap & LC_DRAW_LOCK_Y) - Delta[1] = 0; - - if (m_nSnap & LC_DRAW_LOCK_Z) - Delta[2] = 0; - } - - // Snap. - if (Snap) - SnapRotationVector(Delta, Remainder); - - if (Delta.LengthSquared() < 0.001f) - return false; - - float bs[6] = { 10000, 10000, 10000, -10000, -10000, -10000 }; - lcVector3 pos; - lcVector4 rot; - int nSel = 0; - lcPiece *pFocus = NULL; - - for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++) - { - lcPiece* Piece = mPieces[PieceIdx]; - - if (Piece->IsSelected()) - { - if (Piece->IsFocused()) - pFocus = Piece; - - Piece->CompareBoundingBox(bs); - nSel++; - } - } - - if (pFocus != NULL) - { - pos = pFocus->mPosition; - bs[0] = bs[3] = pos[0]; - bs[1] = bs[4] = pos[1]; - bs[2] = bs[5] = pos[2]; - } - - lcVector3 Center((bs[0]+bs[3])/2, (bs[1]+bs[4])/2, (bs[2]+bs[5])/2); - - // Create the rotation matrix. - lcVector4 RotationQuaternion(0, 0, 0, 1); - lcVector4 WorldToFocusQuaternion, FocusToWorldQuaternion; - - if (!(m_nSnap & LC_DRAW_LOCK_X) && (Delta[0] != 0.0f)) - { - lcVector4 q = lcQuaternionRotationX(Delta[0] * LC_DTOR); - RotationQuaternion = lcQuaternionMultiply(q, RotationQuaternion); - } - - if (!(m_nSnap & LC_DRAW_LOCK_Y) && (Delta[1] != 0.0f)) - { - lcVector4 q = lcQuaternionRotationY(Delta[1] * LC_DTOR); - RotationQuaternion = lcQuaternionMultiply(q, RotationQuaternion); - } - - if (!(m_nSnap & LC_DRAW_LOCK_Z) && (Delta[2] != 0.0f)) - { - lcVector4 q = lcQuaternionRotationZ(Delta[2] * LC_DTOR); - RotationQuaternion = lcQuaternionMultiply(q, RotationQuaternion); - } - - // Transform the rotation relative to the focused piece. - if (m_nSnap & LC_DRAW_GLOBAL_SNAP) - pFocus = NULL; - - if (pFocus != NULL) - { - lcVector4 Rot; - Rot = ((lcPiece*)pFocus)->mRotation; - - WorldToFocusQuaternion = lcQuaternionFromAxisAngle(lcVector4(Rot[0], Rot[1], Rot[2], -Rot[3] * LC_DTOR)); - FocusToWorldQuaternion = lcQuaternionFromAxisAngle(lcVector4(Rot[0], Rot[1], Rot[2], Rot[3] * LC_DTOR)); - - RotationQuaternion = lcQuaternionMultiply(FocusToWorldQuaternion, RotationQuaternion); - } - - for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++) - { - lcPiece* Piece = mPieces[PieceIdx]; - - if (!Piece->IsSelected()) - continue; - - pos = Piece->mPosition; - rot = Piece->mRotation; - - lcVector4 NewRotation; - - if ((nSel == 1) && (pFocus == Piece)) - { - lcVector4 LocalToWorldQuaternion; - LocalToWorldQuaternion = lcQuaternionFromAxisAngle(lcVector4(rot[0], rot[1], rot[2], rot[3] * LC_DTOR)); - - lcVector4 NewLocalToWorldQuaternion; - - if (pFocus != NULL) - { - lcVector4 LocalToFocusQuaternion = lcQuaternionMultiply(WorldToFocusQuaternion, LocalToWorldQuaternion); - NewLocalToWorldQuaternion = lcQuaternionMultiply(LocalToFocusQuaternion, RotationQuaternion); - } - else - { - NewLocalToWorldQuaternion = lcQuaternionMultiply(RotationQuaternion, LocalToWorldQuaternion); - } - - NewRotation = lcQuaternionToAxisAngle(NewLocalToWorldQuaternion); - } - else - { - lcVector3 Distance = lcVector3(pos[0], pos[1], pos[2]) - Center; - - lcVector4 LocalToWorldQuaternion = lcQuaternionFromAxisAngle(lcVector4(rot[0], rot[1], rot[2], rot[3] * LC_DTOR)); - - lcVector4 NewLocalToWorldQuaternion; - - if (pFocus != NULL) - { - lcVector4 LocalToFocusQuaternion = lcQuaternionMultiply(WorldToFocusQuaternion, LocalToWorldQuaternion); - NewLocalToWorldQuaternion = lcQuaternionMultiply(RotationQuaternion, LocalToFocusQuaternion); - - lcVector4 WorldToLocalQuaternion = lcQuaternionFromAxisAngle(lcVector4(rot[0], rot[1], rot[2], -rot[3] * LC_DTOR)); - - Distance = lcQuaternionMul(Distance, WorldToLocalQuaternion); - Distance = lcQuaternionMul(Distance, NewLocalToWorldQuaternion); - } - else - { - NewLocalToWorldQuaternion = lcQuaternionMultiply(RotationQuaternion, LocalToWorldQuaternion); - - Distance = lcQuaternionMul(Distance, RotationQuaternion); - } - - NewRotation = lcQuaternionToAxisAngle(NewLocalToWorldQuaternion); - - pos[0] = Center[0] + Distance[0]; - pos[1] = Center[1] + Distance[1]; - pos[2] = Center[2] + Distance[2]; - - Piece->SetPosition(pos, mCurrentStep, gMainWindow->GetAddKeys()); - } - - rot[0] = NewRotation[0]; - rot[1] = NewRotation[1]; - rot[2] = NewRotation[2]; - rot[3] = NewRotation[3] * LC_RTOD; - - Piece->SetRotation(rot, mCurrentStep, gMainWindow->GetAddKeys()); - Piece->UpdatePosition(mCurrentStep); - } - - return true; + return NewAngles; } void Project::TransformSelectedObjects(lcTransformType Type, const lcVector3& Transform) @@ -5409,14 +4810,14 @@ void Project::TransformSelectedObjects(lcTransformType Type, const lcVector3& Tr case LC_TRANSFORM_RELATIVE_TRANSLATION: { - lcVector3 Move(Transform), Remainder; +/* lcVector3 Move(Transform); - if (MoveSelectedObjects(Move, Remainder, false, false)) + if (MoveSelectedObjects(Move, false, false)) { gMainWindow->UpdateAllViews(); CheckPoint("Moving"); gMainWindow->UpdateFocusObject(GetFocusObject()); - } + }*/ } break; case LC_TRANSFORM_ABSOLUTE_ROTATION: @@ -5469,9 +4870,9 @@ void Project::TransformSelectedObjects(lcTransformType Type, const lcVector3& Tr case LC_TRANSFORM_RELATIVE_ROTATION: { - lcVector3 Rotate(Transform), Remainder; + lcVector3 Rotate(Transform); - if (RotateSelectedObjects(Rotate, Remainder, false, false)) + if (RotateSelectedPieces(Rotate)) { gMainWindow->UpdateAllViews(); CheckPoint("Rotating"); @@ -5703,262 +5104,6 @@ void Project::ZoomActiveView(int Amount) gMainWindow->UpdateAllViews(); } -void Project::BeginMouseTool() -{ - mMouseToolDistance = lcVector3(0.0f, 0.0f, 0.0f); -} - -void Project::EndMouseTool(lcTool Tool, bool Accept) -{ - if (!Accept) - { - LoadCheckPoint(mUndoHistory[0]); - return; - } - - switch (Tool) - { - case LC_TOOL_INSERT: - case LC_TOOL_LIGHT: - break; - - case LC_TOOL_SPOTLIGHT: - SaveCheckpoint(tr("New SpotLight")); - break; - - case LC_TOOL_CAMERA: - gMainWindow->UpdateCameraMenu(); - SaveCheckpoint(tr("New Camera")); - break; - - case LC_TOOL_SELECT: - break; - - case LC_TOOL_MOVE: - SaveCheckpoint(tr("Move")); - break; - - case LC_TOOL_ROTATE: - SaveCheckpoint(tr("Rotate")); - break; - - case LC_TOOL_ERASER: - case LC_TOOL_PAINT: - break; - - case LC_TOOL_ZOOM: - if (!gMainWindow->GetActiveView()->mCamera->IsSimple()) - SaveCheckpoint(tr("Zoom")); - break; - - case LC_TOOL_PAN: - if (!gMainWindow->GetActiveView()->mCamera->IsSimple()) - SaveCheckpoint(tr("Pan")); - break; - - case LC_TOOL_ROTATE_VIEW: - if (!gMainWindow->GetActiveView()->mCamera->IsSimple()) - SaveCheckpoint(tr("Orbit")); - break; - - case LC_TOOL_ROLL: - if (!gMainWindow->GetActiveView()->mCamera->IsSimple()) - SaveCheckpoint(tr("Roll")); - break; - - case LC_TOOL_ZOOM_REGION: - break; - } -} - -void Project::InsertPieceToolClicked(const lcVector3& Position, const lcVector4& Rotation) -{ - lcPiece* Piece = new lcPiece(m_pCurPiece); - Piece->Initialize(Position, Rotation, mCurrentStep); - Piece->SetColorIndex(gMainWindow->mColorIndex); - Piece->UpdatePosition(mCurrentStep); - Piece->CreateName(mPieces); - mPieces.Add(Piece); - - SystemPieceComboAdd(m_pCurPiece->m_strDescription); - ClearSelectionAndSetFocus(Piece, LC_PIECE_SECTION_POSITION); - - SaveCheckpoint(tr("Insert")); -} - -void Project::PointLightToolClicked(const lcVector3& Position) -{ - lcLight* Light = new lcLight(Position[0], Position[1], Position[2]); - Light->CreateName(mLights); - mLights.Add(Light); - - ClearSelectionAndSetFocus(Light, LC_LIGHT_SECTION_POSITION); - SaveCheckpoint(tr("New Light")); -} - -void Project::BeginSpotLightTool(const lcVector3& Position, const lcVector3& Target) -{ - lcLight* Light = new lcLight(Position[0], Position[1], Position[2], Target[0], Target[1], Target[2]); - mLights.Add(Light); - - ClearSelectionAndSetFocus(Light, LC_LIGHT_SECTION_TARGET); -} - -void Project::UpdateSpotLightTool(const lcVector3& Target) -{ - lcLight* Light = mLights[mLights.GetSize() - 1]; - - Light->Move(1, false, Target); - Light->UpdatePosition(1); - - gMainWindow->UpdateFocusObject(Light); - gMainWindow->UpdateAllViews(); -} - -void Project::BeginCameraTool(const lcVector3& Position, const lcVector3& Target) -{ - lcCamera* Camera = new lcCamera(Position[0], Position[1], Position[2], Target[0], Target[1], Target[2]); - Camera->CreateName(mCameras); - mCameras.Add(Camera); - - ClearSelectionAndSetFocus(Camera, LC_CAMERA_SECTION_TARGET); -} - -void Project::UpdateCameraTool(const lcVector3& Target) -{ - lcCamera* Camera = mCameras[mCameras.GetSize() - 1]; - - Camera->Move(1, false, Target); - Camera->UpdatePosition(1); - - gMainWindow->UpdateFocusObject(Camera); - gMainWindow->UpdateAllViews(); -} - -void Project::UpdateMoveTool(const lcVector3& Distance) -{ - lcVector3 Delta, Remainder; - Delta = Distance - mMouseToolDistance; - MoveSelectedObjects(Delta, Remainder, true, true); - mMouseToolDistance += Delta; - - gMainWindow->UpdateFocusObject(GetFocusObject()); - gMainWindow->UpdateAllViews(); -} - -void Project::UpdateRotateTool(const lcVector3& Angles) -{ - lcVector3 Delta, Remainder; - Delta = Angles - mMouseToolDistance; - RotateSelectedObjects(Delta, Remainder, true, true); - mMouseToolDistance += Delta; - - gMainWindow->UpdateFocusObject(GetFocusObject()); - gMainWindow->UpdateAllViews(); -} - -void Project::EraserToolClicked(lcObject* Object) -{ - if (!Object) - return; - - switch (Object->GetType()) - { - case LC_OBJECT_PIECE: - mPieces.Remove((lcPiece*)Object); - RemoveEmptyGroups(); - break; - - case LC_OBJECT_CAMERA: - { - const lcArray Views = gMainWindow->GetViews(); - for (int ViewIdx = 0; ViewIdx < Views.GetSize(); ViewIdx++) - { - View* View = Views[ViewIdx]; - lcCamera* Camera = View->mCamera; - - if (Camera == Object) - View->SetCamera(Camera, true); - } - - mCameras.Remove((lcCamera*)Object); - - gMainWindow->UpdateCameraMenu(); - } - break; - - case LC_OBJECT_LIGHT: - mLights.Remove((lcLight*)Object); - break; - } - - delete Object; - gMainWindow->UpdateFocusObject(GetFocusObject()); - UpdateSelection(); - gMainWindow->UpdateAllViews(); - SaveCheckpoint(tr("Deleting")); -} - -void Project::PaintToolClicked(lcObject* Object) -{ - if (!Object || Object->GetType() != LC_OBJECT_PIECE) - return; - - lcPiece* Piece = (lcPiece*)Object; - - if (Piece->mColorIndex != gMainWindow->mColorIndex) - { - Piece->SetColorIndex(gMainWindow->mColorIndex); - - SaveCheckpoint(tr("Painting")); - gMainWindow->UpdateFocusObject(GetFocusObject()); - gMainWindow->UpdateAllViews(); - } -} - -void Project::UpdateZoomTool(lcCamera* Camera, float Mouse) -{ - Camera->Zoom(Mouse - mMouseToolDistance.x, mCurrentStep, gMainWindow->GetAddKeys()); - mMouseToolDistance.x = Mouse; - gMainWindow->UpdateAllViews(); -} - -void Project::UpdatePanTool(lcCamera* Camera, float MouseX, float MouseY) -{ - Camera->Pan(MouseX - mMouseToolDistance.x, MouseY - mMouseToolDistance.y, mCurrentStep, gMainWindow->GetAddKeys()); - mMouseToolDistance.x = MouseX; - mMouseToolDistance.y = MouseY; - gMainWindow->UpdateAllViews(); -} - -void Project::UpdateOrbitTool(lcCamera* Camera, float MouseX, float MouseY) -{ - lcVector3 Center; - GetSelectionCenter(Center); - Camera->Orbit(MouseX - mMouseToolDistance.x, MouseY - mMouseToolDistance.y, Center, mCurrentStep, gMainWindow->GetAddKeys()); - mMouseToolDistance.x = MouseX; - mMouseToolDistance.y = MouseY; - gMainWindow->UpdateAllViews(); -} - -void Project::UpdateRollTool(lcCamera* Camera, float Mouse) -{ - Camera->Roll(Mouse - mMouseToolDistance.x, mCurrentStep, gMainWindow->GetAddKeys()); - mMouseToolDistance.x = Mouse; - gMainWindow->UpdateAllViews(); -} - -void Project::ZoomRegionToolClicked(lcCamera* Camera, const lcVector3* Points, float RatioX, float RatioY) -{ - Camera->ZoomRegion(Points, RatioX, RatioY, mCurrentStep, gMainWindow->GetAddKeys()); - - gMainWindow->UpdateFocusObject(GetFocusObject()); - gMainWindow->UpdateAllViews(); - - if (!Camera->IsSimple()) - SaveCheckpoint(tr("Zoom")); -} - // Indicates if the existing string represents an instance of the candidate // string in the form " (#)". // diff --git a/common/project.h b/common/project.h index 16fcc777..01fbf8c7 100644 --- a/common/project.h +++ b/common/project.h @@ -8,21 +8,6 @@ #include "lc_commands.h" #include "str.h" -#define LC_DRAW_SNAP_A 0x0004 // Snap Angle -#define LC_DRAW_SNAP_X 0x0008 // Snap X -#define LC_DRAW_SNAP_Y 0x0010 // Snap Y -#define LC_DRAW_SNAP_Z 0x0020 // Snap Z -#define LC_DRAW_SNAP_XYZ (LC_DRAW_SNAP_X | LC_DRAW_SNAP_Y | LC_DRAW_SNAP_Z) -#define LC_DRAW_GLOBAL_SNAP 0x0040 // Don't allow relative snap. -#define LC_DRAW_LOCK_X 0x0100 // Lock X -#define LC_DRAW_LOCK_Y 0x0200 // Lock Y -#define LC_DRAW_LOCK_Z 0x0400 // Lock Z -#define LC_DRAW_LOCK_XYZ (LC_DRAW_LOCK_X | LC_DRAW_LOCK_Y | LC_DRAW_LOCK_Z) -#define LC_DRAW_MOVEAXIS 0x0800 // Move on fixed axis -//#define LC_DRAW_PREVIEW 0x1000 // Show piece position -//#define LC_DRAW_CM_UNITS 0x2000 // Use centimeters -//#define LC_DRAW_3DMOUSE 0x4000 // Mouse moves in all directions - #define LC_SCENE_FOG 0x004 // Enable fog #define LC_SCENE_BG 0x010 // Draw bg image #define LC_SCENE_BG_TILE 0x040 // Tile bg image @@ -91,29 +76,6 @@ public: Project(); ~Project(); - const lcVector3& GetMouseToolDistance() const - { - return mMouseToolDistance; - } - - void BeginMouseTool(); - void EndMouseTool(lcTool Tool, bool Accept); - void InsertPieceToolClicked(const lcVector3& Position, const lcVector4& Rotation); - void PointLightToolClicked(const lcVector3& Position); - void BeginSpotLightTool(const lcVector3& Position, const lcVector3& Target); - void UpdateSpotLightTool(const lcVector3& Target); - void BeginCameraTool(const lcVector3& Position, const lcVector3& Target); - void UpdateCameraTool(const lcVector3& Target); - void UpdateMoveTool(const lcVector3& Distance); - void UpdateRotateTool(const lcVector3& Angles); - void EraserToolClicked(lcObject* Object); - void PaintToolClicked(lcObject* Object); - void UpdateZoomTool(lcCamera* Camera, float Mouse); - void UpdatePanTool(lcCamera* Camera, float MouseX, float MouseY); - void UpdateOrbitTool(lcCamera* Camera, float MouseX, float MouseY); - void UpdateRollTool(lcCamera* Camera, float Mouse); - void ZoomRegionToolClicked(lcCamera* Camera, const lcVector3* Points, float RatioX, float RatioY); - public: void SetCurrentStep(lcStep Step) { @@ -125,33 +87,23 @@ public: { m_pCurPiece = pInfo; } float* GetBackgroundColor() // todo: remove { return mProperties.mBackgroundSolidColor; } - unsigned long GetSnap() const - { return m_nSnap; } - void GetSnapIndex(int* SnapXY, int* SnapZ, int* SnapAngle) const; - void GetSnapText(char* SnapXY, char* SnapZ, char* SnapAngle) const; - void GetSnapDistance(float* SnapXY, float* SnapZ) const; int GetGroupIndex(lcGroup* Group) const { return mGroups.FindIndex(Group); } - lcMatrix44 GetRelativeRotation() const; - void UpdateInterface(); void SetPathName (const char* lpszPathName, bool bAddToMRU); void SetTitle (const char* lpszTitle); public: - void DeleteContents(bool bUndo); - void LoadDefaults(bool cameras); - void RenderInitialize(); + void LoadDefaults(); bool GetPiecesBoundingBox(View* view, float BoundingBox[6]); void GetPiecesUsed(lcArray& PiecesUsed) const; void CreateImages(Image* images, int width, int height, lcStep from, lcStep to, bool hilite); void Render(View* view, bool bToMemory); - bool GetSelectionCenter(lcVector3& Center) const; lcVector3 GetFocusOrSelectionCenter() const; bool GetFocusPosition(lcVector3& Position) const; bool AnyObjectsSelected(bool PiecesOnly) const; @@ -165,27 +117,20 @@ public: void GetPieceInsertPosition(View* view, lcVector3& Position, lcVector4& Orientation); + lcVector3 LockVector(const lcVector3& Vector) const; + lcVector3 SnapVector(const lcVector3& Delta) const; + lcVector3 SnapRotation(const lcVector3& Delta) const; + + void HandleCommand(LC_COMMANDS id); + protected: void CheckPoint(const char* Description); - void LoadCheckPoint(lcModelHistoryEntry* CheckPoint); bool RemoveSelectedObjects(); void GetPieceInsertPosition(lcPiece* OffsetPiece, lcVector3& Position, lcVector4& Rotation); static int InstanceOfName(const String& existingString, const String& candidateString, String& baseNameOut ); - // Movement. - bool MoveSelectedObjects(lcVector3& Move, lcVector3& Remainder, bool Snap, bool Lock); - bool RotateSelectedObjects(lcVector3& Delta, lcVector3& Remainder, bool Snap, bool Lock); - void SnapVector(lcVector3& Delta) const - { - lcVector3 Dummy; - SnapVector(Delta, Dummy); - } - void SnapVector(lcVector3& Delta, lcVector3& Leftover) const; - void SnapRotationVector(lcVector3& Delta, lcVector3& Leftover) const; - - // Rendering functions. void RenderBackground(View* view); void RenderScenePieces(View* view, bool DrawInterface); void RenderSceneObjects(View* view); @@ -195,24 +140,10 @@ protected: void ExportPOVRay(lcFile& File); void ZoomExtents(int FirstView, int LastView); - void RemoveEmptyGroups(); - -public: - void HandleCommand(LC_COMMANDS id); - - lcuint32 m_nSnap; - protected: PieceInfo* m_pCurPiece; +// lcuint16 m_nMoveSnap; - lcuint16 m_nMoveSnap; - lcuint16 m_nAngleSnap; - char m_strFooter[256]; - char m_strHeader[256]; - - lcTexture* m_pBackground; - -protected: bool DoSave(const char* FileName); bool FileLoad(lcFile* file, bool bUndo, bool bMerge); void FileReadLDraw(lcFile* file, const lcMatrix44& CurrentTransform, int* nOk, int DefColor, int* nStep, lcArray& FileArray); diff --git a/common/system.h b/common/system.h index 5ebf7c47..ee349798 100644 --- a/common/system.h +++ b/common/system.h @@ -42,6 +42,4 @@ template<> struct lcStaticAssert { }; template struct lcStaticAssertTest { }; #endif -void SystemPieceComboAdd(char* name); - #endif // _SYSTEM_H_ diff --git a/common/view.cpp b/common/view.cpp index 2ffb8945..d7cc1171 100644 --- a/common/view.cpp +++ b/common/view.cpp @@ -448,7 +448,7 @@ void View::DrawRotateOverlay() lcMatrix44 RelativeRotation = mProject->GetRelativeRotation(); lcVector3 OverlayCenter = mProject->GetFocusOrSelectionCenter(); - const lcVector3& MouseToolDistance = mProject->GetMouseToolDistance(); + lcVector3 MouseToolDistance = mProject->SnapRotation(mProject->GetMouseToolDistance()); bool HasAngle = false; // Draw a disc showing the rotation amount. diff --git a/qt/lc_qmainwindow.cpp b/qt/lc_qmainwindow.cpp index 76d6fcb0..2175927c 100644 --- a/qt/lc_qmainwindow.cpp +++ b/qt/lc_qmainwindow.cpp @@ -115,9 +115,6 @@ void lcQMainWindow::createActions() actions[LC_EDIT_CUT]->setIcon(QIcon(":/resources/edit_cut.png")); actions[LC_EDIT_COPY]->setIcon(QIcon(":/resources/edit_copy.png")); actions[LC_EDIT_PASTE]->setIcon(QIcon(":/resources/edit_paste.png")); - actions[LC_EDIT_LOCK_TOGGLE]->setIcon(QIcon(":/resources/edit_lock.png")); - actions[LC_EDIT_SNAP_TOGGLE]->setIcon(QIcon(":/resources/edit_snap_move.png")); - actions[LC_EDIT_SNAP_ANGLE]->setIcon(QIcon(":/resources/edit_snap_angle.png")); actions[LC_EDIT_ACTION_INSERT]->setIcon(QIcon(":/resources/action_insert.png")); actions[LC_EDIT_ACTION_LIGHT]->setIcon(QIcon(":/resources/action_light.png")); actions[LC_EDIT_ACTION_SPOTLIGHT]->setIcon(QIcon(":/resources/action_spotlight.png")); @@ -151,9 +148,6 @@ void lcQMainWindow::createActions() actions[LC_EDIT_LOCK_Y]->setCheckable(true); actions[LC_EDIT_LOCK_Z]->setCheckable(true); actions[LC_EDIT_SNAP_RELATIVE]->setCheckable(true); - actions[LC_EDIT_SNAP_X]->setCheckable(true); - actions[LC_EDIT_SNAP_Y]->setCheckable(true); - actions[LC_EDIT_SNAP_Z]->setCheckable(true); actions[LC_VIEW_CAMERA_NONE]->setCheckable(true); actions[LC_VIEW_TIME_ADD_KEYS]->setCheckable(true); @@ -212,37 +206,6 @@ void lcQMainWindow::createActions() void lcQMainWindow::createMenus() { - QMenu* lockMenu = new QMenu(tr("Lock Menu")); - lockMenu->addAction(actions[LC_EDIT_LOCK_X]); - lockMenu->addAction(actions[LC_EDIT_LOCK_Y]); - lockMenu->addAction(actions[LC_EDIT_LOCK_Z]); - lockMenu->addAction(actions[LC_EDIT_LOCK_NONE]); - actions[LC_EDIT_LOCK_TOGGLE]->setMenu(lockMenu); - - QMenu* snapXYMenu = new QMenu(tr("Snap XY")); - for (int actionIdx = LC_EDIT_SNAP_MOVE_XY0; actionIdx <= LC_EDIT_SNAP_MOVE_XY9; actionIdx++) - snapXYMenu->addAction(actions[actionIdx]); - - QMenu* snapZMenu = new QMenu(tr("Snap Z")); - for (int actionIdx = LC_EDIT_SNAP_MOVE_Z0; actionIdx <= LC_EDIT_SNAP_MOVE_Z9; actionIdx++) - snapZMenu->addAction(actions[actionIdx]); - - QMenu* snapMenu = new QMenu(tr("Snap Menu")); - snapMenu->addMenu(snapXYMenu); - snapMenu->addMenu(snapZMenu); - snapMenu->addSeparator(); - snapMenu->addAction(actions[LC_EDIT_SNAP_X]); - snapMenu->addAction(actions[LC_EDIT_SNAP_Y]); - snapMenu->addAction(actions[LC_EDIT_SNAP_Z]); - snapMenu->addAction(actions[LC_EDIT_SNAP_NONE]); - snapMenu->addAction(actions[LC_EDIT_SNAP_ALL]); - actions[LC_EDIT_SNAP_TOGGLE]->setMenu(snapMenu); - - QMenu* snapAngleMenu = new QMenu(tr("Snap Angle Menu")); - for (int actionIdx = LC_EDIT_SNAP_ANGLE0; actionIdx <= LC_EDIT_SNAP_ANGLE9; actionIdx++) - snapAngleMenu->addAction(actions[actionIdx]); - actions[LC_EDIT_SNAP_ANGLE]->setMenu(snapAngleMenu); - QMenu* transformMenu = new QMenu(tr("Transform")); transformMenu->addAction(actions[LC_EDIT_TRANSFORM_RELATIVE_TRANSLATION]); transformMenu->addAction(actions[LC_EDIT_TRANSFORM_ABSOLUTE_TRANSLATION]); @@ -376,6 +339,43 @@ void lcQMainWindow::createMenus() void lcQMainWindow::createToolBars() { + QMenu* lockMenu = new QMenu(tr("Lock Menu")); + lockMenu->addAction(actions[LC_EDIT_LOCK_X]); + lockMenu->addAction(actions[LC_EDIT_LOCK_Y]); + lockMenu->addAction(actions[LC_EDIT_LOCK_Z]); + lockMenu->addAction(actions[LC_EDIT_LOCK_NONE]); + + QAction* lockAction = new QAction(tr("Lock Menu"), this); + lockAction->setStatusTip(tr("Toggle mouse movement on specific axes")); + lockAction->setIcon(QIcon(":/resources/edit_lock.png")); + lockAction->setMenu(lockMenu); + + QMenu* snapXYMenu = new QMenu(tr("Snap XY")); + for (int actionIdx = LC_EDIT_SNAP_MOVE_XY0; actionIdx <= LC_EDIT_SNAP_MOVE_XY9; actionIdx++) + snapXYMenu->addAction(actions[actionIdx]); + + QMenu* snapZMenu = new QMenu(tr("Snap Z")); + for (int actionIdx = LC_EDIT_SNAP_MOVE_Z0; actionIdx <= LC_EDIT_SNAP_MOVE_Z9; actionIdx++) + snapZMenu->addAction(actions[actionIdx]); + + QMenu* snapMenu = new QMenu(tr("Snap Menu")); + snapMenu->addMenu(snapXYMenu); + snapMenu->addMenu(snapZMenu); + + QAction* moveAction = new QAction(tr("Snap Move"), this); + moveAction->setStatusTip(tr("Snap translations to fixed intervals")); + moveAction->setIcon(QIcon(":/resources/edit_snap_move.png")); + moveAction->setMenu(snapMenu); + + QMenu* snapAngleMenu = new QMenu(tr("Snap Angle Menu")); + for (int actionIdx = LC_EDIT_SNAP_ANGLE0; actionIdx <= LC_EDIT_SNAP_ANGLE9; actionIdx++) + snapAngleMenu->addAction(actions[actionIdx]); + + QAction* angleAction = new QAction(tr("Snap Rotate"), this); + angleAction->setStatusTip(tr("Snap rotations to fixed intervals")); + angleAction->setIcon(QIcon(":/resources/edit_snap_angle.png")); + angleAction->setMenu(snapMenu); + standardToolBar = addToolBar(tr("Standard")); standardToolBar->setObjectName("StandardToolbar"); standardToolBar->addAction(actions[LC_FILE_NEW]); @@ -390,15 +390,15 @@ void lcQMainWindow::createToolBars() standardToolBar->addAction(actions[LC_EDIT_COPY]); standardToolBar->addAction(actions[LC_EDIT_PASTE]); standardToolBar->addSeparator(); -// standardToolBar->addAction(actions[LC_EDIT_SNAP_RELATIVE]); - standardToolBar->addAction(actions[LC_EDIT_LOCK_TOGGLE]); - standardToolBar->addAction(actions[LC_EDIT_SNAP_TOGGLE]); - standardToolBar->addAction(actions[LC_EDIT_SNAP_ANGLE]); +// standardToolBar->addAction(actions[LC_EDIT_SNAP_RELATIVE]); todo + standardToolBar->addAction(lockAction); + standardToolBar->addAction(moveAction); + standardToolBar->addAction(angleAction); standardToolBar->addSeparator(); standardToolBar->addAction(actions[LC_EDIT_TRANSFORM]); - ((QToolButton*)standardToolBar->widgetForAction(actions[LC_EDIT_LOCK_TOGGLE]))->setPopupMode(QToolButton::InstantPopup); - ((QToolButton*)standardToolBar->widgetForAction(actions[LC_EDIT_SNAP_TOGGLE]))->setPopupMode(QToolButton::InstantPopup); - ((QToolButton*)standardToolBar->widgetForAction(actions[LC_EDIT_SNAP_ANGLE]))->setPopupMode(QToolButton::InstantPopup); + ((QToolButton*)standardToolBar->widgetForAction(lockAction))->setPopupMode(QToolButton::InstantPopup); + ((QToolButton*)standardToolBar->widgetForAction(moveAction))->setPopupMode(QToolButton::InstantPopup); + ((QToolButton*)standardToolBar->widgetForAction(angleAction))->setPopupMode(QToolButton::InstantPopup); ((QToolButton*)standardToolBar->widgetForAction(actions[LC_EDIT_TRANSFORM]))->setPopupMode(QToolButton::InstantPopup); QHBoxLayout *transformLayout = new QHBoxLayout; @@ -1155,32 +1155,23 @@ void lcQMainWindow::setAddKeys(bool addKeys) actions[LC_VIEW_TIME_ADD_KEYS]->setChecked(addKeys); } -void lcQMainWindow::updateLockSnap(lcuint32 snap) +void lcQMainWindow::updateLockSnap() { - actions[LC_EDIT_SNAP_RELATIVE]->setChecked((snap & LC_DRAW_GLOBAL_SNAP) == 0); - actions[LC_EDIT_SNAP_X]->setChecked((snap & LC_DRAW_SNAP_X) != 0); - actions[LC_EDIT_SNAP_Y]->setChecked((snap & LC_DRAW_SNAP_Y) != 0); - actions[LC_EDIT_SNAP_Z]->setChecked((snap & LC_DRAW_SNAP_Z) != 0); + const lcPreferences& Preferences = lcGetPreferences(); - actions[LC_EDIT_LOCK_X]->setChecked((snap & LC_DRAW_LOCK_X) != 0); - actions[LC_EDIT_LOCK_Y]->setChecked((snap & LC_DRAW_LOCK_Y) != 0); - actions[LC_EDIT_LOCK_Z]->setChecked((snap & LC_DRAW_LOCK_Z) != 0); + actions[LC_EDIT_SNAP_RELATIVE]->setChecked(!Preferences.mForceGlobalTransforms); + actions[LC_EDIT_LOCK_X]->setChecked(gMainWindow->GetLockX()); + actions[LC_EDIT_LOCK_Y]->setChecked(gMainWindow->GetLockY()); + actions[LC_EDIT_LOCK_Z]->setChecked(gMainWindow->GetLockZ()); } void lcQMainWindow::updateSnap() { - char xy[32], z[32], angle[32]; - int moveXYSnapIndex, moveZSnapIndex, angleSnapIndex; - Project *project = lcGetActiveProject(); + actions[LC_EDIT_SNAP_MOVE_XY0 + gMainWindow->GetMoveXYSnapIndex()]->setChecked(true); + actions[LC_EDIT_SNAP_MOVE_Z0 + gMainWindow->GetMoveZSnapIndex()]->setChecked(true); + actions[LC_EDIT_SNAP_ANGLE0 + gMainWindow->GetAngleSnapIndex()]->setChecked(true); - project->GetSnapText(xy, z, angle); - project->GetSnapIndex(&moveXYSnapIndex, &moveZSnapIndex, &angleSnapIndex); - - actions[LC_EDIT_SNAP_MOVE_XY0 + moveXYSnapIndex]->setChecked(true); - actions[LC_EDIT_SNAP_MOVE_Z0 + moveZSnapIndex]->setChecked(true); - actions[LC_EDIT_SNAP_ANGLE0 + angleSnapIndex]->setChecked(true); - - statusSnapLabel->setText(QString(tr(" M: %1 %2 R: %3 ")).arg(xy, z, angle)); + statusSnapLabel->setText(QString(tr(" M: %1 %2 R: %3 ")).arg(gMainWindow->GetMoveXYSnapText(), gMainWindow->GetMoveZSnapText(), QString::number(gMainWindow->GetAngleSnap()))); } void lcQMainWindow::updateUndoRedo(const QString& UndoText, const QString& RedoText) diff --git a/qt/lc_qmainwindow.h b/qt/lc_qmainwindow.h index d4c755a4..a902057f 100644 --- a/qt/lc_qmainwindow.h +++ b/qt/lc_qmainwindow.h @@ -36,7 +36,7 @@ public: void updatePaste(bool enabled); void updateCurrentStep(); void setAddKeys(bool addKeys); - void updateLockSnap(lcuint32 snap); + void updateLockSnap(); void updateSnap(); void updateUndoRedo(const QString& UndoText, const QString& RedoText); void updateTransformType(int newType); diff --git a/qt/lc_qpreferencesdialog.cpp b/qt/lc_qpreferencesdialog.cpp index 500db1b6..1fd3e9a5 100644 --- a/qt/lc_qpreferencesdialog.cpp +++ b/qt/lc_qpreferencesdialog.cpp @@ -30,8 +30,8 @@ lcQPreferencesDialog::lcQPreferencesDialog(QWidget *parent, void *data) : ui->lgeoPath->setText(options->LGEOPath); ui->mouseSensitivity->setValue(options->Preferences.mMouseSensitivity); ui->checkForUpdates->setCurrentIndex(options->CheckForUpdates); - ui->noRelativeSnap->setChecked((options->Snap & LC_DRAW_GLOBAL_SNAP) != 0); - ui->fixedDirectionKeys->setChecked((options->Snap & LC_DRAW_MOVEAXIS) != 0); + ui->noRelativeSnap->setChecked(options->Preferences.mForceGlobalTransforms); + ui->fixedDirectionKeys->setChecked((options->Preferences.mFixedAxes) != 0); ui->antiAliasing->setChecked(options->AASamples != 1); if (options->AASamples == 8) @@ -84,8 +84,6 @@ void lcQPreferencesDialog::accept() return; } - options->Snap &= ~(LC_DRAW_GLOBAL_SNAP | LC_DRAW_MOVEAXIS); - strcpy(options->DefaultAuthor, ui->authorName->text().toLocal8Bit().data()); strcpy(options->ProjectsPath, ui->projectsFolder->text().toLocal8Bit().data()); strcpy(options->LibraryPath, ui->partsLibrary->text().toLocal8Bit().data()); @@ -93,12 +91,8 @@ void lcQPreferencesDialog::accept() strcpy(options->LGEOPath, ui->lgeoPath->text().toLocal8Bit().data()); options->Preferences.mMouseSensitivity = ui->mouseSensitivity->value(); options->CheckForUpdates = ui->checkForUpdates->currentIndex(); - - if (ui->noRelativeSnap->isChecked()) - options->Snap |= LC_DRAW_GLOBAL_SNAP; - - if (ui->fixedDirectionKeys->isChecked()) - options->Snap |= LC_DRAW_MOVEAXIS; + options->Preferences.mForceGlobalTransforms = ui->noRelativeSnap->isChecked(); + options->Preferences.mFixedAxes = ui->fixedDirectionKeys->isChecked(); if (!ui->antiAliasing->isChecked()) options->AASamples = 1; diff --git a/qt/qtmain.cpp b/qt/qtmain.cpp index 00a43ea4..d9a228f8 100644 --- a/qt/qtmain.cpp +++ b/qt/qtmain.cpp @@ -530,12 +530,12 @@ void lcMainWindow::SetAddKeys(bool AddKeys) mAddKeys = AddKeys; } -void lcMainWindow::UpdateLockSnap(lcuint32 Snap) +void lcMainWindow::UpdateLockSnap() { lcQMainWindow* window = (lcQMainWindow*)mHandle; if (window) - window->updateLockSnap(Snap); + window->updateLockSnap(); } void lcMainWindow::UpdateSnap() diff --git a/qt/system.cpp b/qt/system.cpp index 7f407204..99ff233f 100644 --- a/qt/system.cpp +++ b/qt/system.cpp @@ -49,7 +49,3 @@ int stricmp(const char *str1, const char *str2) } #endif - -void SystemPieceComboAdd(char* name) -{ -}