summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rwxr-xr-xindra/newview/CMakeLists.txt2
-rwxr-xr-xindra/newview/app_settings/settings.xml33
-rw-r--r--[-rwxr-xr-x]indra/newview/llcallbacklist.cpp0
-rwxr-xr-xindra/newview/llcallbacklist.h72
-rwxr-xr-xindra/newview/llcommandhandler.cpp12
-rwxr-xr-xindra/newview/lldrawpoolavatar.cpp8
-rwxr-xr-xindra/newview/llmeshrepository.cpp375
-rwxr-xr-xindra/newview/llmeshrepository.h50
-rwxr-xr-xindra/newview/llvovolume.cpp4
-rwxr-xr-xindra/newview/skins/default/xui/en/floater_model_preview.xml38
10 files changed, 329 insertions, 265 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 536c7740bb..16877c345e 100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -140,7 +140,6 @@ set(viewer_SOURCE_FILES
llbreadcrumbview.cpp
llbrowsernotification.cpp
llbuycurrencyhtml.cpp
- llcallbacklist.cpp
llcallingcard.cpp
llcapabilitylistener.cpp
llcaphttpsender.cpp
@@ -756,7 +755,6 @@ set(viewer_HEADER_FILES
llbox.h
llbreadcrumbview.h
llbuycurrencyhtml.h
- llcallbacklist.h
llcallingcard.h
llcapabilitylistener.h
llcapabilityprovider.h
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 96fbc8323b..f05836742a 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -2,6 +2,39 @@
<llsd xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="llsd.xsd">
<map>
+ <key>ImporterDebug</key>
+ <map>
+ <key>Comment</key>
+ <string>Enable debug output to more precisely identify sources of import errors. Warning: the output can slow down import on many machines.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>ImporterLegacyMatching</key>
+ <map>
+ <key>Comment</key>
+ <string>Enable index based model matching.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>ImporterModelLimit</key>
+ <map>
+ <key>Comment</key>
+ <string>Limits amount of importer generated models for dae files</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <integer>768</integer>
+ </map>
<key>IMShowTime</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/llcallbacklist.cpp b/indra/newview/llcallbacklist.cpp
index 59ecbdd0ea..59ecbdd0ea 100755..100644
--- a/indra/newview/llcallbacklist.cpp
+++ b/indra/newview/llcallbacklist.cpp
diff --git a/indra/newview/llcallbacklist.h b/indra/newview/llcallbacklist.h
deleted file mode 100755
index 0516c9cdb4..0000000000
--- a/indra/newview/llcallbacklist.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * @file llcallbacklist.h
- * @brief A simple list of callback functions to call.
- *
- * $LicenseInfo:firstyear=2001&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLCALLBACKLIST_H
-#define LL_LLCALLBACKLIST_H
-
-#include "llstl.h"
-
-class LLCallbackList
-{
-public:
- typedef void (*callback_t)(void*);
-
- LLCallbackList();
- ~LLCallbackList();
-
- void addFunction( callback_t func, void *data = NULL ); // register a callback, which will be called as func(data)
- BOOL containsFunction( callback_t func, void *data = NULL ); // true if list already contains the function/data pair
- BOOL deleteFunction( callback_t func, void *data = NULL ); // removes the first instance of this function/data pair from the list, false if not found
- void callFunctions(); // calls all functions
- void deleteAllFunctions();
-
- static void test();
-
-protected:
- // Use a list so that the callbacks are ordered in case that matters
- typedef std::pair<callback_t,void*> callback_pair_t;
- typedef std::list<callback_pair_t > callback_list_t;
- callback_list_t mCallbackList;
-};
-
-typedef boost::function<void ()> nullary_func_t;
-typedef boost::function<bool ()> bool_func_t;
-
-// Call a given callable once in idle loop.
-void doOnIdleOneTime(nullary_func_t callable);
-
-// Repeatedly call a callable in idle loop until it returns true.
-void doOnIdleRepeating(bool_func_t callable);
-
-// Call a given callable once after specified interval.
-void doAfterInterval(nullary_func_t callable, F32 seconds);
-
-// Call a given callable every specified number of seconds, until it returns true.
-void doPeriodically(bool_func_t callable, F32 seconds);
-
-extern LLCallbackList gIdleCallbacks;
-
-#endif
diff --git a/indra/newview/llcommandhandler.cpp b/indra/newview/llcommandhandler.cpp
index 19dba3f917..5ea7efc045 100755
--- a/indra/newview/llcommandhandler.cpp
+++ b/indra/newview/llcommandhandler.cpp
@@ -30,6 +30,7 @@
#include "llcommandhandler.h"
#include "llnotificationsutil.h"
#include "llcommanddispatcherlistener.h"
+#include "llstartup.h"
#include "stringize.h"
// system includes
@@ -116,7 +117,11 @@ bool LLCommandHandlerRegistry::dispatch(const std::string& cmd,
LL_WARNS_ONCE("SLURL") << "Blocked SLURL command from untrusted browser" << LL_ENDL;
if (! slurl_blocked)
{
- LLNotificationsUtil::add("BlockedSLURL");
+ if (LLStartUp::getStartupState() >= STATE_BROWSER_INIT)
+ {
+ // Note: commands can arrive before we initialize everything we need for Notification.
+ LLNotificationsUtil::add("BlockedSLURL");
+ }
slurl_blocked = true;
}
return true;
@@ -138,7 +143,10 @@ bool LLCommandHandlerRegistry::dispatch(const std::string& cmd,
LL_WARNS_ONCE("SLURL") << "Throttled SLURL command from untrusted browser" << LL_ENDL;
if (! slurl_throttled)
{
- LLNotificationsUtil::add("ThrottledSLURL");
+ if (LLStartUp::getStartupState() >= STATE_BROWSER_INIT)
+ {
+ LLNotificationsUtil::add("ThrottledSLURL");
+ }
slurl_throttled = true;
}
return true;
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 821d58a9b2..f828b56f7f 100755
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -1600,6 +1600,14 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*
for (U32 j = 0; j < count; ++j)
{
LLJoint* joint = avatar->getJoint(skin->mJointNames[j]);
+ if (!joint)
+ {
+ joint = avatar->getJoint("mPelvis");
+ }
+ if (!joint)
+ {
+ LL_DEBUGS("Avatar") << "Failed to find " << skin->mJointNames[j] << LL_ENDL;
+ }
if (joint)
{
mat[j] = skin->mInvBindMatrix[j];
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 9a0bd9d1bc..55b94aa141 100755
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -493,6 +493,12 @@ void get_vertex_buffer_from_mesh(LLCDMeshData& mesh, LLModel::PhysicsMesh& res,
}
}
+LLViewerFetchedTexture* LLMeshUploadThread::FindViewerTexture(const LLImportMaterial& material)
+{
+ LLPointer< LLViewerFetchedTexture > * ppTex = static_cast< LLPointer< LLViewerFetchedTexture > * >(material.mOpaqueData);
+ return ppTex ? (*ppTex).get() : NULL;
+}
+
volatile S32 LLMeshRepoThread::sActiveHeaderRequests = 0;
volatile S32 LLMeshRepoThread::sActiveLODRequests = 0;
U32 LLMeshRepoThread::sMaxConcurrentRequests = 1;
@@ -587,16 +593,16 @@ public:
LLMeshLODHandler(const LLVolumeParams & mesh_params, S32 lod, U32 offset, U32 requested_bytes)
: LLMeshHandlerBase(offset, requested_bytes),
mLOD(lod)
- {
+ {
mMeshParams = mesh_params;
LLMeshRepoThread::incActiveLODRequests();
}
virtual ~LLMeshLODHandler();
-
+
protected:
LLMeshLODHandler(const LLMeshLODHandler &); // Not defined
void operator=(const LLMeshLODHandler &); // Not defined
-
+
public:
virtual void processData(LLCore::BufferArray * body, S32 body_offset, U8 * data, S32 data_size);
virtual void processFailure(LLCore::HttpStatus status);
@@ -796,7 +802,7 @@ LLMeshRepoThread::LLMeshRepoThread()
mHttpLargePolicyClass = app_core_http.getPolicy(LLAppCoreHttp::AP_LARGE_MESH);
}
-
+
LLMeshRepoThread::~LLMeshRepoThread()
{
LL_INFOS(LOG_MESH) << "Small GETs issued: " << LLMeshRepository::sHTTPRequestCount
@@ -865,16 +871,16 @@ void LLMeshRepoThread::run()
{
break;
}
-
+
if (! mHttpRequestSet.empty())
{
// Dispatch all HttpHandler notifications
mHttpRequest->update(0L);
}
sRequestWaterLevel = mHttpRequestSet.size(); // Stats data update
-
- // NOTE: order of queue processing intentionally favors LOD requests over header requests
+ // NOTE: order of queue processing intentionally favors LOD requests over header requests
+
while (!mLODReqQ.empty() && mHttpRequestSet.size() < sRequestHighWater)
{
if (! mMutex)
@@ -938,7 +944,7 @@ void LLMeshRepoThread::run()
mSkinRequests.erase(iter);
mMutex->unlock();
- if (!fetchMeshSkinInfo(mesh_id))
+ if (! fetchMeshSkinInfo(mesh_id))
{
incomplete.insert(mesh_id);
}
@@ -967,7 +973,7 @@ void LLMeshRepoThread::run()
mDecompositionRequests.erase(iter);
mMutex->unlock();
- if (!fetchMeshDecomposition(mesh_id))
+ if (! fetchMeshDecomposition(mesh_id))
{
incomplete.insert(mesh_id);
}
@@ -993,7 +999,7 @@ void LLMeshRepoThread::run()
mPhysicsShapeRequests.erase(iter);
mMutex->unlock();
- if (!fetchMeshPhysicsShape(mesh_id))
+ if (! fetchMeshPhysicsShape(mesh_id))
{
incomplete.insert(mesh_id);
}
@@ -1219,7 +1225,7 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)
}
++LLMeshRepository::sMeshRequestCount;
- bool ret = true ;
+ bool ret = true;
U32 header_size = mMeshHeaderSize[mesh_id];
if (header_size > 0)
@@ -1267,7 +1273,7 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)
constructUrl(mesh_id, &http_url, &cap_version);
if (!http_url.empty())
- {
+ {
LLMeshSkinInfoHandler * handler = new LLMeshSkinInfoHandler(mesh_id, offset, size);
LLCore::HttpHandle handle = getByteRange(http_url, cap_version, offset, size, handler);
if (LLCORE_HTTP_HANDLE_INVALID == handle)
@@ -1313,7 +1319,7 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)
++LLMeshRepository::sMeshRequestCount;
U32 header_size = mMeshHeaderSize[mesh_id];
- bool ret = true ;
+ bool ret = true;
if (header_size > 0)
{
@@ -1359,9 +1365,9 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)
int cap_version(2);
std::string http_url;
constructUrl(mesh_id, &http_url, &cap_version);
-
+
if (!http_url.empty())
- {
+ {
LLMeshDecompositionHandler * handler = new LLMeshDecompositionHandler(mesh_id, offset, size);
LLCore::HttpHandle handle = getByteRange(http_url, cap_version, offset, size, handler);
if (LLCORE_HTTP_HANDLE_INVALID == handle)
@@ -1407,7 +1413,7 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
++LLMeshRepository::sMeshRequestCount;
U32 header_size = mMeshHeaderSize[mesh_id];
- bool ret = true ;
+ bool ret = true;
if (header_size > 0)
{
@@ -1452,9 +1458,9 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
int cap_version(2);
std::string http_url;
constructUrl(mesh_id, &http_url, &cap_version);
-
+
if (!http_url.empty())
- {
+ {
LLMeshPhysicsShapeHandler * handler = new LLMeshPhysicsShapeHandler(mesh_id, offset, size);
LLCore::HttpHandle handle = getByteRange(http_url, cap_version, offset, size, handler);
if (LLCORE_HTTP_HANDLE_INVALID == handle)
@@ -1543,11 +1549,11 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params)
}
//either cache entry doesn't exist or is corrupt, request header from simulator
- bool retval = true ;
+ bool retval = true;
int cap_version(2);
std::string http_url;
constructUrl(mesh_params.getSculptID(), &http_url, &cap_version);
-
+
if (!http_url.empty())
{
//grab first 4KB if we're going to bother with a fetch. Cache will prevent future fetches if a full mesh fits
@@ -1635,9 +1641,9 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
int cap_version(2);
std::string http_url;
constructUrl(mesh_id, &http_url, &cap_version);
-
+
if (!http_url.empty())
- {
+ {
LLMeshLODHandler * handler = new LLMeshLODHandler(mesh_params, lod, offset, size);
LLCore::HttpHandle handle = getByteRange(http_url, cap_version, offset, size, handler);
if (LLCORE_HTTP_HANDLE_INVALID == handle)
@@ -1909,7 +1915,7 @@ LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data,
mOrigin += gAgent.getAtAxis() * scale.magVec();
- mMeshUploadTimeOut = gSavedSettings.getS32("MeshUploadTimeOut") ;
+ mMeshUploadTimeOut = gSavedSettings.getS32("MeshUploadTimeOut");
mHttpRequest = new LLCore::HttpRequest;
mHttpOptions = new LLCore::HttpOptions;
@@ -1977,14 +1983,14 @@ void LLMeshUploadThread::preStart()
void LLMeshUploadThread::discard()
{
- LLMutexLock lock(mMutex) ;
+ LLMutexLock lock(mMutex);
mDiscarded = true;
}
bool LLMeshUploadThread::isDiscarded() const
{
- LLMutexLock lock(mMutex) ;
- return mDiscarded ;
+ LLMutexLock lock(mMutex);
+ return mDiscarded;
}
void LLMeshUploadThread::run()
@@ -2049,6 +2055,14 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)
{
LLMeshUploadData data;
data.mBaseModel = iter->first;
+
+ if (data.mBaseModel->mSubmodelID)
+ {
+ // These are handled below to insure correct parenting order on creation
+ // due to map walking being based on model address (aka random)
+ continue;
+ }
+
LLModelInstance& first_instance = *(iter->second.begin());
for (S32 i = 0; i < 5; i++)
{
@@ -2086,7 +2100,10 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)
data.mModel[LLModel::LOD_IMPOSTOR],
decomp,
mUploadSkin,
- mUploadJoints);
+ mUploadJoints,
+ FALSE,
+ FALSE,
+ data.mBaseModel->mSubmodelID);
data.mAssetData = ostr.str();
std::string str = ostr.str();
@@ -2120,17 +2137,26 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)
instance_entry["scale"] = ll_sd_from_vector3(scale);
instance_entry["material"] = LL_MCODE_WOOD;
- instance_entry["physics_shape_type"] = (U8)(LLViewerObject::PHYSICS_SHAPE_CONVEX_HULL);
+ instance_entry["physics_shape_type"] = data.mModel[LLModel::LOD_PHYSICS].notNull() ? (U8)(LLViewerObject::PHYSICS_SHAPE_PRIM) : (U8)(LLViewerObject::PHYSICS_SHAPE_CONVEX_HULL);
instance_entry["mesh"] = mesh_index[data.mBaseModel];
instance_entry["face_list"] = LLSD::emptyArray();
- S32 end = llmin((S32)data.mBaseModel->mMaterialList.size(), data.mBaseModel->getNumVolumeFaces()) ;
+ // We want to be able to allow more than 8 materials...
+ //
+ S32 end = llmin((S32)instance.mMaterial.size(), instance.mModel->getNumVolumeFaces()) ;
+
for (S32 face_num = 0; face_num < end; face_num++)
{
LLImportMaterial& material = instance.mMaterial[data.mBaseModel->mMaterialList[face_num]];
LLSD face_entry = LLSD::emptyMap();
- LLViewerFetchedTexture *texture = material.mDiffuseMap.get();
+
+ LLViewerFetchedTexture *texture = NULL;
+
+ if (material.mDiffuseMapFilename.size())
+ {
+ texture = FindViewerTexture(material);
+ }
if ((texture != NULL) &&
(textures.find(texture) == textures.end()))
@@ -2145,9 +2171,171 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)
{
LLPointer<LLImageJ2C> upload_file =
LLViewerTextureList::convertToUploadFile(texture->getSavedRawImage());
+
+ if (!upload_file.isNull() && upload_file->getDataSize())
+ {
+ texture_str.write((const char*) upload_file->getData(), upload_file->getDataSize());
+ }
+ }
+ }
+
+ if (texture != NULL &&
+ mUploadTextures &&
+ texture_index.find(texture) == texture_index.end())
+ {
+ texture_index[texture] = texture_num;
+ std::string str = texture_str.str();
+ res["texture_list"][texture_num] = LLSD::Binary(str.begin(),str.end());
+ texture_num++;
+ }
+
+ // Subset of TextureEntry fields.
+ if (texture != NULL && mUploadTextures)
+ {
+ face_entry["image"] = texture_index[texture];
+ face_entry["scales"] = 1.0;
+ face_entry["scalet"] = 1.0;
+ face_entry["offsets"] = 0.0;
+ face_entry["offsett"] = 0.0;
+ face_entry["imagerot"] = 0.0;
+ }
+ face_entry["diffuse_color"] = ll_sd_from_color4(material.mDiffuseColor);
+ face_entry["fullbright"] = material.mFullbright;
+ instance_entry["face_list"][face_num] = face_entry;
+ }
+
+ res["instance_list"][instance_num] = instance_entry;
+ instance_num++;
+ }
+ }
+
+ for (instance_map::iterator iter = mInstance.begin(); iter != mInstance.end(); ++iter)
+ {
+ LLMeshUploadData data;
+ data.mBaseModel = iter->first;
+
+ if (!data.mBaseModel->mSubmodelID)
+ {
+ // These were handled above already...
+ //
+ continue;
+ }
+
+ LLModelInstance& first_instance = *(iter->second.begin());
+ for (S32 i = 0; i < 5; i++)
+ {
+ data.mModel[i] = first_instance.mLOD[i];
+ }
+
+ if (mesh_index.find(data.mBaseModel) == mesh_index.end())
+ {
+ // Have not seen this model before - create a new mesh_list entry for it.
+ if (model_name.empty())
+ {
+ model_name = data.mBaseModel->getName();
+ }
+
+ if (model_metric.empty())
+ {
+ model_metric = data.mBaseModel->getMetric();
+ }
+
+ std::stringstream ostr;
+
+ LLModel::Decomposition& decomp =
+ data.mModel[LLModel::LOD_PHYSICS].notNull() ?
+ data.mModel[LLModel::LOD_PHYSICS]->mPhysics :
+ data.mBaseModel->mPhysics;
+
+ decomp.mBaseHull = mHullMap[data.mBaseModel];
+
+ LLSD mesh_header = LLModel::writeModel(
+ ostr,
+ data.mModel[LLModel::LOD_PHYSICS],
+ data.mModel[LLModel::LOD_HIGH],
+ data.mModel[LLModel::LOD_MEDIUM],
+ data.mModel[LLModel::LOD_LOW],
+ data.mModel[LLModel::LOD_IMPOSTOR],
+ decomp,
+ mUploadSkin,
+ mUploadJoints,
+ FALSE,
+ FALSE,
+ data.mBaseModel->mSubmodelID);
+
+ data.mAssetData = ostr.str();
+ std::string str = ostr.str();
+
+ res["mesh_list"][mesh_num] = LLSD::Binary(str.begin(),str.end());
+ mesh_index[data.mBaseModel] = mesh_num;
+ mesh_num++;
+ }
+
+ // For all instances that use this model
+ for (instance_list::iterator instance_iter = iter->second.begin();
+ instance_iter != iter->second.end();
+ ++instance_iter)
+ {
+
+ LLModelInstance& instance = *instance_iter;
+
+ LLSD instance_entry;
+
+ for (S32 i = 0; i < 5; i++)
+ {
+ data.mModel[i] = instance.mLOD[i];
+ }
+
+ LLVector3 pos, scale;
+ LLQuaternion rot;
+ LLMatrix4 transformation = instance.mTransform;
+ decomposeMeshMatrix(transformation,pos,rot,scale);
+ instance_entry["position"] = ll_sd_from_vector3(pos);
+ instance_entry["rotation"] = ll_sd_from_quaternion(rot);
+ instance_entry["scale"] = ll_sd_from_vector3(scale);
+
+ instance_entry["material"] = LL_MCODE_WOOD;
+ instance_entry["physics_shape_type"] = (U8)(LLViewerObject::PHYSICS_SHAPE_NONE);
+ instance_entry["mesh"] = mesh_index[data.mBaseModel];
+
+ instance_entry["face_list"] = LLSD::emptyArray();
+
+ // We want to be able to allow more than 8 materials...
+ //
+ S32 end = llmin((S32)instance.mMaterial.size(), instance.mModel->getNumVolumeFaces()) ;
+
+ for (S32 face_num = 0; face_num < end; face_num++)
+ {
+ LLImportMaterial& material = instance.mMaterial[data.mBaseModel->mMaterialList[face_num]];
+ LLSD face_entry = LLSD::emptyMap();
+
+ LLViewerFetchedTexture *texture = NULL;
+
+ if (material.mDiffuseMapFilename.size())
+ {
+ texture = FindViewerTexture(material);
+ }
+
+ if ((texture != NULL) &&
+ (textures.find(texture) == textures.end()))
+ {
+ textures.insert(texture);
+ }
+
+ std::stringstream texture_str;
+ if (texture != NULL && include_textures && mUploadTextures)
+ {
+ if(texture->hasSavedRawImage())
+ {
+ LLPointer<LLImageJ2C> upload_file =
+ LLViewerTextureList::convertToUploadFile(texture->getSavedRawImage());
+
+ if (!upload_file.isNull() && upload_file->getDataSize())
+ {
texture_str.write((const char*) upload_file->getData(), upload_file->getDataSize());
}
}
+ }
if (texture != NULL &&
mUploadTextures &&
@@ -2235,7 +2423,7 @@ void LLMeshUploadThread::generateHulls()
}
}
- if(has_valid_requests)
+ if (has_valid_requests)
{
// *NOTE: Interesting livelock condition on shutdown. If there
// is an upload request in generateHulls() when shutdown starts,
@@ -2340,7 +2528,7 @@ void LLMeshUploadThread::requestWholeModelFee()
else
{
U32 sleep_time(10);
-
+
mHttpRequest->update(0);
while (! LLApp::isQuitting() && ! finished() && ! isDiscarded())
{
@@ -2435,7 +2623,7 @@ void LLMeshUploadThread::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResp
// model fee case
LLWholeModelFeeObserver* observer(mFeeObserverHandle.get());
mWholeModelUploadURL.clear();
-
+
if (! status)
{
LL_WARNS(LOG_MESH) << "Fee request failed. Reason: " << reason
@@ -2465,7 +2653,7 @@ void LLMeshUploadThread::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResp
LLCoreHttpUtil::responseToLLSD(response, true, body);
}
dump_llsd_to_file(body, make_dump_name("whole_model_fee_response_", dump_num));
-
+
if (body["state"].asString() == "upload")
{
mWholeModelUploadURL = body["uploader"].asString();
@@ -2536,7 +2724,7 @@ void LLMeshRepoThread::notifyLoadedMeshes()
LODRequest req = mUnavailableQ.front();
mUnavailableQ.pop();
mMutex->unlock();
-
+
update_metrics = true;
gMeshRepo.notifyMeshUnavailable(req.mMeshParams, req.mLOD);
}
@@ -2672,7 +2860,7 @@ void LLMeshRepository::cacheOutgoingMesh(LLMeshUploadData& data, LLSD& header)
void LLMeshHandlerBase::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response)
{
mProcessed = true;
-
+
unsigned int retries(0U);
response->getRetries(NULL, &retries);
LLMeshRepository::sHTTPRetryCount += retries;
@@ -2728,7 +2916,7 @@ void LLMeshHandlerBase::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRespo
// 200 case, typically
offset = 0;
}
-
+
// *DEBUG: To test validation below
// offset += 1;
@@ -2844,7 +3032,7 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
const std::string & lod_name = header_lod[i];
lod_bytes = llmax(lod_bytes, header[lod_name]["offset"].asInteger()+header[lod_name]["size"].asInteger());
}
-
+
// just in case skin info or decomposition is at the end of the file (which it shouldn't be)
lod_bytes = llmax(lod_bytes, header["skin"]["offset"].asInteger() + header["skin"]["size"].asInteger());
lod_bytes = llmax(lod_bytes, header["physics_convex"]["offset"].asInteger() + header["physics_convex"]["size"].asInteger());
@@ -2852,7 +3040,7 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
S32 header_bytes = (S32) gMeshRepo.mThread->mMeshHeaderSize[mesh_id];
S32 bytes = lod_bytes + header_bytes;
-
+
// It's possible for the remote asset to have more data than is needed for the local cache
// only allocate as much space in the VFS as is needed for the local cache
data_size = llmin(data_size, bytes);
@@ -2864,11 +3052,11 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
++LLMeshRepository::sCacheWrites;
file.write(data, data_size);
-
+
// zero out the rest of the file
U8 block[MESH_HEADER_SIZE];
memset(block, 0, sizeof(block));
-
+
while (bytes-file.tell() > sizeof(block))
{
file.write(block, sizeof(block));
@@ -2894,8 +3082,8 @@ LLMeshLODHandler::~LLMeshLODHandler()
gMeshRepo.mThread->lockAndLoadMeshLOD(mMeshParams, mLOD);
}
LLMeshRepoThread::decActiveLODRequests();
- }
}
+}
void LLMeshLODHandler::processFailure(LLCore::HttpStatus status)
{
@@ -2913,7 +3101,7 @@ void LLMeshLODHandler::processData(LLCore::BufferArray * /* body */, S32 /* body
{
if ((! MESH_LOD_PROCESS_FAILED) && gMeshRepo.mThread->lodReceived(mMeshParams, mLOD, data, data_size))
{
- //good fetch from sim, write to VFS for caching
+ // good fetch from sim, write to VFS for caching
LLVFile file(gVFS, mMeshParams.getSculptID(), LLAssetType::AT_MESH, LLVFile::WRITE);
S32 offset = mOffset;
@@ -2958,7 +3146,7 @@ void LLMeshSkinInfoHandler::processData(LLCore::BufferArray * /* body */, S32 /*
{
if ((! MESH_SKIN_INFO_PROCESS_FAILED) && gMeshRepo.mThread->skinInfoReceived(mMeshID, data, data_size))
{
- //good fetch from sim, write to VFS for caching
+ // good fetch from sim, write to VFS for caching
LLVFile file(gVFS, mMeshID, LLAssetType::AT_MESH, LLVFile::WRITE);
S32 offset = mOffset;
@@ -3282,7 +3470,7 @@ void LLMeshRepository::notifyLoadedMeshes()
REQUEST2_LOW_WATER_MIN,
REQUEST2_LOW_WATER_MAX);
}
-
+
//clean up completed upload threads
for (std::vector<LLMeshUploadThread*>::iterator iter = mUploads.begin(); iter != mUploads.end(); )
{
@@ -3359,7 +3547,7 @@ void LLMeshRepository::notifyLoadedMeshes()
//call completed callbacks on finished decompositions
mDecompThread->notifyCompleted();
-
+
// For major operations, attempt to get the required locks
// without blocking and punt if they're not available. The
// longest run of holdoffs is kept in sMaxLockHoldoffs just
@@ -3378,12 +3566,12 @@ void LLMeshRepository::notifyLoadedMeshes()
return;
}
hold_offs = 0;
-
+
if (gAgent.getRegion())
{
// Update capability urls
static std::string region_name("never name a region this");
-
+
if (gAgent.getRegion()->getName() != region_name && gAgent.getRegion()->capabilitiesReceived())
{
region_name = gAgent.getRegion()->getName();
@@ -3399,7 +3587,7 @@ void LLMeshRepository::notifyLoadedMeshes()
<< LL_ENDL;
}
}
-
+
//popup queued error messages from background threads
while (!mUploadErrorQ.empty())
{
@@ -3754,7 +3942,7 @@ LLSD& LLMeshRepoThread::getMeshHeader(const LLUUID& mesh_id)
void LLMeshRepository::uploadModel(std::vector<LLModelInstance>& data, LLVector3& scale, bool upload_textures,
- bool upload_skin, bool upload_joints, std::string upload_url, bool do_upload,
+ bool upload_skin, bool upload_joints, std::string upload_url, bool do_upload,
LLHandle<LLWholeModelFeeObserver> fee_observer, LLHandle<LLWholeModelUploadObserver> upload_observer)
{
LLMeshUploadThread* thread = new LLMeshUploadThread(data, scale, upload_textures, upload_skin, upload_joints, upload_url,
@@ -3825,37 +4013,6 @@ void LLMeshUploadThread::decomposeMeshMatrix(LLMatrix4& transformation,
result_rot = quat_rotation;
}
-bool LLImportMaterial::operator<(const LLImportMaterial &rhs) const
-{
- if (mDiffuseMap != rhs.mDiffuseMap)
- {
- return mDiffuseMap < rhs.mDiffuseMap;
- }
-
- if (mDiffuseMapFilename != rhs.mDiffuseMapFilename)
- {
- return mDiffuseMapFilename < rhs.mDiffuseMapFilename;
- }
-
- if (mDiffuseMapLabel != rhs.mDiffuseMapLabel)
- {
- return mDiffuseMapLabel < rhs.mDiffuseMapLabel;
- }
-
- if (mDiffuseColor != rhs.mDiffuseColor)
- {
- return mDiffuseColor < rhs.mDiffuseColor;
- }
-
- if (mBinding != rhs.mBinding)
- {
- return mBinding < rhs.mBinding;
- }
-
- return mFullbright < rhs.mFullbright;
-}
-
-
void LLMeshRepository::updateInventory(inventory_data data)
{
LLMutexLock lock(mMeshMutex);
@@ -4253,7 +4410,7 @@ void LLPhysicsDecomp::doDecompositionSingleHull()
setMeshData(mesh, true);
LLCDResult ret = decomp->buildSingleHull() ;
- if(ret)
+ if (ret)
{
LL_WARNS(LOG_MESH) << "Could not execute decomposition stage when attempting to create single hull." << LL_ENDL;
make_box(mCurRequest);
@@ -4441,60 +4598,6 @@ void LLPhysicsDecomp::Request::setStatusMessage(const std::string& msg)
mStatusMessage = msg;
}
-LLModelInstance::LLModelInstance(LLSD& data)
-{
- mLocalMeshID = data["mesh_id"].asInteger();
- mLabel = data["label"].asString();
- mTransform.setValue(data["transform"]);
-
- for (U32 i = 0; i < data["material"].size(); ++i)
- {
- LLImportMaterial mat(data["material"][i]);
- mMaterial[mat.mBinding] = mat;
- }
-}
-
-
-LLSD LLModelInstance::asLLSD()
-{
- LLSD ret;
-
- ret["mesh_id"] = mModel->mLocalID;
- ret["label"] = mLabel;
- ret["transform"] = mTransform.getValue();
-
- U32 i = 0;
- for (std::map<std::string, LLImportMaterial>::iterator iter = mMaterial.begin(); iter != mMaterial.end(); ++iter)
- {
- ret["material"][i++] = iter->second.asLLSD();
- }
-
- return ret;
-}
-
-LLImportMaterial::LLImportMaterial(LLSD& data)
-{
- mDiffuseMapFilename = data["diffuse"]["filename"].asString();
- mDiffuseMapLabel = data["diffuse"]["label"].asString();
- mDiffuseColor.setValue(data["diffuse"]["color"]);
- mFullbright = data["fullbright"].asBoolean();
- mBinding = data["binding"].asString();
-}
-
-
-LLSD LLImportMaterial::asLLSD()
-{
- LLSD ret;
-
- ret["diffuse"]["filename"] = mDiffuseMapFilename;
- ret["diffuse"]["label"] = mDiffuseMapLabel;
- ret["diffuse"]["color"] = mDiffuseColor.getValue();
- ret["fullbright"] = mFullbright;
- ret["binding"] = mBinding;
-
- return ret;
-}
-
void LLMeshRepository::buildPhysicsMesh(LLModel::Decomposition& decomp)
{
decomp.mMesh.resize(decomp.mHull.size());
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index 39280bea3a..688cd01a87 100755
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -90,54 +90,6 @@ public:
}
};
-class LLImportMaterial
-{
-public:
- LLPointer<LLViewerFetchedTexture> mDiffuseMap;
- std::string mDiffuseMapFilename;
- std::string mDiffuseMapLabel;
- std::string mBinding;
- LLColor4 mDiffuseColor;
- bool mFullbright;
-
- bool operator<(const LLImportMaterial &params) const;
-
- LLImportMaterial()
- : mFullbright(false)
- {
- mDiffuseColor.set(1,1,1,1);
- }
-
- LLImportMaterial(LLSD& data);
-
- LLSD asLLSD();
-};
-
-class LLModelInstance
-{
-public:
- LLPointer<LLModel> mModel;
- LLPointer<LLModel> mLOD[5];
-
- std::string mLabel;
-
- LLUUID mMeshID;
- S32 mLocalMeshID;
-
- LLMatrix4 mTransform;
- std::map<std::string, LLImportMaterial> mMaterial;
-
- LLModelInstance(LLModel* model, const std::string& label, LLMatrix4& transform, std::map<std::string, LLImportMaterial>& materials)
- : mModel(model), mLabel(label), mTransform(transform), mMaterial(materials)
- {
- mLocalMeshID = -1;
- }
-
- LLModelInstance(LLSD& data);
-
- LLSD asLLSD();
-};
-
class LLPhysicsDecomp : public LLThread
{
public:
@@ -483,6 +435,8 @@ public:
// Inherited from LLCore::HttpHandler
virtual void onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response);
+ LLViewerFetchedTexture* FindViewerTexture(const LLImportMaterial& material);
+
private:
LLHandle<LLWholeModelFeeObserver> mFeeObserverHandle;
LLHandle<LLWholeModelUploadObserver> mUploadObserverHandle;
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 4b0e4514a0..68713280c0 100755
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -4184,6 +4184,10 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
for (U32 j = 0; j < maxJoints; ++j)
{
LLJoint* joint = avatar->getJoint(skin->mJointNames[j]);
+ if (!joint)
+ {
+ joint = avatar->getJoint("mPelvis");
+ }
if (joint)
{
mat[j] = skin->mInvBindMatrix[j];
diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml
index a4acd1df78..7183b2f1f9 100755
--- a/indra/newview/skins/default/xui/en/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml
@@ -31,6 +31,7 @@
<string name="mesh_status_too_many_vertices">Level of detail has too many vertices.</string>
<string name="mesh_status_missing_lod">Missing required level of detail.</string>
<string name="mesh_status_invalid_material_list">LOD materials are not a subset of reference model.</string>
+ <string name="phys_status_vertex_limit_exceeded">Some physical hulls exceed vertex limitations.</string>
<string name="layer_all">All</string> <!-- Text to display in physics layer combo box for "all layers" -->
<string name="decomposing">Analyzing...</string>
<string name="simplifying">Simplifying...</string>
@@ -66,7 +67,7 @@
follows="top|left"
layout="topleft"
height="19"
- max_length_bytes="64"
+ max_length_bytes="63"
name="description_form"
prevalidate_callback="ascii"
top_pad="5"
@@ -1027,19 +1028,19 @@
bg_alpha_color="0 0 0 0"
bg_opaque_color="0 0 0 0.3"
follows="left|top"
- height="16"
+ height="19"
layout="topleft"
left="18"
name="physics info"
- top_pad="15"
- width="589">
+ top_pad="12"
+ width="319">
<text
follows="top|left"
height="15"
layout="topleft"
left="0"
text_color="White"
- top_pad="0"
+ top_pad="3"
name="results_text"
width="50">
Results:
@@ -1077,6 +1078,33 @@
Hulls: [HULLS]
</text>
</panel>
+ <panel
+ bg_alpha_color="0 0 0 0"
+ bg_opaque_color="0 0 0 0.3"
+ follows="left|top"
+ height="19"
+ layout="topleft"
+ left_pad="5"
+ top_delta="0"
+ name="physics message"
+ width="270">
+ <icon
+ follows="left|top"
+ height="16"
+ left="0"
+ layout="topleft"
+ name="physics_status_message_icon"
+ top_pad="0"
+ width="16" />
+ <text
+ follows="left|top"
+ height="15"
+ layout="topleft"
+ left_pad="2"
+ name="physics_status_message_text"
+ width="252"
+ top_delta="3"/>
+ </panel>
</panel>
<!-- MODIFIERS PANEL -->
<panel