Fixed POV-Ray area light grid.

This commit is contained in:
Leonardo Zide 2023-11-19 18:05:43 -08:00
parent 0a48e30ec0
commit 0e74aea5fa
9 changed files with 114 additions and 9 deletions

View file

@ -51,6 +51,21 @@ inline T lcClamp(const T& Value, const T& Min, const T& Max)
return Value; return Value;
} }
class lcVector2i
{
public:
lcVector2i()
{
}
constexpr lcVector2i(const int _x, const int _y)
: x(_x), y(_y)
{
}
int x, y;
};
class lcVector2 class lcVector2
{ {
public: public:

View file

@ -3215,7 +3215,7 @@ void lcModel::SetSpotLightTightness(lcLight* Light, float Tightness)
UpdateAllViews(); UpdateAllViews();
} }
void lcModel::SetAreaLightShape(lcLight* Light, lcLightAreaShape LightAreaShape) void lcModel::SetLightAreaShape(lcLight* Light, lcLightAreaShape LightAreaShape)
{ {
if (!Light->SetAreaShape(LightAreaShape)) if (!Light->SetAreaShape(LightAreaShape))
return; return;
@ -3227,6 +3227,18 @@ void lcModel::SetAreaLightShape(lcLight* Light, lcLightAreaShape LightAreaShape)
UpdateAllViews(); UpdateAllViews();
} }
void lcModel::SetLightAreaGrid(lcLight* Light, lcVector2i AreaGrid)
{
if (!Light->SetAreaGrid(AreaGrid, mCurrentStep, gMainWindow->GetAddKeys()))
return;
Light->UpdatePosition(mCurrentStep);
SaveCheckpoint(tr("Changing Area Light Size"));
gMainWindow->UpdateSelectedObjects(false);
UpdateAllViews();
}
void lcModel::SetLightSize(lcLight* Light, lcVector2 LightAreaSize) void lcModel::SetLightSize(lcLight* Light, lcVector2 LightAreaSize)
{ {
Light->SetSize(LightAreaSize, mCurrentStep, gMainWindow->GetAddKeys()); Light->SetSize(LightAreaSize, mCurrentStep, gMainWindow->GetAddKeys());

View file

@ -373,7 +373,8 @@ public:
void SetSpotLightConeAngle(lcLight* Light, float Angle); void SetSpotLightConeAngle(lcLight* Light, float Angle);
void SetSpotLightPenumbraAngle(lcLight* Light, float Angle); void SetSpotLightPenumbraAngle(lcLight* Light, float Angle);
void SetSpotLightTightness(lcLight* Light, float Tightness); void SetSpotLightTightness(lcLight* Light, float Tightness);
void SetAreaLightShape(lcLight* Light, lcLightAreaShape LightAreaShape); void SetLightAreaShape(lcLight* Light, lcLightAreaShape LightAreaShape);
void SetLightAreaGrid(lcLight* Light, lcVector2i AreaGrid);
void SetLightSize(lcLight* Light, lcVector2 LightAreaSize); void SetLightSize(lcLight* Light, lcVector2 LightAreaSize);
void SetLightPower(lcLight* Light, float Power); void SetLightPower(lcLight* Light, float Power);
void SetLightCastShadow(lcLight* Light, bool CastShadow); void SetLightCastShadow(lcLight* Light, bool CastShadow);

View file

@ -43,6 +43,7 @@ lcLight::lcLight(const lcVector3& Position, lcLightType LightType)
mSpotConeAngleKeys.ChangeKey(mSpotConeAngle, 1, true); mSpotConeAngleKeys.ChangeKey(mSpotConeAngle, 1, true);
mSpotPenumbraAngleKeys.ChangeKey(mSpotPenumbraAngle, 1, true); mSpotPenumbraAngleKeys.ChangeKey(mSpotPenumbraAngle, 1, true);
mSpotTightnessKeys.ChangeKey(mSpotTightness, 1, true); mSpotTightnessKeys.ChangeKey(mSpotTightness, 1, true);
mAreaGridKeys.ChangeKey(mAreaGrid, 1, true);
mAttenuationKeys.ChangeKey(mAttenuation, 1, true); mAttenuationKeys.ChangeKey(mAttenuation, 1, true);
mLightDiffuseKeys.ChangeKey(mLightDiffuse, 1, true); mLightDiffuseKeys.ChangeKey(mLightDiffuse, 1, true);
@ -189,6 +190,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");
break; break;
} }
@ -324,6 +326,8 @@ bool lcLight::ParseLDrawLine(QTextStream& Stream)
} }
} }
} }
else if (LoadAttribute(Stream, Token, mAreaGrid, mAreaGridKeys, "AREA_GRID"))
continue;
// else if (Token == QLatin1String("POWER") || Token == QLatin1String("STRENGTH")) // else if (Token == QLatin1String("POWER") || Token == QLatin1String("STRENGTH"))
// { // {
@ -690,6 +694,13 @@ bool lcLight::SetAreaShape(lcLightAreaShape AreaShape)
return false; return false;
} }
bool lcLight::SetAreaGrid(lcVector2i AreaGrid, lcStep Step, bool AddKey)
{
mAreaGridKeys.ChangeKey(AreaGrid, Step, AddKey);
return true;
}
void lcLight::SetSize(lcVector2 Size, lcStep Step, bool AddKey) 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))
@ -722,6 +733,7 @@ void lcLight::InsertTime(lcStep Start, lcStep Time)
mSpotConeAngleKeys.InsertTime(Start, Time); mSpotConeAngleKeys.InsertTime(Start, Time);
mSpotPenumbraAngleKeys.InsertTime(Start, Time); mSpotPenumbraAngleKeys.InsertTime(Start, Time);
mSpotTightnessKeys.InsertTime(Start, Time); mSpotTightnessKeys.InsertTime(Start, Time);
mAreaGridKeys.InsertTime(Start, Time);
mSizeKeys.InsertTime(Start, Time); mSizeKeys.InsertTime(Start, Time);
mPowerKeys.InsertTime(Start, Time); mPowerKeys.InsertTime(Start, Time);
@ -740,6 +752,7 @@ void lcLight::RemoveTime(lcStep Start, lcStep Time)
mSpotConeAngleKeys.RemoveTime(Start, Time); mSpotConeAngleKeys.RemoveTime(Start, Time);
mSpotPenumbraAngleKeys.RemoveTime(Start, Time); mSpotPenumbraAngleKeys.RemoveTime(Start, Time);
mSpotTightnessKeys.RemoveTime(Start, Time); mSpotTightnessKeys.RemoveTime(Start, Time);
mAreaGridKeys.RemoveTime(Start, Time);
mSizeKeys.RemoveTime(Start, Time); mSizeKeys.RemoveTime(Start, Time);
mPowerKeys.RemoveTime(Start, Time); mPowerKeys.RemoveTime(Start, Time);
@ -769,6 +782,7 @@ void lcLight::UpdatePosition(lcStep Step)
mSpotConeAngle = mSpotConeAngleKeys.CalculateKey(Step); mSpotConeAngle = mSpotConeAngleKeys.CalculateKey(Step);
mSpotPenumbraAngle = mSpotPenumbraAngleKeys.CalculateKey(Step); mSpotPenumbraAngle = mSpotPenumbraAngleKeys.CalculateKey(Step);
mSpotTightness = mSpotTightnessKeys.CalculateKey(Step); mSpotTightness = mSpotTightnessKeys.CalculateKey(Step);
mAreaGrid = mAreaGridKeys.CalculateKey(Step);
mSize = mSizeKeys.CalculateKey(Step); mSize = mSizeKeys.CalculateKey(Step);
mPower = mPowerKeys.CalculateKey(Step); mPower = mPowerKeys.CalculateKey(Step);
@ -1207,6 +1221,9 @@ void lcLight::RemoveKeyFrames()
mSpotTightnessKeys.RemoveAll(); mSpotTightnessKeys.RemoveAll();
mSpotTightnessKeys.ChangeKey(mSpotTightness, 1, true); mSpotTightnessKeys.ChangeKey(mSpotTightness, 1, true);
mAreaGridKeys.RemoveAll();
mAreaGridKeys.ChangeKey(mAreaGrid, 1, true);
mSizeKeys.RemoveAll(); mSizeKeys.RemoveAll();
mSizeKeys.ChangeKey(mSize, 1, true); mSizeKeys.ChangeKey(mSize, 1, true);

View file

@ -276,6 +276,13 @@ public:
return mAreaShape; return mAreaShape;
} }
bool SetAreaGrid(lcVector2i AreaGrid, lcStep Step, bool AddKey);
lcVector2i GetAreaGrid() const
{
return mAreaGrid;
}
void SetSize(lcVector2 Size, lcStep Step, bool AddKey); void SetSize(lcVector2 Size, lcStep Step, bool AddKey);
lcVector2 GetSize() const lcVector2 GetSize() const
@ -364,6 +371,7 @@ protected:
float mSpotPenumbraAngle = 0.0f; float mSpotPenumbraAngle = 0.0f;
float mSpotTightness = 0.0f; float mSpotTightness = 0.0f;
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;
@ -378,6 +386,7 @@ protected:
lcObjectKeyArray<float> mSpotConeAngleKeys; lcObjectKeyArray<float> mSpotConeAngleKeys;
lcObjectKeyArray<float> mSpotPenumbraAngleKeys; lcObjectKeyArray<float> mSpotPenumbraAngleKeys;
lcObjectKeyArray<float> mSpotTightnessKeys; lcObjectKeyArray<float> mSpotTightnessKeys;
lcObjectKeyArray<lcVector2i> mAreaGridKeys;
lcObjectKeyArray<lcVector3> mAttenuationKeys; lcObjectKeyArray<lcVector3> mAttenuationKeys;
lcObjectKeyArray<float> mLightSpecularKeys; lcObjectKeyArray<float> mLightSpecularKeys;

View file

@ -12,6 +12,7 @@
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)
LC_OBJECT_ATTRIBUTE(float); LC_OBJECT_ATTRIBUTE(float);
LC_OBJECT_ATTRIBUTE(lcVector2i);
LC_OBJECT_ATTRIBUTE(lcVector2); LC_OBJECT_ATTRIBUTE(lcVector2);
LC_OBJECT_ATTRIBUTE(lcVector3); LC_OBJECT_ATTRIBUTE(lcVector3);
LC_OBJECT_ATTRIBUTE(lcVector4); LC_OBJECT_ATTRIBUTE(lcVector4);

View file

@ -2140,7 +2140,7 @@ bool Project::ExportPOVRay(const QString& FileName)
POVFile.WriteLine(Line); POVFile.WriteLine(Line);
lcVector3 AreaX(1.0f, 0.0f, 0.0f), AreaY(0.0f, 1.0f, 0.0f); lcVector3 AreaX(1.0f, 0.0f, 0.0f), AreaY(0.0f, 1.0f, 0.0f);
lcVector2 AreaSize(200.0f, 200.0f); lcVector2i AreaGrid(1, 1);
int AreaCircle = 0, Shadowless = 0; int AreaCircle = 0, Shadowless = 0;
lcLightType LightType = lcLightType::Area; lcLightType LightType = lcLightType::Area;
float Power = 0, SpotRadius = 0, SpotFalloff = 0, SpotTightness = 0; float Power = 0, SpotRadius = 0, SpotFalloff = 0, SpotTightness = 0;
@ -2167,7 +2167,7 @@ bool Project::ExportPOVRay(const QString& FileName)
LightColor[0], LightColor[1], LightColor[2], LightColor[0], LightColor[1], LightColor[2],
Power, Power,
SpotRadius, SpotFalloff, SpotTightness, SpotRadius, SpotFalloff, SpotTightness,
AreaCircle, AreaX[0], AreaX[1], AreaX[2], AreaY[0], AreaY[1], AreaY[2], (int)AreaSize[0], (int)AreaSize[1]); AreaCircle, AreaX[0], AreaX[1], AreaX[2], AreaY[0], AreaY[1], AreaY[2], AreaGrid.x, AreaGrid.y);
POVFile.WriteLine(Line); POVFile.WriteLine(Line);
} }
} }
@ -2198,9 +2198,9 @@ bool Project::ExportPOVRay(const QString& FileName)
case lcLightType::Area: case lcLightType::Area:
AreaCircle = (Light->GetAreaShape() == lcLightAreaShape::Disk || Light->GetAreaShape() == lcLightAreaShape::Ellipse) ? 1 : 0; AreaCircle = (Light->GetAreaShape() == lcLightAreaShape::Disk || Light->GetAreaShape() == lcLightAreaShape::Ellipse) ? 1 : 0;
AreaSize = Light->GetSize(); AreaX = lcVector3(Light->GetWorldMatrix()[0]) * Light->GetSize().x;
AreaX = lcVector3(Light->GetWorldMatrix()[0]); AreaY = lcVector3(Light->GetWorldMatrix()[1]) * Light->GetSize().y;
AreaY = lcVector3(Light->GetWorldMatrix()[1]); AreaGrid = Light->GetAreaGrid();
break; break;
case lcLightType::Count: case lcLightType::Count:
@ -2216,7 +2216,7 @@ bool Project::ExportPOVRay(const QString& FileName)
LightColor[0], LightColor[1], LightColor[2], LightColor[0], LightColor[1], LightColor[2],
Power, Power,
SpotRadius, SpotFalloff, SpotTightness, SpotRadius, SpotFalloff, SpotTightness,
AreaCircle, AreaX[0], AreaX[1], AreaX[2], AreaY[0], AreaY[1], AreaY[2], (int)AreaSize[0], (int)AreaSize[1]); AreaCircle, AreaX[0], AreaX[1], AreaX[2], AreaY[0], AreaY[1], AreaY[2], AreaGrid.x, AreaGrid.y);
POVFile.WriteLine(Line); POVFile.WriteLine(Line);
} }
} }

View file

@ -447,6 +447,20 @@ QWidget* lcQPropertiesTree::createEditor(QWidget* Parent, QTreeWidgetItem* Item)
return Editor; return Editor;
} }
case PropertyInteger:
{
QLineEdit* Editor = new QLineEdit(Parent);
int Value = Item->data(0, PropertyValueRole).toInt();
QPoint Range = Item->data(0, PropertyRangeRole).toPoint();
Editor->setValidator(Range.isNull() ? new QIntValidator(Editor) : new QIntValidator(Range.x(), Range.y(), Editor));
Editor->setText(QString::number(Value));
connect(Editor, &QLineEdit::returnPressed, this, &lcQPropertiesTree::slotReturnPressed);
return Editor;
}
case PropertyStep: case PropertyStep:
{ {
QLineEdit* Editor = new QLineEdit(Parent); QLineEdit* Editor = new QLineEdit(Parent);
@ -842,6 +856,20 @@ void lcQPropertiesTree::slotReturnPressed()
Model->SetSpotLightTightness(Light, Value); Model->SetSpotLightTightness(Light, Value);
} }
else if (Item == mLightAreaGridXItem)
{
lcVector2i AreaGrid = Light->GetAreaGrid();
AreaGrid.x = Editor->text().toInt();
Model->SetLightAreaGrid(Light, AreaGrid);
}
else if (Item == mLightAreaGridYItem)
{
lcVector2i AreaGrid = Light->GetAreaGrid();
AreaGrid.y = Editor->text().toInt();
Model->SetLightAreaGrid(Light, AreaGrid);
}
else if (Item == mLightSizeXItem) else if (Item == mLightSizeXItem)
{ {
lcVector2 Value = Light->GetSize(); lcVector2 Value = Light->GetSize();
@ -954,7 +982,7 @@ void lcQPropertiesTree::slotSetValue(int Value)
} }
else if (Item == mLightAreaShapeItem) else if (Item == mLightAreaShapeItem)
{ {
Model->SetAreaLightShape(Light, static_cast<lcLightAreaShape>(Value)); Model->SetLightAreaShape(Light, static_cast<lcLightAreaShape>(Value));
} }
else if (Item == lightFormat) else if (Item == lightFormat)
{ {
@ -1100,6 +1128,8 @@ void lcQPropertiesTree::SetEmpty()
mLightSpotPenumbraAngleItem = nullptr; mLightSpotPenumbraAngleItem = nullptr;
mLightSpotTightnessItem = nullptr; mLightSpotTightnessItem = nullptr;
mLightAreaShapeItem = nullptr; mLightAreaShapeItem = nullptr;
mLightAreaGridXItem = nullptr;
mLightAreaGridYItem = nullptr;
mLightSizeXItem = nullptr; mLightSizeXItem = nullptr;
mLightSizeYItem = nullptr; mLightSizeYItem = nullptr;
lightFormat = nullptr; lightFormat = nullptr;
@ -1355,6 +1385,7 @@ void lcQPropertiesTree::SetLight(lcObject* Focus)
lcLightType LightType = lcLightType::Point; lcLightType LightType = lcLightType::Point;
lcLightAreaShape LightAreaShape = lcLightAreaShape::Rectangle; lcLightAreaShape LightAreaShape = lcLightAreaShape::Rectangle;
lcVector2 LightSize(0.0f, 0.0f); lcVector2 LightSize(0.0f, 0.0f);
lcVector2i AreaGrid(2, 2);
float Power = 0.0f; float Power = 0.0f;
int FormatIndex = 0; int FormatIndex = 0;
float Diffuse = 0.0f; float Diffuse = 0.0f;
@ -1386,6 +1417,7 @@ void lcQPropertiesTree::SetLight(lcObject* Focus)
LightType = Light->GetLightType(); LightType = Light->GetLightType();
LightAreaShape = Light->GetAreaShape(); LightAreaShape = Light->GetAreaShape();
LightSize = Light->GetSize(); LightSize = Light->GetSize();
AreaGrid = Light->GetAreaGrid();
switch (LightType) switch (LightType)
{ {
@ -1498,6 +1530,15 @@ void lcQPropertiesTree::SetLight(lcObject* Focus)
case lcLightAreaShape::Count: case lcLightAreaShape::Count:
break; break;
} }
mLightAreaGridXItem = addProperty(mLightAttributesItem, tr("Area Grid X"), PropertyInteger);
mLightAreaGridXItem->setToolTip(1, tr("Number of point sources along the X axis (POV-Ray only)."));
mLightAreaGridXItem->setData(0, PropertyRangeRole, QPointF(1, INT_MAX));
mLightAreaGridYItem = addProperty(mLightAttributesItem, tr("Area Grid Y"), PropertyInteger);
mLightAreaGridYItem->setToolTip(1, tr("Number of point sources along the Y axis (POV-Ray only)."));
mLightAreaGridYItem->setData(0, PropertyRangeRole, QPointF(1, INT_MAX));
break; break;
case lcLightType::Count: case lcLightType::Count:
@ -1630,6 +1671,12 @@ void lcQPropertiesTree::SetLight(lcObject* Focus)
case lcLightType::Area: case lcLightType::Area:
mLightAreaShapeItem->setText(1, lcLight::GetAreaShapeString(LightAreaShape)); mLightAreaShapeItem->setText(1, lcLight::GetAreaShapeString(LightAreaShape));
mLightAreaShapeItem->setData(0, PropertyValueRole, static_cast<int>(LightAreaShape)); mLightAreaShapeItem->setData(0, PropertyValueRole, static_cast<int>(LightAreaShape));
mLightAreaGridXItem->setText(1, QString::number(AreaGrid.x));
mLightAreaGridXItem->setData(0, PropertyValueRole, AreaGrid.x);
mLightAreaGridYItem->setText(1, QString::number(AreaGrid.y));
mLightAreaGridYItem->setData(0, PropertyValueRole, AreaGrid.y);
break; break;
case lcLightType::Count: case lcLightType::Count:

View file

@ -45,6 +45,7 @@ public:
PropertyGroup, PropertyGroup,
PropertyBool, PropertyBool,
PropertyFloat, PropertyFloat,
PropertyInteger,
PropertyStep, PropertyStep,
PropertyString, PropertyString,
PropertyStringList, PropertyStringList,
@ -128,6 +129,8 @@ protected:
QTreeWidgetItem* mLightSpotPenumbraAngleItem; QTreeWidgetItem* mLightSpotPenumbraAngleItem;
QTreeWidgetItem* mLightSpotTightnessItem; QTreeWidgetItem* mLightSpotTightnessItem;
QTreeWidgetItem* mLightAreaShapeItem; QTreeWidgetItem* mLightAreaShapeItem;
QTreeWidgetItem* mLightAreaGridXItem;
QTreeWidgetItem* mLightAreaGridYItem;
QTreeWidgetItem* mLightSizeXItem; QTreeWidgetItem* mLightSizeXItem;
QTreeWidgetItem* mLightSizeYItem; QTreeWidgetItem* mLightSizeYItem;
QTreeWidgetItem* mLightNameItem; QTreeWidgetItem* mLightNameItem;