예제 #1
0
            /// <summary>
            /// Send new AgentUpdate packet to update our current camera 
            /// position and rotation
            /// </summary>
            /// <param name="reliable">Whether to require server acknowledgement
            /// of this packet</param>
            /// <param name="simulator">Simulator to send the update to</param>
            public void SendUpdate(bool reliable, Simulator simulator)
            {
                Vector3f origin = Camera.Position;
                Vector3f xAxis = Camera.LeftAxis;
                Vector3f yAxis = Camera.AtAxis;
                Vector3f zAxis = Camera.UpAxis;

                // Attempted to sort these in a rough order of how often they might change
                if (agentControls == 0 &&
                    yAxis == LastCameraYAxis &&
                    origin == LastCameraCenter &&
                    State == lastState &&
                    HeadRotation == LastHeadRotation &&
                    BodyRotation == LastBodyRotation &&
                    xAxis == LastCameraXAxis &&
                    Camera.Far == LastFar &&
                    zAxis == LastCameraZAxis)
                {
                    ++duplicateCount;
                }
                else
                {
                    duplicateCount = 0;
                }

                if (Client.Settings.DISABLE_AGENT_UPDATE_DUPLICATE_CHECK || duplicateCount < 10)
                {
                    // Store the current state to do duplicate checking
                    LastHeadRotation = HeadRotation;
                    LastBodyRotation = BodyRotation;
                    LastCameraYAxis = yAxis;
                    LastCameraCenter = origin;
                    LastCameraXAxis = xAxis;
                    LastCameraZAxis = zAxis;
                    LastFar = Camera.Far;
                    lastState = State;

                    // Build the AgentUpdate packet and send it
                    AgentUpdatePacket update = new AgentUpdatePacket();
                    update.Header.Reliable = reliable;

                    update.AgentData.AgentID = Client.Self.AgentID;
                    update.AgentData.SessionID = Client.Self.SessionID;
                    update.AgentData.HeadRotation = HeadRotation;
                    update.AgentData.BodyRotation = BodyRotation;
                    update.AgentData.CameraAtAxis = yAxis;
                    update.AgentData.CameraCenter = origin;
                    update.AgentData.CameraLeftAxis = xAxis;
                    update.AgentData.CameraUpAxis = zAxis;
                    update.AgentData.Far = Camera.Far;
                    update.AgentData.State = (byte)State;
                    update.AgentData.ControlFlags = agentControls;
                    update.AgentData.Flags = (byte)Flags;

                    Client.Network.SendPacket(update, simulator);

                    if (autoResetControls) {
                        ResetControlFlags();
                    }
                }
            }
예제 #2
0
            /// <summary>
            /// Builds an AgentUpdate packet entirely from parameters. This
            /// will not touch the state of Self.Movement or
            /// Self.Movement.Camera in any way
            /// </summary>
            /// <param name="controlFlags"></param>
            /// <param name="position"></param>
            /// <param name="forwardAxis"></param>
            /// <param name="leftAxis"></param>
            /// <param name="upAxis"></param>
            /// <param name="bodyRotation"></param>
            /// <param name="headRotation"></param>
            /// <param name="farClip"></param>
            /// <param name="reliable"></param>
            /// <param name="flags"></param>
            /// <param name="state"></param>
            public void SendManualUpdate(AgentManager.ControlFlags controlFlags, Vector3f position, Vector3f forwardAxis,
                Vector3f leftAxis, Vector3f upAxis, Quaternionf bodyRotation, Quaternionf headRotation, float farClip,
                AgentFlags flags, AgentState state, bool reliable)
            {
                AgentUpdatePacket update = new AgentUpdatePacket();

                update.AgentData.AgentID = Client.Self.AgentID;
                update.AgentData.SessionID = Client.Self.SessionID;
                update.AgentData.BodyRotation = bodyRotation;
                update.AgentData.HeadRotation = headRotation;
                update.AgentData.CameraCenter = position;
                update.AgentData.CameraAtAxis = forwardAxis;
                update.AgentData.CameraLeftAxis = leftAxis;
                update.AgentData.CameraUpAxis = upAxis;
                update.AgentData.Far = farClip;
                update.AgentData.ControlFlags = (uint)controlFlags;
                update.AgentData.Flags = (byte)flags;
                update.AgentData.State = (byte)state;

                update.Header.Reliable = reliable;

                Client.Network.SendPacket(update);
            }
예제 #3
0
 /// <summary>
 /// Rez an object from inventory
 /// </summary>
 /// <param name="simulator">Simulator to place object in</param>
 /// <param name="rotation">Rotation of the object when rezzed</param>
 /// <param name="position">Vector of where to place object</param>
 /// <param name="item">InventoryObject object containing item details</param>
 /// <param name="groupOwner">Guid of group to own the object</param>
 public Guid RequestRezFromInventory(Simulator simulator, Quaternionf rotation, Vector3f position,
     InventoryObject item, Guid groupOwner)
 {
     return RequestRezFromInventory(simulator, rotation, position, item, groupOwner, Guid.NewGuid(), false);
 }
예제 #4
0
        /// <summary>
        /// Used for new prims, or significant changes to existing prims
        /// </summary>
        /// <param name="packet"></param>
        /// <param name="simulator"></param>
        protected void UpdateHandler(Packet packet, Simulator simulator)
        {
            ObjectUpdatePacket update = (ObjectUpdatePacket)packet;
			UpdateDilation(simulator, update.RegionData.TimeDilation);

            for (int b = 0; b < update.ObjectData.Length; b++)
            {
                ObjectUpdatePacket.ObjectDataBlock block = update.ObjectData[b];

                Vector4f collisionPlane = Vector4f.Zero;
                Vector3f position = Vector3f.Zero;
                Vector3f velocity = Vector3f.Zero;
                Vector3f acceleration = Vector3f.Zero;
                Quaternionf rotation = Quaternionf.Identity;
                Vector3f angularVelocity = Vector3f.Zero;
                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:
                            if (OnNewFoliage == null) continue;
                            break;
                        case PCode.Prim:
                            if (OnNewPrim == null) continue;
                            break;
                        case PCode.Avatar:
                            // Make an exception for updates about our own agent
                            if (block.FullID != Client.Self.AgentID && OnNewAvatar == 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
                        collisionPlane.FromBytes(block.ObjectData, pos);
                        pos += 16;

                        goto case 60;
                    case 60:
                        // Position
                        position.FromBytes(block.ObjectData, pos);
                        pos += 12;
                        // Velocity
                        velocity.FromBytes(block.ObjectData, pos);
                        pos += 12;
                        // Acceleration
                        acceleration.FromBytes(block.ObjectData, pos);
                        pos += 12;
                        // Rotation (theta)
                        rotation.FromBytes(block.ObjectData, pos, true);
                        pos += 12;
                        // Angular velocity (omega)
                        angularVelocity.FromBytes(block.ObjectData, pos);
                        pos += 12;

                        break;
                    case 48:
                        // Collision normal for avatar
                        collisionPlane.FromBytes(block.ObjectData, pos);
                        pos += 16;

                        goto case 32;
                    case 32:
                        // The data is an array of unsigned shorts

                        // Position
                        position = new Vector3f(
                            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
                        velocity = new Vector3f(
                            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
                        acceleration = new Vector3f(
                            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)
                        rotation = new Quaternionf(
                            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)
                        angularVelocity = new Vector3f(
                            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
                        position = new Vector3f(
                            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
                        velocity = new Vector3f(
                            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
                        acceleration = new Vector3f(
                            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
                        rotation = new Quaternionf(
                            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
                        angularVelocity = new Vector3f(
                            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:
                        Primitive prim = GetPrimitive(simulator, block.ID, block.FullID);

                        #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 = 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 = new Primitive.TextureEntry(block.TextureEntry, 0,
                            block.TextureEntry.Length);

                        prim.TextureAnim = new Primitive.TextureAnimation(block.TextureAnim, 0);
                        prim.ParticleSys = new Primitive.ParticleSystem(block.PSBlock, 0);
                        prim.SetExtraParamsFromBytes(block.ExtraParams, 0);

                        // PCode-specific data
                        prim.GenericData = block.Data;

                        // Packed parameters
                        prim.CollisionPlane = collisionPlane;
                        prim.Position = position;
                        prim.Velocity = velocity;
                        prim.Acceleration = acceleration;
                        prim.Rotation = rotation;
                        prim.AngularVelocity = angularVelocity;
                        #endregion

                        if (attachment)
                            FireOnNewAttachment(simulator, prim, update.RegionData.RegionHandle, 
                                update.RegionData.TimeDilation);
                        else if (pcode == PCode.Prim)
                            FireOnNewPrim(simulator, prim, update.RegionData.RegionHandle, 
                                update.RegionData.TimeDilation);
                        else
                            FireOnNewFoliage(simulator, prim, update.RegionData.RegionHandle, 
                                update.RegionData.TimeDilation);

                        break;
                    #endregion Prim and Foliage
                    #region Avatar
                    case PCode.Avatar:
                        // Update some internals if this is our avatar
                        if (block.FullID == Client.Self.AgentID)
                        {
                            #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 = collisionPlane;
                            Client.Self.relativePosition = position;
                            Client.Self.velocity = velocity;
                            Client.Self.acceleration = acceleration;
                            Client.Self.relativeRotation = rotation;
                            Client.Self.angularVelocity = angularVelocity;

                            #endregion
                        }

                        #region Create an Avatar from the decoded data

                        Avatar avatar = GetAvatar(simulator, block.ID, block.FullID);
                        uint oldSeatID = avatar.ParentID;

                        avatar.ID = block.FullID;
                        avatar.LocalID = block.ID;
                        avatar.CollisionPlane = collisionPlane;
                        avatar.Position = position;
                        avatar.Velocity = velocity;
                        avatar.Acceleration = acceleration;
                        avatar.Rotation = rotation;
                        avatar.AngularVelocity = angularVelocity;
                        avatar.NameValues = nameValues;
                        avatar.PrimData = data;
                        avatar.GenericData = block.Data;
                        avatar.ParentID = block.ParentID;

                        SetAvatarSittingOn(simulator, avatar, block.ParentID, oldSeatID);

                        // Textures
                        avatar.Textures = new Primitive.TextureEntry(block.TextureEntry, 0, 
                            block.TextureEntry.Length);

                        #endregion Create an Avatar from the decoded data

                        FireOnNewAvatar(simulator, avatar, update.RegionData.RegionHandle, 
                            update.RegionData.TimeDilation);

                        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;
                }
            }
        }
예제 #5
0
 public void Rotate(float angle, Vector3f rotationAxis)
 {
     Quaternionf q = new Quaternionf();
     q.FromAxisAngle(rotationAxis, angle);
     Rotate(q);
 }
예제 #6
0
        public void Yaw(float angle)
        {
            Quaternionf q = new Quaternionf();
            q.FromAxisAngle(zAxis, angle);
            Matrix4f m = new Matrix4f();
            m.FromQuaternion(q);
            Rotate(m);

            if (!xAxis.IsFinite() || !yAxis.IsFinite())
                throw new Exception("Non-finite in CoordinateFrame.Yaw()");
        }
예제 #7
0
 public float Dot(Quaternionf quaternion)
 {
     return
         (Vector.X * quaternion.Vector.X) +
         (Vector.Y * quaternion.Vector.Y) +
         (Vector.Z * quaternion.Vector.Z) +
         (Vector.W * quaternion.Vector.W);
 }
예제 #8
0
        public void FromQuaternion(Quaternionf quaternion)
        {
            Matrix4f m1 = new Matrix4f(
                quaternion.W, quaternion.Z, -quaternion.Y, quaternion.X,
                -quaternion.Z, quaternion.W, quaternion.X, quaternion.Y,
                quaternion.Y, -quaternion.X, quaternion.W, quaternion.Z,
                -quaternion.X, -quaternion.Y, -quaternion.Z, quaternion.W);

            Matrix4f m2 = new Matrix4f(
                quaternion.W, quaternion.Z, -quaternion.Y, -quaternion.X,
                -quaternion.Z, quaternion.W, quaternion.X, -quaternion.Y,
                quaternion.Y, -quaternion.X, quaternion.W, -quaternion.Z,
                quaternion.X, quaternion.Y, quaternion.Z, quaternion.W);

            this = m1 * m2;
        }
예제 #9
0
        /// <summary>
        /// Change the rotation of an object
        /// </summary>
        /// <param name="simulator">A reference to the <seealso cref="OpenMetaverse.Simulator"/> object where the object resides</param>
        /// <param name="localID">The objects ID which is local to the simulator the object is in</param>
        /// <param name="rotation">The new rotation of the object</param>
        public void SetRotation(Simulator simulator, uint localID, Quaternionf rotation)
        {
            ObjectRotationPacket objRotPacket = new ObjectRotationPacket();
            objRotPacket.AgentData.AgentID = Client.Self.AgentID;
            objRotPacket.AgentData.SessionID = Client.Self.SessionID;

            objRotPacket.ObjectData = new ObjectRotationPacket.ObjectDataBlock[1];

            objRotPacket.ObjectData[0] = new ObjectRotationPacket.ObjectDataBlock();
            objRotPacket.ObjectData[0].ObjectLocalID = localID;
            objRotPacket.ObjectData[0].Rotation = rotation;
            Client.Network.SendPacket(objRotPacket, simulator);
        }
예제 #10
0
        /// <summary>
        /// Attach an object to this avatar
        /// </summary>
        /// <param name="simulator">A reference to the <seealso cref="OpenMetaverse.Simulator"/> object where the object resides</param>
        /// <param name="localID">The objects ID which is local to the simulator the object is in</param>
        /// <param name="attachPoint">The point on the avatar the object will be attached</param>
        /// <param name="rotation">The rotation of the attached object</param>
        public void AttachObject(Simulator simulator, uint localID, AttachmentPoint attachPoint, Quaternionf rotation)
        {
            ObjectAttachPacket attach = new ObjectAttachPacket();
            attach.AgentData.AgentID = Client.Self.AgentID;
            attach.AgentData.SessionID = Client.Self.SessionID;
            attach.AgentData.AttachmentPoint = (byte)attachPoint;

            attach.ObjectData = new ObjectAttachPacket.ObjectDataBlock[1];
            attach.ObjectData[0] = new ObjectAttachPacket.ObjectDataBlock();
            attach.ObjectData[0].ObjectLocalID = localID;
            attach.ObjectData[0].Rotation = rotation;

            Client.Network.SendPacket(attach, simulator);
        }
예제 #11
0
        /// <summary>
        /// Rez grass and ground cover
        /// </summary>
        /// <param name="simulator">A reference to the <seealso cref="OpenMetaverse.Simulator"/> object where the object resides</param>
        /// <param name="scale">The size of the grass</param>
        /// <param name="rotation">The rotation of the grass</param>
        /// <param name="position">The position of the grass</param>
        /// <param name="grassType">The type of grass from the <seealso cref="Grass"/> enum</param>
        /// <param name="groupOwner">The <seealso cref="Guid"/> of the group to set the tree to, 
        /// or Guid.Empty if no group is to be set</param>
        public void AddGrass(Simulator simulator, Vector3f scale, Quaternionf rotation, Vector3f position,
            Grass grassType, Guid groupOwner)
        {
            ObjectAddPacket add = new ObjectAddPacket();

            add.AgentData.AgentID = Client.Self.AgentID;
            add.AgentData.SessionID = Client.Self.SessionID;
            add.AgentData.GroupID = groupOwner;
            add.ObjectData.BypassRaycast = 1;
            add.ObjectData.Material = 3;
            add.ObjectData.PathCurve = 16;
            add.ObjectData.PCode = (byte)PCode.Grass;
            add.ObjectData.RayEnd = position;
            add.ObjectData.RayStart = position;
            add.ObjectData.RayTargetID = Guid.Empty;
            add.ObjectData.Rotation = rotation;
            add.ObjectData.Scale = scale;
            add.ObjectData.State = (byte)grassType;

            Client.Network.SendPacket(add, simulator);
        }
예제 #12
0
        /// <summary>
        /// Create, or "rez" a new prim object in a simulator
        /// </summary>
        /// <param name="simulator">A reference to the <seealso cref="OpenMetaverse.Simulator"/> object to place the object in</param>
        /// <param name="prim">Data describing the prim object to rez</param>
        /// <param name="groupID">Group ID that this prim will be set to, or Guid.Empty if you
        /// do not want the object to be associated with a specific group</param>
        /// <param name="position">An approximation of the position at which to rez the prim</param>
        /// <param name="scale">Scale vector to size this prim</param>
        /// <param name="rotation">Rotation quaternion to rotate this prim</param>
        /// <remarks>Due to the way client prim rezzing is done on the server,
        /// the requested position for an object is only close to where the prim
        /// actually ends up. If you desire exact placement you'll need to 
        /// follow up by moving the object after it has been created. This
        /// function will not set textures, light and flexible data, or other 
        /// extended primitive properties</remarks>
        public void AddPrim(Simulator simulator, Primitive.ConstructionData prim, Guid groupID, Vector3f position, 
            Vector3f scale, Quaternionf rotation)
        {
            ObjectAddPacket packet = new ObjectAddPacket();

            packet.AgentData.AgentID = Client.Self.AgentID;
            packet.AgentData.SessionID = Client.Self.SessionID;
            packet.AgentData.GroupID = groupID;

            packet.ObjectData.State = prim.State;
            packet.ObjectData.AddFlags = (uint)PrimFlags.CreateSelected;
            packet.ObjectData.PCode = (byte)PCode.Prim;

            packet.ObjectData.Material = (byte)prim.Material;
            packet.ObjectData.Scale = scale;
            packet.ObjectData.Rotation = rotation;

            packet.ObjectData.PathCurve = (byte)prim.PathCurve;
            packet.ObjectData.PathBegin = Primitive.PackBeginCut(prim.PathBegin);
            packet.ObjectData.PathEnd = Primitive.PackEndCut(prim.PathEnd);
            packet.ObjectData.PathRadiusOffset = Primitive.PackPathTwist(prim.PathRadiusOffset);
            packet.ObjectData.PathRevolutions = Primitive.PackPathRevolutions(prim.PathRevolutions);
            packet.ObjectData.PathScaleX = Primitive.PackPathScale(prim.PathScaleX);
            packet.ObjectData.PathScaleY = Primitive.PackPathScale(prim.PathScaleY);
            packet.ObjectData.PathShearX = (byte)Primitive.PackPathShear(prim.PathShearX);
            packet.ObjectData.PathShearY = (byte)Primitive.PackPathShear(prim.PathShearY);
            packet.ObjectData.PathSkew = Primitive.PackPathTwist(prim.PathSkew);
            packet.ObjectData.PathTaperX = Primitive.PackPathTaper(prim.PathTaperX);
            packet.ObjectData.PathTaperY = Primitive.PackPathTaper(prim.PathTaperY);
            packet.ObjectData.PathTwist = Primitive.PackPathTwist(prim.PathTwist);
            packet.ObjectData.PathTwistBegin = Primitive.PackPathTwist(prim.PathTwistBegin);

            packet.ObjectData.ProfileCurve = prim.profileCurve;
            packet.ObjectData.ProfileBegin = Primitive.PackBeginCut(prim.ProfileBegin);
            packet.ObjectData.ProfileEnd = Primitive.PackEndCut(prim.ProfileEnd);
            packet.ObjectData.ProfileHollow = Primitive.PackProfileHollow(prim.ProfileHollow);

            packet.ObjectData.RayStart = position;
            packet.ObjectData.RayEnd = position;
            packet.ObjectData.RayEndIsIntersection = 0;
            packet.ObjectData.RayTargetID = Guid.Empty;
            packet.ObjectData.BypassRaycast = 1;

            Client.Network.SendPacket(packet, simulator);
        }
예제 #13
0
        protected void InterpolationTimer_Elapsed(object obj)
        {
            if (Client.Network.Connected)
            {
                int interval = Environment.TickCount - Client.Self.lastInterpolation;
                float seconds = (float)interval / 1000f;

                // Iterate through all of the simulators
                lock (Client.Network.Simulators)
                {
                    for (int i = 0; i < Client.Network.Simulators.Count; i++)
                    {
                        float adjSeconds = seconds * Client.Network.Simulators[i].Stats.Dilation;

                        // Iterate through all of this sims avatars
                        Client.Network.Simulators[i].ObjectsAvatars.ForEach(
                            delegate(Avatar avatar)
                            {
                                #region Linear Motion
                                // Only do movement interpolation (extrapolation) when there is a non-zero velocity but 
                                // no acceleration
                                if (avatar.Acceleration != Vector3f.Zero && avatar.Velocity == Vector3f.Zero)
                                {
                                    avatar.Position += (avatar.Velocity + avatar.Acceleration *
                                        (0.5f * (adjSeconds - HAVOK_TIMESTEP))) * adjSeconds;
                                    avatar.Velocity += avatar.Acceleration * adjSeconds;
                                }
                                #endregion Linear Motion
                            }
                        );

                        // Iterate through all of this sims primitives
                        Client.Network.Simulators[i].ObjectsPrimitives.ForEach(
                            delegate(Primitive prim)
                            {
                                if (prim.Joint == JointType.Invalid)
                                {
                                    #region Angular Velocity
                                    Vector3f angVel = prim.AngularVelocity;
                                    float omega = angVel.LengthSquared();

                                    if (omega > 0.00001f)
                                    {
                                        omega = (float)Math.Sqrt(omega);
                                        float angle = omega * adjSeconds;
                                        angVel *= 1.0f / omega;
                                        Quaternionf dQ = new Quaternionf();
                                        dQ.FromAxisAngle(angVel, angle);

                                        prim.Rotation *= dQ;
                                    }
                                    #endregion Angular Velocity

                                    #region Linear Motion
                                    // Only do movement interpolation (extrapolation) when there is a non-zero velocity but 
                                    // no acceleration
                                    if (prim.Acceleration != Vector3f.Zero && prim.Velocity == Vector3f.Zero)
                                    {
                                        prim.Position += (prim.Velocity + prim.Acceleration *
                                            (0.5f * (adjSeconds - HAVOK_TIMESTEP))) * adjSeconds;
                                        prim.Velocity += prim.Acceleration * adjSeconds;
                                    }
                                    #endregion Linear Motion
                                }
                                else if (prim.Joint == JointType.Hinge)
                                {
                                    //FIXME: Hinge movement extrapolation
                                }
                                else if (prim.Joint == JointType.Point)
                                {
                                    //FIXME: Point movement extrapolation
                                }
                                else
                                {
                                    Logger.Log("Unhandled joint type " + prim.Joint, Helpers.LogLevel.Warning, Client);
                                }
                            }
                        );
                    }
                }

                // Make sure the last interpolated time is always updated
                Client.Self.lastInterpolation = Environment.TickCount;
            }
        }
예제 #14
0
        public Quaternionf GetQuaternion()
        {
            Quaternionf quat = new Quaternionf();
            float trace = Trace() + 1f;

            if (trace > Single.Epsilon)
            {
                float s = 0.5f / (float)System.Math.Sqrt(trace);

                quat.X = (R2.Y - R1.Z) * s;
                quat.Y = (R0.Z - R2.X) * s;
                quat.Z = (R1.X - R0.Y) * s;
                quat.W = 0.25f / s;
            }
            else
            {
                if (R0.X > R1.Y && R0.X > R2.Z)
                {
                    float s = 2.0f * (float)System.Math.Sqrt(1.0f + R0.X - R1.Y - R2.Z);

                    quat.X = 0.25f * s;
                    quat.Y = (R0.Y + R1.X) / s;
                    quat.Z = (R0.Z + R2.X) / s;
                    quat.W = (R1.Z - R2.Y) / s;
                }
                else if (R1.Y > R2.Z)
                {
                    float s = 2.0f * (float)System.Math.Sqrt(1.0f + R1.Y - R0.X - R2.Z);

                    quat.X = (R0.Y + R1.X) / s;
                    quat.Y = 0.25f * s;
                    quat.Z = (R1.Z + R2.Y) / s;
                    quat.W = (R0.Z - R2.X) / s;
                }
                else
                {
                    float s = 2.0f * (float)System.Math.Sqrt(1.0f + R2.Z - R0.X - R1.Y);

                    quat.X = (R0.Z + R2.X) / s;
                    quat.Y = (R1.Z + R2.Y) / s;
                    quat.Z = 0.25f * s;
                    quat.W = (R0.Y - R1.X) / s;
                }
            }

            return quat;
        }
예제 #15
0
        /// <summary>
        /// Spherical linear interpolation between this quaternion and another
        /// </summary>
        /// <param name="quaternion"></param>
        /// <param name="amount"></param>
        public Quaternionf Slerp(Quaternionf quaternion, float amount)
        {
            float angle = Dot(quaternion);
            Quaternionf q1 = this;

            if (angle < 0f)
            {
                q1.Negate();
                angle *= -1f;
            }

            float scale;
            float invscale;

            if ((angle + 1f) > 0.05f)
            {
                if ((1f - angle) >= 0.05f)
                {
                    // slerp
                    float theta = (float)System.Math.Acos(angle);
                    float invsintheta = 1f / (float)System.Math.Sin(theta);
                    scale = (float)System.Math.Sin(theta * (1f - amount)) * invsintheta;
                    invscale = (float)System.Math.Sin(theta * amount) * invsintheta;
                }
                else
                {
                    // lerp
                    scale = 1f - amount;
                    invscale = amount;
                }
            }
            else
            {
                quaternion.X = -q1.Y;
                quaternion.Y = q1.X;
                quaternion.Z = -q1.W;
                quaternion.W = q1.Z;

                scale = (float)System.Math.Sin(Utils.Pi * (0.5f - amount));
                invscale = (float)System.Math.Sin(Utils.Pi * amount);
            }

            return (q1 * scale) + (quaternion * invscale);
        }
예제 #16
0
        public Matrix4f Transform(Quaternionf rotation)
        {
            float x2 = rotation.X + rotation.X;
            float y2 = rotation.Y + rotation.Y;
            float z2 = rotation.Z + rotation.Z;

            float a = (1f - rotation.Y * y2) - rotation.Z * z2;
            float b = rotation.X * y2 - rotation.W * z2;
            float c = rotation.X * z2 + rotation.W * y2;
            float d = rotation.X * y2 + rotation.W * z2;
            float e = (1f - rotation.X * x2) - rotation.Z * z2;
            float f = rotation.Y * z2 - rotation.W * x2;
            float g = rotation.X * z2 - rotation.W * y2;
            float h = rotation.Y * z2 + rotation.W * x2;
            float i = (1f - rotation.X * x2) - rotation.Y * y2;

            return new Matrix4f(
                new Vector4f(
                    ((R0.X * a) + (R0.Y * b)) + (R0.Z * c),
                    ((R0.X * d) + (R0.Y * e)) + (R0.Z * f),
                    ((R0.X * g) + (R0.Y * h)) + (R0.Z * i),
                    R0.W),
                new Vector4f(
                    ((R1.X * a) + (R1.Y * b)) + (R1.Z * c),
                    ((R1.X * d) + (R1.Y * e)) + (R1.Z * f),
                    ((R1.X * g) + (R1.Y * h)) + (R1.Z * i),
                    R1.W),
                new Vector4f(
                    ((R2.X * a) + (R2.Y * b)) + (R2.Z * c),
                    ((R2.X * d) + (R2.Y * e)) + (R2.Z * f),
                    ((R2.X * g) + (R2.Y * h)) + (R2.Z * i),
                    R2.W),
                new Vector4f(
                    ((R3.X * a) + (R3.Y * b)) + (R3.Z * c),
                    ((R3.X * d) + (R3.Y * e)) + (R3.Z * f),
                    ((R3.X * g) + (R3.Y * h)) + (R3.Z * i),
                    R3.W));
        }
예제 #17
0
 public bool ApproxEquals(Quaternionf quaternion, float tolerance)
 {
     Vector4f diff = Vector - quaternion.Vector;
     return (diff.Length() <= tolerance);
 }
예제 #18
0
        public CoordinateFrame(Vector3f origin, Quaternionf rotation)
        {
            Matrix4f m = new Matrix4f();
            m.FromQuaternion(rotation);

            this.origin = origin;
            xAxis = new Vector3f(m.M11, m.M21, m.M31);
            yAxis = new Vector3f(m.M12, m.M22, m.M32);
            zAxis = new Vector3f(m.M13, m.M23, m.M33);

            if (!IsFinite())
                throw new ArgumentException("Non-finite in CoordinateFrame constructor");
        }
예제 #19
0
 public Quaternionf(Quaternionf quaternion)
 {
     Vector = quaternion.Vector;
 }
예제 #20
0
 public void Rotate(Quaternionf q)
 {
     Matrix4f m = new Matrix4f();
     m.FromQuaternion(q);
     Rotate(m);
 }
예제 #21
0
            /// <summary>
            /// Send an AgentUpdate with the camera set at the current agent
            /// position and pointing towards the heading specified
            /// </summary>
            /// <param name="heading">Camera rotation in radians</param>
            /// <param name="reliable">Whether to send the AgentUpdate reliable
            /// or not</param>
            public void UpdateFromHeading(double heading, bool reliable)
            {
                Camera.Position = Client.Self.SimPosition;
                Camera.LookDirection(heading);
                
                BodyRotation.Z = (float)Math.Sin(heading / 2.0d);
                BodyRotation.W = (float)Math.Cos(heading / 2.0d);
                HeadRotation = BodyRotation;

                SendUpdate(reliable);
            }
예제 #22
0
 /// <summary>
 /// Rez an object from inventory
 /// </summary>
 /// <param name="simulator">Simulator to place object in</param>
 /// <param name="rotation">Rotation of the object when rezzed</param>
 /// <param name="position">Vector of where to place object</param>
 /// <param name="item">InventoryObject object containing item details</param>
 public Guid RequestRezFromInventory(Simulator simulator, Quaternionf rotation, Vector3f position,
     InventoryObject item)
 {
     return RequestRezFromInventory(simulator, rotation, position, item, _Client.Self.ActiveGroup,
         Guid.NewGuid(), false);
 }
예제 #23
0
            /// <summary>
            /// Rotates the avatar body and camera toward a target position.
            /// This will also anchor the camera position on the avatar
            /// </summary>
            /// <param name="target">Region coordinates to turn toward</param>
            public bool TurnToward(Vector3f target)
            {
                if (Client.Settings.SEND_AGENT_UPDATES)
                {
                    Quaternionf parentRot = Quaternionf.Identity;

                    if (Client.Self.SittingOn > 0)
                    {
                        if (!Client.Network.CurrentSim.ObjectsPrimitives.ContainsKey(Client.Self.SittingOn))
                        {
                            Logger.Log("Attempted TurnToward but parent prim is not in dictionary", Helpers.LogLevel.Warning, Client);
                            return false;
                        }
                        else parentRot = Client.Network.CurrentSim.ObjectsPrimitives[Client.Self.SittingOn].Rotation;
                    }

                    Vector3f norm = target - Client.Self.SimPosition;
                    norm.Normalize();
                    Quaternionf rotBetween = Vector3f.UnitX.RotationBetween(ref norm);

                    Quaternionf rot = rotBetween * (Quaternionf.Identity / parentRot);

                    BodyRotation = rot;
                    HeadRotation = rot;
                    Camera.LookAt(Client.Self.SimPosition, target);

                    SendUpdate();

                    return true;
                }
                else
                {
                    Logger.Log("Attempted TurnToward but agent updates are disabled", Helpers.LogLevel.Warning, Client);
                    return false;
                }
            }
예제 #24
0
        /// <summary>
        /// Rez an object from inventory
        /// </summary>
        /// <param name="simulator">Simulator to place object in</param>
        /// <param name="rotation">Rotation of the object when rezzed</param>
        /// <param name="position">Vector of where to place object</param>
        /// <param name="item">InventoryObject object containing item details</param>
        /// <param name="groupOwner">Guid of group to own the object</param>        
        /// <param name="queryID">User defined queryID to correlate replies</param>
        /// <param name="requestObjectDetails">if set to true the simulator
        /// will automatically send object detail packet(s) back to the client</param>
        public Guid RequestRezFromInventory(Simulator simulator, Quaternionf rotation, Vector3f position,
            InventoryObject item, Guid groupOwner, Guid queryID, bool requestObjectDetails)
        {
            RezObjectPacket add = new RezObjectPacket();

            add.AgentData.AgentID = _Client.Self.AgentID;
            add.AgentData.SessionID = _Client.Self.SessionID;
            add.AgentData.GroupID = groupOwner;

            add.RezData.FromTaskID = Guid.Empty;
            add.RezData.BypassRaycast = 1;
            add.RezData.RayStart = position;
            add.RezData.RayEnd = position;
            add.RezData.RayTargetID = Guid.Empty;
            add.RezData.RayEndIsIntersection = false;
            add.RezData.RezSelected = requestObjectDetails;
            add.RezData.RemoveItem = false;
            add.RezData.ItemFlags = (uint)item.Flags;
            add.RezData.GroupMask = (uint)item.Permissions.GroupMask;
            add.RezData.EveryoneMask = (uint)item.Permissions.EveryoneMask;
            add.RezData.NextOwnerMask = (uint)item.Permissions.NextOwnerMask;

            add.InventoryData.ItemID = item.Guid;
            add.InventoryData.FolderID = item.ParentGuid;
            add.InventoryData.CreatorID = item.CreatorID;
            add.InventoryData.OwnerID = item.OwnerID;
            add.InventoryData.GroupID = item.GroupID;
            add.InventoryData.BaseMask = (uint)item.Permissions.BaseMask;
            add.InventoryData.OwnerMask = (uint)item.Permissions.OwnerMask;
            add.InventoryData.GroupMask = (uint)item.Permissions.GroupMask;
            add.InventoryData.EveryoneMask = (uint)item.Permissions.EveryoneMask;
            add.InventoryData.NextOwnerMask = (uint)item.Permissions.NextOwnerMask;
            add.InventoryData.GroupOwned = item.GroupOwned;
            add.InventoryData.TransactionID = queryID;
            add.InventoryData.Type = (sbyte)item.InventoryType;
            add.InventoryData.InvType = (sbyte)item.InventoryType;
            add.InventoryData.Flags = (uint)item.Flags;
            add.InventoryData.SaleType = (byte)item.SaleType;
            add.InventoryData.SalePrice = item.SalePrice;
            add.InventoryData.Name = Utils.StringToBytes(item.Name);
            add.InventoryData.Description = Utils.StringToBytes(item.Description);
            add.InventoryData.CreationDate = (int)Utils.DateTimeToUnixTime(item.CreationDate);

            _Client.Network.SendPacket(add, simulator);

            return queryID;
        }
예제 #25
0
        /// <summary>
        /// Change the Rotation of an object that is either a child or a whole linkset
        /// </summary>
        /// <param name="simulator">A reference to the <seealso cref="OpenMetaverse.Simulator"/> object where the object resides</param>
        /// <param name="localID">The objects ID which is local to the simulator the object is in</param>
        /// <param name="quat">The new scale of the object</param>
        /// <param name="childOnly">If true, will change rotation of this prim only, not entire linkset</param>
        public void SetRotation(Simulator simulator, uint localID, Quaternionf quat, bool childOnly)
        {
            UpdateType type = UpdateType.Rotation;

            if (!childOnly)
                type |= UpdateType.Linked;

            MultipleObjectUpdatePacket multiObjectUpdate = new MultipleObjectUpdatePacket();
            multiObjectUpdate.AgentData.AgentID = Client.Self.AgentID;
            multiObjectUpdate.AgentData.SessionID = Client.Self.SessionID;

            multiObjectUpdate.ObjectData = new MultipleObjectUpdatePacket.ObjectDataBlock[1];

            multiObjectUpdate.ObjectData[0] = new MultipleObjectUpdatePacket.ObjectDataBlock();
            multiObjectUpdate.ObjectData[0].Type = (byte)type;
            multiObjectUpdate.ObjectData[0].ObjectLocalID = localID;
            multiObjectUpdate.ObjectData[0].Data = quat.GetBytes();

            Client.Network.SendPacket(multiObjectUpdate, simulator);
        }