aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llvoavatar.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/newview/llvoavatar.cpp')
-rw-r--r--linden/indra/newview/llvoavatar.cpp98
1 files changed, 34 insertions, 64 deletions
diff --git a/linden/indra/newview/llvoavatar.cpp b/linden/indra/newview/llvoavatar.cpp
index cd90c59..6522a8b 100644
--- a/linden/indra/newview/llvoavatar.cpp
+++ b/linden/indra/newview/llvoavatar.cpp
@@ -704,7 +704,6 @@ BOOL LLVOAvatar::sDebugInvisible = FALSE;
704BOOL LLVOAvatar::sShowAttachmentPoints = FALSE; 704BOOL LLVOAvatar::sShowAttachmentPoints = FALSE;
705BOOL LLVOAvatar::sShowAnimationDebug = FALSE; 705BOOL LLVOAvatar::sShowAnimationDebug = FALSE;
706BOOL LLVOAvatar::sShowFootPlane = FALSE; 706BOOL LLVOAvatar::sShowFootPlane = FALSE;
707BOOL LLVOAvatar::sShowCollisionVolumes = FALSE;
708BOOL LLVOAvatar::sVisibleInFirstPerson = FALSE; 707BOOL LLVOAvatar::sVisibleInFirstPerson = FALSE;
709F32 LLVOAvatar::sLODFactor = 1.f; 708F32 LLVOAvatar::sLODFactor = 1.f;
710BOOL LLVOAvatar::sUseImpostors = FALSE; 709BOOL LLVOAvatar::sUseImpostors = FALSE;
@@ -741,7 +740,6 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
741 mTyping(FALSE), 740 mTyping(FALSE),
742 mMeshValid(FALSE), 741 mMeshValid(FALSE),
743 mVisible(FALSE), 742 mVisible(FALSE),
744 mMeshTexturesDirty(FALSE),
745 mWindFreq(0.f), 743 mWindFreq(0.f),
746 mRipplePhase( 0.f ), 744 mRipplePhase( 0.f ),
747 mBelowWater(FALSE), 745 mBelowWater(FALSE),
@@ -802,7 +800,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
802 mBakedTextureData[i].mLastTextureIndex = IMG_DEFAULT_AVATAR; 800 mBakedTextureData[i].mLastTextureIndex = IMG_DEFAULT_AVATAR;
803 mBakedTextureData[i].mTexLayerSet = NULL; 801 mBakedTextureData[i].mTexLayerSet = NULL;
804 mBakedTextureData[i].mIsLoaded = false; 802 mBakedTextureData[i].mIsLoaded = false;
805 //mBakedTextureData[i].mIsUsed = false; // KL SG 803 mBakedTextureData[i].mIsUsed = false;
806 mBakedTextureData[i].mMaskTexName = 0; 804 mBakedTextureData[i].mMaskTexName = 0;
807 mBakedTextureData[i].mTextureIndex = getTextureIndex((EBakedTextureIndex)i); 805 mBakedTextureData[i].mTextureIndex = getTextureIndex((EBakedTextureIndex)i);
808 } 806 }
@@ -858,11 +856,9 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
858 mRippleTimeLast = 0.f; 856 mRippleTimeLast = 0.f;
859 857
860 mShadowImagep = gImageList.getImageFromFile("foot_shadow.j2c"); 858 mShadowImagep = gImageList.getImageFromFile("foot_shadow.j2c");
861 859 gGL.getTexUnit(0)->bind(mShadowImagep.get());
862 // GL NOT ACTIVE HERE 860 mShadowImagep->setAddressMode(LLTexUnit::TAM_CLAMP);
863 //gGL.getTexUnit(0)->bind(mShadowImagep.get()); 861
864 //mShadowImagep->setAddressMode(LLTexUnit::TAM_CLAMP);
865
866 mInAir = FALSE; 862 mInAir = FALSE;
867 863
868 mStepOnLand = TRUE; 864 mStepOnLand = TRUE;
@@ -1299,7 +1295,7 @@ void LLVOAvatar::resetImpostors()
1299// static 1295// static
1300void LLVOAvatar::deleteCachedImages(bool clearAll) 1296void LLVOAvatar::deleteCachedImages(bool clearAll)
1301{ 1297{
1302/* if(gAuditTexture) 1298if(gAuditTexture)
1303 { 1299 {
1304 S32 total_tex_size = sScratchTexBytes ; 1300 S32 total_tex_size = sScratchTexBytes ;
1305 S32 tex_size = SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT ; 1301 S32 tex_size = SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT ;
@@ -1341,7 +1337,7 @@ void LLVOAvatar::deleteCachedImages(bool clearAll)
1341 total_tex_size -= 4 * tex_size ; 1337 total_tex_size -= 4 * tex_size ;
1342 } 1338 }
1343 } 1339 }
1344*/ 1340
1345 if (LLTexLayerSet::sHasCaches) 1341 if (LLTexLayerSet::sHasCaches)
1346 { 1342 {
1347 lldebugs << "Deleting layer set caches" << llendl; 1343 lldebugs << "Deleting layer set caches" << llendl;
@@ -1866,11 +1862,6 @@ BOOL LLVOAvatar::buildSkeleton(const LLVOAvatarSkeletonInfo *info)
1866 return TRUE; 1862 return TRUE;
1867} 1863}
1868 1864
1869LLVOAvatar* LLVOAvatar::asAvatar() // KL SD
1870{
1871 return this;
1872}
1873
1874//----------------------------------------------------------------------------- 1865//-----------------------------------------------------------------------------
1875// LLVOAvatar::startDefaultMotions() 1866// LLVOAvatar::startDefaultMotions()
1876//----------------------------------------------------------------------------- 1867//-----------------------------------------------------------------------------
@@ -1933,7 +1924,7 @@ void LLVOAvatar::buildCharacter()
1933 LLTimer timer; 1924 LLTimer timer;
1934 1925
1935 BOOL status = loadAvatar(); 1926 BOOL status = loadAvatar();
1936 // stop_glerror(); 1927 stop_glerror();
1937 1928
1938 if (gNoRender) 1929 if (gNoRender)
1939 { 1930 {
@@ -2043,7 +2034,7 @@ void LLVOAvatar::buildCharacter()
2043 processAnimationStateChanges(); 2034 processAnimationStateChanges();
2044 2035
2045 mIsBuilt = TRUE; 2036 mIsBuilt = TRUE;
2046// stop_glerror(); 2037 stop_glerror();
2047 2038
2048 //------------------------------------------------------------------------- 2039 //-------------------------------------------------------------------------
2049 // build the attach and detach menus 2040 // build the attach and detach menus
@@ -5050,7 +5041,7 @@ U32 LLVOAvatar::renderImpostor(LLColor4U color)
5050//------------------------------------------------------------------------ 5041//------------------------------------------------------------------------
5051// LLVOAvatar::updateTextures() 5042// LLVOAvatar::updateTextures()
5052//------------------------------------------------------------------------ 5043//------------------------------------------------------------------------
5053void LLVOAvatar::updateTextures(LLAgent &agent) // KL SD version 5044void LLVOAvatar::updateTextures()
5054{ 5045{
5055 BOOL render_avatar = TRUE; 5046 BOOL render_avatar = TRUE;
5056 5047
@@ -5069,7 +5060,6 @@ void LLVOAvatar::updateTextures(LLAgent &agent) // KL SD version
5069 } 5060 }
5070 5061
5071 std::vector<bool> layer_baked; 5062 std::vector<bool> layer_baked;
5072 // GL NOT ACTIVE HERE - *TODO
5073 for (U32 i = 0; i < mBakedTextureData.size(); i++) 5063 for (U32 i = 0; i < mBakedTextureData.size(); i++)
5074 { 5064 {
5075 layer_baked.push_back(isTextureDefined(mBakedTextureData[i].mTextureIndex)); 5065 layer_baked.push_back(isTextureDefined(mBakedTextureData[i].mTextureIndex));
@@ -5152,7 +5142,13 @@ void LLVOAvatar::updateTextures(LLAgent &agent) // KL SD version
5152 if (texture_dict->mIsLocalTexture) 5142 if (texture_dict->mIsLocalTexture)
5153 { 5143 {
5154 addLocalTextureStats((ETextureIndex)index, imagep, texel_area_ratio, render_avatar, layer_baked[baked_index]); 5144 addLocalTextureStats((ETextureIndex)index, imagep, texel_area_ratio, render_avatar, layer_baked[baked_index]);
5145 // SNOW-8 : temporary snowglobe1.0 fix for baked textures
5146 if (render_avatar && !gGLManager.mIsDisabled )
5147 {
5148 // bind the texture so that its boost level won't be slammed
5149 gGL.getTexUnit(0)->bind(imagep);
5155 } 5150 }
5151 }
5156 else if (texture_dict->mIsBakedTexture) 5152 else if (texture_dict->mIsBakedTexture)
5157 { 5153 {
5158 if (layer_baked[baked_index]) 5154 if (layer_baked[baked_index])
@@ -5398,7 +5394,7 @@ void LLVOAvatar::processAnimationStateChanges()
5398 } 5394 }
5399 } 5395 }
5400 5396
5401 //stop_glerror(); 5397 stop_glerror();
5402} 5398}
5403 5399
5404 5400
@@ -6383,15 +6379,6 @@ LLDrawable *LLVOAvatar::createDrawable(LLPipeline *pipeline)
6383} 6379}
6384 6380
6385 6381
6386void LLVOAvatar::updateGL()
6387{
6388 if (mMeshTexturesDirty)
6389 {
6390 updateMeshTextures();
6391 mMeshTexturesDirty = FALSE;
6392 }
6393}
6394
6395//----------------------------------------------------------------------------- 6382//-----------------------------------------------------------------------------
6396// updateGeometry() 6383// updateGeometry()
6397//----------------------------------------------------------------------------- 6384//-----------------------------------------------------------------------------
@@ -7429,20 +7416,12 @@ BOOL LLVOAvatar::bindScratchTexture( LLGLenum format )
7429 if( *last_bind_time != LLImageGL::sLastFrameTime ) 7416 if( *last_bind_time != LLImageGL::sLastFrameTime )
7430 { 7417 {
7431 *last_bind_time = LLImageGL::sLastFrameTime; 7418 *last_bind_time = LLImageGL::sLastFrameTime;
7432// #if !LL_RELEASE_FOR_DOWNLOAD 7419 LLImageGL::updateBoundTexMemStatic(texture_bytes, SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT, LLViewerImageBoostLevel::AVATAR_SCRATCH_TEX) ;
7433// LLImageGL::updateBoundTexMem(texture_bytes, SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT) ;
7434// #else
7435 LLImageGL::updateBoundTexMem(texture_bytes);
7436// #endif
7437 } 7420 }
7438 } 7421 }
7439 else 7422 else
7440 { 7423 {
7441// #if !LL_RELEASE_FOR_DOWNLOAD 7424 LLImageGL::updateBoundTexMemStatic(texture_bytes, SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT, LLViewerImageBoostLevel::AVATAR_SCRATCH_TEX) ;
7442// LLImageGL::updateBoundTexMem(texture_bytes, SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT) ;
7443// #else
7444 LLImageGL::updateBoundTexMem(texture_bytes);
7445// #endif
7446 LLVOAvatar::sScratchTexLastBindTime.addData( format, new F32(LLImageGL::sLastFrameTime) ); 7425 LLVOAvatar::sScratchTexLastBindTime.addData( format, new F32(LLImageGL::sLastFrameTime) );
7447 } 7426 }
7448 7427
@@ -7464,8 +7443,7 @@ LLGLuint LLVOAvatar::getScratchTexName( LLGLenum format, U32* texture_bytes )
7464 { 7443 {
7465 case GL_LUMINANCE: components = 1; internal_format = GL_LUMINANCE8; break; 7444 case GL_LUMINANCE: components = 1; internal_format = GL_LUMINANCE8; break;
7466 case GL_ALPHA: components = 1; internal_format = GL_ALPHA8; break; 7445 case GL_ALPHA: components = 1; internal_format = GL_ALPHA8; break;
7467// Support for GL_EXT_paletted_texture is deprecated 7446 case GL_COLOR_INDEX: components = 1; internal_format = GL_COLOR_INDEX8_EXT; break;
7468// case GL_COLOR_INDEX: components = 1; internal_format = GL_COLOR_INDEX8_EXT; break;
7469 case GL_LUMINANCE_ALPHA: components = 2; internal_format = GL_LUMINANCE8_ALPHA8; break; 7447 case GL_LUMINANCE_ALPHA: components = 2; internal_format = GL_LUMINANCE8_ALPHA8; break;
7470 case GL_RGB: components = 3; internal_format = GL_RGB8; break; 7448 case GL_RGB: components = 3; internal_format = GL_RGB8; break;
7471 case GL_RGBA: components = 4; internal_format = GL_RGBA8; break; 7449 case GL_RGBA: components = 4; internal_format = GL_RGBA8; break;
@@ -7507,11 +7485,11 @@ LLGLuint LLVOAvatar::getScratchTexName( LLGLenum format, U32* texture_bytes )
7507 7485
7508 LLVOAvatar::sScratchTexBytes += *texture_bytes; 7486 LLVOAvatar::sScratchTexBytes += *texture_bytes;
7509 LLImageGL::sGlobalTextureMemoryInBytes += *texture_bytes; 7487 LLImageGL::sGlobalTextureMemoryInBytes += *texture_bytes;
7510/* 7488
7511 if(gAuditTexture) 7489 if(gAuditTexture)
7512 { 7490 {
7513 LLImageGL::incTextureCounterStatic(SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT, components, LLViewerImageBoostLevel::AVATAR_SCRATCH_TEX) ; 7491 LLImageGL::incTextureCounterStatic(SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT, components, LLViewerImageBoostLevel::AVATAR_SCRATCH_TEX) ;
7514 }*/ 7492 }
7515 7493
7516 return name; 7494 return name;
7517 } 7495 }
@@ -7614,7 +7592,6 @@ void LLVOAvatar::updateMeshTextures()
7614 use_lkg_baked_layer[i] = (!is_layer_baked[i] 7592 use_lkg_baked_layer[i] = (!is_layer_baked[i]
7615 && (mBakedTextureData[i].mLastTextureIndex != IMG_DEFAULT_AVATAR) 7593 && (mBakedTextureData[i].mLastTextureIndex != IMG_DEFAULT_AVATAR)
7616 && mBakedTextureData[i].mTexLayerSet 7594 && mBakedTextureData[i].mTexLayerSet
7617 && mBakedTextureData[i].mTexLayerSet->getComposite() // KL SD
7618 && !mBakedTextureData[i].mTexLayerSet->getComposite()->isInitialized()); 7595 && !mBakedTextureData[i].mTexLayerSet->getComposite()->isInitialized());
7619 if (use_lkg_baked_layer[i]) 7596 if (use_lkg_baked_layer[i])
7620 { 7597 {
@@ -7648,7 +7625,7 @@ void LLVOAvatar::updateMeshTextures()
7648 if (use_lkg_baked_layer[i] && !self_customizing ) 7625 if (use_lkg_baked_layer[i] && !self_customizing )
7649 { 7626 {
7650 LLViewerImage* baked_img = gImageList.getImageFromHost( mBakedTextureData[i].mLastTextureIndex, target_host ); 7627 LLViewerImage* baked_img = gImageList.getImageFromHost( mBakedTextureData[i].mLastTextureIndex, target_host );
7651 //mBakedTextureData[i].mIsUsed = TRUE; 7628 mBakedTextureData[i].mIsUsed = TRUE;
7652 for (U32 k=0; k < mBakedTextureData[i].mMeshes.size(); k++) 7629 for (U32 k=0; k < mBakedTextureData[i].mMeshes.size(); k++)
7653 { 7630 {
7654 mBakedTextureData[i].mMeshes[k]->setTexture( baked_img ); 7631 mBakedTextureData[i].mMeshes[k]->setTexture( baked_img );
@@ -7678,7 +7655,7 @@ void LLVOAvatar::updateMeshTextures()
7678 { 7655 {
7679 mBakedTextureData[i].mTexLayerSet->createComposite(); 7656 mBakedTextureData[i].mTexLayerSet->createComposite();
7680 mBakedTextureData[i].mTexLayerSet->setUpdatesEnabled( TRUE ); 7657 mBakedTextureData[i].mTexLayerSet->setUpdatesEnabled( TRUE );
7681 // mBakedTextureData[i].mIsUsed = FALSE; 7658 mBakedTextureData[i].mIsUsed = FALSE;
7682 for (U32 k=0; k < mBakedTextureData[i].mMeshes.size(); k++) 7659 for (U32 k=0; k < mBakedTextureData[i].mMeshes.size(); k++)
7683 { 7660 {
7684 mBakedTextureData[i].mMeshes[k]->setLayerSet( mBakedTextureData[i].mTexLayerSet ); 7661 mBakedTextureData[i].mMeshes[k]->setLayerSet( mBakedTextureData[i].mTexLayerSet );
@@ -7699,13 +7676,9 @@ void LLVOAvatar::updateMeshTextures()
7699 mBakedTextureData[BAKED_HAIR].mMeshes[i]->setTexture( hair_img ); 7676 mBakedTextureData[BAKED_HAIR].mMeshes[i]->setTexture( hair_img );
7700 } 7677 }
7701 mHasBakedHair = FALSE; 7678 mHasBakedHair = FALSE;
7702 }
7703 else
7704 {
7705 for (U32 i = 0; i < mBakedTextureData[BAKED_HAIR].mMeshes.size(); i++)
7706 {
7707 mBakedTextureData[BAKED_HAIR].mMeshes[i]->setColor( 1.f, 1.f, 1.f, 1.f );
7708 } 7679 }
7680 else
7681 {
7709 mHasBakedHair = TRUE; 7682 mHasBakedHair = TRUE;
7710 } 7683 }
7711 7684
@@ -7837,7 +7810,7 @@ void LLVOAvatar::clearChat()
7837S32 LLVOAvatar::getLocalDiscardLevel( ETextureIndex index ) 7810S32 LLVOAvatar::getLocalDiscardLevel( ETextureIndex index )
7838{ 7811{
7839 // If the texture is not local, we don't care and treat it as fully loaded 7812 // If the texture is not local, we don't care and treat it as fully loaded
7840 if (!isIndexLocalTexture(index)) return FALSE; // KL SD version 7813 if (!isIndexLocalTexture(index)) return 0;
7841 7814
7842 LocalTextureData &local_tex_data = mLocalTextureData[index]; 7815 LocalTextureData &local_tex_data = mLocalTextureData[index];
7843 if (index >= 0 7816 if (index >= 0
@@ -7979,7 +7952,7 @@ bool LLVOAvatar::hasPendingBakedUploads()
7979{ 7952{
7980 for (U32 i = 0; i < mBakedTextureData.size(); i++) 7953 for (U32 i = 0; i < mBakedTextureData.size(); i++)
7981 { 7954 {
7982 bool upload_pending = (mBakedTextureData[i].mTexLayerSet && mBakedTextureData[i].mTexLayerSet->getComposite() && mBakedTextureData[i].mTexLayerSet->getComposite()->uploadPending()); 7955 bool upload_pending = (mBakedTextureData[i].mTexLayerSet && mBakedTextureData[i].mTexLayerSet->getComposite()->uploadPending());
7983 if (upload_pending) 7956 if (upload_pending)
7984 { 7957 {
7985 return true; 7958 return true;
@@ -8514,8 +8487,7 @@ void LLVOAvatar::onFirstTEMessageReceived()
8514 } 8487 }
8515 } 8488 }
8516 8489
8517 mMeshTexturesDirty = TRUE; // updateMeshTextures(); 8490 updateMeshTextures();
8518 gPipeline.markGLRebuild(this);
8519 } 8491 }
8520} 8492}
8521 8493
@@ -8578,22 +8550,20 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
8578 // (isTextureDefined(TEX_SKIRT_BAKED) ? "SKIRT " : "skirt " ) << (getTEImage(TEX_SKIRT_BAKED)->getID()) << std::endl << 8550 // (isTextureDefined(TEX_SKIRT_BAKED) ? "SKIRT " : "skirt " ) << (getTEImage(TEX_SKIRT_BAKED)->getID()) << std::endl <<
8579 // (isTextureDefined(TEX_HAIR_BAKED) ? "HAIR" : "hair " ) << (getTEImage(TEX_HAIR_BAKED)->getID()) << std::endl << 8551 // (isTextureDefined(TEX_HAIR_BAKED) ? "HAIR" : "hair " ) << (getTEImage(TEX_HAIR_BAKED)->getID()) << std::endl <<
8580 // (isTextureDefined(TEX_EYES_BAKED) ? "EYES" : "eyes" ) << (getTEImage(TEX_EYES_BAKED)->getID()) << llendl ; 8552 // (isTextureDefined(TEX_EYES_BAKED) ? "EYES" : "eyes" ) << (getTEImage(TEX_EYES_BAKED)->getID()) << llendl ;
8581 8553
8582 if( !mFirstTEMessageReceived ) 8554 if( !mFirstTEMessageReceived )
8583 { 8555 {
8584 onFirstTEMessageReceived(); 8556 onFirstTEMessageReceived();
8585 } 8557 }
8586 8558
8587 setCompositeUpdatesEnabled( FALSE ); 8559 setCompositeUpdatesEnabled( FALSE );
8588 mMeshTexturesDirty = TRUE;
8589 gPipeline.markGLRebuild(this); // KL SD needing work in S19?
8590 8560
8591 if (!mIsSelf) 8561 if (!mIsSelf)
8592 { 8562 {
8593 releaseUnnecessaryTextures(); 8563 releaseUnnecessaryTextures();
8594 } 8564 }
8595 8565
8596 //updateMeshTextures(); // enables updates for laysets without baked textures. 8566 updateMeshTextures(); // enables updates for laysets without baked textures.
8597 8567
8598 // parse visual params 8568 // parse visual params
8599 S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_VisualParam); 8569 S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_VisualParam);
@@ -8879,7 +8849,7 @@ void LLVOAvatar::useBakedTexture( const LLUUID& id )
8879 if (id == image_baked->getID()) 8849 if (id == image_baked->getID())
8880 { 8850 {
8881 mBakedTextureData[i].mIsLoaded = true; 8851 mBakedTextureData[i].mIsLoaded = true;
8882 //mBakedTextureData[i].mIsUsed = true; 8852 mBakedTextureData[i].mIsUsed = true;
8883 mBakedTextureData[i].mLastTextureIndex = id; 8853 mBakedTextureData[i].mLastTextureIndex = id;
8884 for (U32 k = 0; k < mBakedTextureData[i].mMeshes.size(); k++) 8854 for (U32 k = 0; k < mBakedTextureData[i].mMeshes.size(); k++)
8885 { 8855 {
@@ -9788,9 +9758,9 @@ BOOL LLVOAvatar::updateLOD()
9788 9758
9789 LLFace* facep = mDrawable->getFace(0); 9759 LLFace* facep = mDrawable->getFace(0);
9790 if (facep->mVertexBuffer.isNull() || 9760 if (facep->mVertexBuffer.isNull() ||
9791 (LLVertexBuffer::sEnableVBOs && 9761 LLVertexBuffer::sEnableVBOs &&
9792 ((facep->mVertexBuffer->getUsage() == GL_STATIC_DRAW ? TRUE : FALSE) != 9762 ((facep->mVertexBuffer->getUsage() == GL_STATIC_DRAW ? TRUE : FALSE) !=
9793 (facep->getPool()->getVertexShaderLevel() > 0 ? TRUE : FALSE)))) 9763 (facep->getPool()->getVertexShaderLevel() > 0 ? TRUE : FALSE)))
9794 { 9764 {
9795 mDirtyMesh = TRUE; 9765 mDirtyMesh = TRUE;
9796 } 9766 }