summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/CMakeLists.txt12
-rw-r--r--indra/newview/app_settings/settings.xml27
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl4
-rw-r--r--indra/newview/licenses-win32.txt69
-rw-r--r--indra/newview/llappviewer.cpp98
-rw-r--r--indra/newview/llassetuploadresponders.cpp778
-rw-r--r--indra/newview/llassetuploadresponders.h55
-rw-r--r--indra/newview/lldrawable.cpp22
-rw-r--r--indra/newview/lldrawable.h6
-rw-r--r--indra/newview/lldrawpoolbump.cpp12
-rw-r--r--indra/newview/lldrawpoolbump.h2
-rw-r--r--indra/newview/llface.cpp31
-rw-r--r--indra/newview/llfilepicker.cpp28
-rw-r--r--indra/newview/llfilepicker.h4
-rw-r--r--indra/newview/llhudtext.cpp12
-rw-r--r--indra/newview/llhudtext.h1
-rw-r--r--indra/newview/llinventorybridge.cpp94
-rw-r--r--indra/newview/llinventorybridge.h35
-rw-r--r--indra/newview/llinventoryfunctions.cpp3
-rw-r--r--indra/newview/llpanelgroupnotices.cpp1
-rw-r--r--indra/newview/llpanelobjectinventory.cpp117
-rw-r--r--indra/newview/llselectmgr.cpp80
-rw-r--r--indra/newview/llselectmgr.h1
-rw-r--r--indra/newview/llspatialpartition.cpp1
-rw-r--r--indra/newview/llspatialpartition.h1
-rw-r--r--indra/newview/lltexturectrl.cpp6
-rw-r--r--indra/newview/lltooldraganddrop.cpp2
-rw-r--r--indra/newview/llviewerassettype.cpp2
-rw-r--r--indra/newview/llviewerdisplay.cpp8
-rw-r--r--indra/newview/llviewerfloaterreg.cpp6
-rw-r--r--indra/newview/llviewermenu.cpp2
-rw-r--r--indra/newview/llviewermenufile.cpp456
-rw-r--r--indra/newview/llviewermenufile.h83
-rw-r--r--indra/newview/llviewermessage.cpp3
-rw-r--r--indra/newview/llviewerobjectlist.cpp4
-rw-r--r--indra/newview/llviewerregion.cpp3
-rw-r--r--indra/newview/llviewertexteditor.cpp1
-rw-r--r--indra/newview/llviewertexture.cpp14
-rw-r--r--indra/newview/llviewertexture.h2
-rw-r--r--indra/newview/llviewerwindow.cpp134
-rw-r--r--indra/newview/llvovolume.cpp211
-rw-r--r--indra/newview/llvovolume.h11
-rw-r--r--indra/newview/llworld.cpp2
-rw-r--r--indra/newview/pipeline.cpp75
-rw-r--r--indra/newview/pipeline.h9
-rw-r--r--indra/newview/skins/default/textures/textures.xml3
-rw-r--r--indra/newview/skins/default/xui/en/floater_about.xml3
-rw-r--r--indra/newview/skins/default/xui/en/floater_inventory.xml21
-rw-r--r--indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml29
-rw-r--r--indra/newview/skins/default/xui/en/floater_tools.xml3
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml4
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml13
-rw-r--r--indra/newview/skins/default/xui/en/panel_main_inventory.xml24
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml1
-rwxr-xr-xindra/newview/viewer_manifest.py8
56 files changed, 2113 insertions, 526 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 8953682fae..193109e9f4 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -37,11 +37,13 @@ include(UnixInstall)
include(LLKDU)
include(ViewerMiscLibs)
include(LLLogin)
+include(GLOD)
include(CMakeCopyIfDifferent)
include_directories(
${DBUSGLIB_INCLUDE_DIRS}
${ELFIO_INCLUDE_DIR}
+ ${GLOD_INCLUDE_DIR}
${LLAUDIO_INCLUDE_DIRS}
${LLCHARACTER_INCLUDE_DIRS}
${LLCOMMON_INCLUDE_DIRS}
@@ -60,6 +62,8 @@ include_directories(
${LSCRIPT_INCLUDE_DIRS}
${LSCRIPT_INCLUDE_DIRS}/lscript_compile
${LLLOGIN_INCLUDE_DIRS}
+ ${LIBS_PREBUILT_DIR}/include/collada
+ ${LIBS_PREBUILT_DIR}/include/collada/1.4
)
set(viewer_SOURCE_FILES
@@ -176,6 +180,7 @@ set(viewer_SOURCE_FILES
llfloaterhelpbrowser.cpp
llfloaterhud.cpp
llfloaterimagepreview.cpp
+ llfloaterimportcollada.cpp
llfloaterinspect.cpp
llfloaterinventory.cpp
llfloaterjoystick.cpp
@@ -186,6 +191,7 @@ set(viewer_SOURCE_FILES
llfloatermediabrowser.cpp
llfloatermediasettings.cpp
llfloatermemleak.cpp
+ llfloatermodelpreview.cpp
llfloaternamedesc.cpp
llfloaternearbymedia.cpp
llfloaternotificationsconsole.cpp
@@ -278,6 +284,7 @@ set(viewer_SOURCE_FILES
llmediaremotectrl.cpp
llmemoryview.cpp
llmenucommands.cpp
+ llmeshrepository.cpp
llmetricperformancetester.cpp
llmimetypes.cpp
llmorphview.cpp
@@ -685,6 +692,7 @@ set(viewer_HEADER_FILES
llfloaterhelpbrowser.h
llfloaterhud.h
llfloaterimagepreview.h
+ llfloaterimportcollada.h
llfloaterinspect.h
llfloaterinventory.h
llfloaterjoystick.h
@@ -695,6 +703,7 @@ set(viewer_HEADER_FILES
llfloatermediabrowser.h
llfloatermediasettings.h
llfloatermemleak.h
+ llfloatermodelpreview.h
llfloaternamedesc.h
llfloaternearbymedia.h
llfloaternotificationsconsole.h
@@ -786,6 +795,7 @@ set(viewer_HEADER_FILES
llmediaremotectrl.h
llmemoryview.h
llmenucommands.h
+ llmeshrepository.h
llmetricperformancetester.h
llmimetypes.h
llmorphview.h
@@ -1197,6 +1207,7 @@ if (WINDOWS)
${DINPUT_LIBRARY}
${DXGUID_LIBRARY}
kernel32
+ libboost_system
odbc32
odbccp32
ole32
@@ -1589,6 +1600,7 @@ target_link_libraries(${VIEWER_BINARY_NAME}
${DBUSGLIB_LIBRARIES}
${OPENGL_LIBRARIES}
${FMODWRAPPER_LIBRARY} # must come after LLAudio
+ ${GLOD_LIBRARIES}
${OPENGL_LIBRARIES}
${SDL_LIBRARY}
${SMARTHEAP_LIBRARY}
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 6fa839235a..4285781742 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -7484,7 +7484,30 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>SafeMode</key>
+ <key>MeshThreadCount</key>
+ <map>
+ <key>Comment</key>
+ <string>Number of threads to use for loading meshes.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <integer>8</integer>
+ </map>
+ <key>MeshMaxConcurrentRequests</key>
+ <map>
+ <key>Comment</key>
+ <string>Number of threads to use for loading meshes.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <integer>32</integer>
+ </map>
+
+ <key>SafeMode</key>
<map>
<key>Comment</key>
<string>Reset preferences, run in safe mode.</string>
@@ -10034,7 +10057,7 @@
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
- <integer>1</integer>
+ <integer>0</integer>
</map>
<key>UseStartScreen</key>
<map>
diff --git a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl
index 651959413c..45884d5732 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl
@@ -137,7 +137,7 @@ void main()
}
//float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
- vec4 amb_plcol = texture2DLod(projectionMap, proj_tc.xy, proj_ambient_lod);
+ vec4 amb_plcol = texture2DLod(projectionMap, proj_tc.xy, proj_lod);
amb_da += (da*da*0.5+0.5)*proj_ambiance;
diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl
index a0026edcd2..4333cc64a7 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl
@@ -224,11 +224,11 @@ void main()
//spotlight shadow 1
vec4 lpos = shadow_matrix[4]*spos;
- gl_FragColor[2] = pcfShadow(shadowMap4, lpos, 0.1).x;
+ gl_FragColor[2] = pcfShadow(shadowMap4, lpos, 0.8).x;
//spotlight shadow 2
lpos = shadow_matrix[5]*spos;
- gl_FragColor[3] = pcfShadow(shadowMap5, lpos, 0.1).x;
+ gl_FragColor[3] = pcfShadow(shadowMap5, lpos, 0.8).x;
//gl_FragColor.rgb = pos.xyz;
//gl_FragColor.b = shadow;
diff --git a/indra/newview/licenses-win32.txt b/indra/newview/licenses-win32.txt
index 7e6d4b4561..8736626907 100644
--- a/indra/newview/licenses-win32.txt
+++ b/indra/newview/licenses-win32.txt
@@ -769,3 +769,72 @@ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+=============
+GLOD license
+=============
+The GLOD Open-Source License Version 1.0 June 16, 2004
+
+Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns
+Hopkins University and David Luebke, Brenden Schubert, University of
+Virginia. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, is permitted provided that the following conditions are
+met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer and
+ request.
+
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer and
+ request in the documentation and/or other materials provided with
+ the distribution.
+
+3. The name "GLOD" must not be used to endorse or promote products
+ derived from this software without prior written permission.
+
+4. Redistributions of any modified version of this source, whether in
+ source or binary form , must include a form of the following
+ acknowledgment: "This product is derived from the GLOD library,
+ which is available from http://www.cs.jhu.edu/~graphics/GLOD."
+
+5. Redistributions of any modified version of this source in binary
+ form must provide, free of charge, access to the modified version
+ of the code.
+
+6. This license shall be governed by and construed and enforced in
+ accordance with the laws of the State of Maryland, without
+ reference to its conflicts of law provisions. The exclusive
+ jurisdiction and venue for all legal actions relating to this
+ license shall be in courts of competent subject matter jurisdiction
+ located in the State of Maryland.
+
+TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, GLOD IS PROVIDED
+UNDER THIS LICENSE ON AN AS IS BASIS, WITHOUT WARRANTY OF ANY KIND,
+EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
+THAT GLOD IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR
+PURPOSE OR NON-INFRINGING. ALL WARRANTIES ARE DISCLAIMED AND THE
+ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE CODE IS WITH
+YOU. SHOULD ANY CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE
+COPYRIGHT HOLDER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY
+NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY
+CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY CODE IS
+AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
+
+TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL
+THE COPYRIGHT HOLDER OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY
+SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES FOR LOSS OF
+PROFITS, REVENUE, OR FOR LOSS OF INFORMATION OR ANY OTHER LOSS.
+
+YOU EXPRESSLY AGREE TO FOREVER INDEMNIFY, DEFEND AND HOLD HARMLESS THE
+COPYRIGHT HOLDERS AND CONTRIBUTORS OF GLOD AGAINST ALL CLAIMS,
+DEMANDS, SUITS OR OTHER ACTIONS ARISING DIRECTLY OR INDIRECTLY FROM
+YOUR ACCEPTANCE AND USE OF GLOD.
+
+Although NOT REQUIRED, we would appreciate it if active users of GLOD
+put a link on their web site to the GLOD web site when possible.
+
+
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 07b3399637..753388427a 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -47,6 +47,7 @@
#include "llwindow.h"
#include "llviewerstats.h"
#include "llmd5.h"
+#include "llmeshrepository.h"
#include "llpumpio.h"
#include "llmimetypes.h"
#include "llslurl.h"
@@ -920,6 +921,9 @@ static LLFastTimer::DeclareTimer FTM_LFS("LFS Thread");
static LLFastTimer::DeclareTimer FTM_PAUSE_THREADS("Pause Threads");
static LLFastTimer::DeclareTimer FTM_IDLE("Idle");
static LLFastTimer::DeclareTimer FTM_PUMP("Pump");
+static LLFastTimer::DeclareTimer FTM_PUMP_ARES("Ares");
+static LLFastTimer::DeclareTimer FTM_PUMP_SERVICE("Service");
+static LLFastTimer::DeclareTimer FTM_SERVICE_CALLBACK("Callback");
bool LLAppViewer::mainLoop()
{
@@ -1031,10 +1035,20 @@ bool LLAppViewer::mainLoop()
LLMemType mt_ip(LLMemType::MTYPE_IDLE_PUMP);
pingMainloopTimeout("Main:ServicePump");
LLFastTimer t4(FTM_PUMP);
- gAres->process();
- // this pump is necessary to make the login screen show up
- gServicePump->pump();
- gServicePump->callback();
+ {
+ LLFastTimer t(FTM_PUMP_ARES);
+ gAres->process();
+ }
+ {
+ LLFastTimer t(FTM_PUMP_SERVICE);
+ // this pump is necessary to make the login screen show up
+ gServicePump->pump();
+
+ {
+ LLFastTimer t(FTM_SERVICE_CALLBACK);
+ gServicePump->callback();
+ }
+ }
}
resumeMainloopTimeout();
@@ -1273,6 +1287,9 @@ bool LLAppViewer::cleanup()
llinfos << "Cleaning Up" << llendflush;
+ // shut down mesh streamer
+ gMeshRepo.shutdown();
+
// Must clean up texture references before viewer window is destroyed.
LLHUDManager::getInstance()->updateEffects();
LLHUDObject::updateAll();
@@ -1685,6 +1702,9 @@ bool LLAppViewer::initThreads()
mFastTimerLogThread->start();
}
+ // Mesh streaming and caching
+ gMeshRepo.init();
+
// *FIX: no error handling here!
return true;
}
@@ -2401,6 +2421,7 @@ bool LLAppViewer::initWindow()
gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE );
gPipeline.init();
+
stop_glerror();
gViewerWindow->initGLDefaults();
@@ -3379,6 +3400,10 @@ static LLFastTimer::DeclareTimer FTM_OBJECTLIST_UPDATE("Update Objectlist");
static LLFastTimer::DeclareTimer FTM_REGION_UPDATE("Update Region");
static LLFastTimer::DeclareTimer FTM_WORLD_UPDATE("Update World");
static LLFastTimer::DeclareTimer FTM_NETWORK("Network");
+static LLFastTimer::DeclareTimer FTM_AGENT_NETWORK("Agent Network");
+static LLFastTimer::DeclareTimer FTM_AGENT_AUTOPILOT("Autopilot");
+static LLFastTimer::DeclareTimer FTM_AGENT_UPDATE("Update");
+static LLFastTimer::DeclareTimer FTM_VLMANAGER("VL Manager");
///////////////////////////////////////////////////////
// idle()
@@ -3449,7 +3474,7 @@ void LLAppViewer::idle()
if (!gDisconnected)
{
- LLFastTimer t(FTM_NETWORK);
+ LLFastTimer t(FTM_AGENT_NETWORK);
// Update spaceserver timeinfo
LLWorld::getInstance()->setSpaceTimeUSec(LLWorld::getInstance()->getSpaceTimeUSec() + (U32)(dt_raw * SEC_TO_MICROSEC));
@@ -3464,9 +3489,12 @@ void LLAppViewer::idle()
gAgent.moveYaw(-1.f);
}
- // Handle automatic walking towards points
- gAgentPilot.updateTarget();
- gAgent.autoPilot(&yaw);
+ {
+ LLFastTimer t(FTM_AGENT_AUTOPILOT);
+ // Handle automatic walking towards points
+ gAgentPilot.updateTarget();
+ gAgent.autoPilot(&yaw);
+ }
static LLFrameTimer agent_update_timer;
static U32 last_control_flags;
@@ -3477,6 +3505,7 @@ void LLAppViewer::idle()
if (flags_changed || (agent_update_time > (1.0f / (F32) AGENT_UPDATES_PER_SECOND)))
{
+ LLFastTimer t(FTM_AGENT_UPDATE);
// Send avatar and camera info
last_control_flags = gAgent.getControlFlags();
send_agent_update(TRUE);
@@ -3638,7 +3667,7 @@ void LLAppViewer::idle()
//
{
- LLFastTimer t(FTM_NETWORK);
+ LLFastTimer t(FTM_VLMANAGER);
gVLManager.unpackData();
}
@@ -3883,7 +3912,12 @@ void LLAppViewer::sendLogoutRequest()
static F32 CheckMessagesMaxTime = CHECK_MESSAGES_DEFAULT_MAX_TIME;
#endif
-static LLFastTimer::DeclareTimer FTM_IDLE_NETWORK("Network");
+static LLFastTimer::DeclareTimer FTM_IDLE_NETWORK("Idle Network");
+static LLFastTimer::DeclareTimer FTM_MESSAGE_ACKS("Message Acks");
+static LLFastTimer::DeclareTimer FTM_RETRANSMIT("Retransmit");
+static LLFastTimer::DeclareTimer FTM_TIMEOUT_CHECK("Timeout Check");
+static LLFastTimer::DeclareTimer FTM_DYNAMIC_THROTTLE("Dynamic Throttle");
+static LLFastTimer::DeclareTimer FTM_CHECK_REGION_CIRCUIT("Check Region Circuit");
void LLAppViewer::idleNetwork()
{
@@ -3937,7 +3971,10 @@ void LLAppViewer::idleNetwork()
}
// Handle per-frame message system processing.
- gMessageSystem->processAcks();
+ {
+ LLFastTimer ftm(FTM_MESSAGE_ACKS);
+ gMessageSystem->processAcks();
+ }
#ifdef TIME_THROTTLE_MESSAGES
if (total_time >= CheckMessagesMaxTime)
@@ -3975,26 +4012,41 @@ void LLAppViewer::idleNetwork()
LLViewerStats::getInstance()->mNumNewObjectsStat.addValue(gObjectList.mNumNewObjects);
// Retransmit unacknowledged packets.
- gXferManager->retransmitUnackedPackets();
- gAssetStorage->checkForTimeouts();
+ {
+ LLFastTimer ftm(FTM_RETRANSMIT);
+ gXferManager->retransmitUnackedPackets();
+ }
+
+ {
+ LLFastTimer ftm(FTM_TIMEOUT_CHECK);
+ gAssetStorage->checkForTimeouts();
+ }
+
llpushcallstacks ;
- gViewerThrottle.updateDynamicThrottle();
+
+ {
+ LLFastTimer ftm(FTM_DYNAMIC_THROTTLE);
+ gViewerThrottle.updateDynamicThrottle();
+ }
llpushcallstacks ;
// Check that the circuit between the viewer and the agent's current
// region is still alive
- LLViewerRegion *agent_region = gAgent.getRegion();
- if (agent_region && (LLStartUp::getStartupState()==STATE_STARTED))
{
- LLUUID this_region_id = agent_region->getRegionID();
- bool this_region_alive = agent_region->isAlive();
- if ((mAgentRegionLastAlive && !this_region_alive) // newly dead
- && (mAgentRegionLastID == this_region_id)) // same region
+ LLFastTimer ftm(FTM_CHECK_REGION_CIRCUIT);
+ LLViewerRegion *agent_region = gAgent.getRegion();
+ if (agent_region && (LLStartUp::getStartupState()==STATE_STARTED))
{
- forceDisconnect(LLTrans::getString("AgentLostConnection"));
+ LLUUID this_region_id = agent_region->getRegionID();
+ bool this_region_alive = agent_region->isAlive();
+ if ((mAgentRegionLastAlive && !this_region_alive) // newly dead
+ && (mAgentRegionLastID == this_region_id)) // same region
+ {
+ forceDisconnect(LLTrans::getString("AgentLostConnection"));
+ }
+ mAgentRegionLastID = this_region_id;
+ mAgentRegionLastAlive = this_region_alive;
}
- mAgentRegionLastID = this_region_id;
- mAgentRegionLastAlive = this_region_alive;
}
llpushcallstacks ;
}
diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp
index a2322e28b4..a0be6efdc2 100644
--- a/indra/newview/llassetuploadresponders.cpp
+++ b/indra/newview/llassetuploadresponders.cpp
@@ -41,6 +41,7 @@
#include "llfilepicker.h"
#include "llinventoryobserver.h"
#include "llinventorypanel.h"
+#include "llfloaterimportcollada.h"
#include "llpermissionsflags.h"
#include "llpreviewnotecard.h"
#include "llpreviewscript.h"
@@ -64,6 +65,7 @@
#include "llnotificationsutil.h"
#include "llscrolllistctrl.h"
#include "llsdserialize.h"
+#include "llsdutil.h"
#include "llvfs.h"
// When uploading multiple files, don't display any of them when uploading more than this number.
@@ -71,6 +73,120 @@ static const S32 FILE_COUNT_DISPLAY_THRESHOLD = 5;
void dialog_refresh_all();
+static void on_new_single_inventory_upload_complete(
+ LLAssetType::EType asset_type,
+ LLInventoryType::EType inventory_type,
+ const std::string inventory_type_string,
+ const LLUUID& item_folder_id,
+ const std::string& item_name,
+ const std::string& item_description,
+ const LLSD& server_response,
+ S32 upload_price)
+{
+ if ( upload_price > 0 )
+ {
+ // this upload costed us L$, update our balance
+ // and display something saying that it cost L$
+ LLStatusBar::sendMoneyBalanceRequest();
+
+ LLSD args;
+ args["AMOUNT"] = llformat("%d", upload_price);
+ LLNotificationsUtil::add("UploadPayment", args);
+ }
+
+ // Actually add the upload to viewer inventory
+ llinfos << "Adding " << server_response["new_inventory_item"].asUUID()
+ << " " << server_response["new_asset"].asUUID()
+ << " to inventory." << llendl;
+
+ if( item_folder_id.notNull() )
+ {
+ U32 everyone_perms = PERM_NONE;
+ U32 group_perms = PERM_NONE;
+ U32 next_owner_perms = PERM_ALL;
+ if( server_response.has("new_next_owner_mask") )
+ {
+ // The server provided creation perms so use them.
+ // Do not assume we got the perms we asked for in
+ // since the server may not have granted them all.
+ everyone_perms = server_response["new_everyone_mask"].asInteger();
+ group_perms = server_response["new_group_mask"].asInteger();
+ next_owner_perms = server_response["new_next_owner_mask"].asInteger();
+ }
+ else
+ {
+ // The server doesn't provide creation perms
+ // so use old assumption-based perms.
+ if( inventory_type_string != "snapshot")
+ {
+ next_owner_perms = PERM_MOVE | PERM_TRANSFER;
+ }
+ }
+
+ LLPermissions new_perms;
+ new_perms.init(
+ gAgent.getID(),
+ gAgent.getID(),
+ LLUUID::null,
+ LLUUID::null);
+
+ new_perms.initMasks(
+ PERM_ALL,
+ PERM_ALL,
+ everyone_perms,
+ group_perms,
+ next_owner_perms);
+
+ S32 creation_date_now = time_corrected();
+ LLPointer<LLViewerInventoryItem> item = new LLViewerInventoryItem(
+ server_response["new_inventory_item"].asUUID(),
+ item_folder_id,
+ new_perms,
+ server_response["new_asset"].asUUID(),
+ asset_type,
+ inventory_type,
+ item_name,
+ item_description,
+ LLSaleInfo::DEFAULT,
+ LLInventoryItem::II_FLAGS_NONE,
+ creation_date_now);
+
+ gInventory.updateItem(item);
+ gInventory.notifyObservers();
+
+ // Show the preview panel for textures and sounds to let
+ // user know that the image (or snapshot) arrived intact.
+ LLInventoryPanel* panel = LLInventoryPanel::getActiveInventoryPanel();
+ if ( panel )
+ {
+ LLFocusableElement* focus = gFocusMgr.getKeyboardFocus();
+
+ panel->setSelection(
+ server_response["new_inventory_item"].asUUID(),
+ TAKE_FOCUS_NO);
+
+ if(
+ (LLAssetType::AT_TEXTURE == asset_type ||
+ LLAssetType::AT_SOUND == asset_type) &&
+ (LLFilePicker::instance().getFileCount() <=
+ FILE_COUNT_DISPLAY_THRESHOLD) )
+ {
+ panel->openSelected();
+ }
+
+ // restore keyboard focus
+ gFocusMgr.setKeyboardFocus(focus);
+ }
+ }
+ else
+ {
+ llwarns << "Can't find a folder to put it in" << llendl;
+ }
+
+ // remove the "Uploading..." message
+ LLUploadDialog::modalUploadFinished();
+}
+
LLAssetUploadResponder::LLAssetUploadResponder(const LLSD &post_data,
const LLUUID& vfile_id,
LLAssetType::EType asset_type)
@@ -88,9 +204,10 @@ LLAssetUploadResponder::LLAssetUploadResponder(const LLSD &post_data,
}
}
-LLAssetUploadResponder::LLAssetUploadResponder(const LLSD &post_data,
- const std::string& file_name,
- LLAssetType::EType asset_type)
+LLAssetUploadResponder::LLAssetUploadResponder(
+ const LLSD &post_data,
+ const std::string& file_name,
+ LLAssetType::EType asset_type)
: LLHTTPClient::Responder(),
mPostData(post_data),
mFileName(file_name),
@@ -138,6 +255,7 @@ void LLAssetUploadResponder::result(const LLSD& content)
lldebugs << "LLAssetUploadResponder::result from capabilities" << llendl;
std::string state = content["state"];
+
if (state == "upload")
{
uploadUpload(content);
@@ -196,16 +314,36 @@ void LLAssetUploadResponder::uploadComplete(const LLSD& content)
{
}
-LLNewAgentInventoryResponder::LLNewAgentInventoryResponder(const LLSD& post_data,
- const LLUUID& vfile_id,
- LLAssetType::EType asset_type)
-: LLAssetUploadResponder(post_data, vfile_id, asset_type)
+LLNewAgentInventoryResponder::LLNewAgentInventoryResponder(
+ const LLSD& post_data,
+ const LLUUID& vfile_id,
+ LLAssetType::EType asset_type)
+ : LLAssetUploadResponder(post_data, vfile_id, asset_type)
{
}
-LLNewAgentInventoryResponder::LLNewAgentInventoryResponder(const LLSD& post_data, const std::string& file_name, LLAssetType::EType asset_type)
-: LLAssetUploadResponder(post_data, file_name, asset_type)
+LLNewAgentInventoryResponder::LLNewAgentInventoryResponder(
+ const LLSD& post_data,
+ const std::string& file_name,
+ LLAssetType::EType asset_type)
+ : LLAssetUploadResponder(post_data, file_name, asset_type)
+{
+}
+
+// virtual
+void LLNewAgentInventoryResponder::error(U32 statusNum, const std::string& reason)
+{
+ LLAssetUploadResponder::error(statusNum, reason);
+ LLImportColladaAssetCache::getInstance()->assetUploaded(mVFileID, LLUUID(), FALSE);
+}
+
+
+//virtual
+void LLNewAgentInventoryResponder::uploadFailure(const LLSD& content)
{
+ LLAssetUploadResponder::uploadFailure(content);
+
+ LLImportColladaAssetCache::getInstance()->assetUploaded(mVFileID, content["new_asset"], FALSE);
}
//virtual
@@ -219,95 +357,31 @@ void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content)
LLAssetType::EType asset_type = LLAssetType::lookup(mPostData["asset_type"].asString());
LLInventoryType::EType inventory_type = LLInventoryType::lookup(mPostData["inventory_type"].asString());
- S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
+ S32 expected_upload_cost = 0;
// Update L$ and ownership credit information
// since it probably changed on the server
if (asset_type == LLAssetType::AT_TEXTURE ||
asset_type == LLAssetType::AT_SOUND ||
- asset_type == LLAssetType::AT_ANIMATION)
+ asset_type == LLAssetType::AT_ANIMATION ||
+ asset_type == LLAssetType::AT_MESH)
{
- LLStatusBar::sendMoneyBalanceRequest();
-
- LLSD args;
- args["AMOUNT"] = llformat("%d", expected_upload_cost);
- LLNotificationsUtil::add("UploadPayment", args);
+ expected_upload_cost =
+ LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
}
- // Actually add the upload to viewer inventory
- llinfos << "Adding " << content["new_inventory_item"].asUUID() << " "
- << content["new_asset"].asUUID() << " to inventory." << llendl;
- if(mPostData["folder_id"].asUUID().notNull())
- {
- //std::ostringstream out;
- //LLSDXMLFormatter *formatter = new LLSDXMLFormatter;
- //formatter->format(mPostData, out, LLSDFormatter::OPTIONS_PRETTY);
- //llinfos << "Post Data: " << out.str() << llendl;
+ on_new_single_inventory_upload_complete(
+ asset_type,
+ inventory_type,
+ mPostData["asset_type"].asString(),
+ mPostData["folder_id"].asUUID(),
+ mPostData["name"],
+ mPostData["description"],
+ content,
+ expected_upload_cost);
- U32 everyone_perms = PERM_NONE;
- U32 group_perms = PERM_NONE;
- U32 next_owner_perms = PERM_ALL;
- if(content.has("new_next_owner_mask"))
- {
- // This is a new sim that provides creation perms so use them.
- // Do not assume we got the perms we asked for in mPostData
- // since the sim may not have granted them all.
- everyone_perms = content["new_everyone_mask"].asInteger();
- group_perms = content["new_group_mask"].asInteger();
- next_owner_perms = content["new_next_owner_mask"].asInteger();
- }
- else
- {
- // This old sim doesn't provide creation perms so use old assumption-based perms.
- if(mPostData["inventory_type"].asString() != "snapshot")
- {
- next_owner_perms = PERM_MOVE | PERM_TRANSFER;
- }
- }
- LLPermissions new_perms;
- new_perms.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null);
- new_perms.initMasks(PERM_ALL, PERM_ALL, everyone_perms, group_perms, next_owner_perms);
- S32 creation_date_now = time_corrected();
- LLPointer<LLViewerInventoryItem> item
- = new LLViewerInventoryItem(content["new_inventory_item"].asUUID(),
- mPostData["folder_id"].asUUID(),
- new_perms,
- content["new_asset"].asUUID(),
- asset_type,
- inventory_type,
- mPostData["name"].asString(),
- mPostData["description"].asString(),
- LLSaleInfo::DEFAULT,
- LLInventoryItem::II_FLAGS_NONE,
- creation_date_now);
- gInventory.updateItem(item);
- gInventory.notifyObservers();
-
- // Show the preview panel for textures and sounds to let
- // user know that the image (or snapshot) arrived intact.
- LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel();
- if (active_panel)
- {
- active_panel->setSelection(content["new_inventory_item"].asUUID(), TAKE_FOCUS_NO);
- if((LLAssetType::AT_TEXTURE == asset_type || LLAssetType::AT_SOUND == asset_type)
- && LLFilePicker::instance().getFileCount() <= FILE_COUNT_DISPLAY_THRESHOLD)
- {
- active_panel->openSelected();
- }
- //LLFloaterInventory::dumpSelectionInformation((void*)view);
- // restore keyboard focus
- LLFocusableElement* focus = gFocusMgr.getKeyboardFocus();
- gFocusMgr.setKeyboardFocus(focus);
- }
- }
- else
- {
- llwarns << "Can't find a folder to put it in" << llendl;
- }
+ // continue uploading for bulk uploads
- // remove the "Uploading..." message
- LLUploadDialog::modalUploadFinished();
-
// *FIX: This is a pretty big hack. What this does is check the
// file picker if there are any more pending uploads. If so,
// upload that file.
@@ -324,19 +398,42 @@ void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content)
// Continuing the horrible hack above, we need to extract the originally requested permissions data, if any,
// and use them for each next file to be uploaded. Note the requested perms are not the same as the
- // granted ones found in the given "content" structure but can still be found in mPostData. -MG
- U32 everyone_perms = mPostData.has("everyone_mask") ? mPostData.get("everyone_mask" ).asInteger() : PERM_NONE;
- U32 group_perms = mPostData.has("group_mask") ? mPostData.get("group_mask" ).asInteger() : PERM_NONE;
- U32 next_owner_perms = mPostData.has("next_owner_mask") ? mPostData.get("next_owner_mask").asInteger() : PERM_NONE;
+ U32 everyone_perms =
+ content.has("everyone_mask") ?
+ content["everyone_mask"].asInteger() :
+ PERM_NONE;
+
+ U32 group_perms =
+ content.has("group_mask") ?
+ content["group_mask"].asInteger() :
+ PERM_NONE;
+
+ U32 next_owner_perms =
+ content.has("next_owner_mask") ?
+ content["next_owner_mask"].asInteger() :
+ PERM_NONE;
+
std::string display_name = LLStringUtil::null;
LLAssetStorage::LLStoreAssetCallback callback = NULL;
void *userdata = NULL;
- upload_new_resource(next_file, asset_name, asset_name,
- 0, LLFolderType::FT_NONE, LLInventoryType::IT_NONE,
- next_owner_perms, group_perms,
- everyone_perms, display_name,
- callback, expected_upload_cost, userdata);
+
+ upload_new_resource(
+ next_file,
+ asset_name,
+ asset_name,
+ 0,
+ LLFolderType::FT_NONE,
+ LLInventoryType::IT_NONE,
+ next_owner_perms,
+ group_perms,
+ everyone_perms,
+ display_name,
+ callback,
+ LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(),
+ userdata);
}
+
+ LLImportColladaAssetCache::getInstance()->assetUploaded(mVFileID, content["new_asset"], TRUE);
}
LLSendTexLayerResponder::LLSendTexLayerResponder(const LLSD& post_data,
@@ -390,17 +487,19 @@ void LLSendTexLayerResponder::error(U32 statusNum, const std::string& reason)
mBakedUploadData = NULL; // deleted in onTextureUploadComplete()
}
-LLUpdateAgentInventoryResponder::LLUpdateAgentInventoryResponder(const LLSD& post_data,
- const LLUUID& vfile_id,
- LLAssetType::EType asset_type)
-: LLAssetUploadResponder(post_data, vfile_id, asset_type)
+LLUpdateAgentInventoryResponder::LLUpdateAgentInventoryResponder(
+ const LLSD& post_data,
+ const LLUUID& vfile_id,
+ LLAssetType::EType asset_type)
+ : LLAssetUploadResponder(post_data, vfile_id, asset_type)
{
}
-LLUpdateAgentInventoryResponder::LLUpdateAgentInventoryResponder(const LLSD& post_data,
- const std::string& file_name,
- LLAssetType::EType asset_type)
-: LLAssetUploadResponder(post_data, file_name, asset_type)
+LLUpdateAgentInventoryResponder::LLUpdateAgentInventoryResponder(
+ const LLSD& post_data,
+ const std::string& file_name,
+ LLAssetType::EType asset_type)
+ : LLAssetUploadResponder(post_data, file_name, asset_type)
{
}
@@ -583,3 +682,472 @@ void LLUpdateTaskInventoryResponder::uploadComplete(const LLSD& content)
break;
}
}
+
+
+/////////////////////////////////////////////////////
+// LLNewAgentInventoryVariablePriceResponder::Impl //
+/////////////////////////////////////////////////////
+class LLNewAgentInventoryVariablePriceResponder::Impl
+{
+public:
+ Impl(
+ const LLUUID& vfile_id,
+ LLAssetType::EType asset_type,
+ const LLSD& inventory_data) :
+ mVFileID(vfile_id),
+ mAssetType(asset_type),
+ mInventoryData(inventory_data),
+ mFileName("")
+ {
+ if (!gVFS->getExists(vfile_id, asset_type))
+ {
+ llwarns
+ << "LLAssetUploadResponder called with nonexistant "
+ << "vfile_id " << vfile_id << llendl;
+ mVFileID.setNull();
+ mAssetType = LLAssetType::AT_NONE;
+ }
+ }
+
+ Impl(
+ const std::string& file_name,
+ LLAssetType::EType asset_type,
+ const LLSD& inventory_data) :
+ mFileName(file_name),
+ mAssetType(asset_type),
+ mInventoryData(inventory_data)
+ {
+ mVFileID.setNull();
+ }
+
+ std::string getFilenameOrIDString() const
+ {
+ return (mFileName.empty() ? mVFileID.asString() : mFileName);
+ }
+
+ LLUUID getVFileID() const
+ {
+ return mVFileID;
+ }
+
+ std::string getFilename() const
+ {
+ return mFileName;
+ }
+
+ LLAssetType::EType getAssetType() const
+ {
+ return mAssetType;
+ }
+
+ LLInventoryType::EType getInventoryType() const
+ {
+ return LLInventoryType::lookup(
+ mInventoryData["inventory_type"].asString());
+ }
+
+ std::string getInventoryTypeString() const
+ {
+ return mInventoryData["inventory_type"].asString();
+ }
+
+ LLUUID getFolderID() const
+ {
+ return mInventoryData["folder_id"].asUUID();
+ }
+
+ std::string getItemName() const
+ {
+ return mInventoryData["name"].asString();
+ }
+
+ std::string getItemDescription() const
+ {
+ return mInventoryData["description"].asString();
+ }
+
+ void displayCannotUploadReason(const std::string& reason)
+ {
+ LLSD args;
+ args["FILE"] = getFilenameOrIDString();
+ args["REASON"] = reason;
+
+
+ LLNotificationsUtil::add("CannotUploadReason", args);
+ LLUploadDialog::modalUploadFinished();
+ }
+
+ void onApplicationLevelError(const LLSD& error)
+ {
+ static const std::string _IDENTIFIER = "identifier";
+
+ static const std::string _INSUFFICIENT_FUNDS =
+ "NewAgentInventory_InsufficientLindenDollarBalance";
+ static const std::string _MISSING_REQUIRED_PARAMETER =
+ "NewAgentInventory_MissingRequiredParamater";
+ static const std::string _INVALID_REQUEST_BODY =
+ "NewAgentInventory_InvalidRequestBody";
+ static const std::string _RESOURCE_COST_DIFFERS =
+ "NewAgentInventory_ResourceCostDiffers";
+
+ static const std::string _MISSING_PARAMETER = "missing_parameter";
+ static const std::string _INVALID_PARAMETER = "invalid_parameter";
+ static const std::string _MISSING_RESOURCE = "missing_resource";
+ static const std::string _INVALID_RESOURCE = "invalid_resource";
+
+ // TODO* Add the other error_identifiers
+
+ std::string error_identifier = error[_IDENTIFIER].asString();
+
+ // TODO*: Pull these user visible strings from an xml file
+ // to be localized
+ if ( _INSUFFICIENT_FUNDS == error_identifier )
+ {
+ displayCannotUploadReason("You do not have a sufficient L$ balance to complete this upload.");
+ }
+ else if ( _MISSING_REQUIRED_PARAMETER == error_identifier )
+ {
+ // Missing parameters
+ if (error.has(_MISSING_PARAMETER) )
+ {
+ std::string message =
+ "Upload request was missing required parameter '[P]'";
+ LLStringUtil::replaceString(
+ message,
+ "[P]",
+ error[_MISSING_PARAMETER].asString());
+
+ displayCannotUploadReason(message);
+ }
+ else
+ {
+ std::string message =
+ "Upload request was missing a required parameter";
+ displayCannotUploadReason(message);
+ }
+ }
+ else if ( _INVALID_REQUEST_BODY == error_identifier )
+ {
+ // Invalid request body, check to see if
+ // a particular parameter was invalid
+ if ( error.has(_INVALID_PARAMETER) )
+ {
+ std::string message = "Upload parameter '[P]' is invalid.";
+ LLStringUtil::replaceString(
+ message,
+ "[P]",
+ error[_INVALID_PARAMETER].asString());
+
+ // See if the server also responds with what resource
+ // is missing.
+ if ( error.has(_MISSING_RESOURCE) )
+ {
+ message += "\nMissing resource '[R]'.";
+
+ LLStringUtil::replaceString(
+ message,
+ "[R]",
+ error[_MISSING_RESOURCE].asString());
+ }
+ else if ( error.has(_INVALID_RESOURCE) )
+ {
+ message += "\nInvalid resource '[R]'.";
+
+ LLStringUtil::replaceString(
+ message,
+ "[R]",
+ error[_INVALID_RESOURCE].asString());
+ }
+
+ displayCannotUploadReason(message);
+ }
+ else
+ {
+ std::string message = "Upload request was malformed";
+ displayCannotUploadReason(message);
+ }
+ }
+ else if ( _RESOURCE_COST_DIFFERS == error_identifier )
+ {
+ displayCannotUploadReason("The resource cost associated with this upload is not consistent with the server.");
+ }
+ else
+ {
+ displayCannotUploadReason("Unknown Error");
+ }
+ }
+
+ void onTransportError()
+ {
+ displayCannotUploadReason(
+ "The server is experiencing unexpected difficulties.");
+ }
+
+ void onTransportError(const LLSD& error)
+ {
+ static const std::string _IDENTIFIER = "identifier";
+
+ static const std::string _SERVER_ERROR_AFTER_CHARGE =
+ "NewAgentInventory_ServerErrorAfterCharge";
+
+ std::string error_identifier = error[_IDENTIFIER].asString();
+
+ // TODO*: Pull the user visible strings from an xml file
+ // to be localized
+
+ if ( _SERVER_ERROR_AFTER_CHARGE == error_identifier )
+ {
+ displayCannotUploadReason(
+ "The server is experiencing unexpected difficulties. You may have been charged for the upload.");
+ }
+ else
+ {
+ displayCannotUploadReason(
+ "The server is experiencing unexpected difficulties.");
+ }
+ }
+
+ bool uploadConfirmationCallback(
+ const LLSD& notification,
+ const LLSD& response,
+ boost::intrusive_ptr<LLNewAgentInventoryVariablePriceResponder> responder)
+ {
+ S32 option;
+ std::string confirmation_url;
+
+ option = LLNotificationsUtil::getSelectedOption(
+ notification,
+ response);
+
+ confirmation_url =
+ notification["payload"]["confirmation_url"].asString();
+
+ // Yay! We are confirming or cancelling our upload
+ switch(option)
+ {
+ case 0:
+ {
+ confirmUpload(confirmation_url, responder);
+ }
+ break;
+ case 1:
+ default:
+ break;
+ }
+
+ return false;
+ }
+
+ void confirmUpload(
+ const std::string& confirmation_url,
+ boost::intrusive_ptr<LLNewAgentInventoryVariablePriceResponder> responder)
+ {
+ if ( getFilename().empty() )
+ {
+ // we have no filename, use virtual file ID instead
+ LLHTTPClient::postFile(
+ confirmation_url,
+ getVFileID(),
+ getAssetType(),
+ responder);
+ }
+ else
+ {
+ LLHTTPClient::postFile(
+ confirmation_url,
+ getFilename(),
+ responder);
+ }
+ }
+
+
+private:
+ std::string mFileName;
+
+ LLSD mInventoryData;
+ LLAssetType::EType mAssetType;
+ LLUUID mVFileID;
+};
+
+///////////////////////////////////////////////
+// LLNewAgentInventoryVariablePriceResponder //
+///////////////////////////////////////////////
+LLNewAgentInventoryVariablePriceResponder::LLNewAgentInventoryVariablePriceResponder(
+ const LLUUID& vfile_id,
+ LLAssetType::EType asset_type,
+ const LLSD& inventory_info)
+{
+ mImpl = new Impl(
+ vfile_id,
+ asset_type,
+ inventory_info);
+}
+
+LLNewAgentInventoryVariablePriceResponder::LLNewAgentInventoryVariablePriceResponder(
+ const std::string& file_name,
+ LLAssetType::EType asset_type,
+ const LLSD& inventory_info)
+{
+ mImpl = new Impl(
+ file_name,
+ asset_type,
+ inventory_info);
+}
+
+LLNewAgentInventoryVariablePriceResponder::~LLNewAgentInventoryVariablePriceResponder()
+{
+ delete mImpl;
+}
+
+void LLNewAgentInventoryVariablePriceResponder::errorWithContent(
+ U32 statusNum,
+ const std::string& reason,
+ const LLSD& content)
+{
+ lldebugs
+ << "LLNewAgentInventoryVariablePrice::error " << statusNum
+ << " reason: " << reason << llendl;
+
+ if ( content.has("error") )
+ {
+ static const std::string _ERROR = "error";
+
+ mImpl->onTransportError(content[_ERROR]);
+ }
+ else
+ {
+ mImpl->onTransportError();
+ }
+}
+
+void LLNewAgentInventoryVariablePriceResponder::result(const LLSD& content)
+{
+ // Parse out application level errors and the appropriate
+ // responses for them
+ static const std::string _ERROR = "error";
+ static const std::string _STATE = "state";
+
+ static const std::string _COMPLETE = "complete";
+ static const std::string _CONFIRM_UPLOAD = "confirm_upload";
+
+ static const std::string _UPLOAD_PRICE = "upload_price";
+ static const std::string _RESOURCE_COST = "resource_cost";
+ static const std::string _RSVP = "rsvp";
+
+ // Check for application level errors
+ if ( content.has(_ERROR) )
+ {
+ onApplicationLevelError(content[_ERROR]);
+ return;
+ }
+
+ std::string state = content[_STATE];
+ LLAssetType::EType asset_type = mImpl->getAssetType();
+
+ if ( _COMPLETE == state )
+ {
+ // rename file in VFS with new asset id
+ if (mImpl->getFilename().empty())
+ {
+ // rename the file in the VFS to the actual asset id
+ // llinfos << "Changing uploaded asset UUID to " << content["new_asset"].asUUID() << llendl;
+ gVFS->renameFile(
+ mImpl->getVFileID(),
+ asset_type,
+ content["new_asset"].asUUID(),
+ asset_type);
+ }
+
+ on_new_single_inventory_upload_complete(
+ asset_type,
+ mImpl->getInventoryType(),
+ mImpl->getInventoryTypeString(),
+ mImpl->getFolderID(),
+ mImpl->getItemName(),
+ mImpl->getItemDescription(),
+ content,
+ content[_UPLOAD_PRICE].asInteger());
+
+ // TODO* Add bulk (serial) uploading or add
+ // a super class of this that does so
+ }
+ else if ( _CONFIRM_UPLOAD == state )
+ {
+ showConfirmationDialog(
+ content[_UPLOAD_PRICE].asInteger(),
+ content[_RESOURCE_COST].asInteger(),
+ content[_RSVP].asString());
+ }
+ else
+ {
+ onApplicationLevelError("");
+ }
+}
+
+void LLNewAgentInventoryVariablePriceResponder::onApplicationLevelError(
+ const LLSD& error)
+{
+ mImpl->onApplicationLevelError(error);
+}
+
+void LLNewAgentInventoryVariablePriceResponder::showConfirmationDialog(
+ S32 upload_price,
+ S32 resource_cost,
+ const std::string& confirmation_url)
+{
+ if ( 0 == upload_price )
+ {
+ // don't show confirmation dialog for free uploads, I mean,
+ // they're free!
+
+ // The creating of a new instrusive_ptr(this)
+ // creates a new boost::intrusive_ptr
+ // which is a copy of this. This code is required because
+ // 'this' is always of type Class* and not the intrusive_ptr,
+ // and thus, a reference to 'this' is not registered
+ // by using just plain 'this'.
+
+ // Since LLNewAgentInventoryVariablePriceResponder is a
+ // reference counted class, it is possible (since the
+ // reference to a plain 'this' would be missed here) that,
+ // when using plain ol' 'this', that this object
+ // would be deleted before the callback is triggered
+ // and cause sadness.
+ mImpl->confirmUpload(
+ confirmation_url,
+ boost::intrusive_ptr<LLNewAgentInventoryVariablePriceResponder>(this));
+ }
+ else
+ {
+ LLSD substitutions;
+ LLSD payload;
+
+ substitutions["PRICE"] = upload_price;
+
+ payload["confirmation_url"] = confirmation_url;
+
+ // The creating of a new instrusive_ptr(this)
+ // creates a new boost::intrusive_ptr
+ // which is a copy of this. This code is required because
+ // 'this' is always of type Class* and not the intrusive_ptr,
+ // and thus, a reference to 'this' is not registered
+ // by using just plain 'this'.
+
+ // Since LLNewAgentInventoryVariablePriceResponder is a
+ // reference counted class, it is possible (since the
+ // reference to a plain 'this' would be missed here) that,
+ // when using plain ol' 'this', that this object
+ // would be deleted before the callback is triggered
+ // and cause sadness.
+ LLNotificationsUtil::add(
+ "UploadCostConfirmation",
+ substitutions,
+ payload,
+ boost::bind(
+ &LLNewAgentInventoryVariablePriceResponder::Impl::uploadConfirmationCallback,
+ mImpl,
+ _1,
+ _2,
+ boost::intrusive_ptr<LLNewAgentInventoryVariablePriceResponder>(this)));
+ }
+}
diff --git a/indra/newview/llassetuploadresponders.h b/indra/newview/llassetuploadresponders.h
index e656351305..c869988203 100644
--- a/indra/newview/llassetuploadresponders.h
+++ b/indra/newview/llassetuploadresponders.h
@@ -61,15 +61,60 @@ protected:
std::string mFileName;
};
+
+// TODO*: Remove this once deprecated
class LLNewAgentInventoryResponder : public LLAssetUploadResponder
{
public:
- LLNewAgentInventoryResponder(const LLSD& post_data,
- const LLUUID& vfile_id,
- LLAssetType::EType asset_type);
- LLNewAgentInventoryResponder(const LLSD& post_data, const std::string& file_name,
- LLAssetType::EType asset_type);
+ LLNewAgentInventoryResponder(
+ const LLSD& post_data,
+ const LLUUID& vfile_id,
+ LLAssetType::EType asset_type);
+ LLNewAgentInventoryResponder(
+ const LLSD& post_data,
+ const std::string& file_name,
+ LLAssetType::EType asset_type);
+ virtual void error(U32 statusNum, const std::string& reason);
virtual void uploadComplete(const LLSD& content);
+ virtual void uploadFailure(const LLSD& content);
+};
+
+// A base class which goes through and performs some default
+// actions for variable price uploads. If more specific actions
+// are needed (such as different confirmation messages, etc.)
+// the functions onApplicationLevelError and showConfirmationDialog.
+class LLNewAgentInventoryVariablePriceResponder :
+ public LLHTTPClient::Responder
+{
+public:
+ LLNewAgentInventoryVariablePriceResponder(
+ const LLUUID& vfile_id,
+ LLAssetType::EType asset_type,
+ const LLSD& inventory_info);
+
+ LLNewAgentInventoryVariablePriceResponder(
+ const std::string& file_name,
+ LLAssetType::EType asset_type,
+ const LLSD& inventory_info);
+
+ virtual ~LLNewAgentInventoryVariablePriceResponder();
+
+ void errorWithContent(
+ U32 statusNum,
+ const std::string& reason,
+ const LLSD& content);
+ void result(const LLSD& content);
+
+ virtual void onApplicationLevelError(
+ const LLSD& error);
+ virtual void showConfirmationDialog(
+ S32 upload_price,
+ S32 resource_cost,
+ const std::string& confirmation_url);
+
+private:
+ class Impl;
+ Impl* mImpl;
};
class LLBakedUploadData;
diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index d60330024a..9a3be975cd 100644
--- a/indra/newview/lldrawable.cpp
+++ b/indra/newview/lldrawable.cpp
@@ -189,20 +189,30 @@ BOOL LLDrawable::isLight() const
}
}
+static LLFastTimer::DeclareTimer FTM_CLEANUP_DRAWABLE("Cleanup Drawable");
+static LLFastTimer::DeclareTimer FTM_DEREF_DRAWABLE("Deref");
+static LLFastTimer::DeclareTimer FTM_DELETE_FACES("Faces");
+
void LLDrawable::cleanupReferences()
{
- LLFastTimer t(FTM_PIPELINE);
+ LLFastTimer t(FTM_CLEANUP_DRAWABLE);
- std::for_each(mFaces.begin(), mFaces.end(), DeletePointer());
- mFaces.clear();
+ {
+ LLFastTimer t(FTM_DELETE_FACES);
+ std::for_each(mFaces.begin(), mFaces.end(), DeletePointer());
+ mFaces.clear();
+ }
gObjectList.removeDrawable(this);
gPipeline.unlinkDrawable(this);
- // Cleanup references to other objects
- mVObjp = NULL;
- mParent = NULL;
+ {
+ LLFastTimer t(FTM_DEREF_DRAWABLE);
+ // Cleanup references to other objects
+ mVObjp = NULL;
+ mParent = NULL;
+ }
}
void LLDrawable::cleanupDeadDrawables()
diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h
index 5a10b688da..27c9ab319a 100644
--- a/indra/newview/lldrawable.h
+++ b/indra/newview/lldrawable.h
@@ -314,8 +314,10 @@ private:
inline LLFace* LLDrawable::getFace(const S32 i) const
{
- llassert((U32)i < mFaces.size());
- llassert(mFaces[i]);
+ if ((U32) i >= mFaces.size())
+ {
+ return NULL;
+ }
return mFaces[i];
}
diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp
index 5f845c3721..4778865c4b 100644
--- a/indra/newview/lldrawpoolbump.cpp
+++ b/indra/newview/lldrawpoolbump.cpp
@@ -701,6 +701,18 @@ void LLDrawPoolBump::endBump()
gGL.setSceneBlendType(LLRender::BT_ALPHA);
}
+S32 LLDrawPoolBump::getNumDeferredPasses()
+{
+ if (gSavedSettings.getBOOL("RenderObjectBump"))
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
void LLDrawPoolBump::beginDeferredPass(S32 pass)
{
if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_BUMP))
diff --git a/indra/newview/lldrawpoolbump.h b/indra/newview/lldrawpoolbump.h
index bf940cf1e4..2019f1df26 100644
--- a/indra/newview/lldrawpoolbump.h
+++ b/indra/newview/lldrawpoolbump.h
@@ -79,7 +79,7 @@ public:
void renderBump();
void endBump();
- virtual S32 getNumDeferredPasses() { return 1; }
+ virtual S32 getNumDeferredPasses();
/*virtual*/ void beginDeferredPass(S32 pass);
/*virtual*/ void endDeferredPass(S32 pass);
/*virtual*/ void renderDeferred(S32 pass);
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index eef774426a..91e2fef28d 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -183,22 +183,33 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp)
mUsingAtlas = FALSE ;
}
+static LLFastTimer::DeclareTimer FTM_DESTROY_FACE("Destroy Face");
+static LLFastTimer::DeclareTimer FTM_DESTROY_TEXTURE("Texture");
+static LLFastTimer::DeclareTimer FTM_DESTROY_DRAWPOOL("Drawpool");
+static LLFastTimer::DeclareTimer FTM_DESTROY_TEXTURE_MATRIX("Texture Matrix");
+static LLFastTimer::DeclareTimer FTM_DESTROY_DRAW_INFO("Draw Info");
+static LLFastTimer::DeclareTimer FTM_DESTROY_ATLAS("Atlas");
+static LLFastTimer::DeclareTimer FTM_FACE_DEREF("Deref");
void LLFace::destroy()
{
+ LLFastTimer t(FTM_DESTROY_FACE);
if(mTexture.notNull())
{
+ LLFastTimer t(FTM_DESTROY_TEXTURE);
mTexture->removeFace(this) ;
}
if (mDrawPoolp)
{
+ LLFastTimer t(FTM_DESTROY_DRAWPOOL);
mDrawPoolp->removeFace(this);
mDrawPoolp = NULL;
}
if (mTextureMatrix)
{
+ LLFastTimer t(FTM_DESTROY_TEXTURE_MATRIX);
delete mTextureMatrix;
mTextureMatrix = NULL;
@@ -213,11 +224,21 @@ void LLFace::destroy()
}
}
- setDrawInfo(NULL);
+ {
+ LLFastTimer t(FTM_DESTROY_DRAW_INFO);
+ setDrawInfo(NULL);
+ }
- removeAtlas();
- mDrawablep = NULL;
- mVObjp = NULL;
+ {
+ LLFastTimer t(FTM_DESTROY_ATLAS);
+ removeAtlas();
+ }
+
+ {
+ LLFastTimer t(FTM_FACE_DEREF);
+ mDrawablep = NULL;
+ mVObjp = NULL;
+ }
}
@@ -1057,7 +1078,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
if (full_rebuild)
{
mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex);
- for (U16 i = 0; i < num_indices; i++)
+ for (S32 i = 0; i < num_indices; i++)
{
*indicesp++ = vf.mIndices[i] + index_offset;
}
diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp
index 028e1cc098..8dfb333530 100644
--- a/indra/newview/llfilepicker.cpp
+++ b/indra/newview/llfilepicker.cpp
@@ -55,12 +55,14 @@ LLFilePicker LLFilePicker::sInstance;
#define SOUND_FILTER L"Sounds (*.wav)\0*.wav\0"
#define IMAGE_FILTER L"Images (*.tga; *.bmp; *.jpg; *.jpeg; *.png)\0*.tga;*.bmp;*.jpg;*.jpeg;*.png\0"
#define ANIM_FILTER L"Animations (*.bvh)\0*.bvh\0"
+#define COLLADA_FILTER L"Scene (*.dae)\0*.dae\0"
#ifdef _CORY_TESTING
#define GEOMETRY_FILTER L"SL Geometry (*.slg)\0*.slg\0"
#endif
#define XML_FILTER L"XML files (*.xml)\0*.xml\0"
#define SLOBJECT_FILTER L"Objects (*.slobject)\0*.slobject\0"
#define RAW_FILTER L"RAW files (*.raw)\0*.raw\0"
+#define MODEL_FILTER L"Model files (*.dae)\0*.dae\0"
#endif
//
@@ -175,6 +177,10 @@ BOOL LLFilePicker::setupFilter(ELoadFilter filter)
mOFN.lpstrFilter = ANIM_FILTER \
L"\0";
break;
+ case FFLOAD_COLLADA:
+ mOFN.lpstrFilter = COLLADA_FILTER \
+ L"\0";
+ break;
#ifdef _CORY_TESTING
case FFLOAD_GEOMETRY:
mOFN.lpstrFilter = GEOMETRY_FILTER \
@@ -193,6 +199,10 @@ BOOL LLFilePicker::setupFilter(ELoadFilter filter)
mOFN.lpstrFilter = RAW_FILTER \
L"\0";
break;
+ case FFLOAD_MODEL:
+ mOFN.lpstrFilter = MODEL_FILTER \
+ L"\0";
+ break;
default:
res = FALSE;
break;
@@ -542,6 +552,15 @@ Boolean LLFilePicker::navOpenFilterProc(AEDesc *theItem, void *info, void *callB
result = false;
}
}
+ else if (filter == FFLOAD_COLLADA)
+ {
+ if (fileInfo.filetype != 'DAE ' &&
+ (fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("dae"), kCFCompareCaseInsensitive) != kCFCompareEqualTo))
+ )
+ {
+ result = false;
+ }
+ }
#ifdef _CORY_TESTING
else if (filter == FFLOAD_GEOMETRY)
{
@@ -1088,6 +1107,12 @@ static std::string add_bvh_filter_to_gtkchooser(GtkWindow *picker)
LLTrans::getString("animation_files") + " (*.bvh)");
}
+static std::string add_collada_filter_to_gtkchooser(GtkWindow *picker)
+{
+ return add_simple_pattern_filter_to_gtkchooser(picker, "*.dae",
+ LLTrans::getString("scene_files") + " (*.dae)");
+}
+
static std::string add_imageload_filter_to_gtkchooser(GtkWindow *picker)
{
GtkFileFilter *gfilter = gtk_file_filter_new();
@@ -1212,6 +1237,9 @@ BOOL LLFilePicker::getOpenFile( ELoadFilter filter )
case FFLOAD_ANIM:
filtername = add_bvh_filter_to_gtkchooser(picker);
break;
+ case FFLOAD_COLLADA:
+ filtername = add_collada_filter_to_gtkchooser(picker);
+ break;
case FFLOAD_IMAGE:
filtername = add_imageload_filter_to_gtkchooser(picker);
break;
diff --git a/indra/newview/llfilepicker.h b/indra/newview/llfilepicker.h
index 7ecbc3db60..408d2f2702 100644
--- a/indra/newview/llfilepicker.h
+++ b/indra/newview/llfilepicker.h
@@ -88,6 +88,8 @@ public:
FFLOAD_XML = 6,
FFLOAD_SLOBJECT = 7,
FFLOAD_RAW = 8,
+ FFLOAD_MODEL = 9,
+ FFLOAD_COLLADA = 10,
};
enum ESaveFilter
@@ -193,4 +195,6 @@ public:
~LLFilePicker();
};
+const std::string upload_pick(void* data);
+
#endif
diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp
index 0b5da40be4..6ac5165bba 100644
--- a/indra/newview/llhudtext.cpp
+++ b/indra/newview/llhudtext.cpp
@@ -567,6 +567,18 @@ void LLHUDText::setStringUTF8(const std::string &wtext)
setString(utf8str_to_wstring(wtext));
}
+std::string LLHUDText::getString()
+{
+ std::ostringstream ostr;
+ for (U32 i = 0; i < mTextSegments.size(); ++i)
+ {
+ const std::string str = wstring_to_utf8str(mTextSegments[i].getText());
+ ostr << str;
+ }
+
+ return ostr.str();
+}
+
void LLHUDText::setString(const LLWString &wtext)
{
mTextSegments.clear();
diff --git a/indra/newview/llhudtext.h b/indra/newview/llhudtext.h
index dc14a8c764..4787a15eaf 100644
--- a/indra/newview/llhudtext.h
+++ b/indra/newview/llhudtext.h
@@ -90,6 +90,7 @@ public:
public:
void setStringUTF8(const std::string &utf8string);
+ std::string getString();
void setString(const LLWString &wstring);
void clearString();
void addLine(const std::string &text, const LLColor4& color, const LLFontGL::StyleFlags style = LLFontGL::NORMAL);
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 3fc2cbecbe..922cb53a35 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -125,7 +125,9 @@ std::string ICON_NAME[ICON_NAME_COUNT] =
"Inv_Gesture",
"Inv_LinkItem",
- "Inv_LinkFolder"
+ "Inv_LinkFolder",
+
+ "Inv_Mesh"
};
// +=================================================+
@@ -899,6 +901,14 @@ LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type,
// Only should happen for broken links.
new_listener = new LLLinkItemBridge(inventory, uuid);
break;
+ case LLAssetType::AT_MESH:
+ if(!(inv_type == LLInventoryType::IT_MESH))
+ {
+ llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl;
+ }
+ new_listener = new LLMeshBridge(inventory, uuid);
+ break;
+
default:
llinfos << "Unhandled asset type (llassetstorage.h): "
<< (S32)asset_type << llendl;
@@ -2229,6 +2239,9 @@ LLUIImagePtr LLFolderBridge::getIcon(LLFolderType::EType preferred_type)
{
// we only have one folder image now
return LLUI::getUIImage("Inv_FolderClosed");
+ /*case LLAssetType::AT_MESH:
+ control = "inv_folder_mesh.tga";
+ break;*/
}
BOOL LLFolderBridge::renameItem(const std::string& new_name)
@@ -2705,6 +2718,7 @@ BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop,
case DAD_ANIMATION:
case DAD_GESTURE:
case DAD_LINK:
+ case DAD_MESH:
accept = dragItemIntoFolder((LLInventoryItem*)cargo_data,
drop);
break;
@@ -3683,6 +3697,7 @@ BOOL LLCallingCardBridge::dragOrDrop(MASK mask, BOOL drop,
case DAD_BODYPART:
case DAD_ANIMATION:
case DAD_GESTURE:
+ case DAD_MESH:
{
LLInventoryItem* inv_item = (LLInventoryItem*)cargo_data;
const LLPermissions& perm = inv_item->getPermissions();
@@ -4949,6 +4964,65 @@ void LLWearableBridge::onRemoveFromAvatarArrived(LLWearable* wearable,
delete on_remove_struct;
}
+
+// +=================================================+
+// | LLMeshBridge |
+// +=================================================+
+
+LLUIImagePtr LLMeshBridge::getIcon() const
+{
+ return get_item_icon(LLAssetType::AT_MESH, LLInventoryType::IT_MESH, 0, FALSE);
+}
+
+void LLMeshBridge::openItem()
+{
+ LLViewerInventoryItem* item = getItem();
+
+ if (item)
+ {
+ // open mesh
+ }
+}
+
+void LLMeshBridge::previewItem()
+{
+ LLViewerInventoryItem* item = getItem();
+ if(item)
+ {
+ // preview mesh
+ }
+}
+
+
+void LLMeshBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
+{
+ lldebugs << "LLMeshBridge::buildContextMenu()" << llendl;
+ std::vector<std::string> items;
+ std::vector<std::string> disabled_items;
+
+ if(isInTrash())
+ {
+ items.push_back(std::string("Purge Item"));
+ if (!isItemRemovable())
+ {
+ disabled_items.push_back(std::string("Purge Item"));
+ }
+
+ items.push_back(std::string("Restore Item"));
+ }
+ else
+ {
+ items.push_back(std::string("Properties"));
+
+ getClipboardEntries(true, items, disabled_items, flags);
+ }
+
+
+ hide_context_entries(menu, items, disabled_items);
+}
+
+
+
LLInvFVBridgeAction* LLInvFVBridgeAction::createAction(LLAssetType::EType asset_type,
const LLUUID& uuid,LLInventoryModel* model)
{
@@ -4997,6 +5071,12 @@ LLInvFVBridgeAction* LLInvFVBridgeAction::createAction(LLAssetType::EType asset_
break;
+ case LLAssetType::AT_MESH:
+ action = new LLMeshBridgeAction(uuid,model);
+ break;
+
+
+
default:
break;
}
@@ -5235,6 +5315,18 @@ void LLWearableBridgeAction::doIt()
LLInvFVBridgeAction::doIt();
}
+//virtual
+void LLMeshBridgeAction::doIt()
+{
+ LLViewerInventoryItem* item = getItem();
+ if(item)
+ {
+ // do it
+ }
+
+ LLInvFVBridgeAction::doIt();
+}
+
// +=================================================+
// | LLLinkItemBridge |
// +=================================================+
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index 4d83e9b684..07728cc35a 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -82,6 +82,8 @@ enum EInventoryIcon
LINKITEM_ICON_NAME,
LINKFOLDER_ICON_NAME,
+
+ MESH_ICON_NAME,
ICON_NAME_COUNT
};
@@ -605,7 +607,6 @@ protected:
static std::string sPrefix;
};
-
class LLLinkFolderBridge : public LLItemBridge
{
friend class LLInvFVBridge;
@@ -626,6 +627,25 @@ protected:
static std::string sPrefix;
};
+
+
+class LLMeshBridge : public LLItemBridge
+{
+ friend class LLInvFVBridge;
+public:
+ virtual LLUIImagePtr getIcon() const;
+ virtual void openItem();
+ virtual void previewItem();
+ virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
+
+protected:
+ LLMeshBridge(LLInventoryPanel* inventory, const LLUUID& uuid) :
+ LLItemBridge(inventory, uuid) {}
+};
+
+
+
+
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLInvFVBridgeAction (& its derived classes)
//
@@ -786,6 +806,19 @@ protected:
};
+class LLMeshBridgeAction: public LLInvFVBridgeAction
+{
+ friend class LLInvFVBridgeAction;
+public:
+ virtual void doIt() ;
+ virtual ~LLMeshBridgeAction(){}
+protected:
+ LLMeshBridgeAction(const LLUUID& id,LLInventoryModel* model):LLInvFVBridgeAction(id,model){}
+
+};
+
+
+
void wear_inventory_item_on_avatar(LLInventoryItem* item);
class LLViewerJointAttachment;
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index 8f4136c01f..ce4255448f 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -323,6 +323,9 @@ const std::string& get_item_icon_name(LLAssetType::EType asset_type,
case LLAssetType::AT_LINK_FOLDER:
idx = LINKFOLDER_ICON_NAME;
break;
+ case LLAssetType::AT_MESH:
+ idx = MESH_ICON_NAME;
+ break;
default:
break;
}
diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp
index 6210973dae..516020797d 100644
--- a/indra/newview/llpanelgroupnotices.cpp
+++ b/indra/newview/llpanelgroupnotices.cpp
@@ -158,6 +158,7 @@ BOOL LLGroupDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
case DAD_ANIMATION:
case DAD_GESTURE:
case DAD_CALLINGCARD:
+ case DAD_MESH:
{
LLViewerInventoryItem* inv_item = (LLViewerInventoryItem*)cargo_data;
if(gInventory.getItem(inv_item->getUUID())
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index 43366ef814..0a63032751 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -820,6 +820,7 @@ BOOL LLTaskCategoryBridge::dragOrDrop(MASK mask, BOOL drop,
case DAD_ANIMATION:
case DAD_GESTURE:
case DAD_CALLINGCARD:
+ case DAD_MESH:
accept = LLToolDragAndDrop::isInventoryDropAcceptable(object, (LLViewerInventoryItem*)cargo_data);
if(accept && drop)
{
@@ -1403,6 +1404,117 @@ LLUIImagePtr LLTaskWearableBridge::getIcon() const
return get_item_icon(mAssetType, LLInventoryType::IT_WEARABLE, mFlags, FALSE );
}
+///----------------------------------------------------------------------------
+/// Class LLTaskMeshBridge
+///----------------------------------------------------------------------------
+
+class LLTaskMeshBridge : public LLTaskInvFVBridge
+{
+public:
+ LLTaskMeshBridge(
+ LLPanelObjectInventory* panel,
+ const LLUUID& uuid,
+ const std::string& name);
+
+ virtual LLUIImagePtr getIcon() const;
+ virtual void openItem();
+ virtual void performAction(LLFolderView* folder, LLInventoryModel* model, std::string action);
+ virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
+};
+
+LLTaskMeshBridge::LLTaskMeshBridge(
+ LLPanelObjectInventory* panel,
+ const LLUUID& uuid,
+ const std::string& name) :
+ LLTaskInvFVBridge(panel, uuid, name)
+{
+}
+
+LLUIImagePtr LLTaskMeshBridge::getIcon() const
+{
+ return get_item_icon(LLAssetType::AT_MESH, LLInventoryType::IT_MESH, 0, FALSE);
+}
+
+void LLTaskMeshBridge::openItem()
+{
+ // open mesh
+}
+
+
+// virtual
+void LLTaskMeshBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action)
+{
+ if (action == "mesh action")
+ {
+ LLInventoryItem* item = findItem();
+ if(item)
+ {
+ // do action
+ }
+ }
+ LLTaskInvFVBridge::performAction(folder, model, action);
+}
+
+void LLTaskMeshBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
+{
+ LLInventoryItem* item = findItem();
+ if(!item) return;
+ std::vector<std::string> items;
+ std::vector<std::string> disabled_items;
+
+ if(item->getPermissions().getOwner() != gAgent.getID()
+ && item->getSaleInfo().isForSale())
+ {
+ items.push_back(std::string("Task Buy"));
+
+ std::string label= LLTrans::getString("Buy");
+ // Check the price of the item.
+ S32 price = getPrice();
+ if (-1 == price)
+ {
+ llwarns << "label_buy_task_bridged_item: Invalid price" << llendl;
+ }
+ else
+ {
+ std::ostringstream info;
+ info << LLTrans::getString("BuyforL$") << price;
+ label.assign(info.str());
+ }
+
+ const LLView::child_list_t *list = menu.getChildList();
+ LLView::child_list_t::const_iterator itor;
+ for (itor = list->begin(); itor != list->end(); ++itor)
+ {
+ std::string name = (*itor)->getName();
+ LLMenuItemCallGL* menu_itemp = dynamic_cast<LLMenuItemCallGL*>(*itor);
+ if (name == "Task Buy" && menu_itemp)
+ {
+ menu_itemp->setLabel(label);
+ }
+ }
+ }
+ else
+ {
+ items.push_back(std::string("Task Open"));
+ if (!isItemCopyable())
+ {
+ disabled_items.push_back(std::string("Task Open"));
+ }
+ }
+ items.push_back(std::string("Task Properties"));
+ if(isItemRenameable())
+ {
+ items.push_back(std::string("Task Rename"));
+ }
+ if(isItemRemovable())
+ {
+ items.push_back(std::string("Task Remove"));
+ }
+
+
+ hide_context_entries(menu, items, disabled_items);
+}
+
///----------------------------------------------------------------------------
/// LLTaskInvFVBridge impl
@@ -1484,6 +1596,11 @@ LLTaskInvFVBridge* LLTaskInvFVBridge::createObjectBridge(LLPanelObjectInventory*
object->getUUID(),
object->getName());
break;
+ case LLAssetType::AT_MESH:
+ new_bridge = new LLTaskMeshBridge(panel,
+ object->getUUID(),
+ object->getName());
+ break;
break;
default:
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 60a095506b..852f58e354 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -179,7 +179,6 @@ LLObjectSelection *get_null_object_selection()
// Build time optimization, generate this function once here
template class LLSelectMgr* LLSingleton<class LLSelectMgr>::getInstance();
-
//-----------------------------------------------------------------------------
// LLSelectMgr()
//-----------------------------------------------------------------------------
@@ -5343,6 +5342,78 @@ BOOL LLSelectNode::allowOperationOnNode(PermissionBit op, U64 group_proxy_power)
return (mPermissions->allowOperationBy(op, proxy_agent_id, group_id));
}
+void LLSelectNode::renderOneWireframe(const LLColor4& color)
+{
+ LLViewerObject* objectp = getObject();
+ if (!objectp)
+ {
+ return;
+ }
+
+ LLDrawable* drawable = objectp->mDrawable;
+ if(!drawable)
+ {
+ return;
+ }
+
+ glMatrixMode(GL_MODELVIEW);
+ gGL.pushMatrix();
+
+ BOOL is_hud_object = objectp->isHUDAttachment();
+
+ if (!is_hud_object)
+ {
+ glLoadIdentity();
+ glMultMatrixd(gGLModelView);
+ }
+
+ if (drawable->isActive())
+ {
+ glMultMatrixf((F32*) objectp->getRenderMatrix().mMatrix);
+ }
+
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+
+ if (LLSelectMgr::sRenderHiddenSelections) // && gFloaterTools && gFloaterTools->getVisible())
+ {
+ gGL.blendFunc(LLRender::BF_SOURCE_COLOR, LLRender::BF_ONE);
+ LLGLEnable fog(GL_FOG);
+ glFogi(GL_FOG_MODE, GL_LINEAR);
+ float d = (LLViewerCamera::getInstance()->getPointOfInterest()-LLViewerCamera::getInstance()->getOrigin()).magVec();
+ LLColor4 fogCol = color * (F32)llclamp((LLSelectMgr::getInstance()->getSelectionCenterGlobal()-gAgent.getCameraPositionGlobal()).magVec()/(LLSelectMgr::getInstance()->getBBoxOfSelection().getExtentLocal().magVec()*4), 0.0, 1.0);
+ glFogf(GL_FOG_START, d);
+ glFogf(GL_FOG_END, d*(1 + (LLViewerCamera::getInstance()->getView() / LLViewerCamera::getInstance()->getDefaultFOV())));
+ glFogfv(GL_FOG_COLOR, fogCol.mV);
+
+ LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GEQUAL);
+ gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
+ {
+ glColor4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.4f);
+ for (S32 i = 0; i < drawable->getNumFaces(); ++i)
+ {
+ LLFace* face = drawable->getFace(i);
+ pushVerts(face, LLVertexBuffer::MAP_VERTEX);
+ }
+ }
+ }
+
+ gGL.flush();
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
+
+ glColor4f(color.mV[VRED]*2, color.mV[VGREEN]*2, color.mV[VBLUE]*2, LLSelectMgr::sHighlightAlpha*2);
+ LLGLEnable offset(GL_POLYGON_OFFSET_LINE);
+ glPolygonOffset(3.f, 2.f);
+ glLineWidth(3.f);
+ for (S32 i = 0; i < drawable->getNumFaces(); ++i)
+ {
+ LLFace* face = drawable->getFace(i);
+ pushVerts(face, LLVertexBuffer::MAP_VERTEX);
+ }
+ glLineWidth(1.f);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ gGL.popMatrix();
+}
+
//-----------------------------------------------------------------------------
// renderOneSilhouette()
//-----------------------------------------------------------------------------
@@ -5360,6 +5431,13 @@ void LLSelectNode::renderOneSilhouette(const LLColor4 &color)
return;
}
+ LLVOVolume* vobj = drawable->getVOVolume();
+ if (vobj && vobj->isMesh())
+ {
+ renderOneWireframe(color);
+ return;
+ }
+
if (!mSilhouetteExists)
{
return;
diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h
index f8ecfd0674..f7ce3f72aa 100644
--- a/indra/newview/llselectmgr.h
+++ b/indra/newview/llselectmgr.h
@@ -140,6 +140,7 @@ public:
BOOL isTESelected(S32 te_index);
S32 getLastSelectedTE();
S32 getTESelectMask() { return mTESelectMask; }
+ void renderOneWireframe(const LLColor4& color);
void renderOneSilhouette(const LLColor4 &color);
void setTransient(BOOL transient) { mTransient = transient; }
BOOL isTransient() { return mTransient; }
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 6ca6734598..6856a7d71b 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -2294,7 +2294,6 @@ void pushVerts(LLFace* face, U32 mask)
U16 offset = face->getIndicesStart();
buffer->drawRange(LLRender::TRIANGLES, start, end, count, offset);
}
-
}
void pushBufferVerts(LLVertexBuffer* buffer, U32 mask)
diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h
index 64c2a9acbc..1d9127639a 100644
--- a/indra/newview/llspatialpartition.h
+++ b/indra/newview/llspatialpartition.h
@@ -59,6 +59,7 @@ class LLTextureAtlasSlot;
S32 AABBSphereIntersect(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &rad);
S32 AABBSphereIntersectR2(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &radius_squared);
+void pushVerts(LLFace* face, U32 mask);
// get index buffer for binary encoded axis vertex buffer given a box at center being viewed by given camera
U8* get_box_fan_indices(LLCamera* camera, const LLVector3& center);
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 5f7c2f5080..2180f47218 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -291,7 +291,7 @@ BOOL LLFloaterTexturePicker::handleDragAndDrop(
{
BOOL handled = FALSE;
- if (cargo_type == DAD_TEXTURE)
+ if ((cargo_type == DAD_TEXTURE) || (cargo_type == DAD_MESH))
{
LLInventoryItem *item = (LLInventoryItem *)cargo_data;
@@ -1154,7 +1154,9 @@ BOOL LLTextureCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask,
// returns true, then the cast was valid, and we can perform
// the third test without problems.
LLInventoryItem* item = (LLInventoryItem*)cargo_data;
- if (getEnabled() && (cargo_type == DAD_TEXTURE) && allowDrop(item))
+ if (getEnabled() &&
+ ((cargo_type == DAD_TEXTURE) || (cargo_type == DAD_MESH)) &&
+ allowDrop(item))
{
if (drop)
{
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index aa35f22930..7509246374 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -385,6 +385,7 @@ LLToolDragAndDrop::LLDragAndDropDictionary::LLDragAndDropDictionary()
addEntry(DAD_ANIMATION, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
addEntry(DAD_GESTURE, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dActivateGesture, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
addEntry(DAD_LINK, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL));
+ addEntry(DAD_MESH, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
// TODO: animation on self could play it? edit it?
// TODO: gesture on self could play it? edit it?
};
@@ -1920,6 +1921,7 @@ bool LLToolDragAndDrop::handleGiveDragAndDrop(LLUUID dest_agent, LLUUID session_
case DAD_ANIMATION:
case DAD_GESTURE:
case DAD_CALLINGCARD:
+ case DAD_MESH:
{
LLViewerInventoryItem* inv_item = (LLViewerInventoryItem*)cargo_data;
if(gInventory.getItem(inv_item->getUUID())
diff --git a/indra/newview/llviewerassettype.cpp b/indra/newview/llviewerassettype.cpp
index b382ff6306..4c088a72b7 100644
--- a/indra/newview/llviewerassettype.cpp
+++ b/indra/newview/llviewerassettype.cpp
@@ -85,6 +85,8 @@ LLViewerAssetDictionary::LLViewerAssetDictionary()
addEntry(LLViewerAssetType::AT_LINK, new ViewerAssetEntry(DAD_LINK));
addEntry(LLViewerAssetType::AT_LINK_FOLDER, new ViewerAssetEntry(DAD_LINK));
+ addEntry(LLViewerAssetType::AT_MESH, new ViewerAssetEntry(DAD_MESH));
+
addEntry(LLViewerAssetType::AT_NONE, new ViewerAssetEntry(DAD_NONE));
};
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 68a5147bc7..c837ebef88 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -870,12 +870,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
}
}
- /// We copy the frame buffer straight into a texture here,
- /// and then display it again with compositor effects.
- /// Using render to texture would be faster/better, but I don't have a
- /// grasp of their full display stack just yet.
- // gPostProcess->apply(gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw());
-
if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender)
{
gPipeline.renderDeferredLighting();
@@ -1118,7 +1112,7 @@ void render_ui(F32 zoom_factor, int subfield)
{
gPipeline.renderBloom(gSnapshot, zoom_factor, subfield);
}
-
+
render_hud_elements();
render_hud_attachments();
}
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 35c9a1d367..e8fc50ef21 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -74,6 +74,7 @@
#include "llimpanel.h"
#include "llfloaterinspect.h"
#include "llfloaterinventory.h"
+#include "llfloaterimportcollada.h"
#include "llfloaterjoystick.h"
#include "llfloaterlagmeter.h"
#include "llfloaterland.h"
@@ -128,6 +129,8 @@
#include "llpreviewtexture.h"
#include "llsyswellwindow.h"
#include "llscriptfloater.h"
+#include "llfloatermodelpreview.h"
+
// *NOTE: Please add files in alphabetical order to keep merges easy.
@@ -175,6 +178,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("hud", "floater_hud.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHUD>);
LLFloaterReg::add("impanel", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIMFloater>);
+ LLFloaterReg::add("import_collada", "floater_import_collada.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterImportCollada>);
LLFloaterReg::add("im_container", "floater_im_container.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIMFloaterContainer>);
LLFloaterReg::add("im_well_window", "floater_sys_well.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIMWellWindow>);
LLFloaterReg::add("incoming_call", "floater_incoming_call.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIncomingCallDialog>);
@@ -253,7 +257,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("upload_anim", "floater_animation_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAnimPreview>, "upload");
LLFloaterReg::add("upload_image", "floater_image_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterImagePreview>, "upload");
LLFloaterReg::add("upload_sound", "floater_sound_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSoundPreview>, "upload");
-
+ LLFloaterReg::add("upload_model", "floater_model_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterModelPreview>, "upload");
LLFloaterReg::add("volume_pulldown", "floater_volume_pulldown.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterVolumePulldown>);
LLFloaterReg::add("voice_controls", "floater_voice_controls.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLCallFloater>);
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 791e3a1948..51c9a94298 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -162,7 +162,6 @@ LLMenuItemCallGL* gBusyMenu = NULL;
// Local prototypes
// File Menu
-const char* upload_pick(void* data);
void handle_compress_image(void*);
@@ -450,6 +449,7 @@ void init_menus()
gMenuHolder->childSetLabelArg("Upload Sound", "[COST]", upload_cost);
gMenuHolder->childSetLabelArg("Upload Animation", "[COST]", upload_cost);
gMenuHolder->childSetLabelArg("Bulk Upload", "[COST]", upload_cost);
+ gMenuHolder->childSetLabelArg("Upload Model", "[COST]", upload_cost);
gAFKMenu = gMenuBarView->getChild<LLMenuItemCallGL>("Set Away", TRUE);
gBusyMenu = gMenuBarView->getChild<LLMenuItemCallGL>("Set Busy", TRUE);
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index 6bad8843fd..de6fcbd8bc 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -39,6 +39,8 @@
#include "llfilepicker.h"
#include "llfloaterreg.h"
#include "llfloaterbuycurrency.h"
+#include "llfloaterimportcollada.h"
+#include "llfloatermodelpreview.h"
#include "llfloatersnapshot.h"
#include "llimage.h"
#include "llimagebmp.h"
@@ -63,7 +65,7 @@
#include "llappviewer.h"
#include "lluploaddialog.h"
#include "lltrans.h"
-
+#include "llfloaterimportcollada.h"
// linden libraries
#include "llassetuploadresponders.h"
@@ -71,6 +73,7 @@
#include "llhttpclient.h"
#include "llnotificationsutil.h"
#include "llsdserialize.h"
+#include "llsdutil.h"
#include "llstring.h"
#include "lltransactiontypes.h"
#include "lluuid.h"
@@ -102,6 +105,7 @@ static std::string XML_EXTENSIONS = "xml";
static std::string SLOBJECT_EXTENSIONS = "slobject";
#endif
static std::string ALL_FILE_EXTENSIONS = "*.*";
+static std::string MODEL_EXTENSIONS = "dae";
std::string build_extensions_string(LLFilePicker::ELoadFilter filter)
{
@@ -116,6 +120,8 @@ std::string build_extensions_string(LLFilePicker::ELoadFilter filter)
return ANIM_EXTENSIONS;
case LLFilePicker::FFLOAD_SLOBJECT:
return SLOBJECT_EXTENSIONS;
+ case LLFilePicker::FFLOAD_MODEL:
+ return MODEL_EXTENSIONS;
#ifdef _CORY_TESTING
case LLFilePicker::FFLOAD_GEOMETRY:
return GEOMETRY_EXTENSIONS;
@@ -259,6 +265,33 @@ class LLFileUploadImage : public view_listener_t
}
};
+class LLFileUploadScene : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string filename = upload_pick((void *)LLFilePicker::FFLOAD_COLLADA);
+ if (!filename.empty())
+ {
+ LLImportCollada::getInstance()->importFile(filename);
+ }
+ return TRUE;
+ }
+};
+
+class LLFileUploadModel : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLFloaterModelPreview* fmp = (LLFloaterModelPreview*) LLFloaterReg::showInstance("upload_model");
+ if (fmp)
+ {
+ fmp->loadModel(3);
+ }
+
+ return TRUE;
+ }
+};
+
class LLFileUploadSound : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -320,10 +353,21 @@ class LLFileUploadBulk : public view_listener_t
LLAssetStorage::LLStoreAssetCallback callback = NULL;
S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
void *userdata = NULL;
- upload_new_resource(filename, asset_name, asset_name, 0, LLFolderType::FT_NONE, LLInventoryType::IT_NONE,
- LLFloaterPerms::getNextOwnerPerms(), LLFloaterPerms::getGroupPerms(), LLFloaterPerms::getEveryonePerms(),
- display_name,
- callback, expected_upload_cost, userdata);
+
+ upload_new_resource(
+ filename,
+ asset_name,
+ asset_name,
+ 0,
+ LLFolderType::FT_NONE,
+ LLInventoryType::IT_NONE,
+ LLFloaterPerms::getNextOwnerPerms(),
+ LLFloaterPerms::getGroupPerms(),
+ LLFloaterPerms::getEveryonePerms(),
+ display_name,
+ callback,
+ expected_upload_cost,
+ userdata);
// *NOTE: Ew, we don't iterate over the file list here,
// we handle the next files in upload_done_callback()
@@ -479,17 +523,20 @@ void handle_compress_image(void*)
}
}
-void upload_new_resource(const std::string& src_filename, std::string name,
- std::string desc, S32 compression_info,
- LLFolderType::EType destination_folder_type,
- LLInventoryType::EType inv_type,
- U32 next_owner_perms,
- U32 group_perms,
- U32 everyone_perms,
- const std::string& display_name,
- LLAssetStorage::LLStoreAssetCallback callback,
- S32 expected_upload_cost,
- void *userdata)
+LLUUID upload_new_resource(
+ const std::string& src_filename,
+ std::string name,
+ std::string desc,
+ S32 compression_info,
+ LLFolderType::EType destination_folder_type,
+ LLInventoryType::EType inv_type,
+ U32 next_owner_perms,
+ U32 group_perms,
+ U32 everyone_perms,
+ const std::string& display_name,
+ LLAssetStorage::LLStoreAssetCallback callback,
+ S32 expected_upload_cost,
+ void *userdata)
{
// Generate the temporary UUID.
std::string filename = gDirUtilp->getTempFilename();
@@ -514,7 +561,7 @@ void upload_new_resource(const std::string& src_filename, std::string name,
short_name.c_str());
args["FILE"] = short_name;
upload_error(error_message, "NofileExtension", filename, args);
- return;
+ return LLUUID();
}
else if( exten == "bmp")
{
@@ -528,7 +575,7 @@ void upload_new_resource(const std::string& src_filename, std::string name,
args["FILE"] = src_filename;
args["ERROR"] = LLImage::getLastError();
upload_error(error_message, "ProblemWithFile", filename, args);
- return;
+ return LLUUID();
}
}
else if( exten == "tga")
@@ -543,7 +590,7 @@ void upload_new_resource(const std::string& src_filename, std::string name,
args["FILE"] = src_filename;
args["ERROR"] = LLImage::getLastError();
upload_error(error_message, "ProblemWithFile", filename, args);
- return;
+ return LLUUID();
}
}
else if( exten == "jpg" || exten == "jpeg")
@@ -558,7 +605,7 @@ void upload_new_resource(const std::string& src_filename, std::string name,
args["FILE"] = src_filename;
args["ERROR"] = LLImage::getLastError();
upload_error(error_message, "ProblemWithFile", filename, args);
- return;
+ return LLUUID();
}
}
else if( exten == "png")
@@ -573,7 +620,7 @@ void upload_new_resource(const std::string& src_filename, std::string name,
args["FILE"] = src_filename;
args["ERROR"] = LLImage::getLastError();
upload_error(error_message, "ProblemWithFile", filename, args);
- return;
+ return LLUUID();
}
}
else if(exten == "wav")
@@ -601,7 +648,7 @@ void upload_new_resource(const std::string& src_filename, std::string name,
upload_error(error_message, "UnknownVorbisEncodeFailure", filename, args);
break;
}
- return;
+ return LLUUID();
}
}
else if(exten == "tmp")
@@ -641,7 +688,7 @@ void upload_new_resource(const std::string& src_filename, std::string name,
error_message = llformat("corrupt resource file: %s", src_filename.c_str());
args["FILE"] = src_filename;
upload_error(error_message, "CorruptResourceFile", filename, args);
- return;
+ return LLUUID();
}
if (2 == tokens_read)
@@ -669,7 +716,7 @@ void upload_new_resource(const std::string& src_filename, std::string name,
error_message = llformat("unknown linden resource file version in file: %s", src_filename.c_str());
args["FILE"] = src_filename;
upload_error(error_message, "UnknownResourceFileVersion", filename, args);
- return;
+ return LLUUID();
}
}
else
@@ -711,7 +758,7 @@ void upload_new_resource(const std::string& src_filename, std::string name,
error_message = llformat( "Unable to create output file: %s", filename.c_str());
args["FILE"] = filename;
upload_error(error_message, "UnableToCreateOutputFile", filename, args);
- return;
+ return LLUUID();
}
fclose(in);
@@ -725,7 +772,7 @@ void upload_new_resource(const std::string& src_filename, std::string name,
{
error_message = llformat("We do not currently support bulk upload of animation files\n");
upload_error(error_message, "DoNotSupportBulkAnimationUpload", filename, args);
- return;
+ return LLUUID();
}
else
{
@@ -771,9 +818,21 @@ void upload_new_resource(const std::string& src_filename, std::string name,
{
t_disp_name = src_filename;
}
- upload_new_resource(tid, asset_type, name, desc, compression_info, // tid
- destination_folder_type, inv_type, next_owner_perms, group_perms, everyone_perms,
- display_name, callback, expected_upload_cost, userdata);
+ upload_new_resource(
+ tid,
+ asset_type,
+ name,
+ desc,
+ compression_info, // tid
+ destination_folder_type,
+ inv_type,
+ next_owner_perms,
+ group_perms,
+ everyone_perms,
+ display_name,
+ callback,
+ expected_upload_cost,
+ userdata);
}
else
{
@@ -787,9 +846,15 @@ void upload_new_resource(const std::string& src_filename, std::string name,
}
LLFilePicker::instance().reset();
}
+
+ return uuid;
}
-void upload_done_callback(const LLUUID& uuid, void* user_data, S32 result, LLExtStat ext_status) // StoreAssetData callback (fixed)
+void upload_done_callback(
+ const LLUUID& uuid,
+ void* user_data,
+ S32 result,
+ LLExtStat ext_status) // StoreAssetData callback (fixed)
{
LLResourceData* data = (LLResourceData*)user_data;
S32 expected_upload_cost = data ? data->mExpectedUploadCost : 0;
@@ -890,70 +955,97 @@ void upload_done_callback(const LLUUID& uuid, void* user_data, S32 result, LLExt
std::string display_name = LLStringUtil::null;
LLAssetStorage::LLStoreAssetCallback callback = NULL;
void *userdata = NULL;
- upload_new_resource(next_file, asset_name, asset_name, // file
- 0, LLFolderType::FT_NONE, LLInventoryType::IT_NONE,
- PERM_NONE, PERM_NONE, PERM_NONE,
- display_name,
- callback,
- expected_upload_cost, // assuming next in a group of uploads is of roughly the same type, i.e. same upload cost
- userdata);
+ upload_new_resource(
+ next_file,
+ asset_name,
+ asset_name, // file
+ 0,
+ LLFolderType::FT_NONE,
+ LLInventoryType::IT_NONE,
+ PERM_NONE,
+ PERM_NONE,
+ PERM_NONE,
+ display_name,
+ callback,
+ expected_upload_cost, // assuming next in a group of uploads is of roughly the same type, i.e. same upload cost
+ userdata);
}
}
-void upload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_type,
- std::string name,
- std::string desc, S32 compression_info,
- LLFolderType::EType destination_folder_type,
- LLInventoryType::EType inv_type,
- U32 next_owner_perms,
- U32 group_perms,
- U32 everyone_perms,
- const std::string& display_name,
- LLAssetStorage::LLStoreAssetCallback callback,
- S32 expected_upload_cost,
- void *userdata)
+static LLAssetID upload_new_resource_prep(
+ const LLTransactionID& tid,
+ LLAssetType::EType asset_type,
+ LLInventoryType::EType& inventory_type,
+ std::string& name,
+ const std::string& display_name,
+ std::string& description)
{
- if(gDisconnected)
- {
- return ;
- }
+ LLAssetID uuid = generate_asset_id_for_new_upload(tid);
- LLAssetID uuid = tid.makeAssetID(gAgent.getSecureSessionID());
-
- if( LLAssetType::AT_SOUND == asset_type )
- {
- LLViewerStats::getInstance()->incStat(LLViewerStats::ST_UPLOAD_SOUND_COUNT );
- }
- else
- if( LLAssetType::AT_TEXTURE == asset_type )
- {
- LLViewerStats::getInstance()->incStat(LLViewerStats::ST_UPLOAD_TEXTURE_COUNT );
- }
- else
- if( LLAssetType::AT_ANIMATION == asset_type)
- {
- LLViewerStats::getInstance()->incStat(LLViewerStats::ST_UPLOAD_ANIM_COUNT );
- }
+ increase_new_upload_stats(asset_type);
- if(LLInventoryType::IT_NONE == inv_type)
- {
- inv_type = LLInventoryType::defaultForAssetType(asset_type);
- }
- LLStringUtil::stripNonprintable(name);
- LLStringUtil::stripNonprintable(desc);
- if(name.empty())
- {
- name = "(No Name)";
- }
- if(desc.empty())
- {
- desc = "(No Description)";
- }
-
- // At this point, we're ready for the upload.
- std::string upload_message = "Uploading...\n\n";
- upload_message.append(display_name);
- LLUploadDialog::modalUploadDialog(upload_message);
+ assign_defaults_and_show_upload_message(
+ asset_type,
+ inventory_type,
+ name,
+ display_name,
+ description);
+
+ return uuid;
+}
+
+LLSD generate_new_resource_upload_capability_body(
+ LLAssetType::EType asset_type,
+ const std::string& name,
+ const std::string& desc,
+ LLFolderType::EType destination_folder_type,
+ LLInventoryType::EType inv_type,
+ U32 next_owner_perms,
+ U32 group_perms,
+ U32 everyone_perms)
+{
+ LLSD body;
+
+ body["folder_id"] = gInventory.findCategoryUUIDForType(
+ (destination_folder_type == LLFolderType::FT_NONE) ?
+ (LLFolderType::EType) asset_type :
+ destination_folder_type);
+
+ body["asset_type"] = LLAssetType::lookup(asset_type);
+ body["inventory_type"] = LLInventoryType::lookup(inv_type);
+ body["name"] = name;
+ body["description"] = desc;
+ body["next_owner_mask"] = LLSD::Integer(next_owner_perms);
+ body["group_mask"] = LLSD::Integer(group_perms);
+ body["everyone_mask"] = LLSD::Integer(everyone_perms);
+
+ return body;
+}
+
+void upload_new_resource(
+ const LLTransactionID &tid,
+ LLAssetType::EType asset_type,
+ std::string name,
+ std::string desc,
+ S32 compression_info,
+ LLFolderType::EType destination_folder_type,
+ LLInventoryType::EType inv_type,
+ U32 next_owner_perms,
+ U32 group_perms,
+ U32 everyone_perms,
+ const std::string& display_name,
+ LLAssetStorage::LLStoreAssetCallback callback,
+ S32 expected_upload_cost,
+ void *userdata)
+{
+ LLAssetID uuid =
+ upload_new_resource_prep(
+ tid,
+ asset_type,
+ inv_type,
+ name,
+ display_name,
+ desc);
llinfos << "*** Uploading: " << llendl;
llinfos << "Type: " << LLAssetType::lookup(asset_type) << llendl;
@@ -963,26 +1055,32 @@ void upload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_ty
llinfos << "Expected Upload Cost: " << expected_upload_cost << llendl;
lldebugs << "Folder: " << gInventory.findCategoryUUIDForType((destination_folder_type == LLFolderType::FT_NONE) ? LLFolderType::assetTypeToFolderType(asset_type) : destination_folder_type) << llendl;
lldebugs << "Asset Type: " << LLAssetType::lookup(asset_type) << llendl;
- std::string url = gAgent.getRegion()->getCapability("NewFileAgentInventory");
- if (!url.empty())
+
+ std::string url = gAgent.getRegion()->getCapability(
+ "NewFileAgentInventory");
+
+ if ( !url.empty() )
{
llinfos << "New Agent Inventory via capability" << llendl;
- LLSD body;
- body["folder_id"] = gInventory.findCategoryUUIDForType((destination_folder_type == LLFolderType::FT_NONE) ? LLFolderType::assetTypeToFolderType(asset_type) : destination_folder_type);
- body["asset_type"] = LLAssetType::lookup(asset_type);
- body["inventory_type"] = LLInventoryType::lookup(inv_type);
- body["name"] = name;
- body["description"] = desc;
- body["next_owner_mask"] = LLSD::Integer(next_owner_perms);
- body["group_mask"] = LLSD::Integer(group_perms);
- body["everyone_mask"] = LLSD::Integer(everyone_perms);
- body["expected_upload_cost"] = LLSD::Integer(expected_upload_cost);
-
- //std::ostringstream llsdxml;
- //LLSDSerialize::toPrettyXML(body, llsdxml);
- //llinfos << "posting body to capability: " << llsdxml.str() << llendl;
- LLHTTPClient::post(url, body, new LLNewAgentInventoryResponder(body, uuid, asset_type));
+ LLSD body;
+ body = generate_new_resource_upload_capability_body(
+ asset_type,
+ name,
+ desc,
+ destination_folder_type,
+ inv_type,
+ next_owner_perms,
+ group_perms,
+ everyone_perms);
+
+ LLHTTPClient::post(
+ url,
+ body,
+ new LLNewAgentInventoryResponder(
+ body,
+ uuid,
+ asset_type));
}
else
{
@@ -1020,18 +1118,158 @@ void upload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_ty
{
asset_callback = callback;
}
- gAssetStorage->storeAssetData(data->mAssetInfo.mTransactionID, data->mAssetInfo.mType,
- asset_callback,
- (void*)data,
- FALSE);
+ gAssetStorage->storeAssetData(
+ data->mAssetInfo.mTransactionID,
+ data->mAssetInfo.mType,
+ asset_callback,
+ (void*)data,
+ FALSE);
}
}
+BOOL upload_new_variable_price_resource(
+ const LLTransactionID &tid,
+ LLAssetType::EType asset_type,
+ std::string name,
+ std::string desc,
+ LLFolderType::EType destination_folder_type,
+ LLInventoryType::EType inv_type,
+ U32 next_owner_perms,
+ U32 group_perms,
+ U32 everyone_perms,
+ const std::string& display_name,
+ const LLSD& asset_resources)
+{
+ LLAssetID uuid =
+ upload_new_resource_prep(
+ tid,
+ asset_type,
+ inv_type,
+ name,
+ display_name,
+ desc);
+
+ llinfos << "*** Uploading: " << llendl;
+ llinfos << "Type: " << LLAssetType::lookup(asset_type) << llendl;
+ llinfos << "UUID: " << uuid << llendl;
+ llinfos << "Name: " << name << llendl;
+ llinfos << "Desc: " << desc << llendl;
+ lldebugs << "Folder: "
+ << gInventory.findCategoryUUIDForType((destination_folder_type == LLFolderType::FT_NONE) ? (LLFolderType::EType)asset_type : destination_folder_type) << llendl;
+ lldebugs << "Asset Type: " << LLAssetType::lookup(asset_type) << llendl;
+
+ std::string url = gAgent.getRegion()->getCapability(
+ "NewFileAgentInventoryVariablePrice");
+
+ if ( !url.empty() )
+ {
+ lldebugs
+ << "New Agent Inventory variable price upload" << llendl;
+
+ // Each of the two capabilities has similar data, so
+ // let's reuse that code
+
+ LLSD body;
+
+ body = generate_new_resource_upload_capability_body(
+ asset_type,
+ name,
+ desc,
+ destination_folder_type,
+ inv_type,
+ next_owner_perms,
+ group_perms,
+ everyone_perms);
+
+ body["asset_resources"] = asset_resources;
+
+ LLHTTPClient::post(
+ url,
+ body,
+ new LLNewAgentInventoryVariablePriceResponder(
+ uuid,
+ asset_type,
+ body));
+
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+LLAssetID generate_asset_id_for_new_upload(const LLTransactionID& tid)
+{
+ if ( gDisconnected )
+ {
+ LLAssetID rv;
+
+ rv.setNull();
+ return rv;
+ }
+
+ LLAssetID uuid = tid.makeAssetID(gAgent.getSecureSessionID());
+
+ return uuid;
+}
+
+void increase_new_upload_stats(LLAssetType::EType asset_type)
+{
+ if ( LLAssetType::AT_SOUND == asset_type )
+ {
+ LLViewerStats::getInstance()->incStat(
+ LLViewerStats::ST_UPLOAD_SOUND_COUNT );
+ }
+ else if ( LLAssetType::AT_TEXTURE == asset_type )
+ {
+ LLViewerStats::getInstance()->incStat(
+ LLViewerStats::ST_UPLOAD_TEXTURE_COUNT );
+ }
+ else if ( LLAssetType::AT_ANIMATION == asset_type )
+ {
+ LLViewerStats::getInstance()->incStat(
+ LLViewerStats::ST_UPLOAD_ANIM_COUNT );
+ }
+}
+
+void assign_defaults_and_show_upload_message(
+ LLAssetType::EType asset_type,
+ LLInventoryType::EType& inventory_type,
+ std::string& name,
+ const std::string& display_name,
+ std::string& description)
+{
+ if ( LLInventoryType::IT_NONE == inventory_type )
+ {
+ inventory_type = LLInventoryType::defaultForAssetType(asset_type);
+ }
+ LLStringUtil::stripNonprintable(name);
+ LLStringUtil::stripNonprintable(description);
+
+ if ( name.empty() )
+ {
+ name = "(No Name)";
+ }
+ if ( description.empty() )
+ {
+ description = "(No Description)";
+ }
+
+ // At this point, we're ready for the upload.
+ std::string upload_message = "Uploading...\n\n";
+ upload_message.append(display_name);
+ LLUploadDialog::modalUploadDialog(upload_message);
+}
+
+
void init_menu_file()
{
view_listener_t::addCommit(new LLFileUploadImage(), "File.UploadImage");
view_listener_t::addCommit(new LLFileUploadSound(), "File.UploadSound");
view_listener_t::addCommit(new LLFileUploadAnim(), "File.UploadAnim");
+ view_listener_t::addCommit(new LLFileUploadModel(), "File.UploadModel");
+ view_listener_t::addCommit(new LLFileUploadScene(), "File.UploadScene");
view_listener_t::addCommit(new LLFileUploadBulk(), "File.UploadBulk");
view_listener_t::addCommit(new LLFileCloseWindow(), "File.CloseWindow");
view_listener_t::addCommit(new LLFileCloseAllWindows(), "File.CloseAllWindows");
diff --git a/indra/newview/llviewermenufile.h b/indra/newview/llviewermenufile.h
index 1e6d13f1c6..7167903311 100644
--- a/indra/newview/llviewermenufile.h
+++ b/indra/newview/llviewermenufile.h
@@ -42,33 +42,62 @@ class LLTransactionID;
void init_menu_file();
-void upload_new_resource(const std::string& src_filename,
- std::string name,
- std::string desc,
- S32 compression_info,
- LLFolderType::EType destination_folder_type,
- LLInventoryType::EType inv_type,
- U32 next_owner_perms,
- U32 group_perms,
- U32 everyone_perms,
- const std::string& display_name,
- LLAssetStorage::LLStoreAssetCallback callback,
- S32 expected_upload_cost,
- void *userdata);
+LLUUID upload_new_resource(
+ const std::string& src_filename,
+ std::string name,
+ std::string desc,
+ S32 compression_info,
+ LLFolderType::EType destination_folder_type,
+ LLInventoryType::EType inv_type,
+ U32 next_owner_perms,
+ U32 group_perms,
+ U32 everyone_perms,
+ const std::string& display_name,
+ LLAssetStorage::LLStoreAssetCallback callback,
+ S32 expected_upload_cost,
+ void *userdata);
-void upload_new_resource(const LLTransactionID &tid,
- LLAssetType::EType type,
- std::string name,
- std::string desc,
- S32 compression_info,
- LLFolderType::EType destination_folder_type,
- LLInventoryType::EType inv_type,
- U32 next_owner_perms,
- U32 group_perms,
- U32 everyone_perms,
- const std::string& display_name,
- LLAssetStorage::LLStoreAssetCallback callback,
- S32 expected_upload_cost,
- void *userdata);
+void upload_new_resource(
+ const LLTransactionID &tid,
+ LLAssetType::EType type,
+ std::string name,
+ std::string desc,
+ S32 compression_info,
+ LLFolderType::EType destination_folder_type,
+ LLInventoryType::EType inv_type,
+ U32 next_owner_perms,
+ U32 group_perms,
+ U32 everyone_perms,
+ const std::string& display_name,
+ LLAssetStorage::LLStoreAssetCallback callback,
+ S32 expected_upload_cost,
+ void *userdata);
+
+// TODO* : Move all uploads to use this new function
+// since at some point, that upload path will be deprecated and no longer
+// used
+
+// We make a new function here to ensure that previous code is not broken
+BOOL upload_new_variable_price_resource(
+ const LLTransactionID& tid,
+ LLAssetType::EType type,
+ std::string name,
+ std::string desc,
+ LLFolderType::EType destination_folder_type,
+ LLInventoryType::EType inv_type,
+ U32 next_owner_perms,
+ U32 group_perms,
+ U32 everyone_perms,
+ const std::string& display_name,
+ const LLSD& asset_resources);
+
+LLAssetID generate_asset_id_for_new_upload(const LLTransactionID& tid);
+void increase_new_upload_stats(LLAssetType::EType asset_type);
+void assign_defaults_and_show_upload_message(
+ LLAssetType::EType asset_type,
+ LLInventoryType::EType& inventory_type,
+ std::string& name,
+ const std::string& display_name,
+ std::string& description);
#endif
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index ea40f2aae1..810bf59e41 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -3155,6 +3155,7 @@ const F32 THRESHOLD_HEAD_ROT_QDOT = 0.9997f; // ~= 2.5 degrees -- if its less th
const F32 MAX_HEAD_ROT_QDOT = 0.99999f; // ~= 0.5 degrees -- if its greater than this then no need to update head_rot
// between these values we delay the updates (but no more than one second)
+static LLFastTimer::DeclareTimer FTM_AGENT_UPDATE_SEND("Send Message");
void send_agent_update(BOOL force_send, BOOL send_reliable)
{
@@ -3313,6 +3314,7 @@ void send_agent_update(BOOL force_send, BOOL send_reliable)
if (duplicate_count < DUP_MSGS && !gDisconnected)
{
+ LLFastTimer t(FTM_AGENT_UPDATE_SEND);
// Build the message
msg->newMessageFast(_PREHASH_AgentUpdate);
msg->nextBlockFast(_PREHASH_AgentData);
@@ -4714,6 +4716,7 @@ void process_economy_data(LLMessageSystem *msg, void** /*user_data*/)
gMenuHolder->childSetLabelArg("Upload Image", "[COST]", llformat("%d", upload_cost));
gMenuHolder->childSetLabelArg("Upload Sound", "[COST]", llformat("%d", upload_cost));
+ gMenuHolder->childSetLabelArg("Upload Model", "[COST]", llformat("%d", upload_cost));
gMenuHolder->childSetLabelArg("Upload Animation", "[COST]", llformat("%d", upload_cost));
gMenuHolder->childSetLabelArg("Bulk Upload", "[COST]", llformat("%d", upload_cost));
}
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index 96828ee1b6..7a6f479685 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -866,8 +866,12 @@ void LLViewerObjectList::cleanupReferences(LLViewerObject *objectp)
mNumDeadObjects++;
}
+static LLFastTimer::DeclareTimer FTM_REMOVE_DRAWABLE("Remove Drawable");
+
void LLViewerObjectList::removeDrawable(LLDrawable* drawablep)
{
+ LLFastTimer t(FTM_REMOVE_DRAWABLE);
+
if (!drawablep)
{
return;
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index d1c9840a97..f173149bf4 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -1432,11 +1432,14 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
capabilityNames.append("FetchLib");
capabilityNames.append("FetchLibDescendents");
capabilityNames.append("GetTexture");
+ capabilityNames.append("GetMesh");
capabilityNames.append("GroupProposalBallot");
capabilityNames.append("HomeLocation");
capabilityNames.append("MapLayer");
capabilityNames.append("MapLayerGod");
capabilityNames.append("NewFileAgentInventory");
+ capabilityNames.append("NewFileAgentInventoryVariablePrice");
+ capabilityNames.append("ObjectAdd");
capabilityNames.append("ParcelPropertiesUpdate");
capabilityNames.append("ParcelMediaURLFilterList");
capabilityNames.append("ParcelNavigateMedia");
diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp
index 300aea1620..b0a9ee0dc5 100644
--- a/indra/newview/llviewertexteditor.cpp
+++ b/indra/newview/llviewertexteditor.cpp
@@ -533,6 +533,7 @@ LLUIImagePtr LLEmbeddedItems::getItemImage(llwchar ext_char) const
case LLAssetType::AT_BODYPART: img_name = "Inv_Skin"; break;
case LLAssetType::AT_ANIMATION: img_name = "Inv_Animation"; break;
case LLAssetType::AT_GESTURE: img_name = "Inv_Gesture"; break;
+ case LLAssetType::AT_MESH: img_name = "Inv_Mesh"; break;
default: llassert(0);
}
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index b45148a186..2b97642736 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -627,13 +627,13 @@ void LLViewerTexture::setKnownDrawSize(S32 width, S32 height)
//virtual
void LLViewerTexture::addFace(LLFace* facep)
{
- mFaceList.push_back(facep) ;
+ mFaceList.insert(facep) ;
}
//virtual
void LLViewerTexture::removeFace(LLFace* facep)
{
- mFaceList.remove(facep) ;
+ mFaceList.erase(facep);
}
//virtual
@@ -691,7 +691,7 @@ BOOL LLViewerTexture::createGLTexture(S32 discard_level, const LLImageRaw* image
llassert_always(mGLTexturep.notNull()) ;
BOOL ret = mGLTexturep->createGLTexture(discard_level, imageraw, usename, to_create, category) ;
-
+
if(ret)
{
mFullWidth = mGLTexturep->getCurrentWidth() ;
@@ -1532,7 +1532,7 @@ void LLViewerFetchedTexture::updateVirtualSize()
}
if(mFaceList.size() > 0)
{
- for(std::list<LLFace*>::iterator iter = mFaceList.begin(); iter != mFaceList.end(); ++iter)
+ for(ll_face_list_t::iterator iter = mFaceList.begin(); iter != mFaceList.end(); ++iter)
{
LLFace* facep = *iter ;
if(facep->getDrawable()->isRecentlyVisible())
@@ -2404,7 +2404,7 @@ BOOL LLViewerFetchedTexture::insertToAtlas()
LLFace* facep;
//if the atlas slot pointers for some faces are null, process them later.
- ll_face_list_t waiting_list ;
+ std::vector<LLFace*> waiting_list ;
for(ll_face_list_t::iterator iter = mFaceList.begin(); iter != mFaceList.end(); ++iter)
{
@@ -2488,7 +2488,7 @@ BOOL LLViewerFetchedTexture::insertToAtlas()
}
//process the waiting_list
- for(ll_face_list_t::iterator iter = waiting_list.begin(); iter != waiting_list.end(); ++iter)
+ for(std::vector<LLFace*>::iterator iter = waiting_list.begin(); iter != waiting_list.end(); ++iter)
{
facep = (LLFace*)*iter ;
groupp = facep->getDrawable()->getSpatialGroup() ;
@@ -3166,7 +3166,7 @@ F32 LLViewerMediaTexture::getMaxVirtualSize()
{
if(mFaceList.size() > 0)
{
- for(std::list<LLFace*>::iterator iter = mFaceList.begin(); iter != mFaceList.end(); ++iter)
+ for(ll_face_list_t::iterator iter = mFaceList.begin(); iter != mFaceList.end(); ++iter)
{
LLFace* facep = *iter ;
if(facep->getDrawable()->isRecentlyVisible())
diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h
index d6fbd5d570..548451723d 100644
--- a/indra/newview/llviewertexture.h
+++ b/indra/newview/llviewertexture.h
@@ -134,7 +134,7 @@ public:
static S32 getIndexFromCategory(S32 category) ;
static S32 getCategoryFromIndex(S32 index) ;
- typedef std::list<LLFace*> ll_face_list_t ;
+ typedef std::set<LLFace*> ll_face_list_t ;
protected:
virtual ~LLViewerTexture();
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 9cacdaa3f9..e06d7ec5d3 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -3690,140 +3690,6 @@ void LLViewerWindow::playSnapshotAnimAndSound()
BOOL LLViewerWindow::thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL do_rebuild, ESnapshotType type)
{
return rawSnapshot(raw, preview_width, preview_height, FALSE, FALSE, show_ui, do_rebuild, type);
-
- // *TODO below code was broken in deferred pipeline
- /*
- if ((!raw) || preview_width < 10 || preview_height < 10)
- {
- return FALSE;
- }
-
- if(gResizeScreenTexture) //the window is resizing
- {
- return FALSE ;
- }
-
- setCursor(UI_CURSOR_WAIT);
-
- // Hide all the UI widgets first and draw a frame
- BOOL prev_draw_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI);
-
- if ( prev_draw_ui != show_ui)
- {
- LLPipeline::toggleRenderDebugFeature((void*)LLPipeline::RENDER_DEBUG_FEATURE_UI);
- }
-
- BOOL hide_hud = !gSavedSettings.getBOOL("RenderHUDInSnapshot") && LLPipeline::sShowHUDAttachments;
- if (hide_hud)
- {
- LLPipeline::sShowHUDAttachments = FALSE;
- }
-
- S32 render_name = gSavedSettings.getS32("RenderName");
- gSavedSettings.setS32("RenderName", 0);
- LLVOAvatar::updateFreezeCounter(1) ; //pause avatar updating for one frame
-
- S32 w = preview_width ;
- S32 h = preview_height ;
- LLVector2 display_scale = mDisplayScale ;
- mDisplayScale.setVec((F32)w / mWindowRectRaw.getWidth(), (F32)h / mWindowRectRaw.getHeight()) ;
- LLRect window_rect = mWindowRectRaw;
- mWindowRectRaw.set(0, h, w, 0);
-
- gDisplaySwapBuffers = FALSE;
- gDepthDirty = TRUE;
- glClearColor(0.f, 0.f, 0.f, 0.f);
- glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
- setup3DRender();
-
- LLFontGL::setFontDisplay(FALSE) ;
- LLHUDText::setDisplayText(FALSE) ;
- if (type == SNAPSHOT_TYPE_OBJECT_ID)
- {
- gObjectList.renderPickList(gViewerWindow->getWindowRectScaled(), FALSE, FALSE);
- }
- else
- {
- display(do_rebuild, 1.0f, 0, TRUE);
- render_ui();
- }
-
- S32 glformat, gltype, glpixel_length ;
- if(SNAPSHOT_TYPE_DEPTH == type)
- {
- glpixel_length = 4 ;
- glformat = GL_DEPTH_COMPONENT ;
- gltype = GL_FLOAT ;
- }
- else
- {
- glpixel_length = 3 ;
- glformat = GL_RGB ;
- gltype = GL_UNSIGNED_BYTE ;
- }
-
- raw->resize(w, h, glpixel_length);
- glReadPixels(0, 0, w, h, glformat, gltype, raw->getData());
-
- if(SNAPSHOT_TYPE_DEPTH == type)
- {
- LLViewerCamera* camerap = LLViewerCamera::getInstance();
- F32 depth_conversion_factor_1 = (camerap->getFar() + camerap->getNear()) / (2.f * camerap->getFar() * camerap->getNear());
- F32 depth_conversion_factor_2 = (camerap->getFar() - camerap->getNear()) / (2.f * camerap->getFar() * camerap->getNear());
-
- //calculate the depth
- for (S32 y = 0 ; y < h ; y++)
- {
- for(S32 x = 0 ; x < w ; x++)
- {
- S32 i = (w * y + x) << 2 ;
-
- F32 depth_float_i = *(F32*)(raw->getData() + i);
-
- F32 linear_depth_float = 1.f / (depth_conversion_factor_1 - (depth_float_i * depth_conversion_factor_2));
- U8 depth_byte = F32_to_U8(linear_depth_float, camerap->getNear(), camerap->getFar());
- *(raw->getData() + i + 0) = depth_byte;
- *(raw->getData() + i + 1) = depth_byte;
- *(raw->getData() + i + 2) = depth_byte;
- *(raw->getData() + i + 3) = 255;
- }
- }
- }
-
- LLFontGL::setFontDisplay(TRUE) ;
- LLHUDText::setDisplayText(TRUE) ;
- mDisplayScale.setVec(display_scale) ;
- mWindowRectRaw = window_rect;
- setup3DRender();
- gDisplaySwapBuffers = FALSE;
- gDepthDirty = TRUE;
-
- // POST SNAPSHOT
- if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
- {
- LLPipeline::toggleRenderDebugFeature((void*)LLPipeline::RENDER_DEBUG_FEATURE_UI);
- }
-
- if (hide_hud)
- {
- LLPipeline::sShowHUDAttachments = TRUE;
- }
-
- setCursor(UI_CURSOR_ARROW);
-
- if (do_rebuild)
- {
- // If we had to do a rebuild, that means that the lists of drawables to be rendered
- // was empty before we started.
- // Need to reset these, otherwise we call state sort on it again when render gets called the next time
- // and we stand a good chance of crashing on rebuild because the render drawable arrays have multiple copies of
- // objects on them.
- gPipeline.resetDrawOrders();
- }
-
- gSavedSettings.setS32("RenderName", render_name);
-
- return TRUE;*/
}
// Saves the image from the screen to the specified filename and path.
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index f98aa361e0..cba99b034b 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -36,6 +36,8 @@
#include "llvovolume.h"
+#include <sstream>
+
#include "llviewercontrol.h"
#include "lldir.h"
#include "llflexibleobject.h"
@@ -59,6 +61,7 @@
#include "lltexturefetch.h"
#include "llviewercamera.h"
#include "llviewertexturelist.h"
+#include "llviewerobjectlist.h"
#include "llviewerregion.h"
#include "llviewertextureanim.h"
#include "llworld.h"
@@ -67,6 +70,7 @@
#include "llsdutil.h"
#include "llmediaentry.h"
#include "llmediadataclient.h"
+#include "llmeshrepository.h"
#include "llagent.h"
#include "llviewermediafocus.h"
@@ -88,6 +92,12 @@ LLPointer<LLObjectMediaNavigateClient> LLVOVolume::sObjectMediaNavigateClient =
static LLFastTimer::DeclareTimer FTM_GEN_TRIANGLES("Generate Triangles");
static LLFastTimer::DeclareTimer FTM_GEN_VOLUME("Generate Volumes");
+static LLFastTimer::DeclareTimer FTM_BUILD_MESH("Mesh");
+static LLFastTimer::DeclareTimer FTM_MESH_VFS("VFS");
+static LLFastTimer::DeclareTimer FTM_MESH_STREAM("Stream");
+static LLFastTimer::DeclareTimer FTM_MESH_FACES("Faces");
+static LLFastTimer::DeclareTimer FTM_VOLUME_TEXTURES("Volume Textures");
+
// Implementation class of LLMediaDataClientObject. See llmediadataclient.h
class LLMediaDataClientObjectImpl : public LLMediaDataClientObject
@@ -618,6 +628,7 @@ void LLVOVolume::updateTextures()
void LLVOVolume::updateTextureVirtualSize()
{
+ LLFastTimer ftm(FTM_VOLUME_TEXTURES);
// Update the pixel area of all faces
if(mDrawable.isNull() || !mDrawable->isVisible())
@@ -710,46 +721,52 @@ void LLVOVolume::updateTextureVirtualSize()
if (isSculpted())
{
LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT);
- LLUUID id = sculpt_params->getSculptTexture();
- mSculptTexture = LLViewerTextureManager::getFetchedTexture(id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
- if (mSculptTexture.notNull())
+ LLUUID id = sculpt_params->getSculptTexture();
+ U8 sculpt_type = sculpt_params->getSculptType();
+
+ if ((sculpt_type & LL_SCULPT_TYPE_MASK) != LL_SCULPT_TYPE_MESH)
{
- mSculptTexture->setBoostLevel(llmax((S32)mSculptTexture->getBoostLevel(),
- (S32)LLViewerTexture::BOOST_SCULPTED));
- mSculptTexture->setForSculpt() ;
-
- if(!mSculptTexture->isCachedRawImageReady())
+ mSculptTexture = LLViewerTextureManager::getFetchedTexture(id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+
+ if (mSculptTexture.notNull())
{
- S32 lod = llmin(mLOD, 3);
- F32 lodf = ((F32)(lod + 1.0f)/4.f);
- F32 tex_size = lodf * LLViewerTexture::sMaxSculptRez ;
- mSculptTexture->addTextureStats(2.f * tex_size * tex_size, FALSE);
+ mSculptTexture->setBoostLevel(llmax((S32)mSculptTexture->getBoostLevel(),
+ (S32)LLViewerTexture::BOOST_SCULPTED));
+ mSculptTexture->setForSculpt() ;
- //if the sculpty very close to the view point, load first
- {
+ if(!mSculptTexture->isCachedRawImageReady())
+ {
+ S32 lod = llmin(mLOD, 3);
+ F32 lodf = ((F32)(lod + 1.0f)/4.f);
+ F32 tex_size = lodf * LLViewerTexture::sMaxSculptRez ;
+ mSculptTexture->addTextureStats(2.f * tex_size * tex_size, FALSE);
+
+ //if the sculpty very close to the view point, load first
+ {
LLVector3 lookAt = getPositionAgent() - camera->getOrigin();
- F32 dist = lookAt.normVec() ;
+ F32 dist = lookAt.normVec() ;
F32 cos_angle_to_view_dir = lookAt * camera->getXAxis() ;
- mSculptTexture->setAdditionalDecodePriority(0.8f * LLFace::calcImportanceToCamera(cos_angle_to_view_dir, dist)) ;
+ mSculptTexture->setAdditionalDecodePriority(0.8f * LLFace::calcImportanceToCamera(cos_angle_to_view_dir, dist)) ;
+ }
}
- }
- S32 texture_discard = mSculptTexture->getDiscardLevel(); //try to match the texture
- S32 current_discard = getVolume() ? getVolume()->getSculptLevel() : -2 ;
+ S32 texture_discard = mSculptTexture->getDiscardLevel(); //try to match the texture
+ S32 current_discard = getVolume() ? getVolume()->getSculptLevel() : -2 ;
- if (texture_discard >= 0 && //texture has some data available
- (texture_discard < current_discard || //texture has more data than last rebuild
- current_discard < 0)) //no previous rebuild
- {
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, FALSE);
- mSculptChanged = TRUE;
- }
+ if (texture_discard >= 0 && //texture has some data available
+ (texture_discard < current_discard || //texture has more data than last rebuild
+ current_discard < 0)) //no previous rebuild
+ {
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, FALSE);
+ mSculptChanged = TRUE;
+ }
- if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SCULPTED))
- {
- setDebugText(llformat("T%d C%d V%d\n%dx%d",
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SCULPTED))
+ {
+ setDebugText(llformat("T%d C%d V%d\n%dx%d",
texture_discard, current_discard, getVolume()->getSculptLevel(),
mSculptTexture->getHeight(), mSculptTexture->getWidth()));
+ }
}
}
}
@@ -767,7 +784,7 @@ void LLVOVolume::updateTextureVirtualSize()
*camera));
}
}
-
+
if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA))
{
setDebugText(llformat("%.0f:%.0f", fsqrtf(min_vsize),fsqrtf(max_vsize)));
@@ -863,8 +880,28 @@ LLDrawable *LLVOVolume::createDrawable(LLPipeline *pipeline)
return mDrawable;
}
-BOOL LLVOVolume::setVolume(const LLVolumeParams &volume_params, const S32 detail, bool unique_volume)
+BOOL LLVOVolume::setVolume(const LLVolumeParams &params, const S32 detail, bool unique_volume)
{
+ LLVolumeParams volume_params = params;
+
+ S32 lod = mLOD;
+
+ if (isSculpted())
+ {
+ // if it's a mesh
+ if ((volume_params.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH)
+ { //meshes might not have all LODs, get the force detail to best existing LOD
+ LLUUID mesh_id = params.getSculptID();
+
+ //profile and path params don't matter for meshes
+ volume_params = LLVolumeParams();
+ volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE);
+ volume_params.setSculptID(mesh_id, LL_SCULPT_TYPE_MESH);
+
+ lod = gMeshRepo.getActualMeshLOD(mesh_id, lod);
+ }
+ }
+
// Check if we need to change implementations
bool is_flexible = (volume_params.getPathParams().getCurveType() == LL_PCODE_PATH_FLEXIBLE);
if (is_flexible)
@@ -892,30 +929,50 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &volume_params, const S32 detail
}
}
- if ((LLPrimitive::setVolume(volume_params, mLOD, (mVolumeImpl && mVolumeImpl->isVolumeUnique()))) || mSculptChanged)
+
+
+ if ((LLPrimitive::setVolume(volume_params, lod, (mVolumeImpl && mVolumeImpl->isVolumeUnique()))) || mSculptChanged)
{
mFaceMappingChanged = TRUE;
if (mVolumeImpl)
{
- mVolumeImpl->onSetVolume(volume_params, detail);
+ mVolumeImpl->onSetVolume(volume_params, mLOD);
}
if (isSculpted())
{
- mSculptTexture = LLViewerTextureManager::getFetchedTexture(volume_params.getSculptID(), TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
- if (mSculptTexture.notNull())
+ // if it's a mesh
+ if ((volume_params.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH)
{
- //ignore sculpt GL usage since bao fixed this in a separate branch
- if (!gGLActive)
- {
- gGLActive = TRUE;
- sculpt();
- gGLActive = FALSE;
+ if (getVolume()->getNumVolumeFaces() == 0 || getVolume()->isTetrahedron())
+ {
+ //load request not yet issued, request pipeline load this mesh
+ LLUUID asset_id = volume_params.getSculptID();
+ S32 available_lod = gMeshRepo.loadMesh(this, asset_id, lod);
+ if (available_lod != lod)
+ {
+ LLPrimitive::setVolume(volume_params, available_lod);
+ }
}
- else
+ }
+ else // otherwise is sculptie
+ {
+ mSculptTexture = LLViewerTextureManager::getFetchedTexture(volume_params.getSculptID(), TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+
+ if (mSculptTexture.notNull())
{
- sculpt();
+ //ignore sculpt GL usage since bao fixed this in a separate branch
+ if (!gGLActive)
+ {
+ gGLActive = TRUE;
+ sculpt();
+ gGLActive = FALSE;
+ }
+ else
+ {
+ sculpt();
+ }
}
}
}
@@ -929,6 +986,15 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &volume_params, const S32 detail
return FALSE;
}
+
+
+void LLVOVolume::notifyMeshLoaded()
+{
+ mSculptChanged = TRUE;
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY, TRUE);
+ dirtySpatialGroup(TRUE);
+}
+
// sculpt replaces generate() for sculpted surfaces
void LLVOVolume::sculpt()
{
@@ -1103,6 +1169,11 @@ void LLVOVolume::updateFaceFlags()
for (S32 i = 0; i < getVolume()->getNumFaces(); i++)
{
LLFace *face = mDrawable->getFace(i);
+ if (!face)
+ {
+ return;
+ }
+
BOOL fullbright = getTE(i)->getFullbright();
face->clearState(LLFace::FULLBRIGHT | LLFace::HUD_RENDER | LLFace::LIGHT);
@@ -1189,6 +1260,10 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global)
for (S32 i = 0; i < getVolume()->getNumFaces(); i++)
{
LLFace *face = mDrawable->getFace(i);
+ if (!face)
+ {
+ continue;
+ }
res &= face->genVolumeBBoxes(*getVolume(), i,
mRelativeXform, mRelativeXformInvTrans,
(mVolumeImpl && mVolumeImpl->isVolumeGlobal()) || force_global);
@@ -2456,6 +2531,23 @@ BOOL LLVOVolume::isSculpted() const
return FALSE;
}
+BOOL LLVOVolume::isMesh() const
+{
+ if (isSculpted())
+ {
+ LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+ U8 sculpt_type = sculpt_params->getSculptType();
+
+ if ((sculpt_type & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH)
+ // mesh is a mesh
+ {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
BOOL LLVOVolume::hasLightTexture() const
{
if (getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE))
@@ -2791,6 +2883,30 @@ F32 LLVOVolume::getBinRadius()
{
F32 radius;
+ F32 scale = 1.f;
+
+ if (isSculpted())
+ {
+ LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+ LLUUID id = sculpt_params->getSculptTexture();
+ U8 sculpt_type = sculpt_params->getSculptType();
+
+ if ((sculpt_type & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH)
+ // mesh is a mesh
+ {
+ LLVolume* volume = getVolume();
+ U32 vert_count = 0;
+
+ for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
+ {
+ const LLVolumeFace& face = volume->getVolumeFace(i);
+ vert_count += face.mVertices.size();
+ }
+
+ scale = 1.f/llmax(vert_count/1024.f, 1.f);
+ }
+ }
+
const LLVector3* ext = mDrawable->getSpatialExtents();
BOOL shrink_wrap = mDrawable->isAnimating();
@@ -2849,7 +2965,7 @@ F32 LLVOVolume::getBinRadius()
radius = 8.f;
}
- return llclamp(radius, 0.5f, 256.f);
+ return llclamp(radius*scale, 0.5f, 256.f);
}
const LLVector3 LLVOVolume::getPivotPositionAgent() const
@@ -3441,6 +3557,11 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
face->getGeometryVolume(*volume, face->getTEOffset(),
vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex());
}
+
+ if (!face)
+ {
+ llerrs << "WTF?" << llendl;
+ }
}
drawablep->clearState(LLDrawable::REBUILD_ALL);
@@ -3725,7 +3846,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
}
else
{
- if (LLPipeline::sRenderDeferred && te->getBumpmap())
+ if (LLPipeline::sRenderDeferred && LLPipeline::sRenderBump && te->getBumpmap())
{
registerFace(group, facep, LLRenderPass::PASS_BUMP);
}
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index a287d34402..e414d9da4d 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -182,6 +182,11 @@ public:
/*virtual*/ BOOL setVolume(const LLVolumeParams &volume_params, const S32 detail, bool unique_volume = false);
void sculpt();
+ static void rebuildMeshAssetCallback(LLVFS *vfs,
+ const LLUUID& asset_uuid,
+ LLAssetType::EType type,
+ void* user_data, S32 status, LLExtStat ext_status);
+
void updateRelativeXform();
/*virtual*/ BOOL updateGeometry(LLDrawable *drawable);
/*virtual*/ void updateFaceSize(S32 idx);
@@ -227,6 +232,7 @@ public:
U32 getVolumeInterfaceID() const;
virtual BOOL isFlexible() const;
virtual BOOL isSculpted() const;
+ virtual BOOL isMesh() const;
virtual BOOL hasLightTexture() const;
BOOL isVolumeGlobal() const;
@@ -251,6 +257,7 @@ public:
void mediaNavigated(LLViewerMediaImpl *impl, LLPluginClassMedia* plugin, std::string new_location);
void mediaEvent(LLViewerMediaImpl *impl, LLPluginClassMedia* plugin, LLViewerMediaObserver::EMediaEvent event);
+
// Sync the given media data with the impl and the given te
void syncMediaData(S32 te, const LLSD &media_data, bool merge, bool ignore_agent);
@@ -266,9 +273,11 @@ public:
LLVector3 getApproximateFaceNormal(U8 face_id);
+ void notifyMeshLoaded();
+
// Returns 'true' iff the media data for this object is in flight
bool isMediaDataBeingFetched() const;
-
+
// Returns the "last fetched" media version, or -1 if not fetched yet
S32 getLastFetchedMediaVersion() const { return mLastFetchedMediaVersion; }
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index 118d7f8d08..feab6d126b 100644
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -1024,9 +1024,11 @@ void LLWorld::disconnectRegions()
}
}
+static LLFastTimer::DeclareTimer FTM_ENABLE_SIMULATOR("Enable Sim");
void process_enable_simulator(LLMessageSystem *msg, void **user_data)
{
+ LLFastTimer t(FTM_ENABLE_SIMULATOR);
// enable the appropriate circuit for this simulator and
// add its values into the gSimulator structure
U64 handle;
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 73b5222ee3..224e267d17 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -70,6 +70,7 @@
#include "llgldbg.h"
#include "llhudmanager.h"
#include "lllightconstants.h"
+#include "llmeshrepository.h"
#include "llresmgr.h"
#include "llselectmgr.h"
#include "llsky.h"
@@ -103,6 +104,7 @@
#include "llspatialpartition.h"
#include "llmutelist.h"
#include "lltoolpie.h"
+#include "llcurl.h"
#ifdef _DEBUG
@@ -1141,9 +1143,15 @@ void LLPipeline::allocDrawable(LLViewerObject *vobj)
}
+static LLFastTimer::DeclareTimer FTM_UNLINK("Unlink");
+static LLFastTimer::DeclareTimer FTM_REMOVE_FROM_MOVE_LIST("Movelist");
+static LLFastTimer::DeclareTimer FTM_REMOVE_FROM_SPATIAL_PARTITION("Spatial Partition");
+static LLFastTimer::DeclareTimer FTM_REMOVE_FROM_LIGHT_SET("Light Set");
+static LLFastTimer::DeclareTimer FTM_REMOVE_FROM_HIGHLIGHT_SET("Highlight Set");
+
void LLPipeline::unlinkDrawable(LLDrawable *drawable)
{
- LLFastTimer t(FTM_PIPELINE);
+ LLFastTimer t(FTM_UNLINK);
assertInitialized();
@@ -1152,6 +1160,7 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable)
// Based on flags, remove the drawable from the queues that it's on.
if (drawablep->isState(LLDrawable::ON_MOVE_LIST))
{
+ LLFastTimer t(FTM_REMOVE_FROM_MOVE_LIST);
LLDrawable::drawable_vector_t::iterator iter = std::find(mMovedList.begin(), mMovedList.end(), drawablep);
if (iter != mMovedList.end())
{
@@ -1161,6 +1170,7 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable)
if (drawablep->getSpatialGroup())
{
+ LLFastTimer t(FTM_REMOVE_FROM_SPATIAL_PARTITION);
if (!drawablep->getSpatialGroup()->mSpatialPartition->remove(drawablep, drawablep->getSpatialGroup()))
{
#ifdef LL_RELEASE_FOR_DOWNLOAD
@@ -1171,18 +1181,23 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable)
}
}
- mLights.erase(drawablep);
- for (light_set_t::iterator iter = mNearbyLights.begin();
- iter != mNearbyLights.end(); iter++)
{
- if (iter->drawable == drawablep)
+ LLFastTimer t(FTM_REMOVE_FROM_LIGHT_SET);
+ mLights.erase(drawablep);
+
+ for (light_set_t::iterator iter = mNearbyLights.begin();
+ iter != mNearbyLights.end(); iter++)
{
- mNearbyLights.erase(iter);
- break;
+ if (iter->drawable == drawablep)
+ {
+ mNearbyLights.erase(iter);
+ break;
+ }
}
}
{
+ LLFastTimer t(FTM_REMOVE_FROM_HIGHLIGHT_SET);
HighlightItem item(drawablep);
mHighlightSet.erase(item);
@@ -1796,6 +1811,8 @@ void LLPipeline::rebuildPriorityGroups()
assertInitialized();
+ gMeshRepo.notifyLoadedMeshes();
+
// Iterate through all drawables on the priority build queue,
for (LLSpatialGroup::sg_list_t::iterator iter = mGroupQ1.begin();
iter != mGroupQ1.end(); ++iter)
@@ -1806,6 +1823,7 @@ void LLPipeline::rebuildPriorityGroups()
}
mGroupQ1.clear();
+
}
void LLPipeline::rebuildGroups()
@@ -3424,27 +3442,14 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
gGLLastMatrix = NULL;
glLoadMatrixd(gGLModelView);
- renderHighlights();
- mHighlightFaces.clear();
-
- renderDebug();
-
- LLVertexBuffer::unbind();
-
- if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
- {
- // Render debugging beacons.
- gObjectList.renderObjectBeacons();
- LLHUDObject::renderAll();
- gObjectList.resetObjectBeacons();
- }
-
if (occlude)
{
occlude = FALSE;
gGLLastMatrix = NULL;
glLoadMatrixd(gGLModelView);
doOcclusion(camera);
+ gGLLastMatrix = NULL;
+ glLoadMatrixd(gGLModelView);
}
}
@@ -5842,6 +5847,12 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
gGL.getTexUnit(0)->activate();
gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
+
+ if (LLRenderTarget::sUseFBO)
+ { //copy depth buffer from mScreen to framebuffer
+ LLRenderTarget::copyContentsToFramebuffer(mScreen, 0, 0, mScreen.getWidth(), mScreen.getHeight(),
+ 0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
+ }
}
@@ -6919,6 +6930,24 @@ void LLPipeline::renderDeferredLighting()
mRenderTypeMask = render_mask;
}
+ {
+ //render highlights, etc.
+ renderHighlights();
+ mHighlightFaces.clear();
+
+ renderDebug();
+
+ LLVertexBuffer::unbind();
+
+ if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
+ {
+ // Render debugging beacons.
+ gObjectList.renderObjectBeacons();
+ LLHUDObject::renderAll();
+ gObjectList.resetObjectBeacons();
+ }
+ }
+
mScreen.flush();
}
@@ -7267,7 +7296,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
LLGLDisable cull(GL_CULL_FACE);
updateCull(camera, ref_result, 1);
stateSort(camera, ref_result);
- }
+ }
ref_mask = mRenderTypeMask;
mRenderTypeMask = mask;
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 67004a5f2d..0b040acf51 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -58,6 +58,8 @@ class LLCubeMap;
class LLCullResult;
class LLVOAvatar;
class LLGLSLShader;
+class LLCurlRequest;
+class LLMeshResponder;
typedef enum e_avatar_skinning_method
{
@@ -675,6 +677,13 @@ public:
protected:
std::vector<LLFace*> mSelectedFaces;
+
+ typedef std::map<LLUUID, std::set<LLUUID> > mesh_load_map;
+ mesh_load_map mLoadingMeshes[4];
+
+ typedef std::list<LLMeshResponder*> mesh_response_list;
+ mesh_response_list mMeshResponseList;
+
LLPointer<LLViewerFetchedTexture> mFaceSelectImagep;
LLPointer<LLViewerTexture> mBloomImagep;
LLPointer<LLViewerTexture> mBloomImage2p;
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 0317d55768..35dafe1311 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -237,6 +237,7 @@ with the same filename but different name
<texture name="Inv_LookFolderOpen" file_name="icons/Inv_LookFolderOpen.png" preload="false" />
<texture name="Inv_LookFolderClosed" file_name="icons/Inv_LookFolderClosed.png" preload="false" />
<texture name="Inv_Landmark" file_name="icons/Inv_Landmark.png" preload="false" />
+ <texture name="Inv_Mesh" file_name="icons/Inv_Mesh.png" preload="false" />
<texture name="Inv_Notecard" file_name="icons/Inv_Notecard.png" preload="false" />
<texture name="Inv_Object" file_name="icons/Inv_Object.png" preload="false" />
<texture name="Inv_Pants" file_name="icons/Inv_Pants.png" preload="false" />
@@ -741,6 +742,8 @@ with the same filename but different name
<texture name="icon_popular.tga" />
<texture name="icon_top_pick.tga" />
+ <texture name="inv_folder_mesh.tga"/>
+ <texture name="inv_item_mesh.tga"/>
<texture name="lag_status_critical.tga" />
<texture name="lag_status_good.tga" />
<texture name="lag_status_warning.tga" />
diff --git a/indra/newview/skins/default/xui/en/floater_about.xml b/indra/newview/skins/default/xui/en/floater_about.xml
index 2ff99dcf5a..056d08e6da 100644
--- a/indra/newview/skins/default/xui/en/floater_about.xml
+++ b/indra/newview/skins/default/xui/en/floater_about.xml
@@ -144,17 +144,20 @@ It is a rare mind indeed that can render the hitherto non-existent blindingly ob
word_wrap="true">
3Dconnexion SDK Copyright (C) 1992-2007 3Dconnexion
APR Copyright (C) 2000-2004 The Apache Software Foundation
+ Collada DOM Copyright 2005 Sony Computer Entertainment Inc.
cURL Copyright (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se)
DBus/dbus-glib Copyright (C) 2002, 2003 CodeFactory AB / Copyright (C) 2003, 2004 Red Hat, Inc.
expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd.
FreeType Copyright (C) 1996-2002, The FreeType Project (www.freetype.org).
GL Copyright (C) 1999-2004 Brian Paul.
+ GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University and David Luebke, Brenden Schubert, University of Virginia.
google-perftools Copyright (c) 2005, Google Inc.
Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited.
jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW)
jpeglib Copyright (C) 1991-1998, Thomas G. Lane.
ogg/vorbis Copyright (C) 2001, Xiphophorus
OpenSSL Copyright (C) 1998-2002 The OpenSSL Project.
+ PCRE Copyright (c) 1997-2008 University of Cambridge
Pth Copyright (C) 1999-2006 Ralf S. Engelschall &lt;rse@gnu.org&gt;
SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
diff --git a/indra/newview/skins/default/xui/en/floater_inventory.xml b/indra/newview/skins/default/xui/en/floater_inventory.xml
index ff9f0daee6..4434f5b421 100644
--- a/indra/newview/skins/default/xui/en/floater_inventory.xml
+++ b/indra/newview/skins/default/xui/en/floater_inventory.xml
@@ -41,4 +41,25 @@
name="Inventory Panel"
top="15"
width="467" />
+ <menu_item_call
+ label="Model (L$[COST])..."
+ layout="topleft"
+ name="Upload Model">
+ <menu_item_call.on_click
+ function="File.UploadModel"
+ parameter="" />
+ <menu_item_call.on_enable
+ function="File.EnableUpload" />
+ </menu_item_call>
+ <menu_item_call
+ label="Scene..."
+ layout="topleft"
+ name="Upload Scene">
+ <menu_item_call.on_click
+ function="File.UploadScene"
+ parameter="" />
+ <menu_item_call.on_enable
+ function="File.EnableUpload" />
+ </menu_item_call>
+ <menu_item_call
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml
index 90fee857fb..388825d31a 100644
--- a/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml
+++ b/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml
@@ -104,6 +104,23 @@
width="16" />
<check_box
height="16"
+ label="Meshes"
+ layout="topleft"
+ left_pad="2"
+ name="check_mesh"
+ top_delta="0"
+ width="126" />
+ <icon
+ height="16"
+ image_name="Inv_Mesh"
+ layout="topleft"
+ left="8"
+ mouse_opaque="true"
+ name="icon_mesh"
+ top="142"
+ width="16" />
+ <check_box
+ height="16"
label="Notecards"
layout="topleft"
left_pad="2"
@@ -117,7 +134,7 @@
left="8"
mouse_opaque="true"
name="icon_object"
- top="142"
+ top="162"
width="16" />
<check_box
height="16"
@@ -134,7 +151,7 @@
left="8"
mouse_opaque="true"
name="icon_script"
- top="162"
+ top="182"
width="16" />
<check_box
height="16"
@@ -151,7 +168,7 @@
left="8"
mouse_opaque="true"
name="icon_sound"
- top="182"
+ top="202"
width="16" />
<check_box
height="16"
@@ -168,7 +185,7 @@
left="8"
mouse_opaque="true"
name="icon_texture"
- top="202"
+ top="222"
width="16" />
<check_box
height="16"
@@ -185,7 +202,7 @@
left="8"
mouse_opaque="true"
name="icon_snapshot"
- top="222"
+ top="242"
width="16" />
<check_box
height="16"
@@ -203,7 +220,7 @@
layout="topleft"
left="8"
name="All"
- top="242"
+ top="262"
width="100" />
<button
follows="left|top"
diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml
index f2a5d902e7..6cc52cfdd2 100644
--- a/indra/newview/skins/default/xui/en/floater_tools.xml
+++ b/indra/newview/skins/default/xui/en/floater_tools.xml
@@ -1990,6 +1990,9 @@ even though the user gets a free copy.
label="Cylinder"
name="Cylinder"
value="Cylinder" />
+ <combo_box.item
+ label="Mesh"
+ value="Mesh" />
</combo_box>
</panel>
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 0891afaf76..319930c2e9 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -2515,10 +2515,10 @@
name="Fast Alpha">
<menu_item_check.on_check
function="CheckControl"
- parameter="RenderDebugGL" />
+ parameter="RenderFastAlpha" />
<menu_item_check.on_click
function="ToggleControl"
- parameter="RenderDebugGL" />
+ parameter="RenderFastAlpha" />
</menu_item_check>
<menu_item_check
label="Animation Textures"
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index bcf006f1a0..c8f4621d8a 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -5773,7 +5773,7 @@ Attachment has been saved.
Unable to find the help topic for this element.
</notification>
- <notification
+ <notification
icon="alertmodal.tga"
name="ObjectMediaFailure"
type="alertmodal">
@@ -5803,6 +5803,17 @@ Your voice has been muted by moderator.
name="okbutton"
yestext="OK"/>
</notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="UploadCostConfirmation"
+ type="alertmodal">
+This upload will cost L$[PRICE], do you wish to continue with the upload?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="Upload"/>
+ </notification>
<notification
icon="alertmodal.tga"
diff --git a/indra/newview/skins/default/xui/en/panel_main_inventory.xml b/indra/newview/skins/default/xui/en/panel_main_inventory.xml
index 4353b306cd..c7353f62c1 100644
--- a/indra/newview/skins/default/xui/en/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/en/panel_main_inventory.xml
@@ -65,7 +65,7 @@ halign="center"
height="30"
layout="bottomleft"
left="0"
- visible="true"
+ visible="true"
name="bottom_panel"
width="330">
<button
@@ -116,7 +116,7 @@ halign="center"
mouse_opaque="false"
name="Inventory Menu"
top="0"
- visible="true"
+ visible="true"
width="290">
<menu
height="101"
@@ -174,6 +174,26 @@ halign="center"
function="File.EnableUpload" />
</menu_item_call>
<menu_item_call
+ label="Model (L$[COST])..."
+ layout="topleft"
+ name="Upload Model">
+ <menu_item_call.on_click
+ function="File.UploadModel"
+ parameter="" />
+ <menu_item_call.on_enable
+ function="File.EnableUpload" />
+ </menu_item_call>
+ <menu_item_call
+ label="Scene..."
+ layout="topleft"
+ name="Upload Scene">
+ <menu_item_call.on_click
+ function="File.UploadScene"
+ parameter="" />
+ <menu_item_call.on_enable
+ function="File.EnableUpload" />
+ </menu_item_call>
+ <menu_item_call
label="Bulk (L$[COST] per file)..."
layout="topleft"
name="Bulk Upload">
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index ec4723bd55..d8c7bde383 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -1878,6 +1878,7 @@ this texture in your inventory
<string name="InvFolder favorite">Favorites</string>
<string name="InvFolder Current Outfit">Current Outfit</string>
<string name="InvFolder My Outfits">My Outfits</string>
+ <string name="InvFolder Meshes">Meshes</string>
<!-- are used for Friends and Friends/All folders in Inventory "Calling cards" folder. See EXT-694-->
<string name="InvFolder Friends">Friends</string>
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index d69a771bbb..16a83de108 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -319,9 +319,15 @@ class WindowsManifest(ViewerManifest):
# For using FMOD for sound... DJS
self.path("fmod.dll")
+
+ # For automatic level of detail generation in mesh importer
+ self.path("glod.dll")
+
+ # For reading collada files
+ self.path("libcollada14dom21.dll")
self.enable_no_crt_manifest_check()
-
+
# Media plugins - QuickTime
if self.prefix(src='../media_plugins/quicktime/%s' % self.args['configuration'], dst="llplugin"):
self.path("media_plugin_quicktime.dll")