Fix the particle editor

master
Ansariel 2025-08-19 13:34:08 +02:00
parent 70768b815f
commit 1227e538b1
2 changed files with 103 additions and 122 deletions

View File

@ -22,8 +22,6 @@
#include "llviewerprecompiledheaders.h" #include "llviewerprecompiledheaders.h"
#include "particleeditor.h" #include "particleeditor.h"
#include <fstream>
#include "llagent.h" #include "llagent.h"
#include "llappviewer.h" #include "llappviewer.h"
#include "llcheckboxctrl.h" #include "llcheckboxctrl.h"
@ -47,10 +45,7 @@
#include "llwindow.h" #include "llwindow.h"
#include "llviewerassetupload.h" #include "llviewerassetupload.h"
ParticleEditor::ParticleEditor(const LLSD& key) ParticleEditor::ParticleEditor(const LLSD& key) : LLFloater(key)
: LLFloater(key),
mObject(0),
mParticleScriptInventoryItem(0)
{ {
mPatternMap["drop"] = LLPartSysData::LL_PART_SRC_PATTERN_DROP; mPatternMap["drop"] = LLPartSysData::LL_PART_SRC_PATTERN_DROP;
mPatternMap["explode"] = LLPartSysData::LL_PART_SRC_PATTERN_EXPLODE; mPatternMap["explode"] = LLPartSysData::LL_PART_SRC_PATTERN_EXPLODE;
@ -325,11 +320,11 @@ void ParticleEditor::updateUI()
bool targetLinear = mTargetLinearCheckBox->getValue(); bool targetLinear = mTargetLinearCheckBox->getValue();
bool interpolateColor = mInterpolateColorCheckBox->getValue(); bool interpolateColor = mInterpolateColorCheckBox->getValue();
bool interpolateScale = mInterpolateScaleCheckBox->getValue(); bool interpolateScale = mInterpolateScaleCheckBox->getValue();
bool targetEnabled = targetLinear | (mTargetPositionCheckBox->getValue().asBoolean() ? true : false); bool targetEnabled = targetLinear || (mTargetPositionCheckBox->getValue().asBoolean() ? true : false);
mBurstRadiusSpinner->setEnabled(!(targetLinear | (mFollowSourceCheckBox->getValue().asBoolean() ? true : false) | dropPattern)); mBurstRadiusSpinner->setEnabled(!targetLinear && !(mFollowSourceCheckBox->getValue().asBoolean() ? true : false) && !dropPattern);
mBurstSpeedMinSpinner->setEnabled(!(targetLinear | dropPattern)); mBurstSpeedMinSpinner->setEnabled(!targetLinear && !dropPattern);
mBurstSpeedMaxSpinner->setEnabled(!(targetLinear | dropPattern)); mBurstSpeedMaxSpinner->setEnabled(!targetLinear && !dropPattern);
// disabling a color swatch does nothing visually, so we also set alpha // disabling a color swatch does nothing visually, so we also set alpha
LLColor4 endColor = mEndColorSelector->get(); LLColor4 endColor = mEndColorSelector->get();
@ -355,8 +350,8 @@ void ParticleEditor::updateUI()
mOmegaYSpinner->setEnabled(!targetLinear); mOmegaYSpinner->setEnabled(!targetLinear);
mOmegaZSpinner->setEnabled(!targetLinear); mOmegaZSpinner->setEnabled(!targetLinear);
mAngleBeginSpinner->setEnabled(!(explodePattern | dropPattern)); mAngleBeginSpinner->setEnabled(!explodePattern && !dropPattern);
mAngleEndSpinner->setEnabled(!(explodePattern | dropPattern)); mAngleEndSpinner->setEnabled(!explodePattern && !dropPattern);
} }
void ParticleEditor::onClearTargetButtonClicked() void ParticleEditor::onClearTargetButtonClicked()
@ -369,15 +364,13 @@ void ParticleEditor::onTargetPickerButtonClicked()
{ {
mPickTargetButton->setToggleState(true); mPickTargetButton->setToggleState(true);
mPickTargetButton->setEnabled(false); mPickTargetButton->setEnabled(false);
startPicking(this); startPicking();
} }
// inspired by the LLFloaterReporter object picker // inspired by the LLFloaterReporter object picker
// static void ParticleEditor::startPicking()
void ParticleEditor::startPicking(void* userdata)
{ {
ParticleEditor* self = (ParticleEditor*) userdata; LLToolObjPicker::getInstance()->setExitCallback(ParticleEditor::onTargetPicked, this);
LLToolObjPicker::getInstance()->setExitCallback(ParticleEditor::onTargetPicked, self);
LLToolMgr::getInstance()->setTransientTool(LLToolObjPicker::getInstance()); LLToolMgr::getInstance()->setTransientTool(LLToolObjPicker::getInstance());
} }
@ -386,14 +379,12 @@ void ParticleEditor::onTargetPicked(void* userdata)
{ {
ParticleEditor* self = (ParticleEditor*)userdata; ParticleEditor* self = (ParticleEditor*)userdata;
LLUUID picked = LLToolObjPicker::getInstance()->getObjectID();
LLToolMgr::getInstance()->clearTransientTool(); LLToolMgr::getInstance()->clearTransientTool();
self->mPickTargetButton->setEnabled(true); self->mPickTargetButton->setEnabled(true);
self->mPickTargetButton->setToggleState(false); self->mPickTargetButton->setToggleState(false);
if (picked.notNull()) if (LLUUID picked = LLToolObjPicker::getInstance()->getObjectID(); picked.notNull())
{ {
self->mTargetKeyInput->setValue(picked.asString()); self->mTargetKeyInput->setValue(picked.asString());
self->onParameterChange(); self->onParameterChange();
@ -522,8 +513,7 @@ default\n\
void ParticleEditor::onCopyButtonClicked() void ParticleEditor::onCopyButtonClicked()
{ {
std::string script = createScript(); if (std::string script = createScript(); !script.empty())
if (!script.empty())
{ {
getWindow()->copyTextToClipboard(utf8str_to_wstring(script)); getWindow()->copyTextToClipboard(utf8str_to_wstring(script));
LLNotificationsUtil::add("ParticleScriptCopiedToClipboard"); LLNotificationsUtil::add("ParticleScriptCopiedToClipboard");
@ -608,9 +598,7 @@ void ParticleEditor::callbackReturned(const LLUUID& inventoryItemID)
gInventory.notifyObservers(); gInventory.notifyObservers();
//caps import //caps import
std::string url = gAgent.getRegionCapability("UpdateScriptAgent"); if (std::string url = gAgent.getRegionCapability("UpdateScriptAgent"); !url.empty())
if (!url.empty())
{ {
std::string script = createScript(); std::string script = createScript();
@ -633,30 +621,23 @@ void ParticleEditor::callbackReturned(const LLUUID& inventoryItemID)
void ParticleEditor::scriptInjectReturned() void ParticleEditor::scriptInjectReturned()
{ {
setCanClose(true); setCanClose(true);
mMainPanel->setEnabled(true);
// play it safe, because some time may have passed // play it safe, because some time may have passed
LLViewerObject* object = gObjectList.findObject(mObject->getID()); if (LLViewerObject* object = gObjectList.findObject(mObject->getID()); object && mObject&& !mObject->isDead())
if (!object || mObject->isDead())
{ {
LL_WARNS() << "Can't inject script - object is dead or went away!" << LL_ENDL;
mMainPanel->setEnabled(true);
return;
}
mObject->saveScript(mParticleScriptInventoryItem, true, false); mObject->saveScript(mParticleScriptInventoryItem, true, false);
LLNotificationsUtil::add("ParticleScriptInjected"); LLNotificationsUtil::add("ParticleScriptInjected");
}
delete this; else
{
LL_WARNS() << "Can't inject script - object is dead or went away!" << LL_ENDL;
}
} }
// ---------------------------------- Callbacks ---------------------------------- // ---------------------------------- Callbacks ----------------------------------
ParticleScriptCreationCallback::ParticleScriptCreationCallback(ParticleEditor* editor) ParticleScriptCreationCallback::ParticleScriptCreationCallback(ParticleEditor* editor) : mEditor(editor)
{
mEditor = editor;
}
ParticleScriptCreationCallback::~ParticleScriptCreationCallback()
{ {
} }

View File

@ -66,7 +66,7 @@ class ParticleEditor : public LLFloater
void onClearTargetButtonClicked(); void onClearTargetButtonClicked();
void onTargetPickerButtonClicked(); void onTargetPickerButtonClicked();
static void startPicking(void* userdata); void startPicking();
static void onTargetPicked(void* userdata); static void onTargetPicked(void* userdata);
void callbackReturned(const LLUUID& inv_item); void callbackReturned(const LLUUID& inv_item);
@ -74,11 +74,11 @@ class ParticleEditor : public LLFloater
std::string lslVector(F32 x, F32 y, F32 z); std::string lslVector(F32 x, F32 y, F32 z);
std::string lslColor(const LLColor4& color); std::string lslColor(const LLColor4& color);
LLViewerObject* mObject; LLViewerObject* mObject{ nullptr };
LLViewerTexture* mTexture; LLViewerTexture* mTexture{ nullptr };
LLViewerInventoryItem* mParticleScriptInventoryItem; LLViewerInventoryItem* mParticleScriptInventoryItem{ nullptr };
LLViewerTexture* mDefaultParticleTexture; LLViewerTexture* mDefaultParticleTexture{ nullptr };
LLPartSysData mParticles; LLPartSysData mParticles;
@ -88,60 +88,60 @@ class ParticleEditor : public LLFloater
std::map<std::string, U8> mBlendMap; std::map<std::string, U8> mBlendMap;
std::map<std::string, std::string> mScriptBlendMap; std::map<std::string, std::string> mScriptBlendMap;
LLPanel* mMainPanel; LLPanel* mMainPanel{ nullptr };
LLComboBox* mPatternTypeCombo; LLComboBox* mPatternTypeCombo{ nullptr };
LLTextureCtrl* mTexturePicker; LLTextureCtrl* mTexturePicker{ nullptr };
LLSpinCtrl* mBurstRateSpinner; LLSpinCtrl* mBurstRateSpinner{ nullptr };
LLSpinCtrl* mBurstCountSpinner; LLSpinCtrl* mBurstCountSpinner{ nullptr };
LLSpinCtrl* mBurstRadiusSpinner; LLSpinCtrl* mBurstRadiusSpinner{ nullptr };
LLSpinCtrl* mAngleBeginSpinner; LLSpinCtrl* mAngleBeginSpinner{ nullptr };
LLSpinCtrl* mAngleEndSpinner; LLSpinCtrl* mAngleEndSpinner{ nullptr };
LLSpinCtrl* mBurstSpeedMinSpinner; LLSpinCtrl* mBurstSpeedMinSpinner{ nullptr };
LLSpinCtrl* mBurstSpeedMaxSpinner; LLSpinCtrl* mBurstSpeedMaxSpinner{ nullptr };
LLSpinCtrl* mStartAlphaSpinner; LLSpinCtrl* mStartAlphaSpinner{ nullptr };
LLSpinCtrl* mEndAlphaSpinner; LLSpinCtrl* mEndAlphaSpinner{ nullptr };
LLSpinCtrl* mScaleStartXSpinner; LLSpinCtrl* mScaleStartXSpinner{ nullptr };
LLSpinCtrl* mScaleStartYSpinner; LLSpinCtrl* mScaleStartYSpinner{ nullptr };
LLSpinCtrl* mScaleEndXSpinner; LLSpinCtrl* mScaleEndXSpinner{ nullptr };
LLSpinCtrl* mScaleEndYSpinner; LLSpinCtrl* mScaleEndYSpinner{ nullptr };
LLSpinCtrl* mSourceMaxAgeSpinner; LLSpinCtrl* mSourceMaxAgeSpinner{ nullptr };
LLSpinCtrl* mParticlesMaxAgeSpinner; LLSpinCtrl* mParticlesMaxAgeSpinner{ nullptr };
LLSpinCtrl* mStartGlowSpinner; LLSpinCtrl* mStartGlowSpinner{ nullptr };
LLSpinCtrl* mEndGlowSpinner; LLSpinCtrl* mEndGlowSpinner{ nullptr };
LLComboBox* mBlendFuncSrcCombo; LLComboBox* mBlendFuncSrcCombo{ nullptr };
LLComboBox* mBlendFuncDestCombo; LLComboBox* mBlendFuncDestCombo{ nullptr };
LLCheckBoxCtrl* mBounceCheckBox; LLCheckBoxCtrl* mBounceCheckBox{ nullptr };
LLCheckBoxCtrl* mEmissiveCheckBox; LLCheckBoxCtrl* mEmissiveCheckBox{ nullptr };
LLCheckBoxCtrl* mFollowSourceCheckBox; LLCheckBoxCtrl* mFollowSourceCheckBox{ nullptr };
LLCheckBoxCtrl* mFollowVelocityCheckBox; LLCheckBoxCtrl* mFollowVelocityCheckBox{ nullptr };
LLCheckBoxCtrl* mInterpolateColorCheckBox; LLCheckBoxCtrl* mInterpolateColorCheckBox{ nullptr };
LLCheckBoxCtrl* mInterpolateScaleCheckBox; LLCheckBoxCtrl* mInterpolateScaleCheckBox{ nullptr };
LLCheckBoxCtrl* mTargetPositionCheckBox; LLCheckBoxCtrl* mTargetPositionCheckBox{ nullptr };
LLCheckBoxCtrl* mTargetLinearCheckBox; LLCheckBoxCtrl* mTargetLinearCheckBox{ nullptr };
LLCheckBoxCtrl* mWindCheckBox; LLCheckBoxCtrl* mWindCheckBox{ nullptr };
LLCheckBoxCtrl* mRibbonCheckBox; LLCheckBoxCtrl* mRibbonCheckBox{ nullptr };
LLLineEditor* mTargetKeyInput; LLLineEditor* mTargetKeyInput{ nullptr };
LLButton* mClearTargetButton; LLButton* mClearTargetButton{ nullptr };
LLButton* mPickTargetButton; LLButton* mPickTargetButton{ nullptr };
LLSpinCtrl* mAcellerationXSpinner; LLSpinCtrl* mAcellerationXSpinner{ nullptr };
LLSpinCtrl* mAcellerationYSpinner; LLSpinCtrl* mAcellerationYSpinner{ nullptr };
LLSpinCtrl* mAcellerationZSpinner; LLSpinCtrl* mAcellerationZSpinner{ nullptr };
LLSpinCtrl* mOmegaXSpinner; LLSpinCtrl* mOmegaXSpinner{ nullptr };
LLSpinCtrl* mOmegaYSpinner; LLSpinCtrl* mOmegaYSpinner{ nullptr };
LLSpinCtrl* mOmegaZSpinner; LLSpinCtrl* mOmegaZSpinner{ nullptr };
LLColorSwatchCtrl* mStartColorSelector; LLColorSwatchCtrl* mStartColorSelector{ nullptr };
LLColorSwatchCtrl* mEndColorSelector; LLColorSwatchCtrl* mEndColorSelector{ nullptr };
LLButton* mCopyToLSLButton; LLButton* mCopyToLSLButton{ nullptr };
LLButton* mInjectScriptButton; LLButton* mInjectScriptButton{ nullptr };
}; };
class ParticleScriptCreationCallback : public LLInventoryCallback class ParticleScriptCreationCallback : public LLInventoryCallback
@ -151,7 +151,7 @@ class ParticleScriptCreationCallback : public LLInventoryCallback
void fire(const LLUUID& inventoryItem); void fire(const LLUUID& inventoryItem);
protected: protected:
~ParticleScriptCreationCallback(); ~ParticleScriptCreationCallback() = default;
ParticleEditor* mEditor; ParticleEditor* mEditor;
}; };