diff --git a/common/camera.h b/common/camera.h index bd23064c..7697932f 100644 --- a/common/camera.h +++ b/common/camera.h @@ -195,6 +195,11 @@ public: return ~0; } + virtual lcuint32 GetAllowedTransforms() const + { + return LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Y | LC_OBJECT_TRANSFORM_MOVE_Z; + } + virtual lcVector3 GetSectionPosition(lcuint32 Section) const { switch (Section) diff --git a/common/lc_model.cpp b/common/lc_model.cpp index eee38f35..9cf6aeed 100644 --- a/common/lc_model.cpp +++ b/common/lc_model.cpp @@ -9,6 +9,7 @@ #include "lc_profile.h" #include "lc_library.h" #include "lc_texture.h" +#include "lc_synth.h" #include "pieceinf.h" #include "view.h" #include "preview.h" @@ -3007,7 +3008,8 @@ void lcModel::GetSelectionInformation(int* Flags, lcArray& Selection, *Flags |= LC_SEL_PIECE | LC_SEL_SELECTED; - if (Piece->mPieceInfo->GetSynthInfo()) + lcSynthInfo* SynthInfo = Piece->mPieceInfo->GetSynthInfo(); + if (SynthInfo && SynthInfo->CanAddControlPoints()) { *Flags |= LC_SEL_CAN_ADD_CONTROL_POINT; diff --git a/common/lc_synth.cpp b/common/lc_synth.cpp index 2e787485..a4d91b0d 100644 --- a/common/lc_synth.cpp +++ b/common/lc_synth.cpp @@ -35,7 +35,11 @@ void lcSynthInit() { "32235", LC_SYNTH_PIECE_FLEXIBLE_AXLE, 360.00f, 75 }, // Technic Axle Flexible 19 { "76384", LC_SYNTH_PIECE_STRING_BRAIDED, 200.00f, 46 }, // String Braided 11L with End Studs { "75924", LC_SYNTH_PIECE_STRING_BRAIDED, 400.00f, 96 }, // String Braided 21L with End Studs - { "572C02", LC_SYNTH_PIECE_STRING_BRAIDED, 800.00f, 196 } // String Braided 41L with End Studs + { "572C02", LC_SYNTH_PIECE_STRING_BRAIDED, 800.00f, 196 }, // String Braided 41L with End Studs + { "73129", LC_SYNTH_PIECE_SHOCK_ABSORBER, 110.00f, 1 }, // Technic Shock Absorber 6.5L + { "41838", LC_SYNTH_PIECE_SHOCK_ABSORBER, 110.00f, 1 }, // Technic Shock Absorber 6.5L Soft + { "76138", LC_SYNTH_PIECE_SHOCK_ABSORBER, 110.00f, 1 }, // Technic Shock Absorber 6.5L Stiff + { "76537", LC_SYNTH_PIECE_SHOCK_ABSORBER, 110.00f, 1 } // Technic Shock Absorber 6.5L Extra Stiff }; for (unsigned int InfoIdx = 0; InfoIdx < sizeof(HoseInfo) / sizeof(HoseInfo[0]); InfoIdx++) @@ -43,7 +47,7 @@ void lcSynthInit() PieceInfo* Info = Library->FindPiece(HoseInfo[InfoIdx].PartID, NULL, false); if (Info) - Info->SetSynthInfo(new lcSynthInfo(HoseInfo[InfoIdx].Type, HoseInfo[InfoIdx].Length, HoseInfo[InfoIdx].NumSections)); + Info->SetSynthInfo(new lcSynthInfo(HoseInfo[InfoIdx].Type, HoseInfo[InfoIdx].Length, HoseInfo[InfoIdx].NumSections, Info)); } // "758C01" // Hose Flexible 12L @@ -51,39 +55,58 @@ void lcSynthInit() // "73590B" // Hose Flexible 8.5L with Tabs } -lcSynthInfo::lcSynthInfo(lcSynthType Type, float Length, int NumSections) - : mType(Type), mLength(Length), mNumSections(NumSections) +lcSynthInfo::lcSynthInfo(lcSynthType Type, float Length, int NumSections, PieceInfo* Info) + : mType(Type), mLength(Length), mNumSections(NumSections), mPieceInfo(Info) { float EdgeSectionLength; float MidSectionLength; - mRigidEdges = false; - switch (mType) { case LC_SYNTH_PIECE_RIBBED_HOSE: EdgeSectionLength = 6.25f; MidSectionLength = 6.25f; + mRigidEdges = false; + mCurve = true; break; case LC_SYNTH_PIECE_FLEXIBLE_AXLE: EdgeSectionLength = 30.0f; MidSectionLength = 4.0f; mRigidEdges = true; + mCurve = true; break; case LC_SYNTH_PIECE_STRING_BRAIDED: EdgeSectionLength = 8.0f; MidSectionLength = 4.0f; mRigidEdges = true; + mCurve = true; + break; + + case LC_SYNTH_PIECE_SHOCK_ABSORBER: + EdgeSectionLength = 0.0f; + MidSectionLength = 0.0f; + mRigidEdges = false; + mCurve = false; break; } - mStart.Transform = lcMatrix44(lcMatrix33(lcVector3(0.0f, 0.0f, 1.0f), lcVector3(1.0f, 0.0f, 0.0f), lcVector3(0.0f, 1.0f, 0.0f)), lcVector3(0.0f, 0.0f, 0.0f)); + if (mType != LC_SYNTH_PIECE_SHOCK_ABSORBER) + { + mStart.Transform = lcMatrix44(lcMatrix33(lcVector3(0.0f, 0.0f, 1.0f), lcVector3(1.0f, 0.0f, 0.0f), lcVector3(0.0f, 1.0f, 0.0f)), lcVector3(0.0f, 0.0f, 0.0f)); + mMiddle.Transform = lcMatrix44Identity(); + mEnd.Transform = lcMatrix44(lcMatrix33(lcVector3(0.0f, 0.0f, 1.0f), lcVector3(1.0f, 0.0f, 0.0f), lcVector3(0.0f, 1.0f, 0.0f)), lcVector3(0.0f, 0.0f, 0.0f)); + } + else + { + mStart.Transform = lcMatrix44Identity(); + mMiddle.Transform = lcMatrix44Identity(); + mEnd.Transform = lcMatrix44Identity(); + } + mStart.Length = EdgeSectionLength; - mMiddle.Transform = lcMatrix44Identity(); mMiddle.Length = MidSectionLength; - mEnd.Transform = lcMatrix44(lcMatrix33(lcVector3(0.0f, 0.0f, 1.0f), lcVector3(1.0f, 0.0f, 0.0f), lcVector3(0.0f, 1.0f, 0.0f)), lcVector3(0.0f, 0.0f, 0.0f)); mEnd.Length = EdgeSectionLength; } @@ -106,14 +129,27 @@ void lcSynthInfo::GetDefaultControlPoints(lcArray& ControlP case LC_SYNTH_PIECE_STRING_BRAIDED: Scale = 12.0f; break; + + case LC_SYNTH_PIECE_SHOCK_ABSORBER: + Scale = 1.0f; + break; } float HalfLength = mLength / 2.0f; Scale = lcMin(Scale, HalfLength); - ControlPoints[0].Transform = lcMatrix44Translation(lcVector3(-HalfLength, 0.0f, 0.0f)); + if (mType != LC_SYNTH_PIECE_SHOCK_ABSORBER) + { + ControlPoints[0].Transform = lcMatrix44Translation(lcVector3(-HalfLength, 0.0f, 0.0f)); + ControlPoints[1].Transform = lcMatrix44Translation(lcVector3( HalfLength, 0.0f, 0.0f)); + } + else + { + ControlPoints[0].Transform = lcMatrix44Translation(lcVector3(0.0f, 0.0f, -mLength)); + ControlPoints[1].Transform = lcMatrix44Translation(lcVector3(0.0f, 0.0f, 0.0f)); + } + ControlPoints[0].Scale = Scale; - ControlPoints[1].Transform = lcMatrix44Translation(lcVector3( HalfLength, 0.0f, 0.0f)); ControlPoints[1].Scale = Scale; } @@ -162,7 +198,7 @@ float lcSynthInfo::GetSectionTwist(const lcMatrix44& StartTransform, const lcMat return 0.0f; } -void lcSynthInfo::CalculateSections(const lcArray& ControlPoints, lcArray& Sections, void (*SectionCallback)(const lcVector3& CurvePoint, int SegmentIndex, float t, void* Param), void* CallbackParam) const +void lcSynthInfo::CalculateCurveSections(const lcArray& ControlPoints, lcArray& Sections, void (*SectionCallback)(const lcVector3& CurvePoint, int SegmentIndex, float t, void* Param), void* CallbackParam) const { float SectionLength = 0.0f; @@ -276,6 +312,18 @@ void lcSynthInfo::CalculateSections(const lcArray& ControlP } } +void lcSynthInfo::CalculateLineSections(const lcArray& ControlPoints, lcArray& Sections, void(*SectionCallback)(const lcVector3& CurvePoint, int SegmentIndex, float t, void* Param), void* CallbackParam) const +{ + for (int ControlPointIdx = 0; ControlPointIdx < ControlPoints.GetSize(); ControlPointIdx++) + { + lcMatrix44 Transform = lcMatrix44LeoCADToLDraw(ControlPoints[ControlPointIdx].Transform); + Sections.Add(Transform); + + if (SectionCallback) + SectionCallback(Transform.GetTranslation(), ControlPointIdx, 1.0f, CallbackParam); + } +} + void lcSynthInfo::AddRibbedHoseParts(lcMemFile& File, const lcArray& Sections) const { char Line[256]; @@ -541,10 +589,47 @@ void lcSynthInfo::AddStringBraidedParts(lcMemFile& File, lcLibraryMeshData& Mesh } } +void lcSynthInfo::AddShockAbsorberParts(lcMemFile& File, lcArray& Sections) const +{ + char Line[256]; + lcVector3 Offset; + + Offset = Sections[0].GetTranslation(); + sprintf(Line, "1 0 %f %f %f 1 0 0 0 1 0 0 0 1 4254.DAT\n", Offset[0], Offset[1], Offset[2]); + File.WriteBuffer(Line, strlen(Line)); + + Offset = Sections[1].GetTranslation(); + sprintf(Line, "1 16 %f %f %f 1 0 0 0 1 0 0 0 1 4255.DAT\n", Offset[0], Offset[1], Offset[2]); + File.WriteBuffer(Line, strlen(Line)); + + float Distance = Sections[0].GetTranslation().y - Sections[1].GetTranslation().y; + float Scale = (Distance - 66.0f) / 44.0f; + const char* SpringPart; + + if (!strcmp(mPieceInfo->m_strName, "73129")) + SpringPart = "70038"; + else if (!strcmp(mPieceInfo->m_strName, "41838")) + SpringPart = "41837"; + else if (!strcmp(mPieceInfo->m_strName, "76138")) + SpringPart = "71953"; + else if (!strcmp(mPieceInfo->m_strName, "76537")) + SpringPart = "22977"; + else + return; + + Offset = Sections[0].GetTranslation(); + sprintf(Line, "1 494 %f %f %f 1 0 0 0 %f 0 0 0 1 %s.DAT\n", Offset[0], Offset[1] - 10 - 44.0f * Scale, Offset[2], Scale, SpringPart); + File.WriteBuffer(Line, strlen(Line)); +} + lcMesh* lcSynthInfo::CreateMesh(const lcArray& ControlPoints) const { lcArray Sections; - CalculateSections(ControlPoints, Sections, NULL, NULL); + + if (mCurve) + CalculateCurveSections(ControlPoints, Sections, NULL, NULL); + else + CalculateLineSections(ControlPoints, Sections, NULL, NULL); lcLibraryMeshData MeshData; lcMemFile File; // todo: rewrite this to pass the parts directly @@ -562,6 +647,10 @@ lcMesh* lcSynthInfo::CreateMesh(const lcArray& ControlPoint case LC_SYNTH_PIECE_STRING_BRAIDED: AddStringBraidedParts(File, MeshData, Sections); break; + + case LC_SYNTH_PIECE_SHOCK_ABSORBER: + AddShockAbsorberParts(File, Sections); + break; } File.WriteU8(0); @@ -613,7 +702,7 @@ int lcSynthInfo::InsertControlPoint(lcArray& ControlPoints, SynthInsertParam.BestSegment = -1; SynthInsertParam.BestDistance = FLT_MAX; - CalculateSections(ControlPoints, Sections, lcSynthInsertCallback, &SynthInsertParam); + CalculateCurveSections(ControlPoints, Sections, lcSynthInsertCallback, &SynthInsertParam); if (SynthInsertParam.BestSegment != -1) { diff --git a/common/lc_synth.h b/common/lc_synth.h index 57b9a035..68ace2f6 100644 --- a/common/lc_synth.h +++ b/common/lc_synth.h @@ -8,7 +8,8 @@ enum lcSynthType { LC_SYNTH_PIECE_RIBBED_HOSE, LC_SYNTH_PIECE_FLEXIBLE_AXLE, - LC_SYNTH_PIECE_STRING_BRAIDED + LC_SYNTH_PIECE_STRING_BRAIDED, + LC_SYNTH_PIECE_SHOCK_ABSORBER }; struct lcSynthComponent @@ -22,7 +23,17 @@ class lcLibraryMeshData; class lcSynthInfo { public: - lcSynthInfo(lcSynthType Type, float Length, int NumSections); + lcSynthInfo(lcSynthType Type, float Length, int NumSections, PieceInfo* Info); + + bool CanAddControlPoints() const + { + return mCurve; + } + + bool IsCurve() const + { + return mCurve; + } void GetDefaultControlPoints(lcArray& ControlPoints) const; int InsertControlPoint(lcArray& ControlPoints, const lcVector3& Start, const lcVector3& End) const; @@ -30,15 +41,19 @@ public: protected: float GetSectionTwist(const lcMatrix44& StartTransform, const lcMatrix44& EndTransform) const; - void CalculateSections(const lcArray& ControlPoints, lcArray& Sections, void(*SectionCallback)(const lcVector3& CurvePoint, int SegmentIndex, float t, void* Param), void* CallbackParam) const; + void CalculateCurveSections(const lcArray& ControlPoints, lcArray& Sections, void(*SectionCallback)(const lcVector3& CurvePoint, int SegmentIndex, float t, void* Param), void* CallbackParam) const; + void CalculateLineSections(const lcArray& ControlPoints, lcArray& Sections, void(*SectionCallback)(const lcVector3& CurvePoint, int SegmentIndex, float t, void* Param), void* CallbackParam) const; void AddRibbedHoseParts(lcMemFile& File, const lcArray& Sections) const; void AddFlexibleAxleParts(lcMemFile& File, lcLibraryMeshData& MeshData, const lcArray& Sections) const; void AddStringBraidedParts(lcMemFile& File, lcLibraryMeshData& MeshData, lcArray& Sections) const; + void AddShockAbsorberParts(lcMemFile& File, lcArray& Sections) const; + PieceInfo* mPieceInfo; lcSynthType mType; lcSynthComponent mStart; lcSynthComponent mMiddle; lcSynthComponent mEnd; + bool mCurve; float mLength; int mNumSections; bool mRigidEdges; diff --git a/common/light.h b/common/light.h index fadf3223..3dffc8b6 100644 --- a/common/light.h +++ b/common/light.h @@ -156,6 +156,11 @@ public: return ~0; } + virtual lcuint32 GetAllowedTransforms() const + { + return LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Y | LC_OBJECT_TRANSFORM_MOVE_Z; + } + virtual lcVector3 GetSectionPosition(lcuint32 Section) const { switch (Section) diff --git a/common/object.h b/common/object.h index 265db857..0dc6e8c2 100644 --- a/common/object.h +++ b/common/object.h @@ -44,6 +44,16 @@ struct lcObjectBoxTest lcArray Objects; }; +#define LC_OBJECT_TRANSFORM_MOVE_X 0x001 +#define LC_OBJECT_TRANSFORM_MOVE_Y 0x002 +#define LC_OBJECT_TRANSFORM_MOVE_Z 0x004 +#define LC_OBJECT_TRANSFORM_ROTATE_X 0x010 +#define LC_OBJECT_TRANSFORM_ROTATE_Y 0x020 +#define LC_OBJECT_TRANSFORM_ROTATE_Z 0x040 +#define LC_OBJECT_TRANSFORM_SCALE_X 0x100 +#define LC_OBJECT_TRANSFORM_SCALE_Y 0x200 +#define LC_OBJECT_TRANSFORM_SCALE_Z 0x400 + class lcObject { public: @@ -80,6 +90,7 @@ public: virtual void SetFocused(lcuint32 Section, bool Focused) = 0; virtual lcuint32 GetFocusSection() const = 0; + virtual lcuint32 GetAllowedTransforms() const = 0; virtual lcVector3 GetSectionPosition(lcuint32 Section) const = 0; virtual void RayTest(lcObjectRayTest& ObjectRayTest) const = 0; virtual void BoxTest(lcObjectBoxTest& ObjectBoxTest) const = 0; diff --git a/common/piece.cpp b/common/piece.cpp index 0afa714a..f7967723 100644 --- a/common/piece.cpp +++ b/common/piece.cpp @@ -735,16 +735,30 @@ void lcPiece::RotatePivotPoint(const lcMatrix33& RotationMatrix) mState |= LC_PIECE_PIVOT_POINT_VALID; } +lcuint32 lcPiece::GetAllowedTransforms() const +{ + lcuint32 Section = GetFocusSection(); + + if (Section == LC_PIECE_SECTION_POSITION || Section == LC_PIECE_SECTION_INVALID) + return LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Y | LC_OBJECT_TRANSFORM_MOVE_Z | LC_OBJECT_TRANSFORM_ROTATE_X | LC_OBJECT_TRANSFORM_ROTATE_Y | LC_OBJECT_TRANSFORM_ROTATE_Z; + + if (mPieceInfo->GetSynthInfo()->IsCurve()) + return LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Y | LC_OBJECT_TRANSFORM_MOVE_Z | LC_OBJECT_TRANSFORM_ROTATE_X | LC_OBJECT_TRANSFORM_ROTATE_Y | LC_OBJECT_TRANSFORM_ROTATE_Z | LC_OBJECT_TRANSFORM_SCALE_X; + else + return LC_OBJECT_TRANSFORM_MOVE_Z; +} + bool lcPiece::InsertControlPoint(const lcVector3& WorldStart, const lcVector3& WorldEnd) { - if (!mPieceInfo->GetSynthInfo()) + lcSynthInfo* SynthInfo = mPieceInfo->GetSynthInfo(); + if (!SynthInfo || !SynthInfo->CanAddControlPoints()) return false; lcMatrix44 InverseWorldMatrix = lcMatrix44AffineInverse(mModelWorld); lcVector3 Start = lcMul31(WorldStart, InverseWorldMatrix); lcVector3 End = lcMul31(WorldEnd, InverseWorldMatrix); - int ControlPointIndex = mPieceInfo->GetSynthInfo()->InsertControlPoint(mControlPoints, Start, End); + int ControlPointIndex = SynthInfo->InsertControlPoint(mControlPoints, Start, End); if (ControlPointIndex) { SetFocused(GetFocusSection(), false); diff --git a/common/piece.h b/common/piece.h index a1f9db34..4140592d 100644 --- a/common/piece.h +++ b/common/piece.h @@ -288,6 +288,8 @@ public: return LC_PIECE_SECTION_INVALID; } + virtual lcuint32 GetAllowedTransforms() const; + virtual lcVector3 GetSectionPosition(lcuint32 Section) const { switch (Section) diff --git a/common/view.cpp b/common/view.cpp index 7bac53ae..28ba665f 100644 --- a/common/view.cpp +++ b/common/view.cpp @@ -12,6 +12,7 @@ #include "preview.h" #include "piece.h" #include "pieceinf.h" +#include "lc_synth.h" lcVertexBuffer View::mRotateMoveVertexBuffer; lcIndexBuffer View::mRotateMoveIndexBuffer; @@ -680,64 +681,85 @@ void View::DrawSelectMoveOverlay() mContext->SetVertexBuffer(mRotateMoveVertexBuffer); mContext->SetVertexFormat(0, 3, 0, 0); + lcObject* Focus = mModel->GetFocusObject(); + lcuint32 AllowedTransforms = Focus ? Focus->GetAllowedTransforms() : LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Y | LC_OBJECT_TRANSFORM_MOVE_Z | LC_OBJECT_TRANSFORM_ROTATE_X | LC_OBJECT_TRANSFORM_ROTATE_Y | LC_OBJECT_TRANSFORM_ROTATE_Z; + if (mTrackButton == LC_TRACKBUTTON_NONE || (mTrackTool >= LC_TRACKTOOL_MOVE_X && mTrackTool <= LC_TRACKTOOL_MOVE_XYZ)) { - if ((mTrackTool == LC_TRACKTOOL_MOVE_X) || (mTrackTool == LC_TRACKTOOL_MOVE_XY) || (mTrackTool == LC_TRACKTOOL_MOVE_XZ)) + if (AllowedTransforms & LC_OBJECT_TRANSFORM_MOVE_X) { - mContext->SetColor(0.8f, 0.8f, 0.0f, 1.0f); - mContext->DrawIndexedPrimitives(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 0); - } - else if (mTrackButton == LC_TRACKBUTTON_NONE) - { - mContext->SetColor(0.8f, 0.0f, 0.0f, 1.0f); - mContext->DrawIndexedPrimitives(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 0); + if ((mTrackTool == LC_TRACKTOOL_MOVE_X) || (mTrackTool == LC_TRACKTOOL_MOVE_XY) || (mTrackTool == LC_TRACKTOOL_MOVE_XZ)) + { + mContext->SetColor(0.8f, 0.8f, 0.0f, 1.0f); + mContext->DrawIndexedPrimitives(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 0); + } + else if (mTrackButton == LC_TRACKBUTTON_NONE) + { + mContext->SetColor(0.8f, 0.0f, 0.0f, 1.0f); + mContext->DrawIndexedPrimitives(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 0); + } } - if ((mTrackTool == LC_TRACKTOOL_MOVE_Y) || (mTrackTool == LC_TRACKTOOL_MOVE_XY) || (mTrackTool == LC_TRACKTOOL_MOVE_YZ)) + if (AllowedTransforms & LC_OBJECT_TRANSFORM_MOVE_Y) { - mContext->SetColor(0.8f, 0.8f, 0.0f, 1.0f); - mContext->DrawIndexedPrimitives(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 36 * 2); - } - else if (mTrackButton == LC_TRACKBUTTON_NONE) - { - mContext->SetColor(0.0f, 0.8f, 0.0f, 1.0f); - mContext->DrawIndexedPrimitives(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 36 * 2); + if ((mTrackTool == LC_TRACKTOOL_MOVE_Y) || (mTrackTool == LC_TRACKTOOL_MOVE_XY) || (mTrackTool == LC_TRACKTOOL_MOVE_YZ) && (AllowedTransforms & LC_OBJECT_TRANSFORM_MOVE_Y)) + { + mContext->SetColor(0.8f, 0.8f, 0.0f, 1.0f); + mContext->DrawIndexedPrimitives(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 36 * 2); + } + else if (mTrackButton == LC_TRACKBUTTON_NONE) + { + mContext->SetColor(0.0f, 0.8f, 0.0f, 1.0f); + mContext->DrawIndexedPrimitives(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 36 * 2); + } } - if ((mTrackTool == LC_TRACKTOOL_MOVE_Z) || (mTrackTool == LC_TRACKTOOL_MOVE_XZ) || (mTrackTool == LC_TRACKTOOL_MOVE_YZ)) + if (AllowedTransforms & LC_OBJECT_TRANSFORM_MOVE_Z) { - mContext->SetColor(0.8f, 0.8f, 0.0f, 1.0f); - mContext->DrawIndexedPrimitives(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 72 * 2); - } - else if (mTrackButton == LC_TRACKBUTTON_NONE) - { - mContext->SetColor(0.0f, 0.0f, 0.8f, 1.0f); - mContext->DrawIndexedPrimitives(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 72 * 2); + if ((mTrackTool == LC_TRACKTOOL_MOVE_Z) || (mTrackTool == LC_TRACKTOOL_MOVE_XZ) || (mTrackTool == LC_TRACKTOOL_MOVE_YZ) && (AllowedTransforms & LC_OBJECT_TRANSFORM_MOVE_Z)) + { + mContext->SetColor(0.8f, 0.8f, 0.0f, 1.0f); + mContext->DrawIndexedPrimitives(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 72 * 2); + } + else if (mTrackButton == LC_TRACKBUTTON_NONE) + { + mContext->SetColor(0.0f, 0.0f, 0.8f, 1.0f); + mContext->DrawIndexedPrimitives(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 72 * 2); + } } } if (gMainWindow->GetTool() == LC_TOOL_SELECT && mTrackButton == LC_TRACKBUTTON_NONE && AnyPiecesSelected) { - if (mTrackTool == LC_TRACKTOOL_ROTATE_X) - mContext->SetColor(0.8f, 0.8f, 0.0f, 1.0f); - else - mContext->SetColor(0.8f, 0.0f, 0.0f, 1.0f); + if (AllowedTransforms & LC_OBJECT_TRANSFORM_ROTATE_X) + { + if (mTrackTool == LC_TRACKTOOL_ROTATE_X) + mContext->SetColor(0.8f, 0.8f, 0.0f, 1.0f); + else + mContext->SetColor(0.8f, 0.0f, 0.0f, 1.0f); - mContext->DrawIndexedPrimitives(GL_TRIANGLES, 120, GL_UNSIGNED_SHORT, 108 * 2); + mContext->DrawIndexedPrimitives(GL_TRIANGLES, 120, GL_UNSIGNED_SHORT, 108 * 2); + } - if (mTrackTool == LC_TRACKTOOL_ROTATE_Y) - mContext->SetColor(0.8f, 0.8f, 0.0f, 1.0f); - else - mContext->SetColor(0.0f, 0.8f, 0.0f, 1.0f); + if (AllowedTransforms & LC_OBJECT_TRANSFORM_ROTATE_Y) + { + if (mTrackTool == LC_TRACKTOOL_ROTATE_Y) + mContext->SetColor(0.8f, 0.8f, 0.0f, 1.0f); + else + mContext->SetColor(0.0f, 0.8f, 0.0f, 1.0f); - mContext->DrawIndexedPrimitives(GL_TRIANGLES, 120, GL_UNSIGNED_SHORT, (108 + 120) * 2); + mContext->DrawIndexedPrimitives(GL_TRIANGLES, 120, GL_UNSIGNED_SHORT, (108 + 120) * 2); + } - if (mTrackTool == LC_TRACKTOOL_ROTATE_Z) - mContext->SetColor(0.8f, 0.8f, 0.0f, 1.0f); - else - mContext->SetColor(0.0f, 0.0f, 0.8f, 1.0f); + if (AllowedTransforms & LC_OBJECT_TRANSFORM_ROTATE_Z) + { + if (mTrackTool == LC_TRACKTOOL_ROTATE_Z) + mContext->SetColor(0.8f, 0.8f, 0.0f, 1.0f); + else + mContext->SetColor(0.0f, 0.0f, 0.8f, 1.0f); - mContext->DrawIndexedPrimitives(GL_TRIANGLES, 120, GL_UNSIGNED_SHORT, (108 + 240) * 2); + mContext->DrawIndexedPrimitives(GL_TRIANGLES, 120, GL_UNSIGNED_SHORT, (108 + 240) * 2); + } } if ((mTrackTool == LC_TRACKTOOL_MOVE_XY) || (mTrackTool == LC_TRACKTOOL_MOVE_XZ) || (mTrackTool == LC_TRACKTOOL_MOVE_YZ)) @@ -757,13 +779,12 @@ void View::DrawSelectMoveOverlay() glDisable(GL_BLEND); } - lcObject* Focus = mModel->GetFocusObject(); if (Focus && Focus->IsPiece()) { lcPiece* Piece = (lcPiece*)Focus; lcuint32 Section = Piece->GetFocusSection(); - if (Section >= LC_PIECE_SECTION_CONTROL_POINT_1 && Section <= LC_PIECE_SECTION_CONTROL_POINT_8) + if (Section >= LC_PIECE_SECTION_CONTROL_POINT_1 && Section <= LC_PIECE_SECTION_CONTROL_POINT_8 && Piece->mPieceInfo->GetSynthInfo()->IsCurve()) { int ControlPointIndex = Section - LC_PIECE_SECTION_CONTROL_POINT_1; float Strength = Piece->GetControlPoints()[ControlPointIndex].Scale; @@ -1774,11 +1795,11 @@ void View::UpdateTrackTool() lcuint32 Section = Piece->GetFocusSection(); if (Section >= LC_PIECE_SECTION_CONTROL_POINT_1 && Section <= LC_PIECE_SECTION_CONTROL_POINT_8) - { ControlPointIndex = Section - LC_PIECE_SECTION_CONTROL_POINT_1; - } } + lcuint32 AllowedTransforms = Focus ? Focus->GetAllowedTransforms() : LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Y | LC_OBJECT_TRANSFORM_MOVE_Z | LC_OBJECT_TRANSFORM_ROTATE_X | LC_OBJECT_TRANSFORM_ROTATE_Y | LC_OBJECT_TRANSFORM_ROTATE_Z; + for (int AxisIndex = 0; AxisIndex < 3; AxisIndex++) { lcVector4 Plane(PlaneNormals[AxisIndex], -lcDot(PlaneNormals[AxisIndex], OverlayCenter)); @@ -1801,41 +1822,50 @@ void View::UpdateTrackTool() { lcTrackTool PlaneModes[] = { LC_TRACKTOOL_MOVE_YZ, LC_TRACKTOOL_MOVE_XZ, LC_TRACKTOOL_MOVE_XY }; - NewTrackTool = PlaneModes[AxisIndex]; - - ClosestIntersectionDistance = IntersectionDistance; + if (IsTrackToolAllowed(PlaneModes[AxisIndex], AllowedTransforms)) + { + NewTrackTool = PlaneModes[AxisIndex]; + ClosestIntersectionDistance = IntersectionDistance; + } } if (CurrentTool == LC_TOOL_SELECT && Proj1 > OverlayRotateArrowStart && Proj1 < OverlayRotateArrowEnd && Proj2 > OverlayRotateArrowStart && Proj2 < OverlayRotateArrowEnd && mModel->AnyPiecesSelected()) { lcTrackTool PlaneModes[] = { LC_TRACKTOOL_ROTATE_X, LC_TRACKTOOL_ROTATE_Y, LC_TRACKTOOL_ROTATE_Z }; - NewTrackTool = PlaneModes[AxisIndex]; - - ClosestIntersectionDistance = IntersectionDistance; + if (IsTrackToolAllowed(PlaneModes[AxisIndex], AllowedTransforms)) + { + NewTrackTool = PlaneModes[AxisIndex]; + ClosestIntersectionDistance = IntersectionDistance; + } } if (fabs(Proj1) < OverlayMoveArrowCapRadius && Proj2 > 0.0f && Proj2 < OverlayMoveArrowSize) { lcTrackTool DirModes[] = { LC_TRACKTOOL_MOVE_Z, LC_TRACKTOOL_MOVE_X, LC_TRACKTOOL_MOVE_Y }; - NewTrackTool = DirModes[AxisIndex]; - - ClosestIntersectionDistance = IntersectionDistance; + if (IsTrackToolAllowed(DirModes[AxisIndex], AllowedTransforms)) + { + NewTrackTool = DirModes[AxisIndex]; + ClosestIntersectionDistance = IntersectionDistance; + } } if (fabs(Proj2) < OverlayMoveArrowCapRadius && Proj1 > 0.0f && Proj1 < OverlayMoveArrowSize) { lcTrackTool DirModes[] = { LC_TRACKTOOL_MOVE_Y, LC_TRACKTOOL_MOVE_Z, LC_TRACKTOOL_MOVE_X }; - NewTrackTool = DirModes[AxisIndex]; - - ClosestIntersectionDistance = IntersectionDistance; + if (IsTrackToolAllowed(DirModes[AxisIndex], AllowedTransforms)) + { + NewTrackTool = DirModes[AxisIndex]; + ClosestIntersectionDistance = IntersectionDistance; + } } - if (ControlPointIndex != -1) + lcPiece* Piece = (lcPiece*)Focus; + + if (ControlPointIndex != -1 && Piece->mPieceInfo->GetSynthInfo()->IsCurve()) { - lcPiece* Piece = (lcPiece*)Focus; float Strength = Piece->GetControlPoints()[ControlPointIndex].Scale; const float ScaleStart = (2.0f - OverlayScaleRadius) * OverlayScale + Strength; const float ScaleEnd = (2.0f + OverlayScaleRadius) * OverlayScale + Strength; @@ -1844,30 +1874,38 @@ void View::UpdateTrackTool() { if (Proj2 > ScaleStart && Proj2 < ScaleEnd) { - NewTrackTool = LC_TRACKTOOL_SCALE_PLUS; - - ClosestIntersectionDistance = IntersectionDistance; + if (IsTrackToolAllowed(LC_TRACKTOOL_SCALE_PLUS, AllowedTransforms)) + { + NewTrackTool = LC_TRACKTOOL_SCALE_PLUS; + ClosestIntersectionDistance = IntersectionDistance; + } } else if (Proj2 < -ScaleStart && Proj2 > -ScaleEnd) { - NewTrackTool = LC_TRACKTOOL_SCALE_MINUS; - - ClosestIntersectionDistance = IntersectionDistance; + if (IsTrackToolAllowed(LC_TRACKTOOL_SCALE_MINUS, AllowedTransforms)) + { + NewTrackTool = LC_TRACKTOOL_SCALE_MINUS; + ClosestIntersectionDistance = IntersectionDistance; + } } } else if (AxisIndex == 2 && fabs(Proj2) < OverlayScaleRadius * OverlayScale) { if (Proj1 > ScaleStart && Proj1 < ScaleEnd) { - NewTrackTool = LC_TRACKTOOL_SCALE_PLUS; - - ClosestIntersectionDistance = IntersectionDistance; + if (IsTrackToolAllowed(LC_TRACKTOOL_SCALE_PLUS, AllowedTransforms)) + { + NewTrackTool = LC_TRACKTOOL_SCALE_PLUS; + ClosestIntersectionDistance = IntersectionDistance; + } } else if (Proj1 < -ScaleStart && Proj1 > -ScaleEnd) { - NewTrackTool = LC_TRACKTOOL_SCALE_MINUS; - - ClosestIntersectionDistance = IntersectionDistance; + if (IsTrackToolAllowed(LC_TRACKTOOL_SCALE_MINUS, AllowedTransforms)) + { + NewTrackTool = LC_TRACKTOOL_SCALE_MINUS; + ClosestIntersectionDistance = IntersectionDistance; + } } } } @@ -2106,6 +2144,73 @@ void View::UpdateTrackTool() } } +bool View::IsTrackToolAllowed(lcTrackTool TrackTool, lcuint32 AllowedTransforms) const +{ + switch (TrackTool) + { + case LC_TRACKTOOL_NONE: + case LC_TRACKTOOL_INSERT: + case LC_TRACKTOOL_POINTLIGHT: + case LC_TRACKTOOL_SPOTLIGHT: + case LC_TRACKTOOL_CAMERA: + case LC_TRACKTOOL_SELECT: + return true; + + case LC_TRACKTOOL_MOVE_X: + return AllowedTransforms & LC_OBJECT_TRANSFORM_MOVE_X; + + case LC_TRACKTOOL_MOVE_Y: + return AllowedTransforms & LC_OBJECT_TRANSFORM_MOVE_Y; + + case LC_TRACKTOOL_MOVE_Z: + return AllowedTransforms & LC_OBJECT_TRANSFORM_MOVE_Z; + + case LC_TRACKTOOL_MOVE_XY: + return (AllowedTransforms & (LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Y)) == (LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Y); + + case LC_TRACKTOOL_MOVE_XZ: + return (AllowedTransforms & (LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Z)) == (LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Z); + + case LC_TRACKTOOL_MOVE_YZ: + return (AllowedTransforms & (LC_OBJECT_TRANSFORM_MOVE_Y | LC_OBJECT_TRANSFORM_MOVE_Z)) == (LC_OBJECT_TRANSFORM_MOVE_Y | LC_OBJECT_TRANSFORM_MOVE_Z); + + case LC_TRACKTOOL_MOVE_XYZ: + return (AllowedTransforms & (LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Y | LC_OBJECT_TRANSFORM_MOVE_Z)) == (LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Y | LC_OBJECT_TRANSFORM_MOVE_Z); + + case LC_TRACKTOOL_ROTATE_X: + return AllowedTransforms & LC_OBJECT_TRANSFORM_ROTATE_X; + + case LC_TRACKTOOL_ROTATE_Y: + return AllowedTransforms & LC_OBJECT_TRANSFORM_ROTATE_Y; + + case LC_TRACKTOOL_ROTATE_Z: + return AllowedTransforms & LC_OBJECT_TRANSFORM_ROTATE_Z; + + case LC_TRACKTOOL_ROTATE_XY: + return (AllowedTransforms & (LC_OBJECT_TRANSFORM_ROTATE_X | LC_OBJECT_TRANSFORM_ROTATE_Y)) == (LC_OBJECT_TRANSFORM_ROTATE_X | LC_OBJECT_TRANSFORM_ROTATE_Y); + + case LC_TRACKTOOL_ROTATE_XYZ: + return (AllowedTransforms & (LC_OBJECT_TRANSFORM_ROTATE_X | LC_OBJECT_TRANSFORM_ROTATE_Y | LC_OBJECT_TRANSFORM_ROTATE_Z)) == (LC_OBJECT_TRANSFORM_ROTATE_X | LC_OBJECT_TRANSFORM_ROTATE_Y | LC_OBJECT_TRANSFORM_ROTATE_Z); + + case LC_TRACKTOOL_SCALE_PLUS: + case LC_TRACKTOOL_SCALE_MINUS: + return AllowedTransforms & (LC_OBJECT_TRANSFORM_SCALE_X | LC_OBJECT_TRANSFORM_SCALE_Y | LC_OBJECT_TRANSFORM_SCALE_Z); + + case LC_TRACKTOOL_ERASER: + case LC_TRACKTOOL_PAINT: + case LC_TRACKTOOL_ZOOM: + case LC_TRACKTOOL_PAN: + case LC_TRACKTOOL_ORBIT_X: + case LC_TRACKTOOL_ORBIT_Y: + case LC_TRACKTOOL_ORBIT_XY: + case LC_TRACKTOOL_ROLL: + case LC_TRACKTOOL_ZOOM_REGION: + return true; + } + + return false; +} + void View::StartTracking(lcTrackButton TrackButton) { LC_ASSERT(mTrackButton == LC_TRACKBUTTON_NONE); diff --git a/common/view.h b/common/view.h index be0a96fb..e5246fba 100644 --- a/common/view.h +++ b/common/view.h @@ -133,6 +133,7 @@ protected: void DrawViewport(); void UpdateTrackTool(); + bool IsTrackToolAllowed(lcTrackTool TrackTool, lcuint32 AllowedTransforms) const; lcTool GetCurrentTool() const; lcTrackTool GetOverrideTrackTool(Qt::MouseButton Button) const; float GetOverlayScale() const;