diff options
Diffstat (limited to 'indra/llprimitive')
37 files changed, 7470 insertions, 7470 deletions
diff --git a/indra/llprimitive/legacy_object_types.h b/indra/llprimitive/legacy_object_types.h index 697ad584a5..b6ef8eddc2 100644 --- a/indra/llprimitive/legacy_object_types.h +++ b/indra/llprimitive/legacy_object_types.h @@ -1,25 +1,25 @@ -/** +/** * @file legacy_object_types.h * @brief Byte codes for basic object and primitive types * * $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$ */ @@ -27,51 +27,51 @@ #ifndef LL_LEGACY_OBJECT_TYPES_H #define LL_LEGACY_OBJECT_TYPES_H -const S8 PLAYER = 'c'; -//const S8 BASIC_SHOT = 's'; -//const S8 BIG_SHOT = 'S'; -//const S8 TREE_SHOT = 'g'; -//const S8 PHYSICAL_BALL = 'b'; +const S8 PLAYER = 'c'; +//const S8 BASIC_SHOT = 's'; +//const S8 BIG_SHOT = 'S'; +//const S8 TREE_SHOT = 'g'; +//const S8 PHYSICAL_BALL = 'b'; -const S8 TREE = 'T'; -const S8 TREE_NEW = 'R'; -//const S8 SPARK = 'p'; -//const S8 SMOKE = 'q'; -//const S8 BOX = 'x'; -//const S8 CYLINDER = 'y'; -//const S8 CONE = 'o'; -//const S8 SPHERE = 'h'; -//const S8 BIRD = 'r'; // ascii 114 -//const S8 ATOR = 'a'; -//const S8 ROCK = 'k'; +const S8 TREE = 'T'; +const S8 TREE_NEW = 'R'; +//const S8 SPARK = 'p'; +//const S8 SMOKE = 'q'; +//const S8 BOX = 'x'; +//const S8 CYLINDER = 'y'; +//const S8 CONE = 'o'; +//const S8 SPHERE = 'h'; +//const S8 BIRD = 'r'; // ascii 114 +//const S8 ATOR = 'a'; +//const S8 ROCK = 'k'; -const S8 GRASS = 'd'; +const S8 GRASS = 'd'; const S8 PART_SYS = 'P'; -//const S8 ORACLE = 'O'; -//const S8 TEXTBUBBLE = 't'; // Text bubble to show communication -//const S8 DEMON = 'M'; // Maxwell's demon for scarfing legacy_object_types.h -//const S8 CUBE = 'f'; -//const S8 LSL_TEST = 'L'; -//const S8 PRISM = '1'; -//const S8 PYRAMID = '2'; -//const S8 TETRAHEDRON = '3'; -//const S8 HALF_CYLINDER = '4'; -//const S8 HALF_CONE = '5'; -//const S8 HALF_SPHERE = '6'; +//const S8 ORACLE = 'O'; +//const S8 TEXTBUBBLE = 't'; // Text bubble to show communication +//const S8 DEMON = 'M'; // Maxwell's demon for scarfing legacy_object_types.h +//const S8 CUBE = 'f'; +//const S8 LSL_TEST = 'L'; +//const S8 PRISM = '1'; +//const S8 PYRAMID = '2'; +//const S8 TETRAHEDRON = '3'; +//const S8 HALF_CYLINDER = '4'; +//const S8 HALF_CONE = '5'; +//const S8 HALF_SPHERE = '6'; -const S8 PRIMITIVE_VOLUME = 'v'; +const S8 PRIMITIVE_VOLUME = 'v'; -// Misc constants +// Misc constants -//const F32 AVATAR_RADIUS = 0.5f; -//const F32 SHOT_RADIUS = 0.05f; -//const F32 BIG_SHOT_RADIUS = 0.05f; -//const F32 TREE_SIZE = 5.f; -//const F32 BALL_SIZE = 4.f; +//const F32 AVATAR_RADIUS = 0.5f; +//const F32 SHOT_RADIUS = 0.05f; +//const F32 BIG_SHOT_RADIUS = 0.05f; +//const F32 TREE_SIZE = 5.f; +//const F32 BALL_SIZE = 4.f; -//const F32 SHOT_VELOCITY = 100.f; -//const F32 GRENADE_BLAST_RADIUS = 5.f; +//const F32 SHOT_VELOCITY = 100.f; +//const F32 GRENADE_BLAST_RADIUS = 5.f; #endif diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index 2c357e1ac5..e8b586fdf1 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -63,88 +63,88 @@ #include <boost/regex.hpp> #include <boost/algorithm/string/replace.hpp> -std::string colladaVersion[VERSIONTYPE_COUNT+1] = +std::string colladaVersion[VERSIONTYPE_COUNT+1] = { - "1.4.0", - "1.4.1", - "Unsupported" + "1.4.0", + "1.4.1", + "Unsupported" }; static const std::string lod_suffix[LLModel::NUM_LODS] = { - "_LOD0", - "_LOD1", - "_LOD2", - "", - "_PHYS", + "_LOD0", + "_LOD1", + "_LOD2", + "", + "_PHYS", }; const U32 LIMIT_MATERIALS_OUTPUT = 12; 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) + domSource* &pos_source, domSource* &tc_source, domSource* &norm_source) { - idx_stride = 0; - - for (U32 j = 0; j < inputs.getCount(); ++j) - { - idx_stride = llmax((S32) inputs[j]->getOffset(), idx_stride); - - 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(); - if ( !vertices ) - { - return false; - } - - domInputLocal_Array& v_inp = vertices->getInput_array(); - - - for (U32 k = 0; k < v_inp.getCount(); ++k) - { - if (strcmp(COMMON_PROFILE_INPUT_POSITION, v_inp[k]->getSemantic()) == 0) - { - pos_offset = inputs[j]->getOffset(); - - const domURIFragmentType& uri = v_inp[k]->getSource(); - daeElementRef elem = uri.getElement(); - pos_source = (domSource*) elem.cast(); - } - - if (strcmp(COMMON_PROFILE_INPUT_NORMAL, v_inp[k]->getSemantic()) == 0) - { - norm_offset = inputs[j]->getOffset(); - - const domURIFragmentType& uri = v_inp[k]->getSource(); - daeElementRef elem = uri.getElement(); - norm_source = (domSource*) elem.cast(); - } - } - } - - if (strcmp(COMMON_PROFILE_INPUT_NORMAL, inputs[j]->getSemantic()) == 0) - { - //found normal array for this triangle list - norm_offset = inputs[j]->getOffset(); - const domURIFragmentType& uri = inputs[j]->getSource(); - daeElementRef elem = uri.getElement(); - norm_source = (domSource*) elem.cast(); - } - else if (strcmp(COMMON_PROFILE_INPUT_TEXCOORD, inputs[j]->getSemantic()) == 0) - { //found texCoords - tc_offset = inputs[j]->getOffset(); - const domURIFragmentType& uri = inputs[j]->getSource(); - daeElementRef elem = uri.getElement(); - tc_source = (domSource*) elem.cast(); - } - } - - idx_stride += 1; - - return true; + idx_stride = 0; + + for (U32 j = 0; j < inputs.getCount(); ++j) + { + idx_stride = llmax((S32) inputs[j]->getOffset(), idx_stride); + + 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(); + if ( !vertices ) + { + return false; + } + + domInputLocal_Array& v_inp = vertices->getInput_array(); + + + for (U32 k = 0; k < v_inp.getCount(); ++k) + { + if (strcmp(COMMON_PROFILE_INPUT_POSITION, v_inp[k]->getSemantic()) == 0) + { + pos_offset = inputs[j]->getOffset(); + + const domURIFragmentType& uri = v_inp[k]->getSource(); + daeElementRef elem = uri.getElement(); + pos_source = (domSource*) elem.cast(); + } + + if (strcmp(COMMON_PROFILE_INPUT_NORMAL, v_inp[k]->getSemantic()) == 0) + { + norm_offset = inputs[j]->getOffset(); + + const domURIFragmentType& uri = v_inp[k]->getSource(); + daeElementRef elem = uri.getElement(); + norm_source = (domSource*) elem.cast(); + } + } + } + + if (strcmp(COMMON_PROFILE_INPUT_NORMAL, inputs[j]->getSemantic()) == 0) + { + //found normal array for this triangle list + norm_offset = inputs[j]->getOffset(); + const domURIFragmentType& uri = inputs[j]->getSource(); + daeElementRef elem = uri.getElement(); + norm_source = (domSource*) elem.cast(); + } + else if (strcmp(COMMON_PROFILE_INPUT_TEXCOORD, inputs[j]->getSemantic()) == 0) + { //found texCoords + tc_offset = inputs[j]->getOffset(); + const domURIFragmentType& uri = inputs[j]->getSource(); + daeElementRef elem = uri.getElement(); + tc_source = (domSource*) elem.cast(); + } + } + + idx_stride += 1; + + return true; } LLModel::EModelStatus load_face_from_dom_triangles( @@ -153,59 +153,59 @@ LLModel::EModelStatus load_face_from_dom_triangles( domTrianglesRef& tri, LLSD& log_msg) { - LLVolumeFace face; - std::vector<LLVolumeFace::VertexData> verts; - std::vector<U16> indices; - - const domInputLocalOffset_Array& inputs = tri->getInput_array(); + LLVolumeFace face; + std::vector<LLVolumeFace::VertexData> verts; + std::vector<U16> indices; + + const domInputLocalOffset_Array& inputs = tri->getInput_array(); - S32 pos_offset = -1; - S32 tc_offset = -1; - S32 norm_offset = -1; + S32 pos_offset = -1; + S32 tc_offset = -1; + S32 norm_offset = -1; - domSource* pos_source = NULL; - domSource* tc_source = NULL; - domSource* norm_source = NULL; + domSource* pos_source = NULL; + domSource* tc_source = NULL; + domSource* norm_source = NULL; - S32 idx_stride = 0; + S32 idx_stride = 0; - if ( !get_dom_sources(inputs, pos_offset, tc_offset, norm_offset, idx_stride, pos_source, tc_source, norm_source)) - { + if ( !get_dom_sources(inputs, pos_offset, tc_offset, norm_offset, idx_stride, pos_source, tc_source, norm_source)) + { LLSD args; args["Message"] = "ParsingErrorBadElement"; log_msg.append(args); - return LLModel::BAD_ELEMENT; - } + return LLModel::BAD_ELEMENT; + } - if (!pos_source || !pos_source->getFloat_array()) - { - LL_WARNS() << "Unable to process mesh without position data; invalid model; invalid model." << LL_ENDL; + if (!pos_source || !pos_source->getFloat_array()) + { + LL_WARNS() << "Unable to process mesh without position data; invalid model; invalid model." << LL_ENDL; LLSD args; args["Message"] = "ParsingErrorPositionInvalidModel"; log_msg.append(args); - return LLModel::BAD_ELEMENT; - } - - domPRef p = tri->getP(); - domListOfUInts& idx = p->getValue(); - - domListOfFloats dummy ; - domListOfFloats& v = pos_source ? pos_source->getFloat_array()->getValue() : dummy ; - domListOfFloats& tc = tc_source ? tc_source->getFloat_array()->getValue() : dummy ; - domListOfFloats& n = norm_source ? norm_source->getFloat_array()->getValue() : dummy ; - - if (pos_source) - { - if(v.getCount() == 0) - { - return LLModel::BAD_ELEMENT; - } - // VFExtents change - face.mExtents[0].set(v[0], v[1], v[2]); - face.mExtents[1].set(v[0], v[1], v[2]); - } - - LLVolumeFace::VertexMapData::PointMap point_map; + return LLModel::BAD_ELEMENT; + } + + domPRef p = tri->getP(); + domListOfUInts& idx = p->getValue(); + + domListOfFloats dummy ; + domListOfFloats& v = pos_source ? pos_source->getFloat_array()->getValue() : dummy ; + domListOfFloats& tc = tc_source ? tc_source->getFloat_array()->getValue() : dummy ; + domListOfFloats& n = norm_source ? norm_source->getFloat_array()->getValue() : dummy ; + + if (pos_source) + { + if(v.getCount() == 0) + { + return LLModel::BAD_ELEMENT; + } + // VFExtents change + face.mExtents[0].set(v[0], v[1], v[2]); + face.mExtents[1].set(v[0], v[1], v[2]); + } + + LLVolumeFace::VertexMapData::PointMap point_map; if (idx_stride <= 0 || (pos_source && pos_offset >= idx_stride) @@ -217,152 +217,152 @@ LLModel::EModelStatus load_face_from_dom_triangles( LL_WARNS() << "Invalid pos_offset " << pos_offset << ", tc_offset " << tc_offset << " or norm_offset " << norm_offset << LL_ENDL; return LLModel::BAD_ELEMENT; } - - for (U32 i = 0; i < idx.getCount(); i += idx_stride) - { - LLVolumeFace::VertexData cv; - if (pos_source) - { - cv.setPosition(LLVector4a(v[idx[i+pos_offset]*3+0], - v[idx[i+pos_offset]*3+1], - v[idx[i+pos_offset]*3+2])); - } - - if (tc_source) - { - 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; - - LLVolumeFace::VertexMapData::PointMap::iterator point_iter; - point_iter = point_map.find(LLVector3(cv.getPosition().getF32ptr())); - - if (point_iter != point_map.end()) - { - for (U32 j = 0; j < point_iter->second.size(); ++j) - { - // We have a matching loc - // - if ((point_iter->second)[j] == cv) - { - U16 shared_index = (point_iter->second)[j].mIndex; - - // Don't share verts within the same tri, degenerate - // + + for (U32 i = 0; i < idx.getCount(); i += idx_stride) + { + LLVolumeFace::VertexData cv; + if (pos_source) + { + cv.setPosition(LLVector4a(v[idx[i+pos_offset]*3+0], + v[idx[i+pos_offset]*3+1], + v[idx[i+pos_offset]*3+2])); + } + + if (tc_source) + { + 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; + + LLVolumeFace::VertexMapData::PointMap::iterator point_iter; + point_iter = point_map.find(LLVector3(cv.getPosition().getF32ptr())); + + if (point_iter != point_map.end()) + { + for (U32 j = 0; j < point_iter->second.size(); ++j) + { + // We have a matching loc + // + if ((point_iter->second)[j] == cv) + { + U16 shared_index = (point_iter->second)[j].mIndex; + + // Don't share verts within the same tri, degenerate + // U32 indx_size = indices.size(); U32 verts_new_tri = indx_size % 3; if ((verts_new_tri < 1 || indices[indx_size - 1] != shared_index) && (verts_new_tri < 2 || indices[indx_size - 2] != shared_index)) - { - found = true; - indices.push_back(shared_index); - } - break; - } - } - } - - if (!found) - { - // VFExtents change - update_min_max(face.mExtents[0], face.mExtents[1], cv.getPosition()); - verts.push_back(cv); - if (verts.size() >= 65535) - { - //llerrs << "Attempted to write model exceeding 16-bit index buffer limitation." << LL_ENDL; - return LLModel::VERTEX_NUMBER_OVERFLOW ; - } - U16 index = (U16) (verts.size()-1); - indices.push_back(index); - - LLVolumeFace::VertexMapData d; - d.setPosition(cv.getPosition()); - d.mTexCoord = cv.mTexCoord; - d.setNormal(cv.getNormal()); - d.mIndex = index; - if (point_iter != point_map.end()) - { - point_iter->second.push_back(d); - } - else - { - point_map[LLVector3(d.getPosition().getF32ptr())].push_back(d); - } - } - - if (indices.size()%3 == 0 && verts.size() >= 65532) - { - std::string material; - - if (tri->getMaterial()) - { - material = std::string(tri->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; - } - - face = LLVolumeFace(); - // VFExtents change - face.mExtents[0].set(v[0], v[1], v[2]); - face.mExtents[1].set(v[0], v[1], v[2]); + { + found = true; + indices.push_back(shared_index); + } + break; + } + } + } + + if (!found) + { + // VFExtents change + update_min_max(face.mExtents[0], face.mExtents[1], cv.getPosition()); + verts.push_back(cv); + if (verts.size() >= 65535) + { + //llerrs << "Attempted to write model exceeding 16-bit index buffer limitation." << LL_ENDL; + return LLModel::VERTEX_NUMBER_OVERFLOW ; + } + U16 index = (U16) (verts.size()-1); + indices.push_back(index); + + LLVolumeFace::VertexMapData d; + d.setPosition(cv.getPosition()); + d.mTexCoord = cv.mTexCoord; + d.setNormal(cv.getNormal()); + d.mIndex = index; + if (point_iter != point_map.end()) + { + point_iter->second.push_back(d); + } + else + { + point_map[LLVector3(d.getPosition().getF32ptr())].push_back(d); + } + } + + if (indices.size()%3 == 0 && verts.size() >= 65532) + { + std::string material; + + if (tri->getMaterial()) + { + material = std::string(tri->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; + } + + face = LLVolumeFace(); + // VFExtents change + face.mExtents[0].set(v[0], v[1], v[2]); + face.mExtents[1].set(v[0], v[1], v[2]); verts.clear(); indices.clear(); point_map.clear(); - } - } - - if (!verts.empty()) - { - std::string material; - - if (tri->getMaterial()) - { - material = std::string(tri->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 ; + } + } + + if (!verts.empty()) + { + std::string material; + + if (tri->getMaterial()) + { + material = std::string(tri->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 ; } LLModel::EModelStatus load_face_from_dom_polylist( @@ -371,534 +371,534 @@ LLModel::EModelStatus load_face_from_dom_polylist( domPolylistRef& poly, LLSD& log_msg) { - domPRef p = poly->getP(); - domListOfUInts& idx = p->getValue(); + domPRef p = poly->getP(); + domListOfUInts& idx = p->getValue(); + + if (idx.getCount() == 0) + { + return LLModel::NO_ERRORS ; + } - if (idx.getCount() == 0) - { - return LLModel::NO_ERRORS ; - } + const domInputLocalOffset_Array& inputs = poly->getInput_array(); - const domInputLocalOffset_Array& inputs = poly->getInput_array(); + domListOfUInts& vcount = poly->getVcount()->getValue(); - domListOfUInts& vcount = poly->getVcount()->getValue(); - - S32 pos_offset = -1; - S32 tc_offset = -1; - S32 norm_offset = -1; + S32 pos_offset = -1; + S32 tc_offset = -1; + S32 norm_offset = -1; - domSource* pos_source = NULL; - domSource* tc_source = NULL; - domSource* norm_source = NULL; + domSource* pos_source = NULL; + domSource* tc_source = NULL; + domSource* norm_source = NULL; - S32 idx_stride = 0; + S32 idx_stride = 0; - if (!get_dom_sources(inputs, pos_offset, tc_offset, norm_offset, idx_stride, pos_source, tc_source, norm_source)) - { + if (!get_dom_sources(inputs, pos_offset, tc_offset, norm_offset, idx_stride, pos_source, tc_source, norm_source)) + { LL_WARNS() << "Bad element." << LL_ENDL; LLSD args; args["Message"] = "ParsingErrorBadElement"; log_msg.append(args); - return LLModel::BAD_ELEMENT; - } - - LLVolumeFace face; - - std::vector<U16> indices; - std::vector<LLVolumeFace::VertexData> verts; - - domListOfFloats v; - domListOfFloats tc; - domListOfFloats n; - - if (pos_source) - { - v = pos_source->getFloat_array()->getValue(); - // VFExtents change - face.mExtents[0].set(v[0], v[1], v[2]); - face.mExtents[1].set(v[0], v[1], v[2]); - } - - if (tc_source) - { - tc = tc_source->getFloat_array()->getValue(); - } - - if (norm_source) - { - n = norm_source->getFloat_array()->getValue(); - } - - LLVolumeFace::VertexMapData::PointMap point_map; - - U32 cur_idx = 0; - bool log_tc_msg = true; - for (U32 i = 0; i < vcount.getCount(); ++i) - { //for each polygon - U32 first_index = 0; - U32 last_index = 0; - for (U32 j = 0; j < vcount[i]; ++j) - { //for each vertex - - LLVolumeFace::VertexData cv; - - if (pos_source) - { - cv.getPosition().set(v[idx[cur_idx+pos_offset]*3+0], - v[idx[cur_idx+pos_offset]*3+1], - v[idx[cur_idx+pos_offset]*3+2]); - if (!cv.getPosition().isFinite3()) - { - LL_WARNS() << "Found NaN while loading position data from DAE-Model, invalid model." << LL_ENDL; + return LLModel::BAD_ELEMENT; + } + + LLVolumeFace face; + + std::vector<U16> indices; + std::vector<LLVolumeFace::VertexData> verts; + + domListOfFloats v; + domListOfFloats tc; + domListOfFloats n; + + if (pos_source) + { + v = pos_source->getFloat_array()->getValue(); + // VFExtents change + face.mExtents[0].set(v[0], v[1], v[2]); + face.mExtents[1].set(v[0], v[1], v[2]); + } + + if (tc_source) + { + tc = tc_source->getFloat_array()->getValue(); + } + + if (norm_source) + { + n = norm_source->getFloat_array()->getValue(); + } + + LLVolumeFace::VertexMapData::PointMap point_map; + + U32 cur_idx = 0; + bool log_tc_msg = true; + for (U32 i = 0; i < vcount.getCount(); ++i) + { //for each polygon + U32 first_index = 0; + U32 last_index = 0; + for (U32 j = 0; j < vcount[i]; ++j) + { //for each vertex + + LLVolumeFace::VertexData cv; + + if (pos_source) + { + cv.getPosition().set(v[idx[cur_idx+pos_offset]*3+0], + v[idx[cur_idx+pos_offset]*3+1], + v[idx[cur_idx+pos_offset]*3+2]); + if (!cv.getPosition().isFinite3()) + { + LL_WARNS() << "Found NaN while loading position data from DAE-Model, invalid model." << LL_ENDL; LLSD args; args["Message"] = "PositionNaN"; log_msg.append(args); - return LLModel::BAD_ELEMENT; - } - } - - if (tc_source) - { - U64 idx_x = idx[cur_idx + tc_offset] * 2 + 0; - U64 idx_y = idx[cur_idx + tc_offset] * 2 + 1; - - if (idx_y < tc.getCount()) - { - cv.mTexCoord.setVec(tc[idx_x], tc[idx_y]); - } - else if (log_tc_msg) - { - log_tc_msg = false; - LL_WARNS() << "Texture coordinates data is not complete." << LL_ENDL; - LLSD args; - args["Message"] = "IncompleteTC"; - log_msg.append(args); - } - } - - 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]); - - if (!cv.getNormal().isFinite3()) - { - LL_WARNS() << "Found NaN while loading normals from DAE-Model, invalid model." << LL_ENDL; + return LLModel::BAD_ELEMENT; + } + } + + if (tc_source) + { + U64 idx_x = idx[cur_idx + tc_offset] * 2 + 0; + U64 idx_y = idx[cur_idx + tc_offset] * 2 + 1; + + if (idx_y < tc.getCount()) + { + cv.mTexCoord.setVec(tc[idx_x], tc[idx_y]); + } + else if (log_tc_msg) + { + log_tc_msg = false; + LL_WARNS() << "Texture coordinates data is not complete." << LL_ENDL; + LLSD args; + args["Message"] = "IncompleteTC"; + log_msg.append(args); + } + } + + 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]); + + if (!cv.getNormal().isFinite3()) + { + LL_WARNS() << "Found NaN while loading normals from DAE-Model, invalid model." << LL_ENDL; LLSD args; args["Message"] = "NormalsNaN"; log_msg.append(args); - return LLModel::BAD_ELEMENT; - } - } - - cur_idx += idx_stride; - - BOOL found = FALSE; - - LLVolumeFace::VertexMapData::PointMap::iterator point_iter; - LLVector3 pos3(cv.getPosition().getF32ptr()); - point_iter = point_map.find(pos3); - - if (point_iter != point_map.end()) - { - for (U32 k = 0; k < point_iter->second.size(); ++k) - { - if ((point_iter->second)[k] == cv) - { - found = TRUE; - U32 index = (point_iter->second)[k].mIndex; - if (j == 0) - { - first_index = index; - } - else if (j == 1) - { - last_index = index; - } - else - { - // if these are the same, we have a very, very skinny triangle (coincident verts on one or more edges) - // - llassert((first_index != last_index) && (last_index != index) && (first_index != index)); - indices.push_back(first_index); - indices.push_back(last_index); - indices.push_back(index); - last_index = index; - } - - break; - } - } - } - - if (!found) - { - // VFExtents change - update_min_max(face.mExtents[0], face.mExtents[1], cv.getPosition()); - verts.push_back(cv); - if (verts.size() >= 65535) - { - //llerrs << "Attempted to write model exceeding 16-bit index buffer limitation." << LL_ENDL; - return LLModel::VERTEX_NUMBER_OVERFLOW ; - } - U16 index = (U16) (verts.size()-1); - - if (j == 0) - { - first_index = index; - } - else if (j == 1) - { - last_index = index; - } - else - { - // detect very skinny degenerate triangles with collapsed edges - // - llassert((first_index != last_index) && (last_index != index) && (first_index != index)); - indices.push_back(first_index); - indices.push_back(last_index); - indices.push_back(index); - last_index = index; - } - - LLVolumeFace::VertexMapData d; - d.setPosition(cv.getPosition()); - d.mTexCoord = cv.mTexCoord; - d.setNormal(cv.getNormal()); - d.mIndex = index; - if (point_iter != point_map.end()) - { - point_iter->second.push_back(d); - } - else - { - point_map[pos3].push_back(d); - } - } - - if (indices.size()%3 == 0 && indices.size() >= 65532) - { - std::string material; - - if (poly->getMaterial()) - { - 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; - } - - face = LLVolumeFace(); - // VFExtents change - face.mExtents[0].set(v[0], v[1], v[2]); - face.mExtents[1].set(v[0], v[1], v[2]); - verts.clear(); - indices.clear(); - point_map.clear(); - } - } - } - - if (!verts.empty()) - { - std::string material; - - if (poly->getMaterial()) - { - 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 ; + return LLModel::BAD_ELEMENT; + } + } + + cur_idx += idx_stride; + + BOOL found = FALSE; + + LLVolumeFace::VertexMapData::PointMap::iterator point_iter; + LLVector3 pos3(cv.getPosition().getF32ptr()); + point_iter = point_map.find(pos3); + + if (point_iter != point_map.end()) + { + for (U32 k = 0; k < point_iter->second.size(); ++k) + { + if ((point_iter->second)[k] == cv) + { + found = TRUE; + U32 index = (point_iter->second)[k].mIndex; + if (j == 0) + { + first_index = index; + } + else if (j == 1) + { + last_index = index; + } + else + { + // if these are the same, we have a very, very skinny triangle (coincident verts on one or more edges) + // + llassert((first_index != last_index) && (last_index != index) && (first_index != index)); + indices.push_back(first_index); + indices.push_back(last_index); + indices.push_back(index); + last_index = index; + } + + break; + } + } + } + + if (!found) + { + // VFExtents change + update_min_max(face.mExtents[0], face.mExtents[1], cv.getPosition()); + verts.push_back(cv); + if (verts.size() >= 65535) + { + //llerrs << "Attempted to write model exceeding 16-bit index buffer limitation." << LL_ENDL; + return LLModel::VERTEX_NUMBER_OVERFLOW ; + } + U16 index = (U16) (verts.size()-1); + + if (j == 0) + { + first_index = index; + } + else if (j == 1) + { + last_index = index; + } + else + { + // detect very skinny degenerate triangles with collapsed edges + // + llassert((first_index != last_index) && (last_index != index) && (first_index != index)); + indices.push_back(first_index); + indices.push_back(last_index); + indices.push_back(index); + last_index = index; + } + + LLVolumeFace::VertexMapData d; + d.setPosition(cv.getPosition()); + d.mTexCoord = cv.mTexCoord; + d.setNormal(cv.getNormal()); + d.mIndex = index; + if (point_iter != point_map.end()) + { + point_iter->second.push_back(d); + } + else + { + point_map[pos3].push_back(d); + } + } + + if (indices.size()%3 == 0 && indices.size() >= 65532) + { + std::string material; + + if (poly->getMaterial()) + { + 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; + } + + face = LLVolumeFace(); + // VFExtents change + face.mExtents[0].set(v[0], v[1], v[2]); + face.mExtents[1].set(v[0], v[1], v[2]); + verts.clear(); + indices.clear(); + point_map.clear(); + } + } + } + + if (!verts.empty()) + { + std::string material; + + if (poly->getMaterial()) + { + 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 ; } LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& face_list, std::vector<std::string>& materials, domPolygonsRef& poly) { - LLVolumeFace face; - std::vector<U16> indices; - std::vector<LLVolumeFace::VertexData> verts; - - const domInputLocalOffset_Array& inputs = poly->getInput_array(); - - S32 v_offset = -1; - S32 n_offset = -1; - S32 t_offset = -1; - - domListOfFloats* v = NULL; - domListOfFloats* n = NULL; - domListOfFloats* t = NULL; - - U32 stride = 0; - for (U32 i = 0; i < inputs.getCount(); ++i) - { - stride = llmax((U32) inputs[i]->getOffset()+1, stride); - - if (strcmp(COMMON_PROFILE_INPUT_VERTEX, inputs[i]->getSemantic()) == 0) - { //found vertex array - v_offset = inputs[i]->getOffset(); - - const domURIFragmentType& uri = inputs[i]->getSource(); - daeElementRef elem = uri.getElement(); - domVertices* vertices = (domVertices*) elem.cast(); - if (!vertices) - { - return LLModel::BAD_ELEMENT; - } - domInputLocal_Array& v_inp = vertices->getInput_array(); - - 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) - { - return LLModel::BAD_ELEMENT; - } - v = &(src->getFloat_array()->getValue()); - } - } - } - else if (strcmp(COMMON_PROFILE_INPUT_NORMAL, inputs[i]->getSemantic()) == 0) - { - n_offset = inputs[i]->getOffset(); - //found normal array for this triangle list - const domURIFragmentType& uri = inputs[i]->getSource(); - daeElementRef elem = uri.getElement(); - domSource* src = (domSource*) elem.cast(); - if (!src) - { - return LLModel::BAD_ELEMENT; - } - n = &(src->getFloat_array()->getValue()); - } - else if (strcmp(COMMON_PROFILE_INPUT_TEXCOORD, inputs[i]->getSemantic()) == 0 && inputs[i]->getSet() == 0) - { //found texCoords - t_offset = inputs[i]->getOffset(); - const domURIFragmentType& uri = inputs[i]->getSource(); - daeElementRef elem = uri.getElement(); - domSource* src = (domSource*) elem.cast(); - if (!src) - { - return LLModel::BAD_ELEMENT; - } - t = &(src->getFloat_array()->getValue()); - } - } - - domP_Array& ps = poly->getP_array(); - - //make a triangle list in <verts> - for (U32 i = 0; i < ps.getCount(); ++i) - { //for each polygon - domListOfUInts& idx = ps[i]->getValue(); - for (U32 j = 0; j < idx.getCount()/stride; ++j) - { //for each vertex - if (j > 2) - { - U32 size = verts.size(); - LLVolumeFace::VertexData v0 = verts[size-3]; - LLVolumeFace::VertexData v1 = verts[size-1]; - - verts.push_back(v0); - verts.push_back(v1); - } - - LLVolumeFace::VertexData vert; - - - if (v) - { - U32 v_idx = idx[j*stride+v_offset]*3; - v_idx = llclamp(v_idx, (U32) 0, (U32) v->getCount()); - vert.getPosition().set(v->get(v_idx), - v->get(v_idx+1), - v->get(v_idx+2)); - } - - //bounds check n and t lookups because some FBX to DAE converters - //use negative indices and empty arrays to indicate data does not exist - //for a particular channel - if (n && n->getCount() > 0) - { - U32 n_idx = idx[j*stride+n_offset]*3; - n_idx = llclamp(n_idx, (U32) 0, (U32) n->getCount()); - vert.getNormal().set(n->get(n_idx), - n->get(n_idx+1), - n->get(n_idx+2)); - } - else - { - vert.getNormal().clear(); - } - - - if (t && t->getCount() > 0) - { - U32 t_idx = idx[j*stride+t_offset]*2; - t_idx = llclamp(t_idx, (U32) 0, (U32) t->getCount()); - vert.mTexCoord.setVec(t->get(t_idx), - t->get(t_idx+1)); - } - else - { - vert.mTexCoord.clear(); - } - - - verts.push_back(vert); - } - } - - if (verts.empty()) - { - return LLModel::NO_ERRORS; - } - // VFExtents change - face.mExtents[0] = verts[0].getPosition(); - face.mExtents[1] = verts[0].getPosition(); - - //create a map of unique vertices to indices - std::map<LLVolumeFace::VertexData, U32> vert_idx; - - U32 cur_idx = 0; - for (U32 i = 0; i < verts.size(); ++i) - { - std::map<LLVolumeFace::VertexData, U32>::iterator iter = vert_idx.find(verts[i]); - if (iter == vert_idx.end()) - { - vert_idx[verts[i]] = cur_idx++; - } - } + LLVolumeFace face; + std::vector<U16> indices; + std::vector<LLVolumeFace::VertexData> verts; + + const domInputLocalOffset_Array& inputs = poly->getInput_array(); + + S32 v_offset = -1; + S32 n_offset = -1; + S32 t_offset = -1; + + domListOfFloats* v = NULL; + domListOfFloats* n = NULL; + domListOfFloats* t = NULL; + + U32 stride = 0; + for (U32 i = 0; i < inputs.getCount(); ++i) + { + stride = llmax((U32) inputs[i]->getOffset()+1, stride); + + if (strcmp(COMMON_PROFILE_INPUT_VERTEX, inputs[i]->getSemantic()) == 0) + { //found vertex array + v_offset = inputs[i]->getOffset(); + + const domURIFragmentType& uri = inputs[i]->getSource(); + daeElementRef elem = uri.getElement(); + domVertices* vertices = (domVertices*) elem.cast(); + if (!vertices) + { + return LLModel::BAD_ELEMENT; + } + domInputLocal_Array& v_inp = vertices->getInput_array(); + + 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) + { + return LLModel::BAD_ELEMENT; + } + v = &(src->getFloat_array()->getValue()); + } + } + } + else if (strcmp(COMMON_PROFILE_INPUT_NORMAL, inputs[i]->getSemantic()) == 0) + { + n_offset = inputs[i]->getOffset(); + //found normal array for this triangle list + const domURIFragmentType& uri = inputs[i]->getSource(); + daeElementRef elem = uri.getElement(); + domSource* src = (domSource*) elem.cast(); + if (!src) + { + return LLModel::BAD_ELEMENT; + } + n = &(src->getFloat_array()->getValue()); + } + else if (strcmp(COMMON_PROFILE_INPUT_TEXCOORD, inputs[i]->getSemantic()) == 0 && inputs[i]->getSet() == 0) + { //found texCoords + t_offset = inputs[i]->getOffset(); + const domURIFragmentType& uri = inputs[i]->getSource(); + daeElementRef elem = uri.getElement(); + domSource* src = (domSource*) elem.cast(); + if (!src) + { + return LLModel::BAD_ELEMENT; + } + t = &(src->getFloat_array()->getValue()); + } + } + + domP_Array& ps = poly->getP_array(); + + //make a triangle list in <verts> + for (U32 i = 0; i < ps.getCount(); ++i) + { //for each polygon + domListOfUInts& idx = ps[i]->getValue(); + for (U32 j = 0; j < idx.getCount()/stride; ++j) + { //for each vertex + if (j > 2) + { + U32 size = verts.size(); + LLVolumeFace::VertexData v0 = verts[size-3]; + LLVolumeFace::VertexData v1 = verts[size-1]; + + verts.push_back(v0); + verts.push_back(v1); + } + + LLVolumeFace::VertexData vert; + + + if (v) + { + U32 v_idx = idx[j*stride+v_offset]*3; + v_idx = llclamp(v_idx, (U32) 0, (U32) v->getCount()); + vert.getPosition().set(v->get(v_idx), + v->get(v_idx+1), + v->get(v_idx+2)); + } + + //bounds check n and t lookups because some FBX to DAE converters + //use negative indices and empty arrays to indicate data does not exist + //for a particular channel + if (n && n->getCount() > 0) + { + U32 n_idx = idx[j*stride+n_offset]*3; + n_idx = llclamp(n_idx, (U32) 0, (U32) n->getCount()); + vert.getNormal().set(n->get(n_idx), + n->get(n_idx+1), + n->get(n_idx+2)); + } + else + { + vert.getNormal().clear(); + } + + + if (t && t->getCount() > 0) + { + U32 t_idx = idx[j*stride+t_offset]*2; + t_idx = llclamp(t_idx, (U32) 0, (U32) t->getCount()); + vert.mTexCoord.setVec(t->get(t_idx), + t->get(t_idx+1)); + } + else + { + vert.mTexCoord.clear(); + } + + + verts.push_back(vert); + } + } + + if (verts.empty()) + { + return LLModel::NO_ERRORS; + } + // VFExtents change + face.mExtents[0] = verts[0].getPosition(); + face.mExtents[1] = verts[0].getPosition(); + + //create a map of unique vertices to indices + std::map<LLVolumeFace::VertexData, U32> vert_idx; + + U32 cur_idx = 0; + for (U32 i = 0; i < verts.size(); ++i) + { + std::map<LLVolumeFace::VertexData, U32>::iterator iter = vert_idx.find(verts[i]); + if (iter == vert_idx.end()) + { + vert_idx[verts[i]] = cur_idx++; + } + } // Viewer can only fit U16 vertices, shouldn't we do some checks here and return overflow if result has more? llassert(vert_idx.size() < U16_MAX); - //build vertex array from map - std::vector<LLVolumeFace::VertexData> new_verts; - new_verts.resize(vert_idx.size()); + //build vertex array from map + std::vector<LLVolumeFace::VertexData> new_verts; + new_verts.resize(vert_idx.size()); - for (std::map<LLVolumeFace::VertexData, U32>::iterator iter = vert_idx.begin(); iter != vert_idx.end(); ++iter) - { - new_verts[iter->second] = iter->first; - // VFExtents change - update_min_max(face.mExtents[0], face.mExtents[1], iter->first.getPosition()); - } + for (std::map<LLVolumeFace::VertexData, U32>::iterator iter = vert_idx.begin(); iter != vert_idx.end(); ++iter) + { + new_verts[iter->second] = iter->first; + // VFExtents change + update_min_max(face.mExtents[0], face.mExtents[1], iter->first.getPosition()); + } - //build index array from map - indices.resize(verts.size()); + //build index array from map + indices.resize(verts.size()); - for (U32 i = 0; i < verts.size(); ++i) - { - indices[i] = vert_idx[verts[i]]; + for (U32 i = 0; i < verts.size(); ++i) + { + indices[i] = vert_idx[verts[i]]; if (i % 3 != 0) // assumes GL_TRIANGLES, compare 0-1, 1-2, 3-4, 4-5 but not 2-3 or 5-6 { // A faulty degenerate triangle detection (triangle with 0 area), // probably should be a warning and not an assert llassert(!i || (indices[i-1] != indices[i])); } - } + } - // DEBUG just build an expanded triangle list - /*for (U32 i = 0; i < verts.size(); ++i) - { - indices.push_back((U16) i); - update_min_max(face.mExtents[0], face.mExtents[1], verts[i].getPosition()); - }*/ + // DEBUG just build an expanded triangle list + /*for (U32 i = 0; i < verts.size(); ++i) + { + indices.push_back((U16) i); + update_min_max(face.mExtents[0], face.mExtents[1], verts[i].getPosition()); + }*/ if (!new_verts.empty()) - { - std::string material; - - if (poly->getMaterial()) - { - material = std::string(poly->getMaterial()); - } - - 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 ; + { + std::string material; + + if (poly->getMaterial()) + { + material = std::string(poly->getMaterial()); + } + + 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 ; } //----------------------------------------------------------------------------- // LLDAELoader //----------------------------------------------------------------------------- LLDAELoader::LLDAELoader( - std::string filename, - S32 lod, - load_callback_t load_cb, - joint_lookup_func_t joint_lookup_func, - texture_load_func_t texture_load_func, - state_callback_t state_cb, - void* opaque_userdata, - JointTransformMap& jointTransformMap, - JointNameSet& jointsFromNodes, - std::map<std::string, std::string>& jointAliasMap, - U32 maxJointsPerMesh, - U32 modelLimit, - bool preprocess) + std::string filename, + S32 lod, + load_callback_t load_cb, + joint_lookup_func_t joint_lookup_func, + texture_load_func_t texture_load_func, + state_callback_t state_cb, + void* opaque_userdata, + JointTransformMap& jointTransformMap, + JointNameSet& jointsFromNodes, + std::map<std::string, std::string>& jointAliasMap, + U32 maxJointsPerMesh, + U32 modelLimit, + bool preprocess) : LLModelLoader( - filename, - lod, - load_cb, - joint_lookup_func, - texture_load_func, - state_cb, - opaque_userdata, - jointTransformMap, - jointsFromNodes, + filename, + lod, + load_cb, + joint_lookup_func, + texture_load_func, + state_cb, + opaque_userdata, + jointTransformMap, + jointsFromNodes, jointAliasMap, maxJointsPerMesh), mGeneratedModelLimit(modelLimit), @@ -912,347 +912,347 @@ LLDAELoader::~LLDAELoader() struct ModelSort { - bool operator()(const LLPointer< LLModel >& lhs, const LLPointer< LLModel >& rhs) - { + bool operator()(const LLPointer< LLModel >& lhs, const LLPointer< LLModel >& rhs) + { if (lhs->mSubmodelID < rhs->mSubmodelID) { return true; } - return LLStringUtil::compareInsensitive(lhs->mLabel, rhs->mLabel) < 0; - } + return LLStringUtil::compareInsensitive(lhs->mLabel, rhs->mLabel) < 0; + } }; bool LLDAELoader::OpenFile(const std::string& filename) { - setLoadState( READING_FILE ); - - //no suitable slm exists, load from the .dae file - - // Collada expects file and folder names to be escaped - // Note: cdom::nativePathToUri() - const char* allowed = - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789" - "%-._~:\"|\\/"; - std::string uri_filename = LLURI::escape(filename, allowed); - - DAE dae; - domCOLLADA* dom; - if (mPreprocessDAE) - { - dom = dae.openFromMemory(uri_filename, preprocessDAE(filename).c_str()); - } - else - { - LL_INFOS() << "Skipping dae preprocessing" << LL_ENDL; - dom = dae.open(uri_filename); - } - - if (!dom) - { - LL_INFOS() <<" Error with dae - traditionally indicates a corrupt file."<<LL_ENDL; + setLoadState( READING_FILE ); + + //no suitable slm exists, load from the .dae file + + // Collada expects file and folder names to be escaped + // Note: cdom::nativePathToUri() + const char* allowed = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789" + "%-._~:\"|\\/"; + std::string uri_filename = LLURI::escape(filename, allowed); + + DAE dae; + domCOLLADA* dom; + if (mPreprocessDAE) + { + dom = dae.openFromMemory(uri_filename, preprocessDAE(filename).c_str()); + } + else + { + LL_INFOS() << "Skipping dae preprocessing" << LL_ENDL; + dom = dae.open(uri_filename); + } + + if (!dom) + { + LL_INFOS() <<" Error with dae - traditionally indicates a corrupt file."<<LL_ENDL; LLSD args; args["Message"] = "ParsingErrorCorrupt"; mWarningsArray.append(args); - setLoadState( ERROR_PARSING ); - return false; - } - //Dom version - daeString domVersion = dae.getDomVersion(); - std::string sldom(domVersion); - LL_INFOS()<<"Collada Importer Version: "<<sldom<<LL_ENDL; - //Dae version - domVersionType docVersion = dom->getVersion(); - //0=1.4 - //1=1.4.1 - //2=Currently unsupported, however may work - if (docVersion > 1 ) - { - docVersion = VERSIONTYPE_COUNT; - } - LL_INFOS()<<"Dae version "<<colladaVersion[docVersion]<<LL_ENDL; - - - daeDatabase* db = dae.getDatabase(); - - daeInt count = db->getElementCount(NULL, COLLADA_TYPE_MESH); - - daeDocument* doc = dae.getDoc(uri_filename); - if (!doc) - { - LL_WARNS() << "can't find internal doc" << LL_ENDL; + setLoadState( ERROR_PARSING ); + return false; + } + //Dom version + daeString domVersion = dae.getDomVersion(); + std::string sldom(domVersion); + LL_INFOS()<<"Collada Importer Version: "<<sldom<<LL_ENDL; + //Dae version + domVersionType docVersion = dom->getVersion(); + //0=1.4 + //1=1.4.1 + //2=Currently unsupported, however may work + if (docVersion > 1 ) + { + docVersion = VERSIONTYPE_COUNT; + } + LL_INFOS()<<"Dae version "<<colladaVersion[docVersion]<<LL_ENDL; + + + daeDatabase* db = dae.getDatabase(); + + daeInt count = db->getElementCount(NULL, COLLADA_TYPE_MESH); + + daeDocument* doc = dae.getDoc(uri_filename); + if (!doc) + { + LL_WARNS() << "can't find internal doc" << LL_ENDL; LLSD args; args["Message"] = "ParsingErrorNoDoc"; mWarningsArray.append(args); - return false; - } - - daeElement* root = doc->getDomRoot(); - if (!root) - { - LL_WARNS() << "document has no root" << LL_ENDL; + return false; + } + + daeElement* root = doc->getDomRoot(); + if (!root) + { + LL_WARNS() << "document has no root" << LL_ENDL; LLSD args; args["Message"] = "ParsingErrorNoRoot"; mWarningsArray.append(args); - return false; - } - - //Verify some basic properties of the dae - //1. Basic validity check on controller - U32 controllerCount = (int) db->getElementCount( NULL, "controller" ); - bool result = false; - for ( int i=0; i<controllerCount; ++i ) - { - domController* pController = NULL; - db->getElement( (daeElement**) &pController, i , NULL, "controller" ); - result = verifyController( pController ); - if (!result) - { - LL_INFOS() << "Could not verify controller" << LL_ENDL; + return false; + } + + //Verify some basic properties of the dae + //1. Basic validity check on controller + U32 controllerCount = (int) db->getElementCount( NULL, "controller" ); + bool result = false; + for ( int i=0; i<controllerCount; ++i ) + { + domController* pController = NULL; + db->getElement( (daeElement**) &pController, i , NULL, "controller" ); + result = verifyController( pController ); + if (!result) + { + LL_INFOS() << "Could not verify controller" << LL_ENDL; LLSD args; args["Message"] = "ParsingErrorBadElement"; mWarningsArray.append(args); - setLoadState( ERROR_PARSING ); - return true; - } - } - - - //get unit scale - mTransform.setIdentity(); - - domAsset::domUnit* unit = daeSafeCast<domAsset::domUnit>(root->getDescendant(daeElement::matchType(domAsset::domUnit::ID()))); - - if (unit) - { - F32 meter = unit->getMeter(); - mTransform.mMatrix[0][0] = meter; - mTransform.mMatrix[1][1] = meter; - mTransform.mMatrix[2][2] = meter; - } - - //get up axis rotation - LLMatrix4 rotation; - - domUpAxisType up = UPAXISTYPE_Y_UP; // default is Y_UP - domAsset::domUp_axis* up_axis = - daeSafeCast<domAsset::domUp_axis>(root->getDescendant(daeElement::matchType(domAsset::domUp_axis::ID()))); - - if (up_axis) - { - up = up_axis->getValue(); - } - - if (up == UPAXISTYPE_X_UP) - { - rotation.initRotation(0.0f, 90.0f * DEG_TO_RAD, 0.0f); - } - else if (up == UPAXISTYPE_Y_UP) - { - rotation.initRotation(90.0f * DEG_TO_RAD, 0.0f, 0.0f); - } - - rotation *= mTransform; - mTransform = rotation; - - mTransform.condition(); - - U32 submodel_limit = count > 0 ? mGeneratedModelLimit/count : 0; - for (daeInt idx = 0; idx < count; ++idx) - { //build map of domEntities to LLModel - domMesh* mesh = NULL; - db->getElement((daeElement**) &mesh, idx, NULL, COLLADA_TYPE_MESH); - - if (mesh) - { - - std::vector<LLModel*> models; - - loadModelsFromDomMesh(mesh, models, submodel_limit); - - std::vector<LLModel*>::iterator i; - i = models.begin(); - while (i != models.end()) - { - LLModel* mdl = *i; - if(mdl->getStatus() != LLModel::NO_ERRORS) - { - setLoadState(ERROR_MODEL + mdl->getStatus()) ; - return false; //abort - } - - if (mdl && validate_model(mdl)) - { - mModelList.push_back(mdl); - mModelsMap[mesh].push_back(mdl); - } - i++; - } - } - } - - std::sort(mModelList.begin(), mModelList.end(), ModelSort()); - - model_list::iterator model_iter = mModelList.begin(); - while (model_iter != mModelList.end()) - { - LLModel* mdl = *model_iter; - U32 material_count = mdl->mMaterialList.size(); - LL_INFOS() << "Importing " << mdl->mLabel << " model with " << material_count << " material references" << LL_ENDL; - std::vector<std::string>::iterator mat_iter = mdl->mMaterialList.begin(); - std::vector<std::string>::iterator end_iter = material_count > LIMIT_MATERIALS_OUTPUT - ? mat_iter + LIMIT_MATERIALS_OUTPUT - : mdl->mMaterialList.end(); - while (mat_iter != end_iter) - { - LL_INFOS() << mdl->mLabel << " references " << (*mat_iter) << LL_ENDL; - mat_iter++; - } - model_iter++; - } - - count = db->getElementCount(NULL, COLLADA_TYPE_SKIN); - for (daeInt idx = 0; idx < count; ++idx) - { //add skinned meshes as instances - domSkin* skin = NULL; - db->getElement((daeElement**) &skin, idx, NULL, COLLADA_TYPE_SKIN); - - if (skin) - { - domGeometry* geom = daeSafeCast<domGeometry>(skin->getSource().getElement()); - - if (geom) - { - domMesh* mesh = geom->getMesh(); - if (mesh) - { - std::vector< LLPointer< LLModel > >::iterator i = mModelsMap[mesh].begin(); - while (i != mModelsMap[mesh].end()) - { - LLPointer<LLModel> mdl = *i; - LLDAELoader::processDomModel(mdl, &dae, root, mesh, skin); - i++; - } - } - } - } - } - - LL_INFOS()<< "Collada skins processed: " << count <<LL_ENDL; - - daeElement* scene = root->getDescendant("visual_scene"); - - if (!scene) - { - LL_WARNS() << "document has no visual_scene" << LL_ENDL; + setLoadState( ERROR_PARSING ); + return true; + } + } + + + //get unit scale + mTransform.setIdentity(); + + domAsset::domUnit* unit = daeSafeCast<domAsset::domUnit>(root->getDescendant(daeElement::matchType(domAsset::domUnit::ID()))); + + if (unit) + { + F32 meter = unit->getMeter(); + mTransform.mMatrix[0][0] = meter; + mTransform.mMatrix[1][1] = meter; + mTransform.mMatrix[2][2] = meter; + } + + //get up axis rotation + LLMatrix4 rotation; + + domUpAxisType up = UPAXISTYPE_Y_UP; // default is Y_UP + domAsset::domUp_axis* up_axis = + daeSafeCast<domAsset::domUp_axis>(root->getDescendant(daeElement::matchType(domAsset::domUp_axis::ID()))); + + if (up_axis) + { + up = up_axis->getValue(); + } + + if (up == UPAXISTYPE_X_UP) + { + rotation.initRotation(0.0f, 90.0f * DEG_TO_RAD, 0.0f); + } + else if (up == UPAXISTYPE_Y_UP) + { + rotation.initRotation(90.0f * DEG_TO_RAD, 0.0f, 0.0f); + } + + rotation *= mTransform; + mTransform = rotation; + + mTransform.condition(); + + U32 submodel_limit = count > 0 ? mGeneratedModelLimit/count : 0; + for (daeInt idx = 0; idx < count; ++idx) + { //build map of domEntities to LLModel + domMesh* mesh = NULL; + db->getElement((daeElement**) &mesh, idx, NULL, COLLADA_TYPE_MESH); + + if (mesh) + { + + std::vector<LLModel*> models; + + loadModelsFromDomMesh(mesh, models, submodel_limit); + + std::vector<LLModel*>::iterator i; + i = models.begin(); + while (i != models.end()) + { + LLModel* mdl = *i; + if(mdl->getStatus() != LLModel::NO_ERRORS) + { + setLoadState(ERROR_MODEL + mdl->getStatus()) ; + return false; //abort + } + + if (mdl && validate_model(mdl)) + { + mModelList.push_back(mdl); + mModelsMap[mesh].push_back(mdl); + } + i++; + } + } + } + + std::sort(mModelList.begin(), mModelList.end(), ModelSort()); + + model_list::iterator model_iter = mModelList.begin(); + while (model_iter != mModelList.end()) + { + LLModel* mdl = *model_iter; + U32 material_count = mdl->mMaterialList.size(); + LL_INFOS() << "Importing " << mdl->mLabel << " model with " << material_count << " material references" << LL_ENDL; + std::vector<std::string>::iterator mat_iter = mdl->mMaterialList.begin(); + std::vector<std::string>::iterator end_iter = material_count > LIMIT_MATERIALS_OUTPUT + ? mat_iter + LIMIT_MATERIALS_OUTPUT + : mdl->mMaterialList.end(); + while (mat_iter != end_iter) + { + LL_INFOS() << mdl->mLabel << " references " << (*mat_iter) << LL_ENDL; + mat_iter++; + } + model_iter++; + } + + count = db->getElementCount(NULL, COLLADA_TYPE_SKIN); + for (daeInt idx = 0; idx < count; ++idx) + { //add skinned meshes as instances + domSkin* skin = NULL; + db->getElement((daeElement**) &skin, idx, NULL, COLLADA_TYPE_SKIN); + + if (skin) + { + domGeometry* geom = daeSafeCast<domGeometry>(skin->getSource().getElement()); + + if (geom) + { + domMesh* mesh = geom->getMesh(); + if (mesh) + { + std::vector< LLPointer< LLModel > >::iterator i = mModelsMap[mesh].begin(); + while (i != mModelsMap[mesh].end()) + { + LLPointer<LLModel> mdl = *i; + LLDAELoader::processDomModel(mdl, &dae, root, mesh, skin); + i++; + } + } + } + } + } + + LL_INFOS()<< "Collada skins processed: " << count <<LL_ENDL; + + daeElement* scene = root->getDescendant("visual_scene"); + + if (!scene) + { + LL_WARNS() << "document has no visual_scene" << LL_ENDL; LLSD args; args["Message"] = "ParsingErrorNoScene"; mWarningsArray.append(args); - setLoadState( ERROR_PARSING ); - return true; - } - - setLoadState( DONE ); - - bool badElement = false; - - processElement( scene, badElement, &dae); - - if ( badElement ) - { - LL_INFOS()<<"Scene could not be parsed"<<LL_ENDL; + setLoadState( ERROR_PARSING ); + return true; + } + + setLoadState( DONE ); + + bool badElement = false; + + processElement( scene, badElement, &dae); + + if ( badElement ) + { + LL_INFOS()<<"Scene could not be parsed"<<LL_ENDL; LLSD args; args["Message"] = "ParsingErrorCantParseScene"; mWarningsArray.append(args); - setLoadState( ERROR_PARSING ); - } - - return true; + setLoadState( ERROR_PARSING ); + } + + return true; } std::string LLDAELoader::preprocessDAE(std::string filename) { - // Open a DAE file for some preprocessing (like removing space characters in IDs), see MAINT-5678 - llifstream inFile; - inFile.open(filename.c_str(), std::ios_base::in); - std::stringstream strStream; - strStream << inFile.rdbuf(); - std::string buffer = strStream.str(); - - LL_INFOS() << "Preprocessing dae file to remove spaces from the names, ids, etc." << LL_ENDL; - - try - { - boost::regex re("\"[\\w\\.@#$-]*(\\s[\\w\\.@#$-]*)+\""); - boost::sregex_iterator next(buffer.begin(), buffer.end(), re); - boost::sregex_iterator end; - while (next != end) - { - boost::smatch match = *next; - std::string s = match.str(); - LL_INFOS() << s << " found" << LL_ENDL; - boost::replace_all(s, " ", "_"); - LL_INFOS() << "Replacing with " << s << LL_ENDL; - boost::replace_all(buffer, match.str(), s); - next++; - } - } - catch (boost::regex_error &) - { - LL_INFOS() << "Regex error" << LL_ENDL; - } - - return buffer; + // Open a DAE file for some preprocessing (like removing space characters in IDs), see MAINT-5678 + llifstream inFile; + inFile.open(filename.c_str(), std::ios_base::in); + std::stringstream strStream; + strStream << inFile.rdbuf(); + std::string buffer = strStream.str(); + + LL_INFOS() << "Preprocessing dae file to remove spaces from the names, ids, etc." << LL_ENDL; + + try + { + boost::regex re("\"[\\w\\.@#$-]*(\\s[\\w\\.@#$-]*)+\""); + boost::sregex_iterator next(buffer.begin(), buffer.end(), re); + boost::sregex_iterator end; + while (next != end) + { + boost::smatch match = *next; + std::string s = match.str(); + LL_INFOS() << s << " found" << LL_ENDL; + boost::replace_all(s, " ", "_"); + LL_INFOS() << "Replacing with " << s << LL_ENDL; + boost::replace_all(buffer, match.str(), s); + next++; + } + } + catch (boost::regex_error &) + { + LL_INFOS() << "Regex error" << LL_ENDL; + } + + return buffer; } void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, domMesh* mesh, domSkin* skin) { - llassert(model && dae && mesh && skin); + llassert(model && dae && mesh && skin); - if (model) - { - LLVector3 mesh_scale_vector; - LLVector3 mesh_translation_vector; - model->getNormalizedScaleTranslation(mesh_scale_vector, mesh_translation_vector); + if (model) + { + LLVector3 mesh_scale_vector; + LLVector3 mesh_translation_vector; + model->getNormalizedScaleTranslation(mesh_scale_vector, mesh_translation_vector); - LLMatrix4 normalized_transformation; - normalized_transformation.setTranslation(mesh_translation_vector); + LLMatrix4 normalized_transformation; + normalized_transformation.setTranslation(mesh_translation_vector); - LLMatrix4 mesh_scale; - mesh_scale.initScale(mesh_scale_vector); - mesh_scale *= normalized_transformation; - normalized_transformation = mesh_scale; + LLMatrix4 mesh_scale; + mesh_scale.initScale(mesh_scale_vector); + mesh_scale *= normalized_transformation; + normalized_transformation = mesh_scale; - glh::matrix4f inv_mat((F32*) normalized_transformation.mMatrix); - inv_mat = inv_mat.inverse(); - LLMatrix4 inverse_normalized_transformation(inv_mat.m); + glh::matrix4f inv_mat((F32*) normalized_transformation.mMatrix); + inv_mat = inv_mat.inverse(); + LLMatrix4 inverse_normalized_transformation(inv_mat.m); - domSkin::domBind_shape_matrix* bind_mat = skin->getBind_shape_matrix(); + domSkin::domBind_shape_matrix* bind_mat = skin->getBind_shape_matrix(); - if (bind_mat) - { //get bind shape matrix - domFloat4x4& dom_value = bind_mat->getValue(); + if (bind_mat) + { //get bind shape matrix + domFloat4x4& dom_value = bind_mat->getValue(); - LLMeshSkinInfo& skin_info = model->mSkinInfo; + LLMeshSkinInfo& skin_info = model->mSkinInfo; LLMatrix4 mat; - for (int i = 0; i < 4; i++) - { - for(int j = 0; j < 4; j++) - { + for (int i = 0; i < 4; i++) + { + for(int j = 0; j < 4; j++) + { mat.mMatrix[i][j] = dom_value[i + j*4]; - } - } + } + } skin_info.mBindShapeMatrix.loadu(mat); - LLMatrix4a trans(normalized_transformation); + LLMatrix4a trans(normalized_transformation); matMul(trans, skin_info.mBindShapeMatrix, skin_info.mBindShapeMatrix); - } + } - //Some collada setup for accessing the skeleton + //Some collada setup for accessing the skeleton U32 skeleton_count = dae->getDatabase()->getElementCount( NULL, "skeleton" ); std::vector<domInstance_controller::domSkeleton*> skeletons; for (S32 i=0; i<skeleton_count; i++) @@ -1262,7 +1262,7 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do //Try to get at the skeletal instance controller domInstance_controller::domSkeleton* pSkeleton = daeSafeCast<domInstance_controller::domSkeleton>( pElement ); - daeElement* pSkeletonRootNode = NULL; + daeElement* pSkeletonRootNode = NULL; if (pSkeleton) { pSkeletonRootNode = pSkeleton->getValue().getElement(); @@ -1272,37 +1272,37 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do skeletons.push_back(pSkeleton); } } - bool missingSkeletonOrScene = false; - - //If no skeleton, do a breadth-first search to get at specific joints - if ( skeletons.size() == 0 ) - { - daeElement* pScene = root->getDescendant("visual_scene"); - if ( !pScene ) - { - LL_WARNS()<<"No visual scene - unable to parse bone offsets "<<LL_ENDL; - missingSkeletonOrScene = true; - } - else - { - //Get the children at this level - daeTArray< daeSmartRef<daeElement> > children = pScene->getChildren(); - S32 childCount = children.getCount(); - - //Process any children that are joints - //Not all children are joints, some could be ambient lights, cameras, geometry etc.. - for (S32 i = 0; i < childCount; ++i) - { - domNode* pNode = daeSafeCast<domNode>(children[i]); - if (pNode) - { - processJointNode( pNode, mJointList ); - } - } - } - } - else - //Has one or more skeletons + bool missingSkeletonOrScene = false; + + //If no skeleton, do a breadth-first search to get at specific joints + if ( skeletons.size() == 0 ) + { + daeElement* pScene = root->getDescendant("visual_scene"); + if ( !pScene ) + { + LL_WARNS()<<"No visual scene - unable to parse bone offsets "<<LL_ENDL; + missingSkeletonOrScene = true; + } + else + { + //Get the children at this level + daeTArray< daeSmartRef<daeElement> > children = pScene->getChildren(); + S32 childCount = children.getCount(); + + //Process any children that are joints + //Not all children are joints, some could be ambient lights, cameras, geometry etc.. + for (S32 i = 0; i < childCount; ++i) + { + domNode* pNode = daeSafeCast<domNode>(children[i]); + if (pNode) + { + processJointNode( pNode, mJointList ); + } + } + } + } + else + //Has one or more skeletons for (std::vector<domInstance_controller::domSkeleton*>::iterator skel_it = skeletons.begin(); skel_it != skeletons.end(); ++skel_it) { @@ -1388,100 +1388,100 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do } - domSkin::domJoints* joints = skin->getJoints(); - - domInputLocal_Array& joint_input = joints->getInput_array(); - - for (size_t i = 0; i < joint_input.getCount(); ++i) - { - domInputLocal* input = joint_input.get(i); - xsNMTOKEN semantic = input->getSemantic(); - - if (strcmp(semantic, COMMON_PROFILE_INPUT_JOINT) == 0) - { //found joint source, fill model->mJointMap and model->mSkinInfo.mJointNames - daeElement* elem = input->getSource().getElement(); - - domSource* source = daeSafeCast<domSource>(elem); - if (source) - { - - - domName_array* names_source = source->getName_array(); - - if (names_source) - { - domListOfNames &names = names_source->getValue(); - - for (size_t j = 0; j < names.getCount(); ++j) - { - std::string name(names.get(j)); - if (mJointMap.find(name) != mJointMap.end()) - { - name = mJointMap[name]; - } - model->mSkinInfo.mJointNames.push_back(name); - model->mSkinInfo.mJointNums.push_back(-1); - } - } - else - { - domIDREF_array* names_source = source->getIDREF_array(); - if (names_source) - { - xsIDREFS& names = names_source->getValue(); - - for (size_t j = 0; j < names.getCount(); ++j) - { - std::string name(names.get(j).getID()); - if (mJointMap.find(name) != mJointMap.end()) - { - name = mJointMap[name]; - } - model->mSkinInfo.mJointNames.push_back(name); - model->mSkinInfo.mJointNums.push_back(-1); - } - } - } - } - } - else if (strcmp(semantic, COMMON_PROFILE_INPUT_INV_BIND_MATRIX) == 0) - { //found inv_bind_matrix array, fill model->mInvBindMatrix - domSource* source = daeSafeCast<domSource>(input->getSource().getElement()); - if (source) - { - domFloat_array* t = source->getFloat_array(); - if (t) - { - domListOfFloats& transform = t->getValue(); - S32 count = transform.getCount()/16; - - for (S32 k = 0; k < count; ++k) - { - LLMatrix4 mat; - - for (int i = 0; i < 4; i++) - { - for(int j = 0; j < 4; j++) - { - mat.mMatrix[i][j] = transform[k*16 + i + j*4]; - } - } - model->mSkinInfo.mInvBindMatrix.push_back(LLMatrix4a(mat)); - } - } - } - } - } - - //Now that we've parsed the joint array, let's determine if we have a full rig - //(which means we have all the joint sthat are required for an avatar versus - //a skinned asset attached to a node in a file that contains an entire skeleton, - //but does not use the skeleton). - buildJointToNodeMappingFromScene( root ); - critiqueRigForUploadApplicability( model->mSkinInfo.mJointNames ); - - if ( !missingSkeletonOrScene ) - { + domSkin::domJoints* joints = skin->getJoints(); + + domInputLocal_Array& joint_input = joints->getInput_array(); + + for (size_t i = 0; i < joint_input.getCount(); ++i) + { + domInputLocal* input = joint_input.get(i); + xsNMTOKEN semantic = input->getSemantic(); + + if (strcmp(semantic, COMMON_PROFILE_INPUT_JOINT) == 0) + { //found joint source, fill model->mJointMap and model->mSkinInfo.mJointNames + daeElement* elem = input->getSource().getElement(); + + domSource* source = daeSafeCast<domSource>(elem); + if (source) + { + + + domName_array* names_source = source->getName_array(); + + if (names_source) + { + domListOfNames &names = names_source->getValue(); + + for (size_t j = 0; j < names.getCount(); ++j) + { + std::string name(names.get(j)); + if (mJointMap.find(name) != mJointMap.end()) + { + name = mJointMap[name]; + } + model->mSkinInfo.mJointNames.push_back(name); + model->mSkinInfo.mJointNums.push_back(-1); + } + } + else + { + domIDREF_array* names_source = source->getIDREF_array(); + if (names_source) + { + xsIDREFS& names = names_source->getValue(); + + for (size_t j = 0; j < names.getCount(); ++j) + { + std::string name(names.get(j).getID()); + if (mJointMap.find(name) != mJointMap.end()) + { + name = mJointMap[name]; + } + model->mSkinInfo.mJointNames.push_back(name); + model->mSkinInfo.mJointNums.push_back(-1); + } + } + } + } + } + else if (strcmp(semantic, COMMON_PROFILE_INPUT_INV_BIND_MATRIX) == 0) + { //found inv_bind_matrix array, fill model->mInvBindMatrix + domSource* source = daeSafeCast<domSource>(input->getSource().getElement()); + if (source) + { + domFloat_array* t = source->getFloat_array(); + if (t) + { + domListOfFloats& transform = t->getValue(); + S32 count = transform.getCount()/16; + + for (S32 k = 0; k < count; ++k) + { + LLMatrix4 mat; + + for (int i = 0; i < 4; i++) + { + for(int j = 0; j < 4; j++) + { + mat.mMatrix[i][j] = transform[k*16 + i + j*4]; + } + } + model->mSkinInfo.mInvBindMatrix.push_back(LLMatrix4a(mat)); + } + } + } + } + } + + //Now that we've parsed the joint array, let's determine if we have a full rig + //(which means we have all the joint sthat are required for an avatar versus + //a skinned asset attached to a node in a file that contains an entire skeleton, + //but does not use the skeleton). + buildJointToNodeMappingFromScene( root ); + critiqueRigForUploadApplicability( model->mSkinInfo.mJointNames ); + + if ( !missingSkeletonOrScene ) + { // FIXME: mesh_id is used to determine which mesh gets to // set the joint offset, in the event of a conflict. Since // we don't know the mesh id yet, we can't guarantee that @@ -1492,7 +1492,7 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do LLUUID fake_mesh_id; fake_mesh_id.generate(); - //Set the joint translations on the avatar + //Set the joint translations on the avatar JointMap :: const_iterator masterJointIt = mJointMap.begin(); JointMap :: const_iterator masterJointItEnd = mJointMap.end(); for (;masterJointIt!=masterJointItEnd;++masterJointIt ) @@ -1505,7 +1505,7 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do LLMatrix4 jointTransform = mJointList[lookingForJoint]; LLJoint* pJoint = mJointLookupFunc(lookingForJoint,mOpaqueData); if ( pJoint ) - { + { const LLVector3& joint_pos = jointTransform.getTranslation(); if (pJoint->aboveJointPosThreshold(joint_pos)) { @@ -1524,31 +1524,31 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do } } } - } //missingSkeletonOrScene - - //We need to construct the alternate bind matrix (which contains the new joint positions) - //in the same order as they were stored in the joint buffer. The joints associated - //with the skeleton are not stored in the same order as they are in the exported joint buffer. - //This remaps the skeletal joints to be in the same order as the joints stored in the model. - std::vector<std::string> :: const_iterator jointIt = model->mSkinInfo.mJointNames.begin(); - const int jointCnt = model->mSkinInfo.mJointNames.size(); - for ( int i=0; i<jointCnt; ++i, ++jointIt ) - { - std::string lookingForJoint = (*jointIt).c_str(); - //Look for the joint xform that we extracted from the skeleton, using the jointIt as the key - //and store it in the alternate bind matrix - if (mJointMap.find(lookingForJoint) != mJointMap.end() - && model->mSkinInfo.mInvBindMatrix.size() > i) - { - LLMatrix4 newInverse = LLMatrix4(model->mSkinInfo.mInvBindMatrix[i].getF32ptr()); - newInverse.setTranslation( mJointList[lookingForJoint].getTranslation() ); - model->mSkinInfo.mAlternateBindMatrix.push_back( LLMatrix4a(newInverse) ); + } //missingSkeletonOrScene + + //We need to construct the alternate bind matrix (which contains the new joint positions) + //in the same order as they were stored in the joint buffer. The joints associated + //with the skeleton are not stored in the same order as they are in the exported joint buffer. + //This remaps the skeletal joints to be in the same order as the joints stored in the model. + std::vector<std::string> :: const_iterator jointIt = model->mSkinInfo.mJointNames.begin(); + const int jointCnt = model->mSkinInfo.mJointNames.size(); + for ( int i=0; i<jointCnt; ++i, ++jointIt ) + { + std::string lookingForJoint = (*jointIt).c_str(); + //Look for the joint xform that we extracted from the skeleton, using the jointIt as the key + //and store it in the alternate bind matrix + if (mJointMap.find(lookingForJoint) != mJointMap.end() + && model->mSkinInfo.mInvBindMatrix.size() > i) + { + LLMatrix4 newInverse = LLMatrix4(model->mSkinInfo.mInvBindMatrix[i].getF32ptr()); + newInverse.setTranslation( mJointList[lookingForJoint].getTranslation() ); + model->mSkinInfo.mAlternateBindMatrix.push_back( LLMatrix4a(newInverse) ); } - else - { + else + { LL_DEBUGS("Mesh")<<"Possibly misnamed/missing joint [" <<lookingForJoint.c_str()<<"] "<<LL_ENDL; - } - } + } + } U32 bind_count = model->mSkinInfo.mAlternateBindMatrix.size(); if (bind_count > 0 && bind_count != jointCnt) @@ -1556,138 +1556,138 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do LL_WARNS("Mesh") << "Model " << model->mLabel << " has invalid joint bind matrix list." << LL_ENDL; } - //grab raw position array - - domVertices* verts = mesh->getVertices(); - if (verts) - { - domInputLocal_Array& inputs = verts->getInput_array(); - for (size_t i = 0; i < inputs.getCount() && model->mPosition.empty(); ++i) - { - if (strcmp(inputs[i]->getSemantic(), COMMON_PROFILE_INPUT_POSITION) == 0) - { - domSource* pos_source = daeSafeCast<domSource>(inputs[i]->getSource().getElement()); - if (pos_source) - { - domFloat_array* pos_array = pos_source->getFloat_array(); - if (pos_array) - { - domListOfFloats& pos = pos_array->getValue(); - - for (size_t j = 0; j < pos.getCount(); j += 3) - { - if (pos.getCount() <= j+2) - { - LL_ERRS() << "Invalid position array size." << LL_ENDL; - } - - LLVector3 v(pos[j], pos[j+1], pos[j+2]); - - //transform from COLLADA space to volume space - v = v * inverse_normalized_transformation; - - model->mPosition.push_back(v); - } - } - } - } - } - } - - //grab skin weights array - domSkin::domVertex_weights* weights = skin->getVertex_weights(); - if (weights) - { - domInputLocalOffset_Array& inputs = weights->getInput_array(); - domFloat_array* vertex_weights = NULL; - for (size_t i = 0; i < inputs.getCount(); ++i) - { - if (strcmp(inputs[i]->getSemantic(), COMMON_PROFILE_INPUT_WEIGHT) == 0) - { - domSource* weight_source = daeSafeCast<domSource>(inputs[i]->getSource().getElement()); - if (weight_source) - { - vertex_weights = weight_source->getFloat_array(); - } - } - } - - if (vertex_weights) - { - domListOfFloats& w = vertex_weights->getValue(); - domListOfUInts& vcount = weights->getVcount()->getValue(); - domListOfInts& v = weights->getV()->getValue(); - - U32 c_idx = 0; - for (size_t vc_idx = 0; vc_idx < vcount.getCount(); ++vc_idx) - { //for each vertex - daeUInt count = vcount[vc_idx]; - - //create list of weights that influence this vertex - LLModel::weight_list weight_list; - - for (daeUInt i = 0; i < count; ++i) - { //for each weight - daeInt joint_idx = v[c_idx++]; - daeInt weight_idx = v[c_idx++]; - - if (joint_idx == -1) - { - //ignore bindings to bind_shape_matrix - continue; - } - - F32 weight_value = w[weight_idx]; - - weight_list.push_back(LLModel::JointWeight(joint_idx, weight_value)); - } - - //sort by joint weight - std::sort(weight_list.begin(), weight_list.end(), LLModel::CompareWeightGreater()); - - std::vector<LLModel::JointWeight> wght; - - F32 total = 0.f; - - for (U32 i = 0; i < llmin((U32) 4, (U32) weight_list.size()); ++i) - { //take up to 4 most significant weights - if (weight_list[i].mWeight > 0.f) - { - wght.push_back( weight_list[i] ); - total += weight_list[i].mWeight; - } - } - - F32 scale = 1.f/total; - if (scale != 1.f) - { //normalize weights - for (U32 i = 0; i < wght.size(); ++i) - { - wght[i].mWeight *= scale; - } - } - - model->mSkinWeights[model->mPosition[vc_idx]] = wght; - } - } - - } - - //add instance to scene for this model - - LLMatrix4 transformation; - transformation.initScale(mesh_scale_vector); - transformation.setTranslation(mesh_translation_vector); - transformation *= mTransform; - - std::map<std::string, LLImportMaterial> materials; - for (U32 i = 0; i < model->mMaterialList.size(); ++i) - { - materials[model->mMaterialList[i]] = LLImportMaterial(); - } - mScene[transformation].push_back(LLModelInstance(model, model->mLabel, transformation, materials)); - stretch_extents(model, transformation, mExtents[0], mExtents[1], mFirstTransform); - } + //grab raw position array + + domVertices* verts = mesh->getVertices(); + if (verts) + { + domInputLocal_Array& inputs = verts->getInput_array(); + for (size_t i = 0; i < inputs.getCount() && model->mPosition.empty(); ++i) + { + if (strcmp(inputs[i]->getSemantic(), COMMON_PROFILE_INPUT_POSITION) == 0) + { + domSource* pos_source = daeSafeCast<domSource>(inputs[i]->getSource().getElement()); + if (pos_source) + { + domFloat_array* pos_array = pos_source->getFloat_array(); + if (pos_array) + { + domListOfFloats& pos = pos_array->getValue(); + + for (size_t j = 0; j < pos.getCount(); j += 3) + { + if (pos.getCount() <= j+2) + { + LL_ERRS() << "Invalid position array size." << LL_ENDL; + } + + LLVector3 v(pos[j], pos[j+1], pos[j+2]); + + //transform from COLLADA space to volume space + v = v * inverse_normalized_transformation; + + model->mPosition.push_back(v); + } + } + } + } + } + } + + //grab skin weights array + domSkin::domVertex_weights* weights = skin->getVertex_weights(); + if (weights) + { + domInputLocalOffset_Array& inputs = weights->getInput_array(); + domFloat_array* vertex_weights = NULL; + for (size_t i = 0; i < inputs.getCount(); ++i) + { + if (strcmp(inputs[i]->getSemantic(), COMMON_PROFILE_INPUT_WEIGHT) == 0) + { + domSource* weight_source = daeSafeCast<domSource>(inputs[i]->getSource().getElement()); + if (weight_source) + { + vertex_weights = weight_source->getFloat_array(); + } + } + } + + if (vertex_weights) + { + domListOfFloats& w = vertex_weights->getValue(); + domListOfUInts& vcount = weights->getVcount()->getValue(); + domListOfInts& v = weights->getV()->getValue(); + + U32 c_idx = 0; + for (size_t vc_idx = 0; vc_idx < vcount.getCount(); ++vc_idx) + { //for each vertex + daeUInt count = vcount[vc_idx]; + + //create list of weights that influence this vertex + LLModel::weight_list weight_list; + + for (daeUInt i = 0; i < count; ++i) + { //for each weight + daeInt joint_idx = v[c_idx++]; + daeInt weight_idx = v[c_idx++]; + + if (joint_idx == -1) + { + //ignore bindings to bind_shape_matrix + continue; + } + + F32 weight_value = w[weight_idx]; + + weight_list.push_back(LLModel::JointWeight(joint_idx, weight_value)); + } + + //sort by joint weight + std::sort(weight_list.begin(), weight_list.end(), LLModel::CompareWeightGreater()); + + std::vector<LLModel::JointWeight> wght; + + F32 total = 0.f; + + for (U32 i = 0; i < llmin((U32) 4, (U32) weight_list.size()); ++i) + { //take up to 4 most significant weights + if (weight_list[i].mWeight > 0.f) + { + wght.push_back( weight_list[i] ); + total += weight_list[i].mWeight; + } + } + + F32 scale = 1.f/total; + if (scale != 1.f) + { //normalize weights + for (U32 i = 0; i < wght.size(); ++i) + { + wght[i].mWeight *= scale; + } + } + + model->mSkinWeights[model->mPosition[vc_idx]] = wght; + } + } + + } + + //add instance to scene for this model + + LLMatrix4 transformation; + transformation.initScale(mesh_scale_vector); + transformation.setTranslation(mesh_translation_vector); + transformation *= mTransform; + + std::map<std::string, LLImportMaterial> materials; + for (U32 i = 0; i < model->mMaterialList.size(); ++i) + { + materials[model->mMaterialList[i]] = LLImportMaterial(); + } + mScene[transformation].push_back(LLModelInstance(model, model->mLabel, transformation, materials)); + stretch_extents(model, transformation, mExtents[0], mExtents[1], mFirstTransform); + } } //----------------------------------------------------------------------------- @@ -1695,65 +1695,65 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do //----------------------------------------------------------------------------- void LLDAELoader::buildJointToNodeMappingFromScene( daeElement* pRoot ) { - daeElement* pScene = pRoot->getDescendant("visual_scene"); - if ( pScene ) - { - daeTArray< daeSmartRef<daeElement> > children = pScene->getChildren(); - S32 childCount = children.getCount(); - for (S32 i = 0; i < childCount; ++i) - { - domNode* pNode = daeSafeCast<domNode>(children[i]); - processJointToNodeMapping( pNode ); - } - } + daeElement* pScene = pRoot->getDescendant("visual_scene"); + if ( pScene ) + { + daeTArray< daeSmartRef<daeElement> > children = pScene->getChildren(); + S32 childCount = children.getCount(); + for (S32 i = 0; i < childCount; ++i) + { + domNode* pNode = daeSafeCast<domNode>(children[i]); + processJointToNodeMapping( pNode ); + } + } } //----------------------------------------------------------------------------- // processJointToNodeMapping() //----------------------------------------------------------------------------- void LLDAELoader::processJointToNodeMapping( domNode* pNode ) { - if ( isNodeAJoint( pNode ) ) - { - //1.Store the parent - std::string nodeName = pNode->getName(); - if ( !nodeName.empty() ) - { - mJointsFromNode.push_front( pNode->getName() ); - } - //2. Handle the kiddo's - processChildJoints( pNode ); - } - else - { - //Determine if the're any children wrt to this failed node. - //This occurs when an armature is exported and ends up being what essentially amounts to - //as the root for the visual_scene - if ( pNode ) - { - processChildJoints( pNode ); - } - else - { - LL_INFOS()<<"Node is NULL"<<LL_ENDL; - } - - } + if ( isNodeAJoint( pNode ) ) + { + //1.Store the parent + std::string nodeName = pNode->getName(); + if ( !nodeName.empty() ) + { + mJointsFromNode.push_front( pNode->getName() ); + } + //2. Handle the kiddo's + processChildJoints( pNode ); + } + else + { + //Determine if the're any children wrt to this failed node. + //This occurs when an armature is exported and ends up being what essentially amounts to + //as the root for the visual_scene + if ( pNode ) + { + processChildJoints( pNode ); + } + else + { + LL_INFOS()<<"Node is NULL"<<LL_ENDL; + } + + } } //----------------------------------------------------------------------------- // processChildJoint() //----------------------------------------------------------------------------- void LLDAELoader::processChildJoints( domNode* pParentNode ) -{ - daeTArray< daeSmartRef<daeElement> > childOfChild = pParentNode->getChildren(); - S32 childOfChildCount = childOfChild.getCount(); - for (S32 i = 0; i < childOfChildCount; ++i) - { - domNode* pChildNode = daeSafeCast<domNode>( childOfChild[i] ); - if ( pChildNode ) - { - processJointToNodeMapping( pChildNode ); - } - } +{ + daeTArray< daeSmartRef<daeElement> > childOfChild = pParentNode->getChildren(); + S32 childOfChildCount = childOfChild.getCount(); + for (S32 i = 0; i < childOfChildCount; ++i) + { + domNode* pChildNode = daeSafeCast<domNode>( childOfChild[i] ); + if ( pChildNode ) + { + processJointToNodeMapping( pChildNode ); + } + } } //----------------------------------------------------------------------------- @@ -1762,96 +1762,96 @@ void LLDAELoader::processChildJoints( domNode* pParentNode ) bool LLDAELoader::isNodeAJoint( domNode* pNode ) { if ( !pNode || !pNode->getName() ) - { - LL_INFOS()<<"Created node is NULL or invalid"<<LL_ENDL; - return false; - } - - return LLModelLoader::isNodeAJoint(pNode->getName()); + { + LL_INFOS()<<"Created node is NULL or invalid"<<LL_ENDL; + return false; + } + + return LLModelLoader::isNodeAJoint(pNode->getName()); } //----------------------------------------------------------------------------- // verifyCount //----------------------------------------------------------------------------- bool LLDAELoader::verifyCount( int expected, int result ) { - if ( expected != result ) - { - LL_INFOS()<< "Error: (expected/got)"<<expected<<"/"<<result<<"verts"<<LL_ENDL; - return false; - } - return true; + if ( expected != result ) + { + LL_INFOS()<< "Error: (expected/got)"<<expected<<"/"<<result<<"verts"<<LL_ENDL; + return false; + } + return true; } //----------------------------------------------------------------------------- // verifyController //----------------------------------------------------------------------------- bool LLDAELoader::verifyController( domController* pController ) -{ - - bool result = true; - - domSkin* pSkin = pController->getSkin(); - - if ( pSkin ) - { - xsAnyURI & uri = pSkin->getSource(); - domElement* pElement = uri.getElement(); - - if ( !pElement ) - { - LL_INFOS()<<"Can't resolve skin source"<<LL_ENDL; - return false; - } - - daeString type_str = pElement->getTypeName(); - if ( stricmp(type_str, "geometry") == 0 ) - { - //Skin is reference directly by geometry and get the vertex count from skin - domSkin::domVertex_weights* pVertexWeights = pSkin->getVertex_weights(); - U32 vertexWeightsCount = pVertexWeights->getCount(); - domGeometry* pGeometry = (domGeometry*) (domElement*) uri.getElement(); - domMesh* pMesh = pGeometry->getMesh(); - - if ( pMesh ) - { - //Get vertex count from geometry - domVertices* pVertices = pMesh->getVertices(); - if ( !pVertices ) - { - LL_INFOS()<<"No vertices!"<<LL_ENDL; - return false; - } - - if ( pVertices ) - { - xsAnyURI src = pVertices->getInput_array()[0]->getSource(); - domSource* pSource = (domSource*) (domElement*) src.getElement(); - U32 verticesCount = pSource->getTechnique_common()->getAccessor()->getCount(); - result = verifyCount( verticesCount, vertexWeightsCount ); - if ( !result ) - { - return result; - } - } - } - - U32 vcountCount = (U32) pVertexWeights->getVcount()->getValue().getCount(); - result = verifyCount( vcountCount, vertexWeightsCount ); - if ( !result ) - { - return result; - } - - domInputLocalOffset_Array& inputs = pVertexWeights->getInput_array(); - U32 sum = 0; - for (size_t i=0; i<vcountCount; i++) - { - sum += pVertexWeights->getVcount()->getValue()[i]; - } - result = verifyCount( sum * inputs.getCount(), (domInt) pVertexWeights->getV()->getValue().getCount() ); - } - } - - return result; +{ + + bool result = true; + + domSkin* pSkin = pController->getSkin(); + + if ( pSkin ) + { + xsAnyURI & uri = pSkin->getSource(); + domElement* pElement = uri.getElement(); + + if ( !pElement ) + { + LL_INFOS()<<"Can't resolve skin source"<<LL_ENDL; + return false; + } + + daeString type_str = pElement->getTypeName(); + if ( stricmp(type_str, "geometry") == 0 ) + { + //Skin is reference directly by geometry and get the vertex count from skin + domSkin::domVertex_weights* pVertexWeights = pSkin->getVertex_weights(); + U32 vertexWeightsCount = pVertexWeights->getCount(); + domGeometry* pGeometry = (domGeometry*) (domElement*) uri.getElement(); + domMesh* pMesh = pGeometry->getMesh(); + + if ( pMesh ) + { + //Get vertex count from geometry + domVertices* pVertices = pMesh->getVertices(); + if ( !pVertices ) + { + LL_INFOS()<<"No vertices!"<<LL_ENDL; + return false; + } + + if ( pVertices ) + { + xsAnyURI src = pVertices->getInput_array()[0]->getSource(); + domSource* pSource = (domSource*) (domElement*) src.getElement(); + U32 verticesCount = pSource->getTechnique_common()->getAccessor()->getCount(); + result = verifyCount( verticesCount, vertexWeightsCount ); + if ( !result ) + { + return result; + } + } + } + + U32 vcountCount = (U32) pVertexWeights->getVcount()->getValue().getCount(); + result = verifyCount( vcountCount, vertexWeightsCount ); + if ( !result ) + { + return result; + } + + domInputLocalOffset_Array& inputs = pVertexWeights->getInput_array(); + U32 sum = 0; + for (size_t i=0; i<vcountCount; i++) + { + sum += pVertexWeights->getVcount()->getValue()[i]; + } + result = verifyCount( sum * inputs.getCount(), (domInt) pVertexWeights->getV()->getValue().getCount() ); + } + } + + return result; } //----------------------------------------------------------------------------- @@ -1859,67 +1859,67 @@ bool LLDAELoader::verifyController( domController* pController ) //----------------------------------------------------------------------------- void LLDAELoader::extractTranslation( domTranslate* pTranslate, LLMatrix4& transform ) { - domFloat3 jointTrans = pTranslate->getValue(); - LLVector3 singleJointTranslation( jointTrans[0], jointTrans[1], jointTrans[2] ); - transform.setTranslation( singleJointTranslation ); + domFloat3 jointTrans = pTranslate->getValue(); + LLVector3 singleJointTranslation( jointTrans[0], jointTrans[1], jointTrans[2] ); + transform.setTranslation( singleJointTranslation ); } //----------------------------------------------------------------------------- // extractTranslationViaElement() //----------------------------------------------------------------------------- void LLDAELoader::extractTranslationViaElement( daeElement* pTranslateElement, LLMatrix4& transform ) { - if ( pTranslateElement ) - { - domTranslate* pTranslateChild = static_cast<domTranslate*>( pTranslateElement ); - domFloat3 translateChild = pTranslateChild->getValue(); - LLVector3 singleJointTranslation( translateChild[0], translateChild[1], translateChild[2] ); - transform.setTranslation( singleJointTranslation ); - } + if ( pTranslateElement ) + { + domTranslate* pTranslateChild = static_cast<domTranslate*>( pTranslateElement ); + domFloat3 translateChild = pTranslateChild->getValue(); + LLVector3 singleJointTranslation( translateChild[0], translateChild[1], translateChild[2] ); + transform.setTranslation( singleJointTranslation ); + } } //----------------------------------------------------------------------------- // extractTranslationViaSID() //----------------------------------------------------------------------------- void LLDAELoader::extractTranslationViaSID( daeElement* pElement, LLMatrix4& transform ) { - if ( pElement ) - { - daeSIDResolver resolver( pElement, "./transform" ); - domMatrix* pMatrix = daeSafeCast<domMatrix>( resolver.getElement() ); - //We are only extracting out the translational component atm - LLMatrix4 workingTransform; - if ( pMatrix ) - { - domFloat4x4 domArray = pMatrix->getValue(); - for ( int i = 0; i < 4; i++ ) - { - for( int j = 0; j < 4; j++ ) - { - workingTransform.mMatrix[i][j] = domArray[i + j*4]; - } - } - LLVector3 trans = workingTransform.getTranslation(); - transform.setTranslation( trans ); - } - } - else - { - LL_WARNS()<<"Element is nonexistent - empty/unsupported node."<<LL_ENDL; - } + if ( pElement ) + { + daeSIDResolver resolver( pElement, "./transform" ); + domMatrix* pMatrix = daeSafeCast<domMatrix>( resolver.getElement() ); + //We are only extracting out the translational component atm + LLMatrix4 workingTransform; + if ( pMatrix ) + { + domFloat4x4 domArray = pMatrix->getValue(); + for ( int i = 0; i < 4; i++ ) + { + for( int j = 0; j < 4; j++ ) + { + workingTransform.mMatrix[i][j] = domArray[i + j*4]; + } + } + LLVector3 trans = workingTransform.getTranslation(); + transform.setTranslation( trans ); + } + } + else + { + LL_WARNS()<<"Element is nonexistent - empty/unsupported node."<<LL_ENDL; + } } //----------------------------------------------------------------------------- // processJointNode() //----------------------------------------------------------------------------- void LLDAELoader::processJointNode( domNode* pNode, JointTransformMap& jointTransforms ) { - if (pNode->getName() == NULL) - { - LL_WARNS() << "nameless node, can't process" << LL_ENDL; - return; - } + if (pNode->getName() == NULL) + { + LL_WARNS() << "nameless node, can't process" << LL_ENDL; + return; + } - //LL_WARNS()<<"ProcessJointNode# Node:" <<pNode->getName()<<LL_ENDL; + //LL_WARNS()<<"ProcessJointNode# Node:" <<pNode->getName()<<LL_ENDL; - //1. handle the incoming node - extract out translation via SID or element + //1. handle the incoming node - extract out translation via SID or element if (isNodeAJoint(pNode)) { LLMatrix4 workingTransform; @@ -1976,20 +1976,20 @@ void LLDAELoader::processJointNode( domNode* pNode, JointTransformMap& jointTran jointTransforms[pNode->getName()] = workingTransform; } - //2. handle the nodes children + //2. handle the nodes children - //Gather and handle the incoming nodes children - daeTArray< daeSmartRef<daeElement> > childOfChild = pNode->getChildren(); - S32 childOfChildCount = childOfChild.getCount(); + //Gather and handle the incoming nodes children + daeTArray< daeSmartRef<daeElement> > childOfChild = pNode->getChildren(); + S32 childOfChildCount = childOfChild.getCount(); - for (S32 i = 0; i < childOfChildCount; ++i) - { - domNode* pChildNode = daeSafeCast<domNode>( childOfChild[i] ); - if ( pChildNode ) - { - processJointNode( pChildNode, jointTransforms ); - } - } + for (S32 i = 0; i < childOfChildCount; ++i) + { + domNode* pChildNode = daeSafeCast<domNode>( childOfChild[i] ); + if ( pChildNode ) + { + processJointNode( pChildNode, jointTransforms ); + } + } } //----------------------------------------------------------------------------- // getChildFromElement() @@ -1997,512 +1997,512 @@ void LLDAELoader::processJointNode( domNode* pNode, JointTransformMap& jointTran daeElement* LLDAELoader::getChildFromElement( daeElement* pElement, std::string const & name ) { daeElement* pChildOfElement = pElement->getChild( name.c_str() ); - if ( pChildOfElement ) - { - return pChildOfElement; - } - LL_DEBUGS("Mesh")<< "Could not find a child [" << name << "] for the element: \"" << pElement->getAttribute("id") << "\"" << LL_ENDL; + if ( pChildOfElement ) + { + return pChildOfElement; + } + LL_DEBUGS("Mesh")<< "Could not find a child [" << name << "] for the element: \"" << pElement->getAttribute("id") << "\"" << LL_ENDL; return NULL; } void LLDAELoader::processElement( daeElement* element, bool& badElement, DAE* dae) { - LLMatrix4 saved_transform; - bool pushed_mat = false; - - domNode* node = daeSafeCast<domNode>(element); - if (node) - { - pushed_mat = true; - saved_transform = mTransform; - } - - domTranslate* translate = daeSafeCast<domTranslate>(element); - if (translate) - { - domFloat3 dom_value = translate->getValue(); - - LLMatrix4 translation; - translation.setTranslation(LLVector3(dom_value[0], dom_value[1], dom_value[2])); - - translation *= mTransform; - mTransform = translation; - mTransform.condition(); - } - - domRotate* rotate = daeSafeCast<domRotate>(element); - if (rotate) - { - domFloat4 dom_value = rotate->getValue(); - - LLMatrix4 rotation; - rotation.initRotTrans(dom_value[3] * DEG_TO_RAD, LLVector3(dom_value[0], dom_value[1], dom_value[2]), LLVector3(0, 0, 0)); - - rotation *= mTransform; - mTransform = rotation; - mTransform.condition(); - } - - domScale* scale = daeSafeCast<domScale>(element); - if (scale) - { - domFloat3 dom_value = scale->getValue(); - - - LLVector3 scale_vector = LLVector3(dom_value[0], dom_value[1], dom_value[2]); - scale_vector.abs(); // Set all values positive, since we don't currently support mirrored meshes - LLMatrix4 scaling; - scaling.initScale(scale_vector); - - scaling *= mTransform; - mTransform = scaling; - mTransform.condition(); - } - - domMatrix* matrix = daeSafeCast<domMatrix>(element); - if (matrix) - { - domFloat4x4 dom_value = matrix->getValue(); - - LLMatrix4 matrix_transform; - - for (int i = 0; i < 4; i++) - { - for(int j = 0; j < 4; j++) - { - matrix_transform.mMatrix[i][j] = dom_value[i + j*4]; - } - } - - matrix_transform *= mTransform; - mTransform = matrix_transform; - mTransform.condition(); - } - - domInstance_geometry* instance_geo = daeSafeCast<domInstance_geometry>(element); - if (instance_geo) - { - domGeometry* geo = daeSafeCast<domGeometry>(instance_geo->getUrl().getElement()); - if (geo) - { - domMesh* mesh = daeSafeCast<domMesh>(geo->getDescendant(daeElement::matchType(domMesh::ID()))); - if (mesh) - { - - std::vector< LLPointer< LLModel > >::iterator i = mModelsMap[mesh].begin(); - while (i != mModelsMap[mesh].end()) - { - LLModel* model = *i; - - LLMatrix4 transformation = mTransform; - - if (mTransform.determinant() < 0) - { //negative scales are not supported - LL_INFOS() << "Negative scale detected, unsupported transform. domInstance_geometry: " << getElementLabel(instance_geo) << LL_ENDL; + LLMatrix4 saved_transform; + bool pushed_mat = false; + + domNode* node = daeSafeCast<domNode>(element); + if (node) + { + pushed_mat = true; + saved_transform = mTransform; + } + + domTranslate* translate = daeSafeCast<domTranslate>(element); + if (translate) + { + domFloat3 dom_value = translate->getValue(); + + LLMatrix4 translation; + translation.setTranslation(LLVector3(dom_value[0], dom_value[1], dom_value[2])); + + translation *= mTransform; + mTransform = translation; + mTransform.condition(); + } + + domRotate* rotate = daeSafeCast<domRotate>(element); + if (rotate) + { + domFloat4 dom_value = rotate->getValue(); + + LLMatrix4 rotation; + rotation.initRotTrans(dom_value[3] * DEG_TO_RAD, LLVector3(dom_value[0], dom_value[1], dom_value[2]), LLVector3(0, 0, 0)); + + rotation *= mTransform; + mTransform = rotation; + mTransform.condition(); + } + + domScale* scale = daeSafeCast<domScale>(element); + if (scale) + { + domFloat3 dom_value = scale->getValue(); + + + LLVector3 scale_vector = LLVector3(dom_value[0], dom_value[1], dom_value[2]); + scale_vector.abs(); // Set all values positive, since we don't currently support mirrored meshes + LLMatrix4 scaling; + scaling.initScale(scale_vector); + + scaling *= mTransform; + mTransform = scaling; + mTransform.condition(); + } + + domMatrix* matrix = daeSafeCast<domMatrix>(element); + if (matrix) + { + domFloat4x4 dom_value = matrix->getValue(); + + LLMatrix4 matrix_transform; + + for (int i = 0; i < 4; i++) + { + for(int j = 0; j < 4; j++) + { + matrix_transform.mMatrix[i][j] = dom_value[i + j*4]; + } + } + + matrix_transform *= mTransform; + mTransform = matrix_transform; + mTransform.condition(); + } + + domInstance_geometry* instance_geo = daeSafeCast<domInstance_geometry>(element); + if (instance_geo) + { + domGeometry* geo = daeSafeCast<domGeometry>(instance_geo->getUrl().getElement()); + if (geo) + { + domMesh* mesh = daeSafeCast<domMesh>(geo->getDescendant(daeElement::matchType(domMesh::ID()))); + if (mesh) + { + + std::vector< LLPointer< LLModel > >::iterator i = mModelsMap[mesh].begin(); + while (i != mModelsMap[mesh].end()) + { + LLModel* model = *i; + + LLMatrix4 transformation = mTransform; + + if (mTransform.determinant() < 0) + { //negative scales are not supported + LL_INFOS() << "Negative scale detected, unsupported transform. domInstance_geometry: " << getElementLabel(instance_geo) << LL_ENDL; LLSD args; args["Message"] = "NegativeScaleTrans"; args["LABEL"] = getElementLabel(instance_geo); mWarningsArray.append(args); - badElement = true; - } - - LLModelLoader::material_map materials = getMaterials(model, instance_geo, dae); - - // adjust the transformation to compensate for mesh normalization - LLVector3 mesh_scale_vector; - LLVector3 mesh_translation_vector; - model->getNormalizedScaleTranslation(mesh_scale_vector, mesh_translation_vector); - - LLMatrix4 mesh_translation; - mesh_translation.setTranslation(mesh_translation_vector); - mesh_translation *= transformation; - transformation = mesh_translation; - - LLMatrix4 mesh_scale; - mesh_scale.initScale(mesh_scale_vector); - mesh_scale *= transformation; - transformation = mesh_scale; - - if (transformation.determinant() < 0) - { //negative scales are not supported - LL_INFOS() << "Negative scale detected, unsupported post-normalization transform. domInstance_geometry: " << getElementLabel(instance_geo) << LL_ENDL; + badElement = true; + } + + LLModelLoader::material_map materials = getMaterials(model, instance_geo, dae); + + // adjust the transformation to compensate for mesh normalization + LLVector3 mesh_scale_vector; + LLVector3 mesh_translation_vector; + model->getNormalizedScaleTranslation(mesh_scale_vector, mesh_translation_vector); + + LLMatrix4 mesh_translation; + mesh_translation.setTranslation(mesh_translation_vector); + mesh_translation *= transformation; + transformation = mesh_translation; + + LLMatrix4 mesh_scale; + mesh_scale.initScale(mesh_scale_vector); + mesh_scale *= transformation; + transformation = mesh_scale; + + if (transformation.determinant() < 0) + { //negative scales are not supported + LL_INFOS() << "Negative scale detected, unsupported post-normalization transform. domInstance_geometry: " << getElementLabel(instance_geo) << LL_ENDL; LLSD args; args["Message"] = "NegativeScaleNormTrans"; args["LABEL"] = getElementLabel(instance_geo); mWarningsArray.append(args); - badElement = true; - } - - std::string label; - - if (model->mLabel.empty()) - { - label = getLodlessLabel(instance_geo); - - llassert(!label.empty()); - - if (model->mSubmodelID) - { - label += (char)((int)'a' + model->mSubmodelID); - } - - model->mLabel = label + lod_suffix[mLod]; - } - else - { - // Don't change model's name if possible, it will play havoc with scenes that already use said model. - size_t ext_pos = getSuffixPosition(model->mLabel); - if (ext_pos != -1) - { - label = model->mLabel.substr(0, ext_pos); - } - else - { - label = model->mLabel; - } - } - - mScene[transformation].push_back(LLModelInstance(model, label, transformation, materials)); - stretch_extents(model, transformation, mExtents[0], mExtents[1], mFirstTransform); - i++; - } - } - } - else - { - LL_INFOS()<<"Unable to resolve geometry URL."<<LL_ENDL; + badElement = true; + } + + std::string label; + + if (model->mLabel.empty()) + { + label = getLodlessLabel(instance_geo); + + llassert(!label.empty()); + + if (model->mSubmodelID) + { + label += (char)((int)'a' + model->mSubmodelID); + } + + model->mLabel = label + lod_suffix[mLod]; + } + else + { + // Don't change model's name if possible, it will play havoc with scenes that already use said model. + size_t ext_pos = getSuffixPosition(model->mLabel); + if (ext_pos != -1) + { + label = model->mLabel.substr(0, ext_pos); + } + else + { + label = model->mLabel; + } + } + + mScene[transformation].push_back(LLModelInstance(model, label, transformation, materials)); + stretch_extents(model, transformation, mExtents[0], mExtents[1], mFirstTransform); + i++; + } + } + } + else + { + LL_INFOS()<<"Unable to resolve geometry URL."<<LL_ENDL; LLSD args; args["Message"] = "CantResolveGeometryUrl"; mWarningsArray.append(args); - badElement = true; - } - - } - - domInstance_node* instance_node = daeSafeCast<domInstance_node>(element); - if (instance_node) - { - daeElement* instance = instance_node->getUrl().getElement(); - if (instance) - { - processElement(instance,badElement, dae); - } - } - - //process children - daeTArray< daeSmartRef<daeElement> > children = element->getChildren(); - int childCount = children.getCount(); - for (S32 i = 0; i < childCount; i++) - { - processElement(children[i],badElement, dae); - } - - if (pushed_mat) - { //this element was a node, restore transform before processiing siblings - mTransform = saved_transform; - } + badElement = true; + } + + } + + domInstance_node* instance_node = daeSafeCast<domInstance_node>(element); + if (instance_node) + { + daeElement* instance = instance_node->getUrl().getElement(); + if (instance) + { + processElement(instance,badElement, dae); + } + } + + //process children + daeTArray< daeSmartRef<daeElement> > children = element->getChildren(); + int childCount = children.getCount(); + for (S32 i = 0; i < childCount; i++) + { + processElement(children[i],badElement, dae); + } + + if (pushed_mat) + { //this element was a node, restore transform before processiing siblings + mTransform = saved_transform; + } } std::map<std::string, LLImportMaterial> LLDAELoader::getMaterials(LLModel* model, domInstance_geometry* instance_geo, DAE* dae) { - std::map<std::string, LLImportMaterial> materials; - for (int i = 0; i < model->mMaterialList.size(); i++) - { - LLImportMaterial import_material; - - domInstance_material* instance_mat = NULL; - - domBind_material::domTechnique_common* technique = - daeSafeCast<domBind_material::domTechnique_common>(instance_geo->getDescendant(daeElement::matchType(domBind_material::domTechnique_common::ID()))); - - if (technique) - { - daeTArray< daeSmartRef<domInstance_material> > inst_materials = technique->getChildrenByType<domInstance_material>(); - for (int j = 0; j < inst_materials.getCount(); j++) - { - std::string symbol(inst_materials[j]->getSymbol()); - - if (symbol == model->mMaterialList[i]) // found the binding - { - instance_mat = inst_materials[j]; - break; - } - } - } - - if (instance_mat) - { - domMaterial* material = daeSafeCast<domMaterial>(instance_mat->getTarget().getElement()); - if (material) - { - domInstance_effect* instance_effect = - daeSafeCast<domInstance_effect>(material->getDescendant(daeElement::matchType(domInstance_effect::ID()))); - if (instance_effect) - { - domEffect* effect = daeSafeCast<domEffect>(instance_effect->getUrl().getElement()); - if (effect) - { - domProfile_COMMON* profile = - daeSafeCast<domProfile_COMMON>(effect->getDescendant(daeElement::matchType(domProfile_COMMON::ID()))); - if (profile) - { - import_material = profileToMaterial(profile, dae); - } - } - } - } - } - - import_material.mBinding = model->mMaterialList[i]; - materials[model->mMaterialList[i]] = import_material; - } - - return materials; + std::map<std::string, LLImportMaterial> materials; + for (int i = 0; i < model->mMaterialList.size(); i++) + { + LLImportMaterial import_material; + + domInstance_material* instance_mat = NULL; + + domBind_material::domTechnique_common* technique = + daeSafeCast<domBind_material::domTechnique_common>(instance_geo->getDescendant(daeElement::matchType(domBind_material::domTechnique_common::ID()))); + + if (technique) + { + daeTArray< daeSmartRef<domInstance_material> > inst_materials = technique->getChildrenByType<domInstance_material>(); + for (int j = 0; j < inst_materials.getCount(); j++) + { + std::string symbol(inst_materials[j]->getSymbol()); + + if (symbol == model->mMaterialList[i]) // found the binding + { + instance_mat = inst_materials[j]; + break; + } + } + } + + if (instance_mat) + { + domMaterial* material = daeSafeCast<domMaterial>(instance_mat->getTarget().getElement()); + if (material) + { + domInstance_effect* instance_effect = + daeSafeCast<domInstance_effect>(material->getDescendant(daeElement::matchType(domInstance_effect::ID()))); + if (instance_effect) + { + domEffect* effect = daeSafeCast<domEffect>(instance_effect->getUrl().getElement()); + if (effect) + { + domProfile_COMMON* profile = + daeSafeCast<domProfile_COMMON>(effect->getDescendant(daeElement::matchType(domProfile_COMMON::ID()))); + if (profile) + { + import_material = profileToMaterial(profile, dae); + } + } + } + } + } + + import_material.mBinding = model->mMaterialList[i]; + materials[model->mMaterialList[i]] = import_material; + } + + return materials; } LLImportMaterial LLDAELoader::profileToMaterial(domProfile_COMMON* material, DAE* dae) { - LLImportMaterial mat; - mat.mFullbright = FALSE; - - daeElement* diffuse = material->getDescendant("diffuse"); - if (diffuse) - { - domCommon_color_or_texture_type_complexType::domTexture* texture = - daeSafeCast<domCommon_color_or_texture_type_complexType::domTexture>(diffuse->getDescendant("texture")); - if (texture) - { - domCommon_newparam_type_Array newparams = material->getNewparam_array(); - if (newparams.getCount()) - { - - for (S32 i = 0; i < newparams.getCount(); i++) - { - domFx_surface_common* surface = newparams[i]->getSurface(); - if (surface) - { - domFx_surface_init_common* init = surface->getFx_surface_init_common(); - if (init) - { - domFx_surface_init_from_common_Array init_from = init->getInit_from_array(); - - if (init_from.getCount() > i) - { - domImage* image = daeSafeCast<domImage>(init_from[i]->getValue().getElement()); - if (image) - { - // we only support init_from now - embedded data will come later - domImage::domInit_from* init = image->getInit_from(); - if (init) - { - mat.mDiffuseMapFilename = cdom::uriToNativePath(init->getValue().str()); - mat.mDiffuseMapLabel = getElementLabel(material); - } - } - } - } - } - } - } - else if (texture->getTexture()) - { - domImage* image = NULL; - dae->getDatabase()->getElement((daeElement**) &image, 0, texture->getTexture(), COLLADA_TYPE_IMAGE); - if (image) - { - // we only support init_from now - embedded data will come later - domImage::domInit_from* init = image->getInit_from(); - if (init) - { - std::string image_path_value = cdom::uriToNativePath(init->getValue().str()); + LLImportMaterial mat; + mat.mFullbright = FALSE; + + daeElement* diffuse = material->getDescendant("diffuse"); + if (diffuse) + { + domCommon_color_or_texture_type_complexType::domTexture* texture = + daeSafeCast<domCommon_color_or_texture_type_complexType::domTexture>(diffuse->getDescendant("texture")); + if (texture) + { + domCommon_newparam_type_Array newparams = material->getNewparam_array(); + if (newparams.getCount()) + { + + for (S32 i = 0; i < newparams.getCount(); i++) + { + domFx_surface_common* surface = newparams[i]->getSurface(); + if (surface) + { + domFx_surface_init_common* init = surface->getFx_surface_init_common(); + if (init) + { + domFx_surface_init_from_common_Array init_from = init->getInit_from_array(); + + if (init_from.getCount() > i) + { + domImage* image = daeSafeCast<domImage>(init_from[i]->getValue().getElement()); + if (image) + { + // we only support init_from now - embedded data will come later + domImage::domInit_from* init = image->getInit_from(); + if (init) + { + mat.mDiffuseMapFilename = cdom::uriToNativePath(init->getValue().str()); + mat.mDiffuseMapLabel = getElementLabel(material); + } + } + } + } + } + } + } + else if (texture->getTexture()) + { + domImage* image = NULL; + dae->getDatabase()->getElement((daeElement**) &image, 0, texture->getTexture(), COLLADA_TYPE_IMAGE); + if (image) + { + // we only support init_from now - embedded data will come later + domImage::domInit_from* init = image->getInit_from(); + if (init) + { + std::string image_path_value = cdom::uriToNativePath(init->getValue().str()); #if LL_WINDOWS - // Work-around DOM tendency to resort to UNC names which are only confusing for downstream... - // - std::string::iterator i = image_path_value.begin(); - while (*i == '\\') - i++; - mat.mDiffuseMapFilename.assign(i, image_path_value.end()); + // Work-around DOM tendency to resort to UNC names which are only confusing for downstream... + // + std::string::iterator i = image_path_value.begin(); + while (*i == '\\') + i++; + mat.mDiffuseMapFilename.assign(i, image_path_value.end()); #else - mat.mDiffuseMapFilename = image_path_value; + mat.mDiffuseMapFilename = image_path_value; #endif - mat.mDiffuseMapLabel = getElementLabel(material); - } - } - } - } - - domCommon_color_or_texture_type_complexType::domColor* color = - daeSafeCast<domCommon_color_or_texture_type_complexType::domColor>(diffuse->getDescendant("color")); - if (color) - { - domFx_color_common domfx_color = color->getValue(); - LLColor4 value = LLColor4(domfx_color[0], domfx_color[1], domfx_color[2], domfx_color[3]); - mat.mDiffuseColor = value; - } - } - - daeElement* emission = material->getDescendant("emission"); - if (emission) - { - LLColor4 emission_color = getDaeColor(emission); - if (((emission_color[0] + emission_color[1] + emission_color[2]) / 3.0) > 0.25) - { - mat.mFullbright = TRUE; - } - } - - return mat; + mat.mDiffuseMapLabel = getElementLabel(material); + } + } + } + } + + domCommon_color_or_texture_type_complexType::domColor* color = + daeSafeCast<domCommon_color_or_texture_type_complexType::domColor>(diffuse->getDescendant("color")); + if (color) + { + domFx_color_common domfx_color = color->getValue(); + LLColor4 value = LLColor4(domfx_color[0], domfx_color[1], domfx_color[2], domfx_color[3]); + mat.mDiffuseColor = value; + } + } + + daeElement* emission = material->getDescendant("emission"); + if (emission) + { + LLColor4 emission_color = getDaeColor(emission); + if (((emission_color[0] + emission_color[1] + emission_color[2]) / 3.0) > 0.25) + { + mat.mFullbright = TRUE; + } + } + + return mat; } // try to get a decent label for this element std::string LLDAELoader::getElementLabel(daeElement *element) { - // if we have a name attribute, use it - std::string name = element->getAttribute("name"); - if (name.length()) - { - return name; - } - - // if we have an ID attribute, use it - if (element->getID()) - { - return std::string(element->getID()); - } - - // if we have a parent, use it - daeElement* parent = element->getParent(); - std::string index_string; - if (parent) - { - // retrieve index to distinguish items inside same parent - size_t ind = 0; - parent->getChildren().find(element, ind); - - if (ind > 0) - { - index_string = "_" + std::to_string(ind); - } - - // if parent has a name or ID, use it - std::string name = parent->getAttribute("name"); - if (!name.length()) - { - name = std::string(parent->getID()); - } - - if (name.length()) - { - // make sure that index won't mix up with pre-named lod extensions - size_t ext_pos = getSuffixPosition(name); - - if (ext_pos == -1) - { - return name + index_string; - } - else - { - return name.insert(ext_pos, index_string); - } - } - } - - // try to use our type - daeString element_name = element->getElementName(); - if (element_name) - { - return std::string(element_name) + index_string; - } - - // if all else fails, use "object" - return std::string("object") + index_string; + // if we have a name attribute, use it + std::string name = element->getAttribute("name"); + if (name.length()) + { + return name; + } + + // if we have an ID attribute, use it + if (element->getID()) + { + return std::string(element->getID()); + } + + // if we have a parent, use it + daeElement* parent = element->getParent(); + std::string index_string; + if (parent) + { + // retrieve index to distinguish items inside same parent + size_t ind = 0; + parent->getChildren().find(element, ind); + + if (ind > 0) + { + index_string = "_" + std::to_string(ind); + } + + // if parent has a name or ID, use it + std::string name = parent->getAttribute("name"); + if (!name.length()) + { + name = std::string(parent->getID()); + } + + if (name.length()) + { + // make sure that index won't mix up with pre-named lod extensions + size_t ext_pos = getSuffixPosition(name); + + if (ext_pos == -1) + { + return name + index_string; + } + else + { + return name.insert(ext_pos, index_string); + } + } + } + + // try to use our type + daeString element_name = element->getElementName(); + if (element_name) + { + return std::string(element_name) + index_string; + } + + // if all else fails, use "object" + return std::string("object") + index_string; } // static size_t LLDAELoader::getSuffixPosition(std::string label) { - if ((label.find("_LOD") != -1) || (label.find("_PHYS") != -1)) - { - return label.rfind('_'); - } - return -1; + if ((label.find("_LOD") != -1) || (label.find("_PHYS") != -1)) + { + return label.rfind('_'); + } + return -1; } // static std::string LLDAELoader::getLodlessLabel(daeElement *element) { - std::string label = getElementLabel(element); - size_t ext_pos = getSuffixPosition(label); - if (ext_pos != -1) - { - return label.substr(0, ext_pos); - } - return label; + std::string label = getElementLabel(element); + size_t ext_pos = getSuffixPosition(label); + if (ext_pos != -1) + { + return label.substr(0, ext_pos); + } + return label; } LLColor4 LLDAELoader::getDaeColor(daeElement* element) { - LLColor4 value; - domCommon_color_or_texture_type_complexType::domColor* color = - daeSafeCast<domCommon_color_or_texture_type_complexType::domColor>(element->getDescendant("color")); - if (color) - { - domFx_color_common domfx_color = color->getValue(); - value = LLColor4(domfx_color[0], domfx_color[1], domfx_color[2], domfx_color[3]); - } - - return value; + LLColor4 value; + domCommon_color_or_texture_type_complexType::domColor* color = + daeSafeCast<domCommon_color_or_texture_type_complexType::domColor>(element->getDescendant("color")); + if (color) + { + domFx_color_common domfx_color = color->getValue(); + value = LLColor4(domfx_color[0], domfx_color[1], domfx_color[2], domfx_color[3]); + } + + return value; } bool LLDAELoader::addVolumeFacesFromDomMesh(LLModel* pModel,domMesh* mesh, LLSD& log_msg) { - LLModel::EModelStatus status = LLModel::NO_ERRORS; - domTriangles_Array& tris = mesh->getTriangles_array(); - - for (U32 i = 0; i < tris.getCount(); ++i) - { - domTrianglesRef& tri = tris.get(i); - - status = load_face_from_dom_triangles(pModel->getVolumeFaces(), pModel->getMaterialList(), tri, log_msg); - pModel->mStatus = status; - if(status != LLModel::NO_ERRORS) - { - pModel->ClearFacesAndMaterials(); - return false; - } - } - - domPolylist_Array& polys = mesh->getPolylist_array(); - for (U32 i = 0; i < polys.getCount(); ++i) - { - domPolylistRef& poly = polys.get(i); - status = load_face_from_dom_polylist(pModel->getVolumeFaces(), pModel->getMaterialList(), poly, log_msg); - - if(status != LLModel::NO_ERRORS) - { - pModel->ClearFacesAndMaterials(); - return false; - } - } - - domPolygons_Array& polygons = mesh->getPolygons_array(); - - for (U32 i = 0; i < polygons.getCount(); ++i) - { - domPolygonsRef& poly = polygons.get(i); - - status = load_face_from_dom_polygons(pModel->getVolumeFaces(), pModel->getMaterialList(), poly); - - if(status != LLModel::NO_ERRORS) - { - pModel->ClearFacesAndMaterials(); - return false; - } - } - - return (status == LLModel::NO_ERRORS); + LLModel::EModelStatus status = LLModel::NO_ERRORS; + domTriangles_Array& tris = mesh->getTriangles_array(); + + for (U32 i = 0; i < tris.getCount(); ++i) + { + domTrianglesRef& tri = tris.get(i); + + status = load_face_from_dom_triangles(pModel->getVolumeFaces(), pModel->getMaterialList(), tri, log_msg); + pModel->mStatus = status; + if(status != LLModel::NO_ERRORS) + { + pModel->ClearFacesAndMaterials(); + return false; + } + } + + domPolylist_Array& polys = mesh->getPolylist_array(); + for (U32 i = 0; i < polys.getCount(); ++i) + { + domPolylistRef& poly = polys.get(i); + status = load_face_from_dom_polylist(pModel->getVolumeFaces(), pModel->getMaterialList(), poly, log_msg); + + if(status != LLModel::NO_ERRORS) + { + pModel->ClearFacesAndMaterials(); + return false; + } + } + + domPolygons_Array& polygons = mesh->getPolygons_array(); + + for (U32 i = 0; i < polygons.getCount(); ++i) + { + domPolygonsRef& poly = polygons.get(i); + + status = load_face_from_dom_polygons(pModel->getVolumeFaces(), pModel->getMaterialList(), poly); + + if(status != LLModel::NO_ERRORS) + { + pModel->ClearFacesAndMaterials(); + return false; + } + } + + return (status == LLModel::NO_ERRORS); } //static diff version supports creating multiple models when material counts spill @@ -2511,89 +2511,89 @@ bool LLDAELoader::addVolumeFacesFromDomMesh(LLModel* pModel,domMesh* mesh, LLSD& bool LLDAELoader::loadModelsFromDomMesh(domMesh* mesh, std::vector<LLModel*>& models_out, U32 submodel_limit) { - LLVolumeParams volume_params; - volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE); + LLVolumeParams volume_params; + volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE); - models_out.clear(); + models_out.clear(); - LLModel* ret = new LLModel(volume_params, 0.f); + LLModel* ret = new LLModel(volume_params, 0.f); - std::string model_name = getLodlessLabel(mesh); - ret->mLabel = model_name + lod_suffix[mLod]; + std::string model_name = getLodlessLabel(mesh); + ret->mLabel = model_name + lod_suffix[mLod]; - llassert(!ret->mLabel.empty()); + llassert(!ret->mLabel.empty()); - // Like a monkey, ready to be shot into space - // - ret->ClearFacesAndMaterials(); + // Like a monkey, ready to be shot into space + // + ret->ClearFacesAndMaterials(); - // Get the whole set of volume faces - // - addVolumeFacesFromDomMesh(ret, mesh, mWarningsArray); + // Get the whole set of volume faces + // + addVolumeFacesFromDomMesh(ret, mesh, mWarningsArray); - U32 volume_faces = ret->getNumVolumeFaces(); + U32 volume_faces = ret->getNumVolumeFaces(); - // Side-steps all manner of issues when splitting models - // and matching lower LOD materials to base models - // - ret->sortVolumeFacesByMaterialName(); + // Side-steps all manner of issues when splitting models + // and matching lower LOD materials to base models + // + ret->sortVolumeFacesByMaterialName(); - bool normalized = false; + bool normalized = false; int submodelID = 0; - // remove all faces that definitely won't fit into one model and submodel limit - U32 face_limit = (submodel_limit + 1) * LL_SCULPT_MESH_MAX_FACES; - if (face_limit < volume_faces) - { - ret->setNumVolumeFaces(face_limit); - } - - LLVolume::face_list_t remainder; - do - { - // Insure we do this once with the whole gang and not per-model - // - if (!normalized && !mNoNormalize) - { - normalized = true; - ret->normalizeVolumeFaces(); - } - - ret->trimVolumeFacesToSize(LL_SCULPT_MESH_MAX_FACES, &remainder); + // remove all faces that definitely won't fit into one model and submodel limit + U32 face_limit = (submodel_limit + 1) * LL_SCULPT_MESH_MAX_FACES; + if (face_limit < volume_faces) + { + ret->setNumVolumeFaces(face_limit); + } + + LLVolume::face_list_t remainder; + do + { + // Insure we do this once with the whole gang and not per-model + // + if (!normalized && !mNoNormalize) + { + normalized = true; + ret->normalizeVolumeFaces(); + } + + ret->trimVolumeFacesToSize(LL_SCULPT_MESH_MAX_FACES, &remainder); // remove unused/redundant vertices after normalizing - if (!mNoOptimize) - { - ret->remapVolumeFaces(); - } - - volume_faces = remainder.size(); - - models_out.push_back(ret); - - // If we have left-over volume faces, create another model - // to absorb them... - // - if (volume_faces) - { - LLModel* next = new LLModel(volume_params, 0.f); - next->mSubmodelID = ++submodelID; - next->mLabel = model_name + (char)((int)'a' + next->mSubmodelID) + lod_suffix[mLod]; - next->getVolumeFaces() = remainder; - next->mNormalizedScale = ret->mNormalizedScale; - next->mNormalizedTranslation = ret->mNormalizedTranslation; - - if ( ret->mMaterialList.size() > LL_SCULPT_MESH_MAX_FACES) - { - next->mMaterialList.assign(ret->mMaterialList.begin() + LL_SCULPT_MESH_MAX_FACES, ret->mMaterialList.end()); - } - ret = next; - } - - remainder.clear(); - - } while (volume_faces); - - return true; + if (!mNoOptimize) + { + ret->remapVolumeFaces(); + } + + volume_faces = remainder.size(); + + models_out.push_back(ret); + + // If we have left-over volume faces, create another model + // to absorb them... + // + if (volume_faces) + { + LLModel* next = new LLModel(volume_params, 0.f); + next->mSubmodelID = ++submodelID; + next->mLabel = model_name + (char)((int)'a' + next->mSubmodelID) + lod_suffix[mLod]; + next->getVolumeFaces() = remainder; + next->mNormalizedScale = ret->mNormalizedScale; + next->mNormalizedTranslation = ret->mNormalizedTranslation; + + if ( ret->mMaterialList.size() > LL_SCULPT_MESH_MAX_FACES) + { + next->mMaterialList.assign(ret->mMaterialList.begin() + LL_SCULPT_MESH_MAX_FACES, ret->mMaterialList.end()); + } + ret = next; + } + + remainder.clear(); + + } while (volume_faces); + + return true; } diff --git a/indra/llprimitive/lldaeloader.h b/indra/llprimitive/lldaeloader.h index 52ad908870..4531e03474 100644 --- a/indra/llprimitive/lldaeloader.h +++ b/indra/llprimitive/lldaeloader.h @@ -5,21 +5,21 @@ * $LicenseInfo:firstyear=2013&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2013, 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$ */ @@ -42,69 +42,69 @@ class domMesh; class LLDAELoader : public LLModelLoader { public: - typedef std::map<std::string, LLImportMaterial> material_map; - typedef std::map<daeElement*, std::vector<LLPointer<LLModel> > > dae_model_map; - dae_model_map mModelsMap; - - LLDAELoader( - std::string filename, - S32 lod, - LLModelLoader::load_callback_t load_cb, - LLModelLoader::joint_lookup_func_t joint_lookup_func, - LLModelLoader::texture_load_func_t texture_load_func, - LLModelLoader::state_callback_t state_cb, - void* opaque_userdata, - JointTransformMap& jointTransformMap, - JointNameSet& jointsFromNodes, + typedef std::map<std::string, LLImportMaterial> material_map; + typedef std::map<daeElement*, std::vector<LLPointer<LLModel> > > dae_model_map; + dae_model_map mModelsMap; + + LLDAELoader( + std::string filename, + S32 lod, + LLModelLoader::load_callback_t load_cb, + LLModelLoader::joint_lookup_func_t joint_lookup_func, + LLModelLoader::texture_load_func_t texture_load_func, + LLModelLoader::state_callback_t state_cb, + void* opaque_userdata, + JointTransformMap& jointTransformMap, + JointNameSet& jointsFromNodes, std::map<std::string, std::string>& jointAliasMap, - U32 maxJointsPerMesh, - U32 modelLimit, - bool preprocess); - virtual ~LLDAELoader() ; + U32 maxJointsPerMesh, + U32 modelLimit, + bool preprocess); + virtual ~LLDAELoader() ; - virtual bool OpenFile(const std::string& filename); + virtual bool OpenFile(const std::string& filename); protected: - void processElement(daeElement* element, bool& badElement, DAE* dae); - void processDomModel(LLModel* model, DAE* dae, daeElement* pRoot, domMesh* mesh, domSkin* skin); + void processElement(daeElement* element, bool& badElement, DAE* dae); + void processDomModel(LLModel* model, DAE* dae, daeElement* pRoot, domMesh* mesh, domSkin* skin); + + material_map getMaterials(LLModel* model, domInstance_geometry* instance_geo, DAE* dae); + LLImportMaterial profileToMaterial(domProfile_COMMON* material, DAE* dae); + LLColor4 getDaeColor(daeElement* element); + + daeElement* getChildFromElement( daeElement* pElement, std::string const & name ); - material_map getMaterials(LLModel* model, domInstance_geometry* instance_geo, DAE* dae); - LLImportMaterial profileToMaterial(domProfile_COMMON* material, DAE* dae); - LLColor4 getDaeColor(daeElement* element); - - daeElement* getChildFromElement( daeElement* pElement, std::string const & name ); - - bool isNodeAJoint( domNode* pNode ); - void processJointNode( domNode* pNode, std::map<std::string,LLMatrix4>& jointTransforms ); - void extractTranslation( domTranslate* pTranslate, LLMatrix4& transform ); - void extractTranslationViaElement( daeElement* pTranslateElement, LLMatrix4& transform ); - void extractTranslationViaSID( daeElement* pElement, LLMatrix4& transform ); - void buildJointToNodeMappingFromScene( daeElement* pRoot ); - void processJointToNodeMapping( domNode* pNode ); - void processChildJoints( domNode* pParentNode ); + bool isNodeAJoint( domNode* pNode ); + void processJointNode( domNode* pNode, std::map<std::string,LLMatrix4>& jointTransforms ); + void extractTranslation( domTranslate* pTranslate, LLMatrix4& transform ); + void extractTranslationViaElement( daeElement* pTranslateElement, LLMatrix4& transform ); + void extractTranslationViaSID( daeElement* pElement, LLMatrix4& transform ); + void buildJointToNodeMappingFromScene( daeElement* pRoot ); + void processJointToNodeMapping( domNode* pNode ); + void processChildJoints( domNode* pParentNode ); - bool verifyCount( int expected, int result ); + bool verifyCount( int expected, int result ); - //Verify that a controller matches vertex counts - bool verifyController( domController* pController ); + //Verify that a controller matches vertex counts + bool verifyController( domController* pController ); - static bool addVolumeFacesFromDomMesh(LLModel* model, domMesh* mesh, LLSD& log_msg); + static bool addVolumeFacesFromDomMesh(LLModel* model, domMesh* mesh, LLSD& log_msg); - // Loads a mesh breaking it into one or more models as necessary - // to get around volume face limitations while retaining >8 materials - // - bool loadModelsFromDomMesh(domMesh* mesh, std::vector<LLModel*>& models_out, U32 submodel_limit); + // Loads a mesh breaking it into one or more models as necessary + // to get around volume face limitations while retaining >8 materials + // + bool loadModelsFromDomMesh(domMesh* mesh, std::vector<LLModel*>& models_out, U32 submodel_limit); - static std::string getElementLabel(daeElement *element); - static size_t getSuffixPosition(std::string label); - static std::string getLodlessLabel(daeElement *element); + static std::string getElementLabel(daeElement *element); + static size_t getSuffixPosition(std::string label); + static std::string getLodlessLabel(daeElement *element); - static std::string preprocessDAE(std::string filename); + static std::string preprocessDAE(std::string filename); private: - U32 mGeneratedModelLimit; // Attempt to limit amount of generated submodels - bool mPreprocessDAE; + U32 mGeneratedModelLimit; // Attempt to limit amount of generated submodels + bool mPreprocessDAE; }; #endif // LL_LLDAELLOADER_H diff --git a/indra/llprimitive/llgltfloader.cpp b/indra/llprimitive/llgltfloader.cpp index 8e498158d6..810b648f17 100644 --- a/indra/llprimitive/llgltfloader.cpp +++ b/indra/llprimitive/llgltfloader.cpp @@ -59,11 +59,11 @@ static const std::string lod_suffix[LLModel::NUM_LODS] = { - "_LOD0", - "_LOD1", - "_LOD2", - "", - "_PHYS", + "_LOD0", + "_LOD1", + "_LOD2", + "", + "_PHYS", }; @@ -142,13 +142,13 @@ bool LLGLTFLoader::parseMeshes() // 2022-04 DJH Volume params from dae example. TODO understand PCODE LLVolumeParams volume_params; - volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE); - + volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE); + for (tinygltf::Mesh mesh : mGltfModel.meshes) { LLModel *pModel = new LLModel(volume_params, 0.f); - if (populateModelFromMesh(pModel, mesh) && + if (populateModelFromMesh(pModel, mesh) && (LLModel::NO_ERRORS == pModel->getStatus()) && validate_model(pModel)) { @@ -179,7 +179,7 @@ bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const tinygltf::Mesh & if (pos_idx >= 0) { positions_a = mGltfModel.accessors[pos_idx]; - if (TINYGLTF_COMPONENT_TYPE_FLOAT != positions_a.componentType) + if (TINYGLTF_COMPONENT_TYPE_FLOAT != positions_a.componentType) continue; auto positions_bv = mGltfModel.bufferViews[positions_a.bufferView]; auto positions_buf = mGltfModel.buffers[positions_bv.buffer]; @@ -202,12 +202,12 @@ bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const tinygltf::Mesh & //auto pos = mesh. TODO resume here DJH 2022-04 } } - + //pModel->addFace() return false; } -bool LLGLTFLoader::parseMaterials() +bool LLGLTFLoader::parseMaterials() { if (!mGltfLoaded) return false; @@ -241,7 +241,7 @@ bool LLGLTFLoader::parseMaterials() LL_WARNS("GLTF_IMPORT") << "Unsupported image encoding" << LL_ENDL; return false; } - + if (image.size != image.height * image.width * image.numChannels * image.bytesPerChannel) { LL_WARNS("GLTF_IMPORT") << "Image size error" << LL_ENDL; @@ -329,7 +329,7 @@ bool LLGLTFLoader::parseMaterials() mMaterials.push_back(mat); } - return true; + return true; } // TODO: convert raw vertex buffers to UUIDs @@ -346,7 +346,7 @@ void LLGLTFLoader::uploadMaterials() if (mat.hasBaseTex) { gltf_texture& gtex = mTextures[mat.baseColorTexIdx]; - if (gtex.imageUuid.isNull()) + if (gtex.imageUuid.isNull()) { gtex.imageUuid = imageBufferToTextureUUID(gtex); } diff --git a/indra/llprimitive/llgltfloader.h b/indra/llprimitive/llgltfloader.h index b4d6ca1940..66671d1c5a 100644 --- a/indra/llprimitive/llgltfloader.h +++ b/indra/llprimitive/llgltfloader.h @@ -35,7 +35,7 @@ // gltf_* structs are temporary, used to organize the subset of data that eventually goes into the material LLSD class gltf_sampler -{ +{ public: // Uses GL enums S32 minFilter; // GL_NEAREST, GL_LINEAR, GL_NEAREST_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR or GL_LINEAR_MIPMAP_LINEAR @@ -44,7 +44,7 @@ public: S32 wrapT; // GL_CLAMP_TO_EDGE, GL_MIRRORED_REPEAT or GL_REPEAT //S32 wrapR; // Found in some sample files, but not part of glTF 2.0 spec. Ignored. std::string name; // optional, currently unused - // extensions and extras are sampler optional fields that we don't support - at least initially + // extensions and extras are sampler optional fields that we don't support - at least initially }; class gltf_image @@ -85,7 +85,7 @@ public: // textures U32 baseColorTexIdx; // always sRGB encoded U32 metalRoughTexIdx; // always linear, roughness in G channel, metalness in B channel - U32 normalTexIdx; // linear, valid range R[0-1], G[0-1], B[0.5-1]. Normal = texel * 2 - vec3(1.0) + U32 normalTexIdx; // linear, valid range R[0-1], G[0-1], B[0.5-1]. Normal = texel * 2 - vec3(1.0) U32 occlusionTexIdx; // linear, occlusion in R channel, 0 meaning fully occluded, 1 meaning not occluded U32 emissiveTexIdx; // always stored as sRGB, in nits (candela / meter^2) @@ -201,6 +201,6 @@ private: static std::string preprocessGLTF(std::string filename); */ - + }; #endif // LL_LLGLTFLLOADER_H diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index 237636bd0b..034017e3f3 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -5,21 +5,21 @@ * $LicenseInfo:firstyear=2022&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2022, 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$ */ @@ -722,7 +722,7 @@ void LLGLTFMaterial::applyOverrideLLSD(const LLSD& data) { mMetallicFactor = mf.asReal(); if (mMetallicFactor == getDefaultMetallicFactor()) - { + { // HACK -- nudge by epsilon if we receive a default value (indicates override to default) mMetallicFactor -= FLT_EPSILON; } @@ -733,7 +733,7 @@ void LLGLTFMaterial::applyOverrideLLSD(const LLSD& data) { mRoughnessFactor = rf.asReal(); if (mRoughnessFactor == getDefaultRoughnessFactor()) - { + { // HACK -- nudge by epsilon if we receive a default value (indicates override to default) mRoughnessFactor -= FLT_EPSILON; } diff --git a/indra/llprimitive/llgltfmaterial_templates.h b/indra/llprimitive/llgltfmaterial_templates.h index f607dfe967..276cc71b19 100644 --- a/indra/llprimitive/llgltfmaterial_templates.h +++ b/indra/llprimitive/llgltfmaterial_templates.h @@ -5,21 +5,21 @@ * $LicenseInfo:firstyear=2023&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2023, 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$ */ diff --git a/indra/llprimitive/lllslconstants.h b/indra/llprimitive/lllslconstants.h index b6baf98211..f7461aca38 100644 --- a/indra/llprimitive/lllslconstants.h +++ b/indra/llprimitive/lllslconstants.h @@ -1,4 +1,4 @@ -/** +/** * @file lllslconstants.h * @author James Cook * @brief Constants used in lsl. @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2006&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$ */ @@ -29,107 +29,107 @@ #define LL_LLLSLCONSTANTS_H // LSL: Return flags for llGetAgentInfo -const U32 AGENT_FLYING = 0x0001; -const U32 AGENT_ATTACHMENTS = 0x0002; -const U32 AGENT_SCRIPTED = 0x0004; -const U32 AGENT_MOUSELOOK = 0x0008; -const U32 AGENT_SITTING = 0x0010; -const U32 AGENT_ON_OBJECT = 0x0020; -const U32 AGENT_AWAY = 0x0040; -const U32 AGENT_WALKING = 0x0080; -const U32 AGENT_IN_AIR = 0x0100; -const U32 AGENT_TYPING = 0x0200; -const U32 AGENT_CROUCHING = 0x0400; -const U32 AGENT_BUSY = 0x0800; -const U32 AGENT_ALWAYS_RUN = 0x1000; -const U32 AGENT_AUTOPILOT = 0x2000; +const U32 AGENT_FLYING = 0x0001; +const U32 AGENT_ATTACHMENTS = 0x0002; +const U32 AGENT_SCRIPTED = 0x0004; +const U32 AGENT_MOUSELOOK = 0x0008; +const U32 AGENT_SITTING = 0x0010; +const U32 AGENT_ON_OBJECT = 0x0020; +const U32 AGENT_AWAY = 0x0040; +const U32 AGENT_WALKING = 0x0080; +const U32 AGENT_IN_AIR = 0x0100; +const U32 AGENT_TYPING = 0x0200; +const U32 AGENT_CROUCHING = 0x0400; +const U32 AGENT_BUSY = 0x0800; +const U32 AGENT_ALWAYS_RUN = 0x1000; +const U32 AGENT_AUTOPILOT = 0x2000; -const S32 LSL_REMOTE_DATA_CHANNEL = 1; -const S32 LSL_REMOTE_DATA_REQUEST = 2; -const S32 LSL_REMOTE_DATA_REPLY = 3; +const S32 LSL_REMOTE_DATA_CHANNEL = 1; +const S32 LSL_REMOTE_DATA_REQUEST = 2; +const S32 LSL_REMOTE_DATA_REPLY = 3; // Constants used in extended LSL primitive setter and getters -const S32 LSL_PRIM_TYPE_LEGACY = 1; // No longer supported. -const S32 LSL_PRIM_MATERIAL = 2; -const S32 LSL_PRIM_PHYSICS = 3; -const S32 LSL_PRIM_TEMP_ON_REZ = 4; -const S32 LSL_PRIM_PHANTOM = 5; -const S32 LSL_PRIM_POSITION = 6; -const S32 LSL_PRIM_SIZE = 7; -const S32 LSL_PRIM_ROTATION = 8; -const S32 LSL_PRIM_TYPE = 9; // Replacement for LSL_PRIM_TYPE_LEGACY -const S32 LSL_PRIM_TEXTURE = 17; -const S32 LSL_PRIM_COLOR = 18; -const S32 LSL_PRIM_BUMP_SHINY = 19; -const S32 LSL_PRIM_FULLBRIGHT = 20; -const S32 LSL_PRIM_FLEXIBLE = 21; -const S32 LSL_PRIM_TEXGEN = 22; -const S32 LSL_PRIM_POINT_LIGHT = 23; -const S32 LSL_PRIM_CAST_SHADOWS = 24; -const S32 LSL_PRIM_GLOW = 25; -const S32 LSL_PRIM_TEXT = 26; -const S32 LSL_PRIM_NAME = 27; -const S32 LSL_PRIM_DESC = 28; -const S32 LSL_PRIM_ROT_LOCAL = 29; -const S32 LSL_PRIM_PHYSICS_SHAPE_TYPE = 30; -const S32 LSL_PRIM_OMEGA = 32; -const S32 LSL_PRIM_POS_LOCAL = 33; -const S32 LSL_PRIM_LINK_TARGET = 34; -const S32 LSL_PRIM_SLICE = 35; +const S32 LSL_PRIM_TYPE_LEGACY = 1; // No longer supported. +const S32 LSL_PRIM_MATERIAL = 2; +const S32 LSL_PRIM_PHYSICS = 3; +const S32 LSL_PRIM_TEMP_ON_REZ = 4; +const S32 LSL_PRIM_PHANTOM = 5; +const S32 LSL_PRIM_POSITION = 6; +const S32 LSL_PRIM_SIZE = 7; +const S32 LSL_PRIM_ROTATION = 8; +const S32 LSL_PRIM_TYPE = 9; // Replacement for LSL_PRIM_TYPE_LEGACY +const S32 LSL_PRIM_TEXTURE = 17; +const S32 LSL_PRIM_COLOR = 18; +const S32 LSL_PRIM_BUMP_SHINY = 19; +const S32 LSL_PRIM_FULLBRIGHT = 20; +const S32 LSL_PRIM_FLEXIBLE = 21; +const S32 LSL_PRIM_TEXGEN = 22; +const S32 LSL_PRIM_POINT_LIGHT = 23; +const S32 LSL_PRIM_CAST_SHADOWS = 24; +const S32 LSL_PRIM_GLOW = 25; +const S32 LSL_PRIM_TEXT = 26; +const S32 LSL_PRIM_NAME = 27; +const S32 LSL_PRIM_DESC = 28; +const S32 LSL_PRIM_ROT_LOCAL = 29; +const S32 LSL_PRIM_PHYSICS_SHAPE_TYPE = 30; +const S32 LSL_PRIM_OMEGA = 32; +const S32 LSL_PRIM_POS_LOCAL = 33; +const S32 LSL_PRIM_LINK_TARGET = 34; +const S32 LSL_PRIM_SLICE = 35; -const S32 LSL_PRIM_PHYSICS_SHAPE_PRIM = 0; -const S32 LSL_PRIM_PHYSICS_SHAPE_NONE = 1; -const S32 LSL_PRIM_PHYSICS_SHAPE_CONVEX = 2; +const S32 LSL_PRIM_PHYSICS_SHAPE_PRIM = 0; +const S32 LSL_PRIM_PHYSICS_SHAPE_NONE = 1; +const S32 LSL_PRIM_PHYSICS_SHAPE_CONVEX = 2; -const S32 LSL_PRIM_TYPE_BOX = 0; +const S32 LSL_PRIM_TYPE_BOX = 0; const S32 LSL_PRIM_TYPE_CYLINDER= 1; -const S32 LSL_PRIM_TYPE_PRISM = 2; -const S32 LSL_PRIM_TYPE_SPHERE = 3; -const S32 LSL_PRIM_TYPE_TORUS = 4; -const S32 LSL_PRIM_TYPE_TUBE = 5; -const S32 LSL_PRIM_TYPE_RING = 6; +const S32 LSL_PRIM_TYPE_PRISM = 2; +const S32 LSL_PRIM_TYPE_SPHERE = 3; +const S32 LSL_PRIM_TYPE_TORUS = 4; +const S32 LSL_PRIM_TYPE_TUBE = 5; +const S32 LSL_PRIM_TYPE_RING = 6; const S32 LSL_PRIM_TYPE_SCULPT = 7; const S32 LSL_PRIM_HOLE_DEFAULT = 0x00; -const S32 LSL_PRIM_HOLE_CIRCLE = 0x10; +const S32 LSL_PRIM_HOLE_CIRCLE = 0x10; const S32 LSL_PRIM_HOLE_SQUARE = 0x20; const S32 LSL_PRIM_HOLE_TRIANGLE= 0x30; -const S32 LSL_PRIM_MATERIAL_STONE = 0; -const S32 LSL_PRIM_MATERIAL_METAL = 1; -const S32 LSL_PRIM_MATERIAL_GLASS = 2; -const S32 LSL_PRIM_MATERIAL_WOOD = 3; -const S32 LSL_PRIM_MATERIAL_FLESH = 4; -const S32 LSL_PRIM_MATERIAL_PLASTIC = 5; -const S32 LSL_PRIM_MATERIAL_RUBBER = 6; -const S32 LSL_PRIM_MATERIAL_LIGHT = 7; +const S32 LSL_PRIM_MATERIAL_STONE = 0; +const S32 LSL_PRIM_MATERIAL_METAL = 1; +const S32 LSL_PRIM_MATERIAL_GLASS = 2; +const S32 LSL_PRIM_MATERIAL_WOOD = 3; +const S32 LSL_PRIM_MATERIAL_FLESH = 4; +const S32 LSL_PRIM_MATERIAL_PLASTIC = 5; +const S32 LSL_PRIM_MATERIAL_RUBBER = 6; +const S32 LSL_PRIM_MATERIAL_LIGHT = 7; -const S32 LSL_PRIM_SHINY_NONE = 0; -const S32 LSL_PRIM_SHINY_LOW = 1; -const S32 LSL_PRIM_SHINY_MEDIUM = 2; -const S32 LSL_PRIM_SHINY_HIGH = 3; +const S32 LSL_PRIM_SHINY_NONE = 0; +const S32 LSL_PRIM_SHINY_LOW = 1; +const S32 LSL_PRIM_SHINY_MEDIUM = 2; +const S32 LSL_PRIM_SHINY_HIGH = 3; -const S32 LSL_PRIM_TEXGEN_DEFAULT = 0; -const S32 LSL_PRIM_TEXGEN_PLANAR = 1; +const S32 LSL_PRIM_TEXGEN_DEFAULT = 0; +const S32 LSL_PRIM_TEXGEN_PLANAR = 1; -const S32 LSL_PRIM_BUMP_NONE = 0; -const S32 LSL_PRIM_BUMP_BRIGHT = 1; -const S32 LSL_PRIM_BUMP_DARK = 2; -const S32 LSL_PRIM_BUMP_WOOD = 3; -const S32 LSL_PRIM_BUMP_BARK = 4; -const S32 LSL_PRIM_BUMP_BRICKS = 5; -const S32 LSL_PRIM_BUMP_CHECKER = 6; -const S32 LSL_PRIM_BUMP_CONCRETE = 7; -const S32 LSL_PRIM_BUMP_TILE = 8; -const S32 LSL_PRIM_BUMP_STONE = 9; -const S32 LSL_PRIM_BUMP_DISKS = 10; -const S32 LSL_PRIM_BUMP_GRAVEL = 11; -const S32 LSL_PRIM_BUMP_BLOBS = 12; -const S32 LSL_PRIM_BUMP_SIDING = 13; -const S32 LSL_PRIM_BUMP_LARGETILE = 14; -const S32 LSL_PRIM_BUMP_STUCCO = 15; -const S32 LSL_PRIM_BUMP_SUCTION = 16; -const S32 LSL_PRIM_BUMP_WEAVE = 17; +const S32 LSL_PRIM_BUMP_NONE = 0; +const S32 LSL_PRIM_BUMP_BRIGHT = 1; +const S32 LSL_PRIM_BUMP_DARK = 2; +const S32 LSL_PRIM_BUMP_WOOD = 3; +const S32 LSL_PRIM_BUMP_BARK = 4; +const S32 LSL_PRIM_BUMP_BRICKS = 5; +const S32 LSL_PRIM_BUMP_CHECKER = 6; +const S32 LSL_PRIM_BUMP_CONCRETE = 7; +const S32 LSL_PRIM_BUMP_TILE = 8; +const S32 LSL_PRIM_BUMP_STONE = 9; +const S32 LSL_PRIM_BUMP_DISKS = 10; +const S32 LSL_PRIM_BUMP_GRAVEL = 11; +const S32 LSL_PRIM_BUMP_BLOBS = 12; +const S32 LSL_PRIM_BUMP_SIDING = 13; +const S32 LSL_PRIM_BUMP_LARGETILE = 14; +const S32 LSL_PRIM_BUMP_STUCCO = 15; +const S32 LSL_PRIM_BUMP_SUCTION = 16; +const S32 LSL_PRIM_BUMP_WEAVE = 17; const S32 LSL_PRIM_SCULPT_TYPE_SPHERE = 1; const S32 LSL_PRIM_SCULPT_TYPE_TORUS = 2; @@ -139,19 +139,19 @@ const S32 LSL_PRIM_SCULPT_TYPE_MASK = 7; const S32 LSL_PRIM_SCULPT_FLAG_INVERT = 64; const S32 LSL_PRIM_SCULPT_FLAG_MIRROR = 128; -const S32 LSL_ALL_SIDES = -1; -const S32 LSL_LINK_ROOT = 1; -const S32 LSL_LINK_FIRST_CHILD = 2; -const S32 LSL_LINK_SET = -1; -const S32 LSL_LINK_ALL_OTHERS = -2; -const S32 LSL_LINK_ALL_CHILDREN = -3; -const S32 LSL_LINK_THIS = -4; +const S32 LSL_ALL_SIDES = -1; +const S32 LSL_LINK_ROOT = 1; +const S32 LSL_LINK_FIRST_CHILD = 2; +const S32 LSL_LINK_SET = -1; +const S32 LSL_LINK_ALL_OTHERS = -2; +const S32 LSL_LINK_ALL_CHILDREN = -3; +const S32 LSL_LINK_THIS = -4; // LSL constants for llSetForSell -const S32 SELL_NOT = 0; -const S32 SELL_ORIGINAL = 1; -const S32 SELL_COPY = 2; -const S32 SELL_CONTENTS = 3; +const S32 SELL_NOT = 0; +const S32 SELL_ORIGINAL = 1; +const S32 SELL_COPY = 2; +const S32 SELL_CONTENTS = 3; // LSL constants for llSetPayPrice const S32 PAY_PRICE_HIDE = -1; @@ -163,16 +163,16 @@ const S32 PAY_BUTTON_DEFAULT_2 = 10; const S32 PAY_BUTTON_DEFAULT_3 = 20; // lsl email registration. -const S32 EMAIL_REG_SUBSCRIBE_OBJECT = 0x01; -const S32 EMAIL_REG_UNSUBSCRIBE_OBJECT = 0x02; -const S32 EMAIL_REG_UNSUBSCRIBE_SIM = 0x04; +const S32 EMAIL_REG_SUBSCRIBE_OBJECT = 0x01; +const S32 EMAIL_REG_UNSUBSCRIBE_OBJECT = 0x02; +const S32 EMAIL_REG_UNSUBSCRIBE_SIM = 0x04; const S32 LIST_STAT_RANGE = 0; -const S32 LIST_STAT_MIN = 1; -const S32 LIST_STAT_MAX = 2; -const S32 LIST_STAT_MEAN = 3; -const S32 LIST_STAT_MEDIAN = 4; -const S32 LIST_STAT_STD_DEV = 5; +const S32 LIST_STAT_MIN = 1; +const S32 LIST_STAT_MAX = 2; +const S32 LIST_STAT_MEAN = 3; +const S32 LIST_STAT_MEDIAN = 4; +const S32 LIST_STAT_STD_DEV = 5; const S32 LIST_STAT_SUM = 6; const S32 LIST_STAT_SUM_SQUARES = 7; const S32 LIST_STAT_NUM_COUNT = 8; @@ -213,18 +213,18 @@ const S32 OBJECT_RENDER_WEIGHT = 24; char const* const TEXTBOX_MAGIC_TOKEN = "!!llTextBox!!"; // changed() event flags -const U32 CHANGED_NONE = 0x0; -const U32 CHANGED_INVENTORY = 0x1; -const U32 CHANGED_COLOR = 0x2; -const U32 CHANGED_SHAPE = 0x4; -const U32 CHANGED_SCALE = 0x8; -const U32 CHANGED_TEXTURE = 0x10; -const U32 CHANGED_LINK = 0x20; -const U32 CHANGED_ALLOWED_DROP = 0x40; -const U32 CHANGED_OWNER = 0x80; -const U32 CHANGED_REGION = 0x100; -const U32 CHANGED_TELEPORT = 0x200; -const U32 CHANGED_REGION_START = 0x400; +const U32 CHANGED_NONE = 0x0; +const U32 CHANGED_INVENTORY = 0x1; +const U32 CHANGED_COLOR = 0x2; +const U32 CHANGED_SHAPE = 0x4; +const U32 CHANGED_SCALE = 0x8; +const U32 CHANGED_TEXTURE = 0x10; +const U32 CHANGED_LINK = 0x20; +const U32 CHANGED_ALLOWED_DROP = 0x40; +const U32 CHANGED_OWNER = 0x80; +const U32 CHANGED_REGION = 0x100; +const U32 CHANGED_TELEPORT = 0x200; +const U32 CHANGED_REGION_START = 0x400; const U32 CHANGED_MEDIA = 0x800; // Possible error results @@ -246,7 +246,7 @@ const S32 LSL_XP_ERROR_EXPERIENCES_DISABLED = 2; const S32 LSL_XP_ERROR_INVALID_PARAMETERS = 3; const S32 LSL_XP_ERROR_NOT_PERMITTED = 4; const S32 LSL_XP_ERROR_NO_EXPERIENCE = 5; -const S32 LSL_XP_ERROR_NOT_FOUND = 6; +const S32 LSL_XP_ERROR_NOT_FOUND = 6; const S32 LSL_XP_ERROR_INVALID_EXPERIENCE = 7; const S32 LSL_XP_ERROR_EXPERIENCE_DISABLED = 8; const S32 LSL_XP_ERROR_EXPERIENCE_SUSPENDED = 9; diff --git a/indra/llprimitive/llmaterial.cpp b/indra/llprimitive/llmaterial.cpp index 0d146de949..0453a8f469 100644 --- a/indra/llprimitive/llmaterial.cpp +++ b/indra/llprimitive/llmaterial.cpp @@ -5,21 +5,21 @@ * $LicenseInfo:firstyear=2006&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$ */ @@ -412,7 +412,7 @@ bool LLMaterial::isNull() const bool LLMaterial::operator == (const LLMaterial& rhs) const { - return + return (mNormalID == rhs.mNormalID) && (mNormalOffsetX == rhs.mNormalOffsetX) && (mNormalOffsetY == rhs.mNormalOffsetY) && (mNormalRepeatX == rhs.mNormalRepeatX) && (mNormalRepeatY == rhs.mNormalRepeatY) && (mNormalRotation == rhs.mNormalRotation) && (mSpecularID == rhs.mSpecularID) && (mSpecularOffsetX == rhs.mSpecularOffsetX) && (mSpecularOffsetY == rhs.mSpecularOffsetY) && @@ -430,15 +430,15 @@ bool LLMaterial::operator != (const LLMaterial& rhs) const U32 LLMaterial::getShaderMask(U32 alpha_mode, BOOL is_alpha) { //NEVER incorporate this value into the message system -- this function will vary depending on viewer implementation - //two least significant bits are "diffuse alpha mode" - U32 ret = alpha_mode; + //two least significant bits are "diffuse alpha mode" + U32 ret = alpha_mode; if (ret == DIFFUSE_ALPHA_MODE_DEFAULT) { - ret = getDiffuseAlphaMode(); - if (ret == DIFFUSE_ALPHA_MODE_BLEND && !is_alpha) - { - ret = DIFFUSE_ALPHA_MODE_NONE; - } + ret = getDiffuseAlphaMode(); + if (ret == DIFFUSE_ALPHA_MODE_BLEND && !is_alpha) + { + ret = DIFFUSE_ALPHA_MODE_NONE; + } } llassert(ret < SHADER_COUNT); @@ -452,7 +452,7 @@ U32 LLMaterial::getShaderMask(U32 alpha_mode, BOOL is_alpha) } llassert(ret < SHADER_COUNT); - + //next bit is whether or not normal map is present const U32 NORM_BIT = 0x8; if (getNormalID().notNull()) diff --git a/indra/llprimitive/llmaterial.h b/indra/llprimitive/llmaterial.h index 81f41ddc51..c6bd5a94ce 100644 --- a/indra/llprimitive/llmaterial.h +++ b/indra/llprimitive/llmaterial.h @@ -5,21 +5,21 @@ * $LicenseInfo:firstyear=2006&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$ */ diff --git a/indra/llprimitive/llmaterialid.cpp b/indra/llprimitive/llmaterialid.cpp index 340a83801c..847824d770 100644 --- a/indra/llprimitive/llmaterialid.cpp +++ b/indra/llprimitive/llmaterialid.cpp @@ -1,4 +1,4 @@ -/** +/** * @file llmaterialid.cpp * @brief Implementation of llmaterialid * @author Stinson@lindenlab.com @@ -37,33 +37,33 @@ const LLMaterialID LLMaterialID::null; LLMaterialID::LLMaterialID() { - clear(); + clear(); } LLMaterialID::LLMaterialID(const LLSD& pMaterialID) { - llassert(pMaterialID.isBinary()); - parseFromBinary(pMaterialID.asBinary()); + llassert(pMaterialID.isBinary()); + parseFromBinary(pMaterialID.asBinary()); } LLMaterialID::LLMaterialID(const LLSD::Binary& pMaterialID) { - parseFromBinary(pMaterialID); + parseFromBinary(pMaterialID); } LLMaterialID::LLMaterialID(const void* pMemory) { - set(pMemory); + set(pMemory); } LLMaterialID::LLMaterialID(const LLMaterialID& pOtherMaterialID) { - copyFromOtherMaterialID(pOtherMaterialID); + copyFromOtherMaterialID(pOtherMaterialID); } LLMaterialID::LLMaterialID(const LLUUID& lluid) { - set(lluid.mData); + set(lluid.mData); } LLMaterialID::~LLMaterialID() @@ -72,87 +72,87 @@ LLMaterialID::~LLMaterialID() bool LLMaterialID::operator == (const LLMaterialID& pOtherMaterialID) const { - return (compareToOtherMaterialID(pOtherMaterialID) == 0); + return (compareToOtherMaterialID(pOtherMaterialID) == 0); } bool LLMaterialID::operator != (const LLMaterialID& pOtherMaterialID) const { - return (compareToOtherMaterialID(pOtherMaterialID) != 0); + return (compareToOtherMaterialID(pOtherMaterialID) != 0); } bool LLMaterialID::operator < (const LLMaterialID& pOtherMaterialID) const { - return (compareToOtherMaterialID(pOtherMaterialID) < 0); + return (compareToOtherMaterialID(pOtherMaterialID) < 0); } bool LLMaterialID::operator <= (const LLMaterialID& pOtherMaterialID) const { - return (compareToOtherMaterialID(pOtherMaterialID) <= 0); + return (compareToOtherMaterialID(pOtherMaterialID) <= 0); } bool LLMaterialID::operator > (const LLMaterialID& pOtherMaterialID) const { - return (compareToOtherMaterialID(pOtherMaterialID) > 0); + return (compareToOtherMaterialID(pOtherMaterialID) > 0); } bool LLMaterialID::operator >= (const LLMaterialID& pOtherMaterialID) const { - return (compareToOtherMaterialID(pOtherMaterialID) >= 0); + return (compareToOtherMaterialID(pOtherMaterialID) >= 0); } LLMaterialID& LLMaterialID::operator = (const LLMaterialID& pOtherMaterialID) { - copyFromOtherMaterialID(pOtherMaterialID); - return (*this); + copyFromOtherMaterialID(pOtherMaterialID); + return (*this); } bool LLMaterialID::isNull() const { - return (compareToOtherMaterialID(LLMaterialID::null) == 0); + return (compareToOtherMaterialID(LLMaterialID::null) == 0); } const U8* LLMaterialID::get() const { - return mID; + return mID; } void LLMaterialID::set(const void* pMemory) { - llassert(pMemory != NULL); + llassert(pMemory != NULL); - // assumes that the required size of memory is available - memcpy(mID, pMemory, MATERIAL_ID_SIZE * sizeof(U8)); + // assumes that the required size of memory is available + memcpy(mID, pMemory, MATERIAL_ID_SIZE * sizeof(U8)); } void LLMaterialID::clear() { - memset(mID, 0, MATERIAL_ID_SIZE * sizeof(U8)); + memset(mID, 0, MATERIAL_ID_SIZE * sizeof(U8)); } LLSD LLMaterialID::asLLSD() const { - LLSD::Binary materialIDBinary; + LLSD::Binary materialIDBinary; - materialIDBinary.resize(MATERIAL_ID_SIZE * sizeof(U8)); - memcpy(materialIDBinary.data(), mID, MATERIAL_ID_SIZE * sizeof(U8)); + materialIDBinary.resize(MATERIAL_ID_SIZE * sizeof(U8)); + memcpy(materialIDBinary.data(), mID, MATERIAL_ID_SIZE * sizeof(U8)); - LLSD materialID = materialIDBinary; - return materialID; + LLSD materialID = materialIDBinary; + return materialID; } std::string LLMaterialID::asString() const { - std::string materialIDString; - for (unsigned int i = 0U; i < static_cast<unsigned int>(MATERIAL_ID_SIZE / sizeof(U32)); ++i) - { - if (i != 0U) - { - materialIDString += "-"; - } - const U32 *value = reinterpret_cast<const U32*>(&get()[i * sizeof(U32)]); - materialIDString += llformat("%08x", *value); - } - return materialIDString; + std::string materialIDString; + for (unsigned int i = 0U; i < static_cast<unsigned int>(MATERIAL_ID_SIZE / sizeof(U32)); ++i) + { + if (i != 0U) + { + materialIDString += "-"; + } + const U32 *value = reinterpret_cast<const U32*>(&get()[i * sizeof(U32)]); + materialIDString += llformat("%08x", *value); + } + return materialIDString; } LLUUID LLMaterialID::asUUID() const @@ -164,32 +164,32 @@ LLUUID LLMaterialID::asUUID() const std::ostream& operator<<(std::ostream& s, const LLMaterialID &material_id) { - s << material_id.asString(); - return s; + s << material_id.asString(); + return s; } void LLMaterialID::parseFromBinary (const LLSD::Binary& pMaterialID) { - llassert(pMaterialID.size() == (MATERIAL_ID_SIZE * sizeof(U8))); - memcpy(mID, &pMaterialID[0], MATERIAL_ID_SIZE * sizeof(U8)); + llassert(pMaterialID.size() == (MATERIAL_ID_SIZE * sizeof(U8))); + memcpy(mID, &pMaterialID[0], MATERIAL_ID_SIZE * sizeof(U8)); } void LLMaterialID::copyFromOtherMaterialID(const LLMaterialID& pOtherMaterialID) { - memcpy(mID, pOtherMaterialID.get(), MATERIAL_ID_SIZE * sizeof(U8)); + memcpy(mID, pOtherMaterialID.get(), MATERIAL_ID_SIZE * sizeof(U8)); } int LLMaterialID::compareToOtherMaterialID(const LLMaterialID& pOtherMaterialID) const { - int retVal = 0; + int retVal = 0; - for (unsigned int i = 0U; (retVal == 0) && (i < static_cast<unsigned int>(MATERIAL_ID_SIZE / sizeof(U32))); ++i) - { - const U32 *thisValue = reinterpret_cast<const U32*>(&get()[i * sizeof(U32)]); - const U32 *otherValue = reinterpret_cast<const U32*>(&pOtherMaterialID.get()[i * sizeof(U32)]); - retVal = ((*thisValue < *otherValue) ? -1 : ((*thisValue > *otherValue) ? 1 : 0)); - } + for (unsigned int i = 0U; (retVal == 0) && (i < static_cast<unsigned int>(MATERIAL_ID_SIZE / sizeof(U32))); ++i) + { + const U32 *thisValue = reinterpret_cast<const U32*>(&get()[i * sizeof(U32)]); + const U32 *otherValue = reinterpret_cast<const U32*>(&pOtherMaterialID.get()[i * sizeof(U32)]); + retVal = ((*thisValue < *otherValue) ? -1 : ((*thisValue > *otherValue) ? 1 : 0)); + } - return retVal; + return retVal; } diff --git a/indra/llprimitive/llmaterialid.h b/indra/llprimitive/llmaterialid.h index 5eb463b0fd..bd6256d961 100644 --- a/indra/llprimitive/llmaterialid.h +++ b/indra/llprimitive/llmaterialid.h @@ -1,4 +1,4 @@ -/** +/** * @file llmaterialid.h * @brief Header file for llmaterialid * @author Stinson@lindenlab.com @@ -35,70 +35,70 @@ class LLMaterialID { public: - LLMaterialID(); - LLMaterialID(const LLSD& pMaterialID); - LLMaterialID(const LLSD::Binary& pMaterialID); - LLMaterialID(const void* pMemory); - LLMaterialID(const LLMaterialID& pOtherMaterialID); - LLMaterialID(const LLUUID& lluid); - ~LLMaterialID(); + LLMaterialID(); + LLMaterialID(const LLSD& pMaterialID); + LLMaterialID(const LLSD::Binary& pMaterialID); + LLMaterialID(const void* pMemory); + LLMaterialID(const LLMaterialID& pOtherMaterialID); + LLMaterialID(const LLUUID& lluid); + ~LLMaterialID(); - bool operator == (const LLMaterialID& pOtherMaterialID) const; - bool operator != (const LLMaterialID& pOtherMaterialID) const; + bool operator == (const LLMaterialID& pOtherMaterialID) const; + bool operator != (const LLMaterialID& pOtherMaterialID) const; - bool operator < (const LLMaterialID& pOtherMaterialID) const; - bool operator <= (const LLMaterialID& pOtherMaterialID) const; - bool operator > (const LLMaterialID& pOtherMaterialID) const; - bool operator >= (const LLMaterialID& pOtherMaterialID) const; + bool operator < (const LLMaterialID& pOtherMaterialID) const; + bool operator <= (const LLMaterialID& pOtherMaterialID) const; + bool operator > (const LLMaterialID& pOtherMaterialID) const; + bool operator >= (const LLMaterialID& pOtherMaterialID) const; - LLMaterialID& operator = (const LLMaterialID& pOtherMaterialID); + LLMaterialID& operator = (const LLMaterialID& pOtherMaterialID); - bool isNull() const; + bool isNull() const; - const U8* get() const; - void set(const void* pMemory); - void clear(); + const U8* get() const; + void set(const void* pMemory); + void clear(); - LLSD asLLSD() const; - std::string asString() const; + LLSD asLLSD() const; + std::string asString() const; LLUUID asUUID() const; - friend std::ostream& operator<<(std::ostream& s, const LLMaterialID &material_id); + friend std::ostream& operator<<(std::ostream& s, const LLMaterialID &material_id); - static const LLMaterialID null; + static const LLMaterialID null; - // Returns a 64 bits digest of the material Id, by XORing its two 64 bits - // long words. HB - inline U64 getDigest64() const - { - U64* tmp = (U64*)mID; - return tmp[0] ^ tmp[1]; - } + // Returns a 64 bits digest of the material Id, by XORing its two 64 bits + // long words. HB + inline U64 getDigest64() const + { + U64* tmp = (U64*)mID; + return tmp[0] ^ tmp[1]; + } private: - void parseFromBinary(const LLSD::Binary& pMaterialID); - void copyFromOtherMaterialID(const LLMaterialID& pOtherMaterialID); - int compareToOtherMaterialID(const LLMaterialID& pOtherMaterialID) const; + void parseFromBinary(const LLSD::Binary& pMaterialID); + void copyFromOtherMaterialID(const LLMaterialID& pOtherMaterialID); + int compareToOtherMaterialID(const LLMaterialID& pOtherMaterialID) const; - U8 mID[MATERIAL_ID_SIZE]; + U8 mID[MATERIAL_ID_SIZE]; } ; // std::hash implementation for LLMaterialID namespace std { - template<> struct hash<LLMaterialID> - { - inline size_t operator()(const LLMaterialID& id) const noexcept - { - return (size_t)id.getDigest64(); - } - }; + template<> struct hash<LLMaterialID> + { + inline size_t operator()(const LLMaterialID& id) const noexcept + { + return (size_t)id.getDigest64(); + } + }; } // For use with boost containers. inline size_t hash_value(const LLMaterialID& id) noexcept { - return (size_t)id.getDigest64(); + return (size_t)id.getDigest64(); } #endif // LL_LLMATERIALID_H diff --git a/indra/llprimitive/llmaterialtable.cpp b/indra/llprimitive/llmaterialtable.cpp index 58b2d00d44..344bd49e6d 100644 --- a/indra/llprimitive/llmaterialtable.cpp +++ b/indra/llprimitive/llmaterialtable.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llmaterialtable.cpp * @brief Table of material names and IDs for viewer * * $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$ */ @@ -34,722 +34,722 @@ LLMaterialTable LLMaterialTable::basic(1); -/* - Old Havok 1 constants +/* + Old Havok 1 constants // these are the approximately correct friction values for various materials // however Havok1's friction dynamics are not very correct, so the effective // friction coefficients that result from these numbers are approximately // 25-50% too low, more incorrect for the lower values. -F32 const LLMaterialTable::FRICTION_MIN = 0.2f; -F32 const LLMaterialTable::FRICTION_GLASS = 0.2f; // borosilicate glass -F32 const LLMaterialTable::FRICTION_LIGHT = 0.2f; // -F32 const LLMaterialTable::FRICTION_METAL = 0.3f; // steel -F32 const LLMaterialTable::FRICTION_PLASTIC = 0.4f; // HDPE -F32 const LLMaterialTable::FRICTION_WOOD = 0.6f; // southern pine -F32 const LLMaterialTable::FRICTION_FLESH = 0.60f; // saltwater -F32 const LLMaterialTable::FRICTION_LAND = 0.78f; // dirt -F32 const LLMaterialTable::FRICTION_STONE = 0.8f; // concrete -F32 const LLMaterialTable::FRICTION_RUBBER = 0.9f; // -F32 const LLMaterialTable::FRICTION_MAX = 0.95f; // +F32 const LLMaterialTable::FRICTION_MIN = 0.2f; +F32 const LLMaterialTable::FRICTION_GLASS = 0.2f; // borosilicate glass +F32 const LLMaterialTable::FRICTION_LIGHT = 0.2f; // +F32 const LLMaterialTable::FRICTION_METAL = 0.3f; // steel +F32 const LLMaterialTable::FRICTION_PLASTIC = 0.4f; // HDPE +F32 const LLMaterialTable::FRICTION_WOOD = 0.6f; // southern pine +F32 const LLMaterialTable::FRICTION_FLESH = 0.60f; // saltwater +F32 const LLMaterialTable::FRICTION_LAND = 0.78f; // dirt +F32 const LLMaterialTable::FRICTION_STONE = 0.8f; // concrete +F32 const LLMaterialTable::FRICTION_RUBBER = 0.9f; // +F32 const LLMaterialTable::FRICTION_MAX = 0.95f; // */ // #if LL_CURRENT_HAVOK_VERSION == LL_HAVOK_VERSION_460 // Havok4 has more correct friction dynamics, however here we have to use // the "incorrect" equivalents for the legacy Havok1 behavior -F32 const LLMaterialTable::FRICTION_MIN = 0.15f; -F32 const LLMaterialTable::FRICTION_GLASS = 0.13f; // borosilicate glass -F32 const LLMaterialTable::FRICTION_LIGHT = 0.14f; // -F32 const LLMaterialTable::FRICTION_METAL = 0.22f; // steel -F32 const LLMaterialTable::FRICTION_PLASTIC = 0.3f; // HDPE -F32 const LLMaterialTable::FRICTION_WOOD = 0.44f; // southern pine -F32 const LLMaterialTable::FRICTION_FLESH = 0.46f; // saltwater -F32 const LLMaterialTable::FRICTION_LAND = 0.58f; // dirt -F32 const LLMaterialTable::FRICTION_STONE = 0.6f; // concrete -F32 const LLMaterialTable::FRICTION_RUBBER = 0.67f; // -F32 const LLMaterialTable::FRICTION_MAX = 0.71f; // +F32 const LLMaterialTable::FRICTION_MIN = 0.15f; +F32 const LLMaterialTable::FRICTION_GLASS = 0.13f; // borosilicate glass +F32 const LLMaterialTable::FRICTION_LIGHT = 0.14f; // +F32 const LLMaterialTable::FRICTION_METAL = 0.22f; // steel +F32 const LLMaterialTable::FRICTION_PLASTIC = 0.3f; // HDPE +F32 const LLMaterialTable::FRICTION_WOOD = 0.44f; // southern pine +F32 const LLMaterialTable::FRICTION_FLESH = 0.46f; // saltwater +F32 const LLMaterialTable::FRICTION_LAND = 0.58f; // dirt +F32 const LLMaterialTable::FRICTION_STONE = 0.6f; // concrete +F32 const LLMaterialTable::FRICTION_RUBBER = 0.67f; // +F32 const LLMaterialTable::FRICTION_MAX = 0.71f; // // #endif -F32 const LLMaterialTable::RESTITUTION_MIN = 0.02f; -F32 const LLMaterialTable::RESTITUTION_LAND = LLMaterialTable::RESTITUTION_MIN; -F32 const LLMaterialTable::RESTITUTION_FLESH = 0.2f; // saltwater -F32 const LLMaterialTable::RESTITUTION_STONE = 0.4f; // concrete -F32 const LLMaterialTable::RESTITUTION_METAL = 0.4f; // steel -F32 const LLMaterialTable::RESTITUTION_WOOD = 0.5f; // southern pine -F32 const LLMaterialTable::RESTITUTION_GLASS = 0.7f; // borosilicate glass -F32 const LLMaterialTable::RESTITUTION_PLASTIC = 0.7f; // HDPE -F32 const LLMaterialTable::RESTITUTION_LIGHT = 0.7f; // -F32 const LLMaterialTable::RESTITUTION_RUBBER = 0.9f; // -F32 const LLMaterialTable::RESTITUTION_MAX = 0.95f; +F32 const LLMaterialTable::RESTITUTION_MIN = 0.02f; +F32 const LLMaterialTable::RESTITUTION_LAND = LLMaterialTable::RESTITUTION_MIN; +F32 const LLMaterialTable::RESTITUTION_FLESH = 0.2f; // saltwater +F32 const LLMaterialTable::RESTITUTION_STONE = 0.4f; // concrete +F32 const LLMaterialTable::RESTITUTION_METAL = 0.4f; // steel +F32 const LLMaterialTable::RESTITUTION_WOOD = 0.5f; // southern pine +F32 const LLMaterialTable::RESTITUTION_GLASS = 0.7f; // borosilicate glass +F32 const LLMaterialTable::RESTITUTION_PLASTIC = 0.7f; // HDPE +F32 const LLMaterialTable::RESTITUTION_LIGHT = 0.7f; // +F32 const LLMaterialTable::RESTITUTION_RUBBER = 0.9f; // +F32 const LLMaterialTable::RESTITUTION_MAX = 0.95f; F32 const LLMaterialTable::DEFAULT_FRICTION = 0.5f; F32 const LLMaterialTable::DEFAULT_RESTITUTION = 0.4f; LLMaterialTable::LLMaterialTable() - : mCollisionSoundMatrix(NULL), - mSlidingSoundMatrix(NULL), - mRollingSoundMatrix(NULL) + : mCollisionSoundMatrix(NULL), + mSlidingSoundMatrix(NULL), + mRollingSoundMatrix(NULL) { } LLMaterialTable::LLMaterialTable(U8 isBasic) { - initBasicTable(); + initBasicTable(); } LLMaterialTable::~LLMaterialTable() { - if (mCollisionSoundMatrix) - { - delete [] mCollisionSoundMatrix; - mCollisionSoundMatrix = NULL; - } + if (mCollisionSoundMatrix) + { + delete [] mCollisionSoundMatrix; + mCollisionSoundMatrix = NULL; + } - if (mSlidingSoundMatrix) - { - delete [] mSlidingSoundMatrix; - mSlidingSoundMatrix = NULL; - } + if (mSlidingSoundMatrix) + { + delete [] mSlidingSoundMatrix; + mSlidingSoundMatrix = NULL; + } - if (mRollingSoundMatrix) - { - delete [] mRollingSoundMatrix; - mRollingSoundMatrix = NULL; - } + if (mRollingSoundMatrix) + { + delete [] mRollingSoundMatrix; + mRollingSoundMatrix = NULL; + } - for_each(mMaterialInfoList.begin(), mMaterialInfoList.end(), DeletePointer()); - mMaterialInfoList.clear(); + for_each(mMaterialInfoList.begin(), mMaterialInfoList.end(), DeletePointer()); + mMaterialInfoList.clear(); } void LLMaterialTable::initTableTransNames(std::map<std::string, std::string> namemap) { - for (info_list_t::iterator iter = mMaterialInfoList.begin(); - iter != mMaterialInfoList.end(); ++iter) - { - LLMaterialInfo *infop = *iter; - std::string name = infop->mName; - infop->mName = namemap[name]; - } + for (info_list_t::iterator iter = mMaterialInfoList.begin(); + iter != mMaterialInfoList.end(); ++iter) + { + LLMaterialInfo *infop = *iter; + std::string name = infop->mName; + infop->mName = namemap[name]; + } } void LLMaterialTable::initBasicTable() { - // *TODO: Translate - add(LL_MCODE_STONE,std::string("Stone"), LL_DEFAULT_STONE_UUID); - add(LL_MCODE_METAL,std::string("Metal"), LL_DEFAULT_METAL_UUID); - add(LL_MCODE_GLASS,std::string("Glass"), LL_DEFAULT_GLASS_UUID); - add(LL_MCODE_WOOD,std::string("Wood"), LL_DEFAULT_WOOD_UUID); - add(LL_MCODE_FLESH,std::string("Flesh"), LL_DEFAULT_FLESH_UUID); - add(LL_MCODE_PLASTIC,std::string("Plastic"), LL_DEFAULT_PLASTIC_UUID); - add(LL_MCODE_RUBBER,std::string("Rubber"), LL_DEFAULT_RUBBER_UUID); - add(LL_MCODE_LIGHT,std::string("Light"), LL_DEFAULT_LIGHT_UUID); - - // specify densities for these materials. . . + // *TODO: Translate + add(LL_MCODE_STONE,std::string("Stone"), LL_DEFAULT_STONE_UUID); + add(LL_MCODE_METAL,std::string("Metal"), LL_DEFAULT_METAL_UUID); + add(LL_MCODE_GLASS,std::string("Glass"), LL_DEFAULT_GLASS_UUID); + add(LL_MCODE_WOOD,std::string("Wood"), LL_DEFAULT_WOOD_UUID); + add(LL_MCODE_FLESH,std::string("Flesh"), LL_DEFAULT_FLESH_UUID); + add(LL_MCODE_PLASTIC,std::string("Plastic"), LL_DEFAULT_PLASTIC_UUID); + add(LL_MCODE_RUBBER,std::string("Rubber"), LL_DEFAULT_RUBBER_UUID); + add(LL_MCODE_LIGHT,std::string("Light"), LL_DEFAULT_LIGHT_UUID); + + // specify densities for these materials. . . // these were taken from http://www.mcelwee.net/html/densities_of_various_materials.html - addDensity(LL_MCODE_STONE,30.f); - addDensity(LL_MCODE_METAL,50.f); - addDensity(LL_MCODE_GLASS,20.f); - addDensity(LL_MCODE_WOOD,10.f); - addDensity(LL_MCODE_FLESH,10.f); - addDensity(LL_MCODE_PLASTIC,5.f); - addDensity(LL_MCODE_RUBBER,0.5f); // - addDensity(LL_MCODE_LIGHT,20.f); // - - // add damage and energy values - addDamageAndEnergy(LL_MCODE_STONE, 1.f, 1.f, 1.f); // concrete - addDamageAndEnergy(LL_MCODE_METAL, 1.f, 1.f, 1.f); // steel - addDamageAndEnergy(LL_MCODE_GLASS, 1.f, 1.f, 1.f); // borosilicate glass - addDamageAndEnergy(LL_MCODE_WOOD, 1.f, 1.f, 1.f); // southern pine - addDamageAndEnergy(LL_MCODE_FLESH, 1.f, 1.f, 1.f); // saltwater - addDamageAndEnergy(LL_MCODE_PLASTIC, 1.f, 1.f, 1.f); // HDPE - addDamageAndEnergy(LL_MCODE_RUBBER, 1.f, 1.f, 1.f); // - addDamageAndEnergy(LL_MCODE_LIGHT, 1.f, 1.f, 1.f); // - - addFriction(LL_MCODE_STONE,0.8f); // concrete - addFriction(LL_MCODE_METAL,0.3f); // steel - addFriction(LL_MCODE_GLASS,0.2f); // borosilicate glass - addFriction(LL_MCODE_WOOD,0.6f); // southern pine - addFriction(LL_MCODE_FLESH,0.9f); // saltwater - addFriction(LL_MCODE_PLASTIC,0.4f); // HDPE - addFriction(LL_MCODE_RUBBER,0.9f); // - addFriction(LL_MCODE_LIGHT,0.2f); // - - addRestitution(LL_MCODE_STONE,0.4f); // concrete - addRestitution(LL_MCODE_METAL,0.4f); // steel - addRestitution(LL_MCODE_GLASS,0.7f); // borosilicate glass - addRestitution(LL_MCODE_WOOD,0.5f); // southern pine - addRestitution(LL_MCODE_FLESH,0.3f); // saltwater - addRestitution(LL_MCODE_PLASTIC,0.7f); // HDPE - addRestitution(LL_MCODE_RUBBER,0.9f); // - addRestitution(LL_MCODE_LIGHT,0.7f); // - - addShatterSound(LL_MCODE_STONE,LLUUID("ea296329-0f09-4993-af1b-e6784bab1dc9")); - addShatterSound(LL_MCODE_METAL,LLUUID("d1375446-1c4d-470b-9135-30132433b678")); - addShatterSound(LL_MCODE_GLASS,LLUUID("85cda060-b393-48e6-81c8-2cfdfb275351")); - addShatterSound(LL_MCODE_WOOD,LLUUID("6f00669f-15e0-4793-a63e-c03f62fee43a")); - addShatterSound(LL_MCODE_FLESH,LLUUID("2d8c6f51-149e-4e23-8413-93a379b42b67")); - addShatterSound(LL_MCODE_PLASTIC,LLUUID("d55c7f3c-e1c3-4ddc-9eff-9ef805d9190e")); - addShatterSound(LL_MCODE_RUBBER,LLUUID("212b6d1e-8d9c-4986-b3aa-f3c6df8d987d")); - addShatterSound(LL_MCODE_LIGHT,LLUUID("d55c7f3c-e1c3-4ddc-9eff-9ef805d9190e")); - - // CollisionSounds - mCollisionSoundMatrix = new LLUUID[LL_MCODE_END*LL_MCODE_END]; - if (mCollisionSoundMatrix) - { - addCollisionSound(LL_MCODE_STONE, LL_MCODE_STONE, SND_STONE_STONE); - addCollisionSound(LL_MCODE_STONE, LL_MCODE_METAL, SND_STONE_METAL); - addCollisionSound(LL_MCODE_STONE, LL_MCODE_GLASS, SND_STONE_GLASS); - addCollisionSound(LL_MCODE_STONE, LL_MCODE_WOOD, SND_STONE_WOOD); - addCollisionSound(LL_MCODE_STONE, LL_MCODE_FLESH, SND_STONE_FLESH); - addCollisionSound(LL_MCODE_STONE, LL_MCODE_PLASTIC, SND_STONE_PLASTIC); - addCollisionSound(LL_MCODE_STONE, LL_MCODE_RUBBER, SND_STONE_RUBBER); - addCollisionSound(LL_MCODE_STONE, LL_MCODE_LIGHT, SND_STONE_PLASTIC); - - addCollisionSound(LL_MCODE_METAL, LL_MCODE_METAL, SND_METAL_METAL); - addCollisionSound(LL_MCODE_METAL, LL_MCODE_GLASS, SND_METAL_GLASS); - addCollisionSound(LL_MCODE_METAL, LL_MCODE_WOOD, SND_METAL_WOOD); - addCollisionSound(LL_MCODE_METAL, LL_MCODE_FLESH, SND_METAL_FLESH); - addCollisionSound(LL_MCODE_METAL, LL_MCODE_PLASTIC, SND_METAL_PLASTIC); - addCollisionSound(LL_MCODE_METAL, LL_MCODE_LIGHT, SND_METAL_PLASTIC); - addCollisionSound(LL_MCODE_METAL, LL_MCODE_RUBBER, SND_METAL_RUBBER); - - addCollisionSound(LL_MCODE_GLASS, LL_MCODE_GLASS, SND_GLASS_GLASS); - addCollisionSound(LL_MCODE_GLASS, LL_MCODE_WOOD, SND_GLASS_WOOD); - addCollisionSound(LL_MCODE_GLASS, LL_MCODE_FLESH, SND_GLASS_FLESH); - addCollisionSound(LL_MCODE_GLASS, LL_MCODE_PLASTIC, SND_GLASS_PLASTIC); - addCollisionSound(LL_MCODE_GLASS, LL_MCODE_RUBBER, SND_GLASS_RUBBER); - addCollisionSound(LL_MCODE_GLASS, LL_MCODE_LIGHT, SND_GLASS_PLASTIC); - - addCollisionSound(LL_MCODE_WOOD, LL_MCODE_WOOD, SND_WOOD_WOOD); - addCollisionSound(LL_MCODE_WOOD, LL_MCODE_FLESH, SND_WOOD_FLESH); - addCollisionSound(LL_MCODE_WOOD, LL_MCODE_PLASTIC, SND_WOOD_PLASTIC); - addCollisionSound(LL_MCODE_WOOD, LL_MCODE_RUBBER, SND_WOOD_RUBBER); - addCollisionSound(LL_MCODE_WOOD, LL_MCODE_LIGHT, SND_WOOD_PLASTIC); - - addCollisionSound(LL_MCODE_FLESH, LL_MCODE_FLESH, SND_FLESH_FLESH); - addCollisionSound(LL_MCODE_FLESH, LL_MCODE_PLASTIC, SND_FLESH_PLASTIC); - addCollisionSound(LL_MCODE_FLESH, LL_MCODE_RUBBER, SND_FLESH_RUBBER); - addCollisionSound(LL_MCODE_FLESH, LL_MCODE_LIGHT, SND_FLESH_PLASTIC); - - addCollisionSound(LL_MCODE_RUBBER, LL_MCODE_RUBBER, SND_RUBBER_RUBBER); - addCollisionSound(LL_MCODE_RUBBER, LL_MCODE_PLASTIC, SND_RUBBER_PLASTIC); - addCollisionSound(LL_MCODE_RUBBER, LL_MCODE_LIGHT, SND_RUBBER_PLASTIC); - - addCollisionSound(LL_MCODE_PLASTIC, LL_MCODE_PLASTIC, SND_PLASTIC_PLASTIC); - addCollisionSound(LL_MCODE_PLASTIC, LL_MCODE_LIGHT, SND_PLASTIC_PLASTIC); - - addCollisionSound(LL_MCODE_LIGHT, LL_MCODE_LIGHT, SND_PLASTIC_PLASTIC); - } - - // Sliding Sounds - mSlidingSoundMatrix = new LLUUID[LL_MCODE_END*LL_MCODE_END]; - if (mSlidingSoundMatrix) - { - addSlidingSound(LL_MCODE_STONE, LL_MCODE_STONE, SND_SLIDE_STONE_STONE); - addSlidingSound(LL_MCODE_STONE, LL_MCODE_METAL, SND_SLIDE_STONE_STONE_01); - addSlidingSound(LL_MCODE_STONE, LL_MCODE_GLASS, SND_SLIDE_STONE_STONE_01); - addSlidingSound(LL_MCODE_STONE, LL_MCODE_WOOD, SND_SLIDE_STONE_WOOD); - addSlidingSound(LL_MCODE_STONE, LL_MCODE_FLESH, SND_SLIDE_STONE_STONE_01); - addSlidingSound(LL_MCODE_STONE, LL_MCODE_PLASTIC, SND_SLIDE_STONE_PLASTIC); - addSlidingSound(LL_MCODE_STONE, LL_MCODE_RUBBER, SND_SLIDE_STONE_RUBBER); - addSlidingSound(LL_MCODE_STONE, LL_MCODE_LIGHT, SND_SLIDE_STONE_PLASTIC); - - addSlidingSound(LL_MCODE_METAL, LL_MCODE_METAL, SND_SLIDE_METAL_METAL); - addSlidingSound(LL_MCODE_METAL, LL_MCODE_GLASS, SND_SLIDE_METAL_GLASS); - addSlidingSound(LL_MCODE_METAL, LL_MCODE_WOOD, SND_SLIDE_METAL_WOOD); - addSlidingSound(LL_MCODE_METAL, LL_MCODE_FLESH, SND_SLIDE_METAL_FLESH); - addSlidingSound(LL_MCODE_METAL, LL_MCODE_PLASTIC, SND_SLIDE_STONE_STONE_01); - addSlidingSound(LL_MCODE_METAL, LL_MCODE_RUBBER, SND_SLIDE_METAL_RUBBER); - addSlidingSound(LL_MCODE_METAL, LL_MCODE_LIGHT, SND_SLIDE_STONE_STONE_01); - - addSlidingSound(LL_MCODE_GLASS, LL_MCODE_GLASS, SND_SLIDE_STONE_STONE_01); - addSlidingSound(LL_MCODE_GLASS, LL_MCODE_WOOD, SND_SLIDE_STONE_STONE_01); - addSlidingSound(LL_MCODE_GLASS, LL_MCODE_FLESH, SND_SLIDE_STONE_STONE_01); - addSlidingSound(LL_MCODE_GLASS, LL_MCODE_PLASTIC, SND_SLIDE_STONE_STONE_01); - addSlidingSound(LL_MCODE_GLASS, LL_MCODE_RUBBER, SND_SLIDE_STONE_STONE_01); - addSlidingSound(LL_MCODE_GLASS, LL_MCODE_LIGHT, SND_SLIDE_STONE_STONE_01); - - addSlidingSound(LL_MCODE_WOOD, LL_MCODE_WOOD, SND_SLIDE_WOOD_WOOD); - addSlidingSound(LL_MCODE_WOOD, LL_MCODE_FLESH, SND_SLIDE_WOOD_FLESH); - addSlidingSound(LL_MCODE_WOOD, LL_MCODE_PLASTIC, SND_SLIDE_WOOD_PLASTIC); - addSlidingSound(LL_MCODE_WOOD, LL_MCODE_RUBBER, SND_SLIDE_STONE_STONE_01); - addSlidingSound(LL_MCODE_WOOD, LL_MCODE_LIGHT, SND_SLIDE_WOOD_PLASTIC); - - addSlidingSound(LL_MCODE_FLESH, LL_MCODE_FLESH, SND_SLIDE_FLESH_FLESH); - addSlidingSound(LL_MCODE_FLESH, LL_MCODE_PLASTIC, SND_SLIDE_STONE_STONE_01); - addSlidingSound(LL_MCODE_FLESH, LL_MCODE_RUBBER, SND_SLIDE_STONE_STONE_01); - addSlidingSound(LL_MCODE_FLESH, LL_MCODE_LIGHT, SND_SLIDE_STONE_STONE_01); - - addSlidingSound(LL_MCODE_RUBBER, LL_MCODE_RUBBER, SND_SLIDE_STONE_STONE_01); - addSlidingSound(LL_MCODE_RUBBER, LL_MCODE_PLASTIC, SND_SLIDE_RUBBER_PLASTIC); - addSlidingSound(LL_MCODE_RUBBER, LL_MCODE_LIGHT, SND_SLIDE_RUBBER_PLASTIC); - - addSlidingSound(LL_MCODE_PLASTIC, LL_MCODE_PLASTIC, SND_SLIDE_STONE_STONE_01); - addSlidingSound(LL_MCODE_PLASTIC, LL_MCODE_LIGHT, SND_SLIDE_STONE_STONE_01); - - addSlidingSound(LL_MCODE_LIGHT, LL_MCODE_LIGHT, SND_SLIDE_STONE_STONE_01); - } - - // Rolling Sounds - mRollingSoundMatrix = new LLUUID[LL_MCODE_END*LL_MCODE_END]; - if (mRollingSoundMatrix) - { - addRollingSound(LL_MCODE_STONE, LL_MCODE_STONE, SND_ROLL_STONE_STONE); - addRollingSound(LL_MCODE_STONE, LL_MCODE_METAL, SND_SLIDE_STONE_STONE_01); - addRollingSound(LL_MCODE_STONE, LL_MCODE_GLASS, SND_SLIDE_STONE_STONE_01); - addRollingSound(LL_MCODE_STONE, LL_MCODE_WOOD, SND_ROLL_STONE_WOOD); - addRollingSound(LL_MCODE_STONE, LL_MCODE_FLESH, SND_SLIDE_STONE_STONE_01); - addRollingSound(LL_MCODE_STONE, LL_MCODE_PLASTIC, SND_ROLL_STONE_PLASTIC); - addRollingSound(LL_MCODE_STONE, LL_MCODE_RUBBER, SND_SLIDE_STONE_STONE_01); - addRollingSound(LL_MCODE_STONE, LL_MCODE_LIGHT, SND_ROLL_STONE_PLASTIC); - - addRollingSound(LL_MCODE_METAL, LL_MCODE_METAL, SND_SLIDE_STONE_STONE_01); - addRollingSound(LL_MCODE_METAL, LL_MCODE_GLASS, SND_ROLL_METAL_GLASS); - addRollingSound(LL_MCODE_METAL, LL_MCODE_WOOD, SND_ROLL_METAL_WOOD); - addRollingSound(LL_MCODE_METAL, LL_MCODE_FLESH, SND_SLIDE_STONE_STONE_01); - addRollingSound(LL_MCODE_METAL, LL_MCODE_PLASTIC, SND_ROLL_METAL_WOOD); - addRollingSound(LL_MCODE_METAL, LL_MCODE_RUBBER, SND_SLIDE_STONE_STONE_01); - addRollingSound(LL_MCODE_METAL, LL_MCODE_LIGHT, SND_ROLL_METAL_WOOD); - - addRollingSound(LL_MCODE_GLASS, LL_MCODE_GLASS, SND_SLIDE_STONE_STONE_01); - addRollingSound(LL_MCODE_GLASS, LL_MCODE_WOOD, SND_ROLL_GLASS_WOOD); - addRollingSound(LL_MCODE_GLASS, LL_MCODE_FLESH, SND_SLIDE_STONE_STONE_01); - addRollingSound(LL_MCODE_GLASS, LL_MCODE_PLASTIC, SND_SLIDE_STONE_STONE_01); - addRollingSound(LL_MCODE_GLASS, LL_MCODE_RUBBER, SND_SLIDE_STONE_STONE_01); - addRollingSound(LL_MCODE_GLASS, LL_MCODE_LIGHT, SND_SLIDE_STONE_STONE_01); - - addRollingSound(LL_MCODE_WOOD, LL_MCODE_WOOD, SND_ROLL_WOOD_WOOD); - addRollingSound(LL_MCODE_WOOD, LL_MCODE_FLESH, SND_ROLL_WOOD_FLESH); - addRollingSound(LL_MCODE_WOOD, LL_MCODE_PLASTIC, SND_ROLL_WOOD_PLASTIC); - addRollingSound(LL_MCODE_WOOD, LL_MCODE_RUBBER, SND_SLIDE_STONE_STONE_01); - addRollingSound(LL_MCODE_WOOD, LL_MCODE_LIGHT, SND_ROLL_WOOD_PLASTIC); - - addRollingSound(LL_MCODE_FLESH, LL_MCODE_FLESH, SND_SLIDE_STONE_STONE_01); - addRollingSound(LL_MCODE_FLESH, LL_MCODE_PLASTIC, SND_ROLL_FLESH_PLASTIC); - addRollingSound(LL_MCODE_FLESH, LL_MCODE_RUBBER, SND_SLIDE_STONE_STONE_01); - addRollingSound(LL_MCODE_FLESH, LL_MCODE_LIGHT, SND_ROLL_FLESH_PLASTIC); - - addRollingSound(LL_MCODE_RUBBER, LL_MCODE_RUBBER, SND_SLIDE_STONE_STONE_01); - addRollingSound(LL_MCODE_RUBBER, LL_MCODE_PLASTIC, SND_SLIDE_STONE_STONE_01); - addRollingSound(LL_MCODE_RUBBER, LL_MCODE_LIGHT, SND_SLIDE_STONE_STONE_01); - - addRollingSound(LL_MCODE_PLASTIC, LL_MCODE_PLASTIC, SND_ROLL_PLASTIC_PLASTIC); - addRollingSound(LL_MCODE_PLASTIC, LL_MCODE_LIGHT, SND_ROLL_PLASTIC_PLASTIC); - - addRollingSound(LL_MCODE_LIGHT, LL_MCODE_LIGHT, SND_ROLL_PLASTIC_PLASTIC); - } + addDensity(LL_MCODE_STONE,30.f); + addDensity(LL_MCODE_METAL,50.f); + addDensity(LL_MCODE_GLASS,20.f); + addDensity(LL_MCODE_WOOD,10.f); + addDensity(LL_MCODE_FLESH,10.f); + addDensity(LL_MCODE_PLASTIC,5.f); + addDensity(LL_MCODE_RUBBER,0.5f); // + addDensity(LL_MCODE_LIGHT,20.f); // + + // add damage and energy values + addDamageAndEnergy(LL_MCODE_STONE, 1.f, 1.f, 1.f); // concrete + addDamageAndEnergy(LL_MCODE_METAL, 1.f, 1.f, 1.f); // steel + addDamageAndEnergy(LL_MCODE_GLASS, 1.f, 1.f, 1.f); // borosilicate glass + addDamageAndEnergy(LL_MCODE_WOOD, 1.f, 1.f, 1.f); // southern pine + addDamageAndEnergy(LL_MCODE_FLESH, 1.f, 1.f, 1.f); // saltwater + addDamageAndEnergy(LL_MCODE_PLASTIC, 1.f, 1.f, 1.f); // HDPE + addDamageAndEnergy(LL_MCODE_RUBBER, 1.f, 1.f, 1.f); // + addDamageAndEnergy(LL_MCODE_LIGHT, 1.f, 1.f, 1.f); // + + addFriction(LL_MCODE_STONE,0.8f); // concrete + addFriction(LL_MCODE_METAL,0.3f); // steel + addFriction(LL_MCODE_GLASS,0.2f); // borosilicate glass + addFriction(LL_MCODE_WOOD,0.6f); // southern pine + addFriction(LL_MCODE_FLESH,0.9f); // saltwater + addFriction(LL_MCODE_PLASTIC,0.4f); // HDPE + addFriction(LL_MCODE_RUBBER,0.9f); // + addFriction(LL_MCODE_LIGHT,0.2f); // + + addRestitution(LL_MCODE_STONE,0.4f); // concrete + addRestitution(LL_MCODE_METAL,0.4f); // steel + addRestitution(LL_MCODE_GLASS,0.7f); // borosilicate glass + addRestitution(LL_MCODE_WOOD,0.5f); // southern pine + addRestitution(LL_MCODE_FLESH,0.3f); // saltwater + addRestitution(LL_MCODE_PLASTIC,0.7f); // HDPE + addRestitution(LL_MCODE_RUBBER,0.9f); // + addRestitution(LL_MCODE_LIGHT,0.7f); // + + addShatterSound(LL_MCODE_STONE,LLUUID("ea296329-0f09-4993-af1b-e6784bab1dc9")); + addShatterSound(LL_MCODE_METAL,LLUUID("d1375446-1c4d-470b-9135-30132433b678")); + addShatterSound(LL_MCODE_GLASS,LLUUID("85cda060-b393-48e6-81c8-2cfdfb275351")); + addShatterSound(LL_MCODE_WOOD,LLUUID("6f00669f-15e0-4793-a63e-c03f62fee43a")); + addShatterSound(LL_MCODE_FLESH,LLUUID("2d8c6f51-149e-4e23-8413-93a379b42b67")); + addShatterSound(LL_MCODE_PLASTIC,LLUUID("d55c7f3c-e1c3-4ddc-9eff-9ef805d9190e")); + addShatterSound(LL_MCODE_RUBBER,LLUUID("212b6d1e-8d9c-4986-b3aa-f3c6df8d987d")); + addShatterSound(LL_MCODE_LIGHT,LLUUID("d55c7f3c-e1c3-4ddc-9eff-9ef805d9190e")); + + // CollisionSounds + mCollisionSoundMatrix = new LLUUID[LL_MCODE_END*LL_MCODE_END]; + if (mCollisionSoundMatrix) + { + addCollisionSound(LL_MCODE_STONE, LL_MCODE_STONE, SND_STONE_STONE); + addCollisionSound(LL_MCODE_STONE, LL_MCODE_METAL, SND_STONE_METAL); + addCollisionSound(LL_MCODE_STONE, LL_MCODE_GLASS, SND_STONE_GLASS); + addCollisionSound(LL_MCODE_STONE, LL_MCODE_WOOD, SND_STONE_WOOD); + addCollisionSound(LL_MCODE_STONE, LL_MCODE_FLESH, SND_STONE_FLESH); + addCollisionSound(LL_MCODE_STONE, LL_MCODE_PLASTIC, SND_STONE_PLASTIC); + addCollisionSound(LL_MCODE_STONE, LL_MCODE_RUBBER, SND_STONE_RUBBER); + addCollisionSound(LL_MCODE_STONE, LL_MCODE_LIGHT, SND_STONE_PLASTIC); + + addCollisionSound(LL_MCODE_METAL, LL_MCODE_METAL, SND_METAL_METAL); + addCollisionSound(LL_MCODE_METAL, LL_MCODE_GLASS, SND_METAL_GLASS); + addCollisionSound(LL_MCODE_METAL, LL_MCODE_WOOD, SND_METAL_WOOD); + addCollisionSound(LL_MCODE_METAL, LL_MCODE_FLESH, SND_METAL_FLESH); + addCollisionSound(LL_MCODE_METAL, LL_MCODE_PLASTIC, SND_METAL_PLASTIC); + addCollisionSound(LL_MCODE_METAL, LL_MCODE_LIGHT, SND_METAL_PLASTIC); + addCollisionSound(LL_MCODE_METAL, LL_MCODE_RUBBER, SND_METAL_RUBBER); + + addCollisionSound(LL_MCODE_GLASS, LL_MCODE_GLASS, SND_GLASS_GLASS); + addCollisionSound(LL_MCODE_GLASS, LL_MCODE_WOOD, SND_GLASS_WOOD); + addCollisionSound(LL_MCODE_GLASS, LL_MCODE_FLESH, SND_GLASS_FLESH); + addCollisionSound(LL_MCODE_GLASS, LL_MCODE_PLASTIC, SND_GLASS_PLASTIC); + addCollisionSound(LL_MCODE_GLASS, LL_MCODE_RUBBER, SND_GLASS_RUBBER); + addCollisionSound(LL_MCODE_GLASS, LL_MCODE_LIGHT, SND_GLASS_PLASTIC); + + addCollisionSound(LL_MCODE_WOOD, LL_MCODE_WOOD, SND_WOOD_WOOD); + addCollisionSound(LL_MCODE_WOOD, LL_MCODE_FLESH, SND_WOOD_FLESH); + addCollisionSound(LL_MCODE_WOOD, LL_MCODE_PLASTIC, SND_WOOD_PLASTIC); + addCollisionSound(LL_MCODE_WOOD, LL_MCODE_RUBBER, SND_WOOD_RUBBER); + addCollisionSound(LL_MCODE_WOOD, LL_MCODE_LIGHT, SND_WOOD_PLASTIC); + + addCollisionSound(LL_MCODE_FLESH, LL_MCODE_FLESH, SND_FLESH_FLESH); + addCollisionSound(LL_MCODE_FLESH, LL_MCODE_PLASTIC, SND_FLESH_PLASTIC); + addCollisionSound(LL_MCODE_FLESH, LL_MCODE_RUBBER, SND_FLESH_RUBBER); + addCollisionSound(LL_MCODE_FLESH, LL_MCODE_LIGHT, SND_FLESH_PLASTIC); + + addCollisionSound(LL_MCODE_RUBBER, LL_MCODE_RUBBER, SND_RUBBER_RUBBER); + addCollisionSound(LL_MCODE_RUBBER, LL_MCODE_PLASTIC, SND_RUBBER_PLASTIC); + addCollisionSound(LL_MCODE_RUBBER, LL_MCODE_LIGHT, SND_RUBBER_PLASTIC); + + addCollisionSound(LL_MCODE_PLASTIC, LL_MCODE_PLASTIC, SND_PLASTIC_PLASTIC); + addCollisionSound(LL_MCODE_PLASTIC, LL_MCODE_LIGHT, SND_PLASTIC_PLASTIC); + + addCollisionSound(LL_MCODE_LIGHT, LL_MCODE_LIGHT, SND_PLASTIC_PLASTIC); + } + + // Sliding Sounds + mSlidingSoundMatrix = new LLUUID[LL_MCODE_END*LL_MCODE_END]; + if (mSlidingSoundMatrix) + { + addSlidingSound(LL_MCODE_STONE, LL_MCODE_STONE, SND_SLIDE_STONE_STONE); + addSlidingSound(LL_MCODE_STONE, LL_MCODE_METAL, SND_SLIDE_STONE_STONE_01); + addSlidingSound(LL_MCODE_STONE, LL_MCODE_GLASS, SND_SLIDE_STONE_STONE_01); + addSlidingSound(LL_MCODE_STONE, LL_MCODE_WOOD, SND_SLIDE_STONE_WOOD); + addSlidingSound(LL_MCODE_STONE, LL_MCODE_FLESH, SND_SLIDE_STONE_STONE_01); + addSlidingSound(LL_MCODE_STONE, LL_MCODE_PLASTIC, SND_SLIDE_STONE_PLASTIC); + addSlidingSound(LL_MCODE_STONE, LL_MCODE_RUBBER, SND_SLIDE_STONE_RUBBER); + addSlidingSound(LL_MCODE_STONE, LL_MCODE_LIGHT, SND_SLIDE_STONE_PLASTIC); + + addSlidingSound(LL_MCODE_METAL, LL_MCODE_METAL, SND_SLIDE_METAL_METAL); + addSlidingSound(LL_MCODE_METAL, LL_MCODE_GLASS, SND_SLIDE_METAL_GLASS); + addSlidingSound(LL_MCODE_METAL, LL_MCODE_WOOD, SND_SLIDE_METAL_WOOD); + addSlidingSound(LL_MCODE_METAL, LL_MCODE_FLESH, SND_SLIDE_METAL_FLESH); + addSlidingSound(LL_MCODE_METAL, LL_MCODE_PLASTIC, SND_SLIDE_STONE_STONE_01); + addSlidingSound(LL_MCODE_METAL, LL_MCODE_RUBBER, SND_SLIDE_METAL_RUBBER); + addSlidingSound(LL_MCODE_METAL, LL_MCODE_LIGHT, SND_SLIDE_STONE_STONE_01); + + addSlidingSound(LL_MCODE_GLASS, LL_MCODE_GLASS, SND_SLIDE_STONE_STONE_01); + addSlidingSound(LL_MCODE_GLASS, LL_MCODE_WOOD, SND_SLIDE_STONE_STONE_01); + addSlidingSound(LL_MCODE_GLASS, LL_MCODE_FLESH, SND_SLIDE_STONE_STONE_01); + addSlidingSound(LL_MCODE_GLASS, LL_MCODE_PLASTIC, SND_SLIDE_STONE_STONE_01); + addSlidingSound(LL_MCODE_GLASS, LL_MCODE_RUBBER, SND_SLIDE_STONE_STONE_01); + addSlidingSound(LL_MCODE_GLASS, LL_MCODE_LIGHT, SND_SLIDE_STONE_STONE_01); + + addSlidingSound(LL_MCODE_WOOD, LL_MCODE_WOOD, SND_SLIDE_WOOD_WOOD); + addSlidingSound(LL_MCODE_WOOD, LL_MCODE_FLESH, SND_SLIDE_WOOD_FLESH); + addSlidingSound(LL_MCODE_WOOD, LL_MCODE_PLASTIC, SND_SLIDE_WOOD_PLASTIC); + addSlidingSound(LL_MCODE_WOOD, LL_MCODE_RUBBER, SND_SLIDE_STONE_STONE_01); + addSlidingSound(LL_MCODE_WOOD, LL_MCODE_LIGHT, SND_SLIDE_WOOD_PLASTIC); + + addSlidingSound(LL_MCODE_FLESH, LL_MCODE_FLESH, SND_SLIDE_FLESH_FLESH); + addSlidingSound(LL_MCODE_FLESH, LL_MCODE_PLASTIC, SND_SLIDE_STONE_STONE_01); + addSlidingSound(LL_MCODE_FLESH, LL_MCODE_RUBBER, SND_SLIDE_STONE_STONE_01); + addSlidingSound(LL_MCODE_FLESH, LL_MCODE_LIGHT, SND_SLIDE_STONE_STONE_01); + + addSlidingSound(LL_MCODE_RUBBER, LL_MCODE_RUBBER, SND_SLIDE_STONE_STONE_01); + addSlidingSound(LL_MCODE_RUBBER, LL_MCODE_PLASTIC, SND_SLIDE_RUBBER_PLASTIC); + addSlidingSound(LL_MCODE_RUBBER, LL_MCODE_LIGHT, SND_SLIDE_RUBBER_PLASTIC); + + addSlidingSound(LL_MCODE_PLASTIC, LL_MCODE_PLASTIC, SND_SLIDE_STONE_STONE_01); + addSlidingSound(LL_MCODE_PLASTIC, LL_MCODE_LIGHT, SND_SLIDE_STONE_STONE_01); + + addSlidingSound(LL_MCODE_LIGHT, LL_MCODE_LIGHT, SND_SLIDE_STONE_STONE_01); + } + + // Rolling Sounds + mRollingSoundMatrix = new LLUUID[LL_MCODE_END*LL_MCODE_END]; + if (mRollingSoundMatrix) + { + addRollingSound(LL_MCODE_STONE, LL_MCODE_STONE, SND_ROLL_STONE_STONE); + addRollingSound(LL_MCODE_STONE, LL_MCODE_METAL, SND_SLIDE_STONE_STONE_01); + addRollingSound(LL_MCODE_STONE, LL_MCODE_GLASS, SND_SLIDE_STONE_STONE_01); + addRollingSound(LL_MCODE_STONE, LL_MCODE_WOOD, SND_ROLL_STONE_WOOD); + addRollingSound(LL_MCODE_STONE, LL_MCODE_FLESH, SND_SLIDE_STONE_STONE_01); + addRollingSound(LL_MCODE_STONE, LL_MCODE_PLASTIC, SND_ROLL_STONE_PLASTIC); + addRollingSound(LL_MCODE_STONE, LL_MCODE_RUBBER, SND_SLIDE_STONE_STONE_01); + addRollingSound(LL_MCODE_STONE, LL_MCODE_LIGHT, SND_ROLL_STONE_PLASTIC); + + addRollingSound(LL_MCODE_METAL, LL_MCODE_METAL, SND_SLIDE_STONE_STONE_01); + addRollingSound(LL_MCODE_METAL, LL_MCODE_GLASS, SND_ROLL_METAL_GLASS); + addRollingSound(LL_MCODE_METAL, LL_MCODE_WOOD, SND_ROLL_METAL_WOOD); + addRollingSound(LL_MCODE_METAL, LL_MCODE_FLESH, SND_SLIDE_STONE_STONE_01); + addRollingSound(LL_MCODE_METAL, LL_MCODE_PLASTIC, SND_ROLL_METAL_WOOD); + addRollingSound(LL_MCODE_METAL, LL_MCODE_RUBBER, SND_SLIDE_STONE_STONE_01); + addRollingSound(LL_MCODE_METAL, LL_MCODE_LIGHT, SND_ROLL_METAL_WOOD); + + addRollingSound(LL_MCODE_GLASS, LL_MCODE_GLASS, SND_SLIDE_STONE_STONE_01); + addRollingSound(LL_MCODE_GLASS, LL_MCODE_WOOD, SND_ROLL_GLASS_WOOD); + addRollingSound(LL_MCODE_GLASS, LL_MCODE_FLESH, SND_SLIDE_STONE_STONE_01); + addRollingSound(LL_MCODE_GLASS, LL_MCODE_PLASTIC, SND_SLIDE_STONE_STONE_01); + addRollingSound(LL_MCODE_GLASS, LL_MCODE_RUBBER, SND_SLIDE_STONE_STONE_01); + addRollingSound(LL_MCODE_GLASS, LL_MCODE_LIGHT, SND_SLIDE_STONE_STONE_01); + + addRollingSound(LL_MCODE_WOOD, LL_MCODE_WOOD, SND_ROLL_WOOD_WOOD); + addRollingSound(LL_MCODE_WOOD, LL_MCODE_FLESH, SND_ROLL_WOOD_FLESH); + addRollingSound(LL_MCODE_WOOD, LL_MCODE_PLASTIC, SND_ROLL_WOOD_PLASTIC); + addRollingSound(LL_MCODE_WOOD, LL_MCODE_RUBBER, SND_SLIDE_STONE_STONE_01); + addRollingSound(LL_MCODE_WOOD, LL_MCODE_LIGHT, SND_ROLL_WOOD_PLASTIC); + + addRollingSound(LL_MCODE_FLESH, LL_MCODE_FLESH, SND_SLIDE_STONE_STONE_01); + addRollingSound(LL_MCODE_FLESH, LL_MCODE_PLASTIC, SND_ROLL_FLESH_PLASTIC); + addRollingSound(LL_MCODE_FLESH, LL_MCODE_RUBBER, SND_SLIDE_STONE_STONE_01); + addRollingSound(LL_MCODE_FLESH, LL_MCODE_LIGHT, SND_ROLL_FLESH_PLASTIC); + + addRollingSound(LL_MCODE_RUBBER, LL_MCODE_RUBBER, SND_SLIDE_STONE_STONE_01); + addRollingSound(LL_MCODE_RUBBER, LL_MCODE_PLASTIC, SND_SLIDE_STONE_STONE_01); + addRollingSound(LL_MCODE_RUBBER, LL_MCODE_LIGHT, SND_SLIDE_STONE_STONE_01); + + addRollingSound(LL_MCODE_PLASTIC, LL_MCODE_PLASTIC, SND_ROLL_PLASTIC_PLASTIC); + addRollingSound(LL_MCODE_PLASTIC, LL_MCODE_LIGHT, SND_ROLL_PLASTIC_PLASTIC); + + addRollingSound(LL_MCODE_LIGHT, LL_MCODE_LIGHT, SND_ROLL_PLASTIC_PLASTIC); + } } BOOL LLMaterialTable::add(U8 mcode, const std::string& name, const LLUUID &uuid) { - LLMaterialInfo *infop; + LLMaterialInfo *infop; - infop = new LLMaterialInfo(mcode,name,uuid); - if (!infop) return FALSE; + infop = new LLMaterialInfo(mcode,name,uuid); + if (!infop) return FALSE; - // Add at the end so the order in menus matches the order in this - // file. JNC 11.30.01 - mMaterialInfoList.push_back(infop); + // Add at the end so the order in menus matches the order in this + // file. JNC 11.30.01 + mMaterialInfoList.push_back(infop); - return TRUE; + return TRUE; } BOOL LLMaterialTable::addCollisionSound(U8 mcode, U8 mcode2, const LLUUID &uuid) { - if (mCollisionSoundMatrix && (mcode < LL_MCODE_END) && (mcode2 < LL_MCODE_END)) - { - mCollisionSoundMatrix[mcode * LL_MCODE_END + mcode2] = uuid; - if (mcode != mcode2) - { - mCollisionSoundMatrix[mcode2 * LL_MCODE_END + mcode] = uuid; - } - } - return TRUE; + if (mCollisionSoundMatrix && (mcode < LL_MCODE_END) && (mcode2 < LL_MCODE_END)) + { + mCollisionSoundMatrix[mcode * LL_MCODE_END + mcode2] = uuid; + if (mcode != mcode2) + { + mCollisionSoundMatrix[mcode2 * LL_MCODE_END + mcode] = uuid; + } + } + return TRUE; } BOOL LLMaterialTable::addSlidingSound(U8 mcode, U8 mcode2, const LLUUID &uuid) { - if (mSlidingSoundMatrix && (mcode < LL_MCODE_END) && (mcode2 < LL_MCODE_END)) - { - mSlidingSoundMatrix[mcode * LL_MCODE_END + mcode2] = uuid; - if (mcode != mcode2) - { - mSlidingSoundMatrix[mcode2 * LL_MCODE_END + mcode] = uuid; - } - } - return TRUE; + if (mSlidingSoundMatrix && (mcode < LL_MCODE_END) && (mcode2 < LL_MCODE_END)) + { + mSlidingSoundMatrix[mcode * LL_MCODE_END + mcode2] = uuid; + if (mcode != mcode2) + { + mSlidingSoundMatrix[mcode2 * LL_MCODE_END + mcode] = uuid; + } + } + return TRUE; } BOOL LLMaterialTable::addRollingSound(U8 mcode, U8 mcode2, const LLUUID &uuid) { - if (mRollingSoundMatrix && (mcode < LL_MCODE_END) && (mcode2 < LL_MCODE_END)) - { - mRollingSoundMatrix[mcode * LL_MCODE_END + mcode2] = uuid; - if (mcode != mcode2) - { - mRollingSoundMatrix[mcode2 * LL_MCODE_END + mcode] = uuid; - } - } - return TRUE; + if (mRollingSoundMatrix && (mcode < LL_MCODE_END) && (mcode2 < LL_MCODE_END)) + { + mRollingSoundMatrix[mcode * LL_MCODE_END + mcode2] = uuid; + if (mcode != mcode2) + { + mRollingSoundMatrix[mcode2 * LL_MCODE_END + mcode] = uuid; + } + } + return TRUE; } BOOL LLMaterialTable::addShatterSound(U8 mcode, const LLUUID &uuid) { - for (info_list_t::iterator iter = mMaterialInfoList.begin(); - iter != mMaterialInfoList.end(); ++iter) - { - LLMaterialInfo *infop = *iter; - if (mcode == infop->mMCode) - { - infop->mShatterSoundID = uuid; - return TRUE; - } - } + for (info_list_t::iterator iter = mMaterialInfoList.begin(); + iter != mMaterialInfoList.end(); ++iter) + { + LLMaterialInfo *infop = *iter; + if (mcode == infop->mMCode) + { + infop->mShatterSoundID = uuid; + return TRUE; + } + } - return FALSE; + return FALSE; } BOOL LLMaterialTable::addDensity(U8 mcode, const F32 &density) { - for (info_list_t::iterator iter = mMaterialInfoList.begin(); - iter != mMaterialInfoList.end(); ++iter) - { - LLMaterialInfo *infop = *iter; - if (mcode == infop->mMCode) - { - infop->mDensity = density; - return TRUE; - } - } + for (info_list_t::iterator iter = mMaterialInfoList.begin(); + iter != mMaterialInfoList.end(); ++iter) + { + LLMaterialInfo *infop = *iter; + if (mcode == infop->mMCode) + { + infop->mDensity = density; + return TRUE; + } + } - return FALSE; + return FALSE; } BOOL LLMaterialTable::addRestitution(U8 mcode, const F32 &restitution) { - for (info_list_t::iterator iter = mMaterialInfoList.begin(); - iter != mMaterialInfoList.end(); ++iter) - { - LLMaterialInfo *infop = *iter; - if (mcode == infop->mMCode) - { - infop->mRestitution = restitution; - return TRUE; - } - } + for (info_list_t::iterator iter = mMaterialInfoList.begin(); + iter != mMaterialInfoList.end(); ++iter) + { + LLMaterialInfo *infop = *iter; + if (mcode == infop->mMCode) + { + infop->mRestitution = restitution; + return TRUE; + } + } - return FALSE; + return FALSE; } BOOL LLMaterialTable::addFriction(U8 mcode, const F32 &friction) { - for (info_list_t::iterator iter = mMaterialInfoList.begin(); - iter != mMaterialInfoList.end(); ++iter) - { - LLMaterialInfo *infop = *iter; - if (mcode == infop->mMCode) - { - infop->mFriction = friction; - return TRUE; - } - } + for (info_list_t::iterator iter = mMaterialInfoList.begin(); + iter != mMaterialInfoList.end(); ++iter) + { + LLMaterialInfo *infop = *iter; + if (mcode == infop->mMCode) + { + infop->mFriction = friction; + return TRUE; + } + } - return FALSE; + return FALSE; } BOOL LLMaterialTable::addDamageAndEnergy(U8 mcode, const F32 &hp_mod, const F32 &damage_mod, const F32 &ep_mod) { - for (info_list_t::iterator iter = mMaterialInfoList.begin(); - iter != mMaterialInfoList.end(); ++iter) - { - LLMaterialInfo *infop = *iter; - if (mcode == infop->mMCode) - { - infop->mHPModifier = hp_mod; - infop->mDamageModifier = damage_mod; - infop->mEPModifier = ep_mod; - return TRUE; - } - } - - return FALSE; + for (info_list_t::iterator iter = mMaterialInfoList.begin(); + iter != mMaterialInfoList.end(); ++iter) + { + LLMaterialInfo *infop = *iter; + if (mcode == infop->mMCode) + { + infop->mHPModifier = hp_mod; + infop->mDamageModifier = damage_mod; + infop->mEPModifier = ep_mod; + return TRUE; + } + } + + return FALSE; } LLUUID LLMaterialTable::getDefaultTextureID(const std::string& name) { - for (info_list_t::iterator iter = mMaterialInfoList.begin(); - iter != mMaterialInfoList.end(); ++iter) - { - LLMaterialInfo *infop = *iter; - if (name == infop->mName) - { - return infop->mDefaultTextureID; - } - } + for (info_list_t::iterator iter = mMaterialInfoList.begin(); + iter != mMaterialInfoList.end(); ++iter) + { + LLMaterialInfo *infop = *iter; + if (name == infop->mName) + { + return infop->mDefaultTextureID; + } + } - return LLUUID::null; + return LLUUID::null; } LLUUID LLMaterialTable::getDefaultTextureID(U8 mcode) { - mcode &= LL_MCODE_MASK; - for (info_list_t::iterator iter = mMaterialInfoList.begin(); - iter != mMaterialInfoList.end(); ++iter) - { - LLMaterialInfo *infop = *iter; - if (mcode == infop->mMCode) - { - return infop->mDefaultTextureID; - } - } + mcode &= LL_MCODE_MASK; + for (info_list_t::iterator iter = mMaterialInfoList.begin(); + iter != mMaterialInfoList.end(); ++iter) + { + LLMaterialInfo *infop = *iter; + if (mcode == infop->mMCode) + { + return infop->mDefaultTextureID; + } + } - return LLUUID::null; + return LLUUID::null; } U8 LLMaterialTable::getMCode(const std::string& name) { - for (info_list_t::iterator iter = mMaterialInfoList.begin(); - iter != mMaterialInfoList.end(); ++iter) - { - LLMaterialInfo *infop = *iter; - if (name == infop->mName) - { - return infop->mMCode; - } - } + for (info_list_t::iterator iter = mMaterialInfoList.begin(); + iter != mMaterialInfoList.end(); ++iter) + { + LLMaterialInfo *infop = *iter; + if (name == infop->mName) + { + return infop->mMCode; + } + } - return 0; + return 0; } std::string LLMaterialTable::getName(U8 mcode) { - mcode &= LL_MCODE_MASK; - for (info_list_t::iterator iter = mMaterialInfoList.begin(); - iter != mMaterialInfoList.end(); ++iter) - { - LLMaterialInfo *infop = *iter; - if (mcode == infop->mMCode) - { - return infop->mName; - } - } + mcode &= LL_MCODE_MASK; + for (info_list_t::iterator iter = mMaterialInfoList.begin(); + iter != mMaterialInfoList.end(); ++iter) + { + LLMaterialInfo *infop = *iter; + if (mcode == infop->mMCode) + { + return infop->mName; + } + } - return std::string(); + return std::string(); } LLUUID LLMaterialTable::getCollisionSoundUUID(U8 mcode, U8 mcode2) { - mcode &= LL_MCODE_MASK; - mcode2 &= LL_MCODE_MASK; - - //LL_INFOS() << "code 1: " << ((U32) mcode) << " code 2:" << ((U32) mcode2) << LL_ENDL; - if (mCollisionSoundMatrix && (mcode < LL_MCODE_END) && (mcode2 < LL_MCODE_END)) - { - return(mCollisionSoundMatrix[mcode * LL_MCODE_END + mcode2]); - } - else - { - //LL_INFOS() << "Null Sound" << LL_ENDL; - return(SND_NULL); - } + mcode &= LL_MCODE_MASK; + mcode2 &= LL_MCODE_MASK; + + //LL_INFOS() << "code 1: " << ((U32) mcode) << " code 2:" << ((U32) mcode2) << LL_ENDL; + if (mCollisionSoundMatrix && (mcode < LL_MCODE_END) && (mcode2 < LL_MCODE_END)) + { + return(mCollisionSoundMatrix[mcode * LL_MCODE_END + mcode2]); + } + else + { + //LL_INFOS() << "Null Sound" << LL_ENDL; + return(SND_NULL); + } } bool LLMaterialTable::isCollisionSound(const LLUUID &uuid) { - for (U8 i = 0; i < LL_MCODE_END; i++) - { - for (U8 j = 0; j < LL_MCODE_END; j++) - { - i &= LL_MCODE_MASK; - j &= LL_MCODE_MASK; - if (mCollisionSoundMatrix[i * LL_MCODE_END + j] == uuid) - { - return true; - } - } - } - return false; + for (U8 i = 0; i < LL_MCODE_END; i++) + { + for (U8 j = 0; j < LL_MCODE_END; j++) + { + i &= LL_MCODE_MASK; + j &= LL_MCODE_MASK; + if (mCollisionSoundMatrix[i * LL_MCODE_END + j] == uuid) + { + return true; + } + } + } + return false; } LLUUID LLMaterialTable::getSlidingSoundUUID(U8 mcode, U8 mcode2) -{ - mcode &= LL_MCODE_MASK; - mcode2 &= LL_MCODE_MASK; - - if (mSlidingSoundMatrix && (mcode < LL_MCODE_END) && (mcode2 < LL_MCODE_END)) - { - return(mSlidingSoundMatrix[mcode * LL_MCODE_END + mcode2]); - } - else - { - return(SND_NULL); - } +{ + mcode &= LL_MCODE_MASK; + mcode2 &= LL_MCODE_MASK; + + if (mSlidingSoundMatrix && (mcode < LL_MCODE_END) && (mcode2 < LL_MCODE_END)) + { + return(mSlidingSoundMatrix[mcode * LL_MCODE_END + mcode2]); + } + else + { + return(SND_NULL); + } } LLUUID LLMaterialTable::getRollingSoundUUID(U8 mcode, U8 mcode2) -{ - mcode &= LL_MCODE_MASK; - mcode2 &= LL_MCODE_MASK; - - if (mRollingSoundMatrix && (mcode < LL_MCODE_END) && (mcode2 < LL_MCODE_END)) - { - return(mRollingSoundMatrix[mcode * LL_MCODE_END + mcode2]); - } - else - { - return(SND_NULL); - } +{ + mcode &= LL_MCODE_MASK; + mcode2 &= LL_MCODE_MASK; + + if (mRollingSoundMatrix && (mcode < LL_MCODE_END) && (mcode2 < LL_MCODE_END)) + { + return(mRollingSoundMatrix[mcode * LL_MCODE_END + mcode2]); + } + else + { + return(SND_NULL); + } } LLUUID LLMaterialTable::getGroundCollisionSoundUUID(U8 mcode) -{ - // Create material appropriate sounds for collisions with the ground - // For now, simply return a single sound for all materials - return SND_STONE_DIRT_02; +{ + // Create material appropriate sounds for collisions with the ground + // For now, simply return a single sound for all materials + return SND_STONE_DIRT_02; } LLUUID LLMaterialTable::getGroundSlidingSoundUUID(U8 mcode) -{ - // Create material-specific sound for sliding on ground - // For now, just return a single sound - return SND_SLIDE_STONE_STONE_01; +{ + // Create material-specific sound for sliding on ground + // For now, just return a single sound + return SND_SLIDE_STONE_STONE_01; } LLUUID LLMaterialTable::getGroundRollingSoundUUID(U8 mcode) -{ - // Create material-specific sound for rolling on ground - // For now, just return a single sound - return SND_SLIDE_STONE_STONE_01; +{ + // Create material-specific sound for rolling on ground + // For now, just return a single sound + return SND_SLIDE_STONE_STONE_01; } LLUUID LLMaterialTable::getCollisionParticleUUID(U8 mcode, U8 mcode2) -{ - // Returns an appropriate UUID to use as sprite at collision betweeen objects - // For now, just return a single image - return IMG_SHOT; +{ + // Returns an appropriate UUID to use as sprite at collision betweeen objects + // For now, just return a single image + return IMG_SHOT; } LLUUID LLMaterialTable::getGroundCollisionParticleUUID(U8 mcode) -{ - // Returns an appropriate - // For now, just return a single sound - return IMG_SMOKE_POOF; +{ + // Returns an appropriate + // For now, just return a single sound + return IMG_SMOKE_POOF; } F32 LLMaterialTable::getDensity(U8 mcode) -{ - mcode &= LL_MCODE_MASK; - for (info_list_t::iterator iter = mMaterialInfoList.begin(); - iter != mMaterialInfoList.end(); ++iter) - { - LLMaterialInfo *infop = *iter; - if (mcode == infop->mMCode) - { - return infop->mDensity; - } - } +{ + mcode &= LL_MCODE_MASK; + for (info_list_t::iterator iter = mMaterialInfoList.begin(); + iter != mMaterialInfoList.end(); ++iter) + { + LLMaterialInfo *infop = *iter; + if (mcode == infop->mMCode) + { + return infop->mDensity; + } + } - return 0.f; + return 0.f; } F32 LLMaterialTable::getRestitution(U8 mcode) -{ - mcode &= LL_MCODE_MASK; - for (info_list_t::iterator iter = mMaterialInfoList.begin(); - iter != mMaterialInfoList.end(); ++iter) - { - LLMaterialInfo *infop = *iter; - if (mcode == infop->mMCode) - { - return infop->mRestitution; - } - } +{ + mcode &= LL_MCODE_MASK; + for (info_list_t::iterator iter = mMaterialInfoList.begin(); + iter != mMaterialInfoList.end(); ++iter) + { + LLMaterialInfo *infop = *iter; + if (mcode == infop->mMCode) + { + return infop->mRestitution; + } + } - return LLMaterialTable::DEFAULT_RESTITUTION; + return LLMaterialTable::DEFAULT_RESTITUTION; } F32 LLMaterialTable::getFriction(U8 mcode) -{ - mcode &= LL_MCODE_MASK; - for (info_list_t::iterator iter = mMaterialInfoList.begin(); - iter != mMaterialInfoList.end(); ++iter) - { - LLMaterialInfo *infop = *iter; - if (mcode == infop->mMCode) - { - return infop->mFriction; - } - } +{ + mcode &= LL_MCODE_MASK; + for (info_list_t::iterator iter = mMaterialInfoList.begin(); + iter != mMaterialInfoList.end(); ++iter) + { + LLMaterialInfo *infop = *iter; + if (mcode == infop->mMCode) + { + return infop->mFriction; + } + } - return LLMaterialTable::DEFAULT_FRICTION; + return LLMaterialTable::DEFAULT_FRICTION; } F32 LLMaterialTable::getHPMod(U8 mcode) -{ - mcode &= LL_MCODE_MASK; - for (info_list_t::iterator iter = mMaterialInfoList.begin(); - iter != mMaterialInfoList.end(); ++iter) - { - LLMaterialInfo *infop = *iter; - if (mcode == infop->mMCode) - { - return infop->mHPModifier; - } - } +{ + mcode &= LL_MCODE_MASK; + for (info_list_t::iterator iter = mMaterialInfoList.begin(); + iter != mMaterialInfoList.end(); ++iter) + { + LLMaterialInfo *infop = *iter; + if (mcode == infop->mMCode) + { + return infop->mHPModifier; + } + } - return 1.f; + return 1.f; } F32 LLMaterialTable::getDamageMod(U8 mcode) -{ - mcode &= LL_MCODE_MASK; - for (info_list_t::iterator iter = mMaterialInfoList.begin(); - iter != mMaterialInfoList.end(); ++iter) - { - LLMaterialInfo *infop = *iter; - if (mcode == infop->mMCode) - { - return infop->mDamageModifier; - } - } +{ + mcode &= LL_MCODE_MASK; + for (info_list_t::iterator iter = mMaterialInfoList.begin(); + iter != mMaterialInfoList.end(); ++iter) + { + LLMaterialInfo *infop = *iter; + if (mcode == infop->mMCode) + { + return infop->mDamageModifier; + } + } - return 1.f; + return 1.f; } F32 LLMaterialTable::getEPMod(U8 mcode) -{ - mcode &= LL_MCODE_MASK; - for (info_list_t::iterator iter = mMaterialInfoList.begin(); - iter != mMaterialInfoList.end(); ++iter) - { - LLMaterialInfo *infop = *iter; - if (mcode == infop->mMCode) - { - return infop->mEPModifier; - } - } +{ + mcode &= LL_MCODE_MASK; + for (info_list_t::iterator iter = mMaterialInfoList.begin(); + iter != mMaterialInfoList.end(); ++iter) + { + LLMaterialInfo *infop = *iter; + if (mcode == infop->mMCode) + { + return infop->mEPModifier; + } + } - return 1.f; + return 1.f; } LLUUID LLMaterialTable::getShatterSoundUUID(U8 mcode) -{ - mcode &= LL_MCODE_MASK; - for (info_list_t::iterator iter = mMaterialInfoList.begin(); - iter != mMaterialInfoList.end(); ++iter) - { - LLMaterialInfo *infop = *iter; - if (mcode == infop->mMCode) - { - return infop->mShatterSoundID; - } - } - - return SND_NULL; +{ + mcode &= LL_MCODE_MASK; + for (info_list_t::iterator iter = mMaterialInfoList.begin(); + iter != mMaterialInfoList.end(); ++iter) + { + LLMaterialInfo *infop = *iter; + if (mcode == infop->mMCode) + { + return infop->mShatterSoundID; + } + } + + return SND_NULL; } diff --git a/indra/llprimitive/llmaterialtable.h b/indra/llprimitive/llmaterialtable.h index 0cf5e626ef..d612361041 100644 --- a/indra/llprimitive/llmaterialtable.h +++ b/indra/llprimitive/llmaterialtable.h @@ -1,25 +1,25 @@ -/** +/** * @file llmaterialtable.h * @brief Table of material information for the viewer UI * * $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$ */ @@ -39,7 +39,7 @@ const U32 LLMATERIAL_INFO_NAME_LENGTH = 256; // We've moved toward more reasonable mass values for the Havok4 engine. // The LEGACY_DEFAULT_OBJECT_DENSITY is used to maintain support for // legacy scripts code (llGetMass()) and script energy consumption. -const F32 DEFAULT_OBJECT_DENSITY = 1000.0f; // per m^3 +const F32 DEFAULT_OBJECT_DENSITY = 1000.0f; // per m^3 const F32 LEGACY_DEFAULT_OBJECT_DENSITY = 10.0f; // Avatars density depends on the collision shape used. The approximate @@ -50,139 +50,139 @@ const F32 LEGACY_DEFAULT_OBJECT_DENSITY = 10.0f; // max | max | max | max | 0.208 | // // Either the avatar shape must be tweaked to match those volumes -// or the DEFAULT_AVATAR_DENSITY must be adjusted to achieve the +// or the DEFAULT_AVATAR_DENSITY must be adjusted to achieve the // legacy mass. // // The current density appears to be low because the mass and // inertia are computed as if the avatar were a cylinder which // has more volume than the actual collision shape of the avatar. // See the physics engine mass properties code for more info. -const F32 DEFAULT_AVATAR_DENSITY = 445.3f; // was 444.24f; +const F32 DEFAULT_AVATAR_DENSITY = 445.3f; // was 444.24f; class LLMaterialTable { public: - static const F32 FRICTION_MIN; - static const F32 FRICTION_GLASS; - static const F32 FRICTION_LIGHT; - static const F32 FRICTION_METAL; - static const F32 FRICTION_PLASTIC; - static const F32 FRICTION_WOOD; - static const F32 FRICTION_LAND; - static const F32 FRICTION_STONE; - static const F32 FRICTION_FLESH; - static const F32 FRICTION_RUBBER; - static const F32 FRICTION_MAX; - - static const F32 RESTITUTION_MIN; - static const F32 RESTITUTION_LAND; - static const F32 RESTITUTION_FLESH; - static const F32 RESTITUTION_STONE; - static const F32 RESTITUTION_METAL; - static const F32 RESTITUTION_WOOD; - static const F32 RESTITUTION_GLASS; - static const F32 RESTITUTION_PLASTIC; - static const F32 RESTITUTION_LIGHT; - static const F32 RESTITUTION_RUBBER; - static const F32 RESTITUTION_MAX; - - typedef std::list<LLMaterialInfo*> info_list_t; - info_list_t mMaterialInfoList; - - LLUUID *mCollisionSoundMatrix; - LLUUID *mSlidingSoundMatrix; - LLUUID *mRollingSoundMatrix; - - static const F32 DEFAULT_FRICTION; - static const F32 DEFAULT_RESTITUTION; + static const F32 FRICTION_MIN; + static const F32 FRICTION_GLASS; + static const F32 FRICTION_LIGHT; + static const F32 FRICTION_METAL; + static const F32 FRICTION_PLASTIC; + static const F32 FRICTION_WOOD; + static const F32 FRICTION_LAND; + static const F32 FRICTION_STONE; + static const F32 FRICTION_FLESH; + static const F32 FRICTION_RUBBER; + static const F32 FRICTION_MAX; + + static const F32 RESTITUTION_MIN; + static const F32 RESTITUTION_LAND; + static const F32 RESTITUTION_FLESH; + static const F32 RESTITUTION_STONE; + static const F32 RESTITUTION_METAL; + static const F32 RESTITUTION_WOOD; + static const F32 RESTITUTION_GLASS; + static const F32 RESTITUTION_PLASTIC; + static const F32 RESTITUTION_LIGHT; + static const F32 RESTITUTION_RUBBER; + static const F32 RESTITUTION_MAX; + + typedef std::list<LLMaterialInfo*> info_list_t; + info_list_t mMaterialInfoList; + + LLUUID *mCollisionSoundMatrix; + LLUUID *mSlidingSoundMatrix; + LLUUID *mRollingSoundMatrix; + + static const F32 DEFAULT_FRICTION; + static const F32 DEFAULT_RESTITUTION; public: - LLMaterialTable(); - LLMaterialTable(U8); // cheat with an overloaded constructor to build our basic table - ~LLMaterialTable(); - - void initBasicTable(); - - void initTableTransNames(std::map<std::string, std::string> namemap); - - BOOL add(U8 mcode, const std::string& name, const LLUUID &uuid); - BOOL addCollisionSound(U8 mcode, U8 mcode2, const LLUUID &uuid); - BOOL addSlidingSound(U8 mcode, U8 mcode2, const LLUUID &uuid); - BOOL addRollingSound(U8 mcode, U8 mcode2, const LLUUID &uuid); - BOOL addShatterSound(U8 mcode, const LLUUID &uuid); - BOOL addDensity(U8 mcode, const F32 &density); - BOOL addFriction(U8 mcode, const F32 &friction); - BOOL addRestitution(U8 mcode, const F32 &restitution); - BOOL addDamageAndEnergy(U8 mcode, const F32 &hp_mod, const F32 &damage_mod, const F32 &ep_mod); - - LLUUID getDefaultTextureID(const std::string& name); // LLUUID::null if not found - LLUUID getDefaultTextureID(U8 mcode); // LLUUID::null if not found - U8 getMCode(const std::string& name); // 0 if not found - std::string getName(U8 mcode); - - F32 getDensity(U8 mcode); // kg/m^3, 0 if not found - F32 getFriction(U8 mcode); // physics values - F32 getRestitution(U8 mcode); // physics values - F32 getHPMod(U8 mcode); - F32 getDamageMod(U8 mcode); - F32 getEPMod(U8 mcode); - - bool isCollisionSound(const LLUUID &uuid); - - LLUUID getCollisionSoundUUID(U8 mcode, U8 mcode2); - LLUUID getSlidingSoundUUID(U8 mcode, U8 mcode2); - LLUUID getRollingSoundUUID(U8 mcode, U8 mcode2); - LLUUID getShatterSoundUUID(U8 mcode); // LLUUID::null if not found - - LLUUID getGroundCollisionSoundUUID(U8 mcode); - LLUUID getGroundSlidingSoundUUID(U8 mcode); - LLUUID getGroundRollingSoundUUID(U8 mcode); - LLUUID getCollisionParticleUUID(U8 mcode, U8 mcode2); - LLUUID getGroundCollisionParticleUUID(U8 mcode); - - static LLMaterialTable basic; + LLMaterialTable(); + LLMaterialTable(U8); // cheat with an overloaded constructor to build our basic table + ~LLMaterialTable(); + + void initBasicTable(); + + void initTableTransNames(std::map<std::string, std::string> namemap); + + BOOL add(U8 mcode, const std::string& name, const LLUUID &uuid); + BOOL addCollisionSound(U8 mcode, U8 mcode2, const LLUUID &uuid); + BOOL addSlidingSound(U8 mcode, U8 mcode2, const LLUUID &uuid); + BOOL addRollingSound(U8 mcode, U8 mcode2, const LLUUID &uuid); + BOOL addShatterSound(U8 mcode, const LLUUID &uuid); + BOOL addDensity(U8 mcode, const F32 &density); + BOOL addFriction(U8 mcode, const F32 &friction); + BOOL addRestitution(U8 mcode, const F32 &restitution); + BOOL addDamageAndEnergy(U8 mcode, const F32 &hp_mod, const F32 &damage_mod, const F32 &ep_mod); + + LLUUID getDefaultTextureID(const std::string& name); // LLUUID::null if not found + LLUUID getDefaultTextureID(U8 mcode); // LLUUID::null if not found + U8 getMCode(const std::string& name); // 0 if not found + std::string getName(U8 mcode); + + F32 getDensity(U8 mcode); // kg/m^3, 0 if not found + F32 getFriction(U8 mcode); // physics values + F32 getRestitution(U8 mcode); // physics values + F32 getHPMod(U8 mcode); + F32 getDamageMod(U8 mcode); + F32 getEPMod(U8 mcode); + + bool isCollisionSound(const LLUUID &uuid); + + LLUUID getCollisionSoundUUID(U8 mcode, U8 mcode2); + LLUUID getSlidingSoundUUID(U8 mcode, U8 mcode2); + LLUUID getRollingSoundUUID(U8 mcode, U8 mcode2); + LLUUID getShatterSoundUUID(U8 mcode); // LLUUID::null if not found + + LLUUID getGroundCollisionSoundUUID(U8 mcode); + LLUUID getGroundSlidingSoundUUID(U8 mcode); + LLUUID getGroundRollingSoundUUID(U8 mcode); + LLUUID getCollisionParticleUUID(U8 mcode, U8 mcode2); + LLUUID getGroundCollisionParticleUUID(U8 mcode); + + static LLMaterialTable basic; }; class LLMaterialInfo { public: - U8 mMCode; - std::string mName; - LLUUID mDefaultTextureID; - LLUUID mShatterSoundID; - F32 mDensity; // kg/m^3 - F32 mFriction; - F32 mRestitution; - - // damage and energy constants - F32 mHPModifier; // modifier on mass based HP total - F32 mDamageModifier; // modifier on KE based damage - F32 mEPModifier; // modifier on mass based EP total - - LLMaterialInfo(U8 mcode, const std::string& name, const LLUUID &uuid) - { - init(mcode,name,uuid); - }; - - void init(U8 mcode, const std::string& name, const LLUUID &uuid) - { - mDensity = 1000.f; // default to 1000.0 (water) - mFriction = LLMaterialTable::DEFAULT_FRICTION; - mRestitution = LLMaterialTable::DEFAULT_RESTITUTION; - mHPModifier = 1.f; - mDamageModifier = 1.f; - mEPModifier = 1.f; - - mMCode = mcode; - mName = name; - mDefaultTextureID = uuid; - }; - - ~LLMaterialInfo() - { - }; + U8 mMCode; + std::string mName; + LLUUID mDefaultTextureID; + LLUUID mShatterSoundID; + F32 mDensity; // kg/m^3 + F32 mFriction; + F32 mRestitution; + + // damage and energy constants + F32 mHPModifier; // modifier on mass based HP total + F32 mDamageModifier; // modifier on KE based damage + F32 mEPModifier; // modifier on mass based EP total + + LLMaterialInfo(U8 mcode, const std::string& name, const LLUUID &uuid) + { + init(mcode,name,uuid); + }; + + void init(U8 mcode, const std::string& name, const LLUUID &uuid) + { + mDensity = 1000.f; // default to 1000.0 (water) + mFriction = LLMaterialTable::DEFAULT_FRICTION; + mRestitution = LLMaterialTable::DEFAULT_RESTITUTION; + mHPModifier = 1.f; + mDamageModifier = 1.f; + mEPModifier = 1.f; + + mMCode = mcode; + mName = name; + mDefaultTextureID = uuid; + }; + + ~LLMaterialInfo() + { + }; }; diff --git a/indra/llprimitive/llmediaentry.cpp b/indra/llprimitive/llmediaentry.cpp index 53e9555c6a..e626a989f6 100644 --- a/indra/llprimitive/llmediaentry.cpp +++ b/indra/llprimitive/llmediaentry.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llmediaentry.cpp * @brief This is a single instance of media data related to the face of a prim * * $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$ */ @@ -157,9 +157,9 @@ void LLMediaEntry::asLLSD(LLSD& sd) const // "security" fields sd[WHITELIST_ENABLE_KEY] = mWhiteListEnable; - sd.erase(WHITELIST_KEY); - for (U32 i=0; i<mWhiteList.size(); i++) - { + sd.erase(WHITELIST_KEY); + for (U32 i=0; i<mWhiteList.size(); i++) + { sd[WHITELIST_KEY].append(mWhiteList[i]); } @@ -195,7 +195,7 @@ bool LLMediaEntry::fromLLSDInternal(const LLSD& sd, bool overwrite) // bit field. We "or" into status and instead of returning // it, we return whether it finishes off as LSL_STATUS_OK or not. U32 status = LSL_STATUS_OK; - + // "general" fields if ( overwrite || sd.has(ALT_IMAGE_ENABLE_KEY) ) { @@ -262,7 +262,7 @@ bool LLMediaEntry::fromLLSDInternal(const LLSD& sd, bool overwrite) { status |= setPermsControl( 0xff & (LLSD::Integer)sd[PERMS_CONTROL_KEY] ); } - + return LSL_STATUS_OK == status; } @@ -321,7 +321,7 @@ bool LLMediaEntry::operator==(const LLMediaEntry &rhs) const ); } - + bool LLMediaEntry::operator!=(const LLMediaEntry &rhs) const { return ( @@ -344,8 +344,8 @@ bool LLMediaEntry::operator!=(const LLMediaEntry &rhs) const // "permissions" fields mPermsInteract != rhs.mPermsInteract || - mPermsControl != rhs.mPermsControl - + mPermsControl != rhs.mPermsControl + ); } @@ -358,13 +358,13 @@ U32 LLMediaEntry::setWhiteList( const std::vector<std::string> &whitelist ) // First count to make sure the size constraint is not violated std::vector<std::string>::const_iterator iter = whitelist.begin(); std::vector<std::string>::const_iterator end = whitelist.end(); - for ( ; iter < end; ++iter) + for ( ; iter < end; ++iter) { const std::string &entry = (*iter); size += entry.length() + 1; // Include one for \0 count ++; - if (size > MAX_WHITELIST_SIZE || count > MAX_WHITELIST_COUNT) - { + if (size > MAX_WHITELIST_SIZE || count > MAX_WHITELIST_COUNT) + { return LSL_STATUS_BOUNDS_ERROR; } } @@ -383,14 +383,14 @@ U32 LLMediaEntry::setWhiteList( const std::vector<std::string> &whitelist ) U32 LLMediaEntry::setWhiteList( const LLSD &whitelist ) { // If whitelist is undef, the whitelist is cleared - if (whitelist.isUndefined()) - { - mWhiteList.clear(); - return LSL_STATUS_OK; - } + if (whitelist.isUndefined()) + { + mWhiteList.clear(); + return LSL_STATUS_OK; + } // However, if the whitelist is an empty array, erase it. - if (whitelist.isArray()) + if (whitelist.isArray()) { // *NOTE: This code is VERY similar to the setWhitelist above. // IF YOU CHANGE THIS IMPLEMENTATION, BE SURE TO CHANGE THE OTHER! @@ -399,13 +399,13 @@ U32 LLMediaEntry::setWhiteList( const LLSD &whitelist ) // First check to make sure the size and count constraints are not violated LLSD::array_const_iterator iter = whitelist.beginArray(); LLSD::array_const_iterator end = whitelist.endArray(); - for ( ; iter < end; ++iter) + for ( ; iter < end; ++iter) { const std::string &entry = (*iter).asString(); size += entry.length() + 1; // Include one for \0 count ++; - if (size > MAX_WHITELIST_SIZE || count > MAX_WHITELIST_COUNT) - { + if (size > MAX_WHITELIST_SIZE || count > MAX_WHITELIST_COUNT) + { return LSL_STATUS_BOUNDS_ERROR; } } @@ -420,8 +420,8 @@ U32 LLMediaEntry::setWhiteList( const LLSD &whitelist ) } return LSL_STATUS_OK; } - else - { + else + { return LSL_STATUS_MALFORMED_PARAMS; } } @@ -444,15 +444,15 @@ static bool pattern_match(const std::string &candidate_str, const std::string &p { // If the pattern is empty, it matches if (pattern.empty()) return true; - + // 'pattern' is a glob pattern, we only accept '*' chars // copy it std::string expression = pattern; - + // Escape perl's regexp chars with a backslash, except all "*" chars prefix_with(expression, ".[{()\\+?|^$", "\\"); prefix_with(expression, "*", "."); - + // case-insensitive matching: boost::regex regexp(expression, boost::regex::perl|boost::regex::icase); return ll_regex_match(candidate_str, regexp); @@ -460,26 +460,26 @@ static bool pattern_match(const std::string &candidate_str, const std::string &p bool LLMediaEntry::checkCandidateUrl(const std::string& url) const { - if (getWhiteListEnable()) + if (getWhiteListEnable()) { return checkUrlAgainstWhitelist(url, getWhiteList()); } - else - { + else + { return true; } } // static -bool LLMediaEntry::checkUrlAgainstWhitelist(const std::string& url, +bool LLMediaEntry::checkUrlAgainstWhitelist(const std::string& url, const std::vector<std::string> &whitelist) { bool passes = true; // *NOTE: no entries? Don't check - if (whitelist.size() > 0) + if (whitelist.size() > 0) { passes = false; - + // Case insensitive: the reason why we toUpper both this and the // filter std::string candidate_url = url; @@ -490,10 +490,10 @@ bool LLMediaEntry::checkUrlAgainstWhitelist(const std::string& url, for ( ; iter < end; ++iter ) { std::string filter = *iter; - + LLURI filter_uri(filter); bool scheme_passes = pattern_match( candidate_uri.scheme(), filter_uri.scheme() ); - if (filter_uri.scheme().empty()) + if (filter_uri.scheme().empty()) { filter_uri = LLURI(DEFAULT_URL_PREFIX + filter); } @@ -512,12 +512,12 @@ bool LLMediaEntry::checkUrlAgainstWhitelist(const std::string& url, U32 LLMediaEntry::setStringFieldWithLimit( std::string &field, const std::string &value, U32 limit ) { - if ( value.length() > limit ) - { + if ( value.length() > limit ) + { return LSL_STATUS_BOUNDS_ERROR; } - else - { + else + { field = value; return LSL_STATUS_OK; } @@ -553,12 +553,12 @@ U32 LLMediaEntry::setCurrentURL(const std::string& current_url) U32 LLMediaEntry::setCurrentURLInternal(const std::string& current_url, bool check_whitelist) { - if ( ! check_whitelist || checkCandidateUrl(current_url)) + if ( ! check_whitelist || checkCandidateUrl(current_url)) { return setStringFieldWithLimit( mCurrentURL, current_url, MAX_URL_LENGTH ); } - else - { + else + { return LSL_STATUS_WHITELIST_FAILED; } } @@ -572,14 +572,14 @@ U32 LLMediaEntry::setWidthPixels(U16 width) { if (width > MAX_WIDTH_PIXELS) return LSL_STATUS_BOUNDS_ERROR; mWidthPixels = width; - return LSL_STATUS_OK; + return LSL_STATUS_OK; } U32 LLMediaEntry::setHeightPixels(U16 height) { if (height > MAX_HEIGHT_PIXELS) return LSL_STATUS_BOUNDS_ERROR; mHeightPixels = height; - return LSL_STATUS_OK; + return LSL_STATUS_OK; } const LLUUID &LLMediaEntry::getMediaID() const diff --git a/indra/llprimitive/llmediaentry.h b/indra/llprimitive/llmediaentry.h index 33855b3fb2..cabf06648e 100644 --- a/indra/llprimitive/llmediaentry.h +++ b/indra/llprimitive/llmediaentry.h @@ -1,25 +1,25 @@ -/** +/** * @file llmediaentry.h * @brief This is a single instance of media data related to the face of a prim * * $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$ */ @@ -35,12 +35,12 @@ class LLMediaEntry { -public: +public: enum MediaControls { STANDARD = 0, MINI }; - + // Constructors LLMediaEntry(); LLMediaEntry(const LLMediaEntry &rhs); @@ -50,7 +50,7 @@ public: bool operator==(const LLMediaEntry &rhs) const; bool operator!=(const LLMediaEntry &rhs) const; - + // Render as LLSD LLSD asLLSD() const; void asLLSD(LLSD& sd) const; @@ -61,7 +61,7 @@ public: // This doesn't merge, it overwrites the data, so will use // LLSD defaults if need be. Note: does not check limits! // Use checkLLSD() above first to ensure the LLSD is valid. - void fromLLSD(const LLSD& sd); + void fromLLSD(const LLSD& sd); // This merges data from the incoming LLSD into our fields. // Note that it also does NOT check limits! Use checkLLSD() above first. void mergeFromLLSD(const LLSD& sd); @@ -89,7 +89,7 @@ public: // Setters. Those that return a U32 return a status error code // See lllslconstants.h - + // "general" fields U32 setAltImageEnable(bool alt_image_enable) { mAltImageEnable = alt_image_enable; return LSL_STATUS_OK; } U32 setControls(MediaControls controls); @@ -121,9 +121,9 @@ public: public: // Static function to check a URL against a whitelist // Returns true iff url passes the given whitelist - static bool checkUrlAgainstWhitelist(const std::string &url, + static bool checkUrlAgainstWhitelist(const std::string &url, const std::vector<std::string> &whitelist); - + public: // LLSD key defines // "general" fields @@ -214,7 +214,7 @@ private: // "permissions" fields U8 mPermsInteract; U8 mPermsControl; - + mutable LLUUID *mMediaIDp; // temporary id assigned to media on the viewer }; diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 7b0d2632aa..236cef9c3f 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llmodel.cpp * @brief Model handling implementation * * $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$ */ @@ -41,71 +41,71 @@ std::string model_names[] = { - "lowest_lod", - "low_lod", - "medium_lod", - "high_lod", - "physics_mesh" + "lowest_lod", + "low_lod", + "medium_lod", + "high_lod", + "physics_mesh" }; const int MODEL_NAMES_LENGTH = sizeof(model_names) / sizeof(std::string); LLModel::LLModel(LLVolumeParams& params, F32 detail) - : LLVolume(params, detail), + : LLVolume(params, detail), mNormalizedScale(1,1,1), mNormalizedTranslation(0, 0, 0), - mPelvisOffset( 0.0f ), - mStatus(NO_ERRORS), + mPelvisOffset( 0.0f ), + mStatus(NO_ERRORS), mSubmodelID(0) { - mDecompID = -1; - mLocalID = -1; + mDecompID = -1; + mLocalID = -1; } LLModel::~LLModel() { - if (mDecompID >= 0) - { - LLConvexDecomposition::getInstance()->deleteDecomposition(mDecompID); - } + if (mDecompID >= 0) + { + LLConvexDecomposition::getInstance()->deleteDecomposition(mDecompID); + } mPhysics.mMesh.clear(); } //static std::string LLModel::getStatusString(U32 status) { - const static std::string status_strings[(S32)INVALID_STATUS] = {"status_no_error", "status_vertex_number_overflow","bad_element"}; + const static std::string status_strings[(S32)INVALID_STATUS] = {"status_no_error", "status_vertex_number_overflow","bad_element"}; - if(status < INVALID_STATUS) - { - if(status_strings[status] == std::string()) - { - //LL_ERRS() << "No valid status string for this status: " << (U32)status << LL_ENDL(); - } - return status_strings[status] ; - } + if(status < INVALID_STATUS) + { + if(status_strings[status] == std::string()) + { + //LL_ERRS() << "No valid status string for this status: " << (U32)status << LL_ENDL(); + } + return status_strings[status] ; + } - //LL_ERRS() << "Invalid model status: " << (U32)status << LL_ENDL(); + //LL_ERRS() << "Invalid model status: " << (U32)status << LL_ENDL(); - return std::string() ; + return std::string() ; } void LLModel::offsetMesh( const LLVector3& pivotPoint ) { - LLVector4a pivot( pivotPoint[VX], pivotPoint[VY], pivotPoint[VZ] ); - - for (std::vector<LLVolumeFace>::iterator faceIt = mVolumeFaces.begin(); faceIt != mVolumeFaces.end(); ) - { - std::vector<LLVolumeFace>:: iterator currentFaceIt = faceIt++; - LLVolumeFace& face = *currentFaceIt; - LLVector4a *pos = (LLVector4a*) face.mPositions; - - for (U32 i=0; i<face.mNumVertices; ++i ) - { - pos[i].add( pivot ); - } - } + LLVector4a pivot( pivotPoint[VX], pivotPoint[VY], pivotPoint[VZ] ); + + for (std::vector<LLVolumeFace>::iterator faceIt = mVolumeFaces.begin(); faceIt != mVolumeFaces.end(); ) + { + std::vector<LLVolumeFace>:: iterator currentFaceIt = faceIt++; + LLVolumeFace& face = *currentFaceIt; + LLVector4a *pos = (LLVector4a*) face.mPositions; + + for (U32 i=0; i<face.mNumVertices; ++i ) + { + pos[i].add( pivot ); + } + } } void LLModel::remapVolumeFaces() @@ -118,74 +118,74 @@ void LLModel::remapVolumeFaces() void LLModel::optimizeVolumeFaces() { - for (U32 i = 0; i < getNumVolumeFaces(); ++i) - { - mVolumeFaces[i].optimize(); - } + for (U32 i = 0; i < getNumVolumeFaces(); ++i) + { + mVolumeFaces[i].optimize(); + } } struct MaterialBinding { - int index; - std::string matName; + int index; + std::string matName; }; struct MaterialSort { - bool operator()(const MaterialBinding& lhs, const MaterialBinding& rhs) - { - return LLStringUtil::compareInsensitive(lhs.matName, rhs.matName) < 0; - } + bool operator()(const MaterialBinding& lhs, const MaterialBinding& rhs) + { + return LLStringUtil::compareInsensitive(lhs.matName, rhs.matName) < 0; + } }; void LLModel::sortVolumeFacesByMaterialName() { - std::vector<MaterialBinding> bindings; - bindings.resize(mVolumeFaces.size()); - - for (int i = 0; i < bindings.size(); i++) - { - bindings[i].index = i; - if(i < mMaterialList.size()) - { - bindings[i].matName = mMaterialList[i]; - } - } - std::sort(bindings.begin(), bindings.end(), MaterialSort()); - std::vector< LLVolumeFace > new_faces; - - // remap the faces to be in the same order the mats now are... - // - new_faces.resize(bindings.size()); - for (int i = 0; i < bindings.size(); i++) - { - new_faces[i] = mVolumeFaces[bindings[i].index]; - if(i < mMaterialList.size()) - { - mMaterialList[i] = bindings[i].matName; - } - } - - mVolumeFaces = new_faces; + std::vector<MaterialBinding> bindings; + bindings.resize(mVolumeFaces.size()); + + for (int i = 0; i < bindings.size(); i++) + { + bindings[i].index = i; + if(i < mMaterialList.size()) + { + bindings[i].matName = mMaterialList[i]; + } + } + std::sort(bindings.begin(), bindings.end(), MaterialSort()); + std::vector< LLVolumeFace > new_faces; + + // remap the faces to be in the same order the mats now are... + // + new_faces.resize(bindings.size()); + for (int i = 0; i < bindings.size(); i++) + { + new_faces[i] = mVolumeFaces[bindings[i].index]; + if(i < mMaterialList.size()) + { + mMaterialList[i] = bindings[i].matName; + } + } + + mVolumeFaces = new_faces; } void LLModel::trimVolumeFacesToSize(U32 new_count, LLVolume::face_list_t* remainder) { - llassert(new_count <= LL_SCULPT_MESH_MAX_FACES); - - if (new_count && (getNumVolumeFaces() > new_count)) - { - // Copy out remaining volume faces for alternative handling, if provided - // - if (remainder) - { - (*remainder).assign(mVolumeFaces.begin() + new_count, mVolumeFaces.end()); - } - - // Trim down to the final set of volume faces (now stuffed to the gills!) - // - mVolumeFaces.resize(new_count); - } + llassert(new_count <= LL_SCULPT_MESH_MAX_FACES); + + if (new_count && (getNumVolumeFaces() > new_count)) + { + // Copy out remaining volume faces for alternative handling, if provided + // + if (remainder) + { + (*remainder).assign(mVolumeFaces.begin() + new_count, mVolumeFaces.end()); + } + + // Trim down to the final set of volume faces (now stuffed to the gills!) + // + mVolumeFaces.resize(new_count); + } } // Shrink the model to fit @@ -198,116 +198,116 @@ void LLModel::trimVolumeFacesToSize(U32 new_count, LLVolume::face_list_t* remain // within the unit cube. void LLModel::normalizeVolumeFaces() { - if (!mVolumeFaces.empty()) - { - LLVector4a min, max; - - // For all of the volume faces - // in the model, loop over - // them and see what the extents - // of the volume along each axis. - min = mVolumeFaces[0].mExtents[0]; - max = mVolumeFaces[0].mExtents[1]; - - for (U32 i = 1; i < mVolumeFaces.size(); ++i) - { - LLVolumeFace& face = mVolumeFaces[i]; - - 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 - // we can compute the offset needed to center - // the model at the origin. - - // Compute center of the model - // and make it negative to get translation - // needed to center at origin. - LLVector4a trans; - trans.setAdd(min, max); - trans.mul(-0.5f); - - // Compute the total size along all - // axes of the model. - LLVector4a size; - size.setSub(max, min); - - // Prevent division by zero. - F32 x = size[0]; - F32 y = size[1]; - F32 z = size[2]; - F32 w = size[3]; - if (fabs(x)<F_APPROXIMATELY_ZERO) - { - x = 1.0; - } - if (fabs(y)<F_APPROXIMATELY_ZERO) - { - y = 1.0; - } - if (fabs(z)<F_APPROXIMATELY_ZERO) - { - z = 1.0; - } - size.set(x,y,z,w); - - // Compute scale as reciprocal of size - LLVector4a scale; - scale.splat(1.f); - scale.div(size); - - LLVector4a inv_scale(1.f); - inv_scale.div(scale); - - for (U32 i = 0; i < mVolumeFaces.size(); ++i) - { - LLVolumeFace& face = mVolumeFaces[i]; - - // We shrink the extents so - // that they fall within - // the unit cube. - // VFExtents change - face.mExtents[0].add(trans); - face.mExtents[0].mul(scale); - - face.mExtents[1].add(trans); - face.mExtents[1].mul(scale); - - // For all the positions, we scale - // the positions to fit within the unit cube. - LLVector4a* pos = (LLVector4a*) face.mPositions; - LLVector4a* norm = (LLVector4a*) face.mNormals; + if (!mVolumeFaces.empty()) + { + LLVector4a min, max; + + // For all of the volume faces + // in the model, loop over + // them and see what the extents + // of the volume along each axis. + min = mVolumeFaces[0].mExtents[0]; + max = mVolumeFaces[0].mExtents[1]; + + for (U32 i = 1; i < mVolumeFaces.size(); ++i) + { + LLVolumeFace& face = mVolumeFaces[i]; + + 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 + // we can compute the offset needed to center + // the model at the origin. + + // Compute center of the model + // and make it negative to get translation + // needed to center at origin. + LLVector4a trans; + trans.setAdd(min, max); + trans.mul(-0.5f); + + // Compute the total size along all + // axes of the model. + LLVector4a size; + size.setSub(max, min); + + // Prevent division by zero. + F32 x = size[0]; + F32 y = size[1]; + F32 z = size[2]; + F32 w = size[3]; + if (fabs(x)<F_APPROXIMATELY_ZERO) + { + x = 1.0; + } + if (fabs(y)<F_APPROXIMATELY_ZERO) + { + y = 1.0; + } + if (fabs(z)<F_APPROXIMATELY_ZERO) + { + z = 1.0; + } + size.set(x,y,z,w); + + // Compute scale as reciprocal of size + LLVector4a scale; + scale.splat(1.f); + scale.div(size); + + LLVector4a inv_scale(1.f); + inv_scale.div(scale); + + for (U32 i = 0; i < mVolumeFaces.size(); ++i) + { + LLVolumeFace& face = mVolumeFaces[i]; + + // We shrink the extents so + // that they fall within + // the unit cube. + // VFExtents change + face.mExtents[0].add(trans); + face.mExtents[0].mul(scale); + + face.mExtents[1].add(trans); + face.mExtents[1].mul(scale); + + // For all the positions, we scale + // the positions to fit within the unit cube. + LLVector4a* pos = (LLVector4a*) face.mPositions; + LLVector4a* norm = (LLVector4a*) face.mNormals; LLVector4a* t = (LLVector4a*)face.mTangents; - for (U32 j = 0; j < face.mNumVertices; ++j) - { - pos[j].add(trans); - pos[j].mul(scale); - if (norm && !norm[j].equals3(LLVector4a::getZero())) - { - norm[j].mul(inv_scale); - norm[j].normalize3(); - } + for (U32 j = 0; j < face.mNumVertices; ++j) + { + pos[j].add(trans); + pos[j].mul(scale); + if (norm && !norm[j].equals3(LLVector4a::getZero())) + { + norm[j].mul(inv_scale); + norm[j].normalize3(); + } if (t) { @@ -316,336 +316,336 @@ void LLModel::normalizeVolumeFaces() t[j].normalize3(); t[j].getF32ptr()[3] = w; } - } - } - - // mNormalizedScale is the scale at which - // we would need to multiply the model - // by to get the original size of the - // model instead of the normalized size. - LLVector4a normalized_scale; - normalized_scale.splat(1.f); - normalized_scale.div(scale); - mNormalizedScale.set(normalized_scale.getF32ptr()); - mNormalizedTranslation.set(trans.getF32ptr()); - mNormalizedTranslation *= -1.f; + } + } + + // mNormalizedScale is the scale at which + // we would need to multiply the model + // by to get the original size of the + // model instead of the normalized size. + LLVector4a normalized_scale; + normalized_scale.splat(1.f); + normalized_scale.div(scale); + mNormalizedScale.set(normalized_scale.getF32ptr()); + mNormalizedTranslation.set(trans.getF32ptr()); + mNormalizedTranslation *= -1.f; // remember normalized scale so original dimensions can be recovered for mesh processing (i.e. tangent generation) for (auto& face : mVolumeFaces) { face.mNormalizedScale = mNormalizedScale; } - } + } } void LLModel::getNormalizedScaleTranslation(LLVector3& scale_out, LLVector3& translation_out) { - scale_out = mNormalizedScale; - translation_out = mNormalizedTranslation; + scale_out = mNormalizedScale; + translation_out = mNormalizedTranslation; } LLVector3 LLModel::getTransformedCenter(const LLMatrix4& mat) { - LLVector3 ret; + LLVector3 ret; - if (!mVolumeFaces.empty()) - { - LLMatrix4a m; - m.loadu(mat); + if (!mVolumeFaces.empty()) + { + LLMatrix4a m; + m.loadu(mat); - LLVector4a minv,maxv; + LLVector4a minv,maxv; - LLVector4a t; - m.affineTransform(mVolumeFaces[0].mPositions[0], t); - minv = maxv = t; + LLVector4a t; + m.affineTransform(mVolumeFaces[0].mPositions[0], t); + minv = maxv = t; - for (S32 i = 0; i < mVolumeFaces.size(); ++i) - { - LLVolumeFace& face = mVolumeFaces[i]; + for (S32 i = 0; i < mVolumeFaces.size(); ++i) + { + LLVolumeFace& face = mVolumeFaces[i]; - for (U32 j = 0; j < face.mNumVertices; ++j) - { - m.affineTransform(face.mPositions[j],t); - update_min_max(minv, maxv, t); - } - } + for (U32 j = 0; j < face.mNumVertices; ++j) + { + m.affineTransform(face.mPositions[j],t); + update_min_max(minv, maxv, t); + } + } - minv.add(maxv); - minv.mul(0.5f); + minv.add(maxv); + minv.mul(0.5f); - ret.set(minv.getF32ptr()); - } + ret.set(minv.getF32ptr()); + } - return ret; + return ret; } void LLModel::setNumVolumeFaces(S32 count) { - mVolumeFaces.resize(count); + mVolumeFaces.resize(count); } void LLModel::setVolumeFaceData( - S32 f, - LLStrider<LLVector3> pos, - LLStrider<LLVector3> norm, - LLStrider<LLVector2> tc, - LLStrider<U16> ind, - U32 num_verts, - U32 num_indices) + S32 f, + LLStrider<LLVector3> pos, + LLStrider<LLVector3> norm, + LLStrider<LLVector2> tc, + LLStrider<U16> ind, + U32 num_verts, + U32 num_indices) { llassert(num_indices % 3 == 0); - LLVolumeFace& face = mVolumeFaces[f]; - - face.resizeVertices(num_verts); - face.resizeIndices(num_indices); - - LLVector4a::memcpyNonAliased16((F32*) face.mPositions, (F32*) pos.get(), num_verts*4*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()) - { - U32 tex_size = (num_verts*2*sizeof(F32)+0xF)&~0xF; - LLVector4a::memcpyNonAliased16((F32*) face.mTexCoords, (F32*) tc.get(), tex_size); - } - 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); + LLVolumeFace& face = mVolumeFaces[f]; + + face.resizeVertices(num_verts); + face.resizeIndices(num_indices); + + LLVector4a::memcpyNonAliased16((F32*) face.mPositions, (F32*) pos.get(), num_verts*4*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()) + { + U32 tex_size = (num_verts*2*sizeof(F32)+0xF)&~0xF; + LLVector4a::memcpyNonAliased16((F32*) face.mTexCoords, (F32*) tc.get(), tex_size); + } + 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); } void LLModel::addFace(const LLVolumeFace& face) { - if (face.mNumVertices == 0) - { - LL_ERRS() << "Cannot add empty face." << LL_ENDL; - } + if (face.mNumVertices == 0) + { + LL_ERRS() << "Cannot add empty face." << LL_ENDL; + } - mVolumeFaces.push_back(face); + mVolumeFaces.push_back(face); - if (mVolumeFaces.size() > MAX_MODEL_FACES) - { - LL_ERRS() << "Model prims cannot have more than " << MAX_MODEL_FACES << " faces!" << LL_ENDL; - } + if (mVolumeFaces.size() > MAX_MODEL_FACES) + { + LL_ERRS() << "Model prims cannot have more than " << MAX_MODEL_FACES << " faces!" << LL_ENDL; + } } void LLModel::generateNormals(F32 angle_cutoff) { - //generate normals for all faces by: - // 1 - Create faceted copy of face with no texture coordinates - // 2 - Weld vertices in faceted copy that are shared between triangles with less than "angle_cutoff" difference between normals - // 3 - Generate smoothed set of normals based on welding results - // 4 - Create faceted copy of face with texture coordinates - // 5 - Copy smoothed normals to faceted copy, using closest normal to triangle normal where more than one normal exists for a given position - // 6 - Remove redundant vertices from new faceted (now smooth) copy - - angle_cutoff = cosf(angle_cutoff); - for (U32 j = 0; j < mVolumeFaces.size(); ++j) - { - LLVolumeFace& vol_face = mVolumeFaces[j]; - - if (vol_face.mNumIndices > 65535) - { - LL_WARNS("MESHSKININFO") << "Too many vertices for normal generation to work." << LL_ENDL; - continue; - } - - //create faceted copy of current face with no texture coordinates (step 1) - LLVolumeFace faceted; - - LLVector4a* src_pos = (LLVector4a*) vol_face.mPositions; - //LLVector4a* src_norm = (LLVector4a*) vol_face.mNormals; - - - faceted.resizeVertices(vol_face.mNumIndices); - faceted.resizeIndices(vol_face.mNumIndices); - //bake out triangles into temporary face, clearing texture coordinates - for (U32 i = 0; i < vol_face.mNumIndices; ++i) - { - U32 idx = vol_face.mIndices[i]; - - faceted.mPositions[i] = src_pos[idx]; - faceted.mTexCoords[i] = LLVector2(0,0); - faceted.mIndices[i] = i; - } - - //generate normals for temporary face - for (U32 i = 0; i < faceted.mNumIndices; i += 3) - { //for each triangle - U16 i0 = faceted.mIndices[i+0]; - U16 i1 = faceted.mIndices[i+1]; - U16 i2 = faceted.mIndices[i+2]; - - LLVector4a& p0 = faceted.mPositions[i0]; - LLVector4a& p1 = faceted.mPositions[i1]; - LLVector4a& p2 = faceted.mPositions[i2]; - - LLVector4a& n0 = faceted.mNormals[i0]; - LLVector4a& n1 = faceted.mNormals[i1]; - LLVector4a& n2 = faceted.mNormals[i2]; - - LLVector4a lhs, rhs; - lhs.setSub(p1, p0); - rhs.setSub(p2, p0); - - n0.setCross3(lhs, rhs); - n0.normalize3(); - n1 = n0; - n2 = n0; - } - - //weld vertices in temporary face, respecting angle_cutoff (step 2) - faceted.optimize(angle_cutoff); - - //generate normals for welded face based on new topology (step 3) - - for (U32 i = 0; i < faceted.mNumVertices; i++) - { - faceted.mNormals[i].clear(); - } - - for (U32 i = 0; i < faceted.mNumIndices; i += 3) - { //for each triangle - U16 i0 = faceted.mIndices[i+0]; - U16 i1 = faceted.mIndices[i+1]; - U16 i2 = faceted.mIndices[i+2]; - - LLVector4a& p0 = faceted.mPositions[i0]; - LLVector4a& p1 = faceted.mPositions[i1]; - LLVector4a& p2 = faceted.mPositions[i2]; - - LLVector4a& n0 = faceted.mNormals[i0]; - LLVector4a& n1 = faceted.mNormals[i1]; - LLVector4a& n2 = faceted.mNormals[i2]; - - LLVector4a lhs, rhs; - lhs.setSub(p1, p0); - rhs.setSub(p2, p0); - - LLVector4a n; - n.setCross3(lhs, rhs); - - n0.add(n); - n1.add(n); - n2.add(n); - } - - //normalize normals and build point map - LLVolumeFace::VertexMapData::PointMap point_map; - - for (U32 i = 0; i < faceted.mNumVertices; ++i) - { - faceted.mNormals[i].normalize3(); - - LLVolumeFace::VertexMapData v; - v.setPosition(faceted.mPositions[i]); - v.setNormal(faceted.mNormals[i]); - - point_map[LLVector3(v.getPosition().getF32ptr())].push_back(v); - } - - //create faceted copy of current face with texture coordinates (step 4) - LLVolumeFace new_face; - - //bake out triangles into new face - new_face.resizeIndices(vol_face.mNumIndices); - new_face.resizeVertices(vol_face.mNumIndices); - - for (U32 i = 0; i < vol_face.mNumIndices; ++i) - { - U32 idx = vol_face.mIndices[i]; - LLVolumeFace::VertexData v; - new_face.mPositions[i] = vol_face.mPositions[idx]; - new_face.mNormals[i].clear(); - new_face.mIndices[i] = i; - } - - if (vol_face.mTexCoords) - { - for (U32 i = 0; i < vol_face.mNumIndices; i++) - { - U32 idx = vol_face.mIndices[i]; - new_face.mTexCoords[i] = vol_face.mTexCoords[idx]; - } - } - else - { - //ll_aligned_free_16(new_face.mTexCoords); - new_face.mTexCoords = NULL; - } - - //generate normals for new face - for (U32 i = 0; i < new_face.mNumIndices; i += 3) - { //for each triangle - U16 i0 = new_face.mIndices[i+0]; - U16 i1 = new_face.mIndices[i+1]; - U16 i2 = new_face.mIndices[i+2]; - - LLVector4a& p0 = new_face.mPositions[i0]; - LLVector4a& p1 = new_face.mPositions[i1]; - LLVector4a& p2 = new_face.mPositions[i2]; - - LLVector4a& n0 = new_face.mNormals[i0]; - LLVector4a& n1 = new_face.mNormals[i1]; - LLVector4a& n2 = new_face.mNormals[i2]; - - LLVector4a lhs, rhs; - lhs.setSub(p1, p0); - rhs.setSub(p2, p0); - - n0.setCross3(lhs, rhs); - n0.normalize3(); - n1 = n0; - n2 = n0; - } - - //swap out normals in new_face with best match from point map (step 5) - for (U32 i = 0; i < new_face.mNumVertices; ++i) - { - //LLVolumeFace::VertexData v = new_face.mVertices[i]; - - LLVector4a ref_norm = new_face.mNormals[i]; - - LLVolumeFace::VertexMapData::PointMap::iterator iter = point_map.find(LLVector3(new_face.mPositions[i].getF32ptr())); - - if (iter != point_map.end()) - { - F32 best = -2.f; - for (U32 k = 0; k < iter->second.size(); ++k) - { - LLVector4a& n = iter->second[k].getNormal(); - - F32 cur = n.dot3(ref_norm).getF32(); - - if (cur > best) - { - best = cur; - new_face.mNormals[i] = n; - } - } - } - } - - //remove redundant vertices from new face (step 6) - new_face.optimize(); - - mVolumeFaces[j] = new_face; - } + //generate normals for all faces by: + // 1 - Create faceted copy of face with no texture coordinates + // 2 - Weld vertices in faceted copy that are shared between triangles with less than "angle_cutoff" difference between normals + // 3 - Generate smoothed set of normals based on welding results + // 4 - Create faceted copy of face with texture coordinates + // 5 - Copy smoothed normals to faceted copy, using closest normal to triangle normal where more than one normal exists for a given position + // 6 - Remove redundant vertices from new faceted (now smooth) copy + + angle_cutoff = cosf(angle_cutoff); + for (U32 j = 0; j < mVolumeFaces.size(); ++j) + { + LLVolumeFace& vol_face = mVolumeFaces[j]; + + if (vol_face.mNumIndices > 65535) + { + LL_WARNS("MESHSKININFO") << "Too many vertices for normal generation to work." << LL_ENDL; + continue; + } + + //create faceted copy of current face with no texture coordinates (step 1) + LLVolumeFace faceted; + + LLVector4a* src_pos = (LLVector4a*) vol_face.mPositions; + //LLVector4a* src_norm = (LLVector4a*) vol_face.mNormals; + + + faceted.resizeVertices(vol_face.mNumIndices); + faceted.resizeIndices(vol_face.mNumIndices); + //bake out triangles into temporary face, clearing texture coordinates + for (U32 i = 0; i < vol_face.mNumIndices; ++i) + { + U32 idx = vol_face.mIndices[i]; + + faceted.mPositions[i] = src_pos[idx]; + faceted.mTexCoords[i] = LLVector2(0,0); + faceted.mIndices[i] = i; + } + + //generate normals for temporary face + for (U32 i = 0; i < faceted.mNumIndices; i += 3) + { //for each triangle + U16 i0 = faceted.mIndices[i+0]; + U16 i1 = faceted.mIndices[i+1]; + U16 i2 = faceted.mIndices[i+2]; + + LLVector4a& p0 = faceted.mPositions[i0]; + LLVector4a& p1 = faceted.mPositions[i1]; + LLVector4a& p2 = faceted.mPositions[i2]; + + LLVector4a& n0 = faceted.mNormals[i0]; + LLVector4a& n1 = faceted.mNormals[i1]; + LLVector4a& n2 = faceted.mNormals[i2]; + + LLVector4a lhs, rhs; + lhs.setSub(p1, p0); + rhs.setSub(p2, p0); + + n0.setCross3(lhs, rhs); + n0.normalize3(); + n1 = n0; + n2 = n0; + } + + //weld vertices in temporary face, respecting angle_cutoff (step 2) + faceted.optimize(angle_cutoff); + + //generate normals for welded face based on new topology (step 3) + + for (U32 i = 0; i < faceted.mNumVertices; i++) + { + faceted.mNormals[i].clear(); + } + + for (U32 i = 0; i < faceted.mNumIndices; i += 3) + { //for each triangle + U16 i0 = faceted.mIndices[i+0]; + U16 i1 = faceted.mIndices[i+1]; + U16 i2 = faceted.mIndices[i+2]; + + LLVector4a& p0 = faceted.mPositions[i0]; + LLVector4a& p1 = faceted.mPositions[i1]; + LLVector4a& p2 = faceted.mPositions[i2]; + + LLVector4a& n0 = faceted.mNormals[i0]; + LLVector4a& n1 = faceted.mNormals[i1]; + LLVector4a& n2 = faceted.mNormals[i2]; + + LLVector4a lhs, rhs; + lhs.setSub(p1, p0); + rhs.setSub(p2, p0); + + LLVector4a n; + n.setCross3(lhs, rhs); + + n0.add(n); + n1.add(n); + n2.add(n); + } + + //normalize normals and build point map + LLVolumeFace::VertexMapData::PointMap point_map; + + for (U32 i = 0; i < faceted.mNumVertices; ++i) + { + faceted.mNormals[i].normalize3(); + + LLVolumeFace::VertexMapData v; + v.setPosition(faceted.mPositions[i]); + v.setNormal(faceted.mNormals[i]); + + point_map[LLVector3(v.getPosition().getF32ptr())].push_back(v); + } + + //create faceted copy of current face with texture coordinates (step 4) + LLVolumeFace new_face; + + //bake out triangles into new face + new_face.resizeIndices(vol_face.mNumIndices); + new_face.resizeVertices(vol_face.mNumIndices); + + for (U32 i = 0; i < vol_face.mNumIndices; ++i) + { + U32 idx = vol_face.mIndices[i]; + LLVolumeFace::VertexData v; + new_face.mPositions[i] = vol_face.mPositions[idx]; + new_face.mNormals[i].clear(); + new_face.mIndices[i] = i; + } + + if (vol_face.mTexCoords) + { + for (U32 i = 0; i < vol_face.mNumIndices; i++) + { + U32 idx = vol_face.mIndices[i]; + new_face.mTexCoords[i] = vol_face.mTexCoords[idx]; + } + } + else + { + //ll_aligned_free_16(new_face.mTexCoords); + new_face.mTexCoords = NULL; + } + + //generate normals for new face + for (U32 i = 0; i < new_face.mNumIndices; i += 3) + { //for each triangle + U16 i0 = new_face.mIndices[i+0]; + U16 i1 = new_face.mIndices[i+1]; + U16 i2 = new_face.mIndices[i+2]; + + LLVector4a& p0 = new_face.mPositions[i0]; + LLVector4a& p1 = new_face.mPositions[i1]; + LLVector4a& p2 = new_face.mPositions[i2]; + + LLVector4a& n0 = new_face.mNormals[i0]; + LLVector4a& n1 = new_face.mNormals[i1]; + LLVector4a& n2 = new_face.mNormals[i2]; + + LLVector4a lhs, rhs; + lhs.setSub(p1, p0); + rhs.setSub(p2, p0); + + n0.setCross3(lhs, rhs); + n0.normalize3(); + n1 = n0; + n2 = n0; + } + + //swap out normals in new_face with best match from point map (step 5) + for (U32 i = 0; i < new_face.mNumVertices; ++i) + { + //LLVolumeFace::VertexData v = new_face.mVertices[i]; + + LLVector4a ref_norm = new_face.mNormals[i]; + + LLVolumeFace::VertexMapData::PointMap::iterator iter = point_map.find(LLVector3(new_face.mPositions[i].getF32ptr())); + + if (iter != point_map.end()) + { + F32 best = -2.f; + for (U32 k = 0; k < iter->second.size(); ++k) + { + LLVector4a& n = iter->second[k].getNormal(); + + F32 cur = n.dot3(ref_norm).getF32(); + + if (cur > best) + { + best = cur; + new_face.mNormals[i] = n; + } + } + } + } + + //remove redundant vertices from new face (step 6) + new_face.optimize(); + + mVolumeFaces[j] = new_face; + } } @@ -656,152 +656,152 @@ std::string LLModel::getName() const //static LLSD LLModel::writeModel( - std::ostream& ostr, - LLModel* physics, - LLModel* high, - LLModel* medium, - LLModel* low, - LLModel* impostor, - const LLModel::Decomposition& decomp, - BOOL upload_skin, - BOOL upload_joints, + std::ostream& ostr, + LLModel* physics, + LLModel* high, + LLModel* medium, + LLModel* low, + LLModel* impostor, + const LLModel::Decomposition& decomp, + BOOL upload_skin, + BOOL upload_joints, BOOL lock_scale_if_joint_position, - BOOL nowrite, - BOOL as_slm, - int submodel_id) + BOOL nowrite, + BOOL as_slm, + int submodel_id) { - LLSD mdl; - - LLModel* model[] = - { - impostor, - low, - medium, - high, - physics - }; - - bool skinning = upload_skin && high && !high->mSkinWeights.empty(); - - if (skinning) - { //write skinning block - mdl["skin"] = high->mSkinInfo.asLLSD(upload_joints, lock_scale_if_joint_position); - } - - if (!decomp.mBaseHull.empty() || - !decomp.mHull.empty()) - { - mdl["physics_convex"] = decomp.asLLSD(); - if (!decomp.mHull.empty() && !as_slm) - { //convex decomposition exists, physics mesh will not be used (unless this is an slm file) - model[LLModel::LOD_PHYSICS] = NULL; - } - } - else if (submodel_id) - { - const LLModel::Decomposition fake_decomp; - mdl["secondary"] = true; + LLSD mdl; + + LLModel* model[] = + { + impostor, + low, + medium, + high, + physics + }; + + bool skinning = upload_skin && high && !high->mSkinWeights.empty(); + + if (skinning) + { //write skinning block + mdl["skin"] = high->mSkinInfo.asLLSD(upload_joints, lock_scale_if_joint_position); + } + + if (!decomp.mBaseHull.empty() || + !decomp.mHull.empty()) + { + mdl["physics_convex"] = decomp.asLLSD(); + if (!decomp.mHull.empty() && !as_slm) + { //convex decomposition exists, physics mesh will not be used (unless this is an slm file) + model[LLModel::LOD_PHYSICS] = NULL; + } + } + else if (submodel_id) + { + const LLModel::Decomposition fake_decomp; + mdl["secondary"] = true; mdl["submodel_id"] = submodel_id; - mdl["physics_convex"] = fake_decomp.asLLSD(); - model[LLModel::LOD_PHYSICS] = NULL; - } - - if (as_slm) - { //save material list names - for (U32 i = 0; i < high->mMaterialList.size(); ++i) - { - mdl["material_list"][i] = high->mMaterialList[i]; - } - } - - for (U32 idx = 0; idx < MODEL_NAMES_LENGTH; ++idx) - { - if (model[idx] && (model[idx]->getNumVolumeFaces() > 0) && model[idx]->getVolumeFace(0).mPositions != NULL) - { - LLVector3 min_pos = LLVector3(model[idx]->getVolumeFace(0).mPositions[0].getF32ptr()); - LLVector3 max_pos = min_pos; - - //find position domain - for (S32 i = 0; i < model[idx]->getNumVolumeFaces(); ++i) - { //for each face - const LLVolumeFace& face = model[idx]->getVolumeFace(i); - for (U32 j = 0; j < face.mNumVertices; ++j) - { - update_min_max(min_pos, max_pos, face.mPositions[j].getF32ptr()); - } - } - - LLVector3 pos_range = max_pos - min_pos; - - for (S32 i = 0; i < model[idx]->getNumVolumeFaces(); ++i) - { //for each face - const LLVolumeFace& face = model[idx]->getVolumeFace(i); - if (face.mNumVertices < 3) - { //don't export an empty face - mdl[model_names[idx]][i]["NoGeometry"] = true; - continue; - } - LLSD::Binary verts(face.mNumVertices*3*2); - LLSD::Binary tc(face.mNumVertices*2*2); - LLSD::Binary normals(face.mNumVertices*3*2); + mdl["physics_convex"] = fake_decomp.asLLSD(); + model[LLModel::LOD_PHYSICS] = NULL; + } + + if (as_slm) + { //save material list names + for (U32 i = 0; i < high->mMaterialList.size(); ++i) + { + mdl["material_list"][i] = high->mMaterialList[i]; + } + } + + for (U32 idx = 0; idx < MODEL_NAMES_LENGTH; ++idx) + { + if (model[idx] && (model[idx]->getNumVolumeFaces() > 0) && model[idx]->getVolumeFace(0).mPositions != NULL) + { + LLVector3 min_pos = LLVector3(model[idx]->getVolumeFace(0).mPositions[0].getF32ptr()); + LLVector3 max_pos = min_pos; + + //find position domain + for (S32 i = 0; i < model[idx]->getNumVolumeFaces(); ++i) + { //for each face + const LLVolumeFace& face = model[idx]->getVolumeFace(i); + for (U32 j = 0; j < face.mNumVertices; ++j) + { + update_min_max(min_pos, max_pos, face.mPositions[j].getF32ptr()); + } + } + + LLVector3 pos_range = max_pos - min_pos; + + for (S32 i = 0; i < model[idx]->getNumVolumeFaces(); ++i) + { //for each face + const LLVolumeFace& face = model[idx]->getVolumeFace(i); + if (face.mNumVertices < 3) + { //don't export an empty face + mdl[model_names[idx]][i]["NoGeometry"] = true; + continue; + } + LLSD::Binary verts(face.mNumVertices*3*2); + LLSD::Binary tc(face.mNumVertices*2*2); + LLSD::Binary normals(face.mNumVertices*3*2); LLSD::Binary tangents(face.mNumVertices * 4 * 2); - LLSD::Binary indices(face.mNumIndices*2); + LLSD::Binary indices(face.mNumIndices*2); - U32 vert_idx = 0; - U32 norm_idx = 0; + U32 vert_idx = 0; + U32 norm_idx = 0; //U32 tan_idx = 0; - U32 tc_idx = 0; - - LLVector2* ftc = (LLVector2*) face.mTexCoords; - LLVector2 min_tc; - LLVector2 max_tc; - - if (ftc) - { - 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; - - for (U32 j = 0; j < face.mNumVertices; ++j) - { //for each vert - - F32* pos = face.mPositions[j].getF32ptr(); - - //position - for (U32 k = 0; k < 3; ++k) - { //for each component - //convert to 16-bit normalized across domain - U16 val = (U16) (((pos[k]-min_pos.mV[k])/pos_range.mV[k])*65535); - - U8* buff = (U8*) &val; - //write to binary buffer - verts[vert_idx++] = buff[0]; - verts[vert_idx++] = buff[1]; - } - - if (face.mNormals) - { //normals - F32* norm = face.mNormals[j].getF32ptr(); - - 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; - - //write to binary buffer - normals[norm_idx++] = buff[0]; - normals[norm_idx++] = buff[1]; - } - } + U32 tc_idx = 0; + + LLVector2* ftc = (LLVector2*) face.mTexCoords; + LLVector2 min_tc; + LLVector2 max_tc; + + if (ftc) + { + 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; + + for (U32 j = 0; j < face.mNumVertices; ++j) + { //for each vert + + F32* pos = face.mPositions[j].getF32ptr(); + + //position + for (U32 k = 0; k < 3; ++k) + { //for each component + //convert to 16-bit normalized across domain + U16 val = (U16) (((pos[k]-min_pos.mV[k])/pos_range.mV[k])*65535); + + U8* buff = (U8*) &val; + //write to binary buffer + verts[vert_idx++] = buff[0]; + verts[vert_idx++] = buff[1]; + } + + if (face.mNormals) + { //normals + F32* norm = face.mNormals[j].getF32ptr(); + + 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; + + //write to binary buffer + normals[norm_idx++] = buff[0]; + normals[norm_idx++] = buff[1]; + } + } #if 0 // keep this code for now in case we want to support transporting tangents with mesh assets if (face.mTangents) @@ -820,44 +820,44 @@ LLSD LLModel::writeModel( } } #endif - - //texcoord - if (face.mTexCoords) - { - F32* src_tc = (F32*) face.mTexCoords[j].mV; - - 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; - for (U32 j = 0; j < face.mNumIndices; ++j) - { - U8* buff = (U8*) &(face.mIndices[j]); - indices[idx_idx++] = buff[0]; - indices[idx_idx++] = buff[1]; - } - - //write out face data - mdl[model_names[idx]][i]["PositionDomain"]["Min"] = min_pos.getValue(); - mdl[model_names[idx]][i]["PositionDomain"]["Max"] = max_pos.getValue(); + + //texcoord + if (face.mTexCoords) + { + F32* src_tc = (F32*) face.mTexCoords[j].mV; + + 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; + for (U32 j = 0; j < face.mNumIndices; ++j) + { + U8* buff = (U8*) &(face.mIndices[j]); + indices[idx_idx++] = buff[0]; + indices[idx_idx++] = buff[1]; + } + + //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]["NormalizedScale"] = face.mNormalizedScale.getValue(); - mdl[model_names[idx]][i]["Position"] = verts; - - if (face.mNormals) - { - mdl[model_names[idx]][i]["Normal"] = normals; - } + mdl[model_names[idx]][i]["Position"] = verts; + + if (face.mNormals) + { + mdl[model_names[idx]][i]["Normal"] = normals; + } #if 0 // keep this code for now in case we decide to transport tangents with mesh assets if (face.mTangents) @@ -866,17 +866,17 @@ LLSD LLModel::writeModel( } #endif - 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; - } + 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; + mdl[model_names[idx]][i]["TriangleList"] = indices; - if (skinning) - { + if (skinning) + { if (!model[idx]->mSkinWeights.empty()) { //write out skin weights @@ -940,107 +940,107 @@ LLSD LLModel::writeModel( LL_WARNS("MESHSKININFO") << "Attempting to use skinning without having skin weights" << LL_ENDL; } } - } - } - } - } - - return writeModelToStream(ostr, mdl, nowrite, as_slm); + } + } + } + } + + return writeModelToStream(ostr, mdl, nowrite, as_slm); } LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite, BOOL as_slm) { - std::string::size_type cur_offset = 0; + std::string::size_type cur_offset = 0; - LLSD header; + LLSD header; - if (as_slm && mdl.has("material_list")) - { //save material binding names to header - header["material_list"] = mdl["material_list"]; - } + if (as_slm && mdl.has("material_list")) + { //save material binding names to header + header["material_list"] = mdl["material_list"]; + } - std::string skin; + std::string skin; - if (mdl.has("skin")) - { //write out skin block - skin = zip_llsd(mdl["skin"]); + if (mdl.has("skin")) + { //write out skin block + skin = zip_llsd(mdl["skin"]); - U32 size = skin.size(); - if (size > 0) - { - header["skin"]["offset"] = (LLSD::Integer) cur_offset; - header["skin"]["size"] = (LLSD::Integer) size; - cur_offset += size; - } - } + U32 size = skin.size(); + if (size > 0) + { + header["skin"]["offset"] = (LLSD::Integer) cur_offset; + header["skin"]["size"] = (LLSD::Integer) size; + cur_offset += size; + } + } - std::string decomposition; + std::string decomposition; - if (mdl.has("physics_convex")) - { //write out convex decomposition - decomposition = zip_llsd(mdl["physics_convex"]); + if (mdl.has("physics_convex")) + { //write out convex decomposition + decomposition = zip_llsd(mdl["physics_convex"]); - U32 size = decomposition.size(); - if (size > 0) - { - header["physics_convex"]["offset"] = (LLSD::Integer) cur_offset; - header["physics_convex"]["size"] = (LLSD::Integer) size; - cur_offset += size; - } - } + U32 size = decomposition.size(); + if (size > 0) + { + header["physics_convex"]["offset"] = (LLSD::Integer) cur_offset; + header["physics_convex"]["size"] = (LLSD::Integer) size; + cur_offset += size; + } + } if (mdl.has("submodel_id")) { //write out submodel id header["submodel_id"] = (LLSD::Integer)mdl["submodel_id"]; } - std::string out[MODEL_NAMES_LENGTH]; - - for (S32 i = 0; i < MODEL_NAMES_LENGTH; i++) - { - if (mdl.has(model_names[i])) - { - out[i] = zip_llsd(mdl[model_names[i]]); - - U32 size = out[i].size(); - - header[model_names[i]]["offset"] = (LLSD::Integer) cur_offset; - header[model_names[i]]["size"] = (LLSD::Integer) size; - cur_offset += size; - } - } - - if (!nowrite) - { - LLSDSerialize::toBinary(header, ostr); - - if (!skin.empty()) - { //write skin block - ostr.write((const char*) skin.data(), header["skin"]["size"].asInteger()); - } - - if (!decomposition.empty()) - { //write decomposition block - ostr.write((const char*) decomposition.data(), header["physics_convex"]["size"].asInteger()); - } - - for (S32 i = 0; i < MODEL_NAMES_LENGTH; i++) - { - if (!out[i].empty()) - { - ostr.write((const char*) out[i].data(), header[model_names[i]]["size"].asInteger()); - } - } - } - - return header; + std::string out[MODEL_NAMES_LENGTH]; + + for (S32 i = 0; i < MODEL_NAMES_LENGTH; i++) + { + if (mdl.has(model_names[i])) + { + out[i] = zip_llsd(mdl[model_names[i]]); + + U32 size = out[i].size(); + + header[model_names[i]]["offset"] = (LLSD::Integer) cur_offset; + header[model_names[i]]["size"] = (LLSD::Integer) size; + cur_offset += size; + } + } + + if (!nowrite) + { + LLSDSerialize::toBinary(header, ostr); + + if (!skin.empty()) + { //write skin block + ostr.write((const char*) skin.data(), header["skin"]["size"].asInteger()); + } + + if (!decomposition.empty()) + { //write decomposition block + ostr.write((const char*) decomposition.data(), header["physics_convex"]["size"].asInteger()); + } + + for (S32 i = 0; i < MODEL_NAMES_LENGTH; i++) + { + if (!out[i].empty()) + { + ostr.write((const char*) out[i].data(), header[model_names[i]]["size"].asInteger()); + } + } + } + + return header; } LLModel::weight_list& LLModel::getJointInfluences(const LLVector3& pos) { - //1. If a vertex has been weighted then we'll find it via pos and return its weight list - weight_map::iterator iterPos = mSkinWeights.begin(); - weight_map::iterator iterEnd = mSkinWeights.end(); + //1. If a vertex has been weighted then we'll find it via pos and return its weight list + weight_map::iterator iterPos = mSkinWeights.begin(); + weight_map::iterator iterEnd = mSkinWeights.end(); if (mSkinWeights.empty()) { @@ -1048,32 +1048,32 @@ LLModel::weight_list& LLModel::getJointInfluences(const LLVector3& pos) // everything that calls this function should precheck that there is data. LL_ERRS() << "called getJointInfluences with empty weights list" << LL_ENDL; } - - for ( ; iterPos!=iterEnd; ++iterPos ) - { - if ( jointPositionalLookup( iterPos->first, pos ) ) - { - return iterPos->second; - } - } - - //2. Otherwise we'll use the older implementation - weight_map::iterator iter = mSkinWeights.find(pos); - - if (iter != mSkinWeights.end()) - { - if ((iter->first - pos).magVec() > 0.1f) - { - LL_ERRS() << "Couldn't find weight list." << LL_ENDL; - } - - return iter->second; - } - else - { //no exact match found, get closest point - const F32 epsilon = 1e-5f; - weight_map::iterator iter_up = mSkinWeights.lower_bound(pos); - weight_map::iterator iter_down = iter_up; + + for ( ; iterPos!=iterEnd; ++iterPos ) + { + if ( jointPositionalLookup( iterPos->first, pos ) ) + { + return iterPos->second; + } + } + + //2. Otherwise we'll use the older implementation + weight_map::iterator iter = mSkinWeights.find(pos); + + if (iter != mSkinWeights.end()) + { + if ((iter->first - pos).magVec() > 0.1f) + { + LL_ERRS() << "Couldn't find weight list." << LL_ENDL; + } + + return iter->second; + } + else + { //no exact match found, get closest point + const F32 epsilon = 1e-5f; + weight_map::iterator iter_up = mSkinWeights.lower_bound(pos); + weight_map::iterator iter_down = iter_up; weight_map::iterator best = iter_up; if (iter_up != mSkinWeights.end()) { @@ -1085,260 +1085,260 @@ LLModel::weight_list& LLModel::getJointInfluences(const LLVector3& pos) --best; } - F32 min_dist = (iter->first - pos).magVec(); - - bool done = false; - while (!done) - { //search up and down mSkinWeights from lower bound of pos until a - //match is found within epsilon. If no match is found within epsilon, - //return closest match - done = true; - if (iter_up != mSkinWeights.end() && ++iter_up != mSkinWeights.end()) - { - done = false; - F32 dist = (iter_up->first - pos).magVec(); - - if (dist < epsilon) - { - return iter_up->second; - } - - if (dist < min_dist) - { - best = iter_up; - min_dist = dist; - } - } - - if (iter_down != mSkinWeights.begin() && --iter_down != mSkinWeights.begin()) - { - done = false; - - F32 dist = (iter_down->first - pos).magVec(); - - if (dist < epsilon) - { - return iter_down->second; - } - - if (dist < min_dist) - { - best = iter_down; - min_dist = dist; - } - - } - } - - return best->second; - } + F32 min_dist = (iter->first - pos).magVec(); + + bool done = false; + while (!done) + { //search up and down mSkinWeights from lower bound of pos until a + //match is found within epsilon. If no match is found within epsilon, + //return closest match + done = true; + if (iter_up != mSkinWeights.end() && ++iter_up != mSkinWeights.end()) + { + done = false; + F32 dist = (iter_up->first - pos).magVec(); + + if (dist < epsilon) + { + return iter_up->second; + } + + if (dist < min_dist) + { + best = iter_up; + min_dist = dist; + } + } + + if (iter_down != mSkinWeights.begin() && --iter_down != mSkinWeights.begin()) + { + done = false; + + F32 dist = (iter_down->first - pos).magVec(); + + if (dist < epsilon) + { + return iter_down->second; + } + + if (dist < min_dist) + { + best = iter_down; + min_dist = dist; + } + + } + } + + return best->second; + } } void LLModel::setConvexHullDecomposition( - const LLModel::convex_hull_decomposition& decomp) + const LLModel::convex_hull_decomposition& decomp) { - mPhysics.mHull = decomp; - mPhysics.mMesh.clear(); - updateHullCenters(); + mPhysics.mHull = decomp; + mPhysics.mMesh.clear(); + updateHullCenters(); } void LLModel::updateHullCenters() { - mHullCenter.resize(mPhysics.mHull.size()); - mHullPoints = 0; - mCenterOfHullCenters.clear(); - - for (U32 i = 0; i < mPhysics.mHull.size(); ++i) - { - LLVector3 cur_center; - - for (U32 j = 0; j < mPhysics.mHull[i].size(); ++j) - { - cur_center += mPhysics.mHull[i][j]; - } - mCenterOfHullCenters += cur_center; - cur_center *= 1.f/mPhysics.mHull[i].size(); - mHullCenter[i] = cur_center; - mHullPoints += mPhysics.mHull[i].size(); - } - - if (mHullPoints > 0) - { - mCenterOfHullCenters *= 1.f / mHullPoints; - llassert(mPhysics.hasHullList()); - } + mHullCenter.resize(mPhysics.mHull.size()); + mHullPoints = 0; + mCenterOfHullCenters.clear(); + + for (U32 i = 0; i < mPhysics.mHull.size(); ++i) + { + LLVector3 cur_center; + + for (U32 j = 0; j < mPhysics.mHull[i].size(); ++j) + { + cur_center += mPhysics.mHull[i][j]; + } + mCenterOfHullCenters += cur_center; + cur_center *= 1.f/mPhysics.mHull[i].size(); + mHullCenter[i] = cur_center; + mHullPoints += mPhysics.mHull[i].size(); + } + + if (mHullPoints > 0) + { + mCenterOfHullCenters *= 1.f / mHullPoints; + llassert(mPhysics.hasHullList()); + } } bool LLModel::loadModel(std::istream& is) { - mSculptLevel = -1; // default is an error occured - - LLSD header; - { - if (!LLSDSerialize::fromBinary(header, is, 1024*1024*1024)) - { - LL_WARNS("MESHSKININFO") << "Mesh header parse error. Not a valid mesh asset!" << LL_ENDL; - return false; - } - } - - if (header.has("material_list")) - { //load material list names - mMaterialList.clear(); - for (U32 i = 0; i < header["material_list"].size(); ++i) - { - mMaterialList.push_back(header["material_list"][i].asString()); - } - } - - mSubmodelID = header.has("submodel_id") ? header["submodel_id"].asInteger() : false; - - static const std::string lod_name[] = - { - "lowest_lod", - "low_lod", - "medium_lod", - "high_lod", - "physics_mesh", - }; - - const S32 MODEL_LODS = 5; - - S32 lod = llclamp((S32) mDetail, 0, MODEL_LODS); - - if (header[lod_name[lod]]["offset"].asInteger() == -1 || - header[lod_name[lod]]["size"].asInteger() == 0 ) - { //cannot load requested LOD - LL_WARNS("MESHSKININFO") << "LoD data is invalid!" << LL_ENDL; - return false; - } - - bool has_skin = header["skin"]["offset"].asInteger() >=0 && - header["skin"]["size"].asInteger() > 0; - - if ((lod == LLModel::LOD_HIGH) && !mSubmodelID) - { //try to load skin info and decomp info - std::ios::pos_type cur_pos = is.tellg(); - loadSkinInfo(header, is); - is.seekg(cur_pos); - } - - if ((lod == LLModel::LOD_HIGH || lod == LLModel::LOD_PHYSICS) && !mSubmodelID) - { - std::ios::pos_type cur_pos = is.tellg(); - loadDecomposition(header, is); - is.seekg(cur_pos); - } - - is.seekg(header[lod_name[lod]]["offset"].asInteger(), std::ios_base::cur); - - if (unpackVolumeFaces(is, header[lod_name[lod]]["size"].asInteger())) - { - if (has_skin) - { - //build out mSkinWeight from face info - for (S32 i = 0; i < getNumVolumeFaces(); ++i) - { - const LLVolumeFace& face = getVolumeFace(i); - - if (face.mWeights) - { - for (S32 j = 0; j < face.mNumVertices; ++j) - { - LLVector4a& w = face.mWeights[j]; - - std::vector<JointWeight> wght; - - for (S32 k = 0; k < 4; ++k) - { - S32 idx = (S32) w[k]; - F32 f = w[k] - idx; - if (f > 0.f) - { - wght.push_back(JointWeight(idx, f)); - } - } - - if (!wght.empty()) - { - LLVector3 pos(face.mPositions[j].getF32ptr()); - mSkinWeights[pos] = wght; - } - } - } - } - } - return true; - } - else - { - LL_WARNS("MESHSKININFO") << "unpackVolumeFaces failed!" << LL_ENDL; - } - - return false; + mSculptLevel = -1; // default is an error occured + + LLSD header; + { + if (!LLSDSerialize::fromBinary(header, is, 1024*1024*1024)) + { + LL_WARNS("MESHSKININFO") << "Mesh header parse error. Not a valid mesh asset!" << LL_ENDL; + return false; + } + } + + if (header.has("material_list")) + { //load material list names + mMaterialList.clear(); + for (U32 i = 0; i < header["material_list"].size(); ++i) + { + mMaterialList.push_back(header["material_list"][i].asString()); + } + } + + mSubmodelID = header.has("submodel_id") ? header["submodel_id"].asInteger() : false; + + static const std::string lod_name[] = + { + "lowest_lod", + "low_lod", + "medium_lod", + "high_lod", + "physics_mesh", + }; + + const S32 MODEL_LODS = 5; + + S32 lod = llclamp((S32) mDetail, 0, MODEL_LODS); + + if (header[lod_name[lod]]["offset"].asInteger() == -1 || + header[lod_name[lod]]["size"].asInteger() == 0 ) + { //cannot load requested LOD + LL_WARNS("MESHSKININFO") << "LoD data is invalid!" << LL_ENDL; + return false; + } + + bool has_skin = header["skin"]["offset"].asInteger() >=0 && + header["skin"]["size"].asInteger() > 0; + + if ((lod == LLModel::LOD_HIGH) && !mSubmodelID) + { //try to load skin info and decomp info + std::ios::pos_type cur_pos = is.tellg(); + loadSkinInfo(header, is); + is.seekg(cur_pos); + } + + if ((lod == LLModel::LOD_HIGH || lod == LLModel::LOD_PHYSICS) && !mSubmodelID) + { + std::ios::pos_type cur_pos = is.tellg(); + loadDecomposition(header, is); + is.seekg(cur_pos); + } + + is.seekg(header[lod_name[lod]]["offset"].asInteger(), std::ios_base::cur); + + if (unpackVolumeFaces(is, header[lod_name[lod]]["size"].asInteger())) + { + if (has_skin) + { + //build out mSkinWeight from face info + for (S32 i = 0; i < getNumVolumeFaces(); ++i) + { + const LLVolumeFace& face = getVolumeFace(i); + + if (face.mWeights) + { + for (S32 j = 0; j < face.mNumVertices; ++j) + { + LLVector4a& w = face.mWeights[j]; + + std::vector<JointWeight> wght; + + for (S32 k = 0; k < 4; ++k) + { + S32 idx = (S32) w[k]; + F32 f = w[k] - idx; + if (f > 0.f) + { + wght.push_back(JointWeight(idx, f)); + } + } + + if (!wght.empty()) + { + LLVector3 pos(face.mPositions[j].getF32ptr()); + mSkinWeights[pos] = wght; + } + } + } + } + } + return true; + } + else + { + LL_WARNS("MESHSKININFO") << "unpackVolumeFaces failed!" << LL_ENDL; + } + + return false; } bool LLModel::isMaterialListSubset( LLModel* ref ) { - int refCnt = ref->mMaterialList.size(); - int modelCnt = mMaterialList.size(); - - for (U32 src = 0; src < modelCnt; ++src) - { - bool foundRef = false; - - for (U32 dst = 0; dst < refCnt; ++dst) - { - //LL_INFOS()<<mMaterialList[src]<<" "<<ref->mMaterialList[dst]<<LL_ENDL; - foundRef = mMaterialList[src] == ref->mMaterialList[dst]; - - if ( foundRef ) - { - break; - } - } - - if (!foundRef) - { + int refCnt = ref->mMaterialList.size(); + int modelCnt = mMaterialList.size(); + + for (U32 src = 0; src < modelCnt; ++src) + { + bool foundRef = false; + + for (U32 dst = 0; dst < refCnt; ++dst) + { + //LL_INFOS()<<mMaterialList[src]<<" "<<ref->mMaterialList[dst]<<LL_ENDL; + foundRef = mMaterialList[src] == ref->mMaterialList[dst]; + + if ( foundRef ) + { + break; + } + } + + if (!foundRef) + { LL_INFOS("MESHSKININFO") << "Could not find material " << mMaterialList[src] << " in reference model " << ref->mLabel << LL_ENDL; - return false; - } - } - - return true; + return false; + } + } + + return true; } bool LLModel::needToAddFaces( LLModel* ref, int& refFaceCnt, int& modelFaceCnt ) { - bool changed = false; - if ( refFaceCnt< modelFaceCnt ) - { - refFaceCnt += modelFaceCnt - refFaceCnt; - changed = true; - } - else - if ( modelFaceCnt < refFaceCnt ) - { - modelFaceCnt += refFaceCnt - modelFaceCnt; - changed = true; - } - - return changed; + bool changed = false; + if ( refFaceCnt< modelFaceCnt ) + { + refFaceCnt += modelFaceCnt - refFaceCnt; + changed = true; + } + else + if ( modelFaceCnt < refFaceCnt ) + { + modelFaceCnt += refFaceCnt - modelFaceCnt; + changed = true; + } + + return changed; } bool LLModel::matchMaterialOrder(LLModel* ref, int& refFaceCnt, int& modelFaceCnt ) { - //Is this a subset? - //LODs cannot currently add new materials, e.g. - //1. ref = a,b,c lod1 = d,e => This is not permitted - //2. ref = a,b,c lod1 = c => This would be permitted - - bool isASubset = isMaterialListSubset( ref ); - if ( !isASubset ) - { - LL_INFOS("MESHSKININFO")<<"Material of model is not a subset of reference."<<LL_ENDL; - return false; - } + //Is this a subset? + //LODs cannot currently add new materials, e.g. + //1. ref = a,b,c lod1 = d,e => This is not permitted + //2. ref = a,b,c lod1 = c => This would be permitted + + bool isASubset = isMaterialListSubset( ref ); + if ( !isASubset ) + { + LL_INFOS("MESHSKININFO")<<"Material of model is not a subset of reference."<<LL_ENDL; + return false; + } if (mMaterialList.size() > ref->mMaterialList.size()) { @@ -1347,97 +1347,97 @@ bool LLModel::matchMaterialOrder(LLModel* ref, int& refFaceCnt, int& modelFaceCn // larger than original and if we keep going, reordering will cause a crash return false; } - - std::map<std::string, U32> index_map; - - //build a map of material slot names to face indexes - bool reorder = false; - - std::set<std::string> base_mat; - std::set<std::string> cur_mat; - - for (U32 i = 0; i < mMaterialList.size(); i++) - { - index_map[ref->mMaterialList[i]] = i; - //if any material name does not match reference, we need to reorder - reorder |= ref->mMaterialList[i] != mMaterialList[i]; - base_mat.insert(ref->mMaterialList[i]); - cur_mat.insert(mMaterialList[i]); - } - - - if (reorder && (base_mat == cur_mat)) //don't reorder if material name sets don't match - { - std::vector<LLVolumeFace> new_face_list; - new_face_list.resize(mMaterialList.size()); - - std::vector<std::string> new_material_list; - new_material_list.resize(mMaterialList.size()); - - //rebuild face list so materials have the same order - //as the reference model - for (U32 i = 0; i < mMaterialList.size(); ++i) - { - U32 ref_idx = index_map[mMaterialList[i]]; - - if (i < mVolumeFaces.size()) - { - new_face_list[ref_idx] = mVolumeFaces[i]; - } - new_material_list[ref_idx] = mMaterialList[i]; - } - - llassert(new_material_list == ref->mMaterialList); - - mVolumeFaces = new_face_list; - - //override material list with reference model ordering - mMaterialList = ref->mMaterialList; - } - - return true; + + std::map<std::string, U32> index_map; + + //build a map of material slot names to face indexes + bool reorder = false; + + std::set<std::string> base_mat; + std::set<std::string> cur_mat; + + for (U32 i = 0; i < mMaterialList.size(); i++) + { + index_map[ref->mMaterialList[i]] = i; + //if any material name does not match reference, we need to reorder + reorder |= ref->mMaterialList[i] != mMaterialList[i]; + base_mat.insert(ref->mMaterialList[i]); + cur_mat.insert(mMaterialList[i]); + } + + + if (reorder && (base_mat == cur_mat)) //don't reorder if material name sets don't match + { + std::vector<LLVolumeFace> new_face_list; + new_face_list.resize(mMaterialList.size()); + + std::vector<std::string> new_material_list; + new_material_list.resize(mMaterialList.size()); + + //rebuild face list so materials have the same order + //as the reference model + for (U32 i = 0; i < mMaterialList.size(); ++i) + { + U32 ref_idx = index_map[mMaterialList[i]]; + + if (i < mVolumeFaces.size()) + { + new_face_list[ref_idx] = mVolumeFaces[i]; + } + new_material_list[ref_idx] = mMaterialList[i]; + } + + llassert(new_material_list == ref->mMaterialList); + + mVolumeFaces = new_face_list; + + //override material list with reference model ordering + mMaterialList = ref->mMaterialList; + } + + return true; } bool LLModel::loadSkinInfo(LLSD& header, std::istream &is) { - S32 offset = header["skin"]["offset"].asInteger(); - S32 size = header["skin"]["size"].asInteger(); + S32 offset = header["skin"]["offset"].asInteger(); + S32 size = header["skin"]["size"].asInteger(); - if (offset >= 0 && size > 0) - { - is.seekg(offset, std::ios_base::cur); + if (offset >= 0 && size > 0) + { + is.seekg(offset, std::ios_base::cur); - LLSD skin_data; + LLSD skin_data; - if (LLUZipHelper::unzip_llsd(skin_data, is, size) == LLUZipHelper::ZR_OK) - { - mSkinInfo.fromLLSD(skin_data); - return true; - } - } + if (LLUZipHelper::unzip_llsd(skin_data, is, size) == LLUZipHelper::ZR_OK) + { + mSkinInfo.fromLLSD(skin_data); + return true; + } + } - return false; + return false; } bool LLModel::loadDecomposition(LLSD& header, std::istream& is) { - S32 offset = header["physics_convex"]["offset"].asInteger(); - S32 size = header["physics_convex"]["size"].asInteger(); + S32 offset = header["physics_convex"]["offset"].asInteger(); + S32 size = header["physics_convex"]["size"].asInteger(); - if (offset >= 0 && size > 0 && !mSubmodelID) - { - is.seekg(offset, std::ios_base::cur); + if (offset >= 0 && size > 0 && !mSubmodelID) + { + is.seekg(offset, std::ios_base::cur); - LLSD data; + LLSD data; - if (LLUZipHelper::unzip_llsd(data, is, size) == LLUZipHelper::ZR_OK) - { - mPhysics.fromLLSD(data); - updateHullCenters(); - } - } + if (LLUZipHelper::unzip_llsd(data, is, size) == LLUZipHelper::ZR_OK) + { + mPhysics.fromLLSD(data); + updateHullCenters(); + } + } - return true; + return true; } LLMeshSkinInfo::LLMeshSkinInfo(): @@ -1454,45 +1454,45 @@ LLMeshSkinInfo::LLMeshSkinInfo(LLSD& skin): mInvalidJointsScrubbed(false), mJointNumsInitialized(false) { - fromLLSD(skin); + fromLLSD(skin); } LLMeshSkinInfo::LLMeshSkinInfo(const LLUUID& mesh_id, LLSD& skin) : - mMeshID(mesh_id), - mPelvisOffset(0.0), - mLockScaleIfJointPosition(false), - mInvalidJointsScrubbed(false), - mJointNumsInitialized(false) + mMeshID(mesh_id), + mPelvisOffset(0.0), + mLockScaleIfJointPosition(false), + mInvalidJointsScrubbed(false), + mJointNumsInitialized(false) { - fromLLSD(skin); + fromLLSD(skin); } void LLMeshSkinInfo::fromLLSD(LLSD& skin) { - if (skin.has("joint_names")) - { - for (U32 i = 0; i < skin["joint_names"].size(); ++i) - { - mJointNames.push_back(skin["joint_names"][i]); + if (skin.has("joint_names")) + { + for (U32 i = 0; i < skin["joint_names"].size(); ++i) + { + mJointNames.push_back(skin["joint_names"][i]); mJointNums.push_back(-1); - } - } - - if (skin.has("inverse_bind_matrix")) - { - for (U32 i = 0; i < skin["inverse_bind_matrix"].size(); ++i) - { - LLMatrix4 mat; - for (U32 j = 0; j < 4; j++) - { - for (U32 k = 0; k < 4; k++) - { - mat.mMatrix[j][k] = skin["inverse_bind_matrix"][i][j*4+k].asReal(); - } - } - - mInvBindMatrix.push_back(LLMatrix4a(mat)); - } + } + } + + if (skin.has("inverse_bind_matrix")) + { + for (U32 i = 0; i < skin["inverse_bind_matrix"].size(); ++i) + { + LLMatrix4 mat; + for (U32 j = 0; j < 4; j++) + { + for (U32 k = 0; k < 4; k++) + { + mat.mMatrix[j][k] = skin["inverse_bind_matrix"][i][j*4+k].asReal(); + } + } + + mInvBindMatrix.push_back(LLMatrix4a(mat)); + } if (mJointNames.size() != mInvBindMatrix.size()) { @@ -1501,102 +1501,102 @@ void LLMeshSkinInfo::fromLLSD(LLSD& skin) mJointNums.clear(); mInvBindMatrix.clear(); } - } + } - if (skin.has("bind_shape_matrix")) - { + if (skin.has("bind_shape_matrix")) + { LLMatrix4 mat; - for (U32 j = 0; j < 4; j++) - { - for (U32 k = 0; k < 4; k++) - { - mat.mMatrix[j][k] = skin["bind_shape_matrix"][j*4+k].asReal(); - } - } + for (U32 j = 0; j < 4; j++) + { + for (U32 k = 0; k < 4; k++) + { + mat.mMatrix[j][k] = skin["bind_shape_matrix"][j*4+k].asReal(); + } + } mBindShapeMatrix.loadu(mat); - } - - if (skin.has("alt_inverse_bind_matrix")) - { - for (U32 i = 0; i < skin["alt_inverse_bind_matrix"].size(); ++i) - { - LLMatrix4 mat; - for (U32 j = 0; j < 4; j++) - { - for (U32 k = 0; k < 4; k++) - { - mat.mMatrix[j][k] = skin["alt_inverse_bind_matrix"][i][j*4+k].asReal(); - } - } - - mAlternateBindMatrix.push_back(LLMatrix4a(mat)); - } - } - - if (skin.has("pelvis_offset")) - { - mPelvisOffset = skin["pelvis_offset"].asReal(); - } + } + + if (skin.has("alt_inverse_bind_matrix")) + { + for (U32 i = 0; i < skin["alt_inverse_bind_matrix"].size(); ++i) + { + LLMatrix4 mat; + for (U32 j = 0; j < 4; j++) + { + for (U32 k = 0; k < 4; k++) + { + mat.mMatrix[j][k] = skin["alt_inverse_bind_matrix"][i][j*4+k].asReal(); + } + } + + mAlternateBindMatrix.push_back(LLMatrix4a(mat)); + } + } + + if (skin.has("pelvis_offset")) + { + mPelvisOffset = skin["pelvis_offset"].asReal(); + } if (skin.has("lock_scale_if_joint_position")) { mLockScaleIfJointPosition = skin["lock_scale_if_joint_position"].asBoolean(); } - else - { - mLockScaleIfJointPosition = false; - } + else + { + mLockScaleIfJointPosition = false; + } updateHash(); } LLSD LLMeshSkinInfo::asLLSD(bool include_joints, bool lock_scale_if_joint_position) const { - LLSD ret; - - for (U32 i = 0; i < mJointNames.size(); ++i) - { - ret["joint_names"][i] = mJointNames[i]; - - for (U32 j = 0; j < 4; j++) - { - for (U32 k = 0; k < 4; k++) - { - ret["inverse_bind_matrix"][i][j*4+k] = mInvBindMatrix[i].mMatrix[j][k]; - } - } - } - - for (U32 i = 0; i < 4; i++) - { - for (U32 j = 0; j < 4; j++) - { - ret["bind_shape_matrix"][i*4+j] = mBindShapeMatrix.mMatrix[i][j]; - } - } - - if ( include_joints && mAlternateBindMatrix.size() > 0 ) - { - for (U32 i = 0; i < mJointNames.size(); ++i) - { - for (U32 j = 0; j < 4; j++) - { - for (U32 k = 0; k < 4; k++) - { - ret["alt_inverse_bind_matrix"][i][j*4+k] = mAlternateBindMatrix[i].mMatrix[j][k]; - } - } - } + LLSD ret; + + for (U32 i = 0; i < mJointNames.size(); ++i) + { + ret["joint_names"][i] = mJointNames[i]; + + for (U32 j = 0; j < 4; j++) + { + for (U32 k = 0; k < 4; k++) + { + ret["inverse_bind_matrix"][i][j*4+k] = mInvBindMatrix[i].mMatrix[j][k]; + } + } + } + + for (U32 i = 0; i < 4; i++) + { + for (U32 j = 0; j < 4; j++) + { + ret["bind_shape_matrix"][i*4+j] = mBindShapeMatrix.mMatrix[i][j]; + } + } + + if ( include_joints && mAlternateBindMatrix.size() > 0 ) + { + for (U32 i = 0; i < mJointNames.size(); ++i) + { + for (U32 j = 0; j < 4; j++) + { + for (U32 k = 0; k < 4; k++) + { + ret["alt_inverse_bind_matrix"][i][j*4+k] = mAlternateBindMatrix[i].mMatrix[j][k]; + } + } + } if (lock_scale_if_joint_position) { ret["lock_scale_if_joint_position"] = lock_scale_if_joint_position; } - ret["pelvis_offset"] = mPelvisOffset; - } + ret["pelvis_offset"] = mPelvisOffset; + } - return ret; + return ret; } void LLMeshSkinInfo::updateHash() @@ -1609,13 +1609,13 @@ void LLMeshSkinInfo::updateHash() { hash.update(name); } - - //mJointNums + + //mJointNums hash.update((const void*)mJointNums.data(), sizeof(S32) * mJointNums.size()); - + //mInvBindMatrix F32* src = mInvBindMatrix[0].getF32ptr(); - + for (size_t i = 0, count = mInvBindMatrix.size() * 16; i < count; ++i) { S32 t = llround(src[i] * 10000.f); @@ -1647,108 +1647,108 @@ U32 LLMeshSkinInfo::sizeBytes() const LLModel::Decomposition::Decomposition(LLSD& data) { - fromLLSD(data); + fromLLSD(data); } void LLModel::Decomposition::fromLLSD(LLSD& decomp) { - 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(); - const LLSD::Binary& position = decomp["Positions"].asBinary(); - - U16* p = (U16*) &position[0]; - - mHull.resize(hulls.size()); - - LLVector3 min; - LLVector3 max; - LLVector3 range; - - if (decomp.has("Min")) - { - min.setValue(decomp["Min"]); - max.setValue(decomp["Max"]); - } - else - { - min.set(-0.5f, -0.5f, -0.5f); - max.set(0.5f, 0.5f, 0.5f); - } - - range = max-min; - - for (U32 i = 0; i < hulls.size(); ++i) - { - U16 count = (hulls[i] == 0) ? 256 : hulls[i]; - - std::set<U64> valid; - - //must have at least 4 points - //llassert(count > 3); - - for (U32 j = 0; j < count; ++j) - { - U64 test = (U64) p[0] | ((U64) p[1] << 16) | ((U64) p[2] << 32); - //point must be unique - //llassert(valid.find(test) == valid.end()); - valid.insert(test); - - mHull[i].push_back(LLVector3( - (F32) p[0]/65535.f*range.mV[0]+min.mV[0], - (F32) p[1]/65535.f*range.mV[1]+min.mV[1], - (F32) p[2]/65535.f*range.mV[2]+min.mV[2])); - p += 3; - - - } - - //each hull must contain at least 4 unique points - //llassert(valid.size() > 3); - } - } - - if (decomp.has("BoundingVerts")) - { - const LLSD::Binary& position = decomp["BoundingVerts"].asBinary(); - - U16* p = (U16*) &position[0]; - - LLVector3 min; - LLVector3 max; - LLVector3 range; - - if (decomp.has("Min")) - { - min.setValue(decomp["Min"]); - max.setValue(decomp["Max"]); - } - else - { - min.set(-0.5f, -0.5f, -0.5f); - max.set(0.5f, 0.5f, 0.5f); - } - - range = max-min; - - U16 count = (U16)(position.size()/6); - - for (U32 j = 0; j < count; ++j) - { - mBaseHull.push_back(LLVector3( - (F32) p[0]/65535.f*range.mV[0]+min.mV[0], - (F32) p[1]/65535.f*range.mV[1]+min.mV[1], - (F32) p[2]/65535.f*range.mV[2]+min.mV[2])); - p += 3; - } - } - else - { - //empty base hull mesh to indicate decomposition has been loaded - //but contains no base hull - mBaseHullMesh.clear(); - } + 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(); + const LLSD::Binary& position = decomp["Positions"].asBinary(); + + U16* p = (U16*) &position[0]; + + mHull.resize(hulls.size()); + + LLVector3 min; + LLVector3 max; + LLVector3 range; + + if (decomp.has("Min")) + { + min.setValue(decomp["Min"]); + max.setValue(decomp["Max"]); + } + else + { + min.set(-0.5f, -0.5f, -0.5f); + max.set(0.5f, 0.5f, 0.5f); + } + + range = max-min; + + for (U32 i = 0; i < hulls.size(); ++i) + { + U16 count = (hulls[i] == 0) ? 256 : hulls[i]; + + std::set<U64> valid; + + //must have at least 4 points + //llassert(count > 3); + + for (U32 j = 0; j < count; ++j) + { + U64 test = (U64) p[0] | ((U64) p[1] << 16) | ((U64) p[2] << 32); + //point must be unique + //llassert(valid.find(test) == valid.end()); + valid.insert(test); + + mHull[i].push_back(LLVector3( + (F32) p[0]/65535.f*range.mV[0]+min.mV[0], + (F32) p[1]/65535.f*range.mV[1]+min.mV[1], + (F32) p[2]/65535.f*range.mV[2]+min.mV[2])); + p += 3; + + + } + + //each hull must contain at least 4 unique points + //llassert(valid.size() > 3); + } + } + + if (decomp.has("BoundingVerts")) + { + const LLSD::Binary& position = decomp["BoundingVerts"].asBinary(); + + U16* p = (U16*) &position[0]; + + LLVector3 min; + LLVector3 max; + LLVector3 range; + + if (decomp.has("Min")) + { + min.setValue(decomp["Min"]); + max.setValue(decomp["Max"]); + } + else + { + min.set(-0.5f, -0.5f, -0.5f); + max.set(0.5f, 0.5f, 0.5f); + } + + range = max-min; + + U16 count = (U16)(position.size()/6); + + for (U32 j = 0; j < count; ++j) + { + mBaseHull.push_back(LLVector3( + (F32) p[0]/65535.f*range.mV[0]+min.mV[0], + (F32) p[1]/65535.f*range.mV[1]+min.mV[1], + (F32) p[2]/65535.f*range.mV[2]+min.mV[2])); + p += 3; + } + } + else + { + //empty base hull mesh to indicate decomposition has been loaded + //but contains no base hull + mBaseHullMesh.clear(); + } } U32 LLModel::Decomposition::sizeBytes() const @@ -1777,342 +1777,342 @@ U32 LLModel::Decomposition::sizeBytes() const bool LLModel::Decomposition::hasHullList() const { - return !mHull.empty() ; + return !mHull.empty() ; } LLSD LLModel::Decomposition::asLLSD() const { - LLSD ret; - - if (mBaseHull.empty() && mHull.empty()) - { //nothing to write - return ret; - } - - //write decomposition block - // ["physics_convex"]["HullList"] -- list of 8 bit integers, each entry represents a hull with specified number of points - // ["physics_convex"]["Position"] -- list of 16-bit integers to be decoded to given domain, encoded 3D points - // ["physics_convex"]["BoundingVerts"] -- list of 16-bit integers to be decoded to given domain, encoded 3D points representing a single hull approximation of given shape - - //get minimum and maximum - LLVector3 min; - - if (mHull.empty()) - { - min = mBaseHull[0]; - } - else - { - min = mHull[0][0]; - } - - LLVector3 max = min; - - LLSD::Binary hulls(mHull.size()); - - U32 total = 0; - - for (U32 i = 0; i < mHull.size(); ++i) - { - U32 size = mHull[i].size(); - total += size; - hulls[i] = (U8) (size); - - for (U32 j = 0; j < mHull[i].size(); ++j) - { - update_min_max(min, max, mHull[i][j]); - } - } - - for (U32 i = 0; i < mBaseHull.size(); ++i) - { - update_min_max(min, max, mBaseHull[i]); - } - - ret["Min"] = min.getValue(); - ret["Max"] = max.getValue(); - - LLVector3 range = max-min; - - if (!hulls.empty()) - { - ret["HullList"] = hulls; - } - - if (total > 0) - { - LLSD::Binary p(total*3*2); - - U32 vert_idx = 0; - - for (U32 i = 0; i < mHull.size(); ++i) - { - std::set<U64> valid; - - llassert(!mHull[i].empty()); - - for (U32 j = 0; j < mHull[i].size(); ++j) - { - U64 test = 0; - const F32* src = mHull[i][j].mV; - - for (U32 k = 0; k < 3; k++) - { - //convert to 16-bit normalized across domain - U16 val = (U16) (((src[k]-min.mV[k])/range.mV[k])*65535); - - if(valid.size() < 3) - { - switch (k) - { - case 0: test = test | (U64) val; break; - case 1: test = test | ((U64) val << 16); break; - case 2: test = test | ((U64) val << 32); break; - }; - - valid.insert(test); - } - - U8* buff = (U8*) &val; - //write to binary buffer - p[vert_idx++] = buff[0]; - p[vert_idx++] = buff[1]; - - //makes sure we haven't run off the end of the array - llassert(vert_idx <= p.size()); - } - } - - //must have at least 3 unique points - llassert(valid.size() > 2); - } - - ret["Positions"] = p; - } - - //llassert(!mBaseHull.empty()); - - if (!mBaseHull.empty()) - { - LLSD::Binary p(mBaseHull.size()*3*2); - - U32 vert_idx = 0; - for (U32 j = 0; j < mBaseHull.size(); ++j) - { - const F32* v = mBaseHull[j].mV; - - for (U32 k = 0; k < 3; k++) - { - //convert to 16-bit normalized across domain - U16 val = (U16) (((v[k]-min.mV[k])/range.mV[k])*65535); - - U8* buff = (U8*) &val; - //write to binary buffer - p[vert_idx++] = buff[0]; - p[vert_idx++] = buff[1]; - - if (vert_idx > p.size()) - { - LL_ERRS() << "Index out of bounds" << LL_ENDL; - } - } - } - - ret["BoundingVerts"] = p; - } - - return ret; + LLSD ret; + + if (mBaseHull.empty() && mHull.empty()) + { //nothing to write + return ret; + } + + //write decomposition block + // ["physics_convex"]["HullList"] -- list of 8 bit integers, each entry represents a hull with specified number of points + // ["physics_convex"]["Position"] -- list of 16-bit integers to be decoded to given domain, encoded 3D points + // ["physics_convex"]["BoundingVerts"] -- list of 16-bit integers to be decoded to given domain, encoded 3D points representing a single hull approximation of given shape + + //get minimum and maximum + LLVector3 min; + + if (mHull.empty()) + { + min = mBaseHull[0]; + } + else + { + min = mHull[0][0]; + } + + LLVector3 max = min; + + LLSD::Binary hulls(mHull.size()); + + U32 total = 0; + + for (U32 i = 0; i < mHull.size(); ++i) + { + U32 size = mHull[i].size(); + total += size; + hulls[i] = (U8) (size); + + for (U32 j = 0; j < mHull[i].size(); ++j) + { + update_min_max(min, max, mHull[i][j]); + } + } + + for (U32 i = 0; i < mBaseHull.size(); ++i) + { + update_min_max(min, max, mBaseHull[i]); + } + + ret["Min"] = min.getValue(); + ret["Max"] = max.getValue(); + + LLVector3 range = max-min; + + if (!hulls.empty()) + { + ret["HullList"] = hulls; + } + + if (total > 0) + { + LLSD::Binary p(total*3*2); + + U32 vert_idx = 0; + + for (U32 i = 0; i < mHull.size(); ++i) + { + std::set<U64> valid; + + llassert(!mHull[i].empty()); + + for (U32 j = 0; j < mHull[i].size(); ++j) + { + U64 test = 0; + const F32* src = mHull[i][j].mV; + + for (U32 k = 0; k < 3; k++) + { + //convert to 16-bit normalized across domain + U16 val = (U16) (((src[k]-min.mV[k])/range.mV[k])*65535); + + if(valid.size() < 3) + { + switch (k) + { + case 0: test = test | (U64) val; break; + case 1: test = test | ((U64) val << 16); break; + case 2: test = test | ((U64) val << 32); break; + }; + + valid.insert(test); + } + + U8* buff = (U8*) &val; + //write to binary buffer + p[vert_idx++] = buff[0]; + p[vert_idx++] = buff[1]; + + //makes sure we haven't run off the end of the array + llassert(vert_idx <= p.size()); + } + } + + //must have at least 3 unique points + llassert(valid.size() > 2); + } + + ret["Positions"] = p; + } + + //llassert(!mBaseHull.empty()); + + if (!mBaseHull.empty()) + { + LLSD::Binary p(mBaseHull.size()*3*2); + + U32 vert_idx = 0; + for (U32 j = 0; j < mBaseHull.size(); ++j) + { + const F32* v = mBaseHull[j].mV; + + for (U32 k = 0; k < 3; k++) + { + //convert to 16-bit normalized across domain + U16 val = (U16) (((v[k]-min.mV[k])/range.mV[k])*65535); + + U8* buff = (U8*) &val; + //write to binary buffer + p[vert_idx++] = buff[0]; + p[vert_idx++] = buff[1]; + + if (vert_idx > p.size()) + { + LL_ERRS() << "Index out of bounds" << LL_ENDL; + } + } + } + + ret["BoundingVerts"] = p; + } + + return ret; } void LLModel::Decomposition::merge(const LLModel::Decomposition* rhs) { - if (!rhs) - { - return; - } - - if (mMeshID != rhs->mMeshID) - { - LL_ERRS() << "Attempted to merge with decomposition of some other mesh." << LL_ENDL; - } - - if (mBaseHull.empty()) - { //take base hull and decomposition from rhs - mHull = rhs->mHull; - mBaseHull = rhs->mBaseHull; - mMesh = rhs->mMesh; - mBaseHullMesh = rhs->mBaseHullMesh; - } - - if (mPhysicsShapeMesh.empty()) - { //take physics shape mesh from rhs - mPhysicsShapeMesh = rhs->mPhysicsShapeMesh; - } + if (!rhs) + { + return; + } + + if (mMeshID != rhs->mMeshID) + { + LL_ERRS() << "Attempted to merge with decomposition of some other mesh." << LL_ENDL; + } + + if (mBaseHull.empty()) + { //take base hull and decomposition from rhs + mHull = rhs->mHull; + mBaseHull = rhs->mBaseHull; + mMesh = rhs->mMesh; + mBaseHullMesh = rhs->mBaseHullMesh; + } + + if (mPhysicsShapeMesh.empty()) + { //take physics shape mesh from rhs + mPhysicsShapeMesh = rhs->mPhysicsShapeMesh; + } } bool ll_is_degenerate(const LLVector4a& a, const LLVector4a& b, const LLVector4a& c, F32 tolerance) { - // small area check - { - LLVector4a edge1; edge1.setSub( a, b ); - LLVector4a edge2; edge2.setSub( a, c ); - ////////////////////////////////////////////////////////////////////////// - /// Linden Modified - ////////////////////////////////////////////////////////////////////////// - - // If no one edge is more than 10x longer than any other edge, we weaken - // the tolerance by a factor of 1e-4f. - - LLVector4a edge3; edge3.setSub( c, b ); - const F32 len1sq = edge1.dot3(edge1).getF32(); - const F32 len2sq = edge2.dot3(edge2).getF32(); - const F32 len3sq = edge3.dot3(edge3).getF32(); - bool abOK = (len1sq <= 100.f * len2sq) && (len1sq <= 100.f * len3sq); - bool acOK = (len2sq <= 100.f * len1sq) && (len1sq <= 100.f * len3sq); - bool cbOK = (len3sq <= 100.f * len1sq) && (len1sq <= 100.f * len2sq); - if ( abOK && acOK && cbOK ) - { - tolerance *= 1e-4f; - } - - ////////////////////////////////////////////////////////////////////////// - /// End Modified - ////////////////////////////////////////////////////////////////////////// - - LLVector4a cross; cross.setCross3( edge1, edge2 ); - - LLVector4a edge1b; edge1b.setSub( b, a ); - LLVector4a edge2b; edge2b.setSub( b, c ); - LLVector4a crossb; crossb.setCross3( edge1b, edge2b ); - - if ( ( cross.dot3(cross).getF32() < tolerance ) || ( crossb.dot3(crossb).getF32() < tolerance )) - { - return true; - } - } - - // point triangle distance check - { - LLVector4a Q; Q.setSub(a, b); - LLVector4a R; R.setSub(c, b); - - const F32 QQ = dot3fpu(Q, Q); - const F32 RR = dot3fpu(R, R); - const F32 QR = dot3fpu(R, Q); - - volatile F32 QQRR = QQ * RR; - volatile F32 QRQR = QR * QR; - F32 Det = (QQRR - QRQR); - - if( Det == 0.0f ) - { - return true; - } - } - - return false; + // small area check + { + LLVector4a edge1; edge1.setSub( a, b ); + LLVector4a edge2; edge2.setSub( a, c ); + ////////////////////////////////////////////////////////////////////////// + /// Linden Modified + ////////////////////////////////////////////////////////////////////////// + + // If no one edge is more than 10x longer than any other edge, we weaken + // the tolerance by a factor of 1e-4f. + + LLVector4a edge3; edge3.setSub( c, b ); + const F32 len1sq = edge1.dot3(edge1).getF32(); + const F32 len2sq = edge2.dot3(edge2).getF32(); + const F32 len3sq = edge3.dot3(edge3).getF32(); + bool abOK = (len1sq <= 100.f * len2sq) && (len1sq <= 100.f * len3sq); + bool acOK = (len2sq <= 100.f * len1sq) && (len1sq <= 100.f * len3sq); + bool cbOK = (len3sq <= 100.f * len1sq) && (len1sq <= 100.f * len2sq); + if ( abOK && acOK && cbOK ) + { + tolerance *= 1e-4f; + } + + ////////////////////////////////////////////////////////////////////////// + /// End Modified + ////////////////////////////////////////////////////////////////////////// + + LLVector4a cross; cross.setCross3( edge1, edge2 ); + + LLVector4a edge1b; edge1b.setSub( b, a ); + LLVector4a edge2b; edge2b.setSub( b, c ); + LLVector4a crossb; crossb.setCross3( edge1b, edge2b ); + + if ( ( cross.dot3(cross).getF32() < tolerance ) || ( crossb.dot3(crossb).getF32() < tolerance )) + { + return true; + } + } + + // point triangle distance check + { + LLVector4a Q; Q.setSub(a, b); + LLVector4a R; R.setSub(c, b); + + const F32 QQ = dot3fpu(Q, Q); + const F32 RR = dot3fpu(R, R); + const F32 QR = dot3fpu(R, Q); + + volatile F32 QQRR = QQ * RR; + volatile F32 QRQR = QR * QR; + F32 Det = (QQRR - QRQR); + + if( Det == 0.0f ) + { + return true; + } + } + + return false; } bool validate_face(const LLVolumeFace& face) { - for (U32 i = 0; i < face.mNumIndices; ++i) - { - if (face.mIndices[i] >= face.mNumVertices) - { - LL_WARNS("MESHSKININFO") << "Face has invalid index." << LL_ENDL; - return false; - } - } - - if (face.mNumIndices % 3 != 0 || face.mNumIndices == 0) - { - LL_WARNS("MESHSKININFO") << "Face has invalid number of indices." << LL_ENDL; - return false; - } - - /*const LLVector4a scale(0.5f); - - for (U32 i = 0; i < face.mNumIndices; i+=3) - { - U16 idx1 = face.mIndices[i]; - U16 idx2 = face.mIndices[i+1]; - U16 idx3 = face.mIndices[i+2]; - - LLVector4a v1; v1.setMul(face.mPositions[idx1], scale); - LLVector4a v2; v2.setMul(face.mPositions[idx2], scale); - LLVector4a v3; v3.setMul(face.mPositions[idx3], scale); - - if (ll_is_degenerate(v1,v2,v3)) - { - llwarns << "Degenerate face found!" << LL_ENDL; - return false; - } - }*/ - - return true; + for (U32 i = 0; i < face.mNumIndices; ++i) + { + if (face.mIndices[i] >= face.mNumVertices) + { + LL_WARNS("MESHSKININFO") << "Face has invalid index." << LL_ENDL; + return false; + } + } + + if (face.mNumIndices % 3 != 0 || face.mNumIndices == 0) + { + LL_WARNS("MESHSKININFO") << "Face has invalid number of indices." << LL_ENDL; + return false; + } + + /*const LLVector4a scale(0.5f); + + for (U32 i = 0; i < face.mNumIndices; i+=3) + { + U16 idx1 = face.mIndices[i]; + U16 idx2 = face.mIndices[i+1]; + U16 idx3 = face.mIndices[i+2]; + + LLVector4a v1; v1.setMul(face.mPositions[idx1], scale); + LLVector4a v2; v2.setMul(face.mPositions[idx2], scale); + LLVector4a v3; v3.setMul(face.mPositions[idx3], scale); + + if (ll_is_degenerate(v1,v2,v3)) + { + llwarns << "Degenerate face found!" << LL_ENDL; + return false; + } + }*/ + + return true; } bool validate_model(const LLModel* mdl) { - if (mdl->getNumVolumeFaces() == 0) - { - LL_WARNS("MESHSKININFO") << "Model has no faces!" << LL_ENDL; - return false; - } - - for (S32 i = 0; i < mdl->getNumVolumeFaces(); ++i) - { - if (mdl->getVolumeFace(i).mNumVertices == 0) - { - LL_WARNS("MESHSKININFO") << "Face has no vertices." << LL_ENDL; - return false; - } - - if (mdl->getVolumeFace(i).mNumIndices == 0) - { - LL_WARNS("MESHSKININFO") << "Face has no indices." << LL_ENDL; - return false; - } - - if (!validate_face(mdl->getVolumeFace(i))) - { - return false; - } - } - - return true; + if (mdl->getNumVolumeFaces() == 0) + { + LL_WARNS("MESHSKININFO") << "Model has no faces!" << LL_ENDL; + return false; + } + + for (S32 i = 0; i < mdl->getNumVolumeFaces(); ++i) + { + if (mdl->getVolumeFace(i).mNumVertices == 0) + { + LL_WARNS("MESHSKININFO") << "Face has no vertices." << LL_ENDL; + return false; + } + + if (mdl->getVolumeFace(i).mNumIndices == 0) + { + LL_WARNS("MESHSKININFO") << "Face has no indices." << LL_ENDL; + return false; + } + + if (!validate_face(mdl->getVolumeFace(i))) + { + return false; + } + } + + return true; } LLModelInstance::LLModelInstance(LLSD& data) - : LLModelInstanceBase() + : LLModelInstanceBase() { - 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; - } + 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; +{ + LLSD ret; - ret["mesh_id"] = mModel->mLocalID; - ret["label"] = mLabel; - ret["transform"] = mTransform.getValue(); + 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(); - } + 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; + return ret; } @@ -2122,55 +2122,55 @@ LLImportMaterial::~LLImportMaterial() 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(); + 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; + LLSD ret; - ret["diffuse"]["filename"] = mDiffuseMapFilename; - ret["diffuse"]["label"] = mDiffuseMapLabel; - ret["diffuse"]["color"] = mDiffuseColor.getValue(); - ret["fullbright"] = mFullbright; - ret["binding"] = mBinding; + ret["diffuse"]["filename"] = mDiffuseMapFilename; + ret["diffuse"]["label"] = mDiffuseMapLabel; + ret["diffuse"]["color"] = mDiffuseColor.getValue(); + ret["fullbright"] = mFullbright; + ret["binding"] = mBinding; - return ret; + return ret; } bool LLImportMaterial::operator<(const LLImportMaterial &rhs) const { - if (mDiffuseMapID != rhs.mDiffuseMapID) - { - return mDiffuseMapID < rhs.mDiffuseMapID; - } + if (mDiffuseMapID != rhs.mDiffuseMapID) + { + return mDiffuseMapID < rhs.mDiffuseMapID; + } - if (mDiffuseMapFilename != rhs.mDiffuseMapFilename) - { - return mDiffuseMapFilename < rhs.mDiffuseMapFilename; - } + if (mDiffuseMapFilename != rhs.mDiffuseMapFilename) + { + return mDiffuseMapFilename < rhs.mDiffuseMapFilename; + } - if (mDiffuseMapLabel != rhs.mDiffuseMapLabel) - { - return mDiffuseMapLabel < rhs.mDiffuseMapLabel; - } + if (mDiffuseMapLabel != rhs.mDiffuseMapLabel) + { + return mDiffuseMapLabel < rhs.mDiffuseMapLabel; + } - if (mDiffuseColor != rhs.mDiffuseColor) - { - return mDiffuseColor < rhs.mDiffuseColor; - } + if (mDiffuseColor != rhs.mDiffuseColor) + { + return mDiffuseColor < rhs.mDiffuseColor; + } - if (mBinding != rhs.mBinding) - { - return mBinding < rhs.mBinding; - } + if (mBinding != rhs.mBinding) + { + return mBinding < rhs.mBinding; + } - return mFullbright < rhs.mFullbright; + return mFullbright < rhs.mFullbright; } diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index 040257e00e..657dc31fd2 100644 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -1,25 +1,25 @@ -/** +/** * @file llmodel.h * @brief Model handling class definitions * * $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$ */ @@ -45,26 +45,26 @@ class LLMeshSkinInfo : public LLRefCount { LL_ALIGN_NEW public: - LLMeshSkinInfo(); - LLMeshSkinInfo(LLSD& data); - LLMeshSkinInfo(const LLUUID& mesh_id, LLSD& data); - void fromLLSD(LLSD& data); - LLSD asLLSD(bool include_joints, bool lock_scale_if_joint_position) const; + LLMeshSkinInfo(); + LLMeshSkinInfo(LLSD& data); + LLMeshSkinInfo(const LLUUID& mesh_id, LLSD& data); + void fromLLSD(LLSD& data); + LLSD asLLSD(bool include_joints, bool lock_scale_if_joint_position) const; void updateHash(); U32 sizeBytes() const; - LLUUID mMeshID; - std::vector<std::string> mJointNames; + LLUUID mMeshID; + std::vector<std::string> mJointNames; mutable std::vector<S32> mJointNums; typedef std::vector<LLMatrix4a, boost::alignment::aligned_allocator<LLMatrix4a, 16>> matrix_list_t; - matrix_list_t mInvBindMatrix; + matrix_list_t mInvBindMatrix; // bones/joints position overrides - matrix_list_t mAlternateBindMatrix; + matrix_list_t mAlternateBindMatrix; - LL_ALIGN_16(LLMatrix4a mBindShapeMatrix); + LL_ALIGN_16(LLMatrix4a mBindShapeMatrix); - float mPelvisOffset; + float mPelvisOffset; bool mLockScaleIfJointPosition; bool mInvalidJointsScrubbed; bool mJointNumsInitialized; @@ -77,47 +77,47 @@ class LLModel : public LLVolume LL_ALIGN_NEW public: - enum - { - LOD_IMPOSTOR = 0, - LOD_LOW, - LOD_MEDIUM, - LOD_HIGH, - LOD_PHYSICS, - NUM_LODS - }; - - enum EModelStatus - { - NO_ERRORS = 0, - VERTEX_NUMBER_OVERFLOW, //vertex number is >= 65535. - BAD_ELEMENT, - INVALID_STATUS - } ; - - //convex_hull_decomposition is a vector of convex hulls - //each convex hull is a set of points - typedef std::vector<std::vector<LLVector3> > convex_hull_decomposition; - typedef std::vector<LLVector3> hull; - - class PhysicsMesh - { - public: - std::vector<LLVector3> mPositions; - std::vector<LLVector3> mNormals; + enum + { + LOD_IMPOSTOR = 0, + LOD_LOW, + LOD_MEDIUM, + LOD_HIGH, + LOD_PHYSICS, + NUM_LODS + }; + + enum EModelStatus + { + NO_ERRORS = 0, + VERTEX_NUMBER_OVERFLOW, //vertex number is >= 65535. + BAD_ELEMENT, + INVALID_STATUS + } ; + + //convex_hull_decomposition is a vector of convex hulls + //each convex hull is a set of points + typedef std::vector<std::vector<LLVector3> > convex_hull_decomposition; + typedef std::vector<LLVector3> hull; + + class PhysicsMesh + { + public: + std::vector<LLVector3> mPositions; + std::vector<LLVector3> mNormals; ~PhysicsMesh() {} - void clear() - { - mPositions.clear(); - mNormals.clear(); - } + void clear() + { + mPositions.clear(); + mNormals.clear(); + } - bool empty() const - { - return mPositions.empty(); - } + bool empty() const + { + return mPositions.empty(); + } U32 sizeBytes() const { @@ -126,210 +126,210 @@ public: res += sizeof(LLVector3) * mNormals.size(); return res; } - }; - - class Decomposition - { - public: - Decomposition() { } - Decomposition(LLSD& data); - ~Decomposition() { } - void fromLLSD(LLSD& data); - LLSD asLLSD() const; - bool hasHullList() const; + }; + + class Decomposition + { + public: + Decomposition() { } + Decomposition(LLSD& data); + ~Decomposition() { } + void fromLLSD(LLSD& data); + LLSD asLLSD() const; + bool hasHullList() const; U32 sizeBytes() const; - void merge(const Decomposition* rhs); - - LLUUID mMeshID; - LLModel::convex_hull_decomposition mHull; - LLModel::hull mBaseHull; - - std::vector<LLModel::PhysicsMesh> mMesh; - LLModel::PhysicsMesh mBaseHullMesh; - LLModel::PhysicsMesh mPhysicsShapeMesh; - }; - - LLModel(LLVolumeParams& params, F32 detail); - ~LLModel(); - - bool loadModel(std::istream& is); - bool loadSkinInfo(LLSD& header, std::istream& is); - bool loadDecomposition(LLSD& header, std::istream& is); - - static LLSD writeModel( - std::ostream& ostr, - LLModel* physics, - LLModel* high, - LLModel* medium, - LLModel* low, - LLModel* imposotr, - const LLModel::Decomposition& decomp, - BOOL upload_skin, - BOOL upload_joints, + void merge(const Decomposition* rhs); + + LLUUID mMeshID; + LLModel::convex_hull_decomposition mHull; + LLModel::hull mBaseHull; + + std::vector<LLModel::PhysicsMesh> mMesh; + LLModel::PhysicsMesh mBaseHullMesh; + LLModel::PhysicsMesh mPhysicsShapeMesh; + }; + + LLModel(LLVolumeParams& params, F32 detail); + ~LLModel(); + + bool loadModel(std::istream& is); + bool loadSkinInfo(LLSD& header, std::istream& is); + bool loadDecomposition(LLSD& header, std::istream& is); + + static LLSD writeModel( + std::ostream& ostr, + LLModel* physics, + LLModel* high, + LLModel* medium, + LLModel* low, + LLModel* imposotr, + const LLModel::Decomposition& decomp, + BOOL upload_skin, + BOOL upload_joints, BOOL lock_scale_if_joint_position, - BOOL nowrite = FALSE, - BOOL as_slm = FALSE, - int submodel_id = 0); - - static LLSD writeModelToStream( - std::ostream& ostr, - LLSD& mdl, - BOOL nowrite = FALSE, BOOL as_slm = FALSE); - - void ClearFacesAndMaterials() { mVolumeFaces.clear(); mMaterialList.clear(); } - - std::string getName() const; - EModelStatus getStatus() const {return mStatus;} - static std::string getStatusString(U32 status) ; - - void setNumVolumeFaces(S32 count); - void setVolumeFaceData( - S32 f, - LLStrider<LLVector3> pos, - LLStrider<LLVector3> norm, - LLStrider<LLVector2> tc, - LLStrider<U16> ind, - U32 num_verts, - U32 num_indices); - - void generateNormals(F32 angle_cutoff); - - void addFace(const LLVolumeFace& face); - - void sortVolumeFacesByMaterialName(); - void normalizeVolumeFaces(); - void trimVolumeFacesToSize(U32 new_count = LL_SCULPT_MESH_MAX_FACES, LLVolume::face_list_t* remainder = NULL); + BOOL nowrite = FALSE, + BOOL as_slm = FALSE, + int submodel_id = 0); + + static LLSD writeModelToStream( + std::ostream& ostr, + LLSD& mdl, + BOOL nowrite = FALSE, BOOL as_slm = FALSE); + + void ClearFacesAndMaterials() { mVolumeFaces.clear(); mMaterialList.clear(); } + + std::string getName() const; + EModelStatus getStatus() const {return mStatus;} + static std::string getStatusString(U32 status) ; + + void setNumVolumeFaces(S32 count); + void setVolumeFaceData( + S32 f, + LLStrider<LLVector3> pos, + LLStrider<LLVector3> norm, + LLStrider<LLVector2> tc, + LLStrider<U16> ind, + U32 num_verts, + U32 num_indices); + + void generateNormals(F32 angle_cutoff); + + void addFace(const LLVolumeFace& face); + + void sortVolumeFacesByMaterialName(); + void normalizeVolumeFaces(); + void trimVolumeFacesToSize(U32 new_count = LL_SCULPT_MESH_MAX_FACES, LLVolume::face_list_t* remainder = NULL); void remapVolumeFaces(); - void optimizeVolumeFaces(); - void offsetMesh( const LLVector3& pivotPoint ); - void getNormalizedScaleTranslation(LLVector3& scale_out, LLVector3& translation_out); - LLVector3 getTransformedCenter(const LLMatrix4& mat); - - //reorder face list based on mMaterialList in this and reference so - //order matches that of reference (material ordering touchup) - bool matchMaterialOrder(LLModel* ref, int& refFaceCnt, int& modelFaceCnt ); - bool isMaterialListSubset( LLModel* ref ); - bool needToAddFaces( LLModel* ref, int& refFaceCnt, int& modelFaceCnt ); - - typedef std::vector<std::string> material_list; - - material_list mMaterialList; - - material_list& getMaterialList() { return mMaterialList; } - - //data used for skin weights - class JointWeight - { - public: - S32 mJointIdx; - F32 mWeight; - - JointWeight() - { - mJointIdx = 0; - mWeight = 0.f; - } - - JointWeight(S32 idx, F32 weight) - : mJointIdx(idx), mWeight(weight) - { - } - - bool operator<(const JointWeight& rhs) const - { - if (mWeight == rhs.mWeight) - { - return mJointIdx < rhs.mJointIdx; - } - - return mWeight < rhs.mWeight; - } - - }; - - struct CompareWeightGreater - { - bool operator()(const JointWeight& lhs, const JointWeight& rhs) - { - return rhs < lhs; // strongest = first - } - }; - - - //Are the doubles the same w/in epsilon specified tolerance - bool areEqual( double a, double b ) - { - const float epsilon = 1e-5f; - return (fabs((a - b)) < epsilon) ? true : false ; - } - //Make sure that we return false for any values that are within the tolerance for equivalence - bool jointPositionalLookup( const LLVector3& a, const LLVector3& b ) - { - return ( areEqual( a[0],b[0]) && areEqual( a[1],b[1] ) && areEqual( a[2],b[2]) ) ? true : false; - } - - //copy of position array for this model -- mPosition[idx].mV[X,Y,Z] - std::vector<LLVector3> mPosition; - - //map of positions to skin weights --- mSkinWeights[pos].mV[0..4] == <joint_index>.<weight> - //joint_index corresponds to mJointList - typedef std::vector<JointWeight> weight_list; - typedef std::map<LLVector3, weight_list > weight_map; - weight_map mSkinWeights; - - //get list of weight influences closest to given position - weight_list& getJointInfluences(const LLVector3& pos); - - LLMeshSkinInfo mSkinInfo; - - std::string mRequestedLabel; // name requested in UI, if any. - std::string mLabel; // name computed from dae. - - LLVector3 mNormalizedScale; - LLVector3 mNormalizedTranslation; - - float mPelvisOffset; - // convex hull decomposition - S32 mDecompID; - - void setConvexHullDecomposition( - const convex_hull_decomposition& decomp); - void updateHullCenters(); - - LLVector3 mCenterOfHullCenters; - std::vector<LLVector3> mHullCenter; - U32 mHullPoints; - - //ID for storing this model in a .slm file - S32 mLocalID; - - Decomposition mPhysics; - - EModelStatus mStatus ; + void optimizeVolumeFaces(); + void offsetMesh( const LLVector3& pivotPoint ); + void getNormalizedScaleTranslation(LLVector3& scale_out, LLVector3& translation_out); + LLVector3 getTransformedCenter(const LLMatrix4& mat); + + //reorder face list based on mMaterialList in this and reference so + //order matches that of reference (material ordering touchup) + bool matchMaterialOrder(LLModel* ref, int& refFaceCnt, int& modelFaceCnt ); + bool isMaterialListSubset( LLModel* ref ); + bool needToAddFaces( LLModel* ref, int& refFaceCnt, int& modelFaceCnt ); + + typedef std::vector<std::string> material_list; + + material_list mMaterialList; + + material_list& getMaterialList() { return mMaterialList; } + + //data used for skin weights + class JointWeight + { + public: + S32 mJointIdx; + F32 mWeight; + + JointWeight() + { + mJointIdx = 0; + mWeight = 0.f; + } + + JointWeight(S32 idx, F32 weight) + : mJointIdx(idx), mWeight(weight) + { + } + + bool operator<(const JointWeight& rhs) const + { + if (mWeight == rhs.mWeight) + { + return mJointIdx < rhs.mJointIdx; + } + + return mWeight < rhs.mWeight; + } + + }; + + struct CompareWeightGreater + { + bool operator()(const JointWeight& lhs, const JointWeight& rhs) + { + return rhs < lhs; // strongest = first + } + }; + + + //Are the doubles the same w/in epsilon specified tolerance + bool areEqual( double a, double b ) + { + const float epsilon = 1e-5f; + return (fabs((a - b)) < epsilon) ? true : false ; + } + //Make sure that we return false for any values that are within the tolerance for equivalence + bool jointPositionalLookup( const LLVector3& a, const LLVector3& b ) + { + return ( areEqual( a[0],b[0]) && areEqual( a[1],b[1] ) && areEqual( a[2],b[2]) ) ? true : false; + } + + //copy of position array for this model -- mPosition[idx].mV[X,Y,Z] + std::vector<LLVector3> mPosition; + + //map of positions to skin weights --- mSkinWeights[pos].mV[0..4] == <joint_index>.<weight> + //joint_index corresponds to mJointList + typedef std::vector<JointWeight> weight_list; + typedef std::map<LLVector3, weight_list > weight_map; + weight_map mSkinWeights; + + //get list of weight influences closest to given position + weight_list& getJointInfluences(const LLVector3& pos); + + LLMeshSkinInfo mSkinInfo; + + std::string mRequestedLabel; // name requested in UI, if any. + std::string mLabel; // name computed from dae. + + LLVector3 mNormalizedScale; + LLVector3 mNormalizedTranslation; + + float mPelvisOffset; + // convex hull decomposition + S32 mDecompID; + + void setConvexHullDecomposition( + const convex_hull_decomposition& decomp); + void updateHullCenters(); + + LLVector3 mCenterOfHullCenters; + std::vector<LLVector3> mHullCenter; + U32 mHullPoints; + + //ID for storing this model in a .slm file + S32 mLocalID; + + Decomposition mPhysics; + + EModelStatus mStatus ; // A model/object can only have 8 faces, spillover faces will // be moved to new model/object and assigned a submodel id. - int mSubmodelID; + int mSubmodelID; } LL_ALIGN_POSTFIX(16); -typedef std::vector<LLPointer<LLModel> > model_list; -typedef std::queue<LLPointer<LLModel> > model_queue; +typedef std::vector<LLPointer<LLModel> > model_list; +typedef std::queue<LLPointer<LLModel> > model_queue; class LLModelMaterialBase { -public: - std::string mDiffuseMapFilename; - std::string mDiffuseMapLabel; - std::string mBinding; - LLColor4 mDiffuseColor; - bool mFullbright; - - LLModelMaterialBase() - : mFullbright(false) - { - mDiffuseColor.set(1,1,1,1); - } +public: + std::string mDiffuseMapFilename; + std::string mDiffuseMapLabel; + std::string mBinding; + LLColor4 mDiffuseColor; + bool mFullbright; + + LLModelMaterialBase() + : mFullbright(false) + { + mDiffuseColor.set(1,1,1,1); + } }; class LLImportMaterial : public LLModelMaterialBase @@ -337,26 +337,26 @@ class LLImportMaterial : public LLModelMaterialBase public: friend class LLMeshUploadThread; friend class LLModelPreview; - + bool operator<(const LLImportMaterial ¶ms) const; - + LLImportMaterial() : LLModelMaterialBase() { mDiffuseColor.set(1,1,1,1); } - + LLImportMaterial(LLSD& data); virtual ~LLImportMaterial(); - + LLSD asLLSD(); - - const LLUUID& getDiffuseMap() const { return mDiffuseMapID; } - void setDiffuseMap(const LLUUID& texId) { mDiffuseMapID = texId; } - + + const LLUUID& getDiffuseMap() const { return mDiffuseMapID; } + void setDiffuseMap(const LLUUID& texId) { mDiffuseMapID = texId; } + protected: - - LLUUID mDiffuseMapID; - void* mOpaqueData; // allow refs to viewer/platform-specific structs for each material + + LLUUID mDiffuseMapID; + void* mOpaqueData; // allow refs to viewer/platform-specific structs for each material // currently only stores an LLPointer< LLViewerFetchedTexture > > to // maintain refs to textures associated with each material for free // ref counting. @@ -367,22 +367,22 @@ typedef std::map<std::string, LLImportMaterial> material_map; class LLModelInstanceBase { public: - LLPointer<LLModel> mModel; - LLPointer<LLModel> mLOD[LLModel::NUM_LODS]; - LLUUID mMeshID; + LLPointer<LLModel> mModel; + LLPointer<LLModel> mLOD[LLModel::NUM_LODS]; + LLUUID mMeshID; - LLMatrix4 mTransform; - material_map mMaterial; + LLMatrix4 mTransform; + material_map mMaterial; - LLModelInstanceBase(LLModel* model, LLMatrix4& transform, material_map& materials) - : mModel(model), mTransform(transform), mMaterial(materials) - { - } + LLModelInstanceBase(LLModel* model, LLMatrix4& transform, material_map& materials) + : mModel(model), mTransform(transform), mMaterial(materials) + { + } - LLModelInstanceBase() - : mModel(NULL) - { - } + LLModelInstanceBase() + : mModel(NULL) + { + } virtual ~LLModelInstanceBase() { @@ -399,31 +399,31 @@ typedef std::vector<LLModelInstanceBase> model_instance_list; class LLModelInstance : public LLModelInstanceBase { public: - std::string mLabel; - LLUUID mMeshID; - S32 mLocalMeshID; + std::string mLabel; + LLUUID mMeshID; + S32 mLocalMeshID; - LLModelInstance(LLModel* model, const std::string& label, LLMatrix4& transform, material_map& materials) - : LLModelInstanceBase(model, transform, materials), mLabel(label) - { - mLocalMeshID = -1; - } + LLModelInstance(LLModel* model, const std::string& label, LLMatrix4& transform, material_map& materials) + : LLModelInstanceBase(model, transform, materials), mLabel(label) + { + mLocalMeshID = -1; + } - LLModelInstance(LLSD& data); + LLModelInstance(LLSD& data); ~LLModelInstance() {} - LLSD asLLSD(); + LLSD asLLSD(); }; #define LL_DEGENERACY_TOLERANCE 1e-7f inline F32 dot3fpu(const LLVector4a& a, const LLVector4a& b) { - volatile F32 p0 = a[0] * b[0]; - volatile F32 p1 = a[1] * b[1]; - volatile F32 p2 = a[2] * b[2]; - return p0 + p1 + p2; + volatile F32 p0 = a[0] * b[0]; + volatile F32 p1 = a[1] * b[1]; + volatile F32 p2 = a[2] * b[2]; + return p0 + p1 + p2; } bool ll_is_degenerate(const LLVector4a& a, const LLVector4a& b, const LLVector4a& c, F32 tolerance = LL_DEGENERACY_TOLERANCE); diff --git a/indra/llprimitive/llmodelloader.cpp b/indra/llprimitive/llmodelloader.cpp index fc826727e1..4120352b40 100644 --- a/indra/llprimitive/llmodelloader.cpp +++ b/indra/llprimitive/llmodelloader.cpp @@ -39,82 +39,82 @@ std::list<LLModelLoader*> LLModelLoader::sActiveLoaderList; void stretch_extents(LLModel* model, LLMatrix4a& mat, LLVector4a& min, LLVector4a& max, BOOL& first_transform) { - LLVector4a box[] = - { - LLVector4a(-1, 1,-1), - LLVector4a(-1, 1, 1), - LLVector4a(-1,-1,-1), - LLVector4a(-1,-1, 1), - LLVector4a( 1, 1,-1), - LLVector4a( 1, 1, 1), - LLVector4a( 1,-1,-1), - LLVector4a( 1,-1, 1), - }; - - for (S32 j = 0; j < model->getNumVolumeFaces(); ++j) - { - const LLVolumeFace& face = model->getVolumeFace(j); - - LLVector4a center; - center.setAdd(face.mExtents[0], face.mExtents[1]); - center.mul(0.5f); - LLVector4a size; - size.setSub(face.mExtents[1],face.mExtents[0]); - size.mul(0.5f); - - for (U32 i = 0; i < 8; i++) - { - LLVector4a t; - t.setMul(size, box[i]); - t.add(center); - - LLVector4a v; - - mat.affineTransform(t, v); - - if (first_transform) - { - first_transform = FALSE; - min = max = v; - } - else - { - update_min_max(min, max, v); - } - } - } + LLVector4a box[] = + { + LLVector4a(-1, 1,-1), + LLVector4a(-1, 1, 1), + LLVector4a(-1,-1,-1), + LLVector4a(-1,-1, 1), + LLVector4a( 1, 1,-1), + LLVector4a( 1, 1, 1), + LLVector4a( 1,-1,-1), + LLVector4a( 1,-1, 1), + }; + + for (S32 j = 0; j < model->getNumVolumeFaces(); ++j) + { + const LLVolumeFace& face = model->getVolumeFace(j); + + LLVector4a center; + center.setAdd(face.mExtents[0], face.mExtents[1]); + center.mul(0.5f); + LLVector4a size; + size.setSub(face.mExtents[1],face.mExtents[0]); + size.mul(0.5f); + + for (U32 i = 0; i < 8; i++) + { + LLVector4a t; + t.setMul(size, box[i]); + t.add(center); + + LLVector4a v; + + mat.affineTransform(t, v); + + if (first_transform) + { + first_transform = FALSE; + min = max = v; + } + else + { + update_min_max(min, max, v); + } + } + } } void stretch_extents(LLModel* model, LLMatrix4& mat, LLVector3& min, LLVector3& max, BOOL& first_transform) { - LLVector4a mina, maxa; - LLMatrix4a mata; + LLVector4a mina, maxa; + LLMatrix4a mata; - mata.loadu(mat); - mina.load3(min.mV); - maxa.load3(max.mV); + mata.loadu(mat); + mina.load3(min.mV); + maxa.load3(max.mV); - stretch_extents(model, mata, mina, maxa, first_transform); + stretch_extents(model, mata, mina, maxa, first_transform); - min.set(mina.getF32ptr()); - max.set(maxa.getF32ptr()); + min.set(mina.getF32ptr()); + max.set(maxa.getF32ptr()); } //----------------------------------------------------------------------------- // LLModelLoader //----------------------------------------------------------------------------- LLModelLoader::LLModelLoader( - std::string filename, - S32 lod, - load_callback_t load_cb, - joint_lookup_func_t joint_lookup_func, - texture_load_func_t texture_load_func, - state_callback_t state_cb, - void* opaque_userdata, - JointTransformMap& jointTransformMap, - JointNameSet& jointsFromNodes, + std::string filename, + S32 lod, + load_callback_t load_cb, + joint_lookup_func_t joint_lookup_func, + texture_load_func_t texture_load_func, + state_callback_t state_cb, + void* opaque_userdata, + JointTransformMap& jointTransformMap, + JointNameSet& jointsFromNodes, JointMap& legalJointNamesMap, - U32 maxJointsPerMesh) + U32 maxJointsPerMesh) : mJointList( jointTransformMap ) , mJointsFromNode( jointsFromNodes ) , LLThread("Model Loader") @@ -135,23 +135,23 @@ LLModelLoader::LLModelLoader( , mCacheOnlyHitIfRigged(false) , mMaxJointsPerMesh(maxJointsPerMesh) , mJointMap(legalJointNamesMap) -{ - assert_main_thread(); - sActiveLoaderList.push_back(this) ; - mWarningsArray = LLSD::emptyArray(); +{ + assert_main_thread(); + sActiveLoaderList.push_back(this) ; + mWarningsArray = LLSD::emptyArray(); } LLModelLoader::~LLModelLoader() { - assert_main_thread(); - sActiveLoaderList.remove(this); + assert_main_thread(); + sActiveLoaderList.remove(this); } void LLModelLoader::run() { - mWarningsArray.clear(); - doLoadModel(); - doOnIdleOneTime(boost::bind(&LLModelLoader::loadModelCallback,this)); + mWarningsArray.clear(); + doLoadModel(); + doOnIdleOneTime(boost::bind(&LLModelLoader::loadModelCallback,this)); } // static @@ -174,194 +174,194 @@ bool LLModelLoader::getSLMFilename(const std::string& model_filename, std::strin bool LLModelLoader::doLoadModel() { - //first, look for a .slm file of the same name that was modified later - //than the specified model file + //first, look for a .slm file of the same name that was modified later + //than the specified model file - if (mTrySLM) - { + if (mTrySLM) + { std::string slm_filename; if (getSLMFilename(mFilename, slm_filename)) { - llstat slm_status; - if (LLFile::stat(slm_filename, &slm_status) == 0) - { //slm file exists - llstat model_file_status; - if (LLFile::stat(mFilename, &model_file_status) != 0 || - model_file_status.st_mtime < slm_status.st_mtime) - { - if (loadFromSLM(slm_filename)) - { //slm successfully loaded, if this fails, fall through and - //try loading from model file - - mLod = -1; //successfully loading from an slm implicitly sets all - //LoDs - return true; - } - } - } - } - } - - return OpenFile(mFilename); + llstat slm_status; + if (LLFile::stat(slm_filename, &slm_status) == 0) + { //slm file exists + llstat model_file_status; + if (LLFile::stat(mFilename, &model_file_status) != 0 || + model_file_status.st_mtime < slm_status.st_mtime) + { + if (loadFromSLM(slm_filename)) + { //slm successfully loaded, if this fails, fall through and + //try loading from model file + + mLod = -1; //successfully loading from an slm implicitly sets all + //LoDs + return true; + } + } + } + } + } + + return OpenFile(mFilename); } void LLModelLoader::setLoadState(U32 state) { - mStateCallback(state, mOpaqueData); + mStateCallback(state, mOpaqueData); } bool LLModelLoader::loadFromSLM(const std::string& filename) -{ - //only need to populate mScene with data from slm - llstat stat; - - if (LLFile::stat(filename, &stat)) - { //file does not exist - return false; - } - - S32 file_size = (S32) stat.st_size; - - llifstream ifstream(filename.c_str(), std::ifstream::in | std::ifstream::binary); - LLSD data; - LLSDSerialize::fromBinary(data, ifstream, file_size); - ifstream.close(); - - //build model list for each LoD - model_list model[LLModel::NUM_LODS]; - - if (data["version"].asInteger() != SLM_SUPPORTED_VERSION) - { //unsupported version - return false; - } - - LLSD& mesh = data["mesh"]; - - LLVolumeParams volume_params; - volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE); - - for (S32 lod = 0; lod < LLModel::NUM_LODS; ++lod) - { - for (U32 i = 0; i < mesh.size(); ++i) - { - std::stringstream str(mesh[i].asString()); - LLPointer<LLModel> loaded_model = new LLModel(volume_params, (F32) lod); - if (loaded_model->loadModel(str)) - { - loaded_model->mLocalID = i; - model[lod].push_back(loaded_model); - - if (lod == LLModel::LOD_HIGH) - { - if (!loaded_model->mSkinInfo.mJointNames.empty()) - { - //check to see if rig is valid - critiqueRigForUploadApplicability( loaded_model->mSkinInfo.mJointNames ); - } - else if (mCacheOnlyHitIfRigged) - { - return false; - } - } - } - } - } - - if (model[LLModel::LOD_HIGH].empty()) - { //failed to load high lod - return false; - } - - //load instance list - model_instance_list instance_list; - - LLSD& instance = data["instance"]; - - for (U32 i = 0; i < instance.size(); ++i) - { - //deserialize instance list - instance_list.push_back(LLModelInstance(instance[i])); - - //match up model instance pointers - S32 idx = instance_list[i].mLocalMeshID; - std::string instance_label = instance_list[i].mLabel; - - for (U32 lod = 0; lod < LLModel::NUM_LODS; ++lod) - { - if (!model[lod].empty()) - { - if (idx >= model[lod].size()) - { - if (model[lod].size()) - { - instance_list[i].mLOD[lod] = model[lod][0]; - } - else - { - instance_list[i].mLOD[lod] = NULL; - } - continue; - } - - if (model[lod][idx] - && model[lod][idx]->mLabel.empty() - && !instance_label.empty()) - { - // restore model names - std::string name = instance_label; - switch (lod) - { - case LLModel::LOD_IMPOSTOR: name += "_LOD0"; break; - case LLModel::LOD_LOW: name += "_LOD1"; break; - case LLModel::LOD_MEDIUM: name += "_LOD2"; break; - case LLModel::LOD_PHYSICS: name += "_PHYS"; break; - case LLModel::LOD_HIGH: break; - } - model[lod][idx]->mLabel = name; - } - - instance_list[i].mLOD[lod] = model[lod][idx]; - } - } - - if (!instance_list[i].mModel) - instance_list[i].mModel = model[LLModel::LOD_HIGH][idx]; - } - - // Set name for UI to use - std::string name = data["name"]; - if (!name.empty()) - { - model[LLModel::LOD_HIGH][0]->mRequestedLabel = name; - } - - - //convert instance_list to mScene - mFirstTransform = TRUE; - for (U32 i = 0; i < instance_list.size(); ++i) - { - LLModelInstance& cur_instance = instance_list[i]; - mScene[cur_instance.mTransform].push_back(cur_instance); - stretch_extents(cur_instance.mModel, cur_instance.mTransform, mExtents[0], mExtents[1], mFirstTransform); - } - - setLoadState( DONE ); - - return true; +{ + //only need to populate mScene with data from slm + llstat stat; + + if (LLFile::stat(filename, &stat)) + { //file does not exist + return false; + } + + S32 file_size = (S32) stat.st_size; + + llifstream ifstream(filename.c_str(), std::ifstream::in | std::ifstream::binary); + LLSD data; + LLSDSerialize::fromBinary(data, ifstream, file_size); + ifstream.close(); + + //build model list for each LoD + model_list model[LLModel::NUM_LODS]; + + if (data["version"].asInteger() != SLM_SUPPORTED_VERSION) + { //unsupported version + return false; + } + + LLSD& mesh = data["mesh"]; + + LLVolumeParams volume_params; + volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE); + + for (S32 lod = 0; lod < LLModel::NUM_LODS; ++lod) + { + for (U32 i = 0; i < mesh.size(); ++i) + { + std::stringstream str(mesh[i].asString()); + LLPointer<LLModel> loaded_model = new LLModel(volume_params, (F32) lod); + if (loaded_model->loadModel(str)) + { + loaded_model->mLocalID = i; + model[lod].push_back(loaded_model); + + if (lod == LLModel::LOD_HIGH) + { + if (!loaded_model->mSkinInfo.mJointNames.empty()) + { + //check to see if rig is valid + critiqueRigForUploadApplicability( loaded_model->mSkinInfo.mJointNames ); + } + else if (mCacheOnlyHitIfRigged) + { + return false; + } + } + } + } + } + + if (model[LLModel::LOD_HIGH].empty()) + { //failed to load high lod + return false; + } + + //load instance list + model_instance_list instance_list; + + LLSD& instance = data["instance"]; + + for (U32 i = 0; i < instance.size(); ++i) + { + //deserialize instance list + instance_list.push_back(LLModelInstance(instance[i])); + + //match up model instance pointers + S32 idx = instance_list[i].mLocalMeshID; + std::string instance_label = instance_list[i].mLabel; + + for (U32 lod = 0; lod < LLModel::NUM_LODS; ++lod) + { + if (!model[lod].empty()) + { + if (idx >= model[lod].size()) + { + if (model[lod].size()) + { + instance_list[i].mLOD[lod] = model[lod][0]; + } + else + { + instance_list[i].mLOD[lod] = NULL; + } + continue; + } + + if (model[lod][idx] + && model[lod][idx]->mLabel.empty() + && !instance_label.empty()) + { + // restore model names + std::string name = instance_label; + switch (lod) + { + case LLModel::LOD_IMPOSTOR: name += "_LOD0"; break; + case LLModel::LOD_LOW: name += "_LOD1"; break; + case LLModel::LOD_MEDIUM: name += "_LOD2"; break; + case LLModel::LOD_PHYSICS: name += "_PHYS"; break; + case LLModel::LOD_HIGH: break; + } + model[lod][idx]->mLabel = name; + } + + instance_list[i].mLOD[lod] = model[lod][idx]; + } + } + + if (!instance_list[i].mModel) + instance_list[i].mModel = model[LLModel::LOD_HIGH][idx]; + } + + // Set name for UI to use + std::string name = data["name"]; + if (!name.empty()) + { + model[LLModel::LOD_HIGH][0]->mRequestedLabel = name; + } + + + //convert instance_list to mScene + mFirstTransform = TRUE; + for (U32 i = 0; i < instance_list.size(); ++i) + { + LLModelInstance& cur_instance = instance_list[i]; + mScene[cur_instance.mTransform].push_back(cur_instance); + stretch_extents(cur_instance.mModel, cur_instance.mTransform, mExtents[0], mExtents[1], mFirstTransform); + } + + setLoadState( DONE ); + + return true; } //static bool LLModelLoader::isAlive(LLModelLoader* loader) { - if(!loader) - { - return false ; - } - - std::list<LLModelLoader*>::iterator iter = sActiveLoaderList.begin() ; - for(; iter != sActiveLoaderList.end() && (*iter) != loader; ++iter) ; - - return *iter == loader ; + if(!loader) + { + return false ; + } + + std::list<LLModelLoader*>::iterator iter = sActiveLoaderList.begin() ; + for(; iter != sActiveLoaderList.end() && (*iter) != loader; ++iter) ; + + return *iter == loader ; } void LLModelLoader::loadModelCallback() @@ -371,18 +371,18 @@ void LLModelLoader::loadModelCallback() mLoadCallback(mScene, mModelList, mLod, mOpaqueData); } - while (!isStopped()) - { //wait until this thread is stopped before deleting self - apr_sleep(100); - } + while (!isStopped()) + { //wait until this thread is stopped before deleting self + apr_sleep(100); + } - //double check if "this" is valid before deleting it, in case it is aborted during running. - if(!isAlive(this)) - { - return ; - } + //double check if "this" is valid before deleting it, in case it is aborted during running. + if(!isAlive(this)) + { + return ; + } - delete this; + delete this; } //----------------------------------------------------------------------------- @@ -390,28 +390,28 @@ void LLModelLoader::loadModelCallback() //----------------------------------------------------------------------------- void LLModelLoader::critiqueRigForUploadApplicability( const std::vector<std::string> &jointListFromAsset ) { - //Determines the following use cases for a rig: - //1. It is suitable for upload with skin weights & joint positions, or - //2. It is suitable for upload as standard av with just skin weights - - bool isJointPositionUploadOK = isRigSuitableForJointPositionUpload( jointListFromAsset ); - U32 legacy_rig_flags = determineRigLegacyFlags( jointListFromAsset ); + //Determines the following use cases for a rig: + //1. It is suitable for upload with skin weights & joint positions, or + //2. It is suitable for upload as standard av with just skin weights + + bool isJointPositionUploadOK = isRigSuitableForJointPositionUpload( jointListFromAsset ); + U32 legacy_rig_flags = determineRigLegacyFlags( jointListFromAsset ); - // It's OK that both could end up being true. + // It's OK that both could end up being true. // Both start out as true and are forced to false if any mesh in // the model file is not vald by that criterion. Note that a file // can contain multiple meshes. - if ( !isJointPositionUploadOK ) - { + if ( !isJointPositionUploadOK ) + { // This starts out true, becomes false if false for any loaded - // mesh. - setRigValidForJointPositionUpload( false ); - } + // mesh. + setRigValidForJointPositionUpload( false ); + } - legacy_rig_flags |= getLegacyRigFlags(); - // This starts as 0, changes if any loaded mesh has issues - setLegacyRigFlags(legacy_rig_flags); + legacy_rig_flags |= getLegacyRigFlags(); + // This starts as 0, changes if any loaded mesh has issues + setLegacyRigFlags(legacy_rig_flags); } @@ -420,11 +420,11 @@ void LLModelLoader::critiqueRigForUploadApplicability( const std::vector<std::st //----------------------------------------------------------------------------- U32 LLModelLoader::determineRigLegacyFlags( const std::vector<std::string> &jointListFromAsset ) { - //No joints in asset - if ( jointListFromAsset.size() == 0 ) - { - return false; - } + //No joints in asset + if ( jointListFromAsset.size() == 0 ) + { + return false; + } // Too many joints in asset if (jointListFromAsset.size()>mMaxJointsPerMesh) @@ -478,28 +478,28 @@ bool LLModelLoader::isRigSuitableForJointPositionUpload( const std::vector<std:: //called in the main thread void LLModelLoader::loadTextures() { - BOOL is_paused = isPaused() ; - pause() ; //pause the loader - - for(scene::iterator iter = mScene.begin(); iter != mScene.end(); ++iter) - { - for(U32 i = 0 ; i < iter->second.size(); i++) - { - for(std::map<std::string, LLImportMaterial>::iterator j = iter->second[i].mMaterial.begin(); - j != iter->second[i].mMaterial.end(); ++j) - { - LLImportMaterial& material = j->second; - - if(!material.mDiffuseMapFilename.empty()) - { - mNumOfFetchingTextures += mTextureLoadFunc(material, mOpaqueData); - } - } - } - } - - if(!is_paused) - { - unpause() ; - } + BOOL is_paused = isPaused() ; + pause() ; //pause the loader + + for(scene::iterator iter = mScene.begin(); iter != mScene.end(); ++iter) + { + for(U32 i = 0 ; i < iter->second.size(); i++) + { + for(std::map<std::string, LLImportMaterial>::iterator j = iter->second[i].mMaterial.begin(); + j != iter->second[i].mMaterial.end(); ++j) + { + LLImportMaterial& material = j->second; + + if(!material.mDiffuseMapFilename.empty()) + { + mNumOfFetchingTextures += mTextureLoadFunc(material, mOpaqueData); + } + } + } + } + + if(!is_paused) + { + unpause() ; + } } diff --git a/indra/llprimitive/llmodelloader.h b/indra/llprimitive/llmodelloader.h index fbc74554a0..402c29c260 100644 --- a/indra/llprimitive/llmodelloader.h +++ b/indra/llprimitive/llmodelloader.h @@ -5,21 +5,21 @@ * $LicenseInfo:firstyear=2004&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$ */ @@ -34,13 +34,13 @@ class LLJoint; -typedef std::map<std::string, LLMatrix4> JointTransformMap; -typedef std::map<std::string, LLMatrix4>::iterator JointTransformMapIt; -typedef std::map<std::string, std::string> JointMap; -typedef std::deque<std::string> JointNameSet; +typedef std::map<std::string, LLMatrix4> JointTransformMap; +typedef std::map<std::string, LLMatrix4>::iterator JointTransformMapIt; +typedef std::map<std::string, std::string> JointMap; +typedef std::deque<std::string> JointNameSet; -const S32 SLM_SUPPORTED_VERSION = 3; -const S32 NUM_LOD = 4; +const S32 SLM_SUPPORTED_VERSION = 3; +const S32 NUM_LOD = 4; const U32 LEGACY_RIG_OK = 0; const U32 LEGACY_RIG_FLAG_TOO_MANY_JOINTS = 1; @@ -50,169 +50,169 @@ class LLModelLoader : public LLThread { public: - typedef std::map<std::string, LLImportMaterial> material_map; - typedef std::vector<LLPointer<LLModel > > model_list; - typedef std::vector<LLModelInstance> model_instance_list; - typedef std::map<LLMatrix4, model_instance_list > scene; - - // Callback with loaded model data and loaded LoD - // - typedef boost::function<void (scene&,model_list&,S32,void*) > load_callback_t; - - // Function to provide joint lookup by name - // (within preview avi skeleton, for example) - // - typedef boost::function<LLJoint* (const std::string&,void*) > joint_lookup_func_t; - - // Func to load and associate material with all it's textures, - // returned value is the number of textures loaded - // intentionally non-const so func can modify material to - // store platform-specific data - // - typedef boost::function<U32 (LLImportMaterial&,void*) > texture_load_func_t; - - // Callback to inform client of state changes - // during loading process (errors will be reported - // as state changes here as well) - // - typedef boost::function<void (U32,void*) > state_callback_t; - - typedef enum - { - STARTING = 0, - READING_FILE, - CREATING_FACES, - GENERATING_VERTEX_BUFFERS, - GENERATING_LOD, - DONE, - WARNING_BIND_SHAPE_ORIENTATION, - ERROR_PARSING, //basically loading failed - ERROR_MATERIALS, - ERROR_PASSWORD_REQUIRED, - ERROR_NEED_MORE_MEMORY, - ERROR_INVALID_FILE, - ERROR_LOADER_SETUP, - ERROR_INVALID_PARAMETERS, - ERROR_OUT_OF_RANGE, - ERROR_FILE_VERSION_INVALID, - ERROR_MODEL // this error should always be last in this list, error code is passed as ERROR_MODEL+error_code - } eLoadState; - - U32 mState; - std::string mFilename; - - S32 mLod; - - LLMatrix4 mTransform; - BOOL mFirstTransform; - LLVector3 mExtents[2]; - - bool mTrySLM; - bool mCacheOnlyHitIfRigged; // ignore cached SLM if it does not contain rig info (and we want rig info) - - model_list mModelList; - scene mScene; - - typedef std::queue<LLPointer<LLModel> > model_queue; - - //queue of models that need a physics rep - model_queue mPhysicsQ; - - //map of avatar joints as named in COLLADA assets to internal joint names - JointMap mJointMap; - JointTransformMap& mJointList; - JointNameSet& mJointsFromNode; - U32 mMaxJointsPerMesh; - - LLModelLoader( - std::string filename, - S32 lod, - LLModelLoader::load_callback_t load_cb, - LLModelLoader::joint_lookup_func_t joint_lookup_func, - LLModelLoader::texture_load_func_t texture_load_func, - LLModelLoader::state_callback_t state_cb, - void* opaque_userdata, - JointTransformMap& jointTransformMap, - JointNameSet& jointsFromNodes, + typedef std::map<std::string, LLImportMaterial> material_map; + typedef std::vector<LLPointer<LLModel > > model_list; + typedef std::vector<LLModelInstance> model_instance_list; + typedef std::map<LLMatrix4, model_instance_list > scene; + + // Callback with loaded model data and loaded LoD + // + typedef boost::function<void (scene&,model_list&,S32,void*) > load_callback_t; + + // Function to provide joint lookup by name + // (within preview avi skeleton, for example) + // + typedef boost::function<LLJoint* (const std::string&,void*) > joint_lookup_func_t; + + // Func to load and associate material with all it's textures, + // returned value is the number of textures loaded + // intentionally non-const so func can modify material to + // store platform-specific data + // + typedef boost::function<U32 (LLImportMaterial&,void*) > texture_load_func_t; + + // Callback to inform client of state changes + // during loading process (errors will be reported + // as state changes here as well) + // + typedef boost::function<void (U32,void*) > state_callback_t; + + typedef enum + { + STARTING = 0, + READING_FILE, + CREATING_FACES, + GENERATING_VERTEX_BUFFERS, + GENERATING_LOD, + DONE, + WARNING_BIND_SHAPE_ORIENTATION, + ERROR_PARSING, //basically loading failed + ERROR_MATERIALS, + ERROR_PASSWORD_REQUIRED, + ERROR_NEED_MORE_MEMORY, + ERROR_INVALID_FILE, + ERROR_LOADER_SETUP, + ERROR_INVALID_PARAMETERS, + ERROR_OUT_OF_RANGE, + ERROR_FILE_VERSION_INVALID, + ERROR_MODEL // this error should always be last in this list, error code is passed as ERROR_MODEL+error_code + } eLoadState; + + U32 mState; + std::string mFilename; + + S32 mLod; + + LLMatrix4 mTransform; + BOOL mFirstTransform; + LLVector3 mExtents[2]; + + bool mTrySLM; + bool mCacheOnlyHitIfRigged; // ignore cached SLM if it does not contain rig info (and we want rig info) + + model_list mModelList; + scene mScene; + + typedef std::queue<LLPointer<LLModel> > model_queue; + + //queue of models that need a physics rep + model_queue mPhysicsQ; + + //map of avatar joints as named in COLLADA assets to internal joint names + JointMap mJointMap; + JointTransformMap& mJointList; + JointNameSet& mJointsFromNode; + U32 mMaxJointsPerMesh; + + LLModelLoader( + std::string filename, + S32 lod, + LLModelLoader::load_callback_t load_cb, + LLModelLoader::joint_lookup_func_t joint_lookup_func, + LLModelLoader::texture_load_func_t texture_load_func, + LLModelLoader::state_callback_t state_cb, + void* opaque_userdata, + JointTransformMap& jointTransformMap, + JointNameSet& jointsFromNodes, JointMap& legalJointNamesMap, - U32 maxJointsPerMesh); - virtual ~LLModelLoader() ; + U32 maxJointsPerMesh); + virtual ~LLModelLoader() ; - virtual void setNoNormalize() { mNoNormalize = true; } - virtual void setNoOptimize() { mNoOptimize = true; } + virtual void setNoNormalize() { mNoNormalize = true; } + virtual void setNoOptimize() { mNoOptimize = true; } - virtual void run(); + virtual void run(); static bool getSLMFilename(const std::string& model_filename, std::string& slm_filename); - // Will try SLM or derived class OpenFile as appropriate - // - virtual bool doLoadModel(); + // Will try SLM or derived class OpenFile as appropriate + // + virtual bool doLoadModel(); + + // Derived classes need to provide their parsing of files here + // + virtual bool OpenFile(const std::string& filename) = 0; + + bool loadFromSLM(const std::string& filename); - // Derived classes need to provide their parsing of files here - // - virtual bool OpenFile(const std::string& filename) = 0; + void loadModelCallback(); + void loadTextures() ; //called in the main thread. + void setLoadState(U32 state); - bool loadFromSLM(const std::string& filename); - - void loadModelCallback(); - void loadTextures() ; //called in the main thread. - void setLoadState(U32 state); - - S32 mNumOfFetchingTextures ; //updated in the main thread - bool areTexturesReady() { return !mNumOfFetchingTextures; } //called in the main thread. + S32 mNumOfFetchingTextures ; //updated in the main thread + bool areTexturesReady() { return !mNumOfFetchingTextures; } //called in the main thread. - bool verifyCount( int expected, int result ); + bool verifyCount( int expected, int result ); - //Determines the viability of an asset to be used as an avatar rig (w or w/o joint upload caps) - void critiqueRigForUploadApplicability( const std::vector<std::string> &jointListFromAsset ); + //Determines the viability of an asset to be used as an avatar rig (w or w/o joint upload caps) + void critiqueRigForUploadApplicability( const std::vector<std::string> &jointListFromAsset ); - //Determines if a rig is a legacy from the joint list - U32 determineRigLegacyFlags( const std::vector<std::string> &jointListFromAsset ); + //Determines if a rig is a legacy from the joint list + U32 determineRigLegacyFlags( const std::vector<std::string> &jointListFromAsset ); - //Determines if a rig is suitable for upload - bool isRigSuitableForJointPositionUpload( const std::vector<std::string> &jointListFromAsset ); + //Determines if a rig is suitable for upload + bool isRigSuitableForJointPositionUpload( const std::vector<std::string> &jointListFromAsset ); - const bool isRigValidForJointPositionUpload( void ) const { return mRigValidJointUpload; } - void setRigValidForJointPositionUpload( bool rigValid ) { mRigValidJointUpload = rigValid; } + const bool isRigValidForJointPositionUpload( void ) const { return mRigValidJointUpload; } + void setRigValidForJointPositionUpload( bool rigValid ) { mRigValidJointUpload = rigValid; } - const bool isLegacyRigValid(void) const { return mLegacyRigFlags == 0; } - U32 getLegacyRigFlags() const { return mLegacyRigFlags; } - void setLegacyRigFlags( U32 rigFlags ) { mLegacyRigFlags = rigFlags; } + const bool isLegacyRigValid(void) const { return mLegacyRigFlags == 0; } + U32 getLegacyRigFlags() const { return mLegacyRigFlags; } + void setLegacyRigFlags( U32 rigFlags ) { mLegacyRigFlags = rigFlags; } - //----------------------------------------------------------------------------- - // isNodeAJoint() - //----------------------------------------------------------------------------- - bool isNodeAJoint(const char* name) - { - return name != NULL && mJointMap.find(name) != mJointMap.end(); - } + //----------------------------------------------------------------------------- + // isNodeAJoint() + //----------------------------------------------------------------------------- + bool isNodeAJoint(const char* name) + { + return name != NULL && mJointMap.find(name) != mJointMap.end(); + } - const LLSD logOut() const { return mWarningsArray; } - void clearLog() { mWarningsArray.clear(); } + const LLSD logOut() const { return mWarningsArray; } + void clearLog() { mWarningsArray.clear(); } protected: - LLModelLoader::load_callback_t mLoadCallback; - LLModelLoader::joint_lookup_func_t mJointLookupFunc; - LLModelLoader::texture_load_func_t mTextureLoadFunc; - LLModelLoader::state_callback_t mStateCallback; - void* mOpaqueData; + LLModelLoader::load_callback_t mLoadCallback; + LLModelLoader::joint_lookup_func_t mJointLookupFunc; + LLModelLoader::texture_load_func_t mTextureLoadFunc; + LLModelLoader::state_callback_t mStateCallback; + void* mOpaqueData; - bool mRigValidJointUpload; - U32 mLegacyRigFlags; + bool mRigValidJointUpload; + U32 mLegacyRigFlags; - bool mNoNormalize; - bool mNoOptimize; + bool mNoNormalize; + bool mNoOptimize; - JointTransformMap mJointTransformMap; + JointTransformMap mJointTransformMap; - LLSD mWarningsArray; // preview floater will pull logs from here + LLSD mWarningsArray; // preview floater will pull logs from here - static std::list<LLModelLoader*> sActiveLoaderList; - static bool isAlive(LLModelLoader* loader) ; + static std::list<LLModelLoader*> sActiveLoaderList; + static bool isAlive(LLModelLoader* loader) ; }; class LLMatrix4a; void stretch_extents(LLModel* model, LLMatrix4a& mat, LLVector4a& min, LLVector4a& max, BOOL& first_transform); diff --git a/indra/llprimitive/llprimlinkinfo.h b/indra/llprimitive/llprimlinkinfo.h index bee25975f1..67e40fd5be 100644 --- a/indra/llprimitive/llprimlinkinfo.h +++ b/indra/llprimitive/llprimlinkinfo.h @@ -1,4 +1,4 @@ -/** +/** * @file llprimlinkinfo.h * @author andrew@lindenlab.com * @brief A template for determining which prims in a set are linkable @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2007&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$ */ @@ -42,8 +42,8 @@ #include "llsphere.h" -const F32 MAX_OBJECT_SPAN = 54.f; // max distance from outside edge of an object to the farthest edge -const F32 OBJECT_SPAN_BONUS = 2.f; // infinitesimally small prims can always link up to this distance +const F32 MAX_OBJECT_SPAN = 54.f; // max distance from outside edge of an object to the farthest edge +const F32 OBJECT_SPAN_BONUS = 2.f; // infinitesimally small prims can always link up to this distance const S32 MAX_PRIMS_PER_OBJECT = 256; @@ -51,125 +51,125 @@ template < typename DATA_TYPE > class LLPrimLinkInfo { public: - LLPrimLinkInfo(); - LLPrimLinkInfo( DATA_TYPE data, const LLSphere& sphere ); - ~LLPrimLinkInfo(); + LLPrimLinkInfo(); + LLPrimLinkInfo( DATA_TYPE data, const LLSphere& sphere ); + ~LLPrimLinkInfo(); - void set( DATA_TYPE data, const LLSphere& sphere ); - void append( DATA_TYPE data, const LLSphere& sphere ); - void getData( std::list< DATA_TYPE >& data_list ) const; - F32 getDiameter() const; - LLVector3 getCenter() const; + void set( DATA_TYPE data, const LLSphere& sphere ); + void append( DATA_TYPE data, const LLSphere& sphere ); + void getData( std::list< DATA_TYPE >& data_list ) const; + F32 getDiameter() const; + LLVector3 getCenter() const; - // returns 'true' if this info can link with other_info - bool canLink( const LLPrimLinkInfo< DATA_TYPE >& other_info ); + // returns 'true' if this info can link with other_info + bool canLink( const LLPrimLinkInfo< DATA_TYPE >& other_info ); - S32 getPrimCount() const { return mDataMap.size(); } + S32 getPrimCount() const { return mDataMap.size(); } - void mergeLinkableSet( typename std::list< LLPrimLinkInfo < DATA_TYPE > >& unlinked ); + void mergeLinkableSet( typename std::list< LLPrimLinkInfo < DATA_TYPE > >& unlinked ); - void transform(const LLVector3& position, const LLQuaternion& rotation); + void transform(const LLVector3& position, const LLQuaternion& rotation); private: - // returns number of merges made - S32 merge(LLPrimLinkInfo< DATA_TYPE >& other_info); + // returns number of merges made + S32 merge(LLPrimLinkInfo< DATA_TYPE >& other_info); - // returns number of collapses made - static S32 collapse(typename std::list< LLPrimLinkInfo < DATA_TYPE > >& unlinked ); + // returns number of collapses made + static S32 collapse(typename std::list< LLPrimLinkInfo < DATA_TYPE > >& unlinked ); - void computeBoundingSphere(); + void computeBoundingSphere(); - // Internal utility to encapsulate the link rules - F32 get_max_linkable_span(const LLSphere& first, const LLSphere& second); - F32 get_span(const LLSphere& first, const LLSphere& second); + // Internal utility to encapsulate the link rules + F32 get_max_linkable_span(const LLSphere& first, const LLSphere& second); + F32 get_span(const LLSphere& first, const LLSphere& second); private: - std::map< DATA_TYPE, LLSphere > mDataMap; - LLSphere mBoundingSphere; + std::map< DATA_TYPE, LLSphere > mDataMap; + LLSphere mBoundingSphere; }; template < typename DATA_TYPE > LLPrimLinkInfo< DATA_TYPE >::LLPrimLinkInfo() -: mBoundingSphere( LLVector3(0.f, 0.f, 0.f), 0.f ) +: mBoundingSphere( LLVector3(0.f, 0.f, 0.f), 0.f ) { } template < typename DATA_TYPE > LLPrimLinkInfo< DATA_TYPE >::LLPrimLinkInfo( DATA_TYPE data, const LLSphere& sphere) -: mBoundingSphere(sphere) +: mBoundingSphere(sphere) { - mDataMap[data] = sphere; + mDataMap[data] = sphere; } template < typename DATA_TYPE > LLPrimLinkInfo< DATA_TYPE >::~LLPrimLinkInfo() { - mDataMap.clear(); + mDataMap.clear(); } template < typename DATA_TYPE > void LLPrimLinkInfo< DATA_TYPE>::set( DATA_TYPE data, const LLSphere& sphere ) { - if (!mDataMap.empty()) - { - mDataMap.clear(); - } - mDataMap[data] = sphere; - mBoundingSphere = sphere; + if (!mDataMap.empty()) + { + mDataMap.clear(); + } + mDataMap[data] = sphere; + mBoundingSphere = sphere; } template < typename DATA_TYPE > void LLPrimLinkInfo< DATA_TYPE>::append( DATA_TYPE data, const LLSphere& sphere ) { - mDataMap[data] = sphere; - if (!mBoundingSphere.contains(sphere)) - { - computeBoundingSphere(); - } + mDataMap[data] = sphere; + if (!mBoundingSphere.contains(sphere)) + { + computeBoundingSphere(); + } } template < typename DATA_TYPE > void LLPrimLinkInfo< DATA_TYPE >::getData( std::list< DATA_TYPE >& data_list) const { - typename std::map< DATA_TYPE, LLSphere >::const_iterator map_itr; - for (map_itr = mDataMap.begin(); map_itr != mDataMap.end(); ++map_itr) - { - data_list.push_back(map_itr->first); - } + typename std::map< DATA_TYPE, LLSphere >::const_iterator map_itr; + for (map_itr = mDataMap.begin(); map_itr != mDataMap.end(); ++map_itr) + { + data_list.push_back(map_itr->first); + } } template < typename DATA_TYPE > F32 LLPrimLinkInfo< DATA_TYPE >::getDiameter() const -{ - return 2.f * mBoundingSphere.getRadius(); +{ + return 2.f * mBoundingSphere.getRadius(); } template < typename DATA_TYPE > LLVector3 LLPrimLinkInfo< DATA_TYPE >::getCenter() const -{ - return mBoundingSphere.getCenter(); +{ + return mBoundingSphere.getCenter(); } template < typename DATA_TYPE > F32 LLPrimLinkInfo< DATA_TYPE >::get_max_linkable_span(const LLSphere& first, const LLSphere& second) { - F32 max_span = 3.f * (first.getRadius() + second.getRadius()) + OBJECT_SPAN_BONUS; - if (max_span > MAX_OBJECT_SPAN) - { - max_span = MAX_OBJECT_SPAN; - } + F32 max_span = 3.f * (first.getRadius() + second.getRadius()) + OBJECT_SPAN_BONUS; + if (max_span > MAX_OBJECT_SPAN) + { + max_span = MAX_OBJECT_SPAN; + } - return max_span; + return max_span; } template < typename DATA_TYPE > F32 LLPrimLinkInfo< DATA_TYPE >::get_span(const LLSphere& first, const LLSphere& second) { - F32 span = (first.getCenter() - second.getCenter()).length() - + first.getRadius() + second.getRadius(); - return span; + F32 span = (first.getCenter() - second.getCenter()).length() + + first.getRadius() + second.getRadius(); + return span; } // static @@ -177,90 +177,90 @@ F32 LLPrimLinkInfo< DATA_TYPE >::get_span(const LLSphere& first, const LLSphere& template < typename DATA_TYPE > bool LLPrimLinkInfo< DATA_TYPE >::canLink(const LLPrimLinkInfo& other_info) { - F32 max_span = get_max_linkable_span(mBoundingSphere, other_info.mBoundingSphere); - - F32 span = get_span(mBoundingSphere, other_info.mBoundingSphere); - - if (span <= max_span) - { - // The entire other_info fits inside the max span. - return TRUE; - } - else if (span > max_span + 2.f * other_info.mBoundingSphere.getRadius()) - { - // there is no way any piece of other_info could link with this one - return FALSE; - } - - // there may be a piece of other_info that is linkable - typename std::map< DATA_TYPE, LLSphere >::const_iterator map_itr; - for (map_itr = other_info.mDataMap.begin(); map_itr != other_info.mDataMap.end(); ++map_itr) - { - const LLSphere& other_sphere = (*map_itr).second; - max_span = get_max_linkable_span(mBoundingSphere, other_sphere); - - span = get_span(mBoundingSphere, other_sphere); - - if (span <= max_span) - { - // found one piece that is linkable - return TRUE; - } - } - return FALSE; + F32 max_span = get_max_linkable_span(mBoundingSphere, other_info.mBoundingSphere); + + F32 span = get_span(mBoundingSphere, other_info.mBoundingSphere); + + if (span <= max_span) + { + // The entire other_info fits inside the max span. + return TRUE; + } + else if (span > max_span + 2.f * other_info.mBoundingSphere.getRadius()) + { + // there is no way any piece of other_info could link with this one + return FALSE; + } + + // there may be a piece of other_info that is linkable + typename std::map< DATA_TYPE, LLSphere >::const_iterator map_itr; + for (map_itr = other_info.mDataMap.begin(); map_itr != other_info.mDataMap.end(); ++map_itr) + { + const LLSphere& other_sphere = (*map_itr).second; + max_span = get_max_linkable_span(mBoundingSphere, other_sphere); + + span = get_span(mBoundingSphere, other_sphere); + + if (span <= max_span) + { + // found one piece that is linkable + return TRUE; + } + } + return FALSE; } -// merges elements of 'unlinked' +// merges elements of 'unlinked' // returns number of links made (NOT final prim count, NOR linked prim count) -// and removes any linkable infos from 'unlinked' +// and removes any linkable infos from 'unlinked' template < typename DATA_TYPE > void LLPrimLinkInfo< DATA_TYPE >::mergeLinkableSet(std::list< LLPrimLinkInfo< DATA_TYPE > > & unlinked) { - bool linked_something = true; - while (linked_something) - { - linked_something = false; - - typename std::list< LLPrimLinkInfo< DATA_TYPE > >::iterator other_itr = unlinked.begin(); - while ( other_itr != unlinked.end() - && getPrimCount() < MAX_PRIMS_PER_OBJECT ) - { - S32 merge_count = merge(*other_itr); - if (merge_count > 0) - { - linked_something = true; - } - if (0 == (*other_itr).getPrimCount()) - { - unlinked.erase(other_itr++); - } - else - { - ++other_itr; - } - } - if (!linked_something - && unlinked.size() > 1) - { - S32 collapse_count = collapse(unlinked); - if (collapse_count > 0) - { - linked_something = true; - } - } - } + bool linked_something = true; + while (linked_something) + { + linked_something = false; + + typename std::list< LLPrimLinkInfo< DATA_TYPE > >::iterator other_itr = unlinked.begin(); + while ( other_itr != unlinked.end() + && getPrimCount() < MAX_PRIMS_PER_OBJECT ) + { + S32 merge_count = merge(*other_itr); + if (merge_count > 0) + { + linked_something = true; + } + if (0 == (*other_itr).getPrimCount()) + { + unlinked.erase(other_itr++); + } + else + { + ++other_itr; + } + } + if (!linked_something + && unlinked.size() > 1) + { + S32 collapse_count = collapse(unlinked); + if (collapse_count > 0) + { + linked_something = true; + } + } + } } // transforms all of the spheres into a new reference frame template < typename DATA_TYPE > void LLPrimLinkInfo< DATA_TYPE >::transform(const LLVector3& position, const LLQuaternion& rotation) { - typename std::map< DATA_TYPE, LLSphere >::iterator map_itr; - for (map_itr = mDataMap.begin(); map_itr != mDataMap.end(); ++map_itr) - { - (*map_itr).second.setCenter((*map_itr).second.getCenter() * rotation + position); - } - mBoundingSphere.setCenter(mBoundingSphere.getCenter() * rotation + position); + typename std::map< DATA_TYPE, LLSphere >::iterator map_itr; + for (map_itr = mDataMap.begin(); map_itr != mDataMap.end(); ++map_itr) + { + (*map_itr).second.setCenter((*map_itr).second.getCenter() * rotation + position); + } + mBoundingSphere.setCenter(mBoundingSphere.getCenter() * rotation + position); } // private @@ -268,124 +268,124 @@ void LLPrimLinkInfo< DATA_TYPE >::transform(const LLVector3& position, const LLQ template < typename DATA_TYPE > S32 LLPrimLinkInfo< DATA_TYPE >::merge(LLPrimLinkInfo& other_info) { - S32 link_count = 0; - -// F32 other_radius = other_info.mBoundingSphere.getRadius(); -// other_info.computeBoundingSphere(); -// if ( other_radius != other_info.mBoundingSphere.getRadius() ) -// { -// LL_INFOS() << "Other bounding sphere changed!!" << LL_ENDL; -// } - -// F32 this_radius = mBoundingSphere.getRadius(); -// computeBoundingSphere(); -// if ( this_radius != mBoundingSphere.getRadius() ) -// { -// LL_INFOS() << "This bounding sphere changed!!" << LL_ENDL; -// } - - - F32 max_span = get_max_linkable_span(mBoundingSphere, other_info.mBoundingSphere); - - // F32 center_dist = (mBoundingSphere.getCenter() - other_info.mBoundingSphere.getCenter()).length(); - // LL_INFOS() << "objects are " << center_dist << "m apart" << LL_ENDL; - F32 span = get_span(mBoundingSphere, other_info.mBoundingSphere); - - F32 span_limit = max_span + (2.f * other_info.mBoundingSphere.getRadius()); - if (span > span_limit) - { - // there is no way any piece of other_info could link with this one - // LL_INFOS() << "span too large: " << span << " vs. " << span_limit << LL_ENDL; - return 0; - } - - bool completely_linkable = (span <= max_span) ? true : false; - - typename std::map< DATA_TYPE, LLSphere >::iterator map_itr = other_info.mDataMap.begin(); - while (map_itr != other_info.mDataMap.end() - && getPrimCount() < MAX_PRIMS_PER_OBJECT ) - { - DATA_TYPE other_data = (*map_itr).first; - LLSphere& other_sphere = (*map_itr).second; - - if (!completely_linkable) - { - max_span = get_max_linkable_span(mBoundingSphere, other_sphere); - - F32 span = get_span(mBoundingSphere, other_sphere); - - if (span > max_span) - { - ++map_itr; - continue; - } - } - - mDataMap[other_data] = other_sphere; - ++link_count; - - if (!mBoundingSphere.contains(other_sphere) ) - { - computeBoundingSphere(); - } - - // remove from the other info - other_info.mDataMap.erase(map_itr++); - } - - if (link_count > 0 && other_info.getPrimCount() > 0) - { - other_info.computeBoundingSphere(); - } - return link_count; + S32 link_count = 0; + +// F32 other_radius = other_info.mBoundingSphere.getRadius(); +// other_info.computeBoundingSphere(); +// if ( other_radius != other_info.mBoundingSphere.getRadius() ) +// { +// LL_INFOS() << "Other bounding sphere changed!!" << LL_ENDL; +// } + +// F32 this_radius = mBoundingSphere.getRadius(); +// computeBoundingSphere(); +// if ( this_radius != mBoundingSphere.getRadius() ) +// { +// LL_INFOS() << "This bounding sphere changed!!" << LL_ENDL; +// } + + + F32 max_span = get_max_linkable_span(mBoundingSphere, other_info.mBoundingSphere); + + // F32 center_dist = (mBoundingSphere.getCenter() - other_info.mBoundingSphere.getCenter()).length(); + // LL_INFOS() << "objects are " << center_dist << "m apart" << LL_ENDL; + F32 span = get_span(mBoundingSphere, other_info.mBoundingSphere); + + F32 span_limit = max_span + (2.f * other_info.mBoundingSphere.getRadius()); + if (span > span_limit) + { + // there is no way any piece of other_info could link with this one + // LL_INFOS() << "span too large: " << span << " vs. " << span_limit << LL_ENDL; + return 0; + } + + bool completely_linkable = (span <= max_span) ? true : false; + + typename std::map< DATA_TYPE, LLSphere >::iterator map_itr = other_info.mDataMap.begin(); + while (map_itr != other_info.mDataMap.end() + && getPrimCount() < MAX_PRIMS_PER_OBJECT ) + { + DATA_TYPE other_data = (*map_itr).first; + LLSphere& other_sphere = (*map_itr).second; + + if (!completely_linkable) + { + max_span = get_max_linkable_span(mBoundingSphere, other_sphere); + + F32 span = get_span(mBoundingSphere, other_sphere); + + if (span > max_span) + { + ++map_itr; + continue; + } + } + + mDataMap[other_data] = other_sphere; + ++link_count; + + if (!mBoundingSphere.contains(other_sphere) ) + { + computeBoundingSphere(); + } + + // remove from the other info + other_info.mDataMap.erase(map_itr++); + } + + if (link_count > 0 && other_info.getPrimCount() > 0) + { + other_info.computeBoundingSphere(); + } + return link_count; } // links any linkable elements of unlinked template < typename DATA_TYPE > S32 LLPrimLinkInfo< DATA_TYPE >::collapse(std::list< LLPrimLinkInfo< DATA_TYPE > > & unlinked) -{ - S32 link_count = 0; - bool linked_something = true; - while (linked_something) - { - linked_something = false; - - typename std::list< LLPrimLinkInfo< DATA_TYPE > >::iterator this_itr = unlinked.begin(); - typename std::list< LLPrimLinkInfo< DATA_TYPE > >::iterator other_itr = this_itr; - ++other_itr; - while ( other_itr != unlinked.end() ) - - { - S32 merge_count = (*this_itr).merge(*other_itr); - if (merge_count > 0) - { - linked_something = true; - link_count += merge_count; - } - if (0 == (*other_itr).getPrimCount()) - { - unlinked.erase(other_itr++); - } - else - { - ++other_itr; - } - } - } - return link_count; +{ + S32 link_count = 0; + bool linked_something = true; + while (linked_something) + { + linked_something = false; + + typename std::list< LLPrimLinkInfo< DATA_TYPE > >::iterator this_itr = unlinked.begin(); + typename std::list< LLPrimLinkInfo< DATA_TYPE > >::iterator other_itr = this_itr; + ++other_itr; + while ( other_itr != unlinked.end() ) + + { + S32 merge_count = (*this_itr).merge(*other_itr); + if (merge_count > 0) + { + linked_something = true; + link_count += merge_count; + } + if (0 == (*other_itr).getPrimCount()) + { + unlinked.erase(other_itr++); + } + else + { + ++other_itr; + } + } + } + return link_count; } template < typename DATA_TYPE > void LLPrimLinkInfo< DATA_TYPE >::computeBoundingSphere() -{ - std::vector< LLSphere > sphere_list; - typename std::map< DATA_TYPE, LLSphere >::const_iterator map_itr; - for (map_itr = mDataMap.begin(); map_itr != mDataMap.end(); ++map_itr) - { - sphere_list.push_back(map_itr->second); - } - mBoundingSphere = LLSphere::getBoundingSphere(sphere_list); +{ + std::vector< LLSphere > sphere_list; + typename std::map< DATA_TYPE, LLSphere >::const_iterator map_itr; + for (map_itr = mDataMap.begin(); map_itr != mDataMap.end(); ++map_itr) + { + sphere_list.push_back(map_itr->second); + } + mBoundingSphere = LLSphere::getBoundingSphere(sphere_list); } diff --git a/indra/llprimitive/llprimtexturelist.cpp b/indra/llprimitive/llprimtexturelist.cpp index f4f08248b8..ce4df843ea 100644 --- a/indra/llprimitive/llprimtexturelist.cpp +++ b/indra/llprimitive/llprimtexturelist.cpp @@ -1,25 +1,25 @@ -/** +/** * @file lltexturelist.cpp * @brief LLPrimTextureList (virtual) base class * * $LicenseInfo:firstyear=2008&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$ */ @@ -30,50 +30,50 @@ #include "llmaterialid.h" #include "lltextureentry.h" -// static +// static //int (TMyClass::*pt2Member)(float, char, char) = NULL; // C++ LLTextureEntry* (*LLPrimTextureList::sNewTextureEntryCallback)() = &(LLTextureEntry::newTextureEntry); // static void LLPrimTextureList::setNewTextureEntryCallback( LLTextureEntry* (*callback)() ) { - if (callback) - { - LLPrimTextureList::sNewTextureEntryCallback = callback; - } - else - { - LLPrimTextureList::sNewTextureEntryCallback = &(LLTextureEntry::newTextureEntry); - } + if (callback) + { + LLPrimTextureList::sNewTextureEntryCallback = callback; + } + else + { + LLPrimTextureList::sNewTextureEntryCallback = &(LLTextureEntry::newTextureEntry); + } } -// static +// static // call this to get a new texture entry LLTextureEntry* LLPrimTextureList::newTextureEntry() { - return (*sNewTextureEntryCallback)(); + return (*sNewTextureEntryCallback)(); } LLPrimTextureList::LLPrimTextureList() { } -// virtual +// virtual LLPrimTextureList::~LLPrimTextureList() { - clear(); + clear(); } void LLPrimTextureList::clear() { - texture_list_t::iterator itr = mEntryList.begin(); - while (itr != mEntryList.end()) - { - delete (*itr); - (*itr) = NULL; - ++itr; - } - mEntryList.clear(); + texture_list_t::iterator itr = mEntryList.begin(); + while (itr != mEntryList.end()) + { + delete (*itr); + (*itr) = NULL; + ++itr; + } + mEntryList.clear(); } @@ -82,34 +82,34 @@ void LLPrimTextureList::clear() // this is somewhat expensive, so it must be called explicitly void LLPrimTextureList::copy(const LLPrimTextureList& other_list) { - // compare the sizes - S32 this_size = mEntryList.size(); - S32 other_size = other_list.mEntryList.size(); - - if (this_size > other_size) - { - // remove the extra entries - for (S32 index = this_size; index > other_size; --index) - { - delete mEntryList[index-1]; - } - mEntryList.resize(other_size); - this_size = other_size; - } - - S32 index = 0; - // copy for the entries that already exist - for ( ; index < this_size; ++index) - { - delete mEntryList[index]; - mEntryList[index] = other_list.getTexture(index)->newCopy(); - } - - // add new entires if needed - for ( ; index < other_size; ++index) - { - mEntryList.push_back( other_list.getTexture(index)->newCopy() ); - } + // compare the sizes + S32 this_size = mEntryList.size(); + S32 other_size = other_list.mEntryList.size(); + + if (this_size > other_size) + { + // remove the extra entries + for (S32 index = this_size; index > other_size; --index) + { + delete mEntryList[index-1]; + } + mEntryList.resize(other_size); + this_size = other_size; + } + + S32 index = 0; + // copy for the entries that already exist + for ( ; index < this_size; ++index) + { + delete mEntryList[index]; + mEntryList[index] = other_list.getTexture(index)->newCopy(); + } + + // add new entires if needed + for ( ; index < other_size; ++index) + { + mEntryList.push_back( other_list.getTexture(index)->newCopy() ); + } } // clears current copies @@ -117,329 +117,329 @@ void LLPrimTextureList::copy(const LLPrimTextureList& other_list) // clears other_list void LLPrimTextureList::take(LLPrimTextureList& other_list) { - clear(); - mEntryList = other_list.mEntryList; - other_list.mEntryList.clear(); + clear(); + mEntryList = other_list.mEntryList; + other_list.mEntryList.clear(); } -// virtual +// virtual // copies LLTextureEntry 'te' // returns TEM_CHANGE_TEXTURE if successful, otherwise TEM_CHANGE_NONE S32 LLPrimTextureList::copyTexture(const U8 index, const LLTextureEntry& te) { - if (S32(index) >= mEntryList.size()) - { - S32 current_size = mEntryList.size(); - LL_WARNS() << "ignore copy of index = " << S32(index) << " into texture entry list of size = " << current_size << LL_ENDL; - return TEM_CHANGE_NONE; - } - - // we're changing an existing entry - llassert(mEntryList[index]); - delete (mEntryList[index]); - if (&te) - { - mEntryList[index] = te.newCopy(); - } - else - { - mEntryList[index] = LLPrimTextureList::newTextureEntry(); - } - return TEM_CHANGE_TEXTURE; -} - -// virtual + if (S32(index) >= mEntryList.size()) + { + S32 current_size = mEntryList.size(); + LL_WARNS() << "ignore copy of index = " << S32(index) << " into texture entry list of size = " << current_size << LL_ENDL; + return TEM_CHANGE_NONE; + } + + // we're changing an existing entry + llassert(mEntryList[index]); + delete (mEntryList[index]); + if (&te) + { + mEntryList[index] = te.newCopy(); + } + else + { + mEntryList[index] = LLPrimTextureList::newTextureEntry(); + } + return TEM_CHANGE_TEXTURE; +} + +// virtual // takes ownership of LLTextureEntry* 'te' // returns TEM_CHANGE_TEXTURE if successful, otherwise TEM_CHANGE_NONE // IMPORTANT! -- if you use this function you must check the return value S32 LLPrimTextureList::takeTexture(const U8 index, LLTextureEntry* te) { - if (S32(index) >= mEntryList.size()) - { - return TEM_CHANGE_NONE; - } + if (S32(index) >= mEntryList.size()) + { + return TEM_CHANGE_NONE; + } - // we're changing an existing entry - llassert(mEntryList[index]); - delete (mEntryList[index]); - mEntryList[index] = te; - return TEM_CHANGE_TEXTURE; + // we're changing an existing entry + llassert(mEntryList[index]); + delete (mEntryList[index]); + mEntryList[index] = te; + return TEM_CHANGE_TEXTURE; } // returns pointer to texture at 'index' slot LLTextureEntry* LLPrimTextureList::getTexture(const U8 index) const { - if (index < mEntryList.size()) - { - return mEntryList[index]; - } - return NULL; + if (index < mEntryList.size()) + { + return mEntryList[index]; + } + return NULL; } -//virtual +//virtual //S32 setTE(const U8 index, const LLTextureEntry& te) = 0; S32 LLPrimTextureList::setID(const U8 index, const LLUUID& id) { - if (index < mEntryList.size()) - { - return mEntryList[index]->setID(id); - } - return TEM_CHANGE_NONE; + if (index < mEntryList.size()) + { + return mEntryList[index]->setID(id); + } + return TEM_CHANGE_NONE; } S32 LLPrimTextureList::setColor(const U8 index, const LLColor3& color) { - if (index < mEntryList.size()) - { - return mEntryList[index]->setColor(color); - } - return TEM_CHANGE_NONE; + if (index < mEntryList.size()) + { + return mEntryList[index]->setColor(color); + } + return TEM_CHANGE_NONE; } S32 LLPrimTextureList::setColor(const U8 index, const LLColor4& color) { - if (index < mEntryList.size()) - { - return mEntryList[index]->setColor(color); - } - return TEM_CHANGE_NONE; + if (index < mEntryList.size()) + { + return mEntryList[index]->setColor(color); + } + return TEM_CHANGE_NONE; } S32 LLPrimTextureList::setAlpha(const U8 index, const F32 alpha) { - if (index < mEntryList.size()) - { - return mEntryList[index]->setAlpha(alpha); - } - return TEM_CHANGE_NONE; + if (index < mEntryList.size()) + { + return mEntryList[index]->setAlpha(alpha); + } + return TEM_CHANGE_NONE; } S32 LLPrimTextureList::setScale(const U8 index, const F32 s, const F32 t) { - if (index < mEntryList.size()) - { - return mEntryList[index]->setScale(s, t); - } - return TEM_CHANGE_NONE; + if (index < mEntryList.size()) + { + return mEntryList[index]->setScale(s, t); + } + return TEM_CHANGE_NONE; } S32 LLPrimTextureList::setScaleS(const U8 index, const F32 s) { - if (index < mEntryList.size()) - { - return mEntryList[index]->setScaleS(s); - } - return TEM_CHANGE_NONE; + if (index < mEntryList.size()) + { + return mEntryList[index]->setScaleS(s); + } + return TEM_CHANGE_NONE; } S32 LLPrimTextureList::setScaleT(const U8 index, const F32 t) { - if (index < mEntryList.size()) - { - return mEntryList[index]->setScaleT(t); - } - return TEM_CHANGE_NONE; + if (index < mEntryList.size()) + { + return mEntryList[index]->setScaleT(t); + } + return TEM_CHANGE_NONE; } S32 LLPrimTextureList::setOffset(const U8 index, const F32 s, const F32 t) { - if (index < mEntryList.size()) - { - return mEntryList[index]->setOffset(s, t); - } - return TEM_CHANGE_NONE; + if (index < mEntryList.size()) + { + return mEntryList[index]->setOffset(s, t); + } + return TEM_CHANGE_NONE; } S32 LLPrimTextureList::setOffsetS(const U8 index, const F32 s) { - if (index < mEntryList.size()) - { - return mEntryList[index]->setOffsetS(s); - } - return TEM_CHANGE_NONE; + if (index < mEntryList.size()) + { + return mEntryList[index]->setOffsetS(s); + } + return TEM_CHANGE_NONE; } S32 LLPrimTextureList::setOffsetT(const U8 index, const F32 t) { - if (index < mEntryList.size()) - { - return mEntryList[index]->setOffsetT(t); - } - return TEM_CHANGE_NONE; + if (index < mEntryList.size()) + { + return mEntryList[index]->setOffsetT(t); + } + return TEM_CHANGE_NONE; } S32 LLPrimTextureList::setRotation(const U8 index, const F32 r) { - if (index < mEntryList.size()) - { - return mEntryList[index]->setRotation(r); - } - return TEM_CHANGE_NONE; + if (index < mEntryList.size()) + { + return mEntryList[index]->setRotation(r); + } + return TEM_CHANGE_NONE; } S32 LLPrimTextureList::setBumpShinyFullbright(const U8 index, const U8 bump) { - if (index < mEntryList.size()) - { - return mEntryList[index]->setBumpShinyFullbright(bump); - } - return TEM_CHANGE_NONE; + if (index < mEntryList.size()) + { + return mEntryList[index]->setBumpShinyFullbright(bump); + } + return TEM_CHANGE_NONE; } S32 LLPrimTextureList::setMediaTexGen(const U8 index, const U8 media) { - if (index < mEntryList.size()) - { - return mEntryList[index]->setMediaTexGen(media); - } - return TEM_CHANGE_NONE; + if (index < mEntryList.size()) + { + return mEntryList[index]->setMediaTexGen(media); + } + return TEM_CHANGE_NONE; } S32 LLPrimTextureList::setBumpMap(const U8 index, const U8 bump) { - if (index < mEntryList.size()) - { - return mEntryList[index]->setBumpmap(bump); - } - return TEM_CHANGE_NONE; + if (index < mEntryList.size()) + { + return mEntryList[index]->setBumpmap(bump); + } + return TEM_CHANGE_NONE; } S32 LLPrimTextureList::setBumpShiny(const U8 index, const U8 bump_shiny) { - if (index < mEntryList.size()) - { - return mEntryList[index]->setBumpShiny(bump_shiny); - } - return TEM_CHANGE_NONE; + if (index < mEntryList.size()) + { + return mEntryList[index]->setBumpShiny(bump_shiny); + } + return TEM_CHANGE_NONE; } S32 LLPrimTextureList::setTexGen(const U8 index, const U8 texgen) { - if (index < mEntryList.size()) - { - return mEntryList[index]->setTexGen(texgen); - } - return TEM_CHANGE_NONE; + if (index < mEntryList.size()) + { + return mEntryList[index]->setTexGen(texgen); + } + return TEM_CHANGE_NONE; } S32 LLPrimTextureList::setShiny(const U8 index, const U8 shiny) { - if (index < mEntryList.size()) - { - return mEntryList[index]->setShiny(shiny); - } - return TEM_CHANGE_NONE; + if (index < mEntryList.size()) + { + return mEntryList[index]->setShiny(shiny); + } + return TEM_CHANGE_NONE; } S32 LLPrimTextureList::setFullbright(const U8 index, const U8 fullbright) { - if (index < mEntryList.size()) - { - return mEntryList[index]->setFullbright(fullbright); - } - return TEM_CHANGE_NONE; + if (index < mEntryList.size()) + { + return mEntryList[index]->setFullbright(fullbright); + } + return TEM_CHANGE_NONE; } S32 LLPrimTextureList::setMediaFlags(const U8 index, const U8 media_flags) { - if (index < mEntryList.size()) - { - return mEntryList[index]->setMediaFlags(media_flags); - } - return TEM_CHANGE_NONE; + if (index < mEntryList.size()) + { + return mEntryList[index]->setMediaFlags(media_flags); + } + return TEM_CHANGE_NONE; } S32 LLPrimTextureList::setGlow(const U8 index, const F32 glow) { - if (index < mEntryList.size()) - { - return mEntryList[index]->setGlow(glow); - } - return TEM_CHANGE_NONE; + if (index < mEntryList.size()) + { + return mEntryList[index]->setGlow(glow); + } + return TEM_CHANGE_NONE; } S32 LLPrimTextureList::setMaterialID(const U8 index, const LLMaterialID& pMaterialID) { - if (index < mEntryList.size()) - { - return mEntryList[index]->setMaterialID(pMaterialID); - } - return TEM_CHANGE_NONE; + if (index < mEntryList.size()) + { + return mEntryList[index]->setMaterialID(pMaterialID); + } + return TEM_CHANGE_NONE; } S32 LLPrimTextureList::setMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams) { - if (index < mEntryList.size()) - { - return mEntryList[index]->setMaterialParams(pMaterialParams); - } - return TEM_CHANGE_NONE; + if (index < mEntryList.size()) + { + return mEntryList[index]->setMaterialParams(pMaterialParams); + } + return TEM_CHANGE_NONE; } LLMaterialPtr LLPrimTextureList::getMaterialParams(const U8 index) { - if (index < mEntryList.size()) - { - return mEntryList[index]->getMaterialParams(); - } - - return LLMaterialPtr(); + if (index < mEntryList.size()) + { + return mEntryList[index]->getMaterialParams(); + } + + return LLMaterialPtr(); } S32 LLPrimTextureList::size() const { - return mEntryList.size(); + return mEntryList.size(); } // sets the size of the mEntryList container void LLPrimTextureList::setSize(S32 new_size) { - if (new_size < 0) - { - new_size = 0; - } - - S32 current_size = mEntryList.size(); - - if (new_size > current_size) - { - mEntryList.resize(new_size); - for (S32 index = current_size; index < new_size; ++index) - { - if (current_size > 0 - && mEntryList[current_size - 1]) - { - // copy the last valid entry for the new one - mEntryList[index] = mEntryList[current_size - 1]->newCopy(); - } - else - { - // no valid enries to copy, so we new one up - LLTextureEntry* new_entry = LLPrimTextureList::newTextureEntry(); - mEntryList[index] = new_entry; - } - } - } - else if (new_size < current_size) - { - for (S32 index = current_size-1; index >= new_size; --index) - { - delete mEntryList[index]; - } - mEntryList.resize(new_size); - } + if (new_size < 0) + { + new_size = 0; + } + + S32 current_size = mEntryList.size(); + + if (new_size > current_size) + { + mEntryList.resize(new_size); + for (S32 index = current_size; index < new_size; ++index) + { + if (current_size > 0 + && mEntryList[current_size - 1]) + { + // copy the last valid entry for the new one + mEntryList[index] = mEntryList[current_size - 1]->newCopy(); + } + else + { + // no valid enries to copy, so we new one up + LLTextureEntry* new_entry = LLPrimTextureList::newTextureEntry(); + mEntryList[index] = new_entry; + } + } + } + else if (new_size < current_size) + { + for (S32 index = current_size-1; index >= new_size; --index) + { + delete mEntryList[index]; + } + mEntryList.resize(new_size); + } } void LLPrimTextureList::setAllIDs(const LLUUID& id) { - texture_list_t::iterator itr = mEntryList.begin(); - while (itr != mEntryList.end()) - { - (*itr)->setID(id); - ++itr; - } + texture_list_t::iterator itr = mEntryList.begin(); + while (itr != mEntryList.end()) + { + (*itr)->setID(id); + ++itr; + } } diff --git a/indra/llprimitive/llprimtexturelist.h b/indra/llprimitive/llprimtexturelist.h index 49c636e40f..79744e9f08 100644 --- a/indra/llprimitive/llprimtexturelist.h +++ b/indra/llprimitive/llprimtexturelist.h @@ -1,25 +1,25 @@ -/** +/** * @file llprimtexturelist.h * @brief LLPrimTextureList (virtual) base class * * $LicenseInfo:firstyear=2008&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$ */ @@ -44,84 +44,84 @@ typedef std::vector<LLTextureEntry*> texture_list_t; class LLPrimTextureList { public: - // the LLPrimTextureList needs to know what type of LLTextureEntry - // to generate when it needs a new one, so we may need to set a - // callback for generating it, (or else use the base class default: - // static LLPrimTextureEntry::newTextureEntry() ) - //typedef LLTextureEntry* (__stdcall *NewTextureEntryFunction)(); - //static NewTextureEntryFunction sNewTextureEntryCallback; - static LLTextureEntry* newTextureEntry(); - static void setNewTextureEntryCallback( LLTextureEntry* (*callback)() ); - static LLTextureEntry* (*sNewTextureEntryCallback)(); - - LLPrimTextureList(); - virtual ~LLPrimTextureList(); - - void clear(); - - // clears current entries - // copies contents of other_list - // this is somewhat expensive, so it must be called explicitly - void copy(const LLPrimTextureList& other_list); - - // clears current copies - // takes contents of other_list - // clears other_list - void take(LLPrimTextureList& other_list); - - // copies LLTextureEntry 'te' - // returns TEM_CHANGE_TEXTURE if successful, otherwise TEM_CHANGE_NONE - S32 copyTexture(const U8 index, const LLTextureEntry& te); - - // takes ownership of LLTextureEntry* 'te' - // returns TEM_CHANGE_TEXTURE if successful, otherwise TEM_CHANGE_NONE - // IMPORTANT! -- if you use this function you must check the return value - S32 takeTexture(const U8 index, LLTextureEntry* te); - -// // copies contents of 'entry' and stores it in 'index' slot -// void copyTexture(const U8 index, const LLTextureEntry* entry); - - // returns pointer to texture at 'index' slot - LLTextureEntry* getTexture(const U8 index) const; - - S32 setID(const U8 index, const LLUUID& id); - S32 setColor(const U8 index, const LLColor3& color); - S32 setColor(const U8 index, const LLColor4& color); - S32 setAlpha(const U8 index, const F32 alpha); - S32 setScale(const U8 index, const F32 s, const F32 t); - S32 setScaleS(const U8 index, const F32 s); - S32 setScaleT(const U8 index, const F32 t); - S32 setOffset(const U8 index, const F32 s, const F32 t); - S32 setOffsetS(const U8 index, const F32 s); - S32 setOffsetT(const U8 index, const F32 t); - S32 setRotation(const U8 index, const F32 r); - S32 setBumpShinyFullbright(const U8 index, const U8 bump); - S32 setMediaTexGen(const U8 index, const U8 media); - S32 setBumpMap(const U8 index, const U8 bump); - S32 setBumpShiny(const U8 index, const U8 bump_shiny); - S32 setTexGen(const U8 index, const U8 texgen); - S32 setShiny(const U8 index, const U8 shiny); - S32 setFullbright(const U8 index, const U8 t); - S32 setMediaFlags(const U8 index, const U8 media_flags); - S32 setGlow(const U8 index, const F32 glow); - S32 setMaterialID(const U8 index, const LLMaterialID& pMaterialID); - S32 setMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams); - - LLMaterialPtr getMaterialParams(const U8 index); - - S32 size() const; - -// void forceResize(S32 new_size); - void setSize(S32 new_size); - - void setAllIDs(const LLUUID& id); + // the LLPrimTextureList needs to know what type of LLTextureEntry + // to generate when it needs a new one, so we may need to set a + // callback for generating it, (or else use the base class default: + // static LLPrimTextureEntry::newTextureEntry() ) + //typedef LLTextureEntry* (__stdcall *NewTextureEntryFunction)(); + //static NewTextureEntryFunction sNewTextureEntryCallback; + static LLTextureEntry* newTextureEntry(); + static void setNewTextureEntryCallback( LLTextureEntry* (*callback)() ); + static LLTextureEntry* (*sNewTextureEntryCallback)(); + + LLPrimTextureList(); + virtual ~LLPrimTextureList(); + + void clear(); + + // clears current entries + // copies contents of other_list + // this is somewhat expensive, so it must be called explicitly + void copy(const LLPrimTextureList& other_list); + + // clears current copies + // takes contents of other_list + // clears other_list + void take(LLPrimTextureList& other_list); + + // copies LLTextureEntry 'te' + // returns TEM_CHANGE_TEXTURE if successful, otherwise TEM_CHANGE_NONE + S32 copyTexture(const U8 index, const LLTextureEntry& te); + + // takes ownership of LLTextureEntry* 'te' + // returns TEM_CHANGE_TEXTURE if successful, otherwise TEM_CHANGE_NONE + // IMPORTANT! -- if you use this function you must check the return value + S32 takeTexture(const U8 index, LLTextureEntry* te); + +// // copies contents of 'entry' and stores it in 'index' slot +// void copyTexture(const U8 index, const LLTextureEntry* entry); + + // returns pointer to texture at 'index' slot + LLTextureEntry* getTexture(const U8 index) const; + + S32 setID(const U8 index, const LLUUID& id); + S32 setColor(const U8 index, const LLColor3& color); + S32 setColor(const U8 index, const LLColor4& color); + S32 setAlpha(const U8 index, const F32 alpha); + S32 setScale(const U8 index, const F32 s, const F32 t); + S32 setScaleS(const U8 index, const F32 s); + S32 setScaleT(const U8 index, const F32 t); + S32 setOffset(const U8 index, const F32 s, const F32 t); + S32 setOffsetS(const U8 index, const F32 s); + S32 setOffsetT(const U8 index, const F32 t); + S32 setRotation(const U8 index, const F32 r); + S32 setBumpShinyFullbright(const U8 index, const U8 bump); + S32 setMediaTexGen(const U8 index, const U8 media); + S32 setBumpMap(const U8 index, const U8 bump); + S32 setBumpShiny(const U8 index, const U8 bump_shiny); + S32 setTexGen(const U8 index, const U8 texgen); + S32 setShiny(const U8 index, const U8 shiny); + S32 setFullbright(const U8 index, const U8 t); + S32 setMediaFlags(const U8 index, const U8 media_flags); + S32 setGlow(const U8 index, const F32 glow); + S32 setMaterialID(const U8 index, const LLMaterialID& pMaterialID); + S32 setMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams); + + LLMaterialPtr getMaterialParams(const U8 index); + + S32 size() const; + +// void forceResize(S32 new_size); + void setSize(S32 new_size); + + void setAllIDs(const LLUUID& id); protected: - texture_list_t mEntryList; + texture_list_t mEntryList; private: - LLPrimTextureList(const LLPrimTextureList& other_list) - { - // private so that it can't be used - } + LLPrimTextureList(const LLPrimTextureList& other_list) + { + // private so that it can't be used + } }; #endif diff --git a/indra/llprimitive/lltextureanim.cpp b/indra/llprimitive/lltextureanim.cpp index 7c48e57a1a..cc156722f4 100644 --- a/indra/llprimitive/lltextureanim.cpp +++ b/indra/llprimitive/lltextureanim.cpp @@ -1,25 +1,25 @@ -/** +/** * @file lltextureanim.cpp * @brief LLTextureAnim base class * * $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$ */ @@ -34,7 +34,7 @@ const S32 TA_BLOCK_SIZE = 16; LLTextureAnim::LLTextureAnim() { - reset(); + reset(); } @@ -45,195 +45,195 @@ LLTextureAnim::~LLTextureAnim() void LLTextureAnim::reset() { - mMode = 0; - mFace = -1; - mSizeX = 4; - mSizeY = 4; - mStart = 0.f; - mLength = 0.f; - mRate = 1.f; + mMode = 0; + mFace = -1; + mSizeX = 4; + mSizeY = 4; + mStart = 0.f; + mLength = 0.f; + mRate = 1.f; } BOOL LLTextureAnim::equals(const LLTextureAnim &other) const { - if (mMode != other.mMode) - { - return FALSE; - } - if (mFace != other.mFace) - { - return FALSE; - } - if (mSizeX != other.mSizeX) - { - return FALSE; - } - if (mSizeY != other.mSizeY) - { - return FALSE; - } - if (mStart != other.mStart) - { - return FALSE; - } - if (mLength != other.mLength) - { - return FALSE; - } - if (mRate != other.mRate) - { - return FALSE; - } - - return TRUE; + if (mMode != other.mMode) + { + return FALSE; + } + if (mFace != other.mFace) + { + return FALSE; + } + if (mSizeX != other.mSizeX) + { + return FALSE; + } + if (mSizeY != other.mSizeY) + { + return FALSE; + } + if (mStart != other.mStart) + { + return FALSE; + } + if (mLength != other.mLength) + { + return FALSE; + } + if (mRate != other.mRate) + { + return FALSE; + } + + return TRUE; } void LLTextureAnim::packTAMessage(LLMessageSystem *mesgsys) const { - U8 data[TA_BLOCK_SIZE]; - data[0] = mMode; - data[1] = mFace; - data[2] = mSizeX; - data[3] = mSizeY; - htolememcpy(data + 4, &mStart, MVT_F32, sizeof(F32)); - htolememcpy(data + 8, &mLength, MVT_F32, sizeof(F32)); - htolememcpy(data + 12, &mRate, MVT_F32, sizeof(F32)); - - mesgsys->addBinaryDataFast(_PREHASH_TextureAnim, data, TA_BLOCK_SIZE); + U8 data[TA_BLOCK_SIZE]; + data[0] = mMode; + data[1] = mFace; + data[2] = mSizeX; + data[3] = mSizeY; + htolememcpy(data + 4, &mStart, MVT_F32, sizeof(F32)); + htolememcpy(data + 8, &mLength, MVT_F32, sizeof(F32)); + htolememcpy(data + 12, &mRate, MVT_F32, sizeof(F32)); + + mesgsys->addBinaryDataFast(_PREHASH_TextureAnim, data, TA_BLOCK_SIZE); } void LLTextureAnim::packTAMessage(LLDataPacker &dp) const { - U8 data[TA_BLOCK_SIZE]; - data[0] = mMode; - data[1] = mFace; - data[2] = mSizeX; - data[3] = mSizeY; - htolememcpy(data + 4, &mStart, MVT_F32, sizeof(F32)); - htolememcpy(data + 8, &mLength, MVT_F32, sizeof(F32)); - htolememcpy(data + 12, &mRate, MVT_F32, sizeof(F32)); - - dp.packBinaryData(data, TA_BLOCK_SIZE, "TextureAnimation"); + U8 data[TA_BLOCK_SIZE]; + data[0] = mMode; + data[1] = mFace; + data[2] = mSizeX; + data[3] = mSizeY; + htolememcpy(data + 4, &mStart, MVT_F32, sizeof(F32)); + htolememcpy(data + 8, &mLength, MVT_F32, sizeof(F32)); + htolememcpy(data + 12, &mRate, MVT_F32, sizeof(F32)); + + dp.packBinaryData(data, TA_BLOCK_SIZE, "TextureAnimation"); } void LLTextureAnim::unpackTAMessage(LLMessageSystem *mesgsys, const S32 block_num) { - S32 size = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_TextureAnim); - - if (size != TA_BLOCK_SIZE) - { - if (size) - { - LL_WARNS() << "Bad size " << size << " for TA block, ignoring." << LL_ENDL; - } - mMode = 0; - return; - } - - U8 data[TA_BLOCK_SIZE]; - mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_TextureAnim, data, TA_BLOCK_SIZE, block_num); - - mMode = data[0]; - mFace = data[1]; - if (mMode & LLTextureAnim::SMOOTH) - { - mSizeX = llmax((U8)0, data[2]); - mSizeY = llmax((U8)0, data[3]); - } - else - { - mSizeX = llmax((U8)1, data[2]); - mSizeY = llmax((U8)1, data[3]); - } - htolememcpy(&mStart, data + 4, MVT_F32, sizeof(F32)); - htolememcpy(&mLength, data + 8, MVT_F32, sizeof(F32)); - htolememcpy(&mRate, data + 12, MVT_F32, sizeof(F32)); + S32 size = mesgsys->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_TextureAnim); + + if (size != TA_BLOCK_SIZE) + { + if (size) + { + LL_WARNS() << "Bad size " << size << " for TA block, ignoring." << LL_ENDL; + } + mMode = 0; + return; + } + + U8 data[TA_BLOCK_SIZE]; + mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_TextureAnim, data, TA_BLOCK_SIZE, block_num); + + mMode = data[0]; + mFace = data[1]; + if (mMode & LLTextureAnim::SMOOTH) + { + mSizeX = llmax((U8)0, data[2]); + mSizeY = llmax((U8)0, data[3]); + } + else + { + mSizeX = llmax((U8)1, data[2]); + mSizeY = llmax((U8)1, data[3]); + } + htolememcpy(&mStart, data + 4, MVT_F32, sizeof(F32)); + htolememcpy(&mLength, data + 8, MVT_F32, sizeof(F32)); + htolememcpy(&mRate, data + 12, MVT_F32, sizeof(F32)); } void LLTextureAnim::unpackTAMessage(LLDataPacker &dp) { - S32 size; - U8 data[TA_BLOCK_SIZE]; - dp.unpackBinaryData(data, size, "TextureAnimation"); - if (size != TA_BLOCK_SIZE) - { - if (size) - { - LL_WARNS() << "Bad size " << size << " for TA block, ignoring." << LL_ENDL; - } - mMode = 0; - return; - } - - mMode = data[0]; - mFace = data[1]; - mSizeX = data[2]; - mSizeY = data[3]; - htolememcpy(&mStart, data + 4, MVT_F32, sizeof(F32)); - htolememcpy(&mLength, data + 8, MVT_F32, sizeof(F32)); - htolememcpy(&mRate, data + 12, MVT_F32, sizeof(F32)); + S32 size; + U8 data[TA_BLOCK_SIZE]; + dp.unpackBinaryData(data, size, "TextureAnimation"); + if (size != TA_BLOCK_SIZE) + { + if (size) + { + LL_WARNS() << "Bad size " << size << " for TA block, ignoring." << LL_ENDL; + } + mMode = 0; + return; + } + + mMode = data[0]; + mFace = data[1]; + mSizeX = data[2]; + mSizeY = data[3]; + htolememcpy(&mStart, data + 4, MVT_F32, sizeof(F32)); + htolememcpy(&mLength, data + 8, MVT_F32, sizeof(F32)); + htolememcpy(&mRate, data + 12, MVT_F32, sizeof(F32)); } LLSD LLTextureAnim::asLLSD() const { - LLSD sd; - sd["mode"] = mMode; - sd["face"] = mFace; - sd["sizeX"] = mSizeX; - sd["sizeY"] = mSizeY; - sd["start"] = mStart; - sd["length"] = mLength; - sd["rate"] = mRate; - return sd; + LLSD sd; + sd["mode"] = mMode; + sd["face"] = mFace; + sd["sizeX"] = mSizeX; + sd["sizeY"] = mSizeY; + sd["start"] = mStart; + sd["length"] = mLength; + sd["rate"] = mRate; + return sd; } bool LLTextureAnim::fromLLSD(LLSD& sd) { - const char *w; - w = "mode"; - if (sd.has(w)) - { - mMode = (U8)sd[w].asInteger(); - } else goto fail; - - w = "face"; - if (sd.has(w)) - { - mFace = (S8)sd[w].asInteger(); - } else goto fail; - - w = "sizeX"; - if (sd.has(w)) - { - mSizeX = (U8)sd[w].asInteger(); - } else goto fail; - - w = "sizeY"; - if (sd.has(w)) - { - mSizeY = (U8)sd[w].asInteger(); - } else goto fail; - - w = "start"; - if (sd.has(w)) - { - mStart = (F32)sd[w].asReal(); - } else goto fail; - - w = "length"; - if (sd.has(w)) - { - mLength = (F32)sd[w].asReal(); - } else goto fail; - - w = "rate"; - if (sd.has(w)) - { - mRate = (F32)sd[w].asReal(); - } else goto fail; - - return true; + const char *w; + w = "mode"; + if (sd.has(w)) + { + mMode = (U8)sd[w].asInteger(); + } else goto fail; + + w = "face"; + if (sd.has(w)) + { + mFace = (S8)sd[w].asInteger(); + } else goto fail; + + w = "sizeX"; + if (sd.has(w)) + { + mSizeX = (U8)sd[w].asInteger(); + } else goto fail; + + w = "sizeY"; + if (sd.has(w)) + { + mSizeY = (U8)sd[w].asInteger(); + } else goto fail; + + w = "start"; + if (sd.has(w)) + { + mStart = (F32)sd[w].asReal(); + } else goto fail; + + w = "length"; + if (sd.has(w)) + { + mLength = (F32)sd[w].asReal(); + } else goto fail; + + w = "rate"; + if (sd.has(w)) + { + mRate = (F32)sd[w].asReal(); + } else goto fail; + + return true; fail: - return false; + return false; } diff --git a/indra/llprimitive/lltextureanim.h b/indra/llprimitive/lltextureanim.h index f0d9f9df5c..ef76549903 100644 --- a/indra/llprimitive/lltextureanim.h +++ b/indra/llprimitive/lltextureanim.h @@ -1,25 +1,25 @@ -/** +/** * @file lltextureanim.h * @brief LLTextureAnim base class * * $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$ */ @@ -36,37 +36,37 @@ class LLDataPacker; class LLTextureAnim { public: - LLTextureAnim(); - virtual ~LLTextureAnim(); + LLTextureAnim(); + virtual ~LLTextureAnim(); - virtual void reset(); - void packTAMessage(LLMessageSystem *mesgsys) const; - void packTAMessage(LLDataPacker &dp) const; - void unpackTAMessage(LLMessageSystem *mesgsys, const S32 block_num); - void unpackTAMessage(LLDataPacker &dp); - BOOL equals(const LLTextureAnim &other) const; - LLSD asLLSD() const; - operator LLSD() const { return asLLSD(); } - bool fromLLSD(LLSD& sd); + virtual void reset(); + void packTAMessage(LLMessageSystem *mesgsys) const; + void packTAMessage(LLDataPacker &dp) const; + void unpackTAMessage(LLMessageSystem *mesgsys, const S32 block_num); + void unpackTAMessage(LLDataPacker &dp); + BOOL equals(const LLTextureAnim &other) const; + LLSD asLLSD() const; + operator LLSD() const { return asLLSD(); } + bool fromLLSD(LLSD& sd); - enum - { - ON = 0x01, - LOOP = 0x02, - REVERSE = 0x04, - PING_PONG = 0x08, - SMOOTH = 0x10, - ROTATE = 0x20, - SCALE = 0x40, - }; + enum + { + ON = 0x01, + LOOP = 0x02, + REVERSE = 0x04, + PING_PONG = 0x08, + SMOOTH = 0x10, + ROTATE = 0x20, + SCALE = 0x40, + }; public: - U8 mMode; - S8 mFace; - U8 mSizeX; - U8 mSizeY; - F32 mStart; - F32 mLength; - F32 mRate; // Rate in frames per second. + U8 mMode; + S8 mFace; + U8 mSizeX; + U8 mSizeY; + F32 mStart; + F32 mLength; + F32 mRate; // Rate in frames per second. }; #endif diff --git a/indra/llprimitive/lltextureentry.h b/indra/llprimitive/lltextureentry.h index 0935147688..78c61b4d65 100644 --- a/indra/llprimitive/lltextureentry.h +++ b/indra/llprimitive/lltextureentry.h @@ -1,25 +1,25 @@ -/** +/** * @file lltextureentry.h * @brief LLTextureEntry base class * * $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$ */ @@ -49,130 +49,130 @@ const S32 TEM_BUMPMAP_COUNT = 32; // | SSFBBBBB | S = Shiny, F = Fullbright, B = Bumpmap // | 76543210 | // +----------+ -const S32 TEM_BUMP_MASK = 0x1f; // 5 bits -const S32 TEM_FULLBRIGHT_MASK = 0x01; // 1 bit -const S32 TEM_SHINY_MASK = 0x03; // 2 bits -const S32 TEM_BUMP_SHINY_MASK = (0xc0 | 0x1f); -const S32 TEM_FULLBRIGHT_SHIFT = 5; -const S32 TEM_SHINY_SHIFT = 6; +const S32 TEM_BUMP_MASK = 0x1f; // 5 bits +const S32 TEM_FULLBRIGHT_MASK = 0x01; // 1 bit +const S32 TEM_SHINY_MASK = 0x03; // 2 bits +const S32 TEM_BUMP_SHINY_MASK = (0xc0 | 0x1f); +const S32 TEM_FULLBRIGHT_SHIFT = 5; +const S32 TEM_SHINY_SHIFT = 6; // The Media Tex Gen values are bits in a bit field: // +----------+ // | .....TTM | M = Media Flags (web page), T = LLTextureEntry::eTexGen, . = unused // | 76543210 | // +----------+ -const S32 TEM_MEDIA_MASK = 0x01; -const S32 TEM_TEX_GEN_MASK = 0x06; -const S32 TEM_TEX_GEN_SHIFT = 1; +const S32 TEM_MEDIA_MASK = 0x01; +const S32 TEM_TEX_GEN_MASK = 0x06; +const S32 TEM_TEX_GEN_SHIFT = 1; // forward declarations class LLMediaEntry; class LLTextureEntry { -public: - static LLTextureEntry* newTextureEntry(); - - typedef enum e_texgen - { - TEX_GEN_DEFAULT = 0x00, - TEX_GEN_PLANAR = 0x02, - TEX_GEN_SPHERICAL = 0x04, - TEX_GEN_CYLINDRICAL = 0x06 - } eTexGen; - - LLTextureEntry(); - LLTextureEntry(const LLUUID& tex_id); - LLTextureEntry(const LLTextureEntry &rhs); - - LLTextureEntry &operator=(const LLTextureEntry &rhs); +public: + static LLTextureEntry* newTextureEntry(); + + typedef enum e_texgen + { + TEX_GEN_DEFAULT = 0x00, + TEX_GEN_PLANAR = 0x02, + TEX_GEN_SPHERICAL = 0x04, + TEX_GEN_CYLINDRICAL = 0x06 + } eTexGen; + + LLTextureEntry(); + LLTextureEntry(const LLUUID& tex_id); + LLTextureEntry(const LLTextureEntry &rhs); + + LLTextureEntry &operator=(const LLTextureEntry &rhs); virtual ~LLTextureEntry(); - bool operator==(const LLTextureEntry &rhs) const; - bool operator!=(const LLTextureEntry &rhs) const; - - // Added to allow use with std::map - // - bool operator <(const LLTextureEntry &rhs) const; - - LLSD asLLSD() const; - void asLLSD(LLSD& sd) const; - operator LLSD() const { return asLLSD(); } - bool fromLLSD(const LLSD& sd); - - virtual LLTextureEntry* newBlank() const; - virtual LLTextureEntry* newCopy() const; - - void init(const LLUUID& tex_id, F32 scale_s, F32 scale_t, F32 offset_s, F32 offset_t, F32 rotation, U8 bump); - - bool hasPendingMaterialUpdate() const { return mMaterialUpdatePending; } - bool isSelected() const { return mSelected; } - bool setSelected(bool sel) { bool prev_sel = mSelected; mSelected = sel; return prev_sel; } - - // These return a TEM_ flag from above to indicate if something changed. - S32 setID (const LLUUID &tex_id); - S32 setColor(const LLColor4 &color); - S32 setColor(const LLColor3 &color); - S32 setAlpha(const F32 alpha); - S32 setScale(F32 s, F32 t); - S32 setScaleS(F32 s); - S32 setScaleT(F32 t); - S32 setOffset(F32 s, F32 t); - S32 setOffsetS(F32 s); - S32 setOffsetT(F32 t); - S32 setRotation(F32 theta); - - S32 setBumpmap(U8 bump); - S32 setFullbright(U8 bump); - S32 setShiny(U8 bump); - S32 setBumpShiny(U8 bump); - S32 setBumpShinyFullbright(U8 bump); - - S32 setMediaFlags(U8 media_flags); - S32 setTexGen(U8 texGen); - S32 setMediaTexGen(U8 media); + bool operator==(const LLTextureEntry &rhs) const; + bool operator!=(const LLTextureEntry &rhs) const; + + // Added to allow use with std::map + // + bool operator <(const LLTextureEntry &rhs) const; + + LLSD asLLSD() const; + void asLLSD(LLSD& sd) const; + operator LLSD() const { return asLLSD(); } + bool fromLLSD(const LLSD& sd); + + virtual LLTextureEntry* newBlank() const; + virtual LLTextureEntry* newCopy() const; + + void init(const LLUUID& tex_id, F32 scale_s, F32 scale_t, F32 offset_s, F32 offset_t, F32 rotation, U8 bump); + + bool hasPendingMaterialUpdate() const { return mMaterialUpdatePending; } + bool isSelected() const { return mSelected; } + bool setSelected(bool sel) { bool prev_sel = mSelected; mSelected = sel; return prev_sel; } + + // These return a TEM_ flag from above to indicate if something changed. + S32 setID (const LLUUID &tex_id); + S32 setColor(const LLColor4 &color); + S32 setColor(const LLColor3 &color); + S32 setAlpha(const F32 alpha); + S32 setScale(F32 s, F32 t); + S32 setScaleS(F32 s); + S32 setScaleT(F32 t); + S32 setOffset(F32 s, F32 t); + S32 setOffsetS(F32 s); + S32 setOffsetT(F32 t); + S32 setRotation(F32 theta); + + S32 setBumpmap(U8 bump); + S32 setFullbright(U8 bump); + S32 setShiny(U8 bump); + S32 setBumpShiny(U8 bump); + S32 setBumpShinyFullbright(U8 bump); + + S32 setMediaFlags(U8 media_flags); + S32 setTexGen(U8 texGen); + S32 setMediaTexGen(U8 media); S32 setGlow(F32 glow); - S32 setMaterialID(const LLMaterialID& pMaterialID); - S32 setMaterialParams(const LLMaterialPtr pMaterialParams); - - virtual const LLUUID &getID() const { return mID; } - const LLColor4 &getColor() const { return mColor; } + S32 setMaterialID(const LLMaterialID& pMaterialID); + S32 setMaterialParams(const LLMaterialPtr pMaterialParams); + + virtual const LLUUID &getID() const { return mID; } + const LLColor4 &getColor() const { return mColor; } const F32 getAlpha() const { return mColor.mV[VALPHA]; } - void getScale(F32 *s, F32 *t) const { *s = mScaleS; *t = mScaleT; } - F32 getScaleS() const { return mScaleS; } - F32 getScaleT() const { return mScaleT; } + void getScale(F32 *s, F32 *t) const { *s = mScaleS; *t = mScaleT; } + F32 getScaleS() const { return mScaleS; } + F32 getScaleT() const { return mScaleT; } - void getOffset(F32 *s, F32 *t) const { *s = mOffsetS; *t = mOffsetT; } - F32 getOffsetS() const { return mOffsetS; } - F32 getOffsetT() const { return mOffsetT; } + void getOffset(F32 *s, F32 *t) const { *s = mOffsetS; *t = mOffsetT; } + F32 getOffsetS() const { return mOffsetS; } + F32 getOffsetT() const { return mOffsetT; } - F32 getRotation() const { return mRotation; } - void getRotation(F32 *theta) const { *theta = mRotation; } + F32 getRotation() const { return mRotation; } + void getRotation(F32 *theta) const { *theta = mRotation; } - U8 getBumpmap() const { return mBump & TEM_BUMP_MASK; } - U8 getFullbright() const { return (mBump>>TEM_FULLBRIGHT_SHIFT) & TEM_FULLBRIGHT_MASK; } - U8 getShiny() const { return (mBump>>TEM_SHINY_SHIFT) & TEM_SHINY_MASK; } - U8 getBumpShiny() const { return mBump & TEM_BUMP_SHINY_MASK; } - U8 getBumpShinyFullbright() const { return mBump; } + U8 getBumpmap() const { return mBump & TEM_BUMP_MASK; } + U8 getFullbright() const { return (mBump>>TEM_FULLBRIGHT_SHIFT) & TEM_FULLBRIGHT_MASK; } + U8 getShiny() const { return (mBump>>TEM_SHINY_SHIFT) & TEM_SHINY_MASK; } + U8 getBumpShiny() const { return mBump & TEM_BUMP_SHINY_MASK; } + U8 getBumpShinyFullbright() const { return mBump; } - U8 getMediaFlags() const { return mMediaFlags & TEM_MEDIA_MASK; } - LLTextureEntry::e_texgen getTexGen() const { return LLTextureEntry::e_texgen(mMediaFlags & TEM_TEX_GEN_MASK); } - U8 getMediaTexGen() const { return mMediaFlags; } + U8 getMediaFlags() const { return mMediaFlags & TEM_MEDIA_MASK; } + LLTextureEntry::e_texgen getTexGen() const { return LLTextureEntry::e_texgen(mMediaFlags & TEM_TEX_GEN_MASK); } + U8 getMediaTexGen() const { return mMediaFlags; } F32 getGlow() const { return mGlow; } - const LLMaterialID& getMaterialID() const { return mMaterialID; }; - const LLMaterialPtr getMaterialParams() const { return mMaterial; }; + const LLMaterialID& getMaterialID() const { return mMaterialID; }; + const LLMaterialPtr getMaterialParams() const { return mMaterial; }; // *NOTE: it is possible for hasMedia() to return true, but getMediaData() to return NULL. // CONVERSELY, it is also possible for hasMedia() to return false, but getMediaData() - // to NOT return NULL. - bool hasMedia() const { return (bool)(mMediaFlags & MF_HAS_MEDIA); } - LLMediaEntry* getMediaData() const { return mMediaEntry; } + // to NOT return NULL. + bool hasMedia() const { return (bool)(mMediaFlags & MF_HAS_MEDIA); } + LLMediaEntry* getMediaData() const { return mMediaEntry; } // Completely change the media data on this texture entry. void setMediaData(const LLMediaEntry &media_entry); - // Returns true if media data was updated, false if it was cleared - bool updateMediaData(const LLSD& media_data); + // Returns true if media data was updated, false if it was cleared + bool updateMediaData(const LLSD& media_data); // Clears media data, and sets the media flags bit to 0 void clearMediaData(); // Merges the given LLSD of media fields with this media entry. @@ -188,11 +188,11 @@ public: static U32 getVersionFromMediaVersionString(const std::string &version_string); // Given a media version string, return the UUID of the agent static LLUUID getAgentIDFromMediaVersionString(const std::string &version_string); - // Return whether or not the given string is actually a media version - static bool isMediaVersionString(const std::string &version_string); - - // Media flags - enum { MF_NONE = 0x0, MF_HAS_MEDIA = 0x1 }; + // Return whether or not the given string is actually a media version + static bool isMediaVersionString(const std::string &version_string); + + // Media flags + enum { MF_NONE = 0x0, MF_HAS_MEDIA = 0x1 }; // GLTF asset void setGLTFMaterial(LLGLTFMaterial* material, bool local_origin = true); @@ -212,50 +212,50 @@ public: S32 setGLTFRenderMaterial(LLGLTFMaterial* mat); public: - F32 mScaleS; // S, T offset - F32 mScaleT; // S, T offset - F32 mOffsetS; // S, T offset - F32 mOffsetT; // S, T offset - F32 mRotation; // anti-clockwise rotation in rad about the bottom left corner + F32 mScaleS; // S, T offset + F32 mScaleT; // S, T offset + F32 mOffsetS; // S, T offset + F32 mOffsetT; // S, T offset + F32 mRotation; // anti-clockwise rotation in rad about the bottom left corner - static const LLTextureEntry null; + static const LLTextureEntry null; - // LLSD key defines - static const char* OBJECT_ID_KEY; - static const char* OBJECT_MEDIA_DATA_KEY; + // LLSD key defines + static const char* OBJECT_ID_KEY; + static const char* OBJECT_MEDIA_DATA_KEY; static const char* MEDIA_VERSION_KEY; - static const char* TEXTURE_INDEX_KEY; - static const char* TEXTURE_MEDIA_DATA_KEY; + static const char* TEXTURE_INDEX_KEY; + static const char* TEXTURE_MEDIA_DATA_KEY; protected: - bool mSelected; - LLUUID mID; // Texture GUID - LLColor4 mColor; - U8 mBump; // Bump map, shiny, and fullbright - U8 mMediaFlags; // replace with web page, movie, etc. - F32 mGlow; - bool mMaterialUpdatePending; - LLMaterialID mMaterialID; - LLMaterialPtr mMaterial; - + bool mSelected; + LLUUID mID; // Texture GUID + LLColor4 mColor; + U8 mBump; // Bump map, shiny, and fullbright + U8 mMediaFlags; // replace with web page, movie, etc. + F32 mGlow; + bool mMaterialUpdatePending; + LLMaterialID mMaterialID; + LLMaterialPtr mMaterial; + // Reference to GLTF material asset state // On the viewer, this should be the same LLGLTFMaterial instance that exists in LLGLTFMaterialList - LLPointer<LLGLTFMaterial> mGLTFMaterial; + LLPointer<LLGLTFMaterial> mGLTFMaterial; // GLTF material parameter overrides -- the viewer will use this data to override material parameters // set by the asset and store the results in mRenderGLTFMaterial LLPointer<LLGLTFMaterial> mGLTFMaterialOverrides; // GLTF material to use for rendering -- will always be an LLFetchedGLTFMaterial - LLPointer<LLGLTFMaterial> mGLTFRenderMaterial; + LLPointer<LLGLTFMaterial> mGLTFRenderMaterial; + + // Note the media data is not sent via the same message structure as the rest of the TE + LLMediaEntry* mMediaEntry; // The media data for the face - // Note the media data is not sent via the same message structure as the rest of the TE - LLMediaEntry* mMediaEntry; // The media data for the face + // NOTE: when adding new data to this class, in addition to adding it to the serializers asLLSD/fromLLSD and the + // message packers (e.g. LLPrimitive::packTEMessage) you must also implement its copy in LLPrimitive::copyTEs() - // NOTE: when adding new data to this class, in addition to adding it to the serializers asLLSD/fromLLSD and the - // message packers (e.g. LLPrimitive::packTEMessage) you must also implement its copy in LLPrimitive::copyTEs() - }; #endif diff --git a/indra/llprimitive/lltree_common.h b/indra/llprimitive/lltree_common.h index df00ff1591..c10e3c46e9 100644 --- a/indra/llprimitive/lltree_common.h +++ b/indra/llprimitive/lltree_common.h @@ -1,61 +1,61 @@ -/** +/** * @file lltree_common.h * @brief LLTree_gene_0 base class * * $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$ */ -// Common data for trees shared between simulator and viewer +// Common data for trees shared between simulator and viewer #ifndef LL_LLTREE_COMMON_H #define LL_LLTREE_COMMON_H -struct LLTree_gene_0 +struct LLTree_gene_0 { - LLTree_gene_0() - : scale(0), - branches(0), - twist(0), - droop(0), - species(0), - trunk_depth(0), - branch_thickness(0), - max_depth(0), - scale_step(0) - { - } + LLTree_gene_0() + : scale(0), + branches(0), + twist(0), + droop(0), + species(0), + trunk_depth(0), + branch_thickness(0), + max_depth(0), + scale_step(0) + { + } - // - // The genome for a tree, species 0 - // - U8 scale; // Scales size of the tree ( / 50 = meter) - U8 branches; // When tree forks, how many branches emerge? - U8 twist; // twist about old branch axis for each branch (convert to degrees by dividing/255 * 180) - U8 droop; // Droop away from old branch axis (convert to degrees by dividing/255 * 180) - U8 species; // Branch coloring index - U8 trunk_depth; // max recursions in the main trunk - U8 branch_thickness; // Scales thickness of trunk ( / 50 = meter) - U8 max_depth; // Branch Recursions to flower - U8 scale_step; // How much to multiply scale size at each recursion 0-1.f to convert to float -}; + // + // The genome for a tree, species 0 + // + U8 scale; // Scales size of the tree ( / 50 = meter) + U8 branches; // When tree forks, how many branches emerge? + U8 twist; // twist about old branch axis for each branch (convert to degrees by dividing/255 * 180) + U8 droop; // Droop away from old branch axis (convert to degrees by dividing/255 * 180) + U8 species; // Branch coloring index + U8 trunk_depth; // max recursions in the main trunk + U8 branch_thickness; // Scales thickness of trunk ( / 50 = meter) + U8 max_depth; // Branch Recursions to flower + U8 scale_step; // How much to multiply scale size at each recursion 0-1.f to convert to float +}; #endif diff --git a/indra/llprimitive/lltreeparams.cpp b/indra/llprimitive/lltreeparams.cpp index 19a6db20ae..b85aa3acf2 100644 --- a/indra/llprimitive/lltreeparams.cpp +++ b/indra/llprimitive/lltreeparams.cpp @@ -1,25 +1,25 @@ -/** +/** * @file lltreeparams.cpp * @brief implementation of the LLTreeParams class. * * $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$ */ @@ -40,129 +40,129 @@ LLTreeParams::LLTreeParams() { -// LL_INFOS() << "TREE PARAMS INITIALIZED" << LL_ENDL; - // init to basic something or other... - mShape = SR_TEND_FLAME; - mLevels = 1; - mScale = 15; - mScaleV = 0; - - mBaseSize = 0.3f; +// LL_INFOS() << "TREE PARAMS INITIALIZED" << LL_ENDL; + // init to basic something or other... + mShape = SR_TEND_FLAME; + mLevels = 1; + mScale = 15; + mScaleV = 0; + + mBaseSize = 0.3f; + + mRatio = 0.015f; + mRatioPower = 1.3f; + + mLobes = 0; + mLobeDepth = .1f; - mRatio = 0.015f; - mRatioPower = 1.3f; + mFlare = 1.2f; + mFlarePercentage = 0.1f; + mFlareRes = 3; - mLobes = 0; - mLobeDepth = .1f; + //mAttractionUp = .5f; - mFlare = 1.2f; - mFlarePercentage = 0.1f; - mFlareRes = 3; + mBaseSplits = 0; - //mAttractionUp = .5f; + mScale0 = 2.0; + mScaleV0 = 0.0; - mBaseSplits = 0; + // level 0 - mScale0 = 2.0; - mScaleV0 = 0.0; + // scaling + mLength[0] = 1.0f; + mLengthV[0] = 0; + mTaper[0] = 1.0f; - // level 0 + // stem splits + mSegSplits[0] = 0.15f; + mSplitAngle[0] = 15.0f; + mSplitAngleV[0] = 10.0f; - // scaling - mLength[0] = 1.0f; - mLengthV[0] = 0; - mTaper[0] = 1.0f; + mVertices[0] = 5; - // stem splits - mSegSplits[0] = 0.15f; - mSplitAngle[0] = 15.0f; - mSplitAngleV[0] = 10.0f; + // curvature + mCurveRes[0] = 4; + mCurve[0] = 0; + mCurveV[0] = 25; + mCurveBack[0] = 0; - mVertices[0] = 5; - - // curvature - mCurveRes[0] = 4; - mCurve[0] = 0; - mCurveV[0] = 25; - mCurveBack[0] = 0; + // level 1 - // level 1 + // scaling + mLength[1] = .3f; + mLengthV[1] = 0.05f; + mTaper[1] = 1.0f; - // scaling - mLength[1] = .3f; - mLengthV[1] = 0.05f; - mTaper[1] = 1.0f; + // angle params + mDownAngle[0] = 60.0f; + mDownAngleV[0] = 20.0f; + mRotate[0] = 140.0f; + mRotateV[0] = 0.0f; + mBranches[0] = 35; - // angle params - mDownAngle[0] = 60.0f; - mDownAngleV[0] = 20.0f; - mRotate[0] = 140.0f; - mRotateV[0] = 0.0f; - mBranches[0] = 35; + mVertices[1] = 3; - mVertices[1] = 3; + // stem splits + mSplitAngle[1] = 0.0f; + mSplitAngleV[1] = 0.0f; + mSegSplits[1] = 0.0f; - // stem splits - mSplitAngle[1] = 0.0f; - mSplitAngleV[1] = 0.0f; - mSegSplits[1] = 0.0f; + // curvature + mCurveRes[1] = 4; + mCurve[1] = 0; + mCurveV[1] = 0; + mCurveBack[1] = 40; - // curvature - mCurveRes[1] = 4; - mCurve[1] = 0; - mCurveV[1] = 0; - mCurveBack[1] = 40; + // level 2 + mLength[2] = .6f; + mLengthV[2] = .1f; + mTaper[2] = 1; - // level 2 - mLength[2] = .6f; - mLengthV[2] = .1f; - mTaper[2] = 1; + mDownAngle[1] = 30; + mDownAngleV[1] = 10; + mRotate[1] = 140; + mRotateV[1] = 0; - mDownAngle[1] = 30; - mDownAngleV[1] = 10; - mRotate[1] = 140; - mRotateV[1] = 0; + mBranches[1] = 20; + mVertices[2] = 3; - mBranches[1] = 20; - mVertices[2] = 3; + mSplitAngle[2] = 0; + mSplitAngleV[2] = 0; + mSegSplits[2] = 0; - mSplitAngle[2] = 0; - mSplitAngleV[2] = 0; - mSegSplits[2] = 0; + mCurveRes[2] = 3; + mCurve[2] = 10; + mCurveV[2] = 150; + mCurveBack[2] = 0; - mCurveRes[2] = 3; - mCurve[2] = 10; - mCurveV[2] = 150; - mCurveBack[2] = 0; + // level 3 + mLength[3] = .4f; + mLengthV[3] = 0; + mTaper[3] = 1; - // level 3 - mLength[3] = .4f; - mLengthV[3] = 0; - mTaper[3] = 1; + mDownAngle[2] = 45; + mDownAngleV[2] = 10; + mRotate[2] = 140; + mRotateV[2] = 0; - mDownAngle[2] = 45; - mDownAngleV[2] = 10; - mRotate[2] = 140; - mRotateV[2] = 0; + mBranches[2] = 5; + mVertices[3] = 3; - mBranches[2] = 5; - mVertices[3] = 3; + mSplitAngle[3] = 0; + mSplitAngleV[3] = 0; + mSegSplits[3] = 0; - mSplitAngle[3] = 0; - mSplitAngleV[3] = 0; - mSegSplits[3] = 0; + mCurveRes[3] = 2; + mCurve[3] = 0; + mCurveV[3] = 0; + mCurveBack[3] = 0; - mCurveRes[3] = 2; - mCurve[3] = 0; - mCurveV[3] = 0; - mCurveBack[3] = 0; + mLeaves = 0; + mLeafScaleX = 1.0f; + mLeafScaleY = 1.0f; - mLeaves = 0; - mLeafScaleX = 1.0f; - mLeafScaleY = 1.0f; - - mLeafQuality = 1.25; + mLeafQuality = 1.25; } LLTreeParams::~LLTreeParams() @@ -170,36 +170,36 @@ LLTreeParams::~LLTreeParams() } -F32 LLTreeParams::ShapeRatio(EShapeRatio shape, F32 ratio) +F32 LLTreeParams::ShapeRatio(EShapeRatio shape, F32 ratio) { - switch (shape) { - case (SR_CONICAL): - return (.2f + .8f * ratio); - case (SR_SPHERICAL): - return (.2f + .8f * sinf(F_PI*ratio)); - case (SR_HEMISPHERICAL): - return (.2f + .8f * sinf(.5*F_PI*ratio)); - case (SR_CYLINDRICAL): - return (1); - case (SR_TAPERED_CYLINDRICAL): - return (.5f + .5f * ratio); - case (SR_FLAME): - if (ratio <= .7f) { - return ratio/.7f; - } else { - return ((1 - ratio)/.3f); - } - case (SR_INVERSE_CONICAL): - return (1 - .8f * ratio); - case (SR_TEND_FLAME): - if (ratio <= .7) { - return (.5f + .5f*(ratio/.7f)); - } else { - return (.5f + .5f * (1 - ratio)/.3f); - } - case (SR_ENVELOPE): - return 1; - default: - return 1; - } + switch (shape) { + case (SR_CONICAL): + return (.2f + .8f * ratio); + case (SR_SPHERICAL): + return (.2f + .8f * sinf(F_PI*ratio)); + case (SR_HEMISPHERICAL): + return (.2f + .8f * sinf(.5*F_PI*ratio)); + case (SR_CYLINDRICAL): + return (1); + case (SR_TAPERED_CYLINDRICAL): + return (.5f + .5f * ratio); + case (SR_FLAME): + if (ratio <= .7f) { + return ratio/.7f; + } else { + return ((1 - ratio)/.3f); + } + case (SR_INVERSE_CONICAL): + return (1 - .8f * ratio); + case (SR_TEND_FLAME): + if (ratio <= .7) { + return (.5f + .5f*(ratio/.7f)); + } else { + return (.5f + .5f * (1 - ratio)/.3f); + } + case (SR_ENVELOPE): + return 1; + default: + return 1; + } } diff --git a/indra/llprimitive/lltreeparams.h b/indra/llprimitive/lltreeparams.h index 6e2b47c0e9..6b11ad7dcf 100644 --- a/indra/llprimitive/lltreeparams.h +++ b/indra/llprimitive/lltreeparams.h @@ -1,200 +1,200 @@ -/** +/** * @file lltreeparams.h * @brief Implementation of the LLTreeParams class * * $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_LLTREEPARAMS_H -#define LL_LLTREEPARAMS_H +#define LL_LLTREEPARAMS_H /* for information about formulas associated with each type * check the Weber + Penn paper */ -enum EShapeRatio { SR_CONICAL, SR_SPHERICAL, SR_HEMISPHERICAL, - SR_CYLINDRICAL, SR_TAPERED_CYLINDRICAL, SR_FLAME, - SR_INVERSE_CONICAL, SR_TEND_FLAME, SR_ENVELOPE}; +enum EShapeRatio { SR_CONICAL, SR_SPHERICAL, SR_HEMISPHERICAL, + SR_CYLINDRICAL, SR_TAPERED_CYLINDRICAL, SR_FLAME, + SR_INVERSE_CONICAL, SR_TEND_FLAME, SR_ENVELOPE}; const U32 TREE_BLOCK_SIZE = 16; const U8 MAX_NUM_LEVELS = 4; -class LLTreeParams +class LLTreeParams { public: - LLTreeParams(); - virtual ~LLTreeParams(); + LLTreeParams(); + virtual ~LLTreeParams(); - static F32 ShapeRatio(EShapeRatio shape, F32 ratio); + static F32 ShapeRatio(EShapeRatio shape, F32 ratio); public: - // Variables with an asterick (*) cannot be modified without a re-instancing the - // trunk/branches + // Variables with an asterick (*) cannot be modified without a re-instancing the + // trunk/branches + + // Variables with an exclamation point (!) should probably not be modified outside and instead + // be tied directly to the species + + // Variables with a tilde (~) should be tied to a range specified by the + // species type but still slightly controllable by the user + + // GENERAL + + //! determines length/radius of branches on tree -- ie: general 'shape' + EShapeRatio mShape; + + //! number of recursive branch levels...limit to MAX_NUM_LEVELS + U8 mLevels; + + //~ percentage of trunk at bottom without branches + F32 mBaseSize; + + //~ the general scale + variance of tree + F32 mScale, mScaleV; + + // general scale of tree + F32 mScale0, mScaleV0; + + + + // LOBING + + //*! number of peaks in the radial distance about the perimeter + U8 mLobes; + // even numbers = obvius symmetry ... use odd numbers + + //*! magnitude of the variations as a fraction of the radius + F32 mLobeDepth; - // Variables with an exclamation point (!) should probably not be modified outside and instead - // be tied directly to the species - // Variables with a tilde (~) should be tied to a range specified by the - // species type but still slightly controllable by the user - // GENERAL + // FLARE - //! determines length/radius of branches on tree -- ie: general 'shape' - EShapeRatio mShape; - - //! number of recursive branch levels...limit to MAX_NUM_LEVELS - U8 mLevels; + //*! causes exponential expansion near base of trunk + F32 mFlare; + // scales radius base by min 1 to '1 + flare' - //~ percentage of trunk at bottom without branches - F32 mBaseSize; - - //~ the general scale + variance of tree - F32 mScale, mScaleV; + //*! percentage of the height of the trunk to flair -- likely less than baseSize + F32 mFlarePercentage; - // general scale of tree - F32 mScale0, mScaleV0; + //*! number of cross sections to make for the flair + U8 mFlareRes; - // LOBING + // LEAVES - //*! number of peaks in the radial distance about the perimeter - U8 mLobes; - // even numbers = obvius symmetry ... use odd numbers - - //*! magnitude of the variations as a fraction of the radius - F32 mLobeDepth; + //~ number of leaves to make + U8 mLeaves; + //! scale of the leaves + F32 mLeafScaleX, mLeafScaleY; + // quality/density of leaves + F32 mLeafQuality; - // FLARE + // several params don't have level 0 values - //*! causes exponential expansion near base of trunk - F32 mFlare; - // scales radius base by min 1 to '1 + flare' + // BRANCHES - //*! percentage of the height of the trunk to flair -- likely less than baseSize - F32 mFlarePercentage; + //~ angle away from parent + F32 mDownAngle[MAX_NUM_LEVELS - 1]; + F32 mDownAngleV[MAX_NUM_LEVELS - 1]; - //*! number of cross sections to make for the flair - U8 mFlareRes; + //~ rotation around parent + F32 mRotate[MAX_NUM_LEVELS - 1]; + F32 mRotateV[MAX_NUM_LEVELS - 1]; + //~ num branches to spawn + U8 mBranches[MAX_NUM_LEVELS - 1]; + //~ fractional length of branch. 1 = same length as parent branch + F32 mLength[MAX_NUM_LEVELS]; + F32 mLengthV[MAX_NUM_LEVELS]; - // LEAVES + //!~ ratio and ratiopower determine radius/length + F32 mRatio, mRatioPower; - //~ number of leaves to make - U8 mLeaves; + //*! taper of branches + F32 mTaper[MAX_NUM_LEVELS]; + // 0 - non-tapering cylinder + // 1 - taper to a point + // 2 - taper to a spherical end + // 3 - periodic tapering (concatenated spheres) - //! scale of the leaves - F32 mLeafScaleX, mLeafScaleY; + //! SEG SPLITTING + U8 mBaseSplits; //! num segsplits at first curve cross section of trunk + F32 mSegSplits[MAX_NUM_LEVELS]; //~ splits per cross section. 1 = 1 split per section + F32 mSplitAngle[MAX_NUM_LEVELS]; //~ angle that splits go from parent (tempered by height) + F32 mSplitAngleV[MAX_NUM_LEVELS]; //~ variance of the splits - // quality/density of leaves - F32 mLeafQuality; + // CURVE + F32 mCurve[MAX_NUM_LEVELS]; //* general, 1-axis, overall curve of branch + F32 mCurveV[MAX_NUM_LEVELS]; //* curve variance at each cross section from general overall curve + U8 mCurveRes[MAX_NUM_LEVELS]; //* number of cross sections for curve + F32 mCurveBack[MAX_NUM_LEVELS]; //* curveback is amount branch curves back towards - // several params don't have level 0 values + // vertices per cross section + U8 mVertices[MAX_NUM_LEVELS]; - // BRANCHES + // * no longer useful with pre-instanced branches + // specifies upward tendency of branches. + //F32 mAttractionUp; + // 1 = each branch will slightly go upwards by the end of the branch + // >1 = branches tend to go upwards earlier in their length + // pruning not implemented + // Prune parameters + //F32 mPruneRatio; + //F32 mPruneWidth, mPruneWidthPeak; + //F32 mPrunePowerLow, mPrunePowerHigh; - //~ angle away from parent - F32 mDownAngle[MAX_NUM_LEVELS - 1]; - F32 mDownAngleV[MAX_NUM_LEVELS - 1]; - - //~ rotation around parent - F32 mRotate[MAX_NUM_LEVELS - 1]; - F32 mRotateV[MAX_NUM_LEVELS - 1]; - //~ num branches to spawn - U8 mBranches[MAX_NUM_LEVELS - 1]; + // NETWORK MESSAGE DATA + // Below is the outline for network messages regarding trees. + // The general idea is that a user would pick a general 'tree type' (the first variable) + // and then several 'open ended' variables like 'branchiness' and 'leafiness'. + // The effect that each of these general user variables would then affect the actual + // tree parameters (like # branches, # segsplits) in different ways depending on + // the tree type selected. Essentially, each tree type should have a formula + // that expands the 'leafiness' and 'branchiness' user variables into actual + // values for the tree parameters. - //~ fractional length of branch. 1 = same length as parent branch - F32 mLength[MAX_NUM_LEVELS]; - F32 mLengthV[MAX_NUM_LEVELS]; + // These formulas aren't made yet and will certainly require some tuning. The + // estimates below for the # bits required seems like a good guesstimate. - //!~ ratio and ratiopower determine radius/length - F32 mRatio, mRatioPower; + // VARIABLE - # bits (range) - VARIABLES AFFECTED + // tree type - 5 bits (32) - + // branches - 6 bits (64) - numBranches + // splits - 6 bits (64) - segsplits + // leafiness - 3 bits (8) - numLeaves + // branch spread - 5 bits (32) - splitAngle(V), rotate(V) + // angle - 5 bits (32) - downAngle(V) + // branch length - 6 bits (64) - branchlength(V) + // randomness - 7 bits (128) - percentage for randomness of the (V)'s + // basesize - 5 bits (32) - basesize - //*! taper of branches - F32 mTaper[MAX_NUM_LEVELS]; - // 0 - non-tapering cylinder - // 1 - taper to a point - // 2 - taper to a spherical end - // 3 - periodic tapering (concatenated spheres) - - //! SEG SPLITTING - U8 mBaseSplits; //! num segsplits at first curve cross section of trunk - F32 mSegSplits[MAX_NUM_LEVELS]; //~ splits per cross section. 1 = 1 split per section - F32 mSplitAngle[MAX_NUM_LEVELS]; //~ angle that splits go from parent (tempered by height) - F32 mSplitAngleV[MAX_NUM_LEVELS]; //~ variance of the splits + // total - 48 bits - // CURVE - F32 mCurve[MAX_NUM_LEVELS]; //* general, 1-axis, overall curve of branch - F32 mCurveV[MAX_NUM_LEVELS]; //* curve variance at each cross section from general overall curve - U8 mCurveRes[MAX_NUM_LEVELS]; //* number of cross sections for curve - F32 mCurveBack[MAX_NUM_LEVELS]; //* curveback is amount branch curves back towards - - // vertices per cross section - U8 mVertices[MAX_NUM_LEVELS]; - - // * no longer useful with pre-instanced branches - // specifies upward tendency of branches. - //F32 mAttractionUp; - // 1 = each branch will slightly go upwards by the end of the branch - // >1 = branches tend to go upwards earlier in their length - // pruning not implemented - // Prune parameters - //F32 mPruneRatio; - //F32 mPruneWidth, mPruneWidthPeak; - //F32 mPrunePowerLow, mPrunePowerHigh; - - - // NETWORK MESSAGE DATA - // Below is the outline for network messages regarding trees. - // The general idea is that a user would pick a general 'tree type' (the first variable) - // and then several 'open ended' variables like 'branchiness' and 'leafiness'. - // The effect that each of these general user variables would then affect the actual - // tree parameters (like # branches, # segsplits) in different ways depending on - // the tree type selected. Essentially, each tree type should have a formula - // that expands the 'leafiness' and 'branchiness' user variables into actual - // values for the tree parameters. - - // These formulas aren't made yet and will certainly require some tuning. The - // estimates below for the # bits required seems like a good guesstimate. - - // VARIABLE - # bits (range) - VARIABLES AFFECTED - // tree type - 5 bits (32) - - // branches - 6 bits (64) - numBranches - // splits - 6 bits (64) - segsplits - // leafiness - 3 bits (8) - numLeaves - // branch spread - 5 bits (32) - splitAngle(V), rotate(V) - // angle - 5 bits (32) - downAngle(V) - // branch length - 6 bits (64) - branchlength(V) - // randomness - 7 bits (128) - percentage for randomness of the (V)'s - // basesize - 5 bits (32) - basesize - - // total - 48 bits - - //U8 mNetSpecies; + //U8 mNetSpecies; }; diff --git a/indra/llprimitive/llvolumemessage.cpp b/indra/llprimitive/llvolumemessage.cpp index 8d47a7147f..804b208e3a 100644 --- a/indra/llprimitive/llvolumemessage.cpp +++ b/indra/llprimitive/llvolumemessage.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llvolumemessage.cpp * @brief LLVolumeMessage base class * * $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$ */ @@ -37,164 +37,164 @@ //============================================================================ bool LLVolumeMessage::packProfileParams( - const LLProfileParams* params, - LLMessageSystem *mesgsys) + const LLProfileParams* params, + LLMessageSystem *mesgsys) { - // Default to cylinder - static LLProfileParams defaultparams(LL_PCODE_PROFILE_CIRCLE, U16(0), U16(0), U16(0)); - - if (!params) - params = &defaultparams; - - U8 tempU8; - U16 tempU16; - - tempU8 = params->getCurveType(); - mesgsys->addU8Fast(_PREHASH_ProfileCurve, tempU8); - - tempU16 = (U16) ll_round( params->getBegin() / CUT_QUANTA); - mesgsys->addU16Fast(_PREHASH_ProfileBegin, tempU16); - - tempU16 = 50000 - (U16) ll_round(params->getEnd() / CUT_QUANTA); - mesgsys->addU16Fast(_PREHASH_ProfileEnd, tempU16); - - tempU16 = (U16) ll_round(params->getHollow() / HOLLOW_QUANTA); - mesgsys->addU16Fast(_PREHASH_ProfileHollow, tempU16); - - return true; + // Default to cylinder + static LLProfileParams defaultparams(LL_PCODE_PROFILE_CIRCLE, U16(0), U16(0), U16(0)); + + if (!params) + params = &defaultparams; + + U8 tempU8; + U16 tempU16; + + tempU8 = params->getCurveType(); + mesgsys->addU8Fast(_PREHASH_ProfileCurve, tempU8); + + tempU16 = (U16) ll_round( params->getBegin() / CUT_QUANTA); + mesgsys->addU16Fast(_PREHASH_ProfileBegin, tempU16); + + tempU16 = 50000 - (U16) ll_round(params->getEnd() / CUT_QUANTA); + mesgsys->addU16Fast(_PREHASH_ProfileEnd, tempU16); + + tempU16 = (U16) ll_round(params->getHollow() / HOLLOW_QUANTA); + mesgsys->addU16Fast(_PREHASH_ProfileHollow, tempU16); + + return true; } bool LLVolumeMessage::packProfileParams( - const LLProfileParams* params, - LLDataPacker &dp) + const LLProfileParams* params, + LLDataPacker &dp) { - // Default to cylinder - static LLProfileParams defaultparams(LL_PCODE_PROFILE_CIRCLE, U16(0), U16(0), U16(0)); - - if (!params) - params = &defaultparams; - - U8 tempU8; - U16 tempU16; - - tempU8 = params->getCurveType(); - dp.packU8(tempU8, "Curve"); - - tempU16 = (U16) ll_round( params->getBegin() / CUT_QUANTA); - dp.packU16(tempU16, "Begin"); - - tempU16 = 50000 - (U16) ll_round(params->getEnd() / CUT_QUANTA); - dp.packU16(tempU16, "End"); - - tempU16 = (U16) ll_round(params->getHollow() / HOLLOW_QUANTA); - dp.packU16(tempU16, "Hollow"); - return true; + // Default to cylinder + static LLProfileParams defaultparams(LL_PCODE_PROFILE_CIRCLE, U16(0), U16(0), U16(0)); + + if (!params) + params = &defaultparams; + + U8 tempU8; + U16 tempU16; + + tempU8 = params->getCurveType(); + dp.packU8(tempU8, "Curve"); + + tempU16 = (U16) ll_round( params->getBegin() / CUT_QUANTA); + dp.packU16(tempU16, "Begin"); + + tempU16 = 50000 - (U16) ll_round(params->getEnd() / CUT_QUANTA); + dp.packU16(tempU16, "End"); + + tempU16 = (U16) ll_round(params->getHollow() / HOLLOW_QUANTA); + dp.packU16(tempU16, "Hollow"); + return true; } bool LLVolumeMessage::unpackProfileParams( - LLProfileParams* params, - LLMessageSystem* mesgsys, - char const* block_name, - S32 block_num) + LLProfileParams* params, + LLMessageSystem* mesgsys, + char const* block_name, + S32 block_num) { - bool ok = true; - U8 temp_u8; - U16 temp_u16; - F32 temp_f32; - - mesgsys->getU8Fast(block_name, _PREHASH_ProfileCurve, temp_u8, block_num); - params->setCurveType(temp_u8); - - mesgsys->getU16Fast(block_name, _PREHASH_ProfileBegin, temp_u16, block_num); - temp_f32 = temp_u16 * CUT_QUANTA; - if (temp_f32 > 1.f) - { - LL_WARNS() << "Profile begin out of range: " << temp_f32 - << ". Clamping to 0.0." << LL_ENDL; - temp_f32 = 0.f; - ok = false; - } - params->setBegin(temp_f32); - - mesgsys->getU16Fast(block_name, _PREHASH_ProfileEnd, temp_u16, block_num); - temp_f32 = temp_u16 * CUT_QUANTA; - if (temp_f32 > 1.f) - { - LL_WARNS() << "Profile end out of range: " << 1.f - temp_f32 - << ". Clamping to 1.0." << LL_ENDL; - temp_f32 = 1.f; - ok = false; - } - params->setEnd(1.f - temp_f32); - - mesgsys->getU16Fast(block_name, _PREHASH_ProfileHollow, temp_u16, block_num); - temp_f32 = temp_u16 * HOLLOW_QUANTA; - if (temp_f32 > 1.f) - { - LL_WARNS() << "Profile hollow out of range: " << temp_f32 - << ". Clamping to 0.0." << LL_ENDL; - temp_f32 = 0.f; - ok = false; - } - params->setHollow(temp_f32); - - /* - LL_INFOS() << "Unpacking Profile Block " << block_num << LL_ENDL; - LL_INFOS() << "Curve: " << (U32)getCurve() << LL_ENDL; - LL_INFOS() << "Begin: " << getBegin() << LL_ENDL; - LL_INFOS() << "End: " << getEnd() << LL_ENDL; - LL_INFOS() << "Hollow: " << getHollow() << LL_ENDL; - */ - return ok; + bool ok = true; + U8 temp_u8; + U16 temp_u16; + F32 temp_f32; + + mesgsys->getU8Fast(block_name, _PREHASH_ProfileCurve, temp_u8, block_num); + params->setCurveType(temp_u8); + + mesgsys->getU16Fast(block_name, _PREHASH_ProfileBegin, temp_u16, block_num); + temp_f32 = temp_u16 * CUT_QUANTA; + if (temp_f32 > 1.f) + { + LL_WARNS() << "Profile begin out of range: " << temp_f32 + << ". Clamping to 0.0." << LL_ENDL; + temp_f32 = 0.f; + ok = false; + } + params->setBegin(temp_f32); + + mesgsys->getU16Fast(block_name, _PREHASH_ProfileEnd, temp_u16, block_num); + temp_f32 = temp_u16 * CUT_QUANTA; + if (temp_f32 > 1.f) + { + LL_WARNS() << "Profile end out of range: " << 1.f - temp_f32 + << ". Clamping to 1.0." << LL_ENDL; + temp_f32 = 1.f; + ok = false; + } + params->setEnd(1.f - temp_f32); + + mesgsys->getU16Fast(block_name, _PREHASH_ProfileHollow, temp_u16, block_num); + temp_f32 = temp_u16 * HOLLOW_QUANTA; + if (temp_f32 > 1.f) + { + LL_WARNS() << "Profile hollow out of range: " << temp_f32 + << ". Clamping to 0.0." << LL_ENDL; + temp_f32 = 0.f; + ok = false; + } + params->setHollow(temp_f32); + + /* + LL_INFOS() << "Unpacking Profile Block " << block_num << LL_ENDL; + LL_INFOS() << "Curve: " << (U32)getCurve() << LL_ENDL; + LL_INFOS() << "Begin: " << getBegin() << LL_ENDL; + LL_INFOS() << "End: " << getEnd() << LL_ENDL; + LL_INFOS() << "Hollow: " << getHollow() << LL_ENDL; + */ + return ok; } bool LLVolumeMessage::unpackProfileParams( - LLProfileParams* params, - LLDataPacker &dp) + LLProfileParams* params, + LLDataPacker &dp) { - bool ok = true; - U8 temp_u8; - U16 temp_u16; - F32 temp_f32; - - dp.unpackU8(temp_u8, "Curve"); - params->setCurveType(temp_u8); - - dp.unpackU16(temp_u16, "Begin"); - temp_f32 = temp_u16 * CUT_QUANTA; - if (temp_f32 > 1.f) - { - LL_WARNS() << "Profile begin out of range: " << temp_f32 << LL_ENDL; - LL_WARNS() << "Clamping to 0.0" << LL_ENDL; - temp_f32 = 0.f; - ok = false; - } - params->setBegin(temp_f32); - - dp.unpackU16(temp_u16, "End"); - temp_f32 = temp_u16 * CUT_QUANTA; - if (temp_f32 > 1.f) - { - LL_WARNS() << "Profile end out of range: " << 1.f - temp_f32 << LL_ENDL; - LL_WARNS() << "Clamping to 1.0" << LL_ENDL; - temp_f32 = 1.f; - ok = false; - } - params->setEnd(1.f - temp_f32); - - dp.unpackU16(temp_u16, "Hollow"); - temp_f32 = temp_u16 * HOLLOW_QUANTA; - if (temp_f32 > 1.f) - { - LL_WARNS() << "Profile hollow out of range: " << temp_f32 << LL_ENDL; - LL_WARNS() << "Clamping to 0.0" << LL_ENDL; - temp_f32 = 0.f; - ok = false; - } - params->setHollow(temp_f32); - - return ok; + bool ok = true; + U8 temp_u8; + U16 temp_u16; + F32 temp_f32; + + dp.unpackU8(temp_u8, "Curve"); + params->setCurveType(temp_u8); + + dp.unpackU16(temp_u16, "Begin"); + temp_f32 = temp_u16 * CUT_QUANTA; + if (temp_f32 > 1.f) + { + LL_WARNS() << "Profile begin out of range: " << temp_f32 << LL_ENDL; + LL_WARNS() << "Clamping to 0.0" << LL_ENDL; + temp_f32 = 0.f; + ok = false; + } + params->setBegin(temp_f32); + + dp.unpackU16(temp_u16, "End"); + temp_f32 = temp_u16 * CUT_QUANTA; + if (temp_f32 > 1.f) + { + LL_WARNS() << "Profile end out of range: " << 1.f - temp_f32 << LL_ENDL; + LL_WARNS() << "Clamping to 1.0" << LL_ENDL; + temp_f32 = 1.f; + ok = false; + } + params->setEnd(1.f - temp_f32); + + dp.unpackU16(temp_u16, "Hollow"); + temp_f32 = temp_u16 * HOLLOW_QUANTA; + if (temp_f32 > 1.f) + { + LL_WARNS() << "Profile hollow out of range: " << temp_f32 << LL_ENDL; + LL_WARNS() << "Clamping to 0.0" << LL_ENDL; + temp_f32 = 0.f; + ok = false; + } + params->setHollow(temp_f32); + + return ok; } //============================================================================ @@ -206,248 +206,248 @@ bool LLVolumeMessage::unpackProfileParams( // For shear, range is -0.5 to 0.5, quanta is 0.01, 0 maps to 0 // For taper, range is -1 to 1, quanta is 0.01, 0 maps to 0 bool LLVolumeMessage::packPathParams( - const LLPathParams* params, - LLMessageSystem *mesgsys) + const LLPathParams* params, + LLMessageSystem *mesgsys) { - // Default to cylinder with no cut, top same size as bottom, no shear, no twist - static LLPathParams defaultparams(LL_PCODE_PATH_LINE, U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), 0); - if (!params) - params = &defaultparams; - - U8 curve = params->getCurveType(); - mesgsys->addU8Fast(_PREHASH_PathCurve, curve); + // Default to cylinder with no cut, top same size as bottom, no shear, no twist + static LLPathParams defaultparams(LL_PCODE_PATH_LINE, U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), 0); + if (!params) + params = &defaultparams; - U16 begin = (U16) ll_round(params->getBegin() / CUT_QUANTA); - mesgsys->addU16Fast(_PREHASH_PathBegin, begin); + U8 curve = params->getCurveType(); + mesgsys->addU8Fast(_PREHASH_PathCurve, curve); - U16 end = 50000 - (U16) ll_round(params->getEnd() / CUT_QUANTA); - mesgsys->addU16Fast(_PREHASH_PathEnd, end); + U16 begin = (U16) ll_round(params->getBegin() / CUT_QUANTA); + mesgsys->addU16Fast(_PREHASH_PathBegin, begin); - // Avoid truncation problem with direct F32->U8 cast. - // (e.g., (U8) (0.50 / 0.01) = (U8) 49.9999999 = 49 not 50. + U16 end = 50000 - (U16) ll_round(params->getEnd() / CUT_QUANTA); + mesgsys->addU16Fast(_PREHASH_PathEnd, end); - U8 pack_scale_x = 200 - (U8) ll_round(params->getScaleX() / SCALE_QUANTA); - mesgsys->addU8Fast(_PREHASH_PathScaleX, pack_scale_x ); + // Avoid truncation problem with direct F32->U8 cast. + // (e.g., (U8) (0.50 / 0.01) = (U8) 49.9999999 = 49 not 50. - U8 pack_scale_y = 200 - (U8) ll_round(params->getScaleY() / SCALE_QUANTA); - mesgsys->addU8Fast(_PREHASH_PathScaleY, pack_scale_y ); + U8 pack_scale_x = 200 - (U8) ll_round(params->getScaleX() / SCALE_QUANTA); + mesgsys->addU8Fast(_PREHASH_PathScaleX, pack_scale_x ); - U8 pack_shear_x = (U8) ll_round(params->getShearX() / SHEAR_QUANTA); - mesgsys->addU8Fast(_PREHASH_PathShearX, pack_shear_x ); + U8 pack_scale_y = 200 - (U8) ll_round(params->getScaleY() / SCALE_QUANTA); + mesgsys->addU8Fast(_PREHASH_PathScaleY, pack_scale_y ); - U8 pack_shear_y = (U8) ll_round(params->getShearY() / SHEAR_QUANTA); - mesgsys->addU8Fast(_PREHASH_PathShearY, pack_shear_y ); + U8 pack_shear_x = (U8) ll_round(params->getShearX() / SHEAR_QUANTA); + mesgsys->addU8Fast(_PREHASH_PathShearX, pack_shear_x ); - S8 twist = (S8) ll_round(params->getTwist() / SCALE_QUANTA); - mesgsys->addS8Fast(_PREHASH_PathTwist, twist); + U8 pack_shear_y = (U8) ll_round(params->getShearY() / SHEAR_QUANTA); + mesgsys->addU8Fast(_PREHASH_PathShearY, pack_shear_y ); - S8 twist_begin = (S8) ll_round(params->getTwistBegin() / SCALE_QUANTA); - mesgsys->addS8Fast(_PREHASH_PathTwistBegin, twist_begin); + S8 twist = (S8) ll_round(params->getTwist() / SCALE_QUANTA); + mesgsys->addS8Fast(_PREHASH_PathTwist, twist); - S8 radius_offset = (S8) ll_round(params->getRadiusOffset() / SCALE_QUANTA); - mesgsys->addS8Fast(_PREHASH_PathRadiusOffset, radius_offset); + S8 twist_begin = (S8) ll_round(params->getTwistBegin() / SCALE_QUANTA); + mesgsys->addS8Fast(_PREHASH_PathTwistBegin, twist_begin); - S8 taper_x = (S8) ll_round(params->getTaperX() / TAPER_QUANTA); - mesgsys->addS8Fast(_PREHASH_PathTaperX, taper_x); + S8 radius_offset = (S8) ll_round(params->getRadiusOffset() / SCALE_QUANTA); + mesgsys->addS8Fast(_PREHASH_PathRadiusOffset, radius_offset); - S8 taper_y = (S8) ll_round(params->getTaperY() / TAPER_QUANTA); - mesgsys->addS8Fast(_PREHASH_PathTaperY, taper_y); + S8 taper_x = (S8) ll_round(params->getTaperX() / TAPER_QUANTA); + mesgsys->addS8Fast(_PREHASH_PathTaperX, taper_x); - U8 revolutions = (U8) ll_round( (params->getRevolutions() - 1.0f) / REV_QUANTA); - mesgsys->addU8Fast(_PREHASH_PathRevolutions, revolutions); + S8 taper_y = (S8) ll_round(params->getTaperY() / TAPER_QUANTA); + mesgsys->addS8Fast(_PREHASH_PathTaperY, taper_y); - S8 skew = (S8) ll_round(params->getSkew() / SCALE_QUANTA); - mesgsys->addS8Fast(_PREHASH_PathSkew, skew); + U8 revolutions = (U8) ll_round( (params->getRevolutions() - 1.0f) / REV_QUANTA); + mesgsys->addU8Fast(_PREHASH_PathRevolutions, revolutions); - return true; + S8 skew = (S8) ll_round(params->getSkew() / SCALE_QUANTA); + mesgsys->addS8Fast(_PREHASH_PathSkew, skew); + + return true; } bool LLVolumeMessage::packPathParams( - const LLPathParams* params, - LLDataPacker &dp) + const LLPathParams* params, + LLDataPacker &dp) { - // Default to cylinder with no cut, top same size as bottom, no shear, no twist - static LLPathParams defaultparams(LL_PCODE_PATH_LINE, U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), 0); - if (!params) - params = &defaultparams; - - U8 curve = params->getCurveType(); - dp.packU8(curve, "Curve"); + // Default to cylinder with no cut, top same size as bottom, no shear, no twist + static LLPathParams defaultparams(LL_PCODE_PATH_LINE, U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), 0); + if (!params) + params = &defaultparams; + + U8 curve = params->getCurveType(); + dp.packU8(curve, "Curve"); - U16 begin = (U16) ll_round(params->getBegin() / CUT_QUANTA); - dp.packU16(begin, "Begin"); + U16 begin = (U16) ll_round(params->getBegin() / CUT_QUANTA); + dp.packU16(begin, "Begin"); - U16 end = 50000 - (U16) ll_round(params->getEnd() / CUT_QUANTA); - dp.packU16(end, "End"); + U16 end = 50000 - (U16) ll_round(params->getEnd() / CUT_QUANTA); + dp.packU16(end, "End"); - // Avoid truncation problem with direct F32->U8 cast. - // (e.g., (U8) (0.50 / 0.01) = (U8) 49.9999999 = 49 not 50. + // Avoid truncation problem with direct F32->U8 cast. + // (e.g., (U8) (0.50 / 0.01) = (U8) 49.9999999 = 49 not 50. - U8 pack_scale_x = 200 - (U8) ll_round(params->getScaleX() / SCALE_QUANTA); - dp.packU8(pack_scale_x, "ScaleX"); + U8 pack_scale_x = 200 - (U8) ll_round(params->getScaleX() / SCALE_QUANTA); + dp.packU8(pack_scale_x, "ScaleX"); - U8 pack_scale_y = 200 - (U8) ll_round(params->getScaleY() / SCALE_QUANTA); - dp.packU8(pack_scale_y, "ScaleY"); + U8 pack_scale_y = 200 - (U8) ll_round(params->getScaleY() / SCALE_QUANTA); + dp.packU8(pack_scale_y, "ScaleY"); - S8 pack_shear_x = (S8) ll_round(params->getShearX() / SHEAR_QUANTA); - dp.packU8(*(U8 *)&pack_shear_x, "ShearX"); + S8 pack_shear_x = (S8) ll_round(params->getShearX() / SHEAR_QUANTA); + dp.packU8(*(U8 *)&pack_shear_x, "ShearX"); - S8 pack_shear_y = (S8) ll_round(params->getShearY() / SHEAR_QUANTA); - dp.packU8(*(U8 *)&pack_shear_y, "ShearY"); + S8 pack_shear_y = (S8) ll_round(params->getShearY() / SHEAR_QUANTA); + dp.packU8(*(U8 *)&pack_shear_y, "ShearY"); - S8 twist = (S8) ll_round(params->getTwist() / SCALE_QUANTA); - dp.packU8(*(U8 *)&twist, "Twist"); - - S8 twist_begin = (S8) ll_round(params->getTwistBegin() / SCALE_QUANTA); - dp.packU8(*(U8 *)&twist_begin, "TwistBegin"); + S8 twist = (S8) ll_round(params->getTwist() / SCALE_QUANTA); + dp.packU8(*(U8 *)&twist, "Twist"); - S8 radius_offset = (S8) ll_round(params->getRadiusOffset() / SCALE_QUANTA); - dp.packU8(*(U8 *)&radius_offset, "RadiusOffset"); + S8 twist_begin = (S8) ll_round(params->getTwistBegin() / SCALE_QUANTA); + dp.packU8(*(U8 *)&twist_begin, "TwistBegin"); - S8 taper_x = (S8) ll_round(params->getTaperX() / TAPER_QUANTA); - dp.packU8(*(U8 *)&taper_x, "TaperX"); + S8 radius_offset = (S8) ll_round(params->getRadiusOffset() / SCALE_QUANTA); + dp.packU8(*(U8 *)&radius_offset, "RadiusOffset"); - S8 taper_y = (S8) ll_round(params->getTaperY() / TAPER_QUANTA); - dp.packU8(*(U8 *)&taper_y, "TaperY"); + S8 taper_x = (S8) ll_round(params->getTaperX() / TAPER_QUANTA); + dp.packU8(*(U8 *)&taper_x, "TaperX"); - U8 revolutions = (U8) ll_round( (params->getRevolutions() - 1.0f) / REV_QUANTA); - dp.packU8(*(U8 *)&revolutions, "Revolutions"); + S8 taper_y = (S8) ll_round(params->getTaperY() / TAPER_QUANTA); + dp.packU8(*(U8 *)&taper_y, "TaperY"); - S8 skew = (S8) ll_round(params->getSkew() / SCALE_QUANTA); - dp.packU8(*(U8 *)&skew, "Skew"); + U8 revolutions = (U8) ll_round( (params->getRevolutions() - 1.0f) / REV_QUANTA); + dp.packU8(*(U8 *)&revolutions, "Revolutions"); - return true; + S8 skew = (S8) ll_round(params->getSkew() / SCALE_QUANTA); + dp.packU8(*(U8 *)&skew, "Skew"); + + return true; } bool LLVolumeMessage::unpackPathParams( - LLPathParams* params, - LLMessageSystem* mesgsys, - char const* block_name, - S32 block_num) + LLPathParams* params, + LLMessageSystem* mesgsys, + char const* block_name, + S32 block_num) { - U8 curve; - mesgsys->getU8Fast(block_name, _PREHASH_PathCurve, curve, block_num); - params->setCurveType(curve); - - U16 begin; - mesgsys->getU16Fast(block_name, _PREHASH_PathBegin, begin, block_num); - params->setBegin((F32)(begin * CUT_QUANTA)); - - U16 end; - mesgsys->getU16Fast(block_name, _PREHASH_PathEnd, end, block_num); - params->setEnd((F32)((50000 - end) * CUT_QUANTA)); - - U8 pack_scale_x, pack_scale_y; - mesgsys->getU8Fast(block_name, _PREHASH_PathScaleX, pack_scale_x, block_num); - mesgsys->getU8Fast(block_name, _PREHASH_PathScaleY, pack_scale_y, block_num); - F32 x = (F32) (200 - pack_scale_x) * SCALE_QUANTA; - F32 y = (F32) (200 - pack_scale_y) * SCALE_QUANTA; - params->setScale( x, y ); - - S8 shear_x_quant, shear_y_quant; - mesgsys->getS8Fast(block_name, _PREHASH_PathShearX, shear_x_quant, block_num); - mesgsys->getS8Fast(block_name, _PREHASH_PathShearY, shear_y_quant, block_num); - F32 shear_x = (F32) shear_x_quant * SHEAR_QUANTA; - F32 shear_y = (F32) shear_y_quant * SHEAR_QUANTA; - params->setShear( shear_x, shear_y ); - - S8 twist; - mesgsys->getS8Fast(block_name, _PREHASH_PathTwist, twist, block_num ); - params->setTwist((F32)(twist * SCALE_QUANTA)); - - S8 twist_begin; - mesgsys->getS8Fast(block_name, _PREHASH_PathTwistBegin, twist_begin, block_num ); - params->setTwistBegin((F32)(twist_begin * SCALE_QUANTA)); - - S8 radius_offset; - mesgsys->getS8Fast(block_name, _PREHASH_PathRadiusOffset, radius_offset, block_num ); - params->setRadiusOffset((F32)(radius_offset * SCALE_QUANTA)); - - S8 taper_x_quant, taper_y_quant; - mesgsys->getS8Fast(block_name, _PREHASH_PathTaperX, taper_x_quant, block_num ); - mesgsys->getS8Fast(block_name, _PREHASH_PathTaperY, taper_y_quant, block_num ); - F32 taper_x = (F32)(taper_x_quant * TAPER_QUANTA); - F32 taper_y = (F32)(taper_y_quant * TAPER_QUANTA); - params->setTaper( taper_x, taper_y ); - - U8 revolutions; - mesgsys->getU8Fast(block_name, _PREHASH_PathRevolutions, revolutions, block_num ); - params->setRevolutions((F32)(revolutions * REV_QUANTA + 1.0f)); - - S8 skew; - mesgsys->getS8Fast(block_name, _PREHASH_PathSkew, skew, block_num ); - params->setSkew((F32)(skew * SCALE_QUANTA)); + U8 curve; + mesgsys->getU8Fast(block_name, _PREHASH_PathCurve, curve, block_num); + params->setCurveType(curve); + + U16 begin; + mesgsys->getU16Fast(block_name, _PREHASH_PathBegin, begin, block_num); + params->setBegin((F32)(begin * CUT_QUANTA)); + + U16 end; + mesgsys->getU16Fast(block_name, _PREHASH_PathEnd, end, block_num); + params->setEnd((F32)((50000 - end) * CUT_QUANTA)); + + U8 pack_scale_x, pack_scale_y; + mesgsys->getU8Fast(block_name, _PREHASH_PathScaleX, pack_scale_x, block_num); + mesgsys->getU8Fast(block_name, _PREHASH_PathScaleY, pack_scale_y, block_num); + F32 x = (F32) (200 - pack_scale_x) * SCALE_QUANTA; + F32 y = (F32) (200 - pack_scale_y) * SCALE_QUANTA; + params->setScale( x, y ); + + S8 shear_x_quant, shear_y_quant; + mesgsys->getS8Fast(block_name, _PREHASH_PathShearX, shear_x_quant, block_num); + mesgsys->getS8Fast(block_name, _PREHASH_PathShearY, shear_y_quant, block_num); + F32 shear_x = (F32) shear_x_quant * SHEAR_QUANTA; + F32 shear_y = (F32) shear_y_quant * SHEAR_QUANTA; + params->setShear( shear_x, shear_y ); + + S8 twist; + mesgsys->getS8Fast(block_name, _PREHASH_PathTwist, twist, block_num ); + params->setTwist((F32)(twist * SCALE_QUANTA)); + + S8 twist_begin; + mesgsys->getS8Fast(block_name, _PREHASH_PathTwistBegin, twist_begin, block_num ); + params->setTwistBegin((F32)(twist_begin * SCALE_QUANTA)); + + S8 radius_offset; + mesgsys->getS8Fast(block_name, _PREHASH_PathRadiusOffset, radius_offset, block_num ); + params->setRadiusOffset((F32)(radius_offset * SCALE_QUANTA)); + + S8 taper_x_quant, taper_y_quant; + mesgsys->getS8Fast(block_name, _PREHASH_PathTaperX, taper_x_quant, block_num ); + mesgsys->getS8Fast(block_name, _PREHASH_PathTaperY, taper_y_quant, block_num ); + F32 taper_x = (F32)(taper_x_quant * TAPER_QUANTA); + F32 taper_y = (F32)(taper_y_quant * TAPER_QUANTA); + params->setTaper( taper_x, taper_y ); + + U8 revolutions; + mesgsys->getU8Fast(block_name, _PREHASH_PathRevolutions, revolutions, block_num ); + params->setRevolutions((F32)(revolutions * REV_QUANTA + 1.0f)); + + S8 skew; + mesgsys->getS8Fast(block_name, _PREHASH_PathSkew, skew, block_num ); + params->setSkew((F32)(skew * SCALE_QUANTA)); /* - LL_INFOS() << "Unpacking Path Block " << block_num << LL_ENDL; - LL_INFOS() << "Curve: " << (U32)params->getCurve() << LL_ENDL; - LL_INFOS() << "Begin: " << params->getBegin() << LL_ENDL; - LL_INFOS() << "End: " << params->getEnd() << LL_ENDL; - LL_INFOS() << "Scale: " << params->getScale() << LL_ENDL; - LL_INFOS() << "Twist: " << params->getTwist() << LL_ENDL; + LL_INFOS() << "Unpacking Path Block " << block_num << LL_ENDL; + LL_INFOS() << "Curve: " << (U32)params->getCurve() << LL_ENDL; + LL_INFOS() << "Begin: " << params->getBegin() << LL_ENDL; + LL_INFOS() << "End: " << params->getEnd() << LL_ENDL; + LL_INFOS() << "Scale: " << params->getScale() << LL_ENDL; + LL_INFOS() << "Twist: " << params->getTwist() << LL_ENDL; */ - return true; + return true; } bool LLVolumeMessage::unpackPathParams(LLPathParams* params, LLDataPacker &dp) { - U8 value; - S8 svalue; - U16 temp_u16; - - dp.unpackU8(value, "Curve"); - params->setCurveType( value ); - - dp.unpackU16(temp_u16, "Begin"); - params->setBegin((F32)(temp_u16 * CUT_QUANTA)); - - dp.unpackU16(temp_u16, "End"); - params->setEnd((F32)((50000 - temp_u16) * CUT_QUANTA)); - - dp.unpackU8(value, "ScaleX"); - F32 x = (F32) (200 - value) * SCALE_QUANTA; - dp.unpackU8(value, "ScaleY"); - F32 y = (F32) (200 - value) * SCALE_QUANTA; - params->setScale( x, y ); - - dp.unpackU8(value, "ShearX"); - svalue = *(S8 *)&value; - F32 shear_x = (F32) svalue * SHEAR_QUANTA; - dp.unpackU8(value, "ShearY"); - svalue = *(S8 *)&value; - F32 shear_y = (F32) svalue * SHEAR_QUANTA; - params->setShear( shear_x, shear_y ); - - dp.unpackU8(value, "Twist"); - svalue = *(S8 *)&value; - params->setTwist((F32)(svalue * SCALE_QUANTA)); - - dp.unpackU8(value, "TwistBegin"); - svalue = *(S8 *)&value; - params->setTwistBegin((F32)(svalue * SCALE_QUANTA)); - - dp.unpackU8(value, "RadiusOffset"); - svalue = *(S8 *)&value; - params->setRadiusOffset((F32)(svalue * SCALE_QUANTA)); - - dp.unpackU8(value, "TaperX"); - svalue = *(S8 *)&value; - params->setTaperX((F32)(svalue * TAPER_QUANTA)); - - dp.unpackU8(value, "TaperY"); - svalue = *(S8 *)&value; - params->setTaperY((F32)(svalue * TAPER_QUANTA)); - - dp.unpackU8(value, "Revolutions"); - params->setRevolutions((F32)(value * REV_QUANTA + 1.0f)); - - dp.unpackU8(value, "Skew"); - svalue = *(S8 *)&value; - params->setSkew((F32)(svalue * SCALE_QUANTA)); - - return true; + U8 value; + S8 svalue; + U16 temp_u16; + + dp.unpackU8(value, "Curve"); + params->setCurveType( value ); + + dp.unpackU16(temp_u16, "Begin"); + params->setBegin((F32)(temp_u16 * CUT_QUANTA)); + + dp.unpackU16(temp_u16, "End"); + params->setEnd((F32)((50000 - temp_u16) * CUT_QUANTA)); + + dp.unpackU8(value, "ScaleX"); + F32 x = (F32) (200 - value) * SCALE_QUANTA; + dp.unpackU8(value, "ScaleY"); + F32 y = (F32) (200 - value) * SCALE_QUANTA; + params->setScale( x, y ); + + dp.unpackU8(value, "ShearX"); + svalue = *(S8 *)&value; + F32 shear_x = (F32) svalue * SHEAR_QUANTA; + dp.unpackU8(value, "ShearY"); + svalue = *(S8 *)&value; + F32 shear_y = (F32) svalue * SHEAR_QUANTA; + params->setShear( shear_x, shear_y ); + + dp.unpackU8(value, "Twist"); + svalue = *(S8 *)&value; + params->setTwist((F32)(svalue * SCALE_QUANTA)); + + dp.unpackU8(value, "TwistBegin"); + svalue = *(S8 *)&value; + params->setTwistBegin((F32)(svalue * SCALE_QUANTA)); + + dp.unpackU8(value, "RadiusOffset"); + svalue = *(S8 *)&value; + params->setRadiusOffset((F32)(svalue * SCALE_QUANTA)); + + dp.unpackU8(value, "TaperX"); + svalue = *(S8 *)&value; + params->setTaperX((F32)(svalue * TAPER_QUANTA)); + + dp.unpackU8(value, "TaperY"); + svalue = *(S8 *)&value; + params->setTaperY((F32)(svalue * TAPER_QUANTA)); + + dp.unpackU8(value, "Revolutions"); + params->setRevolutions((F32)(value * REV_QUANTA + 1.0f)); + + dp.unpackU8(value, "Skew"); + svalue = *(S8 *)&value; + params->setSkew((F32)(svalue * SCALE_QUANTA)); + + return true; } //============================================================================ @@ -455,101 +455,101 @@ bool LLVolumeMessage::unpackPathParams(LLPathParams* params, LLDataPacker &dp) // static bool LLVolumeMessage::constrainVolumeParams(LLVolumeParams& params) { - U32 bad = 0; - - // This is called immediately after an unpack. feed the raw data - // through the checked setters to constraint it to a valid set of - // volume params. - bad |= params.setType(params.getProfileParams().getCurveType(), - params.getPathParams().getCurveType()) ? 0 : 1; - bad |= params.setBeginAndEndS(params.getProfileParams().getBegin(), - params.getProfileParams().getEnd()) ? 0 : 2; - bad |= params.setBeginAndEndT(params.getPathParams().getBegin(), - params.getPathParams().getEnd()) ? 0 : 4; - bad |= params.setHollow(params.getProfileParams().getHollow()) ? 0 : 8; - bad |= params.setTwistBegin(params.getPathParams().getTwistBegin()) ? 0 : 0x10; - bad |= params.setTwistEnd(params.getPathParams().getTwistEnd()) ? 0 : 0x20; - bad |= params.setRatio(params.getPathParams().getScaleX(), - params.getPathParams().getScaleY()) ? 0 : 0x40; - bad |= params.setShear(params.getPathParams().getShearX(), - params.getPathParams().getShearY()) ? 0 : 0x80; - bad |= params.setTaper(params.getPathParams().getTaperX(), - params.getPathParams().getTaperY()) ? 0 : 0x100; - bad |= params.setRevolutions(params.getPathParams().getRevolutions()) ? 0 : 0x200; - bad |= params.setRadiusOffset(params.getPathParams().getRadiusOffset()) ? 0 : 0x400; - bad |= params.setSkew(params.getPathParams().getSkew()) ? 0 : 0x800; - if(bad) - { - LL_WARNS() << "LLVolumeMessage::constrainVolumeParams() - " - << "forced to constrain incoming volume params: " - << llformat("0x%04x",bad) << LL_ENDL; - } - return bad ? false : true; + U32 bad = 0; + + // This is called immediately after an unpack. feed the raw data + // through the checked setters to constraint it to a valid set of + // volume params. + bad |= params.setType(params.getProfileParams().getCurveType(), + params.getPathParams().getCurveType()) ? 0 : 1; + bad |= params.setBeginAndEndS(params.getProfileParams().getBegin(), + params.getProfileParams().getEnd()) ? 0 : 2; + bad |= params.setBeginAndEndT(params.getPathParams().getBegin(), + params.getPathParams().getEnd()) ? 0 : 4; + bad |= params.setHollow(params.getProfileParams().getHollow()) ? 0 : 8; + bad |= params.setTwistBegin(params.getPathParams().getTwistBegin()) ? 0 : 0x10; + bad |= params.setTwistEnd(params.getPathParams().getTwistEnd()) ? 0 : 0x20; + bad |= params.setRatio(params.getPathParams().getScaleX(), + params.getPathParams().getScaleY()) ? 0 : 0x40; + bad |= params.setShear(params.getPathParams().getShearX(), + params.getPathParams().getShearY()) ? 0 : 0x80; + bad |= params.setTaper(params.getPathParams().getTaperX(), + params.getPathParams().getTaperY()) ? 0 : 0x100; + bad |= params.setRevolutions(params.getPathParams().getRevolutions()) ? 0 : 0x200; + bad |= params.setRadiusOffset(params.getPathParams().getRadiusOffset()) ? 0 : 0x400; + bad |= params.setSkew(params.getPathParams().getSkew()) ? 0 : 0x800; + if(bad) + { + LL_WARNS() << "LLVolumeMessage::constrainVolumeParams() - " + << "forced to constrain incoming volume params: " + << llformat("0x%04x",bad) << LL_ENDL; + } + return bad ? false : true; } bool LLVolumeMessage::packVolumeParams(const LLVolumeParams* params, LLMessageSystem *mesgsys) { - // LL_INFOS() << "pack volume" << LL_ENDL; - if (params) - { - packPathParams(¶ms->getPathParams(), mesgsys); - packProfileParams(¶ms->getProfileParams(), mesgsys); - } - else - { - packPathParams(0, mesgsys); - packProfileParams(0, mesgsys); - } - return true; + // LL_INFOS() << "pack volume" << LL_ENDL; + if (params) + { + packPathParams(¶ms->getPathParams(), mesgsys); + packProfileParams(¶ms->getProfileParams(), mesgsys); + } + else + { + packPathParams(0, mesgsys); + packProfileParams(0, mesgsys); + } + return true; } bool LLVolumeMessage::packVolumeParams(const LLVolumeParams* params, LLDataPacker &dp) { - // LL_INFOS() << "pack volume" << LL_ENDL; - if (params) - { - packPathParams(¶ms->getPathParams(), dp); - packProfileParams(¶ms->getProfileParams(), dp); - } - else - { - packPathParams(0, dp); - packProfileParams(0, dp); - } - return true; + // LL_INFOS() << "pack volume" << LL_ENDL; + if (params) + { + packPathParams(¶ms->getPathParams(), dp); + packProfileParams(¶ms->getProfileParams(), dp); + } + else + { + packPathParams(0, dp); + packProfileParams(0, dp); + } + return true; } bool LLVolumeMessage::unpackVolumeParams( - LLVolumeParams* params, - LLMessageSystem* mesgsys, - char const* block_name, - S32 block_num) + LLVolumeParams* params, + LLMessageSystem* mesgsys, + char const* block_name, + S32 block_num) { - bool ok = true; - ok &= unpackPathParams( - ¶ms->getPathParams(), - mesgsys, - block_name, - block_num); - ok &= unpackProfileParams( - ¶ms->getProfileParams(), - mesgsys, - block_name, - block_num); - ok &= constrainVolumeParams(*params); - - return ok; + bool ok = true; + ok &= unpackPathParams( + ¶ms->getPathParams(), + mesgsys, + block_name, + block_num); + ok &= unpackProfileParams( + ¶ms->getProfileParams(), + mesgsys, + block_name, + block_num); + ok &= constrainVolumeParams(*params); + + return ok; } bool LLVolumeMessage::unpackVolumeParams( - LLVolumeParams* params, - LLDataPacker &dp) + LLVolumeParams* params, + LLDataPacker &dp) { - bool ok = true; - ok &= unpackPathParams(¶ms->getPathParams(), dp); - ok &= unpackProfileParams(¶ms->getProfileParams(), dp); - ok &= constrainVolumeParams(*params); - return ok; + bool ok = true; + ok &= unpackPathParams(¶ms->getPathParams(), dp); + ok &= unpackProfileParams(¶ms->getProfileParams(), dp); + ok &= constrainVolumeParams(*params); + return ok; } //============================================================================ diff --git a/indra/llprimitive/llvolumemessage.h b/indra/llprimitive/llvolumemessage.h index f59ee79c60..609608023a 100644 --- a/indra/llprimitive/llvolumemessage.h +++ b/indra/llprimitive/llvolumemessage.h @@ -1,25 +1,25 @@ -/** +/** * @file llvolumemessage.h * @brief LLVolumeMessage base class * * $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$ */ @@ -36,56 +36,56 @@ class LLDataPacker; class LLVolumeMessage { protected: - // The profile and path params are protected since they do not do - // any kind of parameter validation or clamping. Use the public - // pack and unpack volume param methods below + // The profile and path params are protected since they do not do + // any kind of parameter validation or clamping. Use the public + // pack and unpack volume param methods below - static bool packProfileParams( - const LLProfileParams* params, - LLMessageSystem* mesgsys); - static bool packProfileParams( - const LLProfileParams* params, - LLDataPacker& dp); - static bool unpackProfileParams( - LLProfileParams* params, - LLMessageSystem* mesgsys, - char const* block_name, - S32 block_num = 0); - static bool unpackProfileParams(LLProfileParams* params, LLDataPacker& dp); + static bool packProfileParams( + const LLProfileParams* params, + LLMessageSystem* mesgsys); + static bool packProfileParams( + const LLProfileParams* params, + LLDataPacker& dp); + static bool unpackProfileParams( + LLProfileParams* params, + LLMessageSystem* mesgsys, + char const* block_name, + S32 block_num = 0); + static bool unpackProfileParams(LLProfileParams* params, LLDataPacker& dp); - static bool packPathParams( - const LLPathParams* params, - LLMessageSystem* mesgsys); - static bool packPathParams(const LLPathParams* params, LLDataPacker& dp); - static bool unpackPathParams( - LLPathParams* params, - LLMessageSystem* mesgsys, - char const* block_name, - S32 block_num = 0); - static bool unpackPathParams(LLPathParams* params, LLDataPacker& dp); + static bool packPathParams( + const LLPathParams* params, + LLMessageSystem* mesgsys); + static bool packPathParams(const LLPathParams* params, LLDataPacker& dp); + static bool unpackPathParams( + LLPathParams* params, + LLMessageSystem* mesgsys, + char const* block_name, + S32 block_num = 0); + static bool unpackPathParams(LLPathParams* params, LLDataPacker& dp); public: - /** - * @brief This method constrains any volume params to make them valid. - * - * @param[in,out] Possibly invalid params in, always valid out. - * @return Returns true if the in params were valid, and therefore - * unchanged. - */ - static bool constrainVolumeParams(LLVolumeParams& params); + /** + * @brief This method constrains any volume params to make them valid. + * + * @param[in,out] Possibly invalid params in, always valid out. + * @return Returns true if the in params were valid, and therefore + * unchanged. + */ + static bool constrainVolumeParams(LLVolumeParams& params); - static bool packVolumeParams( - const LLVolumeParams* params, - LLMessageSystem* mesgsys); - static bool packVolumeParams( - const LLVolumeParams* params, - LLDataPacker& dp); - static bool unpackVolumeParams( - LLVolumeParams* params, - LLMessageSystem* mesgsys, - char const* block_name, - S32 block_num = 0); - static bool unpackVolumeParams(LLVolumeParams* params, LLDataPacker &dp); + static bool packVolumeParams( + const LLVolumeParams* params, + LLMessageSystem* mesgsys); + static bool packVolumeParams( + const LLVolumeParams* params, + LLDataPacker& dp); + static bool unpackVolumeParams( + LLVolumeParams* params, + LLMessageSystem* mesgsys, + char const* block_name, + S32 block_num = 0); + static bool unpackVolumeParams(LLVolumeParams* params, LLDataPacker &dp); }; #endif // LL_LLVOLUMEMESSAGE_H diff --git a/indra/llprimitive/material_codes.cpp b/indra/llprimitive/material_codes.cpp index 2ea47eec36..c66490a0b8 100644 --- a/indra/llprimitive/material_codes.cpp +++ b/indra/llprimitive/material_codes.cpp @@ -1,25 +1,25 @@ -/** +/** * @file material_codes.cpp * @brief Material_codes definitions * * $LicenseInfo:firstyear=2000&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$ */ diff --git a/indra/llprimitive/material_codes.h b/indra/llprimitive/material_codes.h index 84a6f2edd2..bad3345425 100644 --- a/indra/llprimitive/material_codes.h +++ b/indra/llprimitive/material_codes.h @@ -1,25 +1,25 @@ -/** +/** * @file material_codes.h * @brief Material_codes definitions * * $LicenseInfo:firstyear=2000&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$ */ @@ -29,17 +29,17 @@ class LLUUID; - // material types -const U8 LL_MCODE_STONE = 0; -const U8 LL_MCODE_METAL = 1; -const U8 LL_MCODE_GLASS = 2; -const U8 LL_MCODE_WOOD = 3; -const U8 LL_MCODE_FLESH = 4; -const U8 LL_MCODE_PLASTIC = 5; -const U8 LL_MCODE_RUBBER = 6; -const U8 LL_MCODE_LIGHT = 7; + // material types +const U8 LL_MCODE_STONE = 0; +const U8 LL_MCODE_METAL = 1; +const U8 LL_MCODE_GLASS = 2; +const U8 LL_MCODE_WOOD = 3; +const U8 LL_MCODE_FLESH = 4; +const U8 LL_MCODE_PLASTIC = 5; +const U8 LL_MCODE_RUBBER = 6; +const U8 LL_MCODE_LIGHT = 7; const U8 LL_MCODE_END = 8; -const U8 LL_MCODE_MASK = 0x0F; +const U8 LL_MCODE_MASK = 0x0F; // *NOTE: Define these in .cpp file to reduce duplicate instances extern const LLUUID LL_DEFAULT_STONE_UUID; diff --git a/indra/llprimitive/object_flags.h b/indra/llprimitive/object_flags.h index 88eaeb034a..e2cdba072a 100644 --- a/indra/llprimitive/object_flags.h +++ b/indra/llprimitive/object_flags.h @@ -1,25 +1,25 @@ -/** +/** * @file object_flags.h * @brief Flags for object creation and transmission * * $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$ */ @@ -73,12 +73,12 @@ const U32 FLAGS_WORLD = FLAGS_USE_PHYSICS | FLAGS_PHANTOM | FLA typedef enum e_havok_joint_type { - HJT_INVALID = 0, - HJT_HINGE = 1, - HJT_POINT = 2, -// HJT_LPOINT = 3, -// HJT_WHEEL = 4, - HJT_EOF = 3 + HJT_INVALID = 0, + HJT_HINGE = 1, + HJT_POINT = 2, +// HJT_LPOINT = 3, +// HJT_WHEEL = 4, + HJT_EOF = 3 } EHavokJointType; #endif diff --git a/indra/llprimitive/tests/llmediaentry_test.cpp b/indra/llprimitive/tests/llmediaentry_test.cpp index c3e17d1267..e8f40d1ffd 100644 --- a/indra/llprimitive/tests/llmediaentry_test.cpp +++ b/indra/llprimitive/tests/llmediaentry_test.cpp @@ -1,27 +1,27 @@ -/** +/** * @file llmediaentry_test.cpp * @brief llmediaentry unit tests * - * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * $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$ + * $/LicenseInfo$ */ #include "linden_common.h" @@ -154,7 +154,7 @@ namespace tut defaultMediaEntryStr = DEFAULT_MEDIA_ENTRY; std::istringstream d(DEFAULT_MEDIA_ENTRY); LLSDSerialize::fromXML(defaultMediaEntryLLSD, d); - } + } std::string emptyMediaEntryStr; LLSD emptyMediaEntryLLSD; std::string defaultMediaEntryStr; @@ -164,7 +164,7 @@ namespace tut typedef test_group<MediaEntry_test, 55> factory; typedef factory::object object; } - + namespace { @@ -237,18 +237,18 @@ namespace tut whitelist_test(num, true, whitelist, candidate_url, true); } - template<> template<> - void object::test<1>() - { - set_test_name("Test LLMediaEntry Instantiation"); - LLMediaEntry entry; + template<> template<> + void object::test<1>() + { + set_test_name("Test LLMediaEntry Instantiation"); + LLMediaEntry entry; ensure_llsd_equals(get_test_name() + " failed", defaultMediaEntryLLSD, entry.asLLSD()); - } + } - template<> template<> - void object::test<2>() - { - set_test_name("Test LLMediaEntry Instantiation from LLSD"); + template<> template<> + void object::test<2>() + { + set_test_name("Test LLMediaEntry Instantiation from LLSD"); LLMediaEntry entry; LLSD sd; entry.fromLLSD(sd); @@ -275,33 +275,33 @@ namespace tut set_test_name("Test LLMediaEntry::asLLSD()"); LLMediaEntry entry; LLSD sd; - // Put some cruft in the LLSD + // Put some cruft in the LLSD sd[LLMediaEntry::CURRENT_URL_KEY] = "http://www.example.com"; - LLSD whitelist; - whitelist.append("*.example.com"); + LLSD whitelist; + whitelist.append("*.example.com"); sd[LLMediaEntry::WHITELIST_KEY] = whitelist; entry.asLLSD(sd); ensure_llsd_equals(get_test_name() + " failed", defaultMediaEntryLLSD, sd); } - + template<> template<> void object::test<5>() { set_test_name("Test LLMediaEntry::asLLSD() -> LLMediaEntry::fromLLSD()"); LLMediaEntry entry1, entry2; - // Add a whitelist to entry2 - std::vector<std::string> whitelist; - whitelist.push_back("*.example.com"); + // Add a whitelist to entry2 + std::vector<std::string> whitelist; + whitelist.push_back("*.example.com"); entry2.setWhiteList(whitelist); - // Render entry1 (which has no whitelist) as an LLSD + // Render entry1 (which has no whitelist) as an LLSD LLSD sd; - entry1.asLLSD(sd); - // "read" that LLSD into entry 2 - entry2.fromLLSD(sd); + entry1.asLLSD(sd); + // "read" that LLSD into entry 2 + entry2.fromLLSD(sd); ensure_llsd_equals(get_test_name() + " failed", defaultMediaEntryLLSD, entry2.asLLSD()); } - + // limit tests const char *URL_OK = "http://www.example.com"; const char *URL_TOO_BIG = "http://www.example.com.qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq"; @@ -315,7 +315,7 @@ namespace tut ensure(get_test_name() + " ok failed", status == LSL_STATUS_OK); status = entry.setCurrentURL(URL_TOO_BIG); ensure(get_test_name() + " ok failed", status == LSL_STATUS_BOUNDS_ERROR); - } + } template<> template<> void object::test<7>() @@ -332,7 +332,7 @@ namespace tut void object::test<8>() { set_test_name("Test Limits on setting whitelist"); - + // Test a valid list LLMediaEntry entry; std::vector<std::string> whitelist; @@ -346,7 +346,7 @@ namespace tut void object::test<9>() { set_test_name("Test Limits on setting whitelist too big"); - + // Test an invalid list LLMediaEntry entry; std::vector<std::string> whitelist, empty; @@ -361,7 +361,7 @@ namespace tut void object::test<10>() { set_test_name("Test Limits on setting whitelist too many"); - + // Test an invalid list LLMediaEntry entry; std::vector<std::string> whitelist, empty; @@ -377,7 +377,7 @@ namespace tut void object::test<11>() { set_test_name("Test to make sure both setWhiteList() functions behave the same"); - + // Test a valid list std::vector<std::string> whitelist, empty; LLSD whitelist_llsd; @@ -387,10 +387,10 @@ namespace tut ensure(get_test_name() + " setWhiteList(s) don't match", entry1.setWhiteList(whitelist) == LSL_STATUS_OK && entry2.setWhiteList(whitelist_llsd)== LSL_STATUS_OK ); - ensure(get_test_name() + " failed", + ensure(get_test_name() + " failed", entry1.getWhiteList() == entry2.getWhiteList()); } - + template<> template<> void object::test<12>() { @@ -407,7 +407,7 @@ namespace tut ensure(get_test_name() + " setWhiteList(s) don't match", entry1.setWhiteList(whitelist) == LSL_STATUS_BOUNDS_ERROR && entry2.setWhiteList(whitelist_llsd) == LSL_STATUS_BOUNDS_ERROR); - ensure(get_test_name() + " failed", + ensure(get_test_name() + " failed", empty == entry1.getWhiteList() && empty == entry2.getWhiteList()); } @@ -425,78 +425,78 @@ namespace tut whitelist_llsd.append("Q"); } LLMediaEntry entry1, entry2; - ensure(get_test_name() + " invalid result", + ensure(get_test_name() + " invalid result", entry1.setWhiteList(whitelist) == LSL_STATUS_BOUNDS_ERROR && entry2.setWhiteList(whitelist_llsd) == LSL_STATUS_BOUNDS_ERROR); - ensure(get_test_name() + " failed", + ensure(get_test_name() + " failed", empty == entry1.getWhiteList() && empty == entry2.getWhiteList()); } - + template<> template<> - void object::test<14>() - { - // Whitelist check tests - int n=0; - - // Check the "empty whitelist" case - whitelist_test(++n, "", "http://www.example.com", true); - - // Check the "missing scheme" case - whitelist_test(++n, "www.example.com", "http://www.example.com", true); - - // Check the "exactly the same" case - whitelist_test(++n, "http://example.com", "http://example.com", true); - - // Check the enable flag - whitelist_test(++n, false, "www.example.com", "http://www.secondlife.com", true); - whitelist_test(++n, true, "www.example.com", "http://www.secondlife.com", false); - - // Check permutations of trailing slash: - whitelist_test(++n, "http://www.example.com", "http://www.example.com/", true); - whitelist_test(++n, "http://www.example.com/", "http://www.example.com/", true); - whitelist_test(++n, "http://www.example.com/", "http://www.example.com", false); - whitelist_test(++n, "http://www.example.com", "http://www.example.com/foobar", true); - whitelist_test(++n, "http://www.example.com/", "http://www.example.com/foobar", false); - - - // More cases... - whitelist_test(++n, "http://example.com", "http://example.com/wiki", true); - whitelist_test(++n, "www.example.com", "http://www.example.com/help", true); - whitelist_test(++n, "http://www.example.com", "http://wwwexample.com", false); - whitelist_test(++n, "http://www.example.com", "http://www.example.com/wiki", true); - whitelist_test(++n, "example.com", "http://wwwexample.com", false); - whitelist_test(++n, "http://www.example.com/", "http://www.amazon.com/wiki", false); - whitelist_test(++n, "www.example.com", "http://www.amazon.com", false); - - // regexp cases - whitelist_test(++n, "*.example.com", "http://www.example.com", true); - whitelist_test(++n, "*.example.com", "http://www.amazon.com", false); - whitelist_test(++n, "*.example.com", "http://www.example.com/foo/bar", true); - whitelist_test(++n, "*.example.com", "http:/example.com/foo/bar", false); - whitelist_test(++n, "*example.com", "http://example.com/foo/bar", true); - whitelist_test(++n, "*example.com", "http://my.virus.com/foo/bar?example.com", false); - whitelist_test(++n, "example.com", "http://my.virus.com/foo/bar?example.com", false); - whitelist_test(++n, "*example.com", "http://my.virus.com/foo/bar?*example.com", false); - whitelist_test(++n, "http://*example.com", "http://www.example.com", true); - whitelist_test(++n, "http://*.example.com", "http://www.example.com", true); - whitelist_test(++n, "http://*.e$?^.com", "http://www.e$?^.com", true); - whitelist_test(++n, "*.example.com/foo/bar", "http://www.example.com/", false); - whitelist_test(++n, "*.example.com/foo/bar", "http://example.com/foo/bar", false); - whitelist_test(++n, "http://*.example.com/foo/bar", "http://www.example.com", false); - whitelist_test(++n, "http://*.example.com", "https://www.example.com", false); - whitelist_test(++n, "http*://*.example.com", "rtsp://www.example.com", false); - whitelist_test(++n, "http*://*.example.com", "https://www.example.com", true); - whitelist_test(++n, "example.com", "http://www.example.com", false); - whitelist_test(++n, "www.example.com", "http://www.example.com:80", false); - whitelist_test(++n, "www.example.com", "http://www.example.com", true); - whitelist_test(++n, "www.example.com/", "http://www.example.com", false); - whitelist_test(++n, "www.example.com/foo/bar/*", "http://www.example.com/foo/bar/baz", true); + void object::test<14>() + { + // Whitelist check tests + int n=0; + + // Check the "empty whitelist" case + whitelist_test(++n, "", "http://www.example.com", true); + + // Check the "missing scheme" case + whitelist_test(++n, "www.example.com", "http://www.example.com", true); + + // Check the "exactly the same" case + whitelist_test(++n, "http://example.com", "http://example.com", true); + + // Check the enable flag + whitelist_test(++n, false, "www.example.com", "http://www.secondlife.com", true); + whitelist_test(++n, true, "www.example.com", "http://www.secondlife.com", false); + + // Check permutations of trailing slash: + whitelist_test(++n, "http://www.example.com", "http://www.example.com/", true); + whitelist_test(++n, "http://www.example.com/", "http://www.example.com/", true); + whitelist_test(++n, "http://www.example.com/", "http://www.example.com", false); + whitelist_test(++n, "http://www.example.com", "http://www.example.com/foobar", true); + whitelist_test(++n, "http://www.example.com/", "http://www.example.com/foobar", false); + + + // More cases... + whitelist_test(++n, "http://example.com", "http://example.com/wiki", true); + whitelist_test(++n, "www.example.com", "http://www.example.com/help", true); + whitelist_test(++n, "http://www.example.com", "http://wwwexample.com", false); + whitelist_test(++n, "http://www.example.com", "http://www.example.com/wiki", true); + whitelist_test(++n, "example.com", "http://wwwexample.com", false); + whitelist_test(++n, "http://www.example.com/", "http://www.amazon.com/wiki", false); + whitelist_test(++n, "www.example.com", "http://www.amazon.com", false); + + // regexp cases + whitelist_test(++n, "*.example.com", "http://www.example.com", true); + whitelist_test(++n, "*.example.com", "http://www.amazon.com", false); + whitelist_test(++n, "*.example.com", "http://www.example.com/foo/bar", true); + whitelist_test(++n, "*.example.com", "http:/example.com/foo/bar", false); + whitelist_test(++n, "*example.com", "http://example.com/foo/bar", true); + whitelist_test(++n, "*example.com", "http://my.virus.com/foo/bar?example.com", false); + whitelist_test(++n, "example.com", "http://my.virus.com/foo/bar?example.com", false); + whitelist_test(++n, "*example.com", "http://my.virus.com/foo/bar?*example.com", false); + whitelist_test(++n, "http://*example.com", "http://www.example.com", true); + whitelist_test(++n, "http://*.example.com", "http://www.example.com", true); + whitelist_test(++n, "http://*.e$?^.com", "http://www.e$?^.com", true); + whitelist_test(++n, "*.example.com/foo/bar", "http://www.example.com/", false); + whitelist_test(++n, "*.example.com/foo/bar", "http://example.com/foo/bar", false); + whitelist_test(++n, "http://*.example.com/foo/bar", "http://www.example.com", false); + whitelist_test(++n, "http://*.example.com", "https://www.example.com", false); + whitelist_test(++n, "http*://*.example.com", "rtsp://www.example.com", false); + whitelist_test(++n, "http*://*.example.com", "https://www.example.com", true); + whitelist_test(++n, "example.com", "http://www.example.com", false); + whitelist_test(++n, "www.example.com", "http://www.example.com:80", false); + whitelist_test(++n, "www.example.com", "http://www.example.com", true); + whitelist_test(++n, "www.example.com/", "http://www.example.com", false); + whitelist_test(++n, "www.example.com/foo/bar/*", "http://www.example.com/foo/bar/baz", true); // Path only - whitelist_test(++n, "/foo/*/baz", "http://www.example.com/foo/bar/baz", true); - whitelist_test(++n, "/foo/*/baz", "http://www.example.com/foo/bar/", false); - } - + whitelist_test(++n, "/foo/*/baz", "http://www.example.com/foo/bar/baz", true); + whitelist_test(++n, "/foo/*/baz", "http://www.example.com/foo/bar/", false); + } + } diff --git a/indra/llprimitive/tests/llmessagesystem_stub.cpp b/indra/llprimitive/tests/llmessagesystem_stub.cpp index 9006833054..531a8b069d 100644 --- a/indra/llprimitive/tests/llmessagesystem_stub.cpp +++ b/indra/llprimitive/tests/llmessagesystem_stub.cpp @@ -1,26 +1,26 @@ -/** +/** * @file llmessagesystem_stub.cpp * - * $LicenseInfo:firstyear=2008&license=viewerlgpl$ + * $LicenseInfo:firstyear=2008&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$ + * $/LicenseInfo$ */ #include "linden_common.h" @@ -29,12 +29,12 @@ const char * const _PREHASH_TextureEntry = "TextureEntry"; S32 LLMessageSystem::getSizeFast(char const*, char const*) const { - return 0; + return 0; } S32 LLMessageSystem::getSizeFast(char const*, int, char const*) const { - return 0; + return 0; } void LLMessageSystem::getBinaryDataFast(char const*, char const*, void*, int, int, int) diff --git a/indra/llprimitive/tests/llprimitive_test.cpp b/indra/llprimitive/tests/llprimitive_test.cpp index 0ff0795fdc..1b47182c28 100644 --- a/indra/llprimitive/tests/llprimitive_test.cpp +++ b/indra/llprimitive/tests/llprimitive_test.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llprimitive_test.cpp * @brief llprimitive tests * * $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$ */ @@ -35,40 +35,40 @@ class DummyVolumeMgr : public LLVolumeMgr { public: - DummyVolumeMgr() : LLVolumeMgr(), mVolumeTest(NULL), mCurrDetailTest(0) {} - ~DummyVolumeMgr() - { - } - - - virtual LLVolume *refVolume(const LLVolumeParams &volume_params, const S32 detail) - { - if (mVolumeTest.isNull() || volume_params != mCurrParamsTest || detail != mCurrDetailTest) - { - F32 volume_detail = LLVolumeLODGroup::getVolumeScaleFromDetail(detail); - mVolumeTest = new LLVolume(volume_params, volume_detail, FALSE, FALSE); - mCurrParamsTest = volume_params; - mCurrDetailTest = detail; - return mVolumeTest; - } - else - { - return mVolumeTest; - } - } - - virtual void unrefVolume(LLVolume *volumep) - { - if (mVolumeTest == volumep) - { - mVolumeTest = NULL; - } - } - + DummyVolumeMgr() : LLVolumeMgr(), mVolumeTest(NULL), mCurrDetailTest(0) {} + ~DummyVolumeMgr() + { + } + + + virtual LLVolume *refVolume(const LLVolumeParams &volume_params, const S32 detail) + { + if (mVolumeTest.isNull() || volume_params != mCurrParamsTest || detail != mCurrDetailTest) + { + F32 volume_detail = LLVolumeLODGroup::getVolumeScaleFromDetail(detail); + mVolumeTest = new LLVolume(volume_params, volume_detail, FALSE, FALSE); + mCurrParamsTest = volume_params; + mCurrDetailTest = detail; + return mVolumeTest; + } + else + { + return mVolumeTest; + } + } + + virtual void unrefVolume(LLVolume *volumep) + { + if (mVolumeTest == volumep) + { + mVolumeTest = NULL; + } + } + private: - LLPointer<LLVolume> mVolumeTest; - LLVolumeParams mCurrParamsTest; - S32 mCurrDetailTest; + LLPointer<LLVolume> mVolumeTest; + LLVolumeParams mCurrParamsTest; + S32 mCurrDetailTest; }; LLMaterialID::LLMaterialID() {} @@ -114,158 +114,158 @@ S32 LLPrimTextureList::size() const { return mEntryList.size(); } class PRIMITIVE_TEST_SETUP { public: - PRIMITIVE_TEST_SETUP() - { - volume_manager_test = new DummyVolumeMgr(); - LLPrimitive::setVolumeManager(volume_manager_test); - } - - ~PRIMITIVE_TEST_SETUP() - { - LLPrimitive::cleanupVolumeManager(); - } - DummyVolumeMgr * volume_manager_test; -}; + PRIMITIVE_TEST_SETUP() + { + volume_manager_test = new DummyVolumeMgr(); + LLPrimitive::setVolumeManager(volume_manager_test); + } + + ~PRIMITIVE_TEST_SETUP() + { + LLPrimitive::cleanupVolumeManager(); + } + DummyVolumeMgr * volume_manager_test; +}; namespace tut { - struct llprimitive - { - PRIMITIVE_TEST_SETUP setup_class; - }; - - typedef test_group<llprimitive> llprimitive_t; - typedef llprimitive_t::object llprimitive_object_t; - tut::llprimitive_t tut_llprimitive("LLPrimitive"); - - template<> template<> - void llprimitive_object_t::test<1>() - { - set_test_name("Test LLPrimitive Instantiation"); - LLPrimitive test; - } - - template<> template<> - void llprimitive_object_t::test<2>() - { - set_test_name("Test LLPrimitive PCode setter and getter."); - LLPrimitive test; - ensure_equals(test.getPCode(), 0); - LLPCode code = 1; - test.setPCode(code); - ensure_equals(test.getPCode(), code); - } - - template<> template<> - void llprimitive_object_t::test<3>() - { - set_test_name("Test llprimitive constructor and initer."); - LLPCode code = 1; - LLPrimitive primitive; - primitive.init_primitive(code); - ensure_equals(primitive.getPCode(), code); - } - - template<> template<> - void llprimitive_object_t::test<4>() - { - set_test_name("Test Static llprimitive constructor and initer."); - LLPCode code = 1; - LLPrimitive * primitive = LLPrimitive::createPrimitive(code); - ensure(primitive != NULL); - ensure_equals(primitive->getPCode(), code); - } - - template<> template<> - void llprimitive_object_t::test<5>() - { - set_test_name("Test setVolume creation of new unique volume."); - LLPrimitive primitive; - LLVolumeParams params; - - // Make sure volume starts off null - ensure(primitive.getVolume() == NULL); - - // Make sure we have no texture entries before setting the volume - ensure_equals(primitive.getNumTEs(), 0); - - // Test that GEOMETRY has not been flagged as changed. - ensure(!primitive.isChanged(LLXform::GEOMETRY)); - - // Make sure setVolume returns true - ensure(primitive.setVolume(params, 0, true) == TRUE); - LLVolume* new_volume = primitive.getVolume(); - - // make sure new volume was actually created - ensure(new_volume != NULL); - - // Make sure that now that we've set the volume we have texture entries - ensure_not_equals(primitive.getNumTEs(), 0); - - // Make sure that the number of texture entries equals the number of faces in the volume (should be 6) - ensure_equals(new_volume->getNumFaces(), 6); - ensure_equals(primitive.getNumTEs(), new_volume->getNumFaces()); - - // Test that GEOMETRY has been flagged as changed. - ensure(primitive.isChanged(LLXform::GEOMETRY)); - - // Run it twice to make sure it doesn't create a different one if params are the same - ensure(primitive.setVolume(params, 0, true) == FALSE); - ensure(new_volume == primitive.getVolume()); - - // Change the param definition and try setting it again. - params.setRevolutions(4); - ensure(primitive.setVolume(params, 0, true) == TRUE); - - // Ensure that we now have a different volume - ensure(new_volume != primitive.getVolume()); - } - - template<> template<> - void llprimitive_object_t::test<6>() - { - set_test_name("Test setVolume creation of new NOT-unique volume."); - LLPrimitive primitive; - LLVolumeParams params; - - // Make sure volume starts off null - ensure(primitive.getVolume() == NULL); - - // Make sure we have no texture entries before setting the volume - ensure_equals(primitive.getNumTEs(), 0); - - // Test that GEOMETRY has not been flagged as changed. - ensure(!primitive.isChanged(LLXform::GEOMETRY)); - - // Make sure setVolume returns true - ensure(primitive.setVolume(params, 0, false) == TRUE); - - LLVolume* new_volume = primitive.getVolume(); - - // make sure new volume was actually created - ensure(new_volume != NULL); - - // Make sure that now that we've set the volume we have texture entries - ensure_not_equals(primitive.getNumTEs(), 0); - - // Make sure that the number of texture entries equals the number of faces in the volume (should be 6) - ensure_equals(new_volume->getNumFaces(), 6); - ensure_equals(primitive.getNumTEs(), new_volume->getNumFaces()); - - // Test that GEOMETRY has been flagged as changed. - ensure(primitive.isChanged(LLXform::GEOMETRY)); - - // Run it twice to make sure it doesn't create a different one if params are the same - ensure(primitive.setVolume(params, 0, false) == FALSE); - ensure(new_volume == primitive.getVolume()); - - // Change the param definition and try setting it again. - params.setRevolutions(4); - ensure(primitive.setVolume(params, 0, false) == TRUE); - - // Ensure that we now have a different volume - ensure(new_volume != primitive.getVolume()); - } + struct llprimitive + { + PRIMITIVE_TEST_SETUP setup_class; + }; + + typedef test_group<llprimitive> llprimitive_t; + typedef llprimitive_t::object llprimitive_object_t; + tut::llprimitive_t tut_llprimitive("LLPrimitive"); + + template<> template<> + void llprimitive_object_t::test<1>() + { + set_test_name("Test LLPrimitive Instantiation"); + LLPrimitive test; + } + + template<> template<> + void llprimitive_object_t::test<2>() + { + set_test_name("Test LLPrimitive PCode setter and getter."); + LLPrimitive test; + ensure_equals(test.getPCode(), 0); + LLPCode code = 1; + test.setPCode(code); + ensure_equals(test.getPCode(), code); + } + + template<> template<> + void llprimitive_object_t::test<3>() + { + set_test_name("Test llprimitive constructor and initer."); + LLPCode code = 1; + LLPrimitive primitive; + primitive.init_primitive(code); + ensure_equals(primitive.getPCode(), code); + } + + template<> template<> + void llprimitive_object_t::test<4>() + { + set_test_name("Test Static llprimitive constructor and initer."); + LLPCode code = 1; + LLPrimitive * primitive = LLPrimitive::createPrimitive(code); + ensure(primitive != NULL); + ensure_equals(primitive->getPCode(), code); + } + + template<> template<> + void llprimitive_object_t::test<5>() + { + set_test_name("Test setVolume creation of new unique volume."); + LLPrimitive primitive; + LLVolumeParams params; + + // Make sure volume starts off null + ensure(primitive.getVolume() == NULL); + + // Make sure we have no texture entries before setting the volume + ensure_equals(primitive.getNumTEs(), 0); + + // Test that GEOMETRY has not been flagged as changed. + ensure(!primitive.isChanged(LLXform::GEOMETRY)); + + // Make sure setVolume returns true + ensure(primitive.setVolume(params, 0, true) == TRUE); + LLVolume* new_volume = primitive.getVolume(); + + // make sure new volume was actually created + ensure(new_volume != NULL); + + // Make sure that now that we've set the volume we have texture entries + ensure_not_equals(primitive.getNumTEs(), 0); + + // Make sure that the number of texture entries equals the number of faces in the volume (should be 6) + ensure_equals(new_volume->getNumFaces(), 6); + ensure_equals(primitive.getNumTEs(), new_volume->getNumFaces()); + + // Test that GEOMETRY has been flagged as changed. + ensure(primitive.isChanged(LLXform::GEOMETRY)); + + // Run it twice to make sure it doesn't create a different one if params are the same + ensure(primitive.setVolume(params, 0, true) == FALSE); + ensure(new_volume == primitive.getVolume()); + + // Change the param definition and try setting it again. + params.setRevolutions(4); + ensure(primitive.setVolume(params, 0, true) == TRUE); + + // Ensure that we now have a different volume + ensure(new_volume != primitive.getVolume()); + } + + template<> template<> + void llprimitive_object_t::test<6>() + { + set_test_name("Test setVolume creation of new NOT-unique volume."); + LLPrimitive primitive; + LLVolumeParams params; + + // Make sure volume starts off null + ensure(primitive.getVolume() == NULL); + + // Make sure we have no texture entries before setting the volume + ensure_equals(primitive.getNumTEs(), 0); + + // Test that GEOMETRY has not been flagged as changed. + ensure(!primitive.isChanged(LLXform::GEOMETRY)); + + // Make sure setVolume returns true + ensure(primitive.setVolume(params, 0, false) == TRUE); + + LLVolume* new_volume = primitive.getVolume(); + + // make sure new volume was actually created + ensure(new_volume != NULL); + + // Make sure that now that we've set the volume we have texture entries + ensure_not_equals(primitive.getNumTEs(), 0); + + // Make sure that the number of texture entries equals the number of faces in the volume (should be 6) + ensure_equals(new_volume->getNumFaces(), 6); + ensure_equals(primitive.getNumTEs(), new_volume->getNumFaces()); + + // Test that GEOMETRY has been flagged as changed. + ensure(primitive.isChanged(LLXform::GEOMETRY)); + + // Run it twice to make sure it doesn't create a different one if params are the same + ensure(primitive.setVolume(params, 0, false) == FALSE); + ensure(new_volume == primitive.getVolume()); + + // Change the param definition and try setting it again. + params.setRevolutions(4); + ensure(primitive.setVolume(params, 0, false) == TRUE); + + // Ensure that we now have a different volume + ensure(new_volume != primitive.getVolume()); + } } #include "llmessagesystem_stub.cpp" |