diff options
Diffstat (limited to 'indra/llprimitive/llmodel.cpp')
-rw-r--r-- | indra/llprimitive/llmodel.cpp | 252 |
1 files changed, 203 insertions, 49 deletions
diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index ae17996956..7fa72d82e1 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -2,30 +2,25 @@ * @file llmodel.cpp * @brief Model handling implementation * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * 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. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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 * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -41,7 +36,6 @@ #include "dom/domMesh.h" #include "zlib/zlib.h" -#if LL_MESH_ENABLED std::string model_names[] = { @@ -956,13 +950,14 @@ void LLModel::setNumVolumeFaces(S32 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) +void LLModel::setVolumeFaceData( + S32 f, + LLStrider<LLVector3> pos, + LLStrider<LLVector3> norm, + LLStrider<LLVector2> tc, + LLStrider<U16> ind, + U32 num_verts, + U32 num_indices) { LLVolumeFace& face = mVolumeFaces[f]; @@ -1289,11 +1284,63 @@ LLModel* LLModel::loadModelFromDomMesh(domMesh *mesh) } //static -LLSD LLModel::writeModel(std::string filename, LLModel* physics, LLModel* high, LLModel* medium, LLModel* low, LLModel* impostor, LLModel::physics_shape& decomp, BOOL nowrite) +LLSD LLModel::writeModel( + std::string filename, + LLModel* physics, + LLModel* high, + LLModel* medium, + LLModel* low, + LLModel* impostor, + const convex_hull_decomposition& decomp, + BOOL upload_skin, + BOOL upload_joints, + BOOL nowrite) +{ + LLModel::hull dummy_hull; + return writeModel( + filename, + physics, + high, + medium, + low, + impostor, + decomp, + dummy_hull, + upload_skin, + upload_joints, + nowrite); +} + +//static +LLSD LLModel::writeModel( + std::string filename, + LLModel* physics, + LLModel* high, + LLModel* medium, + LLModel* low, + LLModel* impostor, + const convex_hull_decomposition& decomp, + const hull& base_hull, + BOOL upload_skin, + BOOL upload_joints, + BOOL nowrite) { - std::ofstream os(filename.c_str(), std::ofstream::out | std::ofstream::binary); + std::ofstream os( + filename.c_str(), + std::ofstream::out | std::ofstream::binary); - LLSD header = writeModel(os, physics, high, medium, low, impostor, decomp, nowrite); + LLSD header = writeModel( + os, + physics, + high, + medium, + low, + impostor, + decomp, + base_hull, + upload_skin, + upload_joints, + nowrite); os.close(); @@ -1301,7 +1348,18 @@ LLSD LLModel::writeModel(std::string filename, LLModel* physics, LLModel* high, } //static -LLSD LLModel::writeModel(std::ostream& ostr, LLModel* physics, LLModel* high, LLModel* medium, LLModel* low, LLModel* impostor, LLModel::physics_shape& decomp, BOOL nowrite) +LLSD LLModel::writeModel( + std::ostream& ostr, + LLModel* physics, + LLModel* high, + LLModel* medium, + LLModel* low, + LLModel* impostor, + const convex_hull_decomposition& decomp, + const hull& base_hull, + BOOL upload_skin, + BOOL upload_joints, + BOOL nowrite) { LLSD mdl; @@ -1314,7 +1372,7 @@ LLSD LLModel::writeModel(std::ostream& ostr, LLModel* physics, LLModel* high, LL physics }; - bool skinning = high && !high->mSkinWeights.empty(); + bool skinning = upload_skin && high && !high->mSkinWeights.empty(); if (skinning) { //write skinning block @@ -1343,17 +1401,44 @@ LLSD LLModel::writeModel(std::ostream& ostr, LLModel* physics, LLModel* high, LL mdl["skin"]["bind_shape_matrix"][i*4+j] = high->mBindShapeMatrix.mMatrix[i][j]; } } + + if ( upload_joints && high->mAlternateBindMatrix.size() > 0 ) + { + for (U32 i = 0; i < high->mJointList.size(); ++i) + { + for (U32 j = 0; j < 4; j++) + { + for (U32 k = 0; k < 4; k++) + { + mdl["skin"]["alt_inverse_bind_matrix"][i][j*4+k] = high->mAlternateBindMatrix[i].mMatrix[j][k]; + } + } + } + } + } - if (!decomp.empty()) + if (!decomp.empty() || !base_hull.empty()) { //write decomposition block // ["decomposition"]["HullList"] -- list of 8 bit integers, each entry represents a hull with specified number of points // ["decomposition"]["PositionDomain"]["Min"/"Max"] // ["decomposition"]["Position"] -- list of 16-bit integers to be decoded to given domain, encoded 3D points - + // ["decomposition"]["Hull"] -- 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 = decomp[0][0]; + LLVector3 min; + + if (decomp.empty()) + { + min = base_hull[0]; + } + else + { + min = decomp[0][0]; + } + LLVector3 max = min; LLSD::Binary hulls(decomp.size()); @@ -1364,31 +1449,75 @@ LLSD LLModel::writeModel(std::ostream& ostr, LLModel* physics, LLModel* high, LL { U32 size = decomp[i].size(); total += size; - hulls[i] = (U8) size; + // The valid range of sizes is actually 3-256 verts. We need this to fit into a U8, + // So we just subtract 1 + hulls[i] = (U8) (size - 1); for (U32 j = 0; j < decomp[i].size(); ++j) { update_min_max(min, max, decomp[i][j]); } + + } + + for (U32 i = 0; i < base_hull.size(); ++i) + { + update_min_max(min, max, base_hull[i]); } mdl["decomposition"]["Min"] = min.getValue(); mdl["decomposition"]["Max"] = max.getValue(); - mdl["decomposition"]["HullList"] = hulls; - - LLSD::Binary p(total*3*2); - LLVector3 range = max-min; + if (!hulls.empty()) + { + mdl["decomposition"]["HullList"] = hulls; + } - U32 vert_idx = 0; - for (U32 i = 0; i < decomp.size(); ++i) + if (total > 0) { - for (U32 j = 0; j < decomp[i].size(); ++j) + LLSD::Binary p(total*3*2); + + LLVector3 range = max-min; + + U32 vert_idx = 0; + for (U32 i = 0; i < decomp.size(); ++i) + { + for (U32 j = 0; j < decomp[i].size(); ++j) + { + for (U32 k = 0; k < 3; k++) + { + //convert to 16-bit normalized across domain + U16 val = (U16) (((decomp[i][j].mV[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()) + { + llerrs << "WTF?" << llendl; + } + } + } + } + + mdl["decomposition"]["Position"] = p; + } + + if (!base_hull.empty()) + { + LLSD::Binary p(base_hull.size()*3*2); + + LLVector3 range = max-min; + + U32 vert_idx = 0; + for (U32 j = 0; j < base_hull.size(); ++j) { for (U32 k = 0; k < 3; k++) { //convert to 16-bit normalized across domain - U16 val = (U16) (((decomp[i][j].mV[k]-min.mV[k])/range.mV[k])*65535); + U16 val = (U16) (((base_hull[j].mV[k]-min.mV[k])/range.mV[k])*65535); U8* buff = (U8*) &val; //write to binary buffer @@ -1401,9 +1530,9 @@ LLSD LLModel::writeModel(std::ostream& ostr, LLModel* physics, LLModel* high, LL } } } + + mdl["decomposition"]["Hull"] = p; } - - mdl["decomposition"]["Position"] = p; } for (U32 idx = 0; idx < MODEL_NAMES_LENGTH; ++idx) @@ -1646,7 +1775,7 @@ LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite) if (!nowrite) { - LLSDSerialize::serialize(header, ostr, LLSDSerialize::LLSD_BINARY); + LLSDSerialize::toBinary(header, ostr); if (!skin.empty()) { //write skin block @@ -1710,5 +1839,30 @@ LLModel::weight_list& LLModel::getJointInfluences(const LLVector3& pos) } } -#endif +void LLModel::setConvexHullDecomposition( + const LLModel::convex_hull_decomposition& decomp) +{ + mConvexHullDecomp = decomp; + + mHullCenter.resize(mConvexHullDecomp.size()); + mHullPoints = 0; + mCenterOfHullCenters.clear(); + + for (U32 i = 0; i < decomp.size(); ++i) + { + LLVector3 cur_center; + + for (U32 j = 0; j < decomp[i].size(); ++j) + { + cur_center += decomp[i][j]; + } + mCenterOfHullCenters += cur_center; + cur_center *= 1.f/decomp[i].size(); + mHullCenter[i] = cur_center; + mHullPoints += decomp[i].size(); + } + + mCenterOfHullCenters *= 1.f / mHullPoints; +} + |