Compare commits
69 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1e72e1b258 | |||
| bbb9af363d | |||
| bbc40fab62 | |||
| 6026759406 | |||
| 70d24a654b | |||
| 1286677352 | |||
| 803e5498b0 | |||
| 71e26555bd | |||
| 391633c072 | |||
| 1dd3a0bc57 | |||
| 9b75d75724 | |||
| 93fd5e4036 | |||
| b29a09ab8e | |||
| d838f15d97 | |||
| a65cec3986 | |||
| 97698ae311 | |||
| 03268d85c4 | |||
| 5f97c6f8f0 | |||
| c358d5d168 | |||
| 2f6ee8aee2 | |||
| 98de67d573 | |||
| ccceb6d6d2 | |||
| 55ac8c83c7 | |||
| a44ad01492 | |||
| 67407024a2 | |||
| 5dbdd5f8b4 | |||
| dd15f95499 | |||
| ca26583e6b | |||
| c4506cf4f3 | |||
| 8265a88c4a | |||
| f2f33b7577 | |||
| d80936bbbb | |||
| da3aa44138 | |||
| 33ddb6c246 | |||
| c95a23863a | |||
| 38a04ff993 | |||
| d997c49e47 | |||
| ca380ec039 | |||
| 93ee515d9d | |||
| fdafc2a16c | |||
| bf214122cd | |||
| 15d0bc0900 | |||
| ec9ffbb89a | |||
| c61becc62b | |||
| 0cc0a2485c | |||
| ae42c93f9a | |||
| 98a2fa8e35 | |||
| 068a3afad9 | |||
| 16f40c1a15 | |||
| 5eb78aad96 | |||
| 80f4a008eb | |||
| 27cdfb7b84 | |||
| 25889b2d7e | |||
| 119f84fe11 | |||
| 06dba1fa62 | |||
| 4d24bf75fd | |||
| d01b8e163d | |||
| 316e8f9239 | |||
| 9725b829d5 | |||
| 2c05caec7f | |||
| 626940ceb8 | |||
| e984bfb4c6 | |||
| ccca005969 | |||
| 635704b7ef | |||
| 8eb86c9ec9 | |||
| c24c99f4ba | |||
| 9d5ae75950 | |||
| 425d2a2a97 | |||
| 23516717e4 |
@@ -50,6 +50,7 @@ namespace OpenSim.Data
|
||||
public interface IGridUserData
|
||||
{
|
||||
GridUserData Get(string userID);
|
||||
GridUserData[] GetAll(string query);
|
||||
bool Store(GridUserData data);
|
||||
}
|
||||
}
|
||||
@@ -50,7 +50,7 @@ namespace OpenSim.Data.MSSQL
|
||||
{
|
||||
}
|
||||
|
||||
public GridUserData Get(string userID)
|
||||
public new GridUserData Get(string userID)
|
||||
{
|
||||
GridUserData[] ret = Get("UserID", userID);
|
||||
|
||||
@@ -60,5 +60,10 @@ namespace OpenSim.Data.MSSQL
|
||||
return ret[0];
|
||||
}
|
||||
|
||||
public GridUserData[] GetAll(string userID)
|
||||
{
|
||||
return base.Get(String.Format("UserID LIKE '{0}%'", userID));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace OpenSim.Data.MySQL
|
||||
|
||||
public MySQLGridUserData(string connectionString, string realm) : base(connectionString, realm, "GridUserStore") {}
|
||||
|
||||
public GridUserData Get(string userID)
|
||||
public new GridUserData Get(string userID)
|
||||
{
|
||||
GridUserData[] ret = Get("UserID", userID);
|
||||
|
||||
@@ -56,6 +56,9 @@ namespace OpenSim.Data.MySQL
|
||||
return ret[0];
|
||||
}
|
||||
|
||||
|
||||
public GridUserData[] GetAll(string userID)
|
||||
{
|
||||
return base.Get(String.Format("UserID LIKE '{0}%'", userID));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ CREATE TABLE `Friends` (
|
||||
`Offered` VARCHAR(32) NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY(`PrincipalID`, `Friend`),
|
||||
KEY(`PrincipalID`)
|
||||
);
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
COMMIT;
|
||||
|
||||
|
||||
@@ -56,6 +56,10 @@ namespace OpenSim.Data.SQLite
|
||||
return ret[0];
|
||||
}
|
||||
|
||||
public GridUserData[] GetAll(string userID)
|
||||
{
|
||||
return base.Get(String.Format("UserID LIKE '{0}%'", userID));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -226,18 +226,6 @@ namespace OpenSim
|
||||
"Force the update of all objects on clients",
|
||||
HandleForceUpdate);
|
||||
|
||||
m_console.Commands.AddCommand("Debug", false, "debug packet",
|
||||
"debug packet <level> [<avatar-first-name> <avatar-last-name>]",
|
||||
"Turn on packet debugging",
|
||||
"If level > 255 then all incoming and outgoing packets are logged.\n"
|
||||
+ "If level <= 255 then incoming AgentUpdate and outgoing SimStats and SimulatorViewerTimeMessage packets are not logged.\n"
|
||||
+ "If level <= 200 then incoming RequestImage and outgoing ImagePacket, ImageData, LayerData and CoarseLocationUpdate packets are not logged.\n"
|
||||
+ "If level <= 100 then incoming ViewerEffect and AgentAnimation and outgoing ViewerEffect and AvatarAnimation packets are not logged.\n"
|
||||
+ "If level <= 50 then outgoing ImprovedTerseObjectUpdate packets are not logged.\n"
|
||||
+ "If level <= 0 then no packets are logged.\n"
|
||||
+ "If an avatar name is given then only packets from that avatar are logged",
|
||||
Debug);
|
||||
|
||||
m_console.Commands.AddCommand("General", false, "change region",
|
||||
"change region <region name>",
|
||||
"Change current console region", ChangeSelectedRegion);
|
||||
@@ -701,45 +689,6 @@ namespace OpenSim
|
||||
RefreshPrompt();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Turn on some debugging values for OpenSim.
|
||||
/// </summary>
|
||||
/// <param name="args"></param>
|
||||
protected void Debug(string module, string[] args)
|
||||
{
|
||||
if (args.Length == 1)
|
||||
return;
|
||||
|
||||
switch (args[1])
|
||||
{
|
||||
case "packet":
|
||||
string name = null;
|
||||
if (args.Length == 5)
|
||||
name = string.Format("{0} {1}", args[3], args[4]);
|
||||
|
||||
if (args.Length > 2)
|
||||
{
|
||||
int newDebug;
|
||||
if (int.TryParse(args[2], out newDebug))
|
||||
{
|
||||
SceneManager.SetDebugPacketLevelOnCurrentScene(newDebug, name);
|
||||
// We provide user information elsewhere if any clients had their debug level set.
|
||||
// MainConsole.Instance.OutputFormat("Debug packet level set to {0}", newDebug);
|
||||
}
|
||||
else
|
||||
{
|
||||
MainConsole.Instance.Output("Usage: debug packet 0..255");
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
MainConsole.Instance.Output("Unknown debug command");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// see BaseOpenSimServer
|
||||
/// <summary>
|
||||
/// Many commands list objects for debugging. Some of the types are listed here
|
||||
|
||||
@@ -759,73 +759,49 @@ namespace OpenSim
|
||||
/// <summary>
|
||||
/// Handler to supply the current status of this sim
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Currently this is always OK if the simulator is still listening for connections on its HTTP service
|
||||
public class SimStatusHandler : IStreamedRequestHandler
|
||||
/// </remarks>
|
||||
public class SimStatusHandler : BaseStreamHandler
|
||||
{
|
||||
public byte[] Handle(string path, Stream request,
|
||||
public SimStatusHandler() : base("GET", "/simstatus", "SimStatus", "Simulator Status") {}
|
||||
|
||||
public override byte[] Handle(string path, Stream request,
|
||||
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||
{
|
||||
return Util.UTF8.GetBytes("OK");
|
||||
}
|
||||
|
||||
public string Name { get { return "SimStatus"; } }
|
||||
public string Description { get { return "Simulator Status"; } }
|
||||
|
||||
public string ContentType
|
||||
public override string ContentType
|
||||
{
|
||||
get { return "text/plain"; }
|
||||
}
|
||||
|
||||
public string HttpMethod
|
||||
{
|
||||
get { return "GET"; }
|
||||
}
|
||||
|
||||
public string Path
|
||||
{
|
||||
get { return "/simstatus"; }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler to supply the current extended status of this sim
|
||||
/// Sends the statistical data in a json serialization
|
||||
/// </summary>
|
||||
public class XSimStatusHandler : IStreamedRequestHandler
|
||||
public class XSimStatusHandler : BaseStreamHandler
|
||||
{
|
||||
OpenSimBase m_opensim;
|
||||
string osXStatsURI = String.Empty;
|
||||
|
||||
public string Name { get { return "XSimStatus"; } }
|
||||
public string Description { get { return "Simulator XStatus"; } }
|
||||
|
||||
public XSimStatusHandler(OpenSimBase sim)
|
||||
public XSimStatusHandler(OpenSimBase sim)
|
||||
: base("GET", "/" + Util.SHA1Hash(sim.osSecret), "XSimStatus", "Simulator XStatus")
|
||||
{
|
||||
m_opensim = sim;
|
||||
osXStatsURI = Util.SHA1Hash(sim.osSecret);
|
||||
}
|
||||
|
||||
public byte[] Handle(string path, Stream request,
|
||||
public override byte[] Handle(string path, Stream request,
|
||||
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||
{
|
||||
return Util.UTF8.GetBytes(m_opensim.StatReport(httpRequest));
|
||||
}
|
||||
|
||||
public string ContentType
|
||||
public override string ContentType
|
||||
{
|
||||
get { return "text/plain"; }
|
||||
}
|
||||
|
||||
public string HttpMethod
|
||||
{
|
||||
get { return "GET"; }
|
||||
}
|
||||
|
||||
public string Path
|
||||
{
|
||||
// This is for the OpenSimulator instance and is the osSecret hashed
|
||||
get { return "/" + osXStatsURI; }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -834,42 +810,26 @@ namespace OpenSim
|
||||
/// If the request contains a key, "callback" the response will be wrappend in the
|
||||
/// associated value for jsonp used with ajax/javascript
|
||||
/// </summary>
|
||||
public class UXSimStatusHandler : IStreamedRequestHandler
|
||||
public class UXSimStatusHandler : BaseStreamHandler
|
||||
{
|
||||
OpenSimBase m_opensim;
|
||||
string osUXStatsURI = String.Empty;
|
||||
|
||||
public string Name { get { return "UXSimStatus"; } }
|
||||
public string Description { get { return "Simulator UXStatus"; } }
|
||||
|
||||
public UXSimStatusHandler(OpenSimBase sim)
|
||||
: base("GET", "/" + sim.userStatsURI, "UXSimStatus", "Simulator UXStatus")
|
||||
{
|
||||
m_opensim = sim;
|
||||
osUXStatsURI = sim.userStatsURI;
|
||||
|
||||
m_opensim = sim;
|
||||
}
|
||||
|
||||
public byte[] Handle(string path, Stream request,
|
||||
public override byte[] Handle(string path, Stream request,
|
||||
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||
{
|
||||
return Util.UTF8.GetBytes(m_opensim.StatReport(httpRequest));
|
||||
}
|
||||
|
||||
public string ContentType
|
||||
public override string ContentType
|
||||
{
|
||||
get { return "text/plain"; }
|
||||
}
|
||||
|
||||
public string HttpMethod
|
||||
{
|
||||
get { return "GET"; }
|
||||
}
|
||||
|
||||
public string Path
|
||||
{
|
||||
// This is for the OpenSimulator instance and is the user provided URI
|
||||
get { return "/" + osUXStatsURI; }
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -347,6 +347,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
Watchdog.UpdateThread();
|
||||
|
||||
aPollRequest poolreq = m_queue.Dequeue();
|
||||
|
||||
poolreq.thepoll.Process(poolreq);
|
||||
|
||||
@@ -421,7 +421,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
// foreign user is visiting, we need to try again after the first fail to the local
|
||||
// asset service.
|
||||
string assetServerURL = string.Empty;
|
||||
if (InventoryAccessModule.IsForeignUser(AgentID, out assetServerURL))
|
||||
if (InventoryAccessModule.IsForeignUser(AgentID, out assetServerURL) && !string.IsNullOrEmpty(assetServerURL))
|
||||
{
|
||||
if (!assetServerURL.EndsWith("/") && !assetServerURL.EndsWith("="))
|
||||
assetServerURL = assetServerURL + "/";
|
||||
|
||||
@@ -34,6 +34,7 @@ using System.Net.Sockets;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using log4net;
|
||||
using NDesk.Options;
|
||||
using Nini.Config;
|
||||
using OpenMetaverse.Packets;
|
||||
using OpenSim.Framework;
|
||||
@@ -102,10 +103,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
/// </summary>
|
||||
public class LLUDPServer : OpenSimUDPBase
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
/// <summary>Maximum transmission unit, or UDP packet size, for the LLUDP protocol</summary>
|
||||
public const int MTU = 1400;
|
||||
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
/// <summary>
|
||||
/// Default packet debug level given to new clients
|
||||
/// </summary>
|
||||
public int DefaultClientPacketDebugLevel { get; set; }
|
||||
|
||||
/// <summary>The measured resolution of Environment.TickCount</summary>
|
||||
public readonly float TickCountResolution;
|
||||
@@ -512,6 +518,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
if (UsePools)
|
||||
EnablePoolStats();
|
||||
|
||||
MainConsole.Instance.Commands.AddCommand(
|
||||
"Debug", false, "debug lludp packet",
|
||||
"debug lludp packet [--default] <level> [<avatar-first-name> <avatar-last-name>]",
|
||||
"Turn on packet debugging",
|
||||
"If level > 255 then all incoming and outgoing packets are logged.\n"
|
||||
+ "If level <= 255 then incoming AgentUpdate and outgoing SimStats and SimulatorViewerTimeMessage packets are not logged.\n"
|
||||
+ "If level <= 200 then incoming RequestImage and outgoing ImagePacket, ImageData, LayerData and CoarseLocationUpdate packets are not logged.\n"
|
||||
+ "If level <= 100 then incoming ViewerEffect and AgentAnimation and outgoing ViewerEffect and AvatarAnimation packets are not logged.\n"
|
||||
+ "If level <= 50 then outgoing ImprovedTerseObjectUpdate packets are not logged.\n"
|
||||
+ "If level <= 0 then no packets are logged.\n"
|
||||
+ "If --default is specified then the level becomes the default logging level for all subsequent agents.\n"
|
||||
+ "In this case, you cannot also specify an avatar name.\n"
|
||||
+ "If an avatar name is given then only packets from that avatar are logged.",
|
||||
HandlePacketCommand);
|
||||
|
||||
MainConsole.Instance.Commands.AddCommand(
|
||||
"Debug",
|
||||
false,
|
||||
@@ -553,8 +574,68 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
HandleStatusCommand);
|
||||
}
|
||||
|
||||
private void HandlePacketCommand(string module, string[] args)
|
||||
{
|
||||
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
|
||||
return;
|
||||
|
||||
bool setAsDefaultLevel = false;
|
||||
OptionSet optionSet = new OptionSet().Add("default", o => setAsDefaultLevel = o != null);
|
||||
List<string> filteredArgs = optionSet.Parse(args);
|
||||
|
||||
string name = null;
|
||||
|
||||
if (filteredArgs.Count == 6)
|
||||
{
|
||||
if (!setAsDefaultLevel)
|
||||
{
|
||||
name = string.Format("{0} {1}", filteredArgs[4], filteredArgs[5]);
|
||||
}
|
||||
else
|
||||
{
|
||||
MainConsole.Instance.OutputFormat("ERROR: Cannot specify a user name when setting default logging level");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (filteredArgs.Count > 3)
|
||||
{
|
||||
int newDebug;
|
||||
if (int.TryParse(filteredArgs[3], out newDebug))
|
||||
{
|
||||
if (setAsDefaultLevel)
|
||||
{
|
||||
DefaultClientPacketDebugLevel = newDebug;
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"Debug packet debug for new clients set to {0}", DefaultClientPacketDebugLevel);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_scene.ForEachScenePresence(sp =>
|
||||
{
|
||||
if (name == null || sp.Name == name)
|
||||
{
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"Packet debug for {0} ({1}) set to {2} in {3}",
|
||||
sp.Name, sp.IsChildAgent ? "child" : "root", newDebug, m_scene.Name);
|
||||
|
||||
sp.ControllingClient.DebugPacketLevel = newDebug;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MainConsole.Instance.Output("Usage: debug lludp packet [--default] 0..255 [<first-name> <last-name>]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleStartCommand(string module, string[] args)
|
||||
{
|
||||
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
|
||||
return;
|
||||
|
||||
if (args.Length != 4)
|
||||
{
|
||||
MainConsole.Instance.Output("Usage: debug lludp start <in|out|all>");
|
||||
@@ -572,6 +653,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
private void HandleStopCommand(string module, string[] args)
|
||||
{
|
||||
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
|
||||
return;
|
||||
|
||||
if (args.Length != 4)
|
||||
{
|
||||
MainConsole.Instance.Output("Usage: debug lludp stop <in|out|all>");
|
||||
@@ -589,6 +673,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
private void HandlePoolCommand(string module, string[] args)
|
||||
{
|
||||
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
|
||||
return;
|
||||
|
||||
if (args.Length != 4)
|
||||
{
|
||||
MainConsole.Instance.Output("Usage: debug lludp pool <on|off>");
|
||||
@@ -621,6 +708,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
private void HandleStatusCommand(string module, string[] args)
|
||||
{
|
||||
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
|
||||
return;
|
||||
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"IN LLUDP packet processing for {0} is {1}", m_scene.Name, IsRunningInbound ? "enabled" : "disabled");
|
||||
|
||||
@@ -628,6 +718,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
"OUT LLUDP packet processing for {0} is {1}", m_scene.Name, IsRunningOutbound ? "enabled" : "disabled");
|
||||
|
||||
MainConsole.Instance.OutputFormat("LLUDP pools in {0} are {1}", m_scene.Name, UsePools ? "on" : "off");
|
||||
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"Packet debug level for new clients is {0}", DefaultClientPacketDebugLevel);
|
||||
}
|
||||
|
||||
public bool HandlesRegion(Location x)
|
||||
@@ -1474,6 +1567,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
client = new LLClientView(m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode);
|
||||
client.OnLogout += LogoutHandler;
|
||||
client.DebugPacketLevel = DefaultClientPacketDebugLevel;
|
||||
|
||||
((LLClientView)client).DisableFacelights = m_disableFacelights;
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
public override void SetUp()
|
||||
{
|
||||
base.SetUp();
|
||||
|
||||
|
||||
@@ -498,6 +498,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
|
||||
protected virtual void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online)
|
||||
{
|
||||
//m_log.DebugFormat("[FRIENDS]: Entering StatusNotify for {0}", userID);
|
||||
|
||||
List<string> friendStringIds = friendList.ConvertAll<string>(friend => friend.Friend);
|
||||
List<string> remoteFriendStringIds = new List<string>();
|
||||
foreach (string friendStringId in friendStringIds)
|
||||
@@ -523,12 +525,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
foreach (PresenceInfo friendSession in friendSessions)
|
||||
{
|
||||
// let's guard against sessions-gone-bad
|
||||
if (friendSession.RegionID != UUID.Zero)
|
||||
if (friendSession != null && friendSession.RegionID != UUID.Zero)
|
||||
{
|
||||
//m_log.DebugFormat("[FRIENDS]: Get region {0}", friendSession.RegionID);
|
||||
GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
|
||||
//m_log.DebugFormat("[FRIENDS]: Remote Notify to region {0}", region.RegionName);
|
||||
m_FriendsSimConnector.StatusNotify(region, userID, friendSession.UserID, online);
|
||||
if (region != null)
|
||||
{
|
||||
m_FriendsSimConnector.StatusNotify(region, userID, friendSession.UserID, online);
|
||||
}
|
||||
}
|
||||
//else
|
||||
// m_log.DebugFormat("[FRIENDS]: friend session is null or the region is UUID.Zero");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -252,7 +252,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
|
||||
protected override void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online)
|
||||
{
|
||||
// m_log.DebugFormat("[HGFRIENDS MODULE]: Entering StatusNotify for {0}", userID);
|
||||
//m_log.DebugFormat("[HGFRIENDS MODULE]: Entering StatusNotify for {0}", userID);
|
||||
|
||||
// First, let's divide the friends on a per-domain basis
|
||||
Dictionary<string, List<FriendInfo>> friendsPerDomain = new Dictionary<string, List<FriendInfo>>();
|
||||
@@ -348,31 +348,30 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
return null;
|
||||
}
|
||||
|
||||
// public override FriendInfo[] GetFriendsFromService(IClientAPI client)
|
||||
// {
|
||||
//// m_log.DebugFormat("[HGFRIENDS MODULE]: Entering GetFriendsFromService for {0}", client.Name);
|
||||
// Boolean agentIsLocal = true;
|
||||
// if (UserManagementModule != null)
|
||||
// agentIsLocal = UserManagementModule.IsLocalGridUser(client.AgentId);
|
||||
public override FriendInfo[] GetFriendsFromService(IClientAPI client)
|
||||
{
|
||||
// m_log.DebugFormat("[HGFRIENDS MODULE]: Entering GetFriendsFromService for {0}", client.Name);
|
||||
Boolean agentIsLocal = true;
|
||||
if (UserManagementModule != null)
|
||||
agentIsLocal = UserManagementModule.IsLocalGridUser(client.AgentId);
|
||||
|
||||
// if (agentIsLocal)
|
||||
// return base.GetFriendsFromService(client);
|
||||
if (agentIsLocal)
|
||||
return base.GetFriendsFromService(client);
|
||||
|
||||
// FriendInfo[] finfos = new FriendInfo[0];
|
||||
// // Foreigner
|
||||
// AgentCircuitData agentClientCircuit = ((Scene)(client.Scene)).AuthenticateHandler.GetAgentCircuitData(client.CircuitCode);
|
||||
// if (agentClientCircuit != null)
|
||||
// {
|
||||
// //[XXX] string agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit);
|
||||
FriendInfo[] finfos = new FriendInfo[0];
|
||||
// Foreigner
|
||||
AgentCircuitData agentClientCircuit = ((Scene)(client.Scene)).AuthenticateHandler.GetAgentCircuitData(client.CircuitCode);
|
||||
if (agentClientCircuit != null)
|
||||
{
|
||||
// Note that this is calling a different interface than base; this one calls with a string param!
|
||||
finfos = FriendsService.GetFriends(client.AgentId.ToString());
|
||||
m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, client.AgentId.ToString());
|
||||
}
|
||||
|
||||
// finfos = FriendsService.GetFriends(client.AgentId.ToString());
|
||||
// m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, client.AgentId.ToString());
|
||||
// }
|
||||
// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting GetFriendsFromService for {0}", client.Name);
|
||||
|
||||
//// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting GetFriendsFromService for {0}", client.Name);
|
||||
|
||||
// return finfos;
|
||||
// }
|
||||
return finfos;
|
||||
}
|
||||
|
||||
protected override bool StoreRights(UUID agentID, UUID friendID, int rights)
|
||||
{
|
||||
|
||||
+18
-14
@@ -67,10 +67,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
/// </summary>
|
||||
protected bool m_merge;
|
||||
|
||||
/// <value>
|
||||
/// We only use this to request modules
|
||||
/// </value>
|
||||
protected Scene m_scene;
|
||||
protected IInventoryService m_InventoryService;
|
||||
protected IAssetService m_AssetService;
|
||||
protected IUserAccountService m_UserAccountService;
|
||||
|
||||
/// <value>
|
||||
/// The stream from which the inventory archive will be loaded.
|
||||
@@ -118,9 +117,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
protected Dictionary<UUID, UUID> m_creatorIdForAssetId = new Dictionary<UUID, UUID>();
|
||||
|
||||
public InventoryArchiveReadRequest(
|
||||
Scene scene, UserAccount userInfo, string invPath, string loadPath, bool merge)
|
||||
IInventoryService inv, IAssetService assets, IUserAccountService uacc, UserAccount userInfo, string invPath, string loadPath, bool merge)
|
||||
: this(
|
||||
scene,
|
||||
inv,
|
||||
assets,
|
||||
uacc,
|
||||
userInfo,
|
||||
invPath,
|
||||
new GZipStream(ArchiveHelpers.GetStream(loadPath), CompressionMode.Decompress),
|
||||
@@ -129,9 +130,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
}
|
||||
|
||||
public InventoryArchiveReadRequest(
|
||||
Scene scene, UserAccount userInfo, string invPath, Stream loadStream, bool merge)
|
||||
IInventoryService inv, IAssetService assets, IUserAccountService uacc, UserAccount userInfo, string invPath, Stream loadStream, bool merge)
|
||||
{
|
||||
m_scene = scene;
|
||||
m_InventoryService = inv;
|
||||
m_AssetService = assets;
|
||||
m_UserAccountService = uacc;
|
||||
m_merge = merge;
|
||||
m_userInfo = userInfo;
|
||||
m_invPath = invPath;
|
||||
@@ -162,7 +165,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
|
||||
List<InventoryFolderBase> folderCandidates
|
||||
= InventoryArchiveUtils.FindFoldersByPath(
|
||||
m_scene.InventoryService, m_userInfo.PrincipalID, m_invPath);
|
||||
m_InventoryService, m_userInfo.PrincipalID, m_invPath);
|
||||
|
||||
if (folderCandidates.Count == 0)
|
||||
{
|
||||
@@ -297,7 +300,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
string plainPath = ArchiveConstants.ExtractPlainPathFromIarPath(archivePath);
|
||||
List<InventoryFolderBase> folderCandidates
|
||||
= InventoryArchiveUtils.FindFoldersByPath(
|
||||
m_scene.InventoryService, m_userInfo.PrincipalID, plainPath);
|
||||
m_InventoryService, m_userInfo.PrincipalID, plainPath);
|
||||
|
||||
if (folderCandidates.Count != 0)
|
||||
{
|
||||
@@ -380,7 +383,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
= new InventoryFolderBase(
|
||||
newFolderId, newFolderName, m_userInfo.PrincipalID,
|
||||
(short)AssetType.Unknown, destFolder.ID, 1);
|
||||
m_scene.InventoryService.AddFolder(destFolder);
|
||||
m_InventoryService.AddFolder(destFolder);
|
||||
|
||||
// Record that we have now created this folder
|
||||
iarPathExisting += rawDirsToCreate[i] + "/";
|
||||
@@ -406,7 +409,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
// Don't use the item ID that's in the file
|
||||
item.ID = UUID.Random();
|
||||
|
||||
UUID ospResolvedId = OspResolver.ResolveOspa(item.CreatorId, m_scene.UserAccountService);
|
||||
UUID ospResolvedId = OspResolver.ResolveOspa(item.CreatorId, m_UserAccountService);
|
||||
if (UUID.Zero != ospResolvedId) // The user exists in this grid
|
||||
{
|
||||
// m_log.DebugFormat("[INVENTORY ARCHIVER]: Found creator {0} via OSPA resolution", ospResolvedId);
|
||||
@@ -436,7 +439,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
// relying on native tar tools.
|
||||
m_creatorIdForAssetId[item.AssetID] = item.CreatorIdAsUuid;
|
||||
|
||||
m_scene.AddInventoryItem(item);
|
||||
if (!m_InventoryService.AddItem(item))
|
||||
m_log.WarnFormat("[INVENTORY ARCHIVER]: Unable to save item {0} in folder {1}", item.Name, item.Folder);
|
||||
|
||||
return item;
|
||||
}
|
||||
@@ -533,7 +537,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
AssetBase asset = new AssetBase(assetId, "From IAR", assetType, UUID.Zero.ToString());
|
||||
asset.Data = data;
|
||||
|
||||
m_scene.AssetService.Store(asset);
|
||||
m_AssetService.Store(asset);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -294,7 +294,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
|
||||
try
|
||||
{
|
||||
request = new InventoryArchiveReadRequest(m_aScene, userInfo, invPath, loadStream, merge);
|
||||
request = new InventoryArchiveReadRequest(m_aScene.InventoryService, m_aScene.AssetService, m_aScene.UserAccountService, userInfo, invPath, loadStream, merge);
|
||||
}
|
||||
catch (EntryPointNotFoundException e)
|
||||
{
|
||||
@@ -342,7 +342,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
|
||||
try
|
||||
{
|
||||
request = new InventoryArchiveReadRequest(m_aScene, userInfo, invPath, loadPath, merge);
|
||||
request = new InventoryArchiveReadRequest(m_aScene.InventoryService, m_aScene.AssetService, m_aScene.UserAccountService, userInfo, invPath, loadPath, merge);
|
||||
}
|
||||
catch (EntryPointNotFoundException e)
|
||||
{
|
||||
|
||||
+6
-6
@@ -229,7 +229,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
|
||||
{
|
||||
// Test replication of path1
|
||||
new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null, false)
|
||||
new InventoryArchiveReadRequest(scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, null, (Stream)null, false)
|
||||
.ReplicateArchivePathToUserInventory(
|
||||
iarPath1, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
|
||||
foldersCreated, nodesLoaded);
|
||||
@@ -246,7 +246,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
|
||||
{
|
||||
// Test replication of path2
|
||||
new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null, false)
|
||||
new InventoryArchiveReadRequest(scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, null, (Stream)null, false)
|
||||
.ReplicateArchivePathToUserInventory(
|
||||
iarPath2, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
|
||||
foldersCreated, nodesLoaded);
|
||||
@@ -291,8 +291,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
string folder2ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2Name, UUID.Random());
|
||||
|
||||
string itemArchivePath = string.Join("", new string[] { folder1ArchiveName, folder2ArchiveName });
|
||||
|
||||
new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null, false)
|
||||
|
||||
new InventoryArchiveReadRequest(scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, null, (Stream)null, false)
|
||||
.ReplicateArchivePathToUserInventory(
|
||||
itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
|
||||
new Dictionary<string, InventoryFolderBase>(), new HashSet<InventoryNodeBase>());
|
||||
@@ -342,8 +342,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
string folder2ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2Name, UUID.Random());
|
||||
|
||||
string itemArchivePath = string.Join("", new string[] { folder1ArchiveName, folder2ArchiveName });
|
||||
|
||||
new InventoryArchiveReadRequest(scene, ua1, folder1ExistingName, (Stream)null, true)
|
||||
|
||||
new InventoryArchiveReadRequest(scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, folder1ExistingName, (Stream)null, true)
|
||||
.ReplicateArchivePathToUserInventory(
|
||||
itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
|
||||
new Dictionary<string, InventoryFolderBase>(), new HashSet<InventoryNodeBase>());
|
||||
|
||||
+1
-1
@@ -86,7 +86,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH));
|
||||
|
||||
InventoryArchiveReadRequest iarr
|
||||
= new InventoryArchiveReadRequest(null, null, null, (Stream)null, false);
|
||||
= new InventoryArchiveReadRequest(null, null, null, null, null, (Stream)null, false);
|
||||
iarr.LoadControlFile(filePath, data);
|
||||
|
||||
Assert.That(iarr.ControlFileLoaded, Is.True);
|
||||
|
||||
+163
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* 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 copyright
|
||||
* 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.Reflection;
|
||||
using System.Threading;
|
||||
using log4net;
|
||||
using Mono.Addins;
|
||||
using Nini.Config;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Framework.Monitoring;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Framework
|
||||
{
|
||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GridServiceThrottleModule")]
|
||||
public class GridServiceThrottleModule : ISharedRegionModule
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(
|
||||
MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private readonly List<Scene> m_scenes = new List<Scene>();
|
||||
|
||||
private OpenSim.Framework.BlockingQueue<GridRegionRequest> m_RequestQueue = new OpenSim.Framework.BlockingQueue<GridRegionRequest>();
|
||||
|
||||
public void Initialise(IConfigSource config)
|
||||
{
|
||||
Watchdog.StartThread(
|
||||
ProcessQueue,
|
||||
"GridServiceRequestThread",
|
||||
ThreadPriority.BelowNormal,
|
||||
true,
|
||||
false);
|
||||
}
|
||||
|
||||
public void AddRegion(Scene scene)
|
||||
{
|
||||
lock (m_scenes)
|
||||
{
|
||||
m_scenes.Add(scene);
|
||||
scene.EventManager.OnNewClient += OnNewClient;
|
||||
}
|
||||
}
|
||||
|
||||
public void RegionLoaded(Scene scene)
|
||||
{
|
||||
}
|
||||
|
||||
public void RemoveRegion(Scene scene)
|
||||
{
|
||||
lock (m_scenes)
|
||||
{
|
||||
m_scenes.Remove(scene);
|
||||
scene.EventManager.OnNewClient -= OnNewClient;
|
||||
}
|
||||
}
|
||||
|
||||
void OnNewClient(IClientAPI client)
|
||||
{
|
||||
client.OnRegionHandleRequest += OnRegionHandleRequest;
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "GridServiceThrottleModule"; }
|
||||
}
|
||||
|
||||
public Type ReplaceableInterface
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
public void OnRegionHandleRequest(IClientAPI client, UUID regionID)
|
||||
{
|
||||
//m_log.DebugFormat("[GRIDSERVICE THROTTLE]: RegionHandleRequest {0}", regionID);
|
||||
ulong handle = 0;
|
||||
if (IsLocalRegionHandle(regionID, out handle))
|
||||
{
|
||||
client.SendRegionHandle(regionID, handle);
|
||||
return;
|
||||
}
|
||||
|
||||
GridRegionRequest request = new GridRegionRequest(client, regionID);
|
||||
m_RequestQueue.Enqueue(request);
|
||||
|
||||
}
|
||||
|
||||
private bool IsLocalRegionHandle(UUID regionID, out ulong regionHandle)
|
||||
{
|
||||
regionHandle = 0;
|
||||
foreach (Scene s in m_scenes)
|
||||
if (s.RegionInfo.RegionID == regionID)
|
||||
{
|
||||
regionHandle = s.RegionInfo.RegionHandle;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void ProcessQueue()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
Watchdog.UpdateThread();
|
||||
|
||||
GridRegionRequest request = m_RequestQueue.Dequeue();
|
||||
GridRegion r = m_scenes[0].GridService.GetRegionByUUID(UUID.Zero, request.regionID);
|
||||
|
||||
if (r != null && r.RegionHandle != 0)
|
||||
request.client.SendRegionHandle(request.regionID, r.RegionHandle);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class GridRegionRequest
|
||||
{
|
||||
public IClientAPI client;
|
||||
public UUID regionID;
|
||||
|
||||
public GridRegionRequest(IClientAPI c, UUID r)
|
||||
{
|
||||
client = c;
|
||||
regionID = r;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -73,6 +73,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
|
||||
private AssetMetadata FetchMetadata(string url, UUID assetID)
|
||||
{
|
||||
if (string.IsNullOrEmpty(url))
|
||||
return null;
|
||||
|
||||
if (!url.EndsWith("/") && !url.EndsWith("="))
|
||||
url = url + "/";
|
||||
|
||||
@@ -92,6 +95,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
AssetBase asset = m_scene.AssetService.Get(assetID.ToString());
|
||||
if (asset == null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(url))
|
||||
return null;
|
||||
|
||||
if (!url.EndsWith("/") && !url.EndsWith("="))
|
||||
url = url + "/";
|
||||
|
||||
@@ -109,6 +115,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
|
||||
public bool PostAsset(string url, AssetBase asset)
|
||||
{
|
||||
if (string.IsNullOrEmpty(url))
|
||||
return false;
|
||||
|
||||
if (asset != null)
|
||||
{
|
||||
if (!url.EndsWith("/") && !url.EndsWith("="))
|
||||
|
||||
@@ -244,7 +244,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
|
||||
bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
|
||||
{
|
||||
m_log.DebugFormat("[HGScene] RezObject itemID={0} fromTaskID={1}", itemID, fromTaskID);
|
||||
m_log.DebugFormat("[HGScene]: RezObject itemID={0} fromTaskID={1}", itemID, fromTaskID);
|
||||
|
||||
//if (fromTaskID.Equals(UUID.Zero))
|
||||
//{
|
||||
@@ -297,7 +297,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
if (m_Scene.TryGetScenePresence(userID, out sp))
|
||||
{
|
||||
AgentCircuitData aCircuit = m_Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
|
||||
if (aCircuit.ServiceURLs.ContainsKey("AssetServerURI"))
|
||||
if (aCircuit != null && aCircuit.ServiceURLs != null && aCircuit.ServiceURLs.ContainsKey("AssetServerURI"))
|
||||
{
|
||||
assetServerURL = aCircuit.ServiceURLs["AssetServerURI"].ToString();
|
||||
assetServerURL = assetServerURL.Trim(new char[] { '/' });
|
||||
|
||||
@@ -176,7 +176,7 @@ namespace OpenSim.Region.CoreModules.Framework.Library
|
||||
m_log.InfoFormat("[LIBRARY MODULE]: Loading library archive {0} ({1})...", iarFileName, simpleName);
|
||||
simpleName = GetInventoryPathFromName(simpleName);
|
||||
|
||||
InventoryArchiveReadRequest archread = new InventoryArchiveReadRequest(m_MockScene, uinfo, simpleName, iarFileName, false);
|
||||
InventoryArchiveReadRequest archread = new InventoryArchiveReadRequest(m_MockScene.InventoryService, m_MockScene.AssetService, m_MockScene.UserAccountService, uinfo, simpleName, iarFileName, false);
|
||||
try
|
||||
{
|
||||
HashSet<InventoryNodeBase> nodes = archread.Execute();
|
||||
@@ -185,7 +185,7 @@ namespace OpenSim.Region.CoreModules.Framework.Library
|
||||
// didn't find the subfolder with the given name; place it on the top
|
||||
m_log.InfoFormat("[LIBRARY MODULE]: Didn't find {0} in library. Placing archive on the top level", simpleName);
|
||||
archread.Close();
|
||||
archread = new InventoryArchiveReadRequest(m_MockScene, uinfo, "/", iarFileName, false);
|
||||
archread = new InventoryArchiveReadRequest(m_MockScene.InventoryService, m_MockScene.AssetService, m_MockScene.UserAccountService, uinfo, "/", iarFileName, false);
|
||||
archread.Execute();
|
||||
}
|
||||
|
||||
|
||||
@@ -135,7 +135,6 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||
s.ForEachSOG(delegate(SceneObjectGroup sog) { CacheCreators(sog); });
|
||||
}
|
||||
|
||||
|
||||
void EventManager_OnNewClient(IClientAPI client)
|
||||
{
|
||||
client.OnConnectionClosed += new Action<IClientAPI>(HandleConnectionClosed);
|
||||
@@ -151,6 +150,10 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||
|
||||
void HandleUUIDNameRequest(UUID uuid, IClientAPI remote_client)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[USER MANAGEMENT MODULE]: Handling request for name binding of UUID {0} from {1}",
|
||||
// uuid, remote_client.Name);
|
||||
|
||||
if (m_Scenes[0].LibraryService != null && (m_Scenes[0].LibraryService.LibraryRootFolder.Owner == uuid))
|
||||
{
|
||||
remote_client.SendNameReply(uuid, "Mr", "OpenSim");
|
||||
@@ -319,8 +322,34 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||
}
|
||||
else
|
||||
{
|
||||
// Let's try the GridUser service
|
||||
GridUserInfo uInfo = m_Scenes[0].GridUserService.GetGridUserInfo(uuid.ToString());
|
||||
if (uInfo != null)
|
||||
{
|
||||
string url, first, last, tmp;
|
||||
UUID u;
|
||||
if (Util.ParseUniversalUserIdentifier(uInfo.UserID, out u, out url, out first, out last, out tmp))
|
||||
{
|
||||
AddUser(uuid, first, last, url);
|
||||
|
||||
if (m_UserCache.ContainsKey(uuid))
|
||||
{
|
||||
names[0] = m_UserCache[uuid].FirstName;
|
||||
names[1] = m_UserCache[uuid].LastName;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
m_log.DebugFormat("[USER MANAGEMENT MODULE]: Unable to parse UUI {0}", uInfo.UserID);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.DebugFormat("[USER MANAGEMENT MODULE]: No grid user found for {0}", uuid);
|
||||
}
|
||||
|
||||
names[0] = "Unknown";
|
||||
names[1] = "UserUMMTGUN3";
|
||||
names[1] = "UserUMMTGUN7";
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -474,7 +503,6 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||
//m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, creatorData {1}", id, creatorData);
|
||||
|
||||
UserData oldUser;
|
||||
//lock the whole block - prevent concurrent update
|
||||
lock (m_UserCache)
|
||||
m_UserCache.TryGetValue(id, out oldUser);
|
||||
|
||||
@@ -486,9 +514,8 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||
return;
|
||||
}
|
||||
|
||||
//try update unknown users
|
||||
//and creator's home URL's
|
||||
if ((oldUser.FirstName == "Unknown" && !creatorData.Contains("Unknown")) || (oldUser.HomeURL != null && !creatorData.StartsWith(oldUser.HomeURL)))
|
||||
//try update unknown users, but don't update anyone else
|
||||
if (oldUser.FirstName == "Unknown" && !creatorData.Contains("Unknown"))
|
||||
{
|
||||
lock (m_UserCache)
|
||||
m_UserCache.Remove(id);
|
||||
@@ -512,7 +539,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||
UserData user = new UserData();
|
||||
user.Id = id;
|
||||
|
||||
if (creatorData != null && creatorData != string.Empty)
|
||||
if (!string.IsNullOrEmpty(creatorData))
|
||||
{
|
||||
//creatorData = <endpoint>;<name>
|
||||
|
||||
@@ -536,8 +563,12 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||
}
|
||||
else
|
||||
{
|
||||
// Temporarily add unknown user entries of this type into the cache so that we can distinguish
|
||||
// this source from other recent (hopefully resolved) bugs that fail to retrieve a user name binding
|
||||
// TODO: Can be removed when GUN* unknown users have definitely dropped significantly or
|
||||
// disappeared.
|
||||
user.FirstName = "Unknown";
|
||||
user.LastName = "UserUMMAU";
|
||||
user.LastName = "UserUMMAU3";
|
||||
}
|
||||
|
||||
AddUserInternal(user);
|
||||
|
||||
+13
-12
@@ -195,19 +195,20 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
|
||||
{
|
||||
InventoryCollection invCol = m_RemoteConnector.GetFolderContent(userID, folderID);
|
||||
|
||||
if (invCol != null && UserManager != null)
|
||||
{
|
||||
// Protect ourselves against the caller subsequently modifying the items list
|
||||
List<InventoryItemBase> items = new List<InventoryItemBase>(invCol.Items);
|
||||
// Commenting this for now, because it's causing more grief than good
|
||||
//if (invCol != null && UserManager != null)
|
||||
//{
|
||||
// // Protect ourselves against the caller subsequently modifying the items list
|
||||
// List<InventoryItemBase> items = new List<InventoryItemBase>(invCol.Items);
|
||||
|
||||
if (items != null && items.Count > 0)
|
||||
Util.FireAndForget(delegate
|
||||
{
|
||||
foreach (InventoryItemBase item in items)
|
||||
if (!string.IsNullOrEmpty(item.CreatorData))
|
||||
UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData);
|
||||
});
|
||||
}
|
||||
// if (items != null && items.Count > 0)
|
||||
// //Util.FireAndForget(delegate
|
||||
// //{
|
||||
// foreach (InventoryItemBase item in items)
|
||||
// if (!string.IsNullOrEmpty(item.CreatorData))
|
||||
// UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData);
|
||||
// //});
|
||||
//}
|
||||
|
||||
return invCol;
|
||||
}
|
||||
|
||||
@@ -546,7 +546,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
|
||||
{
|
||||
ConsoleDisplayList cdl = new ConsoleDisplayList();
|
||||
cdl.AddRow("Name", so.Name);
|
||||
cdl.AddRow("Descrition", so.Description);
|
||||
cdl.AddRow("Description", so.Description);
|
||||
cdl.AddRow("Local ID", so.LocalId);
|
||||
cdl.AddRow("UUID", so.UUID);
|
||||
cdl.AddRow("Location", string.Format("{0} @ {1}", so.AbsolutePosition, so.Scene.Name));
|
||||
|
||||
@@ -46,47 +46,33 @@ using OpenSim.Region.Framework.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
public class RegionStatsHandler : IStreamedRequestHandler
|
||||
public class RegionStatsHandler : BaseStreamHandler
|
||||
{
|
||||
//private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private string osRXStatsURI = String.Empty;
|
||||
private string osXStatsURI = String.Empty;
|
||||
//private string osSecret = String.Empty;
|
||||
private OpenSim.Framework.RegionInfo regionInfo;
|
||||
public string localZone = TimeZone.CurrentTimeZone.StandardName;
|
||||
public TimeSpan utcOffset = TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now);
|
||||
|
||||
public string Name { get { return "RegionStats"; } }
|
||||
public string Description { get { return "Region Statistics"; } }
|
||||
|
||||
public RegionStatsHandler(RegionInfo region_info)
|
||||
public RegionStatsHandler(RegionInfo region_info)
|
||||
: base("GET", "/" + Util.SHA1Hash(region_info.regionSecret), "RegionStats", "Region Statistics")
|
||||
{
|
||||
regionInfo = region_info;
|
||||
osRXStatsURI = Util.SHA1Hash(regionInfo.regionSecret);
|
||||
osXStatsURI = Util.SHA1Hash(regionInfo.osSecret);
|
||||
}
|
||||
|
||||
public byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||
public override byte[] Handle(
|
||||
string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||
{
|
||||
return Util.UTF8.GetBytes(Report());
|
||||
}
|
||||
|
||||
public string ContentType
|
||||
public override string ContentType
|
||||
{
|
||||
get { return "text/plain"; }
|
||||
}
|
||||
|
||||
public string HttpMethod
|
||||
{
|
||||
get { return "GET"; }
|
||||
}
|
||||
|
||||
public string Path
|
||||
{
|
||||
// This is for the region and is the regionSecret hashed
|
||||
get { return "/" + osRXStatsURI; }
|
||||
}
|
||||
|
||||
private string Report()
|
||||
{
|
||||
|
||||
@@ -3103,7 +3103,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
//client.OnNameFromUUIDRequest += HandleUUIDNameRequest;
|
||||
client.OnMoneyTransferRequest += ProcessMoneyTransferRequest;
|
||||
client.OnRegionHandleRequest += RegionHandleRequest;
|
||||
}
|
||||
|
||||
public virtual void SubscribeToClientNetworkEvents(IClientAPI client)
|
||||
@@ -3227,7 +3226,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
//client.OnNameFromUUIDRequest -= HandleUUIDNameRequest;
|
||||
client.OnMoneyTransferRequest -= ProcessMoneyTransferRequest;
|
||||
client.OnRegionHandleRequest -= RegionHandleRequest;
|
||||
}
|
||||
|
||||
public virtual void UnSubscribeToClientNetworkEvents(IClientAPI client)
|
||||
@@ -4887,21 +4885,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
#endregion
|
||||
|
||||
public void RegionHandleRequest(IClientAPI client, UUID regionID)
|
||||
{
|
||||
ulong handle = 0;
|
||||
if (regionID == RegionInfo.RegionID)
|
||||
handle = RegionInfo.RegionHandle;
|
||||
else
|
||||
{
|
||||
GridRegion r = GridService.GetRegionByUUID(UUID.Zero, regionID);
|
||||
if (r != null)
|
||||
handle = r.RegionHandle;
|
||||
}
|
||||
|
||||
if (handle != 0)
|
||||
client.SendRegionHandle(regionID, handle);
|
||||
}
|
||||
|
||||
// Commented pending deletion since this method no longer appears to do anything at all
|
||||
// public bool NeedSceneCacheClear(UUID agentID)
|
||||
|
||||
@@ -477,29 +477,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the debug packet level on each current scene. This level governs which packets are printed out to the
|
||||
/// console.
|
||||
/// </summary>
|
||||
/// <param name="newDebug"></param>
|
||||
/// <param name="name">Name of avatar to debug</param>
|
||||
public void SetDebugPacketLevelOnCurrentScene(int newDebug, string name)
|
||||
{
|
||||
ForEachSelectedScene(scene =>
|
||||
scene.ForEachScenePresence(sp =>
|
||||
{
|
||||
if (name == null || sp.Name == name)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"Packet debug for {0} ({1}) set to {2}",
|
||||
sp.Name, sp.IsChildAgent ? "child" : "root", newDebug);
|
||||
|
||||
sp.ControllingClient.DebugPacketLevel = newDebug;
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
public List<ScenePresence> GetCurrentSceneAvatars()
|
||||
{
|
||||
List<ScenePresence> avatars = new List<ScenePresence>();
|
||||
|
||||
@@ -505,7 +505,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
CreatorID = uuid;
|
||||
}
|
||||
if (parts.Length >= 2)
|
||||
{
|
||||
CreatorData = parts[1];
|
||||
if (!CreatorData.EndsWith("/"))
|
||||
CreatorData += "/";
|
||||
}
|
||||
if (parts.Length >= 3)
|
||||
name = parts[2];
|
||||
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* 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 copyright
|
||||
* 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.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Timers;
|
||||
using Timer = System.Timers.Timer;
|
||||
using Nini.Config;
|
||||
using NUnit.Framework;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Communications;
|
||||
using OpenSim.Framework.Servers;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
using OpenSim.Region.ClientStack.Linden;
|
||||
using OpenSim.Region.CoreModules.Framework;
|
||||
using OpenSim.Region.CoreModules.Framework.EntityTransfer;
|
||||
using OpenSim.Region.CoreModules.World.Serialiser;
|
||||
using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Tests.Common;
|
||||
using OpenSim.Tests.Common.Mock;
|
||||
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
|
||||
|
||||
namespace OpenSim.Region.Framework.Scenes.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class ScenePresenceCapabilityTests : OpenSimTestCase
|
||||
{
|
||||
[Test]
|
||||
public void TestChildAgentSingleRegionCapabilities()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
TestHelpers.EnableLogging();
|
||||
|
||||
UUID spUuid = TestHelpers.ParseTail(0x1);
|
||||
|
||||
// XXX: This is not great since the use of statics will mean that this has to be manually cleaned up for
|
||||
// any subsequent test.
|
||||
// XXX: May replace with a mock IHttpServer later.
|
||||
BaseHttpServer httpServer = new BaseHttpServer(99999);
|
||||
MainServer.AddHttpServer(httpServer);
|
||||
MainServer.Instance = httpServer;
|
||||
|
||||
CapabilitiesModule capsMod = new CapabilitiesModule();
|
||||
TestScene scene = new SceneHelpers().SetupScene();
|
||||
SceneHelpers.SetupSceneModules(scene, capsMod);
|
||||
|
||||
ScenePresence sp = SceneHelpers.AddChildScenePresence(scene, spUuid);
|
||||
Assert.That(capsMod.GetCapsForUser(spUuid), Is.Not.Null);
|
||||
|
||||
// TODO: Need to add tests for other ICapabiltiesModule methods.
|
||||
|
||||
scene.IncomingCloseAgent(sp.UUID, false);
|
||||
Assert.That(capsMod.GetCapsForUser(spUuid), Is.Null);
|
||||
|
||||
// TODO: Need to add tests for other ICapabiltiesModule methods.
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -50,7 +50,8 @@ public class BSActorMoveToTarget : BSActor
|
||||
// BSActor.isActive
|
||||
public override bool isActive
|
||||
{
|
||||
get { return Enabled; }
|
||||
// MoveToTarget only works on physical prims
|
||||
get { return Enabled && m_controllingPrim.IsPhysicallyActive; }
|
||||
}
|
||||
|
||||
// Release any connections and resources used by the actor.
|
||||
@@ -102,16 +103,28 @@ public class BSActorMoveToTarget : BSActor
|
||||
// We're taking over after this.
|
||||
m_controllingPrim.ZeroMotion(true);
|
||||
|
||||
m_targetMotor = new BSVMotor("BSActorMoveToTargget.Activate",
|
||||
m_controllingPrim.MoveToTargetTau, // timeScale
|
||||
BSMotor.Infinite, // decay time scale
|
||||
1f // efficiency
|
||||
/* Someday use the PID controller
|
||||
m_targetMotor = new BSPIDVMotor("BSActorMoveToTarget-" + m_controllingPrim.LocalID.ToString());
|
||||
m_targetMotor.TimeScale = m_controllingPrim.MoveToTargetTau;
|
||||
m_targetMotor.Efficiency = 1f;
|
||||
*/
|
||||
m_targetMotor = new BSVMotor("BSActorMoveToTarget-" + m_controllingPrim.LocalID.ToString(),
|
||||
m_controllingPrim.MoveToTargetTau, // timeScale
|
||||
BSMotor.Infinite, // decay time scale
|
||||
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;
|
||||
// m_physicsScene.BeforeStep += Mover;
|
||||
m_physicsScene.BeforeStep += Mover2;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If already allocated, make sure the target and other paramters are current
|
||||
m_targetMotor.SetTarget(m_controllingPrim.MoveToTargetTarget);
|
||||
m_targetMotor.SetCurrent(m_controllingPrim.RawPosition);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,12 +132,16 @@ public class BSActorMoveToTarget : BSActor
|
||||
{
|
||||
if (m_targetMotor != null)
|
||||
{
|
||||
m_physicsScene.BeforeStep -= Mover;
|
||||
// m_physicsScene.BeforeStep -= Mover;
|
||||
m_physicsScene.BeforeStep -= Mover2;
|
||||
m_targetMotor = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Called just before the simulation step. Update the vertical position for hoverness.
|
||||
// Origional mover that set the objects position to move to the target.
|
||||
// The problem was that gravity would keep trying to push the object down so
|
||||
// the overall downward velocity would increase to infinity.
|
||||
// Called just before the simulation step.
|
||||
private void Mover(float timeStep)
|
||||
{
|
||||
// Don't do hovering while the object is selected.
|
||||
@@ -142,6 +159,7 @@ public class BSActorMoveToTarget : BSActor
|
||||
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;
|
||||
m_controllingPrim.ForceVelocity = OMV.Vector3.Zero;
|
||||
// Setting the position does not cause the physics engine to generate a property update. Force it.
|
||||
m_physicsScene.PE.PushUpdate(m_controllingPrim.PhysBody);
|
||||
}
|
||||
@@ -151,7 +169,51 @@ public class BSActorMoveToTarget : BSActor
|
||||
// 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},BSActorMoveToTarget.Mover,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);
|
||||
}
|
||||
|
||||
// Version of mover that applies forces to move the physical object to the target.
|
||||
// Also overcomes gravity so the object doesn't just drop to the ground.
|
||||
// Called just before the simulation step.
|
||||
private void Mover2(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)
|
||||
OMV.Vector3 addedForce = OMV.Vector3.Zero;
|
||||
|
||||
// CorrectionVector is the movement vector required this step
|
||||
OMV.Vector3 correctionVector = m_targetMotor.Step(timeStep, m_controllingPrim.RawPosition);
|
||||
|
||||
// If we are very close to our target, turn off the movement motor.
|
||||
if (m_targetMotor.ErrorIsZero())
|
||||
{
|
||||
m_physicsScene.DetailLog("{0},BSActorMoveToTarget.Mover3,zeroMovement,pos={1},mass={2}",
|
||||
m_controllingPrim.LocalID, m_controllingPrim.RawPosition, m_controllingPrim.Mass);
|
||||
m_controllingPrim.ForcePosition = m_targetMotor.TargetValue;
|
||||
m_controllingPrim.ForceVelocity = OMV.Vector3.Zero;
|
||||
// Setting the position does not cause the physics engine to generate a property update. Force it.
|
||||
m_physicsScene.PE.PushUpdate(m_controllingPrim.PhysBody);
|
||||
}
|
||||
else
|
||||
{
|
||||
// First force to move us there -- the motor return a timestep scaled value.
|
||||
addedForce = correctionVector / timeStep;
|
||||
// Remove the existing velocity (only the moveToTarget force counts)
|
||||
addedForce -= m_controllingPrim.RawVelocity;
|
||||
// Overcome gravity.
|
||||
addedForce -= m_controllingPrim.Gravity;
|
||||
|
||||
// Add enough force to overcome the mass of the object
|
||||
addedForce *= m_controllingPrim.Mass;
|
||||
|
||||
m_controllingPrim.AddForce(addedForce, false /* pushForce */, true /* inTaintTime */);
|
||||
}
|
||||
m_physicsScene.DetailLog("{0},BSActorMoveToTarget.Mover3,move,fromPos={1},addedForce={2}",
|
||||
m_controllingPrim.LocalID, origPosition, addedForce);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,12 +43,10 @@ public sealed class BSCharacter : BSPhysObject
|
||||
private OMV.Vector3 _size;
|
||||
private bool _grabbed;
|
||||
private bool _selected;
|
||||
private OMV.Vector3 _position;
|
||||
private float _mass;
|
||||
private float _avatarVolume;
|
||||
private float _collisionScore;
|
||||
private OMV.Vector3 _acceleration;
|
||||
private OMV.Quaternion _orientation;
|
||||
private int _physicsActorType;
|
||||
private bool _isPhysical;
|
||||
private bool _flying;
|
||||
@@ -70,10 +68,10 @@ public sealed class BSCharacter : BSPhysObject
|
||||
: base(parent_scene, localID, avName, "BSCharacter")
|
||||
{
|
||||
_physicsActorType = (int)ActorTypes.Agent;
|
||||
_position = pos;
|
||||
RawPosition = pos;
|
||||
|
||||
_flying = isFlying;
|
||||
_orientation = OMV.Quaternion.Identity;
|
||||
RawOrientation = OMV.Quaternion.Identity;
|
||||
RawVelocity = OMV.Vector3.Zero;
|
||||
_buoyancy = ComputeBuoyancyFromFlying(isFlying);
|
||||
Friction = BSParam.AvatarStandingFriction;
|
||||
@@ -133,7 +131,7 @@ public sealed class BSCharacter : BSPhysObject
|
||||
PhysScene.PE.RemoveObjectFromWorld(PhysScene.World, PhysBody);
|
||||
|
||||
ZeroMotion(true);
|
||||
ForcePosition = _position;
|
||||
ForcePosition = RawPosition;
|
||||
|
||||
// Set the velocity
|
||||
if (m_moveActor != null)
|
||||
@@ -272,38 +270,33 @@ public sealed class BSCharacter : BSPhysObject
|
||||
|
||||
public override void LockAngularMotion(OMV.Vector3 axis) { return; }
|
||||
|
||||
public override OMV.Vector3 RawPosition
|
||||
{
|
||||
get { return _position; }
|
||||
set { _position = value; }
|
||||
}
|
||||
public override OMV.Vector3 Position {
|
||||
get {
|
||||
// Don't refetch the position because this function is called a zillion times
|
||||
// _position = PhysicsScene.PE.GetObjectPosition(Scene.World, LocalID);
|
||||
return _position;
|
||||
// RawPosition = PhysicsScene.PE.GetObjectPosition(Scene.World, LocalID);
|
||||
return RawPosition;
|
||||
}
|
||||
set {
|
||||
_position = value;
|
||||
RawPosition = value;
|
||||
|
||||
PhysScene.TaintedObject("BSCharacter.setPosition", delegate()
|
||||
{
|
||||
DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
|
||||
DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, RawPosition, RawOrientation);
|
||||
PositionSanityCheck();
|
||||
ForcePosition = _position;
|
||||
ForcePosition = RawPosition;
|
||||
});
|
||||
}
|
||||
}
|
||||
public override OMV.Vector3 ForcePosition {
|
||||
get {
|
||||
_position = PhysScene.PE.GetPosition(PhysBody);
|
||||
return _position;
|
||||
RawPosition = PhysScene.PE.GetPosition(PhysBody);
|
||||
return RawPosition;
|
||||
}
|
||||
set {
|
||||
_position = value;
|
||||
RawPosition = value;
|
||||
if (PhysBody.HasPhysicalBody)
|
||||
{
|
||||
PhysScene.PE.SetTranslation(PhysBody, _position, _orientation);
|
||||
PhysScene.PE.SetTranslation(PhysBody, RawPosition, RawOrientation);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -331,16 +324,16 @@ public sealed class BSCharacter : BSPhysObject
|
||||
float terrainHeight = PhysScene.TerrainManager.GetTerrainHeightAtXYZ(RawPosition);
|
||||
if (Position.Z < terrainHeight)
|
||||
{
|
||||
DetailLog("{0},BSCharacter.PositionSanityCheck,adjustForUnderGround,pos={1},terrain={2}", LocalID, _position, terrainHeight);
|
||||
_position.Z = terrainHeight + BSParam.AvatarBelowGroundUpCorrectionMeters;
|
||||
DetailLog("{0},BSCharacter.PositionSanityCheck,adjustForUnderGround,pos={1},terrain={2}", LocalID, RawPosition, terrainHeight);
|
||||
RawPosition = new OMV.Vector3(RawPosition.X, RawPosition.Y, terrainHeight + BSParam.AvatarBelowGroundUpCorrectionMeters);
|
||||
ret = true;
|
||||
}
|
||||
if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0)
|
||||
{
|
||||
float waterHeight = PhysScene.TerrainManager.GetWaterLevelAtXYZ(_position);
|
||||
float waterHeight = PhysScene.TerrainManager.GetWaterLevelAtXYZ(RawPosition);
|
||||
if (Position.Z < waterHeight)
|
||||
{
|
||||
_position.Z = waterHeight;
|
||||
RawPosition = new OMV.Vector3(RawPosition.X, RawPosition.Y, waterHeight);
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
@@ -360,8 +353,8 @@ public sealed class BSCharacter : BSPhysObject
|
||||
// just assign to "Position" because of potential call loops.
|
||||
PhysScene.TaintedObject(inTaintTime, "BSCharacter.PositionSanityCheck", delegate()
|
||||
{
|
||||
DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation);
|
||||
ForcePosition = _position;
|
||||
DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, RawPosition, RawOrientation);
|
||||
ForcePosition = RawPosition;
|
||||
});
|
||||
ret = true;
|
||||
}
|
||||
@@ -466,19 +459,14 @@ public sealed class BSCharacter : BSPhysObject
|
||||
get { return _acceleration; }
|
||||
set { _acceleration = value; }
|
||||
}
|
||||
public override OMV.Quaternion RawOrientation
|
||||
{
|
||||
get { return _orientation; }
|
||||
set { _orientation = value; }
|
||||
}
|
||||
public override OMV.Quaternion Orientation {
|
||||
get { return _orientation; }
|
||||
get { return RawOrientation; }
|
||||
set {
|
||||
// Orientation is set zillions of times when an avatar is walking. It's like
|
||||
// the viewer doesn't trust us.
|
||||
if (_orientation != value)
|
||||
if (RawOrientation != value)
|
||||
{
|
||||
_orientation = value;
|
||||
RawOrientation = value;
|
||||
PhysScene.TaintedObject("BSCharacter.setOrientation", delegate()
|
||||
{
|
||||
// Bullet assumes we know what we are doing when forcing orientation
|
||||
@@ -486,10 +474,10 @@ public sealed class BSCharacter : BSPhysObject
|
||||
// This forces rotation to be only around the Z axis and doesn't change any of the other axis.
|
||||
// This keeps us from flipping the capsule over which the veiwer does not understand.
|
||||
float oRoll, oPitch, oYaw;
|
||||
_orientation.GetEulerAngles(out oRoll, out oPitch, out oYaw);
|
||||
RawOrientation.GetEulerAngles(out oRoll, out oPitch, out oYaw);
|
||||
OMV.Quaternion trimmedOrientation = OMV.Quaternion.CreateFromEulers(0f, 0f, oYaw);
|
||||
// DetailLog("{0},BSCharacter.setOrientation,taint,val={1},valDir={2},conv={3},convDir={4}",
|
||||
// LocalID, _orientation, OMV.Vector3.UnitX * _orientation,
|
||||
// LocalID, RawOrientation, OMV.Vector3.UnitX * RawOrientation,
|
||||
// trimmedOrientation, OMV.Vector3.UnitX * trimmedOrientation);
|
||||
ForceOrientation = trimmedOrientation;
|
||||
});
|
||||
@@ -501,16 +489,16 @@ public sealed class BSCharacter : BSPhysObject
|
||||
{
|
||||
get
|
||||
{
|
||||
_orientation = PhysScene.PE.GetOrientation(PhysBody);
|
||||
return _orientation;
|
||||
RawOrientation = PhysScene.PE.GetOrientation(PhysBody);
|
||||
return RawOrientation;
|
||||
}
|
||||
set
|
||||
{
|
||||
_orientation = value;
|
||||
RawOrientation = value;
|
||||
if (PhysBody.HasPhysicalBody)
|
||||
{
|
||||
// _position = PhysicsScene.PE.GetPosition(BSBody);
|
||||
PhysScene.PE.SetTranslation(PhysBody, _position, _orientation);
|
||||
// RawPosition = PhysicsScene.PE.GetPosition(BSBody);
|
||||
PhysScene.PE.SetTranslation(PhysBody, RawPosition, RawOrientation);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -626,7 +614,7 @@ public sealed class BSCharacter : BSPhysObject
|
||||
OMV.Vector3 addForce = force / PhysScene.LastTimeStep;
|
||||
AddForce(addForce, pushforce, false);
|
||||
}
|
||||
private void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) {
|
||||
public override void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) {
|
||||
if (force.IsFinite())
|
||||
{
|
||||
OMV.Vector3 addForce = Util.ClampV(force, BSParam.MaxAddForceMagnitude);
|
||||
@@ -723,9 +711,9 @@ public sealed class BSCharacter : BSPhysObject
|
||||
{
|
||||
// Don't change position if standing on a stationary object.
|
||||
if (!IsStationary)
|
||||
_position = entprop.Position;
|
||||
RawPosition = entprop.Position;
|
||||
|
||||
_orientation = entprop.Rotation;
|
||||
RawOrientation = entprop.Rotation;
|
||||
|
||||
// Smooth velocity. OpenSimulator is VERY sensitive to changes in velocity of the avatar
|
||||
// and will send agent updates to the clients if velocity changes by more than
|
||||
@@ -740,8 +728,8 @@ public sealed class BSCharacter : BSPhysObject
|
||||
// Do some sanity checking for the avatar. Make sure it's above ground and inbounds.
|
||||
if (PositionSanityCheck(true))
|
||||
{
|
||||
DetailLog("{0},BSCharacter.UpdateProperties,updatePosForSanity,pos={1}", LocalID, _position);
|
||||
entprop.Position = _position;
|
||||
DetailLog("{0},BSCharacter.UpdateProperties,updatePosForSanity,pos={1}", LocalID, RawPosition);
|
||||
entprop.Position = RawPosition;
|
||||
}
|
||||
|
||||
// remember the current and last set values
|
||||
@@ -755,7 +743,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, RawVelocity, _acceleration, _rotationalVelocity);
|
||||
LocalID, RawPosition, RawOrientation, RawVelocity, _acceleration, _rotationalVelocity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
public void SetupVehicleDebugging()
|
||||
{
|
||||
enableAngularVerticalAttraction = true;
|
||||
enableAngularDeflection = false;
|
||||
enableAngularDeflection = true;
|
||||
enableAngularBanking = true;
|
||||
if (BSParam.VehicleDebuggingEnable)
|
||||
{
|
||||
@@ -173,7 +173,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
switch (pParam)
|
||||
{
|
||||
case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY:
|
||||
m_angularDeflectionEfficiency = Math.Max(pValue, 0.01f);
|
||||
m_angularDeflectionEfficiency = ClampInRange(0f, pValue, 1f);
|
||||
break;
|
||||
case Vehicle.ANGULAR_DEFLECTION_TIMESCALE:
|
||||
m_angularDeflectionTimescale = Math.Max(pValue, 0.01f);
|
||||
@@ -774,7 +774,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
|
||||
// Since the computation of terrain height can be a little involved, this routine
|
||||
// is used to fetch the height only once for each vehicle simulation step.
|
||||
Vector3 lastRememberedHeightPos;
|
||||
Vector3 lastRememberedHeightPos = new Vector3(-1, -1, -1);
|
||||
private float GetTerrainHeight(Vector3 pos)
|
||||
{
|
||||
if ((m_knownHas & m_knownChangedTerrainHeight) == 0 || pos != lastRememberedHeightPos)
|
||||
@@ -788,14 +788,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
|
||||
// Since the computation of water level can be a little involved, this routine
|
||||
// is used ot fetch the level only once for each vehicle simulation step.
|
||||
Vector3 lastRememberedWaterHeightPos = new Vector3(-1, -1, -1);
|
||||
private float GetWaterLevel(Vector3 pos)
|
||||
{
|
||||
if ((m_knownHas & m_knownChangedWaterLevel) == 0)
|
||||
if ((m_knownHas & m_knownChangedWaterLevel) == 0 || pos != lastRememberedWaterHeightPos)
|
||||
{
|
||||
lastRememberedWaterHeightPos = pos;
|
||||
m_knownWaterLevel = ControllingPrim.PhysScene.TerrainManager.GetWaterLevelAtXYZ(pos);
|
||||
m_knownHas |= m_knownChangedWaterLevel;
|
||||
}
|
||||
return (float)m_knownWaterLevel;
|
||||
return m_knownWaterLevel;
|
||||
}
|
||||
|
||||
private Vector3 VehiclePosition
|
||||
@@ -991,11 +993,17 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
{
|
||||
Vector3 vel = VehicleVelocity;
|
||||
if ((m_flags & (VehicleFlag.NO_X)) != 0)
|
||||
{
|
||||
vel.X = 0;
|
||||
}
|
||||
if ((m_flags & (VehicleFlag.NO_Y)) != 0)
|
||||
{
|
||||
vel.Y = 0;
|
||||
}
|
||||
if ((m_flags & (VehicleFlag.NO_Z)) != 0)
|
||||
{
|
||||
vel.Z = 0;
|
||||
}
|
||||
VehicleVelocity = vel;
|
||||
}
|
||||
|
||||
@@ -1276,7 +1284,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
|
||||
VehicleAddForce(appliedGravity);
|
||||
|
||||
VDetailLog("{0}, MoveLinear,applyGravity,vehGrav={1},collid={2},fudge={3},mass={4},appliedForce={3}",
|
||||
VDetailLog("{0}, MoveLinear,applyGravity,vehGrav={1},collid={2},fudge={3},mass={4},appliedForce={5}",
|
||||
ControllingPrim.LocalID, m_VehicleGravity,
|
||||
ControllingPrim.IsColliding, BSParam.VehicleGroundGravityFudge, m_vehicleMass, appliedGravity);
|
||||
}
|
||||
@@ -1504,11 +1512,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
// in that direction.
|
||||
// TODO: implement reference frame.
|
||||
public void ComputeAngularDeflection()
|
||||
{
|
||||
// Since angularMotorUp and angularDeflection are computed independently, they will calculate
|
||||
// approximately the same X or Y correction. When added together (when contributions are combined)
|
||||
// this creates an over-correction and then wabbling as the target is overshot.
|
||||
// TODO: rethink how the different correction computations inter-relate.
|
||||
{
|
||||
|
||||
if (enableAngularDeflection && m_angularDeflectionEfficiency != 0 && VehicleForwardSpeed > 0.2)
|
||||
{
|
||||
@@ -1523,10 +1527,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
|
||||
// The direction the vehicle is pointing
|
||||
Vector3 pointingDirection = Vector3.UnitX * VehicleOrientation;
|
||||
pointingDirection.Normalize();
|
||||
//Predict where the Vehicle will be pointing after AngularVelocity change is applied. This will keep
|
||||
// from overshooting and allow this correction to merge with the Vertical Attraction peacefully.
|
||||
Vector3 predictedPointingDirection = pointingDirection * Quaternion.CreateFromAxisAngle(VehicleRotationalVelocity, 0f);
|
||||
predictedPointingDirection.Normalize();
|
||||
|
||||
// The difference between what is and what should be.
|
||||
Vector3 deflectionError = movingDirection - pointingDirection;
|
||||
// Vector3 deflectionError = movingDirection - predictedPointingDirection;
|
||||
Vector3 deflectionError = Vector3.Cross(movingDirection, predictedPointingDirection);
|
||||
|
||||
// Don't try to correct very large errors (not our job)
|
||||
// if (Math.Abs(deflectionError.X) > PIOverFour) deflectionError.X = PIOverTwo * Math.Sign(deflectionError.X);
|
||||
@@ -1539,15 +1547,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
// ret = m_angularDeflectionCorrectionMotor(1f, deflectionError);
|
||||
|
||||
// Scale the correction by recovery timescale and efficiency
|
||||
deflectContributionV = (-deflectionError) * m_angularDeflectionEfficiency;
|
||||
deflectContributionV /= m_angularDeflectionTimescale;
|
||||
|
||||
VehicleRotationalVelocity += deflectContributionV * VehicleOrientation;
|
||||
// Not modeling a spring so clamp the scale to no more then the arc
|
||||
deflectContributionV = (-deflectionError) * ClampInRange(0, m_angularDeflectionEfficiency/m_angularDeflectionTimescale,1f);
|
||||
//deflectContributionV /= m_angularDeflectionTimescale;
|
||||
|
||||
// VehicleRotationalVelocity += deflectContributionV * VehicleOrientation;
|
||||
VehicleRotationalVelocity += deflectContributionV;
|
||||
VDetailLog("{0}, MoveAngular,Deflection,movingDir={1},pointingDir={2},deflectError={3},ret={4}",
|
||||
ControllingPrim.LocalID, movingDirection, pointingDirection, deflectionError, deflectContributionV);
|
||||
VDetailLog("{0}, MoveAngular,Deflection,fwdSpd={1},defEff={2},defTS={3}",
|
||||
ControllingPrim.LocalID, VehicleForwardSpeed, m_angularDeflectionEfficiency, m_angularDeflectionTimescale);
|
||||
VDetailLog("{0}, MoveAngular,Deflection,fwdSpd={1},defEff={2},defTS={3},PredictedPointingDir={4}",
|
||||
ControllingPrim.LocalID, VehicleForwardSpeed, m_angularDeflectionEfficiency, m_angularDeflectionTimescale, predictedPointingDirection);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,14 +33,6 @@ using OMV = OpenMetaverse;
|
||||
namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
{
|
||||
|
||||
// A BSPrim can get individual information about its linkedness attached
|
||||
// to it through an instance of a subclass of LinksetInfo.
|
||||
// Each type of linkset will define the information needed for its type.
|
||||
public abstract class BSLinksetInfo
|
||||
{
|
||||
public virtual void Clear() { }
|
||||
}
|
||||
|
||||
public abstract class BSLinkset
|
||||
{
|
||||
// private static string LogHeader = "[BULLETSIM LINKSET]";
|
||||
@@ -56,15 +48,15 @@ public abstract class BSLinkset
|
||||
{
|
||||
BSLinkset ret = null;
|
||||
|
||||
switch ((int)BSParam.LinksetImplementation)
|
||||
switch (parent.LinksetType)
|
||||
{
|
||||
case (int)LinksetImplementation.Constraint:
|
||||
case LinksetImplementation.Constraint:
|
||||
ret = new BSLinksetConstraints(physScene, parent);
|
||||
break;
|
||||
case (int)LinksetImplementation.Compound:
|
||||
case LinksetImplementation.Compound:
|
||||
ret = new BSLinksetCompound(physScene, parent);
|
||||
break;
|
||||
case (int)LinksetImplementation.Manual:
|
||||
case LinksetImplementation.Manual:
|
||||
// ret = new BSLinksetManual(physScene, parent);
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -35,62 +35,6 @@ using OMV = OpenMetaverse;
|
||||
namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
{
|
||||
|
||||
/*
|
||||
// When a child is linked, the relationship position of the child to the parent
|
||||
// is remembered so the child's world position can be recomputed when it is
|
||||
// removed from the linkset.
|
||||
sealed class BSLinksetCompoundInfo : BSLinksetInfo
|
||||
{
|
||||
public int Index;
|
||||
public OMV.Vector3 OffsetFromRoot;
|
||||
public OMV.Vector3 OffsetFromCenterOfMass;
|
||||
public OMV.Quaternion OffsetRot;
|
||||
public BSLinksetCompoundInfo(int indx, OMV.Vector3 p, OMV.Quaternion r)
|
||||
{
|
||||
Index = indx;
|
||||
OffsetFromRoot = p;
|
||||
OffsetFromCenterOfMass = p;
|
||||
OffsetRot = r;
|
||||
}
|
||||
// 'centerDisplacement' is the distance from the root the the center-of-mass (Bullet 'zero' of the shape)
|
||||
public BSLinksetCompoundInfo(int indx, BSPrimLinkable root, BSPrimLinkable child, OMV.Vector3 centerDisplacement)
|
||||
{
|
||||
// Each child position and rotation is given relative to the center-of-mass.
|
||||
OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(root.RawOrientation);
|
||||
OMV.Vector3 displacementFromRoot = (child.RawPosition - root.RawPosition) * invRootOrientation;
|
||||
OMV.Vector3 displacementFromCOM = displacementFromRoot - centerDisplacement;
|
||||
OMV.Quaternion displacementRot = child.RawOrientation * invRootOrientation;
|
||||
|
||||
// Save relative position for recomputing child's world position after moving linkset.
|
||||
Index = indx;
|
||||
OffsetFromRoot = displacementFromRoot;
|
||||
OffsetFromCenterOfMass = displacementFromCOM;
|
||||
OffsetRot = displacementRot;
|
||||
}
|
||||
public override void Clear()
|
||||
{
|
||||
Index = 0;
|
||||
OffsetFromRoot = OMV.Vector3.Zero;
|
||||
OffsetFromCenterOfMass = OMV.Vector3.Zero;
|
||||
OffsetRot = OMV.Quaternion.Identity;
|
||||
}
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder buff = new StringBuilder();
|
||||
buff.Append("<i=");
|
||||
buff.Append(Index.ToString());
|
||||
buff.Append(",p=");
|
||||
buff.Append(OffsetFromRoot.ToString());
|
||||
buff.Append(",m=");
|
||||
buff.Append(OffsetFromCenterOfMass.ToString());
|
||||
buff.Append(",r=");
|
||||
buff.Append(OffsetRot.ToString());
|
||||
buff.Append(">");
|
||||
return buff.ToString();
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
public sealed class BSLinksetCompound : BSLinkset
|
||||
{
|
||||
private static string LogHeader = "[BULLETSIM LINKSET COMPOUND]";
|
||||
@@ -151,7 +95,9 @@ public sealed class BSLinksetCompound : BSLinkset
|
||||
public override bool MakeStatic(BSPrimLinkable child)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
DetailLog("{0},BSLinksetCompound.MakeStatic,call,IsRoot={1}", child.LocalID, IsRoot(child));
|
||||
child.ClearDisplacement();
|
||||
if (IsRoot(child))
|
||||
{
|
||||
// Schedule a rebuild to verify that the root shape is set to the real shape.
|
||||
@@ -238,7 +184,6 @@ public sealed class BSLinksetCompound : BSLinkset
|
||||
// there will already be a rebuild scheduled.
|
||||
DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild.schedulingRebuild,whichUpdated={1}",
|
||||
updated.LocalID, whichUpdated);
|
||||
updated.LinksetInfo = null; // setting to 'null' causes relative position to be recomputed.
|
||||
ScheduleRebuild(updated);
|
||||
}
|
||||
}
|
||||
@@ -294,7 +239,6 @@ public sealed class BSLinksetCompound : BSLinkset
|
||||
child.LocalID, child.PhysBody.AddrString);
|
||||
|
||||
// Cause the child's body to be rebuilt and thus restored to normal operation
|
||||
child.LinksetInfo = null;
|
||||
child.ForceBodyShapeRebuild(false);
|
||||
|
||||
if (!HasAnyChildren)
|
||||
@@ -317,7 +261,6 @@ public sealed class BSLinksetCompound : BSLinkset
|
||||
// Note that this works for rebuilding just the root after a linkset is taken apart.
|
||||
// Called at taint time!!
|
||||
private bool UseBulletSimRootOffsetHack = false; // Attempt to have Bullet track the coords of root compound shape
|
||||
private bool disableCOM = true; // For basic linkset debugging, turn off the center-of-mass setting
|
||||
private void RecomputeLinksetCompound()
|
||||
{
|
||||
try
|
||||
@@ -328,55 +271,70 @@ public sealed class BSLinksetCompound : BSLinkset
|
||||
// to what they should be as if the root was not in a linkset.
|
||||
// Not that bad since we only get into this routine if there are children in the linkset and
|
||||
// something has been updated/changed.
|
||||
// Have to do the rebuild before checking for physical because this might be a linkset
|
||||
// being destructed and going non-physical.
|
||||
LinksetRoot.ForceBodyShapeRebuild(true);
|
||||
|
||||
// There is no reason to build all this physical stuff for a non-physical linkset.
|
||||
if (!LinksetRoot.IsPhysicallyActive)
|
||||
{
|
||||
// Clean up any old linkset shape and make sure the root shape is set to the root object.
|
||||
DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,notPhysical", LinksetRoot.LocalID);
|
||||
|
||||
return; // Note the 'finally' clause at the botton which will get executed.
|
||||
}
|
||||
|
||||
// Get a new compound shape to build the linkset shape in.
|
||||
BSShape linksetShape = BSShapeCompound.GetReference(m_physicsScene);
|
||||
|
||||
// The center of mass for the linkset is the geometric center of the group.
|
||||
// Compute a displacement for each component so it is relative to the center-of-mass.
|
||||
// Bullet presumes an object's origin (relative <0,0,0>) is its center-of-mass
|
||||
OMV.Vector3 centerOfMassW = ComputeLinksetCenterOfMass();
|
||||
|
||||
OMV.Quaternion invRootOrientation = OMV.Quaternion.Normalize(OMV.Quaternion.Inverse(LinksetRoot.RawOrientation));
|
||||
OMV.Vector3 origRootPosition = LinksetRoot.RawPosition;
|
||||
|
||||
// 'centerDisplacement' is the value to subtract from children to give physical offset position
|
||||
// 'centerDisplacementV' is the vehicle relative distance from the simulator root position to the center-of-mass
|
||||
OMV.Vector3 centerDisplacementV = (centerOfMassW - LinksetRoot.RawPosition) * invRootOrientation;
|
||||
if (UseBulletSimRootOffsetHack || disableCOM)
|
||||
if (UseBulletSimRootOffsetHack || !BSParam.LinksetOffsetCenterOfMass)
|
||||
{
|
||||
// Zero everything if center-of-mass displacement is not being done.
|
||||
centerDisplacementV = OMV.Vector3.Zero;
|
||||
LinksetRoot.ClearDisplacement();
|
||||
}
|
||||
else
|
||||
{
|
||||
LinksetRoot.SetEffectiveCenterOfMassDisplacement(centerDisplacementV);
|
||||
// The actual center-of-mass could have been set by the user.
|
||||
centerDisplacementV = LinksetRoot.SetEffectiveCenterOfMassDisplacement(centerDisplacementV);
|
||||
}
|
||||
|
||||
DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,COM,rootPos={1},com={2},comDisp={3}",
|
||||
LinksetRoot.LocalID, LinksetRoot.RawPosition, centerOfMassW, centerDisplacementV);
|
||||
LinksetRoot.LocalID, origRootPosition, centerOfMassW, centerDisplacementV);
|
||||
|
||||
// Add the shapes of all the components of the linkset
|
||||
int memberIndex = 1;
|
||||
ForEachMember(delegate(BSPrimLinkable cPrim)
|
||||
{
|
||||
// Root shape is always index zero.
|
||||
cPrim.LinksetChildIndex = IsRoot(cPrim) ? 0 : memberIndex;
|
||||
if (IsRoot(cPrim))
|
||||
{
|
||||
// Root shape is always index zero.
|
||||
cPrim.LinksetChildIndex = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
cPrim.LinksetChildIndex = memberIndex;
|
||||
memberIndex++;
|
||||
}
|
||||
|
||||
// Get a reference to the shape of the child and add that shape to the linkset compound shape
|
||||
// Get a reference to the shape of the child for adding of that shape to the linkset compound shape
|
||||
BSShape childShape = cPrim.PhysShape.GetReference(m_physicsScene, cPrim);
|
||||
OMV.Vector3 offsetPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation - centerDisplacementV;
|
||||
|
||||
// Offset the child shape from the center-of-mass and rotate it to vehicle relative.
|
||||
OMV.Vector3 offsetPos = (cPrim.RawPosition - origRootPosition) * invRootOrientation - centerDisplacementV;
|
||||
OMV.Quaternion offsetRot = OMV.Quaternion.Normalize(cPrim.RawOrientation) * invRootOrientation;
|
||||
|
||||
// Add the child shape to the compound shape being built
|
||||
m_physicsScene.PE.AddChildShapeToCompoundShape(linksetShape.physShapeInfo, childShape.physShapeInfo, offsetPos, offsetRot);
|
||||
DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addChild,indx={1},cShape={2},offPos={3},offRot={4}",
|
||||
LinksetRoot.LocalID, memberIndex, childShape, offsetPos, offsetRot);
|
||||
LinksetRoot.LocalID, cPrim.LinksetChildIndex, childShape, offsetPos, offsetRot);
|
||||
|
||||
// Since we are borrowing the shape of the child, disable the origional child body
|
||||
if (!IsRoot(cPrim))
|
||||
@@ -388,8 +346,6 @@ public sealed class BSLinksetCompound : BSLinkset
|
||||
cPrim.PhysBody.collisionType = CollisionType.LinksetChild;
|
||||
}
|
||||
|
||||
memberIndex++;
|
||||
|
||||
return false; // 'false' says to move onto the next child in the list
|
||||
});
|
||||
|
||||
@@ -411,8 +367,9 @@ public sealed class BSLinksetCompound : BSLinkset
|
||||
{
|
||||
// Enable the physical position updator to return the position and rotation of the root shape.
|
||||
// This enables a feature in the C++ code to return the world coordinates of the first shape in the
|
||||
// compound shape. This eleviates the need to offset the returned physical position by the
|
||||
// compound shape. This aleviates the need to offset the returned physical position by the
|
||||
// center-of-mass offset.
|
||||
// TODO: either debug this feature or remove it.
|
||||
m_physicsScene.PE.AddToCollisionFlags(LinksetRoot.PhysBody, CollisionFlags.BS_RETURN_ROOT_COMPOUND_SHAPE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,7 +144,6 @@ public class BSVMotor : BSMotor
|
||||
|
||||
Vector3 correction = Vector3.Zero;
|
||||
Vector3 error = TargetValue - CurrentValue;
|
||||
LastError = error;
|
||||
if (!ErrorIsZero(error))
|
||||
{
|
||||
correction = StepError(timeStep, error);
|
||||
@@ -179,6 +178,7 @@ public class BSVMotor : BSMotor
|
||||
MDetailLog("{0}, BSVMotor.Step,zero,{1},origTgt={2},origCurr={3},currTgt={4},currCurr={5}",
|
||||
BSScene.DetailLogZero, UseName, origCurrVal, origTarget, TargetValue, CurrentValue);
|
||||
}
|
||||
LastError = error;
|
||||
|
||||
return correction;
|
||||
}
|
||||
@@ -188,6 +188,8 @@ public class BSVMotor : BSMotor
|
||||
CurrentValue = current;
|
||||
return Step(timeStep);
|
||||
}
|
||||
// Given and error, computer a correction for this step.
|
||||
// Simple scaling of the error by the timestep.
|
||||
public virtual Vector3 StepError(float timeStep, Vector3 error)
|
||||
{
|
||||
if (!Enabled) return Vector3.Zero;
|
||||
@@ -221,7 +223,7 @@ public class BSVMotor : BSMotor
|
||||
CurrentValue, TargetValue);
|
||||
|
||||
LastError = BSMotor.InfiniteVector;
|
||||
while (maxOutput-- > 0 && !LastError.ApproxEquals(Vector3.Zero, ErrorZeroThreshold))
|
||||
while (maxOutput-- > 0 && !ErrorIsZero())
|
||||
{
|
||||
Vector3 lastStep = Step(timeStep);
|
||||
MDetailLog("{0},BSVMotor.Test,{1},cur={2},tgt={3},lastError={4},lastStep={5}",
|
||||
@@ -293,7 +295,6 @@ public class BSFMotor : BSMotor
|
||||
|
||||
float correction = 0f;
|
||||
float error = TargetValue - CurrentValue;
|
||||
LastError = error;
|
||||
if (!ErrorIsZero(error))
|
||||
{
|
||||
correction = StepError(timeStep, error);
|
||||
@@ -328,6 +329,7 @@ public class BSFMotor : BSMotor
|
||||
MDetailLog("{0}, BSFMotor.Step,zero,{1},origTgt={2},origCurr={3},ret={4}",
|
||||
BSScene.DetailLogZero, UseName, origCurrVal, origTarget, CurrentValue);
|
||||
}
|
||||
LastError = error;
|
||||
|
||||
return CurrentValue;
|
||||
}
|
||||
@@ -363,7 +365,7 @@ public class BSFMotor : BSMotor
|
||||
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// Proportional, Integral, Derivitive Motor
|
||||
// Proportional, Integral, Derivitive ("PID") Motor
|
||||
// Good description at http://www.answers.com/topic/pid-controller . Includes processes for choosing p, i and d factors.
|
||||
public class BSPIDVMotor : BSVMotor
|
||||
{
|
||||
@@ -375,7 +377,6 @@ public class BSPIDVMotor : BSVMotor
|
||||
// The factors are vectors for the three dimensions. This is the proportional of each
|
||||
// that is applied. This could be multiplied through the actual factors but it
|
||||
// is sometimes easier to manipulate the factors and their mix separately.
|
||||
// to
|
||||
public Vector3 FactorMix;
|
||||
|
||||
// Arbritrary factor range.
|
||||
@@ -413,14 +414,14 @@ public class BSPIDVMotor : BSVMotor
|
||||
// If efficiency is high (1f), use a factor value that moves the error value to zero with little overshoot.
|
||||
// If efficiency is low (0f), use a factor value that overcorrects.
|
||||
// TODO: might want to vary contribution of different factor depending on efficiency.
|
||||
float factor = ((1f - this.Efficiency) * EfficiencyHigh + EfficiencyLow) / 3f;
|
||||
// float factor = (1f - this.Efficiency) * EfficiencyHigh + EfficiencyLow;
|
||||
// float factor = ((1f - this.Efficiency) * EfficiencyHigh + EfficiencyLow) / 3f;
|
||||
float factor = (1f - this.Efficiency) * EfficiencyHigh + EfficiencyLow;
|
||||
|
||||
proportionFactor = new Vector3(factor, factor, factor);
|
||||
integralFactor = new Vector3(factor, factor, factor);
|
||||
derivFactor = new Vector3(factor, factor, factor);
|
||||
|
||||
MDetailLog("{0},BSPIDVMotor.setEfficiency,eff={1},factor={2}", BSScene.DetailLogZero, Efficiency, factor);
|
||||
MDetailLog("{0}, BSPIDVMotor.setEfficiency,eff={1},factor={2}", BSScene.DetailLogZero, Efficiency, factor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -434,16 +435,15 @@ public class BSPIDVMotor : BSVMotor
|
||||
|
||||
// A simple derivitive is the rate of change from the last error.
|
||||
Vector3 derivitive = (error - LastError) * timeStep;
|
||||
LastError = error;
|
||||
|
||||
// Correction = (proportionOfPresentError + accumulationOfPastError + rateOfChangeOfError)
|
||||
Vector3 ret = error * timeStep * proportionFactor * FactorMix.X
|
||||
+ RunningIntegration * integralFactor * FactorMix.Y
|
||||
+ derivitive * derivFactor * FactorMix.Z
|
||||
Vector3 ret = error / TimeScale * timeStep * proportionFactor * FactorMix.X
|
||||
+ RunningIntegration / TimeScale * integralFactor * FactorMix.Y
|
||||
+ derivitive / TimeScale * derivFactor * FactorMix.Z
|
||||
;
|
||||
|
||||
MDetailLog("{0},BSPIDVMotor.step,ts={1},err={2},runnInt={3},deriv={4},ret={5}",
|
||||
BSScene.DetailLogZero, timeStep, error, RunningIntegration, derivitive, ret);
|
||||
MDetailLog("{0}, BSPIDVMotor.step,ts={1},err={2},lerr={3},runnInt={4},deriv={5},ret={6}",
|
||||
BSScene.DetailLogZero, timeStep, error, LastError, RunningIntegration, derivitive, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -176,6 +176,7 @@ public static class BSParam
|
||||
|
||||
// Linkset implementation parameters
|
||||
public static float LinksetImplementation { get; private set; }
|
||||
public static bool LinksetOffsetCenterOfMass { get; private set; }
|
||||
public static bool LinkConstraintUseFrameOffset { get; private set; }
|
||||
public static bool LinkConstraintEnableTransMotor { get; private set; }
|
||||
public static float LinkConstraintTransMotorMaxVel { get; private set; }
|
||||
@@ -684,6 +685,8 @@ public static class BSParam
|
||||
|
||||
new ParameterDefn<float>("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)",
|
||||
(float)BSLinkset.LinksetImplementation.Compound ),
|
||||
new ParameterDefn<bool>("LinksetOffsetCenterOfMass", "If 'true', compute linkset center-of-mass and offset linkset position to account for same",
|
||||
false ),
|
||||
new ParameterDefn<bool>("LinkConstraintUseFrameOffset", "For linksets built with constraints, enable frame offsetFor linksets built with constraints, enable frame offset.",
|
||||
false ),
|
||||
new ParameterDefn<bool>("LinkConstraintEnableTransMotor", "Whether to enable translational motor on linkset constraints",
|
||||
|
||||
@@ -90,6 +90,8 @@ public abstract class BSPhysObject : PhysicsActor
|
||||
PhysBody = new BulletBody(localID);
|
||||
PhysShape = new BSShapeNull();
|
||||
|
||||
UserSetCenterOfMassDisplacement = null;
|
||||
|
||||
PrimAssetState = PrimAssetCondition.Unknown;
|
||||
|
||||
// Default material type. Also sets Friction, Restitution and Density.
|
||||
@@ -180,6 +182,7 @@ public abstract class BSPhysObject : PhysicsActor
|
||||
Material = (MaterialAttributes.Material)material;
|
||||
|
||||
// Setting the material sets the material attributes also.
|
||||
// TODO: decide if this is necessary -- the simulator does this.
|
||||
MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, false);
|
||||
Friction = matAttrib.friction;
|
||||
Restitution = matAttrib.restitution;
|
||||
@@ -194,10 +197,10 @@ public abstract class BSPhysObject : PhysicsActor
|
||||
// Update the physical location and motion of the object. Called with data from Bullet.
|
||||
public abstract void UpdateProperties(EntityProperties entprop);
|
||||
|
||||
public abstract OMV.Vector3 RawPosition { get; set; }
|
||||
public virtual OMV.Vector3 RawPosition { get; set; }
|
||||
public abstract OMV.Vector3 ForcePosition { get; set; }
|
||||
|
||||
public abstract OMV.Quaternion RawOrientation { get; set; }
|
||||
public virtual OMV.Quaternion RawOrientation { get; set; }
|
||||
public abstract OMV.Quaternion ForceOrientation { get; set; }
|
||||
|
||||
public OMV.Vector3 RawVelocity { get; set; }
|
||||
@@ -210,6 +213,7 @@ public abstract class BSPhysObject : PhysicsActor
|
||||
AddAngularForce(force, pushforce, false);
|
||||
}
|
||||
public abstract void AddAngularForce(OMV.Vector3 force, bool pushforce, bool inTaintTime);
|
||||
public abstract void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime);
|
||||
|
||||
public abstract OMV.Vector3 ForceRotationalVelocity { get; set; }
|
||||
|
||||
|
||||
@@ -51,12 +51,8 @@ public class BSPrim : BSPhysObject
|
||||
private bool _isSelected;
|
||||
private bool _isVolumeDetect;
|
||||
|
||||
// _position is what the simulator thinks the positions of the prim is.
|
||||
private OMV.Vector3 _position;
|
||||
|
||||
private float _mass; // the mass of this object
|
||||
private OMV.Vector3 _acceleration;
|
||||
private OMV.Quaternion _orientation;
|
||||
private int _physicsActorType;
|
||||
private bool _isPhysical;
|
||||
private bool _flying;
|
||||
@@ -70,18 +66,17 @@ public class BSPrim : BSPhysObject
|
||||
private int CrossingFailures { get; set; }
|
||||
|
||||
// Keep a handle to the vehicle actor so it is easy to set parameters on same.
|
||||
public BSDynamics VehicleActor;
|
||||
public const string VehicleActorName = "BasicVehicle";
|
||||
|
||||
// Parameters for the hover actor
|
||||
public const string HoverActorName = "HoverActor";
|
||||
public const string HoverActorName = "BSPrim.HoverActor";
|
||||
// Parameters for the axis lock actor
|
||||
public const String LockedAxisActorName = "BSPrim.LockedAxis";
|
||||
// Parameters for the move to target actor
|
||||
public const string MoveToTargetActorName = "MoveToTargetActor";
|
||||
public const string MoveToTargetActorName = "BSPrim.MoveToTargetActor";
|
||||
// Parameters for the setForce and setTorque actors
|
||||
public const string SetForceActorName = "SetForceActor";
|
||||
public const string SetTorqueActorName = "SetTorqueActor";
|
||||
public const string SetForceActorName = "BSPrim.SetForceActor";
|
||||
public const string SetTorqueActorName = "BSPrim.SetTorqueActor";
|
||||
|
||||
public BSPrim(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size,
|
||||
OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical)
|
||||
@@ -89,10 +84,10 @@ public class BSPrim : BSPhysObject
|
||||
{
|
||||
// m_log.DebugFormat("{0}: BSPrim creation of {1}, id={2}", LogHeader, primName, localID);
|
||||
_physicsActorType = (int)ActorTypes.Prim;
|
||||
_position = pos;
|
||||
RawPosition = pos;
|
||||
_size = size;
|
||||
Scale = size; // prims are the size the user wants them to be (different for BSCharactes).
|
||||
_orientation = rotation;
|
||||
RawOrientation = rotation;
|
||||
_buoyancy = 0f;
|
||||
RawVelocity = OMV.Vector3.Zero;
|
||||
_rotationalVelocity = OMV.Vector3.Zero;
|
||||
@@ -100,9 +95,8 @@ 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(PhysScene, this, VehicleActorName);
|
||||
PhysicalActors.Add(VehicleActorName, VehicleActor);
|
||||
// Add a dynamic vehicle to our set of actors that can move this prim.
|
||||
PhysicalActors.Add(VehicleActorName, new BSDynamics(PhysScene, this, VehicleActorName));
|
||||
|
||||
_mass = CalculateMass();
|
||||
|
||||
@@ -272,46 +266,42 @@ public class BSPrim : BSPhysObject
|
||||
return;
|
||||
}
|
||||
|
||||
public override OMV.Vector3 RawPosition
|
||||
{
|
||||
get { return _position; }
|
||||
set { _position = value; }
|
||||
}
|
||||
public override OMV.Vector3 Position {
|
||||
get {
|
||||
// don't do the GetObjectPosition for root elements because this function is called a zillion times.
|
||||
// _position = ForcePosition;
|
||||
return _position;
|
||||
// RawPosition = ForcePosition;
|
||||
return RawPosition;
|
||||
}
|
||||
set {
|
||||
// If the position must be forced into the physics engine, use ForcePosition.
|
||||
// All positions are given in world positions.
|
||||
if (_position == value)
|
||||
if (RawPosition == value)
|
||||
{
|
||||
DetailLog("{0},BSPrim.setPosition,call,positionNotChanging,pos={1},orient={2}", LocalID, _position, _orientation);
|
||||
DetailLog("{0},BSPrim.setPosition,call,positionNotChanging,pos={1},orient={2}", LocalID, RawPosition, RawOrientation);
|
||||
return;
|
||||
}
|
||||
_position = value;
|
||||
RawPosition = value;
|
||||
PositionSanityCheck(false);
|
||||
|
||||
PhysScene.TaintedObject("BSPrim.setPosition", delegate()
|
||||
{
|
||||
DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
|
||||
ForcePosition = _position;
|
||||
DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, RawPosition, RawOrientation);
|
||||
ForcePosition = RawPosition;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: overloaded by BSPrimDisplaced to handle offset for center-of-gravity.
|
||||
public override OMV.Vector3 ForcePosition {
|
||||
get {
|
||||
_position = PhysScene.PE.GetPosition(PhysBody);
|
||||
return _position;
|
||||
RawPosition = PhysScene.PE.GetPosition(PhysBody);
|
||||
return RawPosition;
|
||||
}
|
||||
set {
|
||||
_position = value;
|
||||
RawPosition = value;
|
||||
if (PhysBody.HasPhysicalBody)
|
||||
{
|
||||
PhysScene.PE.SetTranslation(PhysBody, _position, _orientation);
|
||||
PhysScene.PE.SetTranslation(PhysBody, RawPosition, RawOrientation);
|
||||
ActivateIfPhysical(false);
|
||||
}
|
||||
}
|
||||
@@ -345,10 +335,10 @@ public class BSPrim : BSPhysObject
|
||||
float targetHeight = terrainHeight + (Size.Z / 2f);
|
||||
// If the object is below ground it just has to be moved up because pushing will
|
||||
// not get it through the terrain
|
||||
_position.Z = targetHeight;
|
||||
RawPosition = new OMV.Vector3(RawPosition.X, RawPosition.Y, targetHeight);
|
||||
if (inTaintTime)
|
||||
{
|
||||
ForcePosition = _position;
|
||||
ForcePosition = RawPosition;
|
||||
}
|
||||
// If we are throwing the object around, zero its other forces
|
||||
ZeroMotion(inTaintTime);
|
||||
@@ -357,7 +347,7 @@ public class BSPrim : BSPhysObject
|
||||
|
||||
if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0)
|
||||
{
|
||||
float waterHeight = PhysScene.TerrainManager.GetWaterLevelAtXYZ(_position);
|
||||
float waterHeight = PhysScene.TerrainManager.GetWaterLevelAtXYZ(RawPosition);
|
||||
// TODO: a floating motor so object will bob in the water
|
||||
if (Math.Abs(RawPosition.Z - waterHeight) > 0.1f)
|
||||
{
|
||||
@@ -366,7 +356,7 @@ public class BSPrim : BSPhysObject
|
||||
|
||||
// Apply upforce and overcome gravity.
|
||||
OMV.Vector3 correctionForce = upForce - PhysScene.DefaultGravity;
|
||||
DetailLog("{0},BSPrim.PositionSanityCheck,applyForce,pos={1},upForce={2},correctionForce={3}", LocalID, _position, upForce, correctionForce);
|
||||
DetailLog("{0},BSPrim.PositionSanityCheck,applyForce,pos={1},upForce={2},correctionForce={3}", LocalID, RawPosition, upForce, correctionForce);
|
||||
AddForce(correctionForce, false, inTaintTime);
|
||||
ret = true;
|
||||
}
|
||||
@@ -385,11 +375,11 @@ public class BSPrim : BSPhysObject
|
||||
uint wayOutThere = Constants.RegionSize * Constants.RegionSize;
|
||||
// There have been instances of objects getting thrown way out of bounds and crashing
|
||||
// the border crossing code.
|
||||
if ( _position.X < -Constants.RegionSize || _position.X > wayOutThere
|
||||
|| _position.Y < -Constants.RegionSize || _position.Y > wayOutThere
|
||||
|| _position.Z < -Constants.RegionSize || _position.Z > wayOutThere)
|
||||
if ( RawPosition.X < -Constants.RegionSize || RawPosition.X > wayOutThere
|
||||
|| RawPosition.Y < -Constants.RegionSize || RawPosition.Y > wayOutThere
|
||||
|| RawPosition.Z < -Constants.RegionSize || RawPosition.Z > wayOutThere)
|
||||
{
|
||||
_position = new OMV.Vector3(10, 10, 50);
|
||||
RawPosition = new OMV.Vector3(10, 10, 50);
|
||||
ZeroMotion(inTaintTime);
|
||||
ret = true;
|
||||
}
|
||||
@@ -450,6 +440,9 @@ public class BSPrim : BSPhysObject
|
||||
Gravity = ComputeGravity(Buoyancy);
|
||||
PhysScene.PE.SetGravity(PhysBody, Gravity);
|
||||
|
||||
OMV.Vector3 currentScale = PhysScene.PE.GetLocalScaling(PhysShape.physShapeInfo); // DEBUG DEBUG
|
||||
DetailLog("{0},BSPrim.UpdateMassProperties,currentScale{1},shape={2}", LocalID, currentScale, PhysShape.physShapeInfo); // DEBUG DEBUG
|
||||
|
||||
Inertia = PhysScene.PE.CalculateLocalInertia(PhysShape.physShapeInfo, physMass);
|
||||
PhysScene.PE.SetMassProps(PhysBody, physMass, Inertia);
|
||||
PhysScene.PE.UpdateInertiaTensor(PhysBody);
|
||||
@@ -502,9 +495,25 @@ public class BSPrim : BSPhysObject
|
||||
}
|
||||
}
|
||||
|
||||
// Find and return a handle to the current vehicle actor.
|
||||
// Return 'null' if there is no vehicle actor.
|
||||
public BSDynamics GetVehicleActor()
|
||||
{
|
||||
BSDynamics ret = null;
|
||||
BSActor actor;
|
||||
if (PhysicalActors.TryGetActor(VehicleActorName, out actor))
|
||||
{
|
||||
ret = actor as BSDynamics;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
public override int VehicleType {
|
||||
get {
|
||||
return (int)VehicleActor.Type;
|
||||
int ret = (int)Vehicle.TYPE_NONE;
|
||||
BSDynamics vehicleActor = GetVehicleActor();
|
||||
if (vehicleActor != null)
|
||||
ret = (int)vehicleActor.Type;
|
||||
return ret;
|
||||
}
|
||||
set {
|
||||
Vehicle type = (Vehicle)value;
|
||||
@@ -515,8 +524,12 @@ public class BSPrim : BSPhysObject
|
||||
// change all the parameters. Like a plane changing to CAR when on the
|
||||
// ground. In this case, don't want to zero motion.
|
||||
// ZeroMotion(true /* inTaintTime */);
|
||||
VehicleActor.ProcessTypeChange(type);
|
||||
ActivateIfPhysical(false);
|
||||
BSDynamics vehicleActor = GetVehicleActor();
|
||||
if (vehicleActor != null)
|
||||
{
|
||||
vehicleActor.ProcessTypeChange(type);
|
||||
ActivateIfPhysical(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -524,31 +537,47 @@ public class BSPrim : BSPhysObject
|
||||
{
|
||||
PhysScene.TaintedObject("BSPrim.VehicleFloatParam", delegate()
|
||||
{
|
||||
VehicleActor.ProcessFloatVehicleParam((Vehicle)param, value);
|
||||
ActivateIfPhysical(false);
|
||||
BSDynamics vehicleActor = GetVehicleActor();
|
||||
if (vehicleActor != null)
|
||||
{
|
||||
vehicleActor.ProcessFloatVehicleParam((Vehicle)param, value);
|
||||
ActivateIfPhysical(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
public override void VehicleVectorParam(int param, OMV.Vector3 value)
|
||||
{
|
||||
PhysScene.TaintedObject("BSPrim.VehicleVectorParam", delegate()
|
||||
{
|
||||
VehicleActor.ProcessVectorVehicleParam((Vehicle)param, value);
|
||||
ActivateIfPhysical(false);
|
||||
BSDynamics vehicleActor = GetVehicleActor();
|
||||
if (vehicleActor != null)
|
||||
{
|
||||
vehicleActor.ProcessVectorVehicleParam((Vehicle)param, value);
|
||||
ActivateIfPhysical(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
public override void VehicleRotationParam(int param, OMV.Quaternion rotation)
|
||||
{
|
||||
PhysScene.TaintedObject("BSPrim.VehicleRotationParam", delegate()
|
||||
{
|
||||
VehicleActor.ProcessRotationVehicleParam((Vehicle)param, rotation);
|
||||
ActivateIfPhysical(false);
|
||||
BSDynamics vehicleActor = GetVehicleActor();
|
||||
if (vehicleActor != null)
|
||||
{
|
||||
vehicleActor.ProcessRotationVehicleParam((Vehicle)param, rotation);
|
||||
ActivateIfPhysical(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
public override void VehicleFlags(int param, bool remove)
|
||||
{
|
||||
PhysScene.TaintedObject("BSPrim.VehicleFlags", delegate()
|
||||
{
|
||||
VehicleActor.ProcessVehicleFlags(param, remove);
|
||||
BSDynamics vehicleActor = GetVehicleActor();
|
||||
if (vehicleActor != null)
|
||||
{
|
||||
vehicleActor.ProcessVehicleFlags(param, remove);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -676,23 +705,19 @@ public class BSPrim : BSPhysObject
|
||||
get { return _acceleration; }
|
||||
set { _acceleration = value; }
|
||||
}
|
||||
public override OMV.Quaternion RawOrientation
|
||||
{
|
||||
get { return _orientation; }
|
||||
set { _orientation = value; }
|
||||
}
|
||||
|
||||
public override OMV.Quaternion Orientation {
|
||||
get {
|
||||
return _orientation;
|
||||
return RawOrientation;
|
||||
}
|
||||
set {
|
||||
if (_orientation == value)
|
||||
if (RawOrientation == value)
|
||||
return;
|
||||
_orientation = value;
|
||||
RawOrientation = value;
|
||||
|
||||
PhysScene.TaintedObject("BSPrim.setOrientation", delegate()
|
||||
{
|
||||
ForceOrientation = _orientation;
|
||||
ForceOrientation = RawOrientation;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -701,14 +726,14 @@ public class BSPrim : BSPhysObject
|
||||
{
|
||||
get
|
||||
{
|
||||
_orientation = PhysScene.PE.GetOrientation(PhysBody);
|
||||
return _orientation;
|
||||
RawOrientation = PhysScene.PE.GetOrientation(PhysBody);
|
||||
return RawOrientation;
|
||||
}
|
||||
set
|
||||
{
|
||||
_orientation = value;
|
||||
RawOrientation = value;
|
||||
if (PhysBody.HasPhysicalBody)
|
||||
PhysScene.PE.SetTranslation(PhysBody, _position, _orientation);
|
||||
PhysScene.PE.SetTranslation(PhysBody, RawPosition, RawOrientation);
|
||||
}
|
||||
}
|
||||
public override int PhysicsActorType {
|
||||
@@ -765,6 +790,7 @@ public class BSPrim : BSPhysObject
|
||||
// isSolid: other objects bounce off of this object
|
||||
// isVolumeDetect: other objects pass through but can generate collisions
|
||||
// collisionEvents: whether this object returns collision events
|
||||
// NOTE: overloaded by BSPrimLinkable to also update linkset physical parameters.
|
||||
public virtual void UpdatePhysicalParameters()
|
||||
{
|
||||
if (!PhysBody.HasPhysicalBody)
|
||||
@@ -851,7 +877,7 @@ public class BSPrim : BSPhysObject
|
||||
// PhysicsScene.PE.ClearAllForces(BSBody);
|
||||
|
||||
// For good measure, make sure the transform is set through to the motion state
|
||||
ForcePosition = _position;
|
||||
ForcePosition = RawPosition;
|
||||
ForceVelocity = RawVelocity;
|
||||
ForceRotationalVelocity = _rotationalVelocity;
|
||||
|
||||
@@ -1040,6 +1066,20 @@ public class BSPrim : BSPhysObject
|
||||
}
|
||||
}
|
||||
|
||||
public override OMV.Vector3 PIDTarget
|
||||
{
|
||||
set
|
||||
{
|
||||
base.PIDTarget = value;
|
||||
BSActor actor;
|
||||
if (PhysicalActors.TryGetActor(MoveToTargetActorName, out actor))
|
||||
{
|
||||
// if the actor exists, tell it to refresh its values.
|
||||
actor.Refresh();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
// Used for llSetHoverHeight and maybe vehicle height
|
||||
// Hover Height will override MoveTo target's Z
|
||||
public override bool PIDHoverActive {
|
||||
@@ -1063,7 +1103,7 @@ public class BSPrim : BSPhysObject
|
||||
|
||||
// Applying a force just adds this to the total force on the object.
|
||||
// This added force will only last the next simulation tick.
|
||||
public void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) {
|
||||
public override void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) {
|
||||
// for an object, doesn't matter if force is a pushforce or not
|
||||
if (IsPhysicallyActive)
|
||||
{
|
||||
@@ -1074,7 +1114,9 @@ public class BSPrim : BSPhysObject
|
||||
OMV.Vector3 addForce = force;
|
||||
PhysScene.TaintedObject(inTaintTime, "BSPrim.AddForce", delegate()
|
||||
{
|
||||
// Bullet adds this central force to the total force for this tick
|
||||
// Bullet adds this central force to the total force for this tick.
|
||||
// Deep down in Bullet:
|
||||
// linearVelocity += totalForce / mass * timeStep;
|
||||
DetailLog("{0},BSPrim.addForce,taint,force={1}", LocalID, addForce);
|
||||
if (PhysBody.HasPhysicalBody)
|
||||
{
|
||||
@@ -1442,6 +1484,8 @@ public class BSPrim : BSPhysObject
|
||||
|
||||
returnMass = Util.Clamp(returnMass, BSParam.MinimumObjectMass, BSParam.MaximumObjectMass);
|
||||
// DetailLog("{0},BSPrim.CalculateMass,den={1},vol={2},mass={3}", LocalID, Density, volume, returnMass);
|
||||
DetailLog("{0},BSPrim.CalculateMass,den={1},vol={2},mass={3},pathB={4},pathE={5},profB={6},profE={7},siz={8}",
|
||||
LocalID, Density, volume, returnMass, pathBegin, pathEnd, profileBegin, profileEnd, _size);
|
||||
|
||||
return returnMass;
|
||||
}// end CalculateMass
|
||||
@@ -1477,6 +1521,8 @@ public class BSPrim : BSPhysObject
|
||||
|
||||
// The physics engine says that properties have updated. Update same and inform
|
||||
// the world that things have changed.
|
||||
// NOTE: BSPrim.UpdateProperties is overloaded by BSPrimLinkable which modifies updates from root and children prims.
|
||||
// NOTE: BSPrim.UpdateProperties is overloaded by BSPrimDisplaced which handles mapping physical position to simulator position.
|
||||
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.
|
||||
@@ -1485,8 +1531,8 @@ public class BSPrim : BSPhysObject
|
||||
// DetailLog("{0},BSPrim.UpdateProperties,entry,entprop={1}", LocalID, entprop); // DEBUG DEBUG
|
||||
|
||||
// Assign directly to the local variables so the normal set actions do not happen
|
||||
_position = entprop.Position;
|
||||
_orientation = entprop.Rotation;
|
||||
RawPosition = entprop.Position;
|
||||
RawOrientation = 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(RawVelocity, BSParam.UpdateVelocityChangeThreshold))
|
||||
@@ -1499,21 +1545,19 @@ public class BSPrim : BSPhysObject
|
||||
// The sanity check can change the velocity and/or position.
|
||||
if (PositionSanityCheck(true /* inTaintTime */ ))
|
||||
{
|
||||
entprop.Position = _position;
|
||||
entprop.Position = RawPosition;
|
||||
entprop.Velocity = RawVelocity;
|
||||
entprop.RotationalVelocity = _rotationalVelocity;
|
||||
entprop.Acceleration = _acceleration;
|
||||
}
|
||||
|
||||
OMV.Vector3 direction = OMV.Vector3.UnitX * _orientation; // DEBUG DEBUG DEBUG
|
||||
OMV.Vector3 direction = OMV.Vector3.UnitX * RawOrientation; // DEBUG DEBUG DEBUG
|
||||
DetailLog("{0},BSPrim.UpdateProperties,call,entProp={1},dir={2}", LocalID, entprop, direction);
|
||||
|
||||
// remember the current and last set values
|
||||
LastEntityProperties = CurrentEntityProperties;
|
||||
CurrentEntityProperties = entprop;
|
||||
|
||||
// Note that BSPrim can be overloaded by BSPrimLinkable which controls updates from root and children prims.
|
||||
|
||||
PhysScene.PostUpdate(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,11 +23,6 @@
|
||||
* 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.
|
||||
*
|
||||
* The quotations from http://wiki.secondlife.com/wiki/Linden_Vehicle_Tutorial
|
||||
* are Copyright (c) 2009 Linden Research, Inc and are used under their license
|
||||
* of Creative Commons Attribution-Share Alike 3.0
|
||||
* (http://creativecommons.org/licenses/by-sa/3.0/).
|
||||
*/
|
||||
|
||||
using System;
|
||||
@@ -44,14 +39,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
{
|
||||
public class BSPrimDisplaced : BSPrim
|
||||
{
|
||||
// The purpose of this module is to do any mapping between what the simulator thinks
|
||||
// The purpose of this subclass is to do any mapping between what the simulator thinks
|
||||
// the prim position and orientation is and what the physical position/orientation.
|
||||
// This difference happens because Bullet assumes the center-of-mass is the <0,0,0>
|
||||
// of the prim/linkset. The simulator tracks the location of the prim/linkset by
|
||||
// the location of the root prim. So, if center-of-mass is anywhere but the origin
|
||||
// of the root prim, the physical origin is displaced from the simulator origin.
|
||||
// of the prim/linkset. The simulator, on the other hand, tracks the location of
|
||||
// the prim/linkset by the location of the root prim. So, if center-of-mass is anywhere
|
||||
// but the origin of the root prim, the physical origin is displaced from the simulator origin.
|
||||
//
|
||||
// This routine works by capturing the Force* setting of position/orientation/... and
|
||||
// This routine works by capturing ForcePosition and
|
||||
// adjusting the simulator values (being set) into the physical values.
|
||||
// The conversion is also done in the opposite direction (physical origin -> simulator origin).
|
||||
//
|
||||
@@ -59,8 +54,8 @@ public class BSPrimDisplaced : BSPrim
|
||||
// are converted into simulator origin values before being passed to the base
|
||||
// class.
|
||||
|
||||
// PositionDisplacement is the vehicle relative distance from the root prim position to the center-of-mass.
|
||||
public virtual OMV.Vector3 PositionDisplacement { get; set; }
|
||||
public virtual OMV.Quaternion OrientationDisplacement { get; set; }
|
||||
|
||||
public BSPrimDisplaced(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size,
|
||||
OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical)
|
||||
@@ -69,50 +64,82 @@ public class BSPrimDisplaced : BSPrim
|
||||
ClearDisplacement();
|
||||
}
|
||||
|
||||
// Clears any center-of-mass displacement introduced by linksets, etc.
|
||||
// Does not clear the displacement set by the user.
|
||||
public void ClearDisplacement()
|
||||
{
|
||||
PositionDisplacement = OMV.Vector3.Zero;
|
||||
OrientationDisplacement = OMV.Quaternion.Identity;
|
||||
if (UserSetCenterOfMassDisplacement.HasValue)
|
||||
PositionDisplacement = (OMV.Vector3)UserSetCenterOfMassDisplacement;
|
||||
else
|
||||
PositionDisplacement = OMV.Vector3.Zero;
|
||||
}
|
||||
|
||||
// Set this sets and computes the displacement from the passed prim to the center-of-mass.
|
||||
// A user set value for center-of-mass overrides whatever might be passed in here.
|
||||
// The displacement is in local coordinates (relative to root prim in linkset oriented coordinates).
|
||||
public virtual void SetEffectiveCenterOfMassDisplacement(Vector3 centerOfMassDisplacement)
|
||||
// Returns the relative offset from the root position to the center-of-mass.
|
||||
// Called at taint time.
|
||||
public virtual Vector3 SetEffectiveCenterOfMassDisplacement(Vector3 centerOfMassDisplacement)
|
||||
{
|
||||
PhysScene.AssertInTaintTime("BSPrimDisplaced.SetEffectiveCenterOfMassDisplacement");
|
||||
Vector3 comDisp;
|
||||
if (UserSetCenterOfMassDisplacement.HasValue)
|
||||
comDisp = (OMV.Vector3)UserSetCenterOfMassDisplacement;
|
||||
else
|
||||
comDisp = centerOfMassDisplacement;
|
||||
|
||||
// Eliminate any jitter caused be very slight differences in masses and positions
|
||||
if (comDisp.ApproxEquals(Vector3.Zero, 0.01f) )
|
||||
comDisp = Vector3.Zero;
|
||||
|
||||
DetailLog("{0},BSPrimDisplaced.SetEffectiveCenterOfMassDisplacement,userSet={1},comDisp={2}",
|
||||
LocalID, UserSetCenterOfMassDisplacement.HasValue, comDisp);
|
||||
if (comDisp == Vector3.Zero)
|
||||
if ( !comDisp.ApproxEquals(PositionDisplacement, 0.01f) )
|
||||
{
|
||||
// If there is no diplacement. Things get reset.
|
||||
PositionDisplacement = OMV.Vector3.Zero;
|
||||
OrientationDisplacement = OMV.Quaternion.Identity;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Remember the displacement from root as well as the origional rotation of the
|
||||
// new center-of-mass.
|
||||
// Displacement setting is changing.
|
||||
// The relationship between the physical object and simulated object must be aligned.
|
||||
PositionDisplacement = comDisp;
|
||||
OrientationDisplacement = OMV.Quaternion.Identity;
|
||||
this.ForcePosition = RawPosition;
|
||||
}
|
||||
|
||||
return PositionDisplacement;
|
||||
}
|
||||
|
||||
// 'ForcePosition' is the one way to set the physical position of the body in the physics engine.
|
||||
// Displace the simulator idea of position (center of root prim) to the physical position.
|
||||
public override Vector3 ForcePosition
|
||||
{
|
||||
get { return base.ForcePosition; }
|
||||
get {
|
||||
OMV.Vector3 physPosition = PhysScene.PE.GetPosition(PhysBody);
|
||||
if (PositionDisplacement != OMV.Vector3.Zero)
|
||||
{
|
||||
// If there is some displacement, return the physical position (center-of-mass)
|
||||
// location minus the displacement to give the center of the root prim.
|
||||
OMV.Vector3 displacement = PositionDisplacement * ForceOrientation;
|
||||
DetailLog("{0},BSPrimDisplaced.ForcePosition,get,physPos={1},disp={2},simPos={3}",
|
||||
LocalID, physPosition, displacement, physPosition - displacement);
|
||||
physPosition -= displacement;
|
||||
}
|
||||
RawPosition = physPosition;
|
||||
return physPosition;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (PositionDisplacement != OMV.Vector3.Zero)
|
||||
{
|
||||
OMV.Vector3 displacedPos = value - (PositionDisplacement * RawOrientation);
|
||||
DetailLog("{0},BSPrimDisplaced.ForcePosition,val={1},disp={2},newPos={3}", LocalID, value, PositionDisplacement, displacedPos);
|
||||
base.ForcePosition = displacedPos;
|
||||
// This value is the simulator's idea of where the prim is: the center of the root prim
|
||||
RawPosition = value;
|
||||
|
||||
// Move the passed root prim postion to the center-of-mass position and set in the physics engine.
|
||||
OMV.Vector3 displacement = PositionDisplacement * RawOrientation;
|
||||
OMV.Vector3 displacedPos = RawPosition + displacement;
|
||||
DetailLog("{0},BSPrimDisplaced.ForcePosition,set,simPos={1},disp={2},physPos={3}",
|
||||
LocalID, RawPosition, displacement, displacedPos);
|
||||
if (PhysBody.HasPhysicalBody)
|
||||
{
|
||||
PhysScene.PE.SetTranslation(PhysBody, displacedPos, RawOrientation);
|
||||
ActivateIfPhysical(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -121,25 +148,12 @@ public class BSPrimDisplaced : BSPrim
|
||||
}
|
||||
}
|
||||
|
||||
public override Quaternion ForceOrientation
|
||||
{
|
||||
get { return base.ForceOrientation; }
|
||||
set
|
||||
{
|
||||
// TODO:
|
||||
base.ForceOrientation = value;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: decide if this is the right place for these variables.
|
||||
// Somehow incorporate the optional settability by the user.
|
||||
// Is this used?
|
||||
// These are also overridden by BSPrimLinkable if the prim can be part of a linkset
|
||||
public override OMV.Vector3 CenterOfMass
|
||||
{
|
||||
get { return RawPosition; }
|
||||
}
|
||||
|
||||
// Is this used?
|
||||
public override OMV.Vector3 GeometricCenter
|
||||
{
|
||||
get { return RawPosition; }
|
||||
@@ -148,15 +162,18 @@ public class BSPrimDisplaced : BSPrim
|
||||
public override void UpdateProperties(EntityProperties entprop)
|
||||
{
|
||||
// Undo any center-of-mass displacement that might have been done.
|
||||
if (PositionDisplacement != OMV.Vector3.Zero || OrientationDisplacement != OMV.Quaternion.Identity)
|
||||
if (PositionDisplacement != OMV.Vector3.Zero)
|
||||
{
|
||||
// Correct for any rotation around the center-of-mass
|
||||
// TODO!!!
|
||||
|
||||
OMV.Vector3 displacedPos = entprop.Position + (PositionDisplacement * entprop.Rotation);
|
||||
DetailLog("{0},BSPrimDisplaced.ForcePosition,physPos={1},disp={2},newPos={3}", LocalID, entprop.Position, PositionDisplacement, displacedPos);
|
||||
// The origional shape was offset from 'zero' by PositionDisplacement.
|
||||
// These physical location must be back converted to be centered around the displaced
|
||||
// root shape.
|
||||
|
||||
// Move the returned center-of-mass location to the root prim location.
|
||||
OMV.Vector3 displacement = PositionDisplacement * entprop.Rotation;
|
||||
OMV.Vector3 displacedPos = entprop.Position - displacement;
|
||||
DetailLog("{0},BSPrimDisplaced.UpdateProperties,physPos={1},disp={2},simPos={3}",
|
||||
LocalID, entprop.Position, displacement, displacedPos);
|
||||
entprop.Position = displacedPos;
|
||||
// entprop.Rotation = something;
|
||||
}
|
||||
|
||||
base.UpdateProperties(entprop);
|
||||
|
||||
@@ -37,16 +37,25 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
{
|
||||
public class BSPrimLinkable : BSPrimDisplaced
|
||||
{
|
||||
// The purpose of this subclass is to add linkset functionality to the prim. This overrides
|
||||
// operations necessary for keeping the linkset created and, additionally, this
|
||||
// calls the linkset implementation for its creation and management.
|
||||
|
||||
// This adds the overrides for link() and delink() so the prim is linkable.
|
||||
|
||||
public BSLinkset Linkset { get; set; }
|
||||
// The index of this child prim.
|
||||
public int LinksetChildIndex { get; set; }
|
||||
|
||||
public BSLinksetInfo LinksetInfo { get; set; }
|
||||
public BSLinkset.LinksetImplementation LinksetType { get; set; }
|
||||
|
||||
public BSPrimLinkable(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size,
|
||||
OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical)
|
||||
: base(localID, primName, parent_scene, pos, size, rotation, pbs, pisPhysical)
|
||||
{
|
||||
// Default linkset implementation for this prim
|
||||
LinksetType = (BSLinkset.LinksetImplementation)BSParam.LinksetImplementation;
|
||||
|
||||
Linkset = BSLinkset.Factory(PhysScene, this);
|
||||
|
||||
PhysScene.TaintedObject("BSPrimLinksetCompound.Refresh", delegate()
|
||||
@@ -66,8 +75,8 @@ public class BSPrimLinkable : BSPrimDisplaced
|
||||
BSPrimLinkable parent = obj as BSPrimLinkable;
|
||||
if (parent != null)
|
||||
{
|
||||
BSPhysObject parentBefore = Linkset.LinksetRoot;
|
||||
int childrenBefore = Linkset.NumberOfChildren;
|
||||
BSPhysObject parentBefore = Linkset.LinksetRoot; // DEBUG
|
||||
int childrenBefore = Linkset.NumberOfChildren; // DEBUG
|
||||
|
||||
Linkset = parent.Linkset.AddMeToLinkset(this);
|
||||
|
||||
@@ -82,8 +91,8 @@ public class BSPrimLinkable : BSPrimDisplaced
|
||||
// TODO: decide if this parent checking needs to happen at taint time
|
||||
// Race condition here: if link() and delink() in same simulation tick, the delink will not happen
|
||||
|
||||
BSPhysObject parentBefore = Linkset.LinksetRoot;
|
||||
int childrenBefore = Linkset.NumberOfChildren;
|
||||
BSPhysObject parentBefore = Linkset.LinksetRoot; // DEBUG
|
||||
int childrenBefore = Linkset.NumberOfChildren; // DEBUG
|
||||
|
||||
Linkset = Linkset.RemoveMeFromLinkset(this);
|
||||
|
||||
@@ -125,6 +134,17 @@ public class BSPrimLinkable : BSPrimDisplaced
|
||||
get { return Linkset.LinksetMass; }
|
||||
}
|
||||
|
||||
public override OMV.Vector3 CenterOfMass
|
||||
{
|
||||
get { return Linkset.CenterOfMass; }
|
||||
}
|
||||
|
||||
public override OMV.Vector3 GeometricCenter
|
||||
{
|
||||
get { return Linkset.GeometricCenter; }
|
||||
}
|
||||
|
||||
// Refresh the linkset structure and parameters when the prim's physical parameters are changed.
|
||||
public override void UpdatePhysicalParameters()
|
||||
{
|
||||
base.UpdatePhysicalParameters();
|
||||
@@ -136,13 +156,17 @@ public class BSPrimLinkable : BSPrimDisplaced
|
||||
Linkset.Refresh(this);
|
||||
}
|
||||
|
||||
// When the prim is made dynamic or static, the linkset needs to change.
|
||||
protected override void MakeDynamic(bool makeStatic)
|
||||
{
|
||||
base.MakeDynamic(makeStatic);
|
||||
if (makeStatic)
|
||||
Linkset.MakeStatic(this);
|
||||
else
|
||||
Linkset.MakeDynamic(this);
|
||||
if (Linkset != null) // null can happen during initialization
|
||||
{
|
||||
if (makeStatic)
|
||||
Linkset.MakeStatic(this);
|
||||
else
|
||||
Linkset.MakeDynamic(this);
|
||||
}
|
||||
}
|
||||
|
||||
// Body is being taken apart. Remove physical dependencies and schedule a rebuild.
|
||||
@@ -152,6 +176,8 @@ public class BSPrimLinkable : BSPrimDisplaced
|
||||
base.RemoveDependencies();
|
||||
}
|
||||
|
||||
// Called after a simulation step for the changes in physical object properties.
|
||||
// Do any filtering/modification needed for linksets.
|
||||
public override void UpdateProperties(EntityProperties entprop)
|
||||
{
|
||||
if (Linkset.IsRoot(this))
|
||||
@@ -173,6 +199,7 @@ public class BSPrimLinkable : BSPrimDisplaced
|
||||
Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this);
|
||||
}
|
||||
|
||||
// Called after a simulation step to post a collision with this object.
|
||||
public override bool Collide(uint collidingWith, BSPhysObject collidee,
|
||||
OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
|
||||
{
|
||||
|
||||
@@ -223,8 +223,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
||||
// can be left in and every call doesn't have to check for null.
|
||||
if (m_physicsLoggingEnabled)
|
||||
{
|
||||
PhysicsLogging = new Logging.LogWriter(m_physicsLoggingDir, m_physicsLoggingPrefix, m_physicsLoggingFileMinutes);
|
||||
PhysicsLogging.ErrorLogger = m_log; // for DEBUG. Let's the logger output error messages.
|
||||
PhysicsLogging = new Logging.LogWriter(m_physicsLoggingDir, m_physicsLoggingPrefix, m_physicsLoggingFileMinutes, m_physicsLoggingDoFlush);
|
||||
PhysicsLogging.ErrorLogger = m_log; // for DEBUG. Let's the logger output its own error messages.
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -785,7 +785,6 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
||||
{
|
||||
// The simulation of the time interval took less than realtime.
|
||||
// Do a sleep for the rest of realtime.
|
||||
DetailLog("{0},BulletSPluginPhysicsThread,sleeping={1}", BSScene.DetailLogZero, simulationTimeVsRealtimeDifferenceMS);
|
||||
Thread.Sleep(simulationTimeVsRealtimeDifferenceMS);
|
||||
}
|
||||
else
|
||||
@@ -1106,8 +1105,6 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
||||
public void DetailLog(string msg, params Object[] args)
|
||||
{
|
||||
PhysicsLogging.Write(msg, args);
|
||||
// Add the Flush() if debugging crashes. Gets all the messages written out.
|
||||
if (m_physicsLoggingDoFlush) PhysicsLogging.Flush();
|
||||
}
|
||||
// Used to fill in the LocalID when there isn't one. It's the correct number of characters.
|
||||
public const string DetailLogZero = "0000000000";
|
||||
|
||||
@@ -3,25 +3,21 @@ CURRENT PROBLEMS TO FIX AND/OR LOOK AT
|
||||
Vehicle buoyancy. Computed correctly? Possibly creating very large effective mass.
|
||||
Interaction of llSetBuoyancy and vehicle buoyancy. Should be additive?
|
||||
Negative buoyancy computed correctly
|
||||
Center-of-gravity
|
||||
Computation of mesh mass. How done? How should it be done?
|
||||
Script changing rotation of child prim while vehicle moving (eg turning wheel) causes
|
||||
the wheel to appear to jump back. Looks like sending position from previous update.
|
||||
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)
|
||||
User settable terrain mesh
|
||||
Allow specifying as convex or concave and use different getHeight functions depending
|
||||
Boats, when turning nose down into the water
|
||||
Acts like rotation around Z is also effecting rotation around X and Y
|
||||
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.
|
||||
Nebadon spiral tube has middle sections which are rotated wrong.
|
||||
Select linked spiral tube. Delink and note where the middle section ends up.
|
||||
Refarb compound linkset creation to create a pseudo-root for center-of-mass
|
||||
Let children change their shape to physical indendently and just add shapes to compound
|
||||
Vehicle angular vertical attraction
|
||||
vehicle angular banking
|
||||
Center-of-gravity
|
||||
Vehicle angular deflection
|
||||
Preferred orientation angular correction fix
|
||||
Teravus llMoveToTarget script debug
|
||||
Mixing of hover, buoyancy/gravity, moveToTarget, into one force
|
||||
Setting hover height to zero disables hover even if hover flags are on (from SL wiki)
|
||||
@@ -33,10 +29,16 @@ Vehicle script tuning/debugging
|
||||
Avanti speed script
|
||||
Weapon shooter script
|
||||
Move material definitions (friction, ...) into simulator.
|
||||
osGetPhysicsEngineVerion() and create a version code for the C++ DLL
|
||||
One sided meshes? Should terrain be built into a closed shape?
|
||||
When meshes get partially wedged into the terrain, they cannot push themselves out.
|
||||
It is possible that Bullet processes collisions whether entering or leaving a mesh.
|
||||
Ref: http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4869
|
||||
Small physical objects do not interact correctly
|
||||
Create chain of .5x.5x.1 torui and make all but top physical so to hang.
|
||||
The chain will fall apart and pairs will dance around on ground
|
||||
Chains of 1x1x.2 will stay connected but will dance.
|
||||
Chains above 2x2x.4 are more stable and get stablier as torui get larger.
|
||||
|
||||
VEHICLES TODO LIST:
|
||||
=================================================
|
||||
@@ -45,14 +47,12 @@ LINEAR_MOTOR_DIRECTION values should be clamped to reasonable numbers.
|
||||
Same for other velocity settings.
|
||||
UBit improvements to remove rubber-banding of avatars sitting on vehicle child prims:
|
||||
https://github.com/UbitUmarov/Ubit-opensim
|
||||
Vehicles (Move smoothly)
|
||||
Some vehicles should not be able to turn if no speed or off ground.
|
||||
Cannot edit/move a vehicle being ridden: it jumps back to the origional position.
|
||||
Neb car jiggling left and right
|
||||
Happens on terrain and any other mesh object. Flat cubes are much smoother.
|
||||
This has been reduced but not eliminated.
|
||||
Implement referenceFrame for all the motion routines.
|
||||
For limitMotorUp, use raycast down to find if vehicle is in the air.
|
||||
Verify llGetVel() is returning a smooth and good value for vehicle movement.
|
||||
llGetVel() should return the root's velocity if requested in a child prim.
|
||||
Implement function efficiency for lineaar and angular motion.
|
||||
@@ -93,29 +93,15 @@ Revisit CollisionMargin. Builders notice the 0.04 spacing between prims.
|
||||
Duplicating a physical prim causes old prim to jump away
|
||||
Dup a phys prim and the original become unselected and thus interacts w/ selected prim.
|
||||
Scenes with hundred of thousands of static objects take a lot of physics CPU time.
|
||||
BSPrim.Force should set a continious force on the prim. The force should be
|
||||
applied each tick. Some limits?
|
||||
Gun sending shooter flying.
|
||||
Collision margin (gap between physical objects lying on each other)
|
||||
Boundry checking (crashes related to crossing boundry)
|
||||
Add check for border edge position for avatars and objects.
|
||||
Verify the events are created for border crossings.
|
||||
Avatar rotation (check out changes to ScenePresence for physical rotation)
|
||||
Avatar running (what does phys engine need to do?)
|
||||
Small physical objects do not interact correctly
|
||||
Create chain of .5x.5x.1 torui and make all but top physical so to hang.
|
||||
The chain will fall apart and pairs will dance around on ground
|
||||
Chains of 1x1x.2 will stay connected but will dance.
|
||||
Chains above 2x2x.4 are more stable and get stablier as torui get larger.
|
||||
Add PID motor for avatar movement (slow to stop, ...)
|
||||
setForce should set a constant force. Different than AddImpulse.
|
||||
Implement raycast.
|
||||
Implement ShapeCollection.Dispose()
|
||||
Implement water as a plain so raycasting and collisions can happen with same.
|
||||
Implement water as a plain or mesh so raycasting and collisions can happen with same.
|
||||
Add collision penetration return
|
||||
Add field passed back by BulletSim.dll and fill with info in ManifoldConstact.GetDistance()
|
||||
Add osGetPhysicsEngineName() so scripters can tell whether BulletSim or ODE
|
||||
Also osGetPhysicsEngineVerion() maybe.
|
||||
Linkset.Position and Linkset.Orientation requre rewrite to properly return
|
||||
child position. LinksetConstraint acts like it's at taint time!!
|
||||
Implement LockAngularMotion -- implements llSetStatus(ROTATE_AXIS_*, T/F)
|
||||
@@ -127,9 +113,6 @@ Selecting and deselecting physical objects causes CPU processing time to jump
|
||||
Re-implement buoyancy as a separate force on the object rather than diddling gravity.
|
||||
Register a pre-step event to add the force.
|
||||
More efficient memory usage when passing hull information from BSPrim to BulletSim
|
||||
Avatar movement motor check for zero or small movement. Somehow suppress small movements
|
||||
when avatar has stopped and is just standing. Simple test for near zero has
|
||||
the problem of preventing starting up (increase from zero) especially when falling.
|
||||
Physical and phantom will drop through the terrain
|
||||
|
||||
|
||||
@@ -172,7 +155,6 @@ Do we need to do convex hulls all the time? Can complex meshes be left meshes?
|
||||
There is some problem with meshes and collisions
|
||||
Hulls are not as detailed as meshes. Hulled vehicles insides are different shape.
|
||||
Debounce avatar contact so legs don't keep folding up when standing.
|
||||
Implement LSL physics controls. Like STATUS_ROTATE_X.
|
||||
Add border extensions to terrain to help region crossings and objects leaving region.
|
||||
Use a different capsule shape for avatar when sitting
|
||||
LL uses a pyrimidal shape scaled by the avatar's bounding box
|
||||
@@ -205,8 +187,6 @@ Keep avatar scaling correct. http://pennycow.blogspot.fr/2011/07/matter-of-scale
|
||||
|
||||
INTERNAL IMPROVEMENT/CLEANUP
|
||||
=================================================
|
||||
Can the 'inTaintTime' flag be cleaned up and used? For instance, a call to
|
||||
BSScene.TaintedObject() could immediately execute the callback if already in taint time.
|
||||
Create the physical wrapper classes (BulletBody, BulletShape) by methods on
|
||||
BSAPITemplate and make their actual implementation Bullet engine specific.
|
||||
For the short term, just call the existing functions in ShapeCollection.
|
||||
@@ -365,4 +345,35 @@ After getting off a vehicle, the root prim is phantom (can be walked through)
|
||||
Explore btGImpactMeshShape as alternative to convex hulls for simplified physical objects.
|
||||
Regular triangle meshes don't do physical collisions.
|
||||
(DONE: discovered GImpact is VERY CPU intensive)
|
||||
Script changing rotation of child prim while vehicle moving (eg turning wheel) causes
|
||||
the wheel to appear to jump back. Looks like sending position from previous update.
|
||||
(DONE: redo of compound linksets fixed problem)
|
||||
Refarb compound linkset creation to create a pseudo-root for center-of-mass
|
||||
Let children change their shape to physical indendently and just add shapes to compound
|
||||
(DONE: redo of compound linkset fixed problem)
|
||||
Vehicle angular vertical attraction (DONE: vegaslon code)
|
||||
vehicle angular banking (DONE: vegaslon code)
|
||||
Vehicle angular deflection (DONE: vegaslon code)
|
||||
Preferred orientation angular correction fix
|
||||
Vehicles (Move smoothly)
|
||||
For limitMotorUp, use raycast down to find if vehicle is in the air.
|
||||
(WILL NOT BE DONE: gravity does the job well enough)
|
||||
BSPrim.Force should set a continious force on the prim. The force should be
|
||||
applied each tick. Some limits?
|
||||
(DONE: added physical actors. Implemented SetForce, SetTorque, ...)
|
||||
Implement LSL physics controls. Like STATUS_ROTATE_X. (DONE)
|
||||
Add osGetPhysicsEngineName() so scripters can tell whether BulletSim or ODE
|
||||
Avatar rotation (check out changes to ScenePresence for physical rotation) (DONE)
|
||||
Avatar running (what does phys engine need to do?) (DONE: multiplies run factor by walking force)
|
||||
setForce should set a constant force. Different than AddImpulse. (DONE)
|
||||
Add PID motor for avatar movement (slow to stop, ...) (WNBD: current works ok)
|
||||
Avatar movement motor check for zero or small movement. Somehow suppress small movements
|
||||
when avatar has stopped and is just standing. Simple test for near zero has
|
||||
the problem of preventing starting up (increase from zero) especially when falling.
|
||||
(DONE: avatar movement actor knows if standing on stationary object and zeros motion)
|
||||
Can the 'inTaintTime' flag be cleaned up and used? For instance, a call to
|
||||
BSScene.TaintedObject() could immediately execute the callback if already in taint time.
|
||||
(DONE)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -114,21 +114,25 @@ public class BasicVehicles : OpenSimTestCase
|
||||
// Instead the appropriate values are set and calls are made just the parts of the
|
||||
// controller we want to exercise. Stepping the physics engine then applies
|
||||
// the actions of that one feature.
|
||||
TestVehicle.VehicleActor.ProcessFloatVehicleParam(Vehicle.VERTICAL_ATTRACTION_EFFICIENCY, efficiency);
|
||||
TestVehicle.VehicleActor.ProcessFloatVehicleParam(Vehicle.VERTICAL_ATTRACTION_TIMESCALE, timeScale);
|
||||
TestVehicle.VehicleActor.enableAngularVerticalAttraction = true;
|
||||
|
||||
TestVehicle.IsPhysical = true;
|
||||
PhysicsScene.ProcessTaints();
|
||||
|
||||
// Step the simulator a bunch of times and vertical attraction should orient the vehicle up
|
||||
for (int ii = 0; ii < simSteps; ii++)
|
||||
BSDynamics vehicleActor = TestVehicle.GetVehicleActor();
|
||||
if (vehicleActor != null)
|
||||
{
|
||||
TestVehicle.VehicleActor.ForgetKnownVehicleProperties();
|
||||
TestVehicle.VehicleActor.ComputeAngularVerticalAttraction();
|
||||
TestVehicle.VehicleActor.PushKnownChanged();
|
||||
vehicleActor.ProcessFloatVehicleParam(Vehicle.VERTICAL_ATTRACTION_EFFICIENCY, efficiency);
|
||||
vehicleActor.ProcessFloatVehicleParam(Vehicle.VERTICAL_ATTRACTION_TIMESCALE, timeScale);
|
||||
vehicleActor.enableAngularVerticalAttraction = true;
|
||||
|
||||
PhysicsScene.Simulate(simulationTimeStep);
|
||||
TestVehicle.IsPhysical = true;
|
||||
PhysicsScene.ProcessTaints();
|
||||
|
||||
// Step the simulator a bunch of times and vertical attraction should orient the vehicle up
|
||||
for (int ii = 0; ii < simSteps; ii++)
|
||||
{
|
||||
vehicleActor.ForgetKnownVehicleProperties();
|
||||
vehicleActor.ComputeAngularVerticalAttraction();
|
||||
vehicleActor.PushKnownChanged();
|
||||
|
||||
PhysicsScene.Simulate(simulationTimeStep);
|
||||
}
|
||||
}
|
||||
|
||||
TestVehicle.IsPhysical = false;
|
||||
|
||||
@@ -2382,6 +2382,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
return force;
|
||||
}
|
||||
|
||||
public void llSetVelocity(LSL_Vector velocity, int local)
|
||||
{
|
||||
m_host.AddScriptLPS(1);
|
||||
|
||||
if (!m_host.ParentGroup.IsDeleted)
|
||||
{
|
||||
if (local != 0)
|
||||
velocity *= llGetRot();
|
||||
|
||||
m_host.ParentGroup.RootPart.Velocity = velocity;
|
||||
}
|
||||
}
|
||||
|
||||
public void llSetAngularVelocity(LSL_Vector angularVelocity, int local)
|
||||
{
|
||||
m_host.AddScriptLPS(1);
|
||||
|
||||
if (!m_host.ParentGroup.IsDeleted)
|
||||
{
|
||||
if (local != 0)
|
||||
angularVelocity *= llGetRot();
|
||||
|
||||
m_host.ParentGroup.RootPart.AngularVelocity = angularVelocity;
|
||||
}
|
||||
}
|
||||
|
||||
public LSL_Integer llTarget(LSL_Vector position, double range)
|
||||
{
|
||||
m_host.AddScriptLPS(1);
|
||||
|
||||
@@ -342,6 +342,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
|
||||
void llSetDamage(double damage);
|
||||
void llSetForce(LSL_Vector force, int local);
|
||||
void llSetForceAndTorque(LSL_Vector force, LSL_Vector torque, int local);
|
||||
void llSetVelocity(LSL_Vector velocity, int local);
|
||||
void llSetAngularVelocity(LSL_Vector angularVelocity, int local);
|
||||
void llSetHoverHeight(double height, int water, double tau);
|
||||
void llSetInventoryPermMask(string item, int mask, int value);
|
||||
void llSetLinkAlpha(int linknumber, double alpha, int face);
|
||||
|
||||
@@ -1548,6 +1548,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
|
||||
m_LSL_Functions.llSetForceAndTorque(force, torque, local);
|
||||
}
|
||||
|
||||
public void llSetVelocity(LSL_Vector force, int local)
|
||||
{
|
||||
m_LSL_Functions.llSetVelocity(force, local);
|
||||
}
|
||||
|
||||
public void llSetAngularVelocity(LSL_Vector force, int local)
|
||||
{
|
||||
m_LSL_Functions.llSetAngularVelocity(force, local);
|
||||
}
|
||||
|
||||
public void llSetHoverHeight(double height, int water, double tau)
|
||||
{
|
||||
m_LSL_Functions.llSetHoverHeight(height, water, tau);
|
||||
|
||||
@@ -185,10 +185,12 @@ namespace OpenSim.Server.Handlers.GridUser
|
||||
GridUserInfo guinfo = m_GridUserService.GetGridUserInfo(user);
|
||||
|
||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||
result["result"] = guinfo.ToKeyValuePairs();
|
||||
if (guinfo != null)
|
||||
result["result"] = guinfo.ToKeyValuePairs();
|
||||
else
|
||||
result["result"] = "null";
|
||||
|
||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
||||
|
||||
//m_log.DebugFormat("[GRID USER HANDLER]: resp string: {0}", xmlString);
|
||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ namespace OpenSim.Server.Handlers.Simulation
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.InfoFormat("[AGENT HANDLER]: method {0} not supported in agent message", method);
|
||||
m_log.InfoFormat("[AGENT HANDLER]: method {0} not supported in agent message (caller is {1})", method, Util.GetCallerIP(request));
|
||||
responsedata["int_response_code"] = HttpStatusCode.MethodNotAllowed;
|
||||
responsedata["str_response_string"] = "Method not allowed";
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
|
||||
public void PostInitialise() { }
|
||||
public void Close() { }
|
||||
|
||||
public SimianPresenceServiceConnector() { m_activityDetector = new SimianActivityDetector(this); }
|
||||
public SimianPresenceServiceConnector() { }
|
||||
public string Name { get { return "SimianPresenceServiceConnector"; } }
|
||||
public void AddRegion(Scene scene)
|
||||
{
|
||||
@@ -121,6 +121,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
|
||||
if (!serviceUrl.EndsWith("/") && !serviceUrl.EndsWith("="))
|
||||
serviceUrl = serviceUrl + '/';
|
||||
m_serverUrl = serviceUrl;
|
||||
m_activityDetector = new SimianActivityDetector(this);
|
||||
m_Enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,12 +46,28 @@ namespace OpenSim.Services.UserAccountService
|
||||
|
||||
public GridUserService(IConfigSource config) : base(config)
|
||||
{
|
||||
m_log.Debug("[USER GRID SERVICE]: Starting user grid service");
|
||||
m_log.Debug("[GRID USER SERVICE]: Starting user grid service");
|
||||
}
|
||||
|
||||
public virtual GridUserInfo GetGridUserInfo(string userID)
|
||||
{
|
||||
GridUserData d = m_Database.Get(userID);
|
||||
GridUserData d = null;
|
||||
if (userID.Length > 36) // it's a UUI
|
||||
d = m_Database.Get(userID);
|
||||
else // it's a UUID
|
||||
{
|
||||
GridUserData[] ds = m_Database.GetAll(userID);
|
||||
if (ds == null)
|
||||
return null;
|
||||
|
||||
if (ds.Length > 0)
|
||||
{
|
||||
d = ds[0];
|
||||
foreach (GridUserData dd in ds)
|
||||
if (dd.UserID.Length > d.UserID.Length) // find the longest
|
||||
d = dd;
|
||||
}
|
||||
}
|
||||
|
||||
if (d == null)
|
||||
return null;
|
||||
@@ -140,7 +156,7 @@ namespace OpenSim.Services.UserAccountService
|
||||
|
||||
public bool SetLastPosition(string userID, UUID sessionID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt)
|
||||
{
|
||||
//m_log.DebugFormat("[Grid User Service]: SetLastPosition for {0}", userID);
|
||||
m_log.DebugFormat("[GRID USER SERVICE]: SetLastPosition for {0}", userID);
|
||||
GridUserData d = m_Database.Get(userID);
|
||||
if (d == null)
|
||||
{
|
||||
|
||||
+10
-6
@@ -268,7 +268,7 @@
|
||||
; AllowedClients =
|
||||
|
||||
;# {BannedClients} {} {Bar (|) separated list of banned clients} {}
|
||||
;# Bar (|) separated list of viewers which may not gain access to the regions.
|
||||
;; Bar (|) separated list of viewers which may not gain access to the regions.
|
||||
;; One can use a Substring of the viewer name to disable only certain
|
||||
;; versions
|
||||
;; Example: Agent uses the viewer "Imprudence 1.3.2.0"
|
||||
@@ -287,7 +287,7 @@
|
||||
;; both to set this to false and comment out the [Modules] MapImageServiceModule setting in config-include/
|
||||
; GenerateMaptiles = true
|
||||
|
||||
;# {MapImageModule} [] {The map image module to use} {MapImageModule Warp3DImageModule} MapImageModule
|
||||
;# {MapImageModule} {} {The map image module to use} {MapImageModule Warp3DImageModule} MapImageModule
|
||||
;; The module to use in order to generate map images.
|
||||
;; MapImageModule is the default. Warp3DImageModule is an alternative experimental module that can
|
||||
;; generate better images.
|
||||
@@ -474,7 +474,10 @@
|
||||
;# {XmlRpcPort} {} {Port for incoming llRemoteData xmlrpc calls} {} 20800
|
||||
;XmlRpcPort = 20800
|
||||
|
||||
;# {XmlRpcHubURI} {XmlRpcRouterModule} {URI for external service used to register xmlrpc channels created in the simulator. This depends on XmlRpcRouterModule being set to XmlRpcGridRouterModule} http://example.com
|
||||
|
||||
;; {option} {depends on} {question to ask} {choices} default value
|
||||
|
||||
;# {XmlRpcHubURI} {XmlRpcRouterModule} {URI for external service used to register xmlrpc channels created in the simulator. This depends on XmlRpcRouterModule being set to XmlRpcGridRouterModule} {} http://example.com
|
||||
;; If XmlRpcRouterModule is set to XmlRpcGridRouterModule, the simulator
|
||||
;; will use this address to register xmlrpc channels on the external
|
||||
;; service
|
||||
@@ -538,7 +541,7 @@
|
||||
;; Distance in meters that ordinary chat should travel.
|
||||
; say_distance = 20
|
||||
|
||||
;# {shout_distance} {Distance at which a shout is heard, in meters?} {} 100
|
||||
;# {shout_distance} {} {Distance at which a shout is heard, in meters?} {} 100
|
||||
;; Distance in meters that shouts should travel.
|
||||
; shout_distance = 100
|
||||
|
||||
@@ -613,7 +616,8 @@
|
||||
;; the "password" parameter)
|
||||
; access_password = ""
|
||||
|
||||
;# List the IP addresses allowed to call RemoteAdmin
|
||||
;# {access_ip_addresses} {enabled:true} {List the IP addresses allowed to call RemoteAdmin?} {}
|
||||
;; List the IP addresses allowed to call RemoteAdmin
|
||||
;; If access_ip_addresses isn't set, then all IP addresses can access RemoteAdmin.
|
||||
;; access_ip_addresses = 0.0.0.0, 0.0.0.0 ...
|
||||
; access_ip_addresses =
|
||||
@@ -798,7 +802,7 @@
|
||||
; ScriptStopStrategy = abort
|
||||
|
||||
|
||||
;# {DeleteScriptsOnStartup} {} {Delete previously compiled script DLLs on startup?} (true false) true
|
||||
;# {DeleteScriptsOnStartup} {} {Delete previously compiled script DLLs on startup?} {true false} true
|
||||
;; Controls whether previously compiled scripts DLLs are deleted on sim restart. If you set this to false
|
||||
;; then startup will be considerably faster since scripts won't need to be recompiled. However, then it becomes your responsibility to delete the
|
||||
;; compiled scripts if you're recompiling OpenSim from source code and internal interfaces used
|
||||
|
||||
+37
-19
@@ -919,54 +919,72 @@
|
||||
; ## Joint support
|
||||
; ##
|
||||
|
||||
; if you would like physics joints to be enabled through a special naming convention in the client, set this to true.
|
||||
; (see NINJA Physics documentation, http://opensimulator.org/wiki/NINJA_Physics)
|
||||
; default is false
|
||||
; If you would like physics joints to be enabled through a special naming
|
||||
; convention in the client, set this to true.
|
||||
; (See NINJA Physics documentation, http://opensimulator.org/wiki/NINJA_Physics)
|
||||
; Default is false
|
||||
;use_NINJA_physics_joints = true
|
||||
|
||||
; ##
|
||||
; ## additional meshing options
|
||||
; ##
|
||||
|
||||
; physical collision mesh proxies are normally created for complex prim shapes, and collisions for simple boxes and
|
||||
; spheres are computed algorithmically. If you would rather have mesh proxies for simple prims, you can set this to
|
||||
; true. Note that this will increase memory usage and region startup time. Default is false.
|
||||
; Physical collision mesh proxies are normally created for complex prim shapes,
|
||||
; and collisions for simple boxes and spheres are computed algorithmically.
|
||||
; If you would rather have mesh proxies for simple prims, you can set this to
|
||||
; true. Note that this will increase memory usage and region startup time.
|
||||
; Default is false.
|
||||
;force_simple_prim_meshing = true
|
||||
|
||||
[BulletSim]
|
||||
; All the BulletSim parameters can be displayed with the console command "physics get all"
|
||||
; and all are defined in the source file OpenSim/Regions/Physics/BulletSPlugin/BSParam.cs.
|
||||
; All the BulletSim parameters can be displayed with the console command
|
||||
; "physics get all" and all are defined in the source file
|
||||
; OpenSim/Regions/Physics/BulletSPlugin/BSParam.cs.
|
||||
|
||||
; There are two bullet physics libraries, bulletunmanaged is the default and is a native c++ dll
|
||||
; bulletxna is a managed C# dll. They have comparible functionality but the c++ one is much faster.
|
||||
; There are two bullet physics libraries, bulletunmanaged is the default and is a
|
||||
; native c++ dll bulletxna is a managed C# dll. They have comparible functionality
|
||||
; but the c++ one is much faster.
|
||||
BulletEngine = "bulletunmanaged"
|
||||
; BulletEngine = "bulletxna"
|
||||
|
||||
; Terrain Implementation
|
||||
TerrainImplementation = 1 ; 0=Heightfield, 1=mesh
|
||||
; For mesh terrain, the detail of the created mesh. '1' gives 256x256 (heightfield resolution). '2'
|
||||
; gives 512x512. Etc. Cannot be larger than '4'. Higher magnification uses lots of memory.
|
||||
; BulletSim can run on its own thread independent of the simulator's heartbeat
|
||||
; thread. Enabling this will nto let the physics engine slow down avatar movement, etc.
|
||||
UseSeparatePhysicsThread = false
|
||||
|
||||
; Terrain implementation can use either Bullet's heightField or BulletSim can build
|
||||
; a mesh. 0=heightField, 1=mesh
|
||||
TerrainImplementation = 1
|
||||
; For mesh terrain, the detail of the created mesh. '1' gives 256x256 (heightfield
|
||||
; resolution). '2' gives 512x512. Etc. Cannot be larger than '4'. Higher
|
||||
; magnification uses lots of memory.
|
||||
TerrainMeshMagnification = 2
|
||||
|
||||
; Avatar physics height adjustments. http://opensimulator.org/wiki/BulletSim#Adjusting_Avatar_Height
|
||||
; Avatar physics height adjustments.
|
||||
; http://opensimulator.org/wiki/BulletSim#Adjusting_Avatar_Height
|
||||
AvatarHeightLowFudge = -0.2 ; Adjustment at low end of height range
|
||||
AvatarHeightMidFudge = 0.1 ; Adjustment at mid point of avatar height range
|
||||
AvatarHeightHighFudge = 0.1 ; Adjustment at high end of height range
|
||||
|
||||
; Default linkset implmentation
|
||||
; 'Constraint' uses physics constraints to hold linkset together. 'Compound' builds a compound
|
||||
; shape from the children shapes to create a single physical shape. 'Compound' uses a lot less CPU time.
|
||||
; 'Constraint' uses physics constraints to hold linkset together. 'Compound'
|
||||
; builds a compound shape from the children shapes to create a single physical
|
||||
; shape. 'Compound' uses a lot less CPU time.
|
||||
LinkImplementation = 1 ; 0=constraint, 1=compound
|
||||
|
||||
; If 'true', offset a linkset's origin based on mass of linkset parts.
|
||||
LinksetOffsetCenterOfMass = false
|
||||
|
||||
; If 'true', turn scuplties into meshes
|
||||
MeshSculptedPrim = true
|
||||
|
||||
; If 'true', force simple prims (box and sphere) to be meshed
|
||||
; If 'false', the Bullet native special case shape is used for square rectangles and even dimensioned spheres
|
||||
; If 'false', the Bullet native special case shape is used for square rectangles
|
||||
; and even dimensioned spheres.
|
||||
ForceSimplePrimMeshing = false
|
||||
|
||||
; If 'true', when creating meshes, remove all triangles that have two equal vertexes.
|
||||
; Happens often in sculpties. If turned off, there will be some doorways that cannot be walked through.
|
||||
; Happens often in sculpties. If turned off, there will be some doorways
|
||||
; that cannot be walked through.
|
||||
ShouldRemoveZeroWidthTriangles = true
|
||||
|
||||
; If 'true', use convex hull definition in mesh asset if present.
|
||||
|
||||
@@ -1482,6 +1482,7 @@
|
||||
<Reference name="System.Drawing"/>
|
||||
<Reference name="System.Xml"/>
|
||||
<Reference name="System.Web"/>
|
||||
<Reference name="NDesk.Options" path="../../../../../bin/"/>
|
||||
<Reference name="OpenMetaverseTypes" path="../../../../../bin/"/>
|
||||
<Reference name="OpenMetaverse.StructuredData" path="../../../../../bin/"/>
|
||||
<Reference name="OpenMetaverse" path="../../../../../bin/"/>
|
||||
@@ -3195,6 +3196,7 @@
|
||||
<Reference name="System.Runtime.Remoting"/>
|
||||
<Reference name="OpenMetaverseTypes" path="../../../bin/"/>
|
||||
<Reference name="OpenMetaverse" path="../../../bin/"/>
|
||||
<Reference name="OpenSim.Capabilities"/>
|
||||
<Reference name="OpenSim.Data"/>
|
||||
<Reference name="OpenSim.Framework"/>
|
||||
<Reference name="OpenSim.Framework.Communications"/>
|
||||
|
||||
Reference in New Issue
Block a user