2017-07-19 23:20:32 +02:00
|
|
|
#pragma once
|
2011-09-07 23:06:51 +02:00
|
|
|
|
|
|
|
#include "object.h"
|
2012-06-07 02:08:59 +02:00
|
|
|
#include "lc_math.h"
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-01 16:55:12 +02:00
|
|
|
#define LC_LIGHT_HIDDEN 0x0001
|
|
|
|
#define LC_LIGHT_DISABLED 0x0002
|
|
|
|
|
2023-09-24 03:38:03 +02:00
|
|
|
enum lcLightSection : quint32
|
2014-05-01 16:55:12 +02:00
|
|
|
{
|
2023-09-24 03:38:03 +02:00
|
|
|
LC_LIGHT_SECTION_INVALID = ~0U,
|
|
|
|
LC_LIGHT_SECTION_POSITION = 0,
|
|
|
|
LC_LIGHT_SECTION_TARGET
|
2014-05-01 16:55:12 +02:00
|
|
|
};
|
|
|
|
|
2023-08-13 15:15:52 +02:00
|
|
|
enum class lcLightType
|
2023-08-07 11:31:33 +02:00
|
|
|
{
|
2023-08-13 15:15:52 +02:00
|
|
|
Point,
|
|
|
|
Spot,
|
|
|
|
Directional,
|
2023-09-02 05:46:29 +02:00
|
|
|
Area,
|
|
|
|
Count
|
2023-08-07 11:31:33 +02:00
|
|
|
};
|
|
|
|
|
2023-09-17 19:40:23 +02:00
|
|
|
enum class lcLightAreaShape
|
2023-08-07 11:31:33 +02:00
|
|
|
{
|
2023-09-17 19:40:23 +02:00
|
|
|
Rectangle,
|
|
|
|
Square,
|
|
|
|
Disk,
|
|
|
|
Ellipse,
|
|
|
|
Count
|
2023-08-07 11:31:33 +02:00
|
|
|
};
|
|
|
|
|
2014-05-01 20:42:11 +02:00
|
|
|
class lcLight : public lcObject
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
|
|
|
public:
|
2023-09-05 05:53:34 +02:00
|
|
|
lcLight(const lcVector3& Position, lcLightType LightType);
|
2023-08-13 15:15:52 +02:00
|
|
|
virtual ~lcLight() = default;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2020-05-04 00:39:39 +02:00
|
|
|
lcLight(const lcLight&) = delete;
|
|
|
|
lcLight(lcLight&&) = delete;
|
|
|
|
lcLight& operator=(const lcLight&) = delete;
|
|
|
|
lcLight& operator=(lcLight&&) = delete;
|
|
|
|
|
2023-09-17 20:45:14 +02:00
|
|
|
static QString GetLightTypeString(lcLightType LightType);
|
2023-12-31 21:55:35 +01:00
|
|
|
static QStringList GetLightTypeStrings();
|
2023-09-17 19:40:23 +02:00
|
|
|
static QString GetAreaShapeString(lcLightAreaShape LightAreaShape);
|
2023-12-31 21:55:35 +01:00
|
|
|
static QStringList GetAreaShapeStrings();
|
2023-09-02 05:46:29 +02:00
|
|
|
|
2014-05-01 16:55:12 +02:00
|
|
|
bool IsPointLight() const
|
|
|
|
{
|
2023-08-13 15:15:52 +02:00
|
|
|
return mLightType == lcLightType::Point;
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2023-09-10 03:25:34 +02:00
|
|
|
bool IsSpotLight() const
|
2023-08-27 04:43:08 +02:00
|
|
|
{
|
|
|
|
return mLightType == lcLightType::Spot;
|
|
|
|
}
|
|
|
|
|
2014-05-01 16:55:12 +02:00
|
|
|
bool IsDirectionalLight() const
|
|
|
|
{
|
2023-08-13 15:15:52 +02:00
|
|
|
return mLightType == lcLightType::Directional;
|
|
|
|
}
|
|
|
|
|
2023-08-27 04:43:08 +02:00
|
|
|
bool IsAreaLight() const
|
|
|
|
{
|
|
|
|
return mLightType == lcLightType::Area;
|
|
|
|
}
|
|
|
|
|
2023-08-13 15:15:52 +02:00
|
|
|
lcLightType GetLightType() const
|
|
|
|
{
|
|
|
|
return mLightType;
|
|
|
|
}
|
|
|
|
|
2023-09-17 19:40:23 +02:00
|
|
|
bool SetLightType(lcLightType LightType);
|
2023-09-02 05:46:29 +02:00
|
|
|
|
2020-03-22 23:44:41 +01:00
|
|
|
bool IsSelected() const override
|
2014-05-01 16:55:12 +02:00
|
|
|
{
|
2023-09-24 03:38:03 +02:00
|
|
|
return mSelected;
|
2014-05-01 16:55:12 +02:00
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2020-03-22 23:44:41 +01:00
|
|
|
bool IsSelected(quint32 Section) const override
|
2014-05-01 16:55:12 +02:00
|
|
|
{
|
2023-09-24 03:38:03 +02:00
|
|
|
Q_UNUSED(Section);
|
2023-09-05 05:53:34 +02:00
|
|
|
|
2023-09-24 03:38:03 +02:00
|
|
|
return mSelected;
|
2014-05-01 16:55:12 +02:00
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2020-03-22 23:44:41 +01:00
|
|
|
void SetSelected(bool Selected) override
|
2014-05-01 16:55:12 +02:00
|
|
|
{
|
2023-09-24 03:38:03 +02:00
|
|
|
mSelected = Selected;
|
|
|
|
|
|
|
|
if (!Selected)
|
|
|
|
mFocusedSection = LC_LIGHT_SECTION_INVALID;
|
2014-05-01 16:55:12 +02:00
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2020-03-22 23:44:41 +01:00
|
|
|
void SetSelected(quint32 Section, bool Selected) override
|
2014-05-01 16:55:12 +02:00
|
|
|
{
|
2023-09-24 03:38:03 +02:00
|
|
|
Q_UNUSED(Section);
|
|
|
|
|
|
|
|
mSelected = Selected;
|
|
|
|
|
|
|
|
if (!Selected)
|
|
|
|
mFocusedSection = LC_LIGHT_SECTION_INVALID;
|
2014-05-01 16:55:12 +02:00
|
|
|
}
|
|
|
|
|
2020-03-22 23:44:41 +01:00
|
|
|
bool IsFocused() const override
|
2014-05-01 16:55:12 +02:00
|
|
|
{
|
2023-09-24 03:38:03 +02:00
|
|
|
return mFocusedSection != LC_LIGHT_SECTION_INVALID;
|
2014-05-01 16:55:12 +02:00
|
|
|
}
|
|
|
|
|
2020-03-22 23:44:41 +01:00
|
|
|
bool IsFocused(quint32 Section) const override
|
2014-05-01 16:55:12 +02:00
|
|
|
{
|
2023-09-24 03:38:03 +02:00
|
|
|
return mFocusedSection == Section;
|
2014-05-01 16:55:12 +02:00
|
|
|
}
|
|
|
|
|
2020-03-22 23:44:41 +01:00
|
|
|
void SetFocused(quint32 Section, bool Focused) override
|
2014-05-01 16:55:12 +02:00
|
|
|
{
|
2023-09-24 03:38:03 +02:00
|
|
|
if (Focused)
|
2014-05-01 16:55:12 +02:00
|
|
|
{
|
2023-09-24 03:38:03 +02:00
|
|
|
mFocusedSection = Section;
|
|
|
|
mSelected = true;
|
2014-05-01 16:55:12 +02:00
|
|
|
}
|
2023-09-24 03:38:03 +02:00
|
|
|
else
|
|
|
|
mFocusedSection = LC_LIGHT_SECTION_INVALID;
|
2014-05-01 16:55:12 +02:00
|
|
|
}
|
|
|
|
|
2020-03-22 23:44:41 +01:00
|
|
|
quint32 GetFocusSection() const override
|
2014-05-01 16:55:12 +02:00
|
|
|
{
|
2023-09-24 03:38:03 +02:00
|
|
|
return mFocusedSection;
|
2014-05-01 16:55:12 +02:00
|
|
|
}
|
|
|
|
|
2020-03-22 23:44:41 +01:00
|
|
|
quint32 GetAllowedTransforms() const override
|
2016-05-01 02:20:37 +02:00
|
|
|
{
|
2023-09-04 19:59:16 +02:00
|
|
|
if (IsPointLight())
|
|
|
|
return LC_OBJECT_TRANSFORM_MOVE_XYZ;
|
|
|
|
|
|
|
|
const quint32 Section = GetFocusSection();
|
|
|
|
|
2023-09-24 03:38:03 +02:00
|
|
|
if (Section == LC_LIGHT_SECTION_POSITION || Section == LC_LIGHT_SECTION_INVALID)
|
2023-09-04 19:59:16 +02:00
|
|
|
return LC_OBJECT_TRANSFORM_MOVE_XYZ | LC_OBJECT_TRANSFORM_ROTATE_XYZ;
|
|
|
|
|
2023-09-24 03:38:03 +02:00
|
|
|
if (Section == LC_LIGHT_SECTION_TARGET)
|
|
|
|
return LC_OBJECT_TRANSFORM_MOVE_XYZ;
|
|
|
|
|
2023-09-04 19:59:16 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
lcMatrix33 GetRelativeRotation() const
|
|
|
|
{
|
|
|
|
const quint32 Section = GetFocusSection();
|
|
|
|
|
|
|
|
if (Section == LC_LIGHT_SECTION_POSITION)
|
2023-09-05 05:53:34 +02:00
|
|
|
return lcMatrix33(mWorldMatrix);
|
2023-09-04 19:59:16 +02:00
|
|
|
else
|
|
|
|
return lcMatrix33Identity();
|
2016-05-01 02:20:37 +02:00
|
|
|
}
|
|
|
|
|
2020-03-22 23:44:41 +01:00
|
|
|
lcVector3 GetSectionPosition(quint32 Section) const override
|
2014-05-01 16:55:12 +02:00
|
|
|
{
|
2023-09-24 03:38:03 +02:00
|
|
|
if (Section == LC_LIGHT_SECTION_POSITION)
|
|
|
|
return mWorldMatrix.GetTranslation();
|
2014-05-01 16:55:12 +02:00
|
|
|
|
2023-09-24 03:38:03 +02:00
|
|
|
if (Section == LC_LIGHT_SECTION_TARGET)
|
|
|
|
return lcMul31(lcVector3(0.0f, 0.0f, -mTargetDistance), mWorldMatrix);
|
|
|
|
|
|
|
|
return lcVector3(0.0f, 0.0f, 0.0f);
|
2023-09-05 05:53:34 +02:00
|
|
|
}
|
2023-08-27 04:43:08 +02:00
|
|
|
|
2023-09-05 05:53:34 +02:00
|
|
|
void SetPosition(const lcVector3& Position, lcStep Step, bool AddKey)
|
|
|
|
{
|
2023-12-28 19:27:00 +01:00
|
|
|
mPosition.ChangeKey(Position, Step, AddKey);
|
2023-09-05 05:53:34 +02:00
|
|
|
}
|
2014-05-01 16:55:12 +02:00
|
|
|
|
2023-09-05 05:53:34 +02:00
|
|
|
void SetRotation(const lcMatrix33& Rotation, lcStep Step, bool AddKey)
|
|
|
|
{
|
2023-12-28 19:27:00 +01:00
|
|
|
mRotation.ChangeKey(Rotation, Step, AddKey);
|
2014-05-01 16:55:12 +02:00
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2023-09-04 19:59:16 +02:00
|
|
|
lcVector3 GetRotationCenter() const
|
|
|
|
{
|
2023-09-24 03:38:03 +02:00
|
|
|
const quint32 Section = GetFocusSection();
|
|
|
|
|
|
|
|
if (Section == LC_LIGHT_SECTION_POSITION || Section == LC_LIGHT_SECTION_INVALID)
|
|
|
|
{
|
|
|
|
return mWorldMatrix.GetTranslation();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return lcMul31(lcVector3(0.0f, 0.0f, -mTargetDistance), mWorldMatrix);
|
|
|
|
}
|
2023-09-05 05:53:34 +02:00
|
|
|
}
|
2023-09-04 19:59:16 +02:00
|
|
|
|
2023-09-05 05:53:34 +02:00
|
|
|
lcVector3 GetPosition() const
|
|
|
|
{
|
|
|
|
return mWorldMatrix.GetTranslation();
|
|
|
|
}
|
2023-09-04 19:59:16 +02:00
|
|
|
|
2023-09-05 05:53:34 +02:00
|
|
|
lcVector3 GetDirection() const
|
|
|
|
{
|
|
|
|
return -lcVector3(mWorldMatrix[2]);
|
2023-09-04 19:59:16 +02:00
|
|
|
}
|
|
|
|
|
2023-10-23 03:48:08 +02:00
|
|
|
const lcMatrix44& GetWorldMatrix() const
|
|
|
|
{
|
|
|
|
return mWorldMatrix;
|
|
|
|
}
|
|
|
|
|
2014-09-05 02:24:28 +02:00
|
|
|
void SaveLDraw(QTextStream& Stream) const;
|
2023-08-07 11:31:33 +02:00
|
|
|
bool ParseLDrawLine(QTextStream& Stream);
|
2014-08-30 01:52:42 +02:00
|
|
|
|
2011-09-07 23:06:51 +02:00
|
|
|
public:
|
2020-03-22 23:44:41 +01:00
|
|
|
void RayTest(lcObjectRayTest& ObjectRayTest) const override;
|
|
|
|
void BoxTest(lcObjectBoxTest& ObjectBoxTest) const override;
|
|
|
|
void DrawInterface(lcContext* Context, const lcScene& Scene) const override;
|
2024-01-15 02:41:01 +01:00
|
|
|
bool HasKeyFrame(lcObjectPropertyId PropertyId, lcStep Time) const override;
|
2020-03-22 23:44:41 +01:00
|
|
|
void RemoveKeyFrames() override;
|
2014-05-01 16:55:12 +02:00
|
|
|
|
2014-08-31 02:53:12 +02:00
|
|
|
void InsertTime(lcStep Start, lcStep Time);
|
|
|
|
void RemoveTime(lcStep Start, lcStep Time);
|
|
|
|
|
2014-05-01 16:55:12 +02:00
|
|
|
bool IsVisible() const
|
2023-08-27 20:17:07 +02:00
|
|
|
{
|
|
|
|
return (mState & LC_LIGHT_HIDDEN) == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SetColor(const lcVector3& Color, lcStep Step, bool AddKey);
|
|
|
|
|
|
|
|
lcVector3 GetColor() const
|
|
|
|
{
|
|
|
|
return mColor;
|
|
|
|
}
|
2014-05-01 16:55:12 +02:00
|
|
|
|
2023-12-17 20:37:11 +01:00
|
|
|
void SetAttenuationDistance(float Distance, lcStep Step, bool AddKey);
|
|
|
|
|
|
|
|
float GetAttenuationDistance() const
|
|
|
|
{
|
|
|
|
return mAttenuationDistance;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SetAttenuationPower(float Power, lcStep Step, bool AddKey);
|
|
|
|
|
|
|
|
float GetAttenuationPower() const
|
|
|
|
{
|
|
|
|
return mAttenuationPower;
|
|
|
|
}
|
|
|
|
|
2023-09-10 03:25:34 +02:00
|
|
|
void SetSpotConeAngle(float Angle, lcStep Step, bool AddKey);
|
|
|
|
|
|
|
|
float GetSpotConeAngle() const
|
|
|
|
{
|
|
|
|
return mSpotConeAngle;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SetSpotPenumbraAngle(float Angle, lcStep Step, bool AddKey);
|
|
|
|
|
|
|
|
float GetSpotPenumbraAngle() const
|
|
|
|
{
|
|
|
|
return mSpotPenumbraAngle;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SetSpotTightness(float Angle, lcStep Step, bool AddKey);
|
|
|
|
|
|
|
|
float GetSpotTightness() const
|
|
|
|
{
|
|
|
|
return mSpotTightness;
|
|
|
|
}
|
|
|
|
|
2023-09-17 19:40:23 +02:00
|
|
|
bool SetAreaShape(lcLightAreaShape LightAreaShape);
|
|
|
|
|
|
|
|
lcLightAreaShape GetAreaShape() const
|
|
|
|
{
|
|
|
|
return mAreaShape;
|
|
|
|
}
|
|
|
|
|
2023-11-20 03:05:43 +01:00
|
|
|
bool SetAreaGrid(lcVector2i AreaGrid, lcStep Step, bool AddKey);
|
|
|
|
|
|
|
|
lcVector2i GetAreaGrid() const
|
|
|
|
{
|
|
|
|
return mAreaGrid;
|
|
|
|
}
|
|
|
|
|
2023-09-17 20:45:14 +02:00
|
|
|
void SetSize(lcVector2 Size, lcStep Step, bool AddKey);
|
2023-09-17 19:40:23 +02:00
|
|
|
|
2023-09-17 20:45:14 +02:00
|
|
|
lcVector2 GetSize() const
|
2023-09-17 19:40:23 +02:00
|
|
|
{
|
2023-09-17 20:45:14 +02:00
|
|
|
return mSize;
|
2023-09-17 19:40:23 +02:00
|
|
|
}
|
|
|
|
|
2023-10-01 22:16:26 +02:00
|
|
|
void SetPower(float Power, lcStep Step, bool AddKey);
|
|
|
|
|
|
|
|
float GetPower() const
|
|
|
|
{
|
|
|
|
return mPower;
|
|
|
|
}
|
|
|
|
|
2023-09-17 19:40:23 +02:00
|
|
|
bool SetCastShadow(bool CastShadow);
|
2023-09-02 19:40:52 +02:00
|
|
|
|
|
|
|
bool GetCastShadow() const
|
|
|
|
{
|
|
|
|
return mCastShadow;
|
|
|
|
}
|
|
|
|
|
2023-08-07 11:31:33 +02:00
|
|
|
void SetName(const QString& Name)
|
|
|
|
{
|
|
|
|
mName = Name;
|
|
|
|
}
|
|
|
|
|
2020-12-14 01:27:21 +01:00
|
|
|
QString GetName() const override
|
|
|
|
{
|
|
|
|
return mName;
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2016-02-19 18:53:54 +01:00
|
|
|
void CompareBoundingBox(lcVector3& Min, lcVector3& Max);
|
2014-07-06 08:04:09 +02:00
|
|
|
void UpdatePosition(lcStep Step);
|
2023-09-24 03:38:03 +02:00
|
|
|
void MoveSelected(lcStep Step, bool AddKey, const lcVector3& Distance, bool FirstMove);
|
2023-09-05 05:53:34 +02:00
|
|
|
void Rotate(lcStep Step, bool AddKey, const lcMatrix33& RotationMatrix, const lcVector3& Center, const lcMatrix33& RotationFrame);
|
2014-08-07 17:22:33 +02:00
|
|
|
void CreateName(const lcArray<lcLight*>& Lights);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
|
|
|
protected:
|
2023-09-17 20:45:14 +02:00
|
|
|
void UpdateLightType();
|
|
|
|
|
2023-09-02 19:40:52 +02:00
|
|
|
void DrawPointLight(lcContext* Context) const;
|
|
|
|
void DrawSpotLight(lcContext* Context) const;
|
|
|
|
void DrawDirectionalLight(lcContext* Context) const;
|
|
|
|
void DrawAreaLight(lcContext* Context) const;
|
|
|
|
|
2023-09-05 05:53:34 +02:00
|
|
|
void SetupLightMatrix(lcContext* Context) const;
|
2023-09-24 03:38:03 +02:00
|
|
|
void DrawSphere(lcContext* Context, const lcVector3& Center, float Radius) const;
|
2023-09-02 19:40:52 +02:00
|
|
|
void DrawCylinder(lcContext* Context, float Radius, float Height) const;
|
2023-09-24 03:38:03 +02:00
|
|
|
void DrawTarget(lcContext* Context) const;
|
2023-09-02 19:40:52 +02:00
|
|
|
void DrawCone(lcContext* Context, float TargetDistance) const;
|
|
|
|
|
2023-09-17 20:45:14 +02:00
|
|
|
QString mName;
|
2023-09-17 19:40:23 +02:00
|
|
|
lcLightType mLightType = lcLightType::Point;
|
2023-09-02 19:40:52 +02:00
|
|
|
bool mCastShadow = true;
|
2023-12-28 19:21:52 +01:00
|
|
|
lcObjectProperty<lcVector3> mPosition = lcObjectProperty<lcVector3>(lcVector3(0.0f, 0.0f, 0.0f));
|
|
|
|
lcObjectProperty<lcMatrix33> mRotation = lcObjectProperty<lcMatrix33>(lcMatrix33Identity());
|
|
|
|
lcObjectProperty<lcVector3> mColor = lcObjectProperty<lcVector3>(lcVector3(1.0f, 1.0f, 1.0f));
|
|
|
|
lcObjectProperty<lcVector2> mSize = lcObjectProperty<lcVector2>(lcVector2(0.0f, 0.0f));
|
|
|
|
lcObjectProperty<float> mPower = lcObjectProperty<float>(1.0f);
|
|
|
|
lcObjectProperty<float> mAttenuationDistance = lcObjectProperty<float>(0.0f);
|
|
|
|
lcObjectProperty<float> mAttenuationPower = lcObjectProperty<float>(0.0f);
|
|
|
|
lcObjectProperty<float> mSpotConeAngle = lcObjectProperty<float>(80.0f);
|
|
|
|
lcObjectProperty<float> mSpotPenumbraAngle = lcObjectProperty<float>(0.0f);
|
|
|
|
lcObjectProperty<float> mSpotTightness = lcObjectProperty<float>(0.0f);
|
|
|
|
lcObjectProperty<lcVector2i> mAreaGrid = lcObjectProperty<lcVector2i>(lcVector2i(2, 2));
|
2023-09-17 19:40:23 +02:00
|
|
|
lcLightAreaShape mAreaShape = lcLightAreaShape::Rectangle;
|
2023-08-27 20:17:07 +02:00
|
|
|
|
2023-09-24 03:38:03 +02:00
|
|
|
quint32 mState = 0;
|
|
|
|
bool mSelected = false;
|
|
|
|
quint32 mFocusedSection = LC_LIGHT_SECTION_INVALID;
|
|
|
|
lcVector3 mTargetMovePosition = lcVector3(0.0f, 0.0f, 0.0f);
|
2023-12-27 21:03:41 +01:00
|
|
|
lcMatrix44 mWorldMatrix;
|
2023-08-27 04:43:08 +02:00
|
|
|
|
2023-09-24 03:38:03 +02:00
|
|
|
static constexpr float mTargetDistance = 50.0f;
|
2011-09-07 23:06:51 +02:00
|
|
|
};
|