aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
authorMelanie2013-05-08 20:59:44 +0100
committerMelanie2013-05-08 20:59:44 +0100
commitbda45650674eba7d69bbc262ebc28f2c5c184623 (patch)
tree43fae3ed56116a8d6c941f011fa8f358c1295442 /OpenSim/Region
parentMerge branch 'master' into careminster (diff)
parentDelete "" entry for AvatarPicker cap. (diff)
downloadopensim-SC-bda45650674eba7d69bbc262ebc28f2c5c184623.zip
opensim-SC-bda45650674eba7d69bbc262ebc28f2c5c184623.tar.gz
opensim-SC-bda45650674eba7d69bbc262ebc28f2c5c184623.tar.bz2
opensim-SC-bda45650674eba7d69bbc262ebc28f2c5c184623.tar.xz
Merge branch 'master' into careminster
Conflicts: OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/AvatarPickerSearchModule.cs140
-rw-r--r--OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs72
-rw-r--r--OpenSim/Region/CoreModules/World/Estate/XEstateConnector.cs215
-rw-r--r--OpenSim/Region/CoreModules/World/Estate/XEstateModule.cs254
-rw-r--r--OpenSim/Region/CoreModules/World/Estate/XEstateRequestHandler.cs298
-rw-r--r--OpenSim/Region/Framework/Interfaces/IEstateModule.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs2
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs16
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs14
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSShapes.cs45
11 files changed, 1002 insertions, 58 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/AvatarPickerSearchModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/AvatarPickerSearchModule.cs
new file mode 100644
index 0000000..d7af1f2
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/Caps/AvatarPickerSearchModule.cs
@@ -0,0 +1,140 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Specialized;
31using System.Drawing;
32using System.Drawing.Imaging;
33using System.Reflection;
34using System.IO;
35using System.Web;
36using log4net;
37using Nini.Config;
38using Mono.Addins;
39using OpenMetaverse;
40using OpenMetaverse.StructuredData;
41using OpenSim.Framework;
42using OpenSim.Framework.Servers;
43using OpenSim.Framework.Servers.HttpServer;
44using OpenSim.Region.Framework.Interfaces;
45using OpenSim.Region.Framework.Scenes;
46using OpenSim.Services.Interfaces;
47using Caps = OpenSim.Framework.Capabilities.Caps;
48using OpenSim.Capabilities.Handlers;
49
50namespace OpenSim.Region.ClientStack.Linden
51{
52
53 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "AvatarPickerSearchModule")]
54 public class AvatarPickerSearchModule : INonSharedRegionModule
55 {
56 private static readonly ILog m_log =
57 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
58
59 private Scene m_scene;
60 private IPeople m_People;
61 private bool m_Enabled = false;
62
63 private string m_URL;
64
65 #region ISharedRegionModule Members
66
67 public void Initialise(IConfigSource source)
68 {
69 IConfig config = source.Configs["ClientStack.LindenCaps"];
70 if (config == null)
71 return;
72
73 m_URL = config.GetString("Cap_AvatarPickerSearch", string.Empty);
74 m_log.DebugFormat("[XXX]: Cap_AvatarPickerSearch = {0}", m_URL);
75 // Cap doesn't exist
76 if (m_URL != string.Empty)
77 m_Enabled = true;
78 }
79
80 public void AddRegion(Scene s)
81 {
82 if (!m_Enabled)
83 return;
84
85 m_scene = s;
86 }
87
88 public void RemoveRegion(Scene s)
89 {
90 if (!m_Enabled)
91 return;
92
93 m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
94 m_scene = null;
95 }
96
97 public void RegionLoaded(Scene s)
98 {
99 if (!m_Enabled)
100 return;
101
102 m_People = m_scene.RequestModuleInterface<IPeople>();
103 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
104 }
105
106 public void PostInitialise()
107 {
108 }
109
110 public void Close() { }
111
112 public string Name { get { return "AvatarPickerSearchModule"; } }
113
114 public Type ReplaceableInterface
115 {
116 get { return null; }
117 }
118
119 #endregion
120
121 public void RegisterCaps(UUID agentID, Caps caps)
122 {
123 UUID capID = UUID.Random();
124
125 if (m_URL == "localhost")
126 {
127 m_log.DebugFormat("[AVATAR PICKER SEARCH]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
128 caps.RegisterHandler(
129 "AvatarPickerSearch",
130 new AvatarPickerSearchHandler("/CAPS/" + capID + "/", m_People, "AvatarPickerSearch", "Search for avatars by name"));
131 }
132 else
133 {
134 // m_log.DebugFormat("[AVATAR PICKER SEARCH]: {0} in region {1}", m_URL, m_scene.RegionInfo.RegionName);
135 caps.RegisterHandler("AvatarPickerSearch", m_URL);
136 }
137 }
138
139 }
140}
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs
index 8ce20e9..fac93e6 100644
--- a/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs
@@ -70,7 +70,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
70 70
71 #endregion ISharedRegionModule 71 #endregion ISharedRegionModule
72 72
73 protected override void AddAdditionalUsers(UUID avatarID, string query, List<UserData> users) 73 protected override void AddAdditionalUsers(string query, List<UserData> users)
74 { 74 {
75 if (query.Contains("@")) // First.Last@foo.com, maybe? 75 if (query.Contains("@")) // First.Last@foo.com, maybe?
76 { 76 {
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
index 7b823ba..6847e57 100644
--- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
@@ -46,17 +46,8 @@ using Mono.Addins;
46 46
47namespace OpenSim.Region.CoreModules.Framework.UserManagement 47namespace OpenSim.Region.CoreModules.Framework.UserManagement
48{ 48{
49 public class UserData
50 {
51 public UUID Id { get; set; }
52 public string FirstName { get; set; }
53 public string LastName { get; set; }
54 public string HomeURL { get; set; }
55 public Dictionary<string, object> ServerURLs { get; set; }
56 }
57
58 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "UserManagementModule")] 49 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "UserManagementModule")]
59 public class UserManagementModule : ISharedRegionModule, IUserManagement 50 public class UserManagementModule : ISharedRegionModule, IUserManagement, IPeople
60 { 51 {
61 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 52 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
62 53
@@ -101,6 +92,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
101 m_Scenes.Add(scene); 92 m_Scenes.Add(scene);
102 93
103 scene.RegisterModuleInterface<IUserManagement>(this); 94 scene.RegisterModuleInterface<IUserManagement>(this);
95 scene.RegisterModuleInterface<IPeople>(this);
104 scene.EventManager.OnNewClient += new EventManager.OnNewClientDelegate(EventManager_OnNewClient); 96 scene.EventManager.OnNewClient += new EventManager.OnNewClientDelegate(EventManager_OnNewClient);
105 scene.EventManager.OnPrimsLoaded += new EventManager.PrimsLoaded(EventManager_OnPrimsLoaded); 97 scene.EventManager.OnPrimsLoaded += new EventManager.PrimsLoaded(EventManager_OnPrimsLoaded);
106 } 98 }
@@ -181,29 +173,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
181 173
182 m_log.DebugFormat("[USER MANAGEMENT MODULE]: HandleAvatarPickerRequest for {0}", query); 174 m_log.DebugFormat("[USER MANAGEMENT MODULE]: HandleAvatarPickerRequest for {0}", query);
183 175
184 // searhc the user accounts service 176 List<UserData> users = GetUserData(query, 500, 1);
185 List<UserAccount> accs = m_Scenes[0].UserAccountService.GetUserAccounts(m_Scenes[0].RegionInfo.ScopeID, query);
186
187 List<UserData> users = new List<UserData>();
188 if (accs != null)
189 {
190 foreach (UserAccount acc in accs)
191 {
192 UserData ud = new UserData();
193 ud.FirstName = acc.FirstName;
194 ud.LastName = acc.LastName;
195 ud.Id = acc.PrincipalID;
196 users.Add(ud);
197 }
198 }
199
200 // search the local cache
201 foreach (UserData data in m_UserCache.Values)
202 if (users.Find(delegate(UserData d) { return d.Id == data.Id; }) == null &&
203 (data.FirstName.ToLower().StartsWith(query.ToLower()) || data.LastName.ToLower().StartsWith(query.ToLower())))
204 users.Add(data);
205
206 AddAdditionalUsers(avatarID, query, users);
207 177
208 AvatarPickerReplyPacket replyPacket = (AvatarPickerReplyPacket)PacketPool.Instance.GetPacket(PacketType.AvatarPickerReply); 178 AvatarPickerReplyPacket replyPacket = (AvatarPickerReplyPacket)PacketPool.Instance.GetPacket(PacketType.AvatarPickerReply);
209 // TODO: don't create new blocks if recycling an old packet 179 // TODO: don't create new blocks if recycling an old packet
@@ -249,12 +219,46 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
249 client.SendAvatarPickerReply(agent_data, data_args); 219 client.SendAvatarPickerReply(agent_data, data_args);
250 } 220 }
251 221
252 protected virtual void AddAdditionalUsers(UUID avatarID, string query, List<UserData> users) 222 protected virtual void AddAdditionalUsers(string query, List<UserData> users)
253 { 223 {
254 } 224 }
255 225
256 #endregion Event Handlers 226 #endregion Event Handlers
257 227
228 #region IPeople
229
230 public List<UserData> GetUserData(string query, int page_size, int page_number)
231 {
232 // search the user accounts service
233 List<UserAccount> accs = m_Scenes[0].UserAccountService.GetUserAccounts(m_Scenes[0].RegionInfo.ScopeID, query);
234
235 List<UserData> users = new List<UserData>();
236 if (accs != null)
237 {
238 foreach (UserAccount acc in accs)
239 {
240 UserData ud = new UserData();
241 ud.FirstName = acc.FirstName;
242 ud.LastName = acc.LastName;
243 ud.Id = acc.PrincipalID;
244 users.Add(ud);
245 }
246 }
247
248 // search the local cache
249 foreach (UserData data in m_UserCache.Values)
250 if (users.Find(delegate(UserData d) { return d.Id == data.Id; }) == null &&
251 (data.FirstName.ToLower().StartsWith(query.ToLower()) || data.LastName.ToLower().StartsWith(query.ToLower())))
252 users.Add(data);
253
254 AddAdditionalUsers(query, users);
255
256 return users;
257
258 }
259
260 #endregion IPeople
261
258 private void CacheCreators(SceneObjectGroup sog) 262 private void CacheCreators(SceneObjectGroup sog)
259 { 263 {
260 //m_log.DebugFormat("[USER MANAGEMENT MODULE]: processing {0} {1}; {2}", sog.RootPart.Name, sog.RootPart.CreatorData, sog.RootPart.CreatorIdentification); 264 //m_log.DebugFormat("[USER MANAGEMENT MODULE]: processing {0} {1}; {2}", sog.RootPart.Name, sog.RootPart.CreatorData, sog.RootPart.CreatorIdentification);
diff --git a/OpenSim/Region/CoreModules/World/Estate/XEstateConnector.cs b/OpenSim/Region/CoreModules/World/Estate/XEstateConnector.cs
new file mode 100644
index 0000000..948c893
--- /dev/null
+++ b/OpenSim/Region/CoreModules/World/Estate/XEstateConnector.cs
@@ -0,0 +1,215 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31
32using OpenSim.Services.Interfaces;
33using GridRegion = OpenSim.Services.Interfaces.GridRegion;
34using OpenSim.Server.Base;
35using OpenSim.Framework.Servers.HttpServer;
36using OpenSim.Framework;
37using OpenSim.Region.Framework.Scenes;
38
39using OpenMetaverse;
40using log4net;
41
42namespace OpenSim.Region.CoreModules.World.Estate
43{
44 public class EstateConnector
45 {
46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47
48 protected XEstateModule m_EstateModule;
49
50 public EstateConnector(XEstateModule module)
51 {
52 m_EstateModule = module;
53 }
54
55 public void SendTeleportHomeOneUser(uint EstateID, UUID PreyID)
56 {
57 Dictionary<string, object> sendData = new Dictionary<string, object>();
58 sendData["METHOD"] = "teleport_home_one_user";
59
60 sendData["EstateID"] = EstateID.ToString();
61 sendData["PreyID"] = PreyID.ToString();
62
63 SendToEstate(EstateID, sendData);
64 }
65
66 public void SendTeleportHomeAllUsers(uint EstateID)
67 {
68 Dictionary<string, object> sendData = new Dictionary<string, object>();
69 sendData["METHOD"] = "teleport_home_all_users";
70
71 sendData["EstateID"] = EstateID.ToString();
72
73 SendToEstate(EstateID, sendData);
74 }
75
76 public bool SendUpdateCovenant(uint EstateID, UUID CovenantID)
77 {
78 Dictionary<string, object> sendData = new Dictionary<string, object>();
79 sendData["METHOD"] = "update_covenant";
80
81 sendData["CovenantID"] = CovenantID.ToString();
82 sendData["EstateID"] = EstateID.ToString();
83
84 // Handle local regions locally
85 //
86 foreach (Scene s in m_EstateModule.Scenes)
87 {
88 if (s.RegionInfo.EstateSettings.EstateID == EstateID)
89 s.RegionInfo.RegionSettings.Covenant = CovenantID;
90// s.ReloadEstateData();
91 }
92
93 SendToEstate(EstateID, sendData);
94
95 return true;
96 }
97
98 public bool SendUpdateEstate(uint EstateID)
99 {
100 Dictionary<string, object> sendData = new Dictionary<string, object>();
101 sendData["METHOD"] = "update_estate";
102
103 sendData["EstateID"] = EstateID.ToString();
104
105 // Handle local regions locally
106 //
107 foreach (Scene s in m_EstateModule.Scenes)
108 {
109 if (s.RegionInfo.EstateSettings.EstateID == EstateID)
110 s.ReloadEstateData();
111 }
112
113 SendToEstate(EstateID, sendData);
114
115 return true;
116 }
117
118 public void SendEstateMessage(uint EstateID, UUID FromID, string FromName, string Message)
119 {
120 Dictionary<string, object> sendData = new Dictionary<string, object>();
121 sendData["METHOD"] = "estate_message";
122
123 sendData["EstateID"] = EstateID.ToString();
124 sendData["FromID"] = FromID.ToString();
125 sendData["FromName"] = FromName;
126 sendData["Message"] = Message;
127
128 SendToEstate(EstateID, sendData);
129 }
130
131 private void SendToEstate(uint EstateID, Dictionary<string, object> sendData)
132 {
133 List<UUID> regions = m_EstateModule.Scenes[0].GetEstateRegions((int)EstateID);
134
135 UUID ScopeID = UUID.Zero;
136
137 // Handle local regions locally
138 //
139 foreach (Scene s in m_EstateModule.Scenes)
140 {
141 if (regions.Contains(s.RegionInfo.RegionID))
142 {
143 // All regions in one estate are in the same scope.
144 // Use that scope.
145 //
146 ScopeID = s.RegionInfo.ScopeID;
147 regions.Remove(s.RegionInfo.RegionID);
148 }
149 }
150
151 // Our own region should always be in the above list.
152 // In a standalone this would not be true. But then,
153 // Scope ID is not relevat there. Use first scope.
154 //
155 if (ScopeID == UUID.Zero)
156 ScopeID = m_EstateModule.Scenes[0].RegionInfo.ScopeID;
157
158 // Don't send to the same instance twice
159 //
160 List<string> done = new List<string>();
161
162 // Send to remote regions
163 //
164 foreach (UUID regionID in regions)
165 {
166 GridRegion region = m_EstateModule.Scenes[0].GridService.GetRegionByUUID(ScopeID, regionID);
167 if (region != null)
168 {
169 string url = "http://" + region.ExternalHostName + ":" + region.HttpPort;
170 if (done.Contains(url))
171 continue;
172
173 Call(region, sendData);
174 done.Add(url);
175 }
176 }
177 }
178
179 private bool Call(GridRegion region, Dictionary<string, object> sendData)
180 {
181 string reqString = ServerUtils.BuildQueryString(sendData);
182 // m_log.DebugFormat("[XESTATE CONNECTOR]: queryString = {0}", reqString);
183 try
184 {
185 string url = "http://" + region.ExternalHostName + ":" + region.HttpPort;
186 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
187 url + "/estate",
188 reqString);
189 if (reply != string.Empty)
190 {
191 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
192
193 if (replyData.ContainsKey("RESULT"))
194 {
195 if (replyData["RESULT"].ToString().ToLower() == "true")
196 return true;
197 else
198 return false;
199 }
200 else
201 m_log.DebugFormat("[XESTATE CONNECTOR]: reply data does not contain result field");
202
203 }
204 else
205 m_log.DebugFormat("[XESTATE CONNECTOR]: received empty reply");
206 }
207 catch (Exception e)
208 {
209 m_log.DebugFormat("[XESTATE CONNECTOR]: Exception when contacting remote sim: {0}", e.Message);
210 }
211
212 return false;
213 }
214 }
215}
diff --git a/OpenSim/Region/CoreModules/World/Estate/XEstateModule.cs b/OpenSim/Region/CoreModules/World/Estate/XEstateModule.cs
new file mode 100644
index 0000000..1f099c6
--- /dev/null
+++ b/OpenSim/Region/CoreModules/World/Estate/XEstateModule.cs
@@ -0,0 +1,254 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Reflection;
32using log4net;
33using Nini.Config;
34using Nwc.XmlRpc;
35using OpenMetaverse;
36using OpenSim.Framework;
37using OpenSim.Framework.Communications;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Services.Interfaces;
41using OpenSim.Server.Base;
42using OpenSim.Framework.Servers;
43using OpenSim.Framework.Servers.HttpServer;
44using Mono.Addins;
45
46namespace OpenSim.Region.CoreModules.World.Estate
47{
48 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "XEstate")]
49 public class XEstateModule : ISharedRegionModule
50 {
51 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
52
53 protected List<Scene> m_Scenes = new List<Scene>();
54 protected bool m_InInfoUpdate = false;
55
56 public bool InInfoUpdate
57 {
58 get { return m_InInfoUpdate; }
59 set { m_InInfoUpdate = value; }
60 }
61
62 public List<Scene> Scenes
63 {
64 get { return m_Scenes; }
65 }
66
67 protected EstateConnector m_EstateConnector;
68
69 public void Initialise(IConfigSource config)
70 {
71 int port = 0;
72
73 IConfig estateConfig = config.Configs["Estate"];
74 if (estateConfig != null)
75 {
76 port = estateConfig.GetInt("Port", 0);
77 }
78
79 m_EstateConnector = new EstateConnector(this);
80
81 // Instantiate the request handler
82 IHttpServer server = MainServer.GetHttpServer((uint)port);
83 server.AddStreamHandler(new EstateRequestHandler(this));
84 }
85
86 public void PostInitialise()
87 {
88 }
89
90 public void Close()
91 {
92 }
93
94 public void AddRegion(Scene scene)
95 {
96 m_Scenes.Add(scene);
97
98 scene.EventManager.OnNewClient += OnNewClient;
99 }
100
101 public void RegionLoaded(Scene scene)
102 {
103 IEstateModule em = scene.RequestModuleInterface<IEstateModule>();
104
105 em.OnRegionInfoChange += OnRegionInfoChange;
106 em.OnEstateInfoChange += OnEstateInfoChange;
107 em.OnEstateMessage += OnEstateMessage;
108 }
109
110 public void RemoveRegion(Scene scene)
111 {
112 scene.EventManager.OnNewClient -= OnNewClient;
113
114 m_Scenes.Remove(scene);
115 }
116
117 public string Name
118 {
119 get { return "EstateModule"; }
120 }
121
122 public Type ReplaceableInterface
123 {
124 get { return null; }
125 }
126
127 private Scene FindScene(UUID RegionID)
128 {
129 foreach (Scene s in Scenes)
130 {
131 if (s.RegionInfo.RegionID == RegionID)
132 return s;
133 }
134
135 return null;
136 }
137
138 private void OnRegionInfoChange(UUID RegionID)
139 {
140 Scene s = FindScene(RegionID);
141 if (s == null)
142 return;
143
144 if (!m_InInfoUpdate)
145 m_EstateConnector.SendUpdateCovenant(s.RegionInfo.EstateSettings.EstateID, s.RegionInfo.RegionSettings.Covenant);
146 }
147
148 private void OnEstateInfoChange(UUID RegionID)
149 {
150 Scene s = FindScene(RegionID);
151 if (s == null)
152 return;
153
154 if (!m_InInfoUpdate)
155 m_EstateConnector.SendUpdateEstate(s.RegionInfo.EstateSettings.EstateID);
156 }
157
158 private void OnEstateMessage(UUID RegionID, UUID FromID, string FromName, string Message)
159 {
160 Scene senderScenes = FindScene(RegionID);
161 if (senderScenes == null)
162 return;
163
164 uint estateID = senderScenes.RegionInfo.EstateSettings.EstateID;
165
166 foreach (Scene s in Scenes)
167 {
168 if (s.RegionInfo.EstateSettings.EstateID == estateID)
169 {
170 IDialogModule dm = s.RequestModuleInterface<IDialogModule>();
171
172 if (dm != null)
173 {
174 dm.SendNotificationToUsersInRegion(FromID, FromName,
175 Message);
176 }
177 }
178 }
179 if (!m_InInfoUpdate)
180 m_EstateConnector.SendEstateMessage(estateID, FromID, FromName, Message);
181 }
182
183 private void OnNewClient(IClientAPI client)
184 {
185 client.OnEstateTeleportOneUserHomeRequest += OnEstateTeleportOneUserHomeRequest;
186 client.OnEstateTeleportAllUsersHomeRequest += OnEstateTeleportAllUsersHomeRequest;
187
188 }
189
190 private void OnEstateTeleportOneUserHomeRequest(IClientAPI client, UUID invoice, UUID senderID, UUID prey)
191 {
192 if (prey == UUID.Zero)
193 return;
194
195 if (!(client.Scene is Scene))
196 return;
197
198 Scene scene = (Scene)client.Scene;
199
200 uint estateID = scene.RegionInfo.EstateSettings.EstateID;
201
202 if (!scene.Permissions.CanIssueEstateCommand(client.AgentId, false))
203 return;
204
205 foreach (Scene s in Scenes)
206 {
207 if (s == scene)
208 continue; // Already handles by estate module
209 if (s.RegionInfo.EstateSettings.EstateID != estateID)
210 continue;
211
212 ScenePresence p = scene.GetScenePresence(prey);
213 if (p != null && !p.IsChildAgent)
214 {
215 p.ControllingClient.SendTeleportStart(16);
216 scene.TeleportClientHome(prey, p.ControllingClient);
217 }
218 }
219
220 m_EstateConnector.SendTeleportHomeOneUser(estateID, prey);
221 }
222
223 private void OnEstateTeleportAllUsersHomeRequest(IClientAPI client, UUID invoice, UUID senderID)
224 {
225 if (!(client.Scene is Scene))
226 return;
227
228 Scene scene = (Scene)client.Scene;
229
230 uint estateID = scene.RegionInfo.EstateSettings.EstateID;
231
232 if (!scene.Permissions.CanIssueEstateCommand(client.AgentId, false))
233 return;
234
235 foreach (Scene s in Scenes)
236 {
237 if (s == scene)
238 continue; // Already handles by estate module
239 if (s.RegionInfo.EstateSettings.EstateID != estateID)
240 continue;
241
242 scene.ForEachScenePresence(delegate(ScenePresence p) {
243 if (p != null && !p.IsChildAgent)
244 {
245 p.ControllingClient.SendTeleportStart(16);
246 scene.TeleportClientHome(p.ControllingClient.AgentId, p.ControllingClient);
247 }
248 });
249 }
250
251 m_EstateConnector.SendTeleportHomeAllUsers(estateID);
252 }
253 }
254}
diff --git a/OpenSim/Region/CoreModules/World/Estate/XEstateRequestHandler.cs b/OpenSim/Region/CoreModules/World/Estate/XEstateRequestHandler.cs
new file mode 100644
index 0000000..eb74cda
--- /dev/null
+++ b/OpenSim/Region/CoreModules/World/Estate/XEstateRequestHandler.cs
@@ -0,0 +1,298 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.IO;
31using System.Reflection;
32using System.Xml;
33
34using OpenSim.Framework;
35using OpenSim.Server.Base;
36using OpenSim.Framework.Servers.HttpServer;
37using OpenSim.Region.Framework.Scenes;
38using OpenSim.Region.Framework.Interfaces;
39
40using OpenMetaverse;
41using log4net;
42
43namespace OpenSim.Region.CoreModules.World.Estate
44{
45 public class EstateRequestHandler : BaseStreamHandler
46 {
47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
48
49 protected XEstateModule m_EstateModule;
50 protected Object m_RequestLock = new Object();
51
52 public EstateRequestHandler(XEstateModule fmodule)
53 : base("POST", "/estate")
54 {
55 m_EstateModule = fmodule;
56 }
57
58 public override byte[] Handle(string path, Stream requestData,
59 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
60 {
61 StreamReader sr = new StreamReader(requestData);
62 string body = sr.ReadToEnd();
63 sr.Close();
64 body = body.Trim();
65
66 m_log.DebugFormat("[XESTATE HANDLER]: query String: {0}", body);
67
68 try
69 {
70 lock (m_RequestLock)
71 {
72 Dictionary<string, object> request =
73 ServerUtils.ParseQueryString(body);
74
75 if (!request.ContainsKey("METHOD"))
76 return FailureResult();
77
78 string method = request["METHOD"].ToString();
79 request.Remove("METHOD");
80
81 try
82 {
83 m_EstateModule.InInfoUpdate = false;
84
85 switch (method)
86 {
87 case "update_covenant":
88 return UpdateCovenant(request);
89 case "update_estate":
90 return UpdateEstate(request);
91 case "estate_message":
92 return EstateMessage(request);
93 case "teleport_home_one_user":
94 return TeleportHomeOneUser(request);
95 case "teleport_home_all_users":
96 return TeleportHomeAllUsers(request);
97 }
98 }
99 finally
100 {
101 m_EstateModule.InInfoUpdate = false;
102 }
103 }
104 }
105 catch (Exception e)
106 {
107 m_log.Debug("[XESTATE]: Exception {0}" + e.ToString());
108 }
109
110 return FailureResult();
111 }
112
113 byte[] TeleportHomeAllUsers(Dictionary<string, object> request)
114 {
115 UUID PreyID = UUID.Zero;
116 int EstateID = 0;
117
118 if (!request.ContainsKey("EstateID"))
119 return FailureResult();
120
121 if (!Int32.TryParse(request["EstateID"].ToString(), out EstateID))
122 return FailureResult();
123
124 foreach (Scene s in m_EstateModule.Scenes)
125 {
126 if (s.RegionInfo.EstateSettings.EstateID == EstateID)
127 {
128 s.ForEachScenePresence(delegate(ScenePresence p) {
129 if (p != null && !p.IsChildAgent)
130 {
131 p.ControllingClient.SendTeleportStart(16);
132 s.TeleportClientHome(p.ControllingClient.AgentId, p.ControllingClient);
133 }
134 });
135 }
136 }
137
138 return SuccessResult();
139 }
140
141 byte[] TeleportHomeOneUser(Dictionary<string, object> request)
142 {
143 UUID PreyID = UUID.Zero;
144 int EstateID = 0;
145
146 if (!request.ContainsKey("PreyID") ||
147 !request.ContainsKey("EstateID"))
148 {
149 return FailureResult();
150 }
151
152 if (!UUID.TryParse(request["PreyID"].ToString(), out PreyID))
153 return FailureResult();
154
155 if (!Int32.TryParse(request["EstateID"].ToString(), out EstateID))
156 return FailureResult();
157
158 foreach (Scene s in m_EstateModule.Scenes)
159 {
160 if (s.RegionInfo.EstateSettings.EstateID == EstateID)
161 {
162 ScenePresence p = s.GetScenePresence(PreyID);
163 if (p != null && !p.IsChildAgent)
164 {
165 p.ControllingClient.SendTeleportStart(16);
166 s.TeleportClientHome(PreyID, p.ControllingClient);
167 }
168 }
169 }
170
171 return SuccessResult();
172 }
173
174 byte[] EstateMessage(Dictionary<string, object> request)
175 {
176 UUID FromID = UUID.Zero;
177 string FromName = String.Empty;
178 string Message = String.Empty;
179 int EstateID = 0;
180
181 if (!request.ContainsKey("FromID") ||
182 !request.ContainsKey("FromName") ||
183 !request.ContainsKey("Message") ||
184 !request.ContainsKey("EstateID"))
185 {
186 return FailureResult();
187 }
188
189 if (!UUID.TryParse(request["FromID"].ToString(), out FromID))
190 return FailureResult();
191
192 if (!Int32.TryParse(request["EstateID"].ToString(), out EstateID))
193 return FailureResult();
194
195 FromName = request["FromName"].ToString();
196 Message = request["Message"].ToString();
197
198 foreach (Scene s in m_EstateModule.Scenes)
199 {
200 if (s.RegionInfo.EstateSettings.EstateID == EstateID)
201 {
202 IDialogModule dm = s.RequestModuleInterface<IDialogModule>();
203
204 if (dm != null)
205 {
206 dm.SendNotificationToUsersInRegion(FromID, FromName,
207 Message);
208 }
209 }
210 }
211
212 return SuccessResult();
213 }
214
215 byte[] UpdateCovenant(Dictionary<string, object> request)
216 {
217 UUID CovenantID = UUID.Zero;
218 int EstateID = 0;
219
220 if (!request.ContainsKey("CovenantID") || !request.ContainsKey("EstateID"))
221 return FailureResult();
222
223 if (!UUID.TryParse(request["CovenantID"].ToString(), out CovenantID))
224 return FailureResult();
225
226 if (!Int32.TryParse(request["EstateID"].ToString(), out EstateID))
227 return FailureResult();
228
229 foreach (Scene s in m_EstateModule.Scenes)
230 {
231 if (s.RegionInfo.EstateSettings.EstateID == (uint)EstateID)
232 s.RegionInfo.RegionSettings.Covenant = CovenantID;
233 }
234
235 return SuccessResult();
236 }
237
238 byte[] UpdateEstate(Dictionary<string, object> request)
239 {
240 int EstateID = 0;
241
242 if (!request.ContainsKey("EstateID"))
243 return FailureResult();
244 if (!Int32.TryParse(request["EstateID"].ToString(), out EstateID))
245 return FailureResult();
246
247 foreach (Scene s in m_EstateModule.Scenes)
248 {
249 if (s.RegionInfo.EstateSettings.EstateID == (uint)EstateID)
250 s.ReloadEstateData();
251 }
252 return SuccessResult();
253 }
254
255 private byte[] FailureResult()
256 {
257 return BoolResult(false);
258 }
259
260 private byte[] SuccessResult()
261 {
262 return BoolResult(true);
263 }
264
265 private byte[] BoolResult(bool value)
266 {
267 XmlDocument doc = new XmlDocument();
268
269 XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration,
270 "", "");
271
272 doc.AppendChild(xmlnode);
273
274 XmlElement rootElement = doc.CreateElement("", "ServerResponse",
275 "");
276
277 doc.AppendChild(rootElement);
278
279 XmlElement result = doc.CreateElement("", "RESULT", "");
280 result.AppendChild(doc.CreateTextNode(value.ToString()));
281
282 rootElement.AppendChild(result);
283
284 return DocToBytes(doc);
285 }
286
287 private byte[] DocToBytes(XmlDocument doc)
288 {
289 MemoryStream ms = new MemoryStream();
290 XmlTextWriter xw = new XmlTextWriter(ms, null);
291 xw.Formatting = Formatting.Indented;
292 doc.WriteTo(xw);
293 xw.Flush();
294
295 return ms.ToArray();
296 }
297 }
298}
diff --git a/OpenSim/Region/Framework/Interfaces/IEstateModule.cs b/OpenSim/Region/Framework/Interfaces/IEstateModule.cs
index 292efa4..d49b24e 100644
--- a/OpenSim/Region/Framework/Interfaces/IEstateModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IEstateModule.cs
@@ -40,7 +40,7 @@ namespace OpenSim.Region.Framework.Interfaces
40 40
41 uint GetRegionFlags(); 41 uint GetRegionFlags();
42 bool IsManager(UUID avatarID); 42 bool IsManager(UUID avatarID);
43 43
44 /// <summary> 44 /// <summary>
45 /// Tell all clients about the current state of the region (terrain textures, water height, etc.). 45 /// Tell all clients about the current state of the region (terrain textures, water height, etc.).
46 /// </summary> 46 /// </summary>
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index caeb980..5860c9a 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -3392,7 +3392,7 @@ namespace OpenSim.Region.Framework.Scenes
3392 { 3392 {
3393 if (EntityTransferModule != null) 3393 if (EntityTransferModule != null)
3394 { 3394 {
3395 EntityTransferModule.TeleportHome(agentId, client); 3395 return EntityTransferModule.TeleportHome(agentId, client);
3396 } 3396 }
3397 else 3397 else
3398 { 3398 {
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
index 04ea289..c16b7d3 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
@@ -1028,6 +1028,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1028 Vector3 currentVelV = VehicleVelocity * Quaternion.Inverse(VehicleOrientation); 1028 Vector3 currentVelV = VehicleVelocity * Quaternion.Inverse(VehicleOrientation);
1029 Vector3 linearMotorCorrectionV = m_linearMotor.Step(pTimestep, currentVelV); 1029 Vector3 linearMotorCorrectionV = m_linearMotor.Step(pTimestep, currentVelV);
1030 1030
1031 // Friction reduces vehicle motion
1032 Vector3 frictionFactorW = ComputeFrictionFactor(m_linearFrictionTimescale, pTimestep);
1033 linearMotorCorrectionV -= (currentVelV * frictionFactorW);
1034
1031 // Motor is vehicle coordinates. Rotate it to world coordinates 1035 // Motor is vehicle coordinates. Rotate it to world coordinates
1032 Vector3 linearMotorVelocityW = linearMotorCorrectionV * VehicleOrientation; 1036 Vector3 linearMotorVelocityW = linearMotorCorrectionV * VehicleOrientation;
1033 1037
@@ -1041,9 +1045,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1041 // Add this correction to the velocity to make it faster/slower. 1045 // Add this correction to the velocity to make it faster/slower.
1042 VehicleVelocity += linearMotorVelocityW; 1046 VehicleVelocity += linearMotorVelocityW;
1043 1047
1044 // Friction reduces vehicle motion 1048
1045 Vector3 frictionFactorW = ComputeFrictionFactor(m_linearFrictionTimescale, pTimestep) * VehicleOrientation;
1046 VehicleVelocity -= (VehicleVelocity * frictionFactorW);
1047 1049
1048 VDetailLog("{0}, MoveLinear,velocity,origVelW={1},velV={2},correctV={3},correctW={4},newVelW={5},fricFact={6}", 1050 VDetailLog("{0}, MoveLinear,velocity,origVelW={1},velV={2},correctV={3},correctW={4},newVelW={5},fricFact={6}",
1049 ControllingPrim.LocalID, origVelW, currentVelV, linearMotorCorrectionV, 1051 ControllingPrim.LocalID, origVelW, currentVelV, linearMotorCorrectionV,
@@ -1337,11 +1339,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1337 // angularMotorContributionV.Y = 0f; 1339 // angularMotorContributionV.Y = 0f;
1338 // } 1340 // }
1339 1341
1342 // Reduce any velocity by friction.
1343 Vector3 frictionFactorW = ComputeFrictionFactor(m_angularFrictionTimescale, pTimestep);
1344 angularMotorContributionV -= (currentAngularV * frictionFactorW);
1345
1340 VehicleRotationalVelocity += angularMotorContributionV * VehicleOrientation; 1346 VehicleRotationalVelocity += angularMotorContributionV * VehicleOrientation;
1341 1347
1342 // Reduce any velocity by friction. 1348
1343 Vector3 frictionFactorW = ComputeFrictionFactor(m_angularFrictionTimescale, pTimestep) * VehicleOrientation;
1344 VehicleRotationalVelocity -= (VehicleRotationalVelocity * frictionFactorW);
1345 1349
1346 VDetailLog("{0}, MoveAngular,angularTurning,angContribV={1}", ControllingPrim.LocalID, angularMotorContributionV); 1350 VDetailLog("{0}, MoveAngular,angularTurning,angContribV={1}", ControllingPrim.LocalID, angularMotorContributionV);
1347 } 1351 }
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
index 1f16cc8..350a5d1 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
@@ -347,21 +347,21 @@ public sealed class BSLinksetCompound : BSLinkset
347 // Bullet presumes an object's origin (relative <0,0,0>) is its center-of-mass 347 // Bullet presumes an object's origin (relative <0,0,0>) is its center-of-mass
348 OMV.Vector3 centerOfMassW = ComputeLinksetCenterOfMass(); 348 OMV.Vector3 centerOfMassW = ComputeLinksetCenterOfMass();
349 349
350 OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation); 350 OMV.Quaternion invRootOrientation = OMV.Quaternion.Normalize(OMV.Quaternion.Inverse(LinksetRoot.RawOrientation));
351 351
352 // 'centerDisplacement' is the value to subtract from children to give physical offset position 352 // 'centerDisplacement' is the value to subtract from children to give physical offset position
353 OMV.Vector3 centerDisplacement = (centerOfMassW - LinksetRoot.RawPosition) * invRootOrientation; 353 OMV.Vector3 centerDisplacementV = (centerOfMassW - LinksetRoot.RawPosition) * invRootOrientation;
354 if (UseBulletSimRootOffsetHack || disableCOM) 354 if (UseBulletSimRootOffsetHack || disableCOM)
355 { 355 {
356 centerDisplacement = OMV.Vector3.Zero; 356 centerDisplacementV = OMV.Vector3.Zero;
357 LinksetRoot.ClearDisplacement(); 357 LinksetRoot.ClearDisplacement();
358 } 358 }
359 else 359 else
360 { 360 {
361 LinksetRoot.SetEffectiveCenterOfMassDisplacement(centerDisplacement); 361 LinksetRoot.SetEffectiveCenterOfMassDisplacement(centerDisplacementV);
362 } 362 }
363 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,COM,rootPos={1},com={2},comDisp={3}", 363 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,COM,rootPos={1},com={2},comDisp={3}",
364 LinksetRoot.LocalID, LinksetRoot.RawPosition, centerOfMassW, centerDisplacement); 364 LinksetRoot.LocalID, LinksetRoot.RawPosition, centerOfMassW, centerDisplacementV);
365 365
366 // Add the shapes of all the components of the linkset 366 // Add the shapes of all the components of the linkset
367 int memberIndex = 1; 367 int memberIndex = 1;
@@ -372,8 +372,8 @@ public sealed class BSLinksetCompound : BSLinkset
372 372
373 // Get a reference to the shape of the child and add that shape to the linkset compound shape 373 // Get a reference to the shape of the child and add that shape to the linkset compound shape
374 BSShape childShape = cPrim.PhysShape.GetReference(m_physicsScene, cPrim); 374 BSShape childShape = cPrim.PhysShape.GetReference(m_physicsScene, cPrim);
375 OMV.Vector3 offsetPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation - centerDisplacement; 375 OMV.Vector3 offsetPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation - centerDisplacementV;
376 OMV.Quaternion offsetRot = cPrim.RawOrientation * invRootOrientation; 376 OMV.Quaternion offsetRot = OMV.Quaternion.Normalize(cPrim.RawOrientation) * invRootOrientation;
377 m_physicsScene.PE.AddChildShapeToCompoundShape(linksetShape.physShapeInfo, childShape.physShapeInfo, offsetPos, offsetRot); 377 m_physicsScene.PE.AddChildShapeToCompoundShape(linksetShape.physShapeInfo, childShape.physShapeInfo, offsetPos, offsetRot);
378 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addChild,indx={1},cShape={2},offPos={3},offRot={4}", 378 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addChild,indx={1},cShape={2},offPos={3},offRot={4}",
379 LinksetRoot.LocalID, memberIndex, childShape, offsetPos, offsetRot); 379 LinksetRoot.LocalID, memberIndex, childShape, offsetPos, offsetRot);
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs
index 1008184..f89c52f 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs
@@ -117,11 +117,11 @@ public abstract class BSShape
117 StringBuilder buff = new StringBuilder(); 117 StringBuilder buff = new StringBuilder();
118 if (physShapeInfo == null) 118 if (physShapeInfo == null)
119 { 119 {
120 buff.Append(",noPhys"); 120 buff.Append("<noPhys");
121 } 121 }
122 else 122 else
123 { 123 {
124 buff.Append(",phy="); 124 buff.Append("<phy=");
125 buff.Append(physShapeInfo.ToString()); 125 buff.Append(physShapeInfo.ToString());
126 } 126 }
127 buff.Append(",c="); 127 buff.Append(",c=");
@@ -810,17 +810,25 @@ public class BSShapeCompound : BSShape
810 } 810 }
811 else 811 else
812 { 812 {
813 if (physicsScene.PE.IsCompound(pShape)) 813 BSShapeConvexHull chullDesc;
814 if (BSShapeConvexHull.TryGetHullByPtr(pShape, out chullDesc))
814 { 815 {
815 BSShapeCompound recursiveCompound = new BSShapeCompound(pShape); 816 chullDesc.Dereference(physicsScene);
816 recursiveCompound.Dereference(physicsScene);
817 } 817 }
818 else 818 else
819 { 819 {
820 if (physicsScene.PE.IsNativeShape(pShape)) 820 if (physicsScene.PE.IsCompound(pShape))
821 { 821 {
822 BSShapeNative nativeShape = new BSShapeNative(pShape); 822 BSShapeCompound recursiveCompound = new BSShapeCompound(pShape);
823 nativeShape.Dereference(physicsScene); 823 recursiveCompound.Dereference(physicsScene);
824 }
825 else
826 {
827 if (physicsScene.PE.IsNativeShape(pShape))
828 {
829 BSShapeNative nativeShape = new BSShapeNative(pShape);
830 nativeShape.Dereference(physicsScene);
831 }
824 } 832 }
825 } 833 }
826 } 834 }
@@ -900,6 +908,27 @@ public class BSShapeConvexHull : BSShape
900 // TODO: schedule aging and destruction of unused meshes. 908 // TODO: schedule aging and destruction of unused meshes.
901 } 909 }
902 } 910 }
911 // Loop through all the known hulls and return the description based on the physical address.
912 public static bool TryGetHullByPtr(BulletShape pShape, out BSShapeConvexHull outHull)
913 {
914 bool ret = false;
915 BSShapeConvexHull foundDesc = null;
916 lock (ConvexHulls)
917 {
918 foreach (BSShapeConvexHull sh in ConvexHulls.Values)
919 {
920 if (sh.physShapeInfo.ReferenceSame(pShape))
921 {
922 foundDesc = sh;
923 ret = true;
924 break;
925 }
926
927 }
928 }
929 outHull = foundDesc;
930 return ret;
931 }
903} 932}
904 933
905// ============================================================================================================ 934// ============================================================================================================