SL-17685 Drag and drop material support WIP

master
Dave Parks 2022-06-29 17:59:09 -05:00
parent f6515257a0
commit fd6b5ea8c3
12 changed files with 273 additions and 46 deletions

View File

@ -1700,7 +1700,7 @@ BOOL LLNetworkData::isValid(U16 param_type, U32 size)
case PARAMS_EXTENDED_MESH:
return (size == 4);
case PARAMS_RENDER_MATERIAL:
return (size == 16);
return (size > 1);
}
return FALSE;
@ -2312,18 +2312,32 @@ LLRenderMaterialParams::LLRenderMaterialParams()
mType = PARAMS_RENDER_MATERIAL;
}
BOOL LLRenderMaterialParams::pack(LLDataPacker &dp) const
BOOL LLRenderMaterialParams::pack(LLDataPacker& dp) const
{
return dp.packUUID(mMaterial, "material");
U8 count = (U8)llmin((S32)mEntries.size(), 14); //limited to 255 bytes, no more than 14 material ids
// return TRUE;
dp.packU8(count, "count");
for (auto& entry : mEntries)
{
dp.packU8(entry.te_idx, "te_idx");
dp.packUUID(entry.id, "id");
}
return TRUE;
}
BOOL LLRenderMaterialParams::unpack(LLDataPacker &dp)
BOOL LLRenderMaterialParams::unpack(LLDataPacker& dp)
{
return dp.unpackUUID(mMaterial, "material");
U8 count;
dp.unpackU8(count, "count");
mEntries.resize(count);
for (auto& entry : mEntries)
{
dp.unpackU8(entry.te_idx, "te_idx");
dp.unpackUUID(entry.id, "te_id");
}
// return TRUE;
return TRUE;
}
bool LLRenderMaterialParams::operator==(const LLNetworkData& data) const
@ -2333,40 +2347,99 @@ bool LLRenderMaterialParams::operator==(const LLNetworkData& data) const
return false;
}
const LLRenderMaterialParams &param = static_cast<const LLRenderMaterialParams&>(data);
const LLRenderMaterialParams& param = static_cast<const LLRenderMaterialParams&>(data);
return param.mMaterial == mMaterial;
if (param.mEntries.size() != mEntries.size())
{
return false;
}
for (auto& entry : mEntries)
{
if (param.getMaterial(entry.te_idx) != entry.id)
{
return false;
}
}
return true;
}
void LLRenderMaterialParams::copy(const LLNetworkData& data)
{
llassert_always(data.mType == PARAMS_RENDER_MATERIAL);
const LLRenderMaterialParams &param = static_cast<const LLRenderMaterialParams&>(data);
mMaterial = param.mMaterial;
const LLRenderMaterialParams& param = static_cast<const LLRenderMaterialParams&>(data);
mEntries = param.mEntries;
}
LLSD LLRenderMaterialParams::asLLSD() const
{
return llsd::map("material", mMaterial);
LLSD ret;
for (int i = 0; i < mEntries.size(); ++i)
{
ret[i]["te_idx"] = mEntries[i].te_idx;
ret[i]["id"] = mEntries[i].id;
}
return ret;
}
bool LLRenderMaterialParams::fromLLSD(LLSD& sd)
{
if (sd.has("material"))
if (sd.isArray())
{
setMaterial(sd["material"]);
mEntries.resize(sd.size());
for (int i = 0; i < sd.size(); ++i)
{
if (sd[i].has("te_idx") && sd.has("id"))
{
mEntries[i].te_idx = sd[i]["te_idx"].asInteger();
mEntries[i].id = sd[i]["id"].asUUID();
}
else
{
return false;
}
}
return true;
}
return false;
}
void LLRenderMaterialParams::setMaterial(const LLUUID & id)
void LLRenderMaterialParams::setMaterial(U8 te, const LLUUID& id)
{
mMaterial = id;
for (int i = 0; i < mEntries.size(); ++i)
{
if (mEntries[i].te_idx == te)
{
if (id.isNull())
{
mEntries.erase(mEntries.begin() + i);
}
else
{
mEntries[i].id = id;
}
return;
}
}
mEntries.push_back({ te, id });
}
LLUUID LLRenderMaterialParams::getMaterial() const
LLUUID LLRenderMaterialParams::getMaterial(U8 te) const
{
return mMaterial;
for (int i = 0; i < mEntries.size(); ++i)
{
if (mEntries[i].te_idx == te)
{
return mEntries[i].id;
}
}
return LLUUID::null;
}

View File

@ -369,22 +369,30 @@ public:
class LLRenderMaterialParams : public LLNetworkData
{
private:
LLUUID mMaterial;
struct Entry
{
U8 te_idx;
LLUUID id;
};
std::vector< Entry > mEntries;
public:
LLRenderMaterialParams();
BOOL pack(LLDataPacker &dp) const override;
BOOL unpack(LLDataPacker &dp) override;
BOOL pack(LLDataPacker& dp) const override;
BOOL unpack(LLDataPacker& dp) override;
bool operator==(const LLNetworkData& data) const override;
void copy(const LLNetworkData& data) override;
LLSD asLLSD() const;
operator LLSD() const { return asLLSD(); }
bool fromLLSD(LLSD& sd);
void setMaterial(const LLUUID & id);
LLUUID getMaterial() const;
void setMaterial(U8 te_idx, const LLUUID& id);
LLUUID getMaterial(U8 te_idx) const;
bool isEmpty() { return mEntries.empty(); }
};
// This code is not naming-standards compliant. Leaving it like this for
// now to make the connection to code in
// BOOL packTEMessage(LLDataPacker &dp) const;
@ -480,12 +488,12 @@ public:
virtual S32 setTEMediaFlags(const U8 te, const U8 flags);
virtual S32 setTEGlow(const U8 te, const F32 glow);
virtual S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID);
virtual S32 setTEMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams);
virtual S32 setTEMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams);
virtual BOOL setMaterial(const U8 material); // returns TRUE if material changed
virtual void setTESelected(const U8 te, bool sel);
LLMaterialPtr getTEMaterialParams(const U8 index);
void copyTEs(const LLPrimitive *primitive);
S32 packTEField(U8 *cur_ptr, U8 *data_ptr, U8 data_size, U8 last_face_index, EMsgVariableType type) const;
BOOL packTEMessage(LLMessageSystem *mesgsys) const;
@ -563,6 +571,8 @@ public:
static LLPCode legacyToPCode(const U8 legacy);
static U8 pCodeToLegacy(const LLPCode pcode);
static bool getTESTAxes(const U8 face, U32* s_axis, U32* t_axis);
BOOL hasRenderMaterialParams() const;
inline static BOOL isPrimitive(const LLPCode pcode);
inline static BOOL isApp(const LLPCode pcode);

View File

@ -4403,6 +4403,7 @@ BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop,
case DAD_GESTURE:
case DAD_MESH:
case DAD_SETTINGS:
case DAD_MATERIAL:
accept = dragItemIntoFolder(inv_item, drop, tooltip_msg);
break;
case DAD_LINK:
@ -6032,6 +6033,7 @@ BOOL LLCallingCardBridge::dragOrDrop(MASK mask, BOOL drop,
case DAD_GESTURE:
case DAD_MESH:
case DAD_SETTINGS:
case DAD_MATERIAL:
{
LLInventoryItem* inv_item = (LLInventoryItem*)cargo_data;
const LLPermissions& perm = inv_item->getPermissions();

View File

@ -156,6 +156,7 @@ BOOL LLGroupDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
case DAD_CALLINGCARD:
case DAD_MESH:
case DAD_SETTINGS:
case DAD_MATERIAL:
{
LLViewerInventoryItem* inv_item = (LLViewerInventoryItem*)cargo_data;
if(gInventory.getItem(inv_item->getUUID())

View File

@ -704,6 +704,7 @@ BOOL LLTaskCategoryBridge::dragOrDrop(MASK mask, BOOL drop,
case DAD_CALLINGCARD:
case DAD_MESH:
case DAD_SETTINGS:
case DAD_MATERIAL:
accept = LLToolDragAndDrop::isInventoryDropAcceptable(object, (LLViewerInventoryItem*)cargo_data);
if(accept && drop)
{

View File

@ -256,7 +256,8 @@ LLToolDragAndDrop::LLDragAndDropDictionary::LLDragAndDropDictionary()
// |-------------------------------|----------------------------------------------|-----------------------------------------------|---------------------------------------------------|--------------------------------|
addEntry(DAD_NONE, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL));
addEntry(DAD_TEXTURE, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dTextureObject, &LLToolDragAndDrop::dad3dNULL));
addEntry(DAD_SOUND, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
addEntry(DAD_MATERIAL, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dMaterialObject, &LLToolDragAndDrop::dad3dNULL));
addEntry(DAD_SOUND, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
addEntry(DAD_CALLINGCARD, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
addEntry(DAD_LANDMARK, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
addEntry(DAD_SCRIPT, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dRezScript, &LLToolDragAndDrop::dad3dNULL));
@ -271,6 +272,7 @@ LLToolDragAndDrop::LLDragAndDropDictionary::LLDragAndDropDictionary()
addEntry(DAD_LINK, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL));
addEntry(DAD_MESH, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dMeshObject, &LLToolDragAndDrop::dad3dNULL));
addEntry(DAD_SETTINGS, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
// TODO: animation on self could play it? edit it?
// TODO: gesture on self could play it? edit it?
};
@ -1062,6 +1064,66 @@ void LLToolDragAndDrop::dropTextureAllFaces(LLViewerObject* hit_obj,
hit_obj->sendTEUpdate();
}
void LLToolDragAndDrop::dropMaterialOneFace(LLViewerObject* hit_obj,
S32 hit_face,
LLInventoryItem* item,
LLToolDragAndDrop::ESource source,
const LLUUID& src_id)
{
if (hit_face == -1) return;
if (!item || item->getInventoryType() != LLInventoryType::IT_MATERIAL)
{
LL_WARNS() << "LLToolDragAndDrop::dropTextureOneFace no material item." << LL_ENDL;
return;
}
LLUUID asset_id = item->getAssetUUID();
BOOL success = handleDropTextureProtections(hit_obj, item, source, src_id);
if (!success)
{
return;
}
LLTextureEntry* tep = hit_obj ? (hit_obj->getTE(hit_face)) : NULL;
hit_obj->setRenderMaterialID(hit_face, asset_id);
dialog_refresh_all();
// send the update to the simulator
hit_obj->sendTEUpdate();
}
void LLToolDragAndDrop::dropMaterialAllFaces(LLViewerObject* hit_obj,
LLInventoryItem* item,
LLToolDragAndDrop::ESource source,
const LLUUID& src_id)
{
if (!item || item->getInventoryType() != LLInventoryType::IT_MATERIAL)
{
LL_WARNS() << "LLToolDragAndDrop::dropTextureAllFaces no material item." << LL_ENDL;
return;
}
LLUUID asset_id = item->getAssetUUID();
BOOL success = handleDropTextureProtections(hit_obj, item, source, src_id);
if (!success)
{
return;
}
S32 num_faces = hit_obj->getNumTEs();
for (S32 face = 0; face < num_faces; face++)
{
// update viewer side material in anticipation of update from simulator
hit_obj->setRenderMaterialID(face, asset_id);
dialog_refresh_all();
}
// send the update to the simulator
hit_obj->sendTEUpdate();
}
void LLToolDragAndDrop::dropMesh(LLViewerObject* hit_obj,
LLInventoryItem* item,
LLToolDragAndDrop::ESource source,
@ -1628,6 +1690,7 @@ bool LLToolDragAndDrop::handleGiveDragAndDrop(LLUUID dest_agent, LLUUID session_
case DAD_MESH:
case DAD_CATEGORY:
case DAD_SETTINGS:
case DAD_MATERIAL:
{
LLInventoryObject* inv_obj = (LLInventoryObject*)cargo_data;
if(gInventory.getCategory(inv_obj->getUUID()) || (gInventory.getItem(inv_obj->getUUID())
@ -1982,6 +2045,17 @@ EAcceptance LLToolDragAndDrop::dad3dApplyToObject(
dropTextureOneFace(obj, face, item, mSource, mSourceID);
}
}
else if (cargo_type == DAD_MATERIAL)
{
if ((mask & MASK_SHIFT))
{
dropMaterialAllFaces(obj, item, mSource, mSourceID);
}
else
{
dropMaterialOneFace(obj, face, item, mSource, mSourceID);
}
}
else if (cargo_type == DAD_MESH)
{
dropMesh(obj, item, mSource, mSourceID);
@ -2010,6 +2084,12 @@ EAcceptance LLToolDragAndDrop::dad3dTextureObject(
return dad3dApplyToObject(obj, face, mask, drop, DAD_TEXTURE);
}
EAcceptance LLToolDragAndDrop::dad3dMaterialObject(
LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
{
return dad3dApplyToObject(obj, face, mask, drop, DAD_MATERIAL);
}
EAcceptance LLToolDragAndDrop::dad3dMeshObject(
LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
{

View File

@ -168,6 +168,8 @@ protected:
MASK mask, BOOL drop);
EAcceptance dad3dTextureObject(LLViewerObject* obj, S32 face,
MASK mask, BOOL drop);
EAcceptance dad3dMaterialObject(LLViewerObject* obj, S32 face,
MASK mask, BOOL drop);
EAcceptance dad3dMeshObject(LLViewerObject* obj, S32 face,
MASK mask, BOOL drop);
// EAcceptance dad3dTextureSelf(LLViewerObject* obj, S32 face,
@ -249,6 +251,14 @@ public:
LLInventoryItem* item,
ESource source,
const LLUUID& src_id);
static void dropMaterialOneFace(LLViewerObject* hit_obj, S32 hit_face,
LLInventoryItem* item,
ESource source,
const LLUUID& src_id);
static void dropMaterialAllFaces(LLViewerObject* hit_obj,
LLInventoryItem* item,
ESource source,
const LLUUID& src_id);
static void dropMesh(LLViewerObject* hit_obj,
LLInventoryItem* item,
ESource source,

View File

@ -6991,6 +6991,61 @@ LLVOAvatar* LLViewerObject::getAvatar() const
return NULL;
}
bool LLViewerObject::hasRenderMaterialParams() const
{
return getParameterEntryInUse(LLNetworkData::PARAMS_RENDER_MATERIAL);
}
void LLViewerObject::setHasRenderMaterialParams(bool has_materials)
{
bool had_materials = hasRenderMaterialParams();
if (had_materials != has_materials)
{
if (has_materials)
{
setParameterEntryInUse(LLNetworkData::PARAMS_RENDER_MATERIAL, TRUE, true);
}
else
{
setParameterEntryInUse(LLNetworkData::PARAMS_RENDER_MATERIAL, FALSE, true);
}
}
}
const LLUUID& LLViewerObject::getRenderMaterialID(U8 te) const
{
LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL);
if (param_block)
{
return param_block->getMaterial(te);
}
return LLUUID::null;
}
void LLViewerObject::setRenderMaterialID(U8 te, const LLUUID& id)
{
if (id.notNull())
{
setHasRenderMaterialParams(true);
}
LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL);
if (param_block)
{
param_block->setMaterial(te, id);
if (param_block->isEmpty())
{ // might be empty if id is null
setHasRenderMaterialParams(false);
}
else
{
parameterChanged(LLNetworkData::PARAMS_RENDER_MATERIAL, true);
}
}
}
class ObjectPhysicsProperties : public LLHTTPNode
{

View File

@ -179,6 +179,13 @@ public:
const std::string& getAttachmentItemName() const;
virtual LLVOAvatar* getAvatar() const; //get the avatar this object is attached to, or NULL if object is not an attachment
bool hasRenderMaterialParams() const;
void setHasRenderMaterialParams(bool has_params);
const LLUUID& getRenderMaterialID(U8 te) const;
void setRenderMaterialID(U8 te, const LLUUID& id);
virtual BOOL isHUDAttachment() const { return FALSE; }
virtual BOOL isTempAttachment() const;

View File

@ -879,6 +879,7 @@ BOOL LLViewerTextEditor::handleDragAndDrop(S32 x, S32 y, MASK mask,
case DAD_ANIMATION:
case DAD_GESTURE:
case DAD_MESH:
case DAD_MATERIAL:
{
supported = true;
break;

View File

@ -2162,6 +2162,7 @@ void LLVOVolume::setNumTEs(const U8 num_tes)
return ;
}
//virtual
void LLVOVolume::changeTEImage(S32 index, LLViewerTexture* imagep)
{
@ -3501,6 +3502,11 @@ F32 LLVOVolume::getLightCutoff() const
}
}
BOOL LLVOVolume::isReflectionProbe() const
{
return getParameterEntryInUse(LLNetworkData::PARAMS_REFLECTION_PROBE);
}
void LLVOVolume::setIsReflectionProbe(BOOL is_probe)
{
BOOL was_probe = isReflectionProbe();
@ -3571,25 +3577,6 @@ void LLVOVolume::setReflectionProbeIsDynamic(bool is_dynamic)
}
}
BOOL LLVOVolume::isReflectionProbe() const
{
// HACK - make this object a Reflection Probe if a certain UUID is detected
static LLCachedControl<std::string> reflection_probe_id(gSavedSettings, "RenderReflectionProbeTextureHackID", "");
LLUUID probe_id(reflection_probe_id);
for (U8 i = 0; i < getNumTEs(); ++i)
{
if (getTE(i)->getID() == probe_id)
{
return true;
}
}
// END HACK
return getParameterEntryInUse(LLNetworkData::PARAMS_REFLECTION_PROBE);
}
F32 LLVOVolume::getReflectionProbeAmbiance() const
{
const LLReflectionProbeParams* param_block = (const LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);

View File

@ -284,7 +284,7 @@ public:
F32 getLightRadius() const;
F32 getLightFalloff(const F32 fudge_factor = 1.f) const;
F32 getLightCutoff() const;
// Reflection Probes
void setIsReflectionProbe(BOOL is_probe);
void setReflectionProbeAmbiance(F32 ambiance);