From 61967623baaa8988f4f8b48043f79be29452ca80 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 21 Oct 2022 16:34:14 -0500 Subject: [PATCH 1/8] SL-18105 Clean up class1/deferred/materialF.glsl (merge cleanup), make override messaging LLSD where it ought to be and JSON where it ought to be. --- .../shaders/class1/deferred/materialF.glsl | 188 +----------------- indra/newview/llgltfmateriallist.cpp | 70 ++++--- indra/newview/llmaterialeditor.cpp | 40 +--- 3 files changed, 51 insertions(+), 247 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl index 70ae615d46..51a36935f2 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl @@ -23,6 +23,7 @@ * $/LicenseInfo$ */ + /*[EXTRA_CODE_HERE]*/ //class1/deferred/materialF.glsl @@ -37,192 +38,15 @@ out vec4 frag_color; out vec4 frag_data[4]; #endif -#ifdef HAS_SUN_SHADOW -float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen); -#endif - -uniform samplerCube environmentMap; -uniform sampler2D lightFunc; - -// Inputs -uniform vec4 morphFactor; -uniform vec3 camPosLocal; -uniform mat3 env_mat; - -uniform vec3 sun_dir; -uniform vec3 moon_dir; -VARYING vec2 vary_fragcoord; - -VARYING vec3 vary_position; - -uniform mat4 proj_mat; -uniform mat4 inv_proj; -uniform vec2 screen_res; - -uniform vec4 light_position[8]; -uniform vec3 light_direction[8]; -uniform vec4 light_attenuation[8]; -uniform vec3 light_diffuse[8]; - -float getAmbientClamp(); - -vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spec, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight, inout float glare, float ambiance) -{ - // SL-14895 inverted attenuation work-around - // This routine is tweaked to match deferred lighting, but previously used an inverted la value. To reconstruct - // that previous value now that the inversion is corrected, we reverse the calculations in LLPipeline::setupHWLights() - // to recover the `adjusted_radius` value previously being sent as la. - float falloff_factor = (12.0 * fa) - 9.0; - float inverted_la = falloff_factor / la; - // Yes, it makes me want to cry as well. DJH - - vec3 col = vec3(0); - - //get light vector - vec3 lv = lp.xyz - v; - - //get distance - float dist = length(lv); - float da = 1.0; - - dist /= inverted_la; - - if (dist > 0.0 && inverted_la > 0.0) - { - //normalize light vector - lv = normalize(lv); - - //distance attenuation - float dist_atten = clamp(1.0 - (dist - 1.0*(1.0 - fa)) / fa, 0.0, 1.0); - dist_atten *= dist_atten; - dist_atten *= 2.0f; - - if (dist_atten <= 0.0) - { - return col; - } - - // spotlight coefficient. - float spot = max(dot(-ln, lv), is_pointlight); - da *= spot*spot; // GL_SPOT_EXPONENT=2 - - //angular attenuation - da *= dot(n, lv); - - float lit = 0.0f; - - float amb_da = ambiance; - if (da >= 0) - { - lit = max(da * dist_atten, 0.0); - col = lit * light_col * diffuse; - amb_da += (da*0.5 + 0.5) * ambiance; - } - amb_da += (da*da*0.5 + 0.5) * ambiance; - amb_da *= dist_atten; - amb_da = min(amb_da, 1.0f - lit); - - // SL-10969 need to see why these are blown out - //col.rgb += amb_da * light_col * diffuse; - - if (spec.a > 0.0) - { - //vec3 ref = dot(pos+lv, norm); - vec3 h = normalize(lv + npos); - float nh = dot(n, h); - float nv = dot(n, npos); - float vh = dot(npos, h); - float sa = nh; - float fres = pow(1 - dot(h, npos), 5)*0.4 + 0.5; - - float gtdenom = 2 * nh; - float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh)); - - if (nh > 0.0) - { - float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt / (nh*da); - vec3 speccol = lit*scol*light_col.rgb*spec.rgb; - speccol = clamp(speccol, vec3(0), vec3(1)); - col += speccol; - - float cur_glare = max(speccol.r, speccol.g); - cur_glare = max(cur_glare, speccol.b); - glare = max(glare, speccol.r); - glare += max(cur_glare, 0.0); - } - } - } - - return max(col, vec3(0.0, 0.0, 0.0)); -} - -#else -#ifdef DEFINE_GL_FRAGCOLOR -out vec4 frag_data[3]; -#else -#define frag_data gl_FragData -#endif -#endif - -uniform sampler2D diffuseMap; //always in sRGB space - -#ifdef HAS_NORMAL_MAP -uniform sampler2D bumpMap; -#endif - -#ifdef HAS_SPECULAR_MAP -uniform sampler2D specularMap; - -VARYING vec2 vary_texcoord2; -#endif - -uniform float env_intensity; -uniform vec4 specular_color; // specular color RGB and specular exponent (glossiness) in alpha - -#ifdef HAS_ALPHA_MASK -uniform float minimum_alpha; -#endif - -#ifdef HAS_NORMAL_MAP -VARYING vec3 vary_mat0; -VARYING vec3 vary_mat1; -VARYING vec3 vary_mat2; -VARYING vec2 vary_texcoord1; -#else -VARYING vec3 vary_normal; -#endif - -VARYING vec4 vertex_color; -VARYING vec2 vary_texcoord0; - -vec2 encode_normal(vec3 n); - void main() { - vec2 pos_screen = vary_texcoord0.xy; - - vec4 diffcol = texture2D(diffuseMap, vary_texcoord0.xy); - diffcol.rgb *= vertex_color.rgb; - -#ifdef HAS_ALPHA_MASK -#if DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND - if (diffcol.a*vertex_color.a < minimum_alpha) -#else - if (diffcol.a < minimum_alpha) -#endif - { - discard; - } -#endif - #if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND) - frag_color = vec4(1,0,0,0.5); + frag_color = vec4(1, 0, 0, 0.5); #else // emissive red PBR material - frag_data[0] = vec4(0,0,0,0); - frag_data[1] = vec4(0,0,0,0); - frag_data[2] = vec4(1,0,0,GBUFFER_FLAG_HAS_PBR); - frag_data[3] = vec4(1,0,0,0); + frag_data[0] = vec4(0, 0, 0, 0); + frag_data[1] = vec4(0, 0, 0, 0); + frag_data[2] = vec4(1, 0, 0, GBUFFER_FLAG_HAS_PBR); + frag_data[3] = vec4(1, 0, 0, 0); #endif } - diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp index 0a104d1db5..88923ba734 100644 --- a/indra/newview/llgltfmateriallist.cpp +++ b/indra/newview/llgltfmateriallist.cpp @@ -45,59 +45,57 @@ namespace { - class LLGLTFOverrideDispatchHandler : public LLDispatchHandler + class LLGLTFMaterialOverrideDispatchHandler : public LLDispatchHandler { - LOG_CLASS(LLGLTFOverrideDispatchHandler); + LOG_CLASS(LLGLTFMaterialOverrideDispatchHandler); public: - LLGLTFOverrideDispatchHandler() = default; - ~LLGLTFOverrideDispatchHandler() override = default; + LLGLTFMaterialOverrideDispatchHandler() = default; + ~LLGLTFMaterialOverrideDispatchHandler() override = default; bool operator()(const LLDispatcher* dispatcher, const std::string& key, const LLUUID& invoice, const sparam_t& strings) override { - // iterate over pairs of parameters - int i; - for (i = 0; i+1 < strings.size(); i += 2) - { - std::string params_json = strings[i]; - std::string override_json = strings[i+1]; + // receive override data from simulator via LargeGenericMessage + // message should have: + // object_id - UUID of LLViewerObject + // side - S32 index of texture entry + // gltf_json - String of GLTF json for override data - LL_DEBUGS() << "received override: " << params_json << " | " << override_json << LL_ENDL; - Json::Value params; - Json::Reader reader; - bool success = reader.parse(params_json, params); - if (!success) + LLSD message; + + sparam_t::const_iterator it = strings.begin(); + if (it != strings.end()) { + const std::string& llsdRaw = *it++; + std::istringstream llsdData(llsdRaw); + if (!LLSDSerialize::deserialize(message, llsdData, llsdRaw.length())) { - LL_WARNS() << "failed to parse override parameters. errors: " << reader.getFormatedErrorMessages() << LL_ENDL; - break; + LL_WARNS() << "LLGLTFMaterialOverrideDispatchHandler: Attempted to read parameter data into LLSD but failed:" << llsdRaw << LL_ENDL; } + } + + LLViewerObject * obj = gObjectList.findObject(message["object_id"].asUUID()); + S32 side = message["side"].asInteger(); + std::string gltf_json = message["gltf_json"].asString(); - LLViewerObject * obj = gObjectList.findObject(LLUUID(params["object_id"].asString())); - S32 side = params["side"].asInt(); - - std::string warn_msg, error_msg; - LLPointer override_data = new LLGLTFMaterial(); - success = override_data->fromJSON(override_json, warn_msg, error_msg); -// if (!success) -// { -// LL_WARNS() << "failed to parse GLTF override data. errors: " << error_msg << " | warnings: " << warn_msg << LL_ENDL; -// break; -// } - - if(obj) + std::string warn_msg, error_msg; + LLPointer 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) { obj->setTEGLTFMaterialOverride(side, override_data); } - - LL_DEBUGS() << "successfully parsed override: " << override_data->asJSON() << LL_ENDL; } - LL_WARNS_IF(i != strings.size()) << "parse error or unhandled mismatched odd number of parameters for material override" << LL_ENDL; - return true; } }; - LLGLTFOverrideDispatchHandler handle_gltf_override_message; + LLGLTFMaterialOverrideDispatchHandler handle_gltf_override_message; } LLGLTFMaterialList gGLTFMaterialList; @@ -256,5 +254,5 @@ void LLGLTFMaterialList::flushMaterials() // static void LLGLTFMaterialList::registerCallbacks() { - gGenericDispatcher.addHandler("GLTF", &handle_gltf_override_message); + gGenericDispatcher.addHandler("GLTFMaterialOverride", &handle_gltf_override_message); } diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index c5cdb81d67..58894dbd69 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1872,42 +1872,24 @@ public: bool apply(LLViewerObject* objectp, S32 te) override { + // post override from given object and te to the simulator + // requestData should have: + // object_id - UUID of LLViewerObject + // side - S32 index of texture entry + // gltf_json - String of GLTF json for override data + if (objectp && objectp->permModify() && objectp->getVolume()) { - //LLVOVolume* vobjp = (LLVOVolume*)objectp; - S32 local_id = objectp->getLocalID(); - LLPointer material = new LLGLTFMaterial(); - LLPointer base; + mEditor->getGLTFMaterial(material); - tinygltf::Model model_out; - - if(mAssetID != LLUUID::null) - { - base = gGLTFMaterialList.getMaterial(mAssetID); - material->writeOverridesToModel(model_out, 0, base); - } - else - { - material->writeToModel(model_out, 0); - } - - std::string overrides_json; - { - tinygltf::TinyGLTF gltf; - std::ostringstream str; - - gltf.WriteGltfSceneToStream(&model_out, str, false, false); - - overrides_json = str.str(); - LL_DEBUGS() << "overrides_json " << overrides_json << LL_ENDL; - } - + std::string overrides_json = material->asJSON(); + LLSD overrides = llsd::map( - "local_id", local_id, + "object_id", objectp->getID(), "side", te, - "overrides", overrides_json + "gltf_json", overrides_json ); LLCoros::instance().launch("modifyMaterialCoro", std::bind(&LLMaterialEditor::modifyMaterialCoro, mEditor, mCapUrl, overrides)); } From 0cd7c3842119f1801872b4db05e17544b4eb7158 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 21 Oct 2022 18:05:19 -0500 Subject: [PATCH 2/8] SL-18105 Hook up live material editor to current selection set and implicitly open build floater when editing a PBR material. --- indra/newview/llmaterialeditor.cpp | 29 ++++++++++++++++++++++------- indra/newview/llmaterialeditor.h | 6 +++++- indra/newview/llpanelface.cpp | 2 +- indra/newview/llselectmgr.cpp | 1 + indra/newview/llviewermenu.cpp | 5 +++-- 5 files changed, 32 insertions(+), 11 deletions(-) diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 58894dbd69..86efdfcd06 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1401,15 +1401,14 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 ind } } -void LLMaterialEditor::loadLiveMaterial(LLUUID &asset_id) +void LLMaterialEditor::loadLiveMaterialEditor() { LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor", LLSD(LIVE_MATERIAL_EDITOR_KEY)); + me->mIsOverride = true; me->setTitle(me->getString("material_override_title")); - me->setAssetId(asset_id); - if (asset_id.notNull()) - { - me->setFromGLTFMaterial(gGLTFMaterialList.getMaterial(asset_id)); - } + me->childSetVisible("save", false); + me->childSetVisible("save_as", false); + me->setFromSelection(); me->openFloater(); me->setFocus(TRUE); } @@ -1904,7 +1903,7 @@ private: void LLMaterialEditor::applyToSelection() { - if (!mKey.isUUID() || mKey.asUUID() != LIVE_MATERIAL_EDITOR_KEY) + if (!mIsOverride) { // Only apply if working with 'live' materials // Might need a better way to distinguish 'live' mode. @@ -1974,6 +1973,22 @@ void LLMaterialEditor::setFromGLTFMaterial(LLGLTFMaterial* mat) setAlphaCutoff(mat->mAlphaCutoff); } +void LLMaterialEditor::setFromSelection() +{ + struct LLSelectedTEGetGLTFRenderMaterial : public LLSelectedTEGetFunctor > + { + LLPointer get(LLViewerObject* object, S32 te_index) + { + return object->getTE(te_index)->getGLTFRenderMaterial(); // present user with combined override + asset + } + } func; + + LLPointer mat; + LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&func, mat); + setFromGLTFMaterial(mat); +} + + void LLMaterialEditor::loadAsset() { // derived from LLPreviewNotecard::loadAsset diff --git a/indra/newview/llmaterialeditor.h b/indra/newview/llmaterialeditor.h index 3b2648cba5..0aaf391431 100644 --- a/indra/newview/llmaterialeditor.h +++ b/indra/newview/llmaterialeditor.h @@ -103,7 +103,7 @@ public: // will promt to select specific one static void loadMaterialFromFile(const std::string& filename, S32 index = -1); - static void loadLiveMaterial(LLUUID &asset_id); + static void loadLiveMaterialEditor(); static void loadFromGLTFMaterial(LLUUID &asset_id); @@ -222,6 +222,7 @@ public: private: void setFromGLTFMaterial(LLGLTFMaterial* mat); + void setFromSelection(); void loadMaterial(const tinygltf::Model &model, const std::string &filename_lc, S32 index); @@ -271,5 +272,8 @@ private: S32 mExpectedUploadCost; std::string mMaterialNameShort; std::string mMaterialName; + + // if true, this instance is live instance editing overrides + bool mIsOverride = false; }; diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index f4b75c9154..f8e786fc97 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -4588,7 +4588,7 @@ void LLPanelFace::onPbrStartEditing() LL_DEBUGS() << "loading material live editor with asset " << material_id << LL_ENDL; - LLMaterialEditor::loadLiveMaterial(material_id); + LLMaterialEditor::loadLiveMaterialEditor(); } bool LLPanelFace::isIdenticalPlanarTexgen() diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index d103141669..2475900d0e 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -8576,6 +8576,7 @@ DEF_DUMMY_CHECK_FUNCTOR(int) DEF_DUMMY_CHECK_FUNCTOR(LLColor4) DEF_DUMMY_CHECK_FUNCTOR(LLMediaEntry) DEF_DUMMY_CHECK_FUNCTOR(LLPointer) +DEF_DUMMY_CHECK_FUNCTOR(LLPointer) DEF_DUMMY_CHECK_FUNCTOR(std::string) DEF_DUMMY_CHECK_FUNCTOR(std::vector) diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 5cb63426a8..47b355e554 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -2970,7 +2970,7 @@ void load_life_gltf_material(bool copy) } else { - LLMaterialEditor::loadLiveMaterial(mat_id); + LLMaterialEditor::loadLiveMaterialEditor(); } LLViewerJoystick::getInstance()->moveObjects(true); @@ -2979,7 +2979,8 @@ void load_life_gltf_material(bool copy) void handle_object_edit_gltf_material() { - load_life_gltf_material(false); + handle_object_edit(); + LLMaterialEditor::loadLiveMaterialEditor(); } void handle_object_save_gltf_material() From 7135934e50bf2727c2366687af7427d44483e984 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Sat, 22 Oct 2022 11:01:35 -0500 Subject: [PATCH 3/8] SL-18105 Fix for crash when attempting to "Edit PBR Material" when there's no PBR material --- indra/newview/llmaterialeditor.cpp | 27 ++++++++++++++++++--------- indra/newview/llmaterialeditor.h | 2 +- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 86efdfcd06..038f4df863 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1404,13 +1404,16 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 ind void LLMaterialEditor::loadLiveMaterialEditor() { LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor", LLSD(LIVE_MATERIAL_EDITOR_KEY)); - me->mIsOverride = true; - me->setTitle(me->getString("material_override_title")); - me->childSetVisible("save", false); - me->childSetVisible("save_as", false); - me->setFromSelection(); - me->openFloater(); - me->setFocus(TRUE); + if (me->setFromSelection()) + { + me->mIsOverride = true; + me->setTitle(me->getString("material_override_title")); + me->childSetVisible("save", false); + me->childSetVisible("save_as", false); + + me->openFloater(); + me->setFocus(TRUE); + } } void LLMaterialEditor::loadFromGLTFMaterial(LLUUID &asset_id) @@ -1973,7 +1976,7 @@ void LLMaterialEditor::setFromGLTFMaterial(LLGLTFMaterial* mat) setAlphaCutoff(mat->mAlphaCutoff); } -void LLMaterialEditor::setFromSelection() +bool LLMaterialEditor::setFromSelection() { struct LLSelectedTEGetGLTFRenderMaterial : public LLSelectedTEGetFunctor > { @@ -1985,7 +1988,13 @@ void LLMaterialEditor::setFromSelection() LLPointer mat; LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&func, mat); - setFromGLTFMaterial(mat); + if (mat.notNull()) + { + setFromGLTFMaterial(mat); + return true; + } + + return false; } diff --git a/indra/newview/llmaterialeditor.h b/indra/newview/llmaterialeditor.h index 0aaf391431..9cd8bcd88b 100644 --- a/indra/newview/llmaterialeditor.h +++ b/indra/newview/llmaterialeditor.h @@ -222,7 +222,7 @@ public: private: void setFromGLTFMaterial(LLGLTFMaterial* mat); - void setFromSelection(); + bool setFromSelection(); void loadMaterial(const tinygltf::Model &model, const std::string &filename_lc, S32 index); From 88659e9fe793a02fb4edcbf8ef07307c25119604 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Sat, 22 Oct 2022 15:25:03 -0500 Subject: [PATCH 4/8] SL-18105 When saving an object's material to inventory, save the version that as overrides applied. --- indra/llprimitive/lltextureentry.cpp | 51 +++++++++++++++++++--------- indra/newview/llgltfmateriallist.cpp | 1 + indra/newview/llmaterialeditor.cpp | 14 +++++++- indra/newview/llmaterialeditor.h | 3 +- indra/newview/llpanelface.cpp | 2 +- indra/newview/llviewermenu.cpp | 6 ++-- indra/newview/llviewerobject.cpp | 3 ++ 7 files changed, 58 insertions(+), 22 deletions(-) diff --git a/indra/llprimitive/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp index e185404ada..68de480d87 100644 --- a/indra/llprimitive/lltextureentry.cpp +++ b/indra/llprimitive/lltextureentry.cpp @@ -80,22 +80,7 @@ LLTextureEntry::LLTextureEntry(const LLTextureEntry &rhs) , mSelected(false) , mMaterialUpdatePending(false) { - mID = rhs.mID; - mScaleS = rhs.mScaleS; - mScaleT = rhs.mScaleT; - mOffsetS = rhs.mOffsetS; - mOffsetT = rhs.mOffsetT; - mRotation = rhs.mRotation; - mColor = rhs.mColor; - mBump = rhs.mBump; - mMediaFlags = rhs.mMediaFlags; - mGlow = rhs.mGlow; - mMaterialID = rhs.mMaterialID; - mMaterial = rhs.mMaterial; - if (rhs.mMediaEntry != NULL) { - // Make a copy - mMediaEntry = new LLMediaEntry(*rhs.mMediaEntry); - } + *this = rhs; } LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs) @@ -124,6 +109,17 @@ LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs) else { mMediaEntry = NULL; } + + mMaterialID = rhs.mMaterialID; + + if (rhs.mGLTFMaterialOverrides.notNull()) + { + mGLTFMaterialOverrides = new LLGLTFMaterial(*rhs.mGLTFMaterialOverrides); + } + else + { + mGLTFMaterialOverrides = nullptr; + } } return *this; @@ -218,6 +214,11 @@ void LLTextureEntry::asLLSD(LLSD& sd) const sd[TEXTURE_MEDIA_DATA_KEY] = mediaData; } sd["glow"] = mGlow; + + if (mGLTFMaterialOverrides.notNull()) + { + sd["gltf_override"] = mGLTFMaterialOverrides->asJSON(); + } } bool LLTextureEntry::fromLLSD(const LLSD& sd) @@ -282,6 +283,24 @@ bool LLTextureEntry::fromLLSD(const LLSD& sd) setGlow((F32)sd[w].asReal() ); } + w = "gltf_override"; + if (sd.has(w)) + { + if (mGLTFMaterialOverrides.isNull()) + { + mGLTFMaterialOverrides = new LLGLTFMaterial(); + } + + std::string warn_msg, error_msg; + if (!mGLTFMaterialOverrides->fromJSON(sd[w].asString(), warn_msg, error_msg)) + { + LL_WARNS() << llformat("Failed to parse GLTF json: %s -- %s", warn_msg.c_str(), error_msg.c_str()) << LL_ENDL; + LL_WARNS() << sd[w].asString() << LL_ENDL; + + mGLTFMaterialOverrides = nullptr; + } + } + return true; fail: return false; diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp index 88923ba734..4861c2a33b 100644 --- a/indra/newview/llgltfmateriallist.cpp +++ b/indra/newview/llgltfmateriallist.cpp @@ -74,6 +74,7 @@ namespace } LLViewerObject * obj = gObjectList.findObject(message["object_id"].asUUID()); + llassert(obj); // should never get an override for an object we don't know about S32 side = message["side"].asInteger(); std::string gltf_json = message["gltf_json"].asString(); diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 038f4df863..8086bcf402 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1401,7 +1401,7 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 ind } } -void LLMaterialEditor::loadLiveMaterialEditor() +void LLMaterialEditor::loadLive() { LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor", LLSD(LIVE_MATERIAL_EDITOR_KEY)); if (me->setFromSelection()) @@ -1416,6 +1416,18 @@ void LLMaterialEditor::loadLiveMaterialEditor() } } +void LLMaterialEditor::loadObjectSave() +{ + LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor", LLSD(LIVE_MATERIAL_EDITOR_KEY)); + if (me->setFromSelection()) + { + me->mIsOverride = false; + me->childSetVisible("save", false); + me->openFloater(); + me->setFocus(TRUE); + } +} + void LLMaterialEditor::loadFromGLTFMaterial(LLUUID &asset_id) { if (asset_id.isNull()) diff --git a/indra/newview/llmaterialeditor.h b/indra/newview/llmaterialeditor.h index 9cd8bcd88b..23cb32aacf 100644 --- a/indra/newview/llmaterialeditor.h +++ b/indra/newview/llmaterialeditor.h @@ -103,7 +103,8 @@ public: // will promt to select specific one static void loadMaterialFromFile(const std::string& filename, S32 index = -1); - static void loadLiveMaterialEditor(); + static void loadLive(); + static void loadObjectSave(); static void loadFromGLTFMaterial(LLUUID &asset_id); diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index f8e786fc97..c6e0bc5153 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -4588,7 +4588,7 @@ void LLPanelFace::onPbrStartEditing() LL_DEBUGS() << "loading material live editor with asset " << material_id << LL_ENDL; - LLMaterialEditor::loadLiveMaterialEditor(); + LLMaterialEditor::loadLive(); } bool LLPanelFace::isIdenticalPlanarTexgen() diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 47b355e554..18d215f9f4 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -2970,7 +2970,7 @@ void load_life_gltf_material(bool copy) } else { - LLMaterialEditor::loadLiveMaterialEditor(); + LLMaterialEditor::loadLive(); } LLViewerJoystick::getInstance()->moveObjects(true); @@ -2980,12 +2980,12 @@ void load_life_gltf_material(bool copy) void handle_object_edit_gltf_material() { handle_object_edit(); - LLMaterialEditor::loadLiveMaterialEditor(); + LLMaterialEditor::loadLive(); } void handle_object_save_gltf_material() { - load_life_gltf_material(true); + LLMaterialEditor::loadObjectSave(); } void handle_attachment_edit(const LLUUID& inv_item_id) diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index eaf0287dae..603dcc4fa7 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -5333,6 +5333,9 @@ 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 ? src_mat : true); + if (override_mat && src_mat) { LLFetchedGLTFMaterial* render_mat = new LLFetchedGLTFMaterial(*src_mat); From 5b5d24a74703d2a8d5da65ef57d9b8af6889e3d7 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 24 Oct 2022 16:27:23 +0300 Subject: [PATCH 5/8] SL-17021 Fix some changes vanishing over merge to D559 --- indra/newview/llvovolume.cpp | 36 ++++++++++++++++++++++++++++++------ indra/newview/llvovolume.h | 12 ++++++++++-- 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 72c03b395f..84158c3a7d 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4773,7 +4773,7 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& { if ((pick_rigged) || (getAvatar() && (getAvatar()->isSelf()) && (LLFloater::isVisible(gFloaterTools)))) { - updateRiggedVolume(true); + updateRiggedVolume(true, LLRiggedVolume::DO_NOT_UPDATE_FACES); volume = mRiggedVolume; transform = false; } @@ -4848,6 +4848,7 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& continue; } + updateRiggedVolume(true, i); face_hit = volume->lineSegmentIntersect(local_start, local_end, i, &p, &tc, &n, &tn); @@ -4971,7 +4972,7 @@ void LLVOVolume::clearRiggedVolume() } } -void LLVOVolume::updateRiggedVolume(bool force_update) +void LLVOVolume::updateRiggedVolume(bool force_treat_as_rigged, LLRiggedVolume::FaceIndex face_index, bool rebuild_face_octrees) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; //Update mRiggedVolume to match current animation frame of avatar. @@ -5006,10 +5007,15 @@ void LLVOVolume::updateRiggedVolume(bool force_update) updateRelativeXform(); } - mRiggedVolume->update(skin, avatar, volume); + mRiggedVolume->update(skin, avatar, volume, face_index, rebuild_face_octrees); } -void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* volume) +void LLRiggedVolume::update( + const LLMeshSkinInfo* skin, + LLVOAvatar* avatar, + const LLVolume* volume, + FaceIndex face_index, + bool rebuild_face_octrees) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; bool copy = false; @@ -5040,7 +5046,7 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons if (is_paused) { S32 frames_paused = LLFrameTimer::getFrameCount() - avatar->getMotionController().getPausedFrame(); - if (frames_paused > 2) + if (frames_paused > 1) { return; } @@ -5059,7 +5065,24 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons S32 rigged_vert_count = 0; S32 rigged_face_count = 0; LLVector4a box_min, box_max; - for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i) + S32 face_begin; + S32 face_end; + if (face_index == DO_NOT_UPDATE_FACES) + { + face_begin = 0; + face_end = 0; + } + else if (face_index == UPDATE_ALL_FACES) + { + face_begin = 0; + face_end = volume->getNumVolumeFaces(); + } + else + { + face_begin = face_index; + face_end = face_begin + 1; + } + for (S32 i = face_begin; i < face_end; ++i) { const LLVolumeFace& vol_face = volume->getVolumeFace(i); @@ -5144,6 +5167,7 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons } + if (rebuild_face_octrees) { dst_face.destroyOctree(); diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 77e7043f40..003ab38d64 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -68,7 +68,12 @@ public: using FaceIndex = S32; static const FaceIndex UPDATE_ALL_FACES = -1; static const FaceIndex DO_NOT_UPDATE_FACES = -2; - void update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* src_volume); + void update( + const LLMeshSkinInfo* skin, + LLVOAvatar* avatar, + const LLVolume* src_volume, + FaceIndex face_index = UPDATE_ALL_FACES, + bool rebuild_face_octrees = true); std::string mExtraDebugText; }; @@ -385,7 +390,10 @@ public: // Rigged volume update (for raycasting) // By default, this updates the bounding boxes of all the faces and builds an octree for precise per-triangle raycasting - void updateRiggedVolume(bool force_treat_as_rigged); + void updateRiggedVolume( + bool force_treat_as_rigged, + LLRiggedVolume::FaceIndex face_index = LLRiggedVolume::UPDATE_ALL_FACES, + bool rebuild_face_octrees = true); LLRiggedVolume* getRiggedVolume(); //returns true if volume should be treated as a rigged volume From 683bfcfdee76d34126810c181ca877afa1deb2b1 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 24 Oct 2022 17:15:41 +0300 Subject: [PATCH 6/8] SL-17021 Fix some changes vanishing over merge to D559 #2 --- indra/newview/llvovolume.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 84158c3a7d..cb58c173d9 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4848,7 +4848,9 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& continue; } - updateRiggedVolume(true, i); + // This calculates the bounding box of the skinned mesh from scratch. It's actually quite expensive, but not nearly as expensive as building a full octree. + // rebuild_face_octrees = false because an octree for this face will be built later only if needed for narrow phase picking. + updateRiggedVolume(true, i, false); face_hit = volume->lineSegmentIntersect(local_start, local_end, i, &p, &tc, &n, &tn); @@ -4978,7 +4980,7 @@ void LLVOVolume::updateRiggedVolume(bool force_treat_as_rigged, LLRiggedVolume:: //Update mRiggedVolume to match current animation frame of avatar. //Also update position/size in octree. - if ((!force_update) && (!treatAsRigged())) + if ((!force_treat_as_rigged) && (!treatAsRigged())) { clearRiggedVolume(); From 620d2f4ee595ec013784a374e9136a43b99a355f Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 24 Oct 2022 17:15:41 +0300 Subject: [PATCH 7/8] SL-17532 Fix some changes vanishing over merge to D559 --- indra/newview/llvovolume.cpp | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index cb58c173d9..9c25606ce9 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4773,7 +4773,7 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& { if ((pick_rigged) || (getAvatar() && (getAvatar()->isSelf()) && (LLFloater::isVisible(gFloaterTools)))) { - updateRiggedVolume(true, LLRiggedVolume::DO_NOT_UPDATE_FACES); + updateRiggedVolume(true, LLRiggedVolume::DO_NOT_UPDATE_FACES); volume = mRiggedVolume; transform = false; } @@ -4980,7 +4980,7 @@ void LLVOVolume::updateRiggedVolume(bool force_treat_as_rigged, LLRiggedVolume:: //Update mRiggedVolume to match current animation frame of avatar. //Also update position/size in octree. - if ((!force_treat_as_rigged) && (!treatAsRigged())) + if ((!force_treat_as_rigged) && (!treatAsRigged())) { clearRiggedVolume(); @@ -5009,7 +5009,7 @@ void LLVOVolume::updateRiggedVolume(bool force_treat_as_rigged, LLRiggedVolume:: updateRelativeXform(); } - mRiggedVolume->update(skin, avatar, volume, face_index, rebuild_face_octrees); + mRiggedVolume->update(skin, avatar, volume, face_index, rebuild_face_octrees); } void LLRiggedVolume::update( @@ -5172,12 +5172,7 @@ void LLRiggedVolume::update( if (rebuild_face_octrees) { dst_face.destroyOctree(); - - LLVector4a size; - size.setSub(dst_face.mExtents[1], dst_face.mExtents[0]); - size.splat(size.getLength3().getF32()*0.5f); - - dst_face.createOctree(1.f); + dst_face.createOctree(); } } } @@ -5427,7 +5422,6 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, LLViewerTexture* tex = facep->getTexture(); - U8 index = facep->getTextureIndex(); LLMaterial* mat = nullptr; @@ -6421,6 +6415,13 @@ struct CompareBatchBreakerRigged } }; +struct CompareDrawOrder +{ + bool operator()(const LLFace* const& lhs, const LLFace* const& rhs) + { + return lhs->getDrawOrderIndex() < rhs->getDrawOrderIndex(); + } +}; U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort, BOOL batch_textures, BOOL rigged) { @@ -6455,6 +6456,11 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace //sort faces by things that break batches, including avatar and mesh id std::sort(faces, faces + face_count, CompareBatchBreakerRigged()); } + else + { + // preserve legacy draw order for rigged faces + std::sort(faces, faces + face_count, CompareDrawOrder()); + } } else if (!distance_sort) { From 4b37414dc0963a9db344c493055f501265f4e59a Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 24 Oct 2022 19:49:36 +0300 Subject: [PATCH 8/8] Re-merged llvovolume.cpp Too many issue were detected after merge, so did a clean remerge of the file. --- indra/newview/llvovolume.cpp | 44 +++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 9c25606ce9..7c58d23d0e 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1994,7 +1994,7 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) if (mDrawable->isState(LLDrawable::REBUILD_RIGGED)) { - updateRiggedVolume(false); + updateRiggedVolume(false); genBBoxes(FALSE); mDrawable->clearState(LLDrawable::REBUILD_RIGGED); } @@ -5704,7 +5704,7 @@ static inline void add_face(T*** list, U32* count, T* face) { if (count[1] < MAX_FACE_COUNT) { - face->setDrawOrderIndex(count[1]); + //face->setDrawOrderIndex(count[1]); list[1][count[1]++] = face; } } @@ -5712,12 +5712,36 @@ static inline void add_face(T*** list, U32* count, T* face) { if (count[0] < MAX_FACE_COUNT) { - face->setDrawOrderIndex(count[0]); + //face->setDrawOrderIndex(count[0]); list[0][count[0]++] = face; } } } +// return index into linkset for given object (0 for root prim) +U32 get_linkset_index(LLVOVolume* vobj) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE; + if (vobj->isRootEdit()) + { + return 0; + } + + LLViewerObject* root = vobj->getRootEdit(); + U32 idx = 1; + for (const auto& child : root->getChildren()) + { + if (child == vobj) + { + return idx; + } + ++idx; + } + + llassert(false); + return idx; //should never get here +} + void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; @@ -5881,6 +5905,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) avatar->addAttachmentOverridesForObject(vobj, NULL, false); } + U32 linkset_index = get_linkset_index(vobj); + // Standard rigged mesh attachments: bool rigged = !vobj->isAnimatedObject() && skinInfo && vobj->isAttachment(); // Animated objects. Have to check for isRiggedMesh() to @@ -5900,6 +5926,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) continue; } + // order by linkset index first and face index second + facep->setDrawOrderIndex(linkset_index * 100 + i); + // HACK -- brute force this check every time a drawable gets rebuilt vobj->updateTEMaterialTextures(i); #if 0 @@ -5939,11 +5968,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) if (facep->isState(LLFace::RIGGED)) { //face is not rigged but used to be, remove from rigged face pool - LLDrawPoolAvatar* pool = (LLDrawPoolAvatar*) facep->getPool(); - if (pool) - { - pool->removeFace(facep); - } facep->clearState(LLFace::RIGGED); facep->mAvatar = NULL; facep->mSkinInfo = NULL; @@ -6251,7 +6275,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) { LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); - if (drawablep && !drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) && !drawablep->isState(LLDrawable::RIGGED) ) + if (drawablep && !drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL)) { LLVOVolume* vobj = drawablep->getVOVolume(); @@ -6285,8 +6309,6 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) LLVertexBuffer* buff = face->getVertexBuffer(); if (buff) { - llassert(!face->isState(LLFace::RIGGED)); - if (!face->getGeometryVolume(*volume, face->getTEOffset(), vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex())) { //something's gone wrong with the vertex buffer accounting, rebuild this group