diff --git a/.github/workflows/build_viewer.yml b/.github/workflows/build_viewer.yml
index d0a6255abf..e4d0f3aa52 100644
--- a/.github/workflows/build_viewer.yml
+++ b/.github/workflows/build_viewer.yml
@@ -9,11 +9,18 @@ on:
- "*preview"
schedule:
- cron: '00 03 * * *' # Run every day at 3am UTC
-env:
+env:
AUTOBUILD_VARIABLES_FILE: ${{github.workspace}}/build-variables/variables
EXTRA_ARGS: -DUSE_FMODSTUDIO=ON -DUSE_KDU=ON --crashreporting
build_secrets_checkout: ${{github.workspace}}/signing
XZ_DEFAULTS: -T0
+ FS_RELEASE_TYPE: Unknown
+ platform: Unknown
+ fallback_platform: ${platform}
+ FS_RELEASE_CHAN: ${FS_RELEASE_TYPE}x64
+ FS_GRID: "GRID FLAGS NOT SET"
+ PYTHON:
+
jobs:
build_matrix:
strategy:
@@ -22,6 +29,9 @@ jobs:
grid: [sl,os]
addrsize: [64]
runs-on: ${{ matrix.os }}
+ outputs:
+ viewer_channel: ${{ steps.channel.outputs.viewer_channel }}
+ viewer_version: ${{ steps.version.outputs.viewer_version }}
steps:
- name: Install Bash 4 and GNU sed on Mac
if: runner.os == 'macOS'
@@ -36,15 +46,20 @@ jobs:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
- id: py312
+ id: py311
with:
- python-version: '3.11.6'
- cache: 'pip'
+ python-version: '3.11'
+
+ - name: Set PYTHON environment for CMake
+ run: |
+ echo "PYTHON=${{ steps.py311.outputs.python-path }}" >> $GITHUB_ENV
+ shell: bash
- name: Install python requirements
run: |
python3 -m pip install -r requirements.txt
python -m pip install -r requirements.txt
+ # export the new python to the environment var $PYTHON
- name: Check python version
run: python -V
@@ -90,6 +105,7 @@ jobs:
shell: bash
- name: find channel from Branch name
+ id: channel
run: |
if [[ "${{ github.ref_name }}" == Firestorm* ]]; then
FS_RELEASE_TYPE=Release
@@ -110,6 +126,7 @@ jobs:
echo "FS_RELEASE_TYPE=${FS_RELEASE_TYPE}" >> $GITHUB_ENV
echo "FS_RELEASE_CHAN=${FS_RELEASE_CHAN}" >> $GITHUB_ENV
echo "Building for channel ${FS_RELEASE_CHAN}"
+ viewer_channel=${FS_RELEASE_CHAN}
shell: bash
- name: Get the code
@@ -238,9 +255,18 @@ jobs:
shell: bash
- name: build
+ id: build
run: autobuild build -c ReleaseFS -A${{matrix.addrsize}} --no-configure
shell: bash
-
+ # - name: Extract version number
+ # id: version
+ # shell: bash
+ # run: |
+ # if [ -r "indra/newview/viewer_version.txt" ]
+ # then
+ # viewer_version="$(<"$build_dir/newview/viewer_version.txt")"
+ # echo "viewer_version=$viewer_version" >> "$GITHUB_OUTPUT"
+ # fi
- name: Publish artifacts
if: runner.os == 'Windows'
uses: actions/upload-artifact@v3
@@ -267,9 +293,37 @@ jobs:
path: |
build-darwin-*/newview/*.dmg
build-darwin-*/newview/*.bz2
+ # post-windows-symbols:
+ # needs: build_matrix
+ # runs-on: ubuntu-latest
+ # steps:
+ # - name: Post Windows symbols
+ # uses: secondlife/viewer-build-util/post-bugsplat-windows@v1
+ # with:
+ # username: ${{ secrets.BUGSPLAT_USER }}
+ # password: ${{ secrets.BUGSPLAT_PASS }}
+ # database: "firestorm_release"
+ # channel: ${{ needs.build_matrix.outputs.viewer_channel }}
+ # version: ${{ needs.build_matrix.outputs.viewer_version }}
+
+ # post-mac-symbols:
+ # needs: build_matrix
+ # runs-on: ubuntu-latest
+ # steps:
+ # - name: Post Mac symbols
+ # uses: secondlife/viewer-build-util/post-bugsplat-mac@v1
+ # with:
+ # username: ${{ secrets.BUGSPLAT_USER }}
+ # password: ${{ secrets.BUGSPLAT_PASS }}
+ # database: "firestorm_release"
+ # channel: ${{ needs.build_matrix.outputs.viewer_channel }}
+ # version: ${{ needs.build_matrix.outputs.viewer_version }}
deploy:
runs-on: ubuntu-latest
needs: build_matrix
+ env:
+ FS_BUILD_WEBHOOK_URL:
+ FS_RELEASE_FOLDER:
if: always()
steps:
- name: Checkout files
diff --git a/FIRESTORM-SOURCE_LICENSE_HEADER.txt b/FIRESTORM-SOURCE_LICENSE_HEADER.txt
index 19eedbfa2e..44f7834caf 100644
--- a/FIRESTORM-SOURCE_LICENSE_HEADER.txt
+++ b/FIRESTORM-SOURCE_LICENSE_HEADER.txt
@@ -2,9 +2,9 @@
* @file
* @brief
*
- * $LicenseInfo:firstyear=2023&license=fsviewerlgpl$
+ * $LicenseInfo:firstyear=2024&license=fsviewerlgpl$
* Phoenix Firestorm Viewer Source Code
- * Copyright (C) 2020, The Phoenix Firestorm Project, Inc.
+ * Copyright (C) 2024, The Phoenix Firestorm Project, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
diff --git a/README.md b/README.md
new file mode 100644
index 0000000000..cb09b89340
--- /dev/null
+++ b/README.md
@@ -0,0 +1,29 @@
+
+
+
+
+**[Firestorm](https://www.firestormviewer.org/) is a free client for 3D virtual worlds such as Second Life and various OpenSim worlds where users can create, connect and chat with others from around the world.** This repository contains the official source code for the Firestorm viewer.
+
+## Open Source
+
+Firestorm is a third party viewer derived from the official [Second Life](https://github.com/secondlife/viewer) client. The client codebase has been open source since 2007 and is available under the LGPL license.
+
+## Download
+
+Pre-built versions of the viewer releases for Windows, Mac and Linux can be downloaded from the [official website](https://www.firestormviewer.org/choose-your-platform/).
+
+## Build Instructions
+
+Build instructions for each operating system can be found in the official [wiki](https://wiki.firestormviewer.org/).
+
+- [Windows](https://wiki.firestormviewer.org/fs_compiling_firestorm_windows)
+
+- [Mac](https://wiki.firestormviewer.org/fs_compiling_firestorm_macos)
+
+- [Linux](https://wiki.firestormviewer.org/fs_compiling_firestorm_linux)
+
+Please note that we do not provide support for compiling the viewer or issues resulting from using a self-compiled viewer. However, there is a self-compilers group within Second Life that can be joined to ask questions related to compiling the viewer: [Firestorm Self Compilers](secondlife:///app/group/2014ce4c-5393-fb67-83ac-910db84c273c/about)
+
+## Contribute
+
+Help make Firestorm better! You can get involved with improvements by filing bugs and suggesting enhancements via [JIRA](https://jira.firestormviewer.org) or creating pull requests.
diff --git a/autobuild.xml b/autobuild.xml
index 2aca0fad61..5cbfe5e686 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -4257,7 +4257,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
license_file
docs/LICENSE-source.txt
copyright
- Copyright (c) 2023, The Phoenix Firestorm Project, Inc.
+ Copyright (c) 2024, The Phoenix Firestorm Project, Inc.
version_file
newview/viewer_version.txt
name
diff --git a/doc/firestorm_256.png b/doc/firestorm_256.png
new file mode 100644
index 0000000000..c440137b72
Binary files /dev/null and b/doc/firestorm_256.png differ
diff --git a/indra/llaudio/llaudioengine.cpp b/indra/llaudio/llaudioengine.cpp
index 2c4a57675e..5f87ac225d 100644
--- a/indra/llaudio/llaudioengine.cpp
+++ b/indra/llaudio/llaudioengine.cpp
@@ -411,7 +411,7 @@ void LLAudioEngine::idle()
for (source_map::value_type& src_pair : mAllSources)
{
LLAudioSource *sourcep = src_pair.second;
- if (sourcep->isMuted() && sourcep->isSyncMaster() && sourcep->getPriority() > max_sm_priority)
+ if (!sourcep->isMuted() && sourcep->isSyncMaster() && sourcep->getPriority() > max_sm_priority)
{
sync_masterp = sourcep;
master_channelp = sync_masterp->getChannel();
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 6154c520aa..be2375d0b8 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -2546,7 +2546,7 @@ if (DARWIN)
set(MACOSX_BUNDLE_BUNDLE_NAME "Firestorm")
set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}")
set(MACOSX_BUNDLE_BUNDLE_VERSION "${VIEWER_SHORT_VERSION}${VIEWER_MACOSX_PHASE}${VIEWER_REVISION}")
- set(MACOSX_BUNDLE_COPYRIGHT "Copyright 2010-2023 The Phoenix Firestorm Project, Inc.")
+ set(MACOSX_BUNDLE_COPYRIGHT "Copyright 2010-2024 The Phoenix Firestorm Project, Inc.")
set(MACOSX_BUNDLE_NSMAIN_NIB_FILE "Firestorm.nib")
set(MACOSX_BUNDLE_NSPRINCIPAL_CLASS "LLApplication")
diff --git a/indra/newview/English.lproj/InfoPlist.strings b/indra/newview/English.lproj/InfoPlist.strings
index 1afe5749be..b19cda2ddd 100644
--- a/indra/newview/English.lproj/InfoPlist.strings
+++ b/indra/newview/English.lproj/InfoPlist.strings
@@ -3,4 +3,4 @@
CFBundleName = "Firestorm";
CFBundleShortVersionString = "Firestorm version %%VERSION%%";
-CFBundleGetInfoString = "Firestorm version %%VERSION%%, Copyright 2010-2023 The Phoenix Firestorm Project, Inc.";
+CFBundleGetInfoString = "Firestorm version %%VERSION%%, Copyright 2010-2024 The Phoenix Firestorm Project, Inc.";
diff --git a/indra/newview/fspanelprefs.cpp b/indra/newview/fspanelprefs.cpp
index 40c2c3bc2e..0f2bf603bd 100644
--- a/indra/newview/fspanelprefs.cpp
+++ b/indra/newview/fspanelprefs.cpp
@@ -283,4 +283,5 @@ void FSPanelPrefs::onResetDefaultFolders()
gSavedPerAccountSettings.getControl("TextureUploadFolder")->resetToDefault(true);
gSavedPerAccountSettings.getControl("SoundUploadFolder")->resetToDefault(true);
gSavedPerAccountSettings.getControl("AnimationUploadFolder")->resetToDefault(true);
+ gSavedPerAccountSettings.getControl("PBRUploadFolder")->resetToDefault(true);
}
diff --git a/indra/newview/llcolorswatch.cpp b/indra/newview/llcolorswatch.cpp
index 036ff17074..d772a92745 100644
--- a/indra/newview/llcolorswatch.cpp
+++ b/indra/newview/llcolorswatch.cpp
@@ -52,6 +52,8 @@ LLColorSwatchCtrl::Params::Params()
border_color("border_color"),
label_width("label_width", -1),
label_height("label_height", -1),
+ text_enabled_color("text_enabled_color"), // Add label/caption colors
+ text_disabled_color("text_disabled_color"), // Add label/caption colors
caption_text("caption_text"),
border("border")
{
@@ -66,6 +68,8 @@ LLColorSwatchCtrl::LLColorSwatchCtrl(const Params& p)
mOnCancelCallback(p.cancel_callback()),
mOnSelectCallback(p.select_callback()),
mBorderColor(p.border_color()),
+ mTextEnabledColor(p.text_enabled_color), // Add label/caption colors
+ mTextDisabledColor(p.text_disabled_color), // Add label/caption colors
mLabelWidth(p.label_width),
mLabelHeight(p.label_height)
{
@@ -95,6 +99,8 @@ LLColorSwatchCtrl::LLColorSwatchCtrl(const Params& p)
params.rect(border_rect);
mBorder = LLUICtrlFactory::create (params);
addChild(mBorder);
+
+ updateLabelColor(); // Add label/caption colors
}
LLColorSwatchCtrl::~LLColorSwatchCtrl ()
@@ -250,12 +256,18 @@ void LLColorSwatchCtrl::draw()
}
}
+ mCaption->setEnabled(getEnabled() && isInEnabledChain()); // Add label/caption colors
+
LLUICtrl::draw();
}
void LLColorSwatchCtrl::setEnabled( BOOL enabled )
{
- mCaption->setEnabled( enabled );
+ // Add label/caption colors
+ // mCaption->setEnabled( enabled );
+ mCaption->setEnabled(enabled && isInEnabledChain());
+ //
+
LLView::setEnabled( enabled );
if (!enabled)
@@ -374,3 +386,10 @@ void LLColorSwatchCtrl::showPicker(BOOL take_focus)
}
}
+// Add label/caption colors
+void LLColorSwatchCtrl::updateLabelColor()
+{
+ mCaption->setColor(mTextEnabledColor.get());
+ mCaption->setReadOnlyColor(mTextDisabledColor.get());
+}
+//
diff --git a/indra/newview/llcolorswatch.h b/indra/newview/llcolorswatch.h
index a17cab486a..5c0afe3d1f 100644
--- a/indra/newview/llcolorswatch.h
+++ b/indra/newview/llcolorswatch.h
@@ -62,6 +62,10 @@ public:
Optional caption_text;
Optional border;
+
+ Optional text_enabled_color; // Add label/caption colors
+ Optional text_disabled_color; // Add label/caption colors
+
Params();
};
@@ -100,7 +104,12 @@ public:
static void onColorChanged ( void* data, EColorPickOp pick_op = COLOR_CHANGE );
void closeFloaterColorPicker();
+ void setLabelColor(const LLColor4& c) { mTextEnabledColor = c; updateLabelColor(); } // Add label/caption colors
+ void setDisabledLabelColor(const LLColor4& c) { mTextDisabledColor = c; updateLabelColor(); } // Add label/caption colors
+
protected:
+ void updateLabelColor(); // Add label/caption colors
+
bool mValid;
LLColor4 mColor;
LLUIColor mBorderColor;
@@ -116,6 +125,9 @@ protected:
LLPointer mAlphaGradientImage;
LLPointer mFallbackImage;
+
+ LLUIColor mTextEnabledColor; // Add label/caption colors
+ LLUIColor mTextDisabledColor; // Add label/caption colors
};
#endif // LL_LLBUTTON_H
diff --git a/indra/newview/llfloaterautoreplacesettings.cpp b/indra/newview/llfloaterautoreplacesettings.cpp
index 516a4d15d6..a0e43ca1a7 100644
--- a/indra/newview/llfloaterautoreplacesettings.cpp
+++ b/indra/newview/llfloaterautoreplacesettings.cpp
@@ -33,7 +33,6 @@
#include "llagent.h"
#include "llpanel.h"
#include "llbutton.h"
-#include "llcolorswatch.h"
#include "llcombobox.h"
#include "llview.h"
#include "llbufferstream.h"
diff --git a/indra/newview/llfloaterinspect.cpp b/indra/newview/llfloaterinspect.cpp
index 8afc10b757..b9a34345f1 100644
--- a/indra/newview/llfloaterinspect.cpp
+++ b/indra/newview/llfloaterinspect.cpp
@@ -49,7 +49,7 @@
// [/RLVa:KB]
// PoundLife - Improved Object Inspect
#include "llresmgr.h"
-#include "lltexturectrl.h"
+#include "lltextbase.h"
#include "llviewerobjectlist.h" //gObjectList
#include "llviewertexturelist.h"
// PoundLife END
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index 9e7ec05e1c..2687d574c5 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -206,8 +206,8 @@ LLPanelMainInventory::LLPanelMainInventory(const LLPanel::Params& p)
mFilterMap["filter_type_sounds"] = 0x01 << LLInventoryType::IT_SOUND;
mFilterMap["filter_type_textures"] = 0x01 << LLInventoryType::IT_TEXTURE;
mFilterMap["filter_type_snapshots"] = 0x01 << LLInventoryType::IT_SNAPSHOT;
- mFilterMap["filter_type_meshes"] = 0x01 << LLInventoryType::IT_MESH;
mFilterMap["filter_type_settings"] = 0x01 << LLInventoryType::IT_SETTINGS;
+ mFilterMap["filter_type_materials"] = 0x01 << LLInventoryType::IT_MATERIAL;
// initialize empty filter mask
mFilterMask = 0;
diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp
index e9fe4324da..a13acea9b7 100644
--- a/indra/newview/llpanelobject.cpp
+++ b/indra/newview/llpanelobject.cpp
@@ -42,7 +42,6 @@
#include "llbutton.h"
#include "llcalc.h"
#include "llcheckboxctrl.h"
-#include "llcolorswatch.h"
#include "llcombobox.h"
#include "llfocusmgr.h"
#include "llmanipscale.h"
diff --git a/indra/newview/llpanelobject.h b/indra/newview/llpanelobject.h
index 69a5d70b11..2aff1a776e 100644
--- a/indra/newview/llpanelobject.h
+++ b/indra/newview/llpanelobject.h
@@ -40,7 +40,6 @@ class LLButton;
class LLMenuButton;
class LLViewerObject;
class LLComboBox;
-class LLColorSwatchCtrl;
class LLTextureCtrl;
class LLInventoryItem;
class LLUUID;
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 8ca6d4b26e..c3eeb8710c 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -1759,6 +1759,8 @@ LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p)
mDefaultImageAssetID(p.default_image_id),
mDefaultImageName(p.default_image_name),
mFallbackImage(p.fallback_image),
+ mTextEnabledColor(p.text_enabled_color), // Add label/caption colors
+ mTextDisabledColor(p.text_disabled_color), // Add label/caption colors
// Mask texture if desired
mIsMasked(FALSE)
{
@@ -1773,7 +1775,10 @@ LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p)
LLTextBox::Params params(p.caption_text);
params.name(p.label);
- params.rect(LLRect( 0, BTN_HEIGHT_SMALL, getRect().getWidth(), 0 ));
+ // Fix label width
+ // params.rect(LLRect( 0, BTN_HEIGHT_SMALL, getRect().getWidth(), 0 ));
+ params.rect(LLRect( 0, BTN_HEIGHT_SMALL, p.label_width == -1 ? getRect().getWidth() : p.label_width, 0 ));
+ // /FS:Zi>
params.initial_value(p.label());
params.follows.flags(FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_BOTTOM);
mCaption = LLUICtrlFactory::create (params);
@@ -1811,6 +1816,8 @@ LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p)
addChild(mBorder);
mLoadingPlaceholderString = LLTrans::getString("texture_loading");
+
+ updateLabelColor(); // Add label/caption colors
}
LLTextureCtrl::~LLTextureCtrl()
@@ -1895,7 +1902,10 @@ void LLTextureCtrl::setEnabled( BOOL enabled )
closeDependentFloater();
}
- mCaption->setEnabled( enabled );
+ // Add label/caption colors
+ // mCaption->setEnabled( enabled );
+ mCaption->setEnabled(enabled && isInEnabledChain());
+ //
// Texture preview mode
//LLView::setEnabled( enabled );
@@ -2420,6 +2430,8 @@ void LLTextureCtrl::draw()
}
}
+ mCaption->setEnabled(getEnabled() && isInEnabledChain()); // Add label/caption colors
+
LLUICtrl::draw();
}
@@ -2526,7 +2538,10 @@ LLSD LLTextureCtrl::getValue() const
return LLSD(getImageAssetID());
}
-
-
-
-
+// Add label/caption colors
+void LLTextureCtrl::updateLabelColor()
+{
+ mCaption->setColor(mTextEnabledColor.get());
+ mCaption->setReadOnlyColor(mTextDisabledColor.get());
+}
+//
diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h
index 98d810273e..a8814e7f88 100644
--- a/indra/newview/lltexturectrl.h
+++ b/indra/newview/lltexturectrl.h
@@ -122,6 +122,9 @@ public:
Optional border;
Optional show_caption; // leave some room underneath the image for the caption
+ Optional text_enabled_color; // Add label/caption colors
+ Optional text_disabled_color; // Add label/caption colors
+
Params()
: image_id("image"),
default_image_id("default_image_id"),
@@ -134,6 +137,8 @@ public:
fallback_image("fallback_image"),
multiselect_text("multiselect_text"),
show_caption("show_caption", true), // leave some room underneath the image for the caption
+ text_enabled_color("text_enabled_color"), // Add label/caption colors
+ text_disabled_color("text_disabled_color"), // Add label/caption colors
caption_text("caption_text"),
border("border")
{}
@@ -250,10 +255,15 @@ public:
// Mask texture if desired
void setIsMasked(BOOL masked) { mIsMasked = masked; }
+ void setLabelColor(const LLColor4& c) { mTextEnabledColor = c; updateLabelColor(); } // Add label/caption colors
+ void setDisabledLabelColor(const LLColor4& c) { mTextDisabledColor = c; updateLabelColor(); } // Add label/caption colors
+
private:
BOOL allowDrop(LLInventoryItem* item, EDragAndDropType cargo_type, std::string& tooltip_msg);
BOOL doDrop(LLInventoryItem* item);
+ void updateLabelColor(); // Add label/caption colors
+
private:
drag_n_drop_callback mDragCallback;
drag_n_drop_callback mDropCallback;
@@ -293,6 +303,9 @@ private:
// Mask texture if desired
BOOL mIsMasked;
+
+ LLUIColor mTextEnabledColor; // Add label/caption colors
+ LLUIColor mTextDisabledColor; // Add label/caption colors
};
//////////////////////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/lltoolplacer.cpp b/indra/newview/lltoolplacer.cpp
index 5943d7de1f..dc573ce2d7 100644
--- a/indra/newview/lltoolplacer.cpp
+++ b/indra/newview/lltoolplacer.cpp
@@ -200,7 +200,16 @@ BOOL LLToolPlacer::raycastForNewObjPos( S32 x, S32 y, LLViewerObject** hit_obj,
}
else
{
- LLVector3d ray_end_global = ray_start_global + (1.f + max_dist_from_camera) * mouse_direction; // add an epsilon to the sim version of the ray to avoid rounding problems.
+ // Fix not being able to rez a box on top of a prim when MaxSelectDistance is shorter
+ // than the surface distance, even though LimitSelectDistance is switched off.
+ // LLVector3d ray_end_global = ray_start_global + (1.f + max_dist_from_camera) * mouse_direction; // add an epsilon to the sim version of the ray to avoid rounding problems.
+ F32 max_raycast_dist = 129.0f;
+ if (limitSelectDistance)
+ {
+ max_raycast_dist = max_dist_from_camera;
+ }
+ LLVector3d ray_end_global = ray_start_global + max_raycast_dist * mouse_direction; // add an epsilon to the sim version of the ray to avoid rounding problems.
+ //
*ray_end_region = regionp->getPosRegionFromGlobal( ray_end_global );
}
diff --git a/indra/newview/llviewerinput.cpp b/indra/newview/llviewerinput.cpp
index 4610d4f226..7035cda219 100644
--- a/indra/newview/llviewerinput.cpp
+++ b/indra/newview/llviewerinput.cpp
@@ -938,12 +938,14 @@ bool voice_follow_key(EKeystate s)
if (KEYSTATE_DOWN == s)
{
if (!LLAgent::isActionAllowed("speak")) return false;
+ if (!LLVoiceClient::getInstance()->getUserPTTState()) make_ui_sound("UISndMicToggle"); // FIRE-33249 Mic toggle
LLVoiceClient::getInstance()->setUserPTTState(true);
return true;
}
else if (KEYSTATE_UP == s && LLVoiceClient::getInstance()->getUserPTTState())
{
LLVoiceClient::getInstance()->setUserPTTState(false);
+ make_ui_sound("UISndMicToggle"); // FIRE-33249 Mic toggle
return true;
}
return false;
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index d6344ccb66..9d98ae9af5 100644
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -628,7 +628,6 @@ void LLVoiceClient::setUserPTTState(bool ptt)
mUserPTTState = ptt;
updateMicMuteLogic();
mMicroChangedSignal();
- make_ui_sound("UISndMicToggle"); // FIRE-33249 Mic toggle
}
bool LLVoiceClient::getUserPTTState()
@@ -678,12 +677,14 @@ void LLVoiceClient::inputUserControlState(bool down)
else // set open-mic state as an absolute
{
setUserPTTState(down);
+ make_ui_sound("UISndMicToggle"); // FIRE-33249 Mic toggle
}
}
void LLVoiceClient::toggleUserPTTState(void)
{
setUserPTTState(!getUserPTTState());
+ make_ui_sound("UISndMicToggle"); // FIRE-33249 Mic toggle
}
diff --git a/indra/newview/res/viewerRes.rc b/indra/newview/res/viewerRes.rc
index dd0da75631..ade5c477c7 100755
--- a/indra/newview/res/viewerRes.rc
+++ b/indra/newview/res/viewerRes.rc
@@ -161,7 +161,7 @@ BEGIN
VALUE "FileDescription", "Firestorm"
VALUE "FileVersion", "${VIEWER_VERSION_MAJOR}.${VIEWER_VERSION_MINOR}.${VIEWER_VERSION_PATCH}.${VIEWER_VERSION_REVISION}"
VALUE "InternalName", "Firestorm"
- VALUE "LegalCopyright", "Copyright \251 2010-2023, The Phoenix Firestorm Project, Inc."
+ VALUE "LegalCopyright", "Copyright \251 2010-2024, The Phoenix Firestorm Project, Inc."
VALUE "OriginalFilename", "Firestorm.exe"
VALUE "ProductName", "Firestorm"
VALUE "ProductVersion", "${VIEWER_VERSION_MAJOR}.${VIEWER_VERSION_MINOR}.${VIEWER_VERSION_PATCH}.${VIEWER_VERSION_REVISION}"
diff --git a/indra/newview/skins/ansastorm/xui/de/panel_main_inventory.xml b/indra/newview/skins/ansastorm/xui/de/panel_main_inventory.xml
index c20ad85a5c..0daf2b5c6b 100644
--- a/indra/newview/skins/ansastorm/xui/de/panel_main_inventory.xml
+++ b/indra/newview/skins/ansastorm/xui/de/panel_main_inventory.xml
@@ -110,8 +110,8 @@
-
+
diff --git a/indra/newview/skins/ansastorm/xui/en/panel_main_inventory.xml b/indra/newview/skins/ansastorm/xui/en/panel_main_inventory.xml
index 5837a3608d..63596de5fa 100644
--- a/indra/newview/skins/ansastorm/xui/en/panel_main_inventory.xml
+++ b/indra/newview/skins/ansastorm/xui/en/panel_main_inventory.xml
@@ -736,7 +736,7 @@
-
+
diff --git a/indra/newview/skins/ansastorm/xui/es/panel_main_inventory.xml b/indra/newview/skins/ansastorm/xui/es/panel_main_inventory.xml
index 418e5978ce..c336d30872 100644
--- a/indra/newview/skins/ansastorm/xui/es/panel_main_inventory.xml
+++ b/indra/newview/skins/ansastorm/xui/es/panel_main_inventory.xml
@@ -82,7 +82,6 @@
-
diff --git a/indra/newview/skins/ansastorm/xui/pl/panel_main_inventory.xml b/indra/newview/skins/ansastorm/xui/pl/panel_main_inventory.xml
index b9d066633a..1ccf340066 100644
--- a/indra/newview/skins/ansastorm/xui/pl/panel_main_inventory.xml
+++ b/indra/newview/skins/ansastorm/xui/pl/panel_main_inventory.xml
@@ -109,7 +109,6 @@
-
diff --git a/indra/newview/skins/ansastorm/xui/ru/panel_main_inventory.xml b/indra/newview/skins/ansastorm/xui/ru/panel_main_inventory.xml
index c3e431c567..1973b9e42b 100644
--- a/indra/newview/skins/ansastorm/xui/ru/panel_main_inventory.xml
+++ b/indra/newview/skins/ansastorm/xui/ru/panel_main_inventory.xml
@@ -97,7 +97,6 @@
-
diff --git a/indra/newview/skins/default/xui/az/panel_main_inventory.xml b/indra/newview/skins/default/xui/az/panel_main_inventory.xml
index daa5c08f3a..2871d62738 100644
--- a/indra/newview/skins/default/xui/az/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/az/panel_main_inventory.xml
@@ -37,7 +37,6 @@
-
diff --git a/indra/newview/skins/default/xui/da/panel_main_inventory.xml b/indra/newview/skins/default/xui/da/panel_main_inventory.xml
index 37a17f4bd6..ac57bae70d 100644
--- a/indra/newview/skins/default/xui/da/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/da/panel_main_inventory.xml
@@ -10,7 +10,7 @@
Genstande:
-
+
diff --git a/indra/newview/skins/default/xui/de/panel_main_inventory.xml b/indra/newview/skins/default/xui/de/panel_main_inventory.xml
index cd575a4119..fe79176257 100644
--- a/indra/newview/skins/default/xui/de/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/de/panel_main_inventory.xml
@@ -41,7 +41,7 @@
-
+
diff --git a/indra/newview/skins/default/xui/en/panel_main_inventory.xml b/indra/newview/skins/default/xui/en/panel_main_inventory.xml
index 2bbd6678cf..eda12fb3f4 100644
--- a/indra/newview/skins/default/xui/en/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/en/panel_main_inventory.xml
@@ -89,7 +89,7 @@
width="324"
name="filter_panel"
visible="true"
- name="filter_layout_panel">
+ >
-
+
diff --git a/indra/newview/skins/default/xui/en/widgets/color_swatch.xml b/indra/newview/skins/default/xui/en/widgets/color_swatch.xml
index ab3de1eaab..3611670121 100644
--- a/indra/newview/skins/default/xui/en/widgets/color_swatch.xml
+++ b/indra/newview/skins/default/xui/en/widgets/color_swatch.xml
@@ -1,6 +1,9 @@
+
+
-
diff --git a/indra/newview/skins/default/xui/fr/panel_main_inventory.xml b/indra/newview/skins/default/xui/fr/panel_main_inventory.xml
index 93a58514c4..23855bfe2f 100644
--- a/indra/newview/skins/default/xui/fr/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/fr/panel_main_inventory.xml
@@ -34,7 +34,6 @@
-
diff --git a/indra/newview/skins/default/xui/it/panel_main_inventory.xml b/indra/newview/skins/default/xui/it/panel_main_inventory.xml
index 1ad2b550c0..6bdafc4443 100644
--- a/indra/newview/skins/default/xui/it/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/it/panel_main_inventory.xml
@@ -38,7 +38,6 @@
-
diff --git a/indra/newview/skins/default/xui/ja/panel_main_inventory.xml b/indra/newview/skins/default/xui/ja/panel_main_inventory.xml
index 6f914cbcb2..d8d781037a 100644
--- a/indra/newview/skins/default/xui/ja/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/ja/panel_main_inventory.xml
@@ -31,7 +31,6 @@
-
diff --git a/indra/newview/skins/default/xui/pl/panel_main_inventory.xml b/indra/newview/skins/default/xui/pl/panel_main_inventory.xml
index afea372723..85a42300ef 100644
--- a/indra/newview/skins/default/xui/pl/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/pl/panel_main_inventory.xml
@@ -42,7 +42,6 @@
-
diff --git a/indra/newview/skins/default/xui/pt/panel_main_inventory.xml b/indra/newview/skins/default/xui/pt/panel_main_inventory.xml
index debd601966..97a95b6a34 100644
--- a/indra/newview/skins/default/xui/pt/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/pt/panel_main_inventory.xml
@@ -14,7 +14,7 @@
Itens:
-
+
diff --git a/indra/newview/skins/default/xui/ru/menu_viewer.xml b/indra/newview/skins/default/xui/ru/menu_viewer.xml
index f674641a44..99110f5011 100644
--- a/indra/newview/skins/default/xui/ru/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/ru/menu_viewer.xml
@@ -300,6 +300,7 @@
+
diff --git a/indra/newview/skins/default/xui/ru/panel_main_inventory.xml b/indra/newview/skins/default/xui/ru/panel_main_inventory.xml
index cf8ac67e8d..9386086786 100644
--- a/indra/newview/skins/default/xui/ru/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/ru/panel_main_inventory.xml
@@ -42,7 +42,6 @@
-
diff --git a/indra/newview/skins/default/xui/ru/panel_preferences_UI.xml b/indra/newview/skins/default/xui/ru/panel_preferences_UI.xml
index 31c67b5c69..77b37113ef 100644
--- a/indra/newview/skins/default/xui/ru/panel_preferences_UI.xml
+++ b/indra/newview/skins/default/xui/ru/panel_preferences_UI.xml
@@ -81,6 +81,15 @@
+
+
+
+ сек
+
diff --git a/indra/newview/skins/default/xui/ru/panel_preferences_sound.xml b/indra/newview/skins/default/xui/ru/panel_preferences_sound.xml
index 7883f66aa6..1ad35e730a 100644
--- a/indra/newview/skins/default/xui/ru/panel_preferences_sound.xml
+++ b/indra/newview/skins/default/xui/ru/panel_preferences_sound.xml
@@ -503,6 +503,13 @@
+
+ Переключатель микрофона:
+
+
+
+
+
Перезагрузка региона:
diff --git a/indra/newview/skins/default/xui/tr/panel_main_inventory.xml b/indra/newview/skins/default/xui/tr/panel_main_inventory.xml
index af55d4cafc..cabdb9911a 100644
--- a/indra/newview/skins/default/xui/tr/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/tr/panel_main_inventory.xml
@@ -14,7 +14,7 @@
Ögeler:
-
+
diff --git a/indra/newview/skins/default/xui/zh/panel_main_inventory.xml b/indra/newview/skins/default/xui/zh/panel_main_inventory.xml
index 6a8ead28b4..7a15d8c180 100644
--- a/indra/newview/skins/default/xui/zh/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/zh/panel_main_inventory.xml
@@ -14,7 +14,7 @@
物品:
-
+
diff --git a/indra/newview/skins/starlight/xui/en/panel_main_inventory.xml b/indra/newview/skins/starlight/xui/en/panel_main_inventory.xml
index 425d93a530..9f9279d5e3 100644
--- a/indra/newview/skins/starlight/xui/en/panel_main_inventory.xml
+++ b/indra/newview/skins/starlight/xui/en/panel_main_inventory.xml
@@ -179,7 +179,7 @@
-
+
diff --git a/indra/newview/skins/starlightcui/xui/en/panel_main_inventory.xml b/indra/newview/skins/starlightcui/xui/en/panel_main_inventory.xml
index 27eb1dc6c4..37a1a95953 100644
--- a/indra/newview/skins/starlightcui/xui/en/panel_main_inventory.xml
+++ b/indra/newview/skins/starlightcui/xui/en/panel_main_inventory.xml
@@ -181,7 +181,7 @@
-
+
diff --git a/indra/newview/skins/vintage/xui/de/panel_main_inventory.xml b/indra/newview/skins/vintage/xui/de/panel_main_inventory.xml
index 9a470da319..eab9799085 100644
--- a/indra/newview/skins/vintage/xui/de/panel_main_inventory.xml
+++ b/indra/newview/skins/vintage/xui/de/panel_main_inventory.xml
@@ -102,7 +102,6 @@
-
diff --git a/indra/newview/skins/vintage/xui/en/panel_main_inventory.xml b/indra/newview/skins/vintage/xui/en/panel_main_inventory.xml
index e9d7e6639c..00497c92ec 100644
--- a/indra/newview/skins/vintage/xui/en/panel_main_inventory.xml
+++ b/indra/newview/skins/vintage/xui/en/panel_main_inventory.xml
@@ -784,7 +784,7 @@
-
+
diff --git a/indra/newview/skins/vintage/xui/es/panel_main_inventory.xml b/indra/newview/skins/vintage/xui/es/panel_main_inventory.xml
index 6a5c6ff9e4..959449bcc2 100644
--- a/indra/newview/skins/vintage/xui/es/panel_main_inventory.xml
+++ b/indra/newview/skins/vintage/xui/es/panel_main_inventory.xml
@@ -82,7 +82,6 @@
-
diff --git a/indra/newview/skins/vintage/xui/fr/panel_main_inventory.xml b/indra/newview/skins/vintage/xui/fr/panel_main_inventory.xml
index 2f985e7d4f..b69c5c4ac3 100644
--- a/indra/newview/skins/vintage/xui/fr/panel_main_inventory.xml
+++ b/indra/newview/skins/vintage/xui/fr/panel_main_inventory.xml
@@ -93,7 +93,6 @@
-
diff --git a/indra/newview/skins/vintage/xui/it/panel_main_inventory.xml b/indra/newview/skins/vintage/xui/it/panel_main_inventory.xml
index adc482d548..f6af585c33 100644
--- a/indra/newview/skins/vintage/xui/it/panel_main_inventory.xml
+++ b/indra/newview/skins/vintage/xui/it/panel_main_inventory.xml
@@ -143,7 +143,6 @@
-
diff --git a/indra/newview/skins/vintage/xui/ja/panel_main_inventory.xml b/indra/newview/skins/vintage/xui/ja/panel_main_inventory.xml
index b5a9a58a8b..435ed06b73 100644
--- a/indra/newview/skins/vintage/xui/ja/panel_main_inventory.xml
+++ b/indra/newview/skins/vintage/xui/ja/panel_main_inventory.xml
@@ -104,7 +104,6 @@
-
diff --git a/indra/newview/skins/vintage/xui/pl/panel_main_inventory.xml b/indra/newview/skins/vintage/xui/pl/panel_main_inventory.xml
index 33e27e827c..4a4b5cbcde 100644
--- a/indra/newview/skins/vintage/xui/pl/panel_main_inventory.xml
+++ b/indra/newview/skins/vintage/xui/pl/panel_main_inventory.xml
@@ -114,7 +114,6 @@
-
diff --git a/indra/newview/skins/vintage/xui/ru/panel_main_inventory.xml b/indra/newview/skins/vintage/xui/ru/panel_main_inventory.xml
index a621bc3cdd..3092e53280 100644
--- a/indra/newview/skins/vintage/xui/ru/panel_main_inventory.xml
+++ b/indra/newview/skins/vintage/xui/ru/panel_main_inventory.xml
@@ -94,7 +94,6 @@
-
diff --git a/indra/newview/vjlocalmesh.cpp b/indra/newview/vjlocalmesh.cpp
index fe8b3b9625..7f01ba422b 100644
--- a/indra/newview/vjlocalmesh.cpp
+++ b/indra/newview/vjlocalmesh.cpp
@@ -37,7 +37,6 @@
// STL headers
#include
-
// boost headers
#include "fix_macros.h"
#include
@@ -72,6 +71,61 @@ void LLLocalMeshFace::setFaceBoundingBox(LLVector4 data_in, bool initial_values)
}
}
+void LLLocalMeshFace::logFaceInfo() const
+{
+ // log all of the attribute of the face using LL_DEBUGS("LocalMesh")
+ LL_DEBUGS("LocalMesh") << "LLLocalMeshFace: " << LL_ENDL;
+ LL_DEBUGS("LocalMesh") << " mFaceBoundingBox: [" << mFaceBoundingBox.first << "," << mFaceBoundingBox.second << LL_ENDL;
+ // create a string stream from mIndices then output it to the log
+ std::stringstream ss;
+ for (const auto& index : mIndices)
+ {
+ ss << "[";
+ ss << index << ",";
+ ss << "]";
+ }
+ LL_DEBUGS("LocalMesh") << " mFaceIndices: " << ss.str() << LL_ENDL;
+ // create a local string stream for the vertex positions in mPositions then log it
+ std::stringstream ss_pos;
+ ss_pos << "[";
+ for (const auto& pos : mPositions)
+ {
+ ss_pos << pos << ",";
+ }
+ ss_pos << "]";
+ LL_DEBUGS("LocalMesh") << " mFacePositions: " << ss_pos.str() << LL_ENDL;
+ // create a local string stream for the UVcoords in mUVs then log it
+ std::stringstream ss_uv;
+ ss_uv << "[";
+ for (const auto& uv : mUVs)
+ {
+ ss_uv << uv << ",";
+ }
+ ss_uv << "]";
+ LL_DEBUGS("LocalMesh") << " mFaceUVs: " << ss_uv.str() << LL_ENDL;
+ // create a local string stream for the normals in mNormals then log it
+ std::stringstream ss_norm;
+ ss_norm << "[";
+ for (const auto& norm : mNormals)
+ {
+ ss_norm << norm << ",";
+ }
+ ss_norm << "]";
+ LL_DEBUGS("LocalMesh") << " mFaceNormals: " << ss_norm.str() << LL_ENDL;
+ int i = 0;
+ for (const auto& skinUnit : mSkin)
+ {
+ // log the mJointIncdices and mJointWeights as "num: idx = weight" for each entry in th skinUnit vector
+ LL_DEBUGS("LocalMesh") << " mSkin[" << i << "]: " << LL_ENDL;
+ for (auto j=0; j<4;j++)
+ {
+ auto index =skinUnit.mJointIndices[j];
+ auto weight = skinUnit.mJointWeights[j];
+ LL_DEBUGS("LocalMesh") << " " << j <<": [" << index << "] = " << weight << LL_ENDL;
+ }
+ ++i;
+ }
+}
/*==========================================*/
/* LLLocalMeshObject: collection of faces */
@@ -88,6 +142,31 @@ LLLocalMeshObject::LLLocalMeshObject(std::string_view name):
LLLocalMeshObject::~LLLocalMeshObject() = default;
+void LLLocalMeshObject::logObjectInfo() const
+{
+ // log all of the attribute of the object using LL_DEBUGS("LocalMesh")
+ LL_DEBUGS("LocalMesh") << "LLLocalMeshObject: " << mObjectName << LL_ENDL;
+ LL_DEBUGS("LocalMesh") << " mSculptID: " << mSculptID << LL_ENDL;
+ LL_DEBUGS("LocalMesh") << " mVolumeParams: " << mVolumeParams << LL_ENDL;
+ LL_DEBUGS("LocalMesh") << " mObjectTranslation: " << mObjectTranslation << LL_ENDL;
+ LL_DEBUGS("LocalMesh") << " mMeshSkinInfo: " << std::hex << std::showbase << (void *)mMeshSkinInfoPtr << LL_ENDL;
+ LL_DEBUGS("LocalMesh") << " asLLSD: " << mMeshSkinInfoPtr->asLLSD(true, true) << LL_ENDL;
+ LL_DEBUGS("LocalMesh") << " mFaceBoundingBox: [" << mObjectBoundingBox.first << "," << mObjectBoundingBox.second << LL_ENDL;
+ LL_DEBUGS("LocalMesh") << " mObjectSize: " << mObjectSize << LL_ENDL;
+ LL_DEBUGS("LocalMesh") << " mObjectScale: " << mObjectScale << LL_ENDL;
+ // Log the number of faces in mFaces and dump each one to the Log
+ // LL_DEBUGS("LocalMesh") << " num faces: " << mFaces.size() << LL_ENDL;
+ // int i=0;
+ // for (const auto& face : mFaces)
+ // {
+ // LL_DEBUGS("LocalMesh") << " face: " << i << LL_ENDL;
+ // face.logFaceInfo();
+ // i++
+ // }
+}
+
+
+
void LLLocalMeshObject::computeObjectBoundingBox()
{
// for the purposes of a bounding box, we only care for LOD3
@@ -804,13 +883,26 @@ void LLLocalMeshFile::pushLog(const std::string& who, const std::string& what, b
log_msg += what;
mLoadingLog.push_back(log_msg);
+ LL_INFOS("LocalMesh") << log_msg << LL_ENDL;
}
-
-
/*==========================================*/
/* LLLocalMeshSystem: Main Manager Class */
/* user facing manager class */
/*==========================================*/
+
+void LLLocalMeshSystem::pushLog(const std::string& who, const std::string& what, bool is_error)
+{
+ std::string log_msg = "[ " + who + " ] ";
+ if (is_error)
+ {
+ log_msg += "[ ERROR ] ";
+ }
+
+ log_msg += what;
+ mSystemLog.push_back(log_msg);
+ LL_INFOS("LocalMesh") << log_msg << LL_ENDL;
+}
+
LLLocalMeshSystem::LLLocalMeshSystem()
{
mLoadedFileList.clear();
diff --git a/indra/newview/vjlocalmesh.h b/indra/newview/vjlocalmesh.h
index 28b294b9a1..6ff89088cc 100644
--- a/indra/newview/vjlocalmesh.h
+++ b/indra/newview/vjlocalmesh.h
@@ -71,6 +71,7 @@ class LLLocalMeshFace
std::vector& getUVs() { return mUVs; };
std::vector& getSkin() { return mSkin; }
std::pair& getFaceBoundingBox() { return mFaceBoundingBox; }
+ void logFaceInfo() const;
private:
std::vector mIndices;
@@ -115,6 +116,7 @@ class LLLocalMeshObject
void setObjectMeshSkinInfo(LLPointer skininfop ) { mMeshSkinInfoPtr = skininfop; };
LLVolumeParams getVolumeParams() const { return mVolumeParams; };
bool getIsRiggedObject() const;
+ void logObjectInfo() const;
private:
// internal data keeping
@@ -198,7 +200,6 @@ class LLLocalMeshFile
void updateVObjects();
void applyToVObject(LLUUID viewer_object_id, int object_index, bool use_scale);
- // misc
void pushLog(const std::string& who, const std::string& what, bool is_error = false);
private:
@@ -249,8 +250,11 @@ class LLLocalMeshSystem : public LLSingleton
void triggerFloaterRefresh( bool keep_selection=true );
std::vector getFileInfoVector() const;
std::vector getFileLog(LLUUID local_file_id) const;
+ // misc
+ void pushLog(const std::string& who, const std::string& what, bool is_error = false);
private:
+ std::vector mSystemLog;
std::vector> mLoadedFileList;
bool mFileAsyncsOngoing;
LLFloaterLocalMesh* mFloaterPtr;
diff --git a/indra/newview/vjlocalmeshimportdae.cpp b/indra/newview/vjlocalmeshimportdae.cpp
index 8661496df9..2d44448788 100644
--- a/indra/newview/vjlocalmeshimportdae.cpp
+++ b/indra/newview/vjlocalmeshimportdae.cpp
@@ -36,6 +36,7 @@
#include "llmodelloader.h"
#include "llvoavatarself.h"
#include "lldaeloader.h" // for preProcessDAE
+#include "llerror.h"
/* dae headers*/
#if LL_MSVC
@@ -59,6 +60,7 @@
LLLocalMeshImportDAE::loadFile_return LLLocalMeshImportDAE::loadFile(LLLocalMeshFile* data, LLLocalMeshFileLOD lod)
{
pushLog("DAE Importer", "Starting");
+ LL_DEBUGS("LocalMesh") << "DAE Importer: Starting" << LL_ENDL;
// instantiate collada objects
DAE collada_core;
@@ -73,6 +75,7 @@ LLLocalMeshImportDAE::loadFile_return LLLocalMeshImportDAE::loadFile(LLLocalMesh
// open file and check if opened
if (gSavedSettings.getBOOL("ImporterPreprocessDAE"))
{
+ LL_DEBUGS("LocalMesh") << "Performing dae preprocessing" << LL_ENDL;
collada_dom = collada_core.openFromMemory(filename, LLDAELoader::preprocessDAE(filename).c_str());
}
else
@@ -83,7 +86,7 @@ LLLocalMeshImportDAE::loadFile_return LLLocalMeshImportDAE::loadFile(LLLocalMesh
if (!collada_dom)
{
- pushLog("DAE Importer", "Collada DOM instance could not initialize.");
+ pushLog("DAE Importer", "Collada DOM instance could not initialize.", true);
return loadFile_return(false, mLoadingLog);
}
@@ -111,10 +114,10 @@ LLLocalMeshImportDAE::loadFile_return LLLocalMeshImportDAE::loadFile(LLLocalMesh
static auto always_use_meter_scale = LLUICachedControl("FSLocalMeshScaleAlwaysMeters", false);
+ scene_transform_base.setIdentity();
if(!always_use_meter_scale)
{
domAsset::domUnit* unit = daeSafeCast(collada_document_root->getDescendant(daeElement::matchType(domAsset::domUnit::ID())));
- scene_transform_base.setIdentity();
if (unit)
{
F32 meter = unit->getMeter();
@@ -123,34 +126,37 @@ LLLocalMeshImportDAE::loadFile_return LLLocalMeshImportDAE::loadFile(LLLocalMesh
scene_transform_base.mMatrix[2][2] = meter;
}
}
- else
- {
- scene_transform_base.setIdentity();
- }
+
//get up axis rotation
LLMatrix4 rotation;
domUpAxisType up = UPAXISTYPE_Y_UP; // default in Collada is Y_UP
domAsset::domUp_axis* up_axis =
- daeSafeCast(collada_document_root->getDescendant(daeElement::matchType(domAsset::domUp_axis::ID())));
+ daeSafeCast(collada_document_root->getDescendant(daeElement::matchType(domAsset::domUp_axis::ID())));
if (up_axis)
{
up = up_axis->getValue();
-
- if (up == UPAXISTYPE_X_UP)
- {
- rotation.initRotation(0.0f, 90.0f * DEG_TO_RAD, 0.0f);
- }
- else if (up == UPAXISTYPE_Y_UP)
- {
- rotation.initRotation(90.0f * DEG_TO_RAD, 0.0f, 0.0f);
- }
-
}
+
+ if (up == UPAXISTYPE_X_UP)
+ {
+ LL_DEBUGS("LocalMesh") << "Up axis is X_UP, setting up axis to Z" << LL_ENDL;
+ rotation.initRotation(0.0f, 90.0f * DEG_TO_RAD, 0.0f);
+ }
+ else if (up == UPAXISTYPE_Y_UP)
+ {
+ LL_DEBUGS("LocalMesh") << "Up axis is Y_UP, setting up axis to Z" << LL_ENDL;
+ rotation.initRotation(90.0f * DEG_TO_RAD, 0.0f, 0.0f);
+ }
+ else if (up == UPAXISTYPE_Z_UP)
+ {
+ LL_DEBUGS("LocalMesh") << "Up axis is Z_UP, not changed" << LL_ENDL;
+ }
+
rotation *= scene_transform_base;
scene_transform_base = rotation;
- scene_transform_base.condition();
+ scene_transform_base.condition();
size_t mesh_amount = collada_db->getElementCount(NULL, COLLADA_TYPE_MESH);
size_t skin_amount = collada_db->getElementCount(NULL, COLLADA_TYPE_SKIN);
@@ -160,6 +166,11 @@ LLLocalMeshImportDAE::loadFile_return LLLocalMeshImportDAE::loadFile(LLLocalMesh
pushLog("DAE Importer", "Collada document contained no MESH instances.");
return loadFile_return(false, mLoadingLog);
}
+ else
+ {
+ LL_DEBUGS("LocalMesh") << "Collada document contained " << mesh_amount << " MESH instances." << LL_ENDL;
+ }
+ LL_DEBUGS("LocalMesh") << "Collada document contained " << skin_amount << " SKIN instances." << LL_ENDL;
std::vector mesh_usage_tracker;
@@ -200,7 +211,6 @@ LLLocalMeshImportDAE::loadFile_return LLLocalMeshImportDAE::loadFile(LLLocalMesh
object_vector.push_back(std::move(current_object));
mesh_usage_tracker.push_back(mesh_current);
}
-
else
{
pushLog("DAE Importer", "Object loading failed, skipping this one.");
@@ -274,7 +284,7 @@ LLLocalMeshImportDAE::loadFile_return LLLocalMeshImportDAE::loadFile(LLLocalMesh
domMesh* skin_current_mesh = skin_current_geom->getMesh();
if (!skin_current_mesh)
{
- pushLog("DAE Importer", "Skin associated geometry continer has no mesh, skipping.");
+ pushLog("DAE Importer", "Skin associated geometry container has no mesh, skipping.");
continue;
}
@@ -314,7 +324,7 @@ LLLocalMeshImportDAE::loadFile_return LLLocalMeshImportDAE::loadFile(LLLocalMesh
{
pushLog("DAE Importer", "Skin idx " + std::to_string(skin_index) + " loading unsuccessful.");
}
-
+ current_object->logObjectInfo();
}
if (skin_amount)
@@ -470,6 +480,27 @@ bool LLLocalMeshImportDAE::processObject(domMesh* current_mesh, LLLocalMeshObjec
return !submesh_failure_found;
}
+// Function to load the JointMap
+JointMap loadJointMap()
+{
+ JointMap joint_map = gAgentAvatarp->getJointAliases();
+
+ // unfortunately getSortedJointNames clears the ref vector, and we need two extra lists.
+ std::vector extra_names, more_extra_names;
+ gAgentAvatarp->getSortedJointNames(1, extra_names);
+ gAgentAvatarp->getSortedJointNames(2, more_extra_names);
+ extra_names.reserve(more_extra_names.size());
+ extra_names.insert(extra_names.end(), more_extra_names.begin(), more_extra_names.end());
+
+ // add the extras to jointmap
+ for (auto extra_name : extra_names)
+ {
+ joint_map[extra_name] = extra_name;
+ }
+
+ return joint_map;
+}
+
// this function is a mess even after refactoring, omnissiah help whichever tech priest delves into this mess.
bool LLLocalMeshImportDAE::processSkin(daeDatabase* collada_db, daeElement* collada_document_root, domMesh* current_mesh, domSkin* current_skin,
std::unique_ptr& current_object)
@@ -488,6 +519,7 @@ bool LLLocalMeshImportDAE::processSkin(daeDatabase* collada_db, daeElement* coll
LLPointer skininfop = current_object->getObjectMeshSkinInfo();
if (skininfop == nullptr)
{
+ LL_DEBUGS("LocalMesh") << "Object mesh skin info is nullptr. allocate a new skininfo." << LL_ENDL;
try
{
skininfop = new LLMeshSkinInfo();
@@ -514,6 +546,7 @@ bool LLLocalMeshImportDAE::processSkin(daeDatabase* collada_db, daeElement* coll
domSkin::domBind_shape_matrix* skin_current_bind_matrix = current_skin->getBind_shape_matrix();
if (skin_current_bind_matrix)
{
+ LL_DEBUGS("LocalMesh") << "Bind shape matrix found. Applying..." << LL_ENDL;
auto& bind_matrix_value = skin_current_bind_matrix->getValue();
LLMatrix4 mat4_proxy;
@@ -530,22 +563,9 @@ bool LLLocalMeshImportDAE::processSkin(daeDatabase* collada_db, daeElement* coll
matMul(transform, skininfop->mBindShapeMatrix, skininfop->mBindShapeMatrix);
}
+ LL_DEBUGS("LocalMesh") << "Loading Joint Map." << LL_ENDL;
// setup joint map
- JointMap joint_map = gAgentAvatarp->getJointAliases();
-
- // unfortunately getSortedJointNames clears the ref vector, and we need two extra lists.
- std::vector extra_names, more_extra_names;
- gAgentAvatarp->getSortedJointNames(1, extra_names);
- gAgentAvatarp->getSortedJointNames(2, more_extra_names);
- extra_names.reserve(more_extra_names.size());
- extra_names.insert(extra_names.end(), more_extra_names.begin(), more_extra_names.end());
-
- // add the extras to jointmap
- for (auto extra_name : extra_names)
- {
- joint_map[extra_name] = extra_name;
- }
-
+ JointMap joint_map = loadJointMap();
//=======================================================
// find or re-create a skeleton, deal with joint offsets
@@ -555,65 +575,98 @@ bool LLLocalMeshImportDAE::processSkin(daeDatabase* collada_db, daeElement* coll
// try to find a regular skeleton
size_t skeleton_count = collada_db->getElementCount(NULL, "skeleton");
- bool use_alternative_joint_search = true;
+ std::vector skeletons;
+
JointTransformMap joint_transforms;
- for (size_t skeleton_iterator = 0; skeleton_iterator < skeleton_count; ++skeleton_iterator)
+ for (size_t skeleton_index = 0; skeleton_index < skeleton_count; ++skeleton_index)
{
daeElement* current_element = nullptr;
- collada_db->getElement(¤t_element, skeleton_iterator, 0, "skeleton");
+ daeElement* current_skeleton_root = nullptr;
+ collada_db->getElement(¤t_element, skeleton_index, 0, "skeleton");
+
auto current_skeleton = daeSafeCast(current_element);
- if (!current_skeleton)
+ if (current_skeleton)
{
- continue;
+ current_skeleton_root = current_skeleton->getValue().getElement();
}
- auto current_skeleton_root = current_skeleton->getValue().getElement();
- if (!current_skeleton_root)
+ if (current_skeleton && current_skeleton_root)
{
- continue;
+ skeletons.push_back(current_skeleton);
}
// we found at least one proper sekeleton
- use_alternative_joint_search = false;
- pushLog("DAE Importer", "Skeleton data found, attempting to process..");
-
- auto skeleton_nodes = current_skeleton_root->getChildrenByType();
- for (size_t skeleton_node_iterator = 0; skeleton_node_iterator < skeleton_nodes.getCount(); ++skeleton_node_iterator)
- {
- auto current_node = daeSafeCast(skeleton_nodes[skeleton_node_iterator]);
- if (!current_node)
- {
- continue;
- }
-
- // work with node here
- processSkeletonJoint(current_node, joint_map, joint_transforms);
- }
}
- // no skeletons found, recreate one from joints
- if (use_alternative_joint_search)
+ if (skeletons.empty())
{
pushLog("DAE Importer", "No conventional skeleton data found, attempting to recreate from joints...");
+
daeElement* document_scene = collada_document_root->getDescendant("visual_scene");
if (!document_scene)
{
- // TODO: ERROR
- // missing skeleton set?
+ LL_WARNS() << "Could not find visual_scene element in DAE document. Skipping skinning" << LL_ENDL;
+ return false;
}
else
{
auto scene_children = document_scene->getChildren();
- for (size_t scene_child_iterator = 0; scene_child_iterator < scene_children.getCount(); ++scene_child_iterator)
- {
- auto current_node = daeSafeCast(scene_children[scene_child_iterator]);
- if (!current_node)
- {
- continue;
- }
+ auto childCount = scene_children.getCount();
- // work with node here
- processSkeletonJoint(current_node, joint_map, joint_transforms);
+ // iterate through all the visual_scene and recursively through children and process any that are joints
+ auto all_ok = false;
+ for (size_t scene_child_index = 0; scene_child_index < childCount; ++scene_child_index)
+ {
+ auto current_node = daeSafeCast(scene_children[scene_child_index]);
+ if (current_node)
+ {
+ all_ok = processSkeletonJoint(current_node, joint_map, joint_transforms, true);
+ if(!all_ok)
+ {
+ LL_DEBUGS("LocalMesh") << "failed to process joint: " << current_node->getName() << LL_ENDL;
+ continue;
+ }
+ }
+ }
+ LL_DEBUGS("LocalMesh") << "All joints processed, all_ok = " << all_ok << LL_ENDL;
+ }
+ }
+ else{
+ pushLog("DAE Importer", "Found " + std::to_string(skeletons.size()) + " skeletons.");
+
+ for( domInstance_controller::domSkeleton* current_skeleton : skeletons)
+ {
+ bool workingSkeleton = false;
+ daeElement* current_skeleton_root = current_skeleton->getValue().getElement();
+ if( current_skeleton_root )
+ {
+ std::stringstream ss;
+ //Build a joint for the resolver to work with
+ for (auto jointIt = joint_map.begin(); jointIt != joint_map.end(); ++jointIt)
+ {
+ // Using stringstream to concatenate strings
+ ss << "./" << jointIt->first;
+ //Setup the resolver
+ daeSIDResolver resolver( current_skeleton_root, ss.str().c_str() );
+
+ //Look for the joint
+ domNode* current_joint = daeSafeCast( resolver.getElement() );
+ if ( current_joint )
+ {
+ workingSkeleton = processSkeletonJoint(current_joint, joint_map, joint_transforms);
+ if( !workingSkeleton )
+ {
+ break;
+ }
+ }
+ ss.str("");
+ }
+ }
+ //If anything failed in regards to extracting the skeleton, joints or translation id,
+ //mention it
+ if ( !workingSkeleton )
+ {
+ LL_WARNS("LocalMesh")<< "Partial jointmap found in asset - did you mean to just have a partial map?" << LL_ENDL;
}
}
}
@@ -628,6 +681,7 @@ bool LLLocalMeshImportDAE::processSkin(daeDatabase* collada_db, daeElement* coll
// seems weird, but ok.
if (joint_map.find(joint_name) != joint_map.end())
{
+ LL_DEBUGS("LocalMesh") << "Found internal joint name: " << joint_name << LL_ENDL;
joint_name = joint_map[joint_name];
skininfo.mJointNames.push_back(JointKey::construct(joint_name));
skininfo.mJointNums.push_back(-1);
@@ -635,18 +689,18 @@ bool LLLocalMeshImportDAE::processSkin(daeDatabase* collada_db, daeElement* coll
};
auto& list_of_jointinputs = current_skin->getJoints()->getInput_array();
- for (size_t joint_input_iterator = 0; joint_input_iterator < list_of_jointinputs.getCount(); ++joint_input_iterator)
+ for (size_t joint_input_loop_idx = 0; joint_input_loop_idx < list_of_jointinputs.getCount(); ++joint_input_loop_idx)
{
- auto current_element = list_of_jointinputs[joint_input_iterator]->getSource().getElement();
+ auto current_element = list_of_jointinputs[joint_input_loop_idx]->getSource().getElement();
auto current_source = daeSafeCast(current_element);
if (!current_source)
{
- pushLog("DAE Importer", "WARNING: Joint data number " + std::to_string(joint_input_iterator) + " could not be read, skipping.");
+ pushLog("DAE Importer", "WARNING: Joint data number " + std::to_string(joint_input_loop_idx) + " could not be read, skipping.");
continue;
}
- std::string current_semantic = list_of_jointinputs[joint_input_iterator]->getSemantic();
+ std::string current_semantic = list_of_jointinputs[joint_input_loop_idx]->getSemantic();
if (current_semantic.compare(COMMON_PROFILE_INPUT_JOINT) == 0)
{
// we got a list of the active joints this mesh uses
@@ -658,9 +712,9 @@ bool LLLocalMeshImportDAE::processSkin(daeDatabase* collada_db, daeElement* coll
if (name_source)
{
auto list_of_names = name_source->getValue();
- for (size_t joint_name_iter = 0; joint_name_iter < list_of_names.getCount(); ++joint_name_iter)
+ for (size_t joint_name_loop_index = 0; joint_name_loop_index < list_of_names.getCount(); ++joint_name_loop_index)
{
- std::string current_name = list_of_names.get(joint_name_iter);
+ std::string current_name = list_of_names.get(joint_name_loop_index);
lambda_process_joint_name(current_name);
}
}
@@ -670,14 +724,14 @@ bool LLLocalMeshImportDAE::processSkin(daeDatabase* collada_db, daeElement* coll
auto id_source = current_source->getIDREF_array();
if (!id_source)
{
- pushLog("DAE Importer", "WARNING: Joint number " + std::to_string(joint_input_iterator) + " did not provide name or ID, skipping.");
+ pushLog("DAE Importer", "WARNING: Joint number " + std::to_string(joint_input_loop_idx) + " did not provide name or ID, skipping.");
continue;
}
auto list_of_names = id_source->getValue();
- for (size_t joint_name_iter = 0; joint_name_iter < list_of_names.getCount(); ++joint_name_iter)
+ for (size_t joint_name_loop_index = 0; joint_name_loop_index < list_of_names.getCount(); ++joint_name_loop_index)
{
- std::string current_name = list_of_names.get(joint_name_iter).getID();
+ std::string current_name = list_of_names.get(joint_name_loop_index).getID();
lambda_process_joint_name(current_name);
}
}
@@ -694,25 +748,24 @@ bool LLLocalMeshImportDAE::processSkin(daeDatabase* collada_db, daeElement* coll
}
auto& current_transform = float_array->getValue();
- for (size_t transform_matrix_iterator = 0; transform_matrix_iterator < (current_transform.getCount() / 16); ++transform_matrix_iterator)
+ for (size_t matrix_index = 0; matrix_index < (current_transform.getCount() / 16); ++matrix_index)
{
- LLMatrix4 current_matrix;
- for (size_t matrix_pos_i = 0; matrix_pos_i < 4; matrix_pos_i++)
+ LLMatrix4 mat;
+ for (size_t i = 0; i < 4; i++)
{
- for (size_t matrix_pos_j = 0; matrix_pos_j < 4; matrix_pos_j++)
+ for (size_t j = 0; j < 4; j++)
{
- current_matrix.mMatrix[matrix_pos_i][matrix_pos_j] = current_transform
- [(transform_matrix_iterator * 16) + matrix_pos_i + (matrix_pos_j * 4)];
+ mat.mMatrix[i][j] = current_transform[(matrix_index * 16) + i + (j * 4)];
}
}
- skininfop->mInvBindMatrix.push_back(LLMatrix4a(current_matrix));
+ skininfop->mInvBindMatrix.push_back(LLMatrix4a(mat));
}
}
}
- int jointname_number_iter = 0;
- for (auto jointname_iterator = skininfop->mJointNames.begin(); jointname_iterator != skininfop->mJointNames.end(); ++jointname_iterator, ++jointname_number_iter)
+ int jointname_idx = 0;
+ for (auto jointname_iterator = skininfop->mJointNames.begin(); jointname_iterator != skininfop->mJointNames.end(); ++jointname_iterator, ++jointname_idx)
{
std::string name_lookup = jointname_iterator->mName;
if (joint_map.find(name_lookup) == joint_map.end())
@@ -720,15 +773,19 @@ bool LLLocalMeshImportDAE::processSkin(daeDatabase* collada_db, daeElement* coll
pushLog("DAE Importer", "WARNING: Unknown joint named " + name_lookup + " found, skipping over it.");
continue;
}
+ else
+ {
+ LL_DEBUGS("LocalMesh") << "Calc invBindMat for joint name: " << name_lookup << LL_ENDL;
+ }
- if (skininfop->mInvBindMatrix.size() <= jointname_number_iter)
+ if (skininfop->mInvBindMatrix.size() <= jointname_idx)
{
// doesn't seem like a critical fail that should invalidate the entire skin, just break and move on?
pushLog("DAE Importer", "WARNING: Requesting out of bounds joint named " + name_lookup);
break;
}
- LLMatrix4 newinverse = LLMatrix4(skininfop->mInvBindMatrix[jointname_number_iter].getF32ptr());
+ LLMatrix4 newinverse = LLMatrix4(skininfop->mInvBindMatrix[jointname_idx].getF32ptr());
auto joint_translation = joint_transforms[name_lookup].getTranslation();
newinverse.setTranslation(joint_translation);
skininfop->mAlternateBindMatrix.push_back( LLMatrix4a(newinverse) );
@@ -741,6 +798,10 @@ bool LLLocalMeshImportDAE::processSkin(daeDatabase* collada_db, daeElement* coll
// because it can just be a case of a few additional joints being ignored, unless i'm missing something?
pushLog("DAE Importer", "WARNING: " + std::to_string(skininfop->mJointNames.size()) + " joints were found, but " + std::to_string(bind_count) + " binds matrices were made.");
}
+ else
+ {
+ LL_DEBUGS("LocalMesh") << "Found " << bind_count << " bind matrices" << LL_ENDL;
+ }
//==============================
// transform vtx positions
@@ -754,25 +815,25 @@ bool LLLocalMeshImportDAE::processSkin(daeDatabase* collada_db, daeElement* coll
return false;
}
- std::vector transformed_positions;
+ std::vector transformed_positions; // equates to the model->mPosition vector in full loader
auto vertex_input_array = raw_vertex_array->getInput_array();
- for (size_t vertex_input_iterator = 0; vertex_input_iterator < vertex_input_array.getCount(); ++vertex_input_iterator)
+ for (size_t vertex_input_index = 0; vertex_input_index < vertex_input_array.getCount(); ++vertex_input_index)
{
- std::string current_semantic = vertex_input_array[vertex_input_iterator]->getSemantic();
+ std::string current_semantic = vertex_input_array[vertex_input_index]->getSemantic();
if (current_semantic.compare(COMMON_PROFILE_INPUT_POSITION) != 0)
{
// if what we got isn't a position array - skip.
continue;
}
- if (!transformed_positions.empty())
- {
- // just in case we somehow got multiple valid position arrays
- break;
- }
+ // if (!transformed_positions.empty())
+ // {
+ // // just in case we somehow got multiple valid position arrays
+ // break;
+ // }
- auto pos_source = daeSafeCast(vertex_input_array[vertex_input_iterator]->getSource().getElement());
+ auto pos_source = daeSafeCast(vertex_input_array[vertex_input_index]->getSource().getElement());
if (!pos_source)
{
// not a valid position array, no need to bother the user wit it though.
@@ -785,26 +846,25 @@ bool LLLocalMeshImportDAE::processSkin(daeDatabase* collada_db, daeElement* coll
continue;
}
- auto& vertex_positions = pos_array->getValue();
- for (size_t vtx_position_iterator = 0; vtx_position_iterator < vertex_positions.getCount(); vtx_position_iterator += 3)
+ auto& vtx_pos_list = pos_array->getValue();
+ auto vtx_pos_count = vtx_pos_list.getCount();
+ for (size_t vtx_pos_index = 0; vtx_pos_index < vtx_pos_count; vtx_pos_index += 3)
{
- if (vertex_positions.getCount() <= (vtx_position_iterator + 2))
+ if (vtx_pos_count <= (vtx_pos_index + 2))
{
pushLog("DAE Importer", "ERROR: Position array request out of bound.");
break;
}
- LLVector3 temp_pos
- (
- vertex_positions[vtx_position_iterator],
- vertex_positions[vtx_position_iterator + 1],
- vertex_positions[vtx_position_iterator + 2]
- );
+ LLVector3 pos_vec(
+ vtx_pos_list[vtx_pos_index],
+ vtx_pos_list[vtx_pos_index + 1],
+ vtx_pos_list[vtx_pos_index + 2] );
- temp_pos = temp_pos * inverse_normalized_transformation;
+ pos_vec = pos_vec * inverse_normalized_transformation;
LLVector4 new_vector;
- new_vector.set(temp_pos[0], temp_pos[1], temp_pos[2]);
+ new_vector.set(pos_vec[0], pos_vec[1], pos_vec[2]);
transformed_positions.push_back(new_vector);
}
@@ -822,20 +882,17 @@ bool LLLocalMeshImportDAE::processSkin(daeDatabase* collada_db, daeElement* coll
auto weight_inputs = current_weights->getInput_array();
domFloat_array* vertex_weights = nullptr;
-
- for (size_t weight_input_iter = 0; weight_input_iter < weight_inputs.getCount(); ++weight_input_iter)
+ auto num_weight_inputs = weight_inputs.getCount();
+ for (size_t weight_input_idx = 0; weight_input_idx < num_weight_inputs; ++weight_input_idx)
{
- std::string current_semantic = weight_inputs[weight_input_iter]->getSemantic();
+ std::string current_semantic = weight_inputs[weight_input_idx]->getSemantic();
if (current_semantic.compare(COMMON_PROFILE_INPUT_WEIGHT) == 0)
{
- auto weights_source = daeSafeCast(weight_inputs[weight_input_iter]->getSource().getElement());
- if (!weights_source)
+ auto weights_source = daeSafeCast(weight_inputs[weight_input_idx]->getSource().getElement());
+ if (weights_source)
{
- continue;
+ vertex_weights = weights_source->getFloat_array();
}
-
- vertex_weights = weights_source->getFloat_array();
- break;
}
}
@@ -849,45 +906,45 @@ bool LLLocalMeshImportDAE::processSkin(daeDatabase* collada_db, daeElement* coll
// v - joint indices
auto& weight_values = vertex_weights->getValue();
- auto& joint_influence_count = current_weights->getVcount()->getValue();
+ auto& vtx_influence_count = current_weights->getVcount()->getValue();
auto& joint_weight_indices = current_weights->getV()->getValue();
+
std::map > skinweight_data;
size_t joint_weight_strider = 0;
- for (size_t joint_iterator = 0; joint_iterator < joint_influence_count.getCount(); ++joint_iterator)
+ for (size_t joint_idx = 0; joint_idx < vtx_influence_count.getCount(); ++joint_idx)
{
- auto influencees_count = joint_influence_count[joint_iterator];
- LLModel::weight_list full_weight_list;
+ auto influences_count = vtx_influence_count[joint_idx];
+ LLModel::weight_list weight_list;
LLModel::weight_list sorted_weight_list;
// extract all of the weights
- for (size_t influence_iter = 0; influence_iter < influencees_count; ++influence_iter)
+ for (size_t influence_idx = 0; influence_idx < influences_count; ++influence_idx)
{
- int joint_idx = joint_weight_indices[joint_weight_strider++];
- int weight_idx = joint_weight_indices[joint_weight_strider++];
+ int vtx_idx = joint_weight_indices[joint_weight_strider++];
+ int this_weight_idx = joint_weight_indices[joint_weight_strider++];
- if (joint_idx == -1)
+ if (vtx_idx == -1)
{
continue;
}
- float weight_value = weight_values[weight_idx];
- full_weight_list.push_back(LLModel::JointWeight(joint_idx, weight_value));
+ float weight_value = weight_values[this_weight_idx];
+ weight_list.push_back(LLModel::JointWeight(vtx_idx, weight_value));
}
// sort by large-to-small
- std::sort(full_weight_list.begin(), full_weight_list.end(), LLModel::CompareWeightGreater());
-
+ std::sort(weight_list.begin(), weight_list.end(), LLModel::CompareWeightGreater());
// limit to 4, and normalize the result
F32 total = 0.f;
- for (U32 i = 0; i < llmin((U32)4, (U32)full_weight_list.size()); ++i)
+ for (U32 i = 0; i < llmin((U32)4, (U32)weight_list.size()); ++i)
{ //take up to 4 most significant weights
- if (full_weight_list[i].mWeight > 0.f)
+ if (weight_list[i].mWeight > 0.f)
{
- sorted_weight_list.push_back(full_weight_list[i]);
- total += full_weight_list[i].mWeight;
+ sorted_weight_list.push_back(weight_list[i]);
+ total += weight_list[i].mWeight;
}
}
@@ -899,8 +956,18 @@ bool LLLocalMeshImportDAE::processSkin(daeDatabase* collada_db, daeElement* coll
sorted_weight_list[i].mWeight *= scale;
}
}
-
- skinweight_data[transformed_positions[joint_iterator]] = sorted_weight_list;
+ // log the weights for this joint_idx
+ LL_DEBUGS("LocalMesh") << "Vertex "
+ << joint_idx
+ << " has " << sorted_weight_list.size() << " weights (" <<
+ sorted_weight_list[0].mJointIdx << "=" <<
+ sorted_weight_list[0].mWeight << ", " <<
+ sorted_weight_list[1].mJointIdx << "=" <<
+ sorted_weight_list[1].mWeight << ", " <<
+ sorted_weight_list[2].mJointIdx << "=" <<
+ sorted_weight_list[3].mWeight << ")"
+ << LL_ENDL;
+ skinweight_data[transformed_positions[joint_idx]] = sorted_weight_list;
}
//==============================
@@ -930,24 +997,25 @@ bool LLLocalMeshImportDAE::processSkin(daeDatabase* collada_db, daeElement* coll
for (auto& current_position : positions)
{
- int found_iterator = -1;
+ int found_idx = -1;
- for (size_t internal_position_iter = 0; internal_position_iter < transformed_positions.size(); ++internal_position_iter)
+ for (size_t internal_position_idx = 0; internal_position_idx < transformed_positions.size(); ++internal_position_idx)
{
- auto& internal_position = transformed_positions[internal_position_iter];
+ auto& internal_position = transformed_positions[internal_position_idx];
if (soft_compare(current_position, internal_position, F_ALMOST_ZERO))
{
- found_iterator = internal_position_iter;
+ found_idx = internal_position_idx;
break;
}
}
- if (found_iterator < 0)
+ if (found_idx < 0)
{
+ LL_DEBUGS("LocalMesh") << "Failed to find position " << current_position << " in transformed positions" << LL_ENDL;
continue;
}
- auto cjoints = skinweight_data[transformed_positions[found_iterator]];
+ auto cjoints = skinweight_data[transformed_positions[found_idx]];
LLLocalMeshFace::LLLocalMeshSkinUnit new_wght;
@@ -976,91 +1044,142 @@ bool LLLocalMeshImportDAE::processSkin(daeDatabase* collada_db, daeElement* coll
}
}
skininfop->updateHash();
+ LL_DEBUGS("LocalMesh") << "hash: " << skininfop->mHash << LL_ENDL;
current_object->setObjectMeshSkinInfo(skininfop);
return true;
}
-void LLLocalMeshImportDAE::processSkeletonJoint(domNode* current_node, std::map& joint_map, std::map& joint_transforms)
+bool LLLocalMeshImportDAE::processSkeletonJoint(domNode* current_node, std::map& joint_map, std::map& joint_transforms, bool recurse_children)
{
// safety checks & name check
- auto node_name = current_node->getName();
+ const auto node_name = current_node->getName();
if (!node_name)
{
- return;
+ LL_WARNS("LocalMesh") << "nameless node, can't process" << LL_ENDL;
+ return false;
}
- auto jointmap_iter = joint_map.find(node_name);
- if (jointmap_iter == joint_map.end())
+ if (auto jointmap_iter = joint_map.find(node_name); jointmap_iter != joint_map.end())
{
- return;
- }
+ LL_DEBUGS("LocalMesh") << "processing joint: " << node_name << LL_ENDL;
- // begin actual joint work
- domTranslate* current_transformation = nullptr;
-
- daeSIDResolver jointResolver_translation(current_node, "./translate");
- current_transformation = daeSafeCast(jointResolver_translation.getElement());
-
- if (!current_transformation)
- {
- daeSIDResolver jointResolver_location(current_node, "./location");
- current_transformation = daeSafeCast(jointResolver_location.getElement());
- }
-
- if (!current_transformation)
- {
- daeElement* child_translate_element = current_node->getChild("translate");
- if (child_translate_element)
+ // begin actual joint work
+ daeSIDResolver jointResolver_translation(current_node, "./translate");
+ domTranslate* current_transformation = daeSafeCast(jointResolver_translation.getElement());
+ if (current_transformation)
{
- current_transformation = daeSafeCast(child_translate_element);
+ LL_DEBUGS("LocalMesh") << "Using ./translate for " << node_name << LL_ENDL;
}
- }
-
- if (!current_transformation) // no queries worked
- {
- daeSIDResolver jointResolver_matrix(current_node, "./matrix");
- auto joint_transform_matrix = daeSafeCast(jointResolver_matrix.getElement());
- if (joint_transform_matrix)
+ else
{
- LLMatrix4 workingTransform;
- domFloat4x4 domArray = joint_transform_matrix->getValue();
- for (int i = 0; i < 4; i++)
+ daeSIDResolver jointResolver_location(current_node, "./location");
+ current_transformation = daeSafeCast(jointResolver_location.getElement());
+ if (current_transformation)
{
- for (int j = 0; j < 4; j++)
+ LL_DEBUGS("LocalMesh") << "Using ./location for " << node_name << LL_ENDL;
+ }
+ }
+
+ if (!current_transformation)
+ {
+ if (daeElement* child_translate_element = current_node->getChild("translate"); child_translate_element)
+ {
+ if (current_transformation = daeSafeCast(child_translate_element); current_transformation)
{
- workingTransform.mMatrix[i][j] = domArray[i + j * 4];
+ LL_DEBUGS("LocalMesh") << "Using translate child for " << node_name << LL_ENDL;
}
}
- // LLVector3 trans = workingTransform.getTranslation();
- joint_transforms[node_name] = workingTransform;
- }
- }
+ else
+ {
+ LL_DEBUGS("Mesh")<< "Could not find a child [\"translate\"] for the element: \"" << node_name << "\"" << LL_ENDL;
+ }
+ }
- else // previous query worked
- {
- domFloat3 joint_transform = current_transformation->getValue();
- LLVector3 singleJointTranslation(joint_transform[0], joint_transform[1], joint_transform[2]);
- LLMatrix4 workingtransform;
- workingtransform.setTranslation(singleJointTranslation);
-
- joint_transforms[node_name] = workingtransform;
- }
- // end actual joint work
-
- // get children to work on
- auto current_node_children = current_node->getChildren();
- for (size_t node_children_iter = 0; node_children_iter < current_node_children.getCount(); ++node_children_iter)
- {
- auto current_child_node = daeSafeCast(current_node_children[node_children_iter]);
- if (!current_child_node)
+ if (!current_transformation) // no queries worked
{
- continue;
+ daeSIDResolver jointResolver_transform(current_node, "./transform");
+
+ auto joint_transform_matrix = daeSafeCast(jointResolver_transform.getElement());
+ if (joint_transform_matrix)
+ {
+ LLMatrix4 workingTransform;
+ domFloat4x4 domArray = joint_transform_matrix->getValue();
+ for (int i = 0; i < 4; i++)
+ {
+ for (int j = 0; j < 4; j++)
+ {
+ workingTransform.mMatrix[i][j] = domArray[i + j * 4];
+ }
+ }
+ joint_transforms[node_name].setTranslation(workingTransform.getTranslation());
+ LL_DEBUGS("LocalMesh") << "Using ./transform matrix for " << node_name << " = "<< joint_transforms[node_name] << LL_ENDL;
+ }
+ else
+ {
+ daeSIDResolver jointResolver_matrix(current_node, "./matrix");
+ joint_transform_matrix = daeSafeCast(jointResolver_matrix.getElement());
+ if (joint_transform_matrix)
+ {
+ LL_DEBUGS("LocalMesh") << "Using ./matrix matrix for " << node_name << LL_ENDL;
+ LLMatrix4 workingTransform;
+ domFloat4x4 domArray = joint_transform_matrix->getValue();
+ for (int i = 0; i < 4; i++)
+ {
+ for (int j = 0; j < 4; j++)
+ {
+ workingTransform.mMatrix[i][j] = domArray[i + j * 4];
+ }
+ }
+ joint_transforms[node_name] = workingTransform;
+ LL_DEBUGS("LocalMesh") << "Using ./transform matrix for " << node_name << " = "<< workingTransform << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS() << "The found element for " << node_name << " is not a translate or matrix node - most likely a corrupt export!" << LL_ENDL;
+ // return false; // Beq - an unweighted bone? returning failure here can trigger problems with otherwise good mesh.
+ }
+ }
}
+ else // previous query worked
+ {
+ domFloat3 joint_transform = current_transformation->getValue();
+ LLVector3 singleJointTranslation(joint_transform[0], joint_transform[1], joint_transform[2]);
+ LLMatrix4 workingTransform;
+ workingTransform.setTranslation(singleJointTranslation);
- processSkeletonJoint(current_child_node, joint_map, joint_transforms);
+ joint_transforms[node_name] = workingTransform;
+ LL_DEBUGS("LocalMesh") << "Applying translation from detected transform for " << node_name << " = "<< workingTransform << LL_ENDL;
+ }
+ // end actual joint work
+ }
+ else
+ {
+ LL_DEBUGS("LocalMesh") << "unknown/unexpected joint: " << node_name << LL_ENDL;
+ // return false; // still need to check the children
}
-}
+ if (recurse_children)
+ {
+ // get children to work on
+ auto current_node_children = current_node->getChildren();
+ auto child_count = current_node_children.getCount();
+ LL_DEBUGS("LocalMesh") << "Processing " << child_count << " children of " << current_node->getName() << LL_ENDL;
+ for (size_t node_children_iter = 0; node_children_iter < child_count; ++node_children_iter)
+ {
+ auto current_child_node = daeSafeCast(current_node_children[node_children_iter]);
+ if (current_child_node)
+ {
+ if( !processSkeletonJoint(current_child_node, joint_map, joint_transforms, recurse_children) )
+ {
+ LL_DEBUGS("LocalMesh") << "failed to process joint (bad child): " << current_child_node->getName() << LL_ENDL;
+ continue;
+ };
+ }
+ }
+ }
+
+ return true;
+}
bool LLLocalMeshImportDAE::readMesh_CommonElements(const domInputLocalOffset_Array& inputs,
int& offset_position, int& offset_normals, int& offset_uvmap, int& index_stride,
@@ -1196,15 +1315,6 @@ std::string LLLocalMeshImportDAE::getElementName(daeElement* element_current, in
return result;
}
-void LLLocalMeshImportDAE::pushLog(std::string who, std::string what)
-{
- std::string log_msg = "[ " + who + " ] ";
-
- log_msg += what;
- mLoadingLog.push_back(log_msg);
-}
-
-
bool LLLocalMeshImportDAE::readMesh_Triangle(LLLocalMeshFace* data_out, const domTrianglesRef& data_in)
{
if (!data_out)
@@ -1675,6 +1785,19 @@ bool LLLocalMeshImportDAE::readMesh_Polylist(LLLocalMeshFace* data_out, const do
return true;
}
+void LLLocalMeshImportDAE::pushLog(const std::string& who, const std::string& what, bool is_error)
+{
+ std::string log_msg = "[ " + who + " ] ";
+ if (is_error)
+ {
+ log_msg += "[ ERROR ] ";
+ }
+
+ log_msg += what;
+ mLoadingLog.push_back(log_msg);
+ LL_INFOS("LocalMesh") << log_msg << LL_ENDL;
+}
+
//bool LLLocalMeshImportDAE::readMesh_Polygons(LLLocalMeshFace* data_out, const domPolygonsRef& data_in)
//{
/*
diff --git a/indra/newview/vjlocalmeshimportdae.h b/indra/newview/vjlocalmeshimportdae.h
index 251e28fc28..1c1dc9628a 100644
--- a/indra/newview/vjlocalmeshimportdae.h
+++ b/indra/newview/vjlocalmeshimportdae.h
@@ -71,14 +71,13 @@ public:
loadFile_return loadFile(LLLocalMeshFile* data, LLLocalMeshFileLOD lod);
bool processObject(domMesh* current_mesh, LLLocalMeshObject* current_object);
bool processSkin(daeDatabase* collada_db, daeElement* collada_document_root, domMesh* current_mesh, domSkin* current_skin, std::unique_ptr& current_object);
- void processSkeletonJoint(domNode* current_node, std::map& joint_map, std::map& joint_transforms);
+ bool processSkeletonJoint(domNode* current_node, std::map& joint_map, std::map& joint_transforms, bool recurse_children=false);
bool readMesh_CommonElements(const domInputLocalOffset_Array& inputs,
int& offset_position, int& offset_normals, int& offset_uvmap, int& index_stride,
domSource*& source_position, domSource*& source_normals, domSource*& source_uvmap);
std::string getElementName(daeElement* element_current, int fallback_index);
- void pushLog(std::string who, std::string what);
// mesh data read functions, basically refactored from what's already in lldaeloader
// consolidating them into a single mega function makes for very sketchy readability.
@@ -87,6 +86,7 @@ public:
// NOTE: polygon schema
//bool readMesh_Polygons(LLLocalMeshFace* data_out, const domPolygonsRef& data_in);
+ void pushLog(const std::string& who, const std::string& what, bool is_error=false);
private:
LLLocalMeshFileLOD mLod;
diff --git a/requirements.txt b/requirements.txt
index 308ed7a4cd..c157ec2b54 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,3 +1,3 @@
-llbase==1.2.11
-autobuild==3.9.1
-llsd==1.2.1
\ No newline at end of file
+llbase
+autobuild
+llsd
\ No newline at end of file
diff --git a/scripts/configure_firestorm.sh b/scripts/configure_firestorm.sh
index 1255293d54..6b2111506a 100755
--- a/scripts/configure_firestorm.sh
+++ b/scripts/configure_firestorm.sh
@@ -594,6 +594,11 @@ if [ $WANTS_CONFIG -eq $TRUE ] ; then
echo "Setting startup project via vstool"
../indra/tools/vstool/VSTool.exe --solution Firestorm.sln --startup firestorm-bin --workingdir firestorm-bin "..\\..\\indra\\newview" --config $BTYPE
fi
+ # Check the return code of the build command
+ if [ $? -ne 0 ]; then
+ echo "Configure failed!"
+ exit 1
+ fi
fi
if [ $WANTS_BUILD -eq $TRUE ] ; then
echo "Building $TARGET_PLATFORM..."
@@ -625,6 +630,12 @@ if [ $WANTS_BUILD -eq $TRUE ] ; then
-verbosity:normal -toolsversion:15.0 -p:"VCBuildAdditionalOptions= /incremental"
fi
fi
+ # Check the return code of the build command
+ if [ $? -ne 0 ]; then
+ echo "Build failed!"
+ exit 1
+ fi
fi
echo "finished"
+exit 0