void ObjectDelinkHandler(Packet packet, Agent agent) { ObjectDelinkPacket delink = (ObjectDelinkPacket)packet; List <SimulationObject> linkSet = new List <SimulationObject>(); for (int i = 0; i < delink.ObjectData.Length; i++) { SimulationObject obj; if (!server.Scene.TryGetObject(delink.ObjectData[i].ObjectLocalID, out obj)) { //TODO: send an error message return; } else if (obj.Prim.OwnerID != agent.AgentID) { //TODO: send an error message return; } else { linkSet.Add(obj); } } ObjectUpdatePacket update = new ObjectUpdatePacket(); update.RegionData.RegionHandle = server.RegionHandle; update.RegionData.TimeDilation = UInt16.MaxValue; update.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[linkSet.Count]; for (int i = 0; i < linkSet.Count; i++) { update.ObjectData[i] = SimulationObject.BuildUpdateBlock(linkSet[i].Prim, server.RegionHandle, 0, linkSet[i].Prim.Flags); update.ObjectData[i].ParentID = 0; linkSet[i].LinkNumber = 0; //add root prim orientation to child prims if (i > 0) { linkSet[i].Prim.Position = linkSet[0].Prim.Position + Vector3.Transform(linkSet[i].Prim.Position, Matrix4.CreateFromQuaternion(linkSet[0].Prim.Rotation)); linkSet[i].Prim.Rotation *= linkSet[0].Prim.Rotation; } update.ObjectData[i].ObjectData = SimulationObject.BuildObjectData( linkSet[i].Prim.Position, linkSet[i].Prim.Rotation, Vector3.Zero, Vector3.Zero, Vector3.Zero); } server.UDP.BroadcastPacket(update, PacketCategory.State); }
void ObjectLinkHandler(Packet packet, Agent agent) { ObjectLinkPacket link = (ObjectLinkPacket)packet; List <SimulationObject> linkSet = new List <SimulationObject>(); for (int i = 0; i < link.ObjectData.Length; i++) { SimulationObject obj; if (!server.Scene.TryGetObject(link.ObjectData[i].ObjectLocalID, out obj)) { //TODO: send an error message return; } else if (obj.Prim.OwnerID != agent.AgentID) { //TODO: send an error message return; } else { linkSet.Add(obj); } } for (int i = 0; i < linkSet.Count; i++) { linkSet[i].LinkNumber = i + 1; ObjectUpdatePacket update = new ObjectUpdatePacket(); update.RegionData.RegionHandle = server.RegionHandle; update.RegionData.TimeDilation = UInt16.MaxValue; update.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; update.ObjectData[0] = SimulationObject.BuildUpdateBlock(linkSet[i].Prim, server.RegionHandle, linkSet[i].Prim.PrimData.State, linkSet[i].Prim.Flags); if (linkSet[i].Prim.ParentID > 0) { //previously linked children SimulationObject parent; if (server.Scene.TryGetObject(linkSet[i].Prim.ParentID, out parent)) { //re-add old root orientation linkSet[i].Prim.Position = parent.Prim.Position + Vector3.Transform(linkSet[i].Prim.Position, Matrix4.CreateFromQuaternion(parent.Prim.Rotation)); linkSet[i].Prim.Rotation *= parent.Prim.Rotation; } } if (i > 0) { //subtract root prim orientation linkSet[i].Prim.Position = Vector3.Transform(linkSet[i].Prim.Position - linkSet[0].Prim.Position, Matrix4.CreateFromQuaternion(Quaternion.Identity / linkSet[0].Prim.Rotation)); linkSet[i].Prim.Rotation /= linkSet[0].Prim.Rotation; //set parent ID update.ObjectData[0].ParentID = linkSet[0].Prim.LocalID; } else { //root prim update.ObjectData[0].ParentID = 0; } update.ObjectData[0].ObjectData = SimulationObject.BuildObjectData( linkSet[i].Prim.Position, linkSet[i].Prim.Rotation, Vector3.Zero, Vector3.Zero, Vector3.Zero); server.UDP.BroadcastPacket(update, PacketCategory.State); } }