Merge branch 'viewer/build' nto rlva/development
|
|
@ -3,6 +3,7 @@
|
|||
*.bak
|
||||
*.diff
|
||||
*.orig
|
||||
*.patch
|
||||
*.pyc
|
||||
*.rej
|
||||
*.swp
|
||||
|
|
|
|||
|
|
@ -729,38 +729,28 @@
|
|||
<key>version</key>
|
||||
<string>2.1.1.500375</string>
|
||||
</map>
|
||||
<key>fmodex</key>
|
||||
<key>fmodstudio</key>
|
||||
<map>
|
||||
<key>copyright</key>
|
||||
<string>COPYRIGHT 2014 FIRELIGHT TECHNOLOGIES PTY LTD. ALL RIGHTS RESERVED</string>
|
||||
<string>FMOD Studio by Firelight Technologies Pty Ltd.</string>
|
||||
<key>description</key>
|
||||
<string>FMOD Studio API</string>
|
||||
<key>license</key>
|
||||
<string>fmodex</string>
|
||||
<string>fmod</string>
|
||||
<key>license_file</key>
|
||||
<string>LICENSES/fmodex.txt</string>
|
||||
<string>LICENSES/fmodstudio.txt</string>
|
||||
<key>name</key>
|
||||
<string>fmodex</string>
|
||||
<string>fmodstudio</string>
|
||||
<key>platforms</key>
|
||||
<map>
|
||||
<key>darwin</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>ed0d8767652aecd65a7fef3e28645bad</string>
|
||||
<key>url</key>
|
||||
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/fmodex_3p-update-fmodex/rev/297261/arch/Darwin/installer/fmodex-4.44.31.297261-darwin-297261.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin</string>
|
||||
</map>
|
||||
<key>darwin64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>cba1feed7f6bb671d791a517fddf205a</string>
|
||||
<string>dc4c9122de8bf77f34cfc8227d10a272</string>
|
||||
<key>url</key>
|
||||
<string>https://downloads.catznip.com/packages/fmodex-44461-darwin-201601300040-r23.tar.bz2</string>
|
||||
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/59038/554626/fmodstudio-2.00.07.541681-darwin64-541681.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
|
|
@ -770,9 +760,9 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>b847ec838da1ad1dd646df9d74e9b395</string>
|
||||
<string>c491bdc1690f3d920c66be509ccc6ef2</string>
|
||||
<key>url</key>
|
||||
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/p64_3p-fmodex/rev/314207/arch/Linux/installer/fmodex-4.44.61.314207-linux-314207.tar.bz2</string>
|
||||
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/59039/554632/fmodstudio-2.00.07.541681-linux-541681.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux</string>
|
||||
|
|
@ -782,9 +772,9 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>89a75d8719f7b2cbe1e54cd8407bb992</string>
|
||||
<string>ae75cdb1cc9da824c9e270bf97bfdd6c</string>
|
||||
<key>url</key>
|
||||
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/1544/3476/fmodex-4.44.64.501533-linux64-501533.tar.bz2</string>
|
||||
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/54589/506866/fmodstudio-2.00.07.538806-linux64-538806.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
|
|
@ -794,9 +784,9 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>2038da4ab71da8dc086738007c0acdd3</string>
|
||||
<string>fbd53fad464526e9331332fc0b3fee0b</string>
|
||||
<key>url</key>
|
||||
<string>http://viewer.catznip.com/downloads/packages/fmodex-4.44.61-windows-171261212.tar.bz2</string>
|
||||
<string>https://downloads.catznip.com/packages/fmodstudio-2.00.09-windows-201512304.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows</string>
|
||||
|
|
@ -806,16 +796,16 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>b4b73cd64bfd72e7ae84aad429d69cf6</string>
|
||||
<string>af7446fdf8d39e114feae354878ec54b</string>
|
||||
<key>url</key>
|
||||
<string>http://viewer.catznip.com/downloads/packages/fmodex-4.44.61-windows64-171261211.tar.bz2</string>
|
||||
<string>https://downloads.catznip.com/packages/fmodstudio-2.00.09-windows64-201512258.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows64</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>version</key>
|
||||
<string>4.44.64.501533</string>
|
||||
<string>2.00.07.541681</string>
|
||||
</map>
|
||||
<key>fontconfig</key>
|
||||
<map>
|
||||
|
|
|
|||
|
|
@ -1517,6 +1517,7 @@ Whirly Fizzle
|
|||
STORM-1930
|
||||
BUG-6659
|
||||
STORM-2078
|
||||
BUG-17349
|
||||
Whoops Babii
|
||||
VWR-631
|
||||
VWR-1640
|
||||
|
|
|
|||
|
|
@ -63,7 +63,8 @@ if (WINDOWS)
|
|||
# http://www.cmake.org/pipermail/cmake/2009-September/032143.html
|
||||
string(REPLACE "/Zm1000" " " CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
|
||||
# Moved to variables for the convenience of people who are not Kitty
|
||||
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
|
||||
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO
|
||||
"${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Zo"
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ set(cmake_SOURCE_FILES
|
|||
FindAPR.cmake
|
||||
FindAutobuild.cmake
|
||||
FindBerkeleyDB.cmake
|
||||
FindFMODEX.cmake
|
||||
FindGLH.cmake
|
||||
FindGoogleBreakpad.cmake
|
||||
FindHUNSPELL.cmake
|
||||
|
|
@ -39,7 +38,7 @@ set(cmake_SOURCE_FILES
|
|||
FindURIPARSER.cmake
|
||||
FindXmlRpcEpi.cmake
|
||||
FindZLIB.cmake
|
||||
FMODEX.cmake
|
||||
FMODSTUDIO.cmake
|
||||
FreeType.cmake
|
||||
GLEXT.cmake
|
||||
GLH.cmake
|
||||
|
|
|
|||
|
|
@ -62,14 +62,10 @@ if(WINDOWS)
|
|||
endif(ADDRESS_SIZE EQUAL 32)
|
||||
endif (BUGSPLAT_DB)
|
||||
|
||||
if (FMODEX)
|
||||
|
||||
if(ADDRESS_SIZE EQUAL 32)
|
||||
set(release_files ${release_files} fmodex.dll)
|
||||
else(ADDRESS_SIZE EQUAL 32)
|
||||
set(release_files ${release_files} fmodex64.dll)
|
||||
endif(ADDRESS_SIZE EQUAL 32)
|
||||
endif (FMODEX)
|
||||
if (FMODSTUDIO)
|
||||
set(debug_files ${debug_files} fmodL.dll)
|
||||
set(release_files ${release_files} fmod.dll)
|
||||
endif (FMODSTUDIO)
|
||||
|
||||
#*******************************
|
||||
# Copy MS C runtime dlls, required for packaging.
|
||||
|
|
@ -192,10 +188,10 @@ elseif(DARWIN)
|
|||
libnghttp2.14.14.0.dylib
|
||||
)
|
||||
|
||||
if (FMODEX)
|
||||
set(debug_files ${debug_files} libfmodexL.dylib)
|
||||
set(release_files ${release_files} libfmodex.dylib)
|
||||
endif (FMODEX)
|
||||
if (FMODSTUDIO)
|
||||
set(debug_files ${debug_files} libfmodL.dylib)
|
||||
set(release_files ${release_files} libfmod.dylib)
|
||||
endif (FMODSTUDIO)
|
||||
|
||||
elseif(LINUX)
|
||||
# linux is weird, multiple side by side configurations aren't supported
|
||||
|
|
@ -242,10 +238,10 @@ elseif(LINUX)
|
|||
libfontconfig.so.1
|
||||
)
|
||||
|
||||
if (FMODEX)
|
||||
set(debug_files ${debug_files} "libfmodexL.so")
|
||||
set(release_files ${release_files} "libfmodex.so")
|
||||
endif (FMODEX)
|
||||
if (FMODSTUDIO)
|
||||
set(debug_files ${debug_files} "libfmodL.so")
|
||||
set(release_files ${release_files} "libfmod.so")
|
||||
endif (FMODSTUDIO)
|
||||
|
||||
else(WINDOWS)
|
||||
message(STATUS "WARNING: unrecognized platform for staging 3rd party libs, skipping...")
|
||||
|
|
|
|||
|
|
@ -1,52 +0,0 @@
|
|||
# -*- cmake -*-
|
||||
|
||||
# FMOD can be set when launching the make using the argument -DFMOD:BOOL=ON
|
||||
# When building using proprietary binaries though (i.e. having access to LL private servers),
|
||||
# we always build with FMODEX.
|
||||
# Open source devs should use the -DFMODEX:BOOL=ON then if they want to build with FMOD, whether
|
||||
# they are using USESYSTEMLIBS or not.
|
||||
if (INSTALL_PROPRIETARY)
|
||||
set(FMODEX ON CACHE BOOL "Using FMOD Ex sound library.")
|
||||
endif (INSTALL_PROPRIETARY)
|
||||
|
||||
if (FMODEX)
|
||||
if (USESYSTEMLIBS)
|
||||
# In that case, we use the version of the library installed on the system
|
||||
set(FMODEX_FIND_REQUIRED ON)
|
||||
include(FindFMODEX)
|
||||
else (USESYSTEMLIBS)
|
||||
if (FMODEX_LIBRARY AND FMODEX_INCLUDE_DIR)
|
||||
# If the path have been specified in the arguments, use that
|
||||
set(FMODEX_LIBRARIES ${FMODEX_LIBRARY})
|
||||
MESSAGE(STATUS "Using FMODEX path: ${FMODEX_LIBRARIES}, ${FMODEX_INCLUDE_DIR}")
|
||||
else (FMODEX_LIBRARY AND FMODEX_INCLUDE_DIR)
|
||||
# If not, we're going to try to get the package listed in autobuild.xml
|
||||
# Note: if you're not using INSTALL_PROPRIETARY, the package URL should be local (file:/// URL)
|
||||
# as accessing the private LL location will fail if you don't have the credential
|
||||
include(Prebuilt)
|
||||
use_prebuilt_binary(fmodex)
|
||||
if (WINDOWS)
|
||||
if (ADDRESS_SIZE EQUAL 32)
|
||||
set(FMODEX_LIBRARY
|
||||
debug fmodexL_vc
|
||||
optimized fmodex_vc)
|
||||
else (ADDRESS_SIZE EQUAL 64)
|
||||
set(FMODEX_LIBRARY
|
||||
debug fmodexL64_vc
|
||||
optimized fmodex64_vc)
|
||||
endif (ADDRESS_SIZE EQUAL 32)
|
||||
elseif (DARWIN)
|
||||
set(FMODEX_LIBRARY
|
||||
debug fmodexL
|
||||
optimized fmodex)
|
||||
elseif (LINUX)
|
||||
set(FMODEX_LIBRARY
|
||||
debug fmodexL
|
||||
optimized fmodex)
|
||||
endif (WINDOWS)
|
||||
set(FMODEX_LIBRARIES ${FMODEX_LIBRARY})
|
||||
set(FMODEX_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/fmodex)
|
||||
endif (FMODEX_LIBRARY AND FMODEX_INCLUDE_DIR)
|
||||
endif (USESYSTEMLIBS)
|
||||
endif (FMODEX)
|
||||
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
# -*- cmake -*-
|
||||
|
||||
# FMODSTUDIO can be set when launching the make using the argument -DFMODSTUDIO:BOOL=ON
|
||||
# When building using proprietary binaries though (i.e. having access to LL private servers),
|
||||
# we always build with FMODSTUDIO.
|
||||
if (INSTALL_PROPRIETARY)
|
||||
set(FMODSTUDIO ON CACHE BOOL "Using FMODSTUDIO sound library.")
|
||||
endif (INSTALL_PROPRIETARY)
|
||||
|
||||
if (FMODSTUDIO)
|
||||
if (FMODSTUDIO_LIBRARY AND FMODSTUDIO_INCLUDE_DIR)
|
||||
# If the path have been specified in the arguments, use that
|
||||
set(FMODSTUDIO_LIBRARIES ${FMODSTUDIO_LIBRARY})
|
||||
else (FMODSTUDIO_LIBRARY AND FMODSTUDIO_INCLUDE_DIR)
|
||||
# If not, we're going to try to get the package listed in autobuild.xml
|
||||
# Note: if you're not using INSTALL_PROPRIETARY, the package URL should be local (file:/// URL)
|
||||
# as accessing the private LL location will fail if you don't have the credential
|
||||
include(Prebuilt)
|
||||
use_prebuilt_binary(fmodstudio)
|
||||
if (WINDOWS)
|
||||
set(FMODSTUDIO_LIBRARY
|
||||
debug fmodL_vc
|
||||
optimized fmod_vc)
|
||||
elseif (DARWIN)
|
||||
#despite files being called libfmod.dylib, we are searching for fmod
|
||||
set(FMODSTUDIO_LIBRARY
|
||||
debug fmodL
|
||||
optimized fmod)
|
||||
elseif (LINUX)
|
||||
set(FMODSTUDIO_LIBRARY
|
||||
debug fmodL
|
||||
optimized fmod)
|
||||
endif (WINDOWS)
|
||||
set(FMODSTUDIO_LIBRARIES ${FMODSTUDIO_LIBRARY})
|
||||
set(FMODSTUDIO_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/fmodstudio)
|
||||
endif (FMODSTUDIO_LIBRARY AND FMODSTUDIO_INCLUDE_DIR)
|
||||
endif (FMODSTUDIO)
|
||||
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
# -*- cmake -*-
|
||||
|
||||
# - Find FMODEX
|
||||
# Find the FMODEX includes and library
|
||||
# This module defines
|
||||
# FMODEX_INCLUDE_DIR, where to find fmod.h and fmod_errors.h
|
||||
# FMODEX_LIBRARIES, the libraries needed to use FMODEX.
|
||||
# FMODEX, If false, do not try to use FMODEX.
|
||||
# also defined, but not for general use are
|
||||
# FMODEX_LIBRARY, where to find the FMODEX library.
|
||||
|
||||
FIND_PATH(FMODEX_INCLUDE_DIR fmod.h PATH_SUFFIXES fmod)
|
||||
|
||||
SET(FMODEX_NAMES ${FMODEX_NAMES} fmodex fmodvc fmodexL_vc)
|
||||
FIND_LIBRARY(FMODEX_LIBRARY
|
||||
NAMES ${FMODEX_NAMES}
|
||||
PATH_SUFFIXES fmodex
|
||||
)
|
||||
|
||||
IF (FMODEX_SDK_DIR OR WINDOWS)
|
||||
if(WINDOWS)
|
||||
set(FMODEX_SDK_DIR "$ENV{PROGRAMFILES}/FMOD SoundSystem/FMOD Programmers API Windows" CACHE PATH "Path to FMODEX")
|
||||
STRING(REGEX REPLACE "\\\\" "/" FMODEX_SDK_DIR ${FMODEX_SDK_DIR})
|
||||
endif(WINDOWS)
|
||||
find_library(FMODEX_LIBRARY
|
||||
fmodex_vc fmodexL_vc
|
||||
PATHS
|
||||
${FMODEX_SDK_DIR}/api/lib
|
||||
${FMODEX_SDK_DIR}/api
|
||||
${FMODEX_SDK_DIR}
|
||||
)
|
||||
find_path(FMODEX_INCLUDE_DIR fmod.h
|
||||
${FMODEX_SDK_DIR}/api/inc
|
||||
${FMODEX_SDK_DIR}/api
|
||||
${FMODEX_SDK_DIR}
|
||||
)
|
||||
find_path(FMODEX_INCLUDE_DIR fmod.h
|
||||
${FMODEX_SDK_DIR}/api/inc
|
||||
${FMODEX_SDK_DIR}/api
|
||||
${FMODEX_SDK_DIR}
|
||||
)
|
||||
IF (FMODEX_LIBRARY AND FMODEX_INCLUDE_DIR)
|
||||
SET(FMODEX_LIBRARIES ${FMODEX_LIBRARY})
|
||||
SET(FMODEX_FOUND "YES")
|
||||
endif (FMODEX_LIBRARY AND FMODEX_INCLUDE_DIR)
|
||||
ENDIF (FMODEX_SDK_DIR OR WINDOWS)
|
||||
|
||||
IF (FMODEX_FOUND)
|
||||
IF (NOT FMODEX_FIND_QUIETLY)
|
||||
MESSAGE(STATUS "Found FMODEX: ${FMODEX_LIBRARIES}")
|
||||
ENDIF (NOT FMODEX_FIND_QUIETLY)
|
||||
ELSE (FMODEX_FOUND)
|
||||
IF (FMODEX_FIND_REQUIRED)
|
||||
MESSAGE(FATAL_ERROR "Could not find FMODEX library")
|
||||
ENDIF (FMODEX_FIND_REQUIRED)
|
||||
ENDIF (FMODEX_FOUND)
|
||||
|
||||
# Deprecated declarations.
|
||||
SET (NATIVE_FMODEX_INCLUDE_PATH ${FMODEX_INCLUDE_DIR} )
|
||||
GET_FILENAME_COMPONENT (NATIVE_FMODEX_LIB_PATH ${FMODEX_LIBRARY} PATH)
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
FMODEX_LIBRARY
|
||||
FMODEX_INCLUDE_DIR
|
||||
)
|
||||
|
|
@ -4,7 +4,7 @@ project(llaudio)
|
|||
|
||||
include(00-Common)
|
||||
include(LLAudio)
|
||||
include(FMODEX)
|
||||
include(FMODSTUDIO)
|
||||
include(OPENAL)
|
||||
include(LLCommon)
|
||||
include(LLMath)
|
||||
|
|
@ -42,22 +42,22 @@ set(llaudio_HEADER_FILES
|
|||
llwindgen.h
|
||||
)
|
||||
|
||||
if (FMODEX)
|
||||
if (FMODSTUDIO)
|
||||
include_directories(
|
||||
${FMODEX_INCLUDE_DIR}
|
||||
${FMODSTUDIO_INCLUDE_DIR}
|
||||
)
|
||||
list(APPEND llaudio_SOURCE_FILES
|
||||
llaudioengine_fmodex.cpp
|
||||
lllistener_fmodex.cpp
|
||||
llstreamingaudio_fmodex.cpp
|
||||
llaudioengine_fmodstudio.cpp
|
||||
lllistener_fmodstudio.cpp
|
||||
llstreamingaudio_fmodstudio.cpp
|
||||
)
|
||||
|
||||
list(APPEND llaudio_HEADER_FILES
|
||||
llaudioengine_fmodex.h
|
||||
lllistener_fmodex.h
|
||||
llstreamingaudio_fmodex.h
|
||||
llaudioengine_fmodstudio.h
|
||||
lllistener_fmodstudio.h
|
||||
llstreamingaudio_fmodstudio.h
|
||||
)
|
||||
endif (FMODEX)
|
||||
endif (FMODSTUDIO)
|
||||
|
||||
if (OPENAL)
|
||||
list(APPEND llaudio_SOURCE_FILES
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ void LLAudioEngine::setDefaults()
|
|||
}
|
||||
|
||||
|
||||
bool LLAudioEngine::init(const S32 num_channels, void* userdata)
|
||||
bool LLAudioEngine::init(const S32 num_channels, void* userdata, const std::string &app_title)
|
||||
{
|
||||
setDefaults();
|
||||
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ public:
|
|||
virtual ~LLAudioEngine();
|
||||
|
||||
// initialization/startup/shutdown
|
||||
virtual bool init(const S32 num_channels, void *userdata);
|
||||
virtual bool init(const S32 num_channels, void *userdata, const std::string &app_title);
|
||||
virtual std::string getDriverName(bool verbose) = 0;
|
||||
virtual void shutdown();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,767 +0,0 @@
|
|||
/**
|
||||
* @file audioengine_fmodex.cpp
|
||||
* @brief Implementation of LLAudioEngine class abstracting the audio
|
||||
* support as a FMODEX implementation
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2014, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "llstreamingaudio.h"
|
||||
#include "llstreamingaudio_fmodex.h"
|
||||
|
||||
#include "llaudioengine_fmodex.h"
|
||||
#include "lllistener_fmodex.h"
|
||||
|
||||
#include "llerror.h"
|
||||
#include "llmath.h"
|
||||
#include "llrand.h"
|
||||
|
||||
#include "fmod.hpp"
|
||||
#include "fmod_errors.h"
|
||||
#include "lldir.h"
|
||||
#include "llapr.h"
|
||||
|
||||
#include "sound_ids.h"
|
||||
|
||||
FMOD_RESULT F_CALLBACK windCallback(FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int outchannels);
|
||||
|
||||
FMOD::ChannelGroup *LLAudioEngine_FMODEX::mChannelGroups[LLAudioEngine::AUDIO_TYPE_COUNT] = {0};
|
||||
|
||||
LLAudioEngine_FMODEX::LLAudioEngine_FMODEX(bool enable_profiler)
|
||||
{
|
||||
mInited = false;
|
||||
mWindGen = NULL;
|
||||
mWindDSP = NULL;
|
||||
mSystem = NULL;
|
||||
mEnableProfiler = enable_profiler;
|
||||
mWindDSPDesc = new FMOD_DSP_DESCRIPTION();
|
||||
}
|
||||
|
||||
|
||||
LLAudioEngine_FMODEX::~LLAudioEngine_FMODEX()
|
||||
{
|
||||
delete mWindDSPDesc;
|
||||
}
|
||||
|
||||
|
||||
inline bool Check_FMOD_Error(FMOD_RESULT result, const char *string)
|
||||
{
|
||||
if(result == FMOD_OK)
|
||||
return false;
|
||||
LL_DEBUGS() << string << " Error: " << FMOD_ErrorString(result) << LL_ENDL;
|
||||
return true;
|
||||
}
|
||||
|
||||
void* F_STDCALL decode_alloc(unsigned int size, FMOD_MEMORY_TYPE type, const char *sourcestr)
|
||||
{
|
||||
if(type & FMOD_MEMORY_STREAM_DECODE)
|
||||
{
|
||||
LL_INFOS() << "Decode buffer size: " << size << LL_ENDL;
|
||||
}
|
||||
else if(type & FMOD_MEMORY_STREAM_FILE)
|
||||
{
|
||||
LL_INFOS() << "Strean buffer size: " << size << LL_ENDL;
|
||||
}
|
||||
return new char[size];
|
||||
}
|
||||
void* F_STDCALL decode_realloc(void *ptr, unsigned int size, FMOD_MEMORY_TYPE type, const char *sourcestr)
|
||||
{
|
||||
memset(ptr,0,size);
|
||||
return ptr;
|
||||
}
|
||||
void F_STDCALL decode_dealloc(void *ptr, FMOD_MEMORY_TYPE type, const char *sourcestr)
|
||||
{
|
||||
delete[] (char*)ptr;
|
||||
}
|
||||
|
||||
bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata)
|
||||
{
|
||||
U32 version;
|
||||
FMOD_RESULT result;
|
||||
|
||||
LL_DEBUGS("AppInit") << "LLAudioEngine_FMODEX::init() initializing FMOD" << LL_ENDL;
|
||||
|
||||
//result = FMOD::Memory_Initialize(NULL, 0, &decode_alloc, &decode_realloc, &decode_dealloc, FMOD_MEMORY_STREAM_DECODE | FMOD_MEMORY_STREAM_FILE);
|
||||
//if(Check_FMOD_Error(result, "FMOD::Memory_Initialize"))
|
||||
// return false;
|
||||
|
||||
// turn off non-error log spam to fmod.log (TODO: why do we even have an fmod.log if we don't link against log lib?)
|
||||
FMOD::Debug_SetLevel(FMOD_DEBUG_LEVEL_ERROR);
|
||||
|
||||
result = FMOD::System_Create(&mSystem);
|
||||
if(Check_FMOD_Error(result, "FMOD::System_Create"))
|
||||
return false;
|
||||
|
||||
//will call LLAudioEngine_FMODEX::allocateListener, which needs a valid mSystem pointer.
|
||||
LLAudioEngine::init(num_channels, userdata);
|
||||
|
||||
result = mSystem->getVersion(&version);
|
||||
Check_FMOD_Error(result, "FMOD::System::getVersion");
|
||||
|
||||
if (version < FMOD_VERSION)
|
||||
{
|
||||
LL_WARNS("AppInit") << "Error : You are using the wrong FMOD Ex version (" << version
|
||||
<< ")! You should be using FMOD Ex" << FMOD_VERSION << LL_ENDL;
|
||||
}
|
||||
|
||||
result = mSystem->setSoftwareFormat(44100, FMOD_SOUND_FORMAT_PCM16, 0, 0, FMOD_DSP_RESAMPLER_LINEAR);
|
||||
Check_FMOD_Error(result,"FMOD::System::setSoftwareFormat");
|
||||
|
||||
// In this case, all sounds, PLUS wind and stream will be software.
|
||||
result = mSystem->setSoftwareChannels(num_channels + 2);
|
||||
Check_FMOD_Error(result,"FMOD::System::setSoftwareChannels");
|
||||
|
||||
U32 fmod_flags = FMOD_INIT_NORMAL;
|
||||
if(mEnableProfiler)
|
||||
{
|
||||
fmod_flags |= FMOD_INIT_ENABLE_PROFILE;
|
||||
mSystem->createChannelGroup("None", &mChannelGroups[AUDIO_TYPE_NONE]);
|
||||
mSystem->createChannelGroup("SFX", &mChannelGroups[AUDIO_TYPE_SFX]);
|
||||
mSystem->createChannelGroup("UI", &mChannelGroups[AUDIO_TYPE_UI]);
|
||||
mSystem->createChannelGroup("Ambient", &mChannelGroups[AUDIO_TYPE_AMBIENT]);
|
||||
}
|
||||
|
||||
#if LL_LINUX
|
||||
bool audio_ok = false;
|
||||
|
||||
if (!audio_ok)
|
||||
{
|
||||
if (NULL == getenv("LL_BAD_FMOD_PULSEAUDIO")) /*Flawfinder: ignore*/
|
||||
{
|
||||
LL_DEBUGS("AppInit") << "Trying PulseAudio audio output..." << LL_ENDL;
|
||||
if(mSystem->setOutput(FMOD_OUTPUTTYPE_PULSEAUDIO) == FMOD_OK &&
|
||||
(result = mSystem->init(num_channels + 2, fmod_flags, 0)) == FMOD_OK)
|
||||
{
|
||||
LL_DEBUGS("AppInit") << "PulseAudio output initialized OKAY" << LL_ENDL;
|
||||
audio_ok = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Check_FMOD_Error(result, "PulseAudio audio output FAILED to initialize");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_DEBUGS("AppInit") << "PulseAudio audio output SKIPPED" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
if (!audio_ok)
|
||||
{
|
||||
if (NULL == getenv("LL_BAD_FMOD_ALSA")) /*Flawfinder: ignore*/
|
||||
{
|
||||
LL_DEBUGS("AppInit") << "Trying ALSA audio output..." << LL_ENDL;
|
||||
if(mSystem->setOutput(FMOD_OUTPUTTYPE_ALSA) == FMOD_OK &&
|
||||
(result = mSystem->init(num_channels + 2, fmod_flags, 0)) == FMOD_OK)
|
||||
{
|
||||
LL_DEBUGS("AppInit") << "ALSA audio output initialized OKAY" << LL_ENDL;
|
||||
audio_ok = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Check_FMOD_Error(result, "ALSA audio output FAILED to initialize");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_DEBUGS("AppInit") << "ALSA audio output SKIPPED" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
if (!audio_ok)
|
||||
{
|
||||
if (NULL == getenv("LL_BAD_FMOD_OSS")) /*Flawfinder: ignore*/
|
||||
{
|
||||
LL_DEBUGS("AppInit") << "Trying OSS audio output..." << LL_ENDL;
|
||||
if(mSystem->setOutput(FMOD_OUTPUTTYPE_OSS) == FMOD_OK &&
|
||||
(result = mSystem->init(num_channels + 2, fmod_flags, 0)) == FMOD_OK)
|
||||
{
|
||||
LL_DEBUGS("AppInit") << "OSS audio output initialized OKAY" << LL_ENDL;
|
||||
audio_ok = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Check_FMOD_Error(result, "OSS audio output FAILED to initialize");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_DEBUGS("AppInit") << "OSS audio output SKIPPED" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
if (!audio_ok)
|
||||
{
|
||||
LL_WARNS("AppInit") << "Overall audio init failure." << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
|
||||
// We're interested in logging which output method we
|
||||
// ended up with, for QA purposes.
|
||||
FMOD_OUTPUTTYPE output_type;
|
||||
mSystem->getOutput(&output_type);
|
||||
switch (output_type)
|
||||
{
|
||||
case FMOD_OUTPUTTYPE_NOSOUND:
|
||||
LL_INFOS("AppInit") << "Audio output: NoSound" << LL_ENDL; break;
|
||||
case FMOD_OUTPUTTYPE_PULSEAUDIO:
|
||||
LL_INFOS("AppInit") << "Audio output: PulseAudio" << LL_ENDL; break;
|
||||
case FMOD_OUTPUTTYPE_ALSA:
|
||||
LL_INFOS("AppInit") << "Audio output: ALSA" << LL_ENDL; break;
|
||||
case FMOD_OUTPUTTYPE_OSS:
|
||||
LL_INFOS("AppInit") << "Audio output: OSS" << LL_ENDL; break;
|
||||
default:
|
||||
LL_INFOS("AppInit") << "Audio output: Unknown!" << LL_ENDL; break;
|
||||
};
|
||||
#else // LL_LINUX
|
||||
|
||||
// initialize the FMOD engine
|
||||
result = mSystem->init( num_channels + 2, fmod_flags, 0);
|
||||
if (result == FMOD_ERR_OUTPUT_CREATEBUFFER)
|
||||
{
|
||||
/*
|
||||
Ok, the speaker mode selected isn't supported by this soundcard. Switch it
|
||||
back to stereo...
|
||||
*/
|
||||
result = mSystem->setSpeakerMode(FMOD_SPEAKERMODE_STEREO);
|
||||
Check_FMOD_Error(result,"Error falling back to stereo mode");
|
||||
/*
|
||||
... and re-init.
|
||||
*/
|
||||
result = mSystem->init( num_channels + 2, fmod_flags, 0);
|
||||
}
|
||||
if(Check_FMOD_Error(result, "Error initializing FMOD Ex"))
|
||||
return false;
|
||||
#endif
|
||||
|
||||
// set up our favourite FMOD-native streaming audio implementation if none has already been added
|
||||
if (!getStreamingAudioImpl()) // no existing implementation added
|
||||
setStreamingAudioImpl(new LLStreamingAudio_FMODEX(mSystem));
|
||||
|
||||
LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init() FMOD Ex initialized correctly" << LL_ENDL;
|
||||
|
||||
int r_numbuffers, r_samplerate, r_channels, r_bits;
|
||||
unsigned int r_bufferlength;
|
||||
mSystem->getDSPBufferSize(&r_bufferlength, &r_numbuffers);
|
||||
LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): r_bufferlength=" << r_bufferlength << " bytes" << LL_ENDL;
|
||||
LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): r_numbuffers=" << r_numbuffers << LL_ENDL;
|
||||
|
||||
mSystem->getSoftwareFormat(&r_samplerate, NULL, &r_channels, NULL, NULL, &r_bits);
|
||||
LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): r_samplerate=" << r_samplerate << "Hz" << LL_ENDL;
|
||||
LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): r_channels=" << r_channels << LL_ENDL;
|
||||
LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): r_bits =" << r_bits << LL_ENDL;
|
||||
|
||||
char r_name[512];
|
||||
mSystem->getDriverInfo(0, r_name, 511, 0);
|
||||
r_name[511] = '\0';
|
||||
LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): r_name=\"" << r_name << "\"" << LL_ENDL;
|
||||
|
||||
int latency = 100; // optimistic default - i suspect if sample rate is 0, everything breaks.
|
||||
if ( r_samplerate != 0 )
|
||||
latency = (int)(1000.0f * r_bufferlength * r_numbuffers / r_samplerate);
|
||||
LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): latency=" << latency << "ms" << LL_ENDL;
|
||||
|
||||
mInited = true;
|
||||
|
||||
LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): initialization complete." << LL_ENDL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
std::string LLAudioEngine_FMODEX::getDriverName(bool verbose)
|
||||
{
|
||||
llassert_always(mSystem);
|
||||
if (verbose)
|
||||
{
|
||||
U32 version;
|
||||
if(!Check_FMOD_Error(mSystem->getVersion(&version), "FMOD::System::getVersion"))
|
||||
{
|
||||
return llformat("FMOD Ex %1x.%02x.%02x", version >> 16, version >> 8 & 0x000000FF, version & 0x000000FF);
|
||||
}
|
||||
}
|
||||
return "FMODEx";
|
||||
}
|
||||
|
||||
|
||||
void LLAudioEngine_FMODEX::allocateListener(void)
|
||||
{
|
||||
mListenerp = (LLListener *) new LLListener_FMODEX(mSystem);
|
||||
if (!mListenerp)
|
||||
{
|
||||
LL_WARNS() << "Listener creation failed" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LLAudioEngine_FMODEX::shutdown()
|
||||
{
|
||||
stopInternetStream();
|
||||
|
||||
LL_INFOS() << "About to LLAudioEngine::shutdown()" << LL_ENDL;
|
||||
LLAudioEngine::shutdown();
|
||||
|
||||
LL_INFOS() << "LLAudioEngine_FMODEX::shutdown() closing FMOD Ex" << LL_ENDL;
|
||||
if ( mSystem ) // speculative fix for MAINT-2657
|
||||
{
|
||||
mSystem->close();
|
||||
mSystem->release();
|
||||
}
|
||||
LL_INFOS() << "LLAudioEngine_FMODEX::shutdown() done closing FMOD Ex" << LL_ENDL;
|
||||
|
||||
delete mListenerp;
|
||||
mListenerp = NULL;
|
||||
}
|
||||
|
||||
|
||||
LLAudioBuffer * LLAudioEngine_FMODEX::createBuffer()
|
||||
{
|
||||
return new LLAudioBufferFMODEX(mSystem);
|
||||
}
|
||||
|
||||
|
||||
LLAudioChannel * LLAudioEngine_FMODEX::createChannel()
|
||||
{
|
||||
return new LLAudioChannelFMODEX(mSystem);
|
||||
}
|
||||
|
||||
bool LLAudioEngine_FMODEX::initWind()
|
||||
{
|
||||
mNextWindUpdate = 0.0;
|
||||
|
||||
if (!mWindDSP)
|
||||
{
|
||||
memset(mWindDSPDesc, 0, sizeof(*mWindDSPDesc)); //Set everything to zero
|
||||
strncpy(mWindDSPDesc->name, "Wind Unit", sizeof(mWindDSPDesc->name));
|
||||
mWindDSPDesc->channels = 2;
|
||||
mWindDSPDesc->read = &windCallback; // Assign callback - may be called from arbitrary threads
|
||||
if (Check_FMOD_Error(mSystem->createDSP(mWindDSPDesc, &mWindDSP), "FMOD::createDSP"))
|
||||
return false;
|
||||
|
||||
if (mWindGen)
|
||||
delete mWindGen;
|
||||
|
||||
float frequency = 44100;
|
||||
mWindDSP->getDefaults(&frequency,0,0,0);
|
||||
mWindGen = new LLWindGen<MIXBUFFERFORMAT>((U32)frequency);
|
||||
mWindDSP->setUserData((void*)mWindGen);
|
||||
}
|
||||
|
||||
// *TODO: Should this guard against multiple plays?
|
||||
if (mWindDSP)
|
||||
{
|
||||
mSystem->playDSP(FMOD_CHANNEL_FREE, mWindDSP, false, 0);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void LLAudioEngine_FMODEX::cleanupWind()
|
||||
{
|
||||
if (mWindDSP)
|
||||
{
|
||||
mWindDSP->remove();
|
||||
mWindDSP->release();
|
||||
mWindDSP = NULL;
|
||||
}
|
||||
|
||||
delete mWindGen;
|
||||
mWindGen = NULL;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
void LLAudioEngine_FMODEX::updateWind(LLVector3 wind_vec, F32 camera_height_above_water)
|
||||
{
|
||||
LLVector3 wind_pos;
|
||||
F64 pitch;
|
||||
F64 center_freq;
|
||||
|
||||
if (!mEnableWind)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (mWindUpdateTimer.checkExpirationAndReset(LL_WIND_UPDATE_INTERVAL))
|
||||
{
|
||||
|
||||
// wind comes in as Linden coordinate (+X = forward, +Y = left, +Z = up)
|
||||
// need to convert this to the conventional orientation DS3D and OpenAL use
|
||||
// where +X = right, +Y = up, +Z = backwards
|
||||
|
||||
wind_vec.setVec(-wind_vec.mV[1], wind_vec.mV[2], -wind_vec.mV[0]);
|
||||
|
||||
// cerr << "Wind update" << endl;
|
||||
|
||||
pitch = 1.0 + mapWindVecToPitch(wind_vec);
|
||||
center_freq = 80.0 * pow(pitch,2.5*(mapWindVecToGain(wind_vec)+1.0));
|
||||
|
||||
mWindGen->mTargetFreq = (F32)center_freq;
|
||||
mWindGen->mTargetGain = (F32)mapWindVecToGain(wind_vec) * mMaxWindGain;
|
||||
mWindGen->mTargetPanGainR = (F32)mapWindVecToPan(wind_vec);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
void LLAudioEngine_FMODEX::setInternalGain(F32 gain)
|
||||
{
|
||||
if (!mInited)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
gain = llclamp( gain, 0.0f, 1.0f );
|
||||
|
||||
FMOD::ChannelGroup *master_group;
|
||||
mSystem->getMasterChannelGroup(&master_group);
|
||||
|
||||
master_group->setVolume(gain);
|
||||
|
||||
LLStreamingAudioInterface *saimpl = getStreamingAudioImpl();
|
||||
if ( saimpl )
|
||||
{
|
||||
// fmod likes its streaming audio channel gain re-asserted after
|
||||
// master volume change.
|
||||
saimpl->setGain(saimpl->getGain());
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// LLAudioChannelFMODEX implementation
|
||||
//
|
||||
|
||||
LLAudioChannelFMODEX::LLAudioChannelFMODEX(FMOD::System *system) : LLAudioChannel(), mSystemp(system), mChannelp(NULL), mLastSamplePos(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
LLAudioChannelFMODEX::~LLAudioChannelFMODEX()
|
||||
{
|
||||
cleanup();
|
||||
}
|
||||
|
||||
bool LLAudioChannelFMODEX::updateBuffer()
|
||||
{
|
||||
if (LLAudioChannel::updateBuffer())
|
||||
{
|
||||
// Base class update returned true, which means that we need to actually
|
||||
// set up the channel for a different buffer.
|
||||
|
||||
LLAudioBufferFMODEX *bufferp = (LLAudioBufferFMODEX *)mCurrentSourcep->getCurrentBuffer();
|
||||
|
||||
// Grab the FMOD sample associated with the buffer
|
||||
FMOD::Sound *soundp = bufferp->getSound();
|
||||
if (!soundp)
|
||||
{
|
||||
// This is bad, there should ALWAYS be a sound associated with a legit
|
||||
// buffer.
|
||||
LL_ERRS() << "No FMOD sound!" << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Actually play the sound. Start it off paused so we can do all the necessary
|
||||
// setup.
|
||||
if(!mChannelp)
|
||||
{
|
||||
FMOD_RESULT result = getSystem()->playSound(FMOD_CHANNEL_FREE, soundp, true, &mChannelp);
|
||||
Check_FMOD_Error(result, "FMOD::System::playSound");
|
||||
}
|
||||
|
||||
//LL_INFOS() << "Setting up channel " << std::hex << mChannelID << std::dec << LL_ENDL;
|
||||
}
|
||||
|
||||
// If we have a source for the channel, we need to update its gain.
|
||||
if (mCurrentSourcep)
|
||||
{
|
||||
// SJB: warnings can spam and hurt framerate, disabling
|
||||
//FMOD_RESULT result;
|
||||
|
||||
mChannelp->setVolume(getSecondaryGain() * mCurrentSourcep->getGain());
|
||||
//Check_FMOD_Error(result, "FMOD::Channel::setVolume");
|
||||
|
||||
mChannelp->setMode(mCurrentSourcep->isLoop() ? FMOD_LOOP_NORMAL : FMOD_LOOP_OFF);
|
||||
/*if(Check_FMOD_Error(result, "FMOD::Channel::setMode"))
|
||||
{
|
||||
S32 index;
|
||||
mChannelp->getIndex(&index);
|
||||
LL_WARNS() << "Channel " << index << "Source ID: " << mCurrentSourcep->getID()
|
||||
<< " at " << mCurrentSourcep->getPositionGlobal() << LL_ENDL;
|
||||
}*/
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void LLAudioChannelFMODEX::update3DPosition()
|
||||
{
|
||||
if (!mChannelp)
|
||||
{
|
||||
// We're not actually a live channel (i.e., we're not playing back anything)
|
||||
return;
|
||||
}
|
||||
|
||||
LLAudioBufferFMODEX *bufferp = (LLAudioBufferFMODEX *)mCurrentBufferp;
|
||||
if (!bufferp)
|
||||
{
|
||||
// We don't have a buffer associated with us (should really have been picked up
|
||||
// by the above if.
|
||||
return;
|
||||
}
|
||||
|
||||
if (mCurrentSourcep->isAmbient())
|
||||
{
|
||||
// Ambient sound, don't need to do any positional updates.
|
||||
set3DMode(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Localized sound. Update the position and velocity of the sound.
|
||||
set3DMode(true);
|
||||
|
||||
LLVector3 float_pos;
|
||||
float_pos.setVec(mCurrentSourcep->getPositionGlobal());
|
||||
FMOD_RESULT result = mChannelp->set3DAttributes((FMOD_VECTOR*)float_pos.mV, (FMOD_VECTOR*)mCurrentSourcep->getVelocity().mV);
|
||||
Check_FMOD_Error(result, "FMOD::Channel::set3DAttributes");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LLAudioChannelFMODEX::updateLoop()
|
||||
{
|
||||
if (!mChannelp)
|
||||
{
|
||||
// May want to clear up the loop/sample counters.
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Hack: We keep track of whether we looped or not by seeing when the
|
||||
// sample position looks like it's going backwards. Not reliable; may
|
||||
// yield false negatives.
|
||||
//
|
||||
U32 cur_pos;
|
||||
mChannelp->getPosition(&cur_pos,FMOD_TIMEUNIT_PCMBYTES);
|
||||
|
||||
if (cur_pos < (U32)mLastSamplePos)
|
||||
{
|
||||
mLoopedThisFrame = true;
|
||||
}
|
||||
mLastSamplePos = cur_pos;
|
||||
}
|
||||
|
||||
|
||||
void LLAudioChannelFMODEX::cleanup()
|
||||
{
|
||||
if (!mChannelp)
|
||||
{
|
||||
//LL_INFOS() << "Aborting cleanup with no channel handle." << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
//LL_INFOS() << "Cleaning up channel: " << mChannelID << LL_ENDL;
|
||||
Check_FMOD_Error(mChannelp->stop(),"FMOD::Channel::stop");
|
||||
|
||||
mCurrentBufferp = NULL;
|
||||
mChannelp = NULL;
|
||||
}
|
||||
|
||||
|
||||
void LLAudioChannelFMODEX::play()
|
||||
{
|
||||
if (!mChannelp)
|
||||
{
|
||||
LL_WARNS() << "Playing without a channel handle, aborting" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
Check_FMOD_Error(mChannelp->setPaused(false), "FMOD::Channel::pause");
|
||||
|
||||
getSource()->setPlayedOnce(true);
|
||||
|
||||
if(LLAudioEngine_FMODEX::mChannelGroups[getSource()->getType()])
|
||||
mChannelp->setChannelGroup(LLAudioEngine_FMODEX::mChannelGroups[getSource()->getType()]);
|
||||
}
|
||||
|
||||
|
||||
void LLAudioChannelFMODEX::playSynced(LLAudioChannel *channelp)
|
||||
{
|
||||
LLAudioChannelFMODEX *fmod_channelp = (LLAudioChannelFMODEX*)channelp;
|
||||
if (!(fmod_channelp->mChannelp && mChannelp))
|
||||
{
|
||||
// Don't have channels allocated to both the master and the slave
|
||||
return;
|
||||
}
|
||||
|
||||
U32 cur_pos;
|
||||
if(Check_FMOD_Error(mChannelp->getPosition(&cur_pos,FMOD_TIMEUNIT_PCMBYTES), "Unable to retrieve current position"))
|
||||
return;
|
||||
|
||||
cur_pos %= mCurrentBufferp->getLength();
|
||||
|
||||
// Try to match the position of our sync master
|
||||
Check_FMOD_Error(mChannelp->setPosition(cur_pos,FMOD_TIMEUNIT_PCMBYTES),"Unable to set current position");
|
||||
|
||||
// Start us playing
|
||||
play();
|
||||
}
|
||||
|
||||
|
||||
bool LLAudioChannelFMODEX::isPlaying()
|
||||
{
|
||||
if (!mChannelp)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool paused, playing;
|
||||
mChannelp->getPaused(&paused);
|
||||
mChannelp->isPlaying(&playing);
|
||||
return !paused && playing;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// LLAudioChannelFMODEX implementation
|
||||
//
|
||||
|
||||
|
||||
LLAudioBufferFMODEX::LLAudioBufferFMODEX(FMOD::System *system) : mSystemp(system), mSoundp(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
LLAudioBufferFMODEX::~LLAudioBufferFMODEX()
|
||||
{
|
||||
if(mSoundp)
|
||||
{
|
||||
mSoundp->release();
|
||||
mSoundp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool LLAudioBufferFMODEX::loadWAV(const std::string& filename)
|
||||
{
|
||||
// Try to open a wav file from disk. This will eventually go away, as we don't
|
||||
// really want to block doing this.
|
||||
if (filename.empty())
|
||||
{
|
||||
// invalid filename, abort.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!LLAPRFile::isExist(filename, NULL, LL_APR_RPB))
|
||||
{
|
||||
// File not found, abort.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mSoundp)
|
||||
{
|
||||
// If there's already something loaded in this buffer, clean it up.
|
||||
mSoundp->release();
|
||||
mSoundp = NULL;
|
||||
}
|
||||
|
||||
FMOD_MODE base_mode = FMOD_LOOP_NORMAL | FMOD_SOFTWARE;
|
||||
FMOD_CREATESOUNDEXINFO exinfo;
|
||||
memset(&exinfo,0,sizeof(exinfo));
|
||||
exinfo.cbsize = sizeof(exinfo);
|
||||
exinfo.suggestedsoundtype = FMOD_SOUND_TYPE_WAV; //Hint to speed up loading.
|
||||
// Load up the wav file into an fmod sample
|
||||
#if LL_WINDOWS
|
||||
FMOD_RESULT result = getSystem()->createSound((const char*)utf8str_to_utf16str(filename).c_str(), base_mode | FMOD_UNICODE, &exinfo, &mSoundp);
|
||||
#else
|
||||
FMOD_RESULT result = getSystem()->createSound(filename.c_str(), base_mode, &exinfo, &mSoundp);
|
||||
#endif
|
||||
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
// We failed to load the file for some reason.
|
||||
LL_WARNS() << "Could not load data '" << filename << "': " << FMOD_ErrorString(result) << LL_ENDL;
|
||||
|
||||
//
|
||||
// If we EVER want to load wav files provided by end users, we need
|
||||
// to rethink this!
|
||||
//
|
||||
// file is probably corrupt - remove it.
|
||||
LLFile::remove(filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Everything went well, return true
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
U32 LLAudioBufferFMODEX::getLength()
|
||||
{
|
||||
if (!mSoundp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
U32 length;
|
||||
mSoundp->getLength(&length, FMOD_TIMEUNIT_PCMBYTES);
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
void LLAudioChannelFMODEX::set3DMode(bool use3d)
|
||||
{
|
||||
FMOD_MODE current_mode;
|
||||
if(mChannelp->getMode(¤t_mode) != FMOD_OK)
|
||||
return;
|
||||
FMOD_MODE new_mode = current_mode;
|
||||
new_mode &= ~(use3d ? FMOD_2D : FMOD_3D);
|
||||
new_mode |= use3d ? FMOD_3D : FMOD_2D;
|
||||
|
||||
if(current_mode != new_mode)
|
||||
{
|
||||
mChannelp->setMode(new_mode);
|
||||
}
|
||||
}
|
||||
|
||||
// *NOTE: This is almost certainly being called on the mixer thread,
|
||||
// not the main thread. May have implications for callees or audio
|
||||
// engine shutdown.
|
||||
|
||||
FMOD_RESULT F_CALLBACK windCallback(FMOD_DSP_STATE *dsp_state, float *originalbuffer, float *newbuffer, unsigned int length, int inchannels, int outchannels)
|
||||
{
|
||||
// originalbuffer = fmod's original mixbuffer.
|
||||
// newbuffer = the buffer passed from the previous DSP unit.
|
||||
// length = length in samples at this mix time.
|
||||
// userdata = user parameter passed through in FSOUND_DSP_Create.
|
||||
|
||||
LLWindGen<LLAudioEngine_FMODEX::MIXBUFFERFORMAT> *windgen;
|
||||
FMOD::DSP *thisdsp = (FMOD::DSP *)dsp_state->instance;
|
||||
|
||||
thisdsp->getUserData((void **)&windgen);
|
||||
S32 channels, configwidth, configheight;
|
||||
thisdsp->getInfo(0, 0, &channels, &configwidth, &configheight);
|
||||
|
||||
windgen->windGenerate((LLAudioEngine_FMODEX::MIXBUFFERFORMAT *)newbuffer, length);
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
|
@ -0,0 +1,753 @@
|
|||
/**
|
||||
* @file audioengine_fmodstudio.cpp
|
||||
* @brief Implementation of LLAudioEngine class abstracting the audio
|
||||
* support as a FMODSTUDIO implementation
|
||||
*
|
||||
* $LicenseInfo:firstyear=2020&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2020, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "llstreamingaudio.h"
|
||||
#include "llstreamingaudio_fmodstudio.h"
|
||||
|
||||
#include "llaudioengine_fmodstudio.h"
|
||||
#include "lllistener_fmodstudio.h"
|
||||
|
||||
#include "llerror.h"
|
||||
#include "llmath.h"
|
||||
#include "llrand.h"
|
||||
|
||||
#include "fmodstudio/fmod.hpp"
|
||||
#include "fmodstudio/fmod_errors.h"
|
||||
#include "lldir.h"
|
||||
#include "llapr.h"
|
||||
|
||||
#include "sound_ids.h"
|
||||
|
||||
FMOD_RESULT F_CALLBACK windCallback(FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int *outchannels);
|
||||
|
||||
FMOD::ChannelGroup *LLAudioEngine_FMODSTUDIO::mChannelGroups[LLAudioEngine::AUDIO_TYPE_COUNT] = {0};
|
||||
|
||||
LLAudioEngine_FMODSTUDIO::LLAudioEngine_FMODSTUDIO(bool enable_profiler)
|
||||
: mInited(false),
|
||||
mWindGen(NULL),
|
||||
mWindDSP(NULL),
|
||||
mSystem(NULL),
|
||||
mEnableProfiler(enable_profiler),
|
||||
mWindDSPDesc(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
LLAudioEngine_FMODSTUDIO::~LLAudioEngine_FMODSTUDIO()
|
||||
{
|
||||
// mWindDSPDesc, mWindGen and mWindDSP get cleaned up on cleanupWind in LLAudioEngine::shutdown()
|
||||
// mSystem gets cleaned up at shutdown()
|
||||
}
|
||||
|
||||
|
||||
static inline bool Check_FMOD_Error(FMOD_RESULT result, const char *string)
|
||||
{
|
||||
if (result == FMOD_OK)
|
||||
return false;
|
||||
LL_DEBUGS("FMOD") << string << " Error: " << FMOD_ErrorString(result) << LL_ENDL;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata, const std::string &app_title)
|
||||
{
|
||||
U32 version;
|
||||
FMOD_RESULT result;
|
||||
|
||||
LL_DEBUGS("AppInit") << "LLAudioEngine_FMODSTUDIO::init() initializing FMOD" << LL_ENDL;
|
||||
|
||||
result = FMOD::System_Create(&mSystem);
|
||||
if (Check_FMOD_Error(result, "FMOD::System_Create"))
|
||||
return false;
|
||||
|
||||
//will call LLAudioEngine_FMODSTUDIO::allocateListener, which needs a valid mSystem pointer.
|
||||
LLAudioEngine::init(num_channels, userdata, app_title);
|
||||
|
||||
result = mSystem->getVersion(&version);
|
||||
Check_FMOD_Error(result, "FMOD::System::getVersion");
|
||||
|
||||
if (version < FMOD_VERSION)
|
||||
{
|
||||
LL_WARNS("AppInit") << "FMOD Studio version mismatch, actual: " << version
|
||||
<< " expected:" << FMOD_VERSION << LL_ENDL;
|
||||
}
|
||||
|
||||
// In this case, all sounds, PLUS wind and stream will be software.
|
||||
result = mSystem->setSoftwareChannels(num_channels + 2);
|
||||
Check_FMOD_Error(result, "FMOD::System::setSoftwareChannels");
|
||||
|
||||
FMOD_ADVANCEDSETTINGS settings;
|
||||
memset(&settings, 0, sizeof(settings));
|
||||
settings.cbSize = sizeof(FMOD_ADVANCEDSETTINGS);
|
||||
settings.resamplerMethod = FMOD_DSP_RESAMPLER_LINEAR;
|
||||
|
||||
result = mSystem->setAdvancedSettings(&settings);
|
||||
Check_FMOD_Error(result, "FMOD::System::setAdvancedSettings");
|
||||
|
||||
// FMOD_INIT_THREAD_UNSAFE Disables thread safety for API calls.
|
||||
// Only use this if FMOD is being called from a single thread, and if Studio API is not being used.
|
||||
U32 fmod_flags = FMOD_INIT_NORMAL | FMOD_INIT_3D_RIGHTHANDED | FMOD_INIT_THREAD_UNSAFE;
|
||||
if (mEnableProfiler)
|
||||
{
|
||||
fmod_flags |= FMOD_INIT_PROFILE_ENABLE;
|
||||
}
|
||||
|
||||
#if LL_LINUX
|
||||
bool audio_ok = false;
|
||||
|
||||
if (!audio_ok)
|
||||
{
|
||||
const char* env_string = getenv("LL_BAD_FMOD_PULSEAUDIO");
|
||||
if (NULL == env_string)
|
||||
{
|
||||
LL_DEBUGS("AppInit") << "Trying PulseAudio audio output..." << LL_ENDL;
|
||||
if (mSystem->setOutput(FMOD_OUTPUTTYPE_PULSEAUDIO) == FMOD_OK &&
|
||||
(result = mSystem->init(num_channels + 2, fmod_flags, const_cast<char*>(app_title.c_str()))) == FMOD_OK)
|
||||
{
|
||||
LL_DEBUGS("AppInit") << "PulseAudio output initialized OKAY" << LL_ENDL;
|
||||
audio_ok = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Check_FMOD_Error(result, "PulseAudio audio output FAILED to initialize");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_DEBUGS("AppInit") << "PulseAudio audio output SKIPPED" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
if (!audio_ok)
|
||||
{
|
||||
const char* env_string = getenv("LL_BAD_FMOD_ALSA");
|
||||
if (NULL == env_string)
|
||||
{
|
||||
LL_DEBUGS("AppInit") << "Trying ALSA audio output..." << LL_ENDL;
|
||||
if (mSystem->setOutput(FMOD_OUTPUTTYPE_ALSA) == FMOD_OK &&
|
||||
(result = mSystem->init(num_channels + 2, fmod_flags, 0)) == FMOD_OK)
|
||||
{
|
||||
LL_DEBUGS("AppInit") << "ALSA audio output initialized OKAY" << LL_ENDL;
|
||||
audio_ok = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Check_FMOD_Error(result, "ALSA audio output FAILED to initialize");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_DEBUGS("AppInit") << "ALSA audio output SKIPPED" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
if (!audio_ok)
|
||||
{
|
||||
LL_WARNS("AppInit") << "Overall audio init failure." << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
|
||||
// We're interested in logging which output method we
|
||||
// ended up with, for QA purposes.
|
||||
FMOD_OUTPUTTYPE output_type;
|
||||
mSystem->getOutput(&output_type);
|
||||
switch (output_type)
|
||||
{
|
||||
case FMOD_OUTPUTTYPE_NOSOUND:
|
||||
LL_INFOS("AppInit") << "Audio output: NoSound" << LL_ENDL; break;
|
||||
case FMOD_OUTPUTTYPE_PULSEAUDIO:
|
||||
LL_INFOS("AppInit") << "Audio output: PulseAudio" << LL_ENDL; break;
|
||||
case FMOD_OUTPUTTYPE_ALSA:
|
||||
LL_INFOS("AppInit") << "Audio output: ALSA" << LL_ENDL; break;
|
||||
default:
|
||||
LL_INFOS("AppInit") << "Audio output: Unknown!" << LL_ENDL; break;
|
||||
};
|
||||
#else // LL_LINUX
|
||||
|
||||
// initialize the FMOD engine
|
||||
// number of channel in this case looks to be identiacal to number of max simultaneously
|
||||
// playing objects and we can set practically any number
|
||||
result = mSystem->init(num_channels + 2, fmod_flags, 0);
|
||||
if (Check_FMOD_Error(result, "Error initializing FMOD Studio with default settins, retrying with other format"))
|
||||
{
|
||||
result = mSystem->setSoftwareFormat(44100, FMOD_SPEAKERMODE_STEREO, 0/*- ignore*/);
|
||||
if (Check_FMOD_Error(result, "Error setting sotware format. Can't init."))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
result = mSystem->init(num_channels + 2, fmod_flags, 0);
|
||||
}
|
||||
if (Check_FMOD_Error(result, "Error initializing FMOD Studio"))
|
||||
{
|
||||
// If it fails here and (result == FMOD_ERR_OUTPUT_CREATEBUFFER),
|
||||
// we can retry with other settings
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// set up our favourite FMOD-native streaming audio implementation if none has already been added
|
||||
if (!getStreamingAudioImpl()) // no existing implementation added
|
||||
setStreamingAudioImpl(new LLStreamingAudio_FMODSTUDIO(mSystem));
|
||||
|
||||
LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::init() FMOD Studio initialized correctly" << LL_ENDL;
|
||||
|
||||
int r_numbuffers, r_samplerate, r_channels;
|
||||
unsigned int r_bufferlength;
|
||||
char r_name[512];
|
||||
int latency = 100;
|
||||
mSystem->getDSPBufferSize(&r_bufferlength, &r_numbuffers);
|
||||
LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::init(): r_bufferlength=" << r_bufferlength << " bytes" << LL_ENDL;
|
||||
LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::init(): r_numbuffers=" << r_numbuffers << LL_ENDL;
|
||||
|
||||
mSystem->getDriverInfo(0, r_name, 511, NULL, &r_samplerate, NULL, &r_channels);
|
||||
r_name[511] = '\0';
|
||||
LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::init(): r_name=\"" << r_name << "\"" << LL_ENDL;
|
||||
|
||||
if (r_samplerate != 0)
|
||||
latency = (int)(1000.0f * r_bufferlength * r_numbuffers / r_samplerate);
|
||||
LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::init(): latency=" << latency << "ms" << LL_ENDL;
|
||||
|
||||
mInited = true;
|
||||
|
||||
LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::init(): initialization complete." << LL_ENDL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
std::string LLAudioEngine_FMODSTUDIO::getDriverName(bool verbose)
|
||||
{
|
||||
llassert_always(mSystem);
|
||||
if (verbose)
|
||||
{
|
||||
U32 version;
|
||||
if (!Check_FMOD_Error(mSystem->getVersion(&version), "FMOD::System::getVersion"))
|
||||
{
|
||||
return llformat("FMOD Studio %1x.%02x.%02x", version >> 16, version >> 8 & 0x000000FF, version & 0x000000FF);
|
||||
}
|
||||
}
|
||||
return "FMOD STUDIO";
|
||||
}
|
||||
|
||||
|
||||
void LLAudioEngine_FMODSTUDIO::allocateListener(void)
|
||||
{
|
||||
mListenerp = (LLListener *) new LLListener_FMODSTUDIO(mSystem);
|
||||
if (!mListenerp)
|
||||
{
|
||||
LL_WARNS("FMOD") << "Listener creation failed" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LLAudioEngine_FMODSTUDIO::shutdown()
|
||||
{
|
||||
stopInternetStream();
|
||||
|
||||
LL_INFOS("FMOD") << "About to LLAudioEngine::shutdown()" << LL_ENDL;
|
||||
LLAudioEngine::shutdown();
|
||||
|
||||
LL_INFOS("FMOD") << "LLAudioEngine_FMODSTUDIO::shutdown() closing FMOD Studio" << LL_ENDL;
|
||||
if (mSystem)
|
||||
{
|
||||
mSystem->close();
|
||||
mSystem->release();
|
||||
}
|
||||
LL_INFOS("FMOD") << "LLAudioEngine_FMODSTUDIO::shutdown() done closing FMOD Studio" << LL_ENDL;
|
||||
|
||||
delete mListenerp;
|
||||
mListenerp = NULL;
|
||||
}
|
||||
|
||||
|
||||
LLAudioBuffer * LLAudioEngine_FMODSTUDIO::createBuffer()
|
||||
{
|
||||
return new LLAudioBufferFMODSTUDIO(mSystem);
|
||||
}
|
||||
|
||||
|
||||
LLAudioChannel * LLAudioEngine_FMODSTUDIO::createChannel()
|
||||
{
|
||||
return new LLAudioChannelFMODSTUDIO(mSystem);
|
||||
}
|
||||
|
||||
bool LLAudioEngine_FMODSTUDIO::initWind()
|
||||
{
|
||||
mNextWindUpdate = 0.0;
|
||||
|
||||
if (!mWindDSPDesc)
|
||||
{
|
||||
mWindDSPDesc = new FMOD_DSP_DESCRIPTION();
|
||||
}
|
||||
|
||||
if (!mWindDSP)
|
||||
{
|
||||
memset(mWindDSPDesc, 0, sizeof(*mWindDSPDesc)); //Set everything to zero
|
||||
strncpy(mWindDSPDesc->name, "Wind Unit", sizeof(mWindDSPDesc->name));
|
||||
mWindDSPDesc->pluginsdkversion = FMOD_PLUGIN_SDK_VERSION;
|
||||
mWindDSPDesc->read = &windCallback; // Assign callback - may be called from arbitrary threads
|
||||
if (Check_FMOD_Error(mSystem->createDSP(mWindDSPDesc, &mWindDSP), "FMOD::createDSP"))
|
||||
return false;
|
||||
|
||||
if (mWindGen)
|
||||
delete mWindGen;
|
||||
|
||||
int frequency = 44100;
|
||||
|
||||
FMOD_SPEAKERMODE mode;
|
||||
if (Check_FMOD_Error(mSystem->getSoftwareFormat(&frequency, &mode, nullptr), "FMOD::System::getSoftwareFormat"))
|
||||
{
|
||||
cleanupWind();
|
||||
return false;
|
||||
}
|
||||
|
||||
mWindGen = new LLWindGen<MIXBUFFERFORMAT>((U32)frequency);
|
||||
|
||||
if (Check_FMOD_Error(mWindDSP->setUserData((void*)mWindGen), "FMOD::DSP::setUserData"))
|
||||
{
|
||||
cleanupWind();
|
||||
return false;
|
||||
}
|
||||
if (Check_FMOD_Error(mWindDSP->setChannelFormat(FMOD_CHANNELMASK_STEREO, 2, mode), "FMOD::DSP::setChannelFormat"))
|
||||
{
|
||||
cleanupWind();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// *TODO: Should this guard against multiple plays?
|
||||
if (Check_FMOD_Error(mSystem->playDSP(mWindDSP, nullptr, false, nullptr), "FMOD::System::playDSP"))
|
||||
{
|
||||
cleanupWind();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void LLAudioEngine_FMODSTUDIO::cleanupWind()
|
||||
{
|
||||
if (mWindDSP)
|
||||
{
|
||||
FMOD::ChannelGroup* master_group = NULL;
|
||||
if (!Check_FMOD_Error(mSystem->getMasterChannelGroup(&master_group), "FMOD::System::getMasterChannelGroup")
|
||||
&& master_group)
|
||||
{
|
||||
master_group->removeDSP(mWindDSP);
|
||||
}
|
||||
mWindDSP->release();
|
||||
mWindDSP = NULL;
|
||||
}
|
||||
|
||||
delete mWindDSPDesc;
|
||||
mWindDSPDesc = NULL;
|
||||
|
||||
delete mWindGen;
|
||||
mWindGen = NULL;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
void LLAudioEngine_FMODSTUDIO::updateWind(LLVector3 wind_vec, F32 camera_height_above_water)
|
||||
{
|
||||
LLVector3 wind_pos;
|
||||
F64 pitch;
|
||||
F64 center_freq;
|
||||
|
||||
if (!mEnableWind)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (mWindUpdateTimer.checkExpirationAndReset(LL_WIND_UPDATE_INTERVAL))
|
||||
{
|
||||
|
||||
// wind comes in as Linden coordinate (+X = forward, +Y = left, +Z = up)
|
||||
// need to convert this to the conventional orientation DS3D and OpenAL use
|
||||
// where +X = right, +Y = up, +Z = backwards
|
||||
|
||||
wind_vec.setVec(-wind_vec.mV[1], wind_vec.mV[2], -wind_vec.mV[0]);
|
||||
|
||||
// cerr << "Wind update" << endl;
|
||||
|
||||
pitch = 1.0 + mapWindVecToPitch(wind_vec);
|
||||
center_freq = 80.0 * pow(pitch, 2.5*(mapWindVecToGain(wind_vec) + 1.0));
|
||||
|
||||
mWindGen->mTargetFreq = (F32)center_freq;
|
||||
mWindGen->mTargetGain = (F32)mapWindVecToGain(wind_vec) * mMaxWindGain;
|
||||
mWindGen->mTargetPanGainR = (F32)mapWindVecToPan(wind_vec);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
void LLAudioEngine_FMODSTUDIO::setInternalGain(F32 gain)
|
||||
{
|
||||
if (!mInited)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
gain = llclamp(gain, 0.0f, 1.0f);
|
||||
|
||||
FMOD::ChannelGroup* master_group = NULL;
|
||||
if (!Check_FMOD_Error(mSystem->getMasterChannelGroup(&master_group), "FMOD::System::getMasterChannelGroup")
|
||||
&& master_group)
|
||||
{
|
||||
master_group->setVolume(gain);
|
||||
}
|
||||
|
||||
LLStreamingAudioInterface *saimpl = getStreamingAudioImpl();
|
||||
if (saimpl)
|
||||
{
|
||||
// fmod likes its streaming audio channel gain re-asserted after
|
||||
// master volume change.
|
||||
saimpl->setGain(saimpl->getGain());
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// LLAudioChannelFMODSTUDIO implementation
|
||||
//
|
||||
|
||||
LLAudioChannelFMODSTUDIO::LLAudioChannelFMODSTUDIO(FMOD::System *system) : LLAudioChannel(), mSystemp(system), mChannelp(NULL), mLastSamplePos(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
LLAudioChannelFMODSTUDIO::~LLAudioChannelFMODSTUDIO()
|
||||
{
|
||||
cleanup();
|
||||
}
|
||||
|
||||
bool LLAudioChannelFMODSTUDIO::updateBuffer()
|
||||
{
|
||||
if (!mCurrentSourcep)
|
||||
{
|
||||
// This channel isn't associated with any source, nothing
|
||||
// to be updated
|
||||
return false;
|
||||
}
|
||||
|
||||
if (LLAudioChannel::updateBuffer())
|
||||
{
|
||||
// Base class update returned true, which means that we need to actually
|
||||
// set up the channel for a different buffer.
|
||||
|
||||
LLAudioBufferFMODSTUDIO *bufferp = (LLAudioBufferFMODSTUDIO *)mCurrentSourcep->getCurrentBuffer();
|
||||
|
||||
// Grab the FMOD sample associated with the buffer
|
||||
FMOD::Sound *soundp = bufferp->getSound();
|
||||
if (!soundp)
|
||||
{
|
||||
// This is bad, there should ALWAYS be a sound associated with a legit
|
||||
// buffer.
|
||||
LL_ERRS() << "No FMOD sound!" << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Actually play the sound. Start it off paused so we can do all the necessary
|
||||
// setup.
|
||||
if (!mChannelp)
|
||||
{
|
||||
FMOD_RESULT result = getSystem()->playSound(soundp, NULL /*free channel?*/, true, &mChannelp);
|
||||
Check_FMOD_Error(result, "FMOD::System::playSound");
|
||||
}
|
||||
|
||||
// Setting up channel mChannelID
|
||||
}
|
||||
|
||||
// If we have a source for the channel, we need to update its gain.
|
||||
if (mCurrentSourcep)
|
||||
{
|
||||
// SJB: warnings can spam and hurt framerate, disabling
|
||||
//FMOD_RESULT result;
|
||||
|
||||
mChannelp->setVolume(getSecondaryGain() * mCurrentSourcep->getGain());
|
||||
//Check_FMOD_Error(result, "FMOD::Channel::setVolume");
|
||||
|
||||
mChannelp->setMode(mCurrentSourcep->isLoop() ? FMOD_LOOP_NORMAL : FMOD_LOOP_OFF);
|
||||
/*if(Check_FMOD_Error(result, "FMOD::Channel::setMode"))
|
||||
{
|
||||
S32 index;
|
||||
mChannelp->getIndex(&index);
|
||||
LL_WARNS() << "Channel " << index << "Source ID: " << mCurrentSourcep->getID()
|
||||
<< " at " << mCurrentSourcep->getPositionGlobal() << LL_ENDL;
|
||||
}*/
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void LLAudioChannelFMODSTUDIO::update3DPosition()
|
||||
{
|
||||
if (!mChannelp)
|
||||
{
|
||||
// We're not actually a live channel (i.e., we're not playing back anything)
|
||||
return;
|
||||
}
|
||||
|
||||
LLAudioBufferFMODSTUDIO *bufferp = (LLAudioBufferFMODSTUDIO *)mCurrentBufferp;
|
||||
if (!bufferp)
|
||||
{
|
||||
// We don't have a buffer associated with us (should really have been picked up
|
||||
// by the above if.
|
||||
return;
|
||||
}
|
||||
|
||||
if (mCurrentSourcep->isAmbient())
|
||||
{
|
||||
// Ambient sound, don't need to do any positional updates.
|
||||
set3DMode(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Localized sound. Update the position and velocity of the sound.
|
||||
set3DMode(true);
|
||||
|
||||
LLVector3 float_pos;
|
||||
float_pos.setVec(mCurrentSourcep->getPositionGlobal());
|
||||
FMOD_RESULT result = mChannelp->set3DAttributes((FMOD_VECTOR*)float_pos.mV, (FMOD_VECTOR*)mCurrentSourcep->getVelocity().mV);
|
||||
Check_FMOD_Error(result, "FMOD::Channel::set3DAttributes");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LLAudioChannelFMODSTUDIO::updateLoop()
|
||||
{
|
||||
if (!mChannelp)
|
||||
{
|
||||
// May want to clear up the loop/sample counters.
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Hack: We keep track of whether we looped or not by seeing when the
|
||||
// sample position looks like it's going backwards. Not reliable; may
|
||||
// yield false negatives.
|
||||
//
|
||||
U32 cur_pos;
|
||||
mChannelp->getPosition(&cur_pos, FMOD_TIMEUNIT_PCMBYTES);
|
||||
|
||||
if (cur_pos < (U32)mLastSamplePos)
|
||||
{
|
||||
mLoopedThisFrame = true;
|
||||
}
|
||||
mLastSamplePos = cur_pos;
|
||||
}
|
||||
|
||||
|
||||
void LLAudioChannelFMODSTUDIO::cleanup()
|
||||
{
|
||||
if (!mChannelp)
|
||||
{
|
||||
// Aborting cleanup with no channel handle.
|
||||
return;
|
||||
}
|
||||
|
||||
//Cleaning up channel mChannelID
|
||||
Check_FMOD_Error(mChannelp->stop(), "FMOD::Channel::stop");
|
||||
|
||||
mCurrentBufferp = NULL;
|
||||
mChannelp = NULL;
|
||||
}
|
||||
|
||||
|
||||
void LLAudioChannelFMODSTUDIO::play()
|
||||
{
|
||||
if (!mChannelp)
|
||||
{
|
||||
LL_WARNS() << "Playing without a channel handle, aborting" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
Check_FMOD_Error(mChannelp->setPaused(false), "FMOD::Channel::pause");
|
||||
|
||||
getSource()->setPlayedOnce(true);
|
||||
|
||||
if (LLAudioEngine_FMODSTUDIO::mChannelGroups[getSource()->getType()])
|
||||
mChannelp->setChannelGroup(LLAudioEngine_FMODSTUDIO::mChannelGroups[getSource()->getType()]);
|
||||
}
|
||||
|
||||
|
||||
void LLAudioChannelFMODSTUDIO::playSynced(LLAudioChannel *channelp)
|
||||
{
|
||||
LLAudioChannelFMODSTUDIO *fmod_channelp = (LLAudioChannelFMODSTUDIO*)channelp;
|
||||
if (!(fmod_channelp->mChannelp && mChannelp))
|
||||
{
|
||||
// Don't have channels allocated to both the master and the slave
|
||||
return;
|
||||
}
|
||||
|
||||
U32 cur_pos;
|
||||
if (Check_FMOD_Error(mChannelp->getPosition(&cur_pos, FMOD_TIMEUNIT_PCMBYTES), "Unable to retrieve current position"))
|
||||
return;
|
||||
|
||||
cur_pos %= mCurrentBufferp->getLength();
|
||||
|
||||
// Try to match the position of our sync master
|
||||
Check_FMOD_Error(mChannelp->setPosition(cur_pos, FMOD_TIMEUNIT_PCMBYTES), "Unable to set current position");
|
||||
|
||||
// Start us playing
|
||||
play();
|
||||
}
|
||||
|
||||
|
||||
bool LLAudioChannelFMODSTUDIO::isPlaying()
|
||||
{
|
||||
if (!mChannelp)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool paused, playing;
|
||||
mChannelp->getPaused(&paused);
|
||||
mChannelp->isPlaying(&playing);
|
||||
return !paused && playing;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// LLAudioChannelFMODSTUDIO implementation
|
||||
//
|
||||
|
||||
|
||||
LLAudioBufferFMODSTUDIO::LLAudioBufferFMODSTUDIO(FMOD::System *system) : mSystemp(system), mSoundp(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
LLAudioBufferFMODSTUDIO::~LLAudioBufferFMODSTUDIO()
|
||||
{
|
||||
if (mSoundp)
|
||||
{
|
||||
mSoundp->release();
|
||||
mSoundp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool LLAudioBufferFMODSTUDIO::loadWAV(const std::string& filename)
|
||||
{
|
||||
// Try to open a wav file from disk. This will eventually go away, as we don't
|
||||
// really want to block doing this.
|
||||
if (filename.empty())
|
||||
{
|
||||
// invalid filename, abort.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!LLAPRFile::isExist(filename, NULL, LL_APR_RPB))
|
||||
{
|
||||
// File not found, abort.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mSoundp)
|
||||
{
|
||||
// If there's already something loaded in this buffer, clean it up.
|
||||
mSoundp->release();
|
||||
mSoundp = NULL;
|
||||
}
|
||||
|
||||
FMOD_MODE base_mode = FMOD_LOOP_NORMAL;
|
||||
FMOD_CREATESOUNDEXINFO exinfo;
|
||||
memset(&exinfo, 0, sizeof(exinfo));
|
||||
exinfo.cbsize = sizeof(exinfo);
|
||||
exinfo.suggestedsoundtype = FMOD_SOUND_TYPE_WAV; //Hint to speed up loading.
|
||||
// Load up the wav file into an fmod sample (since 1.05 fmod studio expects everything in UTF-8)
|
||||
FMOD_RESULT result = getSystem()->createSound(filename.c_str(), base_mode, &exinfo, &mSoundp);
|
||||
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
// We failed to load the file for some reason.
|
||||
LL_WARNS() << "Could not load data '" << filename << "': " << FMOD_ErrorString(result) << LL_ENDL;
|
||||
|
||||
//
|
||||
// If we EVER want to load wav files provided by end users, we need
|
||||
// to rethink this!
|
||||
//
|
||||
// file is probably corrupt - remove it.
|
||||
LLFile::remove(filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Everything went well, return true
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
U32 LLAudioBufferFMODSTUDIO::getLength()
|
||||
{
|
||||
if (!mSoundp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
U32 length;
|
||||
mSoundp->getLength(&length, FMOD_TIMEUNIT_PCMBYTES);
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
void LLAudioChannelFMODSTUDIO::set3DMode(bool use3d)
|
||||
{
|
||||
FMOD_MODE current_mode;
|
||||
if (mChannelp->getMode(¤t_mode) != FMOD_OK)
|
||||
return;
|
||||
FMOD_MODE new_mode = current_mode;
|
||||
new_mode &= ~(use3d ? FMOD_2D : FMOD_3D);
|
||||
new_mode |= use3d ? FMOD_3D : FMOD_2D;
|
||||
|
||||
if (current_mode != new_mode)
|
||||
{
|
||||
mChannelp->setMode(new_mode);
|
||||
}
|
||||
}
|
||||
|
||||
// *NOTE: This is almost certainly being called on the mixer thread,
|
||||
// not the main thread. May have implications for callees or audio
|
||||
// engine shutdown.
|
||||
|
||||
FMOD_RESULT F_CALLBACK windCallback(FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int *outchannels)
|
||||
{
|
||||
// inbuffer = fmod's original mixbuffer.
|
||||
// outbuffer = the buffer passed from the previous DSP unit.
|
||||
// length = length in samples at this mix time.
|
||||
|
||||
LLWindGen<LLAudioEngine_FMODSTUDIO::MIXBUFFERFORMAT> *windgen = NULL;
|
||||
FMOD::DSP *thisdsp = (FMOD::DSP *)dsp_state->instance;
|
||||
|
||||
thisdsp->getUserData((void **)&windgen);
|
||||
|
||||
if (windgen)
|
||||
{
|
||||
windgen->windGenerate((LLAudioEngine_FMODSTUDIO::MIXBUFFERFORMAT *)outbuffer, length);
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
/**
|
||||
* @file audioengine_fmodex.h
|
||||
* @file audioengine_fmodstudio.h
|
||||
* @brief Definition of LLAudioEngine class abstracting the audio
|
||||
* support as a FMODEX implementation
|
||||
* support as a FMODSTUDIO implementation
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
|
||||
* $LicenseInfo:firstyear=2020&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2014, Linden Research, Inc.
|
||||
* Copyright (C) 2020, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
|
@ -25,14 +25,14 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_AUDIOENGINE_FMODEX_H
|
||||
#define LL_AUDIOENGINE_FMODEX_H
|
||||
#ifndef LL_AUDIOENGINE_FMODSTUDIO_H
|
||||
#define LL_AUDIOENGINE_FMODSTUDIO_H
|
||||
|
||||
#include "llaudioengine.h"
|
||||
#include "llwindgen.h"
|
||||
|
||||
//Stubs
|
||||
class LLAudioStreamManagerFMODEX;
|
||||
class LLAudioStreamManagerFMODSTUDIO;
|
||||
namespace FMOD
|
||||
{
|
||||
class System;
|
||||
|
|
@ -44,14 +44,14 @@ namespace FMOD
|
|||
typedef struct FMOD_DSP_DESCRIPTION FMOD_DSP_DESCRIPTION;
|
||||
|
||||
//Interfaces
|
||||
class LLAudioEngine_FMODEX : public LLAudioEngine
|
||||
class LLAudioEngine_FMODSTUDIO : public LLAudioEngine
|
||||
{
|
||||
public:
|
||||
LLAudioEngine_FMODEX(bool enable_profiler);
|
||||
virtual ~LLAudioEngine_FMODEX();
|
||||
LLAudioEngine_FMODSTUDIO(bool enable_profiler);
|
||||
virtual ~LLAudioEngine_FMODSTUDIO();
|
||||
|
||||
// initialization/startup/shutdown
|
||||
virtual bool init(const S32 num_channels, void *user_data);
|
||||
virtual bool init(const S32 num_channels, void *user_data, const std::string &app_title);
|
||||
virtual std::string getDriverName(bool verbose);
|
||||
virtual void allocateListener();
|
||||
|
||||
|
|
@ -85,11 +85,11 @@ public:
|
|||
};
|
||||
|
||||
|
||||
class LLAudioChannelFMODEX : public LLAudioChannel
|
||||
class LLAudioChannelFMODSTUDIO : public LLAudioChannel
|
||||
{
|
||||
public:
|
||||
LLAudioChannelFMODEX(FMOD::System *audioengine);
|
||||
virtual ~LLAudioChannelFMODEX();
|
||||
LLAudioChannelFMODSTUDIO(FMOD::System *audioengine);
|
||||
virtual ~LLAudioChannelFMODSTUDIO();
|
||||
|
||||
protected:
|
||||
/*virtual*/ void play();
|
||||
|
|
@ -110,15 +110,15 @@ protected:
|
|||
};
|
||||
|
||||
|
||||
class LLAudioBufferFMODEX : public LLAudioBuffer
|
||||
class LLAudioBufferFMODSTUDIO : public LLAudioBuffer
|
||||
{
|
||||
public:
|
||||
LLAudioBufferFMODEX(FMOD::System *audioengine);
|
||||
virtual ~LLAudioBufferFMODEX();
|
||||
LLAudioBufferFMODSTUDIO(FMOD::System *audioengine);
|
||||
virtual ~LLAudioBufferFMODSTUDIO();
|
||||
|
||||
/*virtual*/ bool loadWAV(const std::string& filename);
|
||||
/*virtual*/ U32 getLength();
|
||||
friend class LLAudioChannelFMODEX;
|
||||
friend class LLAudioChannelFMODSTUDIO;
|
||||
protected:
|
||||
FMOD::System *getSystem() const {return mSystemp;}
|
||||
FMOD::System *mSystemp;
|
||||
|
|
@ -127,4 +127,4 @@ protected:
|
|||
};
|
||||
|
||||
|
||||
#endif // LL_AUDIOENGINE_FMODEX_H
|
||||
#endif // LL_AUDIOENGINE_FMODSTUDIO_H
|
||||
|
|
@ -52,7 +52,7 @@ LLAudioEngine_OpenAL::~LLAudioEngine_OpenAL()
|
|||
}
|
||||
|
||||
// virtual
|
||||
bool LLAudioEngine_OpenAL::init(const S32 num_channels, void* userdata)
|
||||
bool LLAudioEngine_OpenAL::init(const S32 num_channels, void* userdata, const std::string &app_title)
|
||||
{
|
||||
mWindGen = NULL;
|
||||
LLAudioEngine::init(num_channels, userdata);
|
||||
|
|
@ -239,6 +239,13 @@ bool LLAudioChannelOpenAL::isPlaying()
|
|||
|
||||
bool LLAudioChannelOpenAL::updateBuffer()
|
||||
{
|
||||
if (!mCurrentSourcep)
|
||||
{
|
||||
// This channel isn't associated with any source, nothing
|
||||
// to be updated
|
||||
return false;
|
||||
}
|
||||
|
||||
if (LLAudioChannel::updateBuffer())
|
||||
{
|
||||
// Base class update returned true, which means that we need to actually
|
||||
|
|
|
|||
|
|
@ -40,8 +40,8 @@ class LLAudioEngine_OpenAL : public LLAudioEngine
|
|||
LLAudioEngine_OpenAL();
|
||||
virtual ~LLAudioEngine_OpenAL();
|
||||
|
||||
virtual bool init(const S32 num_channels, void *user_data);
|
||||
virtual std::string getDriverName(bool verbose);
|
||||
virtual bool init(const S32 num_channels, void *user_data, const std::string &app_title);
|
||||
virtual std::string getDriverName(bool verbose);
|
||||
virtual void allocateListener();
|
||||
|
||||
virtual void shutdown();
|
||||
|
|
|
|||
|
|
@ -1,140 +0,0 @@
|
|||
/**
|
||||
* @file listener_fmodex.cpp
|
||||
* @brief Implementation of LISTENER class abstracting the audio
|
||||
* support as a FMODEX implementation
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "linden_common.h"
|
||||
#include "llaudioengine.h"
|
||||
#include "lllistener_fmodex.h"
|
||||
#include "fmod.hpp"
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// constructor
|
||||
//-----------------------------------------------------------------------
|
||||
LLListener_FMODEX::LLListener_FMODEX(FMOD::System *system)
|
||||
{
|
||||
mSystem = system;
|
||||
init();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
LLListener_FMODEX::~LLListener_FMODEX()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
void LLListener_FMODEX::init(void)
|
||||
{
|
||||
// do inherited
|
||||
LLListener::init();
|
||||
mDopplerFactor = 1.0f;
|
||||
mRolloffFactor = 1.0f;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
void LLListener_FMODEX::translate(LLVector3 offset)
|
||||
{
|
||||
LLListener::translate(offset);
|
||||
|
||||
mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)mPosition.mV, NULL, (FMOD_VECTOR*)mListenAt.mV, (FMOD_VECTOR*)mListenUp.mV);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
void LLListener_FMODEX::setPosition(LLVector3 pos)
|
||||
{
|
||||
LLListener::setPosition(pos);
|
||||
|
||||
mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)mPosition.mV, NULL, (FMOD_VECTOR*)mListenAt.mV, (FMOD_VECTOR*)mListenUp.mV);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
void LLListener_FMODEX::setVelocity(LLVector3 vel)
|
||||
{
|
||||
LLListener::setVelocity(vel);
|
||||
|
||||
mSystem->set3DListenerAttributes(0, NULL, (FMOD_VECTOR*)mVelocity.mV, (FMOD_VECTOR*)mListenAt.mV, (FMOD_VECTOR*)mListenUp.mV);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
void LLListener_FMODEX::orient(LLVector3 up, LLVector3 at)
|
||||
{
|
||||
LLListener::orient(up, at);
|
||||
|
||||
// Welcome to the transition between right and left
|
||||
// (coordinate systems, that is)
|
||||
// Leaving the at vector alone results in a L/R reversal
|
||||
// since DX is left-handed and we (LL, OpenGL, OpenAL) are right-handed
|
||||
at = -at;
|
||||
|
||||
mSystem->set3DListenerAttributes(0, NULL, NULL, (FMOD_VECTOR*)at.mV, (FMOD_VECTOR*)up.mV);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
void LLListener_FMODEX::commitDeferredChanges()
|
||||
{
|
||||
if(!mSystem)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mSystem->update();
|
||||
}
|
||||
|
||||
|
||||
void LLListener_FMODEX::setRolloffFactor(F32 factor)
|
||||
{
|
||||
//An internal FMODEx optimization skips 3D updates if there have not been changes to the 3D sound environment.
|
||||
//Sadly, a change in rolloff is not accounted for, thus we must touch the listener properties as well.
|
||||
//In short: Changing the position ticks a dirtyflag inside fmodex, which makes it not skip 3D processing next update call.
|
||||
if(mRolloffFactor != factor)
|
||||
{
|
||||
LLVector3 pos = mVelocity - LLVector3(0.f,0.f,.1f);
|
||||
mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)pos.mV, NULL, NULL, NULL);
|
||||
mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)mVelocity.mV, NULL, NULL, NULL);
|
||||
}
|
||||
mRolloffFactor = factor;
|
||||
mSystem->set3DSettings(mDopplerFactor, 1.f, mRolloffFactor);
|
||||
}
|
||||
|
||||
|
||||
F32 LLListener_FMODEX::getRolloffFactor()
|
||||
{
|
||||
return mRolloffFactor;
|
||||
}
|
||||
|
||||
|
||||
void LLListener_FMODEX::setDopplerFactor(F32 factor)
|
||||
{
|
||||
mDopplerFactor = factor;
|
||||
mSystem->set3DSettings(mDopplerFactor, 1.f, mRolloffFactor);
|
||||
}
|
||||
|
||||
|
||||
F32 LLListener_FMODEX::getDopplerFactor()
|
||||
{
|
||||
return mDopplerFactor;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,136 @@
|
|||
/**
|
||||
* @file listener_fmodstudio.cpp
|
||||
* @brief Implementation of LISTENER class abstracting the audio
|
||||
* support as a FMODSTUDIO implementation
|
||||
*
|
||||
* $LicenseInfo:firstyear=2020&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2020, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "linden_common.h"
|
||||
#include "llaudioengine.h"
|
||||
#include "lllistener_fmodstudio.h"
|
||||
#include "fmodstudio/fmod.hpp"
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// constructor
|
||||
//-----------------------------------------------------------------------
|
||||
LLListener_FMODSTUDIO::LLListener_FMODSTUDIO(FMOD::System *system)
|
||||
{
|
||||
mSystem = system;
|
||||
init();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
LLListener_FMODSTUDIO::~LLListener_FMODSTUDIO()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
void LLListener_FMODSTUDIO::init(void)
|
||||
{
|
||||
// do inherited
|
||||
LLListener::init();
|
||||
mDopplerFactor = 1.0f;
|
||||
mRolloffFactor = 1.0f;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
void LLListener_FMODSTUDIO::translate(LLVector3 offset)
|
||||
{
|
||||
LLListener::translate(offset);
|
||||
|
||||
mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)mPosition.mV, NULL, (FMOD_VECTOR*)mListenAt.mV, (FMOD_VECTOR*)mListenUp.mV);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
void LLListener_FMODSTUDIO::setPosition(LLVector3 pos)
|
||||
{
|
||||
LLListener::setPosition(pos);
|
||||
|
||||
mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)mPosition.mV, NULL, (FMOD_VECTOR*)mListenAt.mV, (FMOD_VECTOR*)mListenUp.mV);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
void LLListener_FMODSTUDIO::setVelocity(LLVector3 vel)
|
||||
{
|
||||
LLListener::setVelocity(vel);
|
||||
|
||||
mSystem->set3DListenerAttributes(0, NULL, (FMOD_VECTOR*)mVelocity.mV, (FMOD_VECTOR*)mListenAt.mV, (FMOD_VECTOR*)mListenUp.mV);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
void LLListener_FMODSTUDIO::orient(LLVector3 up, LLVector3 at)
|
||||
{
|
||||
LLListener::orient(up, at);
|
||||
|
||||
// at = -at; by default Fmod studio is 'left-handed' but we are providing
|
||||
// flag FMOD_INIT_3D_RIGHTHANDED so no correction are needed
|
||||
|
||||
mSystem->set3DListenerAttributes(0, NULL, NULL, (FMOD_VECTOR*)at.mV, (FMOD_VECTOR*)up.mV);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
void LLListener_FMODSTUDIO::commitDeferredChanges()
|
||||
{
|
||||
if (!mSystem)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mSystem->update();
|
||||
}
|
||||
|
||||
|
||||
void LLListener_FMODSTUDIO::setRolloffFactor(F32 factor)
|
||||
{
|
||||
//An internal FMOD optimization skips 3D updates if there have not been changes to the 3D sound environment.
|
||||
// (this was true for FMODex, looks to be still true for FMOD STUDIO, but needs a recheck)
|
||||
//Sadly, a change in rolloff is not accounted for, thus we must touch the listener properties as well.
|
||||
//In short: Changing the position ticks a dirtyflag inside fmod, which makes it not skip 3D processing next update call.
|
||||
if (mRolloffFactor != factor)
|
||||
{
|
||||
LLVector3 pos = mPosition - LLVector3(0.f, 0.f, .1f);
|
||||
mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)pos.mV, NULL, NULL, NULL);
|
||||
mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)mPosition.mV, NULL, NULL, NULL);
|
||||
}
|
||||
mRolloffFactor = factor;
|
||||
mSystem->set3DSettings(mDopplerFactor, 1.f, mRolloffFactor);
|
||||
}
|
||||
|
||||
|
||||
F32 LLListener_FMODSTUDIO::getRolloffFactor()
|
||||
{
|
||||
return mRolloffFactor;
|
||||
}
|
||||
|
||||
|
||||
void LLListener_FMODSTUDIO::setDopplerFactor(F32 factor)
|
||||
{
|
||||
mDopplerFactor = factor;
|
||||
mSystem->set3DSettings(mDopplerFactor, 1.f, mRolloffFactor);
|
||||
}
|
||||
|
||||
|
||||
F32 LLListener_FMODSTUDIO::getDopplerFactor()
|
||||
{
|
||||
return mDopplerFactor;
|
||||
}
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
/**
|
||||
* @file listener_fmodex.h
|
||||
* @file listener_fmodstudio.h
|
||||
* @brief Description of LISTENER class abstracting the audio support
|
||||
* as an FMOD 3D implementation (windows and Linux)
|
||||
* as an FMOD 3D implementation
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
|
||||
* $LicenseInfo:firstyear=2020&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
* Copyright (C) 2020, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
|
@ -25,8 +25,8 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LISTENER_FMODEX_H
|
||||
#define LL_LISTENER_FMODEX_H
|
||||
#ifndef LL_LISTENER_FMODSTUDIO_H
|
||||
#define LL_LISTENER_FMODSTUDIO_H
|
||||
|
||||
#include "lllistener.h"
|
||||
|
||||
|
|
@ -37,27 +37,27 @@ namespace FMOD
|
|||
}
|
||||
|
||||
//Interfaces
|
||||
class LLListener_FMODEX : public LLListener
|
||||
class LLListener_FMODSTUDIO : public LLListener
|
||||
{
|
||||
public:
|
||||
LLListener_FMODEX(FMOD::System *system);
|
||||
virtual ~LLListener_FMODEX();
|
||||
virtual void init();
|
||||
public:
|
||||
LLListener_FMODSTUDIO(FMOD::System *system);
|
||||
virtual ~LLListener_FMODSTUDIO();
|
||||
virtual void init();
|
||||
|
||||
virtual void translate(LLVector3 offset);
|
||||
virtual void setPosition(LLVector3 pos);
|
||||
virtual void setVelocity(LLVector3 vel);
|
||||
virtual void orient(LLVector3 up, LLVector3 at);
|
||||
virtual void commitDeferredChanges();
|
||||
virtual void translate(LLVector3 offset);
|
||||
virtual void setPosition(LLVector3 pos);
|
||||
virtual void setVelocity(LLVector3 vel);
|
||||
virtual void orient(LLVector3 up, LLVector3 at);
|
||||
virtual void commitDeferredChanges();
|
||||
|
||||
virtual void setDopplerFactor(F32 factor);
|
||||
virtual F32 getDopplerFactor();
|
||||
virtual void setRolloffFactor(F32 factor);
|
||||
virtual F32 getRolloffFactor();
|
||||
protected:
|
||||
FMOD::System *mSystem;
|
||||
F32 mDopplerFactor;
|
||||
F32 mRolloffFactor;
|
||||
virtual void setDopplerFactor(F32 factor);
|
||||
virtual F32 getDopplerFactor();
|
||||
virtual void setRolloffFactor(F32 factor);
|
||||
virtual F32 getRolloffFactor();
|
||||
protected:
|
||||
FMOD::System *mSystem;
|
||||
F32 mDopplerFactor;
|
||||
F32 mRolloffFactor;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,392 +0,0 @@
|
|||
/**
|
||||
* @file streamingaudio_fmodex.cpp
|
||||
* @brief LLStreamingAudio_FMODEX implementation
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "llmath.h"
|
||||
|
||||
#include "fmod.hpp"
|
||||
#include "fmod_errors.h"
|
||||
|
||||
#include "llstreamingaudio_fmodex.h"
|
||||
|
||||
|
||||
class LLAudioStreamManagerFMODEX
|
||||
{
|
||||
public:
|
||||
LLAudioStreamManagerFMODEX(FMOD::System *system, const std::string& url);
|
||||
FMOD::Channel* startStream();
|
||||
bool stopStream(); // Returns true if the stream was successfully stopped.
|
||||
bool ready();
|
||||
|
||||
const std::string& getURL() { return mInternetStreamURL; }
|
||||
|
||||
FMOD_OPENSTATE getOpenState(unsigned int* percentbuffered=NULL, bool* starving=NULL, bool* diskbusy=NULL);
|
||||
protected:
|
||||
FMOD::System* mSystem;
|
||||
FMOD::Channel* mStreamChannel;
|
||||
FMOD::Sound* mInternetStream;
|
||||
bool mReady;
|
||||
|
||||
std::string mInternetStreamURL;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Internet Streaming
|
||||
//---------------------------------------------------------------------------
|
||||
LLStreamingAudio_FMODEX::LLStreamingAudio_FMODEX(FMOD::System *system) :
|
||||
mSystem(system),
|
||||
mCurrentInternetStreamp(NULL),
|
||||
mFMODInternetStreamChannelp(NULL),
|
||||
mGain(1.0f)
|
||||
{
|
||||
// Number of milliseconds of audio to buffer for the audio card.
|
||||
// Must be larger than the usual Second Life frame stutter time.
|
||||
const U32 buffer_seconds = 10; //sec
|
||||
const U32 estimated_bitrate = 128; //kbit/sec
|
||||
mSystem->setStreamBufferSize(estimated_bitrate * buffer_seconds * 128/*bytes/kbit*/, FMOD_TIMEUNIT_RAWBYTES);
|
||||
|
||||
// Here's where we set the size of the network buffer and some buffering
|
||||
// parameters. In this case we want a network buffer of 16k, we want it
|
||||
// to prebuffer 40% of that when we first connect, and we want it
|
||||
// to rebuffer 80% of that whenever we encounter a buffer underrun.
|
||||
|
||||
// Leave the net buffer properties at the default.
|
||||
//FSOUND_Stream_Net_SetBufferProperties(20000, 40, 80);
|
||||
}
|
||||
|
||||
|
||||
LLStreamingAudio_FMODEX::~LLStreamingAudio_FMODEX()
|
||||
{
|
||||
// nothing interesting/safe to do.
|
||||
}
|
||||
|
||||
|
||||
void LLStreamingAudio_FMODEX::start(const std::string& url)
|
||||
{
|
||||
//if (!mInited)
|
||||
//{
|
||||
// LL_WARNS() << "startInternetStream before audio initialized" << LL_ENDL;
|
||||
// return;
|
||||
//}
|
||||
|
||||
// "stop" stream but don't clear url, etc. in case url == mInternetStreamURL
|
||||
stop();
|
||||
|
||||
if (!url.empty())
|
||||
{
|
||||
LL_INFOS() << "Starting internet stream: " << url << LL_ENDL;
|
||||
mCurrentInternetStreamp = new LLAudioStreamManagerFMODEX(mSystem,url);
|
||||
mURL = url;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_INFOS() << "Set internet stream to null" << LL_ENDL;
|
||||
mURL.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LLStreamingAudio_FMODEX::update()
|
||||
{
|
||||
// Kill dead internet streams, if possible
|
||||
std::list<LLAudioStreamManagerFMODEX *>::iterator iter;
|
||||
for (iter = mDeadStreams.begin(); iter != mDeadStreams.end();)
|
||||
{
|
||||
LLAudioStreamManagerFMODEX *streamp = *iter;
|
||||
if (streamp->stopStream())
|
||||
{
|
||||
LL_INFOS() << "Closed dead stream" << LL_ENDL;
|
||||
delete streamp;
|
||||
mDeadStreams.erase(iter++);
|
||||
}
|
||||
else
|
||||
{
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
|
||||
// Don't do anything if there are no streams playing
|
||||
if (!mCurrentInternetStreamp)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int progress;
|
||||
bool starving;
|
||||
bool diskbusy;
|
||||
FMOD_OPENSTATE open_state = mCurrentInternetStreamp->getOpenState(&progress, &starving, &diskbusy);
|
||||
|
||||
if (open_state == FMOD_OPENSTATE_READY)
|
||||
{
|
||||
// Stream is live
|
||||
|
||||
// start the stream if it's ready
|
||||
if (!mFMODInternetStreamChannelp &&
|
||||
(mFMODInternetStreamChannelp = mCurrentInternetStreamp->startStream()))
|
||||
{
|
||||
// Reset volume to previously set volume
|
||||
setGain(getGain());
|
||||
mFMODInternetStreamChannelp->setPaused(false);
|
||||
}
|
||||
}
|
||||
else if(open_state == FMOD_OPENSTATE_ERROR)
|
||||
{
|
||||
stop();
|
||||
return;
|
||||
}
|
||||
|
||||
if(mFMODInternetStreamChannelp)
|
||||
{
|
||||
FMOD::Sound *sound = NULL;
|
||||
|
||||
if(mFMODInternetStreamChannelp->getCurrentSound(&sound) == FMOD_OK && sound)
|
||||
{
|
||||
FMOD_TAG tag;
|
||||
S32 tagcount, dirtytagcount;
|
||||
|
||||
if(sound->getNumTags(&tagcount, &dirtytagcount) == FMOD_OK && dirtytagcount)
|
||||
{
|
||||
for(S32 i = 0; i < tagcount; ++i)
|
||||
{
|
||||
if(sound->getTag(NULL, i, &tag)!=FMOD_OK)
|
||||
continue;
|
||||
|
||||
if (tag.type == FMOD_TAGTYPE_FMOD)
|
||||
{
|
||||
if (!strcmp(tag.name, "Sample Rate Change"))
|
||||
{
|
||||
LL_INFOS() << "Stream forced changing sample rate to " << *((float *)tag.data) << LL_ENDL;
|
||||
mFMODInternetStreamChannelp->setFrequency(*((float *)tag.data));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(starving)
|
||||
{
|
||||
bool paused = false;
|
||||
mFMODInternetStreamChannelp->getPaused(&paused);
|
||||
if(!paused)
|
||||
{
|
||||
LL_INFOS() << "Stream starvation detected! Pausing stream until buffer nearly full." << LL_ENDL;
|
||||
LL_INFOS() << " (diskbusy="<<diskbusy<<")" << LL_ENDL;
|
||||
LL_INFOS() << " (progress="<<progress<<")" << LL_ENDL;
|
||||
mFMODInternetStreamChannelp->setPaused(true);
|
||||
}
|
||||
}
|
||||
else if(progress > 80)
|
||||
{
|
||||
mFMODInternetStreamChannelp->setPaused(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLStreamingAudio_FMODEX::stop()
|
||||
{
|
||||
if (mFMODInternetStreamChannelp)
|
||||
{
|
||||
mFMODInternetStreamChannelp->setPaused(true);
|
||||
mFMODInternetStreamChannelp->setPriority(0);
|
||||
mFMODInternetStreamChannelp = NULL;
|
||||
}
|
||||
|
||||
if (mCurrentInternetStreamp)
|
||||
{
|
||||
LL_INFOS() << "Stopping internet stream: " << mCurrentInternetStreamp->getURL() << LL_ENDL;
|
||||
if (mCurrentInternetStreamp->stopStream())
|
||||
{
|
||||
delete mCurrentInternetStreamp;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS() << "Pushing stream to dead list: " << mCurrentInternetStreamp->getURL() << LL_ENDL;
|
||||
mDeadStreams.push_back(mCurrentInternetStreamp);
|
||||
}
|
||||
mCurrentInternetStreamp = NULL;
|
||||
//mURL.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void LLStreamingAudio_FMODEX::pause(int pauseopt)
|
||||
{
|
||||
if (pauseopt < 0)
|
||||
{
|
||||
pauseopt = mCurrentInternetStreamp ? 1 : 0;
|
||||
}
|
||||
|
||||
if (pauseopt)
|
||||
{
|
||||
if (mCurrentInternetStreamp)
|
||||
{
|
||||
stop();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
start(getURL());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// A stream is "playing" if it has been requested to start. That
|
||||
// doesn't necessarily mean audio is coming out of the speakers.
|
||||
int LLStreamingAudio_FMODEX::isPlaying()
|
||||
{
|
||||
if (mCurrentInternetStreamp)
|
||||
{
|
||||
return 1; // Active and playing
|
||||
}
|
||||
else if (!mURL.empty())
|
||||
{
|
||||
return 2; // "Paused"
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
F32 LLStreamingAudio_FMODEX::getGain()
|
||||
{
|
||||
return mGain;
|
||||
}
|
||||
|
||||
|
||||
std::string LLStreamingAudio_FMODEX::getURL()
|
||||
{
|
||||
return mURL;
|
||||
}
|
||||
|
||||
|
||||
void LLStreamingAudio_FMODEX::setGain(F32 vol)
|
||||
{
|
||||
mGain = vol;
|
||||
|
||||
if (mFMODInternetStreamChannelp)
|
||||
{
|
||||
vol = llclamp(vol * vol, 0.f, 1.f); //should vol be squared here?
|
||||
|
||||
mFMODInternetStreamChannelp->setVolume(vol);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// manager of possibly-multiple internet audio streams
|
||||
|
||||
LLAudioStreamManagerFMODEX::LLAudioStreamManagerFMODEX(FMOD::System *system, const std::string& url) :
|
||||
mSystem(system),
|
||||
mStreamChannel(NULL),
|
||||
mInternetStream(NULL),
|
||||
mReady(false)
|
||||
{
|
||||
mInternetStreamURL = url;
|
||||
|
||||
FMOD_RESULT result = mSystem->createStream(url.c_str(), FMOD_2D | FMOD_NONBLOCKING | FMOD_IGNORETAGS, 0, &mInternetStream);
|
||||
|
||||
if (result!= FMOD_OK)
|
||||
{
|
||||
LL_WARNS() << "Couldn't open fmod stream, error "
|
||||
<< FMOD_ErrorString(result)
|
||||
<< LL_ENDL;
|
||||
mReady = false;
|
||||
return;
|
||||
}
|
||||
|
||||
mReady = true;
|
||||
}
|
||||
|
||||
FMOD::Channel *LLAudioStreamManagerFMODEX::startStream()
|
||||
{
|
||||
// We need a live and opened stream before we try and play it.
|
||||
if (!mInternetStream || getOpenState() != FMOD_OPENSTATE_READY)
|
||||
{
|
||||
LL_WARNS() << "No internet stream to start playing!" << LL_ENDL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(mStreamChannel)
|
||||
return mStreamChannel; //Already have a channel for this stream.
|
||||
|
||||
mSystem->playSound(FMOD_CHANNEL_FREE, mInternetStream, true, &mStreamChannel);
|
||||
return mStreamChannel;
|
||||
}
|
||||
|
||||
bool LLAudioStreamManagerFMODEX::stopStream()
|
||||
{
|
||||
if (mInternetStream)
|
||||
{
|
||||
|
||||
|
||||
bool close = true;
|
||||
switch (getOpenState())
|
||||
{
|
||||
case FMOD_OPENSTATE_CONNECTING:
|
||||
close = false;
|
||||
break;
|
||||
default:
|
||||
close = true;
|
||||
}
|
||||
|
||||
if (close)
|
||||
{
|
||||
mInternetStream->release();
|
||||
mStreamChannel = NULL;
|
||||
mInternetStream = NULL;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
FMOD_OPENSTATE LLAudioStreamManagerFMODEX::getOpenState(unsigned int* percentbuffered, bool* starving, bool* diskbusy)
|
||||
{
|
||||
FMOD_OPENSTATE state;
|
||||
mInternetStream->getOpenState(&state, percentbuffered, starving, diskbusy);
|
||||
return state;
|
||||
}
|
||||
|
||||
void LLStreamingAudio_FMODEX::setBufferSizes(U32 streambuffertime, U32 decodebuffertime)
|
||||
{
|
||||
mSystem->setStreamBufferSize(streambuffertime/1000*128*128, FMOD_TIMEUNIT_RAWBYTES);
|
||||
FMOD_ADVANCEDSETTINGS settings;
|
||||
memset(&settings,0,sizeof(settings));
|
||||
settings.cbsize=sizeof(settings);
|
||||
settings.defaultDecodeBufferSize = decodebuffertime;//ms
|
||||
mSystem->setAdvancedSettings(&settings);
|
||||
}
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
/**
|
||||
* @file streamingaudio_fmodex.h
|
||||
* @brief Definition of LLStreamingAudio_FMODEX implementation
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_STREAMINGAUDIO_FMODEX_H
|
||||
#define LL_STREAMINGAUDIO_FMODEX_H
|
||||
|
||||
#include "stdtypes.h" // from llcommon
|
||||
|
||||
#include "llstreamingaudio.h"
|
||||
#include "lltimer.h"
|
||||
|
||||
//Stubs
|
||||
class LLAudioStreamManagerFMODEX;
|
||||
namespace FMOD
|
||||
{
|
||||
class System;
|
||||
class Channel;
|
||||
}
|
||||
|
||||
//Interfaces
|
||||
class LLStreamingAudio_FMODEX : public LLStreamingAudioInterface
|
||||
{
|
||||
public:
|
||||
LLStreamingAudio_FMODEX(FMOD::System *system);
|
||||
/*virtual*/ ~LLStreamingAudio_FMODEX();
|
||||
|
||||
/*virtual*/ void start(const std::string& url);
|
||||
/*virtual*/ void stop();
|
||||
/*virtual*/ void pause(S32 pause);
|
||||
/*virtual*/ void update();
|
||||
/*virtual*/ S32 isPlaying();
|
||||
/*virtual*/ void setGain(F32 vol);
|
||||
/*virtual*/ F32 getGain();
|
||||
/*virtual*/ std::string getURL();
|
||||
|
||||
/*virtual*/ bool supportsAdjustableBufferSizes(){return true;}
|
||||
/*virtual*/ void setBufferSizes(U32 streambuffertime, U32 decodebuffertime);
|
||||
private:
|
||||
FMOD::System *mSystem;
|
||||
|
||||
LLAudioStreamManagerFMODEX *mCurrentInternetStreamp;
|
||||
FMOD::Channel *mFMODInternetStreamChannelp;
|
||||
std::list<LLAudioStreamManagerFMODEX *> mDeadStreams;
|
||||
|
||||
std::string mURL;
|
||||
F32 mGain;
|
||||
};
|
||||
|
||||
|
||||
#endif // LL_STREAMINGAUDIO_FMODEX_H
|
||||
|
|
@ -0,0 +1,392 @@
|
|||
/**
|
||||
* @file streamingaudio_fmodstudio.cpp
|
||||
* @brief LLStreamingAudio_FMODSTUDIO implementation
|
||||
*
|
||||
* $LicenseInfo:firstyear=2020&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2020, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "llmath.h"
|
||||
|
||||
#include "fmodstudio/fmod.hpp"
|
||||
#include "fmodstudio/fmod_errors.h"
|
||||
|
||||
#include "llstreamingaudio_fmodstudio.h"
|
||||
|
||||
|
||||
class LLAudioStreamManagerFMODSTUDIO
|
||||
{
|
||||
public:
|
||||
LLAudioStreamManagerFMODSTUDIO(FMOD::System *system, const std::string& url);
|
||||
FMOD::Channel* startStream();
|
||||
bool stopStream(); // Returns true if the stream was successfully stopped.
|
||||
bool ready();
|
||||
|
||||
const std::string& getURL() { return mInternetStreamURL; }
|
||||
|
||||
FMOD_OPENSTATE getOpenState(unsigned int* percentbuffered = NULL, bool* starving = NULL, bool* diskbusy = NULL);
|
||||
protected:
|
||||
FMOD::System* mSystem;
|
||||
FMOD::Channel* mStreamChannel;
|
||||
FMOD::Sound* mInternetStream;
|
||||
bool mReady;
|
||||
|
||||
std::string mInternetStreamURL;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Internet Streaming
|
||||
//---------------------------------------------------------------------------
|
||||
LLStreamingAudio_FMODSTUDIO::LLStreamingAudio_FMODSTUDIO(FMOD::System *system) :
|
||||
mSystem(system),
|
||||
mCurrentInternetStreamp(NULL),
|
||||
mFMODInternetStreamChannelp(NULL),
|
||||
mGain(1.0f)
|
||||
{
|
||||
// Number of milliseconds of audio to buffer for the audio card.
|
||||
// Must be larger than the usual Second Life frame stutter time.
|
||||
const U32 buffer_seconds = 10; //sec
|
||||
const U32 estimated_bitrate = 128; //kbit/sec
|
||||
mSystem->setStreamBufferSize(estimated_bitrate * buffer_seconds * 128/*bytes/kbit*/, FMOD_TIMEUNIT_RAWBYTES);
|
||||
|
||||
// Here's where we set the size of the network buffer and some buffering
|
||||
// parameters. In this case we want a network buffer of 16k, we want it
|
||||
// to prebuffer 40% of that when we first connect, and we want it
|
||||
// to rebuffer 80% of that whenever we encounter a buffer underrun.
|
||||
|
||||
// Leave the net buffer properties at the default.
|
||||
//FSOUND_Stream_Net_SetBufferProperties(20000, 40, 80);
|
||||
}
|
||||
|
||||
|
||||
LLStreamingAudio_FMODSTUDIO::~LLStreamingAudio_FMODSTUDIO()
|
||||
{
|
||||
// nothing interesting/safe to do.
|
||||
}
|
||||
|
||||
|
||||
void LLStreamingAudio_FMODSTUDIO::start(const std::string& url)
|
||||
{
|
||||
//if (!mInited)
|
||||
//{
|
||||
// LL_WARNS() << "startInternetStream before audio initialized" << LL_ENDL;
|
||||
// return;
|
||||
//}
|
||||
|
||||
// "stop" stream but don't clear url, etc. in case url == mInternetStreamURL
|
||||
stop();
|
||||
|
||||
if (!url.empty())
|
||||
{
|
||||
LL_INFOS() << "Starting internet stream: " << url << LL_ENDL;
|
||||
mCurrentInternetStreamp = new LLAudioStreamManagerFMODSTUDIO(mSystem, url);
|
||||
mURL = url;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_INFOS() << "Set internet stream to null" << LL_ENDL;
|
||||
mURL.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LLStreamingAudio_FMODSTUDIO::update()
|
||||
{
|
||||
// Kill dead internet streams, if possible
|
||||
std::list<LLAudioStreamManagerFMODSTUDIO *>::iterator iter;
|
||||
for (iter = mDeadStreams.begin(); iter != mDeadStreams.end();)
|
||||
{
|
||||
LLAudioStreamManagerFMODSTUDIO *streamp = *iter;
|
||||
if (streamp->stopStream())
|
||||
{
|
||||
LL_INFOS() << "Closed dead stream" << LL_ENDL;
|
||||
delete streamp;
|
||||
mDeadStreams.erase(iter++);
|
||||
}
|
||||
else
|
||||
{
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
|
||||
// Don't do anything if there are no streams playing
|
||||
if (!mCurrentInternetStreamp)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int progress;
|
||||
bool starving;
|
||||
bool diskbusy;
|
||||
FMOD_OPENSTATE open_state = mCurrentInternetStreamp->getOpenState(&progress, &starving, &diskbusy);
|
||||
|
||||
if (open_state == FMOD_OPENSTATE_READY)
|
||||
{
|
||||
// Stream is live
|
||||
|
||||
// start the stream if it's ready
|
||||
if (!mFMODInternetStreamChannelp &&
|
||||
(mFMODInternetStreamChannelp = mCurrentInternetStreamp->startStream()))
|
||||
{
|
||||
// Reset volume to previously set volume
|
||||
setGain(getGain());
|
||||
mFMODInternetStreamChannelp->setPaused(false);
|
||||
}
|
||||
}
|
||||
else if (open_state == FMOD_OPENSTATE_ERROR)
|
||||
{
|
||||
stop();
|
||||
return;
|
||||
}
|
||||
|
||||
if (mFMODInternetStreamChannelp)
|
||||
{
|
||||
FMOD::Sound *sound = NULL;
|
||||
|
||||
if (mFMODInternetStreamChannelp->getCurrentSound(&sound) == FMOD_OK && sound)
|
||||
{
|
||||
FMOD_TAG tag;
|
||||
S32 tagcount, dirtytagcount;
|
||||
|
||||
if (sound->getNumTags(&tagcount, &dirtytagcount) == FMOD_OK && dirtytagcount)
|
||||
{
|
||||
for (S32 i = 0; i < tagcount; ++i)
|
||||
{
|
||||
if (sound->getTag(NULL, i, &tag) != FMOD_OK)
|
||||
continue;
|
||||
|
||||
if (tag.type == FMOD_TAGTYPE_FMOD)
|
||||
{
|
||||
if (!strcmp(tag.name, "Sample Rate Change"))
|
||||
{
|
||||
LL_INFOS() << "Stream forced changing sample rate to " << *((float *)tag.data) << LL_ENDL;
|
||||
mFMODInternetStreamChannelp->setFrequency(*((float *)tag.data));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (starving)
|
||||
{
|
||||
bool paused = false;
|
||||
mFMODInternetStreamChannelp->getPaused(&paused);
|
||||
if (!paused)
|
||||
{
|
||||
LL_INFOS() << "Stream starvation detected! Pausing stream until buffer nearly full." << LL_ENDL;
|
||||
LL_INFOS() << " (diskbusy=" << diskbusy << ")" << LL_ENDL;
|
||||
LL_INFOS() << " (progress=" << progress << ")" << LL_ENDL;
|
||||
mFMODInternetStreamChannelp->setPaused(true);
|
||||
}
|
||||
}
|
||||
else if (progress > 80)
|
||||
{
|
||||
mFMODInternetStreamChannelp->setPaused(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLStreamingAudio_FMODSTUDIO::stop()
|
||||
{
|
||||
if (mFMODInternetStreamChannelp)
|
||||
{
|
||||
mFMODInternetStreamChannelp->setPaused(true);
|
||||
mFMODInternetStreamChannelp->setPriority(0);
|
||||
mFMODInternetStreamChannelp = NULL;
|
||||
}
|
||||
|
||||
if (mCurrentInternetStreamp)
|
||||
{
|
||||
LL_INFOS() << "Stopping internet stream: " << mCurrentInternetStreamp->getURL() << LL_ENDL;
|
||||
if (mCurrentInternetStreamp->stopStream())
|
||||
{
|
||||
delete mCurrentInternetStreamp;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS() << "Pushing stream to dead list: " << mCurrentInternetStreamp->getURL() << LL_ENDL;
|
||||
mDeadStreams.push_back(mCurrentInternetStreamp);
|
||||
}
|
||||
mCurrentInternetStreamp = NULL;
|
||||
//mURL.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void LLStreamingAudio_FMODSTUDIO::pause(int pauseopt)
|
||||
{
|
||||
if (pauseopt < 0)
|
||||
{
|
||||
pauseopt = mCurrentInternetStreamp ? 1 : 0;
|
||||
}
|
||||
|
||||
if (pauseopt)
|
||||
{
|
||||
if (mCurrentInternetStreamp)
|
||||
{
|
||||
stop();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
start(getURL());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// A stream is "playing" if it has been requested to start. That
|
||||
// doesn't necessarily mean audio is coming out of the speakers.
|
||||
int LLStreamingAudio_FMODSTUDIO::isPlaying()
|
||||
{
|
||||
if (mCurrentInternetStreamp)
|
||||
{
|
||||
return 1; // Active and playing
|
||||
}
|
||||
else if (!mURL.empty())
|
||||
{
|
||||
return 2; // "Paused"
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
F32 LLStreamingAudio_FMODSTUDIO::getGain()
|
||||
{
|
||||
return mGain;
|
||||
}
|
||||
|
||||
|
||||
std::string LLStreamingAudio_FMODSTUDIO::getURL()
|
||||
{
|
||||
return mURL;
|
||||
}
|
||||
|
||||
|
||||
void LLStreamingAudio_FMODSTUDIO::setGain(F32 vol)
|
||||
{
|
||||
mGain = vol;
|
||||
|
||||
if (mFMODInternetStreamChannelp)
|
||||
{
|
||||
vol = llclamp(vol * vol, 0.f, 1.f); //should vol be squared here?
|
||||
|
||||
mFMODInternetStreamChannelp->setVolume(vol);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// manager of possibly-multiple internet audio streams
|
||||
|
||||
LLAudioStreamManagerFMODSTUDIO::LLAudioStreamManagerFMODSTUDIO(FMOD::System *system, const std::string& url) :
|
||||
mSystem(system),
|
||||
mStreamChannel(NULL),
|
||||
mInternetStream(NULL),
|
||||
mReady(false)
|
||||
{
|
||||
mInternetStreamURL = url;
|
||||
|
||||
FMOD_RESULT result = mSystem->createStream(url.c_str(), FMOD_2D | FMOD_NONBLOCKING | FMOD_IGNORETAGS, 0, &mInternetStream);
|
||||
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
LL_WARNS() << "Couldn't open fmod stream, error "
|
||||
<< FMOD_ErrorString(result)
|
||||
<< LL_ENDL;
|
||||
mReady = false;
|
||||
return;
|
||||
}
|
||||
|
||||
mReady = true;
|
||||
}
|
||||
|
||||
FMOD::Channel *LLAudioStreamManagerFMODSTUDIO::startStream()
|
||||
{
|
||||
// We need a live and opened stream before we try and play it.
|
||||
if (!mInternetStream || getOpenState() != FMOD_OPENSTATE_READY)
|
||||
{
|
||||
LL_WARNS() << "No internet stream to start playing!" << LL_ENDL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (mStreamChannel)
|
||||
return mStreamChannel; //Already have a channel for this stream.
|
||||
|
||||
mSystem->playSound(mInternetStream, NULL, true, &mStreamChannel);
|
||||
return mStreamChannel;
|
||||
}
|
||||
|
||||
bool LLAudioStreamManagerFMODSTUDIO::stopStream()
|
||||
{
|
||||
if (mInternetStream)
|
||||
{
|
||||
|
||||
|
||||
bool close = true;
|
||||
switch (getOpenState())
|
||||
{
|
||||
case FMOD_OPENSTATE_CONNECTING:
|
||||
close = false;
|
||||
break;
|
||||
default:
|
||||
close = true;
|
||||
}
|
||||
|
||||
if (close)
|
||||
{
|
||||
mInternetStream->release();
|
||||
mStreamChannel = NULL;
|
||||
mInternetStream = NULL;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
FMOD_OPENSTATE LLAudioStreamManagerFMODSTUDIO::getOpenState(unsigned int* percentbuffered, bool* starving, bool* diskbusy)
|
||||
{
|
||||
FMOD_OPENSTATE state;
|
||||
mInternetStream->getOpenState(&state, percentbuffered, starving, diskbusy);
|
||||
return state;
|
||||
}
|
||||
|
||||
void LLStreamingAudio_FMODSTUDIO::setBufferSizes(U32 streambuffertime, U32 decodebuffertime)
|
||||
{
|
||||
mSystem->setStreamBufferSize(streambuffertime / 1000 * 128 * 128, FMOD_TIMEUNIT_RAWBYTES);
|
||||
FMOD_ADVANCEDSETTINGS settings;
|
||||
memset(&settings, 0, sizeof(settings));
|
||||
settings.cbSize = sizeof(settings);
|
||||
settings.defaultDecodeBufferSize = decodebuffertime;//ms
|
||||
mSystem->setAdvancedSettings(&settings);
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
/**
|
||||
* @file streamingaudio_fmodstudio.h
|
||||
* @brief Definition of LLStreamingAudio_FMODSTUDIO implementation
|
||||
*
|
||||
* $LicenseInfo:firstyear=2020&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2020, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_STREAMINGAUDIO_FMODSTUDIO_H
|
||||
#define LL_STREAMINGAUDIO_FMODSTUDIO_H
|
||||
|
||||
#include "stdtypes.h" // from llcommon
|
||||
|
||||
#include "llstreamingaudio.h"
|
||||
#include "lltimer.h"
|
||||
|
||||
//Stubs
|
||||
class LLAudioStreamManagerFMODSTUDIO;
|
||||
namespace FMOD
|
||||
{
|
||||
class System;
|
||||
class Channel;
|
||||
}
|
||||
|
||||
//Interfaces
|
||||
class LLStreamingAudio_FMODSTUDIO : public LLStreamingAudioInterface
|
||||
{
|
||||
public:
|
||||
LLStreamingAudio_FMODSTUDIO(FMOD::System *system);
|
||||
/*virtual*/ ~LLStreamingAudio_FMODSTUDIO();
|
||||
|
||||
/*virtual*/ void start(const std::string& url);
|
||||
/*virtual*/ void stop();
|
||||
/*virtual*/ void pause(S32 pause);
|
||||
/*virtual*/ void update();
|
||||
/*virtual*/ S32 isPlaying();
|
||||
/*virtual*/ void setGain(F32 vol);
|
||||
/*virtual*/ F32 getGain();
|
||||
/*virtual*/ std::string getURL();
|
||||
|
||||
/*virtual*/ bool supportsAdjustableBufferSizes(){return true;}
|
||||
/*virtual*/ void setBufferSizes(U32 streambuffertime, U32 decodebuffertime);
|
||||
private:
|
||||
FMOD::System *mSystem;
|
||||
|
||||
LLAudioStreamManagerFMODSTUDIO *mCurrentInternetStreamp;
|
||||
FMOD::Channel *mFMODInternetStreamChannelp;
|
||||
std::list<LLAudioStreamManagerFMODSTUDIO *> mDeadStreams;
|
||||
|
||||
std::string mURL;
|
||||
F32 mGain;
|
||||
};
|
||||
|
||||
|
||||
#endif // LL_STREAMINGAUDIO_FMODSTUDIO_H
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
/**
|
||||
|
||||
* @file llfloater.cpp
|
||||
* @brief LLFloater base class
|
||||
*
|
||||
|
|
|
|||
|
|
@ -213,7 +213,8 @@ public:
|
|||
|
||||
virtual void setColor(const LLColor4& color);
|
||||
|
||||
F32 getCurrentTransparency();
|
||||
// Ansariel: Changed to virtual. We might want to change the transparency ourself!
|
||||
virtual F32 getCurrentTransparency();
|
||||
|
||||
void setTransparencyType(ETypeTransparency type);
|
||||
ETypeTransparency getTransparencyType() const {return mTransparencyType;}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@
|
|||
#include "v4coloru.h"
|
||||
#include "v4color.h"
|
||||
#include "v3color.h"
|
||||
#include "llquaternion.h"
|
||||
#include "llrect.h"
|
||||
#include "llxmltree.h"
|
||||
#include "llsdserialize.h"
|
||||
|
|
@ -125,6 +126,9 @@ bool LLControlVariable::llsd_compare(const LLSD& a, const LLSD & b)
|
|||
case TYPE_VEC3D:
|
||||
result = LLVector3d(a) == LLVector3d(b);
|
||||
break;
|
||||
case TYPE_QUAT:
|
||||
result = LLQuaternion(a) == LLQuaternion(b);
|
||||
break;
|
||||
case TYPE_RECT:
|
||||
result = LLRect(a) == LLRect(b);
|
||||
break;
|
||||
|
|
@ -361,6 +365,7 @@ const std::string LLControlGroup::mTypeString[TYPE_COUNT] = { "U32"
|
|||
,"String"
|
||||
,"Vector3"
|
||||
,"Vector3D"
|
||||
,"Quaternion"
|
||||
,"Rect"
|
||||
,"Color4"
|
||||
,"Color3"
|
||||
|
|
@ -523,6 +528,11 @@ LLControlVariable* LLControlGroup::declareVec3d(const std::string& name, const L
|
|||
return declareControl(name, TYPE_VEC3D, initial_val.getValue(), comment, persist);
|
||||
}
|
||||
|
||||
LLControlVariable* LLControlGroup::declareQuat(const std::string& name, const LLQuaternion &initial_val, const std::string& comment, LLControlVariable::ePersist persist)
|
||||
{
|
||||
return declareControl(name, TYPE_QUAT, initial_val.getValue(), comment, persist);
|
||||
}
|
||||
|
||||
LLControlVariable* LLControlGroup::declareRect(const std::string& name, const LLRect &initial_val, const std::string& comment, LLControlVariable::ePersist persist)
|
||||
{
|
||||
return declareControl(name, TYPE_RECT, initial_val.getValue(), comment, persist);
|
||||
|
|
@ -600,6 +610,11 @@ LLVector3d LLControlGroup::getVector3d(const std::string& name)
|
|||
return get<LLVector3d>(name);
|
||||
}
|
||||
|
||||
LLQuaternion LLControlGroup::getQuaternion(const std::string& name)
|
||||
{
|
||||
return get<LLQuaternion>(name);
|
||||
}
|
||||
|
||||
LLRect LLControlGroup::getRect(const std::string& name)
|
||||
{
|
||||
return get<LLRect>(name);
|
||||
|
|
@ -677,6 +692,11 @@ void LLControlGroup::setVector3d(const std::string& name, const LLVector3d &val)
|
|||
set(name, val);
|
||||
}
|
||||
|
||||
void LLControlGroup::setQuaternion(const std::string& name, const LLQuaternion &val)
|
||||
{
|
||||
set(name, val);
|
||||
}
|
||||
|
||||
void LLControlGroup::setRect(const std::string& name, const LLRect &val)
|
||||
{
|
||||
set(name, val);
|
||||
|
|
@ -859,6 +879,16 @@ U32 LLControlGroup::loadFromFileLegacy(const std::string& filename, BOOL require
|
|||
validitems++;
|
||||
}
|
||||
break;
|
||||
case TYPE_QUAT:
|
||||
{
|
||||
LLQuaternion quat;
|
||||
|
||||
child_nodep->getAttributeQuat("value", quat);
|
||||
|
||||
control->set(quat.getValue());
|
||||
validitems++;
|
||||
}
|
||||
break;
|
||||
case TYPE_RECT:
|
||||
{
|
||||
//RN: hack to support reading rectangles from a string
|
||||
|
|
@ -1201,6 +1231,11 @@ template <> eControlType get_control_type<LLVector3d>()
|
|||
return TYPE_VEC3D;
|
||||
}
|
||||
|
||||
template <> eControlType get_control_type<LLQuaternion>()
|
||||
{
|
||||
return TYPE_QUAT;
|
||||
}
|
||||
|
||||
template <> eControlType get_control_type<LLRect>()
|
||||
{
|
||||
return TYPE_RECT;
|
||||
|
|
@ -1236,6 +1271,10 @@ template <> LLSD convert_to_llsd<LLVector3d>(const LLVector3d& in)
|
|||
{
|
||||
return in.getValue();
|
||||
}
|
||||
template <> LLSD convert_to_llsd<LLQuaternion>(const LLQuaternion& in)
|
||||
{
|
||||
return in.getValue();
|
||||
}
|
||||
|
||||
template <> LLSD convert_to_llsd<LLRect>(const LLRect& in)
|
||||
{
|
||||
|
|
@ -1348,6 +1387,18 @@ LLVector3d convert_from_llsd<LLVector3d>(const LLSD& sd, eControlType type, cons
|
|||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
LLQuaternion convert_from_llsd<LLQuaternion>(const LLSD& sd, eControlType type, const std::string& control_name)
|
||||
{
|
||||
if (type == TYPE_QUAT)
|
||||
return (LLQuaternion)sd;
|
||||
else
|
||||
{
|
||||
CONTROL_ERRS << "Invalid LLQuaternion value for " << control_name << ": " << LLControlGroup::typeEnumToString(type) << " " << sd << LL_ENDL;
|
||||
return LLQuaternion();
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
LLRect convert_from_llsd<LLRect>(const LLSD& sd, eControlType type, const std::string& control_name)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@
|
|||
|
||||
class LLVector3;
|
||||
class LLVector3d;
|
||||
class LLQuaternion;
|
||||
class LLColor4;
|
||||
class LLColor3;
|
||||
|
||||
|
|
@ -80,6 +81,7 @@ typedef enum e_control_type
|
|||
TYPE_STRING,
|
||||
TYPE_VEC3,
|
||||
TYPE_VEC3D,
|
||||
TYPE_QUAT,
|
||||
TYPE_RECT,
|
||||
TYPE_COL4,
|
||||
TYPE_COL3,
|
||||
|
|
@ -223,6 +225,7 @@ public:
|
|||
LLControlVariable* declareString(const std::string& name, const std::string &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
|
||||
LLControlVariable* declareVec3(const std::string& name, const LLVector3 &initial_val,const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
|
||||
LLControlVariable* declareVec3d(const std::string& name, const LLVector3d &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
|
||||
LLControlVariable* declareQuat(const std::string& name, const LLQuaternion &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
|
||||
LLControlVariable* declareRect(const std::string& name, const LLRect &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
|
||||
LLControlVariable* declareColor4(const std::string& name, const LLColor4 &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
|
||||
LLControlVariable* declareColor3(const std::string& name, const LLColor3 &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
|
||||
|
|
@ -237,10 +240,10 @@ public:
|
|||
|
||||
LLWString getWString(const std::string& name);
|
||||
LLVector3 getVector3(const std::string& name);
|
||||
LLVector3d getVector3d(const std::string& name);
|
||||
LLVector3d getVector3d(const std::string& name);
|
||||
LLRect getRect(const std::string& name);
|
||||
LLSD getLLSD(const std::string& name);
|
||||
|
||||
LLQuaternion getQuaternion(const std::string& name);
|
||||
|
||||
LLColor4 getColor(const std::string& name);
|
||||
LLColor4 getColor4(const std::string& name);
|
||||
|
|
@ -273,6 +276,7 @@ public:
|
|||
void setString(const std::string& name, const std::string& val);
|
||||
void setVector3(const std::string& name, const LLVector3 &val);
|
||||
void setVector3d(const std::string& name, const LLVector3d &val);
|
||||
void setQuaternion(const std::string& name, const LLQuaternion &val);
|
||||
void setRect(const std::string& name, const LLRect &val);
|
||||
void setColor4(const std::string& name, const LLColor4 &val);
|
||||
void setLLSD(const std::string& name, const LLSD& val);
|
||||
|
|
@ -439,7 +443,8 @@ template <> eControlType get_control_type<bool>();
|
|||
//template <> eControlType get_control_type<BOOL> ()
|
||||
template <> eControlType get_control_type<std::string>();
|
||||
template <> eControlType get_control_type<LLVector3>();
|
||||
template <> eControlType get_control_type<LLVector3d>();
|
||||
template <> eControlType get_control_type<LLVector3d>();
|
||||
template <> eControlType get_control_type<LLQuaternion>();
|
||||
template <> eControlType get_control_type<LLRect>();
|
||||
template <> eControlType get_control_type<LLColor4>();
|
||||
template <> eControlType get_control_type<LLColor3>();
|
||||
|
|
@ -447,7 +452,8 @@ template <> eControlType get_control_type<LLSD>();
|
|||
|
||||
template <> LLSD convert_to_llsd<U32>(const U32& in);
|
||||
template <> LLSD convert_to_llsd<LLVector3>(const LLVector3& in);
|
||||
template <> LLSD convert_to_llsd<LLVector3d>(const LLVector3d& in);
|
||||
template <> LLSD convert_to_llsd<LLVector3d>(const LLVector3d& in);
|
||||
template <> LLSD convert_to_llsd<LLQuaternion>(const LLQuaternion& in);
|
||||
template <> LLSD convert_to_llsd<LLRect>(const LLRect& in);
|
||||
template <> LLSD convert_to_llsd<LLColor4>(const LLColor4& in);
|
||||
template <> LLSD convert_to_llsd<LLColor3>(const LLColor3& in);
|
||||
|
|
@ -456,6 +462,7 @@ template<> std::string convert_from_llsd<std::string>(const LLSD& sd, eControlTy
|
|||
template<> LLWString convert_from_llsd<LLWString>(const LLSD& sd, eControlType type, const std::string& control_name);
|
||||
template<> LLVector3 convert_from_llsd<LLVector3>(const LLSD& sd, eControlType type, const std::string& control_name);
|
||||
template<> LLVector3d convert_from_llsd<LLVector3d>(const LLSD& sd, eControlType type, const std::string& control_name);
|
||||
template<> LLQuaternion convert_from_llsd<LLQuaternion>(const LLSD& sd, eControlType type, const std::string& control_name);
|
||||
template<> LLRect convert_from_llsd<LLRect>(const LLSD& sd, eControlType type, const std::string& control_name);
|
||||
template<> bool convert_from_llsd<bool>(const LLSD& sd, eControlType type, const std::string& control_name);
|
||||
template<> S32 convert_from_llsd<S32>(const LLSD& sd, eControlType type, const std::string& control_name);
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ public:
|
|||
virtual void setString(const std::string& name, const std::string& val) {}
|
||||
virtual void setVector3(const std::string& name, const LLVector3 &val) {}
|
||||
virtual void setVector3d(const std::string& name, const LLVector3d &val) {}
|
||||
virtual void setQuaternion(const std::string& name, const LLQuaternion &val) {}
|
||||
virtual void setRect(const std::string& name, const LLRect &val) {}
|
||||
virtual void setColor4(const std::string& name, const LLColor4 &val) {}
|
||||
virtual void setLLSD(const std::string& name, const LLSD& val) {}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ include(DBusGlib)
|
|||
include(DirectX)
|
||||
include(DragDrop)
|
||||
include(EXPAT)
|
||||
include(FMODEX)
|
||||
include(FMODSTUDIO)
|
||||
include(GLOD)
|
||||
include(Hunspell)
|
||||
include(JsonCpp)
|
||||
|
|
@ -63,9 +63,9 @@ if (NOT HAVOK_TPV)
|
|||
add_subdirectory(${LLPHYSICSEXTENSIONS_SRC_DIR} llphysicsextensions)
|
||||
endif (NOT HAVOK_TPV)
|
||||
|
||||
if(FMODEX)
|
||||
include_directories(${FMODEX_INCLUDE_DIR})
|
||||
endif(FMODEX)
|
||||
if(FMODSTUDIO)
|
||||
include_directories(${FMODSTUDIO_INCLUDE_DIR})
|
||||
endif(FMODSTUDIO)
|
||||
|
||||
include_directories(
|
||||
${DBUSGLIB_INCLUDE_DIRS}
|
||||
|
|
@ -228,6 +228,7 @@ set(viewer_SOURCE_FILES
|
|||
llfloaterbuycurrencyhtml.cpp
|
||||
llfloaterbuyland.cpp
|
||||
llfloatercamera.cpp
|
||||
llfloatercamerapresets.cpp
|
||||
llfloaterchatvoicevolume.cpp
|
||||
llfloatercolorpicker.cpp
|
||||
llfloaterconversationlog.cpp
|
||||
|
|
@ -288,12 +289,14 @@ set(viewer_SOURCE_FILES
|
|||
llfloaterperms.cpp
|
||||
llfloaterpostprocess.cpp
|
||||
llfloaterpreference.cpp
|
||||
llfloaterpreferenceviewadvanced.cpp
|
||||
llfloaterpreviewtrash.cpp
|
||||
llfloaterproperties.cpp
|
||||
llfloaterregiondebugconsole.cpp
|
||||
llfloaterregioninfo.cpp
|
||||
llfloaterreporter.cpp
|
||||
llfloaterregionrestarting.cpp
|
||||
llfloatersavecamerapreset.cpp
|
||||
llfloatersaveprefpreset.cpp
|
||||
llfloatersceneloadstats.cpp
|
||||
llfloaterscriptdebug.cpp
|
||||
|
|
@ -481,6 +484,7 @@ set(viewer_SOURCE_FILES
|
|||
llpanelplaceprofile.cpp
|
||||
llpanelplaces.cpp
|
||||
llpanelplacestab.cpp
|
||||
llpanelpresetscamerapulldown.cpp
|
||||
llpanelpresetspulldown.cpp
|
||||
llpanelprimmediacontrols.cpp
|
||||
llpanelprofile.cpp
|
||||
|
|
@ -494,6 +498,7 @@ set(viewer_SOURCE_FILES
|
|||
llpaneltiptoast.cpp
|
||||
llpanelvoiceeffect.cpp
|
||||
llpaneltopinfobar.cpp
|
||||
llpanelpulldown.cpp
|
||||
llpanelvoicedevicesettings.cpp
|
||||
llpanelvolume.cpp
|
||||
llpanelvolumepulldown.cpp
|
||||
|
|
@ -863,6 +868,7 @@ set(viewer_HEADER_FILES
|
|||
llfloaterbuycurrency.h
|
||||
llfloaterbuycurrencyhtml.h
|
||||
llfloaterbuyland.h
|
||||
llfloatercamerapresets.h
|
||||
llfloatercamera.h
|
||||
llfloaterchatvoicevolume.h
|
||||
llfloatercolorpicker.h
|
||||
|
|
@ -927,12 +933,14 @@ set(viewer_HEADER_FILES
|
|||
llfloaterperms.h
|
||||
llfloaterpostprocess.h
|
||||
llfloaterpreference.h
|
||||
llfloaterpreferenceviewadvanced.h
|
||||
llfloaterpreviewtrash.h
|
||||
llfloaterproperties.h
|
||||
llfloaterregiondebugconsole.h
|
||||
llfloaterregioninfo.h
|
||||
llfloaterreporter.h
|
||||
llfloaterregionrestarting.h
|
||||
llfloatersavecamerapreset.h
|
||||
llfloatersaveprefpreset.h
|
||||
llfloatersceneloadstats.h
|
||||
llfloaterscriptdebug.h
|
||||
|
|
@ -1110,12 +1118,14 @@ set(viewer_HEADER_FILES
|
|||
llpanelplaceprofile.h
|
||||
llpanelplaces.h
|
||||
llpanelplacestab.h
|
||||
llpanelpresetscamerapulldown.h
|
||||
llpanelpresetspulldown.h
|
||||
llpanelprimmediacontrols.h
|
||||
llpanelprofile.h
|
||||
llpanelsnapshot.h
|
||||
llpanelteleporthistory.h
|
||||
llpaneltiptoast.h
|
||||
llpanelpulldown.h
|
||||
llpanelvoicedevicesettings.h
|
||||
llpanelvoiceeffect.h
|
||||
llpaneltopinfobar.h
|
||||
|
|
@ -1735,12 +1745,13 @@ if (OPENAL)
|
|||
set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_OPENAL")
|
||||
endif (OPENAL)
|
||||
|
||||
if (FMODEX)
|
||||
set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_FMODEX")
|
||||
set(FMODWRAPPER_LIBRARY ${FMODEX_LIBRARY})
|
||||
endif (FMODEX)
|
||||
if (FMODSTUDIO)
|
||||
set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_FMODSTUDIO")
|
||||
set(FMODWRAPPER_LIBRARY ${FMODSTUDIO_LIBRARY})
|
||||
endif (FMODSTUDIO)
|
||||
|
||||
set_source_files_properties(llstartup.cpp PROPERTIES COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS}")
|
||||
set_source_files_properties(llprogressview.cpp PROPERTIES COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS}")
|
||||
|
||||
list(APPEND viewer_SOURCE_FILES ${viewer_HEADER_FILES})
|
||||
|
||||
|
|
@ -1855,13 +1866,13 @@ if (WINDOWS)
|
|||
)
|
||||
endif (ADDRESS_SIZE EQUAL 64)
|
||||
|
||||
if (FMODEX)
|
||||
if (FMODSTUDIO)
|
||||
list(APPEND COPY_INPUT_DEPENDENCIES
|
||||
${SHARED_LIB_STAGING_DIR}/Release/fmodex.dll
|
||||
${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/fmodex.dll
|
||||
${SHARED_LIB_STAGING_DIR}/Debug/fmodexL.dll
|
||||
${SHARED_LIB_STAGING_DIR}/Release/fmod.dll
|
||||
${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/fmod.dll
|
||||
${SHARED_LIB_STAGING_DIR}/Debug/fmodL.dll
|
||||
)
|
||||
endif (FMODEX)
|
||||
endif (FMODSTUDIO)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_CFG_INTDIR}/copy_touched.bat
|
||||
|
|
@ -1872,6 +1883,7 @@ if (WINDOWS)
|
|||
--arch=${ARCH}
|
||||
--artwork=${ARTWORK_DIR}
|
||||
"--bugsplat=${BUGSPLAT_DB}"
|
||||
"--fmodstudio=${FMODSTUDIO}"
|
||||
--build=${CMAKE_CURRENT_BINARY_DIR}
|
||||
--buildtype=${CMAKE_BUILD_TYPE}
|
||||
"--channel=${VIEWER_CHANNEL}"
|
||||
|
|
@ -1948,6 +1960,7 @@ if (WINDOWS)
|
|||
--arch=${ARCH}
|
||||
--artwork=${ARTWORK_DIR}
|
||||
"--bugsplat=${BUGSPLAT_DB}"
|
||||
"--fmodstudio=${FMODSTUDIO}"
|
||||
--build=${CMAKE_CURRENT_BINARY_DIR}
|
||||
--buildtype=${CMAKE_BUILD_TYPE}
|
||||
"--channel=${VIEWER_CHANNEL}"
|
||||
|
|
@ -2093,6 +2106,7 @@ if (LINUX)
|
|||
--arch=${ARCH}
|
||||
--artwork=${ARTWORK_DIR}
|
||||
"--bugsplat=${BUGSPLAT_DB}"
|
||||
"--fmodstudio=${FMODSTUDIO}"
|
||||
--build=${CMAKE_CURRENT_BINARY_DIR}
|
||||
--buildtype=${CMAKE_BUILD_TYPE}
|
||||
"--channel=${VIEWER_CHANNEL}"
|
||||
|
|
@ -2119,6 +2133,7 @@ if (LINUX)
|
|||
--arch=${ARCH}
|
||||
--artwork=${ARTWORK_DIR}
|
||||
"--bugsplat=${BUGSPLAT_DB}"
|
||||
"--fmodstudio=${FMODSTUDIO}"
|
||||
--build=${CMAKE_CURRENT_BINARY_DIR}
|
||||
--buildtype=${CMAKE_BUILD_TYPE}
|
||||
"--channel=${VIEWER_CHANNEL}"
|
||||
|
|
@ -2195,6 +2210,7 @@ if (DARWIN)
|
|||
--arch=${ARCH}
|
||||
--artwork=${ARTWORK_DIR}
|
||||
"--bugsplat=${BUGSPLAT_DB}"
|
||||
"--fmodstudio=${FMODSTUDIO}"
|
||||
--build=${CMAKE_CURRENT_BINARY_DIR}
|
||||
--buildtype=${CMAKE_BUILD_TYPE}
|
||||
--bundleid=${MACOSX_BUNDLE_GUI_IDENTIFIER}
|
||||
|
|
@ -2229,6 +2245,7 @@ if (DARWIN)
|
|||
--arch=${ARCH}
|
||||
--artwork=${ARTWORK_DIR}
|
||||
"--bugsplat=${BUGSPLAT_DB}"
|
||||
"--fmodstudio=${FMODSTUDIO}"
|
||||
--build=${CMAKE_CURRENT_BINARY_DIR}
|
||||
--buildtype=${CMAKE_BUILD_TYPE}
|
||||
"--channel=${VIEWER_CHANNEL}"
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
6.4.2
|
||||
6.4.3
|
||||
|
|
|
|||
|
|
@ -0,0 +1,142 @@
|
|||
<llsd>
|
||||
<map>
|
||||
<key>AppearanceCameraMovement</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>When entering appearance editing mode, camera zooms in on currently selected portion of avatar</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>AvatarSitRotation</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Avatar real sitting rotation used in preset</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>LLSD</string>
|
||||
<key>Value</key>
|
||||
<array>
|
||||
<real>0</real>
|
||||
<real>0</real>
|
||||
<real>0</real>
|
||||
<real>1</real>
|
||||
</array>
|
||||
</map>
|
||||
<key>CameraAngle</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Camera field of view angle (Radians)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>1.047197551</real>
|
||||
</map>
|
||||
<key>CameraOffsetBuild</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Default camera position relative to focus point when entering build mode</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Vector3</string>
|
||||
<key>Value</key>
|
||||
<array>
|
||||
<real>-6</real>
|
||||
<real>0</real>
|
||||
<real>6</real>
|
||||
</array>
|
||||
</map>
|
||||
<key>CameraOffsetRearView</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Initial camera offset from avatar in Front View</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Vector3</string>
|
||||
<key>Value</key>
|
||||
<array>
|
||||
<real>2.2</real>
|
||||
<real>0.0</real>
|
||||
<real>0.0</real>
|
||||
</array>
|
||||
</map>
|
||||
<key>CameraOffsetScale</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Scales the default offset</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>1</real>
|
||||
</map>
|
||||
<key>CameraZoomFraction</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Mousewheel driven fraction of zoom</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>0.90322577953338623</real>
|
||||
</map>
|
||||
<key>EditCameraMovement</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>When entering build mode, camera moves up above avatar</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>FocusOffsetRearView</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Initial focus point offset relative to avatar for the camera preset Front View (x-axis is forward)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Vector3D</string>
|
||||
<key>Value</key>
|
||||
<array>
|
||||
<real>0.0</real>
|
||||
<real>0.0</real>
|
||||
<real>0.0</real>
|
||||
</array>
|
||||
</map>
|
||||
<key>PresetCameraActive</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Name of currently selected preference</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string>Default</string>
|
||||
</map>
|
||||
<key>TrackFocusObject</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Camera tracks last object zoomed on</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
</map>
|
||||
</llsd>
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
<llsd>
|
||||
<map>
|
||||
<key>AppearanceCameraMovement</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>When entering appearance editing mode, camera zooms in on currently selected portion of avatar</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>AvatarSitRotation</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Avatar real sitting rotation used in preset</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>LLSD</string>
|
||||
<key>Value</key>
|
||||
<array>
|
||||
<real>0</real>
|
||||
<real>0</real>
|
||||
<real>0</real>
|
||||
<real>1</real>
|
||||
</array>
|
||||
</map>
|
||||
<key>CameraAngle</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Camera field of view angle (Radians)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>1.047197551</real>
|
||||
</map>
|
||||
<key>CameraOffsetBuild</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Default camera position relative to focus point when entering build mode</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Vector3</string>
|
||||
<key>Value</key>
|
||||
<array>
|
||||
<real>-6</real>
|
||||
<real>0</real>
|
||||
<real>6</real>
|
||||
</array>
|
||||
</map>
|
||||
<key>CameraOffsetRearView</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Initial camera offset from avatar in Rear View</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Vector3</string>
|
||||
<key>Value</key>
|
||||
<array>
|
||||
<real>-3</real>
|
||||
<real>0</real>
|
||||
<real>0.75</real>
|
||||
</array>
|
||||
</map>
|
||||
<key>CameraOffsetScale</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Scales the default offset</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>1</real>
|
||||
</map>
|
||||
<key>CameraZoomFraction</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Mousewheel driven fraction of zoom</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>0.90322577953338623</real>
|
||||
</map>
|
||||
<key>EditCameraMovement</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>When entering build mode, camera moves up above avatar</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>FocusOffsetRearView</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Initial focus point offset relative to avatar for the camera preset Rear View (x-axis is forward)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Vector3D</string>
|
||||
<key>Value</key>
|
||||
<array>
|
||||
<real>1.0</real>
|
||||
<real>0.0</real>
|
||||
<real>1.0</real>
|
||||
</array>
|
||||
</map>
|
||||
<key>PresetCameraActive</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Name of currently selected preference</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string>Default</string>
|
||||
</map>
|
||||
<key>TrackFocusObject</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Camera tracks last object zoomed on</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
</map>
|
||||
</llsd>
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
<llsd>
|
||||
<map>
|
||||
<key>AppearanceCameraMovement</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>When entering appearance editing mode, camera zooms in on currently selected portion of avatar</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>AvatarSitRotation</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Avatar real sitting rotation used in preset</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>LLSD</string>
|
||||
<key>Value</key>
|
||||
<array>
|
||||
<real>0</real>
|
||||
<real>0</real>
|
||||
<real>0</real>
|
||||
<real>1</real>
|
||||
</array>
|
||||
</map>
|
||||
<key>CameraAngle</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Camera field of view angle (Radians)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>1.047197551</real>
|
||||
</map>
|
||||
<key>CameraOffsetBuild</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Default camera position relative to focus point when entering build mode</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Vector3</string>
|
||||
<key>Value</key>
|
||||
<array>
|
||||
<real>-6</real>
|
||||
<real>0</real>
|
||||
<real>6</real>
|
||||
</array>
|
||||
</map>
|
||||
<key>CameraOffsetRearView</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Initial camera offset from avatar in Side View</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Vector3</string>
|
||||
<key>Value</key>
|
||||
<array>
|
||||
<real>-1.0</real>
|
||||
<real>0.7</real>
|
||||
<real>0.5</real>
|
||||
</array>
|
||||
</map>
|
||||
<key>CameraOffsetScale</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Scales the default offset</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>1</real>
|
||||
</map>
|
||||
<key>CameraZoomFraction</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Mousewheel driven fraction of zoom</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>0.90322577953338623</real>
|
||||
</map>
|
||||
<key>EditCameraMovement</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>When entering build mode, camera moves up above avatar</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>FocusOffsetRearView</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Initial focus point offset relative to avatar for the camera preset Side View (x-axis is forward)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Vector3D</string>
|
||||
<key>Value</key>
|
||||
<array>
|
||||
<real>1.5</real>
|
||||
<real>0.7</real>
|
||||
<real>1.0</real>
|
||||
</array>
|
||||
</map>
|
||||
<key>PresetCameraActive</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Name of currently selected preference</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string>Default</string>
|
||||
</map>
|
||||
<key>TrackFocusObject</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Camera tracks last object zoomed on</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
</map>
|
||||
</llsd>
|
||||
|
|
@ -1818,6 +1818,21 @@
|
|||
<real>0.5</real>
|
||||
</array>
|
||||
</map>
|
||||
<key>CameraOffsetCustomPreset</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Initial camera offset from avatar for the custom camera preset</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Vector3</string>
|
||||
<key>Value</key>
|
||||
<array>
|
||||
<real>-3.0</real>
|
||||
<real>0.0</real>
|
||||
<real>0.75</real>
|
||||
</array>
|
||||
</map>
|
||||
<key>CameraOffsetScale</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -1829,6 +1844,17 @@
|
|||
<key>Value</key>
|
||||
<real>1.0</real>
|
||||
</map>
|
||||
<key>CameraZoomFraction</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Mousewheel driven fraction of zoom</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>0.9</real>
|
||||
</map>
|
||||
<key>CameraPosOnLogout</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -1866,7 +1892,7 @@
|
|||
<key>Value</key>
|
||||
<real>1.0</real>
|
||||
</map>
|
||||
<key>CameraPreset</key>
|
||||
<key>CameraPreset</key> <!-- deprecated (see SL-12429) -->
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Preset camera position - view (0 - rear, 1 - front, 2 - group)</string>
|
||||
|
|
@ -4686,6 +4712,37 @@
|
|||
<real>1.0</real>
|
||||
</array>
|
||||
</map>
|
||||
<key>FocusOffsetCustomPreset</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Initial focus point offset relative to avatar for the custom camera preset (x-axis is forward)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Vector3D</string>
|
||||
<key>Value</key>
|
||||
<array>
|
||||
<real>1.0</real>
|
||||
<real>0.0</real>
|
||||
<real>1.0</real>
|
||||
</array>
|
||||
</map>
|
||||
<key>AvatarSitRotation</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Avatar real sitting rotation used in preset</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>LLSD</string>
|
||||
<key>Value</key>
|
||||
<array>
|
||||
<real>0</real>
|
||||
<real>0</real>
|
||||
<real>0</real>
|
||||
<real>1</real>
|
||||
</array>
|
||||
</map>
|
||||
<key>FocusPosOnLogout</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -16668,7 +16725,7 @@
|
|||
<key>FMODExProfilerEnable</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Enable profiler tool if using FMOD Ex</string>
|
||||
<string>Enable profiler tool if using FMOD Ex or FMOD Studio</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
|
|
@ -16679,7 +16736,7 @@
|
|||
<key>FMODExDecodeBufferSize</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Sets the streaming decode buffer size (in milliseconds)</string>
|
||||
<string>Sets the streaming decode buffer size (in milliseconds) for FMOD Ex or FMOD Studio</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
|
|
@ -16690,7 +16747,7 @@
|
|||
<key>FMODExStreamBufferSize</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Sets the streaming buffer size (in milliseconds)</string>
|
||||
<string>Sets the streaming buffer size (in milliseconds) for FMOD Ex or FMOD Studio</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
|
|
@ -16833,6 +16890,50 @@
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>CameraOpacity</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Opacity of the Camera Controls floater</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>1.0</real>
|
||||
</map>
|
||||
<key>PresetCameraActive</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Name of currently selected preference</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string>Rear View</string>
|
||||
</map>
|
||||
<key>CameraPresetType</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Preset camera position - view (0 - rear, 1 - front, 2 - group, 3 - custom)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>U32</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>HoverHeightAffectsCamera</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Camera view is affected by Hover Height setting</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>CefVerboseLog</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
|
|||
|
|
@ -187,8 +187,8 @@ The 'secondlife' script which launches Second Life contains some
|
|||
configuration options for advanced troubleshooters.
|
||||
|
||||
* AUDIO - Edit the 'secondlife' script and you will see these audio
|
||||
options: LL_BAD_OPENAL_DRIVER, LL_BAD_FMOD_ESD, LL_BAD_FMOD_OSS, and
|
||||
LL_BAD_FMOD_ALSA. Second Life tries to use OpenAL, ESD, OSS, then ALSA
|
||||
options: LL_BAD_OPENAL_DRIVER, LL_BAD_FMODSTUDIO_DRIVER.
|
||||
Second Life tries to use OpenAL, FMODSTUDIO (PULSEAUDIO, ALSA)
|
||||
audio drivers in this order; you may uncomment the corresponding LL_BAD_*
|
||||
option to skip an audio driver which you believe may be causing you trouble.
|
||||
|
||||
|
|
|
|||
|
|
@ -4,17 +4,15 @@
|
|||
## These options are for self-assisted troubleshooting during this beta
|
||||
## testing phase; you should not usually need to touch them.
|
||||
|
||||
## - Avoids using any FMOD Ex audio driver.
|
||||
#export LL_BAD_FMODEX_DRIVER=x
|
||||
## - Avoids using any FMOD STUDIO audio driver.
|
||||
#export LL_BAD_FMODSTUDIO_DRIVER=x
|
||||
## - Avoids using any OpenAL audio driver.
|
||||
#export LL_BAD_OPENAL_DRIVER=x
|
||||
|
||||
## - Avoids using the FMOD Ex PulseAudio audio driver.
|
||||
## - Avoids using the FMOD Studio or FMOD Ex PulseAudio audio driver.
|
||||
#export LL_BAD_FMOD_PULSEAUDIO=x
|
||||
## - Avoids using the FMOD or FMOD Ex ALSA audio driver.
|
||||
## - Avoids using the FMOD Studio or FMOD Ex ALSA audio driver.
|
||||
#export LL_BAD_FMOD_ALSA=x
|
||||
## - Avoids using the FMOD or FMOD Ex OSS audio driver.
|
||||
#export LL_BAD_FMOD_OSS=x
|
||||
|
||||
## - Avoids the optional OpenGL extensions which have proven most problematic
|
||||
## on some hardware. Disabling this option may cause BETTER PERFORMANCE but
|
||||
|
|
|
|||
|
|
@ -188,6 +188,9 @@ LLAgentCamera::LLAgentCamera() :
|
|||
clearGeneralKeys();
|
||||
clearOrbitKeys();
|
||||
clearPanKeys();
|
||||
|
||||
resetPanDiff();
|
||||
resetOrbitDiff();
|
||||
}
|
||||
|
||||
// Requires gSavedSettings to be initialized.
|
||||
|
|
@ -209,19 +212,14 @@ void LLAgentCamera::init()
|
|||
|
||||
mCameraFocusOffsetTarget = LLVector4(gSavedSettings.getVector3("CameraOffsetBuild"));
|
||||
|
||||
mCameraPreset = (ECameraPreset) gSavedSettings.getU32("CameraPreset");
|
||||
mCameraPreset = (ECameraPreset) gSavedSettings.getU32("CameraPresetType");
|
||||
|
||||
mCameraOffsetInitial[CAMERA_PRESET_REAR_VIEW] = gSavedSettings.getControl("CameraOffsetRearView");
|
||||
mCameraOffsetInitial[CAMERA_PRESET_FRONT_VIEW] = gSavedSettings.getControl("CameraOffsetFrontView");
|
||||
mCameraOffsetInitial[CAMERA_PRESET_GROUP_VIEW] = gSavedSettings.getControl("CameraOffsetGroupView");
|
||||
mCameraOffsetInitial = gSavedSettings.getControl("CameraOffsetRearView");
|
||||
mFocusOffsetInitial = gSavedSettings.getControl("FocusOffsetRearView");
|
||||
// [RLVa:KB] - Checked: RLVa-2.0.0
|
||||
mCameraOffsetInitial[CAMERA_RLV_SETCAM_VIEW] = gSavedSettings.declareVec3("CameraOffsetRLVaView", LLVector3(mCameraOffsetInitial[CAMERA_PRESET_REAR_VIEW]->getDefault()), "Declared in code", LLControlVariable::PERSIST_NO);
|
||||
mCameraOffsetInitial[CAMERA_RLV_SETCAM_VIEW]->setHiddenFromSettingsEditor(true);
|
||||
// [/RLVa:KB]
|
||||
|
||||
mFocusOffsetInitial[CAMERA_PRESET_REAR_VIEW] = gSavedSettings.getControl("FocusOffsetRearView");
|
||||
mFocusOffsetInitial[CAMERA_PRESET_FRONT_VIEW] = gSavedSettings.getControl("FocusOffsetFrontView");
|
||||
mFocusOffsetInitial[CAMERA_PRESET_GROUP_VIEW] = gSavedSettings.getControl("FocusOffsetGroupView");
|
||||
// [RLVa:KB] - Checked: RLVa-2.0.0
|
||||
mFocusOffsetInitial[CAMERA_RLV_SETCAM_VIEW] = gSavedSettings.declareVec3("FocusOffsetRLVaView", LLVector3(mFocusOffsetInitial[CAMERA_PRESET_REAR_VIEW]->getDefault()), "Declared in code", LLControlVariable::PERSIST_NO);
|
||||
mFocusOffsetInitial[CAMERA_RLV_SETCAM_VIEW]->setHiddenFromSettingsEditor(true);
|
||||
|
|
@ -365,7 +363,8 @@ void LLAgentCamera::resetView(BOOL reset_camera, BOOL change_camera)
|
|||
|
||||
mCameraFOVZoomFactor = 0.f;
|
||||
}
|
||||
|
||||
resetPanDiff();
|
||||
resetOrbitDiff();
|
||||
mHUDTargetZoom = 1.f;
|
||||
}
|
||||
|
||||
|
|
@ -735,7 +734,7 @@ BOOL LLAgentCamera::calcCameraMinDistance(F32 &obj_min_distance)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
F32 LLAgentCamera::getCameraZoomFraction()
|
||||
F32 LLAgentCamera::getCameraZoomFraction(bool get_third_person)
|
||||
{
|
||||
// 0.f -> camera zoomed all the way out
|
||||
// 1.f -> camera zoomed all the way in
|
||||
|
|
@ -745,7 +744,7 @@ F32 LLAgentCamera::getCameraZoomFraction()
|
|||
// already [0,1]
|
||||
return mHUDTargetZoom;
|
||||
}
|
||||
else if (mFocusOnAvatar && cameraThirdPerson())
|
||||
else if (get_third_person || (mFocusOnAvatar && cameraThirdPerson()))
|
||||
{
|
||||
return clamp_rescale(mCameraZoomFraction, MIN_ZOOM_FRACTION, MAX_ZOOM_FRACTION, 1.f, 0.f);
|
||||
}
|
||||
|
|
@ -807,13 +806,16 @@ void LLAgentCamera::setCameraZoomFraction(F32 fraction)
|
|||
|
||||
if (mFocusObject.notNull())
|
||||
{
|
||||
if (mFocusObject->isAvatar())
|
||||
if (mFocusObject.notNull())
|
||||
{
|
||||
min_zoom = AVATAR_MIN_ZOOM;
|
||||
}
|
||||
else
|
||||
{
|
||||
min_zoom = OBJECT_MIN_ZOOM;
|
||||
if (mFocusObject->isAvatar())
|
||||
{
|
||||
min_zoom = AVATAR_MIN_ZOOM;
|
||||
}
|
||||
else
|
||||
{
|
||||
min_zoom = OBJECT_MIN_ZOOM;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -853,6 +855,7 @@ void LLAgentCamera::cameraOrbitAround(const F32 radians)
|
|||
}
|
||||
else
|
||||
{
|
||||
mOrbitAroundRadians += radians;
|
||||
mCameraFocusOffsetTarget.rotVec(radians, 0.f, 0.f, 1.f);
|
||||
|
||||
cameraZoomIn(1.f);
|
||||
|
|
@ -884,12 +887,34 @@ void LLAgentCamera::cameraOrbitOver(const F32 angle)
|
|||
LLVector3d left_axis;
|
||||
left_axis.setVec(LLViewerCamera::getInstance()->getLeftAxis());
|
||||
F32 new_angle = llclamp(angle_from_up - angle, 1.f * DEG_TO_RAD, 179.f * DEG_TO_RAD);
|
||||
mOrbitOverAngle += angle_from_up - new_angle;
|
||||
mCameraFocusOffsetTarget.rotVec(angle_from_up - new_angle, left_axis);
|
||||
|
||||
cameraZoomIn(1.f);
|
||||
}
|
||||
}
|
||||
|
||||
void LLAgentCamera::resetCameraOrbit()
|
||||
{
|
||||
LLVector3 camera_offset_unit(mCameraFocusOffsetTarget);
|
||||
camera_offset_unit.normalize();
|
||||
|
||||
LLVector3d left_axis;
|
||||
left_axis.setVec(LLViewerCamera::getInstance()->getLeftAxis());
|
||||
mCameraFocusOffsetTarget.rotVec(-mOrbitOverAngle, left_axis);
|
||||
|
||||
mCameraFocusOffsetTarget.rotVec(-mOrbitAroundRadians, 0.f, 0.f, 1.f);
|
||||
|
||||
cameraZoomIn(1.f);
|
||||
resetOrbitDiff();
|
||||
}
|
||||
|
||||
void LLAgentCamera::resetOrbitDiff()
|
||||
{
|
||||
mOrbitAroundRadians = 0;
|
||||
mOrbitOverAngle = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// cameraZoomIn()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -1038,6 +1063,8 @@ void LLAgentCamera::cameraPanIn(F32 meters)
|
|||
LLVector3d at_axis;
|
||||
at_axis.setVec(LLViewerCamera::getInstance()->getAtAxis());
|
||||
|
||||
mPanFocusDiff += meters * at_axis;
|
||||
|
||||
mFocusTargetGlobal += meters * at_axis;
|
||||
mFocusGlobal = mFocusTargetGlobal;
|
||||
// don't enforce zoom constraints as this is the only way for users to get past them easily
|
||||
|
|
@ -1054,6 +1081,8 @@ void LLAgentCamera::cameraPanLeft(F32 meters)
|
|||
LLVector3d left_axis;
|
||||
left_axis.setVec(LLViewerCamera::getInstance()->getLeftAxis());
|
||||
|
||||
mPanFocusDiff += meters * left_axis;
|
||||
|
||||
mFocusTargetGlobal += meters * left_axis;
|
||||
mFocusGlobal = mFocusTargetGlobal;
|
||||
|
||||
|
|
@ -1074,6 +1103,8 @@ void LLAgentCamera::cameraPanUp(F32 meters)
|
|||
LLVector3d up_axis;
|
||||
up_axis.setVec(LLViewerCamera::getInstance()->getUpAxis());
|
||||
|
||||
mPanFocusDiff += meters * up_axis;
|
||||
|
||||
mFocusTargetGlobal += meters * up_axis;
|
||||
mFocusGlobal = mFocusTargetGlobal;
|
||||
|
||||
|
|
@ -1086,6 +1117,26 @@ void LLAgentCamera::cameraPanUp(F32 meters)
|
|||
mCameraSmoothingLastPositionGlobal = calcCameraPositionTargetGlobal();
|
||||
}
|
||||
|
||||
void LLAgentCamera::resetCameraPan()
|
||||
{
|
||||
mFocusTargetGlobal -= mPanFocusDiff;
|
||||
|
||||
mFocusGlobal = mFocusTargetGlobal;
|
||||
mCameraSmoothingStop = true;
|
||||
|
||||
cameraZoomIn(1.f);
|
||||
updateFocusOffset();
|
||||
|
||||
mCameraSmoothingLastPositionGlobal = calcCameraPositionTargetGlobal();
|
||||
|
||||
resetPanDiff();
|
||||
}
|
||||
|
||||
void LLAgentCamera::resetPanDiff()
|
||||
{
|
||||
mPanFocusDiff.clear();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// updateLookAt()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -1645,7 +1696,7 @@ LLVector3d LLAgentCamera::calcThirdPersonFocusOffset()
|
|||
agent_rot *= ((LLViewerObject*)(gAgentAvatarp->getParent()))->getRenderRotation();
|
||||
}
|
||||
|
||||
focus_offset = convert_from_llsd<LLVector3d>(mFocusOffsetInitial[mCameraPreset]->get(), TYPE_VEC3D, "");
|
||||
focus_offset = convert_from_llsd<LLVector3d>(mFocusOffsetInitial->get(), TYPE_VEC3D, "");
|
||||
return focus_offset * agent_rot;
|
||||
}
|
||||
|
||||
|
|
@ -1720,7 +1771,7 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit)
|
|||
F32 camera_land_height;
|
||||
LLVector3d frame_center_global = !isAgentAvatarValid() ?
|
||||
gAgent.getPositionGlobal() :
|
||||
gAgent.getPosGlobalFromAgent(gAgentAvatarp->mRoot->getWorldPosition());
|
||||
gAgent.getPosGlobalFromAgent(getAvatarRootPosition());
|
||||
|
||||
BOOL isConstrained = FALSE;
|
||||
LLVector3d head_offset;
|
||||
|
|
@ -1794,7 +1845,7 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit)
|
|||
at_axis.mV[VZ] = 0.f;
|
||||
at_axis.normalize();
|
||||
gAgent.resetAxes(at_axis * ~parent_rot);
|
||||
|
||||
|
||||
local_camera_offset = local_camera_offset * gAgent.getFrameAgent().getQuaternion() * parent_rot;
|
||||
}
|
||||
else
|
||||
|
|
@ -2056,9 +2107,38 @@ bool LLAgentCamera::clampCameraPosition(LLVector3d& posCamGlobal, const LLVector
|
|||
}
|
||||
// [/RLVa:KB]
|
||||
|
||||
LLVector3 LLAgentCamera::getCurrentCameraOffset()
|
||||
{
|
||||
return (LLViewerCamera::getInstance()->getOrigin() - getAvatarRootPosition() - mThirdPersonHeadOffset) * ~getCurrentAvatarRotation();
|
||||
}
|
||||
|
||||
LLVector3d LLAgentCamera::getCurrentFocusOffset()
|
||||
{
|
||||
return (mFocusTargetGlobal - gAgent.getPositionGlobal()) * ~getCurrentAvatarRotation();
|
||||
}
|
||||
|
||||
LLQuaternion LLAgentCamera::getCurrentAvatarRotation()
|
||||
{
|
||||
LLViewerObject* sit_object = (LLViewerObject*)gAgentAvatarp->getParent();
|
||||
|
||||
LLQuaternion av_rot = gAgent.getFrameAgent().getQuaternion();
|
||||
LLQuaternion obj_rot = sit_object ? sit_object->getRenderRotation() : LLQuaternion::DEFAULT;
|
||||
return av_rot * obj_rot;
|
||||
}
|
||||
|
||||
bool LLAgentCamera::isJoystickCameraUsed()
|
||||
{
|
||||
return ((mOrbitAroundRadians != 0) || (mOrbitOverAngle != 0) || !mPanFocusDiff.isNull());
|
||||
}
|
||||
|
||||
LLVector3 LLAgentCamera::getCameraOffsetInitial()
|
||||
{
|
||||
return convert_from_llsd<LLVector3>(mCameraOffsetInitial[mCameraPreset]->get(), TYPE_VEC3, "");
|
||||
return convert_from_llsd<LLVector3>(mCameraOffsetInitial->get(), TYPE_VEC3, "");
|
||||
}
|
||||
|
||||
LLVector3d LLAgentCamera::getFocusOffsetInitial()
|
||||
{
|
||||
return convert_from_llsd<LLVector3d>(mFocusOffsetInitial->get(), TYPE_VEC3D, "");
|
||||
}
|
||||
|
||||
F32 LLAgentCamera::getCameraMaxZoomDistance()
|
||||
|
|
@ -2069,6 +2149,12 @@ F32 LLAgentCamera::getCameraMaxZoomDistance()
|
|||
LLWorld::getInstance()->getRegionWidthInMeters() - CAMERA_FUDGE_FROM_OBJECT);
|
||||
}
|
||||
|
||||
LLVector3 LLAgentCamera::getAvatarRootPosition()
|
||||
{
|
||||
static LLCachedControl<bool> use_hover_height(gSavedSettings, "HoverHeightAffectsCamera");
|
||||
return use_hover_height ? gAgentAvatarp->mRoot->getWorldPosition() : gAgentAvatarp->mRoot->getWorldPosition() - gAgentAvatarp->getHoverOffset();
|
||||
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// handleScrollWheel()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -2352,15 +2438,7 @@ void LLAgentCamera::changeCameraToThirdPerson(BOOL animate)
|
|||
}
|
||||
|
||||
// Remove any pitch from the avatar
|
||||
if (isAgentAvatarValid() && gAgentAvatarp->getParent())
|
||||
{
|
||||
LLQuaternion obj_rot = ((LLViewerObject*)gAgentAvatarp->getParent())->getRenderRotation();
|
||||
at_axis = LLViewerCamera::getInstance()->getAtAxis();
|
||||
at_axis.mV[VZ] = 0.f;
|
||||
at_axis.normalize();
|
||||
gAgent.resetAxes(at_axis * ~obj_rot);
|
||||
}
|
||||
else
|
||||
if (!isAgentAvatarValid() || !gAgentAvatarp->getParent())
|
||||
{
|
||||
at_axis = gAgent.getFrameAgent().getAtAxis();
|
||||
at_axis.mV[VZ] = 0.f;
|
||||
|
|
@ -2486,7 +2564,10 @@ void LLAgentCamera::switchCameraPreset(ECameraPreset preset)
|
|||
|
||||
mCameraPreset = preset;
|
||||
|
||||
gSavedSettings.setU32("CameraPreset", mCameraPreset);
|
||||
resetPanDiff();
|
||||
resetOrbitDiff();
|
||||
|
||||
gSavedSettings.setU32("CameraPresetType", mCameraPreset);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -2731,7 +2812,7 @@ void LLAgentCamera::setSitCamera(const LLUUID &object_id, const LLVector3 &camer
|
|||
//-----------------------------------------------------------------------------
|
||||
// setFocusOnAvatar()
|
||||
//-----------------------------------------------------------------------------
|
||||
void LLAgentCamera::setFocusOnAvatar(BOOL focus_on_avatar, BOOL animate)
|
||||
void LLAgentCamera::setFocusOnAvatar(BOOL focus_on_avatar, BOOL animate, BOOL reset_axes)
|
||||
{
|
||||
if (focus_on_avatar != mFocusOnAvatar)
|
||||
{
|
||||
|
|
@ -2748,22 +2829,14 @@ void LLAgentCamera::setFocusOnAvatar(BOOL focus_on_avatar, BOOL animate)
|
|||
//RN: when focused on the avatar, we're not "looking" at it
|
||||
// looking implies intent while focusing on avatar means
|
||||
// you're just walking around with a camera on you...eesh.
|
||||
if (!mFocusOnAvatar && focus_on_avatar)
|
||||
if (!mFocusOnAvatar && focus_on_avatar && reset_axes)
|
||||
{
|
||||
setFocusGlobal(LLVector3d::zero);
|
||||
mCameraFOVZoomFactor = 0.f;
|
||||
if (mCameraMode == CAMERA_MODE_THIRD_PERSON)
|
||||
{
|
||||
LLVector3 at_axis;
|
||||
if (isAgentAvatarValid() && gAgentAvatarp->getParent())
|
||||
{
|
||||
LLQuaternion obj_rot = ((LLViewerObject*)gAgentAvatarp->getParent())->getRenderRotation();
|
||||
at_axis = LLViewerCamera::getInstance()->getAtAxis();
|
||||
at_axis.mV[VZ] = 0.f;
|
||||
at_axis.normalize();
|
||||
gAgent.resetAxes(at_axis * ~obj_rot);
|
||||
}
|
||||
else
|
||||
if (!isAgentAvatarValid() || !gAgentAvatarp->getParent())
|
||||
{
|
||||
at_axis = LLViewerCamera::getInstance()->getAtAxis();
|
||||
at_axis.mV[VZ] = 0.f;
|
||||
|
|
@ -2911,6 +2984,17 @@ BOOL LLAgentCamera::setPointAt(EPointAtType target_type, LLViewerObject *object,
|
|||
return mPointAt->setPointAt(target_type, object, position);
|
||||
}
|
||||
|
||||
void LLAgentCamera::rotateToInitSitRot()
|
||||
{
|
||||
gAgent.rotate(~gAgent.getFrameAgent().getQuaternion());
|
||||
gAgent.rotate(mInitSitRot);
|
||||
}
|
||||
|
||||
void LLAgentCamera::resetCameraZoomFraction()
|
||||
{
|
||||
mCameraZoomFraction = INITIAL_ZOOM_FRACTION;
|
||||
}
|
||||
|
||||
ELookAtType LLAgentCamera::getLookAtType()
|
||||
{
|
||||
if (mLookAt)
|
||||
|
|
|
|||
|
|
@ -58,9 +58,12 @@ enum ECameraPreset
|
|||
/** "Above and to the left, over the shoulder, pulled back a little on the zoom" */
|
||||
CAMERA_PRESET_GROUP_VIEW,
|
||||
|
||||
// [RLVa:KB] - Checked: RLVa-2.0.0
|
||||
/** Current view when a preset is saved */
|
||||
CAMERA_PRESET_CUSTOM,
|
||||
|
||||
// [RLVa:KB] - @setcam_eyeoffset and @setcam_focusoffset// [RLVa:KB] - Checked: RLVa-2.0.0
|
||||
/* Used by RLVa */
|
||||
CAMERA_RLV_SETCAM_VIEW
|
||||
CAMERA_RLV_SETCAM_VIEW,
|
||||
// [/RLVa:KB]
|
||||
};
|
||||
|
||||
|
|
@ -114,20 +117,32 @@ private:
|
|||
//--------------------------------------------------------------------
|
||||
public:
|
||||
void switchCameraPreset(ECameraPreset preset);
|
||||
private:
|
||||
/** Determines default camera offset depending on the current camera preset */
|
||||
LLVector3 getCameraOffsetInitial();
|
||||
/** Determines default focus offset depending on the current camera preset */
|
||||
LLVector3d getFocusOffsetInitial();
|
||||
|
||||
LLVector3 getCurrentCameraOffset();
|
||||
LLVector3d getCurrentFocusOffset();
|
||||
LLQuaternion getCurrentAvatarRotation();
|
||||
bool isJoystickCameraUsed();
|
||||
void setInitSitRot(LLQuaternion sit_rot) { mInitSitRot = sit_rot; };
|
||||
void rotateToInitSitRot();
|
||||
|
||||
private:
|
||||
/** Determines maximum camera distance from target for mouselook, opposite to LAND_MIN_ZOOM */
|
||||
F32 getCameraMaxZoomDistance();
|
||||
|
||||
/** Camera preset in Third Person Mode */
|
||||
ECameraPreset mCameraPreset;
|
||||
|
||||
/** Initial camera offsets */
|
||||
std::map<ECameraPreset, LLPointer<LLControlVariable> > mCameraOffsetInitial;
|
||||
/** Initial camera offset */
|
||||
LLPointer<LLControlVariable> mCameraOffsetInitial;
|
||||
|
||||
/** Initial focus offsets */
|
||||
std::map<ECameraPreset, LLPointer<LLControlVariable> > mFocusOffsetInitial;
|
||||
/** Initial focus offset */
|
||||
LLPointer<LLControlVariable> mFocusOffsetInitial;
|
||||
|
||||
LLQuaternion mInitSitRot;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Position
|
||||
|
|
@ -142,6 +157,8 @@ public:
|
|||
F32 getCurrentCameraBuildOffset() { return (F32)mCameraFocusOffset.length(); }
|
||||
void clearCameraLag() { mCameraLag.clearVec(); }
|
||||
private:
|
||||
LLVector3 getAvatarRootPosition();
|
||||
|
||||
F32 mCurrentCameraDistance; // Current camera offset from avatar
|
||||
F32 mTargetCameraDistance; // Target camera offset from avatar
|
||||
F32 mCameraFOVZoomFactor; // Amount of fov zoom applied to camera when zeroing in on an object
|
||||
|
|
@ -209,7 +226,7 @@ public:
|
|||
void validateFocusObject();
|
||||
void setFocusGlobal(const LLPickInfo& pick);
|
||||
void setFocusGlobal(const LLVector3d &focus, const LLUUID &object_id = LLUUID::null);
|
||||
void setFocusOnAvatar(BOOL focus, BOOL animate);
|
||||
void setFocusOnAvatar(BOOL focus, BOOL animate, BOOL reset_axes = TRUE);
|
||||
void setCameraPosAndFocusGlobal(const LLVector3d& pos, const LLVector3d& focus, const LLUUID &object_id);
|
||||
void clearFocusObject();
|
||||
void setFocusObject(LLViewerObject* object);
|
||||
|
|
@ -261,26 +278,31 @@ public:
|
|||
void cameraOrbitAround(const F32 radians); // Rotate camera CCW radians about build focus point
|
||||
void cameraOrbitOver(const F32 radians); // Rotate camera forward radians over build focus point
|
||||
void cameraOrbitIn(const F32 meters); // Move camera in toward build focus point
|
||||
|
||||
void resetCameraOrbit();
|
||||
void resetOrbitDiff();
|
||||
//--------------------------------------------------------------------
|
||||
// Zoom
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
void handleScrollWheel(S32 clicks); // Mousewheel driven zoom
|
||||
void cameraZoomIn(const F32 factor); // Zoom in by fraction of current distance
|
||||
F32 getCameraZoomFraction(); // Get camera zoom as fraction of minimum and maximum zoom
|
||||
void setCameraZoomFraction(F32 fraction); // Set camera zoom as fraction of minimum and maximum zoom
|
||||
void handleScrollWheel(S32 clicks); // Mousewheel driven zoom
|
||||
void cameraZoomIn(const F32 factor); // Zoom in by fraction of current distance
|
||||
F32 getCameraZoomFraction(bool get_third_person = false); // Get camera zoom as fraction of minimum and maximum zoom
|
||||
void setCameraZoomFraction(F32 fraction); // Set camera zoom as fraction of minimum and maximum zoom
|
||||
F32 calcCameraFOVZoomFactor();
|
||||
F32 getAgentHUDTargetZoom();
|
||||
|
||||
void resetCameraZoomFraction();
|
||||
F32 getCurrentCameraZoomFraction() { return mCameraZoomFraction; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Pan
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
void cameraPanIn(const F32 meters);
|
||||
void cameraPanLeft(const F32 meters);
|
||||
void cameraPanUp(const F32 meters);
|
||||
|
||||
void cameraPanUp(const F32 meters);
|
||||
void resetCameraPan();
|
||||
void resetPanDiff();
|
||||
//--------------------------------------------------------------------
|
||||
// View
|
||||
//--------------------------------------------------------------------
|
||||
|
|
@ -379,6 +401,9 @@ private:
|
|||
F32 mOrbitInKey;
|
||||
F32 mOrbitOutKey;
|
||||
|
||||
F32 mOrbitAroundRadians;
|
||||
F32 mOrbitOverAngle;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Pan
|
||||
//--------------------------------------------------------------------
|
||||
|
|
@ -406,6 +431,8 @@ private:
|
|||
F32 mPanInKey;
|
||||
F32 mPanOutKey;
|
||||
|
||||
LLVector3d mPanFocusDiff;
|
||||
|
||||
/** Keys
|
||||
** **
|
||||
*******************************************************************************/
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
// Viewer includes
|
||||
#include "llagent.h"
|
||||
#include "llagentcamera.h"
|
||||
#include "llpresetsmanager.h"
|
||||
#include "lljoystickbutton.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llviewercamera.h"
|
||||
|
|
@ -42,6 +43,8 @@
|
|||
#include "llslider.h"
|
||||
#include "llfirstuse.h"
|
||||
#include "llhints.h"
|
||||
#include "lltabcontainer.h"
|
||||
#include "llvoavatarself.h"
|
||||
|
||||
static LLDefaultChildRegistry::Register<LLPanelCameraItem> r("panel_camera_item");
|
||||
|
||||
|
|
@ -52,7 +55,6 @@ const F32 ORBIT_NUDGE_RATE = 0.05f; // fraction of normal speed
|
|||
#define ORBIT "cam_rotate_stick"
|
||||
#define PAN "cam_track_stick"
|
||||
#define ZOOM "zoom"
|
||||
#define PRESETS "preset_views_list"
|
||||
#define CONTROLS "controls"
|
||||
|
||||
bool LLFloaterCamera::sFreeCamera = false;
|
||||
|
|
@ -269,13 +271,7 @@ void LLFloaterCamera::onAvatarEditingAppearance(bool editing)
|
|||
|
||||
void LLFloaterCamera::handleAvatarEditingAppearance(bool editing)
|
||||
{
|
||||
//camera presets (rear, front, etc.)
|
||||
getChildView("preset_views_list")->setEnabled(!editing);
|
||||
getChildView("presets_btn")->setEnabled(!editing);
|
||||
|
||||
//camera modes (object view, mouselook view)
|
||||
getChildView("camera_modes_list")->setEnabled(!editing);
|
||||
getChildView("avatarview_btn")->setEnabled(!editing);
|
||||
}
|
||||
|
||||
void LLFloaterCamera::update()
|
||||
|
|
@ -322,6 +318,8 @@ void LLFloaterCamera::onOpen(const LLSD& key)
|
|||
else
|
||||
toPrevMode();
|
||||
mClosed = FALSE;
|
||||
|
||||
populatePresetCombo();
|
||||
}
|
||||
|
||||
void LLFloaterCamera::onClose(bool app_quitting)
|
||||
|
|
@ -353,6 +351,8 @@ LLFloaterCamera::LLFloaterCamera(const LLSD& val)
|
|||
{
|
||||
LLHints::getInstance()->registerHintTarget("view_popup", getHandle());
|
||||
mCommitCallbackRegistrar.add("CameraPresets.ChangeView", boost::bind(&LLFloaterCamera::onClickCameraItem, _2));
|
||||
mCommitCallbackRegistrar.add("CameraPresets.Save", boost::bind(&LLFloaterCamera::onSavePreset, this));
|
||||
mCommitCallbackRegistrar.add("CameraPresets.ShowPresetsList", boost::bind(&LLFloaterReg::showInstance, "camera_presets", LLSD(), FALSE));
|
||||
}
|
||||
|
||||
// virtual
|
||||
|
|
@ -363,10 +363,14 @@ BOOL LLFloaterCamera::postBuild()
|
|||
mRotate = getChild<LLJoystickCameraRotate>(ORBIT);
|
||||
mZoom = findChild<LLPanelCameraZoom>(ZOOM);
|
||||
mTrack = getChild<LLJoystickCameraTrack>(PAN);
|
||||
mPresetCombo = getChild<LLComboBox>("preset_combo");
|
||||
|
||||
assignButton2Mode(CAMERA_CTRL_MODE_MODES, "avatarview_btn");
|
||||
assignButton2Mode(CAMERA_CTRL_MODE_PAN, "pan_btn");
|
||||
assignButton2Mode(CAMERA_CTRL_MODE_PRESETS, "presets_btn");
|
||||
getChild<LLTextBox>("precise_ctrs_label")->setShowCursorHand(false);
|
||||
getChild<LLTextBox>("precise_ctrs_label")->setSoundFlags(LLView::MOUSE_UP);
|
||||
getChild<LLTextBox>("precise_ctrs_label")->setClickedCallback(boost::bind(&LLFloaterReg::showInstance, "prefs_view_advanced", LLSD(), FALSE));
|
||||
|
||||
mPresetCombo->setCommitCallback(boost::bind(&LLFloaterCamera::onCustomPresetSelected, this));
|
||||
LLPresetsManager::getInstance()->setPresetListChangeCameraCallback(boost::bind(&LLFloaterCamera::populatePresetCombo, this));
|
||||
|
||||
update();
|
||||
|
||||
|
|
@ -376,6 +380,15 @@ BOOL LLFloaterCamera::postBuild()
|
|||
return LLFloater::postBuild();
|
||||
}
|
||||
|
||||
F32 LLFloaterCamera::getCurrentTransparency()
|
||||
{
|
||||
|
||||
static LLCachedControl<F32> camera_opacity(gSavedSettings, "CameraOpacity");
|
||||
static LLCachedControl<F32> active_floater_transparency(gSavedSettings, "ActiveFloaterTransparency");
|
||||
return llmin(camera_opacity(), active_floater_transparency());
|
||||
|
||||
}
|
||||
|
||||
void LLFloaterCamera::fillFlatlistFromPanel (LLFlatListView* list, LLPanel* panel)
|
||||
{
|
||||
// copying child list and then iterating over a copy, because list itself
|
||||
|
|
@ -444,13 +457,6 @@ void LLFloaterCamera::switchMode(ECameraControlMode mode)
|
|||
|
||||
switch (mode)
|
||||
{
|
||||
case CAMERA_CTRL_MODE_MODES:
|
||||
if(sFreeCamera)
|
||||
{
|
||||
switchMode(CAMERA_CTRL_MODE_FREE_CAMERA);
|
||||
}
|
||||
break;
|
||||
|
||||
case CAMERA_CTRL_MODE_PAN:
|
||||
sFreeCamera = false;
|
||||
clear_camera_tool();
|
||||
|
|
@ -474,36 +480,8 @@ void LLFloaterCamera::switchMode(ECameraControlMode mode)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void LLFloaterCamera::onClickBtn(ECameraControlMode mode)
|
||||
{
|
||||
// check for a click on active button
|
||||
if (mCurrMode == mode) mMode2Button[mode]->setToggleState(TRUE);
|
||||
|
||||
switchMode(mode);
|
||||
|
||||
}
|
||||
|
||||
void LLFloaterCamera::assignButton2Mode(ECameraControlMode mode, const std::string& button_name)
|
||||
{
|
||||
LLButton* button = getChild<LLButton>(button_name);
|
||||
|
||||
button->setClickedCallback(boost::bind(&LLFloaterCamera::onClickBtn, this, mode));
|
||||
mMode2Button[mode] = button;
|
||||
}
|
||||
|
||||
void LLFloaterCamera::updateState()
|
||||
{
|
||||
getChildView(ZOOM)->setVisible(CAMERA_CTRL_MODE_PAN == mCurrMode);
|
||||
|
||||
bool show_presets = (CAMERA_CTRL_MODE_PRESETS == mCurrMode) || (CAMERA_CTRL_MODE_FREE_CAMERA == mCurrMode
|
||||
&& CAMERA_CTRL_MODE_PRESETS == mPrevMode);
|
||||
getChildView(PRESETS)->setVisible(show_presets);
|
||||
|
||||
bool show_camera_modes = CAMERA_CTRL_MODE_MODES == mCurrMode || (CAMERA_CTRL_MODE_FREE_CAMERA == mCurrMode
|
||||
&& CAMERA_CTRL_MODE_MODES == mPrevMode);
|
||||
getChildView("camera_modes_list")->setVisible( show_camera_modes);
|
||||
|
||||
updateItemsSelection();
|
||||
|
||||
if (CAMERA_CTRL_MODE_FREE_CAMERA == mCurrMode)
|
||||
|
|
@ -521,13 +499,13 @@ void LLFloaterCamera::updateState()
|
|||
|
||||
void LLFloaterCamera::updateItemsSelection()
|
||||
{
|
||||
ECameraPreset preset = (ECameraPreset) gSavedSettings.getU32("CameraPreset");
|
||||
ECameraPreset preset = (ECameraPreset) gSavedSettings.getU32("CameraPresetType");
|
||||
LLSD argument;
|
||||
argument["selected"] = preset == CAMERA_PRESET_REAR_VIEW;
|
||||
argument["selected"] = (preset == CAMERA_PRESET_REAR_VIEW) && !sFreeCamera;
|
||||
getChild<LLPanelCameraItem>("rear_view")->setValue(argument);
|
||||
argument["selected"] = preset == CAMERA_PRESET_GROUP_VIEW;
|
||||
argument["selected"] = (preset == CAMERA_PRESET_GROUP_VIEW) && !sFreeCamera;
|
||||
getChild<LLPanelCameraItem>("group_view")->setValue(argument);
|
||||
argument["selected"] = preset == CAMERA_PRESET_FRONT_VIEW;
|
||||
argument["selected"] = (preset == CAMERA_PRESET_FRONT_VIEW) && !sFreeCamera;
|
||||
getChild<LLPanelCameraItem>("front_view")->setValue(argument);
|
||||
argument["selected"] = gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK;
|
||||
getChild<LLPanelCameraItem>("mouselook_view")->setValue(argument);
|
||||
|
|
@ -547,19 +525,19 @@ void LLFloaterCamera::onClickCameraItem(const LLSD& param)
|
|||
{
|
||||
LLFloaterCamera* camera_floater = LLFloaterCamera::findInstance();
|
||||
if (camera_floater)
|
||||
camera_floater->switchMode(CAMERA_CTRL_MODE_FREE_CAMERA);
|
||||
{
|
||||
camera_floater->switchMode(CAMERA_CTRL_MODE_FREE_CAMERA);
|
||||
camera_floater->updateItemsSelection();
|
||||
camera_floater->fromFreeToPresets();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LLFloaterCamera* camera_floater = LLFloaterCamera::findInstance();
|
||||
if (camera_floater)
|
||||
camera_floater->switchMode(CAMERA_CTRL_MODE_PAN);
|
||||
switchToPreset(name);
|
||||
}
|
||||
|
||||
LLFloaterCamera* camera_floater = LLFloaterCamera::findInstance();
|
||||
if (camera_floater)
|
||||
{
|
||||
camera_floater->updateItemsSelection();
|
||||
camera_floater->fromFreeToPresets();
|
||||
}
|
||||
}
|
||||
|
||||
/*static*/
|
||||
|
|
@ -567,18 +545,49 @@ void LLFloaterCamera::switchToPreset(const std::string& name)
|
|||
{
|
||||
sFreeCamera = false;
|
||||
clear_camera_tool();
|
||||
if ("rear_view" == name)
|
||||
if (PRESETS_REAR_VIEW == name)
|
||||
{
|
||||
gAgentCamera.switchCameraPreset(CAMERA_PRESET_REAR_VIEW);
|
||||
}
|
||||
else if ("group_view" == name)
|
||||
else if (PRESETS_SIDE_VIEW == name)
|
||||
{
|
||||
gAgentCamera.switchCameraPreset(CAMERA_PRESET_GROUP_VIEW);
|
||||
}
|
||||
else if ("front_view" == name)
|
||||
else if (PRESETS_FRONT_VIEW == name)
|
||||
{
|
||||
gAgentCamera.switchCameraPreset(CAMERA_PRESET_FRONT_VIEW);
|
||||
}
|
||||
else
|
||||
{
|
||||
gAgentCamera.switchCameraPreset(CAMERA_PRESET_CUSTOM);
|
||||
}
|
||||
|
||||
if (gSavedSettings.getString("PresetCameraActive") != name)
|
||||
{
|
||||
LLPresetsManager::getInstance()->loadPreset(PRESETS_CAMERA, name);
|
||||
}
|
||||
|
||||
if (isAgentAvatarValid() && gAgentAvatarp->getParent())
|
||||
{
|
||||
LLQuaternion sit_rot(gSavedSettings.getLLSD("AvatarSitRotation"));
|
||||
if (sit_rot != LLQuaternion())
|
||||
{
|
||||
gAgent.rotate(~gAgent.getFrameAgent().getQuaternion());
|
||||
gAgent.rotate(sit_rot);
|
||||
}
|
||||
else
|
||||
{
|
||||
gAgentCamera.rotateToInitSitRot();
|
||||
}
|
||||
}
|
||||
gAgentCamera.resetCameraZoomFraction();
|
||||
|
||||
LLFloaterCamera* camera_floater = LLFloaterCamera::findInstance();
|
||||
if (camera_floater)
|
||||
{
|
||||
camera_floater->updateItemsSelection();
|
||||
camera_floater->fromFreeToPresets();
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterCamera::fromFreeToPresets()
|
||||
|
|
@ -588,3 +597,41 @@ void LLFloaterCamera::fromFreeToPresets()
|
|||
switchMode(CAMERA_CTRL_MODE_PRESETS);
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterCamera::populatePresetCombo()
|
||||
{
|
||||
LLPresetsManager::getInstance()->setPresetNamesInComboBox(PRESETS_CAMERA, mPresetCombo, EDefaultOptions::DEFAULT_HIDE);
|
||||
std::string active_preset_name = gSavedSettings.getString("PresetCameraActive");
|
||||
if (active_preset_name.empty())
|
||||
{
|
||||
gSavedSettings.setU32("CameraPresetType", CAMERA_PRESET_CUSTOM);
|
||||
updateItemsSelection();
|
||||
mPresetCombo->setLabel(getString("inactive_combo_text"));
|
||||
}
|
||||
else if ((ECameraPreset)gSavedSettings.getU32("CameraPresetType") == CAMERA_PRESET_CUSTOM)
|
||||
{
|
||||
mPresetCombo->selectByValue(active_preset_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
mPresetCombo->setLabel(getString("inactive_combo_text"));
|
||||
}
|
||||
updateItemsSelection();
|
||||
}
|
||||
|
||||
void LLFloaterCamera::onSavePreset()
|
||||
{
|
||||
LLFloaterReg::hideInstance("delete_pref_preset", PRESETS_CAMERA);
|
||||
LLFloaterReg::hideInstance("load_pref_preset", PRESETS_CAMERA);
|
||||
|
||||
LLFloaterReg::showInstance("save_camera_preset");
|
||||
}
|
||||
|
||||
void LLFloaterCamera::onCustomPresetSelected()
|
||||
{
|
||||
std::string selected_preset = mPresetCombo->getSelectedItemLabel();
|
||||
if (getString("inactive_combo_text") != selected_preset)
|
||||
{
|
||||
switchToPreset(selected_preset);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,10 +36,10 @@ class LLJoystickCameraRotate;
|
|||
class LLJoystickCameraTrack;
|
||||
class LLFloaterReg;
|
||||
class LLPanelCameraZoom;
|
||||
class LLComboBox;
|
||||
|
||||
enum ECameraControlMode
|
||||
{
|
||||
CAMERA_CTRL_MODE_MODES,
|
||||
CAMERA_CTRL_MODE_PAN,
|
||||
CAMERA_CTRL_MODE_FREE_CAMERA,
|
||||
CAMERA_CTRL_MODE_PRESETS
|
||||
|
|
@ -50,7 +50,6 @@ class LLFloaterCamera : public LLFloater
|
|||
friend class LLFloaterReg;
|
||||
|
||||
public:
|
||||
|
||||
/* whether in free camera mode */
|
||||
static bool inFreeCameraMode();
|
||||
/* callback for camera items selection changing */
|
||||
|
|
@ -77,6 +76,11 @@ public:
|
|||
virtual void onOpen(const LLSD& key);
|
||||
virtual void onClose(bool app_quitting);
|
||||
|
||||
void onSavePreset();
|
||||
void onCustomPresetSelected();
|
||||
|
||||
void populatePresetCombo();
|
||||
|
||||
LLJoystickCameraRotate* mRotate;
|
||||
LLPanelCameraZoom* mZoom;
|
||||
LLJoystickCameraTrack* mTrack;
|
||||
|
|
@ -91,6 +95,10 @@ private:
|
|||
|
||||
/*virtual*/ BOOL postBuild();
|
||||
|
||||
F32 getCurrentTransparency();
|
||||
|
||||
void onViewButtonClick(const LLSD& user_data);
|
||||
|
||||
ECameraControlMode determineMode();
|
||||
|
||||
/* resets to the previous mode */
|
||||
|
|
@ -108,9 +116,6 @@ private:
|
|||
/* update camera modes items selection and camera preset items selection according to the currently selected preset */
|
||||
void updateItemsSelection();
|
||||
|
||||
void onClickBtn(ECameraControlMode mode);
|
||||
void assignButton2Mode(ECameraControlMode mode, const std::string& button_name);
|
||||
|
||||
// fills flatlist with items from given panel
|
||||
void fillFlatlistFromPanel (LLFlatListView* list, LLPanel* panel);
|
||||
|
||||
|
|
@ -124,6 +129,8 @@ private:
|
|||
ECameraControlMode mPrevMode;
|
||||
ECameraControlMode mCurrMode;
|
||||
std::map<ECameraControlMode, LLButton*> mMode2Button;
|
||||
|
||||
LLComboBox* mPresetCombo;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -0,0 +1,145 @@
|
|||
/**
|
||||
* @file llfloatercamerapresets.cpp
|
||||
*
|
||||
* $LicenseInfo:firstyear=2019&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2019, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llfloatercamerapresets.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llpresetsmanager.h"
|
||||
#include "llviewercontrol.h"
|
||||
|
||||
LLFloaterCameraPresets::LLFloaterCameraPresets(const LLSD& key)
|
||||
: LLFloater(key)
|
||||
{}
|
||||
|
||||
LLFloaterCameraPresets::~LLFloaterCameraPresets()
|
||||
{}
|
||||
|
||||
BOOL LLFloaterCameraPresets::postBuild()
|
||||
{
|
||||
mPresetList = getChild<LLFlatListView>("preset_list");
|
||||
|
||||
LLPresetsManager::getInstance()->setPresetListChangeCameraCallback(boost::bind(&LLFloaterCameraPresets::populateList, this));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
void LLFloaterCameraPresets::onOpen(const LLSD& key)
|
||||
{
|
||||
populateList();
|
||||
}
|
||||
|
||||
void LLFloaterCameraPresets::populateList()
|
||||
{
|
||||
mPresetList->clear();
|
||||
|
||||
LLPresetsManager* presetsMgr = LLPresetsManager::getInstance();
|
||||
std::list<std::string> preset_names;
|
||||
|
||||
presetsMgr->loadPresetNamesFromDir(PRESETS_CAMERA, preset_names, DEFAULT_BOTTOM);
|
||||
|
||||
for (std::list<std::string>::const_iterator it = preset_names.begin(); it != preset_names.end(); ++it)
|
||||
{
|
||||
const std::string& name = *it;
|
||||
bool is_default = presetsMgr->isDefaultCameraPreset(name);
|
||||
LLCameraPresetFlatItem* item = new LLCameraPresetFlatItem(name, is_default);
|
||||
item->postBuild();
|
||||
mPresetList->addItem(item);
|
||||
}
|
||||
}
|
||||
|
||||
LLCameraPresetFlatItem::LLCameraPresetFlatItem(const std::string &preset_name, bool is_default)
|
||||
: LLPanel(),
|
||||
mPresetName(preset_name),
|
||||
mIsDefaultPrest(is_default)
|
||||
{
|
||||
mCommitCallbackRegistrar.add("CameraPresets.Delete", boost::bind(&LLCameraPresetFlatItem::onDeleteBtnClick, this));
|
||||
mCommitCallbackRegistrar.add("CameraPresets.Reset", boost::bind(&LLCameraPresetFlatItem::onResetBtnClick, this));
|
||||
buildFromFile("panel_camera_preset_item.xml");
|
||||
}
|
||||
|
||||
LLCameraPresetFlatItem::~LLCameraPresetFlatItem()
|
||||
{
|
||||
}
|
||||
|
||||
BOOL LLCameraPresetFlatItem::postBuild()
|
||||
{
|
||||
mDeleteBtn = getChild<LLButton>("delete_btn");
|
||||
mDeleteBtn->setVisible(false);
|
||||
|
||||
mResetBtn = getChild<LLButton>("reset_btn");
|
||||
mResetBtn->setVisible(false);
|
||||
|
||||
LLStyle::Params style;
|
||||
LLTextBox* name_text = getChild<LLTextBox>("preset_name");
|
||||
LLFontDescriptor new_desc(name_text->getFont()->getFontDesc());
|
||||
new_desc.setStyle(mIsDefaultPrest ? LLFontGL::ITALIC : LLFontGL::NORMAL);
|
||||
LLFontGL* new_font = LLFontGL::getFont(new_desc);
|
||||
style.font = new_font;
|
||||
name_text->setText(mPresetName, style);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void LLCameraPresetFlatItem::onMouseEnter(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
mDeleteBtn->setVisible(!mIsDefaultPrest);
|
||||
mResetBtn->setVisible(mIsDefaultPrest);
|
||||
getChildView("hovered_icon")->setVisible(true);
|
||||
LLPanel::onMouseEnter(x, y, mask);
|
||||
}
|
||||
|
||||
void LLCameraPresetFlatItem::onMouseLeave(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
mDeleteBtn->setVisible(false);
|
||||
mResetBtn->setVisible(false);
|
||||
getChildView("hovered_icon")->setVisible(false);
|
||||
LLPanel::onMouseLeave(x, y, mask);
|
||||
}
|
||||
|
||||
void LLCameraPresetFlatItem::setValue(const LLSD& value)
|
||||
{
|
||||
if (!value.isMap()) return;;
|
||||
if (!value.has("selected")) return;
|
||||
getChildView("selected_icon")->setVisible(value["selected"]);
|
||||
}
|
||||
|
||||
void LLCameraPresetFlatItem::onDeleteBtnClick()
|
||||
{
|
||||
if (!LLPresetsManager::getInstance()->deletePreset(PRESETS_CAMERA, mPresetName))
|
||||
{
|
||||
LLSD args;
|
||||
args["NAME"] = mPresetName;
|
||||
LLNotificationsUtil::add("PresetNotDeleted", args);
|
||||
}
|
||||
else if (gSavedSettings.getString("PresetCameraActive") == mPresetName)
|
||||
{
|
||||
gSavedSettings.setString("PresetCameraActive", "");
|
||||
}
|
||||
}
|
||||
|
||||
void LLCameraPresetFlatItem::onResetBtnClick()
|
||||
{
|
||||
LLPresetsManager::getInstance()->resetCameraPreset(mPresetName);
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
/**
|
||||
* @file llfloatercamerapresets.h
|
||||
*
|
||||
* $LicenseInfo:firstyear=2019&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2019, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
#ifndef LLFLOATERCAMERAPRESETS_H
|
||||
#define LLFLOATERCAMERAPRESETS_H
|
||||
|
||||
#include "llfloater.h"
|
||||
#include "llflatlistview.h"
|
||||
|
||||
class LLFloaterReg;
|
||||
|
||||
class LLFloaterCameraPresets : public LLFloater
|
||||
{
|
||||
friend class LLFloaterReg;
|
||||
|
||||
virtual BOOL postBuild();
|
||||
virtual void onOpen(const LLSD& key);
|
||||
|
||||
void populateList();
|
||||
|
||||
private:
|
||||
LLFloaterCameraPresets(const LLSD& key);
|
||||
~LLFloaterCameraPresets();
|
||||
|
||||
LLFlatListView* mPresetList;
|
||||
};
|
||||
|
||||
class LLCameraPresetFlatItem : public LLPanel
|
||||
{
|
||||
public:
|
||||
LLCameraPresetFlatItem(const std::string &preset_name, bool is_default);
|
||||
virtual ~LLCameraPresetFlatItem();
|
||||
|
||||
void setValue(const LLSD& value);
|
||||
|
||||
virtual BOOL postBuild();
|
||||
virtual void onMouseEnter(S32 x, S32 y, MASK mask);
|
||||
virtual void onMouseLeave(S32 x, S32 y, MASK mask);
|
||||
|
||||
private:
|
||||
void onDeleteBtnClick();
|
||||
void onResetBtnClick();
|
||||
|
||||
LLButton* mDeleteBtn;
|
||||
LLButton* mResetBtn;
|
||||
|
||||
std::string mPresetName;
|
||||
bool mIsDefaultPrest;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -60,13 +60,15 @@ void LLFloaterDeletePrefPreset::onOpen(const LLSD& key)
|
|||
{
|
||||
mSubdirectory = key.asString();
|
||||
std::string floater_title = getString(std::string("title_") + mSubdirectory);
|
||||
|
||||
setTitle(floater_title);
|
||||
|
||||
LLComboBox* combo = getChild<LLComboBox>("preset_combo");
|
||||
|
||||
EDefaultOptions option = DEFAULT_HIDE;
|
||||
LLPresetsManager::getInstance()->setPresetNamesInComboBox(mSubdirectory, combo, option);
|
||||
bool action;
|
||||
action = LLPresetsManager::getInstance()->setPresetNamesInComboBox(mSubdirectory, combo, option);
|
||||
|
||||
LLButton* delete_btn = getChild<LLButton>("delete");
|
||||
delete_btn->setEnabled(action);
|
||||
}
|
||||
|
||||
void LLFloaterDeletePrefPreset::onBtnDelete()
|
||||
|
|
@ -80,6 +82,13 @@ void LLFloaterDeletePrefPreset::onBtnDelete()
|
|||
args["NAME"] = name;
|
||||
LLNotificationsUtil::add("PresetNotDeleted", args);
|
||||
}
|
||||
else if (mSubdirectory == PRESETS_CAMERA)
|
||||
{
|
||||
if (gSavedSettings.getString("PresetCameraActive") == name)
|
||||
{
|
||||
gSavedSettings.setString("PresetCameraActive", "");
|
||||
}
|
||||
}
|
||||
|
||||
closeFloater();
|
||||
}
|
||||
|
|
@ -87,12 +96,10 @@ void LLFloaterDeletePrefPreset::onBtnDelete()
|
|||
void LLFloaterDeletePrefPreset::onPresetsListChange()
|
||||
{
|
||||
LLComboBox* combo = getChild<LLComboBox>("preset_combo");
|
||||
LLButton* delete_btn = getChild<LLButton>("delete");
|
||||
|
||||
EDefaultOptions option = DEFAULT_HIDE;
|
||||
LLPresetsManager::getInstance()->setPresetNamesInComboBox(mSubdirectory, combo, option);
|
||||
|
||||
delete_btn->setEnabled(0 != combo->getItemCount());
|
||||
LLPresetsManager::getInstance()->setPresetNamesInComboBox(mSubdirectory, combo, option);
|
||||
}
|
||||
|
||||
void LLFloaterDeletePrefPreset::onBtnCancel()
|
||||
|
|
|
|||
|
|
@ -42,7 +42,8 @@ LLFloaterLoadPrefPreset::LLFloaterLoadPrefPreset(const LLSD &key)
|
|||
|
||||
// virtual
|
||||
BOOL LLFloaterLoadPrefPreset::postBuild()
|
||||
{ LLFloaterPreference* preferences = LLFloaterReg::getTypedInstance<LLFloaterPreference>("preferences");
|
||||
{
|
||||
LLFloaterPreference* preferences = LLFloaterReg::getTypedInstance<LLFloaterPreference>("preferences");
|
||||
if (preferences)
|
||||
{
|
||||
preferences->addDependentFloater(this);
|
||||
|
|
|
|||
|
|
@ -729,7 +729,7 @@ void LLFloaterPreference::cancel()
|
|||
// hide spellchecker settings folder
|
||||
LLFloaterReg::hideInstance("prefs_spellchecker");
|
||||
|
||||
// hide advancede floater
|
||||
// hide advanced graphics floater
|
||||
LLFloaterReg::hideInstance("prefs_graphics_advanced");
|
||||
|
||||
// reverts any changes to current skin
|
||||
|
|
@ -848,7 +848,8 @@ void LLFloaterPreference::onOpen(const LLSD& key)
|
|||
saveSettings();
|
||||
|
||||
// Make sure there is a default preference file
|
||||
LLPresetsManager::getInstance()->createMissingDefault();
|
||||
LLPresetsManager::getInstance()->createMissingDefault(PRESETS_CAMERA);
|
||||
LLPresetsManager::getInstance()->createMissingDefault(PRESETS_GRAPHIC);
|
||||
|
||||
bool started = (LLStartUp::getStartupState() == STATE_STARTED);
|
||||
|
||||
|
|
@ -857,12 +858,15 @@ void LLFloaterPreference::onOpen(const LLSD& key)
|
|||
LLButton* delete_btn = findChild<LLButton>("PrefDeleteButton");
|
||||
LLButton* exceptions_btn = findChild<LLButton>("RenderExceptionsButton");
|
||||
|
||||
load_btn->setEnabled(started);
|
||||
save_btn->setEnabled(started);
|
||||
delete_btn->setEnabled(started);
|
||||
exceptions_btn->setEnabled(started);
|
||||
if (load_btn && save_btn && delete_btn && exceptions_btn)
|
||||
{
|
||||
load_btn->setEnabled(started);
|
||||
save_btn->setEnabled(started);
|
||||
delete_btn->setEnabled(started);
|
||||
exceptions_btn->setEnabled(started);
|
||||
}
|
||||
|
||||
collectSearchableItems();
|
||||
collectSearchableItems();
|
||||
if (!mFilterEdit->getText().empty())
|
||||
{
|
||||
mFilterEdit->setText(LLStringExplicit(""));
|
||||
|
|
@ -2650,20 +2654,17 @@ void LLPanelPreference::updateMediaAutoPlayCheckbox(LLUICtrl* ctrl)
|
|||
|
||||
void LLPanelPreference::deletePreset(const LLSD& user_data)
|
||||
{
|
||||
std::string subdirectory = user_data.asString();
|
||||
LLFloaterReg::showInstance("delete_pref_preset", subdirectory);
|
||||
LLFloaterReg::showInstance("delete_pref_preset", user_data.asString());
|
||||
}
|
||||
|
||||
void LLPanelPreference::savePreset(const LLSD& user_data)
|
||||
{
|
||||
std::string subdirectory = user_data.asString();
|
||||
LLFloaterReg::showInstance("save_pref_preset", subdirectory);
|
||||
LLFloaterReg::showInstance("save_pref_preset", user_data.asString());
|
||||
}
|
||||
|
||||
void LLPanelPreference::loadPreset(const LLSD& user_data)
|
||||
{
|
||||
std::string subdirectory = user_data.asString();
|
||||
LLFloaterReg::showInstance("load_pref_preset", subdirectory);
|
||||
LLFloaterReg::showInstance("load_pref_preset", user_data.asString());
|
||||
}
|
||||
|
||||
void LLPanelPreference::setHardwareDefaults()
|
||||
|
|
@ -2721,7 +2722,7 @@ BOOL LLPanelPreferenceGraphics::postBuild()
|
|||
|
||||
LLPresetsManager* presetsMgr = LLPresetsManager::getInstance();
|
||||
presetsMgr->setPresetListChangeCallback(boost::bind(&LLPanelPreferenceGraphics::onPresetsListChange, this));
|
||||
presetsMgr->createMissingDefault(); // a no-op after the first time, but that's ok
|
||||
presetsMgr->createMissingDefault(PRESETS_GRAPHIC); // a no-op after the first time, but that's ok
|
||||
|
||||
return LLPanelPreference::postBuild();
|
||||
}
|
||||
|
|
@ -2742,11 +2743,6 @@ void LLPanelPreferenceGraphics::onPresetsListChange()
|
|||
{
|
||||
instance->saveSettings(); //make cancel work correctly after changing the preset
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string dummy;
|
||||
instance->saveGraphicsPreset(dummy);
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelPreferenceGraphics::setPresetText()
|
||||
|
|
|
|||
|
|
@ -191,6 +191,7 @@ public:
|
|||
void buildPopupLists();
|
||||
static void refreshSkin(void* data);
|
||||
void selectPanel(const LLSD& name);
|
||||
void saveCameraPreset(std::string& preset);
|
||||
void saveGraphicsPreset(std::string& preset);
|
||||
|
||||
private:
|
||||
|
|
@ -214,6 +215,7 @@ private:
|
|||
std::string mDirectoryVisibility;
|
||||
|
||||
LLAvatarData mAvatarProperties;
|
||||
std::string mSavedCameraPreset;
|
||||
std::string mSavedGraphicsPreset;
|
||||
LOG_CLASS(LLFloaterPreference);
|
||||
|
||||
|
|
@ -288,7 +290,6 @@ protected:
|
|||
bool hasDirtyChilds();
|
||||
|
||||
private:
|
||||
|
||||
void onPresetsListChange();
|
||||
LOG_CLASS(LLPanelPreferenceGraphics);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,82 @@
|
|||
/**
|
||||
* @file llfloaterpreferenceviewadvanced.cpp
|
||||
* @brief floater for adjusting camera position
|
||||
*
|
||||
* $LicenseInfo:firstyear=2018&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2018, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
#include "llagentcamera.h"
|
||||
#include "llfloaterpreferenceviewadvanced.h"
|
||||
#include "llfloater.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#include "llspinctrl.h"
|
||||
#include "llviewercontrol.h"
|
||||
|
||||
|
||||
LLFloaterPreferenceViewAdvanced::LLFloaterPreferenceViewAdvanced(const LLSD& key)
|
||||
: LLFloater(key)
|
||||
{
|
||||
mCommitCallbackRegistrar.add("CommitSettings", boost::bind(&LLFloaterPreferenceViewAdvanced::onCommitSettings, this));
|
||||
}
|
||||
|
||||
LLFloaterPreferenceViewAdvanced::~LLFloaterPreferenceViewAdvanced()
|
||||
{}
|
||||
|
||||
void LLFloaterPreferenceViewAdvanced::updateCameraControl(const LLVector3& vector)
|
||||
{
|
||||
getChild<LLSpinCtrl>("camera_x")->setValue(vector[VX]);
|
||||
getChild<LLSpinCtrl>("camera_y")->setValue(vector[VY]);
|
||||
getChild<LLSpinCtrl>("camera_z")->setValue(vector[VZ]);
|
||||
}
|
||||
|
||||
void LLFloaterPreferenceViewAdvanced::updateFocusControl(const LLVector3d& vector3d)
|
||||
{
|
||||
getChild<LLSpinCtrl>("focus_x")->setValue(vector3d[VX]);
|
||||
getChild<LLSpinCtrl>("focus_y")->setValue(vector3d[VY]);
|
||||
getChild<LLSpinCtrl>("focus_z")->setValue(vector3d[VZ]);
|
||||
}
|
||||
|
||||
void LLFloaterPreferenceViewAdvanced::draw()
|
||||
{
|
||||
updateCameraControl(gAgentCamera.getCameraOffsetInitial());
|
||||
updateFocusControl(gAgentCamera.getFocusOffsetInitial());
|
||||
|
||||
LLFloater::draw();
|
||||
}
|
||||
|
||||
void LLFloaterPreferenceViewAdvanced::onCommitSettings()
|
||||
{
|
||||
LLVector3 vector;
|
||||
LLVector3d vector3d;
|
||||
|
||||
vector.mV[VX] = (F32)getChild<LLUICtrl>("camera_x")->getValue().asReal();
|
||||
vector.mV[VY] = (F32)getChild<LLUICtrl>("camera_y")->getValue().asReal();
|
||||
vector.mV[VZ] = (F32)getChild<LLUICtrl>("camera_z")->getValue().asReal();
|
||||
gSavedSettings.setVector3("CameraOffsetRearView", vector);
|
||||
|
||||
vector3d.mdV[VX] = (F32)getChild<LLUICtrl>("focus_x")->getValue().asReal();
|
||||
vector3d.mdV[VY] = (F32)getChild<LLUICtrl>("focus_y")->getValue().asReal();
|
||||
vector3d.mdV[VZ] = (F32)getChild<LLUICtrl>("focus_z")->getValue().asReal();
|
||||
gSavedSettings.setVector3d("FocusOffsetRearView", vector3d);
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
/**
|
||||
* @file llfloaterpreferenceviewadvanced.h
|
||||
* @brief floater for adjusting camera position
|
||||
*
|
||||
* $LicenseInfo:firstyear=2018&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2018, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LLFLOATERPREFERENCEVIEWADVANCED_H
|
||||
#define LLFLOATERPREFERENCEVIEWADVANCED_H
|
||||
|
||||
#include "llcontrol.h"
|
||||
#include "llfloater.h"
|
||||
|
||||
class LLFloaterPreferenceViewAdvanced
|
||||
: public LLFloater
|
||||
{
|
||||
friend class LLFloaterReg;
|
||||
|
||||
public:
|
||||
LLFloaterPreferenceViewAdvanced(const LLSD& key);
|
||||
virtual void draw();
|
||||
|
||||
void onCommitSettings();
|
||||
void updateCameraControl(const LLVector3& vector);
|
||||
void updateFocusControl(const LLVector3d& vector3d);
|
||||
|
||||
private:
|
||||
virtual ~LLFloaterPreferenceViewAdvanced();
|
||||
};
|
||||
|
||||
#endif //LLFLOATERPREFERENCEVIEWADVANCED_H
|
||||
|
||||
|
|
@ -0,0 +1,172 @@
|
|||
/**
|
||||
* @file llfloatersavecamerapreset.cpp
|
||||
* @brief Floater to save a camera preset
|
||||
*
|
||||
* $LicenseInfo:firstyear=2020&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2020, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llfloatersavecamerapreset.h"
|
||||
|
||||
#include "llagent.h"
|
||||
#include "llagentcamera.h"
|
||||
#include "llbutton.h"
|
||||
#include "llcombobox.h"
|
||||
#include "llfloaterpreference.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "lllineeditor.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llpresetsmanager.h"
|
||||
#include "llradiogroup.h"
|
||||
#include "lltrans.h"
|
||||
#include "llvoavatarself.h"
|
||||
|
||||
LLFloaterSaveCameraPreset::LLFloaterSaveCameraPreset(const LLSD &key)
|
||||
: LLModalDialog(key)
|
||||
{
|
||||
}
|
||||
|
||||
// virtual
|
||||
BOOL LLFloaterSaveCameraPreset::postBuild()
|
||||
{
|
||||
mPresetCombo = getChild<LLComboBox>("preset_combo");
|
||||
|
||||
mNameEditor = getChild<LLLineEditor>("preset_txt_editor");
|
||||
mNameEditor->setKeystrokeCallback(boost::bind(&LLFloaterSaveCameraPreset::onPresetNameEdited, this), NULL);
|
||||
|
||||
mSaveButton = getChild<LLButton>("save");
|
||||
mSaveButton->setCommitCallback(boost::bind(&LLFloaterSaveCameraPreset::onBtnSave, this));
|
||||
|
||||
mSaveRadioGroup = getChild<LLRadioGroup>("radio_save_preset");
|
||||
mSaveRadioGroup->setCommitCallback(boost::bind(&LLFloaterSaveCameraPreset::onSwitchSaveReplace, this));
|
||||
|
||||
getChild<LLButton>("cancel")->setCommitCallback(boost::bind(&LLFloaterSaveCameraPreset::onBtnCancel, this));
|
||||
|
||||
LLPresetsManager::instance().setPresetListChangeCallback(boost::bind(&LLFloaterSaveCameraPreset::onPresetsListChange, this));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLFloaterSaveCameraPreset::onPresetNameEdited()
|
||||
{
|
||||
if (mSaveRadioGroup->getSelectedIndex() == 0)
|
||||
{
|
||||
// Disable saving a preset having empty name.
|
||||
std::string name = mNameEditor->getValue();
|
||||
mSaveButton->setEnabled(!name.empty());
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterSaveCameraPreset::onOpen(const LLSD& key)
|
||||
{
|
||||
LLModalDialog::onOpen(key);
|
||||
S32 index = 0;
|
||||
if (key.has("index"))
|
||||
{
|
||||
index = key["index"].asInteger();
|
||||
}
|
||||
|
||||
LLPresetsManager::getInstance()->setPresetNamesInComboBox(PRESETS_CAMERA, mPresetCombo, DEFAULT_BOTTOM);
|
||||
|
||||
mSaveRadioGroup->setSelectedIndex(index);
|
||||
onPresetNameEdited();
|
||||
onSwitchSaveReplace();
|
||||
}
|
||||
|
||||
void LLFloaterSaveCameraPreset::onBtnSave()
|
||||
{
|
||||
bool is_saving_new = mSaveRadioGroup->getSelectedIndex() == 0;
|
||||
std::string name = is_saving_new ? mNameEditor->getText() : mPresetCombo->getSimple();
|
||||
|
||||
if ((name == LLTrans::getString(PRESETS_DEFAULT)) || (name == PRESETS_DEFAULT))
|
||||
{
|
||||
LLNotificationsUtil::add("DefaultPresetNotSaved");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isAgentAvatarValid() && gAgentAvatarp->getParent())
|
||||
{
|
||||
gSavedSettings.setLLSD("AvatarSitRotation", gAgent.getFrameAgent().getQuaternion().getValue());
|
||||
}
|
||||
if (gAgentCamera.isJoystickCameraUsed())
|
||||
{
|
||||
gSavedSettings.setVector3("CameraOffsetRearView", gAgentCamera.getCurrentCameraOffset());
|
||||
gSavedSettings.setVector3d("FocusOffsetRearView", gAgentCamera.getCurrentFocusOffset());
|
||||
gAgentCamera.resetCameraZoomFraction();
|
||||
gAgentCamera.setFocusOnAvatar(TRUE, TRUE, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLVector3 camera_offset = gSavedSettings.getVector3("CameraOffsetRearView") * gAgentCamera.getCurrentCameraZoomFraction();
|
||||
gSavedSettings.setVector3("CameraOffsetRearView", camera_offset);
|
||||
gAgentCamera.resetCameraZoomFraction();
|
||||
}
|
||||
if (is_saving_new)
|
||||
{
|
||||
std::list<std::string> preset_names;
|
||||
LLPresetsManager::getInstance()->loadPresetNamesFromDir(PRESETS_CAMERA, preset_names, DEFAULT_HIDE);
|
||||
if (std::find(preset_names.begin(), preset_names.end(), name) != preset_names.end())
|
||||
{
|
||||
LLSD args;
|
||||
args["NAME"] = name;
|
||||
LLNotificationsUtil::add("PresetAlreadyExists", args);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!LLPresetsManager::getInstance()->savePreset(PRESETS_CAMERA, name))
|
||||
{
|
||||
LLSD args;
|
||||
args["NAME"] = name;
|
||||
LLNotificationsUtil::add("PresetNotSaved", args);
|
||||
}
|
||||
}
|
||||
|
||||
closeFloater();
|
||||
}
|
||||
|
||||
void LLFloaterSaveCameraPreset::onPresetsListChange()
|
||||
{
|
||||
LLPresetsManager::getInstance()->setPresetNamesInComboBox(PRESETS_CAMERA, mPresetCombo, DEFAULT_BOTTOM);
|
||||
}
|
||||
|
||||
void LLFloaterSaveCameraPreset::onBtnCancel()
|
||||
{
|
||||
closeFloater();
|
||||
}
|
||||
|
||||
void LLFloaterSaveCameraPreset::onSwitchSaveReplace()
|
||||
{
|
||||
bool is_saving_new = mSaveRadioGroup->getSelectedIndex() == 0;
|
||||
std::string label = is_saving_new ? getString("btn_label_save") : getString("btn_label_replace");
|
||||
mSaveButton->setLabel(label);
|
||||
mNameEditor->setEnabled(is_saving_new);
|
||||
mPresetCombo->setEnabled(!is_saving_new);
|
||||
if (is_saving_new)
|
||||
{
|
||||
onPresetNameEdited();
|
||||
}
|
||||
else
|
||||
{
|
||||
mSaveButton->setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
/**
|
||||
* @file llfloatersavecamerapreset.h
|
||||
* @brief Floater to save a camera preset
|
||||
|
||||
*
|
||||
* $LicenseInfo:firstyear=2020&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2020, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLFLOATERSAVECAMERAPRESET_H
|
||||
#define LL_LLFLOATERSAVECAMERAPRESET_H
|
||||
|
||||
#include "llmodaldialog.h"
|
||||
|
||||
class LLComboBox;
|
||||
class LLRadioGroup;
|
||||
class LLLineEditor;
|
||||
|
||||
class LLFloaterSaveCameraPreset : public LLModalDialog
|
||||
{
|
||||
|
||||
public:
|
||||
LLFloaterSaveCameraPreset(const LLSD &key);
|
||||
|
||||
/*virtual*/ BOOL postBuild();
|
||||
/*virtual*/ void onOpen(const LLSD& key);
|
||||
|
||||
void onBtnSave();
|
||||
void onBtnCancel();
|
||||
void onSwitchSaveReplace();
|
||||
|
||||
private:
|
||||
LLRadioGroup* mSaveRadioGroup;
|
||||
LLLineEditor* mNameEditor;
|
||||
LLComboBox* mPresetCombo;
|
||||
LLButton* mSaveButton;
|
||||
|
||||
void onPresetsListChange();
|
||||
void onPresetNameEdited();
|
||||
};
|
||||
|
||||
#endif // LL_LLFLOATERSAVECAMERAPRESET_H
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* @file llfloatersaveprefpreset.cpp
|
||||
* @brief Floater to save a graphics / camera preset
|
||||
* @brief Floater to save a graphics preset
|
||||
*
|
||||
* $LicenseInfo:firstyear=2014&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
|
|
@ -37,24 +37,27 @@
|
|||
#include "lltrans.h"
|
||||
|
||||
LLFloaterSavePrefPreset::LLFloaterSavePrefPreset(const LLSD &key)
|
||||
: LLFloater(key)
|
||||
: LLFloater(key)
|
||||
{
|
||||
}
|
||||
|
||||
// virtual
|
||||
BOOL LLFloaterSavePrefPreset::postBuild()
|
||||
{ LLFloaterPreference* preferences = LLFloaterReg::getTypedInstance<LLFloaterPreference>("preferences");
|
||||
{
|
||||
LLFloaterPreference* preferences = LLFloaterReg::getTypedInstance<LLFloaterPreference>("preferences");
|
||||
if (preferences)
|
||||
{
|
||||
preferences->addDependentFloater(this);
|
||||
}
|
||||
|
||||
getChild<LLComboBox>("preset_combo")->setTextEntryCallback(boost::bind(&LLFloaterSavePrefPreset::onPresetNameEdited, this));
|
||||
getChild<LLComboBox>("preset_combo")->setCommitCallback(boost::bind(&LLFloaterSavePrefPreset::onPresetNameEdited, this));
|
||||
getChild<LLButton>("save")->setCommitCallback(boost::bind(&LLFloaterSavePrefPreset::onBtnSave, this));
|
||||
|
||||
getChild<LLButton>("cancel")->setCommitCallback(boost::bind(&LLFloaterSavePrefPreset::onBtnCancel, this));
|
||||
|
||||
LLPresetsManager::instance().setPresetListChangeCallback(boost::bind(&LLFloaterSavePrefPreset::onPresetsListChange, this));
|
||||
|
||||
|
||||
mSaveButton = getChild<LLButton>("save");
|
||||
mPresetCombo = getChild<LLComboBox>("preset_combo");
|
||||
|
||||
|
|
@ -73,10 +76,6 @@ void LLFloaterSavePrefPreset::onOpen(const LLSD& key)
|
|||
{
|
||||
mSubdirectory = key.asString();
|
||||
|
||||
std::string floater_title = getString(std::string("title_") + mSubdirectory);
|
||||
|
||||
setTitle(floater_title);
|
||||
|
||||
EDefaultOptions option = DEFAULT_HIDE;
|
||||
LLPresetsManager::getInstance()->setPresetNamesInComboBox(mSubdirectory, mPresetCombo, option);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* @file llfloatersaveprefpreset.h
|
||||
* @brief Floater to save a graphics / camera preset
|
||||
* @brief Floater to save a graphics preset
|
||||
|
||||
*
|
||||
* $LicenseInfo:firstyear=2014&license=viewerlgpl$
|
||||
|
|
@ -45,6 +45,7 @@ public:
|
|||
void onBtnCancel();
|
||||
|
||||
private:
|
||||
|
||||
LLComboBox* mPresetCombo;
|
||||
LLButton* mSaveButton;
|
||||
|
||||
|
|
|
|||
|
|
@ -114,6 +114,7 @@ void LLFloaterSettingsDebug::onCommitSettings()
|
|||
|
||||
LLVector3 vector;
|
||||
LLVector3d vectord;
|
||||
LLQuaternion quat;
|
||||
LLRect rect;
|
||||
LLColor4 col4;
|
||||
LLColor3 col3;
|
||||
|
|
@ -149,6 +150,13 @@ void LLFloaterSettingsDebug::onCommitSettings()
|
|||
vectord.mdV[VZ] = getChild<LLUICtrl>("val_spinner_3")->getValue().asReal();
|
||||
controlp->set(vectord.getValue());
|
||||
break;
|
||||
case TYPE_QUAT:
|
||||
quat.mQ[VX] = getChild<LLUICtrl>("val_spinner_1")->getValue().asReal();
|
||||
quat.mQ[VY] = getChild<LLUICtrl>("val_spinner_2")->getValue().asReal();
|
||||
quat.mQ[VZ] = getChild<LLUICtrl>("val_spinner_3")->getValue().asReal();
|
||||
quat.mQ[VS] = getChild<LLUICtrl>("val_spinner_4")->getValue().asReal();;
|
||||
controlp->set(quat.getValue());
|
||||
break;
|
||||
case TYPE_RECT:
|
||||
rect.mLeft = getChild<LLUICtrl>("val_spinner_1")->getValue().asInteger();
|
||||
rect.mRight = getChild<LLUICtrl>("val_spinner_2")->getValue().asInteger();
|
||||
|
|
@ -368,6 +376,40 @@ void LLFloaterSettingsDebug::updateControl(LLControlVariable* controlp)
|
|||
}
|
||||
break;
|
||||
}
|
||||
case TYPE_QUAT:
|
||||
{
|
||||
LLQuaternion q;
|
||||
q.setValue(sd);
|
||||
spinner1->setVisible(TRUE);
|
||||
spinner1->setLabel(std::string("X"));
|
||||
spinner2->setVisible(TRUE);
|
||||
spinner2->setLabel(std::string("Y"));
|
||||
spinner3->setVisible(TRUE);
|
||||
spinner3->setLabel(std::string("Z"));
|
||||
spinner4->setVisible(TRUE);
|
||||
spinner4->setLabel(std::string("S"));
|
||||
if (!spinner1->hasFocus())
|
||||
{
|
||||
spinner1->setPrecision(4);
|
||||
spinner1->setValue(q.mQ[VX]);
|
||||
}
|
||||
if (!spinner2->hasFocus())
|
||||
{
|
||||
spinner2->setPrecision(4);
|
||||
spinner2->setValue(q.mQ[VY]);
|
||||
}
|
||||
if (!spinner3->hasFocus())
|
||||
{
|
||||
spinner3->setPrecision(4);
|
||||
spinner3->setValue(q.mQ[VZ]);
|
||||
}
|
||||
if (!spinner4->hasFocus())
|
||||
{
|
||||
spinner4->setPrecision(4);
|
||||
spinner4->setValue(q.mQ[VS]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TYPE_RECT:
|
||||
{
|
||||
LLRect r;
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
#include "llui.h"
|
||||
#include "llagent.h"
|
||||
#include "llagentcamera.h"
|
||||
#include "llviewercamera.h"
|
||||
#include "llviewertexture.h"
|
||||
#include "llviewertexturelist.h"
|
||||
#include "llviewerwindow.h"
|
||||
|
|
@ -54,6 +55,8 @@ static LLDefaultChildRegistry::Register<LLJoystickQuaternion> r6("joystick_quat"
|
|||
const F32 NUDGE_TIME = 0.25f; // in seconds
|
||||
const F32 ORBIT_NUDGE_RATE = 0.05f; // fraction of normal speed
|
||||
|
||||
const S32 CENTER_DOT_RADIUS = 7;
|
||||
|
||||
//
|
||||
// Public Methods
|
||||
//
|
||||
|
|
@ -138,9 +141,25 @@ bool LLJoystick::pointInCircle(S32 x, S32 y) const
|
|||
//center is x and y coordinates of center of joystick circle, and also its radius
|
||||
int center = this->getLocalRect().getHeight()/2;
|
||||
bool in_circle = (x - center) * (x - center) + (y - center) * (y - center) <= center * center;
|
||||
|
||||
return in_circle;
|
||||
}
|
||||
|
||||
bool LLJoystick::pointInCenterDot(S32 x, S32 y, S32 radius) const
|
||||
{
|
||||
if (this->getLocalRect().getHeight() != this->getLocalRect().getWidth())
|
||||
{
|
||||
LL_WARNS() << "Joystick shape is not square" << LL_ENDL;
|
||||
return true;
|
||||
}
|
||||
|
||||
S32 center = this->getLocalRect().getHeight() / 2;
|
||||
|
||||
bool in_center_circle = (x - center) * (x - center) + (y - center) * (y - center) <= radius * radius;
|
||||
|
||||
return in_center_circle;
|
||||
}
|
||||
|
||||
BOOL LLJoystick::handleMouseDown(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
//LL_INFOS() << "joystick mouse down " << x << ", " << y << LL_ENDL;
|
||||
|
|
@ -403,8 +422,11 @@ LLJoystickCameraRotate::LLJoystickCameraRotate(const LLJoystickCameraRotate::Par
|
|||
mInLeft( FALSE ),
|
||||
mInTop( FALSE ),
|
||||
mInRight( FALSE ),
|
||||
mInBottom( FALSE )
|
||||
{ }
|
||||
mInBottom( FALSE ),
|
||||
mInCenter( FALSE )
|
||||
{
|
||||
mCenterImageName = "Cam_Rotate_Center";
|
||||
}
|
||||
|
||||
|
||||
void LLJoystickCameraRotate::updateSlop()
|
||||
|
|
@ -434,7 +456,16 @@ BOOL LLJoystickCameraRotate::handleMouseDown(S32 x, S32 y, MASK mask)
|
|||
S32 dx = x - horiz_center;
|
||||
S32 dy = y - vert_center;
|
||||
|
||||
if (dy > dx && dy > -dx)
|
||||
if (pointInCenterDot(x, y, CENTER_DOT_RADIUS))
|
||||
{
|
||||
mInitialOffset.mX = 0;
|
||||
mInitialOffset.mY = 0;
|
||||
mInitialQuadrant = JQ_ORIGIN;
|
||||
mInCenter = TRUE;
|
||||
|
||||
resetJoystickCamera();
|
||||
}
|
||||
else if (dy > dx && dy > -dx)
|
||||
{
|
||||
// top
|
||||
mInitialOffset.mX = 0;
|
||||
|
|
@ -469,9 +500,20 @@ BOOL LLJoystickCameraRotate::handleMouseDown(S32 x, S32 y, MASK mask)
|
|||
BOOL LLJoystickCameraRotate::handleMouseUp(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
gAgent.setMovementLocked(FALSE);
|
||||
mInCenter = FALSE;
|
||||
return LLJoystick::handleMouseUp(x, y, mask);
|
||||
}
|
||||
|
||||
BOOL LLJoystickCameraRotate::handleHover(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
if (!pointInCenterDot(x, y, CENTER_DOT_RADIUS))
|
||||
{
|
||||
mInCenter = FALSE;
|
||||
}
|
||||
|
||||
return LLJoystick::handleHover(x, y, mask);
|
||||
}
|
||||
|
||||
void LLJoystickCameraRotate::onHeldDown()
|
||||
{
|
||||
updateSlop();
|
||||
|
|
@ -504,6 +546,11 @@ void LLJoystickCameraRotate::onHeldDown()
|
|||
}
|
||||
}
|
||||
|
||||
void LLJoystickCameraRotate::resetJoystickCamera()
|
||||
{
|
||||
gAgentCamera.resetCameraOrbit();
|
||||
}
|
||||
|
||||
F32 LLJoystickCameraRotate::getOrbitRate()
|
||||
{
|
||||
F32 time = getElapsedHeldDownTime();
|
||||
|
|
@ -536,24 +583,31 @@ void LLJoystickCameraRotate::draw()
|
|||
getImageUnselected()->draw( 0, 0 );
|
||||
LLPointer<LLUIImage> image = getImageSelected();
|
||||
|
||||
if( mInTop )
|
||||
if (mInCenter)
|
||||
{
|
||||
drawRotatedImage( getImageSelected(), 0 );
|
||||
drawRotatedImage(LLUI::getUIImage(mCenterImageName), 0);
|
||||
}
|
||||
|
||||
if( mInRight )
|
||||
else
|
||||
{
|
||||
drawRotatedImage( getImageSelected(), 1 );
|
||||
}
|
||||
if (mInTop)
|
||||
{
|
||||
drawRotatedImage(getImageSelected(), 0);
|
||||
}
|
||||
|
||||
if( mInBottom )
|
||||
{
|
||||
drawRotatedImage( getImageSelected(), 2 );
|
||||
}
|
||||
if (mInRight)
|
||||
{
|
||||
drawRotatedImage(getImageSelected(), 1);
|
||||
}
|
||||
|
||||
if( mInLeft )
|
||||
{
|
||||
drawRotatedImage( getImageSelected(), 3 );
|
||||
if (mInBottom)
|
||||
{
|
||||
drawRotatedImage(getImageSelected(), 2);
|
||||
}
|
||||
|
||||
if (mInLeft)
|
||||
{
|
||||
drawRotatedImage(getImageSelected(), 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -613,7 +667,9 @@ LLJoystickCameraTrack::Params::Params()
|
|||
|
||||
LLJoystickCameraTrack::LLJoystickCameraTrack(const LLJoystickCameraTrack::Params& p)
|
||||
: LLJoystickCameraRotate(p)
|
||||
{}
|
||||
{
|
||||
mCenterImageName = "Cam_Tracking_Center";
|
||||
}
|
||||
|
||||
|
||||
void LLJoystickCameraTrack::onHeldDown()
|
||||
|
|
@ -647,6 +703,11 @@ void LLJoystickCameraTrack::onHeldDown()
|
|||
}
|
||||
}
|
||||
|
||||
void LLJoystickCameraTrack::resetJoystickCamera()
|
||||
{
|
||||
gAgentCamera.resetCameraPan();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// LLJoystickQuaternion
|
||||
//-------------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -80,7 +80,8 @@ public:
|
|||
* Image containing circle is square and this square has adherent points with joystick
|
||||
* circle. Make sure to change method according to shape other than square.
|
||||
*/
|
||||
bool pointInCircle(S32 x, S32 y) const;
|
||||
bool pointInCircle(S32 x, S32 y) const;
|
||||
bool pointInCenterDot(S32 x, S32 y, S32 radius) const;
|
||||
|
||||
static std::string nameFromQuadrant(const EJoystickQuadrant quadrant);
|
||||
static EJoystickQuadrant quadrantFromName(const std::string& name);
|
||||
|
|
@ -148,7 +149,9 @@ public:
|
|||
|
||||
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
|
||||
virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
|
||||
virtual BOOL handleHover(S32 x, S32 y, MASK mask);
|
||||
virtual void onHeldDown();
|
||||
virtual void resetJoystickCamera();
|
||||
virtual void draw();
|
||||
|
||||
protected:
|
||||
|
|
@ -161,6 +164,9 @@ protected:
|
|||
BOOL mInTop;
|
||||
BOOL mInRight;
|
||||
BOOL mInBottom;
|
||||
BOOL mInCenter;
|
||||
|
||||
std::string mCenterImageName;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -177,6 +183,7 @@ public:
|
|||
|
||||
LLJoystickCameraTrack(const LLJoystickCameraTrack::Params&);
|
||||
virtual void onHeldDown();
|
||||
virtual void resetJoystickCamera();
|
||||
};
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -66,9 +66,6 @@ extern LLControlGroup gSavedSettings;
|
|||
static const LLUUID PARCEL_MEDIA_LIST_ITEM_UUID = LLUUID("CAB5920F-E484-4233-8621-384CF373A321");
|
||||
static const LLUUID PARCEL_AUDIO_LIST_ITEM_UUID = LLUUID("DF4B020D-8A24-4B95-AB5D-CA970D694822");
|
||||
|
||||
const F32 AUTO_CLOSE_FADE_TIME_START= 2.0f;
|
||||
const F32 AUTO_CLOSE_FADE_TIME_END = 3.0f;
|
||||
|
||||
//
|
||||
// LLPanelNearByMedia
|
||||
//
|
||||
|
|
@ -82,8 +79,6 @@ LLPanelNearByMedia::LLPanelNearByMedia()
|
|||
mParcelMediaItem(NULL),
|
||||
mParcelAudioItem(NULL)
|
||||
{
|
||||
mHoverTimer.stop();
|
||||
|
||||
// This is just an initial value, mParcelAudioAutoStart does not affect ParcelMediaAutoPlayEnable
|
||||
mParcelAudioAutoStart = gSavedSettings.getS32("ParcelMediaAutoPlayEnable") != 0
|
||||
&& gSavedSettings.getBOOL("MediaTentativeAutoPlay");
|
||||
|
|
@ -111,7 +106,7 @@ LLPanelNearByMedia::~LLPanelNearByMedia()
|
|||
|
||||
BOOL LLPanelNearByMedia::postBuild()
|
||||
{
|
||||
LLPanel::postBuild();
|
||||
LLPanelPulldown::postBuild();
|
||||
|
||||
const S32 RESIZE_BAR_THICKNESS = 6;
|
||||
LLResizeBar::Params p;
|
||||
|
|
@ -193,45 +188,10 @@ void LLPanelNearByMedia::handleMediaAutoPlayChanged(const LLSD& newvalue)
|
|||
inst->cancelNotification();
|
||||
}
|
||||
|
||||
/*virtual*/
|
||||
void LLPanelNearByMedia::onMouseEnter(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
mHoverTimer.stop();
|
||||
LLPanel::onMouseEnter(x,y,mask);
|
||||
}
|
||||
|
||||
|
||||
/*virtual*/
|
||||
void LLPanelNearByMedia::onMouseLeave(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
mHoverTimer.start();
|
||||
LLPanel::onMouseLeave(x,y,mask);
|
||||
}
|
||||
|
||||
/*virtual*/
|
||||
void LLPanelNearByMedia::onTopLost()
|
||||
{
|
||||
setVisible(FALSE);
|
||||
}
|
||||
|
||||
|
||||
/*virtual*/
|
||||
void LLPanelNearByMedia::onVisibilityChange ( BOOL new_visibility )
|
||||
{
|
||||
if (new_visibility)
|
||||
{
|
||||
mHoverTimer.start(); // timer will be stopped when mouse hovers over panel
|
||||
}
|
||||
else
|
||||
{
|
||||
mHoverTimer.stop();
|
||||
}
|
||||
}
|
||||
|
||||
/*virtual*/
|
||||
void LLPanelNearByMedia::reshape(S32 width, S32 height, BOOL called_from_parent)
|
||||
{
|
||||
LLPanel::reshape(width, height, called_from_parent);
|
||||
LLPanelPulldown::reshape(width, height, called_from_parent);
|
||||
|
||||
LLButton* more_btn = findChild<LLButton>("more_btn");
|
||||
if (more_btn && more_btn->getValue().asBoolean())
|
||||
|
|
@ -255,24 +215,14 @@ void LLPanelNearByMedia::draw()
|
|||
|
||||
refreshList();
|
||||
updateControls();
|
||||
|
||||
F32 alpha = mHoverTimer.getStarted()
|
||||
? clamp_rescale(mHoverTimer.getElapsedTimeF32(), AUTO_CLOSE_FADE_TIME_START, AUTO_CLOSE_FADE_TIME_END, 1.f, 0.f)
|
||||
: 1.0f;
|
||||
LLViewDrawContext context(alpha);
|
||||
|
||||
LLPanel::draw();
|
||||
|
||||
if (alpha == 0.f)
|
||||
{
|
||||
setVisible(false);
|
||||
}
|
||||
LLPanelPulldown::draw();
|
||||
}
|
||||
|
||||
/*virtual*/
|
||||
BOOL LLPanelNearByMedia::handleHover(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
LLPanel::handleHover(x, y, mask);
|
||||
LLPanelPulldown::handleHover(x, y, mask);
|
||||
|
||||
// If we are hovering over this panel, make sure to clear any hovered media
|
||||
// ID. Note that the more general solution would be to clear this ID when
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
#ifndef LL_LLPANELNEARBYMEDIA_H
|
||||
#define LL_LLPANELNEARBYMEDIA_H
|
||||
|
||||
#include "llpanel.h"
|
||||
#include "llpanelpulldown.h"
|
||||
|
||||
class LLPanelNearbyMedia;
|
||||
class LLButton;
|
||||
|
|
@ -39,16 +39,12 @@ class LLTextBox;
|
|||
class LLComboBox;
|
||||
class LLViewerMediaImpl;
|
||||
|
||||
class LLPanelNearByMedia : public LLPanel
|
||||
class LLPanelNearByMedia : public LLPanelPulldown
|
||||
{
|
||||
public:
|
||||
|
||||
/*virtual*/ BOOL postBuild();
|
||||
/*virtual*/ void draw();
|
||||
/*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask);
|
||||
/*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);
|
||||
/*virtual*/ void onTopLost();
|
||||
/*virtual*/ void onVisibilityChange ( BOOL new_visibility );
|
||||
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent);
|
||||
/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
|
||||
|
||||
|
|
@ -173,7 +169,6 @@ private:
|
|||
|
||||
LLRect mMoreRect;
|
||||
LLRect mLessRect;
|
||||
LLFrameTimer mHoverTimer;
|
||||
LLScrollListItem* mParcelMediaItem;
|
||||
LLScrollListItem* mParcelAudioItem;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,149 @@
|
|||
/**
|
||||
* @file llpanelpresetscamerapulldown.cpp
|
||||
* @brief A panel showing a quick way to pick camera presets
|
||||
*
|
||||
* $LicenseInfo:firstyear=2017&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2017, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llpanelpresetscamerapulldown.h"
|
||||
|
||||
#include "llviewercontrol.h"
|
||||
#include "llstatusbar.h"
|
||||
|
||||
#include "llbutton.h"
|
||||
#include "lltabcontainer.h"
|
||||
#include "llfloatercamera.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "llfloaterpreference.h"
|
||||
#include "llpresetsmanager.h"
|
||||
#include "llsliderctrl.h"
|
||||
#include "llscrolllistctrl.h"
|
||||
#include "lltrans.h"
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// Class LLPanelPresetsCameraPulldown
|
||||
///----------------------------------------------------------------------------
|
||||
|
||||
// Default constructor
|
||||
LLPanelPresetsCameraPulldown::LLPanelPresetsCameraPulldown()
|
||||
{
|
||||
mCommitCallbackRegistrar.add("Presets.toggleCameraFloater", boost::bind(&LLPanelPresetsCameraPulldown::onViewButtonClick, this, _2));
|
||||
mCommitCallbackRegistrar.add("PresetsCamera.RowClick", boost::bind(&LLPanelPresetsCameraPulldown::onRowClick, this, _2));
|
||||
|
||||
buildFromFile( "panel_presets_camera_pulldown.xml");
|
||||
}
|
||||
|
||||
BOOL LLPanelPresetsCameraPulldown::postBuild()
|
||||
{
|
||||
LLPresetsManager* presetsMgr = LLPresetsManager::getInstance();
|
||||
if (presetsMgr)
|
||||
{
|
||||
// Make sure there is a default preference file
|
||||
presetsMgr->createMissingDefault(PRESETS_CAMERA);
|
||||
|
||||
presetsMgr->startWatching(PRESETS_CAMERA);
|
||||
|
||||
presetsMgr->setPresetListChangeCameraCallback(boost::bind(&LLPanelPresetsCameraPulldown::populatePanel, this));
|
||||
}
|
||||
|
||||
populatePanel();
|
||||
|
||||
return LLPanelPulldown::postBuild();
|
||||
}
|
||||
|
||||
void LLPanelPresetsCameraPulldown::populatePanel()
|
||||
{
|
||||
LLPresetsManager::getInstance()->loadPresetNamesFromDir(PRESETS_CAMERA, mPresetNames, DEFAULT_BOTTOM);
|
||||
|
||||
LLScrollListCtrl* scroll = getChild<LLScrollListCtrl>("preset_camera_list");
|
||||
|
||||
if (scroll && mPresetNames.begin() != mPresetNames.end())
|
||||
{
|
||||
scroll->clearRows();
|
||||
|
||||
std::string active_preset = gSavedSettings.getString("PresetCameraActive");
|
||||
if (active_preset == PRESETS_DEFAULT)
|
||||
{
|
||||
active_preset = LLTrans::getString(PRESETS_DEFAULT);
|
||||
}
|
||||
|
||||
for (std::list<std::string>::const_iterator it = mPresetNames.begin(); it != mPresetNames.end(); ++it)
|
||||
{
|
||||
const std::string& name = *it;
|
||||
LL_DEBUGS() << "adding '" << name << "'" << LL_ENDL;
|
||||
|
||||
LLSD row;
|
||||
row["columns"][0]["column"] = "preset_name";
|
||||
row["columns"][0]["value"] = name;
|
||||
|
||||
bool is_selected_preset = false;
|
||||
if (name == active_preset)
|
||||
{
|
||||
row["columns"][1]["column"] = "icon";
|
||||
row["columns"][1]["type"] = "icon";
|
||||
row["columns"][1]["value"] = "Check_Mark";
|
||||
|
||||
is_selected_preset = true;
|
||||
}
|
||||
|
||||
LLScrollListItem* new_item = scroll->addElement(row);
|
||||
new_item->setSelected(is_selected_preset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelPresetsCameraPulldown::onRowClick(const LLSD& user_data)
|
||||
{
|
||||
LLScrollListCtrl* scroll = getChild<LLScrollListCtrl>("preset_camera_list");
|
||||
|
||||
if (scroll)
|
||||
{
|
||||
LLScrollListItem* item = scroll->getFirstSelected();
|
||||
if (item)
|
||||
{
|
||||
std::string name = item->getColumn(1)->getValue().asString();
|
||||
|
||||
LL_DEBUGS() << "selected '" << name << "'" << LL_ENDL;
|
||||
LLFloaterCamera::switchToPreset(name);
|
||||
|
||||
setVisible(FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_DEBUGS() << "none selected" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_DEBUGS() << "no scroll" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelPresetsCameraPulldown::onViewButtonClick(const LLSD& user_data)
|
||||
{
|
||||
// close the minicontrol, we're bringing up the big one
|
||||
setVisible(FALSE);
|
||||
|
||||
LLFloaterReg::toggleInstanceOrBringToFront("camera");
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/**
|
||||
* @file llpanelpresetscamerapulldown.h
|
||||
* @brief A panel showing a quick way to pick camera presets
|
||||
*
|
||||
* $LicenseInfo:firstyear=2017&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2017, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLPANELPRESETSCAMERAPULLDOWN_H
|
||||
#define LL_LLPANELPRESETSCAMERAPULLDOWN_H
|
||||
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "llpanelpulldown.h"
|
||||
|
||||
class LLPanelPresetsCameraPulldown : public LLPanelPulldown
|
||||
{
|
||||
public:
|
||||
LLPanelPresetsCameraPulldown();
|
||||
/*virtual*/ BOOL postBuild();
|
||||
void populatePanel();
|
||||
|
||||
private:
|
||||
void onViewButtonClick(const LLSD& user_data);
|
||||
void onRowClick(const LLSD& user_data);
|
||||
|
||||
std::list<std::string> mPresetNames;
|
||||
LOG_CLASS(LLPanelPresetsCameraPulldown);
|
||||
};
|
||||
|
||||
#endif // LL_LLPANELPRESETSCAMERAPULLDOWN_H
|
||||
|
|
@ -40,9 +40,6 @@
|
|||
#include "llscrolllistctrl.h"
|
||||
#include "lltrans.h"
|
||||
|
||||
/* static */ const F32 LLPanelPresetsPulldown::sAutoCloseFadeStartTimeSec = 2.0f;
|
||||
/* static */ const F32 LLPanelPresetsPulldown::sAutoCloseTotalTimeSec = 3.0f;
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// Class LLPanelPresetsPulldown
|
||||
///----------------------------------------------------------------------------
|
||||
|
|
@ -63,17 +60,16 @@ BOOL LLPanelPresetsPulldown::postBuild()
|
|||
LLPresetsManager* presetsMgr = LLPresetsManager::getInstance();
|
||||
presetsMgr->setPresetListChangeCallback(boost::bind(&LLPanelPresetsPulldown::populatePanel, this));
|
||||
// Make sure there is a default preference file
|
||||
presetsMgr->createMissingDefault();
|
||||
presetsMgr->createMissingDefault(PRESETS_GRAPHIC);
|
||||
|
||||
populatePanel();
|
||||
|
||||
return LLPanel::postBuild();
|
||||
return LLPanelPulldown::postBuild();
|
||||
}
|
||||
|
||||
void LLPanelPresetsPulldown::populatePanel()
|
||||
{
|
||||
std::string presets_dir = LLPresetsManager::getInstance()->getPresetsDir(PRESETS_GRAPHIC);
|
||||
LLPresetsManager::getInstance()->loadPresetNamesFromDir(presets_dir, mPresetNames, DEFAULT_TOP);
|
||||
LLPresetsManager::getInstance()->loadPresetNamesFromDir(PRESETS_GRAPHIC, mPresetNames, DEFAULT_TOP);
|
||||
|
||||
LLScrollListCtrl* scroll = getChild<LLScrollListCtrl>("preset_list");
|
||||
|
||||
|
|
@ -112,61 +108,6 @@ void LLPanelPresetsPulldown::populatePanel()
|
|||
}
|
||||
}
|
||||
|
||||
/*virtual*/
|
||||
void LLPanelPresetsPulldown::onMouseEnter(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
mHoverTimer.stop();
|
||||
LLPanel::onMouseEnter(x,y,mask);
|
||||
}
|
||||
|
||||
/*virtual*/
|
||||
void LLPanelPresetsPulldown::onTopLost()
|
||||
{
|
||||
setVisible(FALSE);
|
||||
}
|
||||
|
||||
/*virtual*/
|
||||
BOOL LLPanelPresetsPulldown::handleMouseDown(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
LLPanel::handleMouseDown(x,y,mask);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*virtual*/
|
||||
BOOL LLPanelPresetsPulldown::handleRightMouseDown(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
LLPanel::handleRightMouseDown(x, y, mask);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*virtual*/
|
||||
BOOL LLPanelPresetsPulldown::handleDoubleClick(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
LLPanel::handleDoubleClick(x, y, mask);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*virtual*/
|
||||
void LLPanelPresetsPulldown::onMouseLeave(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
mHoverTimer.start();
|
||||
LLPanel::onMouseLeave(x,y,mask);
|
||||
}
|
||||
|
||||
/*virtual*/
|
||||
void LLPanelPresetsPulldown::onVisibilityChange ( BOOL new_visibility )
|
||||
{
|
||||
if (new_visibility)
|
||||
{
|
||||
mHoverTimer.start(); // timer will be stopped when mouse hovers over panel
|
||||
}
|
||||
else
|
||||
{
|
||||
mHoverTimer.stop();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelPresetsPulldown::onRowClick(const LLSD& user_data)
|
||||
{
|
||||
LLScrollListCtrl* scroll = getChild<LLScrollListCtrl>("preset_list");
|
||||
|
|
@ -213,19 +154,3 @@ void LLPanelPresetsPulldown::onGraphicsButtonClick(const LLSD& user_data)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLPanelPresetsPulldown::draw()
|
||||
{
|
||||
F32 alpha = mHoverTimer.getStarted()
|
||||
? clamp_rescale(mHoverTimer.getElapsedTimeF32(), sAutoCloseFadeStartTimeSec, sAutoCloseTotalTimeSec, 1.f, 0.f)
|
||||
: 1.0f;
|
||||
LLViewDrawContext context(alpha);
|
||||
|
||||
LLPanel::draw();
|
||||
|
||||
if (alpha == 0.f)
|
||||
{
|
||||
setVisible(FALSE);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,22 +29,13 @@
|
|||
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "llpanel.h"
|
||||
#include "llpanelpulldown.h"
|
||||
|
||||
class LLFrameTimer;
|
||||
|
||||
class LLPanelPresetsPulldown : public LLPanel
|
||||
class LLPanelPresetsPulldown : public LLPanelPulldown
|
||||
{
|
||||
public:
|
||||
LLPanelPresetsPulldown();
|
||||
/*virtual*/ void draw();
|
||||
/*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask);
|
||||
/*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);
|
||||
/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
|
||||
/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
|
||||
/*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
|
||||
/*virtual*/ void onTopLost();
|
||||
/*virtual*/ void onVisibilityChange ( BOOL new_visibility );
|
||||
/*virtual*/ BOOL postBuild();
|
||||
void populatePanel();
|
||||
|
||||
|
|
@ -53,9 +44,6 @@ class LLPanelPresetsPulldown : public LLPanel
|
|||
void onRowClick(const LLSD& user_data);
|
||||
|
||||
std::list<std::string> mPresetNames;
|
||||
LLFrameTimer mHoverTimer;
|
||||
static const F32 sAutoCloseFadeStartTimeSec;
|
||||
static const F32 sAutoCloseTotalTimeSec;
|
||||
LOG_CLASS(LLPanelPresetsPulldown);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,118 @@
|
|||
/**
|
||||
* @file llpanelpulldown.cpp
|
||||
* @brief A panel that serves as a basis for multiple toolbar pulldown panels
|
||||
*
|
||||
* $LicenseInfo:firstyear=2020&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2020, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llpanelpulldown.h"
|
||||
|
||||
const F32 AUTO_CLOSE_FADE_TIME_START_SEC = 2.0f;
|
||||
const F32 AUTO_CLOSE_FADE_TIME_END_SEC = 3.0f;
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// Class LLPanelPresetsCameraPulldown
|
||||
///----------------------------------------------------------------------------
|
||||
|
||||
// Default constructor
|
||||
LLPanelPulldown::LLPanelPulldown()
|
||||
{
|
||||
mHoverTimer.stop();
|
||||
}
|
||||
|
||||
/*virtual*/
|
||||
void LLPanelPulldown::onMouseEnter(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
mHoverTimer.stop();
|
||||
LLPanel::onMouseEnter(x, y, mask);
|
||||
}
|
||||
|
||||
/*virtual*/
|
||||
void LLPanelPulldown::onTopLost()
|
||||
{
|
||||
setVisible(FALSE);
|
||||
}
|
||||
|
||||
/*virtual*/
|
||||
BOOL LLPanelPulldown::handleMouseDown(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
LLPanel::handleMouseDown(x, y, mask);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*virtual*/
|
||||
BOOL LLPanelPulldown::handleRightMouseDown(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
LLPanel::handleRightMouseDown(x, y, mask);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*virtual*/
|
||||
BOOL LLPanelPulldown::handleDoubleClick(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
LLPanel::handleDoubleClick(x, y, mask);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LLPanelPulldown::handleScrollWheel(S32 x, S32 y, S32 clicks)
|
||||
{
|
||||
LLPanel::handleScrollWheel(x, y, clicks);
|
||||
return TRUE; //If we got here, then we are in Pulldown's rect, consume the event.
|
||||
}
|
||||
|
||||
/*virtual*/
|
||||
void LLPanelPulldown::onMouseLeave(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
mHoverTimer.start();
|
||||
LLPanel::onMouseLeave(x, y, mask);
|
||||
}
|
||||
|
||||
/*virtual*/
|
||||
void LLPanelPulldown::onVisibilityChange(BOOL new_visibility)
|
||||
{
|
||||
if (new_visibility)
|
||||
{
|
||||
mHoverTimer.start(); // timer will be stopped when mouse hovers over panel
|
||||
}
|
||||
else
|
||||
{
|
||||
mHoverTimer.stop();
|
||||
}
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLPanelPulldown::draw()
|
||||
{
|
||||
F32 alpha = mHoverTimer.getStarted()
|
||||
? clamp_rescale(mHoverTimer.getElapsedTimeF32(), AUTO_CLOSE_FADE_TIME_START_SEC, AUTO_CLOSE_FADE_TIME_END_SEC, 1.f, 0.f)
|
||||
: 1.0f;
|
||||
LLViewDrawContext context(alpha);
|
||||
|
||||
LLPanel::draw();
|
||||
|
||||
if (alpha == 0.f)
|
||||
{
|
||||
setVisible(FALSE);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
/**
|
||||
* @file llpanelpulldown.h
|
||||
* @brief A panel that serves as a basis for multiple toolbar pulldown panels
|
||||
*
|
||||
* $LicenseInfo:firstyear=2020&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2020, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLPANELPULLDOWN_H
|
||||
#define LL_LLPANELPULLDOWN_H
|
||||
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "llpanel.h"
|
||||
|
||||
class LLFrameTimer;
|
||||
|
||||
class LLPanelPulldown : public LLPanel
|
||||
{
|
||||
public:
|
||||
LLPanelPulldown();
|
||||
/*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask);
|
||||
/*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);
|
||||
/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
|
||||
/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
|
||||
/*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
|
||||
/*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
|
||||
/*virtual*/ void onTopLost();
|
||||
/*virtual*/ void onVisibilityChange(BOOL new_visibility);
|
||||
|
||||
/*virtual*/ void draw();
|
||||
|
||||
protected:
|
||||
LLFrameTimer mHoverTimer;
|
||||
};
|
||||
|
||||
#endif // LL_LLPANELPULLDOWN_H
|
||||
|
|
@ -41,9 +41,6 @@
|
|||
#include "llfloaterpreference.h"
|
||||
#include "llsliderctrl.h"
|
||||
|
||||
/* static */ const F32 LLPanelVolumePulldown::sAutoCloseFadeStartTimeSec = 2.0f;
|
||||
/* static */ const F32 LLPanelVolumePulldown::sAutoCloseTotalTimeSec = 3.0f;
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// Class LLPanelVolumePulldown
|
||||
///----------------------------------------------------------------------------
|
||||
|
|
@ -51,8 +48,6 @@
|
|||
// Default constructor
|
||||
LLPanelVolumePulldown::LLPanelVolumePulldown()
|
||||
{
|
||||
mHoverTimer.stop();
|
||||
|
||||
mCommitCallbackRegistrar.add("Vol.setControlFalse", boost::bind(&LLPanelVolumePulldown::setControlFalse, this, _2));
|
||||
mCommitCallbackRegistrar.add("Vol.SetSounds", boost::bind(&LLPanelVolumePulldown::onClickSetSounds, this));
|
||||
mCommitCallbackRegistrar.add("Vol.updateMediaAutoPlayCheckbox", boost::bind(&LLPanelVolumePulldown::updateMediaAutoPlayCheckbox, this, _1));
|
||||
|
|
@ -62,41 +57,7 @@ LLPanelVolumePulldown::LLPanelVolumePulldown()
|
|||
|
||||
BOOL LLPanelVolumePulldown::postBuild()
|
||||
{
|
||||
return LLPanel::postBuild();
|
||||
}
|
||||
|
||||
/*virtual*/
|
||||
void LLPanelVolumePulldown::onMouseEnter(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
mHoverTimer.stop();
|
||||
LLPanel::onMouseEnter(x,y,mask);
|
||||
}
|
||||
|
||||
/*virtual*/
|
||||
void LLPanelVolumePulldown::onTopLost()
|
||||
{
|
||||
setVisible(FALSE);
|
||||
}
|
||||
|
||||
/*virtual*/
|
||||
void LLPanelVolumePulldown::onMouseLeave(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
mHoverTimer.start();
|
||||
LLPanel::onMouseLeave(x,y,mask);
|
||||
}
|
||||
|
||||
/*virtual*/
|
||||
void LLPanelVolumePulldown::onVisibilityChange ( BOOL new_visibility )
|
||||
{
|
||||
if (new_visibility)
|
||||
{
|
||||
mHoverTimer.start(); // timer will be stopped when mouse hovers over panel
|
||||
}
|
||||
else
|
||||
{
|
||||
mHoverTimer.stop();
|
||||
|
||||
}
|
||||
return LLPanelPulldown::postBuild();
|
||||
}
|
||||
|
||||
void LLPanelVolumePulldown::onAdvancedButtonClick(const LLSD& user_data)
|
||||
|
|
@ -150,20 +111,3 @@ void LLPanelVolumePulldown::onClickSetSounds()
|
|||
// or if sound effects are disabled.
|
||||
getChild<LLCheckBoxCtrl>("gesture_audio_play_btn")->setEnabled(!gSavedSettings.getBOOL("MuteSounds"));
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLPanelVolumePulldown::draw()
|
||||
{
|
||||
F32 alpha = mHoverTimer.getStarted()
|
||||
? clamp_rescale(mHoverTimer.getElapsedTimeF32(), sAutoCloseFadeStartTimeSec, sAutoCloseTotalTimeSec, 1.f, 0.f)
|
||||
: 1.0f;
|
||||
LLViewDrawContext context(alpha);
|
||||
|
||||
LLPanel::draw();
|
||||
|
||||
if (alpha == 0.f)
|
||||
{
|
||||
setVisible(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,19 +30,12 @@
|
|||
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "llpanel.h"
|
||||
#include "llpanelpulldown.h"
|
||||
|
||||
class LLFrameTimer;
|
||||
|
||||
class LLPanelVolumePulldown : public LLPanel
|
||||
class LLPanelVolumePulldown : public LLPanelPulldown
|
||||
{
|
||||
public:
|
||||
LLPanelVolumePulldown();
|
||||
/*virtual*/ void draw();
|
||||
/*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask);
|
||||
/*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);
|
||||
/*virtual*/ void onTopLost();
|
||||
/*virtual*/ void onVisibilityChange ( BOOL new_visibility );
|
||||
/*virtual*/ BOOL postBuild();
|
||||
|
||||
private:
|
||||
|
|
@ -52,10 +45,6 @@ class LLPanelVolumePulldown : public LLPanel
|
|||
// "Streaming Music" and "Media" are unchecked. Otherwise enables it.
|
||||
void updateMediaAutoPlayCheckbox(LLUICtrl* ctrl);
|
||||
void onAdvancedButtonClick(const LLSD& user_data);
|
||||
|
||||
LLFrameTimer mHoverTimer;
|
||||
static const F32 sAutoCloseFadeStartTimeSec;
|
||||
static const F32 sAutoCloseTotalTimeSec;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,8 @@
|
|||
#include "llfloaterpreference.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "llfeaturemanager.h"
|
||||
#include "llagentcamera.h"
|
||||
#include "llfile.h"
|
||||
|
||||
LLPresetsManager::LLPresetsManager()
|
||||
{
|
||||
|
|
@ -46,6 +48,12 @@ LLPresetsManager::LLPresetsManager()
|
|||
|
||||
LLPresetsManager::~LLPresetsManager()
|
||||
{
|
||||
mCameraChangedSignal.disconnect();
|
||||
}
|
||||
|
||||
void LLPresetsManager::triggerChangeCameraSignal()
|
||||
{
|
||||
mPresetListChangeCameraSignal();
|
||||
}
|
||||
|
||||
void LLPresetsManager::triggerChangeSignal()
|
||||
|
|
@ -53,41 +61,92 @@ void LLPresetsManager::triggerChangeSignal()
|
|||
mPresetListChangeSignal();
|
||||
}
|
||||
|
||||
void LLPresetsManager::createMissingDefault()
|
||||
void LLPresetsManager::createMissingDefault(const std::string& subdirectory)
|
||||
{
|
||||
if(gDirUtilp->getLindenUserDir().empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
std::string default_file = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PRESETS_DIR, PRESETS_GRAPHIC, PRESETS_DEFAULT + ".xml");
|
||||
|
||||
if (PRESETS_CAMERA == subdirectory)
|
||||
{
|
||||
createCameraDefaultPresets();
|
||||
return;
|
||||
}
|
||||
|
||||
std::string default_file = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PRESETS_DIR,
|
||||
subdirectory, PRESETS_DEFAULT + ".xml");
|
||||
if (!gDirUtilp->fileExists(default_file))
|
||||
{
|
||||
LL_INFOS() << "No default preset found -- creating one at " << default_file << LL_ENDL;
|
||||
|
||||
// Write current graphic settings as the default
|
||||
savePreset(PRESETS_GRAPHIC, PRESETS_DEFAULT, true);
|
||||
// Write current settings as the default
|
||||
savePreset(subdirectory, PRESETS_DEFAULT, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_DEBUGS() << "default preset exists; no-op" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
void LLPresetsManager::createCameraDefaultPresets()
|
||||
{
|
||||
bool is_default_created = createDefaultCameraPreset(PRESETS_REAR_VIEW);
|
||||
is_default_created |= createDefaultCameraPreset(PRESETS_FRONT_VIEW);
|
||||
is_default_created |= createDefaultCameraPreset(PRESETS_SIDE_VIEW);
|
||||
|
||||
if (is_default_created)
|
||||
{
|
||||
triggerChangeCameraSignal();
|
||||
}
|
||||
}
|
||||
|
||||
void LLPresetsManager::startWatching(const std::string& subdirectory)
|
||||
{
|
||||
if (PRESETS_CAMERA == subdirectory)
|
||||
{
|
||||
std::vector<std::string> name_list;
|
||||
getControlNames(name_list);
|
||||
|
||||
for (std::vector<std::string>::iterator it = name_list.begin(); it != name_list.end(); ++it)
|
||||
{
|
||||
std::string ctrl_name = *it;
|
||||
if (gSavedSettings.controlExists(ctrl_name))
|
||||
{
|
||||
LLPointer<LLControlVariable> cntrl_ptr = gSavedSettings.getControl(ctrl_name);
|
||||
if (cntrl_ptr.isNull())
|
||||
{
|
||||
LL_WARNS("Init") << "Unable to set signal on global setting '" << ctrl_name
|
||||
<< "'" << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
mCameraChangedSignal = cntrl_ptr->getCommitSignal()->connect(boost::bind(&settingChanged));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_DEBUGS() << "default preset exists; no-op" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
std::string LLPresetsManager::getPresetsDir(const std::string& subdirectory)
|
||||
{
|
||||
std::string presets_path = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PRESETS_DIR);
|
||||
std::string full_path;
|
||||
|
||||
LLFile::mkdir(presets_path);
|
||||
|
||||
full_path = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PRESETS_DIR, subdirectory);
|
||||
LLFile::mkdir(full_path);
|
||||
std::string dest_path = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PRESETS_DIR, subdirectory);
|
||||
if (!gDirUtilp->fileExists(dest_path))
|
||||
LLFile::mkdir(dest_path);
|
||||
|
||||
return full_path;
|
||||
return dest_path;
|
||||
}
|
||||
|
||||
void LLPresetsManager::loadPresetNamesFromDir(const std::string& dir, preset_name_list_t& presets, EDefaultOptions default_option)
|
||||
void LLPresetsManager::loadPresetNamesFromDir(const std::string& subdirectory, preset_name_list_t& presets, EDefaultOptions default_option)
|
||||
{
|
||||
bool IS_CAMERA = (PRESETS_CAMERA == subdirectory);
|
||||
bool IS_GRAPHIC = (PRESETS_GRAPHIC == subdirectory);
|
||||
|
||||
std::string dir = LLPresetsManager::getInstance()->getPresetsDir(subdirectory);
|
||||
LL_INFOS("AppInit") << "Loading list of preset names from " << dir << LL_ENDL;
|
||||
|
||||
mPresetNames.clear();
|
||||
|
|
@ -103,16 +162,33 @@ void LLPresetsManager::loadPresetNamesFromDir(const std::string& dir, preset_nam
|
|||
{
|
||||
std::string path = gDirUtilp->add(dir, file);
|
||||
std::string name = LLURI::unescape(gDirUtilp->getBaseFileName(path, /*strip_exten = */ true));
|
||||
LL_DEBUGS() << " Found preset '" << name << "'" << LL_ENDL;
|
||||
LL_DEBUGS() << " Found preset '" << name << "'" << LL_ENDL;
|
||||
|
||||
if (PRESETS_DEFAULT != name)
|
||||
if (IS_CAMERA)
|
||||
{
|
||||
if (isTemplateCameraPreset(name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ((default_option == DEFAULT_HIDE) || (default_option == DEFAULT_BOTTOM))
|
||||
{
|
||||
if (isDefaultCameraPreset(name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
mPresetNames.push_back(name);
|
||||
}
|
||||
else
|
||||
if (IS_GRAPHIC)
|
||||
{
|
||||
switch (default_option)
|
||||
if (PRESETS_DEFAULT != name)
|
||||
{
|
||||
mPresetNames.push_back(name);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (default_option)
|
||||
{
|
||||
case DEFAULT_SHOW:
|
||||
mPresetNames.push_back(LLTrans::getString(PRESETS_DEFAULT));
|
||||
break;
|
||||
|
|
@ -124,16 +200,77 @@ void LLPresetsManager::loadPresetNamesFromDir(const std::string& dir, preset_nam
|
|||
case DEFAULT_HIDE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_CAMERA)
|
||||
{
|
||||
mPresetNames.sort(LLStringUtil::precedesDict);
|
||||
if (default_option == DEFAULT_BOTTOM)
|
||||
{
|
||||
mPresetNames.push_back(PRESETS_FRONT_VIEW);
|
||||
mPresetNames.push_back(PRESETS_REAR_VIEW);
|
||||
mPresetNames.push_back(PRESETS_SIDE_VIEW);
|
||||
}
|
||||
}
|
||||
|
||||
presets = mPresetNames;
|
||||
}
|
||||
|
||||
bool LLPresetsManager::mCameraDirty = false;
|
||||
bool LLPresetsManager::mIgnoreChangedSignal = false;
|
||||
|
||||
void LLPresetsManager::setCameraDirty(bool dirty)
|
||||
{
|
||||
mCameraDirty = dirty;
|
||||
}
|
||||
|
||||
bool LLPresetsManager::isCameraDirty()
|
||||
{
|
||||
return mCameraDirty;
|
||||
}
|
||||
|
||||
void LLPresetsManager::settingChanged()
|
||||
{
|
||||
setCameraDirty(true);
|
||||
|
||||
static LLCachedControl<std::string> preset_camera_active(gSavedSettings, "PresetCameraActive", "");
|
||||
std::string preset_name = preset_camera_active;
|
||||
if (!preset_name.empty() && !mIgnoreChangedSignal)
|
||||
{
|
||||
gSavedSettings.setString("PresetCameraActive", "");
|
||||
|
||||
// Hack call because this is a static routine
|
||||
LLPresetsManager::getInstance()->triggerChangeCameraSignal();
|
||||
}
|
||||
}
|
||||
|
||||
void LLPresetsManager::getControlNames(std::vector<std::string>& names)
|
||||
{
|
||||
const std::vector<std::string> camera_controls = boost::assign::list_of
|
||||
// From panel_preferences_move.xml
|
||||
("CameraAngle")
|
||||
("CameraOffsetScale")
|
||||
("EditCameraMovement")
|
||||
("AppearanceCameraMovement")
|
||||
// From llagentcamera.cpp
|
||||
("CameraOffsetBuild")
|
||||
("TrackFocusObject")
|
||||
("CameraOffsetRearView")
|
||||
("FocusOffsetRearView")
|
||||
("AvatarSitRotation")
|
||||
;
|
||||
names = camera_controls;
|
||||
}
|
||||
|
||||
bool LLPresetsManager::savePreset(const std::string& subdirectory, std::string name, bool createDefault)
|
||||
{
|
||||
bool IS_CAMERA = (PRESETS_CAMERA == subdirectory);
|
||||
bool IS_GRAPHIC = (PRESETS_GRAPHIC == subdirectory);
|
||||
|
||||
if (LLTrans::getString(PRESETS_DEFAULT) == name)
|
||||
{
|
||||
name = PRESETS_DEFAULT;
|
||||
|
|
@ -144,126 +281,174 @@ bool LLPresetsManager::savePreset(const std::string& subdirectory, std::string n
|
|||
return false;
|
||||
}
|
||||
|
||||
if (isTemplateCameraPreset(name))
|
||||
{
|
||||
LL_WARNS() << "Should not overwrite template presets" << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool saved = false;
|
||||
std::vector<std::string> name_list;
|
||||
|
||||
if(PRESETS_GRAPHIC == subdirectory)
|
||||
if (IS_GRAPHIC)
|
||||
{
|
||||
LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
|
||||
if (instance && !createDefault)
|
||||
{
|
||||
gSavedSettings.setString("PresetGraphicActive", name);
|
||||
gSavedSettings.setString("PresetGraphicActive", name);
|
||||
instance->getControlNames(name_list);
|
||||
LL_DEBUGS() << "saving preset '" << name << "'; " << name_list.size() << " names" << LL_ENDL;
|
||||
LL_DEBUGS() << "saving preset '" << name << "'; " << name_list.size() << " names" << LL_ENDL;
|
||||
name_list.push_back("PresetGraphicActive");
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
LL_WARNS() << "preferences floater instance not found" << LL_ENDL;
|
||||
}
|
||||
LL_WARNS("Presets") << "preferences floater instance not found" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
else if(PRESETS_CAMERA == subdirectory)
|
||||
else if (IS_CAMERA)
|
||||
{
|
||||
name_list.clear();
|
||||
name_list.push_back("Placeholder");
|
||||
getControlNames(name_list);
|
||||
name_list.push_back("PresetCameraActive");
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_ERRS() << "Invalid presets directory '" << subdirectory << "'" << LL_ENDL;
|
||||
}
|
||||
|
||||
if (name_list.size() > 1 // if the active preset name is the only thing in the list, don't save the list
|
||||
|| (createDefault && name == PRESETS_DEFAULT && subdirectory == PRESETS_GRAPHIC)) // or create a default graphics preset from hw recommended settings
|
||||
{
|
||||
// make an empty llsd
|
||||
LLSD paramsData(LLSD::emptyMap());
|
||||
|
||||
if (createDefault)
|
||||
{
|
||||
paramsData = LLFeatureManager::getInstance()->getRecommendedSettingsMap();
|
||||
if (gSavedSettings.getU32("RenderAvatarMaxComplexity") == 0)
|
||||
{
|
||||
// use the recommended setting as an initial one (MAINT-6435)
|
||||
gSavedSettings.setU32("RenderAvatarMaxComplexity", paramsData["RenderAvatarMaxComplexity"]["Value"].asInteger());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (std::vector<std::string>::iterator it = name_list.begin(); it != name_list.end(); ++it)
|
||||
{
|
||||
std::string ctrl_name = *it;
|
||||
LLControlVariable* ctrl = gSavedSettings.getControl(ctrl_name).get();
|
||||
std::string comment = ctrl->getComment();
|
||||
std::string type = LLControlGroup::typeEnumToString(ctrl->type());
|
||||
LLSD value = ctrl->getValue();
|
||||
|
||||
paramsData[ctrl_name]["Comment"] = comment;
|
||||
paramsData[ctrl_name]["Persist"] = 1;
|
||||
paramsData[ctrl_name]["Type"] = type;
|
||||
paramsData[ctrl_name]["Value"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
std::string pathName(getPresetsDir(subdirectory) + gDirUtilp->getDirDelimiter() + LLURI::escape(name) + ".xml");
|
||||
|
||||
// write to file
|
||||
llofstream presetsXML(pathName.c_str());
|
||||
if (presetsXML.is_open())
|
||||
{
|
||||
|
||||
LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter();
|
||||
formatter->format(paramsData, presetsXML, LLSDFormatter::OPTIONS_PRETTY);
|
||||
presetsXML.close();
|
||||
saved = true;
|
||||
|
||||
LL_DEBUGS() << "saved preset '" << name << "'; " << paramsData.size() << " parameters" << LL_ENDL;
|
||||
|
||||
if (!createDefault)
|
||||
{
|
||||
gSavedSettings.setString("PresetGraphicActive", name);
|
||||
// signal interested parties
|
||||
triggerChangeSignal();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("Presets") << "Cannot open for output preset file " << pathName << LL_ENDL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_INFOS() << "No settings found; preferences floater has not yet been created" << LL_ENDL;
|
||||
}
|
||||
|
||||
return saved;
|
||||
}
|
||||
|
||||
void LLPresetsManager::setPresetNamesInComboBox(const std::string& subdirectory, LLComboBox* combo, EDefaultOptions default_option)
|
||||
{
|
||||
combo->clearRows();
|
||||
|
||||
std::string presets_dir = getPresetsDir(subdirectory);
|
||||
|
||||
if (!presets_dir.empty())
|
||||
else
|
||||
{
|
||||
std::list<std::string> preset_names;
|
||||
loadPresetNamesFromDir(presets_dir, preset_names, default_option);
|
||||
LL_ERRS() << "Invalid presets directory '" << subdirectory << "'" << LL_ENDL;
|
||||
}
|
||||
|
||||
// make an empty llsd
|
||||
LLSD paramsData(LLSD::emptyMap());
|
||||
|
||||
std::string preset_graphic_active = gSavedSettings.getString("PresetGraphicActive");
|
||||
|
||||
if (preset_names.begin() != preset_names.end())
|
||||
// Create a default graphics preset from hw recommended settings
|
||||
if (IS_GRAPHIC && createDefault && name == PRESETS_DEFAULT)
|
||||
{
|
||||
paramsData = LLFeatureManager::getInstance()->getRecommendedSettingsMap();
|
||||
if (gSavedSettings.getU32("RenderAvatarMaxComplexity") == 0)
|
||||
{
|
||||
for (std::list<std::string>::const_iterator it = preset_names.begin(); it != preset_names.end(); ++it)
|
||||
// use the recommended setting as an initial one (MAINT-6435)
|
||||
gSavedSettings.setU32("RenderAvatarMaxComplexity", paramsData["RenderAvatarMaxComplexity"]["Value"].asInteger());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ECameraPreset new_camera_preset = (ECameraPreset)gSavedSettings.getU32("CameraPresetType");
|
||||
bool new_camera_offsets = false;
|
||||
if (IS_CAMERA)
|
||||
{
|
||||
if (isDefaultCameraPreset(name))
|
||||
{
|
||||
const std::string& name = *it;
|
||||
combo->add(name, LLSD().with(0, name));
|
||||
if (PRESETS_REAR_VIEW == name)
|
||||
{
|
||||
new_camera_preset = CAMERA_PRESET_REAR_VIEW;
|
||||
}
|
||||
else if (PRESETS_SIDE_VIEW == name)
|
||||
{
|
||||
new_camera_preset = CAMERA_PRESET_GROUP_VIEW;
|
||||
}
|
||||
else if (PRESETS_FRONT_VIEW == name)
|
||||
{
|
||||
new_camera_preset = CAMERA_PRESET_FRONT_VIEW;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
new_camera_preset = CAMERA_PRESET_CUSTOM;
|
||||
}
|
||||
new_camera_offsets = (!isDefaultCameraPreset(name) || (ECameraPreset)gSavedSettings.getU32("CameraPresetType") != new_camera_preset);
|
||||
}
|
||||
for (std::vector<std::string>::iterator it = name_list.begin(); it != name_list.end(); ++it)
|
||||
{
|
||||
std::string ctrl_name = *it;
|
||||
|
||||
LLControlVariable* ctrl = gSavedSettings.getControl(ctrl_name).get();
|
||||
if (ctrl)
|
||||
{
|
||||
std::string comment = ctrl->getComment();
|
||||
std::string type = LLControlGroup::typeEnumToString(ctrl->type());
|
||||
LLSD value = ctrl->getValue();
|
||||
|
||||
paramsData[ctrl_name]["Comment"] = comment;
|
||||
paramsData[ctrl_name]["Persist"] = 1;
|
||||
paramsData[ctrl_name]["Type"] = type;
|
||||
paramsData[ctrl_name]["Value"] = value;
|
||||
}
|
||||
}
|
||||
if (IS_CAMERA)
|
||||
{
|
||||
gSavedSettings.setU32("CameraPresetType", new_camera_preset);
|
||||
}
|
||||
}
|
||||
|
||||
std::string pathName(getPresetsDir(subdirectory) + gDirUtilp->getDirDelimiter() + LLURI::escape(name) + ".xml");
|
||||
|
||||
// If the active preset name is the only thing in the list, don't save the list
|
||||
if (paramsData.size() > 1)
|
||||
{
|
||||
// write to file
|
||||
llofstream presetsXML(pathName.c_str());
|
||||
if (presetsXML.is_open())
|
||||
{
|
||||
LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter();
|
||||
formatter->format(paramsData, presetsXML, LLSDFormatter::OPTIONS_PRETTY);
|
||||
presetsXML.close();
|
||||
saved = true;
|
||||
|
||||
LL_DEBUGS() << "saved preset '" << name << "'; " << paramsData.size() << " parameters" << LL_ENDL;
|
||||
|
||||
if (IS_GRAPHIC)
|
||||
{
|
||||
gSavedSettings.setString("PresetGraphicActive", name);
|
||||
// signal interested parties
|
||||
triggerChangeSignal();
|
||||
}
|
||||
|
||||
if (IS_CAMERA)
|
||||
{
|
||||
gSavedSettings.setString("PresetCameraActive", name);
|
||||
setCameraDirty(false);
|
||||
// signal interested parties
|
||||
triggerChangeCameraSignal();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
combo->setLabel(LLTrans::getString("preset_combo_label"));
|
||||
LL_WARNS("Presets") << "Cannot open for output preset file " << pathName << LL_ENDL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_INFOS() << "No settings available to be saved" << LL_ENDL;
|
||||
}
|
||||
|
||||
return saved;
|
||||
}
|
||||
|
||||
bool LLPresetsManager::setPresetNamesInComboBox(const std::string& subdirectory, LLComboBox* combo, EDefaultOptions default_option)
|
||||
{
|
||||
bool sts = true;
|
||||
|
||||
combo->clearRows();
|
||||
combo->setEnabled(TRUE);
|
||||
|
||||
std::list<std::string> preset_names;
|
||||
loadPresetNamesFromDir(subdirectory, preset_names, default_option);
|
||||
|
||||
if (preset_names.begin() != preset_names.end())
|
||||
{
|
||||
for (std::list<std::string>::const_iterator it = preset_names.begin(); it != preset_names.end(); ++it)
|
||||
{
|
||||
const std::string& name = *it;
|
||||
combo->add(name, name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
combo->setLabel(LLTrans::getString("preset_combo_label"));
|
||||
combo->setEnabled(PRESETS_CAMERA != subdirectory);
|
||||
sts = false;
|
||||
}
|
||||
|
||||
return sts;
|
||||
}
|
||||
|
||||
void LLPresetsManager::loadPreset(const std::string& subdirectory, std::string name)
|
||||
|
|
@ -277,24 +462,32 @@ void LLPresetsManager::loadPreset(const std::string& subdirectory, std::string n
|
|||
|
||||
LL_DEBUGS() << "attempting to load preset '"<<name<<"' from '"<<full_path<<"'" << LL_ENDL;
|
||||
|
||||
mIgnoreChangedSignal = true;
|
||||
if(gSavedSettings.loadFromFile(full_path, false, true) > 0)
|
||||
{
|
||||
mIgnoreChangedSignal = false;
|
||||
if(PRESETS_GRAPHIC == subdirectory)
|
||||
{
|
||||
gSavedSettings.setString("PresetGraphicActive", name);
|
||||
}
|
||||
|
||||
LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
|
||||
if (instance)
|
||||
{
|
||||
instance->refreshEnabledGraphics();
|
||||
LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
|
||||
if (instance)
|
||||
{
|
||||
instance->refreshEnabledGraphics();
|
||||
}
|
||||
triggerChangeSignal();
|
||||
}
|
||||
if(PRESETS_CAMERA == subdirectory)
|
||||
{
|
||||
gSavedSettings.setString("PresetCameraActive", name);
|
||||
triggerChangeCameraSignal();
|
||||
}
|
||||
triggerChangeSignal();
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS() << "failed to load preset '"<<name<<"' from '"<<full_path<<"'" << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
mIgnoreChangedSignal = false;
|
||||
LL_WARNS("Presets") << "failed to load preset '"<<name<<"' from '"<<full_path<<"'" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
bool LLPresetsManager::deletePreset(const std::string& subdirectory, std::string name)
|
||||
|
|
@ -320,17 +513,70 @@ bool LLPresetsManager::deletePreset(const std::string& subdirectory, std::string
|
|||
}
|
||||
|
||||
// If you delete the preset that is currently marked as loaded then also indicate that no preset is loaded.
|
||||
if (gSavedSettings.getString("PresetGraphicActive") == name)
|
||||
if(PRESETS_GRAPHIC == subdirectory)
|
||||
{
|
||||
gSavedSettings.setString("PresetGraphicActive", "");
|
||||
if (gSavedSettings.getString("PresetGraphicActive") == name)
|
||||
{
|
||||
gSavedSettings.setString("PresetGraphicActive", "");
|
||||
}
|
||||
// signal interested parties
|
||||
triggerChangeSignal();
|
||||
}
|
||||
|
||||
// signal interested parties
|
||||
triggerChangeSignal();
|
||||
if(PRESETS_CAMERA == subdirectory)
|
||||
{
|
||||
if (gSavedSettings.getString("PresetCameraActive") == name)
|
||||
{
|
||||
gSavedSettings.setString("PresetCameraActive", "");
|
||||
}
|
||||
// signal interested parties
|
||||
triggerChangeCameraSignal();
|
||||
}
|
||||
|
||||
return sts;
|
||||
}
|
||||
|
||||
bool LLPresetsManager::isDefaultCameraPreset(std::string preset_name)
|
||||
{
|
||||
return (preset_name == PRESETS_REAR_VIEW || preset_name == PRESETS_SIDE_VIEW || preset_name == PRESETS_FRONT_VIEW);
|
||||
}
|
||||
|
||||
bool LLPresetsManager::isTemplateCameraPreset(std::string preset_name)
|
||||
{
|
||||
return (preset_name == PRESETS_REAR || preset_name == PRESETS_SIDE || preset_name == PRESETS_FRONT);
|
||||
}
|
||||
|
||||
void LLPresetsManager::resetCameraPreset(std::string preset_name)
|
||||
{
|
||||
if (isDefaultCameraPreset(preset_name))
|
||||
{
|
||||
createDefaultCameraPreset(preset_name, true);
|
||||
|
||||
if (gSavedSettings.getString("PresetCameraActive") == preset_name)
|
||||
{
|
||||
loadPreset(PRESETS_CAMERA, preset_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool LLPresetsManager::createDefaultCameraPreset(std::string preset_name, bool force_reset)
|
||||
{
|
||||
std::string preset_file = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PRESETS_DIR,
|
||||
PRESETS_CAMERA, LLURI::escape(preset_name) + ".xml");
|
||||
if (!gDirUtilp->fileExists(preset_file) || force_reset)
|
||||
{
|
||||
std::string template_name = preset_name.substr(0, preset_name.size() - PRESETS_VIEW_SUFFIX.size());
|
||||
std::string default_template_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, PRESETS_CAMERA, template_name + ".xml");
|
||||
return LLFile::copy(default_template_file, preset_file);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
boost::signals2::connection LLPresetsManager::setPresetListChangeCameraCallback(const preset_list_signal_t::slot_type& cb)
|
||||
{
|
||||
return mPresetListChangeCameraSignal.connect(cb);
|
||||
}
|
||||
|
||||
boost::signals2::connection LLPresetsManager::setPresetListChangeCallback(const preset_list_signal_t::slot_type& cb)
|
||||
{
|
||||
return mPresetListChangeSignal.connect(cb);
|
||||
|
|
|
|||
|
|
@ -36,11 +36,19 @@ static const std::string PRESETS_DEFAULT = "Default";
|
|||
static const std::string PRESETS_DIR = "presets";
|
||||
static const std::string PRESETS_GRAPHIC = "graphic";
|
||||
static const std::string PRESETS_CAMERA = "camera";
|
||||
static const std::string PRESETS_REAR = "Rear";
|
||||
static const std::string PRESETS_FRONT = "Front";
|
||||
static const std::string PRESETS_SIDE = "Side";
|
||||
static const std::string PRESETS_VIEW_SUFFIX = " View";
|
||||
static const std::string PRESETS_REAR_VIEW = PRESETS_REAR + PRESETS_VIEW_SUFFIX;
|
||||
static const std::string PRESETS_FRONT_VIEW = PRESETS_FRONT + PRESETS_VIEW_SUFFIX;
|
||||
static const std::string PRESETS_SIDE_VIEW = PRESETS_SIDE + PRESETS_VIEW_SUFFIX;
|
||||
|
||||
enum EDefaultOptions
|
||||
{
|
||||
DEFAULT_SHOW,
|
||||
DEFAULT_TOP,
|
||||
DEFAULT_BOTTOM,
|
||||
DEFAULT_HIDE // Do not display "Default" in a list
|
||||
};
|
||||
|
||||
|
|
@ -54,26 +62,47 @@ public:
|
|||
typedef std::list<std::string> preset_name_list_t;
|
||||
typedef boost::signals2::signal<void()> preset_list_signal_t;
|
||||
|
||||
void createMissingDefault();
|
||||
void createMissingDefault(const std::string& subdirectory);
|
||||
void startWatching(const std::string& subdirectory);
|
||||
void triggerChangeCameraSignal();
|
||||
void triggerChangeSignal();
|
||||
static std::string getPresetsDir(const std::string& subdirectory);
|
||||
void setPresetNamesInComboBox(const std::string& subdirectory, LLComboBox* combo, EDefaultOptions default_option);
|
||||
void loadPresetNamesFromDir(const std::string& dir, preset_name_list_t& presets, EDefaultOptions default_option);
|
||||
bool setPresetNamesInComboBox(const std::string& subdirectory, LLComboBox* combo, EDefaultOptions default_option);
|
||||
void loadPresetNamesFromDir(const std::string& subdirectory, preset_name_list_t& presets, EDefaultOptions default_option);
|
||||
bool savePreset(const std::string& subdirectory, std::string name, bool createDefault = false);
|
||||
void loadPreset(const std::string& subdirectory, std::string name);
|
||||
bool deletePreset(const std::string& subdirectory, std::string name);
|
||||
bool isCameraDirty();
|
||||
static void setCameraDirty(bool dirty);
|
||||
|
||||
void createCameraDefaultPresets();
|
||||
|
||||
bool isTemplateCameraPreset(std::string preset_name);
|
||||
bool isDefaultCameraPreset(std::string preset_name);
|
||||
void resetCameraPreset(std::string preset_name);
|
||||
bool createDefaultCameraPreset(std::string preset_name, bool force_reset = false);
|
||||
|
||||
// Emitted when a preset gets loaded, deleted, or saved.
|
||||
boost::signals2::connection setPresetListChangeCameraCallback(const preset_list_signal_t::slot_type& cb);
|
||||
boost::signals2::connection setPresetListChangeCallback(const preset_list_signal_t::slot_type& cb);
|
||||
|
||||
// Emitted when a preset gets loaded or saved.
|
||||
|
||||
preset_name_list_t mPresetNames;
|
||||
|
||||
preset_list_signal_t mPresetListChangeCameraSignal;
|
||||
preset_list_signal_t mPresetListChangeSignal;
|
||||
|
||||
private:
|
||||
LOG_CLASS(LLPresetsManager);
|
||||
LOG_CLASS(LLPresetsManager);
|
||||
|
||||
void getControlNames(std::vector<std::string>& names);
|
||||
static void settingChanged();
|
||||
|
||||
boost::signals2::connection mCameraChangedSignal;
|
||||
|
||||
static bool mCameraDirty;
|
||||
static bool mIgnoreChangedSignal;
|
||||
};
|
||||
|
||||
#endif // LL_PRESETSMANAGER_H
|
||||
|
|
|
|||
|
|
@ -229,6 +229,33 @@ void LLProgressView::drawStartTexture(F32 alpha)
|
|||
gGL.popMatrix();
|
||||
}
|
||||
|
||||
void LLProgressView::drawLogos(F32 alpha)
|
||||
{
|
||||
if (mLogosList.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// logos are tied to label,
|
||||
// due to potential resizes we have to figure offsets out on draw or resize
|
||||
LLTextBox *logos_label = getChild<LLTextBox>("logos_lbl");
|
||||
S32 offset_x, offset_y;
|
||||
logos_label->localPointToScreen(0, 0, &offset_x, &offset_y);
|
||||
std::vector<TextureData>::const_iterator iter = mLogosList.begin();
|
||||
std::vector<TextureData>::const_iterator end = mLogosList.end();
|
||||
for (; iter != end; iter++)
|
||||
{
|
||||
gl_draw_scaled_image_with_border(iter->mDrawRect.mLeft + offset_x,
|
||||
iter->mDrawRect.mBottom + offset_y,
|
||||
iter->mDrawRect.getWidth(),
|
||||
iter->mDrawRect.getHeight(),
|
||||
iter->mTexturep.get(),
|
||||
UI_VERTEX_COLOR % alpha,
|
||||
FALSE,
|
||||
iter->mClipRect,
|
||||
iter->mOffsetRect);
|
||||
}
|
||||
}
|
||||
|
||||
void LLProgressView::draw()
|
||||
{
|
||||
|
|
@ -245,6 +272,7 @@ void LLProgressView::draw()
|
|||
}
|
||||
|
||||
LLPanel::draw();
|
||||
drawLogos(alpha);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -257,6 +285,7 @@ void LLProgressView::draw()
|
|||
|
||||
drawStartTexture(alpha);
|
||||
LLPanel::draw();
|
||||
drawLogos(alpha);
|
||||
|
||||
// faded out completely - remove panel and reveal world
|
||||
if (mFadeToWorldTimer.getElapsedTimeF32() > FADE_TO_WORLD_TIME )
|
||||
|
|
@ -283,7 +312,7 @@ void LLProgressView::draw()
|
|||
// FIXME: this causes a crash that i haven't been able to fix
|
||||
mMediaCtrl->unloadMediaSource();
|
||||
|
||||
gStartTexture = NULL;
|
||||
releaseTextures();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
@ -291,6 +320,7 @@ void LLProgressView::draw()
|
|||
drawStartTexture(1.0f);
|
||||
// draw children
|
||||
LLPanel::draw();
|
||||
drawLogos(1.0f);
|
||||
}
|
||||
|
||||
void LLProgressView::setText(const std::string& text)
|
||||
|
|
@ -309,6 +339,196 @@ void LLProgressView::setMessage(const std::string& msg)
|
|||
getChild<LLUICtrl>("message_text")->setValue(mMessage);
|
||||
}
|
||||
|
||||
void LLProgressView::loadLogo(const std::string &path,
|
||||
const U8 image_codec,
|
||||
const LLRect &pos_rect,
|
||||
const LLRectf &clip_rect,
|
||||
const LLRectf &offset_rect)
|
||||
{
|
||||
// We need these images very early, so we have to force-load them, otherwise they might not load in time.
|
||||
if (!gDirUtilp->fileExists(path))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LLPointer<LLImageFormatted> start_image_frmted = LLImageFormatted::createFromType(image_codec);
|
||||
if (!start_image_frmted->load(path))
|
||||
{
|
||||
LL_WARNS("AppInit") << "Image load failed: " << path << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
LLPointer<LLImageRaw> raw = new LLImageRaw;
|
||||
if (!start_image_frmted->decode(raw, 0.0f))
|
||||
{
|
||||
LL_WARNS("AppInit") << "Image decode failed " << path << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
// HACK: getLocalTexture allows only power of two dimentions
|
||||
raw->expandToPowerOfTwo();
|
||||
|
||||
TextureData data;
|
||||
data.mTexturep = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE);
|
||||
data.mDrawRect = pos_rect;
|
||||
data.mClipRect = clip_rect;
|
||||
data.mOffsetRect = offset_rect;
|
||||
mLogosList.push_back(data);
|
||||
}
|
||||
|
||||
void LLProgressView::initLogos()
|
||||
{
|
||||
mLogosList.clear();
|
||||
|
||||
const U8 image_codec = IMG_CODEC_PNG;
|
||||
const LLRectf default_clip(0.f, 1.f, 1.f, 0.f);
|
||||
const S32 default_height = 28;
|
||||
const S32 default_pad = 15;
|
||||
|
||||
S32 icon_width, icon_height;
|
||||
|
||||
// We don't know final screen rect yet, so we can't precalculate position fully
|
||||
LLTextBox *logos_label = getChild<LLTextBox>("logos_lbl");
|
||||
S32 texture_start_x = logos_label->getFont()->getWidthF32(logos_label->getText()) + default_pad;
|
||||
S32 texture_start_y = -7;
|
||||
|
||||
// Normally we would just preload these textures from textures.xml,
|
||||
// and display them via icon control, but they are only needed on
|
||||
// startup and preloaded/UI ones stay forever
|
||||
// (and this code was done already so simply reused it)
|
||||
std::string temp_str = gDirUtilp->getExpandedFilename(LL_PATH_DEFAULT_SKIN, "textures", "3p_icons");
|
||||
|
||||
temp_str += gDirUtilp->getDirDelimiter();
|
||||
|
||||
#ifdef LL_FMODSTUDIO
|
||||
// original image size is 264x96, it is on longer side but
|
||||
// with no internal paddings so it gets additional padding
|
||||
icon_width = 77;
|
||||
icon_height = 21;
|
||||
S32 pad_y = 4;
|
||||
texture_start_x++;
|
||||
loadLogo(temp_str + "fmod_logo.png",
|
||||
image_codec,
|
||||
LLRect(texture_start_x, texture_start_y + pad_y + icon_height, texture_start_x + icon_width, texture_start_y + pad_y),
|
||||
default_clip,
|
||||
default_clip);
|
||||
|
||||
texture_start_x += icon_width + default_pad + 1;
|
||||
#endif
|
||||
// original image size is 342x113, central element is on a larger side
|
||||
// plus internal padding, so it gets slightly more height than desired 32
|
||||
icon_width = 88;
|
||||
icon_height = 29;
|
||||
pad_y = -1;
|
||||
loadLogo(temp_str + "havok_logo.png",
|
||||
image_codec,
|
||||
LLRect(texture_start_x, texture_start_y + pad_y + icon_height, texture_start_x + icon_width, texture_start_y + pad_y),
|
||||
default_clip,
|
||||
default_clip);
|
||||
|
||||
texture_start_x += icon_width + default_pad;
|
||||
|
||||
// 108x41
|
||||
icon_width = 74;
|
||||
loadLogo(temp_str + "vivox_logo.png",
|
||||
image_codec,
|
||||
LLRect(texture_start_x, texture_start_y + default_height, texture_start_x + icon_width, texture_start_y),
|
||||
default_clip,
|
||||
default_clip);
|
||||
}
|
||||
|
||||
void LLProgressView::initStartTexture(S32 location_id, bool is_in_production)
|
||||
{
|
||||
if (gStartTexture.notNull())
|
||||
{
|
||||
gStartTexture = NULL;
|
||||
LL_INFOS("AppInit") << "re-initializing start screen" << LL_ENDL;
|
||||
}
|
||||
|
||||
LL_DEBUGS("AppInit") << "Loading startup bitmap..." << LL_ENDL;
|
||||
|
||||
U8 image_codec = IMG_CODEC_PNG;
|
||||
std::string temp_str = gDirUtilp->getLindenUserDir() + gDirUtilp->getDirDelimiter();
|
||||
|
||||
if ((S32)START_LOCATION_ID_LAST == location_id)
|
||||
{
|
||||
temp_str += LLStartUp::getScreenLastFilename();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string path = temp_str + LLStartUp::getScreenHomeFilename();
|
||||
|
||||
if (!gDirUtilp->fileExists(path) && is_in_production)
|
||||
{
|
||||
// Fallback to old file, can be removed later
|
||||
// Home image only sets when user changes home, so it will take time for users to switch to pngs
|
||||
temp_str += "screen_home.bmp";
|
||||
image_codec = IMG_CODEC_BMP;
|
||||
}
|
||||
else
|
||||
{
|
||||
temp_str = path;
|
||||
}
|
||||
}
|
||||
|
||||
LLPointer<LLImageFormatted> start_image_frmted = LLImageFormatted::createFromType(image_codec);
|
||||
|
||||
// Turn off start screen to get around the occasional readback
|
||||
// driver bug
|
||||
if (!gSavedSettings.getBOOL("UseStartScreen"))
|
||||
{
|
||||
LL_INFOS("AppInit") << "Bitmap load disabled" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
else if (!start_image_frmted->load(temp_str))
|
||||
{
|
||||
LL_WARNS("AppInit") << "Bitmap load failed" << LL_ENDL;
|
||||
gStartTexture = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
gStartImageWidth = start_image_frmted->getWidth();
|
||||
gStartImageHeight = start_image_frmted->getHeight();
|
||||
|
||||
LLPointer<LLImageRaw> raw = new LLImageRaw;
|
||||
if (!start_image_frmted->decode(raw, 0.0f))
|
||||
{
|
||||
LL_WARNS("AppInit") << "Bitmap decode failed" << LL_ENDL;
|
||||
gStartTexture = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
// HACK: getLocalTexture allows only power of two dimentions
|
||||
raw->expandToPowerOfTwo();
|
||||
gStartTexture = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
if (gStartTexture.isNull())
|
||||
{
|
||||
gStartTexture = LLViewerTexture::sBlackImagep;
|
||||
gStartImageWidth = gStartTexture->getWidth();
|
||||
gStartImageHeight = gStartTexture->getHeight();
|
||||
}
|
||||
}
|
||||
|
||||
void LLProgressView::initTextures(S32 location_id, bool is_in_production)
|
||||
{
|
||||
initStartTexture(location_id, is_in_production);
|
||||
initLogos();
|
||||
|
||||
childSetVisible("panel_icons", mLogosList.empty() ? FALSE : TRUE);
|
||||
childSetVisible("panel_top_spacer", mLogosList.empty() ? TRUE : FALSE);
|
||||
}
|
||||
|
||||
void LLProgressView::releaseTextures()
|
||||
{
|
||||
gStartTexture = NULL;
|
||||
mLogosList.clear();
|
||||
|
||||
childSetVisible("panel_top_spacer", TRUE);
|
||||
childSetVisible("panel_icons", FALSE);
|
||||
}
|
||||
|
||||
void LLProgressView::setCancelButtonVisible(BOOL b, const std::string& label)
|
||||
{
|
||||
mCancelBtn->setVisible( b );
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
class LLImageRaw;
|
||||
class LLButton;
|
||||
class LLProgressBar;
|
||||
class LLViewerTexture;
|
||||
|
||||
class LLProgressView :
|
||||
public LLPanel,
|
||||
|
|
@ -51,6 +52,7 @@ public:
|
|||
|
||||
/*virtual*/ void draw();
|
||||
void drawStartTexture(F32 alpha);
|
||||
void drawLogos(F32 alpha);
|
||||
|
||||
/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
|
||||
/*virtual*/ BOOL handleKeyHere(KEY key, MASK mask);
|
||||
|
|
@ -70,6 +72,10 @@ public:
|
|||
|
||||
void setStartupComplete();
|
||||
|
||||
// we have to preload local textures to make sure they won't be grey
|
||||
void initTextures(S32 location_id, bool is_in_production);
|
||||
void releaseTextures();
|
||||
|
||||
void setCancelButtonVisible(BOOL b, const std::string& label);
|
||||
|
||||
static void onCancelButtonClicked( void* );
|
||||
|
|
@ -95,6 +101,25 @@ protected:
|
|||
|
||||
bool handleUpdate(const LLSD& event_data);
|
||||
static void onIdle(void* user_data);
|
||||
void loadLogo(const std::string &path, const U8 image_codec, const LLRect &pos_rect, const LLRectf &clip_rect, const LLRectf &offset_rect);
|
||||
// logos have unusual location and need to be preloaded to not appear grey, then deleted
|
||||
void initLogos();
|
||||
// Loads a bitmap to display during load
|
||||
void initStartTexture(S32 location_id, bool is_in_production);
|
||||
|
||||
private:
|
||||
// We need to draw textures on login, but only once.
|
||||
// So this vector gets filled up for textures to render and gets cleaned later
|
||||
// Some textures have unusual requirements, so we are rendering directly
|
||||
class TextureData
|
||||
{
|
||||
public:
|
||||
LLPointer<LLViewerTexture> mTexturep;
|
||||
LLRect mDrawRect;
|
||||
LLRectf mClipRect;
|
||||
LLRectf mOffsetRect;
|
||||
};
|
||||
std::vector<TextureData> mLogosList;
|
||||
};
|
||||
|
||||
#endif // LL_LLPROGRESSVIEW_H
|
||||
|
|
|
|||
|
|
@ -39,8 +39,8 @@
|
|||
#include "llviewermedia_streamingaudio.h"
|
||||
#include "llaudioengine.h"
|
||||
|
||||
#ifdef LL_FMODEX
|
||||
# include "llaudioengine_fmodex.h"
|
||||
#ifdef LL_FMODSTUDIO
|
||||
# include "llaudioengine_fmodstudio.h"
|
||||
#endif
|
||||
|
||||
#ifdef LL_OPENAL
|
||||
|
|
@ -71,6 +71,7 @@
|
|||
#include "llnotifications.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llpersistentnotificationstorage.h"
|
||||
#include "llpresetsmanager.h"
|
||||
#include "llteleporthistory.h"
|
||||
#include "llregionhandle.h"
|
||||
#include "llsd.h"
|
||||
|
|
@ -625,13 +626,13 @@ bool idle_startup()
|
|||
delete gAudiop;
|
||||
gAudiop = NULL;
|
||||
|
||||
#ifdef LL_FMODEX
|
||||
#ifdef LL_FMODSTUDIO
|
||||
#if !LL_WINDOWS
|
||||
if (NULL == getenv("LL_BAD_FMODEX_DRIVER"))
|
||||
if (NULL == getenv("LL_BAD_FMODSTUDIO_DRIVER"))
|
||||
#endif // !LL_WINDOWS
|
||||
{
|
||||
gAudiop = (LLAudioEngine *) new LLAudioEngine_FMODEX(gSavedSettings.getBOOL("FMODExProfilerEnable"));
|
||||
}
|
||||
{
|
||||
gAudiop = (LLAudioEngine *) new LLAudioEngine_FMODSTUDIO(gSavedSettings.getBOOL("FMODExProfilerEnable"));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef LL_OPENAL
|
||||
|
|
@ -652,7 +653,7 @@ bool idle_startup()
|
|||
#else
|
||||
void* window_handle = NULL;
|
||||
#endif
|
||||
bool init = gAudiop->init(kAUDIO_NUM_SOURCES, window_handle);
|
||||
bool init = gAudiop->init(kAUDIO_NUM_SOURCES, window_handle, LLAppViewer::instance()->getSecondLifeTitle());
|
||||
if(init)
|
||||
{
|
||||
gAudiop->setMuted(TRUE);
|
||||
|
|
@ -1018,9 +1019,8 @@ bool idle_startup()
|
|||
|
||||
gViewerWindow->getWindow()->setCursor(UI_CURSOR_WAIT);
|
||||
|
||||
init_start_screen(agent_location_id);
|
||||
|
||||
// Display the startup progress bar.
|
||||
gViewerWindow->initTextures(agent_location_id);
|
||||
gViewerWindow->setShowProgress(TRUE);
|
||||
gViewerWindow->setProgressCancelButtonVisible(TRUE, LLTrans::getString("Quit"));
|
||||
|
||||
|
|
@ -1998,6 +1998,8 @@ bool idle_startup()
|
|||
// JC - 7/20/2002
|
||||
gViewerWindow->sendShapeToSim();
|
||||
|
||||
LLPresetsManager::getInstance()->createMissingDefault(PRESETS_CAMERA);
|
||||
|
||||
// The reason we show the alert is because we want to
|
||||
// reduce confusion for when you log in and your provided
|
||||
// location is not your expected location. So, if this is
|
||||
|
|
@ -2747,81 +2749,6 @@ std::string LLStartUp::getUserId()
|
|||
return gUserCredential->userID();
|
||||
}
|
||||
|
||||
// Loads a bitmap to display during load
|
||||
void init_start_screen(S32 location_id)
|
||||
{
|
||||
if (gStartTexture.notNull())
|
||||
{
|
||||
gStartTexture = NULL;
|
||||
LL_INFOS("AppInit") << "re-initializing start screen" << LL_ENDL;
|
||||
}
|
||||
|
||||
LL_DEBUGS("AppInit") << "Loading startup bitmap..." << LL_ENDL;
|
||||
|
||||
U8 image_codec = IMG_CODEC_PNG;
|
||||
std::string temp_str = gDirUtilp->getLindenUserDir() + gDirUtilp->getDirDelimiter();
|
||||
|
||||
if ((S32)START_LOCATION_ID_LAST == location_id)
|
||||
{
|
||||
temp_str += LLStartUp::getScreenLastFilename();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string path = temp_str + LLStartUp::getScreenHomeFilename();
|
||||
|
||||
if (!gDirUtilp->fileExists(path) && LLGridManager::getInstance()->isInProductionGrid())
|
||||
{
|
||||
// Fallback to old file, can be removed later
|
||||
// Home image only sets when user changes home, so it will take time for users to switch to pngs
|
||||
temp_str += "screen_home.bmp";
|
||||
image_codec = IMG_CODEC_BMP;
|
||||
}
|
||||
else
|
||||
{
|
||||
temp_str = path;
|
||||
}
|
||||
}
|
||||
|
||||
LLPointer<LLImageFormatted> start_image_frmted = LLImageFormatted::createFromType(image_codec);
|
||||
|
||||
// Turn off start screen to get around the occasional readback
|
||||
// driver bug
|
||||
if(!gSavedSettings.getBOOL("UseStartScreen"))
|
||||
{
|
||||
LL_INFOS("AppInit") << "Bitmap load disabled" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
else if(!start_image_frmted->load(temp_str) )
|
||||
{
|
||||
LL_WARNS("AppInit") << "Bitmap load failed" << LL_ENDL;
|
||||
gStartTexture = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
gStartImageWidth = start_image_frmted->getWidth();
|
||||
gStartImageHeight = start_image_frmted->getHeight();
|
||||
|
||||
LLPointer<LLImageRaw> raw = new LLImageRaw;
|
||||
if (!start_image_frmted->decode(raw, 0.0f))
|
||||
{
|
||||
LL_WARNS("AppInit") << "Bitmap decode failed" << LL_ENDL;
|
||||
gStartTexture = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
raw->expandToPowerOfTwo();
|
||||
gStartTexture = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE) ;
|
||||
}
|
||||
}
|
||||
|
||||
if(gStartTexture.isNull())
|
||||
{
|
||||
gStartTexture = LLViewerTexture::sBlackImagep ;
|
||||
gStartImageWidth = gStartTexture->getWidth() ;
|
||||
gStartImageHeight = gStartTexture->getHeight() ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// frees the bitmap
|
||||
void release_start_screen()
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
#include "llfloaterbuycurrency.h"
|
||||
#include "llbuycurrencyhtml.h"
|
||||
#include "llpanelnearbymedia.h"
|
||||
#include "llpanelpresetscamerapulldown.h"
|
||||
#include "llpanelpresetspulldown.h"
|
||||
#include "llpanelvolumepulldown.h"
|
||||
#include "llfloaterregioninfo.h"
|
||||
|
|
@ -171,8 +172,11 @@ BOOL LLStatusBar::postBuild()
|
|||
mBoxBalance = getChild<LLTextBox>("balance");
|
||||
mBoxBalance->setClickedCallback( &LLStatusBar::onClickBalance, this );
|
||||
|
||||
mIconPresets = getChild<LLIconCtrl>( "presets_icon" );
|
||||
mIconPresets->setMouseEnterCallback(boost::bind(&LLStatusBar::onMouseEnterPresets, this));
|
||||
mIconPresetsCamera = getChild<LLIconCtrl>( "presets_icon_camera" );
|
||||
mIconPresetsCamera->setMouseEnterCallback(boost::bind(&LLStatusBar::onMouseEnterPresetsCamera, this));
|
||||
|
||||
mIconPresetsGraphic = getChild<LLIconCtrl>( "presets_icon_graphic" );
|
||||
mIconPresetsGraphic->setMouseEnterCallback(boost::bind(&LLStatusBar::onMouseEnterPresets, this));
|
||||
|
||||
mBtnVolume = getChild<LLButton>( "volume_btn" );
|
||||
mBtnVolume->setClickedCallback( onClickVolume, this );
|
||||
|
|
@ -227,6 +231,11 @@ BOOL LLStatusBar::postBuild()
|
|||
mSGPacketLoss = LLUICtrlFactory::create<LLStatGraph>(pgp);
|
||||
addChild(mSGPacketLoss);
|
||||
|
||||
mPanelPresetsCameraPulldown = new LLPanelPresetsCameraPulldown();
|
||||
addChild(mPanelPresetsCameraPulldown);
|
||||
mPanelPresetsCameraPulldown->setFollows(FOLLOWS_TOP|FOLLOWS_RIGHT);
|
||||
mPanelPresetsCameraPulldown->setVisible(FALSE);
|
||||
|
||||
mPanelPresetsPulldown = new LLPanelPresetsPulldown();
|
||||
addChild(mPanelPresetsPulldown);
|
||||
mPanelPresetsPulldown->setFollows(FOLLOWS_TOP|FOLLOWS_RIGHT);
|
||||
|
|
@ -343,7 +352,8 @@ void LLStatusBar::setVisibleForMouselook(bool visible)
|
|||
mSGPacketLoss->setVisible(visible);
|
||||
mSearchPanel->setVisible(visible && gSavedSettings.getBOOL("MenuSearch"));
|
||||
setBackgroundVisible(visible);
|
||||
mIconPresets->setVisible(visible);
|
||||
mIconPresetsCamera->setVisible(visible);
|
||||
mIconPresetsGraphic->setVisible(visible);
|
||||
}
|
||||
|
||||
void LLStatusBar::debitBalance(S32 debit)
|
||||
|
|
@ -484,10 +494,34 @@ void LLStatusBar::onClickBuyCurrency()
|
|||
LLFirstUse::receiveLindens(false);
|
||||
}
|
||||
|
||||
void LLStatusBar::onMouseEnterPresetsCamera()
|
||||
{
|
||||
LLView* popup_holder = gViewerWindow->getRootView()->getChildView("popup_holder");
|
||||
LLIconCtrl* icon = getChild<LLIconCtrl>( "presets_icon_camera" );
|
||||
LLRect icon_rect = icon->getRect();
|
||||
LLRect pulldown_rect = mPanelPresetsCameraPulldown->getRect();
|
||||
pulldown_rect.setLeftTopAndSize(icon_rect.mLeft -
|
||||
(pulldown_rect.getWidth() - icon_rect.getWidth()),
|
||||
icon_rect.mBottom,
|
||||
pulldown_rect.getWidth(),
|
||||
pulldown_rect.getHeight());
|
||||
|
||||
pulldown_rect.translate(popup_holder->getRect().getWidth() - pulldown_rect.mRight, 0);
|
||||
mPanelPresetsCameraPulldown->setShape(pulldown_rect);
|
||||
|
||||
// show the master presets pull-down
|
||||
LLUI::getInstance()->clearPopups();
|
||||
LLUI::getInstance()->addPopup(mPanelPresetsCameraPulldown);
|
||||
mPanelNearByMedia->setVisible(FALSE);
|
||||
mPanelVolumePulldown->setVisible(FALSE);
|
||||
mPanelPresetsPulldown->setVisible(FALSE);
|
||||
mPanelPresetsCameraPulldown->setVisible(TRUE);
|
||||
}
|
||||
|
||||
void LLStatusBar::onMouseEnterPresets()
|
||||
{
|
||||
LLView* popup_holder = gViewerWindow->getRootView()->getChildView("popup_holder");
|
||||
LLIconCtrl* icon = getChild<LLIconCtrl>( "presets_icon" );
|
||||
LLIconCtrl* icon = getChild<LLIconCtrl>( "presets_icon_graphic" );
|
||||
LLRect icon_rect = icon->getRect();
|
||||
LLRect pulldown_rect = mPanelPresetsPulldown->getRect();
|
||||
pulldown_rect.setLeftTopAndSize(icon_rect.mLeft -
|
||||
|
|
@ -526,6 +560,7 @@ void LLStatusBar::onMouseEnterVolume()
|
|||
// show the master volume pull-down
|
||||
LLUI::getInstance()->clearPopups();
|
||||
LLUI::getInstance()->addPopup(mPanelVolumePulldown);
|
||||
mPanelPresetsCameraPulldown->setVisible(FALSE);
|
||||
mPanelPresetsPulldown->setVisible(FALSE);
|
||||
mPanelNearByMedia->setVisible(FALSE);
|
||||
mPanelVolumePulldown->setVisible(TRUE);
|
||||
|
|
@ -550,6 +585,7 @@ void LLStatusBar::onMouseEnterNearbyMedia()
|
|||
LLUI::getInstance()->clearPopups();
|
||||
LLUI::getInstance()->addPopup(mPanelNearByMedia);
|
||||
|
||||
mPanelPresetsCameraPulldown->setVisible(FALSE);
|
||||
mPanelPresetsPulldown->setVisible(FALSE);
|
||||
mPanelVolumePulldown->setVisible(FALSE);
|
||||
mPanelNearByMedia->setVisible(TRUE);
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ class LLUICtrl;
|
|||
class LLUUID;
|
||||
class LLFrameTimer;
|
||||
class LLStatGraph;
|
||||
class LLPanelPresetsCameraPulldown;
|
||||
class LLPanelPresetsPulldown;
|
||||
class LLPanelVolumePulldown;
|
||||
class LLPanelNearByMedia;
|
||||
|
|
@ -99,6 +100,7 @@ private:
|
|||
void onClickBuyCurrency();
|
||||
void onVolumeChanged(const LLSD& newvalue);
|
||||
|
||||
void onMouseEnterPresetsCamera();
|
||||
void onMouseEnterPresets();
|
||||
void onMouseEnterVolume();
|
||||
void onMouseEnterNearbyMedia();
|
||||
|
|
@ -123,7 +125,8 @@ private:
|
|||
LLStatGraph *mSGBandwidth;
|
||||
LLStatGraph *mSGPacketLoss;
|
||||
|
||||
LLIconCtrl *mIconPresets;
|
||||
LLIconCtrl *mIconPresetsCamera;
|
||||
LLIconCtrl *mIconPresetsGraphic;
|
||||
LLButton *mBtnVolume;
|
||||
LLTextBox *mBoxBalance;
|
||||
LLButton *mMediaToggle;
|
||||
|
|
@ -135,6 +138,7 @@ private:
|
|||
S32 mSquareMetersCommitted;
|
||||
LLFrameTimer* mBalanceTimer;
|
||||
LLFrameTimer* mHealthTimer;
|
||||
LLPanelPresetsCameraPulldown* mPanelPresetsCameraPulldown;
|
||||
LLPanelPresetsPulldown* mPanelPresetsPulldown;
|
||||
LLPanelVolumePulldown* mPanelVolumePulldown;
|
||||
LLPanelNearByMedia* mPanelNearByMedia;
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@
|
|||
#include "llfloaterbuyland.h"
|
||||
#include "llfloaterbvhpreview.h"
|
||||
#include "llfloatercamera.h"
|
||||
#include "llfloatercamerapresets.h"
|
||||
#include "llfloaterchatvoicevolume.h"
|
||||
#include "llfloaterconversationlog.h"
|
||||
#include "llfloaterconversationpreview.h"
|
||||
|
|
@ -104,12 +105,14 @@
|
|||
#include "llfloaterperms.h"
|
||||
#include "llfloaterpostprocess.h"
|
||||
#include "llfloaterpreference.h"
|
||||
#include "llfloaterpreferenceviewadvanced.h"
|
||||
#include "llfloaterpreviewtrash.h"
|
||||
#include "llfloaterproperties.h"
|
||||
#include "llfloaterregiondebugconsole.h"
|
||||
#include "llfloaterregioninfo.h"
|
||||
#include "llfloaterregionrestarting.h"
|
||||
#include "llfloaterreporter.h"
|
||||
#include "llfloatersavecamerapreset.h"
|
||||
#include "llfloatersaveprefpreset.h"
|
||||
#include "llfloatersceneloadstats.h"
|
||||
#include "llfloaterscriptdebug.h"
|
||||
|
|
@ -214,6 +217,7 @@ void LLViewerFloaterReg::registerFloaters()
|
|||
LLFloaterReg::add("bumps", "floater_bumps.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBump>);
|
||||
|
||||
LLFloaterReg::add("camera", "floater_camera.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCamera>);
|
||||
LLFloaterReg::add("camera_presets", "floater_camera_presets.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCameraPresets>);
|
||||
LLFloaterReg::add("chat_voice", "floater_voice_chat_volume.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterChatVoiceVolume>);
|
||||
LLFloaterReg::add("nearby_chat", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterIMNearbyChat::buildFloater);
|
||||
LLFloaterReg::add("compile_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCompileQueue>);
|
||||
|
|
@ -301,6 +305,7 @@ void LLViewerFloaterReg::registerFloaters()
|
|||
LLFloaterReg::add("places", "floater_places.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>);
|
||||
LLFloaterReg::add("preferences", "floater_preferences.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreference>);
|
||||
LLFloaterReg::add("prefs_graphics_advanced", "floater_preferences_graphics_advanced.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreferenceGraphicsAdvanced>);
|
||||
LLFloaterReg::add("prefs_view_advanced", "floater_preferences_view_advanced.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreferenceViewAdvanced>);
|
||||
LLFloaterReg::add("prefs_proxy", "floater_preferences_proxy.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreferenceProxy>);
|
||||
LLFloaterReg::add("prefs_spellchecker_import", "floater_spellcheck_import.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSpellCheckerImport>);
|
||||
LLFloaterReg::add("prefs_translation", "floater_translation_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTranslationSettings>);
|
||||
|
|
@ -320,6 +325,7 @@ void LLViewerFloaterReg::registerFloaters()
|
|||
LLFloaterReg::add("properties", "floater_inventory_item_properties.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterProperties>);
|
||||
LLFloaterReg::add("publish_classified", "floater_publish_classified.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPublishClassifiedFloater>);
|
||||
LLFloaterReg::add("save_pref_preset", "floater_save_pref_preset.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSavePrefPreset>);
|
||||
LLFloaterReg::add("save_camera_preset", "floater_save_camera_preset.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSaveCameraPreset>);
|
||||
LLFloaterReg::add("script_colors", "floater_script_ed_prefs.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterScriptEdPrefs>);
|
||||
|
||||
LLFloaterReg::add("telehubs", "floater_telehub.xml",&LLFloaterReg::build<LLFloaterTelehub>);
|
||||
|
|
|
|||
|
|
@ -352,6 +352,7 @@ void camera_spin_around_ccw_sitting( EKeystate s )
|
|||
else
|
||||
{
|
||||
//change camera but do not send keystrokes
|
||||
gAgentCamera.unlockView();
|
||||
gAgentCamera.setOrbitLeftKey( get_orbit_rate() );
|
||||
}
|
||||
}
|
||||
|
|
@ -368,6 +369,7 @@ void camera_spin_around_cw_sitting( EKeystate s )
|
|||
else
|
||||
{
|
||||
//change camera but do not send keystrokes
|
||||
gAgentCamera.unlockView();
|
||||
gAgentCamera.setOrbitRightKey( get_orbit_rate() );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4238,8 +4238,7 @@ void handle_reset_view()
|
|||
// switching to outfit selector should automagically save any currently edited wearable
|
||||
LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "my_outfits"));
|
||||
}
|
||||
|
||||
gAgentCamera.switchCameraPreset(CAMERA_PRESET_REAR_VIEW);
|
||||
|
||||
reset_view_final( TRUE );
|
||||
LLFloaterCamera::resetCameraMode();
|
||||
|
||||
|
|
|
|||
|
|
@ -1902,7 +1902,8 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
|
|||
// If there is a new music URL and it's valid, play it.
|
||||
if (music_url.size() > 12)
|
||||
{
|
||||
if (music_url.substr(0, 7) == "http://")
|
||||
if (music_url.substr(0, 7) == "http://"
|
||||
|| music_url.substr(0, 8) == "https://")
|
||||
{
|
||||
LLViewerRegion *region = LLWorld::getInstance()->getRegion(msg->getSender());
|
||||
optionally_start_music(music_url, parcel->mLocalID, region->getRegionID());
|
||||
|
|
|
|||
|
|
@ -5147,6 +5147,14 @@ void LLViewerWindow::revealIntroPanel()
|
|||
}
|
||||
}
|
||||
|
||||
void LLViewerWindow::initTextures(S32 location_id)
|
||||
{
|
||||
if (mProgressView)
|
||||
{
|
||||
mProgressView->initTextures(location_id, LLGridManager::getInstance()->isInProductionGrid());
|
||||
}
|
||||
}
|
||||
|
||||
void LLViewerWindow::setShowProgress(const BOOL show)
|
||||
{
|
||||
if (mProgressView)
|
||||
|
|
@ -5200,7 +5208,6 @@ void LLViewerWindow::setProgressCancelButtonVisible( BOOL b, const std::string&
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
LLProgressView *LLViewerWindow::getProgressView() const
|
||||
{
|
||||
return mProgressView;
|
||||
|
|
|
|||
|
|
@ -303,6 +303,7 @@ public:
|
|||
BOOL getCursorHidden() { return mCursorHidden; }
|
||||
void moveCursorToCenter(); // move to center of window
|
||||
|
||||
void initTextures(S32 location_id);
|
||||
void setShowProgress(const BOOL show);
|
||||
BOOL getShowProgress() const;
|
||||
void setProgressString(const std::string& string);
|
||||
|
|
|
|||
|
|
@ -7463,7 +7463,8 @@ void LLVOAvatar::sitOnObject(LLViewerObject *sit_object)
|
|||
mRoot->updateWorldMatrixChildren();
|
||||
|
||||
stopMotion(ANIM_AGENT_BODY_NOISE);
|
||||
|
||||
|
||||
gAgentCamera.setInitSitRot(gAgent.getFrameAgent().getQuaternion());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 366 B After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 366 B |
|
|
@ -98,7 +98,7 @@ with the same filename but different name
|
|||
<texture name="BuyArrow_Over" file_name="navbar/BuyArrow_Over.png" preload="true" scale.left="0" scale.top="1" scale.right="0" scale.bottom="0" />
|
||||
<texture name="BuyArrow_Press" file_name="navbar/BuyArrow_Press.png" preload="true" scale.left="1" scale.top="1" scale.right="0" scale.bottom="0" />
|
||||
|
||||
<texture name="Cam_Avatar_Off" file_name="bottomtray/Cam_Avatar_Off.png" preload="false" />
|
||||
<texture name="Cam_Avatar_Off" file_name="bottomtray/Cam_Avatar_Off.png" preload="true" />
|
||||
<texture name="Cam_FreeCam_Off" file_name="bottomtray/Cam_FreeCam_Off.png" preload="false" />
|
||||
<texture name="Cam_Orbit_Off" file_name="bottomtray/Cam_Orbit_Off.png" preload="false" />
|
||||
<texture name="Cam_Pan_Off" file_name="bottomtray/Cam_Pan_Off.png" preload="false" />
|
||||
|
|
@ -113,8 +113,10 @@ with the same filename but different name
|
|||
|
||||
<texture name="Cam_Rotate_In" file_name="bottomtray/Cam_Rotate_In.png" preload="false" />
|
||||
<texture name="Cam_Rotate_Out" file_name="bottomtray/Cam_Rotate_Out.png" preload="false" />
|
||||
<texture name="Cam_Rotate_Center" file_name="bottomtray/Cam_Rotate_Center.png" preload="false" />
|
||||
<texture name="Cam_Tracking_In" file_name="bottomtray/Cam_Tracking_In.png" preload="false" />
|
||||
<texture name="Cam_Tracking_Out" file_name="bottomtray/Cam_Tracking_Out.png" preload="false" />
|
||||
<texture name="Cam_Tracking_Center" file_name="bottomtray/Cam_Tracking_Center.png" preload="false" />
|
||||
|
||||
<texture name="Checkbox_Off_Disabled" file_name="widgets/Checkbox_Disabled.png" preload="true" />
|
||||
<texture name="Checkbox_On_Disabled" file_name="widgets/Checkbox_On_Disabled.png" preload="true" />
|
||||
|
|
@ -204,7 +206,9 @@ with the same filename but different name
|
|||
|
||||
<texture name="Presets_Icon" file_name="icons/Presets_Icon.png" preload="true" />
|
||||
|
||||
<texture name="Favorite_Star_Active" file_name="navbar/Favorite_Star_Active.png" preload="false" />
|
||||
<texture name="Presets_Icon" file_name="icons/Presets_Icon.png" preload="true" />
|
||||
<texture name="Presets_Icon_Graphic" file_name="icons/Presets_Icon_Graphic.png" preload="true" />
|
||||
<texture name="Favorite_Star_Active" file_name="navbar/Favorite_Star_Active.png" preload="false" />
|
||||
<texture name="Favorite_Star_Off" file_name="navbar/Favorite_Star_Off.png" preload="false" />
|
||||
<texture name="Favorite_Star_Press" file_name="navbar/Favorite_Star_Press.png" preload="false" />
|
||||
<texture name="Favorite_Star_Over" file_name="navbar/Favorite_Star_Over.png" preload="false" />
|
||||
|
|
@ -253,6 +257,7 @@ with the same filename but different name
|
|||
<texture name="Icon_Gear_Background" file_name="windows/Icon_Gear_Background.png" preload="false" />
|
||||
<texture name="Icon_Gear_Foreground" file_name="windows/Icon_Gear_Foreground.png" preload="false" />
|
||||
<texture name="Icon_Gear_Press" file_name="windows/Icon_Gear_Press.png" preload="false" />
|
||||
<texture name="Icon_Gear" file_name="windows/Icon_Gear.png" preload="false" />
|
||||
|
||||
<texture name="Icon_Help_Foreground" file_name="windows/Icon_Help_Foreground.png" preload="true" />
|
||||
<texture name="Icon_Help_Press" file_name="windows/Icon_Help_Press.png" preload="true" />
|
||||
|
|
@ -492,6 +497,7 @@ with the same filename but different name
|
|||
<texture name="Play_Press" file_name="icons/Play_Press.png" preload="false" />
|
||||
|
||||
<texture name="ProgressBar" file_name="widgets/ProgressBar.png" preload="true" scale.left="4" scale.top="11" scale.right="48" scale.bottom="3" />
|
||||
<texture name="ProgressBarSolid" file_name="widgets/ProgressBarSolid.png" preload="true" scale.left="4" scale.top="11" scale.right="48" scale.bottom="3" />
|
||||
<texture name="ProgressTrack" file_name="widgets/ProgressTrack.png" preload="true" scale.left="4" scale.top="13" scale.right="148" scale.bottom="2" />
|
||||
|
||||
<texture name="PushButton_Disabled" file_name="widgets/PushButton_Disabled.png" preload="true" scale.left="4" scale.top="19" scale.right="28" scale.bottom="4" />
|
||||
|
|
|
|||
|
After Width: | Height: | Size: 208 B |
|
After Width: | Height: | Size: 6.1 KiB |
|
|
@ -7,7 +7,7 @@
|
|||
legacy_header_height="18"
|
||||
can_minimize="true"
|
||||
can_close="true"
|
||||
height="164"
|
||||
height="135"
|
||||
layout="topleft"
|
||||
name="camera_floater"
|
||||
help_topic="camera_floater"
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
title="CAMERA CONTROLS"
|
||||
chrome="true"
|
||||
save_rect="true"
|
||||
width="228">
|
||||
width="400">
|
||||
<floater.string
|
||||
name="rotate_tooltip">
|
||||
Rotate Camera Around Focus
|
||||
|
|
@ -33,6 +33,7 @@
|
|||
name="free_mode_title">
|
||||
View Object
|
||||
</floater.string>
|
||||
<string name="inactive_combo_text">Use preset</string>
|
||||
<panel
|
||||
border="false"
|
||||
height="123"
|
||||
|
|
@ -41,112 +42,18 @@
|
|||
top="0"
|
||||
mouse_opaque="false"
|
||||
name="controls"
|
||||
width="226">
|
||||
<panel
|
||||
follows="all"
|
||||
height="102"
|
||||
layout="topleft"
|
||||
left="8"
|
||||
name="preset_views_list"
|
||||
top="24"
|
||||
width="212"
|
||||
visible="false">
|
||||
<panel_camera_item
|
||||
name="front_view">
|
||||
<panel_camera_item.mousedown_callback
|
||||
function="CameraPresets.ChangeView"
|
||||
parameter="front_view" />
|
||||
<panel_camera_item.picture
|
||||
image_name="Cam_Preset_Front_Off" />
|
||||
<panel_camera_item.selected_picture
|
||||
image_name="Cam_Preset_Front_On" />
|
||||
<panel_camera_item.text
|
||||
name="front_view_text">
|
||||
Front View
|
||||
</panel_camera_item.text>
|
||||
</panel_camera_item>
|
||||
<panel_camera_item
|
||||
name="group_view"
|
||||
top_pad="4">
|
||||
<panel_camera_item.mousedown_callback
|
||||
function="CameraPresets.ChangeView"
|
||||
parameter="group_view" />
|
||||
<panel_camera_item.picture
|
||||
image_name="Cam_Preset_Side_Off" />
|
||||
<panel_camera_item.selected_picture
|
||||
image_name="Cam_Preset_Side_On" />
|
||||
<panel_camera_item.text
|
||||
name="side_view_text">
|
||||
Side View
|
||||
</panel_camera_item.text>
|
||||
</panel_camera_item>
|
||||
<panel_camera_item
|
||||
name="rear_view"
|
||||
layout="topleft"
|
||||
top_pad="4">
|
||||
<panel_camera_item.mousedown_callback
|
||||
function="CameraPresets.ChangeView"
|
||||
parameter="rear_view" />
|
||||
<panel_camera_item.picture
|
||||
image_name="Cam_Preset_Back_Off" />
|
||||
<panel_camera_item.selected_picture
|
||||
image_name="Cam_Preset_Back_On" />
|
||||
<panel_camera_item.text
|
||||
name="rear_view_text">
|
||||
Rear View
|
||||
</panel_camera_item.text>
|
||||
</panel_camera_item>
|
||||
</panel>
|
||||
<panel
|
||||
follows="all"
|
||||
height="68"
|
||||
layout="topleft"
|
||||
left="8"
|
||||
name="camera_modes_list"
|
||||
top="24"
|
||||
width="212"
|
||||
visible="false">
|
||||
<panel_camera_item
|
||||
name="object_view">
|
||||
<panel_camera_item.mousedown_callback
|
||||
function="CameraPresets.ChangeView"
|
||||
parameter="object_view" />
|
||||
<panel_camera_item.text
|
||||
name="object_view_text">
|
||||
Object View
|
||||
</panel_camera_item.text>
|
||||
<panel_camera_item.picture
|
||||
image_name="Object_View_Off" />
|
||||
<panel_camera_item.selected_picture
|
||||
image_name="Object_View_On" />
|
||||
</panel_camera_item>
|
||||
<panel_camera_item
|
||||
name="mouselook_view"
|
||||
layout="topleft">
|
||||
<panel_camera_item.mousedown_callback
|
||||
function="CameraPresets.ChangeView"
|
||||
parameter="mouselook_view" />
|
||||
<panel_camera_item.text
|
||||
name="mouselook_view_text">
|
||||
Mouselook View
|
||||
</panel_camera_item.text>
|
||||
<panel_camera_item.picture
|
||||
image_name="MouseLook_View_Off" />
|
||||
<panel_camera_item.selected_picture
|
||||
image_name="MouseLook_View_On" />
|
||||
</panel_camera_item>
|
||||
</panel>
|
||||
width="220">
|
||||
<!--TODO: replace + - images -->
|
||||
<panel
|
||||
border="false"
|
||||
class="camera_zoom_panel"
|
||||
height="114"
|
||||
height="123"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
mouse_opaque="false"
|
||||
name="zoom"
|
||||
top="20"
|
||||
width="226">
|
||||
top="0"
|
||||
width="220">
|
||||
<joystick_rotate
|
||||
follows="top|left"
|
||||
height="78"
|
||||
|
|
@ -157,8 +64,8 @@
|
|||
sound_flags="3"
|
||||
visible="true"
|
||||
tool_tip="Orbit camera around focus"
|
||||
top="20"
|
||||
width="78" />
|
||||
top="25"
|
||||
width="78" />
|
||||
<button
|
||||
follows="top|left"
|
||||
height="18"
|
||||
|
|
@ -169,7 +76,7 @@
|
|||
left_pad="14"
|
||||
name="zoom_plus_btn"
|
||||
width="18"
|
||||
top="18">
|
||||
top="23">
|
||||
<commit_callback
|
||||
function="Zoom.plus" />
|
||||
<mouse_held_callback
|
||||
|
|
@ -214,56 +121,136 @@
|
|||
scale_image="false"
|
||||
sound_flags="3"
|
||||
tool_tip="Move camera up and down, left and right"
|
||||
top="20"
|
||||
top="25"
|
||||
width="78"/>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="15"
|
||||
layout="topleft"
|
||||
left="41"
|
||||
top_pad="9"
|
||||
name="precise_ctrs_label"
|
||||
width="200">
|
||||
Use precise controls
|
||||
</text>
|
||||
</panel>
|
||||
</panel>
|
||||
<panel
|
||||
border="false"
|
||||
height="42"
|
||||
follows="all"
|
||||
height="102"
|
||||
layout="topleft"
|
||||
left="2"
|
||||
top_pad="0"
|
||||
name="buttons"
|
||||
width="226">
|
||||
<button
|
||||
height="23"
|
||||
label=""
|
||||
layout="topleft"
|
||||
left="70"
|
||||
is_toggle="true"
|
||||
image_overlay="Cam_Avatar_Off"
|
||||
image_selected="PushButton_Selected_Press"
|
||||
name="presets_btn"
|
||||
tab_stop="false"
|
||||
tool_tip="Preset Views"
|
||||
top="13"
|
||||
width="25">
|
||||
</button>
|
||||
<button
|
||||
height="23"
|
||||
label=""
|
||||
layout="topleft"
|
||||
left_pad="1"
|
||||
is_toggle="true"
|
||||
image_overlay="PanOrbit_Off"
|
||||
image_selected="PushButton_Selected_Press"
|
||||
name="pan_btn"
|
||||
tab_stop="false"
|
||||
tool_tip="Orbit Zoom Pan"
|
||||
width="25">
|
||||
</button>
|
||||
<button
|
||||
height="23"
|
||||
label=""
|
||||
layout="topleft"
|
||||
left_pad="1"
|
||||
image_overlay="Cam_FreeCam_Off"
|
||||
image_selected="PushButton_Selected_Press"
|
||||
name="avatarview_btn"
|
||||
tab_stop="false"
|
||||
tool_tip="Camera modes"
|
||||
width="25">
|
||||
</button>
|
||||
</panel>
|
||||
left_pad="2"
|
||||
name="buttons_panel"
|
||||
top="22"
|
||||
width="212">
|
||||
<panel_camera_item
|
||||
name="front_view"
|
||||
tool_tip="Front View"
|
||||
width="30">
|
||||
<panel_camera_item.mousedown_callback
|
||||
function="CameraPresets.ChangeView"
|
||||
parameter="Front View" />
|
||||
<panel_camera_item.picture
|
||||
image_name="Cam_Preset_Front_Off" />
|
||||
<panel_camera_item.selected_picture
|
||||
image_name="Cam_Preset_Front_On" />
|
||||
</panel_camera_item>
|
||||
<panel_camera_item
|
||||
name="group_view"
|
||||
tool_tip="Side View"
|
||||
width="30"
|
||||
left_pad="4">
|
||||
<panel_camera_item.mousedown_callback
|
||||
function="CameraPresets.ChangeView"
|
||||
parameter="Side View" />
|
||||
<panel_camera_item.picture
|
||||
image_name="Cam_Preset_Side_Off" />
|
||||
<panel_camera_item.selected_picture
|
||||
image_name="Cam_Preset_Side_On" />
|
||||
</panel_camera_item>
|
||||
<panel_camera_item
|
||||
name="rear_view"
|
||||
tool_tip="Rear View"
|
||||
width="30"
|
||||
left_pad="4">
|
||||
<panel_camera_item.mousedown_callback
|
||||
function="CameraPresets.ChangeView"
|
||||
tool_tip="Rear View"
|
||||
parameter="Rear View" />
|
||||
<panel_camera_item.picture
|
||||
image_name="Cam_Preset_Back_Off" />
|
||||
<panel_camera_item.selected_picture
|
||||
image_name="Cam_Preset_Back_On" />
|
||||
</panel_camera_item>
|
||||
<panel_camera_item
|
||||
name="object_view"
|
||||
tool_tip="Object View"
|
||||
width="30"
|
||||
left_pad="4">
|
||||
<panel_camera_item.mousedown_callback
|
||||
function="CameraPresets.ChangeView"
|
||||
parameter="object_view" />
|
||||
<panel_camera_item.picture
|
||||
image_name="Object_View_Off" />
|
||||
<panel_camera_item.selected_picture
|
||||
image_name="Object_View_On" />
|
||||
</panel_camera_item>
|
||||
<panel_camera_item
|
||||
name="mouselook_view"
|
||||
tool_tip="Mouselook View"
|
||||
width="30"
|
||||
left_pad="4">
|
||||
<panel_camera_item.mousedown_callback
|
||||
function="CameraPresets.ChangeView"
|
||||
parameter="mouselook_view" />
|
||||
<panel_camera_item.picture
|
||||
image_name="MouseLook_View_Off" />
|
||||
<panel_camera_item.selected_picture
|
||||
image_name="MouseLook_View_On" />
|
||||
</panel_camera_item>
|
||||
<combo_box
|
||||
height="23"
|
||||
left="0"
|
||||
mouse_opaque="true"
|
||||
name="preset_combo"
|
||||
top_pad="10"
|
||||
width="136">
|
||||
<combo_list
|
||||
mouse_wheel_opaque="true"/>
|
||||
<combo_box.item
|
||||
label="Use preset"
|
||||
name="Use preset"
|
||||
value="default" />
|
||||
</combo_box>
|
||||
<button
|
||||
height="16"
|
||||
width="16"
|
||||
layout="topleft"
|
||||
mouse_opaque="true"
|
||||
name="gear_btn"
|
||||
tool_tip="My Camera Presets"
|
||||
top_delta="3"
|
||||
left_pad="10"
|
||||
image_selected="Icon_Gear"
|
||||
image_pressed="Icon_Gear"
|
||||
image_unselected="Icon_Gear"
|
||||
is_toggle="true">
|
||||
<button.commit_callback
|
||||
function="CameraPresets.ShowPresetsList"/>
|
||||
</button>
|
||||
<button
|
||||
follows="top|left"
|
||||
height="25"
|
||||
label="Save as preset..."
|
||||
layout="topleft"
|
||||
left="0"
|
||||
name="save_preset_btn"
|
||||
top_pad="18"
|
||||
width="150">
|
||||
<button.commit_callback
|
||||
function="CameraPresets.Save"/>
|
||||
</button>
|
||||
</panel>
|
||||
</floater>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<floater
|
||||
legacy_header_height="18"
|
||||
can_resize="true"
|
||||
height="200"
|
||||
min_height="150"
|
||||
title="MY CAMERA PRESETS"
|
||||
layout="topleft"
|
||||
name="floater_camera_presets"
|
||||
single_instance="true"
|
||||
min_width="185"
|
||||
width="250">
|
||||
<flat_list_view
|
||||
allow_select="true"
|
||||
follows="all"
|
||||
height="165"
|
||||
layout="topleft"
|
||||
left="3"
|
||||
multi_select="false"
|
||||
name="preset_list"
|
||||
top="20"
|
||||
width="245" />
|
||||
</floater>
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
height="130"
|
||||
help_topic="floater_delete_preset"
|
||||
layout="topleft"
|
||||
name="Delete Pref Preset"
|
||||
name="delete_pref_preset"
|
||||
save_rect="true"
|
||||
title="DELETE PREF PRESET"
|
||||
width="300">
|
||||
|
|
|
|||
|
|
@ -4,18 +4,16 @@
|
|||
legacy_header_height="225"
|
||||
can_minimize="true"
|
||||
can_close="true"
|
||||
can_resize="true"
|
||||
min_height="65"
|
||||
min_width="515"
|
||||
height="65"
|
||||
can_resize="false"
|
||||
height="80"
|
||||
width="515"
|
||||
layout="topleft"
|
||||
name="HoverHeight"
|
||||
single_instance="true"
|
||||
help_topic="hover_height"
|
||||
save_rect="true"
|
||||
save_visibility="true"
|
||||
title="SET HOVER HEIGHT"
|
||||
width="515">
|
||||
title="SET HOVER HEIGHT">
|
||||
<slider
|
||||
enabled="false"
|
||||
control_name="HoverHeightSlider"
|
||||
|
|
@ -34,4 +32,13 @@
|
|||
can_edit_text="true"
|
||||
>
|
||||
</slider>
|
||||
<check_box
|
||||
control_name="HoverHeightAffectsCamera"
|
||||
follows="all"
|
||||
height="15"
|
||||
label="Bind Camera view"
|
||||
layout="topleft"
|
||||
name="BindCameraCheck"
|
||||
top_pad="7"
|
||||
width="237"/>
|
||||
</floater>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<floater
|
||||
legacy_header_height="18"
|
||||
can_minimize="false"
|
||||
height="488"
|
||||
height="466"
|
||||
layout="topleft"
|
||||
name="Inventory Finder"
|
||||
help_topic="inventory_finder"
|
||||
|
|
@ -202,7 +202,7 @@
|
|||
left="8"
|
||||
mouse_opaque="true"
|
||||
name="icon_settings"
|
||||
top="262"
|
||||
top="242"
|
||||
width="16" />
|
||||
<check_box
|
||||
height="16"
|
||||
|
|
@ -220,7 +220,7 @@
|
|||
layout="topleft"
|
||||
left="8"
|
||||
name="All"
|
||||
top="282"
|
||||
top="262"
|
||||
width="100" />
|
||||
<button
|
||||
height="20"
|
||||
|
|
@ -368,6 +368,6 @@
|
|||
layout="topleft"
|
||||
name="Close"
|
||||
right="-6"
|
||||
top="454"
|
||||
top="434"
|
||||
width="76" />
|
||||
</floater>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
height="130"
|
||||
help_topic="floater_load_preset"
|
||||
layout="topleft"
|
||||
name="Load Pref Preset"
|
||||
name="load_pref_preset"
|
||||
save_rect="true"
|
||||
title="LOAD PREF PRESET"
|
||||
width="300">
|
||||
|
|
|
|||
|
|
@ -0,0 +1,156 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<floater
|
||||
height="190"
|
||||
layout="topleft"
|
||||
name="floaterpreferencesviewadvanced"
|
||||
help_topic="floaterviewadvanced"
|
||||
title="CAMERA POSITION"
|
||||
save_rect="true"
|
||||
width="280">
|
||||
|
||||
<text
|
||||
follows="top|left|right"
|
||||
name="camera_offset_lbl"
|
||||
height="16"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
top="10"
|
||||
width="100">
|
||||
Camera offset:
|
||||
</text>
|
||||
|
||||
<spinner
|
||||
height="20"
|
||||
label="X"
|
||||
label_width="12"
|
||||
follows="top|left"
|
||||
left="10"
|
||||
name="camera_x"
|
||||
top_pad="5"
|
||||
min_val="-1e+007"
|
||||
max_val="1e+007"
|
||||
width="70">
|
||||
<spinner.commit_callback
|
||||
function="CommitSettings" />
|
||||
</spinner>
|
||||
|
||||
<spinner
|
||||
height="20"
|
||||
label="Y"
|
||||
label_width="12"
|
||||
follows="top|left"
|
||||
name="camera_y"
|
||||
left_pad="20"
|
||||
min_val="-1e+007"
|
||||
max_val="1e+007"
|
||||
width="70">
|
||||
<spinner.commit_callback
|
||||
function="CommitSettings" />
|
||||
</spinner>
|
||||
|
||||
<spinner
|
||||
height="20"
|
||||
label="Z"
|
||||
label_width="12"
|
||||
follows="top|left"
|
||||
name="camera_z"
|
||||
left_pad="20"
|
||||
min_val="-1e+007"
|
||||
max_val="1e+007"
|
||||
width="70">
|
||||
<spinner.commit_callback
|
||||
function="CommitSettings" />
|
||||
</spinner>
|
||||
|
||||
<text
|
||||
follows="top|left|right"
|
||||
name="focus_offset_lbl"
|
||||
height="16"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
top_pad="20"
|
||||
width="100">
|
||||
Focus offset:
|
||||
</text>
|
||||
|
||||
<spinner
|
||||
height="20"
|
||||
label="X"
|
||||
label_width="12"
|
||||
follows="top|left"
|
||||
left="10"
|
||||
name="focus_x"
|
||||
top_pad="5"
|
||||
min_val="-1e+007"
|
||||
max_val="1e+007"
|
||||
width="70">
|
||||
<spinner.commit_callback
|
||||
function="CommitSettings" />
|
||||
</spinner>
|
||||
|
||||
<spinner
|
||||
height="20"
|
||||
label="Y"
|
||||
label_width="12"
|
||||
follows="top|left"
|
||||
name="focus_y"
|
||||
left_pad="20"
|
||||
min_val="-1e+007"
|
||||
max_val="1e+007"
|
||||
width="70">
|
||||
<spinner.commit_callback
|
||||
function="CommitSettings" />
|
||||
</spinner>
|
||||
|
||||
<spinner
|
||||
height="20"
|
||||
label="Z"
|
||||
label_width="12"
|
||||
follows="top|left"
|
||||
name="focus_z"
|
||||
left_pad="20"
|
||||
min_val="-1e+007"
|
||||
max_val="1e+007"
|
||||
width="70">
|
||||
<spinner.commit_callback
|
||||
function="CommitSettings" />
|
||||
</spinner>
|
||||
|
||||
<text
|
||||
follows="top|left|right"
|
||||
name="offset_scale_lbl"
|
||||
height="16"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
top_pad="20"
|
||||
width="140">
|
||||
Camera offset scale:
|
||||
</text>
|
||||
|
||||
<slider
|
||||
control_name="CameraOffsetScale"
|
||||
follows="top|left|right"
|
||||
height="16"
|
||||
top_pad="5"
|
||||
increment="0.1"
|
||||
min_val="-3"
|
||||
max_val="5"
|
||||
show_text="false"
|
||||
layout="topleft"
|
||||
left="3"
|
||||
name="offset_scale_sld"
|
||||
width="196" />
|
||||
<spinner
|
||||
control_name="CameraOffsetScale"
|
||||
height="20"
|
||||
follows="top|left|right"
|
||||
left_pad="5"
|
||||
name="offset_scale_ctrl"
|
||||
min_val="-3"
|
||||
max_val="5"
|
||||
width="58">
|
||||
<spinner.commit_callback
|
||||
function="CommitSettings" />
|
||||
</spinner>
|
||||
|
||||
</floater>
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<floater
|
||||
legacy_header_height="18"
|
||||
height="185"
|
||||
help_topic="floater_save_preset"
|
||||
layout="topleft"
|
||||
name="save_camera_preset"
|
||||
save_rect="true"
|
||||
title="Save Camera Preset"
|
||||
width="280">
|
||||
|
||||
<string name="btn_label_save">Save</string>
|
||||
<string name="btn_label_replace">Replace</string>
|
||||
<radio_group
|
||||
height="85"
|
||||
layout="topleft"
|
||||
left="20"
|
||||
top="15"
|
||||
width="150"
|
||||
name="radio_save_preset">
|
||||
<radio_item
|
||||
label="Save as a new preset"
|
||||
name="new_preset"
|
||||
top="10"
|
||||
layout="topleft"
|
||||
height="16"
|
||||
value="0"/>
|
||||
<radio_item
|
||||
label="Replace a preset"
|
||||
name="replace_preset"
|
||||
layout="topleft"
|
||||
top="70"
|
||||
height="16"
|
||||
value="1"/>
|
||||
</radio_group>
|
||||
<line_editor
|
||||
commit_on_focus_lost = "true"
|
||||
follows="top|left"
|
||||
height="23"
|
||||
layout="topleft"
|
||||
left="41"
|
||||
name="preset_txt_editor"
|
||||
width="200"
|
||||
top="45"/>
|
||||
<button
|
||||
follows="top|left"
|
||||
height="25"
|
||||
label="Save"
|
||||
layout="topleft"
|
||||
top="145"
|
||||
left="25"
|
||||
name="save"
|
||||
width="110"/>
|
||||
<button
|
||||
follows="bottom|right"
|
||||
height="25"
|
||||
label="Cancel"
|
||||
layout="topleft"
|
||||
left_pad="20"
|
||||
name="cancel"
|
||||
width="110"/>
|
||||
<!-- *HACK to correctly draw drop-down list over the buttons-->
|
||||
<combo_box
|
||||
follows="top|left"
|
||||
layout="topleft"
|
||||
left="41"
|
||||
name="preset_combo"
|
||||
top_delta="-40"
|
||||
width="200"/>
|
||||
</floater>
|
||||
|
|
@ -4,14 +4,11 @@
|
|||
height="145"
|
||||
help_topic="floater_save_preset"
|
||||
layout="topleft"
|
||||
name="Save Pref Preset"
|
||||
name="save_pref_preset"
|
||||
save_rect="true"
|
||||
title="SAVE PREF PRESET"
|
||||
title="Save Graphic Preset"
|
||||
width="300">
|
||||
|
||||
<string name="title_graphic">Save Graphic Preset</string>
|
||||
<string name="title_camera">Save Camera Preset</string>
|
||||
|
||||
<text
|
||||
follows="top|left|right"
|
||||
height="32"
|
||||
|
|
|
|||
|
|
@ -8545,6 +8545,18 @@ Error saving preset [NAME].
|
|||
Can not overwrite default preset.
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="PresetAlreadyExists"
|
||||
type="alertmodal">
|
||||
'[NAME]' is in use. You may replace
|
||||
this preset or choose another name.
|
||||
<tag>fail</tag>
|
||||
<usetemplate
|
||||
name="okbutton"
|
||||
yestext="OK"/>
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="notifytip.tga"
|
||||
name="PresetNotDeleted"
|
||||
|
|
|
|||