* More aggressive AgentUpdate timer
* Workaround hack for prims appearing in the wrong position for other clients
* Fixed ViewerEffect handling to copy over multiple Effect blocks, and never send ViewerEffect packets with no blocks (which will crash the sim)
* CopyBot will rotate to face the original avatar (kind of, needs refining)
libsecondlife:
* Added an enum for AttachmentPoint
* Couple additional sanity checks for null simulators after disconnecting
* Can build a quaternion from normalized X/Y/Z only now

git-svn-id: http://libopenmetaverse.googlecode.com/svn/trunk@569 52acb1d6-8a22-11de-b505-999d5b087335
This commit is contained in:
John Hurliman
2006-11-12 11:33:42 +00:00
parent 1afcab8952
commit 3ced78e8ff
3 changed files with 169 additions and 112 deletions

View File

@@ -77,11 +77,11 @@ namespace libsecondlife
public LLVector3 RotationVelocity;
}
/// <summary>
/// Handles all network traffic related to prims and avatar positions and
/// <summary>
/// Handles all network traffic related to prims and avatar positions and
/// movement.
/// </summary>
public class ObjectManager
/// </summary>
public class ObjectManager
{
/// <summary>
///
@@ -90,7 +90,7 @@ namespace libsecondlife
/// <param name="prim"></param>
/// <param name="regionHandle"></param>
/// <param name="timeDilation"></param>
public delegate void NewPrimCallback(Simulator simulator, PrimObject prim, ulong regionHandle,
public delegate void NewPrimCallback(Simulator simulator, PrimObject prim, ulong regionHandle,
ushort timeDilation);
/// <summary>
///
@@ -99,7 +99,7 @@ namespace libsecondlife
/// <param name="avatar"></param>
/// <param name="regionHandle"></param>
/// <param name="timeDilation"></param>
public delegate void NewAvatarCallback(Simulator simulator, Avatar avatar, ulong regionHandle,
public delegate void NewAvatarCallback(Simulator simulator, Avatar avatar, ulong regionHandle,
ushort timeDilation);
/// <summary>
///
@@ -108,7 +108,7 @@ namespace libsecondlife
/// <param name="prim"></param>
/// <param name="regionHandle"></param>
/// <param name="timeDilation"></param>
public delegate void PrimMovedCallback(Simulator simulator, PrimUpdate prim, ulong regionHandle,
public delegate void PrimMovedCallback(Simulator simulator, PrimUpdate prim, ulong regionHandle,
ushort timeDilation);
/// <summary>
///
@@ -117,7 +117,7 @@ namespace libsecondlife
/// <param name="avatar"></param>
/// <param name="regionHandle"></param>
/// <param name="timeDilation"></param>
public delegate void AvatarMovedCallback(Simulator simulator, AvatarUpdate avatar, ulong regionHandle,
public delegate void AvatarMovedCallback(Simulator simulator, AvatarUpdate avatar, ulong regionHandle,
ushort timeDilation);
/// <summary>
///
@@ -167,6 +167,40 @@ namespace libsecondlife
Transfer = 0x00002000
}
public enum AttachmentPoint
{
Chest = 1,
Skull,
LeftShoulder,
RightShoulder,
LeftHand,
RightHand,
LeftFoot,
RightFoot,
Spine,
Pelvis,
Mouth,
Chin,
LeftEar,
RightEar,
LeftEyeball,
RightEyeball,
Nose,
RightUpperArm,
RightForarm,
LeftUpperArm,
LeftForearm,
RightHip,
RightUpperLeg,
RightLowerLeg,
LeftHip,
LeftUpperLeg,
LeftLowerLeg,
Stomach,
LeftPec,
RightPec
}
/// <summary>
/// This event will be raised for every ObjectUpdate block that
/// contains a new prim.
@@ -388,116 +422,116 @@ namespace libsecondlife
foreach (ObjectUpdatePacket.ObjectDataBlock block in update.ObjectData)
{
switch(block.PCode)
{
case (byte)PCode.Prim:
if (OnNewPrim != null)
{
// New prim spotted
PrimObject prim = new PrimObject(Client);
prim.Position = new LLVector3(block.ObjectData, 0);
prim.Rotation = new LLQuaternion(block.ObjectData, 36, true);
// TODO: Parse the rest of the ObjectData byte array fields
prim.LocalID = block.ID;
prim.State = block.State;
prim.ID = block.FullID;
prim.ParentID = block.ParentID;
//block.OwnerID Sound-related
prim.Material = block.Material;
prim.PathCurve = block.PathCurve;
prim.ProfileCurve = block.ProfileCurve;
prim.PathBegin = PrimObject.PathBeginFloat(block.PathBegin);
prim.PathEnd = PrimObject.PathEndFloat(block.PathEnd);
prim.PathScaleX = PrimObject.PathScaleFloat(block.PathScaleX);
prim.PathScaleY = PrimObject.PathScaleFloat(block.PathScaleY);
prim.PathShearX = PrimObject.PathShearFloat(block.PathShearX);
prim.PathShearY = PrimObject.PathShearFloat(block.PathShearY);
prim.PathTwist = block.PathTwist; //PrimObject.PathTwistFloat(block.PathTwist);
prim.PathTwistBegin = block.PathTwistBegin; //PrimObject.PathTwistFloat(block.PathTwistBegin);
prim.PathRadiusOffset = PrimObject.PathRadiusOffsetFloat(block.PathRadiusOffset);
prim.PathTaperX = PrimObject.PathTaperFloat(block.PathTaperX);
prim.PathTaperY = PrimObject.PathTaperFloat(block.PathTaperY);
prim.PathRevolutions = PrimObject.PathRevolutionsFloat(block.PathRevolutions);
prim.PathSkew = PrimObject.PathSkewFloat(block.PathSkew);
prim.ProfileBegin = PrimObject.ProfileBeginFloat(block.ProfileBegin);
prim.ProfileEnd = PrimObject.ProfileEndFloat(block.ProfileEnd);
prim.ProfileHollow = block.ProfileHollow;
prim.Name = Helpers.FieldToString(block.NameValue);
//block.Data ?
prim.Text = ASCIIEncoding.ASCII.GetString(block.Text);
//block.TextColor LLColor4U of the hovering text
//block.MediaURL Quicktime stream
prim.Textures = new TextureEntry(block.TextureEntry, 0, block.TextureEntry.Length);
prim.TextureAnim = new TextureAnimation(block.TextureAnim, 0);
//block.JointType ?
//block.JointPivot ?
//block.JointAxisOrAnchor ?
prim.ParticleSys = new ParticleSystem(block.PSBlock, 0);
prim.SetExtraParamsFromBytes(block.ExtraParams, 0);
prim.Scale = block.Scale;
//block.Flags ?
prim.Flags = (ObjectFlags)block.UpdateFlags;
//block.ClickAction ?
//block.Gain Sound-related
//block.Sound Sound-related
//block.Radius Sound-related
switch (block.PCode)
{
case (byte)PCode.Prim:
if (OnNewPrim != null)
{
OnNewPrim(simulator, prim, update.RegionData.RegionHandle, update.RegionData.TimeDilation);
}
}
break;
case (byte)PCode.Avatar:
if (OnNewAvatar != null)
{
Avatar avatar = new Avatar();
// New prim spotted
PrimObject prim = new PrimObject(Client);
string FirstName = "";
string LastName = "";
string GroupName = "";
prim.Position = new LLVector3(block.ObjectData, 0);
prim.Rotation = new LLQuaternion(block.ObjectData, 36, true);
//avatar.CollisionPlane = new LLQuaternion(block.ObjectData, 0);
avatar.Position = new LLVector3(block.ObjectData, 16);
avatar.Rotation = new LLQuaternion(block.ObjectData, 52, true);
// TODO: Parse the rest of the ObjectData byte array fields
// TODO: Parse the rest of the ObjectData byte array fields
prim.LocalID = block.ID;
prim.State = block.State;
prim.ID = block.FullID;
prim.ParentID = block.ParentID;
//block.OwnerID Sound-related
prim.Material = block.Material;
prim.PathCurve = block.PathCurve;
prim.ProfileCurve = block.ProfileCurve;
prim.PathBegin = PrimObject.PathBeginFloat(block.PathBegin);
prim.PathEnd = PrimObject.PathEndFloat(block.PathEnd);
prim.PathScaleX = PrimObject.PathScaleFloat(block.PathScaleX);
prim.PathScaleY = PrimObject.PathScaleFloat(block.PathScaleY);
prim.PathShearX = PrimObject.PathShearFloat(block.PathShearX);
prim.PathShearY = PrimObject.PathShearFloat(block.PathShearY);
prim.PathTwist = block.PathTwist; //PrimObject.PathTwistFloat(block.PathTwist);
prim.PathTwistBegin = block.PathTwistBegin; //PrimObject.PathTwistFloat(block.PathTwistBegin);
prim.PathRadiusOffset = PrimObject.PathRadiusOffsetFloat(block.PathRadiusOffset);
prim.PathTaperX = PrimObject.PathTaperFloat(block.PathTaperX);
prim.PathTaperY = PrimObject.PathTaperFloat(block.PathTaperY);
prim.PathRevolutions = PrimObject.PathRevolutionsFloat(block.PathRevolutions);
prim.PathSkew = PrimObject.PathSkewFloat(block.PathSkew);
prim.ProfileBegin = PrimObject.ProfileBeginFloat(block.ProfileBegin);
prim.ProfileEnd = PrimObject.ProfileEndFloat(block.ProfileEnd);
prim.ProfileHollow = block.ProfileHollow;
prim.Name = Helpers.FieldToString(block.NameValue);
//block.Data ?
prim.Text = ASCIIEncoding.ASCII.GetString(block.Text);
//block.TextColor LLColor4U of the hovering text
//block.MediaURL Quicktime stream
prim.Textures = new TextureEntry(block.TextureEntry, 0, block.TextureEntry.Length);
prim.TextureAnim = new TextureAnimation(block.TextureAnim, 0);
//block.JointType ?
//block.JointPivot ?
//block.JointAxisOrAnchor ?
prim.ParticleSys = new ParticleSystem(block.PSBlock, 0);
prim.SetExtraParamsFromBytes(block.ExtraParams, 0);
prim.Scale = block.Scale;
//block.Flags ?
prim.Flags = (ObjectFlags)block.UpdateFlags;
//block.ClickAction ?
//block.Gain Sound-related
//block.Sound Sound-related
//block.Radius Sound-related
ParseAvName(Helpers.FieldToString(block.NameValue), ref FirstName, ref LastName, ref GroupName);
avatar.ID = block.FullID;
avatar.LocalID = block.ID;
avatar.Name = FirstName + " " + LastName;
avatar.GroupName = GroupName;
avatar.Online = true;
avatar.CurrentRegion = simulator.Region;
avatar.Textures = new TextureEntry(block.TextureEntry, 0, block.TextureEntry.Length);
if (FirstName == Client.Self.FirstName && LastName == Client.Self.LastName)
{
// Update our avatar
Client.Self.LocalID = avatar.LocalID;
Client.Self.Position = avatar.Position;
Client.Self.Rotation = avatar.Rotation;
}
else
{
if (OnNewAvatar != null)
if (OnNewPrim != null)
{
OnNewAvatar(simulator, avatar, update.RegionData.RegionHandle, update.RegionData.TimeDilation);
OnNewPrim(simulator, prim, update.RegionData.RegionHandle, update.RegionData.TimeDilation);
}
}
}
break;
case (byte)PCode.Grass: // FIXME: Handle grass objects
case (byte)PCode.Tree: // FIXME: Handle trees
case (byte)PCode.ParticleSystem: // FIXME: Handle ParticleSystem
default:
break;
break;
case (byte)PCode.Avatar:
if (OnNewAvatar != null)
{
Avatar avatar = new Avatar();
string FirstName = "";
string LastName = "";
string GroupName = "";
//avatar.CollisionPlane = new LLQuaternion(block.ObjectData, 0);
avatar.Position = new LLVector3(block.ObjectData, 16);
avatar.Rotation = new LLQuaternion(block.ObjectData, 52, true);
// TODO: Parse the rest of the ObjectData byte array fields
ParseAvName(Helpers.FieldToString(block.NameValue), ref FirstName, ref LastName, ref GroupName);
avatar.ID = block.FullID;
avatar.LocalID = block.ID;
avatar.Name = FirstName + " " + LastName;
avatar.GroupName = GroupName;
avatar.Online = true;
avatar.CurrentRegion = simulator.Region;
avatar.Textures = new TextureEntry(block.TextureEntry, 0, block.TextureEntry.Length);
if (FirstName == Client.Self.FirstName && LastName == Client.Self.LastName)
{
// Update our avatar
Client.Self.LocalID = avatar.LocalID;
Client.Self.Position = avatar.Position;
Client.Self.Rotation = avatar.Rotation;
}
else
{
if (OnNewAvatar != null)
{
OnNewAvatar(simulator, avatar, update.RegionData.RegionHandle, update.RegionData.TimeDilation);
}
}
}
break;
case (byte)PCode.Grass: // FIXME: Handle grass objects
case (byte)PCode.Tree: // FIXME: Handle trees
case (byte)PCode.ParticleSystem: // FIXME: Handle ParticleSystem
default:
break;
}
}
}
@@ -521,7 +555,7 @@ namespace libsecondlife
int i = 0;
bool avatar;
localid = (uint)(block.Data[i++] + (block.Data[i++] << 8) +
localid = (uint)(block.Data[i++] + (block.Data[i++] << 8) +
(block.Data[i++] << 16) + (block.Data[i++] << 24));
byte state = block.Data[i++];
@@ -817,7 +851,7 @@ namespace libsecondlife
}
catch (System.IndexOutOfRangeException e)
{
Client.Log("Had a problem decoding an ObjectUpdateCompressed packet: " +
Client.Log("Had a problem decoding an ObjectUpdateCompressed packet: " +
e.ToString(), Helpers.LogLevel.Warning);
Client.Log(block.ToString(), Helpers.LogLevel.Warning);
}