summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/llgltfmateriallist.cpp49
-rw-r--r--indra/newview/llgltfmateriallist.h10
-rw-r--r--indra/newview/llviewerobject.cpp5
-rw-r--r--indra/newview/llvovolume.cpp4
4 files changed, 61 insertions, 7 deletions
diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp
index 4861c2a33b..cd60d34d2f 100644
--- a/indra/newview/llgltfmateriallist.cpp
+++ b/indra/newview/llgltfmateriallist.cpp
@@ -43,6 +43,8 @@
#include "json/reader.h"
#include "json/value.h"
+LLGLTFMaterialList gGLTFMaterialList;
+
namespace
{
class LLGLTFMaterialOverrideDispatchHandler : public LLDispatchHandler
@@ -72,24 +74,27 @@ namespace
LL_WARNS() << "LLGLTFMaterialOverrideDispatchHandler: Attempted to read parameter data into LLSD but failed:" << llsdRaw << LL_ENDL;
}
}
+
+ LLUUID object_id = message["object_id"].asUUID();
- LLViewerObject * obj = gObjectList.findObject(message["object_id"].asUUID());
- llassert(obj); // should never get an override for an object we don't know about
+ LLViewerObject * obj = gObjectList.findObject(object_id);
S32 side = message["side"].asInteger();
std::string gltf_json = message["gltf_json"].asString();
std::string warn_msg, error_msg;
LLPointer<LLGLTFMaterial> override_data = new LLGLTFMaterial();
bool success = override_data->fromJSON(gltf_json, warn_msg, error_msg);
+
if (!success)
{
LL_WARNS() << "failed to parse GLTF override data. errors: " << error_msg << " | warnings: " << warn_msg << LL_ENDL;
}
else
{
- if (obj)
+ if (!obj || !obj->setTEGLTFMaterialOverride(side, override_data))
{
- obj->setTEGLTFMaterialOverride(side, override_data);
+ // object not ready to receive override data, queue for later
+ gGLTFMaterialList.queueOverrideUpdate(object_id, side, override_data);
}
}
@@ -99,7 +104,41 @@ namespace
LLGLTFMaterialOverrideDispatchHandler handle_gltf_override_message;
}
-LLGLTFMaterialList gGLTFMaterialList;
+void LLGLTFMaterialList::queueOverrideUpdate(const LLUUID& id, S32 side, LLGLTFMaterial* override_data)
+{
+ override_list_t& overrides = mQueuedOverrides[id];
+
+ if (overrides.size() < side + 1)
+ {
+ overrides.resize(side + 1);
+ }
+
+ overrides[side] = override_data;
+}
+
+void LLGLTFMaterialList::applyQueuedOverrides(LLViewerObject* obj)
+{
+ const LLUUID& id = obj->getID();
+ auto& iter = mQueuedOverrides.find(id);
+
+ if (iter != mQueuedOverrides.end())
+ {
+ override_list_t& overrides = iter->second;
+ for (int i = 0; i < overrides.size(); ++i)
+ {
+ if (overrides[i].notNull())
+ {
+ if (!obj->getTE(i)->getGLTFMaterial())
+ { // object doesn't have its base GLTF material yet, don't apply override (yet)
+ return;
+ }
+ obj->setTEGLTFMaterialOverride(i, overrides[i]);
+ }
+ }
+
+ mQueuedOverrides.erase(iter);
+ }
+}
LLGLTFMaterial* LLGLTFMaterialList::getMaterial(const LLUUID& id)
{
diff --git a/indra/newview/llgltfmateriallist.h b/indra/newview/llgltfmateriallist.h
index 4b905e32c9..ee32dc8825 100644
--- a/indra/newview/llgltfmateriallist.h
+++ b/indra/newview/llgltfmateriallist.h
@@ -48,10 +48,20 @@ public:
void flushMaterials();
static void registerCallbacks();
+
+ // save an override update for later (for example, if an override arrived for an unknown object)
+ void queueOverrideUpdate(const LLUUID& id, S32 side, LLGLTFMaterial* override_data);
+
+ void applyQueuedOverrides(LLViewerObject* obj);
+
private:
typedef std::unordered_map<LLUUID, LLPointer<LLFetchedGLTFMaterial > > uuid_mat_map_t;
uuid_mat_map_t mList;
+ typedef std::vector<LLPointer<LLGLTFMaterial> > override_list_t;
+ typedef std::unordered_map<LLUUID, override_list_t > queued_override_map_t;
+ queued_override_map_t mQueuedOverrides;
+
LLUUID mLastUpdateKey;
};
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 603dcc4fa7..ac519970b7 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -247,6 +247,7 @@ LLViewerObject *LLViewerObject::createObject(const LLUUID &id, const LLPCode pco
LL_WARNS() << "Unknown object pcode " << (S32)pcode << LL_ENDL;
res = NULL; break;
}
+
return res;
}
@@ -5324,8 +5325,8 @@ S32 LLViewerObject::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* override_ma
LLTextureEntry* tep = getTE(te);
if (!tep)
- {
- LL_WARNS() << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL;
+ { // this could happen if the object is not fully formed yet
+ // returning TEM_CHANGE_NONE here signals to LLGLTFMaterialList to queue the override for later
return retval;
}
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index cb58c173d9..aea4353bc8 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -88,6 +88,7 @@
#include "llcallstack.h"
#include "llsculptidsize.h"
#include "llavatarappearancedefines.h"
+#include "llgltfmateriallist.h"
const F32 FORCE_SIMPLE_RENDER_AREA = 512.f;
const F32 FORCE_CULL_AREA = 8.f;
@@ -5823,6 +5824,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
continue;
}
+ // apply any pending material overrides
+ gGLTFMaterialList.applyQueuedOverrides(vobj);
+
std::string vobj_name = llformat("Vol%p", vobj);
bool is_mesh = vobj->isMesh();