2006-12-05 00:07:30 +00:00
using System ;
using System.Collections.Generic ;
using System.Threading ;
using libsecondlife ;
using libsecondlife.AssetSystem ;
2006-12-22 00:21:54 +00:00
using libsecondlife.InventorySystem ;
2006-12-05 00:07:30 +00:00
using libsecondlife.Packets ;
namespace libsecondlife.AssetSystem
{
public class AppearanceManager
2007-01-11 02:24:57 +00:00
{
public enum WearableType
{
Shape = 0 ,
Skin = 1 ,
Hair = 2 ,
Eyes = 3 ,
Shirt = 4 ,
Pants = 5 ,
Shoes = 6 ,
Socks = 7 ,
Jacket = 8 ,
Gloves = 9 ,
Undershirt = 10 ,
Underpants = 11 ,
Skirt = 12 ,
Count = 13 ,
Invalid = 255
} ;
2007-01-09 09:47:45 +00:00
2007-01-13 00:23:00 +00:00
protected SecondLife Client ;
protected AssetManager AManager ;
2006-12-05 00:07:30 +00:00
2007-01-13 00:23:00 +00:00
protected uint SerialNum = 1 ;
2006-12-05 23:01:06 +00:00
2007-02-02 23:17:08 +00:00
protected ManualResetEvent AgentWearablesSignal = new ManualResetEvent ( false ) ;
2006-12-19 23:13:04 +00:00
2007-01-23 04:08:28 +00:00
protected Dictionary < LLUUID , AssetWearable > WearableCache = new Dictionary < LLUUID , AssetWearable > ( ) ;
protected List < LLUUID > WearableAssetQueue = new List < LLUUID > ( ) ;
2006-12-19 23:13:04 +00:00
// This data defines all appearance info for an avatar
public AgentWearablesUpdatePacket . WearableDataBlock [ ] AgentWearablesData ;
2007-01-23 04:08:28 +00:00
public SerializableDictionary < int , float > AgentAppearanceParams = new SerializableDictionary < int , float > ( ) ;
2007-01-29 22:20:12 +00:00
public LLObject . TextureEntry AgentTextureEntry = new LLObject . TextureEntry ( "C228D1CF4B5D4BA884F4899A0796AA97" ) ; // if this isn't valid, blame JH ;-)
2006-12-19 23:13:04 +00:00
2007-01-13 00:23:00 +00:00
/// <summary>
///
/// </summary>
/// <param name="client"></param>
2006-12-05 00:21:45 +00:00
public AppearanceManager ( SecondLife client )
2006-12-05 00:07:30 +00:00
{
Client = client ;
2007-01-13 00:23:00 +00:00
Client . Network . RegisterCallback ( libsecondlife . Packets . PacketType . AgentWearablesUpdate , new NetworkManager . PacketCallback ( AgentWearablesUpdateCallbackHandler ) ) ;
2006-12-05 00:07:30 +00:00
2007-01-23 04:08:28 +00:00
AManager = client . Assets ;
AManager . TransferRequestCompletedEvent + = new AssetManager . On_TransferRequestCompleted ( AManager_TransferRequestCompletedEvent ) ;
2006-12-05 00:07:30 +00:00
}
2007-01-13 00:23:00 +00:00
#region Wear Stuff
2006-12-05 00:07:30 +00:00
2006-12-22 17:34:00 +00:00
/// <summary>
/// Add a single wearable to your outfit, replacing if nessesary.
/// </summary>
/// <param name="wearable"></param>
public void Wear ( InventoryWearable wearable )
{
List < InventoryWearable > x = new List < InventoryWearable > ( ) ;
x . Add ( wearable ) ;
Wear ( x ) ;
}
2006-12-22 15:24:20 +00:00
2006-12-22 17:34:00 +00:00
/// <summary>
/// Add the specified wearables to your outfit, replace existing ones if nessesary.
/// </summary>
/// <param name="wearables"></param>
2006-12-22 15:24:20 +00:00
public void Wear ( List < InventoryWearable > wearables )
{
2006-12-22 17:34:00 +00:00
// Make sure we have some Wearable Data to start with.
if ( ( AgentWearablesData = = null ) | | ( AgentWearablesData . Length = = 0 ) )
{
GetWearables ( ) ;
}
// Update with specified wearables
foreach ( InventoryWearable iw in wearables )
{
2007-02-15 21:39:59 +00:00
byte type = ( byte ) ( ( AssetWearable ) iw . Asset ) . AppearanceLayer ;
2006-12-22 17:34:00 +00:00
AgentWearablesData [ type ] . ItemID = iw . ItemID ;
AgentWearablesData [ type ] . AssetID = iw . AssetID ;
}
// Create AgentIsNowWearing Packet, and send it
SendAgentIsNowWearing ( ) ;
2006-12-22 15:24:20 +00:00
2006-12-22 17:34:00 +00:00
// Update local Appearance Info
GetAvatarAppearanceInfoFromWearableAssets ( ) ;
// Send updated AgentSetAppearance to the grid
2007-02-02 23:17:08 +00:00
BeginAgentSendAppearance ( ) ;
2006-12-22 17:34:00 +00:00
}
2006-12-22 15:24:20 +00:00
/// <summary>
/// Equivalent to the SL "Replace Outfit" command. All clothing is removed, and replaced with wearables in given folder. Body wearables will be replaced if provided.
/// </summary>
/// <param name="outfitFolder">Contains the wearable items to put on.</param>
2006-12-22 00:21:54 +00:00
public void WearOutfit ( InventoryFolder outfitFolder )
2006-12-22 15:24:20 +00:00
{
2007-02-21 21:37:37 +00:00
WearOutfit ( outfitFolder , 10000 , true ) ;
2006-12-22 15:24:20 +00:00
}
/// <summary>
/// Equivalent to the SL "Replace Outfit" command. All clothing is removed, and replaced with wearables in given folder. Body wearables will be replaced if provided.
/// </summary>
/// <param name="outfitFolder">Contains the wearable items to put on.</param>
/// <param name="TimeOut">How long to wait for outfit directory information to download</param>
2007-02-21 21:37:37 +00:00
public void WearOutfit ( InventoryFolder outfitFolder , int TimeOut , bool removeExistingAttachments )
2006-12-22 00:21:54 +00:00
{
// Refresh download of outfit folder
2007-01-05 22:38:15 +00:00
if ( ! outfitFolder . RequestDownloadContents ( false , false , true , true ) . RequestComplete . WaitOne ( TimeOut , false ) )
2006-12-22 00:21:54 +00:00
{
Console . WriteLine ( "An error occured while downloads the folder contents of : " + outfitFolder . Name ) ;
}
2006-12-22 15:24:20 +00:00
// Make sure we have some Wearable Data to start with.
if ( ( AgentWearablesData = = null ) | | ( AgentWearablesData . Length = = 0 ) )
{
GetWearables ( ) ;
}
2006-12-22 00:21:54 +00:00
2006-12-22 15:24:20 +00:00
// Flush the cached clothing wearables so we can redefine them
for ( byte i = 4 ; i < = 12 ; i + + )
2006-12-22 00:21:54 +00:00
{
2006-12-22 15:24:20 +00:00
AgentWearablesData [ i ] . ItemID = LLUUID . Zero ;
AgentWearablesData [ i ] . AssetID = LLUUID . Zero ;
2006-12-22 00:21:54 +00:00
}
2007-02-21 21:37:37 +00:00
List < InventoryItem > attachments = new List < InventoryItem > ( ) ;
2006-12-22 15:24:20 +00:00
// Replace with wearables from Outfit folder
2006-12-22 00:21:54 +00:00
foreach ( InventoryBase ib in outfitFolder . GetContents ( ) )
{
if ( ib is InventoryWearable )
{
2007-02-14 20:26:37 +00:00
try
{
InventoryWearable iw = ( InventoryWearable ) ib ;
2007-02-15 21:39:59 +00:00
Client . Log ( "Retrieving asset for " + iw . Name + "(" + iw . AssetID + ")" , Helpers . LogLevel . Info ) ;
AssetWearable . AppearanceLayerType AppearanceLayer = ( ( AssetWearable ) iw . Asset ) . AppearanceLayer ;
Client . Log ( "Adding skin/clothing layer for " + AppearanceLayer , Helpers . LogLevel . Info ) ;
AgentWearablesData [ ( byte ) AppearanceLayer ] . ItemID = iw . ItemID ;
AgentWearablesData [ ( byte ) AppearanceLayer ] . AssetID = iw . AssetID ;
2007-02-14 20:26:37 +00:00
}
catch ( Exception e )
{
Client . Log ( "Asset for " + ib . _Name + " unavailable: " + e . Message , Helpers . LogLevel . Error ) ;
}
2006-12-22 00:21:54 +00:00
}
2007-02-21 21:37:37 +00:00
else if ( ib is InventoryItem )
{
InventoryItem ii = ( InventoryItem ) ib ;
attachments . Add ( ii ) ;
}
2006-12-22 00:21:54 +00:00
}
2007-02-21 21:37:37 +00:00
// Change attachments
AddAttachments ( attachments , removeExistingAttachments ) ;
2006-12-22 15:24:20 +00:00
// Create AgentIsNowWearing Packet, and send it
2006-12-22 17:34:00 +00:00
SendAgentIsNowWearing ( ) ;
// Update local Appearance Info
GetAvatarAppearanceInfoFromWearableAssets ( ) ;
// Send updated AgentSetAppearance to the grid
2007-02-02 23:17:08 +00:00
BeginAgentSendAppearance ( ) ;
2006-12-22 17:34:00 +00:00
}
2007-02-21 21:37:37 +00:00
public void AddAttachments ( List < InventoryItem > attachments , bool removeExistingFirst )
{
// Use RezMultipleAttachmentsFromInv to clear out current attachments, and attach new ones
RezMultipleAttachmentsFromInvPacket attachmentsPacket = new RezMultipleAttachmentsFromInvPacket ( ) ;
attachmentsPacket . AgentData . AgentID = Client . Network . AgentID ;
attachmentsPacket . AgentData . SessionID = Client . Network . SessionID ;
attachmentsPacket . HeaderData . CompoundMsgID = LLUUID . Random ( ) ;
attachmentsPacket . HeaderData . FirstDetachAll = true ;
attachmentsPacket . HeaderData . TotalObjects = ( byte ) attachments . Count ;
attachmentsPacket . ObjectData = new RezMultipleAttachmentsFromInvPacket . ObjectDataBlock [ attachments . Count ] ;
for ( int i = 0 ; i < attachments . Count ; i + + )
{
attachmentsPacket . ObjectData [ i ] = new RezMultipleAttachmentsFromInvPacket . ObjectDataBlock ( ) ;
attachmentsPacket . ObjectData [ i ] . AttachmentPt = 0 ;
attachmentsPacket . ObjectData [ i ] . EveryoneMask = attachments [ i ] . EveryoneMask ;
attachmentsPacket . ObjectData [ i ] . GroupMask = attachments [ i ] . GroupMask ;
attachmentsPacket . ObjectData [ i ] . ItemFlags = attachments [ i ] . Flags ;
attachmentsPacket . ObjectData [ i ] . ItemID = attachments [ i ] . ItemID ;
attachmentsPacket . ObjectData [ i ] . Name = Helpers . StringToField ( attachments [ i ] . Name ) ;
attachmentsPacket . ObjectData [ i ] . Description = Helpers . StringToField ( attachments [ i ] . Description ) ;
attachmentsPacket . ObjectData [ i ] . NextOwnerMask = attachments [ i ] . NextOwnerMask ;
attachmentsPacket . ObjectData [ i ] . OwnerID = attachments [ i ] . OwnerID ;
}
Client . Network . SendPacket ( attachmentsPacket ) ;
}
2007-01-13 00:23:00 +00:00
#endregion
2006-12-22 17:34:00 +00:00
/// <summary>
/// Creates and sends an AgentIsNowWearing packet based on the local cached AgentWearablesData array.
/// </summary>
2007-01-13 00:23:00 +00:00
protected void SendAgentIsNowWearing ( )
2006-12-22 17:34:00 +00:00
{
2006-12-22 15:24:20 +00:00
AgentIsNowWearingPacket nowWearing = new AgentIsNowWearingPacket ( ) ;
nowWearing . AgentData . AgentID = Client . Network . AgentID ;
nowWearing . AgentData . SessionID = Client . Network . SessionID ;
nowWearing . WearableData = new AgentIsNowWearingPacket . WearableDataBlock [ 13 ] ;
2006-12-22 00:21:54 +00:00
for ( byte i = 0 ; i < = 12 ; i + + )
{
2006-12-22 15:24:20 +00:00
nowWearing . WearableData [ i ] = new AgentIsNowWearingPacket . WearableDataBlock ( ) ;
nowWearing . WearableData [ i ] . WearableType = i ;
nowWearing . WearableData [ i ] . ItemID = AgentWearablesData [ i ] . ItemID ;
2006-12-22 00:21:54 +00:00
}
Client . Network . SendPacket ( nowWearing ) ;
}
2006-12-29 17:59:48 +00:00
/// <summary>
/// Request from the server what wearables we're currently wearing. Update cached info.
/// </summary>
/// <returns>The wearable info for what we're currently wearing</returns>
2007-01-13 00:23:00 +00:00
protected AgentWearablesUpdatePacket . WearableDataBlock [ ] GetWearables ( )
2006-12-05 00:07:30 +00:00
{
2007-02-02 23:17:08 +00:00
AgentWearablesSignal . Reset ( ) ;
2006-12-05 00:07:30 +00:00
AgentWearablesRequestPacket p = new AgentWearablesRequestPacket ( ) ;
p . AgentData . AgentID = Client . Network . AgentID ;
p . AgentData . SessionID = Client . Network . SessionID ;
Client . Network . SendPacket ( p ) ;
AgentWearablesSignal . WaitOne ( ) ;
return AgentWearablesData ;
}
2006-12-29 17:59:48 +00:00
/// <summary>
/// Update the local Avatar Appearance information based on the contents of the assets as defined in the cached wearable data info.
/// </summary>
2007-01-13 00:23:00 +00:00
protected void GetAvatarAppearanceInfoFromWearableAssets ( )
2006-12-05 00:07:30 +00:00
{
2006-12-29 17:59:48 +00:00
// Only request wearable data, if we have to.
if ( ( AgentWearablesData = = null ) | | ( AgentWearablesData . Length = = 0 ) )
{
GetWearables ( ) ;
}
foreach ( AgentWearablesUpdatePacket . WearableDataBlock wdb in AgentWearablesData )
2006-12-05 00:07:30 +00:00
{
if ( wdb . ItemID = = LLUUID . Zero )
{
continue ;
}
2006-12-20 22:19:52 +00:00
AssetWearable wearableAsset ;
2006-12-05 00:07:30 +00:00
switch ( wdb . WearableType )
{
case 0 :
case 1 :
case 2 :
case 3 :
2006-12-20 22:19:52 +00:00
wearableAsset = new AssetWearable_Body ( wdb . AssetID , null ) ;
2006-12-05 00:07:30 +00:00
break ;
default :
2006-12-20 22:19:52 +00:00
wearableAsset = new AssetWearable_Clothing ( wdb . AssetID , null ) ;
2006-12-05 00:07:30 +00:00
break ;
}
2007-01-18 00:20:55 +00:00
AssetRequestDownload request = Client . Assets . RequestInventoryAsset ( wearableAsset . AssetID , wearableAsset . Type ) ;
2007-01-13 00:23:00 +00:00
if ( request . Wait ( AssetManager . DefaultTimeout ) ! = AssetRequestDownload . RequestStatus . Success )
{
2007-02-14 20:26:37 +00:00
Client . Log ( "Asset (" + wearableAsset . AssetID . ToStringHyphenated ( ) + ") unavailable (" + request . StatusMsg + ")" , Helpers . LogLevel . Error ) ;
}
else
{
wearableAsset . SetAssetData ( request . GetAssetData ( ) ) ;
2007-01-13 00:23:00 +00:00
}
2006-12-22 00:21:54 +00:00
if ( ( wearableAsset . AssetData = = null ) | | ( wearableAsset . AssetData . Length = = 0 ) )
2006-12-05 00:07:30 +00:00
{
2006-12-22 00:21:54 +00:00
Client . Log ( "Asset retrieval failed for AssetID: " + wearableAsset . AssetID , Helpers . LogLevel . Warning ) ;
2006-12-05 00:07:30 +00:00
}
2007-01-23 04:08:28 +00:00
UpdateAgentTextureEntryAndAppearanceParams ( wearableAsset ) ;
2006-12-05 00:07:30 +00:00
}
2007-01-23 04:08:28 +00:00
UpdateAgentTextureEntryOrder ( ) ;
}
protected void UpdateAgentTextureEntryOrder ( )
{
2006-12-19 23:13:04 +00:00
// Correct the order of the textures
foreach ( uint faceid in AgentTextureEntry . FaceTextures . Keys )
{
2007-01-23 04:08:28 +00:00
if ( faceid > 18 )
2006-12-19 23:13:04 +00:00
{
2007-01-23 04:08:28 +00:00
Client . Log ( "Unknown order for FaceID: " + faceid + Environment . NewLine +
"Your wearables define a face that we don't know the order of. Please " +
"capture a AgentSetAppearance packet for your current outfit and submit to " +
"static.sprocket@gmail.com, thanks!" , Helpers . LogLevel . Info ) ;
break ;
2006-12-19 23:13:04 +00:00
}
}
//Re-order texture faces to match Linden Labs internal data structure.
2007-01-29 22:20:12 +00:00
LLObject . TextureEntry te2 = new LLObject . TextureEntry ( AgentTextureEntry . DefaultTexture . TextureID ) ;
2006-12-19 23:13:04 +00:00
te2 . CreateFace ( 18 ) . TextureID = AgentTextureEntry . GetFace ( 18 ) . TextureID ;
te2 . CreateFace ( 17 ) . TextureID = AgentTextureEntry . GetFace ( 17 ) . TextureID ;
te2 . CreateFace ( 16 ) . TextureID = AgentTextureEntry . GetFace ( 16 ) . TextureID ;
te2 . CreateFace ( 15 ) . TextureID = AgentTextureEntry . GetFace ( 15 ) . TextureID ;
2006-12-20 22:19:52 +00:00
te2 . CreateFace ( 14 ) . TextureID = AgentTextureEntry . GetFace ( 14 ) . TextureID ;
te2 . CreateFace ( 13 ) . TextureID = AgentTextureEntry . GetFace ( 13 ) . TextureID ;
2006-12-19 23:13:04 +00:00
te2 . CreateFace ( 12 ) . TextureID = AgentTextureEntry . GetFace ( 12 ) . TextureID ;
2006-12-20 23:50:35 +00:00
// I wonder if shoes are somewhere in here?
2006-12-19 23:13:04 +00:00
te2 . CreateFace ( 7 ) . TextureID = AgentTextureEntry . GetFace ( 7 ) . TextureID ;
te2 . CreateFace ( 6 ) . TextureID = AgentTextureEntry . GetFace ( 6 ) . TextureID ;
te2 . CreateFace ( 5 ) . TextureID = AgentTextureEntry . GetFace ( 5 ) . TextureID ;
te2 . CreateFace ( 4 ) . TextureID = AgentTextureEntry . GetFace ( 4 ) . TextureID ;
te2 . CreateFace ( 3 ) . TextureID = AgentTextureEntry . GetFace ( 3 ) . TextureID ;
2006-12-20 22:19:52 +00:00
te2 . CreateFace ( 2 ) . TextureID = AgentTextureEntry . GetFace ( 2 ) . TextureID ;
2006-12-19 23:13:04 +00:00
te2 . CreateFace ( 1 ) . TextureID = AgentTextureEntry . GetFace ( 1 ) . TextureID ;
te2 . CreateFace ( 0 ) . TextureID = AgentTextureEntry . GetFace ( 0 ) . TextureID ;
AgentTextureEntry = te2 ;
}
2007-01-23 04:08:28 +00:00
protected void UpdateAgentTextureEntryAndAppearanceParams ( AssetWearable wearableAsset )
{
try
{
foreach ( KeyValuePair < uint , LLUUID > texture in wearableAsset . Textures )
{
AgentTextureEntry . CreateFace ( texture . Key ) . TextureID = texture . Value ;
}
2007-01-23 22:30:33 +00:00
lock ( AgentAppearanceParams )
2007-01-23 04:08:28 +00:00
{
2007-01-23 22:30:33 +00:00
foreach ( KeyValuePair < int , float > kvp in wearableAsset . Parameters )
{
AgentAppearanceParams [ kvp . Key ] = kvp . Value ;
}
2007-01-23 04:08:28 +00:00
}
}
catch ( Exception e )
{
Client . Log ( e . ToString ( ) + Environment . NewLine + wearableAsset . AssetDataToString ( ) , Helpers . LogLevel . Error ) ;
}
}
/// <summary>
/// Non-blocking async request of wearables, construction and sending of AgentSetAppearance
/// </summary>
public void BeginAgentSendAppearance ( )
{
2007-02-02 23:17:08 +00:00
AgentWearablesSignal . Reset ( ) ;
2007-01-23 04:08:28 +00:00
AgentWearablesRequestPacket p = new AgentWearablesRequestPacket ( ) ;
p . AgentData . AgentID = Client . Network . AgentID ;
p . AgentData . SessionID = Client . Network . SessionID ;
Client . Network . SendPacket ( p ) ;
}
2006-12-29 17:59:48 +00:00
/// <summary>
/// Send an AgentSetAppearance packet to the server to update your appearance.
/// </summary>
2007-02-02 23:17:08 +00:00
protected void SendAgentSetAppearance ( )
2006-12-19 23:13:04 +00:00
{
// Get latest appearance info
if ( AgentAppearanceParams . Count = = 0 )
2006-12-06 03:30:00 +00:00
{
2006-12-19 23:13:04 +00:00
GetAvatarAppearanceInfoFromWearableAssets ( ) ;
2006-12-06 03:30:00 +00:00
}
2006-12-19 23:13:04 +00:00
AgentSetAppearancePacket p = new AgentSetAppearancePacket ( ) ;
p . AgentData . AgentID = Client . Network . AgentID ;
p . AgentData . SessionID = Client . Network . SessionID ;
p . AgentData . SerialNum = + + SerialNum ;
2006-12-05 00:07:30 +00:00
2006-12-19 23:13:04 +00:00
// Add Texture Data
p . ObjectData . TextureEntry = AgentTextureEntry . ToBytes ( ) ;
2007-01-26 22:01:56 +00:00
2006-12-05 00:07:30 +00:00
p . VisualParam = new AgentSetAppearancePacket . VisualParamBlock [ 218 ] ;
2007-01-26 22:01:56 +00:00
// Add Visual Params
lock ( AgentAppearanceParams )
{
for ( int i = 0 ; i < 218 ; i + + )
2006-12-05 00:07:30 +00:00
{
2007-01-26 22:01:56 +00:00
VisualParam param = VisualParams . Params [ i ] ;
p . VisualParam [ i ] = new AgentSetAppearancePacket . VisualParamBlock ( ) ;
2006-12-05 23:01:06 +00:00
2007-01-26 22:01:56 +00:00
if ( AgentAppearanceParams . ContainsKey ( param . ParamID ) )
2007-01-23 04:08:28 +00:00
{
2007-01-26 22:01:56 +00:00
p . VisualParam [ i ] . ParamValue = Helpers . FloatToByte ( AgentAppearanceParams [ param . ParamID ] ,
param . MinValue , param . MaxValue ) ;
}
else
{
// Use the default value for this parameter
p . VisualParam [ i ] . ParamValue = Helpers . FloatToByte ( param . DefaultValue , param . MinValue ,
param . MaxValue ) ;
2007-01-23 04:08:28 +00:00
}
2006-12-05 00:07:30 +00:00
}
}
2006-12-19 23:13:04 +00:00
// Add Size Data
2007-01-26 22:01:56 +00:00
p . AgentData . Size = GetAgentSizeFromVisualParam ( Helpers . ByteToFloat ( p . VisualParam [ 25 ] . ParamValue ,
VisualParams . Params [ 25 ] . MinValue , VisualParams . Params [ 25 ] . MaxValue ) ) ;
2006-12-06 03:30:00 +00:00
2006-12-19 23:13:04 +00:00
Client . Network . SendPacket ( p ) ;
2006-12-05 00:07:30 +00:00
}
2007-01-13 00:23:00 +00:00
/// <summary>
/// Determine agent size for AgentSetAppearance based on Visual Param data.
/// </summary>
2007-01-26 22:01:56 +00:00
/// <param name="heightParam"></param>
2007-01-13 00:23:00 +00:00
/// <returns></returns>
2007-01-26 22:01:56 +00:00
protected LLVector3 GetAgentSizeFromVisualParam ( float heightParam )
2007-01-13 00:23:00 +00:00
{
2007-01-26 22:01:56 +00:00
float AV_Height_Range = 2.025506f - 1.50856f ;
float AV_Height = 1.50856f + ( ( heightParam / 255.0f ) * AV_Height_Range ) ;
return new LLVector3 ( 0.45f , 0.6f , AV_Height ) ;
//return new LLVector3(0.45f, 0.6f, 1.0f);
2007-01-13 00:23:00 +00:00
}
#region Callback Handlers
2006-12-05 00:07:30 +00:00
private void AgentWearablesUpdateCallbackHandler ( Packet packet , Simulator simulator )
{
AgentWearablesUpdatePacket wearablesPacket = ( AgentWearablesUpdatePacket ) packet ;
AgentWearablesData = wearablesPacket . WearableData ;
AgentWearablesSignal . Set ( ) ;
2007-01-23 04:08:28 +00:00
// Queue download of wearables
foreach ( AgentWearablesUpdatePacket . WearableDataBlock wdb in AgentWearablesData )
{
2007-02-03 00:58:38 +00:00
2007-01-23 04:08:28 +00:00
// Don't try to download if AssetID is zero
if ( wdb . AssetID = = LLUUID . Zero )
{
continue ;
}
// Don't try to download, if it's already cached.
if ( WearableCache . ContainsKey ( wdb . AssetID ) )
{
AssetWearable aw = WearableCache [ wdb . AssetID ] ;
if ( aw . _AssetData ! = null )
{
continue ;
}
}
// Don't try to download, if it's already in the download queue
if ( WearableAssetQueue . Contains ( wdb . AssetID ) )
{
continue ;
}
AssetWearable wearableAsset ;
switch ( wdb . WearableType )
{
case 0 :
case 1 :
case 2 :
case 3 :
wearableAsset = new AssetWearable_Body ( wdb . AssetID , null ) ;
break ;
default :
wearableAsset = new AssetWearable_Clothing ( wdb . AssetID , null ) ;
break ;
}
WearableCache [ wdb . AssetID ] = wearableAsset ;
2007-02-03 00:58:38 +00:00
2007-02-14 21:48:16 +00:00
lock ( WearableAssetQueue )
{
if ( ! WearableAssetQueue . Contains ( wdb . AssetID ) )
{
WearableAssetQueue . Add ( wdb . AssetID ) ;
}
}
2007-01-23 04:08:28 +00:00
AssetRequestDownload request = Client . Assets . RequestInventoryAsset ( wearableAsset . AssetID , wearableAsset . Type ) ;
}
2006-12-05 00:07:30 +00:00
}
2007-02-02 23:17:08 +00:00
/// <summary>
/// Called each time a wearable asset is done downloading
/// </summary>
/// <param name="request"></param>
2007-01-23 04:08:28 +00:00
void AManager_TransferRequestCompletedEvent ( AssetRequest request )
{
if ( ! ( request is AssetRequestDownload ) )
{
return ;
}
AssetRequestDownload dlrequest = ( AssetRequestDownload ) request ;
2007-02-14 21:13:10 +00:00
if ( dlrequest . AssetID = = null )
{
Client . Log ( "AssetID is null in AssetRequestDownload: " + dlrequest . StatusMsg , Helpers . LogLevel . Error ) ;
}
2007-02-03 00:58:38 +00:00
2007-02-14 21:48:16 +00:00
lock ( WearableAssetQueue )
2007-01-23 04:08:28 +00:00
{
2007-02-14 21:48:16 +00:00
// Remove from the download queue
if ( ! WearableAssetQueue . Contains ( dlrequest . AssetID ) )
2007-01-23 04:16:17 +00:00
{
return ;
}
2007-02-14 21:48:16 +00:00
WearableAssetQueue . Remove ( dlrequest . AssetID ) ;
}
2007-01-23 04:08:28 +00:00
2007-02-14 21:48:16 +00:00
// If the request wasn't successful, then don't try to process it.
if ( request . Status ! = AssetRequest . RequestStatus . Success )
{
return ;
}
2007-02-03 00:58:38 +00:00
2007-01-23 04:08:28 +00:00
2007-02-14 21:48:16 +00:00
AssetWearable wearableAsset = WearableCache [ dlrequest . AssetID ] ;
wearableAsset . SetAssetData ( dlrequest . GetAssetData ( ) ) ;
2007-02-03 00:58:38 +00:00
2007-02-14 21:48:16 +00:00
if ( ( wearableAsset . AssetData = = null ) | | ( wearableAsset . AssetData . Length = = 0 ) )
{
Client . Log ( "Asset retrieval failed for AssetID: " + wearableAsset . AssetID , Helpers . LogLevel . Warning ) ;
}
else
{
UpdateAgentTextureEntryAndAppearanceParams ( wearableAsset ) ;
UpdateAgentTextureEntryOrder ( ) ;
if ( WearableAssetQueue . Count = = 0 )
{
// Now that all the wearable assets are done downloading
// , we can send an appearance packet
SendAgentSetAppearance ( ) ;
2007-01-23 04:08:28 +00:00
}
}
}
2007-01-13 00:23:00 +00:00
#endregion
2006-12-05 00:07:30 +00:00
}
}