Support rotating lights.

This commit is contained in:
Leonardo Zide 2023-09-04 10:59:16 -07:00
parent 080a418e1b
commit 86327196c2
11 changed files with 247 additions and 79 deletions

View file

@ -202,7 +202,7 @@ public:
quint32 GetAllowedTransforms() const override quint32 GetAllowedTransforms() const override
{ {
return LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Y | LC_OBJECT_TRANSFORM_MOVE_Z; return LC_OBJECT_TRANSFORM_MOVE_XYZ;
} }
lcVector3 GetSectionPosition(quint32 Section) const override lcVector3 GetSectionPosition(quint32 Section) const override

View file

@ -2931,32 +2931,32 @@ void lcMainWindow::HandleCommand(lcCommandId CommandId)
case LC_PIECE_ROTATE_PLUSX: case LC_PIECE_ROTATE_PLUSX:
if (ActiveModel) if (ActiveModel)
ActiveModel->RotateSelectedPieces(ActiveView->GetMoveDirection(lcVector3(lcMax(GetAngleSnap(), 1.0f), 0.0f, 0.0f)), true, false, true, true); ActiveModel->RotateSelectedObjects(ActiveView->GetMoveDirection(lcVector3(lcMax(GetAngleSnap(), 1.0f), 0.0f, 0.0f)), true, false, true, true);
break; break;
case LC_PIECE_ROTATE_MINUSX: case LC_PIECE_ROTATE_MINUSX:
if (ActiveModel) if (ActiveModel)
ActiveModel->RotateSelectedPieces(ActiveView->GetMoveDirection(-lcVector3(lcMax(GetAngleSnap(), 1.0f), 0.0f, 0.0f)), true, false, true, true); ActiveModel->RotateSelectedObjects(ActiveView->GetMoveDirection(-lcVector3(lcMax(GetAngleSnap(), 1.0f), 0.0f, 0.0f)), true, false, true, true);
break; break;
case LC_PIECE_ROTATE_PLUSY: case LC_PIECE_ROTATE_PLUSY:
if (ActiveModel) if (ActiveModel)
ActiveModel->RotateSelectedPieces(ActiveView->GetMoveDirection(lcVector3(0.0f, lcMax(GetAngleSnap(), 1.0f), 0.0f)), true, false, true, true); ActiveModel->RotateSelectedObjects(ActiveView->GetMoveDirection(lcVector3(0.0f, lcMax(GetAngleSnap(), 1.0f), 0.0f)), true, false, true, true);
break; break;
case LC_PIECE_ROTATE_MINUSY: case LC_PIECE_ROTATE_MINUSY:
if (ActiveModel) if (ActiveModel)
ActiveModel->RotateSelectedPieces(ActiveView->GetMoveDirection(lcVector3(0.0f, -lcMax(GetAngleSnap(), 1.0f), 0.0f)), true, false, true, true); ActiveModel->RotateSelectedObjects(ActiveView->GetMoveDirection(lcVector3(0.0f, -lcMax(GetAngleSnap(), 1.0f), 0.0f)), true, false, true, true);
break; break;
case LC_PIECE_ROTATE_PLUSZ: case LC_PIECE_ROTATE_PLUSZ:
if (ActiveModel) if (ActiveModel)
ActiveModel->RotateSelectedPieces(ActiveView->GetMoveDirection(lcVector3(0.0f, 0.0f, lcMax(GetAngleSnap(), 1.0f))), true, false, true, true); ActiveModel->RotateSelectedObjects(ActiveView->GetMoveDirection(lcVector3(0.0f, 0.0f, lcMax(GetAngleSnap(), 1.0f))), true, false, true, true);
break; break;
case LC_PIECE_ROTATE_MINUSZ: case LC_PIECE_ROTATE_MINUSZ:
if (ActiveModel) if (ActiveModel)
ActiveModel->RotateSelectedPieces(ActiveView->GetMoveDirection(lcVector3(0.0f, 0.0f, -lcMax(GetAngleSnap(), 1.0f))), true, false, true, true); ActiveModel->RotateSelectedObjects(ActiveView->GetMoveDirection(lcVector3(0.0f, 0.0f, -lcMax(GetAngleSnap(), 1.0f))), true, false, true, true);
break; break;
case LC_PIECE_MINIFIG_WIZARD: case LC_PIECE_MINIFIG_WIZARD:

View file

@ -2776,7 +2776,7 @@ void lcModel::MoveSelectedObjects(const lcVector3& PieceDistance, const lcVector
} }
} }
void lcModel::RotateSelectedPieces(const lcVector3& Angles, bool Relative, bool RotatePivotPoint, bool Update, bool Checkpoint) void lcModel::RotateSelectedObjects(const lcVector3& Angles, bool Relative, bool RotatePivotPoint, bool Update, bool Checkpoint)
{ {
if (Angles.LengthSquared() < 0.001f) if (Angles.LengthSquared() < 0.001f)
return; return;
@ -2805,6 +2805,12 @@ void lcModel::RotateSelectedPieces(const lcVector3& Angles, bool Relative, bool
} }
else else
{ {
int Flags;
lcArray<lcObject*> Selection;
lcObject* Focus;
GetSelectionInformation(&Flags, Selection, &Focus);
if (!gMainWindow->GetSeparateTransform()) if (!gMainWindow->GetSeparateTransform())
{ {
lcVector3 Center; lcVector3 Center;
@ -2822,42 +2828,78 @@ void lcModel::RotateSelectedPieces(const lcVector3& Angles, bool Relative, bool
else else
WorldToFocusMatrix = lcMatrix33Identity(); WorldToFocusMatrix = lcMatrix33Identity();
for (lcPiece* Piece : mPieces) for (lcObject* Object : Selection)
{ {
if (!Piece->IsSelected()) if (Object->IsPiece())
continue; {
lcPiece* Piece = (lcPiece*)Object;
Piece->Rotate(mCurrentStep, gMainWindow->GetAddKeys(), RotationMatrix, Center, WorldToFocusMatrix); Piece->Rotate(mCurrentStep, gMainWindow->GetAddKeys(), RotationMatrix, Center, WorldToFocusMatrix);
Piece->UpdatePosition(mCurrentStep); Piece->UpdatePosition(mCurrentStep);
Rotated = true; Rotated = true;
}
else if (Object->IsLight())
{
lcLight* Light = (lcLight*)Object;
Light->Rotate(mCurrentStep, gMainWindow->GetAddKeys(), RotationMatrix, WorldToFocusMatrix);
Light->UpdatePosition(mCurrentStep);
Rotated = true;
}
} }
} }
else else
{ {
for (lcPiece* Piece : mPieces) for (lcObject* Object : Selection)
{ {
if (!Piece->IsSelected()) if (Object->IsPiece())
continue;
const lcVector3 Center = Piece->GetRotationCenter();
lcMatrix33 WorldToFocusMatrix;
lcMatrix33 RelativeRotationMatrix;
if (Relative)
{ {
const lcMatrix33 RelativeRotation = Piece->GetRelativeRotation(); lcPiece* Piece = (lcPiece*)Object;
WorldToFocusMatrix = lcMatrix33AffineInverse(RelativeRotation);
RelativeRotationMatrix = lcMul(RotationMatrix, RelativeRotation);
}
else
{
WorldToFocusMatrix = lcMatrix33Identity();
RelativeRotationMatrix = RotationMatrix;
}
Piece->Rotate(mCurrentStep, gMainWindow->GetAddKeys(), RelativeRotationMatrix, Center, WorldToFocusMatrix); const lcVector3 Center = Piece->GetRotationCenter();
Piece->UpdatePosition(mCurrentStep); lcMatrix33 WorldToFocusMatrix;
Rotated = true; lcMatrix33 RelativeRotationMatrix;
if (Relative)
{
const lcMatrix33 RelativeRotation = Piece->GetRelativeRotation();
WorldToFocusMatrix = lcMatrix33AffineInverse(RelativeRotation);
RelativeRotationMatrix = lcMul(RotationMatrix, RelativeRotation);
}
else
{
WorldToFocusMatrix = lcMatrix33Identity();
RelativeRotationMatrix = RotationMatrix;
}
Piece->Rotate(mCurrentStep, gMainWindow->GetAddKeys(), RelativeRotationMatrix, Center, WorldToFocusMatrix);
Piece->UpdatePosition(mCurrentStep);
Rotated = true;
}
else if (Object->IsLight())
{
lcLight* Light = (lcLight*)Object;
const lcVector3 Center = Light->GetRotationCenter();
lcMatrix33 WorldToFocusMatrix;
lcMatrix33 RelativeRotationMatrix;
if (Relative)
{
const lcMatrix33 RelativeRotation = Light->GetRelativeRotation();
WorldToFocusMatrix = lcMatrix33AffineInverse(RelativeRotation);
RelativeRotationMatrix = lcMul(RotationMatrix, RelativeRotation);
}
else
{
WorldToFocusMatrix = lcMatrix33Identity();
RelativeRotationMatrix = RotationMatrix;
}
Light->Rotate(mCurrentStep, gMainWindow->GetAddKeys(), RotationMatrix, WorldToFocusMatrix);
Light->UpdatePosition(mCurrentStep);
Rotated = true;
}
} }
} }
} }
@ -2911,11 +2953,11 @@ void lcModel::TransformSelectedObjects(lcTransformType TransformType, const lcVe
break; break;
case lcTransformType::AbsoluteRotation: case lcTransformType::AbsoluteRotation:
RotateSelectedPieces(Transform, false, false, true, true); RotateSelectedObjects(Transform, false, false, true, true);
break; break;
case lcTransformType::RelativeRotation: case lcTransformType::RelativeRotation:
RotateSelectedPieces(Transform, true, false, true, true); RotateSelectedObjects(Transform, true, false, true, true);
break; break;
case lcTransformType::Count: case lcTransformType::Count:
@ -3274,16 +3316,20 @@ bool lcModel::GetMoveRotateTransform(lcVector3& Center, lcMatrix33& RelativeRota
if (!Light->IsSelected()) if (!Light->IsSelected())
continue; continue;
if (Light->IsFocused() && Relative) if (Light->IsFocused())
{ {
Center = Light->GetSectionPosition(Light->GetFocusSection()); Center = Light->GetRotationCenter();
// RelativeRotation = Piece->GetRelativeRotation();
if (Relative)
RelativeRotation = Light->GetRelativeRotation();
return true; return true;
} }
Center += Light->GetSectionPosition(LC_LIGHT_SECTION_POSITION); Center += Light->GetSectionPosition(LC_LIGHT_SECTION_POSITION);
NumSelected++; NumSelected++;
if (Light->IsDirectionalLight())
if (!Light->IsPointLight())
{ {
Center += Light->GetSectionPosition(LC_LIGHT_SECTION_TARGET); Center += Light->GetSectionPosition(LC_LIGHT_SECTION_TARGET);
NumSelected++; NumSelected++;
@ -3299,6 +3345,33 @@ bool lcModel::GetMoveRotateTransform(lcVector3& Center, lcMatrix33& RelativeRota
return false; return false;
} }
bool lcModel::CanRotateSelection() const
{
int Flags;
lcArray<lcObject*> Selection;
lcObject* Focus;
GetSelectionInformation(&Flags, Selection, &Focus);
if (Flags & LC_SEL_PIECE)
{
if ((Flags & (LC_SEL_CAMERA | LC_SEL_LIGHT)) == 0)
return true;
}
if ((Flags & (LC_SEL_PIECE | LC_SEL_CAMERA)) == 0)
{
if (Focus && Focus->IsLight())
{
lcLight* Light = (lcLight*)Focus;
return (Light->GetAllowedTransforms() & LC_OBJECT_TRANSFORM_ROTATE_XYZ) != 0;
}
}
return false;
}
bool lcModel::GetPieceFocusOrSelectionCenter(lcVector3& Center) const bool lcModel::GetPieceFocusOrSelectionCenter(lcVector3& Center) const
{ {
lcVector3 Min(FLT_MAX, FLT_MAX, FLT_MAX), Max(-FLT_MAX, -FLT_MAX, -FLT_MAX); lcVector3 Min(FLT_MAX, FLT_MAX, FLT_MAX), Max(-FLT_MAX, -FLT_MAX, -FLT_MAX);
@ -3573,7 +3646,7 @@ void lcModel::GetSelectionInformation(int* Flags, lcArray<lcObject*>& Selection,
if (Camera->IsSelected()) if (Camera->IsSelected())
{ {
Selection.Add(Camera); Selection.Add(Camera);
*Flags |= LC_SEL_SELECTED; *Flags |= LC_SEL_SELECTED | LC_SEL_CAMERA;
if (Camera->IsFocused()) if (Camera->IsFocused())
*Focus = Camera; *Focus = Camera;
@ -3585,7 +3658,7 @@ void lcModel::GetSelectionInformation(int* Flags, lcArray<lcObject*>& Selection,
if (Light->IsSelected()) if (Light->IsSelected())
{ {
Selection.Add(Light); Selection.Add(Light);
*Flags |= LC_SEL_SELECTED; *Flags |= LC_SEL_SELECTED | LC_SEL_LIGHT;
if (Light->IsFocused()) if (Light->IsFocused())
*Focus = Light; *Focus = Light;
@ -4271,7 +4344,7 @@ void lcModel::UpdateMoveTool(const lcVector3& Distance, bool AllowRelative, bool
void lcModel::UpdateRotateTool(const lcVector3& Angles, bool AlternateButtonDrag) void lcModel::UpdateRotateTool(const lcVector3& Angles, bool AlternateButtonDrag)
{ {
const lcVector3 Delta = SnapRotation(Angles) - SnapRotation(mMouseToolDistance); const lcVector3 Delta = SnapRotation(Angles) - SnapRotation(mMouseToolDistance);
RotateSelectedPieces(Delta, true, AlternateButtonDrag, false, false); RotateSelectedObjects(Delta, true, AlternateButtonDrag, false, false);
mMouseToolDistance = Angles; mMouseToolDistance = Angles;
gMainWindow->UpdateSelectedObjects(false); gMainWindow->UpdateSelectedObjects(false);

View file

@ -5,18 +5,20 @@
#include "lc_array.h" #include "lc_array.h"
#define LC_SEL_NO_PIECES 0x0001 // No pieces in model #define LC_SEL_NO_PIECES 0x0001 // No pieces in model
#define LC_SEL_PIECE 0x0002 // At last 1 piece selected #define LC_SEL_PIECE 0x0002 // At least 1 piece selected
#define LC_SEL_SELECTED 0x0004 // At last 1 object selected #define LC_SEL_CAMERA 0x0004 // At least 1 camera selected
#define LC_SEL_UNSELECTED 0x0008 // At least 1 piece unselected #define LC_SEL_LIGHT 0x0008 // At least 1 light selected
#define LC_SEL_HIDDEN 0x0010 // At least one piece hidden #define LC_SEL_SELECTED 0x0010 // At least 1 object selected
#define LC_SEL_HIDDEN_SELECTED 0x0020 // At least one piece selected is hidden #define LC_SEL_UNSELECTED 0x0020 // At least 1 piece unselected
#define LC_SEL_VISIBLE_SELECTED 0x0040 // At least one piece selected is not hidden #define LC_SEL_HIDDEN 0x0040 // At least one piece hidden
#define LC_SEL_GROUPED 0x0080 // At least one piece selected is grouped #define LC_SEL_HIDDEN_SELECTED 0x0080 // At least one piece selected is hidden
#define LC_SEL_FOCUS_GROUPED 0x0100 // Focused piece is grouped #define LC_SEL_VISIBLE_SELECTED 0x0100 // At least one piece selected is not hidden
#define LC_SEL_CAN_GROUP 0x0200 // Can make a new group #define LC_SEL_GROUPED 0x0200 // At least one piece selected is grouped
#define LC_SEL_MODEL_SELECTED 0x0400 // At least one model reference is selected #define LC_SEL_FOCUS_GROUPED 0x0400 // Focused piece is grouped
#define LC_SEL_CAN_ADD_CONTROL_POINT 0x0800 // Can add control points to focused piece #define LC_SEL_CAN_GROUP 0x0800 // Can make a new group
#define LC_SEL_CAN_REMOVE_CONTROL_POINT 0x1000 // Can remove control points from focused piece #define LC_SEL_MODEL_SELECTED 0x1000 // At least one model reference is selected
#define LC_SEL_CAN_ADD_CONTROL_POINT 0x2000 // Can add control points to focused piece
#define LC_SEL_CAN_REMOVE_CONTROL_POINT 0x4000 // Can remove control points from focused piece
enum class lcSelectionMode enum class lcSelectionMode
{ {
@ -279,6 +281,7 @@ public:
lcModel* GetFirstSelectedSubmodel() const; lcModel* GetFirstSelectedSubmodel() const;
void GetSubModels(lcArray<lcModel*>& SubModels) const; void GetSubModels(lcArray<lcModel*>& SubModels) const;
bool GetMoveRotateTransform(lcVector3& Center, lcMatrix33& RelativeRotation) const; bool GetMoveRotateTransform(lcVector3& Center, lcMatrix33& RelativeRotation) const;
bool CanRotateSelection() const;
bool GetPieceFocusOrSelectionCenter(lcVector3& Center) const; bool GetPieceFocusOrSelectionCenter(lcVector3& Center) const;
lcVector3 GetSelectionOrModelCenter() const; lcVector3 GetSelectionOrModelCenter() const;
bool GetFocusPosition(lcVector3& Position) const; bool GetFocusPosition(lcVector3& Position) const;
@ -354,7 +357,7 @@ public:
} }
void MoveSelectedObjects(const lcVector3& PieceDistance, const lcVector3& ObjectDistance, bool AllowRelative, bool AlternateButtonDrag, bool Update, bool Checkpoint); void MoveSelectedObjects(const lcVector3& PieceDistance, const lcVector3& ObjectDistance, bool AllowRelative, bool AlternateButtonDrag, bool Update, bool Checkpoint);
void RotateSelectedPieces(const lcVector3& Angles, bool Relative, bool RotatePivotPoint, bool Update, bool Checkpoint); void RotateSelectedObjects(const lcVector3& Angles, bool Relative, bool RotatePivotPoint, bool Update, bool Checkpoint);
void ScaleSelectedPieces(const float Scale, bool Update, bool Checkpoint); void ScaleSelectedPieces(const float Scale, bool Update, bool Checkpoint);
void TransformSelectedObjects(lcTransformType TransformType, const lcVector3& Transform); void TransformSelectedObjects(lcTransformType TransformType, const lcVector3& Transform);
void SetSelectedPiecesColorIndex(int ColorIndex); void SetSelectedPiecesColorIndex(int ColorIndex);

View file

@ -928,7 +928,7 @@ void lcView::OnDraw()
mViewManipulator->DrawSelectMove(mTrackButton, mTrackTool); mViewManipulator->DrawSelectMove(mTrackButton, mTrackTool);
else if (GetCurrentTool() == lcTool::Move && mTrackButton != lcTrackButton::None) else if (GetCurrentTool() == lcTool::Move && mTrackButton != lcTrackButton::None)
mViewManipulator->DrawSelectMove(mTrackButton, mTrackTool); mViewManipulator->DrawSelectMove(mTrackButton, mTrackTool);
else if ((Tool == lcTool::Rotate || (Tool == lcTool::Select && mTrackButton != lcTrackButton::None && mTrackTool >= lcTrackTool::RotateX && mTrackTool <= lcTrackTool::RotateXYZ)) && ActiveModel->AnyPiecesSelected()) else if ((Tool == lcTool::Rotate || (Tool == lcTool::Select && mTrackButton != lcTrackButton::None && mTrackTool >= lcTrackTool::RotateX && mTrackTool <= lcTrackTool::RotateXYZ)) && ActiveModel->CanRotateSelection())
mViewManipulator->DrawRotate(mTrackButton, mTrackTool); mViewManipulator->DrawRotate(mTrackButton, mTrackTool);
else if ((mTrackTool == lcTrackTool::Select || mTrackTool == lcTrackTool::ZoomRegion) && mTrackButton != lcTrackButton::None) else if ((mTrackTool == lcTrackTool::Select || mTrackTool == lcTrackTool::ZoomRegion) && mTrackButton != lcTrackButton::None)
DrawSelectZoomRegionOverlay(); DrawSelectZoomRegionOverlay();
@ -2520,7 +2520,7 @@ void lcView::OnButtonDown(lcTrackButton TrackButton)
case lcTrackTool::RotateZ: case lcTrackTool::RotateZ:
case lcTrackTool::RotateXY: case lcTrackTool::RotateXY:
case lcTrackTool::RotateXYZ: case lcTrackTool::RotateXYZ:
if (ActiveModel->AnyPiecesSelected()) if (ActiveModel->CanRotateSelection())
StartTracking(TrackButton); StartTracking(TrackButton);
break; break;

View file

@ -795,7 +795,7 @@ lcTrackTool lcViewManipulator::UpdateSelectMove()
ControlPointIndex = Section - LC_PIECE_SECTION_CONTROL_POINT_FIRST; ControlPointIndex = Section - LC_PIECE_SECTION_CONTROL_POINT_FIRST;
} }
quint32 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; quint32 AllowedTransforms = Focus ? Focus->GetAllowedTransforms() : LC_OBJECT_TRANSFORM_MOVE_XYZ | LC_OBJECT_TRANSFORM_ROTATE_XYZ;
for (int AxisIndex = 0; AxisIndex < 3; AxisIndex++) for (int AxisIndex = 0; AxisIndex < 3; AxisIndex++)
{ {

View file

@ -859,6 +859,48 @@ void lcLight::MoveSelected(lcStep Step, bool AddKey, const lcVector3& Distance)
} }
} }
void lcLight::Rotate(lcStep Step, bool AddKey, const lcMatrix33& RotationMatrix, const lcMatrix33& RotationFrame)
{
if (IsPointLight())
return;
if (GetFocusSection() != LC_LIGHT_SECTION_POSITION)
return;
// lcVector3 Direction = mTargetPosition - mPosition;
//
// Direction = lcMul(Direction, RotationMatrix);
//
// mTargetPosition = mPosition + Direction;
// mTargetPositionKeys.ChangeKey(mTargetPosition, Step, AddKey);
const lcMatrix33 LocalToWorldMatrix = lcMatrix33AffineInverse(lcMatrix33(mWorldLight));
const lcMatrix33 LocalToFocusMatrix = lcMul(LocalToWorldMatrix, RotationFrame);
lcMatrix33 NewLocalToWorldMatrix = lcMul(LocalToFocusMatrix, RotationMatrix);
const lcMatrix33 WorldToLocalMatrix = lcMatrix33AffineInverse(LocalToWorldMatrix);
NewLocalToWorldMatrix.Orthonormalize();
lcVector3 Target = lcMul(lcVector3(0.0f, 0.0f, lcLength(mTargetPosition - mPosition)), NewLocalToWorldMatrix);
mTargetPosition = mPosition - Target;
mTargetPositionKeys.ChangeKey(mTargetPosition, Step, AddKey);
if (IsAreaLight())
{
const lcVector3 FrontVector(mTargetPosition - mPosition);
lcVector3 SideVector = lcCross(FrontVector, mUpVector);
if (fabsf(lcDot(mUpVector, SideVector)) > 0.99f)
SideVector = lcVector3(1, 0, 0);
mUpVector = lcCross(SideVector, FrontVector);
mUpVector.Normalize();
}
}
void lcLight::SetLightType(lcLightType LightType) void lcLight::SetLightType(lcLightType LightType)
{ {
if (static_cast<int>(LightType) < 0 || LightType >= lcLightType::Count) if (static_cast<int>(LightType) < 0 || LightType >= lcLightType::Count)
@ -937,9 +979,15 @@ void lcLight::UpdatePosition(lcStep Step)
} }
else if (IsAreaLight()) else if (IsAreaLight())
{ {
lcVector3 FrontVector(mTargetPosition - mPosition); lcVector3 UpVector(0, 0, 1), FrontVector(mPosition), SideVector;
const lcVector3 SideVector = lcCross(FrontVector, mUpVector); FrontVector.Normalize();
mUpVector = lcNormalize(lcCross(SideVector, FrontVector)); if (fabsf(lcDot(UpVector, FrontVector)) > 0.99f)
SideVector = lcVector3(-1, 0, 0);
else
SideVector = lcCross(FrontVector, UpVector);
UpVector = lcCross(SideVector, FrontVector);
UpVector.Normalize();
mUpVector = UpVector;
mWorldLight = lcMatrix44LookAt(mPosition, mTargetPosition, mUpVector); mWorldLight = lcMatrix44LookAt(mPosition, mTargetPosition, mUpVector);
} }

View file

@ -277,7 +277,32 @@ public:
quint32 GetAllowedTransforms() const override quint32 GetAllowedTransforms() const override
{ {
return LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Y | LC_OBJECT_TRANSFORM_MOVE_Z; if (IsPointLight())
return LC_OBJECT_TRANSFORM_MOVE_XYZ;
const quint32 Section = GetFocusSection();
if (Section == LC_LIGHT_SECTION_POSITION)
return LC_OBJECT_TRANSFORM_MOVE_XYZ | LC_OBJECT_TRANSFORM_ROTATE_XYZ;
if (Section == LC_LIGHT_SECTION_TARGET || Section == LC_LIGHT_SECTION_UPVECTOR)
return LC_OBJECT_TRANSFORM_MOVE_XYZ;
return 0;
}
lcMatrix33 GetRelativeRotation() const
{
const quint32 Section = GetFocusSection();
if (Section == LC_LIGHT_SECTION_POSITION)
{
return lcMatrix33AffineInverse(lcMatrix33(mWorldLight));
}
else
{
return lcMatrix33Identity();
}
} }
lcVector3 GetSectionPosition(quint32 Section) const override lcVector3 GetSectionPosition(quint32 Section) const override
@ -297,6 +322,23 @@ public:
return lcVector3(0.0f, 0.0f, 0.0f); return lcVector3(0.0f, 0.0f, 0.0f);
} }
lcVector3 GetRotationCenter() const
{
const quint32 Section = GetFocusSection();
switch (Section)
{
case LC_LIGHT_SECTION_POSITION:
return mPosition;
case LC_LIGHT_SECTION_TARGET:
case LC_LIGHT_SECTION_UPVECTOR:
return mTargetPosition;
}
return mPosition;
}
void SaveLDraw(QTextStream& Stream) const; void SaveLDraw(QTextStream& Stream) const;
bool ParseLDrawLine(QTextStream& Stream); bool ParseLDrawLine(QTextStream& Stream);
@ -341,6 +383,7 @@ public:
void CompareBoundingBox(lcVector3& Min, lcVector3& Max); void CompareBoundingBox(lcVector3& Min, lcVector3& Max);
void UpdatePosition(lcStep Step); void UpdatePosition(lcStep Step);
void MoveSelected(lcStep Step, bool AddKey, const lcVector3& Distance); void MoveSelected(lcStep Step, bool AddKey, const lcVector3& Distance);
void Rotate(lcStep Step, bool AddKey, const lcMatrix33& RotationMatrix, const lcMatrix33& RotationFrame);
bool Setup(int LightIndex); bool Setup(int LightIndex);
void CreateName(const lcArray<lcLight*>& Lights); void CreateName(const lcArray<lcLight*>& Lights);
void UpdateLight(lcStep Step, lcLightProperties Props, int Property); void UpdateLight(lcStep Step, lcLightProperties Props, int Property);

View file

@ -79,15 +79,18 @@ struct lcObjectBoxTest
lcArray<lcObject*> Objects; lcArray<lcObject*> Objects;
}; };
#define LC_OBJECT_TRANSFORM_MOVE_X 0x001 #define LC_OBJECT_TRANSFORM_MOVE_X 0x001
#define LC_OBJECT_TRANSFORM_MOVE_Y 0x002 #define LC_OBJECT_TRANSFORM_MOVE_Y 0x002
#define LC_OBJECT_TRANSFORM_MOVE_Z 0x004 #define LC_OBJECT_TRANSFORM_MOVE_Z 0x004
#define LC_OBJECT_TRANSFORM_ROTATE_X 0x010 #define LC_OBJECT_TRANSFORM_MOVE_XYZ (LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Y | LC_OBJECT_TRANSFORM_MOVE_Z)
#define LC_OBJECT_TRANSFORM_ROTATE_Y 0x020 #define LC_OBJECT_TRANSFORM_ROTATE_X 0x010
#define LC_OBJECT_TRANSFORM_ROTATE_Z 0x040 #define LC_OBJECT_TRANSFORM_ROTATE_Y 0x020
#define LC_OBJECT_TRANSFORM_SCALE_X 0x100 #define LC_OBJECT_TRANSFORM_ROTATE_Z 0x040
#define LC_OBJECT_TRANSFORM_SCALE_Y 0x200 #define LC_OBJECT_TRANSFORM_ROTATE_XYZ (LC_OBJECT_TRANSFORM_ROTATE_X | LC_OBJECT_TRANSFORM_ROTATE_Y | LC_OBJECT_TRANSFORM_ROTATE_Z)
#define LC_OBJECT_TRANSFORM_SCALE_Z 0x400 #define LC_OBJECT_TRANSFORM_SCALE_X 0x100
#define LC_OBJECT_TRANSFORM_SCALE_Y 0x200
#define LC_OBJECT_TRANSFORM_SCALE_Z 0x400
#define LC_OBJECT_TRANSFORM_SCALE_XYZ (LC_OBJECT_TRANSFORM_SCALE_X | LC_OBJECT_TRANSFORM_SCALE_Y | LC_OBJECT_TRANSFORM_SCALE_Z)
class lcObject class lcObject
{ {

View file

@ -835,12 +835,10 @@ void lcPiece::RotatePivotPoint(const lcMatrix33& RotationMatrix)
quint32 lcPiece::GetAllowedTransforms() const quint32 lcPiece::GetAllowedTransforms() const
{ {
constexpr quint32 Move = LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Y | LC_OBJECT_TRANSFORM_MOVE_Z;
constexpr quint32 Rotate = LC_OBJECT_TRANSFORM_ROTATE_X | LC_OBJECT_TRANSFORM_ROTATE_Y | LC_OBJECT_TRANSFORM_ROTATE_Z;
const quint32 Section = GetFocusSection(); const quint32 Section = GetFocusSection();
if (Section == LC_PIECE_SECTION_POSITION || Section == LC_PIECE_SECTION_INVALID) if (Section == LC_PIECE_SECTION_POSITION || Section == LC_PIECE_SECTION_INVALID)
return Move | Rotate; return LC_OBJECT_TRANSFORM_MOVE_XYZ | LC_OBJECT_TRANSFORM_ROTATE_XYZ;
const lcSynthInfo* SynthInfo = mPieceInfo->GetSynthInfo(); const lcSynthInfo* SynthInfo = mPieceInfo->GetSynthInfo();
@ -850,10 +848,10 @@ quint32 lcPiece::GetAllowedTransforms() const
return LC_OBJECT_TRANSFORM_MOVE_Z; return LC_OBJECT_TRANSFORM_MOVE_Z;
if (SynthInfo->IsCurve()) if (SynthInfo->IsCurve())
return Move | Rotate | LC_OBJECT_TRANSFORM_SCALE_X; return LC_OBJECT_TRANSFORM_MOVE_XYZ | LC_OBJECT_TRANSFORM_ROTATE_XYZ | LC_OBJECT_TRANSFORM_SCALE_X;
if (SynthInfo->IsNondirectional()) if (SynthInfo->IsNondirectional())
return Move; return LC_OBJECT_TRANSFORM_MOVE_XYZ;
} }
return 0; return 0;

View file

@ -747,7 +747,7 @@ void lcQPropertiesTree::slotReturnPressed()
else if (Item == partRotationZ) else if (Item == partRotationZ)
Rotation[2] = Value; Rotation[2] = Value;
Model->RotateSelectedPieces(Rotation - InitialRotation, true, false, true, true); Model->RotateSelectedObjects(Rotation - InitialRotation, true, false, true, true);
} }
else if (Item == partShow) else if (Item == partShow)
{ {