SL-19169 Local material updates aren't applied with non-default transforms

master
Andrey Kleshchev 2023-03-23 01:18:07 +02:00 committed by akleshchev
parent 02091a0496
commit d423263d54
8 changed files with 88 additions and 6 deletions

View File

@ -41,6 +41,8 @@ namespace tinygltf
class Model;
}
class LLTextureEntry;
class LLGLTFMaterial : public LLRefCount
{
public:
@ -193,6 +195,11 @@ public:
// True if setBaseMaterial() was just called
bool isClearedForBaseMaterial();
// For local materials, they have to keep track of where
// they are assigned to for full updates
virtual void addTextureEntry(LLTextureEntry* te) {};
virtual void removeTextureEntry(LLTextureEntry* te) {};
private:
template<typename T>
void setFromTexture(const tinygltf::Model& model, const T& texture_info, TextureInfo texture_info_id);

View File

@ -112,7 +112,15 @@ LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs)
mMaterialID = rhs.mMaterialID;
if (mGLTFMaterial)
{
mGLTFMaterial->removeTextureEntry(this);
}
mGLTFMaterial = rhs.mGLTFMaterial;
if (mGLTFMaterial)
{
mGLTFMaterial->addTextureEntry(this);
}
if (rhs.mGLTFMaterialOverrides.notNull())
{
@ -155,6 +163,12 @@ LLTextureEntry::~LLTextureEntry()
delete mMediaEntry;
mMediaEntry = NULL;
}
if (mGLTFMaterial)
{
mGLTFMaterial->removeTextureEntry(this);
mGLTFMaterial = NULL;
}
}
bool LLTextureEntry::operator!=(const LLTextureEntry &rhs) const
@ -524,7 +538,20 @@ void LLTextureEntry::setGLTFMaterial(LLGLTFMaterial* material, bool local_origin
// NOTE: if you're hitting this assert, try to make sure calling code is using LLViewerObject::setRenderMaterialID
llassert(!local_origin || getGLTFMaterialOverride() == nullptr || getGLTFMaterialOverride()->isClearedForBaseMaterial());
if (mGLTFMaterial)
{
// Local materials have to keep track
// due to update mechanics
mGLTFMaterial->removeTextureEntry(this);
}
mGLTFMaterial = material;
if (mGLTFMaterial)
{
mGLTFMaterial->addTextureEntry(this);
}
if (mGLTFMaterial == nullptr)
{
setGLTFRenderMaterial(nullptr);

View File

@ -46,6 +46,18 @@ LLFetchedGLTFMaterial::~LLFetchedGLTFMaterial()
}
LLFetchedGLTFMaterial& LLFetchedGLTFMaterial::operator=(const LLFetchedGLTFMaterial& rhs)
{
LLGLTFMaterial::operator =(rhs);
mBaseColorTexture = rhs.mBaseColorTexture;
mNormalTexture = rhs.mNormalTexture;
mMetallicRoughnessTexture = rhs.mMetallicRoughnessTexture;
mEmissiveTexture = rhs.mEmissiveTexture;
return *this;
}
void LLFetchedGLTFMaterial::bind(LLViewerTexture* media_tex)
{
// glTF 2.0 Specification 3.9.4. Alpha Coverage

View File

@ -39,6 +39,8 @@ public:
LLFetchedGLTFMaterial();
virtual ~LLFetchedGLTFMaterial();
LLFetchedGLTFMaterial& operator=(const LLFetchedGLTFMaterial& rhs);
// If this material is loaded, fire the given function
void onMaterialComplete(std::function<void()> material_complete);

View File

@ -45,6 +45,7 @@
#include "llmaterialmgr.h"
#include "llnotificationsutil.h"
#include "llscrolllistctrl.h"
#include "lltextureentry.h"
#include "lltinygltfhelper.h"
#include "llviewertexture.h"
@ -118,6 +119,15 @@ S32 LLLocalGLTFMaterial::getIndexInFile() const
return mMaterialIndex;
}
void LLLocalGLTFMaterial::addTextureEntry(LLTextureEntry* te)
{
mTextureEntires.insert(te);
}
void LLLocalGLTFMaterial::removeTextureEntry(LLTextureEntry* te)
{
mTextureEntires.erase(te);
}
/* update functions */
bool LLLocalGLTFMaterial::updateSelf()
{
@ -154,6 +164,27 @@ bool LLLocalGLTFMaterial::updateSelf()
gGLTFMaterialList.addMaterial(mWorldID, this);
mUpdateRetries = LL_LOCAL_UPDATE_RETRIES;
for (LLTextureEntry* entry : mTextureEntires)
{
// Normally a change in applied material id is supposed to
// drop overrides thus reset material, but local materials
// currently reuse their existing asset id, and purpose is
// to preview how material will work in-world, overrides
// included, so do an override to render update instead.
LLGLTFMaterial* override_mat = entry->getGLTFMaterialOverride();
if (override_mat)
{
// do not create a new material, reuse existing pointer
LLFetchedGLTFMaterial* render_mat = (LLFetchedGLTFMaterial*)entry->getGLTFRenderMaterial();
if (render_mat)
{
*render_mat = *this;
render_mat->applyOverride(*override_mat);
}
}
}
updated = true;
}

View File

@ -34,6 +34,7 @@
class LLScrollListCtrl;
class LLGLTFMaterial;
class LLViewerObject;
class LLTextureEntry;
class LLLocalGLTFMaterial : public LLFetchedGLTFMaterial
{
@ -48,6 +49,9 @@ public: /* accessors */
LLUUID getWorldID() const;
S32 getIndexInFile() const;
void addTextureEntry(LLTextureEntry* te) override;
void removeTextureEntry(LLTextureEntry* te) override;
public:
bool updateSelf();
@ -77,6 +81,7 @@ private: /* members */
ELinkStatus mLinkStatus;
S32 mUpdateRetries;
S32 mMaterialIndex; // Single file can have more than one
std::set<LLTextureEntry*> mTextureEntires;
};
class LLLocalGLTFMaterialTimer : public LLEventTimer

View File

@ -5368,8 +5368,10 @@ S32 LLViewerObject::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* override_ma
LLFetchedGLTFMaterial* src_mat = (LLFetchedGLTFMaterial*) tep->getGLTFMaterial();
// if override mat exists, we must also have a source mat
if (!src_mat)
{ // we can get into this state if an override has arrived before the viewer has
{
// we can get into this state if an override has arrived before the viewer has
// received or handled an update, return TEM_CHANGE_NONE to signal to LLGLTFMaterialList that it
// should queue the update for later
return retval;
@ -5383,10 +5385,7 @@ S32 LLViewerObject::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* override_ma
tep->setGLTFMaterialOverride(override_mat);
// if override mat exists, we must also have a source mat
llassert(override_mat ? bool(src_mat) : true);
if (override_mat && src_mat)
if (override_mat)
{
LLFetchedGLTFMaterial* render_mat = new LLFetchedGLTFMaterial(*src_mat);
render_mat->applyOverride(*override_mat);

View File

@ -29,7 +29,6 @@
color="DkGray2"
opaque="true"
tab_stop="true"
border="false"
reserve_scroll_corner="false">
<panel
name="panel_material"