# Conflicts:
#	indra/llcommon/llcallstack.h
#	indra/llinventory/llsettingssky.cpp
#	indra/llmath/llvolume.cpp
#	indra/llwindow/llwindowwin32.cpp
#	indra/newview/llappviewer.cpp
#	indra/newview/llappviewerwin32.cpp
#	indra/newview/llmeshrepository.cpp
#	indra/newview/llmeshrepository.h
#	indra/newview/llviewerstats.cpp
#	indra/newview/llvoavatar.cpp
master
Ansariel 2023-05-05 12:35:33 +02:00
commit 9057bfc995
41 changed files with 948 additions and 1096 deletions

View File

@ -11,13 +11,15 @@ jobs:
build:
strategy:
matrix:
runner: [windows-large]
runner: [windows-large, macos-12-xl]
configuration: [ReleaseOS]
addrsize: [64]
include:
- runner: windows-large
configuration: ReleaseOS
addrsize: 32
- runner: macos-12-xl
developer_dir: "/Applications/Xcode_14.0.1.app/Contents/Developer"
runs-on: ${{ matrix.runner }}
env:
AUTOBUILD_CONFIGURATION: ${{ matrix.configuration }}
@ -25,8 +27,10 @@ jobs:
AUTOBUILD_INSTALLABLE_CACHE: ${{ github.workspace }}/.autobuild-installables
AUTOBUILD_VARIABLES_FILE: ${{ github.workspace }}/.build-variables/variables
AUTOBUILD_VSVER: "170" # vs2k22
DEVELOPER_DIR: ${{ matrix.developer_dir }}
LOGFAIL: debug # Show details when tests fail
GIT_REF: ${{ github.head_ref || github.ref }}
LL_SKIP_REQUIRE_SYSROOT: 1
steps:
- name: Checkout code
uses: actions/checkout@v3

View File

@ -672,9 +672,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>02b569ac2bd71f201e3dd86ade7b3eeb</string>
<string>27a77bfba1fa56fd59f4f26605baac35</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/113876/983684/bugsplat-1.0.7.579696-darwin64-579696.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/113802/983479/bugsplat-1.0.7.579669-darwin64-579669.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
@ -684,9 +684,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>5b32c47ae8e8cf0d4106f08e8db18044</string>
<string>c5abb9545039bd9113c8bf11d58f4501</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/113878/983697/bugsplat-4.0.3.0.579696-windows-579696.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/113803/983490/bugsplat-4.0.3.0.579669-windows-579669.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@ -696,16 +696,16 @@
<key>archive</key>
<map>
<key>hash</key>
<string>79c005fd8a660f8551b3c9ede64fa4ef</string>
<string>45e9b9215ce653171b572f44ee7bbf0c</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/113879/983696/bugsplat-4.0.3.0.579696-windows64-579696.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/113804/983491/bugsplat-4.0.3.0.579669-windows64-579669.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
<string>4.0.3.0.579696</string>
<string>4.0.3.0.579669</string>
</map>
<key>colladadom</key>
<map>
@ -3884,6 +3884,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<string>RelWithDebInfo</string>
<string>-project</string>
<string>SecondLife.xcodeproj</string>
<string>-parallelizeTargets</string>
</array>
</map>
<key>configure</key>
@ -3917,6 +3918,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<string>RelWithDebInfo</string>
<string>-project</string>
<string>SecondLife.xcodeproj</string>
<string>-parallelizeTargets</string>
</array>
</map>
<key>configure</key>
@ -3946,6 +3948,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<string>Release</string>
<string>-project</string>
<string>SecondLife.xcodeproj</string>
<string>-parallelizeTargets</string>
</array>
</map>
<key>configure</key>
@ -3971,6 +3974,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<string>Release</string>
<string>-project</string>
<string>SecondLife.xcodeproj</string>
<string>-parallelizeTargets</string>
</array>
</map>
<key>configure</key>

View File

@ -2,7 +2,7 @@
include_guard()
# FMODSTUDIO can be set when launching the make using the argument -DFMODSTUDIO:BOOL=ON
# FMODSTUDIO can be set when launching the make using the argument -DUSE_FMODSTUDIO:BOOL=ON
# When building using proprietary binaries though (i.e. having access to LL private servers),
# we always build with FMODSTUDIO.
# Open source devs should use the -DFMODSTUDIO:BOOL=ON then if they want to build with FMOD, whether

View File

@ -130,6 +130,13 @@ MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources)
message("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_CFLAGS ${${name}_test_additional_CFLAGS}")
endif()
if (DARWIN)
# test binaries always need to be signed for local development
set_target_properties(PROJECT_${project}_TEST_${name}
PROPERTIES
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "-")
endif ()
#
# Setup test targets
#
@ -225,6 +232,13 @@ FUNCTION(LL_ADD_INTEGRATION_TEST
)
endif ()
if (DARWIN)
# test binaries always need to be signed for local development
set_target_properties(INTEGRATION_TEST_${testname}
PROPERTIES
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "-")
endif ()
# Add link deps to the executable
if(TEST_DEBUG)
message(STATUS "TARGET_LINK_LIBRARIES(INTEGRATION_TEST_${testname} ${libraries})")

View File

@ -173,13 +173,17 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set(CMAKE_XCODE_ATTRIBUTE_GCC_OPTIMIZATION_LEVEL "${CMAKE_MATCH_1}")
message(STATUS "CMAKE_XCODE_ATTRIBUTE_GCC_OPTIMIZATION_LEVEL = '${CMAKE_XCODE_ATTRIBUTE_GCC_OPTIMIZATION_LEVEL}'")
string(REGEX MATCHALL "[^ ]+" LL_BUILD_LIST "$ENV{LL_BUILD}")
list(FIND LL_BUILD_LIST "-iwithsysroot" sysroot_idx)
if ("${sysroot_idx}" LESS 0)
message(FATAL_ERROR "Environment variable LL_BUILD must contain '-iwithsysroot'")
endif ()
math(EXPR sysroot_idx "${sysroot_idx} + 1")
list(GET LL_BUILD_LIST "${sysroot_idx}" CMAKE_OSX_SYSROOT)
# allow disabling this check by setting LL_SKIP_REQUIRE_SYSROOT either ON as cmake cache var or non-empty as environment var
set(LL_SKIP_REQUIRE_SYSROOT OFF CACHE BOOL "Skip requirement to set toolchain sysroot ahead of time. Not skipped by default for consistency, but skipping can be useful for selecting alternative xcode versions side by side")
if("$ENV{LL_SKIP_REQUIRE_SYSROOT}" STREQUAL "" AND NOT ${LL_SKIP_REQUIRE_SYSROOT})
string(REGEX MATCHALL "[^ ]+" LL_BUILD_LIST "$ENV{LL_BUILD}")
list(FIND LL_BUILD_LIST "-iwithsysroot" sysroot_idx)
if ("${sysroot_idx}" LESS 0)
message(FATAL_ERROR "Environment variable LL_BUILD must contain '-iwithsysroot'")
endif ()
math(EXPR sysroot_idx "${sysroot_idx} + 1")
list(GET LL_BUILD_LIST "${sysroot_idx}" CMAKE_OSX_SYSROOT)
endif()
message(STATUS "CMAKE_OSX_SYSROOT = '${CMAKE_OSX_SYSROOT}'")
set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "com.apple.compilers.llvm.clang.1_0")

View File

@ -79,23 +79,9 @@ struct LLContextStatus
LL_COMMON_API std::ostream& operator<<(std::ostream& s, const LLContextStatus& context_status);
/* <FS:TS> gcc gets unhappy at what it thinks are multiline comments
// <FS:Beq> Store the check to avoid the nasty mutex monster that lies within
//#define dumpStack(tag) \
// if (debugLoggingEnabled(tag)) \
// { \
// LLCallStack cs; \
// LL_DEBUGS(tag) << "STACK:\n" << "====================\n" << cs << "====================" << LL_ENDL; \
// }
*/
#ifdef LL_RELEASE_FOR_DOWNLOAD
#define dumpStack(tag)
#else
#define dumpStack(tag) \
if (debugLoggingEnabled(tag)) \
{ \
LLCallStack cs; \
LL_DEBUGS(tag) << "STACK:\n" << "====================\n" << cs << "====================" << LL_ENDL; \
}
#endif
// </FS:Beq>
#define dumpStack(tag) \
LL_DEBUGS(tag) << "STACK:\n" \
<< "====================\n" \
<< LLCallStack() \
<< "====================" \
<< LL_ENDL;

View File

@ -1627,20 +1627,5 @@ namespace LLError
}
}
bool debugLoggingEnabled(const std::string& tag)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_APP;
LLMutexTrylock lock(getMutex<LOG_MUTEX>(), 5);
if (!lock.isLocked())
{
return false;
}
SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig();
LLError::ELevel level = LLError::LEVEL_DEBUG;
bool res = checkLevelMap(s->mTagLevelMap, tag, level);
return res;
}

View File

@ -479,7 +479,29 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG;
LLError::CallSite& _site(_sites[which]); \
lllog_test_()
// Check at run-time whether logging is enabled, without generating output
/*
// Check at run-time whether logging is enabled, without generating output.
Resist the temptation to add a function like this because it incurs the
expense of locking and map-searching every time control reaches it.
bool debugLoggingEnabled(const std::string& tag);
Instead of:
if debugLoggingEnabled("SomeTag")
{
// ... presumably expensive operation ...
LL_DEBUGS("SomeTag") << ... << LL_ENDL;
}
Use this:
LL_DEBUGS("SomeTag");
// ... presumably expensive operation ...
LL_CONT << ...;
LL_ENDL;
LL_DEBUGS("SomeTag") performs the locking and map-searching ONCE, then caches
the result in a static variable.
*/
#endif // LL_LLERROR_H

View File

@ -36,7 +36,8 @@
//============================================================================
#define MUTEX_DEBUG (LL_DEBUG || LL_RELEASE_WITH_DEBUG_INFO)
//#define MUTEX_DEBUG (LL_DEBUG || LL_RELEASE_WITH_DEBUG_INFO)
#define MUTEX_DEBUG 0 //disable mutex debugging as it's interfering with profiles
#if MUTEX_DEBUG
#include <map>
@ -61,7 +62,7 @@ protected:
mutable LLThread::id_t mLockingThread;
#if MUTEX_DEBUG
std::map<LLThread::id_t, BOOL> mIsLocked;
std::unordered_map<LLThread::id_t, BOOL> mIsLocked;
#endif
};

View File

@ -191,75 +191,6 @@ LLSD& drill_ref( LLSD& blob, const LLSD& path);
}
/*****************************************************************************
* LLSDArray
*****************************************************************************/
/**
* Construct an LLSD::Array inline, with implicit conversion to LLSD. Usage:
*
* @code
* void somefunc(const LLSD&);
* ...
* somefunc(LLSDArray("text")(17)(3.14));
* @endcode
*
* For completeness, LLSDArray() with no args constructs an empty array, so
* <tt>LLSDArray()("text")(17)(3.14)</tt> produces an array equivalent to the
* above. But for most purposes, LLSD() is already equivalent to an empty
* array, and if you explicitly want an empty isArray(), there's
* LLSD::emptyArray(). However, supporting a no-args LLSDArray() constructor
* follows the principle of least astonishment.
*/
class LLSDArray
{
public:
LLSDArray():
_data(LLSD::emptyArray())
{}
/**
* Need an explicit copy constructor. Consider the following:
*
* @code
* LLSD array_of_arrays(LLSDArray(LLSDArray(17)(34))
* (LLSDArray("x")("y")));
* @endcode
*
* The coder intends to construct [[17, 34], ["x", "y"]].
*
* With the compiler's implicit copy constructor, s/he gets instead
* [17, 34, ["x", "y"]].
*
* The expression LLSDArray(17)(34) constructs an LLSDArray with those two
* values. The reader assumes it should be converted to LLSD, as we always
* want with LLSDArray, before passing it to the @em outer LLSDArray
* constructor! This copy constructor makes that happen.
*/
LLSDArray(const LLSDArray& inner):
_data(LLSD::emptyArray())
{
_data.append(inner);
}
LLSDArray(const LLSD& value):
_data(LLSD::emptyArray())
{
_data.append(value);
}
LLSDArray& operator()(const LLSD& value)
{
_data.append(value);
return *this;
}
operator LLSD() const { return _data; }
LLSD get() const { return _data; }
private:
LLSD _data;
};
namespace llsd
{

View File

@ -345,7 +345,7 @@ namespace tut
lleventdispatcher_data():
work("test dispatcher", "op"),
// map {d=double, array=[3 elements]}
required(LLSDMap("d", LLSD::Real(0))("array", LLSDArray(LLSD())(LLSD())(LLSD()))),
required(LLSDMap("d", LLSD::Real(0))("array", llsd::array(LLSD(), LLSD(), LLSD()))),
// first several params are required, last couple optional
partial_offset(3)
{
@ -434,8 +434,8 @@ namespace tut
// freena(), methodna(), cmethodna(), smethodna() all take same param list.
// Same for freenb() et al.
params = LLSDMap("a", LLSDArray("b")("i")("f")("d")("cp"))
("b", LLSDArray("s")("uuid")("date")("uri")("bin"));
params = LLSDMap("a", llsd::array("b", "i", "f", "d", "cp"))
("b", llsd::array("s", "uuid", "date", "uri", "bin"));
debug("params:\n",
params, "\n"
"params[\"a\"]:\n",
@ -452,12 +452,12 @@ namespace tut
// LLDate values are, as long as they're different from the
// LLUUID() and LLDate() default values so inspect() will report
// them.
dft_array_full = LLSDMap("a", LLSDArray(true)(17)(3.14)(123456.78)("classic"))
("b", LLSDArray("string")
(LLUUID::generateNewID())
(LLDate::now())
(LLURI("http://www.ietf.org/rfc/rfc3986.txt"))
(binary));
dft_array_full = LLSDMap("a", llsd::array(true, 17, 3.14, 123456.78, "classic"))
("b", llsd::array("string",
LLUUID::generateNewID(),
LLDate::now(),
LLURI("http://www.ietf.org/rfc/rfc3986.txt"),
binary));
debug("dft_array_full:\n",
dft_array_full);
// Partial defaults arrays.
@ -723,7 +723,7 @@ namespace tut
{
set_test_name("map-style registration with non-array params");
// Pass "param names" as scalar or as map
LLSD attempts(LLSDArray(17)(LLSDMap("pi", 3.14)("two", 2)));
LLSD attempts(llsd::array(17, LLSDMap("pi", 3.14)("two", 2)));
foreach(LLSD ae, inArray(attempts))
{
std::string threw = catch_what<std::exception>([this, &ae](){
@ -738,7 +738,7 @@ namespace tut
{
set_test_name("map-style registration with badly-formed defaults");
std::string threw = catch_what<std::exception>([this](){
work.add("freena_err", "freena", freena, LLSDArray("a")("b"), 17);
work.add("freena_err", "freena", freena, llsd::array("a", "b"), 17);
});
ensure_has(threw, "must be a map or an array");
}
@ -749,8 +749,8 @@ namespace tut
set_test_name("map-style registration with too many array defaults");
std::string threw = catch_what<std::exception>([this](){
work.add("freena_err", "freena", freena,
LLSDArray("a")("b"),
LLSDArray(17)(0.9)("gack"));
llsd::array("a", "b"),
llsd::array(17, 0.9, "gack"));
});
ensure_has(threw, "shorter than");
}
@ -761,7 +761,7 @@ namespace tut
set_test_name("map-style registration with too many map defaults");
std::string threw = catch_what<std::exception>([this](){
work.add("freena_err", "freena", freena,
LLSDArray("a")("b"),
llsd::array("a", "b"),
LLSDMap("b", 17)("foo", 3.14)("bar", "sinister"));
});
ensure_has(threw, "nonexistent params");
@ -798,7 +798,7 @@ namespace tut
void object::test<8>()
{
set_test_name("query Callables with/out required params");
LLSD names(LLSDArray("free1")("Dmethod1")("Dcmethod1")("method1"));
LLSD names(llsd::array("free1", "Dmethod1", "Dcmethod1", "method1"));
foreach(LLSD nm, inArray(names))
{
LLSD metadata(getMetadata(nm));
@ -821,13 +821,13 @@ namespace tut
{
set_test_name("query array-style functions/methods");
// Associate each registered name with expected arity.
LLSD expected(LLSDArray
(LLSDArray
(0)(LLSDArray("free0_array")("smethod0_array")("method0_array")))
(LLSDArray
(5)(LLSDArray("freena_array")("smethodna_array")("methodna_array")))
(LLSDArray
(5)(LLSDArray("freenb_array")("smethodnb_array")("methodnb_array"))));
LLSD expected(llsd::array
(llsd::array
(0, llsd::array("free0_array", "smethod0_array", "method0_array")),
llsd::array
(5, llsd::array("freena_array", "smethodna_array", "methodna_array")),
llsd::array
(5, llsd::array("freenb_array", "smethodnb_array", "methodnb_array"))));
foreach(LLSD ae, inArray(expected))
{
LLSD::Integer arity(ae[0].asInteger());
@ -853,7 +853,7 @@ namespace tut
set_test_name("query map-style no-params functions/methods");
// - (Free function | non-static method), map style, no params (ergo
// no defaults)
LLSD names(LLSDArray("free0_map")("smethod0_map")("method0_map"));
LLSD names(llsd::array("free0_map", "smethod0_map", "method0_map"));
foreach(LLSD nm, inArray(names))
{
LLSD metadata(getMetadata(nm));
@ -877,13 +877,13 @@ namespace tut
// there should (!) be no difference beween array defaults and map
// defaults. Verify, so we can ignore the distinction for all other
// tests.
LLSD equivalences(LLSDArray
(LLSDArray("freena_map_adft")("freena_map_mdft"))
(LLSDArray("freenb_map_adft")("freenb_map_mdft"))
(LLSDArray("smethodna_map_adft")("smethodna_map_mdft"))
(LLSDArray("smethodnb_map_adft")("smethodnb_map_mdft"))
(LLSDArray("methodna_map_adft")("methodna_map_mdft"))
(LLSDArray("methodnb_map_adft")("methodnb_map_mdft")));
LLSD equivalences(llsd::array
(llsd::array("freena_map_adft", "freena_map_mdft"),
llsd::array("freenb_map_adft", "freenb_map_mdft"),
llsd::array("smethodna_map_adft", "smethodna_map_mdft"),
llsd::array("smethodnb_map_adft", "smethodnb_map_mdft"),
llsd::array("methodna_map_adft", "methodna_map_mdft"),
llsd::array("methodnb_map_adft", "methodnb_map_mdft")));
foreach(LLSD eq, inArray(equivalences))
{
LLSD adft(eq[0]);
@ -953,42 +953,42 @@ namespace tut
debug("skipreq:\n",
skipreq);
LLSD groups(LLSDArray // array of groups
LLSD groups(llsd::array // array of groups
(LLSDArray // group
(LLSDArray("freena_map_allreq")("smethodna_map_allreq")("methodna_map_allreq"))
(LLSDArray(allreq["a"])(LLSD()))) // required, optional
(llsd::array // group
(llsd::array("freena_map_allreq", "smethodna_map_allreq", "methodna_map_allreq"),
llsd::array(allreq["a"], LLSD())), // required, optional
(LLSDArray // group
(LLSDArray("freenb_map_allreq")("smethodnb_map_allreq")("methodnb_map_allreq"))
(LLSDArray(allreq["b"])(LLSD()))) // required, optional
llsd::array // group
(llsd::array("freenb_map_allreq", "smethodnb_map_allreq", "methodnb_map_allreq"),
llsd::array(allreq["b"], LLSD())), // required, optional
(LLSDArray // group
(LLSDArray("freena_map_leftreq")("smethodna_map_leftreq")("methodna_map_leftreq"))
(LLSDArray(leftreq["a"])(rightdft["a"]))) // required, optional
llsd::array // group
(llsd::array("freena_map_leftreq", "smethodna_map_leftreq", "methodna_map_leftreq"),
llsd::array(leftreq["a"], rightdft["a"])), // required, optional
(LLSDArray // group
(LLSDArray("freenb_map_leftreq")("smethodnb_map_leftreq")("methodnb_map_leftreq"))
(LLSDArray(leftreq["b"])(rightdft["b"]))) // required, optional
llsd::array // group
(llsd::array("freenb_map_leftreq", "smethodnb_map_leftreq", "methodnb_map_leftreq"),
llsd::array(leftreq["b"], rightdft["b"])), // required, optional
(LLSDArray // group
(LLSDArray("freena_map_skipreq")("smethodna_map_skipreq")("methodna_map_skipreq"))
(LLSDArray(skipreq["a"])(dft_map_partial["a"]))) // required, optional
llsd::array // group
(llsd::array("freena_map_skipreq", "smethodna_map_skipreq", "methodna_map_skipreq"),
llsd::array(skipreq["a"], dft_map_partial["a"])), // required, optional
(LLSDArray // group
(LLSDArray("freenb_map_skipreq")("smethodnb_map_skipreq")("methodnb_map_skipreq"))
(LLSDArray(skipreq["b"])(dft_map_partial["b"]))) // required, optional
llsd::array // group
(llsd::array("freenb_map_skipreq", "smethodnb_map_skipreq", "methodnb_map_skipreq"),
llsd::array(skipreq["b"], dft_map_partial["b"])), // required, optional
// We only need mention the full-map-defaults ("_mdft" suffix)
// registrations, having established their equivalence with the
// full-array-defaults ("_adft" suffix) registrations in another test.
(LLSDArray // group
(LLSDArray("freena_map_mdft")("smethodna_map_mdft")("methodna_map_mdft"))
(LLSDArray(LLSD::emptyMap())(dft_map_full["a"]))) // required, optional
// We only need mention the full-map-defaults ("_mdft" suffix)
// registrations, having established their equivalence with the
// full-array-defaults ("_adft" suffix) registrations in another test.
llsd::array // group
(llsd::array("freena_map_mdft", "smethodna_map_mdft", "methodna_map_mdft"),
llsd::array(LLSD::emptyMap(), dft_map_full["a"])), // required, optional
(LLSDArray // group
(LLSDArray("freenb_map_mdft")("smethodnb_map_mdft")("methodnb_map_mdft"))
(LLSDArray(LLSD::emptyMap())(dft_map_full["b"])))); // required, optional
llsd::array // group
(llsd::array("freenb_map_mdft", "smethodnb_map_mdft", "methodnb_map_mdft"),
llsd::array(LLSD::emptyMap(), dft_map_full["b"])))); // required, optional
foreach(LLSD grp, inArray(groups))
{
@ -1077,7 +1077,7 @@ namespace tut
// with 'required'.
LLSD answer(42);
// LLSD value matching 'required' according to llsd_matches() rules.
LLSD matching(LLSDMap("d", 3.14)("array", LLSDArray("answer")(true)(answer)));
LLSD matching(LLSDMap("d", 3.14)("array", llsd::array("answer", true, answer)));
// Okay, walk through 'tests'.
foreach(const CallablesTriple& tr, tests)
{
@ -1114,17 +1114,17 @@ namespace tut
call_exc("free0_map", 17, map_exc);
// Passing an array to a map-style function works now! No longer an
// error case!
// call_exc("free0_map", LLSDArray("a")("b"), map_exc);
// call_exc("free0_map", llsd::array("a", "b"), map_exc);
}
template<> template<>
void object::test<18>()
{
set_test_name("call no-args functions");
LLSD names(LLSDArray
("free0_array")("free0_map")
("smethod0_array")("smethod0_map")
("method0_array")("method0_map"));
LLSD names(llsd::array
("free0_array", "free0_map",
"smethod0_array", "smethod0_map",
"method0_array", "method0_map"));
foreach(LLSD name, inArray(names))
{
// Look up the Vars instance for this function.
@ -1142,10 +1142,10 @@ namespace tut
}
// Break out this data because we use it in a couple different tests.
LLSD array_funcs(LLSDArray
(LLSDMap("a", "freena_array") ("b", "freenb_array"))
(LLSDMap("a", "smethodna_array")("b", "smethodnb_array"))
(LLSDMap("a", "methodna_array") ("b", "methodnb_array")));
LLSD array_funcs(llsd::array
(LLSDMap("a", "freena_array") ("b", "freenb_array"),
LLSDMap("a", "smethodna_array")("b", "smethodnb_array"),
LLSDMap("a", "methodna_array") ("b", "methodnb_array")));
template<> template<>
void object::test<19>()
@ -1153,7 +1153,7 @@ namespace tut
set_test_name("call array-style functions with too-short arrays");
// Could have two different too-short arrays, one for *na and one for
// *nb, but since they both take 5 params...
LLSD tooshort(LLSDArray("this")("array")("too")("short"));
LLSD tooshort(llsd::array("this", "array", "too", "short"));
foreach(const LLSD& funcsab, inArray(array_funcs))
{
foreach(const llsd::MapEntry& e, inMap(funcsab))
@ -1172,12 +1172,12 @@ namespace tut
{
binary.push_back((U8)h);
}
LLSD args(LLSDMap("a", LLSDArray(true)(17)(3.14)(123.456)("char*"))
("b", LLSDArray("string")
(LLUUID("01234567-89ab-cdef-0123-456789abcdef"))
(LLDate("2011-02-03T15:07:00Z"))
(LLURI("http://secondlife.com"))
(binary)));
LLSD args(LLSDMap("a", llsd::array(true, 17, 3.14, 123.456, "char*"))
("b", llsd::array("string",
LLUUID("01234567-89ab-cdef-0123-456789abcdef"),
LLDate("2011-02-03T15:07:00Z"),
LLURI("http://secondlife.com"),
binary)));
LLSD argsplus(args);
argsplus["a"].append("bogus");
argsplus["b"].append("bogus");
@ -1191,7 +1191,7 @@ namespace tut
debug("expect: ", expect);
// Use substantially the same logic for args and argsplus
LLSD argsarrays(LLSDArray(args)(argsplus));
LLSD argsarrays(llsd::array(args, argsplus));
// So i==0 selects 'args', i==1 selects argsplus
for (LLSD::Integer i(0), iend(argsarrays.size()); i < iend; ++i)
{
@ -1236,8 +1236,8 @@ namespace tut
set_test_name("call map-style functions with (full | oversized) (arrays | maps)");
const char binary[] = "\x99\x88\x77\x66\x55";
LLSD array_full(LLSDMap
("a", LLSDArray(false)(255)(98.6)(1024.5)("pointer"))
("b", LLSDArray("object")(LLUUID::generateNewID())(LLDate::now())(LLURI("http://wiki.lindenlab.com/wiki"))(LLSD::Binary(boost::begin(binary), boost::end(binary)))));
("a", llsd::array(false, 255, 98.6, 1024.5, "pointer"))
("b", llsd::array("object", LLUUID::generateNewID(), LLDate::now(), LLURI("http://wiki.lindenlab.com/wiki"), LLSD::Binary(boost::begin(binary), boost::end(binary)))));
LLSD array_overfull(array_full);
foreach(LLSD::String a, ab)
{
@ -1280,20 +1280,20 @@ namespace tut
// parameter defaults should make NO DIFFERENCE WHATSOEVER. Every call
// should pass all params.
LLSD names(LLSDMap
("a", LLSDArray
("freena_map_allreq") ("smethodna_map_allreq") ("methodna_map_allreq")
("freena_map_leftreq")("smethodna_map_leftreq")("methodna_map_leftreq")
("freena_map_skipreq")("smethodna_map_skipreq")("methodna_map_skipreq")
("freena_map_adft") ("smethodna_map_adft") ("methodna_map_adft")
("freena_map_mdft") ("smethodna_map_mdft") ("methodna_map_mdft"))
("b", LLSDArray
("freenb_map_allreq") ("smethodnb_map_allreq") ("methodnb_map_allreq")
("freenb_map_leftreq")("smethodnb_map_leftreq")("methodnb_map_leftreq")
("freenb_map_skipreq")("smethodnb_map_skipreq")("methodnb_map_skipreq")
("freenb_map_adft") ("smethodnb_map_adft") ("methodnb_map_adft")
("freenb_map_mdft") ("smethodnb_map_mdft") ("methodnb_map_mdft")));
("a", llsd::array
("freena_map_allreq", "smethodna_map_allreq", "methodna_map_allreq",
"freena_map_leftreq", "smethodna_map_leftreq", "methodna_map_leftreq",
"freena_map_skipreq", "smethodna_map_skipreq", "methodna_map_skipreq",
"freena_map_adft", "smethodna_map_adft", "methodna_map_adft",
"freena_map_mdft", "smethodna_map_mdft", "methodna_map_mdft"))
("b", llsd::array
("freenb_map_allreq", "smethodnb_map_allreq", "methodnb_map_allreq",
"freenb_map_leftreq", "smethodnb_map_leftreq", "methodnb_map_leftreq",
"freenb_map_skipreq", "smethodnb_map_skipreq", "methodnb_map_skipreq",
"freenb_map_adft", "smethodnb_map_adft", "methodnb_map_adft",
"freenb_map_mdft", "smethodnb_map_mdft", "methodnb_map_mdft")));
// Treat (full | overfull) (array | map) the same.
LLSD argssets(LLSDArray(array_full)(array_overfull)(map_full)(map_overfull));
LLSD argssets(llsd::array(array_full, array_overfull, map_full, map_overfull));
foreach(const LLSD& args, inArray(argssets))
{
foreach(LLSD::String a, ab)

View File

@ -1817,10 +1817,10 @@ namespace tut
{
set_test_name("verify sequence to Python");
LLSD cdata(LLSDArray(17)(3.14)
("This string\n"
"has several\n"
"lines."));
LLSD cdata(llsd::array(17, 3.14,
"This string\n"
"has several\n"
"lines."));
const char pydata[] =
"def verify(iterable):\n"

View File

@ -441,8 +441,8 @@ LLSD LLSettingsDay::defaults()
}
LLSD tracks;
tracks.append(LLSDArray(waterTrack));
tracks.append(LLSDArray(skyTrack));
tracks.append(llsd::array(waterTrack));
tracks.append(llsd::array(skyTrack));
dfltsetting[SETTING_TRACKS] = tracks;
dfltsetting[SETTING_FRAMES] = frames;

View File

@ -154,28 +154,28 @@ LLSettingsSky::validation_list_t legacyHazeValidationList()
{
legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_AMBIENT, false, LLSD::TypeArray,
boost::bind(&LLSettingsBase::Validator::verifyVectorMinMax, _1, _2,
LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
LLSD(LLSDArray(3.0f)(3.0f)(3.0f)("*")))));
llsd::array(0.0f, 0.0f, 0.0f, "*"),
llsd::array(3.0f, 3.0f, 3.0f, "*"))));
legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_BLUE_DENSITY, false, LLSD::TypeArray,
boost::bind(&LLSettingsBase::Validator::verifyVectorMinMax, _1, _2,
LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
LLSD(LLSDArray(3.0f)(3.0f)(3.0f)("*")))));
llsd::array(0.0f, 0.0f, 0.0f, "*"),
llsd::array(3.0f, 3.0f, 3.0f, "*"))));
legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_BLUE_HORIZON, false, LLSD::TypeArray,
boost::bind(&LLSettingsBase::Validator::verifyVectorMinMax, _1, _2,
LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
LLSD(LLSDArray(3.0f)(3.0f)(3.0f)("*")))));
llsd::array(0.0f, 0.0f, 0.0f, "*"),
llsd::array(3.0f, 3.0f, 3.0f, "*"))));
legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_HAZE_DENSITY, false, LLSD::TypeReal,
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(5.0f)))));
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 5.0f))));
legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_HAZE_HORIZON, false, LLSD::TypeReal,
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(5.0f)))));
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 5.0f))));
// <FS:Beq> FIRE-29682 Allow full range density multipliers
// legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_MULTIPLIER, false, LLSD::TypeReal,
// boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0001f)(2.0f)))));
// boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0001f, 2.0f))));
legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_MULTIPLIER, false, LLSD::TypeReal,
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0000001f)(2.0f)))));
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0000001f, 2.0f))));
// </FS:Beq>
legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DISTANCE_MULTIPLIER, false, LLSD::TypeReal,
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0001f)(1000.0f)))));
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0001f, 1000.0f))));
}
return legacyHazeValidation;
}
@ -186,19 +186,19 @@ LLSettingsSky::validation_list_t rayleighValidationList()
if (rayleighValidation.empty())
{
rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH, false, LLSD::TypeReal,
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(32768.0f)))));
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 32768.0f))));
rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM, false, LLSD::TypeReal,
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(2.0f)))));
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 2.0f))));
rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR, false, LLSD::TypeReal,
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(-1.0f)(1.0f)))));
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(-1.0f, 1.0f))));
rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM, false, LLSD::TypeReal,
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(2.0f)))));
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 2.0f))));
rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM, false, LLSD::TypeReal,
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(1.0f)))));
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f))));
}
return rayleighValidation;
}
@ -209,19 +209,19 @@ LLSettingsSky::validation_list_t absorptionValidationList()
if (absorptionValidation.empty())
{
absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH, false, LLSD::TypeReal,
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(32768.0f)))));
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 32768.0f))));
absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM, false, LLSD::TypeReal,
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(2.0f)))));
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 2.0f))));
absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR, false, LLSD::TypeReal,
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(-1.0f)(1.0f)))));
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(-1.0f, 1.0f))));
absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM, false, LLSD::TypeReal,
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(2.0f)))));
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 2.0f))));
absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM, false, LLSD::TypeReal,
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(1.0f)))));
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f))));
}
return absorptionValidation;
}
@ -232,22 +232,22 @@ LLSettingsSky::validation_list_t mieValidationList()
if (mieValidation.empty())
{
mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH, false, LLSD::TypeReal,
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(32768.0f)))));
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 32768.0f))));
mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM, false, LLSD::TypeReal,
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(2.0f)))));
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 2.0f))));
mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR, false, LLSD::TypeReal,
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(-1.0f)(1.0f)))));
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(-1.0f, 1.0f))));
mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM, false, LLSD::TypeReal,
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(2.0f)))));
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 2.0f))));
mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM, false, LLSD::TypeReal,
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(1.0f)))));
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f))));
mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_MIE_ANISOTROPY_FACTOR, false, LLSD::TypeReal,
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(1.0f)))));
boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f))));
}
return mieValidation;
}
@ -552,92 +552,89 @@ LLSettingsSky::validation_list_t LLSettingsSky::validationList()
static validation_list_t validation;
if (validation.empty())
{ // Note the use of LLSD(LLSDArray()()()...) This is due to an issue with the
// copy constructor for LLSDArray. Directly binding the LLSDArray as
// a parameter without first wrapping it in a pure LLSD object will result
// in deeply nested arrays like this [[[[[[[[[[v1,v2,v3]]]]]]]]]]
{
validation.push_back(Validator(SETTING_BLOOM_TEXTUREID, true, LLSD::TypeUUID));
validation.push_back(Validator(SETTING_RAINBOW_TEXTUREID, false, LLSD::TypeUUID));
validation.push_back(Validator(SETTING_HALO_TEXTUREID, false, LLSD::TypeUUID));
validation.push_back(Validator(SETTING_CLOUD_COLOR, true, LLSD::TypeArray,
boost::bind(&Validator::verifyVectorMinMax, _1, _2,
LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
LLSD(LLSDArray(1.0f)(1.0f)(1.0f)("*")))));
llsd::array(0.0f, 0.0f, 0.0f, "*"),
llsd::array(1.0f, 1.0f, 1.0f, "*"))));
validation.push_back(Validator(SETTING_CLOUD_POS_DENSITY1, true, LLSD::TypeArray,
boost::bind(&Validator::verifyVectorMinMax, _1, _2,
LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
LLSD(LLSDArray(1.0f)(1.0f)(3.0f)("*")))));
llsd::array(0.0f, 0.0f, 0.0f, "*"),
llsd::array(1.0f, 1.0f, 3.0f, "*"))));
validation.push_back(Validator(SETTING_CLOUD_POS_DENSITY2, true, LLSD::TypeArray,
boost::bind(&Validator::verifyVectorMinMax, _1, _2,
LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
LLSD(LLSDArray(1.0f)(1.0f)(1.0f)("*")))));
llsd::array(0.0f, 0.0f, 0.0f, "*"),
llsd::array(1.0f, 1.0f, 1.0f, "*"))));
validation.push_back(Validator(SETTING_CLOUD_SCALE, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.001f)(3.0f)))));
boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.001f, 3.0f))));
validation.push_back(Validator(SETTING_CLOUD_SCROLL_RATE, true, LLSD::TypeArray,
boost::bind(&Validator::verifyVectorMinMax, _1, _2,
LLSD(LLSDArray(-50.0f)(-50.0f)),
LLSD(LLSDArray(50.0f)(50.0f)))));
llsd::array(-50.0f, -50.0f),
llsd::array(50.0f, 50.0f))));
validation.push_back(Validator(SETTING_CLOUD_SHADOW, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(1.0f)))));
boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f))));
validation.push_back(Validator(SETTING_CLOUD_TEXTUREID, false, LLSD::TypeUUID));
validation.push_back(Validator(SETTING_CLOUD_VARIANCE, false, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(1.0f)))));
boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f))));
validation.push_back(Validator(SETTING_DOME_OFFSET, false, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(1.0f)))));
boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f))));
validation.push_back(Validator(SETTING_DOME_RADIUS, false, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(1000.0f)(2000.0f)))));
boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(1000.0f, 2000.0f))));
validation.push_back(Validator(SETTING_GAMMA, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(20.0f)))));
boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 20.0f))));
validation.push_back(Validator(SETTING_GLOW, true, LLSD::TypeArray,
boost::bind(&Validator::verifyVectorMinMax, _1, _2,
LLSD(LLSDArray(0.2f)("*")(-10.0f)("*")),
LLSD(LLSDArray(40.0f)("*")(10.0f)("*")))));
llsd::array(0.2f, "*", -10.0f, "*"),
llsd::array(40.0f, "*", 10.0f, "*"))));
validation.push_back(Validator(SETTING_MAX_Y, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(10000.0f)))));
boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 10000.0f))));
validation.push_back(Validator(SETTING_MOON_ROTATION, true, LLSD::TypeArray, &Validator::verifyQuaternionNormal));
validation.push_back(Validator(SETTING_MOON_SCALE, false, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.25f)(20.0f))), LLSD::Real(1.0)));
boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.25f, 20.0f)), LLSD::Real(1.0)));
validation.push_back(Validator(SETTING_MOON_TEXTUREID, false, LLSD::TypeUUID));
validation.push_back(Validator(SETTING_MOON_BRIGHTNESS, false, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(1.0f)))));
boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f))));
validation.push_back(Validator(SETTING_STAR_BRIGHTNESS, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(500.0f)))));
boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 500.0f))));
validation.push_back(Validator(SETTING_SUNLIGHT_COLOR, true, LLSD::TypeArray,
boost::bind(&Validator::verifyVectorMinMax, _1, _2,
LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
LLSD(LLSDArray(3.0f)(3.0f)(3.0f)("*")))));
llsd::array(0.0f, 0.0f, 0.0f, "*"),
llsd::array(3.0f, 3.0f, 3.0f, "*"))));
validation.push_back(Validator(SETTING_SUN_ROTATION, true, LLSD::TypeArray, &Validator::verifyQuaternionNormal));
validation.push_back(Validator(SETTING_SUN_SCALE, false, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.25f)(20.0f))), LLSD::Real(1.0)));
boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.25f, 20.0f)), LLSD::Real(1.0)));
validation.push_back(Validator(SETTING_SUN_TEXTUREID, false, LLSD::TypeUUID));
validation.push_back(Validator(SETTING_PLANET_RADIUS, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(1000.0f)(32768.0f)))));
boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(1000.0f, 32768.0f))));
validation.push_back(Validator(SETTING_SKY_BOTTOM_RADIUS, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(1000.0f)(32768.0f)))));
boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(1000.0f, 32768.0f))));
validation.push_back(Validator(SETTING_SKY_TOP_RADIUS, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(1000.0f)(32768.0f)))));
boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(1000.0f, 32768.0f))));
validation.push_back(Validator(SETTING_SUN_ARC_RADIANS, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(0.1f)))));
boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 0.1f))));
validation.push_back(Validator(SETTING_SKY_MOISTURE_LEVEL, false, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(1.0f)))));
boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f))));
validation.push_back(Validator(SETTING_SKY_DROPLET_RADIUS, false, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(5.0f)(1000.0f)))));
boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(5.0f, 1000.0f))));
validation.push_back(Validator(SETTING_SKY_ICE_LEVEL, false, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(1.0f)))));
boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f))));
validation.push_back(Validator(SETTING_REFLECTION_PROBE_AMBIANCE, false, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(10.0f)))));
boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(llsd::array(0.0f, 10.0f)))));
validation.push_back(Validator(SETTING_RAYLEIGH_CONFIG, true, LLSD::TypeArray, &validateRayleighLayers));
validation.push_back(Validator(SETTING_ABSORPTION_CONFIG, true, LLSD::TypeArray, &validateAbsorptionLayers));
@ -728,7 +725,7 @@ LLSD LLSettingsSky::defaults(const LLSettingsBase::TrackPosition& position)
dfltsetting[SETTING_CLOUD_POS_DENSITY1] = LLColor4(1.0000f, 0.5260f, 1.0000f, 0.0f).getValue();
dfltsetting[SETTING_CLOUD_POS_DENSITY2] = LLColor4(1.0000f, 0.5260f, 1.0000f, 0.0f).getValue();
dfltsetting[SETTING_CLOUD_SCALE] = LLSD::Real(0.4199);
dfltsetting[SETTING_CLOUD_SCROLL_RATE] = LLSDArray(0.0f)(0.0f);
dfltsetting[SETTING_CLOUD_SCROLL_RATE] = llsd::array(0.0f, 0.0f);
dfltsetting[SETTING_CLOUD_SHADOW] = LLSD::Real(0.2699);
dfltsetting[SETTING_CLOUD_VARIANCE] = LLSD::Real(0.0);

View File

@ -222,42 +222,38 @@ LLSettingsWater::validation_list_t LLSettingsWater::validationList()
static validation_list_t validation;
if (validation.empty())
{ // Note the use of LLSD(LLSDArray()()()...) This is due to an issue with the
// copy constructor for LLSDArray. Directly binding the LLSDArray as
// a parameter without first wrapping it in a pure LLSD object will result
// in deeply nested arrays like this [[[[[[[[[[v1,v2,v3]]]]]]]]]]
{
validation.push_back(Validator(SETTING_BLUR_MULTIPLIER, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(-0.5f)(0.5f)))));
boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(-0.5f, 0.5f))));
validation.push_back(Validator(SETTING_FOG_COLOR, true, LLSD::TypeArray,
boost::bind(&Validator::verifyVectorMinMax, _1, _2,
LLSD(LLSDArray(0.0f)(0.0f)(0.0f)(1.0f)),
LLSD(LLSDArray(1.0f)(1.0f)(1.0f)(1.0f)))));
llsd::array(0.0f, 0.0f, 0.0f, 1.0f),
llsd::array(1.0f, 1.0f, 1.0f, 1.0f))));
validation.push_back(Validator(SETTING_FOG_DENSITY, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(-10.0f)(10.0f)))));
boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(-10.0f, 10.0f))));
validation.push_back(Validator(SETTING_FOG_MOD, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(20.0f)))));
boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 20.0f))));
validation.push_back(Validator(SETTING_FRESNEL_OFFSET, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(1.0f)))));
boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f))));
validation.push_back(Validator(SETTING_FRESNEL_SCALE, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(1.0f)))));
boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f))));
validation.push_back(Validator(SETTING_NORMAL_MAP, true, LLSD::TypeUUID));
validation.push_back(Validator(SETTING_NORMAL_SCALE, true, LLSD::TypeArray,
boost::bind(&Validator::verifyVectorMinMax, _1, _2,
LLSD(LLSDArray(0.0f)(0.0f)(0.0f)),
LLSD(LLSDArray(10.0f)(10.0f)(10.0f)))));
llsd::array(0.0f, 0.0f, 0.0f),
llsd::array(10.0f, 10.0f, 10.0f))));
validation.push_back(Validator(SETTING_SCALE_ABOVE, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(3.0f)))));
boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 3.0f))));
validation.push_back(Validator(SETTING_SCALE_BELOW, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(3.0f)))));
boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 3.0f))));
validation.push_back(Validator(SETTING_WAVE1_DIR, true, LLSD::TypeArray,
boost::bind(&Validator::verifyVectorMinMax, _1, _2,
LLSD(LLSDArray(-20.0f)(-20.0f)),
LLSD(LLSDArray(20.0f)(20.0f)))));
llsd::array(-20.0f, -20.0f),
llsd::array(20.0f, 20.0f))));
validation.push_back(Validator(SETTING_WAVE2_DIR, true, LLSD::TypeArray,
boost::bind(&Validator::verifyVectorMinMax, _1, _2,
LLSD(LLSDArray(-20.0f)(-20.0f)),
LLSD(LLSDArray(20.0f)(20.0f)))));
llsd::array(-20.0f, -20.0f),
llsd::array(20.0f, 20.0f))));
}
return validation;

View File

@ -3377,12 +3377,12 @@ BOOL LLVolume::isFlat(S32 face)
bool LLVolumeParams::isSculpt() const
{
return mSculptID.notNull();
return (mSculptType & LL_SCULPT_TYPE_MASK) != LL_SCULPT_TYPE_NONE;
}
bool LLVolumeParams::isMeshSculpt() const
{
return isSculpt() && ((mSculptType & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH);
return (mSculptType & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH;
}
bool LLVolumeParams::operator==(const LLVolumeParams &params) const
@ -3801,6 +3801,7 @@ void LLVolume::getLoDTriangleCounts(const LLVolumeParams& params, S32* counts, L
// </FS:ND>
{ //attempt to approximate the number of triangles that will result from generating a volume LoD set for the
//supplied LLVolumeParams -- inaccurate, but a close enough approximation for determining streaming cost
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
// <FS:ND> check cache first
if( aVolume->mTrianglesCache && aVolume->mTrianglesCache->mPathParams == params.getPathParams() && aVolume->mTrianglesCache->mProfileParams == params.getProfileParams() )

View File

@ -167,6 +167,7 @@ public:
// set the contents of this LLGLTFMaterial from the given json
// returns true if successful
// if unsuccessful, the contents of this LLGLTFMaterial should be left unchanged and false is returned
// json - the json text to load from
// warn_msg - warning message from TinyGLTF if any
// error_msg - error_msg from TinyGLTF if any

View File

@ -2371,11 +2371,6 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
static bool sHandleDoubleClick = true;
LLWindowWin32* window_imp = (LLWindowWin32*)GetWindowLongPtr(h_wnd, GWLP_USERDATA);
//<FS:Beq> avoid unfortunate sleep during trylock by static check
// bool debug_window_proc = false; // gDebugWindowProc || debugLoggingEnabled("Window");
// static auto debug_logging_on = debugLoggingEnabled("Window");
bool debug_window_proc = false; // gDebugWindowProc || debug_logging_on;
//</FS:Beq>
if (NULL != window_imp)
{
@ -2403,11 +2398,8 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
case WM_DEVICECHANGE:
{
LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_DEVICECHANGE");
if (debug_window_proc)
{
LL_INFOS("Window") << " WM_DEVICECHANGE: wParam=" << w_param
<< "; lParam=" << l_param << LL_ENDL;
}
LL_INFOS("Window") << " WM_DEVICECHANGE: wParam=" << w_param
<< "; lParam=" << l_param << LL_ENDL;
if (w_param == DBT_DEVNODES_CHANGED || w_param == DBT_DEVICEARRIVAL)
{
WINDOW_IMP_POST(window_imp->mCallbacks->handleDeviceChange(window_imp));
@ -2471,14 +2463,11 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
BOOL activating = (BOOL)w_param;
BOOL minimized = window_imp->getMinimized();
if (debug_window_proc)
{
LL_INFOS("Window") << "WINDOWPROC ActivateApp "
<< " activating " << S32(activating)
<< " minimized " << S32(minimized)
<< " fullscreen " << S32(window_imp->mFullscreen)
<< LL_ENDL;
}
LL_INFOS("Window") << "WINDOWPROC ActivateApp "
<< " activating " << S32(activating)
<< " minimized " << S32(minimized)
<< " fullscreen " << S32(window_imp->mFullscreen)
<< LL_ENDL;
if (window_imp->mFullscreen)
{
@ -2523,13 +2512,10 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
// JC - I'm not sure why, but if we don't report that we handled the
// WM_ACTIVATE message, the WM_ACTIVATEAPP messages don't work
// properly when we run fullscreen.
if (debug_window_proc)
{
LL_INFOS("Window") << "WINDOWPROC Activate "
<< " activating " << S32(activating)
<< " minimized " << S32(minimized)
<< LL_ENDL;
}
LL_INFOS("Window") << "WINDOWPROC Activate "
<< " activating " << S32(activating)
<< " minimized " << S32(minimized)
<< LL_ENDL;
});
break;
@ -2608,12 +2594,9 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
window_imp->mRawLParam = l_param;
{
if (debug_window_proc)
{
LL_INFOS("Window") << "Debug WindowProc WM_KEYDOWN "
<< " key " << S32(w_param)
<< LL_ENDL;
}
LL_INFOS("Window") << "Debug WindowProc WM_KEYDOWN "
<< " key " << S32(w_param)
<< LL_ENDL;
gKeyboard->handleKeyDown(w_param, mask);
}
@ -2638,12 +2621,9 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
{
LL_RECORD_BLOCK_TIME(FTM_KEYHANDLER);
if (debug_window_proc)
{
LL_INFOS("Window") << "Debug WindowProc WM_KEYUP "
<< " key " << S32(w_param)
<< LL_ENDL;
}
LL_INFOS("Window") << "Debug WindowProc WM_KEYUP "
<< " key " << S32(w_param)
<< LL_ENDL;
gKeyboard->handleKeyUp(w_param, mask);
}
});
@ -2653,10 +2633,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
case WM_IME_SETCONTEXT:
{
LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_IME_SETCONTEXT");
if (debug_window_proc)
{
LL_INFOS("Window") << "WM_IME_SETCONTEXT" << LL_ENDL;
}
LL_INFOS("Window") << "WM_IME_SETCONTEXT" << LL_ENDL;
if (LLWinImm::isAvailable() && window_imp->mPreeditor)
{
l_param &= ~ISC_SHOWUICOMPOSITIONWINDOW;
@ -2667,10 +2644,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
case WM_IME_STARTCOMPOSITION:
{
LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_IME_STARTCOMPOSITION");
if (debug_window_proc)
{
LL_INFOS() << "WM_IME_STARTCOMPOSITION" << LL_ENDL;
}
LL_INFOS("Window") << "WM_IME_STARTCOMPOSITION" << LL_ENDL;
if (LLWinImm::isAvailable() && window_imp->mPreeditor)
{
WINDOW_IMP_POST(window_imp->handleStartCompositionMessage());
@ -2681,10 +2655,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
case WM_IME_ENDCOMPOSITION:
{
LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_IME_ENDCOMPOSITION");
if (debug_window_proc)
{
LL_INFOS() << "WM_IME_ENDCOMPOSITION" << LL_ENDL;
}
LL_INFOS("Window") << "WM_IME_ENDCOMPOSITION" << LL_ENDL;
if (LLWinImm::isAvailable() && window_imp->mPreeditor)
{
return 0;
@ -2694,10 +2665,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
case WM_IME_COMPOSITION:
{
LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_IME_COMPOSITION");
if (debug_window_proc)
{
LL_INFOS() << "WM_IME_COMPOSITION" << LL_ENDL;
}
LL_INFOS("Window") << "WM_IME_COMPOSITION" << LL_ENDL;
if (LLWinImm::isAvailable() && window_imp->mPreeditor)
{
WINDOW_IMP_POST(window_imp->handleCompositionMessage(l_param));
@ -2708,10 +2676,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
case WM_IME_REQUEST:
{
LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_IME_REQUEST");
if (debug_window_proc)
{
LL_INFOS() << "WM_IME_REQUEST" << LL_ENDL;
}
LL_INFOS("Window") << "WM_IME_REQUEST" << LL_ENDL;
if (LLWinImm::isAvailable() && window_imp->mPreeditor)
{
LRESULT result;
@ -2740,12 +2705,9 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
// it is worth trying. The good old WM_CHAR works just fine even for supplementary
// characters. We just need to take care of surrogate pairs sent as two WM_CHAR's
// by ourselves. It is not that tough. -- Alissa Sabre @ SL
if (debug_window_proc)
{
LL_INFOS("Window") << "Debug WindowProc WM_CHAR "
<< " key " << S32(w_param)
<< LL_ENDL;
}
LL_INFOS("Window") << "Debug WindowProc WM_CHAR "
<< " key " << S32(w_param)
<< LL_ENDL;
// Even if LLWindowCallbacks::handleUnicodeChar(llwchar, BOOL) returned FALSE,
// we *did* processed the event, so I believe we should not pass it to DefWindowProc...
window_imp->handleUnicodeUTF16((U16)w_param, gKeyboard->currentMask(FALSE));
@ -3073,19 +3035,17 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
S32 height = S32(HIWORD(l_param));
if (debug_window_proc)
{
BOOL maximized = (w_param == SIZE_MAXIMIZED);
BOOL restored = (w_param == SIZE_RESTORED);
BOOL minimized = (w_param == SIZE_MINIMIZED);
LL_INFOS("Window");
BOOL maximized = (w_param == SIZE_MAXIMIZED);
BOOL restored = (w_param == SIZE_RESTORED);
BOOL minimized = (w_param == SIZE_MINIMIZED);
LL_INFOS("Window") << "WINDOWPROC Size "
<< width << "x" << height
<< " max " << S32(maximized)
<< " min " << S32(minimized)
<< " rest " << S32(restored)
<< LL_ENDL;
}
LL_CONT << "WINDOWPROC Size "
<< width << "x" << height
<< " max " << S32(maximized)
<< " min " << S32(minimized)
<< " rest " << S32(restored);
LL_ENDL;
// There's an odd behavior with WM_SIZE that I would call a bug. If
// the window is maximized, and you call MoveWindow() with a size smaller
@ -3151,10 +3111,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
case WM_SETFOCUS:
{
LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_SETFOCUS");
if (debug_window_proc)
{
LL_INFOS("Window") << "WINDOWPROC SetFocus" << LL_ENDL;
}
LL_INFOS("Window") << "WINDOWPROC SetFocus" << LL_ENDL;
// <FS:Ansariel> Stop flashing when we gain focus
if (window_imp->mWindowHandle)
@ -3176,10 +3133,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
case WM_KILLFOCUS:
{
LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_KILLFOCUS");
if (debug_window_proc)
{
LL_INFOS("Window") << "WINDOWPROC KillFocus" << LL_ENDL;
}
LL_INFOS("Window") << "WINDOWPROC KillFocus" << LL_ENDL;
WINDOW_IMP_POST(window_imp->mCallbacks->handleFocusLost(window_imp));
return 0;
}
@ -3300,10 +3254,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
default:
{
LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - default");
if (debug_window_proc)
{
LL_INFOS("Window") << "Unhandled windows message code: 0x" << std::hex << U32(u_msg) << LL_ENDL;
}
LL_INFOS("Window") << "Unhandled windows message code: 0x" << std::hex << U32(u_msg) << LL_ENDL;
}
break;
}

View File

@ -64,11 +64,11 @@ GroupChatListener::GroupChatListener():
"Leave a group chat in group with UUID [\"id\"]\n"
"Assumes a prior successful startIM request.",
&LLGroupActions::endIM,
LLSDArray("id"));
add("sendIM",
"send a groupchat IM",
&send_message_wrapper,
LLSDArray("text")("session_id")("group_id"));
llsd::array("id"));
add("sendIM",
"send a groupchat IM",
&send_message_wrapper,
llsd::array("text", "session_id", "group_id"));
}
/*
static void sendMessage(const std::string& utf8_text, const LLUUID& im_session_id,

View File

@ -3748,17 +3748,18 @@ LLSD LLAppViewer::getViewerInfo() const
// LLFloaterAbout.
LLSD info;
auto& versionInfo(LLVersionInfo::instance());
info["VIEWER_VERSION"] = LLSDArray(versionInfo.getMajor())(versionInfo.getMinor())(versionInfo.getPatch())(versionInfo.getBuild());
info["VIEWER_VERSION"] = llsd::array(versionInfo.getMajor(), versionInfo.getMinor(),
versionInfo.getPatch(), versionInfo.getBuild());
info["VIEWER_VERSION_STR"] = versionInfo.getVersion();
info["BUILD_DATE"] = __DATE__;
info["BUILD_TIME"] = __TIME__;
info["CHANNEL"] = versionInfo.getChannel();
info["ADDRESS_SIZE"] = ADDRESS_SIZE;
// std::string build_config = versionInfo.getBuildConfig();
//if (build_config != "Release")
//{
// info["BUILD_CONFIG"] = build_config;
//}
info["ADDRESS_SIZE"] = ADDRESS_SIZE;
//std::string build_config = versionInfo.getBuildConfig();
//if (build_config != "Release")
//{
// info["BUILD_CONFIG"] = build_config;
//}
#ifdef USE_AVX2_OPTIMIZATION
info["SIMD"] = "AVX2";
#elif USE_AVX_OPTIMIZATION

View File

@ -840,19 +840,21 @@ bool LLAppViewerWin32::init()
LL_VIEWER_VERSION_BUILD));
// <FS:ND> Set up Bugsplat to ask or always send
//DWORD dwFlags = MDSF_NONINTERACTIVE | // automatically submit report without prompting
// MDSF_PREVENTHIJACKING; // disallow swiping Exception filter
DWORD dwFlags = dwAsk |
MDSF_PREVENTHIJACKING; // disallow swiping Exception filter
//DWORD dwFlags = MDSF_NONINTERACTIVE | // automatically submit report without prompting
// MDSF_PREVENTHIJACKING; // disallow swiping Exception filter
DWORD dwFlags = dwAsk |
MDSF_PREVENTHIJACKING; // disallow swiping Exception filter
// </FS:ND>
//bool needs_log_file = !isSecondInstance() && debugLoggingEnabled("BUGSPLAT");
//if (needs_log_file)
//{
// // Startup only!
// LL_INFOS("BUGSPLAT") << "Engaged BugSplat logging to bugsplat.log" << LL_ENDL;
// dwFlags |= MDSF_LOGFILE | MDSF_LOG_VERBOSE;
//}
//bool needs_log_file = !isSecondInstance();
//LL_DEBUGS("BUGSPLAT");
//if (needs_log_file)
//{
// // Startup only!
// LL_INFOS("BUGSPLAT") << "Engaged BugSplat logging to bugsplat.log" << LL_ENDL;
// dwFlags |= MDSF_LOGFILE | MDSF_LOG_VERBOSE;
//}
//LL_ENDL;
// have to convert normal wide strings to strings of __wchar_t
sBugSplatSender = new MiniDmpSender(
@ -864,12 +866,14 @@ bool LLAppViewerWin32::init()
sBugSplatSender->setCallback(bugsplatSendLog);
//if (needs_log_file)
//{
// // Log file will be created in %TEMP%, but it will be moved into logs folder in case of crash
// std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "bugsplat.log");
// sBugSplatSender->setLogFilePath(WCSTR(log_file));
//}
//LL_DEBUGS("BUGSPLAT");
//if (needs_log_file)
//{
// // Log file will be created in %TEMP%, but it will be moved into logs folder in case of crash
// std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "bugsplat.log");
// sBugSplatSender->setLogFilePath(WCSTR(log_file));
//}
//LL_ENDL;
// engage stringize() overload that converts from wstring
LL_INFOS("BUGSPLAT") << "Engaged BugSplat(" << LL_TO_STRING(LL_VIEWER_CHANNEL)

View File

@ -530,7 +530,7 @@ void LLFloaterEditSky::refreshSkyPresetsList()
for (LLEnvironment::list_name_id_t::iterator it = list.begin(); it != list.end(); ++it)
{
mSkyPresetCombo->add((*it).first, LLSDArray((*it).first)((*it).second));
mSkyPresetCombo->add((*it).first, llsd::array((*it).first, (*it).second));
}
mSkyPresetCombo->setLabel(getString("combo_label"));

View File

@ -335,7 +335,7 @@ void LLFloaterEditWater::refreshWaterPresetsList()
for (LLEnvironment::list_name_id_t::iterator it = list.begin(); it != list.end(); ++it)
{
mWaterPresetCombo->add((*it).first, LLSDArray((*it).first)((*it).second));
mWaterPresetCombo->add((*it).first, llsd::array((*it).first, (*it).second));
}
mWaterPresetCombo->setLabel(getString("combo_label"));

View File

@ -572,26 +572,21 @@ void LLFloaterInspect::refresh()
attachment_volume_cost += volume->getRenderCost(textures);
LLViewerObject::const_child_list_t children = volume->getChildren();
for (LLViewerObject::const_child_list_t::const_iterator child_iter = children.begin();
child_iter != children.end();
++child_iter)
for (const auto& child_obj : volume->getChildren())
{
LLViewerObject* child_obj = *child_iter;
LLVOVolume *child = dynamic_cast<LLVOVolume*>(child_obj);
LLVOVolume *child = dynamic_cast<LLVOVolume*>(child_obj.get());
if (child)
{
attachment_children_cost += child->getRenderCost(textures);
}
}
for (LLVOVolume::texture_cost_t::iterator volume_texture = textures.begin();
volume_texture != textures.end();
++volume_texture)
for (auto texture : textures)
{
// add the cost of each individual texture in the linkset
attachment_texture_cost += volume_texture->second;
attachment_texture_cost += LLVOVolume::getTextureCost(texture);
}
attachment_total_cost = attachment_volume_cost + attachment_texture_cost + attachment_children_cost;
// Limit attachment complexity to avoid signed integer flipping of the wearer's ACI

View File

@ -219,40 +219,36 @@ public:
struct ReturnData
{
public:
LLPointer<LLGLTFMaterial> mMaterial;
LLGLTFMaterial mMaterial;
S32 mSide;
bool mSuccess;
};
// fromJson() is performance heavy offload to a thread.
main_queue->postTo(
general_queue,
[object_override]() // Work done on general queue
if (!object_override.mSides.empty())
{
std::vector<ReturnData> results;
if (!object_override.mSides.empty())
// fromJson() is performance heavy offload to a thread.
main_queue->postTo(
general_queue,
[sides=object_override.mSides]() // Work done on general queue
{
results.reserve(object_override.mSides.size());
std::vector<ReturnData> results;
results.reserve(sides.size());
// parse json
std::unordered_map<S32, std::string>::const_iterator iter = object_override.mSides.begin();
std::unordered_map<S32, std::string>::const_iterator end = object_override.mSides.end();
std::unordered_map<S32, std::string>::const_iterator iter = sides.begin();
std::unordered_map<S32, std::string>::const_iterator end = sides.end();
while (iter != end)
{
LLPointer<LLGLTFMaterial> override_data = new LLGLTFMaterial();
std::string warn_msg, error_msg;
bool success = override_data->fromJSON(iter->second, warn_msg, error_msg);
ReturnData result;
bool success = result.mMaterial.fromJSON(iter->second, warn_msg, error_msg);
result.mSuccess = success;
result.mSide = iter->first;
if (success)
{
result.mMaterial = override_data;
}
else
if (!success)
{
LL_WARNS("GLTF") << "failed to parse GLTF override data. errors: " << error_msg << " | warnings: " << warn_msg << LL_ENDL;
}
@ -260,64 +256,68 @@ public:
results.push_back(result);
iter++;
}
}
return results;
},
[object_override, this](std::vector<ReturnData> results) // Callback to main thread
return results;
},
[object_id=object_override.mObjectId, this](std::vector<ReturnData> results) // Callback to main thread
{
LLViewerObject * obj = gObjectList.findObject(object_override.mObjectId);
LLViewerObject * obj = gObjectList.findObject(object_id);
if (results.size() > 0 )
{
std::unordered_set<S32> side_set;
for (int i = 0; i < results.size(); ++i)
if (results.size() > 0 )
{
if (results[i].mSuccess)
{
// flag this side to not be nulled out later
side_set.insert(results[i].mSide);
std::unordered_set<S32> side_set;
if (obj)
for (auto const & result : results)
{
S32 side = result.mSide;
if (result.mSuccess)
{
obj->setTEGLTFMaterialOverride(results[i].mSide, results[i].mMaterial);
// copy to heap here because LLTextureEntry is going to take ownership with an LLPointer
LLGLTFMaterial * material = new LLGLTFMaterial(result.mMaterial);
// flag this side to not be nulled out later
side_set.insert(side);
if (obj)
{
obj->setTEGLTFMaterialOverride(side, material);
}
}
// unblock material editor
if (obj && obj->getTE(side) && obj->getTE(side)->isSelected())
{
doSelectionCallbacks(object_id, side);
}
}
// unblock material editor
if (obj && obj->getTE(results[i].mSide) && obj->getTE(results[i].mSide)->isSelected())
{
doSelectionCallbacks(object_override.mObjectId, results[i].mSide);
}
}
if (obj && side_set.size() != obj->getNumTEs())
{ // object exists and at least one texture entry needs to have its override data nulled out
for (int i = 0; i < obj->getNumTEs(); ++i)
{
if (side_set.find(i) == side_set.end())
if (obj && side_set.size() != obj->getNumTEs())
{ // object exists and at least one texture entry needs to have its override data nulled out
for (int i = 0; i < obj->getNumTEs(); ++i)
{
obj->setTEGLTFMaterialOverride(i, nullptr);
if (obj->getTE(i) && obj->getTE(i)->isSelected())
if (side_set.find(i) == side_set.end())
{
doSelectionCallbacks(object_override.mObjectId, i);
obj->setTEGLTFMaterialOverride(i, nullptr);
if (obj->getTE(i) && obj->getTE(i)->isSelected())
{
doSelectionCallbacks(object_id, i);
}
}
}
}
}
}
else if (obj)
{ // override list was empty or an error occurred, null out all overrides for this object
for (int i = 0; i < obj->getNumTEs(); ++i)
{
obj->setTEGLTFMaterialOverride(i, nullptr);
if (obj->getTE(i) && obj->getTE(i)->isSelected())
else if (obj)
{ // override list was empty or an error occurred, null out all overrides for this object
for (int i = 0; i < obj->getNumTEs(); ++i)
{
doSelectionCallbacks(obj->getID(), i);
obj->setTEGLTFMaterialOverride(i, nullptr);
if (obj->getTE(i) && obj->getTE(i)->isSelected())
{
doSelectionCallbacks(obj->getID(), i);
}
}
}
}
});
});
}
}
private:
@ -433,6 +433,19 @@ void LLGLTFMaterialList::queueApply(const LLViewerObject* obj, S32 side, const L
}
}
void LLGLTFMaterialList::queueApply(const LLViewerObject* obj, S32 side, const LLUUID& asset_id, const LLGLTFMaterial* material_override)
{
if (asset_id.isNull() || material_override == nullptr)
{
queueApply(obj, side, asset_id);
}
else
{
LLGLTFMaterial* material = new LLGLTFMaterial(*material_override);
sApplyQueue.push_back({ obj->getID(), side, asset_id, material });
}
}
void LLGLTFMaterialList::queueUpdate(const LLSD& data)
{
llassert(is_valid_update(data));
@ -477,7 +490,7 @@ void LLGLTFMaterialList::flushUpdates(void(*done_callback)(bool))
}
sModifyQueue.clear();
for (auto& e : sApplyQueue)
for (ApplyMaterialAssetData& e : sApplyQueue)
{
data[i]["object_id"] = e.object_id;
data[i]["side"] = e.side;

View File

@ -70,6 +70,13 @@ public:
// NOTE: Implicitly clears most override data if present
static void queueApply(const LLViewerObject* obj, S32 side, const LLUUID& asset_id);
// Queue an application of a material asset we want to send to the simulator. Call "flushUpdates" to flush pending updates.
// object_id - ID of object to apply material asset to
// side - TextureEntry index to apply material to, or -1 for all sides
// asset_id - ID of material asset to apply, or LLUUID::null to disassociate current material asset
// mat - override material, if null, will clear most override data
static void queueApply(const LLViewerObject* obj, S32 side, const LLUUID& asset_id, const LLGLTFMaterial* mat);
// flush pending material updates to the simulator
// Automatically called once per frame, but may be called explicitly
// for cases that care about the done_callback forwarded to LLCoros::instance().launch

View File

@ -1412,10 +1412,11 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id, bool can_retry)
if (header_size > 0)
{
const LLSD& header = header_it->second.second;
S32 version = header["version"].asInteger();
S32 offset = header_size + header["skin"]["offset"].asInteger();
S32 size = header["skin"]["size"].asInteger();
const LLMeshHeader& header = header_it->second.second;
S32 version = header.mVersion;
S32 offset = header_size + header.mSkinOffset;
S32 size = header.mSkinSize;
mHeaderMutex->unlock();
@ -1533,9 +1534,9 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)
if (header_size > 0)
{
const auto& header = header_it->second.second;
S32 version = header["version"].asInteger();
S32 offset = header_size + header["physics_convex"]["offset"].asInteger();
S32 size = header["physics_convex"]["size"].asInteger();
S32 version = header.mVersion;
S32 offset = header_size + header.mPhysicsConvexOffset;
S32 size = header.mPhysicsConvexSize;
mHeaderMutex->unlock();
@ -1639,9 +1640,9 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
if (header_size > 0)
{
const auto& header = header_it->second.second;
S32 version = header["version"].asInteger();
S32 offset = header_size + header["physics_mesh"]["offset"].asInteger();
S32 size = header["physics_mesh"]["size"].asInteger();
S32 version = header.mVersion;
S32 offset = header_size + header.mPhysicsMeshOffset;
S32 size = header.mPhysicsMeshSize;
mHeaderMutex->unlock();
@ -1851,9 +1852,9 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod,
if (header_size > 0)
{
const auto& header = header_it->second.second;
S32 version = header["version"].asInteger();
S32 offset = header_size + header[header_lod[lod]]["offset"].asInteger();
S32 size = header[header_lod[lod]]["size"].asInteger();
S32 version = header.mVersion;
S32 offset = header_size + header.mLodOffset[lod];
S32 size = header.mLodSize[lod];
mHeaderMutex->unlock();
if (version <= MAX_MESH_VERSION && offset >= 0 && size > 0)
@ -1962,8 +1963,10 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod,
EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size)
{
const LLUUID mesh_id = mesh_params.getSculptID();
LLSD header;
LLSD header_data;
LLMeshHeader header;
U32 header_size = 0;
if (data_size > 0)
{
@ -1974,23 +1977,25 @@ EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mes
boost::iostreams::stream<boost::iostreams::array_source> stream(result_ptr, data_size);
if (!LLSDSerialize::fromBinary(header, stream, data_size))
if (!LLSDSerialize::fromBinary(header_data, stream, data_size))
{
LL_WARNS(LOG_MESH) << "Mesh header parse error. Not a valid mesh asset! ID: " << mesh_id
<< LL_ENDL;
return MESH_PARSE_FAILURE;
}
if (!header.isMap())
if (!header_data.isMap())
{
LL_WARNS(LOG_MESH) << "Mesh header is invalid for ID: " << mesh_id << LL_ENDL;
return MESH_INVALID;
}
if (header.has("version") && header["version"].asInteger() > MAX_MESH_VERSION)
header.fromLLSD(header_data);
if (header.mVersion > MAX_MESH_VERSION)
{
LL_INFOS(LOG_MESH) << "Wrong version in header for " << mesh_id << LL_ENDL;
header["404"] = 1;
header.m404 = true;
}
// make sure there is at least one lod, function returns -1 and marks as 404 otherwise
else if (LLMeshRepository::getActualMeshLOD(header, 0) >= 0)
@ -2002,7 +2007,7 @@ EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mes
{
LL_INFOS(LOG_MESH) << "Non-positive data size. Marking header as non-existent, will not retry. ID: " << mesh_id
<< LL_ENDL;
header["404"] = 1;
header.m404 = 1;
}
{
@ -2012,7 +2017,6 @@ EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mes
mMeshHeader[mesh_id] = { header_size, header };
LLMeshRepository::sCacheBytesHeaders += header_size;
}
LLMutexLock lock(mMutex); // make sure only one thread access mPendingLOD at the same time.
@ -3082,7 +3086,7 @@ S32 LLMeshRepoThread::getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lo
if (iter != mMeshHeader.end())
{
LLSD& header = iter->second.second;
auto& header = iter->second.second;
return LLMeshRepository::getActualMeshLOD(header, lod);
}
@ -3091,26 +3095,23 @@ S32 LLMeshRepoThread::getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lo
}
//static
S32 LLMeshRepository::getActualMeshLOD(LLSD& header, S32 lod)
S32 LLMeshRepository::getActualMeshLOD(LLMeshHeader& header, S32 lod)
{
lod = llclamp(lod, 0, 3);
if (header.has("404"))
if (header.m404)
{
return -1;
}
// <FS:Ansariel> OpenSim mesh fix
//S32 version = header["version"];
S32 version = header["version"].asInteger();
// </FS:Ansariel>
S32 version = header.mVersion;
if (version > MAX_MESH_VERSION)
{
return -1;
}
if (header[header_lod[lod]]["size"].asInteger() > 0)
if (header.mLodSize[lod] > 0)
{
return lod;
}
@ -3118,7 +3119,7 @@ S32 LLMeshRepository::getActualMeshLOD(LLSD& header, S32 lod)
//search down to find the next available lower lod
for (S32 i = lod-1; i >= 0; --i)
{
if (header[header_lod[i]]["size"].asInteger() > 0)
if (header.mLodSize[i] > 0)
{
return i;
}
@ -3127,15 +3128,16 @@ S32 LLMeshRepository::getActualMeshLOD(LLSD& header, S32 lod)
//search up to find then ext available higher lod
for (S32 i = lod+1; i < 4; ++i)
{
if (header[header_lod[i]]["size"].asInteger() > 0)
if (header.mLodSize[i] > 0)
{
return i;
}
}
//header exists and no good lod found, treat as 404
header["404"] = 1;
return -1;
header.m404 = true;
return -1;
}
// Handle failed or successful requests for mesh assets.
@ -3324,7 +3326,7 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
{
// header was successfully retrieved from sim and parsed and is in cache
S32 header_bytes = 0;
LLSD header;
LLMeshHeader header;
gMeshRepo.mThread->mHeaderMutex->lock();
LLMeshRepoThread::mesh_header_map::iterator iter = gMeshRepo.mThread->mMeshHeader.find(mesh_id);
@ -3335,8 +3337,8 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
}
if (header_bytes > 0
&& !header.has("404")
&& (!header.has("version") || header["version"].asInteger() <= MAX_MESH_VERSION))
&& !header.m404
&& (header.mVersion <= MAX_MESH_VERSION))
{
std::stringstream str;
@ -3345,13 +3347,12 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
for (U32 i = 0; i < LLModel::LOD_PHYSICS; ++i)
{
// figure out how many bytes we'll need to reserve in the file
const std::string & lod_name = header_lod[i];
lod_bytes = llmax(lod_bytes, header[lod_name]["offset"].asInteger()+header[lod_name]["size"].asInteger());
lod_bytes = llmax(lod_bytes, header.mLodOffset[i]+header.mLodSize[i]);
}
// just in case skin info or decomposition is at the end of the file (which it shouldn't be)
lod_bytes = llmax(lod_bytes, header["skin"]["offset"].asInteger() + header["skin"]["size"].asInteger());
lod_bytes = llmax(lod_bytes, header["physics_convex"]["offset"].asInteger() + header["physics_convex"]["size"].asInteger());
lod_bytes = llmax(lod_bytes, header.mSkinOffset+header.mSkinSize);
lod_bytes = llmax(lod_bytes, header.mPhysicsConvexOffset + header.mPhysicsConvexSize);
// Do not unlock mutex untill we are done with LLSD.
// LLSD is smart and can work like smart pointer, is not thread safe.
@ -4436,8 +4437,8 @@ bool LLMeshRepoThread::hasPhysicsShapeInHeader(const LLUUID& mesh_id)
mesh_header_map::iterator iter = mMeshHeader.find(mesh_id);
if (iter != mMeshHeader.end() && iter->second.first > 0)
{
LLSD &mesh = iter->second.second;
if (mesh.has("physics_mesh") && mesh["physics_mesh"].has("size") && (mesh["physics_mesh"]["size"].asInteger() > 0))
LLMeshHeader &mesh = iter->second.second;
if (mesh.mPhysicsMeshSize > 0)
{
return true;
}
@ -4463,11 +4464,8 @@ LLUUID LLMeshRepoThread::getCreatorFromHeader(const LLUUID& mesh_id)
mesh_header_map::iterator iter = mMeshHeader.find(mesh_id);
if (iter != mMeshHeader.end() && iter->second.first > 0)
{
LLSD& mesh = iter->second.second;
if (mesh.has("creator") && mesh["creator"].isUUID())
{
return mesh["creator"].asUUID();
}
LLMeshHeader& mesh = iter->second.second;
return mesh.mCreatorId;
}
return LLUUID();
@ -4487,20 +4485,21 @@ void LLMeshRepository::uploadModel(std::vector<LLModelInstance>& data, LLVector3
S32 LLMeshRepository::getMeshSize(const LLUUID& mesh_id, S32 lod)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
if (mThread && mesh_id.notNull() && LLPrimitive::NO_LOD != lod)
{
LLMutexLock lock(mThread->mHeaderMutex);
LLMeshRepoThread::mesh_header_map::iterator iter = mThread->mMeshHeader.find(mesh_id);
if (iter != mThread->mMeshHeader.end() && iter->second.first > 0)
{
const LLSD& header = iter->second.second;
const LLMeshHeader& header = iter->second.second;
if (header.has("404"))
if (header.m404)
{
return -1;
}
S32 size = header[header_lod[lod]]["size"].asInteger();
S32 size = header.mLodSize[lod];
return size;
}
@ -4636,14 +4635,11 @@ F32 LLMeshRepository::getStreamingCostLegacy(LLUUID mesh_id, F32 radius, S32* by
// FIXME replace with calc based on LLMeshCostData
//static
F32 LLMeshRepository::getStreamingCostLegacy(LLSD& header, F32 radius, S32* bytes, S32* bytes_visible, S32 lod, F32 *unscaled_value)
F32 LLMeshRepository::getStreamingCostLegacy(LLMeshHeader& header, F32 radius, S32* bytes, S32* bytes_visible, S32 lod, F32 *unscaled_value)
{
if (header.has("404")
|| !header.has("lowest_lod")
// <FS:Ansariel> OpenSim mesh fix
//|| (header.has("version") && header["version"].asInteger() > MAX_MESH_VERSION))
|| ((header.has("version") || !LLGridManager::instance().isInSecondLife()) && header["version"].asInteger() > MAX_MESH_VERSION))
// </FS:Ansariel>
if (header.m404
|| header.mLodSize[0] <= 0
|| (header.mVersion > MAX_MESH_VERSION))
{
return 0.f;
}
@ -4662,10 +4658,10 @@ F32 LLMeshRepository::getStreamingCostLegacy(LLSD& header, F32 radius, S32* byte
F32 minimum_size = (F32)minimum_size_ch;
F32 bytes_per_triangle = (F32)bytes_per_triangle_ch;
S32 bytes_lowest = header["lowest_lod"]["size"].asInteger();
S32 bytes_low = header["low_lod"]["size"].asInteger();
S32 bytes_mid = header["medium_lod"]["size"].asInteger();
S32 bytes_high = header["high_lod"]["size"].asInteger();
S32 bytes_lowest = header.mLodSize[0];
S32 bytes_low = header.mLodSize[1];
S32 bytes_mid = header.mLodSize[2];
S32 bytes_high = header.mLodSize[3];
if (bytes_high == 0)
{
@ -4695,10 +4691,10 @@ F32 LLMeshRepository::getStreamingCostLegacy(LLSD& header, F32 radius, S32* byte
if (bytes)
{
*bytes = 0;
*bytes += header["lowest_lod"]["size"].asInteger();
*bytes += header["low_lod"]["size"].asInteger();
*bytes += header["medium_lod"]["size"].asInteger();
*bytes += header["high_lod"]["size"].asInteger();
*bytes += header.mLodSize[0];
*bytes += header.mLodSize[1];
*bytes += header.mLodSize[2];
*bytes += header.mLodSize[3];
}
if (bytes_visible)
@ -4706,7 +4702,7 @@ F32 LLMeshRepository::getStreamingCostLegacy(LLSD& header, F32 radius, S32* byte
lod = LLMeshRepository::getActualMeshLOD(header, lod);
if (lod >= 0 && lod <= 3)
{
*bytes_visible = header[header_lod[lod]]["size"].asInteger();
*bytes_visible = header.mLodSize[lod];
}
}
@ -4753,34 +4749,29 @@ F32 LLMeshRepository::getStreamingCostLegacy(LLSD& header, F32 radius, S32* byte
LLMeshCostData::LLMeshCostData()
{
mSizeByLOD.resize(4);
mEstTrisByLOD.resize(4);
std::fill(mSizeByLOD.begin(), mSizeByLOD.end(), 0);
std::fill(mEstTrisByLOD.begin(), mEstTrisByLOD.end(), 0.f);
}
bool LLMeshCostData::init(const LLSD& header)
bool LLMeshCostData::init(const LLMeshHeader& header)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
mSizeByLOD.resize(4);
mEstTrisByLOD.resize(4);
std::fill(mSizeByLOD.begin(), mSizeByLOD.end(), 0);
std::fill(mEstTrisByLOD.begin(), mEstTrisByLOD.end(), 0.f);
S32 bytes_high = header["high_lod"]["size"].asInteger();
S32 bytes_med = header["medium_lod"]["size"].asInteger();
S32 bytes_high = header.mLodSize[3];
S32 bytes_med = header.mLodSize[2];
if (bytes_med == 0)
{
bytes_med = bytes_high;
}
S32 bytes_low = header["low_lod"]["size"].asInteger();
S32 bytes_low = header.mLodSize[1];
if (bytes_low == 0)
{
bytes_low = bytes_med;
}
S32 bytes_lowest = header["lowest_lod"]["size"].asInteger();
S32 bytes_lowest = header.mLodSize[0];
if (bytes_lowest == 0)
{
bytes_lowest = bytes_low;
@ -4916,6 +4907,7 @@ F32 LLMeshCostData::getTriangleBasedStreamingCost()
bool LLMeshRepository::getCostData(LLUUID mesh_id, LLMeshCostData& data)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
data = LLMeshCostData();
if (mThread && mesh_id.notNull())
@ -4924,11 +4916,11 @@ bool LLMeshRepository::getCostData(LLUUID mesh_id, LLMeshCostData& data)
LLMeshRepoThread::mesh_header_map::iterator iter = mThread->mMeshHeader.find(mesh_id);
if (iter != mThread->mMeshHeader.end() && iter->second.first > 0)
{
LLSD& header = iter->second.second;
LLMeshHeader& header = iter->second.second;
bool header_invalid = (header.has("404")
|| !header.has("lowest_lod")
|| (header.has("version") && header["version"].asInteger() > MAX_MESH_VERSION));
bool header_invalid = (header.m404
|| header.mLodSize[0] <= 0
|| header.mVersion > MAX_MESH_VERSION);
if (!header_invalid)
{
return getCostData(header, data);
@ -4942,7 +4934,7 @@ bool LLMeshRepository::getCostData(LLUUID mesh_id, LLMeshCostData& data)
// <FS:ND> Use a const ref, just to make sure no one modifies header and we can pass a copy.
// bool LLMeshRepository::getCostData(LLSD& header, LLMeshCostData& data)
bool LLMeshRepository::getCostData(LLSD const& header, LLMeshCostData& data)
bool LLMeshRepository::getCostData(const LLMeshHeader& header, LLMeshCostData& data)
// </FS:ND>
{
data = LLMeshCostData();

View File

@ -194,6 +194,73 @@ private:
LLFrameTimer mTimer;
};
class LLMeshHeader
{
public:
LLMeshHeader() {}
explicit LLMeshHeader(const LLSD& header)
{
fromLLSD(header);
}
void fromLLSD(const LLSD& header)
{
const char* lod[] =
{
"lowest_lod",
"low_lod",
"medium_lod",
"high_lod"
};
mVersion = header["version"].asInteger();
for (U32 i = 0; i < 4; ++i)
{
mLodOffset[i] = header[lod[i]]["offset"].asInteger();
mLodSize[i] = header[lod[i]]["size"].asInteger();
}
mSkinOffset = header["skin"]["offset"].asInteger();
mSkinSize = header["skin"]["size"].asInteger();
mPhysicsConvexOffset = header["physics_convex"]["offset"].asInteger();
mPhysicsConvexSize = header["physics_convex"]["size"].asInteger();
mPhysicsMeshOffset = header["physics_mesh"]["offset"].asInteger();
mPhysicsMeshSize = header["physics_mesh"]["size"].asInteger();
m404 = header.has("404");
// <FS:Ansariel> DAE export
if (header.has("creator") && header["creator"].isUUID())
{
mCreatorId = header["creator"].asUUID();
}
// </FS:Ansariel>
}
S32 mVersion = -1;
S32 mSkinOffset = -1;
S32 mSkinSize = -1;
S32 mPhysicsConvexOffset = -1;
S32 mPhysicsConvexSize = -1;
S32 mPhysicsMeshOffset = -1;
S32 mPhysicsMeshSize = -1;
S32 mLodOffset[4] = { -1 };
S32 mLodSize[4] = { -1 };
bool m404 = false;
// <FS:Ansariel> DAE export
LLUUID mCreatorId{ LLUUID::null };
};
class LLMeshRepoThread : public LLThread
{
public:
@ -210,7 +277,7 @@ public:
LLCondition* mSignal;
//map of known mesh headers
typedef boost::unordered_map<LLUUID, std::pair<U32, LLSD>> mesh_header_map; // pair is header_size and data
typedef boost::unordered_map<LLUUID, std::pair<U32, LLMeshHeader>> mesh_header_map; // pair is header_size and data
mesh_header_map mMeshHeader;
class HeaderRequest : public RequestStats
@ -515,7 +582,7 @@ class LLMeshCostData
public:
LLMeshCostData();
bool init(const LLSD& header);
bool init(const LLMeshHeader& header);
// Size for given LOD
S32 getSizeByLOD(S32 lod);
@ -550,10 +617,10 @@ public:
private:
// From the "size" field of the mesh header. LOD 0=lowest, 3=highest.
std::vector<S32> mSizeByLOD;
std::array<S32,4> mSizeByLOD;
// Estimated triangle counts derived from the LOD sizes. LOD 0=lowest, 3=highest.
std::vector<F32> mEstTrisByLOD;
std::array<F32,4> mEstTrisByLOD;
};
class LLMeshRepository
@ -584,12 +651,11 @@ public:
F32 getEstTrianglesMax(LLUUID mesh_id);
F32 getEstTrianglesStreamingCost(LLUUID mesh_id);
F32 getStreamingCostLegacy(LLUUID mesh_id, F32 radius, S32* bytes = NULL, S32* visible_bytes = NULL, S32 detail = -1, F32 *unscaled_value = NULL);
static F32 getStreamingCostLegacy(LLSD& header, F32 radius, S32* bytes = NULL, S32* visible_bytes = NULL, S32 detail = -1, F32 *unscaled_value = NULL);
static F32 getStreamingCostLegacy(LLMeshHeader& header, F32 radius, S32* bytes = NULL, S32* visible_bytes = NULL, S32 detail = -1, F32 *unscaled_value = NULL);
bool getCostData(LLUUID mesh_id, LLMeshCostData& data);
// <FS:ND> Use a const ref, just to make sure no one modifies header and we can pass a copy.
// bool getCostData(LLSD& header, LLMeshCostData& data);
bool getCostData(LLSD const& header, LLMeshCostData& data);
// bool getCostData(LLMeshHeader& header, LLMeshCostData& data);
bool getCostData(const LLMeshHeader& header, LLMeshCostData& data);
// </FS:ND>
LLMeshRepository();
@ -610,7 +676,7 @@ public:
void notifyDecompositionReceived(LLModel::Decomposition* info);
S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
static S32 getActualMeshLOD(LLSD& header, S32 lod);
static S32 getActualMeshLOD(LLMeshHeader& header, S32 lod);
const LLMeshSkinInfo* getSkinInfo(const LLUUID& mesh_id, LLVOVolume* requesting_obj = nullptr);
LLModel::Decomposition* getDecomposition(const LLUUID& mesh_id);
void fetchPhysicsShape(const LLUUID& mesh_id);

View File

@ -2274,8 +2274,8 @@ void LLSelectMgr::selectionRevertGLTFMaterials()
// Enqueue update to server
if (asset_id.notNull())
{
// Restore overrides
LLGLTFMaterialList::queueModify(objectp, te, nodep->mSavedGLTFOverrideMaterials[te]);
// Restore overrides and base material
LLGLTFMaterialList::queueApply(objectp, te, asset_id, nodep->mSavedGLTFOverrideMaterials[te]);
}
else
{
@ -5991,7 +5991,7 @@ void LLSelectMgr::processObjectProperties(LLMessageSystem* msg, void** user_data
if (can_copy && can_transfer && node->getObject()->getVolume())
{
uuid_vec_t material_ids;
gltf_materials_vec_t materials;
gltf_materials_vec_t override_materials;
LLVOVolume* vobjp = (LLVOVolume*)node->getObject();
for (int i = 0; i < vobjp->getNumTEs(); ++i)
{
@ -6006,18 +6006,16 @@ void LLSelectMgr::processObjectProperties(LLMessageSystem* msg, void** user_data
if (old_override)
{
LLPointer<LLGLTFMaterial> mat = new LLGLTFMaterial(*old_override);
materials.push_back(mat);
override_materials.push_back(mat);
}
else
{
materials.push_back(nullptr);
override_materials.push_back(nullptr);
}
}
node->saveGLTFMaterialIds(material_ids);
// processObjectProperties does not include overrides so this
// might need to be moved to LLGLTFMaterialOverrideDispatchHandler
node->saveGLTFOverrideMaterials(materials);
node->saveGLTFMaterials(material_ids, override_materials);
}
}
@ -6782,8 +6780,7 @@ LLSelectNode::LLSelectNode(const LLSelectNode& nodep)
}
saveTextures(nodep.mSavedTextures);
saveGLTFMaterialIds(nodep.mSavedGLTFMaterialIds);
saveGLTFOverrideMaterials(nodep.mSavedGLTFOverrideMaterials);
saveGLTFMaterials(nodep.mSavedGLTFMaterialIds, nodep.mSavedGLTFOverrideMaterials);
}
LLSelectNode::~LLSelectNode()
@ -6917,28 +6914,21 @@ void LLSelectNode::saveTextures(const uuid_vec_t& textures)
}
}
void LLSelectNode::saveGLTFMaterialIds(const uuid_vec_t& materials)
void LLSelectNode::saveGLTFMaterials(const uuid_vec_t& materials, const gltf_materials_vec_t& override_materials)
{
if (mObject.notNull())
{
mSavedGLTFMaterialIds.clear();
mSavedGLTFOverrideMaterials.clear();
for (uuid_vec_t::const_iterator materials_it = materials.begin();
materials_it != materials.end(); ++materials_it)
{
mSavedGLTFMaterialIds.push_back(*materials_it);
}
}
}
void LLSelectNode::saveGLTFOverrideMaterials(const gltf_materials_vec_t& materials)
{
if (mObject.notNull())
{
mSavedGLTFOverrideMaterials.clear();
for (gltf_materials_vec_t::const_iterator mat_it = materials.begin();
mat_it != materials.end(); ++mat_it)
for (gltf_materials_vec_t::const_iterator mat_it = override_materials.begin();
mat_it != override_materials.end(); ++mat_it)
{
mSavedGLTFOverrideMaterials.push_back(*mat_it);
}
@ -8112,7 +8102,7 @@ S32 LLObjectSelection::getSelectedObjectRenderCost()
for (LLVOVolume::texture_cost_t::iterator iter = textures.begin(); iter != textures.end(); ++iter)
{
// add the cost of each individual texture in the linkset
cost += iter->second;
cost += LLVOVolume::getTextureCost(*iter);
}
textures.clear();
@ -8134,7 +8124,7 @@ S32 LLObjectSelection::getSelectedObjectRenderCost()
for (LLVOVolume::texture_cost_t::iterator iter = textures.begin(); iter != textures.end(); ++iter)
{
// add the cost of each individual texture in the linkset
cost += iter->second;
cost += LLVOVolume::getTextureCost(*iter);
}
textures.clear();

View File

@ -215,8 +215,7 @@ public:
// final gltf material that users see.
// Ids get applied and restored by tools floater,
// overrides get applied in live material editor
void saveGLTFMaterialIds(const uuid_vec_t& materials);
void saveGLTFOverrideMaterials(const gltf_materials_vec_t& materials);
void saveGLTFMaterials(const uuid_vec_t& materials, const gltf_materials_vec_t& override_materials);
BOOL allowOperationOnNode(PermissionBit op, U64 group_proxy_power) const;

View File

@ -574,11 +574,11 @@ void LLSettingsVOSky::convertAtmosphericsToLegacy(LLSD& legacy, LLSD& settings)
legacy[SETTING_BLUE_DENSITY] = ensure_array_4(legacyhaze[SETTING_BLUE_DENSITY], 1.0);
legacy[SETTING_BLUE_HORIZON] = ensure_array_4(legacyhaze[SETTING_BLUE_HORIZON], 1.0);
legacy[SETTING_DENSITY_MULTIPLIER] = LLSDArray(legacyhaze[SETTING_DENSITY_MULTIPLIER].asReal())(0.0f)(0.0f)(1.0f);
legacy[SETTING_DISTANCE_MULTIPLIER] = LLSDArray(legacyhaze[SETTING_DISTANCE_MULTIPLIER].asReal())(0.0f)(0.0f)(1.0f);
legacy[SETTING_DENSITY_MULTIPLIER] = llsd::array(legacyhaze[SETTING_DENSITY_MULTIPLIER].asReal(), 0.0f, 0.0f, 1.0f);
legacy[SETTING_DISTANCE_MULTIPLIER] = llsd::array(legacyhaze[SETTING_DISTANCE_MULTIPLIER].asReal(), 0.0f, 0.0f, 1.0f);
legacy[SETTING_HAZE_DENSITY] = LLSDArray(legacyhaze[SETTING_HAZE_DENSITY])(0.0f)(0.0f)(1.0f);
legacy[SETTING_HAZE_HORIZON] = LLSDArray(legacyhaze[SETTING_HAZE_HORIZON])(0.0f)(0.0f)(1.0f);
legacy[SETTING_HAZE_DENSITY] = llsd::array(legacyhaze[SETTING_HAZE_DENSITY], 0.0f, 0.0f, 1.0f);
legacy[SETTING_HAZE_HORIZON] = llsd::array(legacyhaze[SETTING_HAZE_HORIZON], 0.0f, 0.0f, 1.0f);
}
}
@ -592,15 +592,15 @@ LLSD LLSettingsVOSky::convertToLegacy(const LLSettingsSky::ptr_t &psky, bool isA
legacy[SETTING_CLOUD_COLOR] = ensure_array_4(settings[SETTING_CLOUD_COLOR], 1.0);
legacy[SETTING_CLOUD_POS_DENSITY1] = ensure_array_4(settings[SETTING_CLOUD_POS_DENSITY1], 1.0);
legacy[SETTING_CLOUD_POS_DENSITY2] = ensure_array_4(settings[SETTING_CLOUD_POS_DENSITY2], 1.0);
legacy[SETTING_CLOUD_SCALE] = LLSDArray(settings[SETTING_CLOUD_SCALE])(LLSD::Real(0.0))(LLSD::Real(0.0))(LLSD::Real(1.0));
legacy[SETTING_CLOUD_SCALE] = llsd::array(settings[SETTING_CLOUD_SCALE], LLSD::Real(0.0), LLSD::Real(0.0), LLSD::Real(1.0));
legacy[SETTING_CLOUD_SCROLL_RATE] = settings[SETTING_CLOUD_SCROLL_RATE];
legacy[SETTING_LEGACY_ENABLE_CLOUD_SCROLL] = LLSDArray(LLSD::Boolean(!is_approx_zero(settings[SETTING_CLOUD_SCROLL_RATE][0].asReal())))
(LLSD::Boolean(!is_approx_zero(settings[SETTING_CLOUD_SCROLL_RATE][1].asReal())));
legacy[SETTING_CLOUD_SHADOW] = LLSDArray(settings[SETTING_CLOUD_SHADOW].asReal())(0.0f)(0.0f)(1.0f);
legacy[SETTING_GAMMA] = LLSDArray(settings[SETTING_GAMMA])(0.0f)(0.0f)(1.0f);
legacy[SETTING_LEGACY_ENABLE_CLOUD_SCROLL] = llsd::array(LLSD::Boolean(!is_approx_zero(settings[SETTING_CLOUD_SCROLL_RATE][0].asReal())),
LLSD::Boolean(!is_approx_zero(settings[SETTING_CLOUD_SCROLL_RATE][1].asReal())));
legacy[SETTING_CLOUD_SHADOW] = llsd::array(settings[SETTING_CLOUD_SHADOW].asReal(), 0.0f, 0.0f, 1.0f);
legacy[SETTING_GAMMA] = llsd::array(settings[SETTING_GAMMA], 0.0f, 0.0f, 1.0f);
legacy[SETTING_GLOW] = ensure_array_4(settings[SETTING_GLOW], 1.0);
legacy[SETTING_LIGHT_NORMAL] = ensure_array_4(psky->getLightDirection().getValue(), 0.0f);
legacy[SETTING_MAX_Y] = LLSDArray(settings[SETTING_MAX_Y])(0.0f)(0.0f)(1.0f);
legacy[SETTING_MAX_Y] = llsd::array(settings[SETTING_MAX_Y], 0.0f, 0.0f, 1.0f);
legacy[SETTING_STAR_BRIGHTNESS] = settings[SETTING_STAR_BRIGHTNESS].asReal() / 250.0f; // convert from 0-500 -> 0-2 ala pre-FS-compat changes
legacy[SETTING_SUNLIGHT_COLOR] = ensure_array_4(settings[SETTING_SUNLIGHT_COLOR], 1.0f);
@ -1113,7 +1113,7 @@ LLSettingsDay::ptr_t LLSettingsVODay::buildFromLegacyPreset(const std::string &n
newsettings[SETTING_NAME] = name;
LLSD watertrack = LLSDArray(
LLSD watertrack = llsd::array(
LLSDMap(SETTING_KEYKFRAME, LLSD::Real(0.0f))
(SETTING_KEYNAME, "water:Default"));
@ -1128,7 +1128,7 @@ LLSettingsDay::ptr_t LLSettingsVODay::buildFromLegacyPreset(const std::string &n
skytrack.append(entry);
}
newsettings[SETTING_TRACKS] = LLSDArray(watertrack)(skytrack);
newsettings[SETTING_TRACKS] = llsd::array(watertrack, skytrack);
LLSD frames(LLSD::emptyMap());
@ -1216,7 +1216,7 @@ LLSettingsDay::ptr_t LLSettingsVODay::buildFromLegacyMessage(const LLUUID &regio
watersettings[SETTING_NAME] = watername;
frames[watername] = watersettings;
LLSD watertrack = LLSDArray(
LLSD watertrack = llsd::array(
LLSDMap(SETTING_KEYKFRAME, LLSD::Real(0.0f))
(SETTING_KEYNAME, watername));
@ -1230,7 +1230,7 @@ LLSettingsDay::ptr_t LLSettingsVODay::buildFromLegacyMessage(const LLUUID &regio
LLSD newsettings = LLSDMap
( SETTING_NAME, "Region (legacy)" )
( SETTING_TRACKS, LLSDArray(watertrack)(skytrack))
( SETTING_TRACKS, llsd::array(watertrack, skytrack))
( SETTING_FRAMES, frames )
( SETTING_TYPE, "daycycle" );
@ -1411,7 +1411,7 @@ LLSD LLSettingsVODay::convertToLegacy(const LLSettingsVODay::ptr_t &pday)
skys[name.str()] = std::static_pointer_cast<LLSettingsSky>((*it).second);
F32 frame = ((tracksky.size() == 1) && (it == tracksky.begin())) ? -1.0f : (*it).first;
llsdcycle.append( LLSDArray(LLSD::Real(frame))(name.str()) );
llsdcycle.append( llsd::array(LLSD::Real(frame), name.str()) );
}
LLSD llsdskylist(LLSD::emptyMap());
@ -1424,7 +1424,7 @@ LLSD LLSettingsVODay::convertToLegacy(const LLSettingsVODay::ptr_t &pday)
llsdskylist[(*its).first] = llsdsky;
}
return LLSDArray(LLSD::emptyMap())(llsdcycle)(llsdskylist)(llsdwater);
return llsd::array(LLSD::emptyMap(), llsdcycle, llsdskylist, llsdwater);
}
LLSettingsSkyPtr_t LLSettingsVODay::getDefaultSky() const

View File

@ -1849,116 +1849,6 @@ void renderUpdateType(LLDrawable* drawablep)
}
}
void renderComplexityDisplay(LLDrawable* drawablep)
{
LLViewerObject* vobj = drawablep->getVObj();
if (!vobj)
{
return;
}
LLVOVolume *voVol = dynamic_cast<LLVOVolume*>(vobj);
if (!voVol)
{
return;
}
if (!voVol->isRoot())
{
return;
}
LLVOVolume::texture_cost_t textures;
F32 cost = (F32) voVol->getRenderCost(textures);
// add any child volumes
LLViewerObject::const_child_list_t children = voVol->getChildren();
for (LLViewerObject::const_child_list_t::const_iterator iter = children.begin(); iter != children.end(); ++iter)
{
const LLViewerObject *child = *iter;
const LLVOVolume *child_volume = dynamic_cast<const LLVOVolume*>(child);
if (child_volume)
{
cost += child_volume->getRenderCost(textures);
}
}
// add texture cost
for (LLVOVolume::texture_cost_t::iterator iter = textures.begin(); iter != textures.end(); ++iter)
{
// add the cost of each individual texture in the linkset
cost += iter->second;
}
F32 cost_max = (F32) LLVOVolume::getRenderComplexityMax();
// allow user to set a static color scale
if (gSavedSettings.getS32("RenderComplexityStaticMax") > 0)
{
cost_max = gSavedSettings.getS32("RenderComplexityStaticMax");
}
F32 cost_ratio = cost / cost_max;
// cap cost ratio at 1.0f in case cost_max is at a low threshold
cost_ratio = cost_ratio > 1.0f ? 1.0f : cost_ratio;
LLGLEnable blend(GL_BLEND);
LLColor4 color;
const LLColor4 color_min = gSavedSettings.getColor4("RenderComplexityColorMin");
const LLColor4 color_mid = gSavedSettings.getColor4("RenderComplexityColorMid");
const LLColor4 color_max = gSavedSettings.getColor4("RenderComplexityColorMax");
if (cost_ratio < 0.5f)
{
color = color_min * (1 - cost_ratio * 2) + color_mid * (cost_ratio * 2);
}
else
{
color = color_mid * (1 - (cost_ratio - 0.5) * 2) + color_max * ((cost_ratio - 0.5) * 2);
}
LLSD color_val = color.getValue();
// don't highlight objects below the threshold
if (cost > gSavedSettings.getS32("RenderComplexityThreshold"))
{
glColor4f(color[0],color[1],color[2],0.5f);
S32 num_faces = drawablep->getNumFaces();
if (num_faces)
{
for (S32 i = 0; i < num_faces; ++i)
{
pushVerts(drawablep->getFace(i));
}
}
LLViewerObject::const_child_list_t children = voVol->getChildren();
for (LLViewerObject::const_child_list_t::const_iterator iter = children.begin(); iter != children.end(); ++iter)
{
const LLViewerObject *child = *iter;
if (child)
{
num_faces = child->getNumFaces();
if (num_faces)
{
for (S32 i = 0; i < num_faces; ++i)
{
pushVerts(child->mDrawable->getFace(i));
}
}
}
}
}
voVol->setDebugText(llformat("%4.0f", cost));
}
void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE)
{
if (set_color)
@ -3317,10 +3207,6 @@ public:
{
renderUpdateType(drawable);
}
if(gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RENDER_COMPLEXITY))
{
renderComplexityDisplay(drawable);
}
if(gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY))
{
renderTexelDensity(drawable);
@ -3631,7 +3517,6 @@ void LLSpatialPartition::renderDebug()
LLPipeline::RENDER_DEBUG_AGENT_TARGET |
//LLPipeline::RENDER_DEBUG_BUILD_QUEUE |
LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA |
LLPipeline::RENDER_DEBUG_RENDER_COMPLEXITY |
LLPipeline::RENDER_DEBUG_TEXEL_DENSITY))
{
return;

View File

@ -2234,12 +2234,14 @@ EAcceptance LLToolDragAndDrop::dad3dApplyToObject(
if (nodep)
{
uuid_vec_t material_ids;
gltf_materials_vec_t override_materials;
S32 num_faces = obj->getNumTEs();
for (S32 face = 0; face < num_faces; face++)
{
material_ids.push_back(obj->getRenderMaterialID(face));
override_materials.push_back(nullptr);
}
nodep->saveGLTFMaterialIds(material_ids);
nodep->saveGLTFMaterials(material_ids, override_materials);
}
}
else
@ -2253,6 +2255,7 @@ EAcceptance LLToolDragAndDrop::dad3dApplyToObject(
&& nodep->mSavedGLTFMaterialIds.size() > face)
{
nodep->mSavedGLTFMaterialIds[face] = obj->getRenderMaterialID(face);
nodep->mSavedGLTFOverrideMaterials[face] = nullptr;
}
}
}

View File

@ -387,7 +387,7 @@ LLViewerObject::~LLViewerObject()
}
// Delete memory associated with extra parameters.
std::map<U16, ExtraParameter*>::iterator iter;
std::unordered_map<U16, ExtraParameter*>::iterator iter;
for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
{
if(iter->second != NULL)
@ -1617,7 +1617,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
unpackParticleSource(block_num, owner_id);
// Mark all extra parameters not used
std::map<U16, ExtraParameter*>::iterator iter;
std::unordered_map<U16, ExtraParameter*>::iterator iter;
for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
{
iter->second->in_use = FALSE;
@ -2015,7 +2015,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
}
// Mark all extra parameters not used
std::map<U16, ExtraParameter*>::iterator iter;
std::unordered_map<U16, ExtraParameter*>::iterator iter;
for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
{
iter->second->in_use = FALSE;
@ -6423,7 +6423,8 @@ LLViewerObject::ExtraParameter* LLViewerObject::createNewParameterEntry(U16 para
LLViewerObject::ExtraParameter* LLViewerObject::getExtraParameterEntry(U16 param_type) const
{
std::map<U16, ExtraParameter*>::const_iterator itor = mExtraParameterList.find(param_type);
LL_PROFILE_ZONE_SCOPED_CATEGORY_VIEWER;
std::unordered_map<U16, ExtraParameter*>::const_iterator itor = mExtraParameterList.find(param_type);
if (itor != mExtraParameterList.end())
{
return itor->second;

View File

@ -28,6 +28,7 @@
#define LL_LLVIEWEROBJECT_H
#include <map>
#include <unordered_map>
#include "llassetstorage.h"
#include "llhudicon.h" // <FS:Ansariel> Changed to get the attached icon
@ -124,7 +125,7 @@ protected:
BOOL in_use;
LLNetworkData *data;
};
std::map<U16, ExtraParameter*> mExtraParameterList;
std::unordered_map<U16, ExtraParameter*> mExtraParameterList;
public:
typedef std::list<LLPointer<LLViewerObject> > child_list_t;

View File

@ -836,16 +836,11 @@ void send_viewer_stats(bool include_preferences)
LL_INFOS("LogViewerStatsPacket") << "Sending viewer statistics: " << body << LL_ENDL;
//<FS:Beq> avoid unfortunate sleep during trylock by static check
// if (debugLoggingEnabled("LogViewerStatsPacket"))
static auto debug_logging_on = debugLoggingEnabled("LogViewerStatsPacket");
if (debug_logging_on)
//</FS:Beq>
{
std::string filename("viewer_stats_packet.xml");
llofstream of(filename.c_str());
LLSDSerialize::toPrettyXML(body,of);
}
LL_DEBUGS("LogViewerStatsPacket");
std::string filename("viewer_stats_packet.xml");
llofstream of(filename.c_str());
LLSDSerialize::toPrettyXML(body,of);
LL_ENDL;
// The session ID token must never appear in logs
body["session_id"] = gAgentSessionID;

View File

@ -1571,7 +1571,7 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
continue;
}
}
if (vol && vol->isRiggedMesh())
if (vol && vol->isRiggedMeshFast())
{
continue;
}
@ -11968,6 +11968,7 @@ void LLVOAvatar::updateVisualComplexity()
markARTStale();
}
// Account for the complexity of a single top-level object associated
// with an avatar. This will be either an attached object or an animated
// object.
@ -11985,157 +11986,158 @@ void LLVOAvatar::accountRenderComplexityForObject(
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR;
if (attached_object && !attached_object->isHUDAttachment())
{
{
mAttachmentVisibleTriangleCount += attached_object->recursiveGetTriangleCount();
mAttachmentEstTriangleCount += attached_object->recursiveGetEstTrianglesMax();
mAttachmentSurfaceArea += attached_object->recursiveGetScaledSurfaceArea();
textures.clear();
const LLDrawable* drawable = attached_object->mDrawable;
if (drawable)
{
const LLVOVolume* volume = drawable->getVOVolume();
if (volume)
{
F32 attachment_total_cost = 0;
F32 attachment_volume_cost = 0;
F32 attachment_texture_cost = 0;
F32 attachment_children_cost = 0;
textures.clear();
const LLDrawable* drawable = attached_object->mDrawable;
if (drawable)
{
const LLVOVolume* volume = drawable->getVOVolume();
if (volume)
{
F32 attachment_total_cost = 0;
F32 attachment_volume_cost = 0;
F32 attachment_texture_cost = 0;
F32 attachment_children_cost = 0;
const F32 animated_object_attachment_surcharge = 1000;
if (attached_object->isAnimatedObject())
{
attachment_volume_cost += animated_object_attachment_surcharge;
}
attachment_volume_cost += volume->getRenderCost(textures);
const_child_list_t children = volume->getChildren();
for (const_child_list_t::const_iterator child_iter = children.begin();
child_iter != children.end();
++child_iter)
{
LLViewerObject* child_obj = *child_iter;
LLVOVolume *child = dynamic_cast<LLVOVolume*>( child_obj );
if (child)
{
attachment_children_cost += child->getRenderCost(textures);
}
}
for (LLVOVolume::texture_cost_t::iterator volume_texture = textures.begin();
volume_texture != textures.end();
++volume_texture)
{
// add the cost of each individual texture in the linkset
attachment_texture_cost += volume_texture->second;
}
attachment_total_cost = attachment_volume_cost + attachment_texture_cost + attachment_children_cost;
LL_DEBUGS("ARCdetail") << "Attachment costs " << attached_object->getAttachmentItemID()
<< " total: " << attachment_total_cost
<< ", volume: " << attachment_volume_cost
<< ", " << textures.size()
<< " textures: " << attachment_texture_cost
<< ", " << volume->numChildren()
<< " children: " << attachment_children_cost
<< LL_ENDL;
// Limit attachment complexity to avoid signed integer flipping of the wearer's ACI
cost += (U32)llclamp(attachment_total_cost, MIN_ATTACHMENT_COMPLEXITY, max_attachment_complexity);
if (isSelf())
{
LLObjectComplexity object_complexity;
object_complexity.objectName = attached_object->getAttachmentItemName();
object_complexity.objectId = attached_object->getAttachmentItemID();
object_complexity.objectCost = attachment_total_cost;
object_complexity_list.push_back(object_complexity);
}
// <FS:Ansariel> Show per-item complexity in COF
if (isSelf())
{
if (!attached_object->isTempAttachment())
{
item_complexity.insert(std::make_pair(attached_object->getAttachmentItemID(), (U32)attachment_total_cost));
}
else
{
temp_item_complexity.insert(std::make_pair(attached_object->getID(), (U32)attachment_total_cost));
}
// </FS:Ansariel>
}
}
}
}
if (isSelf()
&& attached_object
&& attached_object->isHUDAttachment()
&& !attached_object->isTempAttachment()
&& attached_object->mDrawable)
if (volume->isAnimatedObjectFast())
{
textures.clear();
BOOL is_rigged_mesh = attached_object->isRiggedMesh();
mAttachmentSurfaceArea += attached_object->recursiveGetScaledSurfaceArea();
attachment_volume_cost += animated_object_attachment_surcharge;
}
attachment_volume_cost += volume->getRenderCost(textures);
const LLVOVolume* volume = attached_object->mDrawable->getVOVolume();
if (volume)
const_child_list_t children = volume->getChildren();
for (const_child_list_t::const_iterator child_iter = children.begin();
child_iter != children.end();
++child_iter)
{
LLViewerObject* child_obj = *child_iter;
LLVOVolume* child = dynamic_cast<LLVOVolume*>(child_obj);
if (child)
{
LLHUDComplexity hud_object_complexity;
hud_object_complexity.objectName = attached_object->getAttachmentItemName();
hud_object_complexity.objectId = attached_object->getAttachmentItemID();
std::string joint_name;
gAgentAvatarp->getAttachedPointName(attached_object->getAttachmentItemID(), joint_name);
hud_object_complexity.jointName = joint_name;
// get cost and individual textures
hud_object_complexity.objectsCost += volume->getRenderCost(textures);
hud_object_complexity.objectsCount++;
LLViewerObject::const_child_list_t& child_list = attached_object->getChildren();
for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
iter != child_list.end(); ++iter)
{
LLViewerObject* childp = *iter;
is_rigged_mesh |= childp->isRiggedMesh();
const LLVOVolume* chld_volume = dynamic_cast<LLVOVolume*>(childp);
if (chld_volume)
{
// get cost and individual textures
hud_object_complexity.objectsCost += chld_volume->getRenderCost(textures);
hud_object_complexity.objectsCount++;
}
}
if (is_rigged_mesh && !attached_object->mRiggedAttachedWarned)
{
LLSD args;
LLViewerInventoryItem* itemp = gInventory.getItem(attached_object->getAttachmentItemID());
args["NAME"] = itemp ? itemp->getName() : LLTrans::getString("Unknown");
args["POINT"] = LLTrans::getString(getTargetAttachmentPoint(attached_object)->getName());
LLNotificationsUtil::add("RiggedMeshAttachedToHUD", args);
attached_object->mRiggedAttachedWarned = true;
}
hud_object_complexity.texturesCount += textures.size();
for (LLVOVolume::texture_cost_t::iterator volume_texture = textures.begin();
volume_texture != textures.end();
++volume_texture)
{
// add the cost of each individual texture (ignores duplicates)
hud_object_complexity.texturesCost += volume_texture->second;
LLViewerFetchedTexture *tex = LLViewerTextureManager::getFetchedTexture(volume_texture->first);
if (tex)
{
// Note: Texture memory might be incorect since texture might be still loading.
hud_object_complexity.texturesMemoryTotal += tex->getTextureMemory();
if (tex->getOriginalHeight() * tex->getOriginalWidth() >= HUD_OVERSIZED_TEXTURE_DATA_SIZE)
{
hud_object_complexity.largeTexturesCount++;
}
}
}
hud_complexity_list.push_back(hud_object_complexity);
attachment_children_cost += child->getRenderCost(textures);
}
}
for (LLVOVolume::texture_cost_t::iterator volume_texture = textures.begin();
volume_texture != textures.end();
++volume_texture)
{
// add the cost of each individual texture in the linkset
attachment_texture_cost += LLVOVolume::getTextureCost(*volume_texture);
}
attachment_total_cost = attachment_volume_cost + attachment_texture_cost + attachment_children_cost;
LL_DEBUGS("ARCdetail") << "Attachment costs " << attached_object->getAttachmentItemID()
<< " total: " << attachment_total_cost
<< ", volume: " << attachment_volume_cost
<< ", " << textures.size()
<< " textures: " << attachment_texture_cost
<< ", " << volume->numChildren()
<< " children: " << attachment_children_cost
<< LL_ENDL;
// Limit attachment complexity to avoid signed integer flipping of the wearer's ACI
cost += (U32)llclamp(attachment_total_cost, MIN_ATTACHMENT_COMPLEXITY, max_attachment_complexity);
if (isSelf())
{
LLObjectComplexity object_complexity;
object_complexity.objectName = attached_object->getAttachmentItemName();
object_complexity.objectId = attached_object->getAttachmentItemID();
object_complexity.objectCost = attachment_total_cost;
object_complexity_list.push_back(object_complexity);
}
// <FS:Ansariel> Show per-item complexity in COF
if (isSelf())
{
if (!attached_object->isTempAttachment())
{
item_complexity.insert(std::make_pair(attached_object->getAttachmentItemID(), (U32)attachment_total_cost));
}
else
{
temp_item_complexity.insert(std::make_pair(attached_object->getID(), (U32)attachment_total_cost));
}
}
// </FS:Ansariel>
}
}
}
if (isSelf()
&& attached_object
&& attached_object->isHUDAttachment()
&& !attached_object->isTempAttachment()
&& attached_object->mDrawable)
{
textures.clear();
mAttachmentSurfaceArea += attached_object->recursiveGetScaledSurfaceArea();
const LLVOVolume* volume = attached_object->mDrawable->getVOVolume();
if (volume)
{
BOOL is_rigged_mesh = volume->isRiggedMeshFast();
LLHUDComplexity hud_object_complexity;
hud_object_complexity.objectName = attached_object->getAttachmentItemName();
hud_object_complexity.objectId = attached_object->getAttachmentItemID();
std::string joint_name;
gAgentAvatarp->getAttachedPointName(attached_object->getAttachmentItemID(), joint_name);
hud_object_complexity.jointName = joint_name;
// get cost and individual textures
hud_object_complexity.objectsCost += volume->getRenderCost(textures);
hud_object_complexity.objectsCount++;
LLViewerObject::const_child_list_t& child_list = attached_object->getChildren();
for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
iter != child_list.end(); ++iter)
{
LLViewerObject* childp = *iter;
const LLVOVolume* chld_volume = dynamic_cast<LLVOVolume*>(childp);
if (chld_volume)
{
is_rigged_mesh = is_rigged_mesh || chld_volume->isRiggedMeshFast();
// get cost and individual textures
hud_object_complexity.objectsCost += chld_volume->getRenderCost(textures);
hud_object_complexity.objectsCount++;
}
}
if (is_rigged_mesh && !attached_object->mRiggedAttachedWarned)
{
LLSD args;
LLViewerInventoryItem* itemp = gInventory.getItem(attached_object->getAttachmentItemID());
args["NAME"] = itemp ? itemp->getName() : LLTrans::getString("Unknown");
args["POINT"] = LLTrans::getString(getTargetAttachmentPoint(attached_object)->getName());
LLNotificationsUtil::add("RiggedMeshAttachedToHUD", args);
attached_object->mRiggedAttachedWarned = true;
}
hud_object_complexity.texturesCount += textures.size();
for (LLVOVolume::texture_cost_t::iterator volume_texture = textures.begin();
volume_texture != textures.end();
++volume_texture)
{
// add the cost of each individual texture (ignores duplicates)
hud_object_complexity.texturesCost += LLVOVolume::getTextureCost(*volume_texture);
const LLViewerTexture* img = *volume_texture;
if (img->getType() == LLViewerTexture::FETCHED_TEXTURE)
{
LLViewerFetchedTexture* tex = (LLViewerFetchedTexture*)img;
// Note: Texture memory might be incorect since texture might be still loading.
hud_object_complexity.texturesMemoryTotal += tex->getTextureMemory();
if (tex->getOriginalHeight() * tex->getOriginalWidth() >= HUD_OVERSIZED_TEXTURE_DATA_SIZE)
{
hud_object_complexity.largeTexturesCount++;
}
}
}
hud_complexity_list.push_back(hud_object_complexity);
}
}
}
// Calculations for mVisualComplexity value
@ -12158,7 +12160,7 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
// Diagnostic list of all textures on our avatar
// <FS:Ansariel> Disable useless diagnostics
//static std::set<LLUUID> all_textures;
//static std::unordered_set<const LLViewerTexture*> all_textures;
// <FS:Ansariel> Show per-item complexity in COF
std::map<LLUUID, U32> item_complexity;
@ -12251,46 +12253,6 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
}
}
// Diagnostic output to identify all avatar-related textures.
// Does not affect rendering cost calculation.
// <FS:Ansariel> Disable useless diagnostics
//if (isSelf() && debugLoggingEnabled("ARCdetail"))
//{
// // print any attachment textures we didn't already know about.
// for (LLVOVolume::texture_cost_t::iterator it = textures.begin(); it != textures.end(); ++it)
// {
// LLUUID image_id = it->first;
// if( ! (image_id.isNull() || image_id == IMG_DEFAULT || image_id == IMG_DEFAULT_AVATAR)
// && (all_textures.find(image_id) == all_textures.end()))
// {
// // attachment texture not previously seen.
// LL_DEBUGS("ARCdetail") << "attachment_texture: " << image_id.asString() << LL_ENDL;
// all_textures.insert(image_id);
// }
// }
// // print any avatar textures we didn't already know about
// for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearance::getDictionary()->getTextures().begin();
// iter != LLAvatarAppearance::getDictionary()->getTextures().end();
// ++iter)
// {
// const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
// // TODO: MULTI-WEARABLE: handle multiple textures for self
// const LLViewerTexture* te_image = getImage(iter->first,0);
// if (!te_image)
// continue;
// LLUUID image_id = te_image->getID();
// if( image_id.isNull() || image_id == IMG_DEFAULT || image_id == IMG_DEFAULT_AVATAR)
// continue;
// if (all_textures.find(image_id) == all_textures.end())
// {
// LL_DEBUGS("ARCdetail") << "local_texture: " << texture_dict->mName << ": " << image_id << LL_ENDL;
// all_textures.insert(image_id);
// }
// }
//}
// </FS:Ansariel>
if ( cost != mVisualComplexity )
{
LL_DEBUGS("AvatarRender") << "Avatar "<< getID()

View File

@ -3387,7 +3387,13 @@ void LLVOVolume::setLightCutoff(F32 cutoff)
BOOL LLVOVolume::getIsLight() const
{
return getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT);
mIsLight = getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT);
return mIsLight;
}
bool LLVOVolume::getIsLightFast() const
{
return mIsLight;
}
LLColor3 LLVOVolume::getLightSRGBBaseColor() const
@ -3773,6 +3779,31 @@ BOOL LLVOVolume::hasLightTexture() const
return FALSE;
}
bool LLVOVolume::isFlexibleFast() const
{
return mVolumep && mVolumep->getParams().getPathParams().getCurveType() == LL_PCODE_PATH_FLEXIBLE;
}
bool LLVOVolume::isSculptedFast() const
{
return mVolumep && mVolumep->getParams().isSculpt();
}
bool LLVOVolume::isMeshFast() const
{
return mVolumep && mVolumep->getParams().isMeshSculpt();
}
bool LLVOVolume::isRiggedMeshFast() const
{
return mSkinInfo.notNull();
}
bool LLVOVolume::isAnimatedObjectFast() const
{
return mIsAnimatedObject;
}
BOOL LLVOVolume::isVolumeGlobal() const
{
if (mVolumeImpl)
@ -3933,8 +3964,8 @@ bool LLVOVolume::canBeAnimatedObject() const
bool LLVOVolume::isAnimatedObject() const
{
LLVOVolume *root_vol = (LLVOVolume*)getRootEdit();
bool root_is_animated_flag = root_vol->getExtendedMeshFlags() & LLExtendedMeshParams::ANIMATED_MESH_ENABLED_FLAG;
return root_is_animated_flag;
mIsAnimatedObject = root_vol->getExtendedMeshFlags() & LLExtendedMeshParams::ANIMATED_MESH_ENABLED_FLAG;
return mIsAnimatedObject;
}
// Called any time parenting changes for a volume. Update flags and
@ -4121,6 +4152,34 @@ const LLMatrix4 LLVOVolume::getRenderMatrix() const
return mDrawable->getWorldMatrix();
}
//static
S32 LLVOVolume::getTextureCost(const LLViewerTexture* img)
{
static const U32 ARC_TEXTURE_COST = 16; // multiplier for texture resolution - performance tested
S32 texture_cost = 0;
S8 type = img->getType();
if (type == LLViewerTexture::FETCHED_TEXTURE || type == LLViewerTexture::LOD_TEXTURE)
{
const LLViewerFetchedTexture* fetched_texturep = static_cast<const LLViewerFetchedTexture*>(img);
if (fetched_texturep
&& fetched_texturep->getFTType() == FTT_LOCAL_FILE
&& (img->getID() == IMG_ALPHA_GRAD_2D || img->getID() == IMG_ALPHA_GRAD)
)
{
// These two textures appear to switch between each other, but are of different sizes (4x256 and 256x256).
// Hardcode cost from larger one to not cause random complexity changes
texture_cost = 320;
}
}
if (texture_cost == 0)
{
texture_cost = 256 + (S32)(ARC_TEXTURE_COST * (img->getFullHeight() / 128.f + img->getFullWidth() / 128.f));
}
return texture_cost;
}
// Returns a base cost and adds textures to passed in set.
// total cost is returned value + 5 * size of the resulting set.
// Cannot include cost of textures, as they may be re-used in linked
@ -4137,17 +4196,16 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const
// Get access to params we'll need at various points.
// Skip if this is object doesn't have a volume (e.g. is an avatar).
BOOL has_volume = (getVolume() != NULL);
LLVolumeParams volume_params;
LLPathParams path_params;
LLProfileParams profile_params;
if (getVolume() == NULL)
{
return 0;
}
U32 num_triangles = 0;
// per-prim costs
static const U32 ARC_PARTICLE_COST = 1; // determined experimentally
static const U32 ARC_PARTICLE_MAX = 2048; // default values
static const U32 ARC_TEXTURE_COST = 16; // multiplier for texture resolution - performance tested
static const U32 ARC_LIGHT_COST = 500; // static cost for light-producing prims
static const U32 ARC_MEDIA_FACE_COST = 1500; // static cost per media-enabled face
@ -4182,45 +4240,41 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const
const LLDrawable* drawablep = mDrawable;
U32 num_faces = drawablep->getNumFaces();
if (has_volume)
{
volume_params = getVolume()->getParams();
path_params = volume_params.getPathParams();
profile_params = volume_params.getProfileParams();
const LLVolumeParams& volume_params = getVolume()->getParams();
LLMeshCostData costs;
if (getCostData(costs))
{
if (isAnimatedObject() && isRiggedMesh())
{
// Scaling here is to make animated object vs
// non-animated object ARC proportional to the
// corresponding calculations for streaming cost.
num_triangles = (ANIMATED_OBJECT_COST_PER_KTRI * 0.001 * costs.getEstTrisForStreamingCost())/0.06;
}
else
{
F32 radius = getScale().length()*0.5f;
num_triangles = costs.getRadiusWeightedTris(radius);
}
}
LLMeshCostData costs;
if (getCostData(costs))
{
if (isAnimatedObjectFast() && isRiggedMeshFast())
{
// Scaling here is to make animated object vs
// non-animated object ARC proportional to the
// corresponding calculations for streaming cost.
num_triangles = (ANIMATED_OBJECT_COST_PER_KTRI * 0.001 * costs.getEstTrisForStreamingCost())/0.06;
}
else
{
F32 radius = getScale().length()*0.5f;
num_triangles = costs.getRadiusWeightedTris(radius);
}
}
if (num_triangles <= 0)
{
num_triangles = 4;
}
if (isSculpted())
if (isSculptedFast())
{
if (isMesh())
if (isMeshFast())
{
// base cost is dependent on mesh complexity
// note that 3 is the highest LOD as of the time of this coding.
S32 size = gMeshRepo.getMeshSize(volume_params.getSculptID(), getLOD());
if ( size > 0)
{
if (isRiggedMesh())
if (isRiggedMeshFast())
{
// weighted attachment - 1 point for every 3 bytes
weighted_mesh = 1;
@ -4234,21 +4288,15 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const
}
else
{
const LLSculptParams *sculpt_params = (LLSculptParams *) getParameterEntry(LLNetworkData::PARAMS_SCULPT);
LLUUID sculpt_id = sculpt_params->getSculptTexture();
if (textures.find(sculpt_id) == textures.end())
LLViewerFetchedTexture* texture = mSculptTexture;
if (texture && textures.find(texture) == textures.end())
{
LLViewerFetchedTexture *texture = LLViewerTextureManager::getFetchedTexture(sculpt_id);
if (texture)
{
S32 texture_cost = 256 + (S32)(ARC_TEXTURE_COST * (texture->getFullHeight() / 128.f + texture->getFullWidth() / 128.f));
textures.insert(texture_cost_t::value_type(sculpt_id, texture_cost));
}
textures.insert(texture);
}
}
}
if (isFlexible())
if (isFlexibleFast())
{
flexi = 1;
}
@ -4257,85 +4305,66 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const
particles = 1;
}
if (getIsLight())
if (getIsLightFast())
{
produces_light = 1;
}
for (S32 i = 0; i < num_faces; ++i)
{
const LLFace* face = drawablep->getFace(i);
if (!face) continue;
const LLTextureEntry* te = face->getTextureEntry();
const LLViewerTexture* img = face->getTexture();
{
LL_PROFILE_ZONE_NAMED_CATEGORY_VOLUME("ARC - face list");
for (S32 i = 0; i < num_faces; ++i)
{
const LLFace* face = drawablep->getFace(i);
if (!face) continue;
const LLTextureEntry* te = face->getTextureEntry();
const LLViewerTexture* img = face->getTexture();
if (img)
{
if (textures.find(img->getID()) == textures.end())
{
S32 texture_cost = 0;
S8 type = img->getType();
if (type == LLViewerTexture::FETCHED_TEXTURE || type == LLViewerTexture::LOD_TEXTURE)
if (img)
{
textures.insert(img);
}
if (face->isInAlphaPool())
{
alpha = 1;
}
else if (img && img->getPrimaryFormat() == GL_ALPHA)
{
invisi = 1;
}
if (face->hasMedia())
{
media_faces++;
}
if (te)
{
if (te->getBumpmap())
{
const LLViewerFetchedTexture* fetched_texturep = static_cast<const LLViewerFetchedTexture*>(img);
if (fetched_texturep
&& fetched_texturep->getFTType() == FTT_LOCAL_FILE
&& (img->getID() == IMG_ALPHA_GRAD_2D || img->getID() == IMG_ALPHA_GRAD)
)
{
// These two textures appear to switch between each other, but are of different sizes (4x256 and 256x256).
// Hardcode cost from larger one to not cause random complexity changes
texture_cost = 320;
}
// bump is a multiplier, don't add per-face
bump = 1;
}
if (texture_cost == 0)
if (te->getShiny())
{
texture_cost = 256 + (S32)(ARC_TEXTURE_COST * (img->getFullHeight() / 128.f + img->getFullWidth() / 128.f));
// shiny is a multiplier, don't add per-face
shiny = 1;
}
textures.insert(texture_cost_t::value_type(img->getID(), texture_cost));
}
}
if (face->isInAlphaPool())
{
alpha = 1;
}
else if (img && img->getPrimaryFormat() == GL_ALPHA)
{
invisi = 1;
}
if (face->hasMedia())
{
media_faces++;
}
if (te)
{
if (te->getBumpmap())
{
// bump is a multiplier, don't add per-face
bump = 1;
}
if (te->getShiny())
{
// shiny is a multiplier, don't add per-face
shiny = 1;
}
if (te->getGlow() > 0.f)
{
// glow is a multiplier, don't add per-face
glow = 1;
}
if (face->mTextureMatrix != NULL)
{
animtex = 1;
}
if (te->getTexGen())
{
planar = 1;
}
}
}
if (te->getGlow() > 0.f)
{
// glow is a multiplier, don't add per-face
glow = 1;
}
if (face->mTextureMatrix != NULL)
{
animtex = 1;
}
if (te->getTexGen())
{
planar = 1;
}
}
}
}
// shame currently has the "base" cost of 1 point per 15 triangles, min 2.
shame = num_triangles * 5.f;
@ -4414,7 +4443,7 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const
// Streaming cost for animated objects includes a fixed cost
// per linkset. Add a corresponding charge here translated into
// triangles, but not weighted by any graphics properties.
if (isAnimatedObject() && isRootEdit())
if (isAnimatedObjectFast() && isRootEdit())
{
shame += (ANIMATED_OBJECT_BASE_COST/0.06) * 5.0f;
}
@ -4429,7 +4458,7 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const
F32 LLVOVolume::getEstTrianglesMax() const
{
if (isMesh() && getVolume())
if (isMeshFast() && getVolume())
{
return gMeshRepo.getEstTrianglesMax(getVolume()->getParams().getSculptID());
}
@ -4438,7 +4467,7 @@ F32 LLVOVolume::getEstTrianglesMax() const
F32 LLVOVolume::getEstTrianglesStreamingCost() const
{
if (isMesh() && getVolume())
if (isMeshFast() && getVolume())
{
return gMeshRepo.getEstTrianglesStreamingCost(getVolume()->getParams().getSculptID());
}
@ -4453,7 +4482,7 @@ F32 LLVOVolume::getStreamingCost() const
LLMeshCostData costs;
if (getCostData(costs))
{
if (isAnimatedObject() && isRootEdit())
if (isRootEdit() && isAnimatedObject())
{
// Root object of an animated object has this to account for skeleton overhead.
linkset_base_cost = ANIMATED_OBJECT_BASE_COST;
@ -4483,7 +4512,9 @@ F32 LLVOVolume::getStreamingCost() const
// virtual
bool LLVOVolume::getCostData(LLMeshCostData& costs) const
{
if (isMesh())
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
if (isMeshFast())
{
return gMeshRepo.getCostData(getVolume()->getParams().getSculptID(), costs);
}
@ -4497,11 +4528,11 @@ bool LLVOVolume::getCostData(LLMeshCostData& costs) const
LLVolume::getLoDTriangleCounts(volume->getParams(), counts, volume);
// </FS:ND>
LLSD header;
header["lowest_lod"]["size"] = counts[0] * 10;
header["low_lod"]["size"] = counts[1] * 10;
header["medium_lod"]["size"] = counts[2] * 10;
header["high_lod"]["size"] = counts[3] * 10;
LLMeshHeader header;
header.mLodSize[0] = counts[0] * 10;
header.mLodSize[1] = counts[1] * 10;
header.mLodSize[2] = counts[2] * 10;
header.mLodSize[3] = counts[3] * 10;
return gMeshRepo.getCostData(header, costs);
}
@ -5973,29 +6004,24 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
//F32 est_tris = vobj->getEstTrianglesMax();
vobj->updateControlAvatar();
// Also avoid unfortunate sleep during trylock by static check
//if(debugLoggingEnabled("AnimatedObjectsLinkset"))
static auto debug_logging_on = debugLoggingEnabled("AnimatedObjectsLinkset");
if (debug_logging_on)
//</FS:Beq>
{
std::string vobj_name = llformat("Vol%p", vobj);
bool is_mesh = vobj->isMesh();
F32 est_tris = vobj->getEstTrianglesMax();
LL_DEBUGS("AnimatedObjectsLinkset") << vobj_name << " rebuilding, isAttachment: " << (U32) vobj->isAttachment()
<< " is_mesh " << is_mesh
<< " est_tris " << est_tris
<< " is_animated " << vobj->isAnimatedObject()
<< " can_animate " << vobj->canBeAnimatedObject()
<< " cav " << vobj->getControlAvatar()
<< " lod " << vobj->getLOD()
<< " drawable rigged " << (drawablep->isState(LLDrawable::RIGGED))
<< " drawable state " << drawablep->getState()
<< " playing " << (U32) (vobj->getControlAvatar() ? vobj->getControlAvatar()->mPlaying : false)
<< " frame " << LLFrameTimer::getFrameCount()
<< LL_ENDL;
}
#if 0
std::string vobj_name = llformat("Vol%p", vobj);
F32 est_tris = vobj->getEstTrianglesMax();
LL_DEBUGS("AnimatedObjectsLinkset") << vobj_name << " rebuilding, isAttachment: " << (U32) vobj->isAttachment()
<< " is_mesh " << is_mesh
<< " est_tris " << est_tris
<< " is_animated " << vobj->isAnimatedObject()
<< " can_animate " << vobj->canBeAnimatedObject()
<< " cav " << vobj->getControlAvatar()
<< " lod " << vobj->getLOD()
<< " drawable rigged " << (drawablep->isState(LLDrawable::RIGGED))
<< " drawable state " << drawablep->getState()
<< " playing " << (U32) (vobj->getControlAvatar() ? vobj->getControlAvatar()->mPlaying : false)
<< " frame " << LLFrameTimer::getFrameCount()
<< LL_ENDL;
#endif
//<FS:Beq> Pointless. We already checked this and have used it.
//llassert_always(vobj);

View File

@ -34,8 +34,8 @@
#include "lllocalbitmaps.h"
#include "m3math.h" // LLMatrix3
#include "m4math.h" // LLMatrix4
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
class LLViewerTextureAnim;
@ -148,7 +148,8 @@ public:
const LLMatrix4& getRelativeXform() const { return mRelativeXform; }
const LLMatrix3& getRelativeXformInvTrans() const { return mRelativeXformInvTrans; }
/*virtual*/ const LLMatrix4 getRenderMatrix() const override;
typedef std::map<LLUUID, S32> texture_cost_t;
typedef std::unordered_set<const LLViewerTexture*> texture_cost_t;
static S32 getTextureCost(const LLViewerTexture* img);
U32 getRenderCost(texture_cost_t &textures) const;
/*virtual*/ F32 getEstTrianglesMax() const override;
/*virtual*/ F32 getEstTrianglesStreamingCost() const override;
@ -272,6 +273,7 @@ public:
void setSpotLightParams(LLVector3 params);
BOOL getIsLight() const;
bool getIsLightFast() const;
// Get the light color in sRGB color space NOT scaled by intensity.
@ -320,7 +322,15 @@ public:
virtual BOOL isRiggedMesh() const override;
virtual BOOL hasLightTexture() const override;
// fast variants above that use state that is filled in later
// not reliable early in the life of an object, but should be used after
// object is loaded
bool isFlexibleFast() const;
bool isSculptedFast() const;
bool isMeshFast() const;
bool isRiggedMeshFast() const;
bool isAnimatedObjectFast() const;
BOOL isVolumeGlobal() const;
BOOL canBeFlexible() const;
BOOL setIsFlexible(BOOL is_flexible);
@ -473,6 +483,13 @@ private:
S32 mIndexInTex[LLRender::NUM_VOLUME_TEXTURE_CHANNELS];
S32 mMDCImplCount;
// cached value of getIsLight to avoid redundant map lookups
// accessed by getIsLightFast
mutable bool mIsLight = false;
// cached value of getIsAnimatedObject to avoid redundant map lookups
// accessed by getIsAnimatedObjectFast
mutable bool mIsAnimatedObject = false;
bool mResetDebugText;
LLPointer<LLRiggedVolume> mRiggedVolume;
@ -487,7 +504,6 @@ public:
static LLPointer<LLObjectMediaDataClient> sObjectMediaClient;
static LLPointer<LLObjectMediaNavigateClient> sObjectMediaNavigateClient;
protected:
static S32 sNumLODChanges;

View File

@ -607,7 +607,6 @@ public:
RENDER_DEBUG_PHYSICS_SHAPES = 0x02000000,
RENDER_DEBUG_NORMALS = 0x04000000,
RENDER_DEBUG_LOD_INFO = 0x08000000,
RENDER_DEBUG_RENDER_COMPLEXITY = 0x10000000,
RENDER_DEBUG_ATTACHMENT_BYTES = 0x20000000, // not used
RENDER_DEBUG_TEXEL_DENSITY = 0x40000000,
RENDER_DEBUG_TRIANGLE_COUNT = 0x80000000,

View File

@ -404,28 +404,28 @@ namespace tut
ensure("hash: equivalent values but different types do not match.", boost::hash<LLSD>{}(data_r1) != boost::hash<LLSD>{}(data_i1));
}
{
LLSD data_a1 = LLSDArray("A")("B")("C");
LLSD data_a2 = LLSDArray("A")("B")("C");
LLSD data_a1 = llsd::array("A", "B", "C");
LLSD data_a2 = llsd::array("A", "B", "C");
ensure("hash: identical arrays produce identical results", boost::hash<LLSD>{}(data_a1) == boost::hash<LLSD>{}(data_a2));
data_a2.append(LLSDArray(1)(2));
data_a2.append(llsd::array(1, 2));
ensure("hash: changing the array changes the hash.", boost::hash<LLSD>{}(data_a1) != boost::hash<LLSD>{}(data_a2));
data_a1.append(LLSDArray(1)(2));
data_a1.append(llsd::array(1, 2));
ensure("hash: identical arrays produce identical results with nested arrays", boost::hash<LLSD>{}(data_a1) == boost::hash<LLSD>{}(data_a2));
}
{
LLSD data_m1 = LLSDMap("key1", LLSD::Real(3.0))("key2", "value2")("key3", LLSDArray(1)(2)(3));
LLSD data_m2 = LLSDMap("key1", LLSD::Real(3.0))("key2", "value2")("key3", LLSDArray(1)(2)(3));
LLSD data_m1 = LLSDMap("key1", LLSD::Real(3.0))("key2", "value2")("key3", llsd::array(1, 2, 3));
LLSD data_m2 = LLSDMap("key1", LLSD::Real(3.0))("key2", "value2")("key3", llsd::array(1, 2, 3));
ensure("hash: identical maps produce identical results", boost::hash<LLSD>{}(data_m1) == boost::hash<LLSD>{}(data_m2));
LLSD data_m3 = LLSDMap("key1", LLSD::Real(5.0))("key2", "value2")("key3", LLSDArray(1)(2)(3));
LLSD data_m3 = LLSDMap("key1", LLSD::Real(5.0))("key2", "value2")("key3", llsd::array(1, 2, 3));
ensure("hash: Different values in the map produce different hashes.", boost::hash<LLSD>{}(data_m1) != boost::hash<LLSD>{}(data_m3));
LLSD data_m4 = LLSDMap("keyA", LLSD::Real(3.0))("key2", "value2")("key3", LLSDArray(1)(2)(3));
LLSD data_m4 = LLSDMap("keyA", LLSD::Real(3.0))("key2", "value2")("key3", llsd::array(1, 2, 3));
ensure("hash: Different keys in the map produce different hashes.", boost::hash<LLSD>{}(data_m1) != boost::hash<LLSD>{}(data_m4));
}