diff options
Diffstat (limited to 'indra')
-rw-r--r-- | indra/appearance_utility/CMakeLists.txt | 21 | ||||
-rw-r--r-- | indra/appearance_utility/appearance_utility.cpp | 403 | ||||
-rw-r--r-- | indra/appearance_utility/llappappearanceutility.cpp | 418 | ||||
-rw-r--r-- | indra/appearance_utility/llappappearanceutility.h | 97 | ||||
-rw-r--r-- | indra/appearance_utility/llbakingavatar.cpp | 61 | ||||
-rw-r--r-- | indra/appearance_utility/llbakingavatar.h | 76 | ||||
-rw-r--r-- | indra/appearance_utility/llbakingjoint.cpp | 54 | ||||
-rw-r--r-- | indra/appearance_utility/llbakingjoint.h | 44 | ||||
-rw-r--r-- | indra/appearance_utility/llbakingjointmesh.cpp | 43 | ||||
-rw-r--r-- | indra/appearance_utility/llbakingjointmesh.h | 43 | ||||
-rw-r--r-- | indra/appearance_utility/llbakingprocess.h | 55 | ||||
-rw-r--r-- | indra/appearance_utility/llbakingshadermgr.h | 4 | ||||
-rw-r--r-- | indra/appearance_utility/llprocessparams.cpp | 51 | ||||
-rw-r--r-- | indra/appearance_utility/llprocessparams.h | 42 | ||||
-rwxr-xr-x | indra/llappearance/llavatarjointmesh.h | 2 | ||||
-rwxr-xr-x | indra/newview/llviewerjointmesh.h | 2 |
16 files changed, 1025 insertions, 391 deletions
diff --git a/indra/appearance_utility/CMakeLists.txt b/indra/appearance_utility/CMakeLists.txt index 3c6d30b124..dfd552ddc6 100644 --- a/indra/appearance_utility/CMakeLists.txt +++ b/indra/appearance_utility/CMakeLists.txt @@ -38,9 +38,26 @@ include_directories( ${LLAPPEARANCE_INCLUDE_DIRS} ) -set(appearance_utility_SOURCE_FILES appearance_utility.cpp llbakingshadermgr.cpp) +set(appearance_utility_SOURCE_FILES + appearance_utility.cpp + llappappearanceutility.cpp + llbakingavatar.cpp + llbakingjoint.cpp + llbakingjointmesh.cpp + llbakingshadermgr.cpp + llprocessparams.cpp + ) -set(appearance_utility_HEADER_FILES CMakeLists.txt llbakingshadermgr.h) +set(appearance_utility_HEADER_FILES + CMakeLists.txt + llappappearanceutility.h + llbakingavatar.h + llbakingjoint.h + llbakingjointmesh.h + llbakingprocess.h + llbakingshadermgr.h + llprocessparams.h + ) set_source_files_properties(${appearance_utility_HEADER_FILES} PROPERTIES HEADER_FILES_ONLY TRUE) diff --git a/indra/appearance_utility/appearance_utility.cpp b/indra/appearance_utility/appearance_utility.cpp index 26f1778ac7..098c3550de 100644 --- a/indra/appearance_utility/appearance_utility.cpp +++ b/indra/appearance_utility/appearance_utility.cpp @@ -25,408 +25,41 @@ * $/LicenseInfo$ */ -#include <iostream> -#include <sstream> -#include <string> - +// linden includes #include "linden_common.h" - -#include "llapp.h" #include "llapr.h" -#include "llerrorcontrol.h" -#include "llsd.h" -#include "llsdserialize.h" -#include "llsdutil.h" - -#include "llwearabledata.h" - -enum EResult -{ - RV_SUCCESS = 0, - RV_UNKNOWN_ERROR, - RV_BAD_ARGUMENTS, - RV_UNABLE_OPEN, - RV_UNABLE_TO_PARSE, -}; - -static const std::string MESSAGE_RV_UNKNOWN("Unknown error."); -static const std::string MESSAGE_RV_ARGUMENTS -("Invalid arguments: "); -static const std::string MESSAGE_RV_UNABLE_OPEN("Unable to open file: "); -static const std::string MESSAGE_RV_UNABLE_TO_PARSE("Unable to parse input LLSD."); - -static const apr_getopt_option_t APPEARANCE_UTILITY_OPTIONS[] = -{ - {"tbd", 't', 0, "Extract dump information from a mesh asset."}, - {"output", 'o', 1, "The output file to write to. Default is stdout"}, - {"agent-id", 'a', 1, "The agent-id of the user."}, - {"grid", 'g', 1, "The grid."}, - {"help", 'h', 0, "Print the help message."}, - {0, 0, 0, 0} -}; - -const std::string NOTHING_EXTRA(""); - -/** - * Helper to return the standard error based on the return value. - */ -LLSD spit_error(EResult rv, const std::string& extra = NOTHING_EXTRA); - -/** - * Helper to generate an error output based on code and message. - */ -LLSD spit_error(const std::string& key, const std::string& message); - - - -LLSD spit_error(EResult value, const std::string& extra) -{ - LLSD rv; - switch(value) - { - case RV_UNKNOWN_ERROR: - rv = spit_error("unknown", MESSAGE_RV_UNKNOWN); - case RV_BAD_ARGUMENTS: - rv = spit_error("arguments", MESSAGE_RV_ARGUMENTS + extra); - break; - case RV_UNABLE_OPEN: - rv = spit_error("file", MESSAGE_RV_UNABLE_OPEN + extra); - break; - case RV_UNABLE_TO_PARSE: - rv = spit_error("input", MESSAGE_RV_UNABLE_TO_PARSE); - break; - default: - rv = spit_error("arguments", "Invalid arguments to spit_error"); - break; - } - return rv; -} - -LLSD spit_error(const std::string& key, const std::string& message) -{ - LLSD rv; - rv["success"] = false; - rv["error"]["key"] = key; - rv["error"]["message"] = message; - return rv; -} - -std::string usage(const char* command) -{ - std::ostringstream ostr; - ostr << "Utilities for processing agent appearance data." - << std::endl << std::endl - << "Usage:" << std::endl - << "\t" << command << " [options] filename" << std::endl << std::endl - << "Will read from stdin if filename is set to '-'." << std::endl << std::endl - << "Options:" << std::endl; - const apr_getopt_option_t* option = &APPEARANCE_UTILITY_OPTIONS[0]; - while(option->name) - { - ostr << "\t--" << option->name << "\t\t" - << option->description << std::endl; - ++option; - } - ostr << std::endl << "Return Values:" << std::endl - << "\t0\t\tSuccess." << std::endl - << "\t1\t\tUnknown error." << std::endl - << "\t2\t\tBad arguments." << std::endl - << "\t3\t\tUnable to open file. Possibly wrong filename" - << " or bad permissions." << std::endl - << "\t4\t\tUnable to parse input LLSD." << std::endl - << std::endl - << "Output:" << std::endl - << "If a non-zero status code is returned, additional error information" - << " will be returned on stderr." << std::endl - << "* This will be in the form of an LLSD document." << std::endl - << "* Check ['error']['message'] to get a human readable message." << std::endl - << "If a zero status code is returned, processed output will be written" - << " to the file specified by --out (or stdout, if not specified)." << std::endl - << std::endl - << std::endl; - return ostr.str(); -} +// project includes +#include "llappappearanceutility.h" -EResult process_tbd(LLSD& input, std::ostream& output, LLSD& error_llsd) +int main(int argc, char** argv) { - EResult rv = RV_SUCCESS; - - LLWearableData wearable_data; - - LLSD result; - result["success"] = true; - result["input"] = input; - output << LLSDOStreamer<LLSDXMLFormatter>(result); - - return rv; -} + // Create an application instance. + ll_init_apr(); + LLAppAppearanceUtility* app = new LLAppAppearanceUtility(argc, argv); -/** - * @brief Called by main() to ensure proper cleanup. Basically main(). - */ -EResult process_command(int argc, char** argv, LLSD& error_llsd) -{ + // Assume success, unless exception is thrown. EResult rv = RV_SUCCESS; - - ////// BEGIN OPTION PARSING ////// - // Check for '-' as last option, since apr doesn't seem to like that. - bool read_stdin = false; - bool write_stdout = true; - if (std::string(argv[argc-1]) == "-") + try { - read_stdin = true; - argc--; - } - - apr_status_t apr_err; - const char* opt_arg = NULL; - int opt_id = 0; - apr_getopt_t* os = NULL; - if(APR_SUCCESS != apr_getopt_init(&os, gAPRPoolp, argc, argv)) - { - std::cerr << "Unable to initialize apr" << std::endl; - rv = RV_UNKNOWN_ERROR; - error_llsd = spit_error(rv); - return rv; - } - - bool tbd = false; - LLUUID agent_id; - std::string output_filename; - std::string grid; - while(true) - { - apr_err = apr_getopt_long(os, APPEARANCE_UTILITY_OPTIONS, &opt_id, &opt_arg); - if(APR_STATUS_IS_EOF(apr_err)) break; - if(apr_err) - { - char buf[MAX_STRING]; /* Flawfinder: ignore */ - std::cerr << "Error parsing options: " - << apr_strerror(apr_err, buf, MAX_STRING) << std::endl; - std::cerr << usage(os->argv[0]) << std::endl; - rv = RV_BAD_ARGUMENTS; - error_llsd = spit_error(rv, buf); - return rv; - } - switch (opt_id) + // Process command line and initialize system. + if (app->init()) { - case 't': - tbd = true; - break; - case 'o': - output_filename.assign(opt_arg); - write_stdout=false; - break; - case 'a': - agent_id.set(opt_arg); - if (agent_id.isNull()) - { - const char* INVALID_AGENT_ID="agent-id must be a valid uuid."; - std::cerr << "Incorrect arguments. " << INVALID_AGENT_ID - << std::endl << usage(argv[0]) << std::endl; - rv = RV_BAD_ARGUMENTS; - error_llsd = spit_error(rv, INVALID_AGENT_ID); - return rv; - } - break; - case 'g': - grid = opt_arg; - break; - case 'h': - std::cout << usage(os->argv[0]); - return RV_SUCCESS; - default: - std::cerr << usage(os->argv[0]); - rv = RV_BAD_ARGUMENTS; - error_llsd = spit_error(rv, "Unknown option."); - return rv; + // Run process. + app->mainLoop(); } } - ////// END OPTION PARSING ////// - - ///// BEGIN ARGUMENT VALIDATION ///// - std::string input_filename; - - // Make sure we don't have more than one command specified. - if (!tbd) + catch (LLAppException& e) { - const char* INVALID_MODE="Must specify mode. (tbd)"; - std::cerr << "Incorrect arguments. " << INVALID_MODE - << std::endl; - std::cerr << usage(os->argv[0]); - rv = RV_BAD_ARGUMENTS; - error_llsd = spit_error(rv, INVALID_MODE); - return rv; + // Deal with errors. + rv = e.getStatusCode(); } - // *TODO: Add debug mode(s). Skip this in debug mode. - LLError::setDefaultLevel(LLError::LEVEL_WARN); - - if (!read_stdin) - { - bool valid_input_filename = false; - // Try to grab the input filename. - if (os->argv && os->argv[os->ind]) - { - input_filename.assign(os->argv[os->ind]); - if (! input_filename.empty() ) - { - valid_input_filename = true; - } - } - if (!valid_input_filename) - { - const char* INVALID_FILENAME="Must specify input file."; - std::cerr << "Incorrect arguments. " << INVALID_FILENAME - << std::endl << usage(os->argv[0]) << std::endl; - rv = RV_BAD_ARGUMENTS; - error_llsd = spit_error(rv, INVALID_FILENAME); - return rv; - } - } - - ///// END ARGUMENT VALIDATION ///// - - ///// BEGIN OPEN INPUT FILE //// - std::ifstream input_file; - std::stringstream data; - std::istream* input = NULL; - - if (read_stdin) - { - // Read unformated data from stdin in to memory. - const S32 BUFFER_SIZE = BUFSIZ; - char buffer[BUFFER_SIZE]; - while (true) - { - std::cin.read(buffer, BUFFER_SIZE); - // Check if anything out of the ordinary happened. - if (!std::cin) - { - // See if something 'really bad' happened, or if we just - // used up all of our buffer. - if (std::cin.bad()) - { - std::cerr << "Problem reading standard input." << std::endl; - rv = RV_UNKNOWN_ERROR; - error_llsd = spit_error(rv); - return rv; - } - else - { - // Output normally. - data.write(buffer, std::cin.gcount()); - if (std::cin.eof()) break; - - // Clear this problem. We have handled it. - std::cin.clear(); - } - } - else - { - data.write(buffer, std::cin.gcount()); - if (std::cin.eof()) break; - } - } - input = &data; - } - else - { - // Make sure we can open the input file. - input_file.open( input_filename.c_str(), std::fstream::in ); - if ( input_file.fail()) - { - std::cerr << "Couldn't open input file '" << input_filename << "'." << std::endl; - rv = RV_UNABLE_OPEN; - error_llsd = spit_error(rv, input_filename); - return rv; - } - input = &input_file; - } - ///// END OPEN INPUT FILE //// - - ///// BEGIN OPEN OUTPUT FILE //// - std::fstream output_file; - std::ostream* output = NULL; - - // Make sure we can open the output file. - if (write_stdout) - { - output = &std::cout; - } - else - { - output_file.open( output_filename.c_str(), std::fstream::out ); - if ( output_file.fail() ) - { - std::cerr << "Couldn't open output file '" << output_filename << "'." << std::endl; - rv = RV_UNABLE_OPEN; - error_llsd = spit_error(rv, output_filename); - if (!read_stdin) input_file.close(); - return rv; - } - output = &output_file; - } - ///// END OPEN OUTPUT FILE //// - - ///// BEGIN INPUT PARSING //// - LLSD input_llsd; - LLSDSerialize::fromXML( input_llsd, *input ); - if (input_llsd.isUndefined()) - { - rv = RV_UNABLE_TO_PARSE; - error_llsd = spit_error(rv); - return rv; - } - - ///// END INPUT PARSING //// - - if (tbd) - { - rv = process_tbd(input_llsd, *output, error_llsd); - } - - if (!write_stdout) output_file.close(); - if (!read_stdin) input_file.close(); - - return rv; -} - -class LLAppAppearanceUtility : public LLApp -{ -public: - LLAppAppearanceUtility() {} - virtual ~LLAppAppearanceUtility() {} - /*virtual*/ bool init(); - /*virtual*/ bool cleanup(); - /*virtual*/ bool mainLoop() { return true;} -}; - -bool LLAppAppearanceUtility::init() -{ - return true; -} - -bool LLAppAppearanceUtility::cleanup() -{ - return true; -} - -int main(int argc, char** argv) -{ - ll_init_apr(); - LLAppAppearanceUtility* app = new LLAppAppearanceUtility(); - app->init(); - LLSD error_llsd; - EResult rv = process_command(argc, argv, error_llsd); - if (RV_SUCCESS != rv) - { - std::cerr << LLSDOStreamer<LLSDXMLFormatter>(error_llsd); - } + // Clean up application instance. app->cleanup(); delete app; ll_cleanup_apr(); + return (int) rv; } diff --git a/indra/appearance_utility/llappappearanceutility.cpp b/indra/appearance_utility/llappappearanceutility.cpp new file mode 100644 index 0000000000..b49e954830 --- /dev/null +++ b/indra/appearance_utility/llappappearanceutility.cpp @@ -0,0 +1,418 @@ +/** + * @file llappappearanceutility.cpp + * @brief Implementation of LLAppAppearanceUtility class. + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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$ + */ + +#include <iostream> +#include <sstream> +#include <string> + +// linden includes +#include "linden_common.h" + +#include "llapr.h" +#include "llerrorcontrol.h" +#include "llsd.h" +#include "llsdserialize.h" +#include "llsdutil.h" + +// project includes +#include "llappappearanceutility.h" +#include "llbakingprocess.h" +#include "llprocessparams.h" + +const std::string NOTHING_EXTRA(""); + +//////////////////////////////////////////// +// LLAppException +//////////////////////////////////////////// + +static const std::string MESSAGE_RV_UNKNOWN("Unknown error."); +static const std::string MESSAGE_RV_ARGUMENTS +("Invalid arguments: "); +static const std::string MESSAGE_RV_UNABLE_OPEN("Unable to open file: "); +static const std::string MESSAGE_RV_UNABLE_TO_PARSE("Unable to parse input LLSD."); +static const std::string MESSAGE_DUPLICATE_MODES = "Cannot specify more than one process mode."; + + +LLAppException::LLAppException(EResult status_code, const std::string& extra) : + mStatusCode(status_code) +{ + switch(status_code) + { + case RV_UNKNOWN_ERROR: + printErrorLLSD("unknown", MESSAGE_RV_UNKNOWN); + case RV_BAD_ARGUMENTS: + printErrorLLSD("arguments", MESSAGE_RV_ARGUMENTS + extra); + break; + case RV_UNABLE_OPEN: + printErrorLLSD("file", MESSAGE_RV_UNABLE_OPEN + extra); + break; + case RV_UNABLE_TO_PARSE: + printErrorLLSD("input", MESSAGE_RV_UNABLE_TO_PARSE); + break; + default: + printErrorLLSD("arguments", "Unknown exception."); + break; + } +} + +void LLAppException::printErrorLLSD(const std::string& key, const std::string& message) +{ + LLSD error_llsd; + error_llsd["success"] = false; + error_llsd["error"]["key"] = key; + error_llsd["error"]["message"] = message; + + std::cerr << LLSDOStreamer<LLSDXMLFormatter>(error_llsd); +} + + + +//////////////////////////////////////////// +// LLAppAppearanceUtility +//////////////////////////////////////////// + +///////// Option Parsing ///////// + +// Simple usage command. +class LLProcessUsage : public LLBakingProcess +{ +public: + LLProcessUsage(LLAppAppearanceUtility* app) : + LLBakingProcess(app) {} + /*virtual*/ void process(LLSD& input, std::ostream& output) + { + mApp->usage(output); + } +}; + + +static const apr_getopt_option_t APPEARANCE_UTILITY_OPTIONS[] = +{ + {"params", 'p', 0, "Generate appearance parameters for an agent."}, + {"output", 'o', 1, "The output file to write to. Default is stdout"}, + {"agent-id", 'a', 1, "The agent-id of the user."}, + //{"grid", 'g', 1, "The grid."}, + {"help", 'h', 0, "Print the help message."}, + {0, 0, 0, 0} +}; + +void LLAppAppearanceUtility::usage(std::ostream& ostr) +{ + ostr << "Utilities for processing agent appearance data." + << std::endl << std::endl + << "Usage:" << std::endl + << "\t" << mAppName << " [options] filename" << std::endl << std::endl + << "Will read from stdin if filename is set to '-'." << std::endl << std::endl + << "Options:" << std::endl; + const apr_getopt_option_t* option = &APPEARANCE_UTILITY_OPTIONS[0]; + while(option->name) + { + ostr << "\t--" << option->name << "\t\t" + << option->description << std::endl; + ++option; + } + ostr << std::endl << "Return Values:" << std::endl + << "\t0\t\tSuccess." << std::endl + << "\t1\t\tUnknown error." << std::endl + << "\t2\t\tBad arguments." << std::endl + << "\t3\t\tUnable to open file. Possibly wrong filename" + << " or bad permissions." << std::endl + << "\t4\t\tUnable to parse input LLSD." << std::endl + << std::endl + << "Output:" << std::endl + << "If a non-zero status code is returned, additional error information" + << " will be returned on stderr." << std::endl + << "* This will be in the form of an LLSD document." << std::endl + << "* Check ['error']['message'] to get a human readable message." << std::endl + << "If a zero status code is returned, processed output will be written" + << " to the file specified by --out (or stdout, if not specified)." << std::endl + << std::endl + << std::endl; +} + + +/////// LLApp Interface //////// + +LLAppAppearanceUtility::LLAppAppearanceUtility(int argc, char** argv) : + LLApp(), + mArgc(argc), + mArgv(argv), + mProcess(NULL), + mInput(NULL), + mOutput(NULL), + mAppName(argv[0]) +{ +} + +// virtual +LLAppAppearanceUtility::~LLAppAppearanceUtility() +{ +} + +void LLAppAppearanceUtility::verifyNoProcess() +{ + if (mProcess) + { + std::cerr << "Invalid arguments. " << MESSAGE_DUPLICATE_MODES << std::endl; + usage(std::cerr); + throw LLAppException(RV_BAD_ARGUMENTS, MESSAGE_DUPLICATE_MODES); + } +} + +void LLAppAppearanceUtility::parseArguments() +{ + ////// BEGIN OPTION PARSING ////// + // Check for '-' as last option, since apr doesn't seem to like that. + if (std::string(mArgv[mArgc-1]) == "-") + { + mInputFilename.assign("-"); + mArgc--; + } + + apr_status_t apr_err; + const char* opt_arg = NULL; + int opt_id = 0; + apr_getopt_t* os = NULL; + if(APR_SUCCESS != apr_getopt_init(&os, gAPRPoolp, mArgc, mArgv)) + { + std::cerr << "Unable to initialize apr" << std::endl; + throw LLAppException(RV_UNKNOWN_ERROR); + } + + //std::string grid; + while(true) + { + apr_err = apr_getopt_long(os, APPEARANCE_UTILITY_OPTIONS, &opt_id, &opt_arg); + if(APR_STATUS_IS_EOF(apr_err)) break; + if(apr_err) + { + char buf[MAX_STRING]; /* Flawfinder: ignore */ + std::cerr << "Error parsing options: " + << apr_strerror(apr_err, buf, MAX_STRING) << std::endl; + usage(std::cerr); + throw LLAppException(RV_BAD_ARGUMENTS, buf); + } + switch (opt_id) + { + case 'h': + verifyNoProcess(); + mProcess = new LLProcessUsage(this); + break; + case 'p': + verifyNoProcess(); + mProcess = new LLProcessParams(this); + break; + case 'o': + mOutputFilename.assign(opt_arg); + break; + case 'a': + mAgentID.set(opt_arg); + if (mAgentID.isNull()) + { + const char* INVALID_AGENT_ID="agent-id must be a valid uuid."; + std::cerr << "Invalid arguments. " << INVALID_AGENT_ID << std::endl; + usage(std::cerr); + throw LLAppException(RV_BAD_ARGUMENTS, INVALID_AGENT_ID); + } + break; + //case 'g': + // grid = opt_arg; + // break; + default: + usage(std::cerr); + throw LLAppException(RV_BAD_ARGUMENTS, "Unknown option."); + } + } + + if ("-" != mInputFilename) + { + bool valid_input_filename = false; + // Try to grab the input filename. + if (os->argv && os->argv[os->ind]) + { + mInputFilename.assign(os->argv[os->ind]); + if (! mInputFilename.empty() ) + { + valid_input_filename = true; + } + } + if (!valid_input_filename) + { + const char* INVALID_FILENAME="Must specify input file."; + std::cerr << "Invalid arguments. " << INVALID_FILENAME << std::endl; + usage(std::cerr); + throw LLAppException(RV_BAD_ARGUMENTS, INVALID_FILENAME); + } + } + + ////// END OPTION PARSING ////// +} + +void LLAppAppearanceUtility::validateArguments() +{ + ///// BEGIN ARGUMENT VALIDATION ///// + + // Make sure we have a command specified. + if (!mProcess) + { + const char* INVALID_MODE="No process mode specified."; + std::cerr << "Invalid arguments. " << INVALID_MODE + << std::endl; + usage(std::cerr); + throw LLAppException(RV_BAD_ARGUMENTS, INVALID_MODE); + } + + ///// END ARGUMENT VALIDATION ///// +} + +void LLAppAppearanceUtility::initializeIO() +{ + ///// BEGIN OPEN INPUT FILE //// + + if ( "-" == mInputFilename ) + { + // Read unformated data from stdin in to memory. + std::stringstream* data = new std::stringstream(); + const S32 BUFFER_SIZE = BUFSIZ; + char buffer[BUFFER_SIZE]; + while (true) + { + std::cin.read(buffer, BUFFER_SIZE); + // Check if anything out of the ordinary happened. + if (!std::cin) + { + // See if something 'really bad' happened, or if we just + // used up all of our buffer. + if (std::cin.bad()) + { + std::cerr << "Problem reading standard input." << std::endl; + delete data; + throw (RV_UNKNOWN_ERROR); + } + else + { + // Output normally. + data->write(buffer, std::cin.gcount()); + if (std::cin.eof()) break; + + // Clear this problem. We have handled it. + std::cin.clear(); + } + } + else + { + data->write(buffer, std::cin.gcount()); + if (std::cin.eof()) break; + } + } + mInput = data; + } + else + { + // Make sure we can open the input file. + std::ifstream* input_file = new std::ifstream(); + input_file->open( mInputFilename.c_str(), std::fstream::in ); + if ( input_file->fail()) + { + std::cerr << "Couldn't open input file '" << mInputFilename << "'." << std::endl; + delete input_file; + throw LLAppException(RV_UNABLE_OPEN, mInputFilename); + } + mInput = input_file; + } + ///// END OPEN INPUT FILE //// + + ///// BEGIN OPEN OUTPUT FILE //// + + if ("" == mOutputFilename) + { + mOutput = &std::cout; + } + else + { + // Make sure we can open the output file. + std::fstream* output_file = new std::fstream(); + output_file->open( mOutputFilename.c_str(), std::fstream::out ); + if ( output_file->fail() ) + { + std::cerr << "Couldn't open output file '" << mOutputFilename << "'." << std::endl; + delete output_file; + throw LLAppException(RV_UNABLE_OPEN, mOutputFilename); + } + mOutput = output_file; + } + ///// END OPEN OUTPUT FILE //// + + ///// BEGIN INPUT PARSING //// + LLSDSerialize::fromXML( mInputData, *mInput ); + if (mInputData.isUndefined()) + { + throw LLAppException(RV_UNABLE_TO_PARSE); + } + ///// END INPUT PARSING //// +} + +bool LLAppAppearanceUtility::init() +{ + parseArguments(); + + // *TODO: Add debug mode(s). Skip this in debug mode. + LLError::setDefaultLevel(LLError::LEVEL_WARN); + + validateArguments(); + initializeIO(); + return true; +} + +bool LLAppAppearanceUtility::cleanup() +{ + if (mProcess) + { + delete mProcess; + mProcess = NULL; + } + if ("-" != mInputFilename && mInput) + { + static_cast<std::ifstream*>(mInput)->close(); + } + if ("" != mOutputFilename && mOutput) + { + static_cast<std::ofstream*>(mOutput)->close(); + delete mOutput; + mOutput = NULL; + } + delete mInput; + mInput = NULL; + return true; +} + +bool LLAppAppearanceUtility::mainLoop() +{ + // This isn't really a loop, for this application. We just execute the requested command. + mProcess->process(mInputData, *mOutput); + return true; +} + diff --git a/indra/appearance_utility/llappappearanceutility.h b/indra/appearance_utility/llappappearanceutility.h new file mode 100644 index 0000000000..2a5b8232eb --- /dev/null +++ b/indra/appearance_utility/llappappearanceutility.h @@ -0,0 +1,97 @@ +/** + * @file llappappearanceutility.h + * @brief Declaration of LLAppAppearanceUtility class. + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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_LLAPPAPPEARANCEUTILITY_H +#define LL_LLAPPAPPEARANCEUTILITY_H + +#include <exception> + +#include "llapp.h" + +enum EResult +{ + RV_SUCCESS = 0, + RV_UNKNOWN_ERROR, + RV_BAD_ARGUMENTS, + RV_UNABLE_OPEN, + RV_UNABLE_TO_PARSE, +}; + +extern const std::string NOTHING_EXTRA; + +class LLAppAppearanceUtility; +class LLBakingProcess; + +// Translate error status into error messages. +class LLAppException : public std::exception +{ +public: + LLAppException(EResult status_code, const std::string& extra = NOTHING_EXTRA); + EResult getStatusCode() { return mStatusCode; } + +private: + void printErrorLLSD(const std::string& key, const std::string& message); + EResult mStatusCode; +}; + + +class LLAppAppearanceUtility : public LLApp +{ +public: + LLAppAppearanceUtility(int argc, char** argv); + virtual ~LLAppAppearanceUtility(); + + // LLApp interface. + /*virtual*/ bool init(); + /*virtual*/ bool cleanup(); + /*virtual*/ bool mainLoop(); + +private: + // Option parsing. + void verifyNoProcess(); + void parseArguments(); + void validateArguments(); + void initializeIO(); +public: + void usage(std::ostream& ostr); + + +private: + int mArgc; + char** mArgv; + LLBakingProcess* mProcess; + std::istream* mInput; + std::ostream* mOutput; + std::string mAppName; + std::string mInputFilename; + std::string mOutputFilename; + LLUUID mAgentID; + LLSD mInputData; +}; + + +#endif /* LL_LLAPPAPPEARANCEUTILITY_H */ + diff --git a/indra/appearance_utility/llbakingavatar.cpp b/indra/appearance_utility/llbakingavatar.cpp new file mode 100644 index 0000000000..bb15a2bf3d --- /dev/null +++ b/indra/appearance_utility/llbakingavatar.cpp @@ -0,0 +1,61 @@ +/** + * @File llbakingavatar.cpp + * @brief Implementation of LLBakingAvatar class which is a derivation of LLAvatarAppearance + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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$ + */ + +#include "linden_common.h" + +#include "llbakingavatar.h" +#include "llbakingjoint.h" +#include "llbakingjointmesh.h" + +LLBakingAvatar::LLBakingAvatar(LLWearableData* wearable_data) : + LLAvatarAppearance(wearable_data) +{ +} + +// virtual +LLBakingAvatar::~LLBakingAvatar() +{ +} + +// virtual +LLAvatarJoint* LLBakingAvatar::createAvatarJoint() +{ + return new LLBakingJoint(); +} + +// virtual +LLAvatarJoint* LLBakingAvatar::createAvatarJoint(S32 joint_num) +{ + return new LLBakingJoint(joint_num); +} + +// virtual +LLAvatarJointMesh* LLBakingAvatar::createAvatarJointMesh() +{ + return new LLBakingJointMesh(); +} + + diff --git a/indra/appearance_utility/llbakingavatar.h b/indra/appearance_utility/llbakingavatar.h new file mode 100644 index 0000000000..53eac8162e --- /dev/null +++ b/indra/appearance_utility/llbakingavatar.h @@ -0,0 +1,76 @@ +/** + * @file llbakingavatar.h + * @brief Declaration of LLBakingAvatar class which is a derivation of LLAvatarAppearance + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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_LLBAKINGAVATAR_H +#define LL_LLBAKINGAVATAR_H + +#include "llavatarappearance.h" + +class LLBakingAvatar : public LLAvatarAppearance +{ + LOG_CLASS(LLBakingAvatar); + +/******************************************************************************** + ** ** + ** INITIALIZATION + **/ +public: + LLBakingAvatar(LLWearableData* wearable_data); + virtual ~LLBakingAvatar(); + + static void initClass(); // initializes static members + +/** Initialization + ** ** + *******************************************************************************/ + +/******************************************************************************** + ** ** + ** STATE + **/ +public: + virtual bool isSelf() const { return true; } + virtual BOOL isValid() const { return TRUE; } + virtual BOOL isUsingBakedTextures() const { return TRUE; } + +/** State + ** ** + *******************************************************************************/ + +/******************************************************************************** + ** ** + ** SKELETON + **/ + +protected: + virtual LLAvatarJoint* createAvatarJoint(); + virtual LLAvatarJoint* createAvatarJoint(S32 joint_num); + virtual LLAvatarJointMesh* createAvatarJointMesh(); + +}; + +#endif /* LL_LLBAKINGAVATAR_H */ + diff --git a/indra/appearance_utility/llbakingjoint.cpp b/indra/appearance_utility/llbakingjoint.cpp new file mode 100644 index 0000000000..96f7b686b2 --- /dev/null +++ b/indra/appearance_utility/llbakingjoint.cpp @@ -0,0 +1,54 @@ +/** + * @file llbakingjoint.cpp + * @brief Implementation of LLBakingJoint class + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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$ + */ + + +#include "linden_common.h" + +#include "llbakingjoint.h" + + +LLBakingJoint::LLBakingJoint() : + LLAvatarJoint() +{ +} + +LLBakingJoint::LLBakingJoint(S32 joint_num) : + LLAvatarJoint(joint_num) +{ +} + +// virtual +LLBakingJoint::~LLBakingJoint() +{ +} + +// virtual +U32 LLBakingJoint::render( F32 pixelArea, BOOL first_pass, BOOL is_dummy) +{ + llerrs << "LLBakingJoint::render() should never be called!" << llendl; + return 0; +} + diff --git a/indra/appearance_utility/llbakingjoint.h b/indra/appearance_utility/llbakingjoint.h new file mode 100644 index 0000000000..5247eb7510 --- /dev/null +++ b/indra/appearance_utility/llbakingjoint.h @@ -0,0 +1,44 @@ +/** + * @file llbakingjoint.h + * @brief Implementation of LLBakingJoint class + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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_LLBAKINGJOINT_H +#define LL_LLBAKINGJOINT_H + +#include "llavatarjoint.h" + +class LLBakingJoint : public virtual LLAvatarJoint +{ +public: + LLBakingJoint(); + LLBakingJoint(S32 joint_num); + virtual ~LLBakingJoint(); + + // LLViewerJoint interface + virtual U32 render( F32 pixelArea, BOOL first_pass = TRUE, BOOL is_dummy = FALSE ); +}; + +#endif /* LL_LLBAKINGJOINT_H */ + diff --git a/indra/appearance_utility/llbakingjointmesh.cpp b/indra/appearance_utility/llbakingjointmesh.cpp new file mode 100644 index 0000000000..877317deb8 --- /dev/null +++ b/indra/appearance_utility/llbakingjointmesh.cpp @@ -0,0 +1,43 @@ +/** + * @file llbakingjointmesh.cpp + * @brief Implementation of LLBakingJointMesh class + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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$ + */ + + +#include "linden_common.h" + +#include "llbakingjointmesh.h" + + +LLBakingJointMesh::LLBakingJointMesh() : + LLAvatarJointMesh() +{ +} + +// virtual +LLBakingJointMesh::~LLBakingJointMesh() +{ +} + + diff --git a/indra/appearance_utility/llbakingjointmesh.h b/indra/appearance_utility/llbakingjointmesh.h new file mode 100644 index 0000000000..6252f6cee3 --- /dev/null +++ b/indra/appearance_utility/llbakingjointmesh.h @@ -0,0 +1,43 @@ +/** + * @file llbakingjoint.h + * @brief Implementation of LLBakingJointMesh class + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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_LLBAKINGJOINTMESH_H +#define LL_LLBAKINGJOINTMESH_H + +#include "llavatarjointmesh.h" +#include "llbakingjoint.h" + +class LLBakingJointMesh : public LLAvatarJointMesh, public LLBakingJoint +{ +public: + LLBakingJointMesh(); + LLBakingJointMesh(S32 joint_num); + virtual ~LLBakingJointMesh(); + +}; + +#endif /* LL_LLBAKINGJOINTMESH_H */ + diff --git a/indra/appearance_utility/llbakingprocess.h b/indra/appearance_utility/llbakingprocess.h new file mode 100644 index 0000000000..a32eae6443 --- /dev/null +++ b/indra/appearance_utility/llbakingprocess.h @@ -0,0 +1,55 @@ +/** + * @file llbakingprocess.h + * @brief Declaration of LLBakingProcess interface. + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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_LLBAKINGPROCESS_H +#define LL_LLBAKINGPROCESS_H + +#include <ostream> + +class LLAppAppearanceUtility; +class LLSD; + +// Simple wrapper for various process modes. +class LLBakingProcess +{ +private: + // Hide default constructor. + LLBakingProcess() {} +public: + LLBakingProcess(LLAppAppearanceUtility* app) : + mApp(app) {} + virtual ~LLBakingProcess() {} + + //virtual std::string getProcessName() const = 0; + virtual void process(LLSD& input, std::ostream& output) = 0; + +protected: + LLAppAppearanceUtility* mApp; +}; + + +#endif /* LL_LLBAKINGPROCESS_H */ + diff --git a/indra/appearance_utility/llbakingshadermgr.h b/indra/appearance_utility/llbakingshadermgr.h index d237682923..88d43ab769 100644 --- a/indra/appearance_utility/llbakingshadermgr.h +++ b/indra/appearance_utility/llbakingshadermgr.h @@ -2,9 +2,9 @@ * @file llbakingshadermgr.h * @brief Texture Baking Shader Manager * - * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2012, 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 diff --git a/indra/appearance_utility/llprocessparams.cpp b/indra/appearance_utility/llprocessparams.cpp new file mode 100644 index 0000000000..71557fa7ba --- /dev/null +++ b/indra/appearance_utility/llprocessparams.cpp @@ -0,0 +1,51 @@ +/** + * @file llprocessparams.cpp + * @brief Implementation of LLProcessParams class. + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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$ + */ + +// linden includes +#include "linden_common.h" + +#include "llsd.h" +#include "llsdserialize.h" +#include "llsdutil.h" + +// appearance includes +#include "llwearabledata.h" + +// project includes +#include "llappappearanceutility.h" +#include "llbakingavatar.h" +#include "llprocessparams.h" + +void LLProcessParams::process(LLSD& input, std::ostream& output) +{ + LLWearableData wearable_data; + + LLSD result; + result["success"] = true; + result["input"] = input; + output << LLSDOStreamer<LLSDXMLFormatter>(result); +} + diff --git a/indra/appearance_utility/llprocessparams.h b/indra/appearance_utility/llprocessparams.h new file mode 100644 index 0000000000..d1e64cb4f0 --- /dev/null +++ b/indra/appearance_utility/llprocessparams.h @@ -0,0 +1,42 @@ +/** + * @file llprocessparams.h + * @brief Declaration of LLProcessParams class. + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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_LLPROCESSPARAMS_H +#define LL_LLPROCESSPARAMS_H + +#include "llbakingprocess.h" + +class LLProcessParams : public LLBakingProcess +{ +public: + LLProcessParams(LLAppAppearanceUtility* app) : + LLBakingProcess(app) {} + + /*virtual*/ void process(LLSD& intput, std::ostream& output); +}; + +#endif /* LL_LLPROCESSPARAMS_H */ + diff --git a/indra/llappearance/llavatarjointmesh.h b/indra/llappearance/llavatarjointmesh.h index 4b56a168ac..427375e733 100755 --- a/indra/llappearance/llavatarjointmesh.h +++ b/indra/llappearance/llavatarjointmesh.h @@ -1,6 +1,6 @@ /** * @file llavatarjointmesh.h - * @brief Implementation of LLAvatarJointMesh class + * @brief Declaration of LLAvatarJointMesh class * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code diff --git a/indra/newview/llviewerjointmesh.h b/indra/newview/llviewerjointmesh.h index 64887152a6..ac5aab4ef2 100755 --- a/indra/newview/llviewerjointmesh.h +++ b/indra/newview/llviewerjointmesh.h @@ -1,6 +1,6 @@ /** * @file llviewerjointmesh.h - * @brief Implementation of LLViewerJointMesh class + * @brief Declaration of LLViewerJointMesh class * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code |