SL-17653 WIP - Apply GLTF material in Material Editor to selected object when you click "Save"

master
Dave Parks 2022-06-23 16:21:53 -05:00
parent 54edd8ba8b
commit 394479d7cc
9 changed files with 156 additions and 23 deletions

View File

@ -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();

View File

@ -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);

View File

@ -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<LLGLTFMaterial> 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

View File

@ -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();
}
}
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);
}
}
}

View File

@ -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

View File

@ -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<LLGLTFMaterial> 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<LLViewerTexture> mNormalMap;
const LLMatrix4* mNormalMapMatrix;
LLPointer<LLViewerTexture> mEmissiveMap;
LLVector4 mSpecColor; // XYZ = Specular RGB, W = Specular Exponent
F32 mEnvIntensity;
F32 mAlphaMaskCutoff;

View File

@ -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;

View File

@ -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<LLViewerTexture> *mTEImages;
LLPointer<LLViewerTexture> *mTENormalMaps;
LLPointer<LLViewerTexture> *mTESpecularMaps;
std::vector<LLPointer<LLViewerTexture> > mGLTFAlbedoMaps;
std::vector<LLPointer<LLViewerTexture> > mGLTFNormalMaps;
std::vector<LLPointer<LLViewerTexture> > mGLTFMetallicRoughnessMaps;
std::vector<LLPointer<LLViewerTexture> > mGLTFEmissiveMaps;
// true if user can select this object by clicking under any circumstances (even if pick_unselectable is true)
// can likely be factored out

View File

@ -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