Merge pull request #48 from secondlife/SL-18820
Sl 18820: Build floater should preserve GLTF transforms when changing the PBR materialmaster
commit
7e1f4e4cc7
|
|
@ -98,6 +98,29 @@ LLGLTFMaterial& LLGLTFMaterial::operator=(const LLGLTFMaterial& rhs)
|
|||
return *this;
|
||||
}
|
||||
|
||||
bool LLGLTFMaterial::operator==(const LLGLTFMaterial& rhs) const
|
||||
{
|
||||
return mBaseColorId == rhs.mBaseColorId &&
|
||||
mNormalId == rhs.mNormalId &&
|
||||
mMetallicRoughnessId == rhs.mMetallicRoughnessId &&
|
||||
mEmissiveId == rhs.mEmissiveId &&
|
||||
|
||||
mBaseColor == rhs.mBaseColor &&
|
||||
mEmissiveColor == rhs.mEmissiveColor &&
|
||||
|
||||
mMetallicFactor == rhs.mMetallicFactor &&
|
||||
mRoughnessFactor == rhs.mRoughnessFactor &&
|
||||
mAlphaCutoff == rhs.mAlphaCutoff &&
|
||||
|
||||
mDoubleSided == rhs.mDoubleSided &&
|
||||
mAlphaMode == rhs.mAlphaMode &&
|
||||
|
||||
mTextureTransform == rhs.mTextureTransform &&
|
||||
|
||||
mOverrideDoubleSided == rhs.mOverrideDoubleSided &&
|
||||
mOverrideAlphaMode == rhs.mOverrideAlphaMode;
|
||||
}
|
||||
|
||||
bool LLGLTFMaterial::fromJSON(const std::string& json, std::string& warn_msg, std::string& error_msg)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
|
|
@ -365,6 +388,28 @@ void LLGLTFMaterial::writeToTexture(tinygltf::Model& model, T& texture_info, Tex
|
|||
texture_info.extensions[GLTF_FILE_EXTENSION_TRANSFORM] = tinygltf::Value(transform_map);
|
||||
}
|
||||
|
||||
bool LLGLTFMaterial::setBaseMaterial()
|
||||
{
|
||||
const LLGLTFMaterial old_override = *this;
|
||||
*this = sDefault;
|
||||
setBaseMaterial(old_override);
|
||||
return *this != old_override;
|
||||
}
|
||||
|
||||
bool LLGLTFMaterial::isClearedForBaseMaterial()
|
||||
{
|
||||
LLGLTFMaterial cleared_override = sDefault;
|
||||
cleared_override.setBaseMaterial(*this);
|
||||
return *this == cleared_override;
|
||||
}
|
||||
|
||||
// For material overrides only. Copies transforms from the old override.
|
||||
void LLGLTFMaterial::setBaseMaterial(const LLGLTFMaterial& old_override_mat)
|
||||
{
|
||||
mTextureTransform = old_override_mat.mTextureTransform;
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void LLGLTFMaterial::hackOverrideUUID(LLUUID& id)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -71,6 +71,8 @@ public:
|
|||
LLGLTFMaterial(const LLGLTFMaterial& rhs);
|
||||
|
||||
LLGLTFMaterial& operator=(const LLGLTFMaterial& rhs);
|
||||
bool operator==(const LLGLTFMaterial& rhs) const;
|
||||
bool operator!=(const LLGLTFMaterial& rhs) const { return !(*this == rhs); }
|
||||
|
||||
LLUUID mBaseColorId;
|
||||
LLUUID mNormalId;
|
||||
|
|
@ -101,7 +103,6 @@ public:
|
|||
md5.finalize();
|
||||
LLUUID id;
|
||||
md5.raw_digest(id.mData);
|
||||
// *TODO: Hash the overrides
|
||||
return id;
|
||||
}
|
||||
|
||||
|
|
@ -181,6 +182,12 @@ public:
|
|||
|
||||
void applyOverride(const LLGLTFMaterial& override_mat);
|
||||
|
||||
// For material overrides only. Clears most properties to
|
||||
// default/fallthrough, but preserves the transforms.
|
||||
bool setBaseMaterial();
|
||||
// True if setBaseMaterial() was just called
|
||||
bool isClearedForBaseMaterial();
|
||||
|
||||
private:
|
||||
|
||||
template<typename T>
|
||||
|
|
@ -188,5 +195,7 @@ private:
|
|||
|
||||
template<typename T>
|
||||
void writeToTexture(tinygltf::Model& model, T& texture_info, TextureInfo texture_info_id, const LLUUID& texture_id) const;
|
||||
|
||||
void setBaseMaterial(const LLGLTFMaterial& old_override_mat);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -514,15 +514,15 @@ S32 LLTextureEntry::setBumpShiny(U8 bump_shiny)
|
|||
return TEM_CHANGE_NONE;
|
||||
}
|
||||
|
||||
void LLTextureEntry::setGLTFMaterial(LLGLTFMaterial* material)
|
||||
void LLTextureEntry::setGLTFMaterial(LLGLTFMaterial* material, bool local_origin)
|
||||
{
|
||||
if (material != getGLTFMaterial())
|
||||
{
|
||||
// assert on precondtion:
|
||||
// whether or not mGLTFMaterial is null, any existing override should have been nulled out
|
||||
// whether or not mGLTFMaterial is null, any existing override should have been cleared
|
||||
// before calling setGLTFMaterial
|
||||
// NOTE: if you're hitting this assert, try to make sure calling code is using LLViewerObject::setRenderMaterialID
|
||||
llassert(getGLTFMaterialOverride() == nullptr);
|
||||
llassert(!local_origin || getGLTFMaterialOverride() == nullptr || getGLTFMaterialOverride()->isClearedForBaseMaterial());
|
||||
|
||||
mGLTFMaterial = material;
|
||||
if (mGLTFMaterial == nullptr)
|
||||
|
|
@ -538,6 +538,27 @@ void LLTextureEntry::setGLTFMaterialOverride(LLGLTFMaterial* mat)
|
|||
mGLTFMaterialOverrides = mat;
|
||||
}
|
||||
|
||||
S32 LLTextureEntry::setBaseMaterial()
|
||||
{
|
||||
S32 changed = TEM_CHANGE_NONE;
|
||||
|
||||
if (mGLTFMaterialOverrides)
|
||||
{
|
||||
if (mGLTFMaterialOverrides->setBaseMaterial())
|
||||
{
|
||||
changed = TEM_CHANGE_TEXTURE;
|
||||
}
|
||||
|
||||
if (LLGLTFMaterial::sDefault == *mGLTFMaterialOverrides)
|
||||
{
|
||||
mGLTFMaterialOverrides = nullptr;
|
||||
changed = TEM_CHANGE_TEXTURE;
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
LLGLTFMaterial* LLTextureEntry::getGLTFRenderMaterial() const
|
||||
{
|
||||
if (mGLTFRenderMaterial.notNull())
|
||||
|
|
@ -545,7 +566,7 @@ LLGLTFMaterial* LLTextureEntry::getGLTFRenderMaterial() const
|
|||
return mGLTFRenderMaterial;
|
||||
}
|
||||
|
||||
llassert(getGLTFMaterialOverride() == nullptr);
|
||||
llassert(getGLTFMaterialOverride() == nullptr || getGLTFMaterialOverride()->isClearedForBaseMaterial());
|
||||
return getGLTFMaterial();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -195,12 +195,16 @@ public:
|
|||
enum { MF_NONE = 0x0, MF_HAS_MEDIA = 0x1 };
|
||||
|
||||
// GLTF asset
|
||||
void setGLTFMaterial(LLGLTFMaterial* material);
|
||||
void setGLTFMaterial(LLGLTFMaterial* material, bool local_origin = true);
|
||||
LLGLTFMaterial* getGLTFMaterial() const { return mGLTFMaterial; }
|
||||
|
||||
// GLTF override
|
||||
LLGLTFMaterial* getGLTFMaterialOverride() const { return mGLTFMaterialOverrides; }
|
||||
void setGLTFMaterialOverride(LLGLTFMaterial* mat);
|
||||
// Clear most overrides so the render material better matches the material
|
||||
// ID (preserve transforms). If the overrides become passthrough, set the
|
||||
// overrides to nullptr.
|
||||
S32 setBaseMaterial();
|
||||
|
||||
// GLTF render material
|
||||
// nuanced behavior here -- if there is no render material, fall back to getGLTFMaterial, but ONLY for the getter, not the setter
|
||||
|
|
|
|||
|
|
@ -404,9 +404,19 @@ void LLGLTFMaterialList::queueModify(const LLUUID& id, S32 side, const LLGLTFMat
|
|||
}
|
||||
}
|
||||
|
||||
void LLGLTFMaterialList::queueApply(const LLUUID& object_id, S32 side, const LLUUID& asset_id)
|
||||
void LLGLTFMaterialList::queueApply(const LLViewerObject* obj, S32 side, const LLUUID& asset_id)
|
||||
{
|
||||
sApplyQueue.push_back({ object_id, side, asset_id});
|
||||
const LLGLTFMaterial* material_override = obj->getTE(side)->getGLTFMaterialOverride();
|
||||
if (material_override)
|
||||
{
|
||||
LLGLTFMaterial* cleared_override = new LLGLTFMaterial(*material_override);
|
||||
cleared_override->setBaseMaterial();
|
||||
sApplyQueue.push_back({ obj->getID(), side, asset_id, cleared_override });
|
||||
}
|
||||
else
|
||||
{
|
||||
sApplyQueue.push_back({ obj->getID(), side, asset_id, nullptr });
|
||||
}
|
||||
}
|
||||
|
||||
void LLGLTFMaterialList::queueUpdate(const LLSD& data)
|
||||
|
|
@ -436,6 +446,11 @@ void LLGLTFMaterialList::flushUpdates(void(*done_callback)(bool))
|
|||
{
|
||||
data[i]["gltf_json"] = e.override_data.asJSON();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Clear all overrides
|
||||
data[i]["gltf_json"] = "";
|
||||
}
|
||||
|
||||
llassert(is_valid_update(data[i]));
|
||||
++i;
|
||||
|
|
@ -447,7 +462,15 @@ void LLGLTFMaterialList::flushUpdates(void(*done_callback)(bool))
|
|||
data[i]["object_id"] = e.object_id;
|
||||
data[i]["side"] = e.side;
|
||||
data[i]["asset_id"] = e.asset_id;
|
||||
data[i]["gltf_json"] = ""; // null out any existing overrides when applying a material asset
|
||||
if (e.override_data)
|
||||
{
|
||||
data[i]["gltf_json"] = e.override_data->asJSON();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Clear all overrides
|
||||
data[i]["gltf_json"] = "";
|
||||
}
|
||||
|
||||
llassert(is_valid_update(data[i]));
|
||||
++i;
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ public:
|
|||
// side - TexureEntry index to modify, or -1 for all sides
|
||||
// mat - material to apply as override, or nullptr to remove existing overrides and revert to asset
|
||||
//
|
||||
// NOTE: do not use to revert to asset when applying a new asset id, use queueApplyMaterialAsset below
|
||||
// NOTE: do not use to revert to asset when applying a new asset id, use queueApply below
|
||||
static void queueModify(const LLUUID& id, S32 side, const LLGLTFMaterial* mat);
|
||||
|
||||
// Queue an application of a material asset we want to send to the simulator. Call "flushUpdates" to flush pending updates.
|
||||
|
|
@ -67,8 +67,8 @@ public:
|
|||
// side - TextureEntry index to apply material to, or -1 for all sides
|
||||
// asset_id - ID of material asset to apply, or LLUUID::null to disassociate current material asset
|
||||
//
|
||||
// NOTE: implicitly removes any override data if present
|
||||
static void queueApply(const LLUUID& object_id, S32 side, const LLUUID& asset_id);
|
||||
// NOTE: Implicitly clears most override data if present
|
||||
static void queueApply(const LLViewerObject* obj, S32 side, const LLUUID& asset_id);
|
||||
|
||||
// flush pending material updates to the simulator
|
||||
// Automatically called once per frame, but may be called explicitly
|
||||
|
|
@ -136,6 +136,7 @@ protected:
|
|||
LLUUID object_id;
|
||||
S32 side = -1;
|
||||
LLUUID asset_id;
|
||||
LLPointer<LLGLTFMaterial> override_data;
|
||||
};
|
||||
|
||||
typedef std::list<ApplyMaterialAssetData> apply_queue_t;
|
||||
|
|
|
|||
|
|
@ -4527,8 +4527,8 @@ void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te)
|
|||
tep->setGLTFRenderMaterial(nullptr);
|
||||
tep->setGLTFMaterialOverride(nullptr);
|
||||
|
||||
// blank out any override data on the server
|
||||
LLGLTFMaterialList::queueApply(objectp->getID(), te, LLUUID::null);
|
||||
// blank out most override data on the server
|
||||
LLGLTFMaterialList::queueApply(objectp, te, LLUUID::null);
|
||||
}
|
||||
|
||||
// Texture map
|
||||
|
|
|
|||
|
|
@ -1806,11 +1806,9 @@ void LLObjectSelection::applyNoCopyPbrMaterialToTEs(LLViewerInventoryItem* item)
|
|||
}
|
||||
|
||||
// apply texture for the selected faces
|
||||
// blank out most override data on the server
|
||||
//add(LLStatViewer::EDIT_TEXTURE, 1);
|
||||
object->setRenderMaterialID(te, asset_id, false /*will be sent later*/);
|
||||
|
||||
// blank out any override data on the server
|
||||
LLGLTFMaterialList::queueApply(object->getID(), te, asset_id);
|
||||
object->setRenderMaterialID(te, asset_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1949,10 +1947,8 @@ void LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id)
|
|||
objectp->setParameterEntryInUse(LLNetworkData::PARAMS_RENDER_MATERIAL, TRUE, false /*prevent an update*/);
|
||||
}
|
||||
|
||||
objectp->setRenderMaterialID(te, asset_id, false /*prevent an update to prevent a race condition*/);
|
||||
|
||||
// blank out any override data on the server
|
||||
LLGLTFMaterialList::queueApply(objectp->getID(), te, asset_id);
|
||||
// Blank out most override data on the object and send to server
|
||||
objectp->setRenderMaterialID(te, asset_id);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -2223,17 +2219,12 @@ void LLSelectMgr::selectionRevertGLTFMaterials()
|
|||
&& asset_id.notNull())
|
||||
{
|
||||
// Restore overrides
|
||||
LLSD overrides;
|
||||
overrides["object_id"] = objectp->getID();
|
||||
overrides["side"] = te;
|
||||
|
||||
overrides["gltf_json"] = nodep->mSavedGLTFOverrideMaterials[te]->asJSON();
|
||||
LLGLTFMaterialList::queueUpdate(overrides);
|
||||
LLGLTFMaterialList::queueModify(objectp->getID(), te, nodep->mSavedGLTFOverrideMaterials[te]);
|
||||
}
|
||||
else
|
||||
{
|
||||
//blank override out
|
||||
LLGLTFMaterialList::queueApply(objectp->getID(), te, asset_id);
|
||||
LLGLTFMaterialList::queueApply(objectp, te, asset_id);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7163,11 +7163,11 @@ void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool updat
|
|||
{
|
||||
// implementation is delicate
|
||||
|
||||
// if update is bound for server, should always null out GLTFRenderMaterial and GLTFMaterialOverride even if ids haven't changed
|
||||
// if update is bound for server, should always null out GLTFRenderMaterial and clear GLTFMaterialOverride even if ids haven't changed
|
||||
// (the case where ids haven't changed indicates the user has reapplied the original material, in which case overrides should be dropped)
|
||||
// otherwise, should only null out where ids have changed
|
||||
// otherwise, should only null out the render material where ids or overrides have changed
|
||||
// (the case where ids have changed but overrides are still present is from unsynchronized updates from the simulator)
|
||||
|
||||
|
||||
S32 start_idx = 0;
|
||||
S32 end_idx = getNumTEs();
|
||||
|
||||
|
|
@ -7180,6 +7180,13 @@ void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool updat
|
|||
start_idx = llmax(start_idx, 0);
|
||||
end_idx = llmin(end_idx, (S32) getNumTEs());
|
||||
|
||||
LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL);
|
||||
if (!param_block && id.notNull())
|
||||
{ // block doesn't exist, but it will need to
|
||||
param_block = (LLRenderMaterialParams*)createNewParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL)->data;
|
||||
}
|
||||
|
||||
|
||||
// update local state
|
||||
for (S32 te = start_idx; te < end_idx; ++te)
|
||||
{
|
||||
|
|
@ -7192,17 +7199,27 @@ void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool updat
|
|||
new_material = gGLTFMaterialList.getMaterial(id);
|
||||
}
|
||||
|
||||
bool material_changed = tep->getGLTFMaterial() != new_material;
|
||||
bool material_changed = !param_block || id != param_block->getMaterial(te);
|
||||
|
||||
if (update_server)
|
||||
{
|
||||
// Clear most overrides so the render material better matches the material
|
||||
// ID (preserve transforms). If overrides become passthrough, set the overrides
|
||||
// to nullptr.
|
||||
if (tep->setBaseMaterial())
|
||||
{
|
||||
material_changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (update_server || material_changed)
|
||||
{
|
||||
tep->setGLTFRenderMaterial(nullptr);
|
||||
tep->setGLTFMaterialOverride(nullptr);
|
||||
}
|
||||
|
||||
if (new_material != tep->getGLTFMaterial())
|
||||
{
|
||||
tep->setGLTFMaterial(new_material);
|
||||
tep->setGLTFMaterial(new_material, !update_server);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -7215,17 +7232,14 @@ void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool updat
|
|||
// update via ModifyMaterialParams cap (server will echo back changes)
|
||||
for (S32 te = start_idx; te < end_idx; ++te)
|
||||
{
|
||||
LLGLTFMaterialList::queueApply(getID(), te, id);
|
||||
// This sends a cleared version of this object's current material
|
||||
// override, but the override should already be cleared due to
|
||||
// calling setBaseMaterial above.
|
||||
LLGLTFMaterialList::queueApply(this, te, id);
|
||||
}
|
||||
}
|
||||
|
||||
// predictively update LLRenderMaterialParams (don't wait for server)
|
||||
LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL);
|
||||
if (!param_block && id.notNull())
|
||||
{ // block doesn't exist, but it will need to
|
||||
param_block = (LLRenderMaterialParams*)createNewParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL)->data;
|
||||
}
|
||||
|
||||
if (param_block)
|
||||
{ // update existing parameter block
|
||||
for (S32 te = start_idx; te < end_idx; ++te)
|
||||
|
|
|
|||
|
|
@ -188,7 +188,7 @@ public:
|
|||
// set the RenderMaterialID for the given TextureEntry
|
||||
// te - TextureEntry index to set, or -1 for all TEs
|
||||
// id - asset id of material asset
|
||||
// update_server - if true, will send updates to server
|
||||
// update_server - if true, will send updates to server and clear most overrides
|
||||
void setRenderMaterialID(S32 te, const LLUUID& id, bool update_server = true);
|
||||
void setRenderMaterialIDs(const LLUUID& id);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue