diff options
Diffstat (limited to 'indra')
32 files changed, 1057 insertions, 656 deletions
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 8c81f27784..bddb8d8c66 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -32,6 +32,7 @@ #if !LL_WINDOWS #include <stdint.h> #endif +#include <cmath> #include "llerror.h" #include "llmemtype.h" @@ -2379,11 +2380,16 @@ bool LLVolumeFace::VertexData::operator==(const LLVolumeFace::VertexData& rhs)co bool LLVolumeFace::VertexData::compareNormal(const LLVolumeFace::VertexData& rhs, F32 angle_cutoff) const { bool retval = false; - if (rhs.mData[POSITION].equals3(mData[POSITION]) && rhs.mTexCoord == mTexCoord) + + const F32 epsilon = 0.00001f; + + if (rhs.mData[POSITION].equals3(mData[POSITION], epsilon) && + fabs(rhs.mTexCoord[0]-mTexCoord[0]) < epsilon && + fabs(rhs.mTexCoord[1]-mTexCoord[1]) < epsilon) { if (angle_cutoff > 1.f) { - retval = (mData[NORMAL].equals3(rhs.mData[NORMAL])); + retval = (mData[NORMAL].equals3(rhs.mData[NORMAL], epsilon)); } else { @@ -2499,38 +2505,52 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) } { - U16* n = (U16*) &(norm[0]); - for (U32 j = 0; j < num_verts; ++j) + if (!norm.empty()) { - norm_out->set((F32) n[0], (F32) n[1], (F32) n[2]); - norm_out->div(65535.f); - norm_out->mul(2.f); - norm_out->sub(1.f); - norm_out++; - n += 3; + U16* n = (U16*) &(norm[0]); + for (U32 j = 0; j < num_verts; ++j) + { + norm_out->set((F32) n[0], (F32) n[1], (F32) n[2]); + norm_out->div(65535.f); + norm_out->mul(2.f); + norm_out->sub(1.f); + norm_out++; + n += 3; + } + } + else + { + memset(norm_out, 0, sizeof(LLVector4a)*num_verts); } } { - U16* t = (U16*) &(tc[0]); - for (U32 j = 0; j < num_verts; j+=2) + if (!tc.empty()) { - if (j < num_verts-1) - { - tc_out->set((F32) t[0], (F32) t[1], (F32) t[2], (F32) t[3]); - } - else + U16* t = (U16*) &(tc[0]); + for (U32 j = 0; j < num_verts; j+=2) { - tc_out->set((F32) t[0], (F32) t[1], 0.f, 0.f); - } + if (j < num_verts-1) + { + tc_out->set((F32) t[0], (F32) t[1], (F32) t[2], (F32) t[3]); + } + else + { + tc_out->set((F32) t[0], (F32) t[1], 0.f, 0.f); + } - t += 4; + t += 4; - tc_out->div(65535.f); - tc_out->mul(tc_range); - tc_out->add(min_tc4); + tc_out->div(65535.f); + tc_out->mul(tc_range); + tc_out->add(min_tc4); - tc_out++; + tc_out++; + } + } + else + { + memset(tc_out, 0, sizeof(LLVector2)*num_verts); } } @@ -2656,6 +2676,25 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) min.setMin(min, face.mPositions[i]); max.setMax(max, face.mPositions[i]); } + + if (face.mTexCoords) + { + LLVector2& min_tc = face.mTexCoordExtents[0]; + LLVector2& max_tc = face.mTexCoordExtents[1]; + + min_tc = face.mTexCoords[0]; + max_tc = face.mTexCoords[0]; + + for (U32 j = 1; j < face.mNumVertices; ++j) + { + update_min_max(min_tc, max_tc, face.mTexCoords[j]); + } + } + else + { + face.mTexCoordExtents[0].set(0,0); + face.mTexCoordExtents[1].set(1,1); + } } } } @@ -2735,11 +2774,13 @@ void LLVolume::makeTetrahedron() n[2] = cv[2].getNormal(); n += 3; - tc[0] = cv[0].mTexCoord; - tc[1] = cv[1].mTexCoord; - tc[2] = cv[2].mTexCoord; - tc += 3; - + if(tc) + { + tc[0] = cv[0].mTexCoord; + tc[1] = cv[1].mTexCoord; + tc[2] = cv[2].mTexCoord; + tc += 3; + } //side 2 cv[0].setPosition(p[3]); @@ -2758,11 +2799,14 @@ void LLVolume::makeTetrahedron() n[2] = cv[2].getNormal(); n += 3; - tc[0] = cv[0].mTexCoord; - tc[1] = cv[1].mTexCoord; - tc[2] = cv[2].mTexCoord; - tc += 3; - + if(tc) + { + tc[0] = cv[0].mTexCoord; + tc[1] = cv[1].mTexCoord; + tc[2] = cv[2].mTexCoord; + tc += 3; + } + //side 3 cv[0].setPosition(p[3]); cv[1].setPosition(p[1]); @@ -2780,10 +2824,13 @@ void LLVolume::makeTetrahedron() n[2] = cv[2].getNormal(); n += 3; - tc[0] = cv[0].mTexCoord; - tc[1] = cv[1].mTexCoord; - tc[2] = cv[2].mTexCoord; - tc += 3; + if(tc) + { + tc[0] = cv[0].mTexCoord; + tc[1] = cv[1].mTexCoord; + tc[2] = cv[2].mTexCoord; + tc += 3; + } //side 4 cv[0].setPosition(p[2]); @@ -2802,10 +2849,13 @@ void LLVolume::makeTetrahedron() n[2] = cv[2].getNormal(); n += 3; - tc[0] = cv[0].mTexCoord; - tc[1] = cv[1].mTexCoord; - tc[2] = cv[2].mTexCoord; - tc += 3; + if(tc) + { + tc[0] = cv[0].mTexCoord; + tc[1] = cv[1].mTexCoord; + tc[2] = cv[2].mTexCoord; + tc += 3; + } //set index buffer for (U16 i = 0; i < 12; i++) @@ -5574,7 +5624,16 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src) LLVector4a::memcpyNonAliased16((F32*) mPositions, (F32*) src.mPositions, vert_size); LLVector4a::memcpyNonAliased16((F32*) mNormals, (F32*) src.mNormals, vert_size); - LLVector4a::memcpyNonAliased16((F32*) mTexCoords, (F32*) src.mTexCoords, tc_size); + + if(src.mTexCoords) + { + LLVector4a::memcpyNonAliased16((F32*) mTexCoords, (F32*) src.mTexCoords, tc_size); + } + else + { + ll_aligned_free_16(mTexCoords) ; + mTexCoords = NULL ; + } if (src.mBinormals) @@ -5696,8 +5755,23 @@ BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build) void LLVolumeFace::getVertexData(U16 index, LLVolumeFace::VertexData& cv) { cv.setPosition(mPositions[index]); - cv.setNormal(mNormals[index]); - cv.mTexCoord = mTexCoords[index]; + if (mNormals) + { + cv.setNormal(mNormals[index]); + } + else + { + cv.getNormal().clear(); + } + + if (mTexCoords) + { + cv.mTexCoord = mTexCoords[index]; + } + else + { + cv.mTexCoord.clear(); + } } bool LLVolumeFace::VertexMapData::operator==(const LLVolumeFace::VertexData& rhs) const @@ -5727,7 +5801,10 @@ void LLVolumeFace::optimize(F32 angle_cutoff) LLVolumeFace new_face; //map of points to vector of vertices at that point - VertexMapData::PointMap point_map; + std::map<U64, std::vector<VertexMapData> > point_map; + + LLVector4a range; + range.setSub(mExtents[1],mExtents[0]); //remove redundant vertices for (U32 i = 0; i < mNumIndices; ++i) @@ -5738,7 +5815,19 @@ void LLVolumeFace::optimize(F32 angle_cutoff) getVertexData(index, cv); BOOL found = FALSE; - VertexMapData::PointMap::iterator point_iter = point_map.find(LLVector3(cv.getPosition().getF32ptr())); + + LLVector4a pos; + pos.setSub(mPositions[index], mExtents[0]); + pos.div(range); + + U64 pos64 = 0; + + pos64 = (U16) (pos[0]*65535); + pos64 = pos64 | (((U64) (pos[1]*65535)) << 16); + pos64 = pos64 | (((U64) (pos[2]*65535)) << 32); + + std::map<U64, std::vector<VertexMapData> >::iterator point_iter = point_map.find(pos64); + if (point_iter != point_map.end()) { //duplicate point might exist for (U32 j = 0; j < point_iter->second.size(); ++j) @@ -5770,11 +5859,26 @@ void LLVolumeFace::optimize(F32 angle_cutoff) } else { - point_map[LLVector3(d.getPosition().getF32ptr())].push_back(d); + point_map[pos64].push_back(d); } } } + llassert(new_face.mNumIndices == mNumIndices); + llassert(new_face.mNumVertices <= mNumVertices); + + if (angle_cutoff > 1.f && !mNormals) + { + ll_aligned_free_16(new_face.mNormals); + new_face.mNormals = NULL; + } + + if (!mTexCoords) + { + ll_aligned_free_16(new_face.mTexCoords); + new_face.mTexCoords = NULL; + } + swapData(new_face); } diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index 7c8b7e3584..44330cf8ff 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -244,7 +244,7 @@ public: U32 report(CURLcode); void getTransferInfo(LLCurl::TransferInfo* info); - void prepRequest(const std::string& url, const std::vector<std::string>& headers, ResponderPtr, bool post = false); + void prepRequest(const std::string& url, const std::vector<std::string>& headers, ResponderPtr, S32 time_out = 0, bool post = false); const char* getErrorBuffer(); @@ -525,7 +525,7 @@ size_t curlHeaderCallback(void* data, size_t size, size_t nmemb, void* user_data void LLCurl::Easy::prepRequest(const std::string& url, const std::vector<std::string>& headers, - ResponderPtr responder, bool post) + ResponderPtr responder, S32 time_out, bool post) { resetState(); @@ -558,7 +558,7 @@ void LLCurl::Easy::prepRequest(const std::string& url, //don't verify host name so urls with scrubbed host names will work (improves DNS performance) setopt(CURLOPT_SSL_VERIFYHOST, 0); - setopt(CURLOPT_TIMEOUT, CURL_REQUEST_TIMEOUT); + setopt(CURLOPT_TIMEOUT, llmax(time_out, CURL_REQUEST_TIMEOUT)); setoptString(CURLOPT_URL, url); @@ -855,14 +855,14 @@ bool LLCurlRequest::getByteRange(const std::string& url, bool LLCurlRequest::post(const std::string& url, const headers_t& headers, const LLSD& data, - LLCurl::ResponderPtr responder) + LLCurl::ResponderPtr responder, S32 time_out) { LLCurl::Easy* easy = allocEasy(); if (!easy) { return false; } - easy->prepRequest(url, headers, responder); + easy->prepRequest(url, headers, responder, time_out); LLSDSerialize::toXML(data, easy->getInput()); S32 bytes = easy->getInput().str().length(); @@ -882,14 +882,14 @@ bool LLCurlRequest::post(const std::string& url, bool LLCurlRequest::post(const std::string& url, const headers_t& headers, const std::string& data, - LLCurl::ResponderPtr responder) + LLCurl::ResponderPtr responder, S32 time_out) { LLCurl::Easy* easy = allocEasy(); if (!easy) { return false; } - easy->prepRequest(url, headers, responder); + easy->prepRequest(url, headers, responder, time_out); easy->getInput().write(data.data(), data.size()); S32 bytes = easy->getInput().str().length(); diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h index 4ce3fa1078..5833a27b84 100644 --- a/indra/llmessage/llcurl.h +++ b/indra/llmessage/llcurl.h @@ -201,8 +201,8 @@ public: void get(const std::string& url, LLCurl::ResponderPtr responder); bool getByteRange(const std::string& url, const headers_t& headers, S32 offset, S32 length, LLCurl::ResponderPtr responder); - bool post(const std::string& url, const headers_t& headers, const LLSD& data, LLCurl::ResponderPtr responder); - bool post(const std::string& url, const headers_t& headers, const std::string& data, LLCurl::ResponderPtr responder); + bool post(const std::string& url, const headers_t& headers, const LLSD& data, LLCurl::ResponderPtr responder, S32 time_out = 0); + bool post(const std::string& url, const headers_t& headers, const std::string& data, LLCurl::ResponderPtr responder, S32 time_out = 0); S32 process(); S32 getQueued(); diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 0463d5364b..da78b30b34 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -27,6 +27,7 @@ #include "linden_common.h" #include "llmodel.h" +#include "llmemory.h" #include "llconvexdecomposition.h" #include "llsdserialize.h" #include "llvector4a.h" @@ -71,88 +72,10 @@ LLModel::~LLModel() } } -void load_face_from_dom_inputs(LLVolumeFace& face, const domInputLocalOffset_Array& inputs, U32 min_idx, U32 max_idx) -{ - for (U32 j = 0; j < inputs.getCount(); ++j) - { - if (strcmp(COMMON_PROFILE_INPUT_VERTEX, inputs[j]->getSemantic()) == 0) - { //found vertex array - const domURIFragmentType& uri = inputs[j]->getSource(); - daeElementRef elem = uri.getElement(); - domVertices* vertices = (domVertices*) elem.cast(); - - domInputLocal_Array& v_inp = vertices->getInput_array(); - if (inputs[j]->getOffset() != 0) - { - llerrs << "Vertex array offset MUST be zero." << llendl; - } - - for (U32 k = 0; k < v_inp.getCount(); ++k) - { - if (strcmp(COMMON_PROFILE_INPUT_POSITION, v_inp[k]->getSemantic()) == 0) - { - const domURIFragmentType& uri = v_inp[k]->getSource(); - - daeElementRef elem = uri.getElement(); - domSource* src = (domSource*) elem.cast(); - - if (src->getTechnique_common()->getAccessor()->getStride() != 3) - { - llerrs << "Vertex array stride MUST be three." << llendl; - } - - domListOfFloats& v = src->getFloat_array()->getValue(); - - LLVector4a min; - min.set(v[min_idx], v[min_idx+1], v[min_idx+2]); - LLVector4a max = min; - - for (U32 j = min_idx; j <= max_idx; ++j) - { //copy vertex array - face.mPositions[j-min_idx].set(v[j*3+0], v[j*3+1], v[j*3+2]); - update_min_max(min, max, face.mPositions[j-min_idx]); - } - - face.mExtents[0] = min; - face.mExtents[1] = max; - } - } - } - - if (strcmp(COMMON_PROFILE_INPUT_NORMAL, inputs[j]->getSemantic()) == 0) - { - //found normal array for this triangle list - const domURIFragmentType& uri = inputs[j]->getSource(); - daeElementRef elem = uri.getElement(); - domSource* src = (domSource*) elem.cast(); - domListOfFloats& n = src->getFloat_array()->getValue(); - - for (U32 j = min_idx; j <= max_idx; ++j) - { - LLVector4a* norm = (LLVector4a*) face.mNormals + (j-min_idx); - norm->set(n[j*3+0], n[j*3+1], n[j*3+2]); - norm->normalize3(); - } - } - else if (strcmp(COMMON_PROFILE_INPUT_TEXCOORD, inputs[j]->getSemantic()) == 0) - { //found texCoords - const domURIFragmentType& uri = inputs[j]->getSource(); - daeElementRef elem = uri.getElement(); - domSource* src = (domSource*) elem.cast(); - domListOfFloats& u = src->getFloat_array()->getValue(); - - for (U32 j = min_idx; j <= max_idx; ++j) - { - face.mTexCoords[j-min_idx].setVec(u[j*2+0], u[j*2+1]); - } - } - } -} bool get_dom_sources(const domInputLocalOffset_Array& inputs, S32& pos_offset, S32& tc_offset, S32& norm_offset, S32 &idx_stride, domSource* &pos_source, domSource* &tc_source, domSource* &norm_source) { - idx_stride = 0; for (U32 j = 0; j < inputs.getCount(); ++j) @@ -271,14 +194,13 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& fa cv.mTexCoord.setVec(tc[idx[i+tc_offset]*2+0], tc[idx[i+tc_offset]*2+1]); } - + if (norm_source) { cv.setNormal(LLVector4a(n[idx[i+norm_offset]*3+0], n[idx[i+norm_offset]*3+1], n[idx[i+norm_offset]*3+2])); } - BOOL found = FALSE; @@ -329,10 +251,22 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& fa { face_list.push_back(face); face_list.rbegin()->fillFromLegacyData(verts, indices); + LLVolumeFace& new_face = *face_list.rbegin(); + if (!norm_source) + { + ll_aligned_free_16(new_face.mNormals); + new_face.mNormals = NULL; + } + + if (!tc_source) + { + ll_aligned_free_16(new_face.mTexCoords); + new_face.mTexCoords = NULL; + } + face = LLVolumeFace(); point_map.clear(); } - } if (!verts.empty()) @@ -348,6 +282,18 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& fa face_list.push_back(face); face_list.rbegin()->fillFromLegacyData(verts, indices); + LLVolumeFace& new_face = *face_list.rbegin(); + if (!norm_source) + { + ll_aligned_free_16(new_face.mNormals); + new_face.mNormals = NULL; + } + + if (!tc_source) + { + ll_aligned_free_16(new_face.mTexCoords); + new_face.mTexCoords = NULL; + } } return LLModel::NO_ERRORS ; @@ -433,14 +379,14 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& fac cv.mTexCoord.setVec(tc[idx[cur_idx+tc_offset]*2+0], tc[idx[cur_idx+tc_offset]*2+1]); } - + if (norm_source) { cv.getNormal().set(n[idx[cur_idx+norm_offset]*3+0], n[idx[cur_idx+norm_offset]*3+1], n[idx[cur_idx+norm_offset]*3+2]); } - + cur_idx += idx_stride; BOOL found = FALSE; @@ -524,6 +470,19 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& fac { face_list.push_back(face); face_list.rbegin()->fillFromLegacyData(verts, indices); + LLVolumeFace& new_face = *face_list.rbegin(); + if (!norm_source) + { + ll_aligned_free_16(new_face.mNormals); + new_face.mNormals = NULL; + } + + if (!tc_source) + { + ll_aligned_free_16(new_face.mTexCoords); + new_face.mTexCoords = NULL; + } + face = LLVolumeFace(); verts.clear(); indices.clear(); @@ -540,10 +499,23 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& fac { material = std::string(poly->getMaterial()); } - + materials.push_back(material); face_list.push_back(face); face_list.rbegin()->fillFromLegacyData(verts, indices); + + LLVolumeFace& new_face = *face_list.rbegin(); + if (!norm_source) + { + ll_aligned_free_16(new_face.mNormals); + new_face.mNormals = NULL; + } + + if (!tc_source) + { + ll_aligned_free_16(new_face.mTexCoords); + new_face.mTexCoords = NULL; + } } return LLModel::NO_ERRORS ; @@ -557,7 +529,6 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac const domInputLocalOffset_Array& inputs = poly->getInput_array(); - S32 v_offset = -1; S32 n_offset = -1; S32 t_offset = -1; @@ -662,15 +633,14 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac n->get(n_idx+1), n->get(n_idx+2)); } - + if (t) { U32 t_idx = idx[j*stride+t_offset]*2; vert.mTexCoord.setVec(t->get(t_idx), t->get(t_idx+1)); } - - + verts.push_back(vert); } } @@ -733,6 +703,19 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac materials.push_back(material); face_list.push_back(face); face_list.rbegin()->fillFromLegacyData(new_verts, indices); + + LLVolumeFace& new_face = *face_list.rbegin(); + if (!n) + { + ll_aligned_free_16(new_face.mNormals); + new_face.mNormals = NULL; + } + + if (!t) + { + ll_aligned_free_16(new_face.mTexCoords); + new_face.mTexCoords = NULL; + } } return LLModel::NO_ERRORS ; @@ -817,9 +800,9 @@ BOOL LLModel::createVolumeFacesFromDomMesh(domMesh* mesh) if (getNumVolumeFaces() > 0) { - optimizeVolumeFaces(); normalizeVolumeFaces(); - + optimizeVolumeFaces(); + if (getNumVolumeFaces() > 0) { return TRUE; @@ -853,81 +836,10 @@ void LLModel::offsetMesh( const LLVector3& pivotPoint ) void LLModel::optimizeVolumeFaces() { -#if 0 //VECTORIZE ? - for (std::vector<LLVolumeFace>::iterator iter = mVolumeFaces.begin(); iter != mVolumeFaces.end(); ) - { - std::vector<LLVolumeFace>::iterator cur_iter = iter++; - LLVolumeFace& face = *cur_iter; - - for (S32 i = 0; i < (S32) face.mNumIndices; i += 3) - { //remove zero area triangles - U16 i0 = face.mIndices[i+0]; - U16 i1 = face.mIndices[i+1]; - U16 i2 = face.mIndices[i+2]; - - if (i0 == i1 || - i1 == i2 || - i0 == i2) - { //duplicate index in triangle, remove triangle - face.mIndices.erase(face.mIndices.begin()+i, face.mIndices.begin()+i+3); - i -= 3; - } - else - { - LLVolumeFace::VertexData& v0 = face.mVertices[i0]; - LLVolumeFace::VertexData& v1 = face.mVertices[i1]; - LLVolumeFace::VertexData& v2 = face.mVertices[i2]; - - if (v0.mPosition == v1.mPosition || - v1.mPosition == v2.mPosition || - v2.mPosition == v0.mPosition) - { //zero area triangle, delete - face.mIndices.erase(face.mIndices.begin()+i, face.mIndices.begin()+i+3); - i-=3; - } - } - } - - //remove unreference vertices - std::vector<bool> ref; - ref.resize(face.mNumVertices); - - for (U32 i = 0; i < ref.size(); ++i) - { - ref[i] = false; - } - - for (U32 i = 0; i < face.mNumIndices; ++i) - { - ref[face.mIndices[i]] = true; - } - - U32 unref_count = 0; - for (U32 i = 0; i < ref.size(); ++i) - { - if (!ref[i]) - { - //vertex is unreferenced - face.mVertices.erase(face.mVertices.begin()+(i-unref_count)); - U16 idx = (U16) (i-unref_count); - - for (U32 j = 0; j < face.mNumIndices; ++j) - { //decrement every index array value greater than idx - if (face.mIndices[j] > idx) - { - --face.mIndices[j]; - } - } - ++unref_count; - } - } - - if (face.mVertices.empty() || face.mIndices.empty()) - { //face is empty, remove it - iter = mVolumeFaces.erase(cur_iter); - } + for (U32 i = 0; i < getNumVolumeFaces(); ++i) + { + mVolumeFaces[i].optimize(); } -#endif } // Shrink the model to fit @@ -962,6 +874,25 @@ void LLModel::normalizeVolumeFaces() update_min_max(min, max, face.mExtents[0]); update_min_max(min, max, face.mExtents[1]); + + if (face.mTexCoords) + { + LLVector2& min_tc = face.mTexCoordExtents[0]; + LLVector2& max_tc = face.mTexCoordExtents[1]; + + min_tc = face.mTexCoords[0]; + max_tc = face.mTexCoords[0]; + + for (U32 j = 1; j < face.mNumVertices; ++j) + { + update_min_max(min_tc, max_tc, face.mTexCoords[j]); + } + } + else + { + face.mTexCoordExtents[0].set(0,0); + face.mTexCoordExtents[1].set(1,1); + } } // Now that we have the extents of the model @@ -1029,8 +960,11 @@ void LLModel::normalizeVolumeFaces() { pos[j].add(trans); pos[j].mul(scale); - norm[j].mul(inv_scale); - norm[j].normalize3(); + if (norm && !norm[j].equals3(LLVector4a::getZero())) + { + norm[j].mul(inv_scale); + norm[j].normalize3(); + } } } @@ -1073,8 +1007,26 @@ void LLModel::setVolumeFaceData( face.resizeIndices(num_indices); LLVector4a::memcpyNonAliased16((F32*) face.mPositions, (F32*) pos.get(), num_verts*4*sizeof(F32)); - LLVector4a::memcpyNonAliased16((F32*) face.mNormals, (F32*) norm.get(), num_verts*4*sizeof(F32)); - LLVector4a::memcpyNonAliased16((F32*) face.mTexCoords, (F32*) tc.get(), num_verts*2*sizeof(F32)); + if (norm.get()) + { + LLVector4a::memcpyNonAliased16((F32*) face.mNormals, (F32*) norm.get(), num_verts*4*sizeof(F32)); + } + else + { + ll_aligned_free_16(face.mNormals); + face.mNormals = NULL; + } + + if (tc.get()) + { + LLVector4a::memcpyNonAliased16((F32*) face.mTexCoords, (F32*) tc.get(), num_verts*2*sizeof(F32)); + } + else + { + ll_aligned_free_16(face.mTexCoords); + face.mTexCoords = NULL; + } + U32 size = (num_indices*2+0xF)&~0xF; LLVector4a::memcpyNonAliased16((F32*) face.mIndices, (F32*) ind.get(), size); } @@ -1462,13 +1414,19 @@ LLSD LLModel::writeModel( U32 tc_idx = 0; LLVector2* ftc = (LLVector2*) face.mTexCoords; - LLVector2 min_tc = ftc[0]; - LLVector2 max_tc = min_tc; - - //get texture coordinate domain - for (U32 j = 0; j < face.mNumVertices; ++j) + LLVector2 min_tc; + LLVector2 max_tc; + + if (ftc) { - update_min_max(min_tc, max_tc, ftc[j]); + min_tc = ftc[0]; + max_tc = min_tc; + + //get texture coordinate domain + for (U32 j = 0; j < face.mNumVertices; ++j) + { + update_min_max(min_tc, max_tc, ftc[j]); + } } LLVector2 tc_range = max_tc - min_tc; @@ -1477,9 +1435,8 @@ LLSD LLModel::writeModel( { //for each vert F32* pos = face.mPositions[j].getF32ptr(); - F32* norm = face.mNormals[j].getF32ptr(); - - //position + normal + + //position for (U32 k = 0; k < 3; ++k) { //for each component //convert to 16-bit normalized across domain @@ -1489,29 +1446,40 @@ LLSD LLModel::writeModel( //write to binary buffer verts[vert_idx++] = buff[0]; verts[vert_idx++] = buff[1]; - - //convert to 16-bit normalized - val = (U16) ((norm[k]+1.f)*0.5f*65535); - - //write to binary buffer - normals[norm_idx++] = buff[0]; - normals[norm_idx++] = buff[1]; } - F32* src_tc = (F32*) face.mTexCoords[j].mV; + if (face.mNormals) + { //normals + F32* norm = face.mNormals[j].getF32ptr(); - //texcoord - for (U32 k = 0; k < 2; ++k) - { //for each component - //convert to 16-bit normalized - U16 val = (U16) ((src_tc[k]-min_tc.mV[k])/tc_range.mV[k]*65535); + for (U32 k = 0; k < 3; ++k) + { //for each component + //convert to 16-bit normalized + U16 val = (U16) ((norm[k]+1.f)*0.5f*65535); + U8* buff = (U8*) &val; - U8* buff = (U8*) &val; - //write to binary buffer - tc[tc_idx++] = buff[0]; - tc[tc_idx++] = buff[1]; + //write to binary buffer + normals[norm_idx++] = buff[0]; + normals[norm_idx++] = buff[1]; + } } + F32* src_tc = (F32*) face.mTexCoords[j].mV; + + //texcoord + if (face.mTexCoords) + { + for (U32 k = 0; k < 2; ++k) + { //for each component + //convert to 16-bit normalized + U16 val = (U16) ((src_tc[k]-min_tc.mV[k])/tc_range.mV[k]*65535); + + U8* buff = (U8*) &val; + //write to binary buffer + tc[tc_idx++] = buff[0]; + tc[tc_idx++] = buff[1]; + } + } } U32 idx_idx = 0; @@ -1525,12 +1493,20 @@ LLSD LLModel::writeModel( //write out face data mdl[model_names[idx]][i]["PositionDomain"]["Min"] = min_pos.getValue(); mdl[model_names[idx]][i]["PositionDomain"]["Max"] = max_pos.getValue(); - mdl[model_names[idx]][i]["TexCoord0Domain"]["Min"] = min_tc.getValue(); - mdl[model_names[idx]][i]["TexCoord0Domain"]["Max"] = max_tc.getValue(); - mdl[model_names[idx]][i]["Position"] = verts; - mdl[model_names[idx]][i]["Normal"] = normals; - mdl[model_names[idx]][i]["TexCoord0"] = tc; + + if (face.mNormals) + { + mdl[model_names[idx]][i]["Normal"] = normals; + } + + if (face.mTexCoords) + { + mdl[model_names[idx]][i]["TexCoord0Domain"]["Min"] = min_tc.getValue(); + mdl[model_names[idx]][i]["TexCoord0Domain"]["Max"] = max_tc.getValue(); + mdl[model_names[idx]][i]["TexCoord0"] = tc; + } + mdl[model_names[idx]][i]["TriangleList"] = indices; if (skinning) @@ -1808,6 +1784,7 @@ bool LLModel::loadModel(std::istream& is) if (header[nm[lod]]["offset"].asInteger() == -1 || header[nm[lod]]["size"].asInteger() == 0 ) { //cannot load requested LOD + llwarns << "LoD data is invalid!" << llendl; return false; } @@ -1821,7 +1798,7 @@ bool LLModel::loadModel(std::istream& is) is.seekg(cur_pos); } - if (lod == LLModel::LOD_PHYSICS) + if (lod == LLModel::LOD_HIGH || lod == LLModel::LOD_PHYSICS) { std::ios::pos_type cur_pos = is.tellg(); loadDecomposition(header, is); @@ -1868,6 +1845,10 @@ bool LLModel::loadModel(std::istream& is) } return true; } + else + { + llwarns << "unpackVolumeFaces failed!" << llendl; + } return false; @@ -2034,7 +2015,7 @@ LLModel::Decomposition::Decomposition(LLSD& data) void LLModel::Decomposition::fromLLSD(LLSD& decomp) { - if (decomp.has("HullList")) + if (decomp.has("HullList") && decomp.has("Positions")) { // updated for const-correctness. gcc is picky about this type of thing - Nyx const LLSD::Binary& hulls = decomp["HullList"].asBinary(); diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 4a0b964e61..d5a7159ee3 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -240,7 +240,8 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask) void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos, const std::vector<LLVector3>& norm) { U32 count = pos.size(); - llassert(norm.size() >= pos.size()); + llassert_always(norm.size() >= pos.size()); + llassert_always(count > 0) ; unbind(); diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 594285b92b..b520650978 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -5587,7 +5587,7 @@ <key>Type</key> <string>Boolean</string> <key>Value</key> - <real>0</real> + <real>1</real> </map> <key>MeshUploadLogXML</key> <map> @@ -5611,6 +5611,17 @@ <key>Value</key> <real>0</real> </map> + <key>MeshUploadTimeOut</key> + <map> + <key>Comment</key> + <string>Maximum time in seconds for llcurl to execute a mesh uoloading request</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <real>600</real> + </map> <key>MigrateCacheDirectory</key> <map> <key>Comment</key> @@ -9134,28 +9145,51 @@ <key>Value</key> <real>1.0</real> </map> - <key>MeshStreamingCostScaler</key> + <key>MeshTriangleBudget</key> <map> <key>Comment</key> - <string>DEBUG</string> + <string>Target visible triangle budget to use when estimating streaming cost.</string> <key>Persist</key> <integer>1</integer> <key>Type</key> - <string>F32</string> + <string>U32</string> <key>Value</key> - <real>2.0</real> + <real>250000</real> </map> - <key>MeshThreadCount</key> + <key>MeshMetaDataDiscount</key> <map> <key>Comment</key> - <string>Number of threads to use for loading meshes.</string> + <string>Number of bytes to deduct for metadata when determining streaming cost.</string> <key>Persist</key> <integer>1</integer> <key>Type</key> <string>U32</string> <key>Value</key> - <integer>8</integer> + <real>384</real> </map> + <key>MeshMinimumByteSize</key> + <map> + <key>Comment</key> + <string>Minimum number of bytes per LoD block when determining streaming cost.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <real>16</real> + </map> + <key>MeshBytesPerTriangle</key> + <map> + <key>Comment</key> + <string>Approximation of bytes per triangle to use for determining mesh streaming cost.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <real>16</real> + </map> + <key>MeshMaxConcurrentRequests</key> <map> <key>Comment</key> @@ -9387,6 +9421,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>ShowAdvancedBuilderOptions</key> + <map> + <key>Comment</key> + <string>Shows physics and display weight</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>ShowAdvancedGraphicsSettings</key> <map> <key>Comment</key> diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index c30d3b9aa3..f195c985c0 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -393,8 +393,6 @@ LLVector3 LLAgentCamera::calcFocusOffset(LLViewerObject *object, LLVector3 origi LLQuaternion inv_obj_rot = ~obj_rot; // get inverse of rotation LLVector3 object_extents = object->getScale(); - const LLVector4a* oe4 = object->mDrawable->getSpatialExtents(); - object_extents.set( oe4[1][0], oe4[1][1], oe4[1][2] ); // make sure they object extents are non-zero object_extents.clamp(0.001f, F32_MAX); diff --git a/indra/newview/llfloaterbuildoptions.cpp b/indra/newview/llfloaterbuildoptions.cpp index 4b6fe4a115..86c1bf0534 100644 --- a/indra/newview/llfloaterbuildoptions.cpp +++ b/indra/newview/llfloaterbuildoptions.cpp @@ -34,15 +34,81 @@ #include "llfloaterbuildoptions.h" #include "lluictrlfactory.h" +#include "llcombobox.h" +#include "llselectmgr.h" + // // Methods // + +void commit_grid_mode(LLUICtrl *); + LLFloaterBuildOptions::LLFloaterBuildOptions(const LLSD& key) - : LLFloater(key) + : LLFloater(key), + mComboGridMode(NULL) { + mCommitCallbackRegistrar.add("GridOptions.gridMode", boost::bind(&commit_grid_mode,_1)); } LLFloaterBuildOptions::~LLFloaterBuildOptions() +{} + +BOOL LLFloaterBuildOptions::postBuild() +{ + mComboGridMode = getChild<LLComboBox>("combobox grid mode"); + + return TRUE; +} + +void LLFloaterBuildOptions::setGridMode(EGridMode mode) +{ + mComboGridMode->setCurrentByIndex((S32)mode); +} + +void LLFloaterBuildOptions::updateGridMode() { + if (mComboGridMode) + { + S32 index = mComboGridMode->getCurrentIndex(); + mComboGridMode->removeall(); + + switch (mObjectSelection->getSelectType()) + { + case SELECT_TYPE_HUD: + mComboGridMode->add(getString("grid_screen_text")); + mComboGridMode->add(getString("grid_local_text")); + break; + case SELECT_TYPE_WORLD: + mComboGridMode->add(getString("grid_world_text")); + mComboGridMode->add(getString("grid_local_text")); + mComboGridMode->add(getString("grid_reference_text")); + break; + case SELECT_TYPE_ATTACHMENT: + mComboGridMode->add(getString("grid_attachment_text")); + mComboGridMode->add(getString("grid_local_text")); + mComboGridMode->add(getString("grid_reference_text")); + break; + } + + mComboGridMode->setCurrentByIndex(index); + } +} + +// virtual +void LLFloaterBuildOptions::onOpen(const LLSD& key) +{ + mObjectSelection = LLSelectMgr::getInstance()->getEditSelection(); } +// virtual +void LLFloaterBuildOptions::onClose(bool app_quitting) +{ + mObjectSelection = NULL; +} + +void commit_grid_mode(LLUICtrl *ctrl) +{ + LLComboBox* combo = (LLComboBox*)ctrl; + + LLSelectMgr::getInstance()->setGridMode((EGridMode)combo->getCurrentIndex()); +} diff --git a/indra/newview/llfloaterbuildoptions.h b/indra/newview/llfloaterbuildoptions.h index 164944d7bc..7f3811bf1c 100644 --- a/indra/newview/llfloaterbuildoptions.h +++ b/indra/newview/llfloaterbuildoptions.h @@ -33,15 +33,34 @@ #define LL_LLFLOATERBUILDOPTIONS_H #include "llfloater.h" +#include "llselectmgr.h" +class LLComboBox; +class LLObjectSelection; + +typedef LLSafeHandle<LLObjectSelection> LLObjectSelectionHandle; class LLFloaterBuildOptions : public LLFloater { - friend class LLFloaterReg; +public: + + virtual BOOL postBuild(); + + /*virtual*/ void onOpen(const LLSD& key); + /*virtual*/ void onClose(bool app_quitting); + + void setGridMode(EGridMode mode); + void updateGridMode(); + private: + + friend class LLFloaterReg; + LLFloaterBuildOptions(const LLSD& key); ~LLFloaterBuildOptions(); -}; + LLComboBox* mComboGridMode; + LLObjectSelectionHandle mObjectSelection; +}; #endif diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index ab6753b4be..67841620ea 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -1968,10 +1968,6 @@ bool LLModelLoader::loadFromSLM(const std::string& filename) mPreview->critiqueRigForUploadApplicability( loaded_model->mSkinInfo.mJointNames ); } } - else - { - llassert(model[lod].empty()); - } } } @@ -1980,6 +1976,12 @@ bool LLModelLoader::loadFromSLM(const std::string& filename) return false; } + if (model[LLModel::LOD_PHYSICS].empty()) + { //no explicit physics block, copy HIGH_LOD into physics array to recover convex decomp + model[LLModel::LOD_PHYSICS] = model[LLModel::LOD_HIGH]; + } + + //load instance list model_instance_list instance_list; @@ -3107,18 +3109,20 @@ void LLModelPreview::rebuildUploadData() } } - for (U32 i = 0; i < LLModel::NUM_LODS; i++) - { //fill LOD slots based on reference model index - if (!mModel[i].empty()) - { - instance.mLOD[i] = mModel[i][idx]; - } - else - { - instance.mLOD[i] = NULL; + if(idx < mBaseModel.size()) + { + for (U32 i = 0; i < LLModel::NUM_LODS; i++) + { //fill LOD slots based on reference model index + if (mModel[i].size() > idx) + { + instance.mLOD[i] = mModel[i][idx]; + } + else + { + instance.mLOD[i] = NULL; + } } } - instance.mTransform = mat; mUploadData.push_back(instance); } @@ -3734,7 +3738,9 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim U32 tri_count = 0; for (U32 i = 0; i < mVertexBuffer[5][mdl].size(); ++i) { - mVertexBuffer[5][mdl][i]->setBuffer(type_mask); + LLVertexBuffer* buff = mVertexBuffer[5][mdl][i]; + buff->setBuffer(type_mask & buff->getTypeMask()); + U32 num_indices = mVertexBuffer[5][mdl][i]->getNumIndices(); if (num_indices > 2) { @@ -3856,6 +3862,8 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim for (GLint i = 0; i < patch_count; ++i) { + type_mask = mVertexBuffer[5][base][i]->getTypeMask(); + LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(type_mask, 0); if (sizes[i*2+1] > 0 && sizes[i*2] > 0) @@ -3880,8 +3888,15 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim LLStrider<U16> index; buff->getVertexStrider(pos); - buff->getNormalStrider(norm); - buff->getTexCoord0Strider(tc); + if (type_mask & LLVertexBuffer::MAP_NORMAL) + { + buff->getNormalStrider(norm); + } + if (type_mask & LLVertexBuffer::MAP_TEXCOORD0) + { + buff->getTexCoord0Strider(tc); + } + buff->getIndexStrider(index); target_model->setVolumeFaceData(names[i], pos, norm, tc, index, buff->getNumVerts(), buff->getNumIndices()); @@ -4087,18 +4102,20 @@ void LLModelPreview::updateStatusMessages() } else if (!verts[lod].empty()) { + S32 sum_verts_higher_lod = 0; + S32 sum_verts_this_lod = 0; for (U32 i = 0; i < verts[lod].size(); ++i) { - S32 max_verts = i < verts[lod+1].size() ? verts[lod+1][i] : 0; + sum_verts_higher_lod += ((i < verts[lod+1].size()) ? verts[lod+1][i] : 0); + sum_verts_this_lod += verts[lod][i]; + } - if (max_verts > 0) - { - if (verts[lod][i] > max_verts) - { //too many vertices in this lod - message = "mesh_status_too_many_vertices"; - upload_status[lod] = 2; - } - } + if ((sum_verts_higher_lod > 0) && + (sum_verts_this_lod > sum_verts_higher_lod)) + { + //too many vertices in this lod + message = "mesh_status_too_many_vertices"; + upload_status[lod] = 2; } } } @@ -4485,7 +4502,7 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights) bool skinned = include_skin_weights && !mdl->mSkinWeights.empty(); - U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0; + U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0 ; if (skinned) { @@ -4503,8 +4520,6 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights) LLStrider<LLVector4> weights_strider; vb->getVertexStrider(vertex_strider); - vb->getNormalStrider(normal_strider); - vb->getTexCoord0Strider(tc_strider); vb->getIndexStrider(index_strider); if (skinned) @@ -4513,8 +4528,18 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights) } LLVector4a::memcpyNonAliased16((F32*) vertex_strider.get(), (F32*) vf.mPositions, num_vertices*4*sizeof(F32)); - LLVector4a::memcpyNonAliased16((F32*) tc_strider.get(), (F32*) vf.mTexCoords, num_vertices*2*sizeof(F32)); - LLVector4a::memcpyNonAliased16((F32*) normal_strider.get(), (F32*) vf.mNormals, num_vertices*4*sizeof(F32)); + + if (vf.mTexCoords) + { + vb->getTexCoord0Strider(tc_strider); + LLVector4a::memcpyNonAliased16((F32*) tc_strider.get(), (F32*) vf.mTexCoords, num_vertices*2*sizeof(F32)); + } + + if (vf.mNormals) + { + vb->getNormalStrider(normal_strider); + LLVector4a::memcpyNonAliased16((F32*) normal_strider.get(), (F32*) vf.mNormals, num_vertices*4*sizeof(F32)); + } if (skinned) { @@ -4773,6 +4798,8 @@ BOOL LLModelPreview::render() const F32 BRIGHTNESS = 0.9f; gGL.color3f(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS); + const U32 type_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0; + LLGLEnable normalize(GL_NORMALIZE); if (!mBaseModel.empty() && mVertexBuffer[5].empty()) @@ -4821,8 +4848,8 @@ BOOL LLModelPreview::render() for (U32 i = 0; i < mVertexBuffer[mPreviewLOD][model].size(); ++i) { LLVertexBuffer* buffer = mVertexBuffer[mPreviewLOD][model][i]; - - buffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0); + + buffer->setBuffer(type_mask & buffer->getTypeMask()); if (textures) { @@ -4941,7 +4968,7 @@ BOOL LLModelPreview::render() { LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][i]; - buffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0); + buffer->setBuffer(type_mask & buffer->getTypeMask()); buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); @@ -5007,7 +5034,7 @@ BOOL LLModelPreview::render() { LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][i]; - buffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0); + buffer->setBuffer(type_mask & buffer->getTypeMask()); LLStrider<LLVector3> pos_strider; buffer->getVertexStrider(pos_strider, 0); @@ -5132,7 +5159,7 @@ BOOL LLModelPreview::render() position[j] = v; } - buffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0); + buffer->setBuffer(type_mask & buffer->getTypeMask()); glColor4fv(instance.mMaterial[i].mDiffuseColor.mV); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); buffer->draw(LLRender::TRIANGLES, buffer->getNumIndices(), 0); diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index 33b7777d2e..dc71ade621 100644 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -36,7 +36,6 @@ #include "llagentcamera.h" #include "llbutton.h" #include "llcheckboxctrl.h" -#include "llcombobox.h" #include "lldraghandle.h" #include "llerror.h" #include "llfloaterbuildoptions.h" @@ -101,6 +100,7 @@ const std::string PANEL_NAMES[LLFloaterTools::PANEL_COUNT] = std::string("Content"), // PANEL_CONTENTS, }; + // Local prototypes void commit_select_component(void *data); void click_show_more(void*); @@ -116,7 +116,6 @@ void commit_radio_group_focus(LLUICtrl* ctrl); void commit_radio_group_move(LLUICtrl* ctrl); void commit_radio_group_edit(LLUICtrl* ctrl); void commit_radio_group_land(LLUICtrl* ctrl); -void commit_grid_mode(LLUICtrl *); void commit_slider_zoom(LLUICtrl *ctrl); @@ -234,7 +233,6 @@ BOOL LLFloaterTools::postBuild() getChild<LLUICtrl>("checkbox uniform")->setValue((BOOL)gSavedSettings.getBOOL("ScaleUniform")); mCheckStretchTexture = getChild<LLCheckBoxCtrl>("checkbox stretch textures"); getChild<LLUICtrl>("checkbox stretch textures")->setValue((BOOL)gSavedSettings.getBOOL("ScaleStretchTextures")); - mComboGridMode = getChild<LLComboBox>("combobox grid mode"); mCheckStretchUniformLabel = getChild<LLTextBox>("checkbox uniform label"); // @@ -269,6 +267,8 @@ BOOL LLFloaterTools::postBuild() // the setting stores the actual force multiplier, but the slider is logarithmic, so we convert here getChild<LLUICtrl>("slider force")->setValue(log10(gSavedSettings.getF32("LandBrushForce"))); + mCostTextBorder = getChild<LLViewBorder>("cost_text_border"); + mTab = getChild<LLTabContainer>("Object Info Tabs"); if(mTab) { @@ -311,7 +311,6 @@ LLFloaterTools::LLFloaterTools(const LLSD& key) mCheckSnapToGrid(NULL), mBtnGridOptions(NULL), mTitleMedia(NULL), - mComboGridMode(NULL), mCheckStretchUniform(NULL), mCheckStretchTexture(NULL), mCheckStretchUniformLabel(NULL), @@ -344,6 +343,7 @@ LLFloaterTools::LLFloaterTools(const LLSD& key) mPanelFace(NULL), mPanelLandInfo(NULL), + mCostTextBorder(NULL), mTabLand(NULL), mDirty(TRUE), mNeedMediaTitle(TRUE) @@ -367,7 +367,6 @@ LLFloaterTools::LLFloaterTools(const LLSD& key) mCommitCallbackRegistrar.add("BuildTool.selectComponent", boost::bind(&commit_select_component, this)); mCommitCallbackRegistrar.add("BuildTool.gridOptions", boost::bind(&LLFloaterTools::onClickGridOptions,this)); mCommitCallbackRegistrar.add("BuildTool.applyToSelection", boost::bind(&click_apply_to_selection, this)); - mCommitCallbackRegistrar.add("BuildTool.gridMode", boost::bind(&commit_grid_mode,_1)); mCommitCallbackRegistrar.add("BuildTool.commitRadioLand", boost::bind(&commit_radio_group_land,_1)); mCommitCallbackRegistrar.add("BuildTool.LandBrushForce", boost::bind(&commit_slider_dozer_force,_1)); mCommitCallbackRegistrar.add("BuildTool.AddMedia", boost::bind(&LLFloaterTools::onClickBtnAddMedia,this)); @@ -428,10 +427,10 @@ void LLFloaterTools::refresh() { std::string obj_count_string; LLResMgr::getInstance()->getIntegerString(obj_count_string, LLSelectMgr::getInstance()->getSelection()->getRootObjectCount()); - getChild<LLUICtrl>("obj_count")->setTextArg("[COUNT]", obj_count_string); + getChild<LLUICtrl>("selection_count")->setTextArg("[OBJ_COUNT]", obj_count_string); std::string prim_count_string; LLResMgr::getInstance()->getIntegerString(prim_count_string, LLSelectMgr::getInstance()->getSelection()->getObjectCount()); - getChild<LLUICtrl>("prim_count")->setTextArg("[COUNT]", prim_count_string); + getChild<LLUICtrl>("selection_count")->setTextArg("[PRIM_COUNT]", prim_count_string); // calculate selection rendering cost if (sShowObjectCost) @@ -449,55 +448,50 @@ void LLFloaterTools::refresh() } else { - // Get the number of objects selected - std::string root_object_count_string; - std::string object_count_string; - - LLResMgr::getInstance()->getIntegerString( - root_object_count_string, - LLSelectMgr::getInstance()->getSelection()->getRootObjectCount()); - LLResMgr::getInstance()->getIntegerString( - object_count_string, - LLSelectMgr::getInstance()->getSelection()->getObjectCount()); - - F32 obj_cost = - LLSelectMgr::getInstance()->getSelection()->getSelectedObjectCost(); - F32 link_cost = - LLSelectMgr::getInstance()->getSelection()->getSelectedLinksetCost(); - F32 obj_physics_cost = - LLSelectMgr::getInstance()->getSelection()->getSelectedPhysicsCost(); - F32 link_physics_cost = - LLSelectMgr::getInstance()->getSelection()->getSelectedLinksetPhysicsCost(); - - // Update the text for the counts - childSetTextArg( - "linked_set_count", - "[COUNT]", - root_object_count_string); - childSetTextArg("object_count", "[COUNT]", object_count_string); - - // Update the text for the resource costs - childSetTextArg("linked_set_cost","[COST]",llformat("%.1f", link_cost)); - childSetTextArg("object_cost", "[COST]", llformat("%.1f", obj_cost)); - childSetTextArg("linked_set_cost","[PHYSICS]",llformat("%.1f", link_physics_cost)); - childSetTextArg("object_cost", "[PHYSICS]", llformat("%.1f", obj_physics_cost)); - - // Display rendering cost if needed - if (sShowObjectCost) + F32 link_phys_cost = LLSelectMgr::getInstance()->getSelection()->getSelectedLinksetPhysicsCost(); + F32 link_cost = LLSelectMgr::getInstance()->getSelection()->getSelectedLinksetCost(); + S32 prim_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); + S32 link_count = LLSelectMgr::getInstance()->getSelection()->getRootObjectCount(); + + LLStringUtil::format_map_t selection_args; + selection_args["OBJ_COUNT"] = llformat("%.1d", link_count); + selection_args["PRIM_COUNT"] = llformat("%.1d", prim_count); + + std::ostringstream selection_info; + + bool show_adv_weight = gSavedSettings.getBOOL("ShowAdvancedBuilderOptions"); + bool show_mesh_cost = gMeshRepo.meshRezEnabled(); + + if (show_mesh_cost) { - std::string prim_cost_string; - LLResMgr::getInstance()->getIntegerString(prim_cost_string, calcRenderCost()); - getChild<LLUICtrl>("RenderingCost")->setTextArg("[COUNT]", prim_cost_string); + LLStringUtil::format_map_t prim_equiv_args; + prim_equiv_args["SEL_WEIGHT"] = llformat("%.1d", (S32)link_cost); + selection_args["PE_STRING"] = getString("status_selectprimequiv", prim_equiv_args); + } + else + { + selection_args["PE_STRING"] = ""; } + selection_info << getString("status_selectcount", selection_args); - // disable the object and prim counts if nothing selected - bool have_selection = ! LLSelectMgr::getInstance()->getSelection()->isEmpty(); - childSetEnabled("linked_set_count", have_selection); - childSetEnabled("object_count", have_selection); - childSetEnabled("linked_set_cost", have_selection); - childSetEnabled("object_cost", have_selection); - getChildView("RenderingCost")->setEnabled(have_selection && sShowObjectCost); + if (show_adv_weight) + { + selection_info << ","; + + childSetTextArg("selection_weight", "[PHYS_WEIGHT]", llformat("%.1f", link_phys_cost)); + childSetTextArg("selection_weight", "[DISP_WEIGHT]", llformat("%.1d", calcRenderCost())); + } + else + { + selection_info<<"."; + } + getChild<LLTextBox>("selection_count")->setText(selection_info.str()); + + bool have_selection = !LLSelectMgr::getInstance()->getSelection()->isEmpty(); + childSetVisible("selection_count", have_selection); + childSetVisible("selection_weight", have_selection && show_adv_weight); + childSetVisible("selection_empty", !have_selection); } @@ -662,33 +656,6 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) mRadioGroupEdit->setValue("radio select face"); } - if (mComboGridMode) - { - mComboGridMode->setVisible( edit_visible ); - S32 index = mComboGridMode->getCurrentIndex(); - mComboGridMode->removeall(); - - switch (mObjectSelection->getSelectType()) - { - case SELECT_TYPE_HUD: - mComboGridMode->add(getString("grid_screen_text")); - mComboGridMode->add(getString("grid_local_text")); - //mComboGridMode->add(getString("grid_reference_text")); - break; - case SELECT_TYPE_WORLD: - mComboGridMode->add(getString("grid_world_text")); - mComboGridMode->add(getString("grid_local_text")); - mComboGridMode->add(getString("grid_reference_text")); - break; - case SELECT_TYPE_ATTACHMENT: - mComboGridMode->add(getString("grid_attachment_text")); - mComboGridMode->add(getString("grid_local_text")); - mComboGridMode->add(getString("grid_reference_text")); - break; - } - - mComboGridMode->setCurrentByIndex(index); - } // Snap to grid disabled for grab tool - very confusing if (mCheckSnapToGrid) mCheckSnapToGrid->setVisible( edit_visible /* || tool == LLToolGrab::getInstance() */ ); if (mBtnGridOptions) mBtnGridOptions->setVisible( edit_visible /* || tool == LLToolGrab::getInstance() */ ); @@ -737,6 +704,8 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) // Land buttons BOOL land_visible = (tool == LLToolBrushLand::getInstance() || tool == LLToolSelectLand::getInstance() ); + mCostTextBorder->setVisible(!land_visible); + if (mBtnLand) mBtnLand ->setToggleState( land_visible ); mRadioGroupLand->setVisible( land_visible ); @@ -789,15 +758,11 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) getChildView("Strength:")->setVisible( land_visible); } - bool show_mesh_cost = gMeshRepo.meshRezEnabled(); + bool have_selection = !LLSelectMgr::getInstance()->getSelection()->isEmpty(); - getChildView("obj_count")->setVisible( !land_visible && !show_mesh_cost); - getChildView("prim_count")->setVisible( !land_visible && !show_mesh_cost); - getChildView("linked_set_count")->setVisible( !land_visible && show_mesh_cost); - getChildView("linked_set_cost")->setVisible( !land_visible && show_mesh_cost); - getChildView("object_count")->setVisible( !land_visible && show_mesh_cost); - getChildView("object_cost")->setVisible( !land_visible && show_mesh_cost); - getChildView("RenderingCost")->setVisible( !land_visible && sShowObjectCost); + getChildView("selection_count")->setVisible(!land_visible && have_selection); + getChildView("selection_weight")->setVisible(!land_visible && have_selection && gSavedSettings.getBOOL("ShowAdvancedBuilderOptions")); + getChildView("selection_empty")->setVisible(!land_visible && !have_selection); mTab->setVisible(!land_visible); mPanelLandInfo->setVisible(land_visible); @@ -1030,13 +995,6 @@ void commit_select_component(void *data) } } -void commit_grid_mode(LLUICtrl *ctrl) -{ - LLComboBox* combo = (LLComboBox*)ctrl; - - LLSelectMgr::getInstance()->setGridMode((EGridMode)combo->getCurrentIndex()); -} - // static void LLFloaterTools::setObjectType( LLPCode pcode ) { diff --git a/indra/newview/llfloatertools.h b/indra/newview/llfloatertools.h index fd81a75397..69636190fc 100644 --- a/indra/newview/llfloatertools.h +++ b/indra/newview/llfloatertools.h @@ -32,7 +32,6 @@ #include "llparcelselection.h" class LLButton; -class LLComboBox; class LLCheckBoxCtrl; class LLPanelPermissions; class LLPanelObject; @@ -140,7 +139,6 @@ public: LLCheckBoxCtrl* mCheckSnapToGrid; LLButton* mBtnGridOptions; - LLComboBox* mComboGridMode; LLCheckBoxCtrl* mCheckStretchUniform; LLCheckBoxCtrl* mCheckStretchTexture; @@ -179,6 +177,8 @@ public: LLPanelFace *mPanelFace; LLPanelLandInfo *mPanelLandInfo; + LLViewBorder* mCostTextBorder; + LLTabContainer* mTabLand; LLParcelSelectionHandle mParcelSelection; diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 6e0722bcf9..be11c53efa 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -78,6 +78,14 @@ LLMeshRepository gMeshRepo; const U32 MAX_MESH_REQUESTS_PER_SECOND = 100; +// Maximum mesh version to support. Three least significant digits are reserved for the minor version, +// with major version changes indicating a format change that is not backwards compatible and should not +// be parsed by viewers that don't specifically support that version. For example, if the integer "1" is +// present, the version is 0.001. A viewer that can parse version 0.001 can also parse versions up to 0.999, +// but not 1.0 (integer 1000). +// See wiki at https://wiki.secondlife.com/wiki/Mesh/Mesh_Asset_Format +const S32 MAX_MESH_VERSION = 999; + U32 LLMeshRepository::sBytesReceived = 0; U32 LLMeshRepository::sHTTPRequestCount = 0; U32 LLMeshRepository::sHTTPRetryCount = 0; @@ -843,12 +851,13 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id) if (header_size > 0) { + S32 version = mMeshHeader[mesh_id]["version"].asInteger(); S32 offset = header_size + mMeshHeader[mesh_id]["skin"]["offset"].asInteger(); S32 size = mMeshHeader[mesh_id]["skin"]["size"].asInteger(); mHeaderMutex->unlock(); - if (offset >= 0 && size > 0) + if (version <= MAX_MESH_VERSION && offset >= 0 && size > 0) { //check VFS for mesh skin info LLVFile file(gVFS, mesh_id, LLAssetType::AT_MESH); @@ -915,12 +924,13 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id) if (header_size > 0) { + S32 version = mMeshHeader[mesh_id]["version"].asInteger(); S32 offset = header_size + mMeshHeader[mesh_id]["physics_convex"]["offset"].asInteger(); S32 size = mMeshHeader[mesh_id]["physics_convex"]["size"].asInteger(); mHeaderMutex->unlock(); - if (offset >= 0 && size > 0) + if (version <= MAX_MESH_VERSION && offset >= 0 && size > 0) { //check VFS for mesh skin info LLVFile file(gVFS, mesh_id, LLAssetType::AT_MESH); @@ -987,12 +997,13 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id) if (header_size > 0) { + S32 version = mMeshHeader[mesh_id]["version"].asInteger(); S32 offset = header_size + mMeshHeader[mesh_id]["physics_mesh"]["offset"].asInteger(); S32 size = mMeshHeader[mesh_id]["physics_mesh"]["size"].asInteger(); mHeaderMutex->unlock(); - if (offset >= 0 && size > 0) + if (version <= MAX_MESH_VERSION && offset >= 0 && size > 0) { //check VFS for mesh physics shape info LLVFile file(gVFS, mesh_id, LLAssetType::AT_MESH); @@ -1103,10 +1114,12 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod) if (header_size > 0) { + S32 version = mMeshHeader[mesh_id]["version"].asInteger(); S32 offset = header_size + mMeshHeader[mesh_id][header_lod[lod]]["offset"].asInteger(); S32 size = mMeshHeader[mesh_id][header_lod[lod]]["size"].asInteger(); mHeaderMutex->unlock(); - if (offset >= 0 && size > 0) + + if (version <= MAX_MESH_VERSION && offset >= 0 && size > 0) { //check VFS for mesh asset @@ -1383,6 +1396,8 @@ LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data, mWholeModelFeeCapability = gAgent.getRegion()->getCapability("NewFileAgentInventory"); mOrigin += gAgent.getAtAxis() * scale.magVec(); + + mMeshUploadTimeOut = gSavedSettings.getS32("MeshUploadTimeOut") ; } LLMeshUploadThread::~LLMeshUploadThread() @@ -1573,6 +1588,11 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures) for (S32 face_num = 0; face_num < data.mBaseModel->getNumVolumeFaces(); face_num++) { + if(face_num >= instance.mMaterial.size()) + { + break ; + } + LLImportMaterial& material = instance.mMaterial[face_num]; LLSD face_entry = LLSD::emptyMap(); LLViewerFetchedTexture *texture = material.mDiffuseMap.get(); @@ -1686,7 +1706,7 @@ void LLMeshUploadThread::doWholeModelUpload() mPendingUploads++; LLCurlRequest::headers_t headers; mCurlRequest->post(mWholeModelFeeCapability, headers, model_data, - new LLWholeModelFeeResponder(this,model_data)); + new LLWholeModelFeeResponder(this,model_data), mMeshUploadTimeOut); do { @@ -1705,7 +1725,7 @@ void LLMeshUploadThread::doWholeModelUpload() LLSD body = full_model_data["asset_resources"]; dump_llsd_to_file(body,make_dump_name("whole_model_body_",dump_num)); mCurlRequest->post(mWholeModelUploadURL, headers, body, - new LLWholeModelUploadResponder(this, model_data)); + new LLWholeModelUploadResponder(this, model_data), mMeshUploadTimeOut); do { mCurlRequest->process(); @@ -1799,7 +1819,9 @@ S32 LLMeshRepository::getActualMeshLOD(LLSD& header, S32 lod) { lod = llclamp(lod, 0, 3); - if (header.has("404")) + S32 version = header["version"]; + + if (header.has("404") || version > MAX_MESH_VERSION) { return -1; } @@ -2135,54 +2157,59 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason, LLUUID mesh_id = mMeshParams.getSculptID(); LLSD header = gMeshRepo.mThread->mMeshHeader[mesh_id]; - std::stringstream str; + S32 version = header["version"].asInteger(); + + if (version <= MAX_MESH_VERSION) + { + std::stringstream str; - S32 lod_bytes = 0; + S32 lod_bytes = 0; - for (U32 i = 0; i < LLModel::LOD_PHYSICS; ++i) - { //figure out how many bytes we'll need to reserve in the file - std::string lod_name = header_lod[i]; - lod_bytes = llmax(lod_bytes, header[lod_name]["offset"].asInteger()+header[lod_name]["size"].asInteger()); - } + for (U32 i = 0; i < LLModel::LOD_PHYSICS; ++i) + { //figure out how many bytes we'll need to reserve in the file + 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()); + //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()); - S32 header_bytes = (S32) gMeshRepo.mThread->mMeshHeaderSize[mesh_id]; - S32 bytes = lod_bytes + header_bytes; + 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); + //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); - LLVFile file(gVFS, mesh_id, LLAssetType::AT_MESH, LLVFile::WRITE); - if (file.getMaxSize() >= bytes || file.setMaxSize(bytes)) - { - LLMeshRepository::sCacheBytesWritten += data_size; + LLVFile file(gVFS, mesh_id, LLAssetType::AT_MESH, LLVFile::WRITE); + if (file.getMaxSize() >= bytes || file.setMaxSize(bytes)) + { + LLMeshRepository::sCacheBytesWritten += data_size; - file.write((const U8*) data, data_size); + file.write((const U8*) data, data_size); - //zero out the rest of the file - U8 block[4096]; - memset(block, 0, 4096); + //zero out the rest of the file + U8 block[4096]; + memset(block, 0, 4096); - while (bytes-file.tell() > 4096) - { - file.write(block, 4096); - } + while (bytes-file.tell() > 4096) + { + file.write(block, 4096); + } - S32 remaining = bytes-file.tell(); + S32 remaining = bytes-file.tell(); - if (remaining < 0 || remaining > 4096) - { - llerrs << "Bad padding of mesh asset cache entry." << llendl; - } + if (remaining < 0 || remaining > 4096) + { + llerrs << "Bad padding of mesh asset cache entry." << llendl; + } - if (remaining > 0) - { - file.write(block, remaining); + if (remaining > 0) + { + file.write(block, remaining); + } } } } @@ -2874,7 +2901,7 @@ void LLMeshUploadThread::doUploadModel(LLMeshUploadData& data) LLCurlRequest::headers_t headers; mPendingUploads++; - mCurlRequest->post(data.mRSVP, headers, data.mAssetData, new LLMeshUploadResponder(data, this)); + mCurlRequest->post(data.mRSVP, headers, data.mAssetData, new LLMeshUploadResponder(data, this), mMeshUploadTimeOut); } } @@ -2906,7 +2933,7 @@ void LLMeshUploadThread::doUploadTexture(LLTextureUploadData& data) LLCurlRequest::headers_t headers; mPendingUploads++; - mCurlRequest->post(data.mRSVP, headers, data.mAssetData, new LLTextureUploadResponder(data, this)); + mCurlRequest->post(data.mRSVP, headers, data.mAssetData, new LLTextureUploadResponder(data, this), mMeshUploadTimeOut); } } @@ -3158,55 +3185,66 @@ void LLMeshRepository::uploadError(LLSD& args) //static F32 LLMeshRepository::getStreamingCost(LLSD& header, F32 radius, S32* bytes, S32* bytes_visible, S32 lod) { - F32 dlowest = llmin(radius/0.03f, 256.f); - F32 dlow = llmin(radius/0.06f, 256.f); - F32 dmid = llmin(radius/0.24f, 256.f); - - F32 bytes_lowest = header["lowest_lod"]["size"].asReal()/1024.f; - F32 bytes_low = header["low_lod"]["size"].asReal()/1024.f; - F32 bytes_mid = header["medium_lod"]["size"].asReal()/1024.f; - F32 bytes_high = header["high_lod"]["size"].asReal()/1024.f; + F32 max_distance = 512.f; - if (bytes) - { - *bytes = 0; - *bytes += header["lowest_lod"]["size"].asInteger(); - *bytes += header["low_lod"]["size"].asInteger(); - *bytes += header["medium_lod"]["size"].asInteger(); - *bytes += header["high_lod"]["size"].asInteger(); - } + F32 dlowest = llmin(radius/0.03f, max_distance); + F32 dlow = llmin(radius/0.06f, max_distance); + F32 dmid = llmin(radius/0.24f, max_distance); + + F32 METADATA_DISCOUNT = (F32) gSavedSettings.getU32("MeshMetaDataDiscount"); //discount 128 bytes to cover the cost of LLSD tags and compression domain overhead + F32 MINIMUM_SIZE = (F32) gSavedSettings.getU32("MeshMinimumByteSize"); //make sure nothing is "free" + F32 bytes_per_triangle = (F32) gSavedSettings.getU32("MeshBytesPerTriangle"); - if (bytes_visible) - { - lod = LLMeshRepository::getActualMeshLOD(header, lod); - if (lod >= 0 && lod <= 3) - { - *bytes_visible = header[header_lod[lod]]["size"].asInteger(); - } - } + S32 bytes_lowest = header["lowest_lod"]["size"].asInteger(); + S32 bytes_low = header["low_lod"]["size"].asInteger(); + S32 bytes_mid = header["medium_lod"]["size"].asInteger(); + S32 bytes_high = header["high_lod"]["size"].asInteger(); - if (bytes_high == 0.f) + if (bytes_high == 0) { return 0.f; } - if (bytes_mid == 0.f) + if (bytes_mid == 0) { bytes_mid = bytes_high; } - if (bytes_low == 0.f) + if (bytes_low == 0) { bytes_low = bytes_mid; } - if (bytes_lowest == 0.f) + if (bytes_lowest == 0) { bytes_lowest = bytes_low; } - F32 max_area = 65536.f; + F32 triangles_lowest = llmax((F32) bytes_lowest-METADATA_DISCOUNT, MINIMUM_SIZE)/bytes_per_triangle; + F32 triangles_low = llmax((F32) bytes_low-METADATA_DISCOUNT, MINIMUM_SIZE)/bytes_per_triangle; + F32 triangles_mid = llmax((F32) bytes_mid-METADATA_DISCOUNT, MINIMUM_SIZE)/bytes_per_triangle; + F32 triangles_high = llmax((F32) bytes_high-METADATA_DISCOUNT, MINIMUM_SIZE)/bytes_per_triangle; + + if (bytes) + { + *bytes = 0; + *bytes += header["lowest_lod"]["size"].asInteger(); + *bytes += header["low_lod"]["size"].asInteger(); + *bytes += header["medium_lod"]["size"].asInteger(); + *bytes += header["high_lod"]["size"].asInteger(); + } + + if (bytes_visible) + { + lod = LLMeshRepository::getActualMeshLOD(header, lod); + if (lod >= 0 && lod <= 3) + { + *bytes_visible = header[header_lod[lod]]["size"].asInteger(); + } + } + + F32 max_area = 102932.f; //area of circle that encompasses region F32 min_area = 1.f; F32 high_area = llmin(F_PI*dmid*dmid, max_area); @@ -3229,12 +3267,12 @@ F32 LLMeshRepository::getStreamingCost(LLSD& header, F32 radius, S32* bytes, S32 low_area /= total_area; lowest_area /= total_area; - F32 weighted_avg = bytes_high*high_area + - bytes_mid*mid_area + - bytes_low*low_area + - bytes_lowest*lowest_area; + F32 weighted_avg = triangles_high*high_area + + triangles_mid*mid_area + + triangles_low*low_area + + triangles_lowest*lowest_area; - return weighted_avg * gSavedSettings.getF32("MeshStreamingCostScaler"); + return weighted_avg/gSavedSettings.getU32("MeshTriangleBudget")*15000.f; } diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index f237c3a60e..f56734a7de 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -356,6 +356,9 @@ public: class LLMeshUploadThread : public LLThread { +private: + S32 mMeshUploadTimeOut ; //maximum time in seconds to execute an uploading request. + public: class DecompRequest : public LLPhysicsDecomp::Request { diff --git a/indra/newview/llsceneview.cpp b/indra/newview/llsceneview.cpp index 8e8fc9dd25..09e799e4f7 100644 --- a/indra/newview/llsceneview.cpp +++ b/indra/newview/llsceneview.cpp @@ -83,6 +83,9 @@ void LLSceneView::draw() S32 total_visible_triangles[] = {0, 0}; S32 total_triangles[] = {0, 0}; + S32 total_visible_bytes[] = {0, 0}; + S32 total_bytes[] = {0, 0}; + //streaming cost std::vector<F32> streaming_cost[2]; F32 total_streaming[] = { 0.f, 0.f }; @@ -122,13 +125,19 @@ void LLSceneView::draw() visible_triangles[idx].push_back(visible); triangles[idx].push_back(high_triangles); - F32 streaming = object->getStreamingCost(); + S32 bytes = 0; + S32 visible_bytes = 0; + + F32 streaming = object->getStreamingCost(&bytes, &visible_bytes); total_streaming[idx] += streaming; streaming_cost[idx].push_back(streaming); F32 physics = object->getPhysicsCost(); total_physics[idx] += physics; physics_cost[idx].push_back(physics); + + total_bytes[idx] += bytes; + total_visible_bytes[idx] += visible_bytes; } } } @@ -279,8 +288,8 @@ void LLSceneView::draw() total_visible += tri_count; } - std::string label = llformat("%s Object Triangle Counts (Ktris) -- [%.2f, %.2f] Mean: %.2f Median: %.2f Visible: %.2f/%.2f", - category[idx], tri_domain[0]/1024.f, tri_domain[1]/1024.f, (total/count)/1024.f, triangles[idx][count/2]/1024.f, total_visible_triangles[idx]/1024.f, total_triangles[idx]/1024.f); + std::string label = llformat("%s Object Triangle Counts (Ktris) -- Visible: %.2f/%.2f (%.2f KB Visible)", + category[idx], total_visible_triangles[idx]/1024.f, total_triangles[idx]/1024.f, total_visible_bytes[idx]/1024.f); LLFontGL::getFontMonospace()->renderUTF8(label, 0 , tri_rect.mLeft, tri_rect.mTop+margin, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP); diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp index bccabe21a8..66df7dae3e 100644 --- a/indra/newview/llsurface.cpp +++ b/indra/newview/llsurface.cpp @@ -334,6 +334,17 @@ void LLSurface::setOriginGlobal(const LLVector3d &origin_global) } } +void LLSurface::getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegions ) +{ + S32 i; + for (i = 0; i < 8; i++) + { + if ( mNeighbors[i] != NULL ) + { + uniqueRegions.push_back( mNeighbors[i]->getRegion() ); + } + } +} void LLSurface::connectNeighbor(LLSurface *neighborp, U32 direction) { diff --git a/indra/newview/llsurface.h b/indra/newview/llsurface.h index 673ee83fe3..a4ef4fe2de 100644 --- a/indra/newview/llsurface.h +++ b/indra/newview/llsurface.h @@ -140,6 +140,9 @@ public: friend class LLSurfacePatch; friend std::ostream& operator<<(std::ostream &s, const LLSurface &S); + + void getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegions ); + public: // Number of grid points on one side of a region, including +1 buffer for // north and east edge. diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index a1c2c926af..f3b22eab40 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -129,12 +129,12 @@ // *NOTE: Please add files in alphabetical order to keep merges easy. -// handle secondlife:///app/floater/{NAME} URLs +// handle secondlife:///app/openfloater/{NAME} URLs class LLFloaterOpenHandler : public LLCommandHandler { public: // requires trusted browser to trigger - LLFloaterOpenHandler() : LLCommandHandler("floater", UNTRUSTED_THROTTLE) { } + LLFloaterOpenHandler() : LLCommandHandler("openfloater", UNTRUSTED_THROTTLE) { } bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web) diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 41d8b57f36..4bf5454905 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -60,6 +60,7 @@ #include "llfloatersnapshot.h" #include "llfloatertools.h" #include "llfloaterworldmap.h" +#include "llfloaterbuildoptions.h" #include "llavataractions.h" #include "lllandmarkactions.h" #include "llgroupmgr.h" @@ -7159,9 +7160,11 @@ class LLToolsUseSelectionForGrid : public view_listener_t } func; LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func); LLSelectMgr::getInstance()->setGridMode(GRID_MODE_REF_OBJECT); - if (gFloaterTools) + + LLFloaterBuildOptions* build_options_floater = LLFloaterReg::getTypedInstance<LLFloaterBuildOptions>("build_options"); + if (build_options_floater && build_options_floater->getVisible()) { - gFloaterTools->mComboGridMode->setCurrentByIndex((S32)GRID_MODE_REF_OBJECT); + build_options_floater->setGridMode(GRID_MODE_REF_OBJECT); } return true; } diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index f6b01e92cb..729f69ec3f 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -936,7 +936,6 @@ protected: //one global instance to bind them LLOpenTaskOffer* gNewInventoryObserver=NULL; - class LLNewInventoryHintObserver : public LLInventoryAddedObserver { protected: @@ -946,6 +945,8 @@ protected: } }; +LLNewInventoryHintObserver* gNewInventoryHintObserver=NULL; + void start_new_inventory_observer() { if (!gNewInventoryObserver) //task offer observer @@ -962,7 +963,12 @@ void start_new_inventory_observer() gInventory.addObserver(gInventoryMoveObserver); } - gInventory.addObserver(new LLNewInventoryHintObserver()); + if (!gNewInventoryHintObserver) + { + // Observer is deleted by gInventory + gNewInventoryHintObserver = new LLNewInventoryHintObserver(); + gInventory.addObserver(gNewInventoryHintObserver); + } } class LLDiscardAgentOffer : public LLInventoryFetchItemsObserver diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index be9ff872c0..c3a7d345f5 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -519,7 +519,6 @@ void LLViewerObject::setNameValueList(const std::string& name_value_list) } } - // This method returns true if the object is over land owned by the // agent. bool LLViewerObject::isReturnable() @@ -528,17 +527,106 @@ bool LLViewerObject::isReturnable() { return false; } + std::vector<LLBBox> boxes; boxes.push_back(LLBBox(getPositionRegion(), getRotationRegion(), getScale() * -0.5f, getScale() * 0.5f).getAxisAligned()); for (child_list_t::iterator iter = mChildList.begin(); iter != mChildList.end(); iter++) { LLViewerObject* child = *iter; - boxes.push_back(LLBBox(child->getPositionRegion(), child->getRotationRegion(), child->getScale() * -0.5f, child->getScale() * 0.5f).getAxisAligned()); + boxes.push_back( LLBBox(child->getPositionRegion(), child->getRotationRegion(), child->getScale() * -0.5f, child->getScale() * 0.5f).getAxisAligned()); + } + + bool result = (mRegionp && mRegionp->objectIsReturnable(getPositionRegion(), boxes)) ? 1 : 0; + + if ( !result ) + { + //Get list of neighboring regions relative to this vo's region + std::vector<LLViewerRegion*> uniqueRegions; + mRegionp->getNeighboringRegions( uniqueRegions ); + + //Build aabb's - for root and all children + std::vector<PotentialReturnableObject> returnables; + typedef std::vector<LLViewerRegion*>::iterator RegionIt; + RegionIt regionStart = uniqueRegions.begin(); + RegionIt regionEnd = uniqueRegions.end(); + + for (; regionStart != regionEnd; ++regionStart ) + { + LLViewerRegion* pTargetRegion = *regionStart; + //Add the root vo as there may be no children and we still want + //to test for any edge overlap + buildReturnablesForChildrenVO( returnables, this, pTargetRegion ); + //Add it's children + for (child_list_t::iterator iter = mChildList.begin(); iter != mChildList.end(); iter++) + { + LLViewerObject* pChild = *iter; + buildReturnablesForChildrenVO( returnables, pChild, pTargetRegion ); + } + } + + //TBD#Eventually create a region -> box list map + typedef std::vector<PotentialReturnableObject>::iterator ReturnablesIt; + ReturnablesIt retCurrentIt = returnables.begin(); + ReturnablesIt retEndIt = returnables.end(); + + for ( ; retCurrentIt !=retEndIt; ++retCurrentIt ) + { + boxes.clear(); + LLViewerRegion* pRegion = (*retCurrentIt).pRegion; + boxes.push_back( (*retCurrentIt).box ); + bool retResult = (pRegion && pRegion->childrenObjectReturnable( boxes )) ? 1 : 0; + if ( retResult ) + { + result = true; + break; + } + } + } + return result; +} + +void LLViewerObject::buildReturnablesForChildrenVO( std::vector<PotentialReturnableObject>& returnables, LLViewerObject* pChild, LLViewerRegion* pTargetRegion ) +{ + if ( !pChild ) + { + llerrs<<"child viewerobject is NULL "<<llendl; + } + + constructAndAddReturnable( returnables, pChild, pTargetRegion ); + + //We want to handle any children VO's as well + for (child_list_t::iterator iter = pChild->mChildList.begin(); iter != pChild->mChildList.end(); iter++) + { + LLViewerObject* pChildofChild = *iter; + buildReturnablesForChildrenVO( returnables, pChildofChild, pTargetRegion ); } +} - return mRegionp - && mRegionp->objectIsReturnable(getPositionRegion(), boxes); +void LLViewerObject::constructAndAddReturnable( std::vector<PotentialReturnableObject>& returnables, LLViewerObject* pChild, LLViewerRegion* pTargetRegion ) +{ + + LLVector3 targetRegionPos; + targetRegionPos.setVec( pChild->getPositionGlobal() ); + + LLBBox childBBox = LLBBox( targetRegionPos, pChild->getRotationRegion(), pChild->getScale() * -0.5f, + pChild->getScale() * 0.5f).getAxisAligned(); + + LLVector3 edgeA = targetRegionPos + childBBox.getMinLocal(); + LLVector3 edgeB = targetRegionPos + childBBox.getMaxLocal(); + + LLVector3d edgeAd, edgeBd; + edgeAd.setVec(edgeA); + edgeBd.setVec(edgeB); + + //Only add the box when either of the extents are in a neighboring region + if ( pTargetRegion->pointInRegionGlobal( edgeAd ) || pTargetRegion->pointInRegionGlobal( edgeBd ) ) + { + PotentialReturnableObject returnableObj; + returnableObj.box = childBBox; + returnableObj.pRegion = pTargetRegion; + returnables.push_back( returnableObj ); + } } BOOL LLViewerObject::setParent(LLViewerObject* parent) diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index a0ad52df6b..f75a3d996d 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -44,11 +44,11 @@ #include "v3math.h" #include "llvertexbuffer.h" #include "llaccountingquota.h" +#include "llbbox.h" class LLAgent; // TODO: Get rid of this. class LLAudioSource; class LLAudioSourceVO; -class LLBBox; class LLDataPacker; class LLColor4; class LLFrameTimer; @@ -112,6 +112,12 @@ public: LLColor4 mColor; }; +struct PotentialReturnableObject +{ + LLBBox box; + LLViewerRegion* pRegion; +}; + //============================================================================ class LLViewerObject : public LLPrimitive, public LLRefCount, public LLGLUpdate @@ -234,6 +240,9 @@ public: // anti-encroachment is enabled bool isReturnable(); + void buildReturnablesForChildrenVO( std::vector<PotentialReturnableObject>& returnables, LLViewerObject* pChild, LLViewerRegion* pTargetRegion ); + void constructAndAddReturnable( std::vector<PotentialReturnableObject>& returnables, LLViewerObject* pChild, LLViewerRegion* pTargetRegion ); + /* // This method will scan through this object, and then query the // selection manager to see if the local agent probably has the diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp index 26765bdd01..eff16b6a6e 100644 --- a/indra/newview/llviewerparceloverlay.cpp +++ b/indra/newview/llviewerparceloverlay.cpp @@ -173,6 +173,33 @@ bool LLViewerParcelOverlay::encroachesOwned(const std::vector<LLBBox>& boxes) co } return false; } +bool LLViewerParcelOverlay::encroachesOnUnowned(const std::vector<LLBBox>& boxes) const +{ + // boxes are expected to already be axis aligned + for (U32 i = 0; i < boxes.size(); ++i) + { + LLVector3 min = boxes[i].getMinAgent(); + LLVector3 max = boxes[i].getMaxAgent(); + + S32 left = S32(llclamp((min.mV[VX] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1)); + S32 right = S32(llclamp((max.mV[VX] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1)); + S32 top = S32(llclamp((min.mV[VY] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1)); + S32 bottom = S32(llclamp((max.mV[VY] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1)); + + for (S32 row = top; row <= bottom; row++) + { + for (S32 column = left; column <= right; column++) + { + U8 type = ownership(row, column); + if ((PARCEL_SELF != type)) + { + return true; + } + } + } + } + return false; +} BOOL LLViewerParcelOverlay::isSoundLocal(const LLVector3& pos) const { diff --git a/indra/newview/llviewerparceloverlay.h b/indra/newview/llviewerparceloverlay.h index c80baedda6..3c6794e7d0 100644 --- a/indra/newview/llviewerparceloverlay.h +++ b/indra/newview/llviewerparceloverlay.h @@ -60,6 +60,7 @@ public: // might be in another parcel. for now, we simply test axis aligned // bounding boxes which isn't perfect, but is close bool encroachesOwned(const std::vector<LLBBox>& boxes) const; + bool encroachesOnUnowned(const std::vector<LLBBox>& boxes) const; BOOL isSoundLocal(const LLVector3& pos) const; diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 002e0567e4..85b4b60bf7 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1699,6 +1699,18 @@ bool LLViewerRegion::objectIsReturnable(const LLVector3& pos, const std::vector< && mParcelOverlay->encroachesOwned(boxes)) ); } +bool LLViewerRegion::childrenObjectReturnable( const std::vector<LLBBox>& boxes ) const +{ + bool result = false; + result = ( mParcelOverlay && mParcelOverlay->encroachesOnUnowned( boxes ) ) ? 1 : 0; + return result; +} + +void LLViewerRegion::getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegions ) +{ + mImpl->mLandp->getNeighboringRegions( uniqueRegions ); +} + void LLViewerRegion::showReleaseNotes() { std::string url = this->getCapability("ServerReleaseNotes"); diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index 3811b989e7..68662c99bd 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -318,6 +318,10 @@ public: LLSpatialPartition* getSpatialPartition(U32 type); bool objectIsReturnable(const LLVector3& pos, const std::vector<LLBBox>& boxes) const; + bool childrenObjectReturnable( const std::vector<LLBBox>& boxes ) const; + + void getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegions ); + public: struct CompareDistance { diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index b1441cc281..b2fd802ae7 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -528,8 +528,8 @@ public: addText(xpos,ypos, llformat("%s streaming cost: %.1f", label, cost)); ypos += y_inc; - addText(xpos, ypos, llformat(" %.1f KTris, %.1f/%.1f KB, %d objects", - count/1024.f, visible_bytes/1024.f, total_bytes/1024.f, object_count)); + addText(xpos, ypos, llformat(" %.3f KTris, %.1f/%.1f KB, %d objects", + count/1000.f, visible_bytes/1024.f, total_bytes/1024.f, object_count)); ypos += y_inc; } @@ -3142,6 +3142,12 @@ void LLViewerWindow::updateLayout() //gMenuBarView->setItemVisible("BuildTools", gFloaterTools->getVisible()); } + LLFloaterBuildOptions* build_options_floater = LLFloaterReg::getTypedInstance<LLFloaterBuildOptions>("build_options"); + if (build_options_floater && build_options_floater->getVisible()) + { + build_options_floater->updateGridMode(); + } + // Always update console if(gConsole) { diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 8eda6346b0..27f3a26f83 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -1123,7 +1123,10 @@ void LLVOAvatar::initClass() // Process XML data // avatar_skeleton.xml - llassert(!sAvatarSkeletonInfo); + if (sAvatarSkeletonInfo) + { //this can happen if a login attempt failed + delete sAvatarSkeletonInfo; + } sAvatarSkeletonInfo = new LLVOAvatarSkeletonInfo; if (!sAvatarSkeletonInfo->parseXml(sSkeletonXMLTree.getRoot())) { diff --git a/indra/newview/skins/default/xui/en/floater_build_options.xml b/indra/newview/skins/default/xui/en/floater_build_options.xml index 56230e912c..c247a12e7a 100644 --- a/indra/newview/skins/default/xui/en/floater_build_options.xml +++ b/indra/newview/skins/default/xui/en/floater_build_options.xml @@ -2,27 +2,84 @@ <floater legacy_header_height="18" follows="right" - height="170" + height="198" layout="topleft" name="build options floater" help_topic="build_options_floater" save_rect="true" title="GRID OPTIONS" width="264"> + <floater.string + name="grid_screen_text"> + Screen + </floater.string> + <floater.string + name="grid_local_text"> + Local + </floater.string> + <floater.string + name="grid_world_text"> + World + </floater.string> + <floater.string + name="grid_reference_text"> + Reference + </floater.string> + <floater.string + name="grid_attachment_text"> + Attachment + </floater.string> + <text + type="string" + length="1" + follows="left|top" + height="16" + layout="topleft" + left="10" + tool_tip="Grid opacity" + name="grid_opacity_label" + top_pad="30" + width="123"> + Mode + </text> + <combo_box + height="23" + layout="topleft" + left_pad="9" + follows="left|top" + name="combobox grid mode" + tool_tip="Choose the type of grid ruler for positioning the object" + top_delta="-3" + width="108"> + <combo_box.item + label="World grid" + name="World" + value="World" /> + <combo_box.item + label="Local grid" + name="Local" + value="Local" /> + <combo_box.item + label="Reference grid" + name="Reference" + value="Reference" /> + <combo_box.commit_callback + function="GridOptions.gridMode"/> + </combo_box> <spinner control_name="GridResolution" follows="left|top" height="23" initial_value="1" - label="Grid Units (meters)" - label_width="160" + label="Units (meters)" + label_width="130" layout="topleft" left="10" max_val="5" min_val="0.01" name="GridResolution" - top="25" - width="230" /> + top_pad="4" + width="200" /> <spinner control_name="GridDrawSize" decimal_digits="1" @@ -30,15 +87,15 @@ height="23" increment="0.5" initial_value="5" - label="Grid Extents (meters)" - label_width="160" + label="Extents (meters)" + label_width="130" layout="topleft" left_delta="0" max_val="50" min_val="1" name="GridDrawSize" top_pad="0" - width="230" /> + width="200" /> <check_box control_name="GridSubUnit" height="16" 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 f58595b3c5..07958b762e 100644 --- a/indra/newview/skins/default/xui/en/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml @@ -1,7 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater can_close="true" can_drag_on_left="false" can_minimize="false" can_resize="true" height="550" min_height="550" min_width="620" - name="Model Preview" title="Upload Model" width="620"> + name="Model Preview" title="Upload Model" width="620" + help_topic="upload_model" > <string name="status_idle">Idle</string> <string name="status_parse_error">Dae parsing issue - see log for details.</string> diff --git a/indra/newview/skins/default/xui/en/floater_model_wizard.xml b/indra/newview/skins/default/xui/en/floater_model_wizard.xml index 8603682e3a..c3f7b70ca7 100644 --- a/indra/newview/skins/default/xui/en/floater_model_wizard.xml +++ b/indra/newview/skins/default/xui/en/floater_model_wizard.xml @@ -281,7 +281,7 @@ height="40" left="10" word_wrap="true"> -Advanced users familiar with 3d content creation tools may prefer to use the [secondlife:///app/floater/upload_model Advanced Mesh Import Window] . +Advanced users familiar with 3d content creation tools may prefer to use the [secondlife:///app/openfloater/upload_model Advanced Mesh Import Window] . </text> </panel> </panel> diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index 8b8f70b940..2169b5ccc3 100644 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -47,24 +47,12 @@ Click and drag to select land </floater.string> <floater.string - name="grid_screen_text"> - Screen + name="status_selectcount"> + [OBJ_COUNT] objects ( [PRIM_COUNT] prims[PE_STRING] ) selected </floater.string> <floater.string - name="grid_local_text"> - Local - </floater.string> - <floater.string - name="grid_world_text"> - World - </floater.string> - <floater.string - name="grid_reference_text"> - Reference - </floater.string> - <floater.string - name="grid_attachment_text"> - Attachment + name="status_selectprimequiv"> + , [SEL_WEIGHT] prim equivs </floater.string> <button follows="left|top" @@ -221,7 +209,7 @@ <radio_group follows="left|top" left="5" - top="59" + top="55" height="70" layout="topleft" name="edit_radio_group"> @@ -255,18 +243,18 @@ label="Edit linked" layout="topleft" name="checkbox edit linked parts" - top_pad="-10"> + top_pad="-18"> <check_box.commit_callback function="BuildTool.selectComponent"/> </check_box> <button follows="left|top" - height="23" + height="20" label="Link" - top_pad="2" + top="108" layout="topleft" - left="5" + left="143" name="link_btn" width="50"> <button.commit_callback @@ -274,7 +262,7 @@ </button> <button follows="left|top" - height="23" + height="20" label="Unlink" layout="topleft" left_pad="2" @@ -283,18 +271,6 @@ <button.commit_callback function="BuildTool.UnlinkObjects"/> </button> - <text - text_color="LtGray_50" - follows="top|left" - halign="left" - left_pad="3" - name="RenderingCost" - tool_tip="Shows the rendering cost calculated for this object" - top_delta="11" - type="string" - width="100"> - รพ: [COUNT] - </text> <check_box control_name="ScaleUniform" height="19" @@ -302,7 +278,7 @@ layout="topleft" left="143" name="checkbox uniform" - top="50" + top="48" width="20" /> <text height="19" @@ -324,53 +300,29 @@ layout="topleft" left="143" name="checkbox stretch textures" - top_pad="-6" + top_pad="-4" follows="left|top" width="134" /> <check_box control_name="SnapEnabled" height="18" initial_value="true" - label="Snap to grid" + label="Snap" layout="topleft" top_pad="0" name="checkbox snap to grid" width="134" /> - <combo_box - height="23" - layout="topleft" - follows="left|top" - name="combobox grid mode" - tool_tip="Choose the type of grid ruler for positioning the object" - top_pad="0" - width="108"> - <combo_box.item - label="World grid" - name="World" - value="World" /> - <combo_box.item - label="Local grid" - name="Local" - value="Local" /> - <combo_box.item - label="Reference grid" - name="Reference" - value="Reference" /> - <combo_box.commit_callback - function="BuildTool.gridMode"/> - </combo_box> <button left_pad="0" - image_selected="ForwardArrow_Press" - image_unselected="ForwardArrow_Off" + label="Options..." layout="topleft" follows="top|left" name="Options..." tool_tip="See more grid options" - top_pad="-22" - right="-10" - width="18" - height="23" > + top="83" + right="-35" + width="65" + height="21" > <button.commit_callback function="BuildTool.gridOptions"/> </button> @@ -385,7 +337,7 @@ left="10" name="ToolCube" tool_tip="Cube" - top="51" + top="58" width="20" /> <button follows="left|top" @@ -447,10 +399,10 @@ image_selected="Object_Hemi_Cylinder_Selected" image_unselected="Object_Hemi_Cylinder" layout="topleft" - left_delta="29" + left="10" name="ToolHemiCylinder" tool_tip="Hemicylinder" - top_delta="0" + top="84" width="20" /> <button follows="left|top" @@ -515,7 +467,7 @@ left="10" name="ToolTorus" tool_tip="Torus" - top="77" + top="109" width="20" /> <button follows="left|top" @@ -575,9 +527,9 @@ height="19" label="Keep Tool selected" layout="topleft" - left="4" + left="155" name="checkbox sticky" - top="101" + top="55" width="128" /> <check_box control_name="CreateToolCopySelection" @@ -596,7 +548,7 @@ layout="topleft" left_delta="18" name="checkbox copy centers" - top="132" + top="85" width="134" /> <check_box control_name="CreateToolCopyRotates" @@ -749,89 +701,49 @@ <button.commit_callback function="BuildTool.applyToSelection"/> </button> + <text + text_color="LtGray_50" + type="string" + length="1" + height="16" + follows="left|top" + font="SansSerifSmall" + layout="topleft" + left="10" + name="selection_empty" + top_pad="0" + width="100"> + Nothing selected. + </text> <text text_color="LtGray_50" type="string" length="1" - height="10" + height="16" follows="left|top" - halign="right" + font="SansSerifSmall" layout="topleft" - right="-10" - name="obj_count" - top_pad="5" - width="143"> - Objects: [COUNT] + left="10" + name="selection_count" + top_delta="0" + visible="false" + width="280"> </text> <text - text_color="LtGray_50" - type="string" - length="1" - height="10" - follows="left|top" - halign="right" - layout="topleft" - right="-10" - name="prim_count" - width="143"> - Prims: [COUNT] + text_color="LtGray_50" + type="string" + length="1" + height="16" + follows="left|top" + font="SansSerifSmall" + layout="topleft" + left="10" + name="selection_weight" + top_pad="0" + visible="false" + width="280"> + Physics weight [PHYS_WEIGHT], Render Cost [DISP_WEIGHT]. </text> - <text - text_color="LtGray_50" - type="string" - length="1" - height="10" - follows="left|top" - halign="right" - layout="topleft" - right="-120" - name="linked_set_count" - top="144" - width="80"> - Linked Sets: [COUNT] - </text> - <text - text_color="LtGray_50" - type="string" - length="1" - height="10" - follows="left|top" - halign="right" - layout="topleft" - top_delta="0" - right="-8" - name="linked_set_cost" - tool_tip="Cost of currently selected linked sets as [prims],[physics complexity]" - width="80"> - Cost: [COST] / [PHYSICS] - </text> - <text - text_color="LtGray_50" - type="string" - length="1" - follows="left|top" - halign="right" - layout="topleft" - top_pad="5" - right="-120" - name="object_count" - width="80"> - Objects: [COUNT] - </text> - <text - text_color="LtGray_50" - type="string" - length="1" - follows="left|top" - halign="right" - layout="topleft" - top_delta="0" - right="-8" - name="object_cost" - tool_tip="Cost of currently selected objects as [prims] / [physics complexity]" - width="80"> - Cost: [COST] / [PHYSICS] - </text> <!-- <text --> <!-- text_color="LtGray_50" --> <!-- type="string" --> @@ -858,6 +770,15 @@ <!-- width="143"> --> <!-- Prims: [COUNT] --> <!-- </text> --> + <view_border + bevel_style="none" + follows="top|left" + height="0" + layout="topleft" + left="6" + name="cost_text_border" + top="135" + width="282"/> <tab_container follows="left|top" height="410" |