SL-17653 Local gltf materials #3

master
Andrey Kleshchev 2022-08-22 22:11:58 +03:00
parent 0d217dc73c
commit 8a91c13947
7 changed files with 47 additions and 264 deletions

View File

@ -1109,9 +1109,10 @@ void LLLocalBitmapMgr::feedScrollList(LLScrollListCtrl* ctrl)
element["columns"][1]["type"] = "text";
element["columns"][1]["value"] = (*iter)->getShortName();
element["columns"][2]["column"] = "unit_id_HIDDEN";
element["columns"][2]["type"] = "text";
element["columns"][2]["value"] = (*iter)->getTrackingID();
LLSD data;
data["id"] = (*iter)->getTrackingID();
data["type"] = (S32)LLAssetType::AT_TEXTURE;
element["value"] = data;
ctrl->addElement(element);
}

View File

@ -39,24 +39,15 @@
#include <ctime>
/* misc headers */
#include "llagentwearables.h"
#include "llface.h"
#include "llfilepicker.h"
#include "llgltfmateriallist.h"
#include "llimagedimensionsinfo.h"
#include "llimage.h"
#include "llinventoryicon.h"
#include "lllocaltextureobject.h"
#include "llmaterialmgr.h"
#include "llnotificationsutil.h"
#include "llscrolllistctrl.h"
#include "lltexlayerparams.h"
#include "lltinygltfhelper.h"
#include "lltrans.h"
#include "llviewercontrol.h"
#include "llviewerdisplay.h"
#include "llviewerobjectlist.h"
#include "llviewerobject.h"
#include "pipeline.h"
#include "llviewertexture.h"
#include "tinygltf/tiny_gltf.h"
/*=======================================*/
@ -64,10 +55,6 @@
/*=======================================*/
static const F32 LL_LOCAL_TIMER_HEARTBEAT = 3.0;
static const BOOL LL_LOCAL_USE_MIPMAPS = true;
static const S32 LL_LOCAL_DISCARD_LEVEL = 0;
static const bool LL_LOCAL_SLAM_FOR_DEBUG = true;
static const bool LL_LOCAL_REPLACE_ON_DEL = true;
static const S32 LL_LOCAL_UPDATE_RETRIES = 5;
/*=======================================*/
@ -104,7 +91,7 @@ LLLocalGLTFMaterial::LLLocalGLTFMaterial(std::string filename)
/* next phase of unit creation is nearly the same as an update cycle.
we're running updateSelf as a special case with the optional UT_FIRSTUSE
which omits the parts associated with removing the outdated texture */
mValid = updateSelf(UT_FIRSTUSE);
mValid = updateSelf();
}
LLLocalGLTFMaterial::~LLLocalGLTFMaterial()
@ -140,7 +127,7 @@ bool LLLocalGLTFMaterial::getValid()
}
/* update functions */
bool LLLocalGLTFMaterial::updateSelf(EUpdateType optional_firstupdate)
bool LLLocalGLTFMaterial::updateSelf()
{
bool updated = false;
@ -164,24 +151,14 @@ bool LLLocalGLTFMaterial::updateSelf(EUpdateType optional_firstupdate)
if (loadMaterial(raw_material))
{
// decode is successful, we can safely proceed.
LLUUID old_id = LLUUID::null;
if ((optional_firstupdate != UT_FIRSTUSE) && !mWorldID.isNull())
{
old_id = mWorldID;
}
mWorldID.generate();
if (mWorldID.isNull())
{
mWorldID.generate();
}
mLastModified = new_last_modified;
// will replace material if it already exists
gGLTFMaterialList.addMaterial(mWorldID, raw_material);
if (optional_firstupdate != UT_FIRSTUSE)
{
// seek out everything old_id uses and replace it with mWorldID
replaceIDs(old_id, mWorldID);
// remove old_id from material list
gGLTFMaterialList.removeMaterial(old_id);
}
mUpdateRetries = LL_LOCAL_UPDATE_RETRIES;
updated = true;
@ -339,151 +316,6 @@ bool LLLocalGLTFMaterial::loadMaterial(LLPointer<LLGLTFMaterial> mat)
return decode_successful;
}
void LLLocalGLTFMaterial::replaceIDs(LLUUID old_id, LLUUID new_id)
{
// checking for misuse.
if (old_id == new_id)
{
LL_INFOS() << "An attempt was made to replace a texture with itself. (matching UUIDs)" << "\n"
<< "Texture UUID: " << old_id.asString() << LL_ENDL;
return;
}
// processing updates per channel; makes the process scalable.
// the only actual difference is in SetTE* call i.e. SetTETexture, SetTENormal, etc.
updateUserPrims(old_id, new_id, LLRender::DIFFUSE_MAP);
updateUserPrims(old_id, new_id, LLRender::NORMAL_MAP);
updateUserPrims(old_id, new_id, LLRender::SPECULAR_MAP);
// default safeguard image for layers
if (new_id == IMG_DEFAULT)
{
new_id = IMG_DEFAULT_AVATAR;
}
}
// this function sorts the faces from a getFaceList[getNumFaces] into a list of objects
// in order to prevent multiple sendTEUpdate calls per object during updateUserPrims
std::vector<LLViewerObject*> LLLocalGLTFMaterial::prepUpdateObjects(LLUUID old_id, U32 channel)
{
std::vector<LLViewerObject*> obj_list;
// todo: find a way to update materials
/*
LLGLTFMaterial* old_material = gGLTFMaterialList.getMaterial(old_id);
for(U32 face_iterator = 0; face_iterator < old_texture->getNumFaces(channel); face_iterator++)
{
// getting an object from a face
LLFace* face_to_object = (*old_texture->getFaceList(channel))[face_iterator];
if(face_to_object)
{
LLViewerObject* affected_object = face_to_object->getViewerObject();
if(affected_object)
{
// we have an object, we'll take it's UUID and compare it to
// whatever we already have in the returnable object list.
// if there is a match - we do not add (to prevent duplicates)
LLUUID mainlist_obj_id = affected_object->getID();
bool add_object = true;
// begin looking for duplicates
std::vector<LLViewerObject*>::iterator objlist_iter = obj_list.begin();
for(; (objlist_iter != obj_list.end()) && add_object; objlist_iter++)
{
LLViewerObject* obj = *objlist_iter;
if (obj->getID() == mainlist_obj_id)
{
add_object = false; // duplicate found.
}
}
// end looking for duplicates
if(add_object)
{
obj_list.push_back(affected_object);
}
}
}
} // end of face-iterating for()
*/
return obj_list;
}
void LLLocalGLTFMaterial::updateUserPrims(LLUUID old_id, LLUUID new_id, U32 channel)
{
/*std::vector<LLViewerObject*> objectlist = prepUpdateObjects(old_id, channel);
for(std::vector<LLViewerObject*>::iterator object_iterator = objectlist.begin();
object_iterator != objectlist.end(); object_iterator++)
{
LLViewerObject* object = *object_iterator;
if(object)
{
bool update_tex = false;
bool update_mat = false;
S32 num_faces = object->getNumFaces();
for (U8 face_iter = 0; face_iter < num_faces; face_iter++)
{
if (object->mDrawable)
{
LLFace* face = object->mDrawable->getFace(face_iter);
if (face && face->getTexture(channel) && face->getTexture(channel)->getID() == old_id)
{
// these things differ per channel, unless there already is a universal
// texture setting function to setTE that takes channel as a param?
// p.s.: switch for now, might become if - if an extra test is needed to verify before touching normalmap/specmap
switch(channel)
{
case LLRender::DIFFUSE_MAP:
{
object->setTETexture(face_iter, new_id);
update_tex = true;
break;
}
case LLRender::NORMAL_MAP:
{
object->setTENormalMap(face_iter, new_id);
update_mat = true;
update_tex = true;
break;
}
case LLRender::SPECULAR_MAP:
{
object->setTESpecularMap(face_iter, new_id);
update_mat = true;
update_tex = true;
break;
}
}
// end switch
}
}
}
if (update_tex)
{
object->sendTEUpdate();
}
if (update_mat)
{
object->mDrawable->getVOVolume()->faceMappingChanged();
}
}
}
*/
}
/*=======================================*/
/* LLLocalGLTFMaterialTimer: timer class */
@ -584,7 +416,7 @@ bool LLLocalGLTFMaterialMgr::addUnit(const std::string& filename)
LLSD notif_args;
notif_args["FNAME"] = filename;
LLNotificationsUtil::add("LocalBitmapsVerifyFail", notif_args);
LLNotificationsUtil::add("LocalGLTFVerifyFail", notif_args);
delete unit;
unit = NULL;
@ -663,6 +495,7 @@ std::string LLLocalGLTFMaterialMgr::getFilename(LLUUID tracking_id)
return filename;
}
// probably shouldn't be here, but at the moment this mirrors lllocalbitmaps
void LLLocalGLTFMaterialMgr::feedScrollList(LLScrollListCtrl* ctrl)
{
if (ctrl)
@ -686,9 +519,10 @@ void LLLocalGLTFMaterialMgr::feedScrollList(LLScrollListCtrl* ctrl)
element["columns"][1]["type"] = "text";
element["columns"][1]["value"] = (*iter)->getShortName();
element["columns"][2]["column"] = "unit_id_HIDDEN";
element["columns"][2]["type"] = "text";
element["columns"][2]["value"] = (*iter)->getTrackingID();
LLSD data;
data["id"] = (*iter)->getTrackingID();
data["type"] = (S32)LLAssetType::AT_MATERIAL;
element["value"] = data;
ctrl->addElement(element);
}

View File

@ -48,20 +48,11 @@ public: /* accessors */
LLUUID getWorldID();
bool getValid();
public: /* self update public section */
enum EUpdateType
{
UT_FIRSTUSE,
UT_REGUPDATE
};
public:
bool updateSelf();
bool updateSelf(EUpdateType = UT_REGUPDATE);
private: /* self update private section */
private:
bool loadMaterial(LLPointer<LLGLTFMaterial> raw);
void replaceIDs(LLUUID old_id, LLUUID new_id);
std::vector<LLViewerObject*> prepUpdateObjects(LLUUID old_id, U32 channel);
void updateUserPrims(LLUUID old_id, LLUUID new_id, U32 channel);
private: /* private enums */
enum ELinkStatus

View File

@ -1048,36 +1048,6 @@ void LLMaterialFilePicker::notify(const std::vector<std::string>& filenames)
}
}
static void strip_alpha_channel(LLPointer<LLImageRaw>& img)
{
if (img->getComponents() == 4)
{
LLImageRaw* tmp = new LLImageRaw(img->getWidth(), img->getHeight(), 3);
tmp->copyUnscaled4onto3(img);
img = tmp;
}
}
// copy red channel from src_img to dst_img
// PRECONDITIONS:
// dst_img must be 3 component
// src_img and dst_image must have the same dimensions
static void copy_red_channel(LLPointer<LLImageRaw>& src_img, LLPointer<LLImageRaw>& dst_img)
{
llassert(src_img->getWidth() == dst_img->getWidth() && src_img->getHeight() == dst_img->getHeight());
llassert(dst_img->getComponents() == 3);
U32 pixel_count = dst_img->getWidth() * dst_img->getHeight();
U8* src = src_img->getData();
U8* dst = dst_img->getData();
S8 src_components = src_img->getComponents();
for (U32 i = 0; i < pixel_count; ++i)
{
dst[i * 3] = src[i * src_components];
}
}
static void pack_textures(
LLPointer<LLImageRaw>& albedo_img,
LLPointer<LLImageRaw>& normal_img,

View File

@ -78,15 +78,6 @@
#include "llavatarappearancedefines.h"
static const S32 LOCAL_ICON_ID_COLUMN = 0;
static const S32 LOCAL_TRACKING_ID_COLUMN = 2;
//static const char CURRENT_IMAGE_NAME[] = "Current Texture";
//static const char WHITE_IMAGE_NAME[] = "Blank Texture";
//static const char NO_IMAGE_NAME[] = "None";
//static
bool get_is_predefined_texture(LLUUID asset_id)
{
@ -756,14 +747,11 @@ void LLFloaterTexturePicker::onBtnSelect(void* userdata)
{
if (self->mLocalScrollCtrl->getVisible() && !self->mLocalScrollCtrl->getAllSelected().empty())
{
std::string icon_name = self->mLocalScrollCtrl->getFirstSelected()->getColumn(LOCAL_ICON_ID_COLUMN)->getValue().asString();
LLUUID temp_id = self->mLocalScrollCtrl->getFirstSelected()->getColumn(LOCAL_TRACKING_ID_COLUMN)->getValue().asUUID();
LLSD data = self->mLocalScrollCtrl->getFirstSelected()->getValue();
LLUUID temp_id = data["id"];
S32 asset_type = data["type"].asInteger();
std::string mat_icon_name = LLInventoryIcon::getIconName(
LLAssetType::AT_MATERIAL,
LLInventoryType::IT_NONE);
if (mat_icon_name == icon_name)
if (LLAssetType::AT_MATERIAL == asset_type)
{
local_id = LLLocalGLTFMaterialMgr::getInstance()->getWorldID(temp_id);
}
@ -931,9 +919,6 @@ void LLFloaterTexturePicker::onBtnRemove(void* userdata)
if (!selected_items.empty())
{
std::string mat_icon_name = LLInventoryIcon::getIconName(
LLAssetType::AT_MATERIAL,
LLInventoryType::IT_NONE);
for(std::vector<LLScrollListItem*>::iterator iter = selected_items.begin();
iter != selected_items.end(); iter++)
@ -941,11 +926,11 @@ void LLFloaterTexturePicker::onBtnRemove(void* userdata)
LLScrollListItem* list_item = *iter;
if (list_item)
{
std::string icon_name = list_item->getColumn(LOCAL_ICON_ID_COLUMN)->getValue().asString();
LLUUID tracking_id = list_item->getColumn(LOCAL_TRACKING_ID_COLUMN)->getValue().asUUID();
LLSD data = self->mLocalScrollCtrl->getFirstSelected()->getValue();
LLUUID tracking_id = data["id"];
S32 asset_type = data["type"].asInteger();
// todo: works, but need a better way to distinguish material from texture
if (icon_name == mat_icon_name)
if (LLAssetType::AT_MATERIAL == asset_type)
{
LLLocalGLTFMaterialMgr::getInstance()->delUnit(tracking_id);
}
@ -978,14 +963,11 @@ void LLFloaterTexturePicker::onBtnUpload(void* userdata)
/* currently only allows uploading one by one, picks the first item from the selection list. (not the vector!)
in the future, it might be a good idea to check the vector size and if more than one units is selected - opt for multi-image upload. */
std::string icon_name = self->mLocalScrollCtrl->getFirstSelected()->getColumn(LOCAL_ICON_ID_COLUMN)->getValue().asString();
LLUUID tracking_id = (LLUUID)self->mLocalScrollCtrl->getSelectedItemLabel(LOCAL_TRACKING_ID_COLUMN);
LLSD data = self->mLocalScrollCtrl->getFirstSelected()->getValue();
LLUUID tracking_id = data["id"];
S32 asset_type = data["type"].asInteger();
std::string mat_icon_name = LLInventoryIcon::getIconName(
LLAssetType::AT_MATERIAL,
LLInventoryType::IT_NONE);
if (mat_icon_name == icon_name)
if (LLAssetType::AT_MATERIAL == asset_type)
{
std::string filename = LLLocalGLTFMaterialMgr::getInstance()->getFilename(tracking_id);
if (!filename.empty())
@ -1020,15 +1002,12 @@ void LLFloaterTexturePicker::onLocalScrollCommit(LLUICtrl* ctrl, void* userdata)
if (has_selection)
{
std::string icon_name = self->mLocalScrollCtrl->getFirstSelected()->getColumn(LOCAL_ICON_ID_COLUMN)->getValue().asString();
LLUUID tracking_id = (LLUUID)self->mLocalScrollCtrl->getSelectedItemLabel(LOCAL_TRACKING_ID_COLUMN);
LLSD data = self->mLocalScrollCtrl->getFirstSelected()->getValue();
LLUUID tracking_id = data["id"];
S32 asset_type = data["type"].asInteger();
LLUUID inworld_id;
std::string mat_icon_name = LLInventoryIcon::getIconName(
LLAssetType::AT_MATERIAL,
LLInventoryType::IT_NONE);
if (icon_name == mat_icon_name)
if (LLAssetType::AT_MATERIAL == asset_type)
{
inworld_id = LLLocalGLTFMaterialMgr::getInstance()->getWorldID(tracking_id);
}

View File

@ -242,7 +242,6 @@
visible="false">
<column name="icon" label="" width="20" />
<column name="unit_name" label="Name" dynamicwidth="true" />
<column name="unit_id_HIDDEN" label="ID" width="0" />
</scroll_list>
<!-- middle: bake mode -->

View File

@ -9802,6 +9802,15 @@ Attempted to add an invalid or unreadable image file [FNAME] which could not be
Attempt cancelled.
</notification>
<notification
icon="alertmodal.tga"
name="LocalGLTFVerifyFail"
persist="true"
type="notify">
Attempted to add an invalid or unreadable GLTF material [FNAME] which could not be opened or decoded.
Attempt cancelled.
</notification>
<notification
icon="alertmodal.tga"
name="PathfindingReturnMultipleItems"