diff options
| -rw-r--r-- | autobuild.xml | 56 | ||||
| -rw-r--r-- | indra/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | indra/cmake/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | indra/cmake/LLMeshOptimizer.cmake | 7 | ||||
| -rw-r--r-- | indra/cmake/MESHOPTIMIZER.cmake | 16 | ||||
| -rw-r--r-- | indra/llmeshoptimizer/CMakeLists.txt | 44 | ||||
| -rw-r--r-- | indra/llmeshoptimizer/llmeshoptimizer.cpp | 108 | ||||
| -rw-r--r-- | indra/llmeshoptimizer/llmeshoptimizer.h | 75 | ||||
| -rw-r--r-- | indra/newview/CMakeLists.txt | 3 | ||||
| -rw-r--r-- | indra/newview/app_settings/key_bindings.xml | 8 | ||||
| -rw-r--r-- | indra/newview/llfloatermodelpreview.cpp | 27 | ||||
| -rw-r--r-- | indra/newview/llkeyconflict.cpp | 66 | ||||
| -rw-r--r-- | indra/newview/llkeyconflict.h | 4 | ||||
| -rw-r--r-- | indra/newview/llmodelpreview.cpp | 295 | ||||
| -rw-r--r-- | indra/newview/llmodelpreview.h | 14 | ||||
| -rw-r--r-- | indra/newview/lltoolcomp.cpp | 10 | ||||
| -rw-r--r-- | indra/newview/lltoolpie.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/llviewerinput.cpp | 81 | ||||
| -rw-r--r-- | indra/newview/llviewerinput.h | 5 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/control_table_contents_media.xml | 10 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/floater_model_preview.xml | 32 | 
21 files changed, 832 insertions, 34 deletions
diff --git a/autobuild.xml b/autobuild.xml index eb057ec8e0..8f5770f5b2 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -2394,6 +2394,62 @@          <key>version</key>          <string>7.11.1.297294</string>        </map> +      <key>meshoptimizer</key> +      <map> +        <key>canonical_repo</key> +        <string>https://bitbucket.org/lindenlab/3p-meshoptimizer</string> +        <key>copyright</key> +        <string>Copyright (c) 2016-2021 Arseny Kapoulkine</string> +        <key>description</key> +        <string>Meshoptimizer. Mesh optimization library.</string> +        <key>license</key> +        <string>meshoptimizer</string> +        <key>license_file</key> +        <string>LICENSES/meshoptimizer.txt</string> +        <key>name</key> +        <string>meshoptimizer</string> +        <key>platforms</key> +        <map> +          <key>darwin64</key> +          <map> +            <key>archive</key> +            <map> +              <key>hash</key> +              <string>30bc37db57bbd87c4b5f62634964242a</string> +              <key>url</key> +              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/84218/784918/meshoptimizer-0.16.561408-darwin64-561408.tar.bz2</string> +            </map> +            <key>name</key> +            <string>darwin64</string> +          </map> +          <key>windows</key> +          <map> +            <key>archive</key> +            <map> +              <key>hash</key> +              <string>ca3684bcf0447746cd2844e94f6d1fc7</string> +              <key>url</key> +              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/84219/784924/meshoptimizer-0.16.561408-windows-561408.tar.bz2</string> +            </map> +            <key>name</key> +            <string>windows</string> +          </map> +          <key>windows64</key> +          <map> +            <key>archive</key> +            <map> +              <key>hash</key> +              <string>aef28c089d20f69d13c9c3e113fb3895</string> +              <key>url</key> +              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/84220/784931/meshoptimizer-0.16.561408-windows64-561408.tar.bz2</string> +            </map> +            <key>name</key> +            <string>windows64</string> +          </map> +        </map> +        <key>version</key> +        <string>0.16.561408</string> +      </map>        <key>nghttp2</key>        <map>          <key>copyright</key> diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt index db88e44127..fcc1b28ebb 100644 --- a/indra/CMakeLists.txt +++ b/indra/CMakeLists.txt @@ -38,6 +38,7 @@ add_subdirectory(${LIBS_OPEN_PREFIX}llkdu)  add_subdirectory(${LIBS_OPEN_PREFIX}llimagej2coj)  add_subdirectory(${LIBS_OPEN_PREFIX}llinventory)  add_subdirectory(${LIBS_OPEN_PREFIX}llmath) +add_subdirectory(${LIBS_OPEN_PREFIX}llmeshoptimizer)  add_subdirectory(${LIBS_OPEN_PREFIX}llmessage)  add_subdirectory(${LIBS_OPEN_PREFIX}llprimitive)  add_subdirectory(${LIBS_OPEN_PREFIX}llrender) diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt index a17e37cd32..527a9cba43 100644 --- a/indra/cmake/CMakeLists.txt +++ b/indra/cmake/CMakeLists.txt @@ -61,6 +61,7 @@ set(cmake_SOURCE_FILES      LLKDU.cmake      LLLogin.cmake      LLMath.cmake +    LLMeshOptimizer.cmake      LLMessage.cmake      LLPhysicsExtensions.cmake      LLPlugin.cmake @@ -74,6 +75,7 @@ set(cmake_SOURCE_FILES      LLXML.cmake      Linking.cmake      MediaPluginBase.cmake +    MESHOPTIMIZER.cmake      NDOF.cmake      OPENAL.cmake      OpenGL.cmake diff --git a/indra/cmake/LLMeshOptimizer.cmake b/indra/cmake/LLMeshOptimizer.cmake new file mode 100644 index 0000000000..b79944f618 --- /dev/null +++ b/indra/cmake/LLMeshOptimizer.cmake @@ -0,0 +1,7 @@ +# -*- cmake -*- + +set(LLMESHOPTIMIZER_INCLUDE_DIRS +    ${LIBS_OPEN_DIR}/llmeshoptimizer +    ) + +set(LLMESHOPTIMIZER_LIBRARIES llmeshoptimizer) diff --git a/indra/cmake/MESHOPTIMIZER.cmake b/indra/cmake/MESHOPTIMIZER.cmake new file mode 100644 index 0000000000..1c5b47b9bd --- /dev/null +++ b/indra/cmake/MESHOPTIMIZER.cmake @@ -0,0 +1,16 @@ +# -*- cmake -*- + +include(Linking) +include(Prebuilt) + +use_prebuilt_binary(meshoptimizer) + +if (WINDOWS) +  set(MESHOPTIMIZER_LIBRARIES meshoptimizer.lib) +elseif (LINUX) +  set(MESHOPTIMIZER_LIBRARIES meshoptimizer.o) +elseif (DARWIN) +  set(MESHOPTIMIZER_LIBRARIES libmeshoptimizer.a) +endif (WINDOWS) + +set(MESHOPTIMIZER_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/meshoptimizer) diff --git a/indra/llmeshoptimizer/CMakeLists.txt b/indra/llmeshoptimizer/CMakeLists.txt new file mode 100644 index 0000000000..016794cfad --- /dev/null +++ b/indra/llmeshoptimizer/CMakeLists.txt @@ -0,0 +1,44 @@ +# -*- cmake -*- + +project(llmeshoptimizer) + +include(MESHOPTIMIZER) + +include(00-Common) +include(LLCommon) +include(LLMath) + +include_directories( +    ${LLCOMMON_INCLUDE_DIRS} +    ${LLMATH_INCLUDE_DIRS} +    ${LLMESHOPTIMIZER_INCLUDE_DIR} +    ${MESHOPTIMIZER_INCLUDE_DIRS} +    ${LIBS_PREBUILT_DIR}/include  #access to boost headers, needed for LLError +    ) + +set(llmeshoptimizer_SOURCE_FILES +    llmeshoptimizer.cpp +    ) + +set(llmeshoptimizer_HEADER_FILES +    CMakeLists.txt + +    llmeshoptimizer.h +    ) + +set_source_files_properties(${llmeshoptimizer_HEADER_FILES} +                            PROPERTIES HEADER_FILE_ONLY TRUE) + +list(APPEND llmeshoptimizer_SOURCE_FILES ${llmeshoptimizer_HEADER_FILES}) + +#if (USE_MESHOPT) +  add_library (llmeshoptimizer ${llmeshoptimizer_SOURCE_FILES}) + +  target_link_libraries(llmeshoptimizer +    ${LLCOMMON_LIBRARIES} +    ${LLMATH_LIBRARIES} +    ${MESHOPTIMIZER_LIBRARIES}) +   +  # Add tests + +#endif (USE_MESHOPT) diff --git a/indra/llmeshoptimizer/llmeshoptimizer.cpp b/indra/llmeshoptimizer/llmeshoptimizer.cpp new file mode 100644 index 0000000000..09fa7cb235 --- /dev/null +++ b/indra/llmeshoptimizer/llmeshoptimizer.cpp @@ -0,0 +1,108 @@ + /**  +* @file llmeshoptimizer.cpp +* @brief Wrapper around meshoptimizer +* +* $LicenseInfo:firstyear=2021&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2021, Linden Research, Inc. +*  +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +*  +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +* Lesser General Public License for more details. +*  +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA +*  +* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA +* $/LicenseInfo$ +*/ + +#include "llmeshoptimizer.h" + +#include "meshoptimizer.h" + +LLMeshOptimizer::LLMeshOptimizer() +{ +    // Todo: Looks like for memory management, we can add allocator and deallocator callbacks +    // Should be one time +    // meshopt_setAllocator(allocate, deallocate); +} + +LLMeshOptimizer::~LLMeshOptimizer() +{ +} + +//static +void LLMeshOptimizer::generateShadowIndexBuffer(U16 *destination, +    const U16 *indices, +    U64 index_count, +    const LLVector4a *vertex_positions, +    U64 vertex_count, +    U64 vertex_positions_stride +) +{ +    meshopt_generateShadowIndexBuffer<unsigned short>(destination, +        indices, +        index_count, +        (const float*)vertex_positions, // verify that it is correct to convert to float +        vertex_count, +        sizeof(LLVector4a), +        vertex_positions_stride +        ); +} + +//static +U64 LLMeshOptimizer::simplify(U16 *destination, +                              const U16 *indices, +                              U64 index_count, +                              const LLVector4a *vertex_positions, +                              U64 vertex_count, +                              U64 vertex_positions_stride, +                              U64 target_index_count, +                              F32 target_error, +                              F32* result_error +    ) +{ + +    return meshopt_simplify<unsigned short>(destination, +                                 indices, +                                 index_count, +                                 (const float*)vertex_positions, +                                 vertex_count, +                                 vertex_positions_stride,  +                                 target_index_count, +                                 target_error, +                                 result_error +                                 ); +} + +//static +U64 LLMeshOptimizer::simplifySloppy(U16 *destination, +                              const U16 *indices, +                              U64 index_count, +                              const LLVector4a *vertex_positions, +                              U64 vertex_count, +    U64 vertex_positions_stride, +                              U64 target_index_count, +                              F32 target_error, +                              F32* result_error +    ) +{ +    return meshopt_simplifySloppy<unsigned short>(destination, +                                 indices, +                                 index_count, +                                 (const float*)vertex_positions, +                                 vertex_count, +                                 vertex_positions_stride,  +                                 target_index_count, +                                 target_error, +                                 result_error +                                 ); +} diff --git a/indra/llmeshoptimizer/llmeshoptimizer.h b/indra/llmeshoptimizer/llmeshoptimizer.h new file mode 100644 index 0000000000..1aa02372fa --- /dev/null +++ b/indra/llmeshoptimizer/llmeshoptimizer.h @@ -0,0 +1,75 @@ +/**  +* @file llmeshoptimizer.h +* @brief Wrapper around meshoptimizer +* +* $LicenseInfo:firstyear=2021&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2021, Linden Research, Inc. +*  +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +*  +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +* Lesser General Public License for more details. +*  +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA +*  +* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA +* $/LicenseInfo$ +*/ +#ifndef LLMESHOPTIMIZER_H +#define LLMESHOPTIMIZER_H + +#include "linden_common.h" + +#include "llmath.h" + +class LLMeshOptimizer +{ +public: +    LLMeshOptimizer(); +    ~LLMeshOptimizer(); + +    static void generateShadowIndexBuffer( +        U16 *destination, +        const U16 *indices, +        U64 index_count, +        const LLVector4a *vertex_positions, +        U64 vertex_count, +        U64 vertex_positions_stride); + +    // returns amount of indices in destiantion +    // result_error returns how far from original the model is in % if not NULL +    static U64 simplify( +        U16 *destination, +        const U16 *indices, +        U64 index_count, +        const LLVector4a *vertex_positions, +        U64 vertex_count, +        U64 vertex_positions_stride, +        U64 target_index_count, +        F32 target_error, +        F32* result_error); + +    // returns amount of indices in destiantion +    // result_error returns how far from original the model is in % if not NULL +    static U64 simplifySloppy( +        U16 *destination, +        const U16 *indices, +        U64 index_count, +        const LLVector4a *vertex_positions, +        U64 vertex_count, +        U64 vertex_positions_stride, +        U64 target_index_count, +        F32 target_error, +        F32* result_error); +private: +}; + +#endif //LLMESHOPTIMIZER_H diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 87caca56af..13e17075d8 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -31,6 +31,7 @@ include(LLInventory)  include(LLKDU)  include(LLLogin)  include(LLMath) +include(LLMeshOptimizer)  include(LLMessage)  include(LLPhysicsExtensions)  include(LLPlugin) @@ -77,6 +78,7 @@ include_directories(      ${LLKDU_INCLUDE_DIRS}      ${LLINVENTORY_INCLUDE_DIRS}      ${LLMATH_INCLUDE_DIRS} +    ${LLMESHOPTIMIZER_INCLUDE_DIRS}      ${LLMESSAGE_INCLUDE_DIRS}      ${LLPLUGIN_INCLUDE_DIRS}      ${LLPRIMITIVE_INCLUDE_DIRS} @@ -2029,6 +2031,7 @@ target_link_libraries(${VIEWER_BINARY_NAME}      ${LLCHARACTER_LIBRARIES}      ${LLIMAGE_LIBRARIES}      ${LLINVENTORY_LIBRARIES} +    ${LLMESHOPTIMIZER_LIBRARIES}      ${LLMESSAGE_LIBRARIES}      ${LLPLUGIN_LIBRARIES}      ${LLPRIMITIVE_LIBRARIES} diff --git a/indra/newview/app_settings/key_bindings.xml b/indra/newview/app_settings/key_bindings.xml index 4f6deb1f98..ffc1b2e7cc 100644 --- a/indra/newview/app_settings/key_bindings.xml +++ b/indra/newview/app_settings/key_bindings.xml @@ -33,6 +33,8 @@      <binding key="DIVIDE" mask="NONE" command="start_gesture"/>      <binding key="" mask="NONE" mouse="MMB" command="toggle_voice"/> + +    <binding key="" mask="NONE" mouse="LMB" command="sript_trigger_lbutton"/>    </first_person>    <third_person>      <binding key="A" mask="NONE" command="turn_left"/> @@ -127,6 +129,8 @@      <binding key="" mask="NONE" mouse="MMB" command="toggle_voice"/>      <binding key="" mask="NONE" mouse="LMB" command="walk_to"/> + +    <binding key="" mask="NONE" mouse="LMB" command="sript_trigger_lbutton"/>    </third_person>    <sitting>      <binding key="A" mask="ALT" command="spin_around_cw"/> @@ -224,6 +228,8 @@      <binding key="DIVIDE" mask="NONE" command="start_gesture"/>      <binding key="" mask="NONE" mouse="MMB" command="toggle_voice"/> + +    <binding key="" mask="NONE" mouse="LMB" command="sript_trigger_lbutton"/>    </sitting>    <edit_avatar>      <!--Avatar editing camera controls--> @@ -251,5 +257,7 @@      <binding key="PAD_DIVIDE" mask="NONE" command="start_gesture"/>      <binding key="" mask="NONE" mouse="MMB" command="toggle_voice"/> + +    <binding key="" mask="NONE" mouse="LMB" command="sript_trigger_lbutton"/>    </edit_avatar>  </keys> diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index d9edd4dc30..d61311d610 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -139,7 +139,7 @@ mAvatarTabIndex(0)  	mLODMode[LLModel::LOD_HIGH] = 0;  	for (U32 i = 0; i < LLModel::LOD_HIGH; i++)  	{ -		mLODMode[i] = 1; +		mLODMode[i] = LLModelPreview::MESH_OPTIMIZER;  	}  } @@ -722,7 +722,23 @@ void LLFloaterModelPreview::onAutoFillCommit(LLUICtrl* ctrl, void* userdata)  void LLFloaterModelPreview::onLODParamCommit(S32 lod, bool enforce_tri_limit)  { -	mModelPreview->onLODParamCommit(lod, enforce_tri_limit); +    LLComboBox* lod_source_combo = getChild<LLComboBox>("lod_source_" + lod_name[lod]); +    S32 mode = lod_source_combo->getCurrentIndex(); +    switch (mode) +    { +    case LLModelPreview::GENERATE: +        mModelPreview->onLODGenerateParamCommit(lod, enforce_tri_limit); +        break; +    case LLModelPreview::MESH_OPTIMIZER: +        mModelPreview->onLODMeshOptimizerParamCommit(lod, enforce_tri_limit, false); +        break; +    case LLModelPreview::MESH_OPTIMIZER_SLOPPY: +        mModelPreview->onLODMeshOptimizerParamCommit(lod, enforce_tri_limit, true); +        break; +    default: +        LL_ERRS() << "Only supposed to be called to generate models" << LL_ENDL; +        break; +    }  	//refresh LoDs that reference this one  	for (S32 i = lod - 1; i >= 0; --i) @@ -1721,7 +1737,10 @@ void LLFloaterModelPreview::onLoDSourceCommit(S32 lod)  	refresh();  	LLComboBox* lod_source_combo = getChild<LLComboBox>("lod_source_" + lod_name[lod]); -	if (lod_source_combo->getCurrentIndex() == LLModelPreview::GENERATE) +    S32 index = lod_source_combo->getCurrentIndex(); +	if (index == LLModelPreview::GENERATE +        || index == LLModelPreview::MESH_OPTIMIZER +        || index == LLModelPreview::MESH_OPTIMIZER_SLOPPY)  	{ //rebuild LoD to update triangle counts  		onLODParamCommit(lod, true);  	} @@ -1752,7 +1771,7 @@ void LLFloaterModelPreview::resetUploadOptions()  	getChild<LLComboBox>("lod_source_" + lod_name[NUM_LOD - 1])->setCurrentByIndex(LLModelPreview::LOD_FROM_FILE);  	for (S32 lod = 0; lod < NUM_LOD - 1; ++lod)  	{ -		getChild<LLComboBox>("lod_source_" + lod_name[lod])->setCurrentByIndex(LLModelPreview::GENERATE); +		getChild<LLComboBox>("lod_source_" + lod_name[lod])->setCurrentByIndex(LLModelPreview::MESH_OPTIMIZER);  		childSetValue("lod_file_" + lod_name[lod], "");  	} diff --git a/indra/newview/llkeyconflict.cpp b/indra/newview/llkeyconflict.cpp index b6107eeedf..58a740e16a 100644 --- a/indra/newview/llkeyconflict.cpp +++ b/indra/newview/llkeyconflict.cpp @@ -730,13 +730,19 @@ void LLKeyConflictHandler::resetToDefault(const std::string &control_name, U32 i      {          return;      } +    LLKeyConflict &type_data = mControlsMap[control_name]; +    if (!type_data.mAssignable) +    { +        return; +    }      LLKeyData data = getDefaultControl(control_name, index); -    if (data != mControlsMap[control_name].getKeyData(index)) +    if (data != type_data.getKeyData(index))      {          // reset controls that might have been switched to our current control          removeConflicts(data, mControlsMap[control_name].mConflictMask);          mControlsMap[control_name].setKeyData(data, index); +        mHasUnsavedChanges = true;      }  } @@ -862,7 +868,7 @@ void LLKeyConflictHandler::resetKeyboardBindings()  void LLKeyConflictHandler::generatePlaceholders(ESourceMode load_mode)  { -    // These controls are meant to cause conflicts when user tries to assign same control somewhere else +    // These placeholds are meant to cause conflict resolution when user tries to assign same control somewhere else      // also this can be used to pre-record controls that should not conflict or to assign conflict groups/masks      if (load_mode == MODE_FIRST_PERSON) @@ -922,25 +928,73 @@ void LLKeyConflictHandler::generatePlaceholders(ESourceMode load_mode)          registerTemporaryControl("spin_around_ccw_sitting");          registerTemporaryControl("spin_around_cw_sitting");      } + + +    // Special case, mouse clicks passed to scripts have 'lowest' piority +    // thus do not conflict, everything else has a chance before them +    // also in ML they have highest priority, but only when script-grabbed, +    // thus do not conflict +    // (see AGENT_CONTROL_ML_LBUTTON_DOWN and CONTROL_LBUTTON_DOWN_INDEX) +    LLKeyConflict *type_data = &mControlsMap[script_mouse_handler_name]; +    type_data->mAssignable = true; +    type_data->mConflictMask = U32_MAX - CONFLICT_LMOUSE;  } -bool LLKeyConflictHandler::removeConflicts(const LLKeyData &data, const U32 &conlict_mask) +bool LLKeyConflictHandler::removeConflicts(const LLKeyData &data, U32 conlict_mask)  {      if (conlict_mask == CONFLICT_NOTHING)      {          // Can't conflict          return true;      } + +    if (data.mMouse == CLICK_LEFT +        && data.mMask == MASK_NONE +        && data.mKey == KEY_NONE) +    { +        if ((conlict_mask & CONFLICT_LMOUSE) == 0) +        { +            // Can't conflict +            return true; +        } +        else +        { +            // simplify conflict mask +            conlict_mask = CONFLICT_LMOUSE; +        } +    } +    else +    { +        // simplify conflict mask +        conlict_mask &= ~CONFLICT_LMOUSE; +    } +      std::map<std::string, S32> conflict_list;      control_map_t::iterator cntrl_iter = mControlsMap.begin();      control_map_t::iterator cntrl_end = mControlsMap.end();      for (; cntrl_iter != cntrl_end; ++cntrl_iter)      { +        const U32 cmp_mask = cntrl_iter->second.mConflictMask; +        if ((cmp_mask & conlict_mask) == 0) +        { +            // can't conflict +            continue; +        }          S32 index = cntrl_iter->second.mKeyBind.findKeyData(data); -        if (index >= 0 -            && cntrl_iter->second.mConflictMask != CONFLICT_NOTHING -            && (cntrl_iter->second.mConflictMask & conlict_mask) != 0) +        if (index >= 0)          { +            if (cmp_mask != U32_MAX) +            { +                const LLKeyData cmp_data = cntrl_iter->second.mKeyBind.getKeyData(index); +                if ((cmp_mask & CONFLICT_LMOUSE) == 0 +                    && cmp_data.mMouse == CLICK_LEFT +                    && cmp_data.mMask == MASK_NONE +                    && cmp_data.mKey == KEY_NONE) +                { +                    // Does not conflict +                    continue; +                } +            }              if (cntrl_iter->second.mAssignable)              {                  // Potentially we can have multiple conflict flags conflicting diff --git a/indra/newview/llkeyconflict.h b/indra/newview/llkeyconflict.h index 2926ca3aeb..e78d2fa33b 100644 --- a/indra/newview/llkeyconflict.h +++ b/indra/newview/llkeyconflict.h @@ -66,6 +66,7 @@ public:      };      const U32 CONFLICT_NOTHING = 0; +    const U32 CONFLICT_LMOUSE = 0x1 << 1;      // at the moment this just means that key will conflict with everything that is identical      const U32 CONFLICT_ANY = U32_MAX; @@ -145,6 +146,7 @@ private:      // at the moment these kind of control is not savable, but takes part in conflict resolution      void registerTemporaryControl(const std::string &control_name, EMouseClickType mouse_ind, KEY key, MASK mask, U32 conflict_mask); +    // conflict mask 0 means that any conflicts will be ignored      void registerTemporaryControl(const std::string &control_name, U32 conflict_mask = 0);      typedef std::map<std::string, LLKeyConflict> control_map_t; @@ -152,7 +154,7 @@ private:      bool loadFromSettings(const ESourceMode &load_mode, const std::string &filename, control_map_t *destination);      void generatePlaceholders(ESourceMode load_mode); //E.x. non-assignable values      // returns false in case user is trying to reuse control that can't be reassigned -    bool removeConflicts(const LLKeyData &data, const U32 &conlict_mask); +    bool removeConflicts(const LLKeyData &data, U32 conlict_mask);      // removes flags and removes temporary file, returns 'true' if file was removed      bool clearUnsavedChanges(); diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index a9e80ab5da..93186657ce 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -41,6 +41,7 @@  #include "lliconctrl.h"  #include "llmatrix4a.h"  #include "llmeshrepository.h" +#include "llmeshoptimizer.h"  #include "llrender.h"  #include "llsdutil_math.h"  #include "llskinningutil.h" @@ -1339,8 +1340,9 @@ void LLModelPreview::restoreNormals()      updateStatusMessages();  } -void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_limit) +void LLModelPreview::genGlodLODs(S32 which_lod, U32 decimation, bool enforce_tri_limit)  { +    LL_INFOS() << "Generating lod " << which_lod << " using glod" << LL_ENDL;      // Allow LoD from -1 to LLModel::LOD_PHYSICS      if (which_lod < -1 || which_lod > LLModel::NUM_LODS - 1)      { @@ -1403,7 +1405,7 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim      U32 type_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0; -    U32 lod_mode = 0; +    U32 lod_mode = LIMIT_TRIANGLES;      F32 lod_error_threshold = 0; @@ -1424,7 +1426,7 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim          mRequestedLoDMode[which_lod] = lod_mode;      } -    if (lod_mode == 0) +    if (lod_mode == LIMIT_TRIANGLES)      {          lod_mode = GLOD_TRIANGLE_BUDGET; @@ -1704,6 +1706,276 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim      }  } +void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, U32 decimation, bool enforce_tri_limit, bool sloppy) +{ +    LL_INFOS() << "Generating lod " << which_lod << " using meshoptimizer" << LL_ENDL; +    // Allow LoD from -1 to LLModel::LOD_PHYSICS +    if (which_lod < -1 || which_lod > LLModel::NUM_LODS - 1) +    { +        std::ostringstream out; +        out << "Invalid level of detail: " << which_lod; +        LL_WARNS() << out.str() << LL_ENDL; +        LLFloaterModelPreview::addStringToLog(out, false); +        assert(lod >= -1 && lod < LLModel::NUM_LODS); +        return; +    } + +    if (mBaseModel.empty()) +    { +        return; +    } + +    //get the triangle count for all base models +    S32 base_triangle_count = 0; +    for (S32 i = 0; i < mBaseModel.size(); ++i) +    { +        base_triangle_count += mBaseModel[i]->getNumTriangles(); +    } + +    // Urgh... +    // TODO: add interface to mFMP to get error treshold or let mFMP write one into LLModelPreview +    // We should not be accesing views from other class! +    U32 lod_mode = LIMIT_TRIANGLES; +    F32 indices_ratio = 0; +    F32 triangle_limit = 0; +    F32 lod_error_threshold = 1; //100% + +    // If requesting a single lod +    if (which_lod > -1 && which_lod < NUM_LOD) +    { +        LLCtrlSelectionInterface* iface = mFMP->childGetSelectionInterface("lod_mode_" + lod_name[which_lod]); +        if (iface) +        { +            lod_mode = iface->getFirstSelectedIndex(); +        } + +        if (lod_mode == LIMIT_TRIANGLES) +        { +            if (!enforce_tri_limit) +            { +                triangle_limit = base_triangle_count; +                // reset to default value for this lod +                F32 pw = pow((F32)decimation, (F32)(LLModel::LOD_HIGH - which_lod)); + +                triangle_limit /= pw; //indices_ratio can be 1/pw +            } +            else +            { + +                // UI spacifies limit for all models of single lod +                triangle_limit = mFMP->childGetValue("lod_triangle_limit_" + lod_name[which_lod]).asInteger(); + +            } +            // meshoptimizer doesn't use triangle limit, it uses indices limit, so convert it to aproximate ratio +            indices_ratio = triangle_limit / (F32)base_triangle_count; +        } +        else +        { +            lod_error_threshold = mFMP->childGetValue("lod_error_threshold_" + lod_name[which_lod]).asReal(); +        } +    } +    else +    { +        // we are genrating all lods and each lod will get own indices_ratio +        indices_ratio = 1; +        triangle_limit = base_triangle_count; +    } + +    mMaxTriangleLimit = base_triangle_count; + +    // TODO: Glod regenerates vertex buffer at this stage +    // check why, it might be needed to regenerate buffer as well + +    // Build models + +    S32 start = LLModel::LOD_HIGH; +    S32 end = 0; + +    if (which_lod != -1) +    { +        start = which_lod; +        end = which_lod; +    } + +    LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; +    if (shader) +    { +        shader->unbind(); +    } + +    for (S32 lod = start; lod >= end; --lod) +    { +        if (which_lod == -1) +        { +            // we are genrating all lods and each lod gets own indices_ratio +            if (lod < start) +            { +                indices_ratio /= decimation; +                triangle_limit /= decimation; +            } +        } + +        mRequestedTriangleCount[lod] = triangle_limit; +        mRequestedErrorThreshold[lod] = lod_error_threshold; +        mRequestedLoDMode[lod] = lod_mode; + +        mModel[lod].clear(); +        mModel[lod].resize(mBaseModel.size()); +        mVertexBuffer[lod].clear(); + + +        for (U32 mdl_idx = 0; mdl_idx < mBaseModel.size(); ++mdl_idx) +        { +            LLModel* base = mBaseModel[mdl_idx]; + +            LLVolumeParams volume_params; +            volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE); +            mModel[lod][mdl_idx] = new LLModel(volume_params, 0.f); + +            std::string name = base->mLabel + getLodSuffix(lod); + +            mModel[lod][mdl_idx]->mLabel = name; +            mModel[lod][mdl_idx]->mSubmodelID = base->mSubmodelID; +            mModel[lod][mdl_idx]->setNumVolumeFaces(base->getNumVolumeFaces()); + +            LLModel* target_model = mModel[lod][mdl_idx]; + +            // Run meshoptimizer for each face +            for (U32 face_idx = 0; face_idx < base->getNumVolumeFaces(); ++face_idx) +            { +                const LLVolumeFace &face = base->getVolumeFace(face_idx); +                S32 num_indices = face.mNumIndices; +                // todo: do not allocate per each face, add one large buffer somewhere +                // faces have limited amount of indices +                S32 size = (num_indices * sizeof(U16) + 0xF) & ~0xF; +                U16* output = (U16*)ll_aligned_malloc_16(size); + +                /* +                generateShadowIndexBuffer appears to deform model +                LLMeshOptimizer::generateShadowIndexBuffer( +                    &shadow[0], +                    face.mIndices, +                    num_indices, +                    &face.mPositions[0], +                    face.mNumVertices); +                */ + +                S32 target_indices = llmax(3, llfloor(num_indices * indices_ratio)); // leave at least one triangle +                F32 result_code = 0; // how far from original the model is, 1 == 100% +                S32 new_indices = 0; + +                if (sloppy) +                { +                    new_indices = LLMeshOptimizer::simplifySloppy( +                        output, +                        face.mIndices, +                        num_indices, +                        face.mPositions, +                        face.mNumVertices, +                        LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_VERTEX], +                        target_indices, +                        lod_error_threshold, +                        &result_code); +                } + +                // todo: instead of checking (new_indices <= 0) +                // create a dummy triangle if simplifySloppy returns nothing +                if (new_indices <= 0) +                { +                    new_indices = LLMeshOptimizer::simplify( +                        output, +                        face.mIndices, +                        num_indices, +                        face.mPositions, +                        face.mNumVertices, +                        LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_VERTEX], +                        target_indices, +                        lod_error_threshold, +                        &result_code); +                } + + +                if (result_code < 0) +                { +                    LL_WARNS() << "Negative result code from meshoptimizer for face " << face_idx +                        << " of model " << target_model->mLabel +                        << " target Indices: " << target_indices +                        << " new Indices: " << new_indices +                        << " original count: " << num_indices << LL_ENDL; +                } +                if (new_indices == 0) +                { +                    LL_WARNS() << "No indices generated by meshoptimizer for face " << face_idx +                        << " of model " << target_model->mLabel +                        << " target Indices: " << target_indices +                        << " original count: " << num_indices << LL_ENDL; +                } + +                LLVolumeFace &new_face = target_model->getVolumeFace(face_idx); + +                // Copy old values +                new_face = face; + +                // Assign new values +                new_face.resizeIndices(new_indices); // will wipe out mIndices, so new_face can't substitute output +                S32 idx_size = (new_indices * sizeof(U16) + 0xF) & ~0xF; +                LLVector4a::memcpyNonAliased16((F32*)new_face.mIndices, (F32*)output, idx_size); + +                ll_aligned_free_16(output); + +                // clear unused values +                new_face.optimize(); +            } + +            //blind copy skin weights and just take closest skin weight to point on +            //decimated mesh for now (auto-generating LODs with skin weights is still a bit +            //of an open problem). +            target_model->mPosition = base->mPosition; +            target_model->mSkinWeights = base->mSkinWeights; +            target_model->mSkinInfo = base->mSkinInfo; + +            //copy material list +            target_model->mMaterialList = base->mMaterialList; + +            if (!validate_model(target_model)) +            { +                LL_ERRS() << "Invalid model generated when creating LODs" << LL_ENDL; +            } +        } + +        //rebuild scene based on mBaseScene +        mScene[lod].clear(); +        mScene[lod] = mBaseScene; + +        for (U32 i = 0; i < mBaseModel.size(); ++i) +        { +            LLModel* mdl = mBaseModel[i]; +            LLModel* target = mModel[lod][i]; +            if (target) +            { +                for (LLModelLoader::scene::iterator iter = mScene[lod].begin(); iter != mScene[lod].end(); ++iter) +                { +                    for (U32 j = 0; j < iter->second.size(); ++j) +                    { +                        if (iter->second[j].mModel == mdl) +                        { +                            iter->second[j].mModel = target; +                        } +                    } +                } +            } +        } +    } + +    mResourceCost = calcResourceCost(); + +    LLVertexBuffer::unbind(); +    if (shader) +    { +        shader->bind(); +    } +} +  void LLModelPreview::updateStatusMessages()  {      // bit mask values for physics errors. used to prevent overwrite of single line status @@ -2957,7 +3229,7 @@ BOOL LLModelPreview::render()      {          genBuffers(-1, skin_weight);          //genBuffers(3); -        //genLODs(); +        //genGlodLODs();      }      if (!mModel[mPreviewLOD].empty()) @@ -3544,7 +3816,7 @@ bool LLModelPreview::lodQueryCallback()          {              S32 lod = preview->mLodsQuery.back();              preview->mLodsQuery.pop_back(); -            preview->genLODs(lod); +            preview->genMeshOptimizerLODs(lod);              if (preview->mLookUpLodFiles && (lod == LLModel::LOD_HIGH))              { @@ -3559,11 +3831,20 @@ bool LLModelPreview::lodQueryCallback()      return true;  } -void LLModelPreview::onLODParamCommit(S32 lod, bool enforce_tri_limit) +void LLModelPreview::onLODGenerateParamCommit(S32 lod, bool enforce_tri_limit) +{ +    if (!mLODFrozen) +    { +        genGlodLODs(lod, 3, enforce_tri_limit); +        refresh(); +    } +} + +void LLModelPreview::onLODMeshOptimizerParamCommit(S32 requested_lod, bool enforce_tri_limit, bool sloppy)  {      if (!mLODFrozen)      { -        genLODs(lod, 3, enforce_tri_limit); +        genMeshOptimizerLODs(requested_lod, 3, enforce_tri_limit, sloppy);          refresh();      }  } diff --git a/indra/newview/llmodelpreview.h b/indra/newview/llmodelpreview.h index 3664a27a72..9f38156ca2 100644 --- a/indra/newview/llmodelpreview.h +++ b/indra/newview/llmodelpreview.h @@ -125,9 +125,17 @@ public:      {          LOD_FROM_FILE = 0,          GENERATE, +        MESH_OPTIMIZER, +        MESH_OPTIMIZER_SLOPPY,          USE_LOD_ABOVE,      } eLoDMode; +    typedef enum +    { +        LIMIT_TRIANGLES = 0, +        LIMIT_ERROR_TRESHOLD, +    } eLoDLimit; +  public:      // Todo: model preview shouldn't need floater dependency, it      // should just expose data to floater, not control flaoter like it does @@ -155,7 +163,8 @@ public:      void loadModelCallback(S32 lod);      bool lodsReady() { return !mGenLOD && mLodsQuery.empty(); }      void queryLODs() { mGenLOD = true; }; -    void genLODs(S32 which_lod = -1, U32 decimation = 3, bool enforce_tri_limit = false); +    void genGlodLODs(S32 which_lod = -1, U32 decimation = 3, bool enforce_tri_limit = false); +    void genMeshOptimizerLODs(S32 which_lod = -1, U32 decimation = 3, bool enforce_tri_limit = false, bool sloppy = false);      void generateNormals();      void restoreNormals();      U32 calcResourceCost(); @@ -166,7 +175,8 @@ public:      void updateStatusMessages();      void updateLodControls(S32 lod);      void clearGLODGroup(); -    void onLODParamCommit(S32 lod, bool enforce_tri_limit); +    void onLODGenerateParamCommit(S32 lod, bool enforce_tri_limit); +    void onLODMeshOptimizerParamCommit(S32 lod, bool enforce_tri_limit, bool sloppy);      void addEmptyFace(LLModel* pTarget);      const bool getModelPivot(void) const { return mHasPivot; } diff --git a/indra/newview/lltoolcomp.cpp b/indra/newview/lltoolcomp.cpp index f9c327b46e..9ac1810964 100644 --- a/indra/newview/lltoolcomp.cpp +++ b/indra/newview/lltoolcomp.cpp @@ -44,6 +44,7 @@  #include "lltoolmgr.h"  #include "lltoolselectrect.h"  #include "lltoolplacer.h" +#include "llviewerinput.h"  #include "llviewermenu.h"  #include "llviewerobject.h"  #include "llviewerwindow.h" @@ -743,7 +744,7 @@ BOOL LLToolCompGun::handleHover(S32 x, S32 y, MASK mask)  BOOL LLToolCompGun::handleMouseDown(S32 x, S32 y, MASK mask)  {   	// if the left button is grabbed, don't put up the pie menu -	if (gAgent.leftButtonGrabbed()) +	if (gAgent.leftButtonGrabbed() && gViewerInput.isLMouseHandlingDefault(MODE_FIRST_PERSON))  	{  		gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_DOWN);  		return FALSE; @@ -760,7 +761,7 @@ BOOL LLToolCompGun::handleMouseDown(S32 x, S32 y, MASK mask)  BOOL LLToolCompGun::handleDoubleClick(S32 x, S32 y, MASK mask)  {  	// if the left button is grabbed, don't put up the pie menu -	if (gAgent.leftButtonGrabbed()) +	if (gAgent.leftButtonGrabbed() && gViewerInput.isLMouseHandlingDefault(MODE_FIRST_PERSON))  	{  		gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_DOWN);  		return FALSE; @@ -794,7 +795,10 @@ BOOL LLToolCompGun::handleRightMouseDown(S32 x, S32 y, MASK mask)  BOOL LLToolCompGun::handleMouseUp(S32 x, S32 y, MASK mask)  { -	gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_UP); +    if (gViewerInput.isLMouseHandlingDefault(MODE_FIRST_PERSON)) +    { +        gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_UP); +    }  	setCurrentTool( (LLTool*) mGun );  	return TRUE;  } diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index 75a5fabdc2..0693775622 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -746,7 +746,7 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)  	else if (!mMouseOutsideSlop   		&& mMouseButtonDown  		// disable camera steering if click on land is not used for moving -		&& gViewerInput.isMouseBindUsed(CLICK_LEFT)) +		&& gViewerInput.isMouseBindUsed(CLICK_LEFT, MASK_NONE, MODE_THIRD_PERSON))  	{  		S32 delta_x = x - mMouseDownX;  		S32 delta_y = y - mMouseDownY; diff --git a/indra/newview/llviewerinput.cpp b/indra/newview/llviewerinput.cpp index c0eaa88f54..8b3d406b78 100644 --- a/indra/newview/llviewerinput.cpp +++ b/indra/newview/llviewerinput.cpp @@ -61,7 +61,7 @@ const F32 ORBIT_NUDGE_RATE = 0.05f;  // fraction of normal speed  const LLKeyData agent_control_lbutton(CLICK_LEFT, KEY_NONE, MASK_NONE, true);  struct LLKeyboardActionRegistry  -:	public LLRegistrySingleton<std::string, boost::function<bool (EKeystate keystate)>, LLKeyboardActionRegistry> +:	public LLRegistrySingleton<const std::string, boost::function<bool (EKeystate keystate)>, LLKeyboardActionRegistry>  {  	LLSINGLETON_EMPTY_CTOR(LLKeyboardActionRegistry);  }; @@ -836,7 +836,49 @@ bool voice_follow_key(EKeystate s)      return false;  } -bool agen_control_lbutton_handle(EKeystate s) +bool sript_trigger_lbutton(EKeystate s) +{ +    // Check for script overriding/expecting left mouse button. +    // Note that this does not pass event further and depends onto mouselook. +    // Checks CONTROL_ML_LBUTTON_DOWN_INDEX for mouselook, +    // CONTROL_LBUTTON_DOWN_INDEX for normal camera +    if (gAgent.leftButtonGrabbed()) +    { +        bool mouselook = gAgentCamera.cameraMouselook(); +        switch (s) +        { +        case KEYSTATE_DOWN: +            // at the moment sript_trigger_lbutton is only intended for mouselook +            // but handling other modes just in case +            if (mouselook) +            { +                gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_DOWN); +            } +            else +            { +                gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_DOWN); +            } +            return true; +        case KEYSTATE_UP: +            if (mouselook) +            { +                gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_UP); +            } +            else +            { +                gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_UP); +            } +            return true; +        default: +            break; +        } +    } +    return false; +} + +// Used by scripts, for overriding/handling left mouse button +// see mControlsTakenCount +bool agent_control_lbutton_handle(EKeystate s)  {      switch (s)      { @@ -905,6 +947,7 @@ REGISTER_KEYBOARD_ACTION("teleport_to", teleport_to);  REGISTER_KEYBOARD_ACTION("walk_to", walk_to);  REGISTER_KEYBOARD_ACTION("toggle_voice", toggle_voice);  REGISTER_KEYBOARD_ACTION("voice_follow_key", voice_follow_key); +REGISTER_KEYBOARD_ACTION(script_mouse_handler_name, sript_trigger_lbutton);  #undef REGISTER_KEYBOARD_ACTION  LLViewerInput::LLViewerInput() @@ -1104,6 +1147,20 @@ BOOL LLViewerInput::bindMouse(const S32 mode, const EMouseClickType mouse, const      typedef boost::function<bool(EKeystate)> function_t;      function_t function = NULL; +    if (mouse == CLICK_LEFT +        && mask == MASK_NONE +        && function_name == script_mouse_handler_name) +    { +        // Special case +        // Left click has script overrides and by default +        // is handled via agent_control_lbutton as last option +        // In case of mouselook and present overrides it has highest +        // priority even over UI and is handled in LLToolCompGun::handleMouseDown +        // so just mark it as having default handler +        mLMouseDefaultHandling[mode] = true; +        return TRUE; +    } +      function_t* result = LLKeyboardActionRegistry::getValue(function_name);      if (result)      { @@ -1164,6 +1221,7 @@ void LLViewerInput::resetBindings()      {          mKeyBindings[i].clear();          mMouseBindings[i].clear(); +        mLMouseDefaultHandling[i] = false;      }  } @@ -1355,13 +1413,14 @@ bool LLViewerInput::scanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level)      if (!res && agent_control_lbutton.canHandle(CLICK_NONE, key, mask))      { +        // pass mouse left button press to script          if (key_down && !repeat)          { -            res = agen_control_lbutton_handle(KEYSTATE_DOWN); +            res = agent_control_lbutton_handle(KEYSTATE_DOWN);          }          if (key_up)          { -            res = agen_control_lbutton_handle(KEYSTATE_UP); +            res = agent_control_lbutton_handle(KEYSTATE_UP);          }      }      return res; @@ -1481,24 +1540,28 @@ bool LLViewerInput::scanMouse(EMouseClickType click, EMouseState state) const      S32 mode = getMode();      MASK mask = gKeyboard->currentMask(TRUE);      res = scanMouse(mMouseBindings[mode], mMouseBindings[mode].size(), click, mask, state); +      // no user defined actions found or those actions can't handle the key/button, handle control if nessesary -    if (!res && agent_control_lbutton.canHandle(click, KEY_NONE, mask)) +    // This will pass AGENT_CONTROL_LBUTTON_DOWN to server, no idea why it doesn't do mouselook variant _ML_ +    // but it was set this way forever (moved as is from LLTool::handleMouseDown) so lots of scripts probably +    // rely on this. +    if (!res && mLMouseDefaultHandling[mode] && agent_control_lbutton.canHandle(click, KEY_NONE, mask))      {          switch (state)          {          case MOUSE_STATE_DOWN: -            agen_control_lbutton_handle(KEYSTATE_DOWN); +            agent_control_lbutton_handle(KEYSTATE_DOWN);              res = true;              break;          case MOUSE_STATE_CLICK:              // might not work best with some functions,              // but some function need specific states too specifically -            agen_control_lbutton_handle(KEYSTATE_DOWN); -            agen_control_lbutton_handle(KEYSTATE_UP); +            agent_control_lbutton_handle(KEYSTATE_DOWN); +            agent_control_lbutton_handle(KEYSTATE_UP);              res = true;              break;          case MOUSE_STATE_UP: -            agen_control_lbutton_handle(KEYSTATE_UP); +            agent_control_lbutton_handle(KEYSTATE_UP);              res = true;              break;          default: diff --git a/indra/newview/llviewerinput.h b/indra/newview/llviewerinput.h index 281a209896..32dd3c0e28 100644 --- a/indra/newview/llviewerinput.h +++ b/indra/newview/llviewerinput.h @@ -31,6 +31,7 @@  #include "llinitparam.h"  const S32 MAX_KEY_BINDINGS = 128; // was 60 +const std::string script_mouse_handler_name = "sript_trigger_lbutton";  class LLNamedFunction  { @@ -124,7 +125,8 @@ public:      BOOL            handleMouse(LLWindow *window_impl, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down);      void            scanMouse(); -    bool            isMouseBindUsed(const EMouseClickType mouse, const MASK mask = MASK_NONE, const S32 mode = MODE_THIRD_PERSON); +    bool            isMouseBindUsed(const EMouseClickType mouse, const MASK mask, const S32 mode); +    bool            isLMouseHandlingDefault(const S32 mode) { return mLMouseDefaultHandling[mode]; }  private:      bool            scanKey(const std::vector<LLKeyboardBinding> &binding, @@ -163,6 +165,7 @@ private:      // to send what we think function wants based on collection of bools (mKeyRepeated, mKeyLevel, mKeyDown)      std::vector<LLKeyboardBinding>	mKeyBindings[MODE_COUNT];      std::vector<LLMouseBinding>		mMouseBindings[MODE_COUNT]; +    bool							mLMouseDefaultHandling[MODE_COUNT]; // Due to having special priority  	typedef std::map<U32, U32> key_remap_t;  	key_remap_t		mRemapKeys[MODE_COUNT]; diff --git a/indra/newview/skins/default/xui/en/control_table_contents_media.xml b/indra/newview/skins/default/xui/en/control_table_contents_media.xml index ce5d3556b6..a97c45dd6f 100644 --- a/indra/newview/skins/default/xui/en/control_table_contents_media.xml +++ b/indra/newview/skins/default/xui/en/control_table_contents_media.xml @@ -73,4 +73,14 @@           name="lst_action"           value="Start Gesture" />      </rows> +    <rows +     name="sript_trigger_lbutton" +     value="sript_trigger_lbutton"> +        <columns +         column="lst_action" +         font="SansSerif" +         halign="left" +         name="lst_action" +         value="Interact (Script LMB)" /> +    </rows>  </contents> diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml index 7f863756eb..230284555c 100644 --- a/indra/newview/skins/default/xui/en/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml @@ -176,6 +176,14 @@                   name="Generate"                   label="Generate"                   value="Generate" /> +                <item +                 name="MeshOpt" +                 label="MeshOpt" +                 value="MeshOpt" /> +                <item +                 name="MeshOptSloppy" +                 label="MeshOptSloppy" +                 value="MeshOptSloppy" />              </combo_box>              <line_editor               follows="left|top" @@ -306,6 +314,14 @@                   label="Generate"                   value="Generate" />                  <item +                 name="MeshOpt" +                 label="MeshOpt" +                 value="MeshOpt" /> +                <item +                 name="MeshOptSloppy" +                 label="MeshOptSloppy" +                 value="MeshOptSloppy" /> +                <item                   name="Use LoD above"                   label="Use LoD above"                   value="Use LoD above" /> @@ -439,6 +455,14 @@                   label="Generate"                   value="Generate" />                  <item +                 name="MeshOpt" +                 label="MeshOpt" +                 value="MeshOpt" /> +                <item +                 name="MeshOptSloppy" +                 label="MeshOptSloppy" +                 value="MeshOptSloppy" /> +                <item                   name="Use LoD above"                   label="Use LoD above"                   value="Use LoD above" /> @@ -572,6 +596,14 @@                   label="Generate"                   value="Generate" />                  <item +                 name="MeshOpt" +                 label="MeshOpt" +                 value="MeshOpt" /> +                <item +                 name="MeshOptSloppy" +                 label="MeshOptSloppy" +                 value="MeshOptSloppy" /> +                <item                   name="Use LoD above"                   label="Use LoD above"                   value="Use LoD above" />  | 
