diff options
Diffstat (limited to 'indra/llprimitive')
28 files changed, 3200 insertions, 883 deletions
diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt index 5dc4c701a1..f4d21308b3 100644 --- a/indra/llprimitive/CMakeLists.txt +++ b/indra/llprimitive/CMakeLists.txt @@ -17,12 +17,15 @@ include_directories( set(llprimitive_SOURCE_FILES llmaterialtable.cpp + llmediaentry.cpp llprimitive.cpp + llprimtexturelist.cpp lltextureanim.cpp lltextureentry.cpp lltreeparams.cpp llvolumemessage.cpp llvolumexml.cpp + material_codes.cpp ) set(llprimitive_HEADER_FILES @@ -30,7 +33,9 @@ set(llprimitive_HEADER_FILES legacy_object_types.h llmaterialtable.h + llmediaentry.h llprimitive.h + llprimtexturelist.h lltextureanim.h lltextureentry.h lltreeparams.h @@ -47,3 +52,12 @@ set_source_files_properties(${llprimitive_HEADER_FILES} list(APPEND llprimitive_SOURCE_FILES ${llprimitive_HEADER_FILES}) add_library (llprimitive ${llprimitive_SOURCE_FILES}) + +if(LL_TESTS) + #add unit tests + INCLUDE(LLAddBuildTest) + SET(llprimitive_TEST_SOURCE_FILES + llmediaentry.cpp + ) + LL_ADD_PROJECT_UNIT_TESTS(llprimitive "${llprimitive_TEST_SOURCE_FILES}") +endif(LL_TESTS) diff --git a/indra/llprimitive/legacy_object_types.h b/indra/llprimitive/legacy_object_types.h index 09fd72af0e..697ad584a5 100644 --- a/indra/llprimitive/legacy_object_types.h +++ b/indra/llprimitive/legacy_object_types.h @@ -2,30 +2,25 @@ * @file legacy_object_types.h * @brief Byte codes for basic object and primitive types * - * $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$ */ diff --git a/indra/llprimitive/llmaterialtable.cpp b/indra/llprimitive/llmaterialtable.cpp index 61c9849144..99f32e4109 100644 --- a/indra/llprimitive/llmaterialtable.cpp +++ b/indra/llprimitive/llmaterialtable.cpp @@ -2,30 +2,25 @@ * @file llmaterialtable.cpp * @brief Table of material names and IDs for viewer * - * $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$ */ @@ -91,6 +86,9 @@ F32 const LLMaterialTable::DEFAULT_FRICTION = 0.5f; F32 const LLMaterialTable::DEFAULT_RESTITUTION = 0.4f; LLMaterialTable::LLMaterialTable() + : mCollisionSoundMatrix(NULL), + mSlidingSoundMatrix(NULL), + mRollingSoundMatrix(NULL) { } @@ -123,16 +121,28 @@ LLMaterialTable::~LLMaterialTable() 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]; + } +} + void LLMaterialTable::initBasicTable() { - add(LL_MCODE_STONE,"Stone", LL_DEFAULT_STONE_UUID); - add(LL_MCODE_METAL,"Metal", LL_DEFAULT_METAL_UUID); - add(LL_MCODE_GLASS,"Glass", LL_DEFAULT_GLASS_UUID); - add(LL_MCODE_WOOD,"Wood", LL_DEFAULT_WOOD_UUID); - add(LL_MCODE_FLESH,"Flesh", LL_DEFAULT_FLESH_UUID); - add(LL_MCODE_PLASTIC,"Plastic", LL_DEFAULT_PLASTIC_UUID); - add(LL_MCODE_RUBBER,"Rubber", LL_DEFAULT_RUBBER_UUID); - add(LL_MCODE_LIGHT,"Light", LL_DEFAULT_LIGHT_UUID); + // *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 @@ -331,7 +341,7 @@ void LLMaterialTable::initBasicTable() } } -BOOL LLMaterialTable::add(U8 mcode, const char* name, const LLUUID &uuid) +BOOL LLMaterialTable::add(U8 mcode, const std::string& name, const LLUUID &uuid) { LLMaterialInfo *infop; @@ -466,13 +476,13 @@ BOOL LLMaterialTable::addDamageAndEnergy(U8 mcode, const F32 &hp_mod, const F32 return FALSE; } -LLUUID LLMaterialTable::getDefaultTextureID(char* name) +LLUUID LLMaterialTable::getDefaultTextureID(const std::string& name) { for (info_list_t::iterator iter = mMaterialInfoList.begin(); iter != mMaterialInfoList.end(); ++iter) { LLMaterialInfo *infop = *iter; - if (!strcmp(name, infop->mName)) + if (name == infop->mName) { return infop->mDefaultTextureID; } @@ -499,13 +509,13 @@ LLUUID LLMaterialTable::getDefaultTextureID(U8 mcode) } -U8 LLMaterialTable::getMCode(const char* name) +U8 LLMaterialTable::getMCode(const std::string& name) { for (info_list_t::iterator iter = mMaterialInfoList.begin(); iter != mMaterialInfoList.end(); ++iter) { LLMaterialInfo *infop = *iter; - if (!strcmp(name, infop->mName)) + if (name == infop->mName) { return infop->mMCode; } @@ -515,7 +525,7 @@ U8 LLMaterialTable::getMCode(const char* name) } -char* LLMaterialTable::getName(U8 mcode) +std::string LLMaterialTable::getName(U8 mcode) { mcode &= LL_MCODE_MASK; for (info_list_t::iterator iter = mMaterialInfoList.begin(); diff --git a/indra/llprimitive/llmaterialtable.h b/indra/llprimitive/llmaterialtable.h index 7dbe7de917..a17e0103ff 100644 --- a/indra/llprimitive/llmaterialtable.h +++ b/indra/llprimitive/llmaterialtable.h @@ -2,30 +2,25 @@ * @file llmaterialtable.h * @brief Table of material information for the viewer UI * - * $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$ */ @@ -37,6 +32,8 @@ #include <list> +class LLMaterialInfo; + const U32 LLMATERIAL_INFO_NAME_LENGTH = 256; // We've moved toward more reasonable mass values for the Havok4 engine. @@ -63,49 +60,6 @@ const F32 LEGACY_DEFAULT_OBJECT_DENSITY = 10.0f; const F32 DEFAULT_AVATAR_DENSITY = 445.3f; // was 444.24f; -class LLMaterialInfo -{ -public: - U8 mMCode; - char mName[LLMATERIAL_INFO_NAME_LENGTH]; /* Flawfinder: ignore */ - 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 char* name, const LLUUID &uuid) - { - init(mcode,name,uuid); - }; - - void init(U8 mcode, const char* name, const LLUUID &uuid) - { - mName[0] = 0; - mDensity = 1000.f; // default to 1000.0 (water) - mHPModifier = 1.f; - mDamageModifier = 1.f; - mEPModifier = 1.f; - - mMCode = mcode; - if (name) - { - LLString::copy(mName,name,LLMATERIAL_INFO_NAME_LENGTH); - } - mDefaultTextureID = uuid; - }; - - ~LLMaterialInfo() - { - }; - -}; - class LLMaterialTable { public: @@ -150,7 +104,9 @@ public: void initBasicTable(); - BOOL add(U8 mcode, const char* name, const LLUUID &uuid); + 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); @@ -160,10 +116,10 @@ public: 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(char* name); // LLUUID::null if not found + LLUUID getDefaultTextureID(const std::string& name); // LLUUID::null if not found LLUUID getDefaultTextureID(U8 mcode); // LLUUID::null if not found - U8 getMCode(const char* name); // 0 if not found - char* getName(U8 mcode); + 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 @@ -186,5 +142,47 @@ public: 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() + { + }; + +}; + #endif diff --git a/indra/llprimitive/llmediaentry.cpp b/indra/llprimitive/llmediaentry.cpp new file mode 100644 index 0000000000..02aba2bd83 --- /dev/null +++ b/indra/llprimitive/llmediaentry.cpp @@ -0,0 +1,596 @@ +/** + * @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$ + */ + +#include "linden_common.h" +#include "llmediaentry.h" +#include "lllslconstants.h" + +#include <boost/regex.hpp> + +// LLSD key defines +// DO NOT REORDER OR REMOVE THESE! + +// Some LLSD keys. Do not change! +#define MEDIA_ALT_IMAGE_ENABLE_KEY_STR "alt_image_enable" +#define MEDIA_CONTROLS_KEY_STR "controls" +#define MEDIA_CURRENT_URL_KEY_STR "current_url" +#define MEDIA_HOME_URL_KEY_STR "home_url" +#define MEDIA_AUTO_LOOP_KEY_STR "auto_loop" +#define MEDIA_AUTO_PLAY_KEY_STR "auto_play" +#define MEDIA_AUTO_SCALE_KEY_STR "auto_scale" +#define MEDIA_AUTO_ZOOM_KEY_STR "auto_zoom" +#define MEDIA_FIRST_CLICK_INTERACT_KEY_STR "first_click_interact" +#define MEDIA_WIDTH_PIXELS_KEY_STR "width_pixels" +#define MEDIA_HEIGHT_PIXELS_KEY_STR "height_pixels" + +// "security" fields +#define MEDIA_WHITELIST_ENABLE_KEY_STR "whitelist_enable" +#define MEDIA_WHITELIST_KEY_STR "whitelist" + +// "permissions" fields +#define MEDIA_PERMS_INTERACT_KEY_STR "perms_interact" +#define MEDIA_PERMS_CONTROL_KEY_STR "perms_control" + +// "general" fields +const char* LLMediaEntry::ALT_IMAGE_ENABLE_KEY = MEDIA_ALT_IMAGE_ENABLE_KEY_STR; +const char* LLMediaEntry::CONTROLS_KEY = MEDIA_CONTROLS_KEY_STR; +const char* LLMediaEntry::CURRENT_URL_KEY = MEDIA_CURRENT_URL_KEY_STR; +const char* LLMediaEntry::HOME_URL_KEY = MEDIA_HOME_URL_KEY_STR; +const char* LLMediaEntry::AUTO_LOOP_KEY = MEDIA_AUTO_LOOP_KEY_STR; +const char* LLMediaEntry::AUTO_PLAY_KEY = MEDIA_AUTO_PLAY_KEY_STR; +const char* LLMediaEntry::AUTO_SCALE_KEY = MEDIA_AUTO_SCALE_KEY_STR; +const char* LLMediaEntry::AUTO_ZOOM_KEY = MEDIA_AUTO_ZOOM_KEY_STR; +const char* LLMediaEntry::FIRST_CLICK_INTERACT_KEY = MEDIA_FIRST_CLICK_INTERACT_KEY_STR; +const char* LLMediaEntry::WIDTH_PIXELS_KEY = MEDIA_WIDTH_PIXELS_KEY_STR; +const char* LLMediaEntry::HEIGHT_PIXELS_KEY = MEDIA_HEIGHT_PIXELS_KEY_STR; + +// "security" fields +const char* LLMediaEntry::WHITELIST_ENABLE_KEY = MEDIA_WHITELIST_ENABLE_KEY_STR; +const char* LLMediaEntry::WHITELIST_KEY = MEDIA_WHITELIST_KEY_STR; + +// "permissions" fields +const char* LLMediaEntry::PERMS_INTERACT_KEY = MEDIA_PERMS_INTERACT_KEY_STR; +const char* LLMediaEntry::PERMS_CONTROL_KEY = MEDIA_PERMS_CONTROL_KEY_STR; + +#define DEFAULT_URL_PREFIX "http://" + +// Constructor(s) +LLMediaEntry::LLMediaEntry() : + mAltImageEnable(false), + mControls(STANDARD), + mCurrentURL(""), + mHomeURL(""), + mAutoLoop(false), + mAutoPlay(false), + mAutoScale(false), + mAutoZoom(false), + mFirstClickInteract(false), + mWidthPixels(0), + mHeightPixels(0), + mWhiteListEnable(false), + // mWhiteList + mPermsInteract(PERM_ALL), + mPermsControl(PERM_ALL), + mMediaIDp(NULL) +{ +} + +LLMediaEntry::LLMediaEntry(const LLMediaEntry &rhs) : + mMediaIDp(NULL) +{ + // "general" fields + mAltImageEnable = rhs.mAltImageEnable; + mControls = rhs.mControls; + mCurrentURL = rhs.mCurrentURL; + mHomeURL = rhs.mHomeURL; + mAutoLoop = rhs.mAutoLoop; + mAutoPlay = rhs.mAutoPlay; + mAutoScale = rhs.mAutoScale; + mAutoZoom = rhs.mAutoZoom; + mFirstClickInteract = rhs.mFirstClickInteract; + mWidthPixels = rhs.mWidthPixels; + mHeightPixels = rhs.mHeightPixels; + + // "security" fields + mWhiteListEnable = rhs.mWhiteListEnable; + mWhiteList = rhs.mWhiteList; + + // "permissions" fields + mPermsInteract = rhs.mPermsInteract; + mPermsControl = rhs.mPermsControl; +} + +LLMediaEntry::~LLMediaEntry() +{ + if (NULL != mMediaIDp) + { + delete mMediaIDp; + } +} + +LLSD LLMediaEntry::asLLSD() const +{ + LLSD sd; + asLLSD(sd); + return sd; +} + +// +// LLSD functions +// +void LLMediaEntry::asLLSD(LLSD& sd) const +{ + // "general" fields + sd[ALT_IMAGE_ENABLE_KEY] = mAltImageEnable; + sd[CONTROLS_KEY] = (LLSD::Integer)mControls; + sd[CURRENT_URL_KEY] = mCurrentURL; + sd[HOME_URL_KEY] = mHomeURL; + sd[AUTO_LOOP_KEY] = mAutoLoop; + sd[AUTO_PLAY_KEY] = mAutoPlay; + sd[AUTO_SCALE_KEY] = mAutoScale; + sd[AUTO_ZOOM_KEY] = mAutoZoom; + sd[FIRST_CLICK_INTERACT_KEY] = mFirstClickInteract; + sd[WIDTH_PIXELS_KEY] = mWidthPixels; + sd[HEIGHT_PIXELS_KEY] = mHeightPixels; + + // "security" fields + sd[WHITELIST_ENABLE_KEY] = mWhiteListEnable; + sd.erase(WHITELIST_KEY); + for (U32 i=0; i<mWhiteList.size(); i++) + { + sd[WHITELIST_KEY].append(mWhiteList[i]); + } + + // "permissions" fields + sd[PERMS_INTERACT_KEY] = mPermsInteract; + sd[PERMS_CONTROL_KEY] = mPermsControl; +} + +// static +bool LLMediaEntry::checkLLSD(const LLSD& sd) +{ + if (sd.isUndefined()) return true; + LLMediaEntry temp; + return temp.fromLLSDInternal(sd, true); +} + +void LLMediaEntry::fromLLSD(const LLSD& sd) +{ + (void)fromLLSDInternal(sd, true); +} + +void LLMediaEntry::mergeFromLLSD(const LLSD& sd) +{ + (void)fromLLSDInternal(sd, false); +} + +// *NOTE: returns true if NO failures to set occurred, false otherwise. +// However, be aware that if a failure to set does occur, it does +// not stop setting fields from the LLSD! +bool LLMediaEntry::fromLLSDInternal(const LLSD& sd, bool overwrite) +{ + // *HACK: we sort of cheat here and assume that status is a + // 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) ) + { + status |= setAltImageEnable( sd[ALT_IMAGE_ENABLE_KEY] ); + } + if ( overwrite || sd.has(CONTROLS_KEY) ) + { + status |= setControls( (MediaControls)(LLSD::Integer)sd[CONTROLS_KEY] ); + } + if ( overwrite || sd.has(CURRENT_URL_KEY) ) + { + // Don't check whitelist + status |= setCurrentURLInternal( sd[CURRENT_URL_KEY], false ); + } + if ( overwrite || sd.has(HOME_URL_KEY) ) + { + status |= setHomeURL( sd[HOME_URL_KEY] ); + } + if ( overwrite || sd.has(AUTO_LOOP_KEY) ) + { + status |= setAutoLoop( sd[AUTO_LOOP_KEY] ); + } + if ( overwrite || sd.has(AUTO_PLAY_KEY) ) + { + status |= setAutoPlay( sd[AUTO_PLAY_KEY] ); + } + if ( overwrite || sd.has(AUTO_SCALE_KEY) ) + { + status |= setAutoScale( sd[AUTO_SCALE_KEY] ); + } + if ( overwrite || sd.has(AUTO_ZOOM_KEY) ) + { + status |= setAutoZoom( sd[AUTO_ZOOM_KEY] ); + } + if ( overwrite || sd.has(FIRST_CLICK_INTERACT_KEY) ) + { + status |= setFirstClickInteract( sd[FIRST_CLICK_INTERACT_KEY] ); + } + if ( overwrite || sd.has(WIDTH_PIXELS_KEY) ) + { + status |= setWidthPixels( (LLSD::Integer)sd[WIDTH_PIXELS_KEY] ); + } + if ( overwrite || sd.has(HEIGHT_PIXELS_KEY) ) + { + status |= setHeightPixels( (LLSD::Integer)sd[HEIGHT_PIXELS_KEY] ); + } + + // "security" fields + if ( overwrite || sd.has(WHITELIST_ENABLE_KEY) ) + { + status |= setWhiteListEnable( sd[WHITELIST_ENABLE_KEY] ); + } + if ( overwrite || sd.has(WHITELIST_KEY) ) + { + status |= setWhiteList( sd[WHITELIST_KEY] ); + } + + // "permissions" fields + if ( overwrite || sd.has(PERMS_INTERACT_KEY) ) + { + status |= setPermsInteract( 0xff & (LLSD::Integer)sd[PERMS_INTERACT_KEY] ); + } + if ( overwrite || sd.has(PERMS_CONTROL_KEY) ) + { + status |= setPermsControl( 0xff & (LLSD::Integer)sd[PERMS_CONTROL_KEY] ); + } + + return LSL_STATUS_OK == status; +} + +LLMediaEntry& LLMediaEntry::operator=(const LLMediaEntry &rhs) +{ + if (this != &rhs) + { + // "general" fields + mAltImageEnable = rhs.mAltImageEnable; + mControls = rhs.mControls; + mCurrentURL = rhs.mCurrentURL; + mHomeURL = rhs.mHomeURL; + mAutoLoop = rhs.mAutoLoop; + mAutoPlay = rhs.mAutoPlay; + mAutoScale = rhs.mAutoScale; + mAutoZoom = rhs.mAutoZoom; + mFirstClickInteract = rhs.mFirstClickInteract; + mWidthPixels = rhs.mWidthPixels; + mHeightPixels = rhs.mHeightPixels; + + // "security" fields + mWhiteListEnable = rhs.mWhiteListEnable; + mWhiteList = rhs.mWhiteList; + + // "permissions" fields + mPermsInteract = rhs.mPermsInteract; + mPermsControl = rhs.mPermsControl; + } + + return *this; +} + +bool LLMediaEntry::operator==(const LLMediaEntry &rhs) const +{ + return ( + // "general" fields + mAltImageEnable == rhs.mAltImageEnable && + mControls == rhs.mControls && + mCurrentURL == rhs.mCurrentURL && + mHomeURL == rhs.mHomeURL && + mAutoLoop == rhs.mAutoLoop && + mAutoPlay == rhs.mAutoPlay && + mAutoScale == rhs.mAutoScale && + mAutoZoom == rhs.mAutoZoom && + mFirstClickInteract == rhs.mFirstClickInteract && + mWidthPixels == rhs.mWidthPixels && + mHeightPixels == rhs.mHeightPixels && + + // "security" fields + mWhiteListEnable == rhs.mWhiteListEnable && + mWhiteList == rhs.mWhiteList && + + // "permissions" fields + mPermsInteract == rhs.mPermsInteract && + mPermsControl == rhs.mPermsControl + + ); +} + +bool LLMediaEntry::operator!=(const LLMediaEntry &rhs) const +{ + return ( + // "general" fields + mAltImageEnable != rhs.mAltImageEnable || + mControls != rhs.mControls || + mCurrentURL != rhs.mCurrentURL || + mHomeURL != rhs.mHomeURL || + mAutoLoop != rhs.mAutoLoop || + mAutoPlay != rhs.mAutoPlay || + mAutoScale != rhs.mAutoScale || + mAutoZoom != rhs.mAutoZoom || + mFirstClickInteract != rhs.mFirstClickInteract || + mWidthPixels != rhs.mWidthPixels || + mHeightPixels != rhs.mHeightPixels || + + // "security" fields + mWhiteListEnable != rhs.mWhiteListEnable || + mWhiteList != rhs.mWhiteList || + + // "permissions" fields + mPermsInteract != rhs.mPermsInteract || + mPermsControl != rhs.mPermsControl + + ); +} + +U32 LLMediaEntry::setWhiteList( const std::vector<std::string> &whitelist ) +{ + // *NOTE: This code is VERY similar to the setWhitelist below. + // IF YOU CHANGE THIS IMPLEMENTATION, BE SURE TO CHANGE THE OTHER! + U32 size = 0; + U32 count = 0; + // 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) + { + const std::string &entry = (*iter); + size += entry.length() + 1; // Include one for \0 + count ++; + if (size > MAX_WHITELIST_SIZE || count > MAX_WHITELIST_COUNT) + { + return LSL_STATUS_BOUNDS_ERROR; + } + } + // Next clear the vector + mWhiteList.clear(); + // Then re-iterate and copy entries + iter = whitelist.begin(); + for ( ; iter < end; ++iter) + { + const std::string &entry = (*iter); + mWhiteList.push_back(entry); + } + return LSL_STATUS_OK; +} + +U32 LLMediaEntry::setWhiteList( const LLSD &whitelist ) +{ + // If whitelist is undef, the whitelist is cleared + if (whitelist.isUndefined()) + { + mWhiteList.clear(); + return LSL_STATUS_OK; + } + + // However, if the whitelist is an empty array, erase it. + if (whitelist.isArray()) + { + // *NOTE: This code is VERY similar to the setWhitelist above. + // IF YOU CHANGE THIS IMPLEMENTATION, BE SURE TO CHANGE THE OTHER! + U32 size = 0; + U32 count = 0; + // 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) + { + const std::string &entry = (*iter).asString(); + size += entry.length() + 1; // Include one for \0 + count ++; + if (size > MAX_WHITELIST_SIZE || count > MAX_WHITELIST_COUNT) + { + return LSL_STATUS_BOUNDS_ERROR; + } + } + // Next clear the vector + mWhiteList.clear(); + // Then re-iterate and copy entries + iter = whitelist.beginArray(); + for ( ; iter < end; ++iter) + { + const std::string &entry = (*iter).asString(); + mWhiteList.push_back(entry); + } + return LSL_STATUS_OK; + } + else + { + return LSL_STATUS_MALFORMED_PARAMS; + } +} + + +static void prefix_with(std::string &str, const char *chars, const char *prefix) +{ + // Given string 'str', prefix all instances of any character in 'chars' + // with 'prefix' + size_t found = str.find_first_of(chars); + size_t prefix_len = strlen(prefix); + while (found != std::string::npos) + { + str.insert(found, prefix, prefix_len); + found = str.find_first_of(chars, found+prefix_len+1); + } +} + +static bool pattern_match(const std::string &candidate_str, const std::string &pattern) +{ + // 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 boost::regex_match(candidate_str, regexp); +} + +bool LLMediaEntry::checkCandidateUrl(const std::string& url) const +{ + if (getWhiteListEnable()) + { + return checkUrlAgainstWhitelist(url, getWhiteList()); + } + else + { + return true; + } +} + +// static +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) + { + passes = false; + + // Case insensitive: the reason why we toUpper both this and the + // filter + std::string candidate_url = url; + // Use lluri to see if there is a path part in the candidate URL. No path? Assume "/" + LLURI candidate_uri(candidate_url); + std::vector<std::string>::const_iterator iter = whitelist.begin(); + std::vector<std::string>::const_iterator end = whitelist.end(); + 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()) + { + filter_uri = LLURI(DEFAULT_URL_PREFIX + filter); + } + bool authority_passes = pattern_match( candidate_uri.authority(), filter_uri.authority() ); + bool path_passes = pattern_match( candidate_uri.escapedPath(), filter_uri.escapedPath() ); + + if (scheme_passes && authority_passes && path_passes) + { + passes = true; + break; + } + } + } + return passes; +} + +U32 LLMediaEntry::setStringFieldWithLimit( std::string &field, const std::string &value, U32 limit ) +{ + if ( value.length() > limit ) + { + return LSL_STATUS_BOUNDS_ERROR; + } + else + { + field = value; + return LSL_STATUS_OK; + } +} + +U32 LLMediaEntry::setControls(LLMediaEntry::MediaControls controls) +{ + if (controls == STANDARD || + controls == MINI) + { + mControls = controls; + return LSL_STATUS_OK; + } + return LSL_STATUS_BOUNDS_ERROR; +} + +U32 LLMediaEntry::setPermsInteract( U8 val ) +{ + mPermsInteract = val & PERM_MASK; + return LSL_STATUS_OK; +} + +U32 LLMediaEntry::setPermsControl( U8 val ) +{ + mPermsControl = val & PERM_MASK; + return LSL_STATUS_OK; +} + +U32 LLMediaEntry::setCurrentURL(const std::string& current_url) +{ + return setCurrentURLInternal( current_url, true ); +} + +U32 LLMediaEntry::setCurrentURLInternal(const std::string& current_url, bool check_whitelist) +{ + if ( ! check_whitelist || checkCandidateUrl(current_url)) + { + return setStringFieldWithLimit( mCurrentURL, current_url, MAX_URL_LENGTH ); + } + else + { + return LSL_STATUS_WHITELIST_FAILED; + } +} + +U32 LLMediaEntry::setHomeURL(const std::string& home_url) +{ + return setStringFieldWithLimit( mHomeURL, home_url, MAX_URL_LENGTH ); +} + +U32 LLMediaEntry::setWidthPixels(U16 width) +{ + if (width > MAX_WIDTH_PIXELS) return LSL_STATUS_BOUNDS_ERROR; + mWidthPixels = width; + 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; +} + +const LLUUID &LLMediaEntry::getMediaID() const +{ + // Lazily generate media ID + if (NULL == mMediaIDp) + { + mMediaIDp = new LLUUID(); + mMediaIDp->generate(); + } + return *mMediaIDp; +} + diff --git a/indra/llprimitive/llmediaentry.h b/indra/llprimitive/llmediaentry.h new file mode 100644 index 0000000000..33855b3fb2 --- /dev/null +++ b/indra/llprimitive/llmediaentry.h @@ -0,0 +1,222 @@ +/** + * @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$ + */ + +#ifndef LL_LLMEDIAENTRY_H +#define LL_LLMEDIAENTRY_H + +#include "llsd.h" +#include "llstring.h" + +// For return values of set* +#include "lllslconstants.h" + +class LLMediaEntry +{ +public: + enum MediaControls { + STANDARD = 0, + MINI + }; + + // Constructors + LLMediaEntry(); + LLMediaEntry(const LLMediaEntry &rhs); + + LLMediaEntry &operator=(const LLMediaEntry &rhs); + virtual ~LLMediaEntry(); + + bool operator==(const LLMediaEntry &rhs) const; + bool operator!=(const LLMediaEntry &rhs) const; + + // Render as LLSD + LLSD asLLSD() const; + void asLLSD(LLSD& sd) const; + operator LLSD() const { return asLLSD(); } + // Returns false iff the given LLSD contains fields that violate any bounds + // limits. + static bool checkLLSD(const LLSD& sd); + // 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); + // 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); + + // "general" fields + bool getAltImageEnable() const { return mAltImageEnable; } + MediaControls getControls() const { return mControls; } + std::string getCurrentURL() const { return mCurrentURL; } + std::string getHomeURL() const { return mHomeURL; } + bool getAutoLoop() const { return mAutoLoop; } + bool getAutoPlay() const { return mAutoPlay; } + bool getAutoScale() const { return mAutoScale; } + bool getAutoZoom() const { return mAutoZoom; } + bool getFirstClickInteract() const { return mFirstClickInteract; } + U16 getWidthPixels() const { return mWidthPixels; } + U16 getHeightPixels() const { return mHeightPixels; } + + // "security" fields + bool getWhiteListEnable() const { return mWhiteListEnable; } + const std::vector<std::string> &getWhiteList() const { return mWhiteList; } + + // "permissions" fields + U8 getPermsInteract() const { return mPermsInteract; } + U8 getPermsControl() const { return mPermsControl; } + + // 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); + U32 setCurrentURL(const std::string& current_url); + U32 setHomeURL(const std::string& home_url); + U32 setAutoLoop(bool auto_loop) { mAutoLoop = auto_loop; return LSL_STATUS_OK; } + U32 setAutoPlay(bool auto_play) { mAutoPlay = auto_play; return LSL_STATUS_OK; } + U32 setAutoScale(bool auto_scale) { mAutoScale = auto_scale; return LSL_STATUS_OK; } + U32 setAutoZoom(bool auto_zoom) { mAutoZoom = auto_zoom; return LSL_STATUS_OK; } + U32 setFirstClickInteract(bool first_click) { mFirstClickInteract = first_click; return LSL_STATUS_OK; } + U32 setWidthPixels(U16 width); + U32 setHeightPixels(U16 height); + + // "security" fields + U32 setWhiteListEnable( bool whitelist_enable ) { mWhiteListEnable = whitelist_enable; return LSL_STATUS_OK; } + U32 setWhiteList( const std::vector<std::string> &whitelist ); + U32 setWhiteList( const LLSD &whitelist ); // takes an LLSD array + + // "permissions" fields + U32 setPermsInteract( U8 val ); + U32 setPermsControl( U8 val ); + + const LLUUID& getMediaID() const; + + // Helper function to check a candidate URL against the whitelist + // Returns true iff candidate URL passes (or if there is no whitelist), false otherwise + bool checkCandidateUrl(const std::string& url) const; + +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, + const std::vector<std::string> &whitelist); + +public: + // LLSD key defines + // "general" fields + static const char* ALT_IMAGE_ENABLE_KEY; + static const char* CONTROLS_KEY; + static const char* CURRENT_URL_KEY; + static const char* HOME_URL_KEY; + static const char* AUTO_LOOP_KEY; + static const char* AUTO_PLAY_KEY; + static const char* AUTO_SCALE_KEY; + static const char* AUTO_ZOOM_KEY; + static const char* FIRST_CLICK_INTERACT_KEY; + static const char* WIDTH_PIXELS_KEY; + static const char* HEIGHT_PIXELS_KEY; + + // "security" fields + static const char* WHITELIST_ENABLE_KEY; + static const char* WHITELIST_KEY; + + // "permissions" fields + static const char* PERMS_INTERACT_KEY; + static const char* PERMS_CONTROL_KEY; + + // Field enumerations & constants + + // *NOTE: DO NOT change the order of these, and do not insert values + // in the middle! + // Add values to the end, and make sure to change PARAM_MAX_ID! + enum Fields { + ALT_IMAGE_ENABLE_ID = 0, + CONTROLS_ID = 1, + CURRENT_URL_ID = 2, + HOME_URL_ID = 3, + AUTO_LOOP_ID = 4, + AUTO_PLAY_ID = 5, + AUTO_SCALE_ID = 6, + AUTO_ZOOM_ID = 7, + FIRST_CLICK_INTERACT_ID = 8, + WIDTH_PIXELS_ID = 9, + HEIGHT_PIXELS_ID = 10, + WHITELIST_ENABLE_ID = 11, + WHITELIST_ID = 12, + PERMS_INTERACT_ID = 13, + PERMS_CONTROL_ID = 14, + PARAM_MAX_ID = PERMS_CONTROL_ID + }; + + // "permissions" values + // (e.g. (PERM_OWNER | PERM_GROUP) sets permissions on for OWNER and GROUP + static const U8 PERM_NONE = 0x0; + static const U8 PERM_OWNER = 0x1; + static const U8 PERM_GROUP = 0x2; + static const U8 PERM_ANYONE = 0x4; + static const U8 PERM_ALL = PERM_OWNER|PERM_GROUP|PERM_ANYONE; + static const U8 PERM_MASK = PERM_OWNER|PERM_GROUP|PERM_ANYONE; + + // Limits (in bytes) + static const U32 MAX_URL_LENGTH = 1024; + static const U32 MAX_WHITELIST_SIZE = 1024; + static const U32 MAX_WHITELIST_COUNT = 64; + static const U16 MAX_WIDTH_PIXELS = 2048; + static const U16 MAX_HEIGHT_PIXELS = 2048; + +private: + + U32 setStringFieldWithLimit( std::string &field, const std::string &value, U32 limit ); + U32 setCurrentURLInternal( const std::string &url, bool check_whitelist); + bool fromLLSDInternal(const LLSD &sd, bool overwrite); + +private: + // "general" fields + bool mAltImageEnable; + MediaControls mControls; + std::string mCurrentURL; + std::string mHomeURL; + bool mAutoLoop; + bool mAutoPlay; + bool mAutoScale; + bool mAutoZoom; + bool mFirstClickInteract; + U16 mWidthPixels; + U16 mHeightPixels; + + // "security" fields + bool mWhiteListEnable; + std::vector<std::string> mWhiteList; + + // "permissions" fields + U8 mPermsInteract; + U8 mPermsControl; + + mutable LLUUID *mMediaIDp; // temporary id assigned to media on the viewer +}; + +#endif + diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index ff69cacf0f..258c0c3c15 100644 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -2,30 +2,25 @@ * @file llprimitive.cpp * @brief LLPrimitive base class * - * $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. * - * 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 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. * - * 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. + * 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. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * 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,7 +37,8 @@ #include "llvolumemgr.h" #include "llstring.h" #include "lldatapacker.h" -#include "llsdutil.h" +#include "llsdutil_math.h" +#include "llprimtexturelist.h" /** * exported constants @@ -111,9 +107,15 @@ const F32 FLEXIBLE_OBJECT_DEFAULT_LENGTH = 1.0f; const BOOL FLEXIBLE_OBJECT_DEFAULT_USING_COLLISION_SPHERE = FALSE; const BOOL FLEXIBLE_OBJECT_DEFAULT_RENDERING_COLLISION_SPHERE = FALSE; +const S32 MAX_FACE_BITS = 9; const char *SCULPT_DEFAULT_TEXTURE = "be293869-d0d9-0a69-5989-ad27f1946fd4"; // old inverted texture: "7595d345-a24c-e7ef-f0bd-78793792133e"; +// Texture rotations are sent over the wire as a S16. This is used to scale the actual float +// value to a S16. Don't use 7FFF as it introduces some odd rounding with 180 since it +// can't be divided by 2. See DEV-19108 +const F32 TEXTURE_ROTATION_PACK_FACTOR = ((F32) 0x08000); + //static // LEGACY: by default we use the LLVolumeMgr::gVolumeMgr global // TODO -- eliminate this global from the codebase! @@ -124,7 +126,7 @@ void LLPrimitive::setVolumeManager( LLVolumeMgr* volume_manager ) { if ( !volume_manager || sVolumeManager ) { - llerrs << "Unable to set LLPrimitive::sVolumeManager to NULL" << llendl; + llerrs << "LLPrimitive::sVolumeManager attempting to be set to NULL or it already has been set." << llendl; } sVolumeManager = volume_manager; } @@ -145,7 +147,9 @@ bool LLPrimitive::cleanupVolumeManager() //=============================================================== LLPrimitive::LLPrimitive() -: mMiscFlags(0) +: mTextureList(), + mNumTEs(0), + mMiscFlags(0) { mPrimitiveCode = 0; @@ -162,20 +166,12 @@ LLPrimitive::LLPrimitive() mAngularVelocity.setVec(0.f,0.f,0.f); mScale.setVec(1.f,1.f,1.f); - - mNumTEs = 0; - mTextureList = NULL; } //=============================================================== LLPrimitive::~LLPrimitive() { - if (mTextureList) - { - delete [] mTextureList; - mTextureList = NULL; - } - + clearTextureList(); // Cleanup handled by volume manager if (mVolumep) { @@ -184,6 +180,10 @@ LLPrimitive::~LLPrimitive() mVolumep = NULL; } +void LLPrimitive::clearTextureList() +{ +} + //=============================================================== // static LLPrimitive *LLPrimitive::createPrimitive(LLPCode p_code) @@ -207,15 +207,7 @@ LLPrimitive *LLPrimitive::createPrimitive(LLPCode p_code) void LLPrimitive::init_primitive(LLPCode p_code) { LLMemType m1(LLMemType::MTYPE_PRIMITIVE); - if (mNumTEs) - { - if (mTextureList) - { - delete [] mTextureList; - } - mTextureList = new LLTextureEntry[mNumTEs]; - } - + clearTextureList(); mPrimitiveCode = p_code; } @@ -225,342 +217,146 @@ void LLPrimitive::setPCode(const U8 p_code) } //=============================================================== -const LLTextureEntry * LLPrimitive::getTE(const U8 te_num) const +LLTextureEntry* LLPrimitive::getTE(const U8 index) const { - // if we're asking for a non-existent face, return null - if (mNumTEs && (te_num< mNumTEs)) - { - return(&mTextureList[te_num]); - } - else - { - return(NULL); - } + return mTextureList.getTexture(index); } //=============================================================== void LLPrimitive::setNumTEs(const U8 num_tes) { - if (num_tes == mNumTEs) - { - return; - } - - // Right now, we don't try and preserve entries when the number of faces - // changes. - - LLMemType m1(LLMemType::MTYPE_PRIMITIVE); - if (num_tes) - { - LLTextureEntry *new_tes; - new_tes = new LLTextureEntry[num_tes]; - U32 i; - for (i = 0; i < num_tes; i++) - { - if (i < mNumTEs) - { - new_tes[i] = mTextureList[i]; - } - else if (mNumTEs) - { - new_tes[i] = mTextureList[mNumTEs - 1]; - } - else - { - new_tes[i] = LLTextureEntry(); - } - } - delete[] mTextureList; - mTextureList = new_tes; - } - else - { - delete[] mTextureList; - mTextureList = NULL; - } - - - mNumTEs = num_tes; + mTextureList.setSize(num_tes); } //=============================================================== void LLPrimitive::setAllTETextures(const LLUUID &tex_id) { - U8 i; - - for (i = 0; i < mNumTEs; i++) - { - mTextureList[i].setID(tex_id); - } + mTextureList.setAllIDs(tex_id); } //=============================================================== -void LLPrimitive::setTE(const U8 index, const LLTextureEntry &te) +void LLPrimitive::setTE(const U8 index, const LLTextureEntry& te) { - mTextureList[index] = te; + mTextureList.copyTexture(index, te); } -S32 LLPrimitive::setTETexture(const U8 te, const LLUUID &tex_id) +S32 LLPrimitive::setTETexture(const U8 index, const LLUUID &id) { - // if we're asking for a non-existent face, return null - if (te >= mNumTEs) - { - llwarns << "setting non-existent te " << te << llendl - return 0; - } - - return mTextureList[te].setID(tex_id); + return mTextureList.setID(index, id); } -S32 LLPrimitive::setTEColor(const U8 te, const LLColor4 &color) +S32 LLPrimitive::setTEColor(const U8 index, const LLColor4 &color) { - // if we're asking for a non-existent face, return null - if (te >= mNumTEs) - { - llwarns << "setting non-existent te " << te << llendl - return 0; - } - - return mTextureList[te].setColor(color); + return mTextureList.setColor(index, color); } -S32 LLPrimitive::setTEColor(const U8 te, const LLColor3 &color) +S32 LLPrimitive::setTEColor(const U8 index, const LLColor3 &color) { - // if we're asking for a non-existent face, return null - if (te >= mNumTEs) - { - llwarns << "setting non-existent te " << te << llendl - return 0; - } - - return mTextureList[te].setColor(color); + return mTextureList.setColor(index, color); } -S32 LLPrimitive::setTEAlpha(const U8 te, const F32 alpha) +S32 LLPrimitive::setTEAlpha(const U8 index, const F32 alpha) { - // if we're asking for a non-existent face, return null - if (te >= mNumTEs) - { - llwarns << "setting non-existent te " << te << llendl - return 0; - } - - return mTextureList[te].setAlpha(alpha); + return mTextureList.setAlpha(index, alpha); } //=============================================================== -S32 LLPrimitive::setTEScale(const U8 te, const F32 s, const F32 t) +S32 LLPrimitive::setTEScale(const U8 index, const F32 s, const F32 t) { - // if we're asking for a non-existent face, return null - if (te >= mNumTEs) - { - llwarns << "Setting nonexistent face" << llendl; - return 0; - } - - return mTextureList[te].setScale(s,t); + return mTextureList.setScale(index, s, t); } // BUG: slow - done this way because texture entries have some // voodoo related to texture coords -S32 LLPrimitive::setTEScaleS(const U8 te, const F32 s) +S32 LLPrimitive::setTEScaleS(const U8 index, const F32 s) { - if (te >= mNumTEs) - { - llwarns << "Setting nonexistent face" << llendl; - return 0; - } - - F32 ignore, t; - mTextureList[te].getScale(&ignore, &t); - return mTextureList[te].setScale(s,t); + return mTextureList.setScaleS(index, s); } // BUG: slow - done this way because texture entries have some // voodoo related to texture coords -S32 LLPrimitive::setTEScaleT(const U8 te, const F32 t) +S32 LLPrimitive::setTEScaleT(const U8 index, const F32 t) { - if (te >= mNumTEs) - { - llwarns << "Setting nonexistent face" << llendl; - return 0; - } - - F32 s, ignore; - mTextureList[te].getScale(&s, &ignore); - return mTextureList[te].setScale(s,t); + return mTextureList.setScaleT(index, t); } //=============================================================== -S32 LLPrimitive::setTEOffset(const U8 te, const F32 s, const F32 t) +S32 LLPrimitive::setTEOffset(const U8 index, const F32 s, const F32 t) { - // if we're asking for a non-existent face, return null - if (te >= mNumTEs) - { - llwarns << "Setting nonexistent face" << llendl; - return 0; - } - - return mTextureList[te].setOffset(s,t); + return mTextureList.setOffset(index, s, t); } // BUG: slow - done this way because texture entries have some // voodoo related to texture coords -S32 LLPrimitive::setTEOffsetS(const U8 te, const F32 s) +S32 LLPrimitive::setTEOffsetS(const U8 index, const F32 s) { - if (te >= mNumTEs) - { - llwarns << "Setting nonexistent face" << llendl; - return 0; - } - - F32 ignore, t; - mTextureList[te].getOffset(&ignore, &t); - return mTextureList[te].setOffset(s,t); + return mTextureList.setOffsetS(index, s); } // BUG: slow - done this way because texture entries have some // voodoo related to texture coords -S32 LLPrimitive::setTEOffsetT(const U8 te, const F32 t) +S32 LLPrimitive::setTEOffsetT(const U8 index, const F32 t) { - if (te >= mNumTEs) - { - llwarns << "Setting nonexistent face" << llendl; - return 0; - } - - F32 s, ignore; - mTextureList[te].getOffset(&s, &ignore); - return mTextureList[te].setOffset(s,t); + return mTextureList.setOffsetT(index, t); } //=============================================================== -S32 LLPrimitive::setTERotation(const U8 te, const F32 r) +S32 LLPrimitive::setTERotation(const U8 index, const F32 r) { - // if we're asking for a non-existent face, return null - if (te >= mNumTEs) - { - llwarns << "Setting nonexistent face" << llendl; - return 0; - } - - return mTextureList[te].setRotation(r); + return mTextureList.setRotation(index, r); } //=============================================================== -S32 LLPrimitive::setTEBumpShinyFullbright(const U8 te, const U8 bump) +S32 LLPrimitive::setTEBumpShinyFullbright(const U8 index, const U8 bump) { - // if we're asking for a non-existent face, return null - if (te >= mNumTEs) - { - llwarns << "setting non-existent te " << te << llendl - return 0; - } - - return mTextureList[te].setBumpShinyFullbright( bump ); + return mTextureList.setBumpShinyFullbright(index, bump); } -S32 LLPrimitive::setTEMediaTexGen(const U8 te, const U8 media) +S32 LLPrimitive::setTEMediaTexGen(const U8 index, const U8 media) { - // if we're asking for a non-existent face, return null - if (te >= mNumTEs) - { - llwarns << "setting non-existent te " << te << llendl - return 0; - } - - return mTextureList[te].setMediaTexGen( media ); + return mTextureList.setMediaTexGen(index, media); } -S32 LLPrimitive::setTEBumpmap(const U8 te, const U8 bump) +S32 LLPrimitive::setTEBumpmap(const U8 index, const U8 bump) { - // if we're asking for a non-existent face, return null - if (te >= mNumTEs) - { - llwarns << "setting non-existent te " << te << llendl - return 0; - } - - return mTextureList[te].setBumpmap( bump ); + return mTextureList.setBumpMap(index, bump); } -S32 LLPrimitive::setTEBumpShiny(const U8 te, const U8 bump_shiny) +S32 LLPrimitive::setTEBumpShiny(const U8 index, const U8 bump_shiny) { - // if we're asking for a non-existent face, return null - if (te >= mNumTEs) - { - llwarns << "setting non-existent te " << te << llendl - return 0; - } - - return mTextureList[te].setBumpShiny( bump_shiny ); + return mTextureList.setBumpShiny(index, bump_shiny); } -S32 LLPrimitive::setTETexGen(const U8 te, const U8 texgen) +S32 LLPrimitive::setTETexGen(const U8 index, const U8 texgen) { - // if we're asking for a non-existent face, return null - if (te >= mNumTEs) - { - llwarns << "setting non-existent te " << te << llendl - return 0; - } - - return mTextureList[te].setTexGen( texgen ); + return mTextureList.setTexGen(index, texgen); } -S32 LLPrimitive::setTEShiny(const U8 te, const U8 shiny) +S32 LLPrimitive::setTEShiny(const U8 index, const U8 shiny) { - // if we're asking for a non-existent face, return null - if (te >= mNumTEs) - { - llwarns << "setting non-existent te " << te << llendl - return 0; - } - - return mTextureList[te].setShiny( shiny ); + return mTextureList.setShiny(index, shiny); } -S32 LLPrimitive::setTEFullbright(const U8 te, const U8 fullbright) +S32 LLPrimitive::setTEFullbright(const U8 index, const U8 fullbright) { - // if we're asking for a non-existent face, return null - if (te >= mNumTEs) - { - llwarns << "setting non-existent te " << te << llendl - return 0; - } - - return mTextureList[te].setFullbright( fullbright ); + return mTextureList.setFullbright(index, fullbright); } -S32 LLPrimitive::setTEMediaFlags(const U8 te, const U8 media_flags) +S32 LLPrimitive::setTEMediaFlags(const U8 index, const U8 media_flags) { - // if we're asking for a non-existent face, return null - if (te >= mNumTEs) - { - llwarns << "setting non-existent te " << te << llendl - return 0; - } - - return mTextureList[te].setMediaFlags( media_flags ); + return mTextureList.setMediaFlags(index, media_flags); } -S32 LLPrimitive::setTEGlow(const U8 te, const F32 glow) +S32 LLPrimitive::setTEGlow(const U8 index, const F32 glow) { - // if we're asking for a non-existent face, return null - if (te >= mNumTEs) - { - llwarns << "setting non-existent te " << te << llendl - return 0; - } - - return mTextureList[te].setGlow( glow ); + return mTextureList.setGlow(index, glow); } @@ -760,15 +556,14 @@ U8 LLPrimitive::pCodeToLegacy(const LLPCode pcode) // static // Don't crash or llerrs here! This function is used for debug strings. -const char * LLPrimitive::pCodeToString(const LLPCode pcode) +std::string LLPrimitive::pCodeToString(const LLPCode pcode) { - static char pcode_string[255]; /* Flawfinder: ignore */ + std::string pcode_string; U8 base_code = pcode & LL_PCODE_BASE_MASK; - pcode_string[0] = 0; if (!pcode) { - snprintf(pcode_string, sizeof(pcode_string), "null"); /* Flawfinder: ignore */ + pcode_string = "null"; } else if ((base_code) == LL_PCODE_LEGACY) { @@ -776,66 +571,66 @@ const char * LLPrimitive::pCodeToString(const LLPCode pcode) switch (pcode) { case LL_PCODE_LEGACY_GRASS: - snprintf(pcode_string, sizeof(pcode_string), "grass"); /* Flawfinder: ignore */ + pcode_string = "grass"; break; case LL_PCODE_LEGACY_PART_SYS: - snprintf(pcode_string, sizeof(pcode_string), "particle system"); /* Flawfinder: ignore */ + pcode_string = "particle system"; break; case LL_PCODE_LEGACY_AVATAR: - snprintf(pcode_string, sizeof(pcode_string), "avatar"); /* Flawfinder: ignore */ + pcode_string = "avatar"; break; case LL_PCODE_LEGACY_TEXT_BUBBLE: - snprintf(pcode_string, sizeof(pcode_string), "text bubble"); /* Flawfinder: ignore */ + pcode_string = "text bubble"; break; case LL_PCODE_LEGACY_TREE: - snprintf(pcode_string, sizeof(pcode_string), "tree"); /* Flawfinder: ignore */ + pcode_string = "tree"; break; case LL_PCODE_TREE_NEW: - snprintf(pcode_string, sizeof(pcode_string), "tree_new"); /* Flawfinder: ignore */ + pcode_string = "tree_new"; break; default: - snprintf(pcode_string, sizeof(pcode_string), "unknown legacy pcode %i",(U32)pcode); /* Flawfinder: ignore */ + pcode_string = llformat( "unknown legacy pcode %i",(U32)pcode); } } else { - char shape[32]; /* Flawfinder: ignore */ - char mask[32]; /* Flawfinder: ignore */ + std::string shape; + std::string mask; if (base_code == LL_PCODE_CUBE) { - snprintf(shape, sizeof(shape), "cube"); /* Flawfinder: ignore */ + shape = "cube"; } else if (base_code == LL_PCODE_CYLINDER) { - snprintf(shape, sizeof(shape), "cylinder"); /* Flawfinder: ignore */ + shape = "cylinder"; } else if (base_code == LL_PCODE_CONE) { - snprintf(shape, sizeof(shape), "cone"); /* Flawfinder: ignore */ + shape = "cone"; } else if (base_code == LL_PCODE_PRISM) { - snprintf(shape, sizeof(shape), "prism"); /* Flawfinder: ignore */ + shape = "prism"; } else if (base_code == LL_PCODE_PYRAMID) { - snprintf(shape, sizeof(shape), "pyramid"); /* Flawfinder: ignore */ + shape = "pyramid"; } else if (base_code == LL_PCODE_SPHERE) { - snprintf(shape, sizeof(shape), "sphere"); /* Flawfinder: ignore */ + shape = "sphere"; } else if (base_code == LL_PCODE_TETRAHEDRON) { - snprintf(shape, sizeof(shape), "tetrahedron"); /* Flawfinder: ignore */ + shape = "tetrahedron"; } else if (base_code == LL_PCODE_VOLUME) { - snprintf(shape, sizeof(shape), "volume"); /* Flawfinder: ignore */ + shape = "volume"; } else if (base_code == LL_PCODE_APP) { - snprintf(shape, sizeof(shape), "app"); /* Flawfinder: ignore */ + shape = "app"; } else { @@ -845,35 +640,27 @@ const char * LLPrimitive::pCodeToString(const LLPCode pcode) U8 mask_code = pcode & (~LL_PCODE_BASE_MASK); if (base_code == LL_PCODE_APP) { - snprintf(mask, sizeof(mask), "%x", mask_code); /* Flawfinder: ignore */ + mask = llformat( "%x", mask_code); } else if (mask_code & LL_PCODE_HEMI_MASK) { - snprintf(mask, sizeof(mask), "hemi"); /* Flawfinder: ignore */ + mask = "hemi"; } else { - snprintf(mask, sizeof(mask), "%x", mask_code); /* Flawfinder: ignore */ + mask = llformat( "%x", mask_code); } - // extra sanity against snprintf() being naturally crap - mask[sizeof(mask)-1] = '\0'; - shape[sizeof(shape)-1] = '\0'; - if (mask[0]) { - snprintf(pcode_string, sizeof(pcode_string), "%s-%s", shape, mask); /* Flawfinder: ignore */ + pcode_string = llformat( "%s-%s", shape.c_str(), mask.c_str()); } else { - snprintf(pcode_string, sizeof(pcode_string), "%s", shape); /* Flawfinder: ignore */ + pcode_string = llformat( "%s", shape.c_str()); } } - // Be really sure that pcode_string is nul-terminated after we've - // been using crappy snprintf() to build it. - pcode_string[sizeof(pcode_string)-1] = '\0'; - return pcode_string; } @@ -881,25 +668,18 @@ const char * LLPrimitive::pCodeToString(const LLPCode pcode) void LLPrimitive::copyTEs(const LLPrimitive *primitivep) { U32 i; - if (primitivep->getNumTEs() != getNumTEs()) + if (primitivep->getExpectedNumTEs() != getExpectedNumTEs()) { - llwarns << "Primitives don't have same number of TE's" << llendl; + llwarns << "Primitives don't have same expected number of TE's" << llendl; + } + U32 num_tes = llmin(primitivep->getExpectedNumTEs(), getExpectedNumTEs()); + if (mTextureList.size() < getExpectedNumTEs()) + { + mTextureList.setSize(getExpectedNumTEs()); } - U32 num_tes = llmin(primitivep->getNumTEs(), getNumTEs()); for (i = 0; i < num_tes; i++) { - const LLTextureEntry *tep = primitivep->getTE(i); - F32 s, t; - setTETexture(i, tep->getID()); - setTEColor(i, tep->getColor()); - tep->getScale(&s, &t); - setTEScale(i, s, t); - tep->getOffset(&s, &t); - setTEOffset(i, s, t); - setTERotation(i, tep->getRotation()); - setTEBumpShinyFullbright(i, tep->getBumpShinyFullbright()); - setTEMediaTexGen(i, tep->getMediaTexGen()); - setTEGlow(i, tep->getGlow()); + mTextureList.copyTexture(i, *(primitivep->getTE(i))); } } @@ -964,22 +744,31 @@ BOOL LLPrimitive::setVolume(const LLVolumeParams &volume_params, const S32 detai S32 face_bit = 0; S32 cur_mask = 0; - // grab copies of the old faces so we can determine the TE mappings... - std::vector<LLProfile::Face> old_faces; // list of old faces for remapping texture entries - LLTextureEntry old_tes[9]; - + // Grab copies of the old faces from the original shape, ordered by type. + // We will use these to figure out what old texture info gets mapped to new + // faces in the new shape. + std::vector<LLProfile::Face> old_faces; for (S32 face = 0; face < mVolumep->getNumFaces(); face++) { old_faces.push_back(mVolumep->getProfile().mFaces[face]); } + // Copy the old texture info off to the side, but not in the order in which + // they live in the mTextureList, rather in order of ther "face id" which + // is the corresponding value of LLVolueParams::LLProfile::mFaces::mIndex. + // + // Hence, some elements of old_tes::mEntryList will be invalid. It is + // initialized to a size of 9 (max number of possible faces on a volume?) + // and only the ones with valid types are filled in. + LLPrimTextureList old_tes; + old_tes.setSize(9); for (face_bit = 0; face_bit < 9; face_bit++) { cur_mask = 0x1 << face_bit; if (old_face_mask & cur_mask) { S32 te_index = face_index_from_id(cur_mask, old_faces); - old_tes[face_bit] = *getTE(te_index); + old_tes.copyTexture(face_bit, *(getTE(te_index))); //llinfos << face_bit << ":" << te_index << ":" << old_tes[face_bit].getID() << llendl; } } @@ -992,37 +781,6 @@ BOOL LLPrimitive::setVolume(const LLVolumeParams &volume_params, const S32 detai U32 new_face_mask = mVolumep->mFaceMask; S32 i; - /* - LLString old_mask_string; - for (i = 0; i < 9; i++) - { - if (old_face_mask & (1 << i)) - { - old_mask_string.append("1"); - } - else - { - old_mask_string.append("0"); - } - } - LLString new_mask_string; - for (i = 0; i < 9; i++) - { - if (new_face_mask & (1 << i)) - { - new_mask_string.append("1"); - } - else - { - new_mask_string.append("0"); - } - } - - llinfos << "old mask: " << old_mask_string << llendl; - llinfos << "new mask: " << new_mask_string << llendl; - */ - - if (old_face_mask == new_face_mask) { // nothing to do @@ -1036,14 +794,19 @@ BOOL LLPrimitive::setVolume(const LLVolumeParams &volume_params, const S32 detai return TRUE; } - + // initialize face_mapping S32 face_mapping[9]; for (face_bit = 0; face_bit < 9; face_bit++) { face_mapping[face_bit] = face_bit; } - // Generate the face-type mappings + // The new shape may have more faces than the original, but we can't just + // add them to the end -- the ordering matters and it may be that we must + // insert the new faces in the middle of the list. When we add a face it + // will pick up the texture/color info of one of the old faces an so we + // now figure out which old face info gets mapped to each new face, and + // store in the face_mapping lookup table. for (face_bit = 0; face_bit < 9; face_bit++) { cur_mask = 0x1 << face_bit; @@ -1151,11 +914,16 @@ BOOL LLPrimitive::setVolume(const LLVolumeParams &volume_params, const S32 detai } face_mapping[face_bit] = min_outer_bit; } - + setNumTEs(mVolumep->getNumFaces()); for (face_bit = 0; face_bit < 9; face_bit++) { + // For each possible face type on the new shape we check to see if that + // face exists and if it does we create a texture entry that is a copy + // of one of the originals. Since the originals might not have a + // matching face, we use the face_mapping lookup table to figure out + // which face information to copy. cur_mask = 0x1 << face_bit; if (new_face_mask & cur_mask) { @@ -1165,7 +933,7 @@ BOOL LLPrimitive::setVolume(const LLVolumeParams &volume_params, const S32 detai } S32 te_num = face_index_from_id(cur_mask, mVolumep->getProfile().mFaces); - setTE(te_num, old_tes[face_mapping[face_bit]]); + setTE(te_num, *(old_tes.getTexture(face_mapping[face_bit]))); } } return TRUE; @@ -1184,50 +952,6 @@ BOOL LLPrimitive::setMaterial(U8 material) } } -void LLPrimitive::setTEArrays(const U8 size, - const LLUUID* image_ids, - const F32* scale_s, - const F32* scale_t) -{ - S32 cur_size = size; - if (cur_size > getNumTEs()) - { - llwarns << "Trying to set more TEs than exist!" << llendl; - cur_size = getNumTEs(); - } - - S32 i; - // Copy over image information - for (i = 0; i < cur_size; i++) - { - // This is very BAD!!!!!! - if (image_ids != NULL) - { - setTETexture(i,image_ids[i]); - } - if (scale_s && scale_t) - { - setTEScale(i, scale_s[i], scale_t[i]); - } - } - - if (i < getNumTEs()) - { - cur_size--; - for (i=i; i < getNumTEs(); i++) // the i=i removes a gcc warning - { - if (image_ids != NULL) - { - setTETexture(i, image_ids[cur_size]); - } - if (scale_s && scale_t) - { - setTEScale(i, scale_s[cur_size], scale_t[cur_size]); - } - } - } -} - const F32 LL_MAX_SCALE_S = 100.0f; const F32 LL_MAX_SCALE_T = 100.0f; S32 LLPrimitive::packTEField(U8 *cur_ptr, U8 *data_ptr, U8 data_size, U8 last_face_index, EMsgVariableType type) const @@ -1382,7 +1106,7 @@ BOOL LLPrimitive::packTEMessage(LLMessageSystem *mesgsys) const scale_t[face_index] = (F32) te->mScaleT; offset_s[face_index] = (S16) llround((llclamp(te->mOffsetS,-1.0f,1.0f) * (F32)0x7FFF)) ; offset_t[face_index] = (S16) llround((llclamp(te->mOffsetT,-1.0f,1.0f) * (F32)0x7FFF)) ; - image_rot[face_index] = (S16) llround(((fmod(te->mRotation, F_TWO_PI)/F_TWO_PI) * (F32)0x7FFF)); + image_rot[face_index] = (S16) llround(((fmod(te->mRotation, F_TWO_PI)/F_TWO_PI) * TEXTURE_ROTATION_PACK_FACTOR)); bump[face_index] = te->getBumpShinyFullbright(); media_flags[face_index] = te->getMediaTexGen(); glow[face_index] = (U8) llround((llclamp(te->getGlow(), 0.0f, 1.0f) * (F32)0xFF)); @@ -1461,7 +1185,7 @@ BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const scale_t[face_index] = (F32) te->mScaleT; offset_s[face_index] = (S16) llround((llclamp(te->mOffsetS,-1.0f,1.0f) * (F32)0x7FFF)) ; offset_t[face_index] = (S16) llround((llclamp(te->mOffsetT,-1.0f,1.0f) * (F32)0x7FFF)) ; - image_rot[face_index] = (S16) llround(((fmod(te->mRotation, F_TWO_PI)/F_TWO_PI) * (F32)0x7FFF)); + image_rot[face_index] = (S16) llround(((fmod(te->mRotation, F_TWO_PI)/F_TWO_PI) * TEXTURE_ROTATION_PACK_FACTOR)); bump[face_index] = te->getBumpShinyFullbright(); media_flags[face_index] = te->getMediaTexGen(); glow[face_index] = (U8) llround((llclamp(te->getGlow(), 0.0f, 1.0f) * (F32)0xFF)); @@ -1575,7 +1299,7 @@ S32 LLPrimitive::unpackTEMessage(LLMessageSystem *mesgsys, char *block_name, con retval |= setTETexture(i, ((LLUUID*)image_data)[i]); retval |= setTEScale(i, scale_s[i], scale_t[i]); retval |= setTEOffset(i, (F32)offset_s[i] / (F32)0x7FFF, (F32) offset_t[i] / (F32) 0x7FFF); - retval |= setTERotation(i, ((F32)image_rot[i]/ (F32)0x7FFF) * F_TWO_PI); + retval |= setTERotation(i, ((F32)image_rot[i] / TEXTURE_ROTATION_PACK_FACTOR) * F_TWO_PI); retval |= setTEBumpShinyFullbright(i, bump[i]); retval |= setTEMediaTexGen(i, media_flags[i]); retval |= setTEGlow(i, (F32)glow[i] / (F32)0xFF); @@ -1590,6 +1314,7 @@ S32 LLPrimitive::unpackTEMessage(LLMessageSystem *mesgsys, char *block_name, con color.mV[VALPHA] = F32(255 - coloru.mV[VALPHA]) / 255.f; retval |= setTEColor(i, color); + } return retval; @@ -1669,7 +1394,7 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp) retval |= setTETexture(i, image_ids[i]); retval |= setTEScale(i, scale_s[i], scale_t[i]); retval |= setTEOffset(i, (F32)offset_s[i] / (F32)0x7FFF, (F32) offset_t[i] / (F32) 0x7FFF); - retval |= setTERotation(i, ((F32)image_rot[i]/ (F32)0x7FFF) * F_TWO_PI); + retval |= setTERotation(i, ((F32)image_rot[i] / TEXTURE_ROTATION_PACK_FACTOR) * F_TWO_PI); retval |= setTEBumpShinyFullbright(i, bump[i]); retval |= setTEMediaTexGen(i, media_flags[i]); retval |= setTEGlow(i, (F32)glow[i] / (F32)0xFF); @@ -1689,11 +1414,24 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp) return retval; } -void LLPrimitive::setTextureList(LLTextureEntry *listp) +U8 LLPrimitive::getExpectedNumTEs() const +{ + U8 expected_face_count = 0; + if (mVolumep) + { + expected_face_count = mVolumep->getNumFaces(); + } + return expected_face_count; +} + +void LLPrimitive::copyTextureList(const LLPrimTextureList& other_list) +{ + mTextureList.copy(other_list); +} + +void LLPrimitive::takeTextureList(LLPrimTextureList& other_list) { - LLTextureEntry* old_texture_list = mTextureList; - mTextureList = listp; - delete[] old_texture_list; + mTextureList.take(other_list); } //============================================================================ @@ -1757,6 +1495,8 @@ BOOL LLNetworkData::isValid(U16 param_type, U32 size) return (size == 16); case PARAMS_SCULPT: return (size == 17); + case PARAMS_LIGHT_IMAGE: + return (size == 28); } return FALSE; @@ -2089,3 +1829,78 @@ bool LLSculptParams::fromLLSD(LLSD& sd) return false; } +//============================================================================ + +LLLightImageParams::LLLightImageParams() +{ + mType = PARAMS_LIGHT_IMAGE; + mParams.setVec(F_PI*0.5f, 0.f, 0.f); +} + +BOOL LLLightImageParams::pack(LLDataPacker &dp) const +{ + dp.packUUID(mLightTexture, "texture"); + dp.packVector3(mParams, "params"); + + return TRUE; +} + +BOOL LLLightImageParams::unpack(LLDataPacker &dp) +{ + dp.unpackUUID(mLightTexture, "texture"); + dp.unpackVector3(mParams, "params"); + + return TRUE; +} + +bool LLLightImageParams::operator==(const LLNetworkData& data) const +{ + if (data.mType != PARAMS_LIGHT_IMAGE) + { + return false; + } + + const LLLightImageParams *param = (const LLLightImageParams*)&data; + if ( (param->mLightTexture != mLightTexture) ) + { + return false; + } + + if ( (param->mParams != mParams ) ) + { + return false; + } + + return true; +} + +void LLLightImageParams::copy(const LLNetworkData& data) +{ + const LLLightImageParams *param = (LLLightImageParams*)&data; + mLightTexture = param->mLightTexture; + mParams = param->mParams; +} + + + +LLSD LLLightImageParams::asLLSD() const +{ + LLSD sd; + + sd["texture"] = mLightTexture; + sd["params"] = mParams.getValue(); + + return sd; +} + +bool LLLightImageParams::fromLLSD(LLSD& sd) +{ + if (sd.has("texture")) + { + setLightTexture( sd["texture"] ); + setParams( LLVector3( sd["params"] ) ); + return true; + } + + return false; +} diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h index 2b738f8d29..f535fb1672 100644 --- a/indra/llprimitive/llprimitive.h +++ b/indra/llprimitive/llprimitive.h @@ -2,30 +2,25 @@ * @file llprimitive.h * @brief LLPrimitive base class * - * $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$ */ @@ -36,9 +31,10 @@ #include "v3math.h" #include "xform.h" #include "message.h" -#include "llmemory.h" +#include "llpointer.h" #include "llvolume.h" #include "lltextureentry.h" +#include "llprimtexturelist.h" // Moved to stdtypes.h --JC // typedef U8 LLPCode; @@ -105,7 +101,8 @@ public: { PARAMS_FLEXIBLE = 0x10, PARAMS_LIGHT = 0x20, - PARAMS_SCULPT = 0x30 + PARAMS_SCULPT = 0x30, + PARAMS_LIGHT_IMAGE = 0x40, }; public: @@ -260,11 +257,34 @@ public: bool fromLLSD(LLSD& sd); void setSculptTexture(const LLUUID& id) { mSculptTexture = id; } - LLUUID getSculptTexture() { return mSculptTexture; } + LLUUID getSculptTexture() const { return mSculptTexture; } void setSculptType(U8 type) { mSculptType = type; } - U8 getSculptType() { return mSculptType; } + U8 getSculptType() const { return mSculptType; } }; +class LLLightImageParams : public LLNetworkData +{ +protected: + LLUUID mLightTexture; + LLVector3 mParams; + +public: + LLLightImageParams(); + /*virtual*/ BOOL pack(LLDataPacker &dp) const; + /*virtual*/ BOOL unpack(LLDataPacker &dp); + /*virtual*/ bool operator==(const LLNetworkData& data) const; + /*virtual*/ void copy(const LLNetworkData& data); + LLSD asLLSD() const; + operator LLSD() const { return asLLSD(); } + bool fromLLSD(LLSD& sd); + + void setLightTexture(const LLUUID& id) { mLightTexture = id; } + LLUUID getLightTexture() const { return mLightTexture; } + bool isLightSpotlight() const { return mLightTexture.notNull(); } + void setParams(const LLVector3& params) { mParams = params; } + LLVector3 getParams() const { return mParams; } + +}; class LLPrimitive : public LLXform @@ -294,6 +314,8 @@ public: LLPrimitive(); virtual ~LLPrimitive(); + void clearTextureList(); + static LLPrimitive *createPrimitive(LLPCode p_code); void init_primitive(LLPCode p_code); @@ -304,11 +326,11 @@ public: // Modify texture entry properties inline BOOL validTE(const U8 te_num) const; - const LLTextureEntry *getTE(const U8 te_num) const; + LLTextureEntry* getTE(const U8 te_num) const; virtual void setNumTEs(const U8 num_tes); virtual void setAllTETextures(const LLUUID &tex_id); - virtual void setTE(const U8 index, const LLTextureEntry &te); + virtual void setTE(const U8 index, const LLTextureEntry& te); virtual S32 setTEColor(const U8 te, const LLColor4 &color); virtual S32 setTEColor(const U8 te, const LLColor3 &color); virtual S32 setTEAlpha(const U8 te, const F32 alpha); @@ -331,10 +353,6 @@ public: virtual S32 setTEGlow(const U8 te, const F32 glow); virtual BOOL setMaterial(const U8 material); // returns TRUE if material changed - void setTEArrays(const U8 size, - const LLUUID* image_ids, - const F32* scale_s, - const F32* scale_t); void copyTEs(const LLPrimitive *primitive); S32 packTEField(U8 *cur_ptr, U8 *data_ptr, U8 data_size, U8 last_face_index, EMsgVariableType type) const; S32 unpackTEField(U8 *cur_ptr, U8 *buffer_end, U8 *data_ptr, U8 data_size, U8 face_count, EMsgVariableType type); @@ -378,18 +396,25 @@ public: #endif LLPCode getPCode() const { return mPrimitiveCode; } - const char * getPCodeString() const { return pCodeToString(mPrimitiveCode); } + std::string getPCodeString() const { return pCodeToString(mPrimitiveCode); } const LLVector3& getAngularVelocity() const { return mAngularVelocity; } const LLVector3& getVelocity() const { return mVelocity; } const LLVector3& getAcceleration() const { return mAcceleration; } - U8 getNumTEs() const { return mNumTEs; } + U8 getNumTEs() const { return mTextureList.size(); } + U8 getExpectedNumTEs() const; U8 getMaterial() const { return mMaterial; } void setVolumeType(const U8 code); U8 getVolumeType(); - void setTextureList(LLTextureEntry *listp); + // clears existing textures + // copies the contents of other_list into mEntryList + void copyTextureList(const LLPrimTextureList& other_list); + + // clears existing textures + // takes the contents of other_list and clears other_list + void takeTextureList(LLPrimTextureList& other_list); inline BOOL isAvatar() const; inline BOOL isSittingAvatar() const; @@ -400,7 +425,7 @@ public: void removeFlags(U32 flags) { mMiscFlags &= ~flags; } U32 getFlags() const { return mMiscFlags; } - static const char *pCodeToString(const LLPCode pcode); + static std::string pCodeToString(const LLPCode pcode); static LLPCode legacyToPCode(const U8 legacy); static U8 pCodeToLegacy(const LLPCode pcode); static bool getTESTAxes(const U8 face, U32* s_axis, U32* t_axis); @@ -414,7 +439,7 @@ protected: LLVector3 mAcceleration; // are we under constant acceleration? LLVector3 mAngularVelocity; // angular velocity LLPointer<LLVolume> mVolumep; - LLTextureEntry *mTextureList; // list of texture GUIDs, scales, offsets + LLPrimTextureList mTextureList; // list of texture GUIDs, scales, offsets U8 mMaterial; // Material code U8 mNumTEs; // # of faces on the primitve U32 mMiscFlags; // home for misc bools diff --git a/indra/llprimitive/llprimlinkinfo.h b/indra/llprimitive/llprimlinkinfo.h index 139617f969..82c50cfe2f 100644 --- a/indra/llprimitive/llprimlinkinfo.h +++ b/indra/llprimitive/llprimlinkinfo.h @@ -3,8 +3,26 @@ * @author andrew@lindenlab.com * @brief A template for determining which prims in a set are linkable * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ + * $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$ */ @@ -26,7 +44,7 @@ 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 = 255; +const S32 MAX_PRIMS_PER_OBJECT = 256; template < typename DATA_TYPE > diff --git a/indra/llprimitive/llprimtexturelist.cpp b/indra/llprimitive/llprimtexturelist.cpp new file mode 100644 index 0000000000..36e04df7b7 --- /dev/null +++ b/indra/llprimitive/llprimtexturelist.cpp @@ -0,0 +1,418 @@ +/** + * @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$ + */ + +#include "linden_common.h" + +#include "llprimtexturelist.h" +#include "lltextureentry.h" +#include "llmemtype.h" + +// 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); + } +} + +// static +// call this to get a new texture entry +LLTextureEntry* LLPrimTextureList::newTextureEntry() +{ + return (*sNewTextureEntryCallback)(); +} + +LLPrimTextureList::LLPrimTextureList() +{ +} + +// virtual +LLPrimTextureList::~LLPrimTextureList() +{ + clear(); +} + +void LLPrimTextureList::clear() +{ + texture_list_t::iterator itr = mEntryList.begin(); + while (itr != mEntryList.end()) + { + delete (*itr); + (*itr) = NULL; + ++itr; + } + mEntryList.clear(); +} + + +// clears current entries +// copies contents of other_list +// 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() ); + } +} + +// clears current copies +// takes contents of other_list +// clears other_list +void LLPrimTextureList::take(LLPrimTextureList& other_list) +{ + clear(); + mEntryList = other_list.mEntryList; + other_list.mEntryList.clear(); +} + +// 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(); + llwarns << "ignore copy of index = " << S32(index) << " into texture entry list of size = " << current_size << llendl; + 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; + } + + // 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; +} + +//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; +} + +S32 LLPrimTextureList::setColor(const U8 index, const LLColor3& color) +{ + 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; +} + +S32 LLPrimTextureList::setAlpha(const U8 index, const F32 alpha) +{ + 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; +} + +S32 LLPrimTextureList::setScaleS(const U8 index, const F32 s) +{ + 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; +} + +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; +} + +S32 LLPrimTextureList::setOffsetS(const U8 index, const F32 s) +{ + 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; +} + +S32 LLPrimTextureList::setRotation(const U8 index, const F32 r) +{ + 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; +} + +S32 LLPrimTextureList::setMediaTexGen(const U8 index, const U8 media) +{ + 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; +} + +S32 LLPrimTextureList::setBumpShiny(const U8 index, const U8 bump_shiny) +{ + 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; +} + +S32 LLPrimTextureList::setShiny(const U8 index, const U8 shiny) +{ + 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; +} + +S32 LLPrimTextureList::setMediaFlags(const U8 index, const U8 media_flags) +{ + 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; +} + +S32 LLPrimTextureList::size() const +{ + return mEntryList.size(); +} + +// sets the size of the mEntryList container +void LLPrimTextureList::setSize(S32 new_size) +{ + LLMemType m1(LLMemType::MTYPE_PRIMITIVE); + 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; + } +} + + diff --git a/indra/llprimitive/llprimtexturelist.h b/indra/llprimitive/llprimtexturelist.h new file mode 100644 index 0000000000..3cfa52f1d5 --- /dev/null +++ b/indra/llprimitive/llprimtexturelist.h @@ -0,0 +1,121 @@ +/** + * @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$ + */ + +#ifndef LL_LLPRIMTEXTURELIST_H +#define LL_LLPRIMTEXTURELIST_H + +#include <vector> +#include "lluuid.h" +#include "v3color.h" +#include "v4color.h" + + +class LLTextureEntry; + +// this is a list of LLTextureEntry*'s because in practice the list's elements +// are of some derived class: LLFooTextureEntry +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 size() const; + +// void forceResize(S32 new_size); + void setSize(S32 new_size); + + void setAllIDs(const LLUUID& id); +protected: + texture_list_t mEntryList; +private: + 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 b15e5a84f0..398af4e6e8 100644 --- a/indra/llprimitive/lltextureanim.cpp +++ b/indra/llprimitive/lltextureanim.cpp @@ -2,30 +2,25 @@ * @file lltextureanim.cpp * @brief LLTextureAnim base class * - * $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$ */ diff --git a/indra/llprimitive/lltextureanim.h b/indra/llprimitive/lltextureanim.h index 32e66da5fe..f0d9f9df5c 100644 --- a/indra/llprimitive/lltextureanim.h +++ b/indra/llprimitive/lltextureanim.h @@ -2,30 +2,25 @@ * @file lltextureanim.h * @brief LLTextureAnim base class * - * $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$ */ diff --git a/indra/llprimitive/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp index 837f8ef361..3c1d031ff5 100644 --- a/indra/llprimitive/lltextureentry.cpp +++ b/indra/llprimitive/lltextureentry.cpp @@ -2,54 +2,76 @@ * @file lltextureentry.cpp * @brief LLTextureEntry base class * - * $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$ */ #include "linden_common.h" +#include "lluuid.h" +#include "llmediaentry.h" #include "lltextureentry.h" -#include "llsdutil.h" +#include "llsdutil_math.h" +#include "v4color.h" const U8 DEFAULT_BUMP_CODE = 0; // no bump or shininess const LLTextureEntry LLTextureEntry::null; +// Some LLSD keys. Do not change these! +#define OBJECT_ID_KEY_STR "object_id" +#define TEXTURE_INDEX_KEY_STR "texture_index" +#define OBJECT_MEDIA_VERSION_KEY_STR "object_media_version" +#define OBJECT_MEDIA_DATA_KEY_STR "object_media_data" +#define TEXTURE_MEDIA_DATA_KEY_STR "media_data" + +/*static*/ const char* LLTextureEntry::OBJECT_ID_KEY = OBJECT_ID_KEY_STR; +/*static*/ const char* LLTextureEntry::OBJECT_MEDIA_DATA_KEY = OBJECT_MEDIA_DATA_KEY_STR; +/*static*/ const char* LLTextureEntry::MEDIA_VERSION_KEY = OBJECT_MEDIA_VERSION_KEY_STR; +/*static*/ const char* LLTextureEntry::TEXTURE_INDEX_KEY = TEXTURE_INDEX_KEY_STR; +/*static*/ const char* LLTextureEntry::TEXTURE_MEDIA_DATA_KEY = TEXTURE_MEDIA_DATA_KEY_STR; + +static const std::string MEDIA_VERSION_STRING_PREFIX = "x-mv:"; + +// static +LLTextureEntry* LLTextureEntry::newTextureEntry() +{ + return new LLTextureEntry(); +} + //=============================================================== LLTextureEntry::LLTextureEntry() + : mMediaEntry(NULL) { init(LLUUID::null,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE); } LLTextureEntry::LLTextureEntry(const LLUUID& tex_id) + : mMediaEntry(NULL) { init(tex_id,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE); } LLTextureEntry::LLTextureEntry(const LLTextureEntry &rhs) + : mMediaEntry(NULL) { mID = rhs.mID; mScaleS = rhs.mScaleS; @@ -61,6 +83,10 @@ LLTextureEntry::LLTextureEntry(const LLTextureEntry &rhs) mBump = rhs.mBump; mMediaFlags = rhs.mMediaFlags; mGlow = rhs.mGlow; + if (rhs.mMediaEntry != NULL) { + // Make a copy + mMediaEntry = new LLMediaEntry(*rhs.mMediaEntry); + } } LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs) @@ -77,6 +103,16 @@ LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs) mBump = rhs.mBump; mMediaFlags = rhs.mMediaFlags; mGlow = rhs.mGlow; + if (mMediaEntry != NULL) { + delete mMediaEntry; + } + if (rhs.mMediaEntry != NULL) { + // Make a copy + mMediaEntry = new LLMediaEntry(*rhs.mMediaEntry); + } + else { + mMediaEntry = NULL; + } } return *this; @@ -96,10 +132,19 @@ void LLTextureEntry::init(const LLUUID& tex_id, F32 scale_s, F32 scale_t, F32 of mGlow = 0; setColor(LLColor4(1.f, 1.f, 1.f, 1.f)); + if (mMediaEntry != NULL) { + delete mMediaEntry; + } + mMediaEntry = NULL; } LLTextureEntry::~LLTextureEntry() { + if(mMediaEntry) + { + delete mMediaEntry; + mMediaEntry = NULL; + } } bool LLTextureEntry::operator!=(const LLTextureEntry &rhs) const @@ -135,23 +180,33 @@ bool LLTextureEntry::operator==(const LLTextureEntry &rhs) const LLSD LLTextureEntry::asLLSD() const { LLSD sd; + asLLSD(sd); + return sd; +} - sd["imageid"] = getID(); - sd["colors"] = ll_sd_from_color4(getColor()); +void LLTextureEntry::asLLSD(LLSD& sd) const +{ + sd["imageid"] = mID; + sd["colors"] = ll_sd_from_color4(mColor); sd["scales"] = mScaleS; sd["scalet"] = mScaleT; sd["offsets"] = mOffsetS; sd["offsett"] = mOffsetT; - sd["imagerot"] = getRotation(); + sd["imagerot"] = mRotation; sd["bump"] = getBumpShiny(); sd["fullbright"] = getFullbright(); - sd["media_flags"] = getMediaTexGen(); - sd["glow"] = getGlow(); - - return sd; + sd["media_flags"] = mMediaFlags; + if (hasMedia()) { + LLSD mediaData; + if (NULL != getMediaData()) { + getMediaData()->asLLSD(mediaData); + } + sd[TEXTURE_MEDIA_DATA_KEY] = mediaData; + } + sd["glow"] = mGlow; } -bool LLTextureEntry::fromLLSD(LLSD& sd) +bool LLTextureEntry::fromLLSD(const LLSD& sd) { const char *w, *x; w = "imageid"; @@ -196,6 +251,17 @@ bool LLTextureEntry::fromLLSD(LLSD& sd) { setMediaTexGen( sd[w].asInteger() ); } else goto fail; + // If the "has media" flag doesn't match the fact that + // media data exists, updateMediaData will "fix" it + // by either clearing or setting the flag + w = TEXTURE_MEDIA_DATA_KEY; + if (hasMedia() != sd.has(w)) + { + llwarns << "LLTextureEntry::fromLLSD: media_flags (" << hasMedia() << + ") does not match presence of media_data (" << sd.has(w) << "). Fixing." << llendl; + } + updateMediaData(sd[w]); + w = "glow"; if (sd.has(w)) { @@ -207,6 +273,19 @@ fail: return false; } +// virtual +// override this method for each derived class +LLTextureEntry* LLTextureEntry::newBlank() const +{ + return new LLTextureEntry(); +} + +// virtual +LLTextureEntry* LLTextureEntry::newCopy() const +{ + return new LLTextureEntry(*this); +} + S32 LLTextureEntry::setID(const LLUUID &tex_id) { if (mID != tex_id) @@ -214,7 +293,7 @@ S32 LLTextureEntry::setID(const LLUUID &tex_id) mID = tex_id; return TEM_CHANGE_TEXTURE; } - return 0; + return TEM_CHANGE_NONE; } S32 LLTextureEntry::setScale(F32 s, F32 t) @@ -232,6 +311,28 @@ S32 LLTextureEntry::setScale(F32 s, F32 t) return retval; } +S32 LLTextureEntry::setScaleS(F32 s) +{ + S32 retval = TEM_CHANGE_NONE; + if (mScaleS != s) + { + mScaleS = s; + retval = TEM_CHANGE_TEXTURE; + } + return retval; +} + +S32 LLTextureEntry::setScaleT(F32 t) +{ + S32 retval = TEM_CHANGE_NONE; + if (mScaleT != t) + { + mScaleT = t; + retval = TEM_CHANGE_TEXTURE; + } + return retval; +} + S32 LLTextureEntry::setColor(const LLColor4 &color) { if (mColor != color) @@ -239,7 +340,7 @@ S32 LLTextureEntry::setColor(const LLColor4 &color) mColor = color; return TEM_CHANGE_COLOR; } - return 0; + return TEM_CHANGE_NONE; } S32 LLTextureEntry::setColor(const LLColor3 &color) @@ -250,7 +351,7 @@ S32 LLTextureEntry::setColor(const LLColor3 &color) mColor.setVec(color); return TEM_CHANGE_COLOR; } - return 0; + return TEM_CHANGE_NONE; } S32 LLTextureEntry::setAlpha(const F32 alpha) @@ -260,7 +361,7 @@ S32 LLTextureEntry::setAlpha(const F32 alpha) mColor.mV[VW] = alpha; return TEM_CHANGE_COLOR; } - return 0; + return TEM_CHANGE_NONE; } S32 LLTextureEntry::setOffset(F32 s, F32 t) @@ -278,6 +379,28 @@ S32 LLTextureEntry::setOffset(F32 s, F32 t) return retval; } +S32 LLTextureEntry::setOffsetS(F32 s) +{ + S32 retval = 0; + if (mOffsetS != s) + { + mOffsetS = s; + retval = TEM_CHANGE_TEXTURE; + } + return retval; +} + +S32 LLTextureEntry::setOffsetT(F32 t) +{ + S32 retval = 0; + if (mOffsetT != t) + { + mOffsetT = t; + retval = TEM_CHANGE_TEXTURE; + } + return retval; +} + S32 LLTextureEntry::setRotation(F32 theta) { if (mRotation != theta) @@ -285,7 +408,7 @@ S32 LLTextureEntry::setRotation(F32 theta) mRotation = theta; return TEM_CHANGE_TEXTURE; } - return 0; + return TEM_CHANGE_NONE; } S32 LLTextureEntry::setBumpShinyFullbright(U8 bump) @@ -295,7 +418,7 @@ S32 LLTextureEntry::setBumpShinyFullbright(U8 bump) mBump = bump; return TEM_CHANGE_TEXTURE; } - return 0; + return TEM_CHANGE_NONE; } S32 LLTextureEntry::setMediaTexGen(U8 media) @@ -303,9 +426,21 @@ S32 LLTextureEntry::setMediaTexGen(U8 media) if (mMediaFlags != media) { mMediaFlags = media; - return TEM_CHANGE_TEXTURE; + + // Special code for media handling + if( hasMedia() && mMediaEntry == NULL) + { + mMediaEntry = new LLMediaEntry; + } + else if ( ! hasMedia() && mMediaEntry != NULL) + { + delete mMediaEntry; + mMediaEntry = NULL; + } + + return TEM_CHANGE_MEDIA; } - return 0; + return TEM_CHANGE_NONE; } S32 LLTextureEntry::setBumpmap(U8 bump) @@ -317,7 +452,7 @@ S32 LLTextureEntry::setBumpmap(U8 bump) mBump |= bump; return TEM_CHANGE_TEXTURE; } - return 0; + return TEM_CHANGE_NONE; } S32 LLTextureEntry::setFullbright(U8 fullbright) @@ -329,7 +464,7 @@ S32 LLTextureEntry::setFullbright(U8 fullbright) mBump |= fullbright << TEM_FULLBRIGHT_SHIFT; return TEM_CHANGE_TEXTURE; } - return 0; + return TEM_CHANGE_NONE; } S32 LLTextureEntry::setShiny(U8 shiny) @@ -341,7 +476,7 @@ S32 LLTextureEntry::setShiny(U8 shiny) mBump |= shiny << TEM_SHINY_SHIFT; return TEM_CHANGE_TEXTURE; } - return 0; + return TEM_CHANGE_NONE; } S32 LLTextureEntry::setBumpShiny(U8 bump_shiny) @@ -353,7 +488,7 @@ S32 LLTextureEntry::setBumpShiny(U8 bump_shiny) mBump |= bump_shiny; return TEM_CHANGE_TEXTURE; } - return 0; + return TEM_CHANGE_NONE; } S32 LLTextureEntry::setMediaFlags(U8 media_flags) @@ -363,9 +498,21 @@ S32 LLTextureEntry::setMediaFlags(U8 media_flags) { mMediaFlags &= ~TEM_MEDIA_MASK; mMediaFlags |= media_flags; - return TEM_CHANGE_TEXTURE; + + // Special code for media handling + if( hasMedia() && mMediaEntry == NULL) + { + mMediaEntry = new LLMediaEntry; + } + else if ( ! hasMedia() && mMediaEntry != NULL) + { + delete mMediaEntry; + mMediaEntry = NULL; + } + + return TEM_CHANGE_MEDIA; } - return 0; + return TEM_CHANGE_NONE; } S32 LLTextureEntry::setTexGen(U8 tex_gen) @@ -377,7 +524,7 @@ S32 LLTextureEntry::setTexGen(U8 tex_gen) mMediaFlags |= tex_gen; return TEM_CHANGE_TEXTURE; } - return 0; + return TEM_CHANGE_NONE; } S32 LLTextureEntry::setGlow(F32 glow) @@ -387,5 +534,115 @@ S32 LLTextureEntry::setGlow(F32 glow) mGlow = glow; return TEM_CHANGE_TEXTURE; } - return 0; + return TEM_CHANGE_NONE; +} + +void LLTextureEntry::setMediaData(const LLMediaEntry &media_entry) +{ + mMediaFlags |= MF_HAS_MEDIA; + if (NULL != mMediaEntry) + { + delete mMediaEntry; + } + mMediaEntry = new LLMediaEntry(media_entry); +} + +bool LLTextureEntry::updateMediaData(const LLSD& media_data) +{ + if (media_data.isUndefined()) + { + // clear the media data + clearMediaData(); + return false; + } + else { + mMediaFlags |= MF_HAS_MEDIA; + if (mMediaEntry == NULL) + { + mMediaEntry = new LLMediaEntry; + } + // *NOTE: this will *clobber* all of the fields in mMediaEntry + // with whatever fields are present (or not present) in media_data! + mMediaEntry->fromLLSD(media_data); + return true; + } +} + +void LLTextureEntry::clearMediaData() +{ + mMediaFlags &= ~MF_HAS_MEDIA; + if (mMediaEntry != NULL) { + delete mMediaEntry; + } + mMediaEntry = NULL; +} + +void LLTextureEntry::mergeIntoMediaData(const LLSD& media_fields) +{ + mMediaFlags |= MF_HAS_MEDIA; + if (mMediaEntry == NULL) + { + mMediaEntry = new LLMediaEntry; + } + // *NOTE: this will *merge* the data in media_fields + // with the data in our media entry + mMediaEntry->mergeFromLLSD(media_fields); +} + +//static +std::string LLTextureEntry::touchMediaVersionString(const std::string &in_version, const LLUUID &agent_id) +{ + // XXX TODO: make media version string binary (base64-encoded?) + // Media "URL" is a representation of a version and the last-touched agent + // x-mv:nnnnn/agent-id + // where "nnnnn" is version number + // *NOTE: not the most efficient code in the world... + U32 current_version = getVersionFromMediaVersionString(in_version) + 1; + const size_t MAX_VERSION_LEN = 10; // 2^32 fits in 10 decimal digits + char buf[MAX_VERSION_LEN+1]; + snprintf(buf, (int)MAX_VERSION_LEN+1, "%0*u", (int)MAX_VERSION_LEN, current_version); // added int cast to fix warning/breakage on mac. + return MEDIA_VERSION_STRING_PREFIX + buf + "/" + agent_id.asString(); +} + +//static +U32 LLTextureEntry::getVersionFromMediaVersionString(const std::string &version_string) +{ + U32 version = 0; + if (!version_string.empty()) + { + size_t found = version_string.find(MEDIA_VERSION_STRING_PREFIX); + if (found != std::string::npos) + { + found = version_string.find_first_of("/", found); + std::string v = version_string.substr(MEDIA_VERSION_STRING_PREFIX.length(), found); + version = strtoul(v.c_str(),NULL,10); + } + } + return version; +} + +//static +LLUUID LLTextureEntry::getAgentIDFromMediaVersionString(const std::string &version_string) +{ + LLUUID id; + if (!version_string.empty()) + { + size_t found = version_string.find(MEDIA_VERSION_STRING_PREFIX); + if (found != std::string::npos) + { + found = version_string.find_first_of("/", found); + if (found != std::string::npos) + { + std::string v = version_string.substr(found + 1); + id.set(v); + } + } + } + return id; +} + +//static +bool LLTextureEntry::isMediaVersionString(const std::string &version_string) +{ + return std::string::npos != version_string.find(MEDIA_VERSION_STRING_PREFIX); } diff --git a/indra/llprimitive/lltextureentry.h b/indra/llprimitive/lltextureentry.h index 960d97ba0c..437b85e03f 100644 --- a/indra/llprimitive/lltextureentry.h +++ b/indra/llprimitive/lltextureentry.h @@ -2,30 +2,25 @@ * @file lltextureentry.h * @brief LLTextureEntry base class * - * $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. * - * 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 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. * - * 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. + * 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. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * 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,9 +31,13 @@ #include "v4color.h" #include "llsd.h" +// These bits are used while unpacking TEM messages to tell which aspects of +// the texture entry changed. +const S32 TEM_CHANGE_NONE = 0x0; const S32 TEM_CHANGE_COLOR = 0x1; const S32 TEM_CHANGE_TEXTURE = 0x2; -const S32 TEM_INVALID = 0x4; +const S32 TEM_CHANGE_MEDIA = 0x4; +const S32 TEM_INVALID = 0x8; const S32 TEM_BUMPMAP_COUNT = 32; @@ -63,10 +62,13 @@ 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 { @@ -81,14 +83,18 @@ public: LLTextureEntry(const LLTextureEntry &rhs); LLTextureEntry &operator=(const LLTextureEntry &rhs); - ~LLTextureEntry(); + virtual ~LLTextureEntry(); bool operator==(const LLTextureEntry &rhs) const; bool operator!=(const LLTextureEntry &rhs) const; LLSD asLLSD() const; + void asLLSD(LLSD& sd) const; operator LLSD() const { return asLLSD(); } - bool fromLLSD(LLSD& sd); + 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); @@ -98,7 +104,11 @@ public: 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); @@ -112,7 +122,7 @@ public: S32 setMediaTexGen(U8 media); S32 setGlow(F32 glow); - const LLUUID &getID() const { return mID; } + virtual const LLUUID &getID() const { return mID; } const LLColor4 &getColor() const { return mColor; } void getScale(F32 *s, F32 *t) const { *s = mScaleS; *t = mScaleT; } void getOffset(F32 *s, F32 *t) const { *s = mOffsetS; *t = mOffsetT; } @@ -129,9 +139,37 @@ public: U8 getTexGen() const { return mMediaFlags & TEM_TEX_GEN_MASK; } U8 getMediaTexGen() const { return mMediaFlags; } F32 getGlow() const { return mGlow; } + + // *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; } + + // 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); + // Clears media data, and sets the media flags bit to 0 + void clearMediaData(); + // Merges the given LLSD of media fields with this media entry. + // Only those fields that are set that match the keys in + // LLMediaEntry will be affected. If no fields are set or if + // the LLSD is undefined, this is a no-op. + void mergeIntoMediaData(const LLSD& media_fields); + + // Takes a media version string (an empty string or a previously-returned string) + // and returns a "touched" string, touched by agent_id + static std::string touchMediaVersionString(const std::string &in_version, const LLUUID &agent_id); + // Given a media version string, return the version + 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_WEB_PAGE = 0x1 }; + enum { MF_NONE = 0x0, MF_HAS_MEDIA = 0x1 }; public: F32 mScaleS; // S, T offset @@ -141,6 +179,14 @@ public: F32 mRotation; // anti-clockwise rotation in rad about the bottom left corner static const LLTextureEntry null; + + // 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; + protected: LLUUID mID; // Texture GUID LLColor4 mColor; @@ -148,6 +194,9 @@ protected: U8 mMediaFlags; // replace with web page, movie, etc. F32 mGlow; + // 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() diff --git a/indra/llprimitive/lltree_common.h b/indra/llprimitive/lltree_common.h index 302e9385f6..df00ff1591 100644 --- a/indra/llprimitive/lltree_common.h +++ b/indra/llprimitive/lltree_common.h @@ -2,30 +2,25 @@ * @file lltree_common.h * @brief LLTree_gene_0 base class * - * $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. * - * 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 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. * - * 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. + * 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. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * 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,6 +31,19 @@ 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) + { + } + // // The genome for a tree, species 0 // diff --git a/indra/llprimitive/lltreeparams.cpp b/indra/llprimitive/lltreeparams.cpp index ba038ffba8..842d848217 100644 --- a/indra/llprimitive/lltreeparams.cpp +++ b/indra/llprimitive/lltreeparams.cpp @@ -2,30 +2,25 @@ * @file lltreeparams.cpp * @brief implementation of the LLTreeParams class. * - * $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$ */ diff --git a/indra/llprimitive/lltreeparams.h b/indra/llprimitive/lltreeparams.h index c4bb1eacaa..6e2b47c0e9 100644 --- a/indra/llprimitive/lltreeparams.h +++ b/indra/llprimitive/lltreeparams.h @@ -2,30 +2,25 @@ * @file lltreeparams.h * @brief Implementation of the LLTreeParams class * - * $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$ */ diff --git a/indra/llprimitive/llvolumemessage.cpp b/indra/llprimitive/llvolumemessage.cpp index c7efc86c12..b6cae5c4df 100644 --- a/indra/llprimitive/llvolumemessage.cpp +++ b/indra/llprimitive/llvolumemessage.cpp @@ -2,30 +2,25 @@ * @file llvolumemessage.cpp * @brief LLVolumeMessage base class * - * $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$ */ diff --git a/indra/llprimitive/llvolumemessage.h b/indra/llprimitive/llvolumemessage.h index 7e7da3da4a..33562323c3 100644 --- a/indra/llprimitive/llvolumemessage.h +++ b/indra/llprimitive/llvolumemessage.h @@ -2,30 +2,25 @@ * @file llvolumemessage.h * @brief LLVolumeMessage base class * - * $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$ */ diff --git a/indra/llprimitive/llvolumexml.cpp b/indra/llprimitive/llvolumexml.cpp index c9af11c4ce..f4f9d4d713 100644 --- a/indra/llprimitive/llvolumexml.cpp +++ b/indra/llprimitive/llvolumexml.cpp @@ -2,30 +2,25 @@ * @file llvolumexml.cpp * @brief LLVolumeXml base class * - * $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$ */ diff --git a/indra/llprimitive/llvolumexml.h b/indra/llprimitive/llvolumexml.h index 8bec5f75e3..5e79205d9a 100644 --- a/indra/llprimitive/llvolumexml.h +++ b/indra/llprimitive/llvolumexml.h @@ -2,30 +2,25 @@ * @file llvolumexml.h * @brief LLVolumeXml base class * - * $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$ */ diff --git a/indra/llprimitive/material_codes.cpp b/indra/llprimitive/material_codes.cpp new file mode 100644 index 0000000000..2ea47eec36 --- /dev/null +++ b/indra/llprimitive/material_codes.cpp @@ -0,0 +1,40 @@ +/** + * @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$ + */ + +#include "linden_common.h" + +#include "material_codes.h" + +#include "lluuid.h" + +const LLUUID LL_DEFAULT_STONE_UUID("87c5765b-aa26-43eb-b8c6-c09a1ca6208e"); +const LLUUID LL_DEFAULT_METAL_UUID("6f3c53e9-ba60-4010-8f3e-30f51a762476"); +const LLUUID LL_DEFAULT_GLASS_UUID("b4ba225c-373f-446d-9f7e-6cb7b5cf9b3d"); +const LLUUID LL_DEFAULT_WOOD_UUID("89556747-24cb-43ed-920b-47caed15465f"); +const LLUUID LL_DEFAULT_FLESH_UUID("80736669-e4b9-450e-8890-d5169f988a50"); +const LLUUID LL_DEFAULT_PLASTIC_UUID("304fcb4e-7d33-4339-ba80-76d3d22dc11a"); +const LLUUID LL_DEFAULT_RUBBER_UUID("9fae0bc5-666d-477e-9f70-84e8556ec867"); +const LLUUID LL_DEFAULT_LIGHT_UUID("00000000-0000-0000-0000-000000000000"); diff --git a/indra/llprimitive/material_codes.h b/indra/llprimitive/material_codes.h index 8e77a432a5..84a6f2edd2 100644 --- a/indra/llprimitive/material_codes.h +++ b/indra/llprimitive/material_codes.h @@ -2,37 +2,32 @@ * @file material_codes.h * @brief Material_codes definitions * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&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$ */ #ifndef LL_MATERIAL_CODES_H #define LL_MATERIAL_CODES_H -#include "lluuid.h" +class LLUUID; // material types const U8 LL_MCODE_STONE = 0; @@ -46,13 +41,14 @@ const U8 LL_MCODE_LIGHT = 7; const U8 LL_MCODE_END = 8; const U8 LL_MCODE_MASK = 0x0F; -const LLUUID LL_DEFAULT_STONE_UUID("87c5765b-aa26-43eb-b8c6-c09a1ca6208e"); -const LLUUID LL_DEFAULT_METAL_UUID("6f3c53e9-ba60-4010-8f3e-30f51a762476"); -const LLUUID LL_DEFAULT_GLASS_UUID("b4ba225c-373f-446d-9f7e-6cb7b5cf9b3d"); -const LLUUID LL_DEFAULT_WOOD_UUID("89556747-24cb-43ed-920b-47caed15465f"); -const LLUUID LL_DEFAULT_FLESH_UUID("80736669-e4b9-450e-8890-d5169f988a50"); -const LLUUID LL_DEFAULT_PLASTIC_UUID("304fcb4e-7d33-4339-ba80-76d3d22dc11a"); -const LLUUID LL_DEFAULT_RUBBER_UUID("9fae0bc5-666d-477e-9f70-84e8556ec867"); -const LLUUID LL_DEFAULT_LIGHT_UUID("00000000-0000-0000-0000-000000000000"); +// *NOTE: Define these in .cpp file to reduce duplicate instances +extern const LLUUID LL_DEFAULT_STONE_UUID; +extern const LLUUID LL_DEFAULT_METAL_UUID; +extern const LLUUID LL_DEFAULT_GLASS_UUID; +extern const LLUUID LL_DEFAULT_WOOD_UUID; +extern const LLUUID LL_DEFAULT_FLESH_UUID; +extern const LLUUID LL_DEFAULT_PLASTIC_UUID; +extern const LLUUID LL_DEFAULT_RUBBER_UUID; +extern const LLUUID LL_DEFAULT_LIGHT_UUID; #endif diff --git a/indra/llprimitive/object_flags.h b/indra/llprimitive/object_flags.h index cc37d06545..94c559d757 100644 --- a/indra/llprimitive/object_flags.h +++ b/indra/llprimitive/object_flags.h @@ -2,30 +2,25 @@ * @file object_flags.h * @brief Flags for object creation and transmission * - * $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$ */ diff --git a/indra/llprimitive/tests/llmediaentry_test.cpp b/indra/llprimitive/tests/llmediaentry_test.cpp new file mode 100644 index 0000000000..16e5f894e2 --- /dev/null +++ b/indra/llprimitive/tests/llmediaentry_test.cpp @@ -0,0 +1,502 @@ +/** + * @file llmediaentry_test.cpp + * @brief llmediaentry unit 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$ + */ + +#include "linden_common.h" +#include "lltut.h" +#if LL_WINDOWS +#pragma warning (push) +#pragma warning (disable : 4702) // boost::lexical_cast generates this warning +#endif +#include <boost/lexical_cast.hpp> +#if LL_WINDOWS +#pragma warning (pop) +#endif +#include "llstring.h" +#include "llsdutil.h" +#include "llsdserialize.h" + +#include "../llmediaentry.h" +#include "lllslconstants.h" + +#define DEFAULT_MEDIA_ENTRY "<llsd>\n\ + <map>\n\ + <key>alt_image_enable</key>\n\ + <boolean>0</boolean>\n\ + <key>auto_loop</key>\n\ + <boolean>0</boolean>\n\ + <key>auto_play</key>\n\ + <boolean>0</boolean>\n\ + <key>auto_scale</key>\n\ + <boolean>0</boolean>\n\ + <key>auto_zoom</key>\n\ + <boolean>0</boolean>\n\ + <key>controls</key>\n\ + <integer>0</integer>\n\ + <key>current_url</key>\n\ + <string />\n\ + <key>first_click_interact</key>\n\ + <boolean>0</boolean>\n\ + <key>height_pixels</key>\n\ + <integer>0</integer>\n\ + <key>home_url</key>\n\ + <string />\n\ + <key>perms_control</key>\n\ + <integer>7</integer>\n\ + <key>perms_interact</key>\n\ + <integer>7</integer>\n\ + <key>whitelist_enable</key>\n\ + <boolean>0</boolean>\n\ + <key>width_pixels</key>\n\ + <integer>0</integer>\n\ + </map>\n\ + </llsd>" + +#define EMPTY_MEDIA_ENTRY "<llsd>\n\ + <map>\n\ + <key>alt_image_enable</key>\n\ + <boolean>0</boolean>\n\ + <key>auto_loop</key>\n\ + <boolean>0</boolean>\n\ + <key>auto_play</key>\n\ + <boolean>0</boolean>\n\ + <key>auto_scale</key>\n\ + <boolean>0</boolean>\n\ + <key>auto_zoom</key>\n\ + <boolean>0</boolean>\n\ + <key>controls</key>\n\ + <integer>0</integer>\n\ + <key>current_url</key>\n\ + <string />\n\ + <key>first_click_interact</key>\n\ + <boolean>0</boolean>\n\ + <key>height_pixels</key>\n\ + <integer>0</integer>\n\ + <key>home_url</key>\n\ + <string />\n\ + <key>perms_control</key>\n\ + <integer>0</integer>\n\ + <key>perms_interact</key>\n\ + <integer>0</integer>\n\ + <key>whitelist_enable</key>\n\ + <boolean>0</boolean>\n\ + <key>width_pixels</key>\n\ + <integer>0</integer>\n\ + </map>\n\ + </llsd>" + +#define PARTIAL_MEDIA_ENTRY(CURRENT_URL) "<llsd>\n\ + <map>\n\ + <key>alt_image_enable</key>\n\ + <boolean>0</boolean>\n\ + <key>auto_loop</key>\n\ + <boolean>0</boolean>\n\ + <key>auto_play</key>\n\ + <boolean>0</boolean>\n\ + <key>auto_scale</key>\n\ + <boolean>0</boolean>\n\ + <key>auto_zoom</key>\n\ + <boolean>0</boolean>\n\ + <key>controls</key>\n\ + <integer>0</integer>\n\ + <key>current_url</key>\n\ + <string>" CURRENT_URL "</string>\n\ + <key>first_click_interact</key>\n\ + <boolean>0</boolean>\n\ + <key>height_pixels</key>\n\ + <integer>0</integer>\n\ + <key>home_url</key>\n\ + <string />\n\ + <key>perms_control</key>\n\ + <integer>0</integer>\n\ + <key>perms_interact</key>\n\ + <integer>0</integer>\n\ + <key>whitelist_enable</key>\n\ + <boolean>0</boolean>\n\ + <key>width_pixels</key>\n\ + <integer>0</integer>\n\ + </map>\n\ + </llsd>" + +namespace tut +{ + // this is fixture data that gets created before each test and destroyed + // after each test. this is where we put all of the setup/takedown code + // and data needed for each test. + struct MediaEntry_test + { + MediaEntry_test() { + emptyMediaEntryStr = EMPTY_MEDIA_ENTRY; + std::istringstream e(EMPTY_MEDIA_ENTRY); + LLSDSerialize::fromXML(emptyMediaEntryLLSD, e); + defaultMediaEntryStr = DEFAULT_MEDIA_ENTRY; + std::istringstream d(DEFAULT_MEDIA_ENTRY); + LLSDSerialize::fromXML(defaultMediaEntryLLSD, d); + } + std::string emptyMediaEntryStr; + LLSD emptyMediaEntryLLSD; + std::string defaultMediaEntryStr; + LLSD defaultMediaEntryLLSD; + }; + + typedef test_group<MediaEntry_test, 55> factory; + typedef factory::object object; +} + + +namespace +{ + // this is for naming our tests to make pretty output + tut::factory tf("LLMediaEntry"); +} + +namespace tut +{ + void ensure_llsd_equals(const std::string& msg, const LLSD& expected, const LLSD& actual) + { + if (!llsd_equals(expected, actual)) + { + std::string message = msg; + message += ": actual: "; + message += ll_pretty_print_sd(actual); + message += "\n expected: "; + message += ll_pretty_print_sd(expected); + message += "\n"; + ensure(message, false); + } + } + + void ensure_string_equals(const std::string& msg, const std::string& expected, const std::string& actual) + { + if ( expected != actual ) + { + std::string message = msg; + message += ": actual: "; + message += actual; + message += "\n expected: "; + message += expected; + message += "\n"; + ensure(message, false); + } + } + + void set_whitelist(LLMediaEntry &entry, const char *str) + { + std::vector<std::string> tokens; + LLStringUtil::getTokens(std::string(str), tokens, ","); + entry.setWhiteList(tokens); + } + + void whitelist_test(int num, bool enable, const char *whitelist, const char *candidate_url, bool expected_pass) + { + std::string message = "Whitelist test " + boost::lexical_cast<std::string>(num); + LLMediaEntry entry; + entry.setWhiteListEnable(enable); + set_whitelist(entry, whitelist); + bool passed_whitelist = entry.checkCandidateUrl(candidate_url); + if (passed_whitelist != expected_pass) + { + message += " failed: expected "; + message += (expected_pass) ? "" : "NOT "; + message += "to match\nwhitelist = "; + message += whitelist; + message += "\ncandidate_url = "; + message += candidate_url; + } + ensure(message, expected_pass == passed_whitelist); + } + + void whitelist_test(int num, const char *whitelist, const char *candidate_url, bool expected_pass) + { + whitelist_test(num, true, whitelist, candidate_url, expected_pass); + } + void whitelist_test(int num, const char *whitelist, const char *candidate_url) + { + whitelist_test(num, true, whitelist, candidate_url, true); + } + + 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"); + LLMediaEntry entry; + LLSD sd; + entry.fromLLSD(sd); + ensure_llsd_equals(get_test_name() + " failed", emptyMediaEntryLLSD, entry.asLLSD()); + } + + template<> template<> + void object::test<3>() + { + set_test_name("Test LLMediaEntry Partial Instantiation from LLSD"); + LLMediaEntry entry; + LLSD sd; + sd[LLMediaEntry::CURRENT_URL_KEY] = "http://www.example.com"; + entry.fromLLSD(sd); + LLSD golden; + std::istringstream p(PARTIAL_MEDIA_ENTRY("http://www.example.com")); + LLSDSerialize::fromXML(golden,p); + ensure_llsd_equals(get_test_name() + " failed", golden, entry.asLLSD()); + } + + template<> template<> + void object::test<4>() + { + set_test_name("Test LLMediaEntry::asLLSD()"); + LLMediaEntry entry; + LLSD sd; + // Put some cruft in the LLSD + sd[LLMediaEntry::CURRENT_URL_KEY] = "http://www.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"); + entry2.setWhiteList(whitelist); + // Render entry1 (which has no whitelist) as an LLSD + LLSD 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"; + + template<> template<> + void object::test<6>() + { + set_test_name("Test Limits on setting current URL"); + LLMediaEntry entry; + U32 status = entry.setCurrentURL(URL_OK); + 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>() + { + set_test_name("Test Limits on setting home URL"); + LLMediaEntry entry; + U32 status = entry.setHomeURL(URL_OK); + ensure(get_test_name() + " ok failed", status == LSL_STATUS_OK); + status = entry.setHomeURL(URL_TOO_BIG); + ensure(get_test_name() + " ok failed", status == LSL_STATUS_BOUNDS_ERROR); + } + + template<> template<> + void object::test<8>() + { + set_test_name("Test Limits on setting whitelist"); + + // Test a valid list + LLMediaEntry entry; + std::vector<std::string> whitelist; + whitelist.push_back(std::string(URL_OK)); + S32 status = entry.setWhiteList(whitelist); + ensure(get_test_name() + " invalid result", status == LSL_STATUS_OK); + ensure(get_test_name() + " failed", whitelist == entry.getWhiteList()); + } + + template<> template<> + 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; + whitelist.push_back(std::string(URL_OK)); + whitelist.push_back(std::string(URL_TOO_BIG)); + S32 status = entry.setWhiteList(whitelist); + ensure(get_test_name() + " invalid result", status == LSL_STATUS_BOUNDS_ERROR); + ensure(get_test_name() + " failed", empty == entry.getWhiteList()); + } + + template<> template<> + 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; + for (int i=0; i < LLMediaEntry::MAX_WHITELIST_SIZE+1; i++) { + whitelist.push_back("Q"); + } + S32 status = entry.setWhiteList(whitelist); + ensure(get_test_name() + " invalid result", status == LSL_STATUS_BOUNDS_ERROR); + ensure(get_test_name() + " failed", empty == entry.getWhiteList()); + } + + template<> template<> + 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; + whitelist.push_back(std::string(URL_OK)); + whitelist_llsd.append(std::string(URL_OK)); + LLMediaEntry entry1, entry2; + 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", + entry1.getWhiteList() == entry2.getWhiteList()); + } + + template<> template<> + void object::test<12>() + { + set_test_name("Test to make sure both setWhiteList() functions behave the same"); + + // Test an invalid list + std::vector<std::string> whitelist, empty; + LLSD whitelist_llsd; + whitelist.push_back(std::string(URL_OK)); + whitelist.push_back(std::string(URL_TOO_BIG)); + whitelist_llsd.append(std::string(URL_OK)); + whitelist_llsd.append(std::string(URL_TOO_BIG)); + LLMediaEntry entry1, entry2; + 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", + empty == entry1.getWhiteList() && + empty == entry2.getWhiteList()); + } + + template<> template<> + void object::test<13>() + { + set_test_name("Test to make sure both setWhiteList() functions behave the same"); + + // Test an invalid list, too many + std::vector<std::string> whitelist, empty; + LLSD whitelist_llsd; + for (int i=0; i < LLMediaEntry::MAX_WHITELIST_SIZE+1; i++) { + whitelist.push_back("Q"); + whitelist_llsd.append("Q"); + } + LLMediaEntry entry1, entry2; + 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", + 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); + + // 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); + } + +} + diff --git a/indra/llprimitive/tests/llmessagesystem_stub.cpp b/indra/llprimitive/tests/llmessagesystem_stub.cpp new file mode 100644 index 0000000000..04e70945c4 --- /dev/null +++ b/indra/llprimitive/tests/llmessagesystem_stub.cpp @@ -0,0 +1,47 @@ +/** + * @file llmessagesystem_stub.cpp + * + * $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$ + */ + +#include "linden_common.h" + +char * _PREHASH_TextureEntry; + +S32 LLMessageSystem::getSizeFast(char const*, char const*) const +{ + return 0; +} + +S32 LLMessageSystem::getSizeFast(char const*, int, char const*) const +{ + return 0; +} + +void LLMessageSystem::getBinaryDataFast(char const*, char const*, void*, int, int, int) +{ +} + +void LLMessageSystem::addBinaryDataFast(char const*, void const*, int) +{ +} + diff --git a/indra/llprimitive/tests/llprimitive_test.cpp b/indra/llprimitive/tests/llprimitive_test.cpp new file mode 100644 index 0000000000..0d60c7cd15 --- /dev/null +++ b/indra/llprimitive/tests/llprimitive_test.cpp @@ -0,0 +1,231 @@ +/** + * @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$ + */ + +#include "linden_common.h" + +#include "../test/lltut.h" + +#include "../llprimitive.h" + +#include "../../llmath/llvolumemgr.h" + +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; + } + } + +private: + LLPointer<LLVolume> mVolumeTest; + LLVolumeParams mCurrParamsTest; + S32 mCurrDetailTest; +}; + +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; +}; + +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()); + } +} + +#include "llmessagesystem_stub.cpp" |