diff options
Diffstat (limited to 'indra/llprimitive/llprimitive.cpp')
-rwxr-xr-x[-rw-r--r--] | indra/llprimitive/llprimitive.cpp | 288 |
1 files changed, 195 insertions, 93 deletions
diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index 258c0c3c15..29747cb09c 100644..100755 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -27,7 +27,6 @@ #include "linden_common.h" #include "material_codes.h" -#include "llmemtype.h" #include "llerror.h" #include "message.h" #include "llprimitive.h" @@ -39,6 +38,7 @@ #include "lldatapacker.h" #include "llsdutil_math.h" #include "llprimtexturelist.h" +#include "llmaterialid.h" /** * exported constants @@ -107,8 +107,6 @@ 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 @@ -126,7 +124,7 @@ void LLPrimitive::setVolumeManager( LLVolumeMgr* volume_manager ) { if ( !volume_manager || sVolumeManager ) { - llerrs << "LLPrimitive::sVolumeManager attempting to be set to NULL or it already has been set." << llendl; + LL_ERRS() << "LLPrimitive::sVolumeManager attempting to be set to NULL or it already has been set." << LL_ENDL; } sVolumeManager = volume_manager; } @@ -149,7 +147,8 @@ bool LLPrimitive::cleanupVolumeManager() LLPrimitive::LLPrimitive() : mTextureList(), mNumTEs(0), - mMiscFlags(0) + mMiscFlags(0), + mNumBumpmapTEs(0) { mPrimitiveCode = 0; @@ -188,7 +187,6 @@ void LLPrimitive::clearTextureList() // static LLPrimitive *LLPrimitive::createPrimitive(LLPCode p_code) { - LLMemType m1(LLMemType::MTYPE_PRIMITIVE); LLPrimitive *retval = new LLPrimitive(); if (retval) @@ -197,7 +195,7 @@ LLPrimitive *LLPrimitive::createPrimitive(LLPCode p_code) } else { - llerrs << "primitive allocation failed" << llendl; + LL_ERRS() << "primitive allocation failed" << LL_ENDL; } return retval; @@ -206,7 +204,6 @@ LLPrimitive *LLPrimitive::createPrimitive(LLPCode p_code) //=============================================================== void LLPrimitive::init_primitive(LLPCode p_code) { - LLMemType m1(LLMemType::MTYPE_PRIMITIVE); clearTextureList(); mPrimitiveCode = p_code; } @@ -237,7 +234,10 @@ void LLPrimitive::setAllTETextures(const LLUUID &tex_id) //=============================================================== void LLPrimitive::setTE(const U8 index, const LLTextureEntry& te) { - mTextureList.copyTexture(index, te); + if(mTextureList.copyTexture(index, te) != TEM_CHANGE_NONE && te.getBumpmap() > 0) + { + mNumBumpmapTEs++; + } } S32 LLPrimitive::setTETexture(const U8 index, const LLUUID &id) @@ -312,10 +312,25 @@ S32 LLPrimitive::setTERotation(const U8 index, const F32 r) return mTextureList.setRotation(index, r); } +S32 LLPrimitive::setTEMaterialID(const U8 index, const LLMaterialID& pMaterialID) +{ + return mTextureList.setMaterialID(index, pMaterialID); +} + +S32 LLPrimitive::setTEMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams) +{ + return mTextureList.setMaterialParams(index, pMaterialParams); +} + +LLMaterialPtr LLPrimitive::getTEMaterialParams(const U8 index) +{ + return mTextureList.getMaterialParams(index); +} //=============================================================== S32 LLPrimitive::setTEBumpShinyFullbright(const U8 index, const U8 bump) { + updateNumBumpmap(index, bump); return mTextureList.setBumpShinyFullbright(index, bump); } @@ -326,11 +341,13 @@ S32 LLPrimitive::setTEMediaTexGen(const U8 index, const U8 media) S32 LLPrimitive::setTEBumpmap(const U8 index, const U8 bump) { + updateNumBumpmap(index, bump); return mTextureList.setBumpMap(index, bump); } S32 LLPrimitive::setTEBumpShiny(const U8 index, const U8 bump_shiny) { + updateNumBumpmap(index, bump_shiny); return mTextureList.setBumpShiny(index, bump_shiny); } @@ -359,6 +376,23 @@ S32 LLPrimitive::setTEGlow(const U8 index, const F32 glow) return mTextureList.setGlow(index, glow); } +void LLPrimitive::setAllTESelected(bool sel) +{ + for (int i = 0, cnt = getNumTEs(); i < cnt; i++) + { + setTESelected(i, sel); + } +} + +void LLPrimitive::setTESelected(const U8 te, bool sel) +{ + LLTextureEntry* tep = getTE(te); + if ( (tep) && (tep->setSelected(sel)) && (!sel) && (tep->hasPendingMaterialUpdate()) ) + { + LLMaterialID material_id = tep->getMaterialID(); + setTEMaterialID(te, material_id); + } +} LLPCode LLPrimitive::legacyToPCode(const U8 legacy) { @@ -452,7 +486,7 @@ LLPCode LLPrimitive::legacyToPCode(const U8 legacy) pcode = LL_PCODE_TREE_NEW; break; default: - llwarns << "Unknown legacy code " << legacy << " [" << (S32)legacy << "]!" << llendl; + LL_WARNS() << "Unknown legacy code " << legacy << " [" << (S32)legacy << "]!" << LL_ENDL; } return pcode; @@ -547,7 +581,7 @@ U8 LLPrimitive::pCodeToLegacy(const LLPCode pcode) legacy = TREE_NEW; break; default: - llwarns << "Unknown pcode " << (S32)pcode << ":" << pcode << "!" << llendl; + LL_WARNS() << "Unknown pcode " << (S32)pcode << ":" << pcode << "!" << LL_ENDL; return 0; } return legacy; @@ -555,7 +589,7 @@ U8 LLPrimitive::pCodeToLegacy(const LLPCode pcode) // static -// Don't crash or llerrs here! This function is used for debug strings. +// Don't crash or LL_ERRS() here! This function is used for debug strings. std::string LLPrimitive::pCodeToString(const LLPCode pcode) { std::string pcode_string; @@ -634,7 +668,7 @@ std::string LLPrimitive::pCodeToString(const LLPCode pcode) } else { - llwarns << "Unknown base mask for pcode: " << base_code << llendl; + LL_WARNS() << "Unknown base mask for pcode: " << base_code << LL_ENDL; } U8 mask_code = pcode & (~LL_PCODE_BASE_MASK); @@ -670,7 +704,7 @@ void LLPrimitive::copyTEs(const LLPrimitive *primitivep) U32 i; if (primitivep->getExpectedNumTEs() != getExpectedNumTEs()) { - llwarns << "Primitives don't have same expected number of TE's" << llendl; + LL_WARNS() << "Primitives don't have same expected number of TE's" << LL_ENDL; } U32 num_tes = llmin(primitivep->getExpectedNumTEs(), getExpectedNumTEs()); if (mTextureList.size() < getExpectedNumTEs()) @@ -698,7 +732,6 @@ S32 face_index_from_id(LLFaceID face_ID, const std::vector<LLProfile::Face>& fac BOOL LLPrimitive::setVolume(const LLVolumeParams &volume_params, const S32 detail, bool unique_volume) { - LLMemType m1(LLMemType::MTYPE_VOLUME); LLVolume *volumep; if (unique_volume) { @@ -738,7 +771,11 @@ BOOL LLPrimitive::setVolume(const LLVolumeParams &volume_params, const S32 detai setNumTEs(mVolumep->getNumFaces()); return TRUE; } - + +#if 0 + // #if 0'd out by davep + // this is a lot of cruft to set texture entry values that just stay the same for LOD switch + // or immediately get overridden by an object update message, also crashes occasionally U32 old_face_mask = mVolumep->mFaceMask; S32 face_bit = 0; @@ -769,7 +806,7 @@ BOOL LLPrimitive::setVolume(const LLVolumeParams &volume_params, const S32 detai { 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; + //LL_INFOS() << face_bit << ":" << te_index << ":" << old_tes[face_bit].getID() << LL_ENDL; } } @@ -789,7 +826,7 @@ BOOL LLPrimitive::setVolume(const LLVolumeParams &volume_params, const S32 detai if (mVolumep->getNumFaces() == 0 && new_face_mask != 0) { - llwarns << "Object with 0 faces found...INCORRECT!" << llendl; + LL_WARNS() << "Object with 0 faces found...INCORRECT!" << LL_ENDL; setNumTEs(mVolumep->getNumFaces()); return TRUE; } @@ -847,7 +884,7 @@ BOOL LLPrimitive::setVolume(const LLVolumeParams &volume_params, const S32 detai } if (i == 4) { - llwarns << "No path end or outer face in volume!" << llendl; + LL_WARNS() << "No path end or outer face in volume!" << LL_ENDL; } continue; } @@ -883,7 +920,7 @@ BOOL LLPrimitive::setVolume(const LLVolumeParams &volume_params, const S32 detai } if (i == 4) { - llwarns << "No path end or outer face in volume!" << llendl; + LL_WARNS() << "No path end or outer face in volume!" << LL_ENDL; } continue; } @@ -909,8 +946,8 @@ BOOL LLPrimitive::setVolume(const LLVolumeParams &volume_params, const S32 detai } if (-1 == min_outer_bit) { - llinfos << (LLVolume *)mVolumep << llendl; - llwarns << "Bad! No outer faces, impossible!" << llendl; + LL_INFOS() << (LLVolume *)mVolumep << LL_ENDL; + LL_WARNS() << "Bad! No outer faces, impossible!" << LL_ENDL; } face_mapping[face_bit] = min_outer_bit; } @@ -929,13 +966,20 @@ BOOL LLPrimitive::setVolume(const LLVolumeParams &volume_params, const S32 detai { if (-1 == face_mapping[face_bit]) { - llwarns << "No mapping from old face to new face!" << llendl; + LL_WARNS() << "No mapping from old face to new face!" << LL_ENDL; } S32 te_num = face_index_from_id(cur_mask, mVolumep->getProfile().mFaces); setTE(te_num, *(old_tes.getTexture(face_mapping[face_bit]))); } } +#else + // build the new object + sVolumeManager->unrefVolume(mVolumep); + mVolumep = volumep; + + setNumTEs(mVolumep->getNumFaces()); +#endif return TRUE; } @@ -952,8 +996,6 @@ BOOL LLPrimitive::setMaterial(U8 material) } } -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 { S32 face_index; @@ -1029,7 +1071,7 @@ S32 LLPrimitive::unpackTEField(U8 *cur_ptr, U8 *buffer_end, U8 *data_ptr, U8 dat while ((cur_ptr < buffer_end) && (*cur_ptr != 0)) { -// llinfos << "TE exception" << llendl; + LL_DEBUGS("TEFieldDecode") << "TE exception" << LL_ENDL; i = 0; while (*cur_ptr & 0x80) { @@ -1044,14 +1086,16 @@ S32 LLPrimitive::unpackTEField(U8 *cur_ptr, U8 *buffer_end, U8 *data_ptr, U8 dat if (i & 0x01) { htonmemcpy(data_ptr+(j*data_size),cur_ptr,type,data_size); -// char foo[64]; -// sprintf(foo,"%x %x",*(data_ptr+(j*data_size)), *(data_ptr+(j*data_size)+1)); -// llinfos << "Assigning " << foo << " to face " << j << llendl; + LL_DEBUGS("TEFieldDecode") << "Assigning " ; + char foo[64]; + sprintf(foo,"%x %x",*(data_ptr+(j*data_size)), *(data_ptr+(j*data_size)+1)); + LL_CONT << foo << " to face " << j << LL_ENDL; } i = i >> 1; } cur_ptr += data_size; } + llassert(cur_ptr <= buffer_end); // buffer underrun return (S32)(cur_ptr - start_loc); } @@ -1073,12 +1117,13 @@ BOOL LLPrimitive::packTEMessage(LLMessageSystem *mesgsys) const U8 bump[MAX_TES]; U8 media_flags[MAX_TES]; U8 glow[MAX_TES]; + U8 material_data[MAX_TES*16]; const U32 MAX_TE_BUFFER = 4096; U8 packed_buffer[MAX_TE_BUFFER]; U8 *cur_ptr = packed_buffer; - S32 last_face_index = getNumTEs() - 1; + S32 last_face_index = llmin((U32) getNumTEs(), MAX_TES) - 1; if (last_face_index > -1) { @@ -1104,12 +1149,15 @@ BOOL LLPrimitive::packTEMessage(LLMessageSystem *mesgsys) const const LLTextureEntry* te = getTE(face_index); scale_s[face_index] = (F32) te->mScaleS; 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) * TEXTURE_ROTATION_PACK_FACTOR)); + offset_s[face_index] = (S16) ll_round((llclamp(te->mOffsetS,-1.0f,1.0f) * (F32)0x7FFF)) ; + offset_t[face_index] = (S16) ll_round((llclamp(te->mOffsetT,-1.0f,1.0f) * (F32)0x7FFF)) ; + image_rot[face_index] = (S16) ll_round(((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)); + glow[face_index] = (U8) ll_round((llclamp(te->getGlow(), 0.0f, 1.0f) * (F32)0xFF)); + + // Directly sending material_ids is not safe! + memcpy(&material_data[face_index*16],getTE(face_index)->getMaterialID().get(),16); /* Flawfinder: ignore */ } cur_ptr += packTEField(cur_ptr, (U8 *)image_ids, sizeof(LLUUID),last_face_index, MVT_LLUUID); @@ -1131,6 +1179,8 @@ BOOL LLPrimitive::packTEMessage(LLMessageSystem *mesgsys) const cur_ptr += packTEField(cur_ptr, (U8 *)media_flags, 1 ,last_face_index, MVT_U8); *cur_ptr++ = 0; cur_ptr += packTEField(cur_ptr, (U8 *)glow, 1 ,last_face_index, MVT_U8); + *cur_ptr++ = 0; + cur_ptr += packTEField(cur_ptr, (U8 *)material_data, 16, last_face_index, MVT_LLUUID); } mesgsys->addBinaryDataFast(_PREHASH_TextureEntry, packed_buffer, (S32)(cur_ptr - packed_buffer)); @@ -1152,6 +1202,7 @@ BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const U8 bump[MAX_TES]; U8 media_flags[MAX_TES]; U8 glow[MAX_TES]; + U8 material_data[MAX_TES*16]; const U32 MAX_TE_BUFFER = 4096; U8 packed_buffer[MAX_TE_BUFFER]; @@ -1183,12 +1234,15 @@ BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const const LLTextureEntry* te = getTE(face_index); scale_s[face_index] = (F32) te->mScaleS; 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) * TEXTURE_ROTATION_PACK_FACTOR)); + offset_s[face_index] = (S16) ll_round((llclamp(te->mOffsetS,-1.0f,1.0f) * (F32)0x7FFF)) ; + offset_t[face_index] = (S16) ll_round((llclamp(te->mOffsetT,-1.0f,1.0f) * (F32)0x7FFF)) ; + image_rot[face_index] = (S16) ll_round(((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)); + glow[face_index] = (U8) ll_round((llclamp(te->getGlow(), 0.0f, 1.0f) * (F32)0xFF)); + + // Directly sending material_ids is not safe! + memcpy(&material_data[face_index*16],getTE(face_index)->getMaterialID().get(),16); /* Flawfinder: ignore */ } cur_ptr += packTEField(cur_ptr, (U8 *)image_ids, sizeof(LLUUID),last_face_index, MVT_LLUUID); @@ -1210,100 +1264,106 @@ BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const cur_ptr += packTEField(cur_ptr, (U8 *)media_flags, 1 ,last_face_index, MVT_U8); *cur_ptr++ = 0; cur_ptr += packTEField(cur_ptr, (U8 *)glow, 1 ,last_face_index, MVT_U8); + *cur_ptr++ = 0; + cur_ptr += packTEField(cur_ptr, (U8 *)material_data, 16, last_face_index, MVT_LLUUID); } dp.packBinaryData(packed_buffer, (S32)(cur_ptr - packed_buffer), "TextureEntry"); return FALSE; } -S32 LLPrimitive::unpackTEMessage(LLMessageSystem *mesgsys, char *block_name) -{ - return(unpackTEMessage(mesgsys,block_name,-1)); -} - -S32 LLPrimitive::unpackTEMessage(LLMessageSystem *mesgsys, char *block_name, const S32 block_num) +S32 LLPrimitive::parseTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num, LLTEContents& tec) { - // use a negative block_num to indicate a single-block read (a non-variable block) S32 retval = 0; - const U32 MAX_TES = 32; - - // Avoid construction of 32 UUIDs per call. JC - - U8 image_data[MAX_TES*16]; - U8 colors[MAX_TES*4]; - F32 scale_s[MAX_TES]; - F32 scale_t[MAX_TES]; - S16 offset_s[MAX_TES]; - S16 offset_t[MAX_TES]; - S16 image_rot[MAX_TES]; - U8 bump[MAX_TES]; - U8 media_flags[MAX_TES]; - U8 glow[MAX_TES]; - - const U32 MAX_TE_BUFFER = 4096; - U8 packed_buffer[MAX_TE_BUFFER]; - U8 *cur_ptr = packed_buffer; - - U32 size; - U32 face_count = 0; + // temp buffer for material ID processing + // data will end up in tec.material_id[] + U8 material_data[LLTEContents::MAX_TES*16]; if (block_num < 0) { - size = mesgsys->getSizeFast(block_name, _PREHASH_TextureEntry); + tec.size = mesgsys->getSizeFast(block_name, _PREHASH_TextureEntry); } else { - size = mesgsys->getSizeFast(block_name, block_num, _PREHASH_TextureEntry); + tec.size = mesgsys->getSizeFast(block_name, block_num, _PREHASH_TextureEntry); } - if (size == 0) + if (tec.size == 0) { + tec.face_count = 0; return retval; } if (block_num < 0) { - mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, packed_buffer, 0, 0, MAX_TE_BUFFER); + mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, tec.packed_buffer, 0, 0, LLTEContents::MAX_TE_BUFFER); } else { - mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, packed_buffer, 0, block_num, MAX_TE_BUFFER); + mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, tec.packed_buffer, 0, block_num, LLTEContents::MAX_TE_BUFFER); } - face_count = getNumTEs(); + tec.face_count = llmin((U32)getNumTEs(),(U32)LLTEContents::MAX_TES); - cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)image_data, 16, face_count, MVT_LLUUID); + U8 *cur_ptr = tec.packed_buffer; + cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.image_data, 16, tec.face_count, MVT_LLUUID); cur_ptr++; - cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)colors, 4, face_count, MVT_U8); + cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.colors, 4, tec.face_count, MVT_U8); cur_ptr++; - cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)scale_s, 4, face_count, MVT_F32); + cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.scale_s, 4, tec.face_count, MVT_F32); cur_ptr++; - cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)scale_t, 4, face_count, MVT_F32); + cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.scale_t, 4, tec.face_count, MVT_F32); cur_ptr++; - cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)offset_s, 2, face_count, MVT_S16Array); + cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.offset_s, 2, tec.face_count, MVT_S16Array); cur_ptr++; - cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)offset_t, 2, face_count, MVT_S16Array); + cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.offset_t, 2, tec.face_count, MVT_S16Array); cur_ptr++; - cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)image_rot, 2, face_count, MVT_S16Array); + cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.image_rot, 2, tec.face_count, MVT_S16Array); cur_ptr++; - cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)bump, 1, face_count, MVT_U8); + cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.bump, 1, tec.face_count, MVT_U8); cur_ptr++; - cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)media_flags, 1, face_count, MVT_U8); + cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.media_flags, 1, tec.face_count, MVT_U8); cur_ptr++; - cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)glow, 1, face_count, MVT_U8); + cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.glow, 1, tec.face_count, MVT_U8); + + if (cur_ptr < tec.packed_buffer + tec.size) + { + cur_ptr++; + cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)material_data, 16, tec.face_count, MVT_LLUUID); + } + else + { + memset(material_data, 0, sizeof(material_data)); + } + + for (U32 i = 0; i < tec.face_count; i++) + { + tec.material_ids[i].set(&material_data[i * 16]); + } + + retval = 1; + return retval; + } + +S32 LLPrimitive::applyParsedTEMessage(LLTEContents& tec) +{ + S32 retval = 0; LLColor4 color; LLColor4U coloru; - for (U32 i = 0; i < face_count; i++) + for (U32 i = 0; i < tec.face_count; i++) { - 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] / 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); - coloru = LLColor4U(colors + 4*i); + LLUUID& req_id = ((LLUUID*)tec.image_data)[i]; + retval |= setTETexture(i, req_id); + retval |= setTEScale(i, tec.scale_s[i], tec.scale_t[i]); + retval |= setTEOffset(i, (F32)tec.offset_s[i] / (F32)0x7FFF, (F32) tec.offset_t[i] / (F32) 0x7FFF); + retval |= setTERotation(i, ((F32)tec.image_rot[i] / TEXTURE_ROTATION_PACK_FACTOR) * F_TWO_PI); + retval |= setTEBumpShinyFullbright(i, tec.bump[i]); + retval |= setTEMediaTexGen(i, tec.media_flags[i]); + retval |= setTEGlow(i, (F32)tec.glow[i] / (F32)0xFF); + retval |= setTEMaterialID(i, tec.material_ids[i]); + + coloru = LLColor4U(tec.colors + 4*i); // Note: This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f) // as all zeros. However, the subtraction and addition must be done in unsigned @@ -1320,6 +1380,15 @@ S32 LLPrimitive::unpackTEMessage(LLMessageSystem *mesgsys, char *block_name, con return retval; } +S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num) +{ + LLTEContents tec; + S32 retval = parseTEMessage(mesgsys, block_name, block_num, tec); + if (!retval) + return retval; + return applyParsedTEMessage(tec); +} + S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp) { // use a negative block_num to indicate a single-block read (a non-variable block) @@ -1328,6 +1397,7 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp) // Avoid construction of 32 UUIDs per call static LLUUID image_ids[MAX_TES]; + static LLMaterialID material_ids[MAX_TES]; U8 image_data[MAX_TES*16]; U8 colors[MAX_TES*4]; @@ -1339,6 +1409,7 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp) U8 bump[MAX_TES]; U8 media_flags[MAX_TES]; U8 glow[MAX_TES]; + U8 material_data[MAX_TES*16]; const U32 MAX_TE_BUFFER = 4096; U8 packed_buffer[MAX_TE_BUFFER]; @@ -1350,7 +1421,7 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp) if (!dp.unpackBinaryData(packed_buffer, size, "TextureEntry")) { retval = TEM_INVALID; - llwarns << "Bad texture entry block! Abort!" << llendl; + LL_WARNS() << "Bad texture entry block! Abort!" << LL_ENDL; return retval; } @@ -1359,7 +1430,7 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp) return retval; } - face_count = getNumTEs(); + face_count = llmin((U32) getNumTEs(), MAX_TES); U32 i; cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)image_data, 16, face_count, MVT_LLUUID); @@ -1381,10 +1452,20 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp) cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)media_flags, 1, face_count, MVT_U8); cur_ptr++; cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)glow, 1, face_count, MVT_U8); + if (cur_ptr < packed_buffer + size) + { + cur_ptr++; + cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)material_data, 16, face_count, MVT_LLUUID); + } + else + { + memset(material_data, 0, sizeof(material_data)); + } for (i = 0; i < face_count; i++) { memcpy(image_ids[i].mData,&image_data[i*16],16); /* Flawfinder: ignore */ + material_ids[i].set(&material_data[i * 16]); } LLColor4 color; @@ -1398,6 +1479,7 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp) retval |= setTEBumpShinyFullbright(i, bump[i]); retval |= setTEMediaTexGen(i, media_flags[i]); retval |= setTEGlow(i, (F32)glow[i] / (F32)0xFF); + retval |= setTEMaterialID(i, material_ids[i]); coloru = LLColor4U(colors + 4*i); // Note: This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f) @@ -1434,6 +1516,26 @@ void LLPrimitive::takeTextureList(LLPrimTextureList& other_list) mTextureList.take(other_list); } +void LLPrimitive::updateNumBumpmap(const U8 index, const U8 bump) +{ + LLTextureEntry* te = getTE(index); + if(!te) + { + return; + } + + U8 old_bump = te->getBumpmap(); + if(old_bump > 0) + { + mNumBumpmapTEs--; + } + if((bump & TEM_BUMP_MASK) > 0) + { + mNumBumpmapTEs++; + } + + return; +} //============================================================================ // Moved from llselectmgr.cpp |