From a3c723ee30db61e4c2c5375fa3c8c677336ca113 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Tue, 2 Apr 2013 23:48:55 +0100
Subject: Fix minor race condition where SOP.GetGeometricCenter() and
GetCenterOfMass() could return results which were never the case if these
values were changed whilst the method was running
No need to create new Vector3s since these are structs.
---
OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index ec9e87e..2fcb199 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -2136,9 +2136,9 @@ namespace OpenSim.Region.Framework.Scenes
PhysicsActor pa = PhysActor;
if (pa != null)
- return new Vector3(pa.GeometricCenter.X, pa.GeometricCenter.Y, pa.GeometricCenter.Z);
+ return pa.GeometricCenter;
else
- return new Vector3(0, 0, 0);
+ return Vector3.Zero;
}
public Vector3 GetCenterOfMass()
@@ -2146,9 +2146,9 @@ namespace OpenSim.Region.Framework.Scenes
PhysicsActor pa = PhysActor;
if (pa != null)
- return new Vector3(pa.CenterOfMass.X, pa.CenterOfMass.Y, pa.CenterOfMass.Z);
+ return pa.CenterOfMass;
else
- return new Vector3(0, 0, 0);
+ return Vector3.Zero;
}
public float GetMass()
--
cgit v1.1
From 3332af4060960a4b649d3d5237988e0f410b54e3 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Wed, 3 Apr 2013 00:01:06 +0100
Subject: minor: Make SOP.UpdateOffset() more consistent by checking against
the same old OffsetPosition rather than one which may vary if it
simultaneously changes.
---
OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 2fcb199..d412702 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -3915,17 +3915,17 @@ namespace OpenSim.Region.Framework.Scenes
}
///
- ///
+ /// Update this part's offset position.
///
///
- public void UpdateOffSet(Vector3 pos)
+ public void UpdateOffSet(Vector3 newPos)
{
- if ((pos.X != OffsetPosition.X) ||
- (pos.Y != OffsetPosition.Y) ||
- (pos.Z != OffsetPosition.Z))
- {
- Vector3 newPos = new Vector3(pos.X, pos.Y, pos.Z);
+ Vector3 oldPos = OffsetPosition;
+ if ((newPos.X != oldPos.X) ||
+ (newPos.Y != oldPos.Y) ||
+ (newPos.Z != oldPos.Z))
+ {
if (ParentGroup.RootPart.GetStatusSandbox())
{
if (Util.GetDistanceTo(ParentGroup.RootPart.StatusSandboxPos, newPos) > 10)
--
cgit v1.1
From c0319daa403f68427bb80b4845a92eb37f21a7b7 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Wed, 3 Apr 2013 00:09:28 +0100
Subject: fix minor race condition in SOP.SitTargetPositionLL where
inconsistency could occur if the sit target position changed whilst the
property was fetched
---
OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index d412702..3e816fc 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -1146,7 +1146,7 @@ namespace OpenSim.Region.Framework.Scenes
// the mappings more consistant.
public Vector3 SitTargetPositionLL
{
- get { return new Vector3(m_sitTargetPosition.X, m_sitTargetPosition.Y,m_sitTargetPosition.Z); }
+ get { return m_sitTargetPosition; }
set { m_sitTargetPosition = value; }
}
--
cgit v1.1
From 97f0c9da84f9a3a73a63c209012260fa2c59c0de Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Wed, 3 Apr 2013 00:23:20 +0100
Subject: Use consistent GroupPosition value Make SOP.UpdateGroupPosition()
rather than one that could change whilst the method is being executed.
---
OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 3e816fc..7697411 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -3902,13 +3902,14 @@ namespace OpenSim.Region.Framework.Scenes
}
}
- public void UpdateGroupPosition(Vector3 pos)
+ public void UpdateGroupPosition(Vector3 newPos)
{
- if ((pos.X != GroupPosition.X) ||
- (pos.Y != GroupPosition.Y) ||
- (pos.Z != GroupPosition.Z))
+ Vector3 oldPos = GroupPosition;
+
+ if ((newPos.X != oldPos.X) ||
+ (newPos.Y != oldPos.Y) ||
+ (newPos.Z != oldPos.Z))
{
- Vector3 newPos = new Vector3(pos.X, pos.Y, pos.Z);
GroupPosition = newPos;
ScheduleTerseUpdate();
}
--
cgit v1.1
From 7bf1986e9138df4629aa9323d3ba9fab5c884400 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Wed, 3 Apr 2013 00:24:33 +0100
Subject: Fix minor race condition in SOP.SitTargetOrientationLL where
inconsistent values could be returned if the sit orientation was changed
whilst the property was being fetched.
---
OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 13 ++-----------
1 file changed, 2 insertions(+), 11 deletions(-)
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 7697411..93d4da0 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -1152,17 +1152,8 @@ namespace OpenSim.Region.Framework.Scenes
public Quaternion SitTargetOrientationLL
{
- get
- {
- return new Quaternion(
- m_sitTargetOrientation.X,
- m_sitTargetOrientation.Y,
- m_sitTargetOrientation.Z,
- m_sitTargetOrientation.W
- );
- }
-
- set { m_sitTargetOrientation = new Quaternion(value.X, value.Y, value.Z, value.W); }
+ get { return m_sitTargetOrientation; }
+ set { m_sitTargetOrientation = value; }
}
public bool Stopped
--
cgit v1.1
From 94d44142e37a9191162a426f28dd23f40b0cf4aa Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Wed, 3 Apr 2013 00:48:36 +0100
Subject: minor: Stop falsely logging that a teleport was being aborted on
client logout even when no teleport was active.
---
.../CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index 3e69bf2..ca0cef1 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -280,10 +280,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
private void OnConnectionClosed(IClientAPI client)
{
- if (client.IsLoggingOut)
+ if (client.IsLoggingOut && m_entityTransferStateMachine.UpdateInTransit(client.AgentId, AgentTransferState.Aborting))
{
- m_entityTransferStateMachine.UpdateInTransit(client.AgentId, AgentTransferState.Aborting);
-
m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: Aborted teleport request from {0} in {1} due to simultaneous logout",
client.Name, Scene.Name);
--
cgit v1.1
From 831e4c38506140e9ece2db4b96b4f0960a0276a8 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 4 Apr 2013 00:36:15 +0100
Subject: Fix bug where outstanding llHTTPRequests for scripts were not being
aborted when they were deleted.
This was because AsyncCommandManager was handing an item ID to IHttpRequestModule.StopHttpRequest() rather than the expected request ID.
This commit also makes the http request asynchronous using BeginGetResponse() rather than doing this by launching a new thread
so that we can more safely abort it via HttpWebRequest.Abort() rather than aborting the thread itself.
This also renames StopHttpRequest() to StopHttpRequestsForScript() since any outstanding requests are now aborted and/or removed.
---
.../Scripting/HttpRequest/ScriptsHttpRequests.cs | 92 +++++++++++++++-------
.../Region/Framework/Interfaces/IHttpRequests.cs | 8 +-
.../Api/Implementation/AsyncCommandManager.cs | 8 +-
3 files changed, 76 insertions(+), 32 deletions(-)
diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
index c2e37c4..1c251b8 100644
--- a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
+++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
@@ -28,12 +28,15 @@
using System;
using System.Collections.Generic;
using System.IO;
+using System.Linq;
using System.Net;
using System.Net.Mail;
using System.Net.Security;
+using System.Reflection;
using System.Text;
using System.Threading;
using System.Security.Cryptography.X509Certificates;
+using log4net;
using Nini.Config;
using OpenMetaverse;
using OpenSim.Framework;
@@ -250,18 +253,29 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
return reqID;
}
- public void StopHttpRequest(uint m_localID, UUID m_itemID)
+ public void StopHttpRequestsForScript(UUID id)
{
if (m_pendingRequests != null)
{
+ List keysToRemove = null;
+
lock (HttpListLock)
{
- HttpRequestClass tmpReq;
- if (m_pendingRequests.TryGetValue(m_itemID, out tmpReq))
+ foreach (HttpRequestClass req in m_pendingRequests.Values)
{
- tmpReq.Stop();
- m_pendingRequests.Remove(m_itemID);
+ if (req.ItemID == id)
+ {
+ req.Stop();
+
+ if (keysToRemove == null)
+ keysToRemove = new List();
+
+ keysToRemove.Add(req.ReqID);
+ }
}
+
+ if (keysToRemove != null)
+ keysToRemove.ForEach(keyToRemove => m_pendingRequests.Remove(keyToRemove));
}
}
}
@@ -362,6 +376,8 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
public class HttpRequestClass: IServiceRequest
{
+// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
// Constants for parameters
// public const int HTTP_BODY_MAXLENGTH = 2;
// public const int HTTP_METHOD = 0;
@@ -419,12 +435,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
public void Process()
{
- httpThread = new Thread(SendRequest);
- httpThread.Name = "HttpRequestThread";
- httpThread.Priority = ThreadPriority.BelowNormal;
- httpThread.IsBackground = true;
- _finished = false;
- httpThread.Start();
+ SendRequest();
}
/*
@@ -435,10 +446,6 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
public void SendRequest()
{
HttpWebResponse response = null;
- StringBuilder sb = new StringBuilder();
- byte[] buf = new byte[8192];
- string tempString = null;
- int count = 0;
try
{
@@ -497,11 +504,12 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
bstream.Close();
}
- Request.Timeout = HttpTimeout;
try
{
- // execute the request
- response = (HttpWebResponse) Request.GetResponse();
+ IAsyncResult result = (IAsyncResult)Request.BeginGetResponse(ResponseCallback, null);
+
+ ThreadPool.RegisterWaitForSingleObject(
+ result.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), null, HttpTimeout, true);
}
catch (WebException e)
{
@@ -510,11 +518,31 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
throw;
}
response = (HttpWebResponse)e.Response;
+ _finished = true;
}
+ }
+ catch (Exception e)
+ {
+ Status = (int)OSHttpStatusCode.ClientErrorJoker;
+ ResponseBody = e.Message;
+ _finished = true;
+ }
+ }
+ private void ResponseCallback(IAsyncResult ar)
+ {
+ HttpWebResponse response = null;
+
+ try
+ {
+ response = (HttpWebResponse)Request.EndGetResponse(ar);
Status = (int)response.StatusCode;
Stream resStream = response.GetResponseStream();
+ StringBuilder sb = new StringBuilder();
+ byte[] buf = new byte[8192];
+ string tempString = null;
+ int count = 0;
do
{
@@ -530,36 +558,40 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
// continue building the string
sb.Append(tempString);
}
- } while (count > 0); // any more data to read?
+ }
+ while (count > 0); // any more data to read?
- ResponseBody = sb.ToString();
+ ResponseBody = sb.ToString();
}
catch (Exception e)
{
Status = (int)OSHttpStatusCode.ClientErrorJoker;
ResponseBody = e.Message;
- _finished = true;
- return;
+// m_log.Debug(
+// string.Format("[SCRIPTS HTTP REQUESTS]: Exception on response to {0} for {1} ", Url, ItemID), e);
}
finally
{
if (response != null)
response.Close();
+
+ _finished = true;
}
+ }
- _finished = true;
+ private void TimeoutCallback(object state, bool timedOut)
+ {
+ if (timedOut)
+ Request.Abort();
}
public void Stop()
{
- try
- {
- httpThread.Abort();
- }
- catch (Exception)
- {
- }
+// m_log.DebugFormat("[SCRIPTS HTTP REQUESTS]: Stopping request to {0} for {1} ", Url, ItemID);
+
+ if (Request != null)
+ Request.Abort();
}
}
}
diff --git a/OpenSim/Region/Framework/Interfaces/IHttpRequests.cs b/OpenSim/Region/Framework/Interfaces/IHttpRequests.cs
index eb6c5ac..113dcd7 100644
--- a/OpenSim/Region/Framework/Interfaces/IHttpRequests.cs
+++ b/OpenSim/Region/Framework/Interfaces/IHttpRequests.cs
@@ -45,7 +45,13 @@ namespace OpenSim.Region.Framework.Interfaces
{
UUID MakeHttpRequest(string url, string parameters, string body);
UUID StartHttpRequest(uint localID, UUID itemID, string url, List parameters, Dictionary headers, string body);
- void StopHttpRequest(uint m_localID, UUID m_itemID);
+
+ ///
+ /// Stop and remove all http requests for the given script.
+ ///
+ ///
+ void StopHttpRequestsForScript(UUID id);
+
IServiceRequest GetNextCompletedRequest();
void RemoveCompletedRequest(UUID id);
}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
index 47a9cdc..1c59624 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
@@ -28,7 +28,9 @@
using System;
using System.Collections;
using System.Collections.Generic;
+using System.Reflection;
using System.Threading;
+using log4net;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Framework.Monitoring;
@@ -45,6 +47,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
///
public class AsyncCommandManager
{
+// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
private static Thread cmdHandlerThread;
private static int cmdHandlerThreadCycleSleepms;
@@ -225,6 +229,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
///
public static void RemoveScript(IScriptEngine engine, uint localID, UUID itemID)
{
+// m_log.DebugFormat("[ASYNC COMMAND MANAGER]: Removing facilities for script {0}", itemID);
+
// Remove a specific script
// Remove dataserver events
@@ -236,7 +242,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
// Remove from: HttpRequest
IHttpRequestModule iHttpReq = engine.World.RequestModuleInterface();
if (iHttpReq != null)
- iHttpReq.StopHttpRequest(localID, itemID);
+ iHttpReq.StopHttpRequestsForScript(itemID);
IWorldComm comms = engine.World.RequestModuleInterface();
if (comms != null)
--
cgit v1.1
From f281a994e8544d95961ef669a0fe14c0cba7f175 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 4 Apr 2013 00:49:07 +0100
Subject: refactor: Simplify ScriptsHttpRequests.GetNextCompletedRequest to
more simply iterate through pending requests without unnecessary checks.
---
.../Scripting/HttpRequest/ScriptsHttpRequests.cs | 14 ++++----------
1 file changed, 4 insertions(+), 10 deletions(-)
diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
index 1c251b8..ebf56cd 100644
--- a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
+++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
@@ -293,19 +293,13 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
{
lock (HttpListLock)
{
- foreach (UUID luid in m_pendingRequests.Keys)
+ foreach (HttpRequestClass req in m_pendingRequests.Values)
{
- HttpRequestClass tmpReq;
-
- if (m_pendingRequests.TryGetValue(luid, out tmpReq))
- {
- if (tmpReq.Finished)
- {
- return tmpReq;
- }
- }
+ if (req.Finished)
+ return req;
}
}
+
return null;
}
--
cgit v1.1
From f064075a85962039f4737ec9ca631c377a6197c9 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 4 Apr 2013 01:06:57 +0100
Subject: Fix XmlRpcAdmin admin_exists_user call so that it actually returns
the last user login time rather than serializing the DateTime directly which
generates a set of unexpected fields.
lastlogin return is in unix timestamp format.
---
OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs
index 5d44b2a..d19b8b6 100644
--- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs
+++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs
@@ -1094,7 +1094,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
{
GridUserInfo userInfo = m_application.SceneManager.CurrentOrFirstScene.GridUserService.GetGridUserInfo(account.PrincipalID.ToString());
if (userInfo != null)
- responseData["lastlogin"] = userInfo.Login;
+ responseData["lastlogin"] = Util.ToUnixTime(userInfo.Login);
else
responseData["lastlogin"] = 0;
--
cgit v1.1
From d2367968e4227f8a6e37d22ed5904c4f1d87a15e Mon Sep 17 00:00:00 2001
From: teravus
Date: Thu, 4 Apr 2013 19:10:23 -0400
Subject: * In between the fog, a moment of clarity. This fixes mantis 6570
---
OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
index dfdd566..96a030b 100644
--- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
+++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
@@ -453,7 +453,7 @@ namespace OpenSim.Framework.Servers.HttpServer
}
OSHttpResponse resp = new OSHttpResponse(new HttpResponse(context, request),context);
-
+ resp.ReuseContext = true;
HandleRequest(req, resp);
--
cgit v1.1
From 0f008d5f7d4a34d4f7529036f5dd83742423c42f Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Sat, 6 Apr 2013 01:44:06 +0100
Subject: When rezzing a coalesced object, check adjust position of all
components.
---
.../InventoryAccess/InventoryAccessModule.cs | 47 +++++++++++++---------
1 file changed, 27 insertions(+), 20 deletions(-)
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index eaf4ce2..ebada5a 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -807,7 +807,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
}
}
- if (item != null && !DoPreRezWhenFromItem(remoteClient, item, objlist, pos, attachment))
+ if (item != null && !DoPreRezWhenFromItem(remoteClient, item, objlist, pos, veclist, attachment))
return null;
for (int i = 0; i < objlist.Count; i++)
@@ -905,10 +905,15 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
///
///
///
+ ///
+ /// List of vector position adjustments for a coalesced objects. For ordinary objects
+ /// this list will contain just Vector3.Zero. The order of adjustments must match the order of objlist
+ ///
///
/// true if we can processed with rezzing, false if we need to abort
private bool DoPreRezWhenFromItem(
- IClientAPI remoteClient, InventoryItemBase item, List objlist, Vector3 pos, bool isAttachment)
+ IClientAPI remoteClient, InventoryItemBase item, List objlist,
+ Vector3 pos, List veclist, bool isAttachment)
{
UUID fromUserInventoryItemId = UUID.Zero;
@@ -932,27 +937,29 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
}
int primcount = 0;
- foreach (SceneObjectGroup g in objlist)
- primcount += g.PrimCount;
-
- if (!m_Scene.Permissions.CanRezObject(
- primcount, remoteClient.AgentId, pos)
- && !isAttachment)
+ for(int i = 0; i < objlist.Count; i++)
{
- // The client operates in no fail mode. It will
- // have already removed the item from the folder
- // if it's no copy.
- // Put it back if it's not an attachment
- //
- if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!isAttachment))
- remoteClient.SendBulkUpdateInventory(item);
+ SceneObjectGroup g = objlist[i];
+
+ if (!m_Scene.Permissions.CanRezObject(
+ g.PrimCount, remoteClient.AgentId, pos + veclist[i])
+ && !isAttachment)
+ {
+ // The client operates in no fail mode. It will
+ // have already removed the item from the folder
+ // if it's no copy.
+ // Put it back if it's not an attachment
+ //
+ if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!isAttachment))
+ remoteClient.SendBulkUpdateInventory(item);
- ILandObject land = m_Scene.LandChannel.GetLandObject(pos.X, pos.Y);
- remoteClient.SendAlertMessage(string.Format(
- "Can't rez object '{0}' at <{1:F3}, {2:F3}, {3:F3}> on parcel '{4}' in region {5}.",
- item.Name, pos.X, pos.Y, pos.Z, land != null ? land.LandData.Name : "Unknown", m_Scene.RegionInfo.RegionName));
+ ILandObject land = m_Scene.LandChannel.GetLandObject(pos.X, pos.Y);
+ remoteClient.SendAlertMessage(string.Format(
+ "Can't rez object '{0}' at <{1:F3}, {2:F3}, {3:F3}> on parcel '{4}' in region {5}.",
+ item.Name, pos.X, pos.Y, pos.Z, land != null ? land.LandData.Name : "Unknown", m_Scene.Name));
- return false;
+ return false;
+ }
}
for (int i = 0; i < objlist.Count; i++)
--
cgit v1.1
From 7f070236f72058ba22d017048b978adea380f0a1 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Sat, 6 Apr 2013 02:34:51 +0100
Subject: Fix taking (and rezzing) of coalesced objects in the non-root
subregions of megaregions.
This fixes the combined bounding box location for regions bigger than 256x256.
It also fixes the position on taking coalesced objects in the non-root regions, where position checks are properly done on rez instead.
It also fixes the megaregion land channel to return null if the land does not exist, which should probably also be done for the ordinary land channels rather than returning a dummy region.
Inspiration from Garmin's commit in http://opensimulator.org/mantis/view.php?id=6595. Thanks!
---
.../InventoryAccess/InventoryAccessModule.cs | 32 ++++-----
.../World/Permissions/PermissionsModule.cs | 2 +
OpenSim/Region/Framework/Scenes/Scene.cs | 12 ++--
.../RegionCombinerLargeLandChannel.cs | 83 ++++++++++++++--------
4 files changed, 76 insertions(+), 53 deletions(-)
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index ebada5a..f796ec9 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -357,19 +357,19 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
foreach (SceneObjectGroup objectGroup in objlist)
{
- Vector3 inventoryStoredPosition = new Vector3
- (((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize)
- ? 250
- : objectGroup.AbsolutePosition.X)
- ,
- (objectGroup.AbsolutePosition.Y > (int)Constants.RegionSize)
- ? 250
- : objectGroup.AbsolutePosition.Y,
- objectGroup.AbsolutePosition.Z);
-
- originalPositions[objectGroup.UUID] = objectGroup.AbsolutePosition;
-
- objectGroup.AbsolutePosition = inventoryStoredPosition;
+// Vector3 inventoryStoredPosition = new Vector3
+// (((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize)
+// ? 250
+// : objectGroup.AbsolutePosition.X)
+// ,
+// (objectGroup.AbsolutePosition.Y > (int)Constants.RegionSize)
+// ? 250
+// : objectGroup.AbsolutePosition.Y,
+// objectGroup.AbsolutePosition.Z);
+//
+// originalPositions[objectGroup.UUID] = objectGroup.AbsolutePosition;
+//
+// objectGroup.AbsolutePosition = inventoryStoredPosition;
// Make sure all bits but the ones we want are clear
// on take.
@@ -397,9 +397,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
else
itemXml = SceneObjectSerializer.ToOriginalXmlFormat(objlist[0], !asAttachment);
- // Restore the position of each group now that it has been stored to inventory.
- foreach (SceneObjectGroup objectGroup in objlist)
- objectGroup.AbsolutePosition = originalPositions[objectGroup.UUID];
+// // Restore the position of each group now that it has been stored to inventory.
+// foreach (SceneObjectGroup objectGroup in objlist)
+// objectGroup.AbsolutePosition = originalPositions[objectGroup.UUID];
InventoryItemBase item = CreateItemForObject(action, remoteClient, objlist[0], folderID);
diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
index 79dd4a0..77299be 100644
--- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
@@ -1453,6 +1453,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions
bool permission = false;
+ m_log.DebugFormat("[PERMISSIONS MODULE]: Checking rez object at {0} in {1}", objectPosition, m_scene.Name);
+
ILandObject land = m_scene.LandChannel.GetLandObject(objectPosition.X, objectPosition.Y);
if (land == null) return false;
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 911a3e4..f50d3cd 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -5361,12 +5361,12 @@ namespace OpenSim.Region.Framework.Scenes
List objects,
out float minX, out float maxX, out float minY, out float maxY, out float minZ, out float maxZ)
{
- minX = 256;
- maxX = -256;
- minY = 256;
- maxY = -256;
- minZ = 8192;
- maxZ = -256;
+ minX = float.MaxValue;
+ maxX = float.MinValue;
+ minY = float.MaxValue;
+ maxY = float.MinValue;
+ minZ = float.MaxValue;
+ maxZ = float.MinValue;
List offsets = new List();
diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerLargeLandChannel.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerLargeLandChannel.cs
index b4abc1d..4bf2a82 100644
--- a/OpenSim/Region/RegionCombinerModule/RegionCombinerLargeLandChannel.cs
+++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerLargeLandChannel.cs
@@ -27,6 +27,8 @@
using System;
using System.Collections.Generic;
+using System.Reflection;
+using log4net;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces;
@@ -34,10 +36,10 @@ using OpenSim.Region.CoreModules.World.Land;
namespace OpenSim.Region.RegionCombinerModule
{
-public class RegionCombinerLargeLandChannel : ILandChannel
+ public class RegionCombinerLargeLandChannel : ILandChannel
{
- // private static readonly ILog m_log =
- // LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
private RegionData RegData;
private ILandChannel RootRegionLandChannel;
private readonly List RegionConnections;
@@ -75,40 +77,51 @@ public class RegionCombinerLargeLandChannel : ILandChannel
public ILandObject GetLandObject(int x, int y)
{
- //m_log.DebugFormat("[BIGLANDTESTINT]: <{0},{1}>", x, y);
-
- if (x > 0 && x <= (int)Constants.RegionSize && y > 0 && y <= (int)Constants.RegionSize)
- {
- return RootRegionLandChannel.GetLandObject(x, y);
- }
- else
- {
- int offsetX = (x / (int)Constants.RegionSize);
- int offsetY = (y / (int)Constants.RegionSize);
- offsetX *= (int)Constants.RegionSize;
- offsetY *= (int)Constants.RegionSize;
-
- foreach (RegionData regionData in RegionConnections)
- {
- if (regionData.Offset.X == offsetX && regionData.Offset.Y == offsetY)
- {
- return regionData.RegionScene.LandChannel.GetLandObject(x - offsetX, y - offsetY);
- }
- }
- ILandObject obj = new LandObject(UUID.Zero, false, RegData.RegionScene);
- obj.LandData.Name = "NO LAND";
- return obj;
- }
+ return GetLandObject((float)x, (float)y);
+
+// m_log.DebugFormat("[BIGLANDTESTINT]: <{0},{1}>", x, y);
+//
+// if (x > 0 && x <= (int)Constants.RegionSize && y > 0 && y <= (int)Constants.RegionSize)
+// {
+// return RootRegionLandChannel.GetLandObject(x, y);
+// }
+// else
+// {
+// int offsetX = (x / (int)Constants.RegionSize);
+// int offsetY = (y / (int)Constants.RegionSize);
+// offsetX *= (int)Constants.RegionSize;
+// offsetY *= (int)Constants.RegionSize;
+//
+// foreach (RegionData regionData in RegionConnections)
+// {
+// if (regionData.Offset.X == offsetX && regionData.Offset.Y == offsetY)
+// {
+// m_log.DebugFormat(
+// "[REGION COMBINER LARGE LAND CHANNEL]: Found region {0} at offset {1},{2}",
+// regionData.RegionScene.Name, offsetX, offsetY);
+//
+// return regionData.RegionScene.LandChannel.GetLandObject(x - offsetX, y - offsetY);
+// }
+// }
+// //ILandObject obj = new LandObject(UUID.Zero, false, RegData.RegionScene);
+// //obj.LandData.Name = "NO LAND";
+// //return obj;
+// }
+//
+// m_log.DebugFormat("[REGION COMBINER LARGE LAND CHANNEL]: No region found at {0},{1}, returning null", x, y);
+//
+// return null;
}
public ILandObject GetLandObject(int localID)
{
+ // XXX: Possibly should be looking in every land channel, not just the root.
return RootRegionLandChannel.GetLandObject(localID);
}
public ILandObject GetLandObject(float x, float y)
{
- //m_log.DebugFormat("[BIGLANDTESTFLOAT]: <{0},{1}>", x, y);
+// m_log.DebugFormat("[BIGLANDTESTFLOAT]: <{0},{1}>", x, y);
if (x > 0 && x <= (int)Constants.RegionSize && y > 0 && y <= (int)Constants.RegionSize)
{
@@ -125,14 +138,22 @@ public class RegionCombinerLargeLandChannel : ILandChannel
{
if (regionData.Offset.X == offsetX && regionData.Offset.Y == offsetY)
{
+// m_log.DebugFormat(
+// "[REGION COMBINER LARGE LAND CHANNEL]: Found region {0} at offset {1},{2}",
+// regionData.RegionScene.Name, offsetX, offsetY);
+
return regionData.RegionScene.LandChannel.GetLandObject(x - offsetX, y - offsetY);
}
}
- ILandObject obj = new LandObject(UUID.Zero, false, RegData.RegionScene);
- obj.LandData.Name = "NO LAND";
- return obj;
+// ILandObject obj = new LandObject(UUID.Zero, false, RegData.RegionScene);
+// obj.LandData.Name = "NO LAND";
+// return obj;
}
+
+// m_log.DebugFormat("[REGION COMBINER LARGE LAND CHANNEL]: No region found at {0},{1}, returning null", x, y);
+
+ return null;
}
public bool IsForcefulBansAllowed()
--
cgit v1.1
From c7cd077e55c2e889f61bb2e28cd3254b15e07567 Mon Sep 17 00:00:00 2001
From: Mic Bowman
Date: Sun, 7 Apr 2013 17:31:44 -0700
Subject: Optimize the number of Simian calls to get the initial presence
information for the friends list. This is a pretty big performance
improvement on login. Note that you must upgrade simian to incorporate the
corresponding GetSessions call.
---
.../SimianGrid/SimianPresenceServiceConnector.cs | 193 +++++++++------------
1 file changed, 83 insertions(+), 110 deletions(-)
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs
index 854bea4..7bb06fb 100644
--- a/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs
@@ -137,10 +137,11 @@ namespace OpenSim.Services.Connectors.SimianGrid
userID, sessionID, secureSessionID);
NameValueCollection requestArgs = new NameValueCollection
- {
- { "RequestMethod", "AddSession" },
- { "UserID", userID.ToString() }
- };
+ {
+ { "RequestMethod", "AddSession" },
+ { "UserID", userID.ToString() }
+ };
+
if (sessionID != UUID.Zero)
{
requestArgs["SessionID"] = sessionID.ToString();
@@ -158,13 +159,13 @@ namespace OpenSim.Services.Connectors.SimianGrid
public bool LogoutAgent(UUID sessionID)
{
-// m_log.InfoFormat("[SIMIAN PRESENCE CONNECTOR]: Logout requested for agent with sessionID " + sessionID);
+ // m_log.InfoFormat("[SIMIAN PRESENCE CONNECTOR]: Logout requested for agent with sessionID " + sessionID);
NameValueCollection requestArgs = new NameValueCollection
- {
- { "RequestMethod", "RemoveSession" },
- { "SessionID", sessionID.ToString() }
- };
+ {
+ { "RequestMethod", "RemoveSession" },
+ { "SessionID", sessionID.ToString() }
+ };
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
bool success = response["Success"].AsBoolean();
@@ -177,13 +178,13 @@ namespace OpenSim.Services.Connectors.SimianGrid
public bool LogoutRegionAgents(UUID regionID)
{
-// m_log.InfoFormat("[SIMIAN PRESENCE CONNECTOR]: Logout requested for all agents in region " + regionID);
+ // m_log.InfoFormat("[SIMIAN PRESENCE CONNECTOR]: Logout requested for all agents in region " + regionID);
NameValueCollection requestArgs = new NameValueCollection
- {
- { "RequestMethod", "RemoveSessions" },
- { "SceneID", regionID.ToString() }
- };
+ {
+ { "RequestMethod", "RemoveSessions" },
+ { "SceneID", regionID.ToString() }
+ };
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
bool success = response["Success"].AsBoolean();
@@ -202,49 +203,46 @@ namespace OpenSim.Services.Connectors.SimianGrid
public PresenceInfo GetAgent(UUID sessionID)
{
-// m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Requesting session data for agent with sessionID " + sessionID);
-
- NameValueCollection requestArgs = new NameValueCollection
- {
- { "RequestMethod", "GetSession" },
- { "SessionID", sessionID.ToString() }
- };
-
- OSDMap sessionResponse = WebUtil.PostToService(m_serverUrl, requestArgs);
- if (sessionResponse["Success"].AsBoolean())
+ OSDMap sessionResponse = GetSessionDataFromSessionID(sessionID);
+ if (sessionResponse == null)
{
- UUID userID = sessionResponse["UserID"].AsUUID();
- m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Requesting user data for " + userID);
-
- requestArgs = new NameValueCollection
- {
- { "RequestMethod", "GetUser" },
- { "UserID", userID.ToString() }
- };
-
- OSDMap userResponse = WebUtil.PostToService(m_serverUrl, requestArgs);
- if (userResponse["Success"].AsBoolean())
- return ResponseToPresenceInfo(sessionResponse, userResponse);
- else
- m_log.Warn("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve user data for " + userID + ": " + userResponse["Message"].AsString());
+ m_log.WarnFormat("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve session {0}: {1}",sessionID.ToString(),sessionResponse["Message"].AsString());
+ return null;
}
- else
+
+ UUID userID = sessionResponse["UserID"].AsUUID();
+ OSDMap userResponse = GetUserData(userID);
+ if (userResponse == null)
{
- m_log.Warn("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve session " + sessionID + ": " + sessionResponse["Message"].AsString());
+ m_log.WarnFormat("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve user data for {0}: {1}",userID.ToString(),userResponse["Message"].AsString());
+ return null;
}
- return null;
+ return ResponseToPresenceInfo(sessionResponse);
}
public PresenceInfo[] GetAgents(string[] userIDs)
{
- List presences = new List(userIDs.Length);
+ List presences = new List();
- for (int i = 0; i < userIDs.Length; i++)
+ NameValueCollection requestArgs = new NameValueCollection
+ {
+ { "RequestMethod", "GetSessions" },
+ { "UserIDList", String.Join(",",userIDs) }
+ };
+
+ OSDMap sessionListResponse = WebUtil.PostToService(m_serverUrl, requestArgs);
+ if (! sessionListResponse["Success"].AsBoolean())
{
- UUID userID;
- if (UUID.TryParse(userIDs[i], out userID) && userID != UUID.Zero)
- presences.AddRange(GetSessions(userID));
+ m_log.WarnFormat("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve sessions: {0}",sessionListResponse["Message"].AsString());
+ return null;
+ }
+
+ OSDArray sessionList = sessionListResponse["Sessions"] as OSDArray;
+ for (int i = 0; i < sessionList.Count; i++)
+ {
+ OSDMap sessionInfo = sessionList[i] as OSDMap;
+ presences.Add(ResponseToPresenceInfo(sessionInfo));
}
return presences.ToArray();
@@ -262,7 +260,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
public bool LoggedOut(string userID, UUID sessionID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt)
{
-// m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Logging out user " + userID);
+ // m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Logging out user " + userID);
// Remove the session to mark this user offline
if (!LogoutAgent(sessionID))
@@ -270,11 +268,11 @@ namespace OpenSim.Services.Connectors.SimianGrid
// Save our last position as user data
NameValueCollection requestArgs = new NameValueCollection
- {
- { "RequestMethod", "AddUserData" },
- { "UserID", userID.ToString() },
- { "LastLocation", SerializeLocation(regionID, lastPosition, lastLookAt) }
- };
+ {
+ { "RequestMethod", "AddUserData" },
+ { "UserID", userID.ToString() },
+ { "LastLocation", SerializeLocation(regionID, lastPosition, lastLookAt) }
+ };
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
bool success = response["Success"].AsBoolean();
@@ -287,14 +285,14 @@ namespace OpenSim.Services.Connectors.SimianGrid
public bool SetHome(string userID, UUID regionID, Vector3 position, Vector3 lookAt)
{
-// m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Setting home location for user " + userID);
+ // m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Setting home location for user " + userID);
NameValueCollection requestArgs = new NameValueCollection
- {
- { "RequestMethod", "AddUserData" },
- { "UserID", userID.ToString() },
- { "HomeLocation", SerializeLocation(regionID, position, lookAt) }
- };
+ {
+ { "RequestMethod", "AddUserData" },
+ { "UserID", userID.ToString() },
+ { "HomeLocation", SerializeLocation(regionID, position, lookAt) }
+ };
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
bool success = response["Success"].AsBoolean();
@@ -312,23 +310,14 @@ namespace OpenSim.Services.Connectors.SimianGrid
public GridUserInfo GetGridUserInfo(string user)
{
-// m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Requesting session data for agent " + user);
+ // m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Requesting session data for agent " + user);
UUID userID = new UUID(user);
-// m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Requesting user data for " + userID);
-
- NameValueCollection requestArgs = new NameValueCollection
- {
- { "RequestMethod", "GetUser" },
- { "UserID", userID.ToString() }
- };
-
- OSDMap userResponse = WebUtil.PostToService(m_serverUrl, requestArgs);
- if (userResponse["Success"].AsBoolean())
+ OSDMap userResponse = GetUserData(userID);
+ if (userResponse != null)
return ResponseToGridUserInfo(userResponse);
- else
- m_log.Warn("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve user data for " + userID + ": " + userResponse["Message"].AsString());
+ m_log.WarnFormat("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve user data for {0}: {1}",userID,userResponse["Message"].AsString());
return null;
}
@@ -338,65 +327,49 @@ namespace OpenSim.Services.Connectors.SimianGrid
private OSDMap GetUserData(UUID userID)
{
-// m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Requesting user data for " + userID);
+ // m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Requesting user data for " + userID);
NameValueCollection requestArgs = new NameValueCollection
- {
- { "RequestMethod", "GetUser" },
- { "UserID", userID.ToString() }
- };
+ {
+ { "RequestMethod", "GetUser" },
+ { "UserID", userID.ToString() }
+ };
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
if (response["Success"].AsBoolean() && response["User"] is OSDMap)
return response;
- else
- m_log.Warn("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve user data for " + userID + ": " + response["Message"].AsString());
+ m_log.WarnFormat("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve user data for {0}; {1}",userID.ToString(),response["Message"].AsString());
return null;
}
- private List GetSessions(UUID userID)
+ private OSDMap GetSessionDataFromSessionID(UUID sessionID)
{
- List presences = new List(1);
-
- OSDMap userResponse = GetUserData(userID);
- if (userResponse != null)
- {
-// m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Requesting sessions for " + userID);
-
- NameValueCollection requestArgs = new NameValueCollection
+ NameValueCollection requestArgs = new NameValueCollection
{
- { "RequestMethod", "GetSession" },
- { "UserID", userID.ToString() }
+ { "RequestMethod", "GetSession" },
+ { "SessionID", sessionID.ToString() }
};
- OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
- if (response["Success"].AsBoolean())
- {
- PresenceInfo presence = ResponseToPresenceInfo(response, userResponse);
- if (presence != null)
- presences.Add(presence);
- }
-// else
-// {
-// m_log.Debug("[SIMIAN PRESENCE CONNECTOR]: No session returned for " + userID + ": " + response["Message"].AsString());
-// }
- }
+ OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
+ if (response["Success"].AsBoolean())
+ return response;
- return presences;
+ m_log.WarnFormat("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve session data for {0}; {1}",sessionID.ToString(),response["Message"].AsString());
+ return null;
}
private bool UpdateSession(UUID sessionID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt)
{
// Save our current location as session data
NameValueCollection requestArgs = new NameValueCollection
- {
- { "RequestMethod", "UpdateSession" },
- { "SessionID", sessionID.ToString() },
- { "SceneID", regionID.ToString() },
- { "ScenePosition", lastPosition.ToString() },
- { "SceneLookAt", lastLookAt.ToString() }
- };
+ {
+ { "RequestMethod", "UpdateSession" },
+ { "SessionID", sessionID.ToString() },
+ { "SceneID", regionID.ToString() },
+ { "ScenePosition", lastPosition.ToString() },
+ { "SceneLookAt", lastLookAt.ToString() }
+ };
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
bool success = response["Success"].AsBoolean();
@@ -407,7 +380,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
return success;
}
- private PresenceInfo ResponseToPresenceInfo(OSDMap sessionResponse, OSDMap userResponse)
+ private PresenceInfo ResponseToPresenceInfo(OSDMap sessionResponse)
{
if (sessionResponse == null)
return null;
--
cgit v1.1
From fe16dc09da3f2736fad5a9e792f5f81098b5f9a1 Mon Sep 17 00:00:00 2001
From: Robert Adams
Date: Sun, 7 Apr 2013 08:27:49 -0700
Subject: BulletSim: complete movement of physical object action code out of
the physical object and into actors for setForce, setTorque, hover, lock axis
and avatar move.
---
.../Physics/BulletSPlugin/BSActorAvatarMove.cs | 287 +++++++++++++++++++
.../Region/Physics/BulletSPlugin/BSActorHover.cs | 176 ++++++++++++
.../Physics/BulletSPlugin/BSActorLockAxis.cs | 4 +-
.../Physics/BulletSPlugin/BSActorMoveToTarget.cs | 156 +++++++++++
.../Physics/BulletSPlugin/BSActorSetForce.cs | 137 +++++++++
.../Physics/BulletSPlugin/BSActorSetTorque.cs | 138 +++++++++
OpenSim/Region/Physics/BulletSPlugin/BSActors.cs | 12 +-
.../Region/Physics/BulletSPlugin/BSCharacter.cs | 268 +++---------------
.../Region/Physics/BulletSPlugin/BSPhysObject.cs | 226 ++++++---------
OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 307 ++++-----------------
.../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 3 +-
11 files changed, 1078 insertions(+), 636 deletions(-)
create mode 100755 OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs
create mode 100755 OpenSim/Region/Physics/BulletSPlugin/BSActorHover.cs
create mode 100755 OpenSim/Region/Physics/BulletSPlugin/BSActorMoveToTarget.cs
create mode 100755 OpenSim/Region/Physics/BulletSPlugin/BSActorSetForce.cs
create mode 100755 OpenSim/Region/Physics/BulletSPlugin/BSActorSetTorque.cs
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs b/OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs
new file mode 100755
index 0000000..634a898
--- /dev/null
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyrightD
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+using OpenSim.Region.Physics.Manager;
+
+using OMV = OpenMetaverse;
+
+namespace OpenSim.Region.Physics.BulletSPlugin
+{
+public class BSActorAvatarMove : BSActor
+{
+ BSVMotor m_velocityMotor;
+
+ public BSActorAvatarMove(BSScene physicsScene, BSPhysObject pObj, string actorName)
+ : base(physicsScene, pObj, actorName)
+ {
+ m_velocityMotor = null;
+ m_physicsScene.DetailLog("{0},BSActorAvatarMove,constructor", m_controllingPrim.LocalID);
+ }
+
+ // BSActor.isActive
+ public override bool isActive
+ {
+ get { return Enabled && m_controllingPrim.IsPhysicallyActive; }
+ }
+
+ // Release any connections and resources used by the actor.
+ // BSActor.Dispose()
+ public override void Dispose()
+ {
+ Enabled = false;
+ }
+
+ // Called when physical parameters (properties set in Bullet) need to be re-applied.
+ // Called at taint-time.
+ // BSActor.Refresh()
+ public override void Refresh()
+ {
+ m_physicsScene.DetailLog("{0},BSActorAvatarMove,refresh", m_controllingPrim.LocalID);
+
+ // If not active any more, get rid of me (shouldn't ever happen, but just to be safe)
+ if (m_controllingPrim.RawForce == OMV.Vector3.Zero)
+ {
+ m_physicsScene.DetailLog("{0},BSActorAvatarMove,refresh,notAvatarMove,removing={1}", m_controllingPrim.LocalID, ActorName);
+ m_controllingPrim.PhysicalActors.RemoveAndRelease(ActorName);
+ return;
+ }
+
+ // If the object is physically active, add the hoverer prestep action
+ if (isActive)
+ {
+ ActivateAvatarMove();
+ }
+ else
+ {
+ DeactivateAvatarMove();
+ }
+ }
+
+ // The object's physical representation is being rebuilt so pick up any physical dependencies (constraints, ...).
+ // Register a prestep action to restore physical requirements before the next simulation step.
+ // Called at taint-time.
+ // BSActor.RemoveBodyDependencies()
+ public override void RemoveBodyDependencies()
+ {
+ // Nothing to do for the hoverer since it is all software at pre-step action time.
+ }
+
+ public void SetVelocityAndTarget(OMV.Vector3 vel, OMV.Vector3 targ, bool inTaintTime)
+ {
+ m_physicsScene.TaintedObject(inTaintTime, "BSActorAvatarMove.setVelocityAndTarget", delegate()
+ {
+ m_velocityMotor.Reset();
+ m_velocityMotor.SetTarget(targ);
+ m_velocityMotor.SetCurrent(vel);
+ m_velocityMotor.Enabled = true;
+ });
+ }
+
+ // If a hover motor has not been created, create one and start the hovering.
+ private void ActivateAvatarMove()
+ {
+ if (m_velocityMotor == null)
+ {
+ // Infinite decay and timescale values so motor only changes current to target values.
+ m_velocityMotor = new BSVMotor("BSCharacter.Velocity",
+ 0.2f, // time scale
+ BSMotor.Infinite, // decay time scale
+ BSMotor.InfiniteVector, // friction timescale
+ 1f // efficiency
+ );
+ // _velocityMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages.
+
+ m_physicsScene.BeforeStep += Mover;
+ }
+ }
+
+ private void DeactivateAvatarMove()
+ {
+ if (m_velocityMotor != null)
+ {
+ m_physicsScene.BeforeStep -= Mover;
+ m_velocityMotor = null;
+ }
+ }
+
+ // Called just before the simulation step. Update the vertical position for hoverness.
+ private void Mover(float timeStep)
+ {
+ // Don't do movement while the object is selected.
+ if (!isActive)
+ return;
+
+ // TODO: Decide if the step parameters should be changed depending on the avatar's
+ // state (flying, colliding, ...). There is code in ODE to do this.
+
+ // COMMENTARY: when the user is making the avatar walk, except for falling, the velocity
+ // specified for the avatar is the one that should be used. For falling, if the avatar
+ // is not flying and is not colliding then it is presumed to be falling and the Z
+ // component is not fooled with (thus allowing gravity to do its thing).
+ // When the avatar is standing, though, the user has specified a velocity of zero and
+ // the avatar should be standing. But if the avatar is pushed by something in the world
+ // (raising elevator platform, moving vehicle, ...) the avatar should be allowed to
+ // move. Thus, the velocity cannot be forced to zero. The problem is that small velocity
+ // errors can creap in and the avatar will slowly float off in some direction.
+ // So, the problem is that, when an avatar is standing, we cannot tell creaping error
+ // from real pushing.
+ // The code below uses whether the collider is static or moving to decide whether to zero motion.
+
+ m_velocityMotor.Step(timeStep);
+ m_controllingPrim.IsStationary = false;
+
+ // If we're not supposed to be moving, make sure things are zero.
+ if (m_velocityMotor.ErrorIsZero() && m_velocityMotor.TargetValue == OMV.Vector3.Zero)
+ {
+ // The avatar shouldn't be moving
+ m_velocityMotor.Zero();
+
+ if (m_controllingPrim.IsColliding)
+ {
+ // If we are colliding with a stationary object, presume we're standing and don't move around
+ if (!m_controllingPrim.ColliderIsMoving)
+ {
+ m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,zeroingMotion", m_controllingPrim.LocalID);
+ m_controllingPrim.IsStationary = true;
+ m_controllingPrim.ZeroMotion(true /* inTaintTime */);
+ }
+
+ // Standing has more friction on the ground
+ if (m_controllingPrim.Friction != BSParam.AvatarStandingFriction)
+ {
+ m_controllingPrim.Friction = BSParam.AvatarStandingFriction;
+ m_physicsScene.PE.SetFriction(m_controllingPrim.PhysBody, m_controllingPrim.Friction);
+ }
+ }
+ else
+ {
+ if (m_controllingPrim.Flying)
+ {
+ // Flying and not collising and velocity nearly zero.
+ m_controllingPrim.ZeroMotion(true /* inTaintTime */);
+ }
+ }
+
+ m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,taint,stopping,target={1},colliding={2}",
+ m_controllingPrim.LocalID, m_velocityMotor.TargetValue, m_controllingPrim.IsColliding);
+ }
+ else
+ {
+ // Supposed to be moving.
+ OMV.Vector3 stepVelocity = m_velocityMotor.CurrentValue;
+
+ if (m_controllingPrim.Friction != BSParam.AvatarFriction)
+ {
+ // Probably starting up walking. Set friction to moving friction.
+ m_controllingPrim.Friction = BSParam.AvatarFriction;
+ m_physicsScene.PE.SetFriction(m_controllingPrim.PhysBody, m_controllingPrim.Friction);
+ }
+
+ // If falling, we keep the world's downward vector no matter what the other axis specify.
+ // The check for RawVelocity.Z < 0 makes jumping work (temporary upward force).
+ if (!m_controllingPrim.Flying && !m_controllingPrim.IsColliding)
+ {
+ if (m_controllingPrim.RawVelocity.Z < 0)
+ stepVelocity.Z = m_controllingPrim.RawVelocity.Z;
+ // DetailLog("{0},BSCharacter.MoveMotor,taint,overrideStepZWithWorldZ,stepVel={1}", LocalID, stepVelocity);
+ }
+
+ // 'stepVelocity' is now the speed we'd like the avatar to move in. Turn that into an instantanous force.
+ OMV.Vector3 moveForce = (stepVelocity - m_controllingPrim.RawVelocity) * m_controllingPrim.Mass;
+
+ // Should we check for move force being small and forcing velocity to zero?
+
+ // Add special movement force to allow avatars to walk up stepped surfaces.
+ moveForce += WalkUpStairs();
+
+ m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}",
+ m_controllingPrim.LocalID, stepVelocity, m_controllingPrim.RawVelocity, m_controllingPrim.Mass, moveForce);
+ m_physicsScene.PE.ApplyCentralImpulse(m_controllingPrim.PhysBody, moveForce);
+ }
+ }
+
+ // Decide if the character is colliding with a low object and compute a force to pop the
+ // avatar up so it can walk up and over the low objects.
+ private OMV.Vector3 WalkUpStairs()
+ {
+ OMV.Vector3 ret = OMV.Vector3.Zero;
+
+ // This test is done if moving forward, not flying and is colliding with something.
+ // DetailLog("{0},BSCharacter.WalkUpStairs,IsColliding={1},flying={2},targSpeed={3},collisions={4}",
+ // LocalID, IsColliding, Flying, TargetSpeed, CollisionsLastTick.Count);
+ if (m_controllingPrim.IsColliding && !m_controllingPrim.Flying && m_controllingPrim.TargetVelocitySpeed > 0.1f /* && ForwardSpeed < 0.1f */)
+ {
+ // The range near the character's feet where we will consider stairs
+ float nearFeetHeightMin = m_controllingPrim.RawPosition.Z - (m_controllingPrim.Size.Z / 2f) + 0.05f;
+ float nearFeetHeightMax = nearFeetHeightMin + BSParam.AvatarStepHeight;
+
+ // Look for a collision point that is near the character's feet and is oriented the same as the charactor is
+ foreach (KeyValuePair kvp in m_controllingPrim.CollisionsLastTick.m_objCollisionList)
+ {
+ // Don't care about collisions with the terrain
+ if (kvp.Key > m_physicsScene.TerrainManager.HighestTerrainID)
+ {
+ OMV.Vector3 touchPosition = kvp.Value.Position;
+ // DetailLog("{0},BSCharacter.WalkUpStairs,min={1},max={2},touch={3}",
+ // LocalID, nearFeetHeightMin, nearFeetHeightMax, touchPosition);
+ if (touchPosition.Z >= nearFeetHeightMin && touchPosition.Z <= nearFeetHeightMax)
+ {
+ // This contact is within the 'near the feet' range.
+ // The normal should be our contact point to the object so it is pointing away
+ // thus the difference between our facing orientation and the normal should be small.
+ OMV.Vector3 directionFacing = OMV.Vector3.UnitX * m_controllingPrim.RawOrientation;
+ OMV.Vector3 touchNormal = OMV.Vector3.Normalize(kvp.Value.SurfaceNormal);
+ float diff = Math.Abs(OMV.Vector3.Distance(directionFacing, touchNormal));
+ if (diff < BSParam.AvatarStepApproachFactor)
+ {
+ // Found the stairs contact point. Push up a little to raise the character.
+ float upForce = (touchPosition.Z - nearFeetHeightMin) * m_controllingPrim.Mass * BSParam.AvatarStepForceFactor;
+ ret = new OMV.Vector3(0f, 0f, upForce);
+
+ // Also move the avatar up for the new height
+ OMV.Vector3 displacement = new OMV.Vector3(0f, 0f, BSParam.AvatarStepHeight / 2f);
+ m_controllingPrim.ForcePosition = m_controllingPrim.RawPosition + displacement;
+ }
+ m_physicsScene.DetailLog("{0},BSCharacter.WalkUpStairs,touchPos={1},nearFeetMin={2},faceDir={3},norm={4},diff={5},ret={6}",
+ m_controllingPrim.LocalID, touchPosition, nearFeetHeightMin, directionFacing, touchNormal, diff, ret);
+ }
+ }
+ }
+ }
+
+ return ret;
+ }
+
+}
+}
+
+
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSActorHover.cs b/OpenSim/Region/Physics/BulletSPlugin/BSActorHover.cs
new file mode 100755
index 0000000..8dd3700
--- /dev/null
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSActorHover.cs
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyrightD
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+using OpenSim.Region.Physics.Manager;
+
+using OMV = OpenMetaverse;
+
+namespace OpenSim.Region.Physics.BulletSPlugin
+{
+public class BSActorHover : BSActor
+{
+ private BSFMotor m_hoverMotor;
+
+ public BSActorHover(BSScene physicsScene, BSPhysObject pObj, string actorName)
+ : base(physicsScene, pObj, actorName)
+ {
+ m_hoverMotor = null;
+ m_physicsScene.DetailLog("{0},BSActorHover,constructor", m_controllingPrim.LocalID);
+ }
+
+ // BSActor.isActive
+ public override bool isActive
+ {
+ get { return Enabled && m_controllingPrim.IsPhysicallyActive; }
+ }
+
+ // Release any connections and resources used by the actor.
+ // BSActor.Dispose()
+ public override void Dispose()
+ {
+ Enabled = false;
+ }
+
+ // Called when physical parameters (properties set in Bullet) need to be re-applied.
+ // Called at taint-time.
+ // BSActor.Refresh()
+ public override void Refresh()
+ {
+ m_physicsScene.DetailLog("{0},BSActorHover,refresh", m_controllingPrim.LocalID);
+
+ // If not active any more, get rid of me (shouldn't ever happen, but just to be safe)
+ if (!m_controllingPrim.HoverActive)
+ {
+ m_physicsScene.DetailLog("{0},BSActorHover,refresh,notHovering,removing={1}", m_controllingPrim.LocalID, ActorName);
+ m_controllingPrim.PhysicalActors.RemoveAndRelease(ActorName);
+ return;
+ }
+
+ // If the object is physically active, add the hoverer prestep action
+ if (isActive)
+ {
+ ActivateHover();
+ }
+ else
+ {
+ DeactivateHover();
+ }
+ }
+
+ // The object's physical representation is being rebuilt so pick up any physical dependencies (constraints, ...).
+ // Register a prestep action to restore physical requirements before the next simulation step.
+ // Called at taint-time.
+ // BSActor.RemoveBodyDependencies()
+ public override void RemoveBodyDependencies()
+ {
+ // Nothing to do for the hoverer since it is all software at pre-step action time.
+ }
+
+ // If a hover motor has not been created, create one and start the hovering.
+ private void ActivateHover()
+ {
+ if (m_hoverMotor == null)
+ {
+ // Turning the target on
+ m_hoverMotor = new BSFMotor("BSActorHover",
+ m_controllingPrim.HoverTau, // timeScale
+ BSMotor.Infinite, // decay time scale
+ BSMotor.Infinite, // friction timescale
+ 1f // efficiency
+ );
+ m_hoverMotor.SetTarget(ComputeCurrentHoverHeight());
+ m_hoverMotor.SetCurrent(m_controllingPrim.RawPosition.Z);
+ m_hoverMotor.PhysicsScene = m_physicsScene; // DEBUG DEBUG so motor will output detail log messages.
+
+ m_physicsScene.BeforeStep += Hoverer;
+ }
+ }
+
+ private void DeactivateHover()
+ {
+ if (m_hoverMotor != null)
+ {
+ m_physicsScene.BeforeStep -= Hoverer;
+ m_hoverMotor = null;
+ }
+ }
+
+ // Called just before the simulation step. Update the vertical position for hoverness.
+ private void Hoverer(float timeStep)
+ {
+ // Don't do hovering while the object is selected.
+ if (!isActive)
+ return;
+
+ m_hoverMotor.SetCurrent(m_controllingPrim.RawPosition.Z);
+ m_hoverMotor.SetTarget(ComputeCurrentHoverHeight());
+ float targetHeight = m_hoverMotor.Step(timeStep);
+
+ // 'targetHeight' is where we'd like the Z of the prim to be at this moment.
+ // Compute the amount of force to push us there.
+ float moveForce = (targetHeight - m_controllingPrim.RawPosition.Z) * m_controllingPrim.RawMass;
+ // Undo anything the object thinks it's doing at the moment
+ moveForce = -m_controllingPrim.RawVelocity.Z * m_controllingPrim.Mass;
+
+ m_physicsScene.PE.ApplyCentralImpulse(m_controllingPrim.PhysBody, new OMV.Vector3(0f, 0f, moveForce));
+ m_physicsScene.DetailLog("{0},BSPrim.Hover,move,targHt={1},moveForce={2},mass={3}",
+ m_controllingPrim.LocalID, targetHeight, moveForce, m_controllingPrim.RawMass);
+ }
+
+ // Based on current position, determine what we should be hovering at now.
+ // Must recompute often. What if we walked offa cliff>
+ private float ComputeCurrentHoverHeight()
+ {
+ float ret = m_controllingPrim.HoverHeight;
+ float groundHeight = m_physicsScene.TerrainManager.GetTerrainHeightAtXYZ(m_controllingPrim.RawPosition);
+
+ switch (m_controllingPrim.HoverType)
+ {
+ case PIDHoverType.Ground:
+ ret = groundHeight + m_controllingPrim.HoverHeight;
+ break;
+ case PIDHoverType.GroundAndWater:
+ float waterHeight = m_physicsScene.TerrainManager.GetWaterLevelAtXYZ(m_controllingPrim.RawPosition);
+ if (groundHeight > waterHeight)
+ {
+ ret = groundHeight + m_controllingPrim.HoverHeight;
+ }
+ else
+ {
+ ret = waterHeight + m_controllingPrim.HoverHeight;
+ }
+ break;
+ }
+ return ret;
+ }
+}
+}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSActorLockAxis.cs b/OpenSim/Region/Physics/BulletSPlugin/BSActorLockAxis.cs
index 7219617..c40a499 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSActorLockAxis.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSActorLockAxis.cs
@@ -40,7 +40,7 @@ public class BSActorLockAxis : BSActor
BSConstraint LockAxisConstraint = null;
public BSActorLockAxis(BSScene physicsScene, BSPhysObject pObj, string actorName)
- : base(physicsScene, pObj,actorName)
+ : base(physicsScene, pObj, actorName)
{
m_physicsScene.DetailLog("{0},BSActorLockAxis,constructor", m_controllingPrim.LocalID);
LockAxisConstraint = null;
@@ -99,7 +99,7 @@ public class BSActorLockAxis : BSActor
// If a constraint is set up, remove it from the physical scene
RemoveAxisLockConstraint();
// Schedule a call before the next simulation step to restore the constraint.
- m_physicsScene.PostTaintObject(m_controllingPrim.LockedAxisActorName, m_controllingPrim.LocalID, delegate()
+ m_physicsScene.PostTaintObject("BSActorLockAxis:" + ActorName, m_controllingPrim.LocalID, delegate()
{
Refresh();
});
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSActorMoveToTarget.cs b/OpenSim/Region/Physics/BulletSPlugin/BSActorMoveToTarget.cs
new file mode 100755
index 0000000..3517ef2
--- /dev/null
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSActorMoveToTarget.cs
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyrightD
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+using OpenSim.Region.Physics.Manager;
+
+using OMV = OpenMetaverse;
+
+namespace OpenSim.Region.Physics.BulletSPlugin
+{
+public class BSActorMoveToTarget : BSActor
+{
+ private BSVMotor m_targetMotor;
+
+ public BSActorMoveToTarget(BSScene physicsScene, BSPhysObject pObj, string actorName)
+ : base(physicsScene, pObj, actorName)
+ {
+ m_targetMotor = null;
+ m_physicsScene.DetailLog("{0},BSActorMoveToTarget,constructor", m_controllingPrim.LocalID);
+ }
+
+ // BSActor.isActive
+ public override bool isActive
+ {
+ get { return Enabled && m_controllingPrim.IsPhysicallyActive; }
+ }
+
+ // Release any connections and resources used by the actor.
+ // BSActor.Dispose()
+ public override void Dispose()
+ {
+ Enabled = false;
+ }
+
+ // Called when physical parameters (properties set in Bullet) need to be re-applied.
+ // Called at taint-time.
+ // BSActor.Refresh()
+ public override void Refresh()
+ {
+ m_physicsScene.DetailLog("{0},BSActorMoveToTarget,refresh", m_controllingPrim.LocalID);
+
+ // If not active any more, get rid of me (shouldn't ever happen, but just to be safe)
+ if (!m_controllingPrim.HoverActive)
+ {
+ m_physicsScene.DetailLog("{0},BSActorMoveToTarget,refresh,notMoveToTarget,removing={1}", m_controllingPrim.LocalID, ActorName);
+ m_controllingPrim.PhysicalActors.RemoveAndRelease(ActorName);
+ return;
+ }
+
+ // If the object is physically active, add the hoverer prestep action
+ if (isActive)
+ {
+ ActivateMoveToTarget();
+ }
+ else
+ {
+ DeactivateMoveToTarget();
+ }
+ }
+
+ // The object's physical representation is being rebuilt so pick up any physical dependencies (constraints, ...).
+ // Register a prestep action to restore physical requirements before the next simulation step.
+ // Called at taint-time.
+ // BSActor.RemoveBodyDependencies()
+ public override void RemoveBodyDependencies()
+ {
+ // Nothing to do for the hoverer since it is all software at pre-step action time.
+ }
+
+ // If a hover motor has not been created, create one and start the hovering.
+ private void ActivateMoveToTarget()
+ {
+ if (m_targetMotor == null)
+ {
+ // We're taking over after this.
+ m_controllingPrim.ZeroMotion(true);
+
+ m_targetMotor = new BSVMotor("BSPrim.PIDTarget",
+ m_controllingPrim.MoveToTargetTau, // timeScale
+ BSMotor.Infinite, // decay time scale
+ BSMotor.InfiniteVector, // friction timescale
+ 1f // efficiency
+ );
+ m_targetMotor.PhysicsScene = m_physicsScene; // DEBUG DEBUG so motor will output detail log messages.
+ m_targetMotor.SetTarget(m_controllingPrim.MoveToTargetTarget);
+ m_targetMotor.SetCurrent(m_controllingPrim.RawPosition);
+
+ m_physicsScene.BeforeStep += Mover;
+ }
+ }
+
+ private void DeactivateMoveToTarget()
+ {
+ if (m_targetMotor != null)
+ {
+ m_physicsScene.BeforeStep -= Mover;
+ m_targetMotor = null;
+ }
+ }
+
+ // Called just before the simulation step. Update the vertical position for hoverness.
+ private void Mover(float timeStep)
+ {
+ // Don't do hovering while the object is selected.
+ if (!isActive)
+ return;
+
+ OMV.Vector3 origPosition = m_controllingPrim.RawPosition; // DEBUG DEBUG (for printout below)
+
+ // 'movePosition' is where we'd like the prim to be at this moment.
+ OMV.Vector3 movePosition = m_controllingPrim.RawPosition + m_targetMotor.Step(timeStep);
+
+ // If we are very close to our target, turn off the movement motor.
+ if (m_targetMotor.ErrorIsZero())
+ {
+ m_physicsScene.DetailLog("{0},BSPrim.PIDTarget,zeroMovement,movePos={1},pos={2},mass={3}",
+ m_controllingPrim.LocalID, movePosition, m_controllingPrim.RawPosition, m_controllingPrim.Mass);
+ m_controllingPrim.ForcePosition = m_targetMotor.TargetValue;
+ m_targetMotor.Enabled = false;
+ }
+ else
+ {
+ m_controllingPrim.ForcePosition = movePosition;
+ }
+ m_physicsScene.DetailLog("{0},BSPrim.PIDTarget,move,fromPos={1},movePos={2}", m_controllingPrim.LocalID, origPosition, movePosition);
+ }
+}
+}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSActorSetForce.cs b/OpenSim/Region/Physics/BulletSPlugin/BSActorSetForce.cs
new file mode 100755
index 0000000..d942490
--- /dev/null
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSActorSetForce.cs
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyrightD
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+using OpenSim.Region.Physics.Manager;
+
+using OMV = OpenMetaverse;
+
+namespace OpenSim.Region.Physics.BulletSPlugin
+{
+public class BSActorSetForce : BSActor
+{
+ BSFMotor m_forceMotor;
+
+ public BSActorSetForce(BSScene physicsScene, BSPhysObject pObj, string actorName)
+ : base(physicsScene, pObj, actorName)
+ {
+ m_forceMotor = null;
+ m_physicsScene.DetailLog("{0},BSActorSetForce,constructor", m_controllingPrim.LocalID);
+ }
+
+ // BSActor.isActive
+ public override bool isActive
+ {
+ get { return Enabled && m_controllingPrim.IsPhysicallyActive; }
+ }
+
+ // Release any connections and resources used by the actor.
+ // BSActor.Dispose()
+ public override void Dispose()
+ {
+ Enabled = false;
+ }
+
+ // Called when physical parameters (properties set in Bullet) need to be re-applied.
+ // Called at taint-time.
+ // BSActor.Refresh()
+ public override void Refresh()
+ {
+ m_physicsScene.DetailLog("{0},BSActorSetForce,refresh", m_controllingPrim.LocalID);
+
+ // If not active any more, get rid of me (shouldn't ever happen, but just to be safe)
+ if (m_controllingPrim.RawForce == OMV.Vector3.Zero)
+ {
+ m_physicsScene.DetailLog("{0},BSActorSetForce,refresh,notSetForce,removing={1}", m_controllingPrim.LocalID, ActorName);
+ m_controllingPrim.PhysicalActors.RemoveAndRelease(ActorName);
+ return;
+ }
+
+ // If the object is physically active, add the hoverer prestep action
+ if (isActive)
+ {
+ ActivateSetForce();
+ }
+ else
+ {
+ DeactivateSetForce();
+ }
+ }
+
+ // The object's physical representation is being rebuilt so pick up any physical dependencies (constraints, ...).
+ // Register a prestep action to restore physical requirements before the next simulation step.
+ // Called at taint-time.
+ // BSActor.RemoveBodyDependencies()
+ public override void RemoveBodyDependencies()
+ {
+ // Nothing to do for the hoverer since it is all software at pre-step action time.
+ }
+
+ // If a hover motor has not been created, create one and start the hovering.
+ private void ActivateSetForce()
+ {
+ if (m_forceMotor == null)
+ {
+ // A fake motor that might be used someday
+ m_forceMotor = new BSFMotor("setForce", 1f, 1f, 1f, 1f);
+
+ m_physicsScene.BeforeStep += Mover;
+ }
+ }
+
+ private void DeactivateSetForce()
+ {
+ if (m_forceMotor != null)
+ {
+ m_physicsScene.BeforeStep -= Mover;
+ m_forceMotor = null;
+ }
+ }
+
+ // Called just before the simulation step. Update the vertical position for hoverness.
+ private void Mover(float timeStep)
+ {
+ // Don't do force while the object is selected.
+ if (!isActive)
+ return;
+
+ m_physicsScene.DetailLog("{0},BSActorSetForce,preStep,force={1}", m_controllingPrim.LocalID, m_controllingPrim.RawForce);
+ if (m_controllingPrim.PhysBody.HasPhysicalBody)
+ {
+ m_physicsScene.PE.ApplyCentralForce(m_controllingPrim.PhysBody, m_controllingPrim.RawForce);
+ m_controllingPrim.ActivateIfPhysical(false);
+ }
+
+ // TODO:
+ }
+}
+}
+
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSActorSetTorque.cs b/OpenSim/Region/Physics/BulletSPlugin/BSActorSetTorque.cs
new file mode 100755
index 0000000..e0f719f
--- /dev/null
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSActorSetTorque.cs
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyrightD
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+using OpenSim.Region.Physics.Manager;
+
+using OMV = OpenMetaverse;
+
+namespace OpenSim.Region.Physics.BulletSPlugin
+{
+public class BSActorSetTorque : BSActor
+{
+ BSFMotor m_torqueMotor;
+
+ public BSActorSetTorque(BSScene physicsScene, BSPhysObject pObj, string actorName)
+ : base(physicsScene, pObj, actorName)
+ {
+ m_torqueMotor = null;
+ m_physicsScene.DetailLog("{0},BSActorSetTorque,constructor", m_controllingPrim.LocalID);
+ }
+
+ // BSActor.isActive
+ public override bool isActive
+ {
+ get { return Enabled && m_controllingPrim.IsPhysicallyActive; }
+ }
+
+ // Release any connections and resources used by the actor.
+ // BSActor.Dispose()
+ public override void Dispose()
+ {
+ Enabled = false;
+ }
+
+ // Called when physical parameters (properties set in Bullet) need to be re-applied.
+ // Called at taint-time.
+ // BSActor.Refresh()
+ public override void Refresh()
+ {
+ m_physicsScene.DetailLog("{0},BSActorSetTorque,refresh", m_controllingPrim.LocalID);
+
+ // If not active any more, get rid of me (shouldn't ever happen, but just to be safe)
+ if (m_controllingPrim.RawTorque == OMV.Vector3.Zero)
+ {
+ m_physicsScene.DetailLog("{0},BSActorSetTorque,refresh,notSetTorque,removing={1}", m_controllingPrim.LocalID, ActorName);
+ m_controllingPrim.PhysicalActors.RemoveAndRelease(ActorName);
+ return;
+ }
+
+ // If the object is physically active, add the hoverer prestep action
+ if (isActive)
+ {
+ ActivateSetTorque();
+ }
+ else
+ {
+ DeactivateSetTorque();
+ }
+ }
+
+ // The object's physical representation is being rebuilt so pick up any physical dependencies (constraints, ...).
+ // Register a prestep action to restore physical requirements before the next simulation step.
+ // Called at taint-time.
+ // BSActor.RemoveBodyDependencies()
+ public override void RemoveBodyDependencies()
+ {
+ // Nothing to do for the hoverer since it is all software at pre-step action time.
+ }
+
+ // If a hover motor has not been created, create one and start the hovering.
+ private void ActivateSetTorque()
+ {
+ if (m_torqueMotor == null)
+ {
+ // A fake motor that might be used someday
+ m_torqueMotor = new BSFMotor("setTorque", 1f, 1f, 1f, 1f);
+
+ m_physicsScene.BeforeStep += Mover;
+ }
+ }
+
+ private void DeactivateSetTorque()
+ {
+ if (m_torqueMotor != null)
+ {
+ m_physicsScene.BeforeStep -= Mover;
+ m_torqueMotor = null;
+ }
+ }
+
+ // Called just before the simulation step. Update the vertical position for hoverness.
+ private void Mover(float timeStep)
+ {
+ // Don't do force while the object is selected.
+ if (!isActive)
+ return;
+
+ m_physicsScene.DetailLog("{0},BSActorSetTorque,preStep,force={1}", m_controllingPrim.LocalID, m_controllingPrim.RawTorque);
+ if (m_controllingPrim.PhysBody.HasPhysicalBody)
+ {
+ m_controllingPrim.AddAngularForce(m_controllingPrim.RawTorque, false, true);
+ m_controllingPrim.ActivateIfPhysical(false);
+ }
+
+ // TODO:
+ }
+}
+}
+
+
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSActors.cs b/OpenSim/Region/Physics/BulletSPlugin/BSActors.cs
index 5a19ba4..fb4d452 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSActors.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSActors.cs
@@ -32,12 +32,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin
{
public class BSActorCollection
{
- private BSScene PhysicsScene { get; set; }
+ private BSScene m_physicsScene { get; set; }
private Dictionary m_actors;
public BSActorCollection(BSScene physicsScene)
{
- PhysicsScene = physicsScene;
+ m_physicsScene = physicsScene;
m_actors = new Dictionary();
}
public void Add(string name, BSActor actor)
@@ -61,6 +61,10 @@ public class BSActorCollection
Release();
m_actors.Clear();
}
+ public void Dispose()
+ {
+ Clear();
+ }
public bool HasActor(string name)
{
return m_actors.ContainsKey(name);
@@ -71,6 +75,10 @@ public class BSActorCollection
act(kvp.Value);
}
+ public void Enable(bool enabl)
+ {
+ ForEachActor(a => a.Enable(enabl));
+ }
public void Release()
{
ForEachActor(a => a.Dispose());
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
index 25be416..09c9b16 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -46,9 +46,6 @@ public sealed class BSCharacter : BSPhysObject
private OMV.Vector3 _position;
private float _mass;
private float _avatarVolume;
- private OMV.Vector3 _force;
- private OMV.Vector3 _velocity;
- private OMV.Vector3 _torque;
private float _collisionScore;
private OMV.Vector3 _acceleration;
private OMV.Quaternion _orientation;
@@ -61,17 +58,13 @@ public sealed class BSCharacter : BSPhysObject
private OMV.Vector3 _rotationalVelocity;
private bool _kinematic;
private float _buoyancy;
- private bool _isStationaryStanding; // true is standing on a stationary object
- private BSVMotor _velocityMotor;
+ private BSActorAvatarMove m_moveActor;
+ private const string AvatarMoveActorName = "BSCharacter.AvatarMove";
private OMV.Vector3 _PIDTarget;
private bool _usePID;
private float _PIDTau;
- private bool _useHoverPID;
- private float _PIDHoverHeight;
- private PIDHoverType _PIDHoverType;
- private float _PIDHoverTao;
public BSCharacter(uint localID, String avName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, bool isFlying)
: base(parent_scene, localID, avName, "BSCharacter")
@@ -81,11 +74,10 @@ public sealed class BSCharacter : BSPhysObject
_flying = isFlying;
_orientation = OMV.Quaternion.Identity;
- _velocity = OMV.Vector3.Zero;
+ RawVelocity = OMV.Vector3.Zero;
_buoyancy = ComputeBuoyancyFromFlying(isFlying);
Friction = BSParam.AvatarStandingFriction;
Density = BSParam.AvatarDensity / BSParam.DensityScaleFactor;
- _isStationaryStanding = false;
// Old versions of ScenePresence passed only the height. If width and/or depth are zero,
// replace with the default values.
@@ -99,7 +91,12 @@ public sealed class BSCharacter : BSPhysObject
// set _avatarVolume and _mass based on capsule size, _density and Scale
ComputeAvatarVolumeAndMass();
- SetupMovementMotor();
+ // The avatar's movement is controlled by this motor that speeds up and slows down
+ // the avatar seeking to reach the motor's target speed.
+ // This motor runs as a prestep action for the avatar so it will keep the avatar
+ // standing as well as moving. Destruction of the avatar will destroy the pre-step action.
+ m_moveActor = new BSActorAvatarMove(PhysicsScene, this, AvatarMoveActorName);
+ PhysicalActors.Add(AvatarMoveActorName, m_moveActor);
DetailLog("{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5}",
LocalID, _size, Scale, Density, _avatarVolume, RawMass);
@@ -139,10 +136,10 @@ public sealed class BSCharacter : BSPhysObject
ForcePosition = _position;
// Set the velocity
- _velocityMotor.Reset();
- _velocityMotor.SetTarget(_velocity);
- _velocityMotor.SetCurrent(_velocity);
- ForceVelocity = _velocity;
+ if (m_moveActor != null)
+ m_moveActor.SetVelocityAndTarget(RawVelocity, RawVelocity, false);
+
+ ForceVelocity = RawVelocity;
// This will enable or disable the flying buoyancy of the avatar.
// Needs to be reset especially when an avatar is recreated after crossing a region boundry.
@@ -176,162 +173,6 @@ public sealed class BSCharacter : BSPhysObject
PhysBody.ApplyCollisionMask(PhysicsScene);
}
- // The avatar's movement is controlled by this motor that speeds up and slows down
- // the avatar seeking to reach the motor's target speed.
- // This motor runs as a prestep action for the avatar so it will keep the avatar
- // standing as well as moving. Destruction of the avatar will destroy the pre-step action.
- private void SetupMovementMotor()
- {
- // Infinite decay and timescale values so motor only changes current to target values.
- _velocityMotor = new BSVMotor("BSCharacter.Velocity",
- 0.2f, // time scale
- BSMotor.Infinite, // decay time scale
- BSMotor.InfiniteVector, // friction timescale
- 1f // efficiency
- );
- // _velocityMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages.
-
- RegisterPreStepAction("BSCharactor.Movement", LocalID, delegate(float timeStep)
- {
- // TODO: Decide if the step parameters should be changed depending on the avatar's
- // state (flying, colliding, ...). There is code in ODE to do this.
-
- // COMMENTARY: when the user is making the avatar walk, except for falling, the velocity
- // specified for the avatar is the one that should be used. For falling, if the avatar
- // is not flying and is not colliding then it is presumed to be falling and the Z
- // component is not fooled with (thus allowing gravity to do its thing).
- // When the avatar is standing, though, the user has specified a velocity of zero and
- // the avatar should be standing. But if the avatar is pushed by something in the world
- // (raising elevator platform, moving vehicle, ...) the avatar should be allowed to
- // move. Thus, the velocity cannot be forced to zero. The problem is that small velocity
- // errors can creap in and the avatar will slowly float off in some direction.
- // So, the problem is that, when an avatar is standing, we cannot tell creaping error
- // from real pushing.
- // The code below uses whether the collider is static or moving to decide whether to zero motion.
-
- _velocityMotor.Step(timeStep);
- _isStationaryStanding = false;
-
- // If we're not supposed to be moving, make sure things are zero.
- if (_velocityMotor.ErrorIsZero() && _velocityMotor.TargetValue == OMV.Vector3.Zero)
- {
- // The avatar shouldn't be moving
- _velocityMotor.Zero();
-
- if (IsColliding)
- {
- // If we are colliding with a stationary object, presume we're standing and don't move around
- if (!ColliderIsMoving)
- {
- DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,zeroingMotion", LocalID);
- _isStationaryStanding = true;
- ZeroMotion(true /* inTaintTime */);
- }
-
- // Standing has more friction on the ground
- if (Friction != BSParam.AvatarStandingFriction)
- {
- Friction = BSParam.AvatarStandingFriction;
- PhysicsScene.PE.SetFriction(PhysBody, Friction);
- }
- }
- else
- {
- if (Flying)
- {
- // Flying and not collising and velocity nearly zero.
- ZeroMotion(true /* inTaintTime */);
- }
- }
-
- DetailLog("{0},BSCharacter.MoveMotor,taint,stopping,target={1},colliding={2}", LocalID, _velocityMotor.TargetValue, IsColliding);
- }
- else
- {
- // Supposed to be moving.
- OMV.Vector3 stepVelocity = _velocityMotor.CurrentValue;
-
- if (Friction != BSParam.AvatarFriction)
- {
- // Probably starting up walking. Set friction to moving friction.
- Friction = BSParam.AvatarFriction;
- PhysicsScene.PE.SetFriction(PhysBody, Friction);
- }
-
- // If falling, we keep the world's downward vector no matter what the other axis specify.
- // The check for _velocity.Z < 0 makes jumping work (temporary upward force).
- if (!Flying && !IsColliding)
- {
- if (_velocity.Z < 0)
- stepVelocity.Z = _velocity.Z;
- // DetailLog("{0},BSCharacter.MoveMotor,taint,overrideStepZWithWorldZ,stepVel={1}", LocalID, stepVelocity);
- }
-
- // 'stepVelocity' is now the speed we'd like the avatar to move in. Turn that into an instantanous force.
- OMV.Vector3 moveForce = (stepVelocity - _velocity) * Mass;
-
- // Should we check for move force being small and forcing velocity to zero?
-
- // Add special movement force to allow avatars to walk up stepped surfaces.
- moveForce += WalkUpStairs();
-
- DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce);
- PhysicsScene.PE.ApplyCentralImpulse(PhysBody, moveForce);
- }
- });
- }
-
- // Decide if the character is colliding with a low object and compute a force to pop the
- // avatar up so it can walk up and over the low objects.
- private OMV.Vector3 WalkUpStairs()
- {
- OMV.Vector3 ret = OMV.Vector3.Zero;
-
- // This test is done if moving forward, not flying and is colliding with something.
- // DetailLog("{0},BSCharacter.WalkUpStairs,IsColliding={1},flying={2},targSpeed={3},collisions={4}",
- // LocalID, IsColliding, Flying, TargetSpeed, CollisionsLastTick.Count);
- if (IsColliding && !Flying && TargetVelocitySpeed > 0.1f /* && ForwardSpeed < 0.1f */)
- {
- // The range near the character's feet where we will consider stairs
- float nearFeetHeightMin = RawPosition.Z - (Size.Z / 2f) + 0.05f;
- float nearFeetHeightMax = nearFeetHeightMin + BSParam.AvatarStepHeight;
-
- // Look for a collision point that is near the character's feet and is oriented the same as the charactor is
- foreach (KeyValuePair kvp in CollisionsLastTick.m_objCollisionList)
- {
- // Don't care about collisions with the terrain
- if (kvp.Key > PhysicsScene.TerrainManager.HighestTerrainID)
- {
- OMV.Vector3 touchPosition = kvp.Value.Position;
- // DetailLog("{0},BSCharacter.WalkUpStairs,min={1},max={2},touch={3}",
- // LocalID, nearFeetHeightMin, nearFeetHeightMax, touchPosition);
- if (touchPosition.Z >= nearFeetHeightMin && touchPosition.Z <= nearFeetHeightMax)
- {
- // This contact is within the 'near the feet' range.
- // The normal should be our contact point to the object so it is pointing away
- // thus the difference between our facing orientation and the normal should be small.
- OMV.Vector3 directionFacing = OMV.Vector3.UnitX * RawOrientation;
- OMV.Vector3 touchNormal = OMV.Vector3.Normalize(kvp.Value.SurfaceNormal);
- float diff = Math.Abs(OMV.Vector3.Distance(directionFacing, touchNormal));
- if (diff < BSParam.AvatarStepApproachFactor)
- {
- // Found the stairs contact point. Push up a little to raise the character.
- float upForce = (touchPosition.Z - nearFeetHeightMin) * Mass * BSParam.AvatarStepForceFactor;
- ret = new OMV.Vector3(0f, 0f, upForce);
-
- // Also move the avatar up for the new height
- OMV.Vector3 displacement = new OMV.Vector3(0f, 0f, BSParam.AvatarStepHeight / 2f);
- ForcePosition = RawPosition + displacement;
- }
- DetailLog("{0},BSCharacter.WalkUpStairs,touchPos={1},nearFeetMin={2},faceDir={3},norm={4},diff={5},ret={6}",
- LocalID, touchPosition, nearFeetHeightMin, directionFacing, touchNormal, diff, ret);
- }
- }
- }
- }
-
- return ret;
- }
public override void RequestPhysicsterseUpdate()
{
@@ -403,7 +244,7 @@ public sealed class BSCharacter : BSPhysObject
// Called at taint time!
public override void ZeroMotion(bool inTaintTime)
{
- _velocity = OMV.Vector3.Zero;
+ RawVelocity = OMV.Vector3.Zero;
_acceleration = OMV.Vector3.Zero;
_rotationalVelocity = OMV.Vector3.Zero;
@@ -542,15 +383,15 @@ public sealed class BSCharacter : BSPhysObject
}
public override OMV.Vector3 Force {
- get { return _force; }
+ get { return RawForce; }
set {
- _force = value;
+ RawForce = value;
// m_log.DebugFormat("{0}: Force = {1}", LogHeader, _force);
PhysicsScene.TaintedObject("BSCharacter.SetForce", delegate()
{
- DetailLog("{0},BSCharacter.setForce,taint,force={1}", LocalID, _force);
+ DetailLog("{0},BSCharacter.setForce,taint,force={1}", LocalID, RawForce);
if (PhysBody.HasPhysicalBody)
- PhysicsScene.PE.SetObjectForce(PhysBody, _force);
+ PhysicsScene.PE.SetObjectForce(PhysBody, RawForce);
});
}
}
@@ -573,7 +414,7 @@ public sealed class BSCharacter : BSPhysObject
{
get
{
- return m_targetVelocity;
+ return base.m_targetVelocity;
}
set
{
@@ -583,51 +424,39 @@ public sealed class BSCharacter : BSPhysObject
if (_setAlwaysRun)
targetVel *= new OMV.Vector3(BSParam.AvatarAlwaysRunFactor, BSParam.AvatarAlwaysRunFactor, 0f);
- PhysicsScene.TaintedObject("BSCharacter.setTargetVelocity", delegate()
- {
- _velocityMotor.Reset();
- _velocityMotor.SetTarget(targetVel);
- _velocityMotor.SetCurrent(_velocity);
- _velocityMotor.Enabled = true;
- });
+ if (m_moveActor != null)
+ m_moveActor.SetVelocityAndTarget(RawVelocity, targetVel, false /* inTaintTime */);
}
}
- public override OMV.Vector3 RawVelocity
- {
- get { return _velocity; }
- set { _velocity = value; }
- }
// Directly setting velocity means this is what the user really wants now.
public override OMV.Vector3 Velocity {
- get { return _velocity; }
+ get { return RawVelocity; }
set {
- _velocity = value;
- // m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, _velocity);
+ RawVelocity = value;
+ // m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, RawVelocity);
PhysicsScene.TaintedObject("BSCharacter.setVelocity", delegate()
{
- _velocityMotor.Reset();
- _velocityMotor.SetCurrent(_velocity);
- _velocityMotor.SetTarget(_velocity);
- _velocityMotor.Enabled = false;
+ if (m_moveActor != null)
+ m_moveActor.SetVelocityAndTarget(RawVelocity, RawVelocity, true /* inTaintTime */);
- DetailLog("{0},BSCharacter.setVelocity,taint,vel={1}", LocalID, _velocity);
- ForceVelocity = _velocity;
+ DetailLog("{0},BSCharacter.setVelocity,taint,vel={1}", LocalID, RawVelocity);
+ ForceVelocity = RawVelocity;
});
}
}
public override OMV.Vector3 ForceVelocity {
- get { return _velocity; }
+ get { return RawVelocity; }
set {
PhysicsScene.AssertInTaintTime("BSCharacter.ForceVelocity");
- _velocity = value;
- PhysicsScene.PE.SetLinearVelocity(PhysBody, _velocity);
+ RawVelocity = value;
+ PhysicsScene.PE.SetLinearVelocity(PhysBody, RawVelocity);
PhysicsScene.PE.Activate(PhysBody, true);
}
}
public override OMV.Vector3 Torque {
- get { return _torque; }
- set { _torque = value;
+ get { return RawTorque; }
+ set { RawTorque = value;
}
}
public override float CollisionScore {
@@ -783,27 +612,6 @@ public sealed class BSCharacter : BSPhysObject
set { _PIDTau = value; }
}
- // Used for llSetHoverHeight and maybe vehicle height
- // Hover Height will override MoveTo target's Z
- public override bool PIDHoverActive {
- set { _useHoverPID = value; }
- }
- public override float PIDHoverHeight {
- set { _PIDHoverHeight = value; }
- }
- public override PIDHoverType PIDHoverType {
- set { _PIDHoverType = value; }
- }
- public override float PIDHoverTau {
- set { _PIDHoverTao = value; }
- }
-
- // For RotLookAt
- public override OMV.Quaternion APIDTarget { set { return; } }
- public override bool APIDActive { set { return; } }
- public override float APIDStrength { set { return; } }
- public override float APIDDamping { set { return; } }
-
public override void AddForce(OMV.Vector3 force, bool pushforce)
{
// Since this force is being applied in only one step, make this a force per second.
@@ -833,7 +641,7 @@ public sealed class BSCharacter : BSPhysObject
}
}
- public override void AddAngularForce(OMV.Vector3 force, bool pushforce) {
+ public override void AddAngularForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) {
}
public override void SetMomentum(OMV.Vector3 momentum) {
}
@@ -887,7 +695,7 @@ public sealed class BSCharacter : BSPhysObject
public override void UpdateProperties(EntityProperties entprop)
{
// Don't change position if standing on a stationary object.
- if (!_isStationaryStanding)
+ if (!IsStationary)
_position = entprop.Position;
_orientation = entprop.Rotation;
@@ -896,8 +704,8 @@ public sealed class BSCharacter : BSPhysObject
// and will send agent updates to the clients if velocity changes by more than
// 0.001m/s. Bullet introduces a lot of jitter in the velocity which causes many
// extra updates.
- if (!entprop.Velocity.ApproxEquals(_velocity, 0.1f))
- _velocity = entprop.Velocity;
+ if (!entprop.Velocity.ApproxEquals(RawVelocity, 0.1f))
+ RawVelocity = entprop.Velocity;
_acceleration = entprop.Acceleration;
_rotationalVelocity = entprop.RotationalVelocity;
@@ -920,7 +728,7 @@ public sealed class BSCharacter : BSPhysObject
// base.RequestPhysicsterseUpdate();
DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
- LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity);
+ LocalID, _position, _orientation, RawVelocity, _acceleration, _rotationalVelocity);
}
}
}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
index 98ea833..644bc7e 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
@@ -43,7 +43,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
* VariableName: used by the simulator and performs taint operations, etc
* RawVariableName: direct reference to the BulletSim storage for the variable value
* ForceVariableName: direct reference (store and fetch) to the value in the physics engine.
- * The last two (and certainly the last one) should be referenced only in taint-time.
+ * The last one should only be referenced in taint-time.
*/
/*
@@ -84,6 +84,7 @@ public abstract class BSPhysObject : PhysicsActor
// Initialize variables kept in base.
GravModifier = 1.0f;
Gravity = new OMV.Vector3(0f, 0f, BSParam.Gravity);
+ HoverActive = false;
// We don't have any physical representation yet.
PhysBody = new BulletBody(localID);
@@ -110,11 +111,10 @@ public abstract class BSPhysObject : PhysicsActor
// Tell the object to clean up.
public virtual void Destroy()
{
- UnRegisterAllPreStepActions();
- UnRegisterAllPostStepActions();
+ PhysicalActors.Enable(false);
PhysicsScene.TaintedObject("BSPhysObject.Destroy", delegate()
{
- PhysicalActors.Release();
+ PhysicalActors.Dispose();
});
}
@@ -203,15 +203,48 @@ public abstract class BSPhysObject : PhysicsActor
public abstract OMV.Quaternion RawOrientation { get; set; }
public abstract OMV.Quaternion ForceOrientation { get; set; }
- public abstract OMV.Vector3 RawVelocity { get; set; }
+ public OMV.Vector3 RawVelocity { get; set; }
public abstract OMV.Vector3 ForceVelocity { get; set; }
+ public OMV.Vector3 RawForce { get; set; }
+ public OMV.Vector3 RawTorque { get; set; }
+ public override void AddAngularForce(OMV.Vector3 force, bool pushforce)
+ {
+ AddAngularForce(force, pushforce, false);
+ }
+ public abstract void AddAngularForce(OMV.Vector3 force, bool pushforce, bool inTaintTime);
+
public abstract OMV.Vector3 ForceRotationalVelocity { get; set; }
public abstract float ForceBuoyancy { get; set; }
public virtual bool ForceBodyShapeRebuild(bool inTaintTime) { return false; }
+ public override bool PIDActive { set { MoveToTargetActive = value; } }
+ public override OMV.Vector3 PIDTarget { set { MoveToTargetTarget = value; } }
+ public override float PIDTau { set { MoveToTargetTau = value; } }
+
+ public bool MoveToTargetActive { get; set; }
+ public OMV.Vector3 MoveToTargetTarget { get; set; }
+ public float MoveToTargetTau { get; set; }
+
+ // Used for llSetHoverHeight and maybe vehicle height. Hover Height will override MoveTo target's Z
+ public override bool PIDHoverActive { set { HoverActive = value; } }
+ public override float PIDHoverHeight { set { HoverHeight = value; } }
+ public override PIDHoverType PIDHoverType { set { HoverType = value; } }
+ public override float PIDHoverTau { set { HoverTau = value; } }
+
+ public bool HoverActive { get; set; }
+ public float HoverHeight { get; set; }
+ public PIDHoverType HoverType { get; set; }
+ public float HoverTau { get; set; }
+
+ // For RotLookAt
+ public override OMV.Quaternion APIDTarget { set { return; } }
+ public override bool APIDActive { set { return; } }
+ public override float APIDStrength { set { return; } }
+ public override float APIDDamping { set { return; } }
+
// The current velocity forward
public virtual float ForwardSpeed
{
@@ -237,7 +270,44 @@ public abstract class BSPhysObject : PhysicsActor
public OMV.Vector3 LockedAxis { get; set; } // zero means locked. one means free.
public readonly OMV.Vector3 LockedAxisFree = new OMV.Vector3(1f, 1f, 1f); // All axis are free
- public readonly String LockedAxisActorName = "BSPrim.LockedAxis";
+
+ // Enable physical actions. Bullet will keep sleeping non-moving physical objects so
+ // they need waking up when parameters are changed.
+ // Called in taint-time!!
+ public void ActivateIfPhysical(bool forceIt)
+ {
+ if (IsPhysical && PhysBody.HasPhysicalBody)
+ PhysicsScene.PE.Activate(PhysBody, forceIt);
+ }
+
+ // 'actors' act on the physical object to change or constrain its motion. These can range from
+ // hovering to complex vehicle motion.
+ public delegate BSActor CreateActor();
+ public void CreateRemoveActor(bool createRemove, string actorName, bool inTaintTime, CreateActor creator)
+ {
+ if (createRemove)
+ {
+ PhysicsScene.TaintedObject(inTaintTime, "BSPrim.CreateRemoveActor:" + actorName, delegate()
+ {
+ if (!PhysicalActors.HasActor(actorName))
+ {
+ DetailLog("{0},BSPrim.CreateRemoveActor,taint,registerActor,a={1}", LocalID, actorName);
+ PhysicalActors.Add(actorName, creator());
+ }
+ });
+ }
+ else
+ {
+ PhysicsScene.TaintedObject(inTaintTime, "BSPrim.CreateRemoveActor:" + actorName, delegate()
+ {
+ if (PhysicalActors.HasActor(actorName))
+ {
+ DetailLog("{0},BSPrim.CreateRemoveActor,taint,unregisterActor,a={1}", LocalID, actorName);
+ PhysicalActors.RemoveAndRelease(actorName);
+ }
+ });
+ }
+ }
#region Collisions
@@ -255,7 +325,9 @@ public abstract class BSPhysObject : PhysicsActor
protected CollisionFlags CurrentCollisionFlags { get; set; }
// On a collision, check the collider and remember if the last collider was moving
// Used to modify the standing of avatars (avatars on stationary things stand still)
- protected bool ColliderIsMoving;
+ public bool ColliderIsMoving;
+ // Used by BSCharacter to manage standing (and not slipping)
+ public bool IsStationary;
// Count of collisions for this object
protected long CollisionAccumulation { get; set; }
@@ -293,7 +365,7 @@ public abstract class BSPhysObject : PhysicsActor
protected CollisionEventUpdate CollisionCollection;
// Remember collisions from last tick for fancy collision based actions
// (like a BSCharacter walking up stairs).
- protected CollisionEventUpdate CollisionsLastTick;
+ public CollisionEventUpdate CollisionsLastTick;
// The simulation step is telling this object about a collision.
// Return 'true' if a collision was processed and should be sent up.
@@ -424,104 +496,6 @@ public abstract class BSPhysObject : PhysicsActor
public BSActorCollection PhysicalActors;
- // There are some actions that must be performed for a physical object before each simulation step.
- // These actions are optional so, rather than scanning all the physical objects and asking them
- // if they have anything to do, a physical object registers for an event call before the step is performed.
- // This bookkeeping makes it easy to add, remove and clean up after all these registrations.
- private Dictionary RegisteredPrestepActions = new Dictionary();
- private Dictionary RegisteredPoststepActions = new Dictionary();
- protected void RegisterPreStepAction(string op, uint id, BSScene.PreStepAction actn)
- {
- string identifier = op + "-" + id.ToString();
-
- lock (RegisteredPrestepActions)
- {
- // Clean out any existing action
- UnRegisterPreStepAction(op, id);
- RegisteredPrestepActions[identifier] = actn;
- PhysicsScene.BeforeStep += actn;
- }
- DetailLog("{0},BSPhysObject.RegisterPreStepAction,id={1}", LocalID, identifier);
- }
-
- // Unregister a pre step action. Safe to call if the action has not been registered.
- // Returns 'true' if an action was actually removed
- protected bool UnRegisterPreStepAction(string op, uint id)
- {
- string identifier = op + "-" + id.ToString();
- bool removed = false;
- lock (RegisteredPrestepActions)
- {
- if (RegisteredPrestepActions.ContainsKey(identifier))
- {
- PhysicsScene.BeforeStep -= RegisteredPrestepActions[identifier];
- RegisteredPrestepActions.Remove(identifier);
- removed = true;
- }
- }
- DetailLog("{0},BSPhysObject.UnRegisterPreStepAction,id={1},removed={2}", LocalID, identifier, removed);
- return removed;
- }
-
- protected void UnRegisterAllPreStepActions()
- {
- lock (RegisteredPrestepActions)
- {
- foreach (KeyValuePair kvp in RegisteredPrestepActions)
- {
- PhysicsScene.BeforeStep -= kvp.Value;
- }
- RegisteredPrestepActions.Clear();
- }
- DetailLog("{0},BSPhysObject.UnRegisterAllPreStepActions,", LocalID);
- }
-
- protected void RegisterPostStepAction(string op, uint id, BSScene.PostStepAction actn)
- {
- string identifier = op + "-" + id.ToString();
-
- lock (RegisteredPoststepActions)
- {
- // Clean out any existing action
- UnRegisterPostStepAction(op, id);
- RegisteredPoststepActions[identifier] = actn;
- PhysicsScene.AfterStep += actn;
- }
- DetailLog("{0},BSPhysObject.RegisterPostStepAction,id={1}", LocalID, identifier);
- }
-
- // Unregister a pre step action. Safe to call if the action has not been registered.
- // Returns 'true' if an action was actually removed.
- protected bool UnRegisterPostStepAction(string op, uint id)
- {
- string identifier = op + "-" + id.ToString();
- bool removed = false;
- lock (RegisteredPoststepActions)
- {
- if (RegisteredPoststepActions.ContainsKey(identifier))
- {
- PhysicsScene.AfterStep -= RegisteredPoststepActions[identifier];
- RegisteredPoststepActions.Remove(identifier);
- removed = true;
- }
- }
- DetailLog("{0},BSPhysObject.UnRegisterPostStepAction,id={1},removed={2}", LocalID, identifier, removed);
- return removed;
- }
-
- protected void UnRegisterAllPostStepActions()
- {
- lock (RegisteredPoststepActions)
- {
- foreach (KeyValuePair kvp in RegisteredPoststepActions)
- {
- PhysicsScene.AfterStep -= kvp.Value;
- }
- RegisteredPoststepActions.Clear();
- }
- DetailLog("{0},BSPhysObject.UnRegisterAllPostStepActions,", LocalID);
- }
-
// When an update to the physical properties happens, this event is fired to let
// different actors to modify the update before it is passed around
public delegate void PreUpdatePropertyAction(ref EntityProperties entprop);
@@ -533,46 +507,6 @@ public abstract class BSPhysObject : PhysicsActor
actions(ref entprop);
}
- private Dictionary RegisteredPreUpdatePropertyActions = new Dictionary();
- public void RegisterPreUpdatePropertyAction(string identifier, PreUpdatePropertyAction actn)
- {
- lock (RegisteredPreUpdatePropertyActions)
- {
- // Clean out any existing action
- UnRegisterPreUpdatePropertyAction(identifier);
- RegisteredPreUpdatePropertyActions[identifier] = actn;
- OnPreUpdateProperty += actn;
- }
- DetailLog("{0},BSPhysObject.RegisterPreUpdatePropertyAction,id={1}", LocalID, identifier);
- }
- public bool UnRegisterPreUpdatePropertyAction(string identifier)
- {
- bool removed = false;
- lock (RegisteredPreUpdatePropertyActions)
- {
- if (RegisteredPreUpdatePropertyActions.ContainsKey(identifier))
- {
- OnPreUpdateProperty -= RegisteredPreUpdatePropertyActions[identifier];
- RegisteredPreUpdatePropertyActions.Remove(identifier);
- removed = true;
- }
- }
- DetailLog("{0},BSPhysObject.UnRegisterPreUpdatePropertyAction,id={1},removed={2}", LocalID, identifier, removed);
- return removed;
- }
- public void UnRegisterAllPreUpdatePropertyActions()
- {
- lock (RegisteredPreUpdatePropertyActions)
- {
- foreach (KeyValuePair kvp in RegisteredPreUpdatePropertyActions)
- {
- OnPreUpdateProperty -= kvp.Value;
- }
- RegisteredPreUpdatePropertyActions.Clear();
- }
- DetailLog("{0},BSPhysObject.UnRegisterAllPreUpdatePropertyAction,", LocalID);
- }
-
#endregion // Per Simulation Step actions
// High performance detailed logging routine used by the physical objects.
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index e56276a..71fea59 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -55,9 +55,6 @@ public class BSPrim : BSPhysObject
private OMV.Vector3 _position;
private float _mass; // the mass of this object
- private OMV.Vector3 _force;
- private OMV.Vector3 _velocity;
- private OMV.Vector3 _torque;
private OMV.Vector3 _acceleration;
private OMV.Quaternion _orientation;
private int _physicsActorType;
@@ -73,16 +70,13 @@ public class BSPrim : BSPhysObject
private int CrossingFailures { get; set; }
public BSDynamics VehicleActor;
- public string VehicleActorName = "BasicVehicle";
+ public const string VehicleActorName = "BasicVehicle";
- private BSVMotor _targetMotor;
- private OMV.Vector3 _PIDTarget;
- private float _PIDTau;
-
- private BSFMotor _hoverMotor;
- private float _PIDHoverHeight;
- private PIDHoverType _PIDHoverType;
- private float _PIDHoverTau;
+ public const string HoverActorName = "HoverActor";
+ public const String LockedAxisActorName = "BSPrim.LockedAxis";
+ public const string MoveToTargetActorName = "MoveToTargetActor";
+ public const string SetForceActorName = "SetForceActor";
+ public const string SetTorqueActorName = "SetTorqueActor";
public BSPrim(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size,
OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical)
@@ -95,7 +89,7 @@ public class BSPrim : BSPhysObject
Scale = size; // prims are the size the user wants them to be (different for BSCharactes).
_orientation = rotation;
_buoyancy = 0f;
- _velocity = OMV.Vector3.Zero;
+ RawVelocity = OMV.Vector3.Zero;
_rotationalVelocity = OMV.Vector3.Zero;
BaseShape = pbs;
_isPhysical = pisPhysical;
@@ -233,7 +227,7 @@ public class BSPrim : BSPhysObject
// Called at taint time!
public override void ZeroMotion(bool inTaintTime)
{
- _velocity = OMV.Vector3.Zero;
+ RawVelocity = OMV.Vector3.Zero;
_acceleration = OMV.Vector3.Zero;
_rotationalVelocity = OMV.Vector3.Zero;
@@ -270,19 +264,17 @@ public class BSPrim : BSPhysObject
if (axis.Z != 1) locking.Z = 0f;
LockedAxis = locking;
- if (LockedAxis != LockedAxisFree)
+ CreateRemoveActor(LockedAxis != LockedAxisFree /* creatActor */, LockedAxisActorName, false /* inTaintTime */, delegate()
{
- PhysicsScene.TaintedObject("BSPrim.LockAngularMotion", delegate()
- {
- // If there is not already an axis locker, make one
- if (!PhysicalActors.HasActor(LockedAxisActorName))
- {
- DetailLog("{0},BSPrim.LockAngularMotion,taint,registeringLockAxisActor", LocalID);
- PhysicalActors.Add(LockedAxisActorName, new BSActorLockAxis(PhysicsScene, this, LockedAxisActorName));
- }
- UpdatePhysicalParameters();
- });
- }
+ return new BSActorLockAxis(PhysicsScene, this, LockedAxisActorName);
+ });
+
+ // Update parameters so the new actor's Refresh() action is called at the right time.
+ PhysicsScene.TaintedObject("BSPrim.LockAngularMotion", delegate()
+ {
+ UpdatePhysicalParameters();
+ });
+
return;
}
@@ -407,9 +399,9 @@ public class BSPrim : BSPhysObject
ZeroMotion(inTaintTime);
ret = true;
}
- if (_velocity.LengthSquared() > BSParam.MaxLinearVelocity)
+ if (RawVelocity.LengthSquared() > BSParam.MaxLinearVelocity)
{
- _velocity = Util.ClampV(_velocity, BSParam.MaxLinearVelocity);
+ RawVelocity = Util.ClampV(RawVelocity, BSParam.MaxLinearVelocity);
ret = true;
}
if (_rotationalVelocity.LengthSquared() > BSParam.MaxAngularVelocitySquared)
@@ -506,35 +498,13 @@ public class BSPrim : BSPhysObject
}
public override OMV.Vector3 Force {
- get { return _force; }
+ get { return RawForce; }
set {
- _force = value;
- if (_force != OMV.Vector3.Zero)
- {
- // If the force is non-zero, it must be reapplied each tick because
- // Bullet clears the forces applied last frame.
- RegisterPreStepAction("BSPrim.setForce", LocalID,
- delegate(float timeStep)
- {
- if (!IsPhysicallyActive || _force == OMV.Vector3.Zero)
- {
- UnRegisterPreStepAction("BSPrim.setForce", LocalID);
- return;
- }
-
- DetailLog("{0},BSPrim.setForce,preStep,force={1}", LocalID, _force);
- if (PhysBody.HasPhysicalBody)
- {
- PhysicsScene.PE.ApplyCentralForce(PhysBody, _force);
- ActivateIfPhysical(false);
- }
- }
- );
- }
- else
+ RawForce = value;
+ CreateRemoveActor(RawForce == OMV.Vector3.Zero, SetForceActorName, false /* inTaintTime */, delegate()
{
- UnRegisterPreStepAction("BSPrim.setForce", LocalID);
- }
+ return new BSActorSetForce(PhysicsScene, this, SetForceActorName);
+ });
}
}
@@ -670,62 +640,39 @@ public class BSPrim : BSPhysObject
}
}
}
- public override OMV.Vector3 RawVelocity
- {
- get { return _velocity; }
- set { _velocity = value; }
- }
public override OMV.Vector3 Velocity {
- get { return _velocity; }
+ get { return RawVelocity; }
set {
- _velocity = value;
+ RawVelocity = value;
PhysicsScene.TaintedObject("BSPrim.setVelocity", delegate()
{
- // DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity);
- ForceVelocity = _velocity;
+ // DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, RawVelocity);
+ ForceVelocity = RawVelocity;
});
}
}
public override OMV.Vector3 ForceVelocity {
- get { return _velocity; }
+ get { return RawVelocity; }
set {
PhysicsScene.AssertInTaintTime("BSPrim.ForceVelocity");
- _velocity = Util.ClampV(value, BSParam.MaxLinearVelocity);
+ RawVelocity = Util.ClampV(value, BSParam.MaxLinearVelocity);
if (PhysBody.HasPhysicalBody)
{
- DetailLog("{0},BSPrim.ForceVelocity,taint,vel={1}", LocalID, _velocity);
- PhysicsScene.PE.SetLinearVelocity(PhysBody, _velocity);
+ DetailLog("{0},BSPrim.ForceVelocity,taint,vel={1}", LocalID, RawVelocity);
+ PhysicsScene.PE.SetLinearVelocity(PhysBody, RawVelocity);
ActivateIfPhysical(false);
}
}
}
public override OMV.Vector3 Torque {
- get { return _torque; }
+ get { return RawTorque; }
set {
- _torque = value;
- if (_torque != OMV.Vector3.Zero)
+ RawTorque = value;
+ CreateRemoveActor(RawTorque == OMV.Vector3.Zero, SetTorqueActorName, false /* inTaintTime */, delegate()
{
- // If the torque is non-zero, it must be reapplied each tick because
- // Bullet clears the forces applied last frame.
- RegisterPreStepAction("BSPrim.setTorque", LocalID,
- delegate(float timeStep)
- {
- if (!IsPhysicallyActive || _torque == OMV.Vector3.Zero)
- {
- UnRegisterPreStepAction("BSPrim.setTorque", LocalID);
- return;
- }
-
- if (PhysBody.HasPhysicalBody)
- AddAngularForce(_torque, false, true);
- }
- );
- }
- else
- {
- UnRegisterPreStepAction("BSPrim.setTorque", LocalID);
- }
+ return new BSActorSetTorque(PhysicsScene, this, SetTorqueActorName);
+ });
// DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, _torque);
}
}
@@ -909,7 +856,7 @@ public class BSPrim : BSPhysObject
// For good measure, make sure the transform is set through to the motion state
ForcePosition = _position;
- ForceVelocity = _velocity;
+ ForceVelocity = RawVelocity;
ForceRotationalVelocity = _rotationalVelocity;
// A dynamic object has mass
@@ -966,15 +913,6 @@ public class BSPrim : BSPhysObject
}
}
- // Enable physical actions. Bullet will keep sleeping non-moving physical objects so
- // they need waking up when parameters are changed.
- // Called in taint-time!!
- private void ActivateIfPhysical(bool forceIt)
- {
- if (IsPhysical && PhysBody.HasPhysicalBody)
- PhysicsScene.PE.Activate(PhysBody, forceIt);
- }
-
// Turn on or off the flag controlling whether collision events are returned to the simulator.
private void EnableCollisions(bool wantsCollisionEvents)
{
@@ -1096,78 +1034,13 @@ public class BSPrim : BSPhysObject
}
}
- // Used for MoveTo
- public override OMV.Vector3 PIDTarget {
- set
- {
- // TODO: add a sanity check -- don't move more than a region or something like that.
- _PIDTarget = value;
- }
- }
- public override float PIDTau {
- set { _PIDTau = value; }
- }
public override bool PIDActive {
set {
- if (value)
- {
- // We're taking over after this.
- ZeroMotion(true);
-
- _targetMotor = new BSVMotor("BSPrim.PIDTarget",
- _PIDTau, // timeScale
- BSMotor.Infinite, // decay time scale
- BSMotor.InfiniteVector, // friction timescale
- 1f // efficiency
- );
- _targetMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages.
- _targetMotor.SetTarget(_PIDTarget);
- _targetMotor.SetCurrent(RawPosition);
- /*
- _targetMotor = new BSPIDVMotor("BSPrim.PIDTarget");
- _targetMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages.
-
- _targetMotor.SetTarget(_PIDTarget);
- _targetMotor.SetCurrent(RawPosition);
- _targetMotor.TimeScale = _PIDTau;
- _targetMotor.Efficiency = 1f;
- */
-
- RegisterPreStepAction("BSPrim.PIDTarget", LocalID, delegate(float timeStep)
- {
- if (!IsPhysicallyActive)
- {
- UnRegisterPreStepAction("BSPrim.PIDTarget", LocalID);
- return;
- }
-
- OMV.Vector3 origPosition = RawPosition; // DEBUG DEBUG (for printout below)
-
- // 'movePosition' is where we'd like the prim to be at this moment.
- OMV.Vector3 movePosition = RawPosition + _targetMotor.Step(timeStep);
-
- // If we are very close to our target, turn off the movement motor.
- if (_targetMotor.ErrorIsZero())
- {
- DetailLog("{0},BSPrim.PIDTarget,zeroMovement,movePos={1},pos={2},mass={3}",
- LocalID, movePosition, RawPosition, Mass);
- ForcePosition = _targetMotor.TargetValue;
- _targetMotor.Enabled = false;
- }
- else
- {
- _position = movePosition;
- PositionSanityCheck(true /* intaintTime */);
- ForcePosition = _position;
- }
- DetailLog("{0},BSPrim.PIDTarget,move,fromPos={1},movePos={2}", LocalID, origPosition, movePosition);
- });
- }
- else
+ base.MoveToTargetActive = value;
+ CreateRemoveActor(MoveToTargetActive, MoveToTargetActorName, false /* inTaintTime */, delegate()
{
- // Stop any targetting
- UnRegisterPreStepAction("BSPrim.PIDTarget", LocalID);
- }
+ return new BSActorMoveToTarget(PhysicsScene, this, MoveToTargetActorName);
+ });
}
}
@@ -1175,88 +1048,14 @@ public class BSPrim : BSPhysObject
// Hover Height will override MoveTo target's Z
public override bool PIDHoverActive {
set {
- if (value)
- {
- // Turning the target on
- _hoverMotor = new BSFMotor("BSPrim.Hover",
- _PIDHoverTau, // timeScale
- BSMotor.Infinite, // decay time scale
- BSMotor.Infinite, // friction timescale
- 1f // efficiency
- );
- _hoverMotor.SetTarget(ComputeCurrentPIDHoverHeight());
- _hoverMotor.SetCurrent(RawPosition.Z);
- _hoverMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages.
-
- RegisterPreStepAction("BSPrim.Hover", LocalID, delegate(float timeStep)
- {
- // Don't do hovering while the object is selected.
- if (!IsPhysicallyActive)
- return;
-
- _hoverMotor.SetCurrent(RawPosition.Z);
- _hoverMotor.SetTarget(ComputeCurrentPIDHoverHeight());
- float targetHeight = _hoverMotor.Step(timeStep);
-
- // 'targetHeight' is where we'd like the Z of the prim to be at this moment.
- // Compute the amount of force to push us there.
- float moveForce = (targetHeight - RawPosition.Z) * Mass;
- // Undo anything the object thinks it's doing at the moment
- moveForce = -RawVelocity.Z * Mass;
-
- PhysicsScene.PE.ApplyCentralImpulse(PhysBody, new OMV.Vector3(0f, 0f, moveForce));
- DetailLog("{0},BSPrim.Hover,move,targHt={1},moveForce={2},mass={3}", LocalID, targetHeight, moveForce, Mass);
- });
- }
- else
+ base.HoverActive = value;
+ CreateRemoveActor(HoverActive /* creatActor */, HoverActorName, false /* inTaintTime */, delegate()
{
- UnRegisterPreStepAction("BSPrim.Hover", LocalID);
- }
- }
- }
- public override float PIDHoverHeight {
- set { _PIDHoverHeight = value; }
- }
- public override PIDHoverType PIDHoverType {
- set { _PIDHoverType = value; }
- }
- public override float PIDHoverTau {
- set { _PIDHoverTau = value; }
- }
- // Based on current position, determine what we should be hovering at now.
- // Must recompute often. What if we walked offa cliff>
- private float ComputeCurrentPIDHoverHeight()
- {
- float ret = _PIDHoverHeight;
- float groundHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(RawPosition);
-
- switch (_PIDHoverType)
- {
- case PIDHoverType.Ground:
- ret = groundHeight + _PIDHoverHeight;
- break;
- case PIDHoverType.GroundAndWater:
- float waterHeight = PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(RawPosition);
- if (groundHeight > waterHeight)
- {
- ret = groundHeight + _PIDHoverHeight;
- }
- else
- {
- ret = waterHeight + _PIDHoverHeight;
- }
- break;
+ return new BSActorHover(PhysicsScene, this, HoverActorName);
+ });
}
- return ret;
}
-
- // For RotLookAt
- public override OMV.Quaternion APIDTarget { set { return; } }
- public override bool APIDActive { set { return; } }
- public override float APIDStrength { set { return; } }
- public override float APIDDamping { set { return; } }
-
public override void AddForce(OMV.Vector3 force, bool pushforce) {
// Per documentation, max force is limited.
OMV.Vector3 addForce = Util.ClampV(force, BSParam.MaxAddForceMagnitude);
@@ -1324,10 +1123,8 @@ public class BSPrim : BSPhysObject
}
}
- public override void AddAngularForce(OMV.Vector3 force, bool pushforce) {
- AddAngularForce(force, pushforce, false);
- }
- public void AddAngularForce(OMV.Vector3 force, bool pushforce, bool inTaintTime)
+ // BSPhysObject.AddAngularForce()
+ public override void AddAngularForce(OMV.Vector3 force, bool pushforce, bool inTaintTime)
{
if (force.IsFinite())
{
@@ -1694,8 +1491,8 @@ public class BSPrim : BSPhysObject
_orientation = entprop.Rotation;
// DEBUG DEBUG DEBUG -- smooth velocity changes a bit. The simulator seems to be
// very sensitive to velocity changes.
- if (entprop.Velocity == OMV.Vector3.Zero || !entprop.Velocity.ApproxEquals(_velocity, BSParam.UpdateVelocityChangeThreshold))
- _velocity = entprop.Velocity;
+ if (entprop.Velocity == OMV.Vector3.Zero || !entprop.Velocity.ApproxEquals(RawVelocity, BSParam.UpdateVelocityChangeThreshold))
+ RawVelocity = entprop.Velocity;
_acceleration = entprop.Acceleration;
_rotationalVelocity = entprop.RotationalVelocity;
@@ -1705,7 +1502,7 @@ public class BSPrim : BSPhysObject
if (PositionSanityCheck(true /* inTaintTime */ ))
{
entprop.Position = _position;
- entprop.Velocity = _velocity;
+ entprop.Velocity = RawVelocity;
entprop.RotationalVelocity = _rotationalVelocity;
entprop.Acceleration = _acceleration;
}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt
index 8a15abe..a0131c7 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt
+++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt
@@ -6,7 +6,6 @@ Enable vehicle border crossings (at least as poorly as ODE)
Terrain skirts
Avatar created in previous region and not new region when crossing border
Vehicle recreated in new sim at small Z value (offset from root value?) (DONE)
-Lock axis
Deleting a linkset while standing on the root will leave the physical shape of the root behind.
Not sure if it is because standing on it. Done with large prim linksets.
Linkset child rotations.
@@ -344,3 +343,5 @@ Angular motion around Z moves the vehicle in world Z and not vehicle Z in ODE.
Verify that angular motion specified around Z moves in the vehicle coordinates.
DONE 20130120: BulletSim properly applies force in vehicle relative coordinates.
Nebadon vehicles turning funny in arena (DONE)
+Lock axis (DONE 20130401)
+
--
cgit v1.1
From a7a1b8b7e9269b446e3396a35153b00942c1e35b Mon Sep 17 00:00:00 2001
From: Robert Adams
Date: Sun, 7 Apr 2013 14:05:35 -0700
Subject: BulletSim: clean up actor code so routines use the same coding
pattern. Fix a few enabling problems.
---
.../Physics/BulletSPlugin/BSActorAvatarMove.cs | 22 ++---
.../Region/Physics/BulletSPlugin/BSActorHover.cs | 6 +-
.../Physics/BulletSPlugin/BSActorLockAxis.cs | 105 ++++++++++-----------
.../Physics/BulletSPlugin/BSActorMoveToTarget.cs | 12 +--
.../Physics/BulletSPlugin/BSActorSetForce.cs | 2 +-
.../Physics/BulletSPlugin/BSActorSetTorque.cs | 4 +-
OpenSim/Region/Physics/BulletSPlugin/BSActors.cs | 49 +++++++---
.../Region/Physics/BulletSPlugin/BSCharacter.cs | 3 +
.../Region/Physics/BulletSPlugin/BSPhysObject.cs | 35 +++----
OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 22 ++---
10 files changed, 137 insertions(+), 123 deletions(-)
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs b/OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs
index 634a898..8416740 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs
@@ -67,14 +67,6 @@ public class BSActorAvatarMove : BSActor
{
m_physicsScene.DetailLog("{0},BSActorAvatarMove,refresh", m_controllingPrim.LocalID);
- // If not active any more, get rid of me (shouldn't ever happen, but just to be safe)
- if (m_controllingPrim.RawForce == OMV.Vector3.Zero)
- {
- m_physicsScene.DetailLog("{0},BSActorAvatarMove,refresh,notAvatarMove,removing={1}", m_controllingPrim.LocalID, ActorName);
- m_controllingPrim.PhysicalActors.RemoveAndRelease(ActorName);
- return;
- }
-
// If the object is physically active, add the hoverer prestep action
if (isActive)
{
@@ -95,14 +87,19 @@ public class BSActorAvatarMove : BSActor
// Nothing to do for the hoverer since it is all software at pre-step action time.
}
+ // Usually called when target velocity changes to set the current velocity and the target
+ // into the movement motor.
public void SetVelocityAndTarget(OMV.Vector3 vel, OMV.Vector3 targ, bool inTaintTime)
{
m_physicsScene.TaintedObject(inTaintTime, "BSActorAvatarMove.setVelocityAndTarget", delegate()
{
- m_velocityMotor.Reset();
- m_velocityMotor.SetTarget(targ);
- m_velocityMotor.SetCurrent(vel);
- m_velocityMotor.Enabled = true;
+ if (m_velocityMotor != null)
+ {
+ m_velocityMotor.Reset();
+ m_velocityMotor.SetTarget(targ);
+ m_velocityMotor.SetCurrent(vel);
+ m_velocityMotor.Enabled = true;
+ }
});
}
@@ -119,6 +116,7 @@ public class BSActorAvatarMove : BSActor
1f // efficiency
);
// _velocityMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages.
+ SetVelocityAndTarget(m_controllingPrim.RawVelocity, m_controllingPrim.TargetVelocity, true /* inTaintTime */);
m_physicsScene.BeforeStep += Mover;
}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSActorHover.cs b/OpenSim/Region/Physics/BulletSPlugin/BSActorHover.cs
index 8dd3700..e8310df 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSActorHover.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSActorHover.cs
@@ -67,12 +67,10 @@ public class BSActorHover : BSActor
{
m_physicsScene.DetailLog("{0},BSActorHover,refresh", m_controllingPrim.LocalID);
- // If not active any more, get rid of me (shouldn't ever happen, but just to be safe)
+ // If not active any more, turn me off
if (!m_controllingPrim.HoverActive)
{
- m_physicsScene.DetailLog("{0},BSActorHover,refresh,notHovering,removing={1}", m_controllingPrim.LocalID, ActorName);
- m_controllingPrim.PhysicalActors.RemoveAndRelease(ActorName);
- return;
+ SetEnabled(false);
}
// If the object is physically active, add the hoverer prestep action
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSActorLockAxis.cs b/OpenSim/Region/Physics/BulletSPlugin/BSActorLockAxis.cs
index c40a499..09ee32b 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSActorLockAxis.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSActorLockAxis.cs
@@ -36,7 +36,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
{
public class BSActorLockAxis : BSActor
{
- bool TryExperimentalLockAxisCode = true;
BSConstraint LockAxisConstraint = null;
public BSActorLockAxis(BSScene physicsScene, BSPhysObject pObj, string actorName)
@@ -69,18 +68,13 @@ public class BSActorLockAxis : BSActor
// If all the axis are free, we don't need to exist
if (m_controllingPrim.LockedAxis == m_controllingPrim.LockedAxisFree)
{
- m_physicsScene.DetailLog("{0},BSActorLockAxis,refresh,allAxisFree,removing={1}", m_controllingPrim.LocalID, ActorName);
- m_controllingPrim.PhysicalActors.RemoveAndRelease(ActorName);
- return;
+ Enabled = false;
}
+
// If the object is physically active, add the axis locking constraint
- if (Enabled
- && m_controllingPrim.IsPhysicallyActive
- && TryExperimentalLockAxisCode
- && m_controllingPrim.LockedAxis != m_controllingPrim.LockedAxisFree)
+ if (isActive)
{
- if (LockAxisConstraint == null)
- AddAxisLockConstraint();
+ AddAxisLockConstraint();
}
else
{
@@ -108,58 +102,61 @@ public class BSActorLockAxis : BSActor
private void AddAxisLockConstraint()
{
- // Lock that axis by creating a 6DOF constraint that has one end in the world and
- // the other in the object.
- // http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?p=20817
- // http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?p=26380
+ if (LockAxisConstraint == null)
+ {
+ // Lock that axis by creating a 6DOF constraint that has one end in the world and
+ // the other in the object.
+ // http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?p=20817
+ // http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?p=26380
- // Remove any existing axis constraint (just to be sure)
- RemoveAxisLockConstraint();
+ // Remove any existing axis constraint (just to be sure)
+ RemoveAxisLockConstraint();
- BSConstraint6Dof axisConstrainer = new BSConstraint6Dof(m_physicsScene.World, m_controllingPrim.PhysBody,
- OMV.Vector3.Zero, OMV.Quaternion.Identity,
- false /* useLinearReferenceFrameB */, true /* disableCollisionsBetweenLinkedBodies */);
- LockAxisConstraint = axisConstrainer;
- m_physicsScene.Constraints.AddConstraint(LockAxisConstraint);
+ BSConstraint6Dof axisConstrainer = new BSConstraint6Dof(m_physicsScene.World, m_controllingPrim.PhysBody,
+ OMV.Vector3.Zero, OMV.Quaternion.Identity,
+ false /* useLinearReferenceFrameB */, true /* disableCollisionsBetweenLinkedBodies */);
+ LockAxisConstraint = axisConstrainer;
+ m_physicsScene.Constraints.AddConstraint(LockAxisConstraint);
- // The constraint is tied to the world and oriented to the prim.
+ // The constraint is tied to the world and oriented to the prim.
- // Free to move linearly in the region
- OMV.Vector3 linearLow = OMV.Vector3.Zero;
- OMV.Vector3 linearHigh = m_physicsScene.TerrainManager.DefaultRegionSize;
- axisConstrainer.SetLinearLimits(linearLow, linearHigh);
+ // Free to move linearly in the region
+ OMV.Vector3 linearLow = OMV.Vector3.Zero;
+ OMV.Vector3 linearHigh = m_physicsScene.TerrainManager.DefaultRegionSize;
+ axisConstrainer.SetLinearLimits(linearLow, linearHigh);
- // Angular with some axis locked
- float fPI = (float)Math.PI;
- OMV.Vector3 angularLow = new OMV.Vector3(-fPI, -fPI, -fPI);
- OMV.Vector3 angularHigh = new OMV.Vector3(fPI, fPI, fPI);
- if (m_controllingPrim.LockedAxis.X != 1f)
- {
- angularLow.X = 0f;
- angularHigh.X = 0f;
- }
- if (m_controllingPrim.LockedAxis.Y != 1f)
- {
- angularLow.Y = 0f;
- angularHigh.Y = 0f;
- }
- if (m_controllingPrim.LockedAxis.Z != 1f)
- {
- angularLow.Z = 0f;
- angularHigh.Z = 0f;
- }
- if (!axisConstrainer.SetAngularLimits(angularLow, angularHigh))
- {
- m_physicsScene.DetailLog("{0},BSActorLockAxis.AddAxisLockConstraint,failedSetAngularLimits", m_controllingPrim.LocalID);
- }
+ // Angular with some axis locked
+ float fPI = (float)Math.PI;
+ OMV.Vector3 angularLow = new OMV.Vector3(-fPI, -fPI, -fPI);
+ OMV.Vector3 angularHigh = new OMV.Vector3(fPI, fPI, fPI);
+ if (m_controllingPrim.LockedAxis.X != 1f)
+ {
+ angularLow.X = 0f;
+ angularHigh.X = 0f;
+ }
+ if (m_controllingPrim.LockedAxis.Y != 1f)
+ {
+ angularLow.Y = 0f;
+ angularHigh.Y = 0f;
+ }
+ if (m_controllingPrim.LockedAxis.Z != 1f)
+ {
+ angularLow.Z = 0f;
+ angularHigh.Z = 0f;
+ }
+ if (!axisConstrainer.SetAngularLimits(angularLow, angularHigh))
+ {
+ m_physicsScene.DetailLog("{0},BSActorLockAxis.AddAxisLockConstraint,failedSetAngularLimits", m_controllingPrim.LocalID);
+ }
- m_physicsScene.DetailLog("{0},BSActorLockAxis.AddAxisLockConstraint,create,linLow={1},linHi={2},angLow={3},angHi={4}",
- m_controllingPrim.LocalID, linearLow, linearHigh, angularLow, angularHigh);
+ m_physicsScene.DetailLog("{0},BSActorLockAxis.AddAxisLockConstraint,create,linLow={1},linHi={2},angLow={3},angHi={4}",
+ m_controllingPrim.LocalID, linearLow, linearHigh, angularLow, angularHigh);
- // Constants from one of the posts mentioned above and used in Bullet's ConstraintDemo.
- axisConstrainer.TranslationalLimitMotor(true /* enable */, 5.0f, 0.1f);
+ // Constants from one of the posts mentioned above and used in Bullet's ConstraintDemo.
+ axisConstrainer.TranslationalLimitMotor(true /* enable */, 5.0f, 0.1f);
- axisConstrainer.RecomputeConstraintVariables(m_controllingPrim.RawMass);
+ axisConstrainer.RecomputeConstraintVariables(m_controllingPrim.RawMass);
+ }
}
private void RemoveAxisLockConstraint()
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSActorMoveToTarget.cs b/OpenSim/Region/Physics/BulletSPlugin/BSActorMoveToTarget.cs
index 3517ef2..16c2b14 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSActorMoveToTarget.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSActorMoveToTarget.cs
@@ -67,15 +67,12 @@ public class BSActorMoveToTarget : BSActor
{
m_physicsScene.DetailLog("{0},BSActorMoveToTarget,refresh", m_controllingPrim.LocalID);
- // If not active any more, get rid of me (shouldn't ever happen, but just to be safe)
- if (!m_controllingPrim.HoverActive)
+ // If not active any more...
+ if (!m_controllingPrim.MoveToTargetActive)
{
- m_physicsScene.DetailLog("{0},BSActorMoveToTarget,refresh,notMoveToTarget,removing={1}", m_controllingPrim.LocalID, ActorName);
- m_controllingPrim.PhysicalActors.RemoveAndRelease(ActorName);
- return;
+ Enabled = false;
}
- // If the object is physically active, add the hoverer prestep action
if (isActive)
{
ActivateMoveToTarget();
@@ -92,7 +89,7 @@ public class BSActorMoveToTarget : BSActor
// BSActor.RemoveBodyDependencies()
public override void RemoveBodyDependencies()
{
- // Nothing to do for the hoverer since it is all software at pre-step action time.
+ // Nothing to do for the moveToTarget since it is all software at pre-step action time.
}
// If a hover motor has not been created, create one and start the hovering.
@@ -144,7 +141,6 @@ public class BSActorMoveToTarget : BSActor
m_physicsScene.DetailLog("{0},BSPrim.PIDTarget,zeroMovement,movePos={1},pos={2},mass={3}",
m_controllingPrim.LocalID, movePosition, m_controllingPrim.RawPosition, m_controllingPrim.Mass);
m_controllingPrim.ForcePosition = m_targetMotor.TargetValue;
- m_targetMotor.Enabled = false;
}
else
{
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSActorSetForce.cs b/OpenSim/Region/Physics/BulletSPlugin/BSActorSetForce.cs
index d942490..3ad138d 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSActorSetForce.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSActorSetForce.cs
@@ -71,7 +71,7 @@ public class BSActorSetForce : BSActor
if (m_controllingPrim.RawForce == OMV.Vector3.Zero)
{
m_physicsScene.DetailLog("{0},BSActorSetForce,refresh,notSetForce,removing={1}", m_controllingPrim.LocalID, ActorName);
- m_controllingPrim.PhysicalActors.RemoveAndRelease(ActorName);
+ Enabled = false;
return;
}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSActorSetTorque.cs b/OpenSim/Region/Physics/BulletSPlugin/BSActorSetTorque.cs
index e0f719f..159a3a8 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSActorSetTorque.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSActorSetTorque.cs
@@ -70,8 +70,8 @@ public class BSActorSetTorque : BSActor
// If not active any more, get rid of me (shouldn't ever happen, but just to be safe)
if (m_controllingPrim.RawTorque == OMV.Vector3.Zero)
{
- m_physicsScene.DetailLog("{0},BSActorSetTorque,refresh,notSetTorque,removing={1}", m_controllingPrim.LocalID, ActorName);
- m_controllingPrim.PhysicalActors.RemoveAndRelease(ActorName);
+ m_physicsScene.DetailLog("{0},BSActorSetTorque,refresh,notSetTorque,disabling={1}", m_controllingPrim.LocalID, ActorName);
+ Enabled = false;
return;
}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSActors.cs b/OpenSim/Region/Physics/BulletSPlugin/BSActors.cs
index fb4d452..12a8817 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSActors.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSActors.cs
@@ -42,24 +42,36 @@ public class BSActorCollection
}
public void Add(string name, BSActor actor)
{
- m_actors[name] = actor;
+ lock (m_actors)
+ {
+ if (!m_actors.ContainsKey(name))
+ {
+ m_actors[name] = actor;
+ }
+ }
}
public bool RemoveAndRelease(string name)
{
bool ret = false;
- if (m_actors.ContainsKey(name))
+ lock (m_actors)
{
- BSActor beingRemoved = m_actors[name];
- beingRemoved.Dispose();
- m_actors.Remove(name);
- ret = true;
+ if (m_actors.ContainsKey(name))
+ {
+ BSActor beingRemoved = m_actors[name];
+ m_actors.Remove(name);
+ beingRemoved.Dispose();
+ ret = true;
+ }
}
return ret;
}
public void Clear()
{
- Release();
- m_actors.Clear();
+ lock (m_actors)
+ {
+ Release();
+ m_actors.Clear();
+ }
}
public void Dispose()
{
@@ -69,15 +81,22 @@ public class BSActorCollection
{
return m_actors.ContainsKey(name);
}
+ public bool TryGetActor(string actorName, out BSActor theActor)
+ {
+ return m_actors.TryGetValue(actorName, out theActor);
+ }
public void ForEachActor(Action act)
{
- foreach (KeyValuePair kvp in m_actors)
- act(kvp.Value);
+ lock (m_actors)
+ {
+ foreach (KeyValuePair kvp in m_actors)
+ act(kvp.Value);
+ }
}
public void Enable(bool enabl)
{
- ForEachActor(a => a.Enable(enabl));
+ ForEachActor(a => a.SetEnabled(enabl));
}
public void Release()
{
@@ -106,7 +125,7 @@ public abstract class BSActor
{
protected BSScene m_physicsScene { get; private set; }
protected BSPhysObject m_controllingPrim { get; private set; }
- protected bool Enabled { get; set; }
+ public virtual bool Enabled { get; set; }
public string ActorName { get; private set; }
public BSActor(BSScene physicsScene, BSPhysObject pObj, string actorName)
@@ -122,8 +141,10 @@ public abstract class BSActor
{
get { return Enabled; }
}
- // Turn the actor on an off.
- public virtual void Enable(bool setEnabled)
+
+ // Turn the actor on an off. Only used by ActorCollection to set all enabled/disabled.
+ // Anyone else should assign true/false to 'Enabled'.
+ public void SetEnabled(bool setEnabled)
{
Enabled = setEnabled;
}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
index 09c9b16..a0d58d3 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -160,6 +160,9 @@ public sealed class BSCharacter : BSPhysObject
// Make so capsule does not fall over
PhysicsScene.PE.SetAngularFactorV(PhysBody, OMV.Vector3.Zero);
+ // The avatar mover sets some parameters.
+ PhysicalActors.Refresh();
+
PhysicsScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.CF_CHARACTER_OBJECT);
PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, PhysBody);
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
index 644bc7e..64bf395 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
@@ -282,30 +282,31 @@ public abstract class BSPhysObject : PhysicsActor
// 'actors' act on the physical object to change or constrain its motion. These can range from
// hovering to complex vehicle motion.
+ // May be called at non-taint time as this just adds the actor to the action list and the real
+ // work is done during the simulation step.
+ // Note that, if the actor is already in the list and we are disabling same, the actor is just left
+ // in the list disabled.
public delegate BSActor CreateActor();
- public void CreateRemoveActor(bool createRemove, string actorName, bool inTaintTime, CreateActor creator)
+ public void EnableActor(bool enableActor, string actorName, CreateActor creator)
{
- if (createRemove)
+ lock (PhysicalActors)
{
- PhysicsScene.TaintedObject(inTaintTime, "BSPrim.CreateRemoveActor:" + actorName, delegate()
+ BSActor theActor;
+ if (PhysicalActors.TryGetActor(actorName, out theActor))
{
- if (!PhysicalActors.HasActor(actorName))
- {
- DetailLog("{0},BSPrim.CreateRemoveActor,taint,registerActor,a={1}", LocalID, actorName);
- PhysicalActors.Add(actorName, creator());
- }
- });
- }
- else
- {
- PhysicsScene.TaintedObject(inTaintTime, "BSPrim.CreateRemoveActor:" + actorName, delegate()
+ // The actor already exists so just turn it on or off
+ theActor.Enabled = enableActor;
+ }
+ else
{
- if (PhysicalActors.HasActor(actorName))
+ // The actor does not exist. If it should, create it.
+ if (enableActor)
{
- DetailLog("{0},BSPrim.CreateRemoveActor,taint,unregisterActor,a={1}", LocalID, actorName);
- PhysicalActors.RemoveAndRelease(actorName);
+ theActor = creator();
+ PhysicalActors.Add(actorName, theActor);
+ theActor.Enabled = true;
}
- });
+ }
}
}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index 71fea59..16c7a90 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -95,6 +95,7 @@ public class BSPrim : BSPhysObject
_isPhysical = pisPhysical;
_isVolumeDetect = false;
+ // We keep a handle to the vehicle actor so we can set vehicle parameters later.
VehicleActor = new BSDynamics(PhysicsScene, this, VehicleActorName);
PhysicalActors.Add(VehicleActorName, VehicleActor);
@@ -264,7 +265,7 @@ public class BSPrim : BSPhysObject
if (axis.Z != 1) locking.Z = 0f;
LockedAxis = locking;
- CreateRemoveActor(LockedAxis != LockedAxisFree /* creatActor */, LockedAxisActorName, false /* inTaintTime */, delegate()
+ EnableActor(LockedAxis != LockedAxisFree, LockedAxisActorName, delegate()
{
return new BSActorLockAxis(PhysicsScene, this, LockedAxisActorName);
});
@@ -501,7 +502,7 @@ public class BSPrim : BSPhysObject
get { return RawForce; }
set {
RawForce = value;
- CreateRemoveActor(RawForce == OMV.Vector3.Zero, SetForceActorName, false /* inTaintTime */, delegate()
+ EnableActor(RawForce != OMV.Vector3.Zero, SetForceActorName, delegate()
{
return new BSActorSetForce(PhysicsScene, this, SetForceActorName);
});
@@ -510,14 +511,13 @@ public class BSPrim : BSPhysObject
public override int VehicleType {
get {
- return (int)VehicleActor.Type; // if we are a vehicle, return that type
+ return (int)VehicleActor.Type;
}
set {
Vehicle type = (Vehicle)value;
PhysicsScene.TaintedObject("setVehicleType", delegate()
{
- // Done at taint time so we're sure the physics engine is not using the variables
// Vehicle code changes the parameters for this vehicle type.
VehicleActor.ProcessTypeChange(type);
ActivateIfPhysical(false);
@@ -669,11 +669,11 @@ public class BSPrim : BSPhysObject
get { return RawTorque; }
set {
RawTorque = value;
- CreateRemoveActor(RawTorque == OMV.Vector3.Zero, SetTorqueActorName, false /* inTaintTime */, delegate()
+ EnableActor(RawTorque != OMV.Vector3.Zero, SetTorqueActorName, delegate()
{
return new BSActorSetTorque(PhysicsScene, this, SetTorqueActorName);
});
- // DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, _torque);
+ DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, RawTorque);
}
}
public override OMV.Vector3 Acceleration {
@@ -786,7 +786,6 @@ public class BSPrim : BSPhysObject
MakeDynamic(IsStatic);
// Update vehicle specific parameters (after MakeDynamic() so can change physical parameters)
- VehicleActor.Refresh();
PhysicalActors.Refresh();
// Arrange for collision events if the simulator wants them
@@ -1037,7 +1036,7 @@ public class BSPrim : BSPhysObject
public override bool PIDActive {
set {
base.MoveToTargetActive = value;
- CreateRemoveActor(MoveToTargetActive, MoveToTargetActorName, false /* inTaintTime */, delegate()
+ EnableActor(MoveToTargetActive, MoveToTargetActorName, delegate()
{
return new BSActorMoveToTarget(PhysicsScene, this, MoveToTargetActorName);
});
@@ -1049,7 +1048,7 @@ public class BSPrim : BSPhysObject
public override bool PIDHoverActive {
set {
base.HoverActive = value;
- CreateRemoveActor(HoverActive /* creatActor */, HoverActorName, false /* inTaintTime */, delegate()
+ EnableActor(HoverActive, HoverActorName, delegate()
{
return new BSActorHover(PhysicsScene, this, HoverActorName);
});
@@ -1458,7 +1457,7 @@ public class BSPrim : BSPhysObject
{
// Create the correct physical representation for this type of object.
// Updates base.PhysBody and base.PhysShape with the new information.
- // Ignore 'forceRebuild'. This routine makes the right choices and changes of necessary.
+ // Ignore 'forceRebuild'. 'GetBodyAndShape' makes the right choices and changes of necessary.
PhysicsScene.Shapes.GetBodyAndShape(false /*forceRebuild */, PhysicsScene.World, this, null, delegate(BulletBody dBody)
{
// Called if the current prim body is about to be destroyed.
@@ -1472,9 +1471,9 @@ public class BSPrim : BSPhysObject
return;
}
+ // Called at taint-time
protected virtual void RemoveBodyDependencies()
{
- VehicleActor.RemoveBodyDependencies();
PhysicalActors.RemoveBodyDependencies();
}
@@ -1482,6 +1481,7 @@ public class BSPrim : BSPhysObject
// the world that things have changed.
public override void UpdateProperties(EntityProperties entprop)
{
+ // Let anyone (like the actors) modify the updated properties before they are pushed into the object and the simulator.
TriggerPreUpdatePropertyAction(ref entprop);
// DetailLog("{0},BSPrim.UpdateProperties,entry,entprop={1}", LocalID, entprop); // DEBUG DEBUG
--
cgit v1.1
From 99f39836a1879a807bb7d6bf5bf793c3a99584c4 Mon Sep 17 00:00:00 2001
From: Robert Adams
Date: Mon, 8 Apr 2013 06:27:01 -0700
Subject: BulletSim: moving comments around. No functional change.
---
OpenSim/Region/Physics/BulletSPlugin/BSActorSetTorque.cs | 2 +-
OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 10 +---------
OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs | 9 +++++++++
3 files changed, 11 insertions(+), 10 deletions(-)
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSActorSetTorque.cs b/OpenSim/Region/Physics/BulletSPlugin/BSActorSetTorque.cs
index 159a3a8..7a791ec 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSActorSetTorque.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSActorSetTorque.cs
@@ -65,7 +65,7 @@ public class BSActorSetTorque : BSActor
// BSActor.Refresh()
public override void Refresh()
{
- m_physicsScene.DetailLog("{0},BSActorSetTorque,refresh", m_controllingPrim.LocalID);
+ m_physicsScene.DetailLog("{0},BSActorSetTorque,refresh,torque={1}", m_controllingPrim.LocalID, m_controllingPrim.RawTorque);
// If not active any more, get rid of me (shouldn't ever happen, but just to be safe)
if (m_controllingPrim.RawTorque == OMV.Vector3.Zero)
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index 16c7a90..3423d2e 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -1514,16 +1514,8 @@ public class BSPrim : BSPhysObject
LastEntityProperties = CurrentEntityProperties;
CurrentEntityProperties = entprop;
+ // Note that BSPrim can be overloaded by BSPrimLinkable which controls updates from root and children prims.
base.RequestPhysicsterseUpdate();
- /*
- else
- {
- // For debugging, report the movement of children
- DetailLog("{0},BSPrim.UpdateProperties,child,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
- LocalID, entprop.Position, entprop.Rotation, entprop.Velocity,
- entprop.Acceleration, entprop.RotationalVelocity);
- }
- */
}
}
}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs
index d65d407..28242d4 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs
@@ -163,6 +163,15 @@ public class BSPrimLinkable : BSPrimDisplaced
// TODO: this will have to change when linksets are articulated.
base.UpdateProperties(entprop);
}
+ /*
+ else
+ {
+ // For debugging, report the movement of children
+ DetailLog("{0},BSPrim.UpdateProperties,child,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
+ LocalID, entprop.Position, entprop.Rotation, entprop.Velocity,
+ entprop.Acceleration, entprop.RotationalVelocity);
+ }
+ */
// The linkset might like to know about changing locations
Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this);
}
--
cgit v1.1
From f68b963596e7df2c28761af4584b4dcb17d550eb Mon Sep 17 00:00:00 2001
From: Jon Cundill
Date: Sun, 7 Apr 2013 12:31:49 +0100
Subject: fixed bullet config for osx
Signed-off-by: Robert Adams
---
bin/Physics/OpenSim.Region.Physics.BulletSPlugin.dll.config | 2 ++
1 file changed, 2 insertions(+)
diff --git a/bin/Physics/OpenSim.Region.Physics.BulletSPlugin.dll.config b/bin/Physics/OpenSim.Region.Physics.BulletSPlugin.dll.config
index 1bc7e41..2763525 100755
--- a/bin/Physics/OpenSim.Region.Physics.BulletSPlugin.dll.config
+++ b/bin/Physics/OpenSim.Region.Physics.BulletSPlugin.dll.config
@@ -1,6 +1,8 @@
+
+
--
cgit v1.1
From 4d2203ff5298ffe40902ce018c1be1b4096c936d Mon Sep 17 00:00:00 2001
From: Robert Adams
Date: Mon, 8 Apr 2013 09:15:20 -0700
Subject: BulletSim: Add dylib for BulletSim and add he who figured out
building BulletSim on a Mac to the CONTRIBUTORS file.
---
CONTRIBUTORS.txt | 1 +
bin/lib32/libBulletSim.dylib | Bin 0 -> 1181656 bytes
2 files changed, 1 insertion(+)
create mode 100755 bin/lib32/libBulletSim.dylib
diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt
index 8ff55df..36b17be 100644
--- a/CONTRIBUTORS.txt
+++ b/CONTRIBUTORS.txt
@@ -101,6 +101,7 @@ what it is today.
* jhurliman
* John R Sohn (XenReborn)
* jonc
+* Jon Cundill
* Junta Kohime
* Kayne
* Kevin Cozens
diff --git a/bin/lib32/libBulletSim.dylib b/bin/lib32/libBulletSim.dylib
new file mode 100755
index 0000000..02f8a7f
Binary files /dev/null and b/bin/lib32/libBulletSim.dylib differ
--
cgit v1.1
From 8e04c752fc2bc1f27fce224d2aec3ea72edbc2cc Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Tue, 9 Apr 2013 22:38:47 +0100
Subject: If OpenSimulator is writing a PID file and finds the file already
present on startup, logging an error since this is commonly due to an unclean
shutdown.
Unclean shutdown can cause constantly moving objects to disappear if an OAR has just been loaded and they have not reached persistence time threshold, among other problems.
---
OpenSim/Framework/Servers/ServerBase.cs | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/OpenSim/Framework/Servers/ServerBase.cs b/OpenSim/Framework/Servers/ServerBase.cs
index 657444c..2c4a687 100644
--- a/OpenSim/Framework/Servers/ServerBase.cs
+++ b/OpenSim/Framework/Servers/ServerBase.cs
@@ -76,6 +76,11 @@ namespace OpenSim.Framework.Servers
protected void CreatePIDFile(string path)
{
+ if (File.Exists(path))
+ m_log.ErrorFormat(
+ "[SERVER BASE]: Previous pid file {0} still exists on startup. Possibly previously unclean shutdown.",
+ path);
+
try
{
string pidstring = System.Diagnostics.Process.GetCurrentProcess().Id.ToString();
--
cgit v1.1
From 8690a08881d41c285dd830b4b1646eb116ad098d Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Tue, 9 Apr 2013 23:02:11 +0100
Subject: minor: Log an exception if we aren't able to delete a script state
file rather than simply ignoring it.
This should never normally happen but if it does then it can be valuable diagonstic information.
---
OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index bf19a42..1e6db43 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -520,8 +520,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
{
File.Delete(savedState);
}
- catch(Exception)
+ catch (Exception e)
{
+ m_log.Warn(
+ string.Format(
+ "[SCRIPT INSTANCE]: Could not delete script state {0} for script {1} (id {2}) in part {3} (id {4}) in object {5} in {6}. Exception ",
+ ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name),
+ e);
}
}
--
cgit v1.1
From 659c741ff5a3d13b4462d3ce906c6785bb296322 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Tue, 9 Apr 2013 23:15:01 +0100
Subject: Add more notes to async_call_method relating to
UnsafeQueueUserWorkItem
UnsafeQueueUserWorkItem is so called because it allows the calling code to escalate its security privileges.
However, since we must already trust this code anyway in OpenSimulator this is not an issue.
---
bin/OpenSimDefaults.ini | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini
index 1d2c0cf..28c1db2 100644
--- a/bin/OpenSimDefaults.ini
+++ b/bin/OpenSimDefaults.ini
@@ -43,9 +43,14 @@
; Sets the method that OpenSim will use to fire asynchronous
; events. Valid values are UnsafeQueueUserWorkItem,
; QueueUserWorkItem, BeginInvoke, SmartThreadPool, and Thread.
+ ;
; SmartThreadPool is reported to work well on Mono/Linux, but
; UnsafeQueueUserWorkItem has been benchmarked with better
; performance on .NET/Windows
+ ;
+ ; UnsafeQueueUserWorkItem refers to the fact that the code creating the event could elevate its security
+ ; privileges. However, as calling code is trusted anyway this is safe (if you set
+ ; TrustedBinaries = true in the [XEngine] section then you already have to trust that incoming code for other reasons).
async_call_method = SmartThreadPool
; Max threads to allocate on the FireAndForget thread pool
--
cgit v1.1
From 06068444e2486cb761d266c6831c54fc27d7d5c2 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Tue, 9 Apr 2013 23:21:13 +0100
Subject: Comment out rez perms logging I accidentally left in at 7f07023 (Sat
Apr 6 02:34:51 2013)
---
OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
index 77299be..f8e93e1 100644
--- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
@@ -1453,7 +1453,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
bool permission = false;
- m_log.DebugFormat("[PERMISSIONS MODULE]: Checking rez object at {0} in {1}", objectPosition, m_scene.Name);
+// m_log.DebugFormat("[PERMISSIONS MODULE]: Checking rez object at {0} in {1}", objectPosition, m_scene.Name);
ILandObject land = m_scene.LandChannel.GetLandObject(objectPosition.X, objectPosition.Y);
if (land == null) return false;
--
cgit v1.1
From e20b0d5695dc583d161b39fa26bfd56e63c7b30e Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Wed, 10 Apr 2013 00:03:37 +0100
Subject: minor: Make exceptions thrown by MySQLAssetData more consistent.
---
OpenSim/Data/MySQL/MySQLAssetData.cs | 29 +++++++++++++++++++----------
1 file changed, 19 insertions(+), 10 deletions(-)
diff --git a/OpenSim/Data/MySQL/MySQLAssetData.cs b/OpenSim/Data/MySQL/MySQLAssetData.cs
index cf80b3d..21362b9 100644
--- a/OpenSim/Data/MySQL/MySQLAssetData.cs
+++ b/OpenSim/Data/MySQL/MySQLAssetData.cs
@@ -142,7 +142,8 @@ namespace OpenSim.Data.MySQL
}
catch (Exception e)
{
- m_log.Error("[ASSETS DB]: MySql failure fetching asset " + assetID + ": " + e.Message);
+ m_log.Error(
+ string.Format("[ASSETS DB]: MySql failure fetching asset {0}. Exception ", assetID), e);
}
}
}
@@ -209,8 +210,11 @@ namespace OpenSim.Data.MySQL
}
catch (Exception e)
{
- m_log.ErrorFormat("[ASSET DB]: MySQL failure creating asset {0} with name \"{1}\". Error: {2}",
- asset.FullID, asset.Name, e.Message);
+ m_log.Error(
+ string.Format(
+ "[ASSET DB]: MySQL failure creating asset {0} with name {1}. Exception ",
+ asset.FullID, asset.Name)
+ , e);
}
}
}
@@ -241,10 +245,11 @@ namespace OpenSim.Data.MySQL
}
catch (Exception e)
{
- m_log.ErrorFormat(
- "[ASSETS DB]: " +
- "MySql failure updating access_time for asset {0} with name {1}" + Environment.NewLine + e.ToString()
- + Environment.NewLine + "Attempting reconnection", asset.FullID, asset.Name);
+ m_log.Error(
+ string.Format(
+ "[ASSETS DB]: Failure updating access_time for asset {0} with name {1}. Exception ",
+ asset.FullID, asset.Name),
+ e);
}
}
}
@@ -284,8 +289,8 @@ namespace OpenSim.Data.MySQL
}
catch (Exception e)
{
- m_log.ErrorFormat(
- "[ASSETS DB]: MySql failure fetching asset {0}" + Environment.NewLine + e.ToString(), uuid);
+ m_log.Error(
+ string.Format("[ASSETS DB]: MySql failure fetching asset {0}. Exception ", uuid), e);
}
}
}
@@ -344,7 +349,11 @@ namespace OpenSim.Data.MySQL
}
catch (Exception e)
{
- m_log.Error("[ASSETS DB]: MySql failure fetching asset set" + Environment.NewLine + e.ToString());
+ m_log.Error(
+ string.Format(
+ "[ASSETS DB]: MySql failure fetching asset set from {0}, count {1}. Exception ",
+ start, count),
+ e);
}
}
}
--
cgit v1.1
From 29e28f4b84677fa1e1b138d0ede610c55add12f2 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Wed, 10 Apr 2013 00:05:03 +0100
Subject: minor: remove mono compiler warnings in InventoryAccessModule
---
.../CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index f796ec9..e0009bb 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -353,7 +353,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
bool asAttachment)
{
CoalescedSceneObjects coa = new CoalescedSceneObjects(UUID.Zero);
- Dictionary originalPositions = new Dictionary();
+// Dictionary originalPositions = new Dictionary();
foreach (SceneObjectGroup objectGroup in objlist)
{
@@ -936,8 +936,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
}
}
- int primcount = 0;
- for(int i = 0; i < objlist.Count; i++)
+ for (int i = 0; i < objlist.Count; i++)
{
SceneObjectGroup g = objlist[i];
--
cgit v1.1
From 148e46563f9f95e43a460780592deceed3dd5d14 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Wed, 10 Apr 2013 00:07:58 +0100
Subject: minor: fix mono compiler warning in ScriptsHttpRequests.cs
---
OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs | 1 -
1 file changed, 1 deletion(-)
diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
index ebf56cd..6793fc8 100644
--- a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
+++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
@@ -395,7 +395,6 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
//public bool HttpVerboseThrottle = true; // not implemented
public List HttpCustomHeaders = null;
public bool HttpPragmaNoCache = true;
- private Thread httpThread;
// Request info
private UUID _itemID;
--
cgit v1.1
From 17fd075f39df71d628db08b7c280150f231f8a26 Mon Sep 17 00:00:00 2001
From: Robert Adams
Date: Tue, 9 Apr 2013 11:55:29 -0700
Subject: BulletSim: fix problem where large sets of mega-regions weren't
registering all the terrain with the base region.
---
OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
index cd15850..5240ad8 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
@@ -213,13 +213,13 @@ public sealed class BSTerrainManager : IDisposable
});
}
- // Another region is calling this region passing a terrain.
+ // Another region is calling this region and passing a terrain.
// A region that is not the mega-region root will pass its terrain to the root region so the root region
// physics engine will have all the terrains.
private void AddMegaRegionChildTerrain(uint id, float[] heightMap, Vector3 minCoords, Vector3 maxCoords)
{
// Since we are called by another region's thread, the action must be rescheduled onto our processing thread.
- PhysicsScene.PostTaintObject("TerrainManager.AddMegaRegionChild" + m_worldOffset.ToString(), 0, delegate()
+ PhysicsScene.PostTaintObject("TerrainManager.AddMegaRegionChild" + minCoords.ToString(), id, delegate()
{
UpdateTerrain(id, heightMap, minCoords, maxCoords);
});
@@ -306,7 +306,7 @@ public sealed class BSTerrainManager : IDisposable
newTerrainID = ++m_terrainCount;
DetailLog("{0},BSTerrainManager.UpdateTerrain:NewTerrain,taint,newID={1},minCoord={2},maxCoord={3}",
- BSScene.DetailLogZero, newTerrainID, minCoords, minCoords);
+ BSScene.DetailLogZero, newTerrainID, minCoords, maxCoords);
BSTerrainPhys newTerrainPhys = BuildPhysicalTerrain(terrainRegionBase, id, heightMap, minCoords, maxCoords);
m_terrains.Add(terrainRegionBase, newTerrainPhys);
--
cgit v1.1
From 59135c9a31875dc514b3ea2fe14021571807701d Mon Sep 17 00:00:00 2001
From: Robert Adams
Date: Tue, 9 Apr 2013 16:32:54 -0700
Subject: BulletSim: add Bullet HACD library invocation. Turned off by default
as not totally debugged. Updated DLLs and SOs with more debugged HACD library
code.
---
OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 53 ++++-
OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 1 +
.../Physics/BulletSPlugin/BSShapeCollection.cs | 223 ++++++++++++---------
bin/lib32/BulletSim.dll | Bin 570880 -> 1008640 bytes
bin/lib32/libBulletSim.so | Bin 1762207 -> 2093987 bytes
bin/lib64/BulletSim.dll | Bin 721920 -> 1140224 bytes
bin/lib64/libBulletSim.so | Bin 1920169 -> 2258808 bytes
7 files changed, 183 insertions(+), 94 deletions(-)
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
index 385ed9e..06df85e 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
@@ -86,6 +86,7 @@ public static class BSParam
public static bool ShouldForceSimplePrimMeshing { get; private set; } // if a cube or sphere, let Bullet do internal shapes
public static bool ShouldUseHullsForPhysicalObjects { get; private set; } // 'true' if should create hulls for physical objects
public static bool ShouldRemoveZeroWidthTriangles { get; private set; }
+ public static bool ShouldUseBulletHACD { get; set; }
public static float TerrainImplementation { get; private set; }
public static int TerrainMeshMagnification { get; private set; }
@@ -149,6 +150,15 @@ public static class BSParam
public static float CSHullVolumeConservationThresholdPercent { get; private set; }
public static int CSHullMaxVertices { get; private set; }
public static float CSHullMaxSkinWidth { get; private set; }
+ public static float BHullMaxVerticesPerHull { get; private set; } // 100
+ public static float BHullMinClusters { get; private set; } // 2
+ public static float BHullCompacityWeight { get; private set; } // 0.1
+ public static float BHullVolumeWeight { get; private set; } // 0.0
+ public static float BHullConcavity { get; private set; } // 100
+ public static bool BHullAddExtraDistPoints { get; private set; } // false
+ public static bool BHullAddNeighboursDistPoints { get; private set; } // false
+ public static bool BHullAddFacesPoints { get; private set; } // false
+ public static bool BHullShouldAdjustCollisionMargin { get; private set; } // false
// Linkset implementation parameters
public static float LinksetImplementation { get; private set; }
@@ -325,6 +335,10 @@ public static class BSParam
true,
(s) => { return ShouldRemoveZeroWidthTriangles; },
(s,v) => { ShouldRemoveZeroWidthTriangles = v; } ),
+ new ParameterDefn("ShouldUseBulletHACD", "If true, use the Bullet version of HACD",
+ false,
+ (s) => { return ShouldUseBulletHACD; },
+ (s,v) => { ShouldUseBulletHACD = v; } ),
new ParameterDefn("CrossingFailuresBeforeOutOfBounds", "How forgiving we are about getting into adjactent regions",
5,
@@ -663,10 +677,47 @@ public static class BSParam
(s) => { return CSHullMaxVertices; },
(s,v) => { CSHullMaxVertices = v; } ),
new ParameterDefn("CSHullMaxSkinWidth", "CS impl: skin width to apply to output hulls.",
- 0,
+ 0f,
(s) => { return CSHullMaxSkinWidth; },
(s,v) => { CSHullMaxSkinWidth = v; } ),
+ new ParameterDefn("BHullMaxVerticesPerHull", "Bullet impl: max number of vertices per created hull",
+ 100f,
+ (s) => { return BHullMaxVerticesPerHull; },
+ (s,v) => { BHullMaxVerticesPerHull = v; } ),
+ new ParameterDefn("BHullMinClusters", "Bullet impl: minimum number of hulls to create per mesh",
+ 2f,
+ (s) => { return BHullMinClusters; },
+ (s,v) => { BHullMinClusters = v; } ),
+ new ParameterDefn("BHullCompacityWeight", "Bullet impl: weight factor for how compact to make hulls",
+ 2f,
+ (s) => { return BHullCompacityWeight; },
+ (s,v) => { BHullCompacityWeight = v; } ),
+ new ParameterDefn("BHullVolumeWeight", "Bullet impl: weight factor for volume in created hull",
+ 0.1f,
+ (s) => { return BHullVolumeWeight; },
+ (s,v) => { BHullVolumeWeight = v; } ),
+ new ParameterDefn("BHullConcavity", "Bullet impl: weight factor for how convex a created hull can be",
+ 100f,
+ (s) => { return BHullConcavity; },
+ (s,v) => { BHullConcavity = v; } ),
+ new ParameterDefn("BHullAddExtraDistPoints", "Bullet impl: whether to add extra vertices for long distance vectors",
+ false,
+ (s) => { return BHullAddExtraDistPoints; },
+ (s,v) => { BHullAddExtraDistPoints = v; } ),
+ new ParameterDefn("BHullAddNeighboursDistPoints", "Bullet impl: whether to add extra vertices between neighbor hulls",
+ false,
+ (s) => { return BHullAddNeighboursDistPoints; },
+ (s,v) => { BHullAddNeighboursDistPoints = v; } ),
+ new ParameterDefn("BHullAddFacesPoints", "Bullet impl: whether to add extra vertices to break up hull faces",
+ false,
+ (s) => { return BHullAddFacesPoints; },
+ (s,v) => { BHullAddFacesPoints = v; } ),
+ new ParameterDefn("BHullShouldAdjustCollisionMargin", "Bullet impl: whether to shrink resulting hulls to account for collision margin",
+ false,
+ (s) => { return BHullShouldAdjustCollisionMargin; },
+ (s,v) => { BHullShouldAdjustCollisionMargin = v; } ),
+
new ParameterDefn("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)",
(float)BSLinkset.LinksetImplementation.Compound,
(s) => { return LinksetImplementation; },
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index 9818b05..8e05b58 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -316,6 +316,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
break;
case "bulletxna":
ret = new BSAPIXNA(engineName, this);
+ BSParam.ShouldUseBulletHACD = false;
break;
}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
index b6ac23d..bfa69b2 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
@@ -720,7 +720,7 @@ public sealed class BSShapeCollection : IDisposable
// Remove usage of the previous shape.
DereferenceShape(prim.PhysShape, shapeCallback);
- newShape = CreatePhysicalHull(prim.PhysObjectName, newHullKey, prim.BaseShape, prim.Size, lod);
+ newShape = CreatePhysicalHull(prim, newHullKey, prim.BaseShape, prim.Size, lod);
// It might not have been created if we're waiting for an asset.
newShape = VerifyMeshCreated(newShape, prim);
@@ -731,7 +731,7 @@ public sealed class BSShapeCollection : IDisposable
}
List m_hulls;
- private BulletShape CreatePhysicalHull(string objName, System.UInt64 newHullKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod)
+ private BulletShape CreatePhysicalHull(BSPhysObject prim, System.UInt64 newHullKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod)
{
BulletShape newShape = new BulletShape();
@@ -745,116 +745,153 @@ public sealed class BSShapeCollection : IDisposable
}
else
{
- // Build a new hull in the physical world.
- // Pass true for physicalness as this prevents the creation of bounding box which is not needed
- IMesh meshData = PhysicsScene.mesher.CreateMesh(objName, pbs, size, lod, true /* isPhysical */, false /* shouldCache */);
- if (meshData != null)
+ if (BSParam.ShouldUseBulletHACD)
{
-
- int[] indices = meshData.getIndexListAsInt();
- List vertices = meshData.getVertexList();
-
- //format conversion from IMesh format to DecompDesc format
- List convIndices = new List();
- List convVertices = new List();
- for (int ii = 0; ii < indices.GetLength(0); ii++)
+ DetailLog("{0},BSShapeCollection.CreatePhysicalHull,shouldUseBulletHACD,entry", prim.LocalID);
+ MeshDesc meshDesc;
+ if (!Meshes.TryGetValue(newHullKey, out meshDesc))
{
- convIndices.Add(indices[ii]);
+ // That's odd because the mesh should have been created before the hull
+ // but, since it doesn't exist, create it.
+ newShape = CreatePhysicalMesh(prim, newHullKey, prim.BaseShape, prim.Size, lod);
+ DetailLog("{0},BSShapeCollection.CreatePhysicalHull,noMeshBuiltNew,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape);
+
+ if (newShape.HasPhysicalShape)
+ {
+ ReferenceShape(newShape);
+ Meshes.TryGetValue(newHullKey, out meshDesc);
+ }
}
- foreach (OMV.Vector3 vv in vertices)
+ if (meshDesc.shape.HasPhysicalShape)
{
- convVertices.Add(new float3(vv.X, vv.Y, vv.Z));
+ HACDParams parms;
+ parms.maxVerticesPerHull = BSParam.BHullMaxVerticesPerHull;
+ parms.minClusters = BSParam.BHullMinClusters;
+ parms.compacityWeight = BSParam.BHullCompacityWeight;
+ parms.volumeWeight = BSParam.BHullVolumeWeight;
+ parms.concavity = BSParam.BHullConcavity;
+ parms.addExtraDistPoints = BSParam.NumericBool(BSParam.BHullAddExtraDistPoints);
+ parms.addNeighboursDistPoints = BSParam.NumericBool(BSParam.BHullAddNeighboursDistPoints);
+ parms.addFacesPoints = BSParam.NumericBool(BSParam.BHullAddFacesPoints);
+ parms.shouldAdjustCollisionMargin = BSParam.NumericBool(BSParam.BHullShouldAdjustCollisionMargin);
+
+ DetailLog("{0},BSShapeCollection.CreatePhysicalHull,hullFromMesh,beforeCall", prim.LocalID, newShape.HasPhysicalShape);
+ newShape = PhysicsScene.PE.BuildHullShapeFromMesh(PhysicsScene.World, meshDesc.shape, parms);
+ DetailLog("{0},BSShapeCollection.CreatePhysicalHull,hullFromMesh,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape);
}
-
- uint maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplit;
- if (BSParam.CSHullMaxDepthSplit != BSParam.CSHullMaxDepthSplitForSimpleShapes)
+ DetailLog("{0},BSShapeCollection.CreatePhysicalHull,shouldUseBulletHACD,exit,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape);
+ }
+ if (!newShape.HasPhysicalShape)
+ {
+ // Build a new hull in the physical world.
+ // Pass true for physicalness as this prevents the creation of bounding box which is not needed
+ IMesh meshData = PhysicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, true /* isPhysical */, false /* shouldCache */);
+ if (meshData != null)
{
- // Simple primitive shapes we know are convex so they are better implemented with
- // fewer hulls.
- // Check for simple shape (prim without cuts) and reduce split parameter if so.
- if (PrimHasNoCuts(pbs))
+ int[] indices = meshData.getIndexListAsInt();
+ List vertices = meshData.getVertexList();
+
+ //format conversion from IMesh format to DecompDesc format
+ List convIndices = new List();
+ List convVertices = new List();
+ for (int ii = 0; ii < indices.GetLength(0); ii++)
{
- maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplitForSimpleShapes;
+ convIndices.Add(indices[ii]);
+ }
+ foreach (OMV.Vector3 vv in vertices)
+ {
+ convVertices.Add(new float3(vv.X, vv.Y, vv.Z));
}
- }
- // setup and do convex hull conversion
- m_hulls = new List();
- DecompDesc dcomp = new DecompDesc();
- dcomp.mIndices = convIndices;
- dcomp.mVertices = convVertices;
- dcomp.mDepth = maxDepthSplit;
- dcomp.mCpercent = BSParam.CSHullConcavityThresholdPercent;
- dcomp.mPpercent = BSParam.CSHullVolumeConservationThresholdPercent;
- dcomp.mMaxVertices = (uint)BSParam.CSHullMaxVertices;
- dcomp.mSkinWidth = BSParam.CSHullMaxSkinWidth;
- ConvexBuilder convexBuilder = new ConvexBuilder(HullReturn);
- // create the hull into the _hulls variable
- convexBuilder.process(dcomp);
-
- DetailLog("{0},BSShapeCollection.CreatePhysicalHull,key={1},inVert={2},inInd={3},split={4},hulls={5}",
- BSScene.DetailLogZero, newHullKey, indices.GetLength(0), vertices.Count, maxDepthSplit, m_hulls.Count);
-
- // Convert the vertices and indices for passing to unmanaged.
- // The hull information is passed as a large floating point array.
- // The format is:
- // convHulls[0] = number of hulls
- // convHulls[1] = number of vertices in first hull
- // convHulls[2] = hull centroid X coordinate
- // convHulls[3] = hull centroid Y coordinate
- // convHulls[4] = hull centroid Z coordinate
- // convHulls[5] = first hull vertex X
- // convHulls[6] = first hull vertex Y
- // convHulls[7] = first hull vertex Z
- // convHulls[8] = second hull vertex X
- // ...
- // convHulls[n] = number of vertices in second hull
- // convHulls[n+1] = second hull centroid X coordinate
- // ...
- //
- // TODO: is is very inefficient. Someday change the convex hull generator to return
- // data structures that do not need to be converted in order to pass to Bullet.
- // And maybe put the values directly into pinned memory rather than marshaling.
- int hullCount = m_hulls.Count;
- int totalVertices = 1; // include one for the count of the hulls
- foreach (ConvexResult cr in m_hulls)
- {
- totalVertices += 4; // add four for the vertex count and centroid
- totalVertices += cr.HullIndices.Count * 3; // we pass just triangles
- }
- float[] convHulls = new float[totalVertices];
+ uint maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplit;
+ if (BSParam.CSHullMaxDepthSplit != BSParam.CSHullMaxDepthSplitForSimpleShapes)
+ {
+ // Simple primitive shapes we know are convex so they are better implemented with
+ // fewer hulls.
+ // Check for simple shape (prim without cuts) and reduce split parameter if so.
+ if (PrimHasNoCuts(pbs))
+ {
+ maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplitForSimpleShapes;
+ }
+ }
- convHulls[0] = (float)hullCount;
- int jj = 1;
- foreach (ConvexResult cr in m_hulls)
- {
- // copy vertices for index access
- float3[] verts = new float3[cr.HullVertices.Count];
- int kk = 0;
- foreach (float3 ff in cr.HullVertices)
+ // setup and do convex hull conversion
+ m_hulls = new List();
+ DecompDesc dcomp = new DecompDesc();
+ dcomp.mIndices = convIndices;
+ dcomp.mVertices = convVertices;
+ dcomp.mDepth = maxDepthSplit;
+ dcomp.mCpercent = BSParam.CSHullConcavityThresholdPercent;
+ dcomp.mPpercent = BSParam.CSHullVolumeConservationThresholdPercent;
+ dcomp.mMaxVertices = (uint)BSParam.CSHullMaxVertices;
+ dcomp.mSkinWidth = BSParam.CSHullMaxSkinWidth;
+ ConvexBuilder convexBuilder = new ConvexBuilder(HullReturn);
+ // create the hull into the _hulls variable
+ convexBuilder.process(dcomp);
+
+ DetailLog("{0},BSShapeCollection.CreatePhysicalHull,key={1},inVert={2},inInd={3},split={4},hulls={5}",
+ BSScene.DetailLogZero, newHullKey, indices.GetLength(0), vertices.Count, maxDepthSplit, m_hulls.Count);
+
+ // Convert the vertices and indices for passing to unmanaged.
+ // The hull information is passed as a large floating point array.
+ // The format is:
+ // convHulls[0] = number of hulls
+ // convHulls[1] = number of vertices in first hull
+ // convHulls[2] = hull centroid X coordinate
+ // convHulls[3] = hull centroid Y coordinate
+ // convHulls[4] = hull centroid Z coordinate
+ // convHulls[5] = first hull vertex X
+ // convHulls[6] = first hull vertex Y
+ // convHulls[7] = first hull vertex Z
+ // convHulls[8] = second hull vertex X
+ // ...
+ // convHulls[n] = number of vertices in second hull
+ // convHulls[n+1] = second hull centroid X coordinate
+ // ...
+ //
+ // TODO: is is very inefficient. Someday change the convex hull generator to return
+ // data structures that do not need to be converted in order to pass to Bullet.
+ // And maybe put the values directly into pinned memory rather than marshaling.
+ int hullCount = m_hulls.Count;
+ int totalVertices = 1; // include one for the count of the hulls
+ foreach (ConvexResult cr in m_hulls)
{
- verts[kk++] = ff;
+ totalVertices += 4; // add four for the vertex count and centroid
+ totalVertices += cr.HullIndices.Count * 3; // we pass just triangles
}
+ float[] convHulls = new float[totalVertices];
- // add to the array one hull's worth of data
- convHulls[jj++] = cr.HullIndices.Count;
- convHulls[jj++] = 0f; // centroid x,y,z
- convHulls[jj++] = 0f;
- convHulls[jj++] = 0f;
- foreach (int ind in cr.HullIndices)
+ convHulls[0] = (float)hullCount;
+ int jj = 1;
+ foreach (ConvexResult cr in m_hulls)
{
- convHulls[jj++] = verts[ind].x;
- convHulls[jj++] = verts[ind].y;
- convHulls[jj++] = verts[ind].z;
+ // copy vertices for index access
+ float3[] verts = new float3[cr.HullVertices.Count];
+ int kk = 0;
+ foreach (float3 ff in cr.HullVertices)
+ {
+ verts[kk++] = ff;
+ }
+
+ // add to the array one hull's worth of data
+ convHulls[jj++] = cr.HullIndices.Count;
+ convHulls[jj++] = 0f; // centroid x,y,z
+ convHulls[jj++] = 0f;
+ convHulls[jj++] = 0f;
+ foreach (int ind in cr.HullIndices)
+ {
+ convHulls[jj++] = verts[ind].x;
+ convHulls[jj++] = verts[ind].y;
+ convHulls[jj++] = verts[ind].z;
+ }
}
+ // create the hull data structure in Bullet
+ newShape = PhysicsScene.PE.CreateHullShape(PhysicsScene.World, hullCount, convHulls);
}
- // create the hull data structure in Bullet
- newShape = PhysicsScene.PE.CreateHullShape(PhysicsScene.World, hullCount, convHulls);
}
+ newShape.shapeKey = newHullKey;
}
- newShape.shapeKey = newHullKey;
-
return newShape;
}
diff --git a/bin/lib32/BulletSim.dll b/bin/lib32/BulletSim.dll
index 5432813..618d4bd 100755
Binary files a/bin/lib32/BulletSim.dll and b/bin/lib32/BulletSim.dll differ
diff --git a/bin/lib32/libBulletSim.so b/bin/lib32/libBulletSim.so
index 286d930..e3b40fb 100755
Binary files a/bin/lib32/libBulletSim.so and b/bin/lib32/libBulletSim.so differ
diff --git a/bin/lib64/BulletSim.dll b/bin/lib64/BulletSim.dll
index dca7116..491ac22 100755
Binary files a/bin/lib64/BulletSim.dll and b/bin/lib64/BulletSim.dll differ
diff --git a/bin/lib64/libBulletSim.so b/bin/lib64/libBulletSim.so
index b63feb3..a8ad533 100755
Binary files a/bin/lib64/libBulletSim.so and b/bin/lib64/libBulletSim.so differ
--
cgit v1.1
From 9cc41d511872fcd74a074ab484db2b981f3f5676 Mon Sep 17 00:00:00 2001
From: Vegaslon
Date: Tue, 9 Apr 2013 17:23:50 -0400
Subject: Another algorithm for AngularVerticalAttraction. This one Takes into
account all rotations before it and makes the corrections more close to the
time that sl does.
Signed-off-by: Robert Adams
---
OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 23 ++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
index 0fd1f73..723be0b 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
@@ -1358,6 +1358,28 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// If vertical attaction timescale is reasonable
if (enableAngularVerticalAttraction && m_verticalAttractionTimescale < m_verticalAttractionCutoff)
{
+ //Another formula to try got from :
+ //http://answers.unity3d.com/questions/10425/how-to-stabilize-angular-motion-alignment-of-hover.html
+ Vector3 VehicleUpAxis = Vector3.UnitZ *VehicleOrientation;
+ //Flipping what was originally a timescale into a speed variable and then multiplying it by 2 since only computing half
+ //the distance between the angles.
+ float VerticalAttractionSpeed=(1/m_verticalAttractionTimescale)*2.0f;
+ //making a prediction of where the up axis will be when this is applied rather then where it is now this makes for a smoother
+ //adjustment and less fighting between the various forces
+ Vector3 predictedUp = VehicleUpAxis * Quaternion.CreateFromAxisAngle(VehicleRotationalVelocity, 0f);
+ //this is only half the distance to the target so it will take 2 seconds to complete the turn.
+ Vector3 torqueVector = Vector3.Cross(predictedUp, Vector3.UnitZ);
+ //Scaling vector by our timescale since it is an acceleration it is r/s^2 or radians a timescale squared
+ Vector3 vertContributionV=torqueVector * VerticalAttractionSpeed *VerticalAttractionSpeed;
+ VehicleRotationalVelocity += vertContributionV;
+ VDetailLog("{0}, MoveAngular,verticalAttraction,UpAxis={1},PredictedUp={2},torqueVector={3},contrib={4}",
+ ControllingPrim.LocalID,
+ VehicleUpAxis,
+ predictedUp,
+ torqueVector,
+ vertContributionV);
+ //=====================================================================
+ /*
// Possible solution derived from a discussion at:
// http://stackoverflow.com/questions/14939657/computing-vector-from-quaternion-works-computing-quaternion-from-vector-does-no
@@ -1392,6 +1414,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
differenceAngle,
correctionRotation,
vertContributionV);
+ */
// ===================================================================
/*
--
cgit v1.1
From b53713cdda3c4e49913a6a82239da35d62f74e68 Mon Sep 17 00:00:00 2001
From: Robert Adams
Date: Tue, 9 Apr 2013 17:14:15 -0700
Subject: BulletSim: some formatting changes.
---
OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 27 ++++++++++++++--------
1 file changed, 17 insertions(+), 10 deletions(-)
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
index 723be0b..612c68b 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
@@ -1360,19 +1360,26 @@ namespace OpenSim.Region.Physics.BulletSPlugin
{
//Another formula to try got from :
//http://answers.unity3d.com/questions/10425/how-to-stabilize-angular-motion-alignment-of-hover.html
- Vector3 VehicleUpAxis = Vector3.UnitZ *VehicleOrientation;
- //Flipping what was originally a timescale into a speed variable and then multiplying it by 2 since only computing half
- //the distance between the angles.
- float VerticalAttractionSpeed=(1/m_verticalAttractionTimescale)*2.0f;
- //making a prediction of where the up axis will be when this is applied rather then where it is now this makes for a smoother
- //adjustment and less fighting between the various forces
+
+ Vector3 VehicleUpAxis = Vector3.UnitZ * VehicleOrientation;
+
+ // Flipping what was originally a timescale into a speed variable and then multiplying it by 2
+ // since only computing half the distance between the angles.
+ float VerticalAttractionSpeed = (1 / m_verticalAttractionTimescale) * 2.0f;
+
+ // Make a prediction of where the up axis will be when this is applied rather then where it is now as
+ // this makes for a smoother adjustment and less fighting between the various forces.
Vector3 predictedUp = VehicleUpAxis * Quaternion.CreateFromAxisAngle(VehicleRotationalVelocity, 0f);
- //this is only half the distance to the target so it will take 2 seconds to complete the turn.
+
+ // This is only half the distance to the target so it will take 2 seconds to complete the turn.
Vector3 torqueVector = Vector3.Cross(predictedUp, Vector3.UnitZ);
- //Scaling vector by our timescale since it is an acceleration it is r/s^2 or radians a timescale squared
- Vector3 vertContributionV=torqueVector * VerticalAttractionSpeed *VerticalAttractionSpeed;
+
+ // Scale vector by our timescale since it is an acceleration it is r/s^2 or radians a timescale squared
+ Vector3 vertContributionV = torqueVector * VerticalAttractionSpeed * VerticalAttractionSpeed;
+
VehicleRotationalVelocity += vertContributionV;
- VDetailLog("{0}, MoveAngular,verticalAttraction,UpAxis={1},PredictedUp={2},torqueVector={3},contrib={4}",
+
+ VDetailLog("{0}, MoveAngular,verticalAttraction,UpAxis={1},PredictedUp={2},torqueVector={3},contrib={4}",
ControllingPrim.LocalID,
VehicleUpAxis,
predictedUp,
--
cgit v1.1
From 5f2cbfc0fd27198f8f05f4a9a4e2908d8b11752e Mon Sep 17 00:00:00 2001
From: Robert Adams
Date: Tue, 9 Apr 2013 17:53:18 -0700
Subject: BulletSim: fixing problems with llMoveToTarget. Not all fixed yet.
---
OpenSim/Region/Physics/BulletSPlugin/BSActorHover.cs | 2 +-
.../Region/Physics/BulletSPlugin/BSActorMoveToTarget.cs | 16 +++++++++++-----
OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs | 6 ++++++
3 files changed, 18 insertions(+), 6 deletions(-)
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSActorHover.cs b/OpenSim/Region/Physics/BulletSPlugin/BSActorHover.cs
index e8310df..92ace66 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSActorHover.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSActorHover.cs
@@ -50,7 +50,7 @@ public class BSActorHover : BSActor
// BSActor.isActive
public override bool isActive
{
- get { return Enabled && m_controllingPrim.IsPhysicallyActive; }
+ get { return Enabled; }
}
// Release any connections and resources used by the actor.
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSActorMoveToTarget.cs b/OpenSim/Region/Physics/BulletSPlugin/BSActorMoveToTarget.cs
index 16c2b14..56aacc5 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSActorMoveToTarget.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSActorMoveToTarget.cs
@@ -50,7 +50,7 @@ public class BSActorMoveToTarget : BSActor
// BSActor.isActive
public override bool isActive
{
- get { return Enabled && m_controllingPrim.IsPhysicallyActive; }
+ get { return Enabled; }
}
// Release any connections and resources used by the actor.
@@ -65,7 +65,9 @@ public class BSActorMoveToTarget : BSActor
// BSActor.Refresh()
public override void Refresh()
{
- m_physicsScene.DetailLog("{0},BSActorMoveToTarget,refresh", m_controllingPrim.LocalID);
+ m_physicsScene.DetailLog("{0},BSActorMoveToTarget,refresh,enabled={1},active={2},target={3},tau={4}",
+ m_controllingPrim.LocalID, Enabled, m_controllingPrim.MoveToTargetActive,
+ m_controllingPrim.MoveToTargetTarget, m_controllingPrim.MoveToTargetTau );
// If not active any more...
if (!m_controllingPrim.MoveToTargetActive)
@@ -100,7 +102,7 @@ public class BSActorMoveToTarget : BSActor
// We're taking over after this.
m_controllingPrim.ZeroMotion(true);
- m_targetMotor = new BSVMotor("BSPrim.PIDTarget",
+ m_targetMotor = new BSVMotor("BSActorMoveToTargget.Activate",
m_controllingPrim.MoveToTargetTau, // timeScale
BSMotor.Infinite, // decay time scale
BSMotor.InfiniteVector, // friction timescale
@@ -138,15 +140,19 @@ public class BSActorMoveToTarget : BSActor
// If we are very close to our target, turn off the movement motor.
if (m_targetMotor.ErrorIsZero())
{
- m_physicsScene.DetailLog("{0},BSPrim.PIDTarget,zeroMovement,movePos={1},pos={2},mass={3}",
+ m_physicsScene.DetailLog("{0},BSActorMoveToTarget.Mover,zeroMovement,movePos={1},pos={2},mass={3}",
m_controllingPrim.LocalID, movePosition, m_controllingPrim.RawPosition, m_controllingPrim.Mass);
m_controllingPrim.ForcePosition = m_targetMotor.TargetValue;
+ // Setting the position does not cause the physics engine to generate a property update. Force it.
+ m_physicsScene.PE.PushUpdate(m_controllingPrim.PhysBody);
}
else
{
m_controllingPrim.ForcePosition = movePosition;
+ // Setting the position does not cause the physics engine to generate a property update. Force it.
+ m_physicsScene.PE.PushUpdate(m_controllingPrim.PhysBody);
}
- m_physicsScene.DetailLog("{0},BSPrim.PIDTarget,move,fromPos={1},movePos={2}", m_controllingPrim.LocalID, origPosition, movePosition);
+ m_physicsScene.DetailLog("{0},BSActorMoveToTarget.Mover,move,fromPos={1},movePos={2}", m_controllingPrim.LocalID, origPosition, movePosition);
}
}
}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
index 64bf395..98eb4ca 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
@@ -295,6 +295,7 @@ public abstract class BSPhysObject : PhysicsActor
if (PhysicalActors.TryGetActor(actorName, out theActor))
{
// The actor already exists so just turn it on or off
+ DetailLog("{0},BSPhysObject.EnableActor,enablingExistingActor,name={1},enable={2}", LocalID, actorName, enableActor);
theActor.Enabled = enableActor;
}
else
@@ -302,10 +303,15 @@ public abstract class BSPhysObject : PhysicsActor
// The actor does not exist. If it should, create it.
if (enableActor)
{
+ DetailLog("{0},BSPhysObject.EnableActor,creatingActor,name={1}", LocalID, actorName);
theActor = creator();
PhysicalActors.Add(actorName, theActor);
theActor.Enabled = true;
}
+ else
+ {
+ DetailLog("{0},BSPhysObject.EnableActor,notCreatingActorSinceNotEnabled,name={1}", LocalID, actorName);
+ }
}
}
}
--
cgit v1.1
From c5de9840b05514eb659696239593e51e636398b8 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Tue, 16 Apr 2013 21:58:24 +0100
Subject: refactor: Remove IClientNetworkServer.NetworkStop() in favour of
existing Stop().
This was an undocumented interface which I think was for long defunct region load balancing experiments.
Also adds method doc for some IClientNetworkServer methods.
---
OpenSim/Region/Application/OpenSimBase.cs | 2 +-
OpenSim/Region/ClientStack/IClientNetworkServer.cs | 15 +++++++++++++--
OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | 5 -----
3 files changed, 14 insertions(+), 8 deletions(-)
diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs
index c555915..d86eefe 100644
--- a/OpenSim/Region/Application/OpenSimBase.cs
+++ b/OpenSim/Region/Application/OpenSimBase.cs
@@ -737,7 +737,7 @@ namespace OpenSim
if (foundClientServer)
{
- m_clientServers[clientServerElement].NetworkStop();
+ m_clientServers[clientServerElement].Stop();
m_clientServers.RemoveAt(clientServerElement);
}
}
diff --git a/OpenSim/Region/ClientStack/IClientNetworkServer.cs b/OpenSim/Region/ClientStack/IClientNetworkServer.cs
index 54a441b..bb7e6d0 100644
--- a/OpenSim/Region/ClientStack/IClientNetworkServer.cs
+++ b/OpenSim/Region/ClientStack/IClientNetworkServer.cs
@@ -38,11 +38,22 @@ namespace OpenSim.Region.ClientStack
IPAddress _listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource,
AgentCircuitManager authenticateClass);
- void NetworkStop();
bool HandlesRegion(Location x);
- void AddScene(IScene x);
+ ///
+ /// Add the given scene to be handled by this IClientNetworkServer.
+ ///
+ ///
+ void AddScene(IScene scene);
+
+ ///
+ /// Start sending and receiving data.
+ ///
void Start();
+
+ ///
+ /// Stop sending and receiving data.
+ ///
void Stop();
}
}
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index 72516cd..985aa4d 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -62,11 +62,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_udpServer = new LLUDPServer(listenIP, ref port, proxyPortOffsetParm, allow_alternate_port, configSource, circuitManager);
}
- public void NetworkStop()
- {
- m_udpServer.Stop();
- }
-
public void AddScene(IScene scene)
{
m_udpServer.AddScene(scene);
--
cgit v1.1
From d4fa2c69ed2895dcab76e0df1b26252246883c07 Mon Sep 17 00:00:00 2001
From: dahlia
Date: Wed, 17 Apr 2013 21:31:18 -0700
Subject: update libomv to git master which adds support for MaterialID in
TextureEntry
---
bin/CSJ2K.dll | Bin 502784 -> 495616 bytes
bin/OpenMetaverse.StructuredData.XML | 28 +-
bin/OpenMetaverse.StructuredData.dll | Bin 114688 -> 102400 bytes
bin/OpenMetaverse.XML | 36629 ++++++++++----------
bin/OpenMetaverse.dll | Bin 1925120 -> 1785856 bytes
bin/OpenMetaverse.dll.config | 8 +-
bin/OpenMetaverseTypes.XML | 1462 +-
bin/OpenMetaverseTypes.dll | Bin 122880 -> 114688 bytes
bin/libopenjpeg-dotnet-2-1.5.0-dotnet-1-i686.so | Bin 0 -> 140028 bytes
bin/libopenjpeg-dotnet-2-1.5.0-dotnet-1-x86_64.so | Bin 0 -> 149368 bytes
bin/libopenjpeg-dotnet-2-1.5.0-dotnet-1.dylib | Bin 0 -> 130560 bytes
11 files changed, 19633 insertions(+), 18494 deletions(-)
create mode 100644 bin/libopenjpeg-dotnet-2-1.5.0-dotnet-1-i686.so
create mode 100644 bin/libopenjpeg-dotnet-2-1.5.0-dotnet-1-x86_64.so
create mode 100644 bin/libopenjpeg-dotnet-2-1.5.0-dotnet-1.dylib
diff --git a/bin/CSJ2K.dll b/bin/CSJ2K.dll
index 238291f..581e410 100755
Binary files a/bin/CSJ2K.dll and b/bin/CSJ2K.dll differ
diff --git a/bin/OpenMetaverse.StructuredData.XML b/bin/OpenMetaverse.StructuredData.XML
index 897a330..3999d99 100644
--- a/bin/OpenMetaverse.StructuredData.XML
+++ b/bin/OpenMetaverse.StructuredData.XML
@@ -31,17 +31,33 @@
-
+ Serializes OSD to binary format. It does no prepend header
-
-
+ OSD to serialize
+ Serialized data
+
+
+
+ Serializes OSD to binary format
+
+ OSD to serialize
+
+ Serialized data
-
+ Serializes OSD to binary format. It does no prepend header
-
-
+ OSD to serialize
+ Serialized data
+
+
+
+ Serializes OSD to binary format
+
+ OSD to serialize
+
+ Serialized data
diff --git a/bin/OpenMetaverse.StructuredData.dll b/bin/OpenMetaverse.StructuredData.dll
index c7216ce..4df771a 100755
Binary files a/bin/OpenMetaverse.StructuredData.dll and b/bin/OpenMetaverse.StructuredData.dll differ
diff --git a/bin/OpenMetaverse.XML b/bin/OpenMetaverse.XML
index 6e57fed..abd4cd5 100644
--- a/bin/OpenMetaverse.XML
+++ b/bin/OpenMetaverse.XML
@@ -4,9695 +4,8916 @@
OpenMetaverse
-
- =
-
-
- Number of times we've received an unknown CAPS exception in series.
+
+
+ Starts a thread that keeps the daemon running
+
+
+
-
- For exponential backoff on error.
+
+
+ Stops the daemon and the thread keeping it running
+
-
+
- Add a custom decoder callback
+
- The key of the field to decode
- The custom decode handler
+
+
+
-
+
- Remove a custom decoder callback
+ Create a Session
+ Sessions typically represent a connection to a media session with one or more
+ participants. This is used to generate an ‘outbound’ call to another user or
+ channel. The specifics depend on the media types involved. A session handle is
+ required to control the local user functions within the session (or remote
+ users if the current account has rights to do so). Currently creating a
+ session automatically connects to the audio media, there is no need to call
+ Session.Connect at this time, this is reserved for future use.
- The key of the field to decode
- The custom decode handler
+ Handle returned from successful Connector ‘create’ request
+ This is the URI of the terminating point of the session (ie who/what is being called)
+ This is the display name of the entity being called (user or channel)
+ Only needs to be supplied when the target URI is password protected
+ This indicates the format of the password as passed in. This can either be
+ “ClearText” or “SHA1UserName”. If this element does not exist, it is assumed to be “ClearText”. If it is
+ “SHA1UserName”, the password as passed in is the SHA1 hash of the password and username concatenated together,
+ then base64 encoded, with the final “=” character stripped off.
+
+
+
-
+
- Creates a formatted string containing the values of a Packet
+ Used to accept a call
- The Packet
- A formatted string of values of the nested items in the Packet object
+ SessionHandle such as received from SessionNewEvent
+ "default"
+
-
+
- Decode an IMessage object into a beautifully formatted string
+ This command is used to start the audio render process, which will then play
+ the passed in file through the selected audio render device. This command
+ should not be issued if the user is on a call.
- The IMessage object
- Recursion level (used for indenting)
- A formatted string containing the names and values of the source object
+ The fully qualified path to the sound file.
+ True if the file is to be played continuously and false if it is should be played once.
+
-
+
- A custom decoder callback
+ This command is used to stop the audio render process.
- The key of the object
- the data to decode
- A string represending the fieldData
+ The fully qualified path to the sound file issued in the start render command.
+
-
+
- Access to the data server which allows searching for land, events, people, etc
+ This is used to ‘end’ an established session (i.e. hang-up or disconnect).
+ Handle returned from successful Session ‘create’ request or a SessionNewEvent
+
-
- The event subscribers. null if no subcribers
+
+
+ Set the combined speaking and listening position in 3D space.
+
+ Handle returned from successful Session ‘create’ request or a SessionNewEvent
+ Speaking position
+ Listening position
+
-
- Raises the EventInfoReply event
- An EventInfoReplyEventArgs object containing the
- data returned from the data server
+
+
+ Set User Volume for a particular user. Does not affect how other users hear that user.
+
+ Handle returned from successful Session ‘create’ request or a SessionNewEvent
+
+ The level of the audio, a number between -100 and 100 where 0 represents ‘normal’ speaking volume
+
-
- Thread sync lock object
+
+
+ This is used to get a list of audio devices that can be used for capture (input) of voice.
+
+
-
- The event subscribers. null if no subcribers
+
+
+ This is used to get a list of audio devices that can be used for render (playback) of voice.
+
-
- Raises the DirEventsReply event
- An DirEventsReplyEventArgs object containing the
- data returned from the data server
+
+
+ This command is used to select the render device.
+
+ The name of the device as returned by the Aux.GetRenderDevices command.
-
- Thread sync lock object
+
+
+ This command is used to select the capture device.
+
+ The name of the device as returned by the Aux.GetCaptureDevices command.
-
- The event subscribers. null if no subcribers
+
+
+ This command is used to start the audio capture process which will cause
+ AuxAudioProperty Events to be raised. These events can be used to display a
+ microphone VU meter for the currently selected capture device. This command
+ should not be issued if the user is on a call.
+
+ (unused but required)
+
-
- Raises the PlacesReply event
- A PlacesReplyEventArgs object containing the
- data returned from the data server
+
+
+ This command is used to stop the audio capture process.
+
+
-
- Thread sync lock object
+
+
+ This command is used to set the mic volume while in the audio tuning process.
+ Once an acceptable mic level is attained, the application must issue a
+ connector set mic volume command to have that level be used while on voice
+ calls.
+
+ the microphone volume (-100 to 100 inclusive)
+
-
- The event subscribers. null if no subcribers
+
+
+ This command is used to set the speaker volume while in the audio tuning
+ process. Once an acceptable speaker level is attained, the application must
+ issue a connector set speaker volume command to have that level be used while
+ on voice calls.
+
+ the speaker volume (-100 to 100 inclusive)
+
-
- Raises the DirPlacesReply event
- A DirPlacesReplyEventArgs object containing the
- data returned from the data server
+
+
+ Start up the Voice service.
+
-
- Thread sync lock object
+
+
+ Handle miscellaneous request status
+
+
+
+ ///If something goes wrong, we log it.
-
- The event subscribers. null if no subcribers
+
+
+ Cleanup oject resources
+
-
- Raises the DirClassifiedsReply event
- A DirClassifiedsReplyEventArgs object containing the
- data returned from the data server
+
+
+ Request voice cap when changing regions
+
-
- Thread sync lock object
+
+
+ Handle a change in session state
+
-
- The event subscribers. null if no subcribers
+
+
+ Close a voice session
+
+
-
- Raises the DirGroupsReply event
- A DirGroupsReplyEventArgs object containing the
- data returned from the data server
+
+
+ Locate a Session context from its handle
+
+ Creates the session context if it does not exist.
-
- Thread sync lock object
+
+
+ Handle completion of main voice cap request.
+
+
+
+
-
- The event subscribers. null if no subcribers
+
+
+ Daemon has started so connect to it.
+
-
- Raises the DirPeopleReply event
- A DirPeopleReplyEventArgs object containing the
- data returned from the data server
+
+
+ The daemon TCP connection is open.
+
-
- Thread sync lock object
-
-
- The event subscribers. null if no subcribers
-
-
- Raises the DirLandReply event
- A DirLandReplyEventArgs object containing the
- data returned from the data server
-
-
- Thread sync lock object
-
-
+
- Constructs a new instance of the DirectoryManager class
+ Handle creation of the Connector.
- An instance of GridClient
-
+
- Query the data server for a list of classified ads containing the specified string.
- Defaults to searching for classified placed in any category, and includes PG, Adult and Mature
- results.
-
- Responses are sent 16 per response packet, there is no way to know how many results a query reply will contain however assuming
- the reply packets arrived ordered, a response with less than 16 entries would indicate all results have been received
-
- The event is raised when a response is received from the simulator
+ Handle response to audio output device query
- A string containing a list of keywords to search for
- A UUID to correlate the results when the event is raised
-
+
- Query the data server for a list of classified ads which contain specified keywords (Overload)
-
- The event is raised when a response is received from the simulator
+ Handle response to audio input device query
- A string containing a list of keywords to search for
- The category to search
- A set of flags which can be ORed to modify query options
- such as classified maturity rating.
- A UUID to correlate the results when the event is raised
-
- Search classified ads containing the key words "foo" and "bar" in the "Any" category that are either PG or Mature
-
- UUID searchID = StartClassifiedSearch("foo bar", ClassifiedCategories.Any, ClassifiedQueryFlags.PG | ClassifiedQueryFlags.Mature);
-
-
-
- Responses are sent 16 at a time, there is no way to know how many results a query reply will contain however assuming
- the reply packets arrived ordered, a response with less than 16 entries would indicate all results have been received
-
-
-
- Starts search for places (Overloaded)
+
+
+ Set voice channel for new parcel
+
- The event is raised when a response is received from the simulator
+
+
+
+ Request info from a parcel capability Uri.
- Search text
- Each request is limited to 100 places
- being returned. To get the first 100 result entries of a request use 0,
- from 100-199 use 1, 200-299 use 2, etc.
- A UUID to correlate the results when the event is raised
+
-
+
- Queries the dataserver for parcels of land which are flagged to be shown in search
-
- The event is raised when a response is received from the simulator
+ Receive parcel voice cap
- A string containing a list of keywords to search for separated by a space character
- A set of flags which can be ORed to modify query options
- such as classified maturity rating.
- The category to search
- Each request is limited to 100 places
- being returned. To get the first 100 result entries of a request use 0,
- from 100-199 use 1, 200-299 use 2, etc.
- A UUID to correlate the results when the event is raised
-
- Search places containing the key words "foo" and "bar" in the "Any" category that are either PG or Adult
-
- UUID searchID = StartDirPlacesSearch("foo bar", DirFindFlags.DwellSort | DirFindFlags.IncludePG | DirFindFlags.IncludeAdult, ParcelCategory.Any, 0);
-
-
-
- Additional information on the results can be obtained by using the ParcelManager.InfoRequest method
-
+
+
+
-
+
- Starts a search for land sales using the directory
-
- The event is raised when a response is received from the simulator
+ Tell Vivox where we are standing
- What type of land to search for. Auction,
- estate, mainland, "first land", etc
- The OnDirLandReply event handler must be registered before
- calling this function. There is no way to determine how many
- results will be returned, or how many times the callback will be
- fired other than you won't get more than 100 total parcels from
- each query.
+ This has to be called when we move or turn.
-
+
- Starts a search for land sales using the directory
-
- The event is raised when a response is received from the simulator
+ Start and stop updating out position.
- What type of land to search for. Auction,
- estate, mainland, "first land", etc
- Maximum price to search for
- Maximum area to search for
- Each request is limited to 100 parcels
- being returned. To get the first 100 parcels of a request use 0,
- from 100-199 use 1, 200-299 use 2, etc.
- The OnDirLandReply event handler must be registered before
- calling this function. There is no way to determine how many
- results will be returned, or how many times the callback will be
- fired other than you won't get more than 100 total parcels from
- each query.
+
-
+
- Send a request to the data server for land sales listings
+ This is used to initialize and stop the Connector as a whole. The Connector
+ Create call must be completed successfully before any other requests are made
+ (typically during application initialization). The shutdown should be called
+ when the application is shutting down to gracefully release resources
-
- Flags sent to specify query options
-
- Available flags:
- Specify the parcel rating with one or more of the following:
- IncludePG IncludeMature IncludeAdult
-
- Specify the field to pre sort the results with ONLY ONE of the following:
- PerMeterSort NameSort AreaSort PricesSort
-
- Specify the order the results are returned in, if not specified the results are pre sorted in a Descending Order
- SortAsc
-
- Specify additional filters to limit the results with one or both of the following:
- LimitByPrice LimitByArea
-
- Flags can be combined by separating them with the | (pipe) character
-
- Additional details can be found in
-
- What type of land to search for. Auction,
- Estate or Mainland
- Maximum price to search for when the
- DirFindFlags.LimitByPrice flag is specified in findFlags
- Maximum area to search for when the
- DirFindFlags.LimitByArea flag is specified in findFlags
- Each request is limited to 100 parcels
- being returned. To get the first 100 parcels of a request use 0,
- from 100-199 use 100, 200-299 use 200, etc.
- The event will be raised with the response from the simulator
-
- There is no way to determine how many results will be returned, or how many times the callback will be
- fired other than you won't get more than 100 total parcels from
- each reply.
-
- Any land set for sale to either anybody or specific to the connected agent will be included in the
- results if the land is included in the query
-
-
- // request all mainland, any maturity rating that is larger than 512 sq.m
- StartLandSearch(DirFindFlags.SortAsc | DirFindFlags.PerMeterSort | DirFindFlags.LimitByArea | DirFindFlags.IncludePG | DirFindFlags.IncludeMature | DirFindFlags.IncludeAdult, SearchTypeFlags.Mainland, 0, 512, 0);
-
+ A string value indicting the Application name
+ URL for the management server
+ LoggingSettings
+
+
-
+
- Search for Groups
+ Shutdown Connector -- Should be called when the application is shutting down
+ to gracefully release resources
- The name or portion of the name of the group you wish to search for
- Start from the match number
-
+ Handle returned from successful Connector ‘create’ request
-
+
- Search for Groups
+ Mute or unmute the microphone
- The name or portion of the name of the group you wish to search for
- Start from the match number
- Search flags
-
+ Handle returned from successful Connector ‘create’ request
+ true (mute) or false (unmute)
-
+
- Search the People directory for other avatars
+ Mute or unmute the speaker
- The name or portion of the name of the avatar you wish to search for
-
-
+ Handle returned from successful Connector ‘create’ request
+ true (mute) or false (unmute)
-
+
- Search Places for parcels of land you personally own
+ Set microphone volume
+ Handle returned from successful Connector ‘create’ request
+ The level of the audio, a number between -100 and 100 where
+ 0 represents ‘normal’ speaking volume
-
+
- Searches Places for land owned by the specified group
+ Set local speaker volume
- ID of the group you want to recieve land list for (You must be a member of the group)
- Transaction (Query) ID which can be associated with results from your request.
+ Handle returned from successful Connector ‘create’ request
+ The level of the audio, a number between -100 and 100 where
+ 0 represents ‘normal’ speaking volume
-
+
- Search the Places directory for parcels that are listed in search and contain the specified keywords
+ This is used to login a specific user account(s). It may only be called after
+ Connector initialization has completed successfully
- A string containing the keywords to search for
- Transaction (Query) ID which can be associated with results from your request.
+ Handle returned from successful Connector ‘create’ request
+ User's account name
+ User's account password
+ Values may be “AutoAnswer” or “VerifyAnswer”
+ ""
+ This is an integer that specifies how often
+ the daemon will send participant property events while in a channel. If this is not set
+ the default will be “on state change”, which means that the events will be sent when
+ the participant starts talking, stops talking, is muted, is unmuted.
+ The valid values are:
+ 0 – Never
+ 5 – 10 times per second
+ 10 – 5 times per second
+ 50 – 1 time per second
+ 100 – on participant state change (this is the default)
+ false
+
-
+
- Search Places - All Options
+ This is used to logout a user session. It should only be called with a valid AccountHandle.
- One of the Values from the DirFindFlags struct, ie: AgentOwned, GroupOwned, etc.
- One of the values from the SearchCategory Struct, ie: Any, Linden, Newcomer
- A string containing a list of keywords to search for separated by a space character
- String Simulator Name to search in
- LLUID of group you want to recieve results for
- Transaction (Query) ID which can be associated with results from your request.
- Transaction (Query) ID which can be associated with results from your request.
+ Handle returned from successful Connector ‘login’ request
+
-
+
- Search All Events with specifid searchText in all categories, includes PG, Mature and Adult
+ Event for most mundane request reposnses.
- A string containing a list of keywords to search for separated by a space character
- Each request is limited to 100 entries
- being returned. To get the first group of entries of a request use 0,
- from 100-199 use 100, 200-299 use 200, etc.
- UUID of query to correlate results in callback.
-
-
- Search Events
-
- A string containing a list of keywords to search for separated by a space character
- One or more of the following flags: DateEvents, IncludePG, IncludeMature, IncludeAdult
- from the Enum
-
- Multiple flags can be combined by separating the flags with the | (pipe) character
- "u" for in-progress and upcoming events, -or- number of days since/until event is scheduled
- For example "0" = Today, "1" = tomorrow, "2" = following day, "-1" = yesterday, etc.
- Each request is limited to 100 entries
- being returned. To get the first group of entries of a request use 0,
- from 100-199 use 100, 200-299 use 200, etc.
- EventCategory event is listed under.
- UUID of query to correlate results in callback.
+
+ Response to Connector.Create request
-
- Requests Event Details
- ID of Event returned from the method
+
+ Response to Aux.GetCaptureDevices request
-
- Process an incoming packet and raise the appropriate events
- The sender
- The EventArgs object containing the packet data
+
+ Response to Aux.GetRenderDevices request
-
- Process an incoming packet and raise the appropriate events
- The sender
- The EventArgs object containing the packet data
+
+ Audio Properties Events are sent after audio capture is started.
+ These events are used to display a microphone VU meter
-
- Process an incoming event message
- The Unique Capabilities Key
- The event message containing the data
- The simulator the message originated from
+
+ Response to Account.Login request
-
- Process an incoming packet and raise the appropriate events
- The sender
- The EventArgs object containing the packet data
+
+ This event message is sent whenever the login state of the
+ particular Account has transitioned from one value to another
-
- Process an incoming packet and raise the appropriate events
- The sender
- The EventArgs object containing the packet data
+
+
+ List of audio input devices
+
-
- Process an incoming event message
- The Unique Capabilities Key
- The event message containing the data
- The simulator the message originated from
+
+
+ List of audio output devices
+
-
- Process an incoming packet and raise the appropriate events
- The sender
- The EventArgs object containing the packet data
+
+
+ Set audio test mode
+
-
- Process an incoming packet and raise the appropriate events
- The sender
- The EventArgs object containing the packet data
+
+ Enable logging
-
- Process an incoming packet and raise the appropriate events
- The sender
- The EventArgs object containing the packet data
+
+ The folder where any logs will be created
-
- Process an incoming packet and raise the appropriate events
- The sender
- The EventArgs object containing the packet data
+
+ This will be prepended to beginning of each log file
-
- Raised when the data server responds to a request.
+
+ The suffix or extension to be appended to each log file
-
- Raised when the data server responds to a request.
+
+
+ 0: NONE - No logging
+ 1: ERROR - Log errors only
+ 2: WARNING - Log errors and warnings
+ 3: INFO - Log errors, warnings and info
+ 4: DEBUG - Log errors, warnings, info and debug
+
-
- Raised when the data server responds to a request.
+
+
+ Constructor for default logging settings
+
-
- Raised when the data server responds to a request.
+
+ Audio Properties Events are sent after audio capture is started. These events are used to display a microphone VU meter
-
- Raised when the data server responds to a request.
+
+ Positional vector of the users position
-
- Raised when the data server responds to a request.
+
+ Velocity vector of the position
-
- Raised when the data server responds to a request.
+
+ At Orientation (X axis) of the position
-
- Raised when the data server responds to a request.
+
+ Up Orientation (Y axis) of the position
-
- Classified Ad categories
+
+ Left Orientation (Z axis) of the position
-
- Classified is listed in the Any category
+
+
+ Represents a string of characters encoded with specific formatting properties
+
-
- Classified is shopping related
+
+
+ Base class for all Asset types
+
-
- Classified is
+
+ A byte array containing the raw asset data
-
-
+
+ True if the asset it only stored on the server temporarily
-
-
+
+ A unique ID
-
-
+
+
+ Construct a new Asset object
+
-
-
+
+
+ Construct a new Asset object
+
+ A unique specific to this asset
+ A byte array containing the raw asset data
-
-
+
+
+ Regenerates the AssetData
byte array from the properties
+ of the derived class.
+
-
-
+
+
+ Decodes the AssetData, placing it in appropriate properties of the derived
+ class.
+
+ True if the asset decoding succeeded, otherwise false
-
-
+
+ The assets unique ID
-
- Event Categories
+
+
+ The "type" of asset, Notecard, Animation, etc
+
-
-
+
+ A text string containing main text of the notecard
-
-
+
+ List of s embedded on the notecard
-
-
+
+ Construct an Asset of type Notecard
-
-
+
+
+ Construct an Asset object of type Notecard
+
+ A unique specific to this asset
+ A byte array containing the raw asset data
-
-
+
+
+ Encode the raw contents of a string with the specific Linden Text properties
+
-
-
+
+
+ Decode the raw asset data including the Linden Text properties
+
+ true if the AssetData was successfully decoded
-
-
+
+ Override the base classes AssetType
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
- Query Flags used in many of the DirectoryManager methods to specify which query to execute and how to return the results.
- Flags can be combined using the | (pipe) character, not all flags are available in all queries
-
- Query the People database
+
+ The event subscribers, null of no subscribers
-
-
+
+ Raises the AttachedSound Event
+ A AttachedSoundEventArgs object containing
+ the data sent from the simulator
-
-
+
+ Thread sync lock object
-
- Query the Groups database
+
+ The event subscribers, null of no subscribers
-
- Query the Events database
+
+ Raises the AttachedSoundGainChange Event
+ A AttachedSoundGainChangeEventArgs object containing
+ the data sent from the simulator
-
- Query the land holdings database for land owned by the currently connected agent
+
+ Thread sync lock object
-
-
+
+ The event subscribers, null of no subscribers
-
- Query the land holdings database for land which is owned by a Group
+
+ Raises the SoundTrigger Event
+ A SoundTriggerEventArgs object containing
+ the data sent from the simulator
-
- Specifies the query should pre sort the results based upon traffic
- when searching the Places database
+
+ Thread sync lock object
-
-
+
+ The event subscribers, null of no subscribers
-
-
+
+ Raises the PreloadSound Event
+ A PreloadSoundEventArgs object containing
+ the data sent from the simulator
-
-
+
+ Thread sync lock object
-
-
+
+
+ Construct a new instance of the SoundManager class, used for playing and receiving
+ sound assets
+
+ A reference to the current GridClient instance
-
- Specifies the query should pre sort the results in an ascending order when searching the land sales database.
- This flag is only used when searching the land sales database
+
+
+ Plays a sound in the current region at full volume from avatar position
+
+ UUID of the sound to be played
-
- Specifies the query should pre sort the results using the SalePrice field when searching the land sales database.
- This flag is only used when searching the land sales database
+
+
+ Plays a sound in the current region at full volume
+
+ UUID of the sound to be played.
+ position for the sound to be played at. Normally the avatar.
-
- Specifies the query should pre sort the results by calculating the average price/sq.m (SalePrice / Area) when searching the land sales database.
- This flag is only used when searching the land sales database
+
+
+ Plays a sound in the current region
+
+ UUID of the sound to be played.
+ position for the sound to be played at. Normally the avatar.
+ volume of the sound, from 0.0 to 1.0
-
- Specifies the query should pre sort the results using the ParcelSize field when searching the land sales database.
- This flag is only used when searching the land sales database
+
+
+ Plays a sound in the specified sim
+
+ UUID of the sound to be played.
+ UUID of the sound to be played.
+ position for the sound to be played at. Normally the avatar.
+ volume of the sound, from 0.0 to 1.0
-
- Specifies the query should pre sort the results using the Name field when searching the land sales database.
- This flag is only used when searching the land sales database
+
+
+ Play a sound asset
+
+ UUID of the sound to be played.
+ handle id for the sim to be played in.
+ position for the sound to be played at. Normally the avatar.
+ volume of the sound, from 0.0 to 1.0
-
- When set, only parcels less than the specified Price will be included when searching the land sales database.
- This flag is only used when searching the land sales database
+
+ Process an incoming packet and raise the appropriate events
+ The sender
+ The EventArgs object containing the packet data
-
- When set, only parcels greater than the specified Size will be included when searching the land sales database.
- This flag is only used when searching the land sales database
+
+ Process an incoming packet and raise the appropriate events
+ The sender
+ The EventArgs object containing the packet data
-
-
+
+ Process an incoming packet and raise the appropriate events
+ The sender
+ The EventArgs object containing the packet data
-
-
+
+ Process an incoming packet and raise the appropriate events
+ The sender
+ The EventArgs object containing the packet data
-
- Include PG land in results. This flag is used when searching both the Groups, Events and Land sales databases
+
+ Raised when the simulator sends us data containing
+ sound
-
- Include Mature land in results. This flag is used when searching both the Groups, Events and Land sales databases
+
+ Raised when the simulator sends us data containing
+ ...
-
- Include Adult land in results. This flag is used when searching both the Groups, Events and Land sales databases
+
+ Raised when the simulator sends us data containing
+ ...
-
-
+
+ Raised when the simulator sends us data containing
+ ...
-
+
+ Provides data for the event
+ The event occurs when the simulator sends
+ the sound data which emits from an agents attachment
+
+ The following code example shows the process to subscribe to the event
+ and a stub to handle the data passed from the simulator
+
+ // Subscribe to the AttachedSound event
+ Client.Sound.AttachedSound += Sound_AttachedSound;
+
+ // process the data raised in the event here
+ private void Sound_AttachedSound(object sender, AttachedSoundEventArgs e)
+ {
+ // ... Process AttachedSoundEventArgs here ...
+ }
+
+
+
+
- Land types to search dataserver for
+ Construct a new instance of the SoundTriggerEventArgs class
+ Simulator where the event originated
+ The sound asset id
+ The ID of the owner
+ The ID of the object
+ The volume level
+ The
-
- Search Auction, Mainland and Estate
-
-
- Land which is currently up for auction
+
+ Simulator where the event originated
-
- Parcels which are on the mainland (Linden owned) continents
+
+ Get the sound asset id
-
- Parcels which are on privately owned simulators
+
+ Get the ID of the owner
-
-
- The content rating of the event
-
+
+ Get the ID of the Object
-
- Event is PG
+
+ Get the volume level
-
- Event is Mature
+
+ Get the
-
- Event is Adult
+
+ Provides data for the event
+ The event occurs when an attached sound
+ changes its volume level
-
+
- Classified Ad Options
+ Construct a new instance of the AttachedSoundGainChangedEventArgs class
- There appear to be two formats the flags are packed in.
- This set of flags is for the newer style
+ Simulator where the event originated
+ The ID of the Object
+ The new volume level
-
-
+
+ Simulator where the event originated
-
-
-
-
-
+
+ Get the ID of the Object
-
-
+
+ Get the volume level
-
-
+
+ Provides data for the event
+ The event occurs when the simulator forwards
+ a request made by yourself or another agent to play either an asset sound or a built in sound
+
+ Requests to play sounds where the is not one of the built-in
+ will require sending a request to download the sound asset before it can be played
+
+
+ The following code example uses the ,
+ and
+ properties to display some information on a sound request on the window.
+
+ // subscribe to the event
+ Client.Sound.SoundTrigger += Sound_SoundTrigger;
+
+ // play the pre-defined BELL_TING sound
+ Client.Sound.SendSoundTrigger(Sounds.BELL_TING);
+
+ // handle the response data
+ private void Sound_SoundTrigger(object sender, SoundTriggerEventArgs e)
+ {
+ Console.WriteLine("{0} played the sound {1} at volume {2}",
+ e.OwnerID, e.SoundID, e.Gain);
+ }
+
+
-
+
- Classified ad query options
+ Construct a new instance of the SoundTriggerEventArgs class
+ Simulator where the event originated
+ The sound asset id
+ The ID of the owner
+ The ID of the object
+ The ID of the objects parent
+ The volume level
+ The regionhandle
+ The source position
-
- Include all ads in results
-
-
- Include PG ads in results
+
+ Simulator where the event originated
-
- Include Mature ads in results
+
+ Get the sound asset id
-
- Include Adult ads in results
+
+ Get the ID of the owner
-
-
- The For Sale flag in PlacesReplyData
-
+
+ Get the ID of the Object
-
- Parcel is not listed for sale
+
+ Get the ID of the objects parent
-
- Parcel is For Sale
+
+ Get the volume level
-
-
- A classified ad on the grid
-
+
+ Get the regionhandle
-
- UUID for this ad, useful for looking up detailed
- information about it
+
+ Get the source position
-
- The title of this classified ad
+
+ Provides data for the event
+ The event occurs when the simulator sends
+ the appearance data for an avatar
+
+ The following code example uses the and
+ properties to display the selected shape of an avatar on the window.
+
+ // subscribe to the event
+ Client.Avatars.AvatarAppearance += Avatars_AvatarAppearance;
+
+ // handle the data when the event is raised
+ void Avatars_AvatarAppearance(object sender, AvatarAppearanceEventArgs e)
+ {
+ Console.WriteLine("The Agent {0} is using a {1} shape.", e.AvatarID, (e.VisualParams[31] > 0) : "male" ? "female")
+ }
+
+
-
- Flags that show certain options applied to the classified
+
+
+ Construct a new instance of the PreloadSoundEventArgs class
+
+ Simulator where the event originated
+ The sound asset id
+ The ID of the owner
+ The ID of the object
-
- Creation date of the ad
+
+ Simulator where the event originated
-
- Expiration date of the ad
+
+ Get the sound asset id
-
- Price that was paid for this ad
+
+ Get the ID of the owner
-
- Print the struct data as a string
- A string containing the field name, and field value
+
+ Get the ID of the Object
-
+
- A parcel retrieved from the dataserver such as results from the
- "For-Sale" listings or "Places" Search
+ Capabilities is the name of the bi-directional HTTP REST protocol
+ used to communicate non real-time transactions such as teleporting or
+ group messaging
-
- The unique dataserver parcel ID
- This id is used to obtain additional information from the entry
- by using the method
-
-
- A string containing the name of the parcel
+
+ Reference to the simulator this system is connected to
-
- The size of the parcel
- This field is not returned for Places searches
+
+
+ Default constructor
+
+
+
-
- The price of the parcel
- This field is not returned for Places searches
+
+
+ Request the URI of a named capability
+
+ Name of the capability to request
+ The URI of the requested capability, or String.Empty if
+ the capability does not exist
-
- If True, this parcel is flagged to be auctioned
+
+
+ Process any incoming events, check to see if we have a message created for the event,
+
+
+
-
- If true, this parcel is currently set for sale
+
+ Capabilities URI this system was initialized with
-
- Parcel traffic
+
+ Whether the capabilities event queue is connected and
+ listening for incoming events
-
- Print the struct data as a string
- A string containing the field name, and field value
+
+
+ Triggered when an event is received via the EventQueueGet
+ capability
+
+ Event name
+ Decoded event data
+ The simulator that generated the event
-
+
- An Avatar returned from the dataserver
+ Manager class for our own avatar
-
- Online status of agent
- This field appears to be obsolete and always returns false
+
+ The event subscribers. null if no subcribers
-
- The agents first name
+
+ Raises the ChatFromSimulator event
+ A ChatEventArgs object containing the
+ data returned from the data server
-
- The agents last name
+
+ Thread sync lock object
-
- The agents
+
+ The event subscribers. null if no subcribers
-
- Print the struct data as a string
- A string containing the field name, and field value
+
+ Raises the ScriptDialog event
+ A SctriptDialogEventArgs object containing the
+ data returned from the data server
-
-
- Response to a "Groups" Search
-
+
+ Thread sync lock object
-
- The Group ID
+
+ The event subscribers. null if no subcribers
-
- The name of the group
+
+ Raises the ScriptQuestion event
+ A ScriptQuestionEventArgs object containing the
+ data returned from the data server
-
- The current number of members
+
+ Thread sync lock object
-
- Print the struct data as a string
- A string containing the field name, and field value
+
+ The event subscribers. null if no subcribers
-
-
- Parcel information returned from a request
-
- Represents one of the following:
- A parcel of land on the grid that has its Show In Search flag set
- A parcel of land owned by the agent making the request
- A parcel of land owned by a group the agent making the request is a member of
-
-
- In a request for Group Land, the First record will contain an empty record
-
- Note: This is not the same as searching the land for sale data source
-
-
-
- The ID of the Agent of Group that owns the parcel
+
+ Raises the LoadURL event
+ A LoadUrlEventArgs object containing the
+ data returned from the data server
-
- The name
+
+ Thread sync lock object
-
- The description
+
+ The event subscribers. null if no subcribers
-
- The Size of the parcel
+
+ Raises the MoneyBalance event
+ A BalanceEventArgs object containing the
+ data returned from the data server
-
- The billable Size of the parcel, for mainland
- parcels this will match the ActualArea field. For Group owned land this will be 10 percent smaller
- than the ActualArea. For Estate land this will always be 0
+
+ Thread sync lock object
-
- Indicates the ForSale status of the parcel
+
+ The event subscribers. null if no subcribers
-
- The Gridwide X position
+
+ Raises the MoneyBalanceReply event
+ A MoneyBalanceReplyEventArgs object containing the
+ data returned from the data server
-
- The Gridwide Y position
+
+ Thread sync lock object
-
- The Z position of the parcel, or 0 if no landing point set
+
+ The event subscribers. null if no subcribers
-
- The name of the Region the parcel is located in
+
+ Raises the IM event
+ A InstantMessageEventArgs object containing the
+ data returned from the data server
-
- The Asset ID of the parcels Snapshot texture
+
+ Thread sync lock object
-
- The calculated visitor traffic
+
+ The event subscribers. null if no subcribers
-
- The billing product SKU
- Known values are:
-
- - 023Mainland / Full Region
- - 024Estate / Full Region
- - 027Estate / Openspace
- - 029Estate / Homestead
- - 129Mainland / Homestead (Linden Owned)
-
-
+
+ Raises the TeleportProgress event
+ A TeleportEventArgs object containing the
+ data returned from the data server
-
- No longer used, will always be 0
+
+ Thread sync lock object
-
- Get a SL URL for the parcel
- A string, containing a standard SLURL
+
+ The event subscribers. null if no subcribers
-
- Print the struct data as a string
- A string containing the field name, and field value
+
+ Raises the AgentDataReply event
+ A AgentDataReplyEventArgs object containing the
+ data returned from the data server
-
-
- An "Event" Listing summary
-
+
+ Thread sync lock object
-
- The ID of the event creator
+
+ The event subscribers. null if no subcribers
-
- The name of the event
+
+ Raises the AnimationsChanged event
+ A AnimationsChangedEventArgs object containing the
+ data returned from the data server
-
- The events ID
+
+ Thread sync lock object
-
- A string containing the short date/time the event will begin
+
+ The event subscribers. null if no subcribers
-
- The event start time in Unixtime (seconds since epoch)
+
+ Raises the MeanCollision event
+ A MeanCollisionEventArgs object containing the
+ data returned from the data server
-
- The events maturity rating
+
+