From c8499b7f01ac3f46f0764ea8195c30a4a2ec27a8 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Tue, 8 Apr 2025 13:51:21 -0400 Subject: [PATCH 001/187] GLTF WIP. Still working on getting transforms working proper and need to figure out our indices. --- indra/llprimitive/CMakeLists.txt | 2 - indra/newview/CMakeLists.txt | 2 + indra/newview/gltf/asset.cpp | 20 ++- indra/newview/gltf/asset.h | 3 + .../gltf}/llgltfloader.cpp | 135 +++++++++++------- .../gltf}/llgltfloader.h | 5 +- indra/newview/llfilepicker.cpp | 2 +- indra/newview/llmodelpreview.cpp | 2 +- 8 files changed, 105 insertions(+), 66 deletions(-) rename indra/{llprimitive => newview/gltf}/llgltfloader.cpp (79%) rename indra/{llprimitive => newview/gltf}/llgltfloader.h (98%) diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt index 3d8e02cb16..e13f0bbd96 100644 --- a/indra/llprimitive/CMakeLists.txt +++ b/indra/llprimitive/CMakeLists.txt @@ -12,7 +12,6 @@ include(TinyGLTF) set(llprimitive_SOURCE_FILES lldaeloader.cpp - llgltfloader.cpp llgltfmaterial.cpp llmaterialid.cpp llmaterial.cpp @@ -32,7 +31,6 @@ set(llprimitive_SOURCE_FILES set(llprimitive_HEADER_FILES CMakeLists.txt lldaeloader.h - llgltfloader.h llgltfmaterial.h llgltfmaterial_templates.h legacy_object_types.h diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index ed29911a43..7dfe01898a 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -76,6 +76,7 @@ set(viewer_SOURCE_FILES gltf/accessor.cpp gltf/primitive.cpp gltf/animation.cpp + gltf/llgltfloader.cpp groupchatlistener.cpp llaccountingcostmanager.cpp llaisapi.cpp @@ -744,6 +745,7 @@ set(viewer_HEADER_FILES gltf/buffer_util.h gltf/primitive.h gltf/animation.h + gltf/llgltfloader.h llaccountingcost.h llaccountingcostmanager.h llaisapi.h diff --git a/indra/newview/gltf/asset.cpp b/indra/newview/gltf/asset.cpp index c210b9c61d..beccb02bd4 100644 --- a/indra/newview/gltf/asset.cpp +++ b/indra/newview/gltf/asset.cpp @@ -472,11 +472,14 @@ void Asset::update() for (auto& image : mImages) { - if (image.mTexture.notNull()) - { // HACK - force texture to be loaded full rez - // TODO: calculate actual vsize - image.mTexture->addTextureStats(2048.f * 2048.f); - image.mTexture->setBoostLevel(LLViewerTexture::BOOST_HIGH); + if (image.mLoadIntoTexturePipe) + { + if (image.mTexture.notNull()) + { // HACK - force texture to be loaded full rez + // TODO: calculate actual vsize + image.mTexture->addTextureStats(2048.f * 2048.f); + image.mTexture->setBoostLevel(LLViewerTexture::BOOST_HIGH); + } } } } @@ -603,6 +606,7 @@ bool Asset::prep() if (vertex_count[variant] > 0) { U32 mat_idx = mat_id + 1; + #if 0 LLVertexBuffer* vb = new LLVertexBuffer(attribute_mask); rd.mBatches[variant][mat_idx].mVertexBuffer = vb; @@ -624,6 +628,7 @@ bool Asset::prep() vb->unmapBuffer(); vb->unbind(); + #endif } } } @@ -634,10 +639,10 @@ bool Asset::prep() { for (auto& primitive : mesh.mPrimitives) { - llassert(primitive.mVertexBuffer.notNull()); + //llassert(primitive.mVertexBuffer.notNull()); } } - + #if 0 // build render batches for (S32 node_id = 0; node_id < mNodes.size(); ++node_id) { @@ -664,6 +669,7 @@ bool Asset::prep() } } } + #endif return true; } diff --git a/indra/newview/gltf/asset.h b/indra/newview/gltf/asset.h index 27821659db..e70fffa986 100644 --- a/indra/newview/gltf/asset.h +++ b/indra/newview/gltf/asset.h @@ -286,6 +286,7 @@ namespace LL void serialize(boost::json::object& dst) const; }; + // Image is for images that we want to load for the given asset. This acts as an interface into the viewer's texture pipe. class Image { public: @@ -301,6 +302,8 @@ namespace LL S32 mBits = -1; S32 mPixelType = -1; + bool mLoadIntoTexturePipe = false; + LLPointer mTexture; const Image& operator=(const Value& src); diff --git a/indra/llprimitive/llgltfloader.cpp b/indra/newview/gltf/llgltfloader.cpp similarity index 79% rename from indra/llprimitive/llgltfloader.cpp rename to indra/newview/gltf/llgltfloader.cpp index 480012699a..106c20d4d3 100644 --- a/indra/llprimitive/llgltfloader.cpp +++ b/indra/newview/gltf/llgltfloader.cpp @@ -106,16 +106,7 @@ bool LLGLTFLoader::OpenFile(const std::string &filename) std::string filename_lc(filename); LLStringUtil::toLower(filename_lc); - // Load a tinygltf model fom a file. Assumes that the input filename has already been - // been sanitized to one of (.gltf , .glb) extensions, so does a simple find to distinguish. - if (std::string::npos == filename_lc.rfind(".gltf")) - { // file is binary - mGltfLoaded = loader.LoadBinaryFromFile(&mGltfModel, &error_msg, &warn_msg, filename); - } - else - { // file is ascii - mGltfLoaded = loader.LoadASCIIFromFile(&mGltfModel, &error_msg, &warn_msg, filename); - } + mGltfLoaded = mGLTFAsset.load(filename); if (!mGltfLoaded) { @@ -129,10 +120,14 @@ bool LLGLTFLoader::OpenFile(const std::string &filename) mMeshesLoaded = parseMeshes(); if (mMeshesLoaded) uploadMeshes(); + /* mMaterialsLoaded = parseMaterials(); if (mMaterialsLoaded) uploadMaterials(); + */ - return (mMeshesLoaded || mMaterialsLoaded); + setLoadState(DONE); + + return (mMeshesLoaded); } bool LLGLTFLoader::parseMeshes() @@ -143,71 +138,102 @@ bool LLGLTFLoader::parseMeshes() LLVolumeParams volume_params; volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE); - for (tinygltf::Mesh mesh : mGltfModel.meshes) + for (auto node : mGLTFAsset.mNodes) { - LLModel *pModel = new LLModel(volume_params, 0.f); + LLMatrix4 transform; + material_map mats; + auto meshidx = node.mMesh; - if (populateModelFromMesh(pModel, mesh) && - (LLModel::NO_ERRORS == pModel->getStatus()) && - validate_model(pModel)) + if (meshidx >= 0) { - mModelList.push_back(pModel); - } - else - { - setLoadState(ERROR_MODEL + pModel->getStatus()); - delete(pModel); - return false; + LLModel* pModel = new LLModel(volume_params, 0.f); + auto mesh = mGLTFAsset.mMeshes[meshidx]; + + if (populateModelFromMesh(pModel, mesh, mats) && (LLModel::NO_ERRORS == pModel->getStatus()) && validate_model(pModel)) + { + mModelList.push_back(pModel); + LLVector3 mesh_scale_vector; + LLVector3 mesh_translation_vector; + pModel->getNormalizedScaleTranslation(mesh_scale_vector, mesh_translation_vector); + + LLMatrix4 mesh_translation; + mesh_translation.setTranslation(mesh_translation_vector); + mesh_translation *= transform; + transform = mesh_translation; + + LLMatrix4 mesh_scale; + mesh_scale.initScale(mesh_scale_vector); + mesh_scale *= transform; + transform = mesh_scale; + + + mScene[transform].push_back(LLModelInstance(pModel, node.mName, transform, mats)); + } + else + { + setLoadState(ERROR_MODEL + pModel->getStatus()); + delete (pModel); + return false; + } } } + return true; } - -bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const tinygltf::Mesh &mesh) + +bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh &mesh, material_map &mats) { - pModel->mLabel = mesh.name; - int pos_idx; - tinygltf::Accessor indices_a, positions_a, normals_a, uv0_a, color0_a; + pModel->mLabel = mesh.mName; + pModel->ClearFacesAndMaterials(); - auto prims = mesh.primitives; + auto prims = mesh.mPrimitives; for (auto prim : prims) { - if (prim.indices >= 0) indices_a = mGltfModel.accessors[prim.indices]; + // So primitives already have all of the data we need for a given face in SL land. + // Primitives may only ever have a single material assigned to them - as the relation is 1:1 in terms of intended draw call count. + // Just go ahead and populate faces direct from the GLTF primitives here. + // -Geenz 2025-04-07 + LLVolumeFace face; + LLVolumeFace::VertexMapData::PointMap point_map; + + std::vector vertices; + std::vector indices; + + LLImportMaterial impMat; + + auto material = mGLTFAsset.mMaterials[prim.mMaterial]; - pos_idx = (prim.attributes.count("POSITION") > 0) ? prim.attributes.at("POSITION") : -1; - if (pos_idx >= 0) + impMat.mDiffuseColor = LLColor4::white; + + + for (U32 i = 0; i < prim.getVertexCount(); i++) { - positions_a = mGltfModel.accessors[pos_idx]; - if (TINYGLTF_COMPONENT_TYPE_FLOAT != positions_a.componentType) - continue; - auto positions_bv = mGltfModel.bufferViews[positions_a.bufferView]; - auto positions_buf = mGltfModel.buffers[positions_bv.buffer]; - //auto type = positions_vb. - //if (positions_buf.name + LLVolumeFace::VertexData vert; + vert.setPosition(prim.mPositions[i]); + vert.setNormal(prim.mNormals[i]); + vert.mTexCoord = prim.mTexCoords0[i]; + vertices.push_back(vert); } -#if 0 - int norm_idx, tan_idx, uv0_idx, uv1_idx, color0_idx, color1_idx; - norm_idx = (prim.attributes.count("NORMAL") > 0) ? prim.attributes.at("NORMAL") : -1; - tan_idx = (prim.attributes.count("TANGENT") > 0) ? prim.attributes.at("TANGENT") : -1; - uv0_idx = (prim.attributes.count("TEXCOORDS_0") > 0) ? prim.attributes.at("TEXCOORDS_0") : -1; - uv1_idx = (prim.attributes.count("TEXCOORDS_1") > 0) ? prim.attributes.at("TEXCOORDS_1") : -1; - color0_idx = (prim.attributes.count("COLOR_0") > 0) ? prim.attributes.at("COLOR_0") : -1; - color1_idx = (prim.attributes.count("COLOR_1") > 0) ? prim.attributes.at("COLOR_1") : -1; -#endif - - if (prim.mode == TINYGLTF_MODE_TRIANGLES) + for (S32 i = 0; i < prim.mIndexArray.size(); i++) { - //auto pos = mesh. TODO resume here DJH 2022-04 + indices.push_back(prim.mIndexArray[i]); } + + face.fillFromLegacyData(vertices, indices); + + pModel->getVolumeFaces().push_back(face); + pModel->getMaterialList().push_back("mat" + std::to_string(prim.mMaterial)); + mats["mat" + std::to_string(prim.mMaterial)] = impMat; } - //pModel->addFace() - return false; + return true; } bool LLGLTFLoader::parseMaterials() { + return true; + /* if (!mGltfLoaded) return false; // fill local texture data structures @@ -329,12 +355,13 @@ bool LLGLTFLoader::parseMaterials() } return true; + */ } // TODO: convert raw vertex buffers to UUIDs void LLGLTFLoader::uploadMeshes() { - llassert(0); + //llassert(0); } // convert raw image buffers to texture UUIDs & assemble into a render material diff --git a/indra/llprimitive/llgltfloader.h b/indra/newview/gltf/llgltfloader.h similarity index 98% rename from indra/llprimitive/llgltfloader.h rename to indra/newview/gltf/llgltfloader.h index 66671d1c5a..3b7147f588 100644 --- a/indra/llprimitive/llgltfloader.h +++ b/indra/newview/gltf/llgltfloader.h @@ -29,6 +29,8 @@ #include "tinygltf/tiny_gltf.h" +#include "asset.h" + #include "llglheaders.h" #include "llmodelloader.h" @@ -138,6 +140,7 @@ class LLGLTFLoader : public LLModelLoader virtual bool OpenFile(const std::string &filename); protected: + LL::GLTF::Asset mGLTFAsset; tinygltf::Model mGltfModel; bool mGltfLoaded; bool mMeshesLoaded; @@ -155,7 +158,7 @@ class LLGLTFLoader : public LLModelLoader void uploadMeshes(); bool parseMaterials(); void uploadMaterials(); - bool populateModelFromMesh(LLModel* pModel, const tinygltf::Mesh &mesh); + bool populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh &mesh, material_map& mats); LLUUID imageBufferToTextureUUID(const gltf_texture& tex); // bool mPreprocessGLTF; diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp index 716e6cd9e3..09a2206cd7 100644 --- a/indra/newview/llfilepicker.cpp +++ b/indra/newview/llfilepicker.cpp @@ -59,7 +59,7 @@ LLFilePicker LLFilePicker::sInstance; #define XML_FILTER L"XML files (*.xml)\0*.xml\0" #define SLOBJECT_FILTER L"Objects (*.slobject)\0*.slobject\0" #define RAW_FILTER L"RAW files (*.raw)\0*.raw\0" -#define MODEL_FILTER L"Model files (*.dae)\0*.dae\0" +#define MODEL_FILTER L"Model files (*.dae, *.gltf, *.glb)\0*.dae;*.gltf;*.glb\0" #define MATERIAL_FILTER L"GLTF Files (*.gltf; *.glb)\0*.gltf;*.glb\0" #define HDRI_FILTER L"HDRI Files (*.exr)\0*.exr\0" #define MATERIAL_TEXTURES_FILTER L"GLTF Import (*.gltf; *.glb; *.tga; *.bmp; *.jpg; *.jpeg; *.png)\0*.gltf;*.glb;*.tga;*.bmp;*.jpg;*.jpeg;*.png\0" diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index 5a8fd299bf..14d23b73c9 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -30,7 +30,7 @@ #include "llmodelloader.h" #include "lldaeloader.h" -#include "llgltfloader.h" +#include "gltf/llgltfloader.h" #include "llfloatermodelpreview.h" #include "llagent.h" From b489134119c71dd4cfd329b3fd50a2bb56fbe61e Mon Sep 17 00:00:00 2001 From: Ansariel Hiller Date: Fri, 20 Sep 2024 19:07:02 +0200 Subject: [PATCH 002/187] Restore option to change location of existing pick --- indra/newview/llpanelprofilepicks.cpp | 42 +++++++++++++++++++ indra/newview/llpanelprofilepicks.h | 10 ++++- .../default/xui/en/panel_profile_pick.xml | 20 +++++++++ 3 files changed, 71 insertions(+), 1 deletion(-) diff --git a/indra/newview/llpanelprofilepicks.cpp b/indra/newview/llpanelprofilepicks.cpp index a87ef4f0f9..c9626bf9ea 100644 --- a/indra/newview/llpanelprofilepicks.cpp +++ b/indra/newview/llpanelprofilepicks.cpp @@ -248,6 +248,8 @@ void LLPanelProfilePicks::onClickNewBtn() select_tab(true). label(pick_panel->getPickName())); updateButtons(); + + pick_panel->addLocationChangedCallbacks(); } void LLPanelProfilePicks::onClickDelete() @@ -607,10 +609,12 @@ void LLPanelProfilePick::setAvatarId(const LLUUID& avatar_id) { mPickName->setEnabled(true); mPickDescription->setEnabled(true); + mSetCurrentLocationButton->setVisible(true); } else { mSnapshotCtrl->setEnabled(false); + mSetCurrentLocationButton->setVisible(false); } } @@ -621,6 +625,7 @@ bool LLPanelProfilePick::postBuild() mSaveButton = getChild("save_changes_btn"); mCreateButton = getChild("create_changes_btn"); mCancelButton = getChild("cancel_changes_btn"); + mSetCurrentLocationButton = getChild("set_to_curr_location_btn"); mSnapshotCtrl = getChild("pick_snapshot"); mSnapshotCtrl->setCommitCallback(boost::bind(&LLPanelProfilePick::onSnapshotChanged, this)); @@ -633,6 +638,7 @@ bool LLPanelProfilePick::postBuild() mSaveButton->setCommitCallback(boost::bind(&LLPanelProfilePick::onClickSave, this)); mCreateButton->setCommitCallback(boost::bind(&LLPanelProfilePick::onClickSave, this)); mCancelButton->setCommitCallback(boost::bind(&LLPanelProfilePick::onClickCancel, this)); + mSetCurrentLocationButton->setCommitCallback(boost::bind(&LLPanelProfilePick::onClickSetLocation, this)); mPickName->setKeystrokeCallback(boost::bind(&LLPanelProfilePick::onPickChanged, this, _1), NULL); mPickName->setEnabled(false); @@ -811,6 +817,32 @@ bool LLPanelProfilePick::isDirty() const return false; } +void LLPanelProfilePick::onClickSetLocation() +{ + // Save location for later use. + setPosGlobal(gAgent.getPositionGlobal()); + + std::string parcel_name, region_name; + + LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); + if (parcel) + { + mParcelId = parcel->getID(); + parcel_name = parcel->getName(); + } + + LLViewerRegion* region = gAgent.getRegion(); + if (region) + { + region_name = region->getName(); + } + + setPickLocation(createLocationText(getLocationNotice(), parcel_name, region_name, getPosGlobal())); + + mLocationChanged = true; + enableSaveButton(true); +} + void LLPanelProfilePick::onClickSave() { if (mRegionCallbackConnection.connected()) @@ -821,6 +853,10 @@ void LLPanelProfilePick::onClickSave() { mParcelCallbackConnection.disconnect(); } + if (mLocationChanged) + { + onClickSetLocation(); + } sendUpdate(); mLocationChanged = false; @@ -871,6 +907,12 @@ void LLPanelProfilePick::processParcelInfo(const LLParcelData& parcel_data) } } +void LLPanelProfilePick::addLocationChangedCallbacks() +{ + mRegionCallbackConnection = gAgent.addRegionChangedCallback([this]() { onClickSetLocation(); }); + mParcelCallbackConnection = gAgent.addParcelChangedCallback([this]() { onClickSetLocation(); }); +} + void LLPanelProfilePick::setParcelID(const LLUUID& parcel_id) { if (mParcelId != parcel_id) diff --git a/indra/newview/llpanelprofilepicks.h b/indra/newview/llpanelprofilepicks.h index b4d3eb010e..847ac57cea 100644 --- a/indra/newview/llpanelprofilepicks.h +++ b/indra/newview/llpanelprofilepicks.h @@ -141,6 +141,8 @@ class LLPanelProfilePick LLUUID getParcelID() const { return mParcelId; } void setErrorStatus(S32 status, const std::string& reason) override {}; + void addLocationChangedCallbacks(); + protected: /** @@ -202,6 +204,11 @@ class LLPanelProfilePick */ void resetDirty() override; + /** + * Callback for "Set Location" button click + */ + void onClickSetLocation(); + /** * Callback for "Save" and "Create" button click */ @@ -224,6 +231,7 @@ class LLPanelProfilePick LLTextureCtrl* mSnapshotCtrl; LLLineEditor* mPickName; LLTextEditor* mPickDescription; + LLButton* mSetCurrentLocationButton; LLButton* mSaveButton; LLButton* mCreateButton; LLButton* mCancelButton; @@ -241,7 +249,7 @@ class LLPanelProfilePick bool mLocationChanged; bool mNewPick; - bool mIsEditing; + bool mIsEditing; void onDescriptionFocusReceived(); }; diff --git a/indra/newview/skins/default/xui/en/panel_profile_pick.xml b/indra/newview/skins/default/xui/en/panel_profile_pick.xml index 024120931f..4f441b9b49 100644 --- a/indra/newview/skins/default/xui/en/panel_profile_pick.xml +++ b/indra/newview/skins/default/xui/en/panel_profile_pick.xml @@ -198,6 +198,26 @@ /> + +