Beispiel #1
0
 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
 }
Beispiel #2
0
 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
 }
Beispiel #3
0
        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;
            }
        }
Beispiel #4
0
        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);
            }
        }
Beispiel #5
0
 public bool TryGetObject(UUID id, out SimulationObject obj)
 {
     return sceneObjects.TryGetValue(id, out obj);
 }
Beispiel #6
0
 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
 }
Beispiel #7
0
        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);
            }
        }
Beispiel #8
0
        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);
        }
Beispiel #9
0
        public void ObjectApplyRotationalImpulse(object sender, SimulationObject obj, Vector3 impulse)
        {
            if (OnObjectApplyRotationalImpulse != null)
            {
                OnObjectApplyRotationalImpulse(sender, obj, impulse);
            }

            // FIXME:
        }
Beispiel #10
0
        public void ObjectSetTorque(object sender, SimulationObject obj, Vector3 torque)
        {
            if (OnObjectSetTorque != null)
            {
                OnObjectSetTorque(sender, obj, torque);
            }

            obj.Torque = torque;
        }
Beispiel #11
0
        public void ObjectSetRotationAxis(object sender, SimulationObject obj, Vector3 rotationAxis)
        {
            if (OnObjectSetRotationAxis != null)
            {
                OnObjectSetRotationAxis(sender, obj, rotationAxis);
            }

            // Update the object
            obj.RotationAxis = rotationAxis;
        }
Beispiel #12
0
        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);
        }
Beispiel #13
0
        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
            }
        }
Beispiel #14
0
 public Agent(SimulationObject avatar, AgentInfo info)
 {
     Avatar = avatar;
     Info = info;
 }
Beispiel #15
0
 public bool TryGetObject(uint localID, out SimulationObject obj)
 {
     return sceneObjects.TryGetValue(localID, out obj);
 }
 public SimulationObjectInventory(SimulationObject hostObject)
 {
     this.hostObject = hostObject;
 }
Beispiel #17
0
        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();
        }