aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs180
1 files changed, 141 insertions, 39 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 443e7a5..67dee02 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -126,11 +126,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
126 m_TransferModule = 126 m_TransferModule =
127 m_ScriptEngine.World.RequestModuleInterface<IMessageTransferModule>(); 127 m_ScriptEngine.World.RequestModuleInterface<IMessageTransferModule>();
128 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>(); 128 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>();
129 if (m_UrlModule != null)
130 {
131 m_ScriptEngine.OnScriptRemoved += m_UrlModule.ScriptRemoved;
132 m_ScriptEngine.OnObjectRemoved += m_UrlModule.ObjectRemoved;
133 }
134 129
135 AsyncCommands = new AsyncCommandManager(ScriptEngine); 130 AsyncCommands = new AsyncCommandManager(ScriptEngine);
136 } 131 }
@@ -468,26 +463,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
468 463
469 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 464 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
470 465
471 // Old implementation of llRot2Euler. Normalization not required as Atan2 function will 466 /// <summary>
472 // only return values >= -PI (-180 degrees) and <= PI (180 degrees). 467 /// Convert an LSL rotation to a Euler vector.
473 468 /// </summary>
469 /// <remarks>
470 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
471 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
472 /// </remarks>
473 /// <param name="r"></param>
474 /// <returns></returns>
474 public LSL_Vector llRot2Euler(LSL_Rotation r) 475 public LSL_Vector llRot2Euler(LSL_Rotation r)
475 { 476 {
476 m_host.AddScriptLPS(1); 477 m_host.AddScriptLPS(1);
477 //This implementation is from http://lslwiki.net/lslwiki/wakka.php?wakka=LibraryRotationFunctions. ckrinke 478
478 LSL_Rotation t = new LSL_Rotation(r.x * r.x, r.y * r.y, r.z * r.z, r.s * r.s); 479 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r.
479 double m = (t.x + t.y + t.z + t.s); 480 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later.
480 if (m == 0) return new LSL_Vector(); 481 if (m == 0.0) return new LSL_Vector();
481 double n = 2 * (r.y * r.s + r.x * r.z); 482 double x = Math.Atan2(-v.y, v.z);
482 double p = m * m - n * n; 483 double sin = v.x / m;
483 if (p > 0) 484 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities.
484 return new LSL_Vector(Math.Atan2(2.0 * (r.x * r.s - r.y * r.z), (-t.x - t.y + t.z + t.s)), 485 double y = Math.Asin(sin);
485 Math.Atan2(n, Math.Sqrt(p)), 486 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation
486 Math.Atan2(2.0 * (r.z * r.s - r.x * r.y), (t.x - t.y - t.z + t.s))); 487 v = new LSL_Vector(1.0, 0.0, 0.0) * ((r * new LSL_Rotation(Math.Sin(-x / 2.0), 0.0, 0.0, Math.Cos(-x / 2.0))) * new LSL_Rotation(0.0, Math.Sin(-y / 2.0), 0.0, Math.Cos(-y / 2.0)));
487 else if (n > 0) 488 double z = Math.Atan2(v.y, v.x);
488 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)); 489
489 else 490 return new LSL_Vector(x, y, z);
490 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));
491 } 491 }
492 492
493 /* From wiki: 493 /* From wiki:
@@ -2856,11 +2856,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2856 // we need to convert from a vector describing 2856 // we need to convert from a vector describing
2857 // the angles of rotation in radians into rotation value 2857 // the angles of rotation in radians into rotation value
2858 2858
2859 LSL_Types.Quaternion rot = llEuler2Rot(angle); 2859 LSL_Rotation rot = llEuler2Rot(angle);
2860 Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s); 2860
2861 m_host.startLookAt(rotation, (float)damping, (float)strength); 2861 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2862 // Orient the object to the angle calculated 2862 // set the rotation of the object, copy that behavior
2863 //llSetRot(rot); 2863 if (strength == 0 || m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2864 {
2865 llSetRot(rot);
2866 }
2867 else
2868 {
2869 m_host.StartLookAt(Rot2Quaternion(rot), (float)strength, (float)damping);
2870 }
2864 } 2871 }
2865 2872
2866 public void llStopLookAt() 2873 public void llStopLookAt()
@@ -3236,8 +3243,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3236 public void llRotLookAt(LSL_Rotation target, double strength, double damping) 3243 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3237 { 3244 {
3238 m_host.AddScriptLPS(1); 3245 m_host.AddScriptLPS(1);
3239 Quaternion rot = new Quaternion((float)target.x, (float)target.y, (float)target.z, (float)target.s); 3246
3240 m_host.RotLookAt(rot, (float)strength, (float)damping); 3247 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
3248 // set the rotation of the object, copy that behavior
3249 if (strength == 0 || m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
3250 {
3251 llSetLocalRot(target);
3252 }
3253 else
3254 {
3255 m_host.RotLookAt(Rot2Quaternion(target), (float)strength, (float)damping);
3256 }
3241 } 3257 }
3242 3258
3243 public LSL_Integer llStringLength(string str) 3259 public LSL_Integer llStringLength(string str)
@@ -4023,9 +4039,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4023 Vector3 av3 = new Vector3(Util.Clip((float)color.x, 0.0f, 1.0f), 4039 Vector3 av3 = new Vector3(Util.Clip((float)color.x, 0.0f, 1.0f),
4024 Util.Clip((float)color.y, 0.0f, 1.0f), 4040 Util.Clip((float)color.y, 0.0f, 1.0f),
4025 Util.Clip((float)color.z, 0.0f, 1.0f)); 4041 Util.Clip((float)color.z, 0.0f, 1.0f));
4026 m_host.SetText(text, av3, Util.Clip((float)alpha, 0.0f, 1.0f)); 4042 m_host.SetText(text.Length > 254 ? text.Remove(255) : text, av3, Util.Clip((float)alpha, 0.0f, 1.0f));
4027 m_host.ParentGroup.HasGroupChanged = true; 4043 //m_host.ParentGroup.HasGroupChanged = true;
4028 m_host.ParentGroup.ScheduleGroupForFullUpdate(); 4044 //m_host.ParentGroup.ScheduleGroupForFullUpdate();
4029 } 4045 }
4030 4046
4031 public LSL_Float llWater(LSL_Vector offset) 4047 public LSL_Float llWater(LSL_Vector offset)
@@ -4693,15 +4709,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4693 return (double)Math.Asin(val); 4709 return (double)Math.Asin(val);
4694 } 4710 }
4695 4711
4696 // Xantor 30/apr/2008 4712 // jcochran 5/jan/2012
4697 public LSL_Float llAngleBetween(LSL_Rotation a, LSL_Rotation b) 4713 public LSL_Float llAngleBetween(LSL_Rotation a, LSL_Rotation b)
4698 { 4714 {
4699 m_host.AddScriptLPS(1); 4715 m_host.AddScriptLPS(1);
4700 4716
4701 double angle = Math.Acos(a.x * b.x + a.y * b.y + a.z * b.z + a.s * b.s) * 2; 4717 double aa = (a.x * a.x + a.y * a.y + a.z * a.z + a.s * a.s);
4702 if (angle < 0) angle = -angle; 4718 double bb = (b.x * b.x + b.y * b.y + b.z * b.z + b.s * b.s);
4703 if (angle > Math.PI) return (Math.PI * 2 - angle); 4719 double aa_bb = aa * bb;
4704 return angle; 4720 if (aa_bb == 0) return 0.0;
4721 double ab = (a.x * b.x + a.y * b.y + a.z * b.z + a.s * b.s);
4722 double quotient = (ab * ab) / aa_bb;
4723 if (quotient >= 1.0) return 0.0;
4724 return Math.Acos(2 * quotient - 1);
4705 } 4725 }
4706 4726
4707 public LSL_String llGetInventoryKey(string name) 4727 public LSL_String llGetInventoryKey(string name)
@@ -5486,7 +5506,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5486 5506
5487 foreach (GridRegion sri in neighbors) 5507 foreach (GridRegion sri in neighbors)
5488 { 5508 {
5489 if (sri.RegionLocX == neighborX && sri.RegionLocY == neighborY) 5509 if (sri.RegionCoordX == neighborX && sri.RegionCoordY == neighborY)
5490 return 0; 5510 return 0;
5491 } 5511 }
5492 5512
@@ -6583,7 +6603,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6583 } 6603 }
6584 6604
6585 // the rest of the permission checks are done in RezScript, so check the pin there as well 6605 // the rest of the permission checks are done in RezScript, so check the pin there as well
6586 World.RezScript(srcId, m_host, destId, pin, running, start_param); 6606 World.RezScriptFromPrim(srcId, m_host, destId, pin, running, start_param);
6607
6587 // this will cause the delay even if the script pin or permissions were wrong - seems ok 6608 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6588 ScriptSleep(3000); 6609 ScriptSleep(3000);
6589 } 6610 }
@@ -7546,6 +7567,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7546 ScriptSleep(2000); 7567 ScriptSleep(2000);
7547 } 7568 }
7548 7569
7570 public LSL_String llGetParcelMusicURL()
7571 {
7572 m_host.AddScriptLPS(1);
7573
7574 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y);
7575
7576 if (land.LandData.OwnerID != m_host.OwnerID)
7577 return String.Empty;
7578
7579 return land.GetMusicUrl();
7580 }
7581
7549 public LSL_Vector llGetRootPosition() 7582 public LSL_Vector llGetRootPosition()
7550 { 7583 {
7551 m_host.AddScriptLPS(1); 7584 m_host.AddScriptLPS(1);
@@ -10613,6 +10646,75 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10613 return list; 10646 return list;
10614 } 10647 }
10615 10648
10649 public LSL_Integer llManageEstateAccess(int action, string avatar)
10650 {
10651 m_host.AddScriptLPS(1);
10652 EstateSettings estate = World.RegionInfo.EstateSettings;
10653 bool isAccount = false;
10654 bool isGroup = false;
10655
10656 if (!estate.IsEstateOwner(m_host.OwnerID) || !estate.IsEstateManager(m_host.OwnerID))
10657 return 0;
10658
10659 UUID id = new UUID();
10660 if (!UUID.TryParse(avatar, out id))
10661 return 0;
10662
10663 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, id);
10664 isAccount = account != null ? true : false;
10665 if (!isAccount)
10666 {
10667 IGroupsModule groups = World.RequestModuleInterface<IGroupsModule>();
10668 if (groups != null)
10669 {
10670 GroupRecord group = groups.GetGroupRecord(id);
10671 isGroup = group != null ? true : false;
10672 if (!isGroup)
10673 return 0;
10674 }
10675 else
10676 return 0;
10677 }
10678
10679 switch (action)
10680 {
10681 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
10682 if (!isAccount) return 0;
10683 if (estate.HasAccess(id)) return 1;
10684 if (estate.IsBanned(id))
10685 estate.RemoveBan(id);
10686 estate.AddEstateUser(id);
10687 break;
10688 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_REMOVE:
10689 if (!isAccount || !estate.HasAccess(id)) return 0;
10690 estate.RemoveEstateUser(id);
10691 break;
10692 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_GROUP_ADD:
10693 if (!isGroup) return 0;
10694 if (estate.GroupAccess(id)) return 1;
10695 estate.AddEstateGroup(id);
10696 break;
10697 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_GROUP_REMOVE:
10698 if (!isGroup || !estate.GroupAccess(id)) return 0;
10699 estate.RemoveEstateGroup(id);
10700 break;
10701 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
10702 if (!isAccount) return 0;
10703 if (estate.IsBanned(id)) return 1;
10704 EstateBan ban = new EstateBan();
10705 ban.EstateID = estate.EstateID;
10706 ban.BannedUserID = id;
10707 estate.AddBan(ban);
10708 break;
10709 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
10710 if (!isAccount || !estate.IsBanned(id)) return 0;
10711 estate.RemoveBan(id);
10712 break;
10713 default: return 0;
10714 }
10715 return 1;
10716 }
10717
10616 #region Not Implemented 10718 #region Not Implemented
10617 // 10719 //
10618 // Listing the unimplemented lsl functions here, please move 10720 // Listing the unimplemented lsl functions here, please move