* Moved OpenMetaverse/Resources to bin/openmetaverse_data until we have a working xbuild and reorganize SVN

* Complete rewrite of AppearanceManager. Appearance editing has not been (re)implemented yet, but the normal appearance setting is much more reliable
* Added a setting (defaulted to true) for automatically setting appearance
* Various baking hacks to get slightly less ugly avatars
* Added baked texture uploading through CAPS in AssetManager.RequestUploadBakedTexture(). UDP fallback is not implemented yet
* Added Parallel.Invoke() and overloads for all three methods that take a threadCount

git-svn-id: http://libopenmetaverse.googlecode.com/svn/libopenmetaverse/trunk@3038 52acb1d6-8a22-11de-b505-999d5b087335
This commit is contained in:
John Hurliman
2009-07-31 17:43:01 +00:00
parent aa28d07115
commit c1bc0b4af6
75 changed files with 1258 additions and 1347 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -31,6 +31,9 @@ using System.IO;
using OpenMetaverse;
using OpenMetaverse.Packets;
using OpenMetaverse.Assets;
using OpenMetaverse.Http;
using OpenMetaverse.StructuredData;
using OpenMetaverse.Messages.Linden;
namespace OpenMetaverse
{
@@ -312,6 +315,11 @@ namespace OpenMetaverse
/// <summary>
///
/// </summary>
/// <param name="newAssetID"></param>
public delegate void BakedTextureUploadedCallback(UUID newAssetID);
/// <summary>
///
/// </summary>
/// <param name="upload"></param>
public delegate void UploadProgressCallback(AssetUpload upload);
/// <summary>
@@ -709,6 +717,70 @@ namespace OpenMetaverse
}
}
public void RequestUploadBakedTexture(byte[] textureData, BakedTextureUploadedCallback callback)
{
Uri url = null;
Caps caps = Client.Network.CurrentSim.Caps;
if (caps != null)
url = caps.CapabilityURI("UploadBakedTexture");
if (url != null)
{
// Fetch the uploader capability
CapsClient request = new CapsClient(url);
request.OnComplete +=
delegate(CapsClient client, OSD result, Exception error)
{
if (error == null && result is OSDMap)
{
UploadBakedTextureMessage message = new UploadBakedTextureMessage();
message.Deserialize((OSDMap)result);
if (message.Request.State == "upload")
{
Uri uploadUrl = ((UploaderRequestUpload)message.Request).Url;
if (uploadUrl != null)
{
// POST the asset data
CapsClient upload = new CapsClient(uploadUrl);
upload.OnComplete +=
delegate(CapsClient client2, OSD result2, Exception error2)
{
if (error2 == null && result2 is OSDMap)
{
UploadBakedTextureMessage message2 = new UploadBakedTextureMessage();
message2.Deserialize((OSDMap)result2);
if (message2.Request.State == "complete")
{
callback(((UploaderRequestComplete)message2.Request).AssetID);
return;
}
}
Logger.Log("Bake upload failed during asset upload", Helpers.LogLevel.Warning, Client);
callback(UUID.Zero);
};
upload.BeginGetResponse(textureData, "application/octet-stream", Client.Settings.CAPS_TIMEOUT);
return;
}
}
}
Logger.Log("Bake upload failed during uploader retrieval", Helpers.LogLevel.Warning, Client);
callback(UUID.Zero);
};
request.BeginGetResponse(new OSDMap(), OSDFormat.Xml, Client.Settings.CAPS_TIMEOUT);
}
else
{
Logger.Log("UploadBakedTexture not available, falling back to UDP method", Helpers.LogLevel.Info, Client);
// FIXME:
}
}
/// <summary>
/// Request a texture asset from the simulator using the <see cref="TexturePipeline"/> system to
/// manage the requests and re-assemble the image from the packets received from the simulator

View File

@@ -61,7 +61,7 @@ namespace OpenMetaverse.Assets
/// <summary>A Dictionary containing Key/Value pairs of the objects parameters</summary>
public Dictionary<int, float> Params = new Dictionary<int, float>();
/// <summary>A Dictionary containing Key/Value pairs where the Key is the textures Index and the Value is the Textures <seealso cref="UUID"/></summary>
public Dictionary<AppearanceManager.TextureIndex, UUID> Textures = new Dictionary<AppearanceManager.TextureIndex, UUID>();
public Dictionary<AvatarTextureIndex, UUID> Textures = new Dictionary<AvatarTextureIndex, UUID>();
/// <summary>Initializes a new instance of an AssetWearable object</summary>
public AssetWearable() { }
@@ -145,7 +145,7 @@ namespace OpenMetaverse.Assets
line = lines[stri].Trim();
fields = line.Split(' ');
AppearanceManager.TextureIndex id = (AppearanceManager.TextureIndex)Int32.Parse(fields[0]);
AvatarTextureIndex id = (AvatarTextureIndex)Int32.Parse(fields[0]);
UUID texture = new UUID(fields[1]);
Textures[id] = texture;
@@ -249,7 +249,7 @@ namespace OpenMetaverse.Assets
}
data.Append("textures "); data.Append(Textures.Count); data.Append(NL);
foreach (KeyValuePair<AppearanceManager.TextureIndex, UUID> texture in Textures)
foreach (KeyValuePair<AvatarTextureIndex, UUID> texture in Textures)
{
data.Append((byte)texture.Key); data.Append(" "); data.Append(texture.Value.ToString()); data.Append(NL);
}

View File

@@ -42,11 +42,11 @@ namespace OpenMetaverse.Imaging
{
public AssetTexture BakedTexture { get { return _bakedTexture; } }
public Dictionary<int, float> ParamValues { get { return _paramValues; } }
public Dictionary<AppearanceManager.TextureIndex, AssetTexture> Textures { get { return _textures; } }
public Dictionary<AvatarTextureIndex, AssetTexture> Textures { get { return _textures; } }
public int TextureCount { get { return _textureCount; } }
public int BakeWidth { get { return _bakeWidth; } }
public int BakeHeight { get { return _bakeHeight; } }
public AppearanceManager.BakeType BakeType { get { return _bakeType; } }
public BakeType BakeType { get { return _bakeType; } }
/// <summary>Reference to the GridClient object</summary>
protected GridClient _client;
@@ -55,7 +55,7 @@ namespace OpenMetaverse.Imaging
/// <summary>Appearance parameters the drive the baking process</summary>
protected Dictionary<int, float> _paramValues;
/// <summary>Wearable textures</summary>
protected Dictionary<AppearanceManager.TextureIndex, AssetTexture> _textures = new Dictionary<AppearanceManager.TextureIndex, AssetTexture>();
protected Dictionary<AvatarTextureIndex, AssetTexture> _textures = new Dictionary<AvatarTextureIndex, AssetTexture>();
/// <summary>Total number of textures in the bake</summary>
protected int _textureCount;
/// <summary>Width of the final baked image and scratchpad</summary>
@@ -63,7 +63,7 @@ namespace OpenMetaverse.Imaging
/// <summary>Height of the final baked image and scratchpad</summary>
protected int _bakeHeight;
/// <summary>Bake type</summary>
protected AppearanceManager.BakeType _bakeType;
protected BakeType _bakeType;
/// <summary>
/// Default constructor
@@ -74,13 +74,13 @@ namespace OpenMetaverse.Imaging
/// composed of</param>
/// <param name="paramValues">Appearance parameters the drive the
/// baking process</param>
public Baker(GridClient client, AppearanceManager.BakeType bakeType, int textureCount, Dictionary<int, float> paramValues)
public Baker(GridClient client, BakeType bakeType, int textureCount, Dictionary<int, float> paramValues)
{
_client = client;
_bakeType = bakeType;
_textureCount = textureCount;
if (bakeType == AppearanceManager.BakeType.Eyes)
if (bakeType == BakeType.Eyes)
{
_bakeWidth = 128;
_bakeHeight = 128;
@@ -108,7 +108,7 @@ namespace OpenMetaverse.Imaging
/// called for the texture, otherwise false</param>
/// <returns>True if this texture is completely baked and JPEG2000 data
/// is available, otherwise false</returns>
public bool AddTexture(AppearanceManager.TextureIndex index, AssetTexture texture, bool needsDecode)
public bool AddTexture(AvatarTextureIndex index, AssetTexture texture, bool needsDecode)
{
lock (_textures)
{
@@ -140,7 +140,7 @@ namespace OpenMetaverse.Imaging
}
}
public bool MissingTexture(AppearanceManager.TextureIndex index)
public bool MissingTexture(AvatarTextureIndex index)
{
Logger.DebugLog(String.Format("Missing texture {0} in bake {1}", index, _bakeType), _client);
_textureCount--;
@@ -161,18 +161,18 @@ namespace OpenMetaverse.Imaging
_bakedTexture = new AssetTexture(new ManagedImage(_bakeWidth, _bakeHeight,
ManagedImage.ImageChannels.Color | ManagedImage.ImageChannels.Alpha | ManagedImage.ImageChannels.Bump));
if (_bakeType == AppearanceManager.BakeType.Eyes)
if (_bakeType == BakeType.Eyes)
{
InitBakedLayerColor(255, 255, 255);
DrawLayer(AppearanceManager.TextureIndex.EyesIris);
DrawLayer(AvatarTextureIndex.EyesIris);
}
else if (_bakeType == AppearanceManager.BakeType.Head)
else if (_bakeType == BakeType.Head)
{
// FIXME: Need to use the visual parameters to determine the base skin color in RGB but
// it's not apparent how to define RGB levels from the skin color parameters, so
// for now use a grey foundation for the skin
InitBakedLayerColor(128, 128, 128);
DrawLayer(AppearanceManager.TextureIndex.HeadBodypaint);
// for now use default color for the skin
InitBakedLayerColor(226, 160, 125);
DrawLayer(AvatarTextureIndex.HeadBodypaint);
// HACK: Bake the eyelashes in if we have them
ManagedImage eyelashes = LoadAlphaLayer("head_alpha.tga");
@@ -187,7 +187,7 @@ namespace OpenMetaverse.Imaging
Logger.Log("head_alpha.tga resource not found, skipping eyelashes", Helpers.LogLevel.Info);
}
}
else if (_bakeType == AppearanceManager.BakeType.Skirt)
else if (_bakeType == BakeType.Skirt)
{
float skirtRed = 1.0f, skirtGreen = 1.0f, skirtBlue = 1.0f;
@@ -202,43 +202,44 @@ namespace OpenMetaverse.Imaging
Logger.Log("Unable to determine skirt color from visual params", Helpers.LogLevel.Warning, _client);
}
InitBakedLayerColor((byte)(skirtRed * 255.0f), (byte)(skirtGreen * 255.0f), (byte)(skirtBlue * 255.0f));
DrawLayer(AppearanceManager.TextureIndex.Skirt);
// FIXME: We should be drawing the skirt first, then tinting with the skirt color
//InitBakedLayerColor((byte)(skirtRed * 255.0f), (byte)(skirtGreen * 255.0f), (byte)(skirtBlue * 255.0f));
DrawLayer(AvatarTextureIndex.Skirt);
}
else if (_bakeType == AppearanceManager.BakeType.UpperBody)
else if (_bakeType == BakeType.UpperBody)
{
InitBakedLayerColor(128, 128, 128);
DrawLayer(AppearanceManager.TextureIndex.UpperBodypaint);
DrawLayer(AppearanceManager.TextureIndex.UpperUndershirt);
DrawLayer(AppearanceManager.TextureIndex.UpperGloves);
DrawLayer(AppearanceManager.TextureIndex.UpperShirt);
DrawLayer(AppearanceManager.TextureIndex.UpperJacket);
InitBakedLayerColor(226, 160, 125);
DrawLayer(AvatarTextureIndex.UpperBodypaint);
DrawLayer(AvatarTextureIndex.UpperUndershirt);
DrawLayer(AvatarTextureIndex.UpperGloves);
DrawLayer(AvatarTextureIndex.UpperShirt);
DrawLayer(AvatarTextureIndex.UpperJacket);
}
else if (_bakeType == AppearanceManager.BakeType.LowerBody)
else if (_bakeType == BakeType.LowerBody)
{
InitBakedLayerColor(128, 128, 128);
DrawLayer(AppearanceManager.TextureIndex.LowerBodypaint);
DrawLayer(AppearanceManager.TextureIndex.LowerUnderpants);
DrawLayer(AppearanceManager.TextureIndex.LowerSocks);
DrawLayer(AppearanceManager.TextureIndex.LowerShoes);
DrawLayer(AppearanceManager.TextureIndex.LowerPants);
DrawLayer(AppearanceManager.TextureIndex.LowerJacket);
InitBakedLayerColor(226, 160, 125);
DrawLayer(AvatarTextureIndex.LowerBodypaint);
DrawLayer(AvatarTextureIndex.LowerUnderpants);
DrawLayer(AvatarTextureIndex.LowerSocks);
DrawLayer(AvatarTextureIndex.LowerShoes);
DrawLayer(AvatarTextureIndex.LowerPants);
DrawLayer(AvatarTextureIndex.LowerJacket);
}
else if (_bakeType == AppearanceManager.BakeType.Hair)
else if (_bakeType == BakeType.Hair)
{
InitBakedLayerColor(255, 255, 255);
DrawLayer(AppearanceManager.TextureIndex.Hair);
DrawLayer(AvatarTextureIndex.Hair);
}
_bakedTexture.Encode();
}
private bool DrawLayer(AppearanceManager.TextureIndex textureIndex)
private bool DrawLayer(AvatarTextureIndex textureIndex)
{
AssetTexture texture;
bool useSourceAlpha =
(textureIndex == AppearanceManager.TextureIndex.HeadBodypaint ||
textureIndex == AppearanceManager.TextureIndex.Skirt);
(textureIndex == AvatarTextureIndex.HeadBodypaint ||
textureIndex == AvatarTextureIndex.Skirt);
if (_textures.TryGetValue(textureIndex, out texture))
return DrawLayer(texture.Image, useSourceAlpha);
@@ -266,9 +267,8 @@ namespace OpenMetaverse.Imaging
catch { return false; }
}
int alpha = 255;
//int alphaInv = 255 - alpha;
int alphaInv = 256 - alpha;
byte alpha = Byte.MaxValue;
byte alphaInv = (byte)(Byte.MaxValue - alpha);
byte[] bakedRed = _bakedTexture.Image.Red;
byte[] bakedGreen = _bakedTexture.Image.Green;
@@ -279,14 +279,8 @@ namespace OpenMetaverse.Imaging
byte[] sourceRed = source.Red;
byte[] sourceGreen = source.Green;
byte[] sourceBlue = source.Blue;
byte[] sourceAlpha = null;
byte[] sourceBump = null;
if (sourceHasAlpha)
sourceAlpha = source.Alpha;
if (sourceHasBump)
sourceBump = source.Bump;
byte[] sourceAlpha = sourceHasAlpha ? source.Alpha : null;
byte[] sourceBump = sourceHasBump ? source.Bump : null;
for (int y = 0; y < _bakeHeight; y++)
{
@@ -295,8 +289,7 @@ namespace OpenMetaverse.Imaging
if (sourceHasAlpha)
{
alpha = sourceAlpha[i];
//alphaInv = 255 - alpha;
alphaInv = 256 - alpha;
alphaInv = (byte)(Byte.MaxValue - alpha);
}
if (sourceHasColor)
@@ -340,15 +333,15 @@ namespace OpenMetaverse.Imaging
gAlt = gByte;
bAlt = bByte;
if (rByte < byte.MaxValue)
if (rByte < Byte.MaxValue)
rAlt++;
else rAlt--;
if (gByte < byte.MaxValue)
if (gByte < Byte.MaxValue)
gAlt++;
else gAlt--;
if (bByte < byte.MaxValue)
if (bByte < Byte.MaxValue)
bAlt++;
else bAlt--;
@@ -369,7 +362,7 @@ namespace OpenMetaverse.Imaging
red[i] = rAlt;
green[i] = gByte;
blue[i] = bByte;
alpha[i] = 128;
alpha[i] = Byte.MaxValue;
bump[i] = 0;
}
else
@@ -377,7 +370,7 @@ namespace OpenMetaverse.Imaging
red[i] = rByte;
green[i] = gAlt;
blue[i] = bAlt;
alpha[i] = 128;
alpha[i] = Byte.MaxValue;
bump[i] = 0;
}
@@ -426,39 +419,39 @@ namespace OpenMetaverse.Imaging
}
public static AppearanceManager.BakeType BakeTypeFor(AppearanceManager.TextureIndex index)
public static BakeType BakeTypeFor(AvatarTextureIndex index)
{
switch (index)
{
case AppearanceManager.TextureIndex.HeadBodypaint:
return AppearanceManager.BakeType.Head;
case AvatarTextureIndex.HeadBodypaint:
return BakeType.Head;
case AppearanceManager.TextureIndex.UpperBodypaint:
case AppearanceManager.TextureIndex.UpperGloves:
case AppearanceManager.TextureIndex.UpperUndershirt:
case AppearanceManager.TextureIndex.UpperShirt:
case AppearanceManager.TextureIndex.UpperJacket:
return AppearanceManager.BakeType.UpperBody;
case AvatarTextureIndex.UpperBodypaint:
case AvatarTextureIndex.UpperGloves:
case AvatarTextureIndex.UpperUndershirt:
case AvatarTextureIndex.UpperShirt:
case AvatarTextureIndex.UpperJacket:
return BakeType.UpperBody;
case AppearanceManager.TextureIndex.LowerBodypaint:
case AppearanceManager.TextureIndex.LowerUnderpants:
case AppearanceManager.TextureIndex.LowerSocks:
case AppearanceManager.TextureIndex.LowerShoes:
case AppearanceManager.TextureIndex.LowerPants:
case AppearanceManager.TextureIndex.LowerJacket:
return AppearanceManager.BakeType.LowerBody;
case AvatarTextureIndex.LowerBodypaint:
case AvatarTextureIndex.LowerUnderpants:
case AvatarTextureIndex.LowerSocks:
case AvatarTextureIndex.LowerShoes:
case AvatarTextureIndex.LowerPants:
case AvatarTextureIndex.LowerJacket:
return BakeType.LowerBody;
case AppearanceManager.TextureIndex.EyesIris:
return AppearanceManager.BakeType.Eyes;
case AvatarTextureIndex.EyesIris:
return BakeType.Eyes;
case AppearanceManager.TextureIndex.Skirt:
return AppearanceManager.BakeType.Skirt;
case AvatarTextureIndex.Skirt:
return BakeType.Skirt;
case AppearanceManager.TextureIndex.Hair:
return AppearanceManager.BakeType.Hair;
case AvatarTextureIndex.Hair:
return BakeType.Hair;
default:
return AppearanceManager.BakeType.Unknown;
return BakeType.Unknown;
}
}
}

View File

@@ -1387,6 +1387,11 @@ namespace OpenMetaverse.Messages.Linden
/// <summary>Base class for Asset uploads/results via Capabilities</summary>
public abstract class AssetUploaderBlock
{
/// <summary>
/// The request state
/// </summary>
public string State;
/// <summary>
/// Serialize the object
/// </summary>
@@ -1406,23 +1411,26 @@ namespace OpenMetaverse.Messages.Linden
/// </summary>
public class UploaderRequestUpload : AssetUploaderBlock
{
/// <summary>The request state (Always "upload")</summary>
public string State = "upload";
/// <summary>The Capability URL sent by the simulator to upload the baked texture to</summary>
public string Url;
public Uri Url;
public UploaderRequestUpload()
{
State = "upload";
}
public override OSDMap Serialize()
{
OSDMap map = new OSDMap(2);
map["state"] = OSD.FromString(State);
map["uploader"] = OSD.FromString(Url);
map["uploader"] = OSD.FromUri(Url);
return map;
}
public override void Deserialize(OSDMap map)
{
Url = map["uploader"].AsString();
Url = map["uploader"].AsUri();
State = map["state"].AsString();
}
}
@@ -1433,11 +1441,14 @@ namespace OpenMetaverse.Messages.Linden
/// </summary>
public class UploaderRequestComplete : AssetUploaderBlock
{
/// <summary>The request state (Always "complete")</summary>
public string State = "complete";
/// <summary>The uploaded texture asset ID</summary>
public UUID AssetID;
public UploaderRequestComplete()
{
State = "complete";
}
public override OSDMap Serialize()
{
OSDMap map = new OSDMap(2);
@@ -1483,11 +1494,8 @@ namespace OpenMetaverse.Messages.Linden
else if (map.ContainsKey("state") && map["state"].AsString().Equals("complete"))
Request = new UploaderRequestComplete();
else
{
Logger.Log("Unable to deserialize UploadBakedTexture: No message handler exists for state " + map["state"].AsString(), Helpers.LogLevel.Warning);
}
if (Request != null)
Request.Deserialize(map);
}

View File

@@ -158,6 +158,10 @@ namespace OpenMetaverse
/// <summary>Enable/disable sending periodic camera updates</summary>
public bool SEND_AGENT_UPDATES = true;
/// <summary>Enable/disable automatically setting agent appearance at
/// login and after sim crossing</summary>
public bool SEND_AGENT_APPEARANCE = true;
/// <summary>Enable/disable automatically setting the bandwidth throttle
/// after connecting to each simulator</summary>
/// <remarks>The default throttle uses the equivalent of the maximum

View File

@@ -35,15 +35,7 @@ namespace OpenMetaverse
/// </summary>
public static class Parallel
{
private static int threadCount = System.Environment.ProcessorCount;
/// <summary>The number of parallel threads to run tasks on. Defaults
/// to the number of system processors</summary>
public static int ThreadCount
{
get { return threadCount; }
set { threadCount = Math.Max(1, value); }
}
private static readonly int processorCount = System.Environment.ProcessorCount;
/// <summary>
/// Executes a for loop in which iterations may run in parallel
@@ -52,6 +44,18 @@ namespace OpenMetaverse
/// <param name="toExclusive">The loop will be terminated before this index is reached</param>
/// <param name="body">Method body to run for each iteration of the loop</param>
public static void For(int fromInclusive, int toExclusive, Action<int> body)
{
For(processorCount, fromInclusive, toExclusive, body);
}
/// <summary>
/// Executes a for loop in which iterations may run in parallel
/// </summary>
/// <param name="threadCount">The number of concurrent execution threads to run</param>
/// <param name="fromInclusive">The loop will be started at this index</param>
/// <param name="toExclusive">The loop will be terminated before this index is reached</param>
/// <param name="body">Method body to run for each iteration of the loop</param>
public static void For(int threadCount, int fromInclusive, int toExclusive, Action<int> body)
{
AutoResetEvent[] threadFinishEvent = new AutoResetEvent[threadCount];
--fromInclusive;
@@ -67,12 +71,12 @@ namespace OpenMetaverse
while (true)
{
int index = Interlocked.Increment(ref fromInclusive);
int currentIndex = Interlocked.Increment(ref fromInclusive);
if (index >= toExclusive)
if (currentIndex >= toExclusive)
break;
body(index);
body(currentIndex);
}
threadFinishEvent[threadIndex].Set();
@@ -91,6 +95,18 @@ namespace OpenMetaverse
/// <param name="enumerable">An enumerable collection to iterate over</param>
/// <param name="body">Method body to run for each object in the collection</param>
public static void ForEach<T>(IEnumerable<T> enumerable, Action<T> body)
{
ForEach<T>(processorCount, enumerable, body);
}
/// <summary>
/// Executes a foreach loop in which iterations may run in parallel
/// </summary>
/// <typeparam name="T">Object type that the collection wraps</typeparam>
/// <param name="threadCount">The number of concurrent execution threads to run</param>
/// <param name="enumerable">An enumerable collection to iterate over</param>
/// <param name="body">Method body to run for each object in the collection</param>
public static void ForEach<T>(int threadCount, IEnumerable<T> enumerable, Action<T> body)
{
AutoResetEvent[] threadFinishEvent = new AutoResetEvent[threadCount];
IEnumerator<T> enumerator = enumerable.GetEnumerator();
@@ -113,7 +129,7 @@ namespace OpenMetaverse
{
if (!enumerator.MoveNext())
break;
entry = enumerator.Current;
entry = (T)enumerator.Current; // Explicit typecast for Mono's sake
}
body(entry);
@@ -127,5 +143,52 @@ namespace OpenMetaverse
for (int i = 0; i < threadCount; i++)
threadFinishEvent[i].WaitOne();
}
/// <summary>
/// Executes a series of tasks in parallel
/// </summary>
/// <param name="actions">A series of method bodies to execute</param>
public static void Invoke(params Action[] actions)
{
Invoke(processorCount, actions);
}
/// <summary>
/// Executes a series of tasks in parallel
/// </summary>
/// <param name="threadCount">The number of concurrent execution threads to run</param>
/// <param name="actions">A series of method bodies to execute</param>
public static void Invoke(int threadCount, params Action[] actions)
{
AutoResetEvent[] threadFinishEvent = new AutoResetEvent[threadCount];
int index = -1;
for (int i = 0; i < threadCount; i++)
{
threadFinishEvent[i] = new AutoResetEvent(false);
ThreadPool.QueueUserWorkItem(
delegate(object o)
{
int threadIndex = (int)o;
while (true)
{
int currentIndex = Interlocked.Increment(ref index);
if (currentIndex >= actions.Length)
break;
actions[currentIndex]();
}
threadFinishEvent[threadIndex].Set();
}, i
);
}
for (int i = 0; i < threadCount; i++)
threadFinishEvent[i].WaitOne();
}
}
}

View File

@@ -282,30 +282,30 @@ namespace AvatarPreview
#region Baking
Dictionary<int, float> paramValues = GetParamValues();
Dictionary<AppearanceManager.TextureIndex, AssetTexture> layers =
new Dictionary<AppearanceManager.TextureIndex, AssetTexture>();
Dictionary<AvatarTextureIndex, AssetTexture> layers =
new Dictionary<AvatarTextureIndex, AssetTexture>();
int textureCount = 0;
if ((string)control.Tag == "Head")
{
if (picHair.Image != null)
{
layers.Add(AppearanceManager.TextureIndex.Hair,
layers.Add(AvatarTextureIndex.Hair,
new AssetTexture(new ManagedImage((Bitmap)picHair.Image)));
++textureCount;
}
if (picHeadBodypaint.Image != null)
{
layers.Add(AppearanceManager.TextureIndex.HeadBodypaint,
layers.Add(AvatarTextureIndex.HeadBodypaint,
new AssetTexture(new ManagedImage((Bitmap)picHeadBodypaint.Image)));
++textureCount;
}
// Compute the head bake
Baker baker = new Baker(
_client, AppearanceManager.BakeType.Head, textureCount, paramValues);
_client, BakeType.Head, textureCount, paramValues);
foreach (KeyValuePair<AppearanceManager.TextureIndex, AssetTexture> kvp in layers)
foreach (KeyValuePair<AvatarTextureIndex, AssetTexture> kvp in layers)
baker.AddTexture(kvp.Key, kvp.Value, false);
if (baker.BakedTexture != null)
@@ -324,40 +324,40 @@ namespace AvatarPreview
{
if (picUpperBodypaint.Image != null)
{
layers.Add(AppearanceManager.TextureIndex.UpperBodypaint,
layers.Add(AvatarTextureIndex.UpperBodypaint,
new AssetTexture(new ManagedImage((Bitmap)picUpperBodypaint.Image)));
++textureCount;
}
if (picUpperGloves.Image != null)
{
layers.Add(AppearanceManager.TextureIndex.UpperGloves,
layers.Add(AvatarTextureIndex.UpperGloves,
new AssetTexture(new ManagedImage((Bitmap)picUpperGloves.Image)));
++textureCount;
}
if (picUpperUndershirt.Image != null)
{
layers.Add(AppearanceManager.TextureIndex.UpperUndershirt,
layers.Add(AvatarTextureIndex.UpperUndershirt,
new AssetTexture(new ManagedImage((Bitmap)picUpperUndershirt.Image)));
++textureCount;
}
if (picUpperShirt.Image != null)
{
layers.Add(AppearanceManager.TextureIndex.UpperShirt,
layers.Add(AvatarTextureIndex.UpperShirt,
new AssetTexture(new ManagedImage((Bitmap)picUpperShirt.Image)));
++textureCount;
}
if (picUpperJacket.Image != null)
{
layers.Add(AppearanceManager.TextureIndex.UpperJacket,
layers.Add(AvatarTextureIndex.UpperJacket,
new AssetTexture(new ManagedImage((Bitmap)picUpperJacket.Image)));
++textureCount;
}
// Compute the upper body bake
Baker baker = new Baker(
_client, AppearanceManager.BakeType.UpperBody, textureCount, paramValues);
_client, BakeType.UpperBody, textureCount, paramValues);
foreach (KeyValuePair<AppearanceManager.TextureIndex, AssetTexture> kvp in layers)
foreach (KeyValuePair<AvatarTextureIndex, AssetTexture> kvp in layers)
baker.AddTexture(kvp.Key, kvp.Value, false);
if (baker.BakedTexture != null)
@@ -376,40 +376,40 @@ namespace AvatarPreview
{
if (picLowerBodypaint.Image != null)
{
layers.Add(AppearanceManager.TextureIndex.LowerBodypaint,
layers.Add(AvatarTextureIndex.LowerBodypaint,
new AssetTexture(new ManagedImage((Bitmap)picLowerBodypaint.Image)));
++textureCount;
}
if (picLowerUnderpants.Image != null)
{
layers.Add(AppearanceManager.TextureIndex.LowerUnderpants,
layers.Add(AvatarTextureIndex.LowerUnderpants,
new AssetTexture(new ManagedImage((Bitmap)picLowerUnderpants.Image)));
++textureCount;
}
if (picLowerSocks.Image != null)
{
layers.Add(AppearanceManager.TextureIndex.LowerSocks,
layers.Add(AvatarTextureIndex.LowerSocks,
new AssetTexture(new ManagedImage((Bitmap)picLowerSocks.Image)));
++textureCount;
}
if (picLowerShoes.Image != null)
{
layers.Add(AppearanceManager.TextureIndex.LowerShoes,
layers.Add(AvatarTextureIndex.LowerShoes,
new AssetTexture(new ManagedImage((Bitmap)picLowerShoes.Image)));
++textureCount;
}
if (picLowerPants.Image != null)
{
layers.Add(AppearanceManager.TextureIndex.LowerPants,
layers.Add(AvatarTextureIndex.LowerPants,
new AssetTexture(new ManagedImage((Bitmap)picLowerPants.Image)));
++textureCount;
}
// Compute the lower body bake
Baker baker = new Baker(
_client, AppearanceManager.BakeType.LowerBody, textureCount, paramValues);
_client, BakeType.LowerBody, textureCount, paramValues);
foreach (KeyValuePair<AppearanceManager.TextureIndex, AssetTexture> kvp in layers)
foreach (KeyValuePair<AvatarTextureIndex, AssetTexture> kvp in layers)
baker.AddTexture(kvp.Key, kvp.Value, false);
if (baker.BakedTexture != null)

View File

@@ -63,7 +63,6 @@ namespace Dashboard
Client.Settings.USE_LLSD_LOGIN = true;
Client.Settings.USE_ASSET_CACHE = true;
Client.Network.OnCurrentSimChanged += new NetworkManager.CurrentSimChangedCallback(Network_OnCurrentSimChanged);
Client.Network.OnDisconnected += new NetworkManager.DisconnectedCallback(Network_OnDisconnected);
Client.Self.OnInstantMessage += new AgentManager.InstantMessageCallback(Self_OnInstantMessage);
@@ -101,11 +100,6 @@ namespace Dashboard
MessageBox.Show(group.Name + " = " + group.ID);
}
void Network_OnCurrentSimChanged(Simulator PreviousSimulator)
{
Client.Appearance.SetPreviousAppearance(false);
}
void Network_OnDisconnected(NetworkManager.DisconnectType reason, string message)
{
InitializeClient(!ShuttingDown);

View File

@@ -12,35 +12,14 @@ namespace OpenMetaverse.TestClient
public AppearanceCommand(TestClient testClient)
{
Name = "appearance";
Description = "Set your current appearance to your last saved appearance";
Description = "Set your current appearance to your last saved appearance. Usage: appearance [rebake]";
Category = CommandCategory.Appearance;
}
public override string Execute(string[] args, UUID fromAgentID)
{
bool success = false;
// Register a handler for the appearance event
AutoResetEvent appearanceEvent = new AutoResetEvent(false);
AppearanceManager.AppearanceUpdatedCallback callback =
delegate(Primitive.TextureEntry te) { appearanceEvent.Set(); };
Client.Appearance.OnAppearanceUpdated += callback;
// Start the appearance setting process (with baking enabled or disabled)
Client.Appearance.SetPreviousAppearance(!(args.Length > 0 && args[0].Equals("nobake")));
// Wait for the process to complete or time out
if (appearanceEvent.WaitOne(1000 * 120, false))
success = true;
// Unregister the handler
Client.Appearance.OnAppearanceUpdated -= callback;
// Return success or failure message
if (success)
return "Successfully set appearance";
else
return "Timed out while setting appearance";
Client.Appearance.RequestSetAppearance((args.Length > 0 && args[0].Equals("rebake")));
return "Appearance sequence started";
}
}
}

View File

@@ -37,7 +37,7 @@ namespace OpenMetaverse.TestClient.Commands.Appearance
if (foundAv.Textures.FaceTextures[i] != null)
{
Primitive.TextureEntryFace face = foundAv.Textures.FaceTextures[i];
AppearanceManager.TextureIndex type = (AppearanceManager.TextureIndex)i;
AvatarTextureIndex type = (AvatarTextureIndex)i;
output.AppendFormat("{0}: {1}", type, face.TextureID);
output.AppendLine();

View File

@@ -31,16 +31,9 @@ namespace OpenMetaverse.TestClient
target = target.TrimEnd();
try
{
Client.Appearance.WearOutfit(target.Split('/'), bake);
}
catch (InvalidOutfitException ex)
{
return "Invalid outfit (" + ex.Message + ")";
}
//Client.Appearance.WearOutfit(target.Split('/'), bake);
return String.Empty;
return "FIXME: Implement this";
}
}
}

View File

@@ -31,22 +31,19 @@ namespace OpenMetaverse.TestClient
// initialize results list
List<InventoryBase> found = new List<InventoryBase>();
try
// find the folder
found = Client.Inventory.LocalFind(Client.Inventory.Store.RootFolder.UUID, target.Split('/'), 0, true);
if (found.Count.Equals(1))
{
// find the folder
found = Client.Inventory.LocalFind(Client.Inventory.Store.RootFolder.UUID, target.Split('/'), 0, true);
if (found.Count.Equals(1))
{
// move the folder to the trash folder
Client.Inventory.MoveFolder(found[0].UUID, Client.Inventory.FindFolderForType(AssetType.TrashFolder));
return String.Format("Moved folder {0} to Trash", found[0].Name);
}
// move the folder to the trash folder
Client.Inventory.MoveFolder(found[0].UUID, Client.Inventory.FindFolderForType(AssetType.TrashFolder));
return String.Format("Moved folder {0} to Trash", found[0].Name);
}
catch (InvalidOutfitException ex)
{
return "Folder Not Found: (" + ex.Message + ")";
}
return string.Empty;
return String.Empty;
}
}
}

View File

@@ -55,20 +55,20 @@ namespace OpenMetaverse.TestClient
{
ImageType type = ImageType.Normal;
switch ((AppearanceManager.TextureIndex)j)
switch ((AvatarTextureIndex)j)
{
case AppearanceManager.TextureIndex.HeadBaked:
case AppearanceManager.TextureIndex.EyesBaked:
case AppearanceManager.TextureIndex.UpperBaked:
case AppearanceManager.TextureIndex.LowerBaked:
case AppearanceManager.TextureIndex.SkirtBaked:
case AvatarTextureIndex.HeadBaked:
case AvatarTextureIndex.EyesBaked:
case AvatarTextureIndex.UpperBaked:
case AvatarTextureIndex.LowerBaked:
case AvatarTextureIndex.SkirtBaked:
type = ImageType.Baked;
break;
}
OutfitAssets.Add(face.TextureID);
Client.Assets.RequestImage(face.TextureID, type, Assets_OnImageReceived);
output.Append(((AppearanceManager.TextureIndex)j).ToString());
output.Append(((AvatarTextureIndex)j).ToString());
output.Append(" ");
}
}

View File

@@ -60,14 +60,14 @@ namespace OpenMetaverse.TestClient
// Determine if this is a baked outfit texture or a normal texture
ImageType type = ImageType.Normal;
AppearanceManager.TextureIndex index = (AppearanceManager.TextureIndex)i;
AvatarTextureIndex index = (AvatarTextureIndex)i;
switch (index)
{
case AppearanceManager.TextureIndex.EyesBaked:
case AppearanceManager.TextureIndex.HeadBaked:
case AppearanceManager.TextureIndex.LowerBaked:
case AppearanceManager.TextureIndex.SkirtBaked:
case AppearanceManager.TextureIndex.UpperBaked:
case AvatarTextureIndex.EyesBaked:
case AvatarTextureIndex.HeadBaked:
case AvatarTextureIndex.LowerBaked:
case AvatarTextureIndex.SkirtBaked:
case AvatarTextureIndex.UpperBaked:
type = ImageType.Baked;
break;
}