From 394479d7cc48a0170854e07f14267e28ba247990 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 23 Jun 2022 16:21:53 -0500 Subject: SL-17653 WIP - Apply GLTF material in Material Editor to selected object when you click "Save" --- indra/llprimitive/llmaterialid.cpp | 7 +++++ indra/llprimitive/llmaterialid.h | 1 + indra/llprimitive/lltextureentry.h | 8 ++++++ indra/newview/llmaterialeditor.cpp | 37 ++++++++++++++++++++++++- indra/newview/llmaterialeditor.h | 3 ++ indra/newview/llspatialpartition.h | 13 +++++++-- indra/newview/llviewerobject.cpp | 56 ++++++++++++++++++++++++++++---------- indra/newview/llviewerobject.h | 14 ++++++++++ indra/newview/llvovolume.cpp | 40 +++++++++++++++++++++++---- 9 files changed, 156 insertions(+), 23 deletions(-) diff --git a/indra/llprimitive/llmaterialid.cpp b/indra/llprimitive/llmaterialid.cpp index f88a607c4f..340a83801c 100644 --- a/indra/llprimitive/llmaterialid.cpp +++ b/indra/llprimitive/llmaterialid.cpp @@ -155,6 +155,13 @@ std::string LLMaterialID::asString() const return materialIDString; } +LLUUID LLMaterialID::asUUID() const +{ + LLUUID ret; + memcpy(ret.mData, mID, MATERIAL_ID_SIZE); + return ret; +} + std::ostream& operator<<(std::ostream& s, const LLMaterialID &material_id) { s << material_id.asString(); diff --git a/indra/llprimitive/llmaterialid.h b/indra/llprimitive/llmaterialid.h index ee663f8f99..e6165dfc91 100644 --- a/indra/llprimitive/llmaterialid.h +++ b/indra/llprimitive/llmaterialid.h @@ -61,6 +61,7 @@ public: LLSD asLLSD() const; std::string asString() const; + LLUUID asUUID() const; friend std::ostream& operator<<(std::ostream& s, const LLMaterialID &material_id); diff --git a/indra/llprimitive/lltextureentry.h b/indra/llprimitive/lltextureentry.h index dc2e201044..1549b2ce87 100644 --- a/indra/llprimitive/lltextureentry.h +++ b/indra/llprimitive/lltextureentry.h @@ -32,6 +32,7 @@ #include "llsd.h" #include "llmaterialid.h" #include "llmaterial.h" +#include "llgltfmaterial.h" // These bits are used while unpacking TEM messages to tell which aspects of // the texture entry changed. @@ -134,6 +135,10 @@ public: S32 setMaterialID(const LLMaterialID& pMaterialID); S32 setMaterialParams(const LLMaterialPtr pMaterialParams); + void setGLTFMaterial(LLGLTFMaterial* material) { mGLTFMaterial = material; } + LLGLTFMaterial* getGLTFMaterial() { return mGLTFMaterial; } + + virtual const LLUUID &getID() const { return mID; } const LLColor4 &getColor() const { return mColor; } const F32 getAlpha() const { return mColor.mV[VALPHA]; } @@ -162,6 +167,8 @@ public: const LLMaterialID& getMaterialID() const { return mMaterialID; }; const LLMaterialPtr getMaterialParams() const { return mMaterial; }; + LLGLTFMaterial* getGLTFMaterial() const { return mGLTFMaterial; } + // *NOTE: it is possible for hasMedia() to return true, but getMediaData() to return NULL. // CONVERSELY, it is also possible for hasMedia() to return false, but getMediaData() // to NOT return NULL. @@ -219,6 +226,7 @@ protected: bool mMaterialUpdatePending; LLMaterialID mMaterialID; LLMaterialPtr mMaterial; + LLPointer mGLTFMaterial; // if present, ignore mMaterial // Note the media data is not sent via the same message structure as the rest of the TE LLMediaEntry* mMediaEntry; // The media data for the face diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 05e7ff524a..5a0c23d59b 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -31,6 +31,8 @@ #include "llviewermenufile.h" #include "llappviewer.h" #include "llviewertexture.h" +#include "llselectmgr.h" +#include "llvovolume.h" #include "tinygltf/tiny_gltf.h" @@ -195,6 +197,8 @@ static U32 write_texture(const LLUUID& id, tinygltf::Model& model) void LLMaterialEditor::onClickSave() { + applyToSelection(); + tinygltf::Model model; model.materials.resize(1); tinygltf::PbrMetallicRoughness& pbrMaterial = model.materials[0].pbrMetallicRoughness; @@ -450,4 +454,35 @@ void LLMaterialFilePicker::loadMaterial(const std::string& filename) void LLMaterialEditor::importMaterial() { (new LLMaterialFilePicker(this))->getFile(); -} \ No newline at end of file +} + +void LLMaterialEditor::applyToSelection() +{ + LLViewerObject* objectp = LLSelectMgr::instance().getSelection()->getFirstObject(); + if (objectp && objectp->getVolume()) + { + LLGLTFMaterial* mat = new LLGLTFMaterial(); + mat->mAlbedoColor = getAlbedoColor(); + mat->mAlbedoColor.mV[3] = getTransparency(); + mat->mAlbedoId = getAlbedoId(); + + mat->mNormalId = getNormalId(); + + mat->mMetallicRoughnessId = getMetallicRoughnessId(); + mat->mMetallicFactor = getMetalnessFactor(); + mat->mRoughnessFactor = getRoughnessFactor(); + + mat->mEmissiveColor = getEmissiveColor(); + mat->mEmissiveId = getEmissiveId(); + + mat->mDoubleSided = getDoubleSided(); + mat->setAlphaMode(getAlphaMode()); + + LLVOVolume* vobjp = (LLVOVolume*)objectp; + for (int i = 0; i < vobjp->getNumTEs(); ++i) + { + vobjp->getTE(i)->setGLTFMaterial(mat); + vobjp->updateTEMaterialTextures(i); + } + } +} diff --git a/indra/newview/llmaterialeditor.h b/indra/newview/llmaterialeditor.h index f0c5dca44d..e773ecd169 100644 --- a/indra/newview/llmaterialeditor.h +++ b/indra/newview/llmaterialeditor.h @@ -36,6 +36,9 @@ public: // open a file dialog and select a gltf/glb file for import void importMaterial(); + // for live preview, apply current material to currently selected object + void applyToSelection(); + void onClickSave(); // llpanel diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index 07d62be7af..c3e9d8ceb9 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -113,9 +113,14 @@ public: LL_ALIGN_16(LLFace* mFace); //associated face F32 mDistance; U32 mDrawMode; - LLMaterialPtr mMaterial; // If this is null, the following parameters are unused. - LLMaterialID mMaterialID; - U32 mShaderMask; + + // Material points here are likely for debugging only and are immaterial (zing!) + LLMaterialPtr mMaterial; + LLPointer mGLTFMaterial; + + LLUUID mMaterialID; // id of LLGLTFMaterial or LLMaterial applied to this draw info + + U32 mShaderMask; U32 mBlendFuncSrc; U32 mBlendFuncDst; BOOL mHasGlow; @@ -123,6 +128,8 @@ public: const LLMatrix4* mSpecularMapMatrix; LLPointer mNormalMap; const LLMatrix4* mNormalMapMatrix; + LLPointer mEmissiveMap; + LLVector4 mSpecColor; // XYZ = Specular RGB, W = Specular Exponent F32 mEnvIntensity; F32 mAlphaMaskCutoff; diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 857a94d7be..16479e02a2 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -406,6 +406,11 @@ void LLViewerObject::deleteTEImages() delete[] mTESpecularMaps; mTESpecularMaps = NULL; } + + mGLTFAlbedoMaps.clear(); + mGLTFNormalMaps.clear(); + mGLTFMetallicRoughnessMaps.clear(); + mGLTFEmissiveMaps.clear(); } void LLViewerObject::markDead() @@ -4731,6 +4736,11 @@ void LLViewerObject::setNumTEs(const U8 num_tes) mTEImages = new_images; mTENormalMaps = new_normmaps; mTESpecularMaps = new_specmaps; + + mGLTFAlbedoMaps.resize(num_tes); + mGLTFNormalMaps.resize(num_tes); + mGLTFMetallicRoughnessMaps.resize(num_tes); + mGLTFEmissiveMaps.resize(num_tes); } else { @@ -4859,23 +4869,28 @@ void LLViewerObject::updateAvatarMeshVisibility(const LLUUID& id, const LLUUID& } } -void LLViewerObject::setTE(const U8 te, const LLTextureEntry &texture_entry) + +void LLViewerObject::setTE(const U8 te, const LLTextureEntry& texture_entry) { - LLUUID old_image_id; - if (getTE(te)) - { - old_image_id = getTE(te)->getID(); - } - - LLPrimitive::setTE(te, texture_entry); + LLUUID old_image_id; + if (getTE(te)) + { + old_image_id = getTE(te)->getID(); + } - const LLUUID& image_id = getTE(te)->getID(); - LLViewerTexture* bakedTexture = getBakedTextureForMagicId(image_id); - mTEImages[te] = bakedTexture ? bakedTexture : LLViewerTextureManager::getFetchedTexture(image_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + LLPrimitive::setTE(te, texture_entry); - - updateAvatarMeshVisibility(image_id,old_image_id); + const LLUUID& image_id = getTE(te)->getID(); + LLViewerTexture* bakedTexture = getBakedTextureForMagicId(image_id); + mTEImages[te] = bakedTexture ? bakedTexture : LLViewerTextureManager::getFetchedTexture(image_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + + updateAvatarMeshVisibility(image_id, old_image_id); + updateTEMaterialTextures(te); +} + +void LLViewerObject::updateTEMaterialTextures(U8 te) +{ if (getTE(te)->getMaterialParams().notNull()) { const LLUUID& norm_id = getTE(te)->getMaterialParams()->getNormalID(); @@ -4884,6 +4899,20 @@ void LLViewerObject::setTE(const U8 te, const LLTextureEntry &texture_entry) const LLUUID& spec_id = getTE(te)->getMaterialParams()->getSpecularID(); mTESpecularMaps[te] = LLViewerTextureManager::getFetchedTexture(spec_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_ALM, LLViewerTexture::LOD_TEXTURE); } + + auto fetch_texture = [](const LLUUID& id) + { + return LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_ALM, LLViewerTexture::LOD_TEXTURE); + }; + + LLGLTFMaterial* mat = getTE(te)->getGLTFMaterial(); + if (mat != nullptr) + { + mGLTFAlbedoMaps[te] = fetch_texture(mat->mAlbedoId); + mGLTFNormalMaps[te] = fetch_texture(mat->mNormalId); + mGLTFMetallicRoughnessMaps[te] = fetch_texture(mat->mMetallicRoughnessId); + mGLTFEmissiveMaps[te] = fetch_texture(mat->mEmissiveId); + } } void LLViewerObject::refreshBakeTexture() @@ -5424,7 +5453,6 @@ void LLViewerObject::fitFaceTexture(const U8 face) LL_INFOS() << "fitFaceTexture not implemented" << LL_ENDL; } - LLBBox LLViewerObject::getBoundingBoxAgent() const { LLVector3 position_agent; diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 1c4cfc6466..5136a7e5ee 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -321,6 +321,7 @@ public: /*virtual*/ void setNumTEs(const U8 num_tes); /*virtual*/ void setTE(const U8 te, const LLTextureEntry &texture_entry); + void updateTEMaterialTextures(U8 te); /*virtual*/ S32 setTETexture(const U8 te, const LLUUID &uuid); /*virtual*/ S32 setTENormalMap(const U8 te, const LLUUID &uuid); /*virtual*/ S32 setTESpecularMap(const U8 te, const LLUUID &uuid); @@ -359,6 +360,12 @@ public: LLViewerTexture *getTEImage(const U8 te) const; LLViewerTexture *getTENormalMap(const U8 te) const; LLViewerTexture *getTESpecularMap(const U8 te) const; + + LLViewerTexture* getGLTFAlbedoMap(U8 te) const { return mGLTFAlbedoMaps[te]; } + LLViewerTexture* getGLTFNormalMap(U8 te) const { return mGLTFNormalMaps[te]; } + LLViewerTexture* getGLTFEmissiveMap(U8 te) const { return mGLTFEmissiveMaps[te]; } + LLViewerTexture* getGLTFMetallicRoughnessMap(U8 te) const { return mGLTFMetallicRoughnessMaps[te]; } + bool isImageAlphaBlended(const U8 te) const; @@ -675,6 +682,13 @@ public: LLPointer *mTEImages; LLPointer *mTENormalMaps; LLPointer *mTESpecularMaps; + + std::vector > mGLTFAlbedoMaps; + std::vector > mGLTFNormalMaps; + std::vector > mGLTFMetallicRoughnessMaps; + std::vector > mGLTFEmissiveMaps; + + // true if user can select this object by clicking under any circumstances (even if pick_unselectable is true) // can likely be factored out diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 3a619b4fcc..302a172858 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -5390,10 +5390,26 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, LLViewerTexture* tex = facep->getTexture(); + U8 index = facep->getTextureIndex(); - LLMaterial* mat = facep->getTextureEntry()->getMaterialParams().get(); - LLMaterialID mat_id = facep->getTextureEntry()->getMaterialID(); + LLMaterial* mat = nullptr; + + LLUUID mat_id; + + LLGLTFMaterial* gltf_mat = facep->getTextureEntry()->getGLTFMaterial(); + if (gltf_mat != nullptr) + { + mat_id = gltf_mat->getHash(); // TODO: cache this hash + } + else + { + mat = facep->getTextureEntry()->getMaterialParams().get(); + if (mat) + { + mat_id = facep->getTextureEntry()->getMaterialID().asUUID(); + } + } bool batchable = false; @@ -5415,7 +5431,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, if (index < FACE_DO_NOT_BATCH_TEXTURES && idx >= 0) { - if (mat || draw_vec[idx]->mMaterial) + if (mat || gltf_mat || draw_vec[idx]->mMaterial) { //can't batch textures when materials are present (yet) batchable = false; } @@ -5447,7 +5463,6 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() <= (U32) gGLManager.mGLMaxVertexRange && draw_vec[idx]->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange && #endif - //draw_vec[idx]->mMaterial == mat && draw_vec[idx]->mMaterialID == mat_id && draw_vec[idx]->mFullbright == fullbright && draw_vec[idx]->mBump == bump && @@ -5504,11 +5519,22 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, draw_info->mEnvIntensity = spec; draw_info->mSpecularMap = NULL; draw_info->mMaterial = mat; + draw_info->mGLTFMaterial = gltf_mat; draw_info->mShaderMask = shader_mask; draw_info->mAvatar = facep->mAvatar; draw_info->mSkinInfo = facep->mSkinInfo; - if (mat) + if (gltf_mat) + { + LLViewerObject* vobj = facep->getViewerObject(); + U8 te = facep->getTEOffset(); + + draw_info->mTexture = vobj->getGLTFAlbedoMap(te); + draw_info->mNormalMap = vobj->getGLTFNormalMap(te); + draw_info->mSpecularMap = vobj->getGLTFMetallicRoughnessMap(te); + draw_info->mEmissiveMap = vobj->getGLTFEmissiveMap(te); + } + else if (mat) { draw_info->mMaterialID = mat_id; @@ -5849,6 +5875,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) continue; } +#if 0 #if LL_RELEASE_WITH_DEBUG_INFO const LLUUID pbr_id( "49c88210-7238-2a6b-70ac-92d4f35963cf" ); const LLUUID obj_id( vobj->getID() ); @@ -5856,6 +5883,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) #else bool is_pbr = false; #endif +#else + bool is_pbr = facep->getTextureEntry()->getGLTFMaterial() != nullptr; +#endif //ALWAYS null out vertex buffer on rebuild -- if the face lands in a render // batch, it will recover its vertex buffer reference from the spatial group -- cgit v1.2.3