leocad/common/light.h

381 lines
8.2 KiB
C
Raw Normal View History

#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
#define LC_LIGHT_HIDDEN 0x0001
#define LC_LIGHT_DISABLED 0x0002
enum lcLightSection : quint32
{
LC_LIGHT_SECTION_INVALID = ~0U,
LC_LIGHT_SECTION_POSITION = 0,
LC_LIGHT_SECTION_TARGET
};
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
};
enum class lcLightAreaShape
2023-08-07 11:31:33 +02:00
{
Rectangle,
Square,
Disk,
Ellipse,
Count
2023-08-07 11:31:33 +02:00
};
enum lcLightProperty
{
2023-08-07 13:22:59 +02:00
LC_LIGHT_DIFFUSE,
2023-08-07 11:31:33 +02:00
LC_LIGHT_SPECULAR,
LC_LIGHT_EXPONENT,
2023-08-07 13:22:59 +02:00
LC_LIGHT_AREA_GRID,
2023-08-07 11:31:33 +02:00
LC_LIGHT_CUTOFF,
2023-08-07 13:22:59 +02:00
LC_LIGHT_USE_CUTOFF,
LC_LIGHT_POVRAY
2023-08-07 11:31:33 +02:00
};
struct lcLightProperties
{
2023-08-07 13:22:59 +02:00
lcVector2 mAreaGrid;
float mLightDiffuse;
2023-08-07 11:31:33 +02:00
float mLightSpecular;
float mSpotExponent;
float mSpotCutoff;
bool mEnableCutoff;
2023-08-07 13:22:59 +02:00
bool mPOVRayLight;
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:
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;
static QString GetLightTypeString(lcLightType LightType);
static QString GetAreaShapeString(lcLightAreaShape LightAreaShape);
2023-09-02 05:46:29 +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;
}
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;
}
bool SetLightType(lcLightType LightType);
2023-09-02 05:46:29 +02:00
bool IsSelected() const override
{
return mSelected;
}
2011-09-07 23:06:51 +02:00
bool IsSelected(quint32 Section) const override
{
Q_UNUSED(Section);
return mSelected;
}
2011-09-07 23:06:51 +02:00
void SetSelected(bool Selected) override
{
mSelected = Selected;
if (!Selected)
mFocusedSection = LC_LIGHT_SECTION_INVALID;
}
2011-09-07 23:06:51 +02:00
void SetSelected(quint32 Section, bool Selected) override
{
Q_UNUSED(Section);
mSelected = Selected;
if (!Selected)
mFocusedSection = LC_LIGHT_SECTION_INVALID;
}
bool IsFocused() const override
{
return mFocusedSection != LC_LIGHT_SECTION_INVALID;
}
bool IsFocused(quint32 Section) const override
{
return mFocusedSection == Section;
}
void SetFocused(quint32 Section, bool Focused) override
{
if (Focused)
{
mFocusedSection = Section;
mSelected = true;
}
else
mFocusedSection = LC_LIGHT_SECTION_INVALID;
}
quint32 GetFocusSection() const override
{
return mFocusedSection;
}
quint32 GetAllowedTransforms() const override
{
2023-09-04 19:59:16 +02:00
if (IsPointLight())
return LC_OBJECT_TRANSFORM_MOVE_XYZ;
const quint32 Section = GetFocusSection();
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;
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)
return lcMatrix33(mWorldMatrix);
2023-09-04 19:59:16 +02:00
else
return lcMatrix33Identity();
}
lcVector3 GetSectionPosition(quint32 Section) const override
{
if (Section == LC_LIGHT_SECTION_POSITION)
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);
}
2023-08-27 04:43:08 +02:00
void SetPosition(const lcVector3& Position, lcStep Step, bool AddKey)
{
mPositionKeys.ChangeKey(Position, Step, AddKey);
}
void SetRotation(const lcMatrix33& Rotation, lcStep Step, bool AddKey)
{
mRotationKeys.ChangeKey(Rotation, Step, AddKey);
}
2011-09-07 23:06:51 +02:00
2023-09-04 19:59:16 +02:00
lcVector3 GetRotationCenter() const
{
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-04 19:59:16 +02:00
lcVector3 GetPosition() const
{
return mWorldMatrix.GetTranslation();
}
2023-09-04 19:59:16 +02:00
lcVector3 GetDirection() const
{
return -lcVector3(mWorldMatrix[2]);
2023-09-04 19:59:16 +02:00
}
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:
void RayTest(lcObjectRayTest& ObjectRayTest) const override;
void BoxTest(lcObjectBoxTest& ObjectBoxTest) const override;
void DrawInterface(lcContext* Context, const lcScene& Scene) const override;
void RemoveKeyFrames() override;
2014-08-31 02:53:12 +02:00
void InsertTime(lcStep Start, lcStep Time);
void RemoveTime(lcStep Start, lcStep Time);
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;
}
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;
}
bool SetAreaShape(lcLightAreaShape LightAreaShape);
lcLightAreaShape GetAreaShape() const
{
return mAreaShape;
}
void SetSize(lcVector2 Size, lcStep Step, bool AddKey);
lcVector2 GetSize() const
{
return mSize;
}
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);
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);
bool Setup(int LightIndex);
2014-08-07 17:22:33 +02:00
void CreateName(const lcArray<lcLight*>& Lights);
2023-08-07 11:31:33 +02:00
void UpdateLight(lcStep Step, lcLightProperties Props, int Property);
2023-08-07 11:31:33 +02:00
lcLightProperties GetLightProperties() const
{
lcLightProperties props;
2023-08-07 13:22:59 +02:00
props.mLightDiffuse = mLightDiffuse;
2023-08-07 11:31:33 +02:00
props.mLightSpecular = mLightSpecular;
props.mSpotExponent = mSpotExponent;
props.mSpotCutoff = mSpotCutoff;
2023-08-07 13:22:59 +02:00
props.mPOVRayLight = mPOVRayLight;
2023-08-07 11:31:33 +02:00
props.mEnableCutoff = mEnableCutoff;
2023-08-07 13:22:59 +02:00
props.mAreaGrid = mAreaGrid;
2023-08-07 11:31:33 +02:00
return props;
}
2011-09-07 23:06:51 +02:00
lcMatrix44 mWorldMatrix;
2023-08-27 04:43:08 +02:00
2014-08-31 02:53:12 +02:00
lcVector3 mAttenuation;
2023-08-07 13:22:59 +02:00
lcVector2 mAreaGrid;
2023-09-02 19:40:52 +02:00
bool mSpotBlendSet;
bool mSpotCutoffSet;
bool mEnableCutoff;
bool mPOVRayLight;
2023-08-07 13:22:59 +02:00
float mLightDiffuse;
2023-08-07 11:31:33 +02:00
float mLightSpecular;
2012-08-17 01:50:40 +02:00
float mSpotCutoff;
float mSpotExponent;
2023-08-07 13:22:59 +02:00
float mPOVRayExponent;
2012-06-07 02:08:59 +02:00
2011-09-07 23:06:51 +02:00
protected:
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;
void SetupLightMatrix(lcContext* Context) const;
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;
void DrawTarget(lcContext* Context) const;
2023-09-02 19:40:52 +02:00
void DrawCone(lcContext* Context, float TargetDistance) const;
QString mName;
lcLightType mLightType = lcLightType::Point;
2023-09-02 19:40:52 +02:00
bool mCastShadow = true;
2023-09-10 03:25:34 +02:00
lcVector3 mColor = lcVector3(1.0f, 1.0f, 1.0f);
lcVector2 mSize = lcVector2(0.0f, 0.0f);
2023-09-10 03:25:34 +02:00
float mSpotConeAngle = 80.0f;
float mSpotPenumbraAngle = 0.0f;
float mSpotTightness = 0.0f;
lcLightAreaShape mAreaShape = lcLightAreaShape::Rectangle;
2023-08-27 20:17:07 +02:00
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<lcMatrix33> mRotationKeys;
2023-08-27 20:17:07 +02:00
lcObjectKeyArray<lcVector3> mColorKeys;
lcObjectKeyArray<lcVector2> mSizeKeys;
2023-09-10 03:25:34 +02:00
lcObjectKeyArray<float> mSpotConeAngleKeys;
lcObjectKeyArray<float> mSpotPenumbraAngleKeys;
lcObjectKeyArray<float> mSpotTightnessKeys;
2023-08-27 04:43:08 +02:00
lcObjectKeyArray<lcVector3> mAttenuationKeys;
2023-08-07 13:22:59 +02:00
lcObjectKeyArray<lcVector2> mAreaGridKeys;
2023-08-07 11:31:33 +02:00
lcObjectKeyArray<float> mLightSpecularKeys;
2023-08-07 13:22:59 +02:00
lcObjectKeyArray<float> mLightDiffuseKeys;
lcObjectKeyArray<float> mSpotCutoffKeys;
lcObjectKeyArray<float> mSpotExponentKeys;
static constexpr float mTargetDistance = 50.0f;
2011-09-07 23:06:51 +02:00
};