public SimulationObject(SimulationObject obj) { Prim = new Primitive(obj.Prim); Server = obj.Server; LinkNumber = obj.LinkNumber; Frozen = obj.Frozen; // Skip everything else because it can be lazily reconstructed }
public SimpleMesh GetWorldMesh(DetailLevel lod, SimulationObject parent) { int i = (int)lod; if (WorldTransformedMeshes[i] != null) { return WorldTransformedMeshes[i]; } else { // Get the untransformed mesh SimpleMesh mesh = GetMesh(lod); // Copy to our new mesh SimpleMesh transformedMesh = new SimpleMesh(); transformedMesh.Indices = new List<ushort>(mesh.Indices); transformedMesh.Path.Open = mesh.Path.Open; transformedMesh.Path.Points = new List<PathPoint>(mesh.Path.Points); transformedMesh.Prim = mesh.Prim; transformedMesh.Profile.Concave = mesh.Profile.Concave; transformedMesh.Profile.Faces = new List<ProfileFace>(mesh.Profile.Faces); transformedMesh.Profile.MaxX = mesh.Profile.MaxX; transformedMesh.Profile.MinX = mesh.Profile.MinX; transformedMesh.Profile.Open = mesh.Profile.Open; transformedMesh.Profile.Positions = new List<Vector3>(mesh.Profile.Positions); transformedMesh.Profile.TotalOutsidePoints = mesh.Profile.TotalOutsidePoints; transformedMesh.Vertices = new List<Vertex>(mesh.Vertices); // Construct a matrix to transform to world space Matrix4 transform = Matrix4.Identity; if (parent != null) { // Apply parent rotation and translation first transform *= Matrix4.CreateFromQuaternion(parent.Prim.Rotation); transform *= Matrix4.CreateTranslation(parent.Prim.Position); } transform *= Matrix4.CreateScale(this.Prim.Scale); transform *= Matrix4.CreateFromQuaternion(this.Prim.Rotation); transform *= Matrix4.CreateTranslation(this.Prim.Position); // Transform the mesh for (int j = 0; j < transformedMesh.Vertices.Count; j++) { Vertex vertex = transformedMesh.Vertices[j]; vertex.Position *= transform; transformedMesh.Vertices[j] = vertex; } WorldTransformedMeshes[i] = transformedMesh; return transformedMesh; } }
public SimpleMesh GetWorldMesh(DetailLevel lod, SimulationObject parent) { int i = (int)lod; if (WorldTransformedMeshes[i] != null) { return(WorldTransformedMeshes[i]); } else { // Get the untransformed mesh SimpleMesh mesh = GetMesh(lod); // Copy to our new mesh SimpleMesh transformedMesh = new SimpleMesh(); transformedMesh.Indices = new List <ushort>(mesh.Indices); transformedMesh.Path.Open = mesh.Path.Open; transformedMesh.Path.Points = new List <PathPoint>(mesh.Path.Points); transformedMesh.Prim = mesh.Prim; transformedMesh.Profile.Concave = mesh.Profile.Concave; transformedMesh.Profile.Faces = new List <ProfileFace>(mesh.Profile.Faces); transformedMesh.Profile.MaxX = mesh.Profile.MaxX; transformedMesh.Profile.MinX = mesh.Profile.MinX; transformedMesh.Profile.Open = mesh.Profile.Open; transformedMesh.Profile.Positions = new List <Vector3>(mesh.Profile.Positions); transformedMesh.Profile.TotalOutsidePoints = mesh.Profile.TotalOutsidePoints; transformedMesh.Vertices = new List <Vertex>(mesh.Vertices); // Construct a matrix to transform to world space Matrix4 transform = Matrix4.Identity; if (parent != null) { // Apply parent rotation and translation first transform *= Matrix4.CreateFromQuaternion(parent.Prim.Rotation); transform *= Matrix4.CreateTranslation(parent.Prim.Position); } transform *= Matrix4.CreateScale(this.Prim.Scale); transform *= Matrix4.CreateFromQuaternion(this.Prim.Rotation); transform *= Matrix4.CreateTranslation(this.Prim.Position); // Transform the mesh for (int j = 0; j < transformedMesh.Vertices.Count; j++) { Vertex vertex = transformedMesh.Vertices[j]; vertex.Position *= transform; transformedMesh.Vertices[j] = vertex; } WorldTransformedMeshes[i] = transformedMesh; return(transformedMesh); } }
public bool TryGetObject(UUID id, out SimulationObject obj) { return sceneObjects.TryGetValue(id, out obj); }
public SimulationObject(SimulationObject obj) { Scene = obj.Scene; Prim = new Primitive(obj.Prim); Inventory = new SimulationObjectInventory(this); LinkNumber = obj.LinkNumber; frozen = obj.frozen; rotationAxis = obj.rotationAxis; // Skip everything else because it can be lazily reconstructed }
public void ObjectRedo(object sender, SimulationObject obj) { if (OnObjectRedo != null) { OnObjectRedo(sender, obj); } Primitive prim = obj.RedoSteps.DequeueLast(); if (prim != null) { Logger.Log(String.Format("Performing redo on object {0}", obj.Prim.ID), Helpers.LogLevel.Debug); obj.UndoSteps.Enqueue(prim); obj.Prim = prim; // Inform clients ObjectAddOrUpdate(this, obj, obj.Prim.OwnerID, 0, PrimFlags.None, UpdateFlags.FullUpdate); } else { Logger.Log(String.Format("Redo requested on object {0} with no remaining redo steps", obj.Prim.ID), Helpers.LogLevel.Debug); } }
void RemoveObject(object sender, SimulationObject obj) { // If this object has an agent associated with it, remove the agent from the scene as well Agent agent; if (sceneAgents.TryGetValue(obj.Prim.ID, out agent)) AgentRemove(sender, agent); // Remove the agent from the scene sceneObjects.Remove(obj.Prim.LocalID, obj.Prim.ID); // Fire the callback if (OnObjectRemove != null) OnObjectRemove(sender, obj); // If this object has a cached task inventory asset, delete it now if (obj.Inventory.InventorySerial > 0) taskInventory.RemoveTaskFile(obj.Inventory.GetInventoryFilename()); // Broadcast the kill message KillObjectPacket kill = new KillObjectPacket(); kill.ObjectData = new KillObjectPacket.ObjectDataBlock[1]; kill.ObjectData[0] = new KillObjectPacket.ObjectDataBlock(); kill.ObjectData[0].ID = obj.Prim.LocalID; udp.BroadcastPacket(kill, PacketCategory.State); }
public void ObjectApplyRotationalImpulse(object sender, SimulationObject obj, Vector3 impulse) { if (OnObjectApplyRotationalImpulse != null) { OnObjectApplyRotationalImpulse(sender, obj, impulse); } // FIXME: }
public void ObjectSetTorque(object sender, SimulationObject obj, Vector3 torque) { if (OnObjectSetTorque != null) { OnObjectSetTorque(sender, obj, torque); } obj.Torque = torque; }
public void ObjectSetRotationAxis(object sender, SimulationObject obj, Vector3 rotationAxis) { if (OnObjectSetRotationAxis != null) { OnObjectSetRotationAxis(sender, obj, rotationAxis); } // Update the object obj.RotationAxis = rotationAxis; }
public void ObjectAddOrUpdate(object sender, SimulationObject obj, UUID ownerID, int scriptStartParam, PrimFlags creatorFlags, UpdateFlags updateFlags) { if (OnObjectAddOrUpdate != null) { OnObjectAddOrUpdate(sender, obj, ownerID, scriptStartParam, creatorFlags, updateFlags); } #region Initialize new objects // Check if the object already exists in the scene if (!sceneObjects.ContainsKey(obj.Prim.ID)) { // Enable some default flags that all objects will have obj.Prim.Flags |= server.Permissions.GetDefaultObjectFlags(); // Object did not exist before, so there's no way it could contain inventory obj.Prim.Flags |= PrimFlags.InventoryEmpty; // Fun Fact: Prim.OwnerID is only used by the LL viewer to mute sounds obj.Prim.OwnerID = ownerID; // Other than storing tree species, I have no idea what this does obj.Prim.ScratchPad = Utils.EmptyBytes; // Assign a unique LocalID to this object if no LocalID is set if (obj.Prim.LocalID == 0) obj.Prim.LocalID = (uint)Interlocked.Increment(ref currentLocalID); // Assign a random ID to this object if no ID is set if (obj.Prim.ID == UUID.Zero) obj.Prim.ID = UUID.Random(); // Set the RegionHandle if no RegionHandle is set if (obj.Prim.RegionHandle == 0) obj.Prim.RegionHandle = regionHandle; // Make sure this object has properties if (obj.Prim.Properties == null) { obj.Prim.Properties = new Primitive.ObjectProperties(); obj.Prim.Properties.CreationDate = DateTime.Now; obj.Prim.Properties.CreatorID = ownerID; obj.Prim.Properties.Name = "New Object"; obj.Prim.Properties.ObjectID = obj.Prim.ID; obj.Prim.Properties.OwnerID = ownerID; obj.Prim.Properties.Permissions = server.Permissions.GetDefaultPermissions(); obj.Prim.Properties.SalePrice = 10; } // Set the default scale if (obj.Prim.Scale == Vector3.Zero) obj.Prim.Scale = new Vector3(0.5f, 0.5f, 0.5f); // Set the collision plane if (obj.Prim.CollisionPlane == Vector4.Zero) obj.Prim.CollisionPlane = Vector4.UnitW; // Set default textures if none are set if (obj.Prim.Textures == null) obj.Prim.Textures = new Primitive.TextureEntry(new UUID("89556747-24cb-43ed-920b-47caed15465f")); // Plywood // Add the object to the scene dictionary sceneObjects.Add(obj.Prim.LocalID, obj.Prim.ID, obj); } #endregion Initialize new objects // Reset the prim CRC obj.CRC = 0; #region UpdateFlags to packet type conversion bool canUseCompressed = true; bool canUseImproved = true; if ((updateFlags & UpdateFlags.FullUpdate) == UpdateFlags.FullUpdate || creatorFlags != PrimFlags.None) { canUseCompressed = false; canUseImproved = false; } else { if ((updateFlags & UpdateFlags.Velocity) != 0 || (updateFlags & UpdateFlags.Acceleration) != 0 || (updateFlags & UpdateFlags.CollisionPlane) != 0 || (updateFlags & UpdateFlags.Joint) != 0) { canUseCompressed = false; } if ((updateFlags & UpdateFlags.PrimFlags) != 0 || (updateFlags & UpdateFlags.ParentID) != 0 || (updateFlags & UpdateFlags.Scale) != 0 || (updateFlags & UpdateFlags.PrimData) != 0 || (updateFlags & UpdateFlags.Text) != 0 || (updateFlags & UpdateFlags.NameValue) != 0 || (updateFlags & UpdateFlags.ExtraData) != 0 || (updateFlags & UpdateFlags.TextureAnim) != 0 || (updateFlags & UpdateFlags.Sound) != 0 || (updateFlags & UpdateFlags.Particles) != 0 || (updateFlags & UpdateFlags.Material) != 0 || (updateFlags & UpdateFlags.ClickAction) != 0 || (updateFlags & UpdateFlags.MediaURL) != 0 || (updateFlags & UpdateFlags.Joint) != 0) { canUseImproved = false; } } #endregion UpdateFlags to packet type conversion SendObjectPacket(obj, canUseCompressed, canUseImproved, creatorFlags, updateFlags); }
void SendObjectPacket(SimulationObject obj, bool canUseCompressed, bool canUseImproved, PrimFlags creatorFlags, UpdateFlags updateFlags) { if (!canUseImproved && !canUseCompressed) { #region ObjectUpdate Logger.DebugLog("Sending ObjectUpdate"); if (sceneAgents.ContainsKey(obj.Prim.OwnerID)) { // Send an update out to the creator ObjectUpdatePacket updateToOwner = new ObjectUpdatePacket(); updateToOwner.RegionData.RegionHandle = regionHandle; updateToOwner.RegionData.TimeDilation = (ushort)(timeDilation * (float)UInt16.MaxValue); updateToOwner.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; updateToOwner.ObjectData[0] = SimulationObject.BuildUpdateBlock(obj.Prim, obj.Prim.Flags | creatorFlags | PrimFlags.ObjectYouOwner, obj.CRC); udp.SendPacket(obj.Prim.OwnerID, updateToOwner, PacketCategory.State); } // Send an update out to everyone else ObjectUpdatePacket updateToOthers = new ObjectUpdatePacket(); updateToOthers.RegionData.RegionHandle = regionHandle; updateToOthers.RegionData.TimeDilation = UInt16.MaxValue; updateToOthers.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; updateToOthers.ObjectData[0] = SimulationObject.BuildUpdateBlock(obj.Prim, obj.Prim.Flags, obj.CRC); ForEachAgent( delegate(Agent recipient) { if (recipient.ID != obj.Prim.OwnerID) udp.SendPacket(recipient.ID, updateToOthers, PacketCategory.State); } ); #endregion ObjectUpdate } else if (!canUseImproved) { #region ObjectUpdateCompressed #region Size calculation and field serialization CompressedFlags flags = 0; int size = 84; byte[] textBytes = null; byte[] mediaURLBytes = null; byte[] particleBytes = null; byte[] extraParamBytes = null; byte[] nameValueBytes = null; byte[] textureBytes = null; byte[] textureAnimBytes = null; if ((updateFlags & UpdateFlags.AngularVelocity) != 0) { flags |= CompressedFlags.HasAngularVelocity; size += 12; } if ((updateFlags & UpdateFlags.ParentID) != 0) { flags |= CompressedFlags.HasParent; size += 4; } if ((updateFlags & UpdateFlags.ScratchPad) != 0) { switch (obj.Prim.PrimData.PCode) { case PCode.Grass: case PCode.Tree: case PCode.NewTree: flags |= CompressedFlags.Tree; size += 2; // Size byte plus one byte break; default: flags |= CompressedFlags.ScratchPad; size += 1 + obj.Prim.ScratchPad.Length; // Size byte plus bytes break; } } if ((updateFlags & UpdateFlags.Text) != 0) { flags |= CompressedFlags.HasText; textBytes = Utils.StringToBytes(obj.Prim.Text); size += textBytes.Length; // Null-terminated, no size byte size += 4; // Text color } if ((updateFlags & UpdateFlags.MediaURL) != 0) { flags |= CompressedFlags.MediaURL; mediaURLBytes = Utils.StringToBytes(obj.Prim.MediaURL); size += mediaURLBytes.Length; // Null-terminated, no size byte } if ((updateFlags & UpdateFlags.Particles) != 0) { flags |= CompressedFlags.HasParticles; particleBytes = obj.Prim.ParticleSys.GetBytes(); size += particleBytes.Length; // Should be exactly 86 bytes } // Extra Params extraParamBytes = obj.Prim.GetExtraParamsBytes(); size += extraParamBytes.Length; if ((updateFlags & UpdateFlags.Sound) != 0) { flags |= CompressedFlags.HasSound; size += 25; // SoundID, SoundGain, SoundFlags, SoundRadius } if ((updateFlags & UpdateFlags.NameValue) != 0) { flags |= CompressedFlags.HasNameValues; nameValueBytes = Utils.StringToBytes(NameValue.NameValuesToString(obj.Prim.NameValues)); size += nameValueBytes.Length; // Null-terminated, no size byte } size += 23; // PrimData size += 4; // Texture Length textureBytes = obj.Prim.Textures.GetBytes(); size += textureBytes.Length; // Texture Entry if ((updateFlags & UpdateFlags.TextureAnim) != 0) { flags |= CompressedFlags.TextureAnimation; size += 4; // TextureAnim Length textureAnimBytes = obj.Prim.TextureAnim.GetBytes(); size += textureAnimBytes.Length; // TextureAnim } #endregion Size calculation and field serialization #region Packet serialization int pos = 0; byte[] data = new byte[size]; // UUID obj.Prim.ID.ToBytes(data, 0); pos += 16; // LocalID Utils.UIntToBytes(obj.Prim.LocalID, data, pos); pos += 4; // PCode data[pos++] = (byte)obj.Prim.PrimData.PCode; // State data[pos++] = obj.Prim.PrimData.State; // CRC Utils.UIntToBytes(obj.CRC, data, pos); pos += 4; // Material data[pos++] = (byte)obj.Prim.PrimData.Material; // ClickAction data[pos++] = (byte)obj.Prim.ClickAction; // Scale obj.Prim.Scale.ToBytes(data, pos); pos += 12; // Position obj.Prim.Position.ToBytes(data, pos); pos += 12; // Rotation obj.Prim.Rotation.ToBytes(data, pos); pos += 12; // Compressed Flags Utils.UIntToBytes((uint)flags, data, pos); pos += 4; // OwnerID obj.Prim.OwnerID.ToBytes(data, pos); pos += 16; if ((flags & CompressedFlags.HasAngularVelocity) != 0) { obj.Prim.AngularVelocity.ToBytes(data, pos); pos += 12; } if ((flags & CompressedFlags.HasParent) != 0) { Utils.UIntToBytes(obj.Prim.ParentID, data, pos); pos += 4; } if ((flags & CompressedFlags.ScratchPad) != 0) { data[pos++] = (byte)obj.Prim.ScratchPad.Length; Buffer.BlockCopy(obj.Prim.ScratchPad, 0, data, pos, obj.Prim.ScratchPad.Length); pos += obj.Prim.ScratchPad.Length; } else if ((flags & CompressedFlags.Tree) != 0) { data[pos++] = 1; data[pos++] = (byte)obj.Prim.TreeSpecies; } if ((flags & CompressedFlags.HasText) != 0) { Buffer.BlockCopy(textBytes, 0, data, pos, textBytes.Length); pos += textBytes.Length; obj.Prim.TextColor.ToBytes(data, pos, false); pos += 4; } if ((flags & CompressedFlags.MediaURL) != 0) { Buffer.BlockCopy(mediaURLBytes, 0, data, pos, mediaURLBytes.Length); pos += mediaURLBytes.Length; } if ((flags & CompressedFlags.HasParticles) != 0) { Buffer.BlockCopy(particleBytes, 0, data, pos, particleBytes.Length); pos += particleBytes.Length; } // Extra Params Buffer.BlockCopy(extraParamBytes, 0, data, pos, extraParamBytes.Length); pos += extraParamBytes.Length; if ((flags & CompressedFlags.HasSound) != 0) { obj.Prim.Sound.ToBytes(data, pos); pos += 16; Utils.FloatToBytes(obj.Prim.SoundGain, data, pos); pos += 4; data[pos++] = (byte)obj.Prim.SoundFlags; Utils.FloatToBytes(obj.Prim.SoundRadius, data, pos); pos += 4; } if ((flags & CompressedFlags.HasNameValues) != 0) { Buffer.BlockCopy(nameValueBytes, 0, data, pos, nameValueBytes.Length); pos += nameValueBytes.Length; } // Path PrimData data[pos++] = (byte)obj.Prim.PrimData.PathCurve; Utils.UInt16ToBytes(Primitive.PackBeginCut(obj.Prim.PrimData.PathBegin), data, pos); pos += 2; Utils.UInt16ToBytes(Primitive.PackEndCut(obj.Prim.PrimData.PathEnd), data, pos); pos += 2; data[pos++] = Primitive.PackPathScale(obj.Prim.PrimData.PathScaleX); data[pos++] = Primitive.PackPathScale(obj.Prim.PrimData.PathScaleY); data[pos++] = (byte)Primitive.PackPathShear(obj.Prim.PrimData.PathShearX); data[pos++] = (byte)Primitive.PackPathShear(obj.Prim.PrimData.PathShearY); data[pos++] = (byte)Primitive.PackPathTwist(obj.Prim.PrimData.PathTwist); data[pos++] = (byte)Primitive.PackPathTwist(obj.Prim.PrimData.PathTwistBegin); data[pos++] = (byte)Primitive.PackPathTwist(obj.Prim.PrimData.PathRadiusOffset); data[pos++] = (byte)Primitive.PackPathTaper(obj.Prim.PrimData.PathTaperX); data[pos++] = (byte)Primitive.PackPathTaper(obj.Prim.PrimData.PathTaperY); data[pos++] = Primitive.PackPathRevolutions(obj.Prim.PrimData.PathRevolutions); data[pos++] = (byte)Primitive.PackPathTwist(obj.Prim.PrimData.PathSkew); // Profile PrimData data[pos++] = obj.Prim.PrimData.profileCurve; Utils.UInt16ToBytes(Primitive.PackBeginCut(obj.Prim.PrimData.ProfileBegin), data, pos); pos += 2; Utils.UInt16ToBytes(Primitive.PackEndCut(obj.Prim.PrimData.ProfileEnd), data, pos); pos += 2; Utils.UInt16ToBytes(Primitive.PackProfileHollow(obj.Prim.PrimData.ProfileHollow), data, pos); pos += 2; // Texture Length Utils.UIntToBytes((uint)textureBytes.Length, data, pos); pos += 4; // Texture Entry Buffer.BlockCopy(textureBytes, 0, data, pos, textureBytes.Length); pos += textureBytes.Length; if ((flags & CompressedFlags.TextureAnimation) != 0) { Utils.UIntToBytes((uint)textureAnimBytes.Length, data, pos); pos += 4; Buffer.BlockCopy(textureAnimBytes, 0, data, pos, textureAnimBytes.Length); pos += textureAnimBytes.Length; } #endregion Packet serialization #region Packet sending //Logger.DebugLog("Sending ObjectUpdateCompressed with " + flags.ToString()); if (sceneAgents.ContainsKey(obj.Prim.OwnerID)) { // Send an update out to the creator ObjectUpdateCompressedPacket updateToOwner = new ObjectUpdateCompressedPacket(); updateToOwner.RegionData.RegionHandle = regionHandle; updateToOwner.RegionData.TimeDilation = (ushort)(timeDilation * (float)UInt16.MaxValue); updateToOwner.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[1]; updateToOwner.ObjectData[0] = new ObjectUpdateCompressedPacket.ObjectDataBlock(); updateToOwner.ObjectData[0].UpdateFlags = (uint)(obj.Prim.Flags | creatorFlags | PrimFlags.ObjectYouOwner); updateToOwner.ObjectData[0].Data = data; udp.SendPacket(obj.Prim.OwnerID, updateToOwner, PacketCategory.State); } // Send an update out to everyone else ObjectUpdateCompressedPacket updateToOthers = new ObjectUpdateCompressedPacket(); updateToOthers.RegionData.RegionHandle = regionHandle; updateToOthers.RegionData.TimeDilation = UInt16.MaxValue; updateToOthers.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[1]; updateToOthers.ObjectData[0] = new ObjectUpdateCompressedPacket.ObjectDataBlock(); updateToOthers.ObjectData[0].UpdateFlags = (uint)obj.Prim.Flags; updateToOthers.ObjectData[0].Data = data; ForEachAgent( delegate(Agent recipient) { if (recipient.ID != obj.Prim.OwnerID) udp.SendPacket(recipient.ID, updateToOthers, PacketCategory.State); } ); #endregion Packet sending #endregion ObjectUpdateCompressed } else { #region ImprovedTerseObjectUpdate //Logger.DebugLog("Sending ImprovedTerseObjectUpdate"); int pos = 0; byte[] data = new byte[(obj.Prim is Avatar ? 60 : 44)]; // LocalID Utils.UIntToBytes(obj.Prim.LocalID, data, pos); pos += 4; // Avatar/CollisionPlane data[pos++] = obj.Prim.PrimData.State; if (obj.Prim is Avatar) { data[pos++] = 1; obj.Prim.CollisionPlane.ToBytes(data, pos); pos += 16; } else { ++pos; } // Position obj.Prim.Position.ToBytes(data, pos); pos += 12; // Velocity Utils.UInt16ToBytes(Utils.FloatToUInt16(obj.Prim.Velocity.X, -128.0f, 128.0f), data, pos); pos += 2; Utils.UInt16ToBytes(Utils.FloatToUInt16(obj.Prim.Velocity.Y, -128.0f, 128.0f), data, pos); pos += 2; Utils.UInt16ToBytes(Utils.FloatToUInt16(obj.Prim.Velocity.Z, -128.0f, 128.0f), data, pos); pos += 2; // Acceleration Utils.UInt16ToBytes(Utils.FloatToUInt16(obj.Prim.Acceleration.X, -64.0f, 64.0f), data, pos); pos += 2; Utils.UInt16ToBytes(Utils.FloatToUInt16(obj.Prim.Acceleration.Y, -64.0f, 64.0f), data, pos); pos += 2; Utils.UInt16ToBytes(Utils.FloatToUInt16(obj.Prim.Acceleration.Z, -64.0f, 64.0f), data, pos); pos += 2; // Rotation Utils.UInt16ToBytes(Utils.FloatToUInt16(obj.Prim.Rotation.X, -1.0f, 1.0f), data, pos); pos += 2; Utils.UInt16ToBytes(Utils.FloatToUInt16(obj.Prim.Rotation.Y, -1.0f, 1.0f), data, pos); pos += 2; Utils.UInt16ToBytes(Utils.FloatToUInt16(obj.Prim.Rotation.Z, -1.0f, 1.0f), data, pos); pos += 2; Utils.UInt16ToBytes(Utils.FloatToUInt16(obj.Prim.Rotation.W, -1.0f, 1.0f), data, pos); pos += 2; // Angular Velocity Utils.UInt16ToBytes(Utils.FloatToUInt16(obj.Prim.AngularVelocity.X, -64.0f, 64.0f), data, pos); pos += 2; Utils.UInt16ToBytes(Utils.FloatToUInt16(obj.Prim.AngularVelocity.Y, -64.0f, 64.0f), data, pos); pos += 2; Utils.UInt16ToBytes(Utils.FloatToUInt16(obj.Prim.AngularVelocity.Z, -64.0f, 64.0f), data, pos); pos += 2; ImprovedTerseObjectUpdatePacket update = new ImprovedTerseObjectUpdatePacket(); update.RegionData.RegionHandle = RegionHandle; update.RegionData.TimeDilation = (ushort)(timeDilation * (float)UInt16.MaxValue); update.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1]; update.ObjectData[0] = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock(); update.ObjectData[0].Data = data; if ((updateFlags & UpdateFlags.Textures) != 0) { byte[] textureBytes = obj.Prim.Textures.GetBytes(); byte[] textureEntry = new byte[textureBytes.Length + 4]; // Texture Length Utils.IntToBytes(textureBytes.Length, textureEntry, 0); // Texture Buffer.BlockCopy(textureBytes, 0, textureEntry, 4, textureBytes.Length); update.ObjectData[0].TextureEntry = textureEntry; } else { update.ObjectData[0].TextureEntry = Utils.EmptyBytes; } udp.BroadcastPacket(update, PacketCategory.State); #endregion ImprovedTerseObjectUpdate } }
public Agent(SimulationObject avatar, AgentInfo info) { Avatar = avatar; Info = info; }
public bool TryGetObject(uint localID, out SimulationObject obj) { return sceneObjects.TryGetValue(localID, out obj); }
public SimulationObjectInventory(SimulationObject hostObject) { this.hostObject = hostObject; }
static void SOPToXml(XmlTextWriter writer, SimulationObject prim, SimulationObject parent) { writer.WriteStartElement("SceneObjectPart"); writer.WriteAttributeString("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); writer.WriteAttributeString("xmlns:xsd", "http://www.w3.org/2001/XMLSchema"); WriteUUID(writer, "CreatorID", prim.Prim.Properties.CreatorID); WriteUUID(writer, "FolderID", prim.Prim.Properties.FolderID); writer.WriteElementString("InventorySerial", prim.Prim.Properties.InventorySerial.ToString()); writer.WriteStartElement("TaskInventory"); writer.WriteEndElement(); writer.WriteElementString("ObjectFlags", ((int)prim.Prim.Flags).ToString()); WriteUUID(writer, "UUID", prim.Prim.ID); writer.WriteElementString("LocalId", prim.Prim.LocalID.ToString()); writer.WriteElementString("Name", prim.Prim.Properties.Name); writer.WriteElementString("Material", ((int)prim.Prim.PrimData.Material).ToString()); writer.WriteElementString("RegionHandle", prim.Prim.RegionHandle.ToString()); writer.WriteElementString("ScriptAccessPin", "0"); Vector3 groupPosition; if (parent == null) groupPosition = prim.Prim.Position; else groupPosition = parent.Prim.Position; WriteVector(writer, "GroupPosition", groupPosition); if (prim.Prim.ParentID == 0) WriteVector(writer, "OffsetPosition", Vector3.Zero); else WriteVector(writer, "OffsetPosition", prim.Prim.Position); WriteQuaternion(writer, "RotationOffset", prim.Prim.Rotation); WriteVector(writer, "Velocity", Vector3.Zero); WriteVector(writer, "RotationalVelocity", Vector3.Zero); WriteVector(writer, "AngularVelocity", prim.Prim.AngularVelocity); WriteVector(writer, "Acceleration", Vector3.Zero); writer.WriteElementString("Description", prim.Prim.Properties.Description); writer.WriteStartElement("Color"); writer.WriteElementString("R", prim.Prim.TextColor.R.ToString()); writer.WriteElementString("G", prim.Prim.TextColor.G.ToString()); writer.WriteElementString("B", prim.Prim.TextColor.B.ToString()); writer.WriteElementString("A", prim.Prim.TextColor.G.ToString()); writer.WriteEndElement(); writer.WriteElementString("Text", prim.Prim.Text); writer.WriteElementString("SitName", prim.Prim.Properties.SitName); writer.WriteElementString("TouchName", prim.Prim.Properties.TouchName); writer.WriteElementString("LinkNum", prim.LinkNumber.ToString()); writer.WriteElementString("ClickAction", ((int)prim.Prim.ClickAction).ToString()); writer.WriteStartElement("Shape"); writer.WriteElementString("PathBegin", Primitive.PackBeginCut(prim.Prim.PrimData.PathBegin).ToString()); writer.WriteElementString("PathCurve", ((byte)prim.Prim.PrimData.PathCurve).ToString()); writer.WriteElementString("PathEnd", Primitive.PackEndCut(prim.Prim.PrimData.PathEnd).ToString()); writer.WriteElementString("PathRadiusOffset", Primitive.PackPathTwist(prim.Prim.PrimData.PathRadiusOffset).ToString()); writer.WriteElementString("PathRevolutions", Primitive.PackPathRevolutions(prim.Prim.PrimData.PathRevolutions).ToString()); writer.WriteElementString("PathScaleX", Primitive.PackPathScale(prim.Prim.PrimData.PathScaleX).ToString()); writer.WriteElementString("PathScaleY", Primitive.PackPathScale(prim.Prim.PrimData.PathScaleY).ToString()); writer.WriteElementString("PathShearX", ((byte)Primitive.PackPathShear(prim.Prim.PrimData.PathShearX)).ToString()); writer.WriteElementString("PathShearY", ((byte)Primitive.PackPathShear(prim.Prim.PrimData.PathShearY)).ToString()); writer.WriteElementString("PathSkew", Primitive.PackPathTwist(prim.Prim.PrimData.PathSkew).ToString()); writer.WriteElementString("PathTaperX", Primitive.PackPathTaper(prim.Prim.PrimData.PathTaperX).ToString()); writer.WriteElementString("PathTaperY", Primitive.PackPathTaper(prim.Prim.PrimData.PathTaperY).ToString()); writer.WriteElementString("PathTwist", Primitive.PackPathTwist(prim.Prim.PrimData.PathTwist).ToString()); writer.WriteElementString("PathTwistBegin", Primitive.PackPathTwist(prim.Prim.PrimData.PathTwistBegin).ToString()); writer.WriteElementString("PCode", ((byte)prim.Prim.PrimData.PCode).ToString()); writer.WriteElementString("ProfileBegin", Primitive.PackBeginCut(prim.Prim.PrimData.ProfileBegin).ToString()); writer.WriteElementString("ProfileEnd", Primitive.PackEndCut(prim.Prim.PrimData.ProfileEnd).ToString()); writer.WriteElementString("ProfileHollow", Primitive.PackProfileHollow(prim.Prim.PrimData.ProfileHollow).ToString()); WriteVector(writer, "Scale", prim.Prim.Scale); writer.WriteElementString("State", prim.Prim.PrimData.State.ToString()); ProfileShape shape = (ProfileShape)prim.Prim.PrimData.ProfileCurve; writer.WriteElementString("ProfileShape", shape.ToString()); writer.WriteElementString("HollowShape", prim.Prim.PrimData.ProfileHole.ToString()); writer.WriteElementString("ProfileCurve", prim.Prim.PrimData.profileCurve.ToString()); writer.WriteStartElement("TextureEntry"); byte[] te; if (prim.Prim.Textures != null) te = prim.Prim.Textures.GetBytes(); else te = Utils.EmptyBytes; writer.WriteBase64(te, 0, te.Length); writer.WriteEndElement(); // FIXME: ExtraParams writer.WriteStartElement("ExtraParams"); writer.WriteEndElement(); writer.WriteEndElement(); WriteVector(writer, "Scale", prim.Prim.Scale); writer.WriteElementString("UpdateFlag", "0"); WriteVector(writer, "SitTargetOrientation", Vector3.UnitZ); // TODO: Is this really a vector and not a quaternion? WriteVector(writer, "SitTargetPosition", prim.SitPosition); WriteVector(writer, "SitTargetPositionLL", prim.SitPosition); WriteQuaternion(writer, "SitTargetOrientationLL", prim.SitRotation); writer.WriteElementString("ParentID", prim.Prim.ParentID.ToString()); writer.WriteElementString("CreationDate", ((int)Utils.DateTimeToUnixTime(prim.Prim.Properties.CreationDate)).ToString()); writer.WriteElementString("Category", ((int)prim.Prim.Properties.Category).ToString()); writer.WriteElementString("SalePrice", prim.Prim.Properties.SalePrice.ToString()); writer.WriteElementString("ObjectSaleType", ((int)prim.Prim.Properties.SaleType).ToString()); writer.WriteElementString("OwnershipCost", prim.Prim.Properties.OwnershipCost.ToString()); WriteUUID(writer, "GroupID", prim.Prim.GroupID); WriteUUID(writer, "OwnerID", prim.Prim.OwnerID); WriteUUID(writer, "LastOwnerID", prim.Prim.Properties.LastOwnerID); writer.WriteElementString("BaseMask", ((uint)PermissionMask.All).ToString()); writer.WriteElementString("OwnerMask", ((uint)PermissionMask.All).ToString()); writer.WriteElementString("GroupMask", ((uint)PermissionMask.All).ToString()); writer.WriteElementString("EveryoneMask", ((uint)PermissionMask.All).ToString()); writer.WriteElementString("NextOwnerMask", ((uint)PermissionMask.All).ToString()); writer.WriteElementString("Flags", "None"); WriteUUID(writer, "SitTargetAvatar", UUID.Zero); writer.WriteEndElement(); }