Added lcObjectProperty class.

This commit is contained in:
Leonardo Zide 2023-12-27 12:03:41 -08:00
parent 2990afba08
commit eeabc06c49
5 changed files with 214 additions and 139 deletions

View file

@ -23,49 +23,40 @@ static const std::array<QLatin1String, static_cast<int>(lcLightAreaShape::Count)
lcLight::lcLight(const lcVector3& Position, lcLightType LightType) lcLight::lcLight(const lcVector3& Position, lcLightType LightType)
: lcObject(lcObjectType::Light), mLightType(LightType) : lcObject(lcObjectType::Light), mLightType(LightType)
{ {
mWorldMatrix = lcMatrix44Translation(Position); mPosition.Reset(Position);
UpdateLightType(); UpdateLightType();
mPositionKeys.ChangeKey(mWorldMatrix.GetTranslation(), 1, true);
mRotationKeys.ChangeKey(lcMatrix33(mWorldMatrix), 1, true);
mColorKeys.ChangeKey(mColor, 1, true);
mPowerKeys.ChangeKey(mPower, 1, true);
mAttenuationDistanceKeys.ChangeKey(mAttenuationDistance, 1, true);
mAttenuationPowerKeys.ChangeKey(mAttenuationPower, 1, true);
mSpotConeAngleKeys.ChangeKey(mSpotConeAngle, 1, true);
mSpotPenumbraAngleKeys.ChangeKey(mSpotPenumbraAngle, 1, true);
mSpotTightnessKeys.ChangeKey(mSpotTightness, 1, true);
mAreaGridKeys.ChangeKey(mAreaGrid, 1, true);
UpdatePosition(1); UpdatePosition(1);
} }
void lcLight::UpdateLightType() void lcLight::UpdateLightType()
{ {
lcVector2 Size;
switch (mLightType) switch (mLightType)
{ {
case lcLightType::Point: case lcLightType::Point:
mSize = lcVector2(0.0f, 0.0f); Size = lcVector2(0.0f, 0.0f);
break; break;
case lcLightType::Spot: case lcLightType::Spot:
mSize = lcVector2(0.0f, 0.0f); Size = lcVector2(0.0f, 0.0f);
break; break;
case lcLightType::Directional: case lcLightType::Directional:
mSize = lcVector2(0.00918f * LC_DTOR, 0.0f); Size = lcVector2(0.00918f * LC_DTOR, 0.0f);
break; break;
case lcLightType::Area: case lcLightType::Area:
mSize = lcVector2(200.0f, 200.0f); Size = lcVector2(200.0f, 200.0f);
break; break;
case lcLightType::Count: case lcLightType::Count:
break; break;
} }
mSizeKeys.Reset(mSize); mSize.Reset(Size);
} }
QString lcLight::GetLightTypeString(lcLightType LightType) QString lcLight::GetLightTypeString(lcLightType LightType)
@ -124,24 +115,24 @@ void lcLight::SaveLDraw(QTextStream& Stream) const
const float* Matrix = mWorldMatrix; const float* Matrix = mWorldMatrix;
const float Numbers[12] = { Matrix[12], -Matrix[14], Matrix[13], Matrix[0], -Matrix[8], Matrix[4], -Matrix[2], Matrix[10], -Matrix[6], Matrix[1], -Matrix[9], Matrix[5] }; const float Numbers[12] = { Matrix[12], -Matrix[14], Matrix[13], Matrix[0], -Matrix[8], Matrix[4], -Matrix[2], Matrix[10], -Matrix[6], Matrix[1], -Matrix[9], Matrix[5] };
if (mPositionKeys.GetSize() > 1) if (mPosition.GetSize() > 1)
mPositionKeys.SaveKeysLDraw(Stream, "LIGHT", "POSITION"); mPosition.SaveKeysLDraw(Stream, "LIGHT", "POSITION");
else else
Stream << QLatin1String("0 !LEOCAD LIGHT POSITION ") << Numbers[0] << ' ' << Numbers[1] << ' ' << Numbers[2] << LineEnding; Stream << QLatin1String("0 !LEOCAD LIGHT POSITION ") << Numbers[0] << ' ' << Numbers[1] << ' ' << Numbers[2] << LineEnding;
if (!IsPointLight()) if (!IsPointLight())
{ {
if (mRotationKeys.GetSize() > 1) if (mRotation.GetSize() > 1)
mRotationKeys.SaveKeysLDraw(Stream, "LIGHT", "ROTATION"); mRotation.SaveKeysLDraw(Stream, "LIGHT", "ROTATION");
else else
Stream << QLatin1String("0 !LEOCAD LIGHT ROTATION ") << Numbers[3] << ' ' << Numbers[4] << ' ' << Numbers[5] << ' ' << Numbers[6] << ' ' << Numbers[7] << ' ' << Numbers[8] << ' ' << Numbers[9] << ' ' << Numbers[10] << ' ' << Numbers[11] << LineEnding; Stream << QLatin1String("0 !LEOCAD LIGHT ROTATION ") << Numbers[3] << ' ' << Numbers[4] << ' ' << Numbers[5] << ' ' << Numbers[6] << ' ' << Numbers[7] << ' ' << Numbers[8] << ' ' << Numbers[9] << ' ' << Numbers[10] << ' ' << Numbers[11] << LineEnding;
} }
SaveAttribute(Stream, mColor, mColorKeys, "LIGHT", "COLOR"); mColor.Save(Stream, "LIGHT", "COLOR");
SaveAttribute(Stream, mSize, mSizeKeys, "LIGHT", "SIZE"); mSize.Save(Stream, "LIGHT", "SIZE");
SaveAttribute(Stream, mPower, mPowerKeys, "LIGHT", "POWER"); mPower.Save(Stream, "LIGHT", "POWER");
SaveAttribute(Stream, mAttenuationDistance, mAttenuationDistanceKeys, "LIGHT", "ATTENUATION_DISTANCE"); mAttenuationDistance.Save(Stream, "LIGHT", "ATTENUATION_DISTANCE");
SaveAttribute(Stream, mAttenuationPower, mAttenuationPowerKeys, "LIGHT", "ATTENUATION_POWER"); mAttenuationPower.Save(Stream, "LIGHT", "ATTENUATION_POWER");
switch (mLightType) switch (mLightType)
{ {
@ -150,9 +141,9 @@ void lcLight::SaveLDraw(QTextStream& Stream) const
break; break;
case lcLightType::Spot: case lcLightType::Spot:
SaveAttribute(Stream, mSpotConeAngle, mSpotConeAngleKeys, "LIGHT", "SPOT_CONE_ANGLE"); mSpotConeAngle.Save(Stream, "LIGHT", "SPOT_CONE_ANGLE");
SaveAttribute(Stream, mSpotPenumbraAngle, mSpotPenumbraAngleKeys, "LIGHT", "SPOT_PENUMBRA_ANGLE"); mSpotPenumbraAngle.Save(Stream, "LIGHT", "SPOT_PENUMBRA_ANGLE");
SaveAttribute(Stream, mSpotTightness, mSpotTightnessKeys, "LIGHT", "SPOT_TIGHTNESS"); mSpotTightness.Save(Stream, "LIGHT", "SPOT_TIGHTNESS");
break; break;
case lcLightType::Directional: case lcLightType::Directional:
@ -160,7 +151,7 @@ void lcLight::SaveLDraw(QTextStream& Stream) const
case lcLightType::Area: case lcLightType::Area:
Stream << QLatin1String("0 !LEOCAD LIGHT AREA_SHAPE ") << gLightAreaShapes[static_cast<int>(mAreaShape)] << LineEnding; Stream << QLatin1String("0 !LEOCAD LIGHT AREA_SHAPE ") << gLightAreaShapes[static_cast<int>(mAreaShape)] << LineEnding;
SaveAttribute(Stream, mAreaGrid, mAreaGridKeys, "LIGHT", "AREA_GRID"); mAreaGrid.Save(Stream, "LIGHT", "AREA_GRID");
break; break;
} }
@ -243,10 +234,10 @@ bool lcLight::ParseLDrawLine(QTextStream& Stream)
Position = lcVector3LDrawToLeoCAD(Position); Position = lcVector3LDrawToLeoCAD(Position);
mWorldMatrix.SetTranslation(Position); mWorldMatrix.SetTranslation(Position);
mPositionKeys.ChangeKey(Position, 1, true); mPosition.ChangeKey(Position, 1, true);
} }
else if (Token == QLatin1String("POSITION_KEY")) else if (Token == QLatin1String("POSITION_KEY"))
mPositionKeys.LoadKeysLDraw(Stream); // todo: convert from ldraw mPosition.LoadKeysLDraw(Stream); // todo: convert from ldraw
else if (Token == QLatin1String("ROTATION")) else if (Token == QLatin1String("ROTATION"))
{ {
float Numbers[9]; float Numbers[9];
@ -266,25 +257,27 @@ bool lcLight::ParseLDrawLine(QTextStream& Stream)
Matrix[9] = -Numbers[7]; Matrix[9] = -Numbers[7];
Matrix[5] = Numbers[8]; Matrix[5] = Numbers[8];
mRotationKeys.ChangeKey(lcMatrix33(mWorldMatrix), 1, true); mRotation.ChangeKey(lcMatrix33(mWorldMatrix), 1, true);
} }
else if (Token == QLatin1String("ROTATION_KEY")) else if (Token == QLatin1String("ROTATION_KEY"))
mRotationKeys.LoadKeysLDraw(Stream); // todo: convert from ldraw mRotation.LoadKeysLDraw(Stream); // todo: convert from ldraw
else if (LoadAttribute(Stream, Token, mColor, mColorKeys, "COLOR")) else if (mColor.Load(Stream, Token, "COLOR"))
continue; continue;
else if (LoadAttribute(Stream, Token, mSize, mSizeKeys, "SIZE")) else if (mSize.Load(Stream, Token, "SIZE"))
continue; continue;
else if (LoadAttribute(Stream, Token, mPower, mPowerKeys, "POWER")) else if (mPower.Load(Stream, Token, "POWER"))
continue; continue;
else if (LoadAttribute(Stream, Token, mAttenuationDistance, mAttenuationDistanceKeys, "ATTENUATION_DISTANCE")) else if (mAttenuationDistance.Load(Stream, Token, "ATTENUATION_DISTANCE"))
continue; continue;
else if (LoadAttribute(Stream, Token, mAttenuationPower, mAttenuationPowerKeys, "ATTENUATION_POWER")) else if (mAttenuationPower.Load(Stream, Token, "ATTENUATION_POWER"))
continue; continue;
else if (LoadAttribute(Stream, Token, mSpotConeAngle, mSpotConeAngleKeys, "SPOT_CONE_ANGLE")) else if (mSpotConeAngle.Load(Stream, Token, "SPOT_CONE_ANGLE"))
continue; continue;
else if (LoadAttribute(Stream, Token, mSpotPenumbraAngle, mSpotPenumbraAngleKeys, "SPOT_PENUMBRA_ANGLE")) else if (mSpotPenumbraAngle.Load(Stream, Token, "SPOT_PENUMBRA_ANGLE"))
continue; continue;
else if (LoadAttribute(Stream, Token, mSpotTightness, mSpotTightnessKeys, "SPOT_TIGHTNESS")) else if (mSpotTightness.Load(Stream, Token, "SPOT_TIGHTNESS"))
continue;
else if (mAreaGrid.Load(Stream, Token, "AREA_GRID"))
continue; continue;
else if (Token == QLatin1String("AREA_SHAPE")) else if (Token == QLatin1String("AREA_SHAPE"))
{ {
@ -300,8 +293,6 @@ bool lcLight::ParseLDrawLine(QTextStream& Stream)
} }
} }
} }
else if (LoadAttribute(Stream, Token, mAreaGrid, mAreaGridKeys, "AREA_GRID"))
continue;
else if (Token == QLatin1String("TYPE")) else if (Token == QLatin1String("TYPE"))
{ {
QString Type; QString Type;
@ -386,8 +377,9 @@ void lcLight::RayTest(lcObjectRayTest& ObjectRayTest) const
float x = lcDot(IntersectionDirection, XAxis); float x = lcDot(IntersectionDirection, XAxis);
float y = lcDot(IntersectionDirection, YAxis); float y = lcDot(IntersectionDirection, YAxis);
const lcVector2& Size = mSize;
if (fabsf(x) < mSize.x / 2.0f && fabsf(y) < mSize.y / 2.0f) if (fabsf(x) < Size.x / 2.0f && fabsf(y) < Size.y / 2.0f)
{ {
float Distance = lcLength(Intersection - ObjectRayTest.Start); float Distance = lcLength(Intersection - ObjectRayTest.Start);
@ -536,32 +528,32 @@ bool lcLight::SetLightType(lcLightType LightType)
void lcLight::SetColor(const lcVector3& Color, lcStep Step, bool AddKey) void lcLight::SetColor(const lcVector3& Color, lcStep Step, bool AddKey)
{ {
mColorKeys.ChangeKey(Color, Step, AddKey); mColor.SetValue(Color, Step, AddKey);
} }
void lcLight::SetAttenuationDistance(float Distance, lcStep Step, bool AddKey) void lcLight::SetAttenuationDistance(float Distance, lcStep Step, bool AddKey)
{ {
mAttenuationDistanceKeys.ChangeKey(Distance, Step, AddKey); mAttenuationDistance.SetValue(Distance, Step, AddKey);
} }
void lcLight::SetAttenuationPower(float Power, lcStep Step, bool AddKey) void lcLight::SetAttenuationPower(float Power, lcStep Step, bool AddKey)
{ {
mAttenuationPowerKeys.ChangeKey(Power, Step, AddKey); mAttenuationPower.SetValue(Power, Step, AddKey);
} }
void lcLight::SetSpotConeAngle(float Angle, lcStep Step, bool AddKey) void lcLight::SetSpotConeAngle(float Angle, lcStep Step, bool AddKey)
{ {
mSpotConeAngleKeys.ChangeKey(Angle, Step, AddKey); mSpotConeAngle.SetValue(Angle, Step, AddKey);
} }
void lcLight::SetSpotPenumbraAngle(float Angle, lcStep Step, bool AddKey) void lcLight::SetSpotPenumbraAngle(float Angle, lcStep Step, bool AddKey)
{ {
mSpotPenumbraAngleKeys.ChangeKey(Angle, Step, AddKey); mSpotPenumbraAngle.SetValue(Angle, Step, AddKey);
} }
void lcLight::SetSpotTightness(float Tightness, lcStep Step, bool AddKey) void lcLight::SetSpotTightness(float Tightness, lcStep Step, bool AddKey)
{ {
mSpotTightnessKeys.ChangeKey(Tightness, Step, AddKey); mSpotTightness.SetValue(Tightness, Step, AddKey);
} }
bool lcLight::SetAreaShape(lcLightAreaShape AreaShape) bool lcLight::SetAreaShape(lcLightAreaShape AreaShape)
@ -580,7 +572,7 @@ bool lcLight::SetAreaShape(lcLightAreaShape AreaShape)
bool lcLight::SetAreaGrid(lcVector2i AreaGrid, lcStep Step, bool AddKey) bool lcLight::SetAreaGrid(lcVector2i AreaGrid, lcStep Step, bool AddKey)
{ {
mAreaGridKeys.ChangeKey(AreaGrid, Step, AddKey); mAreaGrid.SetValue(AreaGrid, Step, AddKey);
return true; return true;
} }
@ -590,12 +582,12 @@ void lcLight::SetSize(lcVector2 Size, lcStep Step, bool AddKey)
if (mLightType == lcLightType::Area && (mAreaShape == lcLightAreaShape::Square || mAreaShape == lcLightAreaShape::Disk)) if (mLightType == lcLightType::Area && (mAreaShape == lcLightAreaShape::Square || mAreaShape == lcLightAreaShape::Disk))
Size[1] = Size[0]; Size[1] = Size[0];
mSizeKeys.ChangeKey(Size, Step, AddKey); mSize.SetValue(Size, Step, AddKey);
} }
void lcLight::SetPower(float Power, lcStep Step, bool AddKey) void lcLight::SetPower(float Power, lcStep Step, bool AddKey)
{ {
mPowerKeys.ChangeKey(Power, Step, AddKey); mPower.SetValue(Power, Step, AddKey);
} }
bool lcLight::SetCastShadow(bool CastShadow) bool lcLight::SetCastShadow(bool CastShadow)
@ -611,58 +603,56 @@ bool lcLight::SetCastShadow(bool CastShadow)
void lcLight::InsertTime(lcStep Start, lcStep Time) void lcLight::InsertTime(lcStep Start, lcStep Time)
{ {
mPositionKeys.InsertTime(Start, Time); mPosition.InsertTime(Start, Time);
mRotationKeys.InsertTime(Start, Time); mRotation.InsertTime(Start, Time);
mColorKeys.InsertTime(Start, Time); mColor.InsertTime(Start, Time);
mSpotConeAngleKeys.InsertTime(Start, Time); mSpotConeAngle.InsertTime(Start, Time);
mSpotPenumbraAngleKeys.InsertTime(Start, Time); mSpotPenumbraAngle.InsertTime(Start, Time);
mSpotTightnessKeys.InsertTime(Start, Time); mSpotTightness.InsertTime(Start, Time);
mAreaGridKeys.InsertTime(Start, Time); mAreaGrid.InsertTime(Start, Time);
mSizeKeys.InsertTime(Start, Time); mSize.InsertTime(Start, Time);
mPowerKeys.InsertTime(Start, Time); mPower.InsertTime(Start, Time);
mAttenuationDistanceKeys.InsertTime(Start, Time); mAttenuationDistance.InsertTime(Start, Time);
mAttenuationPowerKeys.InsertTime(Start, Time); mAttenuationPower.InsertTime(Start, Time);
} }
void lcLight::RemoveTime(lcStep Start, lcStep Time) void lcLight::RemoveTime(lcStep Start, lcStep Time)
{ {
mPositionKeys.RemoveTime(Start, Time); mPosition.RemoveTime(Start, Time);
mRotationKeys.RemoveTime(Start, Time); mRotation.RemoveTime(Start, Time);
mColorKeys.RemoveTime(Start, Time); mColor.RemoveTime(Start, Time);
mSpotConeAngleKeys.RemoveTime(Start, Time); mSpotConeAngle.RemoveTime(Start, Time);
mSpotPenumbraAngleKeys.RemoveTime(Start, Time); mSpotPenumbraAngle.RemoveTime(Start, Time);
mSpotTightnessKeys.RemoveTime(Start, Time); mSpotTightness.RemoveTime(Start, Time);
mAreaGridKeys.RemoveTime(Start, Time); mAreaGrid.RemoveTime(Start, Time);
mSizeKeys.RemoveTime(Start, Time); mSize.RemoveTime(Start, Time);
mPowerKeys.RemoveTime(Start, Time); mPower.RemoveTime(Start, Time);
mAttenuationDistanceKeys.RemoveTime(Start, Time); mAttenuationDistance.RemoveTime(Start, Time);
mAttenuationPowerKeys.RemoveTime(Start, Time); mAttenuationPower.RemoveTime(Start, Time);
} }
void lcLight::UpdatePosition(lcStep Step) void lcLight::UpdatePosition(lcStep Step)
{ {
const lcVector3 Position = mPositionKeys.CalculateKey(Step); mPosition.Update(Step);
mRotation.Update(Step);
mColor.Update(Step);
mSpotConeAngle.Update(Step);
mSpotPenumbraAngle.Update(Step);
mSpotTightness.Update(Step);
mAreaGrid.Update(Step);
mSize.Update(Step);
mPower.Update(Step);
mAttenuationDistance.Update(Step);
mAttenuationPower.Update(Step);
if (IsPointLight()) if (IsPointLight())
{ {
mWorldMatrix = lcMatrix44Translation(Position); mWorldMatrix = lcMatrix44Translation(mPosition);
} }
else else
{ {
const lcMatrix33 Rotation = mRotationKeys.CalculateKey(Step); mWorldMatrix = lcMatrix44(mRotation, mPosition);
mWorldMatrix = lcMatrix44(Rotation, Position);
} }
mColor = mColorKeys.CalculateKey(Step);
mSpotConeAngle = mSpotConeAngleKeys.CalculateKey(Step);
mSpotPenumbraAngle = mSpotPenumbraAngleKeys.CalculateKey(Step);
mSpotTightness = mSpotTightnessKeys.CalculateKey(Step);
mAreaGrid = mAreaGridKeys.CalculateKey(Step);
mSize = mSizeKeys.CalculateKey(Step);
mPower = mPowerKeys.CalculateKey(Step);
mAttenuationDistance = mAttenuationDistanceKeys.CalculateKey(Step);
mAttenuationPower = mAttenuationPowerKeys.CalculateKey(Step);
} }
void lcLight::DrawInterface(lcContext* Context, const lcScene& Scene) const void lcLight::DrawInterface(lcContext* Context, const lcScene& Scene) const
@ -760,21 +750,22 @@ void lcLight::DrawAreaLight(lcContext* Context) const
{ {
float Verts[4 * 3]; float Verts[4 * 3];
float* CurVert = Verts; float* CurVert = Verts;
const lcVector2& Size = mSize;
*CurVert++ = -mSize.x / 2.0f; *CurVert++ = -Size.x / 2.0f;
*CurVert++ = -mSize.y / 2.0f; *CurVert++ = -Size.y / 2.0f;
*CurVert++ = 0.0f; *CurVert++ = 0.0f;
*CurVert++ = mSize.x / 2.0f; *CurVert++ = Size.x / 2.0f;
*CurVert++ = -mSize.y / 2.0f; *CurVert++ = -Size.y / 2.0f;
*CurVert++ = 0.0f; *CurVert++ = 0.0f;
*CurVert++ = mSize.x / 2.0f; *CurVert++ = Size.x / 2.0f;
*CurVert++ = mSize.y / 2.0f; *CurVert++ = Size.y / 2.0f;
*CurVert++ = 0.0f; *CurVert++ = 0.0f;
*CurVert++ = -mSize.x / 2.0f; *CurVert++ = -Size.x / 2.0f;
*CurVert++ = mSize.y / 2.0f; *CurVert++ = Size.y / 2.0f;
*CurVert++ = 0.0f; *CurVert++ = 0.0f;
Context->SetVertexBufferPointer(Verts); Context->SetVertexBufferPointer(Verts);
@ -799,8 +790,9 @@ void lcLight::DrawAreaLight(lcContext* Context) const
for (int EdgeIndex = 0; EdgeIndex < CircleEdges; EdgeIndex++) for (int EdgeIndex = 0; EdgeIndex < CircleEdges; EdgeIndex++)
{ {
float c = cosf((float)EdgeIndex / CircleEdges * LC_2PI) * mSize.x / 2.0f; const lcVector2& Size = mSize;
float s = sinf((float)EdgeIndex / CircleEdges * LC_2PI) * mSize.y / 2.0f; float c = cosf((float)EdgeIndex / CircleEdges * LC_2PI) * Size.x / 2.0f;
float s = sinf((float)EdgeIndex / CircleEdges * LC_2PI) * Size.y / 2.0f;
*CurVert++ = c; *CurVert++ = c;
*CurVert++ = s; *CurVert++ = s;
@ -1075,15 +1067,15 @@ void lcLight::DrawCone(lcContext* Context, float TargetDistance) const
void lcLight::RemoveKeyFrames() void lcLight::RemoveKeyFrames()
{ {
mPositionKeys.Reset(mWorldMatrix.GetTranslation()); mPosition.Reset();
mRotationKeys.Reset(lcMatrix33(mWorldMatrix)); mRotation.Reset();
mColorKeys.Reset(mColor); mColor.Reset();
mSpotConeAngleKeys.Reset(mSpotConeAngle); mSpotConeAngle.Reset();
mSpotPenumbraAngleKeys.Reset(mSpotPenumbraAngle); mSpotPenumbraAngle.Reset();
mSpotTightnessKeys.Reset(mSpotTightness); mSpotTightness.Reset();
mAreaGridKeys.Reset(mAreaGrid); mAreaGrid.Reset();
mSizeKeys.Reset(mSize); mSize.Reset();
mPowerKeys.Reset(mPower); mPower.Reset();
mAttenuationDistanceKeys.Reset(mAttenuationDistance); mAttenuationDistance.Reset();
mAttenuationPowerKeys.Reset(mAttenuationPower); mAttenuationPower.Reset();
} }

View file

@ -167,12 +167,12 @@ public:
void SetPosition(const lcVector3& Position, lcStep Step, bool AddKey) void SetPosition(const lcVector3& Position, lcStep Step, bool AddKey)
{ {
mPositionKeys.ChangeKey(Position, Step, AddKey); mPosition.SetValue(Position, Step, AddKey);
} }
void SetRotation(const lcMatrix33& Rotation, lcStep Step, bool AddKey) void SetRotation(const lcMatrix33& Rotation, lcStep Step, bool AddKey)
{ {
mRotationKeys.ChangeKey(Rotation, Step, AddKey); mRotation.SetValue(Rotation, Step, AddKey);
} }
lcVector3 GetRotationCenter() const lcVector3 GetRotationCenter() const
@ -314,8 +314,6 @@ public:
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);
void CreateName(const lcArray<lcLight*>& Lights); void CreateName(const lcArray<lcLight*>& Lights);
lcMatrix44 mWorldMatrix;
protected: protected:
void UpdateLightType(); void UpdateLightType();
@ -333,33 +331,24 @@ protected:
QString mName; QString mName;
lcLightType mLightType = lcLightType::Point; lcLightType mLightType = lcLightType::Point;
bool mCastShadow = true; bool mCastShadow = true;
lcVector3 mColor = lcVector3(1.0f, 1.0f, 1.0f); lcObjectProperty<lcVector3> mPosition = lcVector3(0.0f, 0.0f, 0.0f);
lcVector2 mSize = lcVector2(0.0f, 0.0f); lcObjectProperty<lcMatrix33> mRotation = lcMatrix33Identity();
float mPower = 1.0f; lcObjectProperty<lcVector3> mColor = lcVector3(1.0f, 1.0f, 1.0f);
float mAttenuationDistance = 0.0f; lcObjectProperty<lcVector2> mSize = lcVector2(0.0f, 0.0f);
float mAttenuationPower = 0.0f; lcObjectProperty<float> mPower = 1.0f;
float mSpotConeAngle = 80.0f; lcObjectProperty<float> mAttenuationDistance = 0.0f;
float mSpotPenumbraAngle = 0.0f; lcObjectProperty<float> mAttenuationPower = 0.0f;
float mSpotTightness = 0.0f; lcObjectProperty<float> mSpotConeAngle = 80.0f;
lcObjectProperty<float> mSpotPenumbraAngle = 0.0f;
lcObjectProperty<float> mSpotTightness = 0.0f;
lcObjectProperty<lcVector2i> mAreaGrid = lcVector2i(2, 2);
lcLightAreaShape mAreaShape = lcLightAreaShape::Rectangle; lcLightAreaShape mAreaShape = lcLightAreaShape::Rectangle;
lcVector2i mAreaGrid = lcVector2i(2, 2);
quint32 mState = 0; quint32 mState = 0;
bool mSelected = false; bool mSelected = false;
quint32 mFocusedSection = LC_LIGHT_SECTION_INVALID; quint32 mFocusedSection = LC_LIGHT_SECTION_INVALID;
lcVector3 mTargetMovePosition = lcVector3(0.0f, 0.0f, 0.0f); lcVector3 mTargetMovePosition = lcVector3(0.0f, 0.0f, 0.0f);
lcMatrix44 mWorldMatrix;
lcObjectKeyArray<lcVector3> mPositionKeys;
lcObjectKeyArray<lcMatrix33> mRotationKeys;
lcObjectKeyArray<lcVector3> mColorKeys;
lcObjectKeyArray<lcVector2> mSizeKeys;
lcObjectKeyArray<float> mPowerKeys;
lcObjectKeyArray<float> mAttenuationDistanceKeys;
lcObjectKeyArray<float> mAttenuationPowerKeys;
lcObjectKeyArray<float> mSpotConeAngleKeys;
lcObjectKeyArray<float> mSpotPenumbraAngleKeys;
lcObjectKeyArray<float> mSpotTightnessKeys;
lcObjectKeyArray<lcVector2i> mAreaGridKeys;
static constexpr float mTargetDistance = 50.0f; static constexpr float mTargetDistance = 50.0f;
}; };

View file

@ -8,6 +8,8 @@
template void lcObjectKeyArray<T>::ChangeKey(const T& Value, lcStep Step, bool AddKey); \ template void lcObjectKeyArray<T>::ChangeKey(const T& Value, lcStep Step, bool AddKey); \
template void lcObjectKeyArray<T>::InsertTime(lcStep Start, lcStep Time); \ template void lcObjectKeyArray<T>::InsertTime(lcStep Start, lcStep Time); \
template void lcObjectKeyArray<T>::RemoveTime(lcStep Start, lcStep Time); \ template void lcObjectKeyArray<T>::RemoveTime(lcStep Start, lcStep Time); \
template void lcObjectProperty<T>::Save(QTextStream& Stream, const char* ObjectName, const char* VariableName) const; \
template bool lcObjectProperty<T>::Load(QTextStream& Stream, const QString& Token, const char* VariableName); \
template void lcObject::SaveAttribute<T>(QTextStream& Stream, const T& Variable, const lcObjectKeyArray<T>& Keys, const char* ObjectName, const char* VariableName) const; \ template void lcObject::SaveAttribute<T>(QTextStream& Stream, const T& Variable, const lcObjectKeyArray<T>& Keys, const char* ObjectName, const char* VariableName) const; \
template bool lcObject::LoadAttribute<T>(QTextStream& Stream, const QString& Token, T& Variable, lcObjectKeyArray<T>& Keys, const char* VariableName) template bool lcObject::LoadAttribute<T>(QTextStream& Stream, const QString& Token, T& Variable, lcObjectKeyArray<T>& Keys, const char* VariableName)
@ -191,6 +193,43 @@ void lcObjectKeyArray<T>::RemoveTime(lcStep Start, lcStep Time)
} }
} }
template<typename T>
void lcObjectProperty<T>::Save(QTextStream& Stream, const char* ObjectName, const char* VariableName) const
{
if (GetSize() == 1)
{
Stream << QLatin1String("0 !LEOCAD ") << ObjectName << ' ' << VariableName << ' ';
SaveValue(Stream, mValue);
Stream << QLatin1String("\r\n");
}
else
SaveKeysLDraw(Stream, ObjectName, VariableName);
}
template<typename T>
bool lcObjectProperty<T>::Load(QTextStream& Stream, const QString& Token, const char* VariableName)
{
if (Token == VariableName)
{
LoadValue(Stream, mValue);
ChangeKey(mValue, 1, true);
return true;
}
if (Token.endsWith(QLatin1String("_KEY")) && Token.leftRef(Token.size() - 4) == VariableName)
{
LoadKeysLDraw(Stream);
return true;
}
return false;
}
template<typename T> template<typename T>
void lcObject::SaveAttribute(QTextStream& Stream, const T& Variable, const lcObjectKeyArray<T>& Keys, const char* ObjectName, const char* VariableName) const void lcObject::SaveAttribute(QTextStream& Stream, const T& Variable, const lcObjectKeyArray<T>& Keys, const char* ObjectName, const char* VariableName) const
{ {

View file

@ -48,6 +48,61 @@ protected:
std::vector<lcObjectKey<T>> mKeys; std::vector<lcObjectKey<T>> mKeys;
}; };
template<typename T>
class lcObjectProperty : public lcObjectKeyArray<T>
{
public:
lcObjectProperty(const T& DefaultValue)
: mValue(DefaultValue)
{
ChangeKey(mValue, 1, true);
}
lcObjectProperty(const lcObjectProperty&) = delete;
lcObjectProperty(lcObjectProperty&&) = delete;
lcObjectProperty& operator=(const lcObjectProperty&) = delete;
lcObjectProperty& operator=(lcObjectProperty&&) = delete;
operator const T&() const
{
return mValue;
}
const T& GetValue() const
{
return mValue;
}
void SetValue(const T& Value, lcStep Step, bool AddKey)
{
mValue = Value;
ChangeKey(Value, Step, AddKey);
}
void Update(lcStep Step)
{
mValue = CalculateKey(Step);
}
void Reset()
{
mKeys.clear();
ChangeKey(mValue, 1, true);
}
void Reset(const T& Value)
{
mValue = Value;
Reset();
}
void Save(QTextStream& Stream, const char* ObjectName, const char* VariableName) const;
bool Load(QTextStream& Stream, const QString& Token, const char* VariableName);
protected:
T mValue;
};
struct lcObjectSection struct lcObjectSection
{ {
lcObject* Object = nullptr; lcObject* Object = nullptr;

View file

@ -682,7 +682,7 @@ void lcQPropertiesTree::slotReturnPressed()
if (Piece) if (Piece)
InitialRotation = lcMatrix44ToEulerAngles(Piece->mModelWorld) * LC_RTOD; InitialRotation = lcMatrix44ToEulerAngles(Piece->mModelWorld) * LC_RTOD;
else if (Light) else if (Light)
InitialRotation = lcMatrix44ToEulerAngles(Light->mWorldMatrix) * LC_RTOD; InitialRotation = lcMatrix44ToEulerAngles(Light->GetWorldMatrix()) * LC_RTOD;
lcVector3 Rotation = InitialRotation; lcVector3 Rotation = InitialRotation;
@ -1481,7 +1481,7 @@ void lcQPropertiesTree::SetLight(lcObject* Focus)
lcVector3 Rotation; lcVector3 Rotation;
if (Light) if (Light)
Rotation = lcMatrix44ToEulerAngles(Light->mWorldMatrix) * LC_RTOD; Rotation = lcMatrix44ToEulerAngles(Light->GetWorldMatrix()) * LC_RTOD;
else else
Rotation = lcVector3(0.0f, 0.0f, 0.0f); Rotation = lcVector3(0.0f, 0.0f, 0.0f);