aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs48
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs87
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs27
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs107
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/OutgoingPacket.cs4
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs27
-rw-r--r--OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs10
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs39
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs32
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs179
-rw-r--r--OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsActor.cs20
-rw-r--r--OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETCharacter.cs6
-rw-r--r--OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETPrim.cs5
-rw-r--r--OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs20
-rw-r--r--OpenSim/Region/Physics/Manager/PhysicsActor.cs13
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODECharacter.cs22
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs20
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODEPrim.cs93
-rw-r--r--OpenSim/Region/Physics/POSPlugin/POSCharacter.cs21
-rw-r--r--OpenSim/Region/Physics/POSPlugin/POSPrim.cs20
-rw-r--r--OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs44
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs18
23 files changed, 706 insertions, 160 deletions
diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs
index 3149eaa..3bc557d 100644
--- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs
+++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs
@@ -123,6 +123,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
123 availableMethods["admin_region_query"] = XmlRpcRegionQueryMethod; 123 availableMethods["admin_region_query"] = XmlRpcRegionQueryMethod;
124 availableMethods["admin_shutdown"] = XmlRpcShutdownMethod; 124 availableMethods["admin_shutdown"] = XmlRpcShutdownMethod;
125 availableMethods["admin_broadcast"] = XmlRpcAlertMethod; 125 availableMethods["admin_broadcast"] = XmlRpcAlertMethod;
126 availableMethods["admin_dialog"] = XmlRpcDialogMethod;
126 availableMethods["admin_restart"] = XmlRpcRestartMethod; 127 availableMethods["admin_restart"] = XmlRpcRestartMethod;
127 availableMethods["admin_load_heightmap"] = XmlRpcLoadHeightmapMethod; 128 availableMethods["admin_load_heightmap"] = XmlRpcLoadHeightmapMethod;
128 // User management 129 // User management
@@ -277,6 +278,53 @@ namespace OpenSim.ApplicationPlugins.RemoteController
277 m_log.Info("[RADMIN]: Alert request complete"); 278 m_log.Info("[RADMIN]: Alert request complete");
278 return response; 279 return response;
279 } 280 }
281 public XmlRpcResponse XmlRpcDialogMethod(XmlRpcRequest request, IPEndPoint remoteClient)
282 {
283 XmlRpcResponse response = new XmlRpcResponse();
284 Hashtable responseData = new Hashtable();
285
286 m_log.Info("[RADMIN]: Dialog request started");
287
288 try
289 {
290 Hashtable requestData = (Hashtable)request.Params[0];
291
292 checkStringParameters(request, new string[] { "password", "from", "message" });
293
294 if (m_requiredPassword != String.Empty &&
295 (!requestData.Contains("password") || (string)requestData["password"] != m_requiredPassword))
296 throw new Exception("wrong password");
297
298 string message = (string)requestData["message"];
299 string fromuuid = (string)requestData["from"];
300 m_log.InfoFormat("[RADMIN]: Broadcasting: {0}", message);
301
302 responseData["accepted"] = true;
303 responseData["success"] = true;
304 response.Value = responseData;
305
306 m_app.SceneManager.ForEachScene(
307 delegate(Scene scene)
308 {
309 IDialogModule dialogModule = scene.RequestModuleInterface<IDialogModule>();
310 if (dialogModule != null)
311 dialogModule.SendNotificationToUsersInRegion(UUID.Zero, fromuuid, message);
312 });
313 }
314 catch (Exception e)
315 {
316 m_log.ErrorFormat("[RADMIN]: Broadcasting: failed: {0}", e.Message);
317 m_log.DebugFormat("[RADMIN]: Broadcasting: failed: {0}", e.ToString());
318
319 responseData["accepted"] = false;
320 responseData["success"] = false;
321 responseData["error"] = e.Message;
322 response.Value = responseData;
323 }
324
325 m_log.Info("[RADMIN]: Alert request complete");
326 return response;
327 }
280 328
281 public XmlRpcResponse XmlRpcLoadHeightmapMethod(XmlRpcRequest request, IPEndPoint remoteClient) 329 public XmlRpcResponse XmlRpcLoadHeightmapMethod(XmlRpcRequest request, IPEndPoint remoteClient)
282 { 330 {
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 07466e2..a8206dc 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -785,6 +785,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
785 public virtual void SendLayerData(float[] map) 785 public virtual void SendLayerData(float[] map)
786 { 786 {
787 Util.FireAndForget(DoSendLayerData, map); 787 Util.FireAndForget(DoSendLayerData, map);
788
789 // Send it sync, and async. It's not that much data
790 // and it improves user experience just so much!
791 DoSendLayerData(map);
788 } 792 }
789 793
790 /// <summary> 794 /// <summary>
@@ -797,16 +801,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
797 801
798 try 802 try
799 { 803 {
800 //for (int y = 0; y < 16; y++) 804 for (int y = 0; y < 16; y++)
801 //{ 805 {
802 // for (int x = 0; x < 16; x++) 806 for (int x = 0; x < 16; x+=4)
803 // { 807 {
804 // SendLayerData(x, y, map); 808 SendLayerPacket(x, y, map);
805 // } 809 }
806 //} 810 }
807
808 // Send LayerData in a spiral pattern. Fun!
809 SendLayerTopRight(map, 0, 0, 15, 15);
810 } 811 }
811 catch (Exception e) 812 catch (Exception e)
812 { 813 {
@@ -814,51 +815,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
814 } 815 }
815 } 816 }
816 817
817 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
818 {
819 // Row
820 for (int i = x1; i <= x2; i++)
821 SendLayerData(i, y1, map);
822
823 // Column
824 for (int j = y1 + 1; j <= y2; j++)
825 SendLayerData(x2, j, map);
826
827 if (x2 - x1 > 0)
828 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
829 }
830
831 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
832 {
833 // Row in reverse
834 for (int i = x2; i >= x1; i--)
835 SendLayerData(i, y2, map);
836
837 // Column in reverse
838 for (int j = y2 - 1; j >= y1; j--)
839 SendLayerData(x1, j, map);
840
841 if (x2 - x1 > 0)
842 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
843 }
844
845 /// <summary> 818 /// <summary>
846 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 819 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
847 /// </summary> 820 /// </summary>
848 /// <param name="map">heightmap</param> 821 /// <param name="map">heightmap</param>
849 /// <param name="px">X coordinate for patches 0..12</param> 822 /// <param name="px">X coordinate for patches 0..12</param>
850 /// <param name="py">Y coordinate for patches 0..15</param> 823 /// <param name="py">Y coordinate for patches 0..15</param>
851 // private void SendLayerPacket(float[] map, int y, int x) 824 private void SendLayerPacket(int x, int y, float[] map)
852 // { 825 {
853 // int[] patches = new int[4]; 826 int[] patches = new int[4];
854 // patches[0] = x + 0 + y * 16; 827 patches[0] = x + 0 + y * 16;
855 // patches[1] = x + 1 + y * 16; 828 patches[1] = x + 1 + y * 16;
856 // patches[2] = x + 2 + y * 16; 829 patches[2] = x + 2 + y * 16;
857 // patches[3] = x + 3 + y * 16; 830 patches[3] = x + 3 + y * 16;
858 831
859 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 832 float[] heightmap = (map.Length == 65536) ?
860 // OutPacket(layerpack, ThrottleOutPacketType.Land); 833 map :
861 // } 834 LLHeightFieldMoronize(map);
835
836 try
837 {
838 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
839 OutPacket(layerpack, ThrottleOutPacketType.Land);
840 }
841 catch
842 {
843 for (int px = x ; px < x + 4 ; px++)
844 SendLayerData(px, y, map);
845 }
846 }
862 847
863 /// <summary> 848 /// <summary>
864 /// Sends a specified patch to a client 849 /// Sends a specified patch to a client
@@ -3136,7 +3121,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3136 3121
3137 objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; 3122 objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
3138 objupdate.ObjectData[0] = CreateAvatarUpdateBlock(data); 3123 objupdate.ObjectData[0] = CreateAvatarUpdateBlock(data);
3139
3140 OutPacket(objupdate, ThrottleOutPacketType.Task); 3124 OutPacket(objupdate, ThrottleOutPacketType.Task);
3141 } 3125 }
3142 3126
@@ -3187,8 +3171,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3187 terse.ObjectData[i] = m_avatarTerseUpdates.Dequeue(); 3171 terse.ObjectData[i] = m_avatarTerseUpdates.Dequeue();
3188 } 3172 }
3189 3173
3190 // HACK: Using the task category until the tiered reprioritization code is in 3174 OutPacket(terse, ThrottleOutPacketType.State);
3191 OutPacket(terse, ThrottleOutPacketType.Task);
3192 } 3175 }
3193 3176
3194 public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) 3177 public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
index c773c05..98bb4f7 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
@@ -399,6 +399,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
399 #region Queue or Send 399 #region Queue or Send
400 400
401 OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category); 401 OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category);
402 outgoingPacket.Type = type;
402 403
403 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket)) 404 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket))
404 SendPacketFinal(outgoingPacket); 405 SendPacketFinal(outgoingPacket);
@@ -510,6 +511,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
510 byte flags = buffer.Data[0]; 511 byte flags = buffer.Data[0];
511 bool isResend = (flags & Helpers.MSG_RESENT) != 0; 512 bool isResend = (flags & Helpers.MSG_RESENT) != 0;
512 bool isReliable = (flags & Helpers.MSG_RELIABLE) != 0; 513 bool isReliable = (flags & Helpers.MSG_RELIABLE) != 0;
514 bool sendSynchronous = false;
513 LLUDPClient udpClient = outgoingPacket.Client; 515 LLUDPClient udpClient = outgoingPacket.Client;
514 516
515 if (!udpClient.IsConnected) 517 if (!udpClient.IsConnected)
@@ -565,9 +567,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
565 if (isReliable) 567 if (isReliable)
566 Interlocked.Add(ref udpClient.UnackedBytes, outgoingPacket.Buffer.DataLength); 568 Interlocked.Add(ref udpClient.UnackedBytes, outgoingPacket.Buffer.DataLength);
567 569
568 // Put the UDP payload on the wire 570 //Some packet types need to be sent synchonously.
569 AsyncBeginSend(buffer); 571 //Sorry, i know it's not optimal, but until the LL client
572 //manages packets correctly and re-orders them as required, this is necessary.
570 573
574
575 // Put the UDP payload on the wire
576 if (outgoingPacket.Type == PacketType.ImprovedTerseObjectUpdate)
577 {
578 SyncBeginPrioritySend(buffer, 2); // highest priority
579 }
580 else if (outgoingPacket.Type == PacketType.ObjectUpdate
581 || outgoingPacket.Type == PacketType.LayerData)
582 {
583 SyncBeginPrioritySend(buffer, 1); // medium priority
584 }
585 else
586 {
587 SyncBeginPrioritySend(buffer, 0); // normal priority
588 }
589
590 //AsyncBeginSend(buffer);
591
571 // Keep track of when this packet was sent out (right now) 592 // Keep track of when this packet was sent out (right now)
572 outgoingPacket.TickCount = Environment.TickCount & Int32.MaxValue; 593 outgoingPacket.TickCount = Environment.TickCount & Int32.MaxValue;
573 } 594 }
@@ -842,7 +863,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
842 863
843 Buffer.BlockCopy(packetData, 0, buffer.Data, 0, length); 864 Buffer.BlockCopy(packetData, 0, buffer.Data, 0, length);
844 865
845 AsyncBeginSend(buffer); 866 SyncBeginPrioritySend(buffer, 1); //Setting this to a medium priority should help minimise resends
846 } 867 }
847 868
848 private bool IsClientAuthorized(UseCircuitCodePacket useCircuitCode, out AuthenticateResponse sessionInfo) 869 private bool IsClientAuthorized(UseCircuitCodePacket useCircuitCode, out AuthenticateResponse sessionInfo)
diff --git a/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs
index d2779ba..de2cd24 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs
@@ -29,6 +29,7 @@ using System;
29using System.Net; 29using System.Net;
30using System.Net.Sockets; 30using System.Net.Sockets;
31using System.Threading; 31using System.Threading;
32using System.Collections.Generic;
32using log4net; 33using log4net;
33 34
34namespace OpenMetaverse 35namespace OpenMetaverse
@@ -52,12 +53,30 @@ namespace OpenMetaverse
52 /// <summary>Local IP address to bind to in server mode</summary> 53 /// <summary>Local IP address to bind to in server mode</summary>
53 protected IPAddress m_localBindAddress; 54 protected IPAddress m_localBindAddress;
54 55
56 /// <summary>
57 /// Standard queue for our outgoing SyncBeginPrioritySend
58 /// </summary>
59 private List<UDPPacketBuffer> m_standardQueue = new List<UDPPacketBuffer>();
60
61 /// <summary>
62 /// Medium priority queue for our outgoing SyncBeginPrioritySend
63 /// </summary>
64 private List<UDPPacketBuffer> m_mediumPriorityQueue = new List<UDPPacketBuffer>();
65
66 /// <summary>
67 /// Prioritised queue for our outgoing SyncBeginPrioritySend
68 /// </summary>
69 private List<UDPPacketBuffer> m_priorityQueue = new List<UDPPacketBuffer>();
70
55 /// <summary>UDP socket, used in either client or server mode</summary> 71 /// <summary>UDP socket, used in either client or server mode</summary>
56 private Socket m_udpSocket; 72 private Socket m_udpSocket;
57 73
58 /// <summary>Flag to process packets asynchronously or synchronously</summary> 74 /// <summary>Flag to process packets asynchronously or synchronously</summary>
59 private bool m_asyncPacketHandling; 75 private bool m_asyncPacketHandling;
60 76
77 /// <summary>Are we currently sending data asynchronously?</summary>
78 private volatile bool m_sendingData = false;
79
61 /// <summary>The all important shutdown flag</summary> 80 /// <summary>The all important shutdown flag</summary>
62 private volatile bool m_shutdownFlag = true; 81 private volatile bool m_shutdownFlag = true;
63 82
@@ -246,7 +265,51 @@ namespace OpenMetaverse
246 } 265 }
247 } 266 }
248 267
249 public void AsyncBeginSend(UDPPacketBuffer buf) 268 public void SyncBeginPrioritySend(UDPPacketBuffer buf, int Priority)
269 {
270 if (!m_shutdownFlag)
271 {
272 if (!m_sendingData)
273 {
274 m_sendingData = true;
275 try
276 {
277 AsyncBeginSend(buf);
278 }
279 catch (SocketException) { }
280 catch (ObjectDisposedException) { }
281 }
282 else
283 {
284 if (Priority == 2)
285 {
286 lock (m_priorityQueue)
287 {
288 m_priorityQueue.Add(buf);
289 }
290 }
291 else
292 {
293 if (Priority != 0)
294 {
295 lock (m_mediumPriorityQueue)
296 {
297 m_mediumPriorityQueue.Add(buf);
298 }
299 }
300 else
301 {
302 lock (m_standardQueue)
303 {
304 m_standardQueue.Add(buf);
305 }
306 }
307 }
308 }
309 }
310 }
311
312 private void AsyncBeginSend(UDPPacketBuffer buf)
250 { 313 {
251 if (!m_shutdownFlag) 314 if (!m_shutdownFlag)
252 { 315 {
@@ -270,8 +333,48 @@ namespace OpenMetaverse
270 { 333 {
271 try 334 try
272 { 335 {
273// UDPPacketBuffer buf = (UDPPacketBuffer)result.AsyncState;
274 m_udpSocket.EndSendTo(result); 336 m_udpSocket.EndSendTo(result);
337
338 if (m_sendingData)
339 {
340 lock (m_priorityQueue)
341 {
342 if (m_priorityQueue.Count > 0)
343 {
344 UDPPacketBuffer buf = m_priorityQueue[0];
345 m_priorityQueue.RemoveAt(0);
346 AsyncBeginSend(buf);
347 }
348 else
349 {
350 lock (m_mediumPriorityQueue)
351 {
352 if (m_mediumPriorityQueue.Count > 0)
353 {
354 UDPPacketBuffer buf = m_mediumPriorityQueue[0];
355 m_mediumPriorityQueue.RemoveAt(0);
356 AsyncBeginSend(buf);
357 }
358 else
359 {
360 lock (m_standardQueue)
361 {
362 if (m_standardQueue.Count > 0)
363 {
364 UDPPacketBuffer buf = m_standardQueue[0];
365 m_standardQueue.RemoveAt(0);
366 AsyncBeginSend(buf);
367 }
368 else
369 {
370 m_sendingData = false;
371 }
372 }
373 }
374 }
375 }
376 }
377 }
275 } 378 }
276 catch (SocketException) { } 379 catch (SocketException) { }
277 catch (ObjectDisposedException) { } 380 catch (ObjectDisposedException) { }
diff --git a/OpenSim/Region/ClientStack/LindenUDP/OutgoingPacket.cs b/OpenSim/Region/ClientStack/LindenUDP/OutgoingPacket.cs
index 1a1a1cb..7dc42d3 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/OutgoingPacket.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/OutgoingPacket.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using OpenSim.Framework; 29using OpenSim.Framework;
30using OpenMetaverse; 30using OpenMetaverse;
31using OpenMetaverse.Packets;
31 32
32namespace OpenSim.Region.ClientStack.LindenUDP 33namespace OpenSim.Region.ClientStack.LindenUDP
33{ 34{
@@ -52,7 +53,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
52 public int TickCount; 53 public int TickCount;
53 /// <summary>Category this packet belongs to</summary> 54 /// <summary>Category this packet belongs to</summary>
54 public ThrottleOutPacketType Category; 55 public ThrottleOutPacketType Category;
55 56 /// <summary>The type of packet so its delivery method can be determined</summary>
57 public PacketType Type;
56 /// <summary> 58 /// <summary>
57 /// Default constructor 59 /// Default constructor
58 /// </summary> 60 /// </summary>
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
index 1614b70..7f9e5af 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
@@ -164,19 +164,22 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
164 List<GridInstantMessage>msglist = SynchronousRestObjectPoster.BeginPostObject<UUID, List<GridInstantMessage>>( 164 List<GridInstantMessage>msglist = SynchronousRestObjectPoster.BeginPostObject<UUID, List<GridInstantMessage>>(
165 "POST", m_RestURL+"/RetrieveMessages/", client.AgentId); 165 "POST", m_RestURL+"/RetrieveMessages/", client.AgentId);
166 166
167 foreach (GridInstantMessage im in msglist) 167 if (msglist != null)
168 { 168 {
169 // client.SendInstantMessage(im); 169 foreach (GridInstantMessage im in msglist)
170 170 {
171 // Send through scene event manager so all modules get a chance 171 // client.SendInstantMessage(im);
172 // to look at this message before it gets delivered. 172
173 // 173 // Send through scene event manager so all modules get a chance
174 // Needed for proper state management for stored group 174 // to look at this message before it gets delivered.
175 // invitations 175 //
176 // 176 // Needed for proper state management for stored group
177 Scene s = FindScene(client.AgentId); 177 // invitations
178 if (s != null) 178 //
179 s.EventManager.TriggerIncomingInstantMessage(im); 179 Scene s = FindScene(client.AgentId);
180 if (s != null)
181 s.EventManager.TriggerIncomingInstantMessage(im);
182 }
180 } 183 }
181 } 184 }
182 185
diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
index 2e4c260..30a95ce 100644
--- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
+++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
@@ -156,8 +156,8 @@ namespace OpenSim.Region.Framework.Scenes.Animation
156 Vector3 left = Vector3.Transform(Vector3.UnitY, rotMatrix); 156 Vector3 left = Vector3.Transform(Vector3.UnitY, rotMatrix);
157 157
158 // Check control flags 158 // Check control flags
159 bool heldForward = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_AT_POS; 159 bool heldForward = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_AT_POS || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS);
160 bool heldBack = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG; 160 bool heldBack = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG);
161 bool heldLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS; 161 bool heldLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS;
162 bool heldRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG; 162 bool heldRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG;
163 //bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT; 163 //bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT;
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index f444e51..4ffa1a2 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -1164,16 +1164,16 @@ namespace OpenSim.Region.Framework.Scenes
1164 // Check if any objects have reached their targets 1164 // Check if any objects have reached their targets
1165 CheckAtTargets(); 1165 CheckAtTargets();
1166 1166
1167 // Update SceneObjectGroups that have scheduled themselves for updates
1168 // Objects queue their updates onto all scene presences
1169 if (m_frame % m_update_objects == 0)
1170 m_sceneGraph.UpdateObjectGroups();
1171
1172 // Run through all ScenePresences looking for updates 1167 // Run through all ScenePresences looking for updates
1173 // Presence updates and queued object updates for each presence are sent to clients 1168 // Presence updates and queued object updates for each presence are sent to clients
1174 if (m_frame % m_update_presences == 0) 1169 if (m_frame % m_update_presences == 0)
1175 m_sceneGraph.UpdatePresences(); 1170 m_sceneGraph.UpdatePresences();
1176 1171
1172 // Update SceneObjectGroups that have scheduled themselves for updates
1173 // Objects queue their updates onto all scene presences
1174 if (m_frame % m_update_objects == 0)
1175 m_sceneGraph.UpdateObjectGroups();
1176
1177 int TempPhysicsMS2 = Environment.TickCount; 1177 int TempPhysicsMS2 = Environment.TickCount;
1178 if ((m_frame % m_update_physics == 0) && m_physics_enabled) 1178 if ((m_frame % m_update_physics == 0) && m_physics_enabled)
1179 m_sceneGraph.UpdatePreparePhysics(); 1179 m_sceneGraph.UpdatePreparePhysics();
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index bcc9b37..ea4f2c7 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -1734,6 +1734,45 @@ namespace OpenSim.Region.Framework.Scenes
1734 } 1734 }
1735 } 1735 }
1736 1736
1737 public void rotLookAt(Quaternion target, float strength, float damping)
1738 {
1739 SceneObjectPart rootpart = m_rootPart;
1740 if (rootpart != null)
1741 {
1742 if (IsAttachment)
1743 {
1744 /*
1745 ScenePresence avatar = m_scene.GetScenePresence(rootpart.AttachedAvatar);
1746 if (avatar != null)
1747 {
1748 Rotate the Av?
1749 } */
1750 }
1751 else
1752 {
1753 if (rootpart.PhysActor != null)
1754 {
1755 rootpart.PhysActor.APIDTarget = new Quaternion(target.X, target.Y, target.Z, target.W);
1756 rootpart.PhysActor.APIDStrength = strength;
1757 rootpart.PhysActor.APIDDamping = damping;
1758 rootpart.PhysActor.APIDActive = true;
1759 }
1760 }
1761 }
1762 }
1763 public void stopLookAt()
1764 {
1765 SceneObjectPart rootpart = m_rootPart;
1766 if (rootpart != null)
1767 {
1768 if (rootpart.PhysActor != null)
1769 {
1770 rootpart.PhysActor.APIDActive = false;
1771 }
1772 }
1773
1774 }
1775
1737 /// <summary> 1776 /// <summary>
1738 /// Uses a PID to attempt to clamp the object on the Z axis at the given height over tau seconds. 1777 /// Uses a PID to attempt to clamp the object on the Z axis at the given height over tau seconds.
1739 /// </summary> 1778 /// </summary>
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 6f1b458..cdec135 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -1064,14 +1064,6 @@ namespace OpenSim.Region.Framework.Scenes
1064 } 1064 }
1065 } 1065 }
1066 1066
1067 /// <summary>
1068 /// Clear all pending updates of parts to clients
1069 /// </summary>
1070 private void ClearUpdateSchedule()
1071 {
1072 m_updateFlag = 0;
1073 }
1074
1075 private void SendObjectPropertiesToClient(UUID AgentID) 1067 private void SendObjectPropertiesToClient(UUID AgentID)
1076 { 1068 {
1077 ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences(); 1069 ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences();
@@ -2185,6 +2177,11 @@ namespace OpenSim.Region.Framework.Scenes
2185 ParentGroup.HasGroupChanged = true; 2177 ParentGroup.HasGroupChanged = true;
2186 ScheduleFullUpdate(); 2178 ScheduleFullUpdate();
2187 } 2179 }
2180
2181 public void RotLookAt(Quaternion target, float strength, float damping)
2182 {
2183 m_parentGroup.rotLookAt(target, strength, damping);
2184 }
2188 2185
2189 /// <summary> 2186 /// <summary>
2190 /// Schedules this prim for a full update 2187 /// Schedules this prim for a full update
@@ -2389,8 +2386,8 @@ namespace OpenSim.Region.Framework.Scenes
2389 { 2386 {
2390 const float ROTATION_TOLERANCE = 0.01f; 2387 const float ROTATION_TOLERANCE = 0.01f;
2391 const float VELOCITY_TOLERANCE = 0.001f; 2388 const float VELOCITY_TOLERANCE = 0.001f;
2392 const float POSITION_TOLERANCE = 0.05f; 2389 const float POSITION_TOLERANCE = 0.05f; // I don't like this, but I suppose it's necessary
2393 const int TIME_MS_TOLERANCE = 3000; 2390 const int TIME_MS_TOLERANCE = 200; //llSetPos has a 200ms delay. This should NOT be 3 seconds.
2394 2391
2395 if (m_updateFlag == 1) 2392 if (m_updateFlag == 1)
2396 { 2393 {
@@ -2404,7 +2401,7 @@ namespace OpenSim.Region.Framework.Scenes
2404 Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) 2401 Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE)
2405 { 2402 {
2406 AddTerseUpdateToAllAvatars(); 2403 AddTerseUpdateToAllAvatars();
2407 ClearUpdateSchedule(); 2404
2408 2405
2409 // This causes the Scene to 'poll' physical objects every couple of frames 2406 // This causes the Scene to 'poll' physical objects every couple of frames
2410 // bad, so it's been replaced by an event driven method. 2407 // bad, so it's been replaced by an event driven method.
@@ -2422,16 +2419,18 @@ namespace OpenSim.Region.Framework.Scenes
2422 m_lastAngularVelocity = AngularVelocity; 2419 m_lastAngularVelocity = AngularVelocity;
2423 m_lastTerseSent = Environment.TickCount; 2420 m_lastTerseSent = Environment.TickCount;
2424 } 2421 }
2422 //Moved this outside of the if clause so updates don't get blocked.. *sigh*
2423 m_updateFlag = 0; //Why were we calling a function to do this? Inefficient! *screams*
2425 } 2424 }
2426 else 2425 else
2427 { 2426 {
2428 if (m_updateFlag == 2) // is a new prim, just created/reloaded or has major changes 2427 if (m_updateFlag == 2) // is a new prim, just created/reloaded or has major changes
2429 { 2428 {
2430 AddFullUpdateToAllAvatars(); 2429 AddFullUpdateToAllAvatars();
2431 ClearUpdateSchedule(); 2430 m_updateFlag = 0; //Same here
2432 } 2431 }
2433 } 2432 }
2434 ClearUpdateSchedule(); 2433 m_updateFlag = 0;
2435 } 2434 }
2436 2435
2437 /// <summary> 2436 /// <summary>
@@ -2684,6 +2683,13 @@ namespace OpenSim.Region.Framework.Scenes
2684 SetText(text); 2683 SetText(text);
2685 } 2684 }
2686 2685
2686 public void StopLookAt()
2687 {
2688 m_parentGroup.stopLookAt();
2689
2690 m_parentGroup.ScheduleGroupForTerseUpdate();
2691 }
2692
2687 public void StopMoveToTarget() 2693 public void StopMoveToTarget()
2688 { 2694 {
2689 m_parentGroup.stopMoveToTarget(); 2695 m_parentGroup.stopMoveToTarget();
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 5604e3d..4e5fee1 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -73,7 +73,7 @@ namespace OpenSim.Region.Framework.Scenes
73// { 73// {
74// m_log.Debug("[ScenePresence] Destructor called"); 74// m_log.Debug("[ScenePresence] Destructor called");
75// } 75// }
76 76
77 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 77 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
78 78
79 private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 }; 79 private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 };
@@ -89,7 +89,8 @@ namespace OpenSim.Region.Framework.Scenes
89 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis 89 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis
90 /// issue #1716 90 /// issue #1716
91 /// </summary> 91 /// </summary>
92 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f); 92// private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f);
93 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f);
93 94
94 public UUID currentParcelUUID = UUID.Zero; 95 public UUID currentParcelUUID = UUID.Zero;
95 96
@@ -113,7 +114,8 @@ namespace OpenSim.Region.Framework.Scenes
113 public Vector3 lastKnownAllowedPosition; 114 public Vector3 lastKnownAllowedPosition;
114 public bool sentMessageAboutRestrictedParcelFlyingDown; 115 public bool sentMessageAboutRestrictedParcelFlyingDown;
115 public Vector4 CollisionPlane = Vector4.UnitW; 116 public Vector4 CollisionPlane = Vector4.UnitW;
116 117
118 private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation
117 private Vector3 m_lastPosition; 119 private Vector3 m_lastPosition;
118 private Quaternion m_lastRotation; 120 private Quaternion m_lastRotation;
119 private Vector3 m_lastVelocity; 121 private Vector3 m_lastVelocity;
@@ -144,7 +146,6 @@ namespace OpenSim.Region.Framework.Scenes
144 private int m_perfMonMS; 146 private int m_perfMonMS;
145 147
146 private bool m_setAlwaysRun; 148 private bool m_setAlwaysRun;
147
148 private bool m_forceFly; 149 private bool m_forceFly;
149 private bool m_flyDisabled; 150 private bool m_flyDisabled;
150 151
@@ -168,7 +169,8 @@ namespace OpenSim.Region.Framework.Scenes
168 protected RegionInfo m_regionInfo; 169 protected RegionInfo m_regionInfo;
169 protected ulong crossingFromRegion; 170 protected ulong crossingFromRegion;
170 171
171 private readonly Vector3[] Dir_Vectors = new Vector3[6]; 172 private readonly Vector3[] Dir_Vectors = new Vector3[9];
173 private bool m_isNudging = false;
172 174
173 // Position of agent's camera in world (region cordinates) 175 // Position of agent's camera in world (region cordinates)
174 protected Vector3 m_CameraCenter; 176 protected Vector3 m_CameraCenter;
@@ -232,6 +234,8 @@ namespace OpenSim.Region.Framework.Scenes
232 DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG, 234 DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG,
233 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 235 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
234 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 236 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
237 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS,
238 DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
235 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG 239 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
236 } 240 }
237 241
@@ -716,21 +720,41 @@ namespace OpenSim.Region.Framework.Scenes
716 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 720 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
717 Dir_Vectors[4] = Vector3.UnitZ; //UP 721 Dir_Vectors[4] = Vector3.UnitZ; //UP
718 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 722 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
719 Dir_Vectors[5] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 723 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
724 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
725 Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
720 } 726 }
721 727
722 private Vector3[] GetWalkDirectionVectors() 728 private Vector3[] GetWalkDirectionVectors()
723 { 729 {
724 Vector3[] vector = new Vector3[6]; 730 Vector3[] vector = new Vector3[9];
725 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD 731 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
726 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK 732 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
727 vector[2] = Vector3.UnitY; //LEFT 733 vector[2] = Vector3.UnitY; //LEFT
728 vector[3] = -Vector3.UnitY; //RIGHT 734 vector[3] = -Vector3.UnitY; //RIGHT
729 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 735 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
730 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN 736 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
731 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge 737 vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
738 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
739 vector[8] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge
732 return vector; 740 return vector;
733 } 741 }
742
743 private bool[] GetDirectionIsNudge()
744 {
745 bool[] isNudge = new bool[9];
746 isNudge[0] = false; //FORWARD
747 isNudge[1] = false; //BACK
748 isNudge[2] = false; //LEFT
749 isNudge[3] = false; //RIGHT
750 isNudge[4] = false; //UP
751 isNudge[5] = false; //DOWN
752 isNudge[6] = true; //FORWARD_NUDGE
753 isNudge[7] = true; //BACK_NUDGE
754 isNudge[8] = true; //DOWN_Nudge
755 return isNudge;
756 }
757
734 758
735 #endregion 759 #endregion
736 760
@@ -1147,7 +1171,6 @@ namespace OpenSim.Region.Framework.Scenes
1147 // // m_log.Debug("DEBUG: HandleAgentUpdate: child agent"); 1171 // // m_log.Debug("DEBUG: HandleAgentUpdate: child agent");
1148 // return; 1172 // return;
1149 //} 1173 //}
1150
1151 m_perfMonMS = Environment.TickCount; 1174 m_perfMonMS = Environment.TickCount;
1152 1175
1153 ++m_movementUpdateCount; 1176 ++m_movementUpdateCount;
@@ -1229,7 +1252,6 @@ namespace OpenSim.Region.Framework.Scenes
1229 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); 1252 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
1230 } 1253 }
1231 } 1254 }
1232
1233 lock (scriptedcontrols) 1255 lock (scriptedcontrols)
1234 { 1256 {
1235 if (scriptedcontrols.Count > 0) 1257 if (scriptedcontrols.Count > 0)
@@ -1261,7 +1283,6 @@ namespace OpenSim.Region.Framework.Scenes
1261 { 1283 {
1262 return; 1284 return;
1263 } 1285 }
1264
1265 if (m_allowMovement) 1286 if (m_allowMovement)
1266 { 1287 {
1267 int i = 0; 1288 int i = 0;
@@ -1289,6 +1310,11 @@ namespace OpenSim.Region.Framework.Scenes
1289 update_rotation = true; 1310 update_rotation = true;
1290 } 1311 }
1291 1312
1313 //guilty until proven innocent..
1314 bool Nudging = true;
1315 //Basically, if there is at least one non-nudge control then we don't need
1316 //to worry about stopping the avatar
1317
1292 if (m_parentID == 0) 1318 if (m_parentID == 0)
1293 { 1319 {
1294 bool bAllowUpdateMoveToPosition = false; 1320 bool bAllowUpdateMoveToPosition = false;
@@ -1303,6 +1329,12 @@ namespace OpenSim.Region.Framework.Scenes
1303 else 1329 else
1304 dirVectors = Dir_Vectors; 1330 dirVectors = Dir_Vectors;
1305 1331
1332 bool[] isNudge = GetDirectionIsNudge();
1333
1334
1335
1336
1337
1306 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1338 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1307 { 1339 {
1308 if (((uint)flags & (uint)DCF) != 0) 1340 if (((uint)flags & (uint)DCF) != 0)
@@ -1312,6 +1344,10 @@ namespace OpenSim.Region.Framework.Scenes
1312 try 1344 try
1313 { 1345 {
1314 agent_control_v3 += dirVectors[i]; 1346 agent_control_v3 += dirVectors[i];
1347 if (isNudge[i] == false)
1348 {
1349 Nudging = false;
1350 }
1315 } 1351 }
1316 catch (IndexOutOfRangeException) 1352 catch (IndexOutOfRangeException)
1317 { 1353 {
@@ -1373,6 +1409,9 @@ namespace OpenSim.Region.Framework.Scenes
1373 // Ignore z component of vector 1409 // Ignore z component of vector
1374 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1410 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1375 LocalVectorToTarget2D.Normalize(); 1411 LocalVectorToTarget2D.Normalize();
1412
1413 //We're not nudging
1414 Nudging = false;
1376 agent_control_v3 += LocalVectorToTarget2D; 1415 agent_control_v3 += LocalVectorToTarget2D;
1377 1416
1378 // update avatar movement flags. the avatar coordinate system is as follows: 1417 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1455,7 +1494,7 @@ namespace OpenSim.Region.Framework.Scenes
1455 // m_log.DebugFormat( 1494 // m_log.DebugFormat(
1456 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1495 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
1457 1496
1458 AddNewMovement(agent_control_v3, q); 1497 AddNewMovement(agent_control_v3, q, Nudging);
1459 1498
1460 if (update_movementflag) 1499 if (update_movementflag)
1461 Animator.UpdateMovementAnimations(); 1500 Animator.UpdateMovementAnimations();
@@ -1538,7 +1577,7 @@ namespace OpenSim.Region.Framework.Scenes
1538 Velocity = Vector3.Zero; 1577 Velocity = Vector3.Zero;
1539 SendFullUpdateToAllClients(); 1578 SendFullUpdateToAllClients();
1540 1579
1541 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1580 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1542 } 1581 }
1543 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1582 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1544 m_requestedSitTargetUUID = UUID.Zero; 1583 m_requestedSitTargetUUID = UUID.Zero;
@@ -1651,7 +1690,7 @@ namespace OpenSim.Region.Framework.Scenes
1651 bool SitTargetisSet = 1690 bool SitTargetisSet =
1652 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f && 1691 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1653 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f)); 1692 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1654 1693 // this test is probably failing
1655 if (SitTargetisSet && SitTargetUnOccupied) 1694 if (SitTargetisSet && SitTargetUnOccupied)
1656 { 1695 {
1657 //switch the target to this prim 1696 //switch the target to this prim
@@ -1678,26 +1717,37 @@ namespace OpenSim.Region.Framework.Scenes
1678 { 1717 {
1679 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 1718 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
1680 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 1719 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1681 1720
1721 // part is the prim to sit on
1722 // offset is the vector distance from that prim center to the click-spot
1723 // UUID is the UUID of the Avatar doing the clicking
1724
1725 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
1726
1682 // Is a sit target available? 1727 // Is a sit target available?
1683 Vector3 avSitOffSet = part.SitTargetPosition; 1728 Vector3 avSitOffSet = part.SitTargetPosition;
1684 Quaternion avSitOrientation = part.SitTargetOrientation; 1729 Quaternion avSitOrientation = part.SitTargetOrientation;
1685 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1730 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1686 1731
1687 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1732 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero));
1688 bool SitTargetisSet = 1733// bool SitTargetisSet =
1689 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 0f && 1734// (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 0f &&
1690 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f)); 1735// avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f));
1691 1736
1737 bool SitTargetisSet = ((Vector3.Zero != avSitOffSet) || (Quaternion.Identity != avSitOrientation));
1738
1739//Console.WriteLine("SendSitResponse offset=" + offset + " UnOccup=" + SitTargetUnOccupied +
1740// " TargSet=" + SitTargetisSet);
1741
1692 if (SitTargetisSet && SitTargetUnOccupied) 1742 if (SitTargetisSet && SitTargetUnOccupied)
1693 { 1743 {
1694 part.SetAvatarOnSitTarget(UUID); 1744 part.SetAvatarOnSitTarget(UUID);
1695 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 1745 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z);
1696 sitOrientation = avSitOrientation; 1746 sitOrientation = avSitOrientation;
1697 autopilot = false; 1747 autopilot = false; // Jump direct to scripted llSitPos()
1698 } 1748 }
1699 1749
1700 pos = part.AbsolutePosition + offset; 1750 pos = part.AbsolutePosition + offset; // Region position where clicked
1701 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) 1751 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1)
1702 //{ 1752 //{
1703 // offset = pos; 1753 // offset = pos;
@@ -1710,17 +1760,17 @@ namespace OpenSim.Region.Framework.Scenes
1710 m_sitAvatarHeight = m_physicsActor.Size.Z; 1760 m_sitAvatarHeight = m_physicsActor.Size.Z;
1711 1761
1712 if (autopilot) 1762 if (autopilot)
1713 { 1763 { // its not a scripted sit
1714 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 1764 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5)
1715 { 1765 {
1716 autopilot = false; 1766 autopilot = false; // close enough
1717 1767
1718 RemoveFromPhysicalScene(); 1768 RemoveFromPhysicalScene();
1719 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 1769 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to Prim
1720 } 1770 } // else the autopilot will get us close
1721 } 1771 }
1722 else 1772 else
1723 { 1773 { // its a scripted sit
1724 RemoveFromPhysicalScene(); 1774 RemoveFromPhysicalScene();
1725 } 1775 }
1726 } 1776 }
@@ -1823,26 +1873,41 @@ namespace OpenSim.Region.Framework.Scenes
1823 { 1873 {
1824 if (part.GetAvatarOnSitTarget() == UUID) 1874 if (part.GetAvatarOnSitTarget() == UUID)
1825 { 1875 {
1876 // Scripted sit
1826 Vector3 sitTargetPos = part.SitTargetPosition; 1877 Vector3 sitTargetPos = part.SitTargetPosition;
1827 Quaternion sitTargetOrient = part.SitTargetOrientation; 1878 Quaternion sitTargetOrient = part.SitTargetOrientation;
1828
1829 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
1830 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
1831
1832 //Quaternion result = (sitTargetOrient * vq) * nq;
1833
1834 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 1879 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
1835 m_pos += SIT_TARGET_ADJUSTMENT; 1880 m_pos += SIT_TARGET_ADJUSTMENT;
1836 m_bodyRot = sitTargetOrient; 1881 m_bodyRot = sitTargetOrient;
1837 //Rotation = sitTargetOrient;
1838 m_parentPosition = part.AbsolutePosition; 1882 m_parentPosition = part.AbsolutePosition;
1839
1840 //SendTerseUpdateToAllClients();
1841 } 1883 }
1842 else 1884 else
1843 { 1885 {
1844 m_pos -= part.AbsolutePosition; 1886 // Non-scripted sit by Kitto Flora 21Nov09
1887 // Calculate angle of line from prim to Av
1888 float y_diff = (m_avInitialPos.Y - part.AbsolutePosition.Y);
1889 float x_diff = ( m_avInitialPos.X - part.AbsolutePosition.X);
1890 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
1891 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
1892 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
1893 Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1894 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
1895 // Av sits at world euler <0,0, z>, translated by part rotation
1896 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
1897 m_pos = new Vector3(0f, 0f, 0.05f) +
1898 (new Vector3(0.0f, 0f, 0.625f) * partIRot) +
1899 (new Vector3(0.25f, 0f, 0.0f) * m_bodyRot); // sit at center of prim
1845 m_parentPosition = part.AbsolutePosition; 1900 m_parentPosition = part.AbsolutePosition;
1901 //Set up raytrace to find top surface of prim
1902 Vector3 size = part.Scale;
1903 float mag = 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
1904 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
1905 Vector3 down = new Vector3(0f, 0f, -1f);
1906 m_scene.PhysicsScene.RaycastWorld(
1907 start, // Vector3 position,
1908 down, // Vector3 direction,
1909 mag, // float length,
1910 SitAltitudeCallback); // retMethod
1846 } 1911 }
1847 } 1912 }
1848 else 1913 else
@@ -1857,11 +1922,22 @@ namespace OpenSim.Region.Framework.Scenes
1857 1922
1858 Animator.TrySetMovementAnimation(sitAnimation); 1923 Animator.TrySetMovementAnimation(sitAnimation);
1859 SendFullUpdateToAllClients(); 1924 SendFullUpdateToAllClients();
1860 // This may seem stupid, but Our Full updates don't send avatar rotation :P
1861 // So we're also sending a terse update (which has avatar rotation)
1862 // [Update] We do now.
1863 //SendTerseUpdateToAllClients();
1864 } 1925 }
1926
1927 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance)
1928 {
1929// Console.WriteLine("[RAYCASTRESULT]: Hit={0}, Point={1}, ID={2}, Dist={3}", hitYN, collisionPoint, localid, distance);
1930 if(hitYN)
1931 {
1932 // m_pos = Av offset from prim center to make look like on center
1933 // m_parentPosition = Actual center pos of prim
1934 // collisionPoint = spot on prim where we want to sit
1935 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
1936 Vector3 offset = (collisionPoint - m_parentPosition) * Quaternion.Inverse(part.RotationOffset);
1937 m_pos += offset;
1938// Console.WriteLine("m_pos={0}, offset={1} newsit={2}", m_pos, offset, newsit);
1939 }
1940 }
1865 1941
1866 /// <summary> 1942 /// <summary>
1867 /// Event handler for the 'Always run' setting on the client 1943 /// Event handler for the 'Always run' setting on the client
@@ -1891,7 +1967,7 @@ namespace OpenSim.Region.Framework.Scenes
1891 /// </summary> 1967 /// </summary>
1892 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 1968 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
1893 /// <param name="rotation">The direction in which this avatar should now face. 1969 /// <param name="rotation">The direction in which this avatar should now face.
1894 public void AddNewMovement(Vector3 vec, Quaternion rotation) 1970 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
1895 { 1971 {
1896 if (m_isChildAgent) 1972 if (m_isChildAgent)
1897 { 1973 {
@@ -1965,7 +2041,7 @@ namespace OpenSim.Region.Framework.Scenes
1965 2041
1966 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2042 // TODO: Add the force instead of only setting it to support multiple forces per frame?
1967 m_forceToApply = direc; 2043 m_forceToApply = direc;
1968 2044 m_isNudging = Nudging;
1969 m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); 2045 m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS);
1970 } 2046 }
1971 2047
@@ -1980,7 +2056,7 @@ namespace OpenSim.Region.Framework.Scenes
1980 const float POSITION_TOLERANCE = 0.05f; 2056 const float POSITION_TOLERANCE = 0.05f;
1981 //const int TIME_MS_TOLERANCE = 3000; 2057 //const int TIME_MS_TOLERANCE = 3000;
1982 2058
1983 SendPrimUpdates(); 2059
1984 2060
1985 if (m_newCoarseLocations) 2061 if (m_newCoarseLocations)
1986 { 2062 {
@@ -2016,6 +2092,9 @@ namespace OpenSim.Region.Framework.Scenes
2016 CheckForBorderCrossing(); 2092 CheckForBorderCrossing();
2017 CheckForSignificantMovement(); // sends update to the modules. 2093 CheckForSignificantMovement(); // sends update to the modules.
2018 } 2094 }
2095
2096 //Sending prim updates AFTER the avatar terse updates are sent
2097 SendPrimUpdates();
2019 } 2098 }
2020 2099
2021 #endregion 2100 #endregion
@@ -2869,14 +2948,24 @@ namespace OpenSim.Region.Framework.Scenes
2869 { 2948 {
2870 if (m_forceToApply.HasValue) 2949 if (m_forceToApply.HasValue)
2871 { 2950 {
2872 Vector3 force = m_forceToApply.Value;
2873 2951
2952 Vector3 force = m_forceToApply.Value;
2874 m_updateflag = true; 2953 m_updateflag = true;
2875// movementvector = force;
2876 Velocity = force; 2954 Velocity = force;
2877 2955
2878 m_forceToApply = null; 2956 m_forceToApply = null;
2879 } 2957 }
2958 else
2959 {
2960 if (m_isNudging)
2961 {
2962 Vector3 force = Vector3.Zero;
2963
2964 m_updateflag = true;
2965 Velocity = force;
2966 m_isNudging = false;
2967 }
2968 }
2880 } 2969 }
2881 2970
2882 public override void SetText(string text, Vector3 color, double alpha) 2971 public override void SetText(string text, Vector3 color, double alpha)
@@ -3585,4 +3674,4 @@ namespace OpenSim.Region.Framework.Scenes
3585 } 3674 }
3586 } 3675 }
3587 } 3676 }
3588} \ No newline at end of file 3677}
diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsActor.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsActor.cs
index 8df997e..f411dd7 100644
--- a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsActor.cs
+++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsActor.cs
@@ -303,6 +303,26 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin
303 set { return; } 303 set { return; }
304 } 304 }
305 305
306 public override Quaternion APIDTarget
307 {
308 set { return; }
309 }
310
311 public override bool APIDActive
312 {
313 set { return; }
314 }
315
316 public override float APIDStrength
317 {
318 set { return; }
319 }
320
321 public override float APIDDamping
322 {
323 set { return; }
324 }
325
306 public override void SubscribeEvents(int ms) 326 public override void SubscribeEvents(int ms)
307 { 327 {
308 } 328 }
diff --git a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETCharacter.cs b/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETCharacter.cs
index 5ed3b14..98681d6 100644
--- a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETCharacter.cs
+++ b/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETCharacter.cs
@@ -619,6 +619,12 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
619 { 619 {
620 set { return; } 620 set { return; }
621 } 621 }
622
623 public override Quaternion APIDTarget { set { return; } }
624 public override bool APIDActive { set { return; } }
625 public override float APIDStrength { set { return; } }
626 public override float APIDDamping { set { return; } }
627
622 628
623 /// <summary> 629 /// <summary>
624 /// Adds the force supplied to the Target Velocity 630 /// Adds the force supplied to the Target Velocity
diff --git a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETPrim.cs b/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETPrim.cs
index 5b542db..d931f126 100644
--- a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETPrim.cs
+++ b/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETPrim.cs
@@ -565,6 +565,11 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
565 public override PIDHoverType PIDHoverType { set { m_PIDHoverType = value; } } 565 public override PIDHoverType PIDHoverType { set { m_PIDHoverType = value; } }
566 public override float PIDHoverTau { set { m_PIDHoverTau = value; } } 566 public override float PIDHoverTau { set { m_PIDHoverTau = value; } }
567 567
568 public override Quaternion APIDTarget { set { return; } }
569 public override bool APIDActive { set { return; } }
570 public override float APIDStrength { set { return; } }
571 public override float APIDDamping { set { return; } }
572
568 573
569 public override void AddForce(Vector3 force, bool pushforce) 574 public override void AddForce(Vector3 force, bool pushforce)
570 { 575 {
diff --git a/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs b/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs
index 1e94ee2..d5d146e 100644
--- a/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs
+++ b/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs
@@ -1238,6 +1238,26 @@ namespace OpenSim.Region.Physics.BulletXPlugin
1238 public override PIDHoverType PIDHoverType { set { return; } } 1238 public override PIDHoverType PIDHoverType { set { return; } }
1239 public override float PIDHoverTau { set { return; } } 1239 public override float PIDHoverTau { set { return; } }
1240 1240
1241 public override OpenMetaverse.Quaternion APIDTarget
1242 {
1243 set { return; }
1244 }
1245
1246 public override bool APIDActive
1247 {
1248 set { return; }
1249 }
1250
1251 public override float APIDStrength
1252 {
1253 set { return; }
1254 }
1255
1256 public override float APIDDamping
1257 {
1258 set { return; }
1259 }
1260
1241 1261
1242 public override void SubscribeEvents(int ms) 1262 public override void SubscribeEvents(int ms)
1243 { 1263 {
diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs
index f58129d..b82586f 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs
@@ -243,7 +243,12 @@ namespace OpenSim.Region.Physics.Manager
243 public abstract PIDHoverType PIDHoverType { set;} 243 public abstract PIDHoverType PIDHoverType { set;}
244 public abstract float PIDHoverTau { set;} 244 public abstract float PIDHoverTau { set;}
245 245
246 246 // For RotLookAt
247 public abstract Quaternion APIDTarget { set;}
248 public abstract bool APIDActive { set;}
249 public abstract float APIDStrength { set;}
250 public abstract float APIDDamping { set;}
251
247 public abstract void AddForce(Vector3 force, bool pushforce); 252 public abstract void AddForce(Vector3 force, bool pushforce);
248 public abstract void AddAngularForce(Vector3 force, bool pushforce); 253 public abstract void AddAngularForce(Vector3 force, bool pushforce);
249 public abstract void SetMomentum(Vector3 momentum); 254 public abstract void SetMomentum(Vector3 momentum);
@@ -476,6 +481,12 @@ namespace OpenSim.Region.Physics.Manager
476 public override bool PIDHoverActive { set { return; } } 481 public override bool PIDHoverActive { set { return; } }
477 public override PIDHoverType PIDHoverType { set { return; } } 482 public override PIDHoverType PIDHoverType { set { return; } }
478 public override float PIDHoverTau { set { return; } } 483 public override float PIDHoverTau { set { return; } }
484
485 public override Quaternion APIDTarget { set { return; } }
486 public override bool APIDActive { set { return; } }
487 public override float APIDStrength { set { return; } }
488 public override float APIDDamping { set { return; } }
489
479 490
480 public override void SetMomentum(Vector3 momentum) 491 public override void SetMomentum(Vector3 momentum)
481 { 492 {
diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
index 1bc4a25..905d3ba 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
@@ -1196,6 +1196,28 @@ namespace OpenSim.Region.Physics.OdePlugin
1196 public override bool PIDHoverActive { set { return; } } 1196 public override bool PIDHoverActive { set { return; } }
1197 public override PIDHoverType PIDHoverType { set { return; } } 1197 public override PIDHoverType PIDHoverType { set { return; } }
1198 public override float PIDHoverTau { set { return; } } 1198 public override float PIDHoverTau { set { return; } }
1199
1200 public override Quaternion APIDTarget
1201 {
1202 set { return; }
1203 }
1204
1205 public override bool APIDActive
1206 {
1207 set { return; }
1208 }
1209
1210 public override float APIDStrength
1211 {
1212 set { return; }
1213 }
1214
1215 public override float APIDDamping
1216 {
1217 set { return; }
1218 }
1219
1220
1199 1221
1200 public override void SubscribeEvents(int ms) 1222 public override void SubscribeEvents(int ms)
1201 { 1223 {
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs b/OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs
index 39cdc0f..78b15be 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs
@@ -23,6 +23,19 @@
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 * Revised Aug, Sept 2009 by Kitto Flora. ODEDynamics.cs replaces
28 * ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised:
29 * ODEPrim.cs contains methods dealing with Prim editing, Prim
30 * characteristics and Kinetic motion.
31 * ODEDynamics.cs contains methods dealing with Prim Physical motion
32 * (dynamics) and the associated settings. Old Linear and angular
33 * motors for dynamic motion have been replace with MoveLinear()
34 * and MoveAngular(); 'Physical' is used only to switch ODE dynamic
35 * simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_<other> is to
36 * switch between 'VEHICLE' parameter use and general dynamics
37 * settings use.
38 *
26 */ 39 */
27 40
28/* Revised Aug, Sept 2009 by Kitto Flora. ODEDynamics.cs replaces 41/* Revised Aug, Sept 2009 by Kitto Flora. ODEDynamics.cs replaces
@@ -120,7 +133,7 @@ namespace OpenSim.Region.Physics.OdePlugin
120// private float m_VhoverEfficiency = 0f; 133// private float m_VhoverEfficiency = 0f;
121 private float m_VhoverTimescale = 0f; 134 private float m_VhoverTimescale = 0f;
122 private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height 135 private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height
123 private float m_VehicleBuoyancy = 0f; //KF: m_VehicleBuoyancy is set by VEHICLE_BUOYANCY for a vehicle. 136 private float m_VehicleBuoyancy = 0f; // Set by VEHICLE_BUOYANCY, for a vehicle.
124 // Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity) 137 // Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity)
125 // KF: So far I have found no good method to combine a script-requested .Z velocity and gravity. 138 // KF: So far I have found no good method to combine a script-requested .Z velocity and gravity.
126 // Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity. 139 // Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity.
@@ -479,7 +492,7 @@ namespace OpenSim.Region.Physics.OdePlugin
479 Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); // rotq = rotation of object 492 Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); // rotq = rotation of object
480 m_dir *= rotq; // apply obj rotation to velocity vector 493 m_dir *= rotq; // apply obj rotation to velocity vector
481 494
482 // add Gravity andBuoyancy 495 // add Gravity and Buoyancy
483 // KF: So far I have found no good method to combine a script-requested 496 // KF: So far I have found no good method to combine a script-requested
484 // .Z velocity and gravity. Therefore only 0g will used script-requested 497 // .Z velocity and gravity. Therefore only 0g will used script-requested
485 // .Z velocity. >0g (m_VehicleBuoyancy < 1) will used modified gravity only. 498 // .Z velocity. >0g (m_VehicleBuoyancy < 1) will used modified gravity only.
@@ -561,6 +574,7 @@ namespace OpenSim.Region.Physics.OdePlugin
561 private Vector3 m_angularFrictionTimescale = Vector3.Zero; // body angular velocity decay rate 574 private Vector3 m_angularFrictionTimescale = Vector3.Zero; // body angular velocity decay rate
562 private Vector3 m_lastAngularVelocity = Vector3.Zero; // what was last applied to body 575 private Vector3 m_lastAngularVelocity = Vector3.Zero; // what was last applied to body
563 */ 576 */
577//if(frcount == 0) Console.WriteLine("MoveAngular ");
564 578
565 // Get what the body is doing, this includes 'external' influences 579 // Get what the body is doing, this includes 'external' influences
566 d.Vector3 angularVelocity = d.BodyGetAngularVel(Body); 580 d.Vector3 angularVelocity = d.BodyGetAngularVel(Body);
@@ -636,7 +650,7 @@ namespace OpenSim.Region.Physics.OdePlugin
636 // Deflection section tba 650 // Deflection section tba
637 651
638 // Sum velocities 652 // Sum velocities
639 m_lastAngularVelocity = m_angularMotorVelocity + vertattr; // + bank + deflection 653 m_lastAngularVelocity = m_angularMotorVelocity + vertattr; // tba: + bank + deflection
640 654
641 if (!m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) 655 if (!m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f))
642 { 656 {
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
index 17552d2..b0e9a91 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
@@ -21,6 +21,18 @@
21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 *
25 * Revised August 26 2009 by Kitto Flora. ODEDynamics.cs replaces
26 * ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised:
27 * ODEPrim.cs contains methods dealing with Prim editing, Prim
28 * characteristics and Kinetic motion.
29 * ODEDynamics.cs contains methods dealing with Prim Physical motion
30 * (dynamics) and the associated settings. Old Linear and angular
31 * motors for dynamic motion have been replace with MoveLinear()
32 * and MoveAngular(); 'Physical' is used only to switch ODE dynamic
33 * simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_<other> is to
34 * switch between 'VEHICLE' parameter use and general dynamics
35 * settings use.
24 */ 36 */
25 37
26/* 38/*
@@ -81,7 +93,12 @@ namespace OpenSim.Region.Physics.OdePlugin
81 private float m_PIDTau; 93 private float m_PIDTau;
82 private float PID_D = 35f; 94 private float PID_D = 35f;
83 private float PID_G = 25f; 95 private float PID_G = 25f;
84 private bool m_usePID; 96 private bool m_usePID = false;
97
98 private Quaternion m_APIDTarget = new Quaternion();
99 private float m_APIDStrength = 0.5f;
100 private float m_APIDDamping = 0.5f;
101 private bool m_useAPID = false;
85 102
86 // KF: These next 7 params apply to llSetHoverHeight(float height, integer water, float tau), 103 // KF: These next 7 params apply to llSetHoverHeight(float height, integer water, float tau),
87 // and are for non-VEHICLES only. 104 // and are for non-VEHICLES only.
@@ -182,6 +199,9 @@ namespace OpenSim.Region.Physics.OdePlugin
182 private ODEDynamics m_vehicle; 199 private ODEDynamics m_vehicle;
183 200
184 internal int m_material = (int)Material.Wood; 201 internal int m_material = (int)Material.Wood;
202
203 private int frcount = 0; // Used to limit dynamics debug output to
204
185 205
186 public OdePrim(String primName, OdeScene parent_scene, Vector3 pos, Vector3 size, 206 public OdePrim(String primName, OdeScene parent_scene, Vector3 pos, Vector3 size,
187 Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical, CollisionLocker dode) 207 Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical, CollisionLocker dode)
@@ -1558,9 +1578,14 @@ Console.WriteLine(" JointCreateFixed");
1558 float fy = 0; 1578 float fy = 0;
1559 float fz = 0; 1579 float fz = 0;
1560 1580
1581 frcount++; // used to limit debug comment output
1582 if (frcount > 100)
1583 frcount = 0;
1561 1584
1562 if (IsPhysical && (Body != IntPtr.Zero) && !m_isSelected && !childPrim) // KF: Only move root prims. 1585 if (IsPhysical && (Body != IntPtr.Zero) && !m_isSelected && !childPrim) // KF: Only move root prims.
1563 { 1586 {
1587//if(frcount == 0) Console.WriteLine("Move " + m_primName + " VTyp " + m_vehicle.Type +
1588 // " usePID=" + m_usePID + " seHover=" + m_useHoverPID + " useAPID=" + m_useAPID);
1564 if (m_vehicle.Type != Vehicle.TYPE_NONE) 1589 if (m_vehicle.Type != Vehicle.TYPE_NONE)
1565 { 1590 {
1566 // 'VEHICLES' are dealt with in ODEDynamics.cs 1591 // 'VEHICLES' are dealt with in ODEDynamics.cs
@@ -1568,7 +1593,6 @@ Console.WriteLine(" JointCreateFixed");
1568 } 1593 }
1569 else 1594 else
1570 { 1595 {
1571//Console.WriteLine("Move " + m_primName);
1572 if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body); // KF add 161009 1596 if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body); // KF add 161009
1573 // NON-'VEHICLES' are dealt with here 1597 // NON-'VEHICLES' are dealt with here
1574 if (d.BodyIsEnabled(Body) && !m_angularlock.ApproxEquals(Vector3.Zero, 0.003f)) 1598 if (d.BodyIsEnabled(Body) && !m_angularlock.ApproxEquals(Vector3.Zero, 0.003f))
@@ -1590,21 +1614,18 @@ Console.WriteLine(" JointCreateFixed");
1590 //m_log.Info(m_collisionFlags.ToString()); 1614 //m_log.Info(m_collisionFlags.ToString());
1591 1615
1592 1616
1593 //KF: m_buoyancy should be set by llSetBuoyancy() for non-vehicle. 1617 //KF: m_buoyancy is set by llSetBuoyancy() and is for non-vehicle.
1594 // would come from SceneObjectPart.cs, public void SetBuoyancy(float fvalue) , PhysActor.Buoyancy = fvalue; ??
1595 // m_buoyancy: (unlimited value) <0=Falls fast; 0=1g; 1=0g; >1 = floats up 1618 // m_buoyancy: (unlimited value) <0=Falls fast; 0=1g; 1=0g; >1 = floats up
1596 // gravityz multiplier = 1 - m_buoyancy 1619 // NB Prims in ODE are no subject to global gravity
1597 fz = _parent_scene.gravityz * (1.0f - m_buoyancy) * m_mass; 1620 fz = _parent_scene.gravityz * (1.0f - m_buoyancy) * m_mass; // force = acceleration * mass
1598 1621
1599 if (m_usePID) 1622 if (m_usePID)
1600 { 1623 {
1601//Console.WriteLine("PID " + m_primName); 1624//if(frcount == 0) Console.WriteLine("PID " + m_primName);
1602 // KF - this is for object move? eg. llSetPos() ? 1625 // KF - this is for object MoveToTarget.
1626
1603 //if (!d.BodyIsEnabled(Body)) 1627 //if (!d.BodyIsEnabled(Body))
1604 //d.BodySetForce(Body, 0f, 0f, 0f); 1628 //d.BodySetForce(Body, 0f, 0f, 0f);
1605 // If we're using the PID controller, then we have no gravity
1606 //fz = (-1 * _parent_scene.gravityz) * m_mass; //KF: ?? Prims have no global gravity,so simply...
1607 fz = 0f;
1608 1629
1609 // no lock; for now it's only called from within Simulate() 1630 // no lock; for now it's only called from within Simulate()
1610 1631
@@ -1739,7 +1760,7 @@ Console.WriteLine(" JointCreateFixed");
1739 d.BodySetPosition(Body, pos.X, pos.Y, m_targetHoverHeight); 1760 d.BodySetPosition(Body, pos.X, pos.Y, m_targetHoverHeight);
1740 d.BodySetLinearVel(Body, vel.X, vel.Y, 0); 1761 d.BodySetLinearVel(Body, vel.X, vel.Y, 0);
1741 d.BodyAddForce(Body, 0, 0, fz); 1762 d.BodyAddForce(Body, 0, 0, fz);
1742 return; 1763 //KF this prevents furthur motions return;
1743 } 1764 }
1744 else 1765 else
1745 { 1766 {
@@ -1748,8 +1769,46 @@ Console.WriteLine(" JointCreateFixed");
1748 // We're flying and colliding with something 1769 // We're flying and colliding with something
1749 fz = fz + ((_target_velocity.Z - vel.Z) * (PID_D) * m_mass); 1770 fz = fz + ((_target_velocity.Z - vel.Z) * (PID_D) * m_mass);
1750 } 1771 }
1751 } 1772 } // end m_useHoverPID && !m_usePID
1752 1773
1774 if (m_useAPID)
1775 {
1776 // RotLookAt, apparently overrides all other rotation sources. Inputs:
1777 // Quaternion m_APIDTarget
1778 // float m_APIDStrength // From SL experiments, this is the time to get there
1779 // float m_APIDDamping // From SL experiments, this is damping, 1.0 = damped, 0.1 = wobbly
1780 // Also in SL the mass of the object has no effect on time to get there.
1781 // Factors:
1782//if(frcount == 0) Console.WriteLine("APID ");
1783 // get present body rotation
1784 float limit = 1.0f;
1785 float scaler = 50f; // adjusts damping time
1786 float RLAservo = 0f;
1787
1788 d.Quaternion rot = d.BodyGetQuaternion(Body);
1789 Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W);
1790 Quaternion rot_diff = Quaternion.Inverse(rotq) * m_APIDTarget;
1791 float diff_angle;
1792 Vector3 diff_axis;
1793 rot_diff.GetAxisAngle(out diff_axis, out diff_angle);
1794 diff_axis.Normalize();
1795 if(diff_angle > 0.01f) // diff_angle is always +ve
1796 {
1797// PhysicsVector rotforce = new PhysicsVector(diff_axis.X, diff_axis.Y, diff_axis.Z);
1798 Vector3 rotforce = new Vector3(diff_axis.X, diff_axis.Y, diff_axis.Z);
1799 rotforce = rotforce * rotq;
1800 if(diff_angle > limit) diff_angle = limit; // cap the rotate rate
1801// RLAservo = timestep / m_APIDStrength * m_mass * scaler;
1802 // rotforce = rotforce * RLAservo * diff_angle ;
1803 // d.BodyAddRelTorque(Body, rotforce.X, rotforce.Y, rotforce.Z);
1804 RLAservo = timestep / m_APIDStrength * scaler;
1805 rotforce = rotforce * RLAservo * diff_angle ;
1806 d.BodySetAngularVel (Body, rotforce.X, rotforce.Y, rotforce.Z);
1807//Console.WriteLine("axis= " + diff_axis + " angle= " + diff_angle + "servo= " + RLAservo);
1808 }
1809//if(frcount == 0) Console.WriteLine("mass= " + m_mass + " servo= " + RLAservo + " angle= " + diff_angle);
1810 } // end m_useAPID
1811
1753 fx *= m_mass; 1812 fx *= m_mass;
1754 fy *= m_mass; 1813 fy *= m_mass;
1755 //fz *= m_mass; 1814 //fz *= m_mass;
@@ -2816,6 +2875,12 @@ Console.WriteLine(" JointCreateFixed");
2816 } 2875 }
2817 public override bool PIDActive { set { m_usePID = value; } } 2876 public override bool PIDActive { set { m_usePID = value; } }
2818 public override float PIDTau { set { m_PIDTau = value; } } 2877 public override float PIDTau { set { m_PIDTau = value; } }
2878
2879 // For RotLookAt
2880 public override Quaternion APIDTarget { set { m_APIDTarget = value; } }
2881 public override bool APIDActive { set { m_useAPID = value; } }
2882 public override float APIDStrength { set { m_APIDStrength = value; } }
2883 public override float APIDDamping { set { m_APIDDamping = value; } }
2819 2884
2820 public override float PIDHoverHeight { set { m_PIDHoverHeight = value; ; } } 2885 public override float PIDHoverHeight { set { m_PIDHoverHeight = value; ; } }
2821 public override bool PIDHoverActive { set { m_useHoverPID = value; } } 2886 public override bool PIDHoverActive { set { m_useHoverPID = value; } }
diff --git a/OpenSim/Region/Physics/POSPlugin/POSCharacter.cs b/OpenSim/Region/Physics/POSPlugin/POSCharacter.cs
index 26cd1dd..566b4e7 100644
--- a/OpenSim/Region/Physics/POSPlugin/POSCharacter.cs
+++ b/OpenSim/Region/Physics/POSPlugin/POSCharacter.cs
@@ -304,6 +304,27 @@ namespace OpenSim.Region.Physics.POSPlugin
304 { 304 {
305 set { return; } 305 set { return; }
306 } 306 }
307
308 public override Quaternion APIDTarget
309 {
310 set { return; }
311 }
312
313 public override bool APIDActive
314 {
315 set { return; }
316 }
317
318 public override float APIDStrength
319 {
320 set { return; }
321 }
322
323 public override float APIDDamping
324 {
325 set { return; }
326 }
327
307 328
308 public override void SubscribeEvents(int ms) 329 public override void SubscribeEvents(int ms)
309 { 330 {
diff --git a/OpenSim/Region/Physics/POSPlugin/POSPrim.cs b/OpenSim/Region/Physics/POSPlugin/POSPrim.cs
index 96c3e26..847b634 100644
--- a/OpenSim/Region/Physics/POSPlugin/POSPrim.cs
+++ b/OpenSim/Region/Physics/POSPlugin/POSPrim.cs
@@ -299,6 +299,26 @@ namespace OpenSim.Region.Physics.POSPlugin
299 { 299 {
300 set { return; } 300 set { return; }
301 } 301 }
302 public override Quaternion APIDTarget
303 {
304 set { return; }
305 }
306
307 public override bool APIDActive
308 {
309 set { return; }
310 }
311
312 public override float APIDStrength
313 {
314 set { return; }
315 }
316
317 public override float APIDDamping
318 {
319 set { return; }
320 }
321
302 322
303 public override void SubscribeEvents(int ms) 323 public override void SubscribeEvents(int ms)
304 { 324 {
diff --git a/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs b/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs
index 8bdb18d..24eb6b1 100644
--- a/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs
+++ b/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs
@@ -498,6 +498,28 @@ namespace OpenSim.Region.Physics.PhysXPlugin
498 public override bool PIDHoverActive { set { return; } } 498 public override bool PIDHoverActive { set { return; } }
499 public override PIDHoverType PIDHoverType { set { return; } } 499 public override PIDHoverType PIDHoverType { set { return; } }
500 public override float PIDHoverTau { set { return; } } 500 public override float PIDHoverTau { set { return; } }
501
502 public override Quaternion APIDTarget
503 {
504 set { return; }
505 }
506
507 public override bool APIDActive
508 {
509 set { return; }
510 }
511
512 public override float APIDStrength
513 {
514 set { return; }
515 }
516
517 public override float APIDDamping
518 {
519 set { return; }
520 }
521
522
501 523
502 public override void SubscribeEvents(int ms) 524 public override void SubscribeEvents(int ms)
503 { 525 {
@@ -780,6 +802,28 @@ namespace OpenSim.Region.Physics.PhysXPlugin
780 public override bool PIDHoverActive { set { return; } } 802 public override bool PIDHoverActive { set { return; } }
781 public override PIDHoverType PIDHoverType { set { return; } } 803 public override PIDHoverType PIDHoverType { set { return; } }
782 public override float PIDHoverTau { set { return; } } 804 public override float PIDHoverTau { set { return; } }
805
806 public override Quaternion APIDTarget
807 {
808 set { return; }
809 }
810
811 public override bool APIDActive
812 {
813 set { return; }
814 }
815
816 public override float APIDStrength
817 {
818 set { return; }
819 }
820
821 public override float APIDDamping
822 {
823 set { return; }
824 }
825
826
783 827
784 public override void SubscribeEvents(int ms) 828 public override void SubscribeEvents(int ms)
785 { 829 {
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 9c62775..50b2fb5 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -2699,11 +2699,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2699 // Orient the object to the angle calculated 2699 // Orient the object to the angle calculated
2700 llSetRot(rot); 2700 llSetRot(rot);
2701 } 2701 }
2702
2703 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
2704 {
2705 m_host.AddScriptLPS(1);
2706// NotImplemented("llRotLookAt");
2707 m_host.RotLookAt(Rot2Quaternion(target), (float)strength, (float)damping);
2708
2709 }
2710
2702 2711
2703 public void llStopLookAt() 2712 public void llStopLookAt()
2704 { 2713 {
2705 m_host.AddScriptLPS(1); 2714 m_host.AddScriptLPS(1);
2706 NotImplemented("llStopLookAt"); 2715// NotImplemented("llStopLookAt");
2716 m_host.StopLookAt();
2707 } 2717 }
2708 2718
2709 public void llSetTimerEvent(double sec) 2719 public void llSetTimerEvent(double sec)
@@ -3047,12 +3057,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3047 m_host.AddScriptLPS(1); 3057 m_host.AddScriptLPS(1);
3048 } 3058 }
3049 3059
3050 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3051 {
3052 m_host.AddScriptLPS(1);
3053 NotImplemented("llRotLookAt");
3054 }
3055
3056 public LSL_Integer llStringLength(string str) 3060 public LSL_Integer llStringLength(string str)
3057 { 3061 {
3058 m_host.AddScriptLPS(1); 3062 m_host.AddScriptLPS(1);