leocad/common/light.h

339 lines
7.8 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
#define LC_LIGHT_DIRECTIONAL 0x0004
#define LC_LIGHT_POSITION_SELECTED 0x0008
#define LC_LIGHT_POSITION_FOCUSED 0x0010
#define LC_LIGHT_TARGET_SELECTED 0x0020
#define LC_LIGHT_TARGET_FOCUSED 0x0040
#define LC_LIGHT_SELECTION_MASK (LC_LIGHT_POSITION_SELECTED | LC_LIGHT_TARGET_SELECTED)
#define LC_LIGHT_FOCUS_MASK (LC_LIGHT_POSITION_FOCUSED | LC_LIGHT_TARGET_FOCUSED)
enum lcLightSection
{
LC_LIGHT_SECTION_POSITION,
LC_LIGHT_SECTION_TARGET
};
2023-08-07 11:31:33 +02:00
enum lcLightType
{
LC_UNDEFINED_LIGHT,
LC_POINTLIGHT,
LC_AREALIGHT,
LC_SUNLIGHT,
LC_SPOTLIGHT
};
enum lcLightShape
{
LC_LIGHT_SHAPE_UNDEFINED = -1,
LC_LIGHT_SHAPE_SQUARE,
LC_LIGHT_SHAPE_DISK,
LC_LIGHT_SHAPE_RECTANGLE,
LC_LIGHT_SHAPE_ELLIPSE
};
enum lcLightProperty
{
LC_LIGHT_NONE,
LC_LIGHT_SHAPE,
LC_LIGHT_COLOR,
LC_LIGHT_TYPE,
LC_LIGHT_FACTOR,
2023-08-07 13:22:59 +02:00
LC_LIGHT_DIFFUSE,
2023-08-07 11:31:33 +02:00
LC_LIGHT_SPECULAR,
2023-08-07 13:22:59 +02:00
LC_LIGHT_SHADOWLESS,
2023-08-07 11:31:33 +02:00
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_SPOT_SIZE,
2023-08-07 13:22:59 +02:00
LC_LIGHT_SPOT_FALLOFF,
LC_LIGHT_SPOT_TIGHTNESS,
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
{
lcVector3 mLightColor;
lcVector2 mLightFactor;
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;
2023-08-07 13:22:59 +02:00
float mSpotFalloff;
float mSpotTightness;
2023-08-07 11:31:33 +02:00
float mSpotSize;
bool mEnableCutoff;
2023-08-07 13:22:59 +02:00
bool mShadowless;
bool mPOVRayLight;
2023-08-07 11:31:33 +02:00
int mLightShape;
};
2014-05-01 20:42:11 +02:00
class lcLight : public lcObject
2011-09-07 23:06:51 +02:00
{
public:
2014-05-01 20:42:11 +02:00
lcLight(float px, float py, float pz);
2023-08-07 11:31:33 +02:00
lcLight(float px, float py, float pz, float tx, float ty, float tz, int LightType);
~lcLight();
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;
bool IsPointLight() const
{
return (mState & LC_LIGHT_DIRECTIONAL) == 0;
2011-09-07 23:06:51 +02:00
}
bool IsDirectionalLight() const
{
return (mState & LC_LIGHT_DIRECTIONAL) != 0;
}
2011-09-07 23:06:51 +02:00
bool IsSelected() const override
{
return (mState & LC_LIGHT_SELECTION_MASK) != 0;
}
2011-09-07 23:06:51 +02:00
bool IsSelected(quint32 Section) const override
{
switch (Section)
{
case LC_LIGHT_SECTION_POSITION:
return (mState & LC_LIGHT_POSITION_SELECTED) != 0;
break;
case LC_LIGHT_SECTION_TARGET:
return (mState & LC_LIGHT_TARGET_SELECTED) != 0;
break;
}
return false;
}
2011-09-07 23:06:51 +02:00
void SetSelected(bool Selected) override
{
if (Selected)
{
if (IsPointLight())
mState |= LC_LIGHT_POSITION_SELECTED;
else
mState |= LC_LIGHT_SELECTION_MASK;
}
else
mState &= ~(LC_LIGHT_SELECTION_MASK | LC_LIGHT_FOCUS_MASK);
}
2011-09-07 23:06:51 +02:00
void SetSelected(quint32 Section, bool Selected) override
{
switch (Section)
{
case LC_LIGHT_SECTION_POSITION:
if (Selected)
mState |= LC_LIGHT_POSITION_SELECTED;
else
mState &= ~(LC_LIGHT_POSITION_SELECTED | LC_LIGHT_POSITION_FOCUSED);
break;
case LC_LIGHT_SECTION_TARGET:
if (Selected)
{
if (!IsPointLight())
mState |= LC_LIGHT_TARGET_SELECTED;
}
else
mState &= ~(LC_LIGHT_TARGET_SELECTED | LC_LIGHT_TARGET_FOCUSED);
break;
}
}
bool IsFocused() const override
{
return (mState & LC_LIGHT_FOCUS_MASK) != 0;
}
bool IsFocused(quint32 Section) const override
{
switch (Section)
{
case LC_LIGHT_SECTION_POSITION:
return (mState & LC_LIGHT_POSITION_FOCUSED) != 0;
break;
case LC_LIGHT_SECTION_TARGET:
return (mState & LC_LIGHT_TARGET_FOCUSED) != 0;
break;
}
return false;
}
void SetFocused(quint32 Section, bool Focused) override
{
switch (Section)
{
case LC_LIGHT_SECTION_POSITION:
if (Focused)
mState |= LC_LIGHT_POSITION_SELECTED | LC_LIGHT_POSITION_FOCUSED;
else
mState &= ~(LC_LIGHT_POSITION_SELECTED | LC_LIGHT_POSITION_FOCUSED);
break;
case LC_LIGHT_SECTION_TARGET:
if (Focused)
{
if (!IsPointLight())
mState |= LC_LIGHT_TARGET_SELECTED | LC_LIGHT_TARGET_FOCUSED;
}
else
mState &= ~(LC_LIGHT_TARGET_SELECTED | LC_LIGHT_TARGET_FOCUSED);
break;
}
}
quint32 GetFocusSection() const override
{
if (mState & LC_LIGHT_POSITION_FOCUSED)
return LC_LIGHT_SECTION_POSITION;
if (!IsPointLight() && (mState & LC_LIGHT_TARGET_FOCUSED))
return LC_LIGHT_SECTION_TARGET;
2017-12-13 07:17:14 +01:00
return ~0U;
}
quint32 GetAllowedTransforms() const override
{
return LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Y | LC_OBJECT_TRANSFORM_MOVE_Z;
}
lcVector3 GetSectionPosition(quint32 Section) const override
{
switch (Section)
{
case LC_LIGHT_SECTION_POSITION:
return mPosition;
case LC_LIGHT_SECTION_TARGET:
return mTargetPosition;
}
return lcVector3(0.0f, 0.0f, 0.0f);
}
2011-09-07 23:06:51 +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
{ return (mState & LC_LIGHT_HIDDEN) == 0; }
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 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);
lcLightProperties GetLightProperties() const
{
lcLightProperties props;
props.mLightColor = mLightColor;
props.mLightFactor = mLightFactor;
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.mSpotFalloff = mSpotFalloff;
props.mSpotTightness = mSpotTightness;
2023-08-07 11:31:33 +02:00
props.mSpotSize = mSpotSize;
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.mShadowless = mShadowless;
props.mAreaGrid = mAreaGrid;
2023-08-07 11:31:33 +02:00
props.mLightShape = mLightShape;
return props;
}
2011-09-07 23:06:51 +02:00
2012-08-17 01:50:40 +02:00
lcMatrix44 mWorldLight;
2012-06-07 02:08:59 +02:00
lcVector3 mPosition;
lcVector3 mTargetPosition;
2012-08-17 01:50:40 +02:00
lcVector4 mAmbientColor;
lcVector4 mDiffuseColor;
lcVector4 mSpecularColor;
2014-08-31 02:53:12 +02:00
lcVector3 mAttenuation;
2023-08-07 11:31:33 +02:00
lcVector3 mLightColor;
lcVector2 mLightFactor;
2023-08-07 13:22:59 +02:00
lcVector2 mAreaGrid;
lcVector2 mAreaSize;
2023-08-07 11:31:33 +02:00
bool mAngleSet;
bool mSpotBlendSet;
bool mSpotCutoffSet;
bool mHeightSet;
bool mEnableCutoff;
2023-08-07 13:22:59 +02:00
bool mPOVRayLight;
bool mShadowless;
2023-08-07 11:31:33 +02:00
int mLightType;
int mLightShape;
2023-08-07 13:22:59 +02:00
float mLightDiffuse;
2023-08-07 11:31:33 +02:00
float mLightSpecular;
float mSpotSize;
2012-08-17 01:50:40 +02:00
float mSpotCutoff;
2023-08-07 13:22:59 +02:00
float mSpotFalloff;
float mSpotTightness;
2012-08-17 01:50:40 +02:00
float mSpotExponent;
2023-08-07 13:22:59 +02:00
float mPOVRayExponent;
2023-08-07 11:31:33 +02:00
QString mName;
2012-06-07 02:08:59 +02:00
2011-09-07 23:06:51 +02:00
protected:
lcObjectKeyArray<lcVector3> mPositionKeys;
lcObjectKeyArray<lcVector3> mTargetPositionKeys;
lcObjectKeyArray<lcVector4> mAmbientColorKeys;
lcObjectKeyArray<lcVector4> mDiffuseColorKeys;
lcObjectKeyArray<lcVector4> mSpecularColorKeys;
lcObjectKeyArray<lcVector3> mAttenuationKeys;
2023-08-07 11:31:33 +02:00
lcObjectKeyArray<lcVector3> mLightColorKeys;
lcObjectKeyArray<lcVector2> mLightFactorKeys;
2023-08-07 13:22:59 +02:00
lcObjectKeyArray<lcVector2> mAreaGridKeys;
2023-08-07 11:31:33 +02:00
lcObjectKeyArray<int> mLightTypeKeys;
lcObjectKeyArray<int> mLightShapeKeys;
lcObjectKeyArray<float> mLightSpecularKeys;
2023-08-07 13:22:59 +02:00
lcObjectKeyArray<float> mLightDiffuseKeys;
lcObjectKeyArray<float> mSpotSizeKeys;
lcObjectKeyArray<float> mSpotCutoffKeys;
2023-08-07 13:22:59 +02:00
lcObjectKeyArray<float> mSpotFalloffKeys;
lcObjectKeyArray<float> mSpotExponentKeys;
2023-08-07 13:22:59 +02:00
lcObjectKeyArray<float> mSpotTightnessKeys;
2014-08-31 02:53:12 +02:00
2023-08-07 11:31:33 +02:00
void Initialize(const lcVector3& Position, const lcVector3& TargetPosition, int LightType);
2012-08-17 01:50:40 +02:00
2023-08-07 11:31:33 +02:00
void DrawDirectionalLight(lcContext* Context) const;
2015-05-17 01:04:35 +02:00
void DrawPointLight(lcContext* Context) const;
2023-08-07 11:31:33 +02:00
void SetLightState(int LightType);
2015-04-19 03:10:01 +02:00
2017-12-02 21:22:04 +01:00
quint32 mState;
2011-09-07 23:06:51 +02:00
};