From 291de90276420f57bddcb060fca8deaef4b54578 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Wed, 23 Feb 2011 01:44:31 -0600 Subject: [PATCH] V2 llprimitive merge --- indra/llprimitive/CMakeLists.txt | 3 + indra/llprimitive/llmaterialtable.cpp | 13 +- indra/llprimitive/llmaterialtable.h | 84 ++-- indra/llprimitive/llprimitive.cpp | 600 +++++++++++------------- indra/llprimitive/llprimitive.h | 26 +- indra/llprimitive/llprimtexturelist.cpp | 418 +++++++++++++++++ indra/llprimitive/llprimtexturelist.h | 129 +++++ indra/llprimitive/lltextureentry.cpp | 119 ++++- indra/llprimitive/lltextureentry.h | 23 +- indra/llprimitive/material_codes.cpp | 47 ++ indra/llprimitive/material_codes.h | 19 +- indra/newview/llselectmgr.cpp | 2 +- 12 files changed, 1056 insertions(+), 427 deletions(-) create mode 100644 indra/llprimitive/llprimtexturelist.cpp create mode 100644 indra/llprimitive/llprimtexturelist.h create mode 100644 indra/llprimitive/material_codes.cpp diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt index a214b519b..572bc4328 100644 --- a/indra/llprimitive/CMakeLists.txt +++ b/indra/llprimitive/CMakeLists.txt @@ -18,11 +18,13 @@ include_directories( set(llprimitive_SOURCE_FILES llmaterialtable.cpp llprimitive.cpp + llprimtexturelist.cpp lltextureanim.cpp lltextureentry.cpp lltreeparams.cpp llvolumemessage.cpp llvolumexml.cpp + material_codes.cpp ) set(llprimitive_HEADER_FILES @@ -31,6 +33,7 @@ set(llprimitive_HEADER_FILES legacy_object_types.h llmaterialtable.h llprimitive.h + llprimtexturelist.h lltextureanim.h lltextureentry.h lltreeparams.h diff --git a/indra/llprimitive/llmaterialtable.cpp b/indra/llprimitive/llmaterialtable.cpp index 24f71d0ad..1772a8485 100644 --- a/indra/llprimitive/llmaterialtable.cpp +++ b/indra/llprimitive/llmaterialtable.cpp @@ -40,16 +40,6 @@ LLMaterialTable LLMaterialTable::basic(1); -// Material UUIDs. -LLUUID const LL_DEFAULT_STONE_UUID("87c5765b-aa26-43eb-b8c6-c09a1ca6208e"); -LLUUID const LL_DEFAULT_METAL_UUID("6f3c53e9-ba60-4010-8f3e-30f51a762476"); -LLUUID const LL_DEFAULT_GLASS_UUID("b4ba225c-373f-446d-9f7e-6cb7b5cf9b3d"); -LLUUID const LL_DEFAULT_WOOD_UUID("89556747-24cb-43ed-920b-47caed15465f"); -LLUUID const LL_DEFAULT_FLESH_UUID("80736669-e4b9-450e-8890-d5169f988a50"); -LLUUID const LL_DEFAULT_PLASTIC_UUID("304fcb4e-7d33-4339-ba80-76d3d22dc11a"); -LLUUID const LL_DEFAULT_RUBBER_UUID("9fae0bc5-666d-477e-9f70-84e8556ec867"); -LLUUID const LL_DEFAULT_LIGHT_UUID("00000000-0000-0000-0000-000000000000"); - /* Old Havok 1 constants @@ -102,6 +92,9 @@ F32 const LLMaterialTable::DEFAULT_FRICTION = 0.5f; F32 const LLMaterialTable::DEFAULT_RESTITUTION = 0.4f; LLMaterialTable::LLMaterialTable() + : mCollisionSoundMatrix(NULL), + mSlidingSoundMatrix(NULL), + mRollingSoundMatrix(NULL) { } diff --git a/indra/llprimitive/llmaterialtable.h b/indra/llprimitive/llmaterialtable.h index ca9017abd..c7144e884 100644 --- a/indra/llprimitive/llmaterialtable.h +++ b/indra/llprimitive/llmaterialtable.h @@ -38,6 +38,8 @@ #include +class LLMaterialInfo; + const U32 LLMATERIAL_INFO_NAME_LENGTH = 256; // We've moved toward more reasonable mass values for the Havok4 engine. @@ -64,45 +66,6 @@ const F32 LEGACY_DEFAULT_OBJECT_DENSITY = 10.0f; const F32 DEFAULT_AVATAR_DENSITY = 445.3f; // was 444.24f; -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) - mHPModifier = 1.f; - mDamageModifier = 1.f; - mEPModifier = 1.f; - - mMCode = mcode; - mName = name; - mDefaultTextureID = uuid; - }; - - ~LLMaterialInfo() - { - }; - -}; - class LLMaterialTable { public: @@ -147,6 +110,7 @@ public: void initBasicTable(); + 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); @@ -183,5 +147,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/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index 1b5de9d6a..9b6f383e1 100644 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -44,6 +44,7 @@ #include "llstring.h" #include "lldatapacker.h" #include "llsdutil_math.h" +#include "llprimtexturelist.h" /** * exported constants @@ -112,6 +113,7 @@ 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"; @@ -130,7 +132,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; } @@ -151,7 +153,9 @@ bool LLPrimitive::cleanupVolumeManager() //=============================================================== LLPrimitive::LLPrimitive() -: mMiscFlags(0) +: mTextureList(), + mNumTEs(0), + mMiscFlags(0) { mPrimitiveCode = 0; @@ -168,20 +172,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) { @@ -190,6 +186,10 @@ LLPrimitive::~LLPrimitive() mVolumep = NULL; } +void LLPrimitive::clearTextureList() +{ +} + //=============================================================== // static LLPrimitive *LLPrimitive::createPrimitive(LLPCode p_code) @@ -213,15 +213,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; } @@ -231,342 +223,146 @@ void LLPrimitive::setPCode(const U8 p_code) } //=============================================================== -const LLTextureEntry * LLPrimitive::getTE(const U8 te_num) const +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); } @@ -878,25 +674,18 @@ std::string 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))); } } @@ -958,16 +747,201 @@ BOOL LLPrimitive::setVolume(const LLVolumeParams &volume_params, const S32 detai U32 old_face_mask = mVolumep->mFaceMask; + S32 face_bit = 0; + S32 cur_mask = 0; + + // 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 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.copyTexture(face_bit, *(getTE(te_index))); + //llinfos << face_bit << ":" << te_index << ":" << old_tes[face_bit].getID() << llendl; + } + } + + // build the new object sVolumeManager->unrefVolume(mVolumep); mVolumep = volumep; - U32 new_face_mask = mVolumep->mFaceMask; - if (old_face_mask != new_face_mask) + U32 new_face_mask = mVolumep->mFaceMask; + S32 i; + + if (old_face_mask == new_face_mask) { + // nothing to do + return TRUE; + } + + if (mVolumep->getNumFaces() == 0 && new_face_mask != 0) + { + llwarns << "Object with 0 faces found...INCORRECT!" << llendl; setNumTEs(mVolumep->getNumFaces()); - } + return TRUE; + } + + // initialize face_mapping + S32 face_mapping[9]; + for (face_bit = 0; face_bit < 9; face_bit++) + { + face_mapping[face_bit] = face_bit; + } + + // 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; + if (!(new_face_mask & cur_mask)) + { + // Face doesn't exist in new map. + face_mapping[face_bit] = -1; + continue; + } + else if (old_face_mask & cur_mask) + { + // Face exists in new and old map. + face_mapping[face_bit] = face_bit; + continue; + } + + // OK, how we've got a mismatch, where we have to fill a new face with one from + // the old face. + if (cur_mask & (LL_FACE_PATH_BEGIN | LL_FACE_PATH_END | LL_FACE_INNER_SIDE)) + { + // It's a top/bottom/hollow interior face. + if (old_face_mask & LL_FACE_PATH_END) + { + face_mapping[face_bit] = 1; + continue; + } + else + { + S32 cur_outer_mask = LL_FACE_OUTER_SIDE_0; + for (i = 0; i < 4; i++) + { + if (old_face_mask & cur_outer_mask) + { + face_mapping[face_bit] = 5 + i; + break; + } + cur_outer_mask <<= 1; + } + if (i == 4) + { + llwarns << "No path end or outer face in volume!" << llendl; + } + continue; + } + } + + if (cur_mask & (LL_FACE_PROFILE_BEGIN | LL_FACE_PROFILE_END)) + { + // A cut slice. Use the hollow interior if we have it. + if (old_face_mask & LL_FACE_INNER_SIDE) + { + face_mapping[face_bit] = 2; + continue; + } + + // No interior, use the bottom face. + // Could figure out which of the outer faces was nearest, but that would be harder. + if (old_face_mask & LL_FACE_PATH_END) + { + face_mapping[face_bit] = 1; + continue; + } + else + { + S32 cur_outer_mask = LL_FACE_OUTER_SIDE_0; + for (i = 0; i < 4; i++) + { + if (old_face_mask & cur_outer_mask) + { + face_mapping[face_bit] = 5 + i; + break; + } + cur_outer_mask <<= 1; + } + if (i == 4) + { + llwarns << "No path end or outer face in volume!" << llendl; + } + continue; + } + } + + // OK, the face that's missing is an outer face... + // Pull from the nearest adjacent outer face (there's always guaranteed to be one... + S32 cur_outer = face_bit - 5; + S32 min_dist = 5; + S32 min_outer_bit = -1; + S32 i; + for (i = 0; i < 4; i++) + { + if (old_face_mask & (LL_FACE_OUTER_SIDE_0 << i)) + { + S32 dist = abs(i - cur_outer); + if (dist < min_dist) + { + min_dist = dist; + min_outer_bit = i + 5; + } + } + } + if (-1 == min_outer_bit) + { + llinfos << (LLVolume *)mVolumep << llendl; + llwarns << "Bad! No outer faces, impossible!" << llendl; + } + 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) + { + if (-1 == face_mapping[face_bit]) + { + llwarns << "No mapping from old face to new face!" << llendl; + } + + S32 te_num = face_index_from_id(cur_mask, mVolumep->getProfile().mFaces); + setTE(te_num, *(old_tes.getTexture(face_mapping[face_bit]))); + } + } return TRUE; } @@ -984,50 +958,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 @@ -1405,6 +1335,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; @@ -1504,11 +1435,24 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp) return retval; } -void LLPrimitive::setTextureList(LLTextureEntry *listp) +U8 LLPrimitive::getExpectedNumTEs() const { - LLTextureEntry* old_texture_list = mTextureList; - mTextureList = listp; - delete[] old_texture_list; + 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) +{ + mTextureList.take(other_list); } //============================================================================ diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h index fca973c1a..03769a87a 100644 --- a/indra/llprimitive/llprimitive.h +++ b/indra/llprimitive/llprimitive.h @@ -40,6 +40,7 @@ #include "llmemory.h" #include "llvolume.h" #include "lltextureentry.h" +#include "llprimtexturelist.h" // Moved to stdtypes.h --JC // typedef U8 LLPCode; @@ -261,9 +262,9 @@ 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; } }; @@ -295,6 +296,8 @@ public: LLPrimitive(); virtual ~LLPrimitive(); + void clearTextureList(); + static LLPrimitive *createPrimitive(LLPCode p_code); void init_primitive(LLPCode p_code); @@ -309,7 +312,7 @@ public: 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); @@ -332,10 +335,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); @@ -383,14 +382,21 @@ public: 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; @@ -415,7 +421,7 @@ protected: LLVector3 mAcceleration; // are we under constant acceleration? LLVector3 mAngularVelocity; // angular velocity LLPointer 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/llprimtexturelist.cpp b/indra/llprimitive/llprimtexturelist.cpp new file mode 100644 index 000000000..36e04df7b --- /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 000000000..71b191ef7 --- /dev/null +++ b/indra/llprimitive/llprimtexturelist.h @@ -0,0 +1,129 @@ +/** + * @file llprimtexturelist.h + * @brief LLPrimTextureList (virtual) base class + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008-2010, Linden Research, Inc. + * + * 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 + * + * 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 + * + * 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. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + * + */ + + +#ifndef LL_LLPRIMTEXTURELIST_H +#define LL_LLPRIMTEXTURELIST_H + +#include +#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 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/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp index 44db39438..3432f0c98 100644 --- a/indra/llprimitive/lltextureentry.cpp +++ b/indra/llprimitive/lltextureentry.cpp @@ -39,6 +39,13 @@ const U8 DEFAULT_BUMP_CODE = 0; // no bump or shininess const LLTextureEntry LLTextureEntry::null; + +// static +LLTextureEntry* LLTextureEntry::newTextureEntry() +{ + return new LLTextureEntry(); +} + //=============================================================== LLTextureEntry::LLTextureEntry() { @@ -136,23 +143,26 @@ 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; + sd["glow"] = mGlow; } -bool LLTextureEntry::fromLLSD(LLSD& sd) +bool LLTextureEntry::fromLLSD(const LLSD& sd) { const char *w, *x; w = "imageid"; @@ -208,6 +218,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) @@ -215,7 +238,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) @@ -233,6 +256,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) @@ -240,7 +285,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) @@ -251,7 +296,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) @@ -261,7 +306,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) @@ -279,14 +324,36 @@ 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) + if (mRotation != theta && llfinite(theta)) { mRotation = theta; return TEM_CHANGE_TEXTURE; } - return 0; + return TEM_CHANGE_NONE; } S32 LLTextureEntry::setBumpShinyFullbright(U8 bump) @@ -296,7 +363,7 @@ S32 LLTextureEntry::setBumpShinyFullbright(U8 bump) mBump = bump; return TEM_CHANGE_TEXTURE; } - return 0; + return TEM_CHANGE_NONE; } S32 LLTextureEntry::setMediaTexGen(U8 media) @@ -304,9 +371,9 @@ S32 LLTextureEntry::setMediaTexGen(U8 media) if (mMediaFlags != media) { mMediaFlags = media; - return TEM_CHANGE_TEXTURE; + return TEM_CHANGE_MEDIA; } - return 0; + return TEM_CHANGE_NONE; } S32 LLTextureEntry::setBumpmap(U8 bump) @@ -318,7 +385,7 @@ S32 LLTextureEntry::setBumpmap(U8 bump) mBump |= bump; return TEM_CHANGE_TEXTURE; } - return 0; + return TEM_CHANGE_NONE; } S32 LLTextureEntry::setFullbright(U8 fullbright) @@ -330,7 +397,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) @@ -342,7 +409,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) @@ -354,7 +421,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) @@ -364,9 +431,9 @@ S32 LLTextureEntry::setMediaFlags(U8 media_flags) { mMediaFlags &= ~TEM_MEDIA_MASK; mMediaFlags |= media_flags; - return TEM_CHANGE_TEXTURE; + return TEM_CHANGE_MEDIA; } - return 0; + return TEM_CHANGE_NONE; } S32 LLTextureEntry::setTexGen(U8 tex_gen) @@ -378,7 +445,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) @@ -388,5 +455,7 @@ S32 LLTextureEntry::setGlow(F32 glow) mGlow = glow; return TEM_CHANGE_TEXTURE; } - return 0; + return TEM_CHANGE_NONE; } + + diff --git a/indra/llprimitive/lltextureentry.h b/indra/llprimitive/lltextureentry.h index c562545fc..e312e2a91 100644 --- a/indra/llprimitive/lltextureentry.h +++ b/indra/llprimitive/lltextureentry.h @@ -37,9 +37,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; //Currently doesn't do anything, (not that TEM_CHANGE_TEXTURE either) +const S32 TEM_INVALID = 0x8; const S32 TEM_BUMPMAP_COUNT = 32; @@ -68,6 +72,7 @@ const S32 TEM_TEX_GEN_SHIFT = 1; class LLTextureEntry { public: + static LLTextureEntry* newTextureEntry(); typedef enum e_texgen { @@ -82,14 +87,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); @@ -99,7 +108,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); @@ -113,7 +126,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; } @@ -132,7 +145,7 @@ public: F32 getGlow() const { return mGlow; } // Media flags - enum { MF_NONE = 0x0, MF_WEB_PAGE = 0x1 }; + enum { MF_NONE = 0x0, MF_HAS_MEDIA = 0x1 }; public: F32 mScaleS; // S, T offset diff --git a/indra/llprimitive/material_codes.cpp b/indra/llprimitive/material_codes.cpp new file mode 100644 index 000000000..1bfb1ea6f --- /dev/null +++ b/indra/llprimitive/material_codes.cpp @@ -0,0 +1,47 @@ +/** + * @file material_codes.cpp + * @brief Material_codes definitions + * + * $LicenseInfo:firstyear=2000&license=viewergpl$ + * + * Copyright (c) 2000-2010, Linden Research, Inc. + * + * 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 + * + * 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 + * + * 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. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/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 ed159bc7d..ba3faba39 100644 --- a/indra/llprimitive/material_codes.h +++ b/indra/llprimitive/material_codes.h @@ -33,7 +33,7 @@ #ifndef LL_MATERIAL_CODES_H #define LL_MATERIAL_CODES_H -#include "lluuid.h" +class LLUUID; // material types const U8 LL_MCODE_STONE = 0; @@ -47,13 +47,14 @@ const U8 LL_MCODE_LIGHT = 7; const U8 LL_MCODE_END = 8; const U8 LL_MCODE_MASK = 0x0F; -extern LLUUID const LL_DEFAULT_STONE_UUID; -extern LLUUID const LL_DEFAULT_METAL_UUID; -extern LLUUID const LL_DEFAULT_GLASS_UUID; -extern LLUUID const LL_DEFAULT_WOOD_UUID; -extern LLUUID const LL_DEFAULT_FLESH_UUID; -extern LLUUID const LL_DEFAULT_PLASTIC_UUID; -extern LLUUID const LL_DEFAULT_RUBBER_UUID; -extern LLUUID const LL_DEFAULT_LIGHT_UUID; +// *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/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 67ffcce87..64f5de223 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -1738,7 +1738,7 @@ void LLSelectMgr::selectionSetMediaTypeAndURL(U8 media_type, const std::string& U8 media_flags = LLTextureEntry::MF_NONE; if (media_type == LLViewerObject::MEDIA_TYPE_WEB_PAGE) { - media_flags = LLTextureEntry::MF_WEB_PAGE; + media_flags = LLTextureEntry::MF_HAS_MEDIA; } struct f : public LLSelectedTEFunctor