From 901acddbdd38c441426f43cbfa78c422a19cec17 Mon Sep 17 00:00:00 2001
From: Dahlia Trimble
Date: Wed, 15 Oct 2008 04:42:28 +0000
Subject: Thanks to M. Igarashi and nlin for a patch that implements
 llGetCameraRot().

---
 OpenSim/Framework/Util.cs                          | 54 ++++++++++++++++++++++
 OpenSim/Region/Environment/Scenes/ScenePresence.cs |  5 ++
 .../Shared/Api/Implementation/LSL_Api.cs           | 16 ++++++-
 3 files changed, 74 insertions(+), 1 deletion(-)

(limited to 'OpenSim')

diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs
index 57c1601..28c818a 100644
--- a/OpenSim/Framework/Util.cs
+++ b/OpenSim/Framework/Util.cs
@@ -116,6 +116,60 @@ namespace OpenSim.Framework
 
         # endregion
 
+        public static Quaternion Axes2Rot(Vector3 fwd, Vector3 left, Vector3 up)
+        {
+            float s;
+            float tr = (float) (fwd.X + left.Y + up.Z + 1.0);
+
+            if (tr >= 1.0)
+            {
+                s = (float) (0.5 / Math.Sqrt(tr));
+                return new Quaternion(
+                        (left.Z - up.Y) * s,
+                        (up.X - fwd.Z) * s,
+                        (fwd.Y - left.X) * s,
+                        (float) 0.25 / s);
+            }
+            else
+            {
+                float max = (left.Y > up.Z) ? left.Y : up.Z;
+
+                if (max < fwd.X)
+                {
+                    s = (float) (Math.Sqrt(fwd.X - (left.Y + up.Z) + 1.0));
+                    float x = (float) (s * 0.5);
+                    s = (float) (0.5 / s);
+                    return new Quaternion(
+                            x,
+                            (fwd.Y + left.X) * s,
+                            (up.X + fwd.Z) * s,
+                            (left.Z - up.Y) * s);
+                }
+                else if (max == left.Y)
+                {
+                    s = (float) (Math.Sqrt(left.Y - (up.Z + fwd.X) + 1.0));
+                    float y = (float) (s * 0.5);
+                    s = (float) (0.5 / s);
+                    return new Quaternion(
+                            (fwd.Y + left.X) * s,
+                            y,
+                            (left.Z + up.Y) * s,
+                            (up.X - fwd.Z) * s);
+                }
+                else
+                {
+                    s = (float) (Math.Sqrt(up.Z - (fwd.X + left.Y) + 1.0));
+                    float z = (float) (s * 0.5);
+                    s = (float) (0.5 / s);
+                    return new Quaternion(
+                            (up.X + fwd.Z) * s,
+                            (left.Z + up.Y) * s,
+                            z,
+                            (fwd.Y - left.X) * s);
+                }
+            }
+        }
+
         public static Random RandomClass
         {
             get { return randomClass; }
diff --git a/OpenSim/Region/Environment/Scenes/ScenePresence.cs b/OpenSim/Region/Environment/Scenes/ScenePresence.cs
index d87a7e2..6f5372a 100644
--- a/OpenSim/Region/Environment/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Environment/Scenes/ScenePresence.cs
@@ -252,6 +252,11 @@ namespace OpenSim.Region.Environment.Scenes
             get { return m_CameraCenter; }
         }
 
+        public Quaternion CameraRotation
+        {
+            get { return Util.Axes2Rot(m_CameraAtAxis, m_CameraLeftAxis, m_CameraUpAxis); }
+        }
+
         public Vector3 Lookat
         {
             get
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 7993d95..826324f 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -7531,7 +7531,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
         public LSL_Rotation llGetCameraRot()
         {
             m_host.AddScriptLPS(1);
-            NotImplemented("llGetCameraRot");
+            UUID invItemID=InventorySelf();
+            if (invItemID == UUID.Zero)
+                return new LSL_Rotation();
+            if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
+               return new LSL_Rotation();
+            if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
+            {
+                ShoutError("No permissions to track the camera");
+                return new LSL_Rotation();
+            }
+            ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
+            if (presence != null)
+            {
+                return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W);
+            }
             return new LSL_Rotation();
         }
 
-- 
cgit v1.1