//Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke

        // Old implementation of llRot2Euler. Normalization not required as Atan2 function will
        // only return values >= -PI (-180 degrees) and <= PI (180 degrees).

        public LSL_Vector llRot2Euler(LSL_Rotation r)
        {
            //This implementation is from http://lslwiki.net/lslwiki/wakka.php?wakka=LibraryRotationFunctions. ckrinke
            LSL_Rotation t = new LSL_Rotation(r.x * r.x, r.y * r.y, r.z * r.z, r.s * r.s);
            double       m = (t.x + t.y + t.z + t.s);

            if (FloatAlmostEqual(m, 0))
            {
                return(new LSL_Vector());
            }

            double n = 2 * (r.y * r.s + r.x * r.z);
            double p = m * m - n * n;

            if (p > 0)
            {
                return(new LSL_Vector(Math.Atan2(2.0 * (r.x * r.s - r.y * r.z), (-t.x - t.y + t.z + t.s)),
                                      Math.Atan2(n, Math.Sqrt(p)),
                                      Math.Atan2(2.0 * (r.z * r.s - r.x * r.y), (t.x - t.y - t.z + t.s))));
            }
            if (n > 0)
            {
                return(new LSL_Vector(0.0, Math.PI * 0.5, Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z)));
            }
            return(new LSL_Vector(0.0, -Math.PI * 0.5, Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z)));
        }
        public LSL_Float llAngleBetween(LSL_Rotation a, LSL_Rotation b)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
            {
                return(new LSL_Float());
            }


            double aa    = (a.x * a.x + a.y * a.y + a.z * a.z + a.s * a.s);
            double bb    = (b.x * b.x + b.y * b.y + b.z * b.z + b.s * b.s);
            double aa_bb = aa * bb;

            if (FloatAlmostEqual(aa_bb, 0))
            {
                return(0.0);
            }
            double ab       = (a.x * b.x + a.y * b.y + a.z * b.z + a.s * b.s);
            double quotient = (ab * ab) / aa_bb;

            if (quotient >= 1.0)
            {
                return(0.0);
            }
            return(Math.Acos(2 * quotient - 1));
        }
        public LSL_Vector llRot2Up(LSL_Rotation r)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
            {
                return(new LSL_Vector());
            }

            double m = r.x * r.x + r.y * r.y + r.z * r.z + r.s * r.s;

            // m is always greater than zero
            // if m is not equal to 1 then Rotation needs to be normalized
            if (Math.Abs(1.0 - m) > 0.000001) // allow a little slop here for calculation precision
            {
                m    = 1.0 / Math.Sqrt(m);
                r.x *= m;
                r.y *= m;
                r.z *= m;
                r.s *= m;
            }

            // Fast Algebric Calculations instead of Vectors & Quaternions Product
            double x = 2 * (r.x * r.z + r.y * r.s);
            double y = 2 * (-r.x * r.s + r.y * r.z);
            double z = -r.x * r.x - r.y * r.y + r.z * r.z + r.s * r.s;

            return(new LSL_Vector(x, y, z));
        }
        // Returns the angle of a quaternion (see llRot2Axis for the axis)
        public LSL_Float llRot2Angle(LSL_Rotation rot)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
            {
                return(new LSL_Float());
            }


            if (rot.s > 1) // normalization needed
            {
                double length = Math.Sqrt(rot.x * rot.x + rot.y * rot.y +
                                          rot.z * rot.z + rot.s * rot.s);

                if (FloatAlmostEqual(length, 0))
                {
                    return(0);
                }
                //                rot.x /= length;
                //                rot.y /= length;
                //                rot.z /= length;
                rot.s /= length;
            }

            double angle = 2 * Math.Acos(rot.s);

            return(angle);
        }
        // convert a LSL_Rotation to a Quaternion
        protected Quaternion Rot2Quaternion(LSL_Rotation r)
        {
            Quaternion q = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);

            q.Normalize();
            return(q);
        }
Esempio n. 6
0
 public void llSitTarget(LSL_Vector offset, LSL_Rotation rot)
 {
     if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
     {
         return;
     }
     SitTarget(m_host, offset, rot);
 }
Esempio n. 7
0
        public DateTime llSetLocalRot(LSL_Rotation rot)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
            {
                return(DateTime.Now);
            }

            SetRot(m_host, Rot2Quaternion(rot));
            return(PScriptSleep(m_sleepMsOnSetLocalRot));
        }
Esempio n. 8
0
        public LSL_Integer llRotTarget(LSL_Rotation rot, double error)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
            {
                return(0);
            }

            return
                (m_host.registerRotTargetWaypoint(
                     new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s), (float)error));
        }
Esempio n. 9
0
        public void llRotLookAt(LSL_Rotation target, double strength, double damping)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
            {
                return;
            }

            Quaternion rot = new Quaternion((float)target.x, (float)target.y, (float)target.z, (float)target.s);

            m_host.RotLookAt(rot, (float)strength, (float)damping);
        }
Esempio n. 10
0
        public DateTime llSetRot(LSL_Rotation rot)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
            {
                return(DateTime.Now);
            }


            // try to let this work as in SL...
            SetLinkRot(m_host, rot);
            return(PScriptSleep(m_sleepMsOnSetRot));
        }
Esempio n. 11
0
        // 04122016 Fly-Man-
        // This function is unknown on the SL Wiki
        public void llLinkRotLookAt(LSL_Integer link, LSL_Rotation target, double strength, double damping)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
            {
                return;
            }

            Quaternion rot = new Quaternion((float)target.x, (float)target.y, (float)target.z, (float)target.s);
            List <ISceneChildEntity> parts = GetLinkParts(link);

            foreach (ISceneChildEntity part in parts)
            {
                part.RotLookAt(rot, (float)strength, (float)damping);
            }
        }
Esempio n. 12
0
        public void llSetVehicleRotationParam(int param, LSL_Rotation rot)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
            {
                return;
            }

            if (m_host.ParentEntity != null)
            {
                if (!m_host.ParentEntity.IsDeleted)
                {
                    m_host.ParentEntity.RootChild.SetVehicleRotationParam(param, Rot2Quaternion(rot));
                }
            }
        }
        // Xantor 29/apr/2008
        // converts a Quaternion to X,Y,Z axis rotations
        public LSL_Vector llRot2Axis(LSL_Rotation rot)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
            {
                return(new LSL_Vector());
            }

            double x, y, z;

            if (rot.s > 1) // normalization needed
            {
                double length = Math.Sqrt(rot.x * rot.x + rot.y * rot.y +
                                          rot.z * rot.z + rot.s * rot.s);
                if (FloatAlmostEqual(length, 0))
                {
                    return(new LSL_Vector(0, 0, 0));
                }
                length = 1 / length;
                rot.x *= length;
                rot.y *= length;
                rot.z *= length;
                rot.s *= length;
            }

            // double angle = 2 * Math.Acos(rot.s);
            double s = Math.Sqrt(1 - rot.s * rot.s);

            if (s < 0.001)
            {
                x = 1;
                y = z = 0;
            }
            else
            {
                s = 1 / s;
                x = rot.x * s; // normalise axis
                y = rot.y * s;
                z = rot.z * s;
            }

            return(new LSL_Vector(x, y, z));
        }
Esempio n. 14
0
        public void botSetRotation(LSL_Key npc, LSL_Rotation rotation)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.Moderate, "botSetRotation", m_host, "bot", m_itemID))
            {
                return;
            }
            IScenePresence sp = World.GetScenePresence(UUID.Parse(npc));

            if (sp == null)
            {
                return;
            }
            UUID uid;

            if (!UUID.TryParse(npc.m_string, out uid))    // not actually interested in the UUID, just need to make sure it is 'real'
            {
                return;
            }

            sp.Rotation = rotation.ToQuaternion();
        }
Esempio n. 15
0
        public void botSetRot(LSL_Key npc, LSL_Rotation rotation)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.Moderate, "botStandUp", m_host, "bot", m_itemID))
            {
                return;
            }
            IScenePresence sp = World.GetScenePresence(UUID.Parse(npc));

            if (sp == null)
            {
                return;
            }
            UUID npcId;

            if (!UUID.TryParse(npc.m_string, out npcId))
            {
                return;
            }

            if (sp != null)
            {
                sp.Rotation = rotation.ToQuaternion();
            }
        }
Esempio n. 16
0
        public void llLinkSitTarget(LSL_Integer link, LSL_Vector offset, LSL_Rotation rot)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
            {
                return;
            }

            if (link == ScriptBaseClass.LINK_ROOT)
            {
                SitTarget(m_host.ParentEntity.RootChild, offset, rot);
            }
            else if (link == ScriptBaseClass.LINK_THIS)
            {
                SitTarget(m_host, offset, rot);
            }
            else
            {
                var entity = m_host.ParentEntity.GetLinkNumPart(link);
                if (entity != null)
                {
                    SitTarget((ISceneChildEntity)entity, offset, rot);
                }
            }
        }
Esempio n. 17
0
 public DateTime llRezObject(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param)
 {
     return(llRezPrim(inventory, pos, vel, rot, param, false, true, true, true));
 }
        public LSL_Rotation llRotBetween(LSL_Vector a, LSL_Vector b)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
            {
                return(new LSL_Rotation());
            }
            //A and B should both be normalized

            LSL_Rotation rotBetween;

            // Check for zero vectors. If either is zero, return zero rotation. Otherwise,
            // continue calculation.
            if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f))
            {
                rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
            }
            else
            {
                a = LSL_Vector.Norm(a);
                b = LSL_Vector.Norm(b);
                double dotProduct = LSL_Vector.Dot(a, b);
                // There are two degenerate cases possible. These are for vectors 180 or
                // 0 degrees apart. These have to be detected and handled individually.
                //
                // Check for vectors 180 degrees apart.
                // A dot product of -1 would mean the angle between vectors is 180 degrees.
                if (dotProduct < -0.9999999f)
                {
                    // First assume X axis is orthogonal to the vectors.
                    LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f);
                    orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a));
                    // Check for near zero vector. A very small non-zero number here will create
                    // a rotation in an undesired direction.
                    rotBetween = LSL_Vector.Mag(orthoVector) > 0.0001
                                     ? new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f)
                                     : new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
                }
                // Check for parallel vectors.
                // A dot product of 1 would mean the angle between vectors is 0 degrees.
                else if (dotProduct > 0.9999999f)
                {
                    // Set zero rotation.
                    rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
                }
                else
                {
                    // All special checks have been performed so get the axis of rotation.
                    LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
                    // Quarternion s value is the length of the unit vector + dot product.
                    double qs = 1.0 + dotProduct;
                    rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
                    // Normalize the rotation.
                    double mag = LSL_Rotation.Mag(rotBetween);
                    // We shouldn't have to worry about a divide by zero here. The qs value will be
                    // non-zero because we already know if we're here, then the dotProduct is not -1 so
                    // qs will not be zero. Also, we've already handled the input vectors being zero so the
                    // crossProduct vector should also not be zero.
                    rotBetween.x = rotBetween.x / mag;
                    rotBetween.y = rotBetween.y / mag;
                    rotBetween.z = rotBetween.z / mag;
                    rotBetween.s = rotBetween.s / mag;
                    // Check for undefined values and set zero rotation if any found. This code might not actually be required
                    // any longer since zero vectors are checked for at the top.
                    if (double.IsNaN(rotBetween.x) || double.IsNaN(rotBetween.y) ||
                        double.IsNaN(rotBetween.z) || double.IsNaN(rotBetween.s))
                    {
                        rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
                    }
                }
            }
            return(rotBetween);
        }
Esempio n. 19
0
        public void osNpcSetRot(LSL_Key npc, LSL_Rotation rotation)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.High, "osNpcSetRot", m_host, "OSSL", m_itemID))
                return;

            IBotManager manager = World.RequestModuleInterface<IBotManager>();
            if (manager != null)
            {
                UUID npcId;
                if (UUID.TryParse (npc.m_string, out npcId))
                {
                    if (!manager.CheckPermission (npcId, m_host.OwnerID))
                        return;

                    IScenePresence sp = World.GetScenePresence (npcId);

                    if (sp != null)
                        sp.Rotation = rotation.ToQuaternion ();
                }
            }
        }
Esempio n. 20
0
        public LSL_Vector llRot2Up(LSL_Rotation r)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
                return new LSL_Vector();

            double m = r.x * r.x + r.y * r.y + r.z * r.z + r.s * r.s;
            // m is always greater than zero
            // if m is not equal to 1 then Rotation needs to be normalized
            if (Math.Abs(1.0 - m) > 0.000001) // allow a little slop here for calculation precision
            {
                m = 1.0 / Math.Sqrt(m);
                r.x *= m;
                r.y *= m;
                r.z *= m;
                r.s *= m;
            }

            // Fast Algebric Calculations instead of Vectors & Quaternions Product
            double x = 2 * (r.x * r.z + r.y * r.s);
            double y = 2 * (-r.x * r.s + r.y * r.z);
            double z = -r.x * r.x - r.y * r.y + r.z * r.z + r.s * r.s;
            return (new LSL_Vector(x, y, z));
        }
Esempio n. 21
0
 public void llSitTarget(LSL_Vector offset, LSL_Rotation rot)
 {
     if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) 
         return;
     SitTarget (m_host, offset, rot);
 }
Esempio n. 22
0
        public void osForceDropAttachmentAt(LSL_Vector pos, LSL_Rotation rot)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.High, "osForceDropAttachmentAt", m_host, "OSSL", m_itemID)) return;

            DropAttachmentAt(false, pos, rot);
        }
Esempio n. 23
0
        /// <summary>
        ///     This isn't really an LSL function, just a way to merge llRezAtRoot and llRezObject into one
        /// </summary>
        /// <param name="inventory"></param>
        /// <param name="pos"></param>
        /// <param name="vel"></param>
        /// <param name="rot"></param>
        /// <param name="param"></param>
        /// <param name="isRezAtRoot"></param>
        /// <param name="doRecoil"></param>
        /// <param name="setDieAtEdge"></param>
        /// <param name="checkPos"></param>
        /// <returns></returns>
        public DateTime llRezPrim(string inventory, LSL_Vector pos, LSL_Vector vel,
                                  LSL_Rotation rot, int param, bool isRezAtRoot, bool doRecoil,
                                  bool setDieAtEdge, bool checkPos)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.Low, "llRezPrim", m_host, "LSL", m_itemID))
                return DateTime.Now;

            if (m_ScriptEngine.Config.GetBoolean("AllowllRezObject", true))
            {
                if (double.IsNaN(rot.x) || double.IsNaN(rot.y) || double.IsNaN(rot.z) || double.IsNaN(rot.s))
                    return DateTime.Now;
                if (checkPos)
                {
                    float dist = (float)llVecDist(llGetPos(), pos);

                    if (dist > m_ScriptDistanceFactor * 10.0f)
                        return DateTime.Now;
                }

                TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone();

                foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory)
                {
                    if (inv.Value.Name == inventory)
                    {
                        // make sure we're an object.
                        if (inv.Value.InvType != (int)InventoryType.Object)
                        {
                            llSay(0, "Unable to create requested object. Object is missing from database.");
                            return DateTime.Now;
                        }

                        Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
                        Vector3 llvel = new Vector3((float)vel.x, (float)vel.y, (float)vel.z);

                        ISceneEntity new_group = RezObject(m_host, inv.Value, llpos, Rot2Quaternion(rot), llvel, param,
                                                           m_host.UUID, isRezAtRoot);
                        if (new_group == null)
                            continue;
                        
                        new_group.OnFinishedPhysicalRepresentationBuilding += 
                            delegate() {
                            //Do this after the physics engine has built the prim
                            float groupmass = new_group.GetMass();
                            //Recoil to the av
                            if (m_host.IsAttachment && 
                                doRecoil && 
                                (new_group.RootChild.Flags & PrimFlags.Physics) == PrimFlags.Physics) {
                                IScenePresence SP = m_host.ParentEntity.Scene.GetScenePresence(m_host.OwnerID);
                                if (SP != null) {
                                    //Push the av backwards (For every action, there is an equal, but opposite reaction)
                                    Vector3 impulse = llvel * groupmass;
                                    impulse.X = impulse.X < 1 ? impulse.X : impulse.X > -1 ? impulse.X : -1;
                                    impulse.Y = impulse.Y < 1 ? impulse.Y : impulse.Y > -1 ? impulse.Y : -1;
                                    impulse.Z = impulse.Z < 1 ? impulse.Z : impulse.Z > -1 ? impulse.Z : -1;
                                    SP.PushForce(impulse);
                                }
                            }
                        };

                        // If there was an unknown error.
                        if (new_group.RootChild == null)
                            continue;

                        // objects rezzed with this method are die_at_edge by default.
                        if (setDieAtEdge)
                            new_group.RootChild.SetDieAtEdge(true);

                        // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
                        return PScriptSleep(m_sleepMsOnRezAtRoot);
                    }
                }

                llSay(0, "Could not find object " + inventory);
            }
            return DateTime.Now;
        }
Esempio n. 24
0
 /// <summary>
 ///     This isn't really an LSL function, just a way to merge llRezAtRoot and llRezObject into one
 /// </summary>
 /// <param name="inventory"></param>
 /// <param name="pos"></param>
 /// <param name="vel"></param>
 /// <param name="rot"></param>
 /// <param name="param"></param>
 /// <param name="isRezAtRoot"></param>
 /// <param name="setDieAtEdge"></param>
 /// <param name="checkPos"></param>
 /// <returns></returns>
 public DateTime llRezPrim(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot,
                           int param, bool isRezAtRoot, bool setDieAtEdge, bool checkPos)
 {
     return llRezPrim(inventory, pos, vel, rot, param, isRezAtRoot, false, setDieAtEdge, checkPos);
 }
Esempio n. 25
0
        public LSL_Integer llRotTarget(LSL_Rotation rot, double error)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) 
                return 0;

            return
                m_host.registerRotTargetWaypoint(
                    new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s), (float)error);
        }
Esempio n. 26
0
        public DateTime llSetLocalRot(LSL_Rotation rot)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
                return DateTime.Now;

            SetRot(m_host, Rot2Quaternion(rot));
            return PScriptSleep(m_sleepMsOnSetLocalRot);
        }
Esempio n. 27
0
 private void SetLinkRot(ISceneChildEntity obj, LSL_Rotation rot)
 {
     if (obj.ParentID == 0)
     {
         // special case: If we are root, rotate complete SOG to new rotation
         SetRot(obj, Rot2Quaternion(rot));
     }
     else
     {
         // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask.
         ISceneEntity group = obj.ParentEntity;
         if (group != null) // a bit paranoid, maybe
         {
             ISceneChildEntity rootPart = group.RootChild;
             if (rootPart != null) // again, better safe than sorry
             {
                 SetRot(obj, rootPart.GetRotationOffset() * Rot2Quaternion(rot));
             }
         }
     }
 }
Esempio n. 28
0
        public DateTime llSetRot(LSL_Rotation rot)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
                return DateTime.Now;


            // try to let this work as in SL...
            SetLinkRot(m_host, rot);
            return PScriptSleep(m_sleepMsOnSetRot);
        }
Esempio n. 29
0
        public void llSetKeyframedMotion(LSL_List keyframes, LSL_List options)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
            {
                return;
            }
            if (!m_host.IsRoot)
            {
                Error("llSetKeyframedMotion", "Must be used in the root object!");
                return;
            }
            KeyframeAnimation.Data  dataType    = KeyframeAnimation.Data.Both;
            KeyframeAnimation.Modes currentMode = KeyframeAnimation.Modes.Forward;
            for (int i = 0; i < options.Length; i += 2)
            {
                LSL_Integer option = options.GetLSLIntegerItem(i);
                LSL_Integer value  = options.GetLSLIntegerItem(i + 1);
                if (option == ScriptBaseClass.KFM_COMMAND)
                {
                    m_host.ParentEntity.AddKeyframedMotion(null, (KeyframeAnimation.Commands)value.value);
                    break; //Its supposed to be the only option in the list
                }
                if (option == ScriptBaseClass.KFM_MODE)
                {
                    currentMode = (KeyframeAnimation.Modes)value.value;
                }
                else if (option == ScriptBaseClass.KFM_DATA)
                {
                    dataType = (KeyframeAnimation.Data)value.value;
                }
            }
            List <Vector3>    positions = new List <Vector3>();
            List <Quaternion> rotations = new List <Quaternion>();
            List <float>      times     = new List <float>();

            for (int i = 0; i < keyframes.Length; i += (dataType == KeyframeAnimation.Data.Both ? 3 : 2))
            {
                if (dataType == KeyframeAnimation.Data.Both ||
                    dataType == KeyframeAnimation.Data.Translation)
                {
                    LSL_Vector pos = keyframes.GetVector3Item(i);
                    positions.Add(pos.ToVector3());
                }
                if (dataType == KeyframeAnimation.Data.Both ||
                    dataType == KeyframeAnimation.Data.Rotation)
                {
                    LSL_Rotation rot  = keyframes.GetQuaternionItem(i + (dataType == KeyframeAnimation.Data.Both ? 1 : 0));
                    Quaternion   quat = rot.ToQuaternion();
                    quat.Normalize();
                    rotations.Add(quat);
                }
                LSL_Float time = keyframes.GetLSLFloatItem(i + (dataType == KeyframeAnimation.Data.Both ? 2 : 1));
                times.Add((float)time);
            }
            KeyframeAnimation animation = new KeyframeAnimation
            {
                CurrentMode              = currentMode,
                PositionList             = positions.ToArray(),
                RotationList             = rotations.ToArray(),
                TimeList                 = times.ToArray(),
                CurrentAnimationPosition = 0,
                InitialPosition          = m_host.AbsolutePosition,
                InitialRotation          = m_host.GetRotationOffset()
            };

            m_host.ParentEntity.AddKeyframedMotion(animation, KeyframeAnimation.Commands.Play);
        }
Esempio n. 30
0
 /// <summary>
 ///     This isn't really an LSL function, just a way to merge llRezAtRoot and llRezObject into one
 /// </summary>
 /// <param name="inventory"></param>
 /// <param name="pos"></param>
 /// <param name="vel"></param>
 /// <param name="rot"></param>
 /// <param name="param"></param>
 /// <param name="isRezAtRoot"></param>
 /// <param name="setDieAtEdge"></param>
 /// <param name="checkPos"></param>
 /// <returns></returns>
 public DateTime llRezPrim(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot,
                           int param, bool isRezAtRoot, bool setDieAtEdge, bool checkPos)
 {
     return(llRezPrim(inventory, pos, vel, rot, param, isRezAtRoot, false, setDieAtEdge, checkPos));
 }
Esempio n. 31
0
 public DateTime llRezObject(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param)
 {
     return llRezPrim(inventory, pos, vel, rot, param, false, true, true, true);
 }
Esempio n. 32
0
        protected void SitTarget (ISceneChildEntity part, LSL_Vector offset, LSL_Rotation rot)
        {
            // LSL quaternions can normalize to 0, normal Quaternions can't.
            if (FloatAlmostEqual (rot.s, 0) &&
                FloatAlmostEqual (rot.x, 0) &&
                FloatAlmostEqual (rot.y, 0) &&
                FloatAlmostEqual (rot.z, 0))
                rot.z = 1; // ZERO_ROTATION = 0,0,0,1

            part.SitTargetPosition = new Vector3 ((float)offset.x, (float)offset.y, (float)offset.z);;
            part.SitTargetOrientation = Rot2Quaternion (rot);;
            part.ParentEntity.HasGroupChanged = true;
        }
Esempio n. 33
0
        private void LookAt(LSL_Vector target, double strength, double damping, ISceneChildEntity obj)
        {
            // Determine where we are looking from
            LSL_Vector from = new LSL_Vector(obj.GetWorldPosition());
			
			// The following code bit was written by Dahlia 
			// from the Opensimulator Core Team. Thank you for fixing this issue
			
			// normalized direction to target
            LSL_Vector dir = llVecNorm(target - from);
            
			// use vertical to help compute left axis
            LSL_Vector up = new LSL_Vector(0.0, 0.0, 1.0);
            
			// find normalized left axis parallel to horizon
            LSL_Vector left = llVecNorm(LSL_Vector.Cross(up, dir));
            
			// make up orthogonal to left and direction
            up = LSL_Vector.Cross(dir, left);
            
			// compute rotation based on orthogonal axes
            LSL_Rotation rot = new LSL_Rotation(0.0, 0.707107, 0.0, 0.707107) * llAxes2Rot(dir, left, up);
			
			// End codebit
            	
            //If the strength is 0, or we are non-physical, set the rotation
            if (FloatAlmostEqual(strength, 0) || obj.PhysActor == null || !obj.PhysActor.IsPhysical)
                SetLinkRot(obj, rot);
            else
                obj.startLookAt(Rot2Quaternion(rot), (float)strength, (float)damping);
        }
Esempio n. 34
0
        public void llLinkSitTarget(LSL_Integer link, LSL_Vector offset, LSL_Rotation rot)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) 
                return;

            if (link == ScriptBaseClass.LINK_ROOT)
                SitTarget (m_host.ParentEntity.RootChild, offset, rot);
            else if (link == ScriptBaseClass.LINK_THIS)
                SitTarget (m_host, offset, rot);
            else {
                var entity = m_host.ParentEntity.GetLinkNumPart (link);
                if (entity != null) {
                    SitTarget ((ISceneChildEntity) entity, offset, rot);
                }
            }
        }
Esempio n. 35
0
        protected void DropAttachmentAt(bool checkPerms, LSL_Vector pos, LSL_Rotation rot)
        {
            if (checkPerms && ShoutErrorOnLackingOwnerPerms(ScriptBaseClass.PERMISSION_ATTACH, "Cannot drop attachment"))
            {
                return;
            }

            IAttachmentsModule attachmentsModule = World.RequestModuleInterface<IAttachmentsModule>();
            IScenePresence sp = attachmentsModule == null ? null : World.GetScenePresence(m_host.OwnerID);

            if (attachmentsModule != null && sp != null)
            {
                attachmentsModule.DetachSingleAttachmentToGround(m_host.ParentEntity.UUID, sp.ControllingClient, pos.ToVector3(), rot.ToQuaternion());
            }
        }
Esempio n. 36
0
        public LSL_Rotation llRotBetween(LSL_Vector a, LSL_Vector b)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
                return new LSL_Rotation();
            //A and B should both be normalized

            LSL_Rotation rotBetween;
            // Check for zero vectors. If either is zero, return zero rotation. Otherwise,
            // continue calculation.
            if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f))
            {
                rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
            }
            else
            {
                a = LSL_Vector.Norm(a);
                b = LSL_Vector.Norm(b);
                double dotProduct = LSL_Vector.Dot(a, b);
                // There are two degenerate cases possible. These are for vectors 180 or
                // 0 degrees apart. These have to be detected and handled individually.
                //
                // Check for vectors 180 degrees apart.
                // A dot product of -1 would mean the angle between vectors is 180 degrees.
                if (dotProduct < -0.9999999f)
                {
                    // First assume X axis is orthogonal to the vectors.
                    LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f);
                    orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a));
                    // Check for near zero vector. A very small non-zero number here will create
                    // a rotation in an undesired direction.
                    rotBetween = LSL_Vector.Mag(orthoVector) > 0.0001
                                     ? new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f)
                                     : new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
                }
                // Check for parallel vectors.
                // A dot product of 1 would mean the angle between vectors is 0 degrees.
                else if (dotProduct > 0.9999999f)
                {
                    // Set zero rotation.
                    rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
                }
                else
                {
                    // All special checks have been performed so get the axis of rotation.
                    LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
                    // Quarternion s value is the length of the unit vector + dot product.
                    double qs = 1.0 + dotProduct;
                    rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
                    // Normalize the rotation.
                    double mag = LSL_Rotation.Mag(rotBetween);
                    // We shouldn't have to worry about a divide by zero here. The qs value will be
                    // non-zero because we already know if we're here, then the dotProduct is not -1 so
                    // qs will not be zero. Also, we've already handled the input vectors being zero so the
                    // crossProduct vector should also not be zero.
                    rotBetween.x = rotBetween.x / mag;
                    rotBetween.y = rotBetween.y / mag;
                    rotBetween.z = rotBetween.z / mag;
                    rotBetween.s = rotBetween.s / mag;
                    // Check for undefined values and set zero rotation if any found. This code might not actually be required
                    // any longer since zero vectors are checked for at the top.
                    if (double.IsNaN(rotBetween.x) || double.IsNaN(rotBetween.y) || 
                        double.IsNaN(rotBetween.z) || double.IsNaN(rotBetween.s))
                    {
                        rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
                    }
                }
            }
            return rotBetween;
        }
Esempio n. 37
0
 public DateTime osRezObject(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param,
                             LSL_Integer isRezAtRoot, LSL_Integer doRecoil, LSL_Integer SetDieAtEdge,
                             LSL_Integer CheckPos)
 {
     InitLSL();
     return m_LSL_Api.llRezPrim(inventory, pos, vel, rot, param, isRezAtRoot == 1, doRecoil == 1,
                                SetDieAtEdge == 1, CheckPos == 1);
 }
Esempio n. 38
0
        public LSL_Rotation osNpcGetRot(LSL_Key npc)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.High, "osNpcGetRot", m_host, "OSSL", m_itemID))
                return new LSL_Rotation(0, 0, 0, 0);

            IBotManager manager = World.RequestModuleInterface<IBotManager>();
            if (manager != null)
            {
                UUID npcId;
                if (UUID.TryParse (npc.m_string, out npcId))
                {
                    var rot = manager.GetRotation (npcId, m_host.OwnerID);
                    var NpcRot = new LSL_Rotation ();
                    NpcRot.x = rot.X;
                    NpcRot.y = rot.Y;
                    NpcRot.z = rot.Z;
                    NpcRot.s = 1;

                    return NpcRot;
                }
            }

            return new LSL_Rotation( 0,0,0,0);
        }
Esempio n. 39
0
        // Xantor 29/apr/2008
        // converts a Quaternion to X,Y,Z axis rotations
        public LSL_Vector llRot2Axis(LSL_Rotation rot)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
                return new LSL_Vector();

            double x, y, z;

            if (rot.s > 1) // normalization needed
            {
                double length = Math.Sqrt(rot.x * rot.x + rot.y * rot.y +
                                          rot.z * rot.z + rot.s * rot.s);
                if (FloatAlmostEqual(length, 0))
                    return new LSL_Vector(0, 0, 0);
                length = 1 / length;
                rot.x *= length;
                rot.y *= length;
                rot.z *= length;
                rot.s *= length;
            }

            // double angle = 2 * Math.Acos(rot.s);
            double s = Math.Sqrt(1 - rot.s * rot.s);
            if (s < 0.001)
            {
                x = 1;
                y = z = 0;
            }
            else
            {
                s = 1 / s;
                x = rot.x * s; // normalise axis
                y = rot.y * s;
                z = rot.z * s;
            }

            return new LSL_Vector(x, y, z);
        }
Esempio n. 40
0
        public void llSitTarget(LSL_Vector offset, LSL_Rotation rot)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) return;

            // LSL quaternions can normalize to 0, normal Quaternions can't.
            if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
                rot.z = 1; // ZERO_ROTATION = 0,0,0,1

            m_host.SitTargetPosition = new Vector3((float)offset.x, (float)offset.y, (float)offset.z);
            m_host.SitTargetOrientation = Rot2Quaternion(rot);
        }
Esempio n. 41
0
        // Returns the angle of a quaternion (see llRot2Axis for the axis)
        public LSL_Float llRot2Angle(LSL_Rotation rot)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
                return new LSL_Float();


            if (rot.s > 1) // normalization needed
            {
                double length = Math.Sqrt(rot.x * rot.x + rot.y * rot.y +
                                          rot.z * rot.z + rot.s * rot.s);

                if (FloatAlmostEqual(length, 0))
                    return 0;
                //                rot.x /= length;
                //                rot.y /= length;
                //                rot.z /= length;
                rot.s /= length;
            }

            double angle = 2 * Math.Acos(rot.s);

            return angle;
        }
Esempio n. 42
0
        public LSL_Float llAngleBetween(LSL_Rotation a, LSL_Rotation b)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
                return new LSL_Float();


            double aa = (a.x * a.x + a.y * a.y + a.z * a.z + a.s * a.s);
            double bb = (b.x * b.x + b.y * b.y + b.z * b.z + b.s * b.s);
            double aa_bb = aa * bb;
            if (FloatAlmostEqual(aa_bb, 0))
                return 0.0;
            double ab = (a.x * b.x + a.y * b.y + a.z * b.z + a.s * b.s);
            double quotient = (ab * ab) / aa_bb;
            if (quotient >= 1.0) return 0.0;
            return Math.Acos(2 * quotient - 1);
        }
Esempio n. 43
0
 // convert a LSL_Rotation to a Quaternion
 protected Quaternion Rot2Quaternion(LSL_Rotation r)
 {
     Quaternion q = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
     q.Normalize();
     return q;
 }
Esempio n. 44
0
 public LSL_Rotation aaGetTextColor()
 {
     if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "aaGetTextColor", m_host, "AA", m_itemID))
         return new LSL_Rotation();
     LSL_Rotation v = new LSL_Rotation(m_host.Color.R, m_host.Color.G, m_host.Color.B, m_host.Color.A);
     return v;
 }
Esempio n. 45
0
        //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke

        // Old implementation of llRot2Euler. Normalization not required as Atan2 function will
        // only return values >= -PI (-180 degrees) and <= PI (180 degrees).

        public LSL_Vector llRot2Euler(LSL_Rotation r)
        {
            //This implementation is from http://lslwiki.net/lslwiki/wakka.php?wakka=LibraryRotationFunctions. ckrinke
            LSL_Rotation t = new LSL_Rotation(r.x * r.x, r.y * r.y, r.z * r.z, r.s * r.s);
            double m = (t.x + t.y + t.z + t.s);
            if (FloatAlmostEqual(m, 0))
                return new LSL_Vector();
            
            double n = 2 * (r.y * r.s + r.x * r.z);
            double p = m * m - n * n;
            if (p > 0)
                return new LSL_Vector(Math.Atan2(2.0 * (r.x * r.s - r.y * r.z), (-t.x - t.y + t.z + t.s)),
                                      Math.Atan2(n, Math.Sqrt(p)),
                                      Math.Atan2(2.0 * (r.z * r.s - r.x * r.y), (t.x - t.y - t.z + t.s)));
            if (n > 0)
                return new LSL_Vector(0.0, Math.PI * 0.5, Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z));
            return new LSL_Vector(0.0, -Math.PI * 0.5, Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z));
        }
Esempio n. 46
0
        /// <summary>
        ///     This isn't really an LSL function, just a way to merge llRezAtRoot and llRezObject into one
        /// </summary>
        /// <param name="inventory"></param>
        /// <param name="pos"></param>
        /// <param name="vel"></param>
        /// <param name="rot"></param>
        /// <param name="param"></param>
        /// <param name="isRezAtRoot"></param>
        /// <param name="doRecoil"></param>
        /// <param name="setDieAtEdge"></param>
        /// <param name="checkPos"></param>
        /// <returns></returns>
        public DateTime llRezPrim(string inventory, LSL_Vector pos, LSL_Vector vel,
                                  LSL_Rotation rot, int param, bool isRezAtRoot, bool doRecoil,
                                  bool setDieAtEdge, bool checkPos)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.Low, "llRezPrim", m_host, "LSL", m_itemID))
            {
                return(DateTime.Now);
            }

            if (m_ScriptEngine.Config.GetBoolean("AllowllRezObject", true))
            {
                if (double.IsNaN(rot.x) || double.IsNaN(rot.y) || double.IsNaN(rot.z) || double.IsNaN(rot.s))
                {
                    return(DateTime.Now);
                }
                if (checkPos)
                {
                    float dist = (float)llVecDist(llGetPos(), pos);

                    if (dist > m_ScriptDistanceFactor * 10.0f)
                    {
                        return(DateTime.Now);
                    }
                }

                TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone();

                foreach (KeyValuePair <UUID, TaskInventoryItem> inv in partInventory)
                {
                    if (inv.Value.Name == inventory)
                    {
                        // make sure we're an object.
                        if (inv.Value.InvType != (int)InventoryType.Object)
                        {
                            llSay(0, "Unable to create requested object. Object is missing from database.");
                            return(DateTime.Now);
                        }

                        Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
                        Vector3 llvel = new Vector3((float)vel.x, (float)vel.y, (float)vel.z);

                        ISceneEntity new_group = RezObject(m_host, inv.Value, llpos, Rot2Quaternion(rot), llvel, param,
                                                           m_host.UUID, isRezAtRoot);
                        if (new_group == null)
                        {
                            continue;
                        }

                        new_group.OnFinishedPhysicalRepresentationBuilding +=
                            delegate() {
                            //Do this after the physics engine has built the prim
                            float groupmass = new_group.GetMass();
                            //Recoil to the av
                            if (m_host.IsAttachment &&
                                doRecoil &&
                                (new_group.RootChild.Flags & PrimFlags.Physics) == PrimFlags.Physics)
                            {
                                IScenePresence SP = m_host.ParentEntity.Scene.GetScenePresence(m_host.OwnerID);
                                if (SP != null)
                                {
                                    //Push the av backwards (For every action, there is an equal, but opposite reaction)
                                    Vector3 impulse = llvel * groupmass;
                                    impulse.X = impulse.X <1 ? impulse.X : impulse.X> -1 ? impulse.X : -1;
                                    impulse.Y = impulse.Y <1 ? impulse.Y : impulse.Y> -1 ? impulse.Y : -1;
                                    impulse.Z = impulse.Z <1 ? impulse.Z : impulse.Z> -1 ? impulse.Z : -1;
                                    SP.PushForce(impulse);
                                }
                            }
                        };

                        // If there was an unknown error.
                        if (new_group.RootChild == null)
                        {
                            continue;
                        }

                        // objects rezzed with this method are die_at_edge by default.
                        if (setDieAtEdge)
                        {
                            new_group.RootChild.SetDieAtEdge(true);
                        }

                        // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
                        return(PScriptSleep(m_sleepMsOnRezAtRoot));
                    }
                }

                llSay(0, "Could not find object " + inventory);
            }
            return(DateTime.Now);
        }
Esempio n. 47
0
        public void llSetVehicleRotationParam(int param, LSL_Rotation rot)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) 
                return;

            if (m_host.ParentEntity != null)
            {
                if (!m_host.ParentEntity.IsDeleted)
                {
                    m_host.ParentEntity.RootChild.SetVehicleRotationParam(param,Rot2Quaternion(rot));
                }
            }
        }
Esempio n. 48
0
        public void llRotLookAt(LSL_Rotation target, double strength, double damping)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
                return;

            Quaternion rot = new Quaternion((float)target.x, (float)target.y, (float)target.z, (float)target.s);
            m_host.RotLookAt(rot, (float)strength, (float)damping);
        }
Esempio n. 49
0
        public void osDropAttachmentAt(LSL_Vector pos, LSL_Rotation rot)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.Moderate, "osDropAttachmentAt", m_host, "OSSL", m_itemID)) return;

            DropAttachmentAt(true, pos, rot);
        }
Esempio n. 50
0
        public void botSetRot(LSL_Key npc, LSL_Rotation rotation)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.Moderate, "botStandUp", m_host, "bot", m_itemID)) return;
            IScenePresence sp = World.GetScenePresence(UUID.Parse(npc));
            if (sp == null)
                return;
            UUID npcId;
            if (!UUID.TryParse(npc.m_string, out npcId))
                return;

            if (sp != null)
                sp.Rotation = rotation.ToQuaternion();
        }
Esempio n. 51
0
        // 04122016 Fly-Man-
        // This function is unknown on the SL Wiki
        public void llLinkRotLookAt(LSL_Integer link, LSL_Rotation target, double strength, double damping)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
                return;

            Quaternion rot = new Quaternion((float)target.x, (float)target.y, (float)target.z, (float)target.s);
            List<ISceneChildEntity> parts = GetLinkParts(link);

            foreach (ISceneChildEntity part in parts)
                part.RotLookAt(rot, (float)strength, (float)damping);
        }