public void Quaternions()
        {
            LLQuaternion a = new LLQuaternion(1, 0, 0, 0);
            LLQuaternion b = new LLQuaternion(1, 0, 0, 0);

            Assert.IsTrue(a == b, "LLQuaternion comparison operator failed");

            LLQuaternion expected = new LLQuaternion(0, 0, 0, -1);
            LLQuaternion result = a * b;

            Assert.IsTrue(result == expected, a.ToString() + " * " + b.ToString() + " produced " + result.ToString() +
                " instead of " + expected.ToString());

            a = new LLQuaternion(1, 0, 0, 0);
            b = new LLQuaternion(0, 1, 0, 0);
            expected = new LLQuaternion(0, 0, 1, 0);
            result = a * b;

            Assert.IsTrue(result == expected, a.ToString() + " * " + b.ToString() + " produced " + result.ToString() +
                " instead of " + expected.ToString());

            a = new LLQuaternion(0, 0, 1, 0);
            b = new LLQuaternion(0, 1, 0, 0);
            expected = new LLQuaternion(-1, 0, 0, 0);
            result = a * b;

            Assert.IsTrue(result == expected, a.ToString() + " * " + b.ToString() + " produced " + result.ToString() +
                " instead of " + expected.ToString());
        }
Beispiel #2
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)
            {
                LLVector3 origin = Camera.Position;
                LLVector3 xAxis  = Camera.LeftAxis;
                LLVector3 yAxis  = Camera.AtAxis;
                LLVector3 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.CONTINUOUS_AGENT_UPDATES || duplicateCount < 10)
                {
                    // Store the current state to do duplicate checking in the future
                    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);

                    ResetControlFlags();
                }
            }
Beispiel #3
0
        public static LLVector3 operator *(LLVector3 vec, LLQuaternion quat)
        {
            LLQuaternion vq = new LLQuaternion(vec.X, vec.Y, vec.Z, 0);
            LLQuaternion nq = new LLQuaternion(-quat.X, -quat.Y, -quat.Z, quat.W);

            LLQuaternion result = (quat * vq) * nq;

            return(new LLVector3(result.X, result.Y, result.Z));
        }
Beispiel #4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="lhs"></param>
        /// <param name="rhs"></param>
        /// <returns></returns>
        public static LLQuaternion operator *(LLQuaternion lhs, LLQuaternion rhs)
        {
            LLQuaternion ret = new LLQuaternion();

            ret.W = lhs.W * rhs.W - lhs.X * rhs.X - lhs.Y * rhs.Y - lhs.Z * rhs.Z;
            ret.X = lhs.W * rhs.X + lhs.X * rhs.W + lhs.Y * rhs.Z - lhs.Z * rhs.Y;
            ret.Y = lhs.W * rhs.Y + lhs.Y * rhs.W + lhs.Z * rhs.X - lhs.X * rhs.Z;
            ret.Z = lhs.W * rhs.Z + lhs.Z * rhs.W + lhs.X * rhs.Y - lhs.Y * rhs.X;
            return(ret);
        }
Beispiel #5
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);
            }
Beispiel #6
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="o"></param>
        /// <returns></returns>
        public override bool Equals(object o)
        {
            if (!(o is LLQuaternion))
            {
                return(false);
            }

            LLQuaternion quaternion = (LLQuaternion)o;

            return(X == quaternion.X && Y == quaternion.Y && Z == quaternion.Z && W == quaternion.W);
        }
Beispiel #7
0
        public void Yaw(float angle)
        {
            LLQuaternion q = new LLQuaternion(angle, zAxis);
            LLMatrix3    m = new LLMatrix3(q);

            Rotate(m);

            if (!xAxis.IsFinite() || !yAxis.IsFinite())
            {
                throw new Exception("Non-finite in CoordinateFrame.Yaw()");
            }
        }
Beispiel #8
0
        public CoordinateFrame(LLVector3 origin, LLQuaternion rotation)
        {
            LLMatrix3 m = new LLMatrix3(rotation);

            this.origin = origin;
            xAxis       = m[0];
            yAxis       = m[1];
            zAxis       = m[2];

            if (!IsFinite())
            {
                throw new ArgumentException("Non-finite in CoordinateFrame constructor");
            }
        }
Beispiel #9
0
        /// <summary>
        /// Constructor, aka 'CallBack Central' - Setup callbacks for packets related to our avatar
        /// </summary>
        /// <param name="client"></param>
        public MainAvatar(SecondLife client)
        {
            PacketCallback callback;

            Client          = client;
            TeleportMessage = "";

            // Create emtpy vectors for now
            HomeLookAt = HomePosition = Position = LookAt = new LLVector3();
            Rotation   = new LLQuaternion();

            // Coarse location callback
            Client.Network.RegisterCallback(PacketType.CoarseLocationUpdate, new PacketCallback(CoarseLocationHandler));

            // Teleport callbacks
            callback = new PacketCallback(TeleportHandler);
            Client.Network.RegisterCallback(PacketType.TeleportStart, callback);
            Client.Network.RegisterCallback(PacketType.TeleportProgress, callback);
            Client.Network.RegisterCallback(PacketType.TeleportFailed, callback);
            Client.Network.RegisterCallback(PacketType.TeleportFinish, callback);

            // Instant Message callback
            Client.Network.RegisterCallback(PacketType.ImprovedInstantMessage, new PacketCallback(InstantMessageHandler));

            // Chat callback
            Client.Network.RegisterCallback(PacketType.ChatFromSimulator, new PacketCallback(ChatHandler));

            TeleportTimer          = new Timer(18000);
            TeleportTimer.Elapsed += new ElapsedEventHandler(TeleportTimerEvent);
            TeleportTimeout        = false;

            // Movement complete callback
            Client.Network.RegisterCallback(PacketType.AgentMovementComplete, new PacketCallback(MovementCompleteHandler));

            // Health callback
            Client.Network.RegisterCallback(PacketType.HealthMessage, new PacketCallback(HealthHandler));

            // Money callbacks
            callback = new PacketCallback(BalanceHandler);
            Client.Network.RegisterCallback(PacketType.MoneyBalanceReply, callback);
            Client.Network.RegisterCallback(PacketType.MoneySummaryReply, callback);
            Client.Network.RegisterCallback(PacketType.AdjustBalance, callback);
        }
Beispiel #10
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(LLVector3 target)
            {
                if (Client.Settings.SEND_AGENT_UPDATES)
                {
                    LLVector3    myPos   = Client.Self.SimPosition;
                    LLVector3    forward = new LLVector3(1, 0, 0);
                    LLVector3    offset  = LLVector3.Norm(target - myPos);
                    LLQuaternion newRot  = LLVector3.RotBetween(forward, offset);

                    BodyRotation = newRot;
                    HeadRotation = newRot;
                    Camera.LookAt(myPos, target);

                    SendUpdate();

                    return(true);
                }
                else
                {
                    Logger.Log("Attempted TurnToward but agent updates are disabled", Helpers.LogLevel.Warning, Client);
                    return(false);
                }
            }
Beispiel #11
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, LLVector3 position, LLVector3 forwardAxis,
                                         LLVector3 leftAxis, LLVector3 upAxis, LLQuaternion bodyRotation, LLQuaternion 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);
            }
Beispiel #12
0
 /// <summary>
 /// Calculate the magnitude of the supplied quaternion
 /// </summary>
 public static float RotMag(LLQuaternion q)
 {
     return (float)Math.Sqrt(q.W * q.W + q.X * q.X + q.Y * q.Y + q.Z * q.Z);
 }
        private void TerseUpdateHandler(Packet packet, Simulator simulator)
        {
            float        x, y, z, w;
            uint         localid;
            LLVector4    CollisionPlane = null;
            LLVector3    Position;
            LLVector3    Velocity;
            LLVector3    Acceleration;
            LLQuaternion Rotation;
            LLVector3    RotationVelocity;

            ImprovedTerseObjectUpdatePacket update = (ImprovedTerseObjectUpdatePacket)packet;

            foreach (ImprovedTerseObjectUpdatePacket.ObjectDataBlock block in update.ObjectData)
            {
                int  i = 0;
                bool avatar;

                localid = (uint)(block.Data[i++] + (block.Data[i++] << 8) +
                                 (block.Data[i++] << 16) + (block.Data[i++] << 24));

                byte state = block.Data[i++];

                avatar = Convert.ToBoolean(block.Data[i++]);

                if (avatar)
                {
                    if (OnAvatarMoved == null)
                    {
                        return;
                    }

                    CollisionPlane = new LLVector4(block.Data, i);
                    i += 16;
                }
                else
                {
                    if (OnPrimMoved == null)
                    {
                        return;
                    }
                }

                // Position
                Position = new LLVector3(block.Data, i);
                i       += 12;
                // Velocity
                x        = Dequantize(block.Data, i, -128.0F, 128.0F);
                i       += 2;
                y        = Dequantize(block.Data, i, -128.0F, 128.0F);
                i       += 2;
                z        = Dequantize(block.Data, i, -128.0F, 128.0F);
                i       += 2;
                Velocity = new LLVector3(x, y, z);
                // Acceleration
                x            = Dequantize(block.Data, i, -64.0F, 64.0F);
                i           += 2;
                y            = Dequantize(block.Data, i, -64.0F, 64.0F);
                i           += 2;
                z            = Dequantize(block.Data, i, -64.0F, 64.0F);
                i           += 2;
                Acceleration = new LLVector3(x, y, z);
                // Rotation
                x        = Dequantize(block.Data, i, -1.0F, 1.0F);
                i       += 2;
                y        = Dequantize(block.Data, i, -1.0F, 1.0F);
                i       += 2;
                z        = Dequantize(block.Data, i, -1.0F, 1.0F);
                i       += 2;
                w        = Dequantize(block.Data, i, -1.0F, 1.0F);
                i       += 2;
                Rotation = new LLQuaternion(x, y, z, w);
                // Rotation velocity
                x  = Dequantize(block.Data, i, -64.0F, 64.0F);
                i += 2;
                y  = Dequantize(block.Data, i, -64.0F, 64.0F);
                i += 2;
                z  = Dequantize(block.Data, i, -64.0F, 64.0F);
                i += 2;
                RotationVelocity = new LLVector3(x, y, z);

                if (avatar)
                {
                    if (localid == Client.Self.LocalID)
                    {
                        Client.Self.Position = Position;
                        Client.Self.Rotation = Rotation;
                    }

                    AvatarUpdate avupdate = new AvatarUpdate();
                    avupdate.LocalID          = localid;
                    avupdate.State            = state;
                    avupdate.Position         = Position;
                    avupdate.CollisionPlane   = CollisionPlane;
                    avupdate.Velocity         = Velocity;
                    avupdate.Acceleration     = Acceleration;
                    avupdate.Rotation         = Rotation;
                    avupdate.RotationVelocity = RotationVelocity;

                    if (OnAvatarMoved != null)
                    {
                        OnAvatarMoved(simulator, avupdate, update.RegionData.RegionHandle, update.RegionData.TimeDilation);
                    }
                }
                else
                {
                    // TODO: Is there an easy way to distinguish prims from trees in this packet,
                    // or would the client have to do it's own lookup to determine whether it's a
                    // prim or a tree? If the latter, we should rename this update to something
                    // less prim specific

                    PrimUpdate primupdate = new PrimUpdate();
                    primupdate.LocalID          = localid;
                    primupdate.State            = state;
                    primupdate.Position         = Position;
                    primupdate.Velocity         = Velocity;
                    primupdate.Acceleration     = Acceleration;
                    primupdate.Rotation         = Rotation;
                    primupdate.RotationVelocity = RotationVelocity;

                    if (OnPrimMoved != null)
                    {
                        OnPrimMoved(simulator, primupdate, update.RegionData.RegionHandle, update.RegionData.TimeDilation);
                    }
                }
            }
        }
Beispiel #14
0
        public void Rotate(LLQuaternion q)
        {
            LLMatrix3 m = new LLMatrix3(q);

            Rotate(m);
        }
Beispiel #15
0
        /// <summary>
        /// Create, or "rez" a new prim object in a simulator
        /// </summary>
        /// <param name="simulator">A reference to the <seealso cref="libsecondlife.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 LLUUID.Zero 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, LLObject.ObjectData prim, LLUUID groupID, LLVector3 position, 
            LLVector3 scale, LLQuaternion 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)LLObject.ObjectFlags.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 = LLObject.PackBeginCut(prim.PathBegin);
            packet.ObjectData.PathEnd = LLObject.PackEndCut(prim.PathEnd);
            packet.ObjectData.PathRadiusOffset = LLObject.PackPathTwist(prim.PathRadiusOffset);
            packet.ObjectData.PathRevolutions = LLObject.PackPathRevolutions(prim.PathRevolutions);
            packet.ObjectData.PathScaleX = LLObject.PackPathScale(prim.PathScaleX);
            packet.ObjectData.PathScaleY = LLObject.PackPathScale(prim.PathScaleY);
            packet.ObjectData.PathShearX = (byte)LLObject.PackPathShear(prim.PathShearX);
            packet.ObjectData.PathShearY = (byte)LLObject.PackPathShear(prim.PathShearY);
            packet.ObjectData.PathSkew = LLObject.PackPathTwist(prim.PathSkew);
            packet.ObjectData.PathTaperX = LLObject.PackPathTaper(prim.PathTaperX);
            packet.ObjectData.PathTaperY = LLObject.PackPathTaper(prim.PathTaperY);
            packet.ObjectData.PathTwist = LLObject.PackPathTwist(prim.PathTwist);
            packet.ObjectData.PathTwistBegin = LLObject.PackPathTwist(prim.PathTwistBegin);

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

            packet.ObjectData.RayStart = position;
            packet.ObjectData.RayEnd = position;
            packet.ObjectData.RayEndIsIntersection = 0;
            packet.ObjectData.RayTargetID = LLUUID.Zero;
            packet.ObjectData.BypassRaycast = 1;

            Client.Network.SendPacket(packet, simulator);
        }
Beispiel #16
0
 /// <summary>
 /// Multiplication operator
 /// </summary>
 /// <param name="lhs"></param>
 /// <param name="rhs"></param>
 /// <returns></returns>
 public static LLQuaternion operator *(LLQuaternion lhs, LLQuaternion rhs)
 {
     LLQuaternion ret = new LLQuaternion();
     ret.W = lhs.W * rhs.W - lhs.X * rhs.X - lhs.Y * rhs.Y - lhs.Z * rhs.Z;
     ret.X = lhs.W * rhs.X + lhs.X * rhs.W + lhs.Y * rhs.Z - lhs.Z * rhs.Y;
     ret.Y = lhs.W * rhs.Y + lhs.Y * rhs.W + lhs.Z * rhs.X - lhs.X * rhs.Z;
     ret.Z = lhs.W * rhs.Z + lhs.Z * rhs.W + lhs.X * rhs.Y - lhs.Y * rhs.X;
     return ret;
 }
Beispiel #17
0
        /// <summary>
        /// Returns a normalized version of the supplied quaternion
        /// </summary>
        /// <param name="q">The quaternion to normalize</param>
        /// <returns>A normalized version of the quaternion</returns>
        public static LLQuaternion Norm(LLQuaternion q)
        {
            const float MAG_THRESHOLD = 0.0000001f;
            float mag = (float)Math.Sqrt(q.X * q.X + q.Y * q.Y + q.Z * q.Z + q.W * q.W);

            if (mag > MAG_THRESHOLD)
            {
                float oomag = 1.0f / mag;
                q.X *= oomag;
                q.Y *= oomag;
                q.Z *= oomag;
                q.W *= oomag;
            }
            else
            {
                q.X = 0.0f;
                q.Y = 0.0f;
                q.Z = 0.0f;
                q.W = 1.0f;
            }

            return q;
        }
Beispiel #18
0
 public void Rotate(LLQuaternion q)
 {
     LLMatrix3 m = new LLMatrix3(q);
     Rotate(m);
 }
Beispiel #19
0
        protected bool MultipleObjUpdate(SimClient simClient, Packet packet)
        {
            MultipleObjectUpdatePacket multipleupdate = (MultipleObjectUpdatePacket)packet;
            for (int i = 0; i < multipleupdate.ObjectData.Length; i++)
            {
                if (multipleupdate.ObjectData[i].Type == 9) //change position
                {
                    libsecondlife.LLVector3 pos = new LLVector3(multipleupdate.ObjectData[i].Data, 0);
                    foreach (Entity ent in m_world.Entities.Values)
                    {
                        if (ent.localid == multipleupdate.ObjectData[i].ObjectLocalID)
                        {
                            ((OpenSim.world.Primitive)ent).UpdatePosition(pos);

                        }
                    }
                    //should update stored position of the prim
                }
                else if (multipleupdate.ObjectData[i].Type == 10)//rotation
                {
                    libsecondlife.LLQuaternion rot = new LLQuaternion(multipleupdate.ObjectData[i].Data, 0, true);
                    foreach (Entity ent in m_world.Entities.Values)
                    {
                        if (ent.localid == multipleupdate.ObjectData[i].ObjectLocalID)
                        {
                            ent.rotation = new Axiom.MathLib.Quaternion(rot.W, rot.X, rot.Y, rot.Z);
                            ((OpenSim.world.Primitive)ent).UpdateFlag = true;
                        }
                    }
                }
                else if (multipleupdate.ObjectData[i].Type == 13)//scale
                {

                    libsecondlife.LLVector3 scale = new LLVector3(multipleupdate.ObjectData[i].Data, 12);
                    foreach (Entity ent in m_world.Entities.Values)
                    {
                        if (ent.localid == multipleupdate.ObjectData[i].ObjectLocalID)
                        {
                            ((OpenSim.world.Primitive)ent).Scale = scale;
                        }
                    }
                }
            }
            return true;
        }
            /// <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);
            }
Beispiel #21
0
        public CoordinateFrame(LLVector3 origin, LLQuaternion rotation)
        {
            LLMatrix3 m = new LLMatrix3(rotation);

            this.origin = origin;
            xAxis = m[0];
            yAxis = m[1];
            zAxis = m[2];

            if (!IsFinite())
                throw new ArgumentException("Non-finite in CoordinateFrame constructor");
        }
Beispiel #22
0
        public static LLVector3 operator *(LLVector3 vec, LLQuaternion quat)
        {
            LLQuaternion vq = new LLQuaternion(vec.X, vec.Y, vec.Z, 0);
            LLQuaternion nq = new LLQuaternion(-quat.X, -quat.Y, -quat.Z, quat.W);

            LLQuaternion result = (quat * vq) * nq;

            return new LLVector3(result.X, result.Y, result.Z);
        }
Beispiel #23
0
 public static LLVector3 Rot(LLVector3 vector, LLQuaternion rotation)
 {
     return vector * rotation;
 }
Beispiel #24
0
 public LLMatrix3(LLQuaternion q)
 {
     this = LLQuaternion.GetMatrix(q);
 }
Beispiel #25
0
        public void Rotate(float angle, LLVector3 rotationAxis)
        {
            LLQuaternion q = new LLQuaternion(angle, rotationAxis);

            Rotate(q);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="simulator"></param>
        /// <param name="scale"></param>
        /// <param name="rotation"></param>
        /// <param name="position"></param>
        /// <param name="grassType"></param>
        /// <param name="groupOwner"></param>
        public void AddGrass(Simulator simulator, LLVector3 scale, LLQuaternion rotation, LLVector3 position,
            Grass grassType, LLUUID groupOwner)
        {
            ObjectAddPacket add = new ObjectAddPacket();

            add.AgentData.AgentID = Client.Network.AgentID;
            add.AgentData.SessionID = Client.Network.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 = LLUUID.Zero;
            add.ObjectData.Rotation = rotation;
            add.ObjectData.Scale = scale;
            add.ObjectData.State = (byte)grassType;

            Client.Network.SendPacket(add, simulator);
        }
        /// <summary>
        /// Constructor, aka 'CallBack Central' - Setup callbacks for packets related to our avatar
        /// </summary>
        /// <param name="client"></param>
        public MainAvatar(SecondLife client)
        {
            PacketCallback callback;
            Client = client;
            TeleportMessage = "";

            // Create emtpy vectors for now
            HomeLookAt = HomePosition = Position = LookAt = new LLVector3();
            Rotation = new LLQuaternion();

            // Coarse location callback
            Client.Network.RegisterCallback(PacketType.CoarseLocationUpdate, new PacketCallback(CoarseLocationHandler));

            // Teleport callbacks
            callback = new PacketCallback(TeleportHandler);
            Client.Network.RegisterCallback(PacketType.TeleportStart, callback);
            Client.Network.RegisterCallback(PacketType.TeleportProgress, callback);
            Client.Network.RegisterCallback(PacketType.TeleportFailed, callback);
            Client.Network.RegisterCallback(PacketType.TeleportFinish, callback);

            // Instant Message callback
            Client.Network.RegisterCallback(PacketType.ImprovedInstantMessage, new PacketCallback(InstantMessageHandler));

            // Chat callback
            Client.Network.RegisterCallback(PacketType.ChatFromSimulator, new PacketCallback(ChatHandler));

            TeleportTimer = new Timer(18000);
            TeleportTimer.Elapsed += new ElapsedEventHandler(TeleportTimerEvent);
            TeleportTimeout = false;

            // Movement complete callback
            Client.Network.RegisterCallback(PacketType.AgentMovementComplete, new PacketCallback(MovementCompleteHandler));

            // Health callback
            Client.Network.RegisterCallback(PacketType.HealthMessage, new PacketCallback(HealthHandler));

            // Money callbacks
            callback = new PacketCallback(BalanceHandler);
            Client.Network.RegisterCallback(PacketType.MoneyBalanceReply, callback);
            Client.Network.RegisterCallback(PacketType.MoneySummaryReply, callback);
            Client.Network.RegisterCallback(PacketType.AdjustBalance, callback);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="simulator"></param>
        /// <param name="localID"></param>
        /// <param name="attachPoint"></param>
        /// <param name="rotation"></param>
        public void AttachObject(Simulator simulator, uint localID, AttachmentPoint attachPoint, LLQuaternion rotation)
        {
            ObjectAttachPacket attach = new ObjectAttachPacket();
            attach.AgentData.AgentID = Client.Network.AgentID;
            attach.AgentData.SessionID = Client.Network.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);
        }
        private void TerseUpdateHandler(Packet packet, Simulator simulator)
        {
            float x, y, z, w;
            uint localid;
            LLVector4 CollisionPlane = LLVector4.Zero;
            LLVector3 Position;
            LLVector3 Velocity;
            LLVector3 Acceleration;
            LLQuaternion Rotation;
            LLVector3 RotationVelocity;

            ImprovedTerseObjectUpdatePacket update = (ImprovedTerseObjectUpdatePacket)packet;

            foreach (ImprovedTerseObjectUpdatePacket.ObjectDataBlock block in update.ObjectData)
            {
                int i = 0;
                bool avatar;

                localid = (uint)(block.Data[i++] + (block.Data[i++] << 8) +
                    (block.Data[i++] << 16) + (block.Data[i++] << 24));

                byte state = block.Data[i++];

                avatar = Convert.ToBoolean(block.Data[i++]);

                if (avatar)
                {
                    if (OnAvatarMoved == null) return;

                    CollisionPlane = new LLVector4(block.Data, i);
                    i += 16;
                }
                else
                {
                    if (OnPrimMoved == null) return;
                }

                // Position
                Position = new LLVector3(block.Data, i);
                i += 12;
                // Velocity
                x = Dequantize(block.Data, i, -128.0F, 128.0F);
                i += 2;
                y = Dequantize(block.Data, i, -128.0F, 128.0F);
                i += 2;
                z = Dequantize(block.Data, i, -128.0F, 128.0F);
                i += 2;
                Velocity = new LLVector3(x, y, z);
                // Acceleration
                x = Dequantize(block.Data, i, -64.0F, 64.0F);
                i += 2;
                y = Dequantize(block.Data, i, -64.0F, 64.0F);
                i += 2;
                z = Dequantize(block.Data, i, -64.0F, 64.0F);
                i += 2;
                Acceleration = new LLVector3(x, y, z);
                // Rotation
                x = Dequantize(block.Data, i, -1.0F, 1.0F);
                i += 2;
                y = Dequantize(block.Data, i, -1.0F, 1.0F);
                i += 2;
                z = Dequantize(block.Data, i, -1.0F, 1.0F);
                i += 2;
                w = Dequantize(block.Data, i, -1.0F, 1.0F);
                i += 2;
                Rotation = new LLQuaternion(x, y, z, w);
                // Rotation velocity
                x = Dequantize(block.Data, i, -64.0F, 64.0F);
                i += 2;
                y = Dequantize(block.Data, i, -64.0F, 64.0F);
                i += 2;
                z = Dequantize(block.Data, i, -64.0F, 64.0F);
                i += 2;
                RotationVelocity = new LLVector3(x, y, z);

                if (avatar)
                {
                    if (localid == Client.Self.LocalID)
                    {
                        Client.Self.Position = Position;
                        Client.Self.Rotation = Rotation;
                    }

                    AvatarUpdate avupdate = new AvatarUpdate();
                    avupdate.LocalID = localid;
                    avupdate.State = state;
                    avupdate.Position = Position;
                    avupdate.CollisionPlane = CollisionPlane;
                    avupdate.Velocity = Velocity;
                    avupdate.Acceleration = Acceleration;
                    avupdate.Rotation = Rotation;
                    avupdate.RotationVelocity = RotationVelocity;
                    avupdate.Textures = new TextureEntry(block.TextureEntry, 4, block.TextureEntry.Length - 4);

                    if (OnAvatarMoved != null)
                    {
                        OnAvatarMoved(simulator, avupdate, update.RegionData.RegionHandle, update.RegionData.TimeDilation);
                    }
                }
                else
                {
                    // TODO: Is there an easy way to distinguish prims from trees in this packet,
                    // or would the client have to do it's own lookup to determine whether it's a
                    // prim or a tree? If the latter, we should rename this update to something 
                    // less prim specific

                    PrimUpdate primupdate = new PrimUpdate();
                    primupdate.LocalID = localid;
                    primupdate.State = state;
                    primupdate.Position = Position;
                    primupdate.Velocity = Velocity;
                    primupdate.Acceleration = Acceleration;
                    primupdate.Rotation = Rotation;
                    primupdate.RotationVelocity = RotationVelocity;
                    primupdate.Textures = new TextureEntry(block.TextureEntry, 4, block.TextureEntry.Length - 4);

                    if (OnPrimMoved != null)
                    {
                        OnPrimMoved(simulator, primupdate, update.RegionData.RegionHandle, update.RegionData.TimeDilation);
                    }
                }
            }
        }
Beispiel #30
0
        /// <summary>
        /// Returns the inverse matrix from a quaternion, or the correct
        /// matrix if the quaternion is inverse
        /// </summary>
        /// <param name="q">Quaternion to convert to a matrix</param>
        /// <returns>A matrix representation of the quaternion</returns>
        public static LLMatrix3 GetMatrix(LLQuaternion q)
        {
            LLMatrix3 m;
            float xx, xy, xz, xw, yy, yz, yw, zz, zw;

            xx = q.X * q.X;
            xy = q.X * q.Y;
            xz = q.X * q.Z;
            xw = q.X * q.W;

            yy = q.Y * q.Y;
            yz = q.Y * q.Z;
            yw = q.Y * q.W;

            zz = q.Z * q.Z;
            zw = q.Z * q.W;

            m.M11 = 1f - 2f * (yy + zz);
            m.M12 = 2f * (xy + zw);
            m.M13 = 2f * (xz - yw);

            m.M21 = 2f * (xy - zw);
            m.M22 = 1f - 2f * (xx + zz);
            m.M23 = 2f * (yz + xw);

            m.M31 = 2f * (xz + yw);
            m.M32 = 2f * (yz - xw);
            m.M33 = 1f - 2f * (xx + yy);

            return m;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="simulator"></param>
        /// <param name="localID"></param>
        /// <param name="rotation"></param>
        public void SetRotation(Simulator simulator, uint localID, LLQuaternion rotation)
        {
            ObjectRotationPacket objRotPacket = new ObjectRotationPacket();
            objRotPacket.AgentData.AgentID = Client.Network.AgentID;
            objRotPacket.AgentData.SessionID = Client.Network.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);
        }
Beispiel #32
0
        public LLQuaternion ToQuaternion()
        {
            LLQuaternion quat = new LLQuaternion();
            float tr, s;
            float[] q = new float[4];
            int i, j, k;
            int[] nxt = new int[] { 1, 2, 0 };

            tr = this[0, 0] + this[1, 1] + this[2, 2];

            // Check the diagonal
            if (tr > 0f)
            {
                s = (float)Math.Sqrt(tr + 1f);
                quat.W = s / 2f;
                
                s = 0.5f / s;
                quat.X = (this[1, 2] - this[2, 1]) * s;
                quat.Y = (this[2, 0] - this[0, 2]) * s;
                quat.Z = (this[0, 1] - this[1, 0]) * s;
            }
            else
            {
                // Diagonal is negative
                i = 0;
                if (this[1, 1] > this[0, 0])
                    i = 1;
                if (this[2, 2] > this[i, i])
                    i = 2;

                j = nxt[i];
                k = nxt[j];

                s = (float)Math.Sqrt((this[i, i] - (this[j, j] + this[k, k])) + 1f);
                q[i] = s * 0.5f;

                if (s != 0f)
                    s = 0.5f / s;

                q[3] = (this[j, k] - this[k, j]) * s;
                q[j] = (this[i, j] + this[j, i]) * s;
                q[k] = (this[i, k] + this[k, i]) * s;

                quat.X = q[0];
                quat.Y = q[1];
                quat.Z = q[2];
                quat.W = q[3];
            }

            return quat;
        }
            /// <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(LLVector3 target)
            {
                if (Client.Settings.SEND_AGENT_UPDATES)
                {
                    LLVector3 myPos = Client.Self.SimPosition;
                    LLVector3 forward = new LLVector3(1, 0, 0);
                    LLVector3 offset = LLVector3.Norm(target - myPos);
                    LLQuaternion newRot = LLVector3.RotBetween(forward, offset);

                    BodyRotation = newRot;
                    HeadRotation = newRot;
                    Camera.LookAt(myPos, target);

                    SendUpdate();

                    return true;
                }
                else
                {
                    Logger.Log("Attempted TurnToward but agent updates are disabled", Helpers.LogLevel.Warning, Client);
                    return false;
                }
            }
Beispiel #34
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">LLUUID of group to own the object</param>
 public LLUUID RequestRezFromInventory(Simulator simulator, LLQuaternion rotation, LLVector3 position,
     InventoryObject item, LLUUID groupOwner)
 {
     return RequestRezFromInventory(simulator, rotation, position, item, groupOwner, LLUUID.Random(), false);
 }
Beispiel #35
0
 public void Rotate(float angle, LLVector3 rotationAxis)
 {
     LLQuaternion q = new LLQuaternion(angle, rotationAxis);
     Rotate(q);
 }
            /// <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)
            {
                LLVector3 origin = Camera.Position;
                LLVector3 xAxis = Camera.LeftAxis;
                LLVector3 yAxis = Camera.AtAxis;
                LLVector3 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();
                    }
                }
            }
Beispiel #37
0
        public void Yaw(float angle)
        {
            LLQuaternion q = new LLQuaternion(angle, zAxis);
            LLMatrix3 m = new LLMatrix3(q);
            Rotate(m);

            if (!xAxis.IsFinite() || !yAxis.IsFinite())
                throw new Exception("Non-finite in CoordinateFrame.Yaw()");
        }
            /// <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, LLVector3 position, LLVector3 forwardAxis,
                LLVector3 leftAxis, LLVector3 upAxis, LLQuaternion bodyRotation, LLQuaternion 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);
            }
        /// <summary>
        /// Sends camera and action updates to the server including the 
        /// position and orientation of our camera, and a ControlFlags field
        /// specifying our current movement actions
        /// </summary>
        /// <param name="reliable">Whether to ensure this packet makes it to the server</param>
        public void UpdateCamera(Avatar.AgentUpdateFlags controlFlags, LLVector3 position, LLVector3 forwardAxis,
            LLVector3 leftAxis, LLVector3 upAxis, LLQuaternion bodyRotation, LLQuaternion headRotation, float farClip,
            bool reliable)
        {
            AgentUpdatePacket update = new AgentUpdatePacket();

            update.AgentData.AgentID = Client.Network.AgentID;
            update.AgentData.SessionID = Client.Network.SessionID;
            update.AgentData.State = 0;
            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 = 0;
            update.Header.Reliable = reliable;

            Client.Network.SendPacket(update);
        }
Beispiel #40
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];

                LLVector4 collisionPlane = LLVector4.Zero;
                LLVector3 position;
                LLVector3 velocity;
                LLVector3 acceleration;
                LLQuaternion rotation;
                LLVector3 angularVelocity;
                NameValue[] nameValues;
                bool attachment = false;
                PCode pcode = (PCode)block.PCode;

                #region Relevance check

                // Check if we are interested in this object
                if (!Client.Settings.ALWAYS_DECODE_OBJECTS)
                {
                    switch (pcode)
                    {
                        case PCode.Grass:
                        case PCode.Tree:
                        case PCode.NewTree:
                            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 = Helpers.FieldToUTF8String(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
                LLObject.ObjectData data = new LLObject.ObjectData();
                data.State = block.State;
                data.Material = (LLObject.MaterialType)block.Material;
                data.PathCurve = (LLObject.PathCurve)block.PathCurve;
                data.profileCurve = block.ProfileCurve;
                data.PathBegin = LLObject.UnpackBeginCut(block.PathBegin);
                data.PathEnd = LLObject.UnpackEndCut(block.PathEnd);
                data.PathScaleX = LLObject.UnpackPathScale(block.PathScaleX);
                data.PathScaleY = LLObject.UnpackPathScale(block.PathScaleY);
                data.PathShearX = LLObject.UnpackPathShear((sbyte)block.PathShearX);
                data.PathShearY = LLObject.UnpackPathShear((sbyte)block.PathShearY);
                data.PathTwist = LLObject.UnpackPathTwist(block.PathTwist);
                data.PathTwistBegin = LLObject.UnpackPathTwist(block.PathTwistBegin);
                data.PathRadiusOffset = LLObject.UnpackPathTwist(block.PathRadiusOffset);
                data.PathTaperX = LLObject.UnpackPathTaper(block.PathTaperX);
                data.PathTaperY = LLObject.UnpackPathTaper(block.PathTaperY);
                data.PathRevolutions = LLObject.UnpackPathRevolutions(block.PathRevolutions);
                data.PathSkew = LLObject.UnpackPathTwist(block.PathSkew);
                data.ProfileBegin = LLObject.UnpackBeginCut(block.ProfileBegin);
                data.ProfileEnd = LLObject.UnpackEndCut(block.ProfileEnd);
                data.ProfileHollow = LLObject.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 = new LLVector4(block.ObjectData, pos);
                        pos += 16;

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

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

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

                        // Position
                        position = new LLVector3(
                            Helpers.UInt16ToFloat(block.ObjectData, pos, -0.5f * 256.0f, 1.5f * 256.0f),
                            Helpers.UInt16ToFloat(block.ObjectData, pos + 2, -0.5f * 256.0f, 1.5f * 256.0f),
                            Helpers.UInt16ToFloat(block.ObjectData, pos + 4, -256.0f, 3.0f * 256.0f));
                        pos += 6;
                        // Velocity
                        velocity = new LLVector3(
                            Helpers.UInt16ToFloat(block.ObjectData, pos, -256.0f, 256.0f),
                            Helpers.UInt16ToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f),
                            Helpers.UInt16ToFloat(block.ObjectData, pos + 4, -256.0f, 256.0f));
                        pos += 6;
                        // Acceleration
                        acceleration = new LLVector3(
                            Helpers.UInt16ToFloat(block.ObjectData, pos, -256.0f, 256.0f),
                            Helpers.UInt16ToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f),
                            Helpers.UInt16ToFloat(block.ObjectData, pos + 4, -256.0f, 256.0f));
                        pos += 6;
                        // Rotation (theta)
                        rotation = new LLQuaternion(
                            Helpers.UInt16ToFloat(block.ObjectData, pos, -1.0f, 1.0f),
                            Helpers.UInt16ToFloat(block.ObjectData, pos + 2, -1.0f, 1.0f),
                            Helpers.UInt16ToFloat(block.ObjectData, pos + 4, -1.0f, 1.0f),
                            Helpers.UInt16ToFloat(block.ObjectData, pos + 6, -1.0f, 1.0f));
                        pos += 8;
                        // Angular velocity (omega)
                        angularVelocity = new LLVector3(
                            Helpers.UInt16ToFloat(block.ObjectData, pos, -256.0f, 256.0f),
                            Helpers.UInt16ToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f),
                            Helpers.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 LLVector3(
                            Helpers.ByteToFloat(block.ObjectData, pos, -256.0f, 256.0f),
                            Helpers.ByteToFloat(block.ObjectData, pos + 1, -256.0f, 256.0f),
                            Helpers.ByteToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f));
                        pos += 3;
                        // Velocity
                        velocity = new LLVector3(
                            Helpers.ByteToFloat(block.ObjectData, pos, -256.0f, 256.0f),
                            Helpers.ByteToFloat(block.ObjectData, pos + 1, -256.0f, 256.0f),
                            Helpers.ByteToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f));
                        pos += 3;
                        // Accleration
                        acceleration = new LLVector3(
                            Helpers.ByteToFloat(block.ObjectData, pos, -256.0f, 256.0f),
                            Helpers.ByteToFloat(block.ObjectData, pos + 1, -256.0f, 256.0f),
                            Helpers.ByteToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f));
                        pos += 3;
                        // Rotation
                        rotation = new LLQuaternion(
                            Helpers.ByteToFloat(block.ObjectData, pos, -1.0f, 1.0f),
                            Helpers.ByteToFloat(block.ObjectData, pos + 1, -1.0f, 1.0f),
                            Helpers.ByteToFloat(block.ObjectData, pos + 2, -1.0f, 1.0f),
                            Helpers.ByteToFloat(block.ObjectData, pos + 3, -1.0f, 1.0f));
                        pos += 4;
                        // Angular Velocity
                        angularVelocity = new LLVector3(
                            Helpers.ByteToFloat(block.ObjectData, pos, -256.0f, 256.0f),
                            Helpers.ByteToFloat(block.ObjectData, pos + 1, -256.0f, 256.0f),
                            Helpers.ByteToFloat(block.ObjectData, pos + 2, -256.0f, 256.0f));
                        pos += 3;

                        break;
                    default:
                        Client.Log("Got an ObjectUpdate block with ObjectUpdate field length of " +
                            block.ObjectData.Length, Helpers.LogLevel.Warning);

                        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 = (LLObject.ObjectFlags)block.UpdateFlags;

                        if ((prim.Flags & LLObject.ObjectFlags.ZlibCompressed) != 0)
                        {
                            Client.Log("Got a ZlibCompressed ObjectUpdate, implement me!", 
                                Helpers.LogLevel.Warning);
                            continue;
                        }

                        // Automatically request ObjectProperties for prim if it was rezzed selected.
                        if ((prim.Flags & LLObject.ObjectFlags.CreateSelected) == LLObject.ObjectFlags.CreateSelected)
                            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 = Helpers.FieldToUTF8String(block.MediaURL);
                        prim.Text = Helpers.FieldToUTF8String(block.Text);
                        prim.TextColor = new LLColor(block.TextColor, 0, false);
                        // Only alpha is inversed
                        prim.TextColor.A = (byte)(1.0f - prim.TextColor.A);

                        // Sound information
                        prim.Sound = block.Sound;
                        prim.SoundFlags = block.Flags;
                        prim.SoundGain = block.Gain;
                        prim.SoundRadius = block.Radius;

                        // Joint information
                        prim.Joint = (Primitive.JointType)block.JointType;
                        prim.JointPivot = block.JointPivot;
                        prim.JointAxisOrAnchor = block.JointAxisOrAnchor;
                        
                        // Object parameters
                        prim.Data = data;

                        // Textures, texture animations, particle system, and extra params
                        prim.Textures = new LLObject.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.sittingOn;

                        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.Data = data;
                        avatar.GenericData = block.Data;
                        avatar.sittingOn = block.ParentID;

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

                        // Set the current simulator for this avatar
                        avatar.CurrentSim = simulator;

                        // 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:
                        Client.DebugLog("Got an ObjectUpdate block with an unrecognized PCode " + pcode.ToString());
                        break;
                }
            }
        }
Beispiel #41
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 LLUUID RequestRezFromInventory(Simulator simulator, LLQuaternion rotation, LLVector3 position,
     InventoryObject item)
 {
     return RequestRezFromInventory(simulator, rotation, position, item, _Client.Self.ActiveGroup,
         LLUUID.Random(), false);
 }
Beispiel #42
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 != LLVector3.Zero && avatar.Velocity == LLVector3.Zero)
                                {
                                    avatar.Position += (avatar.Velocity + (0.5f * (adjSeconds - HAVOK_TIMESTEP)) *
                                        avatar.Acceleration) * 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 == Primitive.JointType.Invalid)
                                {
                                    #region Angular Velocity
                                    LLVector3 angVel = prim.AngularVelocity;
                                    float omega = LLVector3.MagSquared(angVel);

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

                                        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 != LLVector3.Zero && prim.Velocity == LLVector3.Zero)
                                    {
                                        prim.Position += (prim.Velocity + (0.5f * (adjSeconds - HAVOK_TIMESTEP)) *
                                            prim.Acceleration) * adjSeconds;
                                        prim.Velocity += prim.Acceleration * adjSeconds;
                                    }
                                    #endregion Linear Motion
                                }
                                else if (prim.Joint == Primitive.JointType.Hinge)
                                {
                                    //FIXME: Hinge movement extrapolation
                                }
                                else if (prim.Joint == Primitive.JointType.Point)
                                {
                                    //FIXME: Point movement extrapolation
                                }
                                else
                                {
                                    Client.Log("Unhandled joint type " + prim.Joint, Helpers.LogLevel.Warning);
                                }
                            }
                        );
                    }
                }

                // Make sure the last interpolated time is always updated
                Client.Self.lastInterpolation = Environment.TickCount;
            }
        }
Beispiel #43
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">LLUUID 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 LLUUID RequestRezFromInventory(Simulator simulator, LLQuaternion rotation, LLVector3 position,
            InventoryObject item, LLUUID groupOwner, LLUUID 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 = LLUUID.Zero;
            add.RezData.BypassRaycast = 1;
            add.RezData.RayStart = position;
            add.RezData.RayEnd = position;
            add.RezData.RayTargetID = LLUUID.Zero;
            add.RezData.RayEndIsIntersection = false;
            add.RezData.RezSelected = requestObjectDetails;
            add.RezData.RemoveItem = false;
            add.RezData.ItemFlags = 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.UUID;
            add.InventoryData.FolderID = item.ParentUUID;
            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 = item.Flags;
            add.InventoryData.SaleType = (byte)item.SaleType;
            add.InventoryData.SalePrice = item.SalePrice;
            add.InventoryData.Name = Helpers.StringToField(item.Name);
            add.InventoryData.Description = Helpers.StringToField(item.Description);
            add.InventoryData.CreationDate = (int)Helpers.DateTimeToUnixTime(item.CreationDate);

            _Client.Network.SendPacket(add, simulator);

            return queryID;
        }
Beispiel #44
0
        public static Primitive FromLLSD(LLSD llsd)
        {
            Primitive prim = new Primitive();

            LLObject.ObjectData data = new ObjectData();

            LLSDMap map     = (LLSDMap)llsd;
            LLSDMap volume  = (LLSDMap)map["volume"];
            LLSDMap path    = (LLSDMap)volume["path"];
            LLSDMap profile = (LLSDMap)volume["profile"];

            #region Path/Profile

            data.PathBegin        = (float)path["begin"].AsReal();
            data.PathCurve        = (PathCurve)path["curve"].AsInteger();
            data.PathEnd          = (float)path["end"].AsReal();
            data.PathRadiusOffset = (float)path["radius_offset"].AsReal();
            data.PathRevolutions  = (float)path["revolutions"].AsReal();
            data.PathScaleX       = (float)path["scale_x"].AsReal();
            data.PathScaleY       = (float)path["scale_y"].AsReal();
            data.PathShearX       = (float)path["shear_x"].AsReal();
            data.PathShearY       = (float)path["shear_y"].AsReal();
            data.PathSkew         = (float)path["skew"].AsReal();
            data.PathTaperX       = (float)path["taper_x"].AsReal();
            data.PathTaperY       = (float)path["taper_y"].AsReal();
            data.PathTwist        = path["twist"].AsInteger();
            data.PathTwistBegin   = path["twist_begin"].AsInteger();

            data.ProfileBegin  = (float)profile["begin"].AsReal();
            data.ProfileCurve  = (ProfileCurve)profile["curve"].AsInteger();
            data.ProfileHole   = (HoleType)profile["hole"].AsInteger();
            data.ProfileEnd    = (float)profile["end"].AsReal();
            data.ProfileHollow = (float)profile["hollow"].AsReal();

            #endregion Path/Profile

            prim.Data = data;

            if (map["phantom"].AsBoolean())
            {
                prim.Flags |= ObjectFlags.Phantom;
            }

            if (map["physical"].AsBoolean())
            {
                prim.Flags |= ObjectFlags.Physics;
            }

            if (map["shadows"].AsBoolean())
            {
                prim.Flags |= ObjectFlags.CastShadows;
            }

            prim.ParentID = (uint)map["parentid"].AsInteger();
            prim.Position = LLVector3.FromLLSD(map["position"]);
            prim.Rotation = LLQuaternion.FromLLSD(map["rotation"]);
            prim.Scale    = LLVector3.FromLLSD(map["scale"]);
            prim.Flexible = FlexibleData.FromLLSD(map["flexible"]);
            prim.Light    = LightData.FromLLSD(map["light"]);
            prim.Sculpt   = SculptData.FromLLSD(map["sculpt"]);
            prim.Textures = TextureEntry.FromLLSD(map["textures"]);

            return(prim);
        }