public ObjectDataBlockUpdateEventArgs(Simulator simulator, Primitive prim, Primitive.ConstructionData constructionData, ObjectUpdatePacket.ObjectDataBlock block, ObjectMovementUpdate objectupdate, NameValue[] nameValues) { this.m_Simulator = simulator; this.m_Prim = prim; this.m_ConstructionData = constructionData; this.m_Block = block; this.m_Update = objectupdate; this.m_NameValues = nameValues; }
/// <summary> /// A terse object update, used when a transformation matrix or /// velocity/acceleration for an object changes but nothing else /// (scale/position/rotation/acceleration/velocity) /// </summary> /// <param name="sender">The sender</param> /// <param name="e">The EventArgs object containing the packet data</param> protected void ImprovedTerseObjectUpdateHandler(object sender, PacketReceivedEventArgs e) { Packet packet = e.Packet; Simulator simulator = e.Simulator; ImprovedTerseObjectUpdatePacket terse = (ImprovedTerseObjectUpdatePacket)packet; UpdateDilation(simulator, terse.RegionData.TimeDilation); for (int i = 0; i < terse.ObjectData.Length; i++) { ImprovedTerseObjectUpdatePacket.ObjectDataBlock block = terse.ObjectData[i]; try { int pos = 4; uint localid = Utils.BytesToUInt(block.Data, 0); // Check if we are interested in this update if (!Client.Settings.ALWAYS_DECODE_OBJECTS && localid != Client.Self.localID && m_TerseObjectUpdate == null) { continue; } #region Decode update data ObjectMovementUpdate update = new ObjectMovementUpdate(); // LocalID update.LocalID = localid; // State update.State = block.Data[pos++]; // Avatar boolean update.Avatar = (block.Data[pos++] != 0); // Collision normal for avatar if (update.Avatar) { update.CollisionPlane = new Vector4(block.Data, pos); pos += 16; } // Position update.Position = new Vector3(block.Data, pos); pos += 12; // Velocity update.Velocity = new Vector3( Utils.UInt16ToFloat(block.Data, pos, -128.0f, 128.0f), Utils.UInt16ToFloat(block.Data, pos + 2, -128.0f, 128.0f), Utils.UInt16ToFloat(block.Data, pos + 4, -128.0f, 128.0f)); pos += 6; // Acceleration update.Acceleration = new Vector3( Utils.UInt16ToFloat(block.Data, pos, -64.0f, 64.0f), Utils.UInt16ToFloat(block.Data, pos + 2, -64.0f, 64.0f), Utils.UInt16ToFloat(block.Data, pos + 4, -64.0f, 64.0f)); pos += 6; // Rotation (theta) update.Rotation = new Quaternion( Utils.UInt16ToFloat(block.Data, pos, -1.0f, 1.0f), Utils.UInt16ToFloat(block.Data, pos + 2, -1.0f, 1.0f), Utils.UInt16ToFloat(block.Data, pos + 4, -1.0f, 1.0f), Utils.UInt16ToFloat(block.Data, pos + 6, -1.0f, 1.0f)); pos += 8; // Angular velocity (omega) update.AngularVelocity = new Vector3( Utils.UInt16ToFloat(block.Data, pos, -64.0f, 64.0f), Utils.UInt16ToFloat(block.Data, pos + 2, -64.0f, 64.0f), Utils.UInt16ToFloat(block.Data, pos + 4, -64.0f, 64.0f)); pos += 6; // Textures // FIXME: Why are we ignoring the first four bytes here? if (block.TextureEntry.Length != 0) update.Textures = new Primitive.TextureEntry(block.TextureEntry, 4, block.TextureEntry.Length - 4); #endregion Decode update data Primitive obj = !Client.Settings.OBJECT_TRACKING ? null : (update.Avatar) ? (Primitive)GetAvatar(simulator, update.LocalID, UUID.Zero) : (Primitive)GetPrimitive(simulator, update.LocalID, UUID.Zero); // Fire the pre-emptive notice (before we stomp the object) OnTerseObjectUpdate(new TerseObjectUpdateEventArgs(simulator, obj, update, terse.RegionData.TimeDilation)); #region Update Client.Self if (update.LocalID == Client.Self.localID) { Client.Self.collisionPlane = update.CollisionPlane; Client.Self.relativePosition = update.Position; Client.Self.velocity = update.Velocity; Client.Self.acceleration = update.Acceleration; Client.Self.relativeRotation = update.Rotation; Client.Self.angularVelocity = update.AngularVelocity; } #endregion Update Client.Self if (Client.Settings.OBJECT_TRACKING && obj != null) { obj.Position = update.Position; obj.Rotation = update.Rotation; obj.Velocity = update.Velocity; obj.CollisionPlane = update.CollisionPlane; obj.Acceleration = update.Acceleration; obj.AngularVelocity = update.AngularVelocity; obj.PrimData.State = update.State; obj.Textures = update.Textures; } } catch (Exception ex) { Logger.Log(ex.Message, Helpers.LogLevel.Warning, Client, ex); } } }
public TerseObjectUpdateEventArgs(Simulator simulator, Primitive prim, ObjectMovementUpdate update, ushort timeDilation) { this.m_Simulator = simulator; this.m_Prim = prim; this.m_Update = update; this.m_TimeDilation = timeDilation; }
public override void UpdateObject(ObjectMovementUpdate objectUpdate, ObjectMovementUpdate objectUpdateDiff) { }
/// <summary>Process an incoming packet and raise the appropriate events</summary> /// <param name="sender">The sender</param> /// <param name="e">The EventArgs object containing the packet data</param> protected void ObjectUpdateHandler(object sender, PacketReceivedEventArgs e) { Packet packet = e.Packet; Simulator simulator = e.Simulator; ObjectUpdatePacket update = (ObjectUpdatePacket)packet; UpdateDilation(e.Simulator, update.RegionData.TimeDilation); for (int b = 0; b < update.ObjectData.Length; b++) { ObjectUpdatePacket.ObjectDataBlock block = update.ObjectData[b]; ObjectMovementUpdate objectupdate = new ObjectMovementUpdate(); //Vector4 collisionPlane = Vector4.Zero; //Vector3 position; //Vector3 velocity; //Vector3 acceleration; //Quaternion rotation; //Vector3 angularVelocity; NameValue[] nameValues; bool attachment = false; PCode pcode = (PCode)block.PCode; #region Relevance check // Check if we are interested in this object if (!Client.Settings.ALWAYS_DECODE_OBJECTS) { switch (pcode) { case PCode.Grass: case PCode.Tree: case PCode.NewTree: case PCode.Prim: if (m_ObjectUpdate == null) continue; break; case PCode.Avatar: // Make an exception for updates about our own agent if (block.FullID != Client.Self.AgentID && m_AvatarUpdate == null) continue; break; case PCode.ParticleSystem: continue; // TODO: Do something with these } } #endregion Relevance check #region NameValue parsing string nameValue = Utils.BytesToString(block.NameValue); if (nameValue.Length > 0) { string[] lines = nameValue.Split('\n'); nameValues = new NameValue[lines.Length]; for (int i = 0; i < lines.Length; i++) { if (!String.IsNullOrEmpty(lines[i])) { NameValue nv = new NameValue(lines[i]); if (nv.Name == "AttachItemID") attachment = true; nameValues[i] = nv; } } } else { nameValues = new NameValue[0]; } #endregion NameValue parsing #region Decode Object (primitive) parameters Primitive.ConstructionData data = new Primitive.ConstructionData(); data.State = block.State; data.Material = (Material)block.Material; data.PathCurve = (PathCurve)block.PathCurve; data.profileCurve = block.ProfileCurve; data.PathBegin = Primitive.UnpackBeginCut(block.PathBegin); data.PathEnd = Primitive.UnpackEndCut(block.PathEnd); data.PathScaleX = Primitive.UnpackPathScale(block.PathScaleX); data.PathScaleY = Primitive.UnpackPathScale(block.PathScaleY); data.PathShearX = Primitive.UnpackPathShear((sbyte)block.PathShearX); data.PathShearY = Primitive.UnpackPathShear((sbyte)block.PathShearY); data.PathTwist = Primitive.UnpackPathTwist(block.PathTwist); data.PathTwistBegin = Primitive.UnpackPathTwist(block.PathTwistBegin); data.PathRadiusOffset = Primitive.UnpackPathTwist(block.PathRadiusOffset); data.PathTaperX = Primitive.UnpackPathTaper(block.PathTaperX); data.PathTaperY = Primitive.UnpackPathTaper(block.PathTaperY); data.PathRevolutions = Primitive.UnpackPathRevolutions(block.PathRevolutions); data.PathSkew = Primitive.UnpackPathTwist(block.PathSkew); data.ProfileBegin = Primitive.UnpackBeginCut(block.ProfileBegin); data.ProfileEnd = Primitive.UnpackEndCut(block.ProfileEnd); data.ProfileHollow = Primitive.UnpackProfileHollow(block.ProfileHollow); data.PCode = pcode; #endregion #region Decode Additional packed parameters in ObjectData int pos = 0; switch (block.ObjectData.Length) { case 76: // Collision normal for avatar objectupdate.CollisionPlane = new Vector4(block.ObjectData, pos); pos += 16; goto case 60; case 60: // Position objectupdate.Position = new Vector3(block.ObjectData, pos); pos += 12; // Velocity objectupdate.Velocity = new Vector3(block.ObjectData, pos); pos += 12; // Acceleration objectupdate.Acceleration = new Vector3(block.ObjectData, pos); pos += 12; // Rotation (theta) objectupdate.Rotation = new Quaternion(block.ObjectData, pos, true); pos += 12; // Angular velocity (omega) objectupdate.AngularVelocity = new Vector3(block.ObjectData, pos); pos += 12; break; case 48: // Collision normal for avatar objectupdate.CollisionPlane = new Vector4(block.ObjectData, pos); pos += 16; goto case 32; case 32: // The data is an array of unsigned shorts // Position objectupdate.Position = new Vector3( Utils.UInt16ToFloat(block.ObjectData, pos, -0.5f * 256.0f, 1.5f * 256.0f), Utils.UInt16ToFloat(block.ObjectData, pos + 2, -0.5f * 256.0f, 1.5f * 256.0f), Utils.UInt16ToFloat(block.ObjectData, pos + 4, -256.0f, 3.0f * 256.0f)); pos += 6; // Velocity objectupdate.Velocity = new Vector3( Utils.UInt16ToFloat(block.ObjectData, pos, -256.0f, 256.0f), Utils.UInt16ToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f), Utils.UInt16ToFloat(block.ObjectData, pos + 4, -256.0f, 256.0f)); pos += 6; // Acceleration objectupdate.Acceleration = new Vector3( Utils.UInt16ToFloat(block.ObjectData, pos, -256.0f, 256.0f), Utils.UInt16ToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f), Utils.UInt16ToFloat(block.ObjectData, pos + 4, -256.0f, 256.0f)); pos += 6; // Rotation (theta) objectupdate.Rotation = new Quaternion( Utils.UInt16ToFloat(block.ObjectData, pos, -1.0f, 1.0f), Utils.UInt16ToFloat(block.ObjectData, pos + 2, -1.0f, 1.0f), Utils.UInt16ToFloat(block.ObjectData, pos + 4, -1.0f, 1.0f), Utils.UInt16ToFloat(block.ObjectData, pos + 6, -1.0f, 1.0f)); pos += 8; // Angular velocity (omega) objectupdate.AngularVelocity = new Vector3( Utils.UInt16ToFloat(block.ObjectData, pos, -256.0f, 256.0f), Utils.UInt16ToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f), Utils.UInt16ToFloat(block.ObjectData, pos + 4, -256.0f, 256.0f)); pos += 6; break; case 16: // The data is an array of single bytes (8-bit numbers) // Position objectupdate.Position = new Vector3( Utils.ByteToFloat(block.ObjectData, pos, -256.0f, 256.0f), Utils.ByteToFloat(block.ObjectData, pos + 1, -256.0f, 256.0f), Utils.ByteToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f)); pos += 3; // Velocity objectupdate.Velocity = new Vector3( Utils.ByteToFloat(block.ObjectData, pos, -256.0f, 256.0f), Utils.ByteToFloat(block.ObjectData, pos + 1, -256.0f, 256.0f), Utils.ByteToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f)); pos += 3; // Accleration objectupdate.Acceleration = new Vector3( Utils.ByteToFloat(block.ObjectData, pos, -256.0f, 256.0f), Utils.ByteToFloat(block.ObjectData, pos + 1, -256.0f, 256.0f), Utils.ByteToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f)); pos += 3; // Rotation objectupdate.Rotation = new Quaternion( Utils.ByteToFloat(block.ObjectData, pos, -1.0f, 1.0f), Utils.ByteToFloat(block.ObjectData, pos + 1, -1.0f, 1.0f), Utils.ByteToFloat(block.ObjectData, pos + 2, -1.0f, 1.0f), Utils.ByteToFloat(block.ObjectData, pos + 3, -1.0f, 1.0f)); pos += 4; // Angular Velocity objectupdate.AngularVelocity = new Vector3( Utils.ByteToFloat(block.ObjectData, pos, -256.0f, 256.0f), Utils.ByteToFloat(block.ObjectData, pos + 1, -256.0f, 256.0f), Utils.ByteToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f)); pos += 3; break; default: Logger.Log("Got an ObjectUpdate block with ObjectUpdate field length of " + block.ObjectData.Length, Helpers.LogLevel.Warning, Client); continue; } #endregion // Determine the object type and create the appropriate class switch (pcode) { #region Prim and Foliage case PCode.Grass: case PCode.Tree: case PCode.NewTree: case PCode.Prim: bool isNewObject; lock (simulator.ObjectsPrimitives.Dictionary) isNewObject = !simulator.ObjectsPrimitives.ContainsKey(block.ID); Primitive prim = GetPrimitive(simulator, block.ID, block.FullID); // Textures objectupdate.Textures = new Primitive.TextureEntry(block.TextureEntry, 0, block.TextureEntry.Length); OnObjectDataBlockUpdate(new ObjectDataBlockUpdateEventArgs(simulator, prim, data, block, objectupdate, nameValues)); #region Update Prim Info with decoded data prim.Flags = (PrimFlags)block.UpdateFlags; if ((prim.Flags & PrimFlags.ZlibCompressed) != 0) { Logger.Log("Got a ZlibCompressed ObjectUpdate, implement me!", Helpers.LogLevel.Warning, Client); continue; } // Automatically request ObjectProperties for prim if it was rezzed selected. if ((prim.Flags & PrimFlags.CreateSelected) != 0) { SelectObject(simulator, prim.LocalID); } prim.NameValues = nameValues; prim.LocalID = block.ID; prim.ID = block.FullID; prim.ParentID = block.ParentID; prim.RegionHandle = update.RegionData.RegionHandle; prim.Scale = block.Scale; prim.ClickAction = (ClickAction)block.ClickAction; prim.OwnerID = block.OwnerID; prim.MediaURL = Utils.BytesToString(block.MediaURL); prim.Text = Utils.BytesToString(block.Text); prim.TextColor = new Color4(block.TextColor, 0, false, true); // Sound information prim.Sound = block.Sound; prim.SoundFlags = (SoundFlags)block.Flags; prim.SoundGain = block.Gain; prim.SoundRadius = block.Radius; // Joint information prim.Joint = (JointType)block.JointType; prim.JointPivot = block.JointPivot; prim.JointAxisOrAnchor = block.JointAxisOrAnchor; // Object parameters prim.PrimData = data; // Textures, texture animations, particle system, and extra params prim.Textures = objectupdate.Textures; prim.TextureAnim = new Primitive.TextureAnimation(block.TextureAnim, 0); prim.ParticleSys = new Primitive.ParticleSystem(block.PSBlock, 0); prim.SetExtraParamsFromBytes(block.ExtraParams, 0); // PCode-specific data switch (pcode) { case PCode.Grass: case PCode.Tree: case PCode.NewTree: if (block.Data.Length == 1) prim.TreeSpecies = (Tree)block.Data[0]; else Logger.Log("Got a foliage update with an invalid TreeSpecies field", Helpers.LogLevel.Warning); // prim.ScratchPad = Utils.EmptyBytes; // break; //default: // prim.ScratchPad = new byte[block.Data.Length]; // if (block.Data.Length > 0) // Buffer.BlockCopy(block.Data, 0, prim.ScratchPad, 0, prim.ScratchPad.Length); break; } prim.ScratchPad = Utils.EmptyBytes; // Packed parameters prim.CollisionPlane = objectupdate.CollisionPlane; prim.Position = objectupdate.Position; prim.Velocity = objectupdate.Velocity; prim.Acceleration = objectupdate.Acceleration; prim.Rotation = objectupdate.Rotation; prim.AngularVelocity = objectupdate.AngularVelocity; #endregion OnObjectUpdate(new PrimEventArgs(simulator, prim, update.RegionData.TimeDilation, isNewObject, attachment)); break; #endregion Prim and Foliage #region Avatar case PCode.Avatar: bool isNewAvatar; lock (simulator.ObjectsAvatars.Dictionary) isNewAvatar = !simulator.ObjectsAvatars.ContainsKey(block.ID); // Update some internals if this is our avatar if (block.FullID == Client.Self.AgentID && simulator == Client.Network.CurrentSim) { #region Update Client.Self // We need the local ID to recognize terse updates for our agent Client.Self.localID = block.ID; // Packed parameters Client.Self.collisionPlane = objectupdate.CollisionPlane; Client.Self.relativePosition = objectupdate.Position; Client.Self.velocity = objectupdate.Velocity; Client.Self.acceleration = objectupdate.Acceleration; Client.Self.relativeRotation = objectupdate.Rotation; Client.Self.angularVelocity = objectupdate.AngularVelocity; #endregion } #region Create an Avatar from the decoded data Avatar avatar = GetAvatar(simulator, block.ID, block.FullID); objectupdate.Avatar = true; // Textures objectupdate.Textures = new Primitive.TextureEntry(block.TextureEntry, 0, block.TextureEntry.Length); OnObjectDataBlockUpdate(new ObjectDataBlockUpdateEventArgs(simulator, avatar, data, block, objectupdate, nameValues)); uint oldSeatID = avatar.ParentID; avatar.ID = block.FullID; avatar.LocalID = block.ID; avatar.CollisionPlane = objectupdate.CollisionPlane; avatar.Position = objectupdate.Position; avatar.Velocity = objectupdate.Velocity; avatar.Acceleration = objectupdate.Acceleration; avatar.Rotation = objectupdate.Rotation; avatar.AngularVelocity = objectupdate.AngularVelocity; avatar.NameValues = nameValues; avatar.PrimData = data; if (block.Data.Length > 0) { Logger.Log("Unexpected Data field for an avatar update, length " + block.Data.Length, Helpers.LogLevel.Warning); } avatar.ParentID = block.ParentID; avatar.RegionHandle = update.RegionData.RegionHandle; SetAvatarSittingOn(simulator, avatar, block.ParentID, oldSeatID); // Textures avatar.Textures = objectupdate.Textures; #endregion Create an Avatar from the decoded data OnAvatarUpdate(new AvatarUpdateEventArgs(simulator, avatar, update.RegionData.TimeDilation, isNewAvatar)); break; #endregion Avatar case PCode.ParticleSystem: DecodeParticleUpdate(block); // TODO: Create a callback for particle updates break; default: Logger.DebugLog("Got an ObjectUpdate block with an unrecognized PCode " + pcode.ToString(), Client); break; } } }
public static void updateToPrim(Primitive prim, ObjectMovementUpdate update) { prim.Acceleration = update.Acceleration; prim.AngularVelocity = update.AngularVelocity; prim.CollisionPlane = update.CollisionPlane; prim.Position = update.Position; prim.Rotation = update.Rotation; prim.PrimData.State = update.State; if (update.Textures != null) prim.Textures = update.Textures; prim.Velocity = update.Velocity; }
private void PrimtiveBlockUpdate(Simulator simulator, ObjectMovementUpdate objectupdate0, Primitive prim,ObjectUpdatePacket.ObjectDataBlock block, Primitive.ConstructionData data) { bool isNewPrim = prim.Scale == Vector3.Zero && prim.Position == Vector3.Zero && prim.NameValues == null; if (prim.ID == UUID.Zero) { if (!simulator.Client.Settings.OBJECT_TRACKING) { throw new ArgumentException("Need to enable object tracking!!"); } SimObject O = GetSimObjectFromUUID(block.FullID); if (O == null) { Debug("PrimData ZERO for " + prim); if (block.ID > 0) { uint localID = block.ID; prim.LocalID = localID; prim.ID = block.FullID; // var p = simulator.Client.Objects.GetPrimitive(simulator, block.ID, block.FullID, false); // simulator.GetPrimitive( } } else { Debug("SimData ZERO for " + prim); uint localID = block.ID; prim.LocalID = localID; prim.ID = block.FullID; O.IsDebugging = true; } } // else { if (prim.RegionHandle == simulator.Handle && prim.ID != UUID.Zero) { if (!prim.PrimData.Equals(data) /* || prim.Scale != block.Scale || prim.Position != objectupdate.Position || prim.Rotation != objectupdate.Rotation || prim.ParentID != block.ParentID*/ ) { SimObject O = GetSimObjectFromUUID(prim.ID); if (O != null) { if (!isNewPrim) { Debug("PrimData changed for " + prim); O.PathFinding.RemoveCollisions(); } // the old OnNewPrim code will force the reindexing } else { //Debug("PrimData new for " + prim); O = GetSimObject(prim, simulator); return; } } if (!isNewPrim) { DeclareProperties(prim, prim.Properties, simulator); SendNewRegionEvent(SimEventType.DATA_UPDATE, "on-data-updated", prim); } //Objects_OnPrimitiveUpdate(simulator, prim, objectupdate0, simulator.Handle, 0); } else { //if (prim.RegionHandle == 0) // prim.RegionHandle = simulator.Handle; if (prim.ID != UUID.Zero) { SimObject O = GetSimObjectFromUUID(prim.ID); if (O != null && prim.Properties != null && prim.RegionHandle == simulator.Handle) { Objects_OnPrimitiveUpdateReal(simulator, prim, objectupdate0, simulator.Handle, 0); //O = GetSimObject(prim, simulator); } } } } }
public static ObjectMovementUpdate updatFromSimObject(SimObject from) { ObjectMovementUpdate update = new ObjectMovementUpdate(); if (from.Prim != null) { update.Acceleration = from.Prim.Acceleration; update.AngularVelocity = from.Prim.AngularVelocity; update.CollisionPlane = from.Prim.CollisionPlane; update.Position = from.Prim.Position; update.Rotation = from.Prim.Rotation; update.State = from.Prim.PrimData.State; if (from.Prim.Textures != null) update.Textures = from.Prim.Textures; update.Velocity = from.Prim.Velocity; update.LocalID = from.Prim.LocalID; } update.Avatar = (from is SimAvatar); return update; }
public static ObjectMovementUpdate updateDiff(ObjectMovementUpdate fromPrim, ObjectMovementUpdate diff) { ObjectMovementUpdate update;// = new ObjectMovementUpdate(); update.LocalID = fromPrim.LocalID; update.Avatar = fromPrim.Avatar; update.Acceleration = fromPrim.Acceleration - diff.Acceleration; update.AngularVelocity = fromPrim.AngularVelocity - diff.AngularVelocity; update.CollisionPlane = fromPrim.CollisionPlane - diff.CollisionPlane; update.Position = fromPrim.Position - diff.Position; update.Rotation = fromPrim.Rotation - diff.Rotation; update.State = (byte)(fromPrim.State - diff.State); update.Textures = fromPrim.Textures != diff.Textures ? diff.Textures : null; update.Velocity = fromPrim.Velocity - diff.Velocity; return update; }
private Object notifyUpdate(SimObject objectUpdated, ObjectMovementUpdate before, ObjectMovementUpdate after, DoWhat didUpdate) { ObjectMovementUpdate diff = updateDiff(before, after); bool wasChanged = false; bool wasPositionUpdateSent = false; if (before.Acceleration != after.Acceleration) { after.Acceleration = (Vector3) didUpdate(objectUpdated, "Acceleration", before.Acceleration, after.Acceleration, diff.Acceleration); wasChanged = true; } if (before.AngularVelocity != after.AngularVelocity) { after.AngularVelocity = (Vector3) didUpdate(objectUpdated, "AngularVelocity", before.AngularVelocity, after.AngularVelocity, diff.AngularVelocity); wasChanged = true; } if (false) if (before.CollisionPlane != after.CollisionPlane) { after.CollisionPlane = (Vector4) didUpdate(objectUpdated, "CollisionPlane", before.CollisionPlane, after.CollisionPlane, diff.CollisionPlane); wasChanged = true; } if (before.Position != after.Position) { after.Position = (Vector3)didUpdate(objectUpdated, "Position", before.Position, after.Position, diff.Position); wasChanged = true; wasPositionUpdateSent = true; } Quaternion diff1 = before.Rotation - after.Rotation; if (diff1.Length() > 0.1f) { after.Rotation = (Quaternion)didUpdate(objectUpdated, "Rotation", before.Rotation, after.Rotation, diff.Rotation); wasChanged = true; } if (false) if (before.State != after.State) { didUpdate(objectUpdated, "State", before.State, after.State, diff.State); wasChanged = true; } if (before.Textures != after.Textures) { //didUpdate(objectUpdated, "Textures", before.Textures, after.Textures, diff.Textures); //wasChanged = true; } if (before.Velocity != after.Velocity) { // didUpdate(objectUpdated, "Velocity", before.Velocity, after.Velocity, diff.Velocity); if (before.Velocity == Vector3.Zero) { SendNewUpdateEvent("on-object-start-velocity", objectUpdated, after.Velocity); if (!wasPositionUpdateSent) SendNewUpdateEvent("on-object-position", objectUpdated, after.Position); } else if (after.Velocity == Vector3.Zero) { if (!wasPositionUpdateSent) SendNewUpdateEvent("on-object-position", objectUpdated, after.Position); SendNewUpdateEvent("on-object-stop-velocity", objectUpdated, -before.Velocity); } else { //SendNewUpdateEvent("on-object-change-velosity", objectUpdated, after.Velocity); if (!wasPositionUpdateSent) SendNewUpdateEvent("on-object-position", objectUpdated, after.Position); } wasChanged = true; } if (!wasChanged) return null; return diff; }
public void Objects_OnObjectUpdated1(Simulator simulator, Primitive objectUpdated, ObjectMovementUpdate update, ulong regionHandle, ushort timeDilation) { if (!IsMaster(simulator)) return; if (objectUpdated != null) { //lock (objectUpdated) { // other OMV code already updated the Primitive // updateToPrim(prim, update); if (objectUpdated.Properties != null) { //CalcStats(objectUpdated); DeclareProperties(objectUpdated, objectUpdated.Properties, simulator); describePrimToAI(objectUpdated, simulator); } else { EnsureSelected(objectUpdated, simulator); } // Make a Last Object Update from the Primitive if we knew nothing about it if (MaintainObjectUpdates) { SimObject simObject = GetSimObject(objectUpdated, simulator); if (simObject != null) { lock (LastObjectUpdate) if (!LastObjectUpdate.ContainsKey(simObject)) { LastObjectUpdate[simObject] = updatFromSimObject(simObject); } if (m_TheSimAvatar != null) { //double dist = simObject.Distance(TheSimAvatar); //if (dist > 30 && !update.Avatar) return; } // Make a "diff" from previous ObjectMovementUpdate up; lock (LastObjectUpdate) up = LastObjectUpdate[simObject]; Object diffO = notifyUpdate(simObject, up, update, InformUpdate); if (diffO != null) { ObjectMovementUpdate diff = (ObjectMovementUpdate) diffO; //if (lastObjectUpdateDiff.ContainsKey(objectUpdated.ID)) //{ // notifyUpdate(objectUpdated, lastObjectUpdateDiff[objectUpdated.ID], diff, InformUpdateDiff); //} lock (LastObjectUpdateDiff) LastObjectUpdateDiff[objectUpdated.ID] = diff; } else { // someThingElseNeedsUpdate(objectUpdated); // needsOsdDiff = true; } ObjectMovementUpdate TheDiff = default(ObjectMovementUpdate); lock (LastObjectUpdateDiff) { if (LastObjectUpdateDiff.ContainsKey(objectUpdated.ID)) { TheDiff = LastObjectUpdateDiff[objectUpdated.ID]; } else { LastObjectUpdateDiff[objectUpdated.ID] = TheDiff; } } simObject.UpdateObject(update, TheDiff); lock (LastObjectUpdate) LastObjectUpdate[simObject] = update; } } } } else { //WriteLine("missing Objects_OnObjectUpdated"); } }
public void Objects_OnPrimitiveUpdateRealDead(Simulator simulator, ObjectMovementUpdate update, ulong regionHandle, ushort timeDilation) { throw new InvalidOperationException("Objects_OnObjectProperties"); /// return; if (simulator.Handle != regionHandle) { Debug("Strange update" + simulator); //base.Objects_OnObjectUpdated(simulator, update, regionHandle, timeDilation); } // return; CheckConnected(simulator); //all things if (update.Avatar) Primitive av = GetPrimitive(update.LocalID, simulator); Objects_OnObjectUpdated1(simulator, av, update, regionHandle, timeDilation); }
private void Objects_OnPrimitiveUpdateReal(Simulator simulator, Primitive av, ObjectMovementUpdate update, ulong RegionHandle, ushort TimeDilation) { if (!IsMaster(simulator)) return; if (av == null) { return; } if (av.ID == UUID.Zero) { return; // too early } SimObject AV = null; Object Obj; //lock (uuidTypeObject) if (UUIDTypeObjectTryGetValue(av.ID, out Obj)) { AV = Obj as SimObject; } else { if (av.ID==client.Self.AgentID) AV = GetSimObject(av, simulator); } if (AV != null) { Primitive prev = AV.Prim; if (prev == null) { AV.SetFirstPrim(av); } if (av.ParentID == 0 && !SimRegion.OutOfRegion(av.Position)) { AV.ResetPrim(av, client, simulator); } if (prev!=null) { // parent changed? if (prev.ParentID != av.ParentID) { AV.Parent = null; } } if (av.ParentID == 0 && !SimRegion.OutOfRegion(update.Position)) { if (update.Avatar) { SimRegion.GetRegion(simulator).UpdateTraveled(av.ID, av.Position, av.Rotation); //return; } } if (!MaintainObjectUpdates) return; EventQueue.Enqueue(() => Objects_OnObjectUpdated1(simulator, av, updatFromSimObject(AV), RegionHandle, TimeDilation)); } }
void Objects_OnObjectUpdated(Simulator simulator, ObjectMovementUpdate update, ulong regionHandle, ushort timeDilation) { if (!update.Avatar) { Primitive prim; if (prims.TryGetValue(update.LocalID, out prim)) { lock (prim) { if (Program.Verbosity > 1) Logger.Log("Updating state for " + prim.ID.ToString(), Helpers.LogLevel.Info); prim.Acceleration = update.Acceleration; prim.AngularVelocity = update.AngularVelocity; prim.CollisionPlane = update.CollisionPlane; prim.Position = update.Position; prim.Rotation = update.Rotation; prim.PrimData.State = update.State; prim.Textures = update.Textures; prim.Velocity = update.Velocity; } UpdateTextureQueue(prim.Textures); } } }