# Conflicts:
#	.github/workflows/build.yaml
#	indra/newview/llappdelegate-objc.mm
#	indra/newview/llappviewer.cpp
#	indra/newview/llconversationlog.cpp
#	indra/newview/llconversationloglistitem.cpp
#	indra/newview/llpanelprofile.cpp
#	indra/newview/llpanelprofile.h
#	indra/newview/llspeakers.cpp
#	indra/newview/llviewercontrol.cpp
#	indra/newview/pipeline.cpp
#	indra/newview/skins/default/xui/en/menu_viewer.xml
#	indra/newview/viewer_manifest.py
This commit is contained in:
Ansariel
2025-11-22 13:07:03 +01:00
61 changed files with 525 additions and 258 deletions
+23 -17
View File
@@ -362,8 +362,9 @@ jobs:
post-windows-symbols:
env:
BUGSPLAT_USER: ${{ secrets.BUGSPLAT_USER }}
BUGSPLAT_PASS: ${{ secrets.BUGSPLAT_PASS }}
BUGSPLAT_DATABASE: "${{ secrets.BUGSPLAT_DATABASE }}"
SYMBOL_UPLOAD_CLIENT_ID: "${{ secrets.BUGSPLAT_SYMBOL_UPLOAD_CLIENT_ID }}"
SYMBOL_UPLOAD_CLIENT_SECRET: "${{ secrets.BUGSPLAT_SYMBOL_UPLOAD_CLIENT_SECRET }}"
needs: build
if: needs.build.outputs.configuration == 'Release'
runs-on: ubuntu-latest
@@ -374,51 +375,56 @@ jobs:
name: Windows-app
path: _artifacts
- name: Download Windows Symbols
if: env.BUGSPLAT_USER && env.BUGSPLAT_PASS
if: env.BUGSPLAT_DATABASE && env.SYMBOL_UPLOAD_CLIENT_ID
uses: actions/download-artifact@v5
with:
name: Windows-symbols
- name: Extract viewer pdb
if: env.BUGSPLAT_USER && env.BUGSPLAT_PASS
if: env.BUGSPLAT_DATABASE && env.SYMBOL_UPLOAD_CLIENT_ID
shell: bash
run: |
tar -xJf "${{ needs.build.outputs.viewer_channel }}.sym.tar.xz" -C _artifacts
- name: Post Windows symbols
if: env.BUGSPLAT_USER && env.BUGSPLAT_PASS
uses: secondlife-3p/symbol-upload@v10
if: env.BUGSPLAT_DATABASE && env.SYMBOL_UPLOAD_CLIENT_ID
uses: BugSplat-Git/symbol-upload@095d163ae9ceb006d286a731dcd35cf6a1b458c8
with:
username: ${{ env.BUGSPLAT_USER }}
password: ${{ env.BUGSPLAT_PASS }}
database: "SecondLife_Viewer_2018"
clientId: "${{ env.SYMBOL_UPLOAD_CLIENT_ID }}"
clientSecret: "${{ env.SYMBOL_UPLOAD_CLIENT_SECRET }}"
database: "${{ env.BUGSPLAT_DATABASE }}"
application: ${{ needs.build.outputs.viewer_channel }}
version: ${{ needs.build.outputs.viewer_version }}
directory: _artifacts
files: "**/{SecondLifeViewer.exe,llwebrtc.dll,*.pdb}"
node-version: "22"
dumpSyms: false
post-mac-symbols:
env:
BUGSPLAT_USER: ${{ secrets.BUGSPLAT_USER }}
BUGSPLAT_PASS: ${{ secrets.BUGSPLAT_PASS }}
BUGSPLAT_DATABASE: "${{ secrets.BUGSPLAT_DATABASE }}"
SYMBOL_UPLOAD_CLIENT_ID: "${{ secrets.BUGSPLAT_SYMBOL_UPLOAD_CLIENT_ID }}"
SYMBOL_UPLOAD_CLIENT_SECRET: "${{ secrets.BUGSPLAT_SYMBOL_UPLOAD_CLIENT_SECRET }}"
needs: build
if: needs.build.outputs.configuration == 'Release'
runs-on: ubuntu-latest
steps:
- name: Download Mac Symbols
if: env.BUGSPLAT_USER && env.BUGSPLAT_PASS
if: env.BUGSPLAT_DATABASE && env.SYMBOL_UPLOAD_CLIENT_ID
uses: actions/download-artifact@v5
with:
name: macOS-symbols
- name: Post Mac symbols
if: env.BUGSPLAT_USER && env.BUGSPLAT_PASS
uses: secondlife-3p/symbol-upload@v10
if: env.BUGSPLAT_DATABASE && env.SYMBOL_UPLOAD_CLIENT_ID
uses: BugSplat-Git/symbol-upload@095d163ae9ceb006d286a731dcd35cf6a1b458c8
with:
username: ${{ env.BUGSPLAT_USER }}
password: ${{ env.BUGSPLAT_PASS }}
database: "SecondLife_Viewer_2018"
clientId: "${{ env.SYMBOL_UPLOAD_CLIENT_ID }}"
clientSecret: "${{ env.SYMBOL_UPLOAD_CLIENT_SECRET }}"
database: "${{ env.BUGSPLAT_DATABASE }}"
application: ${{ needs.build.outputs.viewer_channel }}
version: ${{ needs.build.outputs.viewer_version }} (${{ needs.build.outputs.viewer_version }})
directory: .
files: "**/*.xcarchive.zip"
node-version: "22"
dumpSyms: false
release:
needs: [setup, build, sign-and-package-windows, sign-and-package-mac]
+4 -4
View File
@@ -468,11 +468,11 @@
<key>archive</key>
<map>
<key>hash</key>
<string>cd1f1d55a2488657ec2253774b3a414621f81b24</string>
<string>9bcafdd7e1df6b92096fa850627d4f3437630d4a</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
<string>https://github.com/secondlife/3p-bugsplat/releases/download/v1.1.5-71fc41e/bugsplat-1.1.1-9599607655-darwin64-9599607655.tar.zst</string>
<string>https://github.com/secondlife/3p-bugsplat/releases/download/v1.2.6-a475cbb/bugsplat-1.2.6-19430122611-darwin64-19430122611.tar.zst</string>
</map>
<key>name</key>
<string>darwin64</string>
@@ -482,11 +482,11 @@
<key>archive</key>
<map>
<key>hash</key>
<string>9fb0615d17988bd89a2e5ae6d4d19e150afb54a9</string>
<string>4e9f0c1cdbc1cebf6185ecc45228ced7f9af1532</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
<string>https://github.com/secondlife/3p-bugsplat/releases/download/v1.1.5-71fc41e/bugsplat-5.0.1.0-9599607655-windows64-9599607655.tar.zst</string>
<string>https://github.com/secondlife/3p-bugsplat/releases/download/v1.2.6-a475cbb/bugsplat-6.1.1.0-19430122611-windows64-19430122611.tar.zst</string>
</map>
<key>name</key>
<string>windows64</string>
+6
View File
@@ -23,8 +23,14 @@ if (USE_BUGSPLAT)
elseif (DARWIN)
find_library(BUGSPLAT_LIBRARIES BugsplatMac REQUIRED
NO_DEFAULT_PATH PATHS "${ARCH_PREBUILT_DIRS_RELEASE}")
find_library(CRASHREPORTED_LIBRARIES CrashReporter REQUIRED
NO_DEFAULT_PATH PATHS "${ARCH_PREBUILT_DIRS_RELEASE}")
find_library(HOCKEYSDK_LIBRARIES HockeySDK REQUIRED
NO_DEFAULT_PATH PATHS "${ARCH_PREBUILT_DIRS_RELEASE}")
target_link_libraries( ll::bugsplat INTERFACE
${BUGSPLAT_LIBRARIES}
${CRASHREPORTED_LIBRARIES}
${HOCKEYSDK_LIBRARIES}
)
else (WINDOWS) #ie: Linux...
add_compile_definitions(__STDC_FORMAT_MACROS)
+2 -1
View File
@@ -457,7 +457,8 @@ public:
("slot", LLSD::Integer(mIndex))
("name", whichfile(mIndex))
("desc", mDesc)
("eof", state == CLOSED));
("eof", state == CLOSED)
("exhst", state == EXHAUSTED));
}
return false;
+1 -26
View File
@@ -739,32 +739,7 @@ private:
}
}
// *NOTE:Mani - I didn't find any docs that assure me that machdep.cpu.feature_bits will always be
// The feature bits I think it is. Here's a test:
#ifndef LL_RELEASE_FOR_DOWNLOAD
#if defined(__i386__) && defined(__PIC__)
/* %ebx may be the PIC register. */
#define __cpuid(level, a, b, c, d) \
__asm__ ("xchgl\t%%ebx, %1\n\t" \
"cpuid\n\t" \
"xchgl\t%%ebx, %1\n\t" \
: "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
: "0" (level))
#else
#define __cpuid(level, a, b, c, d) \
__asm__ ("cpuid\n\t" \
: "=a" (a), "=b" (b), "=c" (c), "=d" (d) \
: "0" (level))
#endif
unsigned int eax, ebx, ecx, edx;
__cpuid(0x1, eax, ebx, ecx, edx);
if(feature_infos[0] != (S32)edx)
{
LL_WARNS() << "machdep.cpu.feature_bits doesn't match expected cpuid result!" << LL_ENDL;
}
#endif // LL_RELEASE_FOR_DOWNLOAD
// @TODO: Audit our usage of machdep.cpu.feature_bits.
uint64_t ext_feature_info = getSysctlInt64("machdep.cpu.extfeature_bits");
S32 *ext_feature_infos = (S32*)(&ext_feature_info);
+2 -2
View File
@@ -1207,8 +1207,8 @@ namespace tut
{
set_test_name("ReadPipe \"eof\" event");
PythonProcessLauncher py(get_test_name(),
"from __future__ import print_function\n"
"print('Hello from Python!')\n");
"import time\n"
"time.sleep(1.5)\n");
py.mParams.files.add(LLProcess::FileParam()); // stdin
py.mParams.files.add(LLProcess::FileParam("pipe")); // stdout
py.launch();
+13 -2
View File
@@ -517,7 +517,7 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev
{ //search from the current gpu class down to class 1 to find the most relevant shader
std::stringstream fname;
fname << getShaderDirPrefix();
fname << gpu_class << "/" << filename;
fname << gpu_class << gDirUtilp->getDirDelimiter() << filename;
open_file_name = fname.str();
@@ -546,7 +546,14 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev
if (file == NULL)
{
LL_WARNS("ShaderLoading") << "GLSL Shader file not found: " << open_file_name << LL_ENDL;
if (gDirUtilp->fileExists(open_file_name))
{
LL_WARNS("ShaderLoading") << "GLSL Shader file failed to open: " << open_file_name << LL_ENDL;
}
else
{
LL_WARNS("ShaderLoading") << "GLSL Shader file not found: " << open_file_name << LL_ENDL;
}
return 0;
}
@@ -863,6 +870,7 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev
//load source
if (ret)
{
LL_DEBUGS("ShaderLoading") << "glCreateShader done" << LL_ENDL;
glShaderSource(ret, shader_code_count, (const GLchar**)shader_code_text, NULL);
error = glGetError();
@@ -877,6 +885,7 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev
//compile source
if (ret)
{
LL_DEBUGS("ShaderLoading") << "glShaderSource done" << U32(ret) << LL_ENDL;
glCompileShader(ret);
error = glGetError();
@@ -891,6 +900,7 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev
if (error == GL_NO_ERROR)
{
//check for errors
LL_DEBUGS("ShaderLoading") << "glCompileShader done" << U32(ret) << LL_ENDL;
GLint success = GL_TRUE;
glGetShaderiv(ret, GL_COMPILE_STATUS, &success);
@@ -907,6 +917,7 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev
}
else
{
LL_DEBUGS("ShaderLoading") << "loadShaderFile() completed, ret: " << U32(ret) << LL_ENDL;
ret = 0;
}
stop_glerror();
+6 -1
View File
@@ -3830,7 +3830,6 @@ S32 LLTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offs
void LLTextSegment::updateLayout(const LLTextBase& editor) {}
F32 LLTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect) { return draw_rect.mLeft; }
bool LLTextSegment::canEdit() const { return false; }
bool LLTextSegment::getPermitsEmoji() const { return true; }
void LLTextSegment::unlinkFromDocument(LLTextBase*) {}
void LLTextSegment::linkToDocument(LLTextBase*) {}
const LLUIColor& LLTextSegment::getColor() const { static const LLUIColor white = LLUIColorTable::instance().getColor("White", LLColor4::white); return white; }
@@ -3874,6 +3873,11 @@ LLNormalTextSegment::LLNormalTextSegment( LLStyleConstSP style, S32 start, S32 e
{
mFontHeight = mStyle->getFont()->getLineHeight();
mCanEdit = !mStyle->getDrawHighlightBg();
if (!mCanEdit)
{
// Emoji shouldn't split the segment with the mention.
mPermitsEmoji = false;
}
LLUIImagePtr image = mStyle->getImage();
if (image.notNull())
@@ -4407,6 +4411,7 @@ LLInlineViewSegment::LLInlineViewSegment(const Params& p, S32 start, S32 end)
mTopPad(p.top_pad),
mBottomPad(p.bottom_pad)
{
mPermitsEmoji = false;
}
LLInlineViewSegment::~LLInlineViewSegment()
+5 -3
View File
@@ -61,13 +61,15 @@ class LLTextSegment
public:
LLTextSegment(S32 start, S32 end)
: mStart(start),
mEnd(end)
mEnd(end),
mPermitsEmoji(true)
{}
virtual ~LLTextSegment();
virtual LLTextSegmentPtr clone(LLTextBase& terget) const { return new LLTextSegment(mStart, mEnd); }
static LLStyleSP cloneStyle(LLTextBase& target, const LLStyle* source);
bool getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const;
bool getPermitsEmoji() const { return mPermitsEmoji; };
virtual bool getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const;
virtual S32 getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const;
@@ -87,7 +89,6 @@ public:
virtual void updateLayout(const class LLTextBase& editor);
virtual F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect);
virtual bool canEdit() const;
virtual bool getPermitsEmoji() const;
virtual void unlinkFromDocument(class LLTextBase* editor);
virtual void linkToDocument(class LLTextBase* editor);
@@ -126,6 +127,8 @@ public:
protected:
S32 mStart;
S32 mEnd;
bool mPermitsEmoji;
};
class LLNormalTextSegment : public LLTextSegment
@@ -256,7 +259,6 @@ public:
/*virtual*/ void updateLayout(const class LLTextBase& editor);
/*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect);
/*virtual*/ bool canEdit() const { return false; }
/*virtual*/ bool getPermitsEmoji() const { return false; }
/*virtual*/ void unlinkFromDocument(class LLTextBase* editor);
/*virtual*/ void linkToDocument(class LLTextBase* editor);
+9 -6
View File
@@ -100,16 +100,19 @@ void LLUICtrlFactory::loadWidgetTemplate(const std::string& widget_tag, LLInitPa
std::string base_filename = search_paths.front();
if (!base_filename.empty())
{
LLUICtrlFactory::instance().pushFileName(base_filename);
LLUICtrlFactory *factory = LLUICtrlFactory::getInstance();
factory->mFileNames.push_back(base_filename);
if (!LLXMLNode::getLayeredXMLNode(root_node, search_paths))
if (LLXMLNode::getLayeredXMLNode(root_node, search_paths))
{
LLXUIParser parser;
parser.readXUI(root_node, block, base_filename);
}
else
{
LL_WARNS() << "Couldn't parse widget from: " << base_filename << LL_ENDL;
return;
}
LLXUIParser parser;
parser.readXUI(root_node, block, base_filename);
LLUICtrlFactory::instance().popFileName();
factory->mFileNames.pop_back();
}
}
+7 -4
View File
@@ -919,14 +919,17 @@ bool LLWebRTCPeerConnectionImpl::initializeConnection(const LLWebRTCPeerConnecti
config.set_max_port(60100);
webrtc::PeerConnectionDependencies pc_dependencies(this);
if (mPeerConnectionFactory == nullptr)
// Other thread manages mPeerConnectionFactory's lifetime and it can be reset
// at any momment, create own scoped_refptr (atomic).
webrtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> peer_connection_factory = mPeerConnectionFactory;
if (peer_connection_factory == nullptr)
{
RTC_LOG(LS_ERROR) << __FUNCTION__ << "Error creating peer connection, factory doesn't exist";
// Too early?
mPendingJobs--;
return;
}
auto error_or_peer_connection = mPeerConnectionFactory->CreatePeerConnectionOrError(config, std::move(pc_dependencies));
auto error_or_peer_connection = peer_connection_factory->CreatePeerConnectionOrError(config, std::move(pc_dependencies));
if (error_or_peer_connection.ok())
{
mPeerConnection = std::move(error_or_peer_connection.value());
@@ -959,10 +962,10 @@ bool LLWebRTCPeerConnectionImpl::initializeConnection(const LLWebRTCPeerConnecti
audioOptions.noise_suppression = true;
audioOptions.init_recording_on_send = false;
mLocalStream = mPeerConnectionFactory->CreateLocalMediaStream("SLStream");
mLocalStream = peer_connection_factory->CreateLocalMediaStream("SLStream");
webrtc::scoped_refptr<webrtc::AudioTrackInterface> audio_track(
mPeerConnectionFactory->CreateAudioTrack("SLAudio", mPeerConnectionFactory->CreateAudioSource(audioOptions).get()));
peer_connection_factory->CreateAudioTrack("SLAudio", peer_connection_factory->CreateAudioSource(audioOptions).get()));
audio_track->set_enabled(false);
mLocalStream->AddTrack(audio_track);
+6 -5
View File
@@ -36,16 +36,17 @@
std::string secondLogPath;
}
@property (assign) IBOutlet LLNSWindow *window;
@property (assign) IBOutlet NSWindow *inputWindow;
@property (assign) IBOutlet LLNonInlineTextView *inputView;
@property (assign) IBOutlet LLNSWindow * _Nullable window;
@property (assign) IBOutlet NSWindow * _Nullable inputWindow;
@property (assign) IBOutlet LLNonInlineTextView * _Nullable inputView;
@property (retain) NSString *currentInputLanguage;
@property (retain) NSString * _Nullable currentInputLanguage;
- (void) oneFrame;
- (void) showInputWindow:(bool)show withEvent:(NSEvent*)textEvent;
- (void) showInputWindow:(bool)show withEvent:(nullable NSEvent *)textEvent;
- (void) languageUpdated;
- (bool) romanScript;
- (void) setBugsplatValue:(nullable NSString *)value forAttribute:(nullable NSString *)attribute;
@end
@interface LLApplication : NSApplication
+8 -11
View File
@@ -2594,16 +2594,13 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
// Comes after WM_QUERYENDSESSION
LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_ENDSESSION");
LL_INFOS("Window") << "Received WM_ENDSESSION with wParam: " << (U32)w_param << " lParam: " << (U32)l_param << LL_ENDL;
unsigned int end_session_flags = (U32)w_param;
if (end_session_flags == 0)
{
// session is not actually ending
return 0;
}
unsigned int end_session_flags = (U32)l_param;
if ((end_session_flags & ENDSESSION_CLOSEAPP)
|| (end_session_flags & ENDSESSION_CRITICAL)
|| (end_session_flags & ENDSESSION_LOGOFF))
if (w_param == TRUE // if true, session is ending
|| end_session_flags == 0 // not possible to determine type of the event
// || (end_session_flags & ENDSESSION_CLOSEAPP)) system update or low resources, must be acompanied by w_param == TRUE
|| (end_session_flags & ENDSESSION_CRITICAL) // will shutdown regardless of app state
|| (end_session_flags & ENDSESSION_LOGOFF)) // logoff, can delay shutdown
{
window_imp->post([=]()
{
@@ -2612,13 +2609,13 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
{
// Get the app to initiate cleanup.
window_imp->mCallbacks->handleQuit(window_imp);
// The app is responsible for calling destroyWindow when done with GL
}
});
// Give app a second to finish up. That's not enough for a clean exit,
// but better than nothing.
// Todo: sync this better, some kind of waitForResult? Can't wait forever,
// but can potentially use ShutdownBlockReasonCreate for a bigger delay.
// but for ENDSESSION_LOGOFF can potentially use ShutdownBlockReasonCreate
// for a bigger delay.
ms_sleep(1000);
}
// Don't need to post quit or destroy window,
+1 -1
View File
@@ -10656,7 +10656,7 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>RenderAvatarCloth</key>
<map>
<key>Comment</key>
<string>DEPRECATED - only false supported - Controls if avatars use wavy cloth</string>
<string>Controls if system avatar clothes use wavy cloth</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -28,6 +28,9 @@ uniform mat4 projection_matrix;
in vec3 position;
in vec3 normal;
in vec2 texcoord0;
#ifdef AVATAR_CLOTH
in vec4 clothing;
#endif
mat4 getSkinnedTransform();
@@ -37,6 +40,15 @@ out vec3 vary_normal;
out vec2 vary_texcoord0;
out vec3 vary_position;
#ifdef AVATAR_CLOTH
uniform vec4 gWindDir;
uniform vec4 gSinWaveParams;
uniform vec4 gGravity;
const vec4 gMinMaxConstants = vec4(1.0, 0.166666, 0.0083143, .00018542); // #minimax-generated coefficients
const vec4 gPiConstants = vec4(0.159154943, 6.28318530, 3.141592653, 1.5707963); // # {1/2PI, 2PI, PI, PI/2}
#endif
void main()
{
vary_texcoord0 = texcoord0;
@@ -46,16 +58,78 @@ void main()
vec4 pos_in = vec4(position.xyz, 1.0);
mat4 trans = getSkinnedTransform();
pos.x = dot(trans[0], pos_in);
pos.y = dot(trans[1], pos_in);
pos.z = dot(trans[2], pos_in);
pos.w = 1.0;
norm.x = dot(trans[0].xyz, normal);
norm.y = dot(trans[1].xyz, normal);
norm.z = dot(trans[2].xyz, normal);
norm = normalize(norm);
#ifdef AVATAR_CLOTH
//wind
vec4 windEffect;
windEffect = vec4(dot(norm, gWindDir.xyz));
pos.x = dot(trans[2], pos_in);
windEffect.xyz = pos.x * vec3(0.015, 0.015, 0.015)
+ windEffect.xyz;
windEffect.w = windEffect.w * 2.0 + 1.0; // move wind offset value to [-1, 3]
windEffect.w = windEffect.w*gWindDir.w; // modulate wind strength
windEffect.xyz = windEffect.xyz*gSinWaveParams.xyz
+vec3(gSinWaveParams.w); // use sin wave params to scale and offset input
//reduce to period of 2 PI
vec4 temp1, temp0, temp2, offsetPos;
temp1.xyz = windEffect.xyz * gPiConstants.x; // change input as multiple of [0-2PI] to [0-1]
temp0.y = mod(temp1.x,1.0);
windEffect.x = temp0.y * gPiConstants.y; // scale from [0,1] to [0, 2PI]
temp1.z = temp1.z - gPiConstants.w; // shift normal oscillation by PI/2
temp0.y = mod(temp1.z,1.0);
windEffect.z = temp0.y * gPiConstants.y; // scale from [0,1] to [0, 2PI]
windEffect.xyz = windEffect.xyz + vec3(-3.141592); // offset to [-PI, PI]
//calculate sinusoid
vec4 sinWave;
temp1 = windEffect*windEffect;
sinWave = -temp1 * gMinMaxConstants.w
+ vec4(gMinMaxConstants.z); // y = -(x^2)/7! + 1/5!
sinWave = sinWave * -temp1 + vec4(gMinMaxConstants.y); // y = -(x^2) * (-(x^2)/7! + 1/5!) + 1/3!
sinWave = sinWave * -temp1 + vec4(gMinMaxConstants.x); // y = -(x^2) * (-(x^2) * (-(x^2)/7! + 1/5!) + 1/3!) + 1
sinWave = sinWave * windEffect; // y = x * (-(x^2) * (-(x^2) * (-(x^2)/7! + 1/5!) + 1/3!) + 1)
// sinWave.x holds sin(norm . wind_direction) with primary frequency
// sinWave.y holds sin(norm . wind_direction) with secondary frequency
// sinWave.z hold cos(norm . wind_direction) with primary frequency
sinWave.xyz = sinWave.xyz * gWindDir.w
+ vec3(windEffect.w); // multiply by wind strength in gWindDir.w [-wind, wind]
// add normal facing bias offset [-wind,wind] -> [-wind - .25, wind + 1]
temp1 = vec4(dot(norm, gGravity.xyz)); // how much is this normal facing in direction of gGravity?
temp1 = min(temp1, vec4(0.2,0.0,0.0,0.0)); // clamp [-1, 1] to [-1, 0.2]
temp1 = temp1*vec4(1.5,0.0,0.0,0.0); // scale from [-1,0.2] to [-1.5, 0.3]
sinWave.x = sinWave.x + temp1.x; // add gGravity effect to sinwave (only primary frequency)
sinWave.xyz = sinWave.xyz * clothing.w; // modulate by clothing coverage
sinWave.xyz = max(sinWave.xyz, vec3(-1.0, -1.0, -1.0)); // clamp to underlying body shape
offsetPos = clothing * sinWave.x; // multiply wind effect times clothing displacement
temp2 = gWindDir*sinWave.z + vec4(norm,0); // calculate normal offset due to wind oscillation
offsetPos = vec4(1.0,1.0,1.0,0.0)*offsetPos+pos_in; // add to offset vertex position, and zero out effect from w
norm += temp2.xyz*2.0; // add sin wave effect on normals (exaggerated)
//renormalize normal (again)
norm = normalize(norm);
pos.x = dot(trans[0], offsetPos);
pos.y = dot(trans[1], offsetPos);
pos.z = dot(trans[2], offsetPos);
pos.w = 1.0;
#else
pos.x = dot(trans[0], pos_in);
pos.y = dot(trans[1], pos_in);
pos.z = dot(trans[2], pos_in);
pos.w = 1.0;
#endif
vary_normal = norm;
vary_position = pos.xyz;
+34 -1
View File
@@ -33,10 +33,11 @@
#include "../llviewertexturelist.h"
#include "../pipeline.h"
#include "buffer_util.h"
#include <boost/url.hpp>
#include "llimagejpeg.h"
#include "../llskinningutil.h"
#include <future>
using namespace LL::GLTF;
using namespace boost::json;
@@ -960,8 +961,40 @@ LLViewerFetchedTexture* fetch_texture(const LLUUID& id);
bool Image::prep(Asset& asset, bool loadIntoVRAM)
{
mLoadIntoTexturePipe = loadIntoVRAM;
LLUUID id;
if (mUri.size() == UUID_STR_SIZE && LLUUID::parseUUID(mUri, &id) && id.notNull())
{ // loaded from an asset, fetch the texture from the asset system
LL_DEBUGS("GLTF") << "Loading image from an id" << id<< LL_ENDL;
}
else if (mUri.find("data:") == 0)
{ // embedded in a data URI, load the texture from the URI
LL_WARNS("GLTF") << "Data URIs not yet supported" << LL_ENDL;
return false;
}
// Image::prepImpl containes code that must run on the main thread
std::promise<bool> prep_promise;
std::future<bool> prep_future = prep_promise.get_future();
LLAppViewer::instance()->postToMainCoro([this, &asset, id, &prep_promise]() mutable {
try {
bool result = prepImpl(asset, id);
prep_promise.set_value(result);
}
catch (...) {
// Propagate exception to the waiting thread
prep_promise.set_exception(std::current_exception());
}
});
// Block until prep is done on the main thread
return prep_future.get();
}
bool Image::prepImpl(Asset& asset, const LLUUID& id)
{
if (id.notNull())
{ // loaded from an asset, fetch the texture from the asset system
mTexture = fetch_texture(id);
}
+2
View File
@@ -320,6 +320,8 @@ namespace LL
void clearData(Asset& asset);
bool prep(Asset& asset, bool loadIntoVRAM);
private:
bool prepImpl(Asset& asset, const LLUUID& id);
};
// Render Batch -- vertex buffer and list of primitives to render using
+10 -3
View File
@@ -602,11 +602,12 @@ LLGLTFLoader::LLGLTFImportMaterial LLGLTFLoader::processMaterial(S32 material_in
if (material->mPbrMetallicRoughness.mBaseColorTexture.mIndex >= 0)
{
S32 texIndex = material->mPbrMetallicRoughness.mBaseColorTexture.mIndex;
std::string filename = processTexture(texIndex, "base_color", material->mName);
std::string full_path;
std::string filename = processTexture(full_path, texIndex, "base_color", material->mName);
if (!filename.empty())
{
impMat.mDiffuseMapFilename = filename;
impMat.mDiffuseMapFilename = full_path;
impMat.mDiffuseMapLabel = material->mName.empty() ? filename : material->mName;
// Check if the texture is already loaded
@@ -637,7 +638,7 @@ LLGLTFLoader::LLGLTFImportMaterial LLGLTFLoader::processMaterial(S32 material_in
return cachedMat;
}
std::string LLGLTFLoader::processTexture(S32 texture_index, const std::string& texture_type, const std::string& material_name)
std::string LLGLTFLoader::processTexture(std::string& full_path_out, S32 texture_index, const std::string& texture_type, const std::string& material_name)
{
S32 sourceIndex;
if (!validateTextureIndex(texture_index, sourceIndex))
@@ -661,6 +662,12 @@ std::string LLGLTFLoader::processTexture(S32 texture_index, const std::string& t
{
// Uri might be escaped
filename = LLURI::unescape(filename);
full_path = dir + gDirUtilp->getDirDelimiter() + filename;
}
if (gDirUtilp->fileExists(full_path))
{
full_path_out = full_path;
}
LL_INFOS("GLTF_IMPORT") << "Found texture: " << filename << " for material: " << material_name << LL_ENDL;
+1 -1
View File
@@ -149,7 +149,7 @@ private:
void processNodeHierarchy(S32 node_idx, std::map<std::string, S32>& mesh_name_counts, U32 submodel_limit, const LLVolumeParams& volume_params);
bool addJointToModelSkin(LLMeshSkinInfo& skin_info, S32 gltf_skin_idx, size_t gltf_joint_idx);
LLGLTFImportMaterial processMaterial(S32 material_index, S32 fallback_index);
std::string processTexture(S32 texture_index, const std::string& texture_type, const std::string& material_name);
std::string processTexture(std::string& full_path_out, S32 texture_index, const std::string& texture_type, const std::string& material_name);
bool validateTextureIndex(S32 texture_index, S32& source_index);
std::string generateMaterialName(S32 material_index, S32 fallback_index = -1);
bool populateModelFromMesh(LLModel* pModel, const std::string& base_name, const LL::GLTF::Mesh &mesh, const LL::GLTF::Node &node, material_map& mats);
+76 -57
View File
@@ -28,9 +28,11 @@
#if defined(LL_BUGSPLAT)
#include <boost/filesystem.hpp>
#include <vector>
@import BugsplatMac;
@import CrashReporter;
@import HockeySDK;
@import BugSplatMac;
// derived from BugsplatMac's BugsplatTester/AppDelegate.m
@interface LLAppDelegate () <BugsplatStartupManagerDelegate>
@interface LLAppDelegate () <BugSplatDelegate>
@end
#endif
#include "llwindowmacosx-objc.h"
@@ -68,13 +70,22 @@
#if defined(LL_BUGSPLAT)
infos("bugsplat setup");
// Engage BugsplatStartupManager *before* calling initViewer() to handle
// Engage BugSplat *before* calling initViewer() to handle
// any crashes during initialization.
// https://www.bugsplat.com/docs/platforms/os-x#initialization
[BugsplatStartupManager sharedManager].autoSubmitCrashReport = NO;
[BugsplatStartupManager sharedManager].askUserDetails = YES;
[BugsplatStartupManager sharedManager].delegate = self;
[[BugsplatStartupManager sharedManager] start];
// Initialize BugSplat
[[BugSplat shared] setDelegate:self];
[[BugSplat shared] setAutoSubmitCrashReport:NO];
[[BugSplat shared] setPersistUserDetails:NO];
[[BugSplat shared] setAskUserDetails:YES];
[BugSplat shared].expirationTimeInterval = 0;
[[BugSplat shared] start];
// Optionally, add some attributes to your crash reports.
// Attributes are artibrary key/value pairs that are searchable in the BugSplat dashboard.
// [[BugSplat shared] setValue:@"Value of Plain Attribute" forAttribute:@"PlainAttribute"];
#endif
infos("post-bugsplat setup");
@@ -213,9 +224,52 @@
return true;
}
- (void) setBugsplatValue:(nullable NSString *)value forAttribute:(NSString *)attribute
{
//[[BugSplat shared] setValue:@"Value of not so plain <value> Attribute" forAttribute:@"NotSoPlainAttribute"];
[[BugSplat shared] setValue:value forAttribute:attribute];
}
#if defined(LL_BUGSPLAT)
- (NSString *)applicationLogForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager
- (void)bugSplatWillSendCrashReport:(BugSplat *)bugSplat
{
infos("bugSplatWillSendCrashReport");
}
- (void)bugSplatWillSendCrashReportsAlways:(BugSplat *)bugSplat
{
infos("bugSplatWillSendCrashReportsAlways");
}
- (void)bugSplatDidFinishSendingCrashReport:(BugSplat *)bugSplat
{
infos("bugSplatDidFinishSendingCrashReport");
if(!secondLogPath.empty())
{
boost::filesystem::remove(secondLogPath);
}
clearDumpLogsDir();
}
- (void)bugSplatWillCancelSendingCrashReport:(BugSplat *)bugSplat
{
infos("bugSplatWillCancelSendingCrashReport");
}
- (void)bugSplatWillShowSubmitCrashReportAlert:(BugSplat *)bugSplat
{
infos("bugSplatWillShowSubmitCrashReportAlert");
}
- (void)bugSplat:(BugSplat *)bugSplat didFailWithError:(NSError *)error
{
std::string error_str([[error localizedDescription] UTF8String]);
infos("bugSplat:didFailWithError: " + error_str);
}
- (NSString *)applicationLogForBugSplat:(BugSplat *)bugSplat;
{
CrashMetadata& meta(CrashMetadata_instance());
// As of BugsplatMac 1.0.6, userName and userEmail properties are now
@@ -226,16 +280,21 @@
// report we are about to send.
infos("applicationLogForBugsplatStartupManager setting userName = '" +
meta.agentFullname + '"');
bugsplatStartupManager.userName =
bugSplat.userName =
[NSString stringWithCString:meta.agentFullname.c_str()
encoding:NSUTF8StringEncoding];
// Use the email field for OS version, just as we do on Windows, until
// BugSplat provides more metadata fields.
infos("applicationLogForBugsplatStartupManager setting userEmail = '" +
meta.OSInfo + '"');
bugsplatStartupManager.userEmail =
bugSplat.userEmail =
[NSString stringWithCString:meta.OSInfo.c_str()
encoding:NSUTF8StringEncoding];
//bugSplat.userID =
// [NSString stringWithCString:meta.regionName.c_str()
// encoding:NSUTF8StringEncoding];
// This strangely-named override method's return value contributes the
// User Description metadata field.
infos("applicationLogForBugsplatStartupManager -> '" + meta.fatalMessage + "'");
@@ -243,7 +302,8 @@
encoding:NSUTF8StringEncoding];
}
- (NSString *)applicationKeyForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager signal:(NSString *)signal exceptionName:(NSString *)exceptionName exceptionReason:(NSString *)exceptionReason {
- (NSString *)applicationKeyForBugSplat:(BugSplat *)bugSplat signal:(NSString *)signal exceptionName:(NSString *)exceptionName exceptionReason:(NSString *)exceptionReason
{
// TODO: exceptionName, exceptionReason
// Windows sends location within region as well, but that's because
@@ -258,27 +318,6 @@
encoding:NSUTF8StringEncoding];
}
- (NSString *)defaultUserNameForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager {
std::string agentFullname(CrashMetadata_instance().agentFullname);
infos("defaultUserNameForBugsplatStartupManager -> '" + agentFullname + "'");
return [NSString stringWithCString:agentFullname.c_str()
encoding:NSUTF8StringEncoding];
}
- (NSString *)defaultUserEmailForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager {
// Use the email field for OS version, just as we do on Windows, until
// BugSplat provides more metadata fields.
std::string OSInfo(CrashMetadata_instance().OSInfo);
infos("defaultUserEmailForBugsplatStartupManager -> '" + OSInfo + "'");
return [NSString stringWithCString:OSInfo.c_str()
encoding:NSUTF8StringEncoding];
}
- (void)bugsplatStartupManagerWillSendCrashReport:(BugsplatStartupManager *)bugsplatStartupManager
{
infos("bugsplatStartupManagerWillSendCrashReport");
}
struct AttachmentInfo
{
AttachmentInfo(const std::string& path, const std::string& type):
@@ -290,7 +329,7 @@ struct AttachmentInfo
std::string pathname, basename, mimetype;
};
- (NSArray<BugsplatAttachment *> *)attachmentsForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager
- (NSArray<BugSplatAttachment *> *)attachmentsForBugSplat:(BugSplat *)bugSplat
{
//const CrashMetadata& metadata(CrashMetadata_instance());
@@ -312,12 +351,12 @@ struct AttachmentInfo
// info.push_back(AttachmentInfo(secondLogPath, "text/xml"));
//}
// We "happen to know" that info[0].basename is "SecondLife.old" -- due to
// We "happen to know" that info[0].basename is "SecondLife.crash" -- due to
// the fact that BugsplatMac only notices a crash during the viewer run
// following the crash.
// The Bugsplat service doesn't respect the MIME type above when returning
// the log data to a browser, so take this opportunity to rename the file
// from <base>.old to <base>_log.txt
// from <base>.crash to <base>_log.txt
// info[0].basename =
// boost::filesystem::path(info[0].pathname).stem().string() + "_log.txt";
// infos("attachmentsForBugsplatStartupManager attaching log " + info[0].basename);
@@ -335,8 +374,8 @@ struct AttachmentInfo
encoding:NSUTF8StringEncoding];
NSData *nsdata = [NSData dataWithContentsOfFile:nspathname];
BugsplatAttachment *attachment =
[[BugsplatAttachment alloc] initWithFilename:nsbasename
BugSplatAttachment *attachment =
[[BugSplatAttachment alloc] initWithFilename:nsbasename
attachmentData:nsdata
contentType:nsmimetype];
@@ -347,26 +386,6 @@ struct AttachmentInfo
return attachments;
}
- (void)bugsplatStartupManagerDidFinishSendingCrashReport:(BugsplatStartupManager *)bugsplatStartupManager
{
infos("Sent crash report to BugSplat");
if(!secondLogPath.empty())
{
boost::filesystem::remove(secondLogPath);
}
clearDumpLogsDir();
}
- (void)bugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager didFailWithError:(NSError *)error
{
// TODO: message string from NSError
infos("Could not send crash report to BugSplat");
NSString *pStr = [NSString stringWithFormat:@"%@", error];
std::string bar = std::string([pStr UTF8String]);
infos(bar);
}
#endif // LL_BUGSPLAT
@end
+33 -10
View File
@@ -755,14 +755,12 @@ LLAppViewer::LLAppViewer()
// that touches files should really go through the lldir API
// <FS:ND> Init our custom directories, not from SecondLife
// gDirUtilp->initAppDirs("SecondLife");
#if ADDRESS_SIZE == 64
gDirUtilp->initAppDirs( APP_NAME + "_x64" );
gDirUtilp->initAppDirs(APP_NAME + "_x64");
#else
gDirUtilp->initAppDirs(APP_NAME);
#endif
// </FS:ND>
//
@@ -4378,13 +4376,18 @@ void LLAppViewer::writeSystemInfo()
if (! gDebugInfo.has("Dynamic") )
gDebugInfo["Dynamic"] = LLSD::emptyMap();
// <FS:ND> we don't want this (otherwise set filename to Firestorm.old/log
// #if LL_WINDOWS && !LL_BUGSPLAT
// gDebugInfo["SLLog"] = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,"SecondLife.log");
// #else
// //Not ideal but sufficient for good reporting.
// gDebugInfo["SLLog"] = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.old"); //LLError::logFileName();
// #endif
// <FS:ND> we don't want this (otherwise set filename to Firestorm.old/log)
//#if LL_DARWIN
// // crash processing in CrashMetadataSingleton reads SLLog
// gDebugInfo["SLLog"] = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.crash");
//#elif LL_WINDOWS && !LL_BUGSPLAT
// gDebugInfo["SLLog"] = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,"SecondLife.log");
//#else
// // Far from ideal, especially when multiple instances get involved.
// // Note that attachmentsForBugSplat expects .old extendion.
// // Todo: improve.
// gDebugInfo["SLLog"] = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.old"); //LLError::logFileName();
//#endif
// </FS:ND>
gDebugInfo["ClientInfo"]["Name"] = LLVersionInfo::instance().getChannel();
@@ -4817,6 +4820,24 @@ void LLAppViewer::processMarkerFiles()
}
LLAPRFile::remove(error_marker_file);
}
// <FS:Ansariel> Looks like we are not using this at all!?
//#if LL_DARWIN
// if (!mSecondInstance && gLastExecEvent != LAST_EXEC_NORMAL)
// {
// // While windows reports crashes immediately, mac reports next run and
// // may take a while to trigger crash report so it has a special file.
// // Remove .crash file if exists
// std::string old_log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
// "SecondLife.old");
// std::string crash_log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
// "SecondLife.crash");
// LLFile::remove(crash_log_file);
// // Rename ".old" log file to ".crash"
// LLFile::rename(old_log_file, crash_log_file);
// }
//#endif
// </FS:Ansariel>
}
void LLAppViewer::removeMarkerFiles()
@@ -5206,6 +5227,8 @@ bool LLAppViewer::initCache()
LL_WARNS("AppCache") << "Unable to set cache location" << LL_ENDL;
gSavedSettings.setString("CacheLocation", "");
gSavedSettings.setString("CacheLocationTopFolder", "");
gSavedSettings.setString("NewCacheLocation", "");
gSavedSettings.setString("NewCacheLocationTopFolder", "");
}
// <FS:Ansariel> Sound cache
+5 -2
View File
@@ -165,9 +165,12 @@ void LLConversation::setListenIMFloaterOpened()
// if floater is already opened or this conversation doesn't have unread offline messages
if (mHasOfflineIMs && !offline_ims_visible)
{
//mIMFloaterShowedConnection = LLFloaterIMSession::setIMFloaterShowedCallback(boost::bind(&LLConversation::onIMFloaterShown, this, _1));
mIMFloaterShowedConnection = FSFloaterIM::setIMFloaterShowedCallback(boost::bind(&LLConversation::onIMFloaterShown, this, _1));
//mIMFloaterShowedConnection = LLFloaterIMSession::setIMFloaterShowedCallback([this](const LLUUID& session_id)
mIMFloaterShowedConnection = FSFloaterIM::setIMFloaterShowedCallback([this](const LLUUID& session_id)
// </FS:CR>
{
onIMFloaterShown(session_id);
});
}
else
{
+5 -2
View File
@@ -56,9 +56,12 @@ LLConversationLogListItem::LLConversationLogListItem(const LLConversation* conve
if (mConversation->hasOfflineMessages() && !ims_are_read)
{
//mIMFloaterShowedConnection = LLFloaterIMSession::setIMFloaterShowedCallback(boost::bind(&LLConversationLogListItem::onIMFloaterShown, this, _1));
mIMFloaterShowedConnection = FSFloaterIM::setIMFloaterShowedCallback(boost::bind(&LLConversationLogListItem::onIMFloaterShown, this, _1));
//mIMFloaterShowedConnection = LLFloaterIMSession::setIMFloaterShowedCallback([this](const LLUUID& session_id)
mIMFloaterShowedConnection = FSFloaterIM::setIMFloaterShowedCallback([this](const LLUUID& session_id)
// </FS:CR>
{
onIMFloaterShown(session_id);
});
}
}
+13 -2
View File
@@ -938,7 +938,10 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update)
LLVector3 cam_pos_from_agent = LLViewerCamera::getInstance()->getOrigin();
LLVector3 cam_to_box_offset = point_to_box_offset(cam_pos_from_agent, av_box);
mDistanceWRTCamera = llmax(0.01f, ll_round(cam_to_box_offset.magVec(), 0.01f));
mVObjp->updateLOD();
if (mVObjp)
{
mVObjp->updateLOD();
}
return;
}
}
@@ -949,7 +952,10 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update)
pos -= camera.getOrigin();
mDistanceWRTCamera = ll_round(pos.magVec(), 0.01f);
mVObjp->updateLOD();
if (mVObjp)
{
mVObjp->updateLOD();
}
}
}
@@ -961,6 +967,11 @@ void LLDrawable::updateTexture()
return;
}
if (!mVObjp)
{
return;
}
if (getNumFaces() != mVObjp->getNumTEs())
{ //drawable is transitioning its face count
return;
+1 -1
View File
@@ -903,7 +903,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
return;
}
if ((sShaderLevel >= SHADER_LEVEL_CLOTH))
if (LLPipeline::RenderAvatarCloth)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_AVATAR("shader level > CLOTH"); // <FS:Beq/> Tracy markup
LLMatrix4 rot_mat;
-6
View File
@@ -45,12 +45,6 @@ extern U32 gFrameCount;
class LLDrawPoolAvatar : public LLFacePool
{
public:
enum
{
SHADER_LEVEL_BUMP = 2,
SHADER_LEVEL_CLOTH = 3
};
enum
{
VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX |
-4
View File
@@ -55,8 +55,6 @@
// static
LLStandardBumpmap gStandardBumpmapList[TEM_BUMPMAP_COUNT];
LL::WorkQueue::weak_t LLBumpImageList::sMainQueue;
LL::WorkQueue::weak_t LLBumpImageList::sTexUpdateQueue;
LLRenderTarget LLBumpImageList::sRenderTarget;
// static
@@ -632,8 +630,6 @@ void LLBumpImageList::init()
llassert( mDarknessEntries.size() == 0 );
LLStandardBumpmap::restoreGL();
sMainQueue = LL::WorkQueue::getInstance("mainloop");
sTexUpdateQueue = LL::WorkQueue::getInstance("LLImageGL"); // Share work queue with tex loader.
}
void LLBumpImageList::clear()
-2
View File
@@ -152,8 +152,6 @@ private:
typedef std::unordered_map<LLUUID, LLPointer<LLViewerTexture> > bump_image_map_t;
bump_image_map_t mBrightnessEntries;
bump_image_map_t mDarknessEntries;
static LL::WorkQueue::weak_t sMainQueue;
static LL::WorkQueue::weak_t sTexUpdateQueue;
static LLRenderTarget sRenderTarget;
};
+1 -1
View File
@@ -128,7 +128,7 @@ public:
void setIndexInTex(U32 ch, S32 index) { llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); mIndexInTex[ch] = index; }
void setWorldMatrix(const LLMatrix4& mat);
const LLTextureEntry* getTextureEntry() const { return mVObjp->getTE(mTEOffset); }
const LLTextureEntry* getTextureEntry() const { return mVObjp ? mVObjp->getTE(mTEOffset) : nullptr; }
LLFacePool* getPool() const { return mDrawPoolp; }
U32 getPoolType() const { return mPoolType; }
+2 -1
View File
@@ -41,6 +41,7 @@ LLFloaterBulkUpload::LLFloaterBulkUpload(const LLSD& key)
mUploadCost = key["upload_cost"].asInteger();
mUploadCount = key["upload_count"].asInteger();
mHas2kTextures = key["has_2k_textures"].asBoolean();
mDestinationFolderId = key["dest"];
if (key["files"].isArray())
{
const LLSD& files = key["files"];
@@ -125,7 +126,7 @@ void LLFloaterBulkUpload::onUpload2KCheckBox()
void LLFloaterBulkUpload::onClickUpload()
{
do_bulk_upload(mFiles, mAllow2kTextures);
do_bulk_upload(mFiles, mAllow2kTextures, mDestinationFolderId);
closeFloater();
}
+1
View File
@@ -59,6 +59,7 @@ private:
std::vector<std::string> mFiles;
bool mAllow2kTextures = true;
bool mHas2kTextures = false;
LLUUID mDestinationFolderId;
S32 mUploadCost = 0;
S32 mUploadCount = 0;
};
+2 -1
View File
@@ -171,7 +171,7 @@ void LLFloaterExperiences::onOpen( const LLSD& key )
refreshContents();
return;
}
region->setCapabilitiesReceivedCallback(boost::bind(&LLFloaterExperiences::refreshContents, this));
mCapsReceivedConnection = region->setCapabilitiesReceivedCallback(boost::bind(&LLFloaterExperiences::refreshContents, this));
return;
}
}
@@ -231,6 +231,7 @@ bool LLFloaterExperiences::updatePermissions( const LLSD& permission )
void LLFloaterExperiences::onClose( bool app_quitting )
{
mCapsReceivedConnection.disconnect();
LLEventPumps::instance().obtain("experience_permission").stopListening("LLFloaterExperiences");
LLFloater::onClose(app_quitting);
}
+1
View File
@@ -71,6 +71,7 @@ private:
static void retrieveExperienceListCoro(std::string url, LLHandle<LLFloaterExperiences> hparent,
NameMap_t tabMapping, std::string errorNotify, Callback_t cback, invokationFn_t invoker);
std::vector<LLUUID> mPrepurchaseIds;
boost::signals2::scoped_connection mCapsReceivedConnection;
};
#endif //LL_LLFLOATEREXPERIENCES_H
+2 -1
View File
@@ -438,7 +438,8 @@ void LLFloaterImagePreview::onBtnOK()
LLFloaterPerms::getNextOwnerPerms("Uploads"),
LLFloaterPerms::getGroupPerms("Uploads"),
LLFloaterPerms::getEveryonePerms("Uploads"),
expected_upload_cost
expected_upload_cost,
mDestinationFolderId
));
upload_new_resource(assetUploadInfo);
+2 -2
View File
@@ -487,13 +487,13 @@ void LLPanelScriptLimitsRegionMemory::setRegionDetails(LLSD content)
names_requested.push_back(owner_id);
if (is_group_owned)
{
gCacheName->getGroup(owner_id,
mGroupNameCacheConnection = gCacheName->getGroup(owner_id,
boost::bind(&LLPanelScriptLimitsRegionMemory::onNameCache,
this, _1, _2));
}
else
{
LLAvatarNameCache::get(owner_id,
mAvatarNameCacheConnection = LLAvatarNameCache::get(owner_id,
boost::bind(&LLPanelScriptLimitsRegionMemory::onAvatarNameCache,
this, _1, _2));
}
+3
View File
@@ -136,6 +136,9 @@ private:
std::vector<LLSD> mObjectListItems;
boost::signals2::scoped_connection mAvatarNameCacheConnection;
boost::signals2::scoped_connection mGroupNameCacheConnection;
void getLandScriptResourcesCoro(std::string url);
void getLandScriptSummaryCoro(std::string url);
void getLandScriptDetailsCoro(std::string url);
+2 -2
View File
@@ -695,7 +695,7 @@ void LLInventoryPanel::itemChanged(const LLUUID& item_id, U32 mask, const LLInve
// This could be anything. For now, just refresh the item.
if (mask & LLInventoryObserver::INTERNAL)
{
if (view_item)
if (view_item && view_item->getViewModelItem())
{
view_item->refresh();
}
@@ -714,7 +714,7 @@ void LLInventoryPanel::itemChanged(const LLUUID& item_id, U32 mask, const LLInve
if (mask & LLInventoryObserver::UPDATE_FAVORITE)
{
if (view_item)
if (view_item && view_item->getViewModelItem())
{
view_item->refresh();
LLFolderViewFolder* parent = view_item->getParentFolder();
+21 -17
View File
@@ -716,24 +716,28 @@ bool LLManipTranslate::handleHover(S32 x, S32 y, MASK mask)
// handle attachments in local space
if (object->isAttachment() && object->mDrawable.notNull())
{
// calculate local version of relative move
LLQuaternion objWorldRotation = object->mDrawable->mXform.getParent()->getWorldRotation();
objWorldRotation.transQuat();
LLVector3 old_position_local = object->getPosition();
LLVector3 new_position_local = selectNode->mSavedPositionLocal + (clamped_relative_move_f * objWorldRotation);
//RN: I forget, but we need to do this because of snapping which doesn't often result
// in position changes even when the mouse moves
object->setPosition(new_position_local);
rebuild(object);
gAgentAvatarp->clampAttachmentPositions();
new_position_local = object->getPosition();
if (selectNode->mIndividualSelection)
LLXform* object_xform_parent = object->mDrawable->mXform.getParent();
if (object_xform_parent)
{
// counter-translate child objects if we are moving the root as an individual
object->resetChildrenPosition(old_position_local - new_position_local, true);
// calculate local version of relative move
LLQuaternion objWorldRotation = object_xform_parent->getWorldRotation();
objWorldRotation.transQuat();
LLVector3 old_position_local = object->getPosition();
LLVector3 new_position_local = selectNode->mSavedPositionLocal + (clamped_relative_move_f * objWorldRotation);
//RN: I forget, but we need to do this because of snapping which doesn't often result
// in position changes even when the mouse moves
object->setPosition(new_position_local);
rebuild(object);
gAgentAvatarp->clampAttachmentPositions();
new_position_local = object->getPosition();
if (selectNode->mIndividualSelection)
{
// counter-translate child objects if we are moving the root as an individual
object->resetChildrenPosition(old_position_local - new_position_local, true);
}
}
}
else
+5 -2
View File
@@ -1997,12 +1997,14 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 ind
{
// Prespecified material
LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor");
me->mUploadFolder = dest_folder;
me->loadMaterial(model_in, filename, index);
}
else if (model_in.materials.size() == 1)
{
// Only one material, just load it
LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor");
me->mUploadFolder = dest_folder;
me->loadMaterial(model_in, filename, 0);
}
else
@@ -2028,11 +2030,12 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 ind
material_list.push_back(LLTrans::getString("material_batch_import_text"));
LLFloaterComboOptions::showUI(
[model_in, filename](const std::string& option, S32 index)
[model_in, filename, dest_folder](const std::string& option, S32 index)
{
if (index >= 0) // -1 on cancel
{
LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor");
me->mUploadFolder = dest_folder;
me->loadMaterial(model_in, filename, index);
}
},
@@ -2458,7 +2461,7 @@ void LLMaterialEditor::loadMaterial(const tinygltf::Model &model_in, const std::
if (index == model_in.materials.size())
{
// bulk upload all the things
upload_bulk({ filename }, LLFilePicker::FFLOAD_MATERIAL, true, LLUUID::null);
upload_bulk({ filename }, LLFilePicker::FFLOAD_MATERIAL, true, mUploadFolder);
return;
}
+16 -14
View File
@@ -1214,26 +1214,22 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
bool missing_asset = false;
{
LLGLenum image_format = GL_RGB;
bool has_alpha = false;
bool identical_image_format = false;
LLSelectedTE::getImageFormat(image_format, identical_image_format, missing_asset);
LLSelectedTE::getImageFormat(image_format, has_alpha, identical_image_format, missing_asset);
if (!missing_asset)
{
mIsAlpha = false;
mIsAlpha = has_alpha;
switch (image_format)
{
case GL_RGBA:
case GL_ALPHA:
{
mIsAlpha = true;
}
break;
case GL_RGB:
break;
default:
{
LL_WARNS() << "Unexpected tex format in LLPanelFace...resorting to no alpha" << LL_ENDL;
LL_WARNS() << "Unexpected tex format in LLPanelFace..." << LL_ENDL;
}
break;
}
@@ -3400,23 +3396,22 @@ void LLPanelFace::onSelectTexture()
sendTexture();
LLGLenum image_format;
bool has_alpha;
bool identical_image_format = false;
bool missing_asset = false;
LLSelectedTE::getImageFormat(image_format, identical_image_format, missing_asset);
LLSelectedTE::getImageFormat(image_format, has_alpha, identical_image_format, missing_asset);
U32 alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
if (!missing_asset)
{
U32 alpha_mode = has_alpha ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
switch (image_format)
{
case GL_RGBA:
case GL_ALPHA:
alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND;
break;
case GL_RGB:
break;
default:
LL_WARNS() << "Unexpected tex format in LLPanelFace...resorting to no alpha" << LL_ENDL;
LL_WARNS() << "Unexpected tex format in LLPanelFace..." << LL_ENDL;
break;
}
@@ -5391,12 +5386,13 @@ void LLPanelFace::LLSelectedTE::getFace(LLFace*& face_to_return, bool& identical
identical_face = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_te_face_func, face_to_return, false, (LLFace*)nullptr);
}
void LLPanelFace::LLSelectedTE::getImageFormat(LLGLenum& image_format_to_return, bool& identical_face, bool& missing_asset)
void LLPanelFace::LLSelectedTE::getImageFormat(LLGLenum& image_format_to_return, bool& has_alpha, bool& identical_face, bool& missing_asset)
{
struct LLSelectedTEGetmatId : public LLSelectedTEFunctor
{
LLSelectedTEGetmatId()
: mImageFormat(GL_RGB)
, mHasAlpha(false)
, mIdentical(true)
, mMissingAsset(false)
, mFirstRun(true)
@@ -5411,6 +5407,10 @@ void LLPanelFace::LLSelectedTE::getImageFormat(LLGLenum& image_format_to_return,
{
format = image->getPrimaryFormat();
missing = image->isMissingAsset();
if (format == GL_RGBA || format == GL_ALPHA)
{
mHasAlpha = true;
}
}
if (mFirstRun)
@@ -5427,6 +5427,7 @@ void LLPanelFace::LLSelectedTE::getImageFormat(LLGLenum& image_format_to_return,
return true;
}
LLGLenum mImageFormat;
bool mHasAlpha;
bool mIdentical;
bool mMissingAsset;
bool mFirstRun;
@@ -5434,6 +5435,7 @@ void LLPanelFace::LLSelectedTE::getImageFormat(LLGLenum& image_format_to_return,
LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func);
image_format_to_return = func.mImageFormat;
has_alpha = func.mHasAlpha;
identical_face = func.mIdentical;
missing_asset = func.mMissingAsset;
}
+1 -1
View File
@@ -735,7 +735,7 @@ public:
{
public:
static void getFace(class LLFace*& face_to_return, bool& identical_face);
static void getImageFormat(LLGLenum& image_format_to_return, bool& identical_face, bool& missing_asset);
static void getImageFormat(LLGLenum& image_format_to_return, bool& has_alpha, bool& identical_face, bool& missing_asset);
static void getTexId(LLUUID& id, bool& identical);
static void getPbrMaterialId(LLUUID& id, bool& identical, bool& has_pbr, bool& has_faces_without_pbr);
static void getObjectScaleS(F32& scale_s, bool& identical);
+5 -1
View File
@@ -737,6 +737,10 @@ LLPanelProfileSecondLife::~LLPanelProfileSecondLife()
{
mAvatarNameCacheConnection.disconnect();
}
if (mMenuNameCacheConnection.connected())
{
mMenuNameCacheConnection.disconnect();
}
// <FS:Ansariel> RLVa support
if (mRlvBehaviorCallbackConnection.connected())
@@ -2045,7 +2049,7 @@ void LLPanelProfileSecondLife::onCommitMenu(const LLSD& userdata)
}
else if (item_name == "edit_display_name")
{
LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileSecondLife::onAvatarNameCacheSetName, this, _1, _2));
mMenuNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileSecondLife::onAvatarNameCacheSetName, this, _1, _2));
LLFirstUse::setDisplayName(false);
}
else if (item_name == "edit_partner")
+1
View File
@@ -289,6 +289,7 @@ private:
LLUUID mImageId;
boost::signals2::connection mAvatarNameCacheConnection;
boost::signals2::connection mMenuNameCacheConnection;
// <FS:Ansariel> RLVa support
boost::signals2::connection mRlvBehaviorCallbackConnection;
+1 -1
View File
@@ -82,7 +82,7 @@ void LLSpeaker::lookupName()
if(!gCacheName)
return;
// </FS:Zi>
LLAvatarNameCache::get(mID, boost::bind(&LLSpeaker::onNameCache, this, _1, _2)); // todo: can be group???
mAvatarNameCacheConnection = LLAvatarNameCache::get(mID, boost::bind(&LLSpeaker::onNameCache, this, _1, _2)); // todo: can be group???
}
}
+3
View File
@@ -80,6 +80,9 @@ public:
bool mIsModerator;
bool mModeratorMutedVoice;
bool mModeratorMutedText;
private:
boost::signals2::scoped_connection mAvatarNameCacheConnection;
};
class LLSpeakerUpdateSpeakerEvent : public LLOldEvents::LLEvent
+26
View File
@@ -713,6 +713,32 @@ bool idle_startup()
LLStringOps::sAM = LLTrans::getString("dateTimeAM");
LLStringOps::sPM = LLTrans::getString("dateTimePM");
}
else
{
std::wstring utf16str = ll_convert<std::wstring>(val);
if (utf16str.size() > 4)
{
LL_DEBUGS("InitInfo") << "Current locale \"" << locale << "\" "
<< "has impracitcally long AM/PM time format" << LL_ENDL;
// fallback to declarations in strings.xml
LLStringOps::sAM = LLTrans::getString("dateTimeAM");
LLStringOps::sPM = LLTrans::getString("dateTimePM");
}
}
}
// Some locales (as well some of our own dateTimeAM/PM) return long
// strings for AM/PM which aren't practical to display in the UI.
// Hardcode to "AM"/"PM" in those cases.
std::wstring utf16str = ll_convert<std::wstring>(LLStringOps::sAM);
if (utf16str.size() > 4)
{
LLStringOps::sAM = "AM";
}
utf16str = ll_convert<std::wstring>(LLStringOps::sPM);
if (utf16str.size() > 4)
{
LLStringOps::sPM = "PM";
}
}
+12 -10
View File
@@ -306,17 +306,19 @@ void LLResourceUploadInfo::assignDefaults()
{
mDescription = "(No Description)";
}
if (mAssetType == LLAssetType::AT_GLTF ||
mAssetType == LLAssetType::AT_GLTF_BIN)
if (mFolderId.isNull()) // don't overwrite if destination is already specified
{
mFolderId = LLUUID::null;
}
else
{
mFolderId = gInventory.findUserDefinedCategoryUUIDForType(
(mDestinationFolderType == LLFolderType::FT_NONE) ?
(LLFolderType::EType)mAssetType : mDestinationFolderType);
if (mAssetType == LLAssetType::AT_GLTF ||
mAssetType == LLAssetType::AT_GLTF_BIN)
{
mFolderId = LLUUID::null;
}
else
{
mFolderId = gInventory.findUserDefinedCategoryUUIDForType(
(mDestinationFolderType == LLFolderType::FT_NONE) ?
(LLFolderType::EType)mAssetType : mDestinationFolderType);
}
}
}
+1
View File
@@ -1337,6 +1337,7 @@ void settings_setup_listeners()
setting_setup_signal_listener(gSavedSettings, "RenderShadowDetail", handleSetShaderChanged);
setting_setup_signal_listener(gSavedSettings, "RenderDeferredSSAO", handleSetShaderChanged);
setting_setup_signal_listener(gSavedSettings, "RenderPerformanceTest", handleRenderPerfTestChanged);
setting_setup_signal_listener(gSavedSettings, "RenderAvatarCloth", handleSetShaderChanged);
setting_setup_signal_listener(gSavedSettings, "ChatConsoleFontSize", handleChatFontSizeChanged);
setting_setup_signal_listener(gSavedSettings, "ChatPersistTime", handleChatPersistTimeChanged); // <FS:Ansariel> Keep custom chat persist time
setting_setup_signal_listener(gSavedSettings, "ConsoleMaxLines", handleConsoleMaxLinesChanged);
+8 -6
View File
@@ -545,7 +545,7 @@ void upload_single_file(
return;
}
void do_bulk_upload(std::vector<std::string> filenames, bool allow_2k)
void do_bulk_upload(std::vector<std::string> filenames, bool allow_2k, const LLUUID& dest)
{
for (std::vector<std::string>::const_iterator in_iter = filenames.begin(); in_iter != filenames.end(); ++in_iter)
{
@@ -665,7 +665,8 @@ void do_bulk_upload(std::vector<std::string> filenames, bool allow_2k)
LLFloaterPerms::getNextOwnerPerms("Uploads"),
LLFloaterPerms::getGroupPerms("Uploads"),
LLFloaterPerms::getEveryonePerms("Uploads"),
LLAgentBenefitsMgr::current().getTextureUploadCost(raw_image->getWidth(), raw_image->getHeight())
LLAgentBenefitsMgr::current().getTextureUploadCost(raw_image->getWidth(), raw_image->getHeight()),
dest
));
upload_new_resource(assetUploadInfo);
@@ -681,7 +682,8 @@ void do_bulk_upload(std::vector<std::string> filenames, bool allow_2k)
LLFloaterPerms::getNextOwnerPerms("Uploads"),
LLFloaterPerms::getGroupPerms("Uploads"),
LLFloaterPerms::getEveryonePerms("Uploads"),
expected_upload_cost);
expected_upload_cost,
dest);
LLResourceUploadInfo::ptr_t uploadInfo(info_p);
upload_new_resource(uploadInfo);
@@ -702,14 +704,14 @@ void do_bulk_upload(std::vector<std::string> filenames, bool allow_2k)
// Todo:
// 1. Decouple bulk upload from material editor
// 2. Take into account possiblity of identical textures
LLMaterialEditor::uploadMaterialFromModel(filename, model, i);
LLMaterialEditor::uploadMaterialFromModel(filename, model, i, dest);
}
}
}
}
}
void do_bulk_upload(std::vector<std::string> filenames, bool allow_2k, const LLSD& notification, const LLSD& response)
void do_bulk_upload(std::vector<std::string> filenames, bool allow_2k, const LLSD& notification, const LLSD& response, const LLUUID& dest)
{
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
if (option != 0)
@@ -718,7 +720,7 @@ void do_bulk_upload(std::vector<std::string> filenames, bool allow_2k, const LLS
return;
}
do_bulk_upload(filenames, allow_2k);
do_bulk_upload(filenames, allow_2k, dest);
}
bool get_bulk_upload_expected_cost(
+1 -1
View File
@@ -73,7 +73,7 @@ bool get_bulk_upload_expected_cost(
S32& bvh_count,
S32& textures_2k_count);
void do_bulk_upload(std::vector<std::string> filenames, bool allow_2k);
void do_bulk_upload(std::vector<std::string> filenames, bool allow_2k, const LLUUID &dest_folder);
void upload_single_file(
const std::vector<std::string>& filenames,
+1 -1
View File
@@ -7488,7 +7488,7 @@ void LLAlphaObject::getBlendFunc(S32 face, LLRender::eBlendFactor& src, LLRender
void LLStaticViewerObject::updateDrawable(bool force_damped)
{
// Force an immediate rebuild on any update
if (mDrawable.notNull())
if (mDrawable.notNull() && mDrawable->getVObj())
{
mDrawable->updateXform(true);
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL);
+4 -1
View File
@@ -587,6 +587,7 @@ void LLViewerShaderMgr::setShaders()
unloadShaders();
LLPipeline::sRenderGlow = gSavedSettings.getBOOL("RenderGlow");
LLPipeline::RenderAvatarCloth = gSavedSettings.getBOOL("RenderAvatarCloth");
if (gViewerWindow)
{
@@ -2390,7 +2391,9 @@ bool LLViewerShaderMgr::loadShadersDeferred()
gDeferredAvatarProgram.mShaderFiles.push_back(make_pair("deferred/avatarF.glsl", GL_FRAGMENT_SHADER));
gDeferredAvatarProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredAvatarProgram.clearPermutations();
add_common_permutations(&gDeferredAvatarProgram);
gDeferredAvatarProgram.addPermutation("AVATAR_CLOTH", LLPipeline::RenderAvatarCloth ? "1" : "0");
success = gDeferredAvatarProgram.createShader();
llassert(success);
@@ -3606,7 +3609,7 @@ bool LLViewerShaderMgr::loadShadersInterface()
std::string LLViewerShaderMgr::getShaderDirPrefix(void)
{
return gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "shaders/class");
return gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "shaders", "class");
}
void LLViewerShaderMgr::updateShaderUniforms(LLGLSLShader * shader)
+2 -1
View File
@@ -1124,7 +1124,6 @@ F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time)
imagep->postCreateTexture();
imagep->mCreatePending = false;
mCreateTextureList.pop();
if (imagep->hasGLTexture() && imagep->getDiscardLevel() < imagep->getDesiredDiscardLevel() &&
(imagep->getDesiredDiscardLevel() <= MAX_DISCARD_LEVEL))
@@ -1136,6 +1135,8 @@ F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time)
imagep->scaleDown();
}
mCreateTextureList.pop();
if (create_timer.getElapsedTimeF32() > max_time)
{
break;
+1 -1
View File
@@ -3739,7 +3739,7 @@ void LLVOAvatar::idleUpdateLoadingEffect()
void LLVOAvatar::idleUpdateWindEffect()
{
// update wind effect
if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) >= LLDrawPoolAvatar::SHADER_LEVEL_CLOTH))
if (LLPipeline::RenderAvatarCloth)
{
F32 hover_strength = 0.f;
F32 time_delta = mRippleTimer.getElapsedTimeF32() - mRippleTimeLast;
+1 -1
View File
@@ -781,7 +781,7 @@ void LLGrassPartition::getGeometry(LLSpatialGroup* group)
void LLVOGrass::updateDrawable(bool force_damped)
{
// Force an immediate rebuild on any update
if (mDrawable.notNull())
if (mDrawable.notNull() && mDrawable->getVObj())
{
mDrawable->updateXform(true);
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL);
+6 -2
View File
@@ -237,6 +237,7 @@ S32 LLPipeline::RenderBufferVisualization;
bool LLPipeline::RenderMirrors;
S32 LLPipeline::RenderHeroProbeUpdateRate;
S32 LLPipeline::RenderHeroProbeConservativeUpdateMultiplier;
bool LLPipeline::RenderAvatarCloth;
LLTrace::EventStatHandle<S64> LLPipeline::sStatBatchSize("renderbatchsize");
// const U32 LLPipeline::MAX_PREVIEW_WIDTH = 512;
@@ -658,6 +659,7 @@ void LLPipeline::init()
connectRefreshCachedSettingsSafe("RenderMirrors");
connectRefreshCachedSettingsSafe("RenderHeroProbeUpdateRate");
connectRefreshCachedSettingsSafe("RenderHeroProbeConservativeUpdateMultiplier");
connectRefreshCachedSettingsSafe("RenderAvatarCloth");
connectRefreshCachedSettingsSafe("FSRenderVignette"); // <FS:CR> Import Vignette from Exodus
// <FS:Ansariel> Make change to RenderAttachedLights & RenderAttachedParticles instant
connectRefreshCachedSettingsSafe("RenderAttachedLights");
@@ -1274,6 +1276,8 @@ void LLPipeline::refreshCachedSettings()
RenderMirrors = gSavedSettings.getBOOL("RenderMirrors");
RenderHeroProbeUpdateRate = gSavedSettings.getS32("RenderHeroProbeUpdateRate");
RenderHeroProbeConservativeUpdateMultiplier = gSavedSettings.getS32("RenderHeroProbeConservativeUpdateMultiplier");
RenderAvatarCloth = gSavedSettings.getBOOL("RenderAvatarCloth");
sReflectionProbesEnabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderReflectionsEnabled") && gSavedSettings.getBOOL("RenderReflectionsEnabled");
// <FS:Beq> [FIRE-35070] Instead of using the above we'll add a new static level variable to save some lookups. Making the above "work" with ProbeLevel will break everything.
sReflectionProbeLevel = gSavedSettings.getS32("RenderReflectionProbeLevel");
@@ -3100,7 +3104,7 @@ void LLPipeline::markMoved(LLDrawable *drawablep, bool damped_motion)
void LLPipeline::markShift(LLDrawable *drawablep)
{
if (!drawablep || drawablep->isDead())
if (!drawablep || drawablep->isDead() || !drawablep->getVObj())
{
return;
}
@@ -3134,7 +3138,7 @@ void LLPipeline::shiftObjects(const LLVector3 &offset)
iter != mShiftList.end(); iter++)
{
LLDrawable *drawablep = *iter;
if (drawablep->isDead())
if (drawablep->isDead() || !drawablep->getVObj())
{
continue;
}
+1
View File
@@ -1167,6 +1167,7 @@ public:
static bool RenderMirrors;
static S32 RenderHeroProbeUpdateRate;
static S32 RenderHeroProbeConservativeUpdateMultiplier;
static bool RenderAvatarCloth;
};
void render_bbox(const LLVector3 &min, const LLVector3 &max);
@@ -560,6 +560,7 @@
<menu_item_check label="Texturen in Vollauflösung (gefährlich)" name="Full Res Textures"/>
<menu_item_check label="Angehängte Lichter rendern" name="Render Attached Lights"/>
<menu_item_check label="Angehängte Partikel rendern" name="Render Attached Particles"/>
<menu_item_check label="Animierte Avatar-System-Kleidung rendern" name="Render Avatar Cloth"/>
<menu_item_check label="Sammeln von Vertex Buffern für Schrift aktivieren" name="Collect Font Vertex Buffers"/>
<menu_item_check label="Shader-Cache aktivieren" name="Enable Shader Cache"/>
<menu_item_call label="Shader-Cache bereinigen" name="Shader Cache Clear"/>
@@ -4733,8 +4733,7 @@
</menu_item_check>
<menu_item_check
label="Object-Object Occlusion"
name="Object-Object Occlusion"
shortcut="control|shift|O">
name="Object-Object Occlusion">
<menu_item_check.on_check
function="CheckControl"
parameter="UseOcclusion" />
@@ -4856,6 +4855,16 @@
function="Advanced.HandleAttachedLightParticles"
parameter="RenderAttachedParticles" />
</menu_item_check>
<menu_item_check
label="Render Animated Avatar System Cloth"
name="Render Avatar Cloth">
<menu_item_check.on_check
function="CheckControl"
parameter="RenderAvatarCloth" />
<menu_item_check.on_click
function="ToggleControl"
parameter="RenderAvatarCloth" />
</menu_item_check>
<menu_item_check
label="Reduce Draw Distance when VRAM is full"
name="Reduce Draw Distance when VRAM is full">
@@ -60,23 +60,23 @@
<scroll_list.columns
label="Parcel"
name="name"
relative_width="0.2" />
relative_width="0.25" />
<scroll_list.columns
label="Region"
name="location"
relative_width="0.2" />
relative_width="0.25" />
<scroll_list.columns
label="Type"
name="type"
relative_width="0.2" />
relative_width="0.25" />
<scroll_list.columns
label="Area"
name="area"
relative_width="0.2" />
relative_width="0.25" />
<scroll_list.columns
label="Hidden"
name="hidden"
relative_width="0.2" />
width="-1" />
</scroll_list>
<button
right="-4"
+24 -5
View File
@@ -348,9 +348,9 @@ class ViewerManifest(LLManifest,FSViewerManifest):
channel_type=self.channel_type()
#<FS:TS> LL uses "Viewer" in the name of their release package. We use "Release".
#if channel_type == 'release':
# app_suffix='Viewer'
# return CHANNEL_VENDOR_BASE
#else:
# app_suffix=self.channel_variant()
# return CHANNEL_VENDOR_BASE + ' ' + self.channel_variant()
app_suffix=self.channel_variant()
#<FS:ND> tag "OS" after CHANNEL_VENDOR_BASE and before any suffix
@@ -1357,13 +1357,12 @@ class Darwin_x86_64_Manifest(ViewerManifest):
bugsplat_db = self.args.get('bugsplat')
print(f"debug: bugsplat_db={bugsplat_db}")
if bugsplat_db:
# Inject BugsplatServerURL into Info.plist if provided.
# Inject Bugsplat's db into Info.plist if provided.
Info_plist = self.dst_path_of("Info.plist")
with open(Info_plist, 'rb') as f:
Info = plistlib.load(f)
# https://www.bugsplat.com/docs/platforms/os-x#configuration
Info["BugsplatServerURL"] = \
"https://{}.bugsplat.com/".format(bugsplat_db)
Info["BugSplatDatabase"] = bugsplat_db
self.put_in_file(
plistlib.dumps(Info),
os.path.basename(Info_plist),
@@ -1382,6 +1381,8 @@ class Darwin_x86_64_Manifest(ViewerManifest):
if self.args.get('bugsplat'):
self.path2basename(relpkgdir, "BugsplatMac.framework")
self.path2basename(relpkgdir, "CrashReporter.framework")
self.path2basename(relpkgdir, "HockeySDK.framework")
# OpenAL dylibs
if self.args['openal'] == 'ON':
@@ -1419,6 +1420,24 @@ class Darwin_x86_64_Manifest(ViewerManifest):
# stamped into the framework.
# Let exception, if any, propagate -- if this doesn't
# work, we need the build to noisily fail!
oldpath = subprocess.check_output(
['objdump', '--macho', '--dylib-id', '--non-verbose',
os.path.join(relpkgdir, "HockeySDK.framework", "HockeySDK")],
text=True
).splitlines()[-1] # take the last line of output
self.run_command(
['install_name_tool', '-change', oldpath,
'@executable_path/../Frameworks/HockeySDK.framework/HockeySDK',
executable])
oldpath = subprocess.check_output(
['objdump', '--macho', '--dylib-id', '--non-verbose',
os.path.join(relpkgdir, "CrashReporter.framework", "CrashReporter")],
text=True
).splitlines()[-1] # take the last line of output
self.run_command(
['install_name_tool', '-change', oldpath,
'@executable_path/../Frameworks/CrashReporter.framework/CrashReporter',
executable])
oldpath = subprocess.check_output(
['objdump', '--macho', '--dylib-id', '--non-verbose',
os.path.join(relpkgdir, "BugsplatMac.framework", "BugsplatMac")],