Ansariel 2024-01-05 13:17:48 +01:00
commit c0abd01b17
61 changed files with 666 additions and 278 deletions

View File

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

View File

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

29
README.md Normal file
View File

@ -0,0 +1,29 @@
<picture>
<img alt="Firestorm Viewer Logo" src="doc/firestorm_256.png">
</picture>
**[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.

View File

@ -4257,7 +4257,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>license_file</key>
<string>docs/LICENSE-source.txt</string>
<key>copyright</key>
<string>Copyright (c) 2023, The Phoenix Firestorm Project, Inc.</string>
<string>Copyright (c) 2024, The Phoenix Firestorm Project, Inc.</string>
<key>version_file</key>
<string>newview/viewer_version.txt</string>
<key>name</key>

BIN
doc/firestorm_256.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 KiB

View File

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

View File

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

View File

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

View File

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

View File

@ -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"), // <FS:Zi> Add label/caption colors
text_disabled_color("text_disabled_color"), // <FS:Zi> 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), // <FS:Zi> Add label/caption colors
mTextDisabledColor(p.text_disabled_color), // <FS:Zi> 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<LLViewBorder> (params);
addChild(mBorder);
updateLabelColor(); // <FS:Zi> Add label/caption colors
}
LLColorSwatchCtrl::~LLColorSwatchCtrl ()
@ -250,12 +256,18 @@ void LLColorSwatchCtrl::draw()
}
}
mCaption->setEnabled(getEnabled() && isInEnabledChain()); // <FS:Zi> Add label/caption colors
LLUICtrl::draw();
}
void LLColorSwatchCtrl::setEnabled( BOOL enabled )
{
mCaption->setEnabled( enabled );
// <FS:Zi> Add label/caption colors
// mCaption->setEnabled( enabled );
mCaption->setEnabled(enabled && isInEnabledChain());
// </FS:Zi>
LLView::setEnabled( enabled );
if (!enabled)
@ -374,3 +386,10 @@ void LLColorSwatchCtrl::showPicker(BOOL take_focus)
}
}
// <FS:Zi> Add label/caption colors
void LLColorSwatchCtrl::updateLabelColor()
{
mCaption->setColor(mTextEnabledColor.get());
mCaption->setReadOnlyColor(mTextDisabledColor.get());
}
// </FS:Zi>

View File

@ -62,6 +62,10 @@ public:
Optional<LLTextBox::Params> caption_text;
Optional<LLViewBorder::Params> border;
Optional<LLUIColor> text_enabled_color; // <FS:Zi> Add label/caption colors
Optional<LLUIColor> text_disabled_color; // <FS:Zi> 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(); } // <FS:Zi> Add label/caption colors
void setDisabledLabelColor(const LLColor4& c) { mTextDisabledColor = c; updateLabelColor(); } // <FS:Zi> Add label/caption colors
protected:
void updateLabelColor(); // <FS:Zi> Add label/caption colors
bool mValid;
LLColor4 mColor;
LLUIColor mBorderColor;
@ -116,6 +125,9 @@ protected:
LLPointer<LLUIImage> mAlphaGradientImage;
LLPointer<LLUIImage> mFallbackImage;
LLUIColor mTextEnabledColor; // <FS:Zi> Add label/caption colors
LLUIColor mTextDisabledColor; // <FS:Zi> Add label/caption colors
};
#endif // LL_LLBUTTON_H

View File

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

View File

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

View File

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

View File

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

View File

@ -40,7 +40,6 @@ class LLButton;
class LLMenuButton;
class LLViewerObject;
class LLComboBox;
class LLColorSwatchCtrl;
class LLTextureCtrl;
class LLInventoryItem;
class LLUUID;

View File

@ -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), // <FS:Zi> Add label/caption colors
mTextDisabledColor(p.text_disabled_color), // <FS:Zi> Add label/caption colors
// <FS:Ansariel> 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 ));
// <FS:Zi> 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<LLTextBox> (params);
@ -1811,6 +1816,8 @@ LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p)
addChild(mBorder);
mLoadingPlaceholderString = LLTrans::getString("texture_loading");
updateLabelColor(); // <FS:Zi> Add label/caption colors
}
LLTextureCtrl::~LLTextureCtrl()
@ -1895,7 +1902,10 @@ void LLTextureCtrl::setEnabled( BOOL enabled )
closeDependentFloater();
}
mCaption->setEnabled( enabled );
// <FS:Zi> Add label/caption colors
// mCaption->setEnabled( enabled );
mCaption->setEnabled(enabled && isInEnabledChain());
// </FS:Zi>
// <FS:Ansariel> Texture preview mode
//LLView::setEnabled( enabled );
@ -2420,6 +2430,8 @@ void LLTextureCtrl::draw()
}
}
mCaption->setEnabled(getEnabled() && isInEnabledChain()); // <FS:Zi> Add label/caption colors
LLUICtrl::draw();
}
@ -2526,7 +2538,10 @@ LLSD LLTextureCtrl::getValue() const
return LLSD(getImageAssetID());
}
// <FS:Zi> Add label/caption colors
void LLTextureCtrl::updateLabelColor()
{
mCaption->setColor(mTextEnabledColor.get());
mCaption->setReadOnlyColor(mTextDisabledColor.get());
}
// </FS:Zi>

View File

@ -122,6 +122,9 @@ public:
Optional<LLViewBorder::Params> border;
Optional<bool> show_caption; // <FS:Zi> leave some room underneath the image for the caption
Optional<LLUIColor> text_enabled_color; // <FS:Zi> Add label/caption colors
Optional<LLUIColor> text_disabled_color; // <FS:Zi> 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), // <FS:Zi> leave some room underneath the image for the caption
text_enabled_color("text_enabled_color"), // <FS:Zi> Add label/caption colors
text_disabled_color("text_disabled_color"), // <FS:Zi> Add label/caption colors
caption_text("caption_text"),
border("border")
{}
@ -250,10 +255,15 @@ public:
// <FS:Ansariel> Mask texture if desired
void setIsMasked(BOOL masked) { mIsMasked = masked; }
void setLabelColor(const LLColor4& c) { mTextEnabledColor = c; updateLabelColor(); } // <FS:Zi> Add label/caption colors
void setDisabledLabelColor(const LLColor4& c) { mTextDisabledColor = c; updateLabelColor(); } // <FS:Zi> Add label/caption colors
private:
BOOL allowDrop(LLInventoryItem* item, EDragAndDropType cargo_type, std::string& tooltip_msg);
BOOL doDrop(LLInventoryItem* item);
void updateLabelColor(); // <FS:Zi> Add label/caption colors
private:
drag_n_drop_callback mDragCallback;
drag_n_drop_callback mDropCallback;
@ -293,6 +303,9 @@ private:
// <FS:Ansariel> Mask texture if desired
BOOL mIsMasked;
LLUIColor mTextEnabledColor; // <FS:Zi> Add label/caption colors
LLUIColor mTextDisabledColor; // <FS:Zi> Add label/caption colors
};
//////////////////////////////////////////////////////////////////////////////////////////

View File

@ -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.
// <FS:Zi> 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.
// </FS:Zi>
*ray_end_region = regionp->getPosRegionFromGlobal( ray_end_global );
}

View File

@ -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"); // <FS:PP> 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"); // <FS:PP> FIRE-33249 Mic toggle
return true;
}
return false;

View File

@ -628,7 +628,6 @@ void LLVoiceClient::setUserPTTState(bool ptt)
mUserPTTState = ptt;
updateMicMuteLogic();
mMicroChangedSignal();
make_ui_sound("UISndMicToggle"); // <FS:PP> 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"); // <FS:PP> FIRE-33249 Mic toggle
}
}
void LLVoiceClient::toggleUserPTTState(void)
{
setUserPTTState(!getUserPTTState());
make_ui_sound("UISndMicToggle"); // <FS:PP> FIRE-33249 Mic toggle
}

View File

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

View File

@ -110,8 +110,8 @@
<combo_box.item value="filter_type_sounds" label="Sounds" />
<combo_box.item value="filter_type_textures" label="Texturen" />
<combo_box.item value="filter_type_snapshots" label="Fotos" />
<combo_box.item value="filter_type_meshes" label="Meshes" />
<combo_box.item value="filter_type_settings" label="Einstellungen" />
<combo_box.item value="filter_type_materials" label="Materialien" />
<combo_box.item value="filter_separator" label="------------" />
<combo_box.item value="filter_type_custom" label="Benutzerdefiniert..." />
</combo_box>

View File

@ -736,7 +736,7 @@
<combo_box.item value="filter_type_sounds" label="Sounds" />
<combo_box.item value="filter_type_textures" label="Textures" />
<combo_box.item value="filter_type_snapshots" label="Snapshots" />
<combo_box.item value="filter_type_meshes" label="Meshes" />
<combo_box.item value="filter_type_materials" label="Materials" />
<combo_box.item value="filter_type_settings" label="Settings" />
<combo_box.item value="filter_separator" label="------------" enabled="false" />
<combo_box.item value="filter_type_custom" label="Custom..." />

View File

@ -82,7 +82,6 @@
<combo_box.item value="filter_type_sounds" label="Sonidos"/>
<combo_box.item value="filter_type_textures" label="Texturas"/>
<combo_box.item value="filter_type_snapshots" label="Fotos"/>
<combo_box.item value="filter_type_meshes" label="Modelos mesh"/>
<combo_box.item value="filter_type_custom" label="Personalizar..."/>
</combo_box>
</layout_panel>

View File

@ -109,7 +109,6 @@
<combo_box.item value="filter_type_sounds" label="Dźwięki" />
<combo_box.item value="filter_type_textures" label="Tekstury" />
<combo_box.item value="filter_type_snapshots" label="Zdjęcia" />
<combo_box.item value="filter_type_meshes" label="Mesze" />
<combo_box.item value="filter_type_settings" label="Otoczenia" />
<combo_box.item value="filter_type_custom" label="Własny filtr..." />
</combo_box>

View File

@ -97,7 +97,6 @@
<combo_box.item value="filter_type_sounds" label="Звуки" />
<combo_box.item value="filter_type_textures" label="Текстуры" />
<combo_box.item value="filter_type_snapshots" label="Снимки" />
<combo_box.item value="filter_type_meshes" label="Меш" />
<combo_box.item value="filter_type_settings" label="Настройки" />
<combo_box.item value="filter_type_custom" label="Другое..." />
</combo_box>

View File

@ -37,7 +37,6 @@
<combo_box.item value="filter_type_sounds" label="Səslər" />
<combo_box.item value="filter_type_textures" label="Teksturlar" />
<combo_box.item value="filter_type_snapshots" label="Şəkillər" />
<combo_box.item value="filter_type_meshes" label="Meş" />
<combo_box.item value="filter_type_settings" label="Seçimlər" />
<combo_box.item value="filter_type_custom" label="Ayrı..." />
</combo_box>

View File

@ -10,7 +10,7 @@
Genstande:
</text>
<layout_stack name="top_stack">
<layout_panel name="filter_layout_panel">
<layout_panel name="filter_panel">
<filter_editor label="Filter" name="inventory search editor"/>
<button name="options_gear_btn" tool_tip="Vis yderligere valg"/>
<button name="add_btn" tool_tip="Tilføj ny genstand"/>

View File

@ -41,7 +41,7 @@
<combo_box.item value="filter_type_sounds" label="Sounds" />
<combo_box.item value="filter_type_textures" label="Texturen" />
<combo_box.item value="filter_type_snapshots" label="Fotos" />
<combo_box.item value="filter_type_meshes" label="Meshes" />
<combo_box.item value="filter_type_materials" label="Materialien" />
<combo_box.item value="filter_type_settings" label="Einstellungen" />
<combo_box.item value="filter_separator" label="------------" />
<combo_box.item value="filter_type_custom" label="Benutzerdefiniert..." />

View File

@ -89,7 +89,7 @@
width="324"
name="filter_panel"
visible="true"
name="filter_layout_panel">
>
<filter_editor
text_pad_left="10"
follows="left|top|right"
@ -180,7 +180,7 @@
<combo_box.item value="filter_type_sounds" label="Sounds" />
<combo_box.item value="filter_type_textures" label="Textures" />
<combo_box.item value="filter_type_snapshots" label="Snapshots" />
<combo_box.item value="filter_type_meshes" label="Meshes" />
<combo_box.item value="filter_type_materials" label="Materials" />
<combo_box.item value="filter_type_settings" label="Settings" />
<combo_box.item value="filter_separator" label="------------" enabled="false" />
<combo_box.item value="filter_type_custom" label="Custom..." />

View File

@ -1,6 +1,9 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<!-- <FS:Zi> Add label/caption colors (text_enabled_color/text_disabled_color) -->
<color_swatch alpha_background_image="color_swatch_alpha.tga"
border_color="ColorSwatchBorderColor"
text_enabled_color="LabelTextColor"
text_disabled_color="LabelDisabledColor"
name="colorswatch">
<color_swatch.caption_text name="caption"
halign="center"

View File

@ -1,8 +1,11 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<!-- <FS:Zi> Add label/caption colors (text_enabled_color/text_disabled_color) -->
<texture_picker border_color="DefaultHighlightLight"
name="texture picker"
mouse_opaque="true"
follows="left|top"
text_enabled_color="LabelTextColor"
text_disabled_color="LabelDisabledColor"
>
<multiselect_text font="SansSerifSmall"/>
<caption_text halign="center"

View File

@ -36,7 +36,6 @@
<combo_box.item value="filter_type_sounds" label="Sonidos"/>
<combo_box.item value="filter_type_textures" label="Texturas"/>
<combo_box.item value="filter_type_snapshots" label="Fotografías"/>
<combo_box.item value="filter_type_meshes" label="Modelos mesh"/>
<combo_box.item value="filter_type_custom" label="Personalizado..."/>
</combo_box>
<menu_button tool_tip="Mostrar opciones de visibilidad de búsqueda" name="options_visibility_btn" />

View File

@ -34,7 +34,6 @@
<combo_box.item value="filter_type_sounds" label="Sons"/>
<combo_box.item value="filter_type_textures" label="Textures"/>
<combo_box.item value="filter_type_snapshots" label="Photos"/>
<combo_box.item value="filter_type_meshes" label="Meshs"/>
<combo_box.item value="filter_type_settings" label="Paramètres" />
<combo_box.item value="filter_type_custom" label="Personnalisé..."/>
</combo_box>

View File

@ -38,7 +38,6 @@
<combo_box.item value="filter_type_sounds" label="Suoni" />
<combo_box.item value="filter_type_textures" label="Texture" />
<combo_box.item value="filter_type_snapshots" label="Fotografie" />
<combo_box.item value="filter_type_meshes" label="Modelli mesh" />
<combo_box.item value="filter_type_settings" label="Ambienti" />
<combo_box.item value="filter_type_custom" label="Personalizzato..." />
</combo_box>

View File

@ -31,7 +31,6 @@
<combo_box.item value="filter_type_sounds" label="サウンド" />
<combo_box.item value="filter_type_textures" label="テクスチャ" />
<combo_box.item value="filter_type_snapshots" label="スナップショット" />
<combo_box.item value="filter_type_meshes" label="メッシュ" />
<combo_box.item value="filter_type_settings" label="自然環境設定" />
<combo_box.item value="filter_type_custom" label="カスタマイズ..." />
</combo_box>

View File

@ -42,7 +42,6 @@
<combo_box.item value="filter_type_sounds" label="Dźwięki" />
<combo_box.item value="filter_type_textures" label="Tekstury" />
<combo_box.item value="filter_type_snapshots" label="Zdjęcia" />
<combo_box.item value="filter_type_meshes" label="Mesze" />
<combo_box.item value="filter_type_settings" label="Otoczenia" />
<combo_box.item value="filter_type_custom" label="Własny filtr..." />
</combo_box>

View File

@ -14,7 +14,7 @@
Itens:
</text>
<layout_stack name="top_stack">
<layout_panel name="filter_layout_panel">
<layout_panel name="filter_panel">
<combo_box name="search_type">
<item label="Nome" name="Name" value="search_by_name"/>
<item label="Criador" name="Creator" value="search_by_creator"/>

View File

@ -300,6 +300,7 @@
<menu_item_call label="Торговая площадка SL (Marketplace)" name="SL Marketplace"/>
<menu_item_call label="Торговые данные L$" name="LindenXchange"/>
<menu_item_call label="Библиотека скриптов" name="Script Library"/>
<menu_item_call label="SL Сообщество (блоги, форумы, новости)" name="SL Community Pages"/>
<menu_item_call label="Блог Firestorm" name="Firestorm Blog"/>
<menu_item_call label="Firestorm Flickr" name="Firestorm Flickr"/>
<menu_item_call label="Firestorm YouTube" name="Firestorm YouTube"/>

View File

@ -42,7 +42,6 @@
<combo_box.item value="filter_type_sounds" label="Звуки" />
<combo_box.item value="filter_type_textures" label="Текстуры" />
<combo_box.item value="filter_type_snapshots" label="Снимки" />
<combo_box.item value="filter_type_meshes" label="Меш" />
<combo_box.item value="filter_type_settings" label="Настройки" />
<combo_box.item value="filter_type_custom" label="Другое..." />
</combo_box>

View File

@ -81,6 +81,15 @@
<check_box label="Предотвращение фокуса окна статистики" name="FSStatisticsNoFocus"
tool_tip="Если включено, окно статистики никогда не будет получать фокус при закрытии другого окна (такие действия, как изменение макета графа для элементов, по-прежнему возможны, если они включены)."
width="256" />
<check_box label="Показывать миниатюры предметов инвентаря во всплывающих подсказках" name="FSShowInventoryThumbnailTooltips"
tool_tip="Если этот параметр включен, при наведении курсора на предметы инвентаря содержащие миниатюру, миниатюра будет отображаться во всплывающей подсказке."
width="256" />
<slider label="Задержка всплывающей подсказки миниатюр:"
tool_tip="Задержка появления всплывающих подсказок с миниатюрами предметов инвентаря."
label_width="200" name="FSInventoryThumbnailTooltipsDelay" width="457" />
<text name="FSInventoryThumbnailTooltipsDelayText" width="50">
сек
</text>
<slider label="Количество миганий вкладки ЛС:" name="ButtonsFlashCount" />
<slider label="Частота мигания вкладок ЛС:" tool_tip="Частота мигания вкладок личных сообщений:" name="ButtonFlashRate" />
<text name="ButtonFlashRateText">

View File

@ -503,6 +503,13 @@
<button name="Def_UISndTrackerBeacon" tool_tip="Сброс к UUID по умолчанию."/>
<check_box label="Включить звук" name="PlayModeUISndTrackerBeacon"/>
<text name="textFSMicToggle" tool_tip="Звуковой UUID воспроизводится при включении или выключении микрофона.">
Переключатель микрофона:
</text>
<button name="Prev_UISndMicToggle" tool_tip="Прослушать этот звук."/>
<button name="Def_UISndMicToggle" tool_tip="Сброс к UUID по умолчанию."/>
<check_box name="PlayModeUISndMicToggle" label="Воспроизведить этот звук"/>
<text tool_tip="UUID звука воспроизводимый, когда происходит перезагрузка региона." name="textFSRestart">
Перезагрузка региона:
</text>

View File

@ -14,7 +14,7 @@
Ögeler:
</text>
<layout_stack name="top_stack">
<layout_panel name="filter_layout_panel">
<layout_panel name="filter_panel">
<combo_box name="search_type">
<item label="Ad" name="Name" value="search_by_name"/>
<item label="Oluşturan" name="Creator" value="search_by_creator"/>

View File

@ -14,7 +14,7 @@
物品:
</text>
<layout_stack name="top_stack">
<layout_panel name="filter_layout_panel">
<layout_panel name="filter_panel">
<combo_box name="search_type">
<item label="名稱" name="Name" value="search_by_name"/>
<item label="創造者" name="Creator" value="search_by_creator"/>

View File

@ -179,7 +179,7 @@
<combo_box.item value="filter_type_sounds" label="Sounds" />
<combo_box.item value="filter_type_textures" label="Textures" />
<combo_box.item value="filter_type_snapshots" label="Snapshots" />
<combo_box.item value="filter_type_meshes" label="Meshes" />
<combo_box.item value="filter_type_materials" label="Materials" />
<combo_box.item value="filter_type_settings" label="Settings" />
<combo_box.item value="filter_separator" label="------------" enabled="false" />
<combo_box.item value="filter_type_custom" label="Custom..." />

View File

@ -181,7 +181,7 @@
<combo_box.item value="filter_type_sounds" label="Sounds" />
<combo_box.item value="filter_type_textures" label="Textures" />
<combo_box.item value="filter_type_snapshots" label="Snapshots" />
<combo_box.item value="filter_type_meshes" label="Meshes" />
<combo_box.item value="filter_type_materials" label="Materials" />
<combo_box.item value="filter_type_settings" label="Settings" />
<combo_box.item value="filter_separator" label="------------" enabled="false" />
<combo_box.item value="filter_type_custom" label="Custom..." />

View File

@ -102,7 +102,6 @@
<combo_box.item value="filter_type_sounds" label="Sounds" />
<combo_box.item value="filter_type_textures" label="Texturen" />
<combo_box.item value="filter_type_snapshots" label="Fotos" />
<combo_box.item value="filter_type_meshes" label="Meshes" />
<combo_box.item value="filter_type_settings" label="Einstellungen" />
<combo_box.item value="filter_separator" label="------------" />
<combo_box.item value="filter_type_custom" label="Benutzerdefiniert..." />

View File

@ -784,7 +784,7 @@
<combo_box.item value="filter_type_sounds" label="Sounds" />
<combo_box.item value="filter_type_textures" label="Textures" />
<combo_box.item value="filter_type_snapshots" label="Snapshots" />
<combo_box.item value="filter_type_meshes" label="Meshes" />
<combo_box.item value="filter_type_materials" label="Materials" />
<combo_box.item value="filter_type_settings" label="Settings" />
<combo_box.item value="filter_separator" label="------------" enabled="false" />
<combo_box.item value="filter_type_custom" label="Custom..." />

View File

@ -82,7 +82,6 @@
<combo_box.item value="filter_type_sounds" label="Sonidos"/>
<combo_box.item value="filter_type_textures" label="Texturas"/>
<combo_box.item value="filter_type_snapshots" label="Fotos"/>
<combo_box.item value="filter_type_meshes" label="Modelos mesh"/>
<combo_box.item value="filter_type_custom" label="Personalizar..."/>
</combo_box>
<panel name="default_inventory_panel">

View File

@ -93,7 +93,6 @@
<combo_box.item value="filter_type_sounds" label="Sons" />
<combo_box.item value="filter_type_textures" label="Textures" />
<combo_box.item value="filter_type_snapshots" label="Photos" />
<combo_box.item value="filter_type_meshes" label="Meshes" />
<combo_box.item value="filter_type_settings" label="Environnements" />
<combo_box.item value="filter_type_custom" label="Filtres personnalisés..." />
</combo_box>

View File

@ -143,7 +143,6 @@
<combo_box.item value="filter_type_sounds" label="Suoni" />
<combo_box.item value="filter_type_textures" label="Texture" />
<combo_box.item value="filter_type_snapshots" label="Foto" />
<combo_box.item value="filter_type_meshes" label="Mesh" />
<combo_box.item value="filter_separator" label="------------" enabled="false" />
<combo_box.item value="filter_type_custom" label="Personalizzato..." />
</combo_box>

View File

@ -104,7 +104,6 @@
<combo_box.item value="filter_type_sounds" label="サウンド" />
<combo_box.item value="filter_type_textures" label="テクスチャ" />
<combo_box.item value="filter_type_snapshots" label="スナップショット" />
<combo_box.item value="filter_type_meshes" label="メッシュ" />
<combo_box.item value="filter_type_settings" label="自然環境設定" />
<combo_box.item value="filter_type_custom" label="カスタマイズ..." />
</combo_box>

View File

@ -114,7 +114,6 @@
<combo_box.item value="filter_type_sounds" label="Dźwięki" />
<combo_box.item value="filter_type_textures" label="Tekstury" />
<combo_box.item value="filter_type_snapshots" label="Zdjęcia" />
<combo_box.item value="filter_type_meshes" label="Mesze" />
<combo_box.item value="filter_type_settings" label="Otoczenia" />
<combo_box.item value="filter_type_custom" label="Własny filtr..." />
</combo_box>

View File

@ -94,7 +94,6 @@
<combo_box.item value="filter_type_sounds" label="Звуки" />
<combo_box.item value="filter_type_textures" label="Текстуры" />
<combo_box.item value="filter_type_snapshots" label="Снимки" />
<combo_box.item value="filter_type_meshes" label="Меш" />
<combo_box.item value="filter_type_settings" label="Настройки" />
<combo_box.item value="filter_type_custom" label="Другое..." />
</combo_box>

View File

@ -37,7 +37,6 @@
// STL headers
#include <chrono>
// boost headers
#include "fix_macros.h"
#include <boost/filesystem.hpp>
@ -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();

View File

@ -71,6 +71,7 @@ class LLLocalMeshFace
std::vector<LLVector2>& getUVs() { return mUVs; };
std::vector<LLLocalMeshSkinUnit>& getSkin() { return mSkin; }
std::pair<LLVector4, LLVector4>& getFaceBoundingBox() { return mFaceBoundingBox; }
void logFaceInfo() const;
private:
std::vector<int> mIndices;
@ -115,6 +116,7 @@ class LLLocalMeshObject
void setObjectMeshSkinInfo(LLPointer<LLMeshSkinInfo> 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<LLLocalMeshSystem>
void triggerFloaterRefresh( bool keep_selection=true );
std::vector<LLLocalMeshFile::LLLocalMeshFileInfo> getFileInfoVector() const;
std::vector<std::string> getFileLog(LLUUID local_file_id) const;
// misc
void pushLog(const std::string& who, const std::string& what, bool is_error = false);
private:
std::vector<std::string> mSystemLog;
std::vector<std::unique_ptr<LLLocalMeshFile>> mLoadedFileList;
bool mFileAsyncsOngoing;
LLFloaterLocalMesh* mFloaterPtr;

View File

@ -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<bool>("FSLocalMeshScaleAlwaysMeters", false);
scene_transform_base.setIdentity();
if(!always_use_meter_scale)
{
domAsset::domUnit* unit = daeSafeCast<domAsset::domUnit>(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<domAsset::domUp_axis>(collada_document_root->getDescendant(daeElement::matchType(domAsset::domUp_axis::ID())));
daeSafeCast<domAsset::domUp_axis>(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<domMesh*> 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<std::string> 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<LLLocalMeshObject>& current_object)
@ -488,6 +519,7 @@ bool LLLocalMeshImportDAE::processSkin(daeDatabase* collada_db, daeElement* coll
LLPointer<LLMeshSkinInfo> 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<std::string> 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<domInstance_controller::domSkeleton*> 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(&current_element, skeleton_iterator, 0, "skeleton");
daeElement* current_skeleton_root = nullptr;
collada_db->getElement(&current_element, skeleton_index, 0, "skeleton");
auto current_skeleton = daeSafeCast<domInstance_controller::domSkeleton>(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<domNode>();
for (size_t skeleton_node_iterator = 0; skeleton_node_iterator < skeleton_nodes.getCount(); ++skeleton_node_iterator)
{
auto current_node = daeSafeCast<domNode>(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<domNode>(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<domNode>(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<domNode>( 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<domSource>(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<LLVector4> transformed_positions;
std::vector<LLVector4> 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<domSource>(vertex_input_array[vertex_input_iterator]->getSource().getElement());
auto pos_source = daeSafeCast<domSource>(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<domSource>(weight_inputs[weight_input_iter]->getSource().getElement());
if (!weights_source)
auto weights_source = daeSafeCast<domSource>(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<LLVector4, std::vector<LLModel::JointWeight> > 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<std::string, std::string>& joint_map, std::map<std::string, LLMatrix4>& joint_transforms)
bool LLLocalMeshImportDAE::processSkeletonJoint(domNode* current_node, std::map<std::string, std::string>& joint_map, std::map<std::string, LLMatrix4>& 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<domTranslate>(jointResolver_translation.getElement());
if (!current_transformation)
{
daeSIDResolver jointResolver_location(current_node, "./location");
current_transformation = daeSafeCast<domTranslate>(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<domTranslate>(jointResolver_translation.getElement());
if (current_transformation)
{
current_transformation = daeSafeCast<domTranslate>(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<domMatrix>(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<domTranslate>(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<domTranslate>(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<domNode>(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<domMatrix>(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<domMatrix>(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<domNode>(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)
//{
/*

View File

@ -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<LLLocalMeshObject>& current_object);
void processSkeletonJoint(domNode* current_node, std::map<std::string, std::string>& joint_map, std::map<std::string, LLMatrix4>& joint_transforms);
bool processSkeletonJoint(domNode* current_node, std::map<std::string, std::string>& joint_map, std::map<std::string, LLMatrix4>& 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;

View File

@ -1,3 +1,3 @@
llbase==1.2.11
autobuild==3.9.1
llsd==1.2.1
llbase
autobuild
llsd

View File

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