Support dragging light targets to rotate.

This commit is contained in:
Leonardo Zide 2023-09-23 18:38:03 -07:00
parent 177c1b82d7
commit a27694a594
7 changed files with 170 additions and 116 deletions

View file

@ -2901,32 +2901,32 @@ void lcMainWindow::HandleCommand(lcCommandId CommandId)
case LC_PIECE_MOVE_PLUSX: case LC_PIECE_MOVE_PLUSX:
if (ActiveModel) if (ActiveModel)
ActiveModel->MoveSelectedObjects(ActiveView->GetMoveDirection(lcVector3(lcMax(GetMoveXYSnap(), 0.1f), 0.0f, 0.0f)), true, false, true, true); ActiveModel->MoveSelectedObjects(ActiveView->GetMoveDirection(lcVector3(lcMax(GetMoveXYSnap(), 0.1f), 0.0f, 0.0f)), true, false, true, true, true);
break; break;
case LC_PIECE_MOVE_MINUSX: case LC_PIECE_MOVE_MINUSX:
if (ActiveModel) if (ActiveModel)
ActiveModel->MoveSelectedObjects(ActiveView->GetMoveDirection(lcVector3(-lcMax(GetMoveXYSnap(), 0.1f), 0.0f, 0.0f)), true, false, true, true); ActiveModel->MoveSelectedObjects(ActiveView->GetMoveDirection(lcVector3(-lcMax(GetMoveXYSnap(), 0.1f), 0.0f, 0.0f)), true, false, true, true, true);
break; break;
case LC_PIECE_MOVE_PLUSY: case LC_PIECE_MOVE_PLUSY:
if (ActiveModel) if (ActiveModel)
ActiveModel->MoveSelectedObjects(ActiveView->GetMoveDirection(lcVector3(0.0f, lcMax(GetMoveXYSnap(), 0.1f), 0.0f)), true, false, true, true); ActiveModel->MoveSelectedObjects(ActiveView->GetMoveDirection(lcVector3(0.0f, lcMax(GetMoveXYSnap(), 0.1f), 0.0f)), true, false, true, true, true);
break; break;
case LC_PIECE_MOVE_MINUSY: case LC_PIECE_MOVE_MINUSY:
if (ActiveModel) if (ActiveModel)
ActiveModel->MoveSelectedObjects(ActiveView->GetMoveDirection(lcVector3(0.0f, -lcMax(GetMoveXYSnap(), 0.1f), 0.0f)), true, false, true, true); ActiveModel->MoveSelectedObjects(ActiveView->GetMoveDirection(lcVector3(0.0f, -lcMax(GetMoveXYSnap(), 0.1f), 0.0f)), true, false, true, true, true);
break; break;
case LC_PIECE_MOVE_PLUSZ: case LC_PIECE_MOVE_PLUSZ:
if (ActiveModel) if (ActiveModel)
ActiveModel->MoveSelectedObjects(ActiveView->GetMoveDirection(lcVector3(0.0f, 0.0f, lcMax(GetMoveZSnap(), 0.1f))), true, false, true, true); ActiveModel->MoveSelectedObjects(ActiveView->GetMoveDirection(lcVector3(0.0f, 0.0f, lcMax(GetMoveZSnap(), 0.1f))), true, false, true, true, true);
break; break;
case LC_PIECE_MOVE_MINUSZ: case LC_PIECE_MOVE_MINUSZ:
if (ActiveModel) if (ActiveModel)
ActiveModel->MoveSelectedObjects(ActiveView->GetMoveDirection(lcVector3(0.0f, 0.0f, -lcMax(GetMoveZSnap(), 0.1f))), true, false, true, true); ActiveModel->MoveSelectedObjects(ActiveView->GetMoveDirection(lcVector3(0.0f, 0.0f, -lcMax(GetMoveZSnap(), 0.1f))), true, false, true, true, true);
break; break;
case LC_PIECE_ROTATE_PLUSX: case LC_PIECE_ROTATE_PLUSX:

View file

@ -2705,7 +2705,7 @@ bool lcModel::RemoveSelectedObjects()
return RemovedPiece || RemovedCamera || RemovedLight; return RemovedPiece || RemovedCamera || RemovedLight;
} }
void lcModel::MoveSelectedObjects(const lcVector3& PieceDistance, const lcVector3& ObjectDistance, bool AllowRelative, bool AlternateButtonDrag, bool Update, bool Checkpoint) void lcModel::MoveSelectedObjects(const lcVector3& PieceDistance, const lcVector3& ObjectDistance, bool AllowRelative, bool AlternateButtonDrag, bool Update, bool Checkpoint, bool FirstMove)
{ {
bool Moved = false; bool Moved = false;
lcMatrix33 RelativeRotation; lcMatrix33 RelativeRotation;
@ -2745,16 +2745,6 @@ void lcModel::MoveSelectedObjects(const lcVector3& PieceDistance, const lcVector
Moved = true; Moved = true;
} }
} }
for (lcLight* Light : mLights)
{
if (Light->IsSelected())
{
Light->MoveSelected(mCurrentStep, gMainWindow->GetAddKeys(), TransformedPieceDistance);
Light->UpdatePosition(mCurrentStep);
Moved = true;
}
}
} }
} }
@ -2771,13 +2761,25 @@ void lcModel::MoveSelectedObjects(const lcVector3& PieceDistance, const lcVector
Moved = true; Moved = true;
} }
} }
for (lcLight* Light : mLights)
{
if (Light->IsSelected())
{
Light->MoveSelected(mCurrentStep, gMainWindow->GetAddKeys(), TransformedObjectDistance, FirstMove);
Light->UpdatePosition(mCurrentStep);
Moved = true;
}
}
} }
if (Moved && Update) if (Moved && Update)
{ {
UpdateAllViews(); UpdateAllViews();
if (Checkpoint) if (Checkpoint)
SaveCheckpoint(tr("Moving")); SaveCheckpoint(tr("Moving"));
gMainWindow->UpdateSelectedObjects(false); gMainWindow->UpdateSelectedObjects(false);
} }
} }
@ -2951,11 +2953,11 @@ void lcModel::TransformSelectedObjects(lcTransformType TransformType, const lcVe
switch (TransformType) switch (TransformType)
{ {
case lcTransformType::AbsoluteTranslation: case lcTransformType::AbsoluteTranslation:
MoveSelectedObjects(Transform, false, false, true, true); MoveSelectedObjects(Transform, false, false, true, true, true);
break; break;
case lcTransformType::RelativeTranslation: case lcTransformType::RelativeTranslation:
MoveSelectedObjects(Transform, true, false, true, true); MoveSelectedObjects(Transform, true, false, true, true, true);
break; break;
case lcTransformType::AbsoluteRotation: case lcTransformType::AbsoluteRotation:
@ -4214,6 +4216,7 @@ void lcModel::RedoAction()
void lcModel::BeginMouseTool() void lcModel::BeginMouseTool()
{ {
mMouseToolDistance = lcVector3(0.0f, 0.0f, 0.0f); mMouseToolDistance = lcVector3(0.0f, 0.0f, 0.0f);
mMouseToolFirstMove = true;
} }
void lcModel::EndMouseTool(lcTool Tool, bool Accept) void lcModel::EndMouseTool(lcTool Tool, bool Accept)
@ -4335,6 +4338,7 @@ void lcModel::BeginCameraTool(const lcVector3& Position, const lcVector3& Target
mCameras.Add(Camera); mCameras.Add(Camera);
mMouseToolDistance = Position; mMouseToolDistance = Position;
mMouseToolFirstMove = false;
ClearSelectionAndSetFocus(Camera, LC_CAMERA_SECTION_TARGET, false); ClearSelectionAndSetFocus(Camera, LC_CAMERA_SECTION_TARGET, false);
} }
@ -4347,6 +4351,7 @@ void lcModel::UpdateCameraTool(const lcVector3& Position)
Camera->UpdatePosition(1); Camera->UpdatePosition(1);
mMouseToolDistance = Position; mMouseToolDistance = Position;
mMouseToolFirstMove = false;
gMainWindow->UpdateSelectedObjects(false); gMainWindow->UpdateSelectedObjects(false);
UpdateAllViews(); UpdateAllViews();
@ -4357,8 +4362,10 @@ void lcModel::UpdateMoveTool(const lcVector3& Distance, bool AllowRelative, bool
const lcVector3 PieceDistance = SnapPosition(Distance) - SnapPosition(mMouseToolDistance); const lcVector3 PieceDistance = SnapPosition(Distance) - SnapPosition(mMouseToolDistance);
const lcVector3 ObjectDistance = Distance - mMouseToolDistance; const lcVector3 ObjectDistance = Distance - mMouseToolDistance;
MoveSelectedObjects(PieceDistance, ObjectDistance, AllowRelative, AlternateButtonDrag, true, false); MoveSelectedObjects(PieceDistance, ObjectDistance, AllowRelative, AlternateButtonDrag, true, false, mMouseToolFirstMove);
mMouseToolDistance = Distance; mMouseToolDistance = Distance;
mMouseToolFirstMove = false;
gMainWindow->UpdateSelectedObjects(false); gMainWindow->UpdateSelectedObjects(false);
UpdateAllViews(); UpdateAllViews();
@ -4368,7 +4375,9 @@ void lcModel::UpdateRotateTool(const lcVector3& Angles, bool AlternateButtonDrag
{ {
const lcVector3 Delta = SnapRotation(Angles) - SnapRotation(mMouseToolDistance); const lcVector3 Delta = SnapRotation(Angles) - SnapRotation(mMouseToolDistance);
RotateSelectedObjects(Delta, true, AlternateButtonDrag, false, false); RotateSelectedObjects(Delta, true, AlternateButtonDrag, false, false);
mMouseToolDistance = Angles; mMouseToolDistance = Angles;
mMouseToolFirstMove = false;
gMainWindow->UpdateSelectedObjects(false); gMainWindow->UpdateSelectedObjects(false);
UpdateAllViews(); UpdateAllViews();

View file

@ -348,12 +348,12 @@ public:
void ZoomExtents(lcCamera* Camera, float Aspect); void ZoomExtents(lcCamera* Camera, float Aspect);
void Zoom(lcCamera* Camera, float Amount); void Zoom(lcCamera* Camera, float Amount);
void MoveSelectedObjects(const lcVector3& Distance, bool AllowRelative, bool AlternateButtonDrag, bool Update, bool Checkpoint) void MoveSelectedObjects(const lcVector3& Distance, bool AllowRelative, bool AlternateButtonDrag, bool Update, bool Checkpoint, bool FirstMove)
{ {
MoveSelectedObjects(Distance, Distance, AllowRelative, AlternateButtonDrag, Update, Checkpoint); MoveSelectedObjects(Distance, Distance, AllowRelative, AlternateButtonDrag, Update, Checkpoint, FirstMove);
} }
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, bool FirstMove);
void RotateSelectedObjects(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);
@ -409,6 +409,7 @@ protected:
bool mActive; bool mActive;
lcStep mCurrentStep; lcStep mCurrentStep;
lcVector3 mMouseToolDistance; lcVector3 mMouseToolDistance;
bool mMouseToolFirstMove;
lcArray<lcPiece*> mPieces; lcArray<lcPiece*> mPieces;
lcArray<lcCamera*> mCameras; lcArray<lcCamera*> mCameras;

View file

@ -2054,7 +2054,7 @@ void lcView::UpdateTrackTool()
break; break;
case lcTool::AreaLight: case lcTool::AreaLight:
NewTrackTool = lcTrackTool::AreaLight;; NewTrackTool = lcTrackTool::AreaLight;
break; break;
case lcTool::Camera: case lcTool::Camera:

View file

@ -9,7 +9,7 @@
#include "lc_context.h" #include "lc_context.h"
#define LC_LIGHT_SPHERE_RADIUS 5.0f #define LC_LIGHT_SPHERE_RADIUS 5.0f
#define LC_LIGHT_TARGET_EDGE 2.0f #define LC_LIGHT_TARGET_RADIUS 2.5f
#define LC_LIGHT_SPOT_CONE_HEIGHT 10.0f #define LC_LIGHT_SPOT_CONE_HEIGHT 10.0f
#define LC_LIGHT_SPOT_CONE_RADIUS 7.5f #define LC_LIGHT_SPOT_CONE_RADIUS 7.5f
#define LC_LIGHT_DIRECTIONAL_RADIUS 5.0f #define LC_LIGHT_DIRECTIONAL_RADIUS 5.0f
@ -627,6 +627,16 @@ void lcLight::RayTest(lcObjectRayTest& ObjectRayTest) const
ObjectRayTest.PieceInfoRayTest.Plane = Plane; ObjectRayTest.PieceInfoRayTest.Plane = Plane;
} }
} }
if (IsSelected())
{
if (lcSphereRayMinIntersectDistance(lcMul31(lcVector3(0,0,-mTargetDistance), mWorldMatrix), LC_LIGHT_TARGET_RADIUS, ObjectRayTest.Start, ObjectRayTest.End, &Distance) && (Distance < ObjectRayTest.Distance))
{
ObjectRayTest.ObjectSection.Object = const_cast<lcLight*>(this);
ObjectRayTest.ObjectSection.Section = LC_LIGHT_SECTION_TARGET;
ObjectRayTest.Distance = Distance;
}
}
} }
void lcLight::BoxTest(lcObjectBoxTest& ObjectBoxTest) const void lcLight::BoxTest(lcObjectBoxTest& ObjectBoxTest) const
@ -659,9 +669,11 @@ void lcLight::BoxTest(lcObjectBoxTest& ObjectBoxTest) const
} }
} }
void lcLight::MoveSelected(lcStep Step, bool AddKey, const lcVector3& Distance) void lcLight::MoveSelected(lcStep Step, bool AddKey, const lcVector3& Distance, bool FirstMove)
{ {
if (IsSelected(LC_LIGHT_SECTION_POSITION)) const quint32 Section = GetFocusSection();
if (Section == LC_LIGHT_SECTION_POSITION || Section == LC_LIGHT_SECTION_INVALID)
{ {
const lcVector3 Position = mWorldMatrix.GetTranslation() + Distance; const lcVector3 Position = mWorldMatrix.GetTranslation() + Distance;
@ -669,6 +681,26 @@ void lcLight::MoveSelected(lcStep Step, bool AddKey, const lcVector3& Distance)
mWorldMatrix.SetTranslation(Position); mWorldMatrix.SetTranslation(Position);
} }
else
{
if (FirstMove)
mTargetMovePosition = lcMul31(lcVector3(0.0f, 0.0f, -mTargetDistance), mWorldMatrix);
mTargetMovePosition += Distance;
lcVector3 CurrentDirection = -lcNormalize(mTargetMovePosition - mWorldMatrix.GetTranslation());
lcMatrix33 WorldMatrix;
WorldMatrix.r[0] = lcCross(lcVector3(mWorldMatrix.r[1]), CurrentDirection);
WorldMatrix.r[1] = lcCross(CurrentDirection, WorldMatrix.r[0]);
WorldMatrix.r[2] = CurrentDirection;
WorldMatrix.Orthonormalize();
SetRotation(WorldMatrix, Step, AddKey);
mWorldMatrix = lcMatrix44(WorldMatrix, mWorldMatrix.GetTranslation());
}
} }
void lcLight::Rotate(lcStep Step, bool AddKey, const lcMatrix33& RotationMatrix, const lcVector3& Center, const lcMatrix33& RotationFrame) void lcLight::Rotate(lcStep Step, bool AddKey, const lcMatrix33& RotationMatrix, const lcVector3& Center, const lcMatrix33& RotationFrame)
@ -861,7 +893,7 @@ void lcLight::DrawPointLight(lcContext* Context) const
{ {
SetupLightMatrix(Context); SetupLightMatrix(Context);
DrawSphere(Context, LC_LIGHT_SPHERE_RADIUS); DrawSphere(Context, lcVector3(0.0f, 0.0f, 0.0f), LC_LIGHT_SPHERE_RADIUS);
} }
void lcLight::DrawSpotLight(lcContext* Context) const void lcLight::DrawSpotLight(lcContext* Context) const
@ -899,12 +931,11 @@ void lcLight::DrawSpotLight(lcContext* Context) const
Context->DrawIndexedPrimitives(GL_LINES, (ConeEdges + 4) * 2, GL_UNSIGNED_SHORT, 0); Context->DrawIndexedPrimitives(GL_LINES, (ConeEdges + 4) * 2, GL_UNSIGNED_SHORT, 0);
const float TargetDistance = 250.0f;
DrawTarget(Context, TargetDistance);
if (IsSelected()) if (IsSelected())
DrawCone(Context, TargetDistance); {
DrawCone(Context, mTargetDistance);
DrawTarget(Context);
}
} }
void lcLight::DrawDirectionalLight(lcContext* Context) const void lcLight::DrawDirectionalLight(lcContext* Context) const
@ -913,9 +944,8 @@ void lcLight::DrawDirectionalLight(lcContext* Context) const
DrawCylinder(Context, LC_LIGHT_DIRECTIONAL_RADIUS, LC_LIGHT_DIRECTIONAL_HEIGHT); DrawCylinder(Context, LC_LIGHT_DIRECTIONAL_RADIUS, LC_LIGHT_DIRECTIONAL_HEIGHT);
const float TargetDistance = 25.0f; if (IsSelected())
DrawTarget(Context);
DrawTarget(Context, TargetDistance);
} }
void lcLight::DrawAreaLight(lcContext* Context) const void lcLight::DrawAreaLight(lcContext* Context) const
@ -988,9 +1018,8 @@ void lcLight::DrawAreaLight(lcContext* Context) const
Context->DrawIndexedPrimitives(GL_LINES, (CircleEdges + 2) * 2, GL_UNSIGNED_SHORT, 0); Context->DrawIndexedPrimitives(GL_LINES, (CircleEdges + 2) * 2, GL_UNSIGNED_SHORT, 0);
} }
const float TargetDistance = 25.0f; if (IsSelected())
DrawTarget(Context);
DrawTarget(Context, TargetDistance);
} }
void lcLight::SetupLightMatrix(lcContext* Context) const void lcLight::SetupLightMatrix(lcContext* Context) const
@ -1021,7 +1050,7 @@ void lcLight::SetupLightMatrix(lcContext* Context) const
} }
} }
void lcLight::DrawSphere(lcContext* Context, float Radius) const void lcLight::DrawSphere(lcContext* Context, const lcVector3& Center, float Radius) const
{ {
constexpr int Slices = 6; constexpr int Slices = 6;
constexpr int NumIndices = 3 * Slices + 6 * Slices * (Slices - 2) + 3 * Slices; constexpr int NumIndices = 3 * Slices + 6 * Slices * (Slices - 2) + 3 * Slices;
@ -1032,7 +1061,7 @@ void lcLight::DrawSphere(lcContext* Context, float Radius) const
lcVector3* Vertex = Vertices; lcVector3* Vertex = Vertices;
quint16* Index = Indices; quint16* Index = Indices;
*Vertex++ = lcVector3(0, 0, Radius); *Vertex++ = Center + lcVector3(0, 0, Radius);
for (int i = 1; i < Slices; i++) for (int i = 1; i < Slices; i++)
{ {
@ -1044,11 +1073,11 @@ void lcLight::DrawSphere(lcContext* Context, float Radius) const
const float x0 = r0 * sinf(j * (LC_2PI / Slices)); const float x0 = r0 * sinf(j * (LC_2PI / Slices));
const float y0 = r0 * cosf(j * (LC_2PI / Slices)); const float y0 = r0 * cosf(j * (LC_2PI / Slices));
*Vertex++ = lcVector3(x0, y0, z0); *Vertex++ = Center + lcVector3(x0, y0, z0);
} }
} }
*Vertex++ = lcVector3(0, 0, -Radius); *Vertex++ = Center + lcVector3(0, 0, -Radius);
for (quint16 i = 0; i < Slices - 1; i++) for (quint16 i = 0; i < Slices - 1; i++)
{ {
@ -1138,37 +1167,50 @@ void lcLight::DrawCylinder(lcContext* Context, float Radius, float Height) const
Context->DrawIndexedPrimitives(GL_LINES, 48, GL_UNSIGNED_SHORT, 0); Context->DrawIndexedPrimitives(GL_LINES, 48, GL_UNSIGNED_SHORT, 0);
} }
void lcLight::DrawTarget(lcContext* Context, float TargetDistance) const void lcLight::DrawTarget(lcContext* Context) const
{ {
float Verts[10 * 3]; float Verts[2 * 3];
float* CurVert = Verts; float* CurVert = Verts;
*CurVert++ = LC_LIGHT_TARGET_EDGE; *CurVert++ = LC_LIGHT_TARGET_EDGE; *CurVert++ = LC_LIGHT_TARGET_EDGE - TargetDistance;
*CurVert++ = -LC_LIGHT_TARGET_EDGE; *CurVert++ = LC_LIGHT_TARGET_EDGE; *CurVert++ = LC_LIGHT_TARGET_EDGE - TargetDistance;
*CurVert++ = -LC_LIGHT_TARGET_EDGE; *CurVert++ = -LC_LIGHT_TARGET_EDGE; *CurVert++ = LC_LIGHT_TARGET_EDGE - TargetDistance;
*CurVert++ = LC_LIGHT_TARGET_EDGE; *CurVert++ = -LC_LIGHT_TARGET_EDGE; *CurVert++ = LC_LIGHT_TARGET_EDGE - TargetDistance;
*CurVert++ = LC_LIGHT_TARGET_EDGE; *CurVert++ = LC_LIGHT_TARGET_EDGE; *CurVert++ = -LC_LIGHT_TARGET_EDGE - TargetDistance;
*CurVert++ = -LC_LIGHT_TARGET_EDGE; *CurVert++ = LC_LIGHT_TARGET_EDGE; *CurVert++ = -LC_LIGHT_TARGET_EDGE - TargetDistance;
*CurVert++ = -LC_LIGHT_TARGET_EDGE; *CurVert++ = -LC_LIGHT_TARGET_EDGE; *CurVert++ = -LC_LIGHT_TARGET_EDGE - TargetDistance;
*CurVert++ = LC_LIGHT_TARGET_EDGE; *CurVert++ = -LC_LIGHT_TARGET_EDGE; *CurVert++ = -LC_LIGHT_TARGET_EDGE - TargetDistance;
*CurVert++ = 0.0f; *CurVert++ = 0.0f; *CurVert++ = 0.0f; *CurVert++ = 0.0f; *CurVert++ = 0.0f; *CurVert++ = 0.0f;
*CurVert++ = 0.0f; *CurVert++ = 0.0f; *CurVert++ = -TargetDistance; *CurVert++ = 0.0f; *CurVert++ = 0.0f; *CurVert++ = -mTargetDistance;
Context->SetVertexBufferPointer(Verts); Context->SetVertexBufferPointer(Verts);
Context->SetVertexFormatPosition(3); Context->SetVertexFormatPosition(3);
const GLushort Indices[(12 + 1) * 2] = const GLushort Indices[2] =
{ {
0, 1, 1, 2, 2, 3, 3, 0, 0, 1
4, 5, 5, 6, 6, 7, 7, 4,
0, 4, 1, 5, 2, 6, 3, 7,
8, 9
}; };
Context->SetIndexBufferPointer(Indices); Context->SetIndexBufferPointer(Indices);
Context->DrawIndexedPrimitives(GL_LINES, (12 + 1) * 2, GL_UNSIGNED_SHORT, 0); Context->DrawIndexedPrimitives(GL_LINES, 2, GL_UNSIGNED_SHORT, 0);
const lcPreferences& Preferences = lcGetPreferences();
const float LineWidth = Preferences.mLineWidth;
if (IsSelected(LC_LIGHT_SECTION_TARGET))
{
const lcVector4 SelectedColor = lcVector4FromColor(Preferences.mObjectSelectedColor);
const lcVector4 FocusedColor = lcVector4FromColor(Preferences.mObjectFocusedColor);
Context->SetLineWidth(2.0f * LineWidth);
if (IsFocused(LC_LIGHT_SECTION_TARGET))
Context->SetColor(FocusedColor);
else
Context->SetColor(SelectedColor);
}
else
{
const lcVector4 LightColor = lcVector4FromColor(Preferences.mLightColor);
Context->SetLineWidth(LineWidth);
Context->SetColor(LightColor);
}
DrawSphere(Context, lcVector3(0.0f, 0.0f, -mTargetDistance), LC_LIGHT_TARGET_RADIUS);
} }
void lcLight::DrawCone(lcContext* Context, float TargetDistance) const void lcLight::DrawCone(lcContext* Context, float TargetDistance) const

View file

@ -5,15 +5,12 @@
#define LC_LIGHT_HIDDEN 0x0001 #define LC_LIGHT_HIDDEN 0x0001
#define LC_LIGHT_DISABLED 0x0002 #define LC_LIGHT_DISABLED 0x0002
#define LC_LIGHT_POSITION_SELECTED 0x0010
#define LC_LIGHT_POSITION_FOCUSED 0x0020
#define LC_LIGHT_SELECTION_MASK LC_LIGHT_POSITION_SELECTED enum lcLightSection : quint32
#define LC_LIGHT_FOCUS_MASK LC_LIGHT_POSITION_FOCUSED
enum lcLightSection
{ {
LC_LIGHT_SECTION_POSITION LC_LIGHT_SECTION_INVALID = ~0U,
LC_LIGHT_SECTION_POSITION = 0,
LC_LIGHT_SECTION_TARGET
}; };
enum class lcLightType enum class lcLightType
@ -99,77 +96,58 @@ public:
bool IsSelected() const override bool IsSelected() const override
{ {
return (mState & LC_LIGHT_SELECTION_MASK) != 0; return mSelected;
} }
bool IsSelected(quint32 Section) const override bool IsSelected(quint32 Section) const override
{ {
switch (Section) Q_UNUSED(Section);
{
case LC_LIGHT_SECTION_POSITION:
return (mState & LC_LIGHT_POSITION_SELECTED) != 0;
break;
}
return false; return mSelected;
} }
void SetSelected(bool Selected) override void SetSelected(bool Selected) override
{ {
if (Selected) mSelected = Selected;
mState |= LC_LIGHT_POSITION_SELECTED;
else if (!Selected)
mState &= ~(LC_LIGHT_SELECTION_MASK | LC_LIGHT_FOCUS_MASK); mFocusedSection = LC_LIGHT_SECTION_INVALID;
} }
void SetSelected(quint32 Section, bool Selected) override void SetSelected(quint32 Section, bool Selected) override
{ {
switch (Section) Q_UNUSED(Section);
{
case LC_LIGHT_SECTION_POSITION: mSelected = Selected;
if (Selected)
mState |= LC_LIGHT_POSITION_SELECTED; if (!Selected)
else mFocusedSection = LC_LIGHT_SECTION_INVALID;
mState &= ~(LC_LIGHT_POSITION_SELECTED | LC_LIGHT_POSITION_FOCUSED);
break;
}
} }
bool IsFocused() const override bool IsFocused() const override
{ {
return (mState & LC_LIGHT_FOCUS_MASK) != 0; return mFocusedSection != LC_LIGHT_SECTION_INVALID;
} }
bool IsFocused(quint32 Section) const override bool IsFocused(quint32 Section) const override
{ {
switch (Section) return mFocusedSection == Section;
{
case LC_LIGHT_SECTION_POSITION:
return (mState & LC_LIGHT_POSITION_FOCUSED) != 0;
}
return false;
} }
void SetFocused(quint32 Section, bool Focused) override void SetFocused(quint32 Section, bool Focused) override
{ {
switch (Section)
{
case LC_LIGHT_SECTION_POSITION:
if (Focused) if (Focused)
mState |= LC_LIGHT_POSITION_SELECTED | LC_LIGHT_POSITION_FOCUSED; {
else mFocusedSection = Section;
mState &= ~(LC_LIGHT_POSITION_SELECTED | LC_LIGHT_POSITION_FOCUSED); mSelected = true;
break;
} }
else
mFocusedSection = LC_LIGHT_SECTION_INVALID;
} }
quint32 GetFocusSection() const override quint32 GetFocusSection() const override
{ {
if (mState & LC_LIGHT_POSITION_FOCUSED) return mFocusedSection;
return LC_LIGHT_SECTION_POSITION;
return ~0U;
} }
quint32 GetAllowedTransforms() const override quint32 GetAllowedTransforms() const override
@ -179,9 +157,12 @@ public:
const quint32 Section = GetFocusSection(); const quint32 Section = GetFocusSection();
if (Section == LC_LIGHT_SECTION_POSITION) if (Section == LC_LIGHT_SECTION_POSITION || Section == LC_LIGHT_SECTION_INVALID)
return LC_OBJECT_TRANSFORM_MOVE_XYZ | LC_OBJECT_TRANSFORM_ROTATE_XYZ; return LC_OBJECT_TRANSFORM_MOVE_XYZ | LC_OBJECT_TRANSFORM_ROTATE_XYZ;
if (Section == LC_LIGHT_SECTION_TARGET)
return LC_OBJECT_TRANSFORM_MOVE_XYZ;
return 0; return 0;
} }
@ -197,9 +178,13 @@ public:
lcVector3 GetSectionPosition(quint32 Section) const override lcVector3 GetSectionPosition(quint32 Section) const override
{ {
Q_UNUSED(Section); if (Section == LC_LIGHT_SECTION_POSITION)
return mWorldMatrix.GetTranslation(); return mWorldMatrix.GetTranslation();
if (Section == LC_LIGHT_SECTION_TARGET)
return lcMul31(lcVector3(0.0f, 0.0f, -mTargetDistance), mWorldMatrix);
return lcVector3(0.0f, 0.0f, 0.0f);
} }
void SetPosition(const lcVector3& Position, lcStep Step, bool AddKey) void SetPosition(const lcVector3& Position, lcStep Step, bool AddKey)
@ -213,9 +198,18 @@ public:
} }
lcVector3 GetRotationCenter() const lcVector3 GetRotationCenter() const
{
const quint32 Section = GetFocusSection();
if (Section == LC_LIGHT_SECTION_POSITION || Section == LC_LIGHT_SECTION_INVALID)
{ {
return mWorldMatrix.GetTranslation(); return mWorldMatrix.GetTranslation();
} }
else
{
return lcMul31(lcVector3(0.0f, 0.0f, -mTargetDistance), mWorldMatrix);
}
}
lcVector3 GetPosition() const lcVector3 GetPosition() const
{ {
@ -305,7 +299,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, bool FirstMove);
void Rotate(lcStep Step, bool AddKey, const lcMatrix33& RotationMatrix, const lcVector3& Center, const lcMatrix33& RotationFrame); void Rotate(lcStep Step, bool AddKey, const lcMatrix33& RotationMatrix, const lcVector3& Center, const lcMatrix33& RotationFrame);
bool Setup(int LightIndex); bool Setup(int LightIndex);
void CreateName(const lcArray<lcLight*>& Lights); void CreateName(const lcArray<lcLight*>& Lights);
@ -347,13 +341,12 @@ protected:
void DrawAreaLight(lcContext* Context) const; void DrawAreaLight(lcContext* Context) const;
void SetupLightMatrix(lcContext* Context) const; void SetupLightMatrix(lcContext* Context) const;
void DrawSphere(lcContext* Context, float Radius) const; void DrawSphere(lcContext* Context, const lcVector3& Center, float Radius) const;
void DrawCylinder(lcContext* Context, float Radius, float Height) const; void DrawCylinder(lcContext* Context, float Radius, float Height) const;
void DrawTarget(lcContext* Context, float TargetDistance) const; void DrawTarget(lcContext* Context) const;
void DrawCone(lcContext* Context, float TargetDistance) const; void DrawCone(lcContext* Context, float TargetDistance) const;
QString mName; QString mName;
quint32 mState = 0;
lcLightType mLightType = lcLightType::Point; lcLightType mLightType = lcLightType::Point;
bool mCastShadow = true; bool mCastShadow = true;
lcVector3 mColor = lcVector3(1.0f, 1.0f, 1.0f); lcVector3 mColor = lcVector3(1.0f, 1.0f, 1.0f);
@ -363,6 +356,11 @@ protected:
float mSpotTightness = 0.0f; float mSpotTightness = 0.0f;
lcLightAreaShape mAreaShape = lcLightAreaShape::Rectangle; lcLightAreaShape mAreaShape = lcLightAreaShape::Rectangle;
quint32 mState = 0;
bool mSelected = false;
quint32 mFocusedSection = LC_LIGHT_SECTION_INVALID;
lcVector3 mTargetMovePosition = lcVector3(0.0f, 0.0f, 0.0f);
lcObjectKeyArray<lcVector3> mPositionKeys; lcObjectKeyArray<lcVector3> mPositionKeys;
lcObjectKeyArray<lcMatrix33> mRotationKeys; lcObjectKeyArray<lcMatrix33> mRotationKeys;
lcObjectKeyArray<lcVector3> mColorKeys; lcObjectKeyArray<lcVector3> mColorKeys;
@ -377,4 +375,6 @@ protected:
lcObjectKeyArray<float> mLightDiffuseKeys; lcObjectKeyArray<float> mLightDiffuseKeys;
lcObjectKeyArray<float> mSpotCutoffKeys; lcObjectKeyArray<float> mSpotCutoffKeys;
lcObjectKeyArray<float> mSpotExponentKeys; lcObjectKeyArray<float> mSpotExponentKeys;
static constexpr float mTargetDistance = 50.0f;
}; };

View file

@ -48,6 +48,7 @@ public:
void SetSelected(bool Selected) override void SetSelected(bool Selected) override
{ {
mSelected = Selected; mSelected = Selected;
if (!Selected) if (!Selected)
mFocusedSection = LC_PIECE_SECTION_INVALID; mFocusedSection = LC_PIECE_SECTION_INVALID;
} }
@ -57,6 +58,7 @@ public:
Q_UNUSED(Section); Q_UNUSED(Section);
mSelected = Selected; mSelected = Selected;
if (!Selected) if (!Selected)
mFocusedSection = LC_PIECE_SECTION_INVALID; mFocusedSection = LC_PIECE_SECTION_INVALID;
} }