diff options
Diffstat (limited to 'OpenSim')
24 files changed, 1338 insertions, 697 deletions
diff --git a/OpenSim/Data/MySQL/MySQLSimulationData.cs b/OpenSim/Data/MySQL/MySQLSimulationData.cs index 80105b2..1197548 100644 --- a/OpenSim/Data/MySQL/MySQLSimulationData.cs +++ b/OpenSim/Data/MySQL/MySQLSimulationData.cs | |||
@@ -170,7 +170,7 @@ namespace OpenSim.Data.MySQL | |||
170 | "ParticleSystem, ClickAction, Material, " + | 170 | "ParticleSystem, ClickAction, Material, " + |
171 | "CollisionSound, CollisionSoundVolume, " + | 171 | "CollisionSound, CollisionSoundVolume, " + |
172 | "PassTouches, " + | 172 | "PassTouches, " + |
173 | "LinkNumber, MediaURL) values (" + "?UUID, " + | 173 | "LinkNumber, MediaURL, KeyframeMotion) values (" + "?UUID, " + |
174 | "?CreationDate, ?Name, ?Text, " + | 174 | "?CreationDate, ?Name, ?Text, " + |
175 | "?Description, ?SitName, ?TouchName, " + | 175 | "?Description, ?SitName, ?TouchName, " + |
176 | "?ObjectFlags, ?OwnerMask, ?NextOwnerMask, " + | 176 | "?ObjectFlags, ?OwnerMask, ?NextOwnerMask, " + |
@@ -201,7 +201,7 @@ namespace OpenSim.Data.MySQL | |||
201 | "?SaleType, ?ColorR, ?ColorG, " + | 201 | "?SaleType, ?ColorR, ?ColorG, " + |
202 | "?ColorB, ?ColorA, ?ParticleSystem, " + | 202 | "?ColorB, ?ColorA, ?ParticleSystem, " + |
203 | "?ClickAction, ?Material, ?CollisionSound, " + | 203 | "?ClickAction, ?Material, ?CollisionSound, " + |
204 | "?CollisionSoundVolume, ?PassTouches, ?LinkNumber, ?MediaURL)"; | 204 | "?CollisionSoundVolume, ?PassTouches, ?LinkNumber, ?MediaURL, ?KeyframeMotion)"; |
205 | 205 | ||
206 | FillPrimCommand(cmd, prim, obj.UUID, regionUUID); | 206 | FillPrimCommand(cmd, prim, obj.UUID, regionUUID); |
207 | 207 | ||
@@ -446,7 +446,11 @@ namespace OpenSim.Data.MySQL | |||
446 | foreach (SceneObjectPart prim in prims.Values) | 446 | foreach (SceneObjectPart prim in prims.Values) |
447 | { | 447 | { |
448 | if (prim.ParentUUID == UUID.Zero) | 448 | if (prim.ParentUUID == UUID.Zero) |
449 | { | ||
449 | objects[prim.UUID] = new SceneObjectGroup(prim); | 450 | objects[prim.UUID] = new SceneObjectGroup(prim); |
451 | if (prim.KeyframeMotion != null) | ||
452 | prim.KeyframeMotion.UpdateSceneObject(objects[prim.UUID]); | ||
453 | } | ||
450 | } | 454 | } |
451 | 455 | ||
452 | // Add all of the children objects to the SOGs | 456 | // Add all of the children objects to the SOGs |
@@ -1227,6 +1231,18 @@ namespace OpenSim.Data.MySQL | |||
1227 | if (!(row["MediaURL"] is System.DBNull)) | 1231 | if (!(row["MediaURL"] is System.DBNull)) |
1228 | prim.MediaUrl = (string)row["MediaURL"]; | 1232 | prim.MediaUrl = (string)row["MediaURL"]; |
1229 | 1233 | ||
1234 | if (!(row["KeyframeMotion"] is DBNull)) | ||
1235 | { | ||
1236 | Byte[] data = (byte[])row["KeyframeMotion"]; | ||
1237 | if (data.Length > 0) | ||
1238 | prim.KeyframeMotion = KeyframeMotion.FromData(null, data); | ||
1239 | else | ||
1240 | prim.KeyframeMotion = null; | ||
1241 | } | ||
1242 | else | ||
1243 | { | ||
1244 | prim.KeyframeMotion = null; | ||
1245 | } | ||
1230 | return prim; | 1246 | return prim; |
1231 | } | 1247 | } |
1232 | 1248 | ||
@@ -1579,6 +1595,11 @@ namespace OpenSim.Data.MySQL | |||
1579 | 1595 | ||
1580 | cmd.Parameters.AddWithValue("LinkNumber", prim.LinkNum); | 1596 | cmd.Parameters.AddWithValue("LinkNumber", prim.LinkNum); |
1581 | cmd.Parameters.AddWithValue("MediaURL", prim.MediaUrl); | 1597 | cmd.Parameters.AddWithValue("MediaURL", prim.MediaUrl); |
1598 | |||
1599 | if (prim.KeyframeMotion != null) | ||
1600 | cmd.Parameters.AddWithValue("KeyframeMotion", prim.KeyframeMotion.Serialize()); | ||
1601 | else | ||
1602 | cmd.Parameters.AddWithValue("KeyframeMotion", new Byte[0]); | ||
1582 | } | 1603 | } |
1583 | 1604 | ||
1584 | /// <summary> | 1605 | /// <summary> |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 2e86315..f835e56 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | |||
@@ -4845,7 +4845,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4845 | if (part != null && part != part.ParentGroup.RootPart) | 4845 | if (part != null && part != part.ParentGroup.RootPart) |
4846 | { | 4846 | { |
4847 | position = part.OffsetPosition + presence.OffsetPosition * part.RotationOffset; | 4847 | position = part.OffsetPosition + presence.OffsetPosition * part.RotationOffset; |
4848 | rotation = presence.Rotation * part.RotationOffset; | 4848 | rotation = part.RotationOffset * presence.Rotation; |
4849 | } | 4849 | } |
4850 | } | 4850 | } |
4851 | 4851 | ||
@@ -4974,7 +4974,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4974 | if (part != null && part != part.ParentGroup.RootPart) | 4974 | if (part != null && part != part.ParentGroup.RootPart) |
4975 | { | 4975 | { |
4976 | offsetPosition = part.OffsetPosition + data.OffsetPosition * part.RotationOffset; | 4976 | offsetPosition = part.OffsetPosition + data.OffsetPosition * part.RotationOffset; |
4977 | rotation = data.Rotation * part.RotationOffset; | 4977 | rotation = part.RotationOffset * data.Rotation; |
4978 | parentID = part.ParentGroup.RootPart.LocalId; | 4978 | parentID = part.ParentGroup.RootPart.LocalId; |
4979 | } | 4979 | } |
4980 | } | 4980 | } |
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index b0cee03..2bebd30 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs | |||
@@ -551,12 +551,17 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
551 | /// <param name="client"></param> | 551 | /// <param name="client"></param> |
552 | private void Client_OnRequestWearables(IClientAPI client) | 552 | private void Client_OnRequestWearables(IClientAPI client) |
553 | { | 553 | { |
554 | // m_log.DebugFormat("[AVFACTORY]: Client_OnRequestWearables called for {0} ({1})", client.Name, client.AgentId); | 554 | Util.FireAndForget(delegate(object x) |
555 | ScenePresence sp = m_scene.GetScenePresence(client.AgentId); | 555 | { |
556 | if (sp != null) | 556 | Thread.Sleep(4000); |
557 | client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++); | 557 | |
558 | else | 558 | // m_log.DebugFormat("[AVFACTORY]: Client_OnRequestWearables called for {0} ({1})", client.Name, client.AgentId); |
559 | m_log.WarnFormat("[AVFACTORY]: Client_OnRequestWearables unable to find presence for {0}", client.AgentId); | 559 | ScenePresence sp = m_scene.GetScenePresence(client.AgentId); |
560 | if (sp != null) | ||
561 | client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++); | ||
562 | else | ||
563 | m_log.WarnFormat("[AVFACTORY]: Client_OnRequestWearables unable to find presence for {0}", client.AgentId); | ||
564 | }); | ||
560 | } | 565 | } |
561 | 566 | ||
562 | /// <summary> | 567 | /// <summary> |
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 2498705..60a8f86 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | |||
@@ -1746,6 +1746,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1746 | if (grp.RootPart.PhysActor != null) | 1746 | if (grp.RootPart.PhysActor != null) |
1747 | { | 1747 | { |
1748 | grp.RootPart.PhysActor.CrossingFailure(); | 1748 | grp.RootPart.PhysActor.CrossingFailure(); |
1749 | if (grp.RootPart.KeyframeMotion != null) | ||
1750 | { | ||
1751 | grp.RootPart.Velocity = Vector3.Zero; | ||
1752 | grp.RootPart.KeyframeMotion.CrossingFailure(); | ||
1753 | grp.SendGroupRootTerseUpdate(); | ||
1754 | } | ||
1749 | } | 1755 | } |
1750 | } | 1756 | } |
1751 | 1757 | ||
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 6c4c63f..192d55f 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs | |||
@@ -355,6 +355,12 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
355 | 355 | ||
356 | foreach (SceneObjectGroup objectGroup in objlist) | 356 | foreach (SceneObjectGroup objectGroup in objlist) |
357 | { | 357 | { |
358 | if (objectGroup.RootPart.KeyframeMotion != null) | ||
359 | objectGroup.RootPart.KeyframeMotion.Stop(); | ||
360 | objectGroup.RootPart.SetForce(Vector3.Zero); | ||
361 | objectGroup.RootPart.SetAngularImpulse(Vector3.Zero, false); | ||
362 | objectGroup.RootPart.KeyframeMotion = null; | ||
363 | |||
358 | Vector3 inventoryStoredPosition = new Vector3 | 364 | Vector3 inventoryStoredPosition = new Vector3 |
359 | (((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize) | 365 | (((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize) |
360 | ? 250 | 366 | ? 250 |
diff --git a/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs b/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs new file mode 100644 index 0000000..b7b0d27 --- /dev/null +++ b/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs | |||
@@ -0,0 +1,422 @@ | |||
1 | // Proprietary code of Avination Virtual Limited | ||
2 | // (c) 2012 Melanie Thielker | ||
3 | // | ||
4 | |||
5 | using System; | ||
6 | using System.Timers; | ||
7 | using System.Collections; | ||
8 | using System.Collections.Generic; | ||
9 | using System.IO; | ||
10 | using System.Diagnostics; | ||
11 | using System.Reflection; | ||
12 | using System.Threading; | ||
13 | using OpenMetaverse; | ||
14 | using OpenSim.Framework; | ||
15 | using OpenSim.Region.Framework.Interfaces; | ||
16 | using OpenSim.Region.Physics.Manager; | ||
17 | using OpenSim.Region.Framework.Scenes.Serialization; | ||
18 | using System.Runtime.Serialization.Formatters.Binary; | ||
19 | using System.Runtime.Serialization; | ||
20 | using Timer = System.Timers.Timer; | ||
21 | using log4net; | ||
22 | |||
23 | namespace OpenSim.Region.Framework.Scenes | ||
24 | { | ||
25 | [Serializable] | ||
26 | public class KeyframeMotion | ||
27 | { | ||
28 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
29 | |||
30 | public enum PlayMode : int | ||
31 | { | ||
32 | Forward = 0, | ||
33 | Reverse = 1, | ||
34 | Loop = 2, | ||
35 | PingPong = 3 | ||
36 | }; | ||
37 | |||
38 | [Flags] | ||
39 | public enum DataFormat : int | ||
40 | { | ||
41 | Translation = 1, | ||
42 | Rotation = 2 | ||
43 | } | ||
44 | |||
45 | [Serializable] | ||
46 | public struct Keyframe | ||
47 | { | ||
48 | public Vector3? Position; | ||
49 | public Quaternion? Rotation; | ||
50 | public Quaternion StartRotation; | ||
51 | public int TimeMS; | ||
52 | public int TimeTotal; | ||
53 | public Vector3 AngularVelocity; | ||
54 | }; | ||
55 | |||
56 | private Vector3 m_basePosition; | ||
57 | private Quaternion m_baseRotation; | ||
58 | private Vector3 m_serializedPosition; | ||
59 | |||
60 | private Keyframe m_currentFrame; | ||
61 | private List<Keyframe> m_frames = new List<Keyframe>(); | ||
62 | |||
63 | private Keyframe[] m_keyframes; | ||
64 | |||
65 | [NonSerialized()] | ||
66 | protected Timer m_timer = new Timer(); | ||
67 | |||
68 | [NonSerialized()] | ||
69 | private SceneObjectGroup m_group; | ||
70 | |||
71 | private PlayMode m_mode = PlayMode.Forward; | ||
72 | private DataFormat m_data = DataFormat.Translation | DataFormat.Rotation; | ||
73 | |||
74 | private bool m_running = false; | ||
75 | [NonSerialized()] | ||
76 | private bool m_selected = false; | ||
77 | |||
78 | private int m_iterations = 0; | ||
79 | |||
80 | private const double timerInterval = 50.0; | ||
81 | |||
82 | public DataFormat Data | ||
83 | { | ||
84 | get { return m_data; } | ||
85 | } | ||
86 | |||
87 | public bool Selected | ||
88 | { | ||
89 | set | ||
90 | { | ||
91 | if (value) | ||
92 | { | ||
93 | // Once we're let go, recompute positions | ||
94 | if (m_selected) | ||
95 | UpdateSceneObject(m_group); | ||
96 | } | ||
97 | else | ||
98 | { | ||
99 | // Save selection position in case we get moved | ||
100 | if (!m_selected) | ||
101 | m_serializedPosition = m_group.AbsolutePosition; | ||
102 | } | ||
103 | m_selected = value; } | ||
104 | } | ||
105 | |||
106 | public static KeyframeMotion FromData(SceneObjectGroup grp, Byte[] data) | ||
107 | { | ||
108 | MemoryStream ms = new MemoryStream(data); | ||
109 | |||
110 | BinaryFormatter fmt = new BinaryFormatter(); | ||
111 | |||
112 | KeyframeMotion newMotion = (KeyframeMotion)fmt.Deserialize(ms); | ||
113 | |||
114 | // This will be started when position is updated | ||
115 | newMotion.m_timer = new Timer(); | ||
116 | newMotion.m_timer.Interval = (int)timerInterval; | ||
117 | newMotion.m_timer.AutoReset = true; | ||
118 | newMotion.m_timer.Elapsed += newMotion.OnTimer; | ||
119 | |||
120 | return newMotion; | ||
121 | } | ||
122 | |||
123 | public void UpdateSceneObject(SceneObjectGroup grp) | ||
124 | { | ||
125 | m_group = grp; | ||
126 | Vector3 offset = grp.AbsolutePosition - m_serializedPosition; | ||
127 | |||
128 | m_basePosition += offset; | ||
129 | m_currentFrame.Position += offset; | ||
130 | for (int i = 0 ; i < m_frames.Count ; i++) | ||
131 | { | ||
132 | Keyframe k = m_frames[i]; | ||
133 | k.Position += offset; | ||
134 | m_frames[i] = k; | ||
135 | } | ||
136 | |||
137 | if (m_running) | ||
138 | Start(); | ||
139 | } | ||
140 | |||
141 | public KeyframeMotion(SceneObjectGroup grp, PlayMode mode, DataFormat data) | ||
142 | { | ||
143 | m_mode = mode; | ||
144 | m_data = data; | ||
145 | |||
146 | m_group = grp; | ||
147 | m_basePosition = grp.AbsolutePosition; | ||
148 | m_baseRotation = grp.GroupRotation; | ||
149 | |||
150 | m_timer.Interval = (int)timerInterval; | ||
151 | m_timer.AutoReset = true; | ||
152 | m_timer.Elapsed += OnTimer; | ||
153 | } | ||
154 | |||
155 | public void SetKeyframes(Keyframe[] frames) | ||
156 | { | ||
157 | m_keyframes = frames; | ||
158 | } | ||
159 | |||
160 | public void Start() | ||
161 | { | ||
162 | if (m_keyframes.Length > 0) | ||
163 | m_timer.Start(); | ||
164 | m_running = true; | ||
165 | } | ||
166 | |||
167 | public void Stop() | ||
168 | { | ||
169 | // Failed object creation | ||
170 | if (m_timer == null) | ||
171 | return; | ||
172 | m_timer.Stop(); | ||
173 | |||
174 | m_basePosition = m_group.AbsolutePosition; | ||
175 | m_baseRotation = m_group.GroupRotation; | ||
176 | |||
177 | m_group.RootPart.Velocity = Vector3.Zero; | ||
178 | m_group.RootPart.UpdateAngularVelocity(Vector3.Zero); | ||
179 | m_group.SendGroupRootTerseUpdate(); | ||
180 | |||
181 | m_frames.Clear(); | ||
182 | m_running = false; | ||
183 | } | ||
184 | |||
185 | public void Pause() | ||
186 | { | ||
187 | m_group.RootPart.Velocity = Vector3.Zero; | ||
188 | m_group.RootPart.UpdateAngularVelocity(Vector3.Zero); | ||
189 | m_group.SendGroupRootTerseUpdate(); | ||
190 | |||
191 | m_timer.Stop(); | ||
192 | m_running = false; | ||
193 | } | ||
194 | |||
195 | private void GetNextList() | ||
196 | { | ||
197 | m_frames.Clear(); | ||
198 | Vector3 pos = m_basePosition; | ||
199 | Quaternion rot = m_baseRotation; | ||
200 | |||
201 | if (m_mode == PlayMode.Loop || m_mode == PlayMode.PingPong || m_iterations == 0) | ||
202 | { | ||
203 | int direction = 1; | ||
204 | if (m_mode == PlayMode.Reverse || ((m_mode == PlayMode.PingPong) && ((m_iterations & 1) != 0))) | ||
205 | direction = -1; | ||
206 | |||
207 | int start = 0; | ||
208 | int end = m_keyframes.Length; | ||
209 | // if (m_mode == PlayMode.PingPong && m_keyframes.Length > 1) | ||
210 | // end = m_keyframes.Length - 1; | ||
211 | |||
212 | if (direction < 0) | ||
213 | { | ||
214 | start = m_keyframes.Length - 1; | ||
215 | end = -1; | ||
216 | // if (m_mode == PlayMode.PingPong && m_keyframes.Length > 1) | ||
217 | // end = 0; | ||
218 | } | ||
219 | |||
220 | for (int i = start; i != end ; i += direction) | ||
221 | { | ||
222 | Keyframe k = m_keyframes[i]; | ||
223 | |||
224 | if (k.Position.HasValue) | ||
225 | k.Position = (k.Position * direction) + pos; | ||
226 | else | ||
227 | k.Position = pos; | ||
228 | |||
229 | k.StartRotation = rot; | ||
230 | if (k.Rotation.HasValue) | ||
231 | { | ||
232 | if (direction == -1) | ||
233 | k.Rotation = Quaternion.Conjugate((Quaternion)k.Rotation); | ||
234 | k.Rotation = rot * k.Rotation; | ||
235 | } | ||
236 | else | ||
237 | { | ||
238 | k.Rotation = rot; | ||
239 | } | ||
240 | |||
241 | float angle = 0; | ||
242 | |||
243 | float aa = k.StartRotation.X * k.StartRotation.X + k.StartRotation.Y * k.StartRotation.Y + k.StartRotation.Z * k.StartRotation.Z + k.StartRotation.W * k.StartRotation.W; | ||
244 | float bb = ((Quaternion)k.Rotation).X * ((Quaternion)k.Rotation).X + ((Quaternion)k.Rotation).Y * ((Quaternion)k.Rotation).Y + ((Quaternion)k.Rotation).Z * ((Quaternion)k.Rotation).Z + ((Quaternion)k.Rotation).W * ((Quaternion)k.Rotation).W; | ||
245 | float aa_bb = aa * bb; | ||
246 | |||
247 | if (aa_bb == 0) | ||
248 | { | ||
249 | angle = 0; | ||
250 | } | ||
251 | else | ||
252 | { | ||
253 | float ab = k.StartRotation.X * ((Quaternion)k.Rotation).X + | ||
254 | k.StartRotation.Y * ((Quaternion)k.Rotation).Y + | ||
255 | k.StartRotation.Z * ((Quaternion)k.Rotation).Z + | ||
256 | k.StartRotation.W * ((Quaternion)k.Rotation).W; | ||
257 | float q = (ab * ab) / aa_bb; | ||
258 | |||
259 | if (q > 1.0f) | ||
260 | { | ||
261 | angle = 0; | ||
262 | } | ||
263 | else | ||
264 | { | ||
265 | angle = (float)Math.Acos(2 * q - 1); | ||
266 | } | ||
267 | } | ||
268 | |||
269 | k.AngularVelocity = (new Vector3(0, 0, 1) * (Quaternion)k.Rotation) * (angle / (k.TimeMS / 1000)); | ||
270 | k.TimeTotal = k.TimeMS; | ||
271 | |||
272 | m_frames.Add(k); | ||
273 | |||
274 | pos = (Vector3)k.Position; | ||
275 | rot = (Quaternion)k.Rotation; | ||
276 | } | ||
277 | |||
278 | m_basePosition = pos; | ||
279 | m_baseRotation = rot; | ||
280 | |||
281 | m_iterations++; | ||
282 | } | ||
283 | } | ||
284 | |||
285 | protected void OnTimer(object sender, ElapsedEventArgs e) | ||
286 | { | ||
287 | if (m_frames.Count == 0) | ||
288 | { | ||
289 | GetNextList(); | ||
290 | |||
291 | if (m_frames.Count == 0) | ||
292 | { | ||
293 | Stop(); | ||
294 | return; | ||
295 | } | ||
296 | |||
297 | m_currentFrame = m_frames[0]; | ||
298 | } | ||
299 | |||
300 | if (m_selected) | ||
301 | { | ||
302 | if (m_group.RootPart.Velocity != Vector3.Zero) | ||
303 | { | ||
304 | m_group.RootPart.Velocity = Vector3.Zero; | ||
305 | m_group.SendGroupRootTerseUpdate(); | ||
306 | } | ||
307 | return; | ||
308 | } | ||
309 | |||
310 | // Do the frame processing | ||
311 | double steps = (double)m_currentFrame.TimeMS / timerInterval; | ||
312 | float complete = ((float)m_currentFrame.TimeTotal - (float)m_currentFrame.TimeMS) / (float)m_currentFrame.TimeTotal; | ||
313 | |||
314 | if (steps <= 1.0) | ||
315 | { | ||
316 | m_currentFrame.TimeMS = 0; | ||
317 | |||
318 | m_group.AbsolutePosition = (Vector3)m_currentFrame.Position; | ||
319 | m_group.UpdateGroupRotationR((Quaternion)m_currentFrame.Rotation); | ||
320 | } | ||
321 | else | ||
322 | { | ||
323 | Vector3 v = (Vector3)m_currentFrame.Position - m_group.AbsolutePosition; | ||
324 | Vector3 motionThisFrame = v / (float)steps; | ||
325 | v = v * 1000 / m_currentFrame.TimeMS; | ||
326 | |||
327 | bool update = false; | ||
328 | |||
329 | if (Vector3.Mag(motionThisFrame) >= 0.05f) | ||
330 | { | ||
331 | m_group.AbsolutePosition += motionThisFrame; | ||
332 | m_group.RootPart.Velocity = v; | ||
333 | update = true; | ||
334 | } | ||
335 | |||
336 | if ((Quaternion)m_currentFrame.Rotation != m_group.GroupRotation) | ||
337 | { | ||
338 | Quaternion current = m_group.GroupRotation; | ||
339 | |||
340 | Quaternion step = Quaternion.Slerp(m_currentFrame.StartRotation, (Quaternion)m_currentFrame.Rotation, complete); | ||
341 | |||
342 | float angle = 0; | ||
343 | |||
344 | float aa = current.X * current.X + current.Y * current.Y + current.Z * current.Z + current.W * current.W; | ||
345 | float bb = step.X * step.X + step.Y * step.Y + step.Z * step.Z + step.W * step.W; | ||
346 | float aa_bb = aa * bb; | ||
347 | |||
348 | if (aa_bb == 0) | ||
349 | { | ||
350 | angle = 0; | ||
351 | } | ||
352 | else | ||
353 | { | ||
354 | float ab = current.X * step.X + | ||
355 | current.Y * step.Y + | ||
356 | current.Z * step.Z + | ||
357 | current.W * step.W; | ||
358 | float q = (ab * ab) / aa_bb; | ||
359 | |||
360 | if (q > 1.0f) | ||
361 | { | ||
362 | angle = 0; | ||
363 | } | ||
364 | else | ||
365 | { | ||
366 | angle = (float)Math.Acos(2 * q - 1); | ||
367 | } | ||
368 | } | ||
369 | |||
370 | if (angle > 0.01f) | ||
371 | { | ||
372 | m_group.UpdateGroupRotationR(step); | ||
373 | //m_group.RootPart.UpdateAngularVelocity(m_currentFrame.AngularVelocity / 2); | ||
374 | update = true; | ||
375 | } | ||
376 | } | ||
377 | |||
378 | if (update) | ||
379 | m_group.SendGroupRootTerseUpdate(); | ||
380 | } | ||
381 | |||
382 | m_currentFrame.TimeMS -= (int)timerInterval; | ||
383 | |||
384 | if (m_currentFrame.TimeMS <= 0) | ||
385 | { | ||
386 | m_group.RootPart.Velocity = Vector3.Zero; | ||
387 | m_group.RootPart.UpdateAngularVelocity(Vector3.Zero); | ||
388 | m_group.SendGroupRootTerseUpdate(); | ||
389 | |||
390 | m_frames.RemoveAt(0); | ||
391 | if (m_frames.Count > 0) | ||
392 | m_currentFrame = m_frames[0]; | ||
393 | } | ||
394 | } | ||
395 | |||
396 | public Byte[] Serialize() | ||
397 | { | ||
398 | MemoryStream ms = new MemoryStream(); | ||
399 | m_timer.Stop(); | ||
400 | |||
401 | BinaryFormatter fmt = new BinaryFormatter(); | ||
402 | SceneObjectGroup tmp = m_group; | ||
403 | m_group = null; | ||
404 | m_serializedPosition = tmp.AbsolutePosition; | ||
405 | fmt.Serialize(ms, this); | ||
406 | m_group = tmp; | ||
407 | return ms.ToArray(); | ||
408 | } | ||
409 | |||
410 | public void CrossingFailure() | ||
411 | { | ||
412 | // The serialization has stopped the timer, so let's wait a moment | ||
413 | // then retry the crossing. We'll get back here if it fails. | ||
414 | Util.FireAndForget(delegate (object x) | ||
415 | { | ||
416 | Thread.Sleep(60000); | ||
417 | if (m_running) | ||
418 | m_timer.Start(); | ||
419 | }); | ||
420 | } | ||
421 | } | ||
422 | } | ||
diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs index bf2e775..b006045 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs | |||
@@ -138,12 +138,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
138 | { | 138 | { |
139 | SceneObjectGroup sog = part.ParentGroup; | 139 | SceneObjectGroup sog = part.ParentGroup; |
140 | sog.SendPropertiesToClient(remoteClient); | 140 | sog.SendPropertiesToClient(remoteClient); |
141 | sog.IsSelected = true; | ||
142 | 141 | ||
143 | // A prim is only tainted if it's allowed to be edited by the person clicking it. | 142 | // A prim is only tainted if it's allowed to be edited by the person clicking it. |
144 | if (Permissions.CanEditObject(sog.UUID, remoteClient.AgentId) | 143 | if (Permissions.CanEditObject(sog.UUID, remoteClient.AgentId) |
145 | || Permissions.CanMoveObject(sog.UUID, remoteClient.AgentId)) | 144 | || Permissions.CanMoveObject(sog.UUID, remoteClient.AgentId)) |
146 | { | 145 | { |
146 | sog.IsSelected = true; | ||
147 | EventManager.TriggerParcelPrimCountTainted(); | 147 | EventManager.TriggerParcelPrimCountTainted(); |
148 | } | 148 | } |
149 | } | 149 | } |
@@ -215,7 +215,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
215 | // handled by group, but by prim. Legacy cruft. | 215 | // handled by group, but by prim. Legacy cruft. |
216 | // TODO: Make selection flagging per prim! | 216 | // TODO: Make selection flagging per prim! |
217 | // | 217 | // |
218 | part.ParentGroup.IsSelected = false; | 218 | if (Permissions.CanEditObject(part.ParentGroup.UUID, remoteClient.AgentId) |
219 | || Permissions.CanMoveObject(part.ParentGroup.UUID, remoteClient.AgentId)) | ||
220 | part.ParentGroup.IsSelected = false; | ||
219 | 221 | ||
220 | if (part.ParentGroup.IsAttachment) | 222 | if (part.ParentGroup.IsAttachment) |
221 | isAttachment = true; | 223 | isAttachment = true; |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 4324cc0..e675c73 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -2411,6 +2411,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
2411 | 2411 | ||
2412 | if (newPosition != Vector3.Zero) | 2412 | if (newPosition != Vector3.Zero) |
2413 | newObject.RootPart.GroupPosition = newPosition; | 2413 | newObject.RootPart.GroupPosition = newPosition; |
2414 | if (newObject.RootPart.KeyframeMotion != null) | ||
2415 | newObject.RootPart.KeyframeMotion.UpdateSceneObject(newObject); | ||
2414 | 2416 | ||
2415 | if (!AddSceneObject(newObject)) | 2417 | if (!AddSceneObject(newObject)) |
2416 | { | 2418 | { |
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 5a7f124..a3206015 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs | |||
@@ -1731,6 +1731,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
1731 | /// <param name="childPrims"></param> | 1731 | /// <param name="childPrims"></param> |
1732 | protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children) | 1732 | protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children) |
1733 | { | 1733 | { |
1734 | if (root.KeyframeMotion != null) | ||
1735 | { | ||
1736 | root.KeyframeMotion.Stop(); | ||
1737 | root.KeyframeMotion = null; | ||
1738 | } | ||
1739 | |||
1734 | SceneObjectGroup parentGroup = root.ParentGroup; | 1740 | SceneObjectGroup parentGroup = root.ParentGroup; |
1735 | if (parentGroup == null) return; | 1741 | if (parentGroup == null) return; |
1736 | 1742 | ||
@@ -1823,6 +1829,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1823 | { | 1829 | { |
1824 | if (part != null) | 1830 | if (part != null) |
1825 | { | 1831 | { |
1832 | if (part.KeyframeMotion != null) | ||
1833 | { | ||
1834 | part.KeyframeMotion.Stop(); | ||
1835 | part.KeyframeMotion = null; | ||
1836 | } | ||
1826 | if (part.ParentGroup.PrimCount != 1) // Skip single | 1837 | if (part.ParentGroup.PrimCount != 1) // Skip single |
1827 | { | 1838 | { |
1828 | if (part.LinkNum < 2) // Root | 1839 | if (part.LinkNum < 2) // Root |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index cf8637f..c9ea8e4 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | |||
@@ -582,7 +582,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
582 | foreach (ScenePresence av in m_linkedAvatars) | 582 | foreach (ScenePresence av in m_linkedAvatars) |
583 | { | 583 | { |
584 | SceneObjectPart p = m_scene.GetSceneObjectPart(av.ParentID); | 584 | SceneObjectPart p = m_scene.GetSceneObjectPart(av.ParentID); |
585 | if (m_parts.TryGetValue(p.UUID, out p)) | 585 | if (p != null && m_parts.TryGetValue(p.UUID, out p)) |
586 | { | 586 | { |
587 | Vector3 offset = p.GetWorldPosition() - av.ParentPosition; | 587 | Vector3 offset = p.GetWorldPosition() - av.ParentPosition; |
588 | av.AbsolutePosition += offset; | 588 | av.AbsolutePosition += offset; |
@@ -720,6 +720,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
720 | child.PhysActor.Selected = value; | 720 | child.PhysActor.Selected = value; |
721 | } | 721 | } |
722 | } | 722 | } |
723 | if (RootPart.KeyframeMotion != null) | ||
724 | RootPart.KeyframeMotion.Selected = value; | ||
723 | } | 725 | } |
724 | } | 726 | } |
725 | 727 | ||
@@ -890,6 +892,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
890 | ApplyPhysics(); | 892 | ApplyPhysics(); |
891 | 893 | ||
892 | if (RootPart.PhysActor != null) | 894 | if (RootPart.PhysActor != null) |
895 | RootPart.Force = RootPart.Force; | ||
896 | if (RootPart.PhysActor != null) | ||
897 | RootPart.Torque = RootPart.Torque; | ||
898 | if (RootPart.PhysActor != null) | ||
893 | RootPart.Buoyancy = RootPart.Buoyancy; | 899 | RootPart.Buoyancy = RootPart.Buoyancy; |
894 | 900 | ||
895 | // Don't trigger the update here - otherwise some client issues occur when multiple updates are scheduled | 901 | // Don't trigger the update here - otherwise some client issues occur when multiple updates are scheduled |
@@ -1829,6 +1835,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1829 | 1835 | ||
1830 | backup_group.ForEachPart(delegate(SceneObjectPart part) | 1836 | backup_group.ForEachPart(delegate(SceneObjectPart part) |
1831 | { | 1837 | { |
1838 | if (part.KeyframeMotion != null) | ||
1839 | { | ||
1840 | part.KeyframeMotion = KeyframeMotion.FromData(backup_group, part.KeyframeMotion.Serialize()); | ||
1841 | part.KeyframeMotion.UpdateSceneObject(this); | ||
1842 | } | ||
1832 | part.Inventory.ProcessInventoryBackup(datastore); | 1843 | part.Inventory.ProcessInventoryBackup(datastore); |
1833 | }); | 1844 | }); |
1834 | 1845 | ||
@@ -1978,10 +1989,18 @@ namespace OpenSim.Region.Framework.Scenes | |||
1978 | public void CopyRootPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed) | 1989 | public void CopyRootPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed) |
1979 | { | 1990 | { |
1980 | SetRootPart(part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, 0, userExposed)); | 1991 | SetRootPart(part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, 0, userExposed)); |
1992 | if (userExposed) | ||
1993 | RootPart.Velocity = Vector3.Zero; // In case source is moving | ||
1981 | } | 1994 | } |
1982 | 1995 | ||
1983 | public void ScriptSetPhysicsStatus(bool usePhysics) | 1996 | public void ScriptSetPhysicsStatus(bool usePhysics) |
1984 | { | 1997 | { |
1998 | if (usePhysics) | ||
1999 | { | ||
2000 | if (RootPart.KeyframeMotion != null) | ||
2001 | RootPart.KeyframeMotion.Stop(); | ||
2002 | RootPart.KeyframeMotion = null; | ||
2003 | } | ||
1985 | UpdatePrimFlags(RootPart.LocalId, usePhysics, IsTemporary, IsPhantom, IsVolumeDetect); | 2004 | UpdatePrimFlags(RootPart.LocalId, usePhysics, IsTemporary, IsPhantom, IsVolumeDetect); |
1986 | } | 2005 | } |
1987 | 2006 | ||
@@ -2045,30 +2064,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
2045 | } | 2064 | } |
2046 | } | 2065 | } |
2047 | 2066 | ||
2048 | public void setAngularImpulse(Vector3 impulse) | ||
2049 | { | ||
2050 | if (RootPart.PhysActor != null) | ||
2051 | { | ||
2052 | if (!IsAttachment) | ||
2053 | { | ||
2054 | RootPart.PhysActor.Torque = impulse; | ||
2055 | m_scene.PhysicsScene.AddPhysicsActorTaint(RootPart.PhysActor); | ||
2056 | } | ||
2057 | } | ||
2058 | } | ||
2059 | |||
2060 | public Vector3 GetTorque() | 2067 | public Vector3 GetTorque() |
2061 | { | 2068 | { |
2062 | if (RootPart.PhysActor != null) | 2069 | return RootPart.Torque; |
2063 | { | ||
2064 | if (!IsAttachment) | ||
2065 | { | ||
2066 | Vector3 torque = RootPart.PhysActor.Torque; | ||
2067 | return torque; | ||
2068 | } | ||
2069 | } | ||
2070 | |||
2071 | return Vector3.Zero; | ||
2072 | } | 2070 | } |
2073 | 2071 | ||
2074 | // This is used by both Double-Click Auto-Pilot and llMoveToTarget() in an attached object | 2072 | // This is used by both Double-Click Auto-Pilot and llMoveToTarget() in an attached object |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index dd9431b..1c72b10 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | |||
@@ -294,6 +294,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
294 | protected Vector3 m_lastAngularVelocity; | 294 | protected Vector3 m_lastAngularVelocity; |
295 | protected int m_lastTerseSent; | 295 | protected int m_lastTerseSent; |
296 | protected float m_buoyancy = 0.0f; | 296 | protected float m_buoyancy = 0.0f; |
297 | protected Vector3 m_force; | ||
298 | protected Vector3 m_torque; | ||
297 | 299 | ||
298 | /// <summary> | 300 | /// <summary> |
299 | /// Stores media texture data | 301 | /// Stores media texture data |
@@ -313,6 +315,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
313 | 315 | ||
314 | private SOPVehicle m_vehicle = null; | 316 | private SOPVehicle m_vehicle = null; |
315 | 317 | ||
318 | private KeyframeMotion m_keyframeMotion = null; | ||
319 | |||
320 | public KeyframeMotion KeyframeMotion | ||
321 | { | ||
322 | get; set; | ||
323 | } | ||
324 | |||
325 | |||
316 | #endregion Fields | 326 | #endregion Fields |
317 | 327 | ||
318 | // ~SceneObjectPart() | 328 | // ~SceneObjectPart() |
@@ -906,7 +916,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
906 | get | 916 | get |
907 | { | 917 | { |
908 | PhysicsActor actor = PhysActor; | 918 | PhysicsActor actor = PhysActor; |
909 | if ((actor != null) && actor.IsPhysical) | 919 | if ((actor != null) && actor.IsPhysical && ParentGroup.RootPart == this) |
910 | { | 920 | { |
911 | m_angularVelocity = actor.RotationalVelocity; | 921 | m_angularVelocity = actor.RotationalVelocity; |
912 | } | 922 | } |
@@ -1302,14 +1312,69 @@ namespace OpenSim.Region.Framework.Scenes | |||
1302 | 1312 | ||
1303 | public float Buoyancy | 1313 | public float Buoyancy |
1304 | { | 1314 | { |
1305 | get { return m_buoyancy; } | 1315 | get |
1316 | { | ||
1317 | if (ParentGroup.RootPart == this) | ||
1318 | return m_buoyancy; | ||
1319 | |||
1320 | return ParentGroup.RootPart.Buoyancy; | ||
1321 | } | ||
1306 | set | 1322 | set |
1307 | { | 1323 | { |
1324 | if (ParentGroup != null && ParentGroup.RootPart != null && ParentGroup.RootPart != this) | ||
1325 | { | ||
1326 | ParentGroup.RootPart.Buoyancy = value; | ||
1327 | return; | ||
1328 | } | ||
1308 | m_buoyancy = value; | 1329 | m_buoyancy = value; |
1309 | if (PhysActor != null) | 1330 | if (PhysActor != null) |
1310 | { | ||
1311 | PhysActor.Buoyancy = value; | 1331 | PhysActor.Buoyancy = value; |
1332 | } | ||
1333 | } | ||
1334 | |||
1335 | public Vector3 Force | ||
1336 | { | ||
1337 | get | ||
1338 | { | ||
1339 | if (ParentGroup.RootPart == this) | ||
1340 | return m_force; | ||
1341 | |||
1342 | return ParentGroup.RootPart.Force; | ||
1343 | } | ||
1344 | |||
1345 | set | ||
1346 | { | ||
1347 | if (ParentGroup != null && ParentGroup.RootPart != null && ParentGroup.RootPart != this) | ||
1348 | { | ||
1349 | ParentGroup.RootPart.Force = value; | ||
1350 | return; | ||
1351 | } | ||
1352 | m_force = value; | ||
1353 | if (PhysActor != null) | ||
1354 | PhysActor.Force = value; | ||
1355 | } | ||
1356 | } | ||
1357 | |||
1358 | public Vector3 Torque | ||
1359 | { | ||
1360 | get | ||
1361 | { | ||
1362 | if (ParentGroup.RootPart == this) | ||
1363 | return m_torque; | ||
1364 | |||
1365 | return ParentGroup.RootPart.Torque; | ||
1366 | } | ||
1367 | |||
1368 | set | ||
1369 | { | ||
1370 | if (ParentGroup != null && ParentGroup.RootPart != null && ParentGroup.RootPart != this) | ||
1371 | { | ||
1372 | ParentGroup.RootPart.Torque = value; | ||
1373 | return; | ||
1312 | } | 1374 | } |
1375 | m_torque = value; | ||
1376 | if (PhysActor != null) | ||
1377 | PhysActor.Torque = value; | ||
1313 | } | 1378 | } |
1314 | } | 1379 | } |
1315 | 1380 | ||
@@ -1488,20 +1553,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
1488 | /// </summary> | 1553 | /// </summary> |
1489 | /// <param name="impulsei">Vector force</param> | 1554 | /// <param name="impulsei">Vector force</param> |
1490 | /// <param name="localGlobalTF">true for the local frame, false for the global frame</param> | 1555 | /// <param name="localGlobalTF">true for the local frame, false for the global frame</param> |
1491 | public void SetAngularImpulse(Vector3 impulsei, bool localGlobalTF) | 1556 | |
1557 | // this is actualy Set Torque.. keeping naming so not to edit lslapi also | ||
1558 | public void SetAngularImpulse(Vector3 torquei, bool localGlobalTF) | ||
1492 | { | 1559 | { |
1493 | Vector3 impulse = impulsei; | 1560 | Vector3 torque = torquei; |
1494 | 1561 | ||
1495 | if (localGlobalTF) | 1562 | if (localGlobalTF) |
1496 | { | 1563 | { |
1564 | /* | ||
1497 | Quaternion grot = GetWorldRotation(); | 1565 | Quaternion grot = GetWorldRotation(); |
1498 | Quaternion AXgrot = grot; | 1566 | Quaternion AXgrot = grot; |
1499 | Vector3 AXimpulsei = impulsei; | 1567 | Vector3 AXimpulsei = impulsei; |
1500 | Vector3 newimpulse = AXimpulsei * AXgrot; | 1568 | Vector3 newimpulse = AXimpulsei * AXgrot; |
1501 | impulse = newimpulse; | 1569 | */ |
1570 | torque *= GetWorldRotation(); | ||
1502 | } | 1571 | } |
1503 | 1572 | ||
1504 | ParentGroup.setAngularImpulse(impulse); | 1573 | Torque = torque; |
1505 | } | 1574 | } |
1506 | 1575 | ||
1507 | /// <summary> | 1576 | /// <summary> |
@@ -1571,14 +1640,22 @@ namespace OpenSim.Region.Framework.Scenes | |||
1571 | 1640 | ||
1572 | DoPhysicsPropertyUpdate(RigidBody, true); | 1641 | DoPhysicsPropertyUpdate(RigidBody, true); |
1573 | PhysActor.SetVolumeDetect(VolumeDetectActive ? 1 : 0); | 1642 | PhysActor.SetVolumeDetect(VolumeDetectActive ? 1 : 0); |
1643 | |||
1644 | if (!building) | ||
1645 | PhysActor.Building = false; | ||
1574 | 1646 | ||
1575 | Velocity = velocity; | 1647 | Velocity = velocity; |
1576 | AngularVelocity = rotationalVelocity; | 1648 | AngularVelocity = rotationalVelocity; |
1577 | PhysActor.Velocity = velocity; | 1649 | PhysActor.Velocity = velocity; |
1578 | PhysActor.RotationalVelocity = rotationalVelocity; | 1650 | PhysActor.RotationalVelocity = rotationalVelocity; |
1579 | 1651 | ||
1580 | if (!building) | 1652 | // if not vehicle and root part apply force and torque |
1581 | PhysActor.Building = false; | 1653 | if ((m_vehicle == null || m_vehicle.Type == Vehicle.TYPE_NONE) |
1654 | && LocalId == ParentGroup.RootPart.LocalId) | ||
1655 | { | ||
1656 | PhysActor.Force = Force; | ||
1657 | PhysActor.Torque = Torque; | ||
1658 | } | ||
1582 | } | 1659 | } |
1583 | } | 1660 | } |
1584 | } | 1661 | } |
@@ -1816,7 +1893,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
1816 | 1893 | ||
1817 | Velocity = new Vector3(0, 0, 0); | 1894 | Velocity = new Vector3(0, 0, 0); |
1818 | Acceleration = new Vector3(0, 0, 0); | 1895 | Acceleration = new Vector3(0, 0, 0); |
1819 | AngularVelocity = new Vector3(0, 0, 0); | 1896 | if (ParentGroup.RootPart == this) |
1897 | AngularVelocity = new Vector3(0, 0, 0); | ||
1820 | 1898 | ||
1821 | PhysActor.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate; | 1899 | PhysActor.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate; |
1822 | PhysActor.OnOutOfBounds -= PhysicsOutOfBounds; | 1900 | PhysActor.OnOutOfBounds -= PhysicsOutOfBounds; |
@@ -1840,7 +1918,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
1840 | // velocity-vector. | 1918 | // velocity-vector. |
1841 | Velocity = new Vector3(0, 0, 0); | 1919 | Velocity = new Vector3(0, 0, 0); |
1842 | Acceleration = new Vector3(0, 0, 0); | 1920 | Acceleration = new Vector3(0, 0, 0); |
1843 | AngularVelocity = new Vector3(0, 0, 0); | 1921 | if (ParentGroup.RootPart == this) |
1922 | AngularVelocity = new Vector3(0, 0, 0); | ||
1844 | //RotationalVelocity = new Vector3(0, 0, 0); | 1923 | //RotationalVelocity = new Vector3(0, 0, 0); |
1845 | } | 1924 | } |
1846 | 1925 | ||
@@ -1855,6 +1934,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
1855 | { | 1934 | { |
1856 | if (UsePhysics) | 1935 | if (UsePhysics) |
1857 | { | 1936 | { |
1937 | if (ParentGroup.RootPart.KeyframeMotion != null) | ||
1938 | ParentGroup.RootPart.KeyframeMotion.Stop(); | ||
1939 | ParentGroup.RootPart.KeyframeMotion = null; | ||
1858 | ParentGroup.Scene.AddPhysicalPrim(1); | 1940 | ParentGroup.Scene.AddPhysicalPrim(1); |
1859 | 1941 | ||
1860 | PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; | 1942 | PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; |
@@ -2002,10 +2084,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2002 | 2084 | ||
2003 | public Vector3 GetForce() | 2085 | public Vector3 GetForce() |
2004 | { | 2086 | { |
2005 | if (PhysActor != null) | 2087 | return Force; |
2006 | return PhysActor.Force; | ||
2007 | else | ||
2008 | return Vector3.Zero; | ||
2009 | } | 2088 | } |
2010 | 2089 | ||
2011 | /// <summary> | 2090 | /// <summary> |
@@ -3150,10 +3229,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
3150 | 3229 | ||
3151 | public void SetBuoyancy(float fvalue) | 3230 | public void SetBuoyancy(float fvalue) |
3152 | { | 3231 | { |
3232 | Buoyancy = fvalue; | ||
3233 | /* | ||
3153 | if (PhysActor != null) | 3234 | if (PhysActor != null) |
3154 | { | 3235 | { |
3155 | PhysActor.Buoyancy = fvalue; | 3236 | PhysActor.Buoyancy = fvalue; |
3156 | } | 3237 | } |
3238 | */ | ||
3157 | } | 3239 | } |
3158 | 3240 | ||
3159 | public void SetDieAtEdge(bool p) | 3241 | public void SetDieAtEdge(bool p) |
@@ -3181,10 +3263,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
3181 | 3263 | ||
3182 | public void SetForce(Vector3 force) | 3264 | public void SetForce(Vector3 force) |
3183 | { | 3265 | { |
3266 | Force = force; | ||
3267 | /* | ||
3184 | if (PhysActor != null) | 3268 | if (PhysActor != null) |
3185 | { | 3269 | { |
3186 | PhysActor.Force = force; | 3270 | PhysActor.Force = force; |
3187 | } | 3271 | } |
3272 | */ | ||
3188 | } | 3273 | } |
3189 | 3274 | ||
3190 | public SOPVehicle sopVehicle | 3275 | public SOPVehicle sopVehicle |
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index 72a0ec3..51a3320 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs | |||
@@ -244,6 +244,12 @@ namespace OpenSim.Region.Framework.Scenes.Serialization | |||
244 | sr.Close(); | 244 | sr.Close(); |
245 | } | 245 | } |
246 | 246 | ||
247 | XmlNodeList keymotion = doc.GetElementsByTagName("KeyframeMotion"); | ||
248 | if (keymotion.Count > 0) | ||
249 | sceneObject.RootPart.KeyframeMotion = KeyframeMotion.FromData(sceneObject, Convert.FromBase64String(keymotion[0].InnerText)); | ||
250 | else | ||
251 | sceneObject.RootPart.KeyframeMotion = null; | ||
252 | |||
247 | // Script state may, or may not, exist. Not having any, is NOT | 253 | // Script state may, or may not, exist. Not having any, is NOT |
248 | // ever a problem. | 254 | // ever a problem. |
249 | sceneObject.LoadScriptState(doc); | 255 | sceneObject.LoadScriptState(doc); |
@@ -349,6 +355,8 @@ namespace OpenSim.Region.Framework.Scenes.Serialization | |||
349 | m_SOPXmlProcessors.Add("PayPrice4", ProcessPayPrice4); | 355 | m_SOPXmlProcessors.Add("PayPrice4", ProcessPayPrice4); |
350 | 356 | ||
351 | m_SOPXmlProcessors.Add("Buoyancy", ProcessBuoyancy); | 357 | m_SOPXmlProcessors.Add("Buoyancy", ProcessBuoyancy); |
358 | m_SOPXmlProcessors.Add("Force", ProcessForce); | ||
359 | m_SOPXmlProcessors.Add("Torque", ProcessTorque); | ||
352 | m_SOPXmlProcessors.Add("VolumeDetectActive", ProcessVolumeDetectActive); | 360 | m_SOPXmlProcessors.Add("VolumeDetectActive", ProcessVolumeDetectActive); |
353 | 361 | ||
354 | //Ubit comented until proper testing | 362 | //Ubit comented until proper testing |
@@ -595,7 +603,6 @@ namespace OpenSim.Region.Framework.Scenes.Serialization | |||
595 | obj.sopVehicle = _vehicle; | 603 | obj.sopVehicle = _vehicle; |
596 | } | 604 | } |
597 | 605 | ||
598 | |||
599 | private static void ProcessShape(SceneObjectPart obj, XmlTextReader reader) | 606 | private static void ProcessShape(SceneObjectPart obj, XmlTextReader reader) |
600 | { | 607 | { |
601 | List<string> errorNodeNames; | 608 | List<string> errorNodeNames; |
@@ -762,7 +769,16 @@ namespace OpenSim.Region.Framework.Scenes.Serialization | |||
762 | 769 | ||
763 | private static void ProcessBuoyancy(SceneObjectPart obj, XmlTextReader reader) | 770 | private static void ProcessBuoyancy(SceneObjectPart obj, XmlTextReader reader) |
764 | { | 771 | { |
765 | obj.Buoyancy = (int)reader.ReadElementContentAsFloat("Buoyancy", String.Empty); | 772 | obj.Buoyancy = (float)reader.ReadElementContentAsFloat("Buoyancy", String.Empty); |
773 | } | ||
774 | |||
775 | private static void ProcessForce(SceneObjectPart obj, XmlTextReader reader) | ||
776 | { | ||
777 | obj.Force = Util.ReadVector(reader, "Force"); | ||
778 | } | ||
779 | private static void ProcessTorque(SceneObjectPart obj, XmlTextReader reader) | ||
780 | { | ||
781 | obj.Torque = Util.ReadVector(reader, "Torque"); | ||
766 | } | 782 | } |
767 | 783 | ||
768 | private static void ProcessVolumeDetectActive(SceneObjectPart obj, XmlTextReader reader) | 784 | private static void ProcessVolumeDetectActive(SceneObjectPart obj, XmlTextReader reader) |
@@ -1157,6 +1173,16 @@ namespace OpenSim.Region.Framework.Scenes.Serialization | |||
1157 | }); | 1173 | }); |
1158 | 1174 | ||
1159 | writer.WriteEndElement(); | 1175 | writer.WriteEndElement(); |
1176 | |||
1177 | if (sog.RootPart.KeyframeMotion != null) | ||
1178 | { | ||
1179 | Byte[] data = sog.RootPart.KeyframeMotion.Serialize(); | ||
1180 | |||
1181 | writer.WriteStartElement(String.Empty, "KeyframeMotion", String.Empty); | ||
1182 | writer.WriteBase64(data, 0, data.Length); | ||
1183 | writer.WriteEndElement(); | ||
1184 | } | ||
1185 | |||
1160 | writer.WriteEndElement(); | 1186 | writer.WriteEndElement(); |
1161 | } | 1187 | } |
1162 | 1188 | ||
@@ -1256,6 +1282,10 @@ namespace OpenSim.Region.Framework.Scenes.Serialization | |||
1256 | writer.WriteElementString("PayPrice4", sop.PayPrice[4].ToString()); | 1282 | writer.WriteElementString("PayPrice4", sop.PayPrice[4].ToString()); |
1257 | 1283 | ||
1258 | writer.WriteElementString("Buoyancy", sop.Buoyancy.ToString()); | 1284 | writer.WriteElementString("Buoyancy", sop.Buoyancy.ToString()); |
1285 | |||
1286 | WriteVector(writer, "Force", sop.Force); | ||
1287 | WriteVector(writer, "Torque", sop.Torque); | ||
1288 | |||
1259 | writer.WriteElementString("VolumeDetectActive", sop.VolumeDetectActive.ToString().ToLower()); | 1289 | writer.WriteElementString("VolumeDetectActive", sop.VolumeDetectActive.ToString().ToLower()); |
1260 | 1290 | ||
1261 | //Ubit comented until proper testing | 1291 | //Ubit comented until proper testing |
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index ae46c97..78e9b29 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs | |||
@@ -99,8 +99,11 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
99 | // Delete existing sp attachments | 99 | // Delete existing sp attachments |
100 | scene.AttachmentsModule.DeleteAttachmentsFromScene(sp, false); | 100 | scene.AttachmentsModule.DeleteAttachmentsFromScene(sp, false); |
101 | 101 | ||
102 | AvatarAppearance app = new AvatarAppearance(appearance, true); | ||
103 | sp.Appearance = app; | ||
104 | |||
102 | // Set new sp appearance. Also sends to clients. | 105 | // Set new sp appearance. Also sends to clients. |
103 | scene.RequestModuleInterface<IAvatarFactoryModule>().SetAppearance(sp, new AvatarAppearance(appearance, true)); | 106 | scene.RequestModuleInterface<IAvatarFactoryModule>().SetAppearance(sp, app); |
104 | 107 | ||
105 | // Rez needed sp attachments | 108 | // Rez needed sp attachments |
106 | scene.AttachmentsModule.RezAttachments(sp); | 109 | scene.AttachmentsModule.RezAttachments(sp); |
diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs index 80c1277..0a4ebe4 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs | |||
@@ -704,6 +704,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
704 | if (m_isphysical) | 704 | if (m_isphysical) |
705 | m_targetSpace = _parent_scene.space; | 705 | m_targetSpace = _parent_scene.space; |
706 | 706 | ||
707 | _triMeshData = IntPtr.Zero; | ||
708 | |||
707 | m_primName = primName; | 709 | m_primName = primName; |
708 | m_taintserial = null; | 710 | m_taintserial = null; |
709 | m_taintadd = true; | 711 | m_taintadd = true; |
@@ -773,6 +775,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
773 | m_targetSpace = _parent_scene.space; | 775 | m_targetSpace = _parent_scene.space; |
774 | } | 776 | } |
775 | 777 | ||
778 | _triMeshData = IntPtr.Zero; | ||
779 | |||
776 | m_taintserial = null; | 780 | m_taintserial = null; |
777 | m_primName = primName; | 781 | m_primName = primName; |
778 | m_taintadd = true; | 782 | m_taintadd = true; |
@@ -1762,7 +1766,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1762 | 1766 | ||
1763 | private static Dictionary<IMesh, IntPtr> m_MeshToTriMeshMap = new Dictionary<IMesh, IntPtr>(); | 1767 | private static Dictionary<IMesh, IntPtr> m_MeshToTriMeshMap = new Dictionary<IMesh, IntPtr>(); |
1764 | 1768 | ||
1765 | public void setMesh(OdeScene parent_scene, IMesh mesh) | 1769 | public bool setMesh(OdeScene parent_scene, IMesh mesh) |
1766 | { | 1770 | { |
1767 | // This sleeper is there to moderate how long it takes between | 1771 | // This sleeper is there to moderate how long it takes between |
1768 | // setting up the mesh and pre-processing it when we get rapid fire mesh requests on a single object | 1772 | // setting up the mesh and pre-processing it when we get rapid fire mesh requests on a single object |
@@ -1785,24 +1789,48 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1785 | disableBody(); | 1789 | disableBody(); |
1786 | } | 1790 | } |
1787 | } | 1791 | } |
1792 | |||
1793 | // do it on caller instead | ||
1794 | /* | ||
1795 | if (_triMeshData != IntPtr.Zero) | ||
1796 | { | ||
1797 | d.GeomTriMeshDataDestroy(_triMeshData); | ||
1798 | _triMeshData = IntPtr.Zero; | ||
1799 | } | ||
1800 | */ | ||
1788 | IntPtr vertices, indices; | 1801 | IntPtr vertices, indices; |
1789 | int vertexCount, indexCount; | 1802 | int vertexCount, indexCount; |
1790 | int vertexStride, triStride; | 1803 | int vertexStride, triStride; |
1791 | mesh.getVertexListAsPtrToFloatArray(out vertices, out vertexStride, out vertexCount); // Note, that vertices are fixed in unmanaged heap | 1804 | mesh.getVertexListAsPtrToFloatArray(out vertices, out vertexStride, out vertexCount); // Note, that vertices are fixed in unmanaged heap |
1792 | mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount); // Also fixed, needs release after usage | 1805 | mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount); // Also fixed, needs release after usage |
1793 | 1806 | ||
1807 | // warning this destroys the mesh for eventual future use. Only pinned float arrays stay valid | ||
1794 | mesh.releaseSourceMeshData(); // free up the original mesh data to save memory | 1808 | mesh.releaseSourceMeshData(); // free up the original mesh data to save memory |
1809 | |||
1810 | if (vertexCount == 0 || indexCount == 0) | ||
1811 | { | ||
1812 | m_log.WarnFormat("[PHYSICS]: Got invalid mesh on prim {0} at <{1},{2},{3}>. It can be a sculp with alpha channel in map. Replacing it by a small box.", Name, _position.X, _position.Y, _position.Z); | ||
1813 | _size.X = 0.05f; | ||
1814 | _size.Y = 0.05f; | ||
1815 | _size.Z = 0.05f; | ||
1816 | return false; | ||
1817 | } | ||
1818 | |||
1819 | /* | ||
1795 | if (m_MeshToTriMeshMap.ContainsKey(mesh)) | 1820 | if (m_MeshToTriMeshMap.ContainsKey(mesh)) |
1796 | { | 1821 | { |
1797 | _triMeshData = m_MeshToTriMeshMap[mesh]; | 1822 | _triMeshData = m_MeshToTriMeshMap[mesh]; |
1798 | } | 1823 | } |
1799 | else | 1824 | else |
1825 | */ | ||
1826 | |||
1827 | |||
1800 | { | 1828 | { |
1801 | _triMeshData = d.GeomTriMeshDataCreate(); | 1829 | _triMeshData = d.GeomTriMeshDataCreate(); |
1802 | 1830 | ||
1803 | d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride); | 1831 | d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride); |
1804 | d.GeomTriMeshDataPreprocess(_triMeshData); | 1832 | d.GeomTriMeshDataPreprocess(_triMeshData); |
1805 | m_MeshToTriMeshMap[mesh] = _triMeshData; | 1833 | // m_MeshToTriMeshMap[mesh] = _triMeshData; |
1806 | } | 1834 | } |
1807 | 1835 | ||
1808 | _parent_scene.waitForSpaceUnlock(m_targetSpace); | 1836 | _parent_scene.waitForSpaceUnlock(m_targetSpace); |
@@ -1810,13 +1838,23 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1810 | { | 1838 | { |
1811 | // if (prim_geom == IntPtr.Zero) // setGeom takes care of phys engine recreate and prim_geom pointer | 1839 | // if (prim_geom == IntPtr.Zero) // setGeom takes care of phys engine recreate and prim_geom pointer |
1812 | // { | 1840 | // { |
1813 | SetGeom(d.CreateTriMesh(m_targetSpace, _triMeshData, parent_scene.triCallback, null, null)); | 1841 | // SetGeom(d.CreateTriMesh(m_targetSpace, _triMeshData, parent_scene.triCallback, null, null)); |
1842 | SetGeom(d.CreateTriMesh(m_targetSpace, _triMeshData, null, null, null)); | ||
1814 | // } | 1843 | // } |
1815 | } | 1844 | } |
1816 | catch (AccessViolationException) | 1845 | catch (Exception e) |
1817 | { | 1846 | { |
1818 | m_log.Error("[PHYSICS]: MESH LOCKED"); | 1847 | m_log.ErrorFormat("[PHYSICS]: Create trimesh failed on prim {0} : {1}",Name,e.Message); |
1819 | return; | 1848 | |
1849 | if (_triMeshData != IntPtr.Zero) | ||
1850 | { | ||
1851 | d.GeomTriMeshDataDestroy(_triMeshData); | ||
1852 | _triMeshData = IntPtr.Zero; | ||
1853 | } | ||
1854 | _size.X = 0.05f; | ||
1855 | _size.Y = 0.05f; | ||
1856 | _size.Z = 0.05f; | ||
1857 | return false; | ||
1820 | } | 1858 | } |
1821 | 1859 | ||
1822 | 1860 | ||
@@ -1828,6 +1866,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1828 | 1866 | ||
1829 | // enableBody(); | 1867 | // enableBody(); |
1830 | // } | 1868 | // } |
1869 | return true; | ||
1831 | } | 1870 | } |
1832 | 1871 | ||
1833 | public void ProcessTaints(float timestep) //============================================================================= | 1872 | public void ProcessTaints(float timestep) //============================================================================= |
@@ -1837,6 +1876,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1837 | changeadd(timestep); | 1876 | changeadd(timestep); |
1838 | } | 1877 | } |
1839 | 1878 | ||
1879 | if (m_taintremove) | ||
1880 | return; | ||
1881 | |||
1840 | if (prim_geom != IntPtr.Zero) | 1882 | if (prim_geom != IntPtr.Zero) |
1841 | { | 1883 | { |
1842 | if (!_position.ApproxEquals(m_taintposition, 0f)) | 1884 | if (!_position.ApproxEquals(m_taintposition, 0f)) |
@@ -2286,75 +2328,62 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2286 | 2328 | ||
2287 | public void CreateGeom(IntPtr m_targetSpace, IMesh _mesh) | 2329 | public void CreateGeom(IntPtr m_targetSpace, IMesh _mesh) |
2288 | { | 2330 | { |
2331 | bool gottrimesh = false; | ||
2332 | |||
2333 | if (_triMeshData != IntPtr.Zero) | ||
2334 | { | ||
2335 | d.GeomTriMeshDataDestroy(_triMeshData); | ||
2336 | _triMeshData = IntPtr.Zero; | ||
2337 | } | ||
2338 | |||
2289 | if (_mesh != null) // Special - make mesh | 2339 | if (_mesh != null) // Special - make mesh |
2290 | { | 2340 | { |
2291 | setMesh(_parent_scene, _mesh); | 2341 | gottrimesh = setMesh(_parent_scene, _mesh); |
2292 | } | 2342 | } |
2293 | else // not a mesh | 2343 | |
2344 | if (!gottrimesh) // not a mesh | ||
2294 | { | 2345 | { |
2295 | if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1) // special profile?? | 2346 | IntPtr geo = IntPtr.Zero; |
2347 | |||
2348 | if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1 | ||
2349 | && _size.X == _size.Y && _size.X == _size.Z) | ||
2296 | { | 2350 | { |
2297 | if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z) // Equi-size | 2351 | // its a sphere |
2352 | _parent_scene.waitForSpaceUnlock(m_targetSpace); | ||
2353 | try | ||
2298 | { | 2354 | { |
2299 | if (((_size.X / 2f) > 0f)) // Has size | 2355 | geo = d.CreateSphere(m_targetSpace, _size.X * 0.5f); |
2300 | { | ||
2301 | _parent_scene.waitForSpaceUnlock(m_targetSpace); | ||
2302 | try | ||
2303 | { | ||
2304 | SetGeom(d.CreateSphere(m_targetSpace, _size.X / 2)); | ||
2305 | } | ||
2306 | catch (AccessViolationException) | ||
2307 | { | ||
2308 | m_log.Warn("[PHYSICS]: Unable to create physics proxy for object"); | ||
2309 | ode.dunlock(_parent_scene.world); | ||
2310 | return; | ||
2311 | } | ||
2312 | } | ||
2313 | else | ||
2314 | { | ||
2315 | _parent_scene.waitForSpaceUnlock(m_targetSpace); | ||
2316 | try | ||
2317 | { | ||
2318 | SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z)); | ||
2319 | } | ||
2320 | catch (AccessViolationException) | ||
2321 | { | ||
2322 | m_log.Warn("[PHYSICS]: Unable to create physics proxy for object"); | ||
2323 | ode.dunlock(_parent_scene.world); | ||
2324 | return; | ||
2325 | } | ||
2326 | } | ||
2327 | } | 2356 | } |
2328 | else // not equi-size | 2357 | catch (Exception e) |
2329 | { | 2358 | { |
2330 | _parent_scene.waitForSpaceUnlock(m_targetSpace); | 2359 | m_log.WarnFormat("[PHYSICS]: Unable to create basic sphere for object {0}", e.Message); |
2331 | try | 2360 | geo = IntPtr.Zero; |
2332 | { | 2361 | ode.dunlock(_parent_scene.world); |
2333 | SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z)); | ||
2334 | } | ||
2335 | catch (AccessViolationException) | ||
2336 | { | ||
2337 | m_log.Warn("[PHYSICS]: Unable to create physics proxy for object"); | ||
2338 | ode.dunlock(_parent_scene.world); | ||
2339 | return; | ||
2340 | } | ||
2341 | } | 2362 | } |
2342 | } | 2363 | } |
2343 | 2364 | else // make it a box | |
2344 | else // not special profile | ||
2345 | { | 2365 | { |
2346 | _parent_scene.waitForSpaceUnlock(m_targetSpace); | 2366 | _parent_scene.waitForSpaceUnlock(m_targetSpace); |
2347 | try | 2367 | try |
2348 | { | 2368 | { |
2349 | SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z)); | 2369 | geo = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z); |
2350 | } | 2370 | } |
2351 | catch (AccessViolationException) | 2371 | catch (Exception e) |
2352 | { | 2372 | { |
2353 | m_log.Warn("[PHYSICS]: Unable to create physics proxy for object"); | 2373 | m_log.WarnFormat("[PHYSICS]: Unable to create basic sphere for object {0}", e.Message); |
2374 | geo = IntPtr.Zero; | ||
2354 | ode.dunlock(_parent_scene.world); | 2375 | ode.dunlock(_parent_scene.world); |
2355 | return; | ||
2356 | } | 2376 | } |
2357 | } | 2377 | } |
2378 | |||
2379 | if (geo == IntPtr.Zero) | ||
2380 | { | ||
2381 | m_taintremove = true; | ||
2382 | _parent_scene.AddPhysicsActorTaint(this); | ||
2383 | return; | ||
2384 | } | ||
2385 | |||
2386 | SetGeom(geo); | ||
2358 | } | 2387 | } |
2359 | } | 2388 | } |
2360 | 2389 | ||
@@ -2372,18 +2401,17 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2372 | { | 2401 | { |
2373 | if (_parent_scene.needsMeshing(_pbs)) | 2402 | if (_parent_scene.needsMeshing(_pbs)) |
2374 | { | 2403 | { |
2375 | // Don't need to re-enable body.. it's done in SetMesh | ||
2376 | try | 2404 | try |
2377 | { | 2405 | { |
2378 | _mesh = _parent_scene.mesher.CreateMesh(m_primName, _pbs, _size, _parent_scene.meshSculptLOD, IsPhysical); | 2406 | _mesh = _parent_scene.mesher.CreateMesh(m_primName, _pbs, _size, (int)LevelOfDetail.High, true); |
2379 | } | 2407 | } |
2380 | catch | 2408 | catch |
2381 | { | 2409 | { |
2382 | //Don't continuously try to mesh prims when meshing has failed | 2410 | //Don't continuously try to mesh prims when meshing has failed |
2383 | m_meshfailed = true; | 2411 | m_meshfailed = true; |
2412 | _mesh = null; | ||
2413 | m_log.WarnFormat("[PHYSICS]: changeAdd CreateMesh fail on prim {0} at <{1},{2},{3}>", Name, _position.X, _position.Y, _position.Z); | ||
2384 | } | 2414 | } |
2385 | // createmesh returns null when it's a shape that isn't a cube. | ||
2386 | // m_log.Debug(m_localID); | ||
2387 | } | 2415 | } |
2388 | } | 2416 | } |
2389 | 2417 | ||
@@ -2630,17 +2658,17 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2630 | try | 2658 | try |
2631 | { | 2659 | { |
2632 | if (_parent_scene.needsMeshing(_pbs)) | 2660 | if (_parent_scene.needsMeshing(_pbs)) |
2633 | mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical); | 2661 | mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, (int)LevelOfDetail.High, true); |
2634 | } | 2662 | } |
2635 | catch | 2663 | catch |
2636 | { | 2664 | { |
2637 | m_meshfailed = true; | 2665 | m_meshfailed = true; |
2666 | mesh = null; | ||
2667 | m_log.WarnFormat("[PHYSICS]: changeSize CreateMesh fail on prim {0} at <{1},{2},{3}>", Name, _position.X, _position.Y, _position.Z); | ||
2638 | } | 2668 | } |
2639 | 2669 | ||
2640 | //IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical); | 2670 | //IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical); |
2641 | CreateGeom(m_targetSpace, mesh); | 2671 | CreateGeom(m_targetSpace, mesh); |
2642 | |||
2643 | |||
2644 | } | 2672 | } |
2645 | else | 2673 | else |
2646 | { | 2674 | { |
@@ -2732,18 +2760,23 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2732 | { | 2760 | { |
2733 | // Don't need to re-enable body.. it's done in SetMesh | 2761 | // Don't need to re-enable body.. it's done in SetMesh |
2734 | float meshlod = _parent_scene.meshSculptLOD; | 2762 | float meshlod = _parent_scene.meshSculptLOD; |
2763 | IMesh mesh; | ||
2735 | 2764 | ||
2736 | if (IsPhysical) | 2765 | if (IsPhysical) |
2737 | meshlod = _parent_scene.MeshSculptphysicalLOD; | 2766 | meshlod = _parent_scene.MeshSculptphysicalLOD; |
2738 | try | 2767 | try |
2739 | { | 2768 | { |
2740 | IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical); | 2769 | mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, (int)LevelOfDetail.High, true); |
2741 | CreateGeom(m_targetSpace, mesh); | ||
2742 | } | 2770 | } |
2743 | catch | 2771 | catch |
2744 | { | 2772 | { |
2773 | mesh = null; | ||
2745 | m_meshfailed = true; | 2774 | m_meshfailed = true; |
2775 | m_log.WarnFormat("[PHYSICS]: changeAdd CreateMesh fail on prim {0} at <{1},{2},{3}>", Name, _position.X, _position.Y, _position.Z); | ||
2746 | } | 2776 | } |
2777 | |||
2778 | CreateGeom(m_targetSpace, mesh); | ||
2779 | |||
2747 | // createmesh returns null when it doesn't mesh. | 2780 | // createmesh returns null when it doesn't mesh. |
2748 | } | 2781 | } |
2749 | else | 2782 | else |
diff --git a/OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs index 61fb2d0..7a1e671 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs | |||
@@ -1772,7 +1772,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1772 | IMesh mesh = null; | 1772 | IMesh mesh = null; |
1773 | 1773 | ||
1774 | if (needsMeshing(pbs)) | 1774 | if (needsMeshing(pbs)) |
1775 | mesh = mesher.CreateMesh(primName, pbs, size, 32f, isPhysical); | 1775 | mesh = mesher.CreateMesh(primName, pbs, size, (int)LevelOfDetail.High, true); |
1776 | 1776 | ||
1777 | result = AddPrim(primName, position, size, rotation, mesh, pbs, isPhysical, localid); | 1777 | result = AddPrim(primName, position, size, rotation, mesh, pbs, isPhysical, localid); |
1778 | 1778 | ||
@@ -2174,6 +2174,16 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2174 | { | 2174 | { |
2175 | prim.ResetTaints(); | 2175 | prim.ResetTaints(); |
2176 | 2176 | ||
2177 | try | ||
2178 | { | ||
2179 | if (prim._triMeshData != IntPtr.Zero) | ||
2180 | { | ||
2181 | d.GeomTriMeshDataDestroy(prim._triMeshData); | ||
2182 | prim._triMeshData = IntPtr.Zero; | ||
2183 | } | ||
2184 | } | ||
2185 | catch { }; | ||
2186 | |||
2177 | if (prim.IsPhysical) | 2187 | if (prim.IsPhysical) |
2178 | { | 2188 | { |
2179 | prim.disableBody(); | 2189 | prim.disableBody(); |
@@ -2185,7 +2195,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2185 | prim.IsPhysical = false; | 2195 | prim.IsPhysical = false; |
2186 | } | 2196 | } |
2187 | 2197 | ||
2188 | |||
2189 | } | 2198 | } |
2190 | // we don't want to remove the main space | 2199 | // we don't want to remove the main space |
2191 | 2200 | ||
@@ -2505,7 +2514,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2505 | } | 2514 | } |
2506 | 2515 | ||
2507 | // if it's a standard box or sphere with no cuts, hollows, twist or top shear, return false since ODE can use an internal representation for the prim | 2516 | // if it's a standard box or sphere with no cuts, hollows, twist or top shear, return false since ODE can use an internal representation for the prim |
2508 | if (!forceSimplePrimMeshing) | 2517 | if (!forceSimplePrimMeshing && !pbs.SculptEntry) |
2509 | { | 2518 | { |
2510 | if ((pbs.ProfileShape == ProfileShape.Square && pbs.PathCurve == (byte)Extrusion.Straight) | 2519 | if ((pbs.ProfileShape == ProfileShape.Square && pbs.PathCurve == (byte)Extrusion.Straight) |
2511 | || (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1 | 2520 | || (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1 |
@@ -2528,6 +2537,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2528 | } | 2537 | } |
2529 | } | 2538 | } |
2530 | 2539 | ||
2540 | if (forceSimplePrimMeshing) | ||
2541 | return true; | ||
2542 | |||
2531 | if (pbs.ProfileHollow != 0) | 2543 | if (pbs.ProfileHollow != 0) |
2532 | iPropertiesNotSupportedDefault++; | 2544 | iPropertiesNotSupportedDefault++; |
2533 | 2545 | ||
@@ -2592,6 +2604,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2592 | } | 2604 | } |
2593 | } | 2605 | } |
2594 | 2606 | ||
2607 | if (pbs.SculptEntry && meshSculptedPrim) | ||
2608 | iPropertiesNotSupportedDefault++; | ||
2595 | 2609 | ||
2596 | if (iPropertiesNotSupportedDefault == 0) | 2610 | if (iPropertiesNotSupportedDefault == 0) |
2597 | { | 2611 | { |
@@ -3443,8 +3457,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3443 | int heightmapWidth = regionsize + 2; // ODE map size 257 x 257 (Meters) (1 extra | 3457 | int heightmapWidth = regionsize + 2; // ODE map size 257 x 257 (Meters) (1 extra |
3444 | int heightmapHeight = regionsize + 2; | 3458 | int heightmapHeight = regionsize + 2; |
3445 | 3459 | ||
3446 | int heightmapWidthSamples = (int)regionsize + 3; // Sample file size, 258 x 258 samples | 3460 | int heightmapWidthSamples = (int)regionsize + 2; // Sample file size, 258 x 258 samples |
3447 | int heightmapHeightSamples = (int)regionsize + 3; | 3461 | int heightmapHeightSamples = (int)regionsize + 2; |
3448 | 3462 | ||
3449 | // Array of height samples for ODE | 3463 | // Array of height samples for ODE |
3450 | float[] _heightmap; | 3464 | float[] _heightmap; |
@@ -3481,7 +3495,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3481 | // Output x = 0 1 2 3 ..... 255 256 257 258 total out | 3495 | // Output x = 0 1 2 3 ..... 255 256 257 258 total out |
3482 | float val= heightMap[(yy * regionsize) + xx]; // input from heightMap, <0-255 * 256> <0-255> | 3496 | float val= heightMap[(yy * regionsize) + xx]; // input from heightMap, <0-255 * 256> <0-255> |
3483 | if (val < minele) val = minele; | 3497 | if (val < minele) val = minele; |
3484 | _heightmap[x * (heightmapHeightSamples) + y] = val; // samples output to _heightmap, <0-257 * 258> <0-257> | 3498 | _heightmap[x * (regionsize + 2) + y] = val; // samples output to _heightmap, <0-257 * 258> <0-257> |
3485 | hfmin = (val < hfmin) ? val : hfmin; | 3499 | hfmin = (val < hfmin) ? val : hfmin; |
3486 | hfmax = (val > hfmax) ? val : hfmax; | 3500 | hfmax = (val > hfmax) ? val : hfmax; |
3487 | } | 3501 | } |
@@ -3531,8 +3545,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3531 | d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle); | 3545 | d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle); |
3532 | d.GeomSetRotation(GroundGeom, ref R); | 3546 | d.GeomSetRotation(GroundGeom, ref R); |
3533 | d.GeomSetPosition(GroundGeom, (pOffset.X + (regionsize * 0.5f)) - 0.5f, (pOffset.Y + (regionsize * 0.5f)) - 0.5f, 0); | 3547 | d.GeomSetPosition(GroundGeom, (pOffset.X + (regionsize * 0.5f)) - 0.5f, (pOffset.Y + (regionsize * 0.5f)) - 0.5f, 0); |
3534 | // having nsamples = size + 1 center is actually at size/2 | ||
3535 | d.GeomSetPosition(GroundGeom, (pOffset.X + (regionsize * 0.5f)), (pOffset.Y + (regionsize * 0.5f)), 0); | ||
3536 | IntPtr testGround = IntPtr.Zero; | 3548 | IntPtr testGround = IntPtr.Zero; |
3537 | if (RegionTerrain.TryGetValue(pOffset, out testGround)) | 3549 | if (RegionTerrain.TryGetValue(pOffset, out testGround)) |
3538 | { | 3550 | { |
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs index 80218e7..c9d0909 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs | |||
@@ -83,7 +83,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
83 | private Vector3 m_linearFrictionTimescale = new Vector3(1000, 1000, 1000); | 83 | private Vector3 m_linearFrictionTimescale = new Vector3(1000, 1000, 1000); |
84 | private float m_linearMotorDecayTimescale = 120; | 84 | private float m_linearMotorDecayTimescale = 120; |
85 | private float m_linearMotorTimescale = 1000; | 85 | private float m_linearMotorTimescale = 1000; |
86 | private Vector3 m_lastLinearVelocityVector = Vector3.Zero; | ||
87 | private Vector3 m_linearMotorOffset = Vector3.Zero; | 86 | private Vector3 m_linearMotorOffset = Vector3.Zero; |
88 | 87 | ||
89 | //Angular properties | 88 | //Angular properties |
@@ -91,7 +90,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
91 | private float m_angularMotorTimescale = 1000; // motor angular velocity ramp up rate | 90 | private float m_angularMotorTimescale = 1000; // motor angular velocity ramp up rate |
92 | private float m_angularMotorDecayTimescale = 120; // motor angular velocity decay rate | 91 | private float m_angularMotorDecayTimescale = 120; // motor angular velocity decay rate |
93 | private Vector3 m_angularFrictionTimescale = new Vector3(1000, 1000, 1000); // body angular velocity decay rate | 92 | private Vector3 m_angularFrictionTimescale = new Vector3(1000, 1000, 1000); // body angular velocity decay rate |
94 | private Vector3 m_lastAngularVelocity = Vector3.Zero; // what was last applied to body | ||
95 | 93 | ||
96 | //Deflection properties | 94 | //Deflection properties |
97 | private float m_angularDeflectionEfficiency = 0; | 95 | private float m_angularDeflectionEfficiency = 0; |
@@ -102,7 +100,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
102 | //Banking properties | 100 | //Banking properties |
103 | private float m_bankingEfficiency = 0; | 101 | private float m_bankingEfficiency = 0; |
104 | private float m_bankingMix = 0; | 102 | private float m_bankingMix = 0; |
105 | private float m_bankingTimescale = 0; | 103 | private float m_bankingTimescale = 1000; |
106 | 104 | ||
107 | //Hover and Buoyancy properties | 105 | //Hover and Buoyancy properties |
108 | private float m_VhoverHeight = 0f; | 106 | private float m_VhoverHeight = 0f; |
@@ -117,9 +115,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
117 | private float m_verticalAttractionEfficiency = 1.0f; // damped | 115 | private float m_verticalAttractionEfficiency = 1.0f; // damped |
118 | private float m_verticalAttractionTimescale = 1000f; // Timescale > 300 means no vert attractor. | 116 | private float m_verticalAttractionTimescale = 1000f; // Timescale > 300 means no vert attractor. |
119 | 117 | ||
120 | // auxiliar | ||
121 | private Vector3 m_dir = Vector3.Zero; // velocity applied to body | ||
122 | 118 | ||
119 | // auxiliar | ||
123 | private float m_lmEfect = 0; // current linear motor eficiency | 120 | private float m_lmEfect = 0; // current linear motor eficiency |
124 | private float m_amEfect = 0; // current angular motor eficiency | 121 | private float m_amEfect = 0; // current angular motor eficiency |
125 | 122 | ||
@@ -130,6 +127,82 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
130 | _pParentScene = rootPrim._parent_scene; | 127 | _pParentScene = rootPrim._parent_scene; |
131 | } | 128 | } |
132 | 129 | ||
130 | |||
131 | public void DoSetVehicle(VehicleData vd) | ||
132 | { | ||
133 | |||
134 | float timestep = _pParentScene.ODE_STEPSIZE; | ||
135 | float invtimestep = 1.0f / timestep; | ||
136 | |||
137 | m_type = vd.m_type; | ||
138 | m_flags = vd.m_flags; | ||
139 | |||
140 | // Linear properties | ||
141 | m_linearMotorDirection = vd.m_linearMotorDirection; | ||
142 | |||
143 | m_linearFrictionTimescale = vd.m_linearFrictionTimescale; | ||
144 | if (m_linearFrictionTimescale.X < timestep) m_linearFrictionTimescale.X = timestep; | ||
145 | if (m_linearFrictionTimescale.Y < timestep) m_linearFrictionTimescale.Y = timestep; | ||
146 | if (m_linearFrictionTimescale.Z < timestep) m_linearFrictionTimescale.Z = timestep; | ||
147 | |||
148 | m_linearMotorDecayTimescale = vd.m_linearMotorDecayTimescale; | ||
149 | if (m_linearMotorDecayTimescale < 0.5f) m_linearMotorDecayTimescale = 0.5f; | ||
150 | m_linearMotorDecayTimescale *= invtimestep; | ||
151 | |||
152 | m_linearMotorTimescale = vd.m_linearMotorTimescale; | ||
153 | if (m_linearMotorTimescale < timestep) m_linearMotorTimescale = timestep; | ||
154 | |||
155 | m_linearMotorOffset = vd.m_linearMotorOffset; | ||
156 | |||
157 | //Angular properties | ||
158 | m_angularMotorDirection = vd.m_angularMotorDirection; | ||
159 | m_angularMotorTimescale = vd.m_angularMotorTimescale; | ||
160 | if (m_angularMotorTimescale < timestep) m_angularMotorTimescale = timestep; | ||
161 | |||
162 | m_angularMotorDecayTimescale = vd.m_angularMotorDecayTimescale; | ||
163 | if (m_angularMotorDecayTimescale < 0.5f) m_angularMotorDecayTimescale = 0.5f; | ||
164 | m_angularMotorDecayTimescale *= invtimestep; | ||
165 | |||
166 | m_angularFrictionTimescale = vd.m_angularFrictionTimescale; | ||
167 | if (m_angularFrictionTimescale.X < timestep) m_angularFrictionTimescale.X = timestep; | ||
168 | if (m_angularFrictionTimescale.Y < timestep) m_angularFrictionTimescale.Y = timestep; | ||
169 | if (m_angularFrictionTimescale.Z < timestep) m_angularFrictionTimescale.Z = timestep; | ||
170 | |||
171 | //Deflection properties | ||
172 | m_angularDeflectionEfficiency = vd.m_angularDeflectionEfficiency; | ||
173 | m_angularDeflectionTimescale = vd.m_angularDeflectionTimescale; | ||
174 | if (m_angularDeflectionTimescale < timestep) m_angularDeflectionTimescale = timestep; | ||
175 | |||
176 | m_linearDeflectionEfficiency = vd.m_linearDeflectionEfficiency; | ||
177 | m_linearDeflectionTimescale = vd.m_linearDeflectionTimescale; | ||
178 | if (m_linearDeflectionTimescale < timestep) m_linearDeflectionTimescale = timestep; | ||
179 | |||
180 | //Banking properties | ||
181 | m_bankingEfficiency = vd.m_bankingEfficiency; | ||
182 | m_bankingMix = vd.m_bankingMix; | ||
183 | m_bankingTimescale = vd.m_bankingTimescale; | ||
184 | if (m_bankingTimescale < timestep) m_bankingTimescale = timestep; | ||
185 | |||
186 | //Hover and Buoyancy properties | ||
187 | m_VhoverHeight = vd.m_VhoverHeight; | ||
188 | m_VhoverEfficiency = vd.m_VhoverEfficiency; | ||
189 | m_VhoverTimescale = vd.m_VhoverTimescale; | ||
190 | if (m_VhoverTimescale < timestep) m_VhoverTimescale = timestep; | ||
191 | |||
192 | m_VehicleBuoyancy = vd.m_VehicleBuoyancy; | ||
193 | |||
194 | //Attractor properties | ||
195 | m_verticalAttractionEfficiency = vd.m_verticalAttractionEfficiency; | ||
196 | m_verticalAttractionTimescale = vd.m_verticalAttractionTimescale; | ||
197 | if (m_verticalAttractionTimescale < timestep) m_verticalAttractionTimescale = timestep; | ||
198 | |||
199 | // Axis | ||
200 | m_referenceFrame = vd.m_referenceFrame; | ||
201 | |||
202 | m_lmEfect = 0; | ||
203 | m_amEfect = 0; | ||
204 | } | ||
205 | |||
133 | internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue) | 206 | internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue) |
134 | { | 207 | { |
135 | float len; | 208 | float len; |
@@ -231,6 +304,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
231 | if (len > 12.566f) | 304 | if (len > 12.566f) |
232 | m_angularMotorDirection *= (12.566f / len); | 305 | m_angularMotorDirection *= (12.566f / len); |
233 | m_amEfect = 1.0f; // turn it on | 306 | m_amEfect = 1.0f; // turn it on |
307 | if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body) | ||
308 | && !rootPrim.m_isSelected && !rootPrim.m_disabled) | ||
309 | d.BodyEnable(rootPrim.Body); | ||
234 | break; | 310 | break; |
235 | case Vehicle.LINEAR_FRICTION_TIMESCALE: | 311 | case Vehicle.LINEAR_FRICTION_TIMESCALE: |
236 | if (pValue < timestep) pValue = timestep; | 312 | if (pValue < timestep) pValue = timestep; |
@@ -242,6 +318,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
242 | if (len > 30.0f) | 318 | if (len > 30.0f) |
243 | m_linearMotorDirection *= (30.0f / len); | 319 | m_linearMotorDirection *= (30.0f / len); |
244 | m_lmEfect = 1.0f; // turn it on | 320 | m_lmEfect = 1.0f; // turn it on |
321 | if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body) | ||
322 | && !rootPrim.m_isSelected && !rootPrim.m_disabled) | ||
323 | d.BodyEnable(rootPrim.Body); | ||
245 | break; | 324 | break; |
246 | case Vehicle.LINEAR_MOTOR_OFFSET: | 325 | case Vehicle.LINEAR_MOTOR_OFFSET: |
247 | m_linearMotorOffset = new Vector3(pValue, pValue, pValue); | 326 | m_linearMotorOffset = new Vector3(pValue, pValue, pValue); |
@@ -273,6 +352,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
273 | if (len > 12.566f) | 352 | if (len > 12.566f) |
274 | m_angularMotorDirection *= (12.566f / len); | 353 | m_angularMotorDirection *= (12.566f / len); |
275 | m_amEfect = 1.0f; // turn it on | 354 | m_amEfect = 1.0f; // turn it on |
355 | if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body) | ||
356 | && !rootPrim.m_isSelected && !rootPrim.m_disabled) | ||
357 | d.BodyEnable(rootPrim.Body); | ||
276 | break; | 358 | break; |
277 | case Vehicle.LINEAR_FRICTION_TIMESCALE: | 359 | case Vehicle.LINEAR_FRICTION_TIMESCALE: |
278 | if (pValue.X < timestep) pValue.X = timestep; | 360 | if (pValue.X < timestep) pValue.X = timestep; |
@@ -286,6 +368,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
286 | if (len > 30.0f) | 368 | if (len > 30.0f) |
287 | m_linearMotorDirection *= (30.0f / len); | 369 | m_linearMotorDirection *= (30.0f / len); |
288 | m_lmEfect = 1.0f; // turn it on | 370 | m_lmEfect = 1.0f; // turn it on |
371 | if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body) | ||
372 | && !rootPrim.m_isSelected && !rootPrim.m_disabled) | ||
373 | d.BodyEnable(rootPrim.Body); | ||
289 | break; | 374 | break; |
290 | case Vehicle.LINEAR_MOTOR_OFFSET: | 375 | case Vehicle.LINEAR_MOTOR_OFFSET: |
291 | m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z); | 376 | m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z); |
@@ -347,12 +432,23 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
347 | m_linearFrictionTimescale = new Vector3(1000, 1000, 1000); | 432 | m_linearFrictionTimescale = new Vector3(1000, 1000, 1000); |
348 | m_angularFrictionTimescale = new Vector3(1000, 1000, 1000); | 433 | m_angularFrictionTimescale = new Vector3(1000, 1000, 1000); |
349 | m_linearMotorTimescale = 1000; | 434 | m_linearMotorTimescale = 1000; |
350 | m_linearMotorDecayTimescale = 120 * invtimestep; | 435 | m_linearMotorDecayTimescale = 120; |
351 | m_angularMotorTimescale = 1000; | 436 | m_angularMotorTimescale = 1000; |
352 | m_angularMotorDecayTimescale = 1000 * invtimestep; | 437 | m_angularMotorDecayTimescale = 1000; |
353 | m_VhoverHeight = 0; | 438 | m_VhoverHeight = 0; |
439 | m_VhoverEfficiency = 1; | ||
354 | m_VhoverTimescale = 1000; | 440 | m_VhoverTimescale = 1000; |
355 | m_VehicleBuoyancy = 0; | 441 | m_VehicleBuoyancy = 0; |
442 | m_linearDeflectionEfficiency = 0; | ||
443 | m_linearDeflectionTimescale = 1000; | ||
444 | m_angularDeflectionEfficiency = 0; | ||
445 | m_angularDeflectionTimescale = 1000; | ||
446 | m_bankingEfficiency = 0; | ||
447 | m_bankingMix = 1; | ||
448 | m_bankingTimescale = 1000; | ||
449 | m_verticalAttractionEfficiency = 0; | ||
450 | m_verticalAttractionTimescale = 1000; | ||
451 | |||
356 | m_flags = (VehicleFlag)0; | 452 | m_flags = (VehicleFlag)0; |
357 | break; | 453 | break; |
358 | 454 | ||
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs index 3b7f562..0ccdbc0 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs | |||
@@ -111,7 +111,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
111 | | CollisionCategories.Body | 111 | | CollisionCategories.Body |
112 | | CollisionCategories.Character | 112 | | CollisionCategories.Character |
113 | ); | 113 | ); |
114 | private bool m_collidesLand = true; | 114 | // private bool m_collidesLand = true; |
115 | private bool m_collidesWater; | 115 | private bool m_collidesWater; |
116 | public bool m_returnCollisions; | 116 | public bool m_returnCollisions; |
117 | 117 | ||
@@ -122,7 +122,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
122 | private CollisionCategories m_collisionFlags = m_default_collisionFlags; | 122 | private CollisionCategories m_collisionFlags = m_default_collisionFlags; |
123 | 123 | ||
124 | public bool m_disabled; | 124 | public bool m_disabled; |
125 | public bool m_taintselected; | 125 | |
126 | 126 | ||
127 | public uint m_localID; | 127 | public uint m_localID; |
128 | 128 | ||
@@ -142,20 +142,19 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
142 | private List<OdePrim> childrenPrim = new List<OdePrim>(); | 142 | private List<OdePrim> childrenPrim = new List<OdePrim>(); |
143 | 143 | ||
144 | private bool m_iscolliding; | 144 | private bool m_iscolliding; |
145 | private bool m_wascolliding; | 145 | |
146 | private bool m_isSelected; | 146 | public bool m_isSelected; |
147 | private bool m_delaySelect; | ||
148 | private bool m_lastdoneSelected; | ||
149 | public bool m_outbounds; | ||
147 | 150 | ||
148 | internal bool m_isVolumeDetect; // If true, this prim only detects collisions but doesn't collide actively | 151 | internal bool m_isVolumeDetect; // If true, this prim only detects collisions but doesn't collide actively |
149 | 152 | ||
150 | private bool m_throttleUpdates; | 153 | private bool m_throttleUpdates; |
151 | private int throttleCounter; | 154 | private int throttleCounter; |
152 | public int m_interpenetrationcount; | ||
153 | public float m_collisionscore; | 155 | public float m_collisionscore; |
154 | int m_colliderfilter = 0; | 156 | int m_colliderfilter = 0; |
155 | public int m_roundsUnderMotionThreshold; | ||
156 | private int m_crossingfailures; | ||
157 | 157 | ||
158 | public bool outofBounds; | ||
159 | private float m_density = 10.000006836f; // Aluminum g/cm3; | 158 | private float m_density = 10.000006836f; // Aluminum g/cm3; |
160 | 159 | ||
161 | public bool _zeroFlag; | 160 | public bool _zeroFlag; |
@@ -166,12 +165,11 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
166 | private Vector3 _target_velocity; | 165 | private Vector3 _target_velocity; |
167 | 166 | ||
168 | public Vector3 primOOBsize; // prim real dimensions from mesh | 167 | public Vector3 primOOBsize; // prim real dimensions from mesh |
169 | public Vector3 primOOBoffset; // is centroid out of mesh or rest aabb | 168 | public Vector3 primOOBoffset; // its centroid out of mesh or rest aabb |
170 | public float primOOBradiusSQ; | 169 | public float primOOBradiusSQ; |
171 | public d.Mass primdMass; // prim inertia information on it's own referencial | 170 | public d.Mass primdMass; // prim inertia information on it's own referencial |
172 | float primMass; // prim own mass | 171 | float primMass; // prim own mass |
173 | float _mass; // object mass acording to case | 172 | float _mass; // object mass acording to case |
174 | public d.Mass objectpMass; // object last computed inertia | ||
175 | private bool hasOOBoffsetFromMesh = false; // if true we did compute it form mesh centroid, else from aabb | 173 | private bool hasOOBoffsetFromMesh = false; // if true we did compute it form mesh centroid, else from aabb |
176 | 174 | ||
177 | public int givefakepos = 0; | 175 | public int givefakepos = 0; |
@@ -182,9 +180,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
182 | public int m_eventsubscription; | 180 | public int m_eventsubscription; |
183 | private CollisionEventUpdate CollisionEventsThisFrame = new CollisionEventUpdate(); | 181 | private CollisionEventUpdate CollisionEventsThisFrame = new CollisionEventUpdate(); |
184 | 182 | ||
185 | private IntPtr m_linkJoint = IntPtr.Zero; | ||
186 | private IntPtr _linkJointGroup = IntPtr.Zero; | ||
187 | |||
188 | public volatile bool childPrim; | 183 | public volatile bool childPrim; |
189 | 184 | ||
190 | public ODEDynamics m_vehicle; | 185 | public ODEDynamics m_vehicle; |
@@ -264,7 +259,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
264 | set | 259 | set |
265 | { | 260 | { |
266 | if (value) | 261 | if (value) |
267 | m_isSelected = value; | 262 | m_isSelected = value; // if true set imediatly to stop moves etc |
268 | AddChange(changes.Selected, value); | 263 | AddChange(changes.Selected, value); |
269 | } | 264 | } |
270 | } | 265 | } |
@@ -298,13 +293,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
298 | m_iscolliding = false; | 293 | m_iscolliding = false; |
299 | else | 294 | else |
300 | m_iscolliding = true; | 295 | m_iscolliding = true; |
301 | |||
302 | if (m_wascolliding != m_iscolliding) | ||
303 | { | ||
304 | if (m_wascolliding && !m_isSelected && Body != IntPtr.Zero) | ||
305 | d.BodyEnable(Body); | ||
306 | m_wascolliding = m_iscolliding; | ||
307 | } | ||
308 | } | 296 | } |
309 | } | 297 | } |
310 | 298 | ||
@@ -665,19 +653,21 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
665 | strVehicleQuatParam fp = new strVehicleQuatParam(); | 653 | strVehicleQuatParam fp = new strVehicleQuatParam(); |
666 | fp.param = param; | 654 | fp.param = param; |
667 | fp.value = value; | 655 | fp.value = value; |
668 | AddChange(changes.VehicleVectorParam, fp); | 656 | AddChange(changes.VehicleRotationParam, fp); |
669 | } | 657 | } |
670 | 658 | ||
671 | public override void VehicleFlags(int param, bool value) | 659 | public override void VehicleFlags(int param, bool value) |
672 | { | 660 | { |
673 | if (m_vehicle == null) | ||
674 | return; | ||
675 | strVehicleBoolParam bp = new strVehicleBoolParam(); | 661 | strVehicleBoolParam bp = new strVehicleBoolParam(); |
676 | bp.param = param; | 662 | bp.param = param; |
677 | bp.value = value; | 663 | bp.value = value; |
678 | AddChange(changes.VehicleFlags, bp); | 664 | AddChange(changes.VehicleFlags, bp); |
679 | } | 665 | } |
680 | 666 | ||
667 | public override void SetVehicle(object vdata) | ||
668 | { | ||
669 | AddChange(changes.SetVehicle, vdata); | ||
670 | } | ||
681 | public void SetAcceleration(Vector3 accel) | 671 | public void SetAcceleration(Vector3 accel) |
682 | { | 672 | { |
683 | _acceleration = accel; | 673 | _acceleration = accel; |
@@ -710,8 +700,30 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
710 | 700 | ||
711 | public override void CrossingFailure() | 701 | public override void CrossingFailure() |
712 | { | 702 | { |
713 | m_crossingfailures++; | 703 | if (m_outbounds) |
714 | changeDisable(false); | 704 | { |
705 | _position.X = Util.Clip(_position.X, 0.5f, _parent_scene.WorldExtents.X - 0.5f); | ||
706 | _position.Y = Util.Clip(_position.Y, 0.5f, _parent_scene.WorldExtents.Y - 0.5f); | ||
707 | _position.Z = Util.Clip(_position.Z + 0.2f, -100f, 50000f); | ||
708 | |||
709 | m_lastposition = _position; | ||
710 | _velocity.X = 0; | ||
711 | _velocity.Y = 0; | ||
712 | _velocity.Z = 0; | ||
713 | |||
714 | m_lastVelocity = _velocity; | ||
715 | if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE) | ||
716 | m_vehicle.Stop(); | ||
717 | |||
718 | if(Body != IntPtr.Zero) | ||
719 | d.BodySetLinearVel(Body, 0, 0, 0); // stop it | ||
720 | if (prim_geom != IntPtr.Zero) | ||
721 | d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); | ||
722 | |||
723 | m_outbounds = false; | ||
724 | changeDisable(false); | ||
725 | base.RequestPhysicsterseUpdate(); | ||
726 | } | ||
715 | } | 727 | } |
716 | 728 | ||
717 | public override void SetMomentum(Vector3 momentum) | 729 | public override void SetMomentum(Vector3 momentum) |
@@ -865,12 +877,14 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
865 | m_force = Vector3.Zero; | 877 | m_force = Vector3.Zero; |
866 | 878 | ||
867 | m_iscolliding = false; | 879 | m_iscolliding = false; |
868 | m_wascolliding = false; | ||
869 | m_colliderfilter = 0; | 880 | m_colliderfilter = 0; |
870 | 881 | ||
871 | hasOOBoffsetFromMesh = false; | 882 | hasOOBoffsetFromMesh = false; |
872 | _triMeshData = IntPtr.Zero; | 883 | _triMeshData = IntPtr.Zero; |
873 | 884 | ||
885 | m_lastdoneSelected = false; | ||
886 | m_isSelected = false; | ||
887 | m_delaySelect = false; | ||
874 | 888 | ||
875 | primContactData.mu = parent_scene.m_materialContactsData[(int)Material.Wood].mu; | 889 | primContactData.mu = parent_scene.m_materialContactsData[(int)Material.Wood].mu; |
876 | primContactData.bounce = parent_scene.m_materialContactsData[(int)Material.Wood].bounce; | 890 | primContactData.bounce = parent_scene.m_materialContactsData[(int)Material.Wood].bounce; |
@@ -885,8 +899,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
885 | private void resetCollisionAccounting() | 899 | private void resetCollisionAccounting() |
886 | { | 900 | { |
887 | m_collisionscore = 0; | 901 | m_collisionscore = 0; |
888 | m_interpenetrationcount = 0; | ||
889 | m_disabled = false; | ||
890 | } | 902 | } |
891 | 903 | ||
892 | private void createAMotor(Vector3 axis) | 904 | private void createAMotor(Vector3 axis) |
@@ -926,9 +938,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
926 | curr.W = dcur.W; | 938 | curr.W = dcur.W; |
927 | Vector3 ax; | 939 | Vector3 ax; |
928 | 940 | ||
929 | const int StopERP = 7; | ||
930 | const int StopCFM = 8; | ||
931 | |||
932 | int i = 0; | 941 | int i = 0; |
933 | int j = 0; | 942 | int j = 0; |
934 | if (axis.X == 0) | 943 | if (axis.X == 0) |
@@ -943,10 +952,10 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
943 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.FudgeFactor, 0.0001f); | 952 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.FudgeFactor, 0.0001f); |
944 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.Bounce, 0f); | 953 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.Bounce, 0f); |
945 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.FMax, 5e8f); | 954 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.FMax, 5e8f); |
946 | d.JointSetAMotorParam(Amotor, (int)StopCFM, 0f); | 955 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.StopCFM, 0f); |
947 | d.JointSetAMotorParam(Amotor, (int)StopERP, 0.8f); | 956 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.StopERP, 0.8f); |
948 | i++; | 957 | i++; |
949 | j = 256; // odeplugin.cs doesn't have all parameters so this moves to next axis set | 958 | j = 256; // move to next axis set |
950 | } | 959 | } |
951 | 960 | ||
952 | if (axis.Y == 0) | 961 | if (axis.Y == 0) |
@@ -960,8 +969,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
960 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FudgeFactor, 0.0001f); | 969 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FudgeFactor, 0.0001f); |
961 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Bounce, 0f); | 970 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Bounce, 0f); |
962 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FMax, 5e8f); | 971 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FMax, 5e8f); |
963 | d.JointSetAMotorParam(Amotor, j + (int)StopCFM, 0f); | 972 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopCFM, 0f); |
964 | d.JointSetAMotorParam(Amotor, j + (int)StopERP, 0.8f); | 973 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopERP, 0.8f); |
965 | i++; | 974 | i++; |
966 | j += 256; | 975 | j += 256; |
967 | } | 976 | } |
@@ -977,8 +986,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
977 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FudgeFactor, 0.0001f); | 986 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FudgeFactor, 0.0001f); |
978 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Bounce, 0f); | 987 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Bounce, 0f); |
979 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FMax, 5e8f); | 988 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FMax, 5e8f); |
980 | d.JointSetAMotorParam(Amotor, j + (int)StopCFM, 0f); | 989 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopCFM, 0f); |
981 | d.JointSetAMotorParam(Amotor, j + (int)StopERP, 0.8f); | 990 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopERP, 0.8f); |
982 | } | 991 | } |
983 | } | 992 | } |
984 | 993 | ||
@@ -1186,24 +1195,10 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1186 | 1195 | ||
1187 | public void enableBodySoft() | 1196 | public void enableBodySoft() |
1188 | { | 1197 | { |
1189 | if (!childPrim) | 1198 | if (!childPrim && !m_isSelected) |
1190 | { | 1199 | { |
1191 | if (m_isphysical && Body != IntPtr.Zero && prim_geom != IntPtr.Zero) | 1200 | if (m_isphysical && Body != IntPtr.Zero && prim_geom != IntPtr.Zero) |
1192 | { | 1201 | { |
1193 | if (m_targetSpace != _parent_scene.ActiveSpace) | ||
1194 | { | ||
1195 | m_targetSpace = _parent_scene.ActiveSpace; | ||
1196 | |||
1197 | foreach (OdePrim prm in childrenPrim) | ||
1198 | { | ||
1199 | if (prm.prim_geom != IntPtr.Zero) | ||
1200 | { | ||
1201 | d.SpaceAdd(m_targetSpace, prm.prim_geom); | ||
1202 | prm.m_targetSpace = m_targetSpace; | ||
1203 | } | ||
1204 | } | ||
1205 | d.SpaceAdd(m_targetSpace, prim_geom); | ||
1206 | } | ||
1207 | d.GeomEnable(prim_geom); | 1202 | d.GeomEnable(prim_geom); |
1208 | foreach (OdePrim prm in childrenPrim) | 1203 | foreach (OdePrim prm in childrenPrim) |
1209 | d.GeomEnable(prm.prim_geom); | 1204 | d.GeomEnable(prm.prim_geom); |
@@ -1211,6 +1206,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1211 | d.BodyEnable(Body); | 1206 | d.BodyEnable(Body); |
1212 | } | 1207 | } |
1213 | } | 1208 | } |
1209 | m_disabled = false; | ||
1214 | resetCollisionAccounting(); // this sets m_disable to false | 1210 | resetCollisionAccounting(); // this sets m_disable to false |
1215 | } | 1211 | } |
1216 | 1212 | ||
@@ -1221,19 +1217,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1221 | { | 1217 | { |
1222 | if (m_isphysical && Body != IntPtr.Zero && prim_geom != IntPtr.Zero) | 1218 | if (m_isphysical && Body != IntPtr.Zero && prim_geom != IntPtr.Zero) |
1223 | { | 1219 | { |
1224 | if (m_targetSpace == _parent_scene.ActiveSpace) | ||
1225 | { | ||
1226 | foreach (OdePrim prm in childrenPrim) | ||
1227 | { | ||
1228 | if (prm.m_targetSpace != IntPtr.Zero && prm.prim_geom != IntPtr.Zero) | ||
1229 | { | ||
1230 | d.SpaceRemove(prm.m_targetSpace, prm.prim_geom); | ||
1231 | prm.m_targetSpace = IntPtr.Zero; | ||
1232 | } | ||
1233 | } | ||
1234 | d.SpaceRemove(m_targetSpace, prim_geom); | ||
1235 | m_targetSpace = IntPtr.Zero; | ||
1236 | } | ||
1237 | d.GeomDisable(prim_geom); | 1220 | d.GeomDisable(prim_geom); |
1238 | foreach (OdePrim prm in childrenPrim) | 1221 | foreach (OdePrim prm in childrenPrim) |
1239 | d.GeomDisable(prm.prim_geom); | 1222 | d.GeomDisable(prm.prim_geom); |
@@ -1369,9 +1352,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1369 | d.BodySetMass(Body, ref objdmass); | 1352 | d.BodySetMass(Body, ref objdmass); |
1370 | _mass = objdmass.mass; | 1353 | _mass = objdmass.mass; |
1371 | 1354 | ||
1372 | m_collisionCategories |= CollisionCategories.Body; | ||
1373 | m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); | ||
1374 | |||
1375 | // disconnect from world gravity so we can apply buoyancy | 1355 | // disconnect from world gravity so we can apply buoyancy |
1376 | d.BodySetGravityMode(Body, false); | 1356 | d.BodySetGravityMode(Body, false); |
1377 | 1357 | ||
@@ -1379,16 +1359,14 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1379 | d.BodySetAutoDisableSteps(Body, body_autodisable_frames); | 1359 | d.BodySetAutoDisableSteps(Body, body_autodisable_frames); |
1380 | // d.BodySetLinearDampingThreshold(Body, 0.01f); | 1360 | // d.BodySetLinearDampingThreshold(Body, 0.01f); |
1381 | // d.BodySetAngularDampingThreshold(Body, 0.001f); | 1361 | // d.BodySetAngularDampingThreshold(Body, 0.001f); |
1382 | d.BodySetDamping(Body, .001f, .0002f); | 1362 | d.BodySetDamping(Body, .002f, .002f); |
1383 | 1363 | ||
1364 | m_collisionCategories |= CollisionCategories.Body; | ||
1365 | m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); | ||
1384 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); | 1366 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); |
1385 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); | 1367 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); |
1386 | |||
1387 | m_interpenetrationcount = 0; | ||
1388 | m_collisionscore = 0; | 1368 | m_collisionscore = 0; |
1389 | 1369 | ||
1390 | m_disabled = false; | ||
1391 | |||
1392 | if (m_targetSpace != _parent_scene.ActiveSpace) | 1370 | if (m_targetSpace != _parent_scene.ActiveSpace) |
1393 | { | 1371 | { |
1394 | if (m_targetSpace != IntPtr.Zero) | 1372 | if (m_targetSpace != IntPtr.Zero) |
@@ -1416,6 +1394,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1416 | prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); | 1394 | prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); |
1417 | d.GeomSetCategoryBits(prm.prim_geom, (int)prm.m_collisionCategories); | 1395 | d.GeomSetCategoryBits(prm.prim_geom, (int)prm.m_collisionCategories); |
1418 | d.GeomSetCollideBits(prm.prim_geom, (int)prm.m_collisionFlags); | 1396 | d.GeomSetCollideBits(prm.prim_geom, (int)prm.m_collisionFlags); |
1397 | prm.m_collisionscore = 0; | ||
1419 | 1398 | ||
1420 | if (prm.m_targetSpace != _parent_scene.ActiveSpace) | 1399 | if (prm.m_targetSpace != _parent_scene.ActiveSpace) |
1421 | { | 1400 | { |
@@ -1428,10 +1407,11 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1428 | prm.m_targetSpace = _parent_scene.ActiveSpace; | 1407 | prm.m_targetSpace = _parent_scene.ActiveSpace; |
1429 | d.SpaceAdd(m_targetSpace, prm.prim_geom); | 1408 | d.SpaceAdd(m_targetSpace, prm.prim_geom); |
1430 | } | 1409 | } |
1431 | d.GeomEnable(prm.prim_geom); | 1410 | |
1411 | if (m_isSelected || m_disabled) | ||
1412 | d.GeomDisable(prm.prim_geom); | ||
1413 | |||
1432 | prm.m_disabled = false; | 1414 | prm.m_disabled = false; |
1433 | prm.m_interpenetrationcount = 0; | ||
1434 | prm.m_collisionscore = 0; | ||
1435 | _parent_scene.addActivePrim(prm); | 1415 | _parent_scene.addActivePrim(prm); |
1436 | } | 1416 | } |
1437 | } | 1417 | } |
@@ -1442,8 +1422,12 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1442 | createAMotor(m_angularlock); | 1422 | createAMotor(m_angularlock); |
1443 | } | 1423 | } |
1444 | 1424 | ||
1445 | d.GeomEnable(prim_geom); | 1425 | if (m_isSelected || m_disabled) |
1446 | m_disabled = false; | 1426 | { |
1427 | d.GeomDisable(prim_geom); | ||
1428 | d.BodyDisable(Body); | ||
1429 | } | ||
1430 | |||
1447 | _parent_scene.addActivePrim(this); | 1431 | _parent_scene.addActivePrim(this); |
1448 | } | 1432 | } |
1449 | 1433 | ||
@@ -1484,12 +1468,16 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1484 | prm.m_collisionscore = 0; | 1468 | prm.m_collisionscore = 0; |
1485 | } | 1469 | } |
1486 | } | 1470 | } |
1471 | if (Amotor != IntPtr.Zero) | ||
1472 | { | ||
1473 | d.JointDestroy(Amotor); | ||
1474 | Amotor = IntPtr.Zero; | ||
1475 | } | ||
1487 | d.BodyDestroy(Body); | 1476 | d.BodyDestroy(Body); |
1488 | } | 1477 | } |
1489 | Body = IntPtr.Zero; | 1478 | Body = IntPtr.Zero; |
1490 | } | 1479 | } |
1491 | _mass = primMass; | 1480 | _mass = primMass; |
1492 | m_disabled = true; | ||
1493 | m_collisionscore = 0; | 1481 | m_collisionscore = 0; |
1494 | } | 1482 | } |
1495 | 1483 | ||
@@ -2115,49 +2103,72 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2115 | d.BodySetTorque(Body, 0f, 0f, 0f); | 2103 | d.BodySetTorque(Body, 0f, 0f, 0f); |
2116 | d.BodySetLinearVel(Body, 0f, 0f, 0f); | 2104 | d.BodySetLinearVel(Body, 0f, 0f, 0f); |
2117 | d.BodySetAngularVel(Body, 0f, 0f, 0f); | 2105 | d.BodySetAngularVel(Body, 0f, 0f, 0f); |
2118 | |||
2119 | } | 2106 | } |
2120 | } | 2107 | } |
2121 | 2108 | ||
2122 | private void changeSelectedStatus(bool newval) | 2109 | private void changeSelectedStatus(bool newval) |
2123 | { | 2110 | { |
2111 | if (m_lastdoneSelected == newval) | ||
2112 | return; | ||
2113 | |||
2114 | m_lastdoneSelected = newval; | ||
2115 | DoSelectedStatus(newval); | ||
2116 | } | ||
2117 | |||
2118 | private void CheckDelaySelect() | ||
2119 | { | ||
2120 | if (m_delaySelect) | ||
2121 | { | ||
2122 | DoSelectedStatus(m_isSelected); | ||
2123 | } | ||
2124 | } | ||
2125 | |||
2126 | private void DoSelectedStatus(bool newval) | ||
2127 | { | ||
2124 | m_isSelected = newval; | 2128 | m_isSelected = newval; |
2125 | Stop(); | 2129 | Stop(); |
2126 | 2130 | ||
2127 | if (newval) | 2131 | if (newval) |
2128 | { | 2132 | { |
2129 | m_collisionCategories = CollisionCategories.Selected; | 2133 | if (!childPrim && Body != IntPtr.Zero) |
2130 | m_collisionFlags = (CollisionCategories.Sensor | CollisionCategories.Space); | 2134 | d.BodyDisable(Body); |
2131 | 2135 | ||
2132 | if (prim_geom != IntPtr.Zero) | 2136 | if (m_delaySelect) |
2133 | { | 2137 | { |
2134 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); | 2138 | if (!childPrim) |
2135 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); | 2139 | { |
2140 | foreach (OdePrim prm in childrenPrim) | ||
2141 | { | ||
2142 | d.GeomDisable(prm.prim_geom); | ||
2143 | prm.m_delaySelect = false; | ||
2144 | } | ||
2145 | } | ||
2146 | d.GeomDisable(prim_geom); | ||
2147 | m_delaySelect = false; | ||
2148 | } | ||
2149 | else | ||
2150 | { | ||
2151 | m_delaySelect = true; | ||
2136 | } | 2152 | } |
2137 | |||
2138 | disableBodySoft(); | ||
2139 | } | 2153 | } |
2140 | else | 2154 | else |
2141 | { | 2155 | { |
2142 | m_collisionCategories = CollisionCategories.Geom; | 2156 | if (!childPrim && Body != IntPtr.Zero && !m_disabled) |
2143 | 2157 | d.BodyEnable(Body); | |
2144 | if (m_isphysical) | ||
2145 | m_collisionCategories |= CollisionCategories.Body; | ||
2146 | |||
2147 | m_collisionFlags = m_default_collisionFlags; | ||
2148 | |||
2149 | if (m_collidesLand) | ||
2150 | m_collisionFlags |= CollisionCategories.Land; | ||
2151 | if (m_collidesWater) | ||
2152 | m_collisionFlags |= CollisionCategories.Water; | ||
2153 | 2158 | ||
2154 | if (prim_geom != IntPtr.Zero) | 2159 | if (!childPrim) |
2155 | { | 2160 | { |
2156 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); | 2161 | foreach (OdePrim prm in childrenPrim) |
2157 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); | 2162 | { |
2163 | if(!prm.m_disabled) | ||
2164 | d.GeomEnable(prm.prim_geom); | ||
2165 | prm.m_delaySelect = false; | ||
2166 | } | ||
2158 | } | 2167 | } |
2168 | if(!m_disabled) | ||
2169 | d.GeomEnable(prim_geom); | ||
2159 | 2170 | ||
2160 | enableBodySoft(); | 2171 | m_delaySelect = false; |
2161 | } | 2172 | } |
2162 | 2173 | ||
2163 | resetCollisionAccounting(); | 2174 | resetCollisionAccounting(); |
@@ -2165,6 +2176,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2165 | 2176 | ||
2166 | private void changePosition(Vector3 newPos) | 2177 | private void changePosition(Vector3 newPos) |
2167 | { | 2178 | { |
2179 | CheckDelaySelect(); | ||
2168 | if (m_isphysical) | 2180 | if (m_isphysical) |
2169 | { | 2181 | { |
2170 | if (childPrim) // inertia is messed, must rebuild | 2182 | if (childPrim) // inertia is messed, must rebuild |
@@ -2207,6 +2219,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2207 | 2219 | ||
2208 | private void changeOrientation(Quaternion newOri) | 2220 | private void changeOrientation(Quaternion newOri) |
2209 | { | 2221 | { |
2222 | CheckDelaySelect(); | ||
2210 | if (m_isphysical) | 2223 | if (m_isphysical) |
2211 | { | 2224 | { |
2212 | if (childPrim) // inertia is messed, must rebuild | 2225 | if (childPrim) // inertia is messed, must rebuild |
@@ -2258,6 +2271,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2258 | 2271 | ||
2259 | private void changePositionAndOrientation(Vector3 newPos, Quaternion newOri) | 2272 | private void changePositionAndOrientation(Vector3 newPos, Quaternion newOri) |
2260 | { | 2273 | { |
2274 | CheckDelaySelect(); | ||
2261 | if (m_isphysical) | 2275 | if (m_isphysical) |
2262 | { | 2276 | { |
2263 | if (childPrim && m_building) // inertia is messed, must rebuild | 2277 | if (childPrim && m_building) // inertia is messed, must rebuild |
@@ -2342,6 +2356,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2342 | 2356 | ||
2343 | private void changePhysicsStatus(bool NewStatus) | 2357 | private void changePhysicsStatus(bool NewStatus) |
2344 | { | 2358 | { |
2359 | CheckDelaySelect(); | ||
2360 | |||
2345 | m_isphysical = NewStatus; | 2361 | m_isphysical = NewStatus; |
2346 | 2362 | ||
2347 | if (!childPrim) | 2363 | if (!childPrim) |
@@ -2384,6 +2400,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2384 | 2400 | ||
2385 | private void changeprimsizeshape() | 2401 | private void changeprimsizeshape() |
2386 | { | 2402 | { |
2403 | CheckDelaySelect(); | ||
2404 | |||
2387 | OdePrim parent = (OdePrim)_parent; | 2405 | OdePrim parent = (OdePrim)_parent; |
2388 | 2406 | ||
2389 | bool chp = childPrim; | 2407 | bool chp = childPrim; |
@@ -2508,7 +2526,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2508 | } | 2526 | } |
2509 | 2527 | ||
2510 | m_collisionscore = 0; | 2528 | m_collisionscore = 0; |
2511 | m_interpenetrationcount = 0; | ||
2512 | } | 2529 | } |
2513 | } | 2530 | } |
2514 | 2531 | ||
@@ -2528,7 +2545,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2528 | } | 2545 | } |
2529 | } | 2546 | } |
2530 | m_collisionscore = 0; | 2547 | m_collisionscore = 0; |
2531 | m_interpenetrationcount = 0; | ||
2532 | } | 2548 | } |
2533 | } | 2549 | } |
2534 | 2550 | ||
@@ -2565,6 +2581,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2565 | else | 2581 | else |
2566 | { | 2582 | { |
2567 | m_building = false; | 2583 | m_building = false; |
2584 | CheckDelaySelect(); | ||
2568 | if (!childPrim) | 2585 | if (!childPrim) |
2569 | MakeBody(); | 2586 | MakeBody(); |
2570 | } | 2587 | } |
@@ -2575,18 +2592,26 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2575 | } | 2592 | } |
2576 | } | 2593 | } |
2577 | 2594 | ||
2578 | private void changeVehicleType(int value) | 2595 | public void changeSetVehicle(VehicleData vdata) |
2579 | { | 2596 | { |
2580 | if (m_vehicle == null) | 2597 | if (m_vehicle == null) |
2598 | m_vehicle = new ODEDynamics(this); | ||
2599 | m_vehicle.DoSetVehicle(vdata); | ||
2600 | } | ||
2601 | private void changeVehicleType(int value) | ||
2602 | { | ||
2603 | if (value == (int)Vehicle.TYPE_NONE) | ||
2581 | { | 2604 | { |
2582 | if (value != (int)Vehicle.TYPE_NONE) | 2605 | if (m_vehicle != null) |
2583 | { | 2606 | m_vehicle = null; |
2584 | m_vehicle = new ODEDynamics(this); | ||
2585 | m_vehicle.ProcessTypeChange((Vehicle)value); | ||
2586 | } | ||
2587 | } | 2607 | } |
2588 | else | 2608 | else |
2609 | { | ||
2610 | if (m_vehicle == null) | ||
2611 | m_vehicle = new ODEDynamics(this); | ||
2612 | |||
2589 | m_vehicle.ProcessTypeChange((Vehicle)value); | 2613 | m_vehicle.ProcessTypeChange((Vehicle)value); |
2614 | } | ||
2590 | } | 2615 | } |
2591 | 2616 | ||
2592 | private void changeVehicleFloatParam(strVehicleFloatParam fp) | 2617 | private void changeVehicleFloatParam(strVehicleFloatParam fp) |
@@ -2595,8 +2620,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2595 | return; | 2620 | return; |
2596 | 2621 | ||
2597 | m_vehicle.ProcessFloatVehicleParam((Vehicle)fp.param, fp.value); | 2622 | m_vehicle.ProcessFloatVehicleParam((Vehicle)fp.param, fp.value); |
2598 | if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body)) | ||
2599 | d.BodyEnable(Body); | ||
2600 | } | 2623 | } |
2601 | 2624 | ||
2602 | private void changeVehicleVectorParam(strVehicleVectorParam vp) | 2625 | private void changeVehicleVectorParam(strVehicleVectorParam vp) |
@@ -2604,8 +2627,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2604 | if (m_vehicle == null) | 2627 | if (m_vehicle == null) |
2605 | return; | 2628 | return; |
2606 | m_vehicle.ProcessVectorVehicleParam((Vehicle)vp.param, vp.value); | 2629 | m_vehicle.ProcessVectorVehicleParam((Vehicle)vp.param, vp.value); |
2607 | if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body)) | ||
2608 | d.BodyEnable(Body); | ||
2609 | } | 2630 | } |
2610 | 2631 | ||
2611 | private void changeVehicleRotationParam(strVehicleQuatParam qp) | 2632 | private void changeVehicleRotationParam(strVehicleQuatParam qp) |
@@ -2613,8 +2634,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2613 | if (m_vehicle == null) | 2634 | if (m_vehicle == null) |
2614 | return; | 2635 | return; |
2615 | m_vehicle.ProcessRotationVehicleParam((Vehicle)qp.param, qp.value); | 2636 | m_vehicle.ProcessRotationVehicleParam((Vehicle)qp.param, qp.value); |
2616 | if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body)) | ||
2617 | d.BodyEnable(Body); | ||
2618 | } | 2637 | } |
2619 | 2638 | ||
2620 | private void changeVehicleFlags(strVehicleBoolParam bp) | 2639 | private void changeVehicleFlags(strVehicleBoolParam bp) |
@@ -2622,8 +2641,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2622 | if (m_vehicle == null) | 2641 | if (m_vehicle == null) |
2623 | return; | 2642 | return; |
2624 | m_vehicle.ProcessVehicleFlags(bp.param, bp.value); | 2643 | m_vehicle.ProcessVehicleFlags(bp.param, bp.value); |
2625 | if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body)) | ||
2626 | d.BodyEnable(Body); | ||
2627 | } | 2644 | } |
2628 | 2645 | ||
2629 | #endregion | 2646 | #endregion |
@@ -2849,41 +2866,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2849 | { | 2866 | { |
2850 | if (Body != IntPtr.Zero) | 2867 | if (Body != IntPtr.Zero) |
2851 | { | 2868 | { |
2852 | if (m_crossingfailures != 0 && m_crossingfailures < 5) | ||
2853 | { | ||
2854 | _position.X = Util.Clip(_position.X, 0.4f, _parent_scene.WorldExtents.X - 0.4f); | ||
2855 | _position.Y = Util.Clip(_position.Y, 0.4f, _parent_scene.WorldExtents.Y - 0.4f); | ||
2856 | _position.Z = Util.Clip(_position.Z + 0.2f, -100f, 50000f); | ||
2857 | |||
2858 | float tmp = _parent_scene.GetTerrainHeightAtXY(_position.X, _position.Y); | ||
2859 | if (_position.Z < tmp) | ||
2860 | _position.Z = tmp + 0.2f; | ||
2861 | |||
2862 | m_lastposition = _position; | ||
2863 | m_lastorientation = _orientation; | ||
2864 | _velocity.X = 0; | ||
2865 | _velocity.Y = 0; | ||
2866 | _velocity.Z = 0; | ||
2867 | |||
2868 | m_lastVelocity = _velocity; | ||
2869 | m_rotationalVelocity = _velocity; | ||
2870 | if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE) | ||
2871 | m_vehicle.Stop(); | ||
2872 | |||
2873 | m_crossingfailures = 0; // do this only once | ||
2874 | d.BodySetLinearVel(Body, 0, 0, 0); // stop it | ||
2875 | d.BodySetAngularVel(Body, 0, 0, 0); | ||
2876 | d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); | ||
2877 | enableBodySoft(); | ||
2878 | base.RequestPhysicsterseUpdate(); | ||
2879 | return; | ||
2880 | } | ||
2881 | |||
2882 | else if (m_crossingfailures != 0) | ||
2883 | { | ||
2884 | return; | ||
2885 | } | ||
2886 | |||
2887 | Vector3 pv = Vector3.Zero; | 2869 | Vector3 pv = Vector3.Zero; |
2888 | bool lastZeroFlag = _zeroFlag; | 2870 | bool lastZeroFlag = _zeroFlag; |
2889 | 2871 | ||
@@ -2899,24 +2881,21 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2899 | // we can't let it keeping moving and having colisions | 2881 | // we can't let it keeping moving and having colisions |
2900 | // since it can be stucked between something like terrain and edge | 2882 | // since it can be stucked between something like terrain and edge |
2901 | // so lets stop and disable it until something else kicks it | 2883 | // so lets stop and disable it until something else kicks it |
2902 | if (m_crossingfailures == 0) | ||
2903 | { | ||
2904 | 2884 | ||
2905 | _position.X = Util.Clip(lpos.X, -0.5f, _parent_scene.WorldExtents.X + 0.5f); | 2885 | _position.X = Util.Clip(lpos.X, -0.2f, _parent_scene.WorldExtents.X + 0.2f); |
2906 | _position.Y = Util.Clip(lpos.Y, -0.5f, _parent_scene.WorldExtents.Y + 0.5f); | 2886 | _position.Y = Util.Clip(lpos.Y, -0.2f, _parent_scene.WorldExtents.Y + 0.2f); |
2907 | _position.Z = Util.Clip(lpos.Z, -100f, 50000f); | 2887 | _position.Z = Util.Clip(lpos.Z, -100f, 50000f); |
2908 | 2888 | ||
2909 | m_lastposition = _position; | 2889 | m_lastposition = _position; |
2910 | m_lastorientation = _orientation; | 2890 | // m_lastorientation = _orientation; |
2911 | 2891 | ||
2912 | d.BodySetLinearVel(Body, 0, 0, 0); // stop it | 2892 | d.BodySetLinearVel(Body, 0, 0, 0); // stop it |
2913 | d.BodySetAngularVel(Body, 0, 0, 0); | 2893 | // d.BodySetAngularVel(Body, 0, 0, 0); |
2914 | d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); | 2894 | d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); |
2915 | disableBodySoft(); // stop collisions | 2895 | disableBodySoft(); // stop collisions |
2916 | m_crossingfailures++; // do this only once | 2896 | m_outbounds = true; |
2917 | base.RequestPhysicsterseUpdate(); | 2897 | base.RequestPhysicsterseUpdate(); |
2918 | return; | 2898 | return; |
2919 | } | ||
2920 | } | 2899 | } |
2921 | 2900 | ||
2922 | if (lpos.Z < -100 || lpos.Z > 100000f) | 2901 | if (lpos.Z < -100 || lpos.Z > 100000f) |
@@ -3159,6 +3138,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3159 | else | 3138 | else |
3160 | ChildRemove(this, false); | 3139 | ChildRemove(this, false); |
3161 | 3140 | ||
3141 | m_vehicle = null; | ||
3162 | RemoveGeom(); | 3142 | RemoveGeom(); |
3163 | m_targetSpace = IntPtr.Zero; | 3143 | m_targetSpace = IntPtr.Zero; |
3164 | if (m_eventsubscription > 0) | 3144 | if (m_eventsubscription > 0) |
@@ -3273,6 +3253,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3273 | changeVehicleRotationParam((strVehicleQuatParam) arg); | 3253 | changeVehicleRotationParam((strVehicleQuatParam) arg); |
3274 | break; | 3254 | break; |
3275 | 3255 | ||
3256 | case changes.SetVehicle: | ||
3257 | changeSetVehicle((VehicleData) arg); | ||
3258 | break; | ||
3276 | case changes.Null: | 3259 | case changes.Null: |
3277 | donullchange(); | 3260 | donullchange(); |
3278 | break; | 3261 | break; |
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs index e62746e..2b6bc59 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs | |||
@@ -1,4 +1,3 @@ | |||
1 | |||
2 | /* | 1 | /* |
3 | * based on: | 2 | * based on: |
4 | * Ode.NET - .NET bindings for ODE | 3 | * Ode.NET - .NET bindings for ODE |
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs index 56f3786..6e4c373 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs | |||
@@ -137,6 +137,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
137 | VehicleVectorParam, | 137 | VehicleVectorParam, |
138 | VehicleRotationParam, | 138 | VehicleRotationParam, |
139 | VehicleFlags, | 139 | VehicleFlags, |
140 | SetVehicle, | ||
140 | 141 | ||
141 | Null //keep this last used do dim the methods array. does nothing but pulsing the prim | 142 | Null //keep this last used do dim the methods array. does nothing but pulsing the prim |
142 | } | 143 | } |
@@ -166,8 +167,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
166 | 167 | ||
167 | float frictionMovementMult = 0.3f; | 168 | float frictionMovementMult = 0.3f; |
168 | 169 | ||
169 | float TerrainBounce = 0.3f; | 170 | float TerrainBounce = 0.1f; |
170 | float TerrainFriction = 0.3f; | 171 | float TerrainFriction = 0.1f; |
171 | 172 | ||
172 | public float AvatarBounce = 0.3f; | 173 | public float AvatarBounce = 0.3f; |
173 | public float AvatarFriction = 0;// 0.9f * 0.5f; | 174 | public float AvatarFriction = 0;// 0.9f * 0.5f; |
@@ -989,145 +990,62 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
989 | /// <param name="timeStep"></param> | 990 | /// <param name="timeStep"></param> |
990 | private void collision_optimized() | 991 | private void collision_optimized() |
991 | { | 992 | { |
992 | // _perloopContact.Clear(); | ||
993 | // clear characts IsColliding until we do it some other way | ||
994 | |||
995 | lock (_characters) | 993 | lock (_characters) |
996 | { | 994 | { |
997 | foreach (OdeCharacter chr in _characters) | 995 | try |
996 | { | ||
997 | foreach (OdeCharacter chr in _characters) | ||
998 | { | 998 | { |
999 | // this are odd checks if they are needed something is wrong elsewhere | 999 | if (chr == null || chr.Shell == IntPtr.Zero || chr.Body == IntPtr.Zero) |
1000 | // keep for now | 1000 | continue; |
1001 | if (chr == null) | 1001 | |
1002 | continue; | 1002 | chr.IsColliding = false; |
1003 | 1003 | // chr.CollidingGround = false; not done here | |
1004 | if (chr.Shell == IntPtr.Zero || chr.Body == IntPtr.Zero) | 1004 | chr.CollidingObj = false; |
1005 | continue; | 1005 | // do colisions with static space |
1006 | 1006 | d.SpaceCollide2(StaticSpace, chr.Shell, IntPtr.Zero, nearCallback); | |
1007 | chr.IsColliding = false; | ||
1008 | // chr.CollidingGround = false; not done here | ||
1009 | chr.CollidingObj = false; | ||
1010 | } | 1007 | } |
1011 | } | 1008 | } |
1012 | 1009 | catch (AccessViolationException) | |
1013 | // now let ode do its job | ||
1014 | // colide active things amoung them | ||
1015 | |||
1016 | int st = Util.EnvironmentTickCount(); | ||
1017 | int ta; | ||
1018 | int ts; | ||
1019 | try | ||
1020 | { | ||
1021 | d.SpaceCollide(ActiveSpace, IntPtr.Zero, nearCallback); | ||
1022 | } | ||
1023 | catch (AccessViolationException) | ||
1024 | { | 1010 | { |
1025 | m_log.Warn("[PHYSICS]: Unable to Active space collide"); | 1011 | m_log.Warn("[PHYSICS]: Unable to collide Character to static space"); |
1026 | } | 1012 | } |
1027 | ta = Util.EnvironmentTickCountSubtract(st); | 1013 | |
1028 | // then active things with static enviroment | 1014 | } |
1029 | try | 1015 | |
1016 | // collide active prims with static enviroment | ||
1017 | lock (_activeprims) | ||
1018 | { | ||
1019 | try | ||
1030 | { | 1020 | { |
1031 | d.SpaceCollide2(ActiveSpace,StaticSpace, IntPtr.Zero, nearCallback); | 1021 | foreach (OdePrim prm in _activeprims) |
1022 | { | ||
1023 | if (d.BodyIsEnabled(prm.Body)) | ||
1024 | d.SpaceCollide2(StaticSpace, prm.prim_geom, IntPtr.Zero, nearCallback); | ||
1025 | } | ||
1032 | } | 1026 | } |
1033 | catch (AccessViolationException) | 1027 | catch (AccessViolationException) |
1034 | { | 1028 | { |
1035 | m_log.Warn("[PHYSICS]: Unable to Active to static space collide"); | 1029 | m_log.Warn("[PHYSICS]: Unable to collide Active prim to static space"); |
1036 | } | 1030 | } |
1037 | ts = Util.EnvironmentTickCountSubtract(st); | ||
1038 | // _perloopContact.Clear(); | ||
1039 | } | ||
1040 | |||
1041 | #endregion | ||
1042 | |||
1043 | |||
1044 | public float GetTerrainHeightAtXY(float x, float y) | ||
1045 | { | ||
1046 | // assumes 1m size grid and constante size square regions | ||
1047 | // region offset in mega position | ||
1048 | |||
1049 | int offsetX = ((int)(x / (int)Constants.RegionSize)) * (int)Constants.RegionSize; | ||
1050 | int offsetY = ((int)(y / (int)Constants.RegionSize)) * (int)Constants.RegionSize; | ||
1051 | |||
1052 | IntPtr heightFieldGeom = IntPtr.Zero; | ||
1053 | |||
1054 | // get region map | ||
1055 | if (!RegionTerrain.TryGetValue(new Vector3(offsetX, offsetY, 0), out heightFieldGeom)) | ||
1056 | return 0f; | ||
1057 | |||
1058 | if (heightFieldGeom == IntPtr.Zero) | ||
1059 | return 0f; | ||
1060 | |||
1061 | if (!TerrainHeightFieldHeights.ContainsKey(heightFieldGeom)) | ||
1062 | return 0f; | ||
1063 | |||
1064 | // TerrainHeightField for ODE as offset 1m | ||
1065 | x += 1f - offsetX; | ||
1066 | y += 1f - offsetY; | ||
1067 | |||
1068 | // make position fit into array | ||
1069 | if (x < 0) | ||
1070 | x = 0; | ||
1071 | if (y < 0) | ||
1072 | y = 0; | ||
1073 | |||
1074 | // integer indexs | ||
1075 | int ix; | ||
1076 | int iy; | ||
1077 | // interpolators offset | ||
1078 | float dx; | ||
1079 | float dy; | ||
1080 | |||
1081 | int regsize = (int)Constants.RegionSize + 2; // map size see setterrain | ||
1082 | |||
1083 | // we still have square fixed size regions | ||
1084 | // also flip x and y because of how map is done for ODE fliped axis | ||
1085 | // so ix,iy,dx and dy are inter exchanged | ||
1086 | if (x < regsize - 1) | ||
1087 | { | ||
1088 | iy = (int)x; | ||
1089 | dy = x - (float)iy; | ||
1090 | } | ||
1091 | else // out world use external height | ||
1092 | { | ||
1093 | iy = regsize - 1; | ||
1094 | dy = 0; | ||
1095 | } | 1031 | } |
1096 | if (y < regsize - 1) | 1032 | |
1033 | // finally colide active things amoung them | ||
1034 | try | ||
1097 | { | 1035 | { |
1098 | ix = (int)y; | 1036 | d.SpaceCollide(ActiveSpace, IntPtr.Zero, nearCallback); |
1099 | dx = y - (float)ix; | ||
1100 | } | 1037 | } |
1101 | else | 1038 | catch (AccessViolationException) |
1102 | { | 1039 | { |
1103 | ix = regsize - 1; | 1040 | m_log.Warn("[PHYSICS]: Unable to collide in Active space"); |
1104 | dx = 0; | ||
1105 | } | 1041 | } |
1106 | 1042 | ||
1107 | float h0; | 1043 | // _perloopContact.Clear(); |
1108 | float h1; | 1044 | } |
1109 | float h2; | ||
1110 | |||
1111 | iy *= regsize; | ||
1112 | iy += ix; // all indexes have iy + ix | ||
1113 | 1045 | ||
1114 | float[] heights = TerrainHeightFieldHeights[heightFieldGeom]; | 1046 | #endregion |
1115 | 1047 | ||
1116 | if ((dx + dy) <= 1.0f) | ||
1117 | { | ||
1118 | h0 = ((float)heights[iy]); // 0,0 vertice | ||
1119 | h1 = (((float)heights[iy + 1]) - h0) * dx; // 1,0 vertice minus 0,0 | ||
1120 | h2 = (((float)heights[iy + regsize]) - h0) * dy; // 0,1 vertice minus 0,0 | ||
1121 | } | ||
1122 | else | ||
1123 | { | ||
1124 | h0 = ((float)heights[iy + regsize + 1]); // 1,1 vertice | ||
1125 | h1 = (((float)heights[iy + 1]) - h0) * (1 - dy); // 1,1 vertice minus 1,0 | ||
1126 | h2 = (((float)heights[iy + regsize]) - h0) * (1 - dx); // 1,1 vertice minus 0,1 | ||
1127 | } | ||
1128 | 1048 | ||
1129 | return h0 + h1 + h2; | ||
1130 | } | ||
1131 | 1049 | ||
1132 | /// <summary> | 1050 | /// <summary> |
1133 | /// Add actor to the list that should receive collision events in the simulate loop. | 1051 | /// Add actor to the list that should receive collision events in the simulate loop. |
@@ -1835,273 +1753,94 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1835 | get { return (false); } | 1753 | get { return (false); } |
1836 | } | 1754 | } |
1837 | 1755 | ||
1838 | #region ODE Specific Terrain Fixes | 1756 | public float GetTerrainHeightAtXY(float x, float y) |
1839 | public float[] ResizeTerrain512NearestNeighbour(float[] heightMap) | ||
1840 | { | 1757 | { |
1841 | float[] returnarr = new float[262144]; | 1758 | // assumes 1m size grid and constante size square regions |
1842 | float[,] resultarr = new float[(int)WorldExtents.X, (int)WorldExtents.Y]; | 1759 | // needs to know about sims around in future |
1760 | // region offset in mega position | ||
1843 | 1761 | ||
1844 | // Filling out the array into its multi-dimensional components | 1762 | int offsetX = ((int)(x / (int)Constants.RegionSize)) * (int)Constants.RegionSize; |
1845 | for (int y = 0; y < WorldExtents.Y; y++) | 1763 | int offsetY = ((int)(y / (int)Constants.RegionSize)) * (int)Constants.RegionSize; |
1846 | { | ||
1847 | for (int x = 0; x < WorldExtents.X; x++) | ||
1848 | { | ||
1849 | resultarr[y, x] = heightMap[y * (int)WorldExtents.Y + x]; | ||
1850 | } | ||
1851 | } | ||
1852 | 1764 | ||
1853 | // Resize using Nearest Neighbour | 1765 | IntPtr heightFieldGeom = IntPtr.Zero; |
1854 | |||
1855 | // This particular way is quick but it only works on a multiple of the original | ||
1856 | |||
1857 | // The idea behind this method can be described with the following diagrams | ||
1858 | // second pass and third pass happen in the same loop really.. just separated | ||
1859 | // them to show what this does. | ||
1860 | |||
1861 | // First Pass | ||
1862 | // ResultArr: | ||
1863 | // 1,1,1,1,1,1 | ||
1864 | // 1,1,1,1,1,1 | ||
1865 | // 1,1,1,1,1,1 | ||
1866 | // 1,1,1,1,1,1 | ||
1867 | // 1,1,1,1,1,1 | ||
1868 | // 1,1,1,1,1,1 | ||
1869 | |||
1870 | // Second Pass | ||
1871 | // ResultArr2: | ||
1872 | // 1,,1,,1,,1,,1,,1, | ||
1873 | // ,,,,,,,,,, | ||
1874 | // 1,,1,,1,,1,,1,,1, | ||
1875 | // ,,,,,,,,,, | ||
1876 | // 1,,1,,1,,1,,1,,1, | ||
1877 | // ,,,,,,,,,, | ||
1878 | // 1,,1,,1,,1,,1,,1, | ||
1879 | // ,,,,,,,,,, | ||
1880 | // 1,,1,,1,,1,,1,,1, | ||
1881 | // ,,,,,,,,,, | ||
1882 | // 1,,1,,1,,1,,1,,1, | ||
1883 | |||
1884 | // Third pass fills in the blanks | ||
1885 | // ResultArr2: | ||
1886 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
1887 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
1888 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
1889 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
1890 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
1891 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
1892 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
1893 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
1894 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
1895 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
1896 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
1897 | |||
1898 | // X,Y = . | ||
1899 | // X+1,y = ^ | ||
1900 | // X,Y+1 = * | ||
1901 | // X+1,Y+1 = # | ||
1902 | |||
1903 | // Filling in like this; | ||
1904 | // .* | ||
1905 | // ^# | ||
1906 | // 1st . | ||
1907 | // 2nd * | ||
1908 | // 3rd ^ | ||
1909 | // 4th # | ||
1910 | // on single loop. | ||
1911 | |||
1912 | float[,] resultarr2 = new float[512, 512]; | ||
1913 | for (int y = 0; y < WorldExtents.Y; y++) | ||
1914 | { | ||
1915 | for (int x = 0; x < WorldExtents.X; x++) | ||
1916 | { | ||
1917 | resultarr2[y * 2, x * 2] = resultarr[y, x]; | ||
1918 | 1766 | ||
1919 | if (y < WorldExtents.Y) | 1767 | // get region map |
1920 | { | 1768 | if (!RegionTerrain.TryGetValue(new Vector3(offsetX, offsetY, 0), out heightFieldGeom)) |
1921 | resultarr2[(y * 2) + 1, x * 2] = resultarr[y, x]; | 1769 | return 0f; |
1922 | } | ||
1923 | if (x < WorldExtents.X) | ||
1924 | { | ||
1925 | resultarr2[y * 2, (x * 2) + 1] = resultarr[y, x]; | ||
1926 | } | ||
1927 | if (x < WorldExtents.X && y < WorldExtents.Y) | ||
1928 | { | ||
1929 | resultarr2[(y * 2) + 1, (x * 2) + 1] = resultarr[y, x]; | ||
1930 | } | ||
1931 | } | ||
1932 | } | ||
1933 | 1770 | ||
1934 | //Flatten out the array | 1771 | if (heightFieldGeom == IntPtr.Zero) |
1935 | int i = 0; | 1772 | return 0f; |
1936 | for (int y = 0; y < 512; y++) | ||
1937 | { | ||
1938 | for (int x = 0; x < 512; x++) | ||
1939 | { | ||
1940 | if (resultarr2[y, x] <= 0) | ||
1941 | returnarr[i] = 0.0000001f; | ||
1942 | else | ||
1943 | returnarr[i] = resultarr2[y, x]; | ||
1944 | 1773 | ||
1945 | i++; | 1774 | if (!TerrainHeightFieldHeights.ContainsKey(heightFieldGeom)) |
1946 | } | 1775 | return 0f; |
1947 | } | ||
1948 | 1776 | ||
1949 | return returnarr; | 1777 | // TerrainHeightField for ODE as offset 1m |
1950 | } | 1778 | x += 1f - offsetX; |
1779 | y += 1f - offsetY; | ||
1951 | 1780 | ||
1952 | public float[] ResizeTerrain512Interpolation(float[] heightMap) | 1781 | // make position fit into array |
1953 | { | 1782 | if (x < 0) |
1954 | float[] returnarr = new float[262144]; | 1783 | x = 0; |
1955 | float[,] resultarr = new float[512,512]; | 1784 | if (y < 0) |
1785 | y = 0; | ||
1786 | |||
1787 | // integer indexs | ||
1788 | int ix; | ||
1789 | int iy; | ||
1790 | // interpolators offset | ||
1791 | float dx; | ||
1792 | float dy; | ||
1793 | |||
1794 | int regsize = (int)Constants.RegionSize + 3; // map size see setterrain number of samples | ||
1956 | 1795 | ||
1957 | // Filling out the array into its multi-dimensional components | 1796 | // we still have square fixed size regions |
1958 | for (int y = 0; y < 256; y++) | 1797 | // also flip x and y because of how map is done for ODE fliped axis |
1798 | // so ix,iy,dx and dy are inter exchanged | ||
1799 | if (x < regsize - 1) | ||
1959 | { | 1800 | { |
1960 | for (int x = 0; x < 256; x++) | 1801 | iy = (int)x; |
1961 | { | 1802 | dy = x - (float)iy; |
1962 | resultarr[y, x] = heightMap[y * 256 + x]; | ||
1963 | } | ||
1964 | } | 1803 | } |
1965 | 1804 | else // out world use external height | |
1966 | // Resize using interpolation | ||
1967 | |||
1968 | // This particular way is quick but it only works on a multiple of the original | ||
1969 | |||
1970 | // The idea behind this method can be described with the following diagrams | ||
1971 | // second pass and third pass happen in the same loop really.. just separated | ||
1972 | // them to show what this does. | ||
1973 | |||
1974 | // First Pass | ||
1975 | // ResultArr: | ||
1976 | // 1,1,1,1,1,1 | ||
1977 | // 1,1,1,1,1,1 | ||
1978 | // 1,1,1,1,1,1 | ||
1979 | // 1,1,1,1,1,1 | ||
1980 | // 1,1,1,1,1,1 | ||
1981 | // 1,1,1,1,1,1 | ||
1982 | |||
1983 | // Second Pass | ||
1984 | // ResultArr2: | ||
1985 | // 1,,1,,1,,1,,1,,1, | ||
1986 | // ,,,,,,,,,, | ||
1987 | // 1,,1,,1,,1,,1,,1, | ||
1988 | // ,,,,,,,,,, | ||
1989 | // 1,,1,,1,,1,,1,,1, | ||
1990 | // ,,,,,,,,,, | ||
1991 | // 1,,1,,1,,1,,1,,1, | ||
1992 | // ,,,,,,,,,, | ||
1993 | // 1,,1,,1,,1,,1,,1, | ||
1994 | // ,,,,,,,,,, | ||
1995 | // 1,,1,,1,,1,,1,,1, | ||
1996 | |||
1997 | // Third pass fills in the blanks | ||
1998 | // ResultArr2: | ||
1999 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
2000 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
2001 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
2002 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
2003 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
2004 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
2005 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
2006 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
2007 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
2008 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
2009 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
2010 | |||
2011 | // X,Y = . | ||
2012 | // X+1,y = ^ | ||
2013 | // X,Y+1 = * | ||
2014 | // X+1,Y+1 = # | ||
2015 | |||
2016 | // Filling in like this; | ||
2017 | // .* | ||
2018 | // ^# | ||
2019 | // 1st . | ||
2020 | // 2nd * | ||
2021 | // 3rd ^ | ||
2022 | // 4th # | ||
2023 | // on single loop. | ||
2024 | |||
2025 | float[,] resultarr2 = new float[512,512]; | ||
2026 | for (int y = 0; y < (int)Constants.RegionSize; y++) | ||
2027 | { | 1805 | { |
2028 | for (int x = 0; x < (int)Constants.RegionSize; x++) | 1806 | iy = regsize - 1; |
2029 | { | 1807 | dy = 0; |
2030 | resultarr2[y*2, x*2] = resultarr[y, x]; | ||
2031 | |||
2032 | if (y < (int)Constants.RegionSize) | ||
2033 | { | ||
2034 | if (y + 1 < (int)Constants.RegionSize) | ||
2035 | { | ||
2036 | if (x + 1 < (int)Constants.RegionSize) | ||
2037 | { | ||
2038 | resultarr2[(y*2) + 1, x*2] = ((resultarr[y, x] + resultarr[y + 1, x] + | ||
2039 | resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4); | ||
2040 | } | ||
2041 | else | ||
2042 | { | ||
2043 | resultarr2[(y*2) + 1, x*2] = ((resultarr[y, x] + resultarr[y + 1, x])/2); | ||
2044 | } | ||
2045 | } | ||
2046 | else | ||
2047 | { | ||
2048 | resultarr2[(y*2) + 1, x*2] = resultarr[y, x]; | ||
2049 | } | ||
2050 | } | ||
2051 | if (x < (int)Constants.RegionSize) | ||
2052 | { | ||
2053 | if (x + 1 < (int)Constants.RegionSize) | ||
2054 | { | ||
2055 | if (y + 1 < (int)Constants.RegionSize) | ||
2056 | { | ||
2057 | resultarr2[y*2, (x*2) + 1] = ((resultarr[y, x] + resultarr[y + 1, x] + | ||
2058 | resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4); | ||
2059 | } | ||
2060 | else | ||
2061 | { | ||
2062 | resultarr2[y*2, (x*2) + 1] = ((resultarr[y, x] + resultarr[y, x + 1])/2); | ||
2063 | } | ||
2064 | } | ||
2065 | else | ||
2066 | { | ||
2067 | resultarr2[y*2, (x*2) + 1] = resultarr[y, x]; | ||
2068 | } | ||
2069 | } | ||
2070 | if (x < (int)Constants.RegionSize && y < (int)Constants.RegionSize) | ||
2071 | { | ||
2072 | if ((x + 1 < (int)Constants.RegionSize) && (y + 1 < (int)Constants.RegionSize)) | ||
2073 | { | ||
2074 | resultarr2[(y*2) + 1, (x*2) + 1] = ((resultarr[y, x] + resultarr[y + 1, x] + | ||
2075 | resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4); | ||
2076 | } | ||
2077 | else | ||
2078 | { | ||
2079 | resultarr2[(y*2) + 1, (x*2) + 1] = resultarr[y, x]; | ||
2080 | } | ||
2081 | } | ||
2082 | } | ||
2083 | } | 1808 | } |
2084 | //Flatten out the array | 1809 | if (y < regsize - 1) |
2085 | int i = 0; | ||
2086 | for (int y = 0; y < 512; y++) | ||
2087 | { | 1810 | { |
2088 | for (int x = 0; x < 512; x++) | 1811 | ix = (int)y; |
2089 | { | 1812 | dx = y - (float)ix; |
2090 | if (Single.IsNaN(resultarr2[y, x]) || Single.IsInfinity(resultarr2[y, x])) | 1813 | } |
2091 | { | 1814 | else |
2092 | m_log.Warn("[PHYSICS]: Non finite heightfield element detected. Setting it to 0"); | 1815 | { |
2093 | resultarr2[y, x] = 0; | 1816 | ix = regsize - 1; |
2094 | } | 1817 | dx = 0; |
2095 | returnarr[i] = resultarr2[y, x]; | ||
2096 | i++; | ||
2097 | } | ||
2098 | } | 1818 | } |
2099 | 1819 | ||
2100 | return returnarr; | 1820 | float h0; |
2101 | } | 1821 | float h1; |
1822 | float h2; | ||
2102 | 1823 | ||
2103 | #endregion | 1824 | iy *= regsize; |
1825 | iy += ix; // all indexes have iy + ix | ||
2104 | 1826 | ||
1827 | float[] heights = TerrainHeightFieldHeights[heightFieldGeom]; | ||
1828 | |||
1829 | if ((dx + dy) <= 1.0f) | ||
1830 | { | ||
1831 | h0 = ((float)heights[iy]); // 0,0 vertice | ||
1832 | h1 = (((float)heights[iy + 1]) - h0) * dx; // 1,0 vertice minus 0,0 | ||
1833 | h2 = (((float)heights[iy + regsize]) - h0) * dy; // 0,1 vertice minus 0,0 | ||
1834 | } | ||
1835 | else | ||
1836 | { | ||
1837 | h0 = ((float)heights[iy + regsize + 1]); // 1,1 vertice | ||
1838 | h1 = (((float)heights[iy + 1]) - h0) * (1 - dy); // 1,1 vertice minus 1,0 | ||
1839 | h2 = (((float)heights[iy + regsize]) - h0) * (1 - dx); // 1,1 vertice minus 0,1 | ||
1840 | } | ||
1841 | |||
1842 | return h0 + h1 + h2; | ||
1843 | } | ||
2105 | public override void SetTerrain(float[] heightMap) | 1844 | public override void SetTerrain(float[] heightMap) |
2106 | { | 1845 | { |
2107 | if (m_worldOffset != Vector3.Zero && m_parentScene != null) | 1846 | if (m_worldOffset != Vector3.Zero && m_parentScene != null) |
@@ -2124,48 +1863,47 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2124 | 1863 | ||
2125 | public void SetTerrain(float[] heightMap, Vector3 pOffset) | 1864 | public void SetTerrain(float[] heightMap, Vector3 pOffset) |
2126 | { | 1865 | { |
1866 | // assumes 1m size grid and constante size square regions | ||
1867 | // needs to know about sims around in future | ||
2127 | 1868 | ||
2128 | float[] _heightmap; | 1869 | float[] _heightmap; |
2129 | _heightmap = new float[(((int)Constants.RegionSize + 2) * ((int)Constants.RegionSize + 2))]; | ||
2130 | 1870 | ||
2131 | uint heightmapWidth = Constants.RegionSize + 2; | 1871 | uint heightmapWidth = Constants.RegionSize + 2; |
2132 | uint heightmapHeight = Constants.RegionSize + 2; | 1872 | uint heightmapHeight = Constants.RegionSize + 2; |
2133 | 1873 | ||
2134 | uint heightmapWidthSamples; | 1874 | uint heightmapWidthSamples = heightmapWidth + 1; |
1875 | uint heightmapHeightSamples = heightmapHeight + 1; | ||
2135 | 1876 | ||
2136 | uint heightmapHeightSamples; | 1877 | _heightmap = new float[heightmapWidthSamples * heightmapHeightSamples]; |
2137 | |||
2138 | heightmapWidthSamples = (uint)Constants.RegionSize + 2; | ||
2139 | heightmapHeightSamples = (uint)Constants.RegionSize + 2; | ||
2140 | 1878 | ||
2141 | const float scale = 1.0f; | 1879 | const float scale = 1.0f; |
2142 | const float offset = 0.0f; | 1880 | const float offset = 0.0f; |
2143 | const float thickness = 10f; | 1881 | const float thickness = 10f; |
2144 | const int wrap = 0; | 1882 | const int wrap = 0; |
2145 | 1883 | ||
2146 | int regionsize = (int) Constants.RegionSize + 2; | 1884 | uint regionsize = Constants.RegionSize; |
2147 | 1885 | ||
2148 | float hfmin = float.MaxValue; | 1886 | float hfmin = float.MaxValue; |
2149 | float hfmax = float.MinValue; | 1887 | float hfmax = float.MinValue; |
2150 | float val; | 1888 | float val; |
2151 | int xx; | 1889 | uint xx; |
2152 | int yy; | 1890 | uint yy; |
2153 | 1891 | ||
2154 | int maxXXYY = regionsize - 3; | 1892 | uint maxXXYY = regionsize - 1; |
2155 | // flipping map adding one margin all around so things don't fall in edges | 1893 | // flipping map adding one margin all around so things don't fall in edges |
2156 | 1894 | ||
2157 | int xt = 0; | 1895 | uint xt = 0; |
2158 | xx = 0; | 1896 | xx = 0; |
2159 | 1897 | ||
2160 | for (int x = 0; x < heightmapWidthSamples; x++) | 1898 | for (uint x = 0; x < heightmapWidthSamples; x++) |
2161 | { | 1899 | { |
2162 | if (x > 1 && xx < maxXXYY) | 1900 | if (x > 1 && xx < maxXXYY) |
2163 | xx++; | 1901 | xx++; |
2164 | yy = 0; | 1902 | yy = 0; |
2165 | for (int y = 0; y < heightmapHeightSamples; y++) | 1903 | for (uint y = 0; y < heightmapHeightSamples; y++) |
2166 | { | 1904 | { |
2167 | if (y > 1 && y < maxXXYY) | 1905 | if (y > 1 && y < maxXXYY) |
2168 | yy += (int)Constants.RegionSize; | 1906 | yy += regionsize; |
2169 | 1907 | ||
2170 | val = heightMap[yy + xx]; | 1908 | val = heightMap[yy + xx]; |
2171 | _heightmap[xt + y] = val; | 1909 | _heightmap[xt + y] = val; |
@@ -2176,8 +1914,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2176 | hfmax = val; | 1914 | hfmax = val; |
2177 | 1915 | ||
2178 | } | 1916 | } |
2179 | 1917 | xt += heightmapHeightSamples; | |
2180 | xt += regionsize; | ||
2181 | } | 1918 | } |
2182 | lock (OdeLock) | 1919 | lock (OdeLock) |
2183 | { | 1920 | { |
@@ -2230,11 +1967,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2230 | d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle); | 1967 | d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle); |
2231 | d.GeomSetRotation(GroundGeom, ref R); | 1968 | d.GeomSetRotation(GroundGeom, ref R); |
2232 | d.GeomSetPosition(GroundGeom, pOffset.X + (float)Constants.RegionSize * 0.5f - 0.5f, pOffset.Y + (float)Constants.RegionSize * 0.5f - 0.5f, 0); | 1969 | d.GeomSetPosition(GroundGeom, pOffset.X + (float)Constants.RegionSize * 0.5f - 0.5f, pOffset.Y + (float)Constants.RegionSize * 0.5f - 0.5f, 0); |
2233 | IntPtr testGround = IntPtr.Zero; | ||
2234 | if (RegionTerrain.TryGetValue(pOffset, out testGround)) | ||
2235 | { | ||
2236 | RegionTerrain.Remove(pOffset); | ||
2237 | } | ||
2238 | RegionTerrain.Add(pOffset, GroundGeom, GroundGeom); | 1970 | RegionTerrain.Add(pOffset, GroundGeom, GroundGeom); |
2239 | // TerrainHeightFieldHeights.Add(GroundGeom, ODElandMap); | 1971 | // TerrainHeightFieldHeights.Add(GroundGeom, ODElandMap); |
2240 | TerrainHeightFieldHeights.Add(GroundGeom, _heightmap); | 1972 | TerrainHeightFieldHeights.Add(GroundGeom, _heightmap); |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 8708b99..4366626 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | |||
@@ -2484,13 +2484,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2484 | public void llApplyRotationalImpulse(LSL_Vector force, int local) | 2484 | public void llApplyRotationalImpulse(LSL_Vector force, int local) |
2485 | { | 2485 | { |
2486 | m_host.AddScriptLPS(1); | 2486 | m_host.AddScriptLPS(1); |
2487 | m_host.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0); | 2487 | m_host.ParentGroup.RootPart.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0); |
2488 | } | 2488 | } |
2489 | 2489 | ||
2490 | public void llSetTorque(LSL_Vector torque, int local) | 2490 | public void llSetTorque(LSL_Vector torque, int local) |
2491 | { | 2491 | { |
2492 | m_host.AddScriptLPS(1); | 2492 | m_host.AddScriptLPS(1); |
2493 | m_host.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0); | 2493 | m_host.ParentGroup.RootPart.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0); |
2494 | } | 2494 | } |
2495 | 2495 | ||
2496 | public LSL_Vector llGetTorque() | 2496 | public LSL_Vector llGetTorque() |
@@ -4657,6 +4657,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4657 | ScriptSleep(5000); | 4657 | ScriptSleep(5000); |
4658 | } | 4658 | } |
4659 | 4659 | ||
4660 | public void llTeleportAgent(string agent, string simname, LSL_Vector pos, LSL_Vector lookAt) | ||
4661 | { | ||
4662 | m_host.AddScriptLPS(1); | ||
4663 | UUID agentId = new UUID(); | ||
4664 | if (UUID.TryParse(agent, out agentId)) | ||
4665 | { | ||
4666 | ScenePresence presence = World.GetScenePresence(agentId); | ||
4667 | if (presence != null) | ||
4668 | { | ||
4669 | // agent must not be a god | ||
4670 | if (presence.UserLevel >= 200) return; | ||
4671 | |||
4672 | // agent must be over the owners land | ||
4673 | if (m_host.OwnerID == World.LandChannel.GetLandObject( | ||
4674 | presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) | ||
4675 | { | ||
4676 | World.RequestTeleportLocation(presence.ControllingClient, simname, new Vector3((float)pos.x, (float)pos.y, (float)pos.z), new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z), (uint)TeleportFlags.ViaLocation); | ||
4677 | } | ||
4678 | } | ||
4679 | } | ||
4680 | } | ||
4681 | |||
4660 | public void llTextBox(string agent, string message, int chatChannel) | 4682 | public void llTextBox(string agent, string message, int chatChannel) |
4661 | { | 4683 | { |
4662 | IDialogModule dm = World.RequestModuleInterface<IDialogModule>(); | 4684 | IDialogModule dm = World.RequestModuleInterface<IDialogModule>(); |
@@ -11980,6 +12002,144 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
11980 | } | 12002 | } |
11981 | 12003 | ||
11982 | #endregion | 12004 | #endregion |
12005 | |||
12006 | public void llSetKeyframedMotion(LSL_List frames, LSL_List options) | ||
12007 | { | ||
12008 | SceneObjectGroup group = m_host.ParentGroup; | ||
12009 | |||
12010 | if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical) | ||
12011 | return; | ||
12012 | if (group.IsAttachment) | ||
12013 | return; | ||
12014 | |||
12015 | if (frames.Data.Length > 0) // We are getting a new motion | ||
12016 | { | ||
12017 | if (group.RootPart.KeyframeMotion != null) | ||
12018 | group.RootPart.KeyframeMotion.Stop(); | ||
12019 | group.RootPart.KeyframeMotion = null; | ||
12020 | |||
12021 | int idx = 0; | ||
12022 | |||
12023 | KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward; | ||
12024 | KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation; | ||
12025 | |||
12026 | while (idx < options.Data.Length) | ||
12027 | { | ||
12028 | int option = (int)options.GetLSLIntegerItem(idx++); | ||
12029 | int remain = options.Data.Length - idx; | ||
12030 | |||
12031 | switch (option) | ||
12032 | { | ||
12033 | case ScriptBaseClass.KFM_MODE: | ||
12034 | if (remain < 1) | ||
12035 | break; | ||
12036 | int modeval = (int)options.GetLSLIntegerItem(idx++); | ||
12037 | switch(modeval) | ||
12038 | { | ||
12039 | case ScriptBaseClass.KFM_FORWARD: | ||
12040 | mode = KeyframeMotion.PlayMode.Forward; | ||
12041 | break; | ||
12042 | case ScriptBaseClass.KFM_REVERSE: | ||
12043 | mode = KeyframeMotion.PlayMode.Reverse; | ||
12044 | break; | ||
12045 | case ScriptBaseClass.KFM_LOOP: | ||
12046 | mode = KeyframeMotion.PlayMode.Loop; | ||
12047 | break; | ||
12048 | case ScriptBaseClass.KFM_PING_PONG: | ||
12049 | mode = KeyframeMotion.PlayMode.PingPong; | ||
12050 | break; | ||
12051 | } | ||
12052 | break; | ||
12053 | case ScriptBaseClass.KFM_DATA: | ||
12054 | if (remain < 1) | ||
12055 | break; | ||
12056 | int dataval = (int)options.GetLSLIntegerItem(idx++); | ||
12057 | data = (KeyframeMotion.DataFormat)dataval; | ||
12058 | break; | ||
12059 | } | ||
12060 | } | ||
12061 | |||
12062 | group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data); | ||
12063 | |||
12064 | idx = 0; | ||
12065 | |||
12066 | int elemLength = 2; | ||
12067 | if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation)) | ||
12068 | elemLength = 3; | ||
12069 | |||
12070 | List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>(); | ||
12071 | while (idx < frames.Data.Length) | ||
12072 | { | ||
12073 | int remain = frames.Data.Length - idx; | ||
12074 | |||
12075 | if (remain < elemLength) | ||
12076 | break; | ||
12077 | |||
12078 | KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe(); | ||
12079 | frame.Position = null; | ||
12080 | frame.Rotation = null; | ||
12081 | |||
12082 | if ((data & KeyframeMotion.DataFormat.Translation) != 0) | ||
12083 | { | ||
12084 | LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++); | ||
12085 | frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z); | ||
12086 | } | ||
12087 | if ((data & KeyframeMotion.DataFormat.Rotation) != 0) | ||
12088 | { | ||
12089 | LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++); | ||
12090 | frame.Rotation = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s); | ||
12091 | } | ||
12092 | |||
12093 | float tempf = (float)frames.GetLSLFloatItem(idx++); | ||
12094 | frame.TimeMS = (int)(tempf * 1000.0f); | ||
12095 | |||
12096 | keyframes.Add(frame); | ||
12097 | } | ||
12098 | |||
12099 | group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray()); | ||
12100 | group.RootPart.KeyframeMotion.Start(); | ||
12101 | } | ||
12102 | else | ||
12103 | { | ||
12104 | if (group.RootPart.KeyframeMotion == null) | ||
12105 | return; | ||
12106 | |||
12107 | if (options.Data.Length == 0) | ||
12108 | { | ||
12109 | group.RootPart.KeyframeMotion.Stop(); | ||
12110 | return; | ||
12111 | } | ||
12112 | |||
12113 | int code = (int)options.GetLSLIntegerItem(0); | ||
12114 | |||
12115 | int idx = 0; | ||
12116 | |||
12117 | while (idx < options.Data.Length) | ||
12118 | { | ||
12119 | int option = (int)options.GetLSLIntegerItem(idx++); | ||
12120 | int remain = options.Data.Length - idx; | ||
12121 | |||
12122 | switch (option) | ||
12123 | { | ||
12124 | case ScriptBaseClass.KFM_COMMAND: | ||
12125 | int cmd = (int)options.GetLSLIntegerItem(idx++); | ||
12126 | switch (cmd) | ||
12127 | { | ||
12128 | case ScriptBaseClass.KFM_CMD_PLAY: | ||
12129 | group.RootPart.KeyframeMotion.Start(); | ||
12130 | break; | ||
12131 | case ScriptBaseClass.KFM_CMD_STOP: | ||
12132 | group.RootPart.KeyframeMotion.Stop(); | ||
12133 | break; | ||
12134 | case ScriptBaseClass.KFM_CMD_PAUSE: | ||
12135 | group.RootPart.KeyframeMotion.Pause(); | ||
12136 | break; | ||
12137 | } | ||
12138 | break; | ||
12139 | } | ||
12140 | } | ||
12141 | } | ||
12142 | } | ||
11983 | } | 12143 | } |
11984 | 12144 | ||
11985 | public class NotecardCache | 12145 | public class NotecardCache |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs index 55444dc..8d97a7c 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs | |||
@@ -399,6 +399,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces | |||
399 | void llTargetOmega(LSL_Vector axis, double spinrate, double gain); | 399 | void llTargetOmega(LSL_Vector axis, double spinrate, double gain); |
400 | void llTargetRemove(int number); | 400 | void llTargetRemove(int number); |
401 | void llTeleportAgentHome(string agent); | 401 | void llTeleportAgentHome(string agent); |
402 | void llTeleportAgent(string agent, string simname, LSL_Vector pos, LSL_Vector lookAt); | ||
402 | void llTextBox(string avatar, string message, int chat_channel); | 403 | void llTextBox(string avatar, string message, int chat_channel); |
403 | LSL_String llToLower(string source); | 404 | LSL_String llToLower(string source); |
404 | LSL_String llToUpper(string source); | 405 | LSL_String llToUpper(string source); |
@@ -419,5 +420,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces | |||
419 | 420 | ||
420 | void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); | 421 | void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); |
421 | LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules); | 422 | LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules); |
423 | void llSetKeyframedMotion(LSL_List frames, LSL_List options); | ||
422 | } | 424 | } |
423 | } | 425 | } |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs index 3d0e5cb..a5e160d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs | |||
@@ -641,5 +641,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase | |||
641 | public static readonly LSLInteger RCERR_UNKNOWN = -1; | 641 | public static readonly LSLInteger RCERR_UNKNOWN = -1; |
642 | public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2; | 642 | public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2; |
643 | public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = 3; | 643 | public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = 3; |
644 | |||
645 | public const int KFM_MODE = 1; | ||
646 | public const int KFM_LOOP = 1; | ||
647 | public const int KFM_REVERSE = 3; | ||
648 | public const int KFM_FORWARD = 0; | ||
649 | public const int KFM_PING_PONG = 2; | ||
650 | public const int KFM_DATA = 2; | ||
651 | public const int KFM_TRANSLATION = 2; | ||
652 | public const int KFM_ROTATION = 1; | ||
653 | public const int KFM_COMMAND = 0; | ||
654 | public const int KFM_CMD_PLAY = 0; | ||
655 | public const int KFM_CMD_STOP = 1; | ||
656 | public const int KFM_CMD_PAUSE = 2; | ||
644 | } | 657 | } |
645 | } | 658 | } |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs index 5f9f0b9..a8d1ddb 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs | |||
@@ -1820,6 +1820,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase | |||
1820 | m_LSL_Functions.llTargetRemove(number); | 1820 | m_LSL_Functions.llTargetRemove(number); |
1821 | } | 1821 | } |
1822 | 1822 | ||
1823 | public void llTeleportAgent(string agent, string simname, LSL_Vector pos, LSL_Vector lookAt) | ||
1824 | { | ||
1825 | m_LSL_Functions.llTeleportAgent(agent, simname, pos, lookAt); | ||
1826 | } | ||
1827 | |||
1823 | public void llTeleportAgentHome(string agent) | 1828 | public void llTeleportAgentHome(string agent) |
1824 | { | 1829 | { |
1825 | m_LSL_Functions.llTeleportAgentHome(agent); | 1830 | m_LSL_Functions.llTeleportAgentHome(agent); |
@@ -1937,7 +1942,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase | |||
1937 | 1942 | ||
1938 | public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link) | 1943 | public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link) |
1939 | { | 1944 | { |
1940 | return m_LSL_Functions.llGetLinkNumberOfSides(link); | 1945 | return m_LSL_Functions.llGetLinkNumberOfSides(link); |
1946 | } | ||
1947 | |||
1948 | public void llSetKeyframedMotion(LSL_List frames, LSL_List options) | ||
1949 | { | ||
1950 | m_LSL_Functions.llSetKeyframedMotion(frames, options); | ||
1941 | } | 1951 | } |
1942 | } | 1952 | } |
1943 | } | 1953 | } |
diff --git a/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs b/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs index 1599a56..7deaf95 100644 --- a/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs +++ b/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs | |||
@@ -48,6 +48,9 @@ namespace OpenSim.Services.Connectors | |||
48 | 48 | ||
49 | private string m_ServerURI = String.Empty; | 49 | private string m_ServerURI = String.Empty; |
50 | 50 | ||
51 | private ExpiringCache<ulong, GridRegion> m_regionCache = | ||
52 | new ExpiringCache<ulong, GridRegion>(); | ||
53 | |||
51 | public GridServicesConnector() | 54 | public GridServicesConnector() |
52 | { | 55 | { |
53 | } | 56 | } |
@@ -265,6 +268,11 @@ namespace OpenSim.Services.Connectors | |||
265 | 268 | ||
266 | public GridRegion GetRegionByPosition(UUID scopeID, int x, int y) | 269 | public GridRegion GetRegionByPosition(UUID scopeID, int x, int y) |
267 | { | 270 | { |
271 | ulong regionHandle = Util.UIntsToLong((uint)x, (uint)y); | ||
272 | |||
273 | if (m_regionCache.Contains(regionHandle)) | ||
274 | return (GridRegion)m_regionCache[regionHandle]; | ||
275 | |||
268 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | 276 | Dictionary<string, object> sendData = new Dictionary<string, object>(); |
269 | 277 | ||
270 | sendData["SCOPEID"] = scopeID.ToString(); | 278 | sendData["SCOPEID"] = scopeID.ToString(); |
@@ -306,6 +314,8 @@ namespace OpenSim.Services.Connectors | |||
306 | else | 314 | else |
307 | m_log.DebugFormat("[GRID CONNECTOR]: GetRegionByPosition received null reply"); | 315 | m_log.DebugFormat("[GRID CONNECTOR]: GetRegionByPosition received null reply"); |
308 | 316 | ||
317 | m_regionCache.Add(regionHandle, rinfo, TimeSpan.FromSeconds(600)); | ||
318 | |||
309 | return rinfo; | 319 | return rinfo; |
310 | } | 320 | } |
311 | 321 | ||